Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
jazzy

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
kilted

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
lyrical

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
rolling

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro ardent showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro bouncy showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro crystal showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro eloquent showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro dashing showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro galactic showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro foxy showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
iron

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro lunar showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro jade showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro indigo showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro hydro showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro kinetic showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

No version for distro melodic showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
humble

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange

Package symbol

fields2cover package from fields2cover repo

fields2cover

ROS Distro
noetic

Package Summary

Version 2.1.0
License BSD-3
Build type CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/Fields2Cover/fields2cover.git
VCS Type git
VCS Version main
Last Updated 2026-09-03
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Robust and efficient coverage paths for autonomous agricultural vehicles. A modular and extensible Coverage Path Planning library

Maintainers

  • Gonzalo Mier

Authors

No additional authors.

Fields2Cover logo

Robust and efficient coverage paths for autonomous agricultural vehicles

DocumentationInstallationQuick StartTutorialsAPIPaper

build coverage PyPI license DOI

Fields2Cover is an open-source C++ library with Python bindings that solves the Coverage Path Planning problem for agriculture: given a field and a vehicle, it computes a complete coverage path — headlands, swaths, an optimized route, and a drivable path with feasible turns. It also provides a common, extensible framework to implement and compare coverage path planning algorithms, so researchers don’t have to re-implement every algorithm they want to compare against. The API is still evolving, so expect occasional breaking changes between releases.

Fields2Cover module diagram

Core features

  • Modular pipeline: headland generation, swath generation, route planning and path planning as interchangeable modules — or a single call to planCovPath.
  • Non-convex fields and obstacles, handled by trapezoidal and boustrophedon decomposition.
  • Route optimization with OR-tools, plus classic patterns like boustrophedon, snake and spiral.
  • Kinematically feasible turns using Dubins and Reeds-Shepp curves, with or without continuous curvature.
  • C++17 core, Python bindings, and a ROS 2 integration via opennav_coverage.

Quick Start

Fields2Cover builds on GDAL, GEOS and OR-tools, which need to be installed first (details in the installation guide):

# Ubuntu
sudo apt install build-essential libgdal-dev libgeos-dev libeigen3-dev libboost-dev \
     libtbb-dev libtinyxml2-dev nlohmann-json3-dev libpython3-dev gnuplot
# plus OR-tools for C++: https://developers.google.com/optimization/install/cpp

# macOS
brew install gdal geos or-tools tinyxml2 eigen tbb boost gnuplot

C++

#include "fields2cover.h"

int main() {
  F2CField field = f2c::Parser::importFieldGml("data/test1.xml");
  F2CRobot robot(2.0, 6.0, 0.5, 0.2);

  F2CPath path = f2c::planCovPath(robot, field, false);

  f2c::Visualizer::figure();
  f2c::Visualizer::plot(field.getCellsAbsPosition());
  f2c::Visualizer::plot(path);
  f2c::Visualizer::show();
  return 0;
}

find_package(Fields2Cover REQUIRED)
target_link_libraries(<your_target> Fields2Cover)

Python

pip install fields2cover

import fields2cover as f2c

field = f2c.Parser().importFieldGml("data/test1.xml")
robot = f2c.Robot(2.0, 6.0, 0.5, 0.2)

path = f2c.planCovPath(robot, field, False)

f2c.Visualizer.figure()
f2c.Visualizer.plot(field.getCellsAbsPosition())
f2c.Visualizer.plot(path)
f2c.Visualizer.show()

Installation

  • Python: pip install fields2cover — the package is built from source on your machine, so the system dependencies above must be installed.
  • C++ / from source: clone this repository and build with CMake — full walkthrough in the installation guide.
  • ROS 2: see opennav_coverage, a Nav2-compatible coverage task server built on Fields2Cover.

File truncated at 100 lines see the full file

CHANGELOG

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::generateHeadlands overloads taking a robot and the track angles, and maxHLWidthRequired.
  • F2CLinearRing::getParallelLine, bufferOutwards, bufferInwards, filterSelfIntersections, removePoint, getSegment, getLastSegment, segmentLength and segmentAng, to offset each segment of a ring by its own distance.
  • Geometry::contains, the other side of Geometry::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::corridorShares takes it as an argument, and CorridorHL::setShareMode/getShareMode set the mode generateHeadlands applies.
  • Python module is built as a proper package with scikit-build-core (pip install .); version is taken from CMakeLists.txt and exposed as fields2cover.__version__.
  • Source distribution published to PyPI (pip install fields2cover).

Fixed

  • f2c::hg::CorridorHL no 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::splitByLine no longer throws std::invalid_argument when a split leaves a piece touching itself at a single point. Reinflating each split piece went through Cell::buffer, which only accepts a single polygon back; a positive buffer on a pinched piece can separate it into two. A MultiLineString split 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, getInteriorRing and addRing no longer segfault on an empty polygon or an out-of-range index; they throw std::out_of_range like getGeometry does.
  • NSwathModified::computeCost read the wrong neighbouring point for the first edge: (i - 1) % ring.size() wraps a size_t to SIZE_MAX % n, which is not the previous vertex. The cost of a polygon now no longer depends on which vertex its ring starts from.
  • generateBestSwaths no 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 --install places the python module in the interpreter’s site-packages instead of calling setup.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.

Dependant Packages

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged fields2cover at Robotics Stack Exchange