Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions TLM/TLM/Manager/Impl/ExtNodeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ public static bool JunctionHasHighwayRules(ushort nodeId) {
return JunctionHasOnlyHighwayRoads(nodeId) && !LaneConnection.LaneConnectionManager.Instance.Sub.HasNodeConnections(nodeId);
}

public GetNodeSegmentIdsEnumerable GetNodeSegmentIds(ushort nodeId, ClockDirection clockDirection) {
ref NetNode netNode = ref nodeId.ToNode();
var initialSegmentId = GetInitialSegment(ref netNode);
public GetNodeSegmentIdsEnumerable GetNodeSegmentIds(ushort nodeId, ClockDirection clockDirection)
=> GetNodeSegmentIds(nodeId, clockDirection, GetInitialSegment(ref nodeId.ToNode()));

internal GetNodeSegmentIdsEnumerable GetNodeSegmentIds(ushort nodeId, ClockDirection clockDirection, ushort initialSegmentId) {
var segmentBuffer = Singleton<NetManager>.instance.m_segments.m_buffer;
return new GetNodeSegmentIdsEnumerable(nodeId, initialSegmentId, clockDirection, segmentBuffer);
}
Expand Down
117 changes: 111 additions & 6 deletions TLM/TLM/Manager/Impl/JunctionRestrictionsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace TrafficManager.Manager.Impl {
using TrafficManager.Util;
using TrafficManager.Util.Extensions;
using TrafficManager.Lifecycle;
using TrafficManager.Util.Iterators;

public class JunctionRestrictionsManager
: AbstractGeometryObservingManager,
Expand Down Expand Up @@ -632,8 +633,8 @@ public bool IsEnteringBlockedJunctionAllowed(ushort segmentId, bool startNode) {
}

public bool IsPedestrianCrossingAllowedConfigurable(ushort segmentId, bool startNode, ref NetNode node) {
bool ret = (node.m_flags & (NetNode.Flags.Junction | NetNode.Flags.Bend)) != NetNode.Flags.None
&& node.Info?.m_class?.m_service != ItemClass.Service.Beautification;
bool ret = IsNodePedestrianCrossingConfigurable(ref node)
&& IsLikelyPedestrianRoute(segmentId, startNode, true);
#if DEBUG
if (DebugSwitch.JunctionRestrictions.Get()) {
Log._Debug(
Expand All @@ -645,18 +646,23 @@ public bool IsPedestrianCrossingAllowedConfigurable(ushort segmentId, bool start
return ret;
}

private static bool IsNodePedestrianCrossingConfigurable(ref NetNode node) {
return (node.m_flags & (NetNode.Flags.Junction | NetNode.Flags.Bend)) != NetNode.Flags.None
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
at bend nodes pedestrian crossing is configurable. Is this intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a change. The code was simply moved from another location in this commit: Elesbaan70@8e732e6

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Elesbaan70 are bend nodes within the scope of this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say no. That code was only touched to address an issue with the way default values were handled when not configurable. This PR is about segments without pedestrian lanes, and not really related to the type of node. And this is how the code worked before.

In my opinion, it should be configurable anyway.

&& node.Info?.m_class?.m_service != ItemClass.Service.Beautification;
}

public bool GetDefaultPedestrianCrossingAllowed(ushort segmentId, bool startNode, ref NetNode node) {
#if DEBUG
bool logLogic = DebugSwitch.JunctionRestrictions.Get();
#else
const bool logLogic = false;
#endif

if (!IsPedestrianCrossingAllowedConfigurable(segmentId, startNode, ref node)) {
if (!IsNodePedestrianCrossingConfigurable(ref node)) {
if (logLogic) {
Log._Debug(
"JunctionRestrictionsManager.GetDefaultPedestrianCrossingAllowed" +
$"({segmentId}, {startNode}): Setting is not configurable. res=true");
$"({segmentId}, {startNode}): Setting is not configurable for this node type. res=true");
}

return true;
Expand Down Expand Up @@ -703,8 +709,9 @@ public bool GetDefaultPedestrianCrossingAllowed(ushort segmentId, bool startNode

// crossing is allowed at junctions and at untouchable nodes (for example: spiral
// underground parking)
bool ret = (node.m_flags & (NetNode.Flags.Junction | NetNode.Flags.Untouchable)) !=
NetNode.Flags.None;
bool ret = ((node.m_flags & (NetNode.Flags.Junction | NetNode.Flags.Untouchable)) != NetNode.Flags.None
|| !IsNodePedestrianCrossingConfigurable(ref node))
&& IsLikelyPedestrianRoute(segmentId, startNode, false);

if (logLogic) {
Log._Debug(
Expand All @@ -715,6 +722,104 @@ public bool GetDefaultPedestrianCrossingAllowed(ushort segmentId, bool startNode
return ret;
}

private static bool IsLikelyPedestrianRoute(ushort segmentId, bool startNode, bool includeAllReachable) {
#if DEBUG
bool logLogic = DebugSwitch.JunctionRestrictions.Get();
string logHeading = $"IsLikelyPedestrianRoute(segmentId: {segmentId}, startNode: {startNode}, includeAllReachable: {includeAllReachable})\r\t";
#else
const bool logLogic = false;
const string logHeading = null;
#endif

NetSegment segment = segmentId.ToSegment();

if (segment.Info.m_hasPedestrianLanes) {

if (logLogic) {
Log._Debug(logHeading
+ $"segment {segmentId} has pedestrian lanes"
+ $"returning true");
}

return true;
}

ushort nodeId = startNode ? segment.m_startNode : segment.m_endNode;

ushort nearestClockwiseSegId = 0;
int clockwiseDistance = 0;
foreach (var otherSegmentId in ExtNodeManager.Instance.GetNodeSegmentIds(nodeId, ClockDirection.Clockwise, segmentId)) {
if (otherSegmentId.ToSegment().Info.m_hasPedestrianLanes) {
nearestClockwiseSegId = otherSegmentId;
break;
}
++clockwiseDistance;
}

if (nearestClockwiseSegId == 0) {

if (logLogic) {
Log._Debug(logHeading
+ $"no pedestrian lanes on node {nodeId}"
+ $"returning false");
}

return false;
}

if (includeAllReachable) {

if (logLogic) {
Log._Debug(logHeading
+ $"pedestrian lanes found on segment {nearestClockwiseSegId}"
+ $"returning true");
}

return true;
}

ushort nearestCounterClockwiseSegId = 0;
int counterClockwiseDistance = 0;
foreach (var otherSegmentId in ExtNodeManager.Instance.GetNodeSegmentIds(nodeId, ClockDirection.CounterClockwise, segmentId)) {
if (otherSegmentId.ToSegment().Info.m_hasPedestrianLanes) {
nearestCounterClockwiseSegId = otherSegmentId;
break;
}
++counterClockwiseDistance;
}

if (nearestCounterClockwiseSegId == 0 || nearestClockwiseSegId == nearestCounterClockwiseSegId) {

if (logLogic) {
Log._Debug(logHeading
+ $"no pedestrian lanes on segment {segmentId}"
+ $"only one segment on node {nodeId} has pedestrian lanes"
+ $"returning false");
}

return false;
}

int distanceThisSide = clockwiseDistance + counterClockwiseDistance - 1;
int distanceOtherSide = 0;
foreach (var otherSegmentId in ExtNodeManager.Instance.GetNodeSegmentIds(nodeId, ClockDirection.Clockwise, nearestClockwiseSegId)) {
++distanceOtherSide;
if (otherSegmentId == nearestCounterClockwiseSegId)
break;
}

bool result = distanceThisSide < distanceOtherSide;

if (logLogic) {
Log._Debug(logHeading
+ $"segments with pedestrian lanes - clockwise: {nearestClockwiseSegId}, counter-clockwise: {nearestCounterClockwiseSegId}\r\t"
+ $"distanceThisSide: {distanceThisSide}, distanceOtherSide: {distanceOtherSide}\r\t"
+ $"returning {result}");
}

return result;
}

public bool IsPedestrianCrossingAllowed(ushort segmentId, bool startNode) {
return segmentRestrictions[segmentId].GetValueOrDefault(JunctionRestrictionFlags.AllowPedestrianCrossing, startNode);
}
Expand Down