Skip to content

Commit c12ded8

Browse files
committed
adding untested BT nodes and navigator plugin for coverage navigation complete
1 parent f20044d commit c12ded8

27 files changed

+976
-20
lines changed

nav2_complete_coverage_msgs/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ rosidl_generate_interfaces(${PROJECT_NAME}
1919
"msg/Swath.msg"
2020
"msg/PathComponents.msg"
2121
"action/ComputeCoveragePath.action"
22+
"action/NavigateCompleteCoverage.action"
2223
DEPENDENCIES builtin_interfaces geometry_msgs std_msgs action_msgs nav_msgs
2324
)
2425

nav2_complete_coverage_msgs/action/ComputeCoveragePath.action

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ bool generate_path True
99
# If providing gml file with multiple fields, specify which with gml_field_id
1010
# If using polygons, bounding polygon must be first, followed by inner cutouts
1111
# Both must specify if the data is cartesian or GPS coordinates
12-
bool frame_cartesian True
1312
bool use_gml_file False
1413
string gml_field
1514
uint16 gml_field_id 0
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#goal definition
2+
3+
# Define the field as either a filepath to a GML file or as a vector of polygons
4+
# Whereas the first polygon is the outer field and subsequent polygons are internal voids.
5+
# When both are specified, the file is used in ComputeCoveragePath BT Node.
6+
string field_filepath
7+
geometry_msgs/Polygon[] polygons
8+
string frame_id map # Specify the frame of reference of the polygon field
9+
10+
string behavior_tree
11+
---
12+
#result definition
13+
14+
# Error codes
15+
# Note: The expected priority order of the errors should match the message order
16+
uint16 NONE=0
17+
18+
uint16 error_code
19+
---
20+
#feedback definition
21+
22+
geometry_msgs/PoseStamped current_pose
23+
builtin_interfaces/Duration navigation_time
24+
builtin_interfaces/Duration estimated_time_remaining
25+
int16 number_of_recoveries
26+
float32 distance_remaining

nav2_coverage/README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Walk through
5656
- Use GPS, Cartesian; files or direct coordinates
5757
- Error codes for contextual failures to know when failures what to do about it
5858
- Return: PathComponents, NavPath, error code, compute time for metrics
59+
- BT nodes + XML using the nav path from coverage + Navigator type for semantic information of request + demo sim use
5960

6061
- Tester to demo
6162
- Basic call
@@ -64,10 +65,13 @@ Walk through
6465
- RQT
6566

6667
Future
67-
- Use coverage exceptions
68+
- Test BT nodes / XML / Navigator // unit tests
69+
- Create simulation to testing / demo
70+
71+
- A couple of utilities for the BT nodes to iterate through the swath-turn combos (optional)
72+
73+
74+
75+
Navigators require Iron+
76+
Options: (A) upgrade, (B) use Navigate To Pose and hardcode the field file path and ignore the pose action request, (C) call the server manually from your application
6877

69-
- BT nodes to interact with in in the Nav2 autonomy framework
70-
- A couple of utilities for the BT nodes to iterate through the swath-turn combos
71-
- Turn tester into Python API for it
72-
- A Navigator API plugin for coverage specific tasks
73-
- A BT XML to pair with the navigator + BT nodes to initial system demos

nav2_coverage/include/nav2_coverage/coverage_server.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class CoverageServer : public nav2_util::LifecycleNode
128128
std::unique_ptr<RouteGenerator> route_gen_;
129129
std::unique_ptr<PathGenerator> path_gen_;
130130
std::unique_ptr<Visualizer> visualizer_;
131+
bool cartesian_frame_;
131132
};
132133

133134
} // namespace nav2_coverage

nav2_coverage/src/coverage_server.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ CoverageServer::on_configure(const rclcpp_lifecycle::State & /*state*/)
4040
path_gen_ = std::make_unique<PathGenerator>(node, robot_params_.get());
4141
visualizer_ = std::make_unique<Visualizer>();
4242

43+
// If in GPS coordinates, we must convert to a CRS to compute coverage
44+
// Then, reconvert back to GPS for the user.
45+
nav2_util::declare_parameter_if_not_declared(
46+
node, "coordinates_in_cartesian_frame", rclcpp::ParameterValue(true));
47+
get_parameter("coordinates_in_cartesian_frame", cartesian_frame_);
48+
4349
double action_server_result_timeout;
4450
nav2_util::declare_parameter_if_not_declared(
4551
node, "action_server_result_timeout", rclcpp::ParameterValue(10.0));
@@ -158,7 +164,6 @@ void CoverageServer::computeCoveragePath()
158164

