@@ -26,12 +26,16 @@ AIDriveStrategyCourse.myStates = {
2626 INITIAL = {},
2727 WAITING_FOR_PATHFINDER = {},
2828 WAITING_FOR_FIELD_BOUNDARY_DETECTION = {},
29+ PRE_FINISHED = {},
30+ WAITING_FOR_FINISHED = {},
31+ FINISHED = {}
2932}
3033
3134--- Implement controller events.
3235--- TODO_25 a more generic implementation
3336AIDriveStrategyCourse .onRaisingEvent = " onRaising"
3437AIDriveStrategyCourse .onLoweringEvent = " onLowering"
38+ AIDriveStrategyCourse .onPreFinishedEvent = " onPreFinished"
3539AIDriveStrategyCourse .onFinishedEvent = " onFinished"
3640AIDriveStrategyCourse .onStartEvent = " onStart"
3741AIDriveStrategyCourse .onStartRefillingEvent = " onStartRefilling"
@@ -59,6 +63,11 @@ function AIDriveStrategyCourse:init(task, job)
5963
6064 self .currentTask = task
6165 self .job = job
66+ self .stopRequestData = {
67+ reason = nil ,
68+ waitForFolding = false ,
69+ prepareTimeout = CpTemporaryObject (true )
70+ }
6271end
6372
6473function AIDriveStrategyCourse :setCurrentTaskFinished ()
279288
280289--- Called in the low frequency function for the helper.
281290function AIDriveStrategyCourse :updateLowFrequencyImplementControllers ()
291+ if self :hasFinished () then
292+ --- Small hack so every ai drive strategy waits during finished.
293+ self :setMaxSpeed (0 )
294+ end
282295 for _ , controller in pairs (self .controllers ) do
283296 --- @type ImplementController
284297 if controller :isEnabled () then
@@ -435,8 +448,57 @@ function AIDriveStrategyCourse:update(dt)
435448 self .pathfinderController :update (dt )
436449 self :updatePathfinding ()
437450 self :updateInfoTexts ()
451+ self :updateFinishing ()
452+ end
453+
454+ function AIDriveStrategyCourse :updateFinishing ()
455+ local function finishStrategy ()
456+ if self .stopRequestData .stopReason then
457+ g_currentMission .aiSystem :stopJob (self .job , self .stopRequestData .stopReason )
458+ return
459+ end
460+ self .currentTask :skip ()
461+ end
462+ if self .state == self .states .PRE_FINISHED then
463+ --- Every implement controller gets the chance to
464+ --- prepare for the driver release.
465+ --- For example balers can unload their bales
466+ --- before we can fold them and so on.
467+ local finished = true
468+ for _ , controller in ipairs (self .controllers ) do
469+ finished = finished and controller :onPreFinished ()
470+ end
471+ if finished then
472+ self :debug (" Precondition for stopping the strategy are reached." )
473+ self .state = self .states .FINISHED
474+ end
475+ elseif self .state == self .states .FINISHED then
476+ self :raiseControllerEvent (self .onFinishedEvent , self .stopRequestData .waitForFolding )
477+ if self .stopRequestData .waitForFolding then
478+ self :debug (" Starting to fold implements and so on..." )
479+ self .vehicle :prepareForAIDriving ()
480+ self .stopRequestData .prepareTimeout :set (false , 15000 )
481+ self .state = self .states .WAITING_FOR_FINISHED
482+ else
483+ finishStrategy ()
484+ end
485+ elseif self .state == self .states .WAITING_FOR_FINISHED then
486+ if not self .vehicle :getIsAIPreparingToDrive () or self .stopRequestData .prepareTimeout :get () then
487+ if self .stopRequestData .prepareTimeout :get () then
488+ self :debug (" Failed to prepare ai drive, aborting .." )
489+ end
490+ finishStrategy ()
491+ end
492+ end
438493end
439494
495+ --- Job has finished and we are now waiting to release the driver.
496+ --- @return boolean
497+ function AIDriveStrategyCourse :hasFinished ()
498+ return self .state == self .states .PRE_FINISHED or
499+ self .state == self .states .WAITING_FOR_FINISHED or
500+ self .state == self .states .FINISHED
501+ end
440502
441503function AIDriveStrategyCourse :getDriveData (dt , vX , vY , vZ )
442504 local moveForwards = not self .ppc :isReversing ()
@@ -664,15 +726,35 @@ function AIDriveStrategyCourse:isCloseToCourseStart(distance)
664726 return self .course :getDistanceFromFirstWaypoint (self .ppc :getCurrentWaypointIx ()) < distance
665727end
666728
729+ --- Possiblity to override the vehicle:stopCurrentAIJob(),
730+ --- if for example refilling on the field is active.
731+ function AIDriveStrategyCourse :handleFinishedRequest (stopReason )
732+ --- override
733+ return false
734+ end
735+
667736--- Event raised when the driver was stopped.
668737--- @param hasFinished boolean | nil flag passed by the info text
669- function AIDriveStrategyCourse :onFinished (hasFinished )
670- self :raiseControllerEvent (self .onFinishedEvent , hasFinished )
671- if hasFinished and self .settings .foldImplementAtEnd :getValue () then
672- --- Folds implements at the end if the setting is active.
673- self :debug (" Finished with folding implements of the implements." )
674- self .vehicle :prepareForAIDriving ()
738+ --- @param stopReason table
739+ function AIDriveStrategyCourse :onFinished (hasFinished , stopReason )
740+ if self :handleFinishedRequest (stopReason ) then
741+ --- Stop request ignored
742+ return
743+ end
744+ if self :hasFinished () then
745+ --- Driver is already stopping and still waiting for folding and so on ...
746+ return
675747 end
748+ self :setFinished (hasFinished and self .settings .foldImplementAtEnd :getValue (), stopReason )
749+ end
750+
751+ --- Internal stop request
752+ --- @param waitForFolding boolean | nil wait until for the folding and so on ..
753+ --- @param stopReason table | nil if nil is given , then the task will be skipped
754+ function AIDriveStrategyCourse :setFinished (waitForFolding , stopReason )
755+ self .stopRequestData .stopReason = stopReason
756+ self .stopRequestData .waitForFolding = waitForFolding
757+ self .state = self .states .PRE_FINISHED
676758end
677759
678760--- This is to set the offsets on the course at start, or update those values
0 commit comments