Skip to content

Commit

Permalink
Fixed: Path-finding fails for citizens at outside connections
Browse files Browse the repository at this point in the history
Parking AI: Improved park & ride behavior
Parking AI: Walking paths from parking position to destination building take public transportation into account
  • Loading branch information
VictorPhilipp committed Jul 14, 2018
1 parent 529ca64 commit e8d4b0d
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 212 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ User manual: http://www.viathinksoft.de/tmpe/wiki

# Changelog
1.10.10, 07/14/2018
- Parking AI: Improved park & ride behavior
- Parking AI: Walking paths from parking position to destination building take public transportation into account
- Bugfix: Parking AI causes unnecessary path-findings (#183, thanks to Sipke82 for reporting)
- Bugfix: Prohibiting cims from crossing the road also affect paths where crossing is unnecessary (#168, thanks to aubergine10 for reporting)

Expand Down
420 changes: 224 additions & 196 deletions TLM/TLM/Custom/AI/CustomCitizenAI.cs

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions TLM/TLM/Custom/AI/CustomPassengerCarAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,12 @@ public bool ExtStartPathFind(ushort vehicleID, ref Vehicle vehicleData, ushort d
skipQueue = true;

bool allowTourists = false;
bool searchAtCurrentPos = false;
if (driverExtInstance.pathMode == ExtPathMode.ParkingFailed) {
// previous parking attempt failed
driverExtInstance.pathMode = ExtPathMode.CalculatingCarPathToAltParkPos;
allowTourists = true;
searchAtCurrentPos = true;

#if DEBUG
if (debug)
Expand Down Expand Up @@ -217,7 +219,7 @@ public bool ExtStartPathFind(ushort vehicleID, ref Vehicle vehicleData, ushort d
bool calcEndPos;
Vector3 parkPos;

if (AdvancedParkingManager.Instance.FindParkingSpaceForCitizen(endPos, vehicleData.Info, ref driverExtInstance, homeId, targetBuildingId == homeId, vehicleID, allowTourists, out parkPos, ref endPosA, out calcEndPos)) {
if (AdvancedParkingManager.Instance.FindParkingSpaceForCitizen(searchAtCurrentPos ? vehicleData.GetLastFramePosition() : endPos, vehicleData.Info, ref driverExtInstance, homeId, targetBuildingId == homeId, vehicleID, allowTourists, out parkPos, ref endPosA, out calcEndPos)) {
calculateEndPos = calcEndPos;
allowRandomParking = false;
movingToParkingPos = true;
Expand Down Expand Up @@ -548,7 +550,9 @@ internal bool ExtParkVehicle(ushort vehicleID, ref Vehicle vehicleData, uint dri

if (!foundParkingSpace && (driverExtInstance.pathMode == ExtCitizenInstance.ExtPathMode.DrivingToAltParkPos || driverExtInstance.pathMode == ExtCitizenInstance.ExtPathMode.DrivingToKnownParkPos) && targetBuildingId != 0) {
// increase parking space demand of target building
ExtBuildingManager.Instance.ExtBuildings[targetBuildingId].AddParkingSpaceDemand(GlobalConfig.Instance.ParkingAI.FailedParkingSpaceDemandIncrement * (uint)driverExtInstance.failedParkingAttempts);
if (driverExtInstance.failedParkingAttempts > 1) {
ExtBuildingManager.Instance.ExtBuildings[targetBuildingId].AddParkingSpaceDemand(GlobalConfig.Instance.ParkingAI.FailedParkingSpaceDemandIncrement * (uint)(driverExtInstance.failedParkingAttempts - 1));
}
}

if (! foundParkingSpace) {
Expand Down
21 changes: 15 additions & 6 deletions TLM/TLM/Custom/PathFinding/CustomPathFind2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -819,12 +819,21 @@ private void ProcessItemMain(BufferItem item, ref NetSegment prevSegment, ref Ne
} else {
// pocket car spawning
#if PARKINGAI
if (Options.prohibitPocketCars &&
m_queueItem.vehicleType == ExtVehicleType.PassengerCar &&
(m_queueItem.pathType == ExtCitizenInstance.ExtPathType.WalkingOnly ||
(m_queueItem.pathType == ExtCitizenInstance.ExtPathType.DrivingOnly && item.m_position.m_segment != m_startSegmentA && item.m_position.m_segment != m_startSegmentB))) {
/* disallow pocket cars on walking paths, allow only if a driving path is required and we reached the start segment */
allowPedestrian = false;
if (
Options.prohibitPocketCars
) {
if (
(m_queueItem.pathType == ExtCitizenInstance.ExtPathType.WalkingOnly && prevIsCarLane) ||
(
m_queueItem.pathType == ExtCitizenInstance.ExtPathType.DrivingOnly &&
m_queueItem.vehicleType == ExtVehicleType.PassengerCar &&
((item.m_position.m_segment != m_startSegmentA && item.m_position.m_segment != m_startSegmentB) || !prevIsCarLane)
)
) {
/* allow pocket cars only if an instant driving path is required and we are at the start segment */
/* disallow pocket cars on walking paths */
allowPedestrian = false;
}
} else {
#endif
switchConnectOffset = (byte)m_pathRandomizer.UInt32(1u, 254u);
Expand Down
8 changes: 6 additions & 2 deletions TLM/TLM/Manager/IAdvancedParkingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@ public enum CarUsagePolicy {
/// </summary>
Allowed,
/// <summary>
/// Citizens are forced to use their car
/// Citizens are forced to use their parked car
/// </summary>
Forced,
ForcedParked,
/// <summary>
/// Citizens are forced to use a pocket car
/// </summary>
ForcedPocket,
/// <summary>
/// Citizens are forbidden to use their car
/// </summary>
Expand Down
38 changes: 33 additions & 5 deletions TLM/TLM/Manager/Impl/AdvancedParkingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ protected ExtSoftPathState OnCitizenPathFindSuccess(ushort instanceId, ref Citiz
bool usesPublicTransport = (laneTypes & (byte)(NetInfo.LaneType.PublicTransport)) != 0;
bool usesCar = (laneTypes & (byte)(NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) != 0 && (vehicleTypes & (ushort)(VehicleInfo.VehicleType.Car)) != 0;

if (usesPublicTransport && usesCar && extInstance.pathMode == ExtPathMode.CalculatingCarPathToKnownParkPos) {
if (usesPublicTransport && usesCar && (extInstance.pathMode == ExtPathMode.CalculatingCarPathToKnownParkPos || extInstance.pathMode == ExtPathMode.CalculatingCarPathToAltParkPos)) {
/*
* when using public transport together with a car (assuming a "source -> walk -> drive -> walk -> use public transport -> walk -> target" path)
* discard parking space information since the cim has to park near the public transport stop
Expand Down Expand Up @@ -563,7 +563,6 @@ protected ExtSoftPathState OnCitizenPathFindSuccess(ushort instanceId, ref Citiz
Log._Debug($"AdvancedParkingManager.OnCitizenPathFindSuccess({instanceId}): Path for citizen instance {instanceId} contains passenger car section. Ensuring that citizen is allowed to use their car.");
#endif

// check if citizen is at an outside connection
ushort sourceBuildingId = instanceData.m_sourceBuilding;
ushort homeId = Singleton<CitizenManager>.instance.m_citizens.m_buffer[instanceData.m_citizen].m_homeBuilding;

Expand Down Expand Up @@ -686,8 +685,33 @@ protected ExtSoftPathState OnCitizenPathFindSuccess(ushort instanceId, ref Citiz
if (debug)
Log._Debug($"AdvancedParkingManager.OnCitizenPathFindSuccess({instanceId}): Path for citizen instance {instanceId} contains passenger car section and citizen should stand in front of their car.");
#endif

if (parkedVehicleId == 0) {
if (
Constants.ManagerFactory.ExtCitizenInstanceManager.IsAtOutsideConnection(instanceId, ref instanceData, ref citizenData) &&
Singleton<BuildingManager>.instance.m_buildings.m_buffer[instanceData.m_sourceBuilding].Info.m_class.m_service == ItemClass.Service.Road
) {
// car path calculated starting at road outside connection: success
if (extInstance.pathMode == ExtPathMode.CalculatingCarPathToAltParkPos) {
extInstance.pathMode = ExtPathMode.DrivingToAltParkPos;
extInstance.parkingPathStartPosition = null;
#if DEBUG
if (debug)
Log._Debug($"AdvancedParkingManager.OnCitizenPathFindSuccess({instanceId}): Path to an alternative parking position is READY! CurrentPathMode={extInstance.pathMode}");
#endif
} else if (extInstance.pathMode == ExtPathMode.CalculatingCarPathToTarget) {
extInstance.pathMode = ExtPathMode.DrivingToTarget;
#if DEBUG
if (debug)
Log._Debug($"AdvancedParkingManager.OnCitizenPathFindSuccess({instanceId}): Car path is READY! CurrentPathMode={extInstance.pathMode}");
#endif
} else if (extInstance.pathMode == ExtPathMode.CalculatingCarPathToKnownParkPos) {
extInstance.pathMode = ExtPathMode.DrivingToKnownParkPos;
#if DEBUG
if (debug)
Log._Debug($"AdvancedParkingManager.OnCitizenPathFindSuccess({instanceId}): Car path to known parking position is READY! CurrentPathMode={extInstance.pathMode}");
#endif
}
return ExtSoftPathState.Ready;
} else if (parkedVehicleId == 0) {
// error! could not find/spawn parked car
#if DEBUG
if (debug)
Expand Down Expand Up @@ -1670,7 +1694,11 @@ public string EnrichLocalizedCarStatus(string ret, ref ExtCitizenInstance driver
if (driverExtInstance.IsValid()) {
switch (driverExtInstance.pathMode) {
case ExtPathMode.DrivingToAltParkPos:
ret = Translation.GetString("Driving_to_another_parking_spot") + " (#" + driverExtInstance.failedParkingAttempts + "), " + ret;
if (driverExtInstance.failedParkingAttempts <= 1) {
ret = Translation.GetString("Looking_for_a_parking_spot") + ", " + ret;
} else {
ret = Translation.GetString("Driving_to_another_parking_spot") + " (#" + driverExtInstance.failedParkingAttempts + "), " + ret;
}
break;
case ExtPathMode.CalculatingCarPathToKnownParkPos:
case ExtPathMode.DrivingToKnownParkPos:
Expand Down
2 changes: 1 addition & 1 deletion TLM/TLM/Traffic/Data/ExtCitizenInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ internal bool CalculateReturnPath(Vector3 parkPos, Vector3 targetPos) {
args.endPosA = targetPathPos;
args.endPosB = dummyPathPos;
args.vehiclePosition = dummyPathPos;
args.laneTypes = NetInfo.LaneType.Pedestrian;
args.laneTypes = NetInfo.LaneType.Pedestrian | NetInfo.LaneType.PublicTransport;
args.vehicleTypes = VehicleInfo.VehicleType.None;
args.maxLength = 20000f;
args.isHeavyVehicle = false;
Expand Down

0 comments on commit e8d4b0d

Please sign in to comment.