Skip to content

Commit

Permalink
fix: make sure rotated plow is lowered
Browse files Browse the repository at this point in the history
  • Loading branch information
pvaiko committed Sep 15, 2023
1 parent 4f62907 commit e13b7e8
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 23 deletions.
2 changes: 1 addition & 1 deletion scripts/ai/AIUtil.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function AIUtil.calculateTightTurnOffset(vehicle, vehicleTurningRadius, course,
local tightTurnOffset

local function smoothOffset(offset)
return (offset + 3 * (previousOffset or 0 )) / 4
return (offset + 4 * (previousOffset or 0 )) / 5
end

-- first of all, does the current waypoint have radius data?
Expand Down
9 changes: 0 additions & 9 deletions scripts/ai/PurePursuitController.lua
Original file line number Diff line number Diff line change
Expand Up @@ -241,15 +241,6 @@ function PurePursuitController:switchControlledNode()
end
end

--- Compatibility function to return the original waypoint index as in vehicle.Waypoints. This
-- is the same as self.currentWpNode.ix unless we have combined courses where the legacy CP code
-- concatenates all courses into one Waypoints array (as opposed to the AIDriver which splits these
-- combined courses into its parts). The rest of the CP code however (HUD, reverse, etc.) works with
-- vehicle.Waypoints and vehicle.cp.waypointIndex and therefore expects the combined index
function PurePursuitController:getCurrentOriginalWaypointIx()
return self.course.waypoints[self:getCurrentWaypointIx()].cpIndex
end

function PurePursuitController:update()
if not self.course then
self:debugSparse('no course set.')
Expand Down
2 changes: 1 addition & 1 deletion scripts/ai/controllers/ImplementController.lua
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ end
function ImplementController:onFinishRow(isHeadlandTurn)
end

function ImplementController:onTurnEndProgress(workStartNode, shouldLower, isLeftTurn)
function ImplementController:onTurnEndProgress(workStartNode, reversing, shouldLower, isLeftTurn)
end

--- Any object this controller wants us to ignore, can register here a callback at the proximity controller
Expand Down
39 changes: 34 additions & 5 deletions scripts/ai/controllers/PlowController.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ PlowController = CpObject(ImplementController)
function PlowController:init(vehicle, implement)
ImplementController.init(self, vehicle, implement)
self.plowSpec = self.implement.spec_plow
-- towed (not hitch mounted) and can reverse
self.towed = AIUtil.getFirstReversingImplementWithWheels(vehicle, true)
-- temporarily store the direction of the last turn. This hack is for the case when for some reason
-- the plow was not rotated into the working position before lowering. If that's the case, onLowering will
-- rotate it but it needs to know which direction to lower, which, however is not known at that point
-- anymore
self.lastTurnIsLeftTurn = CpTemporaryObject()
end


Expand Down Expand Up @@ -98,22 +105,44 @@ function PlowController:onFinishRow(isHeadlandTurn)
end
end


--- making sure the plow is in the working position when lowering
-- TODO: this whole magic hack would not be necessary if we moved the actual lowering into onTurnEndProgress()
function PlowController:onLowering()
-- if we just turned (that is, not starting to work)
local lastTurnIsLeftTurn = self.lastTurnIsLeftTurn:get()
if lastTurnIsLeftTurn ~= nil and
self:isRotatablePlow() and not self:isFullyRotated() and not self:isRotationActive() then
self:debug('Lowering, rotating plow to working position (last turn is left %s).', lastTurnIsLeftTurn)
-- rotation direction depends on the direction of the last turn
self.implement:setRotationMax(lastTurnIsLeftTurn)
end
end

--- This is called in every loop when we approach the start of the row, the location where
--- the plow must be lowered. Currently AIDriveStrategyFieldworkCourse takes care of the lowering,
--- here we only make sure that the plow is rotated to the work position (from the center position)
--- in time.
---@param workStartNode number node where the work starts as calculated by TurnContext
---@param reversing boolean driving in reverse now
---@param shouldLower boolean the implement should be lowered as we are close to the work start (this
--- should most likely be calculated here in the controller, but for now, we get it from an argument
---@param isLeftTurn boolean is this a left turn?
function PlowController:onTurnEndProgress(workStartNode, shouldLower, isLeftTurn)
function PlowController:onTurnEndProgress(workStartNode, reversing, shouldLower, isLeftTurn)
self.lastTurnIsLeftTurn:set(isLeftTurn or false, 2000)
if self:isRotatablePlow() and not self:isFullyRotated() and not self:isRotationActive() then
-- more or less aligned with the first waypoint of the row, start rotating to working position
-- or, when it should have been lowered, that is, we are too late, not aligned yet, but
-- rotate anyway
if CpMathUtil.isSameDirection(self.implement.rootNode, workStartNode, 30) or shouldLower then
self:debug('Rotating plow to working position now.')
self.implement:setRotationMax(isLeftTurn)
if self.towed then
-- let towed plows remain in the center position while reversing to the start of the row
if not reversing then
self:debug('Rotating towed plow to working position.')
self.implement:setRotationMax(isLeftTurn)
end
else
self:debug('Rotating hitch-mounted plow to working position.')
self.implement:setRotationMax(isLeftTurn)
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion scripts/ai/turns/AITurn.lua
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ function CourseTurn:endTurn(dt)
-- keep driving on the turn course until we need to lower our implements
local shouldLower, dz = self.driveStrategy:shouldLowerImplements(self.turnContext.workStartNode, self.ppc:isReversing())
self.driveStrategy:raiseControllerEvent(AIDriveStrategyCourse.onTurnEndProgressEvent,
self.turnContext.workStartNode, shouldLower, self.turnContext:isLeftTurn())
self.turnContext.workStartNode, self.ppc:isReversing(), shouldLower, self.turnContext:isLeftTurn())
if shouldLower then
if not self.implementsLowered then
-- have not started lowering implements yet
Expand Down
29 changes: 24 additions & 5 deletions scripts/dev/DevHelper.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@ function DevHelper:update()
-- make sure not calling this for something which does not have courseplay installed (only ones with spec_aiVehicle)
if g_currentMission.controlledVehicle and g_currentMission.controlledVehicle.spec_aiVehicle then

if self.vehicle ~= g_currentMission.controlledVehicle then
--self.vehicleData = PathfinderUtil.VehicleData(g_currentMission.controlledVehicle, true)
end

self.vehicle = g_currentMission.controlledVehicle
self.node = g_currentMission.controlledVehicle:getAIDirectionNode()
lx, _, lz = localDirectionToWorld(self.node, 0, 0, 1)
Expand Down Expand Up @@ -169,6 +165,8 @@ function DevHelper:keyEvent(unicode, sym, modifier, isDown)
if ok then
self.course = course
end
elseif bitAND(modifier, Input.MOD_LALT) ~= 0 and isDown and sym == Input.KEY_n then
self:togglePpcControlledNode()
end
end

Expand All @@ -182,11 +180,13 @@ function DevHelper:draw()
for key, value in pairs(self.data) do
table.insert(data, {name = key, value = value})
end
DebugUtil.renderTable(0.65, 0.3, 0.013, data, 0.05)
DebugUtil.renderTable(0.65, 0.27, 0.013, data, 0.05)

self:showFillNodes()
self:showAIMarkers()

self:showDriveData()

if not self.tNode then
self.tNode = createTransformGroup("devhelper")
link(g_currentMission.terrainRootNode, self.tNode)
Expand Down Expand Up @@ -268,6 +268,25 @@ function DevHelper:showAIMarkers()

end

function DevHelper:togglePpcControlledNode()
if not self.vehicle then return end
local strategy = self.vehicle:getCpDriveStrategy()
if not strategy then return end
if strategy.ppc:getControlledNode() == AIUtil.getReverserNode(self.vehicle) then
strategy.pcc:resetControlledNode()
else
strategy.ppc:setControlledNode(AIUtil.getReverserNode(self.vehicle))
end
end

function DevHelper:showDriveData()
if not self.vehicle then return end
local strategy = self.vehicle:getCpDriveStrategy()
if not strategy then return end
strategy.ppc:update()
strategy.reverser:getForwardDriveData()
end

-- make sure to recreate the global dev helper whenever this script is (re)loaded
if g_devHelper then
g_devHelper:delete()
Expand Down
2 changes: 1 addition & 1 deletion scripts/util/CpRemainingTime.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ end

function CpRemainingTime:update(dt)
if g_currentMission.controlledVehicle == self.vehicle and self.DEBUG_ACTIVE and CpDebug:isChannelActive(self.debugChannel, self.vehicle) then
DebugUtil.renderTable(0.4, 0.4, 0.018, {
DebugUtil.renderTable(0.2, 0.2, 0.018, {
{name = "time", value = CpGuiUtil.getFormatTimeText(self.time)},
{name = "optimal speed", value = MathUtil.mpsToKmh(self:getOptimalSpeed())},
{name = "optimal time", value = CpGuiUtil.getFormatTimeText(self:getOptimalCourseTime(self.course, self.lastIx))},
Expand Down

0 comments on commit e13b7e8

Please sign in to comment.