Ejemplo n.º 1
0
        public void CalculateAutoPedestrianLightState(bool propagate = true)
        {
#if DEBUGTTL
            bool debug = GlobalConfig.Instance.Debug.Switches[7] && GlobalConfig.Instance.Debug.NodeId == NodeId;
#endif

#if DEBUGTTL
            if (debug)
            {
                Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Calculating pedestrian light state of seg. {SegmentId} @ node {NodeId}");
            }
#endif

            SegmentEndGeometry segmentEndGeometry = SegmentGeometry.Get(SegmentId)?.GetEnd(StartNode);

            if (segmentEndGeometry == null)
            {
                Log._Debug($"Could not get SegmentEndGeometry for segment {SegmentId} @ {NodeId}.");
                AutoPedestrianLightState = RoadBaseAI.TrafficLightState.Green;
                return;
            }

            ushort nodeId = segmentEndGeometry.NodeId();
            if (nodeId != NodeId)
            {
                Log.Warning($"CustomSegmentLights.CalculateAutoPedestrianLightState: Node id mismatch! segment end node is {nodeId} but we are node {NodeId}. segmentEndGeometry={segmentEndGeometry} this={this}");
                return;
            }

            if (propagate)
            {
                foreach (ushort otherSegmentId in segmentEndGeometry.ConnectedSegments)
                {
                    if (otherSegmentId == 0)
                    {
                        continue;
                    }

                    ICustomSegmentLights otherLights = LightsManager.GetSegmentLights(nodeId, otherSegmentId);
                    if (otherLights == null)
                    {
#if DEBUGTTL
                        if (debug)
                        {
                            Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Expected other (propagate) CustomSegmentLights at segment {otherSegmentId} @ {NodeId} but there was none. Original segment id: {SegmentId}");
                        }
#endif
                        continue;
                    }

                    otherLights.CalculateAutoPedestrianLightState(false);
                }
            }

            if (IsAnyGreen())
            {
#if DEBUGTTL
                if (debug)
                {
                    Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Any green at seg. {SegmentId} @ {NodeId}");
                }
#endif
                AutoPedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                return;
            }

#if DEBUGTTL
            if (debug)
            {
                Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Querying incoming segments at seg. {SegmentId} @ {NodeId}");
            }
#endif
            RoadBaseAI.TrafficLightState autoPedestrianLightState = RoadBaseAI.TrafficLightState.Green;

            ItemClass prevConnectionClass = null;
            Constants.ServiceFactory.NetService.ProcessSegment(SegmentId, delegate(ushort prevSegId, ref NetSegment segment) {
                prevConnectionClass = segment.Info.GetConnectionClass();
                return(true);
            });

            if (!segmentEndGeometry.IncomingOneWay)
            {
                // query straight segments
                foreach (ushort otherSegmentId in segmentEndGeometry.IncomingStraightSegments)
                {
                    if (otherSegmentId == 0)
                    {
                        continue;
                    }
#if DEBUGTTL
                    if (debug)
                    {
                        Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Checking incoming straight segment {otherSegmentId} at seg. {SegmentId} @ {NodeId}");
                    }
#endif

                    ICustomSegmentLights otherLights = LightsManager.GetSegmentLights(nodeId, otherSegmentId);
                    if (otherLights == null)
                    {
#if DEBUGTTL
                        if (debug)
                        {
                            Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Expected other (straight) CustomSegmentLights at segment {otherSegmentId} @ {NodeId} but there was none. Original segment id: {SegmentId}");
                        }
#endif
                        continue;
                    }

                    SegmentGeometry otherGeo = SegmentGeometry.Get(otherSegmentId);
                    if (otherGeo == null)
                    {
#if DEBUGTTL
                        if (debug)
                        {
                            Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Expected other (straight) segment geometry at segment {otherSegmentId} @ {NodeId} (startNode={otherLights.StartNode}) but there was none. Original segment id: {SegmentId}");
                        }
#endif
                        continue;
                    }

                    ItemClass nextConnectionClass = null;
                    Constants.ServiceFactory.NetService.ProcessSegment(otherSegmentId, delegate(ushort otherSegId, ref NetSegment segment) {
                        nextConnectionClass = segment.Info.GetConnectionClass();
                        return(true);
                    });

                    if (nextConnectionClass.m_service != prevConnectionClass.m_service)
                    {
#if DEBUGTTL
                        if (debug)
                        {
                            Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Other (straight) segment {otherSegmentId} @ {NodeId} has different connection service than segment {SegmentId} ({nextConnectionClass.m_service} vs. {prevConnectionClass.m_service}). Ignoring traffic light state.");
                        }
#endif
                        continue;
                    }

                    if (!otherLights.IsAllMainRed())
                    {
#if DEBUGTTL
                        if (debug)
                        {
                            Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Not all main red at {otherSegmentId} at seg. {SegmentId} @ {NodeId}");
                        }
#endif
                        autoPedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                        break;
                    }
                }

                // query left/right segments
                if (autoPedestrianLightState == RoadBaseAI.TrafficLightState.Green)
                {
                    bool lhd = Constants.ServiceFactory.SimulationService.LeftHandDrive;
                    foreach (ushort otherSegmentId in lhd ? segmentEndGeometry.IncomingLeftSegments : segmentEndGeometry.IncomingRightSegments)
                    {
                        if (otherSegmentId == 0)
                        {
                            continue;
                        }

#if DEBUGTTL
                        if (debug)
                        {
                            Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Checking left/right segment {otherSegmentId} at seg. {SegmentId} @ {NodeId}");
                        }
#endif

                        ICustomSegmentLights otherLights = LightsManager.GetSegmentLights(nodeId, otherSegmentId);
                        if (otherLights == null)
                        {
#if DEBUGTTL
                            if (debug)
                            {
                                Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Expected other (left/right) CustomSegmentLights at segment {otherSegmentId} @ {NodeId} but there was none. Original segment id: {SegmentId}");
                            }
#endif
                            continue;
                        }

                        ItemClass nextConnectionClass = null;
                        Constants.ServiceFactory.NetService.ProcessSegment(otherSegmentId, delegate(ushort otherSegId, ref NetSegment segment) {
                            nextConnectionClass = segment.Info.GetConnectionClass();
                            return(true);
                        });

                        if (nextConnectionClass.m_service != prevConnectionClass.m_service)
                        {
#if DEBUGTTL
                            if (debug)
                            {
                                Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Other (left/right) segment {otherSegmentId} @ {NodeId} has different connection service than segment {SegmentId} ({nextConnectionClass.m_service} vs. {prevConnectionClass.m_service}). Ignoring traffic light state.");
                            }
#endif
                            continue;
                        }

                        if ((lhd && !otherLights.IsAllRightRed()) || (!lhd && !otherLights.IsAllLeftRed()))
                        {
#if DEBUGTTL
                            if (debug)
                            {
                                Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Not all left red at {otherSegmentId} at seg. {SegmentId} @ {NodeId}");
                            }
#endif
                            autoPedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                            break;
                        }
                    }
                }
            }

            AutoPedestrianLightState = autoPedestrianLightState;
#if DEBUGTTL
            if (debug)
            {
                Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Calculated AutoPedestrianLightState for segment {SegmentId} @ {NodeId}: {AutoPedestrianLightState}");
            }
#endif
        }
