Skip to content
Merged
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
25 changes: 14 additions & 11 deletions scripts/ai/strategies/AIDriveStrategyFieldWorkCourse.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ AIDriveStrategyFieldWorkCourse = CpObject(AIDriveStrategyCourse)

AIDriveStrategyFieldWorkCourse.myStates = {
WORKING = {},
PREPARING = {},
WAITING_FOR_LOWER = {},
WAITING_FOR_LOWER_DELAYED = {},
WAITING_FOR_STOP = {},
Expand Down Expand Up @@ -89,19 +90,11 @@ function AIDriveStrategyFieldWorkCourse:start(course, startIx, jobParameters)
self:debug('Close enough to start waypoint %d, no alignment course needed', startIx)
self:startCourse(course, startIx)
self.state = self.states.INITIAL
self:prepareForFieldWork()
end
--- Store a reference to the original generated course
self.originalGeneratedFieldWorkCourse = self.vehicle:getFieldWorkCourse()
end

--- If the strategy needs a field polygon to work, it won't transition out of the INITIAL state
--- until the field detection, an asynchronous process that may have started only when the job was started, is finished.
---@return boolean true if the strategy needs the field polygon to work
function AIDriveStrategyFieldWorkCourse:needsFieldPolygon()
return false
end

--- Make sure all implements are in the working state
function AIDriveStrategyFieldWorkCourse:prepareForFieldWork()
self.vehicle:raiseAIEvent('onAIFieldWorkerPrepareForWork', 'onAIImplementPrepareForWork')
Expand Down Expand Up @@ -164,6 +157,17 @@ function AIDriveStrategyFieldWorkCourse:getDriveData(dt, vX, vY, vZ)
end
----------------------------------------------------------------
if self.state == self.states.INITIAL then
-- We need a separate phase for preparing to make sure that the
-- * onAIFieldWorkerStart,
-- * onAIFieldWorkerPrepareForWork,
-- * onAIImplementStartLine
-- events are generated one by one, one in each update loop so that at the end of the loop,
-- AIFieldWorker:updateAIFieldWorker() triggers a onAIFieldWorkerActive event.
-- This makes sure that all implements are lowered and started correctly in multiplayer as well.
self:setMaxSpeed(0)
self:prepareForFieldWork()
self.state = self.states.PREPARING
elseif self.state == self.states.PREPARING then
self:setMaxSpeed(0)
self:startWaitingForLower()
self:lowerImplements()
Expand Down Expand Up @@ -328,7 +332,7 @@ function AIDriveStrategyFieldWorkCourse:onWaypointChange(ix, course)
self:calculateTightTurnOffset()
if not self.state ~= self.states.TURNING
and self.course:isTurnStartAtIx(ix) then
if self.state == self.states.INITIAL then
if self.state == self.states.INITIAL or self.state == self.states.PREPARING then
self:debug('Waypoint change (%d) to turn start right after starting work, lowering implements.', ix)
self:startWaitingForLower()
self:lowerImplements()
Expand Down Expand Up @@ -483,8 +487,8 @@ function AIDriveStrategyFieldWorkCourse:startAlignmentTurn(fieldWorkCourse, star
alignmentCourse = self:createAlignmentCourse(fieldWorkCourse, startIx)
end
self.ppc:setShortLookaheadDistance()
self:prepareForFieldWork()
if alignmentCourse then
self:prepareForFieldWork()
local fm, bm = self:getFrontAndBackMarkers()
self.turnContext = RowStartOrFinishContext(self.vehicle, fieldWorkCourse, startIx, startIx, self.turnNodes,
self:getWorkWidth(), fm, bm, self:getTurnEndSideOffset(false), self:getTurnEndForwardOffset())
Expand All @@ -495,7 +499,6 @@ function AIDriveStrategyFieldWorkCourse:startAlignmentTurn(fieldWorkCourse, star
self:debug('Could not create alignment course to first up/down row waypoint, continue without it')
self:startCourse(fieldWorkCourse, startIx)
self.state = self.states.INITIAL
self:prepareForFieldWork()
end
end

Expand Down
31 changes: 31 additions & 0 deletions scripts/ai/tasks/CpAITaskFieldWork.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,37 @@ function CpAITaskFieldWork:update(dt)

end

--- This function can be used to trace the triggering of AI events. The timing of these is critical for multiplayer
--- to work properly, these traces help to determine if this timing is correct. Bad timing will result in implements
--- not lowering or not turning on in multiplayer, while there are no symptoms in single player.
---
--- The game engine needs a separate phase for preparing to make sure that the
--- * onAIFieldWorkerStart,
--- * onAIFieldWorkerPrepareForWork,
--- * onAIImplementStartLine
--- events are generated one by one, one in each update loop so that at the end of the loop,
--- AIFieldWorker:updateAIFieldWorker() triggers a onAIFieldWorkerActive event.
---
function CpAITaskFieldWork:turnOnAIEventTrace()
self.vehicle.raiseAIEvent = function(vehicle, event1, event2, ...)
if vehicle.cpLastRaiseAIEvent ~= event1 and vehicle.cpLastRaiseAIEvent2 ~= event2 then
CpUtil.infoVehicle(vehicle, "raiseAIEvent %s %s", event1, event2)
end
vehicle.cpLastRaiseAIEvent1 = event1
vehicle.cpLastRaiseAIEvent2 = event2
AIVehicle.raiseAIEvent(vehicle, event1, event2, ...)
end

if self.vehicle.actionController ~= nil then
self.vehicle.actionController.onAIEvent = function(actionController, sourceVehicle, eventName)
if eventName ~= 'onAIFieldWorkerActive' and eventName ~= 'onAIImplementActive' then
CpUtil.infoVehicle(self.vehicle, " onAIEvent %s, source %s", eventName, CpUtil.getName(sourceVehicle))
end
VehicleActionController.onAIEvent(actionController, sourceVehicle, eventName)
end
end
end

--- Makes sure the cp fieldworker gets started.
function CpAITaskFieldWork:start()
self:debug("Field work task started.")
Expand Down
Loading