Changelog
- page Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
[2.1.0] - 2026-09-03
Added
f2c::hg::ReqHL, a headland generator that sizes each border on its own: a border the swaths run along is only entered, while a border they end on takes a whole turn. The difference is left to the mainland instead of being given up on every border.HeadlandGeneratorBase::generateHeadlandsoverloads taking a robot and the track angles, andmaxHLWidthRequired.F2CLinearRing::getParallelLine,bufferOutwards,bufferInwards,filterSelfIntersections,removePoint,getSegment,getLastSegment,segmentLengthandsegmentAng, to offset each segment of a ring by its own distance.Geometry::contains, the other side ofGeometry::within.f2c::hg::CorridorHL, a headland generator that opens a corridor where cells border each other instead of shrinking every border. Only the part of an edge a neighbour actually touches is cut, and the corridor comes out of the smaller cell so the larger neighbour keeps its shape; cells of the same size split it evenly. Edges facing the outer boundary or a void are left untouched.f2c::hg::CorridorHL::corridorShares, the rule that generator applies, on its own: for each pair of cells that share a border it reports the two perimeters, whether they count as the same size, how much of the corridor each cell gives, and the border they share.f2c::hg::CorridorShareMode, to split every corridor evenly (SYMMETRIC) instead of giving it all to the smaller cell (ASYMMETRIC, the default).CorridorHL::corridorSharestakes it as an argument, andCorridorHL::setShareMode/getShareModeset the modegenerateHeadlandsapplies.Python module is built as a proper package with scikit-build-core (
pip install .); version is taken fromCMakeLists.txtand exposed asfields2cover.__version__.Source distribution published to PyPI (
pip install fields2cover).
Fixed
f2c::hg::CorridorHLno longer opens a corridor where two cells only meet at a corner. The neighbour is buffered by a tolerance to find the shared border, which turned a single shared point into a few millimetres of “border” on every edge reaching it; in a field of cells meeting at one point that carved a disc out of the middle and made every slice a neighbour of every other.Cells::splitByLineno longer throwsstd::invalid_argumentwhen a split leaves a piece touching itself at a single point. Reinflating each split piece went throughCell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. AMultiLineStringsplit also no longer silently keeps only the first line’s cut: reinflating after every individual line let GEOS collapse the next cut into a no-op, so every line is now buffered and cut in one pass instead of one after another.F2CCells::getCellBorder,getInteriorRingandaddRingno longer segfault on an empty polygon or an out-of-range index; they throwstd::out_of_rangelikegetGeometrydoes.NSwathModified::computeCostread the wrong neighbouring point for the first edge:(i - 1) % ring.size()wraps asize_ttoSIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.generateBestSwathsno longer returns an angle that covers nothing. The objectives estimate the cost from the cell border alone, so a cell with a hairline spur could score best on an angle producing no swath at all and was silently left uncovered.
Changed
CorridorHL’s tolerances (the neighbour-buffer, spur, same-size and minimum-border thresholds) are private member variables instead of constants hidden in the .cpp file, visible directly on the class in the header.The decomposition tutorial carves a corridor between cells instead of running the headland generator a second time, which also shrank the outer boundary.
cmake --installplaces the python module in the interpreter’s site-packages instead of callingsetup.py install.Building the python module requires CMake >= 3.18 and Python >= 3.9.
[2.0.0] - 07-02-2024
Route planner travelling through the headlands
[1.3.0] - 21-04-2023
Add decomposition algorithms: trapezoidal, boustrophedon
[1.2.0] - 17-10-2022
Added
Tests to do cover < 90% functions
Changes
SG use the objective function as a parameter instead of a template.
RP do not save the swaths and modify them using the functions provided
PP do not save the robot and use the robot params with a param on the function.
Changes
Objectives are split for each of the modules.
Global objective renamed to SG objective.
Path objective renamed to RP objective.
Added
PP objective
HL objective
[1.1.0]
Added
On HL module: constant headland algorithm.
On SG module: brute force algorithm.
On RP module: Boustrophedon, custom, snake and spiral.
On PP module: Dubins and Reeds-Sheep with/without continuous curvature.
Objective functions are split between global and path cost functions.