Ejemplo n.º 2
0
        public void CalculateAutoPedestrianLightState(ref NetNode node, bool propagate = true)
        {
#if DEBUGTTL
            bool debug = DebugSwitch.TimedTrafficLights.Get() && DebugSettings.NodeId == NodeId;
#endif

#if DEBUGTTL
            if (debug)
            {
                Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Calculating pedestrian light state of seg. {SegmentId} @ node {NodeId}");
            }
#endif

            IExtSegmentManager    segMan    = Constants.ManagerFactory.ExtSegmentManager;
            IExtSegmentEndManager segEndMan = Constants.ManagerFactory.ExtSegmentEndManager;
            ExtSegment            seg       = segMan.ExtSegments[SegmentId];
            ExtSegmentEnd         segEnd    = segEndMan.ExtSegmentEnds[segEndMan.GetIndex(SegmentId, StartNode)];

            ushort nodeId = segEnd.nodeId;
            if (nodeId != NodeId)
            {
                Log.Warning($"CustomSegmentLights.CalculateAutoPedestrianLightState: Node id mismatch! segment end node is {nodeId} but we are node {NodeId}. segEnd={segEnd} this={this}");
                return;
            }

            if (propagate)
            {
                for (int i = 0; i < 8; ++i)
                {
                    ushort otherSegmentId = node.GetSegment(i);
                    if (otherSegmentId == 0 || otherSegmentId == SegmentId)
                    {
                        continue;
                    }

                    ICustomSegmentLights otherLights = LightsManager.GetSegmentLights(nodeId, otherSegmentId);
                    if (otherLights == null)
                    {
#if DEBUGTTL
                        if (debug)
                        {
                            Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Expected other (propagate) CustomSegmentLights at segment {otherSegmentId} @ {NodeId} but there was none. Original segment id: {SegmentId}");
                        }
#endif
                        continue;
                    }

                    otherLights.CalculateAutoPedestrianLightState(ref node, false);
                }
            }

            if (IsAnyGreen())
            {
#if DEBUGTTL
                if (debug)
                {
                    Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Any green at seg. {SegmentId} @ {NodeId}");
                }
#endif
                AutoPedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                return;
            }

#if DEBUGTTL
            if (debug)
            {
                Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Querying incoming segments at seg. {SegmentId} @ {NodeId}");
            }
#endif

            ItemClass prevConnectionClass = null;
            Constants.ServiceFactory.NetService.ProcessSegment(SegmentId, delegate(ushort prevSegId, ref NetSegment segment) {
                prevConnectionClass = segment.Info.GetConnectionClass();
                return(true);
            });

            RoadBaseAI.TrafficLightState autoPedestrianLightState = RoadBaseAI.TrafficLightState.Green;
            bool lhd = Constants.ServiceFactory.SimulationService.LeftHandDrive;
            if (!(segEnd.incoming && seg.oneWay))
            {
                for (int i = 0; i < 8; ++i)
                {
                    ushort otherSegmentId = node.GetSegment(i);
                    if (otherSegmentId == 0 || otherSegmentId == SegmentId)
                    {
                        continue;
                    }

                    //ExtSegment otherSeg = segMan.ExtSegments[otherSegmentId];

                    if (!segEndMan.ExtSegmentEnds[segEndMan.GetIndex(otherSegmentId, (bool)Constants.ServiceFactory.NetService.IsStartNode(otherSegmentId, NodeId))].incoming)
                    {
                        continue;
                    }

#if DEBUGTTL
                    if (debug)
                    {
                        Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Checking incoming straight segment {otherSegmentId} at seg. {SegmentId} @ {NodeId}");
                    }
#endif

                    ICustomSegmentLights otherLights = LightsManager.GetSegmentLights(nodeId, otherSegmentId);
                    if (otherLights == null)
                    {
#if DEBUGTTL
                        if (debug)
                        {
                            Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Expected other (straight) CustomSegmentLights at segment {otherSegmentId} @ {NodeId} but there was none. Original segment id: {SegmentId}");
                        }
#endif
                        continue;
                    }

                    ItemClass nextConnectionClass = null;
                    Constants.ServiceFactory.NetService.ProcessSegment(otherSegmentId, delegate(ushort otherSegId, ref NetSegment segment) {
                        nextConnectionClass = segment.Info.GetConnectionClass();
                        return(true);
                    });

                    if (nextConnectionClass.m_service != prevConnectionClass.m_service)
                    {
#if DEBUGTTL
                        if (debug)
                        {
                            Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Other (straight) segment {otherSegmentId} @ {NodeId} has different connection service than segment {SegmentId} ({nextConnectionClass.m_service} vs. {prevConnectionClass.m_service}). Ignoring traffic light state.");
                        }
#endif
                        continue;
                    }

                    ArrowDirection dir = segEndMan.GetDirection(ref segEnd, otherSegmentId);
                    if (dir == ArrowDirection.Forward)
                    {
                        if (!otherLights.IsAllMainRed())
                        {
#if DEBUGTTL
                            if (debug)
                            {
                                Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Not all main red at {otherSegmentId} at seg. {SegmentId} @ {NodeId}");
                            }
#endif
                            autoPedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                            break;
                        }
                    }
                    else if ((dir == ArrowDirection.Left && lhd) || (dir == ArrowDirection.Right && !lhd))
                    {
                        if ((lhd && !otherLights.IsAllRightRed()) || (!lhd && !otherLights.IsAllLeftRed()))
                        {
#if DEBUGTTL
                            if (debug)
                            {
                                Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Not all left red at {otherSegmentId} at seg. {SegmentId} @ {NodeId}");
                            }
#endif
                            autoPedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                            break;
                        }
                    }
                }
            }

            AutoPedestrianLightState = autoPedestrianLightState;
#if DEBUGTTL
            if (debug)
            {
                Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Calculated AutoPedestrianLightState for segment {SegmentId} @ {NodeId}: {AutoPedestrianLightState}");
            }
#endif
        }