private TrafficMeasurementManager() { LaneTrafficData = new LaneTrafficData[NetManager.MAX_SEGMENT_COUNT][]; SegmentDirTrafficData = new SegmentDirTrafficData[NetManager.MAX_SEGMENT_COUNT * 2]; for (int i = 0; i < SegmentDirTrafficData.Length; ++i) { SegmentDirTrafficData[i].meanSpeed = REF_REL_SPEED; } ResetTrafficStats(); }
public bool GetLaneTrafficData(ushort segmentId, byte laneIndex, out LaneTrafficData trafficData) { if (laneTrafficData[segmentId] == null || laneIndex >= laneTrafficData[segmentId].Length) { trafficData = default(LaneTrafficData); return(false); } else { trafficData = laneTrafficData[segmentId][laneIndex]; return(true); } }
public void OnBeforeSimulationStep(ushort segmentId, ref NetSegment segment) { GlobalConfig conf = GlobalConfig.Instance; // calculate traffic density NetInfo segmentInfo = segment.Info; int numLanes = segmentInfo.m_lanes.Length; if (LaneTrafficData[segmentId] == null || LaneTrafficData[segmentId].Length < numLanes) { LaneTrafficData[segmentId] = new LaneTrafficData[numLanes]; for (int i = 0; i < numLanes; ++i) { // laneTrafficData[segmentId][i] = new LaneTrafficData(); LaneTrafficData[segmentId][i].meanSpeed = REF_REL_SPEED; } } // calculate max./min. lane speed for (var i = 0; i < 2; ++i) { meanSpeeds[i] = 0; meanSpeedLanes[i] = 0; } uint curLaneId = segment.m_lanes; byte laneIndex = 0; while (laneIndex < numLanes && curLaneId != 0u) { NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; if ((laneInfo.m_laneType & LANE_TYPES) != NetInfo.LaneType.None && (laneInfo.m_vehicleType & VEHICLE_TYPES) != VehicleInfo.VehicleType.None) { int dirIndex = GetDirIndex(laneInfo.m_finalDirection); // calculate reported mean speed ushort newRelSpeed = CalcLaneRelativeMeanSpeed( segmentId, laneIndex, curLaneId, segment.Info.m_lanes[laneIndex]); meanSpeeds[dirIndex] += newRelSpeed; ++meanSpeedLanes[dirIndex]; LaneTrafficData[segmentId][laneIndex].meanSpeed = newRelSpeed; ushort trafficBuffer = LaneTrafficData[segmentId][laneIndex].trafficBuffer; // remember historic data LaneTrafficData[segmentId][laneIndex].lastTrafficBuffer = trafficBuffer; if (trafficBuffer > LaneTrafficData[segmentId][laneIndex].maxTrafficBuffer) { LaneTrafficData[segmentId][laneIndex].maxTrafficBuffer = trafficBuffer; } // reset buffers if (conf.AdvancedVehicleAI.MaxTrafficBuffer > 0) { if (LaneTrafficData[segmentId][laneIndex].trafficBuffer > conf.AdvancedVehicleAI.MaxTrafficBuffer) { LaneTrafficData[segmentId][laneIndex].accumulatedSpeeds /= LaneTrafficData[segmentId][laneIndex].trafficBuffer / conf.AdvancedVehicleAI.MaxTrafficBuffer; LaneTrafficData[segmentId][laneIndex].trafficBuffer = (ushort)conf.AdvancedVehicleAI.MaxTrafficBuffer; } else if (LaneTrafficData[segmentId][laneIndex].trafficBuffer == conf.AdvancedVehicleAI.MaxTrafficBuffer) { LaneTrafficData[segmentId][laneIndex].accumulatedSpeeds = 0; LaneTrafficData[segmentId][laneIndex].trafficBuffer = 0; } } else { LaneTrafficData[segmentId][laneIndex].accumulatedSpeeds = 0; LaneTrafficData[segmentId][laneIndex].trafficBuffer = 0; } } laneIndex++; curLaneId = curLaneId.ToLane().m_nextLane; } for (int i = 0; i < 2; ++i) { int segDirIndex = i == 0 ? GetDirIndex(segmentId, NetInfo.Direction.Forward) : GetDirIndex(segmentId, NetInfo.Direction.Backward); if (meanSpeedLanes[i] > 0) { SegmentDirTrafficData[segDirIndex].meanSpeed = (ushort)Math.Min( REF_REL_SPEED, meanSpeeds[i] / meanSpeedLanes[i]); } else { SegmentDirTrafficData[segDirIndex].meanSpeed = REF_REL_SPEED; } } }
public void SimulationStep(ushort segmentId, ref NetSegment segment) { GlobalConfig conf = GlobalConfig.Instance; // calculate traffic density NetInfo segmentInfo = segment.Info; uint curLaneId = segment.m_lanes; int numLanes = segmentInfo.m_lanes.Length; if (laneTrafficData[segmentId] == null || laneTrafficData[segmentId].Length < numLanes) { laneTrafficData[segmentId] = new LaneTrafficData[numLanes]; for (int i = 0; i < numLanes; ++i) { //laneTrafficData[segmentId][i] = new LaneTrafficData(); laneTrafficData[segmentId][i].meanSpeed = MAX_REL_SPEED; } } // calculate max./min. lane speed for (int i = 0; i < 2; ++i) { #if MEASURECONGESTION minRelSpeeds[i] = REF_REL_SPEED; #endif #if MEASUREDENSITY densities[i] = 0; #endif meanSpeeds[i] = 0; meanSpeedLanes[i] = 0; //numDirLanes[i] = 0; #if EXTSTATS totalPfBuf[i] = 0; #endif } //ushort maxBuffer = 0; /*for (uint li = 0; li < numLanes; ++li) { * NetInfo.Lane laneInfo = segmentInfo.m_lanes[li]; * if ((laneInfo.m_vehicleType & VEHICLE_TYPES) == VehicleInfo.VehicleType.None) * continue; * if ((laneInfo.m_laneType & LANE_TYPES) == NetInfo.LaneType.None) * continue; * * int dirIndex = GetDirIndex(laneInfo.m_finalDirection); * ++numDirLanes[dirIndex]; #if PFTRAFFICSTATS * uint pfBuf = laneTrafficData[segmentId][li].pathFindTrafficBuffer; * totalPfBuf[dirIndex] += pfBuf; * laneTrafficData[segmentId][li].lastPathFindTrafficBuffer = pfBuf; #endif #if MEASURECONGESTION * ushort curSpeed = laneTrafficData[segmentId][li].meanSpeed; * if (curSpeed < minRelSpeeds[dirIndex]) { * minRelSpeeds[dirIndex] = curSpeed; * } #endif * //ushort buf = laneTrafficData[segmentId][li].trafficBuffer; * //if (buf > maxBuffer) { * // maxBuffer = buf; * //} * }*/ curLaneId = segment.m_lanes; byte laneIndex = 0; while (laneIndex < numLanes && curLaneId != 0u) { NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; if ((laneInfo.m_laneType & LANE_TYPES) != NetInfo.LaneType.None && (laneInfo.m_vehicleType & VEHICLE_TYPES) != VehicleInfo.VehicleType.None) { int dirIndex = GetDirIndex(laneInfo.m_finalDirection); // calculate reported mean speed ushort newRelSpeed = CalcLaneRelativeMeanSpeed(segmentId, laneIndex, curLaneId, segment.Info.m_lanes[laneIndex]); #if MEASURECONGESTION if (newRelSpeed < minRelSpeeds[dirIndex]) { minRelSpeeds[dirIndex] = newRelSpeed; } #endif meanSpeeds[dirIndex] += newRelSpeed; ++meanSpeedLanes[dirIndex]; laneTrafficData[segmentId][laneIndex].meanSpeed = newRelSpeed; // reset buffers #if MEASUREDENSITY laneTrafficData[segmentId][laneIndex].accumulatedDensities /= 2; #endif if (laneTrafficData[segmentId][laneIndex].trafficBuffer >= conf.AdvancedVehicleAI.MaxTrafficBuffer) { laneTrafficData[segmentId][laneIndex].accumulatedSpeeds /= laneTrafficData[segmentId][laneIndex].trafficBuffer; laneTrafficData[segmentId][laneIndex].trafficBuffer = 1; } else if (laneTrafficData[segmentId][laneIndex].trafficBuffer == 1) { laneTrafficData[segmentId][laneIndex].accumulatedSpeeds = 0; laneTrafficData[segmentId][laneIndex].trafficBuffer = 0; } /*laneTrafficData[segmentId][laneIndex].accumulatedSpeeds = 0; * laneTrafficData[segmentId][laneIndex].trafficBuffer = 0;*/ #if PFTRAFFICSTATS if (laneTrafficData[segmentId][laneIndex].pathFindTrafficBuffer > conf.MaxPathFindTrafficBuffer) { laneTrafficData[segmentId][laneIndex].pathFindTrafficBuffer >>= 1; } #endif #if MEASUREDENSITY densities[dirIndex] += laneTrafficData[segmentId][laneIndex].accumulatedDensities; #endif } laneIndex++; curLaneId = Singleton <NetManager> .instance.m_lanes.m_buffer[curLaneId].m_nextLane; } for (int i = 0; i < 2; ++i) { int segDirIndex = i == 0 ? GetDirIndex(segmentId, NetInfo.Direction.Forward) : GetDirIndex(segmentId, NetInfo.Direction.Backward); #if MEASURECONGESTION if (segmentDirTrafficData[segDirIndex].numCongestionMeasurements > conf.MaxNumCongestionMeasurements) { segmentDirTrafficData[segDirIndex].numCongestionMeasurements >>= 1; segmentDirTrafficData[segDirIndex].numCongested >>= 1; } segmentDirTrafficData[segDirIndex].minSpeed = Math.Min(REF_REL_SPEED, minRelSpeeds[i]); ++segmentDirTrafficData[segDirIndex].numCongestionMeasurements; if (segmentDirTrafficData[segDirIndex].minSpeed / 100u < conf.CongestionSpeedThreshold) { ++segmentDirTrafficData[segDirIndex].numCongested; } segmentDirTrafficData[segDirIndex].congestionRatioInPercent = (ushort)(segmentDirTrafficData[segDirIndex].numCongestionMeasurements > 0 ? ((uint)segmentDirTrafficData[segDirIndex].numCongested * 100u) / (uint)segmentDirTrafficData[segDirIndex].numCongestionMeasurements : 0); // now in % #endif #if MEASUREDENSITY segmentDirTrafficData[segmentId][i].accumulatedDensities = densities[i]; #endif #if PFTRAFFICSTATS segmentDirTrafficData[segDirIndex].totalPathFindTrafficBuffer = totalPfBuf[i]; #endif if (meanSpeedLanes[i] > 0) { segmentDirTrafficData[segDirIndex].meanSpeed = (ushort)Math.Min(REF_REL_SPEED, (meanSpeeds[i] / meanSpeedLanes[i])); } else { segmentDirTrafficData[segDirIndex].meanSpeed = REF_REL_SPEED; } } }
public void SimulationStep(ushort segmentId, ref NetSegment segmentData) { GlobalConfig conf = GlobalConfig.Instance; // calculate traffic density NetInfo segmentInfo = segmentData.Info; uint curLaneId = segmentData.m_lanes; int numLanes = segmentInfo.m_lanes.Length; // ensure valid array sizes if (segmentDirTrafficData[segmentId] == null) { segmentDirTrafficData[segmentId] = new SegmentDirTrafficData[2]; segmentDirTrafficData[segmentId][0] = new SegmentDirTrafficData(); segmentDirTrafficData[segmentId][1] = new SegmentDirTrafficData(); } if (laneTrafficData[segmentId] == null || laneTrafficData[segmentId].Length < numLanes) { laneTrafficData[segmentId] = new LaneTrafficData[numLanes]; for (int i = 0; i < numLanes; ++i) { laneTrafficData[segmentId][i] = new LaneTrafficData(); laneTrafficData[segmentId][i].meanSpeed = MAX_SPEED; } } // calculate max./min. lane speed for (int i = 0; i < 2; ++i) { minSpeeds[i] = MAX_SPEED; densities[i] = 0; #if DEBUG meanSpeeds[i] = 0; meanSpeedLanes[i] = 0; #endif } for (uint li = 0; li < numLanes; ++li) { NetInfo.Lane laneInfo = segmentInfo.m_lanes[li]; if ((laneInfo.m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) == NetInfo.LaneType.None) { continue; } int dirIndex = GetDirIndex(laneInfo.m_finalDirection); ushort curSpeed = laneTrafficData[segmentId][li].meanSpeed; if (curSpeed < minSpeeds[dirIndex]) { minSpeeds[dirIndex] = curSpeed; } } curLaneId = segmentData.m_lanes; uint laneIndex = 0; while (laneIndex < numLanes && curLaneId != 0u) { NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; if ((laneInfo.m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) != NetInfo.LaneType.None) { int dirIndex = GetDirIndex(laneInfo.m_finalDirection); ushort currentBuf = laneTrafficData[segmentId][laneIndex].trafficBuffer; ushort curSpeed = MAX_SPEED; // we use integer division here because it's faster if (currentBuf > 0) { curSpeed = (ushort)Math.Min((uint)MAX_SPEED, ((laneTrafficData[segmentId][laneIndex].accumulatedSpeeds * (uint)MAX_SPEED) / currentBuf) / ((uint)(Math.Max(Math.Min(2f, SpeedLimitManager.Instance.GetLockFreeGameSpeedLimit(segmentId, laneIndex, curLaneId, segmentData.Info.m_lanes[laneIndex])) * 8f, 1f)))); // 0 .. 10000, 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) } // calculate reported mean speed uint minSpeed = minSpeeds[dirIndex]; ushort prevSpeed = laneTrafficData[segmentId][laneIndex].meanSpeed; float maxSpeedDiff = Mathf.Abs((short)curSpeed - (short)minSpeed); float updateFactor = Mathf.Clamp(1f - (float)maxSpeedDiff / (float)conf.MaxSpeedDifference, conf.MinSpeedUpdateFactor, conf.MaxSpeedUpdateFactor); ushort newSpeed = (ushort)Mathf.Clamp((float)prevSpeed + ((float)curSpeed - (float)prevSpeed) * updateFactor, 0, MAX_SPEED); if (newSpeed < minSpeed) { minSpeeds[dirIndex] = newSpeed; } else { int maxTolerableSpeed = (int)minSpeed + (int)conf.MaxSpeedDifference; if (newSpeed > maxTolerableSpeed) { newSpeed = (ushort)maxTolerableSpeed; } } #if DEBUG meanSpeeds[dirIndex] += newSpeed; meanSpeedLanes[dirIndex]++; #endif laneTrafficData[segmentId][laneIndex].meanSpeed = newSpeed; densities[dirIndex] += laneTrafficData[segmentId][laneIndex].accumulatedDensities; // reset buffers laneTrafficData[segmentId][laneIndex].accumulatedDensities /= 2; laneTrafficData[segmentId][laneIndex].accumulatedSpeeds = 0; laneTrafficData[segmentId][laneIndex].trafficBuffer = 0; } laneIndex++; curLaneId = Singleton <NetManager> .instance.m_lanes.m_buffer[curLaneId].m_nextLane; } for (int i = 0; i < 2; ++i) { segmentDirTrafficData[segmentId][i].minSpeed = minSpeeds[i]; segmentDirTrafficData[segmentId][i].accumulatedDensities = densities[i]; #if DEBUG if (meanSpeedLanes[i] > 0) { segmentDirTrafficData[segmentId][i].meanSpeed = (ushort)(meanSpeeds[i] / meanSpeedLanes[i]); } else { segmentDirTrafficData[segmentId][i].meanSpeed = MAX_SPEED; } #endif } }