private TrafficMeasurementManager() { laneTrafficData = new LaneTrafficData[NetManager.MAX_SEGMENT_COUNT][]; segmentDirTrafficData = new SegmentDirTrafficData[NetManager.MAX_SEGMENT_COUNT][]; defaultSegmentDirTrafficData = new SegmentDirTrafficData(); ResetTrafficStats(); }
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 GetTrafficData(ushort segmentId, NetInfo.Direction dir, out SegmentDirTrafficData trafficData) { if (segmentDirTrafficData[segmentId] == null) { trafficData = defaultSegmentDirTrafficData; return(false); } else { trafficData = segmentDirTrafficData[segmentId][GetDirIndex(dir)]; return(true); } }
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 } }