From 6f9825efe5994bea9196fa1b38ef7dc71b19c0e1 Mon Sep 17 00:00:00 2001 From: Helge Neumann Date: Sat, 4 Jul 2026 13:24:48 +0200 Subject: [PATCH] Account for articulated harvester components when moving out of the way When the unloader moves away from a blocking CP combine, the parallel course offset was computed from the work width around the AI direction node only. Articulated harvesters (e.g. the spinach harvester) can stand bent, with the rear component sticking out sideways well beyond that, so the unloader kept touching the rear part and never got past. Include the lateral extent of all components of the blocking vehicle in the offset calculation. Co-Authored-By: Claude Fable 5 --- .../ai/strategies/AIDriveStrategyUnloadCombine.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/scripts/ai/strategies/AIDriveStrategyUnloadCombine.lua b/scripts/ai/strategies/AIDriveStrategyUnloadCombine.lua index eecc77c8..5f1ab4b2 100644 --- a/scripts/ai/strategies/AIDriveStrategyUnloadCombine.lua +++ b/scripts/ai/strategies/AIDriveStrategyUnloadCombine.lua @@ -2175,7 +2175,16 @@ function AIDriveStrategyUnloadCombine:onBlockingVehicle(blockingVehicle, isBack) -- with an offset from the combine that makes sure we are clear. Use the trailer's root node (and not -- the tractor's) as when we reversing, it is easier when the trailer remains on the same side of the combine local dx, _, _ = localToLocal(referenceObject.rootNode, blockingVehicle:getAIDirectionNode(), 0, 0, 0) - local xOffset = self.vehicle.size.width / 2 + blockingVehicle:getCpDriveStrategy():getWorkWidth() / 2 + 2 + -- articulated harvesters can stand bent, with the rear part sticking out sideways from + -- the direction node - make sure the offset also clears the widest component, not just + -- the work width around the front part + local maxComponentOffset = 0 + for _, component in pairs(blockingVehicle.components) do + local cdx, _, _ = localToLocal(component.node, blockingVehicle:getAIDirectionNode(), 0, 0, 0) + maxComponentOffset = math.max(maxComponentOffset, math.abs(cdx) + blockingVehicle.size.width / 2) + end + local xOffset = self.vehicle.size.width / 2 + + math.max(blockingVehicle:getCpDriveStrategy():getWorkWidth() / 2, maxComponentOffset) + 2 xOffset = dx > 0 and xOffset or -xOffset self:setNewState(self.states.MOVING_AWAY_FROM_OTHER_VEHICLE) self.state.properties.vehicle = blockingVehicle