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

Commit

Permalink
6.01.00388 Big multitool + globalCompany fix
Browse files Browse the repository at this point in the history
Add triggersuport for all scripts of globalCompany #4991

Multitool/offset refactored.

When using multitools, the entire offset course is calculated
when starting the vehicle using the left/right lane offset
setting. This setting can't be changed while CP is driving.

This should fix all issues with multitools, especially headland
turns on the inner courses. #4202 and lot more...
  • Loading branch information
pvaiko committed Feb 29, 2020
1 parent 8118fe4 commit 15b93d4
Show file tree
Hide file tree
Showing 25 changed files with 481 additions and 299 deletions.
14 changes: 8 additions & 6 deletions AIDriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This is the base class of all AI drivers (modes) and implements MODE_TRANSPORT (
using the PurePursuitController (PPC). It replaces the code in drive.lua and has the
basic functionality:
• Drive a course
• Drive turn maneuvers (by passing on control to the code in turn.lua for the duration of the turn)
• Drive turn maneuvers
• Add an alignment when needed before starting the course (this is a lot easier now as
it just initializes the PPC with the alignment course and after that is finished, initializes
it with the regular course)
Expand Down Expand Up @@ -200,15 +200,16 @@ function AIDriver:beforeStart()
end

--- Start driving
-- @param ix the waypoint index to start driving at
function AIDriver:start(ix)
--- @param startingPoint number, one of StartingPointSetting.START_AT_* constants
function AIDriver:start(startingPoint)
self:beforeStart()
self.state = self.states.RUNNING
-- derived classes must disable collision detection if they don't need its
self:enableCollisionDetection()
-- for now, initialize the course with the vehicle's current course
-- main course is the one generated/loaded/recorded
self.mainCourse = Course(self.vehicle, self.vehicle.Waypoints)
local ix = self.mainCourse:getStartingWaypointIx(AIDriverUtil.getDirectionNode(self.vehicle), startingPoint)
self:debug('AI driver in mode %d starting at %d/%d waypoints', self:getMode(), ix, self.mainCourse:getNumberOfWaypoints())
self:startCourseWithAlignment(self.mainCourse, ix)
end
Expand All @@ -224,7 +225,7 @@ function AIDriver:dismiss()
end

--- Stop the driver
-- @param reason as defined in globalInfoText.msgReference
--- @param msgReference string as defined in globalInfoText.msgReference
function AIDriver:stop(msgReference)
self:deleteCollisionDetector()
-- not much to do here, see the derived classes
Expand Down Expand Up @@ -260,13 +261,15 @@ function AIDriver:resumeAt(ix)
self.ppc:initialize(ix)
end

--- @param msgReference string as defined in globalInfoText.msgReference
function AIDriver:setInfoText(msgReference)
if msgReference then
self:debugSparse('set info text to %s', msgReference)
self.activeMsgReferences[msgReference] = true
end
end

--- @param msgReference string as defined in globalInfoText.msgReference
function AIDriver:clearInfoText(msgReference)
if msgReference then
self.activeMsgReferences[msgReference] = nil
Expand Down Expand Up @@ -889,9 +892,8 @@ function AIDriver:dischargeAtUnloadPoint(dt,unloadPointIx)
if tipper.spec_dischargeable then
readyToDischarge = false
tipRefpoint = tipper:getCurrentDischargeNode().node or tipper.rootNode
nx,ny,nz = getWorldTranslation(tipRefpoint);
local isTipping = tipper.spec_dischargeable.currentRaycastDischargeNode.isEffectActive
_,_,z = worldToLocal(tipRefpoint, uX,uY,uZ);
local _,_,z = worldToLocal(tipRefpoint, uX,uY,uZ);
z = courseplay:isNodeTurnedWrongWay(vehicle,tipRefpoint)and -z or z

local foundHeap = self:checkForHeapBehindMe(tipper)
Expand Down
2 changes: 1 addition & 1 deletion AITurn.lua
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ end
function CourseTurn:startTurn()
-- pathfinder and Dubins won't handle multi tools correctly until the big multi tool fix is in place, so until then
-- just don't use it
if self.vehicle.cp.multiTools < 2 and self.turnContext:isWideTurn(self.turningRadius * 2) then
if self.turnContext:isWideTurn(self.turningRadius * 2) then
self:generatePathfinderTurn()
else
self:generateCalculatedTurn()
Expand Down
4 changes: 2 additions & 2 deletions CombineUnloadAIDriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ function CombineUnloadAIDriver:init(vehicle)
self.onTurnAwayCourse = false
end

function CombineUnloadAIDriver:start(ix)
AIDriver.start(self, ix)
function CombineUnloadAIDriver:start(startingPoint)
AIDriver.start(self, startingPoint)
end

function CombineUnloadAIDriver:isAlignmentCourseNeeded(ix)
Expand Down
2 changes: 1 addition & 1 deletion FieldSupplyAIDriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function FieldSupplyAIDriver:setHudContent()
courseplay.hud:setFieldSupplyAIDriverContent(self.vehicle)
end

function FieldSupplyAIDriver:start(ix)
function FieldSupplyAIDriver:start()
self:beforeStart()
self.course = Course(self.vehicle , self.vehicle.Waypoints)
self.ppc:setCourse(self.course)
Expand Down
83 changes: 64 additions & 19 deletions FieldworkAIDriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ function FieldworkAIDriver.getImplementWithSpecialization(vehicle, specializatio
end

--- Start the course and turn on all implements when needed
function FieldworkAIDriver:start(ix)
--- @param startingPoint StartingPointSetting at which waypoint to start the course
function FieldworkAIDriver:start(startingPoint)
self:debug('Starting in mode %d', self.mode)
self.ppc:registerListeners(self, 'onWaypointPassed', 'onWaypointChange')
self:setMarkers()
Expand All @@ -152,25 +153,61 @@ function FieldworkAIDriver:start(ix)
self.vehicle.cp.alignment.enabled = true
-- stop at the last waypoint by default
self.vehicle.cp.stopAtEnd = true
-- any offset imposed by the driver itself (tight turns, end of course, etc.), addtional to any
-- any offset imposed by the driver itself (tight turns, end of course, etc.), additional to any
-- tool offsets
self.aiDriverOffsetX = 0
self.aiDriverOffsetZ = 0

self:setUpCourses()
self.ppc:setNormalLookaheadDistance()

-- now that we have our unload/refill and fieldwork courses set up, see where to start
local closestFieldworkIx, dClosestFieldwork, closestFieldworkIxRightDirection, dClosestFieldworkRightDirection =
self.fieldworkCourse:getNearestWaypoints(AIDriverUtil.getDirectionNode(self.vehicle))

-- default to math.huge in case there isn't an unload refill course to make sure it only the fieldwork Ix is used
local closestUnloadRefillIx, dClosestUnloadRefill, closestUnloadRefillIxRightDirection, dClosestUnloadRefillRightDirection =
0, math.huge, 0, math.huge

if self.unloadRefillCourse then
closestUnloadRefillIx, dClosestUnloadRefill, closestUnloadRefillIxRightDirection, dClosestUnloadRefillRightDirection =
self.unloadRefillCourse:getNearestWaypoints(AIDriverUtil.getDirectionNode(self.vehicle))
end

local ix = self.course and self.course:getCurrentWaypointIx()
local startWithFieldwork

if startingPoint:is(StartingPointSetting.START_AT_NEAREST_POINT) then
if dClosestFieldwork < dClosestUnloadRefill then
ix = closestFieldworkIx
startWithFieldwork = true
else
ix = closestUnloadRefillIx
startWithFieldwork = false
end
end
-- TODO: decide if we even need current point in this mode, does not seem to make any sense
if startingPoint:is(StartingPointSetting.START_AT_NEXT_POINT) or startingPoint:is(StartingPointSetting.START_AT_CURRENT_POINT) then
if dClosestFieldworkRightDirection < dClosestUnloadRefillRightDirection then
ix = closestFieldworkIxRightDirection
startWithFieldwork = true
else
ix = closestUnloadRefillIxRightDirection
startWithFieldwork = false
end
end
if startingPoint:is(StartingPointSetting.START_AT_FIRST_POINT) then
ix = 1
startWithFieldwork = true
end

self.waitingForTools = true
-- on which course are we starting?
-- the ix we receive here is the waypoint index in the fieldwork course and the unload/fill
-- course concatenated.
if ix > self.fieldworkCourse:getNumberOfWaypoints() then
-- beyond the first, fieldwork course: we are on the unload/refill part
self:changeToUnloadOrRefill()
self:startCourseWithAlignment(self.unloadRefillCourse, ix - self.fieldworkCourse:getNumberOfWaypoints())
else
-- we are on the fieldwork part
self.ppc:setNormalLookaheadDistance()

if startWithFieldwork then
self:startFieldworkWithPathfinding(ix)
else
self:changeToUnloadOrRefill()
self:startCourseWithAlignment(self.unloadRefillCourse, ix)
end
end

Expand Down Expand Up @@ -653,14 +690,23 @@ function FieldworkAIDriver:setUpCourses()
self:debug('Course with %d waypoints set up, there seems to be no unload/refill course', #self.vehicle.Waypoints)
self.fieldworkCourse = Course(self.vehicle, self.vehicle.Waypoints, false, 1, #self.vehicle.Waypoints)
end
-- apply the current offset to the fieldwork part (lane+tool, where, confusingly, totalOffsetX contains the toolOffsetX)
self.fieldworkCourse:setOffset(self.vehicle.cp.totalOffsetX, self.vehicle.cp.toolOffsetZ)
-- get a signature of the course now, before offsetting it so can compare for the convoy
self.fieldworkCourseHash = self.fieldworkCourse:getHash()
-- apply the current tool offset to the fieldwork part (multitool offset is added by calculateOffsetCourse when needed)
self.fieldworkCourse:setOffset(self.vehicle.cp.toolOffsetX, self.vehicle.cp.toolOffsetZ)
-- TODO: consolidate the working width calculation and usage, this is currently an ugly mess
self.fieldworkCourse:setWorkWidth(self.vehicle.cp.courseWorkWidth or courseplay:getWorkWidth(self.vehicle))
if self.vehicle.cp.multiTools > 1 then
self:debug('Calculating offset course for position %d of %d', self.vehicle.cp.laneNumber, self.vehicle.cp.multiTools)
self.fieldworkCourse = self.fieldworkCourse:calculateOffsetCourse(
self.vehicle.cp.multiTools, self.vehicle.cp.laneNumber, courseplay:getWorkWidth(self.vehicle),
self.vehicle.cp.settings.symmetricLaneChange:is(true))
end
end

function FieldworkAIDriver:setRidgeMarkers()
if not self.vehicle.cp.ridgeMarkersAutomatic then return end
-- no ridge markers with multitools to avoid collisions.
if not self.vehicle.cp.ridgeMarkersAutomatic or self.vehicle.cp.multiTools > 1 then return end
local active = self.state == self.states.ON_FIELDWORK_COURSE and self.fieldworkState ~= self.states.TURNING
for _, workTool in ipairs(self.vehicle.cp.workTools) do
-- yes, another Giants typo. And not sure why implements with no ridge markers even have the spec_ridgeMarker
Expand All @@ -679,13 +725,13 @@ end
function FieldworkAIDriver:updateFieldworkOffset()
-- (as lua passes tables by reference, we can directly change self.fieldworkCourse even if we passed self.course
-- to the PPC to drive)
self.fieldworkCourse:setOffset(self.vehicle.cp.totalOffsetX + self.aiDriverOffsetX + (self.tightTurnOffset or 0),
self.fieldworkCourse:setOffset(self.vehicle.cp.toolOffsetX + self.aiDriverOffsetX + (self.tightTurnOffset or 0),
self.vehicle.cp.toolOffsetZ + self.aiDriverOffsetZ)
end

function FieldworkAIDriver:hasSameCourse(otherVehicle)
if otherVehicle.cp.driver and otherVehicle.cp.driver.fieldworkCourse then
return self.fieldworkCourse:equals(otherVehicle.cp.driver.fieldworkCourse)
if otherVehicle.cp.driver and otherVehicle.cp.driver.fieldworkCourseHash then
return self.fieldworkCourseHash == otherVehicle.cp.driver.fieldworkCourseHash
else
return false
end
Expand Down Expand Up @@ -1198,7 +1244,6 @@ function FieldworkAIDriver:onDraw()
DebugUtil.drawDebugNode(self.plowReferenceNode, 'Plow reference')
end


AIDriver.onDraw(self)
end

Expand Down
4 changes: 2 additions & 2 deletions GrainTransportAIDriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ function GrainTransportAIDriver:setHudContent()
courseplay.hud:setGrainTransportAIDriverContent(self.vehicle)
end

function GrainTransportAIDriver:start(ix)
function GrainTransportAIDriver:start(startingPoint)
self.vehicle:setCruiseControlMaxSpeed(self.vehicle:getSpeedLimit() or math.huge)
self:beforeStart()
AIDriver.start(self, ix)
AIDriver.start(self, startingPoint)
self:setDriveUnloadNow(false);
end

Expand Down
2 changes: 1 addition & 1 deletion LevelCompactAIDriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function LevelCompactAIDriver:setHudContent()
courseplay.hud:setLevelCompactAIDriverContent(self.vehicle)
end

function LevelCompactAIDriver:start(ix)
function LevelCompactAIDriver:start()
self:beforeStart()

self.course = Course(self.vehicle , self.vehicle.Waypoints)
Expand Down
2 changes: 1 addition & 1 deletion PlowAIDriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ function PlowAIDriver:setOffsetX()
local newToolOffsetX = -(leftMarkerDistance + rightMarkerDistance) / 2
-- set to the average of old and new to smooth a little bit to avoid oscillations
self.vehicle.cp.toolOffsetX = (self.vehicle.cp.toolOffsetX + newToolOffsetX) / 2
self.vehicle.cp.totalOffsetX = self.vehicle.cp.laneOffset + self.vehicle.cp.toolOffsetX
self.vehicle.cp.totalOffsetX = self.vehicle.cp.toolOffsetX
self:debug('%s: left = %.1f, right = %.1f, leftDx = %.1f, rightDx = %.1f, setting tool offsetX to %.2f (total offset %.2f)',
nameNum(self.plow), leftMarkerDistance, rightMarkerDistance, leftDx, rightDx, self.vehicle.cp.toolOffsetX, self.vehicle.cp.totalOffsetX)
end
Expand Down
2 changes: 1 addition & 1 deletion ShovelModeAIDriver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function ShovelModeAIDriver:setHudContent()
courseplay.hud:setShovelModeAIDriverContent(self.vehicle)
end

function ShovelModeAIDriver:start(ix)
function ShovelModeAIDriver:start()
self:beforeStart()
--finding my working points
local vehicle = self.vehicle
Expand Down
Loading

0 comments on commit 15b93d4

Please sign in to comment.