private TrafficMeasurementManager()
 {
     laneTrafficData              = new LaneTrafficData[NetManager.MAX_SEGMENT_COUNT][];
     segmentDirTrafficData        = new SegmentDirTrafficData[NetManager.MAX_SEGMENT_COUNT][];
     defaultSegmentDirTrafficData = new SegmentDirTrafficData();
     ResetTrafficStats();
 }
Exemple #2
0
        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
            }
        }