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
80 changes: 59 additions & 21 deletions DVRouteManager/LocoAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,29 @@ public bool StartAI(RouteTracker routeTracker)
return true;
}

private IEnumerator ReleaseAllBrakes()
{
//// ── Release handbrakes on wagons ─────────────────────────────
//foreach (TrainCar car in loco.trainset.cars)
//{
// if (!car.IsLoco && car.brakeSystem.hasHandbrake)
// {
// car.brakeSystem.SetHandbrakePosition(0f);
// Terminal.Log($"Released handbrake on {car.logicCar.ID}");
// }
//}

// ── Release loco brakes (train + independent) ────────────────
// Use a loop to step them down smoothly
for (int i = 0; i < 10; i++)
{
remoteControl.UpdateIndependentBrake(-1.0f);
remoteControl.UpdateBrake(-1.0f);

yield return new WaitForSeconds(0.3f);
}
}

private IEnumerator AICoroutine()
{
const float TIME_WAIT = 0.3f;
Expand All @@ -250,6 +273,8 @@ private IEnumerator AICoroutine()

RouteTracker.TrackingState lastState = RouteTracker.TrackState;

yield return ReleaseAllBrakes();

while (running)
{
float speed = Mathf.Abs(remoteControl.GetForwardSpeed() * 3.6f);
Expand Down Expand Up @@ -390,6 +415,8 @@ IEnumerator Reverse()
yield return null;
remoteControl.UpdateReverser(direction ? ToggleDirection.DOWN : ToggleDirection.UP);
yield return null;

yield return ReleaseAllBrakes();
}

IEnumerator BrakePulse(int level, float waitTime)
Expand Down Expand Up @@ -446,35 +473,46 @@ private IEnumerator FreightHaulCoroutine(RouteTask task, TrainCar loco)
Track carTrack = freightTrainset.firstCar.Bogies[0].track.LogicTrack();
Track locoTrack = loco.trainset.firstCar.Bogies[0].track.LogicTrack();

var toCarsTask = Route.FindRoute(locoTrack, carTrack, ReversingStrategy.ChooseBest, loco.trainset);
while (!toCarsTask.IsCompleted) yield return null;
bool alreadyCoupled = loco.trainset == freightTrainset;

if (!_freightHaulActive) yield break;

if (toCarsTask.IsFaulted || toCarsTask.Result == null)
if (loco.trainset == freightTrainset)
{
Terminal.Log("Freight haul: cannot find route to cars – " + (toCarsTask.Exception?.InnerException?.Message ?? "null"));
_freightHaulActive = false;
yield break;
Terminal.Log("Freight haul: already coupled to target trainset, skipping routing to cars");
}
else
{

var chain1 = RouteTaskChain.FromDestination(carTrack, loco.trainset);
var tracker1 = new RouteTracker(chain1, true);
tracker1.SetRoute(toCarsTask.Result, loco.trainset);
Module.ActiveRoute.Route = toCarsTask.Result;
Module.ActiveRoute.RouteTracker = tracker1;
var toCarsTask = Route.FindRoute(locoTrack, carTrack, ReversingStrategy.ChooseBest, loco.trainset);
while (!toCarsTask.IsCompleted) yield return null;

StartAI(tracker1);
while (running && _freightHaulActive) yield return null;
if (!_freightHaulActive) yield break;

if (!_freightHaulActive) { Stop(); yield break; }
if (toCarsTask.IsFaulted || toCarsTask.Result == null)
{
Terminal.Log("Freight haul: cannot find route to cars – " + (toCarsTask.Exception?.InnerException?.Message ?? "null"));
_freightHaulActive = false;
yield break;
}

// ── Phase 2: couple and release handbrakes ───────────────────────
Terminal.Log("Freight haul: phase 2 – coupling");
yield return TryCoupleAndReleaseHandbrakes(loco);
yield return new WaitForSeconds(1.5f);
var chain1 = RouteTaskChain.FromDestination(carTrack, loco.trainset);
var tracker1 = new RouteTracker(chain1, true);
tracker1.SetRoute(toCarsTask.Result, loco.trainset);
Module.ActiveRoute.Route = toCarsTask.Result;
Module.ActiveRoute.RouteTracker = tracker1;

if (!_freightHaulActive) yield break;
StartAI(tracker1);
while (running && _freightHaulActive) yield return null;

if (!_freightHaulActive) { Stop(); yield break; }

// ── Phase 2: couple and release handbrakes ───────────────────────
Terminal.Log("Freight haul: phase 2 – coupling");
yield return TryCoupleAndReleaseHandbrakes(loco);
yield return new WaitForSeconds(1.5f);

if (!_freightHaulActive) yield break;

}

// ── Phase 3: drive to destination ────────────────────────────────
Terminal.Log($"Freight haul: phase 3 – routing to {task.DestinationTrack.ID.FullID}");
Expand Down
6 changes: 3 additions & 3 deletions DVRouteManager/LocoCruiseControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,9 @@ protected float MaintainSpeed(float targetAcceleration, float dt, float speed, f
}

if (error < -3.0f || TargetSpeed < Mathf.Epsilon)
remoteControl.UpdateIndependentBrake(0.3f * error * -1.0f * dt);
else if (remoteControl.GetTargetIndependentBrake() > Mathf.Epsilon)
remoteControl.UpdateIndependentBrake(-30.0f * dt);
remoteControl.UpdateBrake(0.3f * error * -1.0f * dt);
else if (remoteControl.GetTargetBrake() > Mathf.Epsilon)
remoteControl.UpdateBrake(-30.0f * dt);

remoteControl.UpdateThrottle(ThrottleCurveFactor(remoteControl.GetTargetThrottle(), controlValue > 0.0f) * controlValue);

Expand Down