Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chopper support #2712

Closed
wants to merge 58 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
d44e28b
Almost Finished
pops64 Aug 17, 2023
9d6cf90
Code Clean Up
pops64 Aug 17, 2023
55f260b
Fix Git
pops64 Aug 17, 2023
e5c2659
Minor Tweaks
pops64 Aug 18, 2023
51ef721
Merge remote-tracking branch 'origin/main' into ChopperSupport
pops64 Aug 18, 2023
07b3d38
Made tweaks and improvemtns
pops64 Aug 18, 2023
fcd4622
Attempt to fix headland crash
pops64 Aug 18, 2023
1ab7bfa
Some upgrades fixed fruit side selection
pops64 Aug 18, 2023
48943c5
Typo Fix
pops64 Aug 18, 2023
68ce94a
Code Cleanup FruitSide Check, Chopper Turn Improvements
pops64 Aug 19, 2023
56872a2
Typo Fixes, Change new states table location
pops64 Aug 21, 2023
0a9f001
WIP
pops64 Aug 21, 2023
7090fb0
Mostly Working two tippers
pops64 Aug 22, 2023
4e667a5
Merge branch 'ChopperSupport2Drivers' into ChopperSupport
pops64 Aug 22, 2023
801c849
Code Cleanup
pops64 Aug 22, 2023
a2e241e
Some Fixes 2 Tippers WIP
pops64 Aug 22, 2023
9cf96d4
2+ Tippers 90% Reliable
pops64 Aug 22, 2023
e7d5ee4
Fixes for 2+ Tipper Improvments
pops64 Aug 22, 2023
9dae2a6
Typos and bug fixes
pops64 Aug 22, 2023
21c29cc
Requested Changes
pops64 Aug 22, 2023
892e1e9
Merge remote-tracking branch 'upstream/main' into ChopperSupport
pops64 Aug 22, 2023
bc8e475
Other Requested Changes
pops64 Aug 22, 2023
cc4780e
Fixes for combines
pops64 Aug 22, 2023
35f30d6
WIP Headland chase and Land chase
pops64 Aug 23, 2023
1ab6fa2
Some Tweaks and Last Row Fix
pops64 Aug 23, 2023
f12c323
95% Feature Complete
pops64 Aug 23, 2023
4b63c0f
Bug fix
pops64 Aug 23, 2023
b96a188
Merge branch 'Courseplay:main' into ChopperSupport
pops64 Aug 23, 2023
e84c22e
Code clean up and sugarcane
pops64 Aug 24, 2023
9d88506
WIP Code Orgazation
pops64 Aug 24, 2023
ddf5b58
Removed A/B Token system
pops64 Aug 24, 2023
9bc42b8
Delete unused code
pops64 Aug 24, 2023
fe9a82f
WIP Improvements to Turn Away From Chopper
pops64 Aug 25, 2023
a5fcf75
Code Comments Code Clean UP
pops64 Aug 25, 2023
5fc1c36
Code Organization Bug Fix in UnloadCombine
pops64 Aug 25, 2023
dc14642
Typo fix, Sugarcane Pipeoffset fix, isChopper change
pops64 Aug 26, 2023
f09bde7
Attempts at Edge Case Fixes
pops64 Aug 26, 2023
c7eb9ce
Attempt at fix Misalignment edge case
pops64 Aug 26, 2023
0b6936b
WIP Import FS19 Chopper Chase Mode
pops64 Aug 27, 2023
3c1fd2b
WIP Temp fix for the imported FS19 chase mode
pops64 Aug 29, 2023
67d56b3
Attempt 5k on fixing edge cases
pops64 Aug 29, 2023
c762e6d
Bug Fix
pops64 Aug 29, 2023
cf26f2b
Fix for chase mode !!!!
pops64 Aug 29, 2023
1826d4c
Beatification
pops64 Aug 29, 2023
2e48994
Better Bug Fix as requested
pops64 Aug 29, 2023
dc11217
Revert "Better Bug Fix as requested"
pops64 Aug 29, 2023
d433e9b
Revert "Beatification"
pops64 Aug 29, 2023
6843c2c
Revert "Fix for chase mode !!!!"
pops64 Aug 29, 2023
dc431ec
Better Fix for Marker Bug Location
pops64 Aug 29, 2023
4f96274
Typo
pops64 Aug 29, 2023
6cf0f02
Switch to using isNodeOnField()
pops64 Aug 29, 2023
384e804
Code Clean Up
pops64 Aug 29, 2023
3242243
AI Direction Fixes, PipeController Update
pops64 Aug 29, 2023
581e1dc
I got a spell checker!
pops64 Aug 29, 2023
6bf0781
Attempt at fixing end of course call stack
pops64 Aug 30, 2023
eade874
Different Attempt at fix end of work call stack
pops64 Aug 30, 2023
53f1170
Some tweaks to changing unloader logic
pops64 Aug 30, 2023
137db29
Fix for drive away course on headlands
pops64 Sep 4, 2023
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
2 changes: 2 additions & 0 deletions config/jobParameters/CombineUnloaderJobParameterSetup.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
<Values>
<Value name="UNLOAD_COMBINE">1</Value>
<Value name="UNLOAD_SILO_LOADER">2</Value>
<Value name="UNLOAD_CHOPPER">3</Value>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big fan of adding another option here, as this complicates the usage for the player.
Maybe instead of creating a new unload copper strategy, we could keep the combine one for both but
add a context with dependcy injection depending on the found unload target(combine or chopper)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of creating a new unload copper strategy, we could keep the combine one for both

