Open
Description
I have used this ros package https://github.com/ethz-asl/polygon_coverage_planning. It is interesting because, It can handles obstacle polygons inside an external polygon that define the terrain limits. The ui is also interesting allowing for polygon drawing in rviz and capability to draw over a satellite image, row overlap etc. But has a few drawbacks :
- not ros 2
- not integrated in the navigation stack
- since it was conceive for drone, points in the path do not have orientation.
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
[-]Improvement Proposal[/-][+]Rviz UI[/+]SteveMacenski commentedon May 20, 2024
Sounds like good potential inhancements! This has the ability to process internal voids with the new F2C release and update in #53. The rviz drawing UI not so much, but that would be relatively straight forward to add. I actually did some of my testing by using the
clicked_point
topic in rviz to set points for tests, so its easy to subscribe to that to populate polygons (or create a whole rviz panel thing for additional options).An effort from yourself or others interested in this capability would be greatly appreciated and I'd be happy to review / merge it to have that available for the community!
I hope you don't mind, I renamed the ticket to be a bit more descriptive
Chuckwisc commentedon Apr 2, 2025
The opennav_coverage_demo is working for me, but I wanted to integrate opennav_coverage
into my project and use a rviz /clicked_point defined field_polygon.
I made a package, points_to_polygon, which takes /clicked_point, publishes a Polygon topic and an [x,y] topic.
Feel free to use the points_to_polygon package. I am new to ros2 and not totally sure of how I did things.
My project (jazzy) is based on linorobot2 (huumble), using linorobot2's rviz, slam and navigation launch.
The navigation.yaml is mainly the current Nav2 website navigation.yaml, with coverage server added.
To launch coverage server I use a simplified version of opennav_coverage_demo/launch
coverage_demo_launch.py modified to coverage.launch.py
bringup_launch.py modified to coverage_bringup.launch.py
since the linorobot2 launch already bring up the controller_server, bt_navigator and velocity_smoother.
The node in coverage.launch.py is points2polygon_coverage.py,
modified from opennav_coverage_demo/opennav_coverage_demo/demo_coverage.py.
In the callback for the subscription to the [x,y] topic ( easier to use than the Polygon topic)
I feed the [x,y] list to navigateCoverage() instead of the demo_coverage.py field.
The [x,y] list from /clicked_point looks to be working, but the navigateCoverage() errors.
[points2polygon_coverage-1] [[-3.3, -4.5], [-2.1, 1.3], [1.5, 1.1], [0.4, -4.4], [-3.3, -4.5]]
[points2polygon_coverage-1] Waiting for bt_navigator to become active..
[points2polygon_coverage-1] Getting bt_navigator state...
[points2polygon_coverage-1] Result of get_state: active
[points2polygon_coverage-1] Waiting for 'NavigateCompleteCoverage' action server
[points2polygon_coverage-1] Navigating to with field of size: 5...
[points2polygon_coverage-1] Task with failed with status code: 6
[points2polygon_coverage-1] Goal failed!
I get a similar error if the demo_coverage.py field is fed to navigateCoverage() within points2polygon_coverage.py,
so think the issue is with my opennav_coverage launch (coverage.launch.py,coverage_bringup.launch.py).
The opennav_coverage README mentions an eventual tutorial about using the coverage server, which would be very helpful for integrating the coverage server into a project.
Here is the points_to_polygon -PointsToPolygonNode.py
import rclpy
from rclpy.node import Node
from rclpy.qos import QoSProfile, HistoryPolicy
from geometry_msgs.msg import Point, Polygon, Point32
from geometry_msgs.msg import PointStamped
from std_msgs.msg import Float64MultiArray
class PointsToPolygonNode(Node):
def init(self):
super().init('points_to_polygon_node')
def main(args=None):
rclpy.init(args=args)
print('Hi from points_to_polygon.')
node = PointsToPolygonNode()
rclpy.spin(node)
if name == 'main':
main()
Here is the points2polygon_coverage.py ( modified from opennav_coverage_demo/demo_coverage.py).
#! /usr/bin/env python3
modified from
Copyright 2023 Open Navigation LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
from enum import Enum
import time
from action_msgs.msg import GoalStatus
from geometry_msgs.msg import Point32, Polygon
from lifecycle_msgs.srv import GetState
from opennav_coverage_msgs.action import NavigateCompleteCoverage
import rclpy
from rclpy.action import ActionClient
from rclpy.duration import Duration
from rclpy.node import Node
from std_msgs.msg import Float64MultiArray
class TaskResult(Enum):
UNKNOWN = 0
SUCCEEDED = 1
CANCELED = 2
FAILED = 3
class CoverageNavigatorTester(Node):
def main():
rclpy.init()
if name == 'main':
main()
Here is the coverage.launch.py.
modified from
Copyright (c) 2023 Open Navigation LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
import os
import tempfile
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import (
ExecuteProcess,
IncludeLaunchDescription,
OpaqueFunction,
RegisterEventHandler,
)
from launch.event_handlers import OnShutdown
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node
def generate_launch_description():
Here is the coverage_bringup.launch.py
modified from
Copyright (c) 2023 Open Navigation LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, SetEnvironmentVariable
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import LoadComposableNodes
from launch_ros.actions import Node
from launch_ros.descriptions import ComposableNode, ParameterFile
from nav2_common.launch import RewrittenYaml
def generate_launch_description():
params_file = LaunchConfiguration('params_file')