Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Commit

Permalink
6.03.00054 Potato/cotton harvester fixes
Browse files Browse the repository at this point in the history
- Fix implement raise/lower for #7110 and #7112

- Cotton harversters should work better (#7103), except the JD
  • Loading branch information
pvaiko committed Apr 21, 2021
1 parent 3e1407b commit 0bfd27d
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 80 deletions.
55 changes: 54 additions & 1 deletion AITurn.lua
Original file line number Diff line number Diff line change
Expand Up @@ -626,8 +626,61 @@ function CombinePocketHeadlandTurn:init(vehicle, driver, turnContext, fieldworkC
CombineCourseTurn.init(self, vehicle, driver, turnContext, fieldworkCourse,'CombinePocketHeadlandTurn')
end

--- Create a pocket in the next row at the corner to stay on the field during the turn maneuver.
---@param turnContext TurnContext
function CombinePocketHeadlandTurn:generatePocketHeadlandTurn(turnContext)
local cornerWaypoints = {}
local turnRadius = self.vehicle.cp.turnDiameter / 2
-- this is how far we have to cut into the next headland (the position where the header will be after the turn)
local offset = math.min(turnRadius + turnContext.frontMarkerDistance, self.vehicle.cp.workWidth)
local corner = turnContext:createCorner(self.vehicle, turnRadius)
local d = -self.vehicle.cp.workWidth / 2 + turnContext.frontMarkerDistance
local wp = corner:getPointAtDistanceFromCornerStart(d + 2)
wp.speed = self.vehicle.cp.speeds.turn * 0.75
table.insert(cornerWaypoints, wp)
-- drive forward up to the field edge
wp = corner:getPointAtDistanceFromCornerStart(d)
wp.speed = self.vehicle.cp.speeds.turn * 0.75
table.insert(cornerWaypoints, wp)
-- drive back to prepare for making a pocket
-- reverse back to set up for the headland after the corner
local reverseDistance = 2 * offset
wp = corner:getPointAtDistanceFromCornerStart(reverseDistance / 2)
wp.rev = true
table.insert(cornerWaypoints, wp)
wp = corner:getPointAtDistanceFromCornerStart(reverseDistance)
wp.rev = true
table.insert(cornerWaypoints, wp)
-- now make a pocket in the inner headland to make room to turn
wp = corner:getPointAtDistanceFromCornerStart(reverseDistance * 0.75, -offset * 0.75)
table.insert(cornerWaypoints, wp)
wp = corner:getPointAtDistanceFromCornerStart(reverseDistance * 0.5, -offset * 0.9)
if not courseplay:isField(wp.x, wp.z) then
self:debug('No field where the pocket would be, this seems to be a 270 corner')
corner:delete()
return nil
end
table.insert(cornerWaypoints, wp)
-- drive forward to the field edge on the inner headland
wp = corner:getPointAtDistanceFromCornerStart(d, -offset)
wp.speed = self.vehicle.cp.speeds.turn * 0.75
table.insert(cornerWaypoints, wp)
wp = corner:getPointAtDistanceFromCornerStart(reverseDistance / 2)
wp.rev = true
table.insert(cornerWaypoints, wp)
wp = corner:getPointAtDistanceFromCornerEnd(turnRadius / 3, turnRadius / 4)
wp.speed = self.vehicle.cp.speeds.turn * 0.5
table.insert(cornerWaypoints, wp)
wp = corner:getPointAtDistanceFromCornerEnd(turnRadius, turnRadius / 4)
wp.speed = self.vehicle.cp.speeds.turn * 0.5
table.insert(cornerWaypoints, wp)
corner:delete()
return Course(self.vehicle, cornerWaypoints, true), turnContext.turnEndWpIx
end


function CombinePocketHeadlandTurn:startTurn()
self.turnCourse = self.driver:createOuterHeadlandCornerCourse(self.turnContext)
self.turnCourse = self:generatePocketHeadlandTurn(self.turnContext)
if not self.turnCourse then
self:debug('Could not create pocket course, falling back to normal headland corner')
self:generateCalculatedTurn()
Expand Down
36 changes: 36 additions & 0 deletions BalerAIDriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ function BalerAIDriver:init(vehicle)
UnloadableFieldworkAIDriver.init(self, vehicle)
self.slowDownFillLevel = 200
self.slowDownStartSpeed = 20

if SpecializationUtil.hasSpecialization(Combine, vehicle.specializations) or
AIDriverUtil.hasAIImplementWithSpecialization(vehicle, Combine) then
self.isCombine = true
end
end

function BalerAIDriver:driveFieldwork(dt)
Expand Down Expand Up @@ -52,6 +57,37 @@ function BalerAIDriver:initializeBaler()
end
end

function BalerAIDriver:startTurn(ix)
if self.isCombine then
self:debug('This vehicle is also a harvester, check check for special headland turns.')
self:setMarkers()
self.turnContext = TurnContext(self.course, ix, self.aiDriverData, self.vehicle.cp.workWidth,
self.frontMarkerDistance, self.backMarkerDistance,
self:getTurnEndSideOffset(), self:getTurnEndForwardOffset())

if self.turnContext:isHeadlandCorner() then
if self.course:isOnConnectingTrack(ix) then
self:debug('Headland turn but this a connecting track, use normal turn maneuvers.')
UnloadableFieldworkAIDriver.startTurn(self, ix)
elseif self.course:isOnOutermostHeadland(ix) and self.vehicle.cp.settings.turnOnField:is(true) then
self:debug('Creating a pocket in the corner so the harvester stays on the field during the turn')
self.aiTurn = CombinePocketHeadlandTurn(self.vehicle, self, self.turnContext, self.fieldworkCourse)
self.fieldworkState = self.states.TURNING
self.ppc:setShortLookaheadDistance()
else
self:debug('Use combine headland turn.')
self.aiTurn = CombineHeadlandTurn(self.vehicle, self, self.turnContext)
self.fieldworkState = self.states.TURNING
end
else
self:debug('Non headland turn.')
UnloadableFieldworkAIDriver.startTurn(self, ix)
end
else
UnloadableFieldworkAIDriver.startTurn(self, ix)
end
end

function BalerAIDriver:dismiss()
UnloadableFieldworkAIDriver.dismiss(self)
--revert possible change for the player to default
Expand Down
69 changes: 0 additions & 69 deletions CombineAIDriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,6 @@ CombineAIDriver.myStates = {
RETURNING_FROM_SELF_UNLOAD = {}
}

CombineAIDriver.turnTypes = {
HEADLAND_NORMAL = {},
HEADLAND_EASY = {},
HEADLAND_POCKET = {},
UP_DOWN_NORMAL = {}
}

-- Developer hack: to check the class of an object one should use the is_a() defined in CpObject.lua.
-- However, when we reload classes on the fly during the development, the is_a() calls in other modules still
Expand Down Expand Up @@ -1005,27 +999,22 @@ function CombineAIDriver:startTurn(ix)
if self.turnContext:isHeadlandCorner() then
if self:isPotatoOrSugarBeetHarvester() then
self:debug('Headland turn but this harvester uses normal turn maneuvers.')
self.turnType = self.turnTypes.HEADLAND_NORMAL
UnloadableFieldworkAIDriver.startTurn(self, ix)
elseif self.course:isOnConnectingTrack(ix) then
self:debug('Headland turn but this a connecting track, use normal turn maneuvers.')
self.turnType = self.turnTypes.HEADLAND_NORMAL
UnloadableFieldworkAIDriver.startTurn(self, ix)
elseif self.course:isOnOutermostHeadland(ix) and self.vehicle.cp.settings.turnOnField:is(true) then
self:debug('Creating a pocket in the corner so the combine stays on the field during the turn')
self.aiTurn = CombinePocketHeadlandTurn(self.vehicle, self, self.turnContext, self.fieldworkCourse)
self.turnType = self.turnTypes.HEADLAND_POCKET
self.fieldworkState = self.states.TURNING
self.ppc:setShortLookaheadDistance()
else
self:debug('Use combine headland turn.')
self.aiTurn = CombineHeadlandTurn(self.vehicle, self, self.turnContext)
self.turnType = self.turnTypes.HEADLAND_EASY
self.fieldworkState = self.states.TURNING
end
else
self:debug('Non headland turn.')
self.turnType = self.turnTypes.UP_DOWN_NORMAL
UnloadableFieldworkAIDriver.startTurn(self, ix)
end
end
Expand All @@ -1051,11 +1040,6 @@ function CombineAIDriver:isTurningOnHeadland()
return self.fieldworkState == self.states.TURNING and self.turnContext and self.turnContext:isHeadlandCorner()
end

---@param turnType table one of CombineAIDriver.turnTypes
function CombineAIDriver:isHeadlandTurn(turnType)
return turnType ~= CombineAIDriver.turnTypes.UP_DOWN_NORMAL
end

function CombineAIDriver:isTurningLeft()
return self.fieldworkState == self.states.TURNING and self.turnContext and self.turnContext:isLeftTurn()
end
Expand All @@ -1068,59 +1052,6 @@ function CombineAIDriver:getWorkWidth()
return self.vehicle.cp.workWidth
end


--- Create a pocket in the next row at the corner to stay on the field during the turn maneuver.
---@param turnContext TurnContext
function CombineAIDriver:createOuterHeadlandCornerCourse(turnContext)
local cornerWaypoints = {}
local turnRadius = self.vehicle.cp.turnDiameter / 2
-- this is how far we have to cut into the next headland (the position where the header will be after the turn)
local offset = math.min(turnRadius + self.frontMarkerDistance, self.vehicle.cp.workWidth)
local corner = turnContext:createCorner(self.vehicle, turnRadius)
local d = -self.vehicle.cp.workWidth / 2 + self.frontMarkerDistance
local wp = corner:getPointAtDistanceFromCornerStart(d + 2)
wp.speed = self.vehicle.cp.speeds.turn * 0.75
table.insert(cornerWaypoints, wp)
-- drive forward up to the field edge
wp = corner:getPointAtDistanceFromCornerStart(d)
wp.speed = self.vehicle.cp.speeds.turn * 0.75
table.insert(cornerWaypoints, wp)
-- drive back to prepare for making a pocket
-- reverse back to set up for the headland after the corner
local reverseDistance = 2 * offset
wp = corner:getPointAtDistanceFromCornerStart(reverseDistance / 2)
wp.rev = true
table.insert(cornerWaypoints, wp)
wp = corner:getPointAtDistanceFromCornerStart(reverseDistance)
wp.rev = true
table.insert(cornerWaypoints, wp)
-- now make a pocket in the inner headland to make room to turn
wp = corner:getPointAtDistanceFromCornerStart(reverseDistance * 0.75, -offset * 0.75)
table.insert(cornerWaypoints, wp)
wp = corner:getPointAtDistanceFromCornerStart(reverseDistance * 0.5, -offset * 0.9)
if not courseplay:isField(wp.x, wp.z) then
self:debug('No field where the pocket would be, this seems to be a 270 corner')
corner:delete()
return nil
end
table.insert(cornerWaypoints, wp)
-- drive forward to the field edge on the inner headland
wp = corner:getPointAtDistanceFromCornerStart(d, -offset)
wp.speed = self.vehicle.cp.speeds.turn * 0.75
table.insert(cornerWaypoints, wp)
wp = corner:getPointAtDistanceFromCornerStart(reverseDistance / 2)
wp.rev = true
table.insert(cornerWaypoints, wp)
wp = corner:getPointAtDistanceFromCornerEnd(turnRadius / 3, turnRadius / 4)
wp.speed = self.vehicle.cp.speeds.turn * 0.5
table.insert(cornerWaypoints, wp)
wp = corner:getPointAtDistanceFromCornerEnd(turnRadius, turnRadius / 4)
wp.speed = self.vehicle.cp.speeds.turn * 0.5
table.insert(cornerWaypoints, wp)
corner:delete()
return Course(self.vehicle, cornerWaypoints, true), turnContext.turnEndWpIx
end

function CombineAIDriver:isChopper()
return self.combine:getFillUnitCapacity(self.combine.fillUnitIndex) > 10000000
end
Expand Down
8 changes: 2 additions & 6 deletions FieldworkAIDriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1013,9 +1013,7 @@ end

function FieldworkAIDriver:lowerImplements()
for _, implement in pairs(self.vehicle:getAttachedAIImplements()) do
if implement.object ~= self.vehicle then
implement.object:aiImplementStartLine()
end
implement.object:aiImplementStartLine()
end
self.vehicle:raiseStateChange(Vehicle.STATE_CHANGE_AI_START_LINE)

Expand All @@ -1028,9 +1026,7 @@ end

function FieldworkAIDriver:raiseImplements()
for _, implement in pairs(self.vehicle:getAttachedAIImplements()) do
if implement.object ~= self.vehicle then
implement.object:aiImplementEndLine()
end
implement.object:aiImplementEndLine()
end
self.vehicle:raiseStateChange(Vehicle.STATE_CHANGE_AI_END_LINE)
end
Expand Down
6 changes: 3 additions & 3 deletions UnloadableFieldworkAIDriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ function UnloadableFieldworkAIDriver.create(vehicle)
-- Bale wrapper is derived from baler so must check it first to make sure that we instantiate a
-- BaleWrapperAIDriver if we have both the baler and the balewrapper specialization
return BaleWrapperAIDriver(vehicle)
elseif SpecializationUtil.hasSpecialization(Combine, vehicle.specializations) or
AIDriverUtil.hasAIImplementWithSpecialization(vehicle, Combine) then
return CombineAIDriver(vehicle)
elseif SpecializationUtil.hasSpecialization(Baler, vehicle.specializations) or
AIDriverUtil.hasAIImplementWithSpecialization(vehicle, Baler) then
return BalerAIDriver(vehicle)
elseif SpecializationUtil.hasSpecialization(Combine, vehicle.specializations) or
AIDriverUtil.hasAIImplementWithSpecialization(vehicle, Combine) then
return CombineAIDriver(vehicle)
elseif SpecializationUtil.hasSpecialization(Plow, vehicle.specializations) or
AIDriverUtil.hasAIImplementWithSpecialization(vehicle, Plow) then
return PlowAIDriver(vehicle)
Expand Down
2 changes: 1 addition & 1 deletion modDesc.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<modDesc descVersion="47">
<version>6.03.00053</version>
<version>6.03.00054</version>
<author><![CDATA[Courseplay.devTeam]]></author>
<title><!-- en=English de=German fr=French es=Spanish ru=Russian pl=Polish it=Italian br=Brazilian-Portuguese cs=Chinese(Simplified) ct=Chinese(Traditional) cz=Czech nl=Netherlands hu=Hungary jp=Japanese kr=Korean pt=Portuguese ro=Romanian tr=Turkish -->
<en>CoursePlay SIX</en>
Expand Down

0 comments on commit 0bfd27d

Please sign in to comment.