I get why you don't like that but I still think it would be cleaner to have separate strategies. Another option could be to create a strategy for idle unloaders and instantiate the combine or chopper strategy only after the unloader is called by the combine/chopper.

Copy link
Contributor Author

@pops64 pops64 Aug 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would go further and move the self unloading code out as well, just my two cents tho. You would be adding a lot of if statements to combine if you combined them as there are some things you just don't want a chopper unload driver to do

</Values>
<Texts>
<Text>combine</Text>
<Text>siloLoader</Text>
<Text>chopper</Text>
</Texts>
</Setting>
</SettingSubTitle>
Expand Down
3 changes: 3 additions & 0 deletions modDesc.xml
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,11 @@ Changelog 7.1.0.0:
<sourceFile filename="scripts/ai/AIDriveStrategyAttachHeader.lua"/>
<sourceFile filename="scripts/ai/AIDriveStrategyFieldWorkCourse.lua"/>
<sourceFile filename="scripts/ai/AIDriveStrategyCombineCourse.lua"/>
<sourceFile filename="scripts/ai/AIDriveStrategyChopperCourse.lua"/>
<sourceFile filename="scripts/ai/AIDriveStrategyPlowCourse.lua"/>
<sourceFile filename="scripts/ai/AIDriveStrategyFindBales.lua"/>
<sourceFile filename="scripts/ai/AIDriveStrategyUnloadCombine.lua"/>
<sourceFile filename="scripts/ai/AIDriveStrategyUnloadChopper.lua"/>
<sourceFile filename="scripts/ai/AIDriveStrategyVineFieldWorkCourse.lua"/>
<sourceFile filename="scripts/ai/AIDriveStrategyBunkerSilo.lua"/>
<sourceFile filename="scripts/ai/AIDriveStrategySiloLoader.lua"/>
Expand All @@ -301,6 +303,7 @@ Changelog 7.1.0.0:
<sourceFile filename="scripts/ai/controllers/SprayerController.lua"/>
<sourceFile filename="scripts/ai/controllers/StonePickerController.lua"/>
<sourceFile filename="scripts/ai/controllers/CombineController.lua"/>
<sourceFile filename="scripts/ai/controllers/ChopperController.lua"/>
<sourceFile filename="scripts/ai/controllers/MotorController.lua"/>
<sourceFile filename="scripts/ai/controllers/VineCutterController.lua"/>
<sourceFile filename="scripts/ai/controllers/WearableController.lua"/>
Expand Down
374 changes: 374 additions & 0 deletions scripts/ai/AIDriveStrategyChopperCourse.lua

Large diffs are not rendered by default.

121 changes: 11 additions & 110 deletions scripts/ai/AIDriveStrategyCombineCourse.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ function AIDriveStrategyCombineCourse.new(customMt)
self.stopDisabledAfterEmpty = CpTemporaryObject(false)
self.stopDisabledAfterEmpty:set(false, 1)
self:initUnloadStates()
self.chopperCanDischarge = CpTemporaryObject(false)
-- hold the harvester temporarily
self.temporaryHold = CpTemporaryObject(false)
-- periodically check if we need to call an unloader
Expand Down Expand Up @@ -120,11 +119,6 @@ function AIDriveStrategyCombineCourse:setAllStaticParameters()
AIDriveStrategyCombineCourse.superClass().setAllStaticParameters(self)
self:debug('AIDriveStrategyCombineCourse set')

if self:isChopper() then
self:debug('This is a chopper.')
end

self:checkMarkers()
self:measureBackDistance()
Markers.setMarkerNodes(self.vehicle, self.measuredBackDistance)

Expand Down Expand Up @@ -167,25 +161,13 @@ function AIDriveStrategyCombineCourse:getProximitySensorWidth()
return self:getWorkWidth()
end

