From 4f317d1286c0a5891f9218fd2c76ed92a942693d Mon Sep 17 00:00:00 2001 From: Peter Vaiko Date: Mon, 25 Jan 2021 17:00:01 -0600 Subject: [PATCH] 6.03.00032 Convoy and attach/detach fixes - Better progress calculation for convoy mode (fixes #6011) - Reset mode when detaching/attaching implements (fixes #6727). This caused some implements not reversing correctly. --- Waypoint.lua | 44 ++++++++++++++++++++++++++++++++------ modDesc.xml | 2 +- test/mock-GiantsEngine.lua | 4 +++- toolManager.lua | 6 +++--- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/Waypoint.lua b/Waypoint.lua index c047b613b..d51a10f57 100644 --- a/Waypoint.lua +++ b/Waypoint.lua @@ -266,7 +266,6 @@ function Course:init(vehicle, waypoints, temporary, first, last) self.currentWaypoint = 1 self.length = 0 self.headlandLength = 0 - self.nHeadlandWaypoints = 0 self.totalTurns = 0 self:enrichWaypointData() end @@ -276,6 +275,7 @@ function Course.createFromGeneratedCourse(vehicle, waypoints, temporary, first, for i = first or 1, last or #waypoints do table.insert(course.waypoints, Waypoint.initFromGeneratedWp(waypoints[i], i)) end + course:enrichWaypointData() return course end @@ -350,24 +350,24 @@ end function Course:enrichWaypointData() if #self.waypoints < 2 then return end self.length = 0 - self.nHeadlandWaypoints = 0 self.headlandLength = 0 self.firstHeadlandWpIx = nil self.firstCenterWpIx = nil + local dOnHeadland = 0 for i = 1, #self.waypoints - 1 do local cx, _, cz = self:getWaypointPosition(i) - local nx, _, nz = self:getWaypointPosition( i + 1) + local nx, _, nz = self:getWaypointPosition(i + 1) local dToNext = courseplay:distance(cx, cz, nx, nz) self.length = self.length + dToNext if self:isOnHeadland(i) then - self.nHeadlandWaypoints = self.nHeadlandWaypoints + 1 self.headlandLength = self.headlandLength + dToNext self.firstHeadlandWpIx = self.firstHeadlandWpIx or i + dOnHeadland = dOnHeadland + dToNext else -- TODO: this and firstHeadlandWpIx works only if there is one block on the field and -- no islands, as then we have more than one group of headlands. But these are only -- for the convoy mode anyway so it is ok if it does not work in all possible situations - self.firstCenterWpIx = self.firstCenterWpIx or i + self.firstCenterWpIx = self.firstCenterWpIx or i end if self:isTurnStartAtIx(i) then self.totalTurns = self.totalTurns + 1 end if self:isTurnEndAtIx(i) then @@ -377,6 +377,7 @@ function Course:enrichWaypointData() end self.waypoints[i].dToNext = dToNext self.waypoints[i].dToHere = self.length + self.waypoints[i].dToHereOnHeadland = dOnHeadland self.waypoints[i].turnsToHere = self.totalTurns self.waypoints[i].dx, _, self.waypoints[i].dz, _ = courseplay:getWorldDirection(cx, 0, cz, nx, 0, nz) local dx, dz = MathUtil.vector2Normalize(nx - cx, nz - cz) @@ -405,6 +406,9 @@ function Course:enrichWaypointData() self.waypoints[#self.waypoints].dz = self.waypoints[#self.waypoints - 1].dz self.waypoints[#self.waypoints].dToNext = 0 self.waypoints[#self.waypoints].dToHere = self.length + self.waypoints[#self.waypoints - 1].dToNext + self.waypoints[#self.waypoints].dToHereOnHeadland = self:isOnHeadland(#self.waypoints - 1) and + self.waypoints[#self.waypoints - 1].dToHereOnHeadland + self.waypoints[#self.waypoints - 1].dToNext or + self.waypoints[#self.waypoints - 1].dToHereOnHeadland self.waypoints[#self.waypoints].turnsToHere = self.totalTurns self.waypoints[#self.waypoints].calculatedRadius = self:calculateRadius(#self.waypoints) self.waypoints[#self.waypoints].reverseOffset = self:isReverseAt(#self.waypoints) @@ -1390,6 +1394,20 @@ function Course:calculateOffsetCourse(nVehicles, position, width, useSameTurnWid end end end + courseplay.debugFormat(7, 'Original headland length %.0f m, new headland length %.0f m (%.1f %%, %.1f m)', + self.headlandLength, offsetCourse.headlandLength, 100 * offsetCourse.headlandLength / self.headlandLength, + offsetCourse.headlandLength - self.headlandLength) + local originalNonHeadlandLength = self.length - self.headlandLength + local offsetNonHeadlandLength = offsetCourse.length - offsetCourse.headlandLength + courseplay.debugFormat(7, 'Original non-headland length %.0f m, new non-headland length %.0f m (%.1f %%, %.1f m)', + originalNonHeadlandLength, offsetNonHeadlandLength, + 100 * offsetNonHeadlandLength / originalNonHeadlandLength, + offsetNonHeadlandLength - originalNonHeadlandLength) + -- remember this for the convoy progress calculation + offsetCourse.headlandLengthRatio = self.headlandLength / offsetCourse.headlandLength + offsetCourse.nonHeadlandLengthRatio = originalNonHeadlandLength / offsetNonHeadlandLength + offsetCourse.originalCourseLength = offsetCourse.nonHeadlandLengthRatio * offsetNonHeadlandLength + + offsetCourse.headlandLengthRatio * offsetCourse.headlandLength -- apply tool offset to new course offsetCourse:setOffset(self.offsetX, self.offsetZ) return offsetCourse @@ -1519,6 +1537,20 @@ end function Course:getProgress(ix) ix = ix or self:getCurrentWaypointIx() - return self.waypoints[ix].dToHere / self.length + if self.originalCourseLength then + -- this is an offset course, measure progress in the original course + -- we assume that the non-headland part of the course is the same as the original ... + local dToHereOnNonHeadland = self.waypoints[ix].dToHere - self.waypoints[ix].dToHereOnHeadland + -- however, the headland part is shorter or longer for the inner and outer offsets (when using multiple tools + -- on the same field in a group, for example 3 combines, one on the original course, on on the left, one on + -- the right. When working clockwise, the headland for one on the right is shorter. + -- So, we project the distance elapsed on the actual offset headland back to the distance elapsed on the + -- original headland. + local dToHere = self.nonHeadlandLengthRatio * dToHereOnNonHeadland + + self.headlandLengthRatio * self.waypoints[ix].dToHereOnHeadland + return dToHere / self.originalCourseLength + else + return self.waypoints[ix].dToHere / self.length + end end diff --git a/modDesc.xml b/modDesc.xml index d0332e864..96db11f8c 100644 --- a/modDesc.xml +++ b/modDesc.xml @@ -1,6 +1,6 @@ - 6.03.00031 + 6.03.00032 <!-- 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> diff --git a/test/mock-GiantsEngine.lua b/test/mock-GiantsEngine.lua index 5bbc73bf9..83b4b83b8 100644 --- a/test/mock-GiantsEngine.lua +++ b/test/mock-GiantsEngine.lua @@ -90,4 +90,6 @@ function giantsVehicle.getSpeedLimit() return 10 end -function giantsVehicle.setCruiseControlMaxSpeed() end \ No newline at end of file +function giantsVehicle.setCruiseControlMaxSpeed() end + +g_time = 0 \ No newline at end of file diff --git a/toolManager.lua b/toolManager.lua index bcf071f1d..b7d9a2c6d 100644 --- a/toolManager.lua +++ b/toolManager.lua @@ -54,7 +54,7 @@ function courseplay:resetTools(vehicle) vehicle.cp.hasAugerWagon = false; vehicle.cp.workToolAttached = courseplay:updateWorkTools(vehicle, vehicle); - if not vehicle.cp.workToolAttached and not vehicle.cp.mode == courseplay.MODE_BUNKERSILO_COMPACTER then + if not vehicle.cp.workToolAttached and vehicle.cp.mode ~= courseplay.MODE_BUNKERSILO_COMPACTER then courseplay:setCpMode(vehicle, courseplay.MODE_TRANSPORT) end @@ -477,7 +477,7 @@ function courseplay:getAIMarkerWidth(object, logPrefix) end end ---this one enable the buttons and allowes the user to change the mode +--this one enable the buttons and allows the user to change the mode function courseplay:getIsToolCombiValidForCpMode(vehicle,cpModeToCheck) --5 is always valid if cpModeToCheck == 5 then @@ -493,7 +493,7 @@ function courseplay:getIsToolCombiValidForCpMode(vehicle,cpModeToCheck) end function courseplay:getIsToolValidForCpMode(object, mode, callback) - isAllowedOkay,isDisallowedOkay = CpManager.validModeSetupHandler:isModeValid(mode,object) + local isAllowedOkay,isDisallowedOkay = CpManager.validModeSetupHandler:isModeValid(mode,object) callback.isAllowedOkay = callback.isAllowedOkay or isAllowedOkay callback.isDisallowedOkay = callback.isDisallowedOkay and isDisallowedOkay for _,impl in pairs(object:getAttachedImplements()) do