159165
try {
160166
// (0) Obtain field to use
161-
bool cartesian_frame = goal->frame_cartesian;
162167
Field field;
163168
F2CField master_field;
164169
std::string frame_id;
@@ -173,7 +178,7 @@ void CoverageServer::computeCoveragePath()
173178
frame_id = goal->frame_id;
174179
}
175180

176-
if (!cartesian_frame) {
181+
if (!cartesian_frame_) {
177182
f2c::Transform::transformToUTM(master_field);
178183
}
179184
field = master_field.field.getGeometry(0);
@@ -204,15 +209,15 @@ void CoverageServer::computeCoveragePath()
204209
if (goal->generate_path) {
205210
Path path = path_gen_->generatePath(route, goal->path_mode);
206211
result->coverage_path =
207-
util::toCoveragePathMsg(path, master_field, header, cartesian_frame);
208-
result->nav_path = util::toNavPathMsg(path, master_field, header, cartesian_frame);
212+
util::toCoveragePathMsg(path, master_field, header, cartesian_frame_);
213+
result->nav_path = util::toNavPathMsg(path, master_field, header, cartesian_frame_);
209214
} else {
210215
result->coverage_path =
211-
util::toCoveragePathMsg(route, master_field, true, header, cartesian_frame);
216+
util::toCoveragePathMsg(route, master_field, true, header, cartesian_frame_);
212217
}
213218
} else {
214219
result->coverage_path =
215-
util::toCoveragePathMsg(swaths, master_field, false, header, cartesian_frame);
220+
util::toCoveragePathMsg(swaths, master_field, false, header, cartesian_frame_);
216221
}
217222

218223
auto cycle_duration = this->now() - start_time;
@@ -277,6 +282,8 @@ CoverageServer::dynamicParametersCallback(std::vector<rclcpp::Parameter> paramet
277282
} else if (type == ParameterType::PARAMETER_BOOL) {
278283
if (name == "default_allow_overlap") {
279284
swath_gen_->setOVerlap(parameter.as_bool());
285+
} else if (name == "coordinates_in_cartesian_frame") {
286+
cartesian_frame_ = parameter.as_bool();
280287
}
281288
} else if (type == ParameterType::PARAMETER_INTEGER) {
282289
if (name == "default_spiral_n") {

nav2_coverage/src/headland_generator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Field HeadlandGenerator::generateHeadlands(
3939

4040

4141
if (!generator) {
42-
throw std::runtime_error("No valid headlands mode set! Options: CONSTANT.");
42+
throw CoverageException("No valid headlands mode set! Options: CONSTANT.");
4343
}
4444

4545
RCLCPP_DEBUG(logger_, "Generating Headland with generator: %s", toString(action_type).c_str());

nav2_coverage/src/path_generator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Path PathGenerator::generatePath(
4040
}
4141

4242
if (!curve) {
43-
throw std::runtime_error("No valid path mode set!");
43+
throw CoverageException("No valid path mode set!");
4444
}
4545

4646
RCLCPP_DEBUG(

nav2_coverage/src/route_generator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Swaths RouteGenerator::generateRoute(
4141
}
4242

4343
if (!generator) {
44-
throw std::runtime_error(
44+
throw CoverageException(
4545
"No valid route mode set! Options: BOUSTROPHEDON, SNAKE, SPIRAL, CUSTOM.");
4646
} else if (action_type == RouteType::SPIRAL) {
4747
dynamic_cast<f2c::rp::SpiralOrder *>(generator.get())->setSpiralSize(spiral_n);

nav2_coverage/src/swath_generator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ Swaths SwathGenerator::generateSwaths(
4949
switch (action_angle_type) {
5050
case SwathAngleType::BRUTE_FORCE:
5151
if (!objective) {
52-
throw std::runtime_error("No valid swath mode set! Options: LENGTH, NUMBER, COVERAGE.");
52+
throw CoverageException("No valid swath mode set! Options: LENGTH, NUMBER, COVERAGE.");
5353
}
5454
generator_->step_angle = step_angle;
5555
return generator_->generateBestSwaths(*objective, robot_params_->getOperationWidth(), field);
5656
case SwathAngleType::SET_ANGLE:
5757
return generator_->generateSwaths(swath_angle, robot_params_->getOperationWidth(), field);
5858
default:
59-
throw std::runtime_error("No valid swath angle mode set! Options: BRUTE_FORCE, SET_ANGLE.");
59+
throw CoverageException("No valid swath angle mode set! Options: BRUTE_FORCE, SET_ANGLE.");
6060
}
6161
}
6262

0 commit comments

Comments
 (0)