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

Commit

Permalink
Fix for #6340
Browse files Browse the repository at this point in the history
Polygon iterator fixed to always normalize
to the range of vertices.
  • Loading branch information
pvaiko committed Nov 22, 2020
1 parent 597f3d4 commit 6330bb8
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 40 deletions.
57 changes: 32 additions & 25 deletions course-generator/center.lua
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,28 @@ function findBestTrackAngle( polygon, islands, width, distanceFromBoundary, cent
return b.angle, b.nTracks, b.nBlocks, b.smallBlockScore == 0 or centerSettings.useBestAngle
end

local function addWaypointsToBlocks(blocks, width, extendTracks)
-- using a while loop as we'll remove blocks if they have no tracks
local nTotalTracks = 0
local i = 1
while blocks[i] do
local block = blocks[i]
nTotalTracks = nTotalTracks + #block
courseGenerator.debug( "Block %d has %d tracks", i, #block )
block.tracksWithWaypoints = addWaypointsToTracks( block, width, extendTracks )
block.covered = false
-- we may end up with blocks without tracks in case we did not find a single track
-- with at least two waypoints. Now remove those blocks
if #blocks[i].tracksWithWaypoints == 0 then
courseGenerator.debug( "Block %d removed as it has no tracks with waypoints", i)
table.remove(blocks, i)
else
i = i + 1
end
end
return nTotalTracks
end

--- Count the blocks with just a few tracks
function countSmallBlockScore( blocks )
local nResult = 0
Expand All @@ -210,14 +232,15 @@ end

--- Generate up/down tracks covering a polygon at the optimum angle
--
function generateTracks( headlands, islands, width, extendTracks, nHeadlandPasses, centerSettings )
local distanceFromBoundary
function generateTracks( headlands, islands, width, nHeadlandPasses, centerSettings )
local distanceFromBoundary, extendTracks
if nHeadlandPasses == 0 then
-- ugly hack: if there are no headlands, our tracks go right up to the field boundary. So extend tracks
-- exactly width / 2
extendTracks = extendTracks + width / 2
extendTracks = width / 2
distanceFromBoundary = width / 2
else
extendTracks = 0
distanceFromBoundary = width
end

Expand Down Expand Up @@ -262,24 +285,7 @@ function generateTracks( headlands, islands, width, extendTracks, nHeadlandPasse

local blocks = splitCenterIntoBlocks( parallelTracks, width )

-- using a while loop as we'll remove blocks if they have no tracks
local nTotalTracks = 0
local i = 1
while blocks[i] do
local block = blocks[i]
nTotalTracks = nTotalTracks + #block
courseGenerator.debug( "Block %d has %d tracks", i, #block )
block.tracksWithWaypoints = addWaypointsToTracks( block, width, extendTracks )
block.covered = false
-- we may end up with blocks without tracks in case we did not find a single track
-- with at least two waypoints. Now remove those blocks
if #blocks[i].tracksWithWaypoints == 0 then
courseGenerator.debug( "Block %d removed as it has no tracks with waypoints", i)
table.remove(blocks, i)
else
i = i + 1
end
end
local nTotalTracks = addWaypointsToBlocks(blocks, width, extendTracks)

if #blocks > 30 or ( #blocks > 1 and ( nTotalTracks / #blocks ) < 2 ) then
-- don't waste time on unrealistic problems
Expand Down Expand Up @@ -315,14 +321,14 @@ function generateTracks( headlands, islands, width, extendTracks, nHeadlandPasse
end
end
courseGenerator.debug( '%d. block %d, entry corner %d, direction to next = %d, on the bottom = %s, on the left = %s', i, block.id, block.entryCorner,
block.directionToNextBlock or 0, tostring( isCornerOnTheBottom( block.entryCorner )), tostring( isCornerOnTheLeft( block.entryCorner )))
block.directionToNextBlock or 0, tostring( isCornerOnTheBottom( block.entryCorner )), tostring( isCornerOnTheLeft( block.entryCorner )))
local continueWithTurn = not block.trackToThisBlock
if continueWithTurn then
track[ #track ].turnStart = true
end
local linkedTracks = linkParallelTracks(block.tracksWithWaypoints,
isCornerOnTheBottom( block.entryCorner ), isCornerOnTheLeft( block.entryCorner ), centerSettings, continueWithTurn,
transformedHeadlands, rotatedIslands, width)
isCornerOnTheBottom( block.entryCorner ), isCornerOnTheLeft( block.entryCorner ), centerSettings, continueWithTurn,
transformedHeadlands, rotatedIslands, width)
-- remember where the up/down rows start (transition from headland to up/down rows)
if i == 1 then
linkedTracks[1].upDownRowStart = #track
Expand Down Expand Up @@ -1141,8 +1147,9 @@ function findBlockSequence( blocks, headland, circleStart, circleStep, nHeadland
if nHeadlandPasses > 0 then
distance, dir = getDistanceBetweenPointsOnHeadland( headland, circleStart, currentBlockEntryPoint.index, { circleStep } )
else
-- if ther's no headland, look for the closest point no matter what direction (as we can ignore the clockwise/ccw settings)
-- if there is no headland, look for the closest point no matter what direction (as we can ignore the clockwise/ccw settings)
distance, dir = getDistanceBetweenPointsOnHeadland( headland, circleStart, currentBlockEntryPoint.index, { -1, 1 } )
--print(currentBlockIx, chromosome.entryCorner[currentBlockIx], distance, dir, circleStart, currentBlockEntryPoint.index)
end
chromosome.distance, chromosome.directionToNextBlock[ currentBlockIx ] = chromosome.distance + distance, dir
else
Expand Down
3 changes: 1 addition & 2 deletions course-generator/cp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ function courseGenerator.generate( vehicle )
vehicle.cp.oldCourseGeneratorSettings.startingLocationWorldPos.z)
end

local extendTracks = 0
local minDistanceBetweenPoints = 0.5
local doSmooth = true
local roundCorners = false
Expand Down Expand Up @@ -173,7 +172,7 @@ function courseGenerator.generate( vehicle )
end
local status, ok = xpcall( generateCourseForField, function(err) printCallstack(); return err end,
field, workWidth, headlandSettings,
extendTracks, minDistanceBetweenPoints,
minDistanceBetweenPoints,
minSmoothAngle, maxSmoothAngle, doSmooth,
roundCorners, turnRadiusAdjustedForMultiTool,
courseGenerator.pointsToXy( islandNodes ),
Expand Down
4 changes: 2 additions & 2 deletions course-generator/geo.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1166,8 +1166,8 @@ end
-- This will do a full circle, that is, roll over from
-- #polygon to 1 or 1 to #polygon if step < 0
function Polygon:iterator( from, to, step )
local i = from or 1
local n = to or #self
local i = from and self:getIndex(from) or 1
local n = to and self:getIndex(to) or #self
local s = step or 1
local lastOne = false
return function()
Expand Down
2 changes: 1 addition & 1 deletion course-generator/headland.lua
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ function calculateOneSide(boundary, innerBoundary, startIx, endIx, step, rightSi
return headlands
end

function generateTwoSideHeadlands( polygon, islands, implementWidth, extendTracks, headlandSettings, centerSettings,
function generateTwoSideHeadlands( polygon, islands, implementWidth, headlandSettings, centerSettings,
minDistanceBetweenPoints, minSmoothAngle, maxSmoothAngle )
-- translate polygon so we can rotate it around its center. This way all points
-- will be approximately the same distance from the origin and the rotation calculation
Expand Down
16 changes: 6 additions & 10 deletions course-generator/track.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,7 @@
-- center tracks to skip. When 0, normal alternating tracks are generated
-- when > 0, intermediate tracks are skipped to allow for wider turns
--
-- extendTracks
-- extend center tracks into the headland (meters) to prevent unworked
-- triangles with long plows.
--
-- minDistanceBetweenPoints
-- minDistanceBetweenPoints
-- minimum distance allowed between vertices. Keeps the number of generated
-- vertices for headland passes low. For fine tuning only
--
Expand Down Expand Up @@ -103,7 +99,7 @@
-- instead of trying to find the optimal angle.
--

function generateCourseForField( field, implementWidth, headlandSettings, extendTracks,
function generateCourseForField( field, implementWidth, headlandSettings,
minDistanceBetweenPoints, minSmoothAngle, maxSmoothAngle, doSmooth, fromInside,
turnRadius, islandNodes, islandBypassMode, centerSettings )

Expand Down Expand Up @@ -136,24 +132,24 @@ function generateCourseForField( field, implementWidth, headlandSettings, extend
linkHeadlandTracks( field, implementWidth, headlandSettings.isClockwise, headlandSettings.startLocation, doSmooth, minSmoothAngle, maxSmoothAngle )

field.track, field.bestAngle, field.nTracks, field.blocks, resultIsOk = generateTracks( field.headlandTracks, field.bigIslands,
implementWidth, extendTracks, headlandSettings.nPasses, centerSettings )
implementWidth, headlandSettings.nPasses, centerSettings )
elseif headlandSettings.nPasses == 0 or -- TODO: use the mode only, not nPasses, this is only for backwards compatibility
headlandSettings.mode == courseGenerator.HEADLAND_MODE_NONE then
-- no headland pass wanted, still generate a dummy one on the field boundary so
-- we have something to work with when generating the up/down tracks
field.headlandTracks[ 1 ] = calculateHeadlandTrack( field.boundary, courseGenerator.HEADLAND_MODE_NORMAL, field.boundary.isClockwise, 0, minDistanceBetweenPoints, minSmoothAngle, maxSmoothAngle, 0, doSmooth, not fromInside, nil, nil )
linkHeadlandTracks( field, implementWidth, headlandSettings.isClockwise, headlandSettings.startLocation, doSmooth, minSmoothAngle, maxSmoothAngle )
field.track, field.bestAngle, field.nTracks, field.blocks, resultIsOk = generateTracks( field.headlandTracks, field.bigIslands,
implementWidth, extendTracks, headlandSettings.nPasses, centerSettings )
implementWidth, headlandSettings.nPasses, centerSettings )
elseif headlandSettings.mode == courseGenerator.HEADLAND_MODE_TWO_SIDE then
-- force headland corners
headlandSettings.minHeadlandTurnAngleDeg = 60
-- start with rows over the field with no headland.
local boundary
field.headlandPath, boundary = generateTwoSideHeadlands( field.boundary, field.bigIslands,
implementWidth, extendTracks, headlandSettings, centerSettings, minDistanceBetweenPoints, minSmoothAngle, maxSmoothAngle)
implementWidth, headlandSettings, centerSettings, minDistanceBetweenPoints, minSmoothAngle, maxSmoothAngle)
field.track, field.bestAngle, field.nTracks, field.blocks, resultIsOk = generateTracks({ boundary }, field.bigIslands,
implementWidth, extendTracks - implementWidth / 2, 0, centerSettings )
implementWidth - implementWidth / 2, 0, centerSettings )
end
courseGenerator.debug("####### COURSE GENERATOR END ###########################################################")

Expand Down

0 comments on commit 6330bb8

Please sign in to comment.