-- This part of an ugly workaround to make the chopper pickups work
function AIDriveStrategyCombineCourse:checkMarkers()
for _, implement in pairs(AIUtil.getAllAIImplements(self.vehicle)) do
local aiLeftMarker, aiRightMarker, aiBackMarker = implement.object:getAIMarkers()
if not aiLeftMarker or not aiRightMarker or not aiBackMarker then
self.notAllImplementsHaveAiMarkers = true
return
end
end
end

--- Get the combine object, this can be different from the vehicle in case of tools towed or mounted on a tractor
function AIDriveStrategyCombineCourse:getCombine()
return self.combine
end

function AIDriveStrategyCombineCourse:update(dt)
AIDriveStrategyFieldWorkCourse.update(self, dt)
self:updateChopperFillType()
self:onDraw()
end

Expand Down Expand Up @@ -677,15 +659,9 @@ function AIDriveStrategyCombineCourse:checkFruit()
dx = dx / length
dz = dz / length
self.vehicle.aiDriveDirection = { dx, dz }
-- getValidityOfTurnDirections works only if all AI Implements have aiMarkers. Since
-- we make all Cutters AI implements, even the ones which do not have AI markers (such as the
-- chopper pickups which do not work with the Giants helper) we have to make sure we don't call
-- getValidityOfTurnDirections for those
if self.notAllImplementsHaveAiMarkers then
self.fruitLeft, self.fruitRight = 0, 0
else
self.fruitLeft, self.fruitRight = AIVehicleUtil.getValidityOfTurnDirections(self.vehicle)
end

self.fruitLeft, self.fruitRight = AIVehicleUtil.getValidityOfTurnDirections(self.vehicle)

local workWidth = self:getWorkWidth()
local x, _, z = localToWorld(self.vehicle:getAIDirectionNode(), workWidth, 0, 0)
self.fieldOnLeft = CpFieldUtil.isOnField(x, z)
Expand All @@ -701,6 +677,7 @@ function AIDriveStrategyCombineCourse:estimateDistanceUntilFull(ix)
-- calculate fill rate so the combine driver knows if it can make the next row without unloading
local fillLevel = self.combineController:getFillLevel()
local capacity = self.combineController:getCapacity()

if ix > 1 then
local dToNext = self.course:getDistanceToNextWaypoint(ix - 1)
if self.fillLevelAtLastWaypoint and self.fillLevelAtLastWaypoint > 0 and self.fillLevelAtLastWaypoint <= fillLevel then
Expand Down Expand Up @@ -897,7 +874,7 @@ function AIDriveStrategyCombineCourse:findUnloader(combine, waypoint)
local x, _, z = getWorldTranslation(self.vehicle.rootNode)
---@type AIDriveStrategyUnloadCombine
local driveStrategy = vehicle:getCpDriveStrategy()
if driveStrategy:isServingPosition(x, z, 0) then
if driveStrategy:isServingPosition(x, z, self.distanceOverFieldEdgeAllowed) then
pops64 marked this conversation as resolved.
Show resolved Hide resolved
local unloaderFillLevelPercentage = driveStrategy:getFillLevelPercentage()
if driveStrategy:isIdle() and unloaderFillLevelPercentage < 99 then
local unloaderDistance, unloaderEte
Expand Down Expand Up @@ -1231,14 +1208,14 @@ function AIDriveStrategyCombineCourse:isFuelSaveAllowed()
if self.combine:getIsThreshingDuringRain() then
return true
end
return self:isWaitingForUnload() or self:isChopperWaitingForUnloader()
return self:isWaitingForUnload()
end

--- Check if the vehicle should stop during a turn for example while it
--- is held for unloading or waiting for the straw swath to stop
function AIDriveStrategyCombineCourse:shouldHoldInTurnManeuver()
--- Hold during discharge
local discharging = self:isDischarging() and not self:isChopper()
local discharging = self:isDischarging()

local isFinishingRow = self.aiTurn and self.aiTurn:isFinishingRow()
local waitForStraw = self.combineController:isDroppingStrawSwath() and not isFinishingRow
Expand Down Expand Up @@ -1374,64 +1351,17 @@ function AIDriveStrategyCombineCourse:getFieldworkCourse()
return self.course
end

function AIDriveStrategyCombineCourse:isChopper()
return self.combineController:isChopper()
end

-----------------------------------------------------------------------------------------------------------------------
--- Pipe handling
-----------------------------------------------------------------------------------------------------------------------
function AIDriveStrategyCombineCourse:handlePipe(dt)
if self:isChopper() then
self:handleChopperPipe()
else
self:handleCombinePipe(dt)
end
end

function AIDriveStrategyCombineCourse:handleCombinePipe(dt)

if self.pipeController:isFillableTrailerUnderPipe() or self:isAutoDriveWaitingForPipe() then
self.pipeController:openPipe()
else
self.pipeController:closePipe(true)
end
end

