Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sharp corner improvements #3560

Merged
merged 11 commits into from
Oct 26, 2024
Merged
2 changes: 1 addition & 1 deletion config/CourseGeneratorSettingsSetup.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<SettingSubTitle title="headland" isVisible="hasHeadlandsSelected">
<Setting classType="AIParameterBooleanSetting" name="sharpenCorners" defaultBool="false"/>
<Setting classType="AIParameterSettingList" name="headlandsWithRoundCorners" min="0" max="50" default="1"/>
<Setting classType="AIParameterSettingList" name="turningRadius" min="5" max="15" setDefault="setDefaultTurningRadius"/>
<Setting classType="AIParameterSettingList" name="turningRadius" min="5" max="12" setDefault="setDefaultTurningRadius"/>
<Setting classType="AIParameterBooleanSetting" name="headlandClockwise" defaultBool="true">
<Texts>
<Text>counterclockwise</Text>
Expand Down
2 changes: 1 addition & 1 deletion scripts/courseGenerator/CourseGenerator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ CourseGenerator.cRowWaypointDistance = 7
-- Maximum cross track error we tolerate when a vehicle follows a path. This is used to
-- find corners which the vehicle can't make due to its turning radius, without deviating more than
-- cMaxCrossTrackError meters from the vertex in the corner.
CourseGenerator.cMaxCrossTrackError = 0.5
CourseGenerator.cMaxCrossTrackError = 0.2
-- Maximum cross track error when generating rows parallel to a non-straight field edge. The row will end when
-- the cross track error is bigger than this limit
CourseGenerator.cMaxCrossTrackErrorForCurvedRows = 0.15
Expand Down
2 changes: 1 addition & 1 deletion scripts/courseGenerator/CourseGeneratorInterface.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function CourseGeneratorInterface.generate(fieldPolygon,
context:setBaselineEdge(startPosition.x, -startPosition.z)
context:setFieldMargin(settings.fieldMargin:getValue())
context:setUseBaselineEdge(settings.useBaseLineEdge:getValue())
context:setFieldCornerRadius(settings.turningRadius:getValue())
context:setFieldCornerRadius(7) --using a default, that is used during testing
context:setHeadlandFirst(settings.startOnHeadland:getValue())
context:setHeadlandClockwise(settings.headlandClockwise:getValue())
context:setHeadlandOverlap(settings.headlandOverlapPercent:getValue())
Expand Down
1 change: 1 addition & 0 deletions scripts/courseGenerator/FieldworkCourse.lua
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ function FieldworkCourse:_setContext(context)
self.logger:debug('sharpening field boundary corners')
self.boundary:ensureMinimumRadius(self.context.fieldCornerRadius, true)
end
CourseGenerator.addDebugPolyline(self.boundary, {0, 1, 1, 0.3})
end

function FieldworkCourse:_removeHeadland(n)
Expand Down
2 changes: 1 addition & 1 deletion scripts/courseGenerator/test/PolygonTest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ function testPolygon()

p = Polygon({ Vector(-20, 0), Vector(-15, -3), Vector(-10, -4), Vector(-5, -4),
Vector(0, 0), Vector(5, 0), Vector(10, 0), Vector(15, 0) })
lu.assertAlmostEquals(p:getSmallestRadiusWithinDistance(4, 15, 20), 3.02)
lu.assertAlmostEquals(p:getSmallestRadiusWithinDistance(4, 15, 20), 1.61)

p = Polygon({ Vector(0, 0), Vector(0, 5), Vector(5, 5), Vector(5, 0) })
lu.assertEquals(p:moveForward(1, 6), 3)
Expand Down
20 changes: 16 additions & 4 deletions scripts/courseGenerator/test/VertexTest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,32 @@ function testVertex()
v:getExitEdge():assertAlmostEquals(CourseGenerator.LineSegment(0, 0, 1, 0))
lu.assertEquals(v:getSignedRadius(), math.huge)

v = Vertex(0, 0)
v:calculateProperties(Vertex(-1, 0), Vertex(0, 1))
lu.assertAlmostEquals(v:getEntryHeading(), 0)
lu.assertAlmostEquals(v:getExitHeading(), math.pi / 2)

v:getEntryEdge():assertAlmostEquals(CourseGenerator.LineSegment(-1, 0, 0, 0))
v:getExitEdge():assertAlmostEquals(CourseGenerator.LineSegment(0, 0, 0, 1))
lu.assertAlmostEquals(v:getSignedRadius(), 1)
v:calculateProperties(Vertex(-1, 0), Vertex(0, -1))
lu.assertAlmostEquals(v:getSignedRadius(), -1)

v = Vertex(0, 0)
v:calculateProperties(Vertex(-1, 0), Vertex(1, 1))
lu.assertAlmostEquals(v:getEntryHeading(), 0)
lu.assertAlmostEquals(v:getExitHeading(), math.pi / 4)

v:getEntryEdge():assertAlmostEquals(CourseGenerator.LineSegment(-1, 0, 0, 0))
v:getExitEdge():assertAlmostEquals(CourseGenerator.LineSegment(0, 0, 1, 1))
lu.assertAlmostEquals(v:getSignedRadius(), 1.84)
lu.assertAlmostEquals(v:getSignedRadius(), 3.41)
v:calculateProperties(Vertex(-1, 0), Vertex(1, -1))
lu.assertAlmostEquals(v:getSignedRadius(), -1.84)
lu.assertAlmostEquals(v:getSignedRadius(), -3.41)

v = Vertex(0, 0)
v:calculateProperties(Vertex(-5, 0), Vertex(5, 5))
lu.assertAlmostEquals(v:getSignedRadius(), 9.23)
lu.assertAlmostEquals(v:getSignedRadius(), 17.07)
v:calculateProperties(Vertex(-5, 0), Vertex(0, 5))
lu.assertAlmostEquals(v:getSignedRadius(), 2.5 * math.sqrt(2))
lu.assertAlmostEquals(v:getSignedRadius(), 5)
end
os.exit(lu.LuaUnit.run())
3 changes: 2 additions & 1 deletion scripts/geometry/Polyline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -487,8 +487,9 @@ function Polyline:ensureMinimumRadius(r, makeCorners)
currentIx = nextIx
nextIx = currentIx + 1
local xte = self:at(currentIx):getXte(r)
local radius = self:at(currentIx):getRadius()
if xte > CourseGenerator.cMaxCrossTrackError then
self.logger:debug('ensureMinimumRadius (%s): found a corner at %d, r: %.1f, xte: %.1f', debugId, currentIx, r, xte)
self.logger:debug('ensureMinimumRadius (%s): found a corner at %d with r: %.1f, r: %.1f, xte: %.1f', debugId, currentIx, radius, r, xte)
-- looks like we can't make this turn without deviating too much from the course,
local entry = CourseGenerator.Slider(self, currentIx, 0)
local exit = CourseGenerator.Slider(self, currentIx, 0)
Expand Down
13 changes: 3 additions & 10 deletions scripts/geometry/Vertex.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,6 @@ function Vertex:getExitHeading()
return self.exitHeading
end

--- The radius at this vertex, calculated from the direction of the entry/exit edges as unit vectors.
--- Positive values are left turns, negative values right turns
---@return number radius
function Vertex:getUnitRadius()
return self.unitRadius
end

--- The radius at this vertex, calculated from the direction of the entry/exit edges and the length of
--- the exit edge. This is the radius a vehicle would need to drive to reach the next waypoint.
--- Positive values are left turns, negative values right turns
Expand Down Expand Up @@ -122,9 +115,9 @@ function Vertex:calculateProperties(entry, exit)
end
if self.entryHeading and self.exitHeading then
self.dA = CpMathUtil.getDeltaAngle(self.entryHeading, self.exitHeading)
-- This is the radius of the unit circle written between
-- entryEdge and exitEdge, which are tangents of the circle
self.unitRadius = 1 / (2 * math.sin(self.dA / 2))
-- This is the radius of a circle written between
-- entryEdge and exitEdge, which are tangents of the circle, touching them 1 unit away from the vertex
self.unitRadius = 1 / (math.tan(self.dA / 2))
self.curvature = 1 / self.unitRadius
self.xte = math.abs(1 / math.cos(self.dA / 2)) - 1
end
Expand Down
Loading