@@ -28,10 +28,10 @@ AIDriveStrategyFieldWorkCourse.myStates = {
2828 WAITING_FOR_LOWER_DELAYED = {},
2929 WAITING_FOR_STOP = {},
3030 WAITING_FOR_WEATHER = {},
31- TURNING = {showTurnContextDebug = true },
31+ TURNING = { showTurnContextDebug = true },
3232 TEMPORARY = {},
3333 RETURNING_TO_START = {},
34- DRIVING_TO_WORK_START_WAYPOINT = {showTurnContextDebug = true },
34+ DRIVING_TO_WORK_START_WAYPOINT = { showTurnContextDebug = true },
3535}
3636
3737AIDriveStrategyFieldWorkCourse .normalFillLevelFullPercentage = 99.5
@@ -94,7 +94,7 @@ function AIDriveStrategyFieldWorkCourse:start(course, startIx, jobParameters)
9494 --- Store a reference to the original generated course
9595 self .originalGeneratedFieldWorkCourse = self .vehicle :getFieldWorkCourse ()
9696
97- if self .fieldPolygon == nil then
97+ if self .fieldPolygon == nil then
9898 self :debug (" No field polygon received, so regenerate it by the course." )
9999 self .fieldPolygon = self .fieldWorkCourse :getFieldPolygon ()
100100 end
114114function AIDriveStrategyFieldWorkCourse :update (dt )
115115 AIDriveStrategyCourse .update (self , dt )
116116 if CpDebug :isChannelActive (CpDebug .DBG_TURN , self .vehicle ) then
117- if self .state == self .states .TURNING then
117+ if self .state == self .states .TURNING then
118118 if self .aiTurn then
119119 self .aiTurn :drawDebug ()
120120 end
@@ -188,7 +188,9 @@ function AIDriveStrategyFieldWorkCourse:getDriveData(dt, vX, vY, vZ)
188188 self :setMaxSpeed (turnMaxSpeed )
189189 -- if turn tells us which way to go, use that, otherwise just do whatever PPC tells us
190190 gx , gz = turnGx or gx , turnGz or gz
191- if turnMoveForwards ~= nil then moveForwards = turnMoveForwards end
191+ if turnMoveForwards ~= nil then
192+ moveForwards = turnMoveForwards
193+ end
192194 elseif self .state == self .states .RETURNING_TO_START then
193195 local isReadyToDrive , blockingVehicle = self .vehicle :getIsAIReadyToDrive ()
194196 if isReadyToDrive or not self .waitingForPrepare :get () then
@@ -263,7 +265,8 @@ function AIDriveStrategyFieldWorkCourse:initializeImplementControllers(vehicle)
263265
264266 self :addImplementController (vehicle , PickupController , Pickup , defaultDisabledStates )
265267 self :addImplementController (vehicle , SprayerController , Sprayer , {})
266- self :addImplementController (vehicle , CutterController , Cutter , {}) --- Makes sure the cutter timer gets reset always.
268+ self :addImplementController (vehicle , CutterController , Cutter , {})
269+ --- Makes sure the cutter timer gets reset always.
267270 self :addImplementController (vehicle , StonePickerController , StonePicker , defaultDisabledStates )
268271
269272 self :addImplementController (vehicle , FoldableController , Foldable , {})
@@ -312,7 +315,9 @@ function AIDriveStrategyFieldWorkCourse:shouldRaiseThisImplement(object, turnSta
312315 local aiFrontMarker , _ , aiBackMarker = WorkWidthUtil .getAIMarkers (object , true )
313316 -- if something (like a combine) does not have an AI marker it should not prevent from raising other implements
314317 -- like the header, which does have markers), therefore, return true here
315- if not aiBackMarker or not aiFrontMarker then return true end
318+ if not aiBackMarker or not aiFrontMarker then
319+ return true
320+ end
316321 local marker = self :getImplementRaiseLate () and aiBackMarker or aiFrontMarker
317322 -- turn start node in the back marker node's coordinate system
318323 local _ , _ , dz = localToLocal (marker , turnStartNode , 0 , 0 , 0 )
355360--- in meters (<0) when driving forward, nil when driving backwards.
356361function AIDriveStrategyFieldWorkCourse :shouldLowerThisImplement (object , workStartNode , reversing )
357362 local aiLeftMarker , aiRightMarker , aiBackMarker = WorkWidthUtil .getAIMarkers (object , true )
358- if not aiLeftMarker then return false , false , nil end
363+ if not aiLeftMarker then
364+ return false , false , nil
365+ end
359366 local dxLeft , _ , dzLeft = localToLocal (aiLeftMarker , workStartNode , 0 , 0 , 0 )
360367 local dxRight , _ , dzRight = localToLocal (aiRightMarker , workStartNode , 0 , 0 , 0 )
361368 local dxBack , _ , dzBack = localToLocal (aiBackMarker , workStartNode , 0 , 0 , 0 )
408415
409416function AIDriveStrategyFieldWorkCourse :isThisImplementAligned (object , node )
410417 local aiFrontMarker , _ , _ = WorkWidthUtil .getAIMarkers (object , true )
411- if not aiFrontMarker then return true end
418+ if not aiFrontMarker then
419+ return true
420+ end
412421 return CpMathUtil .isSameDirection (aiFrontMarker , node , 5 )
413422end
414423
@@ -426,7 +435,8 @@ function AIDriveStrategyFieldWorkCourse:onWaypointChange(ix, course)
426435 end
427436 self :startTurn (ix )
428437 elseif self .state == self .states .WORKING then
429- if self .course :isOnConnectingPath (ix + 1 ) or self .course :shouldUsePathfinderToNextWaypoint (ix ) then
438+ if (self .course :isOnConnectingPath (ix + 1 ) and not self .course :isOnConnectingPath (ix )) or
439+ self .course :shouldUsePathfinderToNextWaypoint (ix ) then
430440 local fm , bm = self :getFrontAndBackMarkers ()
431441 self .turnContext = RowStartOrFinishContext (self .vehicle , self .course , ix , ix , self .turnNodes , self :getWorkWidth (),
432442 fm , bm , 0 , 0 )
626636---- -------------------------------------------------------------------------------------------------------------------
627637function AIDriveStrategyFieldWorkCourse :startPathfindingToNextWaypoint (ix )
628638 self :debug (' start pathfinding to waypoint %d' , ix + 1 )
629- self :raiseImplements ()
630639 local fm , bm = self :getFrontAndBackMarkers ()
631640 self .turnContext = RowStartOrFinishContext (self .vehicle , self .fieldWorkCourse , ix + 1 , ix + 1 ,
632641 self .turnNodes , self :getWorkWidth (), fm , bm , self :getTurnEndSideOffset (), self :getTurnEndForwardOffset ())
@@ -643,10 +652,17 @@ function AIDriveStrategyFieldWorkCourse:startPathfindingToNextWaypoint(ix)
643652 self .pathfinderController :findPathToNode (context , targetNode , 0 , zOffset )
644653end
645654
646- function AIDriveStrategyFieldWorkCourse :onPathfindingFailedToNextWaypoint ()
647- self :debug (' Pathfinding to next waypoint failed, continue directly at waypoint %d' , self .waypointToContinueOnFailedPathfinding )
648- self .state = self .states .WORKING
649- self :startCourse (self .fieldWorkCourse , self .waypointToContinueOnFailedPathfinding )
655+ function AIDriveStrategyFieldWorkCourse :onPathfindingFailedToNextWaypoint (controller , lastContext , wasLastRetry , currentRetryAttempt )
656+ if wasLastRetry then
657+ self :debug (' Pathfinding to next waypoint failed again, continue directly at waypoint %d' , self .waypointToContinueOnFailedPathfinding )
658+ self :startWaitingForLower ()
659+ self :lowerImplements ()
660+ self :startCourse (self .fieldWorkCourse , self .waypointToContinueOnFailedPathfinding )
661+ else
662+ self :debug (' Pathfinding to next waypoint failed once, retry with disabled collisions' )
663+ lastContext :collisionMask (0 )
664+ controller :retry (lastContext )
665+ end
650666end
651667
652668function AIDriveStrategyFieldWorkCourse :onPathfindingDoneToNextWaypoint (controller , success , course , goalNodeInvalid )
@@ -663,22 +679,24 @@ end
663679---- -------------------------------------------------------------------------------------------------------------------
664680function AIDriveStrategyFieldWorkCourse :startConnectingPath (ix )
665681 -- ix was the last waypoint to work before the connecting path, ix + 1 is the first on the connecting path
666- self :debug (' on a connecting path now at waypoint %d, raising implements.' , ix + 1 )
667- self :raiseImplements ()
682+ self :debug (' Row finished before starting on a connecting path at waypoint %d.' , ix + 1 )
668683 -- gather the connecting path waypoints
669684 local connectingPath = {}
670685 local targetWaypointIx
671686 for i = ix + 1 , self .fieldWorkCourse :getNumberOfWaypoints () do
672687 if self .fieldWorkCourse :isOnConnectingPath (i ) then
673688 local x , _ , z = self .fieldWorkCourse :getWaypointPosition (i )
674- table.insert (connectingPath , {x = x , z = z })
689+ table.insert (connectingPath , { x = x , z = z })
675690 else
676691 targetWaypointIx = i
677692 break
678693 end
679694 end
680695 if targetWaypointIx == nil then
681- self :onPathfindingFailedToConnectingPathEnd ()
696+ self :debug (' Can\' t find end of connecting path, continuing work' )
697+ self :startWaitingForLower ()
698+ self :lowerImplements ()
699+ self :startCourse (self .fieldWorkCourse , ix + 1 )
682700 else
683701 -- set up the turn context for the work starter to use when the pathfinding succeeds
684702 local fm , bm = self :getFrontAndBackMarkers ()
@@ -688,28 +706,34 @@ function AIDriveStrategyFieldWorkCourse:startConnectingPath(ix)
688706 local targetNode , zOffset = self .turnContext :getTurnEndNodeAndOffsets (steeringLength )
689707 local context = PathfinderContext (self .vehicle ):allowReverse (self :getAllowReversePathfinding ())
690708 context :preferredPath (connectingPath ):mustBeAccurate (true )
691- self .waypointToContinueOnFailedPathfinding = ix + 1
709+ self .rawConnectingPath = Course ( self . vehicle , connectingPath , true )
692710 self .pathfinderController :registerListeners (self , self .onPathfindingDoneToConnectingPathEnd ,
693711 self .onPathfindingFailedToConnectingPathEnd )
694712 self :debug (' Connecting path has %d waypoints, start pathfinding to target waypoint %d, zOffset %.1f' ,
695713 # connectingPath , targetWaypointIx , zOffset )
696714 self .state = self .states .WAITING_FOR_PATHFINDER
697- self .pathfinderController :findPathToNode (context , targetNode , 0 , zOffset )
715+ self .pathfinderController :findPathToNode (context , targetNode , 0 , zOffset , 1 )
698716 end
699717end
700718
701- function AIDriveStrategyFieldWorkCourse :onPathfindingFailedToConnectingPathEnd ()
702- self :debug (' Pathfinding to end of connecting path failed, use the connecting path as is' )
703- self .state = self .states .WORKING
704- self :startCourse (self .fieldWorkCourse , self .waypointToContinueOnFailedPathfinding )
719+ function AIDriveStrategyFieldWorkCourse :onPathfindingFailedToConnectingPathEnd (controller , lastContext , wasLastRetry , currentRetryAttempt )
720+ if wasLastRetry then
721+ self :debug (' Pathfinding to end of connecting path failed again, use the connecting path as is' )
722+ self :startCourseToWorkStart (self .rawConnectingPath )
723+ else
724+ self :debug (' Pathfinding to end of connecting path failed once, retry with disabled collisions' )
725+ lastContext :collisionMask (0 )
726+ controller :retry (lastContext )
727+ end
705728end
706729
707730function AIDriveStrategyFieldWorkCourse :onPathfindingDoneToConnectingPathEnd (controller , success , course , goalNodeInvalid )
708731 if success then
709732 self :debug (' Pathfinding to end of connecting path finished' )
710733 self :startCourseToWorkStart (course )
711734 else
712- self :onPathfindingFailedToConnectingPathEnd ()
735+ self :debug (' Pathfinding to end of connecting path failed, use the connecting path as is' )
736+ self :startCourseToWorkStart (self .rawConnectingPath )
713737 end
714738end
715739
@@ -732,7 +756,7 @@ function AIDriveStrategyFieldWorkCourse:setAllStaticParameters()
732756end
733757
734758function AIDriveStrategyFieldWorkCourse :setFieldPolygon (polygon )
735- self .fieldPolygon = polygon
759+ self .fieldPolygon = polygon
736760end
737761
738762---- -------------------------------------------------------------------------------------------------------------------
0 commit comments