--- Not exactly sure what this does, but without this the chopper just won't move.
--- Copied from AIDriveStrategyCombine:update()
function AIDriveStrategyCombineCourse:updateChopperFillType()
if self:isChopper() then
self.combineController:updateChopperFillType()
end
end

-- TODO: move this to the PipeController?
function AIDriveStrategyCombineCourse:handleChopperPipe()
self.pipeController:handleChopperPipe()

local trailer = self.pipeController:getClosestObject()
local dischargeNode = self.pipeController:getDischargeNode()
local targetObject = self.pipeController:getDischargeObject()
self:debugSparse('%s %s', dischargeNode, self:isAnyWorkAreaProcessing())
if not self.waitingForTrailer and self:isAnyWorkAreaProcessing() and (targetObject == nil or trailer == nil) then
self:debug('Chopper waiting for trailer, discharge node %s, target object %s, trailer %s',
tostring(dischargeNode), tostring(targetObject), tostring(trailer))
self.waitingForTrailer = true
end
if self.waitingForTrailer then
self:setMaxSpeed(0)
if not (targetObject == nil or trailer == nil) then
self:debug('Chopper has trailer now, continue')
self.waitingForTrailer = false
end
end
end

function AIDriveStrategyCombineCourse:isChopperWaitingForUnloader()
return self.waitingForTrailer
end

function AIDriveStrategyCombineCourse:isAnyWorkAreaProcessing()
for _, implement in pairs(self.vehicle:getChildVehicles()) do
if implement.spec_workArea ~= nil then
Expand Down Expand Up @@ -1484,13 +1414,6 @@ function AIDriveStrategyCombineCourse:getFillType()
return self.pipeController:getFillType()
end

-- even if there is a trailer in range, we should not start moving until the pipe is turned towards the
-- trailer and can start discharging. This returning true does not mean there's a trailer under the pipe,
-- this seems more like for choppers to check if there's a potential target around
function AIDriveStrategyCombineCourse:canDischarge()
return self.pipeController:getDischargeObject()
end

function AIDriveStrategyCombineCourse:isDischarging()
return self.pipeController:isDischarging()
end
Expand Down Expand Up @@ -1639,6 +1562,7 @@ end
--- events are for the low level coordination between the combine and its unloader(s). CombineUnloadManager
--- takes care about coordinating the work between multiple combines.
function AIDriveStrategyCombineCourse:clearAllUnloaderInformation()
self:debug('All Unloader Info has been cleared')
self:cancelRendezvous()
self.unloader:reset()
end
Expand All @@ -1653,35 +1577,11 @@ end
--- Deregister a combine unload AI driver from notifications
---@param driver CombineUnloadAIDriver
function AIDriveStrategyCombineCourse:deregisterUnloader(driver, noEventSend)
self:debug('Unloader has be unregistered')
pops64 marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

self:cancelRendezvous()
self.unloader:reset()
end

--- Make life easier for unloaders, increases reach of the pipe
--- Old code ??
function AIDriveStrategyCombineCourse:fixMaxRotationLimit()
if self.pipe then
local lastPipeNode = self.pipe.nodes and self.pipe.nodes[#self.pipe.nodes]
if self:isChopper() and lastPipeNode and lastPipeNode.maxRotationLimits then
self.oldLastPipeNodeMaxRotationLimit = lastPipeNode.maxRotationLimits
self:debug('Chopper fix maxRotationLimits, old Values: x=%s, y= %s, z =%s', tostring(lastPipeNode.maxRotationLimits[1]), tostring(lastPipeNode.maxRotationLimits[2]), tostring(lastPipeNode.maxRotationLimits[3]))
lastPipeNode.maxRotationLimits = nil
end
end
end

--- Old code ??
function AIDriveStrategyCombineCourse:resetFixMaxRotationLimit()
if self.pipe then
local lastPipeNode = self.pipe.nodes and self.pipe.nodes[#self.pipe.nodes]
if lastPipeNode and self.oldLastPipeNodeMaxRotationLimit then
lastPipeNode.maxRotationLimits = self.oldLastPipeNodeMaxRotationLimit
self:debug('Chopper: reset maxRotationLimits is x=%s, y= %s, z =%s', tostring(lastPipeNode.maxRotationLimits[1]), tostring(lastPipeNode.maxRotationLimits[3]), tostring(lastPipeNode.maxRotationLimits[3]))
self.oldLastPipeNodeMaxRotationLimit = nil
end
end
end

--- Offset of the pipe from the combine implement's root node
---@param additionalOffsetX number add this to the offsetX if you don't want to be directly under the pipe. If
--- greater than 0 -> to the left, less than zero -> to the right
Expand Down Expand Up @@ -1963,4 +1863,5 @@ function AIDriveStrategyCombineCourse:updateInfoTexts()
self:clearInfoText(infoText)
end
end
end
end

Loading