|
19 | 19 | #include <string>
|
20 | 20 | #include <algorithm>
|
21 | 21 | #include <memory>
|
| 22 | +#include <utility> |
22 | 23 |
|
23 | 24 | #include "fields2cover.h" // NOLINT
|
24 | 25 | #include "rclcpp/rclcpp.hpp"
|
@@ -276,6 +277,82 @@ inline void toUpper(std::string & string)
|
276 | 277 | std::transform(string.begin(), string.end(), string.begin(), ::toupper);
|
277 | 278 | }
|
278 | 279 |
|
| 280 | +/** |
| 281 | + * @brief A Path Components iterator object to get next turn/swath from action return |
| 282 | + * |
| 283 | + * Example Use: |
| 284 | + for (opennav_coverage::util::PathComponentsIterator it(msg); it.isValid(); it.advance()) { |
| 285 | + auto curr_row_info = it.getNext(); |
| 286 | +
|
| 287 | + // Always should be valid |
| 288 | + (void)std::get<0>(curr_row_info)->start; |
| 289 | +
|
| 290 | + if (std::get<1>(curr_row_info)) { |
| 291 | + // Always should be before last |
| 292 | + (void)std::get<1>(curr_row_info)->poses; |
| 293 | + } |
| 294 | + } |
| 295 | +
|
| 296 | + auto last_row_info = it.getNext(); |
| 297 | + ASSERT(std::get<1>(last_row_info) == nullptr); |
| 298 | + */ |
| 299 | +class PathComponentsIterator |
| 300 | +{ |
| 301 | +public: |
| 302 | + /** |
| 303 | + * @brief A Path Components iterator constructor |
| 304 | + * @param PathComponents object to iterate over |
| 305 | + */ |
| 306 | + explicit PathComponentsIterator(opennav_coverage_msgs::msg::PathComponents & msg) |
| 307 | + : path_components_(msg), idx_(0) |
| 308 | + { |
| 309 | + if (fabs(path_components_.swaths.size() - path_components_.turns.size()) > 1) { |
| 310 | + throw std::runtime_error("PathComponents size not valid for iteration!"); |
| 311 | + } else if (!path_components_.contains_turns) { |
| 312 | + throw std::runtime_error("PathComponents cannot be iterated over without turns!"); |
| 313 | + } else if (!path_components_.swaths_ordered) { |
| 314 | + throw std::runtime_error("PathComponents cannot be iterated over without ordered swaths!"); |
| 315 | + } |
| 316 | + |
| 317 | + max_idx_ = path_components_.swaths.size(); |
| 318 | + } |
| 319 | + |
| 320 | + /** |
| 321 | + * @brief For condition if still valid to continue iterating |
| 322 | + */ |
| 323 | + bool isValid() |
| 324 | + { |
| 325 | + return idx_ <= max_idx_; |
| 326 | + } |
| 327 | + |
| 328 | + /** |
| 329 | + * @brief For loop marching |
| 330 | + */ |
| 331 | + void advance() |
| 332 | + { |
| 333 | + idx_++; |
| 334 | + } |
| 335 | + |
| 336 | + /** |
| 337 | + * @brief Get the data of the current iteration |
| 338 | + * @return returns a pair of pointers to the current swath and its next turn |
| 339 | + * If at the end, the turn is nullptr, so be sure to check it! |
| 340 | + */ |
| 341 | + std::pair<opennav_coverage_msgs::msg::Swath *, nav_msgs::msg::Path *> |
| 342 | + getNext() |
| 343 | + { |
| 344 | + if (idx_ < max_idx_ - 1) { |
| 345 | + return std::make_pair(&path_components_.swaths[idx_], &path_components_.turns[idx_]); |
| 346 | + } else { |
| 347 | + return std::make_pair(&path_components_.swaths[idx_], nullptr); |
| 348 | + } |
| 349 | + } |
| 350 | + |
| 351 | + opennav_coverage_msgs::msg::PathComponents & path_components_; |
| 352 | + unsigned int idx_; |
| 353 | + unsigned int max_idx_; |
| 354 | +}; |
| 355 | + |
279 | 356 | } // namespace util
|
280 | 357 |
|
281 | 358 | } // namespace opennav_coverage
|
|
0 commit comments