From ad8ac7e53a8e647cdb9a8f2f275bec000780f8d6 Mon Sep 17 00:00:00 2001 From: Marko Bjelonic Date: Tue, 12 Nov 2019 12:33:05 +0100 Subject: [PATCH 001/504] Added loco_perception utils. From 9aff521bfa492df2c7eb83a8d109d17ee853f0b5 Mon Sep 17 00:00:00 2001 From: Marko Bjelonic Date: Tue, 12 Nov 2019 16:23:56 +0100 Subject: [PATCH 002/504] Added jenkins. --- jenkins-pipeline | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 jenkins-pipeline diff --git a/jenkins-pipeline b/jenkins-pipeline new file mode 100644 index 00000000..59d9ff9b --- /dev/null +++ b/jenkins-pipeline @@ -0,0 +1,2 @@ +library 'continuous_integration_pipeline' +ciPipeline("") From 82a57e4307e550cfa645b823574d43a21ffcabdb Mon Sep 17 00:00:00 2001 From: Marko Bjelonic Date: Tue, 12 Nov 2019 17:45:47 +0100 Subject: [PATCH 003/504] Added loco perception ros. --- loco_perception_ros/CMakeLists.txt | 51 ++++++++ .../loco_perception_ros/ConvexSetSequence.hpp | 57 +++++++++ loco_perception_ros/package.xml | 13 ++ loco_perception_ros/src/ConvexSetSequence.cpp | 113 ++++++++++++++++++ 4 files changed, 234 insertions(+) create mode 100644 loco_perception_ros/CMakeLists.txt create mode 100644 loco_perception_ros/include/loco_perception_ros/ConvexSetSequence.hpp create mode 100644 loco_perception_ros/package.xml create mode 100644 loco_perception_ros/src/ConvexSetSequence.cpp diff --git a/loco_perception_ros/CMakeLists.txt b/loco_perception_ros/CMakeLists.txt new file mode 100644 index 00000000..b5be54c7 --- /dev/null +++ b/loco_perception_ros/CMakeLists.txt @@ -0,0 +1,51 @@ +# Project configuration +cmake_minimum_required (VERSION 2.8) +project(loco_perception_ros) + +## Find catkin macros and libraries +## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) +## is used, also find other catkin packages +find_package(catkin REQUIRED COMPONENTS + loco_ros + loco_perception_utils +) + +catkin_package( + INCLUDE_DIRS include + LIBRARIES loco_perception_ros + CATKIN_DEPENDS + loco_ros + loco_perception_utils +# DEPENDS system_lib +) + +find_package(Eigen3 REQUIRED) +find_package(Boost COMPONENTS timer REQUIRED) + +add_definitions(--std=c++11) + +include_directories(include) +include_directories(${EIGEN3_INCLUDE_DIR}) +include_directories(${catkin_INCLUDE_DIRS}) +include_directories(${Boost_INCLUDE_DIRS}) + +add_library(loco_perception_ros SHARED + src/ConvexSetSequence.cpp +) + +add_dependencies(loco_perception_ros ${catkin_EXPORTED_TARGETS}) + +target_link_libraries(loco_perception_ros + ${catkin_LIBRARIES} + ${Boost_LIBRARIES} +) + +install(DIRECTORY include/${PROJECT_NAME}/ + DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/${PROJECT_NAME} + PATTERN ".svn" EXCLUDE +) +install(TARGETS ${PROJECT_NAME} + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +) diff --git a/loco_perception_ros/include/loco_perception_ros/ConvexSetSequence.hpp b/loco_perception_ros/include/loco_perception_ros/ConvexSetSequence.hpp new file mode 100644 index 00000000..98b7d12b --- /dev/null +++ b/loco_perception_ros/include/loco_perception_ros/ConvexSetSequence.hpp @@ -0,0 +1,57 @@ +/* + * ConvexSetSequence.hpp + * + * Created on: Nov 12, 2019 + * Author: Marko Bjelonic + */ + +#pragma once + +// ros +#include +#include + +// loco +#include + +// loco perception utils +#include + +// loco ros +#include +#include + +// robot utils +#include + +// stl +#include + + +namespace loco_perception_ros { + +class ConvexSetSequence { + public: + ConvexSetSequence(); + virtual ~ConvexSetSequence() = default; + + bool initialize(ros::NodeHandle& nodeHandle, const std::string& topic); + bool shutdown(); + + bool update(const std::vector& convexSets); + bool publish(); + + void setColorVector(std::vector>& colors); + void setColorVectorId(unsigned int colorId); + + unsigned int getNumSubscribers() const; + + protected: + ros::NodeHandle nodeHandle_; + visualization_msgs::MarkerArray convexSetSequence_; + ros::Publisher publisher_; + std::vector> colors_; + unsigned int colorId_; +}; + +} /* namespace loco */ diff --git a/loco_perception_ros/package.xml b/loco_perception_ros/package.xml new file mode 100644 index 00000000..38d4e8f7 --- /dev/null +++ b/loco_perception_ros/package.xml @@ -0,0 +1,13 @@ + + + loco_perception_ros + 0.2.0 + The loco_perception_ros package + Marko Bjelonic + Proprietary + https://bitbucket.org/leggedrobotics/loco_anymal_wheels + Marko Bjelonic + catkin + loco_ros + loco_perception_utils + diff --git a/loco_perception_ros/src/ConvexSetSequence.cpp b/loco_perception_ros/src/ConvexSetSequence.cpp new file mode 100644 index 00000000..3e7defe2 --- /dev/null +++ b/loco_perception_ros/src/ConvexSetSequence.cpp @@ -0,0 +1,113 @@ +/* + * ConvexSetSequence.cpp + * + * Created on: Nov 12, 2019 + * Author: Marko Bjelonic + */ + + +// loco perception ros +#include "loco_perception_ros/ConvexSetSequence.hpp" + +namespace loco_perception_ros { + +ConvexSetSequence::ConvexSetSequence() + : nodeHandle_(), + convexSetSequence_(), + publisher_(), + colorId_(0u) +{ + +} + +void ConvexSetSequence::setColorVector(std::vector>& colors) { + colors_ = colors; +} + +void ConvexSetSequence::setColorVectorId(unsigned int colorId) { + colorId_ = colorId; +} + +bool ConvexSetSequence::initialize(ros::NodeHandle& nodeHandle, const std::string& topic) { + nodeHandle_ = nodeHandle; + publisher_ = nodeHandle.advertise(topic, 100); + + return true; +} + +bool ConvexSetSequence::shutdown() { + publisher_.shutdown(); + return true; +} + +bool ConvexSetSequence::update(const std::vector& convexSets) { + if (convexSets.size() == 0u) { + return true; + } + + if (getNumSubscribers() > 0u) { + convexSetSequence_.markers.clear(); + + unsigned int id = 0u; + unsigned int offset = 0u; + + for (const auto& convexSet : convexSets) { + // Number of vertices should not be zero. + if (convexSet.getNumOfVertices() <= 0u) { + ++offset; + continue; + } + + visualization_msgs::Marker convexSetSequence; + convexSetSequence.pose.orientation.w = 1.0; + convexSetSequence.action = visualization_msgs::Marker::ADD; + convexSetSequence.type = visualization_msgs::Marker::LINE_STRIP; + convexSetSequence.scale.x = 0.00200; + convexSetSequence.scale.y = 0.00200; + convexSetSequence.scale.z = 0.00200; + convexSetSequence.color.a = 1.0; + convexSetSequence.header.frame_id = "odom"; + + const unsigned int colorId = robot_utils::intmod(colorId_, colors_.size()); + + convexSetSequence.color.r = colors_[colorId].x(); + convexSetSequence.color.g = colors_[colorId].y(); + convexSetSequence.color.b = colors_[colorId].z(); + + convexSetSequence.id = id; + convexSetSequence.ns = "convex_set" + std::to_string(convexSetSequence.id); + + geometry_msgs::Point point; + convexSetSequence.points.reserve(convexSet.getConvexSetInWorldFrame().getVertices().size()); + for (const auto& vertex : convexSet.getConvexSetInWorldFrame().getVertices()) { + const loco::Position positionWorldToVertexInWorldFrame = + loco::Position(vertex.x(), vertex.y(), 0.0); + point.x = positionWorldToVertexInWorldFrame.x(); + point.y = positionWorldToVertexInWorldFrame.y(); + point.z = positionWorldToVertexInWorldFrame.z(); + convexSetSequence.points.push_back(point); + } + + // Add first point again to reconnect the polygon. + if (convexSetSequence.points.size() > 2) { + convexSetSequence.points.push_back(convexSetSequence.points.front()); + convexSetSequence_.markers.push_back(convexSetSequence); + } + + ++id; + } + } + + return true; +} + +bool ConvexSetSequence::publish() { + loco_ros::publishMsg(publisher_, convexSetSequence_); + return true; +} + +unsigned int ConvexSetSequence::getNumSubscribers() const { + return publisher_.getNumSubscribers(); +} + +} /* namespace loco */ From 65b3ba7189c0a553eb3ee4a77351f52acb25e959 Mon Sep 17 00:00:00 2001 From: Marko Bjelonic Date: Wed, 13 Nov 2019 13:13:05 +0100 Subject: [PATCH 004/504] Fixed vertex iterator. --- loco_perception_ros/src/ConvexSetSequence.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/loco_perception_ros/src/ConvexSetSequence.cpp b/loco_perception_ros/src/ConvexSetSequence.cpp index 3e7defe2..64213b92 100644 --- a/loco_perception_ros/src/ConvexSetSequence.cpp +++ b/loco_perception_ros/src/ConvexSetSequence.cpp @@ -62,9 +62,7 @@ bool ConvexSetSequence::update(const std::vector Date: Thu, 30 Jan 2020 10:01:31 +0100 Subject: [PATCH 005/504] Ignore .idea. --- .gitignore | 1 + .idea/.gitignore | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 .gitignore delete mode 100644 .idea/.gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..9f11b755 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 5c98b428..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Default ignored files -/workspace.xml \ No newline at end of file From a5284a5979eac1a41e934c7b3d8d50b4011e43b9 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Thu, 30 Jan 2020 11:04:12 +0100 Subject: [PATCH 006/504] Added missing geomery utils. --- .../include/geometry_utils.hpp | 23 +++++++ .../src/geometry_utils.cpp | 60 +++++++++++++++++++ convex_plane_decomposition/src/polygon.cpp | 18 +++--- 3 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 convex_plane_decomposition/include/geometry_utils.hpp create mode 100644 convex_plane_decomposition/src/geometry_utils.cpp diff --git a/convex_plane_decomposition/include/geometry_utils.hpp b/convex_plane_decomposition/include/geometry_utils.hpp new file mode 100644 index 00000000..a2b1f786 --- /dev/null +++ b/convex_plane_decomposition/include/geometry_utils.hpp @@ -0,0 +1,23 @@ +#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ +#define CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ + +#include "types.hpp" + +namespace convex_plane_extraction { + +double scalarCrossProduct(const Vector2d &leftVector, const Vector2d &rightVector); + +double distanceToLine(const Vector2d& lineSupportVector, const Vector2d& lineDirectionalVector, const Vector2d& testPoint); + +bool isPointOnRightSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); + +double computeAngleBetweenVectors(const Vector2d& first_vector, const Vector2d& second_vector); + +bool isPointOnLeftSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); + +bool intersectRayWithLineSegment(const Vector2d& ray_source, const Vector2d& ray_direction, + const Vector2d& segment_source, const Vector2d& segment_target, Vector2d* intersection_point); + +double distanceBetweenPoints(Vector2d first, Vector2d second); +} +#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp new file mode 100644 index 00000000..fb794e89 --- /dev/null +++ b/convex_plane_decomposition/src/geometry_utils.cpp @@ -0,0 +1,60 @@ +#include +#include "geometry_utils.hpp" + +namespace convex_plane_extraction { + + double scalarCrossProduct(const Vector2d &leftVector, const Vector2d &rightVector) { + return leftVector.y() * rightVector.x() - leftVector.x() * rightVector.y(); + } + + // Return the non-normalized distance of a 2D-point to a line given by support vector and direction vector. + // Negative distance corresponds to a point on the left of the direction vector + double distanceToLine(const Vector2d &lineSupportVector, + const Vector2d &lineDirectionalVector, + const Vector2d &testPoint) { + Vector2d secondPointOnLine = lineSupportVector + lineDirectionalVector; + return scalarCrossProduct(lineDirectionalVector, testPoint) + + scalarCrossProduct(lineSupportVector, secondPointOnLine); + } + + bool isPointOnRightSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point){ + Vector2d normal_vector(line_direction_vector.y(), (-1.0)*line_direction_vector.x()); + normal_vector.normalize(); + Vector2d point_vector = point - line_support_vector; + return point_vector.transpose() * normal_vector > 0; + } + + bool isPointOnLeftSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point){ + Vector2d normal_vector(line_direction_vector.y(), (-1.0)*line_direction_vector.x()); + normal_vector.normalize(); + Vector2d point_vector = point - line_support_vector; + return point_vector.dot(normal_vector) < 0; + } + + double computeAngleBetweenVectors(const Vector2d& first_vector, const Vector2d& second_vector){ + double scalar_product = first_vector.transpose() * second_vector; + return acos( abs(scalar_product) / (first_vector.norm() * second_vector.norm())); + } + + bool intersectRayWithLineSegment(const Vector2d& ray_source, const Vector2d& ray_direction, + const Vector2d& segment_source, const Vector2d& segment_target, Vector2d* intersection_point){ + CHECK_NOTNULL(intersection_point); + Vector2d segment_direction = segment_target - segment_source; + Matrix2d A; + A.col(0) = ray_direction; + A.col(1) = - segment_direction; + Vector2d b = segment_source - ray_source; + Vector2d solution = A.fullPivHouseholderQr().solve(b); + if (solution(0) <= 0 || solution(1) < 0 || solution(1) > 1){ + return false; + } + *intersection_point = segment_source + solution(1) * segment_direction; + return true; + } + + double distanceBetweenPoints(Vector2d first, Vector2d second){ + return (second - first).norm(); + } + +} + diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index aa120ae7..0eb7bba9 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -7,15 +7,15 @@ namespace convex_plane_extraction { CHECK(polygon.is_simple()); LOG(INFO) << "Started convex decomposition..."; size_t old_list_size = output_polygon_list->size(); - CGAL::optimal_convex_partition_2(polygon.vertices_begin(), - polygon.vertices_end(), - std::back_inserter(*output_polygon_list)); - - assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), - polygon.vertices_end(), - polygon_list.begin(), - polygon_list.end())); -// *output_polygon_list = decomposeInnerApproximation(polygon); +// CGAL::optimal_convex_partition_2(polygon.vertices_begin(), +// polygon.vertices_end(), +// std::back_inserter(*output_polygon_list)); +// +// assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), +// polygon.vertices_end(), +// polygon_list.begin(), +// polygon_list.end())); + *output_polygon_list = decomposeInnerApproximation(polygon); CHECK_GT(output_polygon_list->size(), old_list_size); LOG(INFO) << "done."; } From 93059007340d39df2dfb8263ba6b0a12335d1d45 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Thu, 30 Jan 2020 16:45:58 +0100 Subject: [PATCH 007/504] Fix. --- .../include/polygon.hpp | 2 +- .../src/geometry_utils.cpp | 6 ++- convex_plane_decomposition/src/polygon.cpp | 40 ++++++++++++------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index 9ec9168c..d1ab2bfb 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -118,7 +118,7 @@ namespace convex_plane_extraction{ CgalPoint2d intersection_point_; }; - void intersectPolygonWithRay(int ray_source_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, + bool intersectPolygonWithRay(int ray_source_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, Intersection* intersection); CgalPolygon2dVertexIterator erase(CgalPolygon2dVertexIterator first, CgalPolygon2dVertexIterator last, diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp index fb794e89..3d2509ba 100644 --- a/convex_plane_decomposition/src/geometry_utils.cpp +++ b/convex_plane_decomposition/src/geometry_utils.cpp @@ -45,10 +45,12 @@ namespace convex_plane_extraction { A.col(1) = - segment_direction; Vector2d b = segment_source - ray_source; Vector2d solution = A.fullPivHouseholderQr().solve(b); - if (solution(0) <= 0 || solution(1) < 0 || solution(1) > 1){ + Vector2d ray_solution = ray_source + solution(0) * segment_direction; + Vector2d segment_solution = segment_source + solution(1) * segment_direction; + if (solution(0) <= 0 || solution(1) <= 0 || solution(1) > 1){ // || (ray_solution - segment_solution).norm() > 0.001) { return false; } - *intersection_point = segment_source + solution(1) * segment_direction; + *intersection_point = segment_solution; return true; } diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 0eb7bba9..d967f5f1 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -200,32 +200,31 @@ namespace convex_plane_extraction { std::list decomposeInnerApproximation(const CgalPolygon2d& polygon){ CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); std::list return_list; - // If polygon ceonvex terminate recursion. -// if(polygon.is_convex()){ -// return_list.push_back(polygon); -// return return_list; -// } std::vector dent_locations; detectDentLocations(&dent_locations, polygon); if (dent_locations.empty()){ -// printPolygon(polygon); -// LOG(FATAL) << "No dents detected, but polygon not convex!"; + // No dents detected, polygon must be convex. + // CGAL convexity check might still fail, since very shallow dents are ignored. return_list.push_back(polygon); return return_list; } - //CHECK(!dent_locations.empty()); // If no dents, polygon would be convex, which should have terminated recursion. std::cout << "Dent locations:" << std::endl; for (int location : dent_locations){ std::cout << location << std::endl; } std::cout << "Polygon:" << std::endl; printPolygon(polygon); + bool intersection_clockwise_flag = false; Intersection intersection_clockwise; + bool intersection_counterclockwise_flag = false; Intersection intersection_counterclockwise; - intersectPolygonWithRay(dent_locations.at(0), CGAL::COUNTERCLOCKWISE, + intersection_clockwise_flag = intersectPolygonWithRay(dent_locations.at(0), CGAL::COUNTERCLOCKWISE, polygon, &intersection_counterclockwise); - intersectPolygonWithRay(dent_locations.at(0), CGAL::CLOCKWISE, + intersection_counterclockwise_flag = intersectPolygonWithRay(dent_locations.at(0), CGAL::CLOCKWISE, polygon, &intersection_clockwise); + if (!intersection_clockwise_flag || !intersection_counterclockwise_flag ){ + // return return_list; + } // Generate resulting polygons from cut. // Resulting cut from counter clockwise ray intersection. CgalPolygon2d polygon_counterclockwise_1 = polygon; @@ -247,7 +246,11 @@ namespace convex_plane_extraction { std::cout << "Copy succeeded without problems!" << std::endl; // polygon_counterclockwise_2.insert(polygon_counterclockwise_2.vertices_end(), // first_vertex_to_erase_it, last_vertex_to_erase_it); - polygon_counterclockwise_2.push_back(intersection_counterclockwise.intersection_point_); + CgalPoint2d point_before_intersection = *(previous(last_vertex_to_erase_it, polygon_counterclockwise_2)); + constexpr double kSquaredLengthThreshold = 1e-6; + if ((intersection_counterclockwise.intersection_point_ - point_before_intersection).squared_length() > kSquaredLengthThreshold) { + polygon_counterclockwise_2.push_back(intersection_counterclockwise.intersection_point_); + } // auto element_behind_deleted_it = polygon_counterclockwise_1.erase(first_vertex_to_erase_it, std::next(last_vertex_to_erase_it)); CgalPolygon2dVertexIterator element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); polygon_counterclockwise_1.insert(element_behind_deleted_it, intersection_counterclockwise.intersection_point_); @@ -256,9 +259,12 @@ namespace convex_plane_extraction { // Resulting cut from clockwise ray intersection. CgalPolygon2d polygon_clockwise_1 = polygon; CgalPolygon2d polygon_clockwise_2; - polygon_clockwise_2.push_back(intersection_clockwise.intersection_point_); + first_vertex_to_erase_it = polygon_clockwise_1.vertices_begin(); std::advance(first_vertex_to_erase_it, intersection_clockwise.edge_target_location_); + if ((*first_vertex_to_erase_it - intersection_clockwise.intersection_point_).squared_length() > kSquaredLengthThreshold) { + polygon_clockwise_2.push_back(intersection_clockwise.intersection_point_); + } last_vertex_to_erase_it = polygon_clockwise_1.vertices_begin(); std::advance(last_vertex_to_erase_it, dent_locations.at(0)); copyVertices(polygon_clockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_2, @@ -319,7 +325,7 @@ namespace convex_plane_extraction { return return_list; } - void intersectPolygonWithRay(int ray_source_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, + bool intersectPolygonWithRay(int ray_source_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, Intersection* intersection){ CHECK_NOTNULL(intersection); CHECK(orientation == CGAL::COUNTERCLOCKWISE || orientation == CGAL::CLOCKWISE); @@ -356,7 +362,7 @@ namespace convex_plane_extraction { if (intersectRayWithLineSegment(ray_source, ray_direction, segment_source, segment_target, &intersection_point)){ std::cout << "Intersection succeeded with: " << std::endl; - std::cout << "Ray target" << ray_target << std::endl; + std::cout << "Ray source" << ray_source << std::endl; std::cout << "Segment source: " << segment_source << std::endl; std::cout << "Segment target: " << segment_target << std::endl; std::cout << "Intersection point: " << intersection_point << std::endl; @@ -370,9 +376,13 @@ namespace convex_plane_extraction { } vertex_it = next(vertex_it, polygon); } - CHECK(one_intersection_at_least); + //CHECK(one_intersection_at_least); + if (!one_intersection_at_least){ + return false; + } intersection->setAllMembers(intersection_tmp.edge_source_location_, intersection_tmp.edge_target_location_, intersection_tmp.intersection_point_); + return true; } CgalPolygon2dVertexIterator erase(CgalPolygon2dVertexIterator first, CgalPolygon2dVertexIterator last, From 1b03e2c02d1ac1467f7295ad55efdba7f362aa3a Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Thu, 30 Jan 2020 18:08:35 +0100 Subject: [PATCH 008/504] Added priority to shallow dents. Clean-up. --- .../include/polygon.hpp | 5 +- .../src/geometry_utils.cpp | 2 +- convex_plane_decomposition/src/polygon.cpp | 100 ++++++++---------- 3 files changed, 48 insertions(+), 59 deletions(-) diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index d1ab2bfb..3430ffb0 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -95,7 +96,7 @@ namespace convex_plane_extraction{ double getEdgeLength(const CgalPolygon2dVertexIterator& source, const CgalPolygon2d& polygon); - void detectDentLocations(std::vector* dent_locations, const CgalPolygon2d& polygon); + void detectDentLocations(std::map* dent_locations, const CgalPolygon2d& polygon); struct Intersection{ void setEdgeSourceLocation(const int location){ @@ -118,7 +119,7 @@ namespace convex_plane_extraction{ CgalPoint2d intersection_point_; }; - bool intersectPolygonWithRay(int ray_source_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, + bool intersectPolygonWithRay(int ray_target_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, Intersection* intersection); CgalPolygon2dVertexIterator erase(CgalPolygon2dVertexIterator first, CgalPolygon2dVertexIterator last, diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp index 3d2509ba..627c7244 100644 --- a/convex_plane_decomposition/src/geometry_utils.cpp +++ b/convex_plane_decomposition/src/geometry_utils.cpp @@ -47,7 +47,7 @@ namespace convex_plane_extraction { Vector2d solution = A.fullPivHouseholderQr().solve(b); Vector2d ray_solution = ray_source + solution(0) * segment_direction; Vector2d segment_solution = segment_source + solution(1) * segment_direction; - if (solution(0) <= 0 || solution(1) <= 0 || solution(1) > 1){ // || (ray_solution - segment_solution).norm() > 0.001) { + if (solution(0) <= 0 || solution(1) <= 0 || solution(1) > 1){ return false; } *intersection_point = segment_solution; diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index d967f5f1..8d9f853f 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -177,7 +177,9 @@ namespace convex_plane_extraction { + (destination_point.y() - source_point.y()) * (destination_point.y() - source_point.y()))); } - void detectDentLocations(std::vector* dent_locations, const CgalPolygon2d& polygon){ + // A dent is a vertex, which lies in a counter-clockwise oriented polygon on the left side of its neighbors. + // Dents cause non-convexity. + void detectDentLocations(std::map* dent_locations, const CgalPolygon2d& polygon){ CHECK_NOTNULL(dent_locations); CHECK(dent_locations->empty()); CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); @@ -185,14 +187,15 @@ namespace convex_plane_extraction { auto dent_it = next(source_it, polygon); auto destination_it = next(dent_it, polygon); Vector2d source_point = Vector2d(source_it->x(), source_it->y()); - Vector2d direction_vector = Vector2d(destination_it->x() - source_it->x(), destination_it->y() - source_it->y()); + Vector2d destination_point = Vector2d(destination_it->x(), destination_it->y()); + Vector2d direction_vector = destination_point - source_point; Vector2d test_point = Vector2d(dent_it->x(), dent_it->y()); - const double kAngleThreshold = 0.001;//0.1 * M_PI / 180.0; + const double kAngleThresholdRad = 0.001; // 0.05 deg in rad. if(isPointOnLeftSide(source_point, direction_vector, test_point)){ - std::cout << "Computed angle " << (abs(computeAngleBetweenVectors(direction_vector, test_point - source_point)) > kAngleThreshold) << - std::endl; - if ( abs(computeAngleBetweenVectors(direction_vector, test_point - source_point)) > kAngleThreshold) - dent_locations->push_back(std::distance(polygon.vertices_begin(), dent_it)); + double angle = abs(computeAngleBetweenVectors(source_point - test_point, destination_point - test_point)); + // Ignore very shallow dents. Approximate convex decomposition. + if ( angle > kAngleThresholdRad) + dent_locations->insert(std::make_pair(angle, std::distance(polygon.vertices_begin(), dent_it))); } } } @@ -200,7 +203,7 @@ namespace convex_plane_extraction { std::list decomposeInnerApproximation(const CgalPolygon2d& polygon){ CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); std::list return_list; - std::vector dent_locations; + std::map dent_locations; detectDentLocations(&dent_locations, polygon); if (dent_locations.empty()){ // No dents detected, polygon must be convex. @@ -208,54 +211,48 @@ namespace convex_plane_extraction { return_list.push_back(polygon); return return_list; } - std::cout << "Dent locations:" << std::endl; - for (int location : dent_locations){ - std::cout << location << std::endl; - } - std::cout << "Polygon:" << std::endl; - printPolygon(polygon); + int dent_location = dent_locations.begin()->second; bool intersection_clockwise_flag = false; Intersection intersection_clockwise; bool intersection_counterclockwise_flag = false; Intersection intersection_counterclockwise; - intersection_clockwise_flag = intersectPolygonWithRay(dent_locations.at(0), CGAL::COUNTERCLOCKWISE, + intersection_clockwise_flag = intersectPolygonWithRay(dent_location, CGAL::COUNTERCLOCKWISE, polygon, &intersection_counterclockwise); - intersection_counterclockwise_flag = intersectPolygonWithRay(dent_locations.at(0), CGAL::CLOCKWISE, + intersection_counterclockwise_flag = intersectPolygonWithRay(dent_location, CGAL::CLOCKWISE, polygon, &intersection_clockwise); if (!intersection_clockwise_flag || !intersection_counterclockwise_flag ){ - // return return_list; + LOG(FATAL) << "At least one intersection of dent ray with polygon failed!"; } // Generate resulting polygons from cut. // Resulting cut from counter clockwise ray intersection. CgalPolygon2d polygon_counterclockwise_1 = polygon; CgalPolygon2d polygon_counterclockwise_2; auto first_vertex_to_erase_it = polygon_counterclockwise_1.vertices_begin(); - std::advance(first_vertex_to_erase_it, dent_locations.at(0)); + std::advance(first_vertex_to_erase_it, dent_location); + // Add dent to second polygon. polygon_counterclockwise_2.push_back(*first_vertex_to_erase_it); first_vertex_to_erase_it = next(first_vertex_to_erase_it, polygon_counterclockwise_1); -// for (int i = 0; i < 2; ++i){ -// first_vertex_to_erase_it = previous(first_vertex_to_erase_it, polygon); -// } auto last_vertex_to_erase_it = polygon_counterclockwise_1.vertices_begin(); + // Intersection somewhere must be at or after source vertex of intersection edge. std::advance(last_vertex_to_erase_it, intersection_counterclockwise.edge_source_location_); -// auto last_vertex_to_erase_it = polygon.vertices_begin(); -// std::advance(last_vertex_to_erase_it, intersection_counterclockwise.edge_source_location_); + // Take next vertex due to exclusive upper limit logic. last_vertex_to_erase_it = next(last_vertex_to_erase_it, polygon_counterclockwise_1); + // Copy vertices that will be deleted to second polygon. copyVertices(polygon_counterclockwise_1,first_vertex_to_erase_it,last_vertex_to_erase_it, &polygon_counterclockwise_2, polygon_counterclockwise_2.vertices_end()); - std::cout << "Copy succeeded without problems!" << std::endl; -// polygon_counterclockwise_2.insert(polygon_counterclockwise_2.vertices_end(), -// first_vertex_to_erase_it, last_vertex_to_erase_it); + // Get last point that was erased. CgalPoint2d point_before_intersection = *(previous(last_vertex_to_erase_it, polygon_counterclockwise_2)); + // To avoid numerical issues and duplicate vertices, intersection point is only inserted if sufficiently + // far away from exisiting vertex. constexpr double kSquaredLengthThreshold = 1e-6; if ((intersection_counterclockwise.intersection_point_ - point_before_intersection).squared_length() > kSquaredLengthThreshold) { polygon_counterclockwise_2.push_back(intersection_counterclockwise.intersection_point_); } -// auto element_behind_deleted_it = polygon_counterclockwise_1.erase(first_vertex_to_erase_it, std::next(last_vertex_to_erase_it)); CgalPolygon2dVertexIterator element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); - polygon_counterclockwise_1.insert(element_behind_deleted_it, intersection_counterclockwise.intersection_point_); - std::cout << "First polygon counter-clockwise: " << polygon_counterclockwise_1 << std::endl; - std::cout << "Second polygon counter-clockwise: " << polygon_counterclockwise_2 << std::endl; + // Add intersection vertex to first polygon if existing vertex too far away. +// if ((intersection_counterclockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { + polygon_counterclockwise_1.insert(element_behind_deleted_it, intersection_counterclockwise.intersection_point_); +// } // Resulting cut from clockwise ray intersection. CgalPolygon2d polygon_clockwise_1 = polygon; CgalPolygon2d polygon_clockwise_2; @@ -266,16 +263,14 @@ namespace convex_plane_extraction { polygon_clockwise_2.push_back(intersection_clockwise.intersection_point_); } last_vertex_to_erase_it = polygon_clockwise_1.vertices_begin(); - std::advance(last_vertex_to_erase_it, dent_locations.at(0)); + std::advance(last_vertex_to_erase_it, dent_location); copyVertices(polygon_clockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_2, polygon_clockwise_2.vertices_end()); polygon_clockwise_2.push_back(*last_vertex_to_erase_it); element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_1); - polygon_clockwise_1.insert(element_behind_deleted_it, intersection_clockwise.intersection_point_); -// std::advance(first_element_to_insert_it, intersection_clockwise.edge_target_location_); -// copyVertices(polygon, first_element_to_insert_it, first_vertex_to_erase_it, &polygon_clockwise_2, -// polygon_clockwise_2.vertices_end()); - +// if ((intersection_clockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { + polygon_clockwise_1.insert(element_behind_deleted_it, intersection_clockwise.intersection_point_); +// } // Take the cut with smallest min. area of resulting polygons. double area[4] = {polygon_counterclockwise_1.area(), polygon_counterclockwise_2.area(), polygon_clockwise_1.area(), polygon_clockwise_2.area()}; @@ -318,14 +313,12 @@ namespace convex_plane_extraction { } return_list.splice(return_list.end(), recursion_1); return_list.splice(return_list.end(), recursion_2); - // Check that returned decomposition is in fact convex. -// for (const CgalPolygon2d& polygon_under_test : return_list){ -// CHECK(polygon_under_test.is_convex()); -// } + return return_list; } - bool intersectPolygonWithRay(int ray_source_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, + // Counter-clockwise orientation: ray source vertex is previous vertex in counter-clockwise polygon orientation. + bool intersectPolygonWithRay(int ray_target_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, Intersection* intersection){ CHECK_NOTNULL(intersection); CHECK(orientation == CGAL::COUNTERCLOCKWISE || orientation == CGAL::CLOCKWISE); @@ -335,7 +328,7 @@ namespace convex_plane_extraction { double min_distance = kLargeDistanceValue; bool one_intersection_at_least = false; auto vertex_it = polygon.vertices_begin(); - std::advance(vertex_it, ray_source_location); + std::advance(vertex_it, ray_target_location); auto ray_source_it = vertex_it; CgalPolygon2dVertexIterator ray_target_it = vertex_it; if (orientation == CGAL::COUNTERCLOCKWISE) { @@ -347,11 +340,10 @@ namespace convex_plane_extraction { Vector2d ray_source = Vector2d(ray_source_it->x(), ray_source_it->y()); Vector2d ray_target = Vector2d(ray_target_it->x(), ray_target_it->y()); Vector2d ray_direction = ray_target - ray_source; - std::cout << "Ray direction: " << ray_direction << std::endl; vertex_it = next(vertex_it, polygon); + // Do not intersect with adjacent edges since the intersect already in common vertex. auto condition_it = ray_source_it; if (orientation == CGAL::CLOCKWISE){ - //vertex_it = next(vertex_it, polygon); // Compensate for previous above. condition_it = ray_target_it; } while(next(vertex_it, polygon) != condition_it){ @@ -361,12 +353,8 @@ namespace convex_plane_extraction { Vector2d intersection_point; if (intersectRayWithLineSegment(ray_source, ray_direction, segment_source, segment_target, &intersection_point)){ - std::cout << "Intersection succeeded with: " << std::endl; - std::cout << "Ray source" << ray_source << std::endl; - std::cout << "Segment source: " << segment_source << std::endl; - std::cout << "Segment target: " << segment_target << std::endl; - std::cout << "Intersection point: " << intersection_point << std::endl; - double current_distance = distanceBetweenPoints(ray_target, intersection_point); + double current_distance = distanceBetweenPoints(ray_target, intersection_point); + // Take first intersection on ray. if (current_distance < min_distance){ one_intersection_at_least = true; min_distance = current_distance; @@ -376,7 +364,7 @@ namespace convex_plane_extraction { } vertex_it = next(vertex_it, polygon); } - //CHECK(one_intersection_at_least); + if (!one_intersection_at_least){ return false; } @@ -385,16 +373,15 @@ namespace convex_plane_extraction { return true; } + // Erases vertices [first, last), takes warp around into account. CgalPolygon2dVertexIterator erase(CgalPolygon2dVertexIterator first, CgalPolygon2dVertexIterator last, CgalPolygon2d* polygon){ CHECK_NOTNULL(polygon); CHECK(first != last); - std::cout << "Starting erasing!" << std::endl; if ((std::distance(polygon->vertices_begin(), last) - std::distance(polygon->vertices_begin(), first)) > 0){ - std::cout << (std::distance(polygon->vertices_begin(), last) - std::distance(polygon->vertices_begin(), first)) << std::endl; + // std::cout << (std::distance(polygon->vertices_begin(), last) - std::distance(polygon->vertices_begin(), first)) << std::endl; return polygon->erase(first, last); } else { - std::cout << "Erasing overflow!" << std::endl; int last_iterator_distance = std::distance(polygon->vertices_begin(), last); polygon->erase(first, polygon->vertices_end()); auto erase_iterator = polygon->vertices_begin(); @@ -402,8 +389,9 @@ namespace convex_plane_extraction { return polygon->erase(polygon->vertices_begin(), erase_iterator); } } - // Solves the wrap around issue. - // [first last) are copied to new_polygon before the position indicated ny insert_position. + + // [first last) are copied to new_polygon before the position indicated by insert_position. + // Takes wrap around into account void copyVertices(const CgalPolygon2d& old_polygon, const CgalPolygon2dVertexIterator first, const CgalPolygon2dVertexIterator last, CgalPolygon2d* new_polygon, const CgalPolygon2dVertexIterator insert_position){ CHECK_NOTNULL(new_polygon); From 08ef1d473a1eaee3df6920156aac013e24120541 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Thu, 30 Jan 2020 20:50:07 +0100 Subject: [PATCH 009/504] Fix rank loss. --- .../src/geometry_utils.cpp | 8 ++++-- convex_plane_decomposition/src/polygon.cpp | 26 +++++++++++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp index 627c7244..b5af2e9a 100644 --- a/convex_plane_decomposition/src/geometry_utils.cpp +++ b/convex_plane_decomposition/src/geometry_utils.cpp @@ -44,10 +44,14 @@ namespace convex_plane_extraction { A.col(0) = ray_direction; A.col(1) = - segment_direction; Vector2d b = segment_source - ray_source; - Vector2d solution = A.fullPivHouseholderQr().solve(b); + auto householder_qr = A.fullPivHouseholderQr(); + if (householder_qr.rank() < 2){ + return false; + } + Vector2d solution = householder_qr.solve(b); Vector2d ray_solution = ray_source + solution(0) * segment_direction; Vector2d segment_solution = segment_source + solution(1) * segment_direction; - if (solution(0) <= 0 || solution(1) <= 0 || solution(1) > 1){ + if (solution(0) <= 1 || solution(1) < 0 || solution(1) > 1){ return false; } *intersection_point = segment_solution; diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 8d9f853f..96229ea9 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -204,7 +204,9 @@ namespace convex_plane_extraction { CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); std::list return_list; std::map dent_locations; + LOG(INFO) << "Before dent detection"; detectDentLocations(&dent_locations, polygon); + LOG(INFO) << "Passed dent detection"; if (dent_locations.empty()){ // No dents detected, polygon must be convex. // CGAL convexity check might still fail, since very shallow dents are ignored. @@ -248,11 +250,12 @@ namespace convex_plane_extraction { if ((intersection_counterclockwise.intersection_point_ - point_before_intersection).squared_length() > kSquaredLengthThreshold) { polygon_counterclockwise_2.push_back(intersection_counterclockwise.intersection_point_); } + LOG(INFO) << "Before erase!"; CgalPolygon2dVertexIterator element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); // Add intersection vertex to first polygon if existing vertex too far away. -// if ((intersection_counterclockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { + if ((intersection_counterclockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { polygon_counterclockwise_1.insert(element_behind_deleted_it, intersection_counterclockwise.intersection_point_); -// } + } // Resulting cut from clockwise ray intersection. CgalPolygon2d polygon_clockwise_1 = polygon; CgalPolygon2d polygon_clockwise_2; @@ -268,12 +271,18 @@ namespace convex_plane_extraction { polygon_clockwise_2.vertices_end()); polygon_clockwise_2.push_back(*last_vertex_to_erase_it); element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_1); -// if ((intersection_clockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { + LOG(INFO) << "After erase!"; + if ((intersection_clockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { polygon_clockwise_1.insert(element_behind_deleted_it, intersection_clockwise.intersection_point_); -// } + } + printPolygon(polygon_counterclockwise_1); + printPolygon(polygon_counterclockwise_2); + printPolygon(polygon_clockwise_1); + printPolygon(polygon_clockwise_2); // Take the cut with smallest min. area of resulting polygons. double area[4] = {polygon_counterclockwise_1.area(), polygon_counterclockwise_2.area(), polygon_clockwise_1.area(), polygon_clockwise_2.area()}; + LOG(INFO) << "Passed area computation!"; double* min_area_strategy = std::min_element(area, area+4); std::list recursion_1; std::list recursion_2; @@ -313,7 +322,7 @@ namespace convex_plane_extraction { } return_list.splice(return_list.end(), recursion_1); return_list.splice(return_list.end(), recursion_2); - + LOG(INFO) << "Reached bottom!"; return return_list; } @@ -338,6 +347,7 @@ namespace convex_plane_extraction { ray_source_it = vertex_it; } Vector2d ray_source = Vector2d(ray_source_it->x(), ray_source_it->y()); + LOG(INFO) << "Source ray:" << ray_source; Vector2d ray_target = Vector2d(ray_target_it->x(), ray_target_it->y()); Vector2d ray_direction = ray_target - ray_source; vertex_it = next(vertex_it, polygon); @@ -353,6 +363,12 @@ namespace convex_plane_extraction { Vector2d intersection_point; if (intersectRayWithLineSegment(ray_source, ray_direction, segment_source, segment_target, &intersection_point)){ + LOG(INFO) << "Intersection point:" << intersection_point; + LOG(INFO) << segment_source; + if ((ray_target - intersection_point).norm() < 0.001){ + LOG(INFO) << segment_source; + continue; + } double current_distance = distanceBetweenPoints(ray_target, intersection_point); // Take first intersection on ray. if (current_distance < min_distance){ From fc9c66c467f09a4624a232db114b8616d376df94 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Fri, 31 Jan 2020 09:52:50 +0100 Subject: [PATCH 010/504] Fix infinite loop. --- convex_plane_decomposition/src/polygon.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 96229ea9..e65da1d5 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -367,6 +367,7 @@ namespace convex_plane_extraction { LOG(INFO) << segment_source; if ((ray_target - intersection_point).norm() < 0.001){ LOG(INFO) << segment_source; + vertex_it = next(vertex_it, polygon); continue; } double current_distance = distanceBetweenPoints(ray_target, intersection_point); From 0c95dc3f1b9c13e7dfb1aa8020ccadcc4c40d4d9 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Fri, 31 Jan 2020 14:33:58 +0100 Subject: [PATCH 011/504] Csv export. --- convex_plane_decomposition/CMakeLists.txt | 3 ++- .../include/convex_plane_extraction_ros.hpp | 10 +------- .../include/export_utils.hpp | 21 +++++++++++++++++ .../src/convex_plane_extraction_ros.cpp | 3 +++ .../src/export_utils.cpp | 23 +++++++++++++++++++ 5 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 convex_plane_decomposition/include/export_utils.hpp create mode 100644 convex_plane_decomposition/src/export_utils.cpp diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 077381ca..c0d32a3b 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -163,7 +163,8 @@ add_executable(${PROJECT_NAME}_node src/plane.cpp src/polygon.cpp src/ros_visualizations.cpp - src/geometry_utils.cpp) + src/geometry_utils.cpp + src/export_utils.cpp) ## Rename C++ executable without prefix ## The above recommended prefix causes long target names, the following renames the diff --git a/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp b/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp index d94efe33..6f1de627 100644 --- a/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp +++ b/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp @@ -1,12 +1,3 @@ -/* - * FiltersDemo.hpp - * - * Created on: Aug 16, 2017 - * Author: Peter Fankhauser - * Institute: ETH Zurich, ANYbotics - * - */ - #pragma once #include @@ -18,6 +9,7 @@ #include +#include "export_utils.hpp" #include "grid_map_preprocessing.hpp" #include "plane_extractor.hpp" #include "ransac_plane_extractor.hpp" diff --git a/convex_plane_decomposition/include/export_utils.hpp b/convex_plane_decomposition/include/export_utils.hpp new file mode 100644 index 00000000..a902ee93 --- /dev/null +++ b/convex_plane_decomposition/include/export_utils.hpp @@ -0,0 +1,21 @@ +#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_EXPORT_UTILS_HPP_ +#define CONVEX_PLANE_EXTRACTION_INCLUDE_EXPORT_UTILS_HPP_ + +#include +#include +#include + +#include +#include + +#include "grid_map_ros/grid_map_ros.hpp" + + +namespace convex_plane_extraction { + + bool exportPointsWithNormalsToCsv(grid_map::GridMap &map, const std::string &normals_layer_prefix, + const std::string &layer_height); + +} + +#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_EXPORT_UTILS_HPP_ diff --git a/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp b/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp index 54b90b4d..7ff74e33 100644 --- a/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp +++ b/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp @@ -91,6 +91,9 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { std::cout << inputMap.getPosition() << std::endl; CHECK(success); ROS_INFO("...done."); +// if(exportPointsWithNormalsToCsv(inputMap, "normal_vectors_", "elevation")){ +// ROS_INFO("Map exported to csv."); +// } applyMedianFilter(inputMap.get("elevation"), 5); // Compute planar region segmentation ROS_INFO("Initializing plane extractor..."); diff --git a/convex_plane_decomposition/src/export_utils.cpp b/convex_plane_decomposition/src/export_utils.cpp new file mode 100644 index 00000000..fd1a762d --- /dev/null +++ b/convex_plane_decomposition/src/export_utils.cpp @@ -0,0 +1,23 @@ +#include "export_utils.hpp" + + +namespace convex_plane_extraction { + + bool exportPointsWithNormalsToCsv(grid_map::GridMap &map, const std::string &normals_layer_prefix, + const std::string &layer_height) { + std::ofstream output_file; + output_file.open("/home/andrej/sp_ws/points_and_normals.csv"); + for (grid_map::GridMapIterator iterator(map); + !iterator.isPastEnd(); ++iterator) { + grid_map::Position3 position3; + Eigen::Vector3d point; + Eigen::Vector3d normal; + map.getPosition3(layer_height, *iterator, point); + map.getVector(normals_layer_prefix, *iterator, normal); + output_file << point(0) << ", " << point(1) << ", " << point(2) << ", " << + normal(0) << ", " << normal(1) << ", " << normal(2) << "\n"; + } + return true; + } + +} \ No newline at end of file From 836587a93fbeeaecacba26dfcdd357f2e9aceedb Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Fri, 31 Jan 2020 18:54:35 +0100 Subject: [PATCH 012/504] Fix assertion fail on overlapping rays. --- .../src/geometry_utils.cpp | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp index b5af2e9a..a32ad2e8 100644 --- a/convex_plane_decomposition/src/geometry_utils.cpp +++ b/convex_plane_decomposition/src/geometry_utils.cpp @@ -46,6 +46,32 @@ namespace convex_plane_extraction { Vector2d b = segment_source - ray_source; auto householder_qr = A.fullPivHouseholderQr(); if (householder_qr.rank() < 2){ + // Check whether segment and ray overlap. + Vector2d p_ray_source_segment_source = segment_source - ray_source; + Vector2d ray_parameter_solution = Vector2d(p_ray_source_segment_source.x() / ray_direction.x(), + p_ray_source_segment_source.y() / ray_direction.y()); + constexpr double kSolutionDeviation = 0.0001; + if (abs(ray_parameter_solution.x() - ray_parameter_solution.y()) < kSolutionDeviation){ + double parameter_solution_tmp = ray_parameter_solution.mean(); + if (parameter_solution_tmp < 0){ + return false; + } + CHECK_GT(parameter_solution_tmp, 0); + Vector2d p_ray_source_segment_target = segment_target - ray_source; + ray_parameter_solution = Vector2d(p_ray_source_segment_target.x() / ray_direction.x(), + p_ray_source_segment_target.y() / ray_direction.y()); + // If ray is parallel (rank loss) and source point lies on ray, then target point has to as well. + CHECK(abs(ray_parameter_solution.x() - ray_parameter_solution.y()) < kSolutionDeviation); + if(ray_parameter_solution.mean() < 0){ + return false; + } + if (ray_parameter_solution.mean() < parameter_solution_tmp){ + *intersection_point = segment_target; + } else { + *intersection_point = segment_source; + } + return true; + } return false; } Vector2d solution = householder_qr.solve(b); From 9935987e2b1b1d3f72f73404448a9eca9e82fc32 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Sun, 2 Feb 2020 16:58:00 +0100 Subject: [PATCH 013/504] Some improvement. Check fails. --- .../include/geometry_utils.hpp | 3 + convex_plane_decomposition/include/plane.hpp | 2 +- .../include/polygon.hpp | 3 +- .../src/geometry_utils.cpp | 49 ++++++++++++++++ convex_plane_decomposition/src/plane.cpp | 56 ++++++++++++------- convex_plane_decomposition/src/polygon.cpp | 50 ++++++++++++----- .../src/sliding_window_plane_extractor.cpp | 3 +- 7 files changed, 130 insertions(+), 36 deletions(-) diff --git a/convex_plane_decomposition/include/geometry_utils.hpp b/convex_plane_decomposition/include/geometry_utils.hpp index a2b1f786..3f1304ca 100644 --- a/convex_plane_decomposition/include/geometry_utils.hpp +++ b/convex_plane_decomposition/include/geometry_utils.hpp @@ -19,5 +19,8 @@ bool intersectRayWithLineSegment(const Vector2d& ray_source, const Vector2d& ray const Vector2d& segment_source, const Vector2d& segment_target, Vector2d* intersection_point); double distanceBetweenPoints(Vector2d first, Vector2d second); + +bool intersectLineSegmentWithLineSegment(const Vector2d& segment_1_source, const Vector2d& segment_1_target, + const Vector2d& segment_2_source, const Vector2d& segment_2_target, Vector2d* intersection_point); } #endif //CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ diff --git a/convex_plane_decomposition/include/plane.hpp b/convex_plane_decomposition/include/plane.hpp index 25387a05..fe6645f3 100644 --- a/convex_plane_decomposition/include/plane.hpp +++ b/convex_plane_decomposition/include/plane.hpp @@ -54,7 +54,7 @@ namespace convex_plane_extraction { void extractSlConcavityPointsOfHole(const CgalPolygon2d& hole, std::vector* concavity_positions); - void slConcavityHoleVertexSorting(const CgalPolygon2d& hole, std::multimap* concavity_positions); + void slConcavityHoleVertexSorting(const CgalPolygon2d& hole, std::multimap>* concavity_positions); bool initialized_; diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index 3430ffb0..b4062d5a 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -41,6 +41,7 @@ namespace convex_plane_extraction{ typedef std::vector Polygon3d; typedef std::vector Polygon3dVectorContainer; + typedef K::Intersect_2 Intersect_2; template @@ -77,7 +78,7 @@ namespace convex_plane_extraction{ void performConvexDecomposition(const CgalPolygon2d& polygon, CgalPolygon2dListContainer* output_polyong_list); - bool doPolygonAndSegmentIntersect(const CgalPolygon2d& polygon, const CgalSegment2d& segment); + bool doPolygonAndSegmentIntersect(const CgalPolygon2d& polygon, const CgalSegment2d& segment, bool print_flag); int getClosestPolygonVertexPosition(const CgalPolygon2d& polygon, const CgalPoint2d& point); diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp index a32ad2e8..07e6714a 100644 --- a/convex_plane_decomposition/src/geometry_utils.cpp +++ b/convex_plane_decomposition/src/geometry_utils.cpp @@ -84,6 +84,55 @@ namespace convex_plane_extraction { return true; } + bool intersectLineSegmentWithLineSegment(const Vector2d& segment_1_source, const Vector2d& segment_1_target, + const Vector2d& segment_2_source, const Vector2d& segment_2_target, Vector2d* intersection_point){ + CHECK_NOTNULL(intersection_point); + Vector2d segment_1_direction = segment_1_target - segment_1_source; + Vector2d segment_2_direction = segment_2_target - segment_2_source; + Matrix2d A; + A.col(0) = segment_1_direction; + A.col(1) = - segment_2_direction; + Vector2d b = segment_2_source - segment_1_source; + auto householder_qr = A.fullPivHouseholderQr(); + if (householder_qr.rank() < 2){ + // Check whether segment and ray overlap. + Vector2d p_ray_source_segment_source = segment_2_source - segment_1_source; + Vector2d ray_parameter_solution = Vector2d(p_ray_source_segment_source.x() / segment_1_direction.x(), + p_ray_source_segment_source.y() / segment_1_direction.y()); + constexpr double kSolutionDeviation = 0.0001; + if (abs(ray_parameter_solution.x() - ray_parameter_solution.y()) < kSolutionDeviation){ + double parameter_solution_tmp = ray_parameter_solution.mean(); + if (parameter_solution_tmp < 0){ + return false; + } + CHECK_GT(parameter_solution_tmp, 0); + Vector2d p_ray_source_segment_target = segment_2_target - segment_1_source; + ray_parameter_solution = Vector2d(p_ray_source_segment_target.x() / segment_1_direction.x(), + p_ray_source_segment_target.y() / segment_1_direction.y()); + // If ray is parallel (rank loss) and source point lies on ray, then target point has to as well. + CHECK(abs(ray_parameter_solution.x() - ray_parameter_solution.y()) < kSolutionDeviation); + if(ray_parameter_solution.mean() < 0){ + return false; + } + if (ray_parameter_solution.mean() < parameter_solution_tmp){ + *intersection_point = segment_2_target; + } else { + *intersection_point = segment_2_source; + } + return true; + } + return false; + } + Vector2d solution = householder_qr.solve(b); + Vector2d ray_solution = segment_1_source + solution(0) * segment_2_direction; + Vector2d segment_solution = segment_2_source + solution(1) * segment_2_direction; + if (solution(0) < 0 || solution(0) > 1 || solution(1) < 0 || solution(1) > 1){ + return false; + } + *intersection_point = segment_solution; + return true; + } + double distanceBetweenPoints(Vector2d first, Vector2d second){ return (second - first).norm(); } diff --git a/convex_plane_decomposition/src/plane.cpp b/convex_plane_decomposition/src/plane.cpp index 51101330..33959bcf 100644 --- a/convex_plane_decomposition/src/plane.cpp +++ b/convex_plane_decomposition/src/plane.cpp @@ -190,47 +190,62 @@ namespace convex_plane_extraction{ ++hole_it; hole_polygon_list_.erase(std::prev(hole_it)); } else { - std::multimap connection_candidates; + std::cout << "List size: " << hole_polygon_list_.size() << std::endl; + std::cout << "Outer: " << std::endl; + printPolygon(outer_polygon_); + std::cout << "Hole: " << std::endl; + printPolygon(*hole_polygon_list_.begin()); + std::multimap> connection_candidates; slConcavityHoleVertexSorting(*hole_it, &connection_candidates); - CHECK_GT(connection_candidates.size(), 0); + CHECK(connection_candidates.size() == hole_it->size()*outer_polygon_.size()); // Instead of extracting only the 2 SL-concavity points, sort vertices according to SL-concavity measure. // Then iterate over sorted vertices until a connection to the outer contour is not intersecting the polyogn. // Implement function that checks for intersections with existing polygon contour. int hole_connection_vertex_position; int outer_polygon_connection_vertex_position; bool valid_connection = true; + int i = 0; for (const auto& position : connection_candidates){ auto hole_vertex_it = hole_it->vertices_begin(); - std::advance(hole_vertex_it, position.second); + std::advance(hole_vertex_it, position.second.first); + bool print_flag = false; + if (position.second.first == 7){ + print_flag = true; + } CgalPoint2d hole_vertex = *hole_vertex_it; // Get outer contour connection vertices sorted according to distance to hole vertex. - std::multimap outer_polygon_vertices; - getVertexPositionsInAscendingDistanceToPoint(outer_polygon_, hole_vertex, &outer_polygon_vertices); auto outer_vertex_it = outer_polygon_.vertices_begin(); - std::advance(outer_vertex_it, outer_polygon_vertices.begin()->second); + std::advance(outer_vertex_it, position.second.second); CgalVector2d direction = *outer_vertex_it - hole_vertex; direction = (1.0/direction.squared_length()) * direction; - CgalSegment2d connection(hole_vertex + 0.001 * direction, *outer_vertex_it - 0.001 * direction); - if (!doPolygonAndSegmentIntersect(outer_polygon_, connection)){ + CgalSegment2d connection(hole_vertex + 0.0001 * direction, *outer_vertex_it - 0.0001 * direction); + if (!doPolygonAndSegmentIntersect(outer_polygon_, connection, print_flag)){ for (auto hole_iterator = hole_polygon_list_.begin(); hole_iterator != hole_polygon_list_.end(); ++hole_iterator){ if (hole_iterator->size() < 3){ continue; } - if (doPolygonAndSegmentIntersect(*hole_iterator, connection)) { + if (doPolygonAndSegmentIntersect(*hole_iterator, connection, print_flag)) { valid_connection = false; + //std::cout << "Hole and connection intersect!" << std::endl; + ++i; break; } } + valid_connection = true; } else { + //std::cout << "Outer contour and connection intersect!" << std::endl; + ++i; valid_connection = false; } if (valid_connection){ - hole_connection_vertex_position = position.second; - outer_polygon_connection_vertex_position = outer_polygon_vertices.begin()->second; + hole_connection_vertex_position = position.second.first; + outer_polygon_connection_vertex_position = position.second.second; break; } } if (!valid_connection){ + CHECK_EQ(i, hole_it->size()*outer_polygon_.size()); + LOG(WARNING) << "No valid connection found! " << i << " iterations."; ++hole_it; continue; } @@ -274,9 +289,9 @@ namespace convex_plane_extraction{ Eigen::Vector2d translation_vector(next_vertex->x() - outer_contour_connection_vertex->x(), next_vertex->y() - outer_contour_connection_vertex->y()); translation_vector.normalize(); - outer_point += kPointOffset * translation_vector; + outer_point += kPointOffset * translation_vector.normalized(); } else { - outer_point += kPointOffset * normal_vector; + outer_point += kPointOffset * normal_vector.normalized(); } next_vertex = hole_contour_connection_vertex; if (next_vertex == hole_it->vertices_begin()){ @@ -306,12 +321,11 @@ namespace convex_plane_extraction{ for (; vertex_it != outer_polygon_.vertices_end(); ++vertex_it){ new_polygon.push_back(*vertex_it); } - if (new_polygon.is_simple()){ + if (!new_polygon.is_simple()){ std::cout << "Hole orientation: " << hole_it->orientation() << std::endl; std::cout <<"Hole vertex: " << *hole_contour_connection_vertex << std::endl; std::cout <<"Outer vertex: " << *outer_contour_connection_vertex << std::endl; - for (auto& point : new_polygon) - std::cout << point << std::endl; + printPolygon(new_polygon); } CHECK(new_polygon.is_simple()); outer_polygon_ = new_polygon; @@ -319,7 +333,7 @@ namespace convex_plane_extraction{ hole_polygon_list_.erase(std::prev(hole_it)); } } - approximateContour(&outer_polygon_); + //approximateContour(&outer_polygon_); CHECK(outer_polygon_.is_simple()); } @@ -373,13 +387,15 @@ namespace convex_plane_extraction{ } } - void Plane::slConcavityHoleVertexSorting(const CgalPolygon2d& hole, std::multimap* concavity_positions){ + void Plane::slConcavityHoleVertexSorting(const CgalPolygon2d& hole, std::multimap>* concavity_positions){ CHECK_NOTNULL(concavity_positions); for (auto vertex_it = hole.vertices_begin(); vertex_it != hole.vertices_end(); ++vertex_it){ std::multimap outer_polygon_vertices; getVertexPositionsInAscendingDistanceToPoint(outer_polygon_, *vertex_it, &outer_polygon_vertices); - concavity_positions->insert(std::pair(outer_polygon_vertices.begin()->first, - std::distance(hole.vertices_begin(), vertex_it))); + for (const auto& outer_distance_vertex_pair : outer_polygon_vertices) { + concavity_positions->insert(std::pair>(outer_distance_vertex_pair.first, + std::pair(std::distance(hole.vertices_begin(), vertex_it),outer_distance_vertex_pair.second))); + } } } diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index e65da1d5..1c02ede8 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -7,29 +7,53 @@ namespace convex_plane_extraction { CHECK(polygon.is_simple()); LOG(INFO) << "Started convex decomposition..."; size_t old_list_size = output_polygon_list->size(); -// CGAL::optimal_convex_partition_2(polygon.vertices_begin(), -// polygon.vertices_end(), -// std::back_inserter(*output_polygon_list)); -// -// assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), -// polygon.vertices_end(), -// polygon_list.begin(), -// polygon_list.end())); - *output_polygon_list = decomposeInnerApproximation(polygon); + CGAL::optimal_convex_partition_2(polygon.vertices_begin(), + polygon.vertices_end(), + std::back_inserter(*output_polygon_list)); + + assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), + polygon.vertices_end(), + polygon_list.begin(), + polygon_list.end())); +// *output_polygon_list = decomposeInnerApproximation(polygon); CHECK_GT(output_polygon_list->size(), old_list_size); LOG(INFO) << "done."; } - bool doPolygonAndSegmentIntersect(const CgalPolygon2d& polygon, const CgalSegment2d& segment){ + bool doPolygonAndSegmentIntersect(const CgalPolygon2d& polygon, const CgalSegment2d& segment, bool print_flag){ for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it){ auto next_vertex_it = std::next(vertex_it); if (next_vertex_it == polygon.vertices_end()){ next_vertex_it = polygon.vertices_begin(); } CgalSegment2d test_segment(*vertex_it, *next_vertex_it); - if (do_intersect(test_segment, segment)){ - return true; + CGAL::cpp11::result_of::type + result = intersection(test_segment, segment); + if (result) { + if (const CgalSegment2d *s = boost::get(&*result)) { + std::cout << *s << std::endl; + return true; + } else { + const CgalPoint2d *p = boost::get(&*result); + if (print_flag) { + std::cout << *p << ";" << std::endl; + } + return true; + } } +// Vector2d test_segment_source(vertex_it->x(), vertex_it->y()); +// Vector2d test_segment_target(next_vertex_it->x(), next_vertex_it->y()); +// Vector2d segment_source(segment.source().x(), segment.source().y()); +// Vector2d segment_target(segment.target().x(), segment.target().y()); +// Vector2d intersection_point; +// if (intersectLineSegmentWithLineSegment(test_segment_source, test_segment_target, +// segment_source, segment_target, &intersection_point)){ +// std::cout << intersection_point.x() << ", " << intersection_point.y() << ";" << std::endl; +// return true; +// } +// if (do_intersect(test_segment, segment)){ +// return true; +// } } return false; } @@ -95,7 +119,7 @@ namespace convex_plane_extraction { double a = (third_point - first_point).norm(); double b = (second_point - third_point).norm(); double c = (first_point - second_point).norm(); - constexpr double areaThresholdFactor = 0.01; + constexpr double areaThresholdFactor = 0.025; if (computeTriangleArea(a, b, c) < areaThresholdFactor * area) { LOG(INFO) << "Area sufficiently small!"; CgalPolygon2d new_polygon(*polygon); diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index 6d1aac6b..b2a1e141 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -153,6 +153,7 @@ namespace sliding_window_plane_extractor{ constexpr int kParentFlagIndex = 3; if (hierarchy[hierachy_it-1][kParentFlagIndex] < 0) { //convex_plane_extraction::upSampleLongEdges(&polygon); +// convex_plane_extraction::approximateContour(&polygon); CHECK(plane.addOuterPolygon(polygon)); } else { CHECK(plane.addHolePolygon(polygon)); @@ -163,7 +164,7 @@ namespace sliding_window_plane_extractor{ computePlaneFrameFromLabeledImage(binary_image, &plane); if(plane.isValid()) { LOG(INFO) << "Starting resolving holes..."; - // plane.resolveHoles(); + plane.resolveHoles(); LOG(INFO) << "done."; CHECK(plane.decomposePlaneInConvexPolygons()); planes_.push_back(plane); From 50f18ec6a612a00e24cc4c0e935630f27c11fb4b Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Sun, 2 Feb 2020 20:45:30 +0100 Subject: [PATCH 014/504] Fix. --- convex_plane_decomposition/src/plane.cpp | 29 ++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/convex_plane_decomposition/src/plane.cpp b/convex_plane_decomposition/src/plane.cpp index 33959bcf..e22e795b 100644 --- a/convex_plane_decomposition/src/plane.cpp +++ b/convex_plane_decomposition/src/plane.cpp @@ -220,6 +220,7 @@ namespace convex_plane_extraction{ direction = (1.0/direction.squared_length()) * direction; CgalSegment2d connection(hole_vertex + 0.0001 * direction, *outer_vertex_it - 0.0001 * direction); if (!doPolygonAndSegmentIntersect(outer_polygon_, connection, print_flag)){ + valid_connection = true; for (auto hole_iterator = hole_polygon_list_.begin(); hole_iterator != hole_polygon_list_.end(); ++hole_iterator){ if (hole_iterator->size() < 3){ continue; @@ -231,7 +232,6 @@ namespace convex_plane_extraction{ break; } } - valid_connection = true; } else { //std::cout << "Outer contour and connection intersect!" << std::endl; ++i; @@ -283,7 +283,7 @@ namespace convex_plane_extraction{ next_vertex = outer_polygon_.begin(); } Eigen::Vector2d test_point(next_vertex->x(), next_vertex->y()); - constexpr double kPointOffset = 0.001; + constexpr double kPointOffset = 0.0001; Eigen::Vector2d outer_point(outer_contour_connection_vertex->x(), outer_contour_connection_vertex->y()); if (isPointOnLeftSide(line_start_point, direction_vector, test_point)){ Eigen::Vector2d translation_vector(next_vertex->x() - outer_contour_connection_vertex->x(), @@ -312,6 +312,31 @@ namespace convex_plane_extraction{ } else { hole_point += kPointOffset * normal_vector; } + Vector2d new_edge_direction = outer_point - hole_point; + new_edge_direction.normalize(); + constexpr double kShiftFactor = 0.0001; + bool intersection_caused = false; + CgalSegment2d new_edge(CgalPoint2d(hole_point.x() + kShiftFactor * new_edge_direction.x(), + hole_point.y() + kShiftFactor * new_edge_direction.y()),CgalPoint2d(outer_point.x() - + kShiftFactor * new_edge_direction.x(), outer_point.y() - kShiftFactor * new_edge_direction.y())); + if (!doPolygonAndSegmentIntersect(outer_polygon_, new_edge, false)){ + for (auto hole_iterator = hole_polygon_list_.begin(); hole_iterator != hole_polygon_list_.end(); ++hole_iterator){ + if (hole_iterator->size() < 3){ + continue; + } + if (doPolygonAndSegmentIntersect(*hole_iterator, new_edge, false)) { + intersection_caused = true; + break; + } + } + } else { + //std::cout << "Outer contour and connection intersect!" << std::endl; + intersection_caused = true; + } + if (intersection_caused){ + ++hole_it; + continue; + } // Add new vertices to outer contour. new_polygon.push_back(CgalPoint2d(hole_point.x(), hole_point.y())); new_polygon.push_back(CgalPoint2d(outer_point.x(), outer_point.y())); From cc715c3ce32fa3286f9152a8d6cf058862558144 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Mon, 3 Feb 2020 12:17:17 +0100 Subject: [PATCH 015/504] Experimental exports. --- convex_plane_decomposition/include/plane.hpp | 2 ++ .../include/plane_extractor.hpp | 1 + .../sliding_window_plane_extractor.hpp | 3 +++ convex_plane_decomposition/src/plane.cpp | 4 +++ convex_plane_decomposition/src/polygon.cpp | 18 ++++++------- .../src/sliding_window_plane_extractor.cpp | 25 +++++++++++++++++++ 6 files changed, 44 insertions(+), 9 deletions(-) diff --git a/convex_plane_decomposition/include/plane.hpp b/convex_plane_decomposition/include/plane.hpp index fe6645f3..bc57ebf2 100644 --- a/convex_plane_decomposition/include/plane.hpp +++ b/convex_plane_decomposition/include/plane.hpp @@ -50,6 +50,8 @@ namespace convex_plane_extraction { void resolveHoles(); + const CgalPolygon2dListContainer& getConvexPolygons() const; + private: void extractSlConcavityPointsOfHole(const CgalPolygon2d& hole, std::vector* concavity_positions); diff --git a/convex_plane_decomposition/include/plane_extractor.hpp b/convex_plane_decomposition/include/plane_extractor.hpp index 01a373a4..4434f111 100644 --- a/convex_plane_decomposition/include/plane_extractor.hpp +++ b/convex_plane_decomposition/include/plane_extractor.hpp @@ -61,6 +61,7 @@ namespace convex_plane_extraction { void visualizeConvexDecomposition(jsk_recognition_msgs::PolygonArray* ros_polygon_array){ CHECK_NOTNULL(ros_polygon_array); sliding_window_plane_extractor_.visualizeConvexDecomposition(ros_polygon_array); + sliding_window_plane_extractor_.exportConvexPolygons("/home/andrej/Desktop/"); } void visualizePlaneContours(jsk_recognition_msgs::PolygonArray* ros_polygon_outer_contours, jsk_recognition_msgs::PolygonArray* ros_polygon_hole_contours){ diff --git a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp index d1f7a3e3..0cc76ea0 100644 --- a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp +++ b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp @@ -1,6 +1,7 @@ #ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_SLIDING_WINDOW_PLANE_EXTRACTOR_HPP_ #define CONVEX_PLANE_EXTRACTION_INCLUDE_SLIDING_WINDOW_PLANE_EXTRACTOR_HPP_ +#include #include #include #include @@ -50,6 +51,8 @@ namespace sliding_window_plane_extractor { void visualizePlaneContours(jsk_recognition_msgs::PolygonArray* outer_polygons, jsk_recognition_msgs::PolygonArray* hole_poylgons) const; + void exportConvexPolygons(const std::string& path) const; + private: grid_map::GridMap& map_; diff --git a/convex_plane_decomposition/src/plane.cpp b/convex_plane_decomposition/src/plane.cpp index e22e795b..e164c3d5 100644 --- a/convex_plane_decomposition/src/plane.cpp +++ b/convex_plane_decomposition/src/plane.cpp @@ -424,4 +424,8 @@ namespace convex_plane_extraction{ } } + const CgalPolygon2dListContainer& Plane::getConvexPolygons() const { + return convex_polygon_list_; + } + } diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 1c02ede8..97c33bca 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -7,15 +7,15 @@ namespace convex_plane_extraction { CHECK(polygon.is_simple()); LOG(INFO) << "Started convex decomposition..."; size_t old_list_size = output_polygon_list->size(); - CGAL::optimal_convex_partition_2(polygon.vertices_begin(), - polygon.vertices_end(), - std::back_inserter(*output_polygon_list)); - - assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), - polygon.vertices_end(), - polygon_list.begin(), - polygon_list.end())); -// *output_polygon_list = decomposeInnerApproximation(polygon); +// CGAL::optimal_convex_partition_2(polygon.vertices_begin(), +// polygon.vertices_end(), +// std::back_inserter(*output_polygon_list)); +// +// assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), +// polygon.vertices_end(), +// polygon_list.begin(), +// polygon_list.end())); + *output_polygon_list = decomposeInnerApproximation(polygon); CHECK_GT(output_polygon_list->size(), old_list_size); LOG(INFO) << "done."; } diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index b2a1e141..a33292ee 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -241,5 +241,30 @@ namespace sliding_window_plane_extractor{ } } } + + void SlidingWindowPlaneExtractor::exportConvexPolygons(const std::string& path) const { + std::ofstream output_file; + output_file.open(path + "convex_polygons.txt", std::ofstream::app); + std::chrono::milliseconds time_stamp = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()); + for (const auto& plane : planes_){ + for (const auto& polygon : plane.getConvexPolygons()){ + output_file << time_stamp.count() << ", "; + for (const auto& vertex : polygon){ + output_file << vertex.x() << ", "; + } + for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it){ + output_file << vertex_it->y(); + if (vertex_it != std::prev(polygon.vertices_end())){ + output_file << ", "; + } else { + output_file << "\n"; + } + } + } + } + output_file.close(); + LOG(INFO) << "Exported polygons!"; + } } From b90e9f8571ccad9890b4b101439ed4bee13f2753 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Sun, 23 Feb 2020 20:21:12 +0100 Subject: [PATCH 016/504] Evaluation dependent stuff. --- .../launch/convex_plane_extraction.launch | 8 ++-- .../src/convex_plane_extraction_ros.cpp | 33 ++++++++++++-- convex_plane_decomposition/src/polygon.cpp | 18 ++++---- .../src/ransac_plane_extractor.cpp | 6 ++- .../src/sliding_window_plane_extractor.cpp | 44 ++++++++++++++++--- 5 files changed, 86 insertions(+), 23 deletions(-) diff --git a/convex_plane_decomposition/launch/convex_plane_extraction.launch b/convex_plane_decomposition/launch/convex_plane_extraction.launch index 8e347c3a..11ea00bc 100644 --- a/convex_plane_decomposition/launch/convex_plane_extraction.launch +++ b/convex_plane_decomposition/launch/convex_plane_extraction.launch @@ -5,12 +5,12 @@ --> - + - - + + - + diff --git a/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp b/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp index 7ff74e33..699f2613 100644 --- a/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp +++ b/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp @@ -80,12 +80,14 @@ bool ConvexPlaneExtractionROS::readParameters() } void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { + auto start_total = std::chrono::system_clock::now(); + // Convert message to map. ROS_INFO("Reading input map..."); GridMap messageMap; GridMapRosConverter::fromMessage(message, messageMap); bool success; - GridMap inputMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(6, 6), success); + GridMap inputMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(4, 4), success); Position3 position; inputMap.getPosition3("elevation", Index(0,0), position); std::cout << inputMap.getPosition() << std::endl; @@ -104,22 +106,47 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { jsk_recognition_msgs::PolygonArray ros_polygon_hole_contours; switch (plane_extractor_selector_) { case kRansacExtractor : { + auto start = std::chrono::system_clock::now(); extractor.setRansacParameters(ransac_parameters_); extractor.runRansacPlaneExtractor(); + auto end = std::chrono::system_clock::now(); + auto duration = std::chrono::duration_cast(end - start); + std::ofstream output_file; + output_file.open("/home/andrej/Desktop/computation_times_ransac_12.txt", std::ofstream::app);; + output_file << duration.count() << "\n"; + output_file.close(); extractor.augmentMapWithRansacPlanes(); break; } case kSlidingWindowExtractor : { extractor.setSlidingWindowParameters(sliding_window_parameters_); + auto start = std::chrono::system_clock::now(); extractor.runSlidingWindowPlaneExtractor(); - extractor.augmentMapWithSlidingWindowPlanes(); + auto intermediate = std::chrono::system_clock::now(); + auto duration_intermediate = std::chrono::duration_cast(intermediate - start); + std::ofstream intermediate_runtime_file; + intermediate_runtime_file.open("/home/andrej/Desktop/computation_times_SWE_plane_detect.txt", std::ofstream::app); + intermediate_runtime_file << duration_intermediate.count() << "\n"; + intermediate_runtime_file.close(); +// extractor.augmentMapWithSlidingWindowPlanes(); extractor.generatePlanes(); + auto end = std::chrono::system_clock::now(); + auto duration = std::chrono::duration_cast(end - start); + std::ofstream total_runtime_file; + total_runtime_file.open("/home/andrej/Desktop/computation_times_SWE_full_pipeline.txt", std::ofstream::app); + total_runtime_file << duration.count() << "\n"; + total_runtime_file.close(); extractor.visualizeConvexDecomposition(&ros_polygon_array); extractor.visualizePlaneContours(&ros_polygon_outer_contours, &ros_polygon_hole_contours); break; } } - + auto end_total = std::chrono::system_clock::now(); + auto duration_total = std::chrono::duration_cast(end_total - start_total); + std::ofstream total_file; + total_file.open("/home/andrej/Desktop/computation_times_total.txt", std::ofstream::app); + total_file << duration_total.count() << "\n"; + total_file.close(); grid_map_msgs::GridMap outputMessage; GridMapRosConverter::toMessage(inputMap, outputMessage); grid_map_publisher_.publish(outputMessage); diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 97c33bca..1c02ede8 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -7,15 +7,15 @@ namespace convex_plane_extraction { CHECK(polygon.is_simple()); LOG(INFO) << "Started convex decomposition..."; size_t old_list_size = output_polygon_list->size(); -// CGAL::optimal_convex_partition_2(polygon.vertices_begin(), -// polygon.vertices_end(), -// std::back_inserter(*output_polygon_list)); -// -// assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), -// polygon.vertices_end(), -// polygon_list.begin(), -// polygon_list.end())); - *output_polygon_list = decomposeInnerApproximation(polygon); + CGAL::optimal_convex_partition_2(polygon.vertices_begin(), + polygon.vertices_end(), + std::back_inserter(*output_polygon_list)); + + assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), + polygon.vertices_end(), + polygon_list.begin(), + polygon_list.end())); +// *output_polygon_list = decomposeInnerApproximation(polygon); CHECK_GT(output_polygon_list->size(), old_list_size); LOG(INFO) << "done."; } diff --git a/convex_plane_decomposition/src/ransac_plane_extractor.cpp b/convex_plane_decomposition/src/ransac_plane_extractor.cpp index c52beb7f..c37a5eb9 100644 --- a/convex_plane_decomposition/src/ransac_plane_extractor.cpp +++ b/convex_plane_decomposition/src/ransac_plane_extractor.cpp @@ -74,10 +74,14 @@ void RansacPlaneExtractor::ransacPlaneVisualization(){ Point_3D& point = points_with_normal_.getPoint(*plane_points_it); Eigen::Array2i map_indices; map_.getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); - ransac_map_(map_indices(0), map_indices(1)) = plane_label_iterator; + ransac_map_(map_indices(0), map_indices(1)) = 1;//plane_label_iterator; } ++plane_label_iterator; } + std::ofstream output_file; + output_file.open("/home/andrej/Desktop/number_of_planes_ransac_12.txt", std::ofstream::app);; + output_file << plane_label_iterator << "\n"; + output_file.close(); map_.add("ransac_planes", ransac_map_); std::cout << "Added ransac plane layer!" << std::endl; } diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index a33292ee..8c6ebd2e 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -84,13 +84,31 @@ namespace sliding_window_plane_extractor{ data_points.col(0) = Eigen::Map(&row_position.front(), row_position.size()) * resolution_; data_points.col(1) = Eigen::Map(&col_position.front(), col_position.size()) * resolution_; data_points.col(2) = Eigen::Map(&height_instances.front(), height_instances.size()); - Eigen::BDCSVD svd = data_points.bdcSvd(Eigen::ComputeFullU | Eigen::ComputeFullV); - if(svd.rank() < 3){ - LOG(WARNING) << "Rank loss, cell will be ignored!"; - continue; + const Eigen::Matrix3d covarianceMatrix(data_points.transpose() * data_points); + Vector3 eigenvalues = Vector3::Ones(); + Eigen::Matrix3d eigenvectors = Eigen::Matrix3d::Identity(); + const Eigen::SelfAdjointEigenSolver solver(covarianceMatrix); + eigenvalues = solver.eigenvalues().real(); + eigenvectors = solver.eigenvectors().real(); + //Eigen::BDCSVD svd = data_points.bdcSvd(Eigen::ComputeFullU | Eigen::ComputeFullV); +// if(svd.rank() < 3){ +// LOG(WARNING) << "Rank loss, cell will be ignored!"; +// continue; +// } +// Eigen::Matrix3d V = svd.matrixV(); +// Eigen::Vector3d n = (V.col(0)).cross(V.col(1)); + int smallestId(0); + double smallestValue(std::numeric_limits::max()); + for (int j = 0; j < eigenvectors.cols(); j++) { + if (eigenvalues(j) < smallestValue) { + smallestId = j; + smallestValue = eigenvalues(j); + } } - Eigen::Matrix3d V = svd.matrixV(); - Eigen::Vector3d n = (V.col(0)).cross(V.col(1)); + Vector3 eigenvector = eigenvectors.col(smallestId); + const Eigen::Vector3d normalVectorPositiveAxis_(0,0,1); + if (eigenvector.dot(normalVectorPositiveAxis_) < 0.0) eigenvector = -eigenvector; + Eigen::Vector3d n = eigenvector; Index index = *window_iterator; double mean_error = ((data_points * n).cwiseAbs()).sum() / height_instances.size(); Eigen::Vector3d upwards(0,0,1); @@ -117,7 +135,14 @@ namespace sliding_window_plane_extractor{ } void SlidingWindowPlaneExtractor::generatePlanes(){ + std::ofstream polygonizer_file; + polygonizer_file.open("/home/andrej/Desktop/polygonizer_time.txt", std::ofstream::app); + std::ofstream decomposer_file; + decomposer_file.open("/home/andrej/Desktop/decomposer_time.txt", std::ofstream::app); + std::chrono::milliseconds time_stamp = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()); for (int label_it = 1; label_it <= number_of_extracted_planes_; ++label_it) { + auto polygonizer_start = std::chrono::system_clock::now(); convex_plane_extraction::Plane plane; std::vector> contours; std::vector hierarchy; @@ -162,11 +187,18 @@ namespace sliding_window_plane_extractor{ if(plane.hasOuterContour()) { //LOG(WARNING) << "Dropping plane, no outer contour detected!"; computePlaneFrameFromLabeledImage(binary_image, &plane); + auto polygonizer_end = std::chrono::system_clock::now(); + auto polygonizer_duration = std::chrono::duration_cast(polygonizer_end - polygonizer_start); + polygonizer_file << time_stamp.count() << ", " << polygonizer_duration.count() << "\n"; if(plane.isValid()) { LOG(INFO) << "Starting resolving holes..."; plane.resolveHoles(); LOG(INFO) << "done."; + auto decomposer_start = std::chrono::system_clock::now(); CHECK(plane.decomposePlaneInConvexPolygons()); + auto decomposer_end = std::chrono::system_clock::now(); + auto decomposer_duration = std::chrono::duration_cast(decomposer_end - decomposer_start); + decomposer_file << time_stamp.count() << ", " << decomposer_duration.count() << "\n"; planes_.push_back(plane); } else { LOG(WARNING) << "Dropping plane, normal vector could not be inferred!"; From 43dff316f7293cdbc0f42857ef3639e44b0daf1c Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Sun, 1 Mar 2020 22:02:06 +0100 Subject: [PATCH 017/504] Started refactoring. --- convex_plane_decomposition/CMakeLists.txt | 4 +- .../include/convex_plane_extraction_ros.hpp | 2 +- convex_plane_decomposition/include/plane.hpp | 22 +- .../include/plane_extractor.hpp | 2 +- .../include/plane_factory.hpp | 35 +++ .../include/polygon.hpp | 11 +- .../include/polygonizer.hpp | 42 +++ .../include/ransac_plane_extractor.hpp | 74 +++--- .../sliding_window_plane_extractor.hpp | 47 ++-- convex_plane_decomposition/src/plane.cpp | 22 +- .../src/plane_extractor.cpp | 2 +- .../src/plane_factory.cpp | 97 +++++++ convex_plane_decomposition/src/polygon.cpp | 14 +- .../src/polygonizer.cpp | 249 ++++++++++++++++++ .../src/ransac_plane_extractor.cpp | 55 +--- .../src/sliding_window_plane_extractor.cpp | 229 +++++++++++----- 16 files changed, 706 insertions(+), 201 deletions(-) create mode 100644 convex_plane_decomposition/include/plane_factory.hpp create mode 100644 convex_plane_decomposition/include/polygonizer.hpp create mode 100644 convex_plane_decomposition/src/plane_factory.cpp create mode 100644 convex_plane_decomposition/src/polygonizer.cpp diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index c0d32a3b..4c4069d4 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -164,7 +164,9 @@ add_executable(${PROJECT_NAME}_node src/polygon.cpp src/ros_visualizations.cpp src/geometry_utils.cpp - src/export_utils.cpp) + src/export_utils.cpp + src/plane_factory.cpp + src/polygonizer.cpp) ## Rename C++ executable without prefix ## The above recommended prefix causes long target names, the following renames the diff --git a/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp b/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp index 6f1de627..a0d49bcf 100644 --- a/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp +++ b/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp @@ -71,7 +71,7 @@ class ConvexPlaneExtractionROS ros::Publisher hole_contours_publsiher_; //! Ransac plane extractor parameters. - ransac_plane_extractor::RansacParameters ransac_parameters_; + ransac_plane_extractor::RansacPlaneExtractorParameters ransac_parameters_; PlaneExtractorType plane_extractor_selector_; diff --git a/convex_plane_decomposition/include/plane.hpp b/convex_plane_decomposition/include/plane.hpp index bc57ebf2..fa558500 100644 --- a/convex_plane_decomposition/include/plane.hpp +++ b/convex_plane_decomposition/include/plane.hpp @@ -8,13 +8,23 @@ namespace convex_plane_extraction { + struct PlaneParameters{ + + PlaneParameters(Eigen::Vector3d normal_vector, Eigen::Vector3d support_vector) + : support_vector(support_vector), + normal_vector(normal_vector){}; + + Eigen::Vector3d support_vector; + Eigen::Vector3d normal_vector; + }; + class Plane { public: Plane(); - Plane(CgalPolygon2d& outer_polygon, CgalPolygon2dListContainer& hole_polygon_list); + Plane(CgalPolygon2d& outer_polygon, CgalPolygon2dContainer& holes); virtual ~Plane(); @@ -32,9 +42,9 @@ namespace convex_plane_extraction { CgalPolygon2dVertexConstIterator outerPolygonVertexEnd() const; - CgalPolygon2dListConstIterator holePolygonBegin() const; + CgalPolygon2dContainerConstIterator holePolygonBegin() const; - CgalPolygon2dListConstIterator holePolygonEnd() const; + CgalPolygon2dContainerConstIterator holePolygonEnd() const; bool isValid() const; @@ -50,7 +60,7 @@ namespace convex_plane_extraction { void resolveHoles(); - const CgalPolygon2dListContainer& getConvexPolygons() const; + const CgalPolygon2dContainer& getConvexPolygons() const; private: @@ -61,8 +71,8 @@ namespace convex_plane_extraction { bool initialized_; CgalPolygon2d outer_polygon_; - CgalPolygon2dListContainer hole_polygon_list_; - CgalPolygon2dListContainer convex_polygon_list_; + CgalPolygon2dContainer hole_polygon_list_; + CgalPolygon2dContainer convex_polygon_list_; Vector3d normal_vector_; Vector3d support_vector_; diff --git a/convex_plane_decomposition/include/plane_extractor.hpp b/convex_plane_decomposition/include/plane_extractor.hpp index 4434f111..ec2059f7 100644 --- a/convex_plane_decomposition/include/plane_extractor.hpp +++ b/convex_plane_decomposition/include/plane_extractor.hpp @@ -41,7 +41,7 @@ namespace convex_plane_extraction { grid_map::GridMap& getMap(); // Ransac plane extractor related functions. - void setRansacParameters(const ransac_plane_extractor::RansacParameters& parameters); + void setRansacParameters(const ransac_plane_extractor::RansacPlaneExtractorParameters& parameters); void runRansacPlaneExtractor(); diff --git a/convex_plane_decomposition/include/plane_factory.hpp b/convex_plane_decomposition/include/plane_factory.hpp new file mode 100644 index 00000000..d6deff89 --- /dev/null +++ b/convex_plane_decomposition/include/plane_factory.hpp @@ -0,0 +1,35 @@ +#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_FACTORY_HPP_ +#define CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_FACTORY_HPP_ + +#include + +#include "plane.hpp" + +namespace convex_plane_extraction { + +class PlaneFactory { + public: + + PlaneFactory(grid_map::GridMap& map) + :map_(map){ + computeMapTransformation(); + }; + + void computeMapTransformation(); + + void createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, + const std::map& parameters); + + private: + + // Grid map related members. + grid_map::GridMap& map_; + Eigen::Matrix2d transformation_xy_to_world_frame_; + Eigen::Vector2d map_offset_; + + + std::vector planes_; + +}; +} // namespace convex_plane_extraction +#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_FACTORY_HPP_ diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index b4062d5a..409a3151 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -33,8 +33,8 @@ namespace convex_plane_extraction{ typedef Traits::Vector_2 CgalVector2d; typedef Traits::Polygon_2 CgalPolygon2d; typedef Traits::Segment_2 CgalSegment2d; - typedef std::list CgalPolygon2dListContainer; - typedef CgalPolygon2dListContainer::const_iterator CgalPolygon2dListConstIterator; + typedef std::vector CgalPolygon2dContainer; + typedef CgalPolygon2dContainer::const_iterator CgalPolygon2dConstIterator; typedef CGAL::Polygon_set_2> CgalPolygon2dSetContainer; typedef CgalPolygon2d::Vertex_const_iterator CgalPolygon2dVertexConstIterator; typedef CgalPolygon2d::Vertex_iterator CgalPolygon2dVertexIterator; @@ -43,6 +43,11 @@ namespace convex_plane_extraction{ typedef std::vector Polygon3dVectorContainer; typedef K::Intersect_2 Intersect_2; + struct PolygonWithHoles{ + CgalPolygon2d outer_contour; + CgalPolygon2dContainer holes; + }; + template bool isContourSimple_impl(Iter begin, Iter end, std::bidirectional_iterator_tag){ @@ -76,7 +81,7 @@ namespace convex_plane_extraction{ typename std::iterator_traits::iterator_category()); }; - void performConvexDecomposition(const CgalPolygon2d& polygon, CgalPolygon2dListContainer* output_polyong_list); + void performConvexDecomposition(const CgalPolygon2d& polygon, CgalPolygon2dContainer* output_polyong_list); bool doPolygonAndSegmentIntersect(const CgalPolygon2d& polygon, const CgalSegment2d& segment, bool print_flag); diff --git a/convex_plane_decomposition/include/polygonizer.hpp b/convex_plane_decomposition/include/polygonizer.hpp new file mode 100644 index 00000000..19090feb --- /dev/null +++ b/convex_plane_decomposition/include/polygonizer.hpp @@ -0,0 +1,42 @@ +#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGONIZER_HPP_ +#define CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGONIZER_HPP_ + +#include + +#include +#include +#include + +#include "plane.hpp" +#include "polygon.hpp" + +namespace convex_plane_extraction { + +struct PolygonizerParameters{ + double resolution = 0.02; + int upsampling_factor = 3; + bool activate_long_edge_upsampling = false; + bool activate_contour_approximation = false; + double hole_area_threshold_squared_meters = 2e-3; +}; + +class Polygonizer { + public: + + Polygonizer(const PolygonizerParameters parameters = PolygonizerParameters()) + :parameters_(parameters){}; + + PolygonWithHoles extractPolygonsFromBinaryImage(const cv::Mat& binary_image) const; + + CgalPolygon2d resolveHoles(PolygonWithHoles& polygon_with_holes) const; + + private: + + PolygonizerParameters parameters_; + +}; + + +} // namespace convex_plane_extraction + +#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGONIZER_HPP_ diff --git a/convex_plane_decomposition/include/ransac_plane_extractor.hpp b/convex_plane_decomposition/include/ransac_plane_extractor.hpp index 047d46b4..ed41149e 100644 --- a/convex_plane_decomposition/include/ransac_plane_extractor.hpp +++ b/convex_plane_decomposition/include/ransac_plane_extractor.hpp @@ -19,66 +19,60 @@ #include "CGAL/Shape_detection/Efficient_RANSAC.h" #include "Eigen/Core" #include "Eigen/Dense" +#include #include "grid_map_ros/grid_map_ros.hpp" -#include "point_with_normal_container.hpp" - - - - namespace ransac_plane_extractor { - using namespace point_with_normal_container; - // Type declarations. - typedef CGAL::First_of_pair_property_map PointMap; - typedef CGAL::Second_of_pair_property_map NormalMap; - typedef CGAL::Shape_detection::Efficient_RANSAC_traits - Traits; - typedef CGAL::Shape_detection::Efficient_RANSAC EfficientRansac; - typedef CGAL::Shape_detection::Plane Plane; - - - struct RansacParameters{ - double probability; - double min_points; - double epsilon; - double cluster_epsilon; - double normal_threshold; + // Point with normal related type declarations. + using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; + using Point3D = Kernel::Point_3; + using Vector3D = Kernel::Vector_3; + using PointWithNormal = std::pair; + using PwnVector = std::vector; + + // RANSAC plane extractor related type declarations. + using PointMap = CGAL::First_of_pair_property_map; + using NormalMap = CGAL::Second_of_pair_property_map; + using Traits = CGAL::Shape_detection::Efficient_RANSAC_traits + ; + using EfficientRansac = CGAL::Shape_detection::Efficient_RANSAC; + using Plane = CGAL::Shape_detection::Plane; + + struct RansacPlaneExtractorParameters{ + // Set probability to miss the largest primitive at each iteration. + double probability = 0.01; + // Detect shapes with at least 200 points. + double min_points = 200; + // Set maximum Euclidean distance between a point and a shape. + double epsilon = 0.004; + // Set maximum Euclidean distance between points to be clustered. + double cluster_epsilon = 0.0282842712475; + // Set maximum normal deviation. 0.98 < dot(surface_normal, point_normal); + double normal_threshold = 0.98; }; class RansacPlaneExtractor { public: - /*! - * Constructor. - */ - explicit RansacPlaneExtractor(grid_map::GridMap &map, double resolution, const std::string &normals_layer_prefix, - const std::string &layer_height); - - /*! - * Destructor. - */ - virtual ~RansacPlaneExtractor(); + RansacPlaneExtractor(std::vector& points_with_normal, const RansacPlaneExtractorParameters& parameters); - void setParameters(const RansacParameters& parameters); + void setParameters(const RansacPlaneExtractorParameters& parameters); void runDetection(); - void ransacPlaneVisualization(); + const auto& getDetectedPlanes() const{ + return ransac_.shapes(); + }; - private: - - grid_map::GridMap& map_; - double resolution_; +// void ransacPlaneVisualization(); - PointWithNormalContainer points_with_normal_; + private: EfficientRansac ransac_; EfficientRansac::Parameters parameters_; - Eigen::MatrixXf ransac_map_; - }; } diff --git a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp index 0cc76ea0..d7de989d 100644 --- a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp +++ b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp @@ -16,29 +16,34 @@ #include "plane.hpp" #include "polygon.hpp" +#include "ransac_plane_extractor.hpp" #include "ros_visualizations.hpp" namespace sliding_window_plane_extractor { - struct SlidingWindowParameters{ - int kernel_size; - double plane_error_threshold; + + struct SlidingWindowPlaneExtractorParameters{ + int kernel_size = 3; + double plane_patch_error_threshold = 0.004; + double surface_normal_angle_threshold; + bool include_curvature_detection; + bool include_ransac_refinement; + double global_plane_fit_error_threshold = 0.01; }; + class SlidingWindowPlaneExtractor{ public: SlidingWindowPlaneExtractor(grid_map::GridMap &map, double resolution, const std::string& layer_height, - const std::string& normal_layer_prefix, SlidingWindowParameters& parameters); - - SlidingWindowPlaneExtractor(grid_map::GridMap &map, double resolution, const std::string& normal_layer_prefix, - const std::string& layer_height); + const std::string& normal_layer_prefix, const SlidingWindowPlaneExtractorParameters& parameters = SlidingWindowPlaneExtractorParameters(), + const ransac_plane_extractor::RansacPlaneExtractorParameters& ransac_parameters = ransac_plane_extractor::RansacPlaneExtractorParameters()); - virtual ~SlidingWindowPlaneExtractor(); - - void setParameters(const SlidingWindowParameters& parameters); + void setParameters(const SlidingWindowPlaneExtractorParameters& parameters); void runDetection(); + void runSurfaceNormalCurvatureDetection(); + void slidingWindowPlaneVisualization(); void generatePlanes(); @@ -47,6 +52,16 @@ namespace sliding_window_plane_extractor { void computePlaneFrameFromLabeledImage(const cv::Mat& binary_image, convex_plane_extraction::Plane* plane); + void extractPlaneParametersFromLabeledImage(); + + void computePlaneParametersForLabel(int label); + + double computeAverageErrorToPlane(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector, + const std::vector& points_with_normal) const; + const auto& runRansacRefinement(std::vector& points_with_normal) const; + + void runSegmentation() + void visualizeConvexDecomposition(jsk_recognition_msgs::PolygonArray* ros_polygon_array); void visualizePlaneContours(jsk_recognition_msgs::PolygonArray* outer_polygons, jsk_recognition_msgs::PolygonArray* hole_poylgons) const; @@ -60,15 +75,13 @@ namespace sliding_window_plane_extractor { std::string normal_layer_prefix_; double resolution_; - Eigen::Matrix2d transformation_xy_to_world_frame_; - Eigen::Vector2d map_offset_; - - int kernel_size_; - double plane_error_threshold_; + SlidingWindowPlaneExtractorParameters parameters_; + ransac_plane_extractor::RansacPlaneExtractorParameters ransac_parameters_; + cv::Mat binary_image_patch_; + cv::Mat binary_image_angle_; cv::Mat labeled_image_; int number_of_extracted_planes_; - - convex_plane_extraction::PlaneListContainer planes_; + std::map plane_parameters_; }; } diff --git a/convex_plane_decomposition/src/plane.cpp b/convex_plane_decomposition/src/plane.cpp index e164c3d5..13459666 100644 --- a/convex_plane_decomposition/src/plane.cpp +++ b/convex_plane_decomposition/src/plane.cpp @@ -5,9 +5,9 @@ namespace convex_plane_extraction{ Plane::Plane() : initialized_(false){} - Plane::Plane(CgalPolygon2d& outer_polygon, CgalPolygon2dListContainer& hole_polygon_list) + Plane::Plane(CgalPolygon2d& outer_polygon, CgalPolygon2dContainer& holes) : outer_polygon_(outer_polygon), - hole_polygon_list_(hole_polygon_list), + hole_polygon_list_(holes), initialized_(false){}; Plane::~Plane() = default; @@ -160,12 +160,12 @@ namespace convex_plane_extraction{ return outer_polygon_.vertices_end(); } - CgalPolygon2dListConstIterator Plane::holePolygonBegin() const{ + CgalPolygon2dConstIterator Plane::holePolygonBegin() const{ CHECK(isValid()); return hole_polygon_list_.begin(); } - CgalPolygon2dListConstIterator Plane::holePolygonEnd() const{ + CgalPolygon2dConstIterator Plane::holePolygonEnd() const{ CHECK(isValid()); return hole_polygon_list_.end(); } @@ -412,19 +412,7 @@ namespace convex_plane_extraction{ } } - void Plane::slConcavityHoleVertexSorting(const CgalPolygon2d& hole, std::multimap>* concavity_positions){ - CHECK_NOTNULL(concavity_positions); - for (auto vertex_it = hole.vertices_begin(); vertex_it != hole.vertices_end(); ++vertex_it){ - std::multimap outer_polygon_vertices; - getVertexPositionsInAscendingDistanceToPoint(outer_polygon_, *vertex_it, &outer_polygon_vertices); - for (const auto& outer_distance_vertex_pair : outer_polygon_vertices) { - concavity_positions->insert(std::pair>(outer_distance_vertex_pair.first, - std::pair(std::distance(hole.vertices_begin(), vertex_it),outer_distance_vertex_pair.second))); - } - } - } - - const CgalPolygon2dListContainer& Plane::getConvexPolygons() const { + const CgalPolygon2dContainer& Plane::getConvexPolygons() const { return convex_polygon_list_; } diff --git a/convex_plane_decomposition/src/plane_extractor.cpp b/convex_plane_decomposition/src/plane_extractor.cpp index 7e5e2bcc..a885fcba 100644 --- a/convex_plane_decomposition/src/plane_extractor.cpp +++ b/convex_plane_decomposition/src/plane_extractor.cpp @@ -25,7 +25,7 @@ using namespace grid_map; return map_; } - void PlaneExtractor::setRansacParameters(const ransac_plane_extractor::RansacParameters& parameters){ + void PlaneExtractor::setRansacParameters(const ransac_plane_extractor::RansacPlaneExtractorParameters& parameters){ ransac_plane_extractor_.setParameters(parameters); ROS_INFO("RANSAC parameters set!"); } diff --git a/convex_plane_decomposition/src/plane_factory.cpp b/convex_plane_decomposition/src/plane_factory.cpp new file mode 100644 index 00000000..9eb4b184 --- /dev/null +++ b/convex_plane_decomposition/src/plane_factory.cpp @@ -0,0 +1,97 @@ +// +// Created by andrej on 3/1/20. +// + +#include "plane_factory.hpp" + +using namespace convex_plane_extraction; + +void PlaneFactory::computeMapTransformation(){ + Eigen::Vector2i map_size = map_.getSize(); + CHECK(map_.getPosition(Eigen::Vector2i::Zero(), map_offset_)); + Eigen::Vector2d lower_left_cell_position; + CHECK(map_.getPosition(Eigen::Vector2i(map_size.x() - 1, 0), lower_left_cell_position)); + Eigen::Vector2d upper_right_cell_position; + CHECK(map_.getPosition(Eigen::Vector2i(0, map_size.y() - 1), upper_right_cell_position)); + transformation_xy_to_world_frame_.col(0) = (lower_left_cell_position - map_offset_).normalized(); + transformation_xy_to_world_frame_.col(1) = (upper_right_cell_position - map_offset_).normalized(); +} + +void createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, const int number_of_labels, + const std::map& parameters){ + CHECK_GT(number_of_labels, 0); + CHECK_EQ(number_of_labels, parameters.size()); + for (int label = 1; label < number_of_labels; ++label){ + cv::Mat binary_image(labeled_image.size(), CV_8UC1); + binary_image = labeled_image == label; + extractPolygonsFromBinaryImage(binary_image) + } +} + + + + +for (int label_it = 1; label_it <= number_of_extracted_planes_; ++label_it) { +auto polygonizer_start = std::chrono::system_clock::now(); +convex_plane_extraction::Plane plane; +std::vector> contours; +std::vector hierarchy; +cv::Mat binary_image(labeled_image_.size(), CV_8UC1); +binary_image = labeled_image_ == label_it; +constexpr int kUpSamplingFactor = 3; +cv::Mat binary_image_upsampled; +cv::resize(binary_image, binary_image_upsampled, cv::Size(kUpSamplingFactor*binary_image.size().height, kUpSamplingFactor*binary_image.size().width)); +findContours(binary_image_upsampled, contours, hierarchy, + CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); +std::list> approx_contours; +int hierachy_it = 0; +for (auto& contour : contours) { +++hierachy_it; +std::vector approx_contour; +if (contour.size() <= 10){ +approx_contour = contour; +} else { +cv::approxPolyDP(contour, approx_contour, 9, true); +} +if (approx_contour.size() <= 2) { +LOG_IF(WARNING, hierarchy[hierachy_it-1][3] < 0 && contour.size() > 4) << "Removing parental polygon since too few vertices!"; +continue; +} +convex_plane_extraction::CgalPolygon2d polygon = convex_plane_extraction::createCgalPolygonFromOpenCvPoints(approx_contour.begin(), approx_contour.end(), resolution_ / kUpSamplingFactor); + +if(!polygon.is_simple()) { +convex_plane_extraction::Vector2i index; +index << (*polygon.begin()).x(), (*polygon.begin()).y(); +LOG(WARNING) << "Polygon starting at " << index << " is not simple, will be ignored!"; +continue; +} +constexpr int kParentFlagIndex = 3; +if (hierarchy[hierachy_it-1][kParentFlagIndex] < 0) { +//convex_plane_extraction::upSampleLongEdges(&polygon); +// convex_plane_extraction::approximateContour(&polygon); +CHECK(plane.addOuterPolygon(polygon)); +} else { +CHECK(plane.addHolePolygon(polygon)); +} +} +if(plane.hasOuterContour()) { +//LOG(WARNING) << "Dropping plane, no outer contour detected!"; +computePlaneFrameFromLabeledImage(binary_image, &plane); +auto polygonizer_end = std::chrono::system_clock::now(); +auto polygonizer_duration = std::chrono::duration_cast(polygonizer_end - polygonizer_start); +polygonizer_file << time_stamp.count() << ", " << polygonizer_duration.count() << "\n"; +if(plane.isValid()) { +LOG(INFO) << "Starting resolving holes..."; +plane.resolveHoles(); +LOG(INFO) << "done."; +auto decomposer_start = std::chrono::system_clock::now(); +CHECK(plane.decomposePlaneInConvexPolygons()); +auto decomposer_end = std::chrono::system_clock::now(); +auto decomposer_duration = std::chrono::duration_cast(decomposer_end - decomposer_start); +decomposer_file << time_stamp.count() << ", " << decomposer_duration.count() << "\n"; +planes_.push_back(plane); +} else { +LOG(WARNING) << "Dropping plane, normal vector could not be inferred!"; +} +} +} diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 1c02ede8..6d1dbd5d 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -2,7 +2,7 @@ namespace convex_plane_extraction { - void performConvexDecomposition(const CgalPolygon2d& polygon, CgalPolygon2dListContainer* output_polygon_list){ + void performConvexDecomposition(const CgalPolygon2d& polygon, CgalPolygon2dContainer* output_polygon_list){ CHECK_GE(polygon.size(), 3); CHECK(polygon.is_simple()); LOG(INFO) << "Started convex decomposition..."; @@ -457,4 +457,16 @@ namespace convex_plane_extraction { } } + void slConcavityHoleVertexSorting(const CgalPolygon2d& hole, std::multimap>* concavity_positions){ + CHECK_NOTNULL(concavity_positions); + for (auto vertex_it = hole.vertices_begin(); vertex_it != hole.vertices_end(); ++vertex_it){ + std::multimap outer_polygon_vertices; + getVertexPositionsInAscendingDistanceToPoint(outer_polygon_, *vertex_it, &outer_polygon_vertices); + for (const auto& outer_distance_vertex_pair : outer_polygon_vertices) { + concavity_positions->insert(std::pair>(outer_distance_vertex_pair.first, + std::pair(std::distance(hole.vertices_begin(), vertex_it),outer_distance_vertex_pair.second))); + } + } + } + } diff --git a/convex_plane_decomposition/src/polygonizer.cpp b/convex_plane_decomposition/src/polygonizer.cpp new file mode 100644 index 00000000..04a83bb1 --- /dev/null +++ b/convex_plane_decomposition/src/polygonizer.cpp @@ -0,0 +1,249 @@ +#include "polygonizer.hpp" + +using namespace convex_plane_extraction; + +PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& binary_image) const{ + PolygonWithHoles plane_polygons; + std::vector> contours; + std::vector hierarchy; + cv::Mat binary_image_upsampled; + cv::resize(binary_image, + binary_image_upsampled, + cv::Size(parameters_.upsampling_factor * binary_image.size().height, + parameters_.upsampling_factor * binary_image.size().width)); + findContours(binary_image_upsampled, contours, hierarchy, + CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); + std::vector> approx_contours; + int hierachy_it = 0; + for (auto &contour : contours) { + ++hierachy_it; + std::vector approx_contour; + if (contour.size() <= 10) { + approx_contour = contour; + } else { + cv::approxPolyDP(contour, approx_contour, 9, true); + } + if (approx_contour.size() <= 2) { + LOG_IF(WARNING, hierarchy[hierachy_it - 1][3] < 0 && contour.size() > 3) + << "Removing parental polygon since too few vertices!"; + continue; + } + CgalPolygon2d polygon = convex_plane_extraction::createCgalPolygonFromOpenCvPoints( + approx_contour.begin(), + approx_contour.end(), + parameters_.resolution / parameters_.upsampling_factor); + + if (!polygon.is_simple()) { + convex_plane_extraction::Vector2i index; + index << (*polygon.begin()).x(), (*polygon.begin()).y(); + LOG(WARNING) << "Polygon starting at " << index << " is not simple, will be ignored!"; + continue; + } + constexpr int kParentFlagIndex = 3; + if (hierarchy[hierachy_it - 1][kParentFlagIndex] < 0) { + if (parameters_.activate_long_edge_upsampling) { + upSampleLongEdges(&polygon); + } + if (parameters_.activate_contour_approximation) { + approximateContour(&polygon); + } + plane_polygons.outer_contour = polygon; + } else { + plane_polygons.holes.push_back(polygon); + } + } + return plane_polygons; +} + +CgalPolygon2d Polygonizer::resolveHoles(PolygonWithHoles& polygon_with_holes) const{ + CgalPolygon2dContainer& holes = polygon_with_holes.holes; + if (holes.empty()) { + return polygon_with_holes.outer_contour; + } + auto hole_it = holes.begin(); + while(!holes.empty()) { + if (hole_it == holes.end()){ + hole_it = holes.begin(); + } + // Compute distance to outer contour for each hole. + std::vector distance_to_outer_polygon; + std::vector outer_contour_connection_vertex_positions; // closest outer contour vertex for each hole + std::vector hole_connection_vertex_positions; + if (hole_it->size() < 3) { + ++hole_it; + holes.erase(std::prev(hole_it)); + } else if (abs(hole_it->area()) < parameters_.hole_area_threshold_squared_meters) { + ++hole_it; + holes.erase(std::prev(hole_it)); + } else { + std::cout << "List size: " << holes.size() << std::endl; + std::cout << "Outer: " << std::endl; + printPolygon(polygon_with_holes.outer_contour); + std::cout << "Hole: " << std::endl; + printPolygon(*holes.begin()); + std::multimap> connection_candidates; + slConcavityHoleVertexSorting(*hole_it, &connection_candidates); + CHECK(connection_candidates.size() == hole_it->size()*outer_polygon_.size()); + // Instead of extracting only the 2 SL-concavity points, sort vertices according to SL-concavity measure. + // Then iterate over sorted vertices until a connection to the outer contour is not intersecting the polyogn. + // Implement function that checks for intersections with existing polygon contour. + int hole_connection_vertex_position; + int outer_polygon_connection_vertex_position; + bool valid_connection = true; + int i = 0; + for (const auto& position : connection_candidates){ + auto hole_vertex_it = hole_it->vertices_begin(); + std::advance(hole_vertex_it, position.second.first); + bool print_flag = false; + if (position.second.first == 7){ + print_flag = true; + } + CgalPoint2d hole_vertex = *hole_vertex_it; + // Get outer contour connection vertices sorted according to distance to hole vertex. + auto outer_vertex_it = outer_polygon_.vertices_begin(); + std::advance(outer_vertex_it, position.second.second); + CgalVector2d direction = *outer_vertex_it - hole_vertex; + direction = (1.0/direction.squared_length()) * direction; + CgalSegment2d connection(hole_vertex + 0.0001 * direction, *outer_vertex_it - 0.0001 * direction); + if (!doPolygonAndSegmentIntersect(outer_polygon_, connection, print_flag)){ + valid_connection = true; + for (auto hole_iterator = hole_polygon_list_.begin(); hole_iterator != hole_polygon_list_.end(); ++hole_iterator){ + if (hole_iterator->size() < 3){ + continue; + } + if (doPolygonAndSegmentIntersect(*hole_iterator, connection, print_flag)) { + valid_connection = false; + //std::cout << "Hole and connection intersect!" << std::endl; + ++i; + break; + } + } + } else { + //std::cout << "Outer contour and connection intersect!" << std::endl; + ++i; + valid_connection = false; + } + if (valid_connection){ + hole_connection_vertex_position = position.second.first; + outer_polygon_connection_vertex_position = position.second.second; + break; + } + } + if (!valid_connection){ + CHECK_EQ(i, hole_it->size()*outer_polygon_.size()); + LOG(WARNING) << "No valid connection found! " << i << " iterations."; + ++hole_it; + continue; + } + CHECK(valid_connection); + // Perform the integration of the hole into the outer contour. + auto outer_contour_connection_vertex = outer_polygon_.vertices_begin(); + std::advance(outer_contour_connection_vertex, outer_polygon_connection_vertex_position); + auto hole_contour_connection_vertex = hole_it->vertices_begin(); + std::advance(hole_contour_connection_vertex, hole_connection_vertex_position); + CgalPolygon2d new_polygon; + // Start filling new polygon with outer contour. + for (auto vertex_it = outer_polygon_.vertices_begin(); vertex_it != outer_contour_connection_vertex; ++vertex_it){ + new_polygon.push_back(*vertex_it); + } + new_polygon.push_back(*outer_contour_connection_vertex); + auto hole_vertex_it = hole_contour_connection_vertex; + do { + new_polygon.push_back(*hole_vertex_it); + if (hole_vertex_it != std::prev(hole_it->vertices_end())){ + hole_vertex_it = std::next(hole_vertex_it); + } else { + hole_vertex_it = hole_it->vertices_begin(); + } + } while(hole_vertex_it != hole_contour_connection_vertex); + // Create new vertices next to connection points to avoid same enter and return path. + CgalSegment2d enter_connection(*outer_contour_connection_vertex, *hole_contour_connection_vertex); + Eigen::Vector2d normal_vector; + getSegmentNormalVector(enter_connection, &normal_vector); + // Check for possible intersections. + Eigen::Vector2d line_start_point(hole_contour_connection_vertex->x(), hole_contour_connection_vertex->y()); + Eigen::Vector2d direction_vector(outer_contour_connection_vertex->x() - hole_contour_connection_vertex->x(), + outer_contour_connection_vertex->y() - hole_contour_connection_vertex->y()); + auto next_vertex = std::next(outer_contour_connection_vertex); + if (next_vertex == outer_polygon_.vertices_end()){ + next_vertex = outer_polygon_.begin(); + } + Eigen::Vector2d test_point(next_vertex->x(), next_vertex->y()); + constexpr double kPointOffset = 0.0001; + Eigen::Vector2d outer_point(outer_contour_connection_vertex->x(), outer_contour_connection_vertex->y()); + if (isPointOnLeftSide(line_start_point, direction_vector, test_point)){ + Eigen::Vector2d translation_vector(next_vertex->x() - outer_contour_connection_vertex->x(), + next_vertex->y() - outer_contour_connection_vertex->y()); + translation_vector.normalize(); + outer_point += kPointOffset * translation_vector.normalized(); + } else { + outer_point += kPointOffset * normal_vector.normalized(); + } + next_vertex = hole_contour_connection_vertex; + if (next_vertex == hole_it->vertices_begin()){ + next_vertex = hole_it->vertices_end(); + next_vertex = std::prev(next_vertex); + } else { + next_vertex = std::prev(next_vertex); + } + Eigen::Vector2d hole_point(hole_contour_connection_vertex->x(), hole_contour_connection_vertex->y()); + test_point << next_vertex->x(), next_vertex->y(); + constexpr double kPiHalf = 3.1416 / 2; + if (isPointOnLeftSide(line_start_point, direction_vector, test_point) + && computeAngleBetweenVectors(test_point - line_start_point, direction_vector) < kPiHalf){ + Eigen::Vector2d translation_vector(next_vertex->x() - hole_contour_connection_vertex->x(), + next_vertex->y() - hole_contour_connection_vertex->y()); + translation_vector.normalize(); + hole_point += kPointOffset * translation_vector; + } else { + hole_point += kPointOffset * normal_vector; + } + Vector2d new_edge_direction = outer_point - hole_point; + new_edge_direction.normalize(); + constexpr double kShiftFactor = 0.0001; + bool intersection_caused = false; + CgalSegment2d new_edge(CgalPoint2d(hole_point.x() + kShiftFactor * new_edge_direction.x(), + hole_point.y() + kShiftFactor * new_edge_direction.y()),CgalPoint2d(outer_point.x() - + kShiftFactor * new_edge_direction.x(), outer_point.y() - kShiftFactor * new_edge_direction.y())); + if (!doPolygonAndSegmentIntersect(outer_polygon_, new_edge, false)){ + for (auto hole_iterator = hole_polygon_list_.begin(); hole_iterator != hole_polygon_list_.end(); ++hole_iterator){ + if (hole_iterator->size() < 3){ + continue; + } + if (doPolygonAndSegmentIntersect(*hole_iterator, new_edge, false)) { + intersection_caused = true; + break; + } + } + } else { + //std::cout << "Outer contour and connection intersect!" << std::endl; + intersection_caused = true; + } + if (intersection_caused){ + ++hole_it; + continue; + } + // Add new vertices to outer contour. + new_polygon.push_back(CgalPoint2d(hole_point.x(), hole_point.y())); + new_polygon.push_back(CgalPoint2d(outer_point.x(), outer_point.y())); + // Add remaining outer contour vertices to new polygon. + auto vertex_it = outer_contour_connection_vertex; + vertex_it = std::next(vertex_it); + for (; vertex_it != outer_polygon_.vertices_end(); ++vertex_it){ + new_polygon.push_back(*vertex_it); + } + if (!new_polygon.is_simple()){ + std::cout << "Hole orientation: " << hole_it->orientation() << std::endl; + std::cout <<"Hole vertex: " << *hole_contour_connection_vertex << std::endl; + std::cout <<"Outer vertex: " << *outer_contour_connection_vertex << std::endl; + printPolygon(new_polygon); + } + CHECK(new_polygon.is_simple()); + outer_polygon_ = new_polygon; + ++hole_it; + hole_polygon_list_.erase(std::prev(hole_it)); + } + } + //approximateContour(&outer_polygon_); + CHECK(outer_polygon_.is_simple()); +} \ No newline at end of file diff --git a/convex_plane_decomposition/src/ransac_plane_extractor.cpp b/convex_plane_decomposition/src/ransac_plane_extractor.cpp index c37a5eb9..302f85b6 100644 --- a/convex_plane_decomposition/src/ransac_plane_extractor.cpp +++ b/convex_plane_decomposition/src/ransac_plane_extractor.cpp @@ -1,66 +1,27 @@ -// -// Created by andrej on 11/21/19. -// - #include "ransac_plane_extractor.hpp" using namespace ransac_plane_extractor; -RansacPlaneExtractor::RansacPlaneExtractor(grid_map::GridMap &map, double resolution, const std::string &normals_layer_prefix, - const std::string &layer_height) - : map_(map){ - int map_rows = (map.getSize())(0); - int map_cols = (map.getSize())(1); - double resolution_ = resolution; - ransac_map_ = Eigen::MatrixXf::Zero(map_rows, map_cols); - for (grid_map::GridMapIterator iterator(map_); - !iterator.isPastEnd(); ++iterator) { - grid_map::Position3 position3; - Eigen::Vector3d point; - Eigen::Vector3d normal; - map.getPosition3(layer_height, *iterator, point); - map.getVector(normals_layer_prefix, *iterator, normal); - points_with_normal_.addPointNormalPair(point, normal); - } - ransac_.set_input(points_with_normal_.getReference()); +RansacPlaneExtractor::RansacPlaneExtractor(std::vector& points_with_normal, const RansacPlaneExtractorParameters& parameters){ + ransac_.set_input(points_with_normal); ransac_.add_shape_factory(); - // Set parameters for shape detection. - // Set probability to miss the largest primitive at each iteration. - parameters_.probability = 0.01; - - // Detect shapes with at least 500 points. - parameters_.min_points = 200; - // Set maximum Euclidean distance between a point and a shape. - parameters_.epsilon = 0.004; - - // Set maximum Euclidean distance between points to be clustered. - parameters_.cluster_epsilon = 0.0282842712475 ; - - // Set maximum normal deviation. - // 0.9 < dot(surface_normal, point_normal); - parameters_.normal_threshold = 0.98; + parameters_.probability = parameters.probability; + parameters_.min_points = parameters.min_points; + parameters_.epsilon = parameters.epsilon; + parameters_.cluster_epsilon = parameters.cluster_epsilon; + parameters_.normal_threshold = parameters.normal_threshold; } -RansacPlaneExtractor::~RansacPlaneExtractor(){} - void RansacPlaneExtractor::runDetection(){ // Detect shapes. ransac_.detect(parameters_); } -void RansacPlaneExtractor::setParameters(const RansacParameters& parameters){ - // Set probability to miss the largest primitive at each iteration. +void RansacPlaneExtractor::setParameters(const RansacPlaneExtractorParameters& parameters){ parameters_.probability = parameters.probability; - // Detect shapes with at least min_points number of points. parameters_.min_points = parameters.min_points; - // Set maximum Euclidean distance between a point and a shape. parameters_.epsilon = parameters.epsilon; - - // Set maximum Euclidean distance between points to be clustered. parameters_.cluster_epsilon = parameters.cluster_epsilon; - - // Set maximum normal deviation. - // Example: 0.9 < dot(surface_normal, point_normal). parameters_.normal_threshold = parameters.normal_threshold; } diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index 8c6ebd2e..41f3b3a1 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -6,65 +6,46 @@ namespace sliding_window_plane_extractor{ using namespace grid_map; SlidingWindowPlaneExtractor::SlidingWindowPlaneExtractor(grid_map::GridMap &map, double resolution, - const std::string& layer_height, const std::string& normal_layer_prefix, SlidingWindowParameters& parameters) + const std::string& layer_height, const std::string& normal_layer_prefix, + const SlidingWindowPlaneExtractorParameters& parameters, + const ransac_plane_extractor::RansacPlaneExtractorParameters& ransac_parameters) : map_(map), resolution_(resolution), elevation_layer_(layer_height), normal_layer_prefix_(normal_layer_prefix), - kernel_size_(parameters.kernel_size), - plane_error_threshold_(parameters.plane_error_threshold){ - number_of_extracted_planes_ = 0; + parameters_(parameters), + ransac_parameters_(ransac_parameters){ + number_of_extracted_planes_ = -1; + const grid_map::Size map_size = map.getSize(); + binary_image_patch_ = cv::Mat(map_size(0), map_size(1), CV_8U, false); + binary_image_angle_ = cv::Mat(map_size(0), map_size(1), CV_8U, false); computeMapTransformation(); } - SlidingWindowPlaneExtractor::SlidingWindowPlaneExtractor(grid_map::GridMap &map, double resolution, - const std::string& normal_layer_prefix, const std::string& layer_height) - : map_(map), - resolution_(resolution), - elevation_layer_(layer_height), - normal_layer_prefix_(normal_layer_prefix){ - kernel_size_ = 5; - plane_error_threshold_ = 0.004; - number_of_extracted_planes_ = 0; - computeMapTransformation(); - } - - - SlidingWindowPlaneExtractor::~SlidingWindowPlaneExtractor() = default; - - void SlidingWindowPlaneExtractor::computeMapTransformation(){ - Eigen::Vector2i map_size = map_.getSize(); - CHECK(map_.getPosition(Eigen::Vector2i::Zero(), map_offset_)); - Eigen::Vector2d lower_left_cell_position; - CHECK(map_.getPosition(Eigen::Vector2i(map_size.x() - 1, 0), lower_left_cell_position)); - Eigen::Vector2d upper_right_cell_position; - CHECK(map_.getPosition(Eigen::Vector2i(0, map_size.y() - 1), upper_right_cell_position)); - transformation_xy_to_world_frame_.col(0) = (lower_left_cell_position - map_offset_).normalized(); - transformation_xy_to_world_frame_.col(1) = (upper_right_cell_position - map_offset_).normalized(); - } - void SlidingWindowPlaneExtractor::runDetection(){ - std::cout << "Starting detection!" << std::endl; - Eigen::Matrix binary_map = - Eigen::Matrix::Zero(map_.getSize().x(), map_.getSize().y()); - CHECK(map_.getSize().x() >= kernel_size_); - CHECK(map_.getSize().y() >= kernel_size_); + VLOG(1) << "Starting detection!"; + const grid_map::Size map_size = map_.getSize(); + Eigen::Matrix normal_x(map_size(0), map_size(1)); + Eigen::Matrix normal_y(map_size(0), map_size(1)); + Eigen::Matrix normal_z(map_size(0), map_size(1)); + CHECK(map_.getSize().x() >= parameters_.kernel_size); + CHECK(map_.getSize().y() >= parameters_.kernel_size); SlidingWindowIterator window_iterator(map_, elevation_layer_, SlidingWindowIterator::EdgeHandling::INSIDE, - kernel_size_); + parameters_.kernel_size); for (; !window_iterator.isPastEnd(); ++window_iterator) { Eigen::MatrixXf window_data = window_iterator.getData(); int instance_iterator = 0; std::vector height_instances; std::vector row_position; std::vector col_position; - for (int kernel_col = 0; kernel_col < kernel_size_; ++kernel_col) { - for (int kernel_row = 0; kernel_row < kernel_size_; ++kernel_row) { + for (int kernel_col = 0; kernel_col < parameters_.kernel_size; ++kernel_col) { + for (int kernel_row = 0; kernel_row < parameters_.kernel_size; ++kernel_row) { if (!isfinite(window_data(kernel_row, kernel_col))) { continue; } height_instances.push_back(window_data(kernel_row, kernel_col)); - row_position.push_back(kernel_row - static_cast(kernel_size_ / 2)); - col_position.push_back(kernel_col - static_cast(kernel_size_ / 2)); + row_position.push_back(kernel_row - static_cast(parameters_.kernel_size / 2)); + col_position.push_back(kernel_col - static_cast(parameters_.kernel_size / 2)); } } constexpr int kMinNumberOfDataPoints = 9; @@ -90,13 +71,6 @@ namespace sliding_window_plane_extractor{ const Eigen::SelfAdjointEigenSolver solver(covarianceMatrix); eigenvalues = solver.eigenvalues().real(); eigenvectors = solver.eigenvectors().real(); - //Eigen::BDCSVD svd = data_points.bdcSvd(Eigen::ComputeFullU | Eigen::ComputeFullV); -// if(svd.rank() < 3){ -// LOG(WARNING) << "Rank loss, cell will be ignored!"; -// continue; -// } -// Eigen::Matrix3d V = svd.matrixV(); -// Eigen::Vector3d n = (V.col(0)).cross(V.col(1)); int smallestId(0); double smallestValue(std::numeric_limits::max()); for (int j = 0; j < eigenvectors.cols(); j++) { @@ -108,23 +82,74 @@ namespace sliding_window_plane_extractor{ Vector3 eigenvector = eigenvectors.col(smallestId); const Eigen::Vector3d normalVectorPositiveAxis_(0,0,1); if (eigenvector.dot(normalVectorPositiveAxis_) < 0.0) eigenvector = -eigenvector; - Eigen::Vector3d n = eigenvector; + Eigen::Vector3d n = eigenvector.normalized(); Index index = *window_iterator; double mean_error = ((data_points * n).cwiseAbs()).sum() / height_instances.size(); Eigen::Vector3d upwards(0,0,1); constexpr double kInclinationThreshold = 0.35; - if (mean_error < plane_error_threshold_ && abs(n.transpose()*upwards) > kInclinationThreshold) { - binary_map((*window_iterator).x(), (*window_iterator).y()) = true; + if (mean_error < parameters_.plane_patch_error_threshold && abs(n.transpose()*upwards) > kInclinationThreshold) { + binary_image_patch_.at((*window_iterator).x(), (*window_iterator).y()) = true; + normal_x(index.x(), index.y()) = n.x(); + normal_y(index.x(), index.y()) = n.y(); + normal_z(index.x(), index.y()) = n.z(); } } - cv::Mat binary_image(binary_map.rows(), binary_map.cols(), CV_8U, binary_map.data()); - cv::eigen2cv(binary_map, binary_image); - number_of_extracted_planes_ = cv::connectedComponents(binary_image, labeled_image_, 8, CV_32SC1); + map_.add("normals_x", normal_x); + map_.add("normals_y", normal_y); + map_.add("normals_z", normal_z); } - void SlidingWindowPlaneExtractor::setParameters(const SlidingWindowParameters& parameters){ - kernel_size_ = parameters.kernel_size; - plane_error_threshold_ = parameters.plane_error_threshold; + void SlidingWindowPlaneExtractor::runSurfaceNormalCurvatureDetection(){ + VLOG(1) << "Starting surface normal edge detection!"; + CHECK(map_.exists("normals_x")); + CHECK(map_.exists("normals_y")); + CHECK(map_.exists("normals_z")); + const int surface_normal_map_boundary_offset = parameters_.kernel_size / 2; + CHECK_GT(surface_normal_map_boundary_offset, 0); + const grid_map::Size map_rows_cols = map_.getSize(); + for( int cols = surface_normal_map_boundary_offset; cols < map_rows_cols(1) - surface_normal_map_boundary_offset - 1; ++cols){ + for (int rows = surface_normal_map_boundary_offset; rows < map_rows_cols(0) - surface_normal_map_boundary_offset - 1; ++rows){ + const Eigen::Vector2f normal_vector_center(map_.at("normals_x", Index(rows, cols)), map_.at("normals_y", Index(rows, cols)), + map_.at("normals_z", Index(rows, cols))); + const Eigen::Vector2f normal_vector_next_row(map_.at("normals_x", Index(rows+1, cols)), map_.at("normals_y", Index(rows+1, cols)), + map_.at("normals_z", Index(rows+1, cols))); + const Eigen::Vector2f normal_vector_next_col(map_.at("normals_x", Index(rows, cols+1)), map_.at("normals_y", Index(rows, cols+1)), + map_.at("normals_z", Index(rows, cols+1))); + const float angle_in_col_direction_radians = std::atan2(1.0, normal_vector_center.dot(normal_vector_next_col)); + const float angle_in_row_direction_radians = std::atan2(1.0, normal_vector_center.dot(normal_vector_next_row)); + const double gradient_magnitude_normalized = sqrt((angle_in_col_direction_radians*angle_in_col_direction_radians) + + (angle_in_row_direction_radians * angle_in_row_direction_radians)) / (sqrt(2.0)*M_PI); + binary_image_angle_.at(rows, cols) = gradient_magnitude_normalized <= parameters_.surface_normal_angle_threshold; + } + } + } + + // Label cells according to which cell they belong to using connected component labeling. + void SlidingWindowPlaneExtractor::runSegmentation() { + CHECK_EQ(binary_image_patch_.type(), CV_8U); + const grid_map::Size map_size = map_.getSize(); + CHECK_EQ(binary_image_patch_.rows, map_size(0)); + CHECK_EQ(binary_image_patch_.cols, map_size(1)); + if (parameters_.include_curvature_detection){ + CHECK_EQ(binary_image_patch_.type(), binary_image_angle_.type()); + CHECK_EQ(binary_image_patch_.size, binary_image_angle_.size); + number_of_extracted_planes_ = cv::connectedComponents(binary_image_patch_ & binary_image_angle_, labeled_image_, 8, CV_32SC1); + } else { + number_of_extracted_planes_ = cv::connectedComponents(binary_image_patch_, labeled_image_, 8, CV_32SC1); + } + } + + // Refine connected component using RANSAC. Input vector is modified by function! + const auto& SlidingWindowPlaneExtractor::runRansacRefinement(std::vector& points_with_normal) const { + CHECK(!points_with_normal.empty()); + ransac_plane_extractor::RansacPlaneExtractor ransac_plane_extractor(points_with_normal, ransac_parameters_); + ransac_plane_extractor.runDetection(); + return ransac_plane_extractor.getDetectedPlanes(); + } + + void SlidingWindowPlaneExtractor::setParameters(const SlidingWindowPlaneExtractorParameters& parameters){ + parameters_.kernel_size = parameters.kernel_size; + parameters_.plane_patch_error_threshold = parameters.plane_patch_error_threshold; } void SlidingWindowPlaneExtractor::slidingWindowPlaneVisualization(){ @@ -134,13 +159,18 @@ namespace sliding_window_plane_extractor{ std::cout << "Added ransac plane layer!" << std::endl; } + void SlidingWindowPlaneExtractor::extractPlaneParametersFromLabeledImage(){ + if (number_of_extracted_planes_ < 1){ + LOG(WARNING) << "No planes detected by Sliding Window Plane Extractor!"; + return; + } + const int number_of_extracted_planes_without_refinement = number_of_extracted_planes_; + for (int label = 1; label <= number_of_extracted_planes_without_refinement; ++label) { + computePlaneParametersForLabel(label); + } + } + void SlidingWindowPlaneExtractor::generatePlanes(){ - std::ofstream polygonizer_file; - polygonizer_file.open("/home/andrej/Desktop/polygonizer_time.txt", std::ofstream::app); - std::ofstream decomposer_file; - decomposer_file.open("/home/andrej/Desktop/decomposer_time.txt", std::ofstream::app); - std::chrono::milliseconds time_stamp = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()); for (int label_it = 1; label_it <= number_of_extracted_planes_; ++label_it) { auto polygonizer_start = std::chrono::system_clock::now(); convex_plane_extraction::Plane plane; @@ -207,11 +237,16 @@ namespace sliding_window_plane_extractor{ } } - void SlidingWindowPlaneExtractor::computePlaneFrameFromLabeledImage(const cv::Mat& binary_image, - convex_plane_extraction::Plane* plane){ - CHECK_NOTNULL(plane); + void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label){ + CHECK(map_.exists(elevation_layer_)); + CHECK(map_.exists("normals_x")); + CHECK(map_.exists("normals_y")); + CHECK(map_.exists("normals_z")); Eigen::Vector3d normal_vector = Eigen::Vector3d::Zero(); Eigen::Vector3d support_vector = Eigen::Vector3d::Zero(); + std::vector points_with_normal; + cv::Mat binary_image(labeled_image_.size(), CV_8UC1); + binary_image = labeled_image_ == label; int number_of_normal_instances = 0; int number_of_position_instances = 0; for (int row = 0; row < binary_image.rows; ++row){ @@ -229,15 +264,77 @@ namespace sliding_window_plane_extractor{ support_vector += support_vector_temp; ++number_of_position_instances; } + ransac_plane_extractor::PointWithNormal point_with_normal = std::make_pair(ransac_plane_extractor::Point3D(support_vector_temp.x(), support_vector_temp.y(), support_vector_temp.z()), + ransac_plane_extractor::Vector3D(normal_vector_temp.x(), normal_vector_temp.y(), normal_vector_temp.z())); + points_with_normal.push_back(point_with_normal); } } } if (number_of_normal_instances == 0 || number_of_position_instances == 0){ + LOG(WARNING) << "Label empty, NO plane parameters are created!"; return; } normal_vector = normal_vector / static_cast(number_of_normal_instances); support_vector = support_vector / static_cast(number_of_position_instances); - CHECK(plane->setNormalAndSupportVector(normal_vector, support_vector)); + bool refinement_performed = false; + if (parameters_.include_ransac_refinement) { + // Compute error to fitted plane. + if (computeAverageErrorToPlane(normal_vector, support_vector, points_with_normal) + > parameters_.global_plane_fit_error_threshold){ + const auto& planes = runRansacRefinement(points_with_normal); + CHECK(!planes.empty()) << "No planes detected by RANSAC in as planar classified region."; + int label_counter = 0; + for (const auto& plane : planes){ + const std::vector& plane_point_indices = (*plane.get()).indices_of_assigned_points(); + CHECK(!plane_point_indices.empty()); + Eigen::Vector3d support_vector; + Eigen::Vector3d normal_vector; + for (const auto index : plane_point_indices) { + const auto &point = points_with_normal.at(index).first; + const auto &normal = points_with_normal.at(index).second; + support_vector += Eigen::Vector3d(point.x(), point.y(), point.z()); + normal_vector += Eigen::Vector3d(normal.x(), normal.y(), normal.z()); + Eigen::Array2i map_indices; + map_.getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); + if (label_counter == 0){ + labeled_image_.at(map_indices(0), map_indices(1)) = label; + } else { + labeled_image_.at(map_indices(0), map_indices(1)) = number_of_extracted_planes_ + label_counter; + } + } + support_vector /= static_cast(plane_point_indices.size()); + normal_vector /= static_cast(plane_point_indices.size()); + const convex_plane_extraction::PlaneParameters temp_plane_parameters(normal_vector, support_vector); + if (label_counter == 0) { + plane_parameters_.emplace(label, temp_plane_parameters); + } else { + plane_parameters_.emplace(number_of_extracted_planes_ + label_counter, temp_plane_parameters); + } + ++label_counter; + } + CHECK_EQ(label_counter + 1, planes.size()); + number_of_extracted_planes_ += label_counter; + refinement_performed = true; + } + } + if (refinement_performed){ + const convex_plane_extraction::PlaneParameters temp_plane_parameters(normal_vector, support_vector); + plane_parameters_.emplace(label, temp_plane_parameters); + } + } + + double SlidingWindowPlaneExtractor::computeAverageErrorToPlane(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector, + const std::vector& points_with_normal) const { + CHECK(!points_with_normal.empty()); + double average_error = 0.0; + for (const auto& point_with_normal : points_with_normal){ + Eigen::Vector3d p_S_P(point_with_normal.first.x() - support_vector.x(), point_with_normal.first.y() - support_vector.y(), + point_with_normal.first.z() - support_vector.z()); + average_error += abs(normal_vector.dot(p_S_P)); + } + average_error /= static_cast(points_with_normal.size()); + return average_error; } void SlidingWindowPlaneExtractor::visualizeConvexDecomposition(jsk_recognition_msgs::PolygonArray* ros_polygon_array){ From 97f16fb7065c8b8c50d31c00ae71f7f23608c744 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Mon, 2 Mar 2020 10:08:47 +0100 Subject: [PATCH 018/504] Clean-up. --- convex_plane_decomposition/include/polygon.hpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index 409a3151..6305a8b6 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -104,20 +104,24 @@ namespace convex_plane_extraction{ void detectDentLocations(std::map* dent_locations, const CgalPolygon2d& polygon); + void connectSecondPolygonToFirst(CgalPolygon2d& left_polygon, CgalPolygon2d& right_polygon); + + std::pair getIndicesOfClosestVertexPair(CgalPolygon2d& left_polygon, CgalPolygon2d& right_polygon); + struct Intersection{ void setEdgeSourceLocation(const int location){ - this->edge_source_location_ = location; + edge_source_location_ = location; } void setEdgeTargetLocation(const int location){ - this->edge_target_location_ = location; + edge_target_location_ = location; } void setIntersectionPoint(const CgalPoint2d& intersection_point){ - this->intersection_point_ = intersection_point; + intersection_point_ = intersection_point; } void setAllMembers(const int source_location, const int target_location, const CgalPoint2d& intersection_point){ - this->edge_source_location_ = source_location; - this->edge_target_location_ = target_location; - this->intersection_point_ = intersection_point; + edge_source_location_ = source_location; + edge_target_location_ = target_location; + intersection_point_ = intersection_point; } int edge_source_location_; From b03e75e3ee2ea790dda29f86e66d38c2ddba7e4b Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Tue, 3 Mar 2020 21:11:42 +0100 Subject: [PATCH 019/504] Refactoring continued. --- convex_plane_decomposition/CMakeLists.txt | 2 +- .../include/convex_decomposer.hpp | 38 ++ .../include/pipeline.hpp | 43 ++ convex_plane_decomposition/include/plane.hpp | 58 ++- .../include/plane_factory.hpp | 26 +- .../include/polygon.hpp | 15 +- .../include/polygonizer.hpp | 17 +- .../sliding_window_plane_extractor.hpp | 53 ++- .../src/convex_decomposer.cpp | 189 ++++++++ convex_plane_decomposition/src/pipeline.cpp | 40 ++ convex_plane_decomposition/src/plane.cpp | 310 +------------ .../src/plane_extractor.cpp | 2 +- .../src/plane_factory.cpp | 89 +--- convex_plane_decomposition/src/polygon.cpp | 94 ++-- .../src/polygonizer.cpp | 433 ++++++++++-------- .../src/sliding_window_plane_extractor.cpp | 133 ++---- 16 files changed, 783 insertions(+), 759 deletions(-) create mode 100644 convex_plane_decomposition/include/convex_decomposer.hpp create mode 100644 convex_plane_decomposition/include/pipeline.hpp create mode 100644 convex_plane_decomposition/src/convex_decomposer.cpp create mode 100644 convex_plane_decomposition/src/pipeline.cpp diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 4c4069d4..014b21c5 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -166,7 +166,7 @@ add_executable(${PROJECT_NAME}_node src/geometry_utils.cpp src/export_utils.cpp src/plane_factory.cpp - src/polygonizer.cpp) + src/polygonizer.cpp src/convex_decomposer.cpp include/convex_decomposer.hpp src/pipeline.cpp include/pipeline.hpp) ## Rename C++ executable without prefix ## The above recommended prefix causes long target names, the following renames the diff --git a/convex_plane_decomposition/include/convex_decomposer.hpp b/convex_plane_decomposition/include/convex_decomposer.hpp new file mode 100644 index 00000000..f3b5f52a --- /dev/null +++ b/convex_plane_decomposition/include/convex_decomposer.hpp @@ -0,0 +1,38 @@ +#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_CONVEX_DECOMPOSER_HPP_ +#define CONVEX_PLANE_EXTRACTION_INCLUDE_CONVEX_DECOMPOSER_HPP_ + +#include "polygon.hpp" + +namespace convex_plane_extraction { + +enum class ConvexDecompositionType{ + kGreeneOptimalDecomposition = 1, + kInnerConvexApproximation = 2 +}; + +struct ConvexDecomposerParameters{ + ConvexDecompositionType decomposition_type = ConvexDecompositionType::kGreeneOptimalDecomposition; + double dent_angle_threshold_rad = 0.001; // 0.05 deg in rad. +}; + +class ConvexDecomposer { + public: + + explicit ConvexDecomposer(const ConvexDecomposerParameters& parameters); + + CgalPolygon2dContainer performConvexDecomposition(const CgalPolygon2d& polygon) const; + + CgalPolygon2dContainer performOptimalConvexDecomposition(const CgalPolygon2d& polygon) const; + + CgalPolygon2dContainer performInnerConvexApproximation(const CgalPolygon2d& polygon) const; + + std::multimap detectDentLocations(const CgalPolygon2d& polygon) const; + + private: + + ConvexDecomposerParameters parameters_; +}; + +} // namespace convex_plane_extraction + +#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_CONVEX_DECOMPOSER_HPP_ diff --git a/convex_plane_decomposition/include/pipeline.hpp b/convex_plane_decomposition/include/pipeline.hpp new file mode 100644 index 00000000..8a4edaae --- /dev/null +++ b/convex_plane_decomposition/include/pipeline.hpp @@ -0,0 +1,43 @@ +#ifndef CONVEX_PLANE_EXTRACTION__PIPELINE_HPP_ +#define CONVEX_PLANE_EXTRACTION__PIPELINE_HPP_ + +#include "convex_decomposer.hpp" +#include "plane_factory.hpp" +#include "sliding_window_plane_extractor.hpp" + +namespace convex_plane_extraction { + +struct PipelineParameters{ + sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters sliding_window_plane_extractor_parameters = + sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters(); + PlaneFactoryParameters plane_factory_parameters_ = PlaneFactoryParameters(); + ConvexDecomposerParameters convex_decomposer_parameters = ConvexDecomposerParameters(); +}; + +struct GridMapParameters{ + grid_map::GridMap& map; + double resolution; + std::string& layer_height; + std::string& normal_layer_prefix; +}; + + +class Pipeline { + public: + + explicit Pipeline(const PipelineParameters& parameters) + : parameters_(parameters){}; + + void runPipeline(); + + + private: + + void exportConvexPolygons(const std::string& export_path) const; + + PipelineParameters pipeline_parameters_; + GridMapParameters grid_map_parameters_; + +}; +} // namespace_convex_plane_extraction +#endif //CONVEX_PLANE_EXTRACTION__PIPELINE_HPP_ diff --git a/convex_plane_decomposition/include/plane.hpp b/convex_plane_decomposition/include/plane.hpp index fa558500..80e08443 100644 --- a/convex_plane_decomposition/include/plane.hpp +++ b/convex_plane_decomposition/include/plane.hpp @@ -22,29 +22,34 @@ namespace convex_plane_extraction { public: - Plane(); + Plane(const CgalPolygon2d& plane_contour, const PlaneParameters parameters) + : plane_contour_(plane_contour), + normal_vector_(parameters.normal_vector), + support_vector_(parameters.support_vector){} - Plane(CgalPolygon2d& outer_polygon, CgalPolygon2dContainer& holes); + bool setPlaneContour(const CgalPolygon2d& plane_contour){ + plane_contour_ = plane_contour; + } - virtual ~Plane(); + const Eigen::Vector3d& getPlaneNormalVector() const{ + return normal_vector_; + } - bool addOuterPolygon(const CgalPolygon2d& outer_polygon); - - bool addHolePolygon(const CgalPolygon2d& hole_polygon); + Eigen::Vector3d& getPlaneNormalVectorMutable(){ + return normal_vector_; + } bool setNormalAndSupportVector(const Eigen::Vector3d& normal_vector,const Eigen::Vector3d& support_vector); - bool decomposePlaneInConvexPolygons(); - bool hasOuterContour() const; - CgalPolygon2dVertexConstIterator outerPolygonVertexBegin() const; - - CgalPolygon2dVertexConstIterator outerPolygonVertexEnd() const; - - CgalPolygon2dContainerConstIterator holePolygonBegin() const; + CgalPolygon2d& getOuterPolygonMutable(){ + return plane_contour_; + } - CgalPolygon2dContainerConstIterator holePolygonEnd() const; + const CgalPolygon2d& getOuterPolygon() const{ + return plane_contour_; + } bool isValid() const; @@ -58,9 +63,21 @@ namespace convex_plane_extraction { void computePoint3dWorldFrame(const Vector2d& input_point, Vector3d* output_point) const; - void resolveHoles(); + CgalPolygon2dContainer& getConvexPolygonsMutable(){ + return convex_polygons_; + } - const CgalPolygon2dContainer& getConvexPolygons() const; + const CgalPolygon2dContainer& getConvexPolygons() const{ + return convex_polygons_; + } + + void addConvexPolygon(const CgalPolygon2d& convex_polygon){ + convex_polygons_.push_back(convex_polygon); + } + + void setConvexPolygons(CgalPolygon2dContainer& convex_polygons){ + convex_polygons_ = convex_polygons; + } private: @@ -68,17 +85,12 @@ namespace convex_plane_extraction { void slConcavityHoleVertexSorting(const CgalPolygon2d& hole, std::multimap>* concavity_positions); - bool initialized_; - - CgalPolygon2d outer_polygon_; - CgalPolygon2dContainer hole_polygon_list_; - CgalPolygon2dContainer convex_polygon_list_; + CgalPolygon2d plane_contour_; + CgalPolygon2dContainer convex_polygons_; Vector3d normal_vector_; Vector3d support_vector_; }; - typedef std::list PlaneListContainer; - } #endif //CONVEX_PLANE_EXTRACTION_SRC_PLANE_HPP_ diff --git a/convex_plane_decomposition/include/plane_factory.hpp b/convex_plane_decomposition/include/plane_factory.hpp index d6deff89..5fbc2bbe 100644 --- a/convex_plane_decomposition/include/plane_factory.hpp +++ b/convex_plane_decomposition/include/plane_factory.hpp @@ -1,32 +1,46 @@ #ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_FACTORY_HPP_ #define CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_FACTORY_HPP_ +#include #include #include "plane.hpp" +#include "polygonizer.hpp" namespace convex_plane_extraction { +struct PlaneFactoryParameters{ + PolygonizerParameters polygonizer_parameters = PolygonizerParameters(); + double plane_inclination_threshold_degrees = 70; +}; + class PlaneFactory { public: - PlaneFactory(grid_map::GridMap& map) - :map_(map){ + PlaneFactory(grid_map::GridMap& map, const PlaneFactoryParameters& parameters) + :map_(map), + parameters_(parameters){ computeMapTransformation(); }; - void computeMapTransformation(); - - void createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, - const std::map& parameters); + void createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, const int number_of_labels, + const std::map& plane_parameters); private: + void computeMapTransformation(); + + bool isPlaneInclinationBelowThreshold(const Eigen::Vector3d& plane_normal_vector) const; + // Grid map related members. grid_map::GridMap& map_; Eigen::Matrix2d transformation_xy_to_world_frame_; Eigen::Vector2d map_offset_; + // Parameters. + + PlaneFactoryParameters parameters_; + std::vector planes_; diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index 6305a8b6..c8c57a0d 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -31,7 +31,8 @@ namespace convex_plane_extraction{ typedef CGAL::Partition_traits_2 Traits; typedef Traits::Point_2 CgalPoint2d; typedef Traits::Vector_2 CgalVector2d; - typedef Traits::Polygon_2 CgalPolygon2d; + typedef CGAL::Polygon_2 CgalPolygon2d; + typedef CGAL::Polygon_with_holes_2 CgalPolygonWithHoles2d; typedef Traits::Segment_2 CgalSegment2d; typedef std::vector CgalPolygon2dContainer; typedef CgalPolygon2dContainer::const_iterator CgalPolygon2dConstIterator; @@ -96,17 +97,25 @@ namespace convex_plane_extraction{ CgalPolygon2dVertexIterator next(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon); + CgalPolygon2dVertexIterator previous(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon); + void approximateContour(CgalPolygon2d* polygon); void upSampleLongEdges(CgalPolygon2d* polygon); double getEdgeLength(const CgalPolygon2dVertexIterator& source, const CgalPolygon2d& polygon); - void detectDentLocations(std::map* dent_locations, const CgalPolygon2d& polygon); + std::multimap detectDentLocations(const CgalPolygon2d& polygon); void connectSecondPolygonToFirst(CgalPolygon2d& left_polygon, CgalPolygon2d& right_polygon); - std::pair getIndicesOfClosestVertexPair(CgalPolygon2d& left_polygon, CgalPolygon2d& right_polygon); + std::pair getIndicesOfClosestVertexPair(CgalPolygon2d& first_polygon, CgalPolygon2d& second_polygon); + + std::multimap> getClosestVertexPairsOrdered(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon); + + CgalPoint2d getPolygonVertexAtIndex(const CgalPolygon2d& polygon, int index); + + bool doPointAndPolygonIntersect(const CgalPolygon2d& polygon, const CgalPoint2d& point, int& segment_source_vertex_index); struct Intersection{ void setEdgeSourceLocation(const int location){ diff --git a/convex_plane_decomposition/include/polygonizer.hpp b/convex_plane_decomposition/include/polygonizer.hpp index 19090feb..2947c67c 100644 --- a/convex_plane_decomposition/include/polygonizer.hpp +++ b/convex_plane_decomposition/include/polygonizer.hpp @@ -3,6 +3,10 @@ #include +#include +#include +#include +#include #include #include #include @@ -18,17 +22,26 @@ struct PolygonizerParameters{ bool activate_long_edge_upsampling = false; bool activate_contour_approximation = false; double hole_area_threshold_squared_meters = 2e-3; + double contour_approximation_deviation_threshold = 0.06; }; class Polygonizer { public: - Polygonizer(const PolygonizerParameters parameters = PolygonizerParameters()) + explicit Polygonizer(const PolygonizerParameters parameters = PolygonizerParameters()) :parameters_(parameters){}; PolygonWithHoles extractPolygonsFromBinaryImage(const cv::Mat& binary_image) const; - CgalPolygon2d resolveHoles(PolygonWithHoles& polygon_with_holes) const; + void removeAreasNotContainedInOuterContourFromHoles(const CgalPolygon2d& outer_polygon, std::vector& holes) const; + + CgalPolygon2d resolveHolesWithVerticalConnection(PolygonWithHoles& polygon_with_holes) const; + + void approximatePolygon(CgalPolygon2d& polygon) const; + + CgalPolygon2d runPolygonizationOnBinaryImage(const cv::Mat& binary_image) const; + + bool addHoleToOuterContourAtVertexIndex(int segment_target_vertex_index, const CgalPolygon2d& hole, CgalPolygon2d& outer_contour) const; private: diff --git a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp index d7de989d..b4619b77 100644 --- a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp +++ b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp @@ -25,50 +25,63 @@ namespace sliding_window_plane_extractor { struct SlidingWindowPlaneExtractorParameters{ int kernel_size = 3; double plane_patch_error_threshold = 0.004; - double surface_normal_angle_threshold; - bool include_curvature_detection; - bool include_ransac_refinement; + double surface_normal_angle_threshold_degrees = 1.0; + bool include_curvature_detection = false; + bool include_ransac_refinement = false; double global_plane_fit_error_threshold = 0.01; + + ransac_plane_extractor::RansacPlaneExtractorParameters ransac_parameters = ransac_plane_extractor::RansacPlaneExtractorParameters(); }; class SlidingWindowPlaneExtractor{ public: SlidingWindowPlaneExtractor(grid_map::GridMap &map, double resolution, const std::string& layer_height, - const std::string& normal_layer_prefix, const SlidingWindowPlaneExtractorParameters& parameters = SlidingWindowPlaneExtractorParameters(), - const ransac_plane_extractor::RansacPlaneExtractorParameters& ransac_parameters = ransac_plane_extractor::RansacPlaneExtractorParameters()); + const std::string& normal_layer_prefix, const SlidingWindowPlaneExtractorParameters& parameters = SlidingWindowPlaneExtractorParameters()); void setParameters(const SlidingWindowPlaneExtractorParameters& parameters); - void runDetection(); + void runExtraction(); - void runSurfaceNormalCurvatureDetection(); + const cv::Mat& getLabeledImage() const{ + return labeled_image_; + } - void slidingWindowPlaneVisualization(); + const auto& getLabelPlaneParameterMap() const{ + return label_plane_parameters_map_; + } - void generatePlanes(); + const int getNumberOfExtractedPlanes() const{ + return number_of_extracted_planes_; + } - void computeMapTransformation(); +// void slidingWindowPlaneVisualization(); - void computePlaneFrameFromLabeledImage(const cv::Mat& binary_image, convex_plane_extraction::Plane* plane); +// void computePlaneFrameFromLabeledImage(const cv::Mat& binary_image, convex_plane_extraction::Plane* plane); - void extractPlaneParametersFromLabeledImage(); +// void visualizeConvexDecomposition(jsk_recognition_msgs::PolygonArray* ros_polygon_array); +// +// void visualizePlaneContours(jsk_recognition_msgs::PolygonArray* outer_polygons, jsk_recognition_msgs::PolygonArray* hole_poylgons) const; +// +// void exportConvexPolygons(const std::string& path) const; - void computePlaneParametersForLabel(int label); + private: double computeAverageErrorToPlane(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector, const std::vector& points_with_normal) const; - const auto& runRansacRefinement(std::vector& points_with_normal) const; - void runSegmentation() + void computePlaneParametersForLabel(int label); - void visualizeConvexDecomposition(jsk_recognition_msgs::PolygonArray* ros_polygon_array); + void extractPlaneParametersFromLabeledImage(); - void visualizePlaneContours(jsk_recognition_msgs::PolygonArray* outer_polygons, jsk_recognition_msgs::PolygonArray* hole_poylgons) const; + const auto& runRansacRefinement(std::vector& points_with_normal) const; - void exportConvexPolygons(const std::string& path) const; + void runSegmentation(); + + void runSlidingWindowDetector(); + + void runSurfaceNormalCurvatureDetection(); - private: grid_map::GridMap& map_; std::string elevation_layer_; @@ -81,7 +94,7 @@ namespace sliding_window_plane_extractor { cv::Mat binary_image_angle_; cv::Mat labeled_image_; int number_of_extracted_planes_; - std::map plane_parameters_; + std::map label_plane_parameters_map_; }; } diff --git a/convex_plane_decomposition/src/convex_decomposer.cpp b/convex_plane_decomposition/src/convex_decomposer.cpp new file mode 100644 index 00000000..5f532ed9 --- /dev/null +++ b/convex_plane_decomposition/src/convex_decomposer.cpp @@ -0,0 +1,189 @@ +#include "convex_decomposer.hpp" + +using namespace convex_plane_extraction; + +ConvexDecomposer::ConvexDecomposer(const convex_plane_extraction::ConvexDecomposerParameters ¶meters) + :parameters_(parameters){} + +CgalPolygon2dContainer ConvexDecomposer::performConvexDecomposition(const CgalPolygon2d& polygon) const { + CHECK_GE(polygon.size(), 3); + CHECK(polygon.is_simple()); + VLOG(1) << "Started convex decomposition..."; + CgalPolygon2dContainer convex_polygons; + if(polygon.is_convex()){ + LOG(INFO) << "Polygon already convex, no decompostion performed."; + convex_polygons.push_back(polygon); + return convex_polygons; + } + switch (parameters_.decomposition_type){ + case ConvexDecompositionType::kGreeneOptimalDecomposition : + convex_polygons = performOptimalConvexDecomposition(polygon); + break; + case ConvexDecompositionType::kInnerConvexApproximation : + convex_polygons = performInnerConvexApproximation(polygon); + break; + } + VLOG(1) << "done."; + return convex_polygons; +} + +CgalPolygon2dContainer ConvexDecomposer::performOptimalConvexDecomposition(const CgalPolygon2d& polygon) const{ + CgalPolygon2dContainer output_polygons; + size_t old_container_size = output_polygons.size(); + CGAL::optimal_convex_partition_2(polygon.vertices_begin(), polygon.vertices_end(), + std::back_inserter(output_polygons)); + assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), polygon.vertices_end(), output_polygons.begin(), + output_polygons.end())); + CHECK_GT(output_polygons.size(), old_container_size); + return output_polygons; +} + +CgalPolygon2dContainer ConvexDecomposer::performInnerConvexApproximation(const CgalPolygon2d& polygon) const{ + CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); + CgalPolygon2dContainer convex_polygons; + const std::multimap dent_locations = detectDentLocations(polygon); + if (dent_locations.empty()){ + // No dents detected, polygon must be convex. + // CGAL convexity check might still fail, since very shallow dents are ignored. + convex_polygons.push_back(polygon); + return convex_polygons; + } + int dent_location = dent_locations.begin()->second; + bool intersection_clockwise_flag = false; + Intersection intersection_clockwise; + bool intersection_counterclockwise_flag = false; + Intersection intersection_counterclockwise; + intersection_clockwise_flag = intersectPolygonWithRay(dent_location, CGAL::COUNTERCLOCKWISE, + polygon, &intersection_counterclockwise); + intersection_counterclockwise_flag = intersectPolygonWithRay(dent_location, CGAL::CLOCKWISE, + polygon, &intersection_clockwise); + if (!intersection_clockwise_flag || !intersection_counterclockwise_flag ){ + LOG(FATAL) << "At least one intersection of dent ray with polygon failed!"; + } + // Generate resulting polygons from cut. + // Resulting cut from counter clockwise ray intersection. + CgalPolygon2d polygon_counterclockwise_1 = polygon; + CgalPolygon2d polygon_counterclockwise_2; + auto first_vertex_to_erase_it = polygon_counterclockwise_1.vertices_begin(); + std::advance(first_vertex_to_erase_it, dent_location); + // Add dent to second polygon. + polygon_counterclockwise_2.push_back(*first_vertex_to_erase_it); + first_vertex_to_erase_it = next(first_vertex_to_erase_it, polygon_counterclockwise_1); + auto last_vertex_to_erase_it = polygon_counterclockwise_1.vertices_begin(); + // Intersection somewhere must be at or after source vertex of intersection edge. + std::advance(last_vertex_to_erase_it, intersection_counterclockwise.edge_source_location_); + // Take next vertex due to exclusive upper limit logic. + last_vertex_to_erase_it = next(last_vertex_to_erase_it, polygon_counterclockwise_1); + // Copy vertices that will be deleted to second polygon. + copyVertices(polygon_counterclockwise_1,first_vertex_to_erase_it,last_vertex_to_erase_it, + &polygon_counterclockwise_2, polygon_counterclockwise_2.vertices_end()); + // Get last point that was erased. + CgalPoint2d point_before_intersection = *(previous(last_vertex_to_erase_it, polygon_counterclockwise_2)); + // To avoid numerical issues and duplicate vertices, intersection point is only inserted if sufficiently + // far away from exisiting vertex. + constexpr double kSquaredLengthThreshold = 1e-6; + if ((intersection_counterclockwise.intersection_point_ - point_before_intersection).squared_length() > kSquaredLengthThreshold) { + polygon_counterclockwise_2.push_back(intersection_counterclockwise.intersection_point_); + } + VLOG(1) << "Started splitting vertices..."; + CgalPolygon2dVertexIterator element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); + // Add intersection vertex to first polygon if existing vertex too far away. + if ((intersection_counterclockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { + polygon_counterclockwise_1.insert(element_behind_deleted_it, intersection_counterclockwise.intersection_point_); + } + // Resulting cut from clockwise ray intersection. + CgalPolygon2d polygon_clockwise_1 = polygon; + CgalPolygon2d polygon_clockwise_2; + + first_vertex_to_erase_it = polygon_clockwise_1.vertices_begin(); + std::advance(first_vertex_to_erase_it, intersection_clockwise.edge_target_location_); + if ((*first_vertex_to_erase_it - intersection_clockwise.intersection_point_).squared_length() > kSquaredLengthThreshold) { + polygon_clockwise_2.push_back(intersection_clockwise.intersection_point_); + } + last_vertex_to_erase_it = polygon_clockwise_1.vertices_begin(); + std::advance(last_vertex_to_erase_it, dent_location); + copyVertices(polygon_clockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_2, + polygon_clockwise_2.vertices_end()); + polygon_clockwise_2.push_back(*last_vertex_to_erase_it); + element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_1); + VLOG(1) << "done."; + if ((intersection_clockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { + polygon_clockwise_1.insert(element_behind_deleted_it, intersection_clockwise.intersection_point_); + } + printPolygon(polygon_counterclockwise_1); + printPolygon(polygon_counterclockwise_2); + printPolygon(polygon_clockwise_1); + printPolygon(polygon_clockwise_2); + VLOG(1) << "Started cut area computation..."; + // Take the cut with smallest min. area of resulting polygons. + double area[4] = {polygon_counterclockwise_1.area(), polygon_counterclockwise_2.area(), + polygon_clockwise_1.area(), polygon_clockwise_2.area()}; + VLOG(1) << "done."; + double* min_area_strategy = std::min_element(area, area+4); + CgalPolygon2dContainer recursion_1; + CgalPolygon2dContainer recursion_2; + if ((min_area_strategy - area) < 2){ + // In this case the counter clockwise intersection leads to less loss in area. + // Perform recursion with this split. + if(polygon_counterclockwise_1.orientation() != CGAL::COUNTERCLOCKWISE){ + LOG(WARNING) << "Polygon orientation wrong! Printing polygon ..."; + printPolygon(polygon_counterclockwise_1); + recursion_1 = std::vector(); + } else { + recursion_1 = performInnerConvexApproximation(polygon_counterclockwise_1); + } + if(polygon_counterclockwise_2.orientation() != CGAL::COUNTERCLOCKWISE){ + LOG(WARNING) << "Polygon orientation wrong! Printing polygon ..."; + printPolygon(polygon_counterclockwise_2); + recursion_2 = std::vector(); + } else{ + recursion_2 = performInnerConvexApproximation(polygon_counterclockwise_2); + } + } else { + // In this case the clockwise intersection leads to less loss in area. + if(polygon_clockwise_1.orientation() != CGAL::COUNTERCLOCKWISE){ + LOG(WARNING) << "Polygon orientation wrong! Printing polygon ..."; + printPolygon(polygon_clockwise_1); + recursion_1 = std::vector(); + } else{ + recursion_1 = performInnerConvexApproximation(polygon_clockwise_1); + } + if(polygon_clockwise_2.orientation() != CGAL::COUNTERCLOCKWISE){ + LOG(WARNING) << "Polygon orientation wrong! Printing polygon ..."; + printPolygon(polygon_clockwise_2); + recursion_2 = std::vector(); + } else{ + recursion_2 = performInnerConvexApproximation(polygon_clockwise_2); + } + } + std::move(recursion_1.begin(),recursion_1.end(), std::back_inserter(convex_polygons)); + std::move(recursion_1.begin(), recursion_2.end(), std::back_inserter(convex_polygons)); + VLOG(1) << "Reached bottom!"; + return convex_polygons; +} + +// A dent is a vertex, which lies in a counter-clockwise oriented polygon on the left side of its neighbors. +// Dents cause non-convexity. +std::multimap ConvexDecomposer::detectDentLocations(const CgalPolygon2d& polygon) const { + VLOG(1) << "Starting dent detection..."; + CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); + std::multimap dent_locations; + for (auto source_it = polygon.vertices_begin(); source_it != polygon.vertices_end(); ++source_it){ + auto dent_it = next(source_it, polygon); + auto destination_it = next(dent_it, polygon); + Vector2d source_point = Vector2d(source_it->x(), source_it->y()); + Vector2d destination_point = Vector2d(destination_it->x(), destination_it->y()); + Vector2d direction_vector = destination_point - source_point; + Vector2d test_point = Vector2d(dent_it->x(), dent_it->y()); + if(isPointOnLeftSide(source_point, direction_vector, test_point)){ + double angle = abs(computeAngleBetweenVectors(source_point - test_point, destination_point - test_point)); + // Ignore very shallow dents. Approximate convex decomposition. + if ( angle > parameters_.dent_angle_threshold_rad) + dent_locations.insert(std::make_pair(angle, std::distance(polygon.vertices_begin(), dent_it))); + } + } + VLOG(1) << "done."; + return dent_locations; +} + +// *output_polygon_list = decomposeInnerApproximation(polygon); \ No newline at end of file diff --git a/convex_plane_decomposition/src/pipeline.cpp b/convex_plane_decomposition/src/pipeline.cpp new file mode 100644 index 00000000..e82ae21c --- /dev/null +++ b/convex_plane_decomposition/src/pipeline.cpp @@ -0,0 +1,40 @@ + +#include "pipeline.hpp" + +using namespace convex_plane_extraction; + +void Pipeline::runPipeline() { + sliding_window_plane_extractor::SlidingWindowPlaneExtractor sliding_window_plane_extractor(grid_map_parameters_.map, + grid_map_parameters_.resolution, grid_map_parameters_.layer_height, grid_map_parameters_.normal_layer_prefix, + pipeline_parameters_.sliding_window_plane_extractor_parameters); + sliding_window_plane_extractor.runExtraction(); + PlaneFactory plane_factory(grid_map_parameters_.map, pipeline_parameters_.plane_factory_parameters_); + plane_factory.createPlanesFromLabeledImageAndPlaneParameters(sliding_window_plane_extractor.getLabeledImage(), + sliding_window_plane_extractor.getNumberOfExtractedPlanes(), sliding_window_plane_extractor.getLabelPlaneParameterMap()); + +} + +void Pipeline::exportConvexPolygons(const std::string& export_path) const { + std::ofstream output_file; + output_file.open(export_path + "convex_polygons.txt", std::ofstream::app); + std::chrono::milliseconds time_stamp = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()); + for (const auto& plane : planes_){ + for (const auto& polygon : plane.getConvexPolygons()){ + output_file << time_stamp.count() << ", "; + for (const auto& vertex : polygon){ + output_file << vertex.x() << ", "; + } + for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it){ + output_file << vertex_it->y(); + if (vertex_it != std::prev(polygon.vertices_end())){ + output_file << ", "; + } else { + output_file << "\n"; + } + } + } + } + output_file.close(); + VLOG(1) << "Exported polygons to " << export_path << "convex_polygons.txt !"; +} \ No newline at end of file diff --git a/convex_plane_decomposition/src/plane.cpp b/convex_plane_decomposition/src/plane.cpp index 13459666..b1565257 100644 --- a/convex_plane_decomposition/src/plane.cpp +++ b/convex_plane_decomposition/src/plane.cpp @@ -7,36 +7,11 @@ namespace convex_plane_extraction{ Plane::Plane(CgalPolygon2d& outer_polygon, CgalPolygon2dContainer& holes) : outer_polygon_(outer_polygon), - hole_polygon_list_(holes), - initialized_(false){}; - - Plane::~Plane() = default; - - bool Plane::addHolePolygon(const convex_plane_extraction::CgalPolygon2d & hole_polygon) { - if (initialized_){ - LOG(ERROR) << "Hole cannot be added to plane since already initialized!"; - return false; - } - CHECK(!hole_polygon.is_empty()); - hole_polygon_list_.push_back(hole_polygon); - return true; - } - - bool Plane::addOuterPolygon(const convex_plane_extraction::CgalPolygon2d & outer_polygon) { - if (initialized_){ - LOG(ERROR) << "Outer polygon cannot be added to plane since already initialized!"; - return false; - } - CHECK(!outer_polygon.is_empty()); - outer_polygon_ = (outer_polygon); - return true; - } + hole_polygons_(holes), + initialized_(false){} bool Plane::setNormalAndSupportVector(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector){ - if (initialized_){ - LOG(ERROR) << "Could not set normal and support vector of plane since already initialized!"; - return false; - } + CHECK(!initialized_) << "Could not set normal and support vector of plane since already initialized!"; normal_vector_ = normal_vector; support_vector_ = support_vector; constexpr double inclinationThreshold = 0.35; // cos(70°) @@ -60,17 +35,17 @@ namespace convex_plane_extraction{ LOG(ERROR) << "Connot perform convex decomposition of plane, since not yet initialized."; return false; } - performConvexDecomposition(outer_polygon_, &convex_polygon_list_); + performConvexDecomposition(outer_polygon_, &convex_polygons_); return true; } bool Plane::convertConvexPolygonsToWorldFrame(Polygon3dVectorContainer* output_container, const Eigen::Matrix2d& transformation, const Eigen::Vector2d& map_position) const{ CHECK_NOTNULL(output_container); - if (convex_polygon_list_.empty()){ + if (convex_polygons_.empty()){ LOG(INFO) << "No convex polygons to convert!"; return false; } - for (const auto& polygon : convex_polygon_list_){ + for (const auto& polygon : convex_polygons_){ if (polygon.is_empty()){ continue; } @@ -107,11 +82,11 @@ namespace convex_plane_extraction{ bool Plane::convertHolePolygonsToWorldFrame(Polygon3dVectorContainer* output_container, const Eigen::Matrix2d& transformation, const Eigen::Vector2d& map_position) const{ CHECK_NOTNULL(output_container); - if (hole_polygon_list_.empty()){ + if (hole_polygons_.empty()){ LOG(INFO) << "No hole polygons to convert!"; return false; } - for (const auto& polygon : hole_polygon_list_){ + for (const auto& polygon : hole_polygons_){ if (polygon.is_empty()){ continue; } @@ -146,274 +121,5 @@ namespace convex_plane_extraction{ *output_point = Vector3d(input_point.x(), input_point.y(), z); } - bool Plane::hasOuterContour() const{ - return !outer_polygon_.is_empty(); - } - - CgalPolygon2dVertexConstIterator Plane::outerPolygonVertexBegin() const{ - CHECK(isValid()); - return outer_polygon_.vertices_begin(); - } - - CgalPolygon2dVertexConstIterator Plane::outerPolygonVertexEnd() const{ - CHECK(isValid()); - return outer_polygon_.vertices_end(); - } - - CgalPolygon2dConstIterator Plane::holePolygonBegin() const{ - CHECK(isValid()); - return hole_polygon_list_.begin(); - } - - CgalPolygon2dConstIterator Plane::holePolygonEnd() const{ - CHECK(isValid()); - return hole_polygon_list_.end(); - } - - void Plane::resolveHoles() { - if (hole_polygon_list_.empty()) { - return; - } - auto hole_it = hole_polygon_list_.begin(); - while(!hole_polygon_list_.empty()) { - if (hole_it == hole_polygon_list_.end()){ - hole_it = hole_polygon_list_.begin(); - } - // Compute distance to outer contour for each hole. - std::vector distance_to_outer_polygon; - std::vector outer_contour_connection_vertex_positions; // closest outer contour vertex for each hole - std::vector hole_connection_vertex_positions; - if (hole_it->size() < 3) { - ++hole_it; - hole_polygon_list_.erase(std::prev(hole_it)); - } else if (abs(hole_it->area()) < 2e-3) { - ++hole_it; - hole_polygon_list_.erase(std::prev(hole_it)); - } else { - std::cout << "List size: " << hole_polygon_list_.size() << std::endl; - std::cout << "Outer: " << std::endl; - printPolygon(outer_polygon_); - std::cout << "Hole: " << std::endl; - printPolygon(*hole_polygon_list_.begin()); - std::multimap> connection_candidates; - slConcavityHoleVertexSorting(*hole_it, &connection_candidates); - CHECK(connection_candidates.size() == hole_it->size()*outer_polygon_.size()); - // Instead of extracting only the 2 SL-concavity points, sort vertices according to SL-concavity measure. - // Then iterate over sorted vertices until a connection to the outer contour is not intersecting the polyogn. - // Implement function that checks for intersections with existing polygon contour. - int hole_connection_vertex_position; - int outer_polygon_connection_vertex_position; - bool valid_connection = true; - int i = 0; - for (const auto& position : connection_candidates){ - auto hole_vertex_it = hole_it->vertices_begin(); - std::advance(hole_vertex_it, position.second.first); - bool print_flag = false; - if (position.second.first == 7){ - print_flag = true; - } - CgalPoint2d hole_vertex = *hole_vertex_it; - // Get outer contour connection vertices sorted according to distance to hole vertex. - auto outer_vertex_it = outer_polygon_.vertices_begin(); - std::advance(outer_vertex_it, position.second.second); - CgalVector2d direction = *outer_vertex_it - hole_vertex; - direction = (1.0/direction.squared_length()) * direction; - CgalSegment2d connection(hole_vertex + 0.0001 * direction, *outer_vertex_it - 0.0001 * direction); - if (!doPolygonAndSegmentIntersect(outer_polygon_, connection, print_flag)){ - valid_connection = true; - for (auto hole_iterator = hole_polygon_list_.begin(); hole_iterator != hole_polygon_list_.end(); ++hole_iterator){ - if (hole_iterator->size() < 3){ - continue; - } - if (doPolygonAndSegmentIntersect(*hole_iterator, connection, print_flag)) { - valid_connection = false; - //std::cout << "Hole and connection intersect!" << std::endl; - ++i; - break; - } - } - } else { - //std::cout << "Outer contour and connection intersect!" << std::endl; - ++i; - valid_connection = false; - } - if (valid_connection){ - hole_connection_vertex_position = position.second.first; - outer_polygon_connection_vertex_position = position.second.second; - break; - } - } - if (!valid_connection){ - CHECK_EQ(i, hole_it->size()*outer_polygon_.size()); - LOG(WARNING) << "No valid connection found! " << i << " iterations."; - ++hole_it; - continue; - } - CHECK(valid_connection); - // Perform the integration of the hole into the outer contour. - auto outer_contour_connection_vertex = outer_polygon_.vertices_begin(); - std::advance(outer_contour_connection_vertex, outer_polygon_connection_vertex_position); - auto hole_contour_connection_vertex = hole_it->vertices_begin(); - std::advance(hole_contour_connection_vertex, hole_connection_vertex_position); - CgalPolygon2d new_polygon; - // Start filling new polygon with outer contour. - for (auto vertex_it = outer_polygon_.vertices_begin(); vertex_it != outer_contour_connection_vertex; ++vertex_it){ - new_polygon.push_back(*vertex_it); - } - new_polygon.push_back(*outer_contour_connection_vertex); - auto hole_vertex_it = hole_contour_connection_vertex; - do { - new_polygon.push_back(*hole_vertex_it); - if (hole_vertex_it != std::prev(hole_it->vertices_end())){ - hole_vertex_it = std::next(hole_vertex_it); - } else { - hole_vertex_it = hole_it->vertices_begin(); - } - } while(hole_vertex_it != hole_contour_connection_vertex); - // Create new vertices next to connection points to avoid same enter and return path. - CgalSegment2d enter_connection(*outer_contour_connection_vertex, *hole_contour_connection_vertex); - Eigen::Vector2d normal_vector; - getSegmentNormalVector(enter_connection, &normal_vector); - // Check for possible intersections. - Eigen::Vector2d line_start_point(hole_contour_connection_vertex->x(), hole_contour_connection_vertex->y()); - Eigen::Vector2d direction_vector(outer_contour_connection_vertex->x() - hole_contour_connection_vertex->x(), - outer_contour_connection_vertex->y() - hole_contour_connection_vertex->y()); - auto next_vertex = std::next(outer_contour_connection_vertex); - if (next_vertex == outer_polygon_.vertices_end()){ - next_vertex = outer_polygon_.begin(); - } - Eigen::Vector2d test_point(next_vertex->x(), next_vertex->y()); - constexpr double kPointOffset = 0.0001; - Eigen::Vector2d outer_point(outer_contour_connection_vertex->x(), outer_contour_connection_vertex->y()); - if (isPointOnLeftSide(line_start_point, direction_vector, test_point)){ - Eigen::Vector2d translation_vector(next_vertex->x() - outer_contour_connection_vertex->x(), - next_vertex->y() - outer_contour_connection_vertex->y()); - translation_vector.normalize(); - outer_point += kPointOffset * translation_vector.normalized(); - } else { - outer_point += kPointOffset * normal_vector.normalized(); - } - next_vertex = hole_contour_connection_vertex; - if (next_vertex == hole_it->vertices_begin()){ - next_vertex = hole_it->vertices_end(); - next_vertex = std::prev(next_vertex); - } else { - next_vertex = std::prev(next_vertex); - } - Eigen::Vector2d hole_point(hole_contour_connection_vertex->x(), hole_contour_connection_vertex->y()); - test_point << next_vertex->x(), next_vertex->y(); - constexpr double kPiHalf = 3.1416 / 2; - if (isPointOnLeftSide(line_start_point, direction_vector, test_point) - && computeAngleBetweenVectors(test_point - line_start_point, direction_vector) < kPiHalf){ - Eigen::Vector2d translation_vector(next_vertex->x() - hole_contour_connection_vertex->x(), - next_vertex->y() - hole_contour_connection_vertex->y()); - translation_vector.normalize(); - hole_point += kPointOffset * translation_vector; - } else { - hole_point += kPointOffset * normal_vector; - } - Vector2d new_edge_direction = outer_point - hole_point; - new_edge_direction.normalize(); - constexpr double kShiftFactor = 0.0001; - bool intersection_caused = false; - CgalSegment2d new_edge(CgalPoint2d(hole_point.x() + kShiftFactor * new_edge_direction.x(), - hole_point.y() + kShiftFactor * new_edge_direction.y()),CgalPoint2d(outer_point.x() - - kShiftFactor * new_edge_direction.x(), outer_point.y() - kShiftFactor * new_edge_direction.y())); - if (!doPolygonAndSegmentIntersect(outer_polygon_, new_edge, false)){ - for (auto hole_iterator = hole_polygon_list_.begin(); hole_iterator != hole_polygon_list_.end(); ++hole_iterator){ - if (hole_iterator->size() < 3){ - continue; - } - if (doPolygonAndSegmentIntersect(*hole_iterator, new_edge, false)) { - intersection_caused = true; - break; - } - } - } else { - //std::cout << "Outer contour and connection intersect!" << std::endl; - intersection_caused = true; - } - if (intersection_caused){ - ++hole_it; - continue; - } - // Add new vertices to outer contour. - new_polygon.push_back(CgalPoint2d(hole_point.x(), hole_point.y())); - new_polygon.push_back(CgalPoint2d(outer_point.x(), outer_point.y())); - // Add remaining outer contour vertices to new polygon. - auto vertex_it = outer_contour_connection_vertex; - vertex_it = std::next(vertex_it); - for (; vertex_it != outer_polygon_.vertices_end(); ++vertex_it){ - new_polygon.push_back(*vertex_it); - } - if (!new_polygon.is_simple()){ - std::cout << "Hole orientation: " << hole_it->orientation() << std::endl; - std::cout <<"Hole vertex: " << *hole_contour_connection_vertex << std::endl; - std::cout <<"Outer vertex: " << *outer_contour_connection_vertex << std::endl; - printPolygon(new_polygon); - } - CHECK(new_polygon.is_simple()); - outer_polygon_ = new_polygon; - ++hole_it; - hole_polygon_list_.erase(std::prev(hole_it)); - } - } - //approximateContour(&outer_polygon_); - CHECK(outer_polygon_.is_simple()); - } - - void Plane::extractSlConcavityPointsOfHole(const CgalPolygon2d& hole, std::vector* concavity_positions){ - CHECK_NOTNULL(concavity_positions); - if (hole.is_empty()) { - return; - } else if (hole.size() == 1){ - concavity_positions->push_back(0); - } else if (hole.size() == 2){ - concavity_positions->push_back(0); - concavity_positions->push_back(1); - } else { - MatrixXd data_matrix(hole.size(), 2); - Eigen::Vector2d mean_position = Eigen::Vector2d::Zero(2,1); - auto hole_vertex_it = hole.vertices_begin(); - for (int row = 0; row < hole.size(); ++row){ - data_matrix(row, 0) = (*hole_vertex_it).x(); - data_matrix(row, 1) = (*hole_vertex_it).y(); - mean_position(0) += (*hole_vertex_it).x(); - mean_position(1) += (*hole_vertex_it).y(); - ++hole_vertex_it; - } - mean_position *= (1.0 / static_cast(hole.size())); - for (int row = 0; row < data_matrix.rows(); ++row) { - data_matrix.row(row) -= mean_position.transpose(); - } - Eigen::BDCSVD svd = data_matrix.bdcSvd(Eigen::ComputeFullU | Eigen::ComputeFullV); - Eigen::Vector2d orthonormal_to_PC_axis = svd.matrixV().col(1); - // Place vector to mean position of hole. - Eigen::Vector2d second_point_axis = mean_position + orthonormal_to_PC_axis; - double max_distance = 0; - double min_distance = 0; - int position_right_concavity_point; - int position_left_concavity_point; - hole_vertex_it = hole.vertices_begin(); - for (; hole_vertex_it != hole.vertices_end(); ++hole_vertex_it){ - Eigen::Vector2d vertex_point; - vertex_point << (*hole_vertex_it).x(), (*hole_vertex_it).y(); - double current_distance = distanceToLine(mean_position, orthonormal_to_PC_axis, vertex_point); - if (current_distance > max_distance) { - max_distance = current_distance; - position_right_concavity_point = std::distance(hole.vertices_begin(), hole_vertex_it); - } else if (current_distance < min_distance){ - min_distance = current_distance; - position_left_concavity_point = std::distance(hole.vertices_begin(), hole_vertex_it); - } - } - concavity_positions->push_back(position_left_concavity_point); - concavity_positions->push_back(position_right_concavity_point); - } - } - - const CgalPolygon2dContainer& Plane::getConvexPolygons() const { - return convex_polygon_list_; - } } diff --git a/convex_plane_decomposition/src/plane_extractor.cpp b/convex_plane_decomposition/src/plane_extractor.cpp index a885fcba..e1369da6 100644 --- a/convex_plane_decomposition/src/plane_extractor.cpp +++ b/convex_plane_decomposition/src/plane_extractor.cpp @@ -47,7 +47,7 @@ using namespace grid_map; void PlaneExtractor::runSlidingWindowPlaneExtractor(){ ROS_INFO("Starting sliding window plane extraction..."); - sliding_window_plane_extractor_.runDetection(); + sliding_window_plane_extractor_.runSlidingWindowDetector(); ROS_INFO("... done."); } diff --git a/convex_plane_decomposition/src/plane_factory.cpp b/convex_plane_decomposition/src/plane_factory.cpp index 9eb4b184..c659f4bb 100644 --- a/convex_plane_decomposition/src/plane_factory.cpp +++ b/convex_plane_decomposition/src/plane_factory.cpp @@ -1,7 +1,3 @@ -// -// Created by andrej on 3/1/20. -// - #include "plane_factory.hpp" using namespace convex_plane_extraction; @@ -17,81 +13,26 @@ void PlaneFactory::computeMapTransformation(){ transformation_xy_to_world_frame_.col(1) = (upper_right_cell_position - map_offset_).normalized(); } -void createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, const int number_of_labels, - const std::map& parameters){ +void PlaneFactory::createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, const int number_of_labels, + const std::map& plane_parameters){ CHECK_GT(number_of_labels, 0); - CHECK_EQ(number_of_labels, parameters.size()); + CHECK_EQ(number_of_labels, plane_parameters.size()); + Polygonizer polygonizer(parameters_.polygonizer_parameters); for (int label = 1; label < number_of_labels; ++label){ cv::Mat binary_image(labeled_image.size(), CV_8UC1); binary_image = labeled_image == label; - extractPolygonsFromBinaryImage(binary_image) + const CgalPolygon2d plane_contour = polygonizer.runPolygonizationOnBinaryImage(binary_image); + const auto plane_parameter_it = plane_parameters.find(label); + CHECK_NE(plane_parameter_it, plane_parameters.end()) << "Label not contained in plane parameter container!"; + if (isPlaneInclinationBelowThreshold(plane_parameter_it->second.normal_vector)){ + planes_.emplace_back(plane_contour, plane_parameter_it->second); + } else { + LOG(WARNING) << "Dropping plane due to exceeded inclination threshold!"; + } } } - - - -for (int label_it = 1; label_it <= number_of_extracted_planes_; ++label_it) { -auto polygonizer_start = std::chrono::system_clock::now(); -convex_plane_extraction::Plane plane; -std::vector> contours; -std::vector hierarchy; -cv::Mat binary_image(labeled_image_.size(), CV_8UC1); -binary_image = labeled_image_ == label_it; -constexpr int kUpSamplingFactor = 3; -cv::Mat binary_image_upsampled; -cv::resize(binary_image, binary_image_upsampled, cv::Size(kUpSamplingFactor*binary_image.size().height, kUpSamplingFactor*binary_image.size().width)); -findContours(binary_image_upsampled, contours, hierarchy, - CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); -std::list> approx_contours; -int hierachy_it = 0; -for (auto& contour : contours) { -++hierachy_it; -std::vector approx_contour; -if (contour.size() <= 10){ -approx_contour = contour; -} else { -cv::approxPolyDP(contour, approx_contour, 9, true); -} -if (approx_contour.size() <= 2) { -LOG_IF(WARNING, hierarchy[hierachy_it-1][3] < 0 && contour.size() > 4) << "Removing parental polygon since too few vertices!"; -continue; -} -convex_plane_extraction::CgalPolygon2d polygon = convex_plane_extraction::createCgalPolygonFromOpenCvPoints(approx_contour.begin(), approx_contour.end(), resolution_ / kUpSamplingFactor); - -if(!polygon.is_simple()) { -convex_plane_extraction::Vector2i index; -index << (*polygon.begin()).x(), (*polygon.begin()).y(); -LOG(WARNING) << "Polygon starting at " << index << " is not simple, will be ignored!"; -continue; -} -constexpr int kParentFlagIndex = 3; -if (hierarchy[hierachy_it-1][kParentFlagIndex] < 0) { -//convex_plane_extraction::upSampleLongEdges(&polygon); -// convex_plane_extraction::approximateContour(&polygon); -CHECK(plane.addOuterPolygon(polygon)); -} else { -CHECK(plane.addHolePolygon(polygon)); -} -} -if(plane.hasOuterContour()) { -//LOG(WARNING) << "Dropping plane, no outer contour detected!"; -computePlaneFrameFromLabeledImage(binary_image, &plane); -auto polygonizer_end = std::chrono::system_clock::now(); -auto polygonizer_duration = std::chrono::duration_cast(polygonizer_end - polygonizer_start); -polygonizer_file << time_stamp.count() << ", " << polygonizer_duration.count() << "\n"; -if(plane.isValid()) { -LOG(INFO) << "Starting resolving holes..."; -plane.resolveHoles(); -LOG(INFO) << "done."; -auto decomposer_start = std::chrono::system_clock::now(); -CHECK(plane.decomposePlaneInConvexPolygons()); -auto decomposer_end = std::chrono::system_clock::now(); -auto decomposer_duration = std::chrono::duration_cast(decomposer_end - decomposer_start); -decomposer_file << time_stamp.count() << ", " << decomposer_duration.count() << "\n"; -planes_.push_back(plane); -} else { -LOG(WARNING) << "Dropping plane, normal vector could not be inferred!"; -} -} +bool PlaneFactory::isPlaneInclinationBelowThreshold(const Eigen::Vector3d& plane_normal_vector) const { + const Eigen::Vector3d z_axis(0,0,1); + return std::atan2(1.0, z_axis.dot(plane_normal_vector)) < (parameters_.plane_inclination_threshold_degrees / 180.0 * M_PI); } diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 6d1dbd5d..d75328f5 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -2,24 +2,6 @@ namespace convex_plane_extraction { - void performConvexDecomposition(const CgalPolygon2d& polygon, CgalPolygon2dContainer* output_polygon_list){ - CHECK_GE(polygon.size(), 3); - CHECK(polygon.is_simple()); - LOG(INFO) << "Started convex decomposition..."; - size_t old_list_size = output_polygon_list->size(); - CGAL::optimal_convex_partition_2(polygon.vertices_begin(), - polygon.vertices_end(), - std::back_inserter(*output_polygon_list)); - - assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), - polygon.vertices_end(), - polygon_list.begin(), - polygon_list.end())); -// *output_polygon_list = decomposeInnerApproximation(polygon); - CHECK_GT(output_polygon_list->size(), old_list_size); - LOG(INFO) << "done."; - } - bool doPolygonAndSegmentIntersect(const CgalPolygon2d& polygon, const CgalSegment2d& segment, bool print_flag){ for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it){ auto next_vertex_it = std::next(vertex_it); @@ -201,29 +183,6 @@ namespace convex_plane_extraction { + (destination_point.y() - source_point.y()) * (destination_point.y() - source_point.y()))); } - // A dent is a vertex, which lies in a counter-clockwise oriented polygon on the left side of its neighbors. - // Dents cause non-convexity. - void detectDentLocations(std::map* dent_locations, const CgalPolygon2d& polygon){ - CHECK_NOTNULL(dent_locations); - CHECK(dent_locations->empty()); - CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); - for (auto source_it = polygon.vertices_begin(); source_it != polygon.vertices_end(); ++source_it){ - auto dent_it = next(source_it, polygon); - auto destination_it = next(dent_it, polygon); - Vector2d source_point = Vector2d(source_it->x(), source_it->y()); - Vector2d destination_point = Vector2d(destination_it->x(), destination_it->y()); - Vector2d direction_vector = destination_point - source_point; - Vector2d test_point = Vector2d(dent_it->x(), dent_it->y()); - const double kAngleThresholdRad = 0.001; // 0.05 deg in rad. - if(isPointOnLeftSide(source_point, direction_vector, test_point)){ - double angle = abs(computeAngleBetweenVectors(source_point - test_point, destination_point - test_point)); - // Ignore very shallow dents. Approximate convex decomposition. - if ( angle > kAngleThresholdRad) - dent_locations->insert(std::make_pair(angle, std::distance(polygon.vertices_begin(), dent_it))); - } - } - } - std::list decomposeInnerApproximation(const CgalPolygon2d& polygon){ CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); std::list return_list; @@ -469,4 +428,57 @@ namespace convex_plane_extraction { } } + std::pair getIndicesOfClosestVertexPair(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon){ + CHECK_GT(first_polygon.size(), 0); + CHECK_GT(second_polygon.size(), 0); + std::multimap> buffer = getClosestVertexPairsOrdered(first_polygon, second_polygon); + CHECK(!buffer.empty()); + return buffer.begin()->second; + } + + std::multimap> getClosestVertexPairsOrdered(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon){ + CHECK_GT(first_polygon.size(), 0); + CHECK_GT(second_polygon.size(), 0); + std::multimap> buffer; + for (auto vertex_it = first_polygon.vertices_begin(); vertex_it != first_polygon.vertices_end(); ++vertex_it){ + int first_vertex_index = std::distance(first_polygon.vertices_begin(), vertex_it); + double distance = std::numeric_limits::max(); + int second_vertex_index = 0; + for (auto second_vertex_it = second_polygon.vertices_begin(); second_vertex_it != second_polygon.vertices_begin(); ++second_vertex_it){ + const double temp_distance = sqrt(static_cast(*vertex_it - *second_vertex_it).squared_length()); + if (temp_distance < distance){ + distance = temp_distance; + second_vertex_index = std::distance(second_polygon.vertices_begin(), second_vertex_it); + } + } + buffer.insert(std::make_pair(distance, std::make_pair(first_vertex_index, second_vertex_index))); + } + return buffer; + } + + CgalPoint2d getPolygonVertexAtIndex(const CgalPolygon2d& polygon, int index){ + CHECK_GT(index, 0); + CHECK_LT(index, polygon.size()); + auto vertex_it = polygon.vertices_begin(); + std::advance(vertex_it, index); + return *vertex_it; + } + + bool doPointAndPolygonIntersect(const CgalPolygon2d& polygon, const CgalPoint2d& point, int& segment_target_vertex_index){ + for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it) { + auto next_vertex_it = std::next(vertex_it); + if (next_vertex_it == polygon.vertices_end()) { + next_vertex_it = polygon.vertices_begin(); + } + CgalSegment2d test_segment(*vertex_it, *next_vertex_it); + if (test_segment.has_on(point)){ + segment_target_vertex_index = std::distance(polygon.vertices_begin(), next_vertex_it); + return true; + } + } + return false; + } + + CgalPolygon2d + } diff --git a/convex_plane_decomposition/src/polygonizer.cpp b/convex_plane_decomposition/src/polygonizer.cpp index 04a83bb1..e331347b 100644 --- a/convex_plane_decomposition/src/polygonizer.cpp +++ b/convex_plane_decomposition/src/polygonizer.cpp @@ -21,7 +21,8 @@ PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& bina if (contour.size() <= 10) { approx_contour = contour; } else { - cv::approxPolyDP(contour, approx_contour, 9, true); + approx_contour = contour; // Do this at later stage so that no intersections with holes are generated. + //cv::approxPolyDP(contour, approx_contour, 9, true); } if (approx_contour.size() <= 2) { LOG_IF(WARNING, hierarchy[hierachy_it - 1][3] < 0 && contour.size() > 3) @@ -55,195 +56,263 @@ PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& bina return plane_polygons; } -CgalPolygon2d Polygonizer::resolveHoles(PolygonWithHoles& polygon_with_holes) const{ +//CgalPolygon2d Polygonizer::resolveHoles(PolygonWithHoles& polygon_with_holes) const{ +// CgalPolygon2dContainer& holes = polygon_with_holes.holes; +// // Get hole part which is entirely contained in outer contour. +// // In the contour simplification stage intersections may have been introduced. +// removeAreasNotContainedInOuterContourFromHoles(polygon_with_holes.outer_contour, holes); +// if (holes.empty()) { +// return polygon_with_holes.outer_contour; +// } +// auto hole_it = holes.begin(); +// while(!holes.empty()) { +// if (hole_it == holes.end()){ +// hole_it = holes.begin(); +// } +// // Compute distance to outer contour for each hole. +// if (hole_it->size() < 3) { +// hole_it = holes.erase(hole_it); +// } else if (abs(hole_it->area()) < parameters_.hole_area_threshold_squared_meters) { +// hole_it = holes.erase(hole_it); +// } else { +// // Does one hole edge overlap with outer polygon? Treat this separately. +// doHole +// std::pair bridge_hole_outer_vertex = getIndicesOfClosestVertexPair(*hole_it, polygon_with_holes.outer_contour); +// CgalSegment2d bridge(getPolygonVertexAtIndex(*hole_it, bridge_hole_outer_vertex .first), +// getPolygonVertexAtIndex(polygon_with_holes.outer_contour, bridge_hole_outer_vertex .second)); +// int segment_target_vertex_index; +// if (doPointAndPolygonIntersect(polygon_with_holes.outer_contour, getPolygonVertexAtIndex(*hole_it, +// bridge_hole_outer_vertex.first), segment_target_vertex_index)){ +// addHoleToOuterContourAtVertexIndex(bridge_hole_outer_vertex.first, segment_target_vertex_index, *hole_it, polygon_with_holes.outer_contour); +// } +// int hole_connection_vertex_position; +// int outer_polygon_connection_vertex_position; +// bool valid_connection = true; +// int i = 0; +// for (const auto& position : connection_candidates){ +// auto hole_vertex_it = hole_it->vertices_begin(); +// std::advance(hole_vertex_it, position.second.first); +// bool print_flag = false; +// if (position.second.first == 7){ +// print_flag = true; +// } +// CgalPoint2d hole_vertex = *hole_vertex_it; +// // Get outer contour connection vertices sorted according to distance to hole vertex. +// auto outer_vertex_it = outer_polygon_.vertices_begin(); +// std::advance(outer_vertex_it, position.second.second); +// CgalVector2d direction = *outer_vertex_it - hole_vertex; +// direction = (1.0/direction.squared_length()) * direction; +// CgalSegment2d connection(hole_vertex + 0.0001 * direction, *outer_vertex_it - 0.0001 * direction); +// if (!doPolygonAndSegmentIntersect(outer_polygon_, connection, print_flag)){ +// valid_connection = true; +// for (auto hole_iterator = hole_polygons_.begin(); hole_iterator != hole_polygons_.end(); ++hole_iterator){ +// if (hole_iterator->size() < 3){ +// continue; +// } +// if (doPolygonAndSegmentIntersect(*hole_iterator, connection, print_flag)) { +// valid_connection = false; +// //std::cout << "Hole and connection intersect!" << std::endl; +// ++i; +// break; +// } +// } +// } else { +// //std::cout << "Outer contour and connection intersect!" << std::endl; +// ++i; +// valid_connection = false; +// } +// if (valid_connection){ +// hole_connection_vertex_position = position.second.first; +// outer_polygon_connection_vertex_position = position.second.second; +// break; +// } +// } +// if (!valid_connection){ +// CHECK_EQ(i, hole_it->size()*outer_polygon_.size()); +// LOG(WARNING) << "No valid connection found! " << i << " iterations."; +// ++hole_it; +// continue; +// } +// CHECK(valid_connection); +// // Perform the integration of the hole into the outer contour. +// auto outer_contour_connection_vertex = outer_polygon_.vertices_begin(); +// std::advance(outer_contour_connection_vertex, outer_polygon_connection_vertex_position); +// auto hole_contour_connection_vertex = hole_it->vertices_begin(); +// std::advance(hole_contour_connection_vertex, hole_connection_vertex_position); +// CgalPolygon2d new_polygon; +// // Start filling new polygon with outer contour. +// for (auto vertex_it = outer_polygon_.vertices_begin(); vertex_it != outer_contour_connection_vertex; ++vertex_it){ +// new_polygon.push_back(*vertex_it); +// } +// new_polygon.push_back(*outer_contour_connection_vertex); +// auto hole_vertex_it = hole_contour_connection_vertex; +// do { +// new_polygon.push_back(*hole_vertex_it); +// if (hole_vertex_it != std::prev(hole_it->vertices_end())){ +// hole_vertex_it = std::next(hole_vertex_it); +// } else { +// hole_vertex_it = hole_it->vertices_begin(); +// } +// } while(hole_vertex_it != hole_contour_connection_vertex); +// // Create new vertices next to connection points to avoid same enter and return path. +// CgalSegment2d enter_connection(*outer_contour_connection_vertex, *hole_contour_connection_vertex); +// Eigen::Vector2d normal_vector; +// getSegmentNormalVector(enter_connection, &normal_vector); +// // Check for possible intersections. +// Eigen::Vector2d line_start_point(hole_contour_connection_vertex->x(), hole_contour_connection_vertex->y()); +// Eigen::Vector2d direction_vector(outer_contour_connection_vertex->x() - hole_contour_connection_vertex->x(), +// outer_contour_connection_vertex->y() - hole_contour_connection_vertex->y()); +// auto next_vertex = std::next(outer_contour_connection_vertex); +// if (next_vertex == outer_polygon_.vertices_end()){ +// next_vertex = outer_polygon_.begin(); +// } +// Eigen::Vector2d test_point(next_vertex->x(), next_vertex->y()); +// constexpr double kPointOffset = 0.0001; +// Eigen::Vector2d outer_point(outer_contour_connection_vertex->x(), outer_contour_connection_vertex->y()); +// if (isPointOnLeftSide(line_start_point, direction_vector, test_point)){ +// Eigen::Vector2d translation_vector(next_vertex->x() - outer_contour_connection_vertex->x(), +// next_vertex->y() - outer_contour_connection_vertex->y()); +// translation_vector.normalize(); +// outer_point += kPointOffset * translation_vector.normalized(); +// } else { +// outer_point += kPointOffset * normal_vector.normalized(); +// } +// next_vertex = hole_contour_connection_vertex; +// if (next_vertex == hole_it->vertices_begin()){ +// next_vertex = hole_it->vertices_end(); +// next_vertex = std::prev(next_vertex); +// } else { +// next_vertex = std::prev(next_vertex); +// } +// Eigen::Vector2d hole_point(hole_contour_connection_vertex->x(), hole_contour_connection_vertex->y()); +// test_point << next_vertex->x(), next_vertex->y(); +// constexpr double kPiHalf = 3.1416 / 2; +// if (isPointOnLeftSide(line_start_point, direction_vector, test_point) +// && computeAngleBetweenVectors(test_point - line_start_point, direction_vector) < kPiHalf){ +// Eigen::Vector2d translation_vector(next_vertex->x() - hole_contour_connection_vertex->x(), +// next_vertex->y() - hole_contour_connection_vertex->y()); +// translation_vector.normalize(); +// hole_point += kPointOffset * translation_vector; +// } else { +// hole_point += kPointOffset * normal_vector; +// } +// Vector2d new_edge_direction = outer_point - hole_point; +// new_edge_direction.normalize(); +// constexpr double kShiftFactor = 0.0001; +// bool intersection_caused = false; +// CgalSegment2d new_edge(CgalPoint2d(hole_point.x() + kShiftFactor * new_edge_direction.x(), +// hole_point.y() + kShiftFactor * new_edge_direction.y()),CgalPoint2d(outer_point.x() - +// kShiftFactor * new_edge_direction.x(), outer_point.y() - kShiftFactor * new_edge_direction.y())); +// if (!doPolygonAndSegmentIntersect(outer_polygon_, new_edge, false)){ +// for (auto hole_iterator = hole_polygons_.begin(); hole_iterator != hole_polygons_.end(); ++hole_iterator){ +// if (hole_iterator->size() < 3){ +// continue; +// } +// if (doPolygonAndSegmentIntersect(*hole_iterator, new_edge, false)) { +// intersection_caused = true; +// break; +// } +// } +// } else { +// //std::cout << "Outer contour and connection intersect!" << std::endl; +// intersection_caused = true; +// } +// if (intersection_caused){ +// ++hole_it; +// continue; +// } +// // Add new vertices to outer contour. +// new_polygon.push_back(CgalPoint2d(hole_point.x(), hole_point.y())); +// new_polygon.push_back(CgalPoint2d(outer_point.x(), outer_point.y())); +// // Add remaining outer contour vertices to new polygon. +// auto vertex_it = outer_contour_connection_vertex; +// vertex_it = std::next(vertex_it); +// for (; vertex_it != outer_polygon_.vertices_end(); ++vertex_it){ +// new_polygon.push_back(*vertex_it); +// } +// if (!new_polygon.is_simple()){ +// std::cout << "Hole orientation: " << hole_it->orientation() << std::endl; +// std::cout <<"Hole vertex: " << *hole_contour_connection_vertex << std::endl; +// std::cout <<"Outer vertex: " << *outer_contour_connection_vertex << std::endl; +// printPolygon(new_polygon); +// } +// CHECK(new_polygon.is_simple()); +// outer_polygon_ = new_polygon; +// ++hole_it; +// hole_polygons_.erase(std::prev(hole_it)); +// } +// } +// //approximateContour(&outer_polygon_); +// CHECK(outer_polygon_.is_simple()); +//} + +void Polygonizer::removeAreasNotContainedInOuterContourFromHoles(const CgalPolygon2d& outer_polygon, std::vector& holes) const{ + auto hole_it = holes.begin(); + while(hole_it != holes.end()) { + std::vector buffer; + std::vector::const_iterator buffer_it; + CGAL::intersection(outer_polygon, *hole_it, std::back_inserter(buffer_it)); + if (buffer.empty()){ + hole_it = holes.erase(hole_it); + } else { + CHECK_EQ(buffer.size(), 1) << "Intersection of hole and outer contour cannot have multiple polygons!"; + *hole_it = CgalPolygon2d(buffer.begin()->outer_boundary().vertices_begin(), buffer.begin()->outer_boundary().vertices_end()); + ++hole_it; + } + } +} + +bool Polygonizer::addHoleToOuterContourAtVertexIndex(int segment_target_vertex_index, const CgalPolygon2d& hole, CgalPolygon2d& outer_contour) const{ + CHECK_EQ(outer_contour.orientation(), CGAL::COUNTERCLOCKWISE); + CHECK_EQ(hole.orientation(), CGAL::COUNTERCLOCKWISE); + auto outer_vertex_it = outer_contour.vertices_begin(); + std::advance(outer_vertex_it, segment_target_vertex_index); + const auto& hole_vertex_buffer = hole.container(); + // TODO + return false; +} + +CgalPolygon2d Polygonizer::resolveHolesWithVerticalConnection(PolygonWithHoles& polygon_with_holes) const{ CgalPolygon2dContainer& holes = polygon_with_holes.holes; + // Get hole part which is entirely contained in outer contour. + // In the contour simplification stage intersections may have been introduced. + removeAreasNotContainedInOuterContourFromHoles(polygon_with_holes.outer_contour, holes); if (holes.empty()) { return polygon_with_holes.outer_contour; } auto hole_it = holes.begin(); - while(!holes.empty()) { - if (hole_it == holes.end()){ - hole_it = holes.begin(); - } - // Compute distance to outer contour for each hole. - std::vector distance_to_outer_polygon; - std::vector outer_contour_connection_vertex_positions; // closest outer contour vertex for each hole - std::vector hole_connection_vertex_positions; + while(hole_it!= holes.end()) { if (hole_it->size() < 3) { - ++hole_it; - holes.erase(std::prev(hole_it)); + hole_it = holes.erase(hole_it); } else if (abs(hole_it->area()) < parameters_.hole_area_threshold_squared_meters) { + hole_it = holes.erase(hole_it); + } else { ++hole_it; - holes.erase(std::prev(hole_it)); - } else { - std::cout << "List size: " << holes.size() << std::endl; - std::cout << "Outer: " << std::endl; - printPolygon(polygon_with_holes.outer_contour); - std::cout << "Hole: " << std::endl; - printPolygon(*holes.begin()); - std::multimap> connection_candidates; - slConcavityHoleVertexSorting(*hole_it, &connection_candidates); - CHECK(connection_candidates.size() == hole_it->size()*outer_polygon_.size()); - // Instead of extracting only the 2 SL-concavity points, sort vertices according to SL-concavity measure. - // Then iterate over sorted vertices until a connection to the outer contour is not intersecting the polyogn. - // Implement function that checks for intersections with existing polygon contour. - int hole_connection_vertex_position; - int outer_polygon_connection_vertex_position; - bool valid_connection = true; - int i = 0; - for (const auto& position : connection_candidates){ - auto hole_vertex_it = hole_it->vertices_begin(); - std::advance(hole_vertex_it, position.second.first); - bool print_flag = false; - if (position.second.first == 7){ - print_flag = true; - } - CgalPoint2d hole_vertex = *hole_vertex_it; - // Get outer contour connection vertices sorted according to distance to hole vertex. - auto outer_vertex_it = outer_polygon_.vertices_begin(); - std::advance(outer_vertex_it, position.second.second); - CgalVector2d direction = *outer_vertex_it - hole_vertex; - direction = (1.0/direction.squared_length()) * direction; - CgalSegment2d connection(hole_vertex + 0.0001 * direction, *outer_vertex_it - 0.0001 * direction); - if (!doPolygonAndSegmentIntersect(outer_polygon_, connection, print_flag)){ - valid_connection = true; - for (auto hole_iterator = hole_polygon_list_.begin(); hole_iterator != hole_polygon_list_.end(); ++hole_iterator){ - if (hole_iterator->size() < 3){ - continue; - } - if (doPolygonAndSegmentIntersect(*hole_iterator, connection, print_flag)) { - valid_connection = false; - //std::cout << "Hole and connection intersect!" << std::endl; - ++i; - break; - } - } - } else { - //std::cout << "Outer contour and connection intersect!" << std::endl; - ++i; - valid_connection = false; - } - if (valid_connection){ - hole_connection_vertex_position = position.second.first; - outer_polygon_connection_vertex_position = position.second.second; - break; - } - } - if (!valid_connection){ - CHECK_EQ(i, hole_it->size()*outer_polygon_.size()); - LOG(WARNING) << "No valid connection found! " << i << " iterations."; - ++hole_it; - continue; - } - CHECK(valid_connection); - // Perform the integration of the hole into the outer contour. - auto outer_contour_connection_vertex = outer_polygon_.vertices_begin(); - std::advance(outer_contour_connection_vertex, outer_polygon_connection_vertex_position); - auto hole_contour_connection_vertex = hole_it->vertices_begin(); - std::advance(hole_contour_connection_vertex, hole_connection_vertex_position); - CgalPolygon2d new_polygon; - // Start filling new polygon with outer contour. - for (auto vertex_it = outer_polygon_.vertices_begin(); vertex_it != outer_contour_connection_vertex; ++vertex_it){ - new_polygon.push_back(*vertex_it); - } - new_polygon.push_back(*outer_contour_connection_vertex); - auto hole_vertex_it = hole_contour_connection_vertex; - do { - new_polygon.push_back(*hole_vertex_it); - if (hole_vertex_it != std::prev(hole_it->vertices_end())){ - hole_vertex_it = std::next(hole_vertex_it); - } else { - hole_vertex_it = hole_it->vertices_begin(); - } - } while(hole_vertex_it != hole_contour_connection_vertex); - // Create new vertices next to connection points to avoid same enter and return path. - CgalSegment2d enter_connection(*outer_contour_connection_vertex, *hole_contour_connection_vertex); - Eigen::Vector2d normal_vector; - getSegmentNormalVector(enter_connection, &normal_vector); - // Check for possible intersections. - Eigen::Vector2d line_start_point(hole_contour_connection_vertex->x(), hole_contour_connection_vertex->y()); - Eigen::Vector2d direction_vector(outer_contour_connection_vertex->x() - hole_contour_connection_vertex->x(), - outer_contour_connection_vertex->y() - hole_contour_connection_vertex->y()); - auto next_vertex = std::next(outer_contour_connection_vertex); - if (next_vertex == outer_polygon_.vertices_end()){ - next_vertex = outer_polygon_.begin(); - } - Eigen::Vector2d test_point(next_vertex->x(), next_vertex->y()); - constexpr double kPointOffset = 0.0001; - Eigen::Vector2d outer_point(outer_contour_connection_vertex->x(), outer_contour_connection_vertex->y()); - if (isPointOnLeftSide(line_start_point, direction_vector, test_point)){ - Eigen::Vector2d translation_vector(next_vertex->x() - outer_contour_connection_vertex->x(), - next_vertex->y() - outer_contour_connection_vertex->y()); - translation_vector.normalize(); - outer_point += kPointOffset * translation_vector.normalized(); - } else { - outer_point += kPointOffset * normal_vector.normalized(); - } - next_vertex = hole_contour_connection_vertex; - if (next_vertex == hole_it->vertices_begin()){ - next_vertex = hole_it->vertices_end(); - next_vertex = std::prev(next_vertex); - } else { - next_vertex = std::prev(next_vertex); - } - Eigen::Vector2d hole_point(hole_contour_connection_vertex->x(), hole_contour_connection_vertex->y()); - test_point << next_vertex->x(), next_vertex->y(); - constexpr double kPiHalf = 3.1416 / 2; - if (isPointOnLeftSide(line_start_point, direction_vector, test_point) - && computeAngleBetweenVectors(test_point - line_start_point, direction_vector) < kPiHalf){ - Eigen::Vector2d translation_vector(next_vertex->x() - hole_contour_connection_vertex->x(), - next_vertex->y() - hole_contour_connection_vertex->y()); - translation_vector.normalize(); - hole_point += kPointOffset * translation_vector; - } else { - hole_point += kPointOffset * normal_vector; - } - Vector2d new_edge_direction = outer_point - hole_point; - new_edge_direction.normalize(); - constexpr double kShiftFactor = 0.0001; - bool intersection_caused = false; - CgalSegment2d new_edge(CgalPoint2d(hole_point.x() + kShiftFactor * new_edge_direction.x(), - hole_point.y() + kShiftFactor * new_edge_direction.y()),CgalPoint2d(outer_point.x() - - kShiftFactor * new_edge_direction.x(), outer_point.y() - kShiftFactor * new_edge_direction.y())); - if (!doPolygonAndSegmentIntersect(outer_polygon_, new_edge, false)){ - for (auto hole_iterator = hole_polygon_list_.begin(); hole_iterator != hole_polygon_list_.end(); ++hole_iterator){ - if (hole_iterator->size() < 3){ - continue; - } - if (doPolygonAndSegmentIntersect(*hole_iterator, new_edge, false)) { - intersection_caused = true; - break; - } - } - } else { - //std::cout << "Outer contour and connection intersect!" << std::endl; - intersection_caused = true; - } - if (intersection_caused){ - ++hole_it; - continue; - } - // Add new vertices to outer contour. - new_polygon.push_back(CgalPoint2d(hole_point.x(), hole_point.y())); - new_polygon.push_back(CgalPoint2d(outer_point.x(), outer_point.y())); - // Add remaining outer contour vertices to new polygon. - auto vertex_it = outer_contour_connection_vertex; - vertex_it = std::next(vertex_it); - for (; vertex_it != outer_polygon_.vertices_end(); ++vertex_it){ - new_polygon.push_back(*vertex_it); - } - if (!new_polygon.is_simple()){ - std::cout << "Hole orientation: " << hole_it->orientation() << std::endl; - std::cout <<"Hole vertex: " << *hole_contour_connection_vertex << std::endl; - std::cout <<"Outer vertex: " << *outer_contour_connection_vertex << std::endl; - printPolygon(new_polygon); - } - CHECK(new_polygon.is_simple()); - outer_polygon_ = new_polygon; - ++hole_it; - hole_polygon_list_.erase(std::prev(hole_it)); } } - //approximateContour(&outer_polygon_); - CHECK(outer_polygon_.is_simple()); + CgalPolygonWithHoles2d temp_polygon_with_holes(polygon_with_holes.outer_contour, + polygon_with_holes.holes.begin(), polygon_with_holes.holes.end()); + CgalPolygon2d resolved_polygon; + connect_holes(temp_polygon_with_holes, std::back_inserter (resolved_polygon.container())); + // Create offset polygon to return + constexpr double kSmallOffsetMeters = 1e-12; + std::vector> offset_polygons = CGAL::create_interior_skeleton_and_offset_polygons_2(1e-12, resolved_polygon); + CHECK_EQ(offset_polygons.size(), 1); + return **offset_polygons.begin(); +} + +void Polygonizer::approximatePolygon(CgalPolygon2d& polygon) const{ + std::vector contour; + for (const auto& vertex : polygon.container()){ + contour.emplace_back(vertex.x(), vertex.y()); + } + std::vector approx_contour; + cv::approxPolyDP(contour, approx_contour, parameters_.contour_approximation_deviation_threshold, true); +} + +CgalPolygon2d Polygonizer::runPolygonizationOnBinaryImage(const cv::Mat& binary_image) const{ + PolygonWithHoles polygon_with_holes = extractPolygonsFromBinaryImage(binary_image); + CgalPolygon2d polygon = resolveHolesWithVerticalConnection(polygon_with_holes); + approximatePolygon(polygon); + return polygon; } \ No newline at end of file diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index 41f3b3a1..27d4ea60 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -14,16 +14,14 @@ namespace sliding_window_plane_extractor{ elevation_layer_(layer_height), normal_layer_prefix_(normal_layer_prefix), parameters_(parameters), - ransac_parameters_(ransac_parameters){ + ransac_parameters_(parameters.ransac_parameters){ number_of_extracted_planes_ = -1; const grid_map::Size map_size = map.getSize(); binary_image_patch_ = cv::Mat(map_size(0), map_size(1), CV_8U, false); binary_image_angle_ = cv::Mat(map_size(0), map_size(1), CV_8U, false); - computeMapTransformation(); } - void SlidingWindowPlaneExtractor::runDetection(){ - VLOG(1) << "Starting detection!"; + void SlidingWindowPlaneExtractor::runSlidingWindowDetector(){ const grid_map::Size map_size = map_.getSize(); Eigen::Matrix normal_x(map_size(0), map_size(1)); Eigen::Matrix normal_y(map_size(0), map_size(1)); @@ -100,7 +98,6 @@ namespace sliding_window_plane_extractor{ } void SlidingWindowPlaneExtractor::runSurfaceNormalCurvatureDetection(){ - VLOG(1) << "Starting surface normal edge detection!"; CHECK(map_.exists("normals_x")); CHECK(map_.exists("normals_y")); CHECK(map_.exists("normals_z")); @@ -119,7 +116,7 @@ namespace sliding_window_plane_extractor{ const float angle_in_row_direction_radians = std::atan2(1.0, normal_vector_center.dot(normal_vector_next_row)); const double gradient_magnitude_normalized = sqrt((angle_in_col_direction_radians*angle_in_col_direction_radians) + (angle_in_row_direction_radians * angle_in_row_direction_radians)) / (sqrt(2.0)*M_PI); - binary_image_angle_.at(rows, cols) = gradient_magnitude_normalized <= parameters_.surface_normal_angle_threshold; + binary_image_angle_.at(rows, cols) = gradient_magnitude_normalized <= parameters_.surface_normal_angle_threshold_degrees; } } } @@ -152,13 +149,14 @@ namespace sliding_window_plane_extractor{ parameters_.plane_patch_error_threshold = parameters.plane_patch_error_threshold; } + /* void SlidingWindowPlaneExtractor::slidingWindowPlaneVisualization(){ Eigen::MatrixXf new_layer = Eigen::MatrixXf::Zero(map_.getSize().x(), map_.getSize().y()); cv::cv2eigen(labeled_image_, new_layer); map_.add("sliding_window_planes", new_layer); std::cout << "Added ransac plane layer!" << std::endl; } - +*/ void SlidingWindowPlaneExtractor::extractPlaneParametersFromLabeledImage(){ if (number_of_extracted_planes_ < 1){ LOG(WARNING) << "No planes detected by Sliding Window Plane Extractor!"; @@ -170,73 +168,6 @@ namespace sliding_window_plane_extractor{ } } - void SlidingWindowPlaneExtractor::generatePlanes(){ - for (int label_it = 1; label_it <= number_of_extracted_planes_; ++label_it) { - auto polygonizer_start = std::chrono::system_clock::now(); - convex_plane_extraction::Plane plane; - std::vector> contours; - std::vector hierarchy; - cv::Mat binary_image(labeled_image_.size(), CV_8UC1); - binary_image = labeled_image_ == label_it; - constexpr int kUpSamplingFactor = 3; - cv::Mat binary_image_upsampled; - cv::resize(binary_image, binary_image_upsampled, cv::Size(kUpSamplingFactor*binary_image.size().height, kUpSamplingFactor*binary_image.size().width)); - findContours(binary_image_upsampled, contours, hierarchy, - CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); - std::list> approx_contours; - int hierachy_it = 0; - for (auto& contour : contours) { - ++hierachy_it; - std::vector approx_contour; - if (contour.size() <= 10){ - approx_contour = contour; - } else { - cv::approxPolyDP(contour, approx_contour, 9, true); - } - if (approx_contour.size() <= 2) { - LOG_IF(WARNING, hierarchy[hierachy_it-1][3] < 0 && contour.size() > 4) << "Removing parental polygon since too few vertices!"; - continue; - } - convex_plane_extraction::CgalPolygon2d polygon = convex_plane_extraction::createCgalPolygonFromOpenCvPoints(approx_contour.begin(), approx_contour.end(), resolution_ / kUpSamplingFactor); - - if(!polygon.is_simple()) { - convex_plane_extraction::Vector2i index; - index << (*polygon.begin()).x(), (*polygon.begin()).y(); - LOG(WARNING) << "Polygon starting at " << index << " is not simple, will be ignored!"; - continue; - } - constexpr int kParentFlagIndex = 3; - if (hierarchy[hierachy_it-1][kParentFlagIndex] < 0) { - //convex_plane_extraction::upSampleLongEdges(&polygon); -// convex_plane_extraction::approximateContour(&polygon); - CHECK(plane.addOuterPolygon(polygon)); - } else { - CHECK(plane.addHolePolygon(polygon)); - } - } - if(plane.hasOuterContour()) { - //LOG(WARNING) << "Dropping plane, no outer contour detected!"; - computePlaneFrameFromLabeledImage(binary_image, &plane); - auto polygonizer_end = std::chrono::system_clock::now(); - auto polygonizer_duration = std::chrono::duration_cast(polygonizer_end - polygonizer_start); - polygonizer_file << time_stamp.count() << ", " << polygonizer_duration.count() << "\n"; - if(plane.isValid()) { - LOG(INFO) << "Starting resolving holes..."; - plane.resolveHoles(); - LOG(INFO) << "done."; - auto decomposer_start = std::chrono::system_clock::now(); - CHECK(plane.decomposePlaneInConvexPolygons()); - auto decomposer_end = std::chrono::system_clock::now(); - auto decomposer_duration = std::chrono::duration_cast(decomposer_end - decomposer_start); - decomposer_file << time_stamp.count() << ", " << decomposer_duration.count() << "\n"; - planes_.push_back(plane); - } else { - LOG(WARNING) << "Dropping plane, normal vector could not be inferred!"; - } - } - } - } - void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label){ CHECK(map_.exists(elevation_layer_)); CHECK(map_.exists("normals_x")); @@ -288,8 +219,8 @@ namespace sliding_window_plane_extractor{ for (const auto& plane : planes){ const std::vector& plane_point_indices = (*plane.get()).indices_of_assigned_points(); CHECK(!plane_point_indices.empty()); - Eigen::Vector3d support_vector; - Eigen::Vector3d normal_vector; + support_vector = Eigen::Vector3d::Zero(); + normal_vector = Eigen::Vector3d::Zero(); for (const auto index : plane_point_indices) { const auto &point = points_with_normal.at(index).first; const auto &normal = points_with_normal.at(index).second; @@ -307,9 +238,9 @@ namespace sliding_window_plane_extractor{ normal_vector /= static_cast(plane_point_indices.size()); const convex_plane_extraction::PlaneParameters temp_plane_parameters(normal_vector, support_vector); if (label_counter == 0) { - plane_parameters_.emplace(label, temp_plane_parameters); + label_plane_parameters_map_.emplace(label, temp_plane_parameters); } else { - plane_parameters_.emplace(number_of_extracted_planes_ + label_counter, temp_plane_parameters); + label_plane_parameters_map_.emplace(number_of_extracted_planes_ + label_counter, temp_plane_parameters); } ++label_counter; } @@ -320,7 +251,7 @@ namespace sliding_window_plane_extractor{ } if (refinement_performed){ const convex_plane_extraction::PlaneParameters temp_plane_parameters(normal_vector, support_vector); - plane_parameters_.emplace(label, temp_plane_parameters); + label_plane_parameters_map_.emplace(label, temp_plane_parameters); } } @@ -337,6 +268,24 @@ namespace sliding_window_plane_extractor{ return average_error; } + void SlidingWindowPlaneExtractor::runExtraction(){ + VLOG(1) << "Started sliding window plane detector ..."; + runSlidingWindowDetector(); + VLOG(1) << "done."; + if (parameters_.include_curvature_detection){ + VLOG(1) << "Starting surface normal curvature detection ..."; + runSurfaceNormalCurvatureDetection(); + VLOG(1) << "done."; + } + VLOG(1) << "Starting segmentation ..."; + runSegmentation(); + VLOG(1) << "done."; + VLOG(1) << "Extracting plane parameters from labeled image ..."; + extractPlaneParametersFromLabeledImage(); + VLOG(1) << "done."; + } + + /* void SlidingWindowPlaneExtractor::visualizeConvexDecomposition(jsk_recognition_msgs::PolygonArray* ros_polygon_array){ CHECK_NOTNULL(ros_polygon_array); if (planes_.empty()){ @@ -370,30 +319,6 @@ namespace sliding_window_plane_extractor{ } } } - - void SlidingWindowPlaneExtractor::exportConvexPolygons(const std::string& path) const { - std::ofstream output_file; - output_file.open(path + "convex_polygons.txt", std::ofstream::app); - std::chrono::milliseconds time_stamp = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()); - for (const auto& plane : planes_){ - for (const auto& polygon : plane.getConvexPolygons()){ - output_file << time_stamp.count() << ", "; - for (const auto& vertex : polygon){ - output_file << vertex.x() << ", "; - } - for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it){ - output_file << vertex_it->y(); - if (vertex_it != std::prev(polygon.vertices_end())){ - output_file << ", "; - } else { - output_file << "\n"; - } - } - } - } - output_file.close(); - LOG(INFO) << "Exported polygons!"; - } +*/ } From a0149efa3a703b68f78eb248e5c1d6f231295639 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Wed, 4 Mar 2020 14:15:07 +0100 Subject: [PATCH 020/504] Refactoring continued. --- .../config/parameters.yaml | 32 +++++++ .../include/convex_decomposer.hpp | 4 +- .../include/convex_plane_extraction_ros.hpp | 18 +--- .../include/pipeline.hpp | 12 ++- .../include/pipeline_ros.hpp | 20 ++++ convex_plane_decomposition/include/plane.hpp | 6 +- .../include/plane_factory.hpp | 17 ++++ .../src/convex_plane_extraction_node.cpp | 94 +------------------ .../src/convex_plane_extraction_ros.cpp | 8 +- .../src/grid_map_preprocessing.cpp | 5 +- convex_plane_decomposition/src/pipeline.cpp | 75 ++++++++------- .../src/pipeline_ros.cpp | 5 + convex_plane_decomposition/src/plane.cpp | 72 -------------- .../src/plane_factory.cpp | 65 +++++++++++++ 14 files changed, 205 insertions(+), 228 deletions(-) create mode 100644 convex_plane_decomposition/config/parameters.yaml create mode 100644 convex_plane_decomposition/include/pipeline_ros.hpp create mode 100644 convex_plane_decomposition/src/pipeline_ros.cpp diff --git a/convex_plane_decomposition/config/parameters.yaml b/convex_plane_decomposition/config/parameters.yaml new file mode 100644 index 00000000..8ef9b19c --- /dev/null +++ b/convex_plane_decomposition/config/parameters.yaml @@ -0,0 +1,32 @@ +input_map_topic: '/elevation_mapping/elevation_map' + + + +plane_factory: + plane_inclination_threshold_degrees : 70 + +polygonizer: + upsampling_factor : 3 + activate_long_edge_upsampling : false + activate_contour_approximation : false + hole_area_threshold_squared_meters : 2e-3 + +convex_decomposer: + decomposer_type : 'optimal_decompostion' + +sliding_window_plane_extractor: + kernel_size : 3 + plane_patch_error_threshold : 0.004 + surface_normal_angle_threshold_degrees : 5.0 + include_curvature_detection : false + include_ransac_refinement : false + global_plane_fit_error_threshold : 0.02 + +ransac_plane_refinement: + probability : 0.01 + min_points : 200 + epsilon : 0.004 + cluster_epsilon : 0.0282842712475 + # Set maximum normal deviation. 0.98 < dot(surface_normal, point_normal); + normal_threshold : 0.98 + diff --git a/convex_plane_decomposition/include/convex_decomposer.hpp b/convex_plane_decomposition/include/convex_decomposer.hpp index f3b5f52a..680b2b0b 100644 --- a/convex_plane_decomposition/include/convex_decomposer.hpp +++ b/convex_plane_decomposition/include/convex_decomposer.hpp @@ -22,14 +22,14 @@ class ConvexDecomposer { CgalPolygon2dContainer performConvexDecomposition(const CgalPolygon2d& polygon) const; + private: + CgalPolygon2dContainer performOptimalConvexDecomposition(const CgalPolygon2d& polygon) const; CgalPolygon2dContainer performInnerConvexApproximation(const CgalPolygon2d& polygon) const; std::multimap detectDentLocations(const CgalPolygon2d& polygon) const; - private: - ConvexDecomposerParameters parameters_; }; diff --git a/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp b/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp index a0d49bcf..dc4cbf1e 100644 --- a/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp +++ b/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp @@ -3,16 +3,14 @@ #include #include -#include - #include +#include #include -#include "export_utils.hpp" #include "grid_map_preprocessing.hpp" -#include "plane_extractor.hpp" -#include "ransac_plane_extractor.hpp" +#include "pipeline_ros.hpp" + namespace convex_plane_extraction { @@ -68,14 +66,8 @@ class ConvexPlaneExtractionROS ros::Publisher outer_contours_publisher_; - ros::Publisher hole_contours_publsiher_; - - //! Ransac plane extractor parameters. - ransac_plane_extractor::RansacPlaneExtractorParameters ransac_parameters_; - - PlaneExtractorType plane_extractor_selector_; - - sliding_window_plane_extractor::SlidingWindowParameters sliding_window_parameters_; + //! Convex Plane Extraction Pipeline. + PipelineROS pipeline_ros_; }; diff --git a/convex_plane_decomposition/include/pipeline.hpp b/convex_plane_decomposition/include/pipeline.hpp index 8a4edaae..50279600 100644 --- a/convex_plane_decomposition/include/pipeline.hpp +++ b/convex_plane_decomposition/include/pipeline.hpp @@ -11,7 +11,6 @@ struct PipelineParameters{ sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters sliding_window_plane_extractor_parameters = sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters(); PlaneFactoryParameters plane_factory_parameters_ = PlaneFactoryParameters(); - ConvexDecomposerParameters convex_decomposer_parameters = ConvexDecomposerParameters(); }; struct GridMapParameters{ @@ -25,19 +24,22 @@ struct GridMapParameters{ class Pipeline { public: - explicit Pipeline(const PipelineParameters& parameters) - : parameters_(parameters){}; + Pipeline(const PipelineParameters& pipeline_parameters, const GridMapParameters& grid_map_parameters); - void runPipeline(); + Polygon3dVectorContainer getConvexPolygons() const; + Polygon3dVectorContainer getPlaneContours() const; private: - void exportConvexPolygons(const std::string& export_path) const; +// void exportConvexPolygons(const std::string& export_path) const; PipelineParameters pipeline_parameters_; GridMapParameters grid_map_parameters_; + sliding_window_plane_extractor::SlidingWindowPlaneExtractor sliding_window_plane_extractor_; + PlaneFactory plane_factory_; + }; } // namespace_convex_plane_extraction #endif //CONVEX_PLANE_EXTRACTION__PIPELINE_HPP_ diff --git a/convex_plane_decomposition/include/pipeline_ros.hpp b/convex_plane_decomposition/include/pipeline_ros.hpp new file mode 100644 index 00000000..c082151f --- /dev/null +++ b/convex_plane_decomposition/include/pipeline_ros.hpp @@ -0,0 +1,20 @@ +#ifndef CONVEX_PLANE_EXTRACTION__PIPELINE_ROS_HPP_ +#define CONVEX_PLANE_EXTRACTION__PIPELINE_ROS_HPP_ + +#include + +#include "pipeline.hpp" + +namespace convex_plane_extraction { + +PipelineParameters loadPipelineParameters() + +class PipelineROS { + + private: + + Pipeline pipeline_; +}; + +} // namespace convex_plane_extraction +#endif //CONVEX_PLANE_EXTRACTION__PIPELINE_ROS_HPP_ diff --git a/convex_plane_decomposition/include/plane.hpp b/convex_plane_decomposition/include/plane.hpp index 80e08443..d51e7069 100644 --- a/convex_plane_decomposition/include/plane.hpp +++ b/convex_plane_decomposition/include/plane.hpp @@ -27,6 +27,10 @@ namespace convex_plane_extraction { normal_vector_(parameters.normal_vector), support_vector_(parameters.support_vector){} + PlaneParameters getPlaneParameters() const { + return PlaneParameters(normal_vector_, support_vector_); + } + bool setPlaneContour(const CgalPolygon2d& plane_contour){ plane_contour_ = plane_contour; } @@ -51,8 +55,6 @@ namespace convex_plane_extraction { return plane_contour_; } - bool isValid() const; - bool convertConvexPolygonsToWorldFrame(Polygon3dVectorContainer* output_container, const Eigen::Matrix2d& transformation, const Eigen::Vector2d& map_position) const; bool convertOuterPolygonToWorldFrame(Polygon3dVectorContainer* output_container, const Eigen::Matrix2d& transformation, const Eigen::Vector2d& map_position) const; diff --git a/convex_plane_decomposition/include/plane_factory.hpp b/convex_plane_decomposition/include/plane_factory.hpp index 5fbc2bbe..8c6e5f07 100644 --- a/convex_plane_decomposition/include/plane_factory.hpp +++ b/convex_plane_decomposition/include/plane_factory.hpp @@ -4,6 +4,7 @@ #include #include +#include "convex_decomposer.hpp" #include "plane.hpp" #include "polygonizer.hpp" @@ -11,6 +12,7 @@ namespace convex_plane_extraction { struct PlaneFactoryParameters{ PolygonizerParameters polygonizer_parameters = PolygonizerParameters(); + ConvexDecomposerParameters convex_decomposer_parameters = ConvexDecomposerParameters(); double plane_inclination_threshold_degrees = 70; }; @@ -26,12 +28,27 @@ class PlaneFactory { void createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, const int number_of_labels, const std::map& plane_parameters); + void decomposePlanesInConvexPolygons(); + + Polygon3dVectorContainer getConvexPolygonsInWorldFrame() const; + + Polygon3dVectorContainer getPlaneContoursInWorldFrame() const; + private: void computeMapTransformation(); bool isPlaneInclinationBelowThreshold(const Eigen::Vector3d& plane_normal_vector) const; + Eigen::Vector3d convertPlanePointToWorldFrame(const CgalPoint2d& point, + const PlaneParameters& plane_parameters) const; + + Polygon3dVectorContainer convertPlanePolygonsToWorldFrame(const CgalPolygon2dContainer& polygons, + const PlaneParameters& plane_parameters) const; + + Polygon3dVectorContainer convertPlanePolygonToWorldFrame(const CgalPolygon2d& polygon, + const PlaneParameters& plane_parameters) const; + // Grid map related members. grid_map::GridMap& map_; Eigen::Matrix2d transformation_xy_to_world_frame_; diff --git a/convex_plane_decomposition/src/convex_plane_extraction_node.cpp b/convex_plane_decomposition/src/convex_plane_extraction_node.cpp index 0d5112e6..c13c893b 100644 --- a/convex_plane_decomposition/src/convex_plane_extraction_node.cpp +++ b/convex_plane_decomposition/src/convex_plane_extraction_node.cpp @@ -1,11 +1,3 @@ -/* - * filters_demo_node.cpp - * - * Created on: Aug 14, 2017 - * Author: Peter Fankhauser - * Institute: ETH Zurich, ANYbotics - */ - #include "convex_plane_extraction_ros.hpp" #include @@ -16,94 +8,10 @@ int main(int argc, char** argv) FLAGS_alsologtostderr = 1; FLAGS_colorlogtostderr = 1; google::InitGoogleLogging(argv[0]); - ros::init(argc, argv, "grid_map_segmentation_demo"); + ros::init(argc, argv, "convex_plane_extraction"); ros::NodeHandle nodeHandle("~"); bool success; convex_plane_extraction::ConvexPlaneExtractionROS convex_plane_extraction_ros(nodeHandle, success); if (success) ros::spin(); return 0; } - - - - - -///* -// * filters_demo_node.cpp -// * -// * Created on: Aug 14, 2017 -// * Author: Peter Fankhauser -// * Institute: ETH Zurich, ANYbotics -// */ -// -//#include -//#include -//#include -//#include -//#include -// -//using namespace grid_map; -// -//class GridMapFilterChain -// -// -//(const grid_map_msgs::GridMapPtr& message) -//{ -// GridMap inputMap; -// GridMapRosConverter::fromMessage(message, inputMap); -// ROS_INFO("I heard: [%s]", msg->data.c_str()); -//} -// -//int main(int argc, char** argv) -//{ -// ros::init(argc, argv, "grid_map_filters_demo"); -// ros::NodeHandle nodeHandle("~"); -// ros::Subscriber subscriber = nodeHandle.subscribe("grid_map_in", 1000, chatterCallback); -// ros::Publisher publisher = nodeHandle.advertise("grid_map_out", 1, true); -// -// // Setup filter chain. -// filters::FilterChain filterChain("grid_map::GridMap"); -// if (!filterChain.configure("grid_map_filters", nodeHandle)) { -// ROS_ERROR("Could not configure the filter chain!"); -// return false; -// } -// -// // Create input grid map. -// GridMap inputMap({"elevation"}); -// inputMap.setFrameId("map"); -// inputMap.setGeometry(Length(0.7, 0.7), 0.01, Position(0.0, 0.0)); -// ROS_INFO("Created map with size %f x %f m (%i x %i cells).\n The center of the map is located at (%f, %f) in the %s frame.", -// inputMap.getLength().x(), inputMap.getLength().y(), -// inputMap.getSize()(0), inputMap.getSize()(1), -// inputMap.getPosition().x(), inputMap.getPosition().y(), inputMap.getFrameId().c_str()); -// inputMap["elevation"].setRandom(); -// inputMap["elevation"] *= 0.01; -// for (grid_map::CircleIterator iterator(inputMap, Position(0.0, 0.0), 0.15); !iterator.isPastEnd(); ++iterator) { -// inputMap.at("elevation", *iterator) = 0.1; -// } -// -// while (nodeHandle.ok()) { -// -// // Publish original grid map. -// inputMap.setTimestamp(ros::Time::now().toNSec()); -// grid_map_msgs::GridMap message; -// GridMapRosConverter::toMessage(inputMap, message); -// publisher.publish(message); -// ros::Duration(1.0).sleep(); -// -// // Apply filter chain. -// GridMap outputMap; -// if (!filterChain.update(inputMap, outputMap)) { -// ROS_ERROR("Could not update the grid map filter chain!"); -// break; -// } -// -// // Publish filtered output grid map. -// outputMap.setTimestamp(ros::Time::now().toNSec()); -// GridMapRosConverter::toMessage(outputMap, message); -// publisher.publish(message); -// ros::Duration(1.0).sleep(); -// } -// -// return 0; -//} diff --git a/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp b/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp index 699f2613..f557b084 100644 --- a/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp +++ b/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp @@ -13,8 +13,7 @@ using namespace grid_map; namespace convex_plane_extraction { ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle, bool& success) - : nodeHandle_(nodeHandle) -{ + : nodeHandle_(nodeHandle) { if (!readParameters()) { success = false; return; @@ -24,13 +23,10 @@ ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle, grid_map_publisher_ = nodeHandle_.advertise("convex_plane_extraction", 1, true); convex_polygon_publisher_ = nodeHandle_.advertise("convex_polygons", 1); outer_contours_publisher_ = nodeHandle_.advertise("outer_contours", 1); - hole_contours_publsiher_ = nodeHandle_.advertise("hole_contours", 1); success = true; } -ConvexPlaneExtractionROS::~ConvexPlaneExtractionROS() -{ -} +ConvexPlaneExtractionROS::~ConvexPlaneExtractionROS(){} bool ConvexPlaneExtractionROS::readParameters() { diff --git a/convex_plane_decomposition/src/grid_map_preprocessing.cpp b/convex_plane_decomposition/src/grid_map_preprocessing.cpp index f4dfddf6..dd57bc9f 100644 --- a/convex_plane_decomposition/src/grid_map_preprocessing.cpp +++ b/convex_plane_decomposition/src/grid_map_preprocessing.cpp @@ -1,7 +1,6 @@ -// -// Created by andrej on 12/7/19. -// + #include "grid_map_preprocessing.hpp" + namespace convex_plane_extraction{ void applyMedianFilter(Eigen::MatrixXf& elevation_map, int kernel_size) { diff --git a/convex_plane_decomposition/src/pipeline.cpp b/convex_plane_decomposition/src/pipeline.cpp index e82ae21c..56a3e03b 100644 --- a/convex_plane_decomposition/src/pipeline.cpp +++ b/convex_plane_decomposition/src/pipeline.cpp @@ -3,38 +3,49 @@ using namespace convex_plane_extraction; -void Pipeline::runPipeline() { - sliding_window_plane_extractor::SlidingWindowPlaneExtractor sliding_window_plane_extractor(grid_map_parameters_.map, - grid_map_parameters_.resolution, grid_map_parameters_.layer_height, grid_map_parameters_.normal_layer_prefix, - pipeline_parameters_.sliding_window_plane_extractor_parameters); - sliding_window_plane_extractor.runExtraction(); - PlaneFactory plane_factory(grid_map_parameters_.map, pipeline_parameters_.plane_factory_parameters_); - plane_factory.createPlanesFromLabeledImageAndPlaneParameters(sliding_window_plane_extractor.getLabeledImage(), - sliding_window_plane_extractor.getNumberOfExtractedPlanes(), sliding_window_plane_extractor.getLabelPlaneParameterMap()); +Pipeline::Pipeline(const PipelineParameters& pipeline_parameters, const GridMapParameters& grid_map_parameters) + : pipeline_parameters_(pipeline_parameters), + grid_map_parameters_(grid_map_parameters), + sliding_window_plane_extractor_(sliding_window_plane_extractor::SlidingWindowPlaneExtractor(grid_map_parameters_.map, + grid_map_parameters_.resolution, grid_map_parameters_.layer_height, grid_map_parameters_.normal_layer_prefix, + pipeline_parameters_.sliding_window_plane_extractor_parameters)), + plane_factory_(PlaneFactory(grid_map_parameters_.map, pipeline_parameters_.plane_factory_parameters_)){ + sliding_window_plane_extractor_.runExtraction(); + plane_factory_.createPlanesFromLabeledImageAndPlaneParameters(sliding_window_plane_extractor_.getLabeledImage(), + sliding_window_plane_extractor_.getNumberOfExtractedPlanes(), sliding_window_plane_extractor_.getLabelPlaneParameterMap()); + plane_factory_.decomposePlanesInConvexPolygons(); +} + +Polygon3dVectorContainer Pipeline::getConvexPolygons() const{ + return plane_factory_.getConvexPolygonsInWorldFrame(); +} +Polygon3dVectorContainer Pipeline::getPlaneContours() const{ + return plane_factory_.getPlaneContoursInWorldFrame(); } -void Pipeline::exportConvexPolygons(const std::string& export_path) const { - std::ofstream output_file; - output_file.open(export_path + "convex_polygons.txt", std::ofstream::app); - std::chrono::milliseconds time_stamp = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()); - for (const auto& plane : planes_){ - for (const auto& polygon : plane.getConvexPolygons()){ - output_file << time_stamp.count() << ", "; - for (const auto& vertex : polygon){ - output_file << vertex.x() << ", "; - } - for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it){ - output_file << vertex_it->y(); - if (vertex_it != std::prev(polygon.vertices_end())){ - output_file << ", "; - } else { - output_file << "\n"; - } - } - } - } - output_file.close(); - VLOG(1) << "Exported polygons to " << export_path << "convex_polygons.txt !"; -} \ No newline at end of file + +//void Pipeline::exportConvexPolygons(const std::string& export_path) const { +// std::ofstream output_file; +// output_file.open(export_path + "convex_polygons.txt", std::ofstream::app); +// std::chrono::milliseconds time_stamp = std::chrono::duration_cast( +// std::chrono::system_clock::now().time_since_epoch()); +// for (const auto& plane : planes_){ +// for (const auto& polygon : plane.getConvexPolygons()){ +// output_file << time_stamp.count() << ", "; +// for (const auto& vertex : polygon){ +// output_file << vertex.x() << ", "; +// } +// for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it){ +// output_file << vertex_it->y(); +// if (vertex_it != std::prev(polygon.vertices_end())){ +// output_file << ", "; +// } else { +// output_file << "\n"; +// } +// } +// } +// } +// output_file.close(); +// VLOG(1) << "Exported polygons to " << export_path << "convex_polygons.txt !"; +//} \ No newline at end of file diff --git a/convex_plane_decomposition/src/pipeline_ros.cpp b/convex_plane_decomposition/src/pipeline_ros.cpp new file mode 100644 index 00000000..82f69b7f --- /dev/null +++ b/convex_plane_decomposition/src/pipeline_ros.cpp @@ -0,0 +1,5 @@ +#include "pipeline_ros.hpp" + +using namespace convex_plane_extraction; + +PipelineParameters loadParameters() \ No newline at end of file diff --git a/convex_plane_decomposition/src/plane.cpp b/convex_plane_decomposition/src/plane.cpp index b1565257..0b7c561b 100644 --- a/convex_plane_decomposition/src/plane.cpp +++ b/convex_plane_decomposition/src/plane.cpp @@ -2,63 +2,9 @@ namespace convex_plane_extraction{ - Plane::Plane() - : initialized_(false){} - - Plane::Plane(CgalPolygon2d& outer_polygon, CgalPolygon2dContainer& holes) - : outer_polygon_(outer_polygon), - hole_polygons_(holes), - initialized_(false){} - bool Plane::setNormalAndSupportVector(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector){ - CHECK(!initialized_) << "Could not set normal and support vector of plane since already initialized!"; normal_vector_ = normal_vector; support_vector_ = support_vector; - constexpr double inclinationThreshold = 0.35; // cos(70°) - Eigen::Vector3d upwards(0,0,1); - if (abs(normal_vector.transpose()*upwards < inclinationThreshold)){ - initialized_ = false; - LOG(WARNING) << "Inclination to high, plane will be ignored!"; - } else if (!outer_polygon_.is_empty()) { - initialized_ = true; - LOG(INFO) << "Initialized plane located around support vector " << support_vector << " !"; - } - return true; - } - - bool Plane::isValid() const{ - return !outer_polygon_.is_empty() && initialized_; - } - - bool Plane::decomposePlaneInConvexPolygons(){ - if (!initialized_){ - LOG(ERROR) << "Connot perform convex decomposition of plane, since not yet initialized."; - return false; - } - performConvexDecomposition(outer_polygon_, &convex_polygons_); - return true; - } - - bool Plane::convertConvexPolygonsToWorldFrame(Polygon3dVectorContainer* output_container, const Eigen::Matrix2d& transformation, const Eigen::Vector2d& map_position) const{ - CHECK_NOTNULL(output_container); - if (convex_polygons_.empty()){ - LOG(INFO) << "No convex polygons to convert!"; - return false; - } - for (const auto& polygon : convex_polygons_){ - if (polygon.is_empty()){ - continue; - } - Polygon3d polygon_temp; - for (const auto& point : polygon){ - Vector2d point_2d_world_frame; - convertPoint2dToWorldFrame(point, &point_2d_world_frame, transformation, map_position); - Vector3d point_3d_world_frame; - computePoint3dWorldFrame(point_2d_world_frame, &point_3d_world_frame); - polygon_temp.push_back(point_3d_world_frame); - } - output_container->push_back(polygon_temp); - } return true; } @@ -103,23 +49,5 @@ namespace convex_plane_extraction{ return true; } - void Plane::convertPoint2dToWorldFrame(const CgalPoint2d& point, Vector2d* output_point, const Eigen::Matrix2d& transformation, const Eigen::Vector2d& map_position) const{ - CHECK_NOTNULL(output_point); - Eigen::Vector2d point_vector(point.x(), point.y()); - point_vector = transformation * point_vector; - point_vector = point_vector + map_position; - LOG_IF(FATAL, !std::isfinite(point_vector.x())) << "Not finite x value!"; - LOG_IF(FATAL, !std::isfinite(point_vector.y())) << "Not finite y value!"; - *output_point = point_vector; - } - - void Plane::computePoint3dWorldFrame(const Vector2d& input_point, Vector3d* output_point) const{ - CHECK_NOTNULL(output_point); - double z = (-(input_point.x() - support_vector_.x())*normal_vector_.x() - - (input_point.y() - support_vector_.y())* normal_vector_.y())/normal_vector_(2) + support_vector_(2); - LOG_IF(FATAL, !std::isfinite(z)) << "Not finite z value!"; - *output_point = Vector3d(input_point.x(), input_point.y(), z); - } - } diff --git a/convex_plane_decomposition/src/plane_factory.cpp b/convex_plane_decomposition/src/plane_factory.cpp index c659f4bb..ba5c931c 100644 --- a/convex_plane_decomposition/src/plane_factory.cpp +++ b/convex_plane_decomposition/src/plane_factory.cpp @@ -36,3 +36,68 @@ bool PlaneFactory::isPlaneInclinationBelowThreshold(const Eigen::Vector3d& plane const Eigen::Vector3d z_axis(0,0,1); return std::atan2(1.0, z_axis.dot(plane_normal_vector)) < (parameters_.plane_inclination_threshold_degrees / 180.0 * M_PI); } + +void PlaneFactory::decomposePlanesInConvexPolygons(){ + ConvexDecomposer convex_decomposer(parameters_.convex_decomposer_parameters); + for(Plane& plane : planes_){ + CgalPolygon2dContainer& convex_polygons = plane.getConvexPolygonsMutable(); + convex_polygons = convex_decomposer.performConvexDecomposition(plane.getOuterPolygon()); + } +} + +Polygon3dVectorContainer PlaneFactory::getConvexPolygonsInWorldFrame() const{ + Polygon3dVectorContainer polygon_buffer; + for(const Plane& plane : planes_){ + Polygon3dVectorContainer temp_polygon_buffer = convertPlanePolygonsToWorldFrame(plane.getConvexPolygons(), plane.getPlaneParameters()); + std::move(temp_polygon_buffer.begin(), temp_polygon_buffer.end(), std::back_inserter(polygon_buffer)); + } + return polygon_buffer; +} + +Polygon3dVectorContainer PlaneFactory::getPlaneContoursInWorldFrame() const{ + Polygon3dVectorContainer polygon_buffer; + for(const Plane& plane : planes_){ + Polygon3dVectorContainer temp_polygon_buffer = convertPlanePolygonToWorldFrame(plane.getOuterPolygon(), plane.getPlaneParameters()); + std::move(temp_polygon_buffer.begin(), temp_polygon_buffer.end(), std::back_inserter(polygon_buffer)); + } + return polygon_buffer; +} + +Polygon3dVectorContainer PlaneFactory::convertPlanePolygonToWorldFrame(const CgalPolygon2d& polygon, const PlaneParameters& plane_parameters) const{ + Polygon3dVectorContainer output_polygons; + CHECK(!polygon.is_empty()); + Polygon3d polygon_temp; + for (const auto& point : polygon){ + polygon_temp.push_back(convertPlanePointToWorldFrame(point, plane_parameters)); + } + output_polygons.push_back(polygon_temp); + return output_polygons; +} + +Polygon3dVectorContainer PlaneFactory::convertPlanePolygonsToWorldFrame(const CgalPolygon2dContainer& polygons, const PlaneParameters& plane_parameters) const{ + CHECK(!polygons.empty()) << "Input polygon container empty!"; + Polygon3dVectorContainer output_polygons; + for (const auto& polygon : polygons){ + CHECK(!polygon.is_empty()); + Polygon3d polygon_temp; + for (const auto& point : polygon){ + polygon_temp.push_back(convertPlanePointToWorldFrame(point, plane_parameters)); + } + output_polygons.push_back(polygon_temp); + } + return output_polygons; +} + +Eigen::Vector3d PlaneFactory::convertPlanePointToWorldFrame(const CgalPoint2d& point, const PlaneParameters& plane_parameters) const{ + Eigen::Vector2d temp_point(point.x(), point.y()); + temp_point = transformation_xy_to_world_frame_ * temp_point; + temp_point = temp_point + map_offset_; + LOG_IF(FATAL, !std::isfinite(temp_point.x())) << "Not finite x value!"; + LOG_IF(FATAL, !std::isfinite(temp_point.y())) << "Not finite y value!"; + const double z = (-(temp_point.x() - plane_parameters.support_vector.x())*plane_parameters.normal_vector.x() - + (temp_point.y() - plane_parameters.support_vector.y())* plane_parameters.normal_vector.y()) / + plane_parameters.normal_vector(2) + plane_parameters.support_vector(2); + LOG_IF(FATAL, !std::isfinite(z)) << "Not finite z value!"; + return Vector3d(temp_point.x(), temp_point.y(), z); +} + From 84362c75c45ccbfd9b222ee651c5171ba6f147f8 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Wed, 4 Mar 2020 22:33:07 +0100 Subject: [PATCH 021/504] Ros split. --- convex_plane_decomposition/CMakeLists.txt | 38 ++- .../include/pipeline.hpp | 14 +- .../include/pipeline_ros.hpp | 20 -- convex_plane_decomposition/include/plane.hpp | 13 - .../include/point_with_normal_container.hpp | 82 ------ .../include/polygon.hpp | 4 +- .../include/ransac_plane_extractor.hpp | 3 +- .../sliding_window_plane_extractor.hpp | 16 +- convex_plane_decomposition/package.xml | 33 --- .../src/convex_decomposer.cpp | 24 +- .../src/convex_plane_extraction_ros.cpp | 156 ------------ convex_plane_decomposition/src/pipeline.cpp | 6 +- .../src/pipeline_ros.cpp | 5 - convex_plane_decomposition/src/plane.cpp | 40 --- .../src/plane_factory.cpp | 2 +- .../src/point_with_normal_container.cpp | 37 --- convex_plane_decomposition/src/polygon.cpp | 150 +---------- .../src/polygonizer.cpp | 3 +- .../src/ransac_plane_extractor.cpp | 42 ++-- .../src/sliding_window_plane_extractor.cpp | 77 ++---- convex_plane_decomposition_ros/CMakeLists.txt | 234 ++++++++++++++++++ .../config/parameters.yaml | 6 +- .../include/convex_plane_extraction_ros.hpp | 7 +- .../include/grid_map_preprocessing.hpp | 4 +- .../include/pipeline_ros.hpp | 43 ++++ .../include/ros_visualizations.hpp | 6 +- .../launch/convex_plane_extraction.launch | 0 convex_plane_decomposition_ros/package.xml | 41 +++ .../rviz/config.rviz | 0 .../src/convex_plane_extraction_node.cpp | 2 +- .../src/convex_plane_extraction_ros.cpp | 68 +++++ .../src/grid_map_preprocessing.cpp | 0 .../src/pipeline_ros.cpp | 121 +++++++++ .../src/ros_visualizations.cpp | 11 +- 34 files changed, 640 insertions(+), 668 deletions(-) delete mode 100644 convex_plane_decomposition/include/pipeline_ros.hpp delete mode 100644 convex_plane_decomposition/include/point_with_normal_container.hpp delete mode 100644 convex_plane_decomposition/src/convex_plane_extraction_ros.cpp delete mode 100644 convex_plane_decomposition/src/pipeline_ros.cpp delete mode 100644 convex_plane_decomposition/src/point_with_normal_container.cpp create mode 100644 convex_plane_decomposition_ros/CMakeLists.txt rename {convex_plane_decomposition => convex_plane_decomposition_ros}/config/parameters.yaml (82%) rename {convex_plane_decomposition => convex_plane_decomposition_ros}/include/convex_plane_extraction_ros.hpp (89%) rename {convex_plane_decomposition => convex_plane_decomposition_ros}/include/grid_map_preprocessing.hpp (73%) create mode 100644 convex_plane_decomposition_ros/include/pipeline_ros.hpp rename {convex_plane_decomposition => convex_plane_decomposition_ros}/include/ros_visualizations.hpp (56%) rename {convex_plane_decomposition => convex_plane_decomposition_ros}/launch/convex_plane_extraction.launch (100%) create mode 100644 convex_plane_decomposition_ros/package.xml rename {convex_plane_decomposition => convex_plane_decomposition_ros}/rviz/config.rviz (100%) rename {convex_plane_decomposition => convex_plane_decomposition_ros}/src/convex_plane_extraction_node.cpp (88%) create mode 100644 convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp rename {convex_plane_decomposition => convex_plane_decomposition_ros}/src/grid_map_preprocessing.cpp (100%) create mode 100644 convex_plane_decomposition_ros/src/pipeline_ros.cpp rename {convex_plane_decomposition => convex_plane_decomposition_ros}/src/ros_visualizations.cpp (63%) diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 014b21c5..804da261 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -26,6 +26,8 @@ find_package(catkin REQUIRED COMPONENTS ## System dependencies are found with CMake's conventions find_package(CGAL QUIET) +add_definitions(-DCGAL_HAS_NO_THREADS) + find_package(OpenCV REQUIRED COMPONENTS opencv_highgui @@ -121,8 +123,21 @@ find_package(glog 0.4.0 REQUIRED) ## DEPENDS: system dependencies of this project that dependent projects also need catkin_package( INCLUDE_DIRS include -# LIBRARIES convex_plane_extraction + LIBRARIES convex_plane_extraction CATKIN_DEPENDS + roscpp + grid_map_core + grid_map_ros + grid_map_cv + grid_map_filters + grid_map_loader + grid_map_msgs + grid_map_octomap + grid_map_rviz_plugin + grid_map_visualization + geometry_msgs + sensor_msgs + cv_bridge # DEPENDS system_lib ) @@ -151,22 +166,21 @@ include_directories( ## Declare a C++ executable ## With catkin_make all packages are built within a single CMake context ## The recommended prefix ensures that target names across packages don't collide -add_executable(${PROJECT_NAME}_node - src/convex_plane_extraction_node.cpp - src/convex_plane_extraction_ros.cpp - src/plane_extractor.cpp +add_library(${PROJECT_NAME} src/ransac_plane_extractor.cpp - src/point_with_normal_container.cpp - include/types.hpp - src/grid_map_preprocessing.cpp src/sliding_window_plane_extractor.cpp src/plane.cpp src/polygon.cpp - src/ros_visualizations.cpp src/geometry_utils.cpp src/export_utils.cpp src/plane_factory.cpp - src/polygonizer.cpp src/convex_decomposer.cpp include/convex_decomposer.hpp src/pipeline.cpp include/pipeline.hpp) + src/polygonizer.cpp + src/convex_decomposer.cpp + src/pipeline.cpp) + +add_dependencies(${PROJECT_NAME} + ${catkin_EXPORTED_TARGETS} + ) ## Rename C++ executable without prefix ## The above recommended prefix causes long target names, the following renames the @@ -179,7 +193,7 @@ add_executable(${PROJECT_NAME}_node # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) ## Specify libraries to link a library or executable target against -target_link_libraries(${PROJECT_NAME}_node +target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} @@ -206,7 +220,7 @@ target_link_libraries(${PROJECT_NAME}_node # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} # ) install( - TARGETS ${PROJECT_NAME}_node + TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} diff --git a/convex_plane_decomposition/include/pipeline.hpp b/convex_plane_decomposition/include/pipeline.hpp index 50279600..a16f4069 100644 --- a/convex_plane_decomposition/include/pipeline.hpp +++ b/convex_plane_decomposition/include/pipeline.hpp @@ -10,14 +10,18 @@ namespace convex_plane_extraction { struct PipelineParameters{ sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters sliding_window_plane_extractor_parameters = sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters(); - PlaneFactoryParameters plane_factory_parameters_ = PlaneFactoryParameters(); + PlaneFactoryParameters plane_factory_parameters = PlaneFactoryParameters(); }; struct GridMapParameters{ + GridMapParameters(grid_map::GridMap& input_map, const std::string& height_layer) + : map(input_map), + resolution(input_map.getResolution()), + layer_height(height_layer){} + grid_map::GridMap& map; double resolution; - std::string& layer_height; - std::string& normal_layer_prefix; + const std::string& layer_height; }; @@ -26,6 +30,10 @@ class Pipeline { Pipeline(const PipelineParameters& pipeline_parameters, const GridMapParameters& grid_map_parameters); + const cv::Mat& getSegmentationImage() const{ + return sliding_window_plane_extractor_.getLabeledImage(); + }; + Polygon3dVectorContainer getConvexPolygons() const; Polygon3dVectorContainer getPlaneContours() const; diff --git a/convex_plane_decomposition/include/pipeline_ros.hpp b/convex_plane_decomposition/include/pipeline_ros.hpp deleted file mode 100644 index c082151f..00000000 --- a/convex_plane_decomposition/include/pipeline_ros.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION__PIPELINE_ROS_HPP_ -#define CONVEX_PLANE_EXTRACTION__PIPELINE_ROS_HPP_ - -#include - -#include "pipeline.hpp" - -namespace convex_plane_extraction { - -PipelineParameters loadPipelineParameters() - -class PipelineROS { - - private: - - Pipeline pipeline_; -}; - -} // namespace convex_plane_extraction -#endif //CONVEX_PLANE_EXTRACTION__PIPELINE_ROS_HPP_ diff --git a/convex_plane_decomposition/include/plane.hpp b/convex_plane_decomposition/include/plane.hpp index d51e7069..2747985a 100644 --- a/convex_plane_decomposition/include/plane.hpp +++ b/convex_plane_decomposition/include/plane.hpp @@ -55,15 +55,6 @@ namespace convex_plane_extraction { return plane_contour_; } - bool convertConvexPolygonsToWorldFrame(Polygon3dVectorContainer* output_container, const Eigen::Matrix2d& transformation, const Eigen::Vector2d& map_position) const; - - bool convertOuterPolygonToWorldFrame(Polygon3dVectorContainer* output_container, const Eigen::Matrix2d& transformation, const Eigen::Vector2d& map_position) const; - - bool convertHolePolygonsToWorldFrame(Polygon3dVectorContainer* output_container, const Eigen::Matrix2d& transformation, const Eigen::Vector2d& map_position) const; - - void convertPoint2dToWorldFrame(const CgalPoint2d& point, Vector2d* output_point, const Eigen::Matrix2d& transformation, const Eigen::Vector2d& map_position) const; - - void computePoint3dWorldFrame(const Vector2d& input_point, Vector3d* output_point) const; CgalPolygon2dContainer& getConvexPolygonsMutable(){ return convex_polygons_; @@ -83,10 +74,6 @@ namespace convex_plane_extraction { private: - void extractSlConcavityPointsOfHole(const CgalPolygon2d& hole, std::vector* concavity_positions); - - void slConcavityHoleVertexSorting(const CgalPolygon2d& hole, std::multimap>* concavity_positions); - CgalPolygon2d plane_contour_; CgalPolygon2dContainer convex_polygons_; diff --git a/convex_plane_decomposition/include/point_with_normal_container.hpp b/convex_plane_decomposition/include/point_with_normal_container.hpp deleted file mode 100644 index 6406953f..00000000 --- a/convex_plane_decomposition/include/point_with_normal_container.hpp +++ /dev/null @@ -1,82 +0,0 @@ -// -// Created by andrej on 11/21/19. -// - -#ifndef CONVEX_PLANE_EXTRACTION_POINTWITHNORMALCONTAINER_HPP_ -#define CONVEX_PLANE_EXTRACTION_POINTWITHNORMALCONTAINER_HPP_ - -#include - -#include -#include - -#include -#include -#include - -namespace point_with_normal_container { - // Typedefs - typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; - typedef Kernel::Point_3 Point_3D; - typedef Kernel::Vector_3 Vector_3D; - typedef std::pair PointWithNormal; - typedef std::vector PwnVector; - - struct PointIterator{ - - explicit PointIterator(std::vector::iterator c){ - it = c; - } - - Point_3D& operator* (){ - return std::get<0>(*it); - } - - PointIterator operator++ (){ - it++; - return *this; - } - - std::vector::iterator it; - }; - - class PointWithNormalContainer { - public: - - PointWithNormalContainer(); - - virtual ~PointWithNormalContainer(); - - const Point_3D& getPoint(size_t index) const; - const Vector_3D& getNormalVector(size_t index) const; - void addPointNormalPair(Eigen::Vector3d& position, Eigen::Vector3d& normal); - void addPointNormalPair(Point_3D& position, Vector_3D& normal); - - std::vector& getReference(){ - return container; - } - - // Pointer to first element in container - auto begin(); - - auto end(); - - PointIterator pointsBegin(){ - return PointIterator(container.begin()); - }; - - PointIterator pointsEnd(){ - return PointIterator(container.end()); - }; - - Point_3D& getPoint(size_t index){ - return std::get<0>(container.at(index)); - } - - private: - std::vector container; - }; - -} - -#endif //GRID_MAP_DEMOS_POINTWITHNORMALCONTAINER_HPP_ diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index c8c57a0d..fb8a1209 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -29,8 +29,8 @@ namespace convex_plane_extraction{ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Partition_traits_2 Traits; - typedef Traits::Point_2 CgalPoint2d; - typedef Traits::Vector_2 CgalVector2d; + typedef CGAL::Point_2 CgalPoint2d; + typedef CGAL::Vector_2 CgalVector2d; typedef CGAL::Polygon_2 CgalPolygon2d; typedef CGAL::Polygon_with_holes_2 CgalPolygonWithHoles2d; typedef Traits::Segment_2 CgalSegment2d; diff --git a/convex_plane_decomposition/include/ransac_plane_extractor.hpp b/convex_plane_decomposition/include/ransac_plane_extractor.hpp index ed41149e..4e527f46 100644 --- a/convex_plane_decomposition/include/ransac_plane_extractor.hpp +++ b/convex_plane_decomposition/include/ransac_plane_extractor.hpp @@ -21,7 +21,6 @@ #include "Eigen/Dense" #include -#include "grid_map_ros/grid_map_ros.hpp" namespace ransac_plane_extractor { @@ -62,7 +61,7 @@ namespace ransac_plane_extractor { void runDetection(); - const auto& getDetectedPlanes() const{ + auto getDetectedPlanes() const{ return ransac_.shapes(); }; diff --git a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp index b4619b77..f260bc6e 100644 --- a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp +++ b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp @@ -17,7 +17,6 @@ #include "plane.hpp" #include "polygon.hpp" #include "ransac_plane_extractor.hpp" -#include "ros_visualizations.hpp" namespace sliding_window_plane_extractor { @@ -36,8 +35,8 @@ namespace sliding_window_plane_extractor { class SlidingWindowPlaneExtractor{ public: - SlidingWindowPlaneExtractor(grid_map::GridMap &map, double resolution, const std::string& layer_height, - const std::string& normal_layer_prefix, const SlidingWindowPlaneExtractorParameters& parameters = SlidingWindowPlaneExtractorParameters()); + SlidingWindowPlaneExtractor(grid_map::GridMap &map, double resolution, const std::string& layer_height, const SlidingWindowPlaneExtractorParameters& parameters = SlidingWindowPlaneExtractorParameters(), + const ransac_plane_extractor::RansacPlaneExtractorParameters& ransac_parameters = ransac_plane_extractor::RansacPlaneExtractorParameters()); void setParameters(const SlidingWindowPlaneExtractorParameters& parameters); @@ -55,14 +54,6 @@ namespace sliding_window_plane_extractor { return number_of_extracted_planes_; } -// void slidingWindowPlaneVisualization(); - -// void computePlaneFrameFromLabeledImage(const cv::Mat& binary_image, convex_plane_extraction::Plane* plane); - -// void visualizeConvexDecomposition(jsk_recognition_msgs::PolygonArray* ros_polygon_array); -// -// void visualizePlaneContours(jsk_recognition_msgs::PolygonArray* outer_polygons, jsk_recognition_msgs::PolygonArray* hole_poylgons) const; -// // void exportConvexPolygons(const std::string& path) const; private: @@ -74,7 +65,7 @@ namespace sliding_window_plane_extractor { void extractPlaneParametersFromLabeledImage(); - const auto& runRansacRefinement(std::vector& points_with_normal) const; + auto runRansacRefinement(std::vector& points_with_normal) const; void runSegmentation(); @@ -85,7 +76,6 @@ namespace sliding_window_plane_extractor { grid_map::GridMap& map_; std::string elevation_layer_; - std::string normal_layer_prefix_; double resolution_; SlidingWindowPlaneExtractorParameters parameters_; diff --git a/convex_plane_decomposition/package.xml b/convex_plane_decomposition/package.xml index 3870c2f4..9a024564 100644 --- a/convex_plane_decomposition/package.xml +++ b/convex_plane_decomposition/package.xml @@ -15,39 +15,6 @@ TODO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - catkin catkin roscpp diff --git a/convex_plane_decomposition/src/convex_decomposer.cpp b/convex_plane_decomposition/src/convex_decomposer.cpp index 5f532ed9..ba1ab03f 100644 --- a/convex_plane_decomposition/src/convex_decomposer.cpp +++ b/convex_plane_decomposition/src/convex_decomposer.cpp @@ -28,13 +28,25 @@ CgalPolygon2dContainer ConvexDecomposer::performConvexDecomposition(const CgalPo } CgalPolygon2dContainer ConvexDecomposer::performOptimalConvexDecomposition(const CgalPolygon2d& polygon) const{ - CgalPolygon2dContainer output_polygons; - size_t old_container_size = output_polygons.size(); + std::vector polygon_buffer; + size_t old_container_size = polygon_buffer.size(); + Traits::Polygon_2 input_polygon; + for (const auto& vertex : polygon.container()){ + input_polygon.insert(input_polygon.vertices_end(),Traits::Point_2(vertex.x(), vertex.y())); + } CGAL::optimal_convex_partition_2(polygon.vertices_begin(), polygon.vertices_end(), - std::back_inserter(output_polygons)); - assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), polygon.vertices_end(), output_polygons.begin(), - output_polygons.end())); - CHECK_GT(output_polygons.size(), old_container_size); + std::back_inserter(polygon_buffer)); +// assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), polygon.vertices_end(), output_polygons.begin(), +// output_polygons.end())); + CHECK_GT(polygon_buffer.size(), old_container_size); + CgalPolygon2dContainer output_polygons; + for (const auto& buffer_polygon : polygon_buffer){ + CgalPolygon2d temp_polygon; + for (const auto& vertex : buffer_polygon.container()){ + temp_polygon.insert(temp_polygon.vertices_end(), CgalPoint2d(vertex.x(), vertex.y())); + } + output_polygons.push_back(temp_polygon); + } return output_polygons; } diff --git a/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp b/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp deleted file mode 100644 index f557b084..00000000 --- a/convex_plane_decomposition/src/convex_plane_extraction_ros.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include - - -#include "geometry_msgs/Point32.h" -#include "geometry_msgs/PolygonStamped.h" -#include "jsk_recognition_msgs/PolygonArray.h" - - -#include "convex_plane_extraction_ros.hpp" - -using namespace grid_map; - -namespace convex_plane_extraction { - -ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle, bool& success) - : nodeHandle_(nodeHandle) { - if (!readParameters()) { - success = false; - return; - } - - subscriber_ = nodeHandle_.subscribe(inputTopic_, 1, &ConvexPlaneExtractionROS::callback, this); - grid_map_publisher_ = nodeHandle_.advertise("convex_plane_extraction", 1, true); - convex_polygon_publisher_ = nodeHandle_.advertise("convex_polygons", 1); - outer_contours_publisher_ = nodeHandle_.advertise("outer_contours", 1); - success = true; -} - -ConvexPlaneExtractionROS::~ConvexPlaneExtractionROS(){} - -bool ConvexPlaneExtractionROS::readParameters() -{ - if (!nodeHandle_.getParam("input_topic", inputTopic_)) { - ROS_ERROR("Could not read parameter `input_topic`."); - return false; - } - if (!nodeHandle_.getParam("ransac_probability", ransac_parameters_.probability)) { - ROS_ERROR("Could not read parameter `ransac_probability`. Setting parameter to default value."); - ransac_parameters_.probability = 0.01; - } - if (!nodeHandle_.getParam("ransac_min_points", ransac_parameters_.min_points)) { - ROS_ERROR("Could not read parameter `ransac_min_points`. Setting parameter to default value."); - ransac_parameters_.min_points = 200; - } - if (!nodeHandle_.getParam("ransac_epsilon", ransac_parameters_.epsilon)) { - ROS_ERROR("Could not read parameter `ransac_epsilon`. Setting parameter to default value."); - ransac_parameters_.epsilon = 0.004; - } - if (!nodeHandle_.getParam("ransac_cluster_epsilon", ransac_parameters_.cluster_epsilon)) { - ROS_ERROR("Could not read parameter `ransac_cluster_epsilon`. Setting parameter to default value."); - ransac_parameters_.cluster_epsilon = 0.0282842712475; - } - if (!nodeHandle_.getParam("ransac_normal_threshold", ransac_parameters_.normal_threshold)) { - ROS_ERROR("Could not read parameter `ransac_normal_threshold`. Setting parameter to default value."); - ransac_parameters_.normal_threshold = 0.98; - } - if (!nodeHandle_.getParam("sliding_window_kernel_size", sliding_window_parameters_.kernel_size)) { - ROS_ERROR("Could not read parameter `sliding_window_kernel_size`. Setting parameter to default value."); - sliding_window_parameters_.kernel_size = 5; - } - if (!nodeHandle_.getParam("sliding_window_plane_error", sliding_window_parameters_.plane_error_threshold)) { - ROS_ERROR("Could not read parameter `sliding_window_plane_error`. Setting parameter to default value."); - sliding_window_parameters_.plane_error_threshold = 0.004; - } - std::string extractor_type; - if (!nodeHandle_.getParam("plane_extractor_type", extractor_type)) { - ROS_ERROR("Could not read parameter `plane_extractor_type`. Setting parameter to default value."); - return false; - } - if (extractor_type.compare("ransac") == 0){ - plane_extractor_selector_ = kRansacExtractor; - } else{ - plane_extractor_selector_ = kSlidingWindowExtractor; - } - return true; -} - -void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { - auto start_total = std::chrono::system_clock::now(); - - // Convert message to map. - ROS_INFO("Reading input map..."); - GridMap messageMap; - GridMapRosConverter::fromMessage(message, messageMap); - bool success; - GridMap inputMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(4, 4), success); - Position3 position; - inputMap.getPosition3("elevation", Index(0,0), position); - std::cout << inputMap.getPosition() << std::endl; - CHECK(success); - ROS_INFO("...done."); -// if(exportPointsWithNormalsToCsv(inputMap, "normal_vectors_", "elevation")){ -// ROS_INFO("Map exported to csv."); -// } - applyMedianFilter(inputMap.get("elevation"), 5); - // Compute planar region segmentation - ROS_INFO("Initializing plane extractor..."); - PlaneExtractor extractor(inputMap, inputMap.getResolution(), "normal_vectors_", "elevation"); - ROS_INFO("...done."); - jsk_recognition_msgs::PolygonArray ros_polygon_array; - jsk_recognition_msgs::PolygonArray ros_polygon_outer_contours; - jsk_recognition_msgs::PolygonArray ros_polygon_hole_contours; - switch (plane_extractor_selector_) { - case kRansacExtractor : { - auto start = std::chrono::system_clock::now(); - extractor.setRansacParameters(ransac_parameters_); - extractor.runRansacPlaneExtractor(); - auto end = std::chrono::system_clock::now(); - auto duration = std::chrono::duration_cast(end - start); - std::ofstream output_file; - output_file.open("/home/andrej/Desktop/computation_times_ransac_12.txt", std::ofstream::app);; - output_file << duration.count() << "\n"; - output_file.close(); - extractor.augmentMapWithRansacPlanes(); - break; - } - case kSlidingWindowExtractor : { - extractor.setSlidingWindowParameters(sliding_window_parameters_); - auto start = std::chrono::system_clock::now(); - extractor.runSlidingWindowPlaneExtractor(); - auto intermediate = std::chrono::system_clock::now(); - auto duration_intermediate = std::chrono::duration_cast(intermediate - start); - std::ofstream intermediate_runtime_file; - intermediate_runtime_file.open("/home/andrej/Desktop/computation_times_SWE_plane_detect.txt", std::ofstream::app); - intermediate_runtime_file << duration_intermediate.count() << "\n"; - intermediate_runtime_file.close(); -// extractor.augmentMapWithSlidingWindowPlanes(); - extractor.generatePlanes(); - auto end = std::chrono::system_clock::now(); - auto duration = std::chrono::duration_cast(end - start); - std::ofstream total_runtime_file; - total_runtime_file.open("/home/andrej/Desktop/computation_times_SWE_full_pipeline.txt", std::ofstream::app); - total_runtime_file << duration.count() << "\n"; - total_runtime_file.close(); - extractor.visualizeConvexDecomposition(&ros_polygon_array); - extractor.visualizePlaneContours(&ros_polygon_outer_contours, &ros_polygon_hole_contours); - break; - } - } - auto end_total = std::chrono::system_clock::now(); - auto duration_total = std::chrono::duration_cast(end_total - start_total); - std::ofstream total_file; - total_file.open("/home/andrej/Desktop/computation_times_total.txt", std::ofstream::app); - total_file << duration_total.count() << "\n"; - total_file.close(); - grid_map_msgs::GridMap outputMessage; - GridMapRosConverter::toMessage(inputMap, outputMessage); - grid_map_publisher_.publish(outputMessage); - - convex_polygon_publisher_.publish(ros_polygon_array); - outer_contours_publisher_.publish(ros_polygon_outer_contours); - hole_contours_publsiher_.publish(ros_polygon_hole_contours); - -} - -} /* namespace */ diff --git a/convex_plane_decomposition/src/pipeline.cpp b/convex_plane_decomposition/src/pipeline.cpp index 56a3e03b..7600ecff 100644 --- a/convex_plane_decomposition/src/pipeline.cpp +++ b/convex_plane_decomposition/src/pipeline.cpp @@ -7,9 +7,9 @@ Pipeline::Pipeline(const PipelineParameters& pipeline_parameters, const GridMapP : pipeline_parameters_(pipeline_parameters), grid_map_parameters_(grid_map_parameters), sliding_window_plane_extractor_(sliding_window_plane_extractor::SlidingWindowPlaneExtractor(grid_map_parameters_.map, - grid_map_parameters_.resolution, grid_map_parameters_.layer_height, grid_map_parameters_.normal_layer_prefix, - pipeline_parameters_.sliding_window_plane_extractor_parameters)), - plane_factory_(PlaneFactory(grid_map_parameters_.map, pipeline_parameters_.plane_factory_parameters_)){ + grid_map_parameters_.resolution, grid_map_parameters_.layer_height, + pipeline_parameters_.sliding_window_plane_extractor_parameters, pipeline_parameters_.sliding_window_plane_extractor_parameters.ransac_parameters)), + plane_factory_(PlaneFactory(grid_map_parameters_.map, pipeline_parameters_.plane_factory_parameters)){ sliding_window_plane_extractor_.runExtraction(); plane_factory_.createPlanesFromLabeledImageAndPlaneParameters(sliding_window_plane_extractor_.getLabeledImage(), sliding_window_plane_extractor_.getNumberOfExtractedPlanes(), sliding_window_plane_extractor_.getLabelPlaneParameterMap()); diff --git a/convex_plane_decomposition/src/pipeline_ros.cpp b/convex_plane_decomposition/src/pipeline_ros.cpp deleted file mode 100644 index 82f69b7f..00000000 --- a/convex_plane_decomposition/src/pipeline_ros.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "pipeline_ros.hpp" - -using namespace convex_plane_extraction; - -PipelineParameters loadParameters() \ No newline at end of file diff --git a/convex_plane_decomposition/src/plane.cpp b/convex_plane_decomposition/src/plane.cpp index 0b7c561b..c2fe0ed8 100644 --- a/convex_plane_decomposition/src/plane.cpp +++ b/convex_plane_decomposition/src/plane.cpp @@ -8,46 +8,6 @@ namespace convex_plane_extraction{ return true; } - bool Plane::convertOuterPolygonToWorldFrame(Polygon3dVectorContainer* output_container, const Eigen::Matrix2d& transformation, const Eigen::Vector2d& map_position) const{ - CHECK_NOTNULL(output_container); - if (outer_polygon_.is_empty()){ - LOG(INFO) << "No convex polygons to convert!"; - return false; - } - Polygon3d polygon_temp; - for (const auto& point : outer_polygon_){ - Vector2d point_2d_world_frame; - convertPoint2dToWorldFrame(point, &point_2d_world_frame, transformation, map_position); - Vector3d point_3d_world_frame; - computePoint3dWorldFrame(point_2d_world_frame, &point_3d_world_frame); - polygon_temp.push_back(point_3d_world_frame); - } - output_container->push_back(polygon_temp); - return true; - } - - bool Plane::convertHolePolygonsToWorldFrame(Polygon3dVectorContainer* output_container, const Eigen::Matrix2d& transformation, const Eigen::Vector2d& map_position) const{ - CHECK_NOTNULL(output_container); - if (hole_polygons_.empty()){ - LOG(INFO) << "No hole polygons to convert!"; - return false; - } - for (const auto& polygon : hole_polygons_){ - if (polygon.is_empty()){ - continue; - } - Polygon3d polygon_temp; - for (const auto& point : polygon){ - Vector2d point_2d_world_frame; - convertPoint2dToWorldFrame(point, &point_2d_world_frame, transformation, map_position); - Vector3d point_3d_world_frame; - computePoint3dWorldFrame(point_2d_world_frame, &point_3d_world_frame); - polygon_temp.push_back(point_3d_world_frame); - } - output_container->push_back(polygon_temp); - } - return true; - } } diff --git a/convex_plane_decomposition/src/plane_factory.cpp b/convex_plane_decomposition/src/plane_factory.cpp index ba5c931c..d969db9e 100644 --- a/convex_plane_decomposition/src/plane_factory.cpp +++ b/convex_plane_decomposition/src/plane_factory.cpp @@ -23,7 +23,7 @@ void PlaneFactory::createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& binary_image = labeled_image == label; const CgalPolygon2d plane_contour = polygonizer.runPolygonizationOnBinaryImage(binary_image); const auto plane_parameter_it = plane_parameters.find(label); - CHECK_NE(plane_parameter_it, plane_parameters.end()) << "Label not contained in plane parameter container!"; + CHECK(plane_parameter_it != plane_parameters.end()) << "Label not contained in plane parameter container!"; if (isPlaneInclinationBelowThreshold(plane_parameter_it->second.normal_vector)){ planes_.emplace_back(plane_contour, plane_parameter_it->second); } else { diff --git a/convex_plane_decomposition/src/point_with_normal_container.cpp b/convex_plane_decomposition/src/point_with_normal_container.cpp deleted file mode 100644 index 2f79cde6..00000000 --- a/convex_plane_decomposition/src/point_with_normal_container.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// Created by andrej on 11/21/19. -// - -#include "point_with_normal_container.hpp" - -namespace point_with_normal_container{ - - PointWithNormalContainer::PointWithNormalContainer() = default; - - PointWithNormalContainer::~PointWithNormalContainer() = default; - - const Point_3D& PointWithNormalContainer::getPoint(size_t index) const{ - return std::get<0>(container.at(index)); - } - - const Vector_3D& PointWithNormalContainer::getNormalVector(size_t index) const{ - return std::get<1>(container.at(index)); - } - - void PointWithNormalContainer::addPointNormalPair(Eigen::Vector3d& position, Eigen::Vector3d& normal){ - container.push_back(std::make_pair(*reinterpret_cast(const_cast(position.data())), - *reinterpret_cast(const_cast(normal.data())))); - } - - void PointWithNormalContainer::addPointNormalPair(Point_3D& position, Vector_3D& normal){ - container.push_back(std::make_pair(position, normal)); - } - - auto PointWithNormalContainer::begin(){ - return container.begin(); - } - - auto PointWithNormalContainer::end(){ - return container.end(); - } -} \ No newline at end of file diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index d75328f5..6e40c86e 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -183,132 +183,6 @@ namespace convex_plane_extraction { + (destination_point.y() - source_point.y()) * (destination_point.y() - source_point.y()))); } - std::list decomposeInnerApproximation(const CgalPolygon2d& polygon){ - CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); - std::list return_list; - std::map dent_locations; - LOG(INFO) << "Before dent detection"; - detectDentLocations(&dent_locations, polygon); - LOG(INFO) << "Passed dent detection"; - if (dent_locations.empty()){ - // No dents detected, polygon must be convex. - // CGAL convexity check might still fail, since very shallow dents are ignored. - return_list.push_back(polygon); - return return_list; - } - int dent_location = dent_locations.begin()->second; - bool intersection_clockwise_flag = false; - Intersection intersection_clockwise; - bool intersection_counterclockwise_flag = false; - Intersection intersection_counterclockwise; - intersection_clockwise_flag = intersectPolygonWithRay(dent_location, CGAL::COUNTERCLOCKWISE, - polygon, &intersection_counterclockwise); - intersection_counterclockwise_flag = intersectPolygonWithRay(dent_location, CGAL::CLOCKWISE, - polygon, &intersection_clockwise); - if (!intersection_clockwise_flag || !intersection_counterclockwise_flag ){ - LOG(FATAL) << "At least one intersection of dent ray with polygon failed!"; - } - // Generate resulting polygons from cut. - // Resulting cut from counter clockwise ray intersection. - CgalPolygon2d polygon_counterclockwise_1 = polygon; - CgalPolygon2d polygon_counterclockwise_2; - auto first_vertex_to_erase_it = polygon_counterclockwise_1.vertices_begin(); - std::advance(first_vertex_to_erase_it, dent_location); - // Add dent to second polygon. - polygon_counterclockwise_2.push_back(*first_vertex_to_erase_it); - first_vertex_to_erase_it = next(first_vertex_to_erase_it, polygon_counterclockwise_1); - auto last_vertex_to_erase_it = polygon_counterclockwise_1.vertices_begin(); - // Intersection somewhere must be at or after source vertex of intersection edge. - std::advance(last_vertex_to_erase_it, intersection_counterclockwise.edge_source_location_); - // Take next vertex due to exclusive upper limit logic. - last_vertex_to_erase_it = next(last_vertex_to_erase_it, polygon_counterclockwise_1); - // Copy vertices that will be deleted to second polygon. - copyVertices(polygon_counterclockwise_1,first_vertex_to_erase_it,last_vertex_to_erase_it, - &polygon_counterclockwise_2, polygon_counterclockwise_2.vertices_end()); - // Get last point that was erased. - CgalPoint2d point_before_intersection = *(previous(last_vertex_to_erase_it, polygon_counterclockwise_2)); - // To avoid numerical issues and duplicate vertices, intersection point is only inserted if sufficiently - // far away from exisiting vertex. - constexpr double kSquaredLengthThreshold = 1e-6; - if ((intersection_counterclockwise.intersection_point_ - point_before_intersection).squared_length() > kSquaredLengthThreshold) { - polygon_counterclockwise_2.push_back(intersection_counterclockwise.intersection_point_); - } - LOG(INFO) << "Before erase!"; - CgalPolygon2dVertexIterator element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); - // Add intersection vertex to first polygon if existing vertex too far away. - if ((intersection_counterclockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { - polygon_counterclockwise_1.insert(element_behind_deleted_it, intersection_counterclockwise.intersection_point_); - } - // Resulting cut from clockwise ray intersection. - CgalPolygon2d polygon_clockwise_1 = polygon; - CgalPolygon2d polygon_clockwise_2; - - first_vertex_to_erase_it = polygon_clockwise_1.vertices_begin(); - std::advance(first_vertex_to_erase_it, intersection_clockwise.edge_target_location_); - if ((*first_vertex_to_erase_it - intersection_clockwise.intersection_point_).squared_length() > kSquaredLengthThreshold) { - polygon_clockwise_2.push_back(intersection_clockwise.intersection_point_); - } - last_vertex_to_erase_it = polygon_clockwise_1.vertices_begin(); - std::advance(last_vertex_to_erase_it, dent_location); - copyVertices(polygon_clockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_2, - polygon_clockwise_2.vertices_end()); - polygon_clockwise_2.push_back(*last_vertex_to_erase_it); - element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_1); - LOG(INFO) << "After erase!"; - if ((intersection_clockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { - polygon_clockwise_1.insert(element_behind_deleted_it, intersection_clockwise.intersection_point_); - } - printPolygon(polygon_counterclockwise_1); - printPolygon(polygon_counterclockwise_2); - printPolygon(polygon_clockwise_1); - printPolygon(polygon_clockwise_2); - // Take the cut with smallest min. area of resulting polygons. - double area[4] = {polygon_counterclockwise_1.area(), polygon_counterclockwise_2.area(), - polygon_clockwise_1.area(), polygon_clockwise_2.area()}; - LOG(INFO) << "Passed area computation!"; - double* min_area_strategy = std::min_element(area, area+4); - std::list recursion_1; - std::list recursion_2; - if ((min_area_strategy - area) < 2){ - // In this case the counter clockwise intersection leads to less loss in area. - // Perform recursion with this split. - if(polygon_counterclockwise_1.orientation() != CGAL::COUNTERCLOCKWISE){ - LOG(WARNING) << "Polygon orientation wrong! Printing polygon ..."; - printPolygon(polygon_counterclockwise_1); - recursion_1 = std::list(); - } else { - recursion_1 = decomposeInnerApproximation(polygon_counterclockwise_1); - } - if(polygon_counterclockwise_2.orientation() != CGAL::COUNTERCLOCKWISE){ - LOG(WARNING) << "Polygon orientation wrong! Printing polygon ..."; - printPolygon(polygon_counterclockwise_2); - recursion_2 = std::list(); - } else{ - recursion_2 = decomposeInnerApproximation(polygon_counterclockwise_2); - } - } else { - // In this case the clockwise intersection leads to less loss in area. - if(polygon_clockwise_1.orientation() != CGAL::COUNTERCLOCKWISE){ - LOG(WARNING) << "Polygon orientation wrong! Printing polygon ..."; - printPolygon(polygon_clockwise_1); - recursion_1 = std::list(); - } else{ - recursion_1 = decomposeInnerApproximation(polygon_clockwise_1); - } - if(polygon_clockwise_2.orientation() != CGAL::COUNTERCLOCKWISE){ - LOG(WARNING) << "Polygon orientation wrong! Printing polygon ..."; - printPolygon(polygon_clockwise_2); - recursion_2 = std::list(); - } else{ - recursion_2 = decomposeInnerApproximation(polygon_clockwise_2); - } - } - return_list.splice(return_list.end(), recursion_1); - return_list.splice(return_list.end(), recursion_2); - LOG(INFO) << "Reached bottom!"; - return return_list; - } - // Counter-clockwise orientation: ray source vertex is previous vertex in counter-clockwise polygon orientation. bool intersectPolygonWithRay(int ray_target_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, Intersection* intersection){ @@ -416,17 +290,17 @@ namespace convex_plane_extraction { } } - void slConcavityHoleVertexSorting(const CgalPolygon2d& hole, std::multimap>* concavity_positions){ - CHECK_NOTNULL(concavity_positions); - for (auto vertex_it = hole.vertices_begin(); vertex_it != hole.vertices_end(); ++vertex_it){ - std::multimap outer_polygon_vertices; - getVertexPositionsInAscendingDistanceToPoint(outer_polygon_, *vertex_it, &outer_polygon_vertices); - for (const auto& outer_distance_vertex_pair : outer_polygon_vertices) { - concavity_positions->insert(std::pair>(outer_distance_vertex_pair.first, - std::pair(std::distance(hole.vertices_begin(), vertex_it),outer_distance_vertex_pair.second))); - } - } - } +// void slConcavityHoleVertexSorting(const CgalPolygon2d& hole, std::multimap>* concavity_positions){ +// CHECK_NOTNULL(concavity_positions); +// for (auto vertex_it = hole.vertices_begin(); vertex_it != hole.vertices_end(); ++vertex_it){ +// std::multimap outer_polygon_vertices; +// getVertexPositionsInAscendingDistanceToPoint(outer_polygon_, *vertex_it, &outer_polygon_vertices); +// for (const auto& outer_distance_vertex_pair : outer_polygon_vertices) { +// concavity_positions->insert(std::pair>(outer_distance_vertex_pair.first, +// std::pair(std::distance(hole.vertices_begin(), vertex_it),outer_distance_vertex_pair.second))); +// } +// } +// } std::pair getIndicesOfClosestVertexPair(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon){ CHECK_GT(first_polygon.size(), 0); @@ -479,6 +353,4 @@ namespace convex_plane_extraction { return false; } - CgalPolygon2d - } diff --git a/convex_plane_decomposition/src/polygonizer.cpp b/convex_plane_decomposition/src/polygonizer.cpp index e331347b..4066acfb 100644 --- a/convex_plane_decomposition/src/polygonizer.cpp +++ b/convex_plane_decomposition/src/polygonizer.cpp @@ -250,8 +250,7 @@ void Polygonizer::removeAreasNotContainedInOuterContourFromHoles(const CgalPolyg auto hole_it = holes.begin(); while(hole_it != holes.end()) { std::vector buffer; - std::vector::const_iterator buffer_it; - CGAL::intersection(outer_polygon, *hole_it, std::back_inserter(buffer_it)); + CGAL::intersection(outer_polygon, *hole_it, std::back_inserter(buffer)); if (buffer.empty()){ hole_it = holes.erase(hole_it); } else { diff --git a/convex_plane_decomposition/src/ransac_plane_extractor.cpp b/convex_plane_decomposition/src/ransac_plane_extractor.cpp index 302f85b6..7e7ce385 100644 --- a/convex_plane_decomposition/src/ransac_plane_extractor.cpp +++ b/convex_plane_decomposition/src/ransac_plane_extractor.cpp @@ -25,26 +25,26 @@ void RansacPlaneExtractor::setParameters(const RansacPlaneExtractorParameters& p parameters_.normal_threshold = parameters.normal_threshold; } -void RansacPlaneExtractor::ransacPlaneVisualization(){ - Eigen::MatrixXf plane_map = Eigen::MatrixXf::Zero(map_.getSize().x(), map_.getSize().y()); - int32_t plane_label_iterator = 1; - for (auto plane : ransac_.shapes()){ - const std::vector& plane_points = (*plane.get()).indices_of_assigned_points(); - auto plane_points_it = plane_points.begin(); - for (; plane_points_it != plane_points.end(); ++plane_points_it){ - Point_3D& point = points_with_normal_.getPoint(*plane_points_it); - Eigen::Array2i map_indices; - map_.getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); - ransac_map_(map_indices(0), map_indices(1)) = 1;//plane_label_iterator; - } - ++plane_label_iterator; - } - std::ofstream output_file; - output_file.open("/home/andrej/Desktop/number_of_planes_ransac_12.txt", std::ofstream::app);; - output_file << plane_label_iterator << "\n"; - output_file.close(); - map_.add("ransac_planes", ransac_map_); - std::cout << "Added ransac plane layer!" << std::endl; -} +//void RansacPlaneExtractor::ransacPlaneVisualization(){ +// Eigen::MatrixXf plane_map = Eigen::MatrixXf::Zero(map_.getSize().x(), map_.getSize().y()); +// int32_t plane_label_iterator = 1; +// for (auto plane : ransac_.shapes()){ +// const std::vector& plane_points = (*plane.get()).indices_of_assigned_points(); +// auto plane_points_it = plane_points.begin(); +// for (; plane_points_it != plane_points.end(); ++plane_points_it){ +// Point_3D& point = points_with_normal_.getPoint(*plane_points_it); +// Eigen::Array2i map_indices; +// map_.getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); +// ransac_map_(map_indices(0), map_indices(1)) = 1;//plane_label_iterator; +// } +// ++plane_label_iterator; +// } +// std::ofstream output_file; +// output_file.open("/home/andrej/Desktop/number_of_planes_ransac_12.txt", std::ofstream::app);; +// output_file << plane_label_iterator << "\n"; +// output_file.close(); +// map_.add("ransac_planes", ransac_map_); +// std::cout << "Added ransac plane layer!" << std::endl; +//} diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index 27d4ea60..90937b88 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -3,16 +3,12 @@ namespace sliding_window_plane_extractor{ - using namespace grid_map; - - SlidingWindowPlaneExtractor::SlidingWindowPlaneExtractor(grid_map::GridMap &map, double resolution, - const std::string& layer_height, const std::string& normal_layer_prefix, - const SlidingWindowPlaneExtractorParameters& parameters, + SlidingWindowPlaneExtractor::SlidingWindowPlaneExtractor(grid_map::GridMap& map, double resolution, + const std::string& layer_height, const SlidingWindowPlaneExtractorParameters& parameters, const ransac_plane_extractor::RansacPlaneExtractorParameters& ransac_parameters) : map_(map), resolution_(resolution), elevation_layer_(layer_height), - normal_layer_prefix_(normal_layer_prefix), parameters_(parameters), ransac_parameters_(parameters.ransac_parameters){ number_of_extracted_planes_ = -1; @@ -28,7 +24,7 @@ namespace sliding_window_plane_extractor{ Eigen::Matrix normal_z(map_size(0), map_size(1)); CHECK(map_.getSize().x() >= parameters_.kernel_size); CHECK(map_.getSize().y() >= parameters_.kernel_size); - SlidingWindowIterator window_iterator(map_, elevation_layer_, SlidingWindowIterator::EdgeHandling::INSIDE, + grid_map::SlidingWindowIterator window_iterator(map_, elevation_layer_, grid_map::SlidingWindowIterator::EdgeHandling::INSIDE, parameters_.kernel_size); for (; !window_iterator.isPastEnd(); ++window_iterator) { Eigen::MatrixXf window_data = window_iterator.getData(); @@ -64,7 +60,7 @@ namespace sliding_window_plane_extractor{ data_points.col(1) = Eigen::Map(&col_position.front(), col_position.size()) * resolution_; data_points.col(2) = Eigen::Map(&height_instances.front(), height_instances.size()); const Eigen::Matrix3d covarianceMatrix(data_points.transpose() * data_points); - Vector3 eigenvalues = Vector3::Ones(); + Eigen::Vector3d eigenvalues = Eigen::Vector3d::Ones(); Eigen::Matrix3d eigenvectors = Eigen::Matrix3d::Identity(); const Eigen::SelfAdjointEigenSolver solver(covarianceMatrix); eigenvalues = solver.eigenvalues().real(); @@ -77,11 +73,11 @@ namespace sliding_window_plane_extractor{ smallestValue = eigenvalues(j); } } - Vector3 eigenvector = eigenvectors.col(smallestId); + Eigen::Vector3d eigenvector = eigenvectors.col(smallestId); const Eigen::Vector3d normalVectorPositiveAxis_(0,0,1); if (eigenvector.dot(normalVectorPositiveAxis_) < 0.0) eigenvector = -eigenvector; Eigen::Vector3d n = eigenvector.normalized(); - Index index = *window_iterator; + grid_map::Index index = *window_iterator; double mean_error = ((data_points * n).cwiseAbs()).sum() / height_instances.size(); Eigen::Vector3d upwards(0,0,1); constexpr double kInclinationThreshold = 0.35; @@ -106,12 +102,12 @@ namespace sliding_window_plane_extractor{ const grid_map::Size map_rows_cols = map_.getSize(); for( int cols = surface_normal_map_boundary_offset; cols < map_rows_cols(1) - surface_normal_map_boundary_offset - 1; ++cols){ for (int rows = surface_normal_map_boundary_offset; rows < map_rows_cols(0) - surface_normal_map_boundary_offset - 1; ++rows){ - const Eigen::Vector2f normal_vector_center(map_.at("normals_x", Index(rows, cols)), map_.at("normals_y", Index(rows, cols)), - map_.at("normals_z", Index(rows, cols))); - const Eigen::Vector2f normal_vector_next_row(map_.at("normals_x", Index(rows+1, cols)), map_.at("normals_y", Index(rows+1, cols)), - map_.at("normals_z", Index(rows+1, cols))); - const Eigen::Vector2f normal_vector_next_col(map_.at("normals_x", Index(rows, cols+1)), map_.at("normals_y", Index(rows, cols+1)), - map_.at("normals_z", Index(rows, cols+1))); + const Eigen::Vector3f normal_vector_center(map_.at("normals_x", grid_map::Index(rows, cols)), map_.at("normals_y", grid_map::Index(rows, cols)), + map_.at("normals_z", grid_map::Index(rows, cols))); + const Eigen::Vector3f normal_vector_next_row(map_.at("normals_x", grid_map::Index(rows+1, cols)), map_.at("normals_y", grid_map::Index(rows+1, cols)), + map_.at("normals_z", grid_map::Index(rows+1, cols))); + const Eigen::Vector3f normal_vector_next_col(map_.at("normals_x", grid_map::Index(rows, cols+1)), map_.at("normals_y", grid_map::Index(rows, cols+1)), + map_.at("normals_z", grid_map::Index(rows, cols+1))); const float angle_in_col_direction_radians = std::atan2(1.0, normal_vector_center.dot(normal_vector_next_col)); const float angle_in_row_direction_radians = std::atan2(1.0, normal_vector_center.dot(normal_vector_next_row)); const double gradient_magnitude_normalized = sqrt((angle_in_col_direction_radians*angle_in_col_direction_radians) + @@ -137,7 +133,7 @@ namespace sliding_window_plane_extractor{ } // Refine connected component using RANSAC. Input vector is modified by function! - const auto& SlidingWindowPlaneExtractor::runRansacRefinement(std::vector& points_with_normal) const { + auto SlidingWindowPlaneExtractor::runRansacRefinement(std::vector& points_with_normal) const { CHECK(!points_with_normal.empty()); ransac_plane_extractor::RansacPlaneExtractor ransac_plane_extractor(points_with_normal, ransac_parameters_); ransac_plane_extractor.runDetection(); @@ -149,14 +145,6 @@ namespace sliding_window_plane_extractor{ parameters_.plane_patch_error_threshold = parameters.plane_patch_error_threshold; } - /* - void SlidingWindowPlaneExtractor::slidingWindowPlaneVisualization(){ - Eigen::MatrixXf new_layer = Eigen::MatrixXf::Zero(map_.getSize().x(), map_.getSize().y()); - cv::cv2eigen(labeled_image_, new_layer); - map_.add("sliding_window_planes", new_layer); - std::cout << "Added ransac plane layer!" << std::endl; - } -*/ void SlidingWindowPlaneExtractor::extractPlaneParametersFromLabeledImage(){ if (number_of_extracted_planes_ < 1){ LOG(WARNING) << "No planes detected by Sliding Window Plane Extractor!"; @@ -187,7 +175,7 @@ namespace sliding_window_plane_extractor{ index << row, col; Eigen::Vector3d normal_vector_temp; Eigen::Vector3d support_vector_temp; - if(map_.getVector(normal_layer_prefix_, index, normal_vector_temp)){ + if(map_.getVector("normals", index, normal_vector_temp)){ normal_vector += normal_vector_temp; ++number_of_normal_instances; } @@ -213,7 +201,7 @@ namespace sliding_window_plane_extractor{ // Compute error to fitted plane. if (computeAverageErrorToPlane(normal_vector, support_vector, points_with_normal) > parameters_.global_plane_fit_error_threshold){ - const auto& planes = runRansacRefinement(points_with_normal); + const auto planes = runRansacRefinement(points_with_normal); CHECK(!planes.empty()) << "No planes detected by RANSAC in as planar classified region."; int label_counter = 0; for (const auto& plane : planes){ @@ -285,40 +273,5 @@ namespace sliding_window_plane_extractor{ VLOG(1) << "done."; } - /* - void SlidingWindowPlaneExtractor::visualizeConvexDecomposition(jsk_recognition_msgs::PolygonArray* ros_polygon_array){ - CHECK_NOTNULL(ros_polygon_array); - if (planes_.empty()){ - LOG(INFO) << "No convex polygons to visualize!"; - return; - } - for (const auto& plane : planes_){ - convex_plane_extraction::Polygon3dVectorContainer polygon_container; - if(!plane.convertConvexPolygonsToWorldFrame(&polygon_container, transformation_xy_to_world_frame_, map_offset_)){ - continue; - } - convex_plane_extraction::addRosPolygons(polygon_container, ros_polygon_array); - } - } - - void SlidingWindowPlaneExtractor::visualizePlaneContours(jsk_recognition_msgs::PolygonArray* outer_polygons, jsk_recognition_msgs::PolygonArray* hole_poylgons) const { - CHECK_NOTNULL(outer_polygons); - CHECK_NOTNULL(hole_poylgons); - if (planes_.empty()){ - LOG(INFO) << "No convex polygons to visualize!"; - return; - } - for (const auto& plane : planes_){ - convex_plane_extraction::Polygon3dVectorContainer outer_contour; - if(plane.convertOuterPolygonToWorldFrame(&outer_contour, transformation_xy_to_world_frame_, map_offset_)){ - convex_plane_extraction::addRosPolygons(outer_contour, outer_polygons); - } - convex_plane_extraction::Polygon3dVectorContainer hole_contours; - if (plane.convertHolePolygonsToWorldFrame(&hole_contours, transformation_xy_to_world_frame_, map_offset_)){ - convex_plane_extraction::addRosPolygons(hole_contours, hole_poylgons); - } - } - } -*/ } diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt new file mode 100644 index 00000000..edfed337 --- /dev/null +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -0,0 +1,234 @@ +cmake_minimum_required(VERSION 3.1...3.15) +project(convex_plane_extraction_ros) + +## Compile as C++11, supported in ROS Kinetic and newer +set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}") + +## Find catkin macros and libraries +## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) +## is used, also find other catkin packages +find_package(catkin REQUIRED COMPONENTS + roscpp + grid_map_core + grid_map_ros + grid_map_cv + grid_map_filters + grid_map_loader + grid_map_msgs + grid_map_octomap + grid_map_rviz_plugin + grid_map_visualization + geometry_msgs + sensor_msgs + cv_bridge + convex_plane_extraction + ) + +## System dependencies are found with CMake's conventions +find_package(CGAL QUIET) + +add_definitions(-DCGAL_HAS_NO_THREADS) + +find_package(glog 0.4.0 REQUIRED) + +## Uncomment this if the package has a setup.py. This macro ensures +## modules and global scripts declared therein get installed +## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html +# catkin_python_setup() + +################################################ +## Declare ROS messages, services and actions ## +################################################ + +## To declare and build messages, services or actions from within this +## package, follow these steps: +## * Let MSG_DEP_SET be the set of packages whose message types you use in +## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). +## * In the file package.xml: +## * add a build_depend tag for "message_generation" +## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET +## * If MSG_DEP_SET isn't empty the following dependency has been pulled in +## but can be declared for certainty nonetheless: +## * add a exec_depend tag for "message_runtime" +## * In this file (CMakeLists.txt): +## * add "message_generation" and every package in MSG_DEP_SET to +## find_package(catkin REQUIRED COMPONENTS ...) +## * add "message_runtime" and every package in MSG_DEP_SET to +## catkin_package(CATKIN_DEPENDS ...) +## * uncomment the add_*_files sections below as needed +## and list every .msg/.srv/.action file to be processed +## * uncomment the generate_messages entry below +## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) + +## Generate messages in the 'msg' folder +# add_message_files( +# FILES +# Message1.msg +# Message2.msg +# ) + +## Generate services in the 'srv' folder +# add_service_files( +# FILES +# Service1.srv +# Service2.srv +# ) + +## Generate actions in the 'action' folder +# add_action_files( +# FILES +# Action1.action +# Action2.action +# ) + +## Generate added messages and services with any dependencies listed here +# generate_messages( +# DEPENDENCIES +# std_msgs # Or other packages containing msgs +# ) + +################################################ +## Declare ROS dynamic reconfigure parameters ## +################################################ + +## To declare and build dynamic reconfigure parameters within this +## package, follow these steps: +## * In the file package.xml: +## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" +## * In this file (CMakeLists.txt): +## * add "dynamic_reconfigure" to +## find_package(catkin REQUIRED COMPONENTS ...) +## * uncomment the "generate_dynamic_reconfigure_options" section below +## and list every .cfg file to be processed + +## Generate dynamic reconfigure parameters in the 'cfg' folder +# generate_dynamic_reconfigure_options( +# cfg/DynReconf1.cfg +# cfg/DynReconf2.cfg +# ) + +################################### +## catkin specific configuration ## +################################### +## The catkin_package macro generates cmake config files for your package +## Declare things to be passed to dependent projects +## INCLUDE_DIRS: uncomment this if your package contains header files +## LIBRARIES: libraries you create in this project that dependent projects also need +## CATKIN_DEPENDS: catkin_packages dependent projects also need +## DEPENDS: system dependencies of this project that dependent projects also need +catkin_package( + INCLUDE_DIRS include + # LIBRARIES convex_plane_extraction + CATKIN_DEPENDS + # DEPENDS system_lib +) + +########### +## Build ## +########### + +## Specify additional locations of header files +## Your package locations should be listed before other locations +include_directories( + include + ${catkin_INCLUDE_DIRS} +) + +## Declare a C++ library +# add_library(${PROJECT_NAME} +# src/${PROJECT_NAME}/convex_plane_extraction.cpp +# ) + +## Add cmake target dependencies of the library +## as an example, code may need to be generated before libraries +## either from message generation or dynamic reconfigure +# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Declare a C++ executable +## With catkin_make all packages are built within a single CMake context +## The recommended prefix ensures that target names across packages don't collide +add_executable(${PROJECT_NAME} + src/convex_plane_extraction_node.cpp + src/convex_plane_extraction_ros.cpp + src/grid_map_preprocessing.cpp + src/pipeline_ros.cpp + src/ros_visualizations.cpp) + +## Rename C++ executable without prefix +## The above recommended prefix causes long target names, the following renames the +## target back to the shorter version for ease of user use +## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" +# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") + +## Add cmake target dependencies of the executable +## same as for the library above +# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Specify libraries to link a library or executable target against +target_link_libraries(${PROJECT_NAME} + ${catkin_LIBRARIES} + ${CGAL_LIBRARIES} + ${CGAL_3RD_PARTY_LIBRARIES} + glog + ) + +############# +## Install ## +############# + +# all install targets should use catkin DESTINATION variables +# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html + +## Mark executable scripts (Python etc.) for installation +## in contrast to setup.py, you can choose the destination +# install(PROGRAMS +# scripts/my_python_script +# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark executables for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html +# install(TARGETS ${PROJECT_NAME}_node +# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) +install( + TARGETS ${PROJECT_NAME} + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +) + +## Mark libraries for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html +# install(TARGETS ${PROJECT_NAME} +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} +# ) + +## Mark cpp header files for installation +# install(DIRECTORY include/${PROJECT_NAME}/ +# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} +# FILES_MATCHING PATTERN "*.h" +# PATTERN ".svn" EXCLUDE +# ) + +## Mark other files for installation (e.g. launch and bag files, etc.) +# install(FILES +# # myfile1 +# # myfile2 +# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +# ) + +############# +## Testing ## +############# + +## Add gtest based cpp test target and link libraries +# catkin_add_gtest(${PROJECT_NAME}-test test/test_convex_plane_extraction.cpp) +# if(TARGET ${PROJECT_NAME}-test) +# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) +# endif() + +## Add folders to be run by python nosetests +# catkin_add_nosetests(test) \ No newline at end of file diff --git a/convex_plane_decomposition/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml similarity index 82% rename from convex_plane_decomposition/config/parameters.yaml rename to convex_plane_decomposition_ros/config/parameters.yaml index 8ef9b19c..d496c9db 100644 --- a/convex_plane_decomposition/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -1,5 +1,5 @@ -input_map_topic: '/elevation_mapping/elevation_map' - +input_map_topic : '/elevation_mapping/elevation_map' +height_layer : 'elevation' plane_factory: @@ -10,9 +10,11 @@ polygonizer: activate_long_edge_upsampling : false activate_contour_approximation : false hole_area_threshold_squared_meters : 2e-3 + contour_approximation_deviation_threshold : 0.04 convex_decomposer: decomposer_type : 'optimal_decompostion' + dent_angle_threshold_rad : 0.001 sliding_window_plane_extractor: kernel_size : 3 diff --git a/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp b/convex_plane_decomposition_ros/include/convex_plane_extraction_ros.hpp similarity index 89% rename from convex_plane_decomposition/include/convex_plane_extraction_ros.hpp rename to convex_plane_decomposition_ros/include/convex_plane_extraction_ros.hpp index dc4cbf1e..30586205 100644 --- a/convex_plane_decomposition/include/convex_plane_extraction_ros.hpp +++ b/convex_plane_decomposition_ros/include/convex_plane_extraction_ros.hpp @@ -1,3 +1,6 @@ +#ifndef CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_CONVEX_PLANE_EXTRACTION_ROS_HPP_ +#define CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_CONVEX_PLANE_EXTRACTION_ROS_HPP_ + #pragma once #include @@ -66,9 +69,7 @@ class ConvexPlaneExtractionROS ros::Publisher outer_contours_publisher_; - //! Convex Plane Extraction Pipeline. - PipelineROS pipeline_ros_; - }; } /* namespace */ +#endif \ No newline at end of file diff --git a/convex_plane_decomposition/include/grid_map_preprocessing.hpp b/convex_plane_decomposition_ros/include/grid_map_preprocessing.hpp similarity index 73% rename from convex_plane_decomposition/include/grid_map_preprocessing.hpp rename to convex_plane_decomposition_ros/include/grid_map_preprocessing.hpp index df07522b..ad2a3979 100644 --- a/convex_plane_decomposition/include/grid_map_preprocessing.hpp +++ b/convex_plane_decomposition_ros/include/grid_map_preprocessing.hpp @@ -1,5 +1,5 @@ -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_GRID_MAP_PREPROCESSING_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_GRID_MAP_PREPROCESSING_HPP_ +#ifndef CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_GRID_MAP_PREPROCESSING_HPP_ +#define CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_GRID_MAP_PREPROCESSING_HPP_ #include "Eigen/Core" #include "Eigen/Dense" diff --git a/convex_plane_decomposition_ros/include/pipeline_ros.hpp b/convex_plane_decomposition_ros/include/pipeline_ros.hpp new file mode 100644 index 00000000..84f6a10f --- /dev/null +++ b/convex_plane_decomposition_ros/include/pipeline_ros.hpp @@ -0,0 +1,43 @@ +#ifndef CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_PIPELINE_ROS_HPP_ +#define CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_PIPELINE_ROS_HPP_ + +#include +#include +#include +#include +#include + +#include "pipeline.hpp" +#include "ros_visualizations.hpp" + +namespace convex_plane_extraction { + +PipelineParameters loadPipelineParameters(ros::NodeHandle& nodeHandle, grid_map::GridMap& map); + +GridMapParameters loadGridMapParameters(ros::NodeHandle& nodeHandle, grid_map::GridMap& map){ + // Grid map parameters. + std::string height_layer; + CHECK(nodeHandle.getParam("height_layer", height_layer)); + GridMapParameters grid_map_parameters(map,height_layer); + + return grid_map_parameters; +} + +class PipelineROS { + public: + PipelineROS(ros::NodeHandle& nodeHandle, grid_map::GridMap& map) + : pipeline_(loadPipelineParameters(nodeHandle, map), loadGridMapParameters(nodeHandle, map)){} + + jsk_recognition_msgs::PolygonArray getConvexPolygons() const; + + jsk_recognition_msgs::PolygonArray getOuterPlaneContours() const; + + void augmentGridMapWithSegmentation(grid_map::GridMap& map); + + private: + + Pipeline pipeline_; +}; + +} // namespace convex_plane_extraction +#endif //CONVEX_PLANE_EXTRACTION_ROS__PIPELINE_ROS_HPP_ diff --git a/convex_plane_decomposition/include/ros_visualizations.hpp b/convex_plane_decomposition_ros/include/ros_visualizations.hpp similarity index 56% rename from convex_plane_decomposition/include/ros_visualizations.hpp rename to convex_plane_decomposition_ros/include/ros_visualizations.hpp index bb998e77..8499d4d9 100644 --- a/convex_plane_decomposition/include/ros_visualizations.hpp +++ b/convex_plane_decomposition_ros/include/ros_visualizations.hpp @@ -1,5 +1,5 @@ -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_ROS_VISUALIZATIONS_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_ROS_VISUALIZATIONS_HPP_ +#ifndef CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_ROS_VISUALIZATIONS_HPP_ +#define CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_ROS_VISUALIZATIONS_HPP_ #include #include "Eigen/Core" @@ -13,7 +13,7 @@ namespace convex_plane_extraction{ - void addRosPolygons(const Polygon3dVectorContainer& input_polygons, jsk_recognition_msgs::PolygonArray* polygon_array); + jsk_recognition_msgs::PolygonArray convertToRosPolygons(const Polygon3dVectorContainer &input_polygons); } diff --git a/convex_plane_decomposition/launch/convex_plane_extraction.launch b/convex_plane_decomposition_ros/launch/convex_plane_extraction.launch similarity index 100% rename from convex_plane_decomposition/launch/convex_plane_extraction.launch rename to convex_plane_decomposition_ros/launch/convex_plane_extraction.launch diff --git a/convex_plane_decomposition_ros/package.xml b/convex_plane_decomposition_ros/package.xml new file mode 100644 index 00000000..cf3c6112 --- /dev/null +++ b/convex_plane_decomposition_ros/package.xml @@ -0,0 +1,41 @@ + + + convex_plane_extraction_ros + 0.0.0 + The convex_plane_extraction_ros package + + + + + andrej + + + + + + TODO + + catkin + catkin + roscpp + grid_map_core + grid_map_ros + grid_map_cv + grid_map_filters + grid_map_loader + grid_map_msgs + grid_map_octomap + grid_map_rviz_plugin + grid_map_visualization + geometry_msgs + sensor_msgs + cv_bridge + convex_plane_extraction + + + + + + + + \ No newline at end of file diff --git a/convex_plane_decomposition/rviz/config.rviz b/convex_plane_decomposition_ros/rviz/config.rviz similarity index 100% rename from convex_plane_decomposition/rviz/config.rviz rename to convex_plane_decomposition_ros/rviz/config.rviz diff --git a/convex_plane_decomposition/src/convex_plane_extraction_node.cpp b/convex_plane_decomposition_ros/src/convex_plane_extraction_node.cpp similarity index 88% rename from convex_plane_decomposition/src/convex_plane_extraction_node.cpp rename to convex_plane_decomposition_ros/src/convex_plane_extraction_node.cpp index c13c893b..987d4241 100644 --- a/convex_plane_decomposition/src/convex_plane_extraction_node.cpp +++ b/convex_plane_decomposition_ros/src/convex_plane_extraction_node.cpp @@ -8,7 +8,7 @@ int main(int argc, char** argv) FLAGS_alsologtostderr = 1; FLAGS_colorlogtostderr = 1; google::InitGoogleLogging(argv[0]); - ros::init(argc, argv, "convex_plane_extraction"); + ros::init(argc, argv, "convex_plane_extraction_ros"); ros::NodeHandle nodeHandle("~"); bool success; convex_plane_extraction::ConvexPlaneExtractionROS convex_plane_extraction_ros(nodeHandle, success); diff --git a/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp b/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp new file mode 100644 index 00000000..32665192 --- /dev/null +++ b/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp @@ -0,0 +1,68 @@ +#include + +#include "convex_plane_extraction_ros.hpp" + +using namespace grid_map; + +namespace convex_plane_extraction { + +ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle, bool& success) + : nodeHandle_(nodeHandle) { + if (!readParameters()) { + success = false; + return; + } + + subscriber_ = nodeHandle_.subscribe(inputTopic_, 1, &ConvexPlaneExtractionROS::callback, this); + grid_map_publisher_ = nodeHandle_.advertise("convex_plane_extraction", 1, true); + convex_polygon_publisher_ = nodeHandle_.advertise("convex_polygons", 1); + outer_contours_publisher_ = nodeHandle_.advertise("outer_contours", 1); + success = true; +} + +ConvexPlaneExtractionROS::~ConvexPlaneExtractionROS(){} + +bool ConvexPlaneExtractionROS::readParameters() +{ + if (!nodeHandle_.getParam("input_topic", inputTopic_)) { + ROS_ERROR("Could not read parameter `input_topic`."); + return false; + } + return true; +} + +void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { + auto start_total = std::chrono::system_clock::now(); + + // Convert message to map. + ROS_INFO("Reading input map..."); + GridMap messageMap; + GridMapRosConverter::fromMessage(message, messageMap); + bool success; + GridMap inputMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(4, 4), success); + Position3 position; + inputMap.getPosition3("elevation", Index(0,0), position); + VLOG(1) << inputMap.getPosition(); + CHECK(success); + ROS_INFO("...done."); + + applyMedianFilter(inputMap.get("elevation"), 5); + + // Run pipeline. + PipelineROS pipeline_ros(nodeHandle_, inputMap); + + // Visualize in Rviz. + jsk_recognition_msgs::PolygonArray outer_plane_contours = pipeline_ros.getOuterPlaneContours(); + jsk_recognition_msgs::PolygonArray convex_polygons = pipeline_ros.getConvexPolygons(); + pipeline_ros.augmentGridMapWithSegmentation(inputMap); + + grid_map_msgs::GridMap outputMessage; + GridMapRosConverter::toMessage(inputMap, outputMessage); + grid_map_publisher_.publish(outputMessage); + + convex_polygon_publisher_.publish(convex_polygons); + outer_contours_publisher_.publish(outer_plane_contours); + +} + +} /* namespace */ diff --git a/convex_plane_decomposition/src/grid_map_preprocessing.cpp b/convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp similarity index 100% rename from convex_plane_decomposition/src/grid_map_preprocessing.cpp rename to convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp diff --git a/convex_plane_decomposition_ros/src/pipeline_ros.cpp b/convex_plane_decomposition_ros/src/pipeline_ros.cpp new file mode 100644 index 00000000..e05ac9ae --- /dev/null +++ b/convex_plane_decomposition_ros/src/pipeline_ros.cpp @@ -0,0 +1,121 @@ +#include "pipeline_ros.hpp" + +using namespace convex_plane_extraction; + +PipelineParameters loadPipelineParameters(ros::NodeHandle& nodeHandle, grid_map::GridMap& map){ + + // Grid map parameters. + GridMapParameters grid_map_parameters = loadGridMapParameters(nodeHandle, map); + + // Sliding Window Plane Extractor parameters. + sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters sliding_window_plane_extractor_parameters; + const std::string kSlidingWindowParametersPrefix = "/sliding_window_plane_extractor/"; + if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "kernel_size", sliding_window_plane_extractor_parameters.kernel_size)) { + ROS_ERROR("Could not read parameter `kernel_size`. Setting parameter to default value."); + } + if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "plane_patch_error_threshold", sliding_window_plane_extractor_parameters.plane_patch_error_threshold)) { + ROS_ERROR("Could not read parameter `plane_patch_error_threshold`. Setting parameter to default value."); + } + if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "include_curvature_detection", sliding_window_plane_extractor_parameters.include_curvature_detection)) { + ROS_ERROR("Could not read parameter `include_curvature_detection`. Setting parameter to default value."); + } + if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "include_ransac_refinement", sliding_window_plane_extractor_parameters.include_ransac_refinement)) { + ROS_ERROR("Could not read parameter `include_ransac_refinement`. Setting parameter to default value."); + } + if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "global_plane_fit_error_threshold", sliding_window_plane_extractor_parameters.global_plane_fit_error_threshold)) { + ROS_ERROR("Could not read parameter `global_plane_fit_error_threshold`. Setting parameter to default value."); + } + if(sliding_window_plane_extractor_parameters.include_ransac_refinement){ + // RASNAC refinement related parameters. + ransac_plane_extractor::RansacPlaneExtractorParameters ransac_plane_extractor_parameters; + const std::string kRansacRefinementParameterPrefix = "/ransac_plane_refinement/"; + if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "probability", ransac_plane_extractor_parameters.probability)) { + LOG(WARNING) << "Could not read parameter" << kRansacRefinementParameterPrefix << "probability. Setting parameter to default value."; + } + if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "min_points", ransac_plane_extractor_parameters.min_points)) { + LOG(WARNING) << "Could not read parameter" << kRansacRefinementParameterPrefix << "ransac_min_points. Setting parameter to default value."; + } + if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "epsilon", ransac_plane_extractor_parameters.epsilon)) { + ROS_ERROR("Could not read parameter `epsilon`. Setting parameter to default value."); + } + if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "cluster_epsilon", ransac_plane_extractor_parameters.cluster_epsilon)) { + ROS_ERROR("Could not read parameter `cluster_epsilon`. Setting parameter to default value."); + } + if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "normal_threshold", ransac_plane_extractor_parameters.normal_threshold)) { + ROS_ERROR("Could not read parameter `normal_threshold`. Setting parameter to default value."); + } + sliding_window_plane_extractor_parameters.ransac_parameters = ransac_plane_extractor_parameters; + } + + // Polygonizer parameters. + PolygonizerParameters polygonizer_parameters; + polygonizer_parameters.resolution = grid_map_parameters.resolution; + const std::string kPolygonizerParametersPrefix = "/polygonizer/"; + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "upsampling_factor", polygonizer_parameters.resolution)) { + ROS_ERROR("Could not read parameter `normal_threshold`. Setting parameter to default value."); + } + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "activate_long_edge_upsampling", polygonizer_parameters.activate_long_edge_upsampling)) { + ROS_ERROR("Could not read parameter `activate_long_edge_upsampling`. Setting parameter to default value."); + } + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "activate_contour_approximation", polygonizer_parameters.activate_contour_approximation)) { + ROS_ERROR("Could not read parameter `activate_contour_approximation`. Setting parameter to default value."); + } + if (polygonizer_parameters.activate_contour_approximation){ + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_deviation_threshold", polygonizer_parameters.contour_approximation_deviation_threshold)) { + ROS_ERROR("Could not read parameter `contour_approximation_deviation_threshold`. Setting parameter to default value."); + } + } + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "hole_area_threshold_squared_meters", polygonizer_parameters.hole_area_threshold_squared_meters)) { + ROS_ERROR("Could not read parameter `hole_area_threshold_squared_meters`. Setting parameter to default value."); + } + + // Convex decomposer parameters. + ConvexDecomposerParameters convex_decomposer_parameters; + const std::string kConvexDecomposerParametersPrefix = "/convex_decomposer/"; + std::string decomposer_type; + if (!nodeHandle.getParam(kConvexDecomposerParametersPrefix + "decomposer_type", decomposer_type)) { + ROS_ERROR("Could not read parameter `decomposer_type`. Setting parameter to default value."); + } + if(decomposer_type == "optimal_decompostion"){ + convex_decomposer_parameters.decomposition_type = ConvexDecompositionType::kGreeneOptimalDecomposition; + } else if (decomposer_type == "inner_convex_decomposition"){ + convex_decomposer_parameters.decomposition_type = ConvexDecompositionType::kInnerConvexApproximation; + } + if (!nodeHandle.getParam(kConvexDecomposerParametersPrefix + "dent_angle_threshold_rad", convex_decomposer_parameters.dent_angle_threshold_rad)) { + ROS_ERROR("Could not read parameter `dent_angle_threshold_rad`. Setting parameter to default value."); + } + + // Plane Factory parameters. + PlaneFactoryParameters plane_factory_parameters; + const std::string kPlaneFactoryParametersPrefix = "/plane_factory/"; + if (!nodeHandle.getParam(kPlaneFactoryParametersPrefix + "plane_inclination_threshold_degrees", plane_factory_parameters.plane_inclination_threshold_degrees)) { + ROS_ERROR("Could not read parameter `plane_inclination_threshold_degrees`. Setting parameter to default value."); + } + plane_factory_parameters.polygonizer_parameters = polygonizer_parameters; + plane_factory_parameters.convex_decomposer_parameters = convex_decomposer_parameters; + + // Pipeline parameters. + PipelineParameters pipeline_parameters; + pipeline_parameters.sliding_window_plane_extractor_parameters = sliding_window_plane_extractor_parameters; + pipeline_parameters.plane_factory_parameters = plane_factory_parameters; + + return pipeline_parameters; +} + +jsk_recognition_msgs::PolygonArray PipelineROS::getConvexPolygons() const{ + const Polygon3dVectorContainer convex_polygon_buffer = pipeline_.getConvexPolygons(); + return convertToRosPolygons(convex_polygon_buffer); +} + +jsk_recognition_msgs::PolygonArray PipelineROS::getOuterPlaneContours() const{ + const Polygon3dVectorContainer plane_contour_buffer = pipeline_.getPlaneContours(); + return convertToRosPolygons(plane_contour_buffer); +} + +void PipelineROS::augmentGridMapWithSegmentation(grid_map::GridMap& map){ + Eigen::MatrixXf new_layer = Eigen::MatrixXf::Zero(map.getSize().x(), map.getSize().y()); + cv::cv2eigen(pipeline_.getSegmentationImage(), new_layer); + map.add("plane_segmentation", new_layer); + VLOG(1) << "Added plane segmentation to Grid Map!"; +} + diff --git a/convex_plane_decomposition/src/ros_visualizations.cpp b/convex_plane_decomposition_ros/src/ros_visualizations.cpp similarity index 63% rename from convex_plane_decomposition/src/ros_visualizations.cpp rename to convex_plane_decomposition_ros/src/ros_visualizations.cpp index 67c6468d..765e3ea1 100644 --- a/convex_plane_decomposition/src/ros_visualizations.cpp +++ b/convex_plane_decomposition_ros/src/ros_visualizations.cpp @@ -2,10 +2,10 @@ namespace convex_plane_extraction { - void addRosPolygons(const Polygon3dVectorContainer &input_polygons, jsk_recognition_msgs::PolygonArray *polygon_array) { - - polygon_array->header.stamp = ros::Time::now(); - polygon_array->header.frame_id = "odom"; + jsk_recognition_msgs::PolygonArray convertToRosPolygons(const Polygon3dVectorContainer &input_polygons) { + jsk_recognition_msgs::PolygonArray polygon_buffer; + polygon_buffer.header.stamp = ros::Time::now(); + polygon_buffer.header.frame_id = "odom"; for (const auto &polygon : input_polygons) { if (polygon.empty()) { continue; @@ -20,8 +20,9 @@ namespace convex_plane_extraction { point_ros.z = point(2); polygon_stamped.polygon.points.push_back(point_ros); } - polygon_array->polygons.push_back(polygon_stamped); + polygon_buffer.polygons.push_back(polygon_stamped); } + return polygon_buffer; } } From f63721d0c496b8df0ba52cb56e3d9a3aa0e8f578 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Wed, 4 Mar 2020 23:15:19 +0100 Subject: [PATCH 022/504] Passed build. --- .../include/convex_plane_extraction_ros.hpp | 2 - .../include/pipeline_ros.hpp | 11 +-- .../src/pipeline_ros.cpp | 82 +++++++++++++------ 3 files changed, 57 insertions(+), 38 deletions(-) diff --git a/convex_plane_decomposition_ros/include/convex_plane_extraction_ros.hpp b/convex_plane_decomposition_ros/include/convex_plane_extraction_ros.hpp index 30586205..40c5fec4 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_extraction_ros.hpp +++ b/convex_plane_decomposition_ros/include/convex_plane_extraction_ros.hpp @@ -1,8 +1,6 @@ #ifndef CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_CONVEX_PLANE_EXTRACTION_ROS_HPP_ #define CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_CONVEX_PLANE_EXTRACTION_ROS_HPP_ -#pragma once - #include #include diff --git a/convex_plane_decomposition_ros/include/pipeline_ros.hpp b/convex_plane_decomposition_ros/include/pipeline_ros.hpp index 84f6a10f..8ba2ec8c 100644 --- a/convex_plane_decomposition_ros/include/pipeline_ros.hpp +++ b/convex_plane_decomposition_ros/include/pipeline_ros.hpp @@ -12,16 +12,9 @@ namespace convex_plane_extraction { -PipelineParameters loadPipelineParameters(ros::NodeHandle& nodeHandle, grid_map::GridMap& map); - -GridMapParameters loadGridMapParameters(ros::NodeHandle& nodeHandle, grid_map::GridMap& map){ - // Grid map parameters. - std::string height_layer; - CHECK(nodeHandle.getParam("height_layer", height_layer)); - GridMapParameters grid_map_parameters(map,height_layer); +GridMapParameters loadGridMapParameters(ros::NodeHandle& nodeHandle, grid_map::GridMap& map); - return grid_map_parameters; -} +PipelineParameters loadPipelineParameters(ros::NodeHandle& nodeHandle, grid_map::GridMap& map); class PipelineROS { public: diff --git a/convex_plane_decomposition_ros/src/pipeline_ros.cpp b/convex_plane_decomposition_ros/src/pipeline_ros.cpp index e05ac9ae..4bc56811 100644 --- a/convex_plane_decomposition_ros/src/pipeline_ros.cpp +++ b/convex_plane_decomposition_ros/src/pipeline_ros.cpp @@ -1,8 +1,8 @@ #include "pipeline_ros.hpp" -using namespace convex_plane_extraction; +namespace convex_plane_extraction { -PipelineParameters loadPipelineParameters(ros::NodeHandle& nodeHandle, grid_map::GridMap& map){ +PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map::GridMap &map) { // Grid map parameters. GridMapParameters grid_map_parameters = loadGridMapParameters(nodeHandle, map); @@ -10,38 +10,49 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle& nodeHandle, grid_map: // Sliding Window Plane Extractor parameters. sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters sliding_window_plane_extractor_parameters; const std::string kSlidingWindowParametersPrefix = "/sliding_window_plane_extractor/"; - if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "kernel_size", sliding_window_plane_extractor_parameters.kernel_size)) { + if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "kernel_size", + sliding_window_plane_extractor_parameters.kernel_size)) { ROS_ERROR("Could not read parameter `kernel_size`. Setting parameter to default value."); } - if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "plane_patch_error_threshold", sliding_window_plane_extractor_parameters.plane_patch_error_threshold)) { + if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "plane_patch_error_threshold", + sliding_window_plane_extractor_parameters.plane_patch_error_threshold)) { ROS_ERROR("Could not read parameter `plane_patch_error_threshold`. Setting parameter to default value."); } - if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "include_curvature_detection", sliding_window_plane_extractor_parameters.include_curvature_detection)) { + if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "include_curvature_detection", + sliding_window_plane_extractor_parameters.include_curvature_detection)) { ROS_ERROR("Could not read parameter `include_curvature_detection`. Setting parameter to default value."); } - if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "include_ransac_refinement", sliding_window_plane_extractor_parameters.include_ransac_refinement)) { + if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "include_ransac_refinement", + sliding_window_plane_extractor_parameters.include_ransac_refinement)) { ROS_ERROR("Could not read parameter `include_ransac_refinement`. Setting parameter to default value."); } - if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "global_plane_fit_error_threshold", sliding_window_plane_extractor_parameters.global_plane_fit_error_threshold)) { + if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "global_plane_fit_error_threshold", + sliding_window_plane_extractor_parameters.global_plane_fit_error_threshold)) { ROS_ERROR("Could not read parameter `global_plane_fit_error_threshold`. Setting parameter to default value."); } - if(sliding_window_plane_extractor_parameters.include_ransac_refinement){ + if (sliding_window_plane_extractor_parameters.include_ransac_refinement) { // RASNAC refinement related parameters. ransac_plane_extractor::RansacPlaneExtractorParameters ransac_plane_extractor_parameters; const std::string kRansacRefinementParameterPrefix = "/ransac_plane_refinement/"; - if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "probability", ransac_plane_extractor_parameters.probability)) { - LOG(WARNING) << "Could not read parameter" << kRansacRefinementParameterPrefix << "probability. Setting parameter to default value."; + if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "probability", + ransac_plane_extractor_parameters.probability)) { + LOG(WARNING) << "Could not read parameter" << kRansacRefinementParameterPrefix + << "probability. Setting parameter to default value."; } - if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "min_points", ransac_plane_extractor_parameters.min_points)) { - LOG(WARNING) << "Could not read parameter" << kRansacRefinementParameterPrefix << "ransac_min_points. Setting parameter to default value."; + if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "min_points", + ransac_plane_extractor_parameters.min_points)) { + LOG(WARNING) << "Could not read parameter" << kRansacRefinementParameterPrefix + << "ransac_min_points. Setting parameter to default value."; } if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "epsilon", ransac_plane_extractor_parameters.epsilon)) { ROS_ERROR("Could not read parameter `epsilon`. Setting parameter to default value."); } - if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "cluster_epsilon", ransac_plane_extractor_parameters.cluster_epsilon)) { + if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "cluster_epsilon", + ransac_plane_extractor_parameters.cluster_epsilon)) { ROS_ERROR("Could not read parameter `cluster_epsilon`. Setting parameter to default value."); } - if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "normal_threshold", ransac_plane_extractor_parameters.normal_threshold)) { + if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "normal_threshold", + ransac_plane_extractor_parameters.normal_threshold)) { ROS_ERROR("Could not read parameter `normal_threshold`. Setting parameter to default value."); } sliding_window_plane_extractor_parameters.ransac_parameters = ransac_plane_extractor_parameters; @@ -54,18 +65,23 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle& nodeHandle, grid_map: if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "upsampling_factor", polygonizer_parameters.resolution)) { ROS_ERROR("Could not read parameter `normal_threshold`. Setting parameter to default value."); } - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "activate_long_edge_upsampling", polygonizer_parameters.activate_long_edge_upsampling)) { + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "activate_long_edge_upsampling", + polygonizer_parameters.activate_long_edge_upsampling)) { ROS_ERROR("Could not read parameter `activate_long_edge_upsampling`. Setting parameter to default value."); } - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "activate_contour_approximation", polygonizer_parameters.activate_contour_approximation)) { + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "activate_contour_approximation", + polygonizer_parameters.activate_contour_approximation)) { ROS_ERROR("Could not read parameter `activate_contour_approximation`. Setting parameter to default value."); } - if (polygonizer_parameters.activate_contour_approximation){ - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_deviation_threshold", polygonizer_parameters.contour_approximation_deviation_threshold)) { - ROS_ERROR("Could not read parameter `contour_approximation_deviation_threshold`. Setting parameter to default value."); + if (polygonizer_parameters.activate_contour_approximation) { + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_deviation_threshold", + polygonizer_parameters.contour_approximation_deviation_threshold)) { + ROS_ERROR( + "Could not read parameter `contour_approximation_deviation_threshold`. Setting parameter to default value."); } } - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "hole_area_threshold_squared_meters", polygonizer_parameters.hole_area_threshold_squared_meters)) { + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "hole_area_threshold_squared_meters", + polygonizer_parameters.hole_area_threshold_squared_meters)) { ROS_ERROR("Could not read parameter `hole_area_threshold_squared_meters`. Setting parameter to default value."); } @@ -76,19 +92,21 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle& nodeHandle, grid_map: if (!nodeHandle.getParam(kConvexDecomposerParametersPrefix + "decomposer_type", decomposer_type)) { ROS_ERROR("Could not read parameter `decomposer_type`. Setting parameter to default value."); } - if(decomposer_type == "optimal_decompostion"){ + if (decomposer_type == "optimal_decompostion") { convex_decomposer_parameters.decomposition_type = ConvexDecompositionType::kGreeneOptimalDecomposition; - } else if (decomposer_type == "inner_convex_decomposition"){ + } else if (decomposer_type == "inner_convex_decomposition") { convex_decomposer_parameters.decomposition_type = ConvexDecompositionType::kInnerConvexApproximation; } - if (!nodeHandle.getParam(kConvexDecomposerParametersPrefix + "dent_angle_threshold_rad", convex_decomposer_parameters.dent_angle_threshold_rad)) { + if (!nodeHandle.getParam(kConvexDecomposerParametersPrefix + "dent_angle_threshold_rad", + convex_decomposer_parameters.dent_angle_threshold_rad)) { ROS_ERROR("Could not read parameter `dent_angle_threshold_rad`. Setting parameter to default value."); } // Plane Factory parameters. PlaneFactoryParameters plane_factory_parameters; const std::string kPlaneFactoryParametersPrefix = "/plane_factory/"; - if (!nodeHandle.getParam(kPlaneFactoryParametersPrefix + "plane_inclination_threshold_degrees", plane_factory_parameters.plane_inclination_threshold_degrees)) { + if (!nodeHandle.getParam(kPlaneFactoryParametersPrefix + "plane_inclination_threshold_degrees", + plane_factory_parameters.plane_inclination_threshold_degrees)) { ROS_ERROR("Could not read parameter `plane_inclination_threshold_degrees`. Setting parameter to default value."); } plane_factory_parameters.polygonizer_parameters = polygonizer_parameters; @@ -102,20 +120,30 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle& nodeHandle, grid_map: return pipeline_parameters; } -jsk_recognition_msgs::PolygonArray PipelineROS::getConvexPolygons() const{ +GridMapParameters loadGridMapParameters(ros::NodeHandle &nodeHandle, grid_map::GridMap &map) { + // Grid map parameters. + std::string height_layer; + CHECK(nodeHandle.getParam("height_layer", height_layer)); + GridMapParameters grid_map_parameters(map, height_layer); + + return grid_map_parameters; +} + +jsk_recognition_msgs::PolygonArray PipelineROS::getConvexPolygons() const { const Polygon3dVectorContainer convex_polygon_buffer = pipeline_.getConvexPolygons(); return convertToRosPolygons(convex_polygon_buffer); } -jsk_recognition_msgs::PolygonArray PipelineROS::getOuterPlaneContours() const{ +jsk_recognition_msgs::PolygonArray PipelineROS::getOuterPlaneContours() const { const Polygon3dVectorContainer plane_contour_buffer = pipeline_.getPlaneContours(); return convertToRosPolygons(plane_contour_buffer); } -void PipelineROS::augmentGridMapWithSegmentation(grid_map::GridMap& map){ +void PipelineROS::augmentGridMapWithSegmentation(grid_map::GridMap &map) { Eigen::MatrixXf new_layer = Eigen::MatrixXf::Zero(map.getSize().x(), map.getSize().y()); cv::cv2eigen(pipeline_.getSegmentationImage(), new_layer); map.add("plane_segmentation", new_layer); VLOG(1) << "Added plane segmentation to Grid Map!"; } +} \ No newline at end of file From 9b133a8a8f9b4341b8b41b2f9b1f42ea5a7e1f07 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Thu, 5 Mar 2020 14:46:10 +0100 Subject: [PATCH 023/504] Diverse fixes. --- .../include/pipeline.hpp | 2 +- .../src/convex_decomposer.cpp | 7 ++-- convex_plane_decomposition/src/pipeline.cpp | 8 +++-- .../src/plane_factory.cpp | 5 ++- .../src/polygonizer.cpp | 14 +++++--- .../src/sliding_window_plane_extractor.cpp | 32 +++++++++++++------ .../config/parameters.yaml | 6 ++-- .../launch/convex_plane_extraction.launch | 15 ++------- .../rviz/config.rviz | 6 ++-- .../src/convex_plane_extraction_node.cpp | 1 + .../src/convex_plane_extraction_ros.cpp | 10 +++--- .../src/pipeline_ros.cpp | 17 ++++++---- 12 files changed, 70 insertions(+), 53 deletions(-) diff --git a/convex_plane_decomposition/include/pipeline.hpp b/convex_plane_decomposition/include/pipeline.hpp index a16f4069..d0a97920 100644 --- a/convex_plane_decomposition/include/pipeline.hpp +++ b/convex_plane_decomposition/include/pipeline.hpp @@ -21,7 +21,7 @@ struct GridMapParameters{ grid_map::GridMap& map; double resolution; - const std::string& layer_height; + std::string layer_height; }; diff --git a/convex_plane_decomposition/src/convex_decomposer.cpp b/convex_plane_decomposition/src/convex_decomposer.cpp index ba1ab03f..13e38836 100644 --- a/convex_plane_decomposition/src/convex_decomposer.cpp +++ b/convex_plane_decomposition/src/convex_decomposer.cpp @@ -6,10 +6,13 @@ ConvexDecomposer::ConvexDecomposer(const convex_plane_extraction::ConvexDecompos :parameters_(parameters){} CgalPolygon2dContainer ConvexDecomposer::performConvexDecomposition(const CgalPolygon2d& polygon) const { - CHECK_GE(polygon.size(), 3); - CHECK(polygon.is_simple()); VLOG(1) << "Started convex decomposition..."; CgalPolygon2dContainer convex_polygons; + if (polygon.size() == 2) { + convex_polygons.push_back(polygon); + return convex_polygons; + } + CHECK(polygon.is_simple()); if(polygon.is_convex()){ LOG(INFO) << "Polygon already convex, no decompostion performed."; convex_polygons.push_back(polygon); diff --git a/convex_plane_decomposition/src/pipeline.cpp b/convex_plane_decomposition/src/pipeline.cpp index 7600ecff..36d8d53a 100644 --- a/convex_plane_decomposition/src/pipeline.cpp +++ b/convex_plane_decomposition/src/pipeline.cpp @@ -6,11 +6,13 @@ using namespace convex_plane_extraction; Pipeline::Pipeline(const PipelineParameters& pipeline_parameters, const GridMapParameters& grid_map_parameters) : pipeline_parameters_(pipeline_parameters), grid_map_parameters_(grid_map_parameters), - sliding_window_plane_extractor_(sliding_window_plane_extractor::SlidingWindowPlaneExtractor(grid_map_parameters_.map, + sliding_window_plane_extractor_(grid_map_parameters_.map, grid_map_parameters_.resolution, grid_map_parameters_.layer_height, - pipeline_parameters_.sliding_window_plane_extractor_parameters, pipeline_parameters_.sliding_window_plane_extractor_parameters.ransac_parameters)), - plane_factory_(PlaneFactory(grid_map_parameters_.map, pipeline_parameters_.plane_factory_parameters)){ + pipeline_parameters_.sliding_window_plane_extractor_parameters, pipeline_parameters_.sliding_window_plane_extractor_parameters.ransac_parameters), + plane_factory_(grid_map_parameters_.map, pipeline_parameters_.plane_factory_parameters){ + VLOG(1) << "Starting plane extraction..."; sliding_window_plane_extractor_.runExtraction(); + VLOG(1) << "done"; plane_factory_.createPlanesFromLabeledImageAndPlaneParameters(sliding_window_plane_extractor_.getLabeledImage(), sliding_window_plane_extractor_.getNumberOfExtractedPlanes(), sliding_window_plane_extractor_.getLabelPlaneParameterMap()); plane_factory_.decomposePlanesInConvexPolygons(); diff --git a/convex_plane_decomposition/src/plane_factory.cpp b/convex_plane_decomposition/src/plane_factory.cpp index d969db9e..375c9922 100644 --- a/convex_plane_decomposition/src/plane_factory.cpp +++ b/convex_plane_decomposition/src/plane_factory.cpp @@ -16,9 +16,12 @@ void PlaneFactory::computeMapTransformation(){ void PlaneFactory::createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, const int number_of_labels, const std::map& plane_parameters){ CHECK_GT(number_of_labels, 0); - CHECK_EQ(number_of_labels, plane_parameters.size()); + //CHECK_EQ(number_of_labels, plane_parameters.size()); Polygonizer polygonizer(parameters_.polygonizer_parameters); for (int label = 1; label < number_of_labels; ++label){ + if (plane_parameters.find(label) == plane_parameters.end()){ + continue; + } cv::Mat binary_image(labeled_image.size(), CV_8UC1); binary_image = labeled_image == label; const CgalPolygon2d plane_contour = polygonizer.runPolygonizationOnBinaryImage(binary_image); diff --git a/convex_plane_decomposition/src/polygonizer.cpp b/convex_plane_decomposition/src/polygonizer.cpp index 4066acfb..7db14262 100644 --- a/convex_plane_decomposition/src/polygonizer.cpp +++ b/convex_plane_decomposition/src/polygonizer.cpp @@ -32,7 +32,7 @@ PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& bina CgalPolygon2d polygon = convex_plane_extraction::createCgalPolygonFromOpenCvPoints( approx_contour.begin(), approx_contour.end(), - parameters_.resolution / parameters_.upsampling_factor); + parameters_.resolution / static_cast(parameters_.upsampling_factor)); if (!polygon.is_simple()) { convex_plane_extraction::Vector2i index; @@ -46,7 +46,7 @@ PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& bina upSampleLongEdges(&polygon); } if (parameters_.activate_contour_approximation) { - approximateContour(&polygon); + //approximateContour(&polygon); } plane_polygons.outer_contour = polygon; } else { @@ -301,12 +301,16 @@ CgalPolygon2d Polygonizer::resolveHolesWithVerticalConnection(PolygonWithHoles& } void Polygonizer::approximatePolygon(CgalPolygon2d& polygon) const{ - std::vector contour; + std::vector contour; for (const auto& vertex : polygon.container()){ - contour.emplace_back(vertex.x(), vertex.y()); + contour.emplace_back(vertex.y(), vertex.x()); } - std::vector approx_contour; + std::vector approx_contour; cv::approxPolyDP(contour, approx_contour, parameters_.contour_approximation_deviation_threshold, true); + polygon.clear(); + for (const auto& point : approx_contour){ + polygon.push_back(CgalPoint2d(point.y, point.x)); + } } CgalPolygon2d Polygonizer::runPolygonizationOnBinaryImage(const cv::Mat& binary_image) const{ diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index 90937b88..ee8075c8 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -11,10 +11,14 @@ namespace sliding_window_plane_extractor{ elevation_layer_(layer_height), parameters_(parameters), ransac_parameters_(parameters.ransac_parameters){ + VLOG(1) << "Constructing SWE..."; + VLOG(1) << "Set elevation layer is: " << elevation_layer_; + CHECK(map_.exists(elevation_layer_)); number_of_extracted_planes_ = -1; const grid_map::Size map_size = map.getSize(); binary_image_patch_ = cv::Mat(map_size(0), map_size(1), CV_8U, false); binary_image_angle_ = cv::Mat(map_size(0), map_size(1), CV_8U, false); + VLOG(1) << "done."; } void SlidingWindowPlaneExtractor::runSlidingWindowDetector(){ @@ -175,18 +179,25 @@ namespace sliding_window_plane_extractor{ index << row, col; Eigen::Vector3d normal_vector_temp; Eigen::Vector3d support_vector_temp; - if(map_.getVector("normals", index, normal_vector_temp)){ + if(map_.getVector("normals_", index, normal_vector_temp)) { normal_vector += normal_vector_temp; ++number_of_normal_instances; + if (map_.getPosition3(elevation_layer_, index, support_vector_temp)) { + support_vector += support_vector_temp; + ++number_of_position_instances; + + ransac_plane_extractor::PointWithNormal + point_with_normal = std::make_pair( + ransac_plane_extractor::Point3D(support_vector_temp.x(), + support_vector_temp.y(), + support_vector_temp.z()), + ransac_plane_extractor::Vector3D(normal_vector_temp.x(), + normal_vector_temp.y(), + normal_vector_temp.z())); + points_with_normal.push_back(point_with_normal); + } } - if (map_.getPosition3(elevation_layer_, index, support_vector_temp)) { - support_vector += support_vector_temp; - ++number_of_position_instances; - } - ransac_plane_extractor::PointWithNormal point_with_normal = std::make_pair(ransac_plane_extractor::Point3D(support_vector_temp.x(), support_vector_temp.y(), support_vector_temp.z()), - ransac_plane_extractor::Vector3D(normal_vector_temp.x(), normal_vector_temp.y(), normal_vector_temp.z())); - points_with_normal.push_back(point_with_normal); } } } @@ -237,10 +248,11 @@ namespace sliding_window_plane_extractor{ refinement_performed = true; } } - if (refinement_performed){ + if (!refinement_performed){ const convex_plane_extraction::PlaneParameters temp_plane_parameters(normal_vector, support_vector); label_plane_parameters_map_.emplace(label, temp_plane_parameters); } + VLOG(1) << "Added plane!"; } double SlidingWindowPlaneExtractor::computeAverageErrorToPlane(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector, diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index d496c9db..7ccb6053 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -1,4 +1,4 @@ -input_map_topic : '/elevation_mapping/elevation_map' +input_topic : '/elevation_mapping/elevation_map_raw' height_layer : 'elevation' @@ -8,8 +8,8 @@ plane_factory: polygonizer: upsampling_factor : 3 activate_long_edge_upsampling : false - activate_contour_approximation : false - hole_area_threshold_squared_meters : 2e-3 + activate_contour_approximation : true + hole_area_threshold_squared_meters : 0.002 contour_approximation_deviation_threshold : 0.04 convex_decomposer: diff --git a/convex_plane_decomposition_ros/launch/convex_plane_extraction.launch b/convex_plane_decomposition_ros/launch/convex_plane_extraction.launch index 11ea00bc..5eee1575 100644 --- a/convex_plane_decomposition_ros/launch/convex_plane_extraction.launch +++ b/convex_plane_decomposition_ros/launch/convex_plane_extraction.launch @@ -1,17 +1,8 @@ - - - - --> - - - - - - - + + - + diff --git a/convex_plane_decomposition_ros/rviz/config.rviz b/convex_plane_decomposition_ros/rviz/config.rviz index 885051e5..f8fb179b 100644 --- a/convex_plane_decomposition_ros/rviz/config.rviz +++ b/convex_plane_decomposition_ros/rviz/config.rviz @@ -171,7 +171,7 @@ Visualization Manager: Color: 25; 255; 0 Enabled: true Name: PolygonArray - Topic: /convex_plane_extraction/hole_contours + Topic: /convex_plane_extraction_ros/convex_polygons Unreliable: false Value: true coloring: Auto @@ -184,7 +184,7 @@ Visualization Manager: Color: 25; 255; 0 Enabled: true Name: PolygonArray - Topic: /convex_plane_extraction/outer_contours + Topic: /convex_plane_extraction_ros/outer_contours Unreliable: false Value: true coloring: Auto @@ -209,7 +209,7 @@ Visualization Manager: Min Intensity: 0 Name: GridMap Show Grid Lines: true - Topic: /convex_plane_extraction/convex_plane_extraction + Topic: /convex_plane_extraction_ros/convex_plane_extraction Unreliable: false Use Rainbow: true Value: true diff --git a/convex_plane_decomposition_ros/src/convex_plane_extraction_node.cpp b/convex_plane_decomposition_ros/src/convex_plane_extraction_node.cpp index 987d4241..2b2e0b2a 100644 --- a/convex_plane_decomposition_ros/src/convex_plane_extraction_node.cpp +++ b/convex_plane_decomposition_ros/src/convex_plane_extraction_node.cpp @@ -7,6 +7,7 @@ int main(int argc, char** argv) { FLAGS_alsologtostderr = 1; FLAGS_colorlogtostderr = 1; + FLAGS_v = 1; google::InitGoogleLogging(argv[0]); ros::init(argc, argv, "convex_plane_extraction_ros"); ros::NodeHandle nodeHandle("~"); diff --git a/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp b/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp index 32665192..4fb98843 100644 --- a/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp +++ b/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp @@ -39,18 +39,16 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { GridMap messageMap; GridMapRosConverter::fromMessage(message, messageMap); bool success; - GridMap inputMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(4, 4), success); - Position3 position; - inputMap.getPosition3("elevation", Index(0,0), position); - VLOG(1) << inputMap.getPosition(); + GridMap inputMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(6, 6), success); CHECK(success); ROS_INFO("...done."); - + VLOG(1) << "Applying median filtering to map."; applyMedianFilter(inputMap.get("elevation"), 5); // Run pipeline. + VLOG(1) << "Running pipeline ..."; PipelineROS pipeline_ros(nodeHandle_, inputMap); - + VLOG(1) << "done."; // Visualize in Rviz. jsk_recognition_msgs::PolygonArray outer_plane_contours = pipeline_ros.getOuterPlaneContours(); jsk_recognition_msgs::PolygonArray convex_polygons = pipeline_ros.getConvexPolygons(); diff --git a/convex_plane_decomposition_ros/src/pipeline_ros.cpp b/convex_plane_decomposition_ros/src/pipeline_ros.cpp index 4bc56811..02097b89 100644 --- a/convex_plane_decomposition_ros/src/pipeline_ros.cpp +++ b/convex_plane_decomposition_ros/src/pipeline_ros.cpp @@ -4,12 +4,14 @@ namespace convex_plane_extraction { PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map::GridMap &map) { + const std::string kPackagePrefix = "/convex_plane_extraction_ros"; + // Grid map parameters. GridMapParameters grid_map_parameters = loadGridMapParameters(nodeHandle, map); // Sliding Window Plane Extractor parameters. sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters sliding_window_plane_extractor_parameters; - const std::string kSlidingWindowParametersPrefix = "/sliding_window_plane_extractor/"; + const std::string kSlidingWindowParametersPrefix = kPackagePrefix + "/sliding_window_plane_extractor/"; if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "kernel_size", sliding_window_plane_extractor_parameters.kernel_size)) { ROS_ERROR("Could not read parameter `kernel_size`. Setting parameter to default value."); @@ -33,7 +35,7 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map: if (sliding_window_plane_extractor_parameters.include_ransac_refinement) { // RASNAC refinement related parameters. ransac_plane_extractor::RansacPlaneExtractorParameters ransac_plane_extractor_parameters; - const std::string kRansacRefinementParameterPrefix = "/ransac_plane_refinement/"; + const std::string kRansacRefinementParameterPrefix = kPackagePrefix + "/ransac_plane_refinement/"; if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "probability", ransac_plane_extractor_parameters.probability)) { LOG(WARNING) << "Could not read parameter" << kRansacRefinementParameterPrefix @@ -61,8 +63,8 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map: // Polygonizer parameters. PolygonizerParameters polygonizer_parameters; polygonizer_parameters.resolution = grid_map_parameters.resolution; - const std::string kPolygonizerParametersPrefix = "/polygonizer/"; - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "upsampling_factor", polygonizer_parameters.resolution)) { + const std::string kPolygonizerParametersPrefix = kPackagePrefix + "/polygonizer/"; + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "upsampling_factor", polygonizer_parameters.upsampling_factor)) { ROS_ERROR("Could not read parameter `normal_threshold`. Setting parameter to default value."); } if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "activate_long_edge_upsampling", @@ -87,7 +89,7 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map: // Convex decomposer parameters. ConvexDecomposerParameters convex_decomposer_parameters; - const std::string kConvexDecomposerParametersPrefix = "/convex_decomposer/"; + const std::string kConvexDecomposerParametersPrefix = kPackagePrefix + "/convex_decomposer/"; std::string decomposer_type; if (!nodeHandle.getParam(kConvexDecomposerParametersPrefix + "decomposer_type", decomposer_type)) { ROS_ERROR("Could not read parameter `decomposer_type`. Setting parameter to default value."); @@ -104,7 +106,7 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map: // Plane Factory parameters. PlaneFactoryParameters plane_factory_parameters; - const std::string kPlaneFactoryParametersPrefix = "/plane_factory/"; + const std::string kPlaneFactoryParametersPrefix = kPackagePrefix + "/plane_factory/"; if (!nodeHandle.getParam(kPlaneFactoryParametersPrefix + "plane_inclination_threshold_degrees", plane_factory_parameters.plane_inclination_threshold_degrees)) { ROS_ERROR("Could not read parameter `plane_inclination_threshold_degrees`. Setting parameter to default value."); @@ -116,7 +118,6 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map: PipelineParameters pipeline_parameters; pipeline_parameters.sliding_window_plane_extractor_parameters = sliding_window_plane_extractor_parameters; pipeline_parameters.plane_factory_parameters = plane_factory_parameters; - return pipeline_parameters; } @@ -124,6 +125,7 @@ GridMapParameters loadGridMapParameters(ros::NodeHandle &nodeHandle, grid_map::G // Grid map parameters. std::string height_layer; CHECK(nodeHandle.getParam("height_layer", height_layer)); + VLOG(1) << "Height layer is: " << height_layer; GridMapParameters grid_map_parameters(map, height_layer); return grid_map_parameters; @@ -136,6 +138,7 @@ jsk_recognition_msgs::PolygonArray PipelineROS::getConvexPolygons() const { jsk_recognition_msgs::PolygonArray PipelineROS::getOuterPlaneContours() const { const Polygon3dVectorContainer plane_contour_buffer = pipeline_.getPlaneContours(); + VLOG(1) << "Exported polygons: " << plane_contour_buffer.size(); return convertToRosPolygons(plane_contour_buffer); } From b179bdaf4e0cd774542f2245aee7854ed414347b Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Sun, 22 Mar 2020 21:10:48 +0100 Subject: [PATCH 024/504] Patched polygon approximation. --- convex_plane_decomposition/CMakeLists.txt | 3 +- .../include/geometry_utils.hpp | 8 +- .../include/polygon.hpp | 13 +- .../include/polygonizer.hpp | 12 +- .../src/geometry_utils.cpp | 24 ++- convex_plane_decomposition/src/pipeline.cpp | 2 +- .../src/plane_factory.cpp | 4 + convex_plane_decomposition/src/polygon.cpp | 189 +++++++++++++----- .../src/polygonizer.cpp | 114 +++++++++-- convex_plane_decomposition_ros/CMakeLists.txt | 1 + .../config/parameters.yaml | 5 +- .../src/convex_plane_extraction_ros.cpp | 4 +- .../src/pipeline_ros.cpp | 16 +- 13 files changed, 315 insertions(+), 80 deletions(-) diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 804da261..3a9f58d9 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -195,7 +195,8 @@ add_dependencies(${PROJECT_NAME} ## Specify libraries to link a library or executable target against target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} - ${CGAL_LIBRARIES} + ${CGAL_LIBRARIES} + ${OpenCV_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} glog ) diff --git a/convex_plane_decomposition/include/geometry_utils.hpp b/convex_plane_decomposition/include/geometry_utils.hpp index 3f1304ca..ef05241e 100644 --- a/convex_plane_decomposition/include/geometry_utils.hpp +++ b/convex_plane_decomposition/include/geometry_utils.hpp @@ -9,7 +9,7 @@ double scalarCrossProduct(const Vector2d &leftVector, const Vector2d &rightVecto double distanceToLine(const Vector2d& lineSupportVector, const Vector2d& lineDirectionalVector, const Vector2d& testPoint); -bool isPointOnRightSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); +bool isPointOnRightSideOfLine(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); double computeAngleBetweenVectors(const Vector2d& first_vector, const Vector2d& second_vector); @@ -18,7 +18,11 @@ bool isPointOnLeftSide(const Vector2d& line_support_vector, const Vector2d& line bool intersectRayWithLineSegment(const Vector2d& ray_source, const Vector2d& ray_direction, const Vector2d& segment_source, const Vector2d& segment_target, Vector2d* intersection_point); -double distanceBetweenPoints(Vector2d first, Vector2d second); +double distanceBetweenPoints(const Vector2d& first, const Vector2d& second); + +double getDistanceOfPointToLineSegment(const Vector2d& point, const Vector2d& source, Vector2d& target); + +std::pair getDistanceAndClosestPointOnLineSegment(const Vector2d& point, const Vector2d& source, const Vector2d& target); bool intersectLineSegmentWithLineSegment(const Vector2d& segment_1_source, const Vector2d& segment_1_target, const Vector2d& segment_2_source, const Vector2d& segment_2_target, Vector2d* intersection_point); diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index fb8a1209..b6d5a2b2 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -97,9 +98,11 @@ namespace convex_plane_extraction{ CgalPolygon2dVertexIterator next(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon); + bool next(const CgalPolygon2dVertexIterator& iterator, CgalPolygon2dVertexIterator& output_iterator, const CgalPolygon2d& polygon); + CgalPolygon2dVertexIterator previous(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon); - void approximateContour(CgalPolygon2d* polygon); +void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, double relative_area_threshold, double absolute_area_threshold); void upSampleLongEdges(CgalPolygon2d* polygon); @@ -150,5 +153,13 @@ namespace convex_plane_extraction{ std::list decomposeInnerApproximation(const CgalPolygon2d& polygon); void printPolygon(const CgalPolygon2d& polygon); + + std::pair getVertexPositionsWithHighestHoleSlConcavityMeasure(const CgalPolygon2d& polygon); + + std::pair getClosestPointAndSegmentOnPolygonToPoint(const CgalPoint2d& point, const CgalPolygon2d& polygon); + + std::vector> getCommonVertexPairIndices(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon); + + std::vector getVertexIndicesOfFirstPolygonContainedInSecondPolygonContour(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon); } #endif //CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGON_HPP_ diff --git a/convex_plane_decomposition/include/polygonizer.hpp b/convex_plane_decomposition/include/polygonizer.hpp index 2947c67c..20c04728 100644 --- a/convex_plane_decomposition/include/polygonizer.hpp +++ b/convex_plane_decomposition/include/polygonizer.hpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include "plane.hpp" @@ -22,7 +24,9 @@ struct PolygonizerParameters{ bool activate_long_edge_upsampling = false; bool activate_contour_approximation = false; double hole_area_threshold_squared_meters = 2e-3; - double contour_approximation_deviation_threshold = 0.06; + double contour_approximation_relative_area_threshold = 0.01; + double contour_approximation_absolute_area_threshold_squared_meters = 0.04; + int max_number_of_iterations = 5; }; class Polygonizer { @@ -43,6 +47,12 @@ class Polygonizer { bool addHoleToOuterContourAtVertexIndex(int segment_target_vertex_index, const CgalPolygon2d& hole, CgalPolygon2d& outer_contour) const; + CgalPolygon2d resolveHolesUsingSlConnection(const PolygonWithHoles& polygon_with_holes) const; + + void resolveHolesInBinaryImage(cv::Mat& binary_image, const PolygonWithHoles& contour_with_holes) const; + + PolygonWithHoles extractContoursFromBinaryImage(cv::Mat& binary_image) const; + private: PolygonizerParameters parameters_; diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp index 07e6714a..3e6088c7 100644 --- a/convex_plane_decomposition/src/geometry_utils.cpp +++ b/convex_plane_decomposition/src/geometry_utils.cpp @@ -17,7 +17,7 @@ namespace convex_plane_extraction { + scalarCrossProduct(lineSupportVector, secondPointOnLine); } - bool isPointOnRightSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point){ + bool isPointOnRightSideOfLine(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point){ Vector2d normal_vector(line_direction_vector.y(), (-1.0)*line_direction_vector.x()); normal_vector.normalize(); Vector2d point_vector = point - line_support_vector; @@ -133,9 +133,29 @@ namespace convex_plane_extraction { return true; } - double distanceBetweenPoints(Vector2d first, Vector2d second){ + double distanceBetweenPoints(const Vector2d& first, const Vector2d& second){ return (second - first).norm(); } + double getDistanceOfPointToLineSegment(const Vector2d& point, const Vector2d& source, const Vector2d& target){ + return getDistanceAndClosestPointOnLineSegment(point, source, target).first; + } + + std::pair getDistanceAndClosestPointOnLineSegment(const Vector2d& point, const Vector2d& source, const Vector2d& target){ + const double segment_squared_length = (target - source).squaredNorm(); + if (segment_squared_length == 0.0){ + return std::make_pair(distanceBetweenPoints(point, source), source); + } + const double t = (point - source).dot(target - source) / segment_squared_length; + if (t > 1.0){ + return std::make_pair((target - point).norm(), target); + } else if (t < 0.0){ + return std::make_pair((source - point).norm(), source); + } else { + const Vector2d point_temp = abs(t)*(target - source); + return std::make_pair((point_temp - point).norm(), point_temp); + } + } + } diff --git a/convex_plane_decomposition/src/pipeline.cpp b/convex_plane_decomposition/src/pipeline.cpp index 36d8d53a..27929c4a 100644 --- a/convex_plane_decomposition/src/pipeline.cpp +++ b/convex_plane_decomposition/src/pipeline.cpp @@ -15,7 +15,7 @@ Pipeline::Pipeline(const PipelineParameters& pipeline_parameters, const GridMapP VLOG(1) << "done"; plane_factory_.createPlanesFromLabeledImageAndPlaneParameters(sliding_window_plane_extractor_.getLabeledImage(), sliding_window_plane_extractor_.getNumberOfExtractedPlanes(), sliding_window_plane_extractor_.getLabelPlaneParameterMap()); - plane_factory_.decomposePlanesInConvexPolygons(); + //plane_factory_.decomposePlanesInConvexPolygons(); } Polygon3dVectorContainer Pipeline::getConvexPolygons() const{ diff --git a/convex_plane_decomposition/src/plane_factory.cpp b/convex_plane_decomposition/src/plane_factory.cpp index 375c9922..338932ae 100644 --- a/convex_plane_decomposition/src/plane_factory.cpp +++ b/convex_plane_decomposition/src/plane_factory.cpp @@ -27,6 +27,10 @@ void PlaneFactory::createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& const CgalPolygon2d plane_contour = polygonizer.runPolygonizationOnBinaryImage(binary_image); const auto plane_parameter_it = plane_parameters.find(label); CHECK(plane_parameter_it != plane_parameters.end()) << "Label not contained in plane parameter container!"; + if (plane_contour.is_empty()){ + LOG(WARNING) << "Dropping plane, polygon negligible!"; + continue; + } if (isPlaneInclinationBelowThreshold(plane_parameter_it->second.normal_vector)){ planes_.emplace_back(plane_contour, plane_parameter_it->second); } else { diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 6e40c86e..6b336521 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -13,29 +13,18 @@ namespace convex_plane_extraction { result = intersection(test_segment, segment); if (result) { if (const CgalSegment2d *s = boost::get(&*result)) { - std::cout << *s << std::endl; + if (print_flag) { + VLOG(1) << "Intersection over segment: " << *s; + } return true; } else { const CgalPoint2d *p = boost::get(&*result); if (print_flag) { - std::cout << *p << ";" << std::endl; + VLOG(1) << "Intersection in in point: " << *p; } return true; } } -// Vector2d test_segment_source(vertex_it->x(), vertex_it->y()); -// Vector2d test_segment_target(next_vertex_it->x(), next_vertex_it->y()); -// Vector2d segment_source(segment.source().x(), segment.source().y()); -// Vector2d segment_target(segment.target().x(), segment.target().y()); -// Vector2d intersection_point; -// if (intersectLineSegmentWithLineSegment(test_segment_source, test_segment_target, -// segment_source, segment_target, &intersection_point)){ -// std::cout << intersection_point.x() << ", " << intersection_point.y() << ";" << std::endl; -// return true; -// } -// if (do_intersect(test_segment, segment)){ -// return true; -// } } return false; } @@ -76,7 +65,7 @@ namespace convex_plane_extraction { *normal_vector = normal; } - void approximateContour(CgalPolygon2d* polygon){ + void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, double relative_area_threshold, double absolute_area_threshold){ CHECK_NOTNULL(polygon); if (polygon->size() < 4){ return; @@ -87,50 +76,73 @@ namespace convex_plane_extraction { auto second_vertex_it = std::next(first_vertex_it); auto third_vertex_it = std::next(second_vertex_it); double area = polygon->area(); - do { + int number_of_iterations = 0; + while (number_of_iterations < max_number_of_iterations ){ old_size = polygon->size(); - for (int vertex_position = 0; vertex_position < old_size; ++vertex_position){ - if (polygon->size() < 4){ - break; - } - Vector2d first_point(first_vertex_it->x(), first_vertex_it->y()); - Vector2d second_point(second_vertex_it->x(), second_vertex_it->y()); - Vector2d third_point(third_vertex_it->x(), third_vertex_it->y()); - if (isPointOnRightSide(first_point, third_point - first_point, second_point)) { - LOG(INFO) << "Point on right side!"; - double a = (third_point - first_point).norm(); - double b = (second_point - third_point).norm(); - double c = (first_point - second_point).norm(); - constexpr double areaThresholdFactor = 0.025; - if (computeTriangleArea(a, b, c) < areaThresholdFactor * area) { - LOG(INFO) << "Area sufficiently small!"; - CgalPolygon2d new_polygon(*polygon); - int vertex_position_offset = std::distance(polygon->vertices_begin(), second_vertex_it); - CgalPolygon2dVertexIterator tmp_iterator = new_polygon.vertices_begin(); - std::advance(tmp_iterator, vertex_position_offset); - LOG(INFO) << "Before erase call!"; - new_polygon.erase(tmp_iterator); - LOG(INFO) << "After ease call!"; - if (new_polygon.is_simple()) { - first_vertex_it = third_vertex_it; - polygon->erase(second_vertex_it); - second_vertex_it = next(first_vertex_it, *polygon); - third_vertex_it = next(second_vertex_it, *polygon); - LOG(INFO) << "Removed one vertex!"; - continue; + if (polygon->size() < 4){ + break; + } + Vector2d first_point(first_vertex_it->x(), first_vertex_it->y()); + Vector2d second_point(second_vertex_it->x(), second_vertex_it->y()); + Vector2d third_point(third_vertex_it->x(), third_vertex_it->y()); + LOG(WARNING) << "Got here!"; + if (isPointOnRightSideOfLine(first_point, third_point - first_point, second_point)) { + VLOG(1) << "Point on right side!"; + double a = (third_point - first_point).norm(); + double b = (second_point - third_point).norm(); + double c = (first_point - second_point).norm(); + const double triangle_area = computeTriangleArea(a, b, c); + CHECK(isfinite(triangle_area)) << "Area: " << triangle_area << ", a: " << a << ", b: " << b << ", c: " << c; + CHECK_GE(triangle_area, 0.0); + if ((triangle_area < relative_area_threshold * area) && (triangle_area < absolute_area_threshold)) { + VLOG(1) << "Area sufficiently small!"; + CgalPolygon2d new_polygon(*polygon); + int vertex_position_offset = std::distance(polygon->vertices_begin(), second_vertex_it); + CgalPolygon2dVertexIterator tmp_iterator = new_polygon.vertices_begin(); + std::advance(tmp_iterator, vertex_position_offset); + VLOG(1) << "Before erase call!"; + new_polygon.erase(tmp_iterator); + VLOG(1) << "After ease call!"; + if (new_polygon.is_simple() && (new_polygon.orientation() == CGAL::COUNTERCLOCKWISE) && abs(new_polygon.area() - area) < 0.1 * area && abs(new_polygon.area() - area) < 0.5) { + CHECK_LE(triangle_area, area); + first_vertex_it = polygon->erase(second_vertex_it); + if (first_vertex_it == polygon->vertices_end()){ + first_vertex_it = polygon->vertices_begin(); + } + second_vertex_it = next(first_vertex_it, *polygon); + third_vertex_it = next(second_vertex_it, *polygon); + if ((std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), second_vertex_it)) || + (std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), third_vertex_it)) || + (std::distance(polygon->begin(), second_vertex_it) >= std::distance(polygon->begin(), third_vertex_it))){ + ++number_of_iterations; } + VLOG(1) << "Removed one vertex!"; + continue; } } - first_vertex_it = second_vertex_it; - second_vertex_it = third_vertex_it; - third_vertex_it = next(second_vertex_it, *polygon); } - } while (polygon->size() < old_size); + first_vertex_it = second_vertex_it; + second_vertex_it = third_vertex_it; + third_vertex_it = next(second_vertex_it, *polygon); + LOG(WARNING) << "Got to bottom! Number of iterations: " << std::distance(polygon->begin(), first_vertex_it) << " " << + std::distance(polygon->begin(), second_vertex_it) << " " << std::distance(polygon->begin(), third_vertex_it); + if ((std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), second_vertex_it) || + std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), third_vertex_it) || + std::distance(polygon->begin(), second_vertex_it) >= std::distance(polygon->begin(), third_vertex_it) )){ + ++number_of_iterations; + } + } } double computeTriangleArea(double side_length_a, double side_length_b, double side_length_c){ - double s = (side_length_a + side_length_b + side_length_c) / 2.0; - return sqrt(s * (s-side_length_a) * (s - side_length_b) * (s - side_length_c)); + const double s = (side_length_a + side_length_b + side_length_c) / 2.0; + CHECK_GT(s, 0.0); + double sqrt_argument = s * (s-side_length_a) * (s - side_length_b) * (s - side_length_c); + if (abs(sqrt_argument) < 1e-6){ + sqrt_argument = 0.0; + } + CHECK_GE(sqrt_argument, 0.0); + return sqrt(sqrt_argument); } CgalPolygon2dVertexIterator next(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon){ @@ -141,6 +153,18 @@ namespace convex_plane_extraction { } } + // Retrieves the following vertex in polygon, including wrap around, when last polygon reached. + // In this case the output flag is set to true. + bool next(const CgalPolygon2dVertexIterator& iterator, CgalPolygon2dVertexIterator& output_iterator, const CgalPolygon2d& polygon){ + if (std::next(iterator) == polygon.vertices_end()){ + output_iterator = polygon.vertices_begin(); + return true; + } else { + output_iterator = std::next(iterator); + return false; + } + } + CgalPolygon2dVertexIterator previous(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon){ if (iterator == polygon.vertices_begin()){ return std::prev(polygon.vertices_end()); @@ -353,4 +377,65 @@ namespace convex_plane_extraction { return false; } + std::pair getVertexPositionsWithHighestHoleSlConcavityMeasure(const CgalPolygon2d& polygon){ + CHECK(polygon.size() > 2); + std::multimap> slConcavityScoreMap; + const int number_of_vertices = polygon.size(); + for (int first_vertex_counter = 0; first_vertex_counter < number_of_vertices - 1; ++first_vertex_counter){ + const auto& vertex_container = polygon.container(); + const CgalPoint2d& first_vertex = vertex_container.at(first_vertex_counter); + for (int second_vertex_counter = first_vertex_counter + 1; second_vertex_counter < number_of_vertices; ++second_vertex_counter){ + const CgalPoint2d& second_vertex = vertex_container.at(second_vertex_counter); + const double vertex_squared_distance = (first_vertex - second_vertex).squared_length(); + slConcavityScoreMap.insert(std::make_pair(vertex_squared_distance, std::make_pair(first_vertex_counter, second_vertex_counter))); + } + } + return slConcavityScoreMap.begin()->second; + } + + // Attention, if point overlaps with existing vertex. + std::pair getClosestPointAndSegmentOnPolygonToPoint(const CgalPoint2d& point, const CgalPolygon2d& polygon){ + CHECK_GT(polygon.size(), 2); + std::multimap> distance_to_segment_closest_point_map; + int edge_counter = 0; + for(auto edge_it = polygon.edges_begin(); edge_it != polygon.edges_end(); ++edge_it){ + if (edge_it->has_on(point)){ + distance_to_segment_closest_point_map.insert(std::make_pair(0.0, std::make_pair(edge_counter, Vector2d(point.x(), point.y())))); + ++edge_counter; + continue; + } + const Vector2d source(edge_it->source().x(), edge_it->source().y()); + const Vector2d target(edge_it->target().x(), edge_it->target().y()); + const Vector2d test_point(point.x(), point.y()); + std::pair distance_closest_point = getDistanceAndClosestPointOnLineSegment(test_point, source, target); + distance_to_segment_closest_point_map.insert(std::make_pair(distance_closest_point.first, std::make_pair(edge_counter, distance_closest_point.second))); + ++edge_counter; + } + const int closest_edge_index = distance_to_segment_closest_point_map.begin()->second.first; + const CgalPoint2d closest_point(distance_to_segment_closest_point_map.begin()->second.second.x(), distance_to_segment_closest_point_map.begin()->second.second.y()); + return std::make_pair(closest_edge_index, closest_point); + } + + std::vector> getCommonVertexPairIndices(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon){ + std::vector> return_buffer; + for(int first_polygon_vertex_index = 0; first_polygon_vertex_index < first_polygon.container().size(); ++first_polygon_vertex_index){ + for(int second_polygon_vertex_index = 0; second_polygon_vertex_index < second_polygon.container().size(); ++second_polygon_vertex_index){ + if (first_polygon.container().at(first_polygon_vertex_index) == second_polygon.container().at(second_polygon_vertex_index)){ + return_buffer.push_back(std::make_pair(first_polygon_vertex_index, second_polygon_vertex_index)); + } + } + } + return return_buffer; + } + + std::vector getVertexIndicesOfFirstPolygonContainedInSecondPolygonContour(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon){ + std::vector return_buffer; + for (int vertex_index = 0; vertex_index < first_polygon.container().size(); ++vertex_index){ + if (second_polygon.has_on_boundary(first_polygon.container().at(vertex_index))){ + return_buffer.push_back(vertex_index); + } + } + return return_buffer; + } + } diff --git a/convex_plane_decomposition/src/polygonizer.cpp b/convex_plane_decomposition/src/polygonizer.cpp index 7db14262..f829ea55 100644 --- a/convex_plane_decomposition/src/polygonizer.cpp +++ b/convex_plane_decomposition/src/polygonizer.cpp @@ -11,11 +11,12 @@ PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& bina binary_image_upsampled, cv::Size(parameters_.upsampling_factor * binary_image.size().height, parameters_.upsampling_factor * binary_image.size().width)); + findContours(binary_image_upsampled, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); std::vector> approx_contours; int hierachy_it = 0; - for (auto &contour : contours) { + for (auto& contour : contours) { ++hierachy_it; std::vector approx_contour; if (contour.size() <= 10) { @@ -33,20 +34,16 @@ PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& bina approx_contour.begin(), approx_contour.end(), parameters_.resolution / static_cast(parameters_.upsampling_factor)); - - if (!polygon.is_simple()) { - convex_plane_extraction::Vector2i index; - index << (*polygon.begin()).x(), (*polygon.begin()).y(); - LOG(WARNING) << "Polygon starting at " << index << " is not simple, will be ignored!"; - continue; - } + CHECK(polygon.is_simple()) << "Contour extraction from binary image caused intersection!"; constexpr int kParentFlagIndex = 3; if (hierarchy[hierachy_it - 1][kParentFlagIndex] < 0) { if (parameters_.activate_long_edge_upsampling) { upSampleLongEdges(&polygon); } if (parameters_.activate_contour_approximation) { - //approximateContour(&polygon); + approximateContour(&polygon, parameters_.max_number_of_iterations, parameters_.contour_approximation_relative_area_threshold, + parameters_.contour_approximation_absolute_area_threshold_squared_meters); + VLOG(1) << "Contour approximated!"; } plane_polygons.outer_contour = polygon; } else { @@ -56,6 +53,57 @@ PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& bina return plane_polygons; } +PolygonWithHoles Polygonizer::extractContoursFromBinaryImage(cv::Mat& binary_image) const{ + PolygonWithHoles plane_polygons; + std::vector> contours; + std::vector hierarchy; + findContours(binary_image, contours, hierarchy, + CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); + std::vector> approx_contours; + int hierachy_it = 0; + for (auto& contour : contours) { + ++hierachy_it; + CHECK_GE(contour.size(), 2); + CgalPolygon2d polygon = convex_plane_extraction::createCgalPolygonFromOpenCvPoints( + contour.begin(), contour.end(), 1); + constexpr int kParentFlagIndex = 3; + if (hierarchy[hierachy_it - 1][kParentFlagIndex] < 0) { + plane_polygons.outer_contour = polygon; + } else { + plane_polygons.holes.push_back(polygon); + } + } + return plane_polygons; +} + +void Polygonizer::resolveHolesInBinaryImage(cv::Mat& binary_image, const PolygonWithHoles& contour_with_holes) const{ + for(const auto& hole : contour_with_holes.holes){ + if (hole.area() > 36){ + continue; + } + std::pair slConcavityVertices = getVertexPositionsWithHighestHoleSlConcavityMeasure(hole); + const CgalPoint2d first_sl_point = hole.container().at(slConcavityVertices.first); + const CgalPoint2d second_sl_point = hole.container().at(slConcavityVertices.second); + std::pair first_connection_candidate = + getClosestPointAndSegmentOnPolygonToPoint(first_sl_point, contour_with_holes.outer_contour); + std::pair second_connection_candidate = + getClosestPointAndSegmentOnPolygonToPoint(second_sl_point, contour_with_holes.outer_contour); + if ((first_connection_candidate.second - first_sl_point).squared_length() < + (second_connection_candidate.second - second_sl_point).squared_length()){ + cv::Point first_point(first_connection_candidate.second.y(), first_connection_candidate.second.x()); + cv::Point second_point(first_sl_point.y(), first_sl_point.x()); + cv::line(binary_image, first_point, second_point, CV_RGB(0,0,0),2); + } else{ + cv::Point first_point(second_connection_candidate.second.y(), second_connection_candidate.second.x()); + cv::Point second_point(second_sl_point.y(), second_sl_point.x()); + cv::line(binary_image, first_point, second_point, CV_RGB(0,0,0), 2); + } + } +// cv::namedWindow( "Display window", cv::WINDOW_AUTOSIZE); // Create a window for display. +// cv::imshow( "Display window", binary_image); +// cv::waitKey(0); +} + //CgalPolygon2d Polygonizer::resolveHoles(PolygonWithHoles& polygon_with_holes) const{ // CgalPolygon2dContainer& holes = polygon_with_holes.holes; // // Get hole part which is entirely contained in outer contour. @@ -300,6 +348,7 @@ CgalPolygon2d Polygonizer::resolveHolesWithVerticalConnection(PolygonWithHoles& return **offset_polygons.begin(); } +/* void Polygonizer::approximatePolygon(CgalPolygon2d& polygon) const{ std::vector contour; for (const auto& vertex : polygon.container()){ @@ -312,10 +361,49 @@ void Polygonizer::approximatePolygon(CgalPolygon2d& polygon) const{ polygon.push_back(CgalPoint2d(point.y, point.x)); } } - +*/ CgalPolygon2d Polygonizer::runPolygonizationOnBinaryImage(const cv::Mat& binary_image) const{ PolygonWithHoles polygon_with_holes = extractPolygonsFromBinaryImage(binary_image); - CgalPolygon2d polygon = resolveHolesWithVerticalConnection(polygon_with_holes); - approximatePolygon(polygon); - return polygon; + //CgalPolygon2d polygon = resolveHolesWithVerticalConnection(polygon_with_holes); + //approximatePolygon(polygon_with_holes.outer_contour); + return polygon_with_holes.outer_contour; +} + +CgalPolygon2d Polygonizer::resolveHolesUsingSlConnection(const PolygonWithHoles& polygon_with_holes) const{ + CgalPolygon2dContainer holes = polygon_with_holes.holes; + // Get hole part which is entirely contained in outer contour. + // In the contour simplification stage intersections may have been introduced. + removeAreasNotContainedInOuterContourFromHoles(polygon_with_holes.outer_contour, holes); + if (holes.empty()) { + return polygon_with_holes.outer_contour; + } + auto hole_it = holes.begin(); + while(hole_it!= holes.end()) { + if (hole_it->size() < 3) { + hole_it = holes.erase(hole_it); + } else if (abs(hole_it->area()) < parameters_.hole_area_threshold_squared_meters) { + hole_it = holes.erase(hole_it); + } else { + ++hole_it; + } + } + std::vector difference_polygons; + difference_polygons.emplace_back(polygon_with_holes.outer_contour); + for (const auto& hole : holes) { + std::vector temp_polygon_buffer; + for (const auto& polygon : difference_polygons) { + CGAL::difference(polygon, hole, std::back_inserter(temp_polygon_buffer)); + } + difference_polygons.clear(); + std::move(temp_polygon_buffer.begin(), temp_polygon_buffer.end(), std::back_inserter(difference_polygons)); + } + CgalPolygon2d outer_contour = difference_polygons.rbegin()->outer_boundary(); + holes.clear(); + std::move(difference_polygons.rbegin()->holes_begin(), difference_polygons.rbegin()->holes_end(), std::back_inserter(holes)); + for (const auto& hole : holes){ + if (CGAL::do_intersect(hole, outer_contour)){ + // At this point intersections may only occur in single points. Overlapping edges are not possible. + + } + } } \ No newline at end of file diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index edfed337..72555cc2 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -169,6 +169,7 @@ target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} + ${OpenCV_LIBRARIES} glog ) diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 7ccb6053..105ceb7e 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -9,8 +9,9 @@ polygonizer: upsampling_factor : 3 activate_long_edge_upsampling : false activate_contour_approximation : true - hole_area_threshold_squared_meters : 0.002 - contour_approximation_deviation_threshold : 0.04 + contour_approximation_relative_area_threshold : 0.02 + contour_approximation_absolute_area_threshold_squared_meters : 0.04 + max_number_of_iterations : 15 convex_decomposer: decomposer_type : 'optimal_decompostion' diff --git a/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp b/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp index 4fb98843..8d448778 100644 --- a/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp +++ b/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp @@ -51,14 +51,14 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { VLOG(1) << "done."; // Visualize in Rviz. jsk_recognition_msgs::PolygonArray outer_plane_contours = pipeline_ros.getOuterPlaneContours(); - jsk_recognition_msgs::PolygonArray convex_polygons = pipeline_ros.getConvexPolygons(); + //jsk_recognition_msgs::PolygonArray convex_polygons = pipeline_ros.getConvexPolygons(); pipeline_ros.augmentGridMapWithSegmentation(inputMap); grid_map_msgs::GridMap outputMessage; GridMapRosConverter::toMessage(inputMap, outputMessage); grid_map_publisher_.publish(outputMessage); - convex_polygon_publisher_.publish(convex_polygons); + //convex_polygon_publisher_.publish(convex_polygons); outer_contours_publisher_.publish(outer_plane_contours); } diff --git a/convex_plane_decomposition_ros/src/pipeline_ros.cpp b/convex_plane_decomposition_ros/src/pipeline_ros.cpp index 02097b89..87b98d34 100644 --- a/convex_plane_decomposition_ros/src/pipeline_ros.cpp +++ b/convex_plane_decomposition_ros/src/pipeline_ros.cpp @@ -76,10 +76,20 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map: ROS_ERROR("Could not read parameter `activate_contour_approximation`. Setting parameter to default value."); } if (polygonizer_parameters.activate_contour_approximation) { - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_deviation_threshold", - polygonizer_parameters.contour_approximation_deviation_threshold)) { + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_relative_area_threshold", + polygonizer_parameters.contour_approximation_relative_area_threshold)) { ROS_ERROR( - "Could not read parameter `contour_approximation_deviation_threshold`. Setting parameter to default value."); + "Could not read parameter `contour_approximation_relative_area_threshold`. Setting parameter to default value."); + } + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_absolute_area_threshold_squared_meters", + polygonizer_parameters.contour_approximation_absolute_area_threshold_squared_meters)) { + ROS_ERROR( + "Could not read parameter `contour_approximation_absolute_area_threshold_squared_meters`. Setting parameter to default value."); + } + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "max_number_of_iterations", + polygonizer_parameters.max_number_of_iterations)) { + ROS_ERROR( + "Could not read parameter `max_number_of_iterations`. Setting parameter to default value."); } } if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "hole_area_threshold_squared_meters", From e1ee083aecea2af34817a86f18b4ba0d3b7e2e4c Mon Sep 17 00:00:00 2001 From: Marko Bjelonic Date: Mon, 23 Mar 2020 19:25:15 +0100 Subject: [PATCH 025/504] Removed old loco_perception packages. --- loco_perception_ros/CMakeLists.txt | 51 -------- .../loco_perception_ros/ConvexSetSequence.hpp | 57 --------- loco_perception_ros/package.xml | 13 -- loco_perception_ros/src/ConvexSetSequence.cpp | 111 ------------------ 4 files changed, 232 deletions(-) delete mode 100644 loco_perception_ros/CMakeLists.txt delete mode 100644 loco_perception_ros/include/loco_perception_ros/ConvexSetSequence.hpp delete mode 100644 loco_perception_ros/package.xml delete mode 100644 loco_perception_ros/src/ConvexSetSequence.cpp diff --git a/loco_perception_ros/CMakeLists.txt b/loco_perception_ros/CMakeLists.txt deleted file mode 100644 index b5be54c7..00000000 --- a/loco_perception_ros/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -# Project configuration -cmake_minimum_required (VERSION 2.8) -project(loco_perception_ros) - -## Find catkin macros and libraries -## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) -## is used, also find other catkin packages -find_package(catkin REQUIRED COMPONENTS - loco_ros - loco_perception_utils -) - -catkin_package( - INCLUDE_DIRS include - LIBRARIES loco_perception_ros - CATKIN_DEPENDS - loco_ros - loco_perception_utils -# DEPENDS system_lib -) - -find_package(Eigen3 REQUIRED) -find_package(Boost COMPONENTS timer REQUIRED) - -add_definitions(--std=c++11) - -include_directories(include) -include_directories(${EIGEN3_INCLUDE_DIR}) -include_directories(${catkin_INCLUDE_DIRS}) -include_directories(${Boost_INCLUDE_DIRS}) - -add_library(loco_perception_ros SHARED - src/ConvexSetSequence.cpp -) - -add_dependencies(loco_perception_ros ${catkin_EXPORTED_TARGETS}) - -target_link_libraries(loco_perception_ros - ${catkin_LIBRARIES} - ${Boost_LIBRARIES} -) - -install(DIRECTORY include/${PROJECT_NAME}/ - DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/${PROJECT_NAME} - PATTERN ".svn" EXCLUDE -) -install(TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -) diff --git a/loco_perception_ros/include/loco_perception_ros/ConvexSetSequence.hpp b/loco_perception_ros/include/loco_perception_ros/ConvexSetSequence.hpp deleted file mode 100644 index 98b7d12b..00000000 --- a/loco_perception_ros/include/loco_perception_ros/ConvexSetSequence.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * ConvexSetSequence.hpp - * - * Created on: Nov 12, 2019 - * Author: Marko Bjelonic - */ - -#pragma once - -// ros -#include -#include - -// loco -#include - -// loco perception utils -#include - -// loco ros -#include -#include - -// robot utils -#include - -// stl -#include - - -namespace loco_perception_ros { - -class ConvexSetSequence { - public: - ConvexSetSequence(); - virtual ~ConvexSetSequence() = default; - - bool initialize(ros::NodeHandle& nodeHandle, const std::string& topic); - bool shutdown(); - - bool update(const std::vector& convexSets); - bool publish(); - - void setColorVector(std::vector>& colors); - void setColorVectorId(unsigned int colorId); - - unsigned int getNumSubscribers() const; - - protected: - ros::NodeHandle nodeHandle_; - visualization_msgs::MarkerArray convexSetSequence_; - ros::Publisher publisher_; - std::vector> colors_; - unsigned int colorId_; -}; - -} /* namespace loco */ diff --git a/loco_perception_ros/package.xml b/loco_perception_ros/package.xml deleted file mode 100644 index 38d4e8f7..00000000 --- a/loco_perception_ros/package.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - loco_perception_ros - 0.2.0 - The loco_perception_ros package - Marko Bjelonic - Proprietary - https://bitbucket.org/leggedrobotics/loco_anymal_wheels - Marko Bjelonic - catkin - loco_ros - loco_perception_utils - diff --git a/loco_perception_ros/src/ConvexSetSequence.cpp b/loco_perception_ros/src/ConvexSetSequence.cpp deleted file mode 100644 index 64213b92..00000000 --- a/loco_perception_ros/src/ConvexSetSequence.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * ConvexSetSequence.cpp - * - * Created on: Nov 12, 2019 - * Author: Marko Bjelonic - */ - - -// loco perception ros -#include "loco_perception_ros/ConvexSetSequence.hpp" - -namespace loco_perception_ros { - -ConvexSetSequence::ConvexSetSequence() - : nodeHandle_(), - convexSetSequence_(), - publisher_(), - colorId_(0u) -{ - -} - -void ConvexSetSequence::setColorVector(std::vector>& colors) { - colors_ = colors; -} - -void ConvexSetSequence::setColorVectorId(unsigned int colorId) { - colorId_ = colorId; -} - -bool ConvexSetSequence::initialize(ros::NodeHandle& nodeHandle, const std::string& topic) { - nodeHandle_ = nodeHandle; - publisher_ = nodeHandle.advertise(topic, 100); - - return true; -} - -bool ConvexSetSequence::shutdown() { - publisher_.shutdown(); - return true; -} - -bool ConvexSetSequence::update(const std::vector& convexSets) { - if (convexSets.size() == 0u) { - return true; - } - - if (getNumSubscribers() > 0u) { - convexSetSequence_.markers.clear(); - - unsigned int id = 0u; - unsigned int offset = 0u; - - for (const auto& convexSet : convexSets) { - // Number of vertices should not be zero. - if (convexSet.getNumOfVertices() <= 0u) { - ++offset; - continue; - } - - visualization_msgs::Marker convexSetSequence; - convexSetSequence.pose.orientation.w = 1.0; - convexSetSequence.action = visualization_msgs::Marker::ADD; - convexSetSequence.type = visualization_msgs::Marker::LINE_STRIP; - convexSetSequence.scale.x = 0.02000; - convexSetSequence.color.a = 1.0; - convexSetSequence.header.frame_id = "odom"; - - const unsigned int colorId = robot_utils::intmod(colorId_, colors_.size()); - - convexSetSequence.color.r = colors_[colorId].x(); - convexSetSequence.color.g = colors_[colorId].y(); - convexSetSequence.color.b = colors_[colorId].z(); - - convexSetSequence.id = id; - convexSetSequence.ns = "convex_set" + std::to_string(convexSetSequence.id); - - geometry_msgs::Point point; - convexSetSequence.points.reserve(convexSet.getConvexSetInWorldFrame().getVertices().size()); - for (const auto& vertex : convexSet.getConvexSetInWorldFrame().getVertices()) { - const loco::Position positionWorldToVertexInWorldFrame = - loco::Position(vertex.x(), vertex.y(), 0.0); - point.x = positionWorldToVertexInWorldFrame.x(); - point.y = positionWorldToVertexInWorldFrame.y(); - point.z = positionWorldToVertexInWorldFrame.z(); - convexSetSequence.points.push_back(point); - } - - // Add first point again to reconnect the polygon. - if (convexSetSequence.points.size() > 2) { - convexSetSequence.points.push_back(convexSetSequence.points.front()); - convexSetSequence_.markers.push_back(convexSetSequence); - } - - ++id; - } - } - - return true; -} - -bool ConvexSetSequence::publish() { - loco_ros::publishMsg(publisher_, convexSetSequence_); - return true; -} - -unsigned int ConvexSetSequence::getNumSubscribers() const { - return publisher_.getNumSubscribers(); -} - -} /* namespace loco */ From 5d39a29acbd32c8edeff0f4b5431688f37549c39 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Wed, 25 Mar 2020 23:09:43 +0100 Subject: [PATCH 026/504] Fix, normal vector in world frame. --- .../sliding_window_plane_extractor.hpp | 17 ++++++------- convex_plane_decomposition/src/pipeline.cpp | 1 - .../src/sliding_window_plane_extractor.cpp | 24 +++++++++++++++---- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp index f260bc6e..36211326 100644 --- a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp +++ b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp @@ -46,21 +46,18 @@ namespace sliding_window_plane_extractor { return labeled_image_; } - const auto& getLabelPlaneParameterMap() const{ - return label_plane_parameters_map_; - } + const auto& getLabelPlaneParameterMap() const{ return label_plane_parameters_map_; } - const int getNumberOfExtractedPlanes() const{ - return number_of_extracted_planes_; - } + const int getNumberOfExtractedPlanes() const { return number_of_extracted_planes_; } -// void exportConvexPolygons(const std::string& path) const; + // void exportConvexPolygons(const std::string& path) const; private: - double computeAverageErrorToPlane(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector, const std::vector& points_with_normal) const; + void computeMapTransformation(); + void computePlaneParametersForLabel(int label); void extractPlaneParametersFromLabeledImage(); @@ -73,10 +70,11 @@ namespace sliding_window_plane_extractor { void runSurfaceNormalCurvatureDetection(); - grid_map::GridMap& map_; std::string elevation_layer_; double resolution_; + Eigen::Matrix2d transformation_xy_to_world_frame_; + Eigen::Vector2d map_offset_; SlidingWindowPlaneExtractorParameters parameters_; ransac_plane_extractor::RansacPlaneExtractorParameters ransac_parameters_; @@ -85,7 +83,6 @@ namespace sliding_window_plane_extractor { cv::Mat labeled_image_; int number_of_extracted_planes_; std::map label_plane_parameters_map_; - }; } #endif //CONVEX_PLANE_EXTRACTION_INCLUDE_SLIDING_WINDOW_PLANE_EXTRACTOR_HPP_ diff --git a/convex_plane_decomposition/src/pipeline.cpp b/convex_plane_decomposition/src/pipeline.cpp index 27929c4a..ea792b53 100644 --- a/convex_plane_decomposition/src/pipeline.cpp +++ b/convex_plane_decomposition/src/pipeline.cpp @@ -26,7 +26,6 @@ Polygon3dVectorContainer Pipeline::getPlaneContours() const{ return plane_factory_.getPlaneContoursInWorldFrame(); } - //void Pipeline::exportConvexPolygons(const std::string& export_path) const { // std::ofstream output_file; // output_file.open(export_path + "convex_polygons.txt", std::ofstream::app); diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index ee8075c8..6da3f5d1 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -11,6 +11,7 @@ namespace sliding_window_plane_extractor{ elevation_layer_(layer_height), parameters_(parameters), ransac_parameters_(parameters.ransac_parameters){ + computeMapTransformation(); VLOG(1) << "Constructing SWE..."; VLOG(1) << "Set elevation layer is: " << elevation_layer_; CHECK(map_.exists(elevation_layer_)); @@ -78,15 +79,18 @@ namespace sliding_window_plane_extractor{ } } Eigen::Vector3d eigenvector = eigenvectors.col(smallestId); - const Eigen::Vector3d normalVectorPositiveAxis_(0,0,1); - if (eigenvector.dot(normalVectorPositiveAxis_) < 0.0) eigenvector = -eigenvector; + const Eigen::Vector3d normalVectorPositiveAxis(0, 0, 1); + if (eigenvector.dot(normalVectorPositiveAxis) < 0.0) { + eigenvector = -eigenvector; + } Eigen::Vector3d n = eigenvector.normalized(); grid_map::Index index = *window_iterator; double mean_error = ((data_points * n).cwiseAbs()).sum() / height_instances.size(); - Eigen::Vector3d upwards(0,0,1); + Eigen::Vector3d upwards(0, 0, 1); constexpr double kInclinationThreshold = 0.35; - if (mean_error < parameters_.plane_patch_error_threshold && abs(n.transpose()*upwards) > kInclinationThreshold) { + if (mean_error < parameters_.plane_patch_error_threshold && abs(n.transpose() * upwards) > kInclinationThreshold) { binary_image_patch_.at((*window_iterator).x(), (*window_iterator).y()) = true; + n.head(2) = transformation_xy_to_world_frame_ * n.head(2); normal_x(index.x(), index.y()) = n.x(); normal_y(index.x(), index.y()) = n.y(); normal_z(index.x(), index.y()) = n.z(); @@ -285,5 +289,15 @@ namespace sliding_window_plane_extractor{ VLOG(1) << "done."; } -} + void SlidingWindowPlaneExtractor::computeMapTransformation() { + Eigen::Vector2i map_size = map_.getSize(); + CHECK(map_.getPosition(Eigen::Vector2i::Zero(), map_offset_)); + Eigen::Vector2d lower_left_cell_position; + CHECK(map_.getPosition(Eigen::Vector2i(map_size.x() - 1, 0), lower_left_cell_position)); + Eigen::Vector2d upper_right_cell_position; + CHECK(map_.getPosition(Eigen::Vector2i(0, map_size.y() - 1), upper_right_cell_position)); + transformation_xy_to_world_frame_.col(0) = (lower_left_cell_position - map_offset_).normalized(); + transformation_xy_to_world_frame_.col(1) = (upper_right_cell_position - map_offset_).normalized(); + } + } // namespace sliding_window_plane_extractor From 5050db322e3fa4a445e0c8d9f6161c399b6323bd Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Wed, 25 Mar 2020 23:16:50 +0100 Subject: [PATCH 027/504] Removed deprecated directories. --- include/geometry_utils.hpp | 23 --------------- src/geometry_utils.cpp | 60 -------------------------------------- 2 files changed, 83 deletions(-) delete mode 100644 include/geometry_utils.hpp delete mode 100644 src/geometry_utils.cpp diff --git a/include/geometry_utils.hpp b/include/geometry_utils.hpp deleted file mode 100644 index a2b1f786..00000000 --- a/include/geometry_utils.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ - -#include "types.hpp" - -namespace convex_plane_extraction { - -double scalarCrossProduct(const Vector2d &leftVector, const Vector2d &rightVector); - -double distanceToLine(const Vector2d& lineSupportVector, const Vector2d& lineDirectionalVector, const Vector2d& testPoint); - -bool isPointOnRightSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); - -double computeAngleBetweenVectors(const Vector2d& first_vector, const Vector2d& second_vector); - -bool isPointOnLeftSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); - -bool intersectRayWithLineSegment(const Vector2d& ray_source, const Vector2d& ray_direction, - const Vector2d& segment_source, const Vector2d& segment_target, Vector2d* intersection_point); - -double distanceBetweenPoints(Vector2d first, Vector2d second); -} -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ diff --git a/src/geometry_utils.cpp b/src/geometry_utils.cpp deleted file mode 100644 index fb794e89..00000000 --- a/src/geometry_utils.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include "geometry_utils.hpp" - -namespace convex_plane_extraction { - - double scalarCrossProduct(const Vector2d &leftVector, const Vector2d &rightVector) { - return leftVector.y() * rightVector.x() - leftVector.x() * rightVector.y(); - } - - // Return the non-normalized distance of a 2D-point to a line given by support vector and direction vector. - // Negative distance corresponds to a point on the left of the direction vector - double distanceToLine(const Vector2d &lineSupportVector, - const Vector2d &lineDirectionalVector, - const Vector2d &testPoint) { - Vector2d secondPointOnLine = lineSupportVector + lineDirectionalVector; - return scalarCrossProduct(lineDirectionalVector, testPoint) - + scalarCrossProduct(lineSupportVector, secondPointOnLine); - } - - bool isPointOnRightSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point){ - Vector2d normal_vector(line_direction_vector.y(), (-1.0)*line_direction_vector.x()); - normal_vector.normalize(); - Vector2d point_vector = point - line_support_vector; - return point_vector.transpose() * normal_vector > 0; - } - - bool isPointOnLeftSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point){ - Vector2d normal_vector(line_direction_vector.y(), (-1.0)*line_direction_vector.x()); - normal_vector.normalize(); - Vector2d point_vector = point - line_support_vector; - return point_vector.dot(normal_vector) < 0; - } - - double computeAngleBetweenVectors(const Vector2d& first_vector, const Vector2d& second_vector){ - double scalar_product = first_vector.transpose() * second_vector; - return acos( abs(scalar_product) / (first_vector.norm() * second_vector.norm())); - } - - bool intersectRayWithLineSegment(const Vector2d& ray_source, const Vector2d& ray_direction, - const Vector2d& segment_source, const Vector2d& segment_target, Vector2d* intersection_point){ - CHECK_NOTNULL(intersection_point); - Vector2d segment_direction = segment_target - segment_source; - Matrix2d A; - A.col(0) = ray_direction; - A.col(1) = - segment_direction; - Vector2d b = segment_source - ray_source; - Vector2d solution = A.fullPivHouseholderQr().solve(b); - if (solution(0) <= 0 || solution(1) < 0 || solution(1) > 1){ - return false; - } - *intersection_point = segment_source + solution(1) * segment_direction; - return true; - } - - double distanceBetweenPoints(Vector2d first, Vector2d second){ - return (second - first).norm(); - } - -} - From 1071441a389a96579a4b08bcde03b337834d85c0 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Thu, 26 Mar 2020 12:56:19 +0100 Subject: [PATCH 028/504] Fix surface normal gradient and parameter tuning. --- convex_plane_decomposition/src/polygon.cpp | 31 ++++++++++--------- .../src/sliding_window_plane_extractor.cpp | 31 ++++++++++++------- .../config/parameters.yaml | 4 +-- .../src/pipeline_ros.cpp | 4 +++ 4 files changed, 41 insertions(+), 29 deletions(-) diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 6b336521..5bc7ff4c 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -77,17 +77,17 @@ namespace convex_plane_extraction { auto third_vertex_it = std::next(second_vertex_it); double area = polygon->area(); int number_of_iterations = 0; - while (number_of_iterations < max_number_of_iterations ){ + while (number_of_iterations < max_number_of_iterations ) { old_size = polygon->size(); - if (polygon->size() < 4){ + if (polygon->size() < 4) { break; } Vector2d first_point(first_vertex_it->x(), first_vertex_it->y()); Vector2d second_point(second_vertex_it->x(), second_vertex_it->y()); Vector2d third_point(third_vertex_it->x(), third_vertex_it->y()); - LOG(WARNING) << "Got here!"; + VLOG(2) << "Got here!"; if (isPointOnRightSideOfLine(first_point, third_point - first_point, second_point)) { - VLOG(1) << "Point on right side!"; + VLOG(2) << "Point on right side!"; double a = (third_point - first_point).norm(); double b = (second_point - third_point).norm(); double c = (first_point - second_point).norm(); @@ -95,28 +95,29 @@ namespace convex_plane_extraction { CHECK(isfinite(triangle_area)) << "Area: " << triangle_area << ", a: " << a << ", b: " << b << ", c: " << c; CHECK_GE(triangle_area, 0.0); if ((triangle_area < relative_area_threshold * area) && (triangle_area < absolute_area_threshold)) { - VLOG(1) << "Area sufficiently small!"; + VLOG(2) << "Area sufficiently small!"; CgalPolygon2d new_polygon(*polygon); int vertex_position_offset = std::distance(polygon->vertices_begin(), second_vertex_it); CgalPolygon2dVertexIterator tmp_iterator = new_polygon.vertices_begin(); std::advance(tmp_iterator, vertex_position_offset); - VLOG(1) << "Before erase call!"; + VLOG(2) << "Before erase call!"; new_polygon.erase(tmp_iterator); - VLOG(1) << "After ease call!"; - if (new_polygon.is_simple() && (new_polygon.orientation() == CGAL::COUNTERCLOCKWISE) && abs(new_polygon.area() - area) < 0.1 * area && abs(new_polygon.area() - area) < 0.5) { + VLOG(2) << "After ease call!"; + if (new_polygon.is_simple() && (new_polygon.orientation() == CGAL::COUNTERCLOCKWISE) && + abs(new_polygon.area() - area) < 0.1 * area && abs(new_polygon.area() - area) < 0.5) { CHECK_LE(triangle_area, area); first_vertex_it = polygon->erase(second_vertex_it); - if (first_vertex_it == polygon->vertices_end()){ + if (first_vertex_it == polygon->vertices_end()) { first_vertex_it = polygon->vertices_begin(); } second_vertex_it = next(first_vertex_it, *polygon); third_vertex_it = next(second_vertex_it, *polygon); if ((std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), second_vertex_it)) || (std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), third_vertex_it)) || - (std::distance(polygon->begin(), second_vertex_it) >= std::distance(polygon->begin(), third_vertex_it))){ + (std::distance(polygon->begin(), second_vertex_it) >= std::distance(polygon->begin(), third_vertex_it))) { ++number_of_iterations; } - VLOG(1) << "Removed one vertex!"; + VLOG(2) << "Removed one vertex!"; continue; } } @@ -124,11 +125,11 @@ namespace convex_plane_extraction { first_vertex_it = second_vertex_it; second_vertex_it = third_vertex_it; third_vertex_it = next(second_vertex_it, *polygon); - LOG(WARNING) << "Got to bottom! Number of iterations: " << std::distance(polygon->begin(), first_vertex_it) << " " << - std::distance(polygon->begin(), second_vertex_it) << " " << std::distance(polygon->begin(), third_vertex_it); + VLOG(2) << "Got to bottom! Number of iterations: " << std::distance(polygon->begin(), first_vertex_it) << " " + << std::distance(polygon->begin(), second_vertex_it) << " " << std::distance(polygon->begin(), third_vertex_it); if ((std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), second_vertex_it) || - std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), third_vertex_it) || - std::distance(polygon->begin(), second_vertex_it) >= std::distance(polygon->begin(), third_vertex_it) )){ + std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), third_vertex_it) || + std::distance(polygon->begin(), second_vertex_it) >= std::distance(polygon->begin(), third_vertex_it))) { ++number_of_iterations; } } diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index 6da3f5d1..980ab6d7 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -109,18 +109,25 @@ namespace sliding_window_plane_extractor{ CHECK_GT(surface_normal_map_boundary_offset, 0); const grid_map::Size map_rows_cols = map_.getSize(); for( int cols = surface_normal_map_boundary_offset; cols < map_rows_cols(1) - surface_normal_map_boundary_offset - 1; ++cols){ - for (int rows = surface_normal_map_boundary_offset; rows < map_rows_cols(0) - surface_normal_map_boundary_offset - 1; ++rows){ - const Eigen::Vector3f normal_vector_center(map_.at("normals_x", grid_map::Index(rows, cols)), map_.at("normals_y", grid_map::Index(rows, cols)), - map_.at("normals_z", grid_map::Index(rows, cols))); - const Eigen::Vector3f normal_vector_next_row(map_.at("normals_x", grid_map::Index(rows+1, cols)), map_.at("normals_y", grid_map::Index(rows+1, cols)), - map_.at("normals_z", grid_map::Index(rows+1, cols))); - const Eigen::Vector3f normal_vector_next_col(map_.at("normals_x", grid_map::Index(rows, cols+1)), map_.at("normals_y", grid_map::Index(rows, cols+1)), - map_.at("normals_z", grid_map::Index(rows, cols+1))); - const float angle_in_col_direction_radians = std::atan2(1.0, normal_vector_center.dot(normal_vector_next_col)); - const float angle_in_row_direction_radians = std::atan2(1.0, normal_vector_center.dot(normal_vector_next_row)); - const double gradient_magnitude_normalized = sqrt((angle_in_col_direction_radians*angle_in_col_direction_radians) + - (angle_in_row_direction_radians * angle_in_row_direction_radians)) / (sqrt(2.0)*M_PI); - binary_image_angle_.at(rows, cols) = gradient_magnitude_normalized <= parameters_.surface_normal_angle_threshold_degrees; + for (int rows = surface_normal_map_boundary_offset; rows < map_rows_cols(0) - surface_normal_map_boundary_offset - 1; ++rows) { + const Eigen::Vector3f normal_vector_center(map_.at("normals_x", grid_map::Index(rows, cols)), + map_.at("normals_y", grid_map::Index(rows, cols)), + map_.at("normals_z", grid_map::Index(rows, cols))); + const Eigen::Vector3f normal_vector_next_row(map_.at("normals_x", grid_map::Index(rows + 1, cols)), + map_.at("normals_y", grid_map::Index(rows + 1, cols)), + map_.at("normals_z", grid_map::Index(rows + 1, cols))); + const Eigen::Vector3f normal_vector_next_col(map_.at("normals_x", grid_map::Index(rows, cols + 1)), + map_.at("normals_y", grid_map::Index(rows, cols + 1)), + map_.at("normals_z", grid_map::Index(rows, cols + 1))); + const double angle_in_col_direction_deg = + std::atan2(normal_vector_center.cross(normal_vector_next_col).norm(), normal_vector_center.dot(normal_vector_next_col)) / M_PI * + 180.0; + const double angle_in_row_direction_deg = + std::atan2(normal_vector_center.cross(normal_vector_next_row).norm(), normal_vector_center.dot(normal_vector_next_row)) / M_PI * + 180.0; + binary_image_angle_.at(rows, cols) = isfinite(angle_in_col_direction_deg) && isfinite(angle_in_row_direction_deg) && + abs(angle_in_col_direction_deg) <= parameters_.surface_normal_angle_threshold_degrees && + abs(angle_in_row_direction_deg) <= parameters_.surface_normal_angle_threshold_degrees; } } } diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 105ceb7e..95215c2d 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -20,8 +20,8 @@ convex_decomposer: sliding_window_plane_extractor: kernel_size : 3 plane_patch_error_threshold : 0.004 - surface_normal_angle_threshold_degrees : 5.0 - include_curvature_detection : false + surface_normal_angle_threshold_degrees : 10.0 + include_curvature_detection : true include_ransac_refinement : false global_plane_fit_error_threshold : 0.02 diff --git a/convex_plane_decomposition_ros/src/pipeline_ros.cpp b/convex_plane_decomposition_ros/src/pipeline_ros.cpp index 87b98d34..3bdd77b5 100644 --- a/convex_plane_decomposition_ros/src/pipeline_ros.cpp +++ b/convex_plane_decomposition_ros/src/pipeline_ros.cpp @@ -20,6 +20,10 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map: sliding_window_plane_extractor_parameters.plane_patch_error_threshold)) { ROS_ERROR("Could not read parameter `plane_patch_error_threshold`. Setting parameter to default value."); } + if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "surface_normal_angle_threshold_degrees", + sliding_window_plane_extractor_parameters.surface_normal_angle_threshold_degrees)) { + ROS_ERROR("Could not read parameter `plane_patch_error_threshold`. Setting parameter to default value."); + } if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "include_curvature_detection", sliding_window_plane_extractor_parameters.include_curvature_detection)) { ROS_ERROR("Could not read parameter `include_curvature_detection`. Setting parameter to default value."); From 24b51a2770cd40337400a4445bd9825ceb69c699 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Sat, 28 Mar 2020 00:27:01 +0100 Subject: [PATCH 029/504] Fixes for inner convex approximation, to be continued. --- .../include/polygon.hpp | 37 ++++++++----- .../src/convex_decomposer.cpp | 23 +++++--- .../src/geometry_utils.cpp | 52 ++++++++++++------ convex_plane_decomposition/src/pipeline.cpp | 5 +- convex_plane_decomposition/src/polygon.cpp | 55 +++++++++++++++---- .../src/sliding_window_plane_extractor.cpp | 2 +- .../config/parameters.yaml | 6 +- .../src/convex_plane_extraction_ros.cpp | 4 +- 8 files changed, 127 insertions(+), 57 deletions(-) diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index b6d5a2b2..0f8b5085 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -9,14 +9,15 @@ #include #include -#include -#include #include #include #include -#include +#include #include #include +#include +#include +#include #include #include @@ -35,24 +36,31 @@ namespace convex_plane_extraction{ typedef CGAL::Polygon_2 CgalPolygon2d; typedef CGAL::Polygon_with_holes_2 CgalPolygonWithHoles2d; typedef Traits::Segment_2 CgalSegment2d; - typedef std::vector CgalPolygon2dContainer; - typedef CgalPolygon2dContainer::const_iterator CgalPolygon2dConstIterator; + typedef std::vector CgalPolygon2dContainer; + typedef Traits::Ray_2 CgalRay2d; + typedef CgalPolygon2dContainer::const_iterator CgalPolygon2dConstIterator; typedef CGAL::Polygon_set_2> CgalPolygon2dSetContainer; typedef CgalPolygon2d::Vertex_const_iterator CgalPolygon2dVertexConstIterator; - typedef CgalPolygon2d::Vertex_iterator CgalPolygon2dVertexIterator; + typedef CgalPolygon2d::Vertex_iterator CgalPolygon2dVertexIterator; - typedef std::vector Polygon3d; - typedef std::vector Polygon3dVectorContainer; - typedef K::Intersect_2 Intersect_2; + typedef std::vector Polygon3d; + typedef std::vector Polygon3dVectorContainer; + typedef K::Intersect_2 Intersect_2; - struct PolygonWithHoles{ + struct PolygonWithHoles { CgalPolygon2d outer_contour; CgalPolygon2dContainer holes; }; + enum class SegmentIntersectionLocation { kSource, kTarget, kInterior }; + + struct RaySegmentIntersection { + SegmentInterSectionLocation intersection_location; + CgalPoint2d intersection_point; + }; template - bool isContourSimple_impl(Iter begin, Iter end, std::bidirectional_iterator_tag){ + bool isContourSimple_impl(Iter begin, Iter end, std::bidirectional_iterator_tag) { CgalPolygon2d polygon; for (auto it = begin; it < end; ++it) { polygon.push_back(Point((*it).x, (*it).y)); @@ -160,6 +168,9 @@ void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, do std::vector> getCommonVertexPairIndices(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon); - std::vector getVertexIndicesOfFirstPolygonContainedInSecondPolygonContour(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon); -} + std::vector getVertexIndicesOfFirstPolygonContainedInSecondPolygonContour(const CgalPolygon2d& first_polygon, + const CgalPolygon2d& second_polygon); + + bool doRayAndSegmentIntersect(const CgalRay2d& ray, const CgalSegment2d& segment, RaySegmentIntersection* intersection); + } // namespace convex_plane_extraction #endif //CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGON_HPP_ diff --git a/convex_plane_decomposition/src/convex_decomposer.cpp b/convex_plane_decomposition/src/convex_decomposer.cpp index 13e38836..aa064e02 100644 --- a/convex_plane_decomposition/src/convex_decomposer.cpp +++ b/convex_plane_decomposition/src/convex_decomposer.cpp @@ -53,11 +53,17 @@ CgalPolygon2dContainer ConvexDecomposer::performOptimalConvexDecomposition(const return output_polygons; } -CgalPolygon2dContainer ConvexDecomposer::performInnerConvexApproximation(const CgalPolygon2d& polygon) const{ +CgalPolygon2dContainer ConvexDecomposer::performInnerConvexApproximation(const CgalPolygon2d& polygon) const { CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); + VLOG(1) << "Polygon under decomposition: "; + printPolygon(polygon); CgalPolygon2dContainer convex_polygons; + if (polygon.size() == 3) { + convex_polygons.push_back(polygon); + return convex_polygons; + } const std::multimap dent_locations = detectDentLocations(polygon); - if (dent_locations.empty()){ + if (dent_locations.empty()) { // No dents detected, polygon must be convex. // CGAL convexity check might still fail, since very shallow dents are ignored. convex_polygons.push_back(polygon); @@ -85,13 +91,15 @@ CgalPolygon2dContainer ConvexDecomposer::performInnerConvexApproximation(const C polygon_counterclockwise_2.push_back(*first_vertex_to_erase_it); first_vertex_to_erase_it = next(first_vertex_to_erase_it, polygon_counterclockwise_1); auto last_vertex_to_erase_it = polygon_counterclockwise_1.vertices_begin(); + VLOG(1) << "Add dent to second polygon succeeded."; // Intersection somewhere must be at or after source vertex of intersection edge. std::advance(last_vertex_to_erase_it, intersection_counterclockwise.edge_source_location_); // Take next vertex due to exclusive upper limit logic. last_vertex_to_erase_it = next(last_vertex_to_erase_it, polygon_counterclockwise_1); // Copy vertices that will be deleted to second polygon. - copyVertices(polygon_counterclockwise_1,first_vertex_to_erase_it,last_vertex_to_erase_it, - &polygon_counterclockwise_2, polygon_counterclockwise_2.vertices_end()); + copyVertices(polygon_counterclockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_2, + polygon_counterclockwise_2.vertices_end()); + VLOG(1) << "Copy vertices that will be deleted succeeded."; // Get last point that was erased. CgalPoint2d point_before_intersection = *(previous(last_vertex_to_erase_it, polygon_counterclockwise_2)); // To avoid numerical issues and duplicate vertices, intersection point is only inserted if sufficiently @@ -101,7 +109,8 @@ CgalPolygon2dContainer ConvexDecomposer::performInnerConvexApproximation(const C polygon_counterclockwise_2.push_back(intersection_counterclockwise.intersection_point_); } VLOG(1) << "Started splitting vertices..."; - CgalPolygon2dVertexIterator element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); + CgalPolygon2dVertexIterator element_behind_deleted_it = + erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); // Add intersection vertex to first polygon if existing vertex too far away. if ((intersection_counterclockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { polygon_counterclockwise_1.insert(element_behind_deleted_it, intersection_counterclockwise.intersection_point_); @@ -171,8 +180,8 @@ CgalPolygon2dContainer ConvexDecomposer::performInnerConvexApproximation(const C recursion_2 = performInnerConvexApproximation(polygon_clockwise_2); } } - std::move(recursion_1.begin(),recursion_1.end(), std::back_inserter(convex_polygons)); - std::move(recursion_1.begin(), recursion_2.end(), std::back_inserter(convex_polygons)); + std::move(recursion_1.begin(), recursion_1.end(), std::back_inserter(convex_polygons)); + std::move(recursion_2.begin(), recursion_2.end(), std::back_inserter(convex_polygons)); VLOG(1) << "Reached bottom!"; return convex_polygons; } diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp index 3e6088c7..171c61bc 100644 --- a/convex_plane_decomposition/src/geometry_utils.cpp +++ b/convex_plane_decomposition/src/geometry_utils.cpp @@ -45,27 +45,30 @@ namespace convex_plane_extraction { A.col(1) = - segment_direction; Vector2d b = segment_source - ray_source; auto householder_qr = A.fullPivHouseholderQr(); - if (householder_qr.rank() < 2){ + if (householder_qr.rank() < 2) { // Check whether segment and ray overlap. - Vector2d p_ray_source_segment_source = segment_source - ray_source; - Vector2d ray_parameter_solution = Vector2d(p_ray_source_segment_source.x() / ray_direction.x(), - p_ray_source_segment_source.y() / ray_direction.y()); + const Vector2d p_ray_source_segment_source = segment_source - ray_source; + const Vector2d p_ray_source_segment_target = segment_target - ray_source; + if (p_ray_source_segment_source.norm() > p_ray_source_segment_target) { + } + Vector2d ray_parameter_solution = + Vector2d(p_ray_source_segment_source.x() / ray_direction.x(), p_ray_source_segment_source.y() / ray_direction.y()); constexpr double kSolutionDeviation = 0.0001; - if (abs(ray_parameter_solution.x() - ray_parameter_solution.y()) < kSolutionDeviation){ + if (abs(ray_parameter_solution.x() - ray_parameter_solution.y()) < kSolutionDeviation) { double parameter_solution_tmp = ray_parameter_solution.mean(); - if (parameter_solution_tmp < 0){ + if (parameter_solution_tmp < 0) { return false; } CHECK_GT(parameter_solution_tmp, 0); Vector2d p_ray_source_segment_target = segment_target - ray_source; - ray_parameter_solution = Vector2d(p_ray_source_segment_target.x() / ray_direction.x(), - p_ray_source_segment_target.y() / ray_direction.y()); + ray_parameter_solution = + Vector2d(p_ray_source_segment_target.x() / ray_direction.x(), p_ray_source_segment_target.y() / ray_direction.y()); // If ray is parallel (rank loss) and source point lies on ray, then target point has to as well. - CHECK(abs(ray_parameter_solution.x() - ray_parameter_solution.y()) < kSolutionDeviation); - if(ray_parameter_solution.mean() < 0){ + CHECK_LT(abs(ray_parameter_solution.x() - ray_parameter_solution.y()), kSolutionDeviation); + if (ray_parameter_solution.mean() < 0) { return false; } - if (ray_parameter_solution.mean() < parameter_solution_tmp){ + if (ray_parameter_solution.mean() < parameter_solution_tmp) { *intersection_point = segment_target; } else { *intersection_point = segment_source; @@ -77,11 +80,26 @@ namespace convex_plane_extraction { Vector2d solution = householder_qr.solve(b); Vector2d ray_solution = ray_source + solution(0) * segment_direction; Vector2d segment_solution = segment_source + solution(1) * segment_direction; - if (solution(0) <= 1 || solution(1) < 0 || solution(1) > 1){ + constexpr double kSegmentBorderToleranceMeters = 0.001; + if (solution(0) <= 1) { return false; + } else if (solution(1) < 0) { + if ((segment_solution - segment_source).norm() > kSegmentBorderToleranceMeters) { + return false; + } else { + *intersection_point = segment_source; + return true; + } + } else if (solution(1) > 1) { + if ((segment_solution - segment_target).norm() > kSegmentBorderToleranceMeters) { + return false; + } else { + *intersection_point = segment_target; + } + } else { + *intersection_point = segment_solution; + return true; } - *intersection_point = segment_solution; - return true; } bool intersectLineSegmentWithLineSegment(const Vector2d& segment_1_source, const Vector2d& segment_1_target, @@ -114,7 +132,7 @@ namespace convex_plane_extraction { if(ray_parameter_solution.mean() < 0){ return false; } - if (ray_parameter_solution.mean() < parameter_solution_tmp){ + if (ray_parameter_solution.mean() < parameter_solution_tmp) { *intersection_point = segment_2_target; } else { *intersection_point = segment_2_source; @@ -123,10 +141,10 @@ namespace convex_plane_extraction { } return false; } - Vector2d solution = householder_qr.solve(b); + Vector2d solution = A.inverse() * b; // householder_qr.solve(b); Vector2d ray_solution = segment_1_source + solution(0) * segment_2_direction; Vector2d segment_solution = segment_2_source + solution(1) * segment_2_direction; - if (solution(0) < 0 || solution(0) > 1 || solution(1) < 0 || solution(1) > 1){ + if (solution(0) < 0 || solution(0) > 1 || solution(1) < 0 || solution(1) > 1) { return false; } *intersection_point = segment_solution; diff --git a/convex_plane_decomposition/src/pipeline.cpp b/convex_plane_decomposition/src/pipeline.cpp index ea792b53..1811f0e4 100644 --- a/convex_plane_decomposition/src/pipeline.cpp +++ b/convex_plane_decomposition/src/pipeline.cpp @@ -14,8 +14,9 @@ Pipeline::Pipeline(const PipelineParameters& pipeline_parameters, const GridMapP sliding_window_plane_extractor_.runExtraction(); VLOG(1) << "done"; plane_factory_.createPlanesFromLabeledImageAndPlaneParameters(sliding_window_plane_extractor_.getLabeledImage(), - sliding_window_plane_extractor_.getNumberOfExtractedPlanes(), sliding_window_plane_extractor_.getLabelPlaneParameterMap()); - //plane_factory_.decomposePlanesInConvexPolygons(); + sliding_window_plane_extractor_.getNumberOfExtractedPlanes(), + sliding_window_plane_extractor_.getLabelPlaneParameterMap()); + plane_factory_.decomposePlanesInConvexPolygons(); } Polygon3dVectorContainer Pipeline::getConvexPolygons() const{ diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 5bc7ff4c..0f29587d 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -244,21 +244,22 @@ namespace convex_plane_extraction { Vector2d segment_target = Vector2d(segment_target_it->x(), segment_target_it->y()); Vector2d intersection_point; if (intersectRayWithLineSegment(ray_source, ray_direction, segment_source, segment_target, - &intersection_point)){ + &intersection_point)) { LOG(INFO) << "Intersection point:" << intersection_point; LOG(INFO) << segment_source; - if ((ray_target - intersection_point).norm() < 0.001){ - LOG(INFO) << segment_source; - vertex_it = next(vertex_it, polygon); - continue; - } + // if ((ray_target - intersection_point).norm() < 0.001){ + // LOG(INFO) << ray_target; + // vertex_it = next(vertex_it, polygon); + // continue; + // } double current_distance = distanceBetweenPoints(ray_target, intersection_point); // Take first intersection on ray. - if (current_distance < min_distance){ + if (current_distance < min_distance) { one_intersection_at_least = true; min_distance = current_distance; intersection_tmp.setAllMembers(std::distance(polygon.vertices_begin(), vertex_it), - std::distance(polygon.vertices_begin(), segment_target_it), CgalPoint2d(intersection_point.x(), intersection_point.y())); + std::distance(polygon.vertices_begin(), segment_target_it), + CgalPoint2d(intersection_point.x(), intersection_point.y())); } } vertex_it = next(vertex_it, polygon); @@ -429,14 +430,44 @@ namespace convex_plane_extraction { return return_buffer; } - std::vector getVertexIndicesOfFirstPolygonContainedInSecondPolygonContour(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon){ + std::vector getVertexIndicesOfFirstPolygonContainedInSecondPolygonContour(const CgalPolygon2d& first_polygon, + const CgalPolygon2d& second_polygon) { std::vector return_buffer; - for (int vertex_index = 0; vertex_index < first_polygon.container().size(); ++vertex_index){ - if (second_polygon.has_on_boundary(first_polygon.container().at(vertex_index))){ + for (int vertex_index = 0; vertex_index < first_polygon.container().size(); ++vertex_index) { + if (second_polygon.has_on_boundary(first_polygon.container().at(vertex_index))) { return_buffer.push_back(vertex_index); } } return return_buffer; } -} + bool doRayAndSegmentIntersect(const CgalRay2d& ray, const CgalSegment2d& segment, RaySegmentIntersection* intersection) { + CGAL::cpp11::result_of::type result = CGAL::intersection(ray, segment); + if (result) { + if (const CgalSegment2d* s = boost::get(&*result)) { + if ((ray.source() - segment.source()).squared_length() < (ray.source() - segment.target()).squared_length()) { + intersection->intersection_location = SegmentIntersectionLocation::kSource; + intersection->intersection_point = segment.source(); + } else { + intersection->intersection_location = SegmentIntersectionLocation::kTarget; + intersection->intersection_point = segment.target(); + } + } else { + const CgalPoint2d* intersection_point = boost::get(&*result); + if (*intersection_point == segment.source()) { + intersection->intersection_location = SegmentIntersectionLocation::kSource; + intersection->intersection_point = segment.source(); + } else if (*intersection_point == segment.target()) { + intersection->intersection_location = SegmentIntersectionLocation::kTarget; + intersection->intersection_point = segment.target(); + } else { + intersection->intersection_location = SegmentIntersectionLocation::kInterior; + intersection->intersection_point = *intersection_point; + } + } + return true; + } + return false; + } + + } // namespace convex_plane_extraction diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index 980ab6d7..8cb62a8e 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -254,7 +254,7 @@ namespace sliding_window_plane_extractor{ } ++label_counter; } - CHECK_EQ(label_counter + 1, planes.size()); + CHECK_EQ(label_counter, planes.size()); number_of_extracted_planes_ += label_counter; refinement_performed = true; } diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 95215c2d..33e7f560 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -9,12 +9,12 @@ polygonizer: upsampling_factor : 3 activate_long_edge_upsampling : false activate_contour_approximation : true - contour_approximation_relative_area_threshold : 0.02 + contour_approximation_relative_area_threshold : 0.1 contour_approximation_absolute_area_threshold_squared_meters : 0.04 - max_number_of_iterations : 15 + max_number_of_iterations : 3 convex_decomposer: - decomposer_type : 'optimal_decompostion' + decomposer_type : 'inner_convex_decomposition' #'optimal_decompostion' dent_angle_threshold_rad : 0.001 sliding_window_plane_extractor: diff --git a/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp b/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp index 8d448778..4fb98843 100644 --- a/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp +++ b/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp @@ -51,14 +51,14 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { VLOG(1) << "done."; // Visualize in Rviz. jsk_recognition_msgs::PolygonArray outer_plane_contours = pipeline_ros.getOuterPlaneContours(); - //jsk_recognition_msgs::PolygonArray convex_polygons = pipeline_ros.getConvexPolygons(); + jsk_recognition_msgs::PolygonArray convex_polygons = pipeline_ros.getConvexPolygons(); pipeline_ros.augmentGridMapWithSegmentation(inputMap); grid_map_msgs::GridMap outputMessage; GridMapRosConverter::toMessage(inputMap, outputMessage); grid_map_publisher_.publish(outputMessage); - //convex_polygon_publisher_.publish(convex_polygons); + convex_polygon_publisher_.publish(convex_polygons); outer_contours_publisher_.publish(outer_plane_contours); } From 3388059a0e535702e6f9869faf1288a63a4ae3b7 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Sun, 29 Mar 2020 18:32:55 +0200 Subject: [PATCH 030/504] Fixed inner convex approximation intersection problems: CAUTION with inexact construction kernels. If performance not an issue, go for exact construction kernels. --- .../include/polygon.hpp | 22 +-- .../src/convex_decomposer.cpp | 115 ++++++++++---- .../src/geometry_utils.cpp | 139 +++++++++-------- convex_plane_decomposition/src/polygon.cpp | 147 +++++++++++++----- 4 files changed, 270 insertions(+), 153 deletions(-) diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index 0f8b5085..f5e617fe 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -29,15 +29,17 @@ namespace convex_plane_extraction{ - typedef CGAL::Exact_predicates_inexact_constructions_kernel K; - typedef CGAL::Partition_traits_2 Traits; - typedef CGAL::Point_2 CgalPoint2d; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Exact_predicates_exact_constructions_kernel EKernel; +typedef CGAL::Partition_traits_2 Traits; +typedef CGAL::Point_2 CgalPoint2d; typedef CGAL::Vector_2 CgalVector2d; typedef CGAL::Polygon_2 CgalPolygon2d; typedef CGAL::Polygon_with_holes_2 CgalPolygonWithHoles2d; typedef Traits::Segment_2 CgalSegment2d; typedef std::vector CgalPolygon2dContainer; typedef Traits::Ray_2 CgalRay2d; + typedef Traits::Circle_2 CgalCircle2d; typedef CgalPolygon2dContainer::const_iterator CgalPolygon2dConstIterator; typedef CGAL::Polygon_set_2> CgalPolygon2dSetContainer; typedef CgalPolygon2d::Vertex_const_iterator CgalPolygon2dVertexConstIterator; @@ -52,10 +54,10 @@ namespace convex_plane_extraction{ CgalPolygon2dContainer holes; }; - enum class SegmentIntersectionLocation { kSource, kTarget, kInterior }; + enum class SegmentIntersectionType : int { kSource, kTarget, kInterior }; struct RaySegmentIntersection { - SegmentInterSectionLocation intersection_location; + SegmentIntersectionType intersection_location; CgalPoint2d intersection_point; }; @@ -135,17 +137,18 @@ void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, do void setEdgeTargetLocation(const int location){ edge_target_location_ = location; } - void setIntersectionPoint(const CgalPoint2d& intersection_point){ - intersection_point_ = intersection_point; - } - void setAllMembers(const int source_location, const int target_location, const CgalPoint2d& intersection_point){ + void setIntersectionPoint(const CgalPoint2d& intersection_point) { intersection_point_ = intersection_point; } + void setAllMembers(const int source_location, const int target_location, const CgalPoint2d& intersection_point, + const SegmentIntersectionType& intersection_type) { edge_source_location_ = source_location; edge_target_location_ = target_location; + intersection_type_ = intersection_type; intersection_point_ = intersection_point; } int edge_source_location_; int edge_target_location_; + SegmentIntersectionType intersection_type_; CgalPoint2d intersection_point_; }; @@ -172,5 +175,6 @@ void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, do const CgalPolygon2d& second_polygon); bool doRayAndSegmentIntersect(const CgalRay2d& ray, const CgalSegment2d& segment, RaySegmentIntersection* intersection); + } // namespace convex_plane_extraction #endif //CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGON_HPP_ diff --git a/convex_plane_decomposition/src/convex_decomposer.cpp b/convex_plane_decomposition/src/convex_decomposer.cpp index aa064e02..3d914ebd 100644 --- a/convex_plane_decomposition/src/convex_decomposer.cpp +++ b/convex_plane_decomposition/src/convex_decomposer.cpp @@ -76,77 +76,124 @@ CgalPolygon2dContainer ConvexDecomposer::performInnerConvexApproximation(const C Intersection intersection_counterclockwise; intersection_clockwise_flag = intersectPolygonWithRay(dent_location, CGAL::COUNTERCLOCKWISE, polygon, &intersection_counterclockwise); - intersection_counterclockwise_flag = intersectPolygonWithRay(dent_location, CGAL::CLOCKWISE, - polygon, &intersection_clockwise); - if (!intersection_clockwise_flag || !intersection_counterclockwise_flag ){ + intersection_counterclockwise_flag = intersectPolygonWithRay(dent_location, CGAL::CLOCKWISE, polygon, &intersection_clockwise); + if (!intersection_clockwise_flag || !intersection_counterclockwise_flag) { LOG(FATAL) << "At least one intersection of dent ray with polygon failed!"; } + // Generate resulting polygons from cut. // Resulting cut from counter clockwise ray intersection. CgalPolygon2d polygon_counterclockwise_1 = polygon; CgalPolygon2d polygon_counterclockwise_2; + + SegmentIntersectionType intersection_type = intersection_counterclockwise.intersection_type_; + auto first_vertex_to_erase_it = polygon_counterclockwise_1.vertices_begin(); std::advance(first_vertex_to_erase_it, dent_location); // Add dent to second polygon. polygon_counterclockwise_2.push_back(*first_vertex_to_erase_it); + // First vertex to erase is the vertex following the dent. first_vertex_to_erase_it = next(first_vertex_to_erase_it, polygon_counterclockwise_1); + // Last vertex to erase is the source vertex of the intersecting polygon edge. auto last_vertex_to_erase_it = polygon_counterclockwise_1.vertices_begin(); - VLOG(1) << "Add dent to second polygon succeeded."; - // Intersection somewhere must be at or after source vertex of intersection edge. std::advance(last_vertex_to_erase_it, intersection_counterclockwise.edge_source_location_); // Take next vertex due to exclusive upper limit logic. last_vertex_to_erase_it = next(last_vertex_to_erase_it, polygon_counterclockwise_1); // Copy vertices that will be deleted to second polygon. copyVertices(polygon_counterclockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_2, polygon_counterclockwise_2.vertices_end()); - VLOG(1) << "Copy vertices that will be deleted succeeded."; - // Get last point that was erased. - CgalPoint2d point_before_intersection = *(previous(last_vertex_to_erase_it, polygon_counterclockwise_2)); - // To avoid numerical issues and duplicate vertices, intersection point is only inserted if sufficiently - // far away from exisiting vertex. - constexpr double kSquaredLengthThreshold = 1e-6; - if ((intersection_counterclockwise.intersection_point_ - point_before_intersection).squared_length() > kSquaredLengthThreshold) { - polygon_counterclockwise_2.push_back(intersection_counterclockwise.intersection_point_); - } - VLOG(1) << "Started splitting vertices..."; - CgalPolygon2dVertexIterator element_behind_deleted_it = - erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); - // Add intersection vertex to first polygon if existing vertex too far away. - if ((intersection_counterclockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { - polygon_counterclockwise_1.insert(element_behind_deleted_it, intersection_counterclockwise.intersection_point_); + + CgalPolygon2dVertexIterator element_behind_deleted_it; + + switch (intersection_type) { + case SegmentIntersectionType::kInterior: + polygon_counterclockwise_2.push_back(intersection_counterclockwise.intersection_point_); + element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); + polygon_counterclockwise_1.insert(element_behind_deleted_it, intersection_counterclockwise.intersection_point_); + break; + case SegmentIntersectionType::kSource: + element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); + // Add source vertex again to polygon, since it coincides with intersection point. + polygon_counterclockwise_1.insert(element_behind_deleted_it, intersection_counterclockwise.intersection_point_); + break; + case SegmentIntersectionType::kTarget: + // The intersection point coincides with the target of the intersecting polygon edge, and has to be added here. + polygon_counterclockwise_2.push_back(intersection_counterclockwise.intersection_point_); + element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); + break; } + + VLOG(1) << "Finished counter-clockwise cut."; + // Resulting cut from clockwise ray intersection. CgalPolygon2d polygon_clockwise_1 = polygon; CgalPolygon2d polygon_clockwise_2; + intersection_type = intersection_clockwise.intersection_type_; + + // First vertex, which is pruned off is the target of the intersecting polygon edge. first_vertex_to_erase_it = polygon_clockwise_1.vertices_begin(); std::advance(first_vertex_to_erase_it, intersection_clockwise.edge_target_location_); - if ((*first_vertex_to_erase_it - intersection_clockwise.intersection_point_).squared_length() > kSquaredLengthThreshold) { - polygon_clockwise_2.push_back(intersection_clockwise.intersection_point_); - } + // Last vertex, which is pruned off is the vertex before the dent. (Past-the-end-logic!) last_vertex_to_erase_it = polygon_clockwise_1.vertices_begin(); std::advance(last_vertex_to_erase_it, dent_location); - copyVertices(polygon_clockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_2, - polygon_clockwise_2.vertices_end()); - polygon_clockwise_2.push_back(*last_vertex_to_erase_it); - element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_1); - VLOG(1) << "done."; - if ((intersection_clockwise.intersection_point_ - *element_behind_deleted_it).squared_length() > kSquaredLengthThreshold) { - polygon_clockwise_1.insert(element_behind_deleted_it, intersection_clockwise.intersection_point_); + + switch (intersection_type) { + case SegmentIntersectionType::kInterior: + // First vertex to be added to new polygon is the intersection point. + polygon_clockwise_2.push_back(intersection_clockwise.intersection_point_); + // Added vertices to be deleted to new polygon (Past-the-end-logic!) + copyVertices(polygon_clockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_2, + polygon_clockwise_2.vertices_end()); + // Add dent vertex as well. + polygon_clockwise_2.push_back(*last_vertex_to_erase_it); + // Perform erase operation. + element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_1); + // Add intersection point to polygon. + polygon_clockwise_1.insert(element_behind_deleted_it, intersection_clockwise.intersection_point_); + break; + case SegmentIntersectionType::kSource: + // First vertex to be added to new polygon is source of intersecting polygon edge. + polygon_clockwise_2.push_back(intersection_clockwise.intersection_point_); // Intersection point is equivalent here with source. + // Added vertices to be deleted to new polygon (Past-the-end-logic!) + copyVertices(polygon_clockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_2, + polygon_clockwise_2.vertices_end()); + // Add dent vertex as well. + polygon_clockwise_2.push_back(*last_vertex_to_erase_it); + // Perform erase operation. + element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_1); + break; + case SegmentIntersectionType::kTarget: + // Added vertices to be deleted to new polygon (Past-the-end-logic!) + copyVertices(polygon_clockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_2, + polygon_clockwise_2.vertices_end()); + // Add dent vertex as well. + polygon_clockwise_2.push_back(*last_vertex_to_erase_it); + // Perform erase operation. + element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_1); + // Add intersection point to polygon, which is in this case the target vertex of the intersecting polygon edge. + polygon_clockwise_1.insert(element_behind_deleted_it, intersection_clockwise.intersection_point_); + break; } + + VLOG(1) << "Finished clockwise cut."; printPolygon(polygon_counterclockwise_1); printPolygon(polygon_counterclockwise_2); printPolygon(polygon_clockwise_1); printPolygon(polygon_clockwise_2); + CHECK(polygon_counterclockwise_1.is_simple()); + CHECK(polygon_counterclockwise_2.is_simple()); + CHECK(polygon_clockwise_1.is_simple()); + CHECK(polygon_clockwise_2.is_simple()); VLOG(1) << "Started cut area computation..."; // Take the cut with smallest min. area of resulting polygons. - double area[4] = {polygon_counterclockwise_1.area(), polygon_counterclockwise_2.area(), - polygon_clockwise_1.area(), polygon_clockwise_2.area()}; + double area[4] = {polygon_counterclockwise_1.area(), polygon_counterclockwise_2.area(), polygon_clockwise_1.area(), + polygon_clockwise_2.area()}; VLOG(1) << "done."; - double* min_area_strategy = std::min_element(area, area+4); + double* min_area_strategy = std::min_element(area, area + 4); CgalPolygon2dContainer recursion_1; CgalPolygon2dContainer recursion_2; - if ((min_area_strategy - area) < 2){ + if ((min_area_strategy - area) < 2) { // In this case the counter clockwise intersection leads to less loss in area. // Perform recursion with this split. if(polygon_counterclockwise_1.orientation() != CGAL::COUNTERCLOCKWISE){ diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp index 171c61bc..51aeb611 100644 --- a/convex_plane_decomposition/src/geometry_utils.cpp +++ b/convex_plane_decomposition/src/geometry_utils.cpp @@ -31,85 +31,86 @@ namespace convex_plane_extraction { return point_vector.dot(normal_vector) < 0; } - double computeAngleBetweenVectors(const Vector2d& first_vector, const Vector2d& second_vector){ + double computeAngleBetweenVectors(const Vector2d& first_vector, const Vector2d& second_vector) { double scalar_product = first_vector.transpose() * second_vector; - return acos( abs(scalar_product) / (first_vector.norm() * second_vector.norm())); + return acos(abs(scalar_product) / (first_vector.norm() * second_vector.norm())); } - bool intersectRayWithLineSegment(const Vector2d& ray_source, const Vector2d& ray_direction, - const Vector2d& segment_source, const Vector2d& segment_target, Vector2d* intersection_point){ - CHECK_NOTNULL(intersection_point); - Vector2d segment_direction = segment_target - segment_source; - Matrix2d A; - A.col(0) = ray_direction; - A.col(1) = - segment_direction; - Vector2d b = segment_source - ray_source; - auto householder_qr = A.fullPivHouseholderQr(); - if (householder_qr.rank() < 2) { - // Check whether segment and ray overlap. - const Vector2d p_ray_source_segment_source = segment_source - ray_source; - const Vector2d p_ray_source_segment_target = segment_target - ray_source; - if (p_ray_source_segment_source.norm() > p_ray_source_segment_target) { - } - Vector2d ray_parameter_solution = - Vector2d(p_ray_source_segment_source.x() / ray_direction.x(), p_ray_source_segment_source.y() / ray_direction.y()); - constexpr double kSolutionDeviation = 0.0001; - if (abs(ray_parameter_solution.x() - ray_parameter_solution.y()) < kSolutionDeviation) { - double parameter_solution_tmp = ray_parameter_solution.mean(); - if (parameter_solution_tmp < 0) { - return false; - } - CHECK_GT(parameter_solution_tmp, 0); - Vector2d p_ray_source_segment_target = segment_target - ray_source; - ray_parameter_solution = - Vector2d(p_ray_source_segment_target.x() / ray_direction.x(), p_ray_source_segment_target.y() / ray_direction.y()); - // If ray is parallel (rank loss) and source point lies on ray, then target point has to as well. - CHECK_LT(abs(ray_parameter_solution.x() - ray_parameter_solution.y()), kSolutionDeviation); - if (ray_parameter_solution.mean() < 0) { - return false; - } - if (ray_parameter_solution.mean() < parameter_solution_tmp) { - *intersection_point = segment_target; - } else { - *intersection_point = segment_source; - } - return true; - } - return false; - } - Vector2d solution = householder_qr.solve(b); - Vector2d ray_solution = ray_source + solution(0) * segment_direction; - Vector2d segment_solution = segment_source + solution(1) * segment_direction; - constexpr double kSegmentBorderToleranceMeters = 0.001; - if (solution(0) <= 1) { - return false; - } else if (solution(1) < 0) { - if ((segment_solution - segment_source).norm() > kSegmentBorderToleranceMeters) { - return false; - } else { - *intersection_point = segment_source; - return true; - } - } else if (solution(1) > 1) { - if ((segment_solution - segment_target).norm() > kSegmentBorderToleranceMeters) { - return false; - } else { - *intersection_point = segment_target; - } - } else { - *intersection_point = segment_solution; - return true; - } - } + // bool intersectRayWithLineSegment(const Vector2d& ray_source, const Vector2d& ray_direction, + // const Vector2d& segment_source, const Vector2d& segment_target, Vector2d* intersection_point){ + // CHECK_NOTNULL(intersection_point); + // Vector2d segment_direction = segment_target - segment_source; + // Matrix2d A; + // A.col(0) = ray_direction; + // A.col(1) = - segment_direction; + // Vector2d b = segment_source - ray_source; + // auto householder_qr = A.fullPivHouseholderQr(); + // if (householder_qr.rank() < 2) { + // // Check whether segment and ray overlap. + // const Vector2d p_ray_source_segment_source = segment_source - ray_source; + // const Vector2d p_ray_source_segment_target = segment_target - ray_source; + // if (p_ray_source_segment_source.norm() > p_ray_source_segment_target) { + // } + // Vector2d ray_parameter_solution = + // Vector2d(p_ray_source_segment_source.x() / ray_direction.x(), p_ray_source_segment_source.y() / ray_direction.y()); + // constexpr double kSolutionDeviation = 0.0001; + // if (abs(ray_parameter_solution.x() - ray_parameter_solution.y()) < kSolutionDeviation) { + // double parameter_solution_tmp = ray_parameter_solution.mean(); + // if (parameter_solution_tmp < 0) { + // return false; + // } + // CHECK_GT(parameter_solution_tmp, 0); + // Vector2d p_ray_source_segment_target = segment_target - ray_source; + // ray_parameter_solution = + // Vector2d(p_ray_source_segment_target.x() / ray_direction.x(), p_ray_source_segment_target.y() / ray_direction.y()); + // // If ray is parallel (rank loss) and source point lies on ray, then target point has to as well. + // CHECK_LT(abs(ray_parameter_solution.x() - ray_parameter_solution.y()), kSolutionDeviation); + // if (ray_parameter_solution.mean() < 0) { + // return false; + // } + // if (ray_parameter_solution.mean() < parameter_solution_tmp) { + // *intersection_point = segment_target; + // } else { + // *intersection_point = segment_source; + // } + // return true; + // } + // return false; + // } + // Vector2d solution = householder_qr.solve(b); + // Vector2d ray_solution = ray_source + solution(0) * segment_direction; + // Vector2d segment_solution = segment_source + solution(1) * segment_direction; + // constexpr double kSegmentBorderToleranceMeters = 0.001; + // if (solution(0) <= 1) { + // return false; + // } else if (solution(1) < 0) { + // if ((segment_solution - segment_source).norm() > kSegmentBorderToleranceMeters) { + // return false; + // } else { + // *intersection_point = segment_source; + // return true; + // } + // } else if (solution(1) > 1) { + // if ((segment_solution - segment_target).norm() > kSegmentBorderToleranceMeters) { + // return false; + // } else { + // *intersection_point = segment_target; + // } + // } else { + // *intersection_point = segment_solution; + // return true; + // } + // } bool intersectLineSegmentWithLineSegment(const Vector2d& segment_1_source, const Vector2d& segment_1_target, - const Vector2d& segment_2_source, const Vector2d& segment_2_target, Vector2d* intersection_point){ + const Vector2d& segment_2_source, const Vector2d& segment_2_target, + Vector2d* intersection_point) { CHECK_NOTNULL(intersection_point); Vector2d segment_1_direction = segment_1_target - segment_1_source; Vector2d segment_2_direction = segment_2_target - segment_2_source; Matrix2d A; A.col(0) = segment_1_direction; - A.col(1) = - segment_2_direction; + A.col(1) = -segment_2_direction; Vector2d b = segment_2_source - segment_1_source; auto householder_qr = A.fullPivHouseholderQr(); if (householder_qr.rank() < 2){ diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 0f29587d..eb6dc7d6 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -210,8 +210,8 @@ namespace convex_plane_extraction { // Counter-clockwise orientation: ray source vertex is previous vertex in counter-clockwise polygon orientation. bool intersectPolygonWithRay(int ray_target_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, - Intersection* intersection){ - CHECK_NOTNULL(intersection); + Intersection* output_intersection) { + CHECK_NOTNULL(output_intersection); CHECK(orientation == CGAL::COUNTERCLOCKWISE || orientation == CGAL::CLOCKWISE); CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); Intersection intersection_tmp; @@ -221,55 +221,56 @@ namespace convex_plane_extraction { auto vertex_it = polygon.vertices_begin(); std::advance(vertex_it, ray_target_location); auto ray_source_it = vertex_it; - CgalPolygon2dVertexIterator ray_target_it = vertex_it; + auto ray_target_it = vertex_it; if (orientation == CGAL::COUNTERCLOCKWISE) { ray_source_it = previous(vertex_it, polygon); } else { vertex_it = next(vertex_it, polygon); ray_source_it = vertex_it; } - Vector2d ray_source = Vector2d(ray_source_it->x(), ray_source_it->y()); - LOG(INFO) << "Source ray:" << ray_source; - Vector2d ray_target = Vector2d(ray_target_it->x(), ray_target_it->y()); - Vector2d ray_direction = ray_target - ray_source; vertex_it = next(vertex_it, polygon); - // Do not intersect with adjacent edges since the intersect already in common vertex. + const CgalPoint2d ray_source = *ray_source_it; + VLOG(1) << "Source ray:" << ray_source; + const CgalPoint2d ray_target = *ray_target_it; + const CgalRay2d ray(*ray_target_it, *ray_target_it - *ray_source_it); + VLOG(1) << "Ray target: " << ray.source(); + VLOG(1) << "Ray direction: " << ray.direction(); + CHECK(!ray.is_degenerate()); + // Do not intersect with adjacent edges since they intersect already in common vertex. auto condition_it = ray_source_it; - if (orientation == CGAL::CLOCKWISE){ + if (orientation == CGAL::CLOCKWISE) { condition_it = ray_target_it; } - while(next(vertex_it, polygon) != condition_it){ - Vector2d segment_source = Vector2d(vertex_it->x(), vertex_it->y()); - auto segment_target_it = next(vertex_it, polygon); - Vector2d segment_target = Vector2d(segment_target_it->x(), segment_target_it->y()); - Vector2d intersection_point; - if (intersectRayWithLineSegment(ray_source, ray_direction, segment_source, segment_target, - &intersection_point)) { - LOG(INFO) << "Intersection point:" << intersection_point; - LOG(INFO) << segment_source; - // if ((ray_target - intersection_point).norm() < 0.001){ - // LOG(INFO) << ray_target; - // vertex_it = next(vertex_it, polygon); - // continue; - // } - double current_distance = distanceBetweenPoints(ray_target, intersection_point); + int number_of_polygon_edges_visited = 0; + while (next(vertex_it, polygon) != condition_it) { + ++number_of_polygon_edges_visited; + const CgalPoint2d segment_source = *vertex_it; + const auto segment_target_it = next(vertex_it, polygon); + const CgalPoint2d segment_target = *segment_target_it; + VLOG(1) << "Segment under test: Source: " << segment_source << " Target: " << segment_target; + const CgalSegment2d segment(*vertex_it, *segment_target_it); + RaySegmentIntersection intersection; + if (doRayAndSegmentIntersect(ray, segment, &intersection)) { + VLOG(1) << "Intersection type: " << static_cast(intersection.intersection_location); + VLOG(1) << "Intersection point:" << intersection.intersection_point; + VLOG(1) << segment_source; + const double current_distance = sqrt((ray_target - intersection.intersection_point).squared_length()); // Take first intersection on ray. if (current_distance < min_distance) { one_intersection_at_least = true; min_distance = current_distance; intersection_tmp.setAllMembers(std::distance(polygon.vertices_begin(), vertex_it), - std::distance(polygon.vertices_begin(), segment_target_it), - CgalPoint2d(intersection_point.x(), intersection_point.y())); + std::distance(polygon.vertices_begin(), segment_target_it), intersection.intersection_point, + intersection.intersection_location); } } vertex_it = next(vertex_it, polygon); } - - if (!one_intersection_at_least){ + CHECK_EQ(number_of_polygon_edges_visited, polygon.size() - 3); + if (!one_intersection_at_least) { return false; } - intersection->setAllMembers(intersection_tmp.edge_source_location_, intersection_tmp.edge_target_location_, - intersection_tmp.intersection_point_); + *output_intersection = intersection_tmp; return true; } @@ -442,31 +443,95 @@ namespace convex_plane_extraction { } bool doRayAndSegmentIntersect(const CgalRay2d& ray, const CgalSegment2d& segment, RaySegmentIntersection* intersection) { - CGAL::cpp11::result_of::type result = CGAL::intersection(ray, segment); + constexpr double kSquaredToleranceMeters = 1e-8; + CGAL::Cartesian_converter to_exact; + CGAL::Cartesian_converter to_inexact; + CGAL::cpp11::result_of::type result = + CGAL::intersection(to_exact(ray), to_exact(segment)); + if (result) { - if (const CgalSegment2d* s = boost::get(&*result)) { + if (const EKernel::Segment_2* ek_segment = boost::get(&*result)) { + VLOG(1) << "Segment intersection."; + VLOG(1) << "Segment source: " << segment.source(); + VLOG(1) << "Segment target: " << segment.target(); + VLOG(1) << "Ray point: " << ray.source(); + VLOG(1) << "Ray direction: " << ray.direction(); if ((ray.source() - segment.source()).squared_length() < (ray.source() - segment.target()).squared_length()) { - intersection->intersection_location = SegmentIntersectionLocation::kSource; + intersection->intersection_location = SegmentIntersectionType::kSource; intersection->intersection_point = segment.source(); } else { - intersection->intersection_location = SegmentIntersectionLocation::kTarget; + intersection->intersection_location = SegmentIntersectionType::kTarget; intersection->intersection_point = segment.target(); } } else { - const CgalPoint2d* intersection_point = boost::get(&*result); - if (*intersection_point == segment.source()) { - intersection->intersection_location = SegmentIntersectionLocation::kSource; + VLOG(1) << "Point intersection."; + VLOG(1) << "Segment source: " << segment.source(); + VLOG(1) << "Segment target: " << segment.target(); + VLOG(1) << "Ray point: " << ray.source(); + VLOG(1) << "Ray direction: " << ray.direction(); + const EKernel::Point_2* ek_point = boost::get(&*result); + const CgalPoint2d intersection_point = to_inexact(*ek_point); + if ((intersection_point - segment.source()).squared_length() <= kSquaredToleranceMeters) { + intersection->intersection_location = SegmentIntersectionType::kSource; intersection->intersection_point = segment.source(); - } else if (*intersection_point == segment.target()) { - intersection->intersection_location = SegmentIntersectionLocation::kTarget; + } else if ((intersection_point - segment.target()).squared_length() <= kSquaredToleranceMeters) { + intersection->intersection_location = SegmentIntersectionType::kTarget; intersection->intersection_point = segment.target(); } else { - intersection->intersection_location = SegmentIntersectionLocation::kInterior; - intersection->intersection_point = *intersection_point; + intersection->intersection_location = SegmentIntersectionType::kInterior; + intersection->intersection_point = intersection_point; } } return true; } + constexpr double kToleranceMeters = 1e-6; + const Vector2d ray_source = Vector2d(ray.source().x(), ray.source().y()); + const Vector2d ray_direction = Vector2d(ray.direction().dx(), ray.direction().dy()).normalized(); + const Vector2d segment_source = Vector2d(segment.source().x(), segment.source().y()); + const Vector2d segment_target = Vector2d(segment.target().x(), segment.target().y()); + const Vector2d p_ray_source__segment_source = segment_source - ray_source; + const Vector2d p_ray_source__segment_target = segment_target - ray_source; + const double segment_source_projection = p_ray_source__segment_source.dot(ray_direction); + const double segment_target_projection = p_ray_source__segment_target.dot(ray_direction); + const Vector2d segment_source_projection_point = ray_source + segment_source_projection * ray_direction; + const Vector2d segment_target_projection_point = ray_source + segment_target_projection * ray_direction; + if (segment_source_projection >= 0.0 && segment_target_projection >= 0.0) { + if ((segment_source_projection_point - segment_source).norm() < kToleranceMeters && + (segment_target_projection_point - segment_target).norm() < kToleranceMeters) { + // Source and target lie on ray. Determine, which point is closer. + if ((segment_source_projection_point - ray_source).norm() <= (segment_target_projection_point - ray_source).norm()) { + intersection->intersection_location = SegmentIntersectionType::kSource; + intersection->intersection_point = segment.source(); + return true; + } else { + intersection->intersection_location = SegmentIntersectionType::kTarget; + intersection->intersection_point = segment.target(); + return true; + } + } else if ((segment_source_projection_point - segment_source).norm() < kToleranceMeters) { + // Only source lies on ray. + intersection->intersection_location = SegmentIntersectionType::kSource; + intersection->intersection_point = segment.source(); + return true; + } else if ((segment_target_projection_point - segment_target).norm() < kToleranceMeters) { + // Only target lies on ray. + intersection->intersection_location = SegmentIntersectionType::kTarget; + intersection->intersection_point = segment.target(); + return true; + } + } else if (segment_source_projection >= 0.0) { + if ((segment_source_projection_point - segment_source).norm() < kToleranceMeters) { + intersection->intersection_location = SegmentIntersectionType::kSource; + intersection->intersection_point = segment.source(); + return true; + } + } else if (segment_target_projection >= 0.0) { + if ((segment_target_projection_point - segment_target).norm() < kToleranceMeters) { + intersection->intersection_location = SegmentIntersectionType::kTarget; + intersection->intersection_point = segment.target(); + return true; + } + } return false; } From 3df73fefd6cb22b16bae02bc01f20d789b7703fa Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Mon, 30 Mar 2020 11:07:44 +0200 Subject: [PATCH 031/504] Exposed new parameters for contour approximation. --- .../include/polygon.hpp | 3 ++- .../include/polygonizer.hpp | 6 ++++-- convex_plane_decomposition/src/polygon.cpp | 15 ++++++++------- .../src/polygonizer.cpp | 19 ++++++------------- .../config/parameters.yaml | 12 +++++++----- .../src/pipeline_ros.cpp | 18 ++++++++++++++---- 6 files changed, 41 insertions(+), 32 deletions(-) diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index f5e617fe..b30f9cd8 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -112,7 +112,8 @@ typedef CGAL::Point_2 CgalPoint2d; CgalPolygon2dVertexIterator previous(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon); -void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, double relative_area_threshold, double absolute_area_threshold); + void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, double relative_local_area_threshold, + double absolute_local_area_threshold, double relative_total_area_threshold, double absolute_total_area_threshold); void upSampleLongEdges(CgalPolygon2d* polygon); diff --git a/convex_plane_decomposition/include/polygonizer.hpp b/convex_plane_decomposition/include/polygonizer.hpp index 20c04728..1e8b6d58 100644 --- a/convex_plane_decomposition/include/polygonizer.hpp +++ b/convex_plane_decomposition/include/polygonizer.hpp @@ -24,8 +24,10 @@ struct PolygonizerParameters{ bool activate_long_edge_upsampling = false; bool activate_contour_approximation = false; double hole_area_threshold_squared_meters = 2e-3; - double contour_approximation_relative_area_threshold = 0.01; - double contour_approximation_absolute_area_threshold_squared_meters = 0.04; + double contour_approximation_relative_local_area_threshold = 0.01; + double contour_approximation_absolute_local_area_threshold_squared_meters = 0.04; + double contour_approximation_relative_total_area_threshold = 0.5; + double contour_approximation_absolute_total_area_threshold_squared_meters = 1.0; int max_number_of_iterations = 5; }; diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index eb6dc7d6..e41bde39 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -65,9 +65,11 @@ namespace convex_plane_extraction { *normal_vector = normal; } - void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, double relative_area_threshold, double absolute_area_threshold){ + void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, double relative_local_area_threshold, + double absolute_local_area_threshold, double relative_total_area_threshold, + double absolute_total_area_threshold) { CHECK_NOTNULL(polygon); - if (polygon->size() < 4){ + if (polygon->size() < 4) { return; } CHECK(polygon->orientation() == CGAL::COUNTERCLOCKWISE); @@ -94,7 +96,7 @@ namespace convex_plane_extraction { const double triangle_area = computeTriangleArea(a, b, c); CHECK(isfinite(triangle_area)) << "Area: " << triangle_area << ", a: " << a << ", b: " << b << ", c: " << c; CHECK_GE(triangle_area, 0.0); - if ((triangle_area < relative_area_threshold * area) && (triangle_area < absolute_area_threshold)) { + if ((triangle_area < relative_local_area_threshold * area) && (triangle_area < absolute_local_area_threshold)) { VLOG(2) << "Area sufficiently small!"; CgalPolygon2d new_polygon(*polygon); int vertex_position_offset = std::distance(polygon->vertices_begin(), second_vertex_it); @@ -104,7 +106,8 @@ namespace convex_plane_extraction { new_polygon.erase(tmp_iterator); VLOG(2) << "After ease call!"; if (new_polygon.is_simple() && (new_polygon.orientation() == CGAL::COUNTERCLOCKWISE) && - abs(new_polygon.area() - area) < 0.1 * area && abs(new_polygon.area() - area) < 0.5) { + abs(new_polygon.area() - area) < relative_total_area_threshold * area && + abs(new_polygon.area() - area) < absolute_total_area_threshold) { CHECK_LE(triangle_area, area); first_vertex_it = polygon->erase(second_vertex_it); if (first_vertex_it == polygon->vertices_end()) { @@ -127,9 +130,7 @@ namespace convex_plane_extraction { third_vertex_it = next(second_vertex_it, *polygon); VLOG(2) << "Got to bottom! Number of iterations: " << std::distance(polygon->begin(), first_vertex_it) << " " << std::distance(polygon->begin(), second_vertex_it) << " " << std::distance(polygon->begin(), third_vertex_it); - if ((std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), second_vertex_it) || - std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), third_vertex_it) || - std::distance(polygon->begin(), second_vertex_it) >= std::distance(polygon->begin(), third_vertex_it))) { + if (std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), second_vertex_it)) { ++number_of_iterations; } } diff --git a/convex_plane_decomposition/src/polygonizer.cpp b/convex_plane_decomposition/src/polygonizer.cpp index f829ea55..4ee8e71d 100644 --- a/convex_plane_decomposition/src/polygonizer.cpp +++ b/convex_plane_decomposition/src/polygonizer.cpp @@ -16,23 +16,15 @@ PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& bina CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); std::vector> approx_contours; int hierachy_it = 0; - for (auto& contour : contours) { + for (const auto& contour : contours) { ++hierachy_it; - std::vector approx_contour; - if (contour.size() <= 10) { - approx_contour = contour; - } else { - approx_contour = contour; // Do this at later stage so that no intersections with holes are generated. - //cv::approxPolyDP(contour, approx_contour, 9, true); - } - if (approx_contour.size() <= 2) { + if (contour.size() <= 2) { LOG_IF(WARNING, hierarchy[hierachy_it - 1][3] < 0 && contour.size() > 3) << "Removing parental polygon since too few vertices!"; continue; } CgalPolygon2d polygon = convex_plane_extraction::createCgalPolygonFromOpenCvPoints( - approx_contour.begin(), - approx_contour.end(), + contour.begin(), contour.end(), parameters_.resolution / static_cast(parameters_.upsampling_factor)); CHECK(polygon.is_simple()) << "Contour extraction from binary image caused intersection!"; constexpr int kParentFlagIndex = 3; @@ -41,8 +33,9 @@ PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& bina upSampleLongEdges(&polygon); } if (parameters_.activate_contour_approximation) { - approximateContour(&polygon, parameters_.max_number_of_iterations, parameters_.contour_approximation_relative_area_threshold, - parameters_.contour_approximation_absolute_area_threshold_squared_meters); + approximateContour(&polygon, parameters_.max_number_of_iterations, parameters_.contour_approximation_relative_local_area_threshold, + parameters_.contour_approximation_absolute_local_area_threshold_squared_meters, + parameters_.contour_approximation_relative_total_area_threshold, parameters_.contour_approximation_absolute_total_area_threshold_squared_meters); VLOG(1) << "Contour approximated!"; } plane_polygons.outer_contour = polygon; diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 33e7f560..28a293db 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -9,13 +9,15 @@ polygonizer: upsampling_factor : 3 activate_long_edge_upsampling : false activate_contour_approximation : true - contour_approximation_relative_area_threshold : 0.1 - contour_approximation_absolute_area_threshold_squared_meters : 0.04 - max_number_of_iterations : 3 + contour_approximation_relative_local_area_threshold : 0.1 + contour_approximation_absolute_local_area_threshold_squared_meters : 0.05 + contour_approximation_relative_total_area_threshold : 0.5 + contour_approximation_absolute_total_area_threshold : 1.0 + max_number_of_iterations : 5 convex_decomposer: - decomposer_type : 'inner_convex_decomposition' #'optimal_decompostion' - dent_angle_threshold_rad : 0.001 + decomposer_type : 'inner_convex_decomposition' # 'optimal_decompostion' + dent_angle_threshold_rad : 0.05 sliding_window_plane_extractor: kernel_size : 3 diff --git a/convex_plane_decomposition_ros/src/pipeline_ros.cpp b/convex_plane_decomposition_ros/src/pipeline_ros.cpp index 3bdd77b5..492155c2 100644 --- a/convex_plane_decomposition_ros/src/pipeline_ros.cpp +++ b/convex_plane_decomposition_ros/src/pipeline_ros.cpp @@ -80,13 +80,23 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map: ROS_ERROR("Could not read parameter `activate_contour_approximation`. Setting parameter to default value."); } if (polygonizer_parameters.activate_contour_approximation) { - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_relative_area_threshold", - polygonizer_parameters.contour_approximation_relative_area_threshold)) { + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_relative_local_area_threshold", + polygonizer_parameters.contour_approximation_relative_local_area_threshold)) { ROS_ERROR( "Could not read parameter `contour_approximation_relative_area_threshold`. Setting parameter to default value."); } - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_absolute_area_threshold_squared_meters", - polygonizer_parameters.contour_approximation_absolute_area_threshold_squared_meters)) { + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_absolute_local_area_threshold_squared_meters", + polygonizer_parameters.contour_approximation_absolute_local_area_threshold_squared_meters)) { + ROS_ERROR( + "Could not read parameter `contour_approximation_absolute_area_threshold_squared_meters`. Setting parameter to default value."); + } + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_relative_total_local_area_threshold", + polygonizer_parameters.contour_approximation_relative_total_area_threshold)) { + ROS_ERROR( + "Could not read parameter `contour_approximation_relative_area_threshold`. Setting parameter to default value."); + } + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_absolute_total_area_threshold_squared_meters", + polygonizer_parameters.contour_approximation_absolute_total_area_threshold_squared_meters)) { ROS_ERROR( "Could not read parameter `contour_approximation_absolute_area_threshold_squared_meters`. Setting parameter to default value."); } From 7c15f81568f265d110445702cde302e2e78aea80 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Mon, 30 Mar 2020 12:45:01 +0200 Subject: [PATCH 032/504] Added demo. --- ...nvex_plane_extraction_demo_parameters.yaml | 36 ++++++++++++++++++ .../config/image_loader_demo_parameters.yaml | 6 +++ .../data/demo_map.png | Bin 0 -> 74823 bytes .../convex_plane_extraction_demo.launch | 17 +++++++++ .../src/convex_plane_extraction_ros.cpp | 1 + .../src/pipeline_ros.cpp | 5 +-- 6 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 convex_plane_decomposition_ros/config/convex_plane_extraction_demo_parameters.yaml create mode 100644 convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml create mode 100644 convex_plane_decomposition_ros/data/demo_map.png create mode 100644 convex_plane_decomposition_ros/launch/convex_plane_extraction_demo.launch diff --git a/convex_plane_decomposition_ros/config/convex_plane_extraction_demo_parameters.yaml b/convex_plane_decomposition_ros/config/convex_plane_extraction_demo_parameters.yaml new file mode 100644 index 00000000..ee434007 --- /dev/null +++ b/convex_plane_decomposition_ros/config/convex_plane_extraction_demo_parameters.yaml @@ -0,0 +1,36 @@ +input_topic: '/image_to_gridmap_demo/grid_map' +height_layer: 'elevation' + + +plane_factory: + plane_inclination_threshold_degrees: 70 + +polygonizer: + upsampling_factor: 3 + activate_long_edge_upsampling: false + activate_contour_approximation: true + contour_approximation_relative_local_area_threshold: 0.1 + contour_approximation_absolute_local_area_threshold_squared_meters: 0.05 + contour_approximation_relative_total_area_threshold: 0.2 + contour_approximation_absolute_total_area_threshold_squared_meters: 0.3 + max_number_of_iterations: 5 + +convex_decomposer: + decomposer_type: 'inner_convex_decomposition' # 'optimal_decompostion' + dent_angle_threshold_rad: 0.05 + +sliding_window_plane_extractor: + kernel_size: 3 + plane_patch_error_threshold: 0.004 + surface_normal_angle_threshold_degrees: 10.0 + include_curvature_detection: true + include_ransac_refinement: false + global_plane_fit_error_threshold: 0.02 + +ransac_plane_refinement: + probability: 0.01 + min_points: 200 + epsilon: 0.004 + cluster_epsilon: 0.0282842712475 + # Set maximum normal deviation. 0.98 < dot(surface_normal, point_normal); + normal_threshold: 0.98 \ No newline at end of file diff --git a/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml b/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml new file mode 100644 index 00000000..42a93854 --- /dev/null +++ b/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml @@ -0,0 +1,6 @@ +image_to_gridmap_demo: + image_topic: "/image_publisher/image" + resolution: 0.02 + map_frame_id: "odom" + min_height: 0 + max_height: 1.0 \ No newline at end of file diff --git a/convex_plane_decomposition_ros/data/demo_map.png b/convex_plane_decomposition_ros/data/demo_map.png new file mode 100644 index 0000000000000000000000000000000000000000..f3911e7b91f2642af22212cd54d5eff712738484 GIT binary patch literal 74823 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

*j>9YiEsg>7?=EQgVe_~zM{hDrM^pv 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 + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp b/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp index 4fb98843..8b0002bc 100644 --- a/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp +++ b/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp @@ -41,6 +41,7 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { bool success; GridMap inputMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(6, 6), success); CHECK(success); + inputMap.setFrameId("odom"); ROS_INFO("...done."); VLOG(1) << "Applying median filtering to map."; applyMedianFilter(inputMap.get("elevation"), 5); diff --git a/convex_plane_decomposition_ros/src/pipeline_ros.cpp b/convex_plane_decomposition_ros/src/pipeline_ros.cpp index 492155c2..22c4b338 100644 --- a/convex_plane_decomposition_ros/src/pipeline_ros.cpp +++ b/convex_plane_decomposition_ros/src/pipeline_ros.cpp @@ -90,10 +90,9 @@ PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map: ROS_ERROR( "Could not read parameter `contour_approximation_absolute_area_threshold_squared_meters`. Setting parameter to default value."); } - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_relative_total_local_area_threshold", + if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_relative_total_area_threshold", polygonizer_parameters.contour_approximation_relative_total_area_threshold)) { - ROS_ERROR( - "Could not read parameter `contour_approximation_relative_area_threshold`. Setting parameter to default value."); + ROS_ERROR("Could not read parameter `contour_approximation_relative_area_threshold`. Setting parameter to default value."); } if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_absolute_total_area_threshold_squared_meters", polygonizer_parameters.contour_approximation_absolute_total_area_threshold_squared_meters)) { From 24445ae22762ff46d33e2d3d309d83b08db72dbc Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Mon, 30 Mar 2020 20:34:27 +0200 Subject: [PATCH 033/504] Major clean-up. --- .../include/convex_decomposer.hpp | 6 +- .../include/convex_polygon_decomposition.hpp | 43 ---- .../include/export_utils.hpp | 5 +- .../include/geometry_utils.hpp | 29 +-- .../include/pipeline.hpp | 17 +- convex_plane_decomposition/include/plane.hpp | 56 ++--- .../include/plane_extractor.hpp | 85 ------- .../include/plane_factory.hpp | 16 +- .../include/polygon.hpp | 217 +++++++++--------- .../include/polygonizer.hpp | 20 +- .../include/ransac_plane_extractor.hpp | 6 - .../sliding_window_plane_extractor.hpp | 23 +- .../src/convex_decomposer.cpp | 59 ++--- .../src/convex_polygon_decomposition.cpp | 19 -- .../src/export_utils.cpp | 24 +- .../src/geometry_utils.cpp | 67 ------ convex_plane_decomposition/src/pipeline.cpp | 26 --- convex_plane_decomposition/src/plane.cpp | 2 - .../src/plane_extractor.cpp | 58 ----- .../src/plane_factory.cpp | 25 +- convex_plane_decomposition/src/polygon.cpp | 28 ++- .../src/polygonizer.cpp | 211 +---------------- .../src/ransac_plane_extractor.cpp | 22 -- .../src/sliding_window_plane_extractor.cpp | 1 - 24 files changed, 226 insertions(+), 839 deletions(-) delete mode 100644 convex_plane_decomposition/include/convex_polygon_decomposition.hpp delete mode 100644 convex_plane_decomposition/include/plane_extractor.hpp delete mode 100644 convex_plane_decomposition/src/convex_polygon_decomposition.cpp delete mode 100644 convex_plane_decomposition/src/plane_extractor.cpp diff --git a/convex_plane_decomposition/include/convex_decomposer.hpp b/convex_plane_decomposition/include/convex_decomposer.hpp index 680b2b0b..a4da6a62 100644 --- a/convex_plane_decomposition/include/convex_decomposer.hpp +++ b/convex_plane_decomposition/include/convex_decomposer.hpp @@ -17,18 +17,16 @@ struct ConvexDecomposerParameters{ class ConvexDecomposer { public: - explicit ConvexDecomposer(const ConvexDecomposerParameters& parameters); CgalPolygon2dContainer performConvexDecomposition(const CgalPolygon2d& polygon) const; private: - - CgalPolygon2dContainer performOptimalConvexDecomposition(const CgalPolygon2d& polygon) const; + std::multimap detectDentLocations(const CgalPolygon2d& polygon) const; CgalPolygon2dContainer performInnerConvexApproximation(const CgalPolygon2d& polygon) const; - std::multimap detectDentLocations(const CgalPolygon2d& polygon) const; + CgalPolygon2dContainer performOptimalConvexDecomposition(const CgalPolygon2d& polygon) const; ConvexDecomposerParameters parameters_; }; diff --git a/convex_plane_decomposition/include/convex_polygon_decomposition.hpp b/convex_plane_decomposition/include/convex_polygon_decomposition.hpp deleted file mode 100644 index 1131ca82..00000000 --- a/convex_plane_decomposition/include/convex_polygon_decomposition.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_CONVEX_POLYGON_DECOMPOSITION_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_CONVEX_POLYGON_DECOMPOSITION_HPP_ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "types.hpp" - -namespace convex_plane_extraction { - - typedef CGAL::Exact_predicates_inexact_constructions_kernel K; - typedef CGAL::Partition_traits_2 Traits; - typedef Traits::Point_2 CgalPoint2d; - typedef Traits::Polygon_2 CgalPolygon2d; - typedef std::list CgalPolygon2dListContainer; - - template - CgalPolygon2d createCgalPolygonFromOpenCvPoints_impl(Iter begin, Iter end, std::bidirectional_iterator_tag){ - CgalPolygon2d polygon; - for (auto it = begin; it < end; ++it) { - polygon.push_back(CgalPoint2d((*it).x, (*it).y)); - std::cout << *it << std::endl; - } - return polygon; - } - - template - CgalPolygon2d createCgalPolygonFromOpenCvPoints(Iter begin, Iter end){ - return createCgalPolygonFromOpenCvPoints_impl(begin, end, - typename std::iterator_traits::iterator_category()); - } - - void performConvexDecomposition(const CgalPolygon2d& polygon, CgalPolygon2dListContainer* output_polyong_list); - -} -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_CONVEX_POLYGON_DECOMPOSITION_HPP_ diff --git a/convex_plane_decomposition/include/export_utils.hpp b/convex_plane_decomposition/include/export_utils.hpp index a902ee93..ab53fb63 100644 --- a/convex_plane_decomposition/include/export_utils.hpp +++ b/convex_plane_decomposition/include/export_utils.hpp @@ -13,9 +13,8 @@ namespace convex_plane_extraction { - bool exportPointsWithNormalsToCsv(grid_map::GridMap &map, const std::string &normals_layer_prefix, - const std::string &layer_height); +bool exportPointsWithNormalsToCsv(grid_map::GridMap& map, const std::string& normals_layer_prefix, const std::string& layer_height, + const std::string& path); } - #endif //CONVEX_PLANE_EXTRACTION_INCLUDE_EXPORT_UTILS_HPP_ diff --git a/convex_plane_decomposition/include/geometry_utils.hpp b/convex_plane_decomposition/include/geometry_utils.hpp index ef05241e..94dc8f08 100644 --- a/convex_plane_decomposition/include/geometry_utils.hpp +++ b/convex_plane_decomposition/include/geometry_utils.hpp @@ -5,26 +5,27 @@ namespace convex_plane_extraction { -double scalarCrossProduct(const Vector2d &leftVector, const Vector2d &rightVector); - -double distanceToLine(const Vector2d& lineSupportVector, const Vector2d& lineDirectionalVector, const Vector2d& testPoint); - -bool isPointOnRightSideOfLine(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); +double scalarCrossProduct(const Vector2d& leftVector, const Vector2d& rightVector); double computeAngleBetweenVectors(const Vector2d& first_vector, const Vector2d& second_vector); -bool isPointOnLeftSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); - -bool intersectRayWithLineSegment(const Vector2d& ray_source, const Vector2d& ray_direction, - const Vector2d& segment_source, const Vector2d& segment_target, Vector2d* intersection_point); - double distanceBetweenPoints(const Vector2d& first, const Vector2d& second); -double getDistanceOfPointToLineSegment(const Vector2d& point, const Vector2d& source, Vector2d& target); +double distanceToLine(const Vector2d& lineSupportVector, const Vector2d& lineDirectionalVector, const Vector2d& testPoint); std::pair getDistanceAndClosestPointOnLineSegment(const Vector2d& point, const Vector2d& source, const Vector2d& target); +double getDistanceOfPointToLineSegment(const Vector2d& point, const Vector2d& source, Vector2d& target); + bool intersectLineSegmentWithLineSegment(const Vector2d& segment_1_source, const Vector2d& segment_1_target, - const Vector2d& segment_2_source, const Vector2d& segment_2_target, Vector2d* intersection_point); -} -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ + const Vector2d& segment_2_source, const Vector2d& segment_2_target, Vector2d* intersection_point); + +bool intersectRayWithLineSegment(const Vector2d& ray_source, const Vector2d& ray_direction, const Vector2d& segment_source, + const Vector2d& segment_target, Vector2d* intersection_point); + +bool isPointOnLeftSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); + +bool isPointOnRightSideOfLine(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); + +} // namespace convex_plane_extraction +#endif // CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ diff --git a/convex_plane_decomposition/include/pipeline.hpp b/convex_plane_decomposition/include/pipeline.hpp index d0a97920..ba3572a5 100644 --- a/convex_plane_decomposition/include/pipeline.hpp +++ b/convex_plane_decomposition/include/pipeline.hpp @@ -24,30 +24,23 @@ struct GridMapParameters{ std::string layer_height; }; - class Pipeline { public: - Pipeline(const PipelineParameters& pipeline_parameters, const GridMapParameters& grid_map_parameters); - const cv::Mat& getSegmentationImage() const{ - return sliding_window_plane_extractor_.getLabeledImage(); - }; - Polygon3dVectorContainer getConvexPolygons() const; Polygon3dVectorContainer getPlaneContours() const; - private: - -// void exportConvexPolygons(const std::string& export_path) const; + const cv::Mat& getSegmentationImage() const { return sliding_window_plane_extractor_.getLabeledImage(); }; - PipelineParameters pipeline_parameters_; + private: + // Parameters GridMapParameters grid_map_parameters_; + PipelineParameters pipeline_parameters_; - sliding_window_plane_extractor::SlidingWindowPlaneExtractor sliding_window_plane_extractor_; PlaneFactory plane_factory_; - + sliding_window_plane_extractor::SlidingWindowPlaneExtractor sliding_window_plane_extractor_; }; } // namespace_convex_plane_extraction #endif //CONVEX_PLANE_EXTRACTION__PIPELINE_HPP_ diff --git a/convex_plane_decomposition/include/plane.hpp b/convex_plane_decomposition/include/plane.hpp index 2747985a..00ce8f14 100644 --- a/convex_plane_decomposition/include/plane.hpp +++ b/convex_plane_decomposition/include/plane.hpp @@ -19,61 +19,33 @@ namespace convex_plane_extraction { }; class Plane { - public: - Plane(const CgalPolygon2d& plane_contour, const PlaneParameters parameters) - : plane_contour_(plane_contour), - normal_vector_(parameters.normal_vector), - support_vector_(parameters.support_vector){} - - PlaneParameters getPlaneParameters() const { - return PlaneParameters(normal_vector_, support_vector_); - } + : plane_contour_(plane_contour), normal_vector_(parameters.normal_vector), support_vector_(parameters.support_vector) {} - bool setPlaneContour(const CgalPolygon2d& plane_contour){ - plane_contour_ = plane_contour; - } + void addConvexPolygon(const CgalPolygon2d& convex_polygon) { convex_polygons_.push_back(convex_polygon); } - const Eigen::Vector3d& getPlaneNormalVector() const{ - return normal_vector_; - } + const CgalPolygon2dContainer& getConvexPolygons() const { return convex_polygons_; } - Eigen::Vector3d& getPlaneNormalVectorMutable(){ - return normal_vector_; - } + CgalPolygon2dContainer& getConvexPolygonsMutable() { return convex_polygons_; } - bool setNormalAndSupportVector(const Eigen::Vector3d& normal_vector,const Eigen::Vector3d& support_vector); + const Eigen::Vector3d& getPlaneNormalVector() const { return normal_vector_; } - bool hasOuterContour() const; + Eigen::Vector3d& getPlaneNormalVectorMutable() { return normal_vector_; } - CgalPolygon2d& getOuterPolygonMutable(){ - return plane_contour_; - } + const CgalPolygon2d& getOuterPolygon() const { return plane_contour_; } - const CgalPolygon2d& getOuterPolygon() const{ - return plane_contour_; - } + CgalPolygon2d& getOuterPolygonMutable() { return plane_contour_; } + PlaneParameters getPlaneParameters() const { return PlaneParameters(normal_vector_, support_vector_); } - CgalPolygon2dContainer& getConvexPolygonsMutable(){ - return convex_polygons_; - } + void setConvexPolygons(CgalPolygon2dContainer& convex_polygons) { convex_polygons_ = convex_polygons; } - const CgalPolygon2dContainer& getConvexPolygons() const{ - return convex_polygons_; - } + bool setNormalAndSupportVector(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector); - void addConvexPolygon(const CgalPolygon2d& convex_polygon){ - convex_polygons_.push_back(convex_polygon); - } - - void setConvexPolygons(CgalPolygon2dContainer& convex_polygons){ - convex_polygons_ = convex_polygons; - } + bool setPlaneContour(const CgalPolygon2d& plane_contour) { plane_contour_ = plane_contour; } private: - CgalPolygon2d plane_contour_; CgalPolygon2dContainer convex_polygons_; @@ -81,5 +53,5 @@ namespace convex_plane_extraction { Vector3d support_vector_; }; -} -#endif //CONVEX_PLANE_EXTRACTION_SRC_PLANE_HPP_ + } // namespace convex_plane_extraction +#endif // CONVEX_PLANE_EXTRACTION_SRC_PLANE_HPP_ diff --git a/convex_plane_decomposition/include/plane_extractor.hpp b/convex_plane_decomposition/include/plane_extractor.hpp deleted file mode 100644 index ec2059f7..00000000 --- a/convex_plane_decomposition/include/plane_extractor.hpp +++ /dev/null @@ -1,85 +0,0 @@ -// -// Created by andrej on 12/6/19. -// - -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_EXTRACTOR_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_EXTRACTOR_HPP_ - -#include - -#include "Eigen/Core" -#include "Eigen/Dense" -#include "opencv2/core/eigen.hpp" -#include "opencv2/core/mat.hpp" - -#include "ransac_plane_extractor.hpp" -#include "sliding_window_plane_extractor.hpp" -#include "types.hpp" - -namespace convex_plane_extraction { - using namespace grid_map; - - enum PlaneExtractorType : int { - kRansacExtractor = 0, - kSlidingWindowExtractor = 1 - }; - - class PlaneExtractor { - public: - - /*! - * Constructor. - */ - PlaneExtractor(grid_map::GridMap &map, double resolution, const std::string &normals_layer_prefix, - const std::string &height_layer); - - /*! - * Destructor. - */ - virtual ~PlaneExtractor(); - - grid_map::GridMap& getMap(); - - // Ransac plane extractor related functions. - void setRansacParameters(const ransac_plane_extractor::RansacPlaneExtractorParameters& parameters); - - void runRansacPlaneExtractor(); - - void augmentMapWithRansacPlanes(); - - // Sliding window plane extractor related functions. - void setSlidingWindowParameters(const sliding_window_plane_extractor::SlidingWindowParameters& parameters); - - void runSlidingWindowPlaneExtractor(); - - void augmentMapWithSlidingWindowPlanes(); - - void generatePlanes(){ - sliding_window_plane_extractor_.generatePlanes(); - } - - void visualizeConvexDecomposition(jsk_recognition_msgs::PolygonArray* ros_polygon_array){ - CHECK_NOTNULL(ros_polygon_array); - sliding_window_plane_extractor_.visualizeConvexDecomposition(ros_polygon_array); - sliding_window_plane_extractor_.exportConvexPolygons("/home/andrej/Desktop/"); - } - - void visualizePlaneContours(jsk_recognition_msgs::PolygonArray* ros_polygon_outer_contours, jsk_recognition_msgs::PolygonArray* ros_polygon_hole_contours){ - sliding_window_plane_extractor_.visualizePlaneContours(ros_polygon_outer_contours, ros_polygon_hole_contours); - } - - private: - - // Grid map related - grid_map::GridMap& map_; - double resolution_; - std::string normal_layer_prefix_; - std::string height_layer_; - Vector2i map_size_; - - ransac_plane_extractor::RansacPlaneExtractor ransac_plane_extractor_; - sliding_window_plane_extractor::SlidingWindowPlaneExtractor sliding_window_plane_extractor_; - }; - -} -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_EXTRACTOR_HPP_ diff --git a/convex_plane_decomposition/include/plane_factory.hpp b/convex_plane_decomposition/include/plane_factory.hpp index 8c6e5f07..4582581f 100644 --- a/convex_plane_decomposition/include/plane_factory.hpp +++ b/convex_plane_decomposition/include/plane_factory.hpp @@ -1,7 +1,7 @@ #ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_FACTORY_HPP_ #define CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_FACTORY_HPP_ -#include +#include #include #include "convex_decomposer.hpp" @@ -38,16 +38,14 @@ class PlaneFactory { void computeMapTransformation(); - bool isPlaneInclinationBelowThreshold(const Eigen::Vector3d& plane_normal_vector) const; - - Eigen::Vector3d convertPlanePointToWorldFrame(const CgalPoint2d& point, - const PlaneParameters& plane_parameters) const; + Eigen::Vector3d convertPlanePointToWorldFrame(const CgalPoint2d& point, const PlaneParameters& plane_parameters) const; Polygon3dVectorContainer convertPlanePolygonsToWorldFrame(const CgalPolygon2dContainer& polygons, - const PlaneParameters& plane_parameters) const; + const PlaneParameters& plane_parameters) const; + + Polygon3dVectorContainer convertPlanePolygonToWorldFrame(const CgalPolygon2d& polygon, const PlaneParameters& plane_parameters) const; - Polygon3dVectorContainer convertPlanePolygonToWorldFrame(const CgalPolygon2d& polygon, - const PlaneParameters& plane_parameters) const; + bool isPlaneInclinationBelowThreshold(const Eigen::Vector3d& plane_normal_vector) const; // Grid map related members. grid_map::GridMap& map_; @@ -55,10 +53,8 @@ class PlaneFactory { Eigen::Vector2d map_offset_; // Parameters. - PlaneFactoryParameters parameters_; - std::vector planes_; }; diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index b30f9cd8..eac6246b 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -27,155 +27,150 @@ #include "geometry_utils.hpp" #include "types.hpp" -namespace convex_plane_extraction{ +namespace convex_plane_extraction { + +using K = CGAL::Exact_predicates_inexact_constructions_kernel; +using EKernel = CGAL::Exact_predicates_exact_constructions_kernel; +using Traits = CGAL::Partition_traits_2; +using CgalPoint2d = CGAL::Point_2; +using CgalVector2d = CGAL::Vector_2; +using CgalPolygon2d = CGAL::Polygon_2; +using CgalPolygonWithHoles2d = CGAL::Polygon_with_holes_2; +using CgalSegment2d = Traits::Segment_2; +using CgalPolygon2dContainer = std::vector; +using CgalRay2d = Traits::Ray_2; +using CgalCircle2d = Traits::Circle_2; +using CgalPolygon2dConstIterator = CgalPolygon2dContainer::const_iterator; +using CgalPolygon2dSetContainer = CGAL::Polygon_set_2>; +using CgalPolygon2dVertexConstIterator = CgalPolygon2d::Vertex_const_iterator; +using CgalPolygon2dVertexIterator = CgalPolygon2d::Vertex_iterator; -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Exact_predicates_exact_constructions_kernel EKernel; -typedef CGAL::Partition_traits_2 Traits; -typedef CGAL::Point_2 CgalPoint2d; - typedef CGAL::Vector_2 CgalVector2d; - typedef CGAL::Polygon_2 CgalPolygon2d; - typedef CGAL::Polygon_with_holes_2 CgalPolygonWithHoles2d; - typedef Traits::Segment_2 CgalSegment2d; - typedef std::vector CgalPolygon2dContainer; - typedef Traits::Ray_2 CgalRay2d; - typedef Traits::Circle_2 CgalCircle2d; - typedef CgalPolygon2dContainer::const_iterator CgalPolygon2dConstIterator; - typedef CGAL::Polygon_set_2> CgalPolygon2dSetContainer; - typedef CgalPolygon2d::Vertex_const_iterator CgalPolygon2dVertexConstIterator; - typedef CgalPolygon2d::Vertex_iterator CgalPolygon2dVertexIterator; +using Polygon3d = std::vector; +using Polygon3dVectorContainer = std::vector; +using Intersect_2 = K::Intersect_2; - typedef std::vector Polygon3d; - typedef std::vector Polygon3dVectorContainer; - typedef K::Intersect_2 Intersect_2; +enum class SegmentIntersectionType : int { kSource, kTarget, kInterior }; - struct PolygonWithHoles { - CgalPolygon2d outer_contour; - CgalPolygon2dContainer holes; - }; +struct Intersection { + void setEdgeSourceLocation(const int location) { edge_source_location_ = location; } + void setEdgeTargetLocation(const int location) { edge_target_location_ = location; } + void setIntersectionPoint(const CgalPoint2d& intersection_point) { intersection_point_ = intersection_point; } + void setAllMembers(const int source_location, const int target_location, const CgalPoint2d& intersection_point, + const SegmentIntersectionType& intersection_type) { + edge_source_location_ = source_location; + edge_target_location_ = target_location; + intersection_type_ = intersection_type; + intersection_point_ = intersection_point; + } - enum class SegmentIntersectionType : int { kSource, kTarget, kInterior }; + int edge_source_location_; + int edge_target_location_; + SegmentIntersectionType intersection_type_; + CgalPoint2d intersection_point_; +}; - struct RaySegmentIntersection { - SegmentIntersectionType intersection_location; - CgalPoint2d intersection_point; - }; +struct PolygonWithHoles { + CgalPolygon2d outer_contour; + CgalPolygon2dContainer holes; +}; - template - bool isContourSimple_impl(Iter begin, Iter end, std::bidirectional_iterator_tag) { - CgalPolygon2d polygon; - for (auto it = begin; it < end; ++it) { - polygon.push_back(Point((*it).x, (*it).y)); - std::cout << *it << std::endl; - } - return polygon.is_simple(); - }; +struct RaySegmentIntersection { + SegmentIntersectionType intersection_location; + CgalPoint2d intersection_point; +}; - template - bool isContourSimple(Iter begin, Iter end){ - return isContourSimple_impl(begin, end, - typename std::iterator_traits::iterator_category()); - }; +void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, double relative_local_area_threshold, + double absolute_local_area_threshold, double relative_total_area_threshold, double absolute_total_area_threshold); - template - CgalPolygon2d createCgalPolygonFromOpenCvPoints_impl(Iter begin, Iter end, const double& resolution, std::bidirectional_iterator_tag){ - CgalPolygon2d polygon; - for (auto it = begin; it < end; ++it) { +template +bool isContourSimple_impl(Iter begin, Iter end, std::bidirectional_iterator_tag) { + CgalPolygon2d polygon; + for (auto it = begin; it < end; ++it) { + polygon.push_back(Point((*it).x, (*it).y)); + std::cout << *it << std::endl; + } + return polygon.is_simple(); +}; - polygon.push_back(CgalPoint2d(static_cast((*it).y * resolution), static_cast((*it).x) * resolution)); - } - return polygon; - }; +template +bool isContourSimple(Iter begin, Iter end) { + return isContourSimple_impl(begin, end, typename std::iterator_traits::iterator_category()); +}; - template - CgalPolygon2d createCgalPolygonFromOpenCvPoints(Iter begin, Iter end, const double& resolution){ - return createCgalPolygonFromOpenCvPoints_impl(begin, end, resolution, - typename std::iterator_traits::iterator_category()); - }; +double computeTriangleArea(double side_length_a, double side_length_b, double side_length_c); - void performConvexDecomposition(const CgalPolygon2d& polygon, CgalPolygon2dContainer* output_polyong_list); +void connectSecondPolygonToFirst(CgalPolygon2d& left_polygon, CgalPolygon2d& right_polygon); - bool doPolygonAndSegmentIntersect(const CgalPolygon2d& polygon, const CgalSegment2d& segment, bool print_flag); +void copyVertices(const CgalPolygon2d& old_polygon, const CgalPolygon2dVertexIterator first, const CgalPolygon2dVertexIterator last, + CgalPolygon2d* new_polygon, const CgalPolygon2dVertexIterator insert_position); - int getClosestPolygonVertexPosition(const CgalPolygon2d& polygon, const CgalPoint2d& point); +template +CgalPolygon2d createCgalPolygonFromOpenCvPoints_impl(Iter begin, Iter end, const double& resolution, std::bidirectional_iterator_tag) { + CgalPolygon2d polygon; + for (auto it = begin; it < end; ++it) { + polygon.push_back(CgalPoint2d(static_cast((*it).y * resolution), static_cast((*it).x) * resolution)); + } + return polygon; +}; - void getVertexPositionsInAscendingDistanceToPoint(const CgalPolygon2d& polygon, const CgalPoint2d& point, - std::multimap* vertex_positions); +template +CgalPolygon2d createCgalPolygonFromOpenCvPoints(Iter begin, Iter end, const double& resolution) { + return createCgalPolygonFromOpenCvPoints_impl(begin, end, resolution, typename std::iterator_traits::iterator_category()); +}; - void getSegmentNormalVector(const CgalSegment2d& segment, Eigen::Vector2d* normal_vector); +std::list decomposeInnerApproximation(const CgalPolygon2d& polygon); - double computeTriangleArea(double side_length_a, double side_length_b, double side_length_c); +std::multimap detectDentLocations(const CgalPolygon2d& polygon); - CgalPolygon2dVertexIterator next(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon); +bool doPointAndPolygonIntersect(const CgalPolygon2d& polygon, const CgalPoint2d& point, int& segment_source_vertex_index); - bool next(const CgalPolygon2dVertexIterator& iterator, CgalPolygon2dVertexIterator& output_iterator, const CgalPolygon2d& polygon); +bool doPolygonAndSegmentIntersect(const CgalPolygon2d& polygon, const CgalSegment2d& segment, bool print_flag); - CgalPolygon2dVertexIterator previous(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon); +bool doRayAndSegmentIntersect(const CgalRay2d& ray, const CgalSegment2d& segment, RaySegmentIntersection* intersection); - void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, double relative_local_area_threshold, - double absolute_local_area_threshold, double relative_total_area_threshold, double absolute_total_area_threshold); +CgalPolygon2dVertexIterator erase(CgalPolygon2dVertexIterator first, CgalPolygon2dVertexIterator last, CgalPolygon2d* polygon); - void upSampleLongEdges(CgalPolygon2d* polygon); +std::pair getClosestPointAndSegmentOnPolygonToPoint(const CgalPoint2d& point, const CgalPolygon2d& polygon); - double getEdgeLength(const CgalPolygon2dVertexIterator& source, const CgalPolygon2d& polygon); +int getClosestPolygonVertexPosition(const CgalPolygon2d& polygon, const CgalPoint2d& point); - std::multimap detectDentLocations(const CgalPolygon2d& polygon); +std::multimap> getClosestVertexPairsOrdered(const CgalPolygon2d& first_polygon, + const CgalPolygon2d& second_polygon); - void connectSecondPolygonToFirst(CgalPolygon2d& left_polygon, CgalPolygon2d& right_polygon); +std::vector> getCommonVertexPairIndices(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon); - std::pair getIndicesOfClosestVertexPair(CgalPolygon2d& first_polygon, CgalPolygon2d& second_polygon); +double getEdgeLength(const CgalPolygon2dVertexIterator& source, const CgalPolygon2d& polygon); - std::multimap> getClosestVertexPairsOrdered(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon); +std::pair getIndicesOfClosestVertexPair(CgalPolygon2d& first_polygon, CgalPolygon2d& second_polygon); - CgalPoint2d getPolygonVertexAtIndex(const CgalPolygon2d& polygon, int index); +CgalPoint2d getPolygonVertexAtIndex(const CgalPolygon2d& polygon, int index); - bool doPointAndPolygonIntersect(const CgalPolygon2d& polygon, const CgalPoint2d& point, int& segment_source_vertex_index); +void getSegmentNormalVector(const CgalSegment2d& segment, Eigen::Vector2d* normal_vector); - struct Intersection{ - void setEdgeSourceLocation(const int location){ - edge_source_location_ = location; - } - void setEdgeTargetLocation(const int location){ - edge_target_location_ = location; - } - void setIntersectionPoint(const CgalPoint2d& intersection_point) { intersection_point_ = intersection_point; } - void setAllMembers(const int source_location, const int target_location, const CgalPoint2d& intersection_point, - const SegmentIntersectionType& intersection_type) { - edge_source_location_ = source_location; - edge_target_location_ = target_location; - intersection_type_ = intersection_type; - intersection_point_ = intersection_point; - } +std::vector getVertexIndicesOfFirstPolygonContainedInSecondPolygonContour(const CgalPolygon2d& first_polygon, + const CgalPolygon2d& second_polygon); - int edge_source_location_; - int edge_target_location_; - SegmentIntersectionType intersection_type_; - CgalPoint2d intersection_point_; - }; +void getVertexPositionsInAscendingDistanceToPoint(const CgalPolygon2d& polygon, const CgalPoint2d& point, + std::multimap* vertex_positions); - bool intersectPolygonWithRay(int ray_target_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, - Intersection* intersection); +std::pair getVertexPositionsWithHighestHoleSlConcavityMeasure(const CgalPolygon2d& polygon); - CgalPolygon2dVertexIterator erase(CgalPolygon2dVertexIterator first, CgalPolygon2dVertexIterator last, - CgalPolygon2d* polygon); +bool intersectPolygonWithRay(int ray_target_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, + Intersection* intersection); - void copyVertices(const CgalPolygon2d& old_polygon, const CgalPolygon2dVertexIterator first, const CgalPolygon2dVertexIterator last, - CgalPolygon2d* new_polygon, const CgalPolygon2dVertexIterator insert_position); +CgalPolygon2dVertexIterator next(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon); - std::list decomposeInnerApproximation(const CgalPolygon2d& polygon); +bool next(const CgalPolygon2dVertexIterator& iterator, CgalPolygon2dVertexIterator& output_iterator, const CgalPolygon2d& polygon); - void printPolygon(const CgalPolygon2d& polygon); +void performConvexDecomposition(const CgalPolygon2d& polygon, CgalPolygon2dContainer* output_polyong_list); - std::pair getVertexPositionsWithHighestHoleSlConcavityMeasure(const CgalPolygon2d& polygon); +CgalPolygon2dVertexIterator previous(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon); - std::pair getClosestPointAndSegmentOnPolygonToPoint(const CgalPoint2d& point, const CgalPolygon2d& polygon); +void printPolygon(const CgalPolygon2d& polygon); - std::vector> getCommonVertexPairIndices(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon); +std::string printPolygonToString(const CgalPolygon2d& polygon); - std::vector getVertexIndicesOfFirstPolygonContainedInSecondPolygonContour(const CgalPolygon2d& first_polygon, - const CgalPolygon2d& second_polygon); +void upSampleLongEdges(CgalPolygon2d* polygon); - bool doRayAndSegmentIntersect(const CgalRay2d& ray, const CgalSegment2d& segment, RaySegmentIntersection* intersection); - - } // namespace convex_plane_extraction +} // namespace convex_plane_extraction #endif //CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGON_HPP_ diff --git a/convex_plane_decomposition/include/polygonizer.hpp b/convex_plane_decomposition/include/polygonizer.hpp index 1e8b6d58..a13ed17b 100644 --- a/convex_plane_decomposition/include/polygonizer.hpp +++ b/convex_plane_decomposition/include/polygonizer.hpp @@ -33,32 +33,26 @@ struct PolygonizerParameters{ class Polygonizer { public: + explicit Polygonizer(const PolygonizerParameters parameters = PolygonizerParameters()) : parameters_(parameters){}; - explicit Polygonizer(const PolygonizerParameters parameters = PolygonizerParameters()) - :parameters_(parameters){}; + bool addHoleToOuterContourAtVertexIndex(int segment_target_vertex_index, const CgalPolygon2d& hole, CgalPolygon2d& outer_contour) const; + + PolygonWithHoles extractContoursFromBinaryImage(cv::Mat& binary_image) const; PolygonWithHoles extractPolygonsFromBinaryImage(const cv::Mat& binary_image) const; void removeAreasNotContainedInOuterContourFromHoles(const CgalPolygon2d& outer_polygon, std::vector& holes) const; - CgalPolygon2d resolveHolesWithVerticalConnection(PolygonWithHoles& polygon_with_holes) const; - - void approximatePolygon(CgalPolygon2d& polygon) const; - - CgalPolygon2d runPolygonizationOnBinaryImage(const cv::Mat& binary_image) const; - - bool addHoleToOuterContourAtVertexIndex(int segment_target_vertex_index, const CgalPolygon2d& hole, CgalPolygon2d& outer_contour) const; + void resolveHolesInBinaryImage(cv::Mat& binary_image, const PolygonWithHoles& contour_with_holes) const; CgalPolygon2d resolveHolesUsingSlConnection(const PolygonWithHoles& polygon_with_holes) const; - void resolveHolesInBinaryImage(cv::Mat& binary_image, const PolygonWithHoles& contour_with_holes) const; + CgalPolygon2d resolveHolesWithVerticalConnection(PolygonWithHoles& polygon_with_holes) const; - PolygonWithHoles extractContoursFromBinaryImage(cv::Mat& binary_image) const; + CgalPolygon2d runPolygonizationOnBinaryImage(const cv::Mat& binary_image) const; private: - PolygonizerParameters parameters_; - }; diff --git a/convex_plane_decomposition/include/ransac_plane_extractor.hpp b/convex_plane_decomposition/include/ransac_plane_extractor.hpp index 4e527f46..00ed69a9 100644 --- a/convex_plane_decomposition/include/ransac_plane_extractor.hpp +++ b/convex_plane_decomposition/include/ransac_plane_extractor.hpp @@ -1,7 +1,3 @@ -// -// Created by andrej on 11/21/19. -// - #ifndef CONVEX_PLANE_EXTRACTION_RANSACPLANEEXTRACTOR_HPP_ #define CONVEX_PLANE_EXTRACTION_RANSACPLANEEXTRACTOR_HPP_ @@ -65,8 +61,6 @@ namespace ransac_plane_extractor { return ransac_.shapes(); }; -// void ransacPlaneVisualization(); - private: EfficientRansac ransac_; diff --git a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp index 36211326..5e985def 100644 --- a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp +++ b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp @@ -34,23 +34,20 @@ namespace sliding_window_plane_extractor { class SlidingWindowPlaneExtractor{ public: - - SlidingWindowPlaneExtractor(grid_map::GridMap &map, double resolution, const std::string& layer_height, const SlidingWindowPlaneExtractorParameters& parameters = SlidingWindowPlaneExtractorParameters(), - const ransac_plane_extractor::RansacPlaneExtractorParameters& ransac_parameters = ransac_plane_extractor::RansacPlaneExtractorParameters()); - - void setParameters(const SlidingWindowPlaneExtractorParameters& parameters); + SlidingWindowPlaneExtractor(grid_map::GridMap& map, double resolution, const std::string& layer_height, + const SlidingWindowPlaneExtractorParameters& parameters = SlidingWindowPlaneExtractorParameters(), + const ransac_plane_extractor::RansacPlaneExtractorParameters& ransac_parameters = + ransac_plane_extractor::RansacPlaneExtractorParameters()); void runExtraction(); - const cv::Mat& getLabeledImage() const{ - return labeled_image_; - } + const cv::Mat& getLabeledImage() const { return labeled_image_; } - const auto& getLabelPlaneParameterMap() const{ return label_plane_parameters_map_; } + const auto& getLabelPlaneParameterMap() const { return label_plane_parameters_map_; } - const int getNumberOfExtractedPlanes() const { return number_of_extracted_planes_; } + int getNumberOfExtractedPlanes() const { return number_of_extracted_planes_; } - // void exportConvexPolygons(const std::string& path) const; + void setParameters(const SlidingWindowPlaneExtractorParameters& parameters); private: double computeAverageErrorToPlane(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector, @@ -84,5 +81,5 @@ namespace sliding_window_plane_extractor { int number_of_extracted_planes_; std::map label_plane_parameters_map_; }; -} -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_SLIDING_WINDOW_PLANE_EXTRACTOR_HPP_ + } // namespace sliding_window_plane_extractor +#endif // CONVEX_PLANE_EXTRACTION_INCLUDE_SLIDING_WINDOW_PLANE_EXTRACTOR_HPP_ diff --git a/convex_plane_decomposition/src/convex_decomposer.cpp b/convex_plane_decomposition/src/convex_decomposer.cpp index 3d914ebd..869b89cc 100644 --- a/convex_plane_decomposition/src/convex_decomposer.cpp +++ b/convex_plane_decomposition/src/convex_decomposer.cpp @@ -13,8 +13,8 @@ CgalPolygon2dContainer ConvexDecomposer::performConvexDecomposition(const CgalPo return convex_polygons; } CHECK(polygon.is_simple()); - if(polygon.is_convex()){ - LOG(INFO) << "Polygon already convex, no decompostion performed."; + if(polygon.is_convex()) { + VLOG(1) << "Polygon already convex, no decompostion performed."; convex_polygons.push_back(polygon); return convex_polygons; } @@ -39,8 +39,6 @@ CgalPolygon2dContainer ConvexDecomposer::performOptimalConvexDecomposition(const } CGAL::optimal_convex_partition_2(polygon.vertices_begin(), polygon.vertices_end(), std::back_inserter(polygon_buffer)); -// assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), polygon.vertices_end(), output_polygons.begin(), -// output_polygons.end())); CHECK_GT(polygon_buffer.size(), old_container_size); CgalPolygon2dContainer output_polygons; for (const auto& buffer_polygon : polygon_buffer){ @@ -187,45 +185,29 @@ CgalPolygon2dContainer ConvexDecomposer::performInnerConvexApproximation(const C CHECK(polygon_clockwise_2.is_simple()); VLOG(1) << "Started cut area computation..."; // Take the cut with smallest min. area of resulting polygons. - double area[4] = {polygon_counterclockwise_1.area(), polygon_counterclockwise_2.area(), polygon_clockwise_1.area(), - polygon_clockwise_2.area()}; + std::array area = {polygon_counterclockwise_1.area(), polygon_counterclockwise_2.area(), polygon_clockwise_1.area(), + polygon_clockwise_2.area()}; VLOG(1) << "done."; - double* min_area_strategy = std::min_element(area, area + 4); + const auto min_area_strategy = std::min_element(area.begin(), area.end()); CgalPolygon2dContainer recursion_1; CgalPolygon2dContainer recursion_2; - if ((min_area_strategy - area) < 2) { + if (std::distance(area.begin(), min_area_strategy) < 2) { // In this case the counter clockwise intersection leads to less loss in area. // Perform recursion with this split. - if(polygon_counterclockwise_1.orientation() != CGAL::COUNTERCLOCKWISE){ - LOG(WARNING) << "Polygon orientation wrong! Printing polygon ..."; - printPolygon(polygon_counterclockwise_1); - recursion_1 = std::vector(); - } else { - recursion_1 = performInnerConvexApproximation(polygon_counterclockwise_1); - } - if(polygon_counterclockwise_2.orientation() != CGAL::COUNTERCLOCKWISE){ - LOG(WARNING) << "Polygon orientation wrong! Printing polygon ..."; - printPolygon(polygon_counterclockwise_2); - recursion_2 = std::vector(); - } else{ - recursion_2 = performInnerConvexApproximation(polygon_counterclockwise_2); - } + CHECK_EQ(polygon_counterclockwise_1.orientation(), CGAL::COUNTERCLOCKWISE) + << "Polygon orientation wrong! Printing polygon ..." << printPolygonToString(polygon_counterclockwise_1); + recursion_1 = performInnerConvexApproximation(polygon_counterclockwise_1); + CHECK_EQ(polygon_counterclockwise_2.orientation(), CGAL::COUNTERCLOCKWISE) + << "Polygon orientation wrong! Printing polygon ..." << printPolygonToString(polygon_counterclockwise_2); + recursion_2 = performInnerConvexApproximation(polygon_counterclockwise_2); } else { // In this case the clockwise intersection leads to less loss in area. - if(polygon_clockwise_1.orientation() != CGAL::COUNTERCLOCKWISE){ - LOG(WARNING) << "Polygon orientation wrong! Printing polygon ..."; - printPolygon(polygon_clockwise_1); - recursion_1 = std::vector(); - } else{ - recursion_1 = performInnerConvexApproximation(polygon_clockwise_1); - } - if(polygon_clockwise_2.orientation() != CGAL::COUNTERCLOCKWISE){ - LOG(WARNING) << "Polygon orientation wrong! Printing polygon ..."; - printPolygon(polygon_clockwise_2); - recursion_2 = std::vector(); - } else{ - recursion_2 = performInnerConvexApproximation(polygon_clockwise_2); - } + CHECK_EQ(polygon_clockwise_1.orientation(), CGAL::COUNTERCLOCKWISE) + << "Polygon orientation wrong! Printing polygon ..." << printPolygonToString(polygon_clockwise_1); + recursion_1 = performInnerConvexApproximation(polygon_clockwise_1); + CHECK_EQ(polygon_clockwise_2.orientation(), CGAL::COUNTERCLOCKWISE) + << "Polygon orientation wrong! Printing polygon ..." << printPolygonToString(polygon_clockwise_2); + recursion_2 = performInnerConvexApproximation(polygon_clockwise_2); } std::move(recursion_1.begin(), recursion_1.end(), std::back_inserter(convex_polygons)); std::move(recursion_2.begin(), recursion_2.end(), std::back_inserter(convex_polygons)); @@ -249,12 +231,11 @@ std::multimap ConvexDecomposer::detectDentLocations(const CgalPolyg if(isPointOnLeftSide(source_point, direction_vector, test_point)){ double angle = abs(computeAngleBetweenVectors(source_point - test_point, destination_point - test_point)); // Ignore very shallow dents. Approximate convex decomposition. - if ( angle > parameters_.dent_angle_threshold_rad) + if (angle > parameters_.dent_angle_threshold_rad) { dent_locations.insert(std::make_pair(angle, std::distance(polygon.vertices_begin(), dent_it))); + } } } VLOG(1) << "done."; return dent_locations; } - -// *output_polygon_list = decomposeInnerApproximation(polygon); \ No newline at end of file diff --git a/convex_plane_decomposition/src/convex_polygon_decomposition.cpp b/convex_plane_decomposition/src/convex_polygon_decomposition.cpp deleted file mode 100644 index 7e794d9b..00000000 --- a/convex_plane_decomposition/src/convex_polygon_decomposition.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "convex_polygon_decomposition.hpp" - -namespace convex_plane_extraction { - void performConvexDecomposition(const CgalPolygon2d& polygon, CgalPolygon2dListContainer* output_polyong_list){ - CHECK_GE(polygon.size(), 3); - CHECK(polygon.is_simple()); - LOG(INFO) << "Started convex decomposition..."; - CGAL::optimal_convex_partition_2(polygon.vertices_begin(), - polygon.vertices_end(), - std::back_inserter(*output_polyong_list)); - - assert(CGAL::partition_is_valid_2(polygon.vertices_begin(), - polygon.vertices_end(), - polygon_list.begin(), - polygon_list.end())); - LOG(INFO) << "done."; - } -} - diff --git a/convex_plane_decomposition/src/export_utils.cpp b/convex_plane_decomposition/src/export_utils.cpp index fd1a762d..fb24c046 100644 --- a/convex_plane_decomposition/src/export_utils.cpp +++ b/convex_plane_decomposition/src/export_utils.cpp @@ -3,19 +3,17 @@ namespace convex_plane_extraction { - bool exportPointsWithNormalsToCsv(grid_map::GridMap &map, const std::string &normals_layer_prefix, - const std::string &layer_height) { - std::ofstream output_file; - output_file.open("/home/andrej/sp_ws/points_and_normals.csv"); - for (grid_map::GridMapIterator iterator(map); - !iterator.isPastEnd(); ++iterator) { - grid_map::Position3 position3; - Eigen::Vector3d point; - Eigen::Vector3d normal; - map.getPosition3(layer_height, *iterator, point); - map.getVector(normals_layer_prefix, *iterator, normal); - output_file << point(0) << ", " << point(1) << ", " << point(2) << ", " << - normal(0) << ", " << normal(1) << ", " << normal(2) << "\n"; +bool exportPointsWithNormalsToCsv(grid_map::GridMap& map, const std::string& normals_layer_prefix, const std::string& layer_height, + const std::string& path) { + std::ofstream output_file; + output_file.open(path + "points_and_normals.csv"); + for (grid_map::GridMapIterator iterator(map); !iterator.isPastEnd(); ++iterator) { + grid_map::Position3 position3; + Eigen::Vector3d point; + Eigen::Vector3d normal; + map.getPosition3(layer_height, *iterator, point); + map.getVector(normals_layer_prefix, *iterator, normal); + output_file << point(0) << ", " << point(1) << ", " << point(2) << ", " << normal(0) << ", " << normal(1) << ", " << normal(2) << "\n"; } return true; } diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp index 51aeb611..a1d97ccf 100644 --- a/convex_plane_decomposition/src/geometry_utils.cpp +++ b/convex_plane_decomposition/src/geometry_utils.cpp @@ -36,72 +36,6 @@ namespace convex_plane_extraction { return acos(abs(scalar_product) / (first_vector.norm() * second_vector.norm())); } - // bool intersectRayWithLineSegment(const Vector2d& ray_source, const Vector2d& ray_direction, - // const Vector2d& segment_source, const Vector2d& segment_target, Vector2d* intersection_point){ - // CHECK_NOTNULL(intersection_point); - // Vector2d segment_direction = segment_target - segment_source; - // Matrix2d A; - // A.col(0) = ray_direction; - // A.col(1) = - segment_direction; - // Vector2d b = segment_source - ray_source; - // auto householder_qr = A.fullPivHouseholderQr(); - // if (householder_qr.rank() < 2) { - // // Check whether segment and ray overlap. - // const Vector2d p_ray_source_segment_source = segment_source - ray_source; - // const Vector2d p_ray_source_segment_target = segment_target - ray_source; - // if (p_ray_source_segment_source.norm() > p_ray_source_segment_target) { - // } - // Vector2d ray_parameter_solution = - // Vector2d(p_ray_source_segment_source.x() / ray_direction.x(), p_ray_source_segment_source.y() / ray_direction.y()); - // constexpr double kSolutionDeviation = 0.0001; - // if (abs(ray_parameter_solution.x() - ray_parameter_solution.y()) < kSolutionDeviation) { - // double parameter_solution_tmp = ray_parameter_solution.mean(); - // if (parameter_solution_tmp < 0) { - // return false; - // } - // CHECK_GT(parameter_solution_tmp, 0); - // Vector2d p_ray_source_segment_target = segment_target - ray_source; - // ray_parameter_solution = - // Vector2d(p_ray_source_segment_target.x() / ray_direction.x(), p_ray_source_segment_target.y() / ray_direction.y()); - // // If ray is parallel (rank loss) and source point lies on ray, then target point has to as well. - // CHECK_LT(abs(ray_parameter_solution.x() - ray_parameter_solution.y()), kSolutionDeviation); - // if (ray_parameter_solution.mean() < 0) { - // return false; - // } - // if (ray_parameter_solution.mean() < parameter_solution_tmp) { - // *intersection_point = segment_target; - // } else { - // *intersection_point = segment_source; - // } - // return true; - // } - // return false; - // } - // Vector2d solution = householder_qr.solve(b); - // Vector2d ray_solution = ray_source + solution(0) * segment_direction; - // Vector2d segment_solution = segment_source + solution(1) * segment_direction; - // constexpr double kSegmentBorderToleranceMeters = 0.001; - // if (solution(0) <= 1) { - // return false; - // } else if (solution(1) < 0) { - // if ((segment_solution - segment_source).norm() > kSegmentBorderToleranceMeters) { - // return false; - // } else { - // *intersection_point = segment_source; - // return true; - // } - // } else if (solution(1) > 1) { - // if ((segment_solution - segment_target).norm() > kSegmentBorderToleranceMeters) { - // return false; - // } else { - // *intersection_point = segment_target; - // } - // } else { - // *intersection_point = segment_solution; - // return true; - // } - // } - bool intersectLineSegmentWithLineSegment(const Vector2d& segment_1_source, const Vector2d& segment_1_target, const Vector2d& segment_2_source, const Vector2d& segment_2_target, Vector2d* intersection_point) { @@ -177,4 +111,3 @@ namespace convex_plane_extraction { } } - diff --git a/convex_plane_decomposition/src/pipeline.cpp b/convex_plane_decomposition/src/pipeline.cpp index 1811f0e4..131e72bf 100644 --- a/convex_plane_decomposition/src/pipeline.cpp +++ b/convex_plane_decomposition/src/pipeline.cpp @@ -1,4 +1,3 @@ - #include "pipeline.hpp" using namespace convex_plane_extraction; @@ -26,28 +25,3 @@ Polygon3dVectorContainer Pipeline::getConvexPolygons() const{ Polygon3dVectorContainer Pipeline::getPlaneContours() const{ return plane_factory_.getPlaneContoursInWorldFrame(); } - -//void Pipeline::exportConvexPolygons(const std::string& export_path) const { -// std::ofstream output_file; -// output_file.open(export_path + "convex_polygons.txt", std::ofstream::app); -// std::chrono::milliseconds time_stamp = std::chrono::duration_cast( -// std::chrono::system_clock::now().time_since_epoch()); -// for (const auto& plane : planes_){ -// for (const auto& polygon : plane.getConvexPolygons()){ -// output_file << time_stamp.count() << ", "; -// for (const auto& vertex : polygon){ -// output_file << vertex.x() << ", "; -// } -// for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it){ -// output_file << vertex_it->y(); -// if (vertex_it != std::prev(polygon.vertices_end())){ -// output_file << ", "; -// } else { -// output_file << "\n"; -// } -// } -// } -// } -// output_file.close(); -// VLOG(1) << "Exported polygons to " << export_path << "convex_polygons.txt !"; -//} \ No newline at end of file diff --git a/convex_plane_decomposition/src/plane.cpp b/convex_plane_decomposition/src/plane.cpp index c2fe0ed8..6ae4908d 100644 --- a/convex_plane_decomposition/src/plane.cpp +++ b/convex_plane_decomposition/src/plane.cpp @@ -8,6 +8,4 @@ namespace convex_plane_extraction{ return true; } - - } diff --git a/convex_plane_decomposition/src/plane_extractor.cpp b/convex_plane_decomposition/src/plane_extractor.cpp deleted file mode 100644 index e1369da6..00000000 --- a/convex_plane_decomposition/src/plane_extractor.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// -// Created by andrej on 12/6/19. -// - -#include "plane_extractor.hpp" - -namespace convex_plane_extraction { -using namespace grid_map; - - PlaneExtractor::PlaneExtractor(grid_map::GridMap &map, double resolution, const std::string &normals_layer_prefix, - const std::string &height_layer) - : map_(map), - resolution_(resolution), - normal_layer_prefix_(normals_layer_prefix), - height_layer_(height_layer), - ransac_plane_extractor_(ransac_plane_extractor::RansacPlaneExtractor(map, resolution, normals_layer_prefix, height_layer)), - sliding_window_plane_extractor_(sliding_window_plane_extractor::SlidingWindowPlaneExtractor(map,resolution, normals_layer_prefix, height_layer)){ - map_size_ = map.getSize(); - ROS_INFO("Plane extractor initialization successful!"); - } - - PlaneExtractor::~PlaneExtractor(){} - - grid_map::GridMap& PlaneExtractor::getMap(){ - return map_; - } - - void PlaneExtractor::setRansacParameters(const ransac_plane_extractor::RansacPlaneExtractorParameters& parameters){ - ransac_plane_extractor_.setParameters(parameters); - ROS_INFO("RANSAC parameters set!"); - } - - void PlaneExtractor::runRansacPlaneExtractor(){ - ROS_INFO("Starting RANSAC plane extraction..."); - ransac_plane_extractor_.runDetection(); - ROS_INFO("... done."); - } - - void PlaneExtractor::augmentMapWithRansacPlanes(){ - ransac_plane_extractor_.ransacPlaneVisualization(); - } - - void PlaneExtractor::setSlidingWindowParameters(const sliding_window_plane_extractor::SlidingWindowParameters & parameters) { - sliding_window_plane_extractor_.setParameters(parameters); - ROS_INFO("Sliding window parameters set!"); - } - - void PlaneExtractor::runSlidingWindowPlaneExtractor(){ - ROS_INFO("Starting sliding window plane extraction..."); - sliding_window_plane_extractor_.runSlidingWindowDetector(); - ROS_INFO("... done."); - } - -void PlaneExtractor::augmentMapWithSlidingWindowPlanes(){ - sliding_window_plane_extractor_.slidingWindowPlaneVisualization(); -} - -} \ No newline at end of file diff --git a/convex_plane_decomposition/src/plane_factory.cpp b/convex_plane_decomposition/src/plane_factory.cpp index 338932ae..1e18d838 100644 --- a/convex_plane_decomposition/src/plane_factory.cpp +++ b/convex_plane_decomposition/src/plane_factory.cpp @@ -16,7 +16,6 @@ void PlaneFactory::computeMapTransformation(){ void PlaneFactory::createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, const int number_of_labels, const std::map& plane_parameters){ CHECK_GT(number_of_labels, 0); - //CHECK_EQ(number_of_labels, plane_parameters.size()); Polygonizer polygonizer(parameters_.polygonizer_parameters); for (int label = 1; label < number_of_labels; ++label){ if (plane_parameters.find(label) == plane_parameters.end()){ @@ -27,14 +26,14 @@ void PlaneFactory::createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& const CgalPolygon2d plane_contour = polygonizer.runPolygonizationOnBinaryImage(binary_image); const auto plane_parameter_it = plane_parameters.find(label); CHECK(plane_parameter_it != plane_parameters.end()) << "Label not contained in plane parameter container!"; - if (plane_contour.is_empty()){ - LOG(WARNING) << "Dropping plane, polygon negligible!"; + if (plane_contour.is_empty()) { + LOG(INFO) << "Dropping plane, polygon empty!"; continue; } if (isPlaneInclinationBelowThreshold(plane_parameter_it->second.normal_vector)){ planes_.emplace_back(plane_contour, plane_parameter_it->second); } else { - LOG(WARNING) << "Dropping plane due to exceeded inclination threshold!"; + LOG(INFO) << "Dropping plane due to exceeded inclination threshold!"; } } } @@ -95,16 +94,16 @@ Polygon3dVectorContainer PlaneFactory::convertPlanePolygonsToWorldFrame(const Cg return output_polygons; } -Eigen::Vector3d PlaneFactory::convertPlanePointToWorldFrame(const CgalPoint2d& point, const PlaneParameters& plane_parameters) const{ +Eigen::Vector3d PlaneFactory::convertPlanePointToWorldFrame(const CgalPoint2d& point, const PlaneParameters& plane_parameters) const { Eigen::Vector2d temp_point(point.x(), point.y()); temp_point = transformation_xy_to_world_frame_ * temp_point; temp_point = temp_point + map_offset_; - LOG_IF(FATAL, !std::isfinite(temp_point.x())) << "Not finite x value!"; - LOG_IF(FATAL, !std::isfinite(temp_point.y())) << "Not finite y value!"; - const double z = (-(temp_point.x() - plane_parameters.support_vector.x())*plane_parameters.normal_vector.x() - - (temp_point.y() - plane_parameters.support_vector.y())* plane_parameters.normal_vector.y()) / - plane_parameters.normal_vector(2) + plane_parameters.support_vector(2); - LOG_IF(FATAL, !std::isfinite(z)) << "Not finite z value!"; - return Vector3d(temp_point.x(), temp_point.y(), z); + CHECK(std::isfinite(temp_point.x())) << "Not finite x value!"; + CHECK(std::isfinite(temp_point.y())) << "Not finite y value!"; + const double z = (-(temp_point.x() - plane_parameters.support_vector.x()) * plane_parameters.normal_vector.x() - + (temp_point.y() - plane_parameters.support_vector.y()) * plane_parameters.normal_vector.y()) / + plane_parameters.normal_vector(2) + + plane_parameters.support_vector(2); + CHECK(std::isfinite(z)) << "Not finite z value!"; + return {temp_point.x(), temp_point.y(), z}; } - diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index e41bde39..786bd332 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -311,26 +311,23 @@ namespace convex_plane_extraction { } } - void printPolygon(const CgalPolygon2d& polygon){ + void printPolygon(const CgalPolygon2d& polygon) { std::cout << "Polygon has " << polygon.size() << " vertices." << std::endl; - for (const CgalPoint2d& vertex : polygon){ + for (const CgalPoint2d& vertex : polygon) { std::cout << vertex.x() << " , " << vertex.y() << " ; " << std::endl; } } -// void slConcavityHoleVertexSorting(const CgalPolygon2d& hole, std::multimap>* concavity_positions){ -// CHECK_NOTNULL(concavity_positions); -// for (auto vertex_it = hole.vertices_begin(); vertex_it != hole.vertices_end(); ++vertex_it){ -// std::multimap outer_polygon_vertices; -// getVertexPositionsInAscendingDistanceToPoint(outer_polygon_, *vertex_it, &outer_polygon_vertices); -// for (const auto& outer_distance_vertex_pair : outer_polygon_vertices) { -// concavity_positions->insert(std::pair>(outer_distance_vertex_pair.first, -// std::pair(std::distance(hole.vertices_begin(), vertex_it),outer_distance_vertex_pair.second))); -// } -// } -// } + std::string printPolygonToString(const CgalPolygon2d& polygon) { + std::string string; + string = "Polygon has " + std::to_string(polygon.size()) + " vertices. \n"; + for (const CgalPoint2d& vertex : polygon) { + string += std::to_string(vertex.x()) + " , " + std::to_string(vertex.y()) + " ;\n"; + } + return string; + } - std::pair getIndicesOfClosestVertexPair(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon){ + std::pair getIndicesOfClosestVertexPair(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon) { CHECK_GT(first_polygon.size(), 0); CHECK_GT(second_polygon.size(), 0); std::multimap> buffer = getClosestVertexPairsOrdered(first_polygon, second_polygon); @@ -338,7 +335,8 @@ namespace convex_plane_extraction { return buffer.begin()->second; } - std::multimap> getClosestVertexPairsOrdered(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon){ + std::multimap> getClosestVertexPairsOrdered(const CgalPolygon2d& first_polygon, + const CgalPolygon2d& second_polygon) { CHECK_GT(first_polygon.size(), 0); CHECK_GT(second_polygon.size(), 0); std::multimap> buffer; diff --git a/convex_plane_decomposition/src/polygonizer.cpp b/convex_plane_decomposition/src/polygonizer.cpp index 4ee8e71d..9b0d8f40 100644 --- a/convex_plane_decomposition/src/polygonizer.cpp +++ b/convex_plane_decomposition/src/polygonizer.cpp @@ -69,6 +69,7 @@ PolygonWithHoles Polygonizer::extractContoursFromBinaryImage(cv::Mat& binary_ima return plane_polygons; } +// Deprecated: Due to finite resolution in image, complicated contours are extracted in the end. void Polygonizer::resolveHolesInBinaryImage(cv::Mat& binary_image, const PolygonWithHoles& contour_with_holes) const{ for(const auto& hole : contour_with_holes.holes){ if (hole.area() > 36){ @@ -92,201 +93,8 @@ void Polygonizer::resolveHolesInBinaryImage(cv::Mat& binary_image, const Polygon cv::line(binary_image, first_point, second_point, CV_RGB(0,0,0), 2); } } -// cv::namedWindow( "Display window", cv::WINDOW_AUTOSIZE); // Create a window for display. -// cv::imshow( "Display window", binary_image); -// cv::waitKey(0); } -//CgalPolygon2d Polygonizer::resolveHoles(PolygonWithHoles& polygon_with_holes) const{ -// CgalPolygon2dContainer& holes = polygon_with_holes.holes; -// // Get hole part which is entirely contained in outer contour. -// // In the contour simplification stage intersections may have been introduced. -// removeAreasNotContainedInOuterContourFromHoles(polygon_with_holes.outer_contour, holes); -// if (holes.empty()) { -// return polygon_with_holes.outer_contour; -// } -// auto hole_it = holes.begin(); -// while(!holes.empty()) { -// if (hole_it == holes.end()){ -// hole_it = holes.begin(); -// } -// // Compute distance to outer contour for each hole. -// if (hole_it->size() < 3) { -// hole_it = holes.erase(hole_it); -// } else if (abs(hole_it->area()) < parameters_.hole_area_threshold_squared_meters) { -// hole_it = holes.erase(hole_it); -// } else { -// // Does one hole edge overlap with outer polygon? Treat this separately. -// doHole -// std::pair bridge_hole_outer_vertex = getIndicesOfClosestVertexPair(*hole_it, polygon_with_holes.outer_contour); -// CgalSegment2d bridge(getPolygonVertexAtIndex(*hole_it, bridge_hole_outer_vertex .first), -// getPolygonVertexAtIndex(polygon_with_holes.outer_contour, bridge_hole_outer_vertex .second)); -// int segment_target_vertex_index; -// if (doPointAndPolygonIntersect(polygon_with_holes.outer_contour, getPolygonVertexAtIndex(*hole_it, -// bridge_hole_outer_vertex.first), segment_target_vertex_index)){ -// addHoleToOuterContourAtVertexIndex(bridge_hole_outer_vertex.first, segment_target_vertex_index, *hole_it, polygon_with_holes.outer_contour); -// } -// int hole_connection_vertex_position; -// int outer_polygon_connection_vertex_position; -// bool valid_connection = true; -// int i = 0; -// for (const auto& position : connection_candidates){ -// auto hole_vertex_it = hole_it->vertices_begin(); -// std::advance(hole_vertex_it, position.second.first); -// bool print_flag = false; -// if (position.second.first == 7){ -// print_flag = true; -// } -// CgalPoint2d hole_vertex = *hole_vertex_it; -// // Get outer contour connection vertices sorted according to distance to hole vertex. -// auto outer_vertex_it = outer_polygon_.vertices_begin(); -// std::advance(outer_vertex_it, position.second.second); -// CgalVector2d direction = *outer_vertex_it - hole_vertex; -// direction = (1.0/direction.squared_length()) * direction; -// CgalSegment2d connection(hole_vertex + 0.0001 * direction, *outer_vertex_it - 0.0001 * direction); -// if (!doPolygonAndSegmentIntersect(outer_polygon_, connection, print_flag)){ -// valid_connection = true; -// for (auto hole_iterator = hole_polygons_.begin(); hole_iterator != hole_polygons_.end(); ++hole_iterator){ -// if (hole_iterator->size() < 3){ -// continue; -// } -// if (doPolygonAndSegmentIntersect(*hole_iterator, connection, print_flag)) { -// valid_connection = false; -// //std::cout << "Hole and connection intersect!" << std::endl; -// ++i; -// break; -// } -// } -// } else { -// //std::cout << "Outer contour and connection intersect!" << std::endl; -// ++i; -// valid_connection = false; -// } -// if (valid_connection){ -// hole_connection_vertex_position = position.second.first; -// outer_polygon_connection_vertex_position = position.second.second; -// break; -// } -// } -// if (!valid_connection){ -// CHECK_EQ(i, hole_it->size()*outer_polygon_.size()); -// LOG(WARNING) << "No valid connection found! " << i << " iterations."; -// ++hole_it; -// continue; -// } -// CHECK(valid_connection); -// // Perform the integration of the hole into the outer contour. -// auto outer_contour_connection_vertex = outer_polygon_.vertices_begin(); -// std::advance(outer_contour_connection_vertex, outer_polygon_connection_vertex_position); -// auto hole_contour_connection_vertex = hole_it->vertices_begin(); -// std::advance(hole_contour_connection_vertex, hole_connection_vertex_position); -// CgalPolygon2d new_polygon; -// // Start filling new polygon with outer contour. -// for (auto vertex_it = outer_polygon_.vertices_begin(); vertex_it != outer_contour_connection_vertex; ++vertex_it){ -// new_polygon.push_back(*vertex_it); -// } -// new_polygon.push_back(*outer_contour_connection_vertex); -// auto hole_vertex_it = hole_contour_connection_vertex; -// do { -// new_polygon.push_back(*hole_vertex_it); -// if (hole_vertex_it != std::prev(hole_it->vertices_end())){ -// hole_vertex_it = std::next(hole_vertex_it); -// } else { -// hole_vertex_it = hole_it->vertices_begin(); -// } -// } while(hole_vertex_it != hole_contour_connection_vertex); -// // Create new vertices next to connection points to avoid same enter and return path. -// CgalSegment2d enter_connection(*outer_contour_connection_vertex, *hole_contour_connection_vertex); -// Eigen::Vector2d normal_vector; -// getSegmentNormalVector(enter_connection, &normal_vector); -// // Check for possible intersections. -// Eigen::Vector2d line_start_point(hole_contour_connection_vertex->x(), hole_contour_connection_vertex->y()); -// Eigen::Vector2d direction_vector(outer_contour_connection_vertex->x() - hole_contour_connection_vertex->x(), -// outer_contour_connection_vertex->y() - hole_contour_connection_vertex->y()); -// auto next_vertex = std::next(outer_contour_connection_vertex); -// if (next_vertex == outer_polygon_.vertices_end()){ -// next_vertex = outer_polygon_.begin(); -// } -// Eigen::Vector2d test_point(next_vertex->x(), next_vertex->y()); -// constexpr double kPointOffset = 0.0001; -// Eigen::Vector2d outer_point(outer_contour_connection_vertex->x(), outer_contour_connection_vertex->y()); -// if (isPointOnLeftSide(line_start_point, direction_vector, test_point)){ -// Eigen::Vector2d translation_vector(next_vertex->x() - outer_contour_connection_vertex->x(), -// next_vertex->y() - outer_contour_connection_vertex->y()); -// translation_vector.normalize(); -// outer_point += kPointOffset * translation_vector.normalized(); -// } else { -// outer_point += kPointOffset * normal_vector.normalized(); -// } -// next_vertex = hole_contour_connection_vertex; -// if (next_vertex == hole_it->vertices_begin()){ -// next_vertex = hole_it->vertices_end(); -// next_vertex = std::prev(next_vertex); -// } else { -// next_vertex = std::prev(next_vertex); -// } -// Eigen::Vector2d hole_point(hole_contour_connection_vertex->x(), hole_contour_connection_vertex->y()); -// test_point << next_vertex->x(), next_vertex->y(); -// constexpr double kPiHalf = 3.1416 / 2; -// if (isPointOnLeftSide(line_start_point, direction_vector, test_point) -// && computeAngleBetweenVectors(test_point - line_start_point, direction_vector) < kPiHalf){ -// Eigen::Vector2d translation_vector(next_vertex->x() - hole_contour_connection_vertex->x(), -// next_vertex->y() - hole_contour_connection_vertex->y()); -// translation_vector.normalize(); -// hole_point += kPointOffset * translation_vector; -// } else { -// hole_point += kPointOffset * normal_vector; -// } -// Vector2d new_edge_direction = outer_point - hole_point; -// new_edge_direction.normalize(); -// constexpr double kShiftFactor = 0.0001; -// bool intersection_caused = false; -// CgalSegment2d new_edge(CgalPoint2d(hole_point.x() + kShiftFactor * new_edge_direction.x(), -// hole_point.y() + kShiftFactor * new_edge_direction.y()),CgalPoint2d(outer_point.x() - -// kShiftFactor * new_edge_direction.x(), outer_point.y() - kShiftFactor * new_edge_direction.y())); -// if (!doPolygonAndSegmentIntersect(outer_polygon_, new_edge, false)){ -// for (auto hole_iterator = hole_polygons_.begin(); hole_iterator != hole_polygons_.end(); ++hole_iterator){ -// if (hole_iterator->size() < 3){ -// continue; -// } -// if (doPolygonAndSegmentIntersect(*hole_iterator, new_edge, false)) { -// intersection_caused = true; -// break; -// } -// } -// } else { -// //std::cout << "Outer contour and connection intersect!" << std::endl; -// intersection_caused = true; -// } -// if (intersection_caused){ -// ++hole_it; -// continue; -// } -// // Add new vertices to outer contour. -// new_polygon.push_back(CgalPoint2d(hole_point.x(), hole_point.y())); -// new_polygon.push_back(CgalPoint2d(outer_point.x(), outer_point.y())); -// // Add remaining outer contour vertices to new polygon. -// auto vertex_it = outer_contour_connection_vertex; -// vertex_it = std::next(vertex_it); -// for (; vertex_it != outer_polygon_.vertices_end(); ++vertex_it){ -// new_polygon.push_back(*vertex_it); -// } -// if (!new_polygon.is_simple()){ -// std::cout << "Hole orientation: " << hole_it->orientation() << std::endl; -// std::cout <<"Hole vertex: " << *hole_contour_connection_vertex << std::endl; -// std::cout <<"Outer vertex: " << *outer_contour_connection_vertex << std::endl; -// printPolygon(new_polygon); -// } -// CHECK(new_polygon.is_simple()); -// outer_polygon_ = new_polygon; -// ++hole_it; -// hole_polygons_.erase(std::prev(hole_it)); -// } -// } -// //approximateContour(&outer_polygon_); -// CHECK(outer_polygon_.is_simple()); -//} - void Polygonizer::removeAreasNotContainedInOuterContourFromHoles(const CgalPolygon2d& outer_polygon, std::vector& holes) const{ auto hole_it = holes.begin(); while(hole_it != holes.end()) { @@ -312,6 +120,7 @@ bool Polygonizer::addHoleToOuterContourAtVertexIndex(int segment_target_vertex_i return false; } +// Deprecated: This method produces non-simple polygons. CgalPolygon2d Polygonizer::resolveHolesWithVerticalConnection(PolygonWithHoles& polygon_with_holes) const{ CgalPolygon2dContainer& holes = polygon_with_holes.holes; // Get hole part which is entirely contained in outer contour. @@ -341,27 +150,13 @@ CgalPolygon2d Polygonizer::resolveHolesWithVerticalConnection(PolygonWithHoles& return **offset_polygons.begin(); } -/* -void Polygonizer::approximatePolygon(CgalPolygon2d& polygon) const{ - std::vector contour; - for (const auto& vertex : polygon.container()){ - contour.emplace_back(vertex.y(), vertex.x()); - } - std::vector approx_contour; - cv::approxPolyDP(contour, approx_contour, parameters_.contour_approximation_deviation_threshold, true); - polygon.clear(); - for (const auto& point : approx_contour){ - polygon.push_back(CgalPoint2d(point.y, point.x)); - } -} -*/ CgalPolygon2d Polygonizer::runPolygonizationOnBinaryImage(const cv::Mat& binary_image) const{ PolygonWithHoles polygon_with_holes = extractPolygonsFromBinaryImage(binary_image); //CgalPolygon2d polygon = resolveHolesWithVerticalConnection(polygon_with_holes); - //approximatePolygon(polygon_with_holes.outer_contour); return polygon_with_holes.outer_contour; } +// TODO: complete implementation! CgalPolygon2d Polygonizer::resolveHolesUsingSlConnection(const PolygonWithHoles& polygon_with_holes) const{ CgalPolygon2dContainer holes = polygon_with_holes.holes; // Get hole part which is entirely contained in outer contour. diff --git a/convex_plane_decomposition/src/ransac_plane_extractor.cpp b/convex_plane_decomposition/src/ransac_plane_extractor.cpp index 7e7ce385..1d6f94fd 100644 --- a/convex_plane_decomposition/src/ransac_plane_extractor.cpp +++ b/convex_plane_decomposition/src/ransac_plane_extractor.cpp @@ -25,26 +25,4 @@ void RansacPlaneExtractor::setParameters(const RansacPlaneExtractorParameters& p parameters_.normal_threshold = parameters.normal_threshold; } -//void RansacPlaneExtractor::ransacPlaneVisualization(){ -// Eigen::MatrixXf plane_map = Eigen::MatrixXf::Zero(map_.getSize().x(), map_.getSize().y()); -// int32_t plane_label_iterator = 1; -// for (auto plane : ransac_.shapes()){ -// const std::vector& plane_points = (*plane.get()).indices_of_assigned_points(); -// auto plane_points_it = plane_points.begin(); -// for (; plane_points_it != plane_points.end(); ++plane_points_it){ -// Point_3D& point = points_with_normal_.getPoint(*plane_points_it); -// Eigen::Array2i map_indices; -// map_.getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); -// ransac_map_(map_indices(0), map_indices(1)) = 1;//plane_label_iterator; -// } -// ++plane_label_iterator; -// } -// std::ofstream output_file; -// output_file.open("/home/andrej/Desktop/number_of_planes_ransac_12.txt", std::ofstream::app);; -// output_file << plane_label_iterator << "\n"; -// output_file.close(); -// map_.add("ransac_planes", ransac_map_); -// std::cout << "Added ransac plane layer!" << std::endl; -//} - diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index 8cb62a8e..e1f3227e 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -1,4 +1,3 @@ - #include "sliding_window_plane_extractor.hpp" namespace sliding_window_plane_extractor{ From 6b52c6efe14143e69d5439d9929031f40ea56b1b Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Mon, 30 Mar 2020 21:02:22 +0200 Subject: [PATCH 034/504] Clean-up. --- convex_plane_decomposition/include/plane.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convex_plane_decomposition/include/plane.hpp b/convex_plane_decomposition/include/plane.hpp index 00ce8f14..93aa7b22 100644 --- a/convex_plane_decomposition/include/plane.hpp +++ b/convex_plane_decomposition/include/plane.hpp @@ -20,7 +20,7 @@ namespace convex_plane_extraction { class Plane { public: - Plane(const CgalPolygon2d& plane_contour, const PlaneParameters parameters) + Plane(const CgalPolygon2d& plane_contour, const PlaneParameters& parameters) : plane_contour_(plane_contour), normal_vector_(parameters.normal_vector), support_vector_(parameters.support_vector) {} void addConvexPolygon(const CgalPolygon2d& convex_polygon) { convex_polygons_.push_back(convex_polygon); } From 26bfee9c8e9ccc833f14ad30704fcf3a1e0a0ee7 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Sun, 5 Apr 2020 19:32:31 +0200 Subject: [PATCH 035/504] Modified rviz view. --- .../convex_plane_extraction_demo.launch | 4 +- .../rviz/config.rviz | 8 +- .../rviz/config_demo.rviz | 281 ++++++++++++++++++ 3 files changed, 287 insertions(+), 6 deletions(-) create mode 100644 convex_plane_decomposition_ros/rviz/config_demo.rviz diff --git a/convex_plane_decomposition_ros/launch/convex_plane_extraction_demo.launch b/convex_plane_decomposition_ros/launch/convex_plane_extraction_demo.launch index 9829094c..95cc115d 100644 --- a/convex_plane_decomposition_ros/launch/convex_plane_extraction_demo.launch +++ b/convex_plane_decomposition_ros/launch/convex_plane_extraction_demo.launch @@ -13,5 +13,5 @@ - - \ No newline at end of file + + diff --git a/convex_plane_decomposition_ros/rviz/config.rviz b/convex_plane_decomposition_ros/rviz/config.rviz index f8fb179b..3ee6f810 100644 --- a/convex_plane_decomposition_ros/rviz/config.rviz +++ b/convex_plane_decomposition_ros/rviz/config.rviz @@ -248,9 +248,9 @@ Visualization Manager: Swap Stereo Eyes: false Value: false Focal Point: - X: 1.046505093574524 - Y: -13.699677467346191 - Z: 6.601845741271973 + X: -1 + Y: -1 + Z: 2 Focal Shape Fixed Size: true Focal Shape Size: 0.05000000074505806 Invert Z Axis: false @@ -259,7 +259,7 @@ Visualization Manager: Pitch: 0.6597966551780701 Target Frame: Value: Orbit (rviz) - Yaw: 0.7649338245391846 + Yaw: 0 Saved: ~ Window Geometry: Displays: diff --git a/convex_plane_decomposition_ros/rviz/config_demo.rviz b/convex_plane_decomposition_ros/rviz/config_demo.rviz new file mode 100644 index 00000000..39ec3a20 --- /dev/null +++ b/convex_plane_decomposition_ros/rviz/config_demo.rviz @@ -0,0 +1,281 @@ +Panels: + - Class: rviz/Displays + Help Height: 0 + Name: Displays + Property Tree Widget: + Expanded: + - /Global Options1 + - /PolygonArray1 + - /PolygonArray2 + - /GridMap1 + Splitter Ratio: 0.6114649772644043 + Tree Height: 1173 + - Class: rviz/Selection + Name: Selection + - Class: rviz/Tool Properties + Expanded: + - /2D Pose Estimate1 + - /2D Nav Goal1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz/Time + Experimental: false + Name: Time + SyncMode: 0 + SyncSource: "" +Preferences: + PromptSaveOnExit: true +Toolbars: + toolButtonStyle: 2 +Visualization Manager: + Class: "" + Displays: + - Class: rviz/Axes + Enabled: false + Length: 0.20000000298023224 + Name: Axes + Radius: 0.009999999776482582 + Reference Frame: + Value: false + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: elevation + Color Transformer: GridMapLayer + Enabled: false + Height Layer: elevation + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 255; 255; 255 + Max Intensity: 10 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: Elevation + Show Grid Lines: true + Topic: /grid_map_filter_demo/filtered_map + Unreliable: false + Use Rainbow: true + Value: false + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: normal_color + Color Transformer: ColorLayer + Enabled: false + Height Layer: elevation + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 255; 255; 255 + Max Intensity: 10 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: Normal mapping + Show Grid Lines: false + Topic: /grid_map_filter_demo/filtered_map + Unreliable: false + Use Rainbow: false + Value: false + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: edges + Color Transformer: IntensityLayer + Enabled: false + Height Layer: elevation + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 255; 0; 0 + Max Intensity: 10 + Min Color: 255; 255; 255 + Min Intensity: 0 + Name: Edges + Show Grid Lines: false + Topic: /grid_map_filter_demo/filtered_map + Unreliable: false + Use Rainbow: false + Value: false + - Alpha: 1 + Autocompute Intensity Bounds: false + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: roughness + Color Transformer: IntensityLayer + Enabled: false + Height Layer: elevation + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 255; 255; 255 + Max Intensity: 0.07999999821186066 + Min Color: 0; 0; 0 + Min Intensity: -0.019999999552965164 + Name: Roughness + Show Grid Lines: false + Topic: /grid_map_filter_demo/filtered_map + Unreliable: false + Use Rainbow: true + Value: false + - Alpha: 1 + Autocompute Intensity Bounds: false + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: traversability + Color Transformer: GridMapLayer + Enabled: false + Height Layer: elevation + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: true + Max Color: 255; 255; 255 + Max Intensity: 1.2000000476837158 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: Traversability + Show Grid Lines: false + Topic: /grid_map_filter_demo/filtered_map + Unreliable: false + Use Rainbow: true + Value: false + - Class: rviz/Marker + Enabled: false + Marker Topic: /grid_map_visualization/surface_normals + Name: Surface Normals + Namespaces: + {} + Queue Size: 100 + Value: false + - Alpha: 1 + Class: rviz/Map + Color Scheme: map + Draw Behind: false + Enabled: false + Name: Elevation + Topic: /grid_map_visualization/elevation_grid + Unreliable: false + Use Timestamp: false + Value: false + - Alpha: 1 + Class: jsk_rviz_plugin/PolygonArray + Color: 25; 255; 0 + Enabled: true + Name: PolygonArray + Topic: /convex_plane_extraction_ros/convex_polygons + Unreliable: false + Value: true + coloring: Auto + enable lighting: true + normal length: 0.10000000149011612 + only border: false + show normal: true + - Alpha: 1 + Class: jsk_rviz_plugin/PolygonArray + Color: 25; 255; 0 + Enabled: true + Name: PolygonArray + Topic: /convex_plane_extraction_ros/outer_contours + Unreliable: false + Value: true + coloring: Auto + enable lighting: true + normal length: 0.10000000149011612 + only border: true + show normal: true + - Alpha: 0.10000000149011612 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: elevation + Color Transformer: GridMapLayer + Enabled: true + Height Layer: elevation + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 255; 255; 255 + Max Intensity: 10 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: GridMap + Show Grid Lines: true + Topic: /convex_plane_extraction_ros/convex_plane_extraction + Unreliable: false + Use Rainbow: true + Value: true + Enabled: true + Global Options: + Background Color: 255; 255; 255 + Default Light: true + Fixed Frame: odom + Frame Rate: 30 + Name: root + Tools: + - Class: rviz/Interact + Hide Inactive Objects: true + - Class: rviz/MoveCamera + - Class: rviz/Select + - Class: rviz/FocusCamera + - Class: rviz/Measure + - Class: rviz/SetInitialPose + Theta std deviation: 0.2617993950843811 + Topic: /initialpose + X std deviation: 0.5 + Y std deviation: 0.5 + - Class: rviz/SetGoal + Topic: /move_base_simple/goal + - Class: rviz/PublishPoint + Single click: true + Topic: /clicked_point + Value: true + Views: + Current: + Class: rviz/Orbit + Distance: 6.349719524383545 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Focal Point: + X: -1 + Y: -1 + Z: 2 + Focal Shape Fixed Size: true + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 0.7997971177101135 + Target Frame: + Value: Orbit (rviz) + Yaw: 4.123183727264404 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 1403 + Hide Left Dock: false + Hide Right Dock: true + QMainWindow State: 000000ff00000000fd00000004000000000000016a000004d7fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005e00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c0061007900730100000040000004d7000000ce00fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f0000040efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000280000040e000000ac00fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e1000001970000000300000a000000003efc0100000002fb0000000800540069006d0065010000000000000a000000025700fffffffb0000000800540069006d0065010000000000000450000000000000000000000890000004d700000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: true + Width: 2560 + X: 1360 + Y: 0 From dff75bca0436f955e53bb977fcd78d71e7c640f0 Mon Sep 17 00:00:00 2001 From: andrej1001 Date: Thu, 16 Apr 2020 10:56:51 +0200 Subject: [PATCH 036/504] Edited README. --- README.md | 67 ++++++++++++++++++++++- convex_plane_decomposition/CMakeLists.txt | 7 ++- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7da6c9a7..97810666 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,68 @@ # loco_perception # -This repo is for perceptive motion optimization problems. +## Overview +This is a C++ ROS package for extracting convex polygons from elevation maps created by elevation_mapping. + +![screenshot](convex_plane_decomposition_ros/data/entire_map_decomposed.png) + +## Installation + +### Dependencies + +#### OpenCV +Make sure you have openCV installed. +You can execute the following command to install it. +```bash +sudo apt-get install libopencv-dev +``` + +#### Eigen +```bash +sudo apt install libeigen3-dev +``` + +#### GLOG +```bash +sudo apt-get install libgoogle-glog-dev +``` + +#### CGAL +CGAL5 is required. You can download it from [here](https://github.com/CGAL/cgal/releases/tag/releases%2FCGAL-5.0.2) +and follow the instructions [here](https://doc.cgal.org/latest/Manual/installation.html#installation_idealworld). +Make sure you have the third-party libaries installed on you machine: +```bash +sudo apt-get install libgmp-dev +sudo apt-get install libgmp3-dev +sudo apt-get install libmpfr-dev +sudo apt-get install libboost-all-dev +``` + + +### ROS package dependencies + +#### JSK-visualization +For rviz-visualization the jsk-library is used. +```bash +sudo apt-get install ros-melodic-jsk-visualization +``` + +#### Grid Map +Grid map has to be located in you workspace. You can clone it using: +```bash +git clone https://github.com/ANYbotics/grid_map.git +``` + +## Usage +### Build +```bash +catkin build convex_plane_extraction +``` +### Run demo +```bash +roslaunch convex_plane_extraction_ros convex_plane_extraction_demo.launch +``` + +### Parameters +You can select input map topics, pipeline parameters etc. in the respective yaml file in ```bash +convex_plane_decomposition_ros/config/ +``` diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 3a9f58d9..76a2ab55 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -34,7 +34,8 @@ find_package(OpenCV REQUIRED CONFIG ) -find_package(glog 0.4.0 REQUIRED) +find_package(PkgConfig REQUIRED) +pkg_check_modules(glog libglog REQUIRED) ## Uncomment this if the package has a setup.py. This macro ensures ## modules and global scripts declared therein get installed @@ -138,7 +139,6 @@ catkin_package( geometry_msgs sensor_msgs cv_bridge -# DEPENDS system_lib ) ########### @@ -197,8 +197,9 @@ target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${CGAL_LIBRARIES} ${OpenCV_LIBRARIES} - ${CGAL_3RD_PARTY_LIBRARIES} glog + gmp + mpfr ) ############# From f398318eafd8bc9d3381838a0c20b7881a5ac321 Mon Sep 17 00:00:00 2001 From: Andrej Adzic Date: Thu, 16 Apr 2020 08:59:56 +0000 Subject: [PATCH 037/504] README.md edited online with Bitbucket --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 97810666..de90885e 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ git clone https://github.com/ANYbotics/grid_map.git ## Usage ### Build ```bash -catkin build convex_plane_extraction +catkin build convex_plane_extraction_ros ``` ### Run demo ```bash From 9540f303447d9050363053edea3809125086f1e9 Mon Sep 17 00:00:00 2001 From: Andrej Adzic Date: Thu, 16 Apr 2020 09:01:17 +0000 Subject: [PATCH 038/504] README.md edited online with Bitbucket --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index de90885e..31e91372 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ roslaunch convex_plane_extraction_ros convex_plane_extraction_demo.launch ``` ### Parameters -You can select input map topics, pipeline parameters etc. in the respective yaml file in ```bash +You can select input map topics, pipeline parameters etc. in the respective yaml file in +```bash convex_plane_decomposition_ros/config/ ``` From 8a2cd25eef1d6c5c73da65f7508501afc0485ddb Mon Sep 17 00:00:00 2001 From: Marko Bjelonic Date: Mon, 20 Apr 2020 13:12:57 +0200 Subject: [PATCH 039/504] Fixed Cmake regarding gmp. --- convex_plane_decomposition_ros/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index 72555cc2..3d53d3f7 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -171,6 +171,7 @@ target_link_libraries(${PROJECT_NAME} ${CGAL_3RD_PARTY_LIBRARIES} ${OpenCV_LIBRARIES} glog + gmp ) ############# @@ -232,4 +233,4 @@ install( # endif() ## Add folders to be run by python nosetests -# catkin_add_nosetests(test) \ No newline at end of file +# catkin_add_nosetests(test) From 876d5a65118a1a909320cf4894de75b35892a8f5 Mon Sep 17 00:00:00 2001 From: Marko Bjelonic Date: Mon, 20 Apr 2020 14:59:32 +0200 Subject: [PATCH 040/504] convex_plane_extraction renamed to convex_plane_decomposition. --- README.md | 8 ++++---- convex_plane_decomposition/CMakeLists.txt | 10 +++++----- .../include/convex_decomposer.hpp | 4 ++-- .../include/export_utils.hpp | 2 +- .../include/geometry_utils.hpp | 4 ++-- convex_plane_decomposition/include/pipeline.hpp | 4 ++-- convex_plane_decomposition/include/plane.hpp | 4 ++-- .../include/plane_factory.hpp | 6 +++--- convex_plane_decomposition/include/polygon.hpp | 4 ++-- .../include/polygonizer.hpp | 4 ++-- .../include/sliding_window_plane_extractor.hpp | 2 +- convex_plane_decomposition/include/types.hpp | 2 +- convex_plane_decomposition/package.xml | 4 ++-- .../src/convex_decomposer.cpp | 4 ++-- convex_plane_decomposition/src/export_utils.cpp | 2 +- .../src/geometry_utils.cpp | 2 +- convex_plane_decomposition/src/pipeline.cpp | 2 +- convex_plane_decomposition/src/plane.cpp | 2 +- .../src/plane_factory.cpp | 4 ++-- convex_plane_decomposition/src/polygon.cpp | 4 ++-- convex_plane_decomposition/src/polygonizer.cpp | 6 +++--- .../src/sliding_window_plane_extractor.cpp | 4 ++-- convex_plane_decomposition_ros/CMakeLists.txt | 14 +++++++------- ...ex_plane_decomposition_demo_parameters.yaml} | 0 ...s.hpp => convex_plane_decomposition_ros.hpp} | 2 +- .../include/grid_map_preprocessing.hpp | 2 +- .../include/pipeline_ros.hpp | 4 ++-- .../include/ros_visualizations.hpp | 2 +- .../launch/convex_plane_decomposition.launch | 8 ++++++++ .../convex_plane_decomposition_demo.launch | 17 +++++++++++++++++ .../launch/convex_plane_extraction.launch | 8 -------- .../launch/convex_plane_extraction_demo.launch | 17 ----------------- convex_plane_decomposition_ros/package.xml | 6 +++--- convex_plane_decomposition_ros/rviz/config.rviz | 6 +++--- .../rviz/config_demo.rviz | 6 +++--- ....cpp => convex_plane_decomposition_node.cpp} | 6 +++--- ...s.cpp => convex_plane_decomposition_ros.cpp} | 6 +++--- .../src/grid_map_preprocessing.cpp | 2 +- .../src/pipeline_ros.cpp | 4 ++-- .../src/ros_visualizations.cpp | 2 +- 40 files changed, 100 insertions(+), 100 deletions(-) rename convex_plane_decomposition_ros/config/{convex_plane_extraction_demo_parameters.yaml => convex_plane_decomposition_demo_parameters.yaml} (100%) rename convex_plane_decomposition_ros/include/{convex_plane_extraction_ros.hpp => convex_plane_decomposition_ros.hpp} (97%) create mode 100644 convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch create mode 100644 convex_plane_decomposition_ros/launch/convex_plane_decomposition_demo.launch delete mode 100644 convex_plane_decomposition_ros/launch/convex_plane_extraction.launch delete mode 100644 convex_plane_decomposition_ros/launch/convex_plane_extraction_demo.launch rename convex_plane_decomposition_ros/src/{convex_plane_extraction_node.cpp => convex_plane_decomposition_node.cpp} (57%) rename convex_plane_decomposition_ros/src/{convex_plane_extraction_ros.cpp => convex_plane_decomposition_ros.cpp} (94%) diff --git a/README.md b/README.md index 31e91372..18def001 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# loco_perception # +# Convex Terrain Representation # ## Overview This is a C++ ROS package for extracting convex polygons from elevation maps created by elevation_mapping. @@ -55,15 +55,15 @@ git clone https://github.com/ANYbotics/grid_map.git ## Usage ### Build ```bash -catkin build convex_plane_extraction_ros +catkin build convex_plane_decomposition_ros ``` ### Run demo ```bash -roslaunch convex_plane_extraction_ros convex_plane_extraction_demo.launch +roslaunch convex_plane_decomposition_ros convex_plane_decomposition_demo.launch ``` ### Parameters -You can select input map topics, pipeline parameters etc. in the respective yaml file in +You can select input map topics, pipeline parameters etc. in the respective yaml file in ```bash convex_plane_decomposition_ros/config/ ``` diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 76a2ab55..96589cdc 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.1...3.15) -project(convex_plane_extraction) +project(convex_plane_decomposition) ## Compile as C++11, supported in ROS Kinetic and newer set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}") @@ -124,7 +124,7 @@ pkg_check_modules(glog libglog REQUIRED) ## DEPENDS: system dependencies of this project that dependent projects also need catkin_package( INCLUDE_DIRS include - LIBRARIES convex_plane_extraction + LIBRARIES convex_plane_decomposition CATKIN_DEPENDS roscpp grid_map_core @@ -155,7 +155,7 @@ include_directories( ## Declare a C++ library # add_library(${PROJECT_NAME} -# src/${PROJECT_NAME}/convex_plane_extraction.cpp +# src/${PROJECT_NAME}/convex_plane_decomposition.cpp # ) ## Add cmake target dependencies of the library @@ -194,7 +194,7 @@ add_dependencies(${PROJECT_NAME} ## Specify libraries to link a library or executable target against target_link_libraries(${PROJECT_NAME} - ${catkin_LIBRARIES} + ${catkin_LIBRARIES} ${CGAL_LIBRARIES} ${OpenCV_LIBRARIES} glog @@ -255,7 +255,7 @@ install( ############# ## Add gtest based cpp test target and link libraries -# catkin_add_gtest(${PROJECT_NAME}-test test/test_convex_plane_extraction.cpp) +# catkin_add_gtest(${PROJECT_NAME}-test test/test_convex_plane_decomposition.cpp) # if(TARGET ${PROJECT_NAME}-test) # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) # endif() diff --git a/convex_plane_decomposition/include/convex_decomposer.hpp b/convex_plane_decomposition/include/convex_decomposer.hpp index a4da6a62..71391f97 100644 --- a/convex_plane_decomposition/include/convex_decomposer.hpp +++ b/convex_plane_decomposition/include/convex_decomposer.hpp @@ -3,7 +3,7 @@ #include "polygon.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { enum class ConvexDecompositionType{ kGreeneOptimalDecomposition = 1, @@ -31,6 +31,6 @@ class ConvexDecomposer { ConvexDecomposerParameters parameters_; }; -} // namespace convex_plane_extraction +} // namespace convex_plane_decomposition #endif //CONVEX_PLANE_EXTRACTION_INCLUDE_CONVEX_DECOMPOSER_HPP_ diff --git a/convex_plane_decomposition/include/export_utils.hpp b/convex_plane_decomposition/include/export_utils.hpp index ab53fb63..19b93dad 100644 --- a/convex_plane_decomposition/include/export_utils.hpp +++ b/convex_plane_decomposition/include/export_utils.hpp @@ -11,7 +11,7 @@ #include "grid_map_ros/grid_map_ros.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { bool exportPointsWithNormalsToCsv(grid_map::GridMap& map, const std::string& normals_layer_prefix, const std::string& layer_height, const std::string& path); diff --git a/convex_plane_decomposition/include/geometry_utils.hpp b/convex_plane_decomposition/include/geometry_utils.hpp index 94dc8f08..e0a9528b 100644 --- a/convex_plane_decomposition/include/geometry_utils.hpp +++ b/convex_plane_decomposition/include/geometry_utils.hpp @@ -3,7 +3,7 @@ #include "types.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { double scalarCrossProduct(const Vector2d& leftVector, const Vector2d& rightVector); @@ -27,5 +27,5 @@ bool isPointOnLeftSide(const Vector2d& line_support_vector, const Vector2d& line bool isPointOnRightSideOfLine(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); -} // namespace convex_plane_extraction +} // namespace convex_plane_decomposition #endif // CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ diff --git a/convex_plane_decomposition/include/pipeline.hpp b/convex_plane_decomposition/include/pipeline.hpp index ba3572a5..dd9559d7 100644 --- a/convex_plane_decomposition/include/pipeline.hpp +++ b/convex_plane_decomposition/include/pipeline.hpp @@ -5,7 +5,7 @@ #include "plane_factory.hpp" #include "sliding_window_plane_extractor.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { struct PipelineParameters{ sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters sliding_window_plane_extractor_parameters = @@ -42,5 +42,5 @@ class Pipeline { PlaneFactory plane_factory_; sliding_window_plane_extractor::SlidingWindowPlaneExtractor sliding_window_plane_extractor_; }; -} // namespace_convex_plane_extraction +} // namespace_convex_plane_decomposition #endif //CONVEX_PLANE_EXTRACTION__PIPELINE_HPP_ diff --git a/convex_plane_decomposition/include/plane.hpp b/convex_plane_decomposition/include/plane.hpp index 93aa7b22..8baeaf6c 100644 --- a/convex_plane_decomposition/include/plane.hpp +++ b/convex_plane_decomposition/include/plane.hpp @@ -6,7 +6,7 @@ #include "geometry_utils.hpp" #include "polygon.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { struct PlaneParameters{ @@ -53,5 +53,5 @@ namespace convex_plane_extraction { Vector3d support_vector_; }; - } // namespace convex_plane_extraction + } // namespace convex_plane_decomposition #endif // CONVEX_PLANE_EXTRACTION_SRC_PLANE_HPP_ diff --git a/convex_plane_decomposition/include/plane_factory.hpp b/convex_plane_decomposition/include/plane_factory.hpp index 4582581f..f9f9039a 100644 --- a/convex_plane_decomposition/include/plane_factory.hpp +++ b/convex_plane_decomposition/include/plane_factory.hpp @@ -8,7 +8,7 @@ #include "plane.hpp" #include "polygonizer.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { struct PlaneFactoryParameters{ PolygonizerParameters polygonizer_parameters = PolygonizerParameters(); @@ -26,7 +26,7 @@ class PlaneFactory { }; void createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, const int number_of_labels, - const std::map& plane_parameters); + const std::map& plane_parameters); void decomposePlanesInConvexPolygons(); @@ -58,5 +58,5 @@ class PlaneFactory { std::vector planes_; }; -} // namespace convex_plane_extraction +} // namespace convex_plane_decomposition #endif //CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_FACTORY_HPP_ diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/polygon.hpp index eac6246b..5bc90fed 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/polygon.hpp @@ -27,7 +27,7 @@ #include "geometry_utils.hpp" #include "types.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { using K = CGAL::Exact_predicates_inexact_constructions_kernel; using EKernel = CGAL::Exact_predicates_exact_constructions_kernel; @@ -172,5 +172,5 @@ std::string printPolygonToString(const CgalPolygon2d& polygon); void upSampleLongEdges(CgalPolygon2d* polygon); -} // namespace convex_plane_extraction +} // namespace convex_plane_decomposition #endif //CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGON_HPP_ diff --git a/convex_plane_decomposition/include/polygonizer.hpp b/convex_plane_decomposition/include/polygonizer.hpp index a13ed17b..ac514d57 100644 --- a/convex_plane_decomposition/include/polygonizer.hpp +++ b/convex_plane_decomposition/include/polygonizer.hpp @@ -16,7 +16,7 @@ #include "plane.hpp" #include "polygon.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { struct PolygonizerParameters{ double resolution = 0.02; @@ -56,6 +56,6 @@ class Polygonizer { }; -} // namespace convex_plane_extraction +} // namespace convex_plane_decomposition #endif //CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGONIZER_HPP_ diff --git a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp index 5e985def..19adf4f9 100644 --- a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp +++ b/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp @@ -79,7 +79,7 @@ namespace sliding_window_plane_extractor { cv::Mat binary_image_angle_; cv::Mat labeled_image_; int number_of_extracted_planes_; - std::map label_plane_parameters_map_; + std::map label_plane_parameters_map_; }; } // namespace sliding_window_plane_extractor #endif // CONVEX_PLANE_EXTRACTION_INCLUDE_SLIDING_WINDOW_PLANE_EXTRACTOR_HPP_ diff --git a/convex_plane_decomposition/include/types.hpp b/convex_plane_decomposition/include/types.hpp index 311ad783..cb608b3b 100644 --- a/convex_plane_decomposition/include/types.hpp +++ b/convex_plane_decomposition/include/types.hpp @@ -12,7 +12,7 @@ #include "opencv2/core/eigen.hpp" #include "opencv2/core/mat.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { typedef Eigen::VectorXd VectorXd; typedef Eigen::MatrixXd MatrixXd; diff --git a/convex_plane_decomposition/package.xml b/convex_plane_decomposition/package.xml index 9a024564..32945b22 100644 --- a/convex_plane_decomposition/package.xml +++ b/convex_plane_decomposition/package.xml @@ -1,8 +1,8 @@ - convex_plane_extraction + convex_plane_decomposition 0.0.0 - The convex_plane_extraction package + The convex_plane_decomposition package diff --git a/convex_plane_decomposition/src/convex_decomposer.cpp b/convex_plane_decomposition/src/convex_decomposer.cpp index 869b89cc..d4ae4829 100644 --- a/convex_plane_decomposition/src/convex_decomposer.cpp +++ b/convex_plane_decomposition/src/convex_decomposer.cpp @@ -1,8 +1,8 @@ #include "convex_decomposer.hpp" -using namespace convex_plane_extraction; +using namespace convex_plane_decomposition; -ConvexDecomposer::ConvexDecomposer(const convex_plane_extraction::ConvexDecomposerParameters ¶meters) +ConvexDecomposer::ConvexDecomposer(const convex_plane_decomposition::ConvexDecomposerParameters ¶meters) :parameters_(parameters){} CgalPolygon2dContainer ConvexDecomposer::performConvexDecomposition(const CgalPolygon2d& polygon) const { diff --git a/convex_plane_decomposition/src/export_utils.cpp b/convex_plane_decomposition/src/export_utils.cpp index fb24c046..b6010baa 100644 --- a/convex_plane_decomposition/src/export_utils.cpp +++ b/convex_plane_decomposition/src/export_utils.cpp @@ -1,7 +1,7 @@ #include "export_utils.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { bool exportPointsWithNormalsToCsv(grid_map::GridMap& map, const std::string& normals_layer_prefix, const std::string& layer_height, const std::string& path) { diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp index a1d97ccf..34b98aeb 100644 --- a/convex_plane_decomposition/src/geometry_utils.cpp +++ b/convex_plane_decomposition/src/geometry_utils.cpp @@ -1,7 +1,7 @@ #include #include "geometry_utils.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { double scalarCrossProduct(const Vector2d &leftVector, const Vector2d &rightVector) { return leftVector.y() * rightVector.x() - leftVector.x() * rightVector.y(); diff --git a/convex_plane_decomposition/src/pipeline.cpp b/convex_plane_decomposition/src/pipeline.cpp index 131e72bf..89d89ac6 100644 --- a/convex_plane_decomposition/src/pipeline.cpp +++ b/convex_plane_decomposition/src/pipeline.cpp @@ -1,6 +1,6 @@ #include "pipeline.hpp" -using namespace convex_plane_extraction; +using namespace convex_plane_decomposition; Pipeline::Pipeline(const PipelineParameters& pipeline_parameters, const GridMapParameters& grid_map_parameters) : pipeline_parameters_(pipeline_parameters), diff --git a/convex_plane_decomposition/src/plane.cpp b/convex_plane_decomposition/src/plane.cpp index 6ae4908d..a474e93d 100644 --- a/convex_plane_decomposition/src/plane.cpp +++ b/convex_plane_decomposition/src/plane.cpp @@ -1,6 +1,6 @@ #include "plane.hpp" -namespace convex_plane_extraction{ +namespace convex_plane_decomposition{ bool Plane::setNormalAndSupportVector(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector){ normal_vector_ = normal_vector; diff --git a/convex_plane_decomposition/src/plane_factory.cpp b/convex_plane_decomposition/src/plane_factory.cpp index 1e18d838..62b0bc0d 100644 --- a/convex_plane_decomposition/src/plane_factory.cpp +++ b/convex_plane_decomposition/src/plane_factory.cpp @@ -1,6 +1,6 @@ #include "plane_factory.hpp" -using namespace convex_plane_extraction; +using namespace convex_plane_decomposition; void PlaneFactory::computeMapTransformation(){ Eigen::Vector2i map_size = map_.getSize(); @@ -14,7 +14,7 @@ void PlaneFactory::computeMapTransformation(){ } void PlaneFactory::createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, const int number_of_labels, - const std::map& plane_parameters){ + const std::map& plane_parameters){ CHECK_GT(number_of_labels, 0); Polygonizer polygonizer(parameters_.polygonizer_parameters); for (int label = 1; label < number_of_labels; ++label){ diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 786bd332..5834d296 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -1,6 +1,6 @@ #include "polygon.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { bool doPolygonAndSegmentIntersect(const CgalPolygon2d& polygon, const CgalSegment2d& segment, bool print_flag){ for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it){ @@ -534,4 +534,4 @@ namespace convex_plane_extraction { return false; } - } // namespace convex_plane_extraction + } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/src/polygonizer.cpp b/convex_plane_decomposition/src/polygonizer.cpp index 9b0d8f40..de1c220a 100644 --- a/convex_plane_decomposition/src/polygonizer.cpp +++ b/convex_plane_decomposition/src/polygonizer.cpp @@ -1,6 +1,6 @@ #include "polygonizer.hpp" -using namespace convex_plane_extraction; +using namespace convex_plane_decomposition; PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& binary_image) const{ PolygonWithHoles plane_polygons; @@ -23,7 +23,7 @@ PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& bina << "Removing parental polygon since too few vertices!"; continue; } - CgalPolygon2d polygon = convex_plane_extraction::createCgalPolygonFromOpenCvPoints( + CgalPolygon2d polygon = convex_plane_decomposition::createCgalPolygonFromOpenCvPoints( contour.begin(), contour.end(), parameters_.resolution / static_cast(parameters_.upsampling_factor)); CHECK(polygon.is_simple()) << "Contour extraction from binary image caused intersection!"; @@ -57,7 +57,7 @@ PolygonWithHoles Polygonizer::extractContoursFromBinaryImage(cv::Mat& binary_ima for (auto& contour : contours) { ++hierachy_it; CHECK_GE(contour.size(), 2); - CgalPolygon2d polygon = convex_plane_extraction::createCgalPolygonFromOpenCvPoints( + CgalPolygon2d polygon = convex_plane_decomposition::createCgalPolygonFromOpenCvPoints( contour.begin(), contour.end(), 1); constexpr int kParentFlagIndex = 3; if (hierarchy[hierachy_it - 1][kParentFlagIndex] < 0) { diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index e1f3227e..cdc42568 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -245,7 +245,7 @@ namespace sliding_window_plane_extractor{ } support_vector /= static_cast(plane_point_indices.size()); normal_vector /= static_cast(plane_point_indices.size()); - const convex_plane_extraction::PlaneParameters temp_plane_parameters(normal_vector, support_vector); + const convex_plane_decomposition::PlaneParameters temp_plane_parameters(normal_vector, support_vector); if (label_counter == 0) { label_plane_parameters_map_.emplace(label, temp_plane_parameters); } else { @@ -259,7 +259,7 @@ namespace sliding_window_plane_extractor{ } } if (!refinement_performed){ - const convex_plane_extraction::PlaneParameters temp_plane_parameters(normal_vector, support_vector); + const convex_plane_decomposition::PlaneParameters temp_plane_parameters(normal_vector, support_vector); label_plane_parameters_map_.emplace(label, temp_plane_parameters); } VLOG(1) << "Added plane!"; diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index 3d53d3f7..fcabaec2 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.1...3.15) -project(convex_plane_extraction_ros) +project(convex_plane_decomposition_ros) ## Compile as C++11, supported in ROS Kinetic and newer set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}") @@ -21,7 +21,7 @@ find_package(catkin REQUIRED COMPONENTS geometry_msgs sensor_msgs cv_bridge - convex_plane_extraction + convex_plane_decomposition ) ## System dependencies are found with CMake's conventions @@ -118,7 +118,7 @@ find_package(glog 0.4.0 REQUIRED) ## DEPENDS: system dependencies of this project that dependent projects also need catkin_package( INCLUDE_DIRS include - # LIBRARIES convex_plane_extraction + # LIBRARIES convex_plane_decomposition CATKIN_DEPENDS # DEPENDS system_lib ) @@ -136,7 +136,7 @@ include_directories( ## Declare a C++ library # add_library(${PROJECT_NAME} -# src/${PROJECT_NAME}/convex_plane_extraction.cpp +# src/${PROJECT_NAME}/convex_plane_decomposition.cpp # ) ## Add cmake target dependencies of the library @@ -148,8 +148,8 @@ include_directories( ## With catkin_make all packages are built within a single CMake context ## The recommended prefix ensures that target names across packages don't collide add_executable(${PROJECT_NAME} - src/convex_plane_extraction_node.cpp - src/convex_plane_extraction_ros.cpp + src/convex_plane_decomposition_node.cpp + src/convex_plane_decomposition_ros.cpp src/grid_map_preprocessing.cpp src/pipeline_ros.cpp src/ros_visualizations.cpp) @@ -227,7 +227,7 @@ install( ############# ## Add gtest based cpp test target and link libraries -# catkin_add_gtest(${PROJECT_NAME}-test test/test_convex_plane_extraction.cpp) +# catkin_add_gtest(${PROJECT_NAME}-test test/test_convex_plane_decomposition.cpp) # if(TARGET ${PROJECT_NAME}-test) # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) # endif() diff --git a/convex_plane_decomposition_ros/config/convex_plane_extraction_demo_parameters.yaml b/convex_plane_decomposition_ros/config/convex_plane_decomposition_demo_parameters.yaml similarity index 100% rename from convex_plane_decomposition_ros/config/convex_plane_extraction_demo_parameters.yaml rename to convex_plane_decomposition_ros/config/convex_plane_decomposition_demo_parameters.yaml diff --git a/convex_plane_decomposition_ros/include/convex_plane_extraction_ros.hpp b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros.hpp similarity index 97% rename from convex_plane_decomposition_ros/include/convex_plane_extraction_ros.hpp rename to convex_plane_decomposition_ros/include/convex_plane_decomposition_ros.hpp index 40c5fec4..bcc06ad2 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_extraction_ros.hpp +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros.hpp @@ -13,7 +13,7 @@ #include "pipeline_ros.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { /*! * Applies a chain of grid map filters to a topic and diff --git a/convex_plane_decomposition_ros/include/grid_map_preprocessing.hpp b/convex_plane_decomposition_ros/include/grid_map_preprocessing.hpp index ad2a3979..101f76c8 100644 --- a/convex_plane_decomposition_ros/include/grid_map_preprocessing.hpp +++ b/convex_plane_decomposition_ros/include/grid_map_preprocessing.hpp @@ -9,7 +9,7 @@ #include -namespace convex_plane_extraction{ +namespace convex_plane_decomposition{ using namespace grid_map; void applyMedianFilter(Eigen::MatrixXf& elevation_map, int kernel_size); diff --git a/convex_plane_decomposition_ros/include/pipeline_ros.hpp b/convex_plane_decomposition_ros/include/pipeline_ros.hpp index 8ba2ec8c..7c7e0f77 100644 --- a/convex_plane_decomposition_ros/include/pipeline_ros.hpp +++ b/convex_plane_decomposition_ros/include/pipeline_ros.hpp @@ -10,7 +10,7 @@ #include "pipeline.hpp" #include "ros_visualizations.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { GridMapParameters loadGridMapParameters(ros::NodeHandle& nodeHandle, grid_map::GridMap& map); @@ -32,5 +32,5 @@ class PipelineROS { Pipeline pipeline_; }; -} // namespace convex_plane_extraction +} // namespace convex_plane_decomposition #endif //CONVEX_PLANE_EXTRACTION_ROS__PIPELINE_ROS_HPP_ diff --git a/convex_plane_decomposition_ros/include/ros_visualizations.hpp b/convex_plane_decomposition_ros/include/ros_visualizations.hpp index 8499d4d9..ac88afa6 100644 --- a/convex_plane_decomposition_ros/include/ros_visualizations.hpp +++ b/convex_plane_decomposition_ros/include/ros_visualizations.hpp @@ -11,7 +11,7 @@ #include "plane.hpp" -namespace convex_plane_extraction{ +namespace convex_plane_decomposition{ jsk_recognition_msgs::PolygonArray convertToRosPolygons(const Polygon3dVectorContainer &input_polygons); diff --git a/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch b/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch new file mode 100644 index 00000000..5c72ea36 --- /dev/null +++ b/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/convex_plane_decomposition_ros/launch/convex_plane_decomposition_demo.launch b/convex_plane_decomposition_ros/launch/convex_plane_decomposition_demo.launch new file mode 100644 index 00000000..c8ec1644 --- /dev/null +++ b/convex_plane_decomposition_ros/launch/convex_plane_decomposition_demo.launch @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/convex_plane_decomposition_ros/launch/convex_plane_extraction.launch b/convex_plane_decomposition_ros/launch/convex_plane_extraction.launch deleted file mode 100644 index 5eee1575..00000000 --- a/convex_plane_decomposition_ros/launch/convex_plane_extraction.launch +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/convex_plane_decomposition_ros/launch/convex_plane_extraction_demo.launch b/convex_plane_decomposition_ros/launch/convex_plane_extraction_demo.launch deleted file mode 100644 index 95cc115d..00000000 --- a/convex_plane_decomposition_ros/launch/convex_plane_extraction_demo.launch +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/convex_plane_decomposition_ros/package.xml b/convex_plane_decomposition_ros/package.xml index cf3c6112..97e0d3ef 100644 --- a/convex_plane_decomposition_ros/package.xml +++ b/convex_plane_decomposition_ros/package.xml @@ -1,8 +1,8 @@ - convex_plane_extraction_ros + convex_plane_decomposition_ros 0.0.0 - The convex_plane_extraction_ros package + The convex_plane_decomposition_ros package @@ -30,7 +30,7 @@ geometry_msgs sensor_msgs cv_bridge - convex_plane_extraction + convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/rviz/config.rviz b/convex_plane_decomposition_ros/rviz/config.rviz index 3ee6f810..febf095e 100644 --- a/convex_plane_decomposition_ros/rviz/config.rviz +++ b/convex_plane_decomposition_ros/rviz/config.rviz @@ -171,7 +171,7 @@ Visualization Manager: Color: 25; 255; 0 Enabled: true Name: PolygonArray - Topic: /convex_plane_extraction_ros/convex_polygons + Topic: /convex_plane_decomposition_ros/convex_polygons Unreliable: false Value: true coloring: Auto @@ -184,7 +184,7 @@ Visualization Manager: Color: 25; 255; 0 Enabled: true Name: PolygonArray - Topic: /convex_plane_extraction_ros/outer_contours + Topic: /convex_plane_decomposition_ros/outer_contours Unreliable: false Value: true coloring: Auto @@ -209,7 +209,7 @@ Visualization Manager: Min Intensity: 0 Name: GridMap Show Grid Lines: true - Topic: /convex_plane_extraction_ros/convex_plane_extraction + Topic: /convex_plane_decomposition_ros/convex_plane_decomposition Unreliable: false Use Rainbow: true Value: true diff --git a/convex_plane_decomposition_ros/rviz/config_demo.rviz b/convex_plane_decomposition_ros/rviz/config_demo.rviz index 39ec3a20..42dc80c8 100644 --- a/convex_plane_decomposition_ros/rviz/config_demo.rviz +++ b/convex_plane_decomposition_ros/rviz/config_demo.rviz @@ -171,7 +171,7 @@ Visualization Manager: Color: 25; 255; 0 Enabled: true Name: PolygonArray - Topic: /convex_plane_extraction_ros/convex_polygons + Topic: /convex_plane_decomposition_ros/convex_polygons Unreliable: false Value: true coloring: Auto @@ -184,7 +184,7 @@ Visualization Manager: Color: 25; 255; 0 Enabled: true Name: PolygonArray - Topic: /convex_plane_extraction_ros/outer_contours + Topic: /convex_plane_decomposition_ros/outer_contours Unreliable: false Value: true coloring: Auto @@ -209,7 +209,7 @@ Visualization Manager: Min Intensity: 0 Name: GridMap Show Grid Lines: true - Topic: /convex_plane_extraction_ros/convex_plane_extraction + Topic: /convex_plane_decomposition_ros/convex_plane_decomposition Unreliable: false Use Rainbow: true Value: true diff --git a/convex_plane_decomposition_ros/src/convex_plane_extraction_node.cpp b/convex_plane_decomposition_ros/src/convex_plane_decomposition_node.cpp similarity index 57% rename from convex_plane_decomposition_ros/src/convex_plane_extraction_node.cpp rename to convex_plane_decomposition_ros/src/convex_plane_decomposition_node.cpp index 2b2e0b2a..3b4d5841 100644 --- a/convex_plane_decomposition_ros/src/convex_plane_extraction_node.cpp +++ b/convex_plane_decomposition_ros/src/convex_plane_decomposition_node.cpp @@ -1,4 +1,4 @@ -#include "convex_plane_extraction_ros.hpp" +#include "convex_plane_decomposition_ros.hpp" #include #include @@ -9,10 +9,10 @@ int main(int argc, char** argv) FLAGS_colorlogtostderr = 1; FLAGS_v = 1; google::InitGoogleLogging(argv[0]); - ros::init(argc, argv, "convex_plane_extraction_ros"); + ros::init(argc, argv, "convex_plane_decomposition_ros"); ros::NodeHandle nodeHandle("~"); bool success; - convex_plane_extraction::ConvexPlaneExtractionROS convex_plane_extraction_ros(nodeHandle, success); + convex_plane_decomposition::ConvexPlaneExtractionROS convex_plane_decomposition_ros(nodeHandle, success); if (success) ros::spin(); return 0; } diff --git a/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp b/convex_plane_decomposition_ros/src/convex_plane_decomposition_ros.cpp similarity index 94% rename from convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp rename to convex_plane_decomposition_ros/src/convex_plane_decomposition_ros.cpp index 8b0002bc..2e58295e 100644 --- a/convex_plane_decomposition_ros/src/convex_plane_extraction_ros.cpp +++ b/convex_plane_decomposition_ros/src/convex_plane_decomposition_ros.cpp @@ -1,10 +1,10 @@ #include -#include "convex_plane_extraction_ros.hpp" +#include "convex_plane_decomposition_ros.hpp" using namespace grid_map; -namespace convex_plane_extraction { +namespace convex_plane_decomposition { ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle, bool& success) : nodeHandle_(nodeHandle) { @@ -14,7 +14,7 @@ ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle, } subscriber_ = nodeHandle_.subscribe(inputTopic_, 1, &ConvexPlaneExtractionROS::callback, this); - grid_map_publisher_ = nodeHandle_.advertise("convex_plane_extraction", 1, true); + grid_map_publisher_ = nodeHandle_.advertise("convex_plane_decomposition", 1, true); convex_polygon_publisher_ = nodeHandle_.advertise("convex_polygons", 1); outer_contours_publisher_ = nodeHandle_.advertise("outer_contours", 1); success = true; diff --git a/convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp b/convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp index dd57bc9f..223c6e95 100644 --- a/convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp +++ b/convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp @@ -1,7 +1,7 @@ #include "grid_map_preprocessing.hpp" -namespace convex_plane_extraction{ +namespace convex_plane_decomposition{ void applyMedianFilter(Eigen::MatrixXf& elevation_map, int kernel_size) { cv::Mat elevation_image; diff --git a/convex_plane_decomposition_ros/src/pipeline_ros.cpp b/convex_plane_decomposition_ros/src/pipeline_ros.cpp index 22c4b338..9732ebdb 100644 --- a/convex_plane_decomposition_ros/src/pipeline_ros.cpp +++ b/convex_plane_decomposition_ros/src/pipeline_ros.cpp @@ -1,10 +1,10 @@ #include "pipeline_ros.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map::GridMap &map) { - const std::string kPackagePrefix = "/convex_plane_extraction_ros"; + const std::string kPackagePrefix = "/convex_plane_decomposition_ros"; // Grid map parameters. GridMapParameters grid_map_parameters = loadGridMapParameters(nodeHandle, map); diff --git a/convex_plane_decomposition_ros/src/ros_visualizations.cpp b/convex_plane_decomposition_ros/src/ros_visualizations.cpp index 765e3ea1..e29ee718 100644 --- a/convex_plane_decomposition_ros/src/ros_visualizations.cpp +++ b/convex_plane_decomposition_ros/src/ros_visualizations.cpp @@ -1,6 +1,6 @@ #include "ros_visualizations.hpp" -namespace convex_plane_extraction { +namespace convex_plane_decomposition { jsk_recognition_msgs::PolygonArray convertToRosPolygons(const Polygon3dVectorContainer &input_polygons) { jsk_recognition_msgs::PolygonArray polygon_buffer; From 5091489c05f12cd9cc56bde8ef0f5eaa4073ea75 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 20 Apr 2020 17:35:04 +0200 Subject: [PATCH 041/504] clean up CMakeLists, package.xml, and includes --- convex_plane_decomposition/CMakeLists.txt | 221 ++-------------- .../convex_decomposer.hpp | 0 .../export_utils.hpp | 7 +- .../geometry_utils.hpp | 0 .../pipeline.hpp | 0 .../plane.hpp | 0 .../plane_factory.hpp | 0 .../polygon.hpp | 3 +- .../polygonizer.hpp | 0 .../ransac_plane_extractor.hpp | 4 +- .../sliding_window_plane_extractor.hpp | 4 +- .../types.hpp | 4 +- convex_plane_decomposition/package.xml | 26 -- .../src/convex_decomposer.cpp | 2 +- .../src/export_utils.cpp | 5 +- .../src/geometry_utils.cpp | 3 +- convex_plane_decomposition/src/pipeline.cpp | 2 +- convex_plane_decomposition/src/plane.cpp | 2 +- .../src/plane_factory.cpp | 2 +- convex_plane_decomposition/src/polygon.cpp | 2 +- .../src/polygonizer.cpp | 2 +- .../src/ransac_plane_extractor.cpp | 2 +- .../src/sliding_window_plane_extractor.cpp | 5 +- convex_plane_decomposition_ros/CMakeLists.txt | 247 +++--------------- .../convex_plane_decomposition_ros.hpp | 0 .../grid_map_preprocessing.hpp | 7 +- .../pipeline_ros.hpp | 2 +- .../ros_visualizations.hpp | 13 +- convex_plane_decomposition_ros/package.xml | 17 +- .../src/convex_plane_decomposition_node.cpp | 3 +- .../src/convex_plane_decomposition_ros.cpp | 4 +- .../src/grid_map_preprocessing.cpp | 5 +- .../src/pipeline_ros.cpp | 2 +- .../src/ros_visualizations.cpp | 2 +- 34 files changed, 118 insertions(+), 480 deletions(-) rename convex_plane_decomposition/include/{ => convex_plane_decomposition}/convex_decomposer.hpp (100%) rename convex_plane_decomposition/include/{ => convex_plane_decomposition}/export_utils.hpp (82%) rename convex_plane_decomposition/include/{ => convex_plane_decomposition}/geometry_utils.hpp (100%) rename convex_plane_decomposition/include/{ => convex_plane_decomposition}/pipeline.hpp (100%) rename convex_plane_decomposition/include/{ => convex_plane_decomposition}/plane.hpp (100%) rename convex_plane_decomposition/include/{ => convex_plane_decomposition}/plane_factory.hpp (100%) rename convex_plane_decomposition/include/{ => convex_plane_decomposition}/polygon.hpp (99%) rename convex_plane_decomposition/include/{ => convex_plane_decomposition}/polygonizer.hpp (100%) rename convex_plane_decomposition/include/{ => convex_plane_decomposition}/ransac_plane_extractor.hpp (98%) rename convex_plane_decomposition/include/{ => convex_plane_decomposition}/sliding_window_plane_extractor.hpp (97%) rename convex_plane_decomposition/include/{ => convex_plane_decomposition}/types.hpp (94%) rename convex_plane_decomposition_ros/include/{ => convex_plane_decomposition_ros}/convex_plane_decomposition_ros.hpp (100%) rename convex_plane_decomposition_ros/include/{ => convex_plane_decomposition_ros}/grid_map_preprocessing.hpp (73%) rename convex_plane_decomposition_ros/include/{ => convex_plane_decomposition_ros}/pipeline_ros.hpp (95%) rename convex_plane_decomposition_ros/include/{ => convex_plane_decomposition_ros}/ros_visualizations.hpp (63%) diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 96589cdc..ac696a76 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -1,171 +1,55 @@ cmake_minimum_required(VERSION 3.1...3.15) project(convex_plane_decomposition) -## Compile as C++11, supported in ROS Kinetic and newer -set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}") +# Catkin dependencies +set(CATKIN_PACKAGE_DEPENDENCIES + grid_map_core +) -## Find catkin macros and libraries -## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) -## is used, also find other catkin packages find_package(catkin REQUIRED COMPONENTS - roscpp - grid_map_core - grid_map_ros - grid_map_cv - grid_map_filters - grid_map_loader - grid_map_msgs - grid_map_octomap - grid_map_rviz_plugin - grid_map_visualization - geometry_msgs - sensor_msgs - cv_bridge + ${CATKIN_PACKAGE_DEPENDENCIES} ) -## System dependencies are found with CMake's conventions +# CGAL find_package(CGAL QUIET) +find_package(GMP REQUIRED) +find_package(MPFR REQUIRED) -add_definitions(-DCGAL_HAS_NO_THREADS) - +# OpenCv find_package(OpenCV REQUIRED COMPONENTS - opencv_highgui + opencv_highgui CONFIG ) +# glog find_package(PkgConfig REQUIRED) pkg_check_modules(glog libglog REQUIRED) -## Uncomment this if the package has a setup.py. This macro ensures -## modules and global scripts declared therein get installed -## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html -# catkin_python_setup() - -################################################ -## Declare ROS messages, services and actions ## -################################################ - -## To declare and build messages, services or actions from within this -## package, follow these steps: -## * Let MSG_DEP_SET be the set of packages whose message types you use in -## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). -## * In the file package.xml: -## * add a build_depend tag for "message_generation" -## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET -## * If MSG_DEP_SET isn't empty the following dependency has been pulled in -## but can be declared for certainty nonetheless: -## * add a exec_depend tag for "message_runtime" -## * In this file (CMakeLists.txt): -## * add "message_generation" and every package in MSG_DEP_SET to -## find_package(catkin REQUIRED COMPONENTS ...) -## * add "message_runtime" and every package in MSG_DEP_SET to -## catkin_package(CATKIN_DEPENDS ...) -## * uncomment the add_*_files sections below as needed -## and list every .msg/.srv/.action file to be processed -## * uncomment the generate_messages entry below -## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) - -## Generate messages in the 'msg' folder -# add_message_files( -# FILES -# Message1.msg -# Message2.msg -# ) - -## Generate services in the 'srv' folder -# add_service_files( -# FILES -# Service1.srv -# Service2.srv -# ) - -## Generate actions in the 'action' folder -# add_action_files( -# FILES -# Action1.action -# Action2.action -# ) - -## Generate added messages and services with any dependencies listed here -# generate_messages( -# DEPENDENCIES -# std_msgs # Or other packages containing msgs -# ) - -################################################ -## Declare ROS dynamic reconfigure parameters ## -################################################ - -## To declare and build dynamic reconfigure parameters within this -## package, follow these steps: -## * In the file package.xml: -## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" -## * In this file (CMakeLists.txt): -## * add "dynamic_reconfigure" to -## find_package(catkin REQUIRED COMPONENTS ...) -## * uncomment the "generate_dynamic_reconfigure_options" section below -## and list every .cfg file to be processed - -## Generate dynamic reconfigure parameters in the 'cfg' folder -# generate_dynamic_reconfigure_options( -# cfg/DynReconf1.cfg -# cfg/DynReconf2.cfg -# ) +# Cpp standard version +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) ################################### ## catkin specific configuration ## ################################### -## The catkin_package macro generates cmake config files for your package -## Declare things to be passed to dependent projects -## INCLUDE_DIRS: uncomment this if your package contains header files -## LIBRARIES: libraries you create in this project that dependent projects also need -## CATKIN_DEPENDS: catkin_packages dependent projects also need -## DEPENDS: system dependencies of this project that dependent projects also need catkin_package( INCLUDE_DIRS include - LIBRARIES convex_plane_decomposition - CATKIN_DEPENDS - roscpp - grid_map_core - grid_map_ros - grid_map_cv - grid_map_filters - grid_map_loader - grid_map_msgs - grid_map_octomap - grid_map_rviz_plugin - grid_map_visualization - geometry_msgs - sensor_msgs - cv_bridge + LIBRARIES ${PROJECT_NAME} + CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} + DEPENDS OpenCV CGAL GMP MPFR glog ) ########### ## Build ## ########### -## Specify additional locations of header files -## Your package locations should be listed before other locations include_directories( include ${catkin_INCLUDE_DIRS} ${EIGEN3_INCLUDE_DIR} ) -## Declare a C++ library -# add_library(${PROJECT_NAME} -# src/${PROJECT_NAME}/convex_plane_decomposition.cpp -# ) - -## Add cmake target dependencies of the library -## as an example, code may need to be generated before libraries -## either from message generation or dynamic reconfigure -# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Declare a C++ executable -## With catkin_make all packages are built within a single CMake context -## The recommended prefix ensures that target names across packages don't collide add_library(${PROJECT_NAME} src/ransac_plane_extractor.cpp src/sliding_window_plane_extractor.cpp @@ -176,23 +60,11 @@ add_library(${PROJECT_NAME} src/plane_factory.cpp src/polygonizer.cpp src/convex_decomposer.cpp - src/pipeline.cpp) - + src/pipeline.cpp +) add_dependencies(${PROJECT_NAME} - ${catkin_EXPORTED_TARGETS} - ) - -## Rename C++ executable without prefix -## The above recommended prefix causes long target names, the following renames the -## target back to the shorter version for ease of user use -## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" -# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") - -## Add cmake target dependencies of the executable -## same as for the library above -# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Specify libraries to link a library or executable target against + ${catkin_EXPORTED_TARGETS} +) target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${CGAL_LIBRARIES} @@ -201,64 +73,23 @@ target_link_libraries(${PROJECT_NAME} gmp mpfr ) +target_compile_options(${PROJECT_NAME} + PUBLIC -DCGAL_HAS_NO_THREADS +) ############# ## Install ## ############# -# all install targets should use catkin DESTINATION variables -# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html - -## Mark executable scripts (Python etc.) for installation -## in contrast to setup.py, you can choose the destination -# install(PROGRAMS -# scripts/my_python_script -# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark executables for installation -## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html -# install(TARGETS ${PROJECT_NAME}_node -# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) install( TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) - -## Mark libraries for installation -## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html -# install(TARGETS ${PROJECT_NAME} -# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} -# ) - -## Mark cpp header files for installation -# install(DIRECTORY include/${PROJECT_NAME}/ -# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} -# FILES_MATCHING PATTERN "*.h" -# PATTERN ".svn" EXCLUDE -# ) - -## Mark other files for installation (e.g. launch and bag files, etc.) -# install(FILES -# # myfile1 -# # myfile2 -# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} -# ) +install(DIRECTORY include/${PROJECT_NAME}/ + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}) ############# ## Testing ## ############# - -## Add gtest based cpp test target and link libraries -# catkin_add_gtest(${PROJECT_NAME}-test test/test_convex_plane_decomposition.cpp) -# if(TARGET ${PROJECT_NAME}-test) -# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) -# endif() - -## Add folders to be run by python nosetests -# catkin_add_nosetests(test) diff --git a/convex_plane_decomposition/include/convex_decomposer.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/convex_decomposer.hpp similarity index 100% rename from convex_plane_decomposition/include/convex_decomposer.hpp rename to convex_plane_decomposition/include/convex_plane_decomposition/convex_decomposer.hpp diff --git a/convex_plane_decomposition/include/export_utils.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/export_utils.hpp similarity index 82% rename from convex_plane_decomposition/include/export_utils.hpp rename to convex_plane_decomposition/include/convex_plane_decomposition/export_utils.hpp index 19b93dad..a029f37a 100644 --- a/convex_plane_decomposition/include/export_utils.hpp +++ b/convex_plane_decomposition/include/convex_plane_decomposition/export_utils.hpp @@ -1,15 +1,12 @@ #ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_EXPORT_UTILS_HPP_ #define CONVEX_PLANE_EXTRACTION_INCLUDE_EXPORT_UTILS_HPP_ -#include -#include -#include +#include #include #include -#include "grid_map_ros/grid_map_ros.hpp" - +#include namespace convex_plane_decomposition { diff --git a/convex_plane_decomposition/include/geometry_utils.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/geometry_utils.hpp similarity index 100% rename from convex_plane_decomposition/include/geometry_utils.hpp rename to convex_plane_decomposition/include/convex_plane_decomposition/geometry_utils.hpp diff --git a/convex_plane_decomposition/include/pipeline.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/pipeline.hpp similarity index 100% rename from convex_plane_decomposition/include/pipeline.hpp rename to convex_plane_decomposition/include/convex_plane_decomposition/pipeline.hpp diff --git a/convex_plane_decomposition/include/plane.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/plane.hpp similarity index 100% rename from convex_plane_decomposition/include/plane.hpp rename to convex_plane_decomposition/include/convex_plane_decomposition/plane.hpp diff --git a/convex_plane_decomposition/include/plane_factory.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/plane_factory.hpp similarity index 100% rename from convex_plane_decomposition/include/plane_factory.hpp rename to convex_plane_decomposition/include/convex_plane_decomposition/plane_factory.hpp diff --git a/convex_plane_decomposition/include/polygon.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/polygon.hpp similarity index 99% rename from convex_plane_decomposition/include/polygon.hpp rename to convex_plane_decomposition/include/convex_plane_decomposition/polygon.hpp index 5bc90fed..2f5adbb9 100644 --- a/convex_plane_decomposition/include/polygon.hpp +++ b/convex_plane_decomposition/include/convex_plane_decomposition/polygon.hpp @@ -23,7 +23,8 @@ #include #include -#include "grid_map_core/GridMap.hpp" +#include + #include "geometry_utils.hpp" #include "types.hpp" diff --git a/convex_plane_decomposition/include/polygonizer.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/polygonizer.hpp similarity index 100% rename from convex_plane_decomposition/include/polygonizer.hpp rename to convex_plane_decomposition/include/convex_plane_decomposition/polygonizer.hpp diff --git a/convex_plane_decomposition/include/ransac_plane_extractor.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/ransac_plane_extractor.hpp similarity index 98% rename from convex_plane_decomposition/include/ransac_plane_extractor.hpp rename to convex_plane_decomposition/include/convex_plane_decomposition/ransac_plane_extractor.hpp index 00ed69a9..6fa88a66 100644 --- a/convex_plane_decomposition/include/ransac_plane_extractor.hpp +++ b/convex_plane_decomposition/include/convex_plane_decomposition/ransac_plane_extractor.hpp @@ -13,8 +13,8 @@ #include "CGAL/Point_with_normal_3.h" #include "CGAL/Exact_predicates_inexact_constructions_kernel.h" #include "CGAL/Shape_detection/Efficient_RANSAC.h" -#include "Eigen/Core" -#include "Eigen/Dense" +#include +#include #include diff --git a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extractor.hpp similarity index 97% rename from convex_plane_decomposition/include/sliding_window_plane_extractor.hpp rename to convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extractor.hpp index 19adf4f9..d64926f3 100644 --- a/convex_plane_decomposition/include/sliding_window_plane_extractor.hpp +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extractor.hpp @@ -11,8 +11,8 @@ #include #include -#include "grid_map_ros/grid_map_ros.hpp" -#include "grid_map_core/GridMapMath.hpp" +#include +#include #include "plane.hpp" #include "polygon.hpp" diff --git a/convex_plane_decomposition/include/types.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/types.hpp similarity index 94% rename from convex_plane_decomposition/include/types.hpp rename to convex_plane_decomposition/include/convex_plane_decomposition/types.hpp index cb608b3b..00ae1f3e 100644 --- a/convex_plane_decomposition/include/types.hpp +++ b/convex_plane_decomposition/include/convex_plane_decomposition/types.hpp @@ -9,8 +9,8 @@ #include #include -#include "opencv2/core/eigen.hpp" -#include "opencv2/core/mat.hpp" +#include +#include namespace convex_plane_decomposition { diff --git a/convex_plane_decomposition/package.xml b/convex_plane_decomposition/package.xml index 32945b22..375c4daf 100644 --- a/convex_plane_decomposition/package.xml +++ b/convex_plane_decomposition/package.xml @@ -4,37 +4,11 @@ 0.0.0 The convex_plane_decomposition package - - - andrej - - - - TODO catkin - catkin - roscpp grid_map_core - grid_map_ros - grid_map_cv - grid_map_filters - grid_map_loader - grid_map_msgs - grid_map_octomap - grid_map_rviz_plugin - grid_map_visualization - geometry_msgs - sensor_msgs - cv_bridge - - - - - - diff --git a/convex_plane_decomposition/src/convex_decomposer.cpp b/convex_plane_decomposition/src/convex_decomposer.cpp index d4ae4829..cd3dc99f 100644 --- a/convex_plane_decomposition/src/convex_decomposer.cpp +++ b/convex_plane_decomposition/src/convex_decomposer.cpp @@ -1,4 +1,4 @@ -#include "convex_decomposer.hpp" +#include "convex_plane_decomposition/convex_decomposer.hpp" using namespace convex_plane_decomposition; diff --git a/convex_plane_decomposition/src/export_utils.cpp b/convex_plane_decomposition/src/export_utils.cpp index b6010baa..fbcd181e 100644 --- a/convex_plane_decomposition/src/export_utils.cpp +++ b/convex_plane_decomposition/src/export_utils.cpp @@ -1,5 +1,8 @@ -#include "export_utils.hpp" +#include "convex_plane_decomposition/export_utils.hpp" +#include + +#include namespace convex_plane_decomposition { diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp index 34b98aeb..cfdbb065 100644 --- a/convex_plane_decomposition/src/geometry_utils.cpp +++ b/convex_plane_decomposition/src/geometry_utils.cpp @@ -1,5 +1,6 @@ +#include "convex_plane_decomposition/geometry_utils.hpp" + #include -#include "geometry_utils.hpp" namespace convex_plane_decomposition { diff --git a/convex_plane_decomposition/src/pipeline.cpp b/convex_plane_decomposition/src/pipeline.cpp index 89d89ac6..b605c50d 100644 --- a/convex_plane_decomposition/src/pipeline.cpp +++ b/convex_plane_decomposition/src/pipeline.cpp @@ -1,4 +1,4 @@ -#include "pipeline.hpp" +#include "convex_plane_decomposition/pipeline.hpp" using namespace convex_plane_decomposition; diff --git a/convex_plane_decomposition/src/plane.cpp b/convex_plane_decomposition/src/plane.cpp index a474e93d..c8b1f4b5 100644 --- a/convex_plane_decomposition/src/plane.cpp +++ b/convex_plane_decomposition/src/plane.cpp @@ -1,4 +1,4 @@ -#include "plane.hpp" +#include "convex_plane_decomposition/plane.hpp" namespace convex_plane_decomposition{ diff --git a/convex_plane_decomposition/src/plane_factory.cpp b/convex_plane_decomposition/src/plane_factory.cpp index 62b0bc0d..71102881 100644 --- a/convex_plane_decomposition/src/plane_factory.cpp +++ b/convex_plane_decomposition/src/plane_factory.cpp @@ -1,4 +1,4 @@ -#include "plane_factory.hpp" +#include "convex_plane_decomposition/plane_factory.hpp" using namespace convex_plane_decomposition; diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp index 5834d296..134a3159 100644 --- a/convex_plane_decomposition/src/polygon.cpp +++ b/convex_plane_decomposition/src/polygon.cpp @@ -1,4 +1,4 @@ -#include "polygon.hpp" +#include "convex_plane_decomposition/polygon.hpp" namespace convex_plane_decomposition { diff --git a/convex_plane_decomposition/src/polygonizer.cpp b/convex_plane_decomposition/src/polygonizer.cpp index de1c220a..41084675 100644 --- a/convex_plane_decomposition/src/polygonizer.cpp +++ b/convex_plane_decomposition/src/polygonizer.cpp @@ -1,4 +1,4 @@ -#include "polygonizer.hpp" +#include "convex_plane_decomposition/polygonizer.hpp" using namespace convex_plane_decomposition; diff --git a/convex_plane_decomposition/src/ransac_plane_extractor.cpp b/convex_plane_decomposition/src/ransac_plane_extractor.cpp index 1d6f94fd..b4266dab 100644 --- a/convex_plane_decomposition/src/ransac_plane_extractor.cpp +++ b/convex_plane_decomposition/src/ransac_plane_extractor.cpp @@ -1,4 +1,4 @@ -#include "ransac_plane_extractor.hpp" +#include "convex_plane_decomposition/ransac_plane_extractor.hpp" using namespace ransac_plane_extractor; diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp index cdc42568..f2082e0e 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp @@ -1,4 +1,7 @@ -#include "sliding_window_plane_extractor.hpp" +#include "convex_plane_decomposition/sliding_window_plane_extractor.hpp" + +#include +#include namespace sliding_window_plane_extractor{ diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index fcabaec2..0c29b611 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -1,236 +1,75 @@ cmake_minimum_required(VERSION 3.1...3.15) project(convex_plane_decomposition_ros) -## Compile as C++11, supported in ROS Kinetic and newer -set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}") - -## Find catkin macros and libraries -## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) -## is used, also find other catkin packages +# Catkin dependencies find_package(catkin REQUIRED COMPONENTS - roscpp - grid_map_core - grid_map_ros - grid_map_cv - grid_map_filters - grid_map_loader - grid_map_msgs - grid_map_octomap - grid_map_rviz_plugin - grid_map_visualization - geometry_msgs - sensor_msgs - cv_bridge - convex_plane_decomposition - ) - -## System dependencies are found with CMake's conventions -find_package(CGAL QUIET) - -add_definitions(-DCGAL_HAS_NO_THREADS) - -find_package(glog 0.4.0 REQUIRED) - -## Uncomment this if the package has a setup.py. This macro ensures -## modules and global scripts declared therein get installed -## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html -# catkin_python_setup() - -################################################ -## Declare ROS messages, services and actions ## -################################################ - -## To declare and build messages, services or actions from within this -## package, follow these steps: -## * Let MSG_DEP_SET be the set of packages whose message types you use in -## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). -## * In the file package.xml: -## * add a build_depend tag for "message_generation" -## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET -## * If MSG_DEP_SET isn't empty the following dependency has been pulled in -## but can be declared for certainty nonetheless: -## * add a exec_depend tag for "message_runtime" -## * In this file (CMakeLists.txt): -## * add "message_generation" and every package in MSG_DEP_SET to -## find_package(catkin REQUIRED COMPONENTS ...) -## * add "message_runtime" and every package in MSG_DEP_SET to -## catkin_package(CATKIN_DEPENDS ...) -## * uncomment the add_*_files sections below as needed -## and list every .msg/.srv/.action file to be processed -## * uncomment the generate_messages entry below -## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) - -## Generate messages in the 'msg' folder -# add_message_files( -# FILES -# Message1.msg -# Message2.msg -# ) - -## Generate services in the 'srv' folder -# add_service_files( -# FILES -# Service1.srv -# Service2.srv -# ) - -## Generate actions in the 'action' folder -# add_action_files( -# FILES -# Action1.action -# Action2.action -# ) - -## Generate added messages and services with any dependencies listed here -# generate_messages( -# DEPENDENCIES -# std_msgs # Or other packages containing msgs -# ) + roscpp + grid_map_core + grid_map_ros + grid_map_cv + grid_map_filters + grid_map_loader + grid_map_msgs + grid_map_octomap + grid_map_rviz_plugin + grid_map_visualization + geometry_msgs + sensor_msgs + cv_bridge + jsk_recognition_msgs + convex_plane_decomposition +) -################################################ -## Declare ROS dynamic reconfigure parameters ## -################################################ +# OpenCv +find_package(OpenCV REQUIRED) -## To declare and build dynamic reconfigure parameters within this -## package, follow these steps: -## * In the file package.xml: -## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" -## * In this file (CMakeLists.txt): -## * add "dynamic_reconfigure" to -## find_package(catkin REQUIRED COMPONENTS ...) -## * uncomment the "generate_dynamic_reconfigure_options" section below -## and list every .cfg file to be processed +# glog +find_package(PkgConfig REQUIRED) +pkg_check_modules(glog libglog REQUIRED) -## Generate dynamic reconfigure parameters in the 'cfg' folder -# generate_dynamic_reconfigure_options( -# cfg/DynReconf1.cfg -# cfg/DynReconf2.cfg -# ) +# Cpp standard version +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) ################################### ## catkin specific configuration ## ################################### -## The catkin_package macro generates cmake config files for your package -## Declare things to be passed to dependent projects -## INCLUDE_DIRS: uncomment this if your package contains header files -## LIBRARIES: libraries you create in this project that dependent projects also need -## CATKIN_DEPENDS: catkin_packages dependent projects also need -## DEPENDS: system dependencies of this project that dependent projects also need -catkin_package( - INCLUDE_DIRS include - # LIBRARIES convex_plane_decomposition - CATKIN_DEPENDS - # DEPENDS system_lib -) +catkin_package() ########### ## Build ## ########### -## Specify additional locations of header files -## Your package locations should be listed before other locations include_directories( - include - ${catkin_INCLUDE_DIRS} + include + ${catkin_INCLUDE_DIRS} ) -## Declare a C++ library -# add_library(${PROJECT_NAME} -# src/${PROJECT_NAME}/convex_plane_decomposition.cpp -# ) - -## Add cmake target dependencies of the library -## as an example, code may need to be generated before libraries -## either from message generation or dynamic reconfigure -# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Declare a C++ executable -## With catkin_make all packages are built within a single CMake context -## The recommended prefix ensures that target names across packages don't collide add_executable(${PROJECT_NAME} - src/convex_plane_decomposition_node.cpp - src/convex_plane_decomposition_ros.cpp - src/grid_map_preprocessing.cpp - src/pipeline_ros.cpp - src/ros_visualizations.cpp) - -## Rename C++ executable without prefix -## The above recommended prefix causes long target names, the following renames the -## target back to the shorter version for ease of user use -## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" -# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") - -## Add cmake target dependencies of the executable -## same as for the library above -# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Specify libraries to link a library or executable target against + src/convex_plane_decomposition_node.cpp + src/convex_plane_decomposition_ros.cpp + src/grid_map_preprocessing.cpp + src/pipeline_ros.cpp + src/ros_visualizations.cpp +) target_link_libraries(${PROJECT_NAME} - ${catkin_LIBRARIES} - ${CGAL_LIBRARIES} - ${CGAL_3RD_PARTY_LIBRARIES} - ${OpenCV_LIBRARIES} - glog - gmp - ) + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + glog +) ############# ## Install ## ############# -# all install targets should use catkin DESTINATION variables -# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html - -## Mark executable scripts (Python etc.) for installation -## in contrast to setup.py, you can choose the destination -# install(PROGRAMS -# scripts/my_python_script -# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) - -## Mark executables for installation -## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html -# install(TARGETS ${PROJECT_NAME}_node -# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) -install( - TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +install(TARGETS ${PROJECT_NAME} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +) +install(DIRECTORY config data launch rviz + DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} ) - -## Mark libraries for installation -## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html -# install(TARGETS ${PROJECT_NAME} -# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} -# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} -# ) - -## Mark cpp header files for installation -# install(DIRECTORY include/${PROJECT_NAME}/ -# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} -# FILES_MATCHING PATTERN "*.h" -# PATTERN ".svn" EXCLUDE -# ) - -## Mark other files for installation (e.g. launch and bag files, etc.) -# install(FILES -# # myfile1 -# # myfile2 -# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} -# ) ############# ## Testing ## ############# -## Add gtest based cpp test target and link libraries -# catkin_add_gtest(${PROJECT_NAME}-test test/test_convex_plane_decomposition.cpp) -# if(TARGET ${PROJECT_NAME}-test) -# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) -# endif() - -## Add folders to be run by python nosetests -# catkin_add_nosetests(test) diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros.hpp b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/convex_plane_decomposition_ros.hpp similarity index 100% rename from convex_plane_decomposition_ros/include/convex_plane_decomposition_ros.hpp rename to convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/convex_plane_decomposition_ros.hpp diff --git a/convex_plane_decomposition_ros/include/grid_map_preprocessing.hpp b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/grid_map_preprocessing.hpp similarity index 73% rename from convex_plane_decomposition_ros/include/grid_map_preprocessing.hpp rename to convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/grid_map_preprocessing.hpp index 101f76c8..d11cd155 100644 --- a/convex_plane_decomposition_ros/include/grid_map_preprocessing.hpp +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/grid_map_preprocessing.hpp @@ -1,11 +1,8 @@ #ifndef CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_GRID_MAP_PREPROCESSING_HPP_ #define CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_GRID_MAP_PREPROCESSING_HPP_ -#include "Eigen/Core" -#include "Eigen/Dense" -#include "opencv2/core/eigen.hpp" -#include "opencv2/core/mat.hpp" -#include "opencv2/imgproc.hpp" +#include +#include #include diff --git a/convex_plane_decomposition_ros/include/pipeline_ros.hpp b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/pipeline_ros.hpp similarity index 95% rename from convex_plane_decomposition_ros/include/pipeline_ros.hpp rename to convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/pipeline_ros.hpp index 7c7e0f77..b3bd98fc 100644 --- a/convex_plane_decomposition_ros/include/pipeline_ros.hpp +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/pipeline_ros.hpp @@ -7,7 +7,7 @@ #include #include -#include "pipeline.hpp" +#include "convex_plane_decomposition/pipeline.hpp" #include "ros_visualizations.hpp" namespace convex_plane_decomposition { diff --git a/convex_plane_decomposition_ros/include/ros_visualizations.hpp b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ros_visualizations.hpp similarity index 63% rename from convex_plane_decomposition_ros/include/ros_visualizations.hpp rename to convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ros_visualizations.hpp index ac88afa6..42c14d45 100644 --- a/convex_plane_decomposition_ros/include/ros_visualizations.hpp +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ros_visualizations.hpp @@ -1,15 +1,16 @@ #ifndef CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_ROS_VISUALIZATIONS_HPP_ #define CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_ROS_VISUALIZATIONS_HPP_ + #include -#include "Eigen/Core" -#include "Eigen/Dense" +#include +#include -#include "geometry_msgs/Point32.h" -#include "geometry_msgs/PolygonStamped.h" -#include "jsk_recognition_msgs/PolygonArray.h" +#include +#include +#include -#include "plane.hpp" +#include "convex_plane_decomposition/plane.hpp" namespace convex_plane_decomposition{ diff --git a/convex_plane_decomposition_ros/package.xml b/convex_plane_decomposition_ros/package.xml index 97e0d3ef..a1669e4d 100644 --- a/convex_plane_decomposition_ros/package.xml +++ b/convex_plane_decomposition_ros/package.xml @@ -4,18 +4,10 @@ 0.0.0 The convex_plane_decomposition_ros package - - - andrej - - - - TODO - catkin catkin roscpp grid_map_core @@ -30,12 +22,7 @@ geometry_msgs sensor_msgs cv_bridge + jsk_recognition_msgs convex_plane_decomposition - - - - - - - \ No newline at end of file + diff --git a/convex_plane_decomposition_ros/src/convex_plane_decomposition_node.cpp b/convex_plane_decomposition_ros/src/convex_plane_decomposition_node.cpp index 3b4d5841..1714111c 100644 --- a/convex_plane_decomposition_ros/src/convex_plane_decomposition_node.cpp +++ b/convex_plane_decomposition_ros/src/convex_plane_decomposition_node.cpp @@ -1,4 +1,5 @@ -#include "convex_plane_decomposition_ros.hpp" +#include "convex_plane_decomposition_ros/convex_plane_decomposition_ros.hpp" + #include #include diff --git a/convex_plane_decomposition_ros/src/convex_plane_decomposition_ros.cpp b/convex_plane_decomposition_ros/src/convex_plane_decomposition_ros.cpp index 2e58295e..4b9b20cb 100644 --- a/convex_plane_decomposition_ros/src/convex_plane_decomposition_ros.cpp +++ b/convex_plane_decomposition_ros/src/convex_plane_decomposition_ros.cpp @@ -1,6 +1,6 @@ -#include +#include "convex_plane_decomposition_ros/convex_plane_decomposition_ros.hpp" -#include "convex_plane_decomposition_ros.hpp" +#include using namespace grid_map; diff --git a/convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp b/convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp index 223c6e95..057552fd 100644 --- a/convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp +++ b/convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp @@ -1,5 +1,8 @@ +#include "convex_plane_decomposition_ros/grid_map_preprocessing.hpp" -#include "grid_map_preprocessing.hpp" +#include +#include +#include namespace convex_plane_decomposition{ diff --git a/convex_plane_decomposition_ros/src/pipeline_ros.cpp b/convex_plane_decomposition_ros/src/pipeline_ros.cpp index 9732ebdb..1d076389 100644 --- a/convex_plane_decomposition_ros/src/pipeline_ros.cpp +++ b/convex_plane_decomposition_ros/src/pipeline_ros.cpp @@ -1,4 +1,4 @@ -#include "pipeline_ros.hpp" +#include "convex_plane_decomposition_ros/pipeline_ros.hpp" namespace convex_plane_decomposition { diff --git a/convex_plane_decomposition_ros/src/ros_visualizations.cpp b/convex_plane_decomposition_ros/src/ros_visualizations.cpp index e29ee718..71a0ce09 100644 --- a/convex_plane_decomposition_ros/src/ros_visualizations.cpp +++ b/convex_plane_decomposition_ros/src/ros_visualizations.cpp @@ -1,4 +1,4 @@ -#include "ros_visualizations.hpp" +#include "convex_plane_decomposition_ros/ros_visualizations.hpp" namespace convex_plane_decomposition { From 3af54df1d739a1cea8a7ed05f76706445af0915b Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 20 Apr 2020 17:48:19 +0200 Subject: [PATCH 042/504] some formatting in CMakeLists --- convex_plane_decomposition/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index ac696a76..1868b5f0 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -37,7 +37,7 @@ catkin_package( INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS OpenCV CGAL GMP MPFR glog + DEPENDS OpenCV CGAL GMP MPFR glog ) ########### @@ -81,14 +81,14 @@ target_compile_options(${PROJECT_NAME} ## Install ## ############# -install( - TARGETS ${PROJECT_NAME} +install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) install(DIRECTORY include/${PROJECT_NAME}/ - DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}) + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} +) ############# ## Testing ## From 3dd591decccbe96d44b392260b6f598fe542a264 Mon Sep 17 00:00:00 2001 From: Marko Bjelonic Date: Mon, 20 Apr 2020 20:28:42 +0200 Subject: [PATCH 043/504] Fixed without knowing why cmake. --- convex_plane_decomposition/CMakeLists.txt | 2 +- convex_plane_decomposition_ros/CMakeLists.txt | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 1868b5f0..09742831 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -37,7 +37,7 @@ catkin_package( INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS OpenCV CGAL GMP MPFR glog + DEPENDS OpenCV CGAL GMP MPFR ) ########### diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index 0c29b611..2067b156 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -23,6 +23,9 @@ find_package(catkin REQUIRED COMPONENTS # OpenCv find_package(OpenCV REQUIRED) +# CGAL +find_package(GMP QUIET) + # glog find_package(PkgConfig REQUIRED) pkg_check_modules(glog libglog REQUIRED) @@ -56,6 +59,7 @@ target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} glog + gmp ) ############# @@ -72,4 +76,3 @@ install(DIRECTORY config data launch rviz ############# ## Testing ## ############# - From f5f433e742f58ec13fe251ee948889a6635f56c1 Mon Sep 17 00:00:00 2001 From: Marko Bjelonic Date: Tue, 21 Apr 2020 10:57:11 +0200 Subject: [PATCH 044/504] Reverted back last commit. --- convex_plane_decomposition/CMakeLists.txt | 2 +- convex_plane_decomposition_ros/CMakeLists.txt | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 09742831..1868b5f0 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -37,7 +37,7 @@ catkin_package( INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS OpenCV CGAL GMP MPFR + DEPENDS OpenCV CGAL GMP MPFR glog ) ########### diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index 2067b156..a3ba343c 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -23,9 +23,6 @@ find_package(catkin REQUIRED COMPONENTS # OpenCv find_package(OpenCV REQUIRED) -# CGAL -find_package(GMP QUIET) - # glog find_package(PkgConfig REQUIRED) pkg_check_modules(glog libglog REQUIRED) @@ -59,7 +56,6 @@ target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} glog - gmp ) ############# From d9d124f1ae9c99c00f21968d31fb925450bec777 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 24 Jun 2020 17:38:03 +0200 Subject: [PATCH 045/504] squash region growing dev --- README.md | 69 --- convex_plane_decomposition/CMakeLists.txt | 26 +- .../ConvexRegionGrowing.h | 23 + .../include/convex_plane_decomposition/Draw.h | 24 + .../GeometryUtils.h | 140 +++++ .../GridMapPreprocessing.h | 30 + .../include/convex_plane_decomposition/Nan.h | 29 + .../convex_plane_decomposition/PlanarRegion.h | 38 ++ .../convex_plane_decomposition/PolygonTypes.h | 23 + .../SegmentedPlanesMap.h | 31 + .../contour_extraction/ContourExtraction.h | 49 ++ .../ContourExtractionParameters.h | 16 + .../convex_decomposer.hpp | 36 -- .../export_utils.hpp | 17 - .../geometry_utils.hpp | 31 - .../convex_plane_decomposition/pipeline.hpp | 46 -- .../convex_plane_decomposition/plane.hpp | 57 -- .../plane_factory.hpp | 62 -- .../convex_plane_decomposition/polygon.hpp | 177 ------ .../polygonizer.hpp | 61 -- .../ransac/RansacPlaneExtractor.hpp | 47 ++ .../ransac/RansacPlaneExtractorParameters.h | 22 + .../ransac_plane_extractor.hpp | 73 --- .../SlidingWindowPlaneExtractor.h | 57 ++ .../SlidingWindowPlaneExtractorParameters.h | 38 ++ .../sliding_window_plane_extractor.hpp | 85 --- .../convex_plane_decomposition/types.hpp | 42 -- convex_plane_decomposition/package.xml | 2 + .../src/ConvexRegionGrowing.cpp | 138 +++++ convex_plane_decomposition/src/Draw.cpp | 60 ++ .../src/GridMapPreprocessing.cpp | 73 +++ .../contour_extraction/ContourExtraction.cpp | 127 +++++ .../src/convex_decomposer.cpp | 241 -------- .../src/export_utils.cpp | 24 - .../src/geometry_utils.cpp | 114 ---- convex_plane_decomposition/src/pipeline.cpp | 27 - convex_plane_decomposition/src/plane.cpp | 11 - .../src/plane_factory.cpp | 109 ---- convex_plane_decomposition/src/polygon.cpp | 537 ------------------ .../src/polygonizer.cpp | 197 ------- .../src/ransac/RansacPlaneExtractor.cpp | 23 + .../src/ransac_plane_extractor.cpp | 28 - .../SlidingWindowPlaneExtractor.cpp | 282 +++++++++ .../src/sliding_window_plane_extractor.cpp | 312 ---------- .../CMakeLists.txt | 34 ++ .../msg/BoundingBox2d.msg | 5 + .../msg/PlanarRegion.msg | 7 + .../msg/PlanarTerrain.msg | 1 + .../msg/Point2d.msg | 2 + .../msg/Polygon2d.msg | 2 + .../msg/PolygonWithHoles2d.msg | 3 + convex_plane_decomposition_msgs/package.xml | 21 + convex_plane_decomposition_ros/CMakeLists.txt | 89 ++- ...x_plane_decomposition_demo_parameters.yaml | 55 +- .../config/parameters.yaml | 55 +- .../data/elevationMap_10_277cm.png | Bin 0 -> 21378 bytes .../data/elevationMap_11_278cm.png | Bin 0 -> 21764 bytes .../data/elevationMap_8_139cm.png | Bin 0 -> 20686 bytes .../data/elevationMap_9_308cm.png | Bin 0 -> 16873 bytes convex_plane_decomposition_ros/data/holes.png | Bin 0 -> 350 bytes .../data/realStairs_125cm.png | Bin 0 -> 4211 bytes .../data/slope_1m_1m_20cm.png | Bin 0 -> 358 bytes .../data/straightStairs_1m_1m_60cm.png | Bin 0 -> 262 bytes .../data/terrain.png | Bin 0 -> 112548 bytes .../ConvexPlaneDecompositionRos.h | 57 ++ .../MessageConversion.h | 42 ++ .../ParameterLoading.h | 27 + .../RosVisualizations.h | 13 + .../convex_plane_decomposition_ros.hpp | 73 --- .../grid_map_preprocessing.hpp | 14 - .../pipeline_ros.hpp | 36 -- .../ros_visualizations.hpp | 21 - .../launch/convex_plane_decomposition.launch | 5 +- ...ane_decomposition_save_elevationmap.launch | 11 + ..._decomposition_demo.launch => demo.launch} | 22 +- .../launch/rviz.launch | 5 + convex_plane_decomposition_ros/package.xml | 1 + .../rviz/config_demo.rviz | 218 +++---- ...e.cpp => ConvexPlaneDecompositionNode.cpp} | 12 +- .../src/ConvexPlaneDecompositionRos.cpp | 116 ++++ .../src/MessageConversion.cpp | 139 +++++ .../src/ParameterLoading.cpp | 59 ++ .../src/RosVisualizations.cpp | 70 +++ .../src/SaveElevationMapAsImageNode.cpp | 74 +++ .../src/convex_plane_decomposition_ros.cpp | 67 --- .../src/grid_map_preprocessing.cpp | 17 - .../src/pipeline_ros.cpp | 175 ------ .../src/ros_visualizations.cpp | 28 - .../test/shapeGrowing.cpp | 52 ++ convex_plane_decomposition_ros/test/test.cpp | 181 ++++++ segmented_planes_terrain_model/CMakeLists.txt | 91 +++ .../SegmentedPlanesTerrainModel.h | 29 + .../SegmentedPlanesTerrainModelRos.h | 32 ++ .../launch/demo.launch | 15 + segmented_planes_terrain_model/package.xml | 19 + .../src/DemoNode.cpp | 110 ++++ .../src/SegmentedPlanesTerrainModel.cpp | 150 +++++ .../src/SegmentedPlanesTerrainModelRos.cpp | 32 ++ 98 files changed, 2908 insertions(+), 3033 deletions(-) delete mode 100644 README.md create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/Draw.h create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/Nan.h create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h delete mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/convex_decomposer.hpp delete mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/export_utils.hpp delete mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/geometry_utils.hpp delete mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/pipeline.hpp delete mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/plane.hpp delete mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/plane_factory.hpp delete mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/polygon.hpp delete mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/polygonizer.hpp create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h delete mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/ransac_plane_extractor.hpp create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h delete mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extractor.hpp delete mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/types.hpp create mode 100644 convex_plane_decomposition/src/ConvexRegionGrowing.cpp create mode 100644 convex_plane_decomposition/src/Draw.cpp create mode 100644 convex_plane_decomposition/src/GridMapPreprocessing.cpp create mode 100644 convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp delete mode 100644 convex_plane_decomposition/src/convex_decomposer.cpp delete mode 100644 convex_plane_decomposition/src/export_utils.cpp delete mode 100644 convex_plane_decomposition/src/geometry_utils.cpp delete mode 100644 convex_plane_decomposition/src/pipeline.cpp delete mode 100644 convex_plane_decomposition/src/plane.cpp delete mode 100644 convex_plane_decomposition/src/plane_factory.cpp delete mode 100644 convex_plane_decomposition/src/polygon.cpp delete mode 100644 convex_plane_decomposition/src/polygonizer.cpp create mode 100644 convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp delete mode 100644 convex_plane_decomposition/src/ransac_plane_extractor.cpp create mode 100644 convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp delete mode 100644 convex_plane_decomposition/src/sliding_window_plane_extractor.cpp create mode 100644 convex_plane_decomposition_msgs/CMakeLists.txt create mode 100644 convex_plane_decomposition_msgs/msg/BoundingBox2d.msg create mode 100644 convex_plane_decomposition_msgs/msg/PlanarRegion.msg create mode 100644 convex_plane_decomposition_msgs/msg/PlanarTerrain.msg create mode 100644 convex_plane_decomposition_msgs/msg/Point2d.msg create mode 100644 convex_plane_decomposition_msgs/msg/Polygon2d.msg create mode 100644 convex_plane_decomposition_msgs/msg/PolygonWithHoles2d.msg create mode 100644 convex_plane_decomposition_msgs/package.xml create mode 100644 convex_plane_decomposition_ros/data/elevationMap_10_277cm.png create mode 100644 convex_plane_decomposition_ros/data/elevationMap_11_278cm.png create mode 100644 convex_plane_decomposition_ros/data/elevationMap_8_139cm.png create mode 100644 convex_plane_decomposition_ros/data/elevationMap_9_308cm.png create mode 100644 convex_plane_decomposition_ros/data/holes.png create mode 100644 convex_plane_decomposition_ros/data/realStairs_125cm.png create mode 100644 convex_plane_decomposition_ros/data/slope_1m_1m_20cm.png create mode 100644 convex_plane_decomposition_ros/data/straightStairs_1m_1m_60cm.png create mode 100644 convex_plane_decomposition_ros/data/terrain.png create mode 100644 convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h create mode 100644 convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h create mode 100644 convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h create mode 100644 convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h delete mode 100644 convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/convex_plane_decomposition_ros.hpp delete mode 100644 convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/grid_map_preprocessing.hpp delete mode 100644 convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/pipeline_ros.hpp delete mode 100644 convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ros_visualizations.hpp create mode 100644 convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch rename convex_plane_decomposition_ros/launch/{convex_plane_decomposition_demo.launch => demo.launch} (51%) create mode 100644 convex_plane_decomposition_ros/launch/rviz.launch rename convex_plane_decomposition_ros/src/{convex_plane_decomposition_node.cpp => ConvexPlaneDecompositionNode.cpp} (62%) create mode 100644 convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp create mode 100644 convex_plane_decomposition_ros/src/MessageConversion.cpp create mode 100644 convex_plane_decomposition_ros/src/ParameterLoading.cpp create mode 100644 convex_plane_decomposition_ros/src/RosVisualizations.cpp create mode 100644 convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp delete mode 100644 convex_plane_decomposition_ros/src/convex_plane_decomposition_ros.cpp delete mode 100644 convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp delete mode 100644 convex_plane_decomposition_ros/src/pipeline_ros.cpp delete mode 100644 convex_plane_decomposition_ros/src/ros_visualizations.cpp create mode 100644 convex_plane_decomposition_ros/test/shapeGrowing.cpp create mode 100644 convex_plane_decomposition_ros/test/test.cpp create mode 100644 segmented_planes_terrain_model/CMakeLists.txt create mode 100644 segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h create mode 100644 segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h create mode 100644 segmented_planes_terrain_model/launch/demo.launch create mode 100644 segmented_planes_terrain_model/package.xml create mode 100644 segmented_planes_terrain_model/src/DemoNode.cpp create mode 100644 segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp create mode 100644 segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp diff --git a/README.md b/README.md deleted file mode 100644 index 18def001..00000000 --- a/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# Convex Terrain Representation # - -## Overview -This is a C++ ROS package for extracting convex polygons from elevation maps created by elevation_mapping. - -![screenshot](convex_plane_decomposition_ros/data/entire_map_decomposed.png) - -## Installation - -### Dependencies - -#### OpenCV -Make sure you have openCV installed. -You can execute the following command to install it. -```bash -sudo apt-get install libopencv-dev -``` - -#### Eigen -```bash -sudo apt install libeigen3-dev -``` - -#### GLOG -```bash -sudo apt-get install libgoogle-glog-dev -``` - -#### CGAL -CGAL5 is required. You can download it from [here](https://github.com/CGAL/cgal/releases/tag/releases%2FCGAL-5.0.2) -and follow the instructions [here](https://doc.cgal.org/latest/Manual/installation.html#installation_idealworld). -Make sure you have the third-party libaries installed on you machine: -```bash -sudo apt-get install libgmp-dev -sudo apt-get install libgmp3-dev -sudo apt-get install libmpfr-dev -sudo apt-get install libboost-all-dev -``` - - -### ROS package dependencies - -#### JSK-visualization -For rviz-visualization the jsk-library is used. -```bash -sudo apt-get install ros-melodic-jsk-visualization -``` - -#### Grid Map -Grid map has to be located in you workspace. You can clone it using: -```bash -git clone https://github.com/ANYbotics/grid_map.git -``` - -## Usage -### Build -```bash -catkin build convex_plane_decomposition_ros -``` -### Run demo -```bash -roslaunch convex_plane_decomposition_ros convex_plane_decomposition_demo.launch -``` - -### Parameters -You can select input map topics, pipeline parameters etc. in the respective yaml file in -```bash -convex_plane_decomposition_ros/config/ -``` diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 1868b5f0..10109aa6 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -4,6 +4,7 @@ project(convex_plane_decomposition) # Catkin dependencies set(CATKIN_PACKAGE_DEPENDENCIES grid_map_core + ocs2_switched_model_interface ) find_package(catkin REQUIRED COMPONENTS @@ -15,6 +16,9 @@ find_package(CGAL QUIET) find_package(GMP REQUIRED) find_package(MPFR REQUIRED) +# Boost +find_package(Boost COMPONENTS thread REQUIRED) + # OpenCv find_package(OpenCV REQUIRED COMPONENTS @@ -37,7 +41,7 @@ catkin_package( INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS OpenCV CGAL GMP MPFR glog + DEPENDS OpenCV CGAL GMP MPFR glog Boost ) ########### @@ -48,19 +52,16 @@ include_directories( include ${catkin_INCLUDE_DIRS} ${EIGEN3_INCLUDE_DIR} + ${Boost_INCLUDE_DIR} ) add_library(${PROJECT_NAME} - src/ransac_plane_extractor.cpp - src/sliding_window_plane_extractor.cpp - src/plane.cpp - src/polygon.cpp - src/geometry_utils.cpp - src/export_utils.cpp - src/plane_factory.cpp - src/polygonizer.cpp - src/convex_decomposer.cpp - src/pipeline.cpp + src/contour_extraction/ContourExtraction.cpp + src/ransac/RansacPlaneExtractor.cpp + src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp + src/GridMapPreprocessing.cpp + src/ConvexRegionGrowing.cpp + src/Draw.cpp ) add_dependencies(${PROJECT_NAME} ${catkin_EXPORTED_TARGETS} @@ -69,12 +70,13 @@ target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${CGAL_LIBRARIES} ${OpenCV_LIBRARIES} + ${Boost_LIBRARIES} glog gmp mpfr ) target_compile_options(${PROJECT_NAME} - PUBLIC -DCGAL_HAS_NO_THREADS + PUBLIC -DCGAL_HAS_THREADS ) ############# diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h b/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h new file mode 100644 index 00000000..42bf71b3 --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h @@ -0,0 +1,23 @@ +// +// Created by rgrandia on 09.06.20. +// + +#pragma once + +#include "PolygonTypes.h" + +namespace convex_plane_decomposition { + +CgalPolygon2d createRegularPolygon(const CgalPoint2d& center, double radius, int numberOfVertices); + +CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygon2d& parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor); + +CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygonWithHoles2d & parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor); + + +template +bool pointCanBeMoved(const CgalPolygon2d& growthShape, int i, const CgalPoint2d& candidatePoint, CgalCircle2d& freeSphere, + const T& parentShape); + +void updateMean(CgalPoint2d & mean, const CgalPoint2d& oldValue, const CgalPoint2d& updatedValue, int N); +} \ No newline at end of file diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h b/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h new file mode 100644 index 00000000..9bb6103c --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h @@ -0,0 +1,24 @@ +// +// Created by rgrandia on 09.06.20. +// + +#pragma once + +#include +#include +#include +#include "opencv2/imgproc/imgproc.hpp" + +#include "PolygonTypes.h" + +namespace convex_plane_decomposition { + +cv::Vec3b randomColor(); +std::vector toCv(const CgalPolygon2d& polygon); +void drawContour(cv::Mat& img, const CgalPoint2d& point, double radius = 1, const cv::Vec3b* color = nullptr); +void drawContour(cv::Mat& img, const CgalPolygon2d& polygon, const cv::Vec3b* color = nullptr); +void drawContour(cv::Mat& img, const CgalPolygonWithHoles2d& polygonWithHoles2d, const cv::Vec3b* color = nullptr); +CgalPolygon2d scaleShape(const CgalPolygon2d& polygon, double scale); +CgalPolygonWithHoles2d scaleShape(const CgalPolygonWithHoles2d& polygonWithHoles, double scale); + +} \ No newline at end of file diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h b/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h new file mode 100644 index 00000000..5ccc1749 --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h @@ -0,0 +1,140 @@ +// +// Created by rgrandia on 09.06.20. +// + +#include "PolygonTypes.h" +#include "PlanarRegion.h" + +#pragma once + +namespace convex_plane_decomposition { + +inline bool doEdgesIntersect(const CgalSegment2d& line, const CgalPolygon2d& contour) { + for (auto edgeIt = contour.edges_begin(); edgeIt != contour.edges_end(); ++edgeIt) { + if (CGAL::do_intersect(line, *edgeIt)) { + return true; + } + } + return false; +} + +inline bool doEdgesIntersect(const CgalSegment2d& line, const CgalPolygonWithHoles2d& parentShape) { + if (doEdgesIntersect(line, parentShape.outer_boundary())) { + return true; + } else { + for (const auto& hole : parentShape.holes()) { + if (doEdgesIntersect(line, hole)) { + return true; + } + } + } + return false; +} + +inline double squaredDistance(const CgalPoint2d& point, const CgalPolygon2d& polygon) { + double minDistSquared = std::numeric_limits::max(); + for (auto edgeIt = polygon.edges_begin(); edgeIt != polygon.edges_end(); ++edgeIt) { + double distSquare = CGAL::squared_distance(point, *edgeIt); + minDistSquared = std::min(distSquare, minDistSquared); + } + return minDistSquared; +} + +inline double squaredDistance(const CgalPoint2d& point, const CgalPolygonWithHoles2d& parentShape) { + double minDistSquared = squaredDistance(point, parentShape.outer_boundary()); + for (const auto& hole : parentShape.holes()) { + double distSquare = squaredDistance(point, hole); + minDistSquared = std::min(distSquare, minDistSquared); + } + return minDistSquared; +} + +inline double squaredDistance(const CgalPoint2d& point, const CgalCircle2d& circle) { + auto dx = (point.x() - circle.center().x()); + auto dy = (point.y() - circle.center().y()); + return dx * dx + dy * dy; +} + +template +double distance(const CgalPoint2d& point, const T& shape) { + double distanceSquared = squaredDistance(point, shape); + return (distanceSquared > 0.0) ? std::sqrt(distanceSquared) : 0.0; +} + +inline bool isInside(const CgalPoint2d& point, const CgalCircle2d& circle) { + return squaredDistance(point, circle) <= circle.squared_radius(); +} + +inline bool isInside(const CgalPoint2d& point, const CgalPolygon2d& polygon) { + const auto boundedSide = CGAL::bounded_side_2(polygon.begin(), polygon.end(), point); + return boundedSide == CGAL::ON_BOUNDED_SIDE || boundedSide == CGAL::ON_BOUNDARY; +} + +inline bool isInside(const CgalPoint2d& point, const CgalPolygonWithHoles2d& polygonWithHoles) { + if (isInside(point, polygonWithHoles.outer_boundary())) { + // Inside the outer contour -> return false if the point is inside any of the holes + for (const auto& hole : polygonWithHoles.holes()) { + const auto boundedSide = CGAL::bounded_side_2(hole.begin(), hole.end(), point); + if (boundedSide == CGAL::ON_BOUNDED_SIDE) { // The edge of the hole is considered part of the polygon + return false; + } + } + return true; + } else { + return false; + } +} + +inline CgalPoint2d getPointOnLine(const CgalPoint2d& start, const CgalPoint2d& end, double factor) { + return {factor * (end.x() - start.x()) + start.x(), factor * (end.y() - start.y()) + start.y()}; +} + +inline CgalPoint2d projectToClosestPoint(const CgalPoint2d& point, const CgalSegment2d& segment) { + // The segment as a vector, with the source being the origin + const Eigen::Vector2d sourceToTarget{segment.target().x() - segment.source().x(), segment.target().y() - segment.source().y()}; + const double sourceToTargetDistance = sourceToTarget.norm(); + const Eigen::Vector2d n = sourceToTarget / sourceToTargetDistance; + + // Vector from source to the query point + const Eigen::Vector2d sourceToPoint{point.x() - segment.source().x(), point.y() - segment.source().y()}; + + // Projection to the line, clamped to be between source and target points + const double coeff = std::min(std::max(0.0, n.dot(sourceToPoint)), sourceToTargetDistance); + + return {coeff * n.x() + segment.source().x(), coeff * n.y() + segment.source().y()}; +} + +inline CgalPoint2d projectToClosestPoint(const CgalPoint2d& point, const CgalPolygon2d& polygon) { + double minDistSquared = CGAL::squared_distance(point, *polygon.edges_begin()); + auto closestEdge = polygon.edges_begin(); + for (auto edgeIt = std::next(polygon.edges_begin()); edgeIt != polygon.edges_end(); ++edgeIt) { + double distSquare = CGAL::squared_distance(point, *edgeIt); + if (distSquare < minDistSquared) { + closestEdge = edgeIt; + minDistSquared = distSquare; + } + } + return projectToClosestPoint(point, *closestEdge); +} + +inline void transformInPlace(CgalPolygon2d& polygon, const std::function & f) { + for (auto& point : polygon) { + f(point); + } +} + +inline void transformInPlace(CgalPolygonWithHoles2d& polygonWithHoles, const std::function & f) { + transformInPlace(polygonWithHoles.outer_boundary(), f); + for (auto& hole: polygonWithHoles.holes()) { + transformInPlace(hole, f); + } +} + +inline void transformInPlace(BoundaryWithInset& boundaryWithInset, const std::function & f) { + transformInPlace(boundaryWithInset.boundary, f); + for (auto& inset: boundaryWithInset.insets) { + transformInPlace(inset, f); + } +} + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h new file mode 100644 index 00000000..b532bdae --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +#include + +namespace convex_plane_decomposition { + +struct PreprocessingParameters { + int kernelSize = 5; // Kernel size of the median filter + int numberOfRepeats = 1; // Number of times the image is filtered + bool increasing = false; // If the kernel size should increase each filter step. + double inpaintRadius = 0.05; // [in m] +}; + +class GridMapPreprocessing { + public: + GridMapPreprocessing(const PreprocessingParameters& parameters); + + void preprocess(grid_map::GridMap& gridMap, const std::string& layer); + + private: + void denoise(grid_map::GridMap& gridMap, const std::string& layer); + void inpaint(grid_map::GridMap& gridMap, const std::string& layer, float minValue, float maxValue); + + PreprocessingParameters parameters_; +}; + +} // namespace convex_plane_decomposition + diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/Nan.h b/convex_plane_decomposition/include/convex_plane_decomposition/Nan.h new file mode 100644 index 00000000..a2867698 --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/Nan.h @@ -0,0 +1,29 @@ +// +// Created by rgrandia on 11.06.20. +// + +#pragma once + +#include + +namespace convex_plane_decomposition { + +constexpr float nanfPatch = std::numeric_limits::max(); + +inline bool isNan(float val) { + return val == nanfPatch; +} + +inline bool isNan(double val) { + throw std::runtime_error("Should not call the custom isNan with a double"); +} + +inline void patchNans(Eigen::MatrixXf& matrix) { + matrix = matrix.unaryExpr([](float val) { return (std::isnan(val)) ? nanfPatch : val; }); +} + +inline void reapplyNans(Eigen::MatrixXf& matrix) { + matrix = matrix.unaryExpr([](float val) { return (isNan(val)) ? std::nanf("") : val; }); +} + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h b/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h new file mode 100644 index 00000000..eb7cd415 --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h @@ -0,0 +1,38 @@ +// +// Created by rgrandia on 10.06.20. +// + +#pragma once + +#include + +#include + +#include "PolygonTypes.h" + +namespace convex_plane_decomposition { + +using switched_model::TerrainPlane; + +struct BoundaryWithInset { + /// Boundary of the planar region. + CgalPolygonWithHoles2d boundary; + + /// Encodes an inward offset to the boundary. + std::vector insets; +}; + +struct PlanarRegion { + /// All 2d points are in the terrain frame + BoundaryWithInset boundaryWithInset; + + /// 2D bounding box in terrain frame containing all the boundary points + CgalBbox2d bbox2d; + + /// 3D parameters of the plane + TerrainPlane planeParameters; +}; + +using PlanarTerrain = std::vector; + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h b/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h new file mode 100644 index 00000000..82acad6e --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h @@ -0,0 +1,23 @@ +// +// Created by rgrandia on 07.06.20. +// + +#pragma once + +#include + +#include +#include +#include + +namespace convex_plane_decomposition { + +using K = CGAL::Exact_predicates_inexact_constructions_kernel; +using CgalPoint2d = K::Point_2; +using CgalCircle2d = K::Circle_2; +using CgalPolygon2d = CGAL::Polygon_2; +using CgalSegment2d = CgalPolygon2d::Segment_2; +using CgalPolygonWithHoles2d = CGAL::Polygon_with_holes_2; +using CgalBbox2d = CGAL::Bbox_2; + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h b/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h new file mode 100644 index 00000000..1c437773 --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h @@ -0,0 +1,31 @@ +// +// Created by rgrandia on 10.06.20. +// + +#pragma once + +#include + +#include "PlanarRegion.h" + +namespace convex_plane_decomposition { + +struct SegmentedPlanesMap { + /// Unordered collection of all labels and corresponding plane parameters + std::vector> labelPlaneParameters; + + /// Image with a each pixel being assigned and integer value corresponding to the label. Might contain labels that are not in + /// labelPlaneParameters. These labels should be seen as background. + cv::Mat labeledImage; + + /// Size of each pixel [m] + double resolution; + + /// World X-Y position [m] of the (0, 0) pixel in the image. + Eigen::Vector2d mapOrigin; + + /// All label values are smaller than or equal to highestLabel + int highestLabel; +}; + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h new file mode 100644 index 00000000..aee87d57 --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h @@ -0,0 +1,49 @@ +// +// Created by rgrandia on 04.06.20. +// + +#pragma once + +#include + +#include "convex_plane_decomposition/PlanarRegion.h" +#include "convex_plane_decomposition/PolygonTypes.h" +#include "convex_plane_decomposition/SegmentedPlanesMap.h" + +#include "ContourExtractionParameters.h" + +namespace convex_plane_decomposition { +namespace contour_extraction { + + +/** + * Extracts the contours in map resolution, but with the x and y axis flipped. + * This way all contours are in counter clockwise direction. + */ +class ContourExtraction { + public: + ContourExtraction(const ContourExtractionParameters& parameters); + + std::vector extractPlanarRegions(const SegmentedPlanesMap& segmentedPlanesMap); + + private: + ContourExtractionParameters parameters_; + cv::Mat erosionKernel_; + + // Memory to reuse between calls + cv::Mat binaryImage_; +}; + +/// Modifies the image in-place! +std::vector extractBoundaryAndInset(cv::Mat& binary_image, const cv::Mat& erosionKernel); + +std::vector extractPolygonsFromBinaryImage(const cv::Mat& binary_image); + +CgalPolygon2d cgalPolygonFromOpenCv(const std::vector& openCvPolygon); + +CgalPoint2d worldFrameToTerrainFrame(const CgalPoint2d& worldFrameXY, const TerrainPlane& plane); + +CgalPoint2d pixelToWorldFrame(const CgalPoint2d& pixelspaceCgalPoint2d, double resolution, const Eigen::Vector2d& mapOffset); + +} +} \ No newline at end of file diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h new file mode 100644 index 00000000..b003cb1e --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h @@ -0,0 +1,16 @@ +// +// Created by rgrandia on 07.06.20. +// + +#pragma once + +namespace convex_plane_decomposition { +namespace contour_extraction { + +struct ContourExtractionParameters { + int offsetSize = 2; /// Size of the kernel creating the boundary offset. In number of pixels. +}; + +} // namespace contour_extraction +} + diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/convex_decomposer.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/convex_decomposer.hpp deleted file mode 100644 index 71391f97..00000000 --- a/convex_plane_decomposition/include/convex_plane_decomposition/convex_decomposer.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_CONVEX_DECOMPOSER_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_CONVEX_DECOMPOSER_HPP_ - -#include "polygon.hpp" - -namespace convex_plane_decomposition { - -enum class ConvexDecompositionType{ - kGreeneOptimalDecomposition = 1, - kInnerConvexApproximation = 2 -}; - -struct ConvexDecomposerParameters{ - ConvexDecompositionType decomposition_type = ConvexDecompositionType::kGreeneOptimalDecomposition; - double dent_angle_threshold_rad = 0.001; // 0.05 deg in rad. -}; - -class ConvexDecomposer { - public: - explicit ConvexDecomposer(const ConvexDecomposerParameters& parameters); - - CgalPolygon2dContainer performConvexDecomposition(const CgalPolygon2d& polygon) const; - - private: - std::multimap detectDentLocations(const CgalPolygon2d& polygon) const; - - CgalPolygon2dContainer performInnerConvexApproximation(const CgalPolygon2d& polygon) const; - - CgalPolygon2dContainer performOptimalConvexDecomposition(const CgalPolygon2d& polygon) const; - - ConvexDecomposerParameters parameters_; -}; - -} // namespace convex_plane_decomposition - -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_CONVEX_DECOMPOSER_HPP_ diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/export_utils.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/export_utils.hpp deleted file mode 100644 index a029f37a..00000000 --- a/convex_plane_decomposition/include/convex_plane_decomposition/export_utils.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_EXPORT_UTILS_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_EXPORT_UTILS_HPP_ - -#include - -#include -#include - -#include - -namespace convex_plane_decomposition { - -bool exportPointsWithNormalsToCsv(grid_map::GridMap& map, const std::string& normals_layer_prefix, const std::string& layer_height, - const std::string& path); - -} -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_EXPORT_UTILS_HPP_ diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/geometry_utils.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/geometry_utils.hpp deleted file mode 100644 index e0a9528b..00000000 --- a/convex_plane_decomposition/include/convex_plane_decomposition/geometry_utils.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ - -#include "types.hpp" - -namespace convex_plane_decomposition { - -double scalarCrossProduct(const Vector2d& leftVector, const Vector2d& rightVector); - -double computeAngleBetweenVectors(const Vector2d& first_vector, const Vector2d& second_vector); - -double distanceBetweenPoints(const Vector2d& first, const Vector2d& second); - -double distanceToLine(const Vector2d& lineSupportVector, const Vector2d& lineDirectionalVector, const Vector2d& testPoint); - -std::pair getDistanceAndClosestPointOnLineSegment(const Vector2d& point, const Vector2d& source, const Vector2d& target); - -double getDistanceOfPointToLineSegment(const Vector2d& point, const Vector2d& source, Vector2d& target); - -bool intersectLineSegmentWithLineSegment(const Vector2d& segment_1_source, const Vector2d& segment_1_target, - const Vector2d& segment_2_source, const Vector2d& segment_2_target, Vector2d* intersection_point); - -bool intersectRayWithLineSegment(const Vector2d& ray_source, const Vector2d& ray_direction, const Vector2d& segment_source, - const Vector2d& segment_target, Vector2d* intersection_point); - -bool isPointOnLeftSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); - -bool isPointOnRightSideOfLine(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point); - -} // namespace convex_plane_decomposition -#endif // CONVEX_PLANE_EXTRACTION_INCLUDE_GEOMETRY_UTILS_HPP_ diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/pipeline.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/pipeline.hpp deleted file mode 100644 index dd9559d7..00000000 --- a/convex_plane_decomposition/include/convex_plane_decomposition/pipeline.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION__PIPELINE_HPP_ -#define CONVEX_PLANE_EXTRACTION__PIPELINE_HPP_ - -#include "convex_decomposer.hpp" -#include "plane_factory.hpp" -#include "sliding_window_plane_extractor.hpp" - -namespace convex_plane_decomposition { - -struct PipelineParameters{ - sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters sliding_window_plane_extractor_parameters = - sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters(); - PlaneFactoryParameters plane_factory_parameters = PlaneFactoryParameters(); -}; - -struct GridMapParameters{ - GridMapParameters(grid_map::GridMap& input_map, const std::string& height_layer) - : map(input_map), - resolution(input_map.getResolution()), - layer_height(height_layer){} - - grid_map::GridMap& map; - double resolution; - std::string layer_height; -}; - -class Pipeline { - public: - Pipeline(const PipelineParameters& pipeline_parameters, const GridMapParameters& grid_map_parameters); - - Polygon3dVectorContainer getConvexPolygons() const; - - Polygon3dVectorContainer getPlaneContours() const; - - const cv::Mat& getSegmentationImage() const { return sliding_window_plane_extractor_.getLabeledImage(); }; - - private: - // Parameters - GridMapParameters grid_map_parameters_; - PipelineParameters pipeline_parameters_; - - PlaneFactory plane_factory_; - sliding_window_plane_extractor::SlidingWindowPlaneExtractor sliding_window_plane_extractor_; -}; -} // namespace_convex_plane_decomposition -#endif //CONVEX_PLANE_EXTRACTION__PIPELINE_HPP_ diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/plane.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/plane.hpp deleted file mode 100644 index 8baeaf6c..00000000 --- a/convex_plane_decomposition/include/convex_plane_decomposition/plane.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_SRC_PLANE_HPP_ -#define CONVEX_PLANE_EXTRACTION_SRC_PLANE_HPP_ - -#include - -#include "geometry_utils.hpp" -#include "polygon.hpp" - -namespace convex_plane_decomposition { - - struct PlaneParameters{ - - PlaneParameters(Eigen::Vector3d normal_vector, Eigen::Vector3d support_vector) - : support_vector(support_vector), - normal_vector(normal_vector){}; - - Eigen::Vector3d support_vector; - Eigen::Vector3d normal_vector; - }; - - class Plane { - public: - Plane(const CgalPolygon2d& plane_contour, const PlaneParameters& parameters) - : plane_contour_(plane_contour), normal_vector_(parameters.normal_vector), support_vector_(parameters.support_vector) {} - - void addConvexPolygon(const CgalPolygon2d& convex_polygon) { convex_polygons_.push_back(convex_polygon); } - - const CgalPolygon2dContainer& getConvexPolygons() const { return convex_polygons_; } - - CgalPolygon2dContainer& getConvexPolygonsMutable() { return convex_polygons_; } - - const Eigen::Vector3d& getPlaneNormalVector() const { return normal_vector_; } - - Eigen::Vector3d& getPlaneNormalVectorMutable() { return normal_vector_; } - - const CgalPolygon2d& getOuterPolygon() const { return plane_contour_; } - - CgalPolygon2d& getOuterPolygonMutable() { return plane_contour_; } - - PlaneParameters getPlaneParameters() const { return PlaneParameters(normal_vector_, support_vector_); } - - void setConvexPolygons(CgalPolygon2dContainer& convex_polygons) { convex_polygons_ = convex_polygons; } - - bool setNormalAndSupportVector(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector); - - bool setPlaneContour(const CgalPolygon2d& plane_contour) { plane_contour_ = plane_contour; } - - private: - CgalPolygon2d plane_contour_; - CgalPolygon2dContainer convex_polygons_; - - Vector3d normal_vector_; - Vector3d support_vector_; - }; - - } // namespace convex_plane_decomposition -#endif // CONVEX_PLANE_EXTRACTION_SRC_PLANE_HPP_ diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/plane_factory.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/plane_factory.hpp deleted file mode 100644 index f9f9039a..00000000 --- a/convex_plane_decomposition/include/convex_plane_decomposition/plane_factory.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_FACTORY_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_FACTORY_HPP_ - -#include -#include - -#include "convex_decomposer.hpp" -#include "plane.hpp" -#include "polygonizer.hpp" - -namespace convex_plane_decomposition { - -struct PlaneFactoryParameters{ - PolygonizerParameters polygonizer_parameters = PolygonizerParameters(); - ConvexDecomposerParameters convex_decomposer_parameters = ConvexDecomposerParameters(); - double plane_inclination_threshold_degrees = 70; -}; - -class PlaneFactory { - public: - - PlaneFactory(grid_map::GridMap& map, const PlaneFactoryParameters& parameters) - :map_(map), - parameters_(parameters){ - computeMapTransformation(); - }; - - void createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, const int number_of_labels, - const std::map& plane_parameters); - - void decomposePlanesInConvexPolygons(); - - Polygon3dVectorContainer getConvexPolygonsInWorldFrame() const; - - Polygon3dVectorContainer getPlaneContoursInWorldFrame() const; - - private: - - void computeMapTransformation(); - - Eigen::Vector3d convertPlanePointToWorldFrame(const CgalPoint2d& point, const PlaneParameters& plane_parameters) const; - - Polygon3dVectorContainer convertPlanePolygonsToWorldFrame(const CgalPolygon2dContainer& polygons, - const PlaneParameters& plane_parameters) const; - - Polygon3dVectorContainer convertPlanePolygonToWorldFrame(const CgalPolygon2d& polygon, const PlaneParameters& plane_parameters) const; - - bool isPlaneInclinationBelowThreshold(const Eigen::Vector3d& plane_normal_vector) const; - - // Grid map related members. - grid_map::GridMap& map_; - Eigen::Matrix2d transformation_xy_to_world_frame_; - Eigen::Vector2d map_offset_; - - // Parameters. - PlaneFactoryParameters parameters_; - - std::vector planes_; - -}; -} // namespace convex_plane_decomposition -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_PLANE_FACTORY_HPP_ diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/polygon.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/polygon.hpp deleted file mode 100644 index 2f5adbb9..00000000 --- a/convex_plane_decomposition/include/convex_plane_decomposition/polygon.hpp +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGON_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGON_HPP_ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "geometry_utils.hpp" -#include "types.hpp" - -namespace convex_plane_decomposition { - -using K = CGAL::Exact_predicates_inexact_constructions_kernel; -using EKernel = CGAL::Exact_predicates_exact_constructions_kernel; -using Traits = CGAL::Partition_traits_2; -using CgalPoint2d = CGAL::Point_2; -using CgalVector2d = CGAL::Vector_2; -using CgalPolygon2d = CGAL::Polygon_2; -using CgalPolygonWithHoles2d = CGAL::Polygon_with_holes_2; -using CgalSegment2d = Traits::Segment_2; -using CgalPolygon2dContainer = std::vector; -using CgalRay2d = Traits::Ray_2; -using CgalCircle2d = Traits::Circle_2; -using CgalPolygon2dConstIterator = CgalPolygon2dContainer::const_iterator; -using CgalPolygon2dSetContainer = CGAL::Polygon_set_2>; -using CgalPolygon2dVertexConstIterator = CgalPolygon2d::Vertex_const_iterator; -using CgalPolygon2dVertexIterator = CgalPolygon2d::Vertex_iterator; - -using Polygon3d = std::vector; -using Polygon3dVectorContainer = std::vector; -using Intersect_2 = K::Intersect_2; - -enum class SegmentIntersectionType : int { kSource, kTarget, kInterior }; - -struct Intersection { - void setEdgeSourceLocation(const int location) { edge_source_location_ = location; } - void setEdgeTargetLocation(const int location) { edge_target_location_ = location; } - void setIntersectionPoint(const CgalPoint2d& intersection_point) { intersection_point_ = intersection_point; } - void setAllMembers(const int source_location, const int target_location, const CgalPoint2d& intersection_point, - const SegmentIntersectionType& intersection_type) { - edge_source_location_ = source_location; - edge_target_location_ = target_location; - intersection_type_ = intersection_type; - intersection_point_ = intersection_point; - } - - int edge_source_location_; - int edge_target_location_; - SegmentIntersectionType intersection_type_; - CgalPoint2d intersection_point_; -}; - -struct PolygonWithHoles { - CgalPolygon2d outer_contour; - CgalPolygon2dContainer holes; -}; - -struct RaySegmentIntersection { - SegmentIntersectionType intersection_location; - CgalPoint2d intersection_point; -}; - -void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, double relative_local_area_threshold, - double absolute_local_area_threshold, double relative_total_area_threshold, double absolute_total_area_threshold); - -template -bool isContourSimple_impl(Iter begin, Iter end, std::bidirectional_iterator_tag) { - CgalPolygon2d polygon; - for (auto it = begin; it < end; ++it) { - polygon.push_back(Point((*it).x, (*it).y)); - std::cout << *it << std::endl; - } - return polygon.is_simple(); -}; - -template -bool isContourSimple(Iter begin, Iter end) { - return isContourSimple_impl(begin, end, typename std::iterator_traits::iterator_category()); -}; - -double computeTriangleArea(double side_length_a, double side_length_b, double side_length_c); - -void connectSecondPolygonToFirst(CgalPolygon2d& left_polygon, CgalPolygon2d& right_polygon); - -void copyVertices(const CgalPolygon2d& old_polygon, const CgalPolygon2dVertexIterator first, const CgalPolygon2dVertexIterator last, - CgalPolygon2d* new_polygon, const CgalPolygon2dVertexIterator insert_position); - -template -CgalPolygon2d createCgalPolygonFromOpenCvPoints_impl(Iter begin, Iter end, const double& resolution, std::bidirectional_iterator_tag) { - CgalPolygon2d polygon; - for (auto it = begin; it < end; ++it) { - polygon.push_back(CgalPoint2d(static_cast((*it).y * resolution), static_cast((*it).x) * resolution)); - } - return polygon; -}; - -template -CgalPolygon2d createCgalPolygonFromOpenCvPoints(Iter begin, Iter end, const double& resolution) { - return createCgalPolygonFromOpenCvPoints_impl(begin, end, resolution, typename std::iterator_traits::iterator_category()); -}; - -std::list decomposeInnerApproximation(const CgalPolygon2d& polygon); - -std::multimap detectDentLocations(const CgalPolygon2d& polygon); - -bool doPointAndPolygonIntersect(const CgalPolygon2d& polygon, const CgalPoint2d& point, int& segment_source_vertex_index); - -bool doPolygonAndSegmentIntersect(const CgalPolygon2d& polygon, const CgalSegment2d& segment, bool print_flag); - -bool doRayAndSegmentIntersect(const CgalRay2d& ray, const CgalSegment2d& segment, RaySegmentIntersection* intersection); - -CgalPolygon2dVertexIterator erase(CgalPolygon2dVertexIterator first, CgalPolygon2dVertexIterator last, CgalPolygon2d* polygon); - -std::pair getClosestPointAndSegmentOnPolygonToPoint(const CgalPoint2d& point, const CgalPolygon2d& polygon); - -int getClosestPolygonVertexPosition(const CgalPolygon2d& polygon, const CgalPoint2d& point); - -std::multimap> getClosestVertexPairsOrdered(const CgalPolygon2d& first_polygon, - const CgalPolygon2d& second_polygon); - -std::vector> getCommonVertexPairIndices(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon); - -double getEdgeLength(const CgalPolygon2dVertexIterator& source, const CgalPolygon2d& polygon); - -std::pair getIndicesOfClosestVertexPair(CgalPolygon2d& first_polygon, CgalPolygon2d& second_polygon); - -CgalPoint2d getPolygonVertexAtIndex(const CgalPolygon2d& polygon, int index); - -void getSegmentNormalVector(const CgalSegment2d& segment, Eigen::Vector2d* normal_vector); - -std::vector getVertexIndicesOfFirstPolygonContainedInSecondPolygonContour(const CgalPolygon2d& first_polygon, - const CgalPolygon2d& second_polygon); - -void getVertexPositionsInAscendingDistanceToPoint(const CgalPolygon2d& polygon, const CgalPoint2d& point, - std::multimap* vertex_positions); - -std::pair getVertexPositionsWithHighestHoleSlConcavityMeasure(const CgalPolygon2d& polygon); - -bool intersectPolygonWithRay(int ray_target_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, - Intersection* intersection); - -CgalPolygon2dVertexIterator next(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon); - -bool next(const CgalPolygon2dVertexIterator& iterator, CgalPolygon2dVertexIterator& output_iterator, const CgalPolygon2d& polygon); - -void performConvexDecomposition(const CgalPolygon2d& polygon, CgalPolygon2dContainer* output_polyong_list); - -CgalPolygon2dVertexIterator previous(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon); - -void printPolygon(const CgalPolygon2d& polygon); - -std::string printPolygonToString(const CgalPolygon2d& polygon); - -void upSampleLongEdges(CgalPolygon2d* polygon); - -} // namespace convex_plane_decomposition -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGON_HPP_ diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/polygonizer.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/polygonizer.hpp deleted file mode 100644 index ac514d57..00000000 --- a/convex_plane_decomposition/include/convex_plane_decomposition/polygonizer.hpp +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGONIZER_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGONIZER_HPP_ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "plane.hpp" -#include "polygon.hpp" - -namespace convex_plane_decomposition { - -struct PolygonizerParameters{ - double resolution = 0.02; - int upsampling_factor = 3; - bool activate_long_edge_upsampling = false; - bool activate_contour_approximation = false; - double hole_area_threshold_squared_meters = 2e-3; - double contour_approximation_relative_local_area_threshold = 0.01; - double contour_approximation_absolute_local_area_threshold_squared_meters = 0.04; - double contour_approximation_relative_total_area_threshold = 0.5; - double contour_approximation_absolute_total_area_threshold_squared_meters = 1.0; - int max_number_of_iterations = 5; -}; - -class Polygonizer { - public: - explicit Polygonizer(const PolygonizerParameters parameters = PolygonizerParameters()) : parameters_(parameters){}; - - bool addHoleToOuterContourAtVertexIndex(int segment_target_vertex_index, const CgalPolygon2d& hole, CgalPolygon2d& outer_contour) const; - - PolygonWithHoles extractContoursFromBinaryImage(cv::Mat& binary_image) const; - - PolygonWithHoles extractPolygonsFromBinaryImage(const cv::Mat& binary_image) const; - - void removeAreasNotContainedInOuterContourFromHoles(const CgalPolygon2d& outer_polygon, std::vector& holes) const; - - void resolveHolesInBinaryImage(cv::Mat& binary_image, const PolygonWithHoles& contour_with_holes) const; - - CgalPolygon2d resolveHolesUsingSlConnection(const PolygonWithHoles& polygon_with_holes) const; - - CgalPolygon2d resolveHolesWithVerticalConnection(PolygonWithHoles& polygon_with_holes) const; - - CgalPolygon2d runPolygonizationOnBinaryImage(const cv::Mat& binary_image) const; - - private: - PolygonizerParameters parameters_; -}; - - -} // namespace convex_plane_decomposition - -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_POLYGONIZER_HPP_ diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp new file mode 100644 index 00000000..82a8ba65 --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include + +#include "CGAL/Exact_predicates_inexact_constructions_kernel.h" +#include "CGAL/Point_with_normal_3.h" +#include "CGAL/Shape_detection/Efficient_RANSAC.h" +#include "CGAL/property_map.h" + +#include "RansacPlaneExtractorParameters.h" + +namespace ransac_plane_extractor { + +// Point with normal related type declarations. +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using Point3D = Kernel::Point_3; +using Vector3D = Kernel::Vector_3; +using PointWithNormal = std::pair; +using PwnVector = std::vector; + +// RANSAC plane extractor related type declarations. +using PointMap = CGAL::First_of_pair_property_map; +using NormalMap = CGAL::Second_of_pair_property_map; +using Traits = CGAL::Shape_detection::Efficient_RANSAC_traits; +using EfficientRansac = CGAL::Shape_detection::Efficient_RANSAC; +using Plane = CGAL::Shape_detection::Plane; + +class RansacPlaneExtractor { + public: + RansacPlaneExtractor(const RansacPlaneExtractorParameters& parameters); + + void setParameters(const RansacPlaneExtractorParameters& parameters); + + void detectPlanes(std::vector& points_with_normal); + + /// Returns an iterator range. Data is still in the ransac_object + EfficientRansac::Shape_range getDetectedPlanes() const { return ransac_.shapes(); }; + + /// Returns an iterator range. Data is still in the ransac_object + EfficientRansac::Point_index_range getUnassignedPointIndices() { return ransac_.indices_of_unassigned_points(); } + + private: + EfficientRansac ransac_; + EfficientRansac::Parameters cgalRansacParameters_; +}; + +} // namespace ransac_plane_extractor diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h new file mode 100644 index 00000000..1bb09f76 --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h @@ -0,0 +1,22 @@ +// +// Created by rgrandia on 07.06.20. +// + +#pragma once + +namespace ransac_plane_extractor { + +struct RansacPlaneExtractorParameters { + /// Set probability to miss the largest primitive at each iteration. + double probability = 0.01; + /// Detect shapes with at least 200 points. + double min_points = 200; + /// Set maximum Euclidean distance between a point and a shape. + double epsilon = 0.004; + /// Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon + double cluster_epsilon = 0.03; + /// Set maximum normal deviation. normal_threshold < dot(surface_normal, point_normal); + double normal_threshold = 0.98; +}; + +} // namespace ransac_plane_extractor diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ransac_plane_extractor.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/ransac_plane_extractor.hpp deleted file mode 100644 index 6fa88a66..00000000 --- a/convex_plane_decomposition/include/convex_plane_decomposition/ransac_plane_extractor.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_RANSACPLANEEXTRACTOR_HPP_ -#define CONVEX_PLANE_EXTRACTION_RANSACPLANEEXTRACTOR_HPP_ - -#if defined (_MSC_VER) && !defined (_WIN64) -#pragma warning(disable:4244) // boost::number_distance::distance() - // converts 64 to 32 bits integers -#endif - -#include -#include - -#include "CGAL/property_map.h" -#include "CGAL/Point_with_normal_3.h" -#include "CGAL/Exact_predicates_inexact_constructions_kernel.h" -#include "CGAL/Shape_detection/Efficient_RANSAC.h" -#include -#include -#include - - -namespace ransac_plane_extractor { - - // Point with normal related type declarations. - using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; - using Point3D = Kernel::Point_3; - using Vector3D = Kernel::Vector_3; - using PointWithNormal = std::pair; - using PwnVector = std::vector; - - // RANSAC plane extractor related type declarations. - using PointMap = CGAL::First_of_pair_property_map; - using NormalMap = CGAL::Second_of_pair_property_map; - using Traits = CGAL::Shape_detection::Efficient_RANSAC_traits - ; - using EfficientRansac = CGAL::Shape_detection::Efficient_RANSAC; - using Plane = CGAL::Shape_detection::Plane; - - struct RansacPlaneExtractorParameters{ - // Set probability to miss the largest primitive at each iteration. - double probability = 0.01; - // Detect shapes with at least 200 points. - double min_points = 200; - // Set maximum Euclidean distance between a point and a shape. - double epsilon = 0.004; - // Set maximum Euclidean distance between points to be clustered. - double cluster_epsilon = 0.0282842712475; - // Set maximum normal deviation. 0.98 < dot(surface_normal, point_normal); - double normal_threshold = 0.98; - }; - - class RansacPlaneExtractor { - public: - - RansacPlaneExtractor(std::vector& points_with_normal, const RansacPlaneExtractorParameters& parameters); - - void setParameters(const RansacPlaneExtractorParameters& parameters); - - void runDetection(); - - auto getDetectedPlanes() const{ - return ransac_.shapes(); - }; - - private: - - EfficientRansac ransac_; - EfficientRansac::Parameters parameters_; - - }; - -} - -#endif //GRID_MAP_DEMOS_RANSACPLANEEXTRACTOR_HPP_ diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h new file mode 100644 index 00000000..f1244163 --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +#include +#include + +#include "convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp" +#include "convex_plane_decomposition/SegmentedPlanesMap.h" + +#include "SlidingWindowPlaneExtractorParameters.h" + +namespace convex_plane_decomposition { +namespace sliding_window_plane_extractor { + + +class SlidingWindowPlaneExtractor { + public: + SlidingWindowPlaneExtractor(const SlidingWindowPlaneExtractorParameters& parameters, + const ransac_plane_extractor::RansacPlaneExtractorParameters& ransacParameters); + + void runExtraction(const grid_map::GridMap& map, const std::string& layer_height); + + const SegmentedPlanesMap& getSegmentedPlanesMap() const { return segmentedPlanesMap_; } + + const cv::Mat& getBinaryLabeledImage() const { return binaryImagePatch_; } + + private: + bool isGloballyPlanar(const Eigen::Vector3d& normalVectorPlane, const Eigen::Vector3d& supportVectorPlane, + const std::vector& points_with_normal) const; + + std::pair computeNormalAndErrorForWindow(const Eigen::MatrixXf& windowData) const; + bool isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanError) const; + + int getLinearIndex(int row, int col) const { return row + col * map_->getSize()[0]; }; + + void computePlaneParametersForLabel(int label); + + void extractPlaneParametersFromLabeledImage(); + + void runSegmentation(); + + void runSlidingWindowDetector(); + + SlidingWindowPlaneExtractorParameters parameters_; + ransac_plane_extractor::RansacPlaneExtractorParameters ransacParameters_; + + const grid_map::GridMap* map_; + std::string elevationLayer_; + + std::vector surfaceNormals_; + + cv::Mat binaryImagePatch_; + SegmentedPlanesMap segmentedPlanesMap_; +}; +} // namespace sliding_window_plane_extractor +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h new file mode 100644 index 00000000..40604651 --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h @@ -0,0 +1,38 @@ +// +// Created by rgrandia on 07.06.20. +// + +#pragma once + +namespace convex_plane_decomposition { +namespace sliding_window_plane_extractor { + +struct SlidingWindowPlaneExtractorParameters { + /// Size of the sliding window patch used for normal vector calculation and planarity detection + /// Should be an odd number and at least 3. + int kernel_size = 3; + + /// [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch + double plane_inclination_threshold_degrees = 70.0; + + /// [m] The allowed root-mean-squared deviation from the plane fitted to the patch. Higher -> not planar + double plane_patch_error_threshold = 0.005; + + /// [#] Labels with less points assigned to them are discarded + int min_number_points_per_label = 10; + + /// Label kernel connectivity. 4 or 8 (cross or box) + int connectivity = 4; + + /// Enable RANSAC refinement if the plane is not globally fitting to the assigned points. + bool include_ransac_refinement = true; + + /// [m] Allowed maximum distance from a point to the plane. If any point violates this, RANSAC is triggered + double global_plane_fit_distance_error_threshold = 0.04; + + /// [deg] Allowed normal vector deviation for a point w.r.t. the plane normal. If any point violates this, RANSAC is triggered + double global_plane_fit_angle_error_threshold_degrees = 5.0; +}; + +} // namespace sliding_window_plane_extractor +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extractor.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extractor.hpp deleted file mode 100644 index d64926f3..00000000 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extractor.hpp +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_SLIDING_WINDOW_PLANE_EXTRACTOR_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_SLIDING_WINDOW_PLANE_EXTRACTOR_HPP_ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "plane.hpp" -#include "polygon.hpp" -#include "ransac_plane_extractor.hpp" - - -namespace sliding_window_plane_extractor { - - struct SlidingWindowPlaneExtractorParameters{ - int kernel_size = 3; - double plane_patch_error_threshold = 0.004; - double surface_normal_angle_threshold_degrees = 1.0; - bool include_curvature_detection = false; - bool include_ransac_refinement = false; - double global_plane_fit_error_threshold = 0.01; - - ransac_plane_extractor::RansacPlaneExtractorParameters ransac_parameters = ransac_plane_extractor::RansacPlaneExtractorParameters(); - }; - - class SlidingWindowPlaneExtractor{ - public: - SlidingWindowPlaneExtractor(grid_map::GridMap& map, double resolution, const std::string& layer_height, - const SlidingWindowPlaneExtractorParameters& parameters = SlidingWindowPlaneExtractorParameters(), - const ransac_plane_extractor::RansacPlaneExtractorParameters& ransac_parameters = - ransac_plane_extractor::RansacPlaneExtractorParameters()); - - void runExtraction(); - - const cv::Mat& getLabeledImage() const { return labeled_image_; } - - const auto& getLabelPlaneParameterMap() const { return label_plane_parameters_map_; } - - int getNumberOfExtractedPlanes() const { return number_of_extracted_planes_; } - - void setParameters(const SlidingWindowPlaneExtractorParameters& parameters); - - private: - double computeAverageErrorToPlane(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector, - const std::vector& points_with_normal) const; - - void computeMapTransformation(); - - void computePlaneParametersForLabel(int label); - - void extractPlaneParametersFromLabeledImage(); - - auto runRansacRefinement(std::vector& points_with_normal) const; - - void runSegmentation(); - - void runSlidingWindowDetector(); - - void runSurfaceNormalCurvatureDetection(); - - grid_map::GridMap& map_; - std::string elevation_layer_; - double resolution_; - Eigen::Matrix2d transformation_xy_to_world_frame_; - Eigen::Vector2d map_offset_; - - SlidingWindowPlaneExtractorParameters parameters_; - ransac_plane_extractor::RansacPlaneExtractorParameters ransac_parameters_; - cv::Mat binary_image_patch_; - cv::Mat binary_image_angle_; - cv::Mat labeled_image_; - int number_of_extracted_planes_; - std::map label_plane_parameters_map_; - }; - } // namespace sliding_window_plane_extractor -#endif // CONVEX_PLANE_EXTRACTION_INCLUDE_SLIDING_WINDOW_PLANE_EXTRACTOR_HPP_ diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/types.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/types.hpp deleted file mode 100644 index 00ae1f3e..00000000 --- a/convex_plane_decomposition/include/convex_plane_decomposition/types.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// -// Created by andrej on 12/6/19. -// - -#ifndef CONVEX_PLANE_EXTRACTION_INCLUDE_TYPES_HPP_ -#define CONVEX_PLANE_EXTRACTION_INCLUDE_TYPES_HPP_ - -#include - -#include -#include -#include -#include - -namespace convex_plane_decomposition { - - typedef Eigen::VectorXd VectorXd; - typedef Eigen::MatrixXd MatrixXd; - typedef Eigen::Vector3d Vector3d; - typedef Eigen::Matrix3d Matrix3d; - typedef Eigen::Matrix2d Matrix2d; - typedef Eigen::Vector2d Vector2d; - typedef Eigen::VectorXf VectorXf; - typedef Eigen::MatrixXf MatrixXf; - typedef Eigen::Vector3f Vector3f; - typedef Eigen::Matrix3f Matrix3f; - typedef Eigen::Matrix2f Matrix2f; - typedef Eigen::Vector2f Vector2f; - typedef Eigen::VectorXi VectorXi; - typedef Eigen::MatrixXi MatrixXi; - typedef Eigen::Vector3i Vector3i; - typedef Eigen::Matrix3i Matrix3i; - typedef Eigen::Matrix2i Matrix2i; - typedef Eigen::Vector2i Vector2i; - typedef Eigen::Matrix MatrixXb; - - typedef cv::Point CvPoint2i; - typedef cv::Point2f CvPoint2f; - -} - -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_TYPES_HPP_ diff --git a/convex_plane_decomposition/package.xml b/convex_plane_decomposition/package.xml index 375c4daf..840a1008 100644 --- a/convex_plane_decomposition/package.xml +++ b/convex_plane_decomposition/package.xml @@ -10,5 +10,7 @@ catkin grid_map_core + ocs2_switched_model_interface + diff --git a/convex_plane_decomposition/src/ConvexRegionGrowing.cpp b/convex_plane_decomposition/src/ConvexRegionGrowing.cpp new file mode 100644 index 00000000..a3f963a1 --- /dev/null +++ b/convex_plane_decomposition/src/ConvexRegionGrowing.cpp @@ -0,0 +1,138 @@ +// +// Created by rgrandia on 09.06.20. +// + +#include "convex_plane_decomposition/ConvexRegionGrowing.h" + +#include "convex_plane_decomposition/GeometryUtils.h" + +namespace convex_plane_decomposition { + +CgalPolygon2d createRegularPolygon(const CgalPoint2d& center, double radius, int numberOfVertices) { + assert(numberOfVertices > 2); + CgalPolygon2d polygon; + double angle = (2. * M_PI) / numberOfVertices; + for (int i = 0; i < numberOfVertices; ++i) { + double phi = i * angle; + double px = radius * std::cos(phi) + center.x(); + double py = radius * std::sin(phi) + center.y(); + // Counter clockwise + polygon.push_back({px, py}); + } + return polygon; +} + +int getCounterClockWiseNeighbour(int i, int lastVertex) { + return (i > 0) ? i - 1 : lastVertex; +} + +int getClockWiseNeighbour(int i, int lastVertex) { + return (i < lastVertex) ? i + 1 : 0; +} + +void updateMean(CgalPoint2d & mean, const CgalPoint2d& oldValue, const CgalPoint2d& updatedValue, int N) { + // old_mean = 1/N * ( others + old_value); -> others = N*old_mean - old_value + // new_mean = 1/N * ( others + new_value); -> new_mean = old_mean - 1/N * oldValue + 1/N * updatedValue + mean += 1.0 / N * (updatedValue - oldValue); +} + +std::array getNeighbours(const CgalPolygon2d& polygon, int i) { + assert(i < polygon.size()); + assert(polygon.size() > 1); + int lastVertex = static_cast(polygon.size()) - 1; + int cwNeighbour = getClockWiseNeighbour(i, lastVertex); + int ccwNeighbour = getCounterClockWiseNeighbour(i, lastVertex); + return {polygon.vertex(cwNeighbour), polygon.vertex(ccwNeighbour)}; +} + +std::array get2ndNeighbours(const CgalPolygon2d& polygon, int i) { + assert(i < polygon.size()); + assert(polygon.size() > 1); + int lastVertex = static_cast(polygon.size()) - 1; + int cwNeighbour1 = getClockWiseNeighbour(i, lastVertex); + int cwNeighbour2 = getClockWiseNeighbour(cwNeighbour1, lastVertex); + int ccwNeighbour1 = getCounterClockWiseNeighbour(i, lastVertex); + int ccwNeighbour2 = getCounterClockWiseNeighbour(ccwNeighbour1, lastVertex); + return {polygon.vertex(cwNeighbour2), polygon.vertex(cwNeighbour1), polygon.vertex(ccwNeighbour1), polygon.vertex(ccwNeighbour2)}; +} + +bool remainsConvexWhenMovingPoint(const CgalPolygon2d& polygon, int i, const CgalPoint2d& point) { + auto secondNeighbours = get2ndNeighbours(polygon, i); + CgalPolygon2d subPolygon; + subPolygon.container().reserve(5); + subPolygon.push_back(secondNeighbours[0]); + subPolygon.push_back(secondNeighbours[1]); + subPolygon.push_back(point); + subPolygon.push_back(secondNeighbours[2]); + subPolygon.push_back(secondNeighbours[3]); + return subPolygon.is_convex(); +} + +bool pointAndNeighboursAreWithinFreeSphere(const std::array& neighbours, const CgalPoint2d& point, + const CgalCircle2d& circle) { + return isInside(neighbours[0], circle) && isInside(point, circle) && isInside(neighbours[1], circle); +} + +template +bool pointCanBeMoved(const CgalPolygon2d& growthShape, int i, const CgalPoint2d& candidatePoint, CgalCircle2d& freeSphere, + const T& parentShape) { + if (remainsConvexWhenMovingPoint(growthShape, i, candidatePoint)) { + auto neighbours = getNeighbours(growthShape, i); + if (pointAndNeighboursAreWithinFreeSphere(neighbours, candidatePoint, freeSphere)) { + return true; + } else { + // Update free sphere around new point + freeSphere = CgalCircle2d(candidatePoint, squaredDistance(candidatePoint, parentShape)); + CgalSegment2d segment0{neighbours[0], candidatePoint}; + CgalSegment2d segment1{neighbours[1], candidatePoint}; + + bool segment0IsFree = isInside(neighbours[0], freeSphere) || !doEdgesIntersect(segment0, parentShape); + if (segment0IsFree) { + bool segment1IsFree = isInside(neighbours[1], freeSphere) || !doEdgesIntersect(segment1, parentShape); + return segment1IsFree; + } else { + return false; + } + } + } else { + return false; + } +} + +template +CgalPolygon2d growConvexPolygonInsideShape_impl(const T& parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor) { + constexpr double initialRadiusFactor = 0.999; + double radius = initialRadiusFactor * distance(center, parentShape); + CgalPolygon2d growthShape = createRegularPolygon(center, radius, numberOfVertices); + + // Cached values per vertex + std::vector blocked(numberOfVertices, false); + std::vector freeSpheres(numberOfVertices, CgalCircle2d(center, radius*radius)); + + int Nblocked = 0; + while (Nblocked < numberOfVertices) { + for (int i = 0; i < numberOfVertices; i++) { + if (!blocked[i]) { + const auto candidatePoint = getPointOnLine(center, growthShape.vertex(i), growthFactor); + if (pointCanBeMoved(growthShape, i, candidatePoint, freeSpheres[i], parentShape)) { + updateMean(center, growthShape.vertex(i), candidatePoint, numberOfVertices); + growthShape.vertex(i) = candidatePoint; + } else { + blocked[i] = true; + ++Nblocked; + } + } + } + } + return growthShape; +} + +CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygon2d & parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor) { + return growConvexPolygonInsideShape_impl(parentShape, center, numberOfVertices, growthFactor); +} + +CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygonWithHoles2d& parentShape, CgalPoint2d center, int numberOfVertices, + double growthFactor) { + return growConvexPolygonInsideShape_impl(parentShape, center, numberOfVertices, growthFactor); +} +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/src/Draw.cpp b/convex_plane_decomposition/src/Draw.cpp new file mode 100644 index 00000000..3c20b8c4 --- /dev/null +++ b/convex_plane_decomposition/src/Draw.cpp @@ -0,0 +1,60 @@ +// +// Created by rgrandia on 09.06.20. +// + +#include "convex_plane_decomposition/Draw.h" + +namespace convex_plane_decomposition { + +cv::Vec3b randomColor() { + return cv::Vec3b((rand() & 255), (rand() & 255), (rand() & 255)); +} + +std::vector toCv(const CgalPolygon2d& polygon) { + std::vector contour; + contour.reserve(polygon.size()); + for (const auto& point : polygon) { + contour.emplace_back(point.x(), point.y()); + } + return contour; +} + +void drawContour(cv::Mat& img, const CgalPoint2d& point, double radius, const cv::Vec3b* color) { + const cv::Vec3b contourColor = (color == nullptr) ? randomColor() : *color; + cv::Point cvPoint(point.x(), point.y()); + cv::circle(img, cvPoint, radius, contourColor); +} + +void drawContour(cv::Mat& img, const CgalPolygon2d& polygon, const cv::Vec3b* color) { + const cv::Vec3b contourColor = (color == nullptr) ? randomColor() : *color; + std::vector> contours{toCv(polygon)}; + drawContours(img, contours, 0, contourColor); +} + +void drawContour(cv::Mat& img, const CgalPolygonWithHoles2d& polygonWithHoles2d, const cv::Vec3b* color) { + const cv::Vec3b contourColor = (color == nullptr) ? randomColor() : *color; + + drawContour(img, polygonWithHoles2d.outer_boundary(), &contourColor); + for (const auto& hole : polygonWithHoles2d.holes()) { + drawContour(img, hole, &contourColor); + } +} + +CgalPolygon2d scaleShape(const CgalPolygon2d& polygon, double scale) { + CgalPolygon2d scaledShape; + scaledShape.container().reserve(polygon.size()); + for (const auto& point : polygon) { + scaledShape.push_back({scale * point.x(), scale * point.y()}); + } + return scaledShape; +} +CgalPolygonWithHoles2d scaleShape(const CgalPolygonWithHoles2d& polygonWithHoles, double scale) { + CgalPolygonWithHoles2d scaledShape(scaleShape(polygonWithHoles.outer_boundary(), scale)); + + for (const auto& hole : polygonWithHoles.holes()) { + scaledShape.add_hole(scaleShape(hole, scale)); + } + return scaledShape; +} + +} \ No newline at end of file diff --git a/convex_plane_decomposition/src/GridMapPreprocessing.cpp b/convex_plane_decomposition/src/GridMapPreprocessing.cpp new file mode 100644 index 00000000..650e59a5 --- /dev/null +++ b/convex_plane_decomposition/src/GridMapPreprocessing.cpp @@ -0,0 +1,73 @@ +#include "convex_plane_decomposition/GridMapPreprocessing.h" + +#include +#include +#include +#include +#include + +#include "convex_plane_decomposition/Nan.h" + +namespace convex_plane_decomposition { + +GridMapPreprocessing::GridMapPreprocessing(const PreprocessingParameters& parameters) : parameters_(parameters) {} + +void GridMapPreprocessing::preprocess(grid_map::GridMap& gridMap, const std::string& layer) { + const float minValue = gridMap.get(layer).minCoeffOfFinites(); + const float maxValue = gridMap.get(layer).maxCoeffOfFinites(); + + patchNans(gridMap.get(layer)); + denoise(gridMap, layer); + + if (parameters_.inpaintRadius > 0) { + inpaint(gridMap, layer, minValue, maxValue); + } +} + +void GridMapPreprocessing::denoise(grid_map::GridMap& gridMap, const std::string& layer) { + Eigen::MatrixXf& elevation_map = gridMap.get(layer); + + cv::Mat elevationImage; + cv::eigen2cv(elevation_map, elevationImage); + + int kernelSize = parameters_.kernelSize; + for (int i = 0; i < parameters_.numberOfRepeats; ++i) { + cv::medianBlur(elevationImage, elevationImage, parameters_.kernelSize); + if (parameters_.increasing) { + kernelSize += 2; + } + } + + cv::cv2eigen(elevationImage, elevation_map); +} + +void GridMapPreprocessing::inpaint(grid_map::GridMap& gridMap, const std::string& layer, float minValue, float maxValue) { + Eigen::MatrixXf& elevation_map = gridMap.get(layer); + + Eigen::Matrix mask = elevation_map.unaryExpr([](float val) { return (isNan(val)) ? uchar(1) : uchar(0); }); + + cv::Mat maskImage; + cv::eigen2cv(mask, maskImage); + + cv::Mat elevationImage; + grid_map::GridMapCvConverter::toImage(gridMap, layer, CV_8UC1, minValue, maxValue, elevationImage); + + // Inpainting + cv::Mat filledImage; + const double radiusInPixels = parameters_.inpaintRadius / gridMap.getResolution(); + cv::inpaint(elevationImage, maskImage, filledImage, radiusInPixels, cv::INPAINT_NS); + + // Get inpainting as float + cv::Mat filledImageFloat; + const float maxUCharValue = 255.F; + filledImage.convertTo(filledImageFloat, CV_32F, (maxValue - minValue) / maxUCharValue, minValue); + + // Copy inpainted values back to elevation map + cv::Mat elevationImageFloat; + cv::eigen2cv(elevation_map, elevationImageFloat); + filledImageFloat.copyTo(elevationImageFloat, maskImage); + + cv::cv2eigen(elevationImageFloat, elevation_map); +} + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp new file mode 100644 index 00000000..4777192c --- /dev/null +++ b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp @@ -0,0 +1,127 @@ +// +// Created by rgrandia on 04.06.20. +// + +#include "convex_plane_decomposition/contour_extraction/ContourExtraction.h" + +#include +#include + +namespace convex_plane_decomposition { +namespace contour_extraction { + +ContourExtraction::ContourExtraction(const ContourExtractionParameters& parameters) : parameters_(parameters), + binaryImage_(cv::Size(0, 0), CV_8UC1) { + int erosionSize = parameters_.offsetSize; // single sided length of the kernel + int erosionType = cv::MORPH_CROSS; // cv::MORPH_ELLIPSE, cv::MORPH_RECT + erosionKernel_ = cv::getStructuringElement(erosionType, cv::Size(2 * erosionSize + 1, 2 * erosionSize + 1)); +} + +std::vector ContourExtraction::extractPlanarRegions(const SegmentedPlanesMap& segmentedPlanesMap) { + std::vector planarRegions; + for (const auto& label_plane : segmentedPlanesMap.labelPlaneParameters) { + const int label = label_plane.first; + const auto& plane_parameters = label_plane.second; + + binaryImage_ = segmentedPlanesMap.labeledImage == label; + + auto boundariesAndInsets = contour_extraction::extractBoundaryAndInset(binaryImage_, erosionKernel_); + + for (auto& boundaryAndInset : boundariesAndInsets) { + // Transform points from pixel space to local terrain frame + transformInPlace(boundaryAndInset, [&](CgalPoint2d& point) { + auto pointInWorld = pixelToWorldFrame(point, segmentedPlanesMap.resolution, segmentedPlanesMap.mapOrigin); + point = worldFrameToTerrainFrame(pointInWorld, plane_parameters); + }); + + PlanarRegion planarRegion; + planarRegion.boundaryWithInset = std::move(boundaryAndInset); + planarRegion.planeParameters = plane_parameters; + planarRegion.bbox2d = planarRegion.boundaryWithInset.boundary.outer_boundary().bbox(); + planarRegions.push_back(std::move(planarRegion)); + } + } + return planarRegions; +} + +std::vector extractBoundaryAndInset(cv::Mat& binary_image, const cv::Mat& erosionKernel) { + // Get boundary + std::vector boundaries = extractPolygonsFromBinaryImage(binary_image); + + // Erode + cv::erode( binary_image, binary_image, erosionKernel ); + + // Get insets + std::vector insets = extractPolygonsFromBinaryImage(binary_image); + + // Associate boundaries with insets + std::vector boundariesWithInsets; + for (const auto& boundary : boundaries) { + std::vector assignedInsets; + for (const auto& inset : insets) { + if (isInside(inset.outer_boundary().vertex(0), boundary)) { + assignedInsets.push_back(inset); + } + } + + if (!assignedInsets.empty()){ + BoundaryWithInset boundaryWithInset; + boundaryWithInset.boundary = boundary; + boundaryWithInset.insets = assignedInsets; + boundariesWithInsets.push_back(std::move(boundaryWithInset)); + } + } + return boundariesWithInsets; +} + +std::vector extractPolygonsFromBinaryImage(const cv::Mat& binary_image) { + std::vector> contours; + std::vector hierarchy; // [Next, Previous, First_Child, Parent] + auto isOuterContour = [](const cv::Vec4i& hierarchyVector) { + return hierarchyVector[3] < 0; // no parent + }; + + cv::findContours(binary_image, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); + + std::vector plane_polygons; + for (int i = 0; i < contours.size(); i++) { + if (isOuterContour(hierarchy[i]) && contours[i].size() > 1) { + CgalPolygonWithHoles2d polygon; + polygon.outer_boundary() = cgalPolygonFromOpenCv(contours[i]); + + // Add children as holes + int childIndex = hierarchy[i][2]; // First child + while (childIndex > 0) { + polygon.add_hole(cgalPolygonFromOpenCv(contours[childIndex])); + childIndex = hierarchy[childIndex][0]; // Next child + } + plane_polygons.push_back(std::move(polygon)); + } + } + return plane_polygons; +} + +CgalPolygon2d cgalPolygonFromOpenCv(const std::vector& openCvPolygon) { + CgalPolygon2d polygon; + polygon.container().reserve(openCvPolygon.size()); + for (const auto& point: openCvPolygon) { + polygon.container().emplace_back(point.x, point.y); + } + return polygon; +} + +CgalPoint2d worldFrameToTerrainFrame(const CgalPoint2d& worldFrameXY, const TerrainPlane& plane) { + const auto projectedPositionInWorld = projectPositionInWorldOntoPlaneAlongGravity({worldFrameXY.x(), worldFrameXY.y(), 0.0}, plane); + const auto positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(projectedPositionInWorld, plane); + return {positionInTerrainFrame.x(), positionInTerrainFrame.y()}; +} + +CgalPoint2d pixelToWorldFrame(const CgalPoint2d& pixelspaceCgalPoint2d, double resolution, const Eigen::Vector2d& mapOffset) { + // Notice the transpose of x and y! + return {mapOffset.x() -resolution * pixelspaceCgalPoint2d.y(), mapOffset.y() -resolution * pixelspaceCgalPoint2d.x()}; +} + + + +} // namespace contour_extraction +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/src/convex_decomposer.cpp b/convex_plane_decomposition/src/convex_decomposer.cpp deleted file mode 100644 index cd3dc99f..00000000 --- a/convex_plane_decomposition/src/convex_decomposer.cpp +++ /dev/null @@ -1,241 +0,0 @@ -#include "convex_plane_decomposition/convex_decomposer.hpp" - -using namespace convex_plane_decomposition; - -ConvexDecomposer::ConvexDecomposer(const convex_plane_decomposition::ConvexDecomposerParameters ¶meters) - :parameters_(parameters){} - -CgalPolygon2dContainer ConvexDecomposer::performConvexDecomposition(const CgalPolygon2d& polygon) const { - VLOG(1) << "Started convex decomposition..."; - CgalPolygon2dContainer convex_polygons; - if (polygon.size() == 2) { - convex_polygons.push_back(polygon); - return convex_polygons; - } - CHECK(polygon.is_simple()); - if(polygon.is_convex()) { - VLOG(1) << "Polygon already convex, no decompostion performed."; - convex_polygons.push_back(polygon); - return convex_polygons; - } - switch (parameters_.decomposition_type){ - case ConvexDecompositionType::kGreeneOptimalDecomposition : - convex_polygons = performOptimalConvexDecomposition(polygon); - break; - case ConvexDecompositionType::kInnerConvexApproximation : - convex_polygons = performInnerConvexApproximation(polygon); - break; - } - VLOG(1) << "done."; - return convex_polygons; -} - -CgalPolygon2dContainer ConvexDecomposer::performOptimalConvexDecomposition(const CgalPolygon2d& polygon) const{ - std::vector polygon_buffer; - size_t old_container_size = polygon_buffer.size(); - Traits::Polygon_2 input_polygon; - for (const auto& vertex : polygon.container()){ - input_polygon.insert(input_polygon.vertices_end(),Traits::Point_2(vertex.x(), vertex.y())); - } - CGAL::optimal_convex_partition_2(polygon.vertices_begin(), polygon.vertices_end(), - std::back_inserter(polygon_buffer)); - CHECK_GT(polygon_buffer.size(), old_container_size); - CgalPolygon2dContainer output_polygons; - for (const auto& buffer_polygon : polygon_buffer){ - CgalPolygon2d temp_polygon; - for (const auto& vertex : buffer_polygon.container()){ - temp_polygon.insert(temp_polygon.vertices_end(), CgalPoint2d(vertex.x(), vertex.y())); - } - output_polygons.push_back(temp_polygon); - } - return output_polygons; -} - -CgalPolygon2dContainer ConvexDecomposer::performInnerConvexApproximation(const CgalPolygon2d& polygon) const { - CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); - VLOG(1) << "Polygon under decomposition: "; - printPolygon(polygon); - CgalPolygon2dContainer convex_polygons; - if (polygon.size() == 3) { - convex_polygons.push_back(polygon); - return convex_polygons; - } - const std::multimap dent_locations = detectDentLocations(polygon); - if (dent_locations.empty()) { - // No dents detected, polygon must be convex. - // CGAL convexity check might still fail, since very shallow dents are ignored. - convex_polygons.push_back(polygon); - return convex_polygons; - } - int dent_location = dent_locations.begin()->second; - bool intersection_clockwise_flag = false; - Intersection intersection_clockwise; - bool intersection_counterclockwise_flag = false; - Intersection intersection_counterclockwise; - intersection_clockwise_flag = intersectPolygonWithRay(dent_location, CGAL::COUNTERCLOCKWISE, - polygon, &intersection_counterclockwise); - intersection_counterclockwise_flag = intersectPolygonWithRay(dent_location, CGAL::CLOCKWISE, polygon, &intersection_clockwise); - if (!intersection_clockwise_flag || !intersection_counterclockwise_flag) { - LOG(FATAL) << "At least one intersection of dent ray with polygon failed!"; - } - - // Generate resulting polygons from cut. - // Resulting cut from counter clockwise ray intersection. - CgalPolygon2d polygon_counterclockwise_1 = polygon; - CgalPolygon2d polygon_counterclockwise_2; - - SegmentIntersectionType intersection_type = intersection_counterclockwise.intersection_type_; - - auto first_vertex_to_erase_it = polygon_counterclockwise_1.vertices_begin(); - std::advance(first_vertex_to_erase_it, dent_location); - // Add dent to second polygon. - polygon_counterclockwise_2.push_back(*first_vertex_to_erase_it); - // First vertex to erase is the vertex following the dent. - first_vertex_to_erase_it = next(first_vertex_to_erase_it, polygon_counterclockwise_1); - // Last vertex to erase is the source vertex of the intersecting polygon edge. - auto last_vertex_to_erase_it = polygon_counterclockwise_1.vertices_begin(); - std::advance(last_vertex_to_erase_it, intersection_counterclockwise.edge_source_location_); - // Take next vertex due to exclusive upper limit logic. - last_vertex_to_erase_it = next(last_vertex_to_erase_it, polygon_counterclockwise_1); - // Copy vertices that will be deleted to second polygon. - copyVertices(polygon_counterclockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_2, - polygon_counterclockwise_2.vertices_end()); - - CgalPolygon2dVertexIterator element_behind_deleted_it; - - switch (intersection_type) { - case SegmentIntersectionType::kInterior: - polygon_counterclockwise_2.push_back(intersection_counterclockwise.intersection_point_); - element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); - polygon_counterclockwise_1.insert(element_behind_deleted_it, intersection_counterclockwise.intersection_point_); - break; - case SegmentIntersectionType::kSource: - element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); - // Add source vertex again to polygon, since it coincides with intersection point. - polygon_counterclockwise_1.insert(element_behind_deleted_it, intersection_counterclockwise.intersection_point_); - break; - case SegmentIntersectionType::kTarget: - // The intersection point coincides with the target of the intersecting polygon edge, and has to be added here. - polygon_counterclockwise_2.push_back(intersection_counterclockwise.intersection_point_); - element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_counterclockwise_1); - break; - } - - VLOG(1) << "Finished counter-clockwise cut."; - - // Resulting cut from clockwise ray intersection. - CgalPolygon2d polygon_clockwise_1 = polygon; - CgalPolygon2d polygon_clockwise_2; - - intersection_type = intersection_clockwise.intersection_type_; - - // First vertex, which is pruned off is the target of the intersecting polygon edge. - first_vertex_to_erase_it = polygon_clockwise_1.vertices_begin(); - std::advance(first_vertex_to_erase_it, intersection_clockwise.edge_target_location_); - // Last vertex, which is pruned off is the vertex before the dent. (Past-the-end-logic!) - last_vertex_to_erase_it = polygon_clockwise_1.vertices_begin(); - std::advance(last_vertex_to_erase_it, dent_location); - - switch (intersection_type) { - case SegmentIntersectionType::kInterior: - // First vertex to be added to new polygon is the intersection point. - polygon_clockwise_2.push_back(intersection_clockwise.intersection_point_); - // Added vertices to be deleted to new polygon (Past-the-end-logic!) - copyVertices(polygon_clockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_2, - polygon_clockwise_2.vertices_end()); - // Add dent vertex as well. - polygon_clockwise_2.push_back(*last_vertex_to_erase_it); - // Perform erase operation. - element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_1); - // Add intersection point to polygon. - polygon_clockwise_1.insert(element_behind_deleted_it, intersection_clockwise.intersection_point_); - break; - case SegmentIntersectionType::kSource: - // First vertex to be added to new polygon is source of intersecting polygon edge. - polygon_clockwise_2.push_back(intersection_clockwise.intersection_point_); // Intersection point is equivalent here with source. - // Added vertices to be deleted to new polygon (Past-the-end-logic!) - copyVertices(polygon_clockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_2, - polygon_clockwise_2.vertices_end()); - // Add dent vertex as well. - polygon_clockwise_2.push_back(*last_vertex_to_erase_it); - // Perform erase operation. - element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_1); - break; - case SegmentIntersectionType::kTarget: - // Added vertices to be deleted to new polygon (Past-the-end-logic!) - copyVertices(polygon_clockwise_1, first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_2, - polygon_clockwise_2.vertices_end()); - // Add dent vertex as well. - polygon_clockwise_2.push_back(*last_vertex_to_erase_it); - // Perform erase operation. - element_behind_deleted_it = erase(first_vertex_to_erase_it, last_vertex_to_erase_it, &polygon_clockwise_1); - // Add intersection point to polygon, which is in this case the target vertex of the intersecting polygon edge. - polygon_clockwise_1.insert(element_behind_deleted_it, intersection_clockwise.intersection_point_); - break; - } - - VLOG(1) << "Finished clockwise cut."; - printPolygon(polygon_counterclockwise_1); - printPolygon(polygon_counterclockwise_2); - printPolygon(polygon_clockwise_1); - printPolygon(polygon_clockwise_2); - CHECK(polygon_counterclockwise_1.is_simple()); - CHECK(polygon_counterclockwise_2.is_simple()); - CHECK(polygon_clockwise_1.is_simple()); - CHECK(polygon_clockwise_2.is_simple()); - VLOG(1) << "Started cut area computation..."; - // Take the cut with smallest min. area of resulting polygons. - std::array area = {polygon_counterclockwise_1.area(), polygon_counterclockwise_2.area(), polygon_clockwise_1.area(), - polygon_clockwise_2.area()}; - VLOG(1) << "done."; - const auto min_area_strategy = std::min_element(area.begin(), area.end()); - CgalPolygon2dContainer recursion_1; - CgalPolygon2dContainer recursion_2; - if (std::distance(area.begin(), min_area_strategy) < 2) { - // In this case the counter clockwise intersection leads to less loss in area. - // Perform recursion with this split. - CHECK_EQ(polygon_counterclockwise_1.orientation(), CGAL::COUNTERCLOCKWISE) - << "Polygon orientation wrong! Printing polygon ..." << printPolygonToString(polygon_counterclockwise_1); - recursion_1 = performInnerConvexApproximation(polygon_counterclockwise_1); - CHECK_EQ(polygon_counterclockwise_2.orientation(), CGAL::COUNTERCLOCKWISE) - << "Polygon orientation wrong! Printing polygon ..." << printPolygonToString(polygon_counterclockwise_2); - recursion_2 = performInnerConvexApproximation(polygon_counterclockwise_2); - } else { - // In this case the clockwise intersection leads to less loss in area. - CHECK_EQ(polygon_clockwise_1.orientation(), CGAL::COUNTERCLOCKWISE) - << "Polygon orientation wrong! Printing polygon ..." << printPolygonToString(polygon_clockwise_1); - recursion_1 = performInnerConvexApproximation(polygon_clockwise_1); - CHECK_EQ(polygon_clockwise_2.orientation(), CGAL::COUNTERCLOCKWISE) - << "Polygon orientation wrong! Printing polygon ..." << printPolygonToString(polygon_clockwise_2); - recursion_2 = performInnerConvexApproximation(polygon_clockwise_2); - } - std::move(recursion_1.begin(), recursion_1.end(), std::back_inserter(convex_polygons)); - std::move(recursion_2.begin(), recursion_2.end(), std::back_inserter(convex_polygons)); - VLOG(1) << "Reached bottom!"; - return convex_polygons; -} - -// A dent is a vertex, which lies in a counter-clockwise oriented polygon on the left side of its neighbors. -// Dents cause non-convexity. -std::multimap ConvexDecomposer::detectDentLocations(const CgalPolygon2d& polygon) const { - VLOG(1) << "Starting dent detection..."; - CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); - std::multimap dent_locations; - for (auto source_it = polygon.vertices_begin(); source_it != polygon.vertices_end(); ++source_it){ - auto dent_it = next(source_it, polygon); - auto destination_it = next(dent_it, polygon); - Vector2d source_point = Vector2d(source_it->x(), source_it->y()); - Vector2d destination_point = Vector2d(destination_it->x(), destination_it->y()); - Vector2d direction_vector = destination_point - source_point; - Vector2d test_point = Vector2d(dent_it->x(), dent_it->y()); - if(isPointOnLeftSide(source_point, direction_vector, test_point)){ - double angle = abs(computeAngleBetweenVectors(source_point - test_point, destination_point - test_point)); - // Ignore very shallow dents. Approximate convex decomposition. - if (angle > parameters_.dent_angle_threshold_rad) { - dent_locations.insert(std::make_pair(angle, std::distance(polygon.vertices_begin(), dent_it))); - } - } - } - VLOG(1) << "done."; - return dent_locations; -} diff --git a/convex_plane_decomposition/src/export_utils.cpp b/convex_plane_decomposition/src/export_utils.cpp deleted file mode 100644 index fbcd181e..00000000 --- a/convex_plane_decomposition/src/export_utils.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "convex_plane_decomposition/export_utils.hpp" - -#include - -#include - -namespace convex_plane_decomposition { - -bool exportPointsWithNormalsToCsv(grid_map::GridMap& map, const std::string& normals_layer_prefix, const std::string& layer_height, - const std::string& path) { - std::ofstream output_file; - output_file.open(path + "points_and_normals.csv"); - for (grid_map::GridMapIterator iterator(map); !iterator.isPastEnd(); ++iterator) { - grid_map::Position3 position3; - Eigen::Vector3d point; - Eigen::Vector3d normal; - map.getPosition3(layer_height, *iterator, point); - map.getVector(normals_layer_prefix, *iterator, normal); - output_file << point(0) << ", " << point(1) << ", " << point(2) << ", " << normal(0) << ", " << normal(1) << ", " << normal(2) << "\n"; - } - return true; - } - -} \ No newline at end of file diff --git a/convex_plane_decomposition/src/geometry_utils.cpp b/convex_plane_decomposition/src/geometry_utils.cpp deleted file mode 100644 index cfdbb065..00000000 --- a/convex_plane_decomposition/src/geometry_utils.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "convex_plane_decomposition/geometry_utils.hpp" - -#include - -namespace convex_plane_decomposition { - - double scalarCrossProduct(const Vector2d &leftVector, const Vector2d &rightVector) { - return leftVector.y() * rightVector.x() - leftVector.x() * rightVector.y(); - } - - // Return the non-normalized distance of a 2D-point to a line given by support vector and direction vector. - // Negative distance corresponds to a point on the left of the direction vector - double distanceToLine(const Vector2d &lineSupportVector, - const Vector2d &lineDirectionalVector, - const Vector2d &testPoint) { - Vector2d secondPointOnLine = lineSupportVector + lineDirectionalVector; - return scalarCrossProduct(lineDirectionalVector, testPoint) - + scalarCrossProduct(lineSupportVector, secondPointOnLine); - } - - bool isPointOnRightSideOfLine(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point){ - Vector2d normal_vector(line_direction_vector.y(), (-1.0)*line_direction_vector.x()); - normal_vector.normalize(); - Vector2d point_vector = point - line_support_vector; - return point_vector.transpose() * normal_vector > 0; - } - - bool isPointOnLeftSide(const Vector2d& line_support_vector, const Vector2d& line_direction_vector, const Vector2d& point){ - Vector2d normal_vector(line_direction_vector.y(), (-1.0)*line_direction_vector.x()); - normal_vector.normalize(); - Vector2d point_vector = point - line_support_vector; - return point_vector.dot(normal_vector) < 0; - } - - double computeAngleBetweenVectors(const Vector2d& first_vector, const Vector2d& second_vector) { - double scalar_product = first_vector.transpose() * second_vector; - return acos(abs(scalar_product) / (first_vector.norm() * second_vector.norm())); - } - - bool intersectLineSegmentWithLineSegment(const Vector2d& segment_1_source, const Vector2d& segment_1_target, - const Vector2d& segment_2_source, const Vector2d& segment_2_target, - Vector2d* intersection_point) { - CHECK_NOTNULL(intersection_point); - Vector2d segment_1_direction = segment_1_target - segment_1_source; - Vector2d segment_2_direction = segment_2_target - segment_2_source; - Matrix2d A; - A.col(0) = segment_1_direction; - A.col(1) = -segment_2_direction; - Vector2d b = segment_2_source - segment_1_source; - auto householder_qr = A.fullPivHouseholderQr(); - if (householder_qr.rank() < 2){ - // Check whether segment and ray overlap. - Vector2d p_ray_source_segment_source = segment_2_source - segment_1_source; - Vector2d ray_parameter_solution = Vector2d(p_ray_source_segment_source.x() / segment_1_direction.x(), - p_ray_source_segment_source.y() / segment_1_direction.y()); - constexpr double kSolutionDeviation = 0.0001; - if (abs(ray_parameter_solution.x() - ray_parameter_solution.y()) < kSolutionDeviation){ - double parameter_solution_tmp = ray_parameter_solution.mean(); - if (parameter_solution_tmp < 0){ - return false; - } - CHECK_GT(parameter_solution_tmp, 0); - Vector2d p_ray_source_segment_target = segment_2_target - segment_1_source; - ray_parameter_solution = Vector2d(p_ray_source_segment_target.x() / segment_1_direction.x(), - p_ray_source_segment_target.y() / segment_1_direction.y()); - // If ray is parallel (rank loss) and source point lies on ray, then target point has to as well. - CHECK(abs(ray_parameter_solution.x() - ray_parameter_solution.y()) < kSolutionDeviation); - if(ray_parameter_solution.mean() < 0){ - return false; - } - if (ray_parameter_solution.mean() < parameter_solution_tmp) { - *intersection_point = segment_2_target; - } else { - *intersection_point = segment_2_source; - } - return true; - } - return false; - } - Vector2d solution = A.inverse() * b; // householder_qr.solve(b); - Vector2d ray_solution = segment_1_source + solution(0) * segment_2_direction; - Vector2d segment_solution = segment_2_source + solution(1) * segment_2_direction; - if (solution(0) < 0 || solution(0) > 1 || solution(1) < 0 || solution(1) > 1) { - return false; - } - *intersection_point = segment_solution; - return true; - } - - double distanceBetweenPoints(const Vector2d& first, const Vector2d& second){ - return (second - first).norm(); - } - - double getDistanceOfPointToLineSegment(const Vector2d& point, const Vector2d& source, const Vector2d& target){ - return getDistanceAndClosestPointOnLineSegment(point, source, target).first; - } - - std::pair getDistanceAndClosestPointOnLineSegment(const Vector2d& point, const Vector2d& source, const Vector2d& target){ - const double segment_squared_length = (target - source).squaredNorm(); - if (segment_squared_length == 0.0){ - return std::make_pair(distanceBetweenPoints(point, source), source); - } - const double t = (point - source).dot(target - source) / segment_squared_length; - if (t > 1.0){ - return std::make_pair((target - point).norm(), target); - } else if (t < 0.0){ - return std::make_pair((source - point).norm(), source); - } else { - const Vector2d point_temp = abs(t)*(target - source); - return std::make_pair((point_temp - point).norm(), point_temp); - } - } - -} diff --git a/convex_plane_decomposition/src/pipeline.cpp b/convex_plane_decomposition/src/pipeline.cpp deleted file mode 100644 index b605c50d..00000000 --- a/convex_plane_decomposition/src/pipeline.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "convex_plane_decomposition/pipeline.hpp" - -using namespace convex_plane_decomposition; - -Pipeline::Pipeline(const PipelineParameters& pipeline_parameters, const GridMapParameters& grid_map_parameters) - : pipeline_parameters_(pipeline_parameters), - grid_map_parameters_(grid_map_parameters), - sliding_window_plane_extractor_(grid_map_parameters_.map, - grid_map_parameters_.resolution, grid_map_parameters_.layer_height, - pipeline_parameters_.sliding_window_plane_extractor_parameters, pipeline_parameters_.sliding_window_plane_extractor_parameters.ransac_parameters), - plane_factory_(grid_map_parameters_.map, pipeline_parameters_.plane_factory_parameters){ - VLOG(1) << "Starting plane extraction..."; - sliding_window_plane_extractor_.runExtraction(); - VLOG(1) << "done"; - plane_factory_.createPlanesFromLabeledImageAndPlaneParameters(sliding_window_plane_extractor_.getLabeledImage(), - sliding_window_plane_extractor_.getNumberOfExtractedPlanes(), - sliding_window_plane_extractor_.getLabelPlaneParameterMap()); - plane_factory_.decomposePlanesInConvexPolygons(); -} - -Polygon3dVectorContainer Pipeline::getConvexPolygons() const{ - return plane_factory_.getConvexPolygonsInWorldFrame(); -} - -Polygon3dVectorContainer Pipeline::getPlaneContours() const{ - return plane_factory_.getPlaneContoursInWorldFrame(); -} diff --git a/convex_plane_decomposition/src/plane.cpp b/convex_plane_decomposition/src/plane.cpp deleted file mode 100644 index c8b1f4b5..00000000 --- a/convex_plane_decomposition/src/plane.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "convex_plane_decomposition/plane.hpp" - -namespace convex_plane_decomposition{ - - bool Plane::setNormalAndSupportVector(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector){ - normal_vector_ = normal_vector; - support_vector_ = support_vector; - return true; - } - -} diff --git a/convex_plane_decomposition/src/plane_factory.cpp b/convex_plane_decomposition/src/plane_factory.cpp deleted file mode 100644 index 71102881..00000000 --- a/convex_plane_decomposition/src/plane_factory.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "convex_plane_decomposition/plane_factory.hpp" - -using namespace convex_plane_decomposition; - -void PlaneFactory::computeMapTransformation(){ - Eigen::Vector2i map_size = map_.getSize(); - CHECK(map_.getPosition(Eigen::Vector2i::Zero(), map_offset_)); - Eigen::Vector2d lower_left_cell_position; - CHECK(map_.getPosition(Eigen::Vector2i(map_size.x() - 1, 0), lower_left_cell_position)); - Eigen::Vector2d upper_right_cell_position; - CHECK(map_.getPosition(Eigen::Vector2i(0, map_size.y() - 1), upper_right_cell_position)); - transformation_xy_to_world_frame_.col(0) = (lower_left_cell_position - map_offset_).normalized(); - transformation_xy_to_world_frame_.col(1) = (upper_right_cell_position - map_offset_).normalized(); -} - -void PlaneFactory::createPlanesFromLabeledImageAndPlaneParameters(const cv::Mat& labeled_image, const int number_of_labels, - const std::map& plane_parameters){ - CHECK_GT(number_of_labels, 0); - Polygonizer polygonizer(parameters_.polygonizer_parameters); - for (int label = 1; label < number_of_labels; ++label){ - if (plane_parameters.find(label) == plane_parameters.end()){ - continue; - } - cv::Mat binary_image(labeled_image.size(), CV_8UC1); - binary_image = labeled_image == label; - const CgalPolygon2d plane_contour = polygonizer.runPolygonizationOnBinaryImage(binary_image); - const auto plane_parameter_it = plane_parameters.find(label); - CHECK(plane_parameter_it != plane_parameters.end()) << "Label not contained in plane parameter container!"; - if (plane_contour.is_empty()) { - LOG(INFO) << "Dropping plane, polygon empty!"; - continue; - } - if (isPlaneInclinationBelowThreshold(plane_parameter_it->second.normal_vector)){ - planes_.emplace_back(plane_contour, plane_parameter_it->second); - } else { - LOG(INFO) << "Dropping plane due to exceeded inclination threshold!"; - } - } -} - -bool PlaneFactory::isPlaneInclinationBelowThreshold(const Eigen::Vector3d& plane_normal_vector) const { - const Eigen::Vector3d z_axis(0,0,1); - return std::atan2(1.0, z_axis.dot(plane_normal_vector)) < (parameters_.plane_inclination_threshold_degrees / 180.0 * M_PI); -} - -void PlaneFactory::decomposePlanesInConvexPolygons(){ - ConvexDecomposer convex_decomposer(parameters_.convex_decomposer_parameters); - for(Plane& plane : planes_){ - CgalPolygon2dContainer& convex_polygons = plane.getConvexPolygonsMutable(); - convex_polygons = convex_decomposer.performConvexDecomposition(plane.getOuterPolygon()); - } -} - -Polygon3dVectorContainer PlaneFactory::getConvexPolygonsInWorldFrame() const{ - Polygon3dVectorContainer polygon_buffer; - for(const Plane& plane : planes_){ - Polygon3dVectorContainer temp_polygon_buffer = convertPlanePolygonsToWorldFrame(plane.getConvexPolygons(), plane.getPlaneParameters()); - std::move(temp_polygon_buffer.begin(), temp_polygon_buffer.end(), std::back_inserter(polygon_buffer)); - } - return polygon_buffer; -} - -Polygon3dVectorContainer PlaneFactory::getPlaneContoursInWorldFrame() const{ - Polygon3dVectorContainer polygon_buffer; - for(const Plane& plane : planes_){ - Polygon3dVectorContainer temp_polygon_buffer = convertPlanePolygonToWorldFrame(plane.getOuterPolygon(), plane.getPlaneParameters()); - std::move(temp_polygon_buffer.begin(), temp_polygon_buffer.end(), std::back_inserter(polygon_buffer)); - } - return polygon_buffer; -} - -Polygon3dVectorContainer PlaneFactory::convertPlanePolygonToWorldFrame(const CgalPolygon2d& polygon, const PlaneParameters& plane_parameters) const{ - Polygon3dVectorContainer output_polygons; - CHECK(!polygon.is_empty()); - Polygon3d polygon_temp; - for (const auto& point : polygon){ - polygon_temp.push_back(convertPlanePointToWorldFrame(point, plane_parameters)); - } - output_polygons.push_back(polygon_temp); - return output_polygons; -} - -Polygon3dVectorContainer PlaneFactory::convertPlanePolygonsToWorldFrame(const CgalPolygon2dContainer& polygons, const PlaneParameters& plane_parameters) const{ - CHECK(!polygons.empty()) << "Input polygon container empty!"; - Polygon3dVectorContainer output_polygons; - for (const auto& polygon : polygons){ - CHECK(!polygon.is_empty()); - Polygon3d polygon_temp; - for (const auto& point : polygon){ - polygon_temp.push_back(convertPlanePointToWorldFrame(point, plane_parameters)); - } - output_polygons.push_back(polygon_temp); - } - return output_polygons; -} - -Eigen::Vector3d PlaneFactory::convertPlanePointToWorldFrame(const CgalPoint2d& point, const PlaneParameters& plane_parameters) const { - Eigen::Vector2d temp_point(point.x(), point.y()); - temp_point = transformation_xy_to_world_frame_ * temp_point; - temp_point = temp_point + map_offset_; - CHECK(std::isfinite(temp_point.x())) << "Not finite x value!"; - CHECK(std::isfinite(temp_point.y())) << "Not finite y value!"; - const double z = (-(temp_point.x() - plane_parameters.support_vector.x()) * plane_parameters.normal_vector.x() - - (temp_point.y() - plane_parameters.support_vector.y()) * plane_parameters.normal_vector.y()) / - plane_parameters.normal_vector(2) + - plane_parameters.support_vector(2); - CHECK(std::isfinite(z)) << "Not finite z value!"; - return {temp_point.x(), temp_point.y(), z}; -} diff --git a/convex_plane_decomposition/src/polygon.cpp b/convex_plane_decomposition/src/polygon.cpp deleted file mode 100644 index 134a3159..00000000 --- a/convex_plane_decomposition/src/polygon.cpp +++ /dev/null @@ -1,537 +0,0 @@ -#include "convex_plane_decomposition/polygon.hpp" - -namespace convex_plane_decomposition { - - bool doPolygonAndSegmentIntersect(const CgalPolygon2d& polygon, const CgalSegment2d& segment, bool print_flag){ - for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it){ - auto next_vertex_it = std::next(vertex_it); - if (next_vertex_it == polygon.vertices_end()){ - next_vertex_it = polygon.vertices_begin(); - } - CgalSegment2d test_segment(*vertex_it, *next_vertex_it); - CGAL::cpp11::result_of::type - result = intersection(test_segment, segment); - if (result) { - if (const CgalSegment2d *s = boost::get(&*result)) { - if (print_flag) { - VLOG(1) << "Intersection over segment: " << *s; - } - return true; - } else { - const CgalPoint2d *p = boost::get(&*result); - if (print_flag) { - VLOG(1) << "Intersection in in point: " << *p; - } - return true; - } - } - } - return false; - } - - int getClosestPolygonVertexPosition(const CgalPolygon2d& polygon, const CgalPoint2d& point){ - int closest_vertex_position = 0; - double smallest_distance = std::numeric_limits::infinity(); - int position = 0; - for(auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it){ - double temp_distance = squared_distance(*vertex_it, point); - if (temp_distance < smallest_distance){ - smallest_distance = temp_distance; - closest_vertex_position = position; - } - ++position; - } - return closest_vertex_position; - } - - void getVertexPositionsInAscendingDistanceToPoint(const CgalPolygon2d& polygon, const CgalPoint2d& point, - std::multimap* vertex_positions){ - CHECK_NOTNULL(vertex_positions); - int position = 0; - for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it) { - vertex_positions->insert(std::pair(squared_distance(*vertex_it, point), position)); - ++position; - } - } - - void getSegmentNormalVector(const CgalSegment2d& segment, Eigen::Vector2d* normal_vector){ - CHECK_NOTNULL(normal_vector); - const auto first_vertex = segment.source(); - const auto second_vertex = segment.target(); - double d_x = second_vertex.x() - first_vertex.x(); - double d_y = second_vertex.y() - first_vertex.y(); - Eigen::Vector2d normal(d_y, -d_x); - normal.normalize(); - *normal_vector = normal; - } - - void approximateContour(CgalPolygon2d* polygon, int max_number_of_iterations, double relative_local_area_threshold, - double absolute_local_area_threshold, double relative_total_area_threshold, - double absolute_total_area_threshold) { - CHECK_NOTNULL(polygon); - if (polygon->size() < 4) { - return; - } - CHECK(polygon->orientation() == CGAL::COUNTERCLOCKWISE); - int old_size; - auto first_vertex_it = polygon->vertices_begin(); - auto second_vertex_it = std::next(first_vertex_it); - auto third_vertex_it = std::next(second_vertex_it); - double area = polygon->area(); - int number_of_iterations = 0; - while (number_of_iterations < max_number_of_iterations ) { - old_size = polygon->size(); - if (polygon->size() < 4) { - break; - } - Vector2d first_point(first_vertex_it->x(), first_vertex_it->y()); - Vector2d second_point(second_vertex_it->x(), second_vertex_it->y()); - Vector2d third_point(third_vertex_it->x(), third_vertex_it->y()); - VLOG(2) << "Got here!"; - if (isPointOnRightSideOfLine(first_point, third_point - first_point, second_point)) { - VLOG(2) << "Point on right side!"; - double a = (third_point - first_point).norm(); - double b = (second_point - third_point).norm(); - double c = (first_point - second_point).norm(); - const double triangle_area = computeTriangleArea(a, b, c); - CHECK(isfinite(triangle_area)) << "Area: " << triangle_area << ", a: " << a << ", b: " << b << ", c: " << c; - CHECK_GE(triangle_area, 0.0); - if ((triangle_area < relative_local_area_threshold * area) && (triangle_area < absolute_local_area_threshold)) { - VLOG(2) << "Area sufficiently small!"; - CgalPolygon2d new_polygon(*polygon); - int vertex_position_offset = std::distance(polygon->vertices_begin(), second_vertex_it); - CgalPolygon2dVertexIterator tmp_iterator = new_polygon.vertices_begin(); - std::advance(tmp_iterator, vertex_position_offset); - VLOG(2) << "Before erase call!"; - new_polygon.erase(tmp_iterator); - VLOG(2) << "After ease call!"; - if (new_polygon.is_simple() && (new_polygon.orientation() == CGAL::COUNTERCLOCKWISE) && - abs(new_polygon.area() - area) < relative_total_area_threshold * area && - abs(new_polygon.area() - area) < absolute_total_area_threshold) { - CHECK_LE(triangle_area, area); - first_vertex_it = polygon->erase(second_vertex_it); - if (first_vertex_it == polygon->vertices_end()) { - first_vertex_it = polygon->vertices_begin(); - } - second_vertex_it = next(first_vertex_it, *polygon); - third_vertex_it = next(second_vertex_it, *polygon); - if ((std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), second_vertex_it)) || - (std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), third_vertex_it)) || - (std::distance(polygon->begin(), second_vertex_it) >= std::distance(polygon->begin(), third_vertex_it))) { - ++number_of_iterations; - } - VLOG(2) << "Removed one vertex!"; - continue; - } - } - } - first_vertex_it = second_vertex_it; - second_vertex_it = third_vertex_it; - third_vertex_it = next(second_vertex_it, *polygon); - VLOG(2) << "Got to bottom! Number of iterations: " << std::distance(polygon->begin(), first_vertex_it) << " " - << std::distance(polygon->begin(), second_vertex_it) << " " << std::distance(polygon->begin(), third_vertex_it); - if (std::distance(polygon->begin(), first_vertex_it) >= std::distance(polygon->begin(), second_vertex_it)) { - ++number_of_iterations; - } - } - } - - double computeTriangleArea(double side_length_a, double side_length_b, double side_length_c){ - const double s = (side_length_a + side_length_b + side_length_c) / 2.0; - CHECK_GT(s, 0.0); - double sqrt_argument = s * (s-side_length_a) * (s - side_length_b) * (s - side_length_c); - if (abs(sqrt_argument) < 1e-6){ - sqrt_argument = 0.0; - } - CHECK_GE(sqrt_argument, 0.0); - return sqrt(sqrt_argument); - } - - CgalPolygon2dVertexIterator next(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon){ - if (std::next(iterator) == polygon.vertices_end()){ - return polygon.vertices_begin(); - } else { - return std::next(iterator); - } - } - - // Retrieves the following vertex in polygon, including wrap around, when last polygon reached. - // In this case the output flag is set to true. - bool next(const CgalPolygon2dVertexIterator& iterator, CgalPolygon2dVertexIterator& output_iterator, const CgalPolygon2d& polygon){ - if (std::next(iterator) == polygon.vertices_end()){ - output_iterator = polygon.vertices_begin(); - return true; - } else { - output_iterator = std::next(iterator); - return false; - } - } - - CgalPolygon2dVertexIterator previous(const CgalPolygon2dVertexIterator& iterator, const CgalPolygon2d& polygon){ - if (iterator == polygon.vertices_begin()){ - return std::prev(polygon.vertices_end()); - } else { - return std::prev(iterator); - } - } - - void upSampleLongEdges(CgalPolygon2d* polygon){ - CHECK_NOTNULL(polygon); - for (auto vertex_it = polygon->vertices_begin(); vertex_it != polygon->vertices_end(); ++vertex_it) { - double edge_length = getEdgeLength(vertex_it, *polygon); - CHECK_GT(edge_length, 0); - double kEdgeLengthThreshold = 0.5; - if (edge_length > 2 * kEdgeLengthThreshold){ - int number_of_intervals = static_cast(round(ceil(edge_length / kEdgeLengthThreshold))); - CgalPoint2d source_point = *vertex_it; - CgalPoint2d destination_point = *(next(vertex_it, *polygon)); - CHECK_NE(number_of_intervals , 0); - CgalPoint2d direction_vector = CgalPoint2d((destination_point.x() - source_point.x()) / - static_cast(number_of_intervals),(destination_point.y() - source_point.y()) / - static_cast(number_of_intervals)); - - CHECK_LE(abs(sqrt(pow(direction_vector.x(),2) + pow(direction_vector.y(),2))),edge_length); - std::cout << "Direction vector: " << direction_vector << std::endl; - auto inserter_it = next(vertex_it, *polygon); - for (int i = 0; i < number_of_intervals-1; ++i){ - CgalVector2d new_point = *inserter_it - direction_vector; - inserter_it = polygon->insert(inserter_it, CgalPoint2d(new_point.x(), new_point.y())); - } - std::advance(vertex_it, number_of_intervals - 1); - } - } - } - - double getEdgeLength(const CgalPolygon2dVertexIterator& source, const CgalPolygon2d& polygon) { - CgalPoint2d source_point = *source; - CgalPoint2d destination_point = *(next(source, polygon)); - return abs(sqrt((destination_point.x() - source_point.x()) * (destination_point.x() - source_point.x()) - + (destination_point.y() - source_point.y()) * (destination_point.y() - source_point.y()))); - } - - // Counter-clockwise orientation: ray source vertex is previous vertex in counter-clockwise polygon orientation. - bool intersectPolygonWithRay(int ray_target_location, CGAL::Orientation orientation, const CgalPolygon2d& polygon, - Intersection* output_intersection) { - CHECK_NOTNULL(output_intersection); - CHECK(orientation == CGAL::COUNTERCLOCKWISE || orientation == CGAL::CLOCKWISE); - CHECK(polygon.orientation() == CGAL::COUNTERCLOCKWISE); - Intersection intersection_tmp; - constexpr double kLargeDistanceValue = 1000; - double min_distance = kLargeDistanceValue; - bool one_intersection_at_least = false; - auto vertex_it = polygon.vertices_begin(); - std::advance(vertex_it, ray_target_location); - auto ray_source_it = vertex_it; - auto ray_target_it = vertex_it; - if (orientation == CGAL::COUNTERCLOCKWISE) { - ray_source_it = previous(vertex_it, polygon); - } else { - vertex_it = next(vertex_it, polygon); - ray_source_it = vertex_it; - } - vertex_it = next(vertex_it, polygon); - const CgalPoint2d ray_source = *ray_source_it; - VLOG(1) << "Source ray:" << ray_source; - const CgalPoint2d ray_target = *ray_target_it; - const CgalRay2d ray(*ray_target_it, *ray_target_it - *ray_source_it); - VLOG(1) << "Ray target: " << ray.source(); - VLOG(1) << "Ray direction: " << ray.direction(); - CHECK(!ray.is_degenerate()); - // Do not intersect with adjacent edges since they intersect already in common vertex. - auto condition_it = ray_source_it; - if (orientation == CGAL::CLOCKWISE) { - condition_it = ray_target_it; - } - int number_of_polygon_edges_visited = 0; - while (next(vertex_it, polygon) != condition_it) { - ++number_of_polygon_edges_visited; - const CgalPoint2d segment_source = *vertex_it; - const auto segment_target_it = next(vertex_it, polygon); - const CgalPoint2d segment_target = *segment_target_it; - VLOG(1) << "Segment under test: Source: " << segment_source << " Target: " << segment_target; - const CgalSegment2d segment(*vertex_it, *segment_target_it); - RaySegmentIntersection intersection; - if (doRayAndSegmentIntersect(ray, segment, &intersection)) { - VLOG(1) << "Intersection type: " << static_cast(intersection.intersection_location); - VLOG(1) << "Intersection point:" << intersection.intersection_point; - VLOG(1) << segment_source; - const double current_distance = sqrt((ray_target - intersection.intersection_point).squared_length()); - // Take first intersection on ray. - if (current_distance < min_distance) { - one_intersection_at_least = true; - min_distance = current_distance; - intersection_tmp.setAllMembers(std::distance(polygon.vertices_begin(), vertex_it), - std::distance(polygon.vertices_begin(), segment_target_it), intersection.intersection_point, - intersection.intersection_location); - } - } - vertex_it = next(vertex_it, polygon); - } - CHECK_EQ(number_of_polygon_edges_visited, polygon.size() - 3); - if (!one_intersection_at_least) { - return false; - } - *output_intersection = intersection_tmp; - return true; - } - - // Erases vertices [first, last), takes warp around into account. - CgalPolygon2dVertexIterator erase(CgalPolygon2dVertexIterator first, CgalPolygon2dVertexIterator last, - CgalPolygon2d* polygon){ - CHECK_NOTNULL(polygon); - CHECK(first != last); - if ((std::distance(polygon->vertices_begin(), last) - std::distance(polygon->vertices_begin(), first)) > 0){ - // std::cout << (std::distance(polygon->vertices_begin(), last) - std::distance(polygon->vertices_begin(), first)) << std::endl; - return polygon->erase(first, last); - } else { - int last_iterator_distance = std::distance(polygon->vertices_begin(), last); - polygon->erase(first, polygon->vertices_end()); - auto erase_iterator = polygon->vertices_begin(); - std::advance(erase_iterator, last_iterator_distance); - return polygon->erase(polygon->vertices_begin(), erase_iterator); - } - } - - // [first last) are copied to new_polygon before the position indicated by insert_position. - // Takes wrap around into account - void copyVertices(const CgalPolygon2d& old_polygon, const CgalPolygon2dVertexIterator first, const CgalPolygon2dVertexIterator last, - CgalPolygon2d* new_polygon, const CgalPolygon2dVertexIterator insert_position){ - CHECK_NOTNULL(new_polygon); - CHECK(first != last); - if (std::distance(old_polygon.vertices_begin(), last) - std::distance(old_polygon.vertices_begin(), first) > 0){ - return new_polygon->insert(insert_position, first, last); - } else { - int insert_position_distance = std::distance(new_polygon->vertices_begin(), insert_position); - int number_of_inserted_elements = std::distance(first, old_polygon.vertices_end()); - new_polygon->insert(insert_position, first, old_polygon.vertices_end()); - CgalPolygon2dVertexIterator insert_position_mutable = new_polygon->vertices_begin(); - std::advance(insert_position_mutable, insert_position_distance + number_of_inserted_elements); - new_polygon->insert(insert_position_mutable, old_polygon.vertices_begin(), last); - return; - } - } - - void printPolygon(const CgalPolygon2d& polygon) { - std::cout << "Polygon has " << polygon.size() << " vertices." << std::endl; - for (const CgalPoint2d& vertex : polygon) { - std::cout << vertex.x() << " , " << vertex.y() << " ; " << std::endl; - } - } - - std::string printPolygonToString(const CgalPolygon2d& polygon) { - std::string string; - string = "Polygon has " + std::to_string(polygon.size()) + " vertices. \n"; - for (const CgalPoint2d& vertex : polygon) { - string += std::to_string(vertex.x()) + " , " + std::to_string(vertex.y()) + " ;\n"; - } - return string; - } - - std::pair getIndicesOfClosestVertexPair(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon) { - CHECK_GT(first_polygon.size(), 0); - CHECK_GT(second_polygon.size(), 0); - std::multimap> buffer = getClosestVertexPairsOrdered(first_polygon, second_polygon); - CHECK(!buffer.empty()); - return buffer.begin()->second; - } - - std::multimap> getClosestVertexPairsOrdered(const CgalPolygon2d& first_polygon, - const CgalPolygon2d& second_polygon) { - CHECK_GT(first_polygon.size(), 0); - CHECK_GT(second_polygon.size(), 0); - std::multimap> buffer; - for (auto vertex_it = first_polygon.vertices_begin(); vertex_it != first_polygon.vertices_end(); ++vertex_it){ - int first_vertex_index = std::distance(first_polygon.vertices_begin(), vertex_it); - double distance = std::numeric_limits::max(); - int second_vertex_index = 0; - for (auto second_vertex_it = second_polygon.vertices_begin(); second_vertex_it != second_polygon.vertices_begin(); ++second_vertex_it){ - const double temp_distance = sqrt(static_cast(*vertex_it - *second_vertex_it).squared_length()); - if (temp_distance < distance){ - distance = temp_distance; - second_vertex_index = std::distance(second_polygon.vertices_begin(), second_vertex_it); - } - } - buffer.insert(std::make_pair(distance, std::make_pair(first_vertex_index, second_vertex_index))); - } - return buffer; - } - - CgalPoint2d getPolygonVertexAtIndex(const CgalPolygon2d& polygon, int index){ - CHECK_GT(index, 0); - CHECK_LT(index, polygon.size()); - auto vertex_it = polygon.vertices_begin(); - std::advance(vertex_it, index); - return *vertex_it; - } - - bool doPointAndPolygonIntersect(const CgalPolygon2d& polygon, const CgalPoint2d& point, int& segment_target_vertex_index){ - for (auto vertex_it = polygon.vertices_begin(); vertex_it != polygon.vertices_end(); ++vertex_it) { - auto next_vertex_it = std::next(vertex_it); - if (next_vertex_it == polygon.vertices_end()) { - next_vertex_it = polygon.vertices_begin(); - } - CgalSegment2d test_segment(*vertex_it, *next_vertex_it); - if (test_segment.has_on(point)){ - segment_target_vertex_index = std::distance(polygon.vertices_begin(), next_vertex_it); - return true; - } - } - return false; - } - - std::pair getVertexPositionsWithHighestHoleSlConcavityMeasure(const CgalPolygon2d& polygon){ - CHECK(polygon.size() > 2); - std::multimap> slConcavityScoreMap; - const int number_of_vertices = polygon.size(); - for (int first_vertex_counter = 0; first_vertex_counter < number_of_vertices - 1; ++first_vertex_counter){ - const auto& vertex_container = polygon.container(); - const CgalPoint2d& first_vertex = vertex_container.at(first_vertex_counter); - for (int second_vertex_counter = first_vertex_counter + 1; second_vertex_counter < number_of_vertices; ++second_vertex_counter){ - const CgalPoint2d& second_vertex = vertex_container.at(second_vertex_counter); - const double vertex_squared_distance = (first_vertex - second_vertex).squared_length(); - slConcavityScoreMap.insert(std::make_pair(vertex_squared_distance, std::make_pair(first_vertex_counter, second_vertex_counter))); - } - } - return slConcavityScoreMap.begin()->second; - } - - // Attention, if point overlaps with existing vertex. - std::pair getClosestPointAndSegmentOnPolygonToPoint(const CgalPoint2d& point, const CgalPolygon2d& polygon){ - CHECK_GT(polygon.size(), 2); - std::multimap> distance_to_segment_closest_point_map; - int edge_counter = 0; - for(auto edge_it = polygon.edges_begin(); edge_it != polygon.edges_end(); ++edge_it){ - if (edge_it->has_on(point)){ - distance_to_segment_closest_point_map.insert(std::make_pair(0.0, std::make_pair(edge_counter, Vector2d(point.x(), point.y())))); - ++edge_counter; - continue; - } - const Vector2d source(edge_it->source().x(), edge_it->source().y()); - const Vector2d target(edge_it->target().x(), edge_it->target().y()); - const Vector2d test_point(point.x(), point.y()); - std::pair distance_closest_point = getDistanceAndClosestPointOnLineSegment(test_point, source, target); - distance_to_segment_closest_point_map.insert(std::make_pair(distance_closest_point.first, std::make_pair(edge_counter, distance_closest_point.second))); - ++edge_counter; - } - const int closest_edge_index = distance_to_segment_closest_point_map.begin()->second.first; - const CgalPoint2d closest_point(distance_to_segment_closest_point_map.begin()->second.second.x(), distance_to_segment_closest_point_map.begin()->second.second.y()); - return std::make_pair(closest_edge_index, closest_point); - } - - std::vector> getCommonVertexPairIndices(const CgalPolygon2d& first_polygon, const CgalPolygon2d& second_polygon){ - std::vector> return_buffer; - for(int first_polygon_vertex_index = 0; first_polygon_vertex_index < first_polygon.container().size(); ++first_polygon_vertex_index){ - for(int second_polygon_vertex_index = 0; second_polygon_vertex_index < second_polygon.container().size(); ++second_polygon_vertex_index){ - if (first_polygon.container().at(first_polygon_vertex_index) == second_polygon.container().at(second_polygon_vertex_index)){ - return_buffer.push_back(std::make_pair(first_polygon_vertex_index, second_polygon_vertex_index)); - } - } - } - return return_buffer; - } - - std::vector getVertexIndicesOfFirstPolygonContainedInSecondPolygonContour(const CgalPolygon2d& first_polygon, - const CgalPolygon2d& second_polygon) { - std::vector return_buffer; - for (int vertex_index = 0; vertex_index < first_polygon.container().size(); ++vertex_index) { - if (second_polygon.has_on_boundary(first_polygon.container().at(vertex_index))) { - return_buffer.push_back(vertex_index); - } - } - return return_buffer; - } - - bool doRayAndSegmentIntersect(const CgalRay2d& ray, const CgalSegment2d& segment, RaySegmentIntersection* intersection) { - constexpr double kSquaredToleranceMeters = 1e-8; - CGAL::Cartesian_converter to_exact; - CGAL::Cartesian_converter to_inexact; - CGAL::cpp11::result_of::type result = - CGAL::intersection(to_exact(ray), to_exact(segment)); - - if (result) { - if (const EKernel::Segment_2* ek_segment = boost::get(&*result)) { - VLOG(1) << "Segment intersection."; - VLOG(1) << "Segment source: " << segment.source(); - VLOG(1) << "Segment target: " << segment.target(); - VLOG(1) << "Ray point: " << ray.source(); - VLOG(1) << "Ray direction: " << ray.direction(); - if ((ray.source() - segment.source()).squared_length() < (ray.source() - segment.target()).squared_length()) { - intersection->intersection_location = SegmentIntersectionType::kSource; - intersection->intersection_point = segment.source(); - } else { - intersection->intersection_location = SegmentIntersectionType::kTarget; - intersection->intersection_point = segment.target(); - } - } else { - VLOG(1) << "Point intersection."; - VLOG(1) << "Segment source: " << segment.source(); - VLOG(1) << "Segment target: " << segment.target(); - VLOG(1) << "Ray point: " << ray.source(); - VLOG(1) << "Ray direction: " << ray.direction(); - const EKernel::Point_2* ek_point = boost::get(&*result); - const CgalPoint2d intersection_point = to_inexact(*ek_point); - if ((intersection_point - segment.source()).squared_length() <= kSquaredToleranceMeters) { - intersection->intersection_location = SegmentIntersectionType::kSource; - intersection->intersection_point = segment.source(); - } else if ((intersection_point - segment.target()).squared_length() <= kSquaredToleranceMeters) { - intersection->intersection_location = SegmentIntersectionType::kTarget; - intersection->intersection_point = segment.target(); - } else { - intersection->intersection_location = SegmentIntersectionType::kInterior; - intersection->intersection_point = intersection_point; - } - } - return true; - } - constexpr double kToleranceMeters = 1e-6; - const Vector2d ray_source = Vector2d(ray.source().x(), ray.source().y()); - const Vector2d ray_direction = Vector2d(ray.direction().dx(), ray.direction().dy()).normalized(); - const Vector2d segment_source = Vector2d(segment.source().x(), segment.source().y()); - const Vector2d segment_target = Vector2d(segment.target().x(), segment.target().y()); - const Vector2d p_ray_source__segment_source = segment_source - ray_source; - const Vector2d p_ray_source__segment_target = segment_target - ray_source; - const double segment_source_projection = p_ray_source__segment_source.dot(ray_direction); - const double segment_target_projection = p_ray_source__segment_target.dot(ray_direction); - const Vector2d segment_source_projection_point = ray_source + segment_source_projection * ray_direction; - const Vector2d segment_target_projection_point = ray_source + segment_target_projection * ray_direction; - if (segment_source_projection >= 0.0 && segment_target_projection >= 0.0) { - if ((segment_source_projection_point - segment_source).norm() < kToleranceMeters && - (segment_target_projection_point - segment_target).norm() < kToleranceMeters) { - // Source and target lie on ray. Determine, which point is closer. - if ((segment_source_projection_point - ray_source).norm() <= (segment_target_projection_point - ray_source).norm()) { - intersection->intersection_location = SegmentIntersectionType::kSource; - intersection->intersection_point = segment.source(); - return true; - } else { - intersection->intersection_location = SegmentIntersectionType::kTarget; - intersection->intersection_point = segment.target(); - return true; - } - } else if ((segment_source_projection_point - segment_source).norm() < kToleranceMeters) { - // Only source lies on ray. - intersection->intersection_location = SegmentIntersectionType::kSource; - intersection->intersection_point = segment.source(); - return true; - } else if ((segment_target_projection_point - segment_target).norm() < kToleranceMeters) { - // Only target lies on ray. - intersection->intersection_location = SegmentIntersectionType::kTarget; - intersection->intersection_point = segment.target(); - return true; - } - } else if (segment_source_projection >= 0.0) { - if ((segment_source_projection_point - segment_source).norm() < kToleranceMeters) { - intersection->intersection_location = SegmentIntersectionType::kSource; - intersection->intersection_point = segment.source(); - return true; - } - } else if (segment_target_projection >= 0.0) { - if ((segment_target_projection_point - segment_target).norm() < kToleranceMeters) { - intersection->intersection_location = SegmentIntersectionType::kTarget; - intersection->intersection_point = segment.target(); - return true; - } - } - return false; - } - - } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/src/polygonizer.cpp b/convex_plane_decomposition/src/polygonizer.cpp deleted file mode 100644 index 41084675..00000000 --- a/convex_plane_decomposition/src/polygonizer.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#include "convex_plane_decomposition/polygonizer.hpp" - -using namespace convex_plane_decomposition; - -PolygonWithHoles Polygonizer::extractPolygonsFromBinaryImage(const cv::Mat& binary_image) const{ - PolygonWithHoles plane_polygons; - std::vector> contours; - std::vector hierarchy; - cv::Mat binary_image_upsampled; - cv::resize(binary_image, - binary_image_upsampled, - cv::Size(parameters_.upsampling_factor * binary_image.size().height, - parameters_.upsampling_factor * binary_image.size().width)); - - findContours(binary_image_upsampled, contours, hierarchy, - CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); - std::vector> approx_contours; - int hierachy_it = 0; - for (const auto& contour : contours) { - ++hierachy_it; - if (contour.size() <= 2) { - LOG_IF(WARNING, hierarchy[hierachy_it - 1][3] < 0 && contour.size() > 3) - << "Removing parental polygon since too few vertices!"; - continue; - } - CgalPolygon2d polygon = convex_plane_decomposition::createCgalPolygonFromOpenCvPoints( - contour.begin(), contour.end(), - parameters_.resolution / static_cast(parameters_.upsampling_factor)); - CHECK(polygon.is_simple()) << "Contour extraction from binary image caused intersection!"; - constexpr int kParentFlagIndex = 3; - if (hierarchy[hierachy_it - 1][kParentFlagIndex] < 0) { - if (parameters_.activate_long_edge_upsampling) { - upSampleLongEdges(&polygon); - } - if (parameters_.activate_contour_approximation) { - approximateContour(&polygon, parameters_.max_number_of_iterations, parameters_.contour_approximation_relative_local_area_threshold, - parameters_.contour_approximation_absolute_local_area_threshold_squared_meters, - parameters_.contour_approximation_relative_total_area_threshold, parameters_.contour_approximation_absolute_total_area_threshold_squared_meters); - VLOG(1) << "Contour approximated!"; - } - plane_polygons.outer_contour = polygon; - } else { - plane_polygons.holes.push_back(polygon); - } - } - return plane_polygons; -} - -PolygonWithHoles Polygonizer::extractContoursFromBinaryImage(cv::Mat& binary_image) const{ - PolygonWithHoles plane_polygons; - std::vector> contours; - std::vector hierarchy; - findContours(binary_image, contours, hierarchy, - CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); - std::vector> approx_contours; - int hierachy_it = 0; - for (auto& contour : contours) { - ++hierachy_it; - CHECK_GE(contour.size(), 2); - CgalPolygon2d polygon = convex_plane_decomposition::createCgalPolygonFromOpenCvPoints( - contour.begin(), contour.end(), 1); - constexpr int kParentFlagIndex = 3; - if (hierarchy[hierachy_it - 1][kParentFlagIndex] < 0) { - plane_polygons.outer_contour = polygon; - } else { - plane_polygons.holes.push_back(polygon); - } - } - return plane_polygons; -} - -// Deprecated: Due to finite resolution in image, complicated contours are extracted in the end. -void Polygonizer::resolveHolesInBinaryImage(cv::Mat& binary_image, const PolygonWithHoles& contour_with_holes) const{ - for(const auto& hole : contour_with_holes.holes){ - if (hole.area() > 36){ - continue; - } - std::pair slConcavityVertices = getVertexPositionsWithHighestHoleSlConcavityMeasure(hole); - const CgalPoint2d first_sl_point = hole.container().at(slConcavityVertices.first); - const CgalPoint2d second_sl_point = hole.container().at(slConcavityVertices.second); - std::pair first_connection_candidate = - getClosestPointAndSegmentOnPolygonToPoint(first_sl_point, contour_with_holes.outer_contour); - std::pair second_connection_candidate = - getClosestPointAndSegmentOnPolygonToPoint(second_sl_point, contour_with_holes.outer_contour); - if ((first_connection_candidate.second - first_sl_point).squared_length() < - (second_connection_candidate.second - second_sl_point).squared_length()){ - cv::Point first_point(first_connection_candidate.second.y(), first_connection_candidate.second.x()); - cv::Point second_point(first_sl_point.y(), first_sl_point.x()); - cv::line(binary_image, first_point, second_point, CV_RGB(0,0,0),2); - } else{ - cv::Point first_point(second_connection_candidate.second.y(), second_connection_candidate.second.x()); - cv::Point second_point(second_sl_point.y(), second_sl_point.x()); - cv::line(binary_image, first_point, second_point, CV_RGB(0,0,0), 2); - } - } -} - -void Polygonizer::removeAreasNotContainedInOuterContourFromHoles(const CgalPolygon2d& outer_polygon, std::vector& holes) const{ - auto hole_it = holes.begin(); - while(hole_it != holes.end()) { - std::vector buffer; - CGAL::intersection(outer_polygon, *hole_it, std::back_inserter(buffer)); - if (buffer.empty()){ - hole_it = holes.erase(hole_it); - } else { - CHECK_EQ(buffer.size(), 1) << "Intersection of hole and outer contour cannot have multiple polygons!"; - *hole_it = CgalPolygon2d(buffer.begin()->outer_boundary().vertices_begin(), buffer.begin()->outer_boundary().vertices_end()); - ++hole_it; - } - } -} - -bool Polygonizer::addHoleToOuterContourAtVertexIndex(int segment_target_vertex_index, const CgalPolygon2d& hole, CgalPolygon2d& outer_contour) const{ - CHECK_EQ(outer_contour.orientation(), CGAL::COUNTERCLOCKWISE); - CHECK_EQ(hole.orientation(), CGAL::COUNTERCLOCKWISE); - auto outer_vertex_it = outer_contour.vertices_begin(); - std::advance(outer_vertex_it, segment_target_vertex_index); - const auto& hole_vertex_buffer = hole.container(); - // TODO - return false; -} - -// Deprecated: This method produces non-simple polygons. -CgalPolygon2d Polygonizer::resolveHolesWithVerticalConnection(PolygonWithHoles& polygon_with_holes) const{ - CgalPolygon2dContainer& holes = polygon_with_holes.holes; - // Get hole part which is entirely contained in outer contour. - // In the contour simplification stage intersections may have been introduced. - removeAreasNotContainedInOuterContourFromHoles(polygon_with_holes.outer_contour, holes); - if (holes.empty()) { - return polygon_with_holes.outer_contour; - } - auto hole_it = holes.begin(); - while(hole_it!= holes.end()) { - if (hole_it->size() < 3) { - hole_it = holes.erase(hole_it); - } else if (abs(hole_it->area()) < parameters_.hole_area_threshold_squared_meters) { - hole_it = holes.erase(hole_it); - } else { - ++hole_it; - } - } - CgalPolygonWithHoles2d temp_polygon_with_holes(polygon_with_holes.outer_contour, - polygon_with_holes.holes.begin(), polygon_with_holes.holes.end()); - CgalPolygon2d resolved_polygon; - connect_holes(temp_polygon_with_holes, std::back_inserter (resolved_polygon.container())); - // Create offset polygon to return - constexpr double kSmallOffsetMeters = 1e-12; - std::vector> offset_polygons = CGAL::create_interior_skeleton_and_offset_polygons_2(1e-12, resolved_polygon); - CHECK_EQ(offset_polygons.size(), 1); - return **offset_polygons.begin(); -} - -CgalPolygon2d Polygonizer::runPolygonizationOnBinaryImage(const cv::Mat& binary_image) const{ - PolygonWithHoles polygon_with_holes = extractPolygonsFromBinaryImage(binary_image); - //CgalPolygon2d polygon = resolveHolesWithVerticalConnection(polygon_with_holes); - return polygon_with_holes.outer_contour; -} - -// TODO: complete implementation! -CgalPolygon2d Polygonizer::resolveHolesUsingSlConnection(const PolygonWithHoles& polygon_with_holes) const{ - CgalPolygon2dContainer holes = polygon_with_holes.holes; - // Get hole part which is entirely contained in outer contour. - // In the contour simplification stage intersections may have been introduced. - removeAreasNotContainedInOuterContourFromHoles(polygon_with_holes.outer_contour, holes); - if (holes.empty()) { - return polygon_with_holes.outer_contour; - } - auto hole_it = holes.begin(); - while(hole_it!= holes.end()) { - if (hole_it->size() < 3) { - hole_it = holes.erase(hole_it); - } else if (abs(hole_it->area()) < parameters_.hole_area_threshold_squared_meters) { - hole_it = holes.erase(hole_it); - } else { - ++hole_it; - } - } - std::vector difference_polygons; - difference_polygons.emplace_back(polygon_with_holes.outer_contour); - for (const auto& hole : holes) { - std::vector temp_polygon_buffer; - for (const auto& polygon : difference_polygons) { - CGAL::difference(polygon, hole, std::back_inserter(temp_polygon_buffer)); - } - difference_polygons.clear(); - std::move(temp_polygon_buffer.begin(), temp_polygon_buffer.end(), std::back_inserter(difference_polygons)); - } - CgalPolygon2d outer_contour = difference_polygons.rbegin()->outer_boundary(); - holes.clear(); - std::move(difference_polygons.rbegin()->holes_begin(), difference_polygons.rbegin()->holes_end(), std::back_inserter(holes)); - for (const auto& hole : holes){ - if (CGAL::do_intersect(hole, outer_contour)){ - // At this point intersections may only occur in single points. Overlapping edges are not possible. - - } - } -} \ No newline at end of file diff --git a/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp b/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp new file mode 100644 index 00000000..ccc70966 --- /dev/null +++ b/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp @@ -0,0 +1,23 @@ +#include "convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp" + +namespace ransac_plane_extractor { + +RansacPlaneExtractor::RansacPlaneExtractor(const RansacPlaneExtractorParameters& parameters) { + setParameters(parameters); + ransac_.add_shape_factory(); +} + +void RansacPlaneExtractor::setParameters(const RansacPlaneExtractorParameters& parameters) { + cgalRansacParameters_.probability = parameters.probability; + cgalRansacParameters_.min_points = parameters.min_points; + cgalRansacParameters_.epsilon = parameters.epsilon; + cgalRansacParameters_.cluster_epsilon = parameters.cluster_epsilon; + cgalRansacParameters_.normal_threshold = parameters.normal_threshold; +} + +void RansacPlaneExtractor::detectPlanes(std::vector& points_with_normal) { + ransac_.set_input(points_with_normal); + ransac_.detect(cgalRansacParameters_); +} + +} // namespace ransac_plane_extractor diff --git a/convex_plane_decomposition/src/ransac_plane_extractor.cpp b/convex_plane_decomposition/src/ransac_plane_extractor.cpp deleted file mode 100644 index b4266dab..00000000 --- a/convex_plane_decomposition/src/ransac_plane_extractor.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "convex_plane_decomposition/ransac_plane_extractor.hpp" - -using namespace ransac_plane_extractor; - -RansacPlaneExtractor::RansacPlaneExtractor(std::vector& points_with_normal, const RansacPlaneExtractorParameters& parameters){ - ransac_.set_input(points_with_normal); - ransac_.add_shape_factory(); - parameters_.probability = parameters.probability; - parameters_.min_points = parameters.min_points; - parameters_.epsilon = parameters.epsilon; - parameters_.cluster_epsilon = parameters.cluster_epsilon; - parameters_.normal_threshold = parameters.normal_threshold; -} - -void RansacPlaneExtractor::runDetection(){ - // Detect shapes. - ransac_.detect(parameters_); -} - -void RansacPlaneExtractor::setParameters(const RansacPlaneExtractorParameters& parameters){ - parameters_.probability = parameters.probability; - parameters_.min_points = parameters.min_points; - parameters_.epsilon = parameters.epsilon; - parameters_.cluster_epsilon = parameters.cluster_epsilon; - parameters_.normal_threshold = parameters.normal_threshold; -} - - diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp new file mode 100644 index 00000000..c72380bf --- /dev/null +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -0,0 +1,282 @@ +#include "convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h" + +#include +#include +#include +#include + +#include + +#include + +#include + +#include + +#include "convex_plane_decomposition/Nan.h" + +namespace convex_plane_decomposition { +namespace sliding_window_plane_extractor { + +double angleBetweenVectorsInDegrees(const Eigen::Vector3d& v1, const Eigen::Vector3d& v2) { + double cos_rad = v1.normalized().dot(v2.normalized()); + if (cos_rad < -1.0) { + cos_rad = -1.0; + } else if (cos_rad > 1.0) { + cos_rad = 1.0; + } + return std::abs(std::acos(cos_rad) * 180.0 / M_PI); +} + +SlidingWindowPlaneExtractor::SlidingWindowPlaneExtractor(const SlidingWindowPlaneExtractorParameters& parameters, + const ransac_plane_extractor::RansacPlaneExtractorParameters& ransacParameters) + : parameters_(parameters), ransacParameters_(ransacParameters) {} + +void SlidingWindowPlaneExtractor::runExtraction(const grid_map::GridMap& map, const std::string& layer_height) { + // Extract basic map information + map_ = ↦ + elevationLayer_ = layer_height; + segmentedPlanesMap_.resolution = map_->getResolution(); + map_->getPosition(Eigen::Vector2i(0, 0), segmentedPlanesMap_.mapOrigin); + + // Initialize based on map size. + segmentedPlanesMap_.highestLabel = -1; + segmentedPlanesMap_.labelPlaneParameters.clear(); + const auto& mapSize = map_->getSize(); + binaryImagePatch_ = cv::Mat(mapSize(0), mapSize(1), CV_8U, 0.0); // Zero initialize to set untouched pixels to not planar; + // Need a buffer of at least the linear size of the image. But no need to shrink if the buffer is already bigger. + const int linearMapSize = mapSize(0) * mapSize(1); + if (surfaceNormals_.size() < linearMapSize) { + surfaceNormals_.reserve(linearMapSize); + std::fill_n(surfaceNormals_.begin(), linearMapSize, Eigen::Vector3d::Zero()); + } + + // Run + runSlidingWindowDetector(); + runSegmentation(); + extractPlaneParametersFromLabeledImage(); +} + +std::pair SlidingWindowPlaneExtractor::computeNormalAndErrorForWindow(const Eigen::MatrixXf& windowData) const { + // Gather surrounding data. + size_t nPoints = 0; + Eigen::Vector3d sum = Eigen::Vector3d::Zero(); + Eigen::Matrix3d sumSquared = Eigen::Matrix3d::Zero(); + for (int kernel_col = 0; kernel_col < parameters_.kernel_size; ++kernel_col) { + for (int kernel_row = 0; kernel_row < parameters_.kernel_size; ++kernel_row) { + float height = windowData(kernel_row, kernel_col); + if (isNan(height)) { + continue; + } + // No need to account for map offset. Will substract the mean anyway. + Eigen::Vector3d point{-kernel_row * segmentedPlanesMap_.resolution, -kernel_col * segmentedPlanesMap_.resolution, height}; + nPoints++; + sum += point; + sumSquared.noalias() += point * point.transpose(); + } + } + + if (nPoints < 3) { + // Not enough points to establish normal direction + return {Eigen::Vector3d::UnitZ(), 1e30}; + } else { + const Eigen::Vector3d mean = sum / nPoints; + const Eigen::Matrix3d covarianceMatrix = sumSquared / nPoints - mean * mean.transpose(); + + // Compute Eigenvectors. + // Eigenvalues are ordered small to large. + // Worst case bound for zero eigenvalue from : https://eigen.tuxfamily.org/dox/classEigen_1_1SelfAdjointEigenSolver.html + Eigen::SelfAdjointEigenSolver solver; + solver.computeDirect(covarianceMatrix, Eigen::DecompositionOptions::ComputeEigenvectors); + if (solver.eigenvalues()(1) > 1e-8) { + Eigen::Vector3d unitaryNormalVector = solver.eigenvectors().col(0); + + // Check direction of the normal vector and flip the sign upwards + if (unitaryNormalVector.z() < 0.0) { + unitaryNormalVector = -unitaryNormalVector; + } + // The first eigenvalue might become slightly negative due to numerics. + double rmsError = (solver.eigenvalues()(0) > 0.0) ? std::sqrt(solver.eigenvalues()(0)) : 0.0; + return {unitaryNormalVector, rmsError}; + } else { // If second eigenvalue is zero, the normal is not defined. + return {Eigen::Vector3d::UnitZ(), 1e30}; + } + } +} + +bool SlidingWindowPlaneExtractor::isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanError) const { + return (meanError < parameters_.plane_patch_error_threshold && + angleBetweenVectorsInDegrees(localNormal, Eigen::Vector3d::UnitZ()) < parameters_.plane_inclination_threshold_degrees); +} + +void SlidingWindowPlaneExtractor::runSlidingWindowDetector() { + grid_map::SlidingWindowIterator window_iterator(*map_, elevationLayer_, grid_map::SlidingWindowIterator::EdgeHandling::INSIDE, + parameters_.kernel_size); + const int kernelMiddle = (parameters_.kernel_size - 1) / 2; + + for (; !window_iterator.isPastEnd(); ++window_iterator) { + grid_map::Index index = *window_iterator; + Eigen::MatrixXf window_data = window_iterator.getData(); + const auto middleValue = window_data(kernelMiddle, kernelMiddle); + + if (isNan(middleValue)) { + binaryImagePatch_.at(index.x(), index.y()) = false; + } else { + Eigen::Vector3d n; + double mean_error; + std::tie(n, mean_error) = computeNormalAndErrorForWindow(window_data); + + surfaceNormals_[getLinearIndex(index.x(), index.y())] = n; + binaryImagePatch_.at(index.x(), index.y()) = isLocallyPlanar(n, mean_error); + } + } +} + +// Label cells according to which cell they belong to using connected component labeling. +void SlidingWindowPlaneExtractor::runSegmentation() { + int numberOfLabel = cv::connectedComponents(binaryImagePatch_, segmentedPlanesMap_.labeledImage, parameters_.connectivity, CV_32S); + segmentedPlanesMap_.highestLabel = numberOfLabel - 1; // Labels are [0, N-1] +} + +void SlidingWindowPlaneExtractor::extractPlaneParametersFromLabeledImage() { + if (segmentedPlanesMap_.highestLabel < 1) { + LOG(WARNING) << "No planes detected by Sliding Window Plane Extractor!"; + return; + } + const int numberOfExtractedPlanesWithoutRefinement = segmentedPlanesMap_.highestLabel; // Make local copy. The highestLabel is incremented inside the loop + + // Skip label 0. This is the background, i.e. non-planar region. + for (int label = 1; label <= numberOfExtractedPlanesWithoutRefinement; ++label) { + computePlaneParametersForLabel(label); + } +} + +void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label) { + const auto& elevationData = (*map_)[elevationLayer_]; + + std::vector points_with_normal; + int approximate_num_points = + segmentedPlanesMap_.labeledImage.rows * segmentedPlanesMap_.labeledImage.cols / segmentedPlanesMap_.highestLabel; + points_with_normal.reserve(approximate_num_points); + + int number_of_normal_instances = 0; + int number_of_position_instances = 0; + Eigen::Vector3d normal_vector_sum = Eigen::Vector3d::Zero(); + Eigen::Vector3d support_vector_sum = Eigen::Vector3d::Zero(); + for (int row = 0; row < segmentedPlanesMap_.labeledImage.rows; ++row) { + for (int col = 0; col < segmentedPlanesMap_.labeledImage.cols; ++col) { + if (segmentedPlanesMap_.labeledImage.at(row, col) == label) { + double height = elevationData(row, col); + if (std::isfinite(height)) { + Eigen::Vector2i index{row, col}; + + Eigen::Vector3d normal_vector_temp = surfaceNormals_[getLinearIndex(index.x(), index.y())]; + normal_vector_sum += normal_vector_temp; + ++number_of_normal_instances; + + Eigen::Vector3d point3d{segmentedPlanesMap_.mapOrigin.x() - row * segmentedPlanesMap_.resolution, segmentedPlanesMap_.mapOrigin.y() - col * segmentedPlanesMap_.resolution, height}; + support_vector_sum += point3d; + ++number_of_position_instances; + + points_with_normal.emplace_back( + ransac_plane_extractor::Point3D(point3d.x(), point3d.y(), point3d.z()), + ransac_plane_extractor::Vector3D(normal_vector_temp.x(), normal_vector_temp.y(), normal_vector_temp.z())); + } + } + } + } + if (number_of_position_instances < parameters_.min_number_points_per_label) { + // Label has too little points, no plane parameters are created + return; + } + Eigen::Vector3d normal_vector_avg = normal_vector_sum / number_of_normal_instances; + normal_vector_avg.normalize(); // Averaging does not preserve norm + Eigen::Vector3d support_vector_avg = support_vector_sum / number_of_position_instances; + + // Compute error to fitted plane. + if (parameters_.include_ransac_refinement && !isGloballyPlanar(normal_vector_avg, support_vector_avg, points_with_normal)) { + // Fix the seed for each label to get deterministic behaviour + CGAL::get_default_random() = CGAL::Random(0); + + // Run ransac + ransac_plane_extractor::RansacPlaneExtractor ransac_plane_extractor(ransacParameters_); + ransac_plane_extractor.detectPlanes(points_with_normal); + const auto& planes = ransac_plane_extractor.getDetectedPlanes(); + + bool reuseLabel = true; + for (const auto& plane : planes) { + // Bookkeeping of labels : reuse old label for the first plane + int newLabel = (reuseLabel) ? label : ++segmentedPlanesMap_.highestLabel; + reuseLabel = false; + + // Compute average plane parameters for refined segmentation + const std::vector& plane_point_indices = plane->indices_of_assigned_points(); + CHECK(!plane_point_indices.empty()); + Eigen::Vector3d support_vector_refined_sum = Eigen::Vector3d::Zero(); + Eigen::Vector3d normal_vector_refined_sum = Eigen::Vector3d::Zero(); + for (const auto index : plane_point_indices) { + const auto& point = points_with_normal[index].first; + const auto& normal = points_with_normal[index].second; + support_vector_refined_sum += Eigen::Vector3d(point.x(), point.y(), point.z()); + normal_vector_refined_sum += Eigen::Vector3d(normal.x(), normal.y(), normal.z()); + + // relabel if required + if (newLabel != label) { + // Need to lookup indices in map, because RANSAC has reordered the points + Eigen::Array2i map_indices; + map_->getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); + segmentedPlanesMap_.labeledImage.at(map_indices(0), map_indices(1)) = newLabel; + } + } + + Eigen::Vector3d normal_vector_refined_avg = normal_vector_refined_sum / plane_point_indices.size(); + normal_vector_refined_avg.normalize(); // Averaging does not preserve norm + Eigen::Vector3d support_vector_refined_avg = support_vector_refined_sum / plane_point_indices.size(); + + if (angleBetweenVectorsInDegrees(normal_vector_refined_avg, Eigen::Vector3d::UnitZ()) < + parameters_.plane_inclination_threshold_degrees) { + const TerrainPlane temp_plane_parameters(support_vector_refined_avg, switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normal_vector_refined_avg)); + segmentedPlanesMap_.labelPlaneParameters.emplace_back(newLabel, temp_plane_parameters); + } + } + + const auto& unassigned_points = ransac_plane_extractor.getUnassignedPointIndices(); + for (const auto index : unassigned_points) { + const auto& point = points_with_normal[index].first; + + // Need to lookup indices in map, because RANSAC has reordered the points + Eigen::Array2i map_indices; + map_->getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); + segmentedPlanesMap_.labeledImage.at(map_indices(0), map_indices(1)) = 0; + } + } else { + if (angleBetweenVectorsInDegrees(normal_vector_avg, Eigen::Vector3d::UnitZ()) < + parameters_.plane_inclination_threshold_degrees) { + const TerrainPlane temp_plane_parameters(support_vector_avg, switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normal_vector_avg)); + segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, temp_plane_parameters); + } + } +} + +bool SlidingWindowPlaneExtractor::isGloballyPlanar(const Eigen::Vector3d& normalVectorPlane, const Eigen::Vector3d& supportVectorPlane, + const std::vector& points_with_normal) const { + CHECK(!points_with_normal.empty()); + for (const auto& point_with_normal : points_with_normal) { + Eigen::Vector3d p_S_P(point_with_normal.first.x() - supportVectorPlane.x(), point_with_normal.first.y() - supportVectorPlane.y(), + point_with_normal.first.z() - supportVectorPlane.z()); + double distanceError = std::abs(normalVectorPlane.dot(p_S_P)); + if (distanceError > parameters_.global_plane_fit_distance_error_threshold) { + return false; + } else { + Eigen::Vector3d pointNormal{point_with_normal.second.x(), point_with_normal.second.y(), point_with_normal.second.z()}; + double angleError = angleBetweenVectorsInDegrees(pointNormal, normalVectorPlane); + if (angleError > parameters_.global_plane_fit_angle_error_threshold_degrees) { + return false; + } + } + } + return true; +} + +} // namespace sliding_window_plane_extractor +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp deleted file mode 100644 index f2082e0e..00000000 --- a/convex_plane_decomposition/src/sliding_window_plane_extractor.cpp +++ /dev/null @@ -1,312 +0,0 @@ -#include "convex_plane_decomposition/sliding_window_plane_extractor.hpp" - -#include -#include - -namespace sliding_window_plane_extractor{ - - SlidingWindowPlaneExtractor::SlidingWindowPlaneExtractor(grid_map::GridMap& map, double resolution, - const std::string& layer_height, const SlidingWindowPlaneExtractorParameters& parameters, - const ransac_plane_extractor::RansacPlaneExtractorParameters& ransac_parameters) - : map_(map), - resolution_(resolution), - elevation_layer_(layer_height), - parameters_(parameters), - ransac_parameters_(parameters.ransac_parameters){ - computeMapTransformation(); - VLOG(1) << "Constructing SWE..."; - VLOG(1) << "Set elevation layer is: " << elevation_layer_; - CHECK(map_.exists(elevation_layer_)); - number_of_extracted_planes_ = -1; - const grid_map::Size map_size = map.getSize(); - binary_image_patch_ = cv::Mat(map_size(0), map_size(1), CV_8U, false); - binary_image_angle_ = cv::Mat(map_size(0), map_size(1), CV_8U, false); - VLOG(1) << "done."; - } - - void SlidingWindowPlaneExtractor::runSlidingWindowDetector(){ - const grid_map::Size map_size = map_.getSize(); - Eigen::Matrix normal_x(map_size(0), map_size(1)); - Eigen::Matrix normal_y(map_size(0), map_size(1)); - Eigen::Matrix normal_z(map_size(0), map_size(1)); - CHECK(map_.getSize().x() >= parameters_.kernel_size); - CHECK(map_.getSize().y() >= parameters_.kernel_size); - grid_map::SlidingWindowIterator window_iterator(map_, elevation_layer_, grid_map::SlidingWindowIterator::EdgeHandling::INSIDE, - parameters_.kernel_size); - for (; !window_iterator.isPastEnd(); ++window_iterator) { - Eigen::MatrixXf window_data = window_iterator.getData(); - int instance_iterator = 0; - std::vector height_instances; - std::vector row_position; - std::vector col_position; - for (int kernel_col = 0; kernel_col < parameters_.kernel_size; ++kernel_col) { - for (int kernel_row = 0; kernel_row < parameters_.kernel_size; ++kernel_row) { - if (!isfinite(window_data(kernel_row, kernel_col))) { - continue; - } - height_instances.push_back(window_data(kernel_row, kernel_col)); - row_position.push_back(kernel_row - static_cast(parameters_.kernel_size / 2)); - col_position.push_back(kernel_col - static_cast(parameters_.kernel_size / 2)); - } - } - constexpr int kMinNumberOfDataPoints = 9; - if (height_instances.size() < kMinNumberOfDataPoints) { - continue; - } - CHECK(height_instances.size() == col_position.size()); - CHECK(height_instances.size() == row_position.size()); - // Center height around mean. - double mean_height = std::accumulate(height_instances.begin(), height_instances.end(), 0.0); - mean_height = mean_height / static_cast(height_instances.size()); - for(double& element : height_instances) { - element -= mean_height; - } - // Collect centered data points into matrix. - Eigen::MatrixXd data_points(height_instances.size(), 3); - data_points.col(0) = Eigen::Map(&row_position.front(), row_position.size()) * resolution_; - data_points.col(1) = Eigen::Map(&col_position.front(), col_position.size()) * resolution_; - data_points.col(2) = Eigen::Map(&height_instances.front(), height_instances.size()); - const Eigen::Matrix3d covarianceMatrix(data_points.transpose() * data_points); - Eigen::Vector3d eigenvalues = Eigen::Vector3d::Ones(); - Eigen::Matrix3d eigenvectors = Eigen::Matrix3d::Identity(); - const Eigen::SelfAdjointEigenSolver solver(covarianceMatrix); - eigenvalues = solver.eigenvalues().real(); - eigenvectors = solver.eigenvectors().real(); - int smallestId(0); - double smallestValue(std::numeric_limits::max()); - for (int j = 0; j < eigenvectors.cols(); j++) { - if (eigenvalues(j) < smallestValue) { - smallestId = j; - smallestValue = eigenvalues(j); - } - } - Eigen::Vector3d eigenvector = eigenvectors.col(smallestId); - const Eigen::Vector3d normalVectorPositiveAxis(0, 0, 1); - if (eigenvector.dot(normalVectorPositiveAxis) < 0.0) { - eigenvector = -eigenvector; - } - Eigen::Vector3d n = eigenvector.normalized(); - grid_map::Index index = *window_iterator; - double mean_error = ((data_points * n).cwiseAbs()).sum() / height_instances.size(); - Eigen::Vector3d upwards(0, 0, 1); - constexpr double kInclinationThreshold = 0.35; - if (mean_error < parameters_.plane_patch_error_threshold && abs(n.transpose() * upwards) > kInclinationThreshold) { - binary_image_patch_.at((*window_iterator).x(), (*window_iterator).y()) = true; - n.head(2) = transformation_xy_to_world_frame_ * n.head(2); - normal_x(index.x(), index.y()) = n.x(); - normal_y(index.x(), index.y()) = n.y(); - normal_z(index.x(), index.y()) = n.z(); - } - } - map_.add("normals_x", normal_x); - map_.add("normals_y", normal_y); - map_.add("normals_z", normal_z); - } - - void SlidingWindowPlaneExtractor::runSurfaceNormalCurvatureDetection(){ - CHECK(map_.exists("normals_x")); - CHECK(map_.exists("normals_y")); - CHECK(map_.exists("normals_z")); - const int surface_normal_map_boundary_offset = parameters_.kernel_size / 2; - CHECK_GT(surface_normal_map_boundary_offset, 0); - const grid_map::Size map_rows_cols = map_.getSize(); - for( int cols = surface_normal_map_boundary_offset; cols < map_rows_cols(1) - surface_normal_map_boundary_offset - 1; ++cols){ - for (int rows = surface_normal_map_boundary_offset; rows < map_rows_cols(0) - surface_normal_map_boundary_offset - 1; ++rows) { - const Eigen::Vector3f normal_vector_center(map_.at("normals_x", grid_map::Index(rows, cols)), - map_.at("normals_y", grid_map::Index(rows, cols)), - map_.at("normals_z", grid_map::Index(rows, cols))); - const Eigen::Vector3f normal_vector_next_row(map_.at("normals_x", grid_map::Index(rows + 1, cols)), - map_.at("normals_y", grid_map::Index(rows + 1, cols)), - map_.at("normals_z", grid_map::Index(rows + 1, cols))); - const Eigen::Vector3f normal_vector_next_col(map_.at("normals_x", grid_map::Index(rows, cols + 1)), - map_.at("normals_y", grid_map::Index(rows, cols + 1)), - map_.at("normals_z", grid_map::Index(rows, cols + 1))); - const double angle_in_col_direction_deg = - std::atan2(normal_vector_center.cross(normal_vector_next_col).norm(), normal_vector_center.dot(normal_vector_next_col)) / M_PI * - 180.0; - const double angle_in_row_direction_deg = - std::atan2(normal_vector_center.cross(normal_vector_next_row).norm(), normal_vector_center.dot(normal_vector_next_row)) / M_PI * - 180.0; - binary_image_angle_.at(rows, cols) = isfinite(angle_in_col_direction_deg) && isfinite(angle_in_row_direction_deg) && - abs(angle_in_col_direction_deg) <= parameters_.surface_normal_angle_threshold_degrees && - abs(angle_in_row_direction_deg) <= parameters_.surface_normal_angle_threshold_degrees; - } - } - } - - // Label cells according to which cell they belong to using connected component labeling. - void SlidingWindowPlaneExtractor::runSegmentation() { - CHECK_EQ(binary_image_patch_.type(), CV_8U); - const grid_map::Size map_size = map_.getSize(); - CHECK_EQ(binary_image_patch_.rows, map_size(0)); - CHECK_EQ(binary_image_patch_.cols, map_size(1)); - if (parameters_.include_curvature_detection){ - CHECK_EQ(binary_image_patch_.type(), binary_image_angle_.type()); - CHECK_EQ(binary_image_patch_.size, binary_image_angle_.size); - number_of_extracted_planes_ = cv::connectedComponents(binary_image_patch_ & binary_image_angle_, labeled_image_, 8, CV_32SC1); - } else { - number_of_extracted_planes_ = cv::connectedComponents(binary_image_patch_, labeled_image_, 8, CV_32SC1); - } - } - - // Refine connected component using RANSAC. Input vector is modified by function! - auto SlidingWindowPlaneExtractor::runRansacRefinement(std::vector& points_with_normal) const { - CHECK(!points_with_normal.empty()); - ransac_plane_extractor::RansacPlaneExtractor ransac_plane_extractor(points_with_normal, ransac_parameters_); - ransac_plane_extractor.runDetection(); - return ransac_plane_extractor.getDetectedPlanes(); - } - - void SlidingWindowPlaneExtractor::setParameters(const SlidingWindowPlaneExtractorParameters& parameters){ - parameters_.kernel_size = parameters.kernel_size; - parameters_.plane_patch_error_threshold = parameters.plane_patch_error_threshold; - } - - void SlidingWindowPlaneExtractor::extractPlaneParametersFromLabeledImage(){ - if (number_of_extracted_planes_ < 1){ - LOG(WARNING) << "No planes detected by Sliding Window Plane Extractor!"; - return; - } - const int number_of_extracted_planes_without_refinement = number_of_extracted_planes_; - for (int label = 1; label <= number_of_extracted_planes_without_refinement; ++label) { - computePlaneParametersForLabel(label); - } - } - - void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label){ - CHECK(map_.exists(elevation_layer_)); - CHECK(map_.exists("normals_x")); - CHECK(map_.exists("normals_y")); - CHECK(map_.exists("normals_z")); - Eigen::Vector3d normal_vector = Eigen::Vector3d::Zero(); - Eigen::Vector3d support_vector = Eigen::Vector3d::Zero(); - std::vector points_with_normal; - cv::Mat binary_image(labeled_image_.size(), CV_8UC1); - binary_image = labeled_image_ == label; - int number_of_normal_instances = 0; - int number_of_position_instances = 0; - for (int row = 0; row < binary_image.rows; ++row){ - for (int col = 0; col < binary_image.cols; ++col){ - if (binary_image.at(row, col)) { - Eigen::Vector2i index; - index << row, col; - Eigen::Vector3d normal_vector_temp; - Eigen::Vector3d support_vector_temp; - if(map_.getVector("normals_", index, normal_vector_temp)) { - normal_vector += normal_vector_temp; - ++number_of_normal_instances; - if (map_.getPosition3(elevation_layer_, index, support_vector_temp)) { - support_vector += support_vector_temp; - ++number_of_position_instances; - - ransac_plane_extractor::PointWithNormal - point_with_normal = std::make_pair( - ransac_plane_extractor::Point3D(support_vector_temp.x(), - support_vector_temp.y(), - support_vector_temp.z()), - ransac_plane_extractor::Vector3D(normal_vector_temp.x(), - normal_vector_temp.y(), - normal_vector_temp.z())); - points_with_normal.push_back(point_with_normal); - } - } - } - } - } - if (number_of_normal_instances == 0 || number_of_position_instances == 0){ - LOG(WARNING) << "Label empty, NO plane parameters are created!"; - return; - } - normal_vector = normal_vector / static_cast(number_of_normal_instances); - support_vector = support_vector / static_cast(number_of_position_instances); - bool refinement_performed = false; - if (parameters_.include_ransac_refinement) { - // Compute error to fitted plane. - if (computeAverageErrorToPlane(normal_vector, support_vector, points_with_normal) - > parameters_.global_plane_fit_error_threshold){ - const auto planes = runRansacRefinement(points_with_normal); - CHECK(!planes.empty()) << "No planes detected by RANSAC in as planar classified region."; - int label_counter = 0; - for (const auto& plane : planes){ - const std::vector& plane_point_indices = (*plane.get()).indices_of_assigned_points(); - CHECK(!plane_point_indices.empty()); - support_vector = Eigen::Vector3d::Zero(); - normal_vector = Eigen::Vector3d::Zero(); - for (const auto index : plane_point_indices) { - const auto &point = points_with_normal.at(index).first; - const auto &normal = points_with_normal.at(index).second; - support_vector += Eigen::Vector3d(point.x(), point.y(), point.z()); - normal_vector += Eigen::Vector3d(normal.x(), normal.y(), normal.z()); - Eigen::Array2i map_indices; - map_.getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); - if (label_counter == 0){ - labeled_image_.at(map_indices(0), map_indices(1)) = label; - } else { - labeled_image_.at(map_indices(0), map_indices(1)) = number_of_extracted_planes_ + label_counter; - } - } - support_vector /= static_cast(plane_point_indices.size()); - normal_vector /= static_cast(plane_point_indices.size()); - const convex_plane_decomposition::PlaneParameters temp_plane_parameters(normal_vector, support_vector); - if (label_counter == 0) { - label_plane_parameters_map_.emplace(label, temp_plane_parameters); - } else { - label_plane_parameters_map_.emplace(number_of_extracted_planes_ + label_counter, temp_plane_parameters); - } - ++label_counter; - } - CHECK_EQ(label_counter, planes.size()); - number_of_extracted_planes_ += label_counter; - refinement_performed = true; - } - } - if (!refinement_performed){ - const convex_plane_decomposition::PlaneParameters temp_plane_parameters(normal_vector, support_vector); - label_plane_parameters_map_.emplace(label, temp_plane_parameters); - } - VLOG(1) << "Added plane!"; - } - - double SlidingWindowPlaneExtractor::computeAverageErrorToPlane(const Eigen::Vector3d& normal_vector, const Eigen::Vector3d& support_vector, - const std::vector& points_with_normal) const { - CHECK(!points_with_normal.empty()); - double average_error = 0.0; - for (const auto& point_with_normal : points_with_normal){ - Eigen::Vector3d p_S_P(point_with_normal.first.x() - support_vector.x(), point_with_normal.first.y() - support_vector.y(), - point_with_normal.first.z() - support_vector.z()); - average_error += abs(normal_vector.dot(p_S_P)); - } - average_error /= static_cast(points_with_normal.size()); - return average_error; - } - - void SlidingWindowPlaneExtractor::runExtraction(){ - VLOG(1) << "Started sliding window plane detector ..."; - runSlidingWindowDetector(); - VLOG(1) << "done."; - if (parameters_.include_curvature_detection){ - VLOG(1) << "Starting surface normal curvature detection ..."; - runSurfaceNormalCurvatureDetection(); - VLOG(1) << "done."; - } - VLOG(1) << "Starting segmentation ..."; - runSegmentation(); - VLOG(1) << "done."; - VLOG(1) << "Extracting plane parameters from labeled image ..."; - extractPlaneParametersFromLabeledImage(); - VLOG(1) << "done."; - } - - void SlidingWindowPlaneExtractor::computeMapTransformation() { - Eigen::Vector2i map_size = map_.getSize(); - CHECK(map_.getPosition(Eigen::Vector2i::Zero(), map_offset_)); - Eigen::Vector2d lower_left_cell_position; - CHECK(map_.getPosition(Eigen::Vector2i(map_size.x() - 1, 0), lower_left_cell_position)); - Eigen::Vector2d upper_right_cell_position; - CHECK(map_.getPosition(Eigen::Vector2i(0, map_size.y() - 1), upper_right_cell_position)); - transformation_xy_to_world_frame_.col(0) = (lower_left_cell_position - map_offset_).normalized(); - transformation_xy_to_world_frame_.col(1) = (upper_right_cell_position - map_offset_).normalized(); - } - - } // namespace sliding_window_plane_extractor diff --git a/convex_plane_decomposition_msgs/CMakeLists.txt b/convex_plane_decomposition_msgs/CMakeLists.txt new file mode 100644 index 00000000..ab3b36ae --- /dev/null +++ b/convex_plane_decomposition_msgs/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.1...3.15) +project(convex_plane_decomposition_msgs) + +set(CATKIN_PACKAGE_DEPENDENCIES + std_msgs + geometry_msgs +) + +find_package(catkin REQUIRED + COMPONENTS + ${CATKIN_PACKAGE_DEPENDENCIES} + message_generation +) + +add_message_files( + FILES + BoundingBox2d.msg + PlanarRegion.msg + PlanarTerrain.msg + Point2d.msg + Polygon2d.msg + PolygonWithHoles2d.msg +) + +generate_messages( + DEPENDENCIES + ${CATKIN_PACKAGE_DEPENDENCIES} +) + +catkin_package( + CATKIN_DEPENDS + ${CATKIN_PACKAGE_DEPENDENCIES} + message_runtime +) diff --git a/convex_plane_decomposition_msgs/msg/BoundingBox2d.msg b/convex_plane_decomposition_msgs/msg/BoundingBox2d.msg new file mode 100644 index 00000000..2327348a --- /dev/null +++ b/convex_plane_decomposition_msgs/msg/BoundingBox2d.msg @@ -0,0 +1,5 @@ +# 3D, axis-aligned, bounding box +float32 min_x +float32 min_y +float32 max_x +float32 max_y \ No newline at end of file diff --git a/convex_plane_decomposition_msgs/msg/PlanarRegion.msg b/convex_plane_decomposition_msgs/msg/PlanarRegion.msg new file mode 100644 index 00000000..d93d2478 --- /dev/null +++ b/convex_plane_decomposition_msgs/msg/PlanarRegion.msg @@ -0,0 +1,7 @@ +geometry_msgs/Pose plane_parameters + +BoundingBox2d bbox2d + +PolygonWithHoles2d boundary + +PolygonWithHoles2d[] insets diff --git a/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg b/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg new file mode 100644 index 00000000..c48da4ba --- /dev/null +++ b/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg @@ -0,0 +1 @@ +PlanarRegion[] planarRegions \ No newline at end of file diff --git a/convex_plane_decomposition_msgs/msg/Point2d.msg b/convex_plane_decomposition_msgs/msg/Point2d.msg new file mode 100644 index 00000000..220abf75 --- /dev/null +++ b/convex_plane_decomposition_msgs/msg/Point2d.msg @@ -0,0 +1,2 @@ +float32 x +float32 y \ No newline at end of file diff --git a/convex_plane_decomposition_msgs/msg/Polygon2d.msg b/convex_plane_decomposition_msgs/msg/Polygon2d.msg new file mode 100644 index 00000000..e52128c5 --- /dev/null +++ b/convex_plane_decomposition_msgs/msg/Polygon2d.msg @@ -0,0 +1,2 @@ +# Specification of a 2D polygon where the first and last points are connected +Point2d[] points \ No newline at end of file diff --git a/convex_plane_decomposition_msgs/msg/PolygonWithHoles2d.msg b/convex_plane_decomposition_msgs/msg/PolygonWithHoles2d.msg new file mode 100644 index 00000000..8513f45c --- /dev/null +++ b/convex_plane_decomposition_msgs/msg/PolygonWithHoles2d.msg @@ -0,0 +1,3 @@ +# Specification of a 2D polygon with holes +Polygon2d outer_boundary +Polygon2d[] holes \ No newline at end of file diff --git a/convex_plane_decomposition_msgs/package.xml b/convex_plane_decomposition_msgs/package.xml new file mode 100644 index 00000000..295c4157 --- /dev/null +++ b/convex_plane_decomposition_msgs/package.xml @@ -0,0 +1,21 @@ + + + + + convex_plane_decomposition_msgs + 0.0.0 + Convex plane decomposition message definitions. + + TODO + Ruben Grandia + + catkin + + message_generation + + std_msgs + geometry_msgs + + message_runtime + + diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index a3ba343c..69bf7f72 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -18,11 +18,18 @@ find_package(catkin REQUIRED COMPONENTS cv_bridge jsk_recognition_msgs convex_plane_decomposition + convex_plane_decomposition_msgs ) # OpenCv find_package(OpenCV REQUIRED) +# Qt +find_package(Qt5 COMPONENTS Xml Script OpenGL Svg) + +# CGAL +find_package(CGAL COMPONENTS Core Qt5) + # glog find_package(PkgConfig REQUIRED) pkg_check_modules(glog libglog REQUIRED) @@ -34,7 +41,12 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) ################################### ## catkin specific configuration ## ################################### -catkin_package() +catkin_package( + INCLUDE_DIRS include + LIBRARIES ${PROJECT_NAME} + CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} + DEPENDS +) ########### ## Build ## @@ -45,26 +57,87 @@ include_directories( ${catkin_INCLUDE_DIRS} ) -add_executable(${PROJECT_NAME} - src/convex_plane_decomposition_node.cpp - src/convex_plane_decomposition_ros.cpp - src/grid_map_preprocessing.cpp - src/pipeline_ros.cpp - src/ros_visualizations.cpp -) +add_library(${PROJECT_NAME} + src/ConvexPlaneDecompositionRos.cpp + src/MessageConversion.cpp + src/ParameterLoading.cpp + src/RosVisualizations.cpp + ) +add_dependencies(${PROJECT_NAME} + ${catkin_EXPORTED_TARGETS} + ) target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} glog + ) +target_compile_options(${PROJECT_NAME} + PUBLIC -DCGAL_HAS_THREADS + ) + +add_executable(${PROJECT_NAME}_node + src/ConvexPlaneDecompositionNode.cpp +) +target_link_libraries(${PROJECT_NAME}_node + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + glog + ${PROJECT_NAME} ) +add_executable(${PROJECT_NAME}_test + test/test.cpp + ) +target_link_libraries(${PROJECT_NAME}_test + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + glog + Qt5::Xml Qt5::Script Qt5::OpenGL Qt5::Svg + CGAL::CGAL CGAL::CGAL_Core CGAL::CGAL_Qt5 + ) +target_compile_options(${PROJECT_NAME}_test + PUBLIC -DCGAL_HAS_THREADS -DCGAL_USE_BASIC_VIEWER + ) + +add_executable(${PROJECT_NAME}_shapegrowing + test/shapeGrowing.cpp + ) +target_link_libraries(${PROJECT_NAME}_shapegrowing + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + glog + Qt5::Xml Qt5::Script Qt5::OpenGL Qt5::Svg + CGAL::CGAL CGAL::CGAL_Core CGAL::CGAL_Qt5 + ) +target_compile_options(${PROJECT_NAME}_shapegrowing + PUBLIC -DCGAL_HAS_THREADS -DCGAL_USE_BASIC_VIEWER + ) + +add_executable(${PROJECT_NAME}_save_elevationmap + src/SaveElevationMapAsImageNode.cpp + ) +target_link_libraries(${PROJECT_NAME}_save_elevationmap + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + ) + ############# ## Install ## ############# install(TARGETS ${PROJECT_NAME} + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} + ) +install(DIRECTORY include/${PROJECT_NAME}/ + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} + ) + +install(TARGETS ${PROJECT_NAME}_node RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) + install(DIRECTORY config data launch rviz DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} ) diff --git a/convex_plane_decomposition_ros/config/convex_plane_decomposition_demo_parameters.yaml b/convex_plane_decomposition_ros/config/convex_plane_decomposition_demo_parameters.yaml index ee434007..d3ee9e81 100644 --- a/convex_plane_decomposition_ros/config/convex_plane_decomposition_demo_parameters.yaml +++ b/convex_plane_decomposition_ros/config/convex_plane_decomposition_demo_parameters.yaml @@ -1,36 +1,31 @@ -input_topic: '/image_to_gridmap_demo/grid_map' +elevation_topic: '/image_to_gridmap_demo/grid_map' height_layer: 'elevation' +submap: + width: 6.0 + length: 6.0 - -plane_factory: - plane_inclination_threshold_degrees: 70 - -polygonizer: - upsampling_factor: 3 - activate_long_edge_upsampling: false - activate_contour_approximation: true - contour_approximation_relative_local_area_threshold: 0.1 - contour_approximation_absolute_local_area_threshold_squared_meters: 0.05 - contour_approximation_relative_total_area_threshold: 0.2 - contour_approximation_absolute_total_area_threshold_squared_meters: 0.3 - max_number_of_iterations: 5 - -convex_decomposer: - decomposer_type: 'inner_convex_decomposition' # 'optimal_decompostion' - dent_angle_threshold_rad: 0.05 +preprocessing: + kernelSize: 3 # Kernel size of the median filter + numberOfRepeats: 3 # Number of times to apply the same filter + increasing: True # Increase the kernel size each iteration. + inpaintRadius: 0.05 # [m] sliding_window_plane_extractor: - kernel_size: 3 - plane_patch_error_threshold: 0.004 - surface_normal_angle_threshold_degrees: 10.0 - include_curvature_detection: true - include_ransac_refinement: false - global_plane_fit_error_threshold: 0.02 + kernel_size: 3 # Size of the sliding window patch used for normal vector calculation and planarity detection. Should be an odd number and at least 3. + plane_inclination_threshold_degrees: 45.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch + plane_patch_error_threshold: 0.005 # [m] The allowed root-mean-squared deviation from the plane fitted to the sliding window. + min_number_points_per_label: 10 # [#] Labels with less points assigned to them are discarded + connectivity: 4 # Label kernel connectivity. 4 or 8 (cross or box) + include_ransac_refinement: true # Enable RANSAC refinement if the plane is not globally fitting to the assigned points. + global_plane_fit_distance_error_threshold: 0.04 # [m] Allowed maximum distance from a point to the plane. If any point violates this, RANSAC is triggered + global_plane_fit_angle_error_threshold_degrees: 5.0 # [deg] Allowed normal vector deviation for a point w.r.t. the plane normal. If any point violates this, RANSAC is triggered ransac_plane_refinement: - probability: 0.01 - min_points: 200 - epsilon: 0.004 - cluster_epsilon: 0.0282842712475 - # Set maximum normal deviation. 0.98 < dot(surface_normal, point_normal); - normal_threshold: 0.98 \ No newline at end of file + probability: 0.01 # Probability to miss the largest candidate shape. A lower probability provides a higher reliability and determinism at the cost of longer running times + min_points: 25 # This minimum number of points per plane. Controls the termination of the algorithm. + epsilon: 0.02 # Maximum distance to plane + cluster_epsilon: 0.05 # Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon + normal_threshold: 0.98 # Set maximum normal deviation. normal_threshold < dot(surface_normal, point_normal); + +contour_extraction: + offsetSize: 2 # Size of the kernel creating the boundary offset. In number of pixels. diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 28a293db..d6fe9e03 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -1,37 +1,32 @@ -input_topic : '/elevation_mapping/elevation_map_raw' +elevation_topic : '/elevation_mapping/elevation_map_raw' height_layer : 'elevation' +submap: + width: 3.0 + length: 3.0 - -plane_factory: - plane_inclination_threshold_degrees : 70 - -polygonizer: - upsampling_factor : 3 - activate_long_edge_upsampling : false - activate_contour_approximation : true - contour_approximation_relative_local_area_threshold : 0.1 - contour_approximation_absolute_local_area_threshold_squared_meters : 0.05 - contour_approximation_relative_total_area_threshold : 0.5 - contour_approximation_absolute_total_area_threshold : 1.0 - max_number_of_iterations : 5 - -convex_decomposer: - decomposer_type : 'inner_convex_decomposition' # 'optimal_decompostion' - dent_angle_threshold_rad : 0.05 +preprocessing: + kernelSize: 3 # Kernel size of the median filter + numberOfRepeats: 3 # Number of times to apply the same filter + increasing: True # Increase the kernel size each iteration. + inpaintRadius: 0.05 # [m] sliding_window_plane_extractor: - kernel_size : 3 - plane_patch_error_threshold : 0.004 - surface_normal_angle_threshold_degrees : 10.0 - include_curvature_detection : true - include_ransac_refinement : false - global_plane_fit_error_threshold : 0.02 + kernel_size: 3 # Size of the sliding window patch used for normal vector calculation and planarity detection. Should be an odd number and at least 3. + plane_inclination_threshold_degrees: 45.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch + plane_patch_error_threshold: 0.005 # [m] The allowed root-mean-squared deviation from the plane fitted to the sliding window. + min_number_points_per_label: 10 # [#] Labels with less points assigned to them are discarded + connectivity: 4 # Label kernel connectivity. 4 or 8 (cross or box) + include_ransac_refinement: true # Enable RANSAC refinement if the plane is not globally fitting to the assigned points. + global_plane_fit_distance_error_threshold: 0.04 # [m] Allowed maximum distance from a point to the plane. If any point violates this, RANSAC is triggered + global_plane_fit_angle_error_threshold_degrees: 5.0 # [deg] Allowed normal vector deviation for a point w.r.t. the plane normal. If any point violates this, RANSAC is triggered ransac_plane_refinement: - probability : 0.01 - min_points : 200 - epsilon : 0.004 - cluster_epsilon : 0.0282842712475 - # Set maximum normal deviation. 0.98 < dot(surface_normal, point_normal); - normal_threshold : 0.98 + probability: 0.01 # Probability to miss the largest candidate shape. A lower probability provides a higher reliability and determinism at the cost of longer running times + min_points: 25 # This minimum number of points per plane. Controls the termination of the algorithm. + epsilon: 0.02 # Maximum distance to plane + cluster_epsilon: 0.05 # Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon + normal_threshold: 0.98 # Set maximum normal deviation. normal_threshold < dot(surface_normal, point_normal); + +contour_extraction: + offsetSize: 2 # Size of the kernel creating the boundary offset. In number of pixels. diff --git a/convex_plane_decomposition_ros/data/elevationMap_10_277cm.png b/convex_plane_decomposition_ros/data/elevationMap_10_277cm.png new file mode 100644 index 0000000000000000000000000000000000000000..8897f27fc0d33f94d865bd0136494253f78068ce GIT binary patch literal 21378 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 Eg4imfYybcN literal 0 HcmV?d00001 diff --git a/convex_plane_decomposition_ros/data/straightStairs_1m_1m_60cm.png b/convex_plane_decomposition_ros/data/straightStairs_1m_1m_60cm.png new file mode 100644 index 0000000000000000000000000000000000000000..cf42ffd2448fb87825a12d922d1058e000bb801d GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETvz{)FAsNnZryb-yqQJxA+qlJ{ zaEn9Z9KVV0*srlYbh-1vtk7n2i;D50+}K(=#4hgQ_;6K9b>Y@+5|gTL7oU6Q_EIiUVEXet49asR z9_8rWCcO6X;!v-fBJ+MGXRpnR2g|Cv)vmdK II;Vst0L1)fo&W#< literal 0 HcmV?d00001 diff --git a/convex_plane_decomposition_ros/data/terrain.png b/convex_plane_decomposition_ros/data/terrain.png new file mode 100644 index 0000000000000000000000000000000000000000..65cfe247f929043833c3d49de1f345a4a17f7adf GIT binary patch literal 112548 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≶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 g`e0c+1#i3!b+ +#include +#include + +#include + +#include + +namespace convex_plane_decomposition { + +// Forward declaration +class GridMapPreprocessing; +namespace sliding_window_plane_extractor { +class SlidingWindowPlaneExtractor; +} +namespace contour_extraction { +class ContourExtraction; +} + +class ConvexPlaneExtractionROS { + public: + ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle); + + ~ConvexPlaneExtractionROS(); + + bool loadParameters(const ros::NodeHandle& nodeHandle); + + private: + /** + * Callback method for the incoming grid map message. + * @param message the incoming message. + */ + void callback(const grid_map_msgs::GridMap& message); + + // Parameters + std::string elevationMapTopic_; + std::string elevationLayer_; + double subMapWidth_; + double subMapLength_; + + // ROS communication + ros::Subscriber elevationMapSubscriber_; + ros::Publisher filteredmapPublisher_; + ros::Publisher boundaryPublisher_; + ros::Publisher insetPublisher_; + ros::Publisher regionPublisher_; + + // Pipeline + std::mutex mutex_; + std::unique_ptr preprocessing_; + std::unique_ptr slidingWindowPlaneExtractor_; + std::unique_ptr contourExtraction_; +}; + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h new file mode 100644 index 00000000..7fe2271f --- /dev/null +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h @@ -0,0 +1,42 @@ +// +// Created by rgrandia on 14.06.20. +// + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace convex_plane_decomposition { + +CgalBbox2d fromMessage(const convex_plane_decomposition_msgs::BoundingBox2d& msg); +convex_plane_decomposition_msgs::BoundingBox2d toMessage(const CgalBbox2d& bbox2d); + +PlanarRegion fromMessage(const convex_plane_decomposition_msgs::PlanarRegion& msg); +convex_plane_decomposition_msgs::PlanarRegion toMessage(const PlanarRegion& planarRegion); + +PlanarTerrain fromMessage(const convex_plane_decomposition_msgs::PlanarTerrain& msg); +convex_plane_decomposition_msgs::PlanarTerrain toMessage(const PlanarTerrain& planarTerrain); + +TerrainPlane fromMessage(const geometry_msgs::Pose& msg); +geometry_msgs::Pose toMessage(const TerrainPlane& plane); + +CgalPoint2d fromMessage(const convex_plane_decomposition_msgs::Point2d& msg); +convex_plane_decomposition_msgs::Point2d toMessage(const CgalPoint2d& point2d); + +CgalPolygon2d fromMessage(const convex_plane_decomposition_msgs::Polygon2d& msg); +convex_plane_decomposition_msgs::Polygon2d toMessage(const CgalPolygon2d& polygon2d); + +CgalPolygonWithHoles2d fromMessage(const convex_plane_decomposition_msgs::PolygonWithHoles2d& msg); +convex_plane_decomposition_msgs::PolygonWithHoles2d toMessage(const CgalPolygonWithHoles2d& polygonWithHoles2d); + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h new file mode 100644 index 00000000..fffd28d7 --- /dev/null +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h @@ -0,0 +1,27 @@ +// +// Created by rgrandia on 10.06.20. +// + +#pragma once + +#include + +#include +#include +#include +#include + +namespace convex_plane_decomposition { + +PreprocessingParameters loadPreprocessingParameters(const ros::NodeHandle& nodeHandle, const std::string& prefix); + +contour_extraction::ContourExtractionParameters loadContourExtractionParameters(const ros::NodeHandle& nodeHandle, + const std::string& prefix); + +ransac_plane_extractor::RansacPlaneExtractorParameters loadRansacPlaneExtractorParameters(const ros::NodeHandle& nodeHandle, + const std::string& prefix); + +sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters loadSlidingWindowPlaneExtractorParameters( + const ros::NodeHandle& nodeHandle, const std::string& prefix); + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h new file mode 100644 index 00000000..d642c8cb --- /dev/null +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +#include + +namespace convex_plane_decomposition { + +jsk_recognition_msgs::PolygonArray convertBoundariesToRosPolygons(const std::vector& planarRegions, const std::string& frameId); + +jsk_recognition_msgs::PolygonArray convertInsetsToRosPolygons(const std::vector& planarRegions, const std::string& frameId); + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/convex_plane_decomposition_ros.hpp b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/convex_plane_decomposition_ros.hpp deleted file mode 100644 index bcc06ad2..00000000 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/convex_plane_decomposition_ros.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_CONVEX_PLANE_EXTRACTION_ROS_HPP_ -#define CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_CONVEX_PLANE_EXTRACTION_ROS_HPP_ - -#include - -#include -#include -#include - -#include - -#include "grid_map_preprocessing.hpp" -#include "pipeline_ros.hpp" - - -namespace convex_plane_decomposition { - -/*! - * Applies a chain of grid map filters to a topic and - * republishes the resulting grid map. - */ -class ConvexPlaneExtractionROS -{ - public: - - /*! - * Constructor. - * @param nodeHandle the ROS node handle. - * @param success signalizes if filter is configured ok or not. - */ - ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle, bool& success); - - /*! - * Destructor. - */ - virtual ~ConvexPlaneExtractionROS(); - - /*! - * Reads and verifies the ROS parameters. - * @return true if successful. - */ - bool readParameters(); - - /*! - * Callback method for the incoming grid map message. - * @param message the incoming message. - */ - void callback(const grid_map_msgs::GridMap& message); - - private: - - //! ROS nodehandle. - ros::NodeHandle& nodeHandle_; - - //! Name of the input grid map topic. - std::string inputTopic_; - - //! Name of the output grid map topic. - std::string outputTopic_; - - //! Grid map subscriber - ros::Subscriber subscriber_; - - ros::Publisher grid_map_publisher_; - - ros::Publisher convex_polygon_publisher_; - - ros::Publisher outer_contours_publisher_; - -}; - -} /* namespace */ -#endif \ No newline at end of file diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/grid_map_preprocessing.hpp b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/grid_map_preprocessing.hpp deleted file mode 100644 index d11cd155..00000000 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/grid_map_preprocessing.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_GRID_MAP_PREPROCESSING_HPP_ -#define CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_GRID_MAP_PREPROCESSING_HPP_ - -#include -#include - -#include - -namespace convex_plane_decomposition{ - using namespace grid_map; - - void applyMedianFilter(Eigen::MatrixXf& elevation_map, int kernel_size); -} -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_GRID_MAP_PREPROCESSING_HPP_ diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/pipeline_ros.hpp b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/pipeline_ros.hpp deleted file mode 100644 index b3bd98fc..00000000 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/pipeline_ros.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_PIPELINE_ROS_HPP_ -#define CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_PIPELINE_ROS_HPP_ - -#include -#include -#include -#include -#include - -#include "convex_plane_decomposition/pipeline.hpp" -#include "ros_visualizations.hpp" - -namespace convex_plane_decomposition { - -GridMapParameters loadGridMapParameters(ros::NodeHandle& nodeHandle, grid_map::GridMap& map); - -PipelineParameters loadPipelineParameters(ros::NodeHandle& nodeHandle, grid_map::GridMap& map); - -class PipelineROS { - public: - PipelineROS(ros::NodeHandle& nodeHandle, grid_map::GridMap& map) - : pipeline_(loadPipelineParameters(nodeHandle, map), loadGridMapParameters(nodeHandle, map)){} - - jsk_recognition_msgs::PolygonArray getConvexPolygons() const; - - jsk_recognition_msgs::PolygonArray getOuterPlaneContours() const; - - void augmentGridMapWithSegmentation(grid_map::GridMap& map); - - private: - - Pipeline pipeline_; -}; - -} // namespace convex_plane_decomposition -#endif //CONVEX_PLANE_EXTRACTION_ROS__PIPELINE_ROS_HPP_ diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ros_visualizations.hpp b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ros_visualizations.hpp deleted file mode 100644 index 42c14d45..00000000 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ros_visualizations.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_ROS_VISUALIZATIONS_HPP_ -#define CONVEX_PLANE_EXTRACTION_ROS_INCLUDE_ROS_VISUALIZATIONS_HPP_ - -#include - -#include -#include - -#include -#include -#include - -#include "convex_plane_decomposition/plane.hpp" - -namespace convex_plane_decomposition{ - - jsk_recognition_msgs::PolygonArray convertToRosPolygons(const Polygon3dVectorContainer &input_polygons); - -} - -#endif //CONVEX_PLANE_EXTRACTION_INCLUDE_ROS_VISUALIZATIONS_HPP_ diff --git a/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch b/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch index 5c72ea36..6666f0c9 100644 --- a/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch +++ b/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch @@ -1,8 +1,9 @@ - + - + diff --git a/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch b/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch new file mode 100644 index 00000000..f884c382 --- /dev/null +++ b/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/convex_plane_decomposition_ros/launch/convex_plane_decomposition_demo.launch b/convex_plane_decomposition_ros/launch/demo.launch similarity index 51% rename from convex_plane_decomposition_ros/launch/convex_plane_decomposition_demo.launch rename to convex_plane_decomposition_ros/launch/demo.launch index c8ec1644..43c47e4d 100644 --- a/convex_plane_decomposition_ros/launch/convex_plane_decomposition_demo.launch +++ b/convex_plane_decomposition_ros/launch/demo.launch @@ -1,17 +1,29 @@ + + + + - - + + - + + + + + + - + - + + + diff --git a/convex_plane_decomposition_ros/launch/rviz.launch b/convex_plane_decomposition_ros/launch/rviz.launch new file mode 100644 index 00000000..b3062364 --- /dev/null +++ b/convex_plane_decomposition_ros/launch/rviz.launch @@ -0,0 +1,5 @@ + + + + + diff --git a/convex_plane_decomposition_ros/package.xml b/convex_plane_decomposition_ros/package.xml index a1669e4d..2b59347f 100644 --- a/convex_plane_decomposition_ros/package.xml +++ b/convex_plane_decomposition_ros/package.xml @@ -24,5 +24,6 @@ cv_bridge jsk_recognition_msgs convex_plane_decomposition + convex_plane_decomposition_msgs diff --git a/convex_plane_decomposition_ros/rviz/config_demo.rviz b/convex_plane_decomposition_ros/rviz/config_demo.rviz index 42dc80c8..1eaec5a6 100644 --- a/convex_plane_decomposition_ros/rviz/config_demo.rviz +++ b/convex_plane_decomposition_ros/rviz/config_demo.rviz @@ -5,11 +5,8 @@ Panels: Property Tree Widget: Expanded: - /Global Options1 - - /PolygonArray1 - - /PolygonArray2 - - /GridMap1 - Splitter Ratio: 0.6114649772644043 - Tree Height: 1173 + Splitter Ratio: 0.4083484709262848 + Tree Height: 806 - Class: rviz/Selection Name: Selection - Class: rviz/Tool Properties @@ -36,20 +33,39 @@ Toolbars: Visualization Manager: Class: "" Displays: - - Class: rviz/Axes + - Alpha: 1 + Class: jsk_rviz_plugin/PolygonArray + Color: 25; 255; 0 Enabled: false - Length: 0.20000000298023224 - Name: Axes - Radius: 0.009999999776482582 - Reference Frame: + Name: Boundaries + Topic: /convex_plane_decomposition_ros/boundaries + Unreliable: false Value: false + coloring: Auto + enable lighting: true + normal length: 0.10000000149011612 + only border: true + show normal: false - Alpha: 1 + Class: jsk_rviz_plugin/PolygonArray + Color: 25; 255; 0 + Enabled: false + Name: Insets + Topic: /convex_plane_decomposition_ros/insets + Unreliable: false + Value: false + coloring: Auto + enable lighting: true + normal length: 0.10000000149011612 + only border: true + show normal: false + - Alpha: 0.10000000149011612 Autocompute Intensity Bounds: true Class: grid_map_rviz_plugin/GridMap Color: 200; 200; 200 Color Layer: elevation Color Transformer: GridMapLayer - Enabled: false + Enabled: true Height Layer: elevation Height Transformer: GridMapLayer History Length: 1 @@ -58,59 +74,17 @@ Visualization Manager: Max Intensity: 10 Min Color: 0; 0; 0 Min Intensity: 0 - Name: Elevation + Name: GridMap Show Grid Lines: true - Topic: /grid_map_filter_demo/filtered_map + Topic: /image_to_gridmap_demo/grid_map Unreliable: false Use Rainbow: true - Value: false - - Alpha: 1 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: normal_color - Color Transformer: ColorLayer - Enabled: false - Height Layer: elevation - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 255; 255; 255 - Max Intensity: 10 - Min Color: 0; 0; 0 - Min Intensity: 0 - Name: Normal mapping - Show Grid Lines: false - Topic: /grid_map_filter_demo/filtered_map - Unreliable: false - Use Rainbow: false - Value: false - - Alpha: 1 + Value: true + - Alpha: 0.10000000149011612 Autocompute Intensity Bounds: true Class: grid_map_rviz_plugin/GridMap Color: 200; 200; 200 - Color Layer: edges - Color Transformer: IntensityLayer - Enabled: false - Height Layer: elevation - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 255; 0; 0 - Max Intensity: 10 - Min Color: 255; 255; 255 - Min Intensity: 0 - Name: Edges - Show Grid Lines: false - Topic: /grid_map_filter_demo/filtered_map - Unreliable: false - Use Rainbow: false - Value: false - - Alpha: 1 - Autocompute Intensity Bounds: false - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: roughness + Color Layer: segmentation Color Transformer: IntensityLayer Enabled: false Height Layer: elevation @@ -118,106 +92,44 @@ Visualization Manager: History Length: 1 Invert Rainbow: false Max Color: 255; 255; 255 - Max Intensity: 0.07999999821186066 - Min Color: 0; 0; 0 - Min Intensity: -0.019999999552965164 - Name: Roughness - Show Grid Lines: false - Topic: /grid_map_filter_demo/filtered_map - Unreliable: false - Use Rainbow: true - Value: false - - Alpha: 1 - Autocompute Intensity Bounds: false - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: traversability - Color Transformer: GridMapLayer - Enabled: false - Height Layer: elevation - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: true - Max Color: 255; 255; 255 - Max Intensity: 1.2000000476837158 + Max Intensity: 10 Min Color: 0; 0; 0 Min Intensity: 0 - Name: Traversability - Show Grid Lines: false - Topic: /grid_map_filter_demo/filtered_map + Name: FilteredMap + Show Grid Lines: true + Topic: /convex_plane_decomposition_ros/filtered_map Unreliable: false Use Rainbow: true Value: false - - Class: rviz/Marker - Enabled: false - Marker Topic: /grid_map_visualization/surface_normals - Name: Surface Normals + - Class: rviz/MarkerArray + Enabled: true + Marker Topic: /segmented_planes_terrain_model_demo_node/convex_terrain + Name: ConvexRegion Namespaces: - {} + "": true Queue Size: 100 - Value: false - - Alpha: 1 - Class: rviz/Map - Color Scheme: map - Draw Behind: false - Enabled: false - Name: Elevation - Topic: /grid_map_visualization/elevation_grid - Unreliable: false - Use Timestamp: false - Value: false - - Alpha: 1 - Class: jsk_rviz_plugin/PolygonArray - Color: 25; 255; 0 - Enabled: true - Name: PolygonArray - Topic: /convex_plane_decomposition_ros/convex_polygons - Unreliable: false Value: true - coloring: Auto - enable lighting: true - normal length: 0.10000000149011612 - only border: false - show normal: true - - Alpha: 1 - Class: jsk_rviz_plugin/PolygonArray - Color: 25; 255; 0 + - Class: rviz/Marker Enabled: true - Name: PolygonArray - Topic: /convex_plane_decomposition_ros/outer_contours - Unreliable: false + Marker Topic: /segmented_planes_terrain_model_demo_node/queryPosition + Name: queryPosition + Namespaces: + "": true + Queue Size: 100 Value: true - coloring: Auto - enable lighting: true - normal length: 0.10000000149011612 - only border: true - show normal: true - - Alpha: 0.10000000149011612 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: elevation - Color Transformer: GridMapLayer + - Class: rviz/MarkerArray Enabled: true - Height Layer: elevation - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 255; 255; 255 - Max Intensity: 10 - Min Color: 0; 0; 0 - Min Intensity: 0 - Name: GridMap - Show Grid Lines: true - Topic: /convex_plane_decomposition_ros/convex_plane_decomposition - Unreliable: false - Use Rainbow: true + Marker Topic: /segmented_planes_terrain_model_demo_node/regionBoundary + Name: SelectedRegion + Namespaces: + "": true + Queue Size: 100 Value: true Enabled: true Global Options: Background Color: 255; 255; 255 Default Light: true - Fixed Frame: odom + Fixed Frame: map Frame Rate: 30 Name: root Tools: @@ -241,33 +153,33 @@ Visualization Manager: Views: Current: Class: rviz/Orbit - Distance: 6.349719524383545 + Distance: 0.8380365371704102 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 Swap Stereo Eyes: false Value: false Focal Point: - X: -1 - Y: -1 - Z: 2 + X: -0.02726033888757229 + Y: -0.07391251623630524 + Z: 0.2781669795513153 Focal Shape Fixed Size: true Focal Shape Size: 0.05000000074505806 Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.7997971177101135 + Pitch: 0.6397972702980042 Target Frame: Value: Orbit (rviz) - Yaw: 4.123183727264404 + Yaw: 3.0349738597869873 Saved: ~ Window Geometry: Displays: collapsed: false - Height: 1403 + Height: 1025 Hide Left Dock: false Hide Right Dock: true - QMainWindow State: 000000ff00000000fd00000004000000000000016a000004d7fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005e00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c0061007900730100000040000004d7000000ce00fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f0000040efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000280000040e000000ac00fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e1000001970000000300000a000000003efc0100000002fb0000000800540069006d0065010000000000000a000000025700fffffffb0000000800540069006d0065010000000000000450000000000000000000000890000004d700000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd00000004000000000000022900000363fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000363000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f0000040efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000280000040e000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000073d0000003efc0100000002fb0000000800540069006d006501000000000000073d000002eb00fffffffb0000000800540069006d006501000000000000045000000000000000000000050e0000036300000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -276,6 +188,6 @@ Window Geometry: collapsed: false Views: collapsed: true - Width: 2560 - X: 1360 - Y: 0 + Width: 1853 + X: 67 + Y: 253 diff --git a/convex_plane_decomposition_ros/src/convex_plane_decomposition_node.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp similarity index 62% rename from convex_plane_decomposition_ros/src/convex_plane_decomposition_node.cpp rename to convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp index 1714111c..fa32c89d 100644 --- a/convex_plane_decomposition_ros/src/convex_plane_decomposition_node.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp @@ -1,19 +1,19 @@ -#include "convex_plane_decomposition_ros/convex_plane_decomposition_ros.hpp" +#include "convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h" #include #include -int main(int argc, char** argv) -{ +int main(int argc, char** argv) { FLAGS_alsologtostderr = 1; FLAGS_colorlogtostderr = 1; FLAGS_v = 1; google::InitGoogleLogging(argv[0]); ros::init(argc, argv, "convex_plane_decomposition_ros"); ros::NodeHandle nodeHandle("~"); - bool success; - convex_plane_decomposition::ConvexPlaneExtractionROS convex_plane_decomposition_ros(nodeHandle, success); - if (success) ros::spin(); + + convex_plane_decomposition::ConvexPlaneExtractionROS convex_plane_decomposition_ros(nodeHandle); + ros::spin(); + return 0; } diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp new file mode 100644 index 00000000..0384fe9f --- /dev/null +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -0,0 +1,116 @@ +#include "convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h" + +#include + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include "convex_plane_decomposition/GridMapPreprocessing.h" +#include "convex_plane_decomposition/Nan.h" +#include "convex_plane_decomposition_msgs/PlanarTerrain.h" +#include "convex_plane_decomposition_ros/ParameterLoading.h" +#include "convex_plane_decomposition_ros/RosVisualizations.h" + +#include "convex_plane_decomposition_ros/MessageConversion.h" + +namespace convex_plane_decomposition { + +ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle) { + bool parametersLoaded = loadParameters(nodeHandle); + + if (parametersLoaded) { + elevationMapSubscriber_ = nodeHandle.subscribe(elevationMapTopic_, 1, &ConvexPlaneExtractionROS::callback, this); + filteredmapPublisher_ = nodeHandle.advertise("filtered_map", 1); + boundaryPublisher_ = nodeHandle.advertise("boundaries", 1); + insetPublisher_ = nodeHandle.advertise("insets", 1); + regionPublisher_ = nodeHandle.advertise("planar_terrain", 1); + } +} + +ConvexPlaneExtractionROS::~ConvexPlaneExtractionROS() = default; + +bool ConvexPlaneExtractionROS::loadParameters(const ros::NodeHandle& nodeHandle) { + if (!nodeHandle.getParam("elevation_topic", elevationMapTopic_)) { + ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `elevation_topic`."); + return false; + } + if (!nodeHandle.getParam("height_layer", elevationLayer_)) { + ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `height_layer`."); + return false; + } + if (!nodeHandle.getParam("submap/width", subMapWidth_)) { + ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `submap/width`."); + return false; + } + if (!nodeHandle.getParam("submap/length", subMapLength_)) { + ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `submap/length`."); + return false; + } + + const auto preprocessingParameters = loadPreprocessingParameters(nodeHandle, "preprocessing/"); + const auto contourExtractionParameters = loadContourExtractionParameters(nodeHandle, "contour_extraction/"); + const auto ransacPlaneExtractorParameters = loadRansacPlaneExtractorParameters(nodeHandle, "ransac_plane_refinement/"); + const auto slidingWindowPlaneExtractorParameters = loadSlidingWindowPlaneExtractorParameters(nodeHandle, "sliding_window_plane_extractor/"); + + std::lock_guard lock(mutex_); + preprocessing_ = std::make_unique(preprocessingParameters); + slidingWindowPlaneExtractor_ = std::make_unique(slidingWindowPlaneExtractorParameters, ransacPlaneExtractorParameters); + contourExtraction_ = std::make_unique(contourExtractionParameters); + + return true; +} + +void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { + std::lock_guard lock(mutex_); + + // Convert message to map. + ROS_INFO("Reading input map..."); + grid_map::GridMap messageMap; + grid_map::GridMapRosConverter::fromMessage(message, messageMap, {elevationLayer_}, false, false); + bool success; + grid_map::GridMap elevationMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(subMapWidth_, subMapLength_), success); + ROS_INFO("...done."); + + if (success) { + auto t0 = std::chrono::high_resolution_clock::now(); + preprocessing_ ->preprocess(elevationMap, elevationLayer_); + auto t1 = std::chrono::high_resolution_clock::now(); + VLOG(1) << "Preprocessing took " << 1e-3 * std::chrono::duration_cast( t1 - t0 ).count() << " [ms]\n"; + + // Run pipeline. + slidingWindowPlaneExtractor_->runExtraction(elevationMap, elevationLayer_); + auto t2 = std::chrono::high_resolution_clock::now(); + VLOG(1) << "Sliding window took " << 1e-3 * std::chrono::duration_cast( t2 - t1 ).count() << " [ms]\n"; + + const auto planarRegions = contourExtraction_->extractPlanarRegions(slidingWindowPlaneExtractor_->getSegmentedPlanesMap()); + auto t3 = std::chrono::high_resolution_clock::now(); + VLOG(1) << "Contour extraction took " << 1e-3 * std::chrono::duration_cast( t3 - t2 ).count() << " [ms]\n"; + + // Publish terrain + regionPublisher_.publish(toMessage(planarRegions)); + + // Visualize in Rviz. + reapplyNans(elevationMap.get(elevationLayer_)); + elevationMap.add("segmentation"); + cv::cv2eigen(slidingWindowPlaneExtractor_->getSegmentedPlanesMap().labeledImage, elevationMap.get("segmentation")); + grid_map_msgs::GridMap outputMessage; + grid_map::GridMapRosConverter::toMessage(elevationMap, outputMessage); + filteredmapPublisher_.publish(outputMessage); + + boundaryPublisher_.publish(convertBoundariesToRosPolygons(planarRegions, elevationMap.getFrameId())); + insetPublisher_.publish(convertInsetsToRosPolygons(planarRegions, elevationMap.getFrameId())); + } else { + ROS_WARN("[ConvexPlaneExtractionROS] Could not extract submap"); + } +} + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/src/MessageConversion.cpp b/convex_plane_decomposition_ros/src/MessageConversion.cpp new file mode 100644 index 00000000..a14f83a4 --- /dev/null +++ b/convex_plane_decomposition_ros/src/MessageConversion.cpp @@ -0,0 +1,139 @@ +// +// Created by rgrandia on 14.06.20. +// + +#include "convex_plane_decomposition_ros/MessageConversion.h" + +namespace convex_plane_decomposition { + +CgalBbox2d fromMessage(const convex_plane_decomposition_msgs::BoundingBox2d& msg) { + return {msg.min_x, msg.min_y, msg.max_x, msg.max_y}; +} + +convex_plane_decomposition_msgs::BoundingBox2d toMessage(const CgalBbox2d& bbox2d) { + convex_plane_decomposition_msgs::BoundingBox2d msg; + msg.min_x = bbox2d.xmin(); + msg.min_y = bbox2d.ymin(); + msg.max_x = bbox2d.xmax(); + msg.max_y = bbox2d.ymax(); + return msg; +} + +PlanarRegion fromMessage(const convex_plane_decomposition_msgs::PlanarRegion& msg) { + PlanarRegion planarRegion; + planarRegion.planeParameters = fromMessage(msg.plane_parameters); + planarRegion.boundaryWithInset.boundary = fromMessage(msg.boundary); + planarRegion.boundaryWithInset.insets.reserve(msg.insets.size()); + for (const auto& inset : msg.insets) { + planarRegion.boundaryWithInset.insets.emplace_back(fromMessage(inset)); + } + planarRegion.bbox2d = fromMessage(msg.bbox2d); + return planarRegion; +} + +convex_plane_decomposition_msgs::PlanarRegion toMessage(const PlanarRegion& planarRegion) { + convex_plane_decomposition_msgs::PlanarRegion msg; + msg.plane_parameters = toMessage(planarRegion.planeParameters); + msg.boundary = toMessage(planarRegion.boundaryWithInset.boundary); + msg.insets.reserve(planarRegion.boundaryWithInset.insets.size()); + for (const auto& inset : planarRegion.boundaryWithInset.insets) { + msg.insets.emplace_back(toMessage(inset)); + } + msg.bbox2d = toMessage(planarRegion.bbox2d); + return msg; +} + +PlanarTerrain fromMessage(const convex_plane_decomposition_msgs::PlanarTerrain& msg) { + PlanarTerrain planarTerrain; + planarTerrain.reserve(msg.planarRegions.size()); + for (const auto& planarRegion : msg.planarRegions) { + planarTerrain.emplace_back(fromMessage(planarRegion)); + } + return planarTerrain; +} + +convex_plane_decomposition_msgs::PlanarTerrain toMessage(const PlanarTerrain& planarTerrain) { + convex_plane_decomposition_msgs::PlanarTerrain msg; + msg.planarRegions.reserve(planarTerrain.size()); + for (const auto& planarRegion : planarTerrain) { + msg.planarRegions.emplace_back(toMessage(planarRegion)); + } + return msg; +} + +TerrainPlane fromMessage(const geometry_msgs::Pose& msg){ + TerrainPlane plane; + plane.positionInWorld.x() = msg.position.x; + plane.positionInWorld.y() = msg.position.y; + plane.positionInWorld.z() = msg.position.z; + Eigen::Quaterniond terrainOrientation; + terrainOrientation.x() = msg.orientation.x; + terrainOrientation.y() = msg.orientation.y; + terrainOrientation.z() = msg.orientation.z; + terrainOrientation.w() = msg.orientation.w; + plane.orientationWorldToTerrain = terrainOrientation.toRotationMatrix().transpose(); + return plane; +} + +geometry_msgs::Pose toMessage(const TerrainPlane& plane){ + geometry_msgs::Pose pose; + pose.position.x = plane.positionInWorld.x(); + pose.position.y = plane.positionInWorld.y(); + pose.position.z = plane.positionInWorld.z(); + Eigen::Quaterniond terrainOrientation(plane.orientationWorldToTerrain.transpose()); + pose.orientation.x = terrainOrientation.x(); + pose.orientation.y = terrainOrientation.y(); + pose.orientation.z = terrainOrientation.z(); + pose.orientation.w = terrainOrientation.w(); + return pose; +} + +CgalPoint2d fromMessage(const convex_plane_decomposition_msgs::Point2d& msg) { + return {msg.x, msg.y}; +} + +convex_plane_decomposition_msgs::Point2d toMessage(const CgalPoint2d& point2d) { + convex_plane_decomposition_msgs::Point2d msg; + msg.x = point2d.x(); + msg.y = point2d.y(); + return msg; +} + +CgalPolygon2d fromMessage(const convex_plane_decomposition_msgs::Polygon2d& msg) { + CgalPolygon2d polygon2d; + polygon2d.container().reserve(msg.points.size()); + for (const auto& point : msg.points) { + polygon2d.container().emplace_back(fromMessage(point)); + } + return polygon2d; +} + +convex_plane_decomposition_msgs::Polygon2d toMessage(const CgalPolygon2d& polygon2d) { + convex_plane_decomposition_msgs::Polygon2d msg; + msg.points.reserve(polygon2d.container().size()); + for (const auto& point : polygon2d) { + msg.points.emplace_back(toMessage(point)); + } + return msg; +} + +CgalPolygonWithHoles2d fromMessage(const convex_plane_decomposition_msgs::PolygonWithHoles2d& msg) { + CgalPolygonWithHoles2d polygonWithHoles2d; + polygonWithHoles2d.outer_boundary() = fromMessage(msg.outer_boundary); + for (const auto& hole : msg.holes) { + polygonWithHoles2d.add_hole(fromMessage(hole)); + } + return polygonWithHoles2d; +} + +convex_plane_decomposition_msgs::PolygonWithHoles2d toMessage(const CgalPolygonWithHoles2d& polygonWithHoles2d) { + convex_plane_decomposition_msgs::PolygonWithHoles2d msg; + msg.outer_boundary = toMessage(polygonWithHoles2d.outer_boundary()); + msg.holes.reserve(polygonWithHoles2d.number_of_holes()); + for (const auto& hole : polygonWithHoles2d.holes()) { + msg.holes.emplace_back(toMessage(hole)); + } + return msg; +} + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/convex_plane_decomposition_ros/src/ParameterLoading.cpp new file mode 100644 index 00000000..a702326f --- /dev/null +++ b/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -0,0 +1,59 @@ +// +// Created by rgrandia on 10.06.20. +// + +#include "convex_plane_decomposition_ros/ParameterLoading.h" + +namespace convex_plane_decomposition { + +template +void loadParameter(const ros::NodeHandle& nodeHandle, const std::string& prefix, const std::string& param, T& value) { + if (!nodeHandle.getParam(prefix + param, value)) { + ROS_ERROR_STREAM("[ConvexPlaneExtractionROS] Could not read parameter `" << param << "`. Setting parameter to default value : " << std::to_string(value)); + } +} + +PreprocessingParameters loadPreprocessingParameters(const ros::NodeHandle& nodeHandle, + const std::string& prefix) { + PreprocessingParameters preprocessingParameters; + loadParameter(nodeHandle, prefix, "kernelSize", preprocessingParameters.kernelSize); + loadParameter(nodeHandle, prefix, "numberOfRepeats", preprocessingParameters.numberOfRepeats); + loadParameter(nodeHandle, prefix, "increasing", preprocessingParameters.increasing); + loadParameter(nodeHandle, prefix, "inpaintRadius", preprocessingParameters.inpaintRadius); + return preprocessingParameters; +} + +contour_extraction::ContourExtractionParameters loadContourExtractionParameters(const ros::NodeHandle& nodeHandle, + const std::string& prefix) { + contour_extraction::ContourExtractionParameters contourParams; + loadParameter(nodeHandle, prefix, "offsetSize", contourParams.offsetSize); + return contourParams; +} + +ransac_plane_extractor::RansacPlaneExtractorParameters loadRansacPlaneExtractorParameters(const ros::NodeHandle& nodeHandle, + const std::string& prefix) { + ransac_plane_extractor::RansacPlaneExtractorParameters ransacParams; + loadParameter(nodeHandle, prefix, "probability", ransacParams.probability); + loadParameter(nodeHandle, prefix, "min_points", ransacParams.min_points); + loadParameter(nodeHandle, prefix, "epsilon", ransacParams.epsilon); + loadParameter(nodeHandle, prefix, "cluster_epsilon", ransacParams.cluster_epsilon); + loadParameter(nodeHandle, prefix, "normal_threshold", ransacParams.normal_threshold); + return ransacParams; +} + +sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters loadSlidingWindowPlaneExtractorParameters( + const ros::NodeHandle& nodeHandle, const std::string& prefix) { + sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters swParams; + loadParameter(nodeHandle, prefix, "kernel_size", swParams.kernel_size); + loadParameter(nodeHandle, prefix, "plane_inclination_threshold_degrees", swParams.plane_inclination_threshold_degrees); + loadParameter(nodeHandle, prefix, "plane_patch_error_threshold", swParams.plane_patch_error_threshold); + loadParameter(nodeHandle, prefix, "min_number_points_per_label", swParams.min_number_points_per_label); + loadParameter(nodeHandle, prefix, "connectivity", swParams.connectivity); + loadParameter(nodeHandle, prefix, "include_ransac_refinement", swParams.include_ransac_refinement); + loadParameter(nodeHandle, prefix, "global_plane_fit_distance_error_threshold", swParams.global_plane_fit_distance_error_threshold); + loadParameter(nodeHandle, prefix, "global_plane_fit_angle_error_threshold_degrees", + swParams.global_plane_fit_angle_error_threshold_degrees); + return swParams; +} + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/src/RosVisualizations.cpp b/convex_plane_decomposition_ros/src/RosVisualizations.cpp new file mode 100644 index 00000000..8622e0cc --- /dev/null +++ b/convex_plane_decomposition_ros/src/RosVisualizations.cpp @@ -0,0 +1,70 @@ +#include "convex_plane_decomposition_ros/RosVisualizations.h" + +#include +#include + +namespace convex_plane_decomposition { + +inline geometry_msgs::PolygonStamped to3d(const CgalPolygon2d& polygon, const TerrainPlane& planeParameters, + const std_msgs::Header& header) { + geometry_msgs::PolygonStamped polygon3d; + polygon3d.header = header; + for (const auto& point : polygon) { + geometry_msgs::Point32 point_ros; + const auto pointInWorld = positionInWorldFrameFromPositionInTerrain({point.x(), point.y(), 0.0}, planeParameters); + point_ros.x = pointInWorld.x(); + point_ros.y = pointInWorld.y(); + point_ros.z = pointInWorld.z(); + polygon3d.polygon.points.push_back(point_ros); + } + return polygon3d; +} + +inline std::vector to3d(const CgalPolygonWithHoles2d& polygonWithHoles, const TerrainPlane& planeParameters, + const std_msgs::Header& header) { + std::vector polygons; + + polygons.reserve(polygonWithHoles.number_of_holes() + 1); + polygons.emplace_back(to3d(polygonWithHoles.outer_boundary(), planeParameters, header)); + + for (const auto& hole : polygonWithHoles.holes()) { + polygons.emplace_back(to3d(hole, planeParameters, header)); + } + return polygons; +} + +jsk_recognition_msgs::PolygonArray convertBoundariesToRosPolygons(const std::vector& planarRegions, + const std::string& frameId) { + jsk_recognition_msgs::PolygonArray polygon_buffer; + std_msgs::Header header; + header.stamp = ros::Time::now(); + header.frame_id = frameId; + + polygon_buffer.header = header; + polygon_buffer.polygons.reserve(planarRegions.size()); // lower bound + for (const auto& planarRegion : planarRegions) { + auto boundaries = to3d(planarRegion.boundaryWithInset.boundary, planarRegion.planeParameters, header); + std::move(boundaries.begin(), boundaries.end(), std::back_inserter(polygon_buffer.polygons)); + } + + return polygon_buffer; +} + +jsk_recognition_msgs::PolygonArray convertInsetsToRosPolygons(const std::vector& planarRegions, const std::string& frameId) { + jsk_recognition_msgs::PolygonArray polygon_buffer; + std_msgs::Header header; + header.stamp = ros::Time::now(); + header.frame_id = frameId; + + polygon_buffer.header = header; + polygon_buffer.polygons.reserve(planarRegions.size()); // lower bound + for (const auto& planarRegion : planarRegions) { + for (const auto& inset : planarRegion.boundaryWithInset.insets) { + auto insets = to3d(inset, planarRegion.planeParameters, header); + std::move(insets.begin(), insets.end(), std::back_inserter(polygon_buffer.polygons)); + } + } + return polygon_buffer; +} + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp b/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp new file mode 100644 index 00000000..b6f51ae0 --- /dev/null +++ b/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp @@ -0,0 +1,74 @@ +// +// Created by rgrandia on 11.06.20. +// + +#include + +#include +#include +#include + +#include + +int count = 0; +double frequency; +std::string elevationMapTopic; +std::string elevationLayer; +std::string imageName; + +void callback(const grid_map_msgs::GridMap::ConstPtr& message) { + grid_map::GridMap messageMap; + grid_map::GridMapRosConverter::fromMessage(*message, messageMap); + + const auto& data = messageMap[elevationLayer]; + float maxHeight = std::numeric_limits::lowest(); + float minHeight = std::numeric_limits::max(); + for (int i=0; i(messageMap, elevationLayer, CV_8UC1, minHeight, maxHeight, image); + + int range = 100 * (maxHeight - minHeight); + cv::imwrite( imageName + "_" + std::to_string(count++) + "_" + std::to_string(range) + "cm.png", image); +} + +int main(int argc, char** argv) { + ros::init(argc, argv, "save_elevation_map_to_image"); + ros::NodeHandle nodeHandle("~"); + + if (!nodeHandle.getParam("frequency", frequency)) { + ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `frequency`."); + return 1; + } + if (!nodeHandle.getParam("elevation_topic", elevationMapTopic)) { + ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `elevation_topic`."); + return 1; + } + if (!nodeHandle.getParam("height_layer", elevationLayer)) { + ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `height_layer`."); + return 1; + } + if (!nodeHandle.getParam("imageName", imageName)) { + ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `imageName`."); + return 1; + } + + auto elevationMapSubscriber_ = nodeHandle.subscribe(elevationMapTopic, 1, callback); + + ros::Rate rate(frequency); + while(ros::ok()) + { + ros::spinOnce(); + rate.sleep(); + } + + return 0; +} \ No newline at end of file diff --git a/convex_plane_decomposition_ros/src/convex_plane_decomposition_ros.cpp b/convex_plane_decomposition_ros/src/convex_plane_decomposition_ros.cpp deleted file mode 100644 index 4b9b20cb..00000000 --- a/convex_plane_decomposition_ros/src/convex_plane_decomposition_ros.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "convex_plane_decomposition_ros/convex_plane_decomposition_ros.hpp" - -#include - -using namespace grid_map; - -namespace convex_plane_decomposition { - -ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle, bool& success) - : nodeHandle_(nodeHandle) { - if (!readParameters()) { - success = false; - return; - } - - subscriber_ = nodeHandle_.subscribe(inputTopic_, 1, &ConvexPlaneExtractionROS::callback, this); - grid_map_publisher_ = nodeHandle_.advertise("convex_plane_decomposition", 1, true); - convex_polygon_publisher_ = nodeHandle_.advertise("convex_polygons", 1); - outer_contours_publisher_ = nodeHandle_.advertise("outer_contours", 1); - success = true; -} - -ConvexPlaneExtractionROS::~ConvexPlaneExtractionROS(){} - -bool ConvexPlaneExtractionROS::readParameters() -{ - if (!nodeHandle_.getParam("input_topic", inputTopic_)) { - ROS_ERROR("Could not read parameter `input_topic`."); - return false; - } - return true; -} - -void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { - auto start_total = std::chrono::system_clock::now(); - - // Convert message to map. - ROS_INFO("Reading input map..."); - GridMap messageMap; - GridMapRosConverter::fromMessage(message, messageMap); - bool success; - GridMap inputMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(6, 6), success); - CHECK(success); - inputMap.setFrameId("odom"); - ROS_INFO("...done."); - VLOG(1) << "Applying median filtering to map."; - applyMedianFilter(inputMap.get("elevation"), 5); - - // Run pipeline. - VLOG(1) << "Running pipeline ..."; - PipelineROS pipeline_ros(nodeHandle_, inputMap); - VLOG(1) << "done."; - // Visualize in Rviz. - jsk_recognition_msgs::PolygonArray outer_plane_contours = pipeline_ros.getOuterPlaneContours(); - jsk_recognition_msgs::PolygonArray convex_polygons = pipeline_ros.getConvexPolygons(); - pipeline_ros.augmentGridMapWithSegmentation(inputMap); - - grid_map_msgs::GridMap outputMessage; - GridMapRosConverter::toMessage(inputMap, outputMessage); - grid_map_publisher_.publish(outputMessage); - - convex_polygon_publisher_.publish(convex_polygons); - outer_contours_publisher_.publish(outer_plane_contours); - -} - -} /* namespace */ diff --git a/convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp b/convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp deleted file mode 100644 index 057552fd..00000000 --- a/convex_plane_decomposition_ros/src/grid_map_preprocessing.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "convex_plane_decomposition_ros/grid_map_preprocessing.hpp" - -#include -#include -#include - -namespace convex_plane_decomposition{ - - void applyMedianFilter(Eigen::MatrixXf& elevation_map, int kernel_size) { - cv::Mat elevation_image; - cv::eigen2cv(elevation_map, elevation_image); - cv::Mat blurred_image; - cv::medianBlur(elevation_image, blurred_image, kernel_size); - cv::cv2eigen(blurred_image, elevation_map); - } - -} \ No newline at end of file diff --git a/convex_plane_decomposition_ros/src/pipeline_ros.cpp b/convex_plane_decomposition_ros/src/pipeline_ros.cpp deleted file mode 100644 index 1d076389..00000000 --- a/convex_plane_decomposition_ros/src/pipeline_ros.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "convex_plane_decomposition_ros/pipeline_ros.hpp" - -namespace convex_plane_decomposition { - -PipelineParameters loadPipelineParameters(ros::NodeHandle &nodeHandle, grid_map::GridMap &map) { - - const std::string kPackagePrefix = "/convex_plane_decomposition_ros"; - - // Grid map parameters. - GridMapParameters grid_map_parameters = loadGridMapParameters(nodeHandle, map); - - // Sliding Window Plane Extractor parameters. - sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters sliding_window_plane_extractor_parameters; - const std::string kSlidingWindowParametersPrefix = kPackagePrefix + "/sliding_window_plane_extractor/"; - if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "kernel_size", - sliding_window_plane_extractor_parameters.kernel_size)) { - ROS_ERROR("Could not read parameter `kernel_size`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "plane_patch_error_threshold", - sliding_window_plane_extractor_parameters.plane_patch_error_threshold)) { - ROS_ERROR("Could not read parameter `plane_patch_error_threshold`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "surface_normal_angle_threshold_degrees", - sliding_window_plane_extractor_parameters.surface_normal_angle_threshold_degrees)) { - ROS_ERROR("Could not read parameter `plane_patch_error_threshold`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "include_curvature_detection", - sliding_window_plane_extractor_parameters.include_curvature_detection)) { - ROS_ERROR("Could not read parameter `include_curvature_detection`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "include_ransac_refinement", - sliding_window_plane_extractor_parameters.include_ransac_refinement)) { - ROS_ERROR("Could not read parameter `include_ransac_refinement`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kSlidingWindowParametersPrefix + "global_plane_fit_error_threshold", - sliding_window_plane_extractor_parameters.global_plane_fit_error_threshold)) { - ROS_ERROR("Could not read parameter `global_plane_fit_error_threshold`. Setting parameter to default value."); - } - if (sliding_window_plane_extractor_parameters.include_ransac_refinement) { - // RASNAC refinement related parameters. - ransac_plane_extractor::RansacPlaneExtractorParameters ransac_plane_extractor_parameters; - const std::string kRansacRefinementParameterPrefix = kPackagePrefix + "/ransac_plane_refinement/"; - if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "probability", - ransac_plane_extractor_parameters.probability)) { - LOG(WARNING) << "Could not read parameter" << kRansacRefinementParameterPrefix - << "probability. Setting parameter to default value."; - } - if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "min_points", - ransac_plane_extractor_parameters.min_points)) { - LOG(WARNING) << "Could not read parameter" << kRansacRefinementParameterPrefix - << "ransac_min_points. Setting parameter to default value."; - } - if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "epsilon", ransac_plane_extractor_parameters.epsilon)) { - ROS_ERROR("Could not read parameter `epsilon`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "cluster_epsilon", - ransac_plane_extractor_parameters.cluster_epsilon)) { - ROS_ERROR("Could not read parameter `cluster_epsilon`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kRansacRefinementParameterPrefix + "normal_threshold", - ransac_plane_extractor_parameters.normal_threshold)) { - ROS_ERROR("Could not read parameter `normal_threshold`. Setting parameter to default value."); - } - sliding_window_plane_extractor_parameters.ransac_parameters = ransac_plane_extractor_parameters; - } - - // Polygonizer parameters. - PolygonizerParameters polygonizer_parameters; - polygonizer_parameters.resolution = grid_map_parameters.resolution; - const std::string kPolygonizerParametersPrefix = kPackagePrefix + "/polygonizer/"; - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "upsampling_factor", polygonizer_parameters.upsampling_factor)) { - ROS_ERROR("Could not read parameter `normal_threshold`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "activate_long_edge_upsampling", - polygonizer_parameters.activate_long_edge_upsampling)) { - ROS_ERROR("Could not read parameter `activate_long_edge_upsampling`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "activate_contour_approximation", - polygonizer_parameters.activate_contour_approximation)) { - ROS_ERROR("Could not read parameter `activate_contour_approximation`. Setting parameter to default value."); - } - if (polygonizer_parameters.activate_contour_approximation) { - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_relative_local_area_threshold", - polygonizer_parameters.contour_approximation_relative_local_area_threshold)) { - ROS_ERROR( - "Could not read parameter `contour_approximation_relative_area_threshold`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_absolute_local_area_threshold_squared_meters", - polygonizer_parameters.contour_approximation_absolute_local_area_threshold_squared_meters)) { - ROS_ERROR( - "Could not read parameter `contour_approximation_absolute_area_threshold_squared_meters`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_relative_total_area_threshold", - polygonizer_parameters.contour_approximation_relative_total_area_threshold)) { - ROS_ERROR("Could not read parameter `contour_approximation_relative_area_threshold`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "contour_approximation_absolute_total_area_threshold_squared_meters", - polygonizer_parameters.contour_approximation_absolute_total_area_threshold_squared_meters)) { - ROS_ERROR( - "Could not read parameter `contour_approximation_absolute_area_threshold_squared_meters`. Setting parameter to default value."); - } - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "max_number_of_iterations", - polygonizer_parameters.max_number_of_iterations)) { - ROS_ERROR( - "Could not read parameter `max_number_of_iterations`. Setting parameter to default value."); - } - } - if (!nodeHandle.getParam(kPolygonizerParametersPrefix + "hole_area_threshold_squared_meters", - polygonizer_parameters.hole_area_threshold_squared_meters)) { - ROS_ERROR("Could not read parameter `hole_area_threshold_squared_meters`. Setting parameter to default value."); - } - - // Convex decomposer parameters. - ConvexDecomposerParameters convex_decomposer_parameters; - const std::string kConvexDecomposerParametersPrefix = kPackagePrefix + "/convex_decomposer/"; - std::string decomposer_type; - if (!nodeHandle.getParam(kConvexDecomposerParametersPrefix + "decomposer_type", decomposer_type)) { - ROS_ERROR("Could not read parameter `decomposer_type`. Setting parameter to default value."); - } - if (decomposer_type == "optimal_decompostion") { - convex_decomposer_parameters.decomposition_type = ConvexDecompositionType::kGreeneOptimalDecomposition; - } else if (decomposer_type == "inner_convex_decomposition") { - convex_decomposer_parameters.decomposition_type = ConvexDecompositionType::kInnerConvexApproximation; - } - if (!nodeHandle.getParam(kConvexDecomposerParametersPrefix + "dent_angle_threshold_rad", - convex_decomposer_parameters.dent_angle_threshold_rad)) { - ROS_ERROR("Could not read parameter `dent_angle_threshold_rad`. Setting parameter to default value."); - } - - // Plane Factory parameters. - PlaneFactoryParameters plane_factory_parameters; - const std::string kPlaneFactoryParametersPrefix = kPackagePrefix + "/plane_factory/"; - if (!nodeHandle.getParam(kPlaneFactoryParametersPrefix + "plane_inclination_threshold_degrees", - plane_factory_parameters.plane_inclination_threshold_degrees)) { - ROS_ERROR("Could not read parameter `plane_inclination_threshold_degrees`. Setting parameter to default value."); - } - plane_factory_parameters.polygonizer_parameters = polygonizer_parameters; - plane_factory_parameters.convex_decomposer_parameters = convex_decomposer_parameters; - - // Pipeline parameters. - PipelineParameters pipeline_parameters; - pipeline_parameters.sliding_window_plane_extractor_parameters = sliding_window_plane_extractor_parameters; - pipeline_parameters.plane_factory_parameters = plane_factory_parameters; - return pipeline_parameters; -} - -GridMapParameters loadGridMapParameters(ros::NodeHandle &nodeHandle, grid_map::GridMap &map) { - // Grid map parameters. - std::string height_layer; - CHECK(nodeHandle.getParam("height_layer", height_layer)); - VLOG(1) << "Height layer is: " << height_layer; - GridMapParameters grid_map_parameters(map, height_layer); - - return grid_map_parameters; -} - -jsk_recognition_msgs::PolygonArray PipelineROS::getConvexPolygons() const { - const Polygon3dVectorContainer convex_polygon_buffer = pipeline_.getConvexPolygons(); - return convertToRosPolygons(convex_polygon_buffer); -} - -jsk_recognition_msgs::PolygonArray PipelineROS::getOuterPlaneContours() const { - const Polygon3dVectorContainer plane_contour_buffer = pipeline_.getPlaneContours(); - VLOG(1) << "Exported polygons: " << plane_contour_buffer.size(); - return convertToRosPolygons(plane_contour_buffer); -} - -void PipelineROS::augmentGridMapWithSegmentation(grid_map::GridMap &map) { - Eigen::MatrixXf new_layer = Eigen::MatrixXf::Zero(map.getSize().x(), map.getSize().y()); - cv::cv2eigen(pipeline_.getSegmentationImage(), new_layer); - map.add("plane_segmentation", new_layer); - VLOG(1) << "Added plane segmentation to Grid Map!"; -} - -} \ No newline at end of file diff --git a/convex_plane_decomposition_ros/src/ros_visualizations.cpp b/convex_plane_decomposition_ros/src/ros_visualizations.cpp deleted file mode 100644 index 71a0ce09..00000000 --- a/convex_plane_decomposition_ros/src/ros_visualizations.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "convex_plane_decomposition_ros/ros_visualizations.hpp" - -namespace convex_plane_decomposition { - - jsk_recognition_msgs::PolygonArray convertToRosPolygons(const Polygon3dVectorContainer &input_polygons) { - jsk_recognition_msgs::PolygonArray polygon_buffer; - polygon_buffer.header.stamp = ros::Time::now(); - polygon_buffer.header.frame_id = "odom"; - for (const auto &polygon : input_polygons) { - if (polygon.empty()) { - continue; - } - geometry_msgs::PolygonStamped polygon_stamped; - polygon_stamped.header.stamp = ros::Time::now(); - polygon_stamped.header.frame_id = "odom"; - for (const auto &point : polygon) { - geometry_msgs::Point32 point_ros; - point_ros.x = point.x(); - point_ros.y = point.y(); - point_ros.z = point(2); - polygon_stamped.polygon.points.push_back(point_ros); - } - polygon_buffer.polygons.push_back(polygon_stamped); - } - return polygon_buffer; - } -} - diff --git a/convex_plane_decomposition_ros/test/shapeGrowing.cpp b/convex_plane_decomposition_ros/test/shapeGrowing.cpp new file mode 100644 index 00000000..400af2e2 --- /dev/null +++ b/convex_plane_decomposition_ros/test/shapeGrowing.cpp @@ -0,0 +1,52 @@ +// +// Created by rgrandia on 08.06.20. +// + +#include +#include +#include + +#include + +using namespace convex_plane_decomposition; + +int main(int argc, char** argv) { + CgalPolygonWithHoles2d parentShape; + parentShape.outer_boundary().push_back({0.0, 0.0}); + parentShape.outer_boundary().push_back({0.0, 1000.0}); + parentShape.outer_boundary().push_back({400.0, 800.0}); + parentShape.outer_boundary().push_back({1000.0, 1000.0}); + parentShape.outer_boundary().push_back({800.0, 400.0}); + parentShape.outer_boundary().push_back({1000.0, 0.0}); + parentShape.add_hole(createRegularPolygon(CgalPoint2d(200.0, 200.0), 50, 4)); + parentShape.add_hole(createRegularPolygon(CgalPoint2d(600.0, 700.0), 100, 100)); + + // bounded_side_2 -> is inside + + int numberOfVertices = 16; // Multiple of 4 is nice. + double growthFactor = 1.05; + CgalPoint2d center{700.0, 300.0}; + + cv::Size imgSize(1000, 1000); + + const auto parentColor = randomColor(); + const auto fitColor = randomColor(); + + int N_test = 10; + for (int i = 0; i < N_test; i++) { + center = CgalPoint2d(rand()%1000, rand()%1000); + cv::Mat polygonImage(imgSize, CV_8UC3, cv::Vec3b(0, 0, 0)); + drawContour(polygonImage, parentShape, &parentColor); + drawContour(polygonImage, center, 2, &fitColor); + if (isInside(center, parentShape )) { + const auto fittedPolygon2d = growConvexPolygonInsideShape(parentShape, center, numberOfVertices, growthFactor); + drawContour(polygonImage, fittedPolygon2d, &fitColor); + } + + cv::namedWindow("Polygon", cv::WindowFlags::WINDOW_NORMAL); + cv::imshow("Polygon", polygonImage); + cv::waitKey(0); // Wait for a keystroke in the window + } + + return 0; +} diff --git a/convex_plane_decomposition_ros/test/test.cpp b/convex_plane_decomposition_ros/test/test.cpp new file mode 100644 index 00000000..64f3b18d --- /dev/null +++ b/convex_plane_decomposition_ros/test/test.cpp @@ -0,0 +1,181 @@ +// +// Created by rgrandia on 04.06.20. +// + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +using namespace convex_plane_decomposition; + +grid_map::GridMap loadElevationMapFromFile(const std::string& filePath, double resolution, double scale) { + // Read the file + cv::Mat image; + image = cv::imread(filePath, cv::ImreadModes::IMREAD_GRAYSCALE); + + // Check for invalid input + if (!image.data) { + throw std::runtime_error("Could not open or find the image"); + } + + // Min max values + double minValue, maxValue; + cv::minMaxLoc(image, &minValue, &maxValue); + + grid_map::GridMap mapOut({"elevation"}); + mapOut.setFrameId("odom"); + grid_map::GridMapCvConverter::initializeFromImage(image, resolution, mapOut, grid_map::Position(0.0, 0.0)); + grid_map::GridMapCvConverter::addLayerFromImage(image, std::string("elevation"), mapOut, float(0.0), float(scale), 0.5); + return mapOut; +} + +void plotSlidingWindow(const sliding_window_plane_extractor::SlidingWindowPlaneExtractor& planeExtractor) { + cv::namedWindow("Sliding Window binarymap", cv::WindowFlags::WINDOW_NORMAL); + cv::Mat binaryImage = planeExtractor.getBinaryLabeledImage(); + binaryImage.convertTo(binaryImage, CV_8UC1, 255); + cv::imshow("Sliding Window binarymap", binaryImage); + + cv::namedWindow("Sliding Window labels", cv::WindowFlags::WINDOW_NORMAL); + const auto& labelledImage = planeExtractor.getSegmentedPlanesMap().labeledImage; + const auto& labelsAndPlaneParameters = planeExtractor.getSegmentedPlanesMap().labelPlaneParameters; + std::vector colors(planeExtractor.getSegmentedPlanesMap().highestLabel + 1); + + colors[0] = cv::Vec3b(0, 0, 0); // background in white + for (int label = 1; label <= planeExtractor.getSegmentedPlanesMap().highestLabel; ++label) { + const auto labelIt = + std::find_if(labelsAndPlaneParameters.begin(), labelsAndPlaneParameters.end(), + [=](const std::pair& x) { return x.first == label; }); + if (labelIt != labelsAndPlaneParameters.end()) { + colors[label] = randomColor(); + } else { + colors[label] = colors[0]; + } + } + cv::Mat colorImg(labelledImage.size(), CV_8UC3); + for (int r = 0; r < colorImg.rows; ++r) { + for (int c = 0; c < colorImg.cols; ++c) { + int label = labelledImage.at(r, c); + auto& pixel = colorImg.at(r, c); + pixel = colors[label]; + } + } + cv::imshow("Sliding Window labels", colorImg); +} + +int main(int argc, char** argv) { + std::string folder = "/home/rgrandia/git/anymal/convex_terrain_representation/convex_plane_decomposition_ros/data/"; + std::string file = "elevationMap_8_139cm.png"; double heightScale = 1.39; +// std::string file = "demo_map.png"; double heightScale = 1.25; +// std::string file = "realStairs_125cm.png"; double heightScale = 1.25; +// std::string file = "terrain.png"; double heightScale = 1.25; +// std::string file = "holes.png"; double heightScale = 1.0; +// std::string file = "slope_1m_1m_20cm.png"; double heightScale = 0.2; +// std::string file = "straightStairs_1m_1m_60cm.png"; double heightScale = 0.6; + double resolution = 0.02; + + auto elevationMap = loadElevationMapFromFile(folder + file, resolution, heightScale); + + + cv::Mat image; + grid_map::GridMapCvConverter::toImage(elevationMap, "elevation", CV_8UC1, 0.0, heightScale, image); + cv::namedWindow("Elevation Map", cv::WindowFlags::WINDOW_NORMAL); + cv::imshow("Elevation Map", image); + + // ================== Filter ======================== // + PreprocessingParameters preprocessingParameters; + preprocessingParameters.kernelSize = 5; + preprocessingParameters.numberOfRepeats = 1; + + GridMapPreprocessing preprocessing(preprocessingParameters); + preprocessing.preprocess(elevationMap, "elevation"); + + grid_map::GridMapCvConverter::toImage(elevationMap, "elevation", CV_8UC1, 0.0, heightScale, image); + cv::namedWindow("Filtered Map", cv::WindowFlags::WINDOW_NORMAL); + cv::imshow("Filtered Map", image); + + // ============== Sliding Window =================== // + sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters swParams; + swParams.kernel_size = 3; + swParams.plane_inclination_threshold_degrees = 45.0; + swParams.plane_patch_error_threshold = 0.005; + swParams.min_number_points_per_label = 10; + swParams.include_ransac_refinement = true; + swParams.global_plane_fit_distance_error_threshold = 0.04; + swParams.global_plane_fit_angle_error_threshold_degrees = 5.0; + + ransac_plane_extractor::RansacPlaneExtractorParameters ransacParameters; + ransacParameters.probability = 0.01; + ransacParameters.min_points = 25; + ransacParameters.epsilon = 0.02; + ransacParameters.cluster_epsilon = 0.05; + ransacParameters.normal_threshold = 0.98; + + sliding_window_plane_extractor::SlidingWindowPlaneExtractor planeExtractor(swParams, ransacParameters); + planeExtractor.runExtraction(elevationMap, "elevation"); + plotSlidingWindow(planeExtractor); + + // ============== Polygons =================== // + const auto& labeled_image = planeExtractor.getSegmentedPlanesMap().labeledImage; + cv::Mat binary_image(labeled_image.size(), CV_8UC1); + + for (const auto& label_plane : planeExtractor.getSegmentedPlanesMap().labelPlaneParameters) { + const int label = label_plane.first; + const auto& plane_parameters = label_plane.second; + + binary_image = labeled_image == label; + + // Plot binary image + cv::Mat binaryImagePlot = binary_image; + binaryImagePlot.convertTo(binaryImagePlot, CV_8UC1, 255); + cv::namedWindow("Polygon binary image label", cv::WindowFlags::WINDOW_NORMAL); + cv::imshow("Polygon binary image label", binaryImagePlot); + + // Extract + int erosion_size = 2; // single sided length of the kernel + int erosion_type = cv::MORPH_CROSS; // cv::MORPH_ELLIPSE, cv::MORPH_RECT + cv::Mat element = cv::getStructuringElement( erosion_type, cv::Size( 2*erosion_size + 1, 2*erosion_size+1 ) ); + const auto boundariesAndInsets = contour_extraction::extractBoundaryAndInset(binary_image, element); + + // Plot eroded image + cv::Mat erodedImagePlot = binary_image; + erodedImagePlot.convertTo(erodedImagePlot, CV_8UC1, 255); + cv::namedWindow("Polygon binary eroded label", cv::WindowFlags::WINDOW_NORMAL); + cv::imshow("Polygon binary eroded label", erodedImagePlot); + + // Plot contours + int scale = 5; + cv::Size scaledSize = {scale* binary_image.size().width, scale* binary_image.size().height}; // transposed + cv::Mat realPolygonImage(scaledSize, CV_8UC3, cv::Vec3b(0, 0, 0)); + for (const auto& boundaryAndInset : boundariesAndInsets) { + drawContour(realPolygonImage, scaleShape(boundaryAndInset.boundary, scale)); + for (const auto& inset : boundaryAndInset.insets) { + drawContour(realPolygonImage, scaleShape(inset, scale)); + } + } + + cv::namedWindow("Polygon real", cv::WindowFlags::WINDOW_NORMAL); + cv::imshow("Polygon real", realPolygonImage); + cv::waitKey(0); // Wait for a keystroke in the window + } + + // ============== planar regions extraction ================ + contour_extraction::ContourExtractionParameters polyParams; + polyParams.offsetSize = 2; + + contour_extraction::ContourExtraction contourExtraction(polyParams); + contourExtraction.extractPlanarRegions(planeExtractor.getSegmentedPlanesMap()); + + return 0; +} \ No newline at end of file diff --git a/segmented_planes_terrain_model/CMakeLists.txt b/segmented_planes_terrain_model/CMakeLists.txt new file mode 100644 index 00000000..9b581345 --- /dev/null +++ b/segmented_planes_terrain_model/CMakeLists.txt @@ -0,0 +1,91 @@ +cmake_minimum_required(VERSION 3.1...3.15) +project(segmented_planes_terrain_model) + +# Catkin dependencies +find_package(catkin REQUIRED COMPONENTS + ocs2_switched_model_interface + ocs2_quadruped_interface + convex_plane_decomposition + convex_plane_decomposition_msgs + convex_plane_decomposition_ros + roscpp +) + +# OpenCv +find_package(OpenCV REQUIRED) + +# CGAL +find_package(CGAL COMPONENTS Core) + +# glog +find_package(PkgConfig REQUIRED) +pkg_check_modules(glog libglog REQUIRED) + +# Cpp standard version +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +################################### +## catkin specific configuration ## +################################### +catkin_package() + +########### +## Build ## +########### + +include_directories( + include + ${catkin_INCLUDE_DIRS} +) + +add_library(${PROJECT_NAME} + src/SegmentedPlanesTerrainModel.cpp + src/SegmentedPlanesTerrainModelRos.cpp + ) +add_dependencies(${PROJECT_NAME} + ${catkin_EXPORTED_TARGETS} + ) +target_link_libraries(${PROJECT_NAME} + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + glog + ) +target_compile_options(${PROJECT_NAME} + PUBLIC -DCGAL_HAS_THREADS + ) + +add_executable(${PROJECT_NAME}_demo_node + src/DemoNode.cpp +) +target_link_libraries(${PROJECT_NAME}_demo_node + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + glog + ${PROJECT_NAME} +) + +############# +## Install ## +############# + +install(TARGETS ${PROJECT_NAME} + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} + ) +install(DIRECTORY include/${PROJECT_NAME}/ + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} + ) + +install(TARGETS ${PROJECT_NAME}_demo_node + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +) + +install(DIRECTORY launch + DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +) + +############# +## Testing ## +############# diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h new file mode 100644 index 00000000..93c47671 --- /dev/null +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h @@ -0,0 +1,29 @@ +// +// Created by rgrandia on 23.06.20. +// + +#pragma once + +#include +#include "ocs2_switched_model_interface/terrain/TerrainModel.h" + +namespace switched_model { + +class SegmentedPlanesTerrainModel : switched_model::TerrainModel { + public: + SegmentedPlanesTerrainModel(convex_plane_decomposition::PlanarTerrain planarTerrain); + + TerrainPlane getLocalTerrainAtPositionInWorld(const vector3_t& positionInWorld) const override; + + ConvexTerrain getConvexTerrainAtPositionInWorld(const vector3_t& positionInWorld) const override; + + const convex_plane_decomposition::PlanarTerrain& PlanarTerrain() const { return planarTerrain_; } + + private: + convex_plane_decomposition::PlanarTerrain planarTerrain_; +}; + +std::pair getPlanarRegionAtPositionInWorld( + const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarTerrain& planarTerrain); + +} // namespace switched_model diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h new file mode 100644 index 00000000..1192f57a --- /dev/null +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h @@ -0,0 +1,32 @@ +// +// Created by rgrandia on 24.06.20. +// + +#pragma once + +#include + +#include + +#include + +#include "SegmentedPlanesTerrainModel.h" + +namespace switched_model { + +class SegmentedPlanesTerrainModelRos { + public: + SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle); + + /// Updates the terrain if a new one is available. Return if an update was made + bool update(std::unique_ptr& terrainPtr); + + private: + void callback(const convex_plane_decomposition_msgs::PlanarTerrain::ConstPtr& msg); + + ros::Subscriber terrainSubscriber_; + std::mutex updateMutex_; + std::unique_ptr terrainPtr_; +}; + +} // namespace switched_model diff --git a/segmented_planes_terrain_model/launch/demo.launch b/segmented_planes_terrain_model/launch/demo.launch new file mode 100644 index 00000000..be8661cb --- /dev/null +++ b/segmented_planes_terrain_model/launch/demo.launch @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/segmented_planes_terrain_model/package.xml b/segmented_planes_terrain_model/package.xml new file mode 100644 index 00000000..a0923b28 --- /dev/null +++ b/segmented_planes_terrain_model/package.xml @@ -0,0 +1,19 @@ + + + segmented_planes_terrain_model + 0.0.0 + The segmented_planes_terrain_model package + + Ruben Grandia + + TODO + + catkin + ocs2_switched_model_interface + ocs2_quadruped_interface + convex_plane_decomposition + convex_plane_decomposition_msgs + convex_plane_decomposition_ros + roscpp + + diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp new file mode 100644 index 00000000..41547703 --- /dev/null +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -0,0 +1,110 @@ +// +// Created by rgrandia on 24.06.20. +// + +#include "segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h" + +#include + +#include +#include + +#include + +#include +#include + +const std::string originFrameId_ = "map"; + +visualization_msgs::MarkerArray toMarker(const switched_model::ConvexTerrain& convexTerrain) { + visualization_msgs::MarkerArray markerArray; + + // Polygon message + std::vector boundary; + boundary.reserve(convexTerrain.boundary.size() + 1); + for (const auto& point : convexTerrain.boundary) { + const auto& pointInWorldFrame = positionInWorldFrameFromPositionInTerrain({point.x(), point.y(), 0.0}, convexTerrain.plane); + boundary.emplace_back(switched_model::getPointMsg(pointInWorldFrame)); + } + // Close the polygon + const auto& pointInWorldFrame = positionInWorldFrameFromPositionInTerrain({convexTerrain.boundary.front().x(), convexTerrain.boundary.front().y(), 0.0}, convexTerrain.plane); + boundary.emplace_back(switched_model::getPointMsg(pointInWorldFrame)); + + markerArray.markers.emplace_back(switched_model::getSphereMsg(convexTerrain.plane.positionInWorld, switched_model::Color::orange, 0.02)); + markerArray.markers.emplace_back(switched_model::getLineMsg(std::move(boundary), switched_model::Color::orange, 0.005)); + + // Add headers and Id + const ros::Time timeStamp = ros::Time::now(); + switched_model::assignHeader(markerArray.markers.begin(), markerArray.markers.end(), switched_model::getHeaderMsg(originFrameId_, timeStamp)); + switched_model::assignIncreasingId(markerArray.markers.begin(), markerArray.markers.end()); + + return markerArray; +} + +visualization_msgs::Marker toMarker(const switched_model::vector3_t& position) { + auto marker = switched_model::getSphereMsg(position, switched_model::Color::green, 0.02); + + const ros::Time timeStamp = ros::Time::now(); + marker.header = switched_model::getHeaderMsg(originFrameId_, timeStamp); + return marker; +} + +switched_model::ConvexTerrain toConvexTerrain(const convex_plane_decomposition::CgalPoint2d& centerInTerrainFrame, const convex_plane_decomposition::CgalPolygon2d& polygon, const switched_model::TerrainPlane& plane) { + // Return convex region with origin at the seedpoint + switched_model::ConvexTerrain convexTerrain; + const auto& seedpointInWorldFrame = positionInWorldFrameFromPositionInTerrain({centerInTerrainFrame.x(), centerInTerrainFrame.y(), 0.0}, plane); + convexTerrain.plane = {seedpointInWorldFrame, plane.orientationWorldToTerrain}; // Origin is at the seedpoint + convexTerrain.boundary.reserve(polygon.size()); + for (const auto& point : polygon) { + convexTerrain.boundary.emplace_back(point.x() - centerInTerrainFrame.x(), point.y() - centerInTerrainFrame.y()); // Shift points to new origin + } + return convexTerrain; +} + +int main(int argc, char** argv) { + ros::init(argc, argv, "segmented_planes_demo_node"); + ros::NodeHandle nodeHandle("~"); + + // Subscription to terrain + switched_model::SegmentedPlanesTerrainModelRos segmentedPlanesTerrainModelRos(nodeHandle); + std::unique_ptr terrainModel; + + // Publishers for visualization + auto positionPublisher_ = nodeHandle.advertise("queryPosition", 1); + auto convexTerrainPublisher_ = nodeHandle.advertise("convex_terrain", 1); + auto regionBoundaryPublisher_ = nodeHandle.advertise("regionBoundary", 1); + + // Node loop + ros::Rate rate(2.); + while (ros::ok()) { + if (segmentedPlanesTerrainModelRos.update(terrainModel)) { + ROS_INFO("Terrain model updated!!"); + } + + if (terrainModel) { + const auto RandomFloat = [](float a, float b) { + float random = ((float) rand()) / (float) RAND_MAX; + float diff = b - a; + float r = random * diff; + return a + r; + }; + + switched_model::vector3_t positionInWorld{RandomFloat(-2.0, 2.0), RandomFloat(-2.0, 2.0), RandomFloat(0.0, 1.0)}; + positionPublisher_.publish(toMarker(positionInWorld)); + std::cout << "Query position: " << positionInWorld.transpose() << std::endl; + + auto t0 = std::chrono::high_resolution_clock::now(); + const auto convexTerrain = terrainModel->getConvexTerrainAtPositionInWorld(positionInWorld); + auto t1 = std::chrono::high_resolution_clock::now(); + std::cout << "Query took " << 1e-3 * std::chrono::duration_cast( t1 - t0 ).count() << " [ms]\n"; + + positionPublisher_.publish(toMarker(positionInWorld)); + convexTerrainPublisher_.publish(toMarker(convexTerrain)); + } + + ros::spinOnce(); + rate.sleep(); + } + + return 0; +} \ No newline at end of file diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp new file mode 100644 index 00000000..48e3c036 --- /dev/null +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -0,0 +1,150 @@ +// +// Created by rgrandia on 23.06.20. +// + +#include "segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h" + +#include + +#include +#include + +namespace switched_model { + +SegmentedPlanesTerrainModel::SegmentedPlanesTerrainModel(convex_plane_decomposition::PlanarTerrain planarTerrain) + : planarTerrain_(std::move(planarTerrain)) {} + +TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorld(const vector3_t& positionInWorld) const { + const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_); + const auto& region = *regionAndSeedPoint.first; + const auto& seedpoint = regionAndSeedPoint.second; + const auto& seedpointInWorldFrame = positionInWorldFrameFromPositionInTerrain({seedpoint.x(), seedpoint.y(), 0.0}, region.planeParameters); + return TerrainPlane{seedpointInWorldFrame, region.planeParameters.orientationWorldToTerrain}; +} + +ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld(const vector3_t& positionInWorld) const { + const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_); + const auto& region = *regionAndSeedPoint.first; + const auto& seedpoint = regionAndSeedPoint.second; + const auto& seedpointInWorldFrame = positionInWorldFrameFromPositionInTerrain({seedpoint.x(), seedpoint.y(), 0.0}, region.planeParameters); + + // Convert boundary and seedpoint to terrain frame + const int numberOfVertices = 16; // Multiple of 4 is nice for symmetry. + const double growthFactor = 1.05; + const auto convexRegion = convex_plane_decomposition::growConvexPolygonInsideShape(region.boundaryWithInset.boundary, seedpoint, + numberOfVertices, growthFactor); + + // Return convex region with origin at the seedpoint + ConvexTerrain convexTerrain; + convexTerrain.plane = {seedpointInWorldFrame, region.planeParameters.orientationWorldToTerrain}; // Origin is at the seedpoint + convexTerrain.boundary.reserve(convexRegion.size()); + for (const auto& point : convexRegion) { + convexTerrain.boundary.emplace_back(point.x() - seedpoint.x(), point.y() - seedpoint.y()); // Shift points to new origin + } + return convexTerrain; +} + +double singleSidedSquaredDistance(double value, double min, double max) { + // - | 0 | + + // min max + // Returns 0.0 if between min and max. Returns the distance to one boundary otherwise. + if (value < min) { + double diff = min - value; + return diff * diff; + } else if (value < max) { + return 0.0; + } else { + double diff = max - value; + return diff * diff; + } +} + +double squaredDistanceToBoundingBox(const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarRegion& planarRegion) { + const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionInWorld, planarRegion.planeParameters); + double dxdx = singleSidedSquaredDistance(positionInTerrainFrame.x(), planarRegion.bbox2d.xmin(), planarRegion.bbox2d.xmax()); + double dydy = singleSidedSquaredDistance(positionInTerrainFrame.y(), planarRegion.bbox2d.ymin(), planarRegion.bbox2d.ymax()); + double dzdz = positionInTerrainFrame.z()* positionInTerrainFrame.z(); + return dxdx + dydy + dzdz; +} + +const convex_plane_decomposition::CgalPolygonWithHoles2d* findInsetContainingThePoint(const convex_plane_decomposition::CgalPoint2d& point, const std::vector& insets){ + for (const auto& inset : insets) { + if (convex_plane_decomposition::isInside(point, inset.outer_boundary())) { + return &inset; + } + } + return nullptr; +} + +std::pair squaredDistanceToBoundary(const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarRegion& planarRegion) { + const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionInWorld, planarRegion.planeParameters); + const double dzdz = positionInTerrainFrame.z()* positionInTerrainFrame.z(); + const convex_plane_decomposition::CgalPoint2d queryProjectedToPlane {positionInTerrainFrame.x(), positionInTerrainFrame.y()}; + + // First search if the projected point is inside any of the insets. + const auto insetPtrContainingPoint = findInsetContainingThePoint(queryProjectedToPlane, planarRegion.boundaryWithInset.insets); + + // Compute the projection + convex_plane_decomposition::CgalPoint2d projectedPoint; + if (insetPtrContainingPoint == nullptr) { + // Not inside any of the insets. Need to look for the closest one. The projection will be to the boundary + double minDistSquared = std::numeric_limits::max(); + for (const auto& inset : planarRegion.boundaryWithInset.insets) { + const auto closestPoint = convex_plane_decomposition::projectToClosestPoint(queryProjectedToPlane, inset.outer_boundary()); + double distSquare = convex_plane_decomposition::squaredDistance(closestPoint, queryProjectedToPlane); + if (distSquare < minDistSquared) { + projectedPoint = closestPoint; + minDistSquared = distSquare; + } + } + } else { + // Query point is inside and does not need projection... + projectedPoint = queryProjectedToPlane; + + // ... unless it is inside a hole + for (const auto& hole : insetPtrContainingPoint->holes()) { + if (convex_plane_decomposition::isInside(queryProjectedToPlane, hole)) { + projectedPoint = convex_plane_decomposition::projectToClosestPoint(queryProjectedToPlane, hole); + break; // No need to search other holes. Holes are not overlapping + } + } + } + + return {dzdz + convex_plane_decomposition::squaredDistance(projectedPoint, queryProjectedToPlane), projectedPoint}; +} + +std::pair +getPlanarRegionAtPositionInWorld(const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarTerrain& planarTerrain) { + // Compute distance to bounding boxes + std::vector> regionsAndBboxSquareDistances; + regionsAndBboxSquareDistances.reserve(planarTerrain.size()); + for (const auto& planarRegion : planarTerrain) { + regionsAndBboxSquareDistances.emplace_back(&planarRegion, squaredDistanceToBoundingBox(positionInWorld, planarRegion)); + } + + // Sort regions close to far + std::sort(regionsAndBboxSquareDistances.begin(), regionsAndBboxSquareDistances.end(), + [](const std::pair& lhs, + const std::pair& rhs) { + return lhs.second < rhs.second; + }); + + // Look for closest planar region. Use bbox as lower bound to stop searching. + double minDistSquared = std::numeric_limits::max(); + std::pair closestRegionAndProjection; + for(const auto& regionAndBboxSquareDistance : regionsAndBboxSquareDistances) { + if (regionAndBboxSquareDistance.second > minDistSquared) { + break; // regions are sorted. Can exit on the first lower bound being larger than running minimum + } + + const auto distanceSqrAndProjection = squaredDistanceToBoundary(positionInWorld, *regionAndBboxSquareDistance.first); + if (distanceSqrAndProjection.first < minDistSquared) { + minDistSquared = distanceSqrAndProjection.first; + closestRegionAndProjection = {regionAndBboxSquareDistance.first, distanceSqrAndProjection.second}; + } + } + + return closestRegionAndProjection; +} + +} // namespace switched_model diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp new file mode 100644 index 00000000..f9a1e35e --- /dev/null +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp @@ -0,0 +1,32 @@ +// +// Created by rgrandia on 24.06.20. +// + +#include "segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h" + +#include + +namespace switched_model { + +SegmentedPlanesTerrainModelRos::SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle) { + terrainSubscriber_ = nodehandle.subscribe("/convex_plane_decomposition_ros/planar_terrain", 1, &SegmentedPlanesTerrainModelRos::callback, this); +} + +bool SegmentedPlanesTerrainModelRos::update(std::unique_ptr& terrainPtr) { + std::lock_guard lock(updateMutex_); + + if (terrainPtr_) { + terrainPtr = std::move(terrainPtr_); + terrainPtr_ = nullptr; + return true; + } else { + return false; + } +} + +void SegmentedPlanesTerrainModelRos::callback(const convex_plane_decomposition_msgs::PlanarTerrain::ConstPtr& msg) { + std::lock_guard lock(updateMutex_); + terrainPtr_ = std::make_unique(convex_plane_decomposition::fromMessage(*msg)); +} + +} // namespace switched_model From 42df5accf24f4590739a939c4cfeb8179dfb76eb Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 24 Jun 2020 17:54:41 +0200 Subject: [PATCH 046/504] remove large image --- README.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..6258b4d1 --- /dev/null +++ b/README.md @@ -0,0 +1,67 @@ +# Convex Terrain Representation # + +## Overview +This is a C++ ROS package for extracting convex polygons from elevation maps created by elevation_mapping. + +## Installation + +### Dependencies + +#### OpenCV +Make sure you have openCV installed. +You can execute the following command to install it. +```bash +sudo apt-get install libopencv-dev +``` + +#### Eigen +```bash +sudo apt install libeigen3-dev +``` + +#### GLOG +```bash +sudo apt-get install libgoogle-glog-dev +``` + +#### CGAL +CGAL5 is required. You can download it from [here](https://github.com/CGAL/cgal/releases/tag/releases%2FCGAL-5.0.2) +and follow the instructions [here](https://doc.cgal.org/latest/Manual/installation.html#installation_idealworld). +Make sure you have the third-party libaries installed on you machine: +```bash +sudo apt-get install libgmp-dev +sudo apt-get install libgmp3-dev +sudo apt-get install libmpfr-dev +sudo apt-get install libboost-all-dev +``` + + +### ROS package dependencies + +#### JSK-visualization +For rviz-visualization the jsk-library is used. +```bash +sudo apt-get install ros-melodic-jsk-visualization +``` + +#### Grid Map +Grid map has to be located in you workspace. You can clone it using: +```bash +git clone https://github.com/ANYbotics/grid_map.git +``` + +## Usage +### Build +```bash +catkin build convex_plane_decomposition_ros +``` +### Run demo +```bash +roslaunch convex_plane_decomposition_ros convex_plane_decomposition_demo.launch +``` + +### Parameters +You can select input map topics, pipeline parameters etc. in the respective yaml file in +```bash +convex_plane_decomposition_ros/config/ +``` From 3f3c202cdfb3acf0f2a979e6e44601c3f539e2c2 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 25 Jun 2020 14:19:23 +0200 Subject: [PATCH 047/504] cleanup to integrate with controller --- segmented_planes_terrain_model/CMakeLists.txt | 14 ++++++- .../SegmentedPlanesTerrainModel.h | 2 +- .../SegmentedPlanesTerrainModelRos.h | 1 + .../SegmentedPlanesTerrainVisualization.h | 18 ++++++++ .../launch/demo.launch | 2 +- .../src/DemoNode.cpp | 31 +------------- .../src/SegmentedPlanesTerrainModelRos.cpp | 10 +++-- .../SegmentedPlanesTerrainVisualization.cpp | 41 +++++++++++++++++++ 8 files changed, 82 insertions(+), 37 deletions(-) create mode 100644 segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h create mode 100644 segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp diff --git a/segmented_planes_terrain_model/CMakeLists.txt b/segmented_planes_terrain_model/CMakeLists.txt index 9b581345..253ee617 100644 --- a/segmented_planes_terrain_model/CMakeLists.txt +++ b/segmented_planes_terrain_model/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.1...3.15) project(segmented_planes_terrain_model) # Catkin dependencies -find_package(catkin REQUIRED COMPONENTS +set(CATKIN_PACKAGE_DEPENDENCIES ocs2_switched_model_interface ocs2_quadruped_interface convex_plane_decomposition @@ -11,6 +11,10 @@ find_package(catkin REQUIRED COMPONENTS roscpp ) +find_package(catkin REQUIRED COMPONENTS + ${CATKIN_PACKAGE_DEPENDENCIES} +) + # OpenCv find_package(OpenCV REQUIRED) @@ -28,7 +32,12 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) ################################### ## catkin specific configuration ## ################################### -catkin_package() +catkin_package( + INCLUDE_DIRS include + LIBRARIES ${PROJECT_NAME} + CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} + DEPENDS OpenCV +) ########### ## Build ## @@ -42,6 +51,7 @@ include_directories( add_library(${PROJECT_NAME} src/SegmentedPlanesTerrainModel.cpp src/SegmentedPlanesTerrainModelRos.cpp + src/SegmentedPlanesTerrainVisualization.cpp ) add_dependencies(${PROJECT_NAME} ${catkin_EXPORTED_TARGETS} diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h index 93c47671..2c5bc281 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h @@ -9,7 +9,7 @@ namespace switched_model { -class SegmentedPlanesTerrainModel : switched_model::TerrainModel { +class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { public: SegmentedPlanesTerrainModel(convex_plane_decomposition::PlanarTerrain planarTerrain); diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h index 1192f57a..c55bfcfd 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h @@ -26,6 +26,7 @@ class SegmentedPlanesTerrainModelRos { ros::Subscriber terrainSubscriber_; std::mutex updateMutex_; + std::atomic_bool terrainUpdated_; std::unique_ptr terrainPtr_; }; diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h new file mode 100644 index 00000000..8a1c63ae --- /dev/null +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h @@ -0,0 +1,18 @@ +// +// Created by rgrandia on 24.06.20. +// + +#pragma once + +#include +#include + +#include + +#include + +namespace switched_model { + +visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, Color color, double diameter, double linewidth, double normalLength); + +} // namespace switched_model diff --git a/segmented_planes_terrain_model/launch/demo.launch b/segmented_planes_terrain_model/launch/demo.launch index be8661cb..ef8c03d9 100644 --- a/segmented_planes_terrain_model/launch/demo.launch +++ b/segmented_planes_terrain_model/launch/demo.launch @@ -1,6 +1,6 @@ - + diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp index 41547703..5bf1a721 100644 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -11,27 +11,12 @@ #include -#include -#include +#include "segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h" const std::string originFrameId_ = "map"; visualization_msgs::MarkerArray toMarker(const switched_model::ConvexTerrain& convexTerrain) { - visualization_msgs::MarkerArray markerArray; - - // Polygon message - std::vector boundary; - boundary.reserve(convexTerrain.boundary.size() + 1); - for (const auto& point : convexTerrain.boundary) { - const auto& pointInWorldFrame = positionInWorldFrameFromPositionInTerrain({point.x(), point.y(), 0.0}, convexTerrain.plane); - boundary.emplace_back(switched_model::getPointMsg(pointInWorldFrame)); - } - // Close the polygon - const auto& pointInWorldFrame = positionInWorldFrameFromPositionInTerrain({convexTerrain.boundary.front().x(), convexTerrain.boundary.front().y(), 0.0}, convexTerrain.plane); - boundary.emplace_back(switched_model::getPointMsg(pointInWorldFrame)); - - markerArray.markers.emplace_back(switched_model::getSphereMsg(convexTerrain.plane.positionInWorld, switched_model::Color::orange, 0.02)); - markerArray.markers.emplace_back(switched_model::getLineMsg(std::move(boundary), switched_model::Color::orange, 0.005)); + visualization_msgs::MarkerArray markerArray = switched_model::getConvexTerrainMarkers(convexTerrain, switched_model::Color::orange, 0.02, 0.005, 0.1); // Add headers and Id const ros::Time timeStamp = ros::Time::now(); @@ -49,18 +34,6 @@ visualization_msgs::Marker toMarker(const switched_model::vector3_t& position) { return marker; } -switched_model::ConvexTerrain toConvexTerrain(const convex_plane_decomposition::CgalPoint2d& centerInTerrainFrame, const convex_plane_decomposition::CgalPolygon2d& polygon, const switched_model::TerrainPlane& plane) { - // Return convex region with origin at the seedpoint - switched_model::ConvexTerrain convexTerrain; - const auto& seedpointInWorldFrame = positionInWorldFrameFromPositionInTerrain({centerInTerrainFrame.x(), centerInTerrainFrame.y(), 0.0}, plane); - convexTerrain.plane = {seedpointInWorldFrame, plane.orientationWorldToTerrain}; // Origin is at the seedpoint - convexTerrain.boundary.reserve(polygon.size()); - for (const auto& point : polygon) { - convexTerrain.boundary.emplace_back(point.x() - centerInTerrainFrame.x(), point.y() - centerInTerrainFrame.y()); // Shift points to new origin - } - return convexTerrain; -} - int main(int argc, char** argv) { ros::init(argc, argv, "segmented_planes_demo_node"); ros::NodeHandle nodeHandle("~"); diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp index f9a1e35e..dc450792 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp @@ -8,16 +8,17 @@ namespace switched_model { -SegmentedPlanesTerrainModelRos::SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle) { +SegmentedPlanesTerrainModelRos::SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle) : terrainUpdated_(false) { terrainSubscriber_ = nodehandle.subscribe("/convex_plane_decomposition_ros/planar_terrain", 1, &SegmentedPlanesTerrainModelRos::callback, this); } bool SegmentedPlanesTerrainModelRos::update(std::unique_ptr& terrainPtr) { - std::lock_guard lock(updateMutex_); - - if (terrainPtr_) { + // Avoid locking the mutex in the common case that the terrain is not updated. + if (terrainUpdated_) { + std::lock_guard lock(updateMutex_); terrainPtr = std::move(terrainPtr_); terrainPtr_ = nullptr; + terrainUpdated_ = false; return true; } else { return false; @@ -27,6 +28,7 @@ bool SegmentedPlanesTerrainModelRos::update(std::unique_ptr lock(updateMutex_); terrainPtr_ = std::make_unique(convex_plane_decomposition::fromMessage(*msg)); + terrainUpdated_ = true; } } // namespace switched_model diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp new file mode 100644 index 00000000..cad3bc3d --- /dev/null +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp @@ -0,0 +1,41 @@ +// +// Created by rgrandia on 24.06.20. +// + +#include "segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h" + +namespace switched_model { + +visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, Color color, double diameter, double linewidth, double normalLength) { + visualization_msgs::MarkerArray markerArray; + markerArray.markers.reserve(3); + + // Mark the center point + markerArray.markers.emplace_back(getSphereMsg(convexTerrain.plane.positionInWorld, color, diameter)); + + // Mark the surface normal + const vector3_t surfaceNormal = normalLength * surfaceNormalInWorld(convexTerrain.plane); + markerArray.markers.emplace_back(getArrowAtPointMsg(surfaceNormal, convexTerrain.plane.positionInWorld, color)); + + // Polygon message + if (!convexTerrain.boundary.empty()){ + std::vector boundary; + boundary.reserve(convexTerrain.boundary.size() + 1); + for (const auto& point : convexTerrain.boundary) { + const auto& pointInWorldFrame = positionInWorldFrameFromPositionInTerrain({point.x(), point.y(), 0.0}, convexTerrain.plane); + boundary.emplace_back(getPointMsg(pointInWorldFrame)); + } + // Close the polygon + const auto& pointInWorldFrame = positionInWorldFrameFromPositionInTerrain({convexTerrain.boundary.front().x(), convexTerrain.boundary.front().y(), 0.0}, convexTerrain.plane); + boundary.emplace_back(getPointMsg(pointInWorldFrame)); + + markerArray.markers.emplace_back(getLineMsg(std::move(boundary), color, linewidth)); + } else { + + } + + + return markerArray; +} + +} // namespace switched_model From e05d8b7e8b1e343fffccec2218931cf063feee1d Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 29 Jun 2020 13:51:56 +0200 Subject: [PATCH 048/504] minor fixes --- convex_plane_decomposition_ros/CMakeLists.txt | 6 +++++- convex_plane_decomposition_ros/config/parameters.yaml | 2 +- .../convex_plane_decomposition_ros/MessageConversion.h | 2 +- .../convex_plane_decomposition_save_elevationmap.launch | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index 69bf7f72..1ba33625 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.1...3.15) project(convex_plane_decomposition_ros) # Catkin dependencies -find_package(catkin REQUIRED COMPONENTS +set(CATKIN_PACKAGE_DEPENDENCIES roscpp grid_map_core grid_map_ros @@ -21,6 +21,10 @@ find_package(catkin REQUIRED COMPONENTS convex_plane_decomposition_msgs ) +find_package(catkin REQUIRED COMPONENTS + ${CATKIN_PACKAGE_DEPENDENCIES} +) + # OpenCv find_package(OpenCV REQUIRED) diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index d6fe9e03..180bf395 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -24,7 +24,7 @@ ransac_plane_refinement: probability: 0.01 # Probability to miss the largest candidate shape. A lower probability provides a higher reliability and determinism at the cost of longer running times min_points: 25 # This minimum number of points per plane. Controls the termination of the algorithm. epsilon: 0.02 # Maximum distance to plane - cluster_epsilon: 0.05 # Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon + cluster_epsilon: 0.02 # Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon normal_threshold: 0.98 # Set maximum normal deviation. normal_threshold < dot(surface_normal, point_normal); contour_extraction: diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h index 7fe2271f..24d40a11 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h @@ -6,7 +6,7 @@ #include -#include +#include #include #include #include diff --git a/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch b/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch index f884c382..d2b9ec81 100644 --- a/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch +++ b/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch @@ -3,7 +3,7 @@ - + From 9953d0f73809ce02e95573d6013c96ac4a332f1c Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 29 Jun 2020 17:10:16 +0200 Subject: [PATCH 049/504] wrap cgal into a catkin package --- cgal5_catkin/.gitignore | 32 ++++++++++++++++ cgal5_catkin/CMakeLists.txt | 28 ++++++++++++++ cgal5_catkin/README.md | 2 + cgal5_catkin/cmake/cgal-extras.cmake.in | 2 + cgal5_catkin/package.xml | 10 +++++ convex_plane_decomposition/CMakeLists.txt | 37 +++++++++---------- .../ransac/RansacPlaneExtractor.hpp | 8 ++-- convex_plane_decomposition/package.xml | 1 + convex_plane_decomposition_ros/CMakeLists.txt | 19 ---------- .../rviz/config_demo.rviz | 18 ++++----- segmented_planes_terrain_model/CMakeLists.txt | 16 +------- 11 files changed, 107 insertions(+), 66 deletions(-) create mode 100644 cgal5_catkin/.gitignore create mode 100644 cgal5_catkin/CMakeLists.txt create mode 100644 cgal5_catkin/README.md create mode 100644 cgal5_catkin/cmake/cgal-extras.cmake.in create mode 100644 cgal5_catkin/package.xml diff --git a/cgal5_catkin/.gitignore b/cgal5_catkin/.gitignore new file mode 100644 index 00000000..259148fa --- /dev/null +++ b/cgal5_catkin/.gitignore @@ -0,0 +1,32 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app diff --git a/cgal5_catkin/CMakeLists.txt b/cgal5_catkin/CMakeLists.txt new file mode 100644 index 00000000..2582a1a7 --- /dev/null +++ b/cgal5_catkin/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.10) +project(cgal5_catkin) + +find_package(catkin REQUIRED) + +include(ExternalProject) + +set(VERSION 5.0.2) + +file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/include) + +set(CGAL_VERSION 5.0.2) +ExternalProject_Add(cgal + URL https://github.com/CGAL/cgal/archive/releases/CGAL-${CGAL_VERSION}.tar.gz + UPDATE_COMMAND "" + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=${CATKIN_DEVEL_PREFIX} + -DWITH_CGAL_Qt5:BOOL=OFF + -DWITH_CGAL_ImageIO:BOOL=OFF + -DCMAKE_BUILD_TYPE:STRING=Release + BUILD_COMMAND $(MAKE) + INSTALL_COMMAND $(MAKE) install +) + +catkin_package( + INCLUDE_DIRS ${CATKIN_DEVEL_PREFIX}/include + CFG_EXTRAS cgal-extras.cmake +) diff --git a/cgal5_catkin/README.md b/cgal5_catkin/README.md new file mode 100644 index 00000000..6d808478 --- /dev/null +++ b/cgal5_catkin/README.md @@ -0,0 +1,2 @@ +# cgal_catkin +Catkin wrapper of the Computational Geometry Algorithms Library (CGAL) diff --git a/cgal5_catkin/cmake/cgal-extras.cmake.in b/cgal5_catkin/cmake/cgal-extras.cmake.in new file mode 100644 index 00000000..aebefc49 --- /dev/null +++ b/cgal5_catkin/cmake/cgal-extras.cmake.in @@ -0,0 +1,2 @@ +# Makes CGAL/find___.cmake available +list(APPEND CMAKE_MODULE_PATH @CATKIN_DEVEL_PREFIX@/lib/cmake/CGAL) \ No newline at end of file diff --git a/cgal5_catkin/package.xml b/cgal5_catkin/package.xml new file mode 100644 index 00000000..29ae2f27 --- /dev/null +++ b/cgal5_catkin/package.xml @@ -0,0 +1,10 @@ + + cgal5_catkin + 5.0.2 + Catkin wrapper for CGAL 5. + Ruben Grandia + + See package + + catkin + diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 10109aa6..327de6aa 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -3,6 +3,7 @@ project(convex_plane_decomposition) # Catkin dependencies set(CATKIN_PACKAGE_DEPENDENCIES + cgal5_catkin grid_map_core ocs2_switched_model_interface ) @@ -11,25 +12,21 @@ find_package(catkin REQUIRED COMPONENTS ${CATKIN_PACKAGE_DEPENDENCIES} ) -# CGAL -find_package(CGAL QUIET) -find_package(GMP REQUIRED) -find_package(MPFR REQUIRED) - -# Boost -find_package(Boost COMPONENTS thread REQUIRED) +# CGAL dependencies (QUIET because they cannot be found by Clion) +find_package(GMP 4.2 QUIET) +find_package(MPFR 2.2.1 QUIET) +find_package(Boost 1.57 QUIET) # OpenCv -find_package(OpenCV REQUIRED - COMPONENTS - opencv_highgui - CONFIG -) +find_package(OpenCV REQUIRED COMPONENTS opencv_highgui CONFIG) # glog find_package(PkgConfig REQUIRED) pkg_check_modules(glog libglog REQUIRED) +# Eigen +find_package(Eigen3 3.3 REQUIRED NO_MODULE) + # Cpp standard version set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -38,10 +35,15 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) ## catkin specific configuration ## ################################### catkin_package( - INCLUDE_DIRS include - LIBRARIES ${PROJECT_NAME} - CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS OpenCV CGAL GMP MPFR glog Boost + INCLUDE_DIRS + include + ${EIGEN3_INCLUDE_DIRS} + LIBRARIES + ${PROJECT_NAME} + CATKIN_DEPENDS + ${CATKIN_PACKAGE_DEPENDENCIES} + DEPENDS + OpenCV glog GMP MPFR Boost ) ########### @@ -52,7 +54,6 @@ include_directories( include ${catkin_INCLUDE_DIRS} ${EIGEN3_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} ) add_library(${PROJECT_NAME} @@ -68,9 +69,7 @@ add_dependencies(${PROJECT_NAME} ) target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} - ${CGAL_LIBRARIES} ${OpenCV_LIBRARIES} - ${Boost_LIBRARIES} glog gmp mpfr diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp index 82a8ba65..8a9ad54d 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp +++ b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp @@ -2,10 +2,10 @@ #include -#include "CGAL/Exact_predicates_inexact_constructions_kernel.h" -#include "CGAL/Point_with_normal_3.h" -#include "CGAL/Shape_detection/Efficient_RANSAC.h" -#include "CGAL/property_map.h" +#include +#include +#include +#include #include "RansacPlaneExtractorParameters.h" diff --git a/convex_plane_decomposition/package.xml b/convex_plane_decomposition/package.xml index 840a1008..df94a10d 100644 --- a/convex_plane_decomposition/package.xml +++ b/convex_plane_decomposition/package.xml @@ -9,6 +9,7 @@ TODO catkin + cgal5_catkin grid_map_core ocs2_switched_model_interface diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index 1ba33625..fcfe971f 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -28,12 +28,6 @@ find_package(catkin REQUIRED COMPONENTS # OpenCv find_package(OpenCV REQUIRED) -# Qt -find_package(Qt5 COMPONENTS Xml Script OpenGL Svg) - -# CGAL -find_package(CGAL COMPONENTS Core Qt5) - # glog find_package(PkgConfig REQUIRED) pkg_check_modules(glog libglog REQUIRED) @@ -75,9 +69,6 @@ target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES} glog ) -target_compile_options(${PROJECT_NAME} - PUBLIC -DCGAL_HAS_THREADS - ) add_executable(${PROJECT_NAME}_node src/ConvexPlaneDecompositionNode.cpp @@ -96,11 +87,6 @@ target_link_libraries(${PROJECT_NAME}_test ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} glog - Qt5::Xml Qt5::Script Qt5::OpenGL Qt5::Svg - CGAL::CGAL CGAL::CGAL_Core CGAL::CGAL_Qt5 - ) -target_compile_options(${PROJECT_NAME}_test - PUBLIC -DCGAL_HAS_THREADS -DCGAL_USE_BASIC_VIEWER ) add_executable(${PROJECT_NAME}_shapegrowing @@ -110,11 +96,6 @@ target_link_libraries(${PROJECT_NAME}_shapegrowing ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} glog - Qt5::Xml Qt5::Script Qt5::OpenGL Qt5::Svg - CGAL::CGAL CGAL::CGAL_Core CGAL::CGAL_Qt5 - ) -target_compile_options(${PROJECT_NAME}_shapegrowing - PUBLIC -DCGAL_HAS_THREADS -DCGAL_USE_BASIC_VIEWER ) add_executable(${PROJECT_NAME}_save_elevationmap diff --git a/convex_plane_decomposition_ros/rviz/config_demo.rviz b/convex_plane_decomposition_ros/rviz/config_demo.rviz index 1eaec5a6..7f2f8a13 100644 --- a/convex_plane_decomposition_ros/rviz/config_demo.rviz +++ b/convex_plane_decomposition_ros/rviz/config_demo.rviz @@ -36,11 +36,11 @@ Visualization Manager: - Alpha: 1 Class: jsk_rviz_plugin/PolygonArray Color: 25; 255; 0 - Enabled: false + Enabled: true Name: Boundaries Topic: /convex_plane_decomposition_ros/boundaries Unreliable: false - Value: false + Value: true coloring: Auto enable lighting: true normal length: 0.10000000149011612 @@ -106,7 +106,7 @@ Visualization Manager: Marker Topic: /segmented_planes_terrain_model_demo_node/convex_terrain Name: ConvexRegion Namespaces: - "": true + {} Queue Size: 100 Value: true - Class: rviz/Marker @@ -114,7 +114,7 @@ Visualization Manager: Marker Topic: /segmented_planes_terrain_model_demo_node/queryPosition Name: queryPosition Namespaces: - "": true + {} Queue Size: 100 Value: true - Class: rviz/MarkerArray @@ -122,7 +122,7 @@ Visualization Manager: Marker Topic: /segmented_planes_terrain_model_demo_node/regionBoundary Name: SelectedRegion Namespaces: - "": true + {} Queue Size: 100 Value: true Enabled: true @@ -153,7 +153,7 @@ Visualization Manager: Views: Current: Class: rviz/Orbit - Distance: 0.8380365371704102 + Distance: 4.217182636260986 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 @@ -168,10 +168,10 @@ Visualization Manager: Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.6397972702980042 + Pitch: 0.6197972893714905 Target Frame: Value: Orbit (rviz) - Yaw: 3.0349738597869873 + Yaw: 3.8899669647216797 Saved: ~ Window Geometry: Displays: @@ -190,4 +190,4 @@ Window Geometry: collapsed: true Width: 1853 X: 67 - Y: 253 + Y: 27 diff --git a/segmented_planes_terrain_model/CMakeLists.txt b/segmented_planes_terrain_model/CMakeLists.txt index 253ee617..9aa9420a 100644 --- a/segmented_planes_terrain_model/CMakeLists.txt +++ b/segmented_planes_terrain_model/CMakeLists.txt @@ -15,16 +15,6 @@ find_package(catkin REQUIRED COMPONENTS ${CATKIN_PACKAGE_DEPENDENCIES} ) -# OpenCv -find_package(OpenCV REQUIRED) - -# CGAL -find_package(CGAL COMPONENTS Core) - -# glog -find_package(PkgConfig REQUIRED) -pkg_check_modules(glog libglog REQUIRED) - # Cpp standard version set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -36,7 +26,7 @@ catkin_package( INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS OpenCV + DEPENDS ) ########### @@ -58,8 +48,6 @@ add_dependencies(${PROJECT_NAME} ) target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - glog ) target_compile_options(${PROJECT_NAME} PUBLIC -DCGAL_HAS_THREADS @@ -70,8 +58,6 @@ add_executable(${PROJECT_NAME}_demo_node ) target_link_libraries(${PROJECT_NAME}_demo_node ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - glog ${PROJECT_NAME} ) From 0c61359dbfa11615fe63604187f38252bf689471 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 30 Jun 2020 10:47:11 +0200 Subject: [PATCH 050/504] clean up dependencies --- README.md | 13 +--- cgal5_catkin/README.md | 2 +- convex_plane_decomposition/CMakeLists.txt | 11 +-- .../ConvexRegionGrowing.h | 9 +-- .../include/convex_plane_decomposition/Draw.h | 5 +- .../GeometryUtils.h | 12 ++-- .../GridMapPreprocessing.h | 13 ++-- .../convex_plane_decomposition/PolygonTypes.h | 2 - .../SegmentedPlanesMap.h | 1 + .../ContourExtractionParameters.h | 3 +- .../SlidingWindowPlaneExtractor.h | 1 - .../SlidingWindowPlaneExtractor.cpp | 9 --- .../CMakeLists.txt | 2 +- convex_plane_decomposition_ros/CMakeLists.txt | 53 ++++++--------- .../ConvexPlaneDecompositionRos.h | 2 +- .../launch/convex_plane_decomposition.launch | 1 + .../launch/demo.launch | 1 + convex_plane_decomposition_ros/package.xml | 6 -- .../src/ConvexPlaneDecompositionNode.cpp | 19 ++++-- .../src/ConvexPlaneDecompositionRos.cpp | 16 ++--- segmented_planes_terrain_model/CMakeLists.txt | 3 +- .../SegmentedPlanesTerrainModel.h | 4 +- .../SegmentedPlanesTerrainVisualization.h | 3 +- segmented_planes_terrain_model/package.xml | 1 + .../src/DemoNode.cpp | 14 ++-- .../src/SegmentedPlanesTerrainModel.cpp | 68 ++++++++++--------- .../src/SegmentedPlanesTerrainModelRos.cpp | 3 +- .../SegmentedPlanesTerrainVisualization.cpp | 10 +-- 28 files changed, 134 insertions(+), 153 deletions(-) diff --git a/README.md b/README.md index 6258b4d1..0fa1cce7 100644 --- a/README.md +++ b/README.md @@ -19,23 +19,15 @@ sudo apt-get install libopencv-dev sudo apt install libeigen3-dev ``` -#### GLOG -```bash -sudo apt-get install libgoogle-glog-dev -``` - #### CGAL -CGAL5 is required. You can download it from [here](https://github.com/CGAL/cgal/releases/tag/releases%2FCGAL-5.0.2) -and follow the instructions [here](https://doc.cgal.org/latest/Manual/installation.html#installation_idealworld). +CGAL5 is required. It will be automatically downloaded and installed into the catkin workspace by the cgal5_catkin package. Make sure you have the third-party libaries installed on you machine: ```bash sudo apt-get install libgmp-dev -sudo apt-get install libgmp3-dev sudo apt-get install libmpfr-dev sudo apt-get install libboost-all-dev ``` - ### ROS package dependencies #### JSK-visualization @@ -45,7 +37,7 @@ sudo apt-get install ros-melodic-jsk-visualization ``` #### Grid Map -Grid map has to be located in you workspace. You can clone it using: +Grid map is available through ANYmal-research, or you can add it to your workspace. You can clone it using: ```bash git clone https://github.com/ANYbotics/grid_map.git ``` @@ -65,3 +57,4 @@ You can select input map topics, pipeline parameters etc. in the respective yaml ```bash convex_plane_decomposition_ros/config/ ``` +Some other parameters are set through the launch files. \ No newline at end of file diff --git a/cgal5_catkin/README.md b/cgal5_catkin/README.md index 6d808478..6079c91e 100644 --- a/cgal5_catkin/README.md +++ b/cgal5_catkin/README.md @@ -1,2 +1,2 @@ -# cgal_catkin +# cgal5_catkin Catkin wrapper of the Computational Geometry Algorithms Library (CGAL) diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 327de6aa..9a973bb5 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1...3.15) +cmake_minimum_required(VERSION 3.10) project(convex_plane_decomposition) # Catkin dependencies @@ -18,11 +18,7 @@ find_package(MPFR 2.2.1 QUIET) find_package(Boost 1.57 QUIET) # OpenCv -find_package(OpenCV REQUIRED COMPONENTS opencv_highgui CONFIG) - -# glog -find_package(PkgConfig REQUIRED) -pkg_check_modules(glog libglog REQUIRED) +find_package(OpenCV REQUIRED) # Eigen find_package(Eigen3 3.3 REQUIRED NO_MODULE) @@ -43,7 +39,7 @@ catkin_package( CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} DEPENDS - OpenCV glog GMP MPFR Boost + OpenCV GMP MPFR Boost ) ########### @@ -70,7 +66,6 @@ add_dependencies(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} - glog gmp mpfr ) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h b/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h index 42bf71b3..498ce95b 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h @@ -12,12 +12,13 @@ CgalPolygon2d createRegularPolygon(const CgalPoint2d& center, double radius, int CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygon2d& parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor); -CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygonWithHoles2d & parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor); - +CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygonWithHoles2d& parentShape, CgalPoint2d center, int numberOfVertices, + double growthFactor); template bool pointCanBeMoved(const CgalPolygon2d& growthShape, int i, const CgalPoint2d& candidatePoint, CgalCircle2d& freeSphere, const T& parentShape); -void updateMean(CgalPoint2d & mean, const CgalPoint2d& oldValue, const CgalPoint2d& updatedValue, int N); -} \ No newline at end of file +void updateMean(CgalPoint2d& mean, const CgalPoint2d& oldValue, const CgalPoint2d& updatedValue, int N); + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h b/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h index 9bb6103c..07de3c16 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h @@ -14,11 +14,14 @@ namespace convex_plane_decomposition { cv::Vec3b randomColor(); + std::vector toCv(const CgalPolygon2d& polygon); + void drawContour(cv::Mat& img, const CgalPoint2d& point, double radius = 1, const cv::Vec3b* color = nullptr); void drawContour(cv::Mat& img, const CgalPolygon2d& polygon, const cv::Vec3b* color = nullptr); void drawContour(cv::Mat& img, const CgalPolygonWithHoles2d& polygonWithHoles2d, const cv::Vec3b* color = nullptr); + CgalPolygon2d scaleShape(const CgalPolygon2d& polygon, double scale); CgalPolygonWithHoles2d scaleShape(const CgalPolygonWithHoles2d& polygonWithHoles, double scale); -} \ No newline at end of file +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h b/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h index 5ccc1749..1a2f432d 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h @@ -2,8 +2,8 @@ // Created by rgrandia on 09.06.20. // -#include "PolygonTypes.h" #include "PlanarRegion.h" +#include "PolygonTypes.h" #pragma once @@ -117,22 +117,22 @@ inline CgalPoint2d projectToClosestPoint(const CgalPoint2d& point, const CgalPol return projectToClosestPoint(point, *closestEdge); } -inline void transformInPlace(CgalPolygon2d& polygon, const std::function & f) { +inline void transformInPlace(CgalPolygon2d& polygon, const std::function& f) { for (auto& point : polygon) { f(point); } } -inline void transformInPlace(CgalPolygonWithHoles2d& polygonWithHoles, const std::function & f) { +inline void transformInPlace(CgalPolygonWithHoles2d& polygonWithHoles, const std::function& f) { transformInPlace(polygonWithHoles.outer_boundary(), f); - for (auto& hole: polygonWithHoles.holes()) { + for (auto& hole : polygonWithHoles.holes()) { transformInPlace(hole, f); } } -inline void transformInPlace(BoundaryWithInset& boundaryWithInset, const std::function & f) { +inline void transformInPlace(BoundaryWithInset& boundaryWithInset, const std::function& f) { transformInPlace(boundaryWithInset.boundary, f); - for (auto& inset: boundaryWithInset.insets) { + for (auto& inset : boundaryWithInset.insets) { transformInPlace(inset, f); } } diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h index b532bdae..9cb83f68 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h @@ -7,10 +7,14 @@ namespace convex_plane_decomposition { struct PreprocessingParameters { - int kernelSize = 5; // Kernel size of the median filter - int numberOfRepeats = 1; // Number of times the image is filtered - bool increasing = false; // If the kernel size should increase each filter step. - double inpaintRadius = 0.05; // [in m] + /// Kernel size of the median filter + int kernelSize = 5; + /// Number of times the image is filtered + int numberOfRepeats = 1; + /// If the kernel size should increase each filter step. + bool increasing = false; + /// [m] radius used for inpainting + double inpaintRadius = 0.05; }; class GridMapPreprocessing { @@ -27,4 +31,3 @@ class GridMapPreprocessing { }; } // namespace convex_plane_decomposition - diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h b/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h index 82acad6e..40fe764f 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h @@ -4,8 +4,6 @@ #pragma once -#include - #include #include #include diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h b/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h index 1c437773..0a48b91f 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include "PlanarRegion.h" diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h index b003cb1e..8ac00075 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h @@ -8,7 +8,8 @@ namespace convex_plane_decomposition { namespace contour_extraction { struct ContourExtractionParameters { - int offsetSize = 2; /// Size of the kernel creating the boundary offset. In number of pixels. + /// Size of the kernel creating the boundary offset. In number of pixels. + int offsetSize = 2; }; } // namespace contour_extraction diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h index f1244163..0c496eb1 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h @@ -13,7 +13,6 @@ namespace convex_plane_decomposition { namespace sliding_window_plane_extractor { - class SlidingWindowPlaneExtractor { public: SlidingWindowPlaneExtractor(const SlidingWindowPlaneExtractorParameters& parameters, diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index c72380bf..e32e6fd3 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include @@ -11,8 +10,6 @@ #include -#include - #include "convex_plane_decomposition/Nan.h" namespace convex_plane_decomposition { @@ -139,10 +136,6 @@ void SlidingWindowPlaneExtractor::runSegmentation() { } void SlidingWindowPlaneExtractor::extractPlaneParametersFromLabeledImage() { - if (segmentedPlanesMap_.highestLabel < 1) { - LOG(WARNING) << "No planes detected by Sliding Window Plane Extractor!"; - return; - } const int numberOfExtractedPlanesWithoutRefinement = segmentedPlanesMap_.highestLabel; // Make local copy. The highestLabel is incremented inside the loop // Skip label 0. This is the background, i.e. non-planar region. @@ -211,7 +204,6 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label) { // Compute average plane parameters for refined segmentation const std::vector& plane_point_indices = plane->indices_of_assigned_points(); - CHECK(!plane_point_indices.empty()); Eigen::Vector3d support_vector_refined_sum = Eigen::Vector3d::Zero(); Eigen::Vector3d normal_vector_refined_sum = Eigen::Vector3d::Zero(); for (const auto index : plane_point_indices) { @@ -260,7 +252,6 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label) { bool SlidingWindowPlaneExtractor::isGloballyPlanar(const Eigen::Vector3d& normalVectorPlane, const Eigen::Vector3d& supportVectorPlane, const std::vector& points_with_normal) const { - CHECK(!points_with_normal.empty()); for (const auto& point_with_normal : points_with_normal) { Eigen::Vector3d p_S_P(point_with_normal.first.x() - supportVectorPlane.x(), point_with_normal.first.y() - supportVectorPlane.y(), point_with_normal.first.z() - supportVectorPlane.z()); diff --git a/convex_plane_decomposition_msgs/CMakeLists.txt b/convex_plane_decomposition_msgs/CMakeLists.txt index ab3b36ae..ebf14939 100644 --- a/convex_plane_decomposition_msgs/CMakeLists.txt +++ b/convex_plane_decomposition_msgs/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1...3.15) +cmake_minimum_required(VERSION 3.10) project(convex_plane_decomposition_msgs) set(CATKIN_PACKAGE_DEPENDENCIES diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index fcfe971f..ead67e38 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1...3.15) +cmake_minimum_required(VERSION 3.10) project(convex_plane_decomposition_ros) # Catkin dependencies @@ -7,15 +7,9 @@ set(CATKIN_PACKAGE_DEPENDENCIES grid_map_core grid_map_ros grid_map_cv - grid_map_filters - grid_map_loader grid_map_msgs - grid_map_octomap grid_map_rviz_plugin - grid_map_visualization geometry_msgs - sensor_msgs - cv_bridge jsk_recognition_msgs convex_plane_decomposition convex_plane_decomposition_msgs @@ -28,9 +22,8 @@ find_package(catkin REQUIRED COMPONENTS # OpenCv find_package(OpenCV REQUIRED) -# glog -find_package(PkgConfig REQUIRED) -pkg_check_modules(glog libglog REQUIRED) +# Eigen +find_package(Eigen3 3.3 REQUIRED NO_MODULE) # Cpp standard version set(CMAKE_CXX_STANDARD 14) @@ -40,10 +33,10 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) ## catkin specific configuration ## ################################### catkin_package( - INCLUDE_DIRS include + INCLUDE_DIRS include ${EIGEN3_INCLUDE_DIRS} LIBRARIES ${PROJECT_NAME} CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS + DEPENDS OpenCV ) ########### @@ -52,6 +45,7 @@ catkin_package( include_directories( include + ${EIGEN3_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS} ) @@ -67,7 +61,6 @@ add_dependencies(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} - glog ) add_executable(${PROJECT_NAME}_node @@ -76,28 +69,9 @@ add_executable(${PROJECT_NAME}_node target_link_libraries(${PROJECT_NAME}_node ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} - glog ${PROJECT_NAME} ) -add_executable(${PROJECT_NAME}_test - test/test.cpp - ) -target_link_libraries(${PROJECT_NAME}_test - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - glog - ) - -add_executable(${PROJECT_NAME}_shapegrowing - test/shapeGrowing.cpp - ) -target_link_libraries(${PROJECT_NAME}_shapegrowing - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - glog - ) - add_executable(${PROJECT_NAME}_save_elevationmap src/SaveElevationMapAsImageNode.cpp ) @@ -130,3 +104,18 @@ install(DIRECTORY config data launch rviz ############# ## Testing ## ############# +add_executable(${PROJECT_NAME}_test + test/test.cpp +) +target_link_libraries(${PROJECT_NAME}_test + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} +) + +add_executable(${PROJECT_NAME}_shapegrowing + test/shapeGrowing.cpp +) +target_link_libraries(${PROJECT_NAME}_shapegrowing + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} +) \ No newline at end of file diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h index c9018f66..4f4c0fdb 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h @@ -10,7 +10,7 @@ namespace convex_plane_decomposition { -// Forward declaration +// Forward declarations class GridMapPreprocessing; namespace sliding_window_plane_extractor { class SlidingWindowPlaneExtractor; diff --git a/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch b/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch index 6666f0c9..a02a07b0 100644 --- a/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch +++ b/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch @@ -4,6 +4,7 @@ + diff --git a/convex_plane_decomposition_ros/launch/demo.launch b/convex_plane_decomposition_ros/launch/demo.launch index 43c47e4d..a2be6e15 100644 --- a/convex_plane_decomposition_ros/launch/demo.launch +++ b/convex_plane_decomposition_ros/launch/demo.launch @@ -22,6 +22,7 @@ + diff --git a/convex_plane_decomposition_ros/package.xml b/convex_plane_decomposition_ros/package.xml index 2b59347f..0ae94d4e 100644 --- a/convex_plane_decomposition_ros/package.xml +++ b/convex_plane_decomposition_ros/package.xml @@ -13,15 +13,9 @@ grid_map_core grid_map_ros grid_map_cv - grid_map_filters - grid_map_loader grid_map_msgs - grid_map_octomap grid_map_rviz_plugin - grid_map_visualization geometry_msgs - sensor_msgs - cv_bridge jsk_recognition_msgs convex_plane_decomposition convex_plane_decomposition_msgs diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp index fa32c89d..df7417c9 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp @@ -2,18 +2,23 @@ #include -#include - int main(int argc, char** argv) { - FLAGS_alsologtostderr = 1; - FLAGS_colorlogtostderr = 1; - FLAGS_v = 1; - google::InitGoogleLogging(argv[0]); ros::init(argc, argv, "convex_plane_decomposition_ros"); ros::NodeHandle nodeHandle("~"); + double frequency; + if (!nodeHandle.getParam("frequency", frequency)) { + ROS_ERROR("[ConvexPlaneDecompositionNode] Could not read parameter `frequency`."); + return 1; + } + convex_plane_decomposition::ConvexPlaneExtractionROS convex_plane_decomposition_ros(nodeHandle); - ros::spin(); + ros::Rate rate(frequency); + while(ros::ok()) + { + ros::spinOnce(); + rate.sleep(); + } return 0; } diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 0384fe9f..a910d005 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -2,8 +2,6 @@ #include -#include - #include #include @@ -13,13 +11,13 @@ #include #include +#include +#include + +#include -#include "convex_plane_decomposition/GridMapPreprocessing.h" -#include "convex_plane_decomposition/Nan.h" -#include "convex_plane_decomposition_msgs/PlanarTerrain.h" #include "convex_plane_decomposition_ros/ParameterLoading.h" #include "convex_plane_decomposition_ros/RosVisualizations.h" - #include "convex_plane_decomposition_ros/MessageConversion.h" namespace convex_plane_decomposition { @@ -84,16 +82,16 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { auto t0 = std::chrono::high_resolution_clock::now(); preprocessing_ ->preprocess(elevationMap, elevationLayer_); auto t1 = std::chrono::high_resolution_clock::now(); - VLOG(1) << "Preprocessing took " << 1e-3 * std::chrono::duration_cast( t1 - t0 ).count() << " [ms]\n"; + ROS_INFO_STREAM("Preprocessing took " << 1e-3 * std::chrono::duration_cast( t1 - t0 ).count() << " [ms]"); // Run pipeline. slidingWindowPlaneExtractor_->runExtraction(elevationMap, elevationLayer_); auto t2 = std::chrono::high_resolution_clock::now(); - VLOG(1) << "Sliding window took " << 1e-3 * std::chrono::duration_cast( t2 - t1 ).count() << " [ms]\n"; + ROS_INFO_STREAM("Sliding window took " << 1e-3 * std::chrono::duration_cast( t2 - t1 ).count() << " [ms]"); const auto planarRegions = contourExtraction_->extractPlanarRegions(slidingWindowPlaneExtractor_->getSegmentedPlanesMap()); auto t3 = std::chrono::high_resolution_clock::now(); - VLOG(1) << "Contour extraction took " << 1e-3 * std::chrono::duration_cast( t3 - t2 ).count() << " [ms]\n"; + ROS_INFO_STREAM("Contour extraction took " << 1e-3 * std::chrono::duration_cast( t3 - t2 ).count() << " [ms]"); // Publish terrain regionPublisher_.publish(toMessage(planarRegions)); diff --git a/segmented_planes_terrain_model/CMakeLists.txt b/segmented_planes_terrain_model/CMakeLists.txt index 9aa9420a..ff8aea6b 100644 --- a/segmented_planes_terrain_model/CMakeLists.txt +++ b/segmented_planes_terrain_model/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1...3.15) +cmake_minimum_required(VERSION 3.10) project(segmented_planes_terrain_model) # Catkin dependencies @@ -9,6 +9,7 @@ set(CATKIN_PACKAGE_DEPENDENCIES convex_plane_decomposition_msgs convex_plane_decomposition_ros roscpp + visualization_msgs ) find_package(catkin REQUIRED COMPONENTS diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h index 2c5bc281..1f7617fe 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h @@ -5,7 +5,7 @@ #pragma once #include -#include "ocs2_switched_model_interface/terrain/TerrainModel.h" +#include namespace switched_model { @@ -24,6 +24,6 @@ class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { }; std::pair getPlanarRegionAtPositionInWorld( - const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarTerrain& planarTerrain); + const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarTerrain& planarTerrain); } // namespace switched_model diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h index 8a1c63ae..3cabb232 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h @@ -13,6 +13,7 @@ namespace switched_model { -visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, Color color, double diameter, double linewidth, double normalLength); +visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, Color color, double diameter, double linewidth, + double normalLength); } // namespace switched_model diff --git a/segmented_planes_terrain_model/package.xml b/segmented_planes_terrain_model/package.xml index a0923b28..c6c2d86a 100644 --- a/segmented_planes_terrain_model/package.xml +++ b/segmented_planes_terrain_model/package.xml @@ -15,5 +15,6 @@ convex_plane_decomposition_msgs convex_plane_decomposition_ros roscpp + visualization_msgs diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp index 5bf1a721..892d0445 100644 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -16,11 +16,13 @@ const std::string originFrameId_ = "map"; visualization_msgs::MarkerArray toMarker(const switched_model::ConvexTerrain& convexTerrain) { - visualization_msgs::MarkerArray markerArray = switched_model::getConvexTerrainMarkers(convexTerrain, switched_model::Color::orange, 0.02, 0.005, 0.1); + visualization_msgs::MarkerArray markerArray = + switched_model::getConvexTerrainMarkers(convexTerrain, switched_model::Color::orange, 0.02, 0.005, 0.1); // Add headers and Id const ros::Time timeStamp = ros::Time::now(); - switched_model::assignHeader(markerArray.markers.begin(), markerArray.markers.end(), switched_model::getHeaderMsg(originFrameId_, timeStamp)); + switched_model::assignHeader(markerArray.markers.begin(), markerArray.markers.end(), + switched_model::getHeaderMsg(originFrameId_, timeStamp)); switched_model::assignIncreasingId(markerArray.markers.begin(), markerArray.markers.end()); return markerArray; @@ -30,7 +32,7 @@ visualization_msgs::Marker toMarker(const switched_model::vector3_t& position) { auto marker = switched_model::getSphereMsg(position, switched_model::Color::green, 0.02); const ros::Time timeStamp = ros::Time::now(); - marker.header = switched_model::getHeaderMsg(originFrameId_, timeStamp); + marker.header = switched_model::getHeaderMsg(originFrameId_, timeStamp); return marker; } @@ -56,20 +58,20 @@ int main(int argc, char** argv) { if (terrainModel) { const auto RandomFloat = [](float a, float b) { - float random = ((float) rand()) / (float) RAND_MAX; + float random = ((float)rand()) / (float)RAND_MAX; float diff = b - a; float r = random * diff; return a + r; }; - switched_model::vector3_t positionInWorld{RandomFloat(-2.0, 2.0), RandomFloat(-2.0, 2.0), RandomFloat(0.0, 1.0)}; + switched_model::vector3_t positionInWorld{RandomFloat(-2.0, 2.0), RandomFloat(-2.0, 2.0), RandomFloat(0.0, 1.0)}; positionPublisher_.publish(toMarker(positionInWorld)); std::cout << "Query position: " << positionInWorld.transpose() << std::endl; auto t0 = std::chrono::high_resolution_clock::now(); const auto convexTerrain = terrainModel->getConvexTerrainAtPositionInWorld(positionInWorld); auto t1 = std::chrono::high_resolution_clock::now(); - std::cout << "Query took " << 1e-3 * std::chrono::duration_cast( t1 - t0 ).count() << " [ms]\n"; + std::cout << "Query took " << 1e-3 * std::chrono::duration_cast(t1 - t0).count() << " [ms]\n"; positionPublisher_.publish(toMarker(positionInWorld)); convexTerrainPublisher_.publish(toMarker(convexTerrain)); diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index 48e3c036..9ce41303 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -18,30 +18,32 @@ TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorld(const const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_); const auto& region = *regionAndSeedPoint.first; const auto& seedpoint = regionAndSeedPoint.second; - const auto& seedpointInWorldFrame = positionInWorldFrameFromPositionInTerrain({seedpoint.x(), seedpoint.y(), 0.0}, region.planeParameters); + const auto& seedpointInWorldFrame = + positionInWorldFrameFromPositionInTerrain({seedpoint.x(), seedpoint.y(), 0.0}, region.planeParameters); return TerrainPlane{seedpointInWorldFrame, region.planeParameters.orientationWorldToTerrain}; } ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld(const vector3_t& positionInWorld) const { - const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_); - const auto& region = *regionAndSeedPoint.first; - const auto& seedpoint = regionAndSeedPoint.second; - const auto& seedpointInWorldFrame = positionInWorldFrameFromPositionInTerrain({seedpoint.x(), seedpoint.y(), 0.0}, region.planeParameters); - - // Convert boundary and seedpoint to terrain frame - const int numberOfVertices = 16; // Multiple of 4 is nice for symmetry. - const double growthFactor = 1.05; - const auto convexRegion = convex_plane_decomposition::growConvexPolygonInsideShape(region.boundaryWithInset.boundary, seedpoint, - numberOfVertices, growthFactor); - - // Return convex region with origin at the seedpoint - ConvexTerrain convexTerrain; - convexTerrain.plane = {seedpointInWorldFrame, region.planeParameters.orientationWorldToTerrain}; // Origin is at the seedpoint - convexTerrain.boundary.reserve(convexRegion.size()); - for (const auto& point : convexRegion) { - convexTerrain.boundary.emplace_back(point.x() - seedpoint.x(), point.y() - seedpoint.y()); // Shift points to new origin - } - return convexTerrain; + const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_); + const auto& region = *regionAndSeedPoint.first; + const auto& seedpoint = regionAndSeedPoint.second; + const auto& seedpointInWorldFrame = + positionInWorldFrameFromPositionInTerrain({seedpoint.x(), seedpoint.y(), 0.0}, region.planeParameters); + + // Convert boundary and seedpoint to terrain frame + const int numberOfVertices = 16; // Multiple of 4 is nice for symmetry. + const double growthFactor = 1.05; + const auto convexRegion = convex_plane_decomposition::growConvexPolygonInsideShape(region.boundaryWithInset.boundary, seedpoint, + numberOfVertices, growthFactor); + + // Return convex region with origin at the seedpoint + ConvexTerrain convexTerrain; + convexTerrain.plane = {seedpointInWorldFrame, region.planeParameters.orientationWorldToTerrain}; // Origin is at the seedpoint + convexTerrain.boundary.reserve(convexRegion.size()); + for (const auto& point : convexRegion) { + convexTerrain.boundary.emplace_back(point.x() - seedpoint.x(), point.y() - seedpoint.y()); // Shift points to new origin + } + return convexTerrain; } double singleSidedSquaredDistance(double value, double min, double max) { @@ -63,11 +65,12 @@ double squaredDistanceToBoundingBox(const vector3_t& positionInWorld, const conv const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionInWorld, planarRegion.planeParameters); double dxdx = singleSidedSquaredDistance(positionInTerrainFrame.x(), planarRegion.bbox2d.xmin(), planarRegion.bbox2d.xmax()); double dydy = singleSidedSquaredDistance(positionInTerrainFrame.y(), planarRegion.bbox2d.ymin(), planarRegion.bbox2d.ymax()); - double dzdz = positionInTerrainFrame.z()* positionInTerrainFrame.z(); + double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); return dxdx + dydy + dzdz; } -const convex_plane_decomposition::CgalPolygonWithHoles2d* findInsetContainingThePoint(const convex_plane_decomposition::CgalPoint2d& point, const std::vector& insets){ +const convex_plane_decomposition::CgalPolygonWithHoles2d* findInsetContainingThePoint( + const convex_plane_decomposition::CgalPoint2d& point, const std::vector& insets) { for (const auto& inset : insets) { if (convex_plane_decomposition::isInside(point, inset.outer_boundary())) { return &inset; @@ -76,10 +79,11 @@ const convex_plane_decomposition::CgalPolygonWithHoles2d* findInsetContainingThe return nullptr; } -std::pair squaredDistanceToBoundary(const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarRegion& planarRegion) { +std::pair squaredDistanceToBoundary( + const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarRegion& planarRegion) { const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionInWorld, planarRegion.planeParameters); - const double dzdz = positionInTerrainFrame.z()* positionInTerrainFrame.z(); - const convex_plane_decomposition::CgalPoint2d queryProjectedToPlane {positionInTerrainFrame.x(), positionInTerrainFrame.y()}; + const double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); + const convex_plane_decomposition::CgalPoint2d queryProjectedToPlane{positionInTerrainFrame.x(), positionInTerrainFrame.y()}; // First search if the projected point is inside any of the insets. const auto insetPtrContainingPoint = findInsetContainingThePoint(queryProjectedToPlane, planarRegion.boundaryWithInset.insets); @@ -105,7 +109,7 @@ std::pair squaredDistanceToBoun for (const auto& hole : insetPtrContainingPoint->holes()) { if (convex_plane_decomposition::isInside(queryProjectedToPlane, hole)) { projectedPoint = convex_plane_decomposition::projectToClosestPoint(queryProjectedToPlane, hole); - break; // No need to search other holes. Holes are not overlapping + break; // No need to search other holes. Holes are not overlapping } } } @@ -113,8 +117,8 @@ std::pair squaredDistanceToBoun return {dzdz + convex_plane_decomposition::squaredDistance(projectedPoint, queryProjectedToPlane), projectedPoint}; } -std::pair -getPlanarRegionAtPositionInWorld(const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarTerrain& planarTerrain) { +std::pair getPlanarRegionAtPositionInWorld( + const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarTerrain& planarTerrain) { // Compute distance to bounding boxes std::vector> regionsAndBboxSquareDistances; regionsAndBboxSquareDistances.reserve(planarTerrain.size()); @@ -125,16 +129,14 @@ getPlanarRegionAtPositionInWorld(const vector3_t& positionInWorld, const convex // Sort regions close to far std::sort(regionsAndBboxSquareDistances.begin(), regionsAndBboxSquareDistances.end(), [](const std::pair& lhs, - const std::pair& rhs) { - return lhs.second < rhs.second; - }); + const std::pair& rhs) { return lhs.second < rhs.second; }); // Look for closest planar region. Use bbox as lower bound to stop searching. double minDistSquared = std::numeric_limits::max(); std::pair closestRegionAndProjection; - for(const auto& regionAndBboxSquareDistance : regionsAndBboxSquareDistances) { + for (const auto& regionAndBboxSquareDistance : regionsAndBboxSquareDistances) { if (regionAndBboxSquareDistance.second > minDistSquared) { - break; // regions are sorted. Can exit on the first lower bound being larger than running minimum + break; // regions are sorted. Can exit on the first lower bound being larger than running minimum } const auto distanceSqrAndProjection = squaredDistanceToBoundary(positionInWorld, *regionAndBboxSquareDistance.first); diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp index dc450792..4fd04973 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp @@ -9,7 +9,8 @@ namespace switched_model { SegmentedPlanesTerrainModelRos::SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle) : terrainUpdated_(false) { - terrainSubscriber_ = nodehandle.subscribe("/convex_plane_decomposition_ros/planar_terrain", 1, &SegmentedPlanesTerrainModelRos::callback, this); + terrainSubscriber_ = + nodehandle.subscribe("/convex_plane_decomposition_ros/planar_terrain", 1, &SegmentedPlanesTerrainModelRos::callback, this); } bool SegmentedPlanesTerrainModelRos::update(std::unique_ptr& terrainPtr) { diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp index cad3bc3d..73956a99 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp @@ -6,7 +6,8 @@ namespace switched_model { -visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, Color color, double diameter, double linewidth, double normalLength) { +visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, Color color, double diameter, double linewidth, + double normalLength) { visualization_msgs::MarkerArray markerArray; markerArray.markers.reserve(3); @@ -18,7 +19,7 @@ visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& con markerArray.markers.emplace_back(getArrowAtPointMsg(surfaceNormal, convexTerrain.plane.positionInWorld, color)); // Polygon message - if (!convexTerrain.boundary.empty()){ + if (!convexTerrain.boundary.empty()) { std::vector boundary; boundary.reserve(convexTerrain.boundary.size() + 1); for (const auto& point : convexTerrain.boundary) { @@ -26,15 +27,14 @@ visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& con boundary.emplace_back(getPointMsg(pointInWorldFrame)); } // Close the polygon - const auto& pointInWorldFrame = positionInWorldFrameFromPositionInTerrain({convexTerrain.boundary.front().x(), convexTerrain.boundary.front().y(), 0.0}, convexTerrain.plane); + const auto& pointInWorldFrame = positionInWorldFrameFromPositionInTerrain( + {convexTerrain.boundary.front().x(), convexTerrain.boundary.front().y(), 0.0}, convexTerrain.plane); boundary.emplace_back(getPointMsg(pointInWorldFrame)); markerArray.markers.emplace_back(getLineMsg(std::move(boundary), color, linewidth)); } else { - } - return markerArray; } From 3ee5496e696af18b8a084ae2af2f5aba32cf86b5 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 30 Jun 2020 15:23:48 +0200 Subject: [PATCH 051/504] split parameters into node and pipeline --- ...x_plane_decomposition_demo_parameters.yaml | 31 ------------------- .../config/demo_node.yaml | 7 +++++ .../config/node.yaml | 7 +++++ .../config/parameters.yaml | 7 ----- .../config/standalone_node.yaml | 7 +++++ .../ConvexPlaneDecompositionRos.h | 1 + .../launch/convex_plane_decomposition.launch | 7 +++-- .../launch/demo.launch | 12 +++---- .../launch/standalone.launch | 11 +++++++ .../src/ConvexPlaneDecompositionRos.cpp | 8 ++++- 10 files changed, 51 insertions(+), 47 deletions(-) delete mode 100644 convex_plane_decomposition_ros/config/convex_plane_decomposition_demo_parameters.yaml create mode 100644 convex_plane_decomposition_ros/config/demo_node.yaml create mode 100644 convex_plane_decomposition_ros/config/node.yaml create mode 100644 convex_plane_decomposition_ros/config/standalone_node.yaml create mode 100644 convex_plane_decomposition_ros/launch/standalone.launch diff --git a/convex_plane_decomposition_ros/config/convex_plane_decomposition_demo_parameters.yaml b/convex_plane_decomposition_ros/config/convex_plane_decomposition_demo_parameters.yaml deleted file mode 100644 index d3ee9e81..00000000 --- a/convex_plane_decomposition_ros/config/convex_plane_decomposition_demo_parameters.yaml +++ /dev/null @@ -1,31 +0,0 @@ -elevation_topic: '/image_to_gridmap_demo/grid_map' -height_layer: 'elevation' -submap: - width: 6.0 - length: 6.0 - -preprocessing: - kernelSize: 3 # Kernel size of the median filter - numberOfRepeats: 3 # Number of times to apply the same filter - increasing: True # Increase the kernel size each iteration. - inpaintRadius: 0.05 # [m] - -sliding_window_plane_extractor: - kernel_size: 3 # Size of the sliding window patch used for normal vector calculation and planarity detection. Should be an odd number and at least 3. - plane_inclination_threshold_degrees: 45.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch - plane_patch_error_threshold: 0.005 # [m] The allowed root-mean-squared deviation from the plane fitted to the sliding window. - min_number_points_per_label: 10 # [#] Labels with less points assigned to them are discarded - connectivity: 4 # Label kernel connectivity. 4 or 8 (cross or box) - include_ransac_refinement: true # Enable RANSAC refinement if the plane is not globally fitting to the assigned points. - global_plane_fit_distance_error_threshold: 0.04 # [m] Allowed maximum distance from a point to the plane. If any point violates this, RANSAC is triggered - global_plane_fit_angle_error_threshold_degrees: 5.0 # [deg] Allowed normal vector deviation for a point w.r.t. the plane normal. If any point violates this, RANSAC is triggered - -ransac_plane_refinement: - probability: 0.01 # Probability to miss the largest candidate shape. A lower probability provides a higher reliability and determinism at the cost of longer running times - min_points: 25 # This minimum number of points per plane. Controls the termination of the algorithm. - epsilon: 0.02 # Maximum distance to plane - cluster_epsilon: 0.05 # Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon - normal_threshold: 0.98 # Set maximum normal deviation. normal_threshold < dot(surface_normal, point_normal); - -contour_extraction: - offsetSize: 2 # Size of the kernel creating the boundary offset. In number of pixels. diff --git a/convex_plane_decomposition_ros/config/demo_node.yaml b/convex_plane_decomposition_ros/config/demo_node.yaml new file mode 100644 index 00000000..8f24686d --- /dev/null +++ b/convex_plane_decomposition_ros/config/demo_node.yaml @@ -0,0 +1,7 @@ +elevation_topic: '/image_to_gridmap_demo/grid_map' +height_layer: 'elevation' +submap: + width: 6.0 + length: 6.0 +publish_to_controller: false +frequency: 10.0 diff --git a/convex_plane_decomposition_ros/config/node.yaml b/convex_plane_decomposition_ros/config/node.yaml new file mode 100644 index 00000000..4343d077 --- /dev/null +++ b/convex_plane_decomposition_ros/config/node.yaml @@ -0,0 +1,7 @@ +elevation_topic: '/elevation_mapping/elevation_map_raw' +height_layer: 'elevation' +submap: + width: 3.0 + length: 3.0 +publish_to_controller: true +frequency: 10.0 diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 180bf395..1ac210c1 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -1,9 +1,3 @@ -elevation_topic : '/elevation_mapping/elevation_map_raw' -height_layer : 'elevation' -submap: - width: 3.0 - length: 3.0 - preprocessing: kernelSize: 3 # Kernel size of the median filter numberOfRepeats: 3 # Number of times to apply the same filter @@ -29,4 +23,3 @@ ransac_plane_refinement: contour_extraction: offsetSize: 2 # Size of the kernel creating the boundary offset. In number of pixels. - diff --git a/convex_plane_decomposition_ros/config/standalone_node.yaml b/convex_plane_decomposition_ros/config/standalone_node.yaml new file mode 100644 index 00000000..ab2ee21b --- /dev/null +++ b/convex_plane_decomposition_ros/config/standalone_node.yaml @@ -0,0 +1,7 @@ +elevation_topic: '/elevation_mapping/elevation_map_raw' +height_layer: 'elevation' +submap: + width: 6.0 + length: 6.0 +publish_to_controller: false +frequency: 10.0 diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h index 4f4c0fdb..62d15f91 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h @@ -39,6 +39,7 @@ class ConvexPlaneExtractionROS { std::string elevationLayer_; double subMapWidth_; double subMapLength_; + bool publishToController_; // ROS communication ros::Subscriber elevationMapSubscriber_; diff --git a/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch b/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch index a02a07b0..7716193d 100644 --- a/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch +++ b/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch @@ -1,10 +1,13 @@ + + + - - + + diff --git a/convex_plane_decomposition_ros/launch/demo.launch b/convex_plane_decomposition_ros/launch/demo.launch index a2be6e15..5a1fbf20 100644 --- a/convex_plane_decomposition_ros/launch/demo.launch +++ b/convex_plane_decomposition_ros/launch/demo.launch @@ -19,12 +19,12 @@ - - - - + + + + - + + diff --git a/convex_plane_decomposition_ros/launch/standalone.launch b/convex_plane_decomposition_ros/launch/standalone.launch new file mode 100644 index 00000000..06cf11f5 --- /dev/null +++ b/convex_plane_decomposition_ros/launch/standalone.launch @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index a910d005..aef0efb1 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -53,6 +53,10 @@ bool ConvexPlaneExtractionROS::loadParameters(const ros::NodeHandle& nodeHandle) ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `submap/length`."); return false; } + if (!nodeHandle.getParam("publish_to_controller", publishToController_)) { + ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `publish_to_controller`."); + return false; + } const auto preprocessingParameters = loadPreprocessingParameters(nodeHandle, "preprocessing/"); const auto contourExtractionParameters = loadContourExtractionParameters(nodeHandle, "contour_extraction/"); @@ -94,7 +98,9 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { ROS_INFO_STREAM("Contour extraction took " << 1e-3 * std::chrono::duration_cast( t3 - t2 ).count() << " [ms]"); // Publish terrain - regionPublisher_.publish(toMessage(planarRegions)); + if (publishToController_) { + regionPublisher_.publish(toMessage(planarRegions)); + } // Visualize in Rviz. reapplyNans(elevationMap.get(elevationLayer_)); From 6ee539b305f903bf029eb625072c2222e28abe8a Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 2 Jul 2020 09:29:48 +0200 Subject: [PATCH 052/504] add deadzone to z-direction for computing distance cost --- .../src/SegmentedPlanesTerrainModel.cpp | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index 9ce41303..3bfdbe38 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -11,6 +11,30 @@ namespace switched_model { +const double zHeightDistanceDeadzone = 0.1; // [m] This difference in z height is not counted + +double distanceCost(const vector3_t& query, const vector3_t& terrainPoint) { + const double dx = query.x() - terrainPoint.x(); + const double dy = query.y() - terrainPoint.y(); + const double dz = std::max(0.0, std::abs(query.z() - terrainPoint.z()) - zHeightDistanceDeadzone); + return dx * dx + dy * dy + dz * dz; +} + +double distanceCostLowerbound(double distanceSquared) { + // cost = dx*dx + dy*dy + max(0.0, (|dz| - z0)).^2 with z0 >= 0 + // Need a lower bound for this cost derived from square distance and shift + // + // dz*dz - z0*z0 < max(0.0, (|dz| - z0)).^2 + // if |dz| > z0 ==> + // dz*dz - 2*|dz|*z0 + z0*z0 = (|dz| - z0).^2 + // dz*dz - 2*z0*z0 + z0*z0 < (|dz| - z0).^2 + // dz*dz - z0*z0 < (|dz| - z0).^2 + // + // if |dz| < z0 ==> + // dz*dz - z0*z0 < 0.0 (true) + return distanceSquared - zHeightDistanceDeadzone * zHeightDistanceDeadzone; +} + SegmentedPlanesTerrainModel::SegmentedPlanesTerrainModel(convex_plane_decomposition::PlanarTerrain planarTerrain) : planarTerrain_(std::move(planarTerrain)) {} @@ -123,7 +147,8 @@ std::pair> regionsAndBboxSquareDistances; regionsAndBboxSquareDistances.reserve(planarTerrain.size()); for (const auto& planarRegion : planarTerrain) { - regionsAndBboxSquareDistances.emplace_back(&planarRegion, squaredDistanceToBoundingBox(positionInWorld, planarRegion)); + double squareDistance = squaredDistanceToBoundingBox(positionInWorld, planarRegion); + regionsAndBboxSquareDistances.emplace_back(&planarRegion, distanceCostLowerbound(squareDistance)); } // Sort regions close to far @@ -140,8 +165,12 @@ std::pairplaneParameters); + const double distCost = distanceCost(positionInWorld, projectionInWorldFrame); + if (distCost < minDistSquared) { + minDistSquared = distCost; closestRegionAndProjection = {regionAndBboxSquareDistance.first, distanceSqrAndProjection.second}; } } From d0e5b2b6d54bb89ff5f66fb5f7bb60b919762cd5 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 6 Jul 2020 23:29:39 +0200 Subject: [PATCH 053/504] listen to tf tree to transform the elevation map to odom --- convex_plane_decomposition_ros/CMakeLists.txt | 1 + .../config/image_loader_demo_parameters.yaml | 2 +- .../ConvexPlaneDecompositionRos.h | 13 ++++- .../RosVisualizations.h | 3 +- .../launch/demo.launch | 3 + convex_plane_decomposition_ros/package.xml | 1 + .../src/ConvexPlaneDecompositionNode.cpp | 3 +- .../src/ConvexPlaneDecompositionRos.cpp | 56 +++++++++++++++---- .../src/MessageConversion.cpp | 4 +- .../src/ParameterLoading.cpp | 6 +- .../src/SaveElevationMapAsImageNode.cpp | 13 ++--- 11 files changed, 77 insertions(+), 28 deletions(-) diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index ead67e38..ef57d760 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -13,6 +13,7 @@ set(CATKIN_PACKAGE_DEPENDENCIES jsk_recognition_msgs convex_plane_decomposition convex_plane_decomposition_msgs + tf2_ros ) find_package(catkin REQUIRED COMPONENTS diff --git a/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml b/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml index 42a93854..d53ea989 100644 --- a/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml +++ b/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml @@ -1,6 +1,6 @@ image_to_gridmap_demo: image_topic: "/image_publisher/image" resolution: 0.02 - map_frame_id: "odom" + map_frame_id: "map" # This parameter is actually not used. The gridmap is always in map frame min_height: 0 max_height: 1.0 \ No newline at end of file diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h index 62d15f91..fcca9c26 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h @@ -1,10 +1,14 @@ #pragma once -#include #include #include +#include +#include #include +#include + +#include #include @@ -15,7 +19,7 @@ class GridMapPreprocessing; namespace sliding_window_plane_extractor { class SlidingWindowPlaneExtractor; } -namespace contour_extraction { +namespace contour_extraction { class ContourExtraction; } @@ -34,9 +38,12 @@ class ConvexPlaneExtractionROS { */ void callback(const grid_map_msgs::GridMap& message); + Eigen::Isometry3d getTransformToTargetFrame(const std::string& sourceFrame); + // Parameters std::string elevationMapTopic_; std::string elevationLayer_; + std::string targetFrameId_ = "odom"; double subMapWidth_; double subMapLength_; bool publishToController_; @@ -47,6 +54,8 @@ class ConvexPlaneExtractionROS { ros::Publisher boundaryPublisher_; ros::Publisher insetPublisher_; ros::Publisher regionPublisher_; + tf2_ros::Buffer tfBuffer_; + tf2_ros::TransformListener tfListener_; // Pipeline std::mutex mutex_; diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h index d642c8cb..eaac3612 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h @@ -6,7 +6,8 @@ namespace convex_plane_decomposition { -jsk_recognition_msgs::PolygonArray convertBoundariesToRosPolygons(const std::vector& planarRegions, const std::string& frameId); +jsk_recognition_msgs::PolygonArray convertBoundariesToRosPolygons(const std::vector& planarRegions, + const std::string& frameId); jsk_recognition_msgs::PolygonArray convertInsetsToRosPolygons(const std::vector& planarRegions, const std::string& frameId); diff --git a/convex_plane_decomposition_ros/launch/demo.launch b/convex_plane_decomposition_ros/launch/demo.launch index 5a1fbf20..b0df4646 100644 --- a/convex_plane_decomposition_ros/launch/demo.launch +++ b/convex_plane_decomposition_ros/launch/demo.launch @@ -19,6 +19,9 @@ + + + diff --git a/convex_plane_decomposition_ros/package.xml b/convex_plane_decomposition_ros/package.xml index 0ae94d4e..74382d54 100644 --- a/convex_plane_decomposition_ros/package.xml +++ b/convex_plane_decomposition_ros/package.xml @@ -19,5 +19,6 @@ jsk_recognition_msgs convex_plane_decomposition convex_plane_decomposition_msgs + tf2_ros diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp index df7417c9..3d622df7 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp @@ -15,8 +15,7 @@ int main(int argc, char** argv) { convex_plane_decomposition::ConvexPlaneExtractionROS convex_plane_decomposition_ros(nodeHandle); ros::Rate rate(frequency); - while(ros::ok()) - { + while (ros::ok()) { ros::spinOnce(); rate.sleep(); } diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index aef0efb1..bf9bae7f 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -9,20 +9,20 @@ #include #include -#include -#include #include #include +#include +#include #include +#include "convex_plane_decomposition_ros/MessageConversion.h" #include "convex_plane_decomposition_ros/ParameterLoading.h" #include "convex_plane_decomposition_ros/RosVisualizations.h" -#include "convex_plane_decomposition_ros/MessageConversion.h" namespace convex_plane_decomposition { -ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle) { +ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle) : tfBuffer_(), tfListener_(tfBuffer_) { bool parametersLoaded = loadParameters(nodeHandle); if (parametersLoaded) { @@ -61,11 +61,13 @@ bool ConvexPlaneExtractionROS::loadParameters(const ros::NodeHandle& nodeHandle) const auto preprocessingParameters = loadPreprocessingParameters(nodeHandle, "preprocessing/"); const auto contourExtractionParameters = loadContourExtractionParameters(nodeHandle, "contour_extraction/"); const auto ransacPlaneExtractorParameters = loadRansacPlaneExtractorParameters(nodeHandle, "ransac_plane_refinement/"); - const auto slidingWindowPlaneExtractorParameters = loadSlidingWindowPlaneExtractorParameters(nodeHandle, "sliding_window_plane_extractor/"); + const auto slidingWindowPlaneExtractorParameters = + loadSlidingWindowPlaneExtractorParameters(nodeHandle, "sliding_window_plane_extractor/"); std::lock_guard lock(mutex_); preprocessing_ = std::make_unique(preprocessingParameters); - slidingWindowPlaneExtractor_ = std::make_unique(slidingWindowPlaneExtractorParameters, ransacPlaneExtractorParameters); + slidingWindowPlaneExtractor_ = std::make_unique( + slidingWindowPlaneExtractorParameters, ransacPlaneExtractorParameters); contourExtraction_ = std::make_unique(contourExtractionParameters); return true; @@ -82,20 +84,31 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { grid_map::GridMap elevationMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(subMapWidth_, subMapLength_), success); ROS_INFO("...done."); + // Transform map if necessary + if (targetFrameId_ != elevationMap.getFrameId()) { + std::string errorMsg; + if (tfBuffer_.canTransform(targetFrameId_, elevationMap.getFrameId(), ros::Time(0), &errorMsg)) { + elevationMap = elevationMap.getTransformedMap(getTransformToTargetFrame(elevationMap.getFrameId()), elevationLayer_, targetFrameId_); + } else { + ROS_ERROR_STREAM("[ConvexPlaneExtractionROS] " << errorMsg); + return; + } + } + if (success) { auto t0 = std::chrono::high_resolution_clock::now(); - preprocessing_ ->preprocess(elevationMap, elevationLayer_); + preprocessing_->preprocess(elevationMap, elevationLayer_); auto t1 = std::chrono::high_resolution_clock::now(); - ROS_INFO_STREAM("Preprocessing took " << 1e-3 * std::chrono::duration_cast( t1 - t0 ).count() << " [ms]"); + ROS_INFO_STREAM("Preprocessing took " << 1e-3 * std::chrono::duration_cast(t1 - t0).count() << " [ms]"); // Run pipeline. slidingWindowPlaneExtractor_->runExtraction(elevationMap, elevationLayer_); auto t2 = std::chrono::high_resolution_clock::now(); - ROS_INFO_STREAM("Sliding window took " << 1e-3 * std::chrono::duration_cast( t2 - t1 ).count() << " [ms]"); + ROS_INFO_STREAM("Sliding window took " << 1e-3 * std::chrono::duration_cast(t2 - t1).count() << " [ms]"); const auto planarRegions = contourExtraction_->extractPlanarRegions(slidingWindowPlaneExtractor_->getSegmentedPlanesMap()); auto t3 = std::chrono::high_resolution_clock::now(); - ROS_INFO_STREAM("Contour extraction took " << 1e-3 * std::chrono::duration_cast( t3 - t2 ).count() << " [ms]"); + ROS_INFO_STREAM("Contour extraction took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]"); // Publish terrain if (publishToController_) { @@ -117,4 +130,27 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { } } +Eigen::Isometry3d ConvexPlaneExtractionROS::getTransformToTargetFrame(const std::string& sourceFrame) { + geometry_msgs::TransformStamped transformStamped; + try { + transformStamped = tfBuffer_.lookupTransform(targetFrameId_, sourceFrame, ros::Time(0)); + } catch (tf2::TransformException& ex) { + ROS_ERROR("[ConvexPlaneExtractionROS] %s", ex.what()); + return Eigen::Isometry3d(); + } + + Eigen::Isometry3d transformation; + + // Extract translation. + transformation.translation().x() = transformStamped.transform.translation.x; + transformation.translation().y() = transformStamped.transform.translation.y; + transformation.translation().z() = transformStamped.transform.translation.z; + + // Extract rotation. + Eigen::Quaterniond rotationQuaternion(transformStamped.transform.rotation.w, transformStamped.transform.rotation.x, + transformStamped.transform.rotation.y, transformStamped.transform.rotation.z); + transformation.linear() = rotationQuaternion.toRotationMatrix(); + return transformation; +} + } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/src/MessageConversion.cpp b/convex_plane_decomposition_ros/src/MessageConversion.cpp index a14f83a4..d60e47de 100644 --- a/convex_plane_decomposition_ros/src/MessageConversion.cpp +++ b/convex_plane_decomposition_ros/src/MessageConversion.cpp @@ -61,7 +61,7 @@ convex_plane_decomposition_msgs::PlanarTerrain toMessage(const PlanarTerrain& pl return msg; } -TerrainPlane fromMessage(const geometry_msgs::Pose& msg){ +TerrainPlane fromMessage(const geometry_msgs::Pose& msg) { TerrainPlane plane; plane.positionInWorld.x() = msg.position.x; plane.positionInWorld.y() = msg.position.y; @@ -75,7 +75,7 @@ TerrainPlane fromMessage(const geometry_msgs::Pose& msg){ return plane; } -geometry_msgs::Pose toMessage(const TerrainPlane& plane){ +geometry_msgs::Pose toMessage(const TerrainPlane& plane) { geometry_msgs::Pose pose; pose.position.x = plane.positionInWorld.x(); pose.position.y = plane.positionInWorld.y(); diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/convex_plane_decomposition_ros/src/ParameterLoading.cpp index a702326f..76c3b688 100644 --- a/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ b/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -9,12 +9,12 @@ namespace convex_plane_decomposition { template void loadParameter(const ros::NodeHandle& nodeHandle, const std::string& prefix, const std::string& param, T& value) { if (!nodeHandle.getParam(prefix + param, value)) { - ROS_ERROR_STREAM("[ConvexPlaneExtractionROS] Could not read parameter `" << param << "`. Setting parameter to default value : " << std::to_string(value)); + ROS_ERROR_STREAM("[ConvexPlaneExtractionROS] Could not read parameter `" + << param << "`. Setting parameter to default value : " << std::to_string(value)); } } -PreprocessingParameters loadPreprocessingParameters(const ros::NodeHandle& nodeHandle, - const std::string& prefix) { +PreprocessingParameters loadPreprocessingParameters(const ros::NodeHandle& nodeHandle, const std::string& prefix) { PreprocessingParameters preprocessingParameters; loadParameter(nodeHandle, prefix, "kernelSize", preprocessingParameters.kernelSize); loadParameter(nodeHandle, prefix, "numberOfRepeats", preprocessingParameters.numberOfRepeats); diff --git a/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp b/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp index b6f51ae0..8f471b22 100644 --- a/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp +++ b/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp @@ -23,10 +23,10 @@ void callback(const grid_map_msgs::GridMap::ConstPtr& message) { const auto& data = messageMap[elevationLayer]; float maxHeight = std::numeric_limits::lowest(); float minHeight = std::numeric_limits::max(); - for (int i=0; i(messageMap, elevationLayer, CV_8UC1, minHeight, maxHeight, image); int range = 100 * (maxHeight - minHeight); - cv::imwrite( imageName + "_" + std::to_string(count++) + "_" + std::to_string(range) + "cm.png", image); + cv::imwrite(imageName + "_" + std::to_string(count++) + "_" + std::to_string(range) + "cm.png", image); } int main(int argc, char** argv) { @@ -64,8 +64,7 @@ int main(int argc, char** argv) { auto elevationMapSubscriber_ = nodeHandle.subscribe(elevationMapTopic, 1, callback); ros::Rate rate(frequency); - while(ros::ok()) - { + while (ros::ok()) { ros::spinOnce(); rate.sleep(); } From 528239dd8f8d280ddd1eb970d7a7304eeb80f70a Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 6 Jul 2020 23:42:00 +0200 Subject: [PATCH 054/504] formatting --- .../contour_extraction/ContourExtraction.h | 5 ++--- .../ContourExtractionParameters.h | 3 +-- .../ransac/RansacPlaneExtractorParameters.h | 3 ++- .../SlidingWindowPlaneExtractor.h | 4 ++-- .../src/ConvexRegionGrowing.cpp | 7 ++++--- .../contour_extraction/ContourExtraction.cpp | 18 ++++++++---------- .../SlidingWindowPlaneExtractor.cpp | 19 +++++++++++-------- 7 files changed, 30 insertions(+), 29 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h index aee87d57..310bdf21 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h @@ -15,7 +15,6 @@ namespace convex_plane_decomposition { namespace contour_extraction { - /** * Extracts the contours in map resolution, but with the x and y axis flipped. * This way all contours are in counter clockwise direction. @@ -45,5 +44,5 @@ CgalPoint2d worldFrameToTerrainFrame(const CgalPoint2d& worldFrameXY, const Terr CgalPoint2d pixelToWorldFrame(const CgalPoint2d& pixelspaceCgalPoint2d, double resolution, const Eigen::Vector2d& mapOffset); -} -} \ No newline at end of file +} // namespace contour_extraction +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h index 8ac00075..1d92911b 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h @@ -13,5 +13,4 @@ struct ContourExtractionParameters { }; } // namespace contour_extraction -} - +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h index 1bb09f76..60fe43ef 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h @@ -13,7 +13,8 @@ struct RansacPlaneExtractorParameters { double min_points = 200; /// Set maximum Euclidean distance between a point and a shape. double epsilon = 0.004; - /// Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon + /// Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most + /// 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon double cluster_epsilon = 0.03; /// Set maximum normal deviation. normal_threshold < dot(surface_normal, point_normal); double normal_threshold = 0.98; diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h index 0c496eb1..e62d2dab 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h @@ -5,8 +5,8 @@ #include #include -#include "convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp" #include "convex_plane_decomposition/SegmentedPlanesMap.h" +#include "convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp" #include "SlidingWindowPlaneExtractorParameters.h" @@ -16,7 +16,7 @@ namespace sliding_window_plane_extractor { class SlidingWindowPlaneExtractor { public: SlidingWindowPlaneExtractor(const SlidingWindowPlaneExtractorParameters& parameters, - const ransac_plane_extractor::RansacPlaneExtractorParameters& ransacParameters); + const ransac_plane_extractor::RansacPlaneExtractorParameters& ransacParameters); void runExtraction(const grid_map::GridMap& map, const std::string& layer_height); diff --git a/convex_plane_decomposition/src/ConvexRegionGrowing.cpp b/convex_plane_decomposition/src/ConvexRegionGrowing.cpp index a3f963a1..b5fd52c1 100644 --- a/convex_plane_decomposition/src/ConvexRegionGrowing.cpp +++ b/convex_plane_decomposition/src/ConvexRegionGrowing.cpp @@ -30,7 +30,7 @@ int getClockWiseNeighbour(int i, int lastVertex) { return (i < lastVertex) ? i + 1 : 0; } -void updateMean(CgalPoint2d & mean, const CgalPoint2d& oldValue, const CgalPoint2d& updatedValue, int N) { +void updateMean(CgalPoint2d& mean, const CgalPoint2d& oldValue, const CgalPoint2d& updatedValue, int N) { // old_mean = 1/N * ( others + old_value); -> others = N*old_mean - old_value // new_mean = 1/N * ( others + new_value); -> new_mean = old_mean - 1/N * oldValue + 1/N * updatedValue mean += 1.0 / N * (updatedValue - oldValue); @@ -107,7 +107,7 @@ CgalPolygon2d growConvexPolygonInsideShape_impl(const T& parentShape, CgalPoint2 // Cached values per vertex std::vector blocked(numberOfVertices, false); - std::vector freeSpheres(numberOfVertices, CgalCircle2d(center, radius*radius)); + std::vector freeSpheres(numberOfVertices, CgalCircle2d(center, radius * radius)); int Nblocked = 0; while (Nblocked < numberOfVertices) { @@ -127,7 +127,8 @@ CgalPolygon2d growConvexPolygonInsideShape_impl(const T& parentShape, CgalPoint2 return growthShape; } -CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygon2d & parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor) { +CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygon2d& parentShape, CgalPoint2d center, int numberOfVertices, + double growthFactor) { return growConvexPolygonInsideShape_impl(parentShape, center, numberOfVertices, growthFactor); } diff --git a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp index 4777192c..58c3b16b 100644 --- a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp +++ b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp @@ -10,10 +10,10 @@ namespace convex_plane_decomposition { namespace contour_extraction { -ContourExtraction::ContourExtraction(const ContourExtractionParameters& parameters) : parameters_(parameters), - binaryImage_(cv::Size(0, 0), CV_8UC1) { - int erosionSize = parameters_.offsetSize; // single sided length of the kernel - int erosionType = cv::MORPH_CROSS; // cv::MORPH_ELLIPSE, cv::MORPH_RECT +ContourExtraction::ContourExtraction(const ContourExtractionParameters& parameters) + : parameters_(parameters), binaryImage_(cv::Size(0, 0), CV_8UC1) { + int erosionSize = parameters_.offsetSize; // single sided length of the kernel + int erosionType = cv::MORPH_CROSS; // cv::MORPH_ELLIPSE, cv::MORPH_RECT erosionKernel_ = cv::getStructuringElement(erosionType, cv::Size(2 * erosionSize + 1, 2 * erosionSize + 1)); } @@ -49,7 +49,7 @@ std::vector extractBoundaryAndInset(cv::Mat& binary_image, co std::vector boundaries = extractPolygonsFromBinaryImage(binary_image); // Erode - cv::erode( binary_image, binary_image, erosionKernel ); + cv::erode(binary_image, binary_image, erosionKernel); // Get insets std::vector insets = extractPolygonsFromBinaryImage(binary_image); @@ -64,7 +64,7 @@ std::vector extractBoundaryAndInset(cv::Mat& binary_image, co } } - if (!assignedInsets.empty()){ + if (!assignedInsets.empty()) { BoundaryWithInset boundaryWithInset; boundaryWithInset.boundary = boundary; boundaryWithInset.insets = assignedInsets; @@ -104,7 +104,7 @@ std::vector extractPolygonsFromBinaryImage(const cv::Mat CgalPolygon2d cgalPolygonFromOpenCv(const std::vector& openCvPolygon) { CgalPolygon2d polygon; polygon.container().reserve(openCvPolygon.size()); - for (const auto& point: openCvPolygon) { + for (const auto& point : openCvPolygon) { polygon.container().emplace_back(point.x, point.y); } return polygon; @@ -118,10 +118,8 @@ CgalPoint2d worldFrameToTerrainFrame(const CgalPoint2d& worldFrameXY, const Terr CgalPoint2d pixelToWorldFrame(const CgalPoint2d& pixelspaceCgalPoint2d, double resolution, const Eigen::Vector2d& mapOffset) { // Notice the transpose of x and y! - return {mapOffset.x() -resolution * pixelspaceCgalPoint2d.y(), mapOffset.y() -resolution * pixelspaceCgalPoint2d.x()}; + return {mapOffset.x() - resolution * pixelspaceCgalPoint2d.y(), mapOffset.y() - resolution * pixelspaceCgalPoint2d.x()}; } - - } // namespace contour_extraction } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index e32e6fd3..0f0a7aa1 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -40,7 +40,7 @@ void SlidingWindowPlaneExtractor::runExtraction(const grid_map::GridMap& map, co segmentedPlanesMap_.highestLabel = -1; segmentedPlanesMap_.labelPlaneParameters.clear(); const auto& mapSize = map_->getSize(); - binaryImagePatch_ = cv::Mat(mapSize(0), mapSize(1), CV_8U, 0.0); // Zero initialize to set untouched pixels to not planar; + binaryImagePatch_ = cv::Mat(mapSize(0), mapSize(1), CV_8U, 0.0); // Zero initialize to set untouched pixels to not planar; // Need a buffer of at least the linear size of the image. But no need to shrink if the buffer is already bigger. const int linearMapSize = mapSize(0) * mapSize(1); if (surfaceNormals_.size() < linearMapSize) { @@ -132,11 +132,12 @@ void SlidingWindowPlaneExtractor::runSlidingWindowDetector() { // Label cells according to which cell they belong to using connected component labeling. void SlidingWindowPlaneExtractor::runSegmentation() { int numberOfLabel = cv::connectedComponents(binaryImagePatch_, segmentedPlanesMap_.labeledImage, parameters_.connectivity, CV_32S); - segmentedPlanesMap_.highestLabel = numberOfLabel - 1; // Labels are [0, N-1] + segmentedPlanesMap_.highestLabel = numberOfLabel - 1; // Labels are [0, N-1] } void SlidingWindowPlaneExtractor::extractPlaneParametersFromLabeledImage() { - const int numberOfExtractedPlanesWithoutRefinement = segmentedPlanesMap_.highestLabel; // Make local copy. The highestLabel is incremented inside the loop + const int numberOfExtractedPlanesWithoutRefinement = + segmentedPlanesMap_.highestLabel; // Make local copy. The highestLabel is incremented inside the loop // Skip label 0. This is the background, i.e. non-planar region. for (int label = 1; label <= numberOfExtractedPlanesWithoutRefinement; ++label) { @@ -167,7 +168,8 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label) { normal_vector_sum += normal_vector_temp; ++number_of_normal_instances; - Eigen::Vector3d point3d{segmentedPlanesMap_.mapOrigin.x() - row * segmentedPlanesMap_.resolution, segmentedPlanesMap_.mapOrigin.y() - col * segmentedPlanesMap_.resolution, height}; + Eigen::Vector3d point3d{segmentedPlanesMap_.mapOrigin.x() - row * segmentedPlanesMap_.resolution, + segmentedPlanesMap_.mapOrigin.y() - col * segmentedPlanesMap_.resolution, height}; support_vector_sum += point3d; ++number_of_position_instances; @@ -227,7 +229,8 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label) { if (angleBetweenVectorsInDegrees(normal_vector_refined_avg, Eigen::Vector3d::UnitZ()) < parameters_.plane_inclination_threshold_degrees) { - const TerrainPlane temp_plane_parameters(support_vector_refined_avg, switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normal_vector_refined_avg)); + const TerrainPlane temp_plane_parameters( + support_vector_refined_avg, switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normal_vector_refined_avg)); segmentedPlanesMap_.labelPlaneParameters.emplace_back(newLabel, temp_plane_parameters); } } @@ -242,9 +245,9 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label) { segmentedPlanesMap_.labeledImage.at(map_indices(0), map_indices(1)) = 0; } } else { - if (angleBetweenVectorsInDegrees(normal_vector_avg, Eigen::Vector3d::UnitZ()) < - parameters_.plane_inclination_threshold_degrees) { - const TerrainPlane temp_plane_parameters(support_vector_avg, switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normal_vector_avg)); + if (angleBetweenVectorsInDegrees(normal_vector_avg, Eigen::Vector3d::UnitZ()) < parameters_.plane_inclination_threshold_degrees) { + const TerrainPlane temp_plane_parameters(support_vector_avg, + switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normal_vector_avg)); segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, temp_plane_parameters); } } From 2122467e5744dfe00b1ef10f634b188ee1bbd4c4 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 5 Aug 2020 11:13:08 +0200 Subject: [PATCH 055/504] add comment --- .../src/SegmentedPlanesTerrainModel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index 3bfdbe38..ab2ea0c4 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -11,6 +11,7 @@ namespace switched_model { +// TODO (rgrandia) : deadzone a parameter const double zHeightDistanceDeadzone = 0.1; // [m] This difference in z height is not counted double distanceCost(const vector3_t& query, const vector3_t& terrainPoint) { From b4b63b86c5c1e7737cdae9fe7bfae6e6f4184b52 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 5 Aug 2020 11:23:53 +0200 Subject: [PATCH 056/504] adapt to renaming --- .../SegmentedPlanesTerrainModel.h | 2 +- .../src/SegmentedPlanesTerrainModel.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h index 1f7617fe..ace46075 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h @@ -13,7 +13,7 @@ class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { public: SegmentedPlanesTerrainModel(convex_plane_decomposition::PlanarTerrain planarTerrain); - TerrainPlane getLocalTerrainAtPositionInWorld(const vector3_t& positionInWorld) const override; + TerrainPlane getLocalTerrainAtPositionInWorldAlongGravity(const vector3_t& positionInWorld) const override; ConvexTerrain getConvexTerrainAtPositionInWorld(const vector3_t& positionInWorld) const override; diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index ab2ea0c4..ec958a2d 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -39,7 +39,7 @@ double distanceCostLowerbound(double distanceSquared) { SegmentedPlanesTerrainModel::SegmentedPlanesTerrainModel(convex_plane_decomposition::PlanarTerrain planarTerrain) : planarTerrain_(std::move(planarTerrain)) {} -TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorld(const vector3_t& positionInWorld) const { +TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorldAlongGravity(const vector3_t& positionInWorld) const { const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_); const auto& region = *regionAndSeedPoint.first; const auto& seedpoint = regionAndSeedPoint.second; From 1f70e6d952ddd53026ef4a2756f1afe2b911cc26 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 5 Aug 2020 11:25:37 +0200 Subject: [PATCH 057/504] install gmp, mfpr on the buildserver --- cgal5_catkin/package.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cgal5_catkin/package.xml b/cgal5_catkin/package.xml index 29ae2f27..87364daa 100644 --- a/cgal5_catkin/package.xml +++ b/cgal5_catkin/package.xml @@ -7,4 +7,6 @@ See package catkin + libgmp-dev + libmpfr-dev From b859b5999294232ea9c0cf06134f2359d0b79ba6 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 5 Aug 2020 11:27:36 +0200 Subject: [PATCH 058/504] change package xml version --- cgal5_catkin/package.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cgal5_catkin/package.xml b/cgal5_catkin/package.xml index 87364daa..4cbb5614 100644 --- a/cgal5_catkin/package.xml +++ b/cgal5_catkin/package.xml @@ -1,4 +1,5 @@ - + + cgal5_catkin 5.0.2 Catkin wrapper for CGAL 5. From 99e7063d09d42e65e73d5ee700f5f7b238570458 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 5 Aug 2020 12:04:47 +0200 Subject: [PATCH 059/504] install headers --- cgal5_catkin/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cgal5_catkin/CMakeLists.txt b/cgal5_catkin/CMakeLists.txt index 2582a1a7..445a42f5 100644 --- a/cgal5_catkin/CMakeLists.txt +++ b/cgal5_catkin/CMakeLists.txt @@ -26,3 +26,8 @@ catkin_package( INCLUDE_DIRS ${CATKIN_DEVEL_PREFIX}/include CFG_EXTRAS cgal-extras.cmake ) + +install(DIRECTORY ${CATKIN_DEVEL_PREFIX}/include/CGAL/ + DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/CGAL/ +) + From 596385c7f5b8fc4e38e4d7c7353f017d75a54c94 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 5 Aug 2020 11:10:21 +0200 Subject: [PATCH 060/504] signed distance wip --- .../config/demo_node.yaml | 2 +- .../config/image_loader_demo_parameters.yaml | 2 +- .../config/parameters.yaml | 2 +- .../config/standalone_node.yaml | 6 +- .../rviz/config_demo.rviz | 588 +++++++++++++++++- segmented_planes_terrain_model/CMakeLists.txt | 12 + .../distance_transform/COPYING | 339 ++++++++++ .../distance_transform/dt.h | 117 ++++ .../distance_transform/image.h | 101 +++ .../distance_transform/imconv.h | 179 ++++++ .../distance_transform/imutil.h | 67 ++ .../distance_transform/misc.h | 62 ++ .../distance_transform/pnmfile.h | 214 +++++++ segmented_planes_terrain_model/package.xml | 4 + .../src/DemoNode.cpp | 61 +- .../test/signedDistanceTest.cpp | 261 ++++++++ signed_distance_field/CMakeLists.txt | 72 +++ .../signed_distance_field/SignedDistance2d.h | 28 + .../include/signed_distance_field/Utils.h | 12 + signed_distance_field/package.xml | 15 + .../src/SignedDistance2d.cpp | 177 ++++++ .../src/SignedDistanceField.cpp | 7 + .../test/testSignedDistance2d.cpp | 161 +++++ 23 files changed, 2458 insertions(+), 31 deletions(-) create mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/COPYING create mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/dt.h create mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/image.h create mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imconv.h create mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imutil.h create mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/misc.h create mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/pnmfile.h create mode 100644 segmented_planes_terrain_model/test/signedDistanceTest.cpp create mode 100644 signed_distance_field/CMakeLists.txt create mode 100644 signed_distance_field/include/signed_distance_field/SignedDistance2d.h create mode 100644 signed_distance_field/include/signed_distance_field/Utils.h create mode 100644 signed_distance_field/package.xml create mode 100644 signed_distance_field/src/SignedDistance2d.cpp create mode 100644 signed_distance_field/src/SignedDistanceField.cpp create mode 100644 signed_distance_field/test/testSignedDistance2d.cpp diff --git a/convex_plane_decomposition_ros/config/demo_node.yaml b/convex_plane_decomposition_ros/config/demo_node.yaml index 8f24686d..a25332aa 100644 --- a/convex_plane_decomposition_ros/config/demo_node.yaml +++ b/convex_plane_decomposition_ros/config/demo_node.yaml @@ -3,5 +3,5 @@ height_layer: 'elevation' submap: width: 6.0 length: 6.0 -publish_to_controller: false +publish_to_controller: true frequency: 10.0 diff --git a/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml b/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml index d53ea989..fcf5ef45 100644 --- a/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml +++ b/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml @@ -1,6 +1,6 @@ image_to_gridmap_demo: image_topic: "/image_publisher/image" resolution: 0.02 - map_frame_id: "map" # This parameter is actually not used. The gridmap is always in map frame + map_frame_id: "map" # This parameter is actually not used. The gridmap is always in map frame min_height: 0 max_height: 1.0 \ No newline at end of file diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 1ac210c1..aa45a11c 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -18,7 +18,7 @@ ransac_plane_refinement: probability: 0.01 # Probability to miss the largest candidate shape. A lower probability provides a higher reliability and determinism at the cost of longer running times min_points: 25 # This minimum number of points per plane. Controls the termination of the algorithm. epsilon: 0.02 # Maximum distance to plane - cluster_epsilon: 0.02 # Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon + cluster_epsilon: 0.05 # Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon normal_threshold: 0.98 # Set maximum normal deviation. normal_threshold < dot(surface_normal, point_normal); contour_extraction: diff --git a/convex_plane_decomposition_ros/config/standalone_node.yaml b/convex_plane_decomposition_ros/config/standalone_node.yaml index ab2ee21b..f6b76949 100644 --- a/convex_plane_decomposition_ros/config/standalone_node.yaml +++ b/convex_plane_decomposition_ros/config/standalone_node.yaml @@ -1,7 +1,7 @@ -elevation_topic: '/elevation_mapping/elevation_map_raw' +elevation_topic: '/elevation_mapping/elevation_map_recordable' height_layer: 'elevation' submap: - width: 6.0 - length: 6.0 + width: 3.0 + length: 3.0 publish_to_controller: false frequency: 10.0 diff --git a/convex_plane_decomposition_ros/rviz/config_demo.rviz b/convex_plane_decomposition_ros/rviz/config_demo.rviz index 7f2f8a13..9aeda245 100644 --- a/convex_plane_decomposition_ros/rviz/config_demo.rviz +++ b/convex_plane_decomposition_ros/rviz/config_demo.rviz @@ -6,7 +6,7 @@ Panels: Expanded: - /Global Options1 Splitter Ratio: 0.4083484709262848 - Tree Height: 806 + Tree Height: 540 - Class: rviz/Selection Name: Selection - Class: rviz/Tool Properties @@ -76,7 +76,7 @@ Visualization Manager: Min Intensity: 0 Name: GridMap Show Grid Lines: true - Topic: /image_to_gridmap_demo/grid_map + Topic: /elevation_mapping/elevation_map_recordable Unreliable: false Use Rainbow: true Value: true @@ -125,11 +125,571 @@ Visualization Manager: {} Queue Size: 100 Value: true + - Class: anymal_rviz_plugin/AnymalDisplay + Contact Polygon: + CoM Arrow Alpha: 0.6000000238418579 + CoM Arrow Color: 0; 204; 204 + CoM Arrow Thickness: 0.029999999329447746 + CoM Polygon Projection Alpha: 0.6000000238418579 + CoM Polygon Projection Color: 0; 102; 102 + Polygon Line Color: 204; 204; 204 + Polygon Line Thickness: 0.009999999776482582 + Polygon Line alpha: 0.6000000238418579 + Show CoM Column: true + Show CoM Projection: true + Value: false + Contacts: + Alpha: 0.30000001192092896 + Color: 100; 100; 100 + Color Mode: Contact/Plane + LF_FOOT: + Alpha: 0.30000001192092896 + Color: 204; 41; 204 + Color Mode: Contact/Plane + Normal Plane Size: 0.20000000298023224 + Show Normal: true + Show Wrench: true + Value: false + Wrench Arrow Width: 0.009999999776482582 + Wrench Scale: 0.003000000026077032 + LH_FOOT: + Alpha: 0.30000001192092896 + Color: 204; 41; 204 + Color Mode: Contact/Plane + Normal Plane Size: 0.20000000298023224 + Show Normal: true + Show Wrench: true + Value: false + Wrench Arrow Width: 0.009999999776482582 + Wrench Scale: 0.003000000026077032 + Normal Plane Size: 0.20000000298023224 + RF_FOOT: + Alpha: 0.30000001192092896 + Color: 204; 41; 204 + Color Mode: Contact/Plane + Normal Plane Size: 0.20000000298023224 + Show Normal: true + Show Wrench: true + Value: false + Wrench Arrow Width: 0.009999999776482582 + Wrench Scale: 0.003000000026077032 + RH_FOOT: + Alpha: 0.30000001192092896 + Color: 204; 41; 204 + Color Mode: Contact/Plane + Normal Plane Size: 0.20000000298023224 + Show Normal: true + Show Wrench: true + Value: false + Wrench Arrow Width: 0.009999999776482582 + Wrench Scale: 0.003000000026077032 + Show Normal: true + Show Wrench: true + Value: false + Wrench Arrow Width: 0.009999999776482582 + Wrench Scale: 0.003000000026077032 + Enabled: true + Joint Torques: + Alpha: 1 + Color: 240; 240; 240 + Color Mode: + Threshold: 0.75 + Value: Solid Color + LF_HAA: + Offset: 0 + Torque Maximum: 40 + Value: false + LF_HFE: + Offset: 0 + Torque Maximum: 40 + Value: false + LF_KFE: + Offset: 0 + Torque Maximum: 40 + Value: false + LH_HAA: + Offset: 0 + Torque Maximum: 40 + Value: false + LH_HFE: + Offset: 0 + Torque Maximum: 40 + Value: false + LH_KFE: + Offset: 0 + Torque Maximum: 40 + Value: false + RF_HAA: + Offset: 0 + Torque Maximum: 40 + Value: false + RF_HFE: + Offset: 0 + Torque Maximum: 40 + Value: false + RF_KFE: + Offset: 0 + Torque Maximum: 40 + Value: false + RH_HAA: + Offset: 0 + Torque Maximum: 40 + Value: false + RH_HFE: + Offset: 0 + Torque Maximum: 40 + Value: false + RH_KFE: + Offset: 0 + Torque Maximum: 40 + Value: false + Size: 0.10000000149011612 + Value: false + Name: AnymalDisplay + Robot Description: anymal_description + Robot Display Options: + Alpha: 1 + Collision Enabled: false + Color Mode: + Color: 204; 204; 204 + Value: Mesh Texture + Links: + All Links Enabled: true + Expand Joint Details: false + Expand Link Details: false + Expand Tree: false + LF_FOOT: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LF_HAA: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LF_HFE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LF_HIP: + Alpha: 1 + Show Axes: false + Show Trail: false + LF_KFE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LF_SHANK: + Alpha: 1 + Show Axes: false + Show Trail: false + LF_THIGH: + Alpha: 1 + Show Axes: false + Show Trail: false + LF_hip_fixed: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LF_shank_fixed: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LF_thigh_fixed: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LH_FOOT: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LH_HAA: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LH_HFE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LH_HIP: + Alpha: 1 + Show Axes: false + Show Trail: false + LH_KFE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LH_SHANK: + Alpha: 1 + Show Axes: false + Show Trail: false + LH_THIGH: + Alpha: 1 + Show Axes: false + Show Trail: false + LH_hip_fixed: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LH_shank_fixed: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LH_thigh_fixed: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + Link Tree Style: Links in Alphabetic Order + RF_FOOT: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RF_HAA: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RF_HFE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RF_HIP: + Alpha: 1 + Show Axes: false + Show Trail: false + RF_KFE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RF_SHANK: + Alpha: 1 + Show Axes: false + Show Trail: false + RF_THIGH: + Alpha: 1 + Show Axes: false + Show Trail: false + RF_hip_fixed: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RF_shank_fixed: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RF_thigh_fixed: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RH_FOOT: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RH_HAA: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RH_HFE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RH_HIP: + Alpha: 1 + Show Axes: false + Show Trail: false + RH_KFE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RH_SHANK: + Alpha: 1 + Show Axes: false + Show Trail: false + RH_THIGH: + Alpha: 1 + Show Axes: false + Show Trail: false + RH_hip_fixed: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RH_shank_fixed: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RH_thigh_fixed: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + base: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + base_inertia: + Alpha: 1 + Show Axes: false + Show Trail: false + battery: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + blackfly_front_camera: + Alpha: 1 + Show Axes: false + Show Trail: false + blackfly_front_camera_parent: + Alpha: 1 + Show Axes: false + Show Trail: false + blackfly_rear_camera: + Alpha: 1 + Show Axes: false + Show Trail: false + blackfly_rear_camera_parent: + Alpha: 1 + Show Axes: false + Show Trail: false + docking_socket: + Alpha: 1 + Show Axes: false + Show Trail: false + face_front: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + face_rear: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + hatch: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + imu_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + realsense_d435_front_camera: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_front_camera_parent: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_front_color_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_front_color_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_front_depth_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_left_camera: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_left_camera_parent: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_left_color_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_left_color_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_left_depth_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_rear_camera: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_rear_camera_parent: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_rear_color_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_rear_color_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_rear_depth_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_right_camera: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_right_camera_parent: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_right_color_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_right_color_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_d435_right_depth_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + shell: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + velodyne: + Alpha: 1 + Show Axes: false + Show Trail: false + velodyne_cage: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + Visual Enabled: true + Robot Velocity: + Alpha: 0.6000000238418579 + Angular Color: 0; 204; 0 + Angular Scale: 0.5 + Linear Color: 0; 0; 204 + Linear Scale: 1 + Offset: 0.4000000059604645 + Show Angular: true + Show Linear: true + Value: false + Topic: /state_estimator/anymal_state + Traces: + Alpha: 0.5 + Color: 255; 0; 0 + LF_FOOT: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + LF_HIP: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + LF_SHANK: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + LF_THIGH: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + LH_FOOT: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + LH_HIP: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + LH_SHANK: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + LH_THIGH: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + RF_FOOT: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + RF_HIP: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + RF_SHANK: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + RF_THIGH: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + RH_FOOT: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + RH_HIP: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + RH_SHANK: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + RH_THIGH: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + Time Length: 10 + Value: false + Width: 0.004999999888241291 + base: + Alpha: 0.5 + Color: 255; 0; 0 + Value: false + Unreliable: false + Update Rate: 20 + Value: true + World Frame Name: odom Enabled: true Global Options: Background Color: 255; 255; 255 Default Light: true - Fixed Frame: map + Fixed Frame: odom Frame Rate: 30 Name: root Tools: @@ -153,33 +713,33 @@ Visualization Manager: Views: Current: Class: rviz/Orbit - Distance: 4.217182636260986 + Distance: 2.9079933166503906 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 Swap Stereo Eyes: false Value: false Focal Point: - X: -0.02726033888757229 - Y: -0.07391251623630524 - Z: 0.2781669795513153 + X: 2.382049322128296 + Y: -0.7195556163787842 + Z: -0.01261717639863491 Focal Shape Fixed Size: true Focal Shape Size: 0.05000000074505806 Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.6197972893714905 + Pitch: 0.499797523021698 Target Frame: Value: Orbit (rviz) - Yaw: 3.8899669647216797 + Yaw: 1.5949591398239136 Saved: ~ Window Geometry: Displays: collapsed: false - Height: 1025 + Height: 759 Hide Left Dock: false Hide Right Dock: true - QMainWindow State: 000000ff00000000fd00000004000000000000022900000363fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000363000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f0000040efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000280000040e000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000073d0000003efc0100000002fb0000000800540069006d006501000000000000073d000002eb00fffffffb0000000800540069006d006501000000000000045000000000000000000000050e0000036300000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd00000004000000000000022900000259fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000259000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f0000040efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000280000040e000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000056d0000003efc0100000002fb0000000800540069006d006501000000000000056d000002eb00fffffffb0000000800540069006d006501000000000000045000000000000000000000033e0000025900000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -188,6 +748,6 @@ Window Geometry: collapsed: false Views: collapsed: true - Width: 1853 - X: 67 - Y: 27 + Width: 1389 + X: 2208 + Y: 195 diff --git a/segmented_planes_terrain_model/CMakeLists.txt b/segmented_planes_terrain_model/CMakeLists.txt index ff8aea6b..9482e05c 100644 --- a/segmented_planes_terrain_model/CMakeLists.txt +++ b/segmented_planes_terrain_model/CMakeLists.txt @@ -5,11 +5,15 @@ project(segmented_planes_terrain_model) set(CATKIN_PACKAGE_DEPENDENCIES ocs2_switched_model_interface ocs2_quadruped_interface + grid_map_sdf + pcl_ros convex_plane_decomposition convex_plane_decomposition_msgs convex_plane_decomposition_ros + signed_distance_field roscpp visualization_msgs + sensor_msgs ) find_package(catkin REQUIRED COMPONENTS @@ -86,3 +90,11 @@ install(DIRECTORY launch ############# ## Testing ## ############# + +add_executable(${PROJECT_NAME}_signed_distance_test + test/signedDistanceTest.cpp + ) +target_link_libraries(${PROJECT_NAME}_signed_distance_test + ${catkin_LIBRARIES} + ${PROJECT_NAME} + ) \ No newline at end of file diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/COPYING b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/COPYING new file mode 100755 index 00000000..d511905c --- /dev/null +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/dt.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/dt.h new file mode 100755 index 00000000..2c83de57 --- /dev/null +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/dt.h @@ -0,0 +1,117 @@ +/* +Copyright (C) 2006 Pedro Felzenszwalb + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* distance transform */ + +#pragma once + +#include + +#include "image.h" +#include "imconv.h" + +namespace distance_transform +{ + const double INF = 1E20; + + /* dt of 1d function using squared distance */ + static float *dt_1d(float *f, int n) { + float *d = new float[n]; + int *v = new int[n]; + float *z = new float[n+1]; + int k = 0; + v[0] = 0; + z[0] = -INF; + z[1] = +INF; + for (int q = 1; q <= n-1; q++) { + float s = ((f[q]+square(q))-(f[v[k]]+square(v[k])))/(2*q-2*v[k]); + while (s <= z[k]) { + k--; + s = ((f[q]+square(q))-(f[v[k]]+square(v[k])))/(2*q-2*v[k]); + } + k++; + v[k] = q; + z[k] = s; + z[k+1] = +INF; + } + + k = 0; + for (int q = 0; q <= n-1; q++) { + while (z[k+1] < q) + k++; + d[q] = square(q-v[k]) + f[v[k]]; + } + + delete [] v; + delete [] z; + return d; + } + + /* dt of 2d function using squared distance */ + static void dt_2d(image *im) { + int width = im->width(); + int height = im->height(); + float *f = new float[std::max(width,height)]; + + // transform along columns + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + f[y] = imRef(im, x, y); + } + float *d = dt_1d(f, height); + for (int y = 0; y < height; y++) { + imRef(im, x, y) = d[y]; + } + delete [] d; + } + + // transform along rows + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + f[x] = imRef(im, x, y); + } + float *d = dt_1d(f, width); + for (int x = 0; x < width; x++) { + imRef(im, x, y) = d[x]; + } + delete [] d; + } + + delete [] f; + } + + /* dt of binary image using squared distance */ + static image *dt(image *im, uchar on = 1) { + int width = im->width(); + int height = im->height(); + + image *out = new image(width, height, false); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + if (imRef(im, x, y) == on) + imRef(out, x, y) = 0; + else + imRef(out, x, y) = INF; + } + } + + dt_2d(out); + return out; + } + +} // namespace diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/image.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/image.h new file mode 100755 index 00000000..47cada09 --- /dev/null +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/image.h @@ -0,0 +1,101 @@ +/* +Copyright (C) 2006 Pedro Felzenszwalb + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* a simple image class */ + +#pragma once + +#include + +namespace distance_transform +{ + + template + class image { + public: + /* create an image */ + image(const int width, const int height, const bool init = true); + + /* delete an image */ + ~image(); + + /* init an image */ + void init(const T &val); + + /* copy an image */ + image *copy() const; + + /* get the width of an image. */ + int width() const { return w; } + + /* get the height of an image. */ + int height() const { return h; } + + /* image data. */ + T *data; + + /* row pointers. */ + T **access; + + private: + int w, h; + }; + + /* use imRef to access image data. */ +#define imRef(im, x, y) (im->access[y][x]) + + /* use imPtr to get pointer to image data. */ +#define imPtr(im, x, y) &(im->access[y][x]) + + template + image::image(const int width, const int height, const bool init) { + w = width; + h = height; + data = new T[w * h]; // allocate space for image data + access = new T*[h]; // allocate space for row pointers + + // initialize row pointers + for (int i = 0; i < h; i++) + access[i] = data + (i * w); + + if (init) + memset(data, 0, w * h * sizeof(T)); + } + + template + image::~image() { + delete [] data; + delete [] access; + } + + template + void image::init(const T &val) { + T *ptr = imPtr(this, 0, 0); + T *end = imPtr(this, w-1, h-1); + while (ptr <= end) + *ptr++ = val; + } + + template + image *image::copy() const { + image *im = new image(w, h, false); + memcpy(im->data, data, w * h * sizeof(T)); + return im; + } + +} // namespace diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imconv.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imconv.h new file mode 100755 index 00000000..b4f27ff3 --- /dev/null +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imconv.h @@ -0,0 +1,179 @@ +/* +Copyright (C) 2006 Pedro Felzenszwalb + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* image conversion */ + +#pragma once + +#include + +#include "image.h" +#include "imutil.h" +#include "misc.h" + +namespace distance_transform +{ + const double RED_WEIGHT = 0.299; + const double GREEN_WEIGHT = 0.584; + const double BLUE_WEIGHT = 0.114; + + static image *imageRGBtoGRAY(image *input) { + int width = input->width(); + int height = input->height(); + image *output = new image(width, height, false); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + imRef(output, x, y) = (uchar) + (imRef(input, x, y).r * RED_WEIGHT + + imRef(input, x, y).g * GREEN_WEIGHT + + imRef(input, x, y).b * BLUE_WEIGHT); + } + } + return output; + } + + static image *imageGRAYtoRGB(image *input) { + int width = input->width(); + int height = input->height(); + image *output = new image(width, height, false); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + imRef(output, x, y).r = imRef(input, x, y); + imRef(output, x, y).g = imRef(input, x, y); + imRef(output, x, y).b = imRef(input, x, y); + } + } + return output; + } + + static image *imageUCHARtoFLOAT(image *input) { + int width = input->width(); + int height = input->height(); + image *output = new image(width, height, false); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + imRef(output, x, y) = imRef(input, x, y); + } + } + return output; + } + + static image *imageINTtoFLOAT(image *input) { + int width = input->width(); + int height = input->height(); + image *output = new image(width, height, false); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + imRef(output, x, y) = imRef(input, x, y); + } + } + return output; + } + + static image *imageFLOATtoUCHAR(image *input, + float min, float max) { + int width = input->width(); + int height = input->height(); + image *output = new image(width, height, false); + + if (max == min) + return output; + + float scale = UCHAR_MAX / (max - min); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + uchar val = (uchar)((imRef(input, x, y) - min) * scale); + imRef(output, x, y) = bound(val, (uchar)0, (uchar)UCHAR_MAX); + } + } + return output; + } + + static image *imageFLOATtoUCHAR(image *input) { + float min, max; + min_max(input, &min, &max); + return imageFLOATtoUCHAR(input, min, max); + } + + static image *imageUCHARtoLONG(image *input) { + int width = input->width(); + int height = input->height(); + image *output = new image(width, height, false); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + imRef(output, x, y) = imRef(input, x, y); + } + } + return output; + } + + static image *imageLONGtoUCHAR(image *input, long min, long max) { + int width = input->width(); + int height = input->height(); + image *output = new image(width, height, false); + + if (max == min) + return output; + + float scale = UCHAR_MAX / (float)(max - min); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + uchar val = (uchar)((imRef(input, x, y) - min) * scale); + imRef(output, x, y) = bound(val, (uchar)0, (uchar)UCHAR_MAX); + } + } + return output; + } + + static image *imageLONGtoUCHAR(image *input) { + long min, max; + min_max(input, &min, &max); + return imageLONGtoUCHAR(input, min, max); + } + + static image *imageSHORTtoUCHAR(image *input, + short min, short max) { + int width = input->width(); + int height = input->height(); + image *output = new image(width, height, false); + + if (max == min) + return output; + + float scale = UCHAR_MAX / (float)(max - min); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + uchar val = (uchar)((imRef(input, x, y) - min) * scale); + imRef(output, x, y) = bound(val, (uchar)0, (uchar)UCHAR_MAX); + } + } + return output; + } + + static image *imageSHORTtoUCHAR(image *input) { + short min, max; + min_max(input, &min, &max); + return imageSHORTtoUCHAR(input, min, max); + } + +} // namespace diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imutil.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imutil.h new file mode 100755 index 00000000..ad09d1f8 --- /dev/null +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imutil.h @@ -0,0 +1,67 @@ +/* +Copyright (C) 2006 Pedro Felzenszwalb + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* some image utilities */ + +#pragma once + +#include "image.h" +#include "misc.h" + +namespace distance_transform +{ + + /* compute minimum and maximum value in an image */ + template + void min_max(image *im, T *ret_min, T *ret_max) { + int width = im->width(); + int height = im->height(); + + T min = imRef(im, 0, 0); + T max = imRef(im, 0, 0); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + T val = imRef(im, x, y); + if (min > val) + min = val; + if (max < val) + max = val; + } + } + + *ret_min = min; + *ret_max = max; + } + + /* threshold image */ + template + image *threshold(image *src, int t) { + int width = src->width(); + int height = src->height(); + image *dst = new image(width, height); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + imRef(dst, x, y) = (imRef(src, x, y) >= t); + } + } + + return dst; + } + +} // namespace diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/misc.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/misc.h new file mode 100755 index 00000000..a9514d1f --- /dev/null +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/misc.h @@ -0,0 +1,62 @@ +/* +Copyright (C) 2006 Pedro Felzenszwalb + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* random stuff */ + +#pragma once + +#include + +namespace distance_transform +{ + typedef unsigned char uchar; + + typedef struct { uchar r, g, b; } rgb; + + inline bool operator==(const rgb &a, const rgb &b) { + return ((a.r == b.r) && (a.g == b.g) && (a.b == b.b)); + } + + template + inline T abs(const T &x) { return (x > 0 ? x : -x); }; + + template + inline int sign(const T &x) { return (x >= 0 ? 1 : -1); }; + + template + inline T square(const T &x) { return x*x; }; + + template + inline T bound(const T &x, const T &min, const T &max) { + return (x < min ? min : (x > max ? max : x)); + } + + template + inline bool check_bound(const T &x, const T&min, const T &max) { + return ((x < min) || (x > max)); + } + + inline int vlib_round(float x) { return (int)(x + 0.5F); } + + inline int vlib_round(double x) { return (int)(x + 0.5); } + + inline double gaussian(double val, double sigma) { + return exp(-square(val/sigma)/2)/(sqrt(2*M_PI)*sigma); + } + +} // namespace diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/pnmfile.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/pnmfile.h new file mode 100755 index 00000000..28284328 --- /dev/null +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/pnmfile.h @@ -0,0 +1,214 @@ +/* +Copyright (C) 2006 Pedro Felzenszwalb + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* basic image I/O */ + +#pragma once + +#include +#include +#include +#include + +#include "image.h" +#include "misc.h" + +namespace distance_transform +{ + + const short BUF_SIZE = 256; + + class pnm_error { }; + + static void read_packed(unsigned char *data, int size, std::ifstream &f) { + unsigned char c = 0; + + int bitshift = -1; + for (int pos = 0; pos < size; pos++) { + if (bitshift == -1) { + c = f.get(); + bitshift = 7; + } + data[pos] = (c >> bitshift) & 1; + bitshift--; + } + } + + static void write_packed(unsigned char *data, int size, std::ofstream &f) { + unsigned char c = 0; + + int bitshift = 7; + for (int pos = 0; pos < size; pos++) { + c = c | (data[pos] << bitshift); + bitshift--; + if ((bitshift == -1) || (pos == size-1)) { + f.put(c); + bitshift = 7; + c = 0; + } + } + } + + /* read PNM field, skipping comments */ + static void pnm_read(std::ifstream &file, char *buf) { + char doc[BUF_SIZE]; + char c; + + file >> c; + while (c == '#') { + file.getline(doc, BUF_SIZE); + file >> c; + } + file.putback(c); + + file.width(BUF_SIZE); + file >> buf; + file.ignore(); + } + + static image *loadPBM(const char *name) { + char buf[BUF_SIZE]; + + /* read header */ + std::ifstream file(name, std::ios::in | std::ios::binary); + pnm_read(file, buf); + if (strncmp(buf, "P4", 2)) + throw pnm_error(); + + pnm_read(file, buf); + int width = atoi(buf); + pnm_read(file, buf); + int height = atoi(buf); + + /* read data */ + image *im = new image(width, height); + for (int i = 0; i < height; i++) + read_packed(imPtr(im, 0, i), width, file); + + return im; + } + + static void savePBM(image *im, const char *name) { + int width = im->width(); + int height = im->height(); + std::ofstream file(name, std::ios::out | std::ios::binary); + + file << "P4\n" << width << " " << height << "\n"; + for (int i = 0; i < height; i++) + write_packed(imPtr(im, 0, i), width, file); + } + + static image *loadPGM(const char *name) { + char buf[BUF_SIZE]; + + /* read header */ + std::ifstream file(name, std::ios::in | std::ios::binary); + pnm_read(file, buf); + if (strncmp(buf, "P5", 2)) + throw pnm_error(); + + pnm_read(file, buf); + int width = atoi(buf); + pnm_read(file, buf); + int height = atoi(buf); + + pnm_read(file, buf); + if (atoi(buf) > UCHAR_MAX) + throw pnm_error(); + + /* read data */ + image *im = new image(width, height); + file.read((char *)imPtr(im, 0, 0), width * height * sizeof(uchar)); + + return im; + } + + static void savePGM(image *im, const char *name) { + int width = im->width(); + int height = im->height(); + std::ofstream file(name, std::ios::out | std::ios::binary); + + file << "P5\n" << width << " " << height << "\n" << UCHAR_MAX << "\n"; + file.write((char *)imPtr(im, 0, 0), width * height * sizeof(uchar)); + } + + static image *loadPPM(const char *name) { + char buf[BUF_SIZE], doc[BUF_SIZE]; + + /* read header */ + std::ifstream file(name, std::ios::in | std::ios::binary); + pnm_read(file, buf); + if (strncmp(buf, "P6", 2)) + throw pnm_error(); + + pnm_read(file, buf); + int width = atoi(buf); + pnm_read(file, buf); + int height = atoi(buf); + + pnm_read(file, buf); + if (atoi(buf) > UCHAR_MAX) + throw pnm_error(); + + /* read data */ + image *im = new image(width, height); + file.read((char *)imPtr(im, 0, 0), width * height * sizeof(rgb)); + + return im; + } + + static void savePPM(image *im, const char *name) { + int width = im->width(); + int height = im->height(); + std::ofstream file(name, std::ios::out | std::ios::binary); + + file << "P6\n" << width << " " << height << "\n" << UCHAR_MAX << "\n"; + file.write((char *)imPtr(im, 0, 0), width * height * sizeof(rgb)); + } + + template + void load_image(image **im, const char *name) { + char buf[BUF_SIZE]; + + /* read header */ + std::ifstream file(name, std::ios::in | std::ios::binary); + pnm_read(file, buf); + if (strncmp(buf, "VLIB", 9)) + throw pnm_error(); + + pnm_read(file, buf); + int width = atoi(buf); + pnm_read(file, buf); + int height = atoi(buf); + + /* read data */ + *im = new image(width, height); + file.read((char *)imPtr((*im), 0, 0), width * height * sizeof(T)); + } + + template + void save_image(image *im, const char *name) { + int width = im->width(); + int height = im->height(); + std::ofstream file(name, std::ios::out | std::ios::binary); + + file << "VLIB\n" << width << " " << height << "\n"; + file.write((char *)imPtr(im, 0, 0), width * height * sizeof(T)); + } + +} // namespace diff --git a/segmented_planes_terrain_model/package.xml b/segmented_planes_terrain_model/package.xml index c6c2d86a..8547f888 100644 --- a/segmented_planes_terrain_model/package.xml +++ b/segmented_planes_terrain_model/package.xml @@ -11,10 +11,14 @@ catkin ocs2_switched_model_interface ocs2_quadruped_interface + grid_map_sdf + pcl_ros convex_plane_decomposition convex_plane_decomposition_msgs convex_plane_decomposition_ros + signed_distance_field roscpp visualization_msgs + sensor_msgs diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp index 892d0445..73507c03 100644 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -9,11 +9,19 @@ #include #include +#include +#include +#include +#include +#include +#include + #include #include "segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h" -const std::string originFrameId_ = "map"; +const std::string originFrameId_ = "odom"; +std::unique_ptr messageMap; visualization_msgs::MarkerArray toMarker(const switched_model::ConvexTerrain& convexTerrain) { visualization_msgs::MarkerArray markerArray = @@ -36,6 +44,20 @@ visualization_msgs::Marker toMarker(const switched_model::vector3_t& position) { return marker; } +void elevationMappingCallback(const grid_map_msgs::GridMap& message) { + if (!messageMap) { + messageMap = std::make_unique(); + } + grid_map::GridMapRosConverter::fromMessage(message, *messageMap, {"elevation"}, false, false); +} + +float randomFloat(float a, float b) { + float random = ((float)rand()) / (float)RAND_MAX; + float diff = b - a; + float r = random * diff; + return a + r; +} + int main(int argc, char** argv) { ros::init(argc, argv, "segmented_planes_demo_node"); ros::NodeHandle nodeHandle("~"); @@ -44,27 +66,24 @@ int main(int argc, char** argv) { switched_model::SegmentedPlanesTerrainModelRos segmentedPlanesTerrainModelRos(nodeHandle); std::unique_ptr terrainModel; + // Elevation subscription + // Publishers for visualization auto positionPublisher_ = nodeHandle.advertise("queryPosition", 1); auto convexTerrainPublisher_ = nodeHandle.advertise("convex_terrain", 1); auto regionBoundaryPublisher_ = nodeHandle.advertise("regionBoundary", 1); + auto distanceFieldPublisher = nodeHandle.advertise("signed_distance_field", 1); + auto elevationMapSubscriber = nodeHandle.subscribe("/convex_plane_decomposition_ros/filtered_map", 1, &elevationMappingCallback); // Node loop - ros::Rate rate(2.); + ros::Rate rate(1./5.); while (ros::ok()) { if (segmentedPlanesTerrainModelRos.update(terrainModel)) { ROS_INFO("Terrain model updated!!"); } - if (terrainModel) { - const auto RandomFloat = [](float a, float b) { - float random = ((float)rand()) / (float)RAND_MAX; - float diff = b - a; - float r = random * diff; - return a + r; - }; - - switched_model::vector3_t positionInWorld{RandomFloat(-2.0, 2.0), RandomFloat(-2.0, 2.0), RandomFloat(0.0, 1.0)}; + if (terrainModel && messageMap) { + switched_model::vector3_t positionInWorld{randomFloat(-2.0, 2.0), randomFloat(-2.0, 2.0), randomFloat(0.0, 1.0)}; positionPublisher_.publish(toMarker(positionInWorld)); std::cout << "Query position: " << positionInWorld.transpose() << std::endl; @@ -75,6 +94,26 @@ int main(int argc, char** argv) { positionPublisher_.publish(toMarker(positionInWorld)); convexTerrainPublisher_.publish(toMarker(convexTerrain)); + + + grid_map::SignedDistanceField signedDistanceField; + double heightClearance = 0.1; + double width = 0.5; + bool success; + grid_map::GridMap localMap = messageMap->getSubmap({convexTerrain.plane.positionInWorld.x(), convexTerrain.plane.positionInWorld.y()}, Eigen::Array2d(width, width), success); + auto t2 = std::chrono::high_resolution_clock::now(); + signedDistanceField.calculateSignedDistanceField(*messageMap, "elevation", heightClearance); + auto t3 = std::chrono::high_resolution_clock::now(); + std::cout << "Sdf computation took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]\n"; + + pcl::PointCloud points; + signedDistanceField.convertToPointCloud(points); + + sensor_msgs::PointCloud2 pointCloud2Msg; + pcl::toROSMsg(points, pointCloud2Msg); + pointCloud2Msg.header = switched_model::getHeaderMsg(originFrameId_, ros::Time::now()); + + distanceFieldPublisher.publish(pointCloud2Msg); } ros::spinOnce(); diff --git a/segmented_planes_terrain_model/test/signedDistanceTest.cpp b/segmented_planes_terrain_model/test/signedDistanceTest.cpp new file mode 100644 index 00000000..d288977b --- /dev/null +++ b/segmented_planes_terrain_model/test/signedDistanceTest.cpp @@ -0,0 +1,261 @@ +// +// Created by rgrandia on 09.07.20. +// + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace distance_transform; + +constexpr float myINF = 1e20F; + +grid_map::GridMap loadElevationMapFromFile(const std::string& filePath, double resolution, double scale) { + // Read the file + cv::Mat image; + image = cv::imread(filePath, cv::ImreadModes::IMREAD_GRAYSCALE); + + // Check for invalid input + if (!image.data) { + throw std::runtime_error("Could not open or find the image"); + } + + // Min max values + double minValue, maxValue; + cv::minMaxLoc(image, &minValue, &maxValue); + + grid_map::GridMap mapOut({"elevation"}); + mapOut.setFrameId("odom"); + grid_map::GridMapCvConverter::initializeFromImage(image, resolution, mapOut, grid_map::Position(0.0, 0.0)); + grid_map::GridMapCvConverter::addLayerFromImage(image, std::string("elevation"), mapOut, float(0.0), float(scale), 0.5); + return mapOut; +} + +grid_map::Matrix getPlanarSignedDistanceField(const Eigen::Matrix& data) { + image* input = new image(data.rows(), data.cols(), true); + + for (int y = 0; y < input->height(); y++) { + for (int x = 0; x < input->width(); x++) { + imRef(input, x, y) = data(x, y); + } + } + + // Compute dt. + image* out = dt(input); + + grid_map::Matrix result(data.rows(), data.cols()); + + // Take square roots. + for (int y = 0; y < out->height(); y++) { + for (int x = 0; x < out->width(); x++) { + result(x, y) = sqrt(imRef(out, x, y)); + } + } + return result; +} + +void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDistance1d, Eigen::Ref d, + Eigen::Ref z, std::vector& v) { + const int n = squareDistance1d.size(); + const auto& f = squareDistance1d; + assert(d.size() == n); + assert(z.size() == n + 1); + assert(v.size() == n); + + // Initialize + int k = 0; + v[0] = 0; + z[0] = -myINF; + z[1] = myINF; + + // Compute bounds + for (int q = 1; q < n; q++) { + auto factor1 = static_cast(q - v[k]); + auto factor2 = static_cast(q + v[k]); + float s = 0.5F * ( (f[q] - f[v[k]]) / factor1 + factor2); + while (s <= z[k]) { + k--; + factor1 = static_cast(q - v[k]); + factor2 = static_cast(q + v[k]); + s = 0.5F * ( (f[q] - f[v[k]]) / factor1 + factor2); + } + k++; + v[k] = q; + z[k] = s; + z[k + 1] = myINF; + } + + // Collect results + k = 0; + for (int q = 0; q < n; q++) { + while (z[k + 1] < static_cast(q)) { + k++; + } + d[q] = square(q - v[k]) + f[v[k]]; + } + + // Write distance result back in place + squareDistance1d = d; +} + +void squaredDistanceTransform_2d_columnwiseInplace(grid_map::Matrix& squareDistance, bool skipCheck) { + const size_t n = squareDistance.cols(); + Eigen::VectorXf workvector(2 * n + 1); + std::vector intWorkvector(n); + + for (size_t i = 0; i < n; i++) { + // Only when there is a mix of elements and free space, we need to update the initialized distance. + bool needsComputation = skipCheck || ((squareDistance.col(i).array() == 0.0).any() && (squareDistance.col(i).array() == myINF).any()); + if (needsComputation) { + squaredDistanceTransform_1d_inplace(squareDistance.col(i), workvector.segment(0, n), workvector.segment(n, n+1), + intWorkvector); + } + } +} + +void squaredDistanceTransform_2d(grid_map::Matrix& squareDistance) { + // TODO (check which one we want to do first) + + // Process columns + squaredDistanceTransform_2d_columnwiseInplace(squareDistance, false); + + // Process rows + squareDistance.transposeInPlace(); + squaredDistanceTransform_2d_columnwiseInplace(squareDistance, true); + squareDistance.transposeInPlace(); +} + +void getPlanarSignedDistanceField_2(grid_map::Matrix& squareDistance) { + squaredDistanceTransform_2d(squareDistance); + squareDistance = squareDistance.cwiseSqrt(); +} + +grid_map::Matrix getPlanarSignedDistanceField_3(const grid_map::Matrix& map, float threshold, float resolution) { + bool hasObstacles = (map.array() >= threshold).any(); + if (hasObstacles) { + bool hasFreeSpace = (map.array() < threshold).any(); + if (hasFreeSpace) { + // Both obstacles and free space -> compute planar signed distance + // Compute pixel distance to obstacles + grid_map::Matrix sdfObstacle = map.unaryExpr([=](float val) {return (val >= threshold) ? 0.0F : myINF;}); + getPlanarSignedDistanceField_2(sdfObstacle); + + // Compute pixel distance to obstacle free space + grid_map::Matrix sdfObstacleFree = map.unaryExpr([=](float val) {return (val < threshold) ? 0.0F : myINF;}); + getPlanarSignedDistanceField_2(sdfObstacleFree); + + grid_map::Matrix sdf2d = resolution * (sdfObstacle - sdfObstacleFree); + return sdf2d; + } else { + // Only obstacles -> distance is zero everywhere + return grid_map::Matrix::Zero(map.rows(), map.cols()); + } + } else { + // No obstacles -> planar distance is infinite + return grid_map::Matrix::Constant(map.rows(), map.cols(), myINF); + } +} + +int main(int argc, char** argv) { + std::string folder = "/home/rgrandia/git/anymal/convex_terrain_representation/convex_plane_decomposition_ros/data/"; + // std::string file = "elevationMap_8_139cm.png"; + // double heightScale = 1.39; + std::string file = "demo_map.png"; + double heightScale = 1.25; + // std::string file = "realStairs_125cm.png"; double heightScale = 1.25; + // std::string file = "terrain.png"; double heightScale = 1.25; + // std::string file = "holes.png"; double heightScale = 1.0; + // std::string file = "slope_1m_1m_20cm.png"; double heightScale = 0.2; + // std::string file = "straightStairs_1m_1m_60cm.png"; double heightScale = 0.6; + double resolution = 0.02; + + auto messageMap = loadElevationMapFromFile(folder + file, resolution, heightScale); + + grid_map::SignedDistanceField signedDistanceField; + + double width = 1.0; + bool success; + grid_map::GridMap localMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(width, width), success); + + // signedDistanceField.calculateSignedDistanceField(messageMap, "elevation", heightClearance); + const grid_map::GridMap& gridMap = localMap; + const std::string& layer = "elevation"; + const double heightClearance = 0.1; + + // Members + float resolution_; + grid_map::Size size_; + grid_map::Position position_; + std::vector data_; + float zIndexStartHeight_; + float maxDistance_; + const float lowestHeight_ = -1e5; + using grid_map::Matrix; + + auto t2 = std::chrono::high_resolution_clock::now(); + const int N = 30; + for (int rep = 0; rep < N; rep++) { + // ========================================================= + data_.clear(); + resolution_ = gridMap.getResolution(); + position_ = gridMap.getPosition(); + size_ = gridMap.getSize(); + Matrix map = gridMap.get(layer); // Copy! + + float minHeight = map.minCoeffOfFinites(); + if (!std::isfinite(minHeight)) minHeight = lowestHeight_; + float maxHeight = map.maxCoeffOfFinites(); + if (!std::isfinite(maxHeight)) maxHeight = lowestHeight_; + + const float valueForEmptyCells = lowestHeight_; // maxHeight, minHeight (TODO Make this an option). + for (size_t i = 0; i < map.size(); ++i) { + if (std::isnan(map(i))) map(i) = valueForEmptyCells; + } + + // Height range of the signed distance field is higher than the max height. + maxHeight += heightClearance; + + Matrix sdfElevationAbove = Matrix::Ones(map.rows(), map.cols()) * maxDistance_; + Matrix sdfLayer = Matrix::Zero(map.rows(), map.cols()); + + zIndexStartHeight_ = minHeight; + + // Calculate signed distance field from bottom. + Eigen::Matrix obstacleFreeField; + Eigen::Matrix obstacleField; + for (float h = minHeight; h < maxHeight; h += resolution_) { + Matrix sdf2d = signed_distance_field::computeSignedDistanceAtHeight(map, h, resolution_); + + for (size_t i = 0; i < sdfElevationAbove.size(); ++i) { + if (map(i) <= h) { + if (sdfElevationAbove(i) == maxDistance_) { + sdfElevationAbove(i) = h - map(i); + } else { + sdfElevationAbove(i) = sdfLayer(i) + resolution_; + } + } + + if (sdf2d(i) == 0) { + sdfLayer(i) = h - map(i); + } else if (sdf2d(i) < 0) { + sdfLayer(i) = -std::min(fabs(sdf2d(i)), fabs(map(i) - h)); + } else { + sdfLayer(i) = std::min(sdf2d(i), sdfElevationAbove(i)); + } + } + data_.push_back(sdfLayer); + } + + // ========================================================= + } + auto t3 = std::chrono::high_resolution_clock::now(); + std::cout << "Sdf computation took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() / N << " [ms]\n"; +} \ No newline at end of file diff --git a/signed_distance_field/CMakeLists.txt b/signed_distance_field/CMakeLists.txt new file mode 100644 index 00000000..252d1bf2 --- /dev/null +++ b/signed_distance_field/CMakeLists.txt @@ -0,0 +1,72 @@ +cmake_minimum_required(VERSION 3.10) +project(signed_distance_field) + +# Catkin dependencies +set(CATKIN_PACKAGE_DEPENDENCIES + grid_map_core +) + +find_package(catkin REQUIRED COMPONENTS + ${CATKIN_PACKAGE_DEPENDENCIES} +) + +# Cpp standard version +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +################################### +## catkin specific configuration ## +################################### +catkin_package( + INCLUDE_DIRS include + LIBRARIES ${PROJECT_NAME} + CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} + DEPENDS +) + +########### +## Build ## +########### + +include_directories( + include + ${catkin_INCLUDE_DIRS} +) + +add_library(${PROJECT_NAME} + src/SignedDistanceField.cpp + src/SignedDistance2d.cpp + ) +add_dependencies(${PROJECT_NAME} + ${catkin_EXPORTED_TARGETS} + ) +target_link_libraries(${PROJECT_NAME} + ${catkin_LIBRARIES} + ) + + +############# +## Install ## +############# + +install(TARGETS ${PROJECT_NAME} + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} + ) +install(DIRECTORY include/${PROJECT_NAME}/ + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} + ) + +############# +## Testing ## +############# + +add_executable(${PROJECT_NAME}_test + test/testSignedDistance2d.cpp + ) +target_link_libraries(${PROJECT_NAME}_test + ${catkin_LIBRARIES} + ${PROJECT_NAME} + gtest_main + ) \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h new file mode 100644 index 00000000..89edb3a7 --- /dev/null +++ b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h @@ -0,0 +1,28 @@ +// +// Created by rgrandia on 10.07.20. +// + +#pragma once + +#include + +#include + +#include "Utils.h" + +namespace signed_distance_field { + +struct SparsityInfo { + bool hasObstacles; + bool hasFreeSpace; + std::vector rowsIsHomogenous; + std::vector colsIsHomogenous; + int numRowsHomogeneous; + int numColsHomogeneous; +}; + +SparsityInfo collectSparsityInfo(const grid_map::Matrix& elevationMap, float height); + +grid_map::Matrix computeSignedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution); + +} \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/Utils.h b/signed_distance_field/include/signed_distance_field/Utils.h new file mode 100644 index 00000000..37c437e4 --- /dev/null +++ b/signed_distance_field/include/signed_distance_field/Utils.h @@ -0,0 +1,12 @@ +// +// Created by rgrandia on 10.07.20. +// + +#pragma once + + +namespace signed_distance_field { + +constexpr float INF = 1e15; // maximum well below numeric_limits::max + +} \ No newline at end of file diff --git a/signed_distance_field/package.xml b/signed_distance_field/package.xml new file mode 100644 index 00000000..e27f28e4 --- /dev/null +++ b/signed_distance_field/package.xml @@ -0,0 +1,15 @@ + + + signed_distance_field + 0.0.0 + The signed_distance_field package + + Ruben Grandia + + TODO + + catkin + + grid_map_core + + diff --git a/signed_distance_field/src/SignedDistance2d.cpp b/signed_distance_field/src/SignedDistance2d.cpp new file mode 100644 index 00000000..113d7dc2 --- /dev/null +++ b/signed_distance_field/src/SignedDistance2d.cpp @@ -0,0 +1,177 @@ +// +// Created by rgrandia on 10.07.20. +// + +#include "signed_distance_field/SignedDistance2d.h" + +namespace signed_distance_field { + +namespace internal { +template +T square(T x) { + return x * x; +} + +/** + * 1D Euclidean Distance Transform based on: http://cs.brown.edu/people/pfelzens/dt/ + * Adapted to work on Eigen objects directly + * Optimized computation of s + */ +void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDistance1d, Eigen::Ref d, + Eigen::Ref z, std::vector& v) { + const int n = squareDistance1d.size(); + const auto& f = squareDistance1d; + assert(d.size() == n); + assert(z.size() == n + 1); + assert(v.size() == n); + + // Initialize + int k = 0; + v[0] = 0; + z[0] = -INF; + z[1] = INF; + + // Compute bounds + for (int q = 1; q < n; q++) { + auto factor1 = static_cast(q - v[k]); + auto factor2 = static_cast(q + v[k]); + float s = 0.5F * ((f[q] - f[v[k]]) / factor1 + factor2); + while (s <= z[k]) { + k--; + factor1 = static_cast(q - v[k]); + factor2 = static_cast(q + v[k]); + s = 0.5F * ((f[q] - f[v[k]]) / factor1 + factor2); + } + k++; + v[k] = q; + z[k] = s; + z[k + 1] = INF; + } + + // Collect results + k = 0; + for (int q = 0; q < n; q++) { + while (z[k + 1] < static_cast(q)) { + k++; + } + d[q] = square(q - v[k]) + f[v[k]]; + } + + // Write distance result back in place + squareDistance1d = d; +} + +void squaredDistanceTransform_2d_columnwiseInplace(grid_map::Matrix& squareDistance, const std::vector* skipLine = nullptr) { + const size_t n = squareDistance.rows(); + const size_t m = squareDistance.cols(); + Eigen::VectorXf workvector(2 * n + 1); + std::vector intWorkvector(n); + + for (size_t i = 0; i < m; i++) { + if (skipLine == nullptr || !(*skipLine)[i]) { + squaredDistanceTransform_1d_inplace(squareDistance.col(i), workvector.segment(0, n), workvector.segment(n, n + 1), intWorkvector); + } + } +} + +// SquareDistance must be initialized with 0.0 for elements and INF for non-elements +void computePixelDistance2d(grid_map::Matrix& squareDistance, const SparsityInfo& sparsityInfo) { + // Start with the dimension that maximizes the number of points being skips + if (sparsityInfo.numColsHomogeneous * squareDistance.rows() > sparsityInfo.numRowsHomogeneous * squareDistance.cols()) { + // Process columns + squaredDistanceTransform_2d_columnwiseInplace(squareDistance, &sparsityInfo.colsIsHomogenous); + + // Process rows + squareDistance.transposeInPlace(); + squaredDistanceTransform_2d_columnwiseInplace(squareDistance); + squareDistance.transposeInPlace(); + } else { + // Process rows + squareDistance.transposeInPlace(); + squaredDistanceTransform_2d_columnwiseInplace(squareDistance, &sparsityInfo.rowsIsHomogenous); + squareDistance.transposeInPlace(); + + // Process columns + squaredDistanceTransform_2d_columnwiseInplace(squareDistance); + } + + // Convert square distance to absolute distance + squareDistance = squareDistance.cwiseSqrt(); +} +} // namespace internal + +grid_map::Matrix computeSignedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution) { + const auto sparsityInfo = signed_distance_field::collectSparsityInfo(elevationMap, height); + + if (sparsityInfo.hasObstacles) { + if (sparsityInfo.hasFreeSpace) { + // Both obstacles and free space -> compute planar signed distance + // Compute pixel distance to obstacles + grid_map::Matrix sdfObstacle = elevationMap.unaryExpr([=](float val) { return (val >= height) ? 0.0F : INF; }); + internal::computePixelDistance2d(sdfObstacle, sparsityInfo); + + // Compute pixel distance to obstacle free space + grid_map::Matrix sdfObstacleFree = elevationMap.unaryExpr([=](float val) { return (val < height) ? 0.0F : INF; }); + internal::computePixelDistance2d(sdfObstacleFree, sparsityInfo); + + grid_map::Matrix sdf2d = resolution * (sdfObstacle - sdfObstacleFree); + return sdf2d; + } else { + // Only obstacles -> distance is zero everywhere + return grid_map::Matrix::Zero(elevationMap.rows(), elevationMap.cols()); + } + } else { + // No obstacles -> planar distance is infinite + return grid_map::Matrix::Constant(elevationMap.rows(), elevationMap.cols(), INF); + } +} + +SparsityInfo collectSparsityInfo(const grid_map::Matrix& elevationMap, float height) { + const size_t n = elevationMap.rows(); + const size_t m = elevationMap.cols(); + + SparsityInfo sparsityInfo; + // Assume false and set true if detected otherwise + sparsityInfo.hasObstacles = false; + sparsityInfo.hasFreeSpace = false; + + // Assume true and set false if detected otherwise + sparsityInfo.rowsIsHomogenous.resize(elevationMap.rows(), true); + sparsityInfo.colsIsHomogenous.resize(elevationMap.cols(), true); + + Eigen::Matrix firstColIsObstacle = elevationMap.col(0).array() >= height; + + // Loop according to Eigen column major storage order. + for (size_t j = 0; j < m; ++j) { + bool firstRowIsObstacle = elevationMap(0, j) >= height; + bool thisColIsHomogeneous = true; + for (size_t i = 0; i < n; ++i) { + float currentValue = elevationMap(i, j); + if (currentValue >= height) { // current location contains obstacle + sparsityInfo.hasObstacles = true; + if (!firstRowIsObstacle) { + thisColIsHomogeneous = false; + } + if (!firstColIsObstacle(i)) { + sparsityInfo.rowsIsHomogenous[i] = false; + } + } else { // current location is free + sparsityInfo.hasFreeSpace = true; + if (firstRowIsObstacle) { + thisColIsHomogeneous = false; + } + if (firstColIsObstacle(i)) { + sparsityInfo.rowsIsHomogenous[i] = false; + } + } + } + sparsityInfo.colsIsHomogenous[j] = thisColIsHomogeneous; + } + + sparsityInfo.numRowsHomogeneous = std::count(sparsityInfo.rowsIsHomogenous.begin(), sparsityInfo.rowsIsHomogenous.end(), true); + sparsityInfo.numColsHomogeneous = std::count(sparsityInfo.colsIsHomogenous.begin(), sparsityInfo.colsIsHomogenous.end(), true); + + return sparsityInfo; +} + +} // namespace signed_distance_field diff --git a/signed_distance_field/src/SignedDistanceField.cpp b/signed_distance_field/src/SignedDistanceField.cpp new file mode 100644 index 00000000..3fe2c783 --- /dev/null +++ b/signed_distance_field/src/SignedDistanceField.cpp @@ -0,0 +1,7 @@ +// +// Created by rgrandia on 10.07.20. +// + +#include "signed_distance_field/SignedDistanceField.h" + +#include "signed_distance_field/SignedDistance2d.h" \ No newline at end of file diff --git a/signed_distance_field/test/testSignedDistance2d.cpp b/signed_distance_field/test/testSignedDistance2d.cpp new file mode 100644 index 00000000..2cd2d3d5 --- /dev/null +++ b/signed_distance_field/test/testSignedDistance2d.cpp @@ -0,0 +1,161 @@ +// +// Created by rgrandia on 10.07.20. +// + +#include + +#include "signed_distance_field/SignedDistance2d.h" + +namespace signed_distance_field { + +// N^2 naive implementation, for testing purposes +grid_map::Matrix naiveSignedDistance(const grid_map::Matrix& elevationMap, float height, float resolution) { + grid_map::Matrix signedDistance(elevationMap.rows(), elevationMap.cols()); + + // For each point + for (int row = 0; row < elevationMap.rows(); ++row) { + for (int col = 0; col < elevationMap.cols(); ++col) { + if (elevationMap(row, col) >= height) { + signedDistance(row, col) = -INF; + // find closest open space over all other points + for (int i = 0; i < elevationMap.rows(); ++i) { + for (int j = 0; j < elevationMap.cols(); ++j) { + if (elevationMap(i, j) < height) { + float dx = resolution * (i - row); + float dy = resolution * (j - col); + float currentSignedDistance = -std::sqrt(dx * dx + dy * dy); + signedDistance(row, col) = std::max(signedDistance(row, col), currentSignedDistance); + } + } + } + } else { + signedDistance(row, col) = INF; + // find closest object over all other points + for (int i = 0; i < elevationMap.rows(); ++i) { + for (int j = 0; j < elevationMap.cols(); ++j) { + if (elevationMap(i, j) >= height) { + float dx = resolution * (i - row); + float dy = resolution * (j - col); + float currentSignedDistance = std::sqrt(dx * dx + dy * dy); + signedDistance(row, col) = std::min(signedDistance(row, col), currentSignedDistance); + } + } + } + } + } + } + + return signedDistance; +} +} // namespace signed_distance_field + +TEST(testSignedDistance2d, sparsityInfo_noObstacles) { + const int n = 3; + const int m = 4; + const grid_map::Matrix map = grid_map::Matrix::Ones(n, m); + + const auto sparsityInfo = signed_distance_field::collectSparsityInfo(map, 2.0); + + ASSERT_TRUE(sparsityInfo.hasFreeSpace); + ASSERT_FALSE(sparsityInfo.hasObstacles); + ASSERT_EQ(sparsityInfo.numColsHomogeneous, m); + ASSERT_EQ(sparsityInfo.numRowsHomogeneous, n); +} + +TEST(testSignedDistance2d, sparsityInfo_allObstacles) { + const int n = 3; + const int m = 4; + const grid_map::Matrix map = grid_map::Matrix::Ones(n, m); + + const auto sparsityInfo = signed_distance_field::collectSparsityInfo(map, 0.0); + + ASSERT_FALSE(sparsityInfo.hasFreeSpace); + ASSERT_TRUE(sparsityInfo.hasObstacles); + ASSERT_EQ(sparsityInfo.numColsHomogeneous, m); + ASSERT_EQ(sparsityInfo.numRowsHomogeneous, n); +} + +TEST(testSignedDistance2d, sparsityInfo_mixed) { + const int n = 2; + const int m = 3; + grid_map::Matrix map(n, m); + map << 0.0, 1.0, 1.0, 0.0, 0.0, 0.0; + + const auto sparsityInfo = signed_distance_field::collectSparsityInfo(map, 0.5); + + ASSERT_TRUE(sparsityInfo.hasFreeSpace); + ASSERT_TRUE(sparsityInfo.hasObstacles); + ASSERT_TRUE(sparsityInfo.colsIsHomogenous[0]); + ASSERT_TRUE(sparsityInfo.rowsIsHomogenous[1]); + ASSERT_EQ(sparsityInfo.numColsHomogeneous, 1); + ASSERT_EQ(sparsityInfo.numRowsHomogeneous, 1); +} + +TEST(testSignedDistance2d, signedDistance2d_noObstacles) { + const int n = 3; + const int m = 4; + const float resolution = 0.1; + const grid_map::Matrix map = grid_map::Matrix::Ones(n, m); + + const auto signedDistance = signed_distance_field::computeSignedDistanceAtHeight(map, 2.0, resolution); + + ASSERT_TRUE((signedDistance.array() == signed_distance_field::INF).all()); +} + +TEST(testSignedDistance2d, signedDistance2d_allObstacles) { + const int n = 3; + const int m = 4; + const float resolution = 0.1; + const grid_map::Matrix map = grid_map::Matrix::Ones(n, m); + + const auto signedDistance = signed_distance_field::computeSignedDistanceAtHeight(map, 0.0, resolution); + + ASSERT_TRUE((signedDistance.array() == 0.0).all()); +} + +TEST(testSignedDistance2d, signedDistance2d_mixed) { + const int n = 2; + const int m = 3; + const float resolution = 0.1; + grid_map::Matrix map(n, m); + map << 0.0, 1.0, 1.0, 0.0, 0.0, 0.0; + + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistance(map, 0.5, resolution); + const auto signedDistance = signed_distance_field::computeSignedDistanceAtHeight(map, 0.5, resolution); + ASSERT_TRUE(signedDistance.isApprox(naiveSignedDistance)); +} + +TEST(testSignedDistance2d, signedDistance2d_oneObstacle) { + const int n = 20; + const int m = 30; + const float resolution = 0.1; + grid_map::Matrix map = grid_map::Matrix::Zero(n, m); + map(n/2, m/2) = 1.0; + + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistance(map, 0.5, resolution); + const auto signedDistance = signed_distance_field::computeSignedDistanceAtHeight(map, 0.5, resolution); + ASSERT_TRUE(signedDistance.isApprox(naiveSignedDistance)); +} + +TEST(testSignedDistance2d, signedDistance2d_oneFreeSpace) { + const int n = 20; + const int m = 30; + const float resolution = 0.1; + grid_map::Matrix map = grid_map::Matrix::Ones(n, m); + map(n/2, m/2) = 0.0; + + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistance(map, 0.5, resolution); + const auto signedDistance = signed_distance_field::computeSignedDistanceAtHeight(map, 0.5, resolution); + ASSERT_TRUE(signedDistance.isApprox(naiveSignedDistance)); +} + +TEST(testSignedDistance2d, signedDistance2d_random) { + const int n = 20; + const int m = 30; + const float resolution = 0.1; + grid_map::Matrix map = grid_map::Matrix::Random(n, m); // random [-1.0, 1.0] + + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistance(map, 0.0, resolution); + const auto signedDistance = signed_distance_field::computeSignedDistanceAtHeight(map, 0.0, resolution); + ASSERT_TRUE(signedDistance.isApprox(naiveSignedDistance)); +} \ No newline at end of file From ebb7f7f9f5f9ca5b34bfefca9c8b5f09e3cec102 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 5 Aug 2020 11:15:47 +0200 Subject: [PATCH 061/504] add file --- .../signed_distance_field/SignedDistanceField.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 signed_distance_field/include/signed_distance_field/SignedDistanceField.h diff --git a/signed_distance_field/include/signed_distance_field/SignedDistanceField.h b/signed_distance_field/include/signed_distance_field/SignedDistanceField.h new file mode 100644 index 00000000..18756fa6 --- /dev/null +++ b/signed_distance_field/include/signed_distance_field/SignedDistanceField.h @@ -0,0 +1,12 @@ +// +// Created by rgrandia on 10.07.20. +// + +#pragma once + +namespace signed_distance_field { + +class SignedDistanceField {}; + +} + From b27d6121018df16a039d25845029ffef62e2c8a1 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 10 Aug 2020 13:32:21 +0200 Subject: [PATCH 062/504] 3d signed distance working and tested --- .../test/signedDistanceTest.cpp | 30 +-- signed_distance_field/CMakeLists.txt | 3 + .../PixelBorderDistance.h | 38 ++++ .../signed_distance_field/SignedDistance2d.h | 18 +- .../SignedDistanceField.h | 23 ++- .../src/PixelBorderDistance.cpp | 52 ++++++ .../src/SignedDistance2d.cpp | 175 ++++++++---------- .../test/naiveSignedDistance.h | 93 ++++++++++ .../test/testPixelBorderDistance.cpp | 50 +++++ .../test/testSignedDistance2d.cpp | 151 +++++---------- .../test/testSignedDistance3d.cpp | 44 +++++ 11 files changed, 439 insertions(+), 238 deletions(-) create mode 100644 signed_distance_field/include/signed_distance_field/PixelBorderDistance.h create mode 100644 signed_distance_field/src/PixelBorderDistance.cpp create mode 100644 signed_distance_field/test/naiveSignedDistance.h create mode 100644 signed_distance_field/test/testPixelBorderDistance.cpp create mode 100644 signed_distance_field/test/testSignedDistance3d.cpp diff --git a/segmented_planes_terrain_model/test/signedDistanceTest.cpp b/segmented_planes_terrain_model/test/signedDistanceTest.cpp index d288977b..64e17157 100644 --- a/segmented_planes_terrain_model/test/signedDistanceTest.cpp +++ b/segmented_planes_terrain_model/test/signedDistanceTest.cpp @@ -201,7 +201,7 @@ int main(int argc, char** argv) { using grid_map::Matrix; auto t2 = std::chrono::high_resolution_clock::now(); - const int N = 30; + const int N = 300; for (int rep = 0; rep < N; rep++) { // ========================================================= data_.clear(); @@ -223,35 +223,9 @@ int main(int argc, char** argv) { // Height range of the signed distance field is higher than the max height. maxHeight += heightClearance; - Matrix sdfElevationAbove = Matrix::Ones(map.rows(), map.cols()) * maxDistance_; - Matrix sdfLayer = Matrix::Zero(map.rows(), map.cols()); - - zIndexStartHeight_ = minHeight; - // Calculate signed distance field from bottom. - Eigen::Matrix obstacleFreeField; - Eigen::Matrix obstacleField; for (float h = minHeight; h < maxHeight; h += resolution_) { - Matrix sdf2d = signed_distance_field::computeSignedDistanceAtHeight(map, h, resolution_); - - for (size_t i = 0; i < sdfElevationAbove.size(); ++i) { - if (map(i) <= h) { - if (sdfElevationAbove(i) == maxDistance_) { - sdfElevationAbove(i) = h - map(i); - } else { - sdfElevationAbove(i) = sdfLayer(i) + resolution_; - } - } - - if (sdf2d(i) == 0) { - sdfLayer(i) = h - map(i); - } else if (sdf2d(i) < 0) { - sdfLayer(i) = -std::min(fabs(sdf2d(i)), fabs(map(i) - h)); - } else { - sdfLayer(i) = std::min(sdf2d(i), sdfElevationAbove(i)); - } - } - data_.push_back(sdfLayer); + data_.emplace_back(signed_distance_field::signedDistanceAtHeight(map, h, resolution)); } // ========================================================= diff --git a/signed_distance_field/CMakeLists.txt b/signed_distance_field/CMakeLists.txt index 252d1bf2..458c8dc3 100644 --- a/signed_distance_field/CMakeLists.txt +++ b/signed_distance_field/CMakeLists.txt @@ -34,6 +34,7 @@ include_directories( ) add_library(${PROJECT_NAME} + src/PixelBorderDistance.cpp src/SignedDistanceField.cpp src/SignedDistance2d.cpp ) @@ -63,7 +64,9 @@ install(DIRECTORY include/${PROJECT_NAME}/ ############# add_executable(${PROJECT_NAME}_test + test/testPixelBorderDistance.cpp test/testSignedDistance2d.cpp + test/testSignedDistance3d.cpp ) target_link_libraries(${PROJECT_NAME}_test ${catkin_LIBRARIES} diff --git a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h new file mode 100644 index 00000000..394753d3 --- /dev/null +++ b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h @@ -0,0 +1,38 @@ +// +// Created by rgrandia on 07.08.20. +// + +#pragma once + +#include + +namespace signed_distance_field { + +/** + * Returns distance between the center of a pixel and the border of an other pixel. + * Returns zero if the center is inside the other pixel. + * Pixels are assumed to have size 1.0F + * @param i : location of pixel 1 + * @param j : location of pixel 2 + * @return : absolute distance between center of pixel 1 and the border of pixel 2 + */ +inline float pixelBorderDistance(float i, float j) { + return std::max(std::abs(i-j) - 0.5F, 0.0F); +} + +/** + * Returns square pixelBorderDistance, adding offset f. + */ +inline float squarePixelBorderDistance(float i, float j, float f) { + float distance = pixelBorderDistance(i, j); + return distance * distance + f; +} + +/** + * Return the point s in pixel space that is equally far from p and q (taking into account offsets fp, and fq) + * It is the solution to the following equation: + * squarePixelBorderDistance(s, q, fq) == squarePixelBorderDistance(s, p, fp) + */ +float equidistancePoint(int q, float fq, int p, float fp); + +} // namespace signed_distance_field diff --git a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h index 89edb3a7..fe5b5ea3 100644 --- a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h +++ b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h @@ -12,17 +12,13 @@ namespace signed_distance_field { -struct SparsityInfo { - bool hasObstacles; - bool hasFreeSpace; - std::vector rowsIsHomogenous; - std::vector colsIsHomogenous; - int numRowsHomogeneous; - int numColsHomogeneous; -}; +inline Eigen::Matrix occupancyAtHeight(const grid_map::Matrix& elevationMap, float height) { + Eigen::Matrix occupany = elevationMap.unaryExpr([=](float val) { return val > height; }); + return occupany; +} -SparsityInfo collectSparsityInfo(const grid_map::Matrix& elevationMap, float height); +grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution); -grid_map::Matrix computeSignedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution); +grid_map::Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution); -} \ No newline at end of file +} // namespace signed_distance_field \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/SignedDistanceField.h b/signed_distance_field/include/signed_distance_field/SignedDistanceField.h index 18756fa6..c6e1b9d9 100644 --- a/signed_distance_field/include/signed_distance_field/SignedDistanceField.h +++ b/signed_distance_field/include/signed_distance_field/SignedDistanceField.h @@ -4,9 +4,28 @@ #pragma once +#include + +#include + namespace signed_distance_field { -class SignedDistanceField {}; +class SignedDistanceField { + public: + double atPosition(const Eigen::Vector3d& position) const; + Eigen::Vector3d derivativeAtPosition(const Eigen::Vector3d& position) const; + + private: + size_t nearestNode(const Eigen::Vector3d& position) const; + Eigen::Vector3d nodePosition(const Eigen::Vector3d& position) const; + + using node_data_t = std::array; + static double distance(const node_data_t& nodeData) noexcept { return nodeData[0]; } + static Eigen::Vector3d derivative(const node_data_t& nodeData) noexcept { return {nodeData[1], nodeData[2], nodeData[3]}; } -} + double resolution_; + std::array gridsize_; + std::vector data_; +}; +} // namespace signed_distance_field diff --git a/signed_distance_field/src/PixelBorderDistance.cpp b/signed_distance_field/src/PixelBorderDistance.cpp new file mode 100644 index 00000000..51d71d75 --- /dev/null +++ b/signed_distance_field/src/PixelBorderDistance.cpp @@ -0,0 +1,52 @@ +// +// Created by rgrandia on 07.08.20. +// + +#include "signed_distance_field/PixelBorderDistance.h" + +#include + +namespace signed_distance_field { + +namespace internal { + +/** + * Return equidistancepoint between origin and pixel p (with p > 0) with offset fp + */ +inline float intersectionPointRightSideOfOrigin(int p, float fp) { + auto pFloat = static_cast(p); + auto pSquared = pFloat * pFloat; + auto fpAbs = std::abs(fp); + if (fpAbs >= pSquared) { + float s = (pSquared + fp) / (2.0F * pFloat); + return (fp > 0.0F) ? s + 0.5F : s - 0.5F; + } else { + float boundary = (pSquared - 2 * pFloat + 1); + if (fpAbs < boundary) { + return (pSquared - pFloat + fp) / (2.0F * pFloat - 2.0F); + } else { + float s = 0.5F + std::sqrt(fpAbs); + return (fp > 0.0F) ? s : pFloat - s; + } + } +} + +/** + * Return equidistancepoint between origin and pixel p with offset fp + */ +inline float intersectionOffsetFromOrigin(int p, float fp) { + float intersectionOffset = intersectionPointRightSideOfOrigin(std::abs(p), fp); + return (p > 0) ? intersectionOffset : -intersectionOffset; +} + +} // namespace internal + +float equidistancePoint(int q, float fq, int p, float fp) { + if (q != p) { + return internal::intersectionOffsetFromOrigin(p - q, fp - fq) + static_cast(q); + } else { + return static_cast(q); + } +} + +} \ No newline at end of file diff --git a/signed_distance_field/src/SignedDistance2d.cpp b/signed_distance_field/src/SignedDistance2d.cpp index 113d7dc2..46ea838e 100644 --- a/signed_distance_field/src/SignedDistance2d.cpp +++ b/signed_distance_field/src/SignedDistance2d.cpp @@ -4,14 +4,11 @@ #include "signed_distance_field/SignedDistance2d.h" +#include "signed_distance_field/PixelBorderDistance.h" + namespace signed_distance_field { namespace internal { -template -T square(T x) { - return x * x; -} - /** * 1D Euclidean Distance Transform based on: http://cs.brown.edu/people/pfelzens/dt/ * Adapted to work on Eigen objects directly @@ -33,14 +30,10 @@ void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDista // Compute bounds for (int q = 1; q < n; q++) { - auto factor1 = static_cast(q - v[k]); - auto factor2 = static_cast(q + v[k]); - float s = 0.5F * ((f[q] - f[v[k]]) / factor1 + factor2); + float s = equidistancePoint(q, f[q], v[k], f[v[k]]); while (s <= z[k]) { k--; - factor1 = static_cast(q - v[k]); - factor2 = static_cast(q + v[k]); - s = 0.5F * ((f[q] - f[v[k]]) / factor1 + factor2); + s = equidistancePoint(q, f[q], v[k], f[v[k]]); } k++; v[k] = q; @@ -51,127 +44,119 @@ void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDista // Collect results k = 0; for (int q = 0; q < n; q++) { - while (z[k + 1] < static_cast(q)) { + auto qFloat = static_cast(q); + while (z[k + 1] < qFloat) { k++; } - d[q] = square(q - v[k]) + f[v[k]]; + d[q] = squarePixelBorderDistance(qFloat, v[k], f[v[k]]); } // Write distance result back in place squareDistance1d = d; } -void squaredDistanceTransform_2d_columnwiseInplace(grid_map::Matrix& squareDistance, const std::vector* skipLine = nullptr) { +void squaredDistanceTransform_2d_columnwiseInplace(grid_map::Matrix& squareDistance) { const size_t n = squareDistance.rows(); const size_t m = squareDistance.cols(); Eigen::VectorXf workvector(2 * n + 1); std::vector intWorkvector(n); for (size_t i = 0; i < m; i++) { - if (skipLine == nullptr || !(*skipLine)[i]) { - squaredDistanceTransform_1d_inplace(squareDistance.col(i), workvector.segment(0, n), workvector.segment(n, n + 1), intWorkvector); - } + squaredDistanceTransform_1d_inplace(squareDistance.col(i), workvector.segment(0, n), workvector.segment(n, n + 1), intWorkvector); } } // SquareDistance must be initialized with 0.0 for elements and INF for non-elements -void computePixelDistance2d(grid_map::Matrix& squareDistance, const SparsityInfo& sparsityInfo) { - // Start with the dimension that maximizes the number of points being skips - if (sparsityInfo.numColsHomogeneous * squareDistance.rows() > sparsityInfo.numRowsHomogeneous * squareDistance.cols()) { - // Process columns - squaredDistanceTransform_2d_columnwiseInplace(squareDistance, &sparsityInfo.colsIsHomogenous); - - // Process rows - squareDistance.transposeInPlace(); - squaredDistanceTransform_2d_columnwiseInplace(squareDistance); - squareDistance.transposeInPlace(); - } else { - // Process rows - squareDistance.transposeInPlace(); - squaredDistanceTransform_2d_columnwiseInplace(squareDistance, &sparsityInfo.rowsIsHomogenous); - squareDistance.transposeInPlace(); +void computePixelDistance2d(grid_map::Matrix& squareDistance) { + // Process columns + squaredDistanceTransform_2d_columnwiseInplace(squareDistance); - // Process columns - squaredDistanceTransform_2d_columnwiseInplace(squareDistance); - } + // Process rows + squareDistance.transposeInPlace(); + squaredDistanceTransform_2d_columnwiseInplace(squareDistance); + squareDistance.transposeInPlace(); // Convert square distance to absolute distance squareDistance = squareDistance.cwiseSqrt(); } + +// Initialize with square distance in height direction in pixel units if above the surface +grid_map::Matrix initializeObstacleDistance(const grid_map::Matrix& elevationMap, float height, float resolution) { + return elevationMap.unaryExpr([=](float elevation) { + if (height > elevation) { + const auto diff = (height - elevation) / resolution; + return diff * diff; + } else { + return 0.0F; + } + }); +} + +// Initialize with square distance in height direction in pixel units if below the surface +grid_map::Matrix initializeObstacleFreeDistance(const grid_map::Matrix& elevationMap, float height, float resolution) { + return elevationMap.unaryExpr([=](float elevation) { + if (height < elevation) { + const auto diff = (height - elevation) / resolution; + return diff * diff; + } else { + return 0.0F; + } + }); +} + +grid_map::Matrix pixelDistanceToFreeSpace(const grid_map::Matrix& elevationMap, float height, float resolution) { + grid_map::Matrix sdfObstacleFree = internal::initializeObstacleFreeDistance(elevationMap, height, resolution); + internal::computePixelDistance2d(sdfObstacleFree); + return sdfObstacleFree; +} + +grid_map::Matrix pixelDistanceToObstacle(const grid_map::Matrix& elevationMap, float height, float resolution) { + grid_map::Matrix sdfObstacle = internal::initializeObstacleDistance(elevationMap, height, resolution); + internal::computePixelDistance2d(sdfObstacle); + return sdfObstacle; +} + } // namespace internal -grid_map::Matrix computeSignedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution) { - const auto sparsityInfo = signed_distance_field::collectSparsityInfo(elevationMap, height); +grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution) { + auto obstacleCount = (elevationMap.array() > height).count(); + bool allPixelsAreObstacles = obstacleCount == elevationMap.size(); + bool allPixelsAreFreeSpace = obstacleCount == 0; + + if (allPixelsAreObstacles) { + return -resolution * internal::pixelDistanceToFreeSpace(elevationMap, height, resolution); + } else if (allPixelsAreFreeSpace) { + return resolution * internal::pixelDistanceToObstacle(elevationMap, height, resolution); + } else { // This layer contains a mix of obstacles and free space + return resolution * (internal::pixelDistanceToObstacle(elevationMap, height, resolution) - + internal::pixelDistanceToFreeSpace(elevationMap, height, resolution)); + } +} - if (sparsityInfo.hasObstacles) { - if (sparsityInfo.hasFreeSpace) { - // Both obstacles and free space -> compute planar signed distance +grid_map::Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution) { + auto obstacleCount = occupancyGrid.count(); + bool hasObstacles = obstacleCount > 0; + if (hasObstacles){ + bool hasFreeSpace = obstacleCount < occupancyGrid.size(); + if (hasFreeSpace){ // Compute pixel distance to obstacles - grid_map::Matrix sdfObstacle = elevationMap.unaryExpr([=](float val) { return (val >= height) ? 0.0F : INF; }); - internal::computePixelDistance2d(sdfObstacle, sparsityInfo); + grid_map::Matrix sdfObstacle = occupancyGrid.unaryExpr([=](bool val) { return (val) ? 0.0F : INF; }); + internal::computePixelDistance2d(sdfObstacle); // Compute pixel distance to obstacle free space - grid_map::Matrix sdfObstacleFree = elevationMap.unaryExpr([=](float val) { return (val < height) ? 0.0F : INF; }); - internal::computePixelDistance2d(sdfObstacleFree, sparsityInfo); + grid_map::Matrix sdfObstacleFree = occupancyGrid.unaryExpr([=](bool val) { return (val) ? INF : 0.0F; }); + internal::computePixelDistance2d(sdfObstacleFree); grid_map::Matrix sdf2d = resolution * (sdfObstacle - sdfObstacleFree); return sdf2d; } else { - // Only obstacles -> distance is zero everywhere - return grid_map::Matrix::Zero(elevationMap.rows(), elevationMap.cols()); + // Only obstacles -> distance is minus infinity everywhere + return grid_map::Matrix::Constant(occupancyGrid.rows(), occupancyGrid.cols(), -INF); } } else { // No obstacles -> planar distance is infinite - return grid_map::Matrix::Constant(elevationMap.rows(), elevationMap.cols(), INF); + return grid_map::Matrix::Constant(occupancyGrid.rows(), occupancyGrid.cols(), INF); } } -SparsityInfo collectSparsityInfo(const grid_map::Matrix& elevationMap, float height) { - const size_t n = elevationMap.rows(); - const size_t m = elevationMap.cols(); - - SparsityInfo sparsityInfo; - // Assume false and set true if detected otherwise - sparsityInfo.hasObstacles = false; - sparsityInfo.hasFreeSpace = false; - - // Assume true and set false if detected otherwise - sparsityInfo.rowsIsHomogenous.resize(elevationMap.rows(), true); - sparsityInfo.colsIsHomogenous.resize(elevationMap.cols(), true); - - Eigen::Matrix firstColIsObstacle = elevationMap.col(0).array() >= height; - - // Loop according to Eigen column major storage order. - for (size_t j = 0; j < m; ++j) { - bool firstRowIsObstacle = elevationMap(0, j) >= height; - bool thisColIsHomogeneous = true; - for (size_t i = 0; i < n; ++i) { - float currentValue = elevationMap(i, j); - if (currentValue >= height) { // current location contains obstacle - sparsityInfo.hasObstacles = true; - if (!firstRowIsObstacle) { - thisColIsHomogeneous = false; - } - if (!firstColIsObstacle(i)) { - sparsityInfo.rowsIsHomogenous[i] = false; - } - } else { // current location is free - sparsityInfo.hasFreeSpace = true; - if (firstRowIsObstacle) { - thisColIsHomogeneous = false; - } - if (firstColIsObstacle(i)) { - sparsityInfo.rowsIsHomogenous[i] = false; - } - } - } - sparsityInfo.colsIsHomogenous[j] = thisColIsHomogeneous; - } - - sparsityInfo.numRowsHomogeneous = std::count(sparsityInfo.rowsIsHomogenous.begin(), sparsityInfo.rowsIsHomogenous.end(), true); - sparsityInfo.numColsHomogeneous = std::count(sparsityInfo.colsIsHomogenous.begin(), sparsityInfo.colsIsHomogenous.end(), true); - - return sparsityInfo; -} - } // namespace signed_distance_field diff --git a/signed_distance_field/test/naiveSignedDistance.h b/signed_distance_field/test/naiveSignedDistance.h new file mode 100644 index 00000000..622cd240 --- /dev/null +++ b/signed_distance_field/test/naiveSignedDistance.h @@ -0,0 +1,93 @@ +// +// Created by rgrandia on 10.08.20. +// + +#pragma once + +namespace signed_distance_field { + +inline bool isEqualSdf(const grid_map::Matrix& sdf0, const grid_map::Matrix& sdf1, float tol) { + grid_map::Matrix error = (sdf0 - sdf1).array().abs(); + float maxDifference = error.maxCoeff(); + return maxDifference < tol; +} + +// N^2 naive implementation, for testing purposes +inline grid_map::Matrix naiveSignedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution) { + grid_map::Matrix signedDistance(elevationMap.rows(), elevationMap.cols()); + + // For each point + for (int row = 0; row < elevationMap.rows(); ++row) { + for (int col = 0; col < elevationMap.cols(); ++col) { + if (elevationMap(row, col) >= height) { // point is below surface + signedDistance(row, col) = -INF; + // find closest open space over all other points + for (int i = 0; i < elevationMap.rows(); ++i) { + for (int j = 0; j < elevationMap.cols(); ++j) { + // Compute distance to free cube at location (i, j) + float dx = resolution * pixelBorderDistance(i, row); + float dy = resolution * pixelBorderDistance(j, col); + float dz = std::max(elevationMap(i, j) - height, 0.0F); + float currentSignedDistance = -std::sqrt(dx * dx + dy * dy + dz * dz); + signedDistance(row, col) = std::max(signedDistance(row, col), currentSignedDistance); + } + } + } else { // point is above surface + signedDistance(row, col) = INF; + // find closest object over all other points + for (int i = 0; i < elevationMap.rows(); ++i) { + for (int j = 0; j < elevationMap.cols(); ++j) { + // Compute distance to occupied cube at location (i, j) + float dx = resolution * pixelBorderDistance(i, row); + float dy = resolution * pixelBorderDistance(j, col); + float dz = std::max(height - elevationMap(i, j), 0.0F); + float currentSignedDistance = std::sqrt(dx * dx + dy * dy + dz * dz); + signedDistance(row, col) = std::min(signedDistance(row, col), currentSignedDistance); + } + } + } + } + } + + return signedDistance; +} + +inline grid_map::Matrix naiveSignedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution) { + grid_map::Matrix signedDistance(occupancyGrid.rows(), occupancyGrid.cols()); + + // For each point + for (int row = 0; row < occupancyGrid.rows(); ++row) { + for (int col = 0; col < occupancyGrid.cols(); ++col) { + if (occupancyGrid(row, col)) { // This point is an obstable + signedDistance(row, col) = -INF; + // find closest open space over all other points + for (int i = 0; i < occupancyGrid.rows(); ++i) { + for (int j = 0; j < occupancyGrid.cols(); ++j) { + if (!occupancyGrid(i, j)) { + float dx = resolution * pixelBorderDistance(i, row); + float dy = resolution * pixelBorderDistance(j, col); + float currentSignedDistance = -std::sqrt(dx * dx + dy * dy); + signedDistance(row, col) = std::max(signedDistance(row, col), currentSignedDistance); + } + } + } + } else { // This point is in free space + signedDistance(row, col) = INF; + // find closest object over all other points + for (int i = 0; i < occupancyGrid.rows(); ++i) { + for (int j = 0; j < occupancyGrid.cols(); ++j) { + if (occupancyGrid(i, j)) { + float dx = resolution * pixelBorderDistance(i, row); + float dy = resolution * pixelBorderDistance(j, col); + float currentSignedDistance = std::sqrt(dx * dx + dy * dy); + signedDistance(row, col) = std::min(signedDistance(row, col), currentSignedDistance); + } + } + } + } + } + } + + return signedDistance; +} +} \ No newline at end of file diff --git a/signed_distance_field/test/testPixelBorderDistance.cpp b/signed_distance_field/test/testPixelBorderDistance.cpp new file mode 100644 index 00000000..8e83a04a --- /dev/null +++ b/signed_distance_field/test/testPixelBorderDistance.cpp @@ -0,0 +1,50 @@ +// +// Created by rgrandia on 07.08.20. +// + +#include + +#include "signed_distance_field/PixelBorderDistance.h" + + +TEST(testPixelBorderDistance, distanceFunction) { + using signed_distance_field::pixelBorderDistance; + // Basic properties of the distance function + ASSERT_TRUE(pixelBorderDistance(0, 0) == 0.0F); + ASSERT_FLOAT_EQ(pixelBorderDistance(0, 1), 0.5); + ASSERT_FLOAT_EQ(pixelBorderDistance(0, 2), 1.5); + ASSERT_TRUE(pixelBorderDistance(0, 1) == pixelBorderDistance(1, 0)); + ASSERT_TRUE(pixelBorderDistance(-10, 42) == pixelBorderDistance(42, -10)); +} + +TEST(testPixelBorderDistance, equidistantPoint) { + using signed_distance_field::equidistancePoint; + using signed_distance_field::squarePixelBorderDistance; + + int pixelRange = 10; + float offsetRange = 20.0; + float offsetStep = 0.25; + float tol = 1e-4; + + for (int p =-pixelRange; p #include "signed_distance_field/SignedDistance2d.h" +#include "signed_distance_field/PixelBorderDistance.h" -namespace signed_distance_field { - -// N^2 naive implementation, for testing purposes -grid_map::Matrix naiveSignedDistance(const grid_map::Matrix& elevationMap, float height, float resolution) { - grid_map::Matrix signedDistance(elevationMap.rows(), elevationMap.cols()); - - // For each point - for (int row = 0; row < elevationMap.rows(); ++row) { - for (int col = 0; col < elevationMap.cols(); ++col) { - if (elevationMap(row, col) >= height) { - signedDistance(row, col) = -INF; - // find closest open space over all other points - for (int i = 0; i < elevationMap.rows(); ++i) { - for (int j = 0; j < elevationMap.cols(); ++j) { - if (elevationMap(i, j) < height) { - float dx = resolution * (i - row); - float dy = resolution * (j - col); - float currentSignedDistance = -std::sqrt(dx * dx + dy * dy); - signedDistance(row, col) = std::max(signedDistance(row, col), currentSignedDistance); - } - } - } - } else { - signedDistance(row, col) = INF; - // find closest object over all other points - for (int i = 0; i < elevationMap.rows(); ++i) { - for (int j = 0; j < elevationMap.cols(); ++j) { - if (elevationMap(i, j) >= height) { - float dx = resolution * (i - row); - float dy = resolution * (j - col); - float currentSignedDistance = std::sqrt(dx * dx + dy * dy); - signedDistance(row, col) = std::min(signedDistance(row, col), currentSignedDistance); - } - } - } - } - } - } - - return signedDistance; -} -} // namespace signed_distance_field - -TEST(testSignedDistance2d, sparsityInfo_noObstacles) { - const int n = 3; - const int m = 4; - const grid_map::Matrix map = grid_map::Matrix::Ones(n, m); - - const auto sparsityInfo = signed_distance_field::collectSparsityInfo(map, 2.0); - - ASSERT_TRUE(sparsityInfo.hasFreeSpace); - ASSERT_FALSE(sparsityInfo.hasObstacles); - ASSERT_EQ(sparsityInfo.numColsHomogeneous, m); - ASSERT_EQ(sparsityInfo.numRowsHomogeneous, n); -} - -TEST(testSignedDistance2d, sparsityInfo_allObstacles) { - const int n = 3; - const int m = 4; - const grid_map::Matrix map = grid_map::Matrix::Ones(n, m); - - const auto sparsityInfo = signed_distance_field::collectSparsityInfo(map, 0.0); - - ASSERT_FALSE(sparsityInfo.hasFreeSpace); - ASSERT_TRUE(sparsityInfo.hasObstacles); - ASSERT_EQ(sparsityInfo.numColsHomogeneous, m); - ASSERT_EQ(sparsityInfo.numRowsHomogeneous, n); -} - -TEST(testSignedDistance2d, sparsityInfo_mixed) { - const int n = 2; - const int m = 3; - grid_map::Matrix map(n, m); - map << 0.0, 1.0, 1.0, 0.0, 0.0, 0.0; - - const auto sparsityInfo = signed_distance_field::collectSparsityInfo(map, 0.5); - - ASSERT_TRUE(sparsityInfo.hasFreeSpace); - ASSERT_TRUE(sparsityInfo.hasObstacles); - ASSERT_TRUE(sparsityInfo.colsIsHomogenous[0]); - ASSERT_TRUE(sparsityInfo.rowsIsHomogenous[1]); - ASSERT_EQ(sparsityInfo.numColsHomogeneous, 1); - ASSERT_EQ(sparsityInfo.numRowsHomogeneous, 1); -} +#include "naiveSignedDistance.h" TEST(testSignedDistance2d, signedDistance2d_noObstacles) { const int n = 3; @@ -97,7 +15,8 @@ TEST(testSignedDistance2d, signedDistance2d_noObstacles) { const float resolution = 0.1; const grid_map::Matrix map = grid_map::Matrix::Ones(n, m); - const auto signedDistance = signed_distance_field::computeSignedDistanceAtHeight(map, 2.0, resolution); + const auto occupancy = signed_distance_field::occupancyAtHeight(map, 2.0); + const auto signedDistance = signed_distance_field::signedDistanceFromOccupancy(occupancy, resolution); ASSERT_TRUE((signedDistance.array() == signed_distance_field::INF).all()); } @@ -108,21 +27,23 @@ TEST(testSignedDistance2d, signedDistance2d_allObstacles) { const float resolution = 0.1; const grid_map::Matrix map = grid_map::Matrix::Ones(n, m); - const auto signedDistance = signed_distance_field::computeSignedDistanceAtHeight(map, 0.0, resolution); + const auto occupancy = signed_distance_field::occupancyAtHeight(map, 0.0); + const auto signedDistance = signed_distance_field::signedDistanceFromOccupancy(occupancy, resolution); - ASSERT_TRUE((signedDistance.array() == 0.0).all()); + ASSERT_TRUE((signedDistance.array() == -signed_distance_field::INF).all()); } TEST(testSignedDistance2d, signedDistance2d_mixed) { const int n = 2; const int m = 3; - const float resolution = 0.1; + const float resolution = 1.0; grid_map::Matrix map(n, m); - map << 0.0, 1.0, 1.0, 0.0, 0.0, 0.0; + map << 0.0, 1.0, 1.0, 0.0, 0.0, 1.0; + const auto occupancy = signed_distance_field::occupancyAtHeight(map, 0.5); - const auto naiveSignedDistance = signed_distance_field::naiveSignedDistance(map, 0.5, resolution); - const auto signedDistance = signed_distance_field::computeSignedDistanceAtHeight(map, 0.5, resolution); - ASSERT_TRUE(signedDistance.isApprox(naiveSignedDistance)); + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistanceFromOccupancy(occupancy, resolution); + const auto signedDistance = signed_distance_field::signedDistanceFromOccupancy(occupancy, resolution); + ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)); } TEST(testSignedDistance2d, signedDistance2d_oneObstacle) { @@ -131,10 +52,11 @@ TEST(testSignedDistance2d, signedDistance2d_oneObstacle) { const float resolution = 0.1; grid_map::Matrix map = grid_map::Matrix::Zero(n, m); map(n/2, m/2) = 1.0; + const auto occupancy = signed_distance_field::occupancyAtHeight(map, 0.5); - const auto naiveSignedDistance = signed_distance_field::naiveSignedDistance(map, 0.5, resolution); - const auto signedDistance = signed_distance_field::computeSignedDistanceAtHeight(map, 0.5, resolution); - ASSERT_TRUE(signedDistance.isApprox(naiveSignedDistance)); + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistanceFromOccupancy(occupancy, resolution); + const auto signedDistance = signed_distance_field::signedDistanceFromOccupancy(occupancy, resolution); + ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)); } TEST(testSignedDistance2d, signedDistance2d_oneFreeSpace) { @@ -144,18 +66,43 @@ TEST(testSignedDistance2d, signedDistance2d_oneFreeSpace) { grid_map::Matrix map = grid_map::Matrix::Ones(n, m); map(n/2, m/2) = 0.0; - const auto naiveSignedDistance = signed_distance_field::naiveSignedDistance(map, 0.5, resolution); - const auto signedDistance = signed_distance_field::computeSignedDistanceAtHeight(map, 0.5, resolution); - ASSERT_TRUE(signedDistance.isApprox(naiveSignedDistance)); + const auto occupancy = signed_distance_field::occupancyAtHeight(map, 0.5); + + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistanceFromOccupancy(occupancy, resolution); + const auto signedDistance = signed_distance_field::signedDistanceFromOccupancy(occupancy, resolution); + ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)); +} + +TEST(testSignedDistance2d, signedDistance2d_debugcase) { + const int n = 3; + const int m = 3; + const float resolution = 1.0; + grid_map::Matrix map(n, m); + map << + 1.0, 1.0, 1.0, + 0.0, 1.0, 1.0, + 1.0, 1.0, 0.0; + + const auto occupancy = signed_distance_field::occupancyAtHeight(map, 0.5); + + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistanceFromOccupancy(occupancy, resolution); + const auto signedDistance = signed_distance_field::signedDistanceFromOccupancy(occupancy, resolution); + ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)); } TEST(testSignedDistance2d, signedDistance2d_random) { const int n = 20; const int m = 30; - const float resolution = 0.1; + const float resolution = 1.0; grid_map::Matrix map = grid_map::Matrix::Random(n, m); // random [-1.0, 1.0] - const auto naiveSignedDistance = signed_distance_field::naiveSignedDistance(map, 0.0, resolution); - const auto signedDistance = signed_distance_field::computeSignedDistanceAtHeight(map, 0.0, resolution); - ASSERT_TRUE(signedDistance.isApprox(naiveSignedDistance)); + // Check at different heights, resulting in different levels of sparsity. + float heightStep = 0.1; + for (float height = -1.0 - heightStep; height < 1.0 + heightStep; height+=heightStep) { + const auto occupancy = signed_distance_field::occupancyAtHeight(map, height); + + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistanceFromOccupancy(occupancy, resolution); + const auto signedDistance = signed_distance_field::signedDistanceFromOccupancy(occupancy, resolution); + ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)) << "height: " << height; + } } \ No newline at end of file diff --git a/signed_distance_field/test/testSignedDistance3d.cpp b/signed_distance_field/test/testSignedDistance3d.cpp new file mode 100644 index 00000000..d90eb679 --- /dev/null +++ b/signed_distance_field/test/testSignedDistance3d.cpp @@ -0,0 +1,44 @@ +// +// Created by rgrandia on 10.08.20. +// + +#include + +#include "signed_distance_field/PixelBorderDistance.h" +#include "signed_distance_field/SignedDistance2d.h" + +#include "naiveSignedDistance.h" + +TEST(testSignedDistance3d, flatTerrain) { + const int n = 3; + const int m = 4; + const float resolution = 0.1; + const float terrainHeight = 0.5; + const grid_map::Matrix map = grid_map::Matrix::Constant(n, m, terrainHeight); + + const float testHeightAboveTerrain = 3.0; + const auto naiveSignedDistanceAbove = signed_distance_field::naiveSignedDistanceAtHeight(map, testHeightAboveTerrain, resolution); + const auto signedDistanceAbove = signed_distance_field::signedDistanceAtHeight(map, testHeightAboveTerrain, resolution); + ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistanceAbove, naiveSignedDistanceAbove, 1e-4)); + + const float testHeightBelowTerrain = -3.0; + const auto naiveSignedDistanceBelow = signed_distance_field::naiveSignedDistanceAtHeight(map, testHeightBelowTerrain, resolution); + const auto signedDistanceBelow = signed_distance_field::signedDistanceAtHeight(map, testHeightBelowTerrain, resolution); + ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistanceBelow, naiveSignedDistanceBelow, 1e-4)); +} + +TEST(testSignedDistance3d, randomTerrain) { + const int n = 20; + const int m = 30; + const float resolution = 0.1; + grid_map::Matrix map = grid_map::Matrix::Random(n, m); // random [-1.0, 1.0] + + // Check at different heights, resulting in different levels of sparsity. + float heightStep = 0.1; + for (float height = -1.0 - heightStep; height < 1.0 + heightStep; height+=heightStep) { + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistanceAtHeight(map, height, resolution); + const auto signedDistance = signed_distance_field::signedDistanceAtHeight(map, height, resolution); + + ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)) << "height: " << height; + } +} \ No newline at end of file From 3b3f4bbd589b94e070ac49fce8c1c86dd829886d Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 11 Aug 2020 15:08:37 +0200 Subject: [PATCH 063/504] implemented signed distance class with derivatives precomputed --- .../src/DemoNode.cpp | 17 ++-- .../test/signedDistanceTest.cpp | 56 ++++++----- signed_distance_field/CMakeLists.txt | 2 + .../DistanceDerivatives.h | 45 +++++++++ .../PixelBorderDistance.h | 56 ++++++++++- .../SignedDistanceField.h | 21 +++- signed_distance_field/package.xml | 1 + .../src/PixelBorderDistance.cpp | 44 +-------- .../src/SignedDistance2d.cpp | 96 ++++++++++++------- .../src/SignedDistanceField.cpp | 90 ++++++++++++++++- .../test/testDerivatives.cpp | 44 +++++++++ 11 files changed, 355 insertions(+), 117 deletions(-) create mode 100644 signed_distance_field/include/signed_distance_field/DistanceDerivatives.h create mode 100644 signed_distance_field/test/testDerivatives.cpp diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp index 73507c03..db208601 100644 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -96,21 +97,19 @@ int main(int argc, char** argv) { convexTerrainPublisher_.publish(toMarker(convexTerrain)); - grid_map::SignedDistanceField signedDistanceField; - double heightClearance = 0.1; - double width = 0.5; + + double heightClearance = 0.35; + double width = 1.5; + double length = 2.0; bool success; - grid_map::GridMap localMap = messageMap->getSubmap({convexTerrain.plane.positionInWorld.x(), convexTerrain.plane.positionInWorld.y()}, Eigen::Array2d(width, width), success); + grid_map::GridMap localMap = messageMap->getSubmap({convexTerrain.plane.positionInWorld.x(), convexTerrain.plane.positionInWorld.y()}, Eigen::Array2d(width, length), success); auto t2 = std::chrono::high_resolution_clock::now(); - signedDistanceField.calculateSignedDistanceField(*messageMap, "elevation", heightClearance); + signed_distance_field::SignedDistanceField sdf(localMap, "elevation", convexTerrain.plane.positionInWorld.z() - heightClearance, convexTerrain.plane.positionInWorld.z() + heightClearance); auto t3 = std::chrono::high_resolution_clock::now(); std::cout << "Sdf computation took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]\n"; - pcl::PointCloud points; - signedDistanceField.convertToPointCloud(points); - sensor_msgs::PointCloud2 pointCloud2Msg; - pcl::toROSMsg(points, pointCloud2Msg); + pcl::toROSMsg(sdf.asPointCloud(), pointCloud2Msg); pointCloud2Msg.header = switched_model::getHeaderMsg(originFrameId_, ros::Time::now()); distanceFieldPublisher.publish(pointCloud2Msg); diff --git a/segmented_planes_terrain_model/test/signedDistanceTest.cpp b/segmented_planes_terrain_model/test/signedDistanceTest.cpp index 64e17157..0ead6ebe 100644 --- a/segmented_planes_terrain_model/test/signedDistanceTest.cpp +++ b/segmented_planes_terrain_model/test/signedDistanceTest.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -181,7 +182,7 @@ int main(int argc, char** argv) { grid_map::SignedDistanceField signedDistanceField; - double width = 1.0; + double width = 4.0; bool success; grid_map::GridMap localMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(width, width), success); @@ -200,33 +201,36 @@ int main(int argc, char** argv) { const float lowestHeight_ = -1e5; using grid_map::Matrix; - auto t2 = std::chrono::high_resolution_clock::now(); - const int N = 300; - for (int rep = 0; rep < N; rep++) { - // ========================================================= - data_.clear(); - resolution_ = gridMap.getResolution(); - position_ = gridMap.getPosition(); - size_ = gridMap.getSize(); - Matrix map = gridMap.get(layer); // Copy! - - float minHeight = map.minCoeffOfFinites(); - if (!std::isfinite(minHeight)) minHeight = lowestHeight_; - float maxHeight = map.maxCoeffOfFinites(); - if (!std::isfinite(maxHeight)) maxHeight = lowestHeight_; - - const float valueForEmptyCells = lowestHeight_; // maxHeight, minHeight (TODO Make this an option). - for (size_t i = 0; i < map.size(); ++i) { - if (std::isnan(map(i))) map(i) = valueForEmptyCells; - } + // initialization + resolution_ = gridMap.getResolution(); + position_ = gridMap.getPosition(); + size_ = gridMap.getSize(); + Matrix map = gridMap.get(layer); // Copy! - // Height range of the signed distance field is higher than the max height. - maxHeight += heightClearance; + float minHeight = map.minCoeffOfFinites(); + if (!std::isfinite(minHeight)) minHeight = lowestHeight_; + float maxHeight = map.maxCoeffOfFinites(); + if (!std::isfinite(maxHeight)) maxHeight = lowestHeight_; - // Calculate signed distance field from bottom. - for (float h = minHeight; h < maxHeight; h += resolution_) { - data_.emplace_back(signed_distance_field::signedDistanceAtHeight(map, h, resolution)); - } + const float valueForEmptyCells = lowestHeight_; // maxHeight, minHeight (TODO Make this an option). + for (size_t i = 0; i < map.size(); ++i) { + if (std::isnan(map(i))) map(i) = valueForEmptyCells; + } + + // Height range of the signed distance field is higher than the max height. + maxHeight += heightClearance; + + auto t2 = std::chrono::high_resolution_clock::now(); + const int N = 50; + for (int rep = 0; rep < N; rep++) { +// // ========================================================= +// data_.clear(); +// +// // Calculate signed distance field from bottom. +// for (float h = minHeight; h < maxHeight; h += resolution_) { +// data_.emplace_back(signed_distance_field::signedDistanceAtHeight(map, h, resolution)); +// } + auto sdf = signed_distance_field::SignedDistanceField(gridMap, layer, minHeight, maxHeight); // ========================================================= } diff --git a/signed_distance_field/CMakeLists.txt b/signed_distance_field/CMakeLists.txt index 458c8dc3..b324e0a1 100644 --- a/signed_distance_field/CMakeLists.txt +++ b/signed_distance_field/CMakeLists.txt @@ -4,6 +4,7 @@ project(signed_distance_field) # Catkin dependencies set(CATKIN_PACKAGE_DEPENDENCIES grid_map_core + pcl_ros ) find_package(catkin REQUIRED COMPONENTS @@ -64,6 +65,7 @@ install(DIRECTORY include/${PROJECT_NAME}/ ############# add_executable(${PROJECT_NAME}_test + test/testDerivatives.cpp test/testPixelBorderDistance.cpp test/testSignedDistance2d.cpp test/testSignedDistance3d.cpp diff --git a/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h b/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h new file mode 100644 index 00000000..d0e97a7d --- /dev/null +++ b/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h @@ -0,0 +1,45 @@ +// +// Created by rgrandia on 10.08.20. +// + +#pragma once + +#include + +namespace signed_distance_field { + +inline Eigen::MatrixXf columnwiseCentralDifference(const Eigen::MatrixXf& data, float resolution) { + assert(data.cols() >= 2); // Minimum size to take finite differences. + + const int m = data.cols(); + Eigen::MatrixXf centralDifference(data.rows(), data.cols()); + + // First column + centralDifference.col(0) = (data.col(1) - data.col(0)) / resolution; + + // All the middle columns + float doubleResolution = 2.0F * resolution; + for (int i = 1; i + 1 < m; ++i) { + centralDifference.col(i) = (data.col(i + 1) - data.col(i - 1)) / doubleResolution; + } + + // Last column + centralDifference.col(m - 1) = (data.col(m - 1) - data.col(m - 2)) / resolution; + + return centralDifference; +} + +inline Eigen::MatrixXf rowwiseCentralDifference(const Eigen::MatrixXf& data, float resolution) { + return columnwiseCentralDifference(data.transpose(), resolution).transpose(); +} + +inline Eigen::MatrixXf layerFiniteDifference(const Eigen::MatrixXf& data_k, const Eigen::MatrixXf& data_kp1, float resolution) { + return (data_kp1 - data_k) / resolution; +} + +inline Eigen::MatrixXf layerCentralDifference(const Eigen::MatrixXf& data_km1, const Eigen::MatrixXf& data_kp1, float resolution) { + float doubleResolution = 2.0F * resolution; + return (data_kp1 - data_km1) / doubleResolution; +} + +} // namespace signed_distance_field diff --git a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h index 394753d3..9412e1bd 100644 --- a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h +++ b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h @@ -5,6 +5,8 @@ #pragma once #include +#include +#include namespace signed_distance_field { @@ -24,15 +26,63 @@ inline float pixelBorderDistance(float i, float j) { * Returns square pixelBorderDistance, adding offset f. */ inline float squarePixelBorderDistance(float i, float j, float f) { - float distance = pixelBorderDistance(i, j); - return distance * distance + f; + assert(i == j || std::abs(i - j) >= 1.0F); // Check that q and p are proper pixel locations: either the same pixel or non-overlapping pixels + if (i == j) { + return f; + } else { + float diff = std::abs(i-j) - 0.5F; + return diff * diff + f; + } } +namespace internal { + +/** + * Return equidistancepoint between origin and pixel p (with p > 0) with offset fp + */ +inline float intersectionPointRightSideOfOrigin(float p, float fp) { + auto pSquared = p * p; + auto fpAbs = std::abs(fp); + if (fpAbs >= pSquared) { + float s = (pSquared + fp) / (2.0F * p); + return (fp > 0.0F) ? s + 0.5F : s - 0.5F; + } else { + float boundary = pSquared - 2.0F * p + 1.0F; + if (fpAbs < boundary) { + return (pSquared - p + fp) / (2.0F * p - 2.0F); + } else { + float s = 0.5F + std::sqrt(fpAbs); + return (fp > 0.0F) ? s : p - s; + } + } +} + +/** + * Return equidistancepoint between origin and pixel p with offset fp + */ +inline float intersectionOffsetFromOrigin(float p, float fp) { + float intersectionOffset = intersectionPointRightSideOfOrigin(std::abs(p), fp); + return (p > 0) ? intersectionOffset : -intersectionOffset; +} + +} // namespace internal + /** * Return the point s in pixel space that is equally far from p and q (taking into account offsets fp, and fq) * It is the solution to the following equation: * squarePixelBorderDistance(s, q, fq) == squarePixelBorderDistance(s, p, fp) */ -float equidistancePoint(int q, float fq, int p, float fp); +inline float equidistancePoint(float q, float fq, float p, float fp) { + assert(q == p || std::abs(q-p) >= 1.0F); // Check that q and p are proper pixel locations: either the same pixel or non-overlapping pixels + assert((q == p) ? fp == fq : true); // Check when q and p are equal, the offsets are also equal + + float df = fp - fq; + if (df==0) { // quite common case when both pixels are of the same class (occupied / free) + return 0.5F * (p + q); + } else { + float dr = p - q; + return internal::intersectionOffsetFromOrigin(dr, df) + q; + } +} } // namespace signed_distance_field diff --git a/signed_distance_field/include/signed_distance_field/SignedDistanceField.h b/signed_distance_field/include/signed_distance_field/SignedDistanceField.h index c6e1b9d9..e7de346b 100644 --- a/signed_distance_field/include/signed_distance_field/SignedDistanceField.h +++ b/signed_distance_field/include/signed_distance_field/SignedDistanceField.h @@ -8,23 +8,40 @@ #include +#include +#include + +#include +#include + namespace signed_distance_field { class SignedDistanceField { public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + SignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, double minHeight, double maxHeight); + double atPosition(const Eigen::Vector3d& position) const; Eigen::Vector3d derivativeAtPosition(const Eigen::Vector3d& position) const; + pcl::PointCloud asPointCloud() const; + private: + void computeSignedDistance(const grid_map::Matrix& elevation); + // Must be called in ascending layers numbers [0, gridSize_[2]-1] + void emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dx, const grid_map::Matrix& dy, const grid_map::Matrix& dz); size_t nearestNode(const Eigen::Vector3d& position) const; - Eigen::Vector3d nodePosition(const Eigen::Vector3d& position) const; + Eigen::Vector3d nodePosition(size_t rowX, size_t colY, size_t layerZ) const; + size_t linearIndex(size_t rowX, size_t colY, size_t layerZ) const ; using node_data_t = std::array; static double distance(const node_data_t& nodeData) noexcept { return nodeData[0]; } static Eigen::Vector3d derivative(const node_data_t& nodeData) noexcept { return {nodeData[1], nodeData[2], nodeData[3]}; } - double resolution_; + float resolution_; std::array gridsize_; + Eigen::Vector3d gridOrigin_; std::vector data_; }; diff --git a/signed_distance_field/package.xml b/signed_distance_field/package.xml index e27f28e4..a6ba2663 100644 --- a/signed_distance_field/package.xml +++ b/signed_distance_field/package.xml @@ -11,5 +11,6 @@ catkin grid_map_core + pcl_ros diff --git a/signed_distance_field/src/PixelBorderDistance.cpp b/signed_distance_field/src/PixelBorderDistance.cpp index 51d71d75..2a1ed055 100644 --- a/signed_distance_field/src/PixelBorderDistance.cpp +++ b/signed_distance_field/src/PixelBorderDistance.cpp @@ -4,49 +4,11 @@ #include "signed_distance_field/PixelBorderDistance.h" -#include namespace signed_distance_field { -namespace internal { - -/** - * Return equidistancepoint between origin and pixel p (with p > 0) with offset fp - */ -inline float intersectionPointRightSideOfOrigin(int p, float fp) { - auto pFloat = static_cast(p); - auto pSquared = pFloat * pFloat; - auto fpAbs = std::abs(fp); - if (fpAbs >= pSquared) { - float s = (pSquared + fp) / (2.0F * pFloat); - return (fp > 0.0F) ? s + 0.5F : s - 0.5F; - } else { - float boundary = (pSquared - 2 * pFloat + 1); - if (fpAbs < boundary) { - return (pSquared - pFloat + fp) / (2.0F * pFloat - 2.0F); - } else { - float s = 0.5F + std::sqrt(fpAbs); - return (fp > 0.0F) ? s : pFloat - s; - } - } -} - -/** - * Return equidistancepoint between origin and pixel p with offset fp - */ -inline float intersectionOffsetFromOrigin(int p, float fp) { - float intersectionOffset = intersectionPointRightSideOfOrigin(std::abs(p), fp); - return (p > 0) ? intersectionOffset : -intersectionOffset; -} - -} // namespace internal - -float equidistancePoint(int q, float fq, int p, float fp) { - if (q != p) { - return internal::intersectionOffsetFromOrigin(p - q, fp - fq) + static_cast(q); - } else { - return static_cast(q); - } -} + + + } \ No newline at end of file diff --git a/signed_distance_field/src/SignedDistance2d.cpp b/signed_distance_field/src/SignedDistance2d.cpp index 46ea838e..f673cb71 100644 --- a/signed_distance_field/src/SignedDistance2d.cpp +++ b/signed_distance_field/src/SignedDistance2d.cpp @@ -9,64 +9,90 @@ namespace signed_distance_field { namespace internal { -/** - * 1D Euclidean Distance Transform based on: http://cs.brown.edu/people/pfelzens/dt/ - * Adapted to work on Eigen objects directly - * Optimized computation of s - */ -void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDistance1d, Eigen::Ref d, - Eigen::Ref z, std::vector& v) { +struct DistanceLowerBound { + float v; // origin of bounding function + float f; // functional offset at the origin + float zprev; // lhs of interval where this bound holds + float z; // rhs of interval where this lower bound holds +}; + +inline void fillLowerBounds(const Eigen::Ref& squareDistance1d, std::vector& lowerBounds) { const int n = squareDistance1d.size(); - const auto& f = squareDistance1d; - assert(d.size() == n); - assert(z.size() == n + 1); - assert(v.size() == n); // Initialize - int k = 0; - v[0] = 0; - z[0] = -INF; - z[1] = INF; + auto lowerBoundIt = lowerBounds.begin(); + *lowerBoundIt = DistanceLowerBound{0.0F, squareDistance1d[0], -INF, INF}; // Compute bounds + float qFloat = 1.0F; for (int q = 1; q < n; q++) { - float s = equidistancePoint(q, f[q], v[k], f[v[k]]); - while (s <= z[k]) { - k--; - s = equidistancePoint(q, f[q], v[k], f[v[k]]); + // Storing these quantaties by value gives better performance (removed indirection?) + const float fq = squareDistance1d[q]; + DistanceLowerBound lastBound = *lowerBoundIt; + + float s = equidistancePoint(qFloat, fq, lastBound.v, lastBound.f); + + // Search backwards in bounds until s is within [zprev, z] + while (s <= lastBound.zprev) { + --lowerBoundIt; + lastBound = *lowerBoundIt; + s = equidistancePoint(qFloat, fq, lastBound.v, lastBound.f); } - k++; - v[k] = q; - z[k] = s; - z[k + 1] = INF; + lowerBoundIt->z = s; + ++lowerBoundIt; + *lowerBoundIt = DistanceLowerBound{qFloat, fq, s, INF}; + qFloat += 1.0F; } +} + +inline void extractDistances(Eigen::Ref squareDistance1d, const std::vector& lowerBounds) { + const int n = squareDistance1d.size(); + auto lowerBoundIt = lowerBounds.begin(); - // Collect results - k = 0; + // Store active lower bound by value to remove indirection + auto lastz = lowerBoundIt->z; + auto lastv = lowerBoundIt->v; + auto lastf = lowerBoundIt->f; + + float qFloat = 0.0F; for (int q = 0; q < n; q++) { - auto qFloat = static_cast(q); - while (z[k + 1] < qFloat) { - k++; + // Find the new active lower bound if q no longer belongs to current interval + if (qFloat > lastz) { + do { + ++lowerBoundIt; + lastz = lowerBoundIt->z; + } while (lastz < qFloat); + lastv = lowerBoundIt->v; + lastf = lowerBoundIt->f; } - d[q] = squarePixelBorderDistance(qFloat, v[k], f[v[k]]); + + squareDistance1d[q] = squarePixelBorderDistance(qFloat, lastv, lastf); + qFloat += 1.0F; } +} + +/** + * 1D Euclidean Distance Transform based on: http://cs.brown.edu/people/pfelzens/dt/ + * Adapted to work on Eigen objects directly + * Optimized computation of s + */ +inline void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDistance1d, std::vector& lowerBounds) { + assert(lowerBounds.size() == squareDistance1d.size()); - // Write distance result back in place - squareDistance1d = d; + fillLowerBounds(squareDistance1d, lowerBounds); + extractDistances(squareDistance1d, lowerBounds); } void squaredDistanceTransform_2d_columnwiseInplace(grid_map::Matrix& squareDistance) { const size_t n = squareDistance.rows(); const size_t m = squareDistance.cols(); - Eigen::VectorXf workvector(2 * n + 1); - std::vector intWorkvector(n); + std::vector lowerBounds(n); for (size_t i = 0; i < m; i++) { - squaredDistanceTransform_1d_inplace(squareDistance.col(i), workvector.segment(0, n), workvector.segment(n, n + 1), intWorkvector); + squaredDistanceTransform_1d_inplace(squareDistance.col(i), lowerBounds); } } -// SquareDistance must be initialized with 0.0 for elements and INF for non-elements void computePixelDistance2d(grid_map::Matrix& squareDistance) { // Process columns squaredDistanceTransform_2d_columnwiseInplace(squareDistance); diff --git a/signed_distance_field/src/SignedDistanceField.cpp b/signed_distance_field/src/SignedDistanceField.cpp index 3fe2c783..38618ef6 100644 --- a/signed_distance_field/src/SignedDistanceField.cpp +++ b/signed_distance_field/src/SignedDistanceField.cpp @@ -4,4 +4,92 @@ #include "signed_distance_field/SignedDistanceField.h" -#include "signed_distance_field/SignedDistance2d.h" \ No newline at end of file +#include "signed_distance_field/DistanceDerivatives.h" +#include "signed_distance_field/SignedDistance2d.h" + +namespace signed_distance_field { + +SignedDistanceField::SignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, double minHeight, double maxHeight) : + resolution_(static_cast(gridMap.getResolution())) { + assert(maxHeight >= minHeight); + grid_map::Position mapOriginXY; + gridMap.getPosition(Eigen::Vector2i(0, 0), mapOriginXY); + gridOrigin_ = {mapOriginXY.x(), mapOriginXY.y(), minHeight}; + + // Take minimum of two layers to enable finite difference in Z direction + const auto numZLayers = static_cast(std::max(std::ceil((maxHeight - minHeight) / gridMap.getResolution() ), 2.0)); + const size_t numXrows = gridMap.getSize().x(); + const size_t numYrows = gridMap.getSize().y(); + gridsize_ = {numXrows, numYrows, numZLayers}; + + data_.reserve(numXrows * numYrows * numZLayers); + computeSignedDistance(gridMap.get(elevationLayer)); +} +Eigen::Vector3d SignedDistanceField::nodePosition(size_t rowX, size_t colY, size_t layerZ) const { + return {gridOrigin_.x() - rowX * resolution_, gridOrigin_.y() - colY * resolution_, gridOrigin_.z() + layerZ * resolution_}; +} + +size_t SignedDistanceField::linearIndex(size_t rowX, size_t colY, size_t layerZ) const { + return layerZ * gridsize_[1] * gridsize_[0] + colY * gridsize_[0] + rowX; +} + +void SignedDistanceField::computeSignedDistance(const grid_map::Matrix& elevation) { + // First layer: forward difference in z + grid_map::Matrix currentLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOrigin_.z(), resolution_); + grid_map::Matrix nextLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOrigin_.z() + resolution_, resolution_); + grid_map::Matrix dz = signed_distance_field::layerFiniteDifference(currentLayer, nextLayer, resolution_); // dz / layer = +resolution + grid_map::Matrix dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution_); // dy / dcol = -resolution + grid_map::Matrix dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution_); // dx / drow = -resolution + emplacebackLayerData(currentLayer, dx, dy, dz); + + // Middle layers: central difference in z + for (size_t layerZ = 1; layerZ + 1 < gridsize_[2]; ++layerZ) { + grid_map::Matrix previousLayer = std::move(currentLayer); + currentLayer = std::move(nextLayer); + nextLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOrigin_.z() + (layerZ + 1) * resolution_, resolution_); + + dz = signed_distance_field::layerCentralDifference(previousLayer, nextLayer, resolution_); + dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution_); + dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution_); + emplacebackLayerData(currentLayer, dx, dy, dz); + } + + // Last layer: backward difference in z + grid_map::Matrix previousLayer = std::move(currentLayer); + currentLayer = std::move(nextLayer); + dz = signed_distance_field::layerCentralDifference(previousLayer, currentLayer, resolution_); + dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution_); + dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution_); + emplacebackLayerData(currentLayer, dx, dy, dz); +} + +void SignedDistanceField::emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dx, + const grid_map::Matrix& dy, const grid_map::Matrix& dz) { + for (size_t colY=0; colY SignedDistanceField::asPointCloud() const { + pcl::PointCloud points; + points.reserve(gridsize_[0]*gridsize_[1]*gridsize_[2]); + for (size_t layerZ=0; layerZ + +#include "signed_distance_field/DistanceDerivatives.h" + + +TEST(testDerivatives, columnwise) { + Eigen::MatrixXf data(2, 3); + data << 1.0, 2.0, 4.0, + 2.0, 4.0, 6.0; + + float resolution = 0.1; + float doubleResolution = 2.0F * resolution; + + Eigen::MatrixXf manualDifference(2, 3); + manualDifference << 1.0 /resolution, 3.0 /doubleResolution, 2.0 /resolution, + 2.0 /resolution, 4.0 /doubleResolution, 2.0 /resolution; + + const auto computedDifference = signed_distance_field::columnwiseCentralDifference(data, resolution); + + ASSERT_TRUE(manualDifference.isApprox(computedDifference)); +} + +TEST(testDerivatives, rowwise) { + Eigen::MatrixXf data(3, 2); + data << 1.0, 2.0, + 4.0, 2.0, + 4.0, 6.0; + + float resolution = 0.1; + float doubleResolution = 2.0F * resolution; + + Eigen::MatrixXf manualDifference(3, 2); + manualDifference << 3.0 /resolution, 0.0 /resolution, + 3.0 /doubleResolution, 4.0 /doubleResolution, + 0.0 /resolution, 4.0 /resolution; + + const auto computedDifference = signed_distance_field::rowwiseCentralDifference(data, resolution); + + ASSERT_TRUE(manualDifference.isApprox(computedDifference)); +} \ No newline at end of file From 42e09b5c203af3328312d6e84e2007daa0f200d4 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 12 Aug 2020 11:23:16 +0200 Subject: [PATCH 064/504] start lowerbound building at the minimum --- .../PixelBorderDistance.h | 6 +- .../src/SignedDistance2d.cpp | 109 +++++++++++++----- 2 files changed, 81 insertions(+), 34 deletions(-) diff --git a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h index 9412e1bd..0db7cfcf 100644 --- a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h +++ b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h @@ -26,7 +26,7 @@ inline float pixelBorderDistance(float i, float j) { * Returns square pixelBorderDistance, adding offset f. */ inline float squarePixelBorderDistance(float i, float j, float f) { - assert(i == j || std::abs(i - j) >= 1.0F); // Check that q and p are proper pixel locations: either the same pixel or non-overlapping pixels + assert(i == j || std::abs(i - j) >= 1.0F); // Check that i and j are proper pixel locations: either the same pixel or non-overlapping pixels if (i == j) { return f; } else { @@ -76,10 +76,10 @@ inline float equidistancePoint(float q, float fq, float p, float fp) { assert(q == p || std::abs(q-p) >= 1.0F); // Check that q and p are proper pixel locations: either the same pixel or non-overlapping pixels assert((q == p) ? fp == fq : true); // Check when q and p are equal, the offsets are also equal - float df = fp - fq; - if (df==0) { // quite common case when both pixels are of the same class (occupied / free) + if (fp == fq) { // quite common case when both pixels are of the same class (occupied / free) return 0.5F * (p + q); } else { + float df = fp - fq; float dr = p - q; return internal::intersectionOffsetFromOrigin(dr, df) + q; } diff --git a/signed_distance_field/src/SignedDistance2d.cpp b/signed_distance_field/src/SignedDistance2d.cpp index f673cb71..3dd68d1c 100644 --- a/signed_distance_field/src/SignedDistance2d.cpp +++ b/signed_distance_field/src/SignedDistance2d.cpp @@ -10,47 +10,90 @@ namespace signed_distance_field { namespace internal { struct DistanceLowerBound { - float v; // origin of bounding function - float f; // functional offset at the origin - float zprev; // lhs of interval where this bound holds - float z; // rhs of interval where this lower bound holds + float v; // origin of bounding function + float f; // functional offset at the origin + float z_lhs; // lhs of interval where this bound holds + float z_rhs; // rhs of interval where this lower bound holds }; -inline void fillLowerBounds(const Eigen::Ref& squareDistance1d, std::vector& lowerBounds) { +inline std::vector::iterator fillLowerBounds(const Eigen::Ref& squareDistance1d, + std::vector& lowerBounds) { const int n = squareDistance1d.size(); + const auto nFloat = static_cast(n); + + // Find minimum + int qMin = 0; + float fMin = squareDistance1d[0]; + if (fMin > 0.0F) { + for (int q = 1; q < n; ++q) { + const float fq = squareDistance1d[q]; + if (fq < fMin) { + qMin = q; + fMin = fq; + if (fMin == 0.0F) { + break; + } + } + } + } // Initialize - auto lowerBoundIt = lowerBounds.begin(); - *lowerBoundIt = DistanceLowerBound{0.0F, squareDistance1d[0], -INF, INF}; + auto lowerBoundIt = lowerBounds.begin() + qMin; + *lowerBoundIt = DistanceLowerBound{static_cast(qMin), fMin, -INF, INF}; - // Compute bounds - float qFloat = 1.0F; - for (int q = 1; q < n; q++) { + // Compute bounds to the right of minimum + float qFloat = static_cast(qMin) + 1.0F; + for (int q = qMin + 1; q < n; ++q) { // Storing these quantaties by value gives better performance (removed indirection?) const float fq = squareDistance1d[q]; DistanceLowerBound lastBound = *lowerBoundIt; float s = equidistancePoint(qFloat, fq, lastBound.v, lastBound.f); + if (s < nFloat) { // Can ignore the lower bound derived from this point if it is only active outsize of [0, n] + // Search backwards in bounds until s is within [z_lhs, z_rhs] + while (s < lastBound.z_lhs) { + --lowerBoundIt; + lastBound = *lowerBoundIt; + s = equidistancePoint(qFloat, fq, lastBound.v, lastBound.f); + } + lowerBoundIt->z_rhs = s; + ++lowerBoundIt; + *lowerBoundIt = DistanceLowerBound{qFloat, fq, s, INF}; + } + qFloat += 1.0F; + } + + // Compute bounds to the left of minimum + lowerBoundIt = lowerBounds.begin() + qMin; + qFloat = static_cast(qMin) - 1.0F; + for (int q = qMin - 1; q >= 0; --q) { + const float fq = squareDistance1d[q]; + DistanceLowerBound lastBound = *lowerBoundIt; - // Search backwards in bounds until s is within [zprev, z] - while (s <= lastBound.zprev) { + float s = equidistancePoint(qFloat, fq, lastBound.v, lastBound.f); + if (s > 0.0F) { // Can ignore the lower bound derived from this point if it is only active outsize of [0, n] + // Search forwards in bounds until s is within [z_lhs, z_rhs] + while (s > lastBound.z_rhs) { + ++lowerBoundIt; + lastBound = *lowerBoundIt; + s = equidistancePoint(qFloat, fq, lastBound.v, lastBound.f); + } + lowerBoundIt->z_lhs = s; --lowerBoundIt; - lastBound = *lowerBoundIt; - s = equidistancePoint(qFloat, fq, lastBound.v, lastBound.f); + *lowerBoundIt = DistanceLowerBound{qFloat, fq, -INF, s}; } - lowerBoundIt->z = s; - ++lowerBoundIt; - *lowerBoundIt = DistanceLowerBound{qFloat, fq, s, INF}; - qFloat += 1.0F; + qFloat -= 1.0F; } + + return lowerBoundIt; } -inline void extractDistances(Eigen::Ref squareDistance1d, const std::vector& lowerBounds) { +inline void extractDistances(Eigen::Ref squareDistance1d, const std::vector& lowerBounds, + std::vector::iterator lowerBoundIt) { const int n = squareDistance1d.size(); - auto lowerBoundIt = lowerBounds.begin(); // Store active lower bound by value to remove indirection - auto lastz = lowerBoundIt->z; + auto lastz = lowerBoundIt->z_rhs; auto lastv = lowerBoundIt->v; auto lastf = lowerBoundIt->f; @@ -60,7 +103,7 @@ inline void extractDistances(Eigen::Ref squareDistance1d, const if (qFloat > lastz) { do { ++lowerBoundIt; - lastz = lowerBoundIt->z; + lastz = lowerBoundIt->z_rhs; } while (lastz < qFloat); lastv = lowerBoundIt->v; lastf = lowerBoundIt->f; @@ -76,11 +119,15 @@ inline void extractDistances(Eigen::Ref squareDistance1d, const * Adapted to work on Eigen objects directly * Optimized computation of s */ -inline void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDistance1d, std::vector& lowerBounds) { - assert(lowerBounds.size() == squareDistance1d.size()); - - fillLowerBounds(squareDistance1d, lowerBounds); - extractDistances(squareDistance1d, lowerBounds); +inline void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDistance1d, + std::vector& lowerBounds) { + assert(lowerBounds.size() == squareDistance1d.size()); + + // If all distances are zero, then result remains all zeros + if ((squareDistance1d.array() > 0.0F).any()) { + auto startIt = fillLowerBounds(squareDistance1d, lowerBounds); + extractDistances(squareDistance1d, lowerBounds, startIt); + } } void squaredDistanceTransform_2d_columnwiseInplace(grid_map::Matrix& squareDistance) { @@ -110,7 +157,7 @@ void computePixelDistance2d(grid_map::Matrix& squareDistance) { grid_map::Matrix initializeObstacleDistance(const grid_map::Matrix& elevationMap, float height, float resolution) { return elevationMap.unaryExpr([=](float elevation) { if (height > elevation) { - const auto diff = (height - elevation) / resolution; + const auto diff = (height - elevation) / resolution; return diff * diff; } else { return 0.0F; @@ -122,7 +169,7 @@ grid_map::Matrix initializeObstacleDistance(const grid_map::Matrix& elevationMap grid_map::Matrix initializeObstacleFreeDistance(const grid_map::Matrix& elevationMap, float height, float resolution) { return elevationMap.unaryExpr([=](float elevation) { if (height < elevation) { - const auto diff = (height - elevation) / resolution; + const auto diff = (height - elevation) / resolution; return diff * diff; } else { return 0.0F; @@ -162,9 +209,9 @@ grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, fl grid_map::Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution) { auto obstacleCount = occupancyGrid.count(); bool hasObstacles = obstacleCount > 0; - if (hasObstacles){ + if (hasObstacles) { bool hasFreeSpace = obstacleCount < occupancyGrid.size(); - if (hasFreeSpace){ + if (hasFreeSpace) { // Compute pixel distance to obstacles grid_map::Matrix sdfObstacle = occupancyGrid.unaryExpr([=](bool val) { return (val) ? 0.0F : INF; }); internal::computePixelDistance2d(sdfObstacle); From 28bf3812f8fd7e5fd7baa54b22cd876e14b3e976 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 13 Aug 2020 19:46:43 +0200 Subject: [PATCH 065/504] separate grid lookup into separate class --- .../src/DemoNode.cpp | 8 +- .../signed_distance_field/Gridmap3dLookup.h | 69 +++++++++++++++ .../SignedDistanceField.h | 13 ++- .../src/SignedDistanceField.cpp | 84 ++++++++++++------- 4 files changed, 131 insertions(+), 43 deletions(-) create mode 100644 signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp index db208601..2d8b13e2 100644 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -21,7 +21,7 @@ #include "segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h" -const std::string originFrameId_ = "odom"; +const std::string frameId_ = "odom"; std::unique_ptr messageMap; visualization_msgs::MarkerArray toMarker(const switched_model::ConvexTerrain& convexTerrain) { @@ -31,7 +31,7 @@ visualization_msgs::MarkerArray toMarker(const switched_model::ConvexTerrain& co // Add headers and Id const ros::Time timeStamp = ros::Time::now(); switched_model::assignHeader(markerArray.markers.begin(), markerArray.markers.end(), - switched_model::getHeaderMsg(originFrameId_, timeStamp)); + switched_model::getHeaderMsg(frameId_, timeStamp)); switched_model::assignIncreasingId(markerArray.markers.begin(), markerArray.markers.end()); return markerArray; @@ -41,7 +41,7 @@ visualization_msgs::Marker toMarker(const switched_model::vector3_t& position) { auto marker = switched_model::getSphereMsg(position, switched_model::Color::green, 0.02); const ros::Time timeStamp = ros::Time::now(); - marker.header = switched_model::getHeaderMsg(originFrameId_, timeStamp); + marker.header = switched_model::getHeaderMsg(frameId_, timeStamp); return marker; } @@ -110,7 +110,7 @@ int main(int argc, char** argv) { sensor_msgs::PointCloud2 pointCloud2Msg; pcl::toROSMsg(sdf.asPointCloud(), pointCloud2Msg); - pointCloud2Msg.header = switched_model::getHeaderMsg(originFrameId_, ros::Time::now()); + pointCloud2Msg.header = switched_model::getHeaderMsg(frameId_, ros::Time::now()); distanceFieldPublisher.publish(pointCloud2Msg); } diff --git a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h new file mode 100644 index 00000000..4ec61f89 --- /dev/null +++ b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h @@ -0,0 +1,69 @@ +// +// Created by rgrandia on 13.08.20. +// + +#pragma once + +#include +#include + +#include + +namespace signed_distance_field { + +/** + * Stores 3 dimensional grid information and provides methods to convert between position - 3d Index - linear index. + * + * As with grid map, the X-Y position is opposite to the row-col-index: lowest at (0,0) and highest at (n, m). + * The z-position is increasing with the layer-index. + */ +struct Gridmap3dLookup { + public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + /// size_t in 3 dimensions + struct size_t_3d { + size_t x; + size_t y; + size_t z; + }; + + size_t_3d gridsize_; + Eigen::Vector3d gridOrigin_; + double resolution_; + + /** + * Constructor + * @param gridsize : x, y, z size of the grid + * @param gridOrigin : position at x=y=z=0 + * @param resolution : (>0.0) size of 1 voxel + */ + Gridmap3dLookup(const size_t_3d& gridsize, const Eigen::Vector3d& gridOrigin, double resolution) : + gridsize_(gridsize), gridOrigin_(gridOrigin), resolution_(resolution) { + assert(resolution_ > 0.0); + }; + + /** Default constructor: creates an empty grid */ + Gridmap3dLookup() : Gridmap3dLookup({0, 0, 0}, {0.0,0.0,0.0}, 1.0) {} + + /** Returns the 3d index of the grid node closest to the query position */ + size_t_3d nearestNode(const Eigen::Vector3d& position) const noexcept { + auto round = [](double val) { + return static_cast(std::round(val)); + }; + Eigen::Vector3d subpixelVector = (position - gridOrigin_) / resolution_; + return {round(subpixelVector.x()), round(subpixelVector.y()), round(subpixelVector.z())}; + } + + /** Returns the 3d node position from a 3d index */ + Eigen::Vector3d nodePosition(const size_t_3d& index) const noexcept { + return {gridOrigin_.x() - index.x * resolution_, gridOrigin_.y() - index.y * resolution_, gridOrigin_.z() + index.z * resolution_}; + } + + /** Returns the linear node index from a 3d node index */ + size_t linearIndex(const size_t_3d& index) const noexcept { return index.z * gridsize_.y * gridsize_.x + index.y * gridsize_.x + index.x; } + + /** Linear size */ + size_t linearSize() const noexcept { return gridsize_.x * gridsize_.y * gridsize_.z; } +}; + +} // namespace signed_distance_field diff --git a/signed_distance_field/include/signed_distance_field/SignedDistanceField.h b/signed_distance_field/include/signed_distance_field/SignedDistanceField.h index e7de346b..33c5717c 100644 --- a/signed_distance_field/include/signed_distance_field/SignedDistanceField.h +++ b/signed_distance_field/include/signed_distance_field/SignedDistanceField.h @@ -14,6 +14,8 @@ #include #include +#include "Gridmap3dLookup.h" + namespace signed_distance_field { class SignedDistanceField { @@ -23,25 +25,22 @@ class SignedDistanceField { SignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, double minHeight, double maxHeight); double atPosition(const Eigen::Vector3d& position) const; + Eigen::Vector3d derivativeAtPosition(const Eigen::Vector3d& position) const; + std::pair distanceAndDerivativeAt(const Eigen::Vector3d& position) const; + pcl::PointCloud asPointCloud() const; private: void computeSignedDistance(const grid_map::Matrix& elevation); - // Must be called in ascending layers numbers [0, gridSize_[2]-1] void emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dx, const grid_map::Matrix& dy, const grid_map::Matrix& dz); - size_t nearestNode(const Eigen::Vector3d& position) const; - Eigen::Vector3d nodePosition(size_t rowX, size_t colY, size_t layerZ) const; - size_t linearIndex(size_t rowX, size_t colY, size_t layerZ) const ; using node_data_t = std::array; static double distance(const node_data_t& nodeData) noexcept { return nodeData[0]; } static Eigen::Vector3d derivative(const node_data_t& nodeData) noexcept { return {nodeData[1], nodeData[2], nodeData[3]}; } - float resolution_; - std::array gridsize_; - Eigen::Vector3d gridOrigin_; + Gridmap3dLookup gridmap3DLookup_; std::vector data_; }; diff --git a/signed_distance_field/src/SignedDistanceField.cpp b/signed_distance_field/src/SignedDistanceField.cpp index 38618ef6..d1884ff0 100644 --- a/signed_distance_field/src/SignedDistanceField.cpp +++ b/signed_distance_field/src/SignedDistanceField.cpp @@ -9,64 +9,84 @@ namespace signed_distance_field { -SignedDistanceField::SignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, double minHeight, double maxHeight) : - resolution_(static_cast(gridMap.getResolution())) { +SignedDistanceField::SignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, double minHeight, + double maxHeight) { assert(maxHeight >= minHeight); grid_map::Position mapOriginXY; gridMap.getPosition(Eigen::Vector2i(0, 0), mapOriginXY); - gridOrigin_ = {mapOriginXY.x(), mapOriginXY.y(), minHeight}; + Eigen::Vector3d gridOrigin(mapOriginXY.x(), mapOriginXY.y(), minHeight); // Take minimum of two layers to enable finite difference in Z direction - const auto numZLayers = static_cast(std::max(std::ceil((maxHeight - minHeight) / gridMap.getResolution() ), 2.0)); + const auto numZLayers = static_cast(std::max(std::ceil((maxHeight - minHeight) / gridMap.getResolution()), 2.0)); const size_t numXrows = gridMap.getSize().x(); const size_t numYrows = gridMap.getSize().y(); - gridsize_ = {numXrows, numYrows, numZLayers}; + Gridmap3dLookup::size_t_3d gridsize = {numXrows, numYrows, numZLayers}; - data_.reserve(numXrows * numYrows * numZLayers); + gridmap3DLookup_ = Gridmap3dLookup(gridsize, gridOrigin, gridMap.getResolution()); + + data_.reserve(gridmap3DLookup_.linearSize()); computeSignedDistance(gridMap.get(elevationLayer)); } -Eigen::Vector3d SignedDistanceField::nodePosition(size_t rowX, size_t colY, size_t layerZ) const { - return {gridOrigin_.x() - rowX * resolution_, gridOrigin_.y() - colY * resolution_, gridOrigin_.z() + layerZ * resolution_}; + +double SignedDistanceField::atPosition(const Eigen::Vector3d& position) const { + const auto nodeIndex = gridmap3DLookup_.nearestNode(position); + const Eigen::Vector3d nodePosition = gridmap3DLookup_.nodePosition(nodeIndex); + const node_data_t nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; + const Eigen::Vector3d jacobian = derivative(nodeData); + return distance(nodeData) + jacobian.dot(position - nodePosition); } -size_t SignedDistanceField::linearIndex(size_t rowX, size_t colY, size_t layerZ) const { - return layerZ * gridsize_[1] * gridsize_[0] + colY * gridsize_[0] + rowX; +Eigen::Vector3d SignedDistanceField::derivativeAtPosition(const Eigen::Vector3d& position) const { + const auto nodeIndex = gridmap3DLookup_.nearestNode(position); + const node_data_t nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; + return derivative(nodeData); +} + +std::pair SignedDistanceField::distanceAndDerivativeAt(const Eigen::Vector3d& position) const { + const auto nodeIndex = gridmap3DLookup_.nearestNode(position); + const Eigen::Vector3d nodePosition = gridmap3DLookup_.nodePosition(nodeIndex); + const node_data_t nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; + const Eigen::Vector3d jacobian = derivative(nodeData); + return {distance(nodeData) + jacobian.dot(position - nodePosition), jacobian}; } void SignedDistanceField::computeSignedDistance(const grid_map::Matrix& elevation) { + const auto gridOriginZ = static_cast(gridmap3DLookup_.gridOrigin_.z()); + const auto resolution = static_cast(gridmap3DLookup_.resolution_); + // First layer: forward difference in z - grid_map::Matrix currentLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOrigin_.z(), resolution_); - grid_map::Matrix nextLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOrigin_.z() + resolution_, resolution_); - grid_map::Matrix dz = signed_distance_field::layerFiniteDifference(currentLayer, nextLayer, resolution_); // dz / layer = +resolution - grid_map::Matrix dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution_); // dy / dcol = -resolution - grid_map::Matrix dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution_); // dx / drow = -resolution + grid_map::Matrix currentLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOriginZ, resolution); + grid_map::Matrix nextLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOriginZ + resolution, resolution); + grid_map::Matrix dz = signed_distance_field::layerFiniteDifference(currentLayer, nextLayer, resolution); // dz / layer = +resolution + grid_map::Matrix dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); // dy / dcol = -resolution + grid_map::Matrix dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution); // dx / drow = -resolution emplacebackLayerData(currentLayer, dx, dy, dz); // Middle layers: central difference in z - for (size_t layerZ = 1; layerZ + 1 < gridsize_[2]; ++layerZ) { + for (size_t layerZ = 1; layerZ + 1 < gridmap3DLookup_.gridsize_.z; ++layerZ) { grid_map::Matrix previousLayer = std::move(currentLayer); currentLayer = std::move(nextLayer); - nextLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOrigin_.z() + (layerZ + 1) * resolution_, resolution_); + nextLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOriginZ + (layerZ + 1) * resolution, resolution); - dz = signed_distance_field::layerCentralDifference(previousLayer, nextLayer, resolution_); - dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution_); - dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution_); + dz = signed_distance_field::layerCentralDifference(previousLayer, nextLayer, resolution); + dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); + dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution); emplacebackLayerData(currentLayer, dx, dy, dz); } // Last layer: backward difference in z grid_map::Matrix previousLayer = std::move(currentLayer); currentLayer = std::move(nextLayer); - dz = signed_distance_field::layerCentralDifference(previousLayer, currentLayer, resolution_); - dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution_); - dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution_); + dz = signed_distance_field::layerCentralDifference(previousLayer, currentLayer, resolution); + dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); + dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution); emplacebackLayerData(currentLayer, dx, dy, dz); } void SignedDistanceField::emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dx, - const grid_map::Matrix& dy, const grid_map::Matrix& dz) { - for (size_t colY=0; colY SignedDistanceField::asPointCloud() const { pcl::PointCloud points; - points.reserve(gridsize_[0]*gridsize_[1]*gridsize_[2]); - for (size_t layerZ=0; layerZ Date: Fri, 14 Aug 2020 11:10:22 +0200 Subject: [PATCH 066/504] add different pointcloud views to sdf --- .../src/DemoNode.cpp | 2 +- .../SignedDistanceField.h | 27 ++++++++++++-- .../src/SignedDistanceField.cpp | 37 +++++++++++++------ 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp index 2d8b13e2..d716059f 100644 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -109,7 +109,7 @@ int main(int argc, char** argv) { std::cout << "Sdf computation took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]\n"; sensor_msgs::PointCloud2 pointCloud2Msg; - pcl::toROSMsg(sdf.asPointCloud(), pointCloud2Msg); + pcl::toROSMsg(sdf.obstaclePointCloud(4), pointCloud2Msg); pointCloud2Msg.header = switched_model::getHeaderMsg(frameId_, ros::Time::now()); distanceFieldPublisher.publish(pointCloud2Msg); diff --git a/signed_distance_field/include/signed_distance_field/SignedDistanceField.h b/signed_distance_field/include/signed_distance_field/SignedDistanceField.h index 33c5717c..453345c2 100644 --- a/signed_distance_field/include/signed_distance_field/SignedDistanceField.h +++ b/signed_distance_field/include/signed_distance_field/SignedDistanceField.h @@ -8,11 +8,11 @@ #include -#include #include +#include -#include #include +#include #include "Gridmap3dLookup.h" @@ -30,11 +30,30 @@ class SignedDistanceField { std::pair distanceAndDerivativeAt(const Eigen::Vector3d& position) const; - pcl::PointCloud asPointCloud() const; + /** + * Return the signed distance field as a pointcloud. The signed distance is assigned to the point's intensity. + * @param decimation : specifies how many points are returned. 1: all points, 2: every second point, etc. + * @param condition : specifies the condition on the distance value to add it to the pointcloud (default = any distance is added) + */ + pcl::PointCloud asPointCloud( + size_t decimation = 1, const std::function& condition = [](float) { return true; }) const; + + /** + * Return the signed distance field as a pointcloud where the distance is positive. + * @param decimation : specifies how many points are returned. 1: all points, 2: every second point, etc. + */ + pcl::PointCloud freeSpacePointCloud(size_t decimation = 1) const; + + /** + * Return the signed distance field as a pointcloud where the distance is negative. + * @param decimation : specifies how many points are returned. 1: all points, 2: every second point, etc. + */ + pcl::PointCloud obstaclePointCloud(size_t decimation = 1) const; private: void computeSignedDistance(const grid_map::Matrix& elevation); - void emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dx, const grid_map::Matrix& dy, const grid_map::Matrix& dz); + void emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dx, const grid_map::Matrix& dy, + const grid_map::Matrix& dz); using node_data_t = std::array; static double distance(const node_data_t& nodeData) noexcept { return nodeData[0]; } diff --git a/signed_distance_field/src/SignedDistanceField.cpp b/signed_distance_field/src/SignedDistanceField.cpp index d1884ff0..21736102 100644 --- a/signed_distance_field/src/SignedDistanceField.cpp +++ b/signed_distance_field/src/SignedDistanceField.cpp @@ -92,24 +92,37 @@ void SignedDistanceField::emplacebackLayerData(const grid_map::Matrix& signedDis } } -pcl::PointCloud SignedDistanceField::asPointCloud() const { +pcl::PointCloud SignedDistanceField::asPointCloud(size_t decimation, const std::function& condition) const { pcl::PointCloud points; points.reserve(gridmap3DLookup_.linearSize()); - for (size_t layerZ = 0; layerZ < gridmap3DLookup_.gridsize_.z; ++layerZ) { - for (size_t colY = 0; colY < gridmap3DLookup_.gridsize_.y; ++colY) { - for (size_t rowX = 0; rowX < gridmap3DLookup_.gridsize_.x; ++rowX) { - const auto index = gridmap3DLookup_.linearIndex({rowX, colY, layerZ}); - const auto p = gridmap3DLookup_.nodePosition({rowX, colY, layerZ}); - pcl::PointXYZI point; - point.x = p.x(); - point.y = p.y(); - point.z = p.z(); - point.intensity = data_[index][0]; - points.push_back(point); + for (size_t layerZ = 0; layerZ < gridmap3DLookup_.gridsize_.z; layerZ+=decimation) { + for (size_t colY = 0; colY < gridmap3DLookup_.gridsize_.y; colY+=decimation) { + for (size_t rowX = 0; rowX < gridmap3DLookup_.gridsize_.x; rowX+=decimation) { + const Gridmap3dLookup::size_t_3d index3d = {rowX, colY, layerZ}; + const auto index = gridmap3DLookup_.linearIndex(index3d); + const auto signeddistance = distance(data_[index]); + if (condition(signeddistance)) { + const auto p = gridmap3DLookup_.nodePosition(index3d); + pcl::PointXYZI point; + point.x = p.x(); + point.y = p.y(); + point.z = p.z(); + point.intensity = signeddistance; + points.push_back(point); + } + } } } return points; } +pcl::PointCloud SignedDistanceField::freeSpacePointCloud(size_t decimation) const { + return asPointCloud(decimation, [](float signedDistance){return signedDistance >=0.0F; }); +} + +pcl::PointCloud SignedDistanceField::obstaclePointCloud(size_t decimation) const { + return asPointCloud(decimation, [](float signedDistance){return signedDistance <=0.0F; }); +} + } // namespace signed_distance_field From d7b6811a50648631dc66c5dc3f28f0bc07a86aea Mon Sep 17 00:00:00 2001 From: rgrandia Date: Fri, 14 Aug 2020 15:41:05 +0200 Subject: [PATCH 067/504] add signed distance to the terrain model, add gridmap to the planarTerrain message --- .../convex_plane_decomposition/PlanarRegion.h | 7 +- .../CMakeLists.txt | 3 +- .../msg/PlanarTerrain.msg | 3 +- convex_plane_decomposition_msgs/package.xml | 1 + .../src/ConvexPlaneDecompositionRos.cpp | 20 +-- .../src/MessageConversion.cpp | 12 +- .../SegmentedPlanesTerrainModel.h | 6 +- .../src/DemoNode.cpp | 15 +- .../src/SegmentedPlanesTerrainModel.cpp | 12 +- .../test/signedDistanceTest.cpp | 131 +----------------- signed_distance_field/CMakeLists.txt | 3 +- ...ceField.h => GridmapSignedDistanceField.h} | 17 ++- signed_distance_field/package.xml | 1 + ...eld.cpp => GridmapSignedDistanceField.cpp} | 44 +++--- 14 files changed, 91 insertions(+), 184 deletions(-) rename signed_distance_field/include/signed_distance_field/{SignedDistanceField.h => GridmapSignedDistanceField.h} (73%) rename signed_distance_field/src/{SignedDistanceField.cpp => GridmapSignedDistanceField.cpp} (71%) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h b/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h index eb7cd415..d7091e14 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h @@ -6,6 +6,8 @@ #include +#include + #include #include "PolygonTypes.h" @@ -33,6 +35,9 @@ struct PlanarRegion { TerrainPlane planeParameters; }; -using PlanarTerrain = std::vector; +struct PlanarTerrain { + std::vector planarRegions; + grid_map::GridMap gridMap; +}; } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_msgs/CMakeLists.txt b/convex_plane_decomposition_msgs/CMakeLists.txt index ebf14939..12f1b2b4 100644 --- a/convex_plane_decomposition_msgs/CMakeLists.txt +++ b/convex_plane_decomposition_msgs/CMakeLists.txt @@ -4,6 +4,7 @@ project(convex_plane_decomposition_msgs) set(CATKIN_PACKAGE_DEPENDENCIES std_msgs geometry_msgs + grid_map_msgs ) find_package(catkin REQUIRED @@ -30,5 +31,5 @@ generate_messages( catkin_package( CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} - message_runtime + message_runtime ) diff --git a/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg b/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg index c48da4ba..c50376ee 100644 --- a/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg +++ b/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg @@ -1 +1,2 @@ -PlanarRegion[] planarRegions \ No newline at end of file +PlanarRegion[] planarRegions +grid_map_msgs/GridMap gridmap \ No newline at end of file diff --git a/convex_plane_decomposition_msgs/package.xml b/convex_plane_decomposition_msgs/package.xml index 295c4157..3e20ee3b 100644 --- a/convex_plane_decomposition_msgs/package.xml +++ b/convex_plane_decomposition_msgs/package.xml @@ -15,6 +15,7 @@ std_msgs geometry_msgs + grid_map_msgs message_runtime diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index bf9bae7f..e63edc83 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -106,25 +106,29 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { auto t2 = std::chrono::high_resolution_clock::now(); ROS_INFO_STREAM("Sliding window took " << 1e-3 * std::chrono::duration_cast(t2 - t1).count() << " [ms]"); - const auto planarRegions = contourExtraction_->extractPlanarRegions(slidingWindowPlaneExtractor_->getSegmentedPlanesMap()); + PlanarTerrain planarTerrain; + planarTerrain.planarRegions = contourExtraction_->extractPlanarRegions(slidingWindowPlaneExtractor_->getSegmentedPlanesMap()); auto t3 = std::chrono::high_resolution_clock::now(); ROS_INFO_STREAM("Contour extraction took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]"); + // Add grid map to the terrain + planarTerrain.gridMap = std::move(elevationMap); + // Publish terrain if (publishToController_) { - regionPublisher_.publish(toMessage(planarRegions)); + regionPublisher_.publish(toMessage(planarTerrain)); } // Visualize in Rviz. - reapplyNans(elevationMap.get(elevationLayer_)); - elevationMap.add("segmentation"); - cv::cv2eigen(slidingWindowPlaneExtractor_->getSegmentedPlanesMap().labeledImage, elevationMap.get("segmentation")); + reapplyNans(planarTerrain.gridMap.get(elevationLayer_)); + planarTerrain.gridMap.add("segmentation"); + cv::cv2eigen(slidingWindowPlaneExtractor_->getSegmentedPlanesMap().labeledImage, planarTerrain.gridMap.get("segmentation")); grid_map_msgs::GridMap outputMessage; - grid_map::GridMapRosConverter::toMessage(elevationMap, outputMessage); + grid_map::GridMapRosConverter::toMessage(planarTerrain.gridMap, outputMessage); filteredmapPublisher_.publish(outputMessage); - boundaryPublisher_.publish(convertBoundariesToRosPolygons(planarRegions, elevationMap.getFrameId())); - insetPublisher_.publish(convertInsetsToRosPolygons(planarRegions, elevationMap.getFrameId())); + boundaryPublisher_.publish(convertBoundariesToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId())); + insetPublisher_.publish(convertInsetsToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId())); } else { ROS_WARN("[ConvexPlaneExtractionROS] Could not extract submap"); } diff --git a/convex_plane_decomposition_ros/src/MessageConversion.cpp b/convex_plane_decomposition_ros/src/MessageConversion.cpp index d60e47de..1e44dae2 100644 --- a/convex_plane_decomposition_ros/src/MessageConversion.cpp +++ b/convex_plane_decomposition_ros/src/MessageConversion.cpp @@ -4,6 +4,8 @@ #include "convex_plane_decomposition_ros/MessageConversion.h" +#include + namespace convex_plane_decomposition { CgalBbox2d fromMessage(const convex_plane_decomposition_msgs::BoundingBox2d& msg) { @@ -45,19 +47,21 @@ convex_plane_decomposition_msgs::PlanarRegion toMessage(const PlanarRegion& plan PlanarTerrain fromMessage(const convex_plane_decomposition_msgs::PlanarTerrain& msg) { PlanarTerrain planarTerrain; - planarTerrain.reserve(msg.planarRegions.size()); + planarTerrain.planarRegions.reserve(msg.planarRegions.size()); for (const auto& planarRegion : msg.planarRegions) { - planarTerrain.emplace_back(fromMessage(planarRegion)); + planarTerrain.planarRegions.emplace_back(fromMessage(planarRegion)); } + grid_map::GridMapRosConverter::fromMessage(msg.gridmap, planarTerrain.gridMap); return planarTerrain; } convex_plane_decomposition_msgs::PlanarTerrain toMessage(const PlanarTerrain& planarTerrain) { convex_plane_decomposition_msgs::PlanarTerrain msg; - msg.planarRegions.reserve(planarTerrain.size()); - for (const auto& planarRegion : planarTerrain) { + msg.planarRegions.reserve(planarTerrain.planarRegions.size()); + for (const auto& planarRegion : planarTerrain.planarRegions) { msg.planarRegions.emplace_back(toMessage(planarRegion)); } + grid_map::GridMapRosConverter::toMessage(planarTerrain.gridMap, msg.gridmap); return msg; } diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h index ace46075..0ce10ec6 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h @@ -17,13 +17,15 @@ class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { ConvexTerrain getConvexTerrainAtPositionInWorld(const vector3_t& positionInWorld) const override; - const convex_plane_decomposition::PlanarTerrain& PlanarTerrain() const { return planarTerrain_; } + const SignedDistanceField* getSignedDistanceField() const override { return nullptr; } + + const convex_plane_decomposition::PlanarTerrain& planarTerrain() const { return planarTerrain_; } private: convex_plane_decomposition::PlanarTerrain planarTerrain_; }; std::pair getPlanarRegionAtPositionInWorld( - const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarTerrain& planarTerrain); + const vector3_t& positionInWorld, const std::vector& planarRegions); } // namespace switched_model diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp index d716059f..b9ae9d7d 100644 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -10,12 +10,12 @@ #include #include +#include +#include +#include #include #include #include -#include -#include -#include #include @@ -96,18 +96,21 @@ int main(int argc, char** argv) { positionPublisher_.publish(toMarker(positionInWorld)); convexTerrainPublisher_.publish(toMarker(convexTerrain)); - - double heightClearance = 0.35; double width = 1.5; double length = 2.0; bool success; grid_map::GridMap localMap = messageMap->getSubmap({convexTerrain.plane.positionInWorld.x(), convexTerrain.plane.positionInWorld.y()}, Eigen::Array2d(width, length), success); auto t2 = std::chrono::high_resolution_clock::now(); - signed_distance_field::SignedDistanceField sdf(localMap, "elevation", convexTerrain.plane.positionInWorld.z() - heightClearance, convexTerrain.plane.positionInWorld.z() + heightClearance); + signed_distance_field::GridmapSignedDistanceField sdf(localMap, "elevation", convexTerrain.plane.positionInWorld.z() - heightClearance, convexTerrain.plane.positionInWorld.z() + heightClearance); auto t3 = std::chrono::high_resolution_clock::now(); std::cout << "Sdf computation took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]\n"; + auto t4 = std::chrono::high_resolution_clock::now(); + auto sdfClone = std::unique_ptr(sdf.clone()); + auto t5 = std::chrono::high_resolution_clock::now(); + std::cout << "Sdf.clone() computation took " << 1e-3 * std::chrono::duration_cast(t5 - t4).count() << " [ms]\n"; + sensor_msgs::PointCloud2 pointCloud2Msg; pcl::toROSMsg(sdf.obstaclePointCloud(4), pointCloud2Msg); pointCloud2Msg.header = switched_model::getHeaderMsg(frameId_, ros::Time::now()); diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index ec958a2d..9a65d5e4 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -40,7 +40,7 @@ SegmentedPlanesTerrainModel::SegmentedPlanesTerrainModel(convex_plane_decomposit : planarTerrain_(std::move(planarTerrain)) {} TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorldAlongGravity(const vector3_t& positionInWorld) const { - const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_); + const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions); const auto& region = *regionAndSeedPoint.first; const auto& seedpoint = regionAndSeedPoint.second; const auto& seedpointInWorldFrame = @@ -49,7 +49,7 @@ TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorldAlongG } ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld(const vector3_t& positionInWorld) const { - const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_); + const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions); const auto& region = *regionAndSeedPoint.first; const auto& seedpoint = regionAndSeedPoint.second; const auto& seedpointInWorldFrame = @@ -111,7 +111,7 @@ std::pair squaredDistanceToBoun const convex_plane_decomposition::CgalPoint2d queryProjectedToPlane{positionInTerrainFrame.x(), positionInTerrainFrame.y()}; // First search if the projected point is inside any of the insets. - const auto insetPtrContainingPoint = findInsetContainingThePoint(queryProjectedToPlane, planarRegion.boundaryWithInset.insets); + const auto* const insetPtrContainingPoint = findInsetContainingThePoint(queryProjectedToPlane, planarRegion.boundaryWithInset.insets); // Compute the projection convex_plane_decomposition::CgalPoint2d projectedPoint; @@ -143,11 +143,11 @@ std::pair squaredDistanceToBoun } std::pair getPlanarRegionAtPositionInWorld( - const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarTerrain& planarTerrain) { + const vector3_t& positionInWorld, const std::vector& planarRegions) { // Compute distance to bounding boxes std::vector> regionsAndBboxSquareDistances; - regionsAndBboxSquareDistances.reserve(planarTerrain.size()); - for (const auto& planarRegion : planarTerrain) { + regionsAndBboxSquareDistances.reserve(planarRegions.size()); + for (const auto& planarRegion : planarRegions) { double squareDistance = squaredDistanceToBoundingBox(positionInWorld, planarRegion); regionsAndBboxSquareDistances.emplace_back(&planarRegion, distanceCostLowerbound(squareDistance)); } diff --git a/segmented_planes_terrain_model/test/signedDistanceTest.cpp b/segmented_planes_terrain_model/test/signedDistanceTest.cpp index 0ead6ebe..b58a3964 100644 --- a/segmented_planes_terrain_model/test/signedDistanceTest.cpp +++ b/segmented_planes_terrain_model/test/signedDistanceTest.cpp @@ -8,16 +8,14 @@ #include #include +#include #include -#include #include #include -#include #include using namespace distance_transform; -constexpr float myINF = 1e20F; grid_map::GridMap loadElevationMapFromFile(const std::string& filePath, double resolution, double scale) { // Read the file @@ -40,131 +38,6 @@ grid_map::GridMap loadElevationMapFromFile(const std::string& filePath, double r return mapOut; } -grid_map::Matrix getPlanarSignedDistanceField(const Eigen::Matrix& data) { - image* input = new image(data.rows(), data.cols(), true); - - for (int y = 0; y < input->height(); y++) { - for (int x = 0; x < input->width(); x++) { - imRef(input, x, y) = data(x, y); - } - } - - // Compute dt. - image* out = dt(input); - - grid_map::Matrix result(data.rows(), data.cols()); - - // Take square roots. - for (int y = 0; y < out->height(); y++) { - for (int x = 0; x < out->width(); x++) { - result(x, y) = sqrt(imRef(out, x, y)); - } - } - return result; -} - -void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDistance1d, Eigen::Ref d, - Eigen::Ref z, std::vector& v) { - const int n = squareDistance1d.size(); - const auto& f = squareDistance1d; - assert(d.size() == n); - assert(z.size() == n + 1); - assert(v.size() == n); - - // Initialize - int k = 0; - v[0] = 0; - z[0] = -myINF; - z[1] = myINF; - - // Compute bounds - for (int q = 1; q < n; q++) { - auto factor1 = static_cast(q - v[k]); - auto factor2 = static_cast(q + v[k]); - float s = 0.5F * ( (f[q] - f[v[k]]) / factor1 + factor2); - while (s <= z[k]) { - k--; - factor1 = static_cast(q - v[k]); - factor2 = static_cast(q + v[k]); - s = 0.5F * ( (f[q] - f[v[k]]) / factor1 + factor2); - } - k++; - v[k] = q; - z[k] = s; - z[k + 1] = myINF; - } - - // Collect results - k = 0; - for (int q = 0; q < n; q++) { - while (z[k + 1] < static_cast(q)) { - k++; - } - d[q] = square(q - v[k]) + f[v[k]]; - } - - // Write distance result back in place - squareDistance1d = d; -} - -void squaredDistanceTransform_2d_columnwiseInplace(grid_map::Matrix& squareDistance, bool skipCheck) { - const size_t n = squareDistance.cols(); - Eigen::VectorXf workvector(2 * n + 1); - std::vector intWorkvector(n); - - for (size_t i = 0; i < n; i++) { - // Only when there is a mix of elements and free space, we need to update the initialized distance. - bool needsComputation = skipCheck || ((squareDistance.col(i).array() == 0.0).any() && (squareDistance.col(i).array() == myINF).any()); - if (needsComputation) { - squaredDistanceTransform_1d_inplace(squareDistance.col(i), workvector.segment(0, n), workvector.segment(n, n+1), - intWorkvector); - } - } -} - -void squaredDistanceTransform_2d(grid_map::Matrix& squareDistance) { - // TODO (check which one we want to do first) - - // Process columns - squaredDistanceTransform_2d_columnwiseInplace(squareDistance, false); - - // Process rows - squareDistance.transposeInPlace(); - squaredDistanceTransform_2d_columnwiseInplace(squareDistance, true); - squareDistance.transposeInPlace(); -} - -void getPlanarSignedDistanceField_2(grid_map::Matrix& squareDistance) { - squaredDistanceTransform_2d(squareDistance); - squareDistance = squareDistance.cwiseSqrt(); -} - -grid_map::Matrix getPlanarSignedDistanceField_3(const grid_map::Matrix& map, float threshold, float resolution) { - bool hasObstacles = (map.array() >= threshold).any(); - if (hasObstacles) { - bool hasFreeSpace = (map.array() < threshold).any(); - if (hasFreeSpace) { - // Both obstacles and free space -> compute planar signed distance - // Compute pixel distance to obstacles - grid_map::Matrix sdfObstacle = map.unaryExpr([=](float val) {return (val >= threshold) ? 0.0F : myINF;}); - getPlanarSignedDistanceField_2(sdfObstacle); - - // Compute pixel distance to obstacle free space - grid_map::Matrix sdfObstacleFree = map.unaryExpr([=](float val) {return (val < threshold) ? 0.0F : myINF;}); - getPlanarSignedDistanceField_2(sdfObstacleFree); - - grid_map::Matrix sdf2d = resolution * (sdfObstacle - sdfObstacleFree); - return sdf2d; - } else { - // Only obstacles -> distance is zero everywhere - return grid_map::Matrix::Zero(map.rows(), map.cols()); - } - } else { - // No obstacles -> planar distance is infinite - return grid_map::Matrix::Constant(map.rows(), map.cols(), myINF); - } -} - int main(int argc, char** argv) { std::string folder = "/home/rgrandia/git/anymal/convex_terrain_representation/convex_plane_decomposition_ros/data/"; // std::string file = "elevationMap_8_139cm.png"; @@ -230,7 +103,7 @@ int main(int argc, char** argv) { // for (float h = minHeight; h < maxHeight; h += resolution_) { // data_.emplace_back(signed_distance_field::signedDistanceAtHeight(map, h, resolution)); // } - auto sdf = signed_distance_field::SignedDistanceField(gridMap, layer, minHeight, maxHeight); + signed_distance_field::GridmapSignedDistanceField sdf(gridMap, layer, minHeight, maxHeight); // ========================================================= } diff --git a/signed_distance_field/CMakeLists.txt b/signed_distance_field/CMakeLists.txt index b324e0a1..bd3fda80 100644 --- a/signed_distance_field/CMakeLists.txt +++ b/signed_distance_field/CMakeLists.txt @@ -5,6 +5,7 @@ project(signed_distance_field) set(CATKIN_PACKAGE_DEPENDENCIES grid_map_core pcl_ros + ocs2_switched_model_interface ) find_package(catkin REQUIRED COMPONENTS @@ -36,7 +37,7 @@ include_directories( add_library(${PROJECT_NAME} src/PixelBorderDistance.cpp - src/SignedDistanceField.cpp + src/GridmapSignedDistanceField.cpp src/SignedDistance2d.cpp ) add_dependencies(${PROJECT_NAME} diff --git a/signed_distance_field/include/signed_distance_field/SignedDistanceField.h b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h similarity index 73% rename from signed_distance_field/include/signed_distance_field/SignedDistanceField.h rename to signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h index 453345c2..e7da9cf5 100644 --- a/signed_distance_field/include/signed_distance_field/SignedDistanceField.h +++ b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h @@ -14,21 +14,23 @@ #include #include +#include + #include "Gridmap3dLookup.h" namespace signed_distance_field { -class SignedDistanceField { +class GridmapSignedDistanceField : public switched_model::SignedDistanceField { public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW - SignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, double minHeight, double maxHeight); - - double atPosition(const Eigen::Vector3d& position) const; - - Eigen::Vector3d derivativeAtPosition(const Eigen::Vector3d& position) const; + GridmapSignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, double minHeight, double maxHeight); + GridmapSignedDistanceField* clone() const override; - std::pair distanceAndDerivativeAt(const Eigen::Vector3d& position) const; + switched_model::scalar_t value(const switched_model::vector3_t& position) const override; + switched_model::vector3_t derivative(const switched_model::vector3_t& position) const override; + std::pair valueAndDerivative( + const switched_model::vector3_t& position) const override; /** * Return the signed distance field as a pointcloud. The signed distance is assigned to the point's intensity. @@ -51,6 +53,7 @@ class SignedDistanceField { pcl::PointCloud obstaclePointCloud(size_t decimation = 1) const; private: + GridmapSignedDistanceField(const GridmapSignedDistanceField& other); void computeSignedDistance(const grid_map::Matrix& elevation); void emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dx, const grid_map::Matrix& dy, const grid_map::Matrix& dz); diff --git a/signed_distance_field/package.xml b/signed_distance_field/package.xml index a6ba2663..86d78b3a 100644 --- a/signed_distance_field/package.xml +++ b/signed_distance_field/package.xml @@ -12,5 +12,6 @@ grid_map_core pcl_ros + ocs2_switched_model_interface diff --git a/signed_distance_field/src/SignedDistanceField.cpp b/signed_distance_field/src/GridmapSignedDistanceField.cpp similarity index 71% rename from signed_distance_field/src/SignedDistanceField.cpp rename to signed_distance_field/src/GridmapSignedDistanceField.cpp index 21736102..bb959f94 100644 --- a/signed_distance_field/src/SignedDistanceField.cpp +++ b/signed_distance_field/src/GridmapSignedDistanceField.cpp @@ -2,15 +2,15 @@ // Created by rgrandia on 10.07.20. // -#include "signed_distance_field/SignedDistanceField.h" +#include "signed_distance_field/GridmapSignedDistanceField.h" #include "signed_distance_field/DistanceDerivatives.h" #include "signed_distance_field/SignedDistance2d.h" namespace signed_distance_field { -SignedDistanceField::SignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, double minHeight, - double maxHeight) { +GridmapSignedDistanceField::GridmapSignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, + double minHeight, double maxHeight) { assert(maxHeight >= minHeight); grid_map::Position mapOriginXY; gridMap.getPosition(Eigen::Vector2i(0, 0), mapOriginXY); @@ -28,7 +28,14 @@ SignedDistanceField::SignedDistanceField(const grid_map::GridMap& gridMap, const computeSignedDistance(gridMap.get(elevationLayer)); } -double SignedDistanceField::atPosition(const Eigen::Vector3d& position) const { +GridmapSignedDistanceField::GridmapSignedDistanceField(const GridmapSignedDistanceField& other) + : gridmap3DLookup_(other.gridmap3DLookup_), data_(other.data_) {} + +GridmapSignedDistanceField* GridmapSignedDistanceField::clone() const { + return new GridmapSignedDistanceField(*this); +} + +switched_model::scalar_t GridmapSignedDistanceField::value(const switched_model::vector3_t& position) const { const auto nodeIndex = gridmap3DLookup_.nearestNode(position); const Eigen::Vector3d nodePosition = gridmap3DLookup_.nodePosition(nodeIndex); const node_data_t nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; @@ -36,13 +43,14 @@ double SignedDistanceField::atPosition(const Eigen::Vector3d& position) const { return distance(nodeData) + jacobian.dot(position - nodePosition); } -Eigen::Vector3d SignedDistanceField::derivativeAtPosition(const Eigen::Vector3d& position) const { +switched_model::vector3_t GridmapSignedDistanceField::derivative(const switched_model::vector3_t& position) const { const auto nodeIndex = gridmap3DLookup_.nearestNode(position); const node_data_t nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; return derivative(nodeData); } -std::pair SignedDistanceField::distanceAndDerivativeAt(const Eigen::Vector3d& position) const { +std::pair GridmapSignedDistanceField::valueAndDerivative( + const switched_model::vector3_t& position) const { const auto nodeIndex = gridmap3DLookup_.nearestNode(position); const Eigen::Vector3d nodePosition = gridmap3DLookup_.nodePosition(nodeIndex); const node_data_t nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; @@ -50,7 +58,7 @@ std::pair SignedDistanceField::distanceAndDerivativeAt( return {distance(nodeData) + jacobian.dot(position - nodePosition), jacobian}; } -void SignedDistanceField::computeSignedDistance(const grid_map::Matrix& elevation) { +void GridmapSignedDistanceField::computeSignedDistance(const grid_map::Matrix& elevation) { const auto gridOriginZ = static_cast(gridmap3DLookup_.gridOrigin_.z()); const auto resolution = static_cast(gridmap3DLookup_.resolution_); @@ -83,8 +91,8 @@ void SignedDistanceField::computeSignedDistance(const grid_map::Matrix& elevatio emplacebackLayerData(currentLayer, dx, dy, dz); } -void SignedDistanceField::emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dx, - const grid_map::Matrix& dy, const grid_map::Matrix& dz) { +void GridmapSignedDistanceField::emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dx, + const grid_map::Matrix& dy, const grid_map::Matrix& dz) { for (size_t colY = 0; colY < gridmap3DLookup_.gridsize_.y; ++colY) { for (size_t rowX = 0; rowX < gridmap3DLookup_.gridsize_.x; ++rowX) { data_.emplace_back(node_data_t{signedDistance(rowX, colY), dx(rowX, colY), dy(rowX, colY), dz(rowX, colY)}); @@ -92,12 +100,13 @@ void SignedDistanceField::emplacebackLayerData(const grid_map::Matrix& signedDis } } -pcl::PointCloud SignedDistanceField::asPointCloud(size_t decimation, const std::function& condition) const { +pcl::PointCloud GridmapSignedDistanceField::asPointCloud(size_t decimation, + const std::function& condition) const { pcl::PointCloud points; points.reserve(gridmap3DLookup_.linearSize()); - for (size_t layerZ = 0; layerZ < gridmap3DLookup_.gridsize_.z; layerZ+=decimation) { - for (size_t colY = 0; colY < gridmap3DLookup_.gridsize_.y; colY+=decimation) { - for (size_t rowX = 0; rowX < gridmap3DLookup_.gridsize_.x; rowX+=decimation) { + for (size_t layerZ = 0; layerZ < gridmap3DLookup_.gridsize_.z; layerZ += decimation) { + for (size_t colY = 0; colY < gridmap3DLookup_.gridsize_.y; colY += decimation) { + for (size_t rowX = 0; rowX < gridmap3DLookup_.gridsize_.x; rowX += decimation) { const Gridmap3dLookup::size_t_3d index3d = {rowX, colY, layerZ}; const auto index = gridmap3DLookup_.linearIndex(index3d); const auto signeddistance = distance(data_[index]); @@ -110,19 +119,18 @@ pcl::PointCloud SignedDistanceField::asPointCloud(size_t decimat point.intensity = signeddistance; points.push_back(point); } - } } } return points; } -pcl::PointCloud SignedDistanceField::freeSpacePointCloud(size_t decimation) const { - return asPointCloud(decimation, [](float signedDistance){return signedDistance >=0.0F; }); +pcl::PointCloud GridmapSignedDistanceField::freeSpacePointCloud(size_t decimation) const { + return asPointCloud(decimation, [](float signedDistance) { return signedDistance >= 0.0F; }); } -pcl::PointCloud SignedDistanceField::obstaclePointCloud(size_t decimation) const { - return asPointCloud(decimation, [](float signedDistance){return signedDistance <=0.0F; }); +pcl::PointCloud GridmapSignedDistanceField::obstaclePointCloud(size_t decimation) const { + return asPointCloud(decimation, [](float signedDistance) { return signedDistance <= 0.0F; }); } } // namespace signed_distance_field From 4e2d6e89d0ce0917a8262413b85f761922525436 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 17 Aug 2020 18:20:08 +0200 Subject: [PATCH 068/504] add signed distance communication and publishing --- .../SegmentedPlanesTerrainModel.h | 7 ++- .../SegmentedPlanesTerrainModelRos.h | 18 +++++++ .../src/SegmentedPlanesTerrainModel.cpp | 17 +++++- .../src/SegmentedPlanesTerrainModelRos.cpp | 54 +++++++++++++++++-- 4 files changed, 90 insertions(+), 6 deletions(-) diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h index 0ce10ec6..b83c8262 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h @@ -7,6 +7,8 @@ #include #include +#include + namespace switched_model { class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { @@ -17,12 +19,15 @@ class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { ConvexTerrain getConvexTerrainAtPositionInWorld(const vector3_t& positionInWorld) const override; - const SignedDistanceField* getSignedDistanceField() const override { return nullptr; } + void createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, const Eigen::Vector3d& maxCoordinates); + + const signed_distance_field::GridmapSignedDistanceField* getSignedDistanceField() const override { return signedDistanceField_.get(); } const convex_plane_decomposition::PlanarTerrain& planarTerrain() const { return planarTerrain_; } private: convex_plane_decomposition::PlanarTerrain planarTerrain_; + std::unique_ptr signedDistanceField_; }; std::pair getPlanarRegionAtPositionInWorld( diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h index c55bfcfd..3f9cc207 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h @@ -8,6 +8,9 @@ #include +#include +#include + #include #include "SegmentedPlanesTerrainModel.h" @@ -16,18 +19,33 @@ namespace switched_model { class SegmentedPlanesTerrainModelRos { public: + std::string frameId_ = "odom"; + SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle); /// Updates the terrain if a new one is available. Return if an update was made bool update(std::unique_ptr& terrainPtr); + void createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, const Eigen::Vector3d& maxCoordinates); + + void publish(); + private: void callback(const convex_plane_decomposition_msgs::PlanarTerrain::ConstPtr& msg); ros::Subscriber terrainSubscriber_; + ros::Publisher distanceFieldPublisher_; + std::mutex updateMutex_; std::atomic_bool terrainUpdated_; std::unique_ptr terrainPtr_; + + std::mutex updateCoordinatesMutex_; + Eigen::Vector3d minCoordinates_; + Eigen::Vector3d maxCoordinates_; + + std::mutex pointCloudMutex_; + pcl::PointCloud pointCloud_; }; } // namespace switched_model diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index 9a65d5e4..aeb225cc 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -8,6 +8,7 @@ #include #include +#include namespace switched_model { @@ -37,7 +38,7 @@ double distanceCostLowerbound(double distanceSquared) { } SegmentedPlanesTerrainModel::SegmentedPlanesTerrainModel(convex_plane_decomposition::PlanarTerrain planarTerrain) - : planarTerrain_(std::move(planarTerrain)) {} + : planarTerrain_(std::move(planarTerrain)), signedDistanceField_(nullptr) {} TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorldAlongGravity(const vector3_t& positionInWorld) const { const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions); @@ -71,6 +72,20 @@ ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld(con return convexTerrain; } +void SegmentedPlanesTerrainModel::createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, + const Eigen::Vector3d& maxCoordinates) { + Eigen::Vector3d centerCoordinates = 0.5 * (minCoordinates + maxCoordinates); + Eigen::Vector3d lengths = maxCoordinates - minCoordinates; + + bool success = true; + grid_map::GridMap subMap = + planarTerrain_.gridMap.getSubmap({centerCoordinates.x(), centerCoordinates.y()}, Eigen::Array2d(lengths.x(), lengths.y()), success); + if (success) { + signedDistanceField_ = + std::make_unique(subMap, "elevation", minCoordinates.z(), maxCoordinates.z()); + } +} + double singleSidedSquaredDistance(double value, double min, double max) { // - | 0 | + // min max diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp index 4fd04973..0fccb2f8 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp @@ -4,13 +4,18 @@ #include "segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h" +#include +#include + #include +#include namespace switched_model { -SegmentedPlanesTerrainModelRos::SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle) : terrainUpdated_(false) { +SegmentedPlanesTerrainModelRos::SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle) : terrainUpdated_(false), minCoordinates_(Eigen::Vector3d::Zero()), maxCoordinates_(Eigen::Vector3d::Zero()) { terrainSubscriber_ = nodehandle.subscribe("/convex_plane_decomposition_ros/planar_terrain", 1, &SegmentedPlanesTerrainModelRos::callback, this); + distanceFieldPublisher_ = nodehandle.advertise("/convex_plane_decomposition_ros/signed_distance_field", 1); } bool SegmentedPlanesTerrainModelRos::update(std::unique_ptr& terrainPtr) { @@ -26,10 +31,51 @@ bool SegmentedPlanesTerrainModelRos::update(std::unique_ptr lock(updateCoordinatesMutex_); + minCoordinates_ = minCoordinates; + maxCoordinates_ = maxCoordinates; +} + +void SegmentedPlanesTerrainModelRos::publish() { + sensor_msgs::PointCloud2 pointCloud2Msg; + { + std::lock_guard lock(pointCloudMutex_); + pcl::toROSMsg(pointCloud_, pointCloud2Msg); + } + + pointCloud2Msg.header = switched_model::getHeaderMsg(frameId_, ros::Time::now()); + distanceFieldPublisher_.publish(pointCloud2Msg); +} + void SegmentedPlanesTerrainModelRos::callback(const convex_plane_decomposition_msgs::PlanarTerrain::ConstPtr& msg) { - std::lock_guard lock(updateMutex_); - terrainPtr_ = std::make_unique(convex_plane_decomposition::fromMessage(*msg)); - terrainUpdated_ = true; + // Read terrain + auto terrainPtr = std::make_unique(convex_plane_decomposition::fromMessage(*msg)); + + // Extract coordinates for signed distance field + Eigen::Vector3d minCoordinates; + Eigen::Vector3d maxCoordinates; + { + std::lock_guard lock(updateCoordinatesMutex_); + minCoordinates = minCoordinates_; + maxCoordinates = maxCoordinates_; + } + + // Build signed distance field + terrainPtr->createSignedDistanceBetween(minCoordinates_, maxCoordinates_); + + // Create pointcloud + { + std::lock_guard lock(pointCloudMutex_); + pointCloud_ = terrainPtr->getSignedDistanceField()->asPointCloud(1, [](float val) { return -0.05F <= val && val <= 0.0F; }); + } + + // Move to storage under the lock + { + std::lock_guard lock(updateMutex_); + terrainPtr_ = std::move(terrainPtr); + terrainUpdated_ = true; + } } } // namespace switched_model From c2bfd3484dc5a28038bead3161ab9e050bd1d3b3 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 18 Aug 2020 09:17:35 +0200 Subject: [PATCH 069/504] delete third-party files --- .../distance_transform/COPYING | 339 ------------------ .../distance_transform/dt.h | 117 ------ .../distance_transform/image.h | 101 ------ .../distance_transform/imconv.h | 179 --------- .../distance_transform/imutil.h | 67 ---- .../distance_transform/misc.h | 62 ---- .../distance_transform/pnmfile.h | 214 ----------- .../test/signedDistanceTest.cpp | 5 +- 8 files changed, 1 insertion(+), 1083 deletions(-) delete mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/COPYING delete mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/dt.h delete mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/image.h delete mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imconv.h delete mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imutil.h delete mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/misc.h delete mode 100755 segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/pnmfile.h diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/COPYING b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/COPYING deleted file mode 100755 index d511905c..00000000 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/dt.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/dt.h deleted file mode 100755 index 2c83de57..00000000 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/dt.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright (C) 2006 Pedro Felzenszwalb - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* distance transform */ - -#pragma once - -#include - -#include "image.h" -#include "imconv.h" - -namespace distance_transform -{ - const double INF = 1E20; - - /* dt of 1d function using squared distance */ - static float *dt_1d(float *f, int n) { - float *d = new float[n]; - int *v = new int[n]; - float *z = new float[n+1]; - int k = 0; - v[0] = 0; - z[0] = -INF; - z[1] = +INF; - for (int q = 1; q <= n-1; q++) { - float s = ((f[q]+square(q))-(f[v[k]]+square(v[k])))/(2*q-2*v[k]); - while (s <= z[k]) { - k--; - s = ((f[q]+square(q))-(f[v[k]]+square(v[k])))/(2*q-2*v[k]); - } - k++; - v[k] = q; - z[k] = s; - z[k+1] = +INF; - } - - k = 0; - for (int q = 0; q <= n-1; q++) { - while (z[k+1] < q) - k++; - d[q] = square(q-v[k]) + f[v[k]]; - } - - delete [] v; - delete [] z; - return d; - } - - /* dt of 2d function using squared distance */ - static void dt_2d(image *im) { - int width = im->width(); - int height = im->height(); - float *f = new float[std::max(width,height)]; - - // transform along columns - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - f[y] = imRef(im, x, y); - } - float *d = dt_1d(f, height); - for (int y = 0; y < height; y++) { - imRef(im, x, y) = d[y]; - } - delete [] d; - } - - // transform along rows - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - f[x] = imRef(im, x, y); - } - float *d = dt_1d(f, width); - for (int x = 0; x < width; x++) { - imRef(im, x, y) = d[x]; - } - delete [] d; - } - - delete [] f; - } - - /* dt of binary image using squared distance */ - static image *dt(image *im, uchar on = 1) { - int width = im->width(); - int height = im->height(); - - image *out = new image(width, height, false); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - if (imRef(im, x, y) == on) - imRef(out, x, y) = 0; - else - imRef(out, x, y) = INF; - } - } - - dt_2d(out); - return out; - } - -} // namespace diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/image.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/image.h deleted file mode 100755 index 47cada09..00000000 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/image.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright (C) 2006 Pedro Felzenszwalb - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* a simple image class */ - -#pragma once - -#include - -namespace distance_transform -{ - - template - class image { - public: - /* create an image */ - image(const int width, const int height, const bool init = true); - - /* delete an image */ - ~image(); - - /* init an image */ - void init(const T &val); - - /* copy an image */ - image *copy() const; - - /* get the width of an image. */ - int width() const { return w; } - - /* get the height of an image. */ - int height() const { return h; } - - /* image data. */ - T *data; - - /* row pointers. */ - T **access; - - private: - int w, h; - }; - - /* use imRef to access image data. */ -#define imRef(im, x, y) (im->access[y][x]) - - /* use imPtr to get pointer to image data. */ -#define imPtr(im, x, y) &(im->access[y][x]) - - template - image::image(const int width, const int height, const bool init) { - w = width; - h = height; - data = new T[w * h]; // allocate space for image data - access = new T*[h]; // allocate space for row pointers - - // initialize row pointers - for (int i = 0; i < h; i++) - access[i] = data + (i * w); - - if (init) - memset(data, 0, w * h * sizeof(T)); - } - - template - image::~image() { - delete [] data; - delete [] access; - } - - template - void image::init(const T &val) { - T *ptr = imPtr(this, 0, 0); - T *end = imPtr(this, w-1, h-1); - while (ptr <= end) - *ptr++ = val; - } - - template - image *image::copy() const { - image *im = new image(w, h, false); - memcpy(im->data, data, w * h * sizeof(T)); - return im; - } - -} // namespace diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imconv.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imconv.h deleted file mode 100755 index b4f27ff3..00000000 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imconv.h +++ /dev/null @@ -1,179 +0,0 @@ -/* -Copyright (C) 2006 Pedro Felzenszwalb - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* image conversion */ - -#pragma once - -#include - -#include "image.h" -#include "imutil.h" -#include "misc.h" - -namespace distance_transform -{ - const double RED_WEIGHT = 0.299; - const double GREEN_WEIGHT = 0.584; - const double BLUE_WEIGHT = 0.114; - - static image *imageRGBtoGRAY(image *input) { - int width = input->width(); - int height = input->height(); - image *output = new image(width, height, false); - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - imRef(output, x, y) = (uchar) - (imRef(input, x, y).r * RED_WEIGHT + - imRef(input, x, y).g * GREEN_WEIGHT + - imRef(input, x, y).b * BLUE_WEIGHT); - } - } - return output; - } - - static image *imageGRAYtoRGB(image *input) { - int width = input->width(); - int height = input->height(); - image *output = new image(width, height, false); - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - imRef(output, x, y).r = imRef(input, x, y); - imRef(output, x, y).g = imRef(input, x, y); - imRef(output, x, y).b = imRef(input, x, y); - } - } - return output; - } - - static image *imageUCHARtoFLOAT(image *input) { - int width = input->width(); - int height = input->height(); - image *output = new image(width, height, false); - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - imRef(output, x, y) = imRef(input, x, y); - } - } - return output; - } - - static image *imageINTtoFLOAT(image *input) { - int width = input->width(); - int height = input->height(); - image *output = new image(width, height, false); - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - imRef(output, x, y) = imRef(input, x, y); - } - } - return output; - } - - static image *imageFLOATtoUCHAR(image *input, - float min, float max) { - int width = input->width(); - int height = input->height(); - image *output = new image(width, height, false); - - if (max == min) - return output; - - float scale = UCHAR_MAX / (max - min); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - uchar val = (uchar)((imRef(input, x, y) - min) * scale); - imRef(output, x, y) = bound(val, (uchar)0, (uchar)UCHAR_MAX); - } - } - return output; - } - - static image *imageFLOATtoUCHAR(image *input) { - float min, max; - min_max(input, &min, &max); - return imageFLOATtoUCHAR(input, min, max); - } - - static image *imageUCHARtoLONG(image *input) { - int width = input->width(); - int height = input->height(); - image *output = new image(width, height, false); - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - imRef(output, x, y) = imRef(input, x, y); - } - } - return output; - } - - static image *imageLONGtoUCHAR(image *input, long min, long max) { - int width = input->width(); - int height = input->height(); - image *output = new image(width, height, false); - - if (max == min) - return output; - - float scale = UCHAR_MAX / (float)(max - min); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - uchar val = (uchar)((imRef(input, x, y) - min) * scale); - imRef(output, x, y) = bound(val, (uchar)0, (uchar)UCHAR_MAX); - } - } - return output; - } - - static image *imageLONGtoUCHAR(image *input) { - long min, max; - min_max(input, &min, &max); - return imageLONGtoUCHAR(input, min, max); - } - - static image *imageSHORTtoUCHAR(image *input, - short min, short max) { - int width = input->width(); - int height = input->height(); - image *output = new image(width, height, false); - - if (max == min) - return output; - - float scale = UCHAR_MAX / (float)(max - min); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - uchar val = (uchar)((imRef(input, x, y) - min) * scale); - imRef(output, x, y) = bound(val, (uchar)0, (uchar)UCHAR_MAX); - } - } - return output; - } - - static image *imageSHORTtoUCHAR(image *input) { - short min, max; - min_max(input, &min, &max); - return imageSHORTtoUCHAR(input, min, max); - } - -} // namespace diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imutil.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imutil.h deleted file mode 100755 index ad09d1f8..00000000 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/imutil.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright (C) 2006 Pedro Felzenszwalb - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* some image utilities */ - -#pragma once - -#include "image.h" -#include "misc.h" - -namespace distance_transform -{ - - /* compute minimum and maximum value in an image */ - template - void min_max(image *im, T *ret_min, T *ret_max) { - int width = im->width(); - int height = im->height(); - - T min = imRef(im, 0, 0); - T max = imRef(im, 0, 0); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - T val = imRef(im, x, y); - if (min > val) - min = val; - if (max < val) - max = val; - } - } - - *ret_min = min; - *ret_max = max; - } - - /* threshold image */ - template - image *threshold(image *src, int t) { - int width = src->width(); - int height = src->height(); - image *dst = new image(width, height); - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - imRef(dst, x, y) = (imRef(src, x, y) >= t); - } - } - - return dst; - } - -} // namespace diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/misc.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/misc.h deleted file mode 100755 index a9514d1f..00000000 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/misc.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright (C) 2006 Pedro Felzenszwalb - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* random stuff */ - -#pragma once - -#include - -namespace distance_transform -{ - typedef unsigned char uchar; - - typedef struct { uchar r, g, b; } rgb; - - inline bool operator==(const rgb &a, const rgb &b) { - return ((a.r == b.r) && (a.g == b.g) && (a.b == b.b)); - } - - template - inline T abs(const T &x) { return (x > 0 ? x : -x); }; - - template - inline int sign(const T &x) { return (x >= 0 ? 1 : -1); }; - - template - inline T square(const T &x) { return x*x; }; - - template - inline T bound(const T &x, const T &min, const T &max) { - return (x < min ? min : (x > max ? max : x)); - } - - template - inline bool check_bound(const T &x, const T&min, const T &max) { - return ((x < min) || (x > max)); - } - - inline int vlib_round(float x) { return (int)(x + 0.5F); } - - inline int vlib_round(double x) { return (int)(x + 0.5); } - - inline double gaussian(double val, double sigma) { - return exp(-square(val/sigma)/2)/(sqrt(2*M_PI)*sigma); - } - -} // namespace diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/pnmfile.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/pnmfile.h deleted file mode 100755 index 28284328..00000000 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/distance_transform/pnmfile.h +++ /dev/null @@ -1,214 +0,0 @@ -/* -Copyright (C) 2006 Pedro Felzenszwalb - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* basic image I/O */ - -#pragma once - -#include -#include -#include -#include - -#include "image.h" -#include "misc.h" - -namespace distance_transform -{ - - const short BUF_SIZE = 256; - - class pnm_error { }; - - static void read_packed(unsigned char *data, int size, std::ifstream &f) { - unsigned char c = 0; - - int bitshift = -1; - for (int pos = 0; pos < size; pos++) { - if (bitshift == -1) { - c = f.get(); - bitshift = 7; - } - data[pos] = (c >> bitshift) & 1; - bitshift--; - } - } - - static void write_packed(unsigned char *data, int size, std::ofstream &f) { - unsigned char c = 0; - - int bitshift = 7; - for (int pos = 0; pos < size; pos++) { - c = c | (data[pos] << bitshift); - bitshift--; - if ((bitshift == -1) || (pos == size-1)) { - f.put(c); - bitshift = 7; - c = 0; - } - } - } - - /* read PNM field, skipping comments */ - static void pnm_read(std::ifstream &file, char *buf) { - char doc[BUF_SIZE]; - char c; - - file >> c; - while (c == '#') { - file.getline(doc, BUF_SIZE); - file >> c; - } - file.putback(c); - - file.width(BUF_SIZE); - file >> buf; - file.ignore(); - } - - static image *loadPBM(const char *name) { - char buf[BUF_SIZE]; - - /* read header */ - std::ifstream file(name, std::ios::in | std::ios::binary); - pnm_read(file, buf); - if (strncmp(buf, "P4", 2)) - throw pnm_error(); - - pnm_read(file, buf); - int width = atoi(buf); - pnm_read(file, buf); - int height = atoi(buf); - - /* read data */ - image *im = new image(width, height); - for (int i = 0; i < height; i++) - read_packed(imPtr(im, 0, i), width, file); - - return im; - } - - static void savePBM(image *im, const char *name) { - int width = im->width(); - int height = im->height(); - std::ofstream file(name, std::ios::out | std::ios::binary); - - file << "P4\n" << width << " " << height << "\n"; - for (int i = 0; i < height; i++) - write_packed(imPtr(im, 0, i), width, file); - } - - static image *loadPGM(const char *name) { - char buf[BUF_SIZE]; - - /* read header */ - std::ifstream file(name, std::ios::in | std::ios::binary); - pnm_read(file, buf); - if (strncmp(buf, "P5", 2)) - throw pnm_error(); - - pnm_read(file, buf); - int width = atoi(buf); - pnm_read(file, buf); - int height = atoi(buf); - - pnm_read(file, buf); - if (atoi(buf) > UCHAR_MAX) - throw pnm_error(); - - /* read data */ - image *im = new image(width, height); - file.read((char *)imPtr(im, 0, 0), width * height * sizeof(uchar)); - - return im; - } - - static void savePGM(image *im, const char *name) { - int width = im->width(); - int height = im->height(); - std::ofstream file(name, std::ios::out | std::ios::binary); - - file << "P5\n" << width << " " << height << "\n" << UCHAR_MAX << "\n"; - file.write((char *)imPtr(im, 0, 0), width * height * sizeof(uchar)); - } - - static image *loadPPM(const char *name) { - char buf[BUF_SIZE], doc[BUF_SIZE]; - - /* read header */ - std::ifstream file(name, std::ios::in | std::ios::binary); - pnm_read(file, buf); - if (strncmp(buf, "P6", 2)) - throw pnm_error(); - - pnm_read(file, buf); - int width = atoi(buf); - pnm_read(file, buf); - int height = atoi(buf); - - pnm_read(file, buf); - if (atoi(buf) > UCHAR_MAX) - throw pnm_error(); - - /* read data */ - image *im = new image(width, height); - file.read((char *)imPtr(im, 0, 0), width * height * sizeof(rgb)); - - return im; - } - - static void savePPM(image *im, const char *name) { - int width = im->width(); - int height = im->height(); - std::ofstream file(name, std::ios::out | std::ios::binary); - - file << "P6\n" << width << " " << height << "\n" << UCHAR_MAX << "\n"; - file.write((char *)imPtr(im, 0, 0), width * height * sizeof(rgb)); - } - - template - void load_image(image **im, const char *name) { - char buf[BUF_SIZE]; - - /* read header */ - std::ifstream file(name, std::ios::in | std::ios::binary); - pnm_read(file, buf); - if (strncmp(buf, "VLIB", 9)) - throw pnm_error(); - - pnm_read(file, buf); - int width = atoi(buf); - pnm_read(file, buf); - int height = atoi(buf); - - /* read data */ - *im = new image(width, height); - file.read((char *)imPtr((*im), 0, 0), width * height * sizeof(T)); - } - - template - void save_image(image *im, const char *name) { - int width = im->width(); - int height = im->height(); - std::ofstream file(name, std::ios::out | std::ios::binary); - - file << "VLIB\n" << width << " " << height << "\n"; - file.write((char *)imPtr(im, 0, 0), width * height * sizeof(T)); - } - -} // namespace diff --git a/segmented_planes_terrain_model/test/signedDistanceTest.cpp b/segmented_planes_terrain_model/test/signedDistanceTest.cpp index b58a3964..d0a4b2c8 100644 --- a/segmented_planes_terrain_model/test/signedDistanceTest.cpp +++ b/segmented_planes_terrain_model/test/signedDistanceTest.cpp @@ -4,7 +4,7 @@ #include -#include + #include #include @@ -14,9 +14,6 @@ #include #include -using namespace distance_transform; - - grid_map::GridMap loadElevationMapFromFile(const std::string& filePath, double resolution, double scale) { // Read the file cv::Mat image; From 93954c523f7cb15aba660a619628de4df310608f Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 19 Aug 2020 14:45:28 +0200 Subject: [PATCH 070/504] fix 3d lookup --- signed_distance_field/CMakeLists.txt | 1 + .../signed_distance_field/Gridmap3dLookup.h | 35 +++++++----- .../GridmapSignedDistanceField.h | 1 + .../src/GridmapSignedDistanceField.cpp | 2 +- signed_distance_field/test/test3dLookup.cpp | 54 +++++++++++++++++++ .../test/testDerivatives.cpp | 1 - 6 files changed, 80 insertions(+), 14 deletions(-) create mode 100644 signed_distance_field/test/test3dLookup.cpp diff --git a/signed_distance_field/CMakeLists.txt b/signed_distance_field/CMakeLists.txt index bd3fda80..c61862b2 100644 --- a/signed_distance_field/CMakeLists.txt +++ b/signed_distance_field/CMakeLists.txt @@ -66,6 +66,7 @@ install(DIRECTORY include/${PROJECT_NAME}/ ############# add_executable(${PROJECT_NAME}_test + test/test3dLookup.cpp test/testDerivatives.cpp test/testPixelBorderDistance.cpp test/testSignedDistance2d.cpp diff --git a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h index 4ec61f89..90ec2d06 100644 --- a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h +++ b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h @@ -14,7 +14,7 @@ namespace signed_distance_field { /** * Stores 3 dimensional grid information and provides methods to convert between position - 3d Index - linear index. * - * As with grid map, the X-Y position is opposite to the row-col-index: lowest at (0,0) and highest at (n, m). + * As with grid map, the X-Y position is opposite to the row-col-index: (X,Y) is highest at (0,0) and lowest at (n, m). * The z-position is increasing with the layer-index. */ struct Gridmap3dLookup { @@ -37,21 +37,22 @@ struct Gridmap3dLookup { * @param gridOrigin : position at x=y=z=0 * @param resolution : (>0.0) size of 1 voxel */ - Gridmap3dLookup(const size_t_3d& gridsize, const Eigen::Vector3d& gridOrigin, double resolution) : - gridsize_(gridsize), gridOrigin_(gridOrigin), resolution_(resolution) { - assert(resolution_ > 0.0); - }; + Gridmap3dLookup(const size_t_3d& gridsize, const Eigen::Vector3d& gridOrigin, double resolution) + : gridsize_(gridsize), gridOrigin_(gridOrigin), resolution_(resolution) { + assert(resolution_ > 0.0); + assert(gridsize_.x > 0); + assert(gridsize_.y > 0); + assert(gridsize_.z > 0); + }; /** Default constructor: creates an empty grid */ - Gridmap3dLookup() : Gridmap3dLookup({0, 0, 0}, {0.0,0.0,0.0}, 1.0) {} + Gridmap3dLookup() : Gridmap3dLookup({1, 1, 1}, {0.0, 0.0, 0.0}, 1.0) {} /** Returns the 3d index of the grid node closest to the query position */ size_t_3d nearestNode(const Eigen::Vector3d& position) const noexcept { - auto round = [](double val) { - return static_cast(std::round(val)); - }; - Eigen::Vector3d subpixelVector = (position - gridOrigin_) / resolution_; - return {round(subpixelVector.x()), round(subpixelVector.y()), round(subpixelVector.z())}; + Eigen::Vector3d subpixelVector{(gridOrigin_.x() - position.x()) / resolution_, (gridOrigin_.y() - position.y()) / resolution_, (position.z() - gridOrigin_.z()) / resolution_}; + return {nearestPositiveInteger(subpixelVector.x(), gridsize_.x - 1), nearestPositiveInteger(subpixelVector.y(), gridsize_.y - 1), + nearestPositiveInteger(subpixelVector.z(), gridsize_.z - 1)}; } /** Returns the 3d node position from a 3d index */ @@ -60,10 +61,20 @@ struct Gridmap3dLookup { } /** Returns the linear node index from a 3d node index */ - size_t linearIndex(const size_t_3d& index) const noexcept { return index.z * gridsize_.y * gridsize_.x + index.y * gridsize_.x + index.x; } + size_t linearIndex(const size_t_3d& index) const noexcept { return (index.z * gridsize_.y + index.y) * gridsize_.x + index.x; } /** Linear size */ size_t linearSize() const noexcept { return gridsize_.x * gridsize_.y * gridsize_.z; } + + /** rounds subindex value and clamps it to [0, max] */ + static size_t nearestPositiveInteger(double val, size_t max) { + // Comparing bounds as double prevents underflow/overflow + if (val > 0.0) { + return static_cast(std::min(std::round(val), static_cast(max))); + } else { + return 0; + } + } }; } // namespace signed_distance_field diff --git a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h index e7da9cf5..5967439c 100644 --- a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h +++ b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h @@ -25,6 +25,7 @@ class GridmapSignedDistanceField : public switched_model::SignedDistanceField { EIGEN_MAKE_ALIGNED_OPERATOR_NEW GridmapSignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, double minHeight, double maxHeight); + ~GridmapSignedDistanceField() override = default; GridmapSignedDistanceField* clone() const override; switched_model::scalar_t value(const switched_model::vector3_t& position) const override; diff --git a/signed_distance_field/src/GridmapSignedDistanceField.cpp b/signed_distance_field/src/GridmapSignedDistanceField.cpp index bb959f94..2c5558fe 100644 --- a/signed_distance_field/src/GridmapSignedDistanceField.cpp +++ b/signed_distance_field/src/GridmapSignedDistanceField.cpp @@ -29,7 +29,7 @@ GridmapSignedDistanceField::GridmapSignedDistanceField(const grid_map::GridMap& } GridmapSignedDistanceField::GridmapSignedDistanceField(const GridmapSignedDistanceField& other) - : gridmap3DLookup_(other.gridmap3DLookup_), data_(other.data_) {} + : switched_model::SignedDistanceField(), gridmap3DLookup_(other.gridmap3DLookup_), data_(other.data_) {} GridmapSignedDistanceField* GridmapSignedDistanceField::clone() const { return new GridmapSignedDistanceField(*this); diff --git a/signed_distance_field/test/test3dLookup.cpp b/signed_distance_field/test/test3dLookup.cpp new file mode 100644 index 00000000..64be208e --- /dev/null +++ b/signed_distance_field/test/test3dLookup.cpp @@ -0,0 +1,54 @@ +// +// Created by rgrandia on 18.08.20. +// + +#include + +#include "signed_distance_field/Gridmap3dLookup.h" + +using signed_distance_field::Gridmap3dLookup; +using size_t_3d = signed_distance_field::Gridmap3dLookup::size_t_3d; + +TEST(testGridmap3dLookup, nearestNode) { + const size_t_3d gridsize{8, 9, 10}; + const Eigen::Vector3d gridOrigin{-0.1, -0.2, -0.4}; + const double resolution = 0.1; + + signed_distance_field::Gridmap3dLookup gridmap3DLookup(gridsize, gridOrigin, resolution); + + // Retreive origin + const size_t_3d originNode = gridmap3DLookup.nearestNode(gridOrigin); + ASSERT_EQ(originNode.x, 0); + ASSERT_EQ(originNode.y, 0); + ASSERT_EQ(originNode.z, 0); + + // test underflow + const size_t_3d originNodeProjected = gridmap3DLookup.nearestNode(gridOrigin + Eigen::Vector3d{1e20, 1e20, -1e20}); + ASSERT_EQ(originNodeProjected.x, 0); + ASSERT_EQ(originNodeProjected.y, 0); + ASSERT_EQ(originNodeProjected.z, 0); + + // test overflow + const size_t_3d maxNodeProjected = gridmap3DLookup.nearestNode(gridOrigin + Eigen::Vector3d{-1e20, -1e20, +1e20}); + ASSERT_EQ(maxNodeProjected.x, gridsize.x - 1); + ASSERT_EQ(maxNodeProjected.y, gridsize.y - 1); + ASSERT_EQ(maxNodeProjected.z, gridsize.z - 1); + + // Nearest neighbour + const size_t_3d nodeIndex{3, 4, 5}; + const Eigen::Vector3d nodePosition = gridmap3DLookup.nodePosition(nodeIndex); + const size_t_3d closestNodeIndex = gridmap3DLookup.nearestNode(nodePosition + 0.49 * Eigen::Vector3d::Constant(resolution)); + ASSERT_EQ(closestNodeIndex.x, nodeIndex.x); + ASSERT_EQ(closestNodeIndex.y, nodeIndex.y); + ASSERT_EQ(closestNodeIndex.z, nodeIndex.z); +} + +TEST(testGridmap3dLookup, linearIndex) { + const size_t_3d gridsize{8, 9, 10}; + const Eigen::Vector3d gridOrigin{-0.1, -0.2, -0.4}; + const double resolution = 0.1; + + signed_distance_field::Gridmap3dLookup gridmap3DLookup(gridsize, gridOrigin, resolution); + ASSERT_EQ(gridmap3DLookup.linearIndex({0, 0, 0}), 0); + ASSERT_EQ(gridmap3DLookup.linearIndex({gridsize.x - 1, gridsize.y - 1, gridsize.z - 1}), gridmap3DLookup.linearSize() - 1); +} \ No newline at end of file diff --git a/signed_distance_field/test/testDerivatives.cpp b/signed_distance_field/test/testDerivatives.cpp index eac1e207..f56c35b7 100644 --- a/signed_distance_field/test/testDerivatives.cpp +++ b/signed_distance_field/test/testDerivatives.cpp @@ -6,7 +6,6 @@ #include "signed_distance_field/DistanceDerivatives.h" - TEST(testDerivatives, columnwise) { Eigen::MatrixXf data(2, 3); data << 1.0, 2.0, 4.0, From da846853750aed8d470d505b46ccef1abcf2984e Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 25 Aug 2020 13:53:22 +0200 Subject: [PATCH 071/504] decrease ransac connectivity distance --- convex_plane_decomposition_ros/config/parameters.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index aa45a11c..1ac210c1 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -18,7 +18,7 @@ ransac_plane_refinement: probability: 0.01 # Probability to miss the largest candidate shape. A lower probability provides a higher reliability and determinism at the cost of longer running times min_points: 25 # This minimum number of points per plane. Controls the termination of the algorithm. epsilon: 0.02 # Maximum distance to plane - cluster_epsilon: 0.05 # Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon + cluster_epsilon: 0.02 # Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon normal_threshold: 0.98 # Set maximum normal deviation. normal_threshold < dot(surface_normal, point_normal); contour_extraction: From d4677d1d66c37b2842817f228bf86fae928f8862 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Fri, 11 Sep 2020 10:01:19 +0200 Subject: [PATCH 072/504] make brace initializer type explicit --- .../src/ConvexPlaneDecompositionRos.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index bf9bae7f..af1d0458 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -79,7 +79,8 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { // Convert message to map. ROS_INFO("Reading input map..."); grid_map::GridMap messageMap; - grid_map::GridMapRosConverter::fromMessage(message, messageMap, {elevationLayer_}, false, false); + std::vector layers{elevationLayer_}; + grid_map::GridMapRosConverter::fromMessage(message, messageMap, layers, false, false); bool success; grid_map::GridMap elevationMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(subMapWidth_, subMapLength_), success); ROS_INFO("...done."); From 9ea8b1c3c874ba4f5c6746bc351c007be5a0169c Mon Sep 17 00:00:00 2001 From: rgrandia Date: Fri, 11 Sep 2020 10:40:37 +0200 Subject: [PATCH 073/504] environment anymal --- jenkins-pipeline | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkins-pipeline b/jenkins-pipeline index 59d9ff9b..ba291975 100644 --- a/jenkins-pipeline +++ b/jenkins-pipeline @@ -1,2 +1,2 @@ library 'continuous_integration_pipeline' -ciPipeline("") +ciPipeline("--environment anymal") From 209f78ae2961ab2bd2f79fb436f4d1cde8379e72 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 28 Sep 2020 15:36:34 +0200 Subject: [PATCH 074/504] point to ocs2_anymal branch for CI --- jenkins-pipeline | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkins-pipeline b/jenkins-pipeline index ba291975..cc00826c 100644 --- a/jenkins-pipeline +++ b/jenkins-pipeline @@ -1,2 +1,2 @@ library 'continuous_integration_pipeline' -ciPipeline("--environment anymal") +ciPipeline("--environment anymal --dependencies git@bitbucket.org:leggedrobotics/ocs2_anymal.git;feature/perception;git") From fd202f0a83ad9f75f51c03ecc552ced0c2fe121c Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 28 Sep 2020 17:26:53 +0200 Subject: [PATCH 075/504] move visualization helpers to switched_model --- cgal5_catkin/CMakeLists.txt | 4 +++ segmented_planes_terrain_model/CMakeLists.txt | 1 - .../SegmentedPlanesTerrainModelRos.h | 1 + .../SegmentedPlanesTerrainVisualization.h | 3 +-- segmented_planes_terrain_model/package.xml | 1 - .../src/DemoNode.cpp | 2 +- .../src/SegmentedPlanesTerrainModelRos.cpp | 25 ++++++++++++------- 7 files changed, 23 insertions(+), 14 deletions(-) diff --git a/cgal5_catkin/CMakeLists.txt b/cgal5_catkin/CMakeLists.txt index 445a42f5..687ee40d 100644 --- a/cgal5_catkin/CMakeLists.txt +++ b/cgal5_catkin/CMakeLists.txt @@ -9,6 +9,10 @@ set(VERSION 5.0.2) file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/include) +# Cpp standard version +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CGAL_VERSION 5.0.2) ExternalProject_Add(cgal URL https://github.com/CGAL/cgal/archive/releases/CGAL-${CGAL_VERSION}.tar.gz diff --git a/segmented_planes_terrain_model/CMakeLists.txt b/segmented_planes_terrain_model/CMakeLists.txt index 9482e05c..dccffca0 100644 --- a/segmented_planes_terrain_model/CMakeLists.txt +++ b/segmented_planes_terrain_model/CMakeLists.txt @@ -4,7 +4,6 @@ project(segmented_planes_terrain_model) # Catkin dependencies set(CATKIN_PACKAGE_DEPENDENCIES ocs2_switched_model_interface - ocs2_quadruped_interface grid_map_sdf pcl_ros convex_plane_decomposition diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h index 3f9cc207..46f0931f 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h @@ -43,6 +43,7 @@ class SegmentedPlanesTerrainModelRos { std::mutex updateCoordinatesMutex_; Eigen::Vector3d minCoordinates_; Eigen::Vector3d maxCoordinates_; + bool createSignedDistance_ = false; std::mutex pointCloudMutex_; pcl::PointCloud pointCloud_; diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h index 3cabb232..a89c2cb9 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h @@ -8,8 +8,7 @@ #include #include - -#include +#include namespace switched_model { diff --git a/segmented_planes_terrain_model/package.xml b/segmented_planes_terrain_model/package.xml index 8547f888..2034ed44 100644 --- a/segmented_planes_terrain_model/package.xml +++ b/segmented_planes_terrain_model/package.xml @@ -10,7 +10,6 @@ catkin ocs2_switched_model_interface - ocs2_quadruped_interface grid_map_sdf pcl_ros convex_plane_decomposition diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp index b9ae9d7d..0500d2e8 100644 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include "segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h" diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp index 0fccb2f8..78b6f36b 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp @@ -8,11 +8,12 @@ #include #include -#include +#include namespace switched_model { -SegmentedPlanesTerrainModelRos::SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle) : terrainUpdated_(false), minCoordinates_(Eigen::Vector3d::Zero()), maxCoordinates_(Eigen::Vector3d::Zero()) { +SegmentedPlanesTerrainModelRos::SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle) + : terrainUpdated_(false), minCoordinates_(Eigen::Vector3d::Zero()), maxCoordinates_(Eigen::Vector3d::Zero()) { terrainSubscriber_ = nodehandle.subscribe("/convex_plane_decomposition_ros/planar_terrain", 1, &SegmentedPlanesTerrainModelRos::callback, this); distanceFieldPublisher_ = nodehandle.advertise("/convex_plane_decomposition_ros/signed_distance_field", 1); @@ -31,10 +32,12 @@ bool SegmentedPlanesTerrainModelRos::update(std::unique_ptr lock(updateCoordinatesMutex_); minCoordinates_ = minCoordinates; maxCoordinates_ = maxCoordinates; + createSignedDistance_ = true; } void SegmentedPlanesTerrainModelRos::publish() { @@ -53,21 +56,25 @@ void SegmentedPlanesTerrainModelRos::callback(const convex_plane_decomposition_m auto terrainPtr = std::make_unique(convex_plane_decomposition::fromMessage(*msg)); // Extract coordinates for signed distance field + bool createSignedDistance = false; Eigen::Vector3d minCoordinates; Eigen::Vector3d maxCoordinates; { std::lock_guard lock(updateCoordinatesMutex_); minCoordinates = minCoordinates_; maxCoordinates = maxCoordinates_; + createSignedDistance = createSignedDistance_; } - // Build signed distance field - terrainPtr->createSignedDistanceBetween(minCoordinates_, maxCoordinates_); + if (createSignedDistance) { + // Build signed distance field + terrainPtr->createSignedDistanceBetween(minCoordinates_, maxCoordinates_); - // Create pointcloud - { - std::lock_guard lock(pointCloudMutex_); - pointCloud_ = terrainPtr->getSignedDistanceField()->asPointCloud(1, [](float val) { return -0.05F <= val && val <= 0.0F; }); + // Create pointcloud + { + std::lock_guard lock(pointCloudMutex_); + pointCloud_ = terrainPtr->getSignedDistanceField()->asPointCloud(1, [](float val) { return -0.05F <= val && val <= 0.0F; }); + } } // Move to storage under the lock From 0320f050cde6c4f6b8c722af5df14db13ee232df Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 28 Sep 2020 18:29:08 +0200 Subject: [PATCH 076/504] add cpp14 as requirement for CGAL --- cgal5_catkin/CMakeLists.txt | 4 ---- cgal5_catkin/cmake/cgal-extras.cmake.in | 6 +++++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cgal5_catkin/CMakeLists.txt b/cgal5_catkin/CMakeLists.txt index 687ee40d..445a42f5 100644 --- a/cgal5_catkin/CMakeLists.txt +++ b/cgal5_catkin/CMakeLists.txt @@ -9,10 +9,6 @@ set(VERSION 5.0.2) file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/include) -# Cpp standard version -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CGAL_VERSION 5.0.2) ExternalProject_Add(cgal URL https://github.com/CGAL/cgal/archive/releases/CGAL-${CGAL_VERSION}.tar.gz diff --git a/cgal5_catkin/cmake/cgal-extras.cmake.in b/cgal5_catkin/cmake/cgal-extras.cmake.in index aebefc49..3db7988c 100644 --- a/cgal5_catkin/cmake/cgal-extras.cmake.in +++ b/cgal5_catkin/cmake/cgal-extras.cmake.in @@ -1,2 +1,6 @@ # Makes CGAL/find___.cmake available -list(APPEND CMAKE_MODULE_PATH @CATKIN_DEVEL_PREFIX@/lib/cmake/CGAL) \ No newline at end of file +list(APPEND CMAKE_MODULE_PATH @CATKIN_DEVEL_PREFIX@/lib/cmake/CGAL) + +# Cpp standard version +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) \ No newline at end of file From 54242698a97e1bc7af6daff9e7062641c3a54d55 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 5 Oct 2020 17:07:32 +0200 Subject: [PATCH 077/504] check for nullptr --- .../src/SegmentedPlanesTerrainModelRos.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp index 78b6f36b..9bc758bf 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp @@ -69,11 +69,12 @@ void SegmentedPlanesTerrainModelRos::callback(const convex_plane_decomposition_m if (createSignedDistance) { // Build signed distance field terrainPtr->createSignedDistanceBetween(minCoordinates_, maxCoordinates_); + const auto* sdfPtr = terrainPtr->getSignedDistanceField(); // Create pointcloud - { + if (sdfPtr != nullptr) { std::lock_guard lock(pointCloudMutex_); - pointCloud_ = terrainPtr->getSignedDistanceField()->asPointCloud(1, [](float val) { return -0.05F <= val && val <= 0.0F; }); + pointCloud_ = sdfPtr->asPointCloud(1, [](float val) { return -0.05F <= val && val <= 0.0F; }); } } From 5302efccf9eaacc1107af8d410ad6cb53360c29a Mon Sep 17 00:00:00 2001 From: Marko Bjelonic Date: Sun, 22 Nov 2020 14:37:00 +0100 Subject: [PATCH 078/504] Genralize launch and config files. --- convex_plane_decomposition_ros/config/node.yaml | 1 + .../ConvexPlaneDecompositionRos.h | 2 +- .../launch/convex_plane_decomposition.launch | 8 ++++---- .../src/ConvexPlaneDecompositionRos.cpp | 6 +++++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/convex_plane_decomposition_ros/config/node.yaml b/convex_plane_decomposition_ros/config/node.yaml index 4343d077..e7901ec4 100644 --- a/convex_plane_decomposition_ros/config/node.yaml +++ b/convex_plane_decomposition_ros/config/node.yaml @@ -1,5 +1,6 @@ elevation_topic: '/elevation_mapping/elevation_map_raw' height_layer: 'elevation' +target_frame_id: 'odom' submap: width: 3.0 length: 3.0 diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h index fcca9c26..6b37f375 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h @@ -43,7 +43,7 @@ class ConvexPlaneExtractionROS { // Parameters std::string elevationMapTopic_; std::string elevationLayer_; - std::string targetFrameId_ = "odom"; + std::string targetFrameId_; double subMapWidth_; double subMapLength_; bool publishToController_; diff --git a/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch b/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch index 7716193d..d72f65e1 100644 --- a/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch +++ b/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch @@ -1,13 +1,13 @@ - - + + - - + + diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 03db24e0..f7ffa7e0 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -41,6 +41,10 @@ bool ConvexPlaneExtractionROS::loadParameters(const ros::NodeHandle& nodeHandle) ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `elevation_topic`."); return false; } + if (!nodeHandle.getParam("target_frame_id", targetFrameId_)) { + ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `elevation_topic`."); + return false; + } if (!nodeHandle.getParam("height_layer", elevationLayer_)) { ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `height_layer`."); return false; @@ -82,7 +86,7 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { std::vector layers{elevationLayer_}; grid_map::GridMapRosConverter::fromMessage(message, messageMap, layers, false, false); bool success; - grid_map::GridMap elevationMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(subMapWidth_, subMapLength_), success); + grid_map::GridMap elevationMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(subMapLength_, subMapWidth_), success); ROS_INFO("...done."); // Transform map if necessary From db64d24d85403d65ca67786a5f08ca3a8d2b063b Mon Sep 17 00:00:00 2001 From: Marko Bjelonic Date: Mon, 23 Nov 2020 11:15:31 +0100 Subject: [PATCH 079/504] Fixed error message when reading target frame id. --- .../src/ConvexPlaneDecompositionRos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index f7ffa7e0..8407842f 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -42,7 +42,7 @@ bool ConvexPlaneExtractionROS::loadParameters(const ros::NodeHandle& nodeHandle) return false; } if (!nodeHandle.getParam("target_frame_id", targetFrameId_)) { - ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `elevation_topic`."); + ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `target_frame_id`."); return false; } if (!nodeHandle.getParam("height_layer", elevationLayer_)) { From 31cfb2fd3f3cef2f009fcc690243a577ed002859 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Fri, 27 Nov 2020 11:55:51 +0100 Subject: [PATCH 080/504] - generate sdf pointcloud without holding the lock. - return terrainPtr by value - create full sdf if no range is specified. --- .../SegmentedPlanesTerrainModelRos.h | 16 ++- .../src/DemoNode.cpp | 3 +- .../src/SegmentedPlanesTerrainModelRos.cpp | 107 ++++++++++++------ 3 files changed, 84 insertions(+), 42 deletions(-) diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h index 46f0931f..f16aa770 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h @@ -11,6 +11,7 @@ #include #include +#include #include #include "SegmentedPlanesTerrainModel.h" @@ -19,12 +20,12 @@ namespace switched_model { class SegmentedPlanesTerrainModelRos { public: - std::string frameId_ = "odom"; - SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle); - /// Updates the terrain if a new one is available. Return if an update was made - bool update(std::unique_ptr& terrainPtr); + ~SegmentedPlanesTerrainModelRos(); + + /// Extract the latest terrain model. Resets internal model to a nullptr + std::unique_ptr getTerrainModel(); void createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, const Eigen::Vector3d& maxCoordinates); @@ -33,6 +34,8 @@ class SegmentedPlanesTerrainModelRos { private: void callback(const convex_plane_decomposition_msgs::PlanarTerrain::ConstPtr& msg); + std::pair getSignedDistanceRange(const grid_map::GridMap& gridMap, const std::string& elevationLayer); + ros::Subscriber terrainSubscriber_; ros::Publisher distanceFieldPublisher_; @@ -43,10 +46,13 @@ class SegmentedPlanesTerrainModelRos { std::mutex updateCoordinatesMutex_; Eigen::Vector3d minCoordinates_; Eigen::Vector3d maxCoordinates_; - bool createSignedDistance_ = false; + bool externalCoordinatesGiven_; std::mutex pointCloudMutex_; pcl::PointCloud pointCloud_; + std::string frameId_; + + ocs2::benchmark::RepeatedTimer callbackTimer_; }; } // namespace switched_model diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp index 0500d2e8..d5a1a0c7 100644 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -79,7 +79,8 @@ int main(int argc, char** argv) { // Node loop ros::Rate rate(1./5.); while (ros::ok()) { - if (segmentedPlanesTerrainModelRos.update(terrainModel)) { + if (auto newTerrain = segmentedPlanesTerrainModelRos.getTerrainModel()) { + terrainModel = std::move(newTerrain); ROS_INFO("Terrain model updated!!"); } diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp index 9bc758bf..cc0ceef6 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp @@ -13,77 +13,112 @@ namespace switched_model { SegmentedPlanesTerrainModelRos::SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle) - : terrainUpdated_(false), minCoordinates_(Eigen::Vector3d::Zero()), maxCoordinates_(Eigen::Vector3d::Zero()) { + : terrainUpdated_(false), + minCoordinates_(Eigen::Vector3d::Zero()), + maxCoordinates_(Eigen::Vector3d::Zero()), + externalCoordinatesGiven_(false) { terrainSubscriber_ = nodehandle.subscribe("/convex_plane_decomposition_ros/planar_terrain", 1, &SegmentedPlanesTerrainModelRos::callback, this); - distanceFieldPublisher_ = nodehandle.advertise("/convex_plane_decomposition_ros/signed_distance_field", 1); + distanceFieldPublisher_ = + nodehandle.advertise("/convex_plane_decomposition_ros/signed_distance_field", 1, true); } -bool SegmentedPlanesTerrainModelRos::update(std::unique_ptr& terrainPtr) { - // Avoid locking the mutex in the common case that the terrain is not updated. - if (terrainUpdated_) { - std::lock_guard lock(updateMutex_); - terrainPtr = std::move(terrainPtr_); - terrainPtr_ = nullptr; - terrainUpdated_ = false; - return true; - } else { - return false; +SegmentedPlanesTerrainModelRos::~SegmentedPlanesTerrainModelRos() { + if (callbackTimer_.getNumTimedIntervals() > 0) { + std::cout << "[SegmentedPlanesTerrainModelRos] Benchmarking terrain Callback\n" + << "\tStatistics computed over " << callbackTimer_.getNumTimedIntervals() << " iterations. \n" + << "\tAverage time [ms] " << callbackTimer_.getAverageInMilliseconds() << "\n" + << "\tMaximum time [ms] " << callbackTimer_.getMaxIntervalInMilliseconds() << std::endl; } } +std::unique_ptr SegmentedPlanesTerrainModelRos::getTerrainModel() { + std::lock_guard lock(updateMutex_); + return std::move(terrainPtr_); +} + void SegmentedPlanesTerrainModelRos::createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, const Eigen::Vector3d& maxCoordinates) { std::lock_guard lock(updateCoordinatesMutex_); minCoordinates_ = minCoordinates; maxCoordinates_ = maxCoordinates; - createSignedDistance_ = true; + externalCoordinatesGiven_ = true; } void SegmentedPlanesTerrainModelRos::publish() { - sensor_msgs::PointCloud2 pointCloud2Msg; + // Extract point cloud. + pcl::PointCloud pointcloud; { std::lock_guard lock(pointCloudMutex_); - pcl::toROSMsg(pointCloud_, pointCloud2Msg); + pointcloud.swap(pointCloud_); } - pointCloud2Msg.header = switched_model::getHeaderMsg(frameId_, ros::Time::now()); - distanceFieldPublisher_.publish(pointCloud2Msg); + // Publish. + if (!pointcloud.empty()) { + sensor_msgs::PointCloud2 pointCloud2Msg; + pcl::toROSMsg(pointcloud, pointCloud2Msg); + + pointCloud2Msg.header = switched_model::getHeaderMsg(frameId_, ros::Time::now()); + distanceFieldPublisher_.publish(pointCloud2Msg); + } } void SegmentedPlanesTerrainModelRos::callback(const convex_plane_decomposition_msgs::PlanarTerrain::ConstPtr& msg) { + callbackTimer_.startTimer(); + // Read terrain auto terrainPtr = std::make_unique(convex_plane_decomposition::fromMessage(*msg)); + // Create SDF + const std::string elevationLayer = "elevation"; + if (terrainPtr->planarTerrain().gridMap.exists(elevationLayer)) { + const auto sdfRange = getSignedDistanceRange(terrainPtr->planarTerrain().gridMap, elevationLayer); + terrainPtr->createSignedDistanceBetween(sdfRange.first, sdfRange.second); + } + + // Create pointcloud for visualization + const auto* sdfPtr = terrainPtr->getSignedDistanceField(); + if (sdfPtr != nullptr) { + auto pointCloud = sdfPtr->asPointCloud(1, [](float val) { return -0.05F <= val && val <= 0.0F; }); + std::lock_guard lock(pointCloudMutex_); + pointCloud_.swap(pointCloud); + frameId_ = terrainPtr->planarTerrain().gridMap.getFrameId(); + } + + { // Move to storage under the lock + std::lock_guard lock(updateMutex_); + terrainPtr_ = std::move(terrainPtr); + } + + callbackTimer_.endTimer(); +} + +std::pair SegmentedPlanesTerrainModelRos::getSignedDistanceRange(const grid_map::GridMap& gridMap, + const std::string& elevationLayer) { // Extract coordinates for signed distance field - bool createSignedDistance = false; Eigen::Vector3d minCoordinates; Eigen::Vector3d maxCoordinates; + bool externalRangeGiven; { std::lock_guard lock(updateCoordinatesMutex_); minCoordinates = minCoordinates_; maxCoordinates = maxCoordinates_; - createSignedDistance = createSignedDistance_; + externalRangeGiven = externalCoordinatesGiven_; } - if (createSignedDistance) { - // Build signed distance field - terrainPtr->createSignedDistanceBetween(minCoordinates_, maxCoordinates_); - const auto* sdfPtr = terrainPtr->getSignedDistanceField(); + if (!externalRangeGiven) { + // Read min-max from elevation map + const float heightMargin = 0.1; + const auto& elevationData = gridMap.get(elevationLayer); + const float minValue = elevationData.minCoeffOfFinites() - heightMargin; + const float maxValue = elevationData.maxCoeffOfFinites() + heightMargin; + auto minXY = gridMap.getClosestPositionInMap({std::numeric_limits::lowest(), std::numeric_limits::lowest()}); + auto maxXY = gridMap.getClosestPositionInMap({std::numeric_limits::max(), std::numeric_limits::max()}); + minCoordinates = {minXY.x(), minXY.y(), minValue}; + maxCoordinates = {maxXY.x(), maxXY.y(), maxValue}; + }; - // Create pointcloud - if (sdfPtr != nullptr) { - std::lock_guard lock(pointCloudMutex_); - pointCloud_ = sdfPtr->asPointCloud(1, [](float val) { return -0.05F <= val && val <= 0.0F; }); - } - } - - // Move to storage under the lock - { - std::lock_guard lock(updateMutex_); - terrainPtr_ = std::move(terrainPtr); - terrainUpdated_ = true; - } + return {minCoordinates, maxCoordinates}; } } // namespace switched_model From fb57bc26eb32d38013148d3f4f8c78ac7e8a466a Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 3 Dec 2020 10:56:30 +0100 Subject: [PATCH 081/504] Project coordinates to map to make getSubmap succeed. Print warning on failure --- .../src/SegmentedPlanesTerrainModel.cpp | 12 ++++++++---- .../src/GridmapSignedDistanceField.cpp | 6 +++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index aeb225cc..23ab8f3d 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -74,15 +74,19 @@ ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld(con void SegmentedPlanesTerrainModel::createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, const Eigen::Vector3d& maxCoordinates) { - Eigen::Vector3d centerCoordinates = 0.5 * (minCoordinates + maxCoordinates); - Eigen::Vector3d lengths = maxCoordinates - minCoordinates; + // Compute coordinates of submap + const auto minXY = planarTerrain_.gridMap.getClosestPositionInMap({minCoordinates.x(), minCoordinates.y()}); + const auto maxXY = planarTerrain_.gridMap.getClosestPositionInMap({maxCoordinates.x(), maxCoordinates.y()}); + const auto centerXY = 0.5 * (minXY + maxXY); + const auto lengths = maxXY - minXY; bool success = true; - grid_map::GridMap subMap = - planarTerrain_.gridMap.getSubmap({centerCoordinates.x(), centerCoordinates.y()}, Eigen::Array2d(lengths.x(), lengths.y()), success); + grid_map::GridMap subMap = planarTerrain_.gridMap.getSubmap(centerXY, lengths, success); if (success) { signedDistanceField_ = std::make_unique(subMap, "elevation", minCoordinates.z(), maxCoordinates.z()); + } else { + std::cerr << "[SegmentedPlanesTerrainModel] Failed to get subMap" << std::endl; } } diff --git a/signed_distance_field/src/GridmapSignedDistanceField.cpp b/signed_distance_field/src/GridmapSignedDistanceField.cpp index 2c5558fe..68fcd043 100644 --- a/signed_distance_field/src/GridmapSignedDistanceField.cpp +++ b/signed_distance_field/src/GridmapSignedDistanceField.cpp @@ -25,7 +25,11 @@ GridmapSignedDistanceField::GridmapSignedDistanceField(const grid_map::GridMap& gridmap3DLookup_ = Gridmap3dLookup(gridsize, gridOrigin, gridMap.getResolution()); data_.reserve(gridmap3DLookup_.linearSize()); - computeSignedDistance(gridMap.get(elevationLayer)); + const auto& elevationData = gridMap.get(elevationLayer); + if (elevationData.hasNaN()) { + std::cerr << "[GridmapSignedDistanceField] elevation data contains NaN" << std::endl; + } + computeSignedDistance(elevationData); } GridmapSignedDistanceField::GridmapSignedDistanceField(const GridmapSignedDistanceField& other) From 92d8d6663d5b6fce0c8c4d30ed3fe56f433dc22d Mon Sep 17 00:00:00 2001 From: rgrandia Date: Fri, 11 Dec 2020 10:13:38 +0100 Subject: [PATCH 082/504] no change --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0fa1cce7..5652a860 100644 --- a/README.md +++ b/README.md @@ -57,4 +57,4 @@ You can select input map topics, pipeline parameters etc. in the respective yaml ```bash convex_plane_decomposition_ros/config/ ``` -Some other parameters are set through the launch files. \ No newline at end of file +Some other parameters are set through the launch files. From 3fd62ef02e507f25284dcf9c10fd7d86bddaca66 Mon Sep 17 00:00:00 2001 From: Jan Carius Date: Tue, 23 Feb 2021 11:47:45 +0100 Subject: [PATCH 083/504] update to ubuntu20 and ros noetic. --- README.md | 2 +- .../src/contour_extraction/ContourExtraction.cpp | 2 +- .../SlidingWindowPlaneExtractor.cpp | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5652a860..bef9dce0 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ sudo apt-get install libboost-all-dev #### JSK-visualization For rviz-visualization the jsk-library is used. ```bash -sudo apt-get install ros-melodic-jsk-visualization +sudo apt-get install ros-noetic-jsk-visualization ``` #### Grid Map diff --git a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp index 58c3b16b..1963af66 100644 --- a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp +++ b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp @@ -81,7 +81,7 @@ std::vector extractPolygonsFromBinaryImage(const cv::Mat return hierarchyVector[3] < 0; // no parent }; - cv::findContours(binary_image, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); + cv::findContours(binary_image, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE); std::vector plane_polygons; for (int i = 0; i < contours.size(); i++) { diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index 0f0a7aa1..8ea045eb 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -6,7 +6,8 @@ #include -#include +#include +#include #include From 26684a2f373c548f2198ae0570ab46285014700f Mon Sep 17 00:00:00 2001 From: rgrandia Date: Fri, 26 Feb 2021 08:32:05 +0100 Subject: [PATCH 084/504] add PCL build from source --- README.md | 9 ++++++++ pcl_catkin/.gitignore | 32 ++++++++++++++++++++++++++++ pcl_catkin/CMakeLists.txt | 31 +++++++++++++++++++++++++++ pcl_catkin/README.md | 2 ++ pcl_catkin/cmake/pcl-extras.cmake.in | 3 +++ pcl_catkin/package.xml | 13 +++++++++++ 6 files changed, 90 insertions(+) create mode 100644 pcl_catkin/.gitignore create mode 100644 pcl_catkin/CMakeLists.txt create mode 100644 pcl_catkin/README.md create mode 100644 pcl_catkin/cmake/pcl-extras.cmake.in create mode 100644 pcl_catkin/package.xml diff --git a/README.md b/README.md index bef9dce0..434d7e76 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,15 @@ sudo apt-get install libmpfr-dev sudo apt-get install libboost-all-dev ``` +#### PCL +PCL is required, but the ANYbotics distributed version does not contain visualization components. +With the following commands PCL can be build from source directly into your catkin workspace. +DO NOT do this on the ANYmal onboard PCs, only on OPC and simulation PCs. +```bash +sudo apt-get install libvtk7-dev +catkin build pcl_catkin +``` + ### ROS package dependencies #### JSK-visualization diff --git a/pcl_catkin/.gitignore b/pcl_catkin/.gitignore new file mode 100644 index 00000000..259148fa --- /dev/null +++ b/pcl_catkin/.gitignore @@ -0,0 +1,32 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app diff --git a/pcl_catkin/CMakeLists.txt b/pcl_catkin/CMakeLists.txt new file mode 100644 index 00000000..f9db00da --- /dev/null +++ b/pcl_catkin/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.10) +project(pcl_catkin) + +find_package(catkin REQUIRED) + +include(ExternalProject) + +set(VERSION 1.10.0) + +file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/include) + +set(PCL_VERSION 1.10.0) +ExternalProject_Add(pcl + URL https://github.com/PointCloudLibrary/pcl/archive/pcl-${PCL_VERSION}.tar.gz + UPDATE_COMMAND "" + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=${CATKIN_DEVEL_PREFIX} + -DCMAKE_BUILD_TYPE:STRING=Release + BUILD_COMMAND $(MAKE) + INSTALL_COMMAND $(MAKE) install +) + +catkin_package( + INCLUDE_DIRS ${CATKIN_DEVEL_PREFIX}/include + CFG_EXTRAS pcl-extras.cmake +) + +install(DIRECTORY ${CATKIN_DEVEL_PREFIX}/include/pcl-1.10/pcl/ + DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/pcl/ +) + diff --git a/pcl_catkin/README.md b/pcl_catkin/README.md new file mode 100644 index 00000000..a8b07986 --- /dev/null +++ b/pcl_catkin/README.md @@ -0,0 +1,2 @@ +# pcl_catkin +Catkin wrapper of the Point Cloud Library (PCL) diff --git a/pcl_catkin/cmake/pcl-extras.cmake.in b/pcl_catkin/cmake/pcl-extras.cmake.in new file mode 100644 index 00000000..3dc8a6c5 --- /dev/null +++ b/pcl_catkin/cmake/pcl-extras.cmake.in @@ -0,0 +1,3 @@ +# Cpp standard version +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) \ No newline at end of file diff --git a/pcl_catkin/package.xml b/pcl_catkin/package.xml new file mode 100644 index 00000000..65f211f3 --- /dev/null +++ b/pcl_catkin/package.xml @@ -0,0 +1,13 @@ + + + pcl_catkin + 1.7.2 + Catkin wrapper for PCL. + Ruben Grandia + + See package + + catkin + libvtk7-dev + + From 65229ccc1bd214dafbe136f555dda1c55990ad8f Mon Sep 17 00:00:00 2001 From: rgrandia Date: Fri, 26 Feb 2021 08:32:13 +0100 Subject: [PATCH 085/504] fix demo node --- .../config/demo_node.yaml | 1 + .../launch/demo.launch | 2 +- .../rviz/config_demo.rviz | 576 +----------------- 3 files changed, 11 insertions(+), 568 deletions(-) diff --git a/convex_plane_decomposition_ros/config/demo_node.yaml b/convex_plane_decomposition_ros/config/demo_node.yaml index a25332aa..22ceb32a 100644 --- a/convex_plane_decomposition_ros/config/demo_node.yaml +++ b/convex_plane_decomposition_ros/config/demo_node.yaml @@ -1,5 +1,6 @@ elevation_topic: '/image_to_gridmap_demo/grid_map' height_layer: 'elevation' +target_frame_id: 'odom' submap: width: 6.0 length: 6.0 diff --git a/convex_plane_decomposition_ros/launch/demo.launch b/convex_plane_decomposition_ros/launch/demo.launch index b0df4646..82561c20 100644 --- a/convex_plane_decomposition_ros/launch/demo.launch +++ b/convex_plane_decomposition_ros/launch/demo.launch @@ -24,7 +24,7 @@ - + diff --git a/convex_plane_decomposition_ros/rviz/config_demo.rviz b/convex_plane_decomposition_ros/rviz/config_demo.rviz index 9aeda245..d15f170f 100644 --- a/convex_plane_decomposition_ros/rviz/config_demo.rviz +++ b/convex_plane_decomposition_ros/rviz/config_demo.rviz @@ -38,6 +38,7 @@ Visualization Manager: Color: 25; 255; 0 Enabled: true Name: Boundaries + Queue Size: 10 Topic: /convex_plane_decomposition_ros/boundaries Unreliable: false Value: true @@ -51,6 +52,7 @@ Visualization Manager: Color: 25; 255; 0 Enabled: false Name: Insets + Queue Size: 10 Topic: /convex_plane_decomposition_ros/insets Unreliable: false Value: false @@ -125,566 +127,6 @@ Visualization Manager: {} Queue Size: 100 Value: true - - Class: anymal_rviz_plugin/AnymalDisplay - Contact Polygon: - CoM Arrow Alpha: 0.6000000238418579 - CoM Arrow Color: 0; 204; 204 - CoM Arrow Thickness: 0.029999999329447746 - CoM Polygon Projection Alpha: 0.6000000238418579 - CoM Polygon Projection Color: 0; 102; 102 - Polygon Line Color: 204; 204; 204 - Polygon Line Thickness: 0.009999999776482582 - Polygon Line alpha: 0.6000000238418579 - Show CoM Column: true - Show CoM Projection: true - Value: false - Contacts: - Alpha: 0.30000001192092896 - Color: 100; 100; 100 - Color Mode: Contact/Plane - LF_FOOT: - Alpha: 0.30000001192092896 - Color: 204; 41; 204 - Color Mode: Contact/Plane - Normal Plane Size: 0.20000000298023224 - Show Normal: true - Show Wrench: true - Value: false - Wrench Arrow Width: 0.009999999776482582 - Wrench Scale: 0.003000000026077032 - LH_FOOT: - Alpha: 0.30000001192092896 - Color: 204; 41; 204 - Color Mode: Contact/Plane - Normal Plane Size: 0.20000000298023224 - Show Normal: true - Show Wrench: true - Value: false - Wrench Arrow Width: 0.009999999776482582 - Wrench Scale: 0.003000000026077032 - Normal Plane Size: 0.20000000298023224 - RF_FOOT: - Alpha: 0.30000001192092896 - Color: 204; 41; 204 - Color Mode: Contact/Plane - Normal Plane Size: 0.20000000298023224 - Show Normal: true - Show Wrench: true - Value: false - Wrench Arrow Width: 0.009999999776482582 - Wrench Scale: 0.003000000026077032 - RH_FOOT: - Alpha: 0.30000001192092896 - Color: 204; 41; 204 - Color Mode: Contact/Plane - Normal Plane Size: 0.20000000298023224 - Show Normal: true - Show Wrench: true - Value: false - Wrench Arrow Width: 0.009999999776482582 - Wrench Scale: 0.003000000026077032 - Show Normal: true - Show Wrench: true - Value: false - Wrench Arrow Width: 0.009999999776482582 - Wrench Scale: 0.003000000026077032 - Enabled: true - Joint Torques: - Alpha: 1 - Color: 240; 240; 240 - Color Mode: - Threshold: 0.75 - Value: Solid Color - LF_HAA: - Offset: 0 - Torque Maximum: 40 - Value: false - LF_HFE: - Offset: 0 - Torque Maximum: 40 - Value: false - LF_KFE: - Offset: 0 - Torque Maximum: 40 - Value: false - LH_HAA: - Offset: 0 - Torque Maximum: 40 - Value: false - LH_HFE: - Offset: 0 - Torque Maximum: 40 - Value: false - LH_KFE: - Offset: 0 - Torque Maximum: 40 - Value: false - RF_HAA: - Offset: 0 - Torque Maximum: 40 - Value: false - RF_HFE: - Offset: 0 - Torque Maximum: 40 - Value: false - RF_KFE: - Offset: 0 - Torque Maximum: 40 - Value: false - RH_HAA: - Offset: 0 - Torque Maximum: 40 - Value: false - RH_HFE: - Offset: 0 - Torque Maximum: 40 - Value: false - RH_KFE: - Offset: 0 - Torque Maximum: 40 - Value: false - Size: 0.10000000149011612 - Value: false - Name: AnymalDisplay - Robot Description: anymal_description - Robot Display Options: - Alpha: 1 - Collision Enabled: false - Color Mode: - Color: 204; 204; 204 - Value: Mesh Texture - Links: - All Links Enabled: true - Expand Joint Details: false - Expand Link Details: false - Expand Tree: false - LF_FOOT: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LF_HAA: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LF_HFE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LF_HIP: - Alpha: 1 - Show Axes: false - Show Trail: false - LF_KFE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LF_SHANK: - Alpha: 1 - Show Axes: false - Show Trail: false - LF_THIGH: - Alpha: 1 - Show Axes: false - Show Trail: false - LF_hip_fixed: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LF_shank_fixed: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LF_thigh_fixed: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LH_FOOT: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LH_HAA: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LH_HFE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LH_HIP: - Alpha: 1 - Show Axes: false - Show Trail: false - LH_KFE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LH_SHANK: - Alpha: 1 - Show Axes: false - Show Trail: false - LH_THIGH: - Alpha: 1 - Show Axes: false - Show Trail: false - LH_hip_fixed: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LH_shank_fixed: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LH_thigh_fixed: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - Link Tree Style: Links in Alphabetic Order - RF_FOOT: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RF_HAA: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RF_HFE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RF_HIP: - Alpha: 1 - Show Axes: false - Show Trail: false - RF_KFE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RF_SHANK: - Alpha: 1 - Show Axes: false - Show Trail: false - RF_THIGH: - Alpha: 1 - Show Axes: false - Show Trail: false - RF_hip_fixed: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RF_shank_fixed: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RF_thigh_fixed: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RH_FOOT: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RH_HAA: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RH_HFE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RH_HIP: - Alpha: 1 - Show Axes: false - Show Trail: false - RH_KFE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RH_SHANK: - Alpha: 1 - Show Axes: false - Show Trail: false - RH_THIGH: - Alpha: 1 - Show Axes: false - Show Trail: false - RH_hip_fixed: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RH_shank_fixed: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RH_thigh_fixed: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - base: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - base_inertia: - Alpha: 1 - Show Axes: false - Show Trail: false - battery: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - blackfly_front_camera: - Alpha: 1 - Show Axes: false - Show Trail: false - blackfly_front_camera_parent: - Alpha: 1 - Show Axes: false - Show Trail: false - blackfly_rear_camera: - Alpha: 1 - Show Axes: false - Show Trail: false - blackfly_rear_camera_parent: - Alpha: 1 - Show Axes: false - Show Trail: false - docking_socket: - Alpha: 1 - Show Axes: false - Show Trail: false - face_front: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - face_rear: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - hatch: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - imu_link: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - realsense_d435_front_camera: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_front_camera_parent: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_front_color_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_front_color_optical_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_front_depth_optical_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_left_camera: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_left_camera_parent: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_left_color_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_left_color_optical_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_left_depth_optical_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_rear_camera: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_rear_camera_parent: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_rear_color_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_rear_color_optical_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_rear_depth_optical_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_right_camera: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_right_camera_parent: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_right_color_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_right_color_optical_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - realsense_d435_right_depth_optical_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - shell: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - velodyne: - Alpha: 1 - Show Axes: false - Show Trail: false - velodyne_cage: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - Visual Enabled: true - Robot Velocity: - Alpha: 0.6000000238418579 - Angular Color: 0; 204; 0 - Angular Scale: 0.5 - Linear Color: 0; 0; 204 - Linear Scale: 1 - Offset: 0.4000000059604645 - Show Angular: true - Show Linear: true - Value: false - Topic: /state_estimator/anymal_state - Traces: - Alpha: 0.5 - Color: 255; 0; 0 - LF_FOOT: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - LF_HIP: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - LF_SHANK: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - LF_THIGH: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - LH_FOOT: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - LH_HIP: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - LH_SHANK: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - LH_THIGH: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - RF_FOOT: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - RF_HIP: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - RF_SHANK: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - RF_THIGH: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - RH_FOOT: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - RH_HIP: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - RH_SHANK: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - RH_THIGH: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - Time Length: 10 - Value: false - Width: 0.004999999888241291 - base: - Alpha: 0.5 - Color: 255; 0; 0 - Value: false - Unreliable: false - Update Rate: 20 - Value: true - World Frame Name: odom Enabled: true Global Options: Background Color: 255; 255; 255 @@ -713,25 +155,25 @@ Visualization Manager: Views: Current: Class: rviz/Orbit - Distance: 2.9079933166503906 + Distance: 7.077206611633301 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 Swap Stereo Eyes: false Value: false + Field of View: 0.7853981852531433 Focal Point: - X: 2.382049322128296 - Y: -0.7195556163787842 - Z: -0.01261717639863491 + X: 1.0492274761199951 + Y: -0.5030490159988403 + Z: -2.4208056926727295 Focal Shape Fixed Size: true Focal Shape Size: 0.05000000074505806 Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.499797523021698 + Pitch: 0.6197975277900696 Target Frame: - Value: Orbit (rviz) - Yaw: 1.5949591398239136 + Yaw: 2.844961643218994 Saved: ~ Window Geometry: Displays: From 63b70fa2c4f1fe533e7a5f630105d01a9449a809 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Fri, 26 Feb 2021 08:38:50 +0100 Subject: [PATCH 086/504] add correct version to package.xml --- pcl_catkin/package.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcl_catkin/package.xml b/pcl_catkin/package.xml index 65f211f3..afe59140 100644 --- a/pcl_catkin/package.xml +++ b/pcl_catkin/package.xml @@ -1,7 +1,7 @@ pcl_catkin - 1.7.2 + 1.10.0 Catkin wrapper for PCL. Ruben Grandia From 9efcaffc47d93865a31ba5c1dcd4cce0eca0829f Mon Sep 17 00:00:00 2001 From: rgrandia Date: Fri, 26 Feb 2021 11:01:24 +0100 Subject: [PATCH 087/504] fix launch file name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 434d7e76..df2bef02 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ catkin build convex_plane_decomposition_ros ``` ### Run demo ```bash -roslaunch convex_plane_decomposition_ros convex_plane_decomposition_demo.launch +roslaunch convex_plane_decomposition_ros demo.launch ``` ### Parameters From 44ab36fe144a99149781b92e39705f5aa324a6c3 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 3 Mar 2021 15:10:25 +0100 Subject: [PATCH 088/504] fix maintainer, remove grid_map_rviz from dependencies. --- convex_plane_decomposition/package.xml | 2 +- convex_plane_decomposition_ros/CMakeLists.txt | 1 - convex_plane_decomposition_ros/package.xml | 3 +-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/convex_plane_decomposition/package.xml b/convex_plane_decomposition/package.xml index df94a10d..a9084924 100644 --- a/convex_plane_decomposition/package.xml +++ b/convex_plane_decomposition/package.xml @@ -4,7 +4,7 @@ 0.0.0 The convex_plane_decomposition package - andrej + Ruben Grandia TODO diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index ef57d760..1c34b62f 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -8,7 +8,6 @@ set(CATKIN_PACKAGE_DEPENDENCIES grid_map_ros grid_map_cv grid_map_msgs - grid_map_rviz_plugin geometry_msgs jsk_recognition_msgs convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/package.xml b/convex_plane_decomposition_ros/package.xml index 74382d54..126edcfe 100644 --- a/convex_plane_decomposition_ros/package.xml +++ b/convex_plane_decomposition_ros/package.xml @@ -4,7 +4,7 @@ 0.0.0 The convex_plane_decomposition_ros package - andrej + Ruben Grandia TODO @@ -14,7 +14,6 @@ grid_map_ros grid_map_cv grid_map_msgs - grid_map_rviz_plugin geometry_msgs jsk_recognition_msgs convex_plane_decomposition From e18bd1575fbe75621d9367aa1450990a70dda543 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 8 Apr 2021 16:03:22 +0200 Subject: [PATCH 089/504] implement resampling to change the gridmap resolution --- .../GridMapPreprocessing.h | 9 ++++-- .../src/GridMapPreprocessing.cpp | 31 +++++++++++++++++-- .../config/image_loader_demo_parameters.yaml | 6 ---- .../config/parameters.yaml | 1 + .../launch/demo.launch | 4 +-- .../src/ParameterLoading.cpp | 1 + 6 files changed, 37 insertions(+), 15 deletions(-) delete mode 100644 convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h index 9cb83f68..d8ab63ed 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h @@ -7,6 +7,8 @@ namespace convex_plane_decomposition { struct PreprocessingParameters { + /// Resample to this resolution, set to negative values to skip + double resolution = -1.0; /// Kernel size of the median filter int kernelSize = 5; /// Number of times the image is filtered @@ -21,11 +23,12 @@ class GridMapPreprocessing { public: GridMapPreprocessing(const PreprocessingParameters& parameters); - void preprocess(grid_map::GridMap& gridMap, const std::string& layer); + void preprocess(grid_map::GridMap& gridMap, const std::string& layer) const; private: - void denoise(grid_map::GridMap& gridMap, const std::string& layer); - void inpaint(grid_map::GridMap& gridMap, const std::string& layer, float minValue, float maxValue); + void denoise(grid_map::GridMap& gridMap, const std::string& layer) const; + void changeResolution(grid_map::GridMap& gridMap, const std::string& layer) const; + void inpaint(grid_map::GridMap& gridMap, const std::string& layer, float minValue, float maxValue) const; PreprocessingParameters parameters_; }; diff --git a/convex_plane_decomposition/src/GridMapPreprocessing.cpp b/convex_plane_decomposition/src/GridMapPreprocessing.cpp index 650e59a5..92ad38cf 100644 --- a/convex_plane_decomposition/src/GridMapPreprocessing.cpp +++ b/convex_plane_decomposition/src/GridMapPreprocessing.cpp @@ -12,7 +12,7 @@ namespace convex_plane_decomposition { GridMapPreprocessing::GridMapPreprocessing(const PreprocessingParameters& parameters) : parameters_(parameters) {} -void GridMapPreprocessing::preprocess(grid_map::GridMap& gridMap, const std::string& layer) { +void GridMapPreprocessing::preprocess(grid_map::GridMap& gridMap, const std::string& layer) const { const float minValue = gridMap.get(layer).minCoeffOfFinites(); const float maxValue = gridMap.get(layer).maxCoeffOfFinites(); @@ -21,10 +21,11 @@ void GridMapPreprocessing::preprocess(grid_map::GridMap& gridMap, const std::str if (parameters_.inpaintRadius > 0) { inpaint(gridMap, layer, minValue, maxValue); + changeResolution(gridMap, layer); } } -void GridMapPreprocessing::denoise(grid_map::GridMap& gridMap, const std::string& layer) { +void GridMapPreprocessing::denoise(grid_map::GridMap& gridMap, const std::string& layer) const { Eigen::MatrixXf& elevation_map = gridMap.get(layer); cv::Mat elevationImage; @@ -41,7 +42,31 @@ void GridMapPreprocessing::denoise(grid_map::GridMap& gridMap, const std::string cv::cv2eigen(elevationImage, elevation_map); } -void GridMapPreprocessing::inpaint(grid_map::GridMap& gridMap, const std::string& layer, float minValue, float maxValue) { +void GridMapPreprocessing::changeResolution(grid_map::GridMap& gridMap, const std::string& layer) const { + if (parameters_.resolution > 0.0 && gridMap.getResolution() != parameters_.resolution) { + Eigen::MatrixXf elevation_map = std::move(gridMap.get(layer)); + + cv::Mat elevationImage; + cv::eigen2cv(elevation_map, elevationImage); + + double scaling = gridMap.getResolution() / parameters_.resolution; + int width = int(elevationImage.size[1] * scaling); + int height = int(elevationImage.size[0] * scaling); + cv::Size dim{width, height}; + + cv::Mat resizedImage; + cv::resize(elevationImage, resizedImage, dim, 0, 0, cv::INTER_LINEAR); + + cv::cv2eigen(resizedImage, elevation_map); + + const auto oldPosition = gridMap.getPosition(); + gridMap.setGeometry({elevation_map.rows() * parameters_.resolution, elevation_map.cols() * parameters_.resolution}, + parameters_.resolution, oldPosition); + gridMap.get(layer) = std::move(elevation_map); + } +} + +void GridMapPreprocessing::inpaint(grid_map::GridMap& gridMap, const std::string& layer, float minValue, float maxValue) const { Eigen::MatrixXf& elevation_map = gridMap.get(layer); Eigen::Matrix mask = elevation_map.unaryExpr([](float val) { return (isNan(val)) ? uchar(1) : uchar(0); }); diff --git a/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml b/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml deleted file mode 100644 index fcf5ef45..00000000 --- a/convex_plane_decomposition_ros/config/image_loader_demo_parameters.yaml +++ /dev/null @@ -1,6 +0,0 @@ -image_to_gridmap_demo: - image_topic: "/image_publisher/image" - resolution: 0.02 - map_frame_id: "map" # This parameter is actually not used. The gridmap is always in map frame - min_height: 0 - max_height: 1.0 \ No newline at end of file diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 1ac210c1..bbc9780f 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -1,4 +1,5 @@ preprocessing: + resolution: 0.02 # Resampling resolution, set negative to skip, requires inpainting to be used kernelSize: 3 # Kernel size of the median filter numberOfRepeats: 3 # Number of times to apply the same filter increasing: True # Increase the kernel size each iteration. diff --git a/convex_plane_decomposition_ros/launch/demo.launch b/convex_plane_decomposition_ros/launch/demo.launch index 82561c20..6f37b3e5 100644 --- a/convex_plane_decomposition_ros/launch/demo.launch +++ b/convex_plane_decomposition_ros/launch/demo.launch @@ -3,8 +3,6 @@ - - @@ -15,7 +13,7 @@ - + diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/convex_plane_decomposition_ros/src/ParameterLoading.cpp index 76c3b688..034c38b9 100644 --- a/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ b/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -16,6 +16,7 @@ void loadParameter(const ros::NodeHandle& nodeHandle, const std::string& prefix, PreprocessingParameters loadPreprocessingParameters(const ros::NodeHandle& nodeHandle, const std::string& prefix) { PreprocessingParameters preprocessingParameters; + loadParameter(nodeHandle, prefix, "resolution", preprocessingParameters.resolution); loadParameter(nodeHandle, prefix, "kernelSize", preprocessingParameters.kernelSize); loadParameter(nodeHandle, prefix, "numberOfRepeats", preprocessingParameters.numberOfRepeats); loadParameter(nodeHandle, prefix, "increasing", preprocessingParameters.increasing); From ae8933b978eb1bbb9baa095a9a01346313fe4f6c Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 6 May 2021 08:58:58 +0200 Subject: [PATCH 090/504] add height offset as postprocessing --- convex_plane_decomposition/CMakeLists.txt | 9 +++---- .../Postprocessing.h | 24 +++++++++++++++++++ .../src/Postprocessing.cpp | 19 +++++++++++++++ .../config/parameters.yaml | 3 +++ .../ConvexPlaneDecompositionRos.h | 2 ++ .../ParameterLoading.h | 3 +++ .../src/ConvexPlaneDecompositionRos.cpp | 7 ++++++ .../src/ParameterLoading.cpp | 6 +++++ 8 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h create mode 100644 convex_plane_decomposition/src/Postprocessing.cpp diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 9a973bb5..dafad609 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -53,12 +53,13 @@ include_directories( ) add_library(${PROJECT_NAME} - src/contour_extraction/ContourExtraction.cpp - src/ransac/RansacPlaneExtractor.cpp + src/contour_extraction/ContourExtraction.cpp + src/ransac/RansacPlaneExtractor.cpp src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp src/GridMapPreprocessing.cpp - src/ConvexRegionGrowing.cpp - src/Draw.cpp + src/ConvexRegionGrowing.cpp + src/Draw.cpp + src/Postprocessing.cpp ) add_dependencies(${PROJECT_NAME} ${catkin_EXPORTED_TARGETS} diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h b/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h new file mode 100644 index 00000000..ff058f6f --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h @@ -0,0 +1,24 @@ +#pragma once + +#include "convex_plane_decomposition/PlanarRegion.h" + +namespace convex_plane_decomposition { + +struct PostprocessingParameters { + /// Added offset in z direction to compensate for the location of the foot frame w.r.t. the elevation map + double extracted_planes_height_offset = 0.0; +}; + +class Postprocessing { + public: + Postprocessing(const PostprocessingParameters& parameters); + + void postprocess(PlanarTerrain& planarTerrain) const; + + private: + void addHeightOffset(PlanarTerrain& planarTerrain) const; + + PostprocessingParameters parameters_; +}; + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/src/Postprocessing.cpp b/convex_plane_decomposition/src/Postprocessing.cpp new file mode 100644 index 00000000..5ace7cb6 --- /dev/null +++ b/convex_plane_decomposition/src/Postprocessing.cpp @@ -0,0 +1,19 @@ +#include "convex_plane_decomposition/Postprocessing.h" + +namespace convex_plane_decomposition { + +Postprocessing::Postprocessing(const PostprocessingParameters& parameters) : parameters_(parameters) {} + +void Postprocessing::postprocess(PlanarTerrain& planarTerrain) const { + addHeightOffset(planarTerrain); +} + +void Postprocessing::addHeightOffset(PlanarTerrain& planarTerrain) const { + if (parameters_.extracted_planes_height_offset != 0.0) { + for (auto& planarRegion : planarTerrain.planarRegions) { + planarRegion.planeParameters.positionInWorld.z() += parameters_.extracted_planes_height_offset; + } + } +} + +} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index bbc9780f..46355abb 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -24,3 +24,6 @@ ransac_plane_refinement: contour_extraction: offsetSize: 2 # Size of the kernel creating the boundary offset. In number of pixels. + +postprocessing: + extracted_planes_height_offset: 0.02 # Added offset in z direction to compensate for the location of the foot frame w.r.t. the elevation map diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h index 6b37f375..279002c3 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h @@ -16,6 +16,7 @@ namespace convex_plane_decomposition { // Forward declarations class GridMapPreprocessing; +class Postprocessing; namespace sliding_window_plane_extractor { class SlidingWindowPlaneExtractor; } @@ -62,6 +63,7 @@ class ConvexPlaneExtractionROS { std::unique_ptr preprocessing_; std::unique_ptr slidingWindowPlaneExtractor_; std::unique_ptr contourExtraction_; + std::unique_ptr postprocessing_; }; } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h index fffd28d7..704ad73a 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -24,4 +25,6 @@ ransac_plane_extractor::RansacPlaneExtractorParameters loadRansacPlaneExtractorP sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters loadSlidingWindowPlaneExtractorParameters( const ros::NodeHandle& nodeHandle, const std::string& prefix); +PostprocessingParameters loadPostprocessingParameters(const ros::NodeHandle& nodeHandle, const std::string& prefix); + } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 8407842f..288e5165 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -67,12 +68,14 @@ bool ConvexPlaneExtractionROS::loadParameters(const ros::NodeHandle& nodeHandle) const auto ransacPlaneExtractorParameters = loadRansacPlaneExtractorParameters(nodeHandle, "ransac_plane_refinement/"); const auto slidingWindowPlaneExtractorParameters = loadSlidingWindowPlaneExtractorParameters(nodeHandle, "sliding_window_plane_extractor/"); + const auto postprocessingParameters = loadPostprocessingParameters(nodeHandle, "postprocessing/"); std::lock_guard lock(mutex_); preprocessing_ = std::make_unique(preprocessingParameters); slidingWindowPlaneExtractor_ = std::make_unique( slidingWindowPlaneExtractorParameters, ransacPlaneExtractorParameters); contourExtraction_ = std::make_unique(contourExtractionParameters); + postprocessing_ = std::make_unique(postprocessingParameters); return true; } @@ -119,6 +122,10 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { // Add grid map to the terrain planarTerrain.gridMap = std::move(elevationMap); + postprocessing_->postprocess(planarTerrain); + auto t4 = std::chrono::high_resolution_clock::now(); + ROS_INFO_STREAM("Postprocessing took " << 1e-3 * std::chrono::duration_cast(t4 - t3).count() << " [ms]"); + // Publish terrain if (publishToController_) { regionPublisher_.publish(toMessage(planarTerrain)); diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/convex_plane_decomposition_ros/src/ParameterLoading.cpp index 034c38b9..4936b7d6 100644 --- a/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ b/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -57,4 +57,10 @@ sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters loadSlidin return swParams; } +PostprocessingParameters loadPostprocessingParameters(const ros::NodeHandle& nodeHandle, const std::string& prefix) { + PostprocessingParameters postprocessingParameters; + loadParameter(nodeHandle, prefix, "extracted_planes_height_offset", postprocessingParameters.extracted_planes_height_offset); + return postprocessingParameters; +} + } // namespace convex_plane_decomposition From 5f8f5a37a4547d247e8b0a5c2f9bb7141f40164b Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 6 May 2021 10:09:24 +0200 Subject: [PATCH 091/504] tune segmentation parameters --- .../ransac/RansacPlaneExtractorParameters.h | 6 +++--- .../src/ransac/RansacPlaneExtractor.cpp | 2 +- convex_plane_decomposition_ros/config/parameters.yaml | 10 +++++----- .../src/ConvexPlaneDecompositionRos.cpp | 2 ++ 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h index 60fe43ef..bb1f3ba9 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h @@ -11,13 +11,13 @@ struct RansacPlaneExtractorParameters { double probability = 0.01; /// Detect shapes with at least 200 points. double min_points = 200; - /// Set maximum Euclidean distance between a point and a shape. + /// [m] Set maximum Euclidean distance between a point and a shape. double epsilon = 0.004; /// Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most /// 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon double cluster_epsilon = 0.03; - /// Set maximum normal deviation. normal_threshold < dot(surface_normal, point_normal); - double normal_threshold = 0.98; + /// [deg] Set maximum normal deviation between cluster surface_normal and point normal. + double normal_threshold = 25.0; }; } // namespace ransac_plane_extractor diff --git a/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp b/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp index ccc70966..b035af32 100644 --- a/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp @@ -12,7 +12,7 @@ void RansacPlaneExtractor::setParameters(const RansacPlaneExtractorParameters& p cgalRansacParameters_.min_points = parameters.min_points; cgalRansacParameters_.epsilon = parameters.epsilon; cgalRansacParameters_.cluster_epsilon = parameters.cluster_epsilon; - cgalRansacParameters_.normal_threshold = parameters.normal_threshold; + cgalRansacParameters_.normal_threshold = std::cos(parameters.normal_threshold * M_PI / 180.0); } void RansacPlaneExtractor::detectPlanes(std::vector& points_with_normal) { diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 46355abb..72f81315 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -12,15 +12,15 @@ sliding_window_plane_extractor: min_number_points_per_label: 10 # [#] Labels with less points assigned to them are discarded connectivity: 4 # Label kernel connectivity. 4 or 8 (cross or box) include_ransac_refinement: true # Enable RANSAC refinement if the plane is not globally fitting to the assigned points. - global_plane_fit_distance_error_threshold: 0.04 # [m] Allowed maximum distance from a point to the plane. If any point violates this, RANSAC is triggered - global_plane_fit_angle_error_threshold_degrees: 5.0 # [deg] Allowed normal vector deviation for a point w.r.t. the plane normal. If any point violates this, RANSAC is triggered + global_plane_fit_distance_error_threshold: 0.025 # [m] Allowed maximum distance from a point to the plane. If any point violates this, RANSAC is triggered + global_plane_fit_angle_error_threshold_degrees: 25.0 # [deg] Allowed normal vector deviation for a point w.r.t. the plane normal. If any point violates this, RANSAC is triggered ransac_plane_refinement: probability: 0.01 # Probability to miss the largest candidate shape. A lower probability provides a higher reliability and determinism at the cost of longer running times min_points: 25 # This minimum number of points per plane. Controls the termination of the algorithm. - epsilon: 0.02 # Maximum distance to plane - cluster_epsilon: 0.02 # Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon - normal_threshold: 0.98 # Set maximum normal deviation. normal_threshold < dot(surface_normal, point_normal); + epsilon: 0.025 # Maximum distance to plane + cluster_epsilon: 0.02 # [m] Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon + normal_threshold: 25.0 # [deg] Set maximum normal deviation between cluster surface_normal and point normal. contour_extraction: offsetSize: 2 # Size of the kernel creating the boundary offset. In number of pixels. diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 288e5165..025e74b0 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -133,6 +133,8 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { // Visualize in Rviz. reapplyNans(planarTerrain.gridMap.get(elevationLayer_)); + // planarTerrain.gridMap.add("plane_classification"); + // cv::cv2eigen(slidingWindowPlaneExtractor_->getBinaryLabeledImage(), planarTerrain.gridMap.get("plane_classification")); planarTerrain.gridMap.add("segmentation"); cv::cv2eigen(slidingWindowPlaneExtractor_->getSegmentedPlanesMap().labeledImage, planarTerrain.gridMap.get("segmentation")); grid_map_msgs::GridMap outputMessage; From a70176f323c8b083878e7e85728f1f06f2283e8c Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 11 May 2021 18:40:02 +0200 Subject: [PATCH 092/504] also lift elevation map in postprocessing --- .../convex_plane_decomposition/Postprocessing.h | 4 ++-- convex_plane_decomposition/src/Postprocessing.cpp | 10 +++++++--- .../src/ConvexPlaneDecompositionRos.cpp | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h b/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h index ff058f6f..7d178a78 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h @@ -13,10 +13,10 @@ class Postprocessing { public: Postprocessing(const PostprocessingParameters& parameters); - void postprocess(PlanarTerrain& planarTerrain) const; + void postprocess(PlanarTerrain& planarTerrain, const std::string& layer) const; private: - void addHeightOffset(PlanarTerrain& planarTerrain) const; + void addHeightOffset(PlanarTerrain& planarTerrain, const std::string& layer) const; PostprocessingParameters parameters_; }; diff --git a/convex_plane_decomposition/src/Postprocessing.cpp b/convex_plane_decomposition/src/Postprocessing.cpp index 5ace7cb6..fd703e7c 100644 --- a/convex_plane_decomposition/src/Postprocessing.cpp +++ b/convex_plane_decomposition/src/Postprocessing.cpp @@ -4,15 +4,19 @@ namespace convex_plane_decomposition { Postprocessing::Postprocessing(const PostprocessingParameters& parameters) : parameters_(parameters) {} -void Postprocessing::postprocess(PlanarTerrain& planarTerrain) const { - addHeightOffset(planarTerrain); +void Postprocessing::postprocess(PlanarTerrain& planarTerrain, const std::string& layer) const { + addHeightOffset(planarTerrain, layer); } -void Postprocessing::addHeightOffset(PlanarTerrain& planarTerrain) const { +void Postprocessing::addHeightOffset(PlanarTerrain& planarTerrain, const std::string& layer) const { if (parameters_.extracted_planes_height_offset != 0.0) { + // Lift planar regions for (auto& planarRegion : planarTerrain.planarRegions) { planarRegion.planeParameters.positionInWorld.z() += parameters_.extracted_planes_height_offset; } + + // lift elevation layer + planarTerrain.gridMap.get(layer).array() += parameters_.extracted_planes_height_offset; } } diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 025e74b0..4a7ea73f 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -122,7 +122,7 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { // Add grid map to the terrain planarTerrain.gridMap = std::move(elevationMap); - postprocessing_->postprocess(planarTerrain); + postprocessing_->postprocess(planarTerrain, elevationLayer_); auto t4 = std::chrono::high_resolution_clock::now(); ROS_INFO_STREAM("Postprocessing took " << 1e-3 * std::chrono::duration_cast(t4 - t3).count() << " [ms]"); From 69424094767cd98d610629f6df341d1a843bea07 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 8 Jun 2021 09:20:51 +0200 Subject: [PATCH 093/504] fix median filter kernel size --- .../convex_plane_decomposition/GridMapPreprocessing.h | 2 +- convex_plane_decomposition/src/GridMapPreprocessing.cpp | 8 +++++--- convex_plane_decomposition_ros/config/parameters.yaml | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h index d8ab63ed..9fef5c32 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h @@ -9,7 +9,7 @@ namespace convex_plane_decomposition { struct PreprocessingParameters { /// Resample to this resolution, set to negative values to skip double resolution = -1.0; - /// Kernel size of the median filter + /// Kernel size of the median filter, either 3 or 5 int kernelSize = 5; /// Number of times the image is filtered int numberOfRepeats = 1; diff --git a/convex_plane_decomposition/src/GridMapPreprocessing.cpp b/convex_plane_decomposition/src/GridMapPreprocessing.cpp index 92ad38cf..b72ce854 100644 --- a/convex_plane_decomposition/src/GridMapPreprocessing.cpp +++ b/convex_plane_decomposition/src/GridMapPreprocessing.cpp @@ -29,12 +29,14 @@ void GridMapPreprocessing::denoise(grid_map::GridMap& gridMap, const std::string Eigen::MatrixXf& elevation_map = gridMap.get(layer); cv::Mat elevationImage; - cv::eigen2cv(elevation_map, elevationImage); + cv::eigen2cv(elevation_map, elevationImage); // creates CV_32F image int kernelSize = parameters_.kernelSize; + for (int i = 0; i < parameters_.numberOfRepeats; ++i) { - cv::medianBlur(elevationImage, elevationImage, parameters_.kernelSize); - if (parameters_.increasing) { + kernelSize = std::max(3, std::min(kernelSize, 5)); // must be 3 or 5 for current image type, see doc of cv::medianBlur + cv::medianBlur(elevationImage, elevationImage, kernelSize); + if (parameters_.increasing) { // TODO (rgrandia) : remove this option or enable kernels of other size than 3 / 5 kernelSize += 2; } } diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 72f81315..717ae0b9 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -1,8 +1,8 @@ preprocessing: resolution: 0.02 # Resampling resolution, set negative to skip, requires inpainting to be used - kernelSize: 3 # Kernel size of the median filter + kernelSize: 3 # Kernel size of the median filter, either 3 or 5 numberOfRepeats: 3 # Number of times to apply the same filter - increasing: True # Increase the kernel size each iteration. + increasing: False # Increase the kernel size each iteration. inpaintRadius: 0.05 # [m] sliding_window_plane_extractor: From 9ebf94da7f3e8201723ee991586affc5d189d0ca Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 24 Jun 2021 17:46:48 +0200 Subject: [PATCH 094/504] blow up non-planar region for better collision avoidance --- .../Postprocessing.h | 17 +++++- .../src/Postprocessing.cpp | 57 ++++++++++++++++--- .../config/parameters.yaml | 4 +- .../src/ConvexPlaneDecompositionRos.cpp | 10 +++- .../src/ParameterLoading.cpp | 2 + 5 files changed, 76 insertions(+), 14 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h b/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h index 7d178a78..d56279ff 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h @@ -7,16 +7,29 @@ namespace convex_plane_decomposition { struct PostprocessingParameters { /// Added offset in z direction to compensate for the location of the foot frame w.r.t. the elevation map double extracted_planes_height_offset = 0.0; + + /// Added offset in z direction added in cells that are not traversable + double nonplanar_height_offset = 0.0; + + /// Size of the kernel creating the boundary offset. In number of pixels. + int nonplanar_horizontal_offset = 2; }; class Postprocessing { public: Postprocessing(const PostprocessingParameters& parameters); - void postprocess(PlanarTerrain& planarTerrain, const std::string& layer) const; + /** + * @param planarTerrain + * @param elevationLayer : name of the elevation layer + * @param planeSegmentationLayer : name of the planarity layer with planar = 1.0, non-planar = 0.0 + */ + void postprocess(PlanarTerrain& planarTerrain, const std::string& elevationLayer, const std::string& planeSegmentationLayer) const; private: - void addHeightOffset(PlanarTerrain& planarTerrain, const std::string& layer) const; + void dilationInNonplanarRegions(Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const; + void addHeightOffset(Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const; + void addHeightOffset(std::vector& planarRegions) const; PostprocessingParameters parameters_; }; diff --git a/convex_plane_decomposition/src/Postprocessing.cpp b/convex_plane_decomposition/src/Postprocessing.cpp index fd703e7c..f0e5887d 100644 --- a/convex_plane_decomposition/src/Postprocessing.cpp +++ b/convex_plane_decomposition/src/Postprocessing.cpp @@ -1,22 +1,63 @@ #include "convex_plane_decomposition/Postprocessing.h" +#include +#include +#include + namespace convex_plane_decomposition { Postprocessing::Postprocessing(const PostprocessingParameters& parameters) : parameters_(parameters) {} -void Postprocessing::postprocess(PlanarTerrain& planarTerrain, const std::string& layer) const { - addHeightOffset(planarTerrain, layer); +void Postprocessing::postprocess(PlanarTerrain& planarTerrain, const std::string& elevationLayer, + const std::string& planeSegmentationLayer) const { + auto& elevationData = planarTerrain.gridMap.get(elevationLayer); + const auto& planarityMask = planarTerrain.gridMap.get(planeSegmentationLayer); + + // post process planar regions + addHeightOffset(planarTerrain.planarRegions); + + // post process elevation map + dilationInNonplanarRegions(elevationData, planarityMask); + addHeightOffset(elevationData, planarityMask); } -void Postprocessing::addHeightOffset(PlanarTerrain& planarTerrain, const std::string& layer) const { +void Postprocessing::dilationInNonplanarRegions(Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const { + if (parameters_.nonplanar_horizontal_offset > 0) { + // Convert to opencv image + cv::Mat elevationImage; + cv::eigen2cv(elevationData, elevationImage); // creates CV_32F image + + // dilate + const int dilationSize = 2 * parameters_.nonplanar_horizontal_offset + 1; // + const int dilationType = cv::MORPH_ELLIPSE; // ellipse inscribed in the square of size dilationSize + const auto dilationKernel_ = cv::getStructuringElement(dilationType, cv::Size(dilationSize, dilationSize)); + cv::dilate(elevationImage, elevationImage, dilationKernel_); + + // convert back + Eigen::MatrixXf elevationDilated; + cv::cv2eigen(elevationImage, elevationDilated); + + // merge: original elevation for planar regions (mask = 1.0), dilated elevation for non-planar (mask = 0.0) + elevationData = planarityMask.array() * elevationData.array() + (1.0 - planarityMask.array()) * elevationDilated.array(); + } +} + +void Postprocessing::addHeightOffset(Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const { + // lift elevation layer. For untraversable offset we first add the offset everywhere and substract it again in traversable regions. + if (parameters_.extracted_planes_height_offset != 0.0 || parameters_.nonplanar_height_offset != 0.0) { + elevationData.array() += (parameters_.extracted_planes_height_offset + parameters_.nonplanar_height_offset); + + if (parameters_.nonplanar_height_offset != 0.0) { + elevationData.noalias() -= parameters_.nonplanar_height_offset * planarityMask; + } + } +} + +void Postprocessing::addHeightOffset(std::vector& planarRegions) const { if (parameters_.extracted_planes_height_offset != 0.0) { - // Lift planar regions - for (auto& planarRegion : planarTerrain.planarRegions) { + for (auto& planarRegion : planarRegions) { planarRegion.planeParameters.positionInWorld.z() += parameters_.extracted_planes_height_offset; } - - // lift elevation layer - planarTerrain.gridMap.get(layer).array() += parameters_.extracted_planes_height_offset; } } diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 717ae0b9..804feaf8 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -26,4 +26,6 @@ contour_extraction: offsetSize: 2 # Size of the kernel creating the boundary offset. In number of pixels. postprocessing: - extracted_planes_height_offset: 0.02 # Added offset in z direction to compensate for the location of the foot frame w.r.t. the elevation map + extracted_planes_height_offset: 0.02 # Added offset in Z direction for the full map to compensate for the location of the foot frame w.r.t. the contact point + nonplanar_height_offset: 0.02 # Added offset in Z direction for non-planar cells of the map. (Additional to extracted_planes_height_offset) + nonplanar_horizontal_offset: 2 # Added offset in XY direction for non-planar cells of the map. In number of pixels. \ No newline at end of file diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 4a7ea73f..54d6f8f8 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -122,7 +122,13 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { // Add grid map to the terrain planarTerrain.gridMap = std::move(elevationMap); - postprocessing_->postprocess(planarTerrain, elevationLayer_); + // Add binary map + const std::string planeClassificationLayer{"plane_classification"}; + planarTerrain.gridMap.add(planeClassificationLayer); + auto& traversabilityMask = planarTerrain.gridMap.get(planeClassificationLayer); + cv::cv2eigen(slidingWindowPlaneExtractor_->getBinaryLabeledImage(), traversabilityMask); + + postprocessing_->postprocess(planarTerrain, elevationLayer_, planeClassificationLayer); auto t4 = std::chrono::high_resolution_clock::now(); ROS_INFO_STREAM("Postprocessing took " << 1e-3 * std::chrono::duration_cast(t4 - t3).count() << " [ms]"); @@ -133,8 +139,6 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { // Visualize in Rviz. reapplyNans(planarTerrain.gridMap.get(elevationLayer_)); - // planarTerrain.gridMap.add("plane_classification"); - // cv::cv2eigen(slidingWindowPlaneExtractor_->getBinaryLabeledImage(), planarTerrain.gridMap.get("plane_classification")); planarTerrain.gridMap.add("segmentation"); cv::cv2eigen(slidingWindowPlaneExtractor_->getSegmentedPlanesMap().labeledImage, planarTerrain.gridMap.get("segmentation")); grid_map_msgs::GridMap outputMessage; diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/convex_plane_decomposition_ros/src/ParameterLoading.cpp index 4936b7d6..7bb76b52 100644 --- a/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ b/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -60,6 +60,8 @@ sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters loadSlidin PostprocessingParameters loadPostprocessingParameters(const ros::NodeHandle& nodeHandle, const std::string& prefix) { PostprocessingParameters postprocessingParameters; loadParameter(nodeHandle, prefix, "extracted_planes_height_offset", postprocessingParameters.extracted_planes_height_offset); + loadParameter(nodeHandle, prefix, "nonplanar_height_offset", postprocessingParameters.nonplanar_height_offset); + loadParameter(nodeHandle, prefix, "nonplanar_horizontal_offset", postprocessingParameters.nonplanar_horizontal_offset); return postprocessingParameters; } From 555b1e071a814450ec895b66d455fd495a5605be Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 6 Jul 2021 15:55:13 +0200 Subject: [PATCH 095/504] fix visualization --- .../SegmentedPlanesTerrainVisualization.h | 6 ++--- .../src/DemoNode.cpp | 27 ++++++++++--------- .../src/SegmentedPlanesTerrainModelRos.cpp | 4 +-- .../SegmentedPlanesTerrainVisualization.cpp | 16 ++++++----- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h index a89c2cb9..bc2f14e4 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h @@ -7,12 +7,12 @@ #include #include +#include #include -#include namespace switched_model { -visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, Color color, double diameter, double linewidth, - double normalLength); +visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, ocs2::Color color, double diameter, + double linewidth, double normalLength); } // namespace switched_model diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp index d5a1a0c7..875c4e4c 100644 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include "segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h" @@ -26,22 +26,21 @@ std::unique_ptr messageMap; visualization_msgs::MarkerArray toMarker(const switched_model::ConvexTerrain& convexTerrain) { visualization_msgs::MarkerArray markerArray = - switched_model::getConvexTerrainMarkers(convexTerrain, switched_model::Color::orange, 0.02, 0.005, 0.1); + switched_model::getConvexTerrainMarkers(convexTerrain, ocs2::Color::orange, 0.02, 0.005, 0.1); // Add headers and Id const ros::Time timeStamp = ros::Time::now(); - switched_model::assignHeader(markerArray.markers.begin(), markerArray.markers.end(), - switched_model::getHeaderMsg(frameId_, timeStamp)); - switched_model::assignIncreasingId(markerArray.markers.begin(), markerArray.markers.end()); + ocs2::assignHeader(markerArray.markers.begin(), markerArray.markers.end(), ocs2::getHeaderMsg(frameId_, timeStamp)); + ocs2::assignIncreasingId(markerArray.markers.begin(), markerArray.markers.end()); return markerArray; } visualization_msgs::Marker toMarker(const switched_model::vector3_t& position) { - auto marker = switched_model::getSphereMsg(position, switched_model::Color::green, 0.02); + auto marker = ocs2::getSphereMsg(position, ocs2::Color::green, 0.02); const ros::Time timeStamp = ros::Time::now(); - marker.header = switched_model::getHeaderMsg(frameId_, timeStamp); + marker.header = ocs2::getHeaderMsg(frameId_, timeStamp); return marker; } @@ -77,7 +76,7 @@ int main(int argc, char** argv) { auto elevationMapSubscriber = nodeHandle.subscribe("/convex_plane_decomposition_ros/filtered_map", 1, &elevationMappingCallback); // Node loop - ros::Rate rate(1./5.); + ros::Rate rate(1. / 5.); while (ros::ok()) { if (auto newTerrain = segmentedPlanesTerrainModelRos.getTerrainModel()) { terrainModel = std::move(newTerrain); @@ -101,20 +100,24 @@ int main(int argc, char** argv) { double width = 1.5; double length = 2.0; bool success; - grid_map::GridMap localMap = messageMap->getSubmap({convexTerrain.plane.positionInWorld.x(), convexTerrain.plane.positionInWorld.y()}, Eigen::Array2d(width, length), success); + grid_map::GridMap localMap = messageMap->getSubmap({convexTerrain.plane.positionInWorld.x(), convexTerrain.plane.positionInWorld.y()}, + Eigen::Array2d(width, length), success); auto t2 = std::chrono::high_resolution_clock::now(); - signed_distance_field::GridmapSignedDistanceField sdf(localMap, "elevation", convexTerrain.plane.positionInWorld.z() - heightClearance, convexTerrain.plane.positionInWorld.z() + heightClearance); + signed_distance_field::GridmapSignedDistanceField sdf(localMap, "elevation", + convexTerrain.plane.positionInWorld.z() - heightClearance, + convexTerrain.plane.positionInWorld.z() + heightClearance); auto t3 = std::chrono::high_resolution_clock::now(); std::cout << "Sdf computation took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]\n"; auto t4 = std::chrono::high_resolution_clock::now(); auto sdfClone = std::unique_ptr(sdf.clone()); auto t5 = std::chrono::high_resolution_clock::now(); - std::cout << "Sdf.clone() computation took " << 1e-3 * std::chrono::duration_cast(t5 - t4).count() << " [ms]\n"; + std::cout << "Sdf.clone() computation took " << 1e-3 * std::chrono::duration_cast(t5 - t4).count() + << " [ms]\n"; sensor_msgs::PointCloud2 pointCloud2Msg; pcl::toROSMsg(sdf.obstaclePointCloud(4), pointCloud2Msg); - pointCloud2Msg.header = switched_model::getHeaderMsg(frameId_, ros::Time::now()); + pointCloud2Msg.header = ocs2::getHeaderMsg(frameId_, ros::Time::now()); distanceFieldPublisher.publish(pointCloud2Msg); } diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp index cc0ceef6..7ce7d3a6 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include namespace switched_model { @@ -58,7 +58,7 @@ void SegmentedPlanesTerrainModelRos::publish() { sensor_msgs::PointCloud2 pointCloud2Msg; pcl::toROSMsg(pointcloud, pointCloud2Msg); - pointCloud2Msg.header = switched_model::getHeaderMsg(frameId_, ros::Time::now()); + pointCloud2Msg.header = ocs2::getHeaderMsg(frameId_, ros::Time::now()); distanceFieldPublisher_.publish(pointCloud2Msg); } } diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp index 73956a99..bfadd576 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp @@ -4,19 +4,21 @@ #include "segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h" +#include + namespace switched_model { -visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, Color color, double diameter, double linewidth, - double normalLength) { +visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, ocs2::Color color, double diameter, + double linewidth, double normalLength) { visualization_msgs::MarkerArray markerArray; markerArray.markers.reserve(3); // Mark the center point - markerArray.markers.emplace_back(getSphereMsg(convexTerrain.plane.positionInWorld, color, diameter)); + markerArray.markers.emplace_back(ocs2::getSphereMsg(convexTerrain.plane.positionInWorld, color, diameter)); // Mark the surface normal const vector3_t surfaceNormal = normalLength * surfaceNormalInWorld(convexTerrain.plane); - markerArray.markers.emplace_back(getArrowAtPointMsg(surfaceNormal, convexTerrain.plane.positionInWorld, color)); + markerArray.markers.emplace_back(ocs2::getArrowAtPointMsg(surfaceNormal, convexTerrain.plane.positionInWorld, color)); // Polygon message if (!convexTerrain.boundary.empty()) { @@ -24,14 +26,14 @@ visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& con boundary.reserve(convexTerrain.boundary.size() + 1); for (const auto& point : convexTerrain.boundary) { const auto& pointInWorldFrame = positionInWorldFrameFromPositionInTerrain({point.x(), point.y(), 0.0}, convexTerrain.plane); - boundary.emplace_back(getPointMsg(pointInWorldFrame)); + boundary.emplace_back(ocs2::getPointMsg(pointInWorldFrame)); } // Close the polygon const auto& pointInWorldFrame = positionInWorldFrameFromPositionInTerrain( {convexTerrain.boundary.front().x(), convexTerrain.boundary.front().y(), 0.0}, convexTerrain.plane); - boundary.emplace_back(getPointMsg(pointInWorldFrame)); + boundary.emplace_back(ocs2::getPointMsg(pointInWorldFrame)); - markerArray.markers.emplace_back(getLineMsg(std::move(boundary), color, linewidth)); + markerArray.markers.emplace_back(ocs2::getLineMsg(std::move(boundary), color, linewidth)); } else { } From 0762df8f7a1f1e3ceb462de211ac0bd80bb91bc9 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 6 Jul 2021 15:55:23 +0200 Subject: [PATCH 096/504] add planarity_erosion --- .../SlidingWindowPlaneExtractorParameters.h | 3 +++ .../SlidingWindowPlaneExtractor.cpp | 8 ++++++++ convex_plane_decomposition_ros/config/parameters.yaml | 3 ++- convex_plane_decomposition_ros/src/ParameterLoading.cpp | 1 + 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h index 40604651..d60607fe 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h @@ -12,6 +12,9 @@ struct SlidingWindowPlaneExtractorParameters { /// Should be an odd number and at least 3. int kernel_size = 3; + /// [#] Erode planarity detection by this amount of pixels + int planarity_erosion = 0; + /// [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch double plane_inclination_threshold_degrees = 70.0; diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index 8ea045eb..24942288 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -128,6 +128,14 @@ void SlidingWindowPlaneExtractor::runSlidingWindowDetector() { binaryImagePatch_.at(index.x(), index.y()) = isLocallyPlanar(n, mean_error); } } + + // erode + if (parameters_.planarity_erosion > 0) { + const int erosionSize = 2 * parameters_.planarity_erosion + 1; + const int erosionType = cv::MORPH_CROSS; + const auto erosionKernel_ = cv::getStructuringElement(erosionType, cv::Size(erosionSize, erosionSize)); + cv::erode(binaryImagePatch_, binaryImagePatch_, erosionKernel_); + } } // Label cells according to which cell they belong to using connected component labeling. diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 804feaf8..14e53db1 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -7,6 +7,7 @@ preprocessing: sliding_window_plane_extractor: kernel_size: 3 # Size of the sliding window patch used for normal vector calculation and planarity detection. Should be an odd number and at least 3. + planarity_erosion: 1 # [#] Erode planarity detection by this amount of pixels plane_inclination_threshold_degrees: 45.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch plane_patch_error_threshold: 0.005 # [m] The allowed root-mean-squared deviation from the plane fitted to the sliding window. min_number_points_per_label: 10 # [#] Labels with less points assigned to them are discarded @@ -26,6 +27,6 @@ contour_extraction: offsetSize: 2 # Size of the kernel creating the boundary offset. In number of pixels. postprocessing: - extracted_planes_height_offset: 0.02 # Added offset in Z direction for the full map to compensate for the location of the foot frame w.r.t. the contact point + extracted_planes_height_offset: 0.0 # Added offset in Z direction for the full map to compensate for the location of the foot frame w.r.t. the contact point nonplanar_height_offset: 0.02 # Added offset in Z direction for non-planar cells of the map. (Additional to extracted_planes_height_offset) nonplanar_horizontal_offset: 2 # Added offset in XY direction for non-planar cells of the map. In number of pixels. \ No newline at end of file diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/convex_plane_decomposition_ros/src/ParameterLoading.cpp index 7bb76b52..e6953c43 100644 --- a/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ b/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -46,6 +46,7 @@ sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters loadSlidin const ros::NodeHandle& nodeHandle, const std::string& prefix) { sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters swParams; loadParameter(nodeHandle, prefix, "kernel_size", swParams.kernel_size); + loadParameter(nodeHandle, prefix, "planarity_erosion", swParams.planarity_erosion); loadParameter(nodeHandle, prefix, "plane_inclination_threshold_degrees", swParams.plane_inclination_threshold_degrees); loadParameter(nodeHandle, prefix, "plane_patch_error_threshold", swParams.plane_patch_error_threshold); loadParameter(nodeHandle, prefix, "min_number_points_per_label", swParams.min_number_points_per_label); From 7adb7de8091d82e945b39af8b5656b35fe6a6e04 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 7 Jul 2021 13:41:53 +0200 Subject: [PATCH 097/504] change openCV inpaint to min-inpaint. Remove custom NaN processing --- convex_plane_decomposition/CMakeLists.txt | 1 + .../GridMapPreprocessing.h | 4 +- .../include/convex_plane_decomposition/Nan.h | 29 ------------ convex_plane_decomposition/package.xml | 1 + .../src/GridMapPreprocessing.cpp | 46 ++++--------------- .../SlidingWindowPlaneExtractor.cpp | 6 +-- .../config/parameters.yaml | 3 +- .../src/ConvexPlaneDecompositionRos.cpp | 2 - .../src/ParameterLoading.cpp | 1 - 9 files changed, 14 insertions(+), 79 deletions(-) delete mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/Nan.h diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index dafad609..82659a85 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -6,6 +6,7 @@ set(CATKIN_PACKAGE_DEPENDENCIES cgal5_catkin grid_map_core ocs2_switched_model_interface + grid_map_filters_rsl ) find_package(catkin REQUIRED COMPONENTS diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h index 9fef5c32..4eede3f0 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h @@ -15,8 +15,6 @@ struct PreprocessingParameters { int numberOfRepeats = 1; /// If the kernel size should increase each filter step. bool increasing = false; - /// [m] radius used for inpainting - double inpaintRadius = 0.05; }; class GridMapPreprocessing { @@ -28,7 +26,7 @@ class GridMapPreprocessing { private: void denoise(grid_map::GridMap& gridMap, const std::string& layer) const; void changeResolution(grid_map::GridMap& gridMap, const std::string& layer) const; - void inpaint(grid_map::GridMap& gridMap, const std::string& layer, float minValue, float maxValue) const; + void inpaint(grid_map::GridMap& gridMap, const std::string& layer) const; PreprocessingParameters parameters_; }; diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/Nan.h b/convex_plane_decomposition/include/convex_plane_decomposition/Nan.h deleted file mode 100644 index a2867698..00000000 --- a/convex_plane_decomposition/include/convex_plane_decomposition/Nan.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// Created by rgrandia on 11.06.20. -// - -#pragma once - -#include - -namespace convex_plane_decomposition { - -constexpr float nanfPatch = std::numeric_limits::max(); - -inline bool isNan(float val) { - return val == nanfPatch; -} - -inline bool isNan(double val) { - throw std::runtime_error("Should not call the custom isNan with a double"); -} - -inline void patchNans(Eigen::MatrixXf& matrix) { - matrix = matrix.unaryExpr([](float val) { return (std::isnan(val)) ? nanfPatch : val; }); -} - -inline void reapplyNans(Eigen::MatrixXf& matrix) { - matrix = matrix.unaryExpr([](float val) { return (isNan(val)) ? std::nanf("") : val; }); -} - -} // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/package.xml b/convex_plane_decomposition/package.xml index a9084924..43e12a95 100644 --- a/convex_plane_decomposition/package.xml +++ b/convex_plane_decomposition/package.xml @@ -12,6 +12,7 @@ cgal5_catkin grid_map_core ocs2_switched_model_interface + grid_map_filters_rsl diff --git a/convex_plane_decomposition/src/GridMapPreprocessing.cpp b/convex_plane_decomposition/src/GridMapPreprocessing.cpp index b72ce854..10b0629a 100644 --- a/convex_plane_decomposition/src/GridMapPreprocessing.cpp +++ b/convex_plane_decomposition/src/GridMapPreprocessing.cpp @@ -1,28 +1,19 @@ #include "convex_plane_decomposition/GridMapPreprocessing.h" -#include #include #include #include -#include -#include "convex_plane_decomposition/Nan.h" +#include namespace convex_plane_decomposition { GridMapPreprocessing::GridMapPreprocessing(const PreprocessingParameters& parameters) : parameters_(parameters) {} void GridMapPreprocessing::preprocess(grid_map::GridMap& gridMap, const std::string& layer) const { - const float minValue = gridMap.get(layer).minCoeffOfFinites(); - const float maxValue = gridMap.get(layer).maxCoeffOfFinites(); - - patchNans(gridMap.get(layer)); denoise(gridMap, layer); - - if (parameters_.inpaintRadius > 0) { - inpaint(gridMap, layer, minValue, maxValue); - changeResolution(gridMap, layer); - } + inpaint(gridMap, layer); + changeResolution(gridMap, layer); } void GridMapPreprocessing::denoise(grid_map::GridMap& gridMap, const std::string& layer) const { @@ -68,33 +59,12 @@ void GridMapPreprocessing::changeResolution(grid_map::GridMap& gridMap, const st } } -void GridMapPreprocessing::inpaint(grid_map::GridMap& gridMap, const std::string& layer, float minValue, float maxValue) const { - Eigen::MatrixXf& elevation_map = gridMap.get(layer); - - Eigen::Matrix mask = elevation_map.unaryExpr([](float val) { return (isNan(val)) ? uchar(1) : uchar(0); }); - - cv::Mat maskImage; - cv::eigen2cv(mask, maskImage); - - cv::Mat elevationImage; - grid_map::GridMapCvConverter::toImage(gridMap, layer, CV_8UC1, minValue, maxValue, elevationImage); - - // Inpainting - cv::Mat filledImage; - const double radiusInPixels = parameters_.inpaintRadius / gridMap.getResolution(); - cv::inpaint(elevationImage, maskImage, filledImage, radiusInPixels, cv::INPAINT_NS); - - // Get inpainting as float - cv::Mat filledImageFloat; - const float maxUCharValue = 255.F; - filledImage.convertTo(filledImageFloat, CV_32F, (maxValue - minValue) / maxUCharValue, minValue); - - // Copy inpainted values back to elevation map - cv::Mat elevationImageFloat; - cv::eigen2cv(elevation_map, elevationImageFloat); - filledImageFloat.copyTo(elevationImageFloat, maskImage); +void GridMapPreprocessing::inpaint(grid_map::GridMap& gridMap, const std::string& layer) const { + const std::string& layerOut = "tmp"; + grid_map::inpainting::minValues(gridMap, layer, layerOut); - cv::cv2eigen(elevationImageFloat, elevation_map); + gridMap.get(layer) = std::move(gridMap.get(layerOut)); + gridMap.erase(layerOut); } } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index 24942288..b5a3e677 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -11,8 +11,6 @@ #include -#include "convex_plane_decomposition/Nan.h" - namespace convex_plane_decomposition { namespace sliding_window_plane_extractor { @@ -63,7 +61,7 @@ std::pair SlidingWindowPlaneExtractor::computeNormalAnd for (int kernel_col = 0; kernel_col < parameters_.kernel_size; ++kernel_col) { for (int kernel_row = 0; kernel_row < parameters_.kernel_size; ++kernel_row) { float height = windowData(kernel_row, kernel_col); - if (isNan(height)) { + if (!std::isfinite(height)) { continue; } // No need to account for map offset. Will substract the mean anyway. @@ -117,7 +115,7 @@ void SlidingWindowPlaneExtractor::runSlidingWindowDetector() { Eigen::MatrixXf window_data = window_iterator.getData(); const auto middleValue = window_data(kernelMiddle, kernelMiddle); - if (isNan(middleValue)) { + if (!std::isfinite(middleValue)) { binaryImagePatch_.at(index.x(), index.y()) = false; } else { Eigen::Vector3d n; diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 14e53db1..305a0083 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -3,11 +3,10 @@ preprocessing: kernelSize: 3 # Kernel size of the median filter, either 3 or 5 numberOfRepeats: 3 # Number of times to apply the same filter increasing: False # Increase the kernel size each iteration. - inpaintRadius: 0.05 # [m] sliding_window_plane_extractor: kernel_size: 3 # Size of the sliding window patch used for normal vector calculation and planarity detection. Should be an odd number and at least 3. - planarity_erosion: 1 # [#] Erode planarity detection by this amount of pixels + planarity_erosion: 0 # [#] Erode planarity detection by this amount of pixels plane_inclination_threshold_degrees: 45.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch plane_patch_error_threshold: 0.005 # [m] The allowed root-mean-squared deviation from the plane fitted to the sliding window. min_number_points_per_label: 10 # [#] Labels with less points assigned to them are discarded diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 54d6f8f8..beaa63ad 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -138,7 +137,6 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { } // Visualize in Rviz. - reapplyNans(planarTerrain.gridMap.get(elevationLayer_)); planarTerrain.gridMap.add("segmentation"); cv::cv2eigen(slidingWindowPlaneExtractor_->getSegmentedPlanesMap().labeledImage, planarTerrain.gridMap.get("segmentation")); grid_map_msgs::GridMap outputMessage; diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/convex_plane_decomposition_ros/src/ParameterLoading.cpp index e6953c43..853d359f 100644 --- a/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ b/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -20,7 +20,6 @@ PreprocessingParameters loadPreprocessingParameters(const ros::NodeHandle& nodeH loadParameter(nodeHandle, prefix, "kernelSize", preprocessingParameters.kernelSize); loadParameter(nodeHandle, prefix, "numberOfRepeats", preprocessingParameters.numberOfRepeats); loadParameter(nodeHandle, prefix, "increasing", preprocessingParameters.increasing); - loadParameter(nodeHandle, prefix, "inpaintRadius", preprocessingParameters.inpaintRadius); return preprocessingParameters; } From 7cd95a1704ae4ba78b11749b0e1fa4dc95a5ea34 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 14 Jul 2021 09:48:48 +0200 Subject: [PATCH 098/504] update jenkins pipeline --- jenkins-pipeline | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jenkins-pipeline b/jenkins-pipeline index cc00826c..f0fe0a26 100644 --- a/jenkins-pipeline +++ b/jenkins-pipeline @@ -1,2 +1,4 @@ library 'continuous_integration_pipeline' -ciPipeline("--environment anymal --dependencies git@bitbucket.org:leggedrobotics/ocs2_anymal.git;feature/perception;git") +ciPipeline("--environment anymal \ + --dependencies 'git@bitbucket.org:leggedrobotics/ocs2_anymal.git;feature/perception;git'\ + 'git@bitbucket.org:leggedrobotics/ocs2_dev;feature/perception;git'") From 99f475fa9b981e7ed7903f16564b82fe7b430d3f Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 29 Jul 2021 12:48:28 +0200 Subject: [PATCH 099/504] check there is at least one finite value in the submap --- .../GridMapPreprocessing.h | 5 +++++ .../src/GridMapPreprocessing.cpp | 17 ++++++++++++++--- .../src/ConvexPlaneDecompositionRos.cpp | 1 + 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h index 4eede3f0..abcf9e25 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h @@ -31,4 +31,9 @@ class GridMapPreprocessing { PreprocessingParameters parameters_; }; +/** + * @return true if any of the elements in the map are finite + */ +bool containsFiniteValue(const grid_map::Matrix& map); + } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/src/GridMapPreprocessing.cpp b/convex_plane_decomposition/src/GridMapPreprocessing.cpp index 10b0629a..65cea07d 100644 --- a/convex_plane_decomposition/src/GridMapPreprocessing.cpp +++ b/convex_plane_decomposition/src/GridMapPreprocessing.cpp @@ -20,14 +20,14 @@ void GridMapPreprocessing::denoise(grid_map::GridMap& gridMap, const std::string Eigen::MatrixXf& elevation_map = gridMap.get(layer); cv::Mat elevationImage; - cv::eigen2cv(elevation_map, elevationImage); // creates CV_32F image + cv::eigen2cv(elevation_map, elevationImage); // creates CV_32F image int kernelSize = parameters_.kernelSize; for (int i = 0; i < parameters_.numberOfRepeats; ++i) { - kernelSize = std::max(3, std::min(kernelSize, 5)); // must be 3 or 5 for current image type, see doc of cv::medianBlur + kernelSize = std::max(3, std::min(kernelSize, 5)); // must be 3 or 5 for current image type, see doc of cv::medianBlur cv::medianBlur(elevationImage, elevationImage, kernelSize); - if (parameters_.increasing) { // TODO (rgrandia) : remove this option or enable kernels of other size than 3 / 5 + if (parameters_.increasing) { // TODO (rgrandia) : remove this option or enable kernels of other size than 3 / 5 kernelSize += 2; } } @@ -67,4 +67,15 @@ void GridMapPreprocessing::inpaint(grid_map::GridMap& gridMap, const std::string gridMap.erase(layerOut); } +bool containsFiniteValue(const grid_map::Matrix& map) { + for (int col = 0; col < map.cols(); ++col) { + for (int row = 0; row < map.rows(); ++row) { + if (std::isfinite(map(col, row))) { + return true; + } + } + } + return false; +} + } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index beaa63ad..2a42d3b6 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -89,6 +89,7 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { grid_map::GridMapRosConverter::fromMessage(message, messageMap, layers, false, false); bool success; grid_map::GridMap elevationMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(subMapLength_, subMapWidth_), success); + success = success && containsFiniteValue(elevationMap.get(elevationLayer_)); // Check if there are values ROS_INFO("...done."); // Transform map if necessary From f36e12e33ecb3b5095277a477ff1eeb5872fbcc9 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 5 Aug 2021 13:32:14 +0200 Subject: [PATCH 100/504] add highest obstacle interface --- segmented_planes_terrain_model/CMakeLists.txt | 1 + .../SegmentedPlanesTerrainModel.h | 2 ++ segmented_planes_terrain_model/package.xml | 1 + .../src/SegmentedPlanesTerrainModel.cpp | 18 ++++++++++++++++++ 4 files changed, 22 insertions(+) diff --git a/segmented_planes_terrain_model/CMakeLists.txt b/segmented_planes_terrain_model/CMakeLists.txt index dccffca0..e9d3fa10 100644 --- a/segmented_planes_terrain_model/CMakeLists.txt +++ b/segmented_planes_terrain_model/CMakeLists.txt @@ -3,6 +3,7 @@ project(segmented_planes_terrain_model) # Catkin dependencies set(CATKIN_PACKAGE_DEPENDENCIES + grid_map_filters_rsl ocs2_switched_model_interface grid_map_sdf pcl_ros diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h index b83c8262..ccfce13a 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h @@ -23,6 +23,8 @@ class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { const signed_distance_field::GridmapSignedDistanceField* getSignedDistanceField() const override { return signedDistanceField_.get(); } + vector3_t getHighestObstacleAlongLine(const vector3_t& position1InWorld, const vector3_t& position2InWorld) const override; + const convex_plane_decomposition::PlanarTerrain& planarTerrain() const { return planarTerrain_; } private: diff --git a/segmented_planes_terrain_model/package.xml b/segmented_planes_terrain_model/package.xml index 2034ed44..a876d763 100644 --- a/segmented_planes_terrain_model/package.xml +++ b/segmented_planes_terrain_model/package.xml @@ -9,6 +9,7 @@ TODO catkin + grid_map_filters_rsl ocs2_switched_model_interface grid_map_sdf pcl_ros diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index 23ab8f3d..2a8880e2 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace switched_model { @@ -198,4 +199,21 @@ std::pair position2InWorld.z()) { + return position1InWorld; + } else { + return position2InWorld; + } + } +} + } // namespace switched_model From b9aa43b73bf2248f39c94e4c00f23576fe89a3c3 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 11 Aug 2021 16:56:45 +0200 Subject: [PATCH 101/504] take reference to elevation data during initialization --- .../SegmentedPlanesTerrainModel.h | 3 ++- .../src/SegmentedPlanesTerrainModel.cpp | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h index ccfce13a..098b28df 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h @@ -28,8 +28,9 @@ class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { const convex_plane_decomposition::PlanarTerrain& planarTerrain() const { return planarTerrain_; } private: - convex_plane_decomposition::PlanarTerrain planarTerrain_; + const convex_plane_decomposition::PlanarTerrain planarTerrain_; std::unique_ptr signedDistanceField_; + const grid_map::Matrix* const elevationData_; }; std::pair getPlanarRegionAtPositionInWorld( diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index 2a8880e2..22883179 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -13,8 +13,11 @@ namespace switched_model { +namespace { // TODO (rgrandia) : deadzone a parameter const double zHeightDistanceDeadzone = 0.1; // [m] This difference in z height is not counted +const std::string elevationLayerName = "elevation"; +} // namespace double distanceCost(const vector3_t& query, const vector3_t& terrainPoint) { const double dx = query.x() - terrainPoint.x(); @@ -39,7 +42,9 @@ double distanceCostLowerbound(double distanceSquared) { } SegmentedPlanesTerrainModel::SegmentedPlanesTerrainModel(convex_plane_decomposition::PlanarTerrain planarTerrain) - : planarTerrain_(std::move(planarTerrain)), signedDistanceField_(nullptr) {} + : planarTerrain_(std::move(planarTerrain)), + signedDistanceField_(nullptr), + elevationData_(&planarTerrain_.gridMap.get(elevationLayerName)) {} TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorldAlongGravity(const vector3_t& positionInWorld) const { const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions); @@ -84,8 +89,8 @@ void SegmentedPlanesTerrainModel::createSignedDistanceBetween(const Eigen::Vecto bool success = true; grid_map::GridMap subMap = planarTerrain_.gridMap.getSubmap(centerXY, lengths, success); if (success) { - signedDistanceField_ = - std::make_unique(subMap, "elevation", minCoordinates.z(), maxCoordinates.z()); + signedDistanceField_ = std::make_unique(subMap, elevationLayerName, + minCoordinates.z(), maxCoordinates.z()); } else { std::cerr << "[SegmentedPlanesTerrainModel] Failed to get subMap" << std::endl; } @@ -201,9 +206,8 @@ std::pair Date: Tue, 17 Aug 2021 16:33:48 +0200 Subject: [PATCH 102/504] fix: swap over move under lock --- .../src/SegmentedPlanesTerrainModelRos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp index 7ce7d3a6..1fb14c5f 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp @@ -87,7 +87,7 @@ void SegmentedPlanesTerrainModelRos::callback(const convex_plane_decomposition_m { // Move to storage under the lock std::lock_guard lock(updateMutex_); - terrainPtr_ = std::move(terrainPtr); + terrainPtr_.swap(terrainPtr); } callbackTimer_.endTimer(); From 538322df32145784263349ad87519b022e9bc868 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 17 Aug 2021 23:41:42 +0200 Subject: [PATCH 103/504] keep distance as float converting to pointcloud --- .../include/signed_distance_field/GridmapSignedDistanceField.h | 1 + signed_distance_field/src/GridmapSignedDistanceField.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h index 5967439c..4ed38749 100644 --- a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h +++ b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h @@ -61,6 +61,7 @@ class GridmapSignedDistanceField : public switched_model::SignedDistanceField { using node_data_t = std::array; static double distance(const node_data_t& nodeData) noexcept { return nodeData[0]; } + static float distanceFloat(const node_data_t& nodeData) noexcept { return nodeData[0]; } static Eigen::Vector3d derivative(const node_data_t& nodeData) noexcept { return {nodeData[1], nodeData[2], nodeData[3]}; } Gridmap3dLookup gridmap3DLookup_; diff --git a/signed_distance_field/src/GridmapSignedDistanceField.cpp b/signed_distance_field/src/GridmapSignedDistanceField.cpp index 68fcd043..af67d5a3 100644 --- a/signed_distance_field/src/GridmapSignedDistanceField.cpp +++ b/signed_distance_field/src/GridmapSignedDistanceField.cpp @@ -113,7 +113,7 @@ pcl::PointCloud GridmapSignedDistanceField::asPointCloud(size_t for (size_t rowX = 0; rowX < gridmap3DLookup_.gridsize_.x; rowX += decimation) { const Gridmap3dLookup::size_t_3d index3d = {rowX, colY, layerZ}; const auto index = gridmap3DLookup_.linearIndex(index3d); - const auto signeddistance = distance(data_[index]); + const auto signeddistance = distanceFloat(data_[index]); if (condition(signeddistance)) { const auto p = gridmap3DLookup_.nodePosition(index3d); pcl::PointXYZI point; From 433ac1370f969efbcd8d1803e11979d5fe261a1f Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 18 Aug 2021 20:28:09 +0200 Subject: [PATCH 104/504] inpaint before denoising operation --- convex_plane_decomposition/src/GridMapPreprocessing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convex_plane_decomposition/src/GridMapPreprocessing.cpp b/convex_plane_decomposition/src/GridMapPreprocessing.cpp index 65cea07d..19979602 100644 --- a/convex_plane_decomposition/src/GridMapPreprocessing.cpp +++ b/convex_plane_decomposition/src/GridMapPreprocessing.cpp @@ -11,8 +11,8 @@ namespace convex_plane_decomposition { GridMapPreprocessing::GridMapPreprocessing(const PreprocessingParameters& parameters) : parameters_(parameters) {} void GridMapPreprocessing::preprocess(grid_map::GridMap& gridMap, const std::string& layer) const { - denoise(gridMap, layer); inpaint(gridMap, layer); + denoise(gridMap, layer); changeResolution(gridMap, layer); } From 25f8a8f8a41712f3b1ea1411fafd9ce72ac9c3f9 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 19 Aug 2021 21:54:32 +0200 Subject: [PATCH 105/504] reduce median filter to 1 repetition --- convex_plane_decomposition_ros/config/parameters.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 305a0083..41db87d4 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -1,7 +1,7 @@ preprocessing: resolution: 0.02 # Resampling resolution, set negative to skip, requires inpainting to be used kernelSize: 3 # Kernel size of the median filter, either 3 or 5 - numberOfRepeats: 3 # Number of times to apply the same filter + numberOfRepeats: 1 # Number of times to apply the same filter increasing: False # Increase the kernel size each iteration. sliding_window_plane_extractor: From a759aa907e7f3ba44a22c5b1efefff0b336eb161 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 12 Oct 2021 15:41:06 +0200 Subject: [PATCH 106/504] add a smooth layer to be used as base reference --- .../Postprocessing.h | 10 ++++ .../src/Postprocessing.cpp | 58 +++++++++++++++++++ .../config/parameters.yaml | 5 +- .../src/ParameterLoading.cpp | 3 + 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h b/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h index d56279ff..5dfb751e 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h @@ -13,6 +13,15 @@ struct PostprocessingParameters { /// Size of the kernel creating the boundary offset. In number of pixels. int nonplanar_horizontal_offset = 2; + + /// Half the width of the dilation used before the smooth layer [m] + double smoothing_dilation_size = 0.2; + + /// Half the width of the box kernel used for the smooth layer [m] + double smoothing_box_kernel_size = 0.3; + + /// Half the width of the Gaussian kernel used for the smooth layer [m] + double smoothing_gauss_kernel_size = 0.1; }; class Postprocessing { @@ -30,6 +39,7 @@ class Postprocessing { void dilationInNonplanarRegions(Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const; void addHeightOffset(Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const; void addHeightOffset(std::vector& planarRegions) const; + void addSmoothLayer(grid_map::GridMap& gridMap, const Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const; PostprocessingParameters parameters_; }; diff --git a/convex_plane_decomposition/src/Postprocessing.cpp b/convex_plane_decomposition/src/Postprocessing.cpp index f0e5887d..331573ac 100644 --- a/convex_plane_decomposition/src/Postprocessing.cpp +++ b/convex_plane_decomposition/src/Postprocessing.cpp @@ -4,6 +4,8 @@ #include #include +#include + namespace convex_plane_decomposition { Postprocessing::Postprocessing(const PostprocessingParameters& parameters) : parameters_(parameters) {} @@ -16,6 +18,9 @@ void Postprocessing::postprocess(PlanarTerrain& planarTerrain, const std::string // post process planar regions addHeightOffset(planarTerrain.planarRegions); + // Add smooth layer for base reference + addSmoothLayer(planarTerrain.gridMap, elevationData, planarityMask); + // post process elevation map dilationInNonplanarRegions(elevationData, planarityMask); addHeightOffset(elevationData, planarityMask); @@ -61,4 +66,57 @@ void Postprocessing::addHeightOffset(std::vector& planarRegions) c } } +void Postprocessing::addSmoothLayer(grid_map::GridMap& gridMap, const Eigen::MatrixXf& elevationData, + const Eigen::MatrixXf& planarityMask) const { + const int dilationSize = 2 * std::round(parameters_.smoothing_dilation_size / gridMap.getResolution()) + 1; + const int kernel = 2 * std::round(parameters_.smoothing_box_kernel_size / gridMap.getResolution()) + 1; + const int kernelGauss = 2 * std::round(parameters_.smoothing_gauss_kernel_size / gridMap.getResolution()) + 1; + + // Set nonplanar regions to "NaN" + const auto lowestFloat = std::numeric_limits::lowest(); // Take lowest to not interfere with Dilation, using true NaN doesn't work with opencv dilation. + Eigen::MatrixXf elevationWithNaN = + (planarityMask.array() == 1.0).select(elevationData, Eigen::MatrixXf::Constant(elevationData.rows(), elevationData.cols(), lowestFloat)); + + // Convert to openCV + cv::Mat elevationWithNaNImage; + cv::eigen2cv(elevationWithNaN, elevationWithNaNImage); // creates CV_32F image + + // Dilate + const int dilationType = cv::MORPH_ELLIPSE; // ellipse inscribed in the square of size dilationSize + const auto dilationKernel_ = cv::getStructuringElement(dilationType, cv::Size(dilationSize, dilationSize)); + cv::dilate(elevationWithNaNImage, elevationWithNaNImage, dilationKernel_); + + // Take complement image where elevation data was set to NaN + cv::Mat indicatorImage = cv::Mat::ones(elevationWithNaNImage.rows, elevationWithNaNImage.cols, CV_32F); + indicatorImage.setTo(0.0, elevationWithNaNImage == lowestFloat); + + // Set NaN's to 0.0 + elevationWithNaNImage.setTo(0.0, elevationWithNaNImage == lowestFloat); + + // Filter definition + auto smoothingFilter = [kernel, kernelGauss](const cv::Mat& imageIn) { + cv::Mat imageOut; + cv::boxFilter(imageIn, imageOut, -1, {kernel, kernel}, cv::Point(-1, -1), true, cv::BorderTypes::BORDER_CONSTANT); + cv::GaussianBlur(imageOut, imageOut, {kernelGauss, kernelGauss}, 0, 0, cv::BorderTypes::BORDER_CONSTANT); + return imageOut; + }; + + // Helper to convert to Eigen + auto toEigen = [](const cv::Mat& image) { + Eigen::MatrixXf data; + cv::cv2eigen(image, data); + return data; + }; + + // Filter trick for data with NaN from: https://stackoverflow.com/questions/18697532/gaussian-filtering-a-image-with-nan-in-python + auto planarOnly = smoothingFilter(elevationWithNaNImage); + auto complement = smoothingFilter(indicatorImage); + complement += 1e-6; // Prevent division by zero + cv::Mat result; + cv::divide(planarOnly, complement, result); + + // Add layer to map. + gridMap.add("smooth_planar", toEigen(result)); +} + } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 41db87d4..32e4529c 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -28,4 +28,7 @@ contour_extraction: postprocessing: extracted_planes_height_offset: 0.0 # Added offset in Z direction for the full map to compensate for the location of the foot frame w.r.t. the contact point nonplanar_height_offset: 0.02 # Added offset in Z direction for non-planar cells of the map. (Additional to extracted_planes_height_offset) - nonplanar_horizontal_offset: 2 # Added offset in XY direction for non-planar cells of the map. In number of pixels. \ No newline at end of file + nonplanar_horizontal_offset: 2 # Added offset in XY direction for non-planar cells of the map. In number of pixels. + smoothing_dilation_size: 0.2 # Half the width of the dilation used before the smooth layer [m] + smoothing_box_kernel_size: 0.3 # Half the width of the box kernel used for the smooth layer [m] + smoothing_gauss_kernel_size: 0.1 # Half the width of the Gaussian kernel used for the smooth layer [m] \ No newline at end of file diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/convex_plane_decomposition_ros/src/ParameterLoading.cpp index 853d359f..cc444ab5 100644 --- a/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ b/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -62,6 +62,9 @@ PostprocessingParameters loadPostprocessingParameters(const ros::NodeHandle& nod loadParameter(nodeHandle, prefix, "extracted_planes_height_offset", postprocessingParameters.extracted_planes_height_offset); loadParameter(nodeHandle, prefix, "nonplanar_height_offset", postprocessingParameters.nonplanar_height_offset); loadParameter(nodeHandle, prefix, "nonplanar_horizontal_offset", postprocessingParameters.nonplanar_horizontal_offset); + loadParameter(nodeHandle, prefix, "smoothing_dilation_size", postprocessingParameters.smoothing_dilation_size); + loadParameter(nodeHandle, prefix, "smoothing_box_kernel_size", postprocessingParameters.smoothing_box_kernel_size); + loadParameter(nodeHandle, prefix, "smoothing_gauss_kernel_size", postprocessingParameters.smoothing_gauss_kernel_size); return postprocessingParameters; } From 3d725f5487c7bbb0685378faf05fb9e4528fc54a Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 12 Oct 2021 16:38:30 +0200 Subject: [PATCH 107/504] remove one marker from convex terrain --- .../SegmentedPlanesTerrainVisualization.h | 4 ++-- segmented_planes_terrain_model/src/DemoNode.cpp | 3 +-- .../src/SegmentedPlanesTerrainVisualization.cpp | 9 +++------ 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h index bc2f14e4..6c8acf6b 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h @@ -12,7 +12,7 @@ namespace switched_model { -visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, ocs2::Color color, double diameter, - double linewidth, double normalLength); +visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, ocs2::Color color, double linewidth, + double normalLength); } // namespace switched_model diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp index 875c4e4c..2e4a0d81 100644 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -25,8 +25,7 @@ const std::string frameId_ = "odom"; std::unique_ptr messageMap; visualization_msgs::MarkerArray toMarker(const switched_model::ConvexTerrain& convexTerrain) { - visualization_msgs::MarkerArray markerArray = - switched_model::getConvexTerrainMarkers(convexTerrain, ocs2::Color::orange, 0.02, 0.005, 0.1); + visualization_msgs::MarkerArray markerArray = switched_model::getConvexTerrainMarkers(convexTerrain, ocs2::Color::orange, 0.005, 0.1); // Add headers and Id const ros::Time timeStamp = ros::Time::now(); diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp index bfadd576..b8a576c3 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp @@ -8,13 +8,10 @@ namespace switched_model { -visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, ocs2::Color color, double diameter, - double linewidth, double normalLength) { +visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, ocs2::Color color, double linewidth, + double normalLength) { visualization_msgs::MarkerArray markerArray; - markerArray.markers.reserve(3); - - // Mark the center point - markerArray.markers.emplace_back(ocs2::getSphereMsg(convexTerrain.plane.positionInWorld, color, diameter)); + markerArray.markers.reserve(2); // Mark the surface normal const vector3_t surfaceNormal = normalLength * surfaceNormalInWorld(convexTerrain.plane); From 922c436cd247bf8b934bc57aeae45b02a0aacd26 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 12 Oct 2021 17:25:09 +0200 Subject: [PATCH 108/504] refactor: move free standing function to separate file --- segmented_planes_terrain_model/CMakeLists.txt | 1 + .../SegmentedPlaneProjection.h | 31 ++++ .../src/SegmentedPlaneProjection.cpp | 147 ++++++++++++++++++ .../src/SegmentedPlanesTerrainModel.cpp | 135 +--------------- 4 files changed, 181 insertions(+), 133 deletions(-) create mode 100644 segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h create mode 100644 segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp diff --git a/segmented_planes_terrain_model/CMakeLists.txt b/segmented_planes_terrain_model/CMakeLists.txt index e9d3fa10..39d96401 100644 --- a/segmented_planes_terrain_model/CMakeLists.txt +++ b/segmented_planes_terrain_model/CMakeLists.txt @@ -44,6 +44,7 @@ include_directories( ) add_library(${PROJECT_NAME} + src/SegmentedPlaneProjection.cpp src/SegmentedPlanesTerrainModel.cpp src/SegmentedPlanesTerrainModelRos.cpp src/SegmentedPlanesTerrainVisualization.cpp diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h new file mode 100644 index 00000000..95be21a5 --- /dev/null +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h @@ -0,0 +1,31 @@ +// +// Created by rgrandia on 12.10.21. +// + +#pragma once + +#include + +#include +#include + +namespace switched_model { + +double distanceCost(const vector3_t& query, const vector3_t& terrainPoint); + +double distanceCostLowerbound(double distanceSquared); + +double singleSidedSquaredDistance(double value, double min, double max); + +double squaredDistanceToBoundingBox(const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarRegion& planarRegion); + +const convex_plane_decomposition::CgalPolygonWithHoles2d* findInsetContainingThePoint( + const convex_plane_decomposition::CgalPoint2d& point, const std::vector& insets); + +std::pair squaredDistanceToBoundary( + const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarRegion& planarRegion); + +std::pair getPlanarRegionAtPositionInWorld( + const vector3_t& positionInWorld, const std::vector& planarRegions); + +} // namespace switched_model \ No newline at end of file diff --git a/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp b/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp new file mode 100644 index 00000000..de82571c --- /dev/null +++ b/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp @@ -0,0 +1,147 @@ +// +// Created by rgrandia on 12.10.21. +// + +#include "segmented_planes_terrain_model/SegmentedPlaneProjection.h" + +#include + +namespace switched_model { + +// alias to avoid long namespace +namespace cpd = convex_plane_decomposition; + +// TODO (rgrandia) : deadzone a parameter +const double zHeightDistanceDeadzone = 0.1; // [m] This difference in z height is not counted + +double distanceCost(const vector3_t& query, const vector3_t& terrainPoint) { + const double dx = query.x() - terrainPoint.x(); + const double dy = query.y() - terrainPoint.y(); + const double dz = std::max(0.0, std::abs(query.z() - terrainPoint.z()) - zHeightDistanceDeadzone); + return dx * dx + dy * dy + dz * dz; +} + +double distanceCostLowerbound(double distanceSquared) { + // cost = dx*dx + dy*dy + max(0.0, (|dz| - z0)).^2 with z0 >= 0 + // Need a lower bound for this cost derived from square distance and shift + // + // dz*dz - z0*z0 < max(0.0, (|dz| - z0)).^2 + // if |dz| > z0 ==> + // dz*dz - 2*|dz|*z0 + z0*z0 = (|dz| - z0).^2 + // dz*dz - 2*z0*z0 + z0*z0 < (|dz| - z0).^2 + // dz*dz - z0*z0 < (|dz| - z0).^2 + // + // if |dz| < z0 ==> + // dz*dz - z0*z0 < 0.0 (true) + return distanceSquared - zHeightDistanceDeadzone * zHeightDistanceDeadzone; +} + +double singleSidedSquaredDistance(double value, double min, double max) { + // - | 0 | + + // min max + // Returns 0.0 if between min and max. Returns the distance to one boundary otherwise. + if (value < min) { + double diff = min - value; + return diff * diff; + } else if (value < max) { + return 0.0; + } else { + double diff = max - value; + return diff * diff; + } +} + +double squaredDistanceToBoundingBox(const vector3_t& positionInWorld, const cpd::PlanarRegion& planarRegion) { + const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionInWorld, planarRegion.planeParameters); + double dxdx = singleSidedSquaredDistance(positionInTerrainFrame.x(), planarRegion.bbox2d.xmin(), planarRegion.bbox2d.xmax()); + double dydy = singleSidedSquaredDistance(positionInTerrainFrame.y(), planarRegion.bbox2d.ymin(), planarRegion.bbox2d.ymax()); + double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); + return dxdx + dydy + dzdz; +} + +const cpd::CgalPolygonWithHoles2d* findInsetContainingThePoint(const cpd::CgalPoint2d& point, + const std::vector& insets) { + for (const auto& inset : insets) { + if (cpd::isInside(point, inset.outer_boundary())) { + return &inset; + } + } + return nullptr; +} + +std::pair squaredDistanceToBoundary(const vector3_t& positionInWorld, const cpd::PlanarRegion& planarRegion) { + const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionInWorld, planarRegion.planeParameters); + const double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); + const cpd::CgalPoint2d queryProjectedToPlane{positionInTerrainFrame.x(), positionInTerrainFrame.y()}; + + // First search if the projected point is inside any of the insets. + const auto* const insetPtrContainingPoint = findInsetContainingThePoint(queryProjectedToPlane, planarRegion.boundaryWithInset.insets); + + // Compute the projection + cpd::CgalPoint2d projectedPoint; + if (insetPtrContainingPoint == nullptr) { + // Not inside any of the insets. Need to look for the closest one. The projection will be to the boundary + double minDistSquared = std::numeric_limits::max(); + for (const auto& inset : planarRegion.boundaryWithInset.insets) { + const auto closestPoint = cpd::projectToClosestPoint(queryProjectedToPlane, inset.outer_boundary()); + double distSquare = cpd::squaredDistance(closestPoint, queryProjectedToPlane); + if (distSquare < minDistSquared) { + projectedPoint = closestPoint; + minDistSquared = distSquare; + } + } + } else { + // Query point is inside and does not need projection... + projectedPoint = queryProjectedToPlane; + + // ... unless it is inside a hole + for (const auto& hole : insetPtrContainingPoint->holes()) { + if (cpd::isInside(queryProjectedToPlane, hole)) { + projectedPoint = cpd::projectToClosestPoint(queryProjectedToPlane, hole); + break; // No need to search other holes. Holes are not overlapping + } + } + } + + return {dzdz + cpd::squaredDistance(projectedPoint, queryProjectedToPlane), projectedPoint}; +} + +std::pair getPlanarRegionAtPositionInWorld( + const vector3_t& positionInWorld, const std::vector& planarRegions) { + // Compute distance to bounding boxes + std::vector> regionsAndBboxSquareDistances; + regionsAndBboxSquareDistances.reserve(planarRegions.size()); + for (const auto& planarRegion : planarRegions) { + double squareDistance = squaredDistanceToBoundingBox(positionInWorld, planarRegion); + regionsAndBboxSquareDistances.emplace_back(&planarRegion, distanceCostLowerbound(squareDistance)); + } + + // Sort regions close to far + std::sort(regionsAndBboxSquareDistances.begin(), regionsAndBboxSquareDistances.end(), + [](const std::pair& lhs, const std::pair& rhs) { + return lhs.second < rhs.second; + }); + + // Look for closest planar region. Use bbox as lower bound to stop searching. + double minDistSquared = std::numeric_limits::max(); + std::pair closestRegionAndProjection; + for (const auto& regionAndBboxSquareDistance : regionsAndBboxSquareDistances) { + if (regionAndBboxSquareDistance.second > minDistSquared) { + break; // regions are sorted. Can exit on the first lower bound being larger than running minimum + } + + const auto distanceSqrAndProjection = squaredDistanceToBoundary(positionInWorld, *regionAndBboxSquareDistance.first); + const auto& projectionInWorldFrame = + positionInWorldFrameFromPositionInTerrain({distanceSqrAndProjection.second.x(), distanceSqrAndProjection.second.y(), 0.0}, + regionAndBboxSquareDistance.first->planeParameters); + const double distCost = distanceCost(positionInWorld, projectionInWorldFrame); + if (distCost < minDistSquared) { + minDistSquared = distCost; + closestRegionAndProjection = {regionAndBboxSquareDistance.first, distanceSqrAndProjection.second}; + } + } + + return closestRegionAndProjection; +} + +} // namespace switched_model \ No newline at end of file diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index 22883179..8cdb4d0f 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -7,40 +7,17 @@ #include #include -#include #include #include +#include "segmented_planes_terrain_model/SegmentedPlaneProjection.h" + namespace switched_model { namespace { -// TODO (rgrandia) : deadzone a parameter -const double zHeightDistanceDeadzone = 0.1; // [m] This difference in z height is not counted const std::string elevationLayerName = "elevation"; } // namespace -double distanceCost(const vector3_t& query, const vector3_t& terrainPoint) { - const double dx = query.x() - terrainPoint.x(); - const double dy = query.y() - terrainPoint.y(); - const double dz = std::max(0.0, std::abs(query.z() - terrainPoint.z()) - zHeightDistanceDeadzone); - return dx * dx + dy * dy + dz * dz; -} - -double distanceCostLowerbound(double distanceSquared) { - // cost = dx*dx + dy*dy + max(0.0, (|dz| - z0)).^2 with z0 >= 0 - // Need a lower bound for this cost derived from square distance and shift - // - // dz*dz - z0*z0 < max(0.0, (|dz| - z0)).^2 - // if |dz| > z0 ==> - // dz*dz - 2*|dz|*z0 + z0*z0 = (|dz| - z0).^2 - // dz*dz - 2*z0*z0 + z0*z0 < (|dz| - z0).^2 - // dz*dz - z0*z0 < (|dz| - z0).^2 - // - // if |dz| < z0 ==> - // dz*dz - z0*z0 < 0.0 (true) - return distanceSquared - zHeightDistanceDeadzone * zHeightDistanceDeadzone; -} - SegmentedPlanesTerrainModel::SegmentedPlanesTerrainModel(convex_plane_decomposition::PlanarTerrain planarTerrain) : planarTerrain_(std::move(planarTerrain)), signedDistanceField_(nullptr), @@ -96,114 +73,6 @@ void SegmentedPlanesTerrainModel::createSignedDistanceBetween(const Eigen::Vecto } } -double singleSidedSquaredDistance(double value, double min, double max) { - // - | 0 | + - // min max - // Returns 0.0 if between min and max. Returns the distance to one boundary otherwise. - if (value < min) { - double diff = min - value; - return diff * diff; - } else if (value < max) { - return 0.0; - } else { - double diff = max - value; - return diff * diff; - } -} - -double squaredDistanceToBoundingBox(const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarRegion& planarRegion) { - const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionInWorld, planarRegion.planeParameters); - double dxdx = singleSidedSquaredDistance(positionInTerrainFrame.x(), planarRegion.bbox2d.xmin(), planarRegion.bbox2d.xmax()); - double dydy = singleSidedSquaredDistance(positionInTerrainFrame.y(), planarRegion.bbox2d.ymin(), planarRegion.bbox2d.ymax()); - double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); - return dxdx + dydy + dzdz; -} - -const convex_plane_decomposition::CgalPolygonWithHoles2d* findInsetContainingThePoint( - const convex_plane_decomposition::CgalPoint2d& point, const std::vector& insets) { - for (const auto& inset : insets) { - if (convex_plane_decomposition::isInside(point, inset.outer_boundary())) { - return &inset; - } - } - return nullptr; -} - -std::pair squaredDistanceToBoundary( - const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarRegion& planarRegion) { - const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionInWorld, planarRegion.planeParameters); - const double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); - const convex_plane_decomposition::CgalPoint2d queryProjectedToPlane{positionInTerrainFrame.x(), positionInTerrainFrame.y()}; - - // First search if the projected point is inside any of the insets. - const auto* const insetPtrContainingPoint = findInsetContainingThePoint(queryProjectedToPlane, planarRegion.boundaryWithInset.insets); - - // Compute the projection - convex_plane_decomposition::CgalPoint2d projectedPoint; - if (insetPtrContainingPoint == nullptr) { - // Not inside any of the insets. Need to look for the closest one. The projection will be to the boundary - double minDistSquared = std::numeric_limits::max(); - for (const auto& inset : planarRegion.boundaryWithInset.insets) { - const auto closestPoint = convex_plane_decomposition::projectToClosestPoint(queryProjectedToPlane, inset.outer_boundary()); - double distSquare = convex_plane_decomposition::squaredDistance(closestPoint, queryProjectedToPlane); - if (distSquare < minDistSquared) { - projectedPoint = closestPoint; - minDistSquared = distSquare; - } - } - } else { - // Query point is inside and does not need projection... - projectedPoint = queryProjectedToPlane; - - // ... unless it is inside a hole - for (const auto& hole : insetPtrContainingPoint->holes()) { - if (convex_plane_decomposition::isInside(queryProjectedToPlane, hole)) { - projectedPoint = convex_plane_decomposition::projectToClosestPoint(queryProjectedToPlane, hole); - break; // No need to search other holes. Holes are not overlapping - } - } - } - - return {dzdz + convex_plane_decomposition::squaredDistance(projectedPoint, queryProjectedToPlane), projectedPoint}; -} - -std::pair getPlanarRegionAtPositionInWorld( - const vector3_t& positionInWorld, const std::vector& planarRegions) { - // Compute distance to bounding boxes - std::vector> regionsAndBboxSquareDistances; - regionsAndBboxSquareDistances.reserve(planarRegions.size()); - for (const auto& planarRegion : planarRegions) { - double squareDistance = squaredDistanceToBoundingBox(positionInWorld, planarRegion); - regionsAndBboxSquareDistances.emplace_back(&planarRegion, distanceCostLowerbound(squareDistance)); - } - - // Sort regions close to far - std::sort(regionsAndBboxSquareDistances.begin(), regionsAndBboxSquareDistances.end(), - [](const std::pair& lhs, - const std::pair& rhs) { return lhs.second < rhs.second; }); - - // Look for closest planar region. Use bbox as lower bound to stop searching. - double minDistSquared = std::numeric_limits::max(); - std::pair closestRegionAndProjection; - for (const auto& regionAndBboxSquareDistance : regionsAndBboxSquareDistances) { - if (regionAndBboxSquareDistance.second > minDistSquared) { - break; // regions are sorted. Can exit on the first lower bound being larger than running minimum - } - - const auto distanceSqrAndProjection = squaredDistanceToBoundary(positionInWorld, *regionAndBboxSquareDistance.first); - const auto& projectionInWorldFrame = - positionInWorldFrameFromPositionInTerrain({distanceSqrAndProjection.second.x(), distanceSqrAndProjection.second.y(), 0.0}, - regionAndBboxSquareDistance.first->planeParameters); - const double distCost = distanceCost(positionInWorld, projectionInWorldFrame); - if (distCost < minDistSquared) { - minDistSquared = distCost; - closestRegionAndProjection = {regionAndBboxSquareDistance.first, distanceSqrAndProjection.second}; - } - } - - return closestRegionAndProjection; -} - vector3_t SegmentedPlanesTerrainModel::getHighestObstacleAlongLine(const vector3_t& position1InWorld, const vector3_t& position2InWorld) const { const auto result = grid_map::lookup::maxValueBetweenLocations( From e51ea24065920316c612ddf62a20054f37d2f427 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 12 Oct 2021 18:58:07 +0200 Subject: [PATCH 109/504] refactor shortest plane projection. Remove discount on z-direction. No longer necessary with perceptive base reference. --- .../SegmentedPlaneProjection.h | 30 +++++- .../src/SegmentedPlaneProjection.cpp | 98 ++++++++++--------- .../src/SegmentedPlanesTerrainModel.cpp | 6 +- 3 files changed, 78 insertions(+), 56 deletions(-) diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h index 95be21a5..07df944f 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include @@ -15,15 +16,36 @@ double distanceCost(const vector3_t& query, const vector3_t& terrainPoint); double distanceCostLowerbound(double distanceSquared); -double singleSidedSquaredDistance(double value, double min, double max); +double intervalSquareDistance(double value, double min, double max); -double squaredDistanceToBoundingBox(const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarRegion& planarRegion); +double squaredDistanceToBoundingBox(const convex_plane_decomposition::CgalPoint2d& point, const convex_plane_decomposition::CgalBbox2d& boundingBox) ; + +/** Converts a 3D position in world frame to a 2D position in the terrain frame. */ +inline convex_plane_decomposition::CgalPoint2d position2dInTerrainFrameFromPositionInWorld(const vector3_t& positionWorld, + const TerrainPlane& terrainPlane) { + const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionWorld, terrainPlane); + return {positionInTerrainFrame.x(), positionInTerrainFrame.y()}; +} + +/** Converts a 2D position in terrain frame to a 3D position in the world frame. */ +inline vector3_t positionInWorldFrameFromPosition2dInTerrain(const convex_plane_decomposition::CgalPoint2d& positionInTerrain, + const TerrainPlane& terrainPlane) { + return positionInWorldFrameFromPositionInTerrain({positionInTerrain.x(), positionInTerrain.y(), 0.0}, terrainPlane); +} const convex_plane_decomposition::CgalPolygonWithHoles2d* findInsetContainingThePoint( const convex_plane_decomposition::CgalPoint2d& point, const std::vector& insets); -std::pair squaredDistanceToBoundary( - const vector3_t& positionInWorld, const convex_plane_decomposition::PlanarRegion& planarRegion); +convex_plane_decomposition::CgalPoint2d projectToPlanarRegion(const convex_plane_decomposition::CgalPoint2d& queryProjectedToPlane, + const convex_plane_decomposition::PlanarRegion& planarRegion); + +struct RegionSortingInfo { + const convex_plane_decomposition::PlanarRegion* regionPtr; + convex_plane_decomposition::CgalPoint2d positionInTerrainFrame; + double boundingBoxSquareDistance; +}; +std::vector sortWithBoundingBoxes(const vector3_t& positionInWorld, + const std::vector& planarRegions); std::pair getPlanarRegionAtPositionInWorld( const vector3_t& positionInWorld, const std::vector& planarRegions); diff --git a/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp b/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp index de82571c..b8463cf9 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp @@ -11,32 +11,18 @@ namespace switched_model { // alias to avoid long namespace namespace cpd = convex_plane_decomposition; -// TODO (rgrandia) : deadzone a parameter -const double zHeightDistanceDeadzone = 0.1; // [m] This difference in z height is not counted - double distanceCost(const vector3_t& query, const vector3_t& terrainPoint) { const double dx = query.x() - terrainPoint.x(); const double dy = query.y() - terrainPoint.y(); - const double dz = std::max(0.0, std::abs(query.z() - terrainPoint.z()) - zHeightDistanceDeadzone); + const double dz = query.z() - terrainPoint.z(); return dx * dx + dy * dy + dz * dz; } double distanceCostLowerbound(double distanceSquared) { - // cost = dx*dx + dy*dy + max(0.0, (|dz| - z0)).^2 with z0 >= 0 - // Need a lower bound for this cost derived from square distance and shift - // - // dz*dz - z0*z0 < max(0.0, (|dz| - z0)).^2 - // if |dz| > z0 ==> - // dz*dz - 2*|dz|*z0 + z0*z0 = (|dz| - z0).^2 - // dz*dz - 2*z0*z0 + z0*z0 < (|dz| - z0).^2 - // dz*dz - z0*z0 < (|dz| - z0).^2 - // - // if |dz| < z0 ==> - // dz*dz - z0*z0 < 0.0 (true) - return distanceSquared - zHeightDistanceDeadzone * zHeightDistanceDeadzone; + return distanceSquared; } -double singleSidedSquaredDistance(double value, double min, double max) { +double intervalSquareDistance(double value, double min, double max) { // - | 0 | + // min max // Returns 0.0 if between min and max. Returns the distance to one boundary otherwise. @@ -51,12 +37,10 @@ double singleSidedSquaredDistance(double value, double min, double max) { } } -double squaredDistanceToBoundingBox(const vector3_t& positionInWorld, const cpd::PlanarRegion& planarRegion) { - const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionInWorld, planarRegion.planeParameters); - double dxdx = singleSidedSquaredDistance(positionInTerrainFrame.x(), planarRegion.bbox2d.xmin(), planarRegion.bbox2d.xmax()); - double dydy = singleSidedSquaredDistance(positionInTerrainFrame.y(), planarRegion.bbox2d.ymin(), planarRegion.bbox2d.ymax()); - double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); - return dxdx + dydy + dzdz; +double squaredDistanceToBoundingBox(const cpd::CgalPoint2d& point, const cpd::CgalBbox2d& boundingBox) { + double dxdx = intervalSquareDistance(point.x(), boundingBox.xmin(), boundingBox.xmax()); + double dydy = intervalSquareDistance(point.y(), boundingBox.ymin(), boundingBox.ymax()); + return dxdx + dydy; } const cpd::CgalPolygonWithHoles2d* findInsetContainingThePoint(const cpd::CgalPoint2d& point, @@ -69,11 +53,7 @@ const cpd::CgalPolygonWithHoles2d* findInsetContainingThePoint(const cpd::CgalPo return nullptr; } -std::pair squaredDistanceToBoundary(const vector3_t& positionInWorld, const cpd::PlanarRegion& planarRegion) { - const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionInWorld, planarRegion.planeParameters); - const double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); - const cpd::CgalPoint2d queryProjectedToPlane{positionInTerrainFrame.x(), positionInTerrainFrame.y()}; - +cpd::CgalPoint2d projectToPlanarRegion(const cpd::CgalPoint2d& queryProjectedToPlane, const cpd::PlanarRegion& planarRegion) { // First search if the projected point is inside any of the insets. const auto* const insetPtrContainingPoint = findInsetContainingThePoint(queryProjectedToPlane, planarRegion.boundaryWithInset.insets); @@ -103,41 +83,63 @@ std::pair squaredDistanceToBoundary(const vector3_t& p } } - return {dzdz + cpd::squaredDistance(projectedPoint, queryProjectedToPlane), projectedPoint}; + return projectedPoint; } -std::pair getPlanarRegionAtPositionInWorld( - const vector3_t& positionInWorld, const std::vector& planarRegions) { +std::vector sortWithBoundingBoxes(const vector3_t& positionInWorld, + const std::vector& planarRegions) { // Compute distance to bounding boxes - std::vector> regionsAndBboxSquareDistances; + std::vector regionsAndBboxSquareDistances; regionsAndBboxSquareDistances.reserve(planarRegions.size()); for (const auto& planarRegion : planarRegions) { - double squareDistance = squaredDistanceToBoundingBox(positionInWorld, planarRegion); - regionsAndBboxSquareDistances.emplace_back(&planarRegion, distanceCostLowerbound(squareDistance)); + const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionInWorld, planarRegion.planeParameters); + const double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); + + RegionSortingInfo regionSortingInfo; + regionSortingInfo.regionPtr = &planarRegion; + regionSortingInfo.positionInTerrainFrame = {positionInTerrainFrame.x(), positionInTerrainFrame.y()}; + regionSortingInfo.boundingBoxSquareDistance = + squaredDistanceToBoundingBox(regionSortingInfo.positionInTerrainFrame, planarRegion.bbox2d) + dzdz; + + regionsAndBboxSquareDistances.push_back(regionSortingInfo); } // Sort regions close to far std::sort(regionsAndBboxSquareDistances.begin(), regionsAndBboxSquareDistances.end(), - [](const std::pair& lhs, const std::pair& rhs) { - return lhs.second < rhs.second; + [](const RegionSortingInfo& lhs, const RegionSortingInfo& rhs) { + return lhs.boundingBoxSquareDistance < rhs.boundingBoxSquareDistance; }); - // Look for closest planar region. Use bbox as lower bound to stop searching. - double minDistSquared = std::numeric_limits::max(); + return regionsAndBboxSquareDistances; +} + +std::pair getPlanarRegionAtPositionInWorld( + const vector3_t& positionInWorld, const std::vector& planarRegions) { + const auto sortedRegions = sortWithBoundingBoxes(positionInWorld, planarRegions); + + // Look for closest planar region. + double minCost = std::numeric_limits::max(); std::pair closestRegionAndProjection; - for (const auto& regionAndBboxSquareDistance : regionsAndBboxSquareDistances) { - if (regionAndBboxSquareDistance.second > minDistSquared) { - break; // regions are sorted. Can exit on the first lower bound being larger than running minimum + for (const auto& regionInfo : sortedRegions) { + // Skip based on lower bound + if (distanceCostLowerbound(regionInfo.boundingBoxSquareDistance) > minCost) { + continue; } - const auto distanceSqrAndProjection = squaredDistanceToBoundary(positionInWorld, *regionAndBboxSquareDistance.first); - const auto& projectionInWorldFrame = - positionInWorldFrameFromPositionInTerrain({distanceSqrAndProjection.second.x(), distanceSqrAndProjection.second.y(), 0.0}, - regionAndBboxSquareDistance.first->planeParameters); + // Shorthand + const auto* regionPtr = regionInfo.regionPtr; + const auto& planeParameters = regionPtr->planeParameters; + + // Project onto planar region + const auto projectedPointInTerrainFrame = projectToPlanarRegion(regionInfo.positionInTerrainFrame, *regionPtr); + + // Express projected point in World frame + const auto projectionInWorldFrame = positionInWorldFrameFromPosition2dInTerrain(projectedPointInTerrainFrame, planeParameters); + const double distCost = distanceCost(positionInWorld, projectionInWorldFrame); - if (distCost < minDistSquared) { - minDistSquared = distCost; - closestRegionAndProjection = {regionAndBboxSquareDistance.first, distanceSqrAndProjection.second}; + if (distCost < minCost) { + minCost = distCost; + closestRegionAndProjection = {regionPtr, projectedPointInTerrainFrame}; } } diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index 8cdb4d0f..ebf05fbe 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -27,8 +27,7 @@ TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorldAlongG const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions); const auto& region = *regionAndSeedPoint.first; const auto& seedpoint = regionAndSeedPoint.second; - const auto& seedpointInWorldFrame = - positionInWorldFrameFromPositionInTerrain({seedpoint.x(), seedpoint.y(), 0.0}, region.planeParameters); + const auto& seedpointInWorldFrame = positionInWorldFrameFromPosition2dInTerrain(seedpoint, region.planeParameters); return TerrainPlane{seedpointInWorldFrame, region.planeParameters.orientationWorldToTerrain}; } @@ -36,8 +35,7 @@ ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld(con const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions); const auto& region = *regionAndSeedPoint.first; const auto& seedpoint = regionAndSeedPoint.second; - const auto& seedpointInWorldFrame = - positionInWorldFrameFromPositionInTerrain({seedpoint.x(), seedpoint.y(), 0.0}, region.planeParameters); + const auto& seedpointInWorldFrame = positionInWorldFrameFromPosition2dInTerrain(seedpoint, region.planeParameters); // Convert boundary and seedpoint to terrain frame const int numberOfVertices = 16; // Multiple of 4 is nice for symmetry. From 09eb0f627d975a46468c82a4765368d1a78eb238 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Fri, 15 Oct 2021 16:57:04 +0200 Subject: [PATCH 110/504] provide height profile along line --- .../SegmentedPlanesTerrainModel.h | 2 ++ .../src/SegmentedPlanesTerrainModel.cpp | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h index 098b28df..23960def 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h @@ -25,6 +25,8 @@ class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { vector3_t getHighestObstacleAlongLine(const vector3_t& position1InWorld, const vector3_t& position2InWorld) const override; + std::vector getHeightProfileAlongLine(const vector3_t& position1InWorld, const vector3_t& position2InWorld) const override; + const convex_plane_decomposition::PlanarTerrain& planarTerrain() const { return planarTerrain_; } private: diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index ebf05fbe..f3a7bc1a 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -87,4 +87,35 @@ vector3_t SegmentedPlanesTerrainModel::getHighestObstacleAlongLine(const vector3 } } +std::vector SegmentedPlanesTerrainModel::getHeightProfileAlongLine(const vector3_t& position1InWorld, + const vector3_t& position2InWorld) const { + const vector2_t diff2d = position2InWorld.head<2>() - position1InWorld.head<2>(); + const scalar_t diffSquareNorm = diff2d.squaredNorm(); + const auto resolution = planarTerrain_.gridMap.getResolution(); + + if (diffSquareNorm > (resolution * resolution)) { // norm(p2-p1)_XY > resolution + const auto pointsOnLine = + grid_map::lookup::valuesBetweenLocations({position1InWorld.x(), position1InWorld.y()}, {position2InWorld.x(), position2InWorld.y()}, + planarTerrain_.gridMap, *elevationData_); + + std::vector heightProfile; + heightProfile.reserve(pointsOnLine.size()); + + for (const auto& point : pointsOnLine) { + const vector2_t pointDiff = point.head<2>() - position1InWorld.head<2>(); + const scalar_t lineProgress = pointDiff.dot(diff2d) / diffSquareNorm; + if (lineProgress >= 0.0 && lineProgress <= 1.0) { + heightProfile.push_back({lineProgress, point.z()}); + } + } + + return heightProfile; + } else { + grid_map::Index index; + planarTerrain_.gridMap.getIndex({position1InWorld.x(), position1InWorld.y()}, index); + scalar_t heightData = (*elevationData_)(index(0), index(1)); + return {{0.0, heightData}, {1.0, heightData}}; + } +} + } // namespace switched_model From 3905fac9388120923828430725642a0d5cbe48df Mon Sep 17 00:00:00 2001 From: rgrandia Date: Sun, 17 Oct 2021 20:56:09 +0200 Subject: [PATCH 111/504] fix plane surface normal computation (avg -> covariance based). + refactor --- .../SlidingWindowPlaneExtractor.h | 5 +- .../SlidingWindowPlaneExtractor.cpp | 237 +++++++++--------- 2 files changed, 127 insertions(+), 115 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h index e62d2dab..3003d818 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h @@ -26,14 +26,15 @@ class SlidingWindowPlaneExtractor { private: bool isGloballyPlanar(const Eigen::Vector3d& normalVectorPlane, const Eigen::Vector3d& supportVectorPlane, - const std::vector& points_with_normal) const; + const std::vector& pointsWithNormal) const; std::pair computeNormalAndErrorForWindow(const Eigen::MatrixXf& windowData) const; bool isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanError) const; int getLinearIndex(int row, int col) const { return row + col * map_->getSize()[0]; }; - void computePlaneParametersForLabel(int label); + void computePlaneParametersForLabel(int label, std::vector& pointsWithNormal); + void refineLabelWithRansac(int label, std::vector& pointsWithNormal); void extractPlaneParametersFromLabeledImage(); diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index b5a3e677..e3459371 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -14,8 +14,11 @@ namespace convex_plane_decomposition { namespace sliding_window_plane_extractor { -double angleBetweenVectorsInDegrees(const Eigen::Vector3d& v1, const Eigen::Vector3d& v2) { - double cos_rad = v1.normalized().dot(v2.normalized()); +namespace { + +// Assumes v1 and v2 are of unit lenght +double angleBetweenNormalizedVectorsInDegrees(const Eigen::Vector3d& v1, const Eigen::Vector3d& v2) { + double cos_rad = v1.dot(v2); if (cos_rad < -1.0) { cos_rad = -1.0; } else if (cos_rad > 1.0) { @@ -24,6 +27,32 @@ double angleBetweenVectorsInDegrees(const Eigen::Vector3d& v1, const Eigen::Vect return std::abs(std::acos(cos_rad) * 180.0 / M_PI); } +std::pair normalAndErrorFromCovariance(int numPoint, const Eigen::Vector3d& mean, + const Eigen::Matrix3d& sumSquared) { + const Eigen::Matrix3d covarianceMatrix = sumSquared / numPoint - mean * mean.transpose(); + + // Compute Eigenvectors. + // Eigenvalues are ordered small to large. + // Worst case bound for zero eigenvalue from : https://eigen.tuxfamily.org/dox/classEigen_1_1SelfAdjointEigenSolver.html + Eigen::SelfAdjointEigenSolver solver; + solver.computeDirect(covarianceMatrix, Eigen::DecompositionOptions::ComputeEigenvectors); + if (solver.eigenvalues()(1) > 1e-8) { + Eigen::Vector3d unitaryNormalVector = solver.eigenvectors().col(0); + + // Check direction of the normal vector and flip the sign upwards + if (unitaryNormalVector.z() < 0.0) { + unitaryNormalVector = -unitaryNormalVector; + } + // The first eigenvalue might become slightly negative due to numerics. + double rmsError = (solver.eigenvalues()(0) > 0.0) ? std::sqrt(solver.eigenvalues()(0)) : 0.0; + return {unitaryNormalVector, rmsError}; + } else { // If second eigenvalue is zero, the normal is not defined. + return {Eigen::Vector3d::UnitZ(), 1e30}; + } +} + +} // namespace + SlidingWindowPlaneExtractor::SlidingWindowPlaneExtractor(const SlidingWindowPlaneExtractorParameters& parameters, const ransac_plane_extractor::RansacPlaneExtractorParameters& ransacParameters) : parameters_(parameters), ransacParameters_(ransacParameters) {} @@ -77,32 +106,13 @@ std::pair SlidingWindowPlaneExtractor::computeNormalAnd return {Eigen::Vector3d::UnitZ(), 1e30}; } else { const Eigen::Vector3d mean = sum / nPoints; - const Eigen::Matrix3d covarianceMatrix = sumSquared / nPoints - mean * mean.transpose(); - - // Compute Eigenvectors. - // Eigenvalues are ordered small to large. - // Worst case bound for zero eigenvalue from : https://eigen.tuxfamily.org/dox/classEigen_1_1SelfAdjointEigenSolver.html - Eigen::SelfAdjointEigenSolver solver; - solver.computeDirect(covarianceMatrix, Eigen::DecompositionOptions::ComputeEigenvectors); - if (solver.eigenvalues()(1) > 1e-8) { - Eigen::Vector3d unitaryNormalVector = solver.eigenvectors().col(0); - - // Check direction of the normal vector and flip the sign upwards - if (unitaryNormalVector.z() < 0.0) { - unitaryNormalVector = -unitaryNormalVector; - } - // The first eigenvalue might become slightly negative due to numerics. - double rmsError = (solver.eigenvalues()(0) > 0.0) ? std::sqrt(solver.eigenvalues()(0)) : 0.0; - return {unitaryNormalVector, rmsError}; - } else { // If second eigenvalue is zero, the normal is not defined. - return {Eigen::Vector3d::UnitZ(), 1e30}; - } + return normalAndErrorFromCovariance(nPoints, mean, sumSquared); } } bool SlidingWindowPlaneExtractor::isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanError) const { return (meanError < parameters_.plane_patch_error_threshold && - angleBetweenVectorsInDegrees(localNormal, Eigen::Vector3d::UnitZ()) < parameters_.plane_inclination_threshold_degrees); + angleBetweenNormalizedVectorsInDegrees(localNormal, Eigen::Vector3d::UnitZ()) < parameters_.plane_inclination_threshold_degrees); } void SlidingWindowPlaneExtractor::runSlidingWindowDetector() { @@ -146,131 +156,132 @@ void SlidingWindowPlaneExtractor::extractPlaneParametersFromLabeledImage() { const int numberOfExtractedPlanesWithoutRefinement = segmentedPlanesMap_.highestLabel; // Make local copy. The highestLabel is incremented inside the loop + // Reserve a workvector that is reused between processing labels + std::vector pointsWithNormal; + pointsWithNormal.reserve(segmentedPlanesMap_.labeledImage.rows * segmentedPlanesMap_.labeledImage.cols); + // Skip label 0. This is the background, i.e. non-planar region. for (int label = 1; label <= numberOfExtractedPlanesWithoutRefinement; ++label) { - computePlaneParametersForLabel(label); + computePlaneParametersForLabel(label, pointsWithNormal); } } -void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label) { +void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label, + std::vector& pointsWithNormal) { const auto& elevationData = (*map_)[elevationLayer_]; + pointsWithNormal.clear(); // clear the workvector - std::vector points_with_normal; - int approximate_num_points = - segmentedPlanesMap_.labeledImage.rows * segmentedPlanesMap_.labeledImage.cols / segmentedPlanesMap_.highestLabel; - points_with_normal.reserve(approximate_num_points); - - int number_of_normal_instances = 0; - int number_of_position_instances = 0; - Eigen::Vector3d normal_vector_sum = Eigen::Vector3d::Zero(); - Eigen::Vector3d support_vector_sum = Eigen::Vector3d::Zero(); - for (int row = 0; row < segmentedPlanesMap_.labeledImage.rows; ++row) { - for (int col = 0; col < segmentedPlanesMap_.labeledImage.cols; ++col) { + int numPoints = 0; + Eigen::Vector3d sum = Eigen::Vector3d::Zero(); + Eigen::Matrix3d sumSquared = Eigen::Matrix3d::Zero(); + for (int col = 0; col < segmentedPlanesMap_.labeledImage.cols; ++col) { + for (int row = 0; row < segmentedPlanesMap_.labeledImage.rows; ++row) { if (segmentedPlanesMap_.labeledImage.at(row, col) == label) { double height = elevationData(row, col); if (std::isfinite(height)) { - Eigen::Vector2i index{row, col}; - - Eigen::Vector3d normal_vector_temp = surfaceNormals_[getLinearIndex(index.x(), index.y())]; - normal_vector_sum += normal_vector_temp; - ++number_of_normal_instances; + const Eigen::Vector3d point3d{segmentedPlanesMap_.mapOrigin.x() - row * segmentedPlanesMap_.resolution, + segmentedPlanesMap_.mapOrigin.y() - col * segmentedPlanesMap_.resolution, height}; - Eigen::Vector3d point3d{segmentedPlanesMap_.mapOrigin.x() - row * segmentedPlanesMap_.resolution, - segmentedPlanesMap_.mapOrigin.y() - col * segmentedPlanesMap_.resolution, height}; - support_vector_sum += point3d; - ++number_of_position_instances; + ++numPoints; + sum += point3d; + sumSquared.noalias() += point3d * point3d.transpose(); - points_with_normal.emplace_back( + const auto& localSurfaceNormal = surfaceNormals_[getLinearIndex(row, col)]; + pointsWithNormal.emplace_back( ransac_plane_extractor::Point3D(point3d.x(), point3d.y(), point3d.z()), - ransac_plane_extractor::Vector3D(normal_vector_temp.x(), normal_vector_temp.y(), normal_vector_temp.z())); + ransac_plane_extractor::Vector3D(localSurfaceNormal.x(), localSurfaceNormal.y(), localSurfaceNormal.z())); } } } } - if (number_of_position_instances < parameters_.min_number_points_per_label) { + if (numPoints < parameters_.min_number_points_per_label || numPoints < 3) { // Label has too little points, no plane parameters are created return; } - Eigen::Vector3d normal_vector_avg = normal_vector_sum / number_of_normal_instances; - normal_vector_avg.normalize(); // Averaging does not preserve norm - Eigen::Vector3d support_vector_avg = support_vector_sum / number_of_position_instances; - // Compute error to fitted plane. - if (parameters_.include_ransac_refinement && !isGloballyPlanar(normal_vector_avg, support_vector_avg, points_with_normal)) { - // Fix the seed for each label to get deterministic behaviour - CGAL::get_default_random() = CGAL::Random(0); - - // Run ransac - ransac_plane_extractor::RansacPlaneExtractor ransac_plane_extractor(ransacParameters_); - ransac_plane_extractor.detectPlanes(points_with_normal); - const auto& planes = ransac_plane_extractor.getDetectedPlanes(); - - bool reuseLabel = true; - for (const auto& plane : planes) { - // Bookkeeping of labels : reuse old label for the first plane - int newLabel = (reuseLabel) ? label : ++segmentedPlanesMap_.highestLabel; - reuseLabel = false; - - // Compute average plane parameters for refined segmentation - const std::vector& plane_point_indices = plane->indices_of_assigned_points(); - Eigen::Vector3d support_vector_refined_sum = Eigen::Vector3d::Zero(); - Eigen::Vector3d normal_vector_refined_sum = Eigen::Vector3d::Zero(); - for (const auto index : plane_point_indices) { - const auto& point = points_with_normal[index].first; - const auto& normal = points_with_normal[index].second; - support_vector_refined_sum += Eigen::Vector3d(point.x(), point.y(), point.z()); - normal_vector_refined_sum += Eigen::Vector3d(normal.x(), normal.y(), normal.z()); - - // relabel if required - if (newLabel != label) { - // Need to lookup indices in map, because RANSAC has reordered the points - Eigen::Array2i map_indices; - map_->getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); - segmentedPlanesMap_.labeledImage.at(map_indices(0), map_indices(1)) = newLabel; - } - } + const Eigen::Vector3d supportVector = sum / numPoints; + const Eigen::Vector3d normalVector = normalAndErrorFromCovariance(numPoints, supportVector, sumSquared).first; - Eigen::Vector3d normal_vector_refined_avg = normal_vector_refined_sum / plane_point_indices.size(); - normal_vector_refined_avg.normalize(); // Averaging does not preserve norm - Eigen::Vector3d support_vector_refined_avg = support_vector_refined_sum / plane_point_indices.size(); + // Compute error to fitted plane. + if (parameters_.include_ransac_refinement && !isGloballyPlanar(normalVector, supportVector, pointsWithNormal)) { + refineLabelWithRansac(label, pointsWithNormal); + } else { + if (angleBetweenNormalizedVectorsInDegrees(normalVector, Eigen::Vector3d::UnitZ()) < parameters_.plane_inclination_threshold_degrees) { + const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); + segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, TerrainPlane(supportVector, terrainOrientation)); + } + } +} - if (angleBetweenVectorsInDegrees(normal_vector_refined_avg, Eigen::Vector3d::UnitZ()) < - parameters_.plane_inclination_threshold_degrees) { - const TerrainPlane temp_plane_parameters( - support_vector_refined_avg, switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normal_vector_refined_avg)); - segmentedPlanesMap_.labelPlaneParameters.emplace_back(newLabel, temp_plane_parameters); +void SlidingWindowPlaneExtractor::refineLabelWithRansac(int label, std::vector& pointsWithNormal) { + // Fix the seed for each label to get deterministic behaviour + CGAL::get_default_random() = CGAL::Random(0); + + // Run ransac + ransac_plane_extractor::RansacPlaneExtractor ransac_plane_extractor(ransacParameters_); + ransac_plane_extractor.detectPlanes(pointsWithNormal); + const auto& planes = ransac_plane_extractor.getDetectedPlanes(); + + bool reuseLabel = true; + for (const auto& plane : planes) { + // Bookkeeping of labels : reuse old label for the first plane + const int newLabel = (reuseLabel) ? label : ++segmentedPlanesMap_.highestLabel; + reuseLabel = false; + + // Compute average plane parameters for refined segmentation + const std::vector& plane_point_indices = plane->indices_of_assigned_points(); + Eigen::Vector3d sum = Eigen::Vector3d::Zero(); + Eigen::Matrix3d sumSquared = Eigen::Matrix3d::Zero(); + for (const auto index : plane_point_indices) { + const auto& point = pointsWithNormal[index].first; + const Eigen::Vector3d point3d(point.x(), point.y(), point.z()); + + sum += point3d; + sumSquared.noalias() += point3d * point3d.transpose(); + + // relabel if required + if (newLabel != label) { + // Need to lookup indices in map, because RANSAC has reordered the points + Eigen::Array2i map_indices; + map_->getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); + segmentedPlanesMap_.labeledImage.at(map_indices(0), map_indices(1)) = newLabel; } } - const auto& unassigned_points = ransac_plane_extractor.getUnassignedPointIndices(); - for (const auto index : unassigned_points) { - const auto& point = points_with_normal[index].first; + const auto numPoints = plane_point_indices.size(); + const Eigen::Vector3d supportVector = sum / numPoints; + const Eigen::Vector3d normalVector = normalAndErrorFromCovariance(numPoints, supportVector, sumSquared).first; - // Need to lookup indices in map, because RANSAC has reordered the points - Eigen::Array2i map_indices; - map_->getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); - segmentedPlanesMap_.labeledImage.at(map_indices(0), map_indices(1)) = 0; - } - } else { - if (angleBetweenVectorsInDegrees(normal_vector_avg, Eigen::Vector3d::UnitZ()) < parameters_.plane_inclination_threshold_degrees) { - const TerrainPlane temp_plane_parameters(support_vector_avg, - switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normal_vector_avg)); - segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, temp_plane_parameters); + if (angleBetweenNormalizedVectorsInDegrees(normalVector, Eigen::Vector3d::UnitZ()) < parameters_.plane_inclination_threshold_degrees) { + const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); + segmentedPlanesMap_.labelPlaneParameters.emplace_back(newLabel, TerrainPlane(supportVector, terrainOrientation)); } } + + const auto& unassigned_points = ransac_plane_extractor.getUnassignedPointIndices(); + for (const auto index : unassigned_points) { + const auto& point = pointsWithNormal[index].first; + + // Need to lookup indices in map, because RANSAC has reordered the points + Eigen::Array2i map_indices; + map_->getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); + segmentedPlanesMap_.labeledImage.at(map_indices(0), map_indices(1)) = 0; + } } bool SlidingWindowPlaneExtractor::isGloballyPlanar(const Eigen::Vector3d& normalVectorPlane, const Eigen::Vector3d& supportVectorPlane, - const std::vector& points_with_normal) const { - for (const auto& point_with_normal : points_with_normal) { - Eigen::Vector3d p_S_P(point_with_normal.first.x() - supportVectorPlane.x(), point_with_normal.first.y() - supportVectorPlane.y(), - point_with_normal.first.z() - supportVectorPlane.z()); - double distanceError = std::abs(normalVectorPlane.dot(p_S_P)); + const std::vector& pointsWithNormal) const { + const double normalDotSupportvector = normalVectorPlane.dot(supportVectorPlane); + + for (const auto& pointWithNormal : pointsWithNormal) { + const double normalDotPoint = normalVectorPlane.x() * pointWithNormal.first.x() + normalVectorPlane.y() * pointWithNormal.first.y() + + normalVectorPlane.z() * pointWithNormal.first.z(); + const double distanceError = std::abs(normalDotPoint - normalDotSupportvector); if (distanceError > parameters_.global_plane_fit_distance_error_threshold) { return false; } else { - Eigen::Vector3d pointNormal{point_with_normal.second.x(), point_with_normal.second.y(), point_with_normal.second.z()}; - double angleError = angleBetweenVectorsInDegrees(pointNormal, normalVectorPlane); + Eigen::Vector3d pointNormal{pointWithNormal.second.x(), pointWithNormal.second.y(), pointWithNormal.second.z()}; + double angleError = angleBetweenNormalizedVectorsInDegrees(pointNormal, normalVectorPlane); if (angleError > parameters_.global_plane_fit_angle_error_threshold_degrees) { return false; } From f83b8abcd2f3581edb7c0d8b3dea79273d5bc834 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 18 Oct 2021 12:56:16 +0200 Subject: [PATCH 112/504] take cosine computation for angle threshold out of the loop --- .../SlidingWindowPlaneExtractor.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index e3459371..a2d1dc7a 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -271,22 +271,26 @@ void SlidingWindowPlaneExtractor::refineLabelWithRansac(int label, std::vector& pointsWithNormal) const { + // Part of the plane projection that is independent of the point const double normalDotSupportvector = normalVectorPlane.dot(supportVectorPlane); + // Convert threshold in degrees to threshold on dot product (between normalized vectors) + const double dotProductThreshold = std::cos(parameters_.global_plane_fit_angle_error_threshold_degrees * M_PI / 180.0); + for (const auto& pointWithNormal : pointsWithNormal) { const double normalDotPoint = normalVectorPlane.x() * pointWithNormal.first.x() + normalVectorPlane.y() * pointWithNormal.first.y() + normalVectorPlane.z() * pointWithNormal.first.z(); const double distanceError = std::abs(normalDotPoint - normalDotSupportvector); - if (distanceError > parameters_.global_plane_fit_distance_error_threshold) { + + const double dotProductNormals = normalVectorPlane.x() * pointWithNormal.second.x() + + normalVectorPlane.y() * pointWithNormal.second.y() + + normalVectorPlane.z() * pointWithNormal.second.z(); + + if (distanceError > parameters_.global_plane_fit_distance_error_threshold || dotProductNormals > dotProductThreshold) { return false; - } else { - Eigen::Vector3d pointNormal{pointWithNormal.second.x(), pointWithNormal.second.y(), pointWithNormal.second.z()}; - double angleError = angleBetweenNormalizedVectorsInDegrees(pointNormal, normalVectorPlane); - if (angleError > parameters_.global_plane_fit_angle_error_threshold_degrees) { - return false; - } } } + return true; } From 71195377fa578edf3f333d69d3056d016394957e Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 18 Oct 2021 13:26:17 +0200 Subject: [PATCH 113/504] save elevation before postprocessing --- convex_plane_decomposition/src/Postprocessing.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/convex_plane_decomposition/src/Postprocessing.cpp b/convex_plane_decomposition/src/Postprocessing.cpp index 331573ac..eca1808a 100644 --- a/convex_plane_decomposition/src/Postprocessing.cpp +++ b/convex_plane_decomposition/src/Postprocessing.cpp @@ -15,6 +15,9 @@ void Postprocessing::postprocess(PlanarTerrain& planarTerrain, const std::string auto& elevationData = planarTerrain.gridMap.get(elevationLayer); const auto& planarityMask = planarTerrain.gridMap.get(planeSegmentationLayer); + // Store the unaltered map + planarTerrain.gridMap.add(elevationLayer + "_before_postprocess", elevationData); + // post process planar regions addHeightOffset(planarTerrain.planarRegions); From 618b48db38765b7a4032bf652514370747d1488d Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 18 Oct 2021 13:26:35 +0200 Subject: [PATCH 114/504] lookup tf at the time of the gridmap message --- .../ConvexPlaneDecompositionRos.h | 2 +- .../src/ConvexPlaneDecompositionRos.cpp | 102 +++++++++--------- 2 files changed, 54 insertions(+), 50 deletions(-) diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h index 279002c3..d15083a7 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h @@ -39,7 +39,7 @@ class ConvexPlaneExtractionROS { */ void callback(const grid_map_msgs::GridMap& message); - Eigen::Isometry3d getTransformToTargetFrame(const std::string& sourceFrame); + Eigen::Isometry3d getTransformToTargetFrame(const std::string& sourceFrame, const ros::Time& time); // Parameters std::string elevationMapTopic_; diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 2a42d3b6..26e0cd8f 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -89,72 +89,76 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { grid_map::GridMapRosConverter::fromMessage(message, messageMap, layers, false, false); bool success; grid_map::GridMap elevationMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(subMapLength_, subMapWidth_), success); - success = success && containsFiniteValue(elevationMap.get(elevationLayer_)); // Check if there are values + success = success && containsFiniteValue(elevationMap.get(elevationLayer_)); // Check if there are values ROS_INFO("...done."); + // Exit early if map is not valid. + if (!success) { + ROS_WARN("[ConvexPlaneExtractionROS] Could not extract submap"); + return; + } + // Transform map if necessary if (targetFrameId_ != elevationMap.getFrameId()) { std::string errorMsg; - if (tfBuffer_.canTransform(targetFrameId_, elevationMap.getFrameId(), ros::Time(0), &errorMsg)) { - elevationMap = elevationMap.getTransformedMap(getTransformToTargetFrame(elevationMap.getFrameId()), elevationLayer_, targetFrameId_); + ros::Time timeStamp(messageMap.getTimestamp()); + if (tfBuffer_.canTransform(targetFrameId_, elevationMap.getFrameId(), timeStamp, &errorMsg)) { + elevationMap = + elevationMap.getTransformedMap(getTransformToTargetFrame(elevationMap.getFrameId(), timeStamp), elevationLayer_, targetFrameId_); } else { ROS_ERROR_STREAM("[ConvexPlaneExtractionROS] " << errorMsg); return; } } - if (success) { - auto t0 = std::chrono::high_resolution_clock::now(); - preprocessing_->preprocess(elevationMap, elevationLayer_); - auto t1 = std::chrono::high_resolution_clock::now(); - ROS_INFO_STREAM("Preprocessing took " << 1e-3 * std::chrono::duration_cast(t1 - t0).count() << " [ms]"); - - // Run pipeline. - slidingWindowPlaneExtractor_->runExtraction(elevationMap, elevationLayer_); - auto t2 = std::chrono::high_resolution_clock::now(); - ROS_INFO_STREAM("Sliding window took " << 1e-3 * std::chrono::duration_cast(t2 - t1).count() << " [ms]"); - - PlanarTerrain planarTerrain; - planarTerrain.planarRegions = contourExtraction_->extractPlanarRegions(slidingWindowPlaneExtractor_->getSegmentedPlanesMap()); - auto t3 = std::chrono::high_resolution_clock::now(); - ROS_INFO_STREAM("Contour extraction took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]"); - - // Add grid map to the terrain - planarTerrain.gridMap = std::move(elevationMap); - - // Add binary map - const std::string planeClassificationLayer{"plane_classification"}; - planarTerrain.gridMap.add(planeClassificationLayer); - auto& traversabilityMask = planarTerrain.gridMap.get(planeClassificationLayer); - cv::cv2eigen(slidingWindowPlaneExtractor_->getBinaryLabeledImage(), traversabilityMask); - - postprocessing_->postprocess(planarTerrain, elevationLayer_, planeClassificationLayer); - auto t4 = std::chrono::high_resolution_clock::now(); - ROS_INFO_STREAM("Postprocessing took " << 1e-3 * std::chrono::duration_cast(t4 - t3).count() << " [ms]"); - - // Publish terrain - if (publishToController_) { - regionPublisher_.publish(toMessage(planarTerrain)); - } + auto t0 = std::chrono::high_resolution_clock::now(); + preprocessing_->preprocess(elevationMap, elevationLayer_); + auto t1 = std::chrono::high_resolution_clock::now(); + ROS_INFO_STREAM("Preprocessing took " << 1e-3 * std::chrono::duration_cast(t1 - t0).count() << " [ms]"); + + // Run pipeline. + slidingWindowPlaneExtractor_->runExtraction(elevationMap, elevationLayer_); + auto t2 = std::chrono::high_resolution_clock::now(); + ROS_INFO_STREAM("Sliding window took " << 1e-3 * std::chrono::duration_cast(t2 - t1).count() << " [ms]"); + + PlanarTerrain planarTerrain; + planarTerrain.planarRegions = contourExtraction_->extractPlanarRegions(slidingWindowPlaneExtractor_->getSegmentedPlanesMap()); + auto t3 = std::chrono::high_resolution_clock::now(); + ROS_INFO_STREAM("Contour extraction took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]"); + + // Add grid map to the terrain + planarTerrain.gridMap = std::move(elevationMap); + + // Add binary map + const std::string planeClassificationLayer{"plane_classification"}; + planarTerrain.gridMap.add(planeClassificationLayer); + auto& traversabilityMask = planarTerrain.gridMap.get(planeClassificationLayer); + cv::cv2eigen(slidingWindowPlaneExtractor_->getBinaryLabeledImage(), traversabilityMask); + + postprocessing_->postprocess(planarTerrain, elevationLayer_, planeClassificationLayer); + auto t4 = std::chrono::high_resolution_clock::now(); + ROS_INFO_STREAM("Postprocessing took " << 1e-3 * std::chrono::duration_cast(t4 - t3).count() << " [ms]"); + + // Publish terrain + if (publishToController_) { + regionPublisher_.publish(toMessage(planarTerrain)); + } - // Visualize in Rviz. - planarTerrain.gridMap.add("segmentation"); - cv::cv2eigen(slidingWindowPlaneExtractor_->getSegmentedPlanesMap().labeledImage, planarTerrain.gridMap.get("segmentation")); - grid_map_msgs::GridMap outputMessage; - grid_map::GridMapRosConverter::toMessage(planarTerrain.gridMap, outputMessage); - filteredmapPublisher_.publish(outputMessage); + // Visualize in Rviz. + planarTerrain.gridMap.add("segmentation"); + cv::cv2eigen(slidingWindowPlaneExtractor_->getSegmentedPlanesMap().labeledImage, planarTerrain.gridMap.get("segmentation")); + grid_map_msgs::GridMap outputMessage; + grid_map::GridMapRosConverter::toMessage(planarTerrain.gridMap, outputMessage); + filteredmapPublisher_.publish(outputMessage); - boundaryPublisher_.publish(convertBoundariesToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId())); - insetPublisher_.publish(convertInsetsToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId())); - } else { - ROS_WARN("[ConvexPlaneExtractionROS] Could not extract submap"); - } + boundaryPublisher_.publish(convertBoundariesToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId())); + insetPublisher_.publish(convertInsetsToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId())); } -Eigen::Isometry3d ConvexPlaneExtractionROS::getTransformToTargetFrame(const std::string& sourceFrame) { +Eigen::Isometry3d ConvexPlaneExtractionROS::getTransformToTargetFrame(const std::string& sourceFrame, const ros::Time& time) { geometry_msgs::TransformStamped transformStamped; try { - transformStamped = tfBuffer_.lookupTransform(targetFrameId_, sourceFrame, ros::Time(0)); + transformStamped = tfBuffer_.lookupTransform(targetFrameId_, sourceFrame, time); } catch (tf2::TransformException& ex) { ROS_ERROR("[ConvexPlaneExtractionROS] %s", ex.what()); return Eigen::Isometry3d(); From 468ddb3b1bfaf96c5589fc36b6e673834ed37710 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 18 Oct 2021 16:52:01 +0200 Subject: [PATCH 115/504] - Split global / local inclination threshold - Change convolution borders to REPLICATE - Fix unassigned cells with nonzero labels -> set them to background - Extract classification after plane segmentation - Add opening filter and adapt inset size --- .../SlidingWindowPlaneExtractor.h | 2 + .../SlidingWindowPlaneExtractorParameters.h | 7 ++- .../src/Postprocessing.cpp | 8 +-- .../contour_extraction/ContourExtraction.cpp | 2 +- .../SlidingWindowPlaneExtractor.cpp | 53 ++++++++++--------- .../config/parameters.yaml | 7 +-- .../src/ParameterLoading.cpp | 3 +- 7 files changed, 47 insertions(+), 35 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h index 3003d818..699dfcc5 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h @@ -42,6 +42,8 @@ class SlidingWindowPlaneExtractor { void runSlidingWindowDetector(); + void setToBackground(int label); + SlidingWindowPlaneExtractorParameters parameters_; ransac_plane_extractor::RansacPlaneExtractorParameters ransacParameters_; diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h index d60607fe..bcdabb48 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h @@ -12,12 +12,15 @@ struct SlidingWindowPlaneExtractorParameters { /// Should be an odd number and at least 3. int kernel_size = 3; - /// [#] Erode planarity detection by this amount of pixels - int planarity_erosion = 0; + /// [#] Apply opening filter (erosion -> dilation) to planarity detection by this amount of pixels + int planarity_opening_filter = 0; /// [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch double plane_inclination_threshold_degrees = 70.0; + /// [deg] Maximum allowed angle between the surface normal and the world-z direction for a cell + double local_plane_inclination_threshold_degrees = 70.0; + /// [m] The allowed root-mean-squared deviation from the plane fitted to the patch. Higher -> not planar double plane_patch_error_threshold = 0.005; diff --git a/convex_plane_decomposition/src/Postprocessing.cpp b/convex_plane_decomposition/src/Postprocessing.cpp index eca1808a..355ef6c4 100644 --- a/convex_plane_decomposition/src/Postprocessing.cpp +++ b/convex_plane_decomposition/src/Postprocessing.cpp @@ -39,7 +39,7 @@ void Postprocessing::dilationInNonplanarRegions(Eigen::MatrixXf& elevationData, const int dilationSize = 2 * parameters_.nonplanar_horizontal_offset + 1; // const int dilationType = cv::MORPH_ELLIPSE; // ellipse inscribed in the square of size dilationSize const auto dilationKernel_ = cv::getStructuringElement(dilationType, cv::Size(dilationSize, dilationSize)); - cv::dilate(elevationImage, elevationImage, dilationKernel_); + cv::dilate(elevationImage, elevationImage, dilationKernel_, cv::Point(-1, -1), 1, cv::BORDER_REPLICATE); // convert back Eigen::MatrixXf elevationDilated; @@ -87,7 +87,7 @@ void Postprocessing::addSmoothLayer(grid_map::GridMap& gridMap, const Eigen::Mat // Dilate const int dilationType = cv::MORPH_ELLIPSE; // ellipse inscribed in the square of size dilationSize const auto dilationKernel_ = cv::getStructuringElement(dilationType, cv::Size(dilationSize, dilationSize)); - cv::dilate(elevationWithNaNImage, elevationWithNaNImage, dilationKernel_); + cv::dilate(elevationWithNaNImage, elevationWithNaNImage, dilationKernel_, cv::Point(-1, -1), 1, cv::BORDER_REPLICATE); // Take complement image where elevation data was set to NaN cv::Mat indicatorImage = cv::Mat::ones(elevationWithNaNImage.rows, elevationWithNaNImage.cols, CV_32F); @@ -99,8 +99,8 @@ void Postprocessing::addSmoothLayer(grid_map::GridMap& gridMap, const Eigen::Mat // Filter definition auto smoothingFilter = [kernel, kernelGauss](const cv::Mat& imageIn) { cv::Mat imageOut; - cv::boxFilter(imageIn, imageOut, -1, {kernel, kernel}, cv::Point(-1, -1), true, cv::BorderTypes::BORDER_CONSTANT); - cv::GaussianBlur(imageOut, imageOut, {kernelGauss, kernelGauss}, 0, 0, cv::BorderTypes::BORDER_CONSTANT); + cv::boxFilter(imageIn, imageOut, -1, {kernel, kernel}, cv::Point(-1, -1), true, cv::BorderTypes::BORDER_REPLICATE); + cv::GaussianBlur(imageOut, imageOut, {kernelGauss, kernelGauss}, 0, 0, cv::BorderTypes::BORDER_REPLICATE); return imageOut; }; diff --git a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp index 1963af66..21c4ac8f 100644 --- a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp +++ b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp @@ -49,7 +49,7 @@ std::vector extractBoundaryAndInset(cv::Mat& binary_image, co std::vector boundaries = extractPolygonsFromBinaryImage(binary_image); // Erode - cv::erode(binary_image, binary_image, erosionKernel); + cv::erode(binary_image, binary_image, erosionKernel, cv::Point(-1,-1), 1, cv::BORDER_REPLICATE); // Get insets std::vector insets = extractPolygonsFromBinaryImage(binary_image); diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index a2d1dc7a..3f0686b7 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -80,6 +80,10 @@ void SlidingWindowPlaneExtractor::runExtraction(const grid_map::GridMap& map, co runSlidingWindowDetector(); runSegmentation(); extractPlaneParametersFromLabeledImage(); + + // Get classification from segmentation to account for unassigned points. + binaryImagePatch_ = segmentedPlanesMap_.labeledImage > 0; + binaryImagePatch_.setTo(1, binaryImagePatch_ == 255); } std::pair SlidingWindowPlaneExtractor::computeNormalAndErrorForWindow(const Eigen::MatrixXf& windowData) const { @@ -112,7 +116,7 @@ std::pair SlidingWindowPlaneExtractor::computeNormalAnd bool SlidingWindowPlaneExtractor::isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanError) const { return (meanError < parameters_.plane_patch_error_threshold && - angleBetweenNormalizedVectorsInDegrees(localNormal, Eigen::Vector3d::UnitZ()) < parameters_.plane_inclination_threshold_degrees); + angleBetweenNormalizedVectorsInDegrees(localNormal, Eigen::Vector3d::UnitZ()) < parameters_.local_plane_inclination_threshold_degrees); } void SlidingWindowPlaneExtractor::runSlidingWindowDetector() { @@ -137,12 +141,12 @@ void SlidingWindowPlaneExtractor::runSlidingWindowDetector() { } } - // erode - if (parameters_.planarity_erosion > 0) { - const int erosionSize = 2 * parameters_.planarity_erosion + 1; - const int erosionType = cv::MORPH_CROSS; - const auto erosionKernel_ = cv::getStructuringElement(erosionType, cv::Size(erosionSize, erosionSize)); - cv::erode(binaryImagePatch_, binaryImagePatch_, erosionKernel_); + // opening filter + if (parameters_.planarity_opening_filter > 0) { + const int openingKernelSize = 2 * parameters_.planarity_opening_filter + 1; + const int openingKernelType = cv::MORPH_RECT; + const auto kernel_ = cv::getStructuringElement(openingKernelType, cv::Size(openingKernelSize, openingKernelSize)); + cv::morphologyEx(binaryImagePatch_, binaryImagePatch_, cv::MORPH_OPEN, kernel_, cv::Point(-1, -1), 1, cv::BORDER_REPLICATE); } } @@ -209,6 +213,8 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label, if (angleBetweenNormalizedVectorsInDegrees(normalVector, Eigen::Vector3d::UnitZ()) < parameters_.plane_inclination_threshold_degrees) { const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, TerrainPlane(supportVector, terrainOrientation)); + } else { + setToBackground(label); } } } @@ -222,6 +228,9 @@ void SlidingWindowPlaneExtractor::refineLabelWithRansac(int label, std::vectorgetIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); - segmentedPlanesMap_.labeledImage.at(map_indices(0), map_indices(1)) = newLabel; - } } const auto numPoints = plane_point_indices.size(); @@ -255,17 +256,17 @@ void SlidingWindowPlaneExtractor::refineLabelWithRansac(int label, std::vectorgetIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); - segmentedPlanesMap_.labeledImage.at(map_indices(0), map_indices(1)) = 0; + // Need to lookup indices in map, because RANSAC has reordered the points + Eigen::Array2i map_indices; + map_->getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); + segmentedPlanesMap_.labeledImage.at(map_indices(0), map_indices(1)) = newLabel; + } + } } } @@ -294,5 +295,9 @@ bool SlidingWindowPlaneExtractor::isGloballyPlanar(const Eigen::Vector3d& normal return true; } +void SlidingWindowPlaneExtractor::setToBackground(int label) { + segmentedPlanesMap_.labeledImage.setTo(0, segmentedPlanesMap_.labeledImage == label); +} + } // namespace sliding_window_plane_extractor } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 32e4529c..45df5bd0 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -6,8 +6,9 @@ preprocessing: sliding_window_plane_extractor: kernel_size: 3 # Size of the sliding window patch used for normal vector calculation and planarity detection. Should be an odd number and at least 3. - planarity_erosion: 0 # [#] Erode planarity detection by this amount of pixels - plane_inclination_threshold_degrees: 45.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch + planarity_opening_filter: 2 # [#] Apply opening filter (erosion -> dilation) to planarity detection by this amount of pixels + plane_inclination_threshold_degrees: 40.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch + local_plane_inclination_threshold_degrees: 55.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a cell plane_patch_error_threshold: 0.005 # [m] The allowed root-mean-squared deviation from the plane fitted to the sliding window. min_number_points_per_label: 10 # [#] Labels with less points assigned to them are discarded connectivity: 4 # Label kernel connectivity. 4 or 8 (cross or box) @@ -23,7 +24,7 @@ ransac_plane_refinement: normal_threshold: 25.0 # [deg] Set maximum normal deviation between cluster surface_normal and point normal. contour_extraction: - offsetSize: 2 # Size of the kernel creating the boundary offset. In number of pixels. + offsetSize: 1 # Size of the kernel creating the boundary offset. In number of pixels. postprocessing: extracted_planes_height_offset: 0.0 # Added offset in Z direction for the full map to compensate for the location of the foot frame w.r.t. the contact point diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/convex_plane_decomposition_ros/src/ParameterLoading.cpp index cc444ab5..b94c8925 100644 --- a/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ b/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -45,8 +45,9 @@ sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters loadSlidin const ros::NodeHandle& nodeHandle, const std::string& prefix) { sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters swParams; loadParameter(nodeHandle, prefix, "kernel_size", swParams.kernel_size); - loadParameter(nodeHandle, prefix, "planarity_erosion", swParams.planarity_erosion); + loadParameter(nodeHandle, prefix, "planarity_opening_filter", swParams.planarity_opening_filter); loadParameter(nodeHandle, prefix, "plane_inclination_threshold_degrees", swParams.plane_inclination_threshold_degrees); + loadParameter(nodeHandle, prefix, "local_plane_inclination_threshold_degrees", swParams.local_plane_inclination_threshold_degrees); loadParameter(nodeHandle, prefix, "plane_patch_error_threshold", swParams.plane_patch_error_threshold); loadParameter(nodeHandle, prefix, "min_number_points_per_label", swParams.min_number_points_per_label); loadParameter(nodeHandle, prefix, "connectivity", swParams.connectivity); From 27905a4f1f91b092d600d396e803be52059973fe Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 18 Oct 2021 17:11:01 +0200 Subject: [PATCH 116/504] simple optimizations. No sqrt for error comparison. Take angle threshold on dot product directly --- .../SlidingWindowPlaneExtractor.h | 2 +- .../SlidingWindowPlaneExtractorParameters.h | 8 ++--- .../SlidingWindowPlaneExtractor.cpp | 34 +++++++------------ .../src/ParameterLoading.cpp | 6 ++-- convex_plane_decomposition_ros/test/test.cpp | 33 +++++++++--------- 5 files changed, 38 insertions(+), 45 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h index 699dfcc5..374cd1a7 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h @@ -29,7 +29,7 @@ class SlidingWindowPlaneExtractor { const std::vector& pointsWithNormal) const; std::pair computeNormalAndErrorForWindow(const Eigen::MatrixXf& windowData) const; - bool isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanError) const; + bool isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanSquaredError) const; int getLinearIndex(int row, int col) const { return row + col * map_->getSize()[0]; }; diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h index bcdabb48..2309aaec 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h @@ -15,11 +15,11 @@ struct SlidingWindowPlaneExtractorParameters { /// [#] Apply opening filter (erosion -> dilation) to planarity detection by this amount of pixels int planarity_opening_filter = 0; - /// [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch - double plane_inclination_threshold_degrees = 70.0; + /// [-] Maximum allowed angle between the surface normal and the world-z direction for a patch (converted to dotproduct bound) + double plane_inclination_threshold = std::cos(70.0 * M_PI / 180.0); - /// [deg] Maximum allowed angle between the surface normal and the world-z direction for a cell - double local_plane_inclination_threshold_degrees = 70.0; + /// [-] Maximum allowed angle between the surface normal and the world-z direction for a cell (converted to dotproduct bound) + double local_plane_inclination_threshold = std::cos(70.0 * M_PI / 180.0); /// [m] The allowed root-mean-squared deviation from the plane fitted to the patch. Higher -> not planar double plane_patch_error_threshold = 0.005; diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index 3f0686b7..b7635c07 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -16,17 +16,6 @@ namespace sliding_window_plane_extractor { namespace { -// Assumes v1 and v2 are of unit lenght -double angleBetweenNormalizedVectorsInDegrees(const Eigen::Vector3d& v1, const Eigen::Vector3d& v2) { - double cos_rad = v1.dot(v2); - if (cos_rad < -1.0) { - cos_rad = -1.0; - } else if (cos_rad > 1.0) { - cos_rad = 1.0; - } - return std::abs(std::acos(cos_rad) * 180.0 / M_PI); -} - std::pair normalAndErrorFromCovariance(int numPoint, const Eigen::Vector3d& mean, const Eigen::Matrix3d& sumSquared) { const Eigen::Matrix3d covarianceMatrix = sumSquared / numPoint - mean * mean.transpose(); @@ -44,8 +33,8 @@ std::pair normalAndErrorFromCovariance(int numPoint, co unitaryNormalVector = -unitaryNormalVector; } // The first eigenvalue might become slightly negative due to numerics. - double rmsError = (solver.eigenvalues()(0) > 0.0) ? std::sqrt(solver.eigenvalues()(0)) : 0.0; - return {unitaryNormalVector, rmsError}; + double squareError = (solver.eigenvalues()(0) > 0.0) ? solver.eigenvalues()(0) : 0.0; + return {unitaryNormalVector, squareError}; } else { // If second eigenvalue is zero, the normal is not defined. return {Eigen::Vector3d::UnitZ(), 1e30}; } @@ -114,9 +103,12 @@ std::pair SlidingWindowPlaneExtractor::computeNormalAnd } } -bool SlidingWindowPlaneExtractor::isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanError) const { - return (meanError < parameters_.plane_patch_error_threshold && - angleBetweenNormalizedVectorsInDegrees(localNormal, Eigen::Vector3d::UnitZ()) < parameters_.local_plane_inclination_threshold_degrees); +bool SlidingWindowPlaneExtractor::isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanSquaredError) const { + const double thresholdSquared = parameters_.plane_patch_error_threshold * parameters_.plane_patch_error_threshold; + + // Dotproduct between normal and Eigen::Vector3d::UnitZ(); + const double normalDotProduct = localNormal.z(); + return (meanSquaredError < thresholdSquared && normalDotProduct > parameters_.local_plane_inclination_threshold); } void SlidingWindowPlaneExtractor::runSlidingWindowDetector() { @@ -133,11 +125,11 @@ void SlidingWindowPlaneExtractor::runSlidingWindowDetector() { binaryImagePatch_.at(index.x(), index.y()) = false; } else { Eigen::Vector3d n; - double mean_error; - std::tie(n, mean_error) = computeNormalAndErrorForWindow(window_data); + double meanSquaredError; + std::tie(n, meanSquaredError) = computeNormalAndErrorForWindow(window_data); surfaceNormals_[getLinearIndex(index.x(), index.y())] = n; - binaryImagePatch_.at(index.x(), index.y()) = isLocallyPlanar(n, mean_error); + binaryImagePatch_.at(index.x(), index.y()) = isLocallyPlanar(n, meanSquaredError); } } @@ -210,7 +202,7 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label, if (parameters_.include_ransac_refinement && !isGloballyPlanar(normalVector, supportVector, pointsWithNormal)) { refineLabelWithRansac(label, pointsWithNormal); } else { - if (angleBetweenNormalizedVectorsInDegrees(normalVector, Eigen::Vector3d::UnitZ()) < parameters_.plane_inclination_threshold_degrees) { + if (normalVector.z() > parameters_.plane_inclination_threshold) { const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, TerrainPlane(supportVector, terrainOrientation)); } else { @@ -253,7 +245,7 @@ void SlidingWindowPlaneExtractor::refineLabelWithRansac(int label, std::vector parameters_.plane_inclination_threshold) { const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); segmentedPlanesMap_.labelPlaneParameters.emplace_back(newLabel, TerrainPlane(supportVector, terrainOrientation)); diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/convex_plane_decomposition_ros/src/ParameterLoading.cpp index b94c8925..88218cb8 100644 --- a/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ b/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -46,8 +46,10 @@ sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters loadSlidin sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters swParams; loadParameter(nodeHandle, prefix, "kernel_size", swParams.kernel_size); loadParameter(nodeHandle, prefix, "planarity_opening_filter", swParams.planarity_opening_filter); - loadParameter(nodeHandle, prefix, "plane_inclination_threshold_degrees", swParams.plane_inclination_threshold_degrees); - loadParameter(nodeHandle, prefix, "local_plane_inclination_threshold_degrees", swParams.local_plane_inclination_threshold_degrees); + loadParameter(nodeHandle, prefix, "plane_inclination_threshold_degrees", swParams.plane_inclination_threshold); + swParams.plane_inclination_threshold = std::cos(swParams.plane_inclination_threshold * M_PI / 180.0); + loadParameter(nodeHandle, prefix, "local_plane_inclination_threshold_degrees", swParams.local_plane_inclination_threshold); + swParams.local_plane_inclination_threshold = std::cos(swParams.local_plane_inclination_threshold * M_PI / 180.0); loadParameter(nodeHandle, prefix, "plane_patch_error_threshold", swParams.plane_patch_error_threshold); loadParameter(nodeHandle, prefix, "min_number_points_per_label", swParams.min_number_points_per_label); loadParameter(nodeHandle, prefix, "connectivity", swParams.connectivity); diff --git a/convex_plane_decomposition_ros/test/test.cpp b/convex_plane_decomposition_ros/test/test.cpp index 64f3b18d..30b997be 100644 --- a/convex_plane_decomposition_ros/test/test.cpp +++ b/convex_plane_decomposition_ros/test/test.cpp @@ -54,9 +54,8 @@ void plotSlidingWindow(const sliding_window_plane_extractor::SlidingWindowPlaneE colors[0] = cv::Vec3b(0, 0, 0); // background in white for (int label = 1; label <= planeExtractor.getSegmentedPlanesMap().highestLabel; ++label) { - const auto labelIt = - std::find_if(labelsAndPlaneParameters.begin(), labelsAndPlaneParameters.end(), - [=](const std::pair& x) { return x.first == label; }); + const auto labelIt = std::find_if(labelsAndPlaneParameters.begin(), labelsAndPlaneParameters.end(), + [=](const std::pair& x) { return x.first == label; }); if (labelIt != labelsAndPlaneParameters.end()) { colors[label] = randomColor(); } else { @@ -76,18 +75,18 @@ void plotSlidingWindow(const sliding_window_plane_extractor::SlidingWindowPlaneE int main(int argc, char** argv) { std::string folder = "/home/rgrandia/git/anymal/convex_terrain_representation/convex_plane_decomposition_ros/data/"; - std::string file = "elevationMap_8_139cm.png"; double heightScale = 1.39; -// std::string file = "demo_map.png"; double heightScale = 1.25; -// std::string file = "realStairs_125cm.png"; double heightScale = 1.25; -// std::string file = "terrain.png"; double heightScale = 1.25; -// std::string file = "holes.png"; double heightScale = 1.0; -// std::string file = "slope_1m_1m_20cm.png"; double heightScale = 0.2; -// std::string file = "straightStairs_1m_1m_60cm.png"; double heightScale = 0.6; + std::string file = "elevationMap_8_139cm.png"; + double heightScale = 1.39; + // std::string file = "demo_map.png"; double heightScale = 1.25; + // std::string file = "realStairs_125cm.png"; double heightScale = 1.25; + // std::string file = "terrain.png"; double heightScale = 1.25; + // std::string file = "holes.png"; double heightScale = 1.0; + // std::string file = "slope_1m_1m_20cm.png"; double heightScale = 0.2; + // std::string file = "straightStairs_1m_1m_60cm.png"; double heightScale = 0.6; double resolution = 0.02; auto elevationMap = loadElevationMapFromFile(folder + file, resolution, heightScale); - cv::Mat image; grid_map::GridMapCvConverter::toImage(elevationMap, "elevation", CV_8UC1, 0.0, heightScale, image); cv::namedWindow("Elevation Map", cv::WindowFlags::WINDOW_NORMAL); @@ -108,7 +107,7 @@ int main(int argc, char** argv) { // ============== Sliding Window =================== // sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters swParams; swParams.kernel_size = 3; - swParams.plane_inclination_threshold_degrees = 45.0; + swParams.plane_inclination_threshold = std::cos(45.0 * M_PI / 180); swParams.plane_patch_error_threshold = 0.005; swParams.min_number_points_per_label = 10; swParams.include_ransac_refinement = true; @@ -143,9 +142,9 @@ int main(int argc, char** argv) { cv::imshow("Polygon binary image label", binaryImagePlot); // Extract - int erosion_size = 2; // single sided length of the kernel - int erosion_type = cv::MORPH_CROSS; // cv::MORPH_ELLIPSE, cv::MORPH_RECT - cv::Mat element = cv::getStructuringElement( erosion_type, cv::Size( 2*erosion_size + 1, 2*erosion_size+1 ) ); + int erosion_size = 2; // single sided length of the kernel + int erosion_type = cv::MORPH_CROSS; // cv::MORPH_ELLIPSE, cv::MORPH_RECT + cv::Mat element = cv::getStructuringElement(erosion_type, cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1)); const auto boundariesAndInsets = contour_extraction::extractBoundaryAndInset(binary_image, element); // Plot eroded image @@ -156,10 +155,10 @@ int main(int argc, char** argv) { // Plot contours int scale = 5; - cv::Size scaledSize = {scale* binary_image.size().width, scale* binary_image.size().height}; // transposed + cv::Size scaledSize = {scale * binary_image.size().width, scale * binary_image.size().height}; // transposed cv::Mat realPolygonImage(scaledSize, CV_8UC3, cv::Vec3b(0, 0, 0)); for (const auto& boundaryAndInset : boundariesAndInsets) { - drawContour(realPolygonImage, scaleShape(boundaryAndInset.boundary, scale)); + drawContour(realPolygonImage, scaleShape(boundaryAndInset.boundary, scale)); for (const auto& inset : boundaryAndInset.insets) { drawContour(realPolygonImage, scaleShape(inset, scale)); } From 1db2bc60a9af27215975cc6e0de934331d756512 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 18 Oct 2021 17:30:52 +0200 Subject: [PATCH 117/504] fix convergion in load degrees --- .../src/ParameterLoading.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/convex_plane_decomposition_ros/src/ParameterLoading.cpp index 88218cb8..021d6516 100644 --- a/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ b/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -7,10 +7,13 @@ namespace convex_plane_decomposition { template -void loadParameter(const ros::NodeHandle& nodeHandle, const std::string& prefix, const std::string& param, T& value) { +bool loadParameter(const ros::NodeHandle& nodeHandle, const std::string& prefix, const std::string& param, T& value) { if (!nodeHandle.getParam(prefix + param, value)) { ROS_ERROR_STREAM("[ConvexPlaneExtractionROS] Could not read parameter `" << param << "`. Setting parameter to default value : " << std::to_string(value)); + return false; + } else { + return true; } } @@ -46,10 +49,12 @@ sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters loadSlidin sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters swParams; loadParameter(nodeHandle, prefix, "kernel_size", swParams.kernel_size); loadParameter(nodeHandle, prefix, "planarity_opening_filter", swParams.planarity_opening_filter); - loadParameter(nodeHandle, prefix, "plane_inclination_threshold_degrees", swParams.plane_inclination_threshold); - swParams.plane_inclination_threshold = std::cos(swParams.plane_inclination_threshold * M_PI / 180.0); - loadParameter(nodeHandle, prefix, "local_plane_inclination_threshold_degrees", swParams.local_plane_inclination_threshold); - swParams.local_plane_inclination_threshold = std::cos(swParams.local_plane_inclination_threshold * M_PI / 180.0); + if (loadParameter(nodeHandle, prefix, "plane_inclination_threshold_degrees", swParams.plane_inclination_threshold)) { + swParams.plane_inclination_threshold = std::cos(swParams.plane_inclination_threshold * M_PI / 180.0); + } + if (loadParameter(nodeHandle, prefix, "local_plane_inclination_threshold_degrees", swParams.local_plane_inclination_threshold)) { + swParams.local_plane_inclination_threshold = std::cos(swParams.local_plane_inclination_threshold * M_PI / 180.0); + } loadParameter(nodeHandle, prefix, "plane_patch_error_threshold", swParams.plane_patch_error_threshold); loadParameter(nodeHandle, prefix, "min_number_points_per_label", swParams.min_number_points_per_label); loadParameter(nodeHandle, prefix, "connectivity", swParams.connectivity); From 1ca025a440b0370479fc4aba0b5261793d24623f Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 18 Oct 2021 17:39:38 +0200 Subject: [PATCH 118/504] fix funny oversegmentation. Numerical issue in cluster epsilon --- convex_plane_decomposition_ros/config/parameters.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 45df5bd0..0a01c966 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -20,7 +20,7 @@ ransac_plane_refinement: probability: 0.01 # Probability to miss the largest candidate shape. A lower probability provides a higher reliability and determinism at the cost of longer running times min_points: 25 # This minimum number of points per plane. Controls the termination of the algorithm. epsilon: 0.025 # Maximum distance to plane - cluster_epsilon: 0.02 # [m] Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon + cluster_epsilon: 0.025 # [m] Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon. Set this higher than resolution normal_threshold: 25.0 # [deg] Set maximum normal deviation between cluster surface_normal and point normal. contour_extraction: From 2f1f85c666579a637b6de4a00f5f97a822bc20b6 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 19 Oct 2021 10:31:47 +0200 Subject: [PATCH 119/504] real to pixel kernel conversion as lambda --- .../src/Postprocessing.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/convex_plane_decomposition/src/Postprocessing.cpp b/convex_plane_decomposition/src/Postprocessing.cpp index 355ef6c4..460a15a7 100644 --- a/convex_plane_decomposition/src/Postprocessing.cpp +++ b/convex_plane_decomposition/src/Postprocessing.cpp @@ -71,14 +71,20 @@ void Postprocessing::addHeightOffset(std::vector& planarRegions) c void Postprocessing::addSmoothLayer(grid_map::GridMap& gridMap, const Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const { - const int dilationSize = 2 * std::round(parameters_.smoothing_dilation_size / gridMap.getResolution()) + 1; - const int kernel = 2 * std::round(parameters_.smoothing_box_kernel_size / gridMap.getResolution()) + 1; - const int kernelGauss = 2 * std::round(parameters_.smoothing_gauss_kernel_size / gridMap.getResolution()) + 1; + auto kernelSizeInPixels = [res = gridMap.getResolution()](double realSize) { + return 2 * static_cast(std::round(realSize / res)) + 1; + }; + + const int dilationSize = kernelSizeInPixels(parameters_.smoothing_dilation_size); + const int kernel = kernelSizeInPixels(parameters_.smoothing_box_kernel_size); + const int kernelGauss = kernelSizeInPixels(parameters_.smoothing_gauss_kernel_size); // Set nonplanar regions to "NaN" - const auto lowestFloat = std::numeric_limits::lowest(); // Take lowest to not interfere with Dilation, using true NaN doesn't work with opencv dilation. + const auto lowestFloat = std::numeric_limits::lowest(); // Take lowest to not interfere with Dilation, using true NaN doesn't work + // with opencv dilation. Eigen::MatrixXf elevationWithNaN = - (planarityMask.array() == 1.0).select(elevationData, Eigen::MatrixXf::Constant(elevationData.rows(), elevationData.cols(), lowestFloat)); + (planarityMask.array() == 1.0) + .select(elevationData, Eigen::MatrixXf::Constant(elevationData.rows(), elevationData.cols(), lowestFloat)); // Convert to openCV cv::Mat elevationWithNaNImage; From 7167f265d6413847a3f32ada5298f45c2b08004d Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 19 Oct 2021 12:10:12 +0200 Subject: [PATCH 120/504] fix error in globally planarity normal threshold --- .../SlidingWindowPlaneExtractor.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index b7635c07..bac12ca2 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -198,10 +198,18 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label, const Eigen::Vector3d supportVector = sum / numPoints; const Eigen::Vector3d normalVector = normalAndErrorFromCovariance(numPoints, supportVector, sumSquared).first; - // Compute error to fitted plane. - if (parameters_.include_ransac_refinement && !isGloballyPlanar(normalVector, supportVector, pointsWithNormal)) { - refineLabelWithRansac(label, pointsWithNormal); - } else { + if (parameters_.include_ransac_refinement) { // with RANSAC + if (isGloballyPlanar(normalVector, supportVector, pointsWithNormal)) { // Already planar enough + if (normalVector.z() > parameters_.plane_inclination_threshold) { + const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); + segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, TerrainPlane(supportVector, terrainOrientation)); + } else { + setToBackground(label); + } + } else { + refineLabelWithRansac(label, pointsWithNormal); + } + } else { // no RANSAC if (normalVector.z() > parameters_.plane_inclination_threshold) { const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, TerrainPlane(supportVector, terrainOrientation)); @@ -279,7 +287,7 @@ bool SlidingWindowPlaneExtractor::isGloballyPlanar(const Eigen::Vector3d& normal normalVectorPlane.y() * pointWithNormal.second.y() + normalVectorPlane.z() * pointWithNormal.second.z(); - if (distanceError > parameters_.global_plane_fit_distance_error_threshold || dotProductNormals > dotProductThreshold) { + if (distanceError > parameters_.global_plane_fit_distance_error_threshold || dotProductNormals < dotProductThreshold) { return false; } } From e9e74a93593f9a28249a64a196595ae85175542e Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 26 Oct 2021 12:12:33 +0200 Subject: [PATCH 121/504] add some maps --- .../data/elevationMap_0_107cm.png | Bin 0 -> 1316 bytes .../data/elevationMap_0_148cm.png | Bin 0 -> 797 bytes .../data/elevationMap_0_44cm.png | Bin 0 -> 1175 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 convex_plane_decomposition_ros/data/elevationMap_0_107cm.png create mode 100644 convex_plane_decomposition_ros/data/elevationMap_0_148cm.png create mode 100644 convex_plane_decomposition_ros/data/elevationMap_0_44cm.png diff --git a/convex_plane_decomposition_ros/data/elevationMap_0_107cm.png b/convex_plane_decomposition_ros/data/elevationMap_0_107cm.png new file mode 100644 index 0000000000000000000000000000000000000000..8426c5fa39263a68ca9d06e3533ca0d595b2834b GIT binary patch literal 1316 zcmXYxYfuwc6vu-Bvx$I<0WlHih7I5lMxKMpqmZ!V#Y14?1D!HvTzO1w>ja7eh(g@N zM0sq2K@ycVvb91fWN>V$R*@~mL>OV>RHa3fX&lOwT1qL85w#oJ59gf!?|;ud_k6ng zyj+P7i_4Ury=*4$Qn@> zF7hXUh1+ecbLY&%SBU4^b%Obih#lKY^Z0x|2w9P{sn_3M`nlwf_*W&3W22aP#=w9! zriav}(5h$)G?#~+j{7o?$NMJ{8RTW}yeBQG^~V@=cjah);Q+8+<1^8c-*2kV<7_zC z7twJ{K%Y)$ZGERQc7l|G_w27e9(#U7$k+~-XtK1D=3QKXT~BJ~fFaxB*MWgm3&i)= zQ^GGy|D|~WH@VWgNXthJ)|;_|IK7kAQBP(+a&4Pz3$hb5y2jjXHyt~y zf*8VWqv)VrUV3MZ*W3>>rhL3ru`z3Eu`j_CDZ{h+Hd~_8WLK`nNLi;{@m#Z%-QZu` z2PIo)0)C24JIt3j5y)x~IQ^1}VylLw#ZFAdSEw?p$tgis36!M*EindhPkAer=Ja3R zHFE0BBFApbUI%dGZBqDgm15_umDh~swCS(zy_d4uHgGw0)o=CH#K5z5n7S(-#`FoQ z;M7|yPnS=w8wO)fyso{oIyUg&NTx42^zQ5of8a>;Ot(YW*5-Z)?g;E_DSt$;8hKlA z@y*b9QYX*)XgtF zm7IEWx|@l?Y;P%?s!X{1ck`+FrHj)gPM2|{ck1Mz7Bl6^;9zS(JL88(SyN+}oI4A! zYeSNXR3cEF;AD5z&nP8#o?~^MWdxk<+Ldg)a0$er#tKZocHnt$TFKyvR}r~@6c;Cv z$jN^^)()@C52U@pudXab_wM2WLT=%?*lg@e<;c9{BH*;|^=40(JrR7;uZJ4vH1sO& z(*3PBJ;{7ryd?Vdq3uY~LmmQ1gxm?eb#=|Jrgy>+9^_SqMhDeCsPp(P2+z{aYlF+& z{gtFqp_F|?Ft0<6-9Os+$p*@glEPc9lBwO6m<>+*0o(?85KMb}f^suqFxkR(gyxj0 z6Z-rfxx@rB2Nx%jmIe~(iC|cnR5w40iR2o>6R4HXDl@BUFF;G!s_4w5N{mC+Oksi?@^}p#` BHv#|v literal 0 HcmV?d00001 diff --git a/convex_plane_decomposition_ros/data/elevationMap_0_148cm.png b/convex_plane_decomposition_ros/data/elevationMap_0_148cm.png new file mode 100644 index 0000000000000000000000000000000000000000..caf91d540f74e3cea59a685c186b0b9f3b504836 GIT binary patch literal 797 zcmeAS@N?(olHy`uVBq!ia0vp^DIm-NBp5vMURqY%Zi|6rr`yz!5}{tLl`mAJLW3@Pnygx~XmUn~r>pwK6_dLB76qz`&UK+s zVah3mt3ZRH6wv%k5uo`W->(<(JX$Z`)Y>27c~rVHdY#0RC69W~=(+}dbbB^UvU&c5 zE_0#nXE+@FwC-JO$o7S z)OjOuB67mSCiOm*37Z9O6sk2VD6{&@oZKp#Zp2{}^x??F9w#TD@L~l;*7^^ODp3q> z4GM35I6AR8I&sOJd}}$$0mc$Sh|Ns!gh)aemFmI=n?!6T-7Z!N1~Dd7voWV=MNDX7 zFFN1Qc!uTrk_U};c6)&XFQL}t_)w6A^>5e0T~`3k!Me04b(-;Q~uc%`1&lnF`y1rRdW@-n8}+Hyu9qB*_fS~ z_`#fOD(MHOtnob8q!~Gp2Tt@faYjxA5tDg9L{AepgqRq^BECs&Cx;t^kekWnwu$j( m11KR%PvAYlmcoq2{m<;>J~y@abg%^|-Fv$FxvXb?ZW3+ z?~eOwJWH;vx>Kc}c{R;aGiWs@6AQ-#Q=5Zs@8&DEAO1bL<_VAJJYjvFW&EP&d41%y z;v~St47;E`CI+<&ECiA+%3y@y(r{Ulh7h|9PM{D*(9|E%G`0zjStK80US?Fv);8UHh zfP1Q7w&s-Q|2|B99(35dP-vOztc5{-r;O|W9B$N)>#$CYS|oWYvhvkz<#-$M?;umA zbYH41e$t)(NXN(9#JMtLR(@a2#}FHcN#dzLpE+7~Pu8E;#SYS{m8vOT|5=?s=-t`< z|3B-`>*zMny~s0Vnaz*0^Xvcj$JhOuJ~{s1+c&HA6^7%lv#5Xae$7z^qM{zppl~mva>cx`KJB=4|%;yFRx+{Tv@# zvp%BTWN~+cLNBdP3d3a?0kj6YoaC6z{wtbHmmH<|pyl%)8lFg59xV z%CeXozBdr>IxjVOnpB+dT?1^zDPag_7sz{0JBv12Zm1TC1^TJ&lMC3qEyusJE^wmJ)IW0jlrS^U2M4|c#RSfi1e$xWL}8uA z`Cg#8Gy0B*KJ_h(jS0Ocbp2@PQ{BSQI}7$GuIrMXVtypFu=~@l9cp>OaiZ6cY(5l}LB$K5Yo{~2GMOe-mV Sm~{eF;&{6HxvX Date: Tue, 26 Oct 2021 12:16:12 +0200 Subject: [PATCH 122/504] upgrade CGAL version. Improved RANSAC --- cgal5_catkin/CMakeLists.txt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/cgal5_catkin/CMakeLists.txt b/cgal5_catkin/CMakeLists.txt index 445a42f5..75aa205a 100644 --- a/cgal5_catkin/CMakeLists.txt +++ b/cgal5_catkin/CMakeLists.txt @@ -1,22 +1,20 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.14) project(cgal5_catkin) find_package(catkin REQUIRED) include(ExternalProject) -set(VERSION 5.0.2) +set(VERSION 5.3) file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/include) -set(CGAL_VERSION 5.0.2) +set(CGAL_VERSION 5.3) ExternalProject_Add(cgal - URL https://github.com/CGAL/cgal/archive/releases/CGAL-${CGAL_VERSION}.tar.gz + URL https://github.com/CGAL/cgal/archive/refs/tags/v${CGAL_VERSION}.tar.gz UPDATE_COMMAND "" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CATKIN_DEVEL_PREFIX} - -DWITH_CGAL_Qt5:BOOL=OFF - -DWITH_CGAL_ImageIO:BOOL=OFF -DCMAKE_BUILD_TYPE:STRING=Release BUILD_COMMAND $(MAKE) INSTALL_COMMAND $(MAKE) install From 55fdd481e3bcc0ebe11b7d889d0536fee1749218 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 26 Oct 2021 12:17:40 +0200 Subject: [PATCH 123/504] add plotting of surface normals --- .../SlidingWindowPlaneExtractor.h | 4 ++ .../SlidingWindowPlaneExtractor.cpp | 40 +++++++++++++++---- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h index 374cd1a7..77b20537 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h @@ -24,9 +24,13 @@ class SlidingWindowPlaneExtractor { const cv::Mat& getBinaryLabeledImage() const { return binaryImagePatch_; } + /** Can be run after extraction for debugging purpose */ + void addSurfaceNormalToMap(grid_map::GridMap& map, const std::string& layerPrefix) const; + private: bool isGloballyPlanar(const Eigen::Vector3d& normalVectorPlane, const Eigen::Vector3d& supportVectorPlane, const std::vector& pointsWithNormal) const; + bool isWithinInclinationLimit(const Eigen::Vector3d& normalVectorPlane) const; std::pair computeNormalAndErrorForWindow(const Eigen::MatrixXf& windowData) const; bool isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanSquaredError) const; diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index bac12ca2..4d641bca 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -112,7 +112,7 @@ bool SlidingWindowPlaneExtractor::isLocallyPlanar(const Eigen::Vector3d& localNo } void SlidingWindowPlaneExtractor::runSlidingWindowDetector() { - grid_map::SlidingWindowIterator window_iterator(*map_, elevationLayer_, grid_map::SlidingWindowIterator::EdgeHandling::INSIDE, + grid_map::SlidingWindowIterator window_iterator(*map_, elevationLayer_, grid_map::SlidingWindowIterator::EdgeHandling::EMPTY, parameters_.kernel_size); const int kernelMiddle = (parameters_.kernel_size - 1) / 2; @@ -136,7 +136,7 @@ void SlidingWindowPlaneExtractor::runSlidingWindowDetector() { // opening filter if (parameters_.planarity_opening_filter > 0) { const int openingKernelSize = 2 * parameters_.planarity_opening_filter + 1; - const int openingKernelType = cv::MORPH_RECT; + const int openingKernelType = cv::MORPH_CROSS; const auto kernel_ = cv::getStructuringElement(openingKernelType, cv::Size(openingKernelSize, openingKernelSize)); cv::morphologyEx(binaryImagePatch_, binaryImagePatch_, cv::MORPH_OPEN, kernel_, cv::Point(-1, -1), 1, cv::BORDER_REPLICATE); } @@ -198,9 +198,9 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label, const Eigen::Vector3d supportVector = sum / numPoints; const Eigen::Vector3d normalVector = normalAndErrorFromCovariance(numPoints, supportVector, sumSquared).first; - if (parameters_.include_ransac_refinement) { // with RANSAC - if (isGloballyPlanar(normalVector, supportVector, pointsWithNormal)) { // Already planar enough - if (normalVector.z() > parameters_.plane_inclination_threshold) { + if (parameters_.include_ransac_refinement) { // with RANSAC + if (isGloballyPlanar(normalVector, supportVector, pointsWithNormal)) { // Already planar enough + if (isWithinInclinationLimit(normalVector)) { const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, TerrainPlane(supportVector, terrainOrientation)); } else { @@ -209,8 +209,8 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label, } else { refineLabelWithRansac(label, pointsWithNormal); } - } else { // no RANSAC - if (normalVector.z() > parameters_.plane_inclination_threshold) { + } else { // no RANSAC + if (isWithinInclinationLimit(normalVector)) { const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, TerrainPlane(supportVector, terrainOrientation)); } else { @@ -253,7 +253,7 @@ void SlidingWindowPlaneExtractor::refineLabelWithRansac(int label, std::vector parameters_.plane_inclination_threshold) { + if (isWithinInclinationLimit(normalVector)) { const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); segmentedPlanesMap_.labelPlaneParameters.emplace_back(newLabel, TerrainPlane(supportVector, terrainOrientation)); @@ -270,6 +270,26 @@ void SlidingWindowPlaneExtractor::refineLabelWithRansac(int label, std::vector& pointsWithNormal) const { // Part of the plane projection that is independent of the point @@ -295,6 +315,10 @@ bool SlidingWindowPlaneExtractor::isGloballyPlanar(const Eigen::Vector3d& normal return true; } +bool SlidingWindowPlaneExtractor::isWithinInclinationLimit(const Eigen::Vector3d& normalVectorPlane) const { + return normalVectorPlane.z() > parameters_.plane_inclination_threshold; +} + void SlidingWindowPlaneExtractor::setToBackground(int label) { segmentedPlanesMap_.labeledImage.setTo(0, segmentedPlanesMap_.labeledImage == label); } From 06d85dd050c843be8151cf79006c4ca26f09bc4a Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 26 Oct 2021 12:18:32 +0200 Subject: [PATCH 124/504] set up node that republishes the map with noise --- convex_plane_decomposition_ros/CMakeLists.txt | 7 ++ .../config/demo_node.yaml | 2 +- .../launch/demo.launch | 21 +++- .../rviz/config_demo.rviz | 50 ++++---- .../src/noiseNode.cpp | 107 ++++++++++++++++++ 5 files changed, 158 insertions(+), 29 deletions(-) create mode 100644 convex_plane_decomposition_ros/src/noiseNode.cpp diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index 1c34b62f..a30f0a7d 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -72,6 +72,13 @@ target_link_libraries(${PROJECT_NAME}_node ${PROJECT_NAME} ) +add_executable(${PROJECT_NAME}_add_noise + src/noiseNode.cpp +) +target_link_libraries(${PROJECT_NAME}_add_noise + ${catkin_LIBRARIES} +) + add_executable(${PROJECT_NAME}_save_elevationmap src/SaveElevationMapAsImageNode.cpp ) diff --git a/convex_plane_decomposition_ros/config/demo_node.yaml b/convex_plane_decomposition_ros/config/demo_node.yaml index 22ceb32a..214d2a57 100644 --- a/convex_plane_decomposition_ros/config/demo_node.yaml +++ b/convex_plane_decomposition_ros/config/demo_node.yaml @@ -1,4 +1,4 @@ -elevation_topic: '/image_to_gridmap_demo/grid_map' +elevation_topic: '/elevation_mapping/elevation_map_raw' height_layer: 'elevation' target_frame_id: 'odom' submap: diff --git a/convex_plane_decomposition_ros/launch/demo.launch b/convex_plane_decomposition_ros/launch/demo.launch index 6f37b3e5..09f41c17 100644 --- a/convex_plane_decomposition_ros/launch/demo.launch +++ b/convex_plane_decomposition_ros/launch/demo.launch @@ -1,7 +1,7 @@ - - + + @@ -14,11 +14,24 @@ - + + + + + + + + + + + + + - + diff --git a/convex_plane_decomposition_ros/rviz/config_demo.rviz b/convex_plane_decomposition_ros/rviz/config_demo.rviz index d15f170f..8ed503d8 100644 --- a/convex_plane_decomposition_ros/rviz/config_demo.rviz +++ b/convex_plane_decomposition_ros/rviz/config_demo.rviz @@ -5,8 +5,10 @@ Panels: Property Tree Widget: Expanded: - /Global Options1 + - /GridMap1 + - /FilteredMap1 Splitter Ratio: 0.4083484709262848 - Tree Height: 540 + Tree Height: 824 - Class: rviz/Selection Name: Selection - Class: rviz/Tool Properties @@ -36,12 +38,12 @@ Visualization Manager: - Alpha: 1 Class: jsk_rviz_plugin/PolygonArray Color: 25; 255; 0 - Enabled: true + Enabled: false Name: Boundaries Queue Size: 10 Topic: /convex_plane_decomposition_ros/boundaries Unreliable: false - Value: true + Value: false coloring: Auto enable lighting: true normal length: 0.10000000149011612 @@ -67,7 +69,7 @@ Visualization Manager: Color: 200; 200; 200 Color Layer: elevation Color Transformer: GridMapLayer - Enabled: true + Enabled: false Height Layer: elevation Height Transformer: GridMapLayer History Length: 1 @@ -78,19 +80,19 @@ Visualization Manager: Min Intensity: 0 Name: GridMap Show Grid Lines: true - Topic: /elevation_mapping/elevation_map_recordable + Topic: /elevation_mapping/elevation_map_raw Unreliable: false Use Rainbow: true - Value: true - - Alpha: 0.10000000149011612 + Value: false + - Alpha: 0.6000000238418579 Autocompute Intensity Bounds: true Class: grid_map_rviz_plugin/GridMap Color: 200; 200; 200 - Color Layer: segmentation + Color Layer: plane_classification Color Transformer: IntensityLayer - Enabled: false - Height Layer: elevation - Height Transformer: GridMapLayer + Enabled: true + Height Layer: elevation_before_postprocess + Height Transformer: "" History Length: 1 Invert Rainbow: false Max Color: 255; 255; 255 @@ -101,8 +103,8 @@ Visualization Manager: Show Grid Lines: true Topic: /convex_plane_decomposition_ros/filtered_map Unreliable: false - Use Rainbow: true - Value: false + Use Rainbow: false + Value: true - Class: rviz/MarkerArray Enabled: true Marker Topic: /segmented_planes_terrain_model_demo_node/convex_terrain @@ -155,7 +157,7 @@ Visualization Manager: Views: Current: Class: rviz/Orbit - Distance: 7.077206611633301 + Distance: 12.107149124145508 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 @@ -163,25 +165,25 @@ Visualization Manager: Value: false Field of View: 0.7853981852531433 Focal Point: - X: 1.0492274761199951 - Y: -0.5030490159988403 - Z: -2.4208056926727295 + X: -3.3109402656555176 + Y: -1.6383998394012451 + Z: -3.4406676292419434 Focal Shape Fixed Size: true Focal Shape Size: 0.05000000074505806 Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.6197975277900696 + Pitch: 0.5047986507415771 Target Frame: - Yaw: 2.844961643218994 + Yaw: 1.6149601936340332 Saved: ~ Window Geometry: Displays: collapsed: false - Height: 759 + Height: 1043 Hide Left Dock: false Hide Right Dock: true - QMainWindow State: 000000ff00000000fd00000004000000000000022900000259fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000259000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f0000040efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000280000040e000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000056d0000003efc0100000002fb0000000800540069006d006501000000000000056d000002eb00fffffffb0000000800540069006d006501000000000000045000000000000000000000033e0000025900000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd00000004000000000000022900000375fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000375000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f0000040efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000280000040e000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007380000003efc0100000002fb0000000800540069006d0065010000000000000738000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000005090000037500000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -190,6 +192,6 @@ Window Geometry: collapsed: false Views: collapsed: true - Width: 1389 - X: 2208 - Y: 195 + Width: 1848 + X: 72 + Y: 0 diff --git a/convex_plane_decomposition_ros/src/noiseNode.cpp b/convex_plane_decomposition_ros/src/noiseNode.cpp new file mode 100644 index 00000000..c65f03de --- /dev/null +++ b/convex_plane_decomposition_ros/src/noiseNode.cpp @@ -0,0 +1,107 @@ +// +// Created by rgrandia on 25.10.21. +// + +#include + +#include +#include + +#include +#include + +double noiseUniform; +double noiseGauss; +double outlierPercentage; +bool blur; +double frequency; +std::string elevationMapTopicIn; +std::string elevationMapTopicOut; +std::string elevationLayer; +ros::Publisher publisher; +grid_map::GridMap::Matrix noiseLayer; + +void createNoise(size_t row, size_t col) { + // Box-Muller Transform + grid_map::GridMap::Matrix u1 = 0.5 * grid_map::GridMap::Matrix::Random(row, col).array() + 0.5; + grid_map::GridMap::Matrix u2 = 0.5 * grid_map::GridMap::Matrix::Random(row, col).array() + 0.5; + grid_map::GridMap::Matrix gauss01 = + u1.binaryExpr(u2, [&](float v1, float v2) { return std::sqrt(-2.0f * log(v1)) * cos(2.0f * M_PIf32 * v2); }); + + noiseLayer = noiseUniform * grid_map::GridMap::Matrix::Random(row, col) + noiseGauss * gauss01; +} + +void callback(const grid_map_msgs::GridMap::ConstPtr& message) { + grid_map::GridMap messageMap; + grid_map::GridMapRosConverter::fromMessage(*message, messageMap); + + if (blur) { + // Copy! + auto originalMap = messageMap.get(elevationLayer); + + // Blur (remove nan -> filter -> put back nan + grid_map::inpainting::minValues(messageMap, elevationLayer, "i"); + grid_map::smoothing::boxBlur(messageMap, "i", elevationLayer, 3, 1); + messageMap.get(elevationLayer) = (originalMap.array().isFinite()).select(messageMap.get(elevationLayer), originalMap); + } + + auto& elevation = messageMap.get(elevationLayer); + if (noiseLayer.size() != elevation.size()) { + createNoise(elevation.rows(), elevation.cols()); + } + + elevation += noiseLayer; + + grid_map_msgs::GridMap messageMapOut; + grid_map::GridMapRosConverter::toMessage(messageMap, messageMapOut); + publisher.publish(messageMapOut); +} + +int main(int argc, char** argv) { + ros::init(argc, argv, "noise_node"); + ros::NodeHandle nodeHandle("~"); + + if (!nodeHandle.getParam("frequency", frequency)) { + ROS_ERROR("[ConvexPlaneExtractionROS::NoiseNode] Could not read parameter `frequency`."); + return 1; + } + if (!nodeHandle.getParam("noiseGauss", noiseGauss)) { + ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `noiseGauss`."); + return 1; + } + if (!nodeHandle.getParam("noiseUniform", noiseUniform)) { + ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `noiseUniform`."); + return 1; + } + if (!nodeHandle.getParam("blur", blur)) { + ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `blur`."); + return 1; + } + if (!nodeHandle.getParam("outlier_percentage", outlierPercentage)) { + ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `outlier_percentage`."); + return 1; + } + if (!nodeHandle.getParam("elevation_topic_in", elevationMapTopicIn)) { + ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `elevation_topic_in`."); + return 1; + } + if (!nodeHandle.getParam("elevation_topic_out", elevationMapTopicOut)) { + ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `elevation_topic_out`."); + return 1; + } + if (!nodeHandle.getParam("height_layer", elevationLayer)) { + ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `height_layer`."); + return 1; + } + + publisher = nodeHandle.advertise(elevationMapTopicOut, 1); + auto elevationMapSubscriber_ = nodeHandle.subscribe(elevationMapTopicIn, 1, callback); + + ros::Rate rate(frequency); + while (ros::ok()) { + ros::spinOnce(); + rate.sleep(); + } + + return 0; +} \ No newline at end of file From 81ff51ce1170781a6d7f8bb1df8a501fd54599f6 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 26 Oct 2021 12:58:45 +0200 Subject: [PATCH 125/504] store map rows for linear dimension --- .../SlidingWindowPlaneExtractor.h | 3 ++- .../SlidingWindowPlaneExtractor.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h index 77b20537..f86fdc79 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h @@ -35,7 +35,7 @@ class SlidingWindowPlaneExtractor { std::pair computeNormalAndErrorForWindow(const Eigen::MatrixXf& windowData) const; bool isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanSquaredError) const; - int getLinearIndex(int row, int col) const { return row + col * map_->getSize()[0]; }; + int getLinearIndex(int row, int col) const { return row + col * mapRows_; }; void computePlaneParametersForLabel(int label, std::vector& pointsWithNormal); void refineLabelWithRansac(int label, std::vector& pointsWithNormal); @@ -53,6 +53,7 @@ class SlidingWindowPlaneExtractor { const grid_map::GridMap* map_; std::string elevationLayer_; + int mapRows_; std::vector surfaceNormals_; diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index 4d641bca..4b58285a 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -50,6 +50,7 @@ void SlidingWindowPlaneExtractor::runExtraction(const grid_map::GridMap& map, co // Extract basic map information map_ = ↦ elevationLayer_ = layer_height; + mapRows_ = map_->getSize()[0]; segmentedPlanesMap_.resolution = map_->getResolution(); map_->getPosition(Eigen::Vector2i(0, 0), segmentedPlanesMap_.mapOrigin); From 9751d4d8ce59de88e37af7c760ed02ffb3a8c317 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 26 Oct 2021 13:01:33 +0200 Subject: [PATCH 126/504] use inpainting between planar regions instead of NaN tricks --- .../src/Postprocessing.cpp | 75 +++++++++++-------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/convex_plane_decomposition/src/Postprocessing.cpp b/convex_plane_decomposition/src/Postprocessing.cpp index 460a15a7..4aacec43 100644 --- a/convex_plane_decomposition/src/Postprocessing.cpp +++ b/convex_plane_decomposition/src/Postprocessing.cpp @@ -5,6 +5,7 @@ #include #include +#include namespace convex_plane_decomposition { @@ -75,32 +76,59 @@ void Postprocessing::addSmoothLayer(grid_map::GridMap& gridMap, const Eigen::Mat return 2 * static_cast(std::round(realSize / res)) + 1; }; + // Helper to convert to Eigen + auto toEigen = [](const cv::Mat& image) { + Eigen::MatrixXf data; + cv::cv2eigen(image, data); + return data; + }; + + // Helper to openCV + auto toCv = [](const Eigen::MatrixXf& data) { + cv::Mat image; + cv::eigen2cv(data, image); + return image; + }; + const int dilationSize = kernelSizeInPixels(parameters_.smoothing_dilation_size); const int kernel = kernelSizeInPixels(parameters_.smoothing_box_kernel_size); const int kernelGauss = kernelSizeInPixels(parameters_.smoothing_gauss_kernel_size); - // Set nonplanar regions to "NaN" - const auto lowestFloat = std::numeric_limits::lowest(); // Take lowest to not interfere with Dilation, using true NaN doesn't work - // with opencv dilation. + + // Set non planar regions to NaN Eigen::MatrixXf elevationWithNaN = (planarityMask.array() == 1.0) - .select(elevationData, Eigen::MatrixXf::Constant(elevationData.rows(), elevationData.cols(), lowestFloat)); + .select(elevationData, Eigen::MatrixXf::Constant(elevationData.rows(), elevationData.cols(), NAN)); + gridMap.add("elevationWithNaN", elevationWithNaN); - // Convert to openCV - cv::Mat elevationWithNaNImage; - cv::eigen2cv(elevationWithNaN, elevationWithNaNImage); // creates CV_32F image + // Inpainting + grid_map::inpainting::minValues(gridMap, "elevationWithNaN", "elevationWithNaN_i"); - // Dilate + // Closing + auto elevationWithNaNCv = toCv(gridMap.get("elevationWithNaN_i")); const int dilationType = cv::MORPH_ELLIPSE; // ellipse inscribed in the square of size dilationSize const auto dilationKernel_ = cv::getStructuringElement(dilationType, cv::Size(dilationSize, dilationSize)); - cv::dilate(elevationWithNaNImage, elevationWithNaNImage, dilationKernel_, cv::Point(-1, -1), 1, cv::BORDER_REPLICATE); - - // Take complement image where elevation data was set to NaN - cv::Mat indicatorImage = cv::Mat::ones(elevationWithNaNImage.rows, elevationWithNaNImage.cols, CV_32F); - indicatorImage.setTo(0.0, elevationWithNaNImage == lowestFloat); + cv::morphologyEx(elevationWithNaNCv, elevationWithNaNCv, cv::MORPH_CLOSE, dilationKernel_, cv::Point(-1, -1), 1, cv::BORDER_REPLICATE); + + gridMap.add("elevationWithNaNClosed", toEigen(elevationWithNaNCv)); + + // Dilation with a slope of 45 deg + int halfDilationSize = (dilationSize - 1) / 2; + float slope = gridMap.getResolution(); // dh dpixel + Eigen::MatrixXf offsets(dilationSize, dilationSize); + for (int i = 0; i < dilationSize; ++i) { + for (int j = 0; j < dilationSize; ++j) { + const auto dx = (i - halfDilationSize); + const auto dy = (j - halfDilationSize); + offsets(i, j) = slope * std::sqrt(dx * dx + dy * dy); + } + } + grid_map::processing::applyKernelFunction( + gridMap, "elevationWithNaNClosed", "elevationWithNaNClosedDilated", dilationSize, + [&](const Eigen::Ref& data) -> float { return (data - offsets).maxCoeffOfFinites(); }); - // Set NaN's to 0.0 - elevationWithNaNImage.setTo(0.0, elevationWithNaNImage == lowestFloat); + // Convert to openCV + auto elevationWithNaNImage = toCv(gridMap.get("elevationWithNaNClosedDilated")); // Filter definition auto smoothingFilter = [kernel, kernelGauss](const cv::Mat& imageIn) { @@ -109,23 +137,10 @@ void Postprocessing::addSmoothLayer(grid_map::GridMap& gridMap, const Eigen::Mat cv::GaussianBlur(imageOut, imageOut, {kernelGauss, kernelGauss}, 0, 0, cv::BorderTypes::BORDER_REPLICATE); return imageOut; }; - - // Helper to convert to Eigen - auto toEigen = [](const cv::Mat& image) { - Eigen::MatrixXf data; - cv::cv2eigen(image, data); - return data; - }; - - // Filter trick for data with NaN from: https://stackoverflow.com/questions/18697532/gaussian-filtering-a-image-with-nan-in-python - auto planarOnly = smoothingFilter(elevationWithNaNImage); - auto complement = smoothingFilter(indicatorImage); - complement += 1e-6; // Prevent division by zero - cv::Mat result; - cv::divide(planarOnly, complement, result); + auto smooth_planar = smoothingFilter(elevationWithNaNImage); // Add layer to map. - gridMap.add("smooth_planar", toEigen(result)); + gridMap.add("smooth_planar", toEigen(smooth_planar)); } } // namespace convex_plane_decomposition From 6c0c6ef4c58e156a67a9601f3b4906c24a0e07c0 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 26 Oct 2021 13:01:50 +0200 Subject: [PATCH 127/504] rotate before extacting submap. Add surface normals for debugging --- .../ConvexPlaneDecompositionRos.h | 2 + .../src/ConvexPlaneDecompositionRos.cpp | 48 +++++++++++++------ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h index d15083a7..d0578334 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h @@ -41,6 +41,8 @@ class ConvexPlaneExtractionROS { Eigen::Isometry3d getTransformToTargetFrame(const std::string& sourceFrame, const ros::Time& time); + ros::Time getMessageTime(const grid_map_msgs::GridMap& message) const; + // Parameters std::string elevationMapTopic_; std::string elevationLayer_; diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 26e0cd8f..87c1118d 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -87,30 +87,33 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { grid_map::GridMap messageMap; std::vector layers{elevationLayer_}; grid_map::GridMapRosConverter::fromMessage(message, messageMap, layers, false, false); - bool success; - grid_map::GridMap elevationMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(subMapLength_, subMapWidth_), success); - success = success && containsFiniteValue(elevationMap.get(elevationLayer_)); // Check if there are values - ROS_INFO("...done."); - - // Exit early if map is not valid. - if (!success) { - ROS_WARN("[ConvexPlaneExtractionROS] Could not extract submap"); + if (!containsFiniteValue(messageMap.get(elevationLayer_))) { + ROS_WARN("[ConvexPlaneExtractionROS] map does not contain any values"); return; } // Transform map if necessary - if (targetFrameId_ != elevationMap.getFrameId()) { + if (targetFrameId_ != messageMap.getFrameId()) { std::string errorMsg; - ros::Time timeStamp(messageMap.getTimestamp()); - if (tfBuffer_.canTransform(targetFrameId_, elevationMap.getFrameId(), timeStamp, &errorMsg)) { - elevationMap = - elevationMap.getTransformedMap(getTransformToTargetFrame(elevationMap.getFrameId(), timeStamp), elevationLayer_, targetFrameId_); + ros::Time timeStamp = getMessageTime(message); + if (tfBuffer_.canTransform(targetFrameId_, messageMap.getFrameId(), timeStamp, &errorMsg)) { + messageMap = + messageMap.getTransformedMap(getTransformToTargetFrame(messageMap.getFrameId(), timeStamp), elevationLayer_, targetFrameId_); } else { ROS_ERROR_STREAM("[ConvexPlaneExtractionROS] " << errorMsg); return; } } + // Extract submap + bool success; + grid_map::GridMap elevationMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(subMapLength_, subMapWidth_), success); + if (!success) { + ROS_WARN("[ConvexPlaneExtractionROS] Could not extract submap"); + return; + } + ROS_INFO("...done."); + auto t0 = std::chrono::high_resolution_clock::now(); preprocessing_->preprocess(elevationMap, elevationLayer_); auto t1 = std::chrono::high_resolution_clock::now(); @@ -126,6 +129,8 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { auto t3 = std::chrono::high_resolution_clock::now(); ROS_INFO_STREAM("Contour extraction took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]"); + + // Add grid map to the terrain planarTerrain.gridMap = std::move(elevationMap); @@ -144,9 +149,15 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { regionPublisher_.publish(toMessage(planarTerrain)); } - // Visualize in Rviz. + // --- Visualize in Rviz --- Not published to the controller + + // Add surface normals + slidingWindowPlaneExtractor_->addSurfaceNormalToMap(planarTerrain.gridMap, "normal"); + + // Add surface normals planarTerrain.gridMap.add("segmentation"); cv::cv2eigen(slidingWindowPlaneExtractor_->getSegmentedPlanesMap().labeledImage, planarTerrain.gridMap.get("segmentation")); + grid_map_msgs::GridMap outputMessage; grid_map::GridMapRosConverter::toMessage(planarTerrain.gridMap, outputMessage); filteredmapPublisher_.publish(outputMessage); @@ -178,4 +189,13 @@ Eigen::Isometry3d ConvexPlaneExtractionROS::getTransformToTargetFrame(const std: return transformation; } +ros::Time ConvexPlaneExtractionROS::getMessageTime(const grid_map_msgs::GridMap& message) const { + try { + return ros::Time(message.info.header.stamp.toNSec()); + } catch (std::runtime_error& ex) { + ROS_WARN("[ConvexPlaneExtractionROS::getMessageTime] %s", ex.what()); + return ros::Time::now(); + } +} + } // namespace convex_plane_decomposition From 5d915ebfa3c00db4aeab14cf95695a3c5b3312ab Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 26 Oct 2021 13:02:10 +0200 Subject: [PATCH 128/504] tune parameters to work with 4cm resolution --- .../config/parameters.yaml | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 0a01c966..6ac7df7c 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -1,16 +1,16 @@ preprocessing: - resolution: 0.02 # Resampling resolution, set negative to skip, requires inpainting to be used + resolution: 0.04 # Resampling resolution, set negative to skip, requires inpainting to be used kernelSize: 3 # Kernel size of the median filter, either 3 or 5 - numberOfRepeats: 1 # Number of times to apply the same filter + numberOfRepeats: 2 # Number of times to apply the same filter increasing: False # Increase the kernel size each iteration. sliding_window_plane_extractor: kernel_size: 3 # Size of the sliding window patch used for normal vector calculation and planarity detection. Should be an odd number and at least 3. - planarity_opening_filter: 2 # [#] Apply opening filter (erosion -> dilation) to planarity detection by this amount of pixels - plane_inclination_threshold_degrees: 40.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch - local_plane_inclination_threshold_degrees: 55.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a cell - plane_patch_error_threshold: 0.005 # [m] The allowed root-mean-squared deviation from the plane fitted to the sliding window. - min_number_points_per_label: 10 # [#] Labels with less points assigned to them are discarded + planarity_opening_filter: 1 # [#] Apply opening filter (erosion -> dilation) to planarity detection by this amount of pixels + plane_inclination_threshold_degrees: 30.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch + local_plane_inclination_threshold_degrees: 35.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a cell + plane_patch_error_threshold: 0.02 # [m] The allowed root-mean-squared deviation from the plane fitted to the sliding window. + min_number_points_per_label: 4 # [#] Labels with less points assigned to them are discarded connectivity: 4 # Label kernel connectivity. 4 or 8 (cross or box) include_ransac_refinement: true # Enable RANSAC refinement if the plane is not globally fitting to the assigned points. global_plane_fit_distance_error_threshold: 0.025 # [m] Allowed maximum distance from a point to the plane. If any point violates this, RANSAC is triggered @@ -18,9 +18,9 @@ sliding_window_plane_extractor: ransac_plane_refinement: probability: 0.01 # Probability to miss the largest candidate shape. A lower probability provides a higher reliability and determinism at the cost of longer running times - min_points: 25 # This minimum number of points per plane. Controls the termination of the algorithm. + min_points: 4 # This minimum number of points per plane. Controls the termination of the algorithm. epsilon: 0.025 # Maximum distance to plane - cluster_epsilon: 0.025 # [m] Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon. Set this higher than resolution + cluster_epsilon: 0.08 # [m] Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon. Set this higher than resolution normal_threshold: 25.0 # [deg] Set maximum normal deviation between cluster surface_normal and point normal. contour_extraction: @@ -29,7 +29,7 @@ contour_extraction: postprocessing: extracted_planes_height_offset: 0.0 # Added offset in Z direction for the full map to compensate for the location of the foot frame w.r.t. the contact point nonplanar_height_offset: 0.02 # Added offset in Z direction for non-planar cells of the map. (Additional to extracted_planes_height_offset) - nonplanar_horizontal_offset: 2 # Added offset in XY direction for non-planar cells of the map. In number of pixels. + nonplanar_horizontal_offset: 1 # Added offset in XY direction for non-planar cells of the map. In number of pixels. smoothing_dilation_size: 0.2 # Half the width of the dilation used before the smooth layer [m] - smoothing_box_kernel_size: 0.3 # Half the width of the box kernel used for the smooth layer [m] - smoothing_gauss_kernel_size: 0.1 # Half the width of the Gaussian kernel used for the smooth layer [m] \ No newline at end of file + smoothing_box_kernel_size: 0.2 # Half the width of the box kernel used for the smooth layer [m] + smoothing_gauss_kernel_size: 0.05 # Half the width of the Gaussian kernel used for the smooth layer [m] \ No newline at end of file From 5aa734a1104d7f934b3afb359030a276a82ccd9a Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 27 Oct 2021 12:22:08 +0200 Subject: [PATCH 129/504] add upsampling algorithm --- convex_plane_decomposition/CMakeLists.txt | 13 ++++ .../contour_extraction/Upsampling.h | 31 ++++++++ .../src/contour_extraction/Upsampling.cpp | 71 +++++++++++++++++++ .../test/testUpsampling.cpp | 28 ++++++++ 4 files changed, 143 insertions(+) create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/Upsampling.h create mode 100644 convex_plane_decomposition/src/contour_extraction/Upsampling.cpp create mode 100644 convex_plane_decomposition/test/testUpsampling.cpp diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index 82659a85..fc25bfcf 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -55,6 +55,7 @@ include_directories( add_library(${PROJECT_NAME} src/contour_extraction/ContourExtraction.cpp + src/contour_extraction/Upsampling.cpp src/ransac/RansacPlaneExtractor.cpp src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp src/GridMapPreprocessing.cpp @@ -91,3 +92,15 @@ install(DIRECTORY include/${PROJECT_NAME}/ ############# ## Testing ## ############# + +catkin_add_gtest(test_${PROJECT_NAME}_upsampling + test/testUpsampling.cpp +) +target_link_libraries(test_${PROJECT_NAME}_upsampling + ${PROJECT_NAME} + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + gmp + mpfr + gtest_main +) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/Upsampling.h b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/Upsampling.h new file mode 100644 index 00000000..0f80223b --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/Upsampling.h @@ -0,0 +1,31 @@ +// +// Created by rgrandia on 26.10.21. +// + +#pragma once + +#include "convex_plane_decomposition/SegmentedPlanesMap.h" + +namespace convex_plane_decomposition { +namespace contour_extraction { + +/** + * Upsamples an image such that all pixels are turned into 9 pixels, with the original pixel in the middle. + * Around the edges, each pixel is only upsamples in the inward direction. + * + * @param image : source image + * @return upsamples image + */ +cv::Mat upSample(const cv::Mat& image); + +/** + * Upsamples a segmented terrain such that the resulting terrain has 1/3 of the input resolution. (Each cell is split into 9 cells) + * This specific upsampling ratio makes it possible to keep labels in their exact original location in world frame. + * + * @param mapIn : source terrain + * @return upsampled terrain + */ +SegmentedPlanesMap upSample(const SegmentedPlanesMap& mapIn); + +} // namespace contour_extraction +} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/convex_plane_decomposition/src/contour_extraction/Upsampling.cpp b/convex_plane_decomposition/src/contour_extraction/Upsampling.cpp new file mode 100644 index 00000000..a742d069 --- /dev/null +++ b/convex_plane_decomposition/src/contour_extraction/Upsampling.cpp @@ -0,0 +1,71 @@ +// +// Created by rgrandia on 26.10.21. +// + +#include "convex_plane_decomposition/contour_extraction/Upsampling.h" + +namespace convex_plane_decomposition { +namespace contour_extraction { + +namespace { +// Helper function that upsamples a single column. Writes into a target that is already allocated with the right size +void upSampleColumn(const cv::Mat& column, cv::Mat& target, int col, int rows, int upsampledRows) { + for (int row = 0; row < rows; ++row) { + const auto value = column.at(row); + if (row == 0) { + target.at(0, col) = value; + target.at(1, col) = value; + } else if (row + 1 == rows) { + target.at(upsampledRows - 2, col) = value; + target.at(upsampledRows - 1, col) = value; + } else { + const int targetRow = 2 + 3 * (row - 1); + target.at(targetRow, col) = value; + target.at(targetRow + 1, col) = value; + target.at(targetRow + 2, col) = value; + } + } +} +} // namespace + +cv::Mat upSample(const cv::Mat& image) { + const int rows = image.rows; + const int cols = image.cols; + assert(rows >= 2); + assert(cols >= 2); + const int upsampledRows = 4 + 3 * (rows - 2); + const int upsampledCols = 4 + 3 * (cols - 2); + + cv::Mat result(upsampledRows, upsampledCols, image.type()); + + for (int col = 0; col < cols; ++col) { + const auto& column = image.col(col); + if (col == 0) { + upSampleColumn(column, result, 0, rows, upsampledRows); + result.col(0).copyTo(result.col(1)); + } else if (col + 1 == cols) { + upSampleColumn(column, result, upsampledCols - 2, rows, upsampledRows); + result.col(upsampledCols - 2).copyTo(result.col(upsampledCols - 1)); + } else { + const int targetCol = 2 + 3 * (col - 1); + upSampleColumn(column, result, targetCol, rows, upsampledRows); + result.col(targetCol).copyTo(result.col(targetCol + 1)); + result.col(targetCol + 1).copyTo(result.col(targetCol + 2)); + } + } + + return result; +} + +SegmentedPlanesMap upSample(const SegmentedPlanesMap& mapIn) { + SegmentedPlanesMap mapOut; + mapOut.labelPlaneParameters = mapIn.labelPlaneParameters; + mapOut.labeledImage = upSample(mapIn.labeledImage); + mapOut.resolution = mapIn.resolution / 3.0; + mapOut.mapOrigin = mapIn.mapOrigin; + mapOut.highestLabel = mapIn.highestLabel; + return mapOut; +} + +} // namespace contour_extraction +} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/convex_plane_decomposition/test/testUpsampling.cpp b/convex_plane_decomposition/test/testUpsampling.cpp new file mode 100644 index 00000000..06538b10 --- /dev/null +++ b/convex_plane_decomposition/test/testUpsampling.cpp @@ -0,0 +1,28 @@ +// +// Created by rgrandia on 26.10.21. +// + +#include + +#include "convex_plane_decomposition/contour_extraction/Upsampling.h" + +TEST(TestUpsampling, upsampleImage) { + // clang-format off + cv::Mat M = (cv::Mat_(3, 3) << + 1, 2, 3, + 4, 5, 6, + 7, 8, 9); + cv::Mat MoutCheck = (cv::Mat_(7, 7) << + 1, 1, 2, 2, 2, 3, 3, + 1, 1, 2, 2, 2, 3, 3, + 4, 4, 5, 5, 5, 6, 6, + 4, 4, 5, 5, 5, 6, 6, + 4, 4, 5, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 9, 9, + 7, 7, 8, 8, 8, 9, 9); + // clang-format on + + const auto Mout = convex_plane_decomposition::contour_extraction::upSample(M); + + ASSERT_TRUE(std::equal(MoutCheck.begin(), MoutCheck.end(), Mout.begin())); +} \ No newline at end of file From c658d705cd23f2180e953baf56de26445304419c Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 27 Oct 2021 12:22:42 +0200 Subject: [PATCH 130/504] add stepping stones terrain --- .../data/stepping_stones_65cm.png | Bin 0 -> 2364 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 convex_plane_decomposition_ros/data/stepping_stones_65cm.png diff --git a/convex_plane_decomposition_ros/data/stepping_stones_65cm.png b/convex_plane_decomposition_ros/data/stepping_stones_65cm.png new file mode 100644 index 0000000000000000000000000000000000000000..36cd697478aa5a51158c7654d575639be4cf4663 GIT binary patch literal 2364 zcmX9=dr*?;8gHjI+jh0oM8R9@BwH%7)`xO*)v++eyWov9GjLT9G&022%rk47A)%ez zCZovITp>jy!ZcBj1vqP7(mro^OK8(ja&^7s^CC^~d1!HF4+e(?7c+Ssgca?fPan7UL6<@-?rmtMKf%M97;Z-P4>o+Ck%hk`v{M ze}C`)qmS%6+&&;@q-t#OU#A=F2gTKKA?{-)b{#*?wcR*Ig8#Yuzx&Fsk8BAx#VcNn ztqz7q=0HI!kC_yz&XAj5?lGMcC`{*}YPQS|I4zlU(Y)(!63Ny(nna`K=ia;7<{pN3 z9sNA9op5DkFn3Pmw>9Txo|`Odu(qAJn$$t(NB3xodZ~mAlm$v_aX+)~k;GXa*gj6EVuCu8!q3$7*`>0DQd)4I7xUat)Kn22ct+72M~$Fg1R2swn~*lor2b?l z6BL&gcbll0#$D@Gdd}Yx=KbLlFgDx(e3R-o0t-^r@L2iOF)Yd&CTuqQ$Qf4l*5~tf2S{T=W$*BcX&Md+xw1VnHTvjW-MaHjcT{Z907boXG^wr=VW?(ys=|Nqt z`{J|a*}wcww=gLEIfEQ^tf%pihd7!-f^4Y0n}JJKxKeTk87G;FGhq@%a0NV;Jnp?< z@9JzxS$+^GHfK_zs89RByTe(~L*A&yj|s@-fK#-mk>{pIzAe5_G%L0gn;Vdv1};Ot zAT5aMgSCc6>PL_n*-hjk0B>${xR#oihvqBX@3w%UdyD50Q76YY1@d^Sek$)S8St8D zwN<@u+Ws}&&}+GMlWCky50fzB0~8bSU3(4HqZTz8OW~fd_A;+?+DDlt@^X4rOnZNi zZ0i6LnU=qH#VlKD>JtRZ{@FV2P87aWs1DKDV>B2-`+F%*>=n)OU;r3n18Jcmm8o2d zKyl;az=AH~eaYf%~j)@xy>`R=et?iqP^ zs9i(b+mf-82svx$b>L5#RiK~{6RhqovT1+6H@p+5tYopITyRBeziqMQy7QP?4K zwBo48@Q{A#y=h*p1<8 z7^Uj;6i$pU&RtqMaGg2lwGr*Tp<`}#HPxndsxc%aQOr^Dh?kr*DabDG^}DDhdPG^7 zF<`<*oU)GWXAKGRR;RXqeWzp<KI? zVE2zvz}2df{>SG{Yu6=?H*Iii74-ChK;2_{L~(FKE!Gjtk@6J^VZN`6g`!b)Z6-N- zTKBaXDB$+1)dMS7d;a>sjZn_wK(r21s`wQN2O3%o|rk4_Kp7=j` zr>_B@Ou>Bz*X*Cf|k;>FF`fU$V=6TGiWignKVYj?9gBW0P|hyX+M6yoJCfyNR*c|PcEohzGH9UfrS?-R~k024Pz zlGW$0MBtI%eef{DRLM}|)y#hSg+D$WV$>bC+#V`QM=pH-N<@JGoSS5)fh6(Di(Yhi zwy#d;lvd-E=0xlR1WF=lYYYF*cAXAtb!*cSe=#1 z(J>&eeEFnX+!<pim!1xew>4s(J2b2&1b4?r4dkT%AILB-fizM4!G$0}3o9F#sn|N_a3F zkZ&i&dj#u*L1}fzv#W1l-=f8?Z2ZX5GBF4{CTLcz7cH=2m(|?#L>*oS<>>|(Wu}YieY1`)QA9DYm3Z3w3Cft)PfxH!4 zo968guN1oW*0o7p@wt&e2A?r1S!%Y~eD#C(qCxJ~q7J_zn``&eD1=29>FdcMik{8f Y4?!yjZ)IQf-&u>Wz9E>}lL^2654pL?i2wiq literal 0 HcmV?d00001 From 4f71f7e1bdbdea6d6967ab6fdd347b10ebac6df1 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 27 Oct 2021 12:23:47 +0200 Subject: [PATCH 131/504] adapt contour extraction to provide a margin (if possible). Use upsampling to make sure the erosion operations don't fully remove regions --- .../contour_extraction/ContourExtraction.h | 3 +- .../ContourExtractionParameters.h | 4 +-- .../contour_extraction/ContourExtraction.cpp | 35 +++++++++++++++---- .../config/parameters.yaml | 4 +-- .../src/ParameterLoading.cpp | 2 +- convex_plane_decomposition_ros/test/test.cpp | 2 +- 6 files changed, 36 insertions(+), 14 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h index 310bdf21..568cdada 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h @@ -27,7 +27,8 @@ class ContourExtraction { private: ContourExtractionParameters parameters_; - cv::Mat erosionKernel_; + cv::Mat insetKernel_; + cv::Mat marginKernel_; // Memory to reuse between calls cv::Mat binaryImage_; diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h index 1d92911b..662f4671 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h @@ -8,8 +8,8 @@ namespace convex_plane_decomposition { namespace contour_extraction { struct ContourExtractionParameters { - /// Size of the kernel creating the boundary offset. In number of pixels. - int offsetSize = 2; + /// Size of the kernel creating the boundary offset. In number of (sub) pixels. + int marginSize = 2; }; } // namespace contour_extraction diff --git a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp index 21c4ac8f..b09af9f7 100644 --- a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp +++ b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp @@ -3,6 +3,7 @@ // #include "convex_plane_decomposition/contour_extraction/ContourExtraction.h" +#include "convex_plane_decomposition/contour_extraction/Upsampling.h" #include #include @@ -12,25 +13,44 @@ namespace contour_extraction { ContourExtraction::ContourExtraction(const ContourExtractionParameters& parameters) : parameters_(parameters), binaryImage_(cv::Size(0, 0), CV_8UC1) { - int erosionSize = parameters_.offsetSize; // single sided length of the kernel - int erosionType = cv::MORPH_CROSS; // cv::MORPH_ELLIPSE, cv::MORPH_RECT - erosionKernel_ = cv::getStructuringElement(erosionType, cv::Size(2 * erosionSize + 1, 2 * erosionSize + 1)); + { + int erosionSize = 1; // single sided length of the kernel + int erosionType = cv::MORPH_CROSS; + insetKernel_ = cv::getStructuringElement(erosionType, cv::Size(2 * erosionSize + 1, 2 * erosionSize + 1)); + } + { + int erosionSize = 1 + parameters_.marginSize; // single sided length of the kernel + int erosionType = cv::MORPH_ELLIPSE; + marginKernel_ = cv::getStructuringElement(erosionType, cv::Size(2 * erosionSize + 1, 2 * erosionSize + 1)); + } } std::vector ContourExtraction::extractPlanarRegions(const SegmentedPlanesMap& segmentedPlanesMap) { + const auto upSampledMap = upSample(segmentedPlanesMap); + std::vector planarRegions; - for (const auto& label_plane : segmentedPlanesMap.labelPlaneParameters) { + for (const auto& label_plane : upSampledMap.labelPlaneParameters) { const int label = label_plane.first; const auto& plane_parameters = label_plane.second; - binaryImage_ = segmentedPlanesMap.labeledImage == label; + binaryImage_ = upSampledMap.labeledImage == label; - auto boundariesAndInsets = contour_extraction::extractBoundaryAndInset(binaryImage_, erosionKernel_); + // Try with safety margin + cv::erode(binaryImage_, binaryImage_, marginKernel_, cv::Point(-1,-1), 1, cv::BORDER_REPLICATE); + auto boundariesAndInsets = contour_extraction::extractBoundaryAndInset(binaryImage_, insetKernel_); + + // If safety margin makes the region disappear -> try without + if (boundariesAndInsets.empty()) { + binaryImage_ = upSampledMap.labeledImage == label; + // still 1 pixel erosion to remove the growth after upsampling + cv::erode(binaryImage_, binaryImage_, insetKernel_, cv::Point(-1,-1), 1, cv::BORDER_REPLICATE); + boundariesAndInsets = contour_extraction::extractBoundaryAndInset(binaryImage_, insetKernel_); + } for (auto& boundaryAndInset : boundariesAndInsets) { // Transform points from pixel space to local terrain frame transformInPlace(boundaryAndInset, [&](CgalPoint2d& point) { - auto pointInWorld = pixelToWorldFrame(point, segmentedPlanesMap.resolution, segmentedPlanesMap.mapOrigin); + auto pointInWorld = pixelToWorldFrame(point, upSampledMap.resolution, upSampledMap.mapOrigin); point = worldFrameToTerrainFrame(pointInWorld, plane_parameters); }); @@ -45,6 +65,7 @@ std::vector ContourExtraction::extractPlanarRegions(const Segmente } std::vector extractBoundaryAndInset(cv::Mat& binary_image, const cv::Mat& erosionKernel) { + // Get boundary std::vector boundaries = extractPolygonsFromBinaryImage(binary_image); diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 6ac7df7c..46a41500 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -6,7 +6,7 @@ preprocessing: sliding_window_plane_extractor: kernel_size: 3 # Size of the sliding window patch used for normal vector calculation and planarity detection. Should be an odd number and at least 3. - planarity_opening_filter: 1 # [#] Apply opening filter (erosion -> dilation) to planarity detection by this amount of pixels + planarity_opening_filter: 0 # [#] Apply opening filter (erosion -> dilation) to planarity detection by this amount of pixels plane_inclination_threshold_degrees: 30.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch local_plane_inclination_threshold_degrees: 35.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a cell plane_patch_error_threshold: 0.02 # [m] The allowed root-mean-squared deviation from the plane fitted to the sliding window. @@ -24,7 +24,7 @@ ransac_plane_refinement: normal_threshold: 25.0 # [deg] Set maximum normal deviation between cluster surface_normal and point normal. contour_extraction: - offsetSize: 1 # Size of the kernel creating the boundary offset. In number of pixels. + marginSize: 1 # Size of the kernel creating the boundary offset. In number of (sub) pixels. postprocessing: extracted_planes_height_offset: 0.0 # Added offset in Z direction for the full map to compensate for the location of the foot frame w.r.t. the contact point diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/convex_plane_decomposition_ros/src/ParameterLoading.cpp index 021d6516..1859b1df 100644 --- a/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ b/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -29,7 +29,7 @@ PreprocessingParameters loadPreprocessingParameters(const ros::NodeHandle& nodeH contour_extraction::ContourExtractionParameters loadContourExtractionParameters(const ros::NodeHandle& nodeHandle, const std::string& prefix) { contour_extraction::ContourExtractionParameters contourParams; - loadParameter(nodeHandle, prefix, "offsetSize", contourParams.offsetSize); + loadParameter(nodeHandle, prefix, "marginSize", contourParams.marginSize); return contourParams; } diff --git a/convex_plane_decomposition_ros/test/test.cpp b/convex_plane_decomposition_ros/test/test.cpp index 30b997be..86acc44b 100644 --- a/convex_plane_decomposition_ros/test/test.cpp +++ b/convex_plane_decomposition_ros/test/test.cpp @@ -171,7 +171,7 @@ int main(int argc, char** argv) { // ============== planar regions extraction ================ contour_extraction::ContourExtractionParameters polyParams; - polyParams.offsetSize = 2; + polyParams.marginSize = 2; contour_extraction::ContourExtraction contourExtraction(polyParams); contourExtraction.extractPlanarRegions(planeExtractor.getSegmentedPlanesMap()); From 4c6cd0b8d3a85e059df7441c58d89eafbb70bd71 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Sat, 30 Oct 2021 22:02:49 +0200 Subject: [PATCH 132/504] fix pixelborder distance test. Need special case for the test --- .../PixelBorderDistance.h | 1 + .../test/testPixelBorderDistance.cpp | 34 +++++++++++++------ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h index 0db7cfcf..9456d3fa 100644 --- a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h +++ b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h @@ -24,6 +24,7 @@ inline float pixelBorderDistance(float i, float j) { /** * Returns square pixelBorderDistance, adding offset f. + * ! only works when i and j are cast from integers. */ inline float squarePixelBorderDistance(float i, float j, float f) { assert(i == j || std::abs(i - j) >= 1.0F); // Check that i and j are proper pixel locations: either the same pixel or non-overlapping pixels diff --git a/signed_distance_field/test/testPixelBorderDistance.cpp b/signed_distance_field/test/testPixelBorderDistance.cpp index 8e83a04a..de6b3101 100644 --- a/signed_distance_field/test/testPixelBorderDistance.cpp +++ b/signed_distance_field/test/testPixelBorderDistance.cpp @@ -6,6 +6,21 @@ #include "signed_distance_field/PixelBorderDistance.h" +namespace { +/* + * Specialization of the pixel border distance to test for the correctness of the equidistant point. + * The function contained in the library can only be called for casts from integer i, and j + */ +inline float squarePixelBorderDistanceTest(float i, float j, float f) { + if (i == j) { + return f; + } else { + float diff = std::abs(i - j) - 0.5F; + diff = std::max(diff, 0.0F); // ! adaptation needed to test for non integer i, j + return diff * diff + f; + } +} +} // namespace TEST(testPixelBorderDistance, distanceFunction) { using signed_distance_field::pixelBorderDistance; @@ -19,17 +34,16 @@ TEST(testPixelBorderDistance, distanceFunction) { TEST(testPixelBorderDistance, equidistantPoint) { using signed_distance_field::equidistancePoint; - using signed_distance_field::squarePixelBorderDistance; int pixelRange = 10; float offsetRange = 20.0; float offsetStep = 0.25; float tol = 1e-4; - for (int p =-pixelRange; p Date: Sat, 30 Oct 2021 22:03:24 +0200 Subject: [PATCH 133/504] improve shortcut to detect if a layer is of only obstacles or freespace --- .../signed_distance_field/SignedDistance2d.h | 18 ++++++++++++------ .../src/GridmapSignedDistanceField.cpp | 10 +++++++--- signed_distance_field/src/SignedDistance2d.cpp | 8 ++++---- .../test/naiveSignedDistance.h | 5 +++++ .../test/testSignedDistance3d.cpp | 10 +++++++--- 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h index fe5b5ea3..1ecb2036 100644 --- a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h +++ b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h @@ -12,12 +12,18 @@ namespace signed_distance_field { -inline Eigen::Matrix occupancyAtHeight(const grid_map::Matrix& elevationMap, float height) { - Eigen::Matrix occupany = elevationMap.unaryExpr([=](float val) { return val > height; }); - return occupany; -} - -grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution); +/** + * Computes the signed distance field at a specified height for a given elevation map. + * + * @param elevationMap : elevation data. + * @param height : height to generate the signed distance at. + * @param resolution : resolution of the elevation map. (The true distance [m] between cells in world frame) + * @param minHeight : the lowest height contained in elevationMap + * @param maxHeight : the maximum height contained in elevationMap + * @return The signed distance field at the query height. + */ +grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution, float minHeight, + float maxHeight); grid_map::Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution); diff --git a/signed_distance_field/src/GridmapSignedDistanceField.cpp b/signed_distance_field/src/GridmapSignedDistanceField.cpp index af67d5a3..1a8b3c60 100644 --- a/signed_distance_field/src/GridmapSignedDistanceField.cpp +++ b/signed_distance_field/src/GridmapSignedDistanceField.cpp @@ -65,10 +65,13 @@ std::pair GridmapSignedDist void GridmapSignedDistanceField::computeSignedDistance(const grid_map::Matrix& elevation) { const auto gridOriginZ = static_cast(gridmap3DLookup_.gridOrigin_.z()); const auto resolution = static_cast(gridmap3DLookup_.resolution_); + const auto minHeight = elevation.minCoeff(); + const auto maxHeight = elevation.maxCoeff(); // First layer: forward difference in z - grid_map::Matrix currentLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOriginZ, resolution); - grid_map::Matrix nextLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOriginZ + resolution, resolution); + grid_map::Matrix currentLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOriginZ, resolution, minHeight, maxHeight); + grid_map::Matrix nextLayer = + signed_distance_field::signedDistanceAtHeight(elevation, gridOriginZ + resolution, resolution, minHeight, maxHeight); grid_map::Matrix dz = signed_distance_field::layerFiniteDifference(currentLayer, nextLayer, resolution); // dz / layer = +resolution grid_map::Matrix dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); // dy / dcol = -resolution grid_map::Matrix dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution); // dx / drow = -resolution @@ -78,7 +81,8 @@ void GridmapSignedDistanceField::computeSignedDistance(const grid_map::Matrix& e for (size_t layerZ = 1; layerZ + 1 < gridmap3DLookup_.gridsize_.z; ++layerZ) { grid_map::Matrix previousLayer = std::move(currentLayer); currentLayer = std::move(nextLayer); - nextLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOriginZ + (layerZ + 1) * resolution, resolution); + nextLayer = + signed_distance_field::signedDistanceAtHeight(elevation, gridOriginZ + (layerZ + 1) * resolution, resolution, minHeight, maxHeight); dz = signed_distance_field::layerCentralDifference(previousLayer, nextLayer, resolution); dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); diff --git a/signed_distance_field/src/SignedDistance2d.cpp b/signed_distance_field/src/SignedDistance2d.cpp index 3dd68d1c..17ca4e1b 100644 --- a/signed_distance_field/src/SignedDistance2d.cpp +++ b/signed_distance_field/src/SignedDistance2d.cpp @@ -191,10 +191,10 @@ grid_map::Matrix pixelDistanceToObstacle(const grid_map::Matrix& elevationMap, f } // namespace internal -grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution) { - auto obstacleCount = (elevationMap.array() > height).count(); - bool allPixelsAreObstacles = obstacleCount == elevationMap.size(); - bool allPixelsAreFreeSpace = obstacleCount == 0; +grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution, float minHeight, + float maxHeight) { + const bool allPixelsAreObstacles = height < minHeight; + const bool allPixelsAreFreeSpace = height > maxHeight; if (allPixelsAreObstacles) { return -resolution * internal::pixelDistanceToFreeSpace(elevationMap, height, resolution); diff --git a/signed_distance_field/test/naiveSignedDistance.h b/signed_distance_field/test/naiveSignedDistance.h index 622cd240..2ea41685 100644 --- a/signed_distance_field/test/naiveSignedDistance.h +++ b/signed_distance_field/test/naiveSignedDistance.h @@ -6,6 +6,11 @@ namespace signed_distance_field { +inline Eigen::Matrix occupancyAtHeight(const grid_map::Matrix& elevationMap, float height) { + Eigen::Matrix occupany = elevationMap.unaryExpr([=](float val) { return val > height; }); + return occupany; +} + inline bool isEqualSdf(const grid_map::Matrix& sdf0, const grid_map::Matrix& sdf1, float tol) { grid_map::Matrix error = (sdf0 - sdf1).array().abs(); float maxDifference = error.maxCoeff(); diff --git a/signed_distance_field/test/testSignedDistance3d.cpp b/signed_distance_field/test/testSignedDistance3d.cpp index d90eb679..8a5545fd 100644 --- a/signed_distance_field/test/testSignedDistance3d.cpp +++ b/signed_distance_field/test/testSignedDistance3d.cpp @@ -15,15 +15,17 @@ TEST(testSignedDistance3d, flatTerrain) { const float resolution = 0.1; const float terrainHeight = 0.5; const grid_map::Matrix map = grid_map::Matrix::Constant(n, m, terrainHeight); + const float minHeight = map.minCoeff(); + const float maxHeight = map.maxCoeff(); const float testHeightAboveTerrain = 3.0; const auto naiveSignedDistanceAbove = signed_distance_field::naiveSignedDistanceAtHeight(map, testHeightAboveTerrain, resolution); - const auto signedDistanceAbove = signed_distance_field::signedDistanceAtHeight(map, testHeightAboveTerrain, resolution); + const auto signedDistanceAbove = signed_distance_field::signedDistanceAtHeight(map, testHeightAboveTerrain, resolution, minHeight, maxHeight); ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistanceAbove, naiveSignedDistanceAbove, 1e-4)); const float testHeightBelowTerrain = -3.0; const auto naiveSignedDistanceBelow = signed_distance_field::naiveSignedDistanceAtHeight(map, testHeightBelowTerrain, resolution); - const auto signedDistanceBelow = signed_distance_field::signedDistanceAtHeight(map, testHeightBelowTerrain, resolution); + const auto signedDistanceBelow = signed_distance_field::signedDistanceAtHeight(map, testHeightBelowTerrain, resolution, minHeight, maxHeight); ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistanceBelow, naiveSignedDistanceBelow, 1e-4)); } @@ -32,12 +34,14 @@ TEST(testSignedDistance3d, randomTerrain) { const int m = 30; const float resolution = 0.1; grid_map::Matrix map = grid_map::Matrix::Random(n, m); // random [-1.0, 1.0] + const float minHeight = map.minCoeff(); + const float maxHeight = map.maxCoeff(); // Check at different heights, resulting in different levels of sparsity. float heightStep = 0.1; for (float height = -1.0 - heightStep; height < 1.0 + heightStep; height+=heightStep) { const auto naiveSignedDistance = signed_distance_field::naiveSignedDistanceAtHeight(map, height, resolution); - const auto signedDistance = signed_distance_field::signedDistanceAtHeight(map, height, resolution); + const auto signedDistance = signed_distance_field::signedDistanceAtHeight(map, height, resolution, minHeight, maxHeight); ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)) << "height: " << height; } From c0efdba74fa34e9278cb03709fb1409f97aea8ee Mon Sep 17 00:00:00 2001 From: rgrandia Date: Sun, 31 Oct 2021 21:16:39 +0100 Subject: [PATCH 134/504] refactor pixel border distance to minimize branching --- .../PixelBorderDistance.h | 52 ++++++++++++------- .../src/PixelBorderDistance.cpp | 9 +--- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h index 9456d3fa..32375335 100644 --- a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h +++ b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h @@ -5,8 +5,8 @@ #pragma once #include -#include #include +#include namespace signed_distance_field { @@ -19,7 +19,7 @@ namespace signed_distance_field { * @return : absolute distance between center of pixel 1 and the border of pixel 2 */ inline float pixelBorderDistance(float i, float j) { - return std::max(std::abs(i-j) - 0.5F, 0.0F); + return std::max(std::abs(i - j) - 0.5F, 0.0F); } /** @@ -27,11 +27,12 @@ inline float pixelBorderDistance(float i, float j) { * ! only works when i and j are cast from integers. */ inline float squarePixelBorderDistance(float i, float j, float f) { - assert(i == j || std::abs(i - j) >= 1.0F); // Check that i and j are proper pixel locations: either the same pixel or non-overlapping pixels + assert(i == j || + std::abs(i - j) >= 1.0F); // Check that i and j are proper pixel locations: either the same pixel or non-overlapping pixels if (i == j) { return f; } else { - float diff = std::abs(i-j) - 0.5F; + float diff = std::abs(i - j) - 0.5F; return diff * diff + f; } } @@ -42,18 +43,28 @@ namespace internal { * Return equidistancepoint between origin and pixel p (with p > 0) with offset fp */ inline float intersectionPointRightSideOfOrigin(float p, float fp) { + /* + * There are 5 different solutions + * In decreasing order: + * sol 1 in [p^2, inf] + * sol 2 in [bound, p^2] + * sol 3 in [-bound, bound] + * sol 4 in [-p^2, -bound] + * sol 5 in [-inf, -p^2] + */ auto pSquared = p * p; - auto fpAbs = std::abs(fp); - if (fpAbs >= pSquared) { - float s = (pSquared + fp) / (2.0F * p); - return (fp > 0.0F) ? s + 0.5F : s - 0.5F; + if (fp > pSquared) { + return (pSquared + p + fp) / (2.0F * p); // sol 1 + } else if (fp < -pSquared) { + return (pSquared - p + fp) / (2.0F * p); // sol 5 } else { - float boundary = pSquared - 2.0F * p + 1.0F; - if (fpAbs < boundary) { - return (pSquared - p + fp) / (2.0F * p - 2.0F); + float bound = pSquared - 2.0F * p + 1.0F; // Always positive because (p > 0) + if (fp > bound) { + return 0.5F + std::sqrt(fp); // sol 2 + } else if (fp < -bound) { + return p - 0.5F - std::sqrt(-fp); // sol 4 } else { - float s = 0.5F + std::sqrt(fpAbs); - return (fp > 0.0F) ? s : p - s; + return (pSquared - p + fp) / (2.0F * p - 2.0F); // sol 3 } } } @@ -62,8 +73,12 @@ inline float intersectionPointRightSideOfOrigin(float p, float fp) { * Return equidistancepoint between origin and pixel p with offset fp */ inline float intersectionOffsetFromOrigin(float p, float fp) { - float intersectionOffset = intersectionPointRightSideOfOrigin(std::abs(p), fp); - return (p > 0) ? intersectionOffset : -intersectionOffset; + if (p > 0.0F) { + return intersectionPointRightSideOfOrigin(p, fp); + } else { + // call with negative p and flip the result + return -intersectionPointRightSideOfOrigin(-p, fp); + } } } // namespace internal @@ -74,10 +89,11 @@ inline float intersectionOffsetFromOrigin(float p, float fp) { * squarePixelBorderDistance(s, q, fq) == squarePixelBorderDistance(s, p, fp) */ inline float equidistancePoint(float q, float fq, float p, float fp) { - assert(q == p || std::abs(q-p) >= 1.0F); // Check that q and p are proper pixel locations: either the same pixel or non-overlapping pixels - assert((q == p) ? fp == fq : true); // Check when q and p are equal, the offsets are also equal + assert(q == p || + std::abs(q - p) >= 1.0F); // Check that q and p are proper pixel locations: either the same pixel or non-overlapping pixels + assert((q == p) ? fp == fq : true); // Check when q and p are equal, the offsets are also equal - if (fp == fq) { // quite common case when both pixels are of the same class (occupied / free) + if (fp == fq) { // quite common case when both pixels are of the same class (occupied / free) return 0.5F * (p + q); } else { float df = fp - fq; diff --git a/signed_distance_field/src/PixelBorderDistance.cpp b/signed_distance_field/src/PixelBorderDistance.cpp index 2a1ed055..34047f8e 100644 --- a/signed_distance_field/src/PixelBorderDistance.cpp +++ b/signed_distance_field/src/PixelBorderDistance.cpp @@ -4,11 +4,4 @@ #include "signed_distance_field/PixelBorderDistance.h" - -namespace signed_distance_field { - - - - - -} \ No newline at end of file +namespace signed_distance_field {} \ No newline at end of file From 402b8efbf5b612e45996bcfc27be5df373a8dc46 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Sun, 31 Oct 2021 22:23:30 +0100 Subject: [PATCH 135/504] refactor and simplify bound computation --- .../PixelBorderDistance.h | 2 +- .../src/SignedDistance2d.cpp | 100 ++++++------------ 2 files changed, 33 insertions(+), 69 deletions(-) diff --git a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h index 32375335..785d20f2 100644 --- a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h +++ b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h @@ -58,7 +58,7 @@ inline float intersectionPointRightSideOfOrigin(float p, float fp) { } else if (fp < -pSquared) { return (pSquared - p + fp) / (2.0F * p); // sol 5 } else { - float bound = pSquared - 2.0F * p + 1.0F; // Always positive because (p > 0) + const float bound = pSquared - 2.0F * p + 1.0F; // Always positive because (p > 0) if (fp > bound) { return 0.5F + std::sqrt(fp); // sol 2 } else if (fp < -bound) { diff --git a/signed_distance_field/src/SignedDistance2d.cpp b/signed_distance_field/src/SignedDistance2d.cpp index 17ca4e1b..18ec6de4 100644 --- a/signed_distance_field/src/SignedDistance2d.cpp +++ b/signed_distance_field/src/SignedDistance2d.cpp @@ -16,100 +16,64 @@ struct DistanceLowerBound { float z_rhs; // rhs of interval where this lower bound holds }; -inline std::vector::iterator fillLowerBounds(const Eigen::Ref& squareDistance1d, - std::vector& lowerBounds) { - const int n = squareDistance1d.size(); +std::vector::iterator fillLowerBounds(const Eigen::Ref& squareDistance1d, + std::vector& lowerBounds) { + const auto n = squareDistance1d.size(); const auto nFloat = static_cast(n); - // Find minimum - int qMin = 0; - float fMin = squareDistance1d[0]; - if (fMin > 0.0F) { - for (int q = 1; q < n; ++q) { - const float fq = squareDistance1d[q]; - if (fq < fMin) { - qMin = q; - fMin = fq; - if (fMin == 0.0F) { - break; - } - } - } - } - // Initialize - auto lowerBoundIt = lowerBounds.begin() + qMin; - *lowerBoundIt = DistanceLowerBound{static_cast(qMin), fMin, -INF, INF}; + auto rhsBoundIt = lowerBounds.begin(); + *rhsBoundIt = DistanceLowerBound{0.0F, squareDistance1d[0], -INF, INF}; + auto firstBoundIt = lowerBounds.begin(); // Compute bounds to the right of minimum - float qFloat = static_cast(qMin) + 1.0F; - for (int q = qMin + 1; q < n; ++q) { - // Storing these quantaties by value gives better performance (removed indirection?) + float qFloat = 1.0F; + for (Eigen::Index q = 1; q < n; ++q) { + // Storing this by value gives better performance (removed indirection?) const float fq = squareDistance1d[q]; - DistanceLowerBound lastBound = *lowerBoundIt; - float s = equidistancePoint(qFloat, fq, lastBound.v, lastBound.f); + float s = equidistancePoint(qFloat, fq, rhsBoundIt->v, rhsBoundIt->f); if (s < nFloat) { // Can ignore the lower bound derived from this point if it is only active outsize of [0, n] // Search backwards in bounds until s is within [z_lhs, z_rhs] - while (s < lastBound.z_lhs) { - --lowerBoundIt; - lastBound = *lowerBoundIt; - s = equidistancePoint(qFloat, fq, lastBound.v, lastBound.f); + while (s < rhsBoundIt->z_lhs) { + --rhsBoundIt; + s = equidistancePoint(qFloat, fq, rhsBoundIt->v, rhsBoundIt->f); } - lowerBoundIt->z_rhs = s; - ++lowerBoundIt; - *lowerBoundIt = DistanceLowerBound{qFloat, fq, s, INF}; - } - qFloat += 1.0F; - } - - // Compute bounds to the left of minimum - lowerBoundIt = lowerBounds.begin() + qMin; - qFloat = static_cast(qMin) - 1.0F; - for (int q = qMin - 1; q >= 0; --q) { - const float fq = squareDistance1d[q]; - DistanceLowerBound lastBound = *lowerBoundIt; - - float s = equidistancePoint(qFloat, fq, lastBound.v, lastBound.f); - if (s > 0.0F) { // Can ignore the lower bound derived from this point if it is only active outsize of [0, n] - // Search forwards in bounds until s is within [z_lhs, z_rhs] - while (s > lastBound.z_rhs) { - ++lowerBoundIt; - lastBound = *lowerBoundIt; - s = equidistancePoint(qFloat, fq, lastBound.v, lastBound.f); + if (s >= 0.0F) { // Intersection is within [0, n]. Adjust current lowerbound and insert the new one after + rhsBoundIt->z_rhs = s; // Update the bound that comes before + ++rhsBoundIt; // insert new bound after. + *rhsBoundIt = DistanceLowerBound{qFloat, fq, s, INF}; // Valid from s till infinity + } else { // Intersection is outside [0, n]. This means that the new bound dominates all previous bounds + *rhsBoundIt = DistanceLowerBound{qFloat, fq, -INF, INF}; + firstBoundIt = rhsBoundIt; // No need to keep other bounds, so update the first bound iterator to this one. } - lowerBoundIt->z_lhs = s; - --lowerBoundIt; - *lowerBoundIt = DistanceLowerBound{qFloat, fq, -INF, s}; } - qFloat -= 1.0F; + + // Increment to follow loop counter as float + qFloat += 1.0F; } - return lowerBoundIt; + return firstBoundIt; } -inline void extractDistances(Eigen::Ref squareDistance1d, const std::vector& lowerBounds, - std::vector::iterator lowerBoundIt) { - const int n = squareDistance1d.size(); +void extractDistances(Eigen::Ref squareDistance1d, const std::vector& lowerBounds, + std::vector::const_iterator lowerBoundIt) { + const auto n = squareDistance1d.size(); - // Store active lower bound by value to remove indirection + // Store active bound by value to remove indirection auto lastz = lowerBoundIt->z_rhs; - auto lastv = lowerBoundIt->v; - auto lastf = lowerBoundIt->f; float qFloat = 0.0F; - for (int q = 0; q < n; q++) { + for (Eigen::Index q = 0; q < n; ++q) { // Find the new active lower bound if q no longer belongs to current interval if (qFloat > lastz) { do { ++lowerBoundIt; - lastz = lowerBoundIt->z_rhs; - } while (lastz < qFloat); - lastv = lowerBoundIt->v; - lastf = lowerBoundIt->f; + } while (lowerBoundIt->z_rhs < qFloat); + lastz = lowerBoundIt->z_rhs; } - squareDistance1d[q] = squarePixelBorderDistance(qFloat, lastv, lastf); + squareDistance1d[q] = squarePixelBorderDistance(qFloat, lowerBoundIt->v, lowerBoundIt->f); qFloat += 1.0F; } } From f5ee84f9b4b9f569c8df2ecda74891130b9e94ac Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 2 Nov 2021 10:27:06 +0100 Subject: [PATCH 136/504] add test for interpolation of the sdf --- .../test/testSignedDistance3d.cpp | 42 +++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/signed_distance_field/test/testSignedDistance3d.cpp b/signed_distance_field/test/testSignedDistance3d.cpp index 8a5545fd..b846165d 100644 --- a/signed_distance_field/test/testSignedDistance3d.cpp +++ b/signed_distance_field/test/testSignedDistance3d.cpp @@ -4,6 +4,7 @@ #include +#include "signed_distance_field/GridmapSignedDistanceField.h" #include "signed_distance_field/PixelBorderDistance.h" #include "signed_distance_field/SignedDistance2d.h" @@ -20,12 +21,14 @@ TEST(testSignedDistance3d, flatTerrain) { const float testHeightAboveTerrain = 3.0; const auto naiveSignedDistanceAbove = signed_distance_field::naiveSignedDistanceAtHeight(map, testHeightAboveTerrain, resolution); - const auto signedDistanceAbove = signed_distance_field::signedDistanceAtHeight(map, testHeightAboveTerrain, resolution, minHeight, maxHeight); + const auto signedDistanceAbove = + signed_distance_field::signedDistanceAtHeight(map, testHeightAboveTerrain, resolution, minHeight, maxHeight); ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistanceAbove, naiveSignedDistanceAbove, 1e-4)); const float testHeightBelowTerrain = -3.0; const auto naiveSignedDistanceBelow = signed_distance_field::naiveSignedDistanceAtHeight(map, testHeightBelowTerrain, resolution); - const auto signedDistanceBelow = signed_distance_field::signedDistanceAtHeight(map, testHeightBelowTerrain, resolution, minHeight, maxHeight); + const auto signedDistanceBelow = + signed_distance_field::signedDistanceAtHeight(map, testHeightBelowTerrain, resolution, minHeight, maxHeight); ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistanceBelow, naiveSignedDistanceBelow, 1e-4)); } @@ -33,16 +36,47 @@ TEST(testSignedDistance3d, randomTerrain) { const int n = 20; const int m = 30; const float resolution = 0.1; - grid_map::Matrix map = grid_map::Matrix::Random(n, m); // random [-1.0, 1.0] + grid_map::Matrix map = grid_map::Matrix::Random(n, m); // random [-1.0, 1.0] const float minHeight = map.minCoeff(); const float maxHeight = map.maxCoeff(); // Check at different heights, resulting in different levels of sparsity. float heightStep = 0.1; - for (float height = -1.0 - heightStep; height < 1.0 + heightStep; height+=heightStep) { + for (float height = -1.0 - heightStep; height < 1.0 + heightStep; height += heightStep) { const auto naiveSignedDistance = signed_distance_field::naiveSignedDistanceAtHeight(map, height, resolution); const auto signedDistance = signed_distance_field::signedDistanceAtHeight(map, height, resolution, minHeight, maxHeight); ASSERT_TRUE(signed_distance_field::isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)) << "height: " << height; } +} + +TEST(testSignedDistance3d, randomTerrainInterpolation) { + const int n = 20; + const int m = 30; + const float resolution = 0.1; + grid_map::GridMap map; + map.setGeometry({n * resolution, m * resolution}, resolution); + map.add("elevation"); + map.get("elevation").setRandom(); // random [-1.0, 1.0] + const grid_map::Matrix mapData = map.get("elevation"); + const float minHeight = mapData.minCoeff(); + const float maxHeight = mapData.maxCoeff(); + + signed_distance_field::GridmapSignedDistanceField sdf(map, "elevation", minHeight, maxHeight); + + // Check at different heights/ + for (float height = minHeight; height < maxHeight; height += resolution) { + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistanceAtHeight(mapData, height, resolution); + + for (int i = 0; i < mapData.rows(); ++i) { + for (int j = 0; j < mapData.rows(); ++j) { + grid_map::Position position2d; + map.getPosition({i, j}, position2d); + + const auto sdfValue = sdf.value({position2d.x(), position2d.y(), height}); + const auto sdfCheck = naiveSignedDistance(i, j); + ASSERT_LT(std::abs(sdfValue - sdfCheck), 1e-4); + } + } + } } \ No newline at end of file From ae7b5b053ccaa416731c25f244a1f3bdaf2ca61e Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 2 Nov 2021 10:27:48 +0100 Subject: [PATCH 137/504] simplify square distance --- .../PixelBorderDistance.h | 10 +++------ .../test/testPixelBorderDistance.cpp | 21 +++---------------- 2 files changed, 6 insertions(+), 25 deletions(-) diff --git a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h index 785d20f2..c72db18e 100644 --- a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h +++ b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h @@ -24,17 +24,13 @@ inline float pixelBorderDistance(float i, float j) { /** * Returns square pixelBorderDistance, adding offset f. - * ! only works when i and j are cast from integers. */ inline float squarePixelBorderDistance(float i, float j, float f) { assert(i == j || std::abs(i - j) >= 1.0F); // Check that i and j are proper pixel locations: either the same pixel or non-overlapping pixels - if (i == j) { - return f; - } else { - float diff = std::abs(i - j) - 0.5F; - return diff * diff + f; - } + + float d = pixelBorderDistance(i, j); + return d * d + f; } namespace internal { diff --git a/signed_distance_field/test/testPixelBorderDistance.cpp b/signed_distance_field/test/testPixelBorderDistance.cpp index de6b3101..43f6bf0e 100644 --- a/signed_distance_field/test/testPixelBorderDistance.cpp +++ b/signed_distance_field/test/testPixelBorderDistance.cpp @@ -6,22 +6,6 @@ #include "signed_distance_field/PixelBorderDistance.h" -namespace { -/* - * Specialization of the pixel border distance to test for the correctness of the equidistant point. - * The function contained in the library can only be called for casts from integer i, and j - */ -inline float squarePixelBorderDistanceTest(float i, float j, float f) { - if (i == j) { - return f; - } else { - float diff = std::abs(i - j) - 0.5F; - diff = std::max(diff, 0.0F); // ! adaptation needed to test for non integer i, j - return diff * diff + f; - } -} -} // namespace - TEST(testPixelBorderDistance, distanceFunction) { using signed_distance_field::pixelBorderDistance; // Basic properties of the distance function @@ -34,6 +18,7 @@ TEST(testPixelBorderDistance, distanceFunction) { TEST(testPixelBorderDistance, equidistantPoint) { using signed_distance_field::equidistancePoint; + using signed_distance_field::squarePixelBorderDistance; int pixelRange = 10; float offsetRange = 20.0; @@ -54,8 +39,8 @@ TEST(testPixelBorderDistance, equidistantPoint) { ASSERT_LT(std::abs(s0 - s1), tol); // Check that the distance from s0 to p and q is indeed equal - float dp = squarePixelBorderDistanceTest(s0, p, fp); - float dq = squarePixelBorderDistanceTest(s0, q, fq); + float dp = squarePixelBorderDistance(s0, p, fp); + float dq = squarePixelBorderDistance(s0, q, fq); ASSERT_LT(std::abs(dp - dq), tol) << "p: " << p << ", q: " << q << ", fp: " << fp << ", fq: " << fq; } } From 60a4abf85aba1fb3739bd79cfe3974d5fb88bf42 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 2 Nov 2021 10:29:20 +0100 Subject: [PATCH 138/504] reduce amount of transposing. better exploit leading zeros also in bound computation --- .../GridmapSignedDistanceField.h | 2 +- .../signed_distance_field/SignedDistance2d.h | 6 + .../src/GridmapSignedDistanceField.cpp | 51 ++++-- .../src/SignedDistance2d.cpp | 171 +++++++++++------- 4 files changed, 150 insertions(+), 80 deletions(-) diff --git a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h index 4ed38749..d803dfa6 100644 --- a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h +++ b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h @@ -56,7 +56,7 @@ class GridmapSignedDistanceField : public switched_model::SignedDistanceField { private: GridmapSignedDistanceField(const GridmapSignedDistanceField& other); void computeSignedDistance(const grid_map::Matrix& elevation); - void emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dx, const grid_map::Matrix& dy, + void emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dxTranspose, const grid_map::Matrix& dy, const grid_map::Matrix& dz); using node_data_t = std::array; diff --git a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h index 1ecb2036..e937ad3a 100644 --- a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h +++ b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h @@ -25,6 +25,12 @@ namespace signed_distance_field { grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution, float minHeight, float maxHeight); +/** + * Same as above, but returns the sdf in transposed form. + */ +grid_map::Matrix signedDistanceAtHeightTranspose(const grid_map::Matrix& elevationMap, float height, float resolution, float minHeight, + float maxHeight); + grid_map::Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution); } // namespace signed_distance_field \ No newline at end of file diff --git a/signed_distance_field/src/GridmapSignedDistanceField.cpp b/signed_distance_field/src/GridmapSignedDistanceField.cpp index 1a8b3c60..de2a2e77 100644 --- a/signed_distance_field/src/GridmapSignedDistanceField.cpp +++ b/signed_distance_field/src/GridmapSignedDistanceField.cpp @@ -68,42 +68,69 @@ void GridmapSignedDistanceField::computeSignedDistance(const grid_map::Matrix& e const auto minHeight = elevation.minCoeff(); const auto maxHeight = elevation.maxCoeff(); + /* + * General strategy to reduce the amount of transposing: + * - SDF at a height is in transposed form after computing it. + * - Take the finite difference in dx, now that this data is continuous in memory. + * - Transpose the SDF + * - Take other finite differences, now dy is efficient. + * - When writing to the 3D structure, keep in mind that dx is still transposed. + */ + // First layer: forward difference in z - grid_map::Matrix currentLayer = signed_distance_field::signedDistanceAtHeight(elevation, gridOriginZ, resolution, minHeight, maxHeight); + grid_map::Matrix currentLayer = + signed_distance_field::signedDistanceAtHeightTranspose(elevation, gridOriginZ, resolution, minHeight, maxHeight); + grid_map::Matrix dxTranspose = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); // dx / drow = -resolution + currentLayer.transposeInPlace(); + grid_map::Matrix nextLayer = - signed_distance_field::signedDistanceAtHeight(elevation, gridOriginZ + resolution, resolution, minHeight, maxHeight); + signed_distance_field::signedDistanceAtHeightTranspose(elevation, gridOriginZ + resolution, resolution, minHeight, maxHeight); + grid_map::Matrix dxNextTranspose = signed_distance_field::columnwiseCentralDifference(nextLayer, -resolution); + nextLayer.transposeInPlace(); + grid_map::Matrix dz = signed_distance_field::layerFiniteDifference(currentLayer, nextLayer, resolution); // dz / layer = +resolution grid_map::Matrix dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); // dy / dcol = -resolution - grid_map::Matrix dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution); // dx / drow = -resolution - emplacebackLayerData(currentLayer, dx, dy, dz); + + emplacebackLayerData(currentLayer, dxTranspose, dy, dz); // Middle layers: central difference in z for (size_t layerZ = 1; layerZ + 1 < gridmap3DLookup_.gridsize_.z; ++layerZ) { grid_map::Matrix previousLayer = std::move(currentLayer); currentLayer = std::move(nextLayer); - nextLayer = - signed_distance_field::signedDistanceAtHeight(elevation, gridOriginZ + (layerZ + 1) * resolution, resolution, minHeight, maxHeight); + dxTranspose = std::move(dxNextTranspose); + // Compute next layer transposed + nextLayer = signed_distance_field::signedDistanceAtHeightTranspose(elevation, gridOriginZ + (layerZ + 1) * resolution, resolution, + minHeight, maxHeight); + + // Take dx here, so we can operate on columns before transposing + dxNextTranspose = signed_distance_field::columnwiseCentralDifference(nextLayer, -resolution); + + // Transpose the data + nextLayer.transposeInPlace(); + + // Compute other finite differences dz = signed_distance_field::layerCentralDifference(previousLayer, nextLayer, resolution); dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); - dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution); - emplacebackLayerData(currentLayer, dx, dy, dz); + + // Add the data to the 3D structure + emplacebackLayerData(currentLayer, dxTranspose, dy, dz); } // Last layer: backward difference in z grid_map::Matrix previousLayer = std::move(currentLayer); currentLayer = std::move(nextLayer); + dxTranspose = std::move(dxNextTranspose); dz = signed_distance_field::layerCentralDifference(previousLayer, currentLayer, resolution); dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); - dx = signed_distance_field::rowwiseCentralDifference(currentLayer, -resolution); - emplacebackLayerData(currentLayer, dx, dy, dz); + emplacebackLayerData(currentLayer, dxTranspose, dy, dz); } -void GridmapSignedDistanceField::emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dx, +void GridmapSignedDistanceField::emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dxdxTranspose, const grid_map::Matrix& dy, const grid_map::Matrix& dz) { for (size_t colY = 0; colY < gridmap3DLookup_.gridsize_.y; ++colY) { for (size_t rowX = 0; rowX < gridmap3DLookup_.gridsize_.x; ++rowX) { - data_.emplace_back(node_data_t{signedDistance(rowX, colY), dx(rowX, colY), dy(rowX, colY), dz(rowX, colY)}); + data_.emplace_back(node_data_t{signedDistance(rowX, colY), dxdxTranspose(colY, rowX), dy(rowX, colY), dz(rowX, colY)}); } } } diff --git a/signed_distance_field/src/SignedDistance2d.cpp b/signed_distance_field/src/SignedDistance2d.cpp index 18ec6de4..edfc3b21 100644 --- a/signed_distance_field/src/SignedDistance2d.cpp +++ b/signed_distance_field/src/SignedDistance2d.cpp @@ -17,29 +17,30 @@ struct DistanceLowerBound { }; std::vector::iterator fillLowerBounds(const Eigen::Ref& squareDistance1d, - std::vector& lowerBounds) { + std::vector& lowerBounds, Eigen::Index start) { const auto n = squareDistance1d.size(); const auto nFloat = static_cast(n); + const auto startFloat = static_cast(start); // Initialize auto rhsBoundIt = lowerBounds.begin(); - *rhsBoundIt = DistanceLowerBound{0.0F, squareDistance1d[0], -INF, INF}; + *rhsBoundIt = DistanceLowerBound{startFloat, squareDistance1d[start], -INF, INF}; auto firstBoundIt = lowerBounds.begin(); // Compute bounds to the right of minimum - float qFloat = 1.0F; - for (Eigen::Index q = 1; q < n; ++q) { + float qFloat = rhsBoundIt->v + 1.0F; + for (Eigen::Index q = start + 1; q < n; ++q) { // Storing this by value gives better performance (removed indirection?) const float fq = squareDistance1d[q]; float s = equidistancePoint(qFloat, fq, rhsBoundIt->v, rhsBoundIt->f); - if (s < nFloat) { // Can ignore the lower bound derived from this point if it is only active outsize of [0, n] + if (s < nFloat) { // Can ignore the lower bound derived from this point if it is only active outsize of [start, n] // Search backwards in bounds until s is within [z_lhs, z_rhs] while (s < rhsBoundIt->z_lhs) { --rhsBoundIt; s = equidistancePoint(qFloat, fq, rhsBoundIt->v, rhsBoundIt->f); } - if (s >= 0.0F) { // Intersection is within [0, n]. Adjust current lowerbound and insert the new one after + if (s > startFloat) { // Intersection is within [start, n]. Adjust current lowerbound and insert the new one after rhsBoundIt->z_rhs = s; // Update the bound that comes before ++rhsBoundIt; // insert new bound after. *rhsBoundIt = DistanceLowerBound{qFloat, fq, s, INF}; // Valid from s till infinity @@ -57,27 +58,45 @@ std::vector::iterator fillLowerBounds(const Eigen::Ref squareDistance1d, const std::vector& lowerBounds, - std::vector::const_iterator lowerBoundIt) { + std::vector::const_iterator lowerBoundIt, Eigen::Index start) { const auto n = squareDistance1d.size(); // Store active bound by value to remove indirection auto lastz = lowerBoundIt->z_rhs; - float qFloat = 0.0F; - for (Eigen::Index q = 0; q < n; ++q) { - // Find the new active lower bound if q no longer belongs to current interval - if (qFloat > lastz) { - do { - ++lowerBoundIt; - } while (lowerBoundIt->z_rhs < qFloat); - lastz = lowerBoundIt->z_rhs; + auto qFloat = static_cast(start); + for (Eigen::Index q = start; q < n; ++q) { + if (squareDistance1d[q] > 0.0F) { // Observe that if squareDistance1d[q] == 0.0, this is already the minimum and it will stay 0.0 + // Find the new active lower bound if q no longer belongs to current interval + if (qFloat > lastz) { + do { + ++lowerBoundIt; + } while (lowerBoundIt->z_rhs < qFloat); + lastz = lowerBoundIt->z_rhs; + } + + squareDistance1d[q] = squarePixelBorderDistance(qFloat, lowerBoundIt->v, lowerBoundIt->f); } - squareDistance1d[q] = squarePixelBorderDistance(qFloat, lowerBoundIt->v, lowerBoundIt->f); qFloat += 1.0F; } } +Eigen::Index lastZero(const Eigen::Ref& squareDistance1d) { + const auto n = squareDistance1d.size(); + + for (Eigen::Index q = 0; q < n; ++q) { + if (squareDistance1d[q] > 0.0F) { + if (q > 0) { + return q - 1; + } else { + return 0; + } + } + } + return n; +} + /** * 1D Euclidean Distance Transform based on: http://cs.brown.edu/people/pfelzens/dt/ * Adapted to work on Eigen objects directly @@ -85,33 +104,36 @@ void extractDistances(Eigen::Ref squareDistance1d, const std::v */ inline void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDistance1d, std::vector& lowerBounds) { - assert(lowerBounds.size() == squareDistance1d.size()); + assert(lowerBounds.size() >= squareDistance1d.size()); + + auto start = lastZero(squareDistance1d); - // If all distances are zero, then result remains all zeros - if ((squareDistance1d.array() > 0.0F).any()) { - auto startIt = fillLowerBounds(squareDistance1d, lowerBounds); - extractDistances(squareDistance1d, lowerBounds, startIt); + // Only need to process line if there are nonzero elements. Also the first zeros stay untouched. + if (start < squareDistance1d.size()) { + auto startIt = fillLowerBounds(squareDistance1d, lowerBounds, start); + extractDistances(squareDistance1d, lowerBounds, startIt, start); } } -void squaredDistanceTransform_2d_columnwiseInplace(grid_map::Matrix& squareDistance) { - const size_t n = squareDistance.rows(); - const size_t m = squareDistance.cols(); - std::vector lowerBounds(n); - - for (size_t i = 0; i < m; i++) { +void squaredDistanceTransform_2d_columnwiseInplace(grid_map::Matrix& squareDistance, std::vector& lowerBounds) { + const auto m = squareDistance.cols(); + for (Eigen::Index i = 0; i < m; ++i) { squaredDistanceTransform_1d_inplace(squareDistance.col(i), lowerBounds); } } -void computePixelDistance2d(grid_map::Matrix& squareDistance) { +void computePixelDistance2dTranspose(grid_map::Matrix& squareDistance) { + // Allocate a buffer big enough for processing both rowise and columnwise + const size_t n = squareDistance.rows(); + const size_t m = squareDistance.cols(); + std::vector lowerBounds(std::max(n, m)); + // Process columns - squaredDistanceTransform_2d_columnwiseInplace(squareDistance); + squaredDistanceTransform_2d_columnwiseInplace(squareDistance, lowerBounds); // Process rows squareDistance.transposeInPlace(); - squaredDistanceTransform_2d_columnwiseInplace(squareDistance); - squareDistance.transposeInPlace(); + squaredDistanceTransform_2d_columnwiseInplace(squareDistance, lowerBounds); // Convert square distance to absolute distance squareDistance = squareDistance.cwiseSqrt(); @@ -119,73 +141,88 @@ void computePixelDistance2d(grid_map::Matrix& squareDistance) { // Initialize with square distance in height direction in pixel units if above the surface grid_map::Matrix initializeObstacleDistance(const grid_map::Matrix& elevationMap, float height, float resolution) { - return elevationMap.unaryExpr([=](float elevation) { - if (height > elevation) { - const auto diff = (height - elevation) / resolution; - return diff * diff; - } else { - return 0.0F; - } - }); + /* Vectorized implementation of: + * if (height > elevation) { + * const auto diff = (height - elevation) / resolution; + * return diff * diff; + * } else { + * return 0.0F; + * } + */ + return ((1.0F / resolution) * (height - elevationMap.array()).cwiseMax(0.0F)).square(); } // Initialize with square distance in height direction in pixel units if below the surface grid_map::Matrix initializeObstacleFreeDistance(const grid_map::Matrix& elevationMap, float height, float resolution) { - return elevationMap.unaryExpr([=](float elevation) { - if (height < elevation) { - const auto diff = (height - elevation) / resolution; - return diff * diff; - } else { - return 0.0F; - } - }); + /* Vectorized implementation of: + * if (height < elevation) { + * const auto diff = (height - elevation) / resolution; + * return diff * diff; + * } else { + * return 0.0F; + * } + */ + return ((1.0F / resolution) * (height - elevationMap.array()).cwiseMin(0.0F)).square(); } -grid_map::Matrix pixelDistanceToFreeSpace(const grid_map::Matrix& elevationMap, float height, float resolution) { +grid_map::Matrix pixelDistanceToFreeSpaceTranspose(const grid_map::Matrix& elevationMap, float height, float resolution) { grid_map::Matrix sdfObstacleFree = internal::initializeObstacleFreeDistance(elevationMap, height, resolution); - internal::computePixelDistance2d(sdfObstacleFree); + internal::computePixelDistance2dTranspose(sdfObstacleFree); return sdfObstacleFree; } -grid_map::Matrix pixelDistanceToObstacle(const grid_map::Matrix& elevationMap, float height, float resolution) { +grid_map::Matrix pixelDistanceToObstacleTranspose(const grid_map::Matrix& elevationMap, float height, float resolution) { grid_map::Matrix sdfObstacle = internal::initializeObstacleDistance(elevationMap, height, resolution); - internal::computePixelDistance2d(sdfObstacle); + internal::computePixelDistance2dTranspose(sdfObstacle); return sdfObstacle; } +grid_map::Matrix signedDistanceFromOccupancyTranspose(const Eigen::Matrix& occupancyGrid, float resolution) { + // Compute pixel distance to obstacles + grid_map::Matrix sdfObstacle = occupancyGrid.unaryExpr([=](bool val) { return (val) ? 0.0F : INF; }); + internal::computePixelDistance2dTranspose(sdfObstacle); + + // Compute pixel distance to obstacle free space + grid_map::Matrix sdfObstacleFree = occupancyGrid.unaryExpr([=](bool val) { return (val) ? INF : 0.0F; }); + internal::computePixelDistance2dTranspose(sdfObstacleFree); + + grid_map::Matrix sdf2d = resolution * (sdfObstacle - sdfObstacleFree); + return sdf2d; +} + } // namespace internal -grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution, float minHeight, - float maxHeight) { +grid_map::Matrix signedDistanceAtHeightTranspose(const grid_map::Matrix& elevationMap, float height, float resolution, float minHeight, + float maxHeight) { const bool allPixelsAreObstacles = height < minHeight; const bool allPixelsAreFreeSpace = height > maxHeight; if (allPixelsAreObstacles) { - return -resolution * internal::pixelDistanceToFreeSpace(elevationMap, height, resolution); + return -resolution * internal::pixelDistanceToFreeSpaceTranspose(elevationMap, height, resolution); } else if (allPixelsAreFreeSpace) { - return resolution * internal::pixelDistanceToObstacle(elevationMap, height, resolution); + return resolution * internal::pixelDistanceToObstacleTranspose(elevationMap, height, resolution); } else { // This layer contains a mix of obstacles and free space - return resolution * (internal::pixelDistanceToObstacle(elevationMap, height, resolution) - - internal::pixelDistanceToFreeSpace(elevationMap, height, resolution)); + return resolution * (internal::pixelDistanceToObstacleTranspose(elevationMap, height, resolution) - + internal::pixelDistanceToFreeSpaceTranspose(elevationMap, height, resolution)); } } +grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution, float minHeight, + float maxHeight) { + grid_map::Matrix sdfTranspose = signedDistanceAtHeightTranspose(elevationMap, height, resolution, minHeight, maxHeight); + sdfTranspose.transposeInPlace(); + return sdfTranspose; +} + grid_map::Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution) { auto obstacleCount = occupancyGrid.count(); bool hasObstacles = obstacleCount > 0; if (hasObstacles) { bool hasFreeSpace = obstacleCount < occupancyGrid.size(); if (hasFreeSpace) { - // Compute pixel distance to obstacles - grid_map::Matrix sdfObstacle = occupancyGrid.unaryExpr([=](bool val) { return (val) ? 0.0F : INF; }); - internal::computePixelDistance2d(sdfObstacle); - - // Compute pixel distance to obstacle free space - grid_map::Matrix sdfObstacleFree = occupancyGrid.unaryExpr([=](bool val) { return (val) ? INF : 0.0F; }); - internal::computePixelDistance2d(sdfObstacleFree); - - grid_map::Matrix sdf2d = resolution * (sdfObstacle - sdfObstacleFree); - return sdf2d; + grid_map::Matrix sdfTranspose = internal::signedDistanceFromOccupancyTranspose(occupancyGrid, resolution); + sdfTranspose.transposeInPlace(); + return sdfTranspose; } else { // Only obstacles -> distance is minus infinity everywhere return grid_map::Matrix::Constant(occupancyGrid.rows(), occupancyGrid.cols(), -INF); From d21627e3b04aa35e0d579370d38f87e69ce7d3d2 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 2 Nov 2021 14:10:53 +0100 Subject: [PATCH 139/504] add test for derivatives --- .../test/testSignedDistance3d.cpp | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/signed_distance_field/test/testSignedDistance3d.cpp b/signed_distance_field/test/testSignedDistance3d.cpp index b846165d..1f08434e 100644 --- a/signed_distance_field/test/testSignedDistance3d.cpp +++ b/signed_distance_field/test/testSignedDistance3d.cpp @@ -79,4 +79,75 @@ TEST(testSignedDistance3d, randomTerrainInterpolation) { } } } +} + +TEST(testSignedDistance3d, randomTerrainDerivative) { + const int n = 10; + const int m = 20; + const float resolution = 0.1; + grid_map::GridMap map; + map.setGeometry({n * resolution, m * resolution}, resolution); + map.add("elevation"); + map.get("elevation").setRandom(); // random [-1.0, 1.0] + const grid_map::Matrix mapData = map.get("elevation"); + const float minHeight = mapData.minCoeff(); + const float maxHeight = mapData.maxCoeff(); + + signed_distance_field::GridmapSignedDistanceField sdf(map, "elevation", minHeight, maxHeight); + + // Check at different heights/ + int numLayers = (maxHeight - minHeight) / resolution; + for (int k = 0; k <= numLayers; ++k) { + const float height = minHeight + k * resolution; + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistanceAtHeight(mapData, height, resolution); + const auto naiveSignedDistanceNext = signed_distance_field::naiveSignedDistanceAtHeight(mapData, height + resolution, resolution); + const auto naiveSignedDistancePrevious = signed_distance_field::naiveSignedDistanceAtHeight(mapData, height - resolution, resolution); + + for (int i = 0; i < mapData.rows(); ++i) { + for (int j = 0; j < mapData.rows(); ++j) { + grid_map::Position position2d; + map.getPosition({i, j}, position2d); + const auto sdfderivative = sdf.valueAndDerivative(switched_model::vector3_t{position2d.x(), position2d.y(), height}); + const auto sdfCheck = naiveSignedDistance(i, j); + ASSERT_LT(std::abs(sdfderivative.first - sdfCheck), 1e-4); + + // Check finite difference + float dx = 0.0; + if (i > 0) { + if (i + 1 < mapData.rows()) { + dx = (naiveSignedDistance(i + 1, j) - naiveSignedDistance(i - 1, j)) / (-2.0 * resolution); + } else { + dx = (naiveSignedDistance(i, j) - naiveSignedDistance(i - 1, j)) / (-resolution); + } + } else { + dx = (naiveSignedDistance(i + 1, j) - naiveSignedDistance(i, j)) / (-resolution); + } + ASSERT_LT(std::abs(dx - sdfderivative.second.x()), 1e-4); + + float dy = 0.0; + if (j > 0) { + if (j + 1 < mapData.cols()) { + dy = (naiveSignedDistance(i, j + 1) - naiveSignedDistance(i, j - 1)) / (-2.0 * resolution); + } else { + dy = (naiveSignedDistance(i, j) - naiveSignedDistance(i, j - 1)) / (-resolution); + } + } else { + dy = (naiveSignedDistance(i, j + 1) - naiveSignedDistance(i, j)) / (-resolution); + } + ASSERT_LT(std::abs(dy - sdfderivative.second.y()), 1e-4); + + float dz = 0.0; + if (k > 0) { + if (k < numLayers) { + dz = (naiveSignedDistanceNext(i, j) - naiveSignedDistancePrevious(i, j)) / (2.0 * resolution); + } else { + dz = (naiveSignedDistance(i, j) - naiveSignedDistancePrevious(i, j)) / (resolution); + } + } else { + dz = (naiveSignedDistanceNext(i, j) - naiveSignedDistance(i, j)) / (resolution); + } + ASSERT_LT(std::abs(dz - sdfderivative.second.z()), 1e-4); + } + } + } } \ No newline at end of file From aa768469aefe8a066e579d44a076959595626e9a Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 2 Nov 2021 14:16:23 +0100 Subject: [PATCH 140/504] refactor to reduce temporaries in SDF computation --- .../DistanceDerivatives.h | 18 +- .../GridmapSignedDistanceField.h | 3 + .../PixelBorderDistance.h | 3 - .../signed_distance_field/SignedDistance2d.h | 14 +- .../src/GridmapSignedDistanceField.cpp | 89 ++++++---- .../src/SignedDistance2d.cpp | 161 ++++++++++++------ .../test/testDerivatives.cpp | 22 +-- 7 files changed, 190 insertions(+), 120 deletions(-) diff --git a/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h b/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h index d0e97a7d..eb37ac65 100644 --- a/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h +++ b/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h @@ -8,11 +8,10 @@ namespace signed_distance_field { -inline Eigen::MatrixXf columnwiseCentralDifference(const Eigen::MatrixXf& data, float resolution) { +inline void columnwiseCentralDifference(const Eigen::MatrixXf& data, Eigen::MatrixXf& centralDifference, float resolution) { assert(data.cols() >= 2); // Minimum size to take finite differences. const int m = data.cols(); - Eigen::MatrixXf centralDifference(data.rows(), data.cols()); // First column centralDifference.col(0) = (data.col(1) - data.col(0)) / resolution; @@ -25,21 +24,16 @@ inline Eigen::MatrixXf columnwiseCentralDifference(const Eigen::MatrixXf& data, // Last column centralDifference.col(m - 1) = (data.col(m - 1) - data.col(m - 2)) / resolution; - - return centralDifference; -} - -inline Eigen::MatrixXf rowwiseCentralDifference(const Eigen::MatrixXf& data, float resolution) { - return columnwiseCentralDifference(data.transpose(), resolution).transpose(); } -inline Eigen::MatrixXf layerFiniteDifference(const Eigen::MatrixXf& data_k, const Eigen::MatrixXf& data_kp1, float resolution) { - return (data_kp1 - data_k) / resolution; +inline void layerFiniteDifference(const Eigen::MatrixXf& data_k, const Eigen::MatrixXf& data_kp1, Eigen::MatrixXf& result, + float resolution) { + result = (1.0F / resolution) * (data_kp1 - data_k); } -inline Eigen::MatrixXf layerCentralDifference(const Eigen::MatrixXf& data_km1, const Eigen::MatrixXf& data_kp1, float resolution) { +inline void layerCentralDifference(const Eigen::MatrixXf& data_km1, const Eigen::MatrixXf& data_kp1, Eigen::MatrixXf& result, float resolution) { float doubleResolution = 2.0F * resolution; - return (data_kp1 - data_km1) / doubleResolution; + result = (1.0F / doubleResolution) * (data_kp1 - data_km1); } } // namespace signed_distance_field diff --git a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h index d803dfa6..927fa7a8 100644 --- a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h +++ b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h @@ -56,6 +56,9 @@ class GridmapSignedDistanceField : public switched_model::SignedDistanceField { private: GridmapSignedDistanceField(const GridmapSignedDistanceField& other); void computeSignedDistance(const grid_map::Matrix& elevation); + void computeLayerSdfandDeltaX(const grid_map::Matrix& elevation, grid_map::Matrix& currentLayer, grid_map::Matrix& dxTranspose, + grid_map::Matrix& sdfTranspose, grid_map::Matrix& tmp, grid_map::Matrix& tmpTranspose, + const float gridOriginZ, const float resolution, const float minHeight, const float maxHeight) const; void emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dxTranspose, const grid_map::Matrix& dy, const grid_map::Matrix& dz); diff --git a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h index c72db18e..bee0014e 100644 --- a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h +++ b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h @@ -26,9 +26,6 @@ inline float pixelBorderDistance(float i, float j) { * Returns square pixelBorderDistance, adding offset f. */ inline float squarePixelBorderDistance(float i, float j, float f) { - assert(i == j || - std::abs(i - j) >= 1.0F); // Check that i and j are proper pixel locations: either the same pixel or non-overlapping pixels - float d = pixelBorderDistance(i, j); return d * d + f; } diff --git a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h index e937ad3a..8f1b8709 100644 --- a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h +++ b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h @@ -27,9 +27,19 @@ grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, fl /** * Same as above, but returns the sdf in transposed form. + * Also takes temporary variables from outside to prevent memory allocation. + * + * @param elevationMap : elevation data. + * @param sdfTranspose : [output] resulting sdf in transposed form (automatically allocated if of wrong size) + * @param tmp : temporary of size elevationMap (automatically allocated if of wrong size) + * @param tmpTranspose : temporary of size elevationMap transpose (automatically allocated if of wrong size) + * @param height : height to generate the signed distance at. + * @param resolution : resolution of the elevation map. (The true distance [m] between cells in world frame) + * @param minHeight : the lowest height contained in elevationMap + * @param maxHeight : the maximum height contained in elevationMap */ -grid_map::Matrix signedDistanceAtHeightTranspose(const grid_map::Matrix& elevationMap, float height, float resolution, float minHeight, - float maxHeight); +void signedDistanceAtHeightTranspose(const grid_map::Matrix& elevationMap, grid_map::Matrix& sdfTranspose, grid_map::Matrix& tmp, + grid_map::Matrix& tmpTranspose, float height, float resolution, float minHeight, float maxHeight); grid_map::Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution); diff --git a/signed_distance_field/src/GridmapSignedDistanceField.cpp b/signed_distance_field/src/GridmapSignedDistanceField.cpp index de2a2e77..05666083 100644 --- a/signed_distance_field/src/GridmapSignedDistanceField.cpp +++ b/signed_distance_field/src/GridmapSignedDistanceField.cpp @@ -63,6 +63,11 @@ std::pair GridmapSignedDist } void GridmapSignedDistanceField::computeSignedDistance(const grid_map::Matrix& elevation) { + using signed_distance_field::columnwiseCentralDifference; + using signed_distance_field::layerCentralDifference; + using signed_distance_field::layerFiniteDifference; + using signed_distance_field::signedDistanceAtHeightTranspose; + const auto gridOriginZ = static_cast(gridmap3DLookup_.gridOrigin_.z()); const auto resolution = static_cast(gridmap3DLookup_.resolution_); const auto minHeight = elevation.minCoeff(); @@ -73,58 +78,80 @@ void GridmapSignedDistanceField::computeSignedDistance(const grid_map::Matrix& e * - SDF at a height is in transposed form after computing it. * - Take the finite difference in dx, now that this data is continuous in memory. * - Transpose the SDF - * - Take other finite differences, now dy is efficient. + * - Take other finite differences. Now dy is efficient. * - When writing to the 3D structure, keep in mind that dx is still transposed. */ - // First layer: forward difference in z - grid_map::Matrix currentLayer = - signed_distance_field::signedDistanceAtHeightTranspose(elevation, gridOriginZ, resolution, minHeight, maxHeight); - grid_map::Matrix dxTranspose = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); // dx / drow = -resolution - currentLayer.transposeInPlace(); + // Memory needed to compute the SDF at a layer + grid_map::Matrix tmp; // allocated on first use + grid_map::Matrix tmpTranspose; // allocated on first use + grid_map::Matrix sdfTranspose; // allocated on first use + + // Memory needed to keep a buffer of layers. We need 3 due to the central difference + grid_map::Matrix currentLayer; // allocated on first use + grid_map::Matrix nextLayer; // allocated on first use + grid_map::Matrix previousLayer; // allocated on first use - grid_map::Matrix nextLayer = - signed_distance_field::signedDistanceAtHeightTranspose(elevation, gridOriginZ + resolution, resolution, minHeight, maxHeight); - grid_map::Matrix dxNextTranspose = signed_distance_field::columnwiseCentralDifference(nextLayer, -resolution); - nextLayer.transposeInPlace(); + // Memory needed to compute finite differences + grid_map::Matrix dxTranspose = grid_map::Matrix::Zero(elevation.cols(), elevation.rows()); + grid_map::Matrix dxNextTranspose = grid_map::Matrix::Zero(elevation.cols(), elevation.rows()); + grid_map::Matrix dy = grid_map::Matrix::Zero(elevation.rows(), elevation.cols()); + grid_map::Matrix dz = grid_map::Matrix::Zero(elevation.rows(), elevation.cols()); - grid_map::Matrix dz = signed_distance_field::layerFiniteDifference(currentLayer, nextLayer, resolution); // dz / layer = +resolution - grid_map::Matrix dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); // dy / dcol = -resolution + // Compute SDF of first layer + computeLayerSdfandDeltaX(elevation, currentLayer, dxTranspose, sdfTranspose, tmp, tmpTranspose, gridOriginZ, resolution, minHeight, + maxHeight); + + // Compute SDF of second layer + computeLayerSdfandDeltaX(elevation, nextLayer, dxNextTranspose, sdfTranspose, tmp, tmpTranspose, gridOriginZ + resolution, resolution, + minHeight, maxHeight); + + // First layer: forward difference in z + layerFiniteDifference(currentLayer, nextLayer, dz, resolution); // dz / layer = +resolution + columnwiseCentralDifference(currentLayer, dy, -resolution); // dy / dcol = -resolution emplacebackLayerData(currentLayer, dxTranspose, dy, dz); // Middle layers: central difference in z for (size_t layerZ = 1; layerZ + 1 < gridmap3DLookup_.gridsize_.z; ++layerZ) { - grid_map::Matrix previousLayer = std::move(currentLayer); - currentLayer = std::move(nextLayer); - dxTranspose = std::move(dxNextTranspose); + // Circulate layer buffers + previousLayer.swap(currentLayer); + currentLayer.swap(nextLayer); + dxTranspose.swap(dxNextTranspose); - // Compute next layer transposed - nextLayer = signed_distance_field::signedDistanceAtHeightTranspose(elevation, gridOriginZ + (layerZ + 1) * resolution, resolution, - minHeight, maxHeight); - - // Take dx here, so we can operate on columns before transposing - dxNextTranspose = signed_distance_field::columnwiseCentralDifference(nextLayer, -resolution); - - // Transpose the data - nextLayer.transposeInPlace(); + // Compute SDF of next layer + computeLayerSdfandDeltaX(elevation, nextLayer, dxNextTranspose, sdfTranspose, tmp, tmpTranspose, + gridOriginZ + (layerZ + 1) * resolution, resolution, minHeight, maxHeight); // Compute other finite differences - dz = signed_distance_field::layerCentralDifference(previousLayer, nextLayer, resolution); - dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); + layerCentralDifference(previousLayer, nextLayer, dz, resolution); + columnwiseCentralDifference(currentLayer, dy, -resolution); // Add the data to the 3D structure emplacebackLayerData(currentLayer, dxTranspose, dy, dz); } + // Circulate layer buffers on last time + previousLayer.swap(currentLayer); + currentLayer.swap(nextLayer); + dxTranspose.swap(dxNextTranspose); + // Last layer: backward difference in z - grid_map::Matrix previousLayer = std::move(currentLayer); - currentLayer = std::move(nextLayer); - dxTranspose = std::move(dxNextTranspose); - dz = signed_distance_field::layerCentralDifference(previousLayer, currentLayer, resolution); - dy = signed_distance_field::columnwiseCentralDifference(currentLayer, -resolution); + layerFiniteDifference(previousLayer, currentLayer, dz, resolution); + columnwiseCentralDifference(currentLayer, dy, -resolution); + + // Add the data to the 3D structure emplacebackLayerData(currentLayer, dxTranspose, dy, dz); } +void GridmapSignedDistanceField::computeLayerSdfandDeltaX(const grid_map::Matrix& elevation, grid_map::Matrix& currentLayer, + grid_map::Matrix& dxTranspose, grid_map::Matrix& sdfTranspose, + grid_map::Matrix& tmp, grid_map::Matrix& tmpTranspose, const float gridOriginZ, + const float resolution, const float minHeight, const float maxHeight) const { + // Compute SDF + dx of layer: compute sdfTranspose -> take dxTranspose -> transpose to get sdf + signedDistanceAtHeightTranspose(elevation, sdfTranspose, tmp, tmpTranspose, gridOriginZ, resolution, minHeight, maxHeight); + columnwiseCentralDifference(sdfTranspose, dxTranspose, -resolution); // dx / drow = -resolution + currentLayer = sdfTranspose.transpose(); +} void GridmapSignedDistanceField::emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dxdxTranspose, const grid_map::Matrix& dy, const grid_map::Matrix& dz) { diff --git a/signed_distance_field/src/SignedDistance2d.cpp b/signed_distance_field/src/SignedDistance2d.cpp index edfc3b21..e4248770 100644 --- a/signed_distance_field/src/SignedDistance2d.cpp +++ b/signed_distance_field/src/SignedDistance2d.cpp @@ -16,6 +16,12 @@ struct DistanceLowerBound { float z_rhs; // rhs of interval where this lower bound holds }; +/** + * 1D Euclidean Distance Transform based on: http://cs.brown.edu/people/pfelzens/dt/ + * Adapted to work on Eigen objects directly + * Optimized computation of s. + * Some optimization to not keep track of bounds that lie fully outside the grid. + */ std::vector::iterator fillLowerBounds(const Eigen::Ref& squareDistance1d, std::vector& lowerBounds, Eigen::Index start) { const auto n = squareDistance1d.size(); @@ -57,7 +63,7 @@ std::vector::iterator fillLowerBounds(const Eigen::Ref squareDistance1d, const std::vector& lowerBounds, +void extractSquareDistances(Eigen::Ref squareDistance1d, const std::vector& lowerBounds, std::vector::const_iterator lowerBoundIt, Eigen::Index start) { const auto n = squareDistance1d.size(); @@ -82,7 +88,39 @@ void extractDistances(Eigen::Ref squareDistance1d, const std::v } } -Eigen::Index lastZero(const Eigen::Ref& squareDistance1d) { +/** + * Same as extractSquareDistances, but takes the sqrt as a final step. + * Because several cells will have a value of 0.0 (obstacle / free space label), we can skip the sqrt computation for those. + */ +void extractDistances(Eigen::Ref squareDistance1d, const std::vector& lowerBounds, + std::vector::const_iterator lowerBoundIt, Eigen::Index start) { + const auto n = squareDistance1d.size(); + + // Store active bound by value to remove indirection + auto lastz = lowerBoundIt->z_rhs; + + auto qFloat = static_cast(start); + for (Eigen::Index q = start; q < n; ++q) { + if (squareDistance1d[q] > 0.0F) { // Observe that if squareDistance1d[q] == 0.0, this is already the minimum and it will stay 0.0 + // Find the new active lower bound if q no longer belongs to current interval + if (qFloat > lastz) { + do { + ++lowerBoundIt; + } while (lowerBoundIt->z_rhs < qFloat); + lastz = lowerBoundIt->z_rhs; + } + + squareDistance1d[q] = std::sqrt(squarePixelBorderDistance(qFloat, lowerBoundIt->v, lowerBoundIt->f)); + } + + qFloat += 1.0F; + } +} + +/** + * Find the location of the last zero value from the front + */ +Eigen::Index lastZeroFromFront(const Eigen::Ref& squareDistance1d) { const auto n = squareDistance1d.size(); for (Eigen::Index q = 0; q < n; ++q) { @@ -97,50 +135,60 @@ Eigen::Index lastZero(const Eigen::Ref& squareDistance1d) { return n; } -/** - * 1D Euclidean Distance Transform based on: http://cs.brown.edu/people/pfelzens/dt/ - * Adapted to work on Eigen objects directly - * Optimized computation of s - */ inline void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDistance1d, std::vector& lowerBounds) { assert(lowerBounds.size() >= squareDistance1d.size()); - auto start = lastZero(squareDistance1d); + auto start = lastZeroFromFront(squareDistance1d); // Only need to process line if there are nonzero elements. Also the first zeros stay untouched. if (start < squareDistance1d.size()) { auto startIt = fillLowerBounds(squareDistance1d, lowerBounds, start); - extractDistances(squareDistance1d, lowerBounds, startIt, start); + extractSquareDistances(squareDistance1d, lowerBounds, startIt, start); } } -void squaredDistanceTransform_2d_columnwiseInplace(grid_map::Matrix& squareDistance, std::vector& lowerBounds) { - const auto m = squareDistance.cols(); - for (Eigen::Index i = 0; i < m; ++i) { - squaredDistanceTransform_1d_inplace(squareDistance.col(i), lowerBounds); +/** + * Same as above, but takes sqrt as final step (within the same loop) + * @param squareDistance1d : input as squared distance, output is the distance after sqrt. + * @param lowerBounds : work vector + */ +inline void distanceTransform_1d_inplace(Eigen::Ref squareDistance1d, + std::vector& lowerBounds) { + assert(lowerBounds.size() >= squareDistance1d.size()); + + auto start = lastZeroFromFront(squareDistance1d); + + // Only need to process line if there are nonzero elements. Also the first zeros stay untouched. + if (start < squareDistance1d.size()) { + auto startIt = fillLowerBounds(squareDistance1d, lowerBounds, start); + extractDistances(squareDistance1d, lowerBounds, startIt, start); } } -void computePixelDistance2dTranspose(grid_map::Matrix& squareDistance) { +void computePixelDistance2dTranspose(grid_map::Matrix& input, grid_map::Matrix& distanceTranspose) { + const size_t n = input.rows(); + const size_t m = input.cols(); + // Allocate a buffer big enough for processing both rowise and columnwise - const size_t n = squareDistance.rows(); - const size_t m = squareDistance.cols(); std::vector lowerBounds(std::max(n, m)); // Process columns - squaredDistanceTransform_2d_columnwiseInplace(squareDistance, lowerBounds); - - // Process rows - squareDistance.transposeInPlace(); - squaredDistanceTransform_2d_columnwiseInplace(squareDistance, lowerBounds); + for (Eigen::Index i = 0; i < m; ++i) { + squaredDistanceTransform_1d_inplace(input.col(i), lowerBounds); + } - // Convert square distance to absolute distance - squareDistance = squareDistance.cwiseSqrt(); + // Process rows (= columns after transpose). + distanceTranspose = input.transpose(); + for (Eigen::Index i = 0; i < n; ++i) { + // Fuses square distance algorithm and taking sqrt. + distanceTransform_1d_inplace(distanceTranspose.col(i), lowerBounds); + } } // Initialize with square distance in height direction in pixel units if above the surface -grid_map::Matrix initializeObstacleDistance(const grid_map::Matrix& elevationMap, float height, float resolution) { +void initializeObstacleDistance(const grid_map::Matrix& elevationMap, grid_map::Matrix& result, float height, + float resolution) { /* Vectorized implementation of: * if (height > elevation) { * const auto diff = (height - elevation) / resolution; @@ -149,11 +197,12 @@ grid_map::Matrix initializeObstacleDistance(const grid_map::Matrix& elevationMap * return 0.0F; * } */ - return ((1.0F / resolution) * (height - elevationMap.array()).cwiseMax(0.0F)).square(); + result = ((1.0F / resolution) * (height - elevationMap.array()).cwiseMax(0.0F)).square(); } // Initialize with square distance in height direction in pixel units if below the surface -grid_map::Matrix initializeObstacleFreeDistance(const grid_map::Matrix& elevationMap, float height, float resolution) { +void initializeObstacleFreeDistance(const grid_map::Matrix& elevationMap, grid_map::Matrix& result, float height, + float resolution) { /* Vectorized implementation of: * if (height < elevation) { * const auto diff = (height - elevation) / resolution; @@ -162,56 +211,66 @@ grid_map::Matrix initializeObstacleFreeDistance(const grid_map::Matrix& elevatio * return 0.0F; * } */ - return ((1.0F / resolution) * (height - elevationMap.array()).cwiseMin(0.0F)).square(); + result = ((1.0F / resolution) * (height - elevationMap.array()).cwiseMin(0.0F)).square(); } -grid_map::Matrix pixelDistanceToFreeSpaceTranspose(const grid_map::Matrix& elevationMap, float height, float resolution) { - grid_map::Matrix sdfObstacleFree = internal::initializeObstacleFreeDistance(elevationMap, height, resolution); - internal::computePixelDistance2dTranspose(sdfObstacleFree); - return sdfObstacleFree; +void pixelDistanceToFreeSpaceTranspose(const grid_map::Matrix& elevationMap, grid_map::Matrix& sdfObstacleFree, grid_map::Matrix& tmp, float height, + float resolution) { + internal::initializeObstacleFreeDistance(elevationMap, tmp, height, resolution); + internal::computePixelDistance2dTranspose(tmp, sdfObstacleFree); } -grid_map::Matrix pixelDistanceToObstacleTranspose(const grid_map::Matrix& elevationMap, float height, float resolution) { - grid_map::Matrix sdfObstacle = internal::initializeObstacleDistance(elevationMap, height, resolution); - internal::computePixelDistance2dTranspose(sdfObstacle); - return sdfObstacle; +void pixelDistanceToObstacleTranspose(const grid_map::Matrix& elevationMap, grid_map::Matrix& sdfObstacleTranspose, grid_map::Matrix& tmp, float height, + float resolution) { + internal::initializeObstacleDistance(elevationMap, tmp, height, resolution); + internal::computePixelDistance2dTranspose(tmp, sdfObstacleTranspose); } grid_map::Matrix signedDistanceFromOccupancyTranspose(const Eigen::Matrix& occupancyGrid, float resolution) { // Compute pixel distance to obstacles - grid_map::Matrix sdfObstacle = occupancyGrid.unaryExpr([=](bool val) { return (val) ? 0.0F : INF; }); - internal::computePixelDistance2dTranspose(sdfObstacle); + grid_map::Matrix sdfObstacle; + grid_map::Matrix init = occupancyGrid.unaryExpr([=](bool val) { return (val) ? 0.0F : INF; }); + internal::computePixelDistance2dTranspose(init, sdfObstacle); // Compute pixel distance to obstacle free space - grid_map::Matrix sdfObstacleFree = occupancyGrid.unaryExpr([=](bool val) { return (val) ? INF : 0.0F; }); - internal::computePixelDistance2dTranspose(sdfObstacleFree); + grid_map::Matrix sdfObstacleFree; + init = occupancyGrid.unaryExpr([=](bool val) { return (val) ? INF : 0.0F; }); + internal::computePixelDistance2dTranspose(init, sdfObstacleFree); - grid_map::Matrix sdf2d = resolution * (sdfObstacle - sdfObstacleFree); - return sdf2d; + return resolution * (sdfObstacle - sdfObstacleFree); } } // namespace internal -grid_map::Matrix signedDistanceAtHeightTranspose(const grid_map::Matrix& elevationMap, float height, float resolution, float minHeight, +void signedDistanceAtHeightTranspose(const grid_map::Matrix& elevationMap, grid_map::Matrix& sdfTranspose, grid_map::Matrix& tmp, grid_map::Matrix& tmpTranspose, float height, float resolution, float minHeight, float maxHeight) { const bool allPixelsAreObstacles = height < minHeight; const bool allPixelsAreFreeSpace = height > maxHeight; if (allPixelsAreObstacles) { - return -resolution * internal::pixelDistanceToFreeSpaceTranspose(elevationMap, height, resolution); + internal::pixelDistanceToFreeSpaceTranspose(elevationMap, sdfTranspose, tmp, height, resolution); + + sdfTranspose *= -resolution; } else if (allPixelsAreFreeSpace) { - return resolution * internal::pixelDistanceToObstacleTranspose(elevationMap, height, resolution); + internal::pixelDistanceToObstacleTranspose(elevationMap, sdfTranspose, tmp, height, resolution); + + sdfTranspose *= resolution; } else { // This layer contains a mix of obstacles and free space - return resolution * (internal::pixelDistanceToObstacleTranspose(elevationMap, height, resolution) - - internal::pixelDistanceToFreeSpaceTranspose(elevationMap, height, resolution)); + internal::pixelDistanceToObstacleTranspose(elevationMap, sdfTranspose, tmp, height, resolution); + internal::pixelDistanceToFreeSpaceTranspose(elevationMap, tmpTranspose, tmp, height, resolution); + + sdfTranspose = resolution * (sdfTranspose - tmpTranspose); } } grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution, float minHeight, float maxHeight) { - grid_map::Matrix sdfTranspose = signedDistanceAtHeightTranspose(elevationMap, height, resolution, minHeight, maxHeight); - sdfTranspose.transposeInPlace(); - return sdfTranspose; + grid_map::Matrix sdfTranspose; + grid_map::Matrix tmp; + grid_map::Matrix tmpTranspose; + + signedDistanceAtHeightTranspose(elevationMap, sdfTranspose, tmp, tmpTranspose, height, resolution, minHeight, maxHeight); + return sdfTranspose.transpose(); } grid_map::Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution) { @@ -220,9 +279,7 @@ grid_map::Matrix signedDistanceFromOccupancy(const Eigen::Matrix& if (hasObstacles) { bool hasFreeSpace = obstacleCount < occupancyGrid.size(); if (hasFreeSpace) { - grid_map::Matrix sdfTranspose = internal::signedDistanceFromOccupancyTranspose(occupancyGrid, resolution); - sdfTranspose.transposeInPlace(); - return sdfTranspose; + return internal::signedDistanceFromOccupancyTranspose(occupancyGrid, resolution).transpose(); } else { // Only obstacles -> distance is minus infinity everywhere return grid_map::Matrix::Constant(occupancyGrid.rows(), occupancyGrid.cols(), -INF); diff --git a/signed_distance_field/test/testDerivatives.cpp b/signed_distance_field/test/testDerivatives.cpp index f56c35b7..538a3505 100644 --- a/signed_distance_field/test/testDerivatives.cpp +++ b/signed_distance_field/test/testDerivatives.cpp @@ -18,26 +18,8 @@ TEST(testDerivatives, columnwise) { manualDifference << 1.0 /resolution, 3.0 /doubleResolution, 2.0 /resolution, 2.0 /resolution, 4.0 /doubleResolution, 2.0 /resolution; - const auto computedDifference = signed_distance_field::columnwiseCentralDifference(data, resolution); + Eigen::MatrixXf computedDifference = Eigen::MatrixXf::Zero(data.rows(), data.cols()); + signed_distance_field::columnwiseCentralDifference(data, computedDifference, resolution); ASSERT_TRUE(manualDifference.isApprox(computedDifference)); } - -TEST(testDerivatives, rowwise) { - Eigen::MatrixXf data(3, 2); - data << 1.0, 2.0, - 4.0, 2.0, - 4.0, 6.0; - - float resolution = 0.1; - float doubleResolution = 2.0F * resolution; - - Eigen::MatrixXf manualDifference(3, 2); - manualDifference << 3.0 /resolution, 0.0 /resolution, - 3.0 /doubleResolution, 4.0 /doubleResolution, - 0.0 /resolution, 4.0 /resolution; - - const auto computedDifference = signed_distance_field::rowwiseCentralDifference(data, resolution); - - ASSERT_TRUE(manualDifference.isApprox(computedDifference)); -} \ No newline at end of file From 69eef105aaeed016ae49206d3f9acbd3d6c37b23 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 4 Nov 2021 10:32:38 +0100 Subject: [PATCH 141/504] Fix extraction of plane parameters after RANSAC. Get plane from RANSAC results directly --- .../ransac/RansacPlaneExtractor.hpp | 6 ++++ .../src/ransac/RansacPlaneExtractor.cpp | 16 +++++++++++ .../SlidingWindowPlaneExtractor.cpp | 28 ++++++------------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp index 8a9ad54d..ca76b89d 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp +++ b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp @@ -2,6 +2,8 @@ #include +#include + #include #include #include @@ -24,6 +26,7 @@ using NormalMap = CGAL::Second_of_pair_property_map; using Traits = CGAL::Shape_detection::Efficient_RANSAC_traits; using EfficientRansac = CGAL::Shape_detection::Efficient_RANSAC; using Plane = CGAL::Shape_detection::Plane; +using Shape = CGAL::Shape_detection::Shape_base; class RansacPlaneExtractor { public: @@ -33,6 +36,9 @@ class RansacPlaneExtractor { void detectPlanes(std::vector& points_with_normal); + /// Return {plane normal, support vector} for the detected shape + static std::pair getPlaneParameters(Shape* shapePtr); + /// Returns an iterator range. Data is still in the ransac_object EfficientRansac::Shape_range getDetectedPlanes() const { return ransac_.shapes(); }; diff --git a/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp b/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp index b035af32..a977c31e 100644 --- a/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp @@ -20,4 +20,20 @@ void RansacPlaneExtractor::detectPlanes(std::vector& points_wit ransac_.detect(cgalRansacParameters_); } +std::pair RansacPlaneExtractor::getPlaneParameters(Shape* shapePtr) { + const auto* planePtr = static_cast(shapePtr); + + // Get Normal, pointing upwards + Eigen::Vector3d normalVector(planePtr->plane_normal().x(), planePtr->plane_normal().y(), planePtr->plane_normal().z()); + if (normalVector.z() < 0.0) { + normalVector = -normalVector; + } + + // Project origin to get a point on the plane. + const auto support = planePtr->projection({0.0, 0.0, 0.0}); + const Eigen::Vector3d supportVector(support.x(), support.y(), support.z()); + + return {normalVector, supportVector}; +} + } // namespace ransac_plane_extractor diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index 4b58285a..9ba4c54d 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -234,32 +234,20 @@ void SlidingWindowPlaneExtractor::refineLabelWithRansac(int label, std::vector& plane_point_indices = plane->indices_of_assigned_points(); - Eigen::Vector3d sum = Eigen::Vector3d::Zero(); - Eigen::Matrix3d sumSquared = Eigen::Matrix3d::Zero(); - for (const auto index : plane_point_indices) { - const auto& point = pointsWithNormal[index].first; - const Eigen::Vector3d point3d(point.x(), point.y(), point.z()); - - sum += point3d; - sumSquared.noalias() += point3d * point3d.transpose(); - } - - const auto numPoints = plane_point_indices.size(); - const Eigen::Vector3d supportVector = sum / numPoints; - const Eigen::Vector3d normalVector = normalAndErrorFromCovariance(numPoints, supportVector, sumSquared).first; + const auto planeInfo = ransac_plane_extractor::RansacPlaneExtractor::getPlaneParameters(plane.get()); + const auto& normalVector = planeInfo.first; + const auto& supportVector = planeInfo.second; if (isWithinInclinationLimit(normalVector)) { + // Bookkeeping of labels : reuse old label for the first plane + const int newLabel = (reuseLabel) ? label : ++segmentedPlanesMap_.highestLabel; + reuseLabel = false; + const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); segmentedPlanesMap_.labelPlaneParameters.emplace_back(newLabel, TerrainPlane(supportVector, terrainOrientation)); // Assign label in segmentation - for (const auto index : plane_point_indices) { + for (const auto index : plane->indices_of_assigned_points()) { const auto& point = pointsWithNormal[index].first; // Need to lookup indices in map, because RANSAC has reordered the points From 94e3b1278dd313ae984cbf49fd38c24bbfb62077 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 23 Nov 2021 10:24:55 +0100 Subject: [PATCH 142/504] add raw map to visualization --- .../src/ConvexPlaneDecompositionRos.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 87c1118d..f23e7e82 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -113,6 +113,7 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { return; } ROS_INFO("...done."); + const auto elevationRaw = elevationMap.get(elevationLayer_); auto t0 = std::chrono::high_resolution_clock::now(); preprocessing_->preprocess(elevationMap, elevationLayer_); @@ -150,6 +151,8 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { } // --- Visualize in Rviz --- Not published to the controller + // Add raw map + planarTerrain.gridMap.add("elevation_raw", elevationRaw); // Add surface normals slidingWindowPlaneExtractor_->addSurfaceNormalToMap(planarTerrain.gridMap, "normal"); From 2a6aa6776581e962d9ca32fd7d2ac0b185ca2bdc Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 1 Dec 2021 15:49:03 +0100 Subject: [PATCH 143/504] adapt smoothing size after changing reference generation --- convex_plane_decomposition_ros/config/parameters.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 46a41500..0ecc3d1d 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -31,5 +31,5 @@ postprocessing: nonplanar_height_offset: 0.02 # Added offset in Z direction for non-planar cells of the map. (Additional to extracted_planes_height_offset) nonplanar_horizontal_offset: 1 # Added offset in XY direction for non-planar cells of the map. In number of pixels. smoothing_dilation_size: 0.2 # Half the width of the dilation used before the smooth layer [m] - smoothing_box_kernel_size: 0.2 # Half the width of the box kernel used for the smooth layer [m] + smoothing_box_kernel_size: 0.1 # Half the width of the box kernel used for the smooth layer [m] smoothing_gauss_kernel_size: 0.05 # Half the width of the Gaussian kernel used for the smooth layer [m] \ No newline at end of file From 376215d1bd4f6410c9fbd158af73b78dcc4aeb65 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 6 Dec 2021 19:36:39 +0100 Subject: [PATCH 144/504] copy shared library instead of building from source --- pcl_catkin/CMakeLists.txt | 28 ++++++------------ pcl_catkin/README.md | 3 +- pcl_catkin/cmake/pcl-extras.cmake.in | 3 -- pcl_catkin/lib/libpcl_visualization.so.1.10 | Bin 0 -> 1747408 bytes pcl_catkin/lib/libpcl_visualization.so.1.10.0 | Bin 0 -> 1747408 bytes .../lib/pkgconfig/pcl_visualization-1.10.pc | 13 ++++++++ 6 files changed, 24 insertions(+), 23 deletions(-) delete mode 100644 pcl_catkin/cmake/pcl-extras.cmake.in create mode 100644 pcl_catkin/lib/libpcl_visualization.so.1.10 create mode 100644 pcl_catkin/lib/libpcl_visualization.so.1.10.0 create mode 100644 pcl_catkin/lib/pkgconfig/pcl_visualization-1.10.pc diff --git a/pcl_catkin/CMakeLists.txt b/pcl_catkin/CMakeLists.txt index f9db00da..00484962 100644 --- a/pcl_catkin/CMakeLists.txt +++ b/pcl_catkin/CMakeLists.txt @@ -3,29 +3,19 @@ project(pcl_catkin) find_package(catkin REQUIRED) -include(ExternalProject) +file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so.1.10 DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so.1.10.0 DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) -set(VERSION 1.10.0) - -file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/include) - -set(PCL_VERSION 1.10.0) -ExternalProject_Add(pcl - URL https://github.com/PointCloudLibrary/pcl/archive/pcl-${PCL_VERSION}.tar.gz - UPDATE_COMMAND "" - CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX=${CATKIN_DEVEL_PREFIX} - -DCMAKE_BUILD_TYPE:STRING=Release - BUILD_COMMAND $(MAKE) - INSTALL_COMMAND $(MAKE) install -) +file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib/pkgconfig) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/pkgconfig/pcl_visualization-1.10.pc DESTINATION ${CATKIN_DEVEL_PREFIX}/lib/pkgconfig) catkin_package( - INCLUDE_DIRS ${CATKIN_DEVEL_PREFIX}/include - CFG_EXTRAS pcl-extras.cmake + INCLUDE_DIRS ) -install(DIRECTORY ${CATKIN_DEVEL_PREFIX}/include/pcl-1.10/pcl/ - DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/pcl/ +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib + DESTINATION ${CMAKE_INSTALL_LIBDIR} ) diff --git a/pcl_catkin/README.md b/pcl_catkin/README.md index a8b07986..bba5b2ad 100644 --- a/pcl_catkin/README.md +++ b/pcl_catkin/README.md @@ -1,2 +1,3 @@ # pcl_catkin -Catkin wrapper of the Point Cloud Library (PCL) +Catkin wrapper of the visualization part of Point Cloud Library (PCL) +Just copies the shared library into the catkin workspace. \ No newline at end of file diff --git a/pcl_catkin/cmake/pcl-extras.cmake.in b/pcl_catkin/cmake/pcl-extras.cmake.in deleted file mode 100644 index 3dc8a6c5..00000000 --- a/pcl_catkin/cmake/pcl-extras.cmake.in +++ /dev/null @@ -1,3 +0,0 @@ -# Cpp standard version -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) \ No newline at end of file diff --git a/pcl_catkin/lib/libpcl_visualization.so.1.10 b/pcl_catkin/lib/libpcl_visualization.so.1.10 new file mode 100644 index 0000000000000000000000000000000000000000..0ddc619760db1b0231a09856a6b147658faefff8 GIT binary patch literal 1747408 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%0A}P_+_$9Nw;1~`1Go}Lq*lRzOkbG8 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�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

FM73XU%g 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 literal 0 HcmV?d00001 diff --git a/pcl_catkin/lib/libpcl_visualization.so.1.10.0 b/pcl_catkin/lib/libpcl_visualization.so.1.10.0 new file mode 100644 index 0000000000000000000000000000000000000000..0ddc619760db1b0231a09856a6b147658faefff8 GIT binary patch literal 1747408 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%0A}P_+_$9Nw;1~`1Go}Lq*lRzOkbG8 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�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

FM73XU%g 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 literal 0 HcmV?d00001 diff --git a/pcl_catkin/lib/pkgconfig/pcl_visualization-1.10.pc b/pcl_catkin/lib/pkgconfig/pcl_visualization-1.10.pc new file mode 100644 index 00000000..49fb4aee --- /dev/null +++ b/pcl_catkin/lib/pkgconfig/pcl_visualization-1.10.pc @@ -0,0 +1,13 @@ +# This file was generated by CMake for PCL library pcl_visualization +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib/x86_64-linux-gnu +#includedir=${prefix}/include/pcl-1.10/pcl +includedir=${prefix}/include/pcl-1.10 +Name: pcl_visualization +Description: Point cloud visualization library +Version: 1.10.0 +Requires: libopenni libopenni2 pcl_common-1.10 pcl_io-1.10 pcl_kdtree-1.10 pcl_geometry-1.10 pcl_search-1.10 pcl_octree-1.10 +Libs: -L${libdir} -lpcl_visualization +Cflags: -I${includedir} + From e1ab2aaf5e9da7a474bee585f18f09f48514098b Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 6 Dec 2021 19:52:06 +0100 Subject: [PATCH 145/504] . --- pcl_catkin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcl_catkin/README.md b/pcl_catkin/README.md index bba5b2ad..36bf8783 100644 --- a/pcl_catkin/README.md +++ b/pcl_catkin/README.md @@ -1,3 +1,3 @@ # pcl_catkin -Catkin wrapper of the visualization part of Point Cloud Library (PCL) +Catkin wrapper of the visualization part of Point Cloud Library (PCL). Just copies the shared library into the catkin workspace. \ No newline at end of file From 0aaabf87aaa3a50eadba5a07e520ab0c1cd62f91 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 6 Dec 2021 19:58:53 +0100 Subject: [PATCH 146/504] un-ignore the shared library --- pcl_catkin/.gitignore | 32 ------------------------- pcl_catkin/lib/libpcl_visualization.so | Bin 0 -> 1747408 bytes 2 files changed, 32 deletions(-) delete mode 100644 pcl_catkin/.gitignore create mode 100644 pcl_catkin/lib/libpcl_visualization.so diff --git a/pcl_catkin/.gitignore b/pcl_catkin/.gitignore deleted file mode 100644 index 259148fa..00000000 --- a/pcl_catkin/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app diff --git a/pcl_catkin/lib/libpcl_visualization.so b/pcl_catkin/lib/libpcl_visualization.so new file mode 100644 index 0000000000000000000000000000000000000000..0ddc619760db1b0231a09856a6b147658faefff8 GIT binary patch literal 1747408 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%0A}P_+_$9Nw;1~`1Go}Lq*lRzOkbG8 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�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

FM73XU%g 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 literal 0 HcmV?d00001 From 9bd1707ebd558b0e6d72937a1b9d1c6516266364 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Dec 2021 10:10:36 +0100 Subject: [PATCH 147/504] make matrix type explicit. Produced corrupted data before --- .../src/ConvexPlaneDecompositionRos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index f23e7e82..e00518b3 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -113,7 +113,7 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { return; } ROS_INFO("...done."); - const auto elevationRaw = elevationMap.get(elevationLayer_); + const grid_map::Matrix elevationRaw = elevationMap.get(elevationLayer_); auto t0 = std::chrono::high_resolution_clock::now(); preprocessing_->preprocess(elevationMap, elevationLayer_); From 7d3f66c862313c52e617be53976810cb3672dd0f Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Dec 2021 19:04:08 +0100 Subject: [PATCH 148/504] formatting --- .../src/ConvexPlaneDecompositionRos.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index e00518b3..6a23dc3b 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -130,8 +130,6 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { auto t3 = std::chrono::high_resolution_clock::now(); ROS_INFO_STREAM("Contour extraction took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]"); - - // Add grid map to the terrain planarTerrain.gridMap = std::move(elevationMap); From b6128ece325ba5859d8949dbc44cd098d2864233 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 9 Dec 2021 12:02:23 +0100 Subject: [PATCH 149/504] add penalty function to terrain selection --- .../SegmentedPlaneProjection.h | 6 ++++-- .../SegmentedPlanesTerrainModel.h | 10 +++++----- .../src/SegmentedPlaneProjection.cpp | 11 ++++++----- .../src/SegmentedPlanesTerrainModel.cpp | 12 ++++++++---- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h index 07df944f..f8779221 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h @@ -18,7 +18,8 @@ double distanceCostLowerbound(double distanceSquared); double intervalSquareDistance(double value, double min, double max); -double squaredDistanceToBoundingBox(const convex_plane_decomposition::CgalPoint2d& point, const convex_plane_decomposition::CgalBbox2d& boundingBox) ; +double squaredDistanceToBoundingBox(const convex_plane_decomposition::CgalPoint2d& point, + const convex_plane_decomposition::CgalBbox2d& boundingBox); /** Converts a 3D position in world frame to a 2D position in the terrain frame. */ inline convex_plane_decomposition::CgalPoint2d position2dInTerrainFrameFromPositionInWorld(const vector3_t& positionWorld, @@ -48,6 +49,7 @@ std::vector sortWithBoundingBoxes(const vector3_t& positionIn const std::vector& planarRegions); std::pair getPlanarRegionAtPositionInWorld( - const vector3_t& positionInWorld, const std::vector& planarRegions); + const vector3_t& positionInWorld, const std::vector& planarRegions, + std::function penaltyFunction); } // namespace switched_model \ No newline at end of file diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h index 23960def..f8fdf4b6 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h @@ -15,9 +15,12 @@ class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { public: SegmentedPlanesTerrainModel(convex_plane_decomposition::PlanarTerrain planarTerrain); - TerrainPlane getLocalTerrainAtPositionInWorldAlongGravity(const vector3_t& positionInWorld) const override; + TerrainPlane getLocalTerrainAtPositionInWorldAlongGravity(const vector3_t& positionInWorld, + std::function penaltyFunction) const override; - ConvexTerrain getConvexTerrainAtPositionInWorld(const vector3_t& positionInWorld) const override; + using switched_model::TerrainModel::getConvexTerrainAtPositionInWorld; + ConvexTerrain getConvexTerrainAtPositionInWorld(const vector3_t& positionInWorld, + std::function penaltyFunction) const override; void createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, const Eigen::Vector3d& maxCoordinates); @@ -35,7 +38,4 @@ class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { const grid_map::Matrix* const elevationData_; }; -std::pair getPlanarRegionAtPositionInWorld( - const vector3_t& positionInWorld, const std::vector& planarRegions); - } // namespace switched_model diff --git a/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp b/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp index b8463cf9..11172165 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp @@ -114,11 +114,12 @@ std::vector sortWithBoundingBoxes(const vector3_t& positionIn } std::pair getPlanarRegionAtPositionInWorld( - const vector3_t& positionInWorld, const std::vector& planarRegions) { + const vector3_t& positionInWorld, const std::vector& planarRegions, + std::function penaltyFunction) { const auto sortedRegions = sortWithBoundingBoxes(positionInWorld, planarRegions); // Look for closest planar region. - double minCost = std::numeric_limits::max(); + scalar_t minCost = std::numeric_limits::max(); std::pair closestRegionAndProjection; for (const auto& regionInfo : sortedRegions) { // Skip based on lower bound @@ -136,9 +137,9 @@ std::pair getPlanarRegionAtPositionI // Express projected point in World frame const auto projectionInWorldFrame = positionInWorldFrameFromPosition2dInTerrain(projectedPointInTerrainFrame, planeParameters); - const double distCost = distanceCost(positionInWorld, projectionInWorldFrame); - if (distCost < minCost) { - minCost = distCost; + const scalar_t cost = distanceCost(positionInWorld, projectionInWorldFrame) + penaltyFunction(projectionInWorldFrame); + if (cost < minCost) { + minCost = cost; closestRegionAndProjection = {regionPtr, projectedPointInTerrainFrame}; } } diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index f3a7bc1a..bc37607d 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -23,16 +23,20 @@ SegmentedPlanesTerrainModel::SegmentedPlanesTerrainModel(convex_plane_decomposit signedDistanceField_(nullptr), elevationData_(&planarTerrain_.gridMap.get(elevationLayerName)) {} -TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorldAlongGravity(const vector3_t& positionInWorld) const { - const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions); +TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorldAlongGravity( + const vector3_t& positionInWorld, std::function penaltyFunction) const { + const auto regionAndSeedPoint = + getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions, std::move(penaltyFunction)); const auto& region = *regionAndSeedPoint.first; const auto& seedpoint = regionAndSeedPoint.second; const auto& seedpointInWorldFrame = positionInWorldFrameFromPosition2dInTerrain(seedpoint, region.planeParameters); return TerrainPlane{seedpointInWorldFrame, region.planeParameters.orientationWorldToTerrain}; } -ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld(const vector3_t& positionInWorld) const { - const auto regionAndSeedPoint = getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions); +ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld( + const vector3_t& positionInWorld, std::function penaltyFunction) const { + const auto regionAndSeedPoint = + getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions, std::move(penaltyFunction)); const auto& region = *regionAndSeedPoint.first; const auto& seedpoint = regionAndSeedPoint.second; const auto& seedpointInWorldFrame = positionInWorldFrameFromPosition2dInTerrain(seedpoint, region.planeParameters); From 89b7c3dd9c9226690c7f573f99d9f0a8f85340dd Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 13 Dec 2021 10:59:33 +0100 Subject: [PATCH 150/504] compute true resolution after rescaling --- .../src/GridMapPreprocessing.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/convex_plane_decomposition/src/GridMapPreprocessing.cpp b/convex_plane_decomposition/src/GridMapPreprocessing.cpp index 19979602..1dc8c055 100644 --- a/convex_plane_decomposition/src/GridMapPreprocessing.cpp +++ b/convex_plane_decomposition/src/GridMapPreprocessing.cpp @@ -37,12 +37,17 @@ void GridMapPreprocessing::denoise(grid_map::GridMap& gridMap, const std::string void GridMapPreprocessing::changeResolution(grid_map::GridMap& gridMap, const std::string& layer) const { if (parameters_.resolution > 0.0 && gridMap.getResolution() != parameters_.resolution) { + // Original map info + const auto oldPosition = gridMap.getPosition(); + const auto oldSize = gridMap.getSize(); + const auto oldResolution = gridMap.getResolution(); + Eigen::MatrixXf elevation_map = std::move(gridMap.get(layer)); cv::Mat elevationImage; cv::eigen2cv(elevation_map, elevationImage); - double scaling = gridMap.getResolution() / parameters_.resolution; + double scaling = oldResolution / parameters_.resolution; int width = int(elevationImage.size[1] * scaling); int height = int(elevationImage.size[0] * scaling); cv::Size dim{width, height}; @@ -52,9 +57,12 @@ void GridMapPreprocessing::changeResolution(grid_map::GridMap& gridMap, const st cv::cv2eigen(resizedImage, elevation_map); - const auto oldPosition = gridMap.getPosition(); - gridMap.setGeometry({elevation_map.rows() * parameters_.resolution, elevation_map.cols() * parameters_.resolution}, - parameters_.resolution, oldPosition); + // Compute true new resolution. Might be slightly different due to rounding. Take average of both dimensions. + grid_map::Size newSize = {elevation_map.rows(), elevation_map.cols()}; + const double newResolution = 0.5 * ((oldSize[0] * oldResolution) / newSize[0] + (oldSize[1] * oldResolution) / newSize[1]); + grid_map::Position newPosition = oldPosition; + + gridMap.setGeometry({newSize[0] * newResolution, newSize[1] * newResolution}, newResolution, newPosition); gridMap.get(layer) = std::move(elevation_map); } } From c3f9fc9cf4c458755a29bd392053258da15b7d52 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 13 Dec 2021 11:00:17 +0100 Subject: [PATCH 151/504] take submap around closest central cell --- .../src/ConvexPlaneDecompositionRos.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 6a23dc3b..24209a03 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -107,7 +107,16 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { // Extract submap bool success; - grid_map::GridMap elevationMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(subMapLength_, subMapWidth_), success); + const grid_map::Position submapPosition = [&]() { + // The map center might be between cells. Taking the submap there can result in changing submap dimensions. + // project map center to an index and index to center s.t. we get the location of a cell. + grid_map::Index centerIndex; + grid_map::Position centerPosition; + messageMap.getIndex(messageMap.getPosition(), centerIndex); + messageMap.getPosition(centerIndex, centerPosition); + return centerPosition; + }(); + grid_map::GridMap elevationMap = messageMap.getSubmap(submapPosition, Eigen::Array2d(subMapLength_, subMapWidth_), success); if (!success) { ROS_WARN("[ConvexPlaneExtractionROS] Could not extract submap"); return; From 34634ace0c5f678c99e6df56ecbf06a359e3dd23 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Fri, 17 Dec 2021 09:15:09 +0100 Subject: [PATCH 152/504] move call the label reset --- .../SlidingWindowPlaneExtractor.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index 9ba4c54d..cc5ef599 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -208,6 +208,8 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label, setToBackground(label); } } else { + // Set entire label to background, so unassigned points are automatically in background + setToBackground(label); refineLabelWithRansac(label, pointsWithNormal); } } else { // no RANSAC @@ -229,9 +231,6 @@ void SlidingWindowPlaneExtractor::refineLabelWithRansac(int label, std::vector Date: Fri, 17 Dec 2021 09:15:49 +0100 Subject: [PATCH 153/504] fix RANSAC distance threshold. Need to divide by 3 to counter a multiplication by 3 in the CGAL implementation --- convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp b/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp index a977c31e..98dc720e 100644 --- a/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp @@ -10,7 +10,7 @@ RansacPlaneExtractor::RansacPlaneExtractor(const RansacPlaneExtractorParameters& void RansacPlaneExtractor::setParameters(const RansacPlaneExtractorParameters& parameters) { cgalRansacParameters_.probability = parameters.probability; cgalRansacParameters_.min_points = parameters.min_points; - cgalRansacParameters_.epsilon = parameters.epsilon; + cgalRansacParameters_.epsilon = parameters.epsilon / 3.0; // CGAL ransac puts the inlier tolerance at 3 times epsilon cgalRansacParameters_.cluster_epsilon = parameters.cluster_epsilon; cgalRansacParameters_.normal_threshold = std::cos(parameters.normal_threshold * M_PI / 180.0); } From 8cd5afa0b36ee71bcc41c8f032c6d5e9fb6ea0dd Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 20 Jan 2022 21:39:24 +0100 Subject: [PATCH 154/504] update benchmarking --- .../ConvexPlaneDecompositionRos.h | 9 ++++ .../src/ConvexPlaneDecompositionRos.cpp | 47 ++++++++++++++----- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h index d0578334..5e14999f 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h @@ -10,6 +10,8 @@ #include +#include + #include namespace convex_plane_decomposition { @@ -66,6 +68,13 @@ class ConvexPlaneExtractionROS { std::unique_ptr slidingWindowPlaneExtractor_; std::unique_ptr contourExtraction_; std::unique_ptr postprocessing_; + + // Timing + ocs2::benchmark::RepeatedTimer callbackTimer_; + ocs2::benchmark::RepeatedTimer preprocessTimer_; + ocs2::benchmark::RepeatedTimer slidingWindowTimer_; + ocs2::benchmark::RepeatedTimer planeExtractionTimer_; + ocs2::benchmark::RepeatedTimer postprocessTimer_; }; } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 24209a03..119efa70 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -34,7 +34,27 @@ ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle) } } -ConvexPlaneExtractionROS::~ConvexPlaneExtractionROS() = default; +ConvexPlaneExtractionROS::~ConvexPlaneExtractionROS() { + std::stringstream infoStream; + if (callbackTimer_.getNumTimedIntervals() > 0) { + infoStream << "\n########################################################################\n"; + infoStream << "The benchmarking is computed over " << callbackTimer_.getNumTimedIntervals() << " iterations. \n"; + infoStream << "PlaneExtraction Benchmarking : Average time [ms], Max time [ms]\n"; + auto printLine = [](std::string name, const ocs2::benchmark::RepeatedTimer& timer) { + std::stringstream ss; + ss << std::fixed << std::setprecision(2); + ss << "\t" << name << "\t: " << std::setw(17) << timer.getAverageInMilliseconds() << ", " << std::setw(13) + << timer.getMaxIntervalInMilliseconds() << "\n"; + return ss.str(); + }; + infoStream << printLine("Pre-process ", preprocessTimer_); + infoStream << printLine("Sliding window ", slidingWindowTimer_); + infoStream << printLine("Plane extraction", planeExtractionTimer_); + infoStream << printLine("Post-process ", postprocessTimer_); + infoStream << printLine("Total callback ", callbackTimer_); + } + std::cerr << infoStream.str() << std::endl; +} bool ConvexPlaneExtractionROS::loadParameters(const ros::NodeHandle& nodeHandle) { if (!nodeHandle.getParam("elevation_topic", elevationMapTopic_)) { @@ -81,14 +101,15 @@ bool ConvexPlaneExtractionROS::loadParameters(const ros::NodeHandle& nodeHandle) void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { std::lock_guard lock(mutex_); + callbackTimer_.startTimer(); // Convert message to map. - ROS_INFO("Reading input map..."); grid_map::GridMap messageMap; std::vector layers{elevationLayer_}; grid_map::GridMapRosConverter::fromMessage(message, messageMap, layers, false, false); if (!containsFiniteValue(messageMap.get(elevationLayer_))) { ROS_WARN("[ConvexPlaneExtractionROS] map does not contain any values"); + callbackTimer_.endTimer(); return; } @@ -101,6 +122,7 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { messageMap.getTransformedMap(getTransformToTargetFrame(messageMap.getFrameId(), timeStamp), elevationLayer_, targetFrameId_); } else { ROS_ERROR_STREAM("[ConvexPlaneExtractionROS] " << errorMsg); + callbackTimer_.endTimer(); return; } } @@ -119,27 +141,27 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { grid_map::GridMap elevationMap = messageMap.getSubmap(submapPosition, Eigen::Array2d(subMapLength_, subMapWidth_), success); if (!success) { ROS_WARN("[ConvexPlaneExtractionROS] Could not extract submap"); + callbackTimer_.endTimer(); return; } - ROS_INFO("...done."); const grid_map::Matrix elevationRaw = elevationMap.get(elevationLayer_); - auto t0 = std::chrono::high_resolution_clock::now(); + preprocessTimer_.startTimer(); preprocessing_->preprocess(elevationMap, elevationLayer_); - auto t1 = std::chrono::high_resolution_clock::now(); - ROS_INFO_STREAM("Preprocessing took " << 1e-3 * std::chrono::duration_cast(t1 - t0).count() << " [ms]"); + preprocessTimer_.endTimer(); // Run pipeline. + slidingWindowTimer_.startTimer(); slidingWindowPlaneExtractor_->runExtraction(elevationMap, elevationLayer_); - auto t2 = std::chrono::high_resolution_clock::now(); - ROS_INFO_STREAM("Sliding window took " << 1e-3 * std::chrono::duration_cast(t2 - t1).count() << " [ms]"); + slidingWindowTimer_.endTimer(); + planeExtractionTimer_.startTimer(); PlanarTerrain planarTerrain; planarTerrain.planarRegions = contourExtraction_->extractPlanarRegions(slidingWindowPlaneExtractor_->getSegmentedPlanesMap()); - auto t3 = std::chrono::high_resolution_clock::now(); - ROS_INFO_STREAM("Contour extraction took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]"); + planeExtractionTimer_.endTimer(); // Add grid map to the terrain + postprocessTimer_.startTimer(); planarTerrain.gridMap = std::move(elevationMap); // Add binary map @@ -149,8 +171,7 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { cv::cv2eigen(slidingWindowPlaneExtractor_->getBinaryLabeledImage(), traversabilityMask); postprocessing_->postprocess(planarTerrain, elevationLayer_, planeClassificationLayer); - auto t4 = std::chrono::high_resolution_clock::now(); - ROS_INFO_STREAM("Postprocessing took " << 1e-3 * std::chrono::duration_cast(t4 - t3).count() << " [ms]"); + postprocessTimer_.endTimer(); // Publish terrain if (publishToController_) { @@ -174,6 +195,8 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { boundaryPublisher_.publish(convertBoundariesToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId())); insetPublisher_.publish(convertInsetsToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId())); + + callbackTimer_.endTimer(); } Eigen::Isometry3d ConvexPlaneExtractionROS::getTransformToTargetFrame(const std::string& sourceFrame, const ros::Time& time) { From 0998bb7111abe147b3cc9e8961578f5786d08c44 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 2 Feb 2022 10:59:12 +0100 Subject: [PATCH 155/504] add test for extrapolating the sdf --- .../test/testSignedDistance3d.cpp | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/signed_distance_field/test/testSignedDistance3d.cpp b/signed_distance_field/test/testSignedDistance3d.cpp index 1f08434e..47631b88 100644 --- a/signed_distance_field/test/testSignedDistance3d.cpp +++ b/signed_distance_field/test/testSignedDistance3d.cpp @@ -150,4 +150,39 @@ TEST(testSignedDistance3d, randomTerrainDerivative) { } } } +} + +TEST(testSignedDistance3d, extrapolation) { + const int n = 20; + const int m = 30; + const float resolution = 0.1; + const float h = 0.5; + grid_map::GridMap map; + map.setGeometry({n * resolution, m * resolution}, resolution); + map.add("elevation"); + map.get("elevation").setConstant(h); // random [-1.0, 1.0] + const grid_map::Matrix mapData = map.get("elevation"); + const float minHeight = h - resolution; + const float maxHeight = h + resolution; + + signed_distance_field::GridmapSignedDistanceField sdf(map, "elevation", minHeight, maxHeight); + + // Check at different heights/ + for (float height = h - 1.0; height < h + 1.0; height += resolution) { + const auto naiveSignedDistance = signed_distance_field::naiveSignedDistanceAtHeight(mapData, height, resolution); + + for (int i = 0; i < mapData.rows(); ++i) { + for (int j = 0; j < mapData.rows(); ++j) { + grid_map::Position position2d; + map.getPosition({i, j}, position2d); + + const auto sdfValueAndDerivative = sdf.valueAndDerivative({position2d.x(), position2d.y(), height}); + const auto sdfCheck = naiveSignedDistance(i, j); + ASSERT_LT(std::abs(sdfValueAndDerivative.first - sdfCheck), 1e-4); + + // Constant terrain, derivative should be up everywhere + ASSERT_LT((sdfValueAndDerivative.second - switched_model::vector3_t::UnitZ()).norm(), 1e-4); + } + } + } } \ No newline at end of file From 44ae468fe00a6078be5d37597afbafe0f86f14d6 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 2 Feb 2022 10:59:28 +0100 Subject: [PATCH 156/504] fix timestamp conversion --- .../src/ConvexPlaneDecompositionRos.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 119efa70..7249a377 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -224,7 +224,8 @@ Eigen::Isometry3d ConvexPlaneExtractionROS::getTransformToTargetFrame(const std: ros::Time ConvexPlaneExtractionROS::getMessageTime(const grid_map_msgs::GridMap& message) const { try { - return ros::Time(message.info.header.stamp.toNSec()); + ros::Time time; + return time.fromNSec(message.info.header.stamp.toNSec()); } catch (std::runtime_error& ex) { ROS_WARN("[ConvexPlaneExtractionROS::getMessageTime] %s", ex.what()); return ros::Time::now(); From 856461bb1fd5c708cc21d6984ec65e4386f36911 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 2 Feb 2022 16:32:17 +0100 Subject: [PATCH 157/504] fix inset at border of the map --- .../src/contour_extraction/ContourExtraction.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp index b09af9f7..3815bc31 100644 --- a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp +++ b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp @@ -72,6 +72,12 @@ std::vector extractBoundaryAndInset(cv::Mat& binary_image, co // Erode cv::erode(binary_image, binary_image, erosionKernel, cv::Point(-1,-1), 1, cv::BORDER_REPLICATE); + // Erosion of the edge of the map + binary_image.row(0) = 0; + binary_image.row(binary_image.rows - 1) = 0; + binary_image.col(0) = 0; + binary_image.col(binary_image.cols - 1) = 0; + // Get insets std::vector insets = extractPolygonsFromBinaryImage(binary_image); From 94a662b6fea0dc8aec3069a3549689ccc658bacb Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 2 Feb 2022 16:33:09 +0100 Subject: [PATCH 158/504] set max iterations in region growing and print if it is reached. Remove unnecessary memory allocations --- .../src/ConvexRegionGrowing.cpp | 57 ++++++++++++++++--- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/convex_plane_decomposition/src/ConvexRegionGrowing.cpp b/convex_plane_decomposition/src/ConvexRegionGrowing.cpp index b5fd52c1..c94282f0 100644 --- a/convex_plane_decomposition/src/ConvexRegionGrowing.cpp +++ b/convex_plane_decomposition/src/ConvexRegionGrowing.cpp @@ -11,6 +11,7 @@ namespace convex_plane_decomposition { CgalPolygon2d createRegularPolygon(const CgalPoint2d& center, double radius, int numberOfVertices) { assert(numberOfVertices > 2); CgalPolygon2d polygon; + polygon.container().reserve(numberOfVertices); double angle = (2. * M_PI) / numberOfVertices; for (int i = 0; i < numberOfVertices; ++i) { double phi = i * angle; @@ -58,13 +59,14 @@ std::array get2ndNeighbours(const CgalPolygon2d& polygon, int i) bool remainsConvexWhenMovingPoint(const CgalPolygon2d& polygon, int i, const CgalPoint2d& point) { auto secondNeighbours = get2ndNeighbours(polygon, i); - CgalPolygon2d subPolygon; - subPolygon.container().reserve(5); - subPolygon.push_back(secondNeighbours[0]); - subPolygon.push_back(secondNeighbours[1]); - subPolygon.push_back(point); - subPolygon.push_back(secondNeighbours[2]); - subPolygon.push_back(secondNeighbours[3]); + using CgalPolygon2dFixedSize = CGAL::Polygon_2>; + + CgalPolygon2dFixedSize subPolygon; + subPolygon.container()[0] = secondNeighbours[0]; + subPolygon.container()[1] = secondNeighbours[1]; + subPolygon.container()[2] = point; + subPolygon.container()[3] = secondNeighbours[2]; + subPolygon.container()[4] = secondNeighbours[3]; return subPolygon.is_convex(); } @@ -99,18 +101,47 @@ bool pointCanBeMoved(const CgalPolygon2d& growthShape, int i, const CgalPoint2d& } } +namespace { +inline std::ostream& operator<<(std::ostream& os, const CgalPolygon2d& p) { + os << "CgalPolygon2d: \n"; + for (auto it = p.vertices_begin(); it != p.vertices_end(); ++it) { + os << "\t(" << it->x() << ", " << it->y() << ")\n"; + } + return os; +} + +inline std::ostream& operator<<(std::ostream& os, const CgalPolygonWithHoles2d& p) { + os << "CgalPolygonWithHoles2d: \n"; + os << "\t" << p.outer_boundary() << "\n"; + os << "\tHoles: \n"; + for (auto it = p.holes_begin(); it != p.holes_end(); ++it) { + os << "\t\t" << *it << "\n"; + } + return os; +} +} // namespace + template CgalPolygon2d growConvexPolygonInsideShape_impl(const T& parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor) { + const auto centerCopy = center; constexpr double initialRadiusFactor = 0.999; + constexpr int maxIter = 1000; double radius = initialRadiusFactor * distance(center, parentShape); + CgalPolygon2d growthShape = createRegularPolygon(center, radius, numberOfVertices); + if (radius == 0.0) { + std::cerr << "[growConvexPolygonInsideShape] Zero initial radius. Provide a point with a non-zero offset to the boundary.\n"; + return growthShape; + } + // Cached values per vertex std::vector blocked(numberOfVertices, false); std::vector freeSpheres(numberOfVertices, CgalCircle2d(center, radius * radius)); int Nblocked = 0; - while (Nblocked < numberOfVertices) { + int iter = 0; + while (Nblocked < numberOfVertices && iter < maxIter) { for (int i = 0; i < numberOfVertices; i++) { if (!blocked[i]) { const auto candidatePoint = getPointOnLine(center, growthShape.vertex(i), growthFactor); @@ -123,7 +154,17 @@ CgalPolygon2d growConvexPolygonInsideShape_impl(const T& parentShape, CgalPoint2 } } } + ++iter; } + + if (iter == maxIter) { + std::cerr << "[growConvexPolygonInsideShape] max iteration in region growing! Debug information: \n"; + std::cerr << "numberOfVertices: " << numberOfVertices << "\n"; + std::cerr << "growthFactor: " << growthFactor << "\n"; + std::cerr << "Center: " << centerCopy.x() << ", " << centerCopy.y() << "\n"; + std::cerr << parentShape << "\n"; + } + return growthShape; } From 936c9b47298dad2e4d835558a4141471f093d739 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 2 Feb 2022 16:33:20 +0100 Subject: [PATCH 159/504] add region growing test --- convex_plane_decomposition/CMakeLists.txt | 12 ++++ .../test/testRegionGrowing.cpp | 69 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 convex_plane_decomposition/test/testRegionGrowing.cpp diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index fc25bfcf..d7caaca2 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -104,3 +104,15 @@ target_link_libraries(test_${PROJECT_NAME}_upsampling mpfr gtest_main ) + +catkin_add_gtest(test_${PROJECT_NAME}_regionGrowing + test/testRegionGrowing.cpp + ) +target_link_libraries(test_${PROJECT_NAME}_regionGrowing + ${PROJECT_NAME} + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + gmp + mpfr + gtest_main + ) \ No newline at end of file diff --git a/convex_plane_decomposition/test/testRegionGrowing.cpp b/convex_plane_decomposition/test/testRegionGrowing.cpp new file mode 100644 index 00000000..e0932c28 --- /dev/null +++ b/convex_plane_decomposition/test/testRegionGrowing.cpp @@ -0,0 +1,69 @@ +// +// Created by rgrandia on 02.02.22. +// + + +#include + +#include "convex_plane_decomposition/ConvexRegionGrowing.h" + +#include + +using namespace convex_plane_decomposition; + +TEST(TestRegionGrowing, center_on_border) { + // Rare case where the region algorithm go stuck + const int numberOfVertices = 16; // Multiple of 4 is nice for symmetry. + const double growthFactor = 1.05; + CgalPoint2d center(0.0, 1.0); + + CgalPolygonWithHoles2d parentShape; + parentShape.outer_boundary().container() = {{1, -1}, {1, 1}, {-1, 1}, {-1, -1}}; + + const auto convexInnerApprox = growConvexPolygonInsideShape(parentShape, center, numberOfVertices, growthFactor); + ASSERT_TRUE(convexInnerApprox.is_convex()); + for (auto it = convexInnerApprox.vertices_begin(); it!=convexInnerApprox.vertices_end(); ++it) { + ASSERT_TRUE(isInside(*it, parentShape)); + } +} + +TEST(TestRegionGrowing, debug_case) { + // Rare case where the region algorithm go stuck + const int numberOfVertices = 16; // Multiple of 4 is nice for symmetry. + const double growthFactor = 1.05; + CgalPoint2d center(-0.147433, 0.800114); + + CgalPolygonWithHoles2d parentShape; + parentShape.outer_boundary().container() = { + {1.03923, -0.946553}, {1.03923, 0.840114}, {0.7859, 0.840114}, {0.772567, 0.853447}, {0.759233, 0.853447}, + {0.7459, 0.86678}, {0.7459, 0.880114}, {0.732567, 0.893447}, {0.719233, 0.893447}, {0.7059, 0.90678}, + {0.7059, 1.05345}, {0.652567, 1.05345}, {0.652567, 0.90678}, {0.639233, 0.893447}, {0.6259, 0.893447}, + {0.612567, 0.880114}, {0.612567, 0.86678}, {0.599233, 0.853447}, {0.5859, 0.853447}, {0.572567, 0.840114}, + {0.532567, 0.840114}, {0.532567, 0.82678}, {0.519233, 0.813447}, {0.5059, 0.813447}, {0.492567, 0.800114}, + {0.3059, 0.800114}, {0.292567, 0.813447}, {0.279233, 0.813447}, {0.2659, 0.82678}, {0.2659, 0.840114}, + {0.252567, 0.853447}, {0.239233, 0.853447}, {0.2259, 0.86678}, {0.2259, 0.920114}, {0.212567, 0.933447}, + {0.199233, 0.933447}, {0.1859, 0.94678}, {0.1859, 1.05345}, {0.132567, 1.05345}, {0.132567, 0.86678}, + {0.119233, 0.853447}, {0.1059, 0.853447}, {0.0925666, 0.840114}, {0.0925666, 0.82678}, {0.0792332, 0.813447}, + {0.0658999, 0.813447}, {0.0525666, 0.800114}, {-0.1341, 0.800114}, {-0.147433, 0.813447}, {-0.160767, 0.813447}, + {-0.1741, 0.82678}, {-0.1741, 0.840114}, {-0.2141, 0.840114}, {-0.227433, 0.853447}, {-0.240767, 0.853447}, + {-0.2541, 0.86678}, {-0.2541, 0.880114}, {-0.267433, 0.893447}, {-0.280767, 0.893447}, {-0.2941, 0.90678}, + {-0.2941, 1.05345}, {-0.960767, 1.05345}, {-0.960767, -0.946553}}; + + CgalPolygon2d hole; + hole.container() = {{0.5459, -0.266553}, {0.532566, -0.279886}, {0.3059, -0.279886}, {0.292566, -0.266553}, {0.279233, -0.266553}, + {0.2659, -0.25322}, {0.2659, -0.239886}, {0.252566, -0.226553}, {0.239233, -0.226553}, {0.2259, -0.21322}, + {0.2259, 0.320114}, {0.239233, 0.333447}, {0.252566, 0.333447}, {0.2659, 0.34678}, {0.532567, 0.34678}, + {0.5459, 0.333447}, {0.559233, 0.333447}, {0.572567, 0.320114}, {0.572567, 0.30678}, {0.5859, 0.293447}, + {0.599233, 0.293447}, {0.612567, 0.280114}, {0.612566, 0.0667803}, {0.6259, 0.053447}, {0.639233, 0.053447}, + {0.652566, 0.0401136}, {0.652566, -0.17322}, {0.639233, -0.186553}, {0.6259, -0.186553}, {0.612566, -0.199886}, + {0.612566, -0.21322}, {0.599233, -0.226553}, {0.5859, -0.226553}, {0.572566, -0.239886}, {0.572566, -0.25322}, + {0.559233, -0.266553}}; + parentShape.holes().push_back(std::move(hole)); + + const auto convexInnerApprox = growConvexPolygonInsideShape(parentShape, center, numberOfVertices, growthFactor); + + ASSERT_TRUE(convexInnerApprox.is_convex()); + for (auto it = convexInnerApprox.vertices_begin(); it!=convexInnerApprox.vertices_end(); ++it) { + ASSERT_TRUE(isInside(*it, parentShape)); + } +} \ No newline at end of file From 030ee8b73b54e6fbaf8d0459da70f72da706c2ae Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 3 Feb 2022 10:26:07 +0100 Subject: [PATCH 160/504] fix gridmap map projection --- .../src/SegmentedPlanesTerrainModel.cpp | 4 ++-- .../src/SegmentedPlanesTerrainModelRos.cpp | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index bc37607d..393ebe78 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -60,8 +60,8 @@ ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld( void SegmentedPlanesTerrainModel::createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, const Eigen::Vector3d& maxCoordinates) { // Compute coordinates of submap - const auto minXY = planarTerrain_.gridMap.getClosestPositionInMap({minCoordinates.x(), minCoordinates.y()}); - const auto maxXY = planarTerrain_.gridMap.getClosestPositionInMap({maxCoordinates.x(), maxCoordinates.y()}); + const auto minXY = grid_map::lookup::projectToMapWithMargin(planarTerrain_.gridMap, grid_map::Position(minCoordinates.x(), minCoordinates.y())); + const auto maxXY = grid_map::lookup::projectToMapWithMargin(planarTerrain_.gridMap, grid_map::Position(maxCoordinates.x(), maxCoordinates.y())); const auto centerXY = 0.5 * (minXY + maxXY); const auto lengths = maxXY - minXY; diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp index 1fb14c5f..af91f652 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp @@ -9,6 +9,7 @@ #include #include +#include namespace switched_model { @@ -112,8 +113,10 @@ std::pair SegmentedPlanesTerrainModelRos::getS const auto& elevationData = gridMap.get(elevationLayer); const float minValue = elevationData.minCoeffOfFinites() - heightMargin; const float maxValue = elevationData.maxCoeffOfFinites() + heightMargin; - auto minXY = gridMap.getClosestPositionInMap({std::numeric_limits::lowest(), std::numeric_limits::lowest()}); - auto maxXY = gridMap.getClosestPositionInMap({std::numeric_limits::max(), std::numeric_limits::max()}); + auto minXY = grid_map::lookup::projectToMapWithMargin( + gridMap, grid_map::Position(std::numeric_limits::lowest(), std::numeric_limits::lowest())); + auto maxXY = grid_map::lookup::projectToMapWithMargin( + gridMap, grid_map::Position(std::numeric_limits::max(), std::numeric_limits::max())); minCoordinates = {minXY.x(), minXY.y(), minValue}; maxCoordinates = {maxXY.x(), maxXY.y(), maxValue}; }; From 7e2c4b7d955cff495a396f5ac0c054a73c3de56c Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 3 Feb 2022 10:26:21 +0100 Subject: [PATCH 161/504] increase node frequency --- convex_plane_decomposition_ros/config/node.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/config/node.yaml b/convex_plane_decomposition_ros/config/node.yaml index e7901ec4..68790760 100644 --- a/convex_plane_decomposition_ros/config/node.yaml +++ b/convex_plane_decomposition_ros/config/node.yaml @@ -5,4 +5,4 @@ submap: width: 3.0 length: 3.0 publish_to_controller: true -frequency: 10.0 +frequency: 20.0 From ba503060e884c40dd702639c68800d4ae1ae3402 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 8 Feb 2022 09:03:20 +0100 Subject: [PATCH 162/504] extend polygon visualization with external timestamp and with labels --- .../RosVisualizations.h | 5 +++-- .../src/ConvexPlaneDecompositionRos.cpp | 6 ++++-- .../src/RosVisualizations.cpp | 21 +++++++++++++++---- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h index eaac3612..6495015c 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h @@ -7,8 +7,9 @@ namespace convex_plane_decomposition { jsk_recognition_msgs::PolygonArray convertBoundariesToRosPolygons(const std::vector& planarRegions, - const std::string& frameId); + const std::string& frameId, grid_map::Time time); -jsk_recognition_msgs::PolygonArray convertInsetsToRosPolygons(const std::vector& planarRegions, const std::string& frameId); +jsk_recognition_msgs::PolygonArray convertInsetsToRosPolygons(const std::vector& planarRegions, const std::string& frameId, + grid_map::Time time); } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 7249a377..39776e1b 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -193,8 +193,10 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { grid_map::GridMapRosConverter::toMessage(planarTerrain.gridMap, outputMessage); filteredmapPublisher_.publish(outputMessage); - boundaryPublisher_.publish(convertBoundariesToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId())); - insetPublisher_.publish(convertInsetsToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId())); + boundaryPublisher_.publish(convertBoundariesToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId(), + planarTerrain.gridMap.getTimestamp())); + insetPublisher_.publish(convertInsetsToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId(), + planarTerrain.gridMap.getTimestamp())); callbackTimer_.endTimer(); } diff --git a/convex_plane_decomposition_ros/src/RosVisualizations.cpp b/convex_plane_decomposition_ros/src/RosVisualizations.cpp index 8622e0cc..234c3e1a 100644 --- a/convex_plane_decomposition_ros/src/RosVisualizations.cpp +++ b/convex_plane_decomposition_ros/src/RosVisualizations.cpp @@ -34,35 +34,48 @@ inline std::vector to3d(const CgalPolygonWithHole } jsk_recognition_msgs::PolygonArray convertBoundariesToRosPolygons(const std::vector& planarRegions, - const std::string& frameId) { + const std::string& frameId, grid_map::Time time) { jsk_recognition_msgs::PolygonArray polygon_buffer; std_msgs::Header header; - header.stamp = ros::Time::now(); + header.stamp.fromNSec(time); header.frame_id = frameId; polygon_buffer.header = header; polygon_buffer.polygons.reserve(planarRegions.size()); // lower bound + polygon_buffer.labels.reserve(planarRegions.size()); + uint32_t label = 0; for (const auto& planarRegion : planarRegions) { auto boundaries = to3d(planarRegion.boundaryWithInset.boundary, planarRegion.planeParameters, header); std::move(boundaries.begin(), boundaries.end(), std::back_inserter(polygon_buffer.polygons)); + for (size_t i = 0; i < boundaries.size(); ++i) { + polygon_buffer.labels.push_back(label); + } + ++label; } return polygon_buffer; } -jsk_recognition_msgs::PolygonArray convertInsetsToRosPolygons(const std::vector& planarRegions, const std::string& frameId) { +jsk_recognition_msgs::PolygonArray convertInsetsToRosPolygons(const std::vector& planarRegions, const std::string& frameId, + grid_map::Time time) { jsk_recognition_msgs::PolygonArray polygon_buffer; std_msgs::Header header; - header.stamp = ros::Time::now(); + header.stamp.fromNSec(time); header.frame_id = frameId; polygon_buffer.header = header; polygon_buffer.polygons.reserve(planarRegions.size()); // lower bound + polygon_buffer.labels.reserve(planarRegions.size()); + uint32_t label = 0; for (const auto& planarRegion : planarRegions) { for (const auto& inset : planarRegion.boundaryWithInset.insets) { auto insets = to3d(inset, planarRegion.planeParameters, header); std::move(insets.begin(), insets.end(), std::back_inserter(polygon_buffer.polygons)); + for (size_t i = 0; i < insets.size(); ++i) { + polygon_buffer.labels.push_back(label); + } } + ++label; } return polygon_buffer; } From da02b110588ffb7ae70bca4a3623daf30da3755b Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 8 Feb 2022 09:04:00 +0100 Subject: [PATCH 163/504] update rviz config --- .../rviz/config_demo.rviz | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/convex_plane_decomposition_ros/rviz/config_demo.rviz b/convex_plane_decomposition_ros/rviz/config_demo.rviz index 8ed503d8..c49630ca 100644 --- a/convex_plane_decomposition_ros/rviz/config_demo.rviz +++ b/convex_plane_decomposition_ros/rviz/config_demo.rviz @@ -5,7 +5,6 @@ Panels: Property Tree Widget: Expanded: - /Global Options1 - - /GridMap1 - /FilteredMap1 Splitter Ratio: 0.4083484709262848 Tree Height: 824 @@ -38,13 +37,13 @@ Visualization Manager: - Alpha: 1 Class: jsk_rviz_plugin/PolygonArray Color: 25; 255; 0 - Enabled: false + Enabled: true Name: Boundaries Queue Size: 10 Topic: /convex_plane_decomposition_ros/boundaries Unreliable: false - Value: false - coloring: Auto + Value: true + coloring: Label enable lighting: true normal length: 0.10000000149011612 only border: true @@ -58,7 +57,7 @@ Visualization Manager: Topic: /convex_plane_decomposition_ros/insets Unreliable: false Value: false - coloring: Auto + coloring: Label enable lighting: true normal length: 0.10000000149011612 only border: true @@ -70,6 +69,8 @@ Visualization Manager: Color Layer: elevation Color Transformer: GridMapLayer Enabled: false + Grid Cell Decimation: 1 + Grid Line Thickness: 0.10000000149011612 Height Layer: elevation Height Transformer: GridMapLayer History Length: 1 @@ -91,6 +92,8 @@ Visualization Manager: Color Layer: plane_classification Color Transformer: IntensityLayer Enabled: true + Grid Cell Decimation: 1 + Grid Line Thickness: 0.10000000149011612 Height Layer: elevation_before_postprocess Height Transformer: "" History Length: 1 @@ -156,8 +159,8 @@ Visualization Manager: Value: true Views: Current: - Class: rviz/Orbit - Distance: 12.107149124145508 + Class: rviz/XYOrbit + Distance: 23.61389923095703 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 @@ -165,25 +168,25 @@ Visualization Manager: Value: false Field of View: 0.7853981852531433 Focal Point: - X: -3.3109402656555176 - Y: -1.6383998394012451 - Z: -3.4406676292419434 + X: 8.348309516906738 + Y: 0.002288922667503357 + Z: 3.0517578125e-05 Focal Shape Fixed Size: true Focal Shape Size: 0.05000000074505806 Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.5047986507415771 + Pitch: 0.8357961773872375 Target Frame: - Yaw: 1.6149601936340332 + Yaw: 0 Saved: ~ Window Geometry: Displays: - collapsed: false + collapsed: true Height: 1043 - Hide Left Dock: false - Hide Right Dock: true - QMainWindow State: 000000ff00000000fd00000004000000000000022900000375fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000375000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f0000040efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000280000040e000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007380000003efc0100000002fb0000000800540069006d0065010000000000000738000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000005090000037500000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Hide Left Dock: true + Hide Right Dock: false + QMainWindow State: 000000ff00000000fd00000004000000000000022900000375fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073000000003d00000375000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f00000375fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d00000375000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007380000003efc0100000002fb0000000800540069006d0065010000000000000738000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000007380000037500000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -191,7 +194,7 @@ Window Geometry: Tool Properties: collapsed: false Views: - collapsed: true + collapsed: false Width: 1848 X: 72 Y: 0 From af7d5242d1c05a1a6100c54df57efa1914f33f6f Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 23 Feb 2022 09:43:18 +0100 Subject: [PATCH 164/504] use latest TF instead of time stamped --- .../src/ConvexPlaneDecompositionRos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 39776e1b..57eb1eed 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -116,7 +116,7 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { // Transform map if necessary if (targetFrameId_ != messageMap.getFrameId()) { std::string errorMsg; - ros::Time timeStamp = getMessageTime(message); + ros::Time timeStamp = ros::Time(0); // Use Time(0) to get the latest transform. if (tfBuffer_.canTransform(targetFrameId_, messageMap.getFrameId(), timeStamp, &errorMsg)) { messageMap = messageMap.getTransformedMap(getTransformToTargetFrame(messageMap.getFrameId(), timeStamp), elevationLayer_, targetFrameId_); From 1da7b870f7e61678f23f789eb258c357bfc917b4 Mon Sep 17 00:00:00 2001 From: Vassilios Tsounis Date: Thu, 3 Mar 2022 15:51:56 +0100 Subject: [PATCH 165/504] Fixes missing CMake module inclusion in pcl_catkin. --- pcl_catkin/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pcl_catkin/CMakeLists.txt b/pcl_catkin/CMakeLists.txt index 00484962..89658bd2 100644 --- a/pcl_catkin/CMakeLists.txt +++ b/pcl_catkin/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 3.10) project(pcl_catkin) +include(GNUInstallDirs) + find_package(catkin REQUIRED) file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib) From c063e55a2eb4fc25266aaaa04467025e41208c97 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 15 Mar 2022 09:09:40 +0100 Subject: [PATCH 166/504] store position and normal in sliding window extractor --- .../include/convex_plane_decomposition/PlanarRegion.h | 8 ++++++++ .../convex_plane_decomposition/SegmentedPlanesMap.h | 2 +- .../src/contour_extraction/ContourExtraction.cpp | 3 ++- .../SlidingWindowPlaneExtractor.cpp | 9 +++------ convex_plane_decomposition_ros/test/test.cpp | 3 +-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h b/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h index d7091e14..3d3bc926 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h @@ -16,6 +16,14 @@ namespace convex_plane_decomposition { using switched_model::TerrainPlane; +struct NormalAndPosition { + /// 3D position. + Eigen::Vector3d position; + + /// Surface normal. + Eigen::Vector3d normal; +}; + struct BoundaryWithInset { /// Boundary of the planar region. CgalPolygonWithHoles2d boundary; diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h b/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h index 0a48b91f..f5576239 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h @@ -13,7 +13,7 @@ namespace convex_plane_decomposition { struct SegmentedPlanesMap { /// Unordered collection of all labels and corresponding plane parameters - std::vector> labelPlaneParameters; + std::vector> labelPlaneParameters; /// Image with a each pixel being assigned and integer value corresponding to the label. Might contain labels that are not in /// labelPlaneParameters. These labels should be seen as background. diff --git a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp index 3815bc31..190c2a1e 100644 --- a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp +++ b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp @@ -31,7 +31,8 @@ std::vector ContourExtraction::extractPlanarRegions(const Segmente std::vector planarRegions; for (const auto& label_plane : upSampledMap.labelPlaneParameters) { const int label = label_plane.first; - const auto& plane_parameters = label_plane.second; + const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(label_plane.second.normal); + const auto plane_parameters = switched_model::TerrainPlane(label_plane.second.position, terrainOrientation); binaryImage_ = upSampledMap.labeledImage == label; diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index cc5ef599..433e0ac6 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -202,8 +202,7 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label, if (parameters_.include_ransac_refinement) { // with RANSAC if (isGloballyPlanar(normalVector, supportVector, pointsWithNormal)) { // Already planar enough if (isWithinInclinationLimit(normalVector)) { - const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); - segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, TerrainPlane(supportVector, terrainOrientation)); + segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, NormalAndPosition{supportVector, normalVector}); } else { setToBackground(label); } @@ -214,8 +213,7 @@ void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label, } } else { // no RANSAC if (isWithinInclinationLimit(normalVector)) { - const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(normalVector); - segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, TerrainPlane(supportVector, terrainOrientation)); + segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, NormalAndPosition{supportVector, normalVector}); } else { setToBackground(label); } @@ -242,8 +240,7 @@ void SlidingWindowPlaneExtractor::refineLabelWithRansac(int label, std::vectorindices_of_assigned_points()) { diff --git a/convex_plane_decomposition_ros/test/test.cpp b/convex_plane_decomposition_ros/test/test.cpp index 86acc44b..b2d8bb66 100644 --- a/convex_plane_decomposition_ros/test/test.cpp +++ b/convex_plane_decomposition_ros/test/test.cpp @@ -55,7 +55,7 @@ void plotSlidingWindow(const sliding_window_plane_extractor::SlidingWindowPlaneE colors[0] = cv::Vec3b(0, 0, 0); // background in white for (int label = 1; label <= planeExtractor.getSegmentedPlanesMap().highestLabel; ++label) { const auto labelIt = std::find_if(labelsAndPlaneParameters.begin(), labelsAndPlaneParameters.end(), - [=](const std::pair& x) { return x.first == label; }); + [=](const std::pair& x) { return x.first == label; }); if (labelIt != labelsAndPlaneParameters.end()) { colors[label] = randomColor(); } else { @@ -131,7 +131,6 @@ int main(int argc, char** argv) { for (const auto& label_plane : planeExtractor.getSegmentedPlanesMap().labelPlaneParameters) { const int label = label_plane.first; - const auto& plane_parameters = label_plane.second; binary_image = labeled_image == label; From b7eaac3cd68304f955db7508ad0347b61da9e7ba Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 15 Mar 2022 17:02:26 +0100 Subject: [PATCH 167/504] substitute switched_model TerrainPlane with Eigen::Isometry3d --- convex_plane_decomposition/CMakeLists.txt | 22 ++--- .../convex_plane_decomposition/PlanarRegion.h | 27 ++++-- .../contour_extraction/ContourExtraction.h | 2 - convex_plane_decomposition/package.xml | 2 - .../src/PlanarRegion.cpp | 60 +++++++++++++ .../src/Postprocessing.cpp | 2 +- .../contour_extraction/ContourExtraction.cpp | 14 +-- .../test/testPlanarRegion.cpp | 85 +++++++++++++++++++ convex_plane_decomposition_ros/CMakeLists.txt | 1 + .../MessageConversion.h | 4 +- convex_plane_decomposition_ros/package.xml | 1 + .../src/MessageConversion.cpp | 38 ++++----- .../src/RosVisualizations.cpp | 14 +-- .../SegmentedPlaneProjection.h | 13 --- .../src/SegmentedPlaneProjection.cpp | 6 +- .../src/SegmentedPlanesTerrainModel.cpp | 16 ++-- 16 files changed, 219 insertions(+), 88 deletions(-) create mode 100644 convex_plane_decomposition/src/PlanarRegion.cpp create mode 100644 convex_plane_decomposition/test/testPlanarRegion.cpp diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index d7caaca2..f18606d1 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -5,7 +5,6 @@ project(convex_plane_decomposition) set(CATKIN_PACKAGE_DEPENDENCIES cgal5_catkin grid_map_core - ocs2_switched_model_interface grid_map_filters_rsl ) @@ -58,9 +57,10 @@ add_library(${PROJECT_NAME} src/contour_extraction/Upsampling.cpp src/ransac/RansacPlaneExtractor.cpp src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp - src/GridMapPreprocessing.cpp src/ConvexRegionGrowing.cpp src/Draw.cpp + src/GridMapPreprocessing.cpp + src/PlanarRegion.cpp src/Postprocessing.cpp ) add_dependencies(${PROJECT_NAME} @@ -93,10 +93,12 @@ install(DIRECTORY include/${PROJECT_NAME}/ ## Testing ## ############# -catkin_add_gtest(test_${PROJECT_NAME}_upsampling +catkin_add_gtest(test_${PROJECT_NAME} + test/testPlanarRegion.cpp + test/testRegionGrowing.cpp test/testUpsampling.cpp ) -target_link_libraries(test_${PROJECT_NAME}_upsampling +target_link_libraries(test_${PROJECT_NAME} ${PROJECT_NAME} ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} @@ -104,15 +106,3 @@ target_link_libraries(test_${PROJECT_NAME}_upsampling mpfr gtest_main ) - -catkin_add_gtest(test_${PROJECT_NAME}_regionGrowing - test/testRegionGrowing.cpp - ) -target_link_libraries(test_${PROJECT_NAME}_regionGrowing - ${PROJECT_NAME} - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - gmp - mpfr - gtest_main - ) \ No newline at end of file diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h b/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h index 3d3bc926..1d414ff4 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h @@ -5,17 +5,14 @@ #pragma once #include +#include #include -#include - #include "PolygonTypes.h" namespace convex_plane_decomposition { -using switched_model::TerrainPlane; - struct NormalAndPosition { /// 3D position. Eigen::Vector3d position; @@ -39,8 +36,8 @@ struct PlanarRegion { /// 2D bounding box in terrain frame containing all the boundary points CgalBbox2d bbox2d; - /// 3D parameters of the plane - TerrainPlane planeParameters; + /// 3D Transformation from terrain to world. v_world = T * v_plane. Use .linear() for the rotation and .translation() for the translation + Eigen::Isometry3d transformPlaneToWorld; }; struct PlanarTerrain { @@ -48,4 +45,22 @@ struct PlanarTerrain { grid_map::GridMap gridMap; }; +/** + * Convert a position and normal the a transform from the induced local frame and global frame. + * + * For example, if the normal and position are defined in world. We return a transform T terrain -> world, such that v_world = T * v_plane. + * The normal will be taken as the z-direction of the local frame. The x and y direction are arbitrary. + */ +Eigen::Isometry3d getTransformLocalToGlobal(const NormalAndPosition& normalAndPosition); + +/** + * Project a 2D point in world along gravity to obtain a 2D point in the plane + */ +CgalPoint2d projectToPlaneAlongGravity(const CgalPoint2d& worldFrameXY, const Eigen::Isometry3d& transformPlaneToWorld); + +/** + * Transforms a point on the plane to a 3D position expressed in the world frame + */ +Eigen::Vector3d positionInWorldFrameFromPosition2dInPlane(const CgalPoint2d& planeXY, const Eigen::Isometry3d& transformPlaneToWorld); + } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h index 568cdada..1c0cbe90 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h @@ -41,8 +41,6 @@ std::vector extractPolygonsFromBinaryImage(const cv::Mat CgalPolygon2d cgalPolygonFromOpenCv(const std::vector& openCvPolygon); -CgalPoint2d worldFrameToTerrainFrame(const CgalPoint2d& worldFrameXY, const TerrainPlane& plane); - CgalPoint2d pixelToWorldFrame(const CgalPoint2d& pixelspaceCgalPoint2d, double resolution, const Eigen::Vector2d& mapOffset); } // namespace contour_extraction diff --git a/convex_plane_decomposition/package.xml b/convex_plane_decomposition/package.xml index 43e12a95..b16a4e18 100644 --- a/convex_plane_decomposition/package.xml +++ b/convex_plane_decomposition/package.xml @@ -11,8 +11,6 @@ catkin cgal5_catkin grid_map_core - ocs2_switched_model_interface grid_map_filters_rsl - diff --git a/convex_plane_decomposition/src/PlanarRegion.cpp b/convex_plane_decomposition/src/PlanarRegion.cpp new file mode 100644 index 00000000..9497c941 --- /dev/null +++ b/convex_plane_decomposition/src/PlanarRegion.cpp @@ -0,0 +1,60 @@ +#include "convex_plane_decomposition/PlanarRegion.h" + +namespace convex_plane_decomposition { + +Eigen::Isometry3d getTransformLocalToGlobal(const NormalAndPosition& normalAndPosition) { + const Eigen::Vector3d zAxisInGlobal = normalAndPosition.normal.normalized(); + const auto& positionInGlobal = normalAndPosition.position; + + // Cross with any vector that is not equal to surfaceNormal + Eigen::Vector3d yAxisInGlobal = zAxisInGlobal.cross(Eigen::Vector3d::UnitX()); + { // Normalize the yAxis. Need to pick a different direction if z happened to intersect with unitX + const auto ySquaredNorm = yAxisInGlobal.squaredNorm(); + const double crossTolerance = 1e-3; + if (ySquaredNorm > crossTolerance) { + yAxisInGlobal /= std::sqrt(ySquaredNorm); + } else { + // normal was almost equal to unitX. Pick the y-axis in a different way (approximately equal to unitY): + yAxisInGlobal = zAxisInGlobal.cross(Eigen::Vector3d::UnitY().cross(zAxisInGlobal)).normalized(); + } + } + + Eigen::Isometry3d transform; + transform.linear().col(0) = yAxisInGlobal.cross(zAxisInGlobal); + transform.linear().col(1) = yAxisInGlobal; + transform.linear().col(2) = zAxisInGlobal; + transform.translation() = positionInGlobal; + + return transform; +} + +CgalPoint2d projectToPlaneAlongGravity(const CgalPoint2d& worldFrameXY, const Eigen::Isometry3d& transformPlaneToWorld) { + // Shorthands + const auto& xAxis = transformPlaneToWorld.linear().col(0); + const auto& yAxis = transformPlaneToWorld.linear().col(1); + const auto& surfaceNormalInWorld = transformPlaneToWorld.linear().col(2); + const auto& planeOriginInWorld = transformPlaneToWorld.translation(); + + // Horizontal difference + const double dx = worldFrameXY.x() - planeOriginInWorld.x(); + const double dy = worldFrameXY.y() - planeOriginInWorld.y(); + + // Vertical difference + // solve surfaceNormalInWorld.dot(projectedPosition - planeOriginInWorld) = 0 + // with projectPosition XY = worldFrameXY; + Eigen::Vector3d planeOriginToProjectedPointInWorld(dx, dy, (-dx * surfaceNormalInWorld.x() - dy * surfaceNormalInWorld.y()) / + surfaceNormalInWorld.z()); + + // Project XY coordinates to the plane frame + return {xAxis.dot(planeOriginToProjectedPointInWorld), yAxis.dot(planeOriginToProjectedPointInWorld)}; +} + +Eigen::Vector3d positionInWorldFrameFromPosition2dInPlane(const CgalPoint2d& planeXY, const Eigen::Isometry3d& transformPlaneToWorld) { + // Compute transform given that z in plane = 0.0 + Eigen::Vector3d pointInWorld = transformPlaneToWorld.translation(); + pointInWorld += planeXY.x() * transformPlaneToWorld.linear().col(0); + pointInWorld += planeXY.y() * transformPlaneToWorld.linear().col(1); + return pointInWorld; +} + +} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/convex_plane_decomposition/src/Postprocessing.cpp b/convex_plane_decomposition/src/Postprocessing.cpp index 4aacec43..4b07aadf 100644 --- a/convex_plane_decomposition/src/Postprocessing.cpp +++ b/convex_plane_decomposition/src/Postprocessing.cpp @@ -65,7 +65,7 @@ void Postprocessing::addHeightOffset(Eigen::MatrixXf& elevationData, const Eigen void Postprocessing::addHeightOffset(std::vector& planarRegions) const { if (parameters_.extracted_planes_height_offset != 0.0) { for (auto& planarRegion : planarRegions) { - planarRegion.planeParameters.positionInWorld.z() += parameters_.extracted_planes_height_offset; + planarRegion.transformPlaneToWorld.translation().z() += parameters_.extracted_planes_height_offset; } } } diff --git a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp index 190c2a1e..2c037d78 100644 --- a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp +++ b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp @@ -31,9 +31,6 @@ std::vector ContourExtraction::extractPlanarRegions(const Segmente std::vector planarRegions; for (const auto& label_plane : upSampledMap.labelPlaneParameters) { const int label = label_plane.first; - const auto terrainOrientation = switched_model::orientationWorldToTerrainFromSurfaceNormalInWorld(label_plane.second.normal); - const auto plane_parameters = switched_model::TerrainPlane(label_plane.second.position, terrainOrientation); - binaryImage_ = upSampledMap.labeledImage == label; // Try with safety margin @@ -48,16 +45,17 @@ std::vector ContourExtraction::extractPlanarRegions(const Segmente boundariesAndInsets = contour_extraction::extractBoundaryAndInset(binaryImage_, insetKernel_); } + const auto plane_parameters = getTransformLocalToGlobal(label_plane.second); for (auto& boundaryAndInset : boundariesAndInsets) { // Transform points from pixel space to local terrain frame transformInPlace(boundaryAndInset, [&](CgalPoint2d& point) { auto pointInWorld = pixelToWorldFrame(point, upSampledMap.resolution, upSampledMap.mapOrigin); - point = worldFrameToTerrainFrame(pointInWorld, plane_parameters); + point = projectToPlaneAlongGravity(pointInWorld, plane_parameters); }); PlanarRegion planarRegion; planarRegion.boundaryWithInset = std::move(boundaryAndInset); - planarRegion.planeParameters = plane_parameters; + planarRegion.transformPlaneToWorld = plane_parameters; planarRegion.bbox2d = planarRegion.boundaryWithInset.boundary.outer_boundary().bbox(); planarRegions.push_back(std::move(planarRegion)); } @@ -138,12 +136,6 @@ CgalPolygon2d cgalPolygonFromOpenCv(const std::vector& openCvPolygon) return polygon; } -CgalPoint2d worldFrameToTerrainFrame(const CgalPoint2d& worldFrameXY, const TerrainPlane& plane) { - const auto projectedPositionInWorld = projectPositionInWorldOntoPlaneAlongGravity({worldFrameXY.x(), worldFrameXY.y(), 0.0}, plane); - const auto positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(projectedPositionInWorld, plane); - return {positionInTerrainFrame.x(), positionInTerrainFrame.y()}; -} - CgalPoint2d pixelToWorldFrame(const CgalPoint2d& pixelspaceCgalPoint2d, double resolution, const Eigen::Vector2d& mapOffset) { // Notice the transpose of x and y! return {mapOffset.x() - resolution * pixelspaceCgalPoint2d.y(), mapOffset.y() - resolution * pixelspaceCgalPoint2d.x()}; diff --git a/convex_plane_decomposition/test/testPlanarRegion.cpp b/convex_plane_decomposition/test/testPlanarRegion.cpp new file mode 100644 index 00000000..3b33818e --- /dev/null +++ b/convex_plane_decomposition/test/testPlanarRegion.cpp @@ -0,0 +1,85 @@ +// +// Created by rgrandia on 15.03.22. +// + +#include + +#include "convex_plane_decomposition/PlanarRegion.h" + +using namespace convex_plane_decomposition; + +TEST(TestPlanarRegion, getTransformFromNormalAndPosition_identity) { + NormalAndPosition normalAndPosition = {Eigen::Vector3d::Zero(), Eigen::Vector3d::UnitZ()}; + const auto transform = getTransformLocalToGlobal(normalAndPosition); + + // Orientation + ASSERT_TRUE(transform.linear().isApprox(Eigen::Matrix3d::Identity())); + + // Position + ASSERT_TRUE(transform.translation().isApprox(normalAndPosition.position)); +} + +TEST(TestPlanarRegion, getTransformFromNormalAndPosition_random) { + NormalAndPosition normalAndPosition = {Eigen::Vector3d(0.1, 0.2, 0.3), Eigen::Vector3d(0.4, 0.5, 0.6).normalized()}; + const auto transform = getTransformLocalToGlobal(normalAndPosition); + + const Eigen::Vector3d xAxisInWorld = transform.linear().col(0); + const Eigen::Vector3d yAxisInWorld = transform.linear().col(1); + const Eigen::Vector3d zAxisInWorld = transform.linear().col(2); + + // Z direction + ASSERT_TRUE(zAxisInWorld.isApprox(normalAndPosition.normal)); + + // Orthogonal + ASSERT_LT(std::abs(zAxisInWorld.dot(yAxisInWorld)), 1e-12); + ASSERT_LT(std::abs(zAxisInWorld.dot(xAxisInWorld)), 1e-12); + + // Scale + ASSERT_DOUBLE_EQ(xAxisInWorld.norm(), 1.0); + ASSERT_DOUBLE_EQ(yAxisInWorld.norm(), 1.0); + + // Position + ASSERT_TRUE(transform.translation().isApprox(normalAndPosition.position)); +} + +TEST(TestPlanarRegion, getTransformFromNormalAndPosition_unitX) { + NormalAndPosition normalAndPosition = {Eigen::Vector3d(0.1, 0.2, 0.3), Eigen::Vector3d::UnitX()}; + const auto transform = getTransformLocalToGlobal(normalAndPosition); + + const Eigen::Vector3d xAxisInWorld = transform.linear().col(0); + const Eigen::Vector3d yAxisInWorld = transform.linear().col(1); + const Eigen::Vector3d zAxisInWorld = transform.linear().col(2); + + // Z direction + ASSERT_TRUE(zAxisInWorld.isApprox(normalAndPosition.normal)); + + // XY + ASSERT_TRUE(xAxisInWorld.isApprox(-Eigen::Vector3d::UnitZ())); + ASSERT_TRUE(yAxisInWorld.isApprox(Eigen::Vector3d::UnitY())); + + // Position + ASSERT_TRUE(transform.translation().isApprox(normalAndPosition.position)); +} + +TEST(TestPlanarRegion, projectPositionInWorldOntoPlaneAlongGravity) { + const NormalAndPosition normalAndPosition = {Eigen::Vector3d(0.1, 0.2, 0.3), Eigen::Vector3d(0.4, 0.5, 0.6).normalized()}; + const auto transformPlaneToWorld = getTransformLocalToGlobal(normalAndPosition); + + // Origin of plane is projected to 0, 0 + const CgalPoint2d originXY = {normalAndPosition.position.x(), normalAndPosition.position.y()}; + const CgalPoint2d originInPlane = projectToPlaneAlongGravity(originXY, transformPlaneToWorld); + ASSERT_LT(std::abs(originInPlane.x()), 1e-12); + ASSERT_LT(std::abs(originInPlane.y()), 1e-12); + + // Random point projected + const Eigen::Vector2d queryPosition = Eigen::Vector2d::Random(); + const CgalPoint2d projectedPositionInPlane = projectToPlaneAlongGravity({queryPosition.x(), queryPosition.y()}, transformPlaneToWorld); + + // Convert back to world to check + Eigen::Vector3d projectedPositionInPlane3d = {projectedPositionInPlane.x(), projectedPositionInPlane.y(), 0.0}; + Eigen::Vector3d projectedPositionInWorld3d = transformPlaneToWorld * projectedPositionInPlane3d; + + // x, y position remained to same + ASSERT_DOUBLE_EQ(projectedPositionInWorld3d.x(), queryPosition.x()); + ASSERT_DOUBLE_EQ(projectedPositionInWorld3d.y(), queryPosition.y()); +} \ No newline at end of file diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index a30f0a7d..581221ac 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -4,6 +4,7 @@ project(convex_plane_decomposition_ros) # Catkin dependencies set(CATKIN_PACKAGE_DEPENDENCIES roscpp + ocs2_core grid_map_core grid_map_ros grid_map_cv diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h index 24d40a11..53006225 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h @@ -27,8 +27,8 @@ convex_plane_decomposition_msgs::PlanarRegion toMessage(const PlanarRegion& plan PlanarTerrain fromMessage(const convex_plane_decomposition_msgs::PlanarTerrain& msg); convex_plane_decomposition_msgs::PlanarTerrain toMessage(const PlanarTerrain& planarTerrain); -TerrainPlane fromMessage(const geometry_msgs::Pose& msg); -geometry_msgs::Pose toMessage(const TerrainPlane& plane); +Eigen::Isometry3d fromMessage(const geometry_msgs::Pose& msg); +geometry_msgs::Pose toMessage(const Eigen::Isometry3d& transform); CgalPoint2d fromMessage(const convex_plane_decomposition_msgs::Point2d& msg); convex_plane_decomposition_msgs::Point2d toMessage(const CgalPoint2d& point2d); diff --git a/convex_plane_decomposition_ros/package.xml b/convex_plane_decomposition_ros/package.xml index 126edcfe..b79fa8c5 100644 --- a/convex_plane_decomposition_ros/package.xml +++ b/convex_plane_decomposition_ros/package.xml @@ -10,6 +10,7 @@ catkin roscpp + ocs2_core grid_map_core grid_map_ros grid_map_cv diff --git a/convex_plane_decomposition_ros/src/MessageConversion.cpp b/convex_plane_decomposition_ros/src/MessageConversion.cpp index 1e44dae2..5194bfe0 100644 --- a/convex_plane_decomposition_ros/src/MessageConversion.cpp +++ b/convex_plane_decomposition_ros/src/MessageConversion.cpp @@ -23,7 +23,7 @@ convex_plane_decomposition_msgs::BoundingBox2d toMessage(const CgalBbox2d& bbox2 PlanarRegion fromMessage(const convex_plane_decomposition_msgs::PlanarRegion& msg) { PlanarRegion planarRegion; - planarRegion.planeParameters = fromMessage(msg.plane_parameters); + planarRegion.transformPlaneToWorld = fromMessage(msg.plane_parameters); planarRegion.boundaryWithInset.boundary = fromMessage(msg.boundary); planarRegion.boundaryWithInset.insets.reserve(msg.insets.size()); for (const auto& inset : msg.insets) { @@ -35,7 +35,7 @@ PlanarRegion fromMessage(const convex_plane_decomposition_msgs::PlanarRegion& ms convex_plane_decomposition_msgs::PlanarRegion toMessage(const PlanarRegion& planarRegion) { convex_plane_decomposition_msgs::PlanarRegion msg; - msg.plane_parameters = toMessage(planarRegion.planeParameters); + msg.plane_parameters = toMessage(planarRegion.transformPlaneToWorld); msg.boundary = toMessage(planarRegion.boundaryWithInset.boundary); msg.insets.reserve(planarRegion.boundaryWithInset.insets.size()); for (const auto& inset : planarRegion.boundaryWithInset.insets) { @@ -65,26 +65,26 @@ convex_plane_decomposition_msgs::PlanarTerrain toMessage(const PlanarTerrain& pl return msg; } -TerrainPlane fromMessage(const geometry_msgs::Pose& msg) { - TerrainPlane plane; - plane.positionInWorld.x() = msg.position.x; - plane.positionInWorld.y() = msg.position.y; - plane.positionInWorld.z() = msg.position.z; - Eigen::Quaterniond terrainOrientation; - terrainOrientation.x() = msg.orientation.x; - terrainOrientation.y() = msg.orientation.y; - terrainOrientation.z() = msg.orientation.z; - terrainOrientation.w() = msg.orientation.w; - plane.orientationWorldToTerrain = terrainOrientation.toRotationMatrix().transpose(); - return plane; +Eigen::Isometry3d fromMessage(const geometry_msgs::Pose& msg) { + Eigen::Isometry3d transform; + transform.translation().x() = msg.position.x; + transform.translation().y() = msg.position.y; + transform.translation().z() = msg.position.z; + Eigen::Quaterniond orientation; + orientation.x() = msg.orientation.x; + orientation.y() = msg.orientation.y; + orientation.z() = msg.orientation.z; + orientation.w() = msg.orientation.w; + transform.linear() = orientation.toRotationMatrix(); + return transform; } -geometry_msgs::Pose toMessage(const TerrainPlane& plane) { +geometry_msgs::Pose toMessage(const Eigen::Isometry3d& transform) { geometry_msgs::Pose pose; - pose.position.x = plane.positionInWorld.x(); - pose.position.y = plane.positionInWorld.y(); - pose.position.z = plane.positionInWorld.z(); - Eigen::Quaterniond terrainOrientation(plane.orientationWorldToTerrain.transpose()); + pose.position.x = transform.translation().x(); + pose.position.y = transform.translation().y(); + pose.position.z = transform.translation().z(); + Eigen::Quaterniond terrainOrientation(transform.linear()); pose.orientation.x = terrainOrientation.x(); pose.orientation.y = terrainOrientation.y(); pose.orientation.z = terrainOrientation.z(); diff --git a/convex_plane_decomposition_ros/src/RosVisualizations.cpp b/convex_plane_decomposition_ros/src/RosVisualizations.cpp index 234c3e1a..c10e9c6e 100644 --- a/convex_plane_decomposition_ros/src/RosVisualizations.cpp +++ b/convex_plane_decomposition_ros/src/RosVisualizations.cpp @@ -5,13 +5,13 @@ namespace convex_plane_decomposition { -inline geometry_msgs::PolygonStamped to3d(const CgalPolygon2d& polygon, const TerrainPlane& planeParameters, +inline geometry_msgs::PolygonStamped to3d(const CgalPolygon2d& polygon, const Eigen::Isometry3d& transformPlaneToWorld, const std_msgs::Header& header) { geometry_msgs::PolygonStamped polygon3d; polygon3d.header = header; for (const auto& point : polygon) { geometry_msgs::Point32 point_ros; - const auto pointInWorld = positionInWorldFrameFromPositionInTerrain({point.x(), point.y(), 0.0}, planeParameters); + const auto pointInWorld = positionInWorldFrameFromPosition2dInPlane(point, transformPlaneToWorld); point_ros.x = pointInWorld.x(); point_ros.y = pointInWorld.y(); point_ros.z = pointInWorld.z(); @@ -20,15 +20,15 @@ inline geometry_msgs::PolygonStamped to3d(const CgalPolygon2d& polygon, const Te return polygon3d; } -inline std::vector to3d(const CgalPolygonWithHoles2d& polygonWithHoles, const TerrainPlane& planeParameters, +inline std::vector to3d(const CgalPolygonWithHoles2d& polygonWithHoles, const Eigen::Isometry3d& transformPlaneToWorld, const std_msgs::Header& header) { std::vector polygons; polygons.reserve(polygonWithHoles.number_of_holes() + 1); - polygons.emplace_back(to3d(polygonWithHoles.outer_boundary(), planeParameters, header)); + polygons.emplace_back(to3d(polygonWithHoles.outer_boundary(), transformPlaneToWorld, header)); for (const auto& hole : polygonWithHoles.holes()) { - polygons.emplace_back(to3d(hole, planeParameters, header)); + polygons.emplace_back(to3d(hole, transformPlaneToWorld, header)); } return polygons; } @@ -45,7 +45,7 @@ jsk_recognition_msgs::PolygonArray convertBoundariesToRosPolygons(const std::vec polygon_buffer.labels.reserve(planarRegions.size()); uint32_t label = 0; for (const auto& planarRegion : planarRegions) { - auto boundaries = to3d(planarRegion.boundaryWithInset.boundary, planarRegion.planeParameters, header); + auto boundaries = to3d(planarRegion.boundaryWithInset.boundary, planarRegion.transformPlaneToWorld, header); std::move(boundaries.begin(), boundaries.end(), std::back_inserter(polygon_buffer.polygons)); for (size_t i = 0; i < boundaries.size(); ++i) { polygon_buffer.labels.push_back(label); @@ -69,7 +69,7 @@ jsk_recognition_msgs::PolygonArray convertInsetsToRosPolygons(const std::vector< uint32_t label = 0; for (const auto& planarRegion : planarRegions) { for (const auto& inset : planarRegion.boundaryWithInset.insets) { - auto insets = to3d(inset, planarRegion.planeParameters, header); + auto insets = to3d(inset, planarRegion.transformPlaneToWorld, header); std::move(insets.begin(), insets.end(), std::back_inserter(polygon_buffer.polygons)); for (size_t i = 0; i < insets.size(); ++i) { polygon_buffer.labels.push_back(label); diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h index f8779221..25261dd2 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h @@ -21,19 +21,6 @@ double intervalSquareDistance(double value, double min, double max); double squaredDistanceToBoundingBox(const convex_plane_decomposition::CgalPoint2d& point, const convex_plane_decomposition::CgalBbox2d& boundingBox); -/** Converts a 3D position in world frame to a 2D position in the terrain frame. */ -inline convex_plane_decomposition::CgalPoint2d position2dInTerrainFrameFromPositionInWorld(const vector3_t& positionWorld, - const TerrainPlane& terrainPlane) { - const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionWorld, terrainPlane); - return {positionInTerrainFrame.x(), positionInTerrainFrame.y()}; -} - -/** Converts a 2D position in terrain frame to a 3D position in the world frame. */ -inline vector3_t positionInWorldFrameFromPosition2dInTerrain(const convex_plane_decomposition::CgalPoint2d& positionInTerrain, - const TerrainPlane& terrainPlane) { - return positionInWorldFrameFromPositionInTerrain({positionInTerrain.x(), positionInTerrain.y(), 0.0}, terrainPlane); -} - const convex_plane_decomposition::CgalPolygonWithHoles2d* findInsetContainingThePoint( const convex_plane_decomposition::CgalPoint2d& point, const std::vector& insets); diff --git a/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp b/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp index 11172165..1f00659b 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp @@ -92,7 +92,7 @@ std::vector sortWithBoundingBoxes(const vector3_t& positionIn std::vector regionsAndBboxSquareDistances; regionsAndBboxSquareDistances.reserve(planarRegions.size()); for (const auto& planarRegion : planarRegions) { - const auto& positionInTerrainFrame = positionInTerrainFrameFromPositionInWorld(positionInWorld, planarRegion.planeParameters); + const auto& positionInTerrainFrame = planarRegion.transformPlaneToWorld.inverse() * positionInWorld; const double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); RegionSortingInfo regionSortingInfo; @@ -129,13 +129,13 @@ std::pair getPlanarRegionAtPositionI // Shorthand const auto* regionPtr = regionInfo.regionPtr; - const auto& planeParameters = regionPtr->planeParameters; // Project onto planar region const auto projectedPointInTerrainFrame = projectToPlanarRegion(regionInfo.positionInTerrainFrame, *regionPtr); // Express projected point in World frame - const auto projectionInWorldFrame = positionInWorldFrameFromPosition2dInTerrain(projectedPointInTerrainFrame, planeParameters); + const auto projectionInWorldFrame = + convex_plane_decomposition::positionInWorldFrameFromPosition2dInPlane(projectedPointInTerrainFrame, regionPtr->transformPlaneToWorld); const scalar_t cost = distanceCost(positionInWorld, projectionInWorldFrame) + penaltyFunction(projectionInWorldFrame); if (cost < minCost) { diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index 393ebe78..1227e067 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -29,8 +29,9 @@ TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorldAlongG getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions, std::move(penaltyFunction)); const auto& region = *regionAndSeedPoint.first; const auto& seedpoint = regionAndSeedPoint.second; - const auto& seedpointInWorldFrame = positionInWorldFrameFromPosition2dInTerrain(seedpoint, region.planeParameters); - return TerrainPlane{seedpointInWorldFrame, region.planeParameters.orientationWorldToTerrain}; + const auto& seedpointInWorldFrame = + convex_plane_decomposition::positionInWorldFrameFromPosition2dInPlane(seedpoint, region.transformPlaneToWorld); + return TerrainPlane{seedpointInWorldFrame, region.transformPlaneToWorld.linear().transpose()}; } ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld( @@ -39,7 +40,8 @@ ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld( getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions, std::move(penaltyFunction)); const auto& region = *regionAndSeedPoint.first; const auto& seedpoint = regionAndSeedPoint.second; - const auto& seedpointInWorldFrame = positionInWorldFrameFromPosition2dInTerrain(seedpoint, region.planeParameters); + const auto& seedpointInWorldFrame = + convex_plane_decomposition::positionInWorldFrameFromPosition2dInPlane(seedpoint, region.transformPlaneToWorld); // Convert boundary and seedpoint to terrain frame const int numberOfVertices = 16; // Multiple of 4 is nice for symmetry. @@ -49,7 +51,7 @@ ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld( // Return convex region with origin at the seedpoint ConvexTerrain convexTerrain; - convexTerrain.plane = {seedpointInWorldFrame, region.planeParameters.orientationWorldToTerrain}; // Origin is at the seedpoint + convexTerrain.plane = {seedpointInWorldFrame, region.transformPlaneToWorld.linear().transpose()}; // Origin is at the seedpoint convexTerrain.boundary.reserve(convexRegion.size()); for (const auto& point : convexRegion) { convexTerrain.boundary.emplace_back(point.x() - seedpoint.x(), point.y() - seedpoint.y()); // Shift points to new origin @@ -60,8 +62,10 @@ ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld( void SegmentedPlanesTerrainModel::createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, const Eigen::Vector3d& maxCoordinates) { // Compute coordinates of submap - const auto minXY = grid_map::lookup::projectToMapWithMargin(planarTerrain_.gridMap, grid_map::Position(minCoordinates.x(), minCoordinates.y())); - const auto maxXY = grid_map::lookup::projectToMapWithMargin(planarTerrain_.gridMap, grid_map::Position(maxCoordinates.x(), maxCoordinates.y())); + const auto minXY = + grid_map::lookup::projectToMapWithMargin(planarTerrain_.gridMap, grid_map::Position(minCoordinates.x(), minCoordinates.y())); + const auto maxXY = + grid_map::lookup::projectToMapWithMargin(planarTerrain_.gridMap, grid_map::Position(maxCoordinates.x(), maxCoordinates.y())); const auto centerXY = 0.5 * (minXY + maxXY); const auto lengths = maxXY - minXY; From af37ee62268c942d66994b38122f159a256a0138 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 15 Mar 2022 17:38:50 +0100 Subject: [PATCH 168/504] copy the timer to get rid of ocs2_core dependency --- convex_plane_decomposition_ros/CMakeLists.txt | 1 - .../ConvexPlaneDecompositionRos.h | 14 ++-- .../convex_plane_decomposition_ros/Timer.h | 82 +++++++++++++++++++ convex_plane_decomposition_ros/package.xml | 1 - .../src/ConvexPlaneDecompositionRos.cpp | 4 +- 5 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/Timer.h diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/convex_plane_decomposition_ros/CMakeLists.txt index 581221ac..a30f0a7d 100644 --- a/convex_plane_decomposition_ros/CMakeLists.txt +++ b/convex_plane_decomposition_ros/CMakeLists.txt @@ -4,7 +4,6 @@ project(convex_plane_decomposition_ros) # Catkin dependencies set(CATKIN_PACKAGE_DEPENDENCIES roscpp - ocs2_core grid_map_core grid_map_ros grid_map_cv diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h index 5e14999f..15b8d350 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h @@ -10,10 +10,10 @@ #include -#include - #include +#include "Timer.h" + namespace convex_plane_decomposition { // Forward declarations @@ -70,11 +70,11 @@ class ConvexPlaneExtractionROS { std::unique_ptr postprocessing_; // Timing - ocs2::benchmark::RepeatedTimer callbackTimer_; - ocs2::benchmark::RepeatedTimer preprocessTimer_; - ocs2::benchmark::RepeatedTimer slidingWindowTimer_; - ocs2::benchmark::RepeatedTimer planeExtractionTimer_; - ocs2::benchmark::RepeatedTimer postprocessTimer_; + Timer callbackTimer_; + Timer preprocessTimer_; + Timer slidingWindowTimer_; + Timer planeExtractionTimer_; + Timer postprocessTimer_; }; } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/Timer.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/Timer.h new file mode 100644 index 00000000..3eaa93e6 --- /dev/null +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/Timer.h @@ -0,0 +1,82 @@ +// +// Created by rgrandia on 15.03.22. +// + +#pragma once + +namespace convex_plane_decomposition { + +/** + * Timer class that can be repeatedly started and stopped. Statistics are collected for all measured intervals . + * + * Taken and adapted from ocs2_core + */ +class Timer { + public: + Timer() + : numTimedIntervals_(0), + totalTime_(std::chrono::nanoseconds::zero()), + maxIntervalTime_(std::chrono::nanoseconds::zero()), + lastIntervalTime_(std::chrono::nanoseconds::zero()), + startTime_(std::chrono::steady_clock::now()) {} + + /** + * Reset the timer statistics + */ + void reset() { + totalTime_ = std::chrono::nanoseconds::zero(); + maxIntervalTime_ = std::chrono::nanoseconds::zero(); + lastIntervalTime_ = std::chrono::nanoseconds::zero(); + numTimedIntervals_ = 0; + } + + /** + * Start timing an interval + */ + void startTimer() { startTime_ = std::chrono::steady_clock::now(); } + + /** + * Stop timing of an interval + */ + void endTimer() { + auto endTime = std::chrono::steady_clock::now(); + lastIntervalTime_ = std::chrono::duration_cast(endTime - startTime_); + maxIntervalTime_ = std::max(maxIntervalTime_, lastIntervalTime_); + totalTime_ += lastIntervalTime_; + numTimedIntervals_++; + }; + + /** + * @return Number of intervals that were timed + */ + int getNumTimedIntervals() const { return numTimedIntervals_; } + + /** + * @return Total cumulative time of timed intervals + */ + double getTotalInMilliseconds() const { return std::chrono::duration(totalTime_).count(); } + + /** + * @return Maximum duration of a single interval + */ + double getMaxIntervalInMilliseconds() const { return std::chrono::duration(maxIntervalTime_).count(); } + + /** + * @return Duration of the last timed interval + */ + double getLastIntervalInMilliseconds() const { return std::chrono::duration(lastIntervalTime_).count(); } + + /** + * @return Average duration of all timed intervals + */ + double getAverageInMilliseconds() const { return getTotalInMilliseconds() / numTimedIntervals_; } + + private: + int numTimedIntervals_; + std::chrono::nanoseconds totalTime_; + std::chrono::nanoseconds maxIntervalTime_; + std::chrono::nanoseconds lastIntervalTime_; + std::chrono::steady_clock::time_point startTime_; +}; + +} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/convex_plane_decomposition_ros/package.xml b/convex_plane_decomposition_ros/package.xml index b79fa8c5..126edcfe 100644 --- a/convex_plane_decomposition_ros/package.xml +++ b/convex_plane_decomposition_ros/package.xml @@ -10,7 +10,6 @@ catkin roscpp - ocs2_core grid_map_core grid_map_ros grid_map_cv diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 57eb1eed..5c50dc50 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -40,7 +40,7 @@ ConvexPlaneExtractionROS::~ConvexPlaneExtractionROS() { infoStream << "\n########################################################################\n"; infoStream << "The benchmarking is computed over " << callbackTimer_.getNumTimedIntervals() << " iterations. \n"; infoStream << "PlaneExtraction Benchmarking : Average time [ms], Max time [ms]\n"; - auto printLine = [](std::string name, const ocs2::benchmark::RepeatedTimer& timer) { + auto printLine = [](std::string name, const Timer& timer) { std::stringstream ss; ss << std::fixed << std::setprecision(2); ss << "\t" << name << "\t: " << std::setw(17) << timer.getAverageInMilliseconds() << ", " << std::setw(13) @@ -207,7 +207,7 @@ Eigen::Isometry3d ConvexPlaneExtractionROS::getTransformToTargetFrame(const std: transformStamped = tfBuffer_.lookupTransform(targetFrameId_, sourceFrame, time); } catch (tf2::TransformException& ex) { ROS_ERROR("[ConvexPlaneExtractionROS] %s", ex.what()); - return Eigen::Isometry3d(); + return Eigen::Isometry3d::Identity(); } Eigen::Isometry3d transformation; From 75384750200abe04a5d20efcf0c7a621f8b48677 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 15 Mar 2022 18:24:17 +0100 Subject: [PATCH 169/504] fix doc --- .../include/convex_plane_decomposition/PlanarRegion.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h b/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h index 1d414ff4..5e90ac00 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h @@ -46,9 +46,9 @@ struct PlanarTerrain { }; /** - * Convert a position and normal the a transform from the induced local frame and global frame. + * Convert a position and normal the a transform from the induced local frame to the global frame. * - * For example, if the normal and position are defined in world. We return a transform T terrain -> world, such that v_world = T * v_plane. + * For example, if the normal and position are defined in world. We return a transform T, such that v_world = T * v_plane. * The normal will be taken as the z-direction of the local frame. The x and y direction are arbitrary. */ Eigen::Isometry3d getTransformLocalToGlobal(const NormalAndPosition& normalAndPosition); From 83ef49ce1eef985fef71eba97b68baa890c63100 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 15 Mar 2022 18:24:40 +0100 Subject: [PATCH 170/504] compute plane projection in one expression --- convex_plane_decomposition/src/PlanarRegion.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/convex_plane_decomposition/src/PlanarRegion.cpp b/convex_plane_decomposition/src/PlanarRegion.cpp index 9497c941..f0aa09f6 100644 --- a/convex_plane_decomposition/src/PlanarRegion.cpp +++ b/convex_plane_decomposition/src/PlanarRegion.cpp @@ -42,8 +42,8 @@ CgalPoint2d projectToPlaneAlongGravity(const CgalPoint2d& worldFrameXY, const Ei // Vertical difference // solve surfaceNormalInWorld.dot(projectedPosition - planeOriginInWorld) = 0 // with projectPosition XY = worldFrameXY; - Eigen::Vector3d planeOriginToProjectedPointInWorld(dx, dy, (-dx * surfaceNormalInWorld.x() - dy * surfaceNormalInWorld.y()) / - surfaceNormalInWorld.z()); + Eigen::Vector3d planeOriginToProjectedPointInWorld( + dx, dy, (-dx * surfaceNormalInWorld.x() - dy * surfaceNormalInWorld.y()) / surfaceNormalInWorld.z()); // Project XY coordinates to the plane frame return {xAxis.dot(planeOriginToProjectedPointInWorld), yAxis.dot(planeOriginToProjectedPointInWorld)}; @@ -51,9 +51,8 @@ CgalPoint2d projectToPlaneAlongGravity(const CgalPoint2d& worldFrameXY, const Ei Eigen::Vector3d positionInWorldFrameFromPosition2dInPlane(const CgalPoint2d& planeXY, const Eigen::Isometry3d& transformPlaneToWorld) { // Compute transform given that z in plane = 0.0 - Eigen::Vector3d pointInWorld = transformPlaneToWorld.translation(); - pointInWorld += planeXY.x() * transformPlaneToWorld.linear().col(0); - pointInWorld += planeXY.y() * transformPlaneToWorld.linear().col(1); + Eigen::Vector3d pointInWorld = transformPlaneToWorld.translation() + planeXY.x() * transformPlaneToWorld.linear().col(0) + + planeXY.y() * transformPlaneToWorld.linear().col(1); return pointInWorld; } From f2018e2988beac72cbb4f26912eda6d43e73ccf3 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 15 Mar 2022 18:25:03 +0100 Subject: [PATCH 171/504] reserve during msg creation --- convex_plane_decomposition_ros/src/RosVisualizations.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/convex_plane_decomposition_ros/src/RosVisualizations.cpp b/convex_plane_decomposition_ros/src/RosVisualizations.cpp index c10e9c6e..041e209a 100644 --- a/convex_plane_decomposition_ros/src/RosVisualizations.cpp +++ b/convex_plane_decomposition_ros/src/RosVisualizations.cpp @@ -9,6 +9,7 @@ inline geometry_msgs::PolygonStamped to3d(const CgalPolygon2d& polygon, const Ei const std_msgs::Header& header) { geometry_msgs::PolygonStamped polygon3d; polygon3d.header = header; + polygon3d.polygon.points.reserve(polygon.size()); for (const auto& point : polygon) { geometry_msgs::Point32 point_ros; const auto pointInWorld = positionInWorldFrameFromPosition2dInPlane(point, transformPlaneToWorld); From 47f28aa6bb3ce35ec7bc0036e2a628b95f682e12 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 15 Mar 2022 22:03:54 +0100 Subject: [PATCH 172/504] fix explicit cast to float --- convex_plane_decomposition_ros/src/RosVisualizations.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/convex_plane_decomposition_ros/src/RosVisualizations.cpp b/convex_plane_decomposition_ros/src/RosVisualizations.cpp index 041e209a..83a50e24 100644 --- a/convex_plane_decomposition_ros/src/RosVisualizations.cpp +++ b/convex_plane_decomposition_ros/src/RosVisualizations.cpp @@ -13,9 +13,9 @@ inline geometry_msgs::PolygonStamped to3d(const CgalPolygon2d& polygon, const Ei for (const auto& point : polygon) { geometry_msgs::Point32 point_ros; const auto pointInWorld = positionInWorldFrameFromPosition2dInPlane(point, transformPlaneToWorld); - point_ros.x = pointInWorld.x(); - point_ros.y = pointInWorld.y(); - point_ros.z = pointInWorld.z(); + point_ros.x = static_cast(pointInWorld.x()); + point_ros.y = static_cast(pointInWorld.y()); + point_ros.z = static_cast(pointInWorld.z()); polygon3d.polygon.points.push_back(point_ros); } return polygon3d; From 8b172a2536ccf4ceddc6b9f6817290545b518f8b Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 15 Mar 2022 22:06:00 +0100 Subject: [PATCH 173/504] use cv getTransformedMap, which avoids generating NaN values in the map --- .../src/ConvexPlaneDecompositionRos.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 5c50dc50..3bc47ee6 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -118,8 +119,8 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { std::string errorMsg; ros::Time timeStamp = ros::Time(0); // Use Time(0) to get the latest transform. if (tfBuffer_.canTransform(targetFrameId_, messageMap.getFrameId(), timeStamp, &errorMsg)) { - messageMap = - messageMap.getTransformedMap(getTransformToTargetFrame(messageMap.getFrameId(), timeStamp), elevationLayer_, targetFrameId_); + const auto transform = getTransformToTargetFrame(messageMap.getFrameId(), timeStamp); + messageMap = grid_map::GridMapCvProcessing::getTransformedMap(std::move(messageMap), transform, elevationLayer_, targetFrameId_); } else { ROS_ERROR_STREAM("[ConvexPlaneExtractionROS] " << errorMsg); callbackTimer_.endTimer(); From 107b53b14633529944a68069e68fb7bbf3c2c790 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 16 Mar 2022 12:36:02 +0100 Subject: [PATCH 174/504] split out the computation pipeline from the ros node. --- convex_plane_decomposition/CMakeLists.txt | 4 + .../GridMapPreprocessing.h | 6 +- .../LoadGridmapFromImage.h | 26 +++++ .../PlaneDecompositionPipeline.h | 79 +++++++++++++++ .../Postprocessing.h | 8 +- .../convex_plane_decomposition}/Timer.h | 0 .../ContourExtractionParameters.h | 2 +- .../ransac/RansacPlaneExtractorParameters.h | 8 +- .../SlidingWindowPlaneExtractor.h | 1 + .../SlidingWindowPlaneExtractorParameters.h | 12 +-- convex_plane_decomposition/package.xml | 1 + .../src/LoadGridmapFromImage.cpp | 36 +++++++ .../src/PlaneDecompositionPipeline.cpp | 45 +++++++++ .../contour_extraction/ContourExtraction.cpp | 2 +- .../SlidingWindowPlaneExtractor.cpp | 5 +- .../test/data/terrain.png | Bin 0 -> 112548 bytes .../test/testPipeline.cpp | 35 +++++++ .../ConvexPlaneDecompositionRos.h | 26 +---- .../src/ConvexPlaneDecompositionRos.cpp | 90 +++++------------- convex_plane_decomposition_ros/test/test.cpp | 29 ++---- 20 files changed, 283 insertions(+), 132 deletions(-) create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/LoadGridmapFromImage.h create mode 100644 convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h rename {convex_plane_decomposition_ros/include/convex_plane_decomposition_ros => convex_plane_decomposition/include/convex_plane_decomposition}/Timer.h (100%) create mode 100644 convex_plane_decomposition/src/LoadGridmapFromImage.cpp create mode 100644 convex_plane_decomposition/src/PlaneDecompositionPipeline.cpp create mode 100644 convex_plane_decomposition/test/data/terrain.png create mode 100644 convex_plane_decomposition/test/testPipeline.cpp diff --git a/convex_plane_decomposition/CMakeLists.txt b/convex_plane_decomposition/CMakeLists.txt index f18606d1..2dd3403b 100644 --- a/convex_plane_decomposition/CMakeLists.txt +++ b/convex_plane_decomposition/CMakeLists.txt @@ -5,6 +5,7 @@ project(convex_plane_decomposition) set(CATKIN_PACKAGE_DEPENDENCIES cgal5_catkin grid_map_core + grid_map_cv grid_map_filters_rsl ) @@ -60,7 +61,9 @@ add_library(${PROJECT_NAME} src/ConvexRegionGrowing.cpp src/Draw.cpp src/GridMapPreprocessing.cpp + src/LoadGridmapFromImage.cpp src/PlanarRegion.cpp + src/PlaneDecompositionPipeline.cpp src/Postprocessing.cpp ) add_dependencies(${PROJECT_NAME} @@ -94,6 +97,7 @@ install(DIRECTORY include/${PROJECT_NAME}/ ############# catkin_add_gtest(test_${PROJECT_NAME} + test/testPipeline.cpp test/testPlanarRegion.cpp test/testRegionGrowing.cpp test/testUpsampling.cpp diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h index abcf9e25..5f04874a 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h @@ -8,11 +8,11 @@ namespace convex_plane_decomposition { struct PreprocessingParameters { /// Resample to this resolution, set to negative values to skip - double resolution = -1.0; + double resolution = 0.04; /// Kernel size of the median filter, either 3 or 5 - int kernelSize = 5; + int kernelSize = 3; /// Number of times the image is filtered - int numberOfRepeats = 1; + int numberOfRepeats = 2; /// If the kernel size should increase each filter step. bool increasing = false; }; diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/LoadGridmapFromImage.h b/convex_plane_decomposition/include/convex_plane_decomposition/LoadGridmapFromImage.h new file mode 100644 index 00000000..1b8f117a --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/LoadGridmapFromImage.h @@ -0,0 +1,26 @@ +// +// Created by rgrandia on 16.03.22. +// + +#pragma once + +#include + +#include + +namespace convex_plane_decomposition { + +/** + * Load an elevation map from a grey scale image. + * + * @param filePath : absolute path to file + * @param elevationLayer : name of the elevation layer + * @param frameId : frame assigned to loaded map + * @param resolution : map resolution [m/pixel] + * @param scale : distance [m] between lowest and highest point in the map + * @return Gridmap with the loaded image as elevation layer. + */ +grid_map::GridMap loadGridmapFromImage(const std::string& filePath, const std::string& elevationLayer, const std::string& frameId, + double resolution, double scale); + +} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h b/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h new file mode 100644 index 00000000..459e8f44 --- /dev/null +++ b/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h @@ -0,0 +1,79 @@ +// +// Created by rgrandia on 16.03.22. +// + +#pragma once + +#include + +#include "convex_plane_decomposition/GridMapPreprocessing.h" +#include "convex_plane_decomposition/PlanarRegion.h" +#include "convex_plane_decomposition/Postprocessing.h" +#include "convex_plane_decomposition/Timer.h" +#include "convex_plane_decomposition/contour_extraction/ContourExtraction.h" +#include "convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h" + +namespace convex_plane_decomposition { + +/** + * Encloses the full plane decomposition pipeline: + * + * Input: + * - Elevation map + * Output: + * - Planar terrain (planes + filtered elevation map) + * - Segmented elevation map + */ +class PlaneDecompositionPipeline { + public: + /** Collection of all parameters of steps in the pipeline */ + struct Config { + PreprocessingParameters preprocessingParameters; + sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters slidingWindowPlaneExtractorParameters; + ransac_plane_extractor::RansacPlaneExtractorParameters ransacPlaneExtractorParameters; + contour_extraction::ContourExtractionParameters contourExtractionParameters; + PostprocessingParameters postprocessingParameters; + }; + + /** + * Constructor + * @param config : configuration containing all parameters of the pipeline + */ + PlaneDecompositionPipeline(const Config& config); + + /** + * Trigger update of the pipeline + * @param gridMap : gridmap to process. Will be modified and added to the resulting planar terrain. + * @param elevationLayer : Name of the elevation layer. + */ + void update(grid_map::GridMap&& gridMap, const std::string& elevationLayer); + + /// Access to the Pipeline result. + PlanarTerrain& getPlanarTerrain() { return planarTerrain_; } + + /// Fills in the resulting segmentation into a gridmap layer data. + void getSegmentation(grid_map::GridMap::Matrix& segmentation) const; + + // Timers + const Timer& getPrepocessTimer() const { return preprocessTimer_; } + const Timer& getSlidingWindowTimer() const { return slidingWindowTimer_; } + const Timer& getContourExtractionTimer() const { return contourExtractionTimer_; } + const Timer& getPostprocessTimer() const { return postprocessTimer_; } + + private: + PlanarTerrain planarTerrain_; + + // Pipeline + GridMapPreprocessing preprocessing_; + sliding_window_plane_extractor::SlidingWindowPlaneExtractor slidingWindowPlaneExtractor_; + contour_extraction::ContourExtraction contourExtraction_; + Postprocessing postprocessing_; + + // Timing + Timer preprocessTimer_; + Timer slidingWindowTimer_; + Timer contourExtractionTimer_; + Timer postprocessTimer_; +}; + +} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h b/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h index 5dfb751e..12b85323 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h @@ -9,19 +9,19 @@ struct PostprocessingParameters { double extracted_planes_height_offset = 0.0; /// Added offset in z direction added in cells that are not traversable - double nonplanar_height_offset = 0.0; + double nonplanar_height_offset = 0.02; /// Size of the kernel creating the boundary offset. In number of pixels. - int nonplanar_horizontal_offset = 2; + int nonplanar_horizontal_offset = 1; /// Half the width of the dilation used before the smooth layer [m] double smoothing_dilation_size = 0.2; /// Half the width of the box kernel used for the smooth layer [m] - double smoothing_box_kernel_size = 0.3; + double smoothing_box_kernel_size = 0.1; /// Half the width of the Gaussian kernel used for the smooth layer [m] - double smoothing_gauss_kernel_size = 0.1; + double smoothing_gauss_kernel_size = 0.05; }; class Postprocessing { diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/Timer.h b/convex_plane_decomposition/include/convex_plane_decomposition/Timer.h similarity index 100% rename from convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/Timer.h rename to convex_plane_decomposition/include/convex_plane_decomposition/Timer.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h index 662f4671..009bc37e 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h @@ -9,7 +9,7 @@ namespace contour_extraction { struct ContourExtractionParameters { /// Size of the kernel creating the boundary offset. In number of (sub) pixels. - int marginSize = 2; + int marginSize = 1; }; } // namespace contour_extraction diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h index bb1f3ba9..ef94c557 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h @@ -9,13 +9,13 @@ namespace ransac_plane_extractor { struct RansacPlaneExtractorParameters { /// Set probability to miss the largest primitive at each iteration. double probability = 0.01; - /// Detect shapes with at least 200 points. - double min_points = 200; + /// Detect shapes with at least N points. + double min_points = 4; /// [m] Set maximum Euclidean distance between a point and a shape. - double epsilon = 0.004; + double epsilon = 0.025; /// Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most /// 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon - double cluster_epsilon = 0.03; + double cluster_epsilon = 0.08; /// [deg] Set maximum normal deviation between cluster surface_normal and point normal. double normal_threshold = 25.0; }; diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h index f86fdc79..f60398ad 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h @@ -56,6 +56,7 @@ class SlidingWindowPlaneExtractor { int mapRows_; std::vector surfaceNormals_; + std::vector pointsWithNormal_; cv::Mat binaryImagePatch_; SegmentedPlanesMap segmentedPlanesMap_; diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h index 2309aaec..51009a4f 100644 --- a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h +++ b/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h @@ -16,16 +16,16 @@ struct SlidingWindowPlaneExtractorParameters { int planarity_opening_filter = 0; /// [-] Maximum allowed angle between the surface normal and the world-z direction for a patch (converted to dotproduct bound) - double plane_inclination_threshold = std::cos(70.0 * M_PI / 180.0); + double plane_inclination_threshold = std::cos(30.0 * M_PI / 180.0); /// [-] Maximum allowed angle between the surface normal and the world-z direction for a cell (converted to dotproduct bound) - double local_plane_inclination_threshold = std::cos(70.0 * M_PI / 180.0); + double local_plane_inclination_threshold = std::cos(35.0 * M_PI / 180.0); /// [m] The allowed root-mean-squared deviation from the plane fitted to the patch. Higher -> not planar - double plane_patch_error_threshold = 0.005; + double plane_patch_error_threshold = 0.02; /// [#] Labels with less points assigned to them are discarded - int min_number_points_per_label = 10; + int min_number_points_per_label = 4; /// Label kernel connectivity. 4 or 8 (cross or box) int connectivity = 4; @@ -34,10 +34,10 @@ struct SlidingWindowPlaneExtractorParameters { bool include_ransac_refinement = true; /// [m] Allowed maximum distance from a point to the plane. If any point violates this, RANSAC is triggered - double global_plane_fit_distance_error_threshold = 0.04; + double global_plane_fit_distance_error_threshold = 0.025; /// [deg] Allowed normal vector deviation for a point w.r.t. the plane normal. If any point violates this, RANSAC is triggered - double global_plane_fit_angle_error_threshold_degrees = 5.0; + double global_plane_fit_angle_error_threshold_degrees = 25.0; }; } // namespace sliding_window_plane_extractor diff --git a/convex_plane_decomposition/package.xml b/convex_plane_decomposition/package.xml index b16a4e18..38f1d22b 100644 --- a/convex_plane_decomposition/package.xml +++ b/convex_plane_decomposition/package.xml @@ -11,6 +11,7 @@ catkin cgal5_catkin grid_map_core + grid_map_cv grid_map_filters_rsl diff --git a/convex_plane_decomposition/src/LoadGridmapFromImage.cpp b/convex_plane_decomposition/src/LoadGridmapFromImage.cpp new file mode 100644 index 00000000..2f1fc783 --- /dev/null +++ b/convex_plane_decomposition/src/LoadGridmapFromImage.cpp @@ -0,0 +1,36 @@ +// +// Created by rgrandia on 16.03.22. +// + +#include "convex_plane_decomposition/LoadGridmapFromImage.h" + +#include +#include + +#include + +namespace convex_plane_decomposition { + +grid_map::GridMap loadGridmapFromImage(const std::string& filePath, const std::string& elevationLayer, const std::string& frameId, + double resolution, double scale) { + // Read the file + cv::Mat image; + image = cv::imread(filePath, cv::ImreadModes::IMREAD_GRAYSCALE); + + // Check for invalid input + if (!image.data) { + throw std::runtime_error("Could not open or find the image"); + } + + // Min max values + double minValue, maxValue; + cv::minMaxLoc(image, &minValue, &maxValue); + + grid_map::GridMap mapOut({elevationLayer}); + mapOut.setFrameId(frameId); + grid_map::GridMapCvConverter::initializeFromImage(image, resolution, mapOut, grid_map::Position(0.0, 0.0)); + grid_map::GridMapCvConverter::addLayerFromImage(image, elevationLayer, mapOut, float(0.0), float(scale), 0.5); + return mapOut; +} + +} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/convex_plane_decomposition/src/PlaneDecompositionPipeline.cpp b/convex_plane_decomposition/src/PlaneDecompositionPipeline.cpp new file mode 100644 index 00000000..573fc580 --- /dev/null +++ b/convex_plane_decomposition/src/PlaneDecompositionPipeline.cpp @@ -0,0 +1,45 @@ +#include "convex_plane_decomposition/PlaneDecompositionPipeline.h" + +#include + +namespace convex_plane_decomposition { + +PlaneDecompositionPipeline::PlaneDecompositionPipeline(const Config& config) + : preprocessing_(config.preprocessingParameters), + slidingWindowPlaneExtractor_(config.slidingWindowPlaneExtractorParameters, config.ransacPlaneExtractorParameters), + contourExtraction_(config.contourExtractionParameters), + postprocessing_(config.postprocessingParameters) {} + +void PlaneDecompositionPipeline::update(grid_map::GridMap&& gridMap, const std::string& elevationLayer) { + // Clear / Overwrite old result + planarTerrain_.planarRegions.clear(); + planarTerrain_.gridMap = std::move(gridMap); + + preprocessTimer_.startTimer(); + preprocessing_.preprocess(planarTerrain_.gridMap, elevationLayer); + preprocessTimer_.endTimer(); + + slidingWindowTimer_.startTimer(); + slidingWindowPlaneExtractor_.runExtraction(planarTerrain_.gridMap, elevationLayer); + slidingWindowTimer_.endTimer(); + + contourExtractionTimer_.startTimer(); + planarTerrain_.planarRegions = contourExtraction_.extractPlanarRegions(slidingWindowPlaneExtractor_.getSegmentedPlanesMap()); + contourExtractionTimer_.endTimer(); + + postprocessTimer_.startTimer(); + // Add binary map + const std::string planeClassificationLayer{"plane_classification"}; + planarTerrain_.gridMap.add(planeClassificationLayer); + auto& traversabilityMask = planarTerrain_.gridMap.get(planeClassificationLayer); + cv::cv2eigen(slidingWindowPlaneExtractor_.getBinaryLabeledImage(), traversabilityMask); + + postprocessing_.postprocess(planarTerrain_, elevationLayer, planeClassificationLayer); + postprocessTimer_.endTimer(); +} + +void PlaneDecompositionPipeline::getSegmentation(grid_map::GridMap::Matrix& segmentation) const { + cv::cv2eigen(slidingWindowPlaneExtractor_.getSegmentedPlanesMap().labeledImage, segmentation); +} + +} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp index 2c037d78..ee5a3fc9 100644 --- a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp +++ b/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp @@ -29,6 +29,7 @@ std::vector ContourExtraction::extractPlanarRegions(const Segmente const auto upSampledMap = upSample(segmentedPlanesMap); std::vector planarRegions; + planarRegions.reserve(upSampledMap.highestLabel + 1); // Can be more or less in the end if regions are split or removed. for (const auto& label_plane : upSampledMap.labelPlaneParameters) { const int label = label_plane.first; binaryImage_ = upSampledMap.labeledImage == label; @@ -64,7 +65,6 @@ std::vector ContourExtraction::extractPlanarRegions(const Segmente } std::vector extractBoundaryAndInset(cv::Mat& binary_image, const cv::Mat& erosionKernel) { - // Get boundary std::vector boundaries = extractPolygonsFromBinaryImage(binary_image); diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp index 433e0ac6..04c488d6 100644 --- a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ b/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp @@ -154,12 +154,11 @@ void SlidingWindowPlaneExtractor::extractPlaneParametersFromLabeledImage() { segmentedPlanesMap_.highestLabel; // Make local copy. The highestLabel is incremented inside the loop // Reserve a workvector that is reused between processing labels - std::vector pointsWithNormal; - pointsWithNormal.reserve(segmentedPlanesMap_.labeledImage.rows * segmentedPlanesMap_.labeledImage.cols); + pointsWithNormal_.reserve(segmentedPlanesMap_.labeledImage.rows * segmentedPlanesMap_.labeledImage.cols); // Skip label 0. This is the background, i.e. non-planar region. for (int label = 1; label <= numberOfExtractedPlanesWithoutRefinement; ++label) { - computePlaneParametersForLabel(label, pointsWithNormal); + computePlaneParametersForLabel(label, pointsWithNormal_); } } diff --git a/convex_plane_decomposition/test/data/terrain.png b/convex_plane_decomposition/test/data/terrain.png new file mode 100644 index 0000000000000000000000000000000000000000..65cfe247f929043833c3d49de1f345a4a17f7adf GIT binary patch literal 112548 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≶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 g`e0c+1#i3!b+ + +#include + +#include "convex_plane_decomposition/LoadGridmapFromImage.h" +#include "convex_plane_decomposition/PlaneDecompositionPipeline.h" + +using namespace convex_plane_decomposition; + +TEST(TestPipeline, runOnDemoMap) { + // Config + PlaneDecompositionPipeline::Config config; + const auto resolution = config.preprocessingParameters.resolution; + const std::string elevationLayer{"elevation_test"}; + const std::string frameId{"odom_test"}; + const Eigen::Array2d submapSize(3.0, 3.0); + std::string file = "terrain.png"; + double heightScale = 1.25; + + // Terrain Loading + boost::filesystem::path filePath(__FILE__); + std::string folder = filePath.parent_path().generic_string() + std::string{"/data/"}; + const auto loadedMap = loadGridmapFromImage(folder + file, elevationLayer, frameId, resolution, heightScale); + bool success = false; + auto elevationMap = loadedMap.getSubmap(loadedMap.getPosition(), submapSize, success); + ASSERT_TRUE(success); + + // Run + PlaneDecompositionPipeline pipeline(config); + ASSERT_NO_THROW(pipeline.update(std::move(elevationMap), elevationLayer)); +} diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h index 15b8d350..a51ae69a 100644 --- a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h +++ b/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include @@ -12,19 +11,12 @@ #include -#include "Timer.h" +#include namespace convex_plane_decomposition { -// Forward declarations -class GridMapPreprocessing; -class Postprocessing; -namespace sliding_window_plane_extractor { -class SlidingWindowPlaneExtractor; -} -namespace contour_extraction { -class ContourExtraction; -} +// Forward declaration of the pipeline +class PlaneDecompositionPipeline; class ConvexPlaneExtractionROS { public: @@ -32,9 +24,9 @@ class ConvexPlaneExtractionROS { ~ConvexPlaneExtractionROS(); + private: bool loadParameters(const ros::NodeHandle& nodeHandle); - private: /** * Callback method for the incoming grid map message. * @param message the incoming message. @@ -63,18 +55,10 @@ class ConvexPlaneExtractionROS { tf2_ros::TransformListener tfListener_; // Pipeline - std::mutex mutex_; - std::unique_ptr preprocessing_; - std::unique_ptr slidingWindowPlaneExtractor_; - std::unique_ptr contourExtraction_; - std::unique_ptr postprocessing_; + std::unique_ptr planeDecompositionPipeline_; // Timing Timer callbackTimer_; - Timer preprocessTimer_; - Timer slidingWindowTimer_; - Timer planeExtractionTimer_; - Timer postprocessTimer_; }; } // namespace convex_plane_decomposition diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index 3bc47ee6..ed569c7c 100644 --- a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -1,20 +1,10 @@ #include "convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h" -#include - -#include - -#include - #include -#include #include +#include -#include -#include -#include -#include - +#include #include #include "convex_plane_decomposition_ros/MessageConversion.h" @@ -36,8 +26,8 @@ ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle) } ConvexPlaneExtractionROS::~ConvexPlaneExtractionROS() { - std::stringstream infoStream; - if (callbackTimer_.getNumTimedIntervals() > 0) { + if (callbackTimer_.getNumTimedIntervals() > 0 && planeDecompositionPipeline_ != nullptr) { + std::stringstream infoStream; infoStream << "\n########################################################################\n"; infoStream << "The benchmarking is computed over " << callbackTimer_.getNumTimedIntervals() << " iterations. \n"; infoStream << "PlaneExtraction Benchmarking : Average time [ms], Max time [ms]\n"; @@ -48,13 +38,13 @@ ConvexPlaneExtractionROS::~ConvexPlaneExtractionROS() { << timer.getMaxIntervalInMilliseconds() << "\n"; return ss.str(); }; - infoStream << printLine("Pre-process ", preprocessTimer_); - infoStream << printLine("Sliding window ", slidingWindowTimer_); - infoStream << printLine("Plane extraction", planeExtractionTimer_); - infoStream << printLine("Post-process ", postprocessTimer_); - infoStream << printLine("Total callback ", callbackTimer_); + infoStream << printLine("Pre-process ", planeDecompositionPipeline_->getPrepocessTimer()); + infoStream << printLine("Sliding window ", planeDecompositionPipeline_->getSlidingWindowTimer()); + infoStream << printLine("Contour extraction ", planeDecompositionPipeline_->getContourExtractionTimer()); + infoStream << printLine("Post-process ", planeDecompositionPipeline_->getPostprocessTimer()); + infoStream << printLine("Total callback ", callbackTimer_); + std::cerr << infoStream.str() << std::endl; } - std::cerr << infoStream.str() << std::endl; } bool ConvexPlaneExtractionROS::loadParameters(const ros::NodeHandle& nodeHandle) { @@ -83,25 +73,19 @@ bool ConvexPlaneExtractionROS::loadParameters(const ros::NodeHandle& nodeHandle) return false; } - const auto preprocessingParameters = loadPreprocessingParameters(nodeHandle, "preprocessing/"); - const auto contourExtractionParameters = loadContourExtractionParameters(nodeHandle, "contour_extraction/"); - const auto ransacPlaneExtractorParameters = loadRansacPlaneExtractorParameters(nodeHandle, "ransac_plane_refinement/"); - const auto slidingWindowPlaneExtractorParameters = - loadSlidingWindowPlaneExtractorParameters(nodeHandle, "sliding_window_plane_extractor/"); - const auto postprocessingParameters = loadPostprocessingParameters(nodeHandle, "postprocessing/"); + PlaneDecompositionPipeline::Config config; + config.preprocessingParameters = loadPreprocessingParameters(nodeHandle, "preprocessing/"); + config.contourExtractionParameters = loadContourExtractionParameters(nodeHandle, "contour_extraction/"); + config.ransacPlaneExtractorParameters = loadRansacPlaneExtractorParameters(nodeHandle, "ransac_plane_refinement/"); + config.slidingWindowPlaneExtractorParameters = loadSlidingWindowPlaneExtractorParameters(nodeHandle, "sliding_window_plane_extractor/"); + config.postprocessingParameters = loadPostprocessingParameters(nodeHandle, "postprocessing/"); - std::lock_guard lock(mutex_); - preprocessing_ = std::make_unique(preprocessingParameters); - slidingWindowPlaneExtractor_ = std::make_unique( - slidingWindowPlaneExtractorParameters, ransacPlaneExtractorParameters); - contourExtraction_ = std::make_unique(contourExtractionParameters); - postprocessing_ = std::make_unique(postprocessingParameters); + planeDecompositionPipeline_ = std::make_unique(config); return true; } void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { - std::lock_guard lock(mutex_); callbackTimer_.startTimer(); // Convert message to map. @@ -117,7 +101,7 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { // Transform map if necessary if (targetFrameId_ != messageMap.getFrameId()) { std::string errorMsg; - ros::Time timeStamp = ros::Time(0); // Use Time(0) to get the latest transform. + ros::Time timeStamp = ros::Time(0); // Use Time(0) to get the latest transform. if (tfBuffer_.canTransform(targetFrameId_, messageMap.getFrameId(), timeStamp, &errorMsg)) { const auto transform = getTransformToTargetFrame(messageMap.getFrameId(), timeStamp); messageMap = grid_map::GridMapCvProcessing::getTransformedMap(std::move(messageMap), transform, elevationLayer_, targetFrameId_); @@ -147,32 +131,9 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { } const grid_map::Matrix elevationRaw = elevationMap.get(elevationLayer_); - preprocessTimer_.startTimer(); - preprocessing_->preprocess(elevationMap, elevationLayer_); - preprocessTimer_.endTimer(); - // Run pipeline. - slidingWindowTimer_.startTimer(); - slidingWindowPlaneExtractor_->runExtraction(elevationMap, elevationLayer_); - slidingWindowTimer_.endTimer(); - - planeExtractionTimer_.startTimer(); - PlanarTerrain planarTerrain; - planarTerrain.planarRegions = contourExtraction_->extractPlanarRegions(slidingWindowPlaneExtractor_->getSegmentedPlanesMap()); - planeExtractionTimer_.endTimer(); - - // Add grid map to the terrain - postprocessTimer_.startTimer(); - planarTerrain.gridMap = std::move(elevationMap); - - // Add binary map - const std::string planeClassificationLayer{"plane_classification"}; - planarTerrain.gridMap.add(planeClassificationLayer); - auto& traversabilityMask = planarTerrain.gridMap.get(planeClassificationLayer); - cv::cv2eigen(slidingWindowPlaneExtractor_->getBinaryLabeledImage(), traversabilityMask); - - postprocessing_->postprocess(planarTerrain, elevationLayer_, planeClassificationLayer); - postprocessTimer_.endTimer(); + planeDecompositionPipeline_->update(std::move(elevationMap), elevationLayer_); + auto& planarTerrain = planeDecompositionPipeline_->getPlanarTerrain(); // Publish terrain if (publishToController_) { @@ -183,12 +144,9 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { // Add raw map planarTerrain.gridMap.add("elevation_raw", elevationRaw); - // Add surface normals - slidingWindowPlaneExtractor_->addSurfaceNormalToMap(planarTerrain.gridMap, "normal"); - - // Add surface normals + // Add segmentation planarTerrain.gridMap.add("segmentation"); - cv::cv2eigen(slidingWindowPlaneExtractor_->getSegmentedPlanesMap().labeledImage, planarTerrain.gridMap.get("segmentation")); + planeDecompositionPipeline_->getSegmentation(planarTerrain.gridMap.get("segmentation")); grid_map_msgs::GridMap outputMessage; grid_map::GridMapRosConverter::toMessage(planarTerrain.gridMap, outputMessage); @@ -196,8 +154,8 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { boundaryPublisher_.publish(convertBoundariesToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId(), planarTerrain.gridMap.getTimestamp())); - insetPublisher_.publish(convertInsetsToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId(), - planarTerrain.gridMap.getTimestamp())); + insetPublisher_.publish( + convertInsetsToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId(), planarTerrain.gridMap.getTimestamp())); callbackTimer_.endTimer(); } diff --git a/convex_plane_decomposition_ros/test/test.cpp b/convex_plane_decomposition_ros/test/test.cpp index b2d8bb66..f952b6d3 100644 --- a/convex_plane_decomposition_ros/test/test.cpp +++ b/convex_plane_decomposition_ros/test/test.cpp @@ -9,38 +9,20 @@ #include #include +#include + #include #include #include #include #include +#include #include #include using namespace convex_plane_decomposition; -grid_map::GridMap loadElevationMapFromFile(const std::string& filePath, double resolution, double scale) { - // Read the file - cv::Mat image; - image = cv::imread(filePath, cv::ImreadModes::IMREAD_GRAYSCALE); - - // Check for invalid input - if (!image.data) { - throw std::runtime_error("Could not open or find the image"); - } - - // Min max values - double minValue, maxValue; - cv::minMaxLoc(image, &minValue, &maxValue); - - grid_map::GridMap mapOut({"elevation"}); - mapOut.setFrameId("odom"); - grid_map::GridMapCvConverter::initializeFromImage(image, resolution, mapOut, grid_map::Position(0.0, 0.0)); - grid_map::GridMapCvConverter::addLayerFromImage(image, std::string("elevation"), mapOut, float(0.0), float(scale), 0.5); - return mapOut; -} - void plotSlidingWindow(const sliding_window_plane_extractor::SlidingWindowPlaneExtractor& planeExtractor) { cv::namedWindow("Sliding Window binarymap", cv::WindowFlags::WINDOW_NORMAL); cv::Mat binaryImage = planeExtractor.getBinaryLabeledImage(); @@ -74,7 +56,8 @@ void plotSlidingWindow(const sliding_window_plane_extractor::SlidingWindowPlaneE } int main(int argc, char** argv) { - std::string folder = "/home/rgrandia/git/anymal/convex_terrain_representation/convex_plane_decomposition_ros/data/"; + boost::filesystem::path filePath(__FILE__); + std::string folder = filePath.parent_path().parent_path().generic_string() + std::string{"/data/"}; std::string file = "elevationMap_8_139cm.png"; double heightScale = 1.39; // std::string file = "demo_map.png"; double heightScale = 1.25; @@ -85,7 +68,7 @@ int main(int argc, char** argv) { // std::string file = "straightStairs_1m_1m_60cm.png"; double heightScale = 0.6; double resolution = 0.02; - auto elevationMap = loadElevationMapFromFile(folder + file, resolution, heightScale); + auto elevationMap = loadGridmapFromImage(folder + file, "elevation", "odom", resolution, heightScale); cv::Mat image; grid_map::GridMapCvConverter::toImage(elevationMap, "elevation", CV_8UC1, 0.0, heightScale, image); From ca8f4a98c268a9fc9457024d844e31aeee2ad013 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 17 Mar 2022 15:21:52 +0100 Subject: [PATCH 175/504] refactor sdf: - Do the switched_model wrapping in the segmented_planes_model - Clean up dependencies - Prepare types and namespaces to fit grid_map - Extend documentation --- .../SegmentedPlanesSignedDistanceField.h | 53 ++++++++ .../SegmentedPlanesTerrainModel.h | 6 +- .../src/DemoNode.cpp | 10 +- .../src/SegmentedPlanesTerrainModel.cpp | 4 +- .../test/signedDistanceTest.cpp | 5 +- signed_distance_field/CMakeLists.txt | 18 ++- .../DistanceDerivatives.h | 43 +++++-- .../signed_distance_field/Gridmap3dLookup.h | 20 +-- .../GridmapSignedDistanceField.h | 115 ++++++++++++++---- .../PixelBorderDistance.h | 4 +- .../signed_distance_field/SignedDistance2d.h | 21 +++- .../include/signed_distance_field/Utils.h | 7 +- signed_distance_field/package.xml | 1 - .../src/GridmapSignedDistanceField.cpp | 108 ++++++++-------- .../src/PixelBorderDistance.cpp | 7 -- .../src/SignedDistance2d.cpp | 51 ++++---- .../test/naiveSignedDistance.h | 19 +-- signed_distance_field/test/test3dLookup.cpp | 21 ++-- .../test/testDerivatives.cpp | 11 +- .../test/testPixelBorderDistance.cpp | 7 +- .../test/testSignedDistance2d.cpp | 69 ++++++----- .../test/testSignedDistance3d.cpp | 63 +++++----- 22 files changed, 411 insertions(+), 252 deletions(-) create mode 100644 segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h delete mode 100644 signed_distance_field/src/PixelBorderDistance.cpp diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h new file mode 100644 index 00000000..46aa3e73 --- /dev/null +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h @@ -0,0 +1,53 @@ +// +// Created by rgrandia on 17.03.22. +// + +#pragma once + +#include + +#include + +namespace switched_model { + +/** + * Simple wrapper class to implement the switched_model::SignedDistanceField interface. + * See the forwarded function for documentation. + */ +class SegmentedPlanesSignedDistanceField : public SignedDistanceField { + public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + SegmentedPlanesSignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, double minHeight, + double maxHeight) + : sdf_(gridMap, elevationLayer, minHeight, maxHeight) {} + + ~SegmentedPlanesSignedDistanceField() override = default; + SegmentedPlanesSignedDistanceField* clone() const override { return new SegmentedPlanesSignedDistanceField(*this); }; + + switched_model::scalar_t value(const switched_model::vector3_t& position) const override { return sdf_.value(position); } + + switched_model::vector3_t derivative(const switched_model::vector3_t& position) const override { return sdf_.derivative(position); } + + std::pair valueAndDerivative( + const switched_model::vector3_t& position) const override { + return sdf_.valueAndDerivative(position); + } + + pcl::PointCloud asPointCloud( + size_t decimation = 1, const std::function& condition = [](float) { return true; }) const { + return sdf_.asPointCloud(decimation, condition); + } + + pcl::PointCloud freeSpacePointCloud(size_t decimation = 1) const { return sdf_.freeSpacePointCloud(decimation); } + + pcl::PointCloud obstaclePointCloud(size_t decimation = 1) const { return sdf_.obstaclePointCloud(decimation); } + + protected: + SegmentedPlanesSignedDistanceField(const SegmentedPlanesSignedDistanceField& other) : sdf_(other.sdf_){}; + + private: + grid_map::GridmapSignedDistanceField sdf_; +}; + +} // namespace switched_model \ No newline at end of file diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h index f8fdf4b6..1e2240f8 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h @@ -7,7 +7,7 @@ #include #include -#include +#include "segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h" namespace switched_model { @@ -24,7 +24,7 @@ class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { void createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, const Eigen::Vector3d& maxCoordinates); - const signed_distance_field::GridmapSignedDistanceField* getSignedDistanceField() const override { return signedDistanceField_.get(); } + const SegmentedPlanesSignedDistanceField* getSignedDistanceField() const override { return signedDistanceField_.get(); } vector3_t getHighestObstacleAlongLine(const vector3_t& position1InWorld, const vector3_t& position2InWorld) const override; @@ -34,7 +34,7 @@ class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { private: const convex_plane_decomposition::PlanarTerrain planarTerrain_; - std::unique_ptr signedDistanceField_; + std::unique_ptr signedDistanceField_; const grid_map::Matrix* const elevationData_; }; diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp index 2e4a0d81..edca9ae6 100644 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ b/segmented_planes_terrain_model/src/DemoNode.cpp @@ -12,13 +12,13 @@ #include #include #include -#include #include #include #include #include +#include "segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h" #include "segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h" const std::string frameId_ = "odom"; @@ -102,14 +102,14 @@ int main(int argc, char** argv) { grid_map::GridMap localMap = messageMap->getSubmap({convexTerrain.plane.positionInWorld.x(), convexTerrain.plane.positionInWorld.y()}, Eigen::Array2d(width, length), success); auto t2 = std::chrono::high_resolution_clock::now(); - signed_distance_field::GridmapSignedDistanceField sdf(localMap, "elevation", - convexTerrain.plane.positionInWorld.z() - heightClearance, - convexTerrain.plane.positionInWorld.z() + heightClearance); + switched_model::SegmentedPlanesSignedDistanceField sdf(localMap, "elevation", + convexTerrain.plane.positionInWorld.z() - heightClearance, + convexTerrain.plane.positionInWorld.z() + heightClearance); auto t3 = std::chrono::high_resolution_clock::now(); std::cout << "Sdf computation took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]\n"; auto t4 = std::chrono::high_resolution_clock::now(); - auto sdfClone = std::unique_ptr(sdf.clone()); + auto sdfClone = std::unique_ptr(sdf.clone()); auto t5 = std::chrono::high_resolution_clock::now(); std::cout << "Sdf.clone() computation took " << 1e-3 * std::chrono::duration_cast(t5 - t4).count() << " [ms]\n"; diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp index 1227e067..21e3c396 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp @@ -7,7 +7,7 @@ #include #include -#include + #include #include "segmented_planes_terrain_model/SegmentedPlaneProjection.h" @@ -72,7 +72,7 @@ void SegmentedPlanesTerrainModel::createSignedDistanceBetween(const Eigen::Vecto bool success = true; grid_map::GridMap subMap = planarTerrain_.gridMap.getSubmap(centerXY, lengths, success); if (success) { - signedDistanceField_ = std::make_unique(subMap, elevationLayerName, + signedDistanceField_ = std::make_unique(subMap, elevationLayerName, minCoordinates.z(), maxCoordinates.z()); } else { std::cerr << "[SegmentedPlanesTerrainModel] Failed to get subMap" << std::endl; diff --git a/segmented_planes_terrain_model/test/signedDistanceTest.cpp b/segmented_planes_terrain_model/test/signedDistanceTest.cpp index d0a4b2c8..6db3eaa8 100644 --- a/segmented_planes_terrain_model/test/signedDistanceTest.cpp +++ b/segmented_planes_terrain_model/test/signedDistanceTest.cpp @@ -8,12 +8,13 @@ #include #include -#include #include #include #include #include +#include "segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h" + grid_map::GridMap loadElevationMapFromFile(const std::string& filePath, double resolution, double scale) { // Read the file cv::Mat image; @@ -100,7 +101,7 @@ int main(int argc, char** argv) { // for (float h = minHeight; h < maxHeight; h += resolution_) { // data_.emplace_back(signed_distance_field::signedDistanceAtHeight(map, h, resolution)); // } - signed_distance_field::GridmapSignedDistanceField sdf(gridMap, layer, minHeight, maxHeight); + switched_model::SegmentedPlanesSignedDistanceField sdf(gridMap, layer, minHeight, maxHeight); // ========================================================= } diff --git a/signed_distance_field/CMakeLists.txt b/signed_distance_field/CMakeLists.txt index c61862b2..c9490b9d 100644 --- a/signed_distance_field/CMakeLists.txt +++ b/signed_distance_field/CMakeLists.txt @@ -5,7 +5,6 @@ project(signed_distance_field) set(CATKIN_PACKAGE_DEPENDENCIES grid_map_core pcl_ros - ocs2_switched_model_interface ) find_package(catkin REQUIRED COMPONENTS @@ -36,16 +35,15 @@ include_directories( ) add_library(${PROJECT_NAME} - src/PixelBorderDistance.cpp src/GridmapSignedDistanceField.cpp - src/SignedDistance2d.cpp - ) + src/SignedDistance2d.cpp +) add_dependencies(${PROJECT_NAME} ${catkin_EXPORTED_TARGETS} - ) +) target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} - ) +) ############# @@ -56,10 +54,10 @@ install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} - ) +) install(DIRECTORY include/${PROJECT_NAME}/ DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} - ) +) ############# ## Testing ## @@ -71,9 +69,9 @@ add_executable(${PROJECT_NAME}_test test/testPixelBorderDistance.cpp test/testSignedDistance2d.cpp test/testSignedDistance3d.cpp - ) +) target_link_libraries(${PROJECT_NAME}_test ${catkin_LIBRARIES} ${PROJECT_NAME} gtest_main - ) \ No newline at end of file +) \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h b/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h index eb37ac65..384ccb08 100644 --- a/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h +++ b/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h @@ -4,36 +4,55 @@ #pragma once -#include +#include +namespace grid_map { namespace signed_distance_field { -inline void columnwiseCentralDifference(const Eigen::MatrixXf& data, Eigen::MatrixXf& centralDifference, float resolution) { +/** + * Takes the columnwise central difference of a matrix. Uses single sided difference at the boundaries. + * diff = (col(i+1) - col(i-1)) / (2 * resolution) + * + * @param data [in] : data to take the difference of. + * @param centralDifference [out] : matrix to store the result in. + * @param resolution [in] : scaling of the distance between two columns. + */ +inline void columnwiseCentralDifference(const Matrix& data, Matrix& centralDifference, float resolution) { assert(data.cols() >= 2); // Minimum size to take finite differences. const int m = data.cols(); + const float resInv = 1.0F / resolution; + const float doubleResInv = 1.0F / (2.0F * resolution); // First column - centralDifference.col(0) = (data.col(1) - data.col(0)) / resolution; + centralDifference.col(0) = resInv * (data.col(1) - data.col(0)); // All the middle columns - float doubleResolution = 2.0F * resolution; for (int i = 1; i + 1 < m; ++i) { - centralDifference.col(i) = (data.col(i + 1) - data.col(i - 1)) / doubleResolution; + centralDifference.col(i) = doubleResInv * (data.col(i + 1) - data.col(i - 1)); } // Last column - centralDifference.col(m - 1) = (data.col(m - 1) - data.col(m - 2)) / resolution; + centralDifference.col(m - 1) = resInv * (data.col(m - 1) - data.col(m - 2)); } -inline void layerFiniteDifference(const Eigen::MatrixXf& data_k, const Eigen::MatrixXf& data_kp1, Eigen::MatrixXf& result, - float resolution) { - result = (1.0F / resolution) * (data_kp1 - data_k); +/** + * Takes the finite difference between layers + * result = (data_{k+1} - data{k}) / resolution + */ +inline void layerFiniteDifference(const Matrix& data_k, const Matrix& data_kp1, Matrix& result, float resolution) { + const float resInv = 1.0F / resolution; + result = resInv * (data_kp1 - data_k); } -inline void layerCentralDifference(const Eigen::MatrixXf& data_km1, const Eigen::MatrixXf& data_kp1, Eigen::MatrixXf& result, float resolution) { - float doubleResolution = 2.0F * resolution; - result = (1.0F / doubleResolution) * (data_kp1 - data_km1); +/** + * Takes the central difference between layers + * result = (data_{k+1} - data{k-1}) / (2.0 * resolution) + */ +inline void layerCentralDifference(const Matrix& data_km1, const Matrix& data_kp1, Matrix& result, float resolution) { + const float doubleResInv = 1.0F / (2.0F * resolution); + result = doubleResInv * (data_kp1 - data_km1); } } // namespace signed_distance_field +} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h index 90ec2d06..f0447efe 100644 --- a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h +++ b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h @@ -4,11 +4,9 @@ #pragma once -#include -#include - -#include +#include +namespace grid_map { namespace signed_distance_field { /** @@ -28,7 +26,7 @@ struct Gridmap3dLookup { }; size_t_3d gridsize_; - Eigen::Vector3d gridOrigin_; + Position3 gridOrigin_; double resolution_; /** @@ -37,7 +35,7 @@ struct Gridmap3dLookup { * @param gridOrigin : position at x=y=z=0 * @param resolution : (>0.0) size of 1 voxel */ - Gridmap3dLookup(const size_t_3d& gridsize, const Eigen::Vector3d& gridOrigin, double resolution) + Gridmap3dLookup(const size_t_3d& gridsize, const Position3& gridOrigin, double resolution) : gridsize_(gridsize), gridOrigin_(gridOrigin), resolution_(resolution) { assert(resolution_ > 0.0); assert(gridsize_.x > 0); @@ -49,14 +47,15 @@ struct Gridmap3dLookup { Gridmap3dLookup() : Gridmap3dLookup({1, 1, 1}, {0.0, 0.0, 0.0}, 1.0) {} /** Returns the 3d index of the grid node closest to the query position */ - size_t_3d nearestNode(const Eigen::Vector3d& position) const noexcept { - Eigen::Vector3d subpixelVector{(gridOrigin_.x() - position.x()) / resolution_, (gridOrigin_.y() - position.y()) / resolution_, (position.z() - gridOrigin_.z()) / resolution_}; + size_t_3d nearestNode(const Position3& position) const noexcept { + Position3 subpixelVector{(gridOrigin_.x() - position.x()) / resolution_, (gridOrigin_.y() - position.y()) / resolution_, + (position.z() - gridOrigin_.z()) / resolution_}; return {nearestPositiveInteger(subpixelVector.x(), gridsize_.x - 1), nearestPositiveInteger(subpixelVector.y(), gridsize_.y - 1), nearestPositiveInteger(subpixelVector.z(), gridsize_.z - 1)}; } /** Returns the 3d node position from a 3d index */ - Eigen::Vector3d nodePosition(const size_t_3d& index) const noexcept { + Position3 nodePosition(const size_t_3d& index) const noexcept { return {gridOrigin_.x() - index.x * resolution_, gridOrigin_.y() - index.y * resolution_, gridOrigin_.z() + index.z * resolution_}; } @@ -67,7 +66,7 @@ struct Gridmap3dLookup { size_t linearSize() const noexcept { return gridsize_.x * gridsize_.y * gridsize_.z; } /** rounds subindex value and clamps it to [0, max] */ - static size_t nearestPositiveInteger(double val, size_t max) { + static size_t nearestPositiveInteger(double val, size_t max) noexcept { // Comparing bounds as double prevents underflow/overflow if (val > 0.0) { return static_cast(std::min(std::round(val), static_cast(max))); @@ -78,3 +77,4 @@ struct Gridmap3dLookup { }; } // namespace signed_distance_field +} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h index 927fa7a8..455b18d1 100644 --- a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h +++ b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h @@ -11,27 +11,56 @@ #include #include -#include +#include #include -#include - #include "Gridmap3dLookup.h" -namespace signed_distance_field { - -class GridmapSignedDistanceField : public switched_model::SignedDistanceField { +namespace grid_map { + +/** + * This class creates a dense 3D signed distance field grid for a given elevation map. + * The 3D grid uses the same resolution as the 2D map. i.e. all voxels are of size (resolution x resolution x resolution). + * The size of the 3D grid is the same as the map in XY direction. The size is Z direction is specified in the constructor. + * + * During the creation of the class all values and derivatives are pre-computed in one go. This makes repeated lookups very cheap. + * Querying a point outside of the constructed grid will result in linear extrapolation. + */ +class GridmapSignedDistanceField { public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW + using Derivative3 = Eigen::Vector3d; - GridmapSignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, double minHeight, double maxHeight); - ~GridmapSignedDistanceField() override = default; - GridmapSignedDistanceField* clone() const override; + /** + * Create a signed distance field and its derivative for an elevation layer in the grid map. + * + * @param gridMap : Input map to create the SDF for. + * @param elevationLayer : Name of the elevation layer. + * @param minHeight : Desired starting height of the 3D SDF grid. + * @param maxHeight : Desired ending height of the 3D SDF grid. (Will be rounded up to match the resolution) + */ + GridmapSignedDistanceField(const GridMap& gridMap, const std::string& elevationLayer, double minHeight, double maxHeight); - switched_model::scalar_t value(const switched_model::vector3_t& position) const override; - switched_model::vector3_t derivative(const switched_model::vector3_t& position) const override; - std::pair valueAndDerivative( - const switched_model::vector3_t& position) const override; + /** + * Get the signed distance value at a 3D position. + * @param position : 3D position in the frame of the gridmap. + * @return signed distance to the elevation surface. + */ + double value(const Position3& position) const noexcept; + + /** + * Get the signed distance derivative at a 3D position. + * @param position : 3D position in the frame of the gridmap. + * @return derivative of the signed distance field. + */ + Derivative3 derivative(const Position3& position) const noexcept; + + /** + * Get both the signed distance value and derivative at a 3D position. + * @param position : 3D position in the frame of the gridmap. + * @return {value, derivative} of the signed distance field. + */ + std::pair valueAndDerivative(const Position3& position) const noexcept; /** * Return the signed distance field as a pointcloud. The signed distance is assigned to the point's intensity. @@ -54,21 +83,61 @@ class GridmapSignedDistanceField : public switched_model::SignedDistanceField { pcl::PointCloud obstaclePointCloud(size_t decimation = 1) const; private: - GridmapSignedDistanceField(const GridmapSignedDistanceField& other); - void computeSignedDistance(const grid_map::Matrix& elevation); - void computeLayerSdfandDeltaX(const grid_map::Matrix& elevation, grid_map::Matrix& currentLayer, grid_map::Matrix& dxTranspose, - grid_map::Matrix& sdfTranspose, grid_map::Matrix& tmp, grid_map::Matrix& tmpTranspose, - const float gridOriginZ, const float resolution, const float minHeight, const float maxHeight) const; - void emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dxTranspose, const grid_map::Matrix& dy, - const grid_map::Matrix& dz); + /** + * Implementation of the signed distance field computation in this class. + * @param elevation + */ + void computeSignedDistance(const Matrix& elevation); + + /** + * Simultaneously compute the signed distance and derivative in x direction at a given height + * @param elevation [in] : elevation data + * @param currentLayer [out] : signed distance values + * @param dxTranspose [out] : derivative in x direction (the matrix is transposed) + * @param sdfTranspose [tmp] : temporary variable to reuse between calls (allocated on first use) + * @param tmp [tmp] : temporary variable (allocated on first use) + * @param tmpTranspose [tmp] : temporary variable (allocated on first use) + * @param height [in] : height the signed distance is create for. + * @param resolution [in] : resolution of the map. + * @param minHeight [in] : smallest height value in the elevation data. + * @param maxHeight [in] : largest height value in the elevation data. + */ + void computeLayerSdfandDeltaX(const Matrix& elevation, Matrix& currentLayer, Matrix& dxTranspose, Matrix& sdfTranspose, Matrix& tmp, + Matrix& tmpTranspose, float height, float resolution, float minHeight, float maxHeight) const; + + /** + * Add the computed signed distance values and derivatives at a particular height to the grid. + * Adds the layer to the back of data_ + * @param signedDistance : signed distance values. + * @param dxTranspose : x components of the derivative (matrix is transposed). + * @param dy : y components of the derivative. + * @param dz : z components of the derivative. + */ + void emplacebackLayerData(const Matrix& signedDistance, const Matrix& dxTranspose, const Matrix& dy, const Matrix& dz); + //! Data structure to store together {signed distance value, derivative}. using node_data_t = std::array; + + /** Helper function to extract the sdf value */ static double distance(const node_data_t& nodeData) noexcept { return nodeData[0]; } + + /** Helper function to extract the sdf value as float */ static float distanceFloat(const node_data_t& nodeData) noexcept { return nodeData[0]; } - static Eigen::Vector3d derivative(const node_data_t& nodeData) noexcept { return {nodeData[1], nodeData[2], nodeData[3]}; } - Gridmap3dLookup gridmap3DLookup_; + /** Helper function to extract the sdf derivative */ + static Derivative3 derivative(const node_data_t& nodeData) noexcept { return {nodeData[1], nodeData[2], nodeData[3]}; } + + //! Object encoding the 3D grid. + signed_distance_field::Gridmap3dLookup gridmap3DLookup_; + + //! Object encoding the signed distance value and derivative in the grid. std::vector data_; + + //! Frame id of the grid map. + std::string frameId_; + + //! Timestamp of the grid map (nanoseconds). + Time timestamp_; }; -} // namespace signed_distance_field +} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h index bee0014e..97006570 100644 --- a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h +++ b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h @@ -8,6 +8,7 @@ #include #include +namespace grid_map { namespace signed_distance_field { /** @@ -51,7 +52,7 @@ inline float intersectionPointRightSideOfOrigin(float p, float fp) { } else if (fp < -pSquared) { return (pSquared - p + fp) / (2.0F * p); // sol 5 } else { - const float bound = pSquared - 2.0F * p + 1.0F; // Always positive because (p > 0) + const float bound = pSquared - 2.0F * p + 1.0F; // Always positive because (p > 0) if (fp > bound) { return 0.5F + std::sqrt(fp); // sol 2 } else if (fp < -bound) { @@ -96,3 +97,4 @@ inline float equidistancePoint(float q, float fq, float p, float fp) { } } // namespace signed_distance_field +} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h index 8f1b8709..ff6b64a6 100644 --- a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h +++ b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h @@ -10,6 +10,7 @@ #include "Utils.h" +namespace grid_map { namespace signed_distance_field { /** @@ -22,8 +23,7 @@ namespace signed_distance_field { * @param maxHeight : the maximum height contained in elevationMap * @return The signed distance field at the query height. */ -grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution, float minHeight, - float maxHeight); +Matrix signedDistanceAtHeight(const Matrix& elevationMap, float height, float resolution, float minHeight, float maxHeight); /** * Same as above, but returns the sdf in transposed form. @@ -38,9 +38,18 @@ grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, fl * @param minHeight : the lowest height contained in elevationMap * @param maxHeight : the maximum height contained in elevationMap */ -void signedDistanceAtHeightTranspose(const grid_map::Matrix& elevationMap, grid_map::Matrix& sdfTranspose, grid_map::Matrix& tmp, - grid_map::Matrix& tmpTranspose, float height, float resolution, float minHeight, float maxHeight); +void signedDistanceAtHeightTranspose(const Matrix& elevationMap, Matrix& sdfTranspose, Matrix& tmp, Matrix& tmpTranspose, float height, + float resolution, float minHeight, float maxHeight); -grid_map::Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution); +/** + * Gets the 2D signed distance from an occupancy grid. + * Returns +INF if there are no obstacles, and -INF if there are only obstacles + * + * @param occupancyGrid : occupancy grid with true = obstacle, false = free space + * @param resolution : resolution of the grid. + * @return signed distance for each point in the grid to the occupancy border. + */ +Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution); -} // namespace signed_distance_field \ No newline at end of file +} // namespace signed_distance_field +} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/Utils.h b/signed_distance_field/include/signed_distance_field/Utils.h index 37c437e4..d6953d8c 100644 --- a/signed_distance_field/include/signed_distance_field/Utils.h +++ b/signed_distance_field/include/signed_distance_field/Utils.h @@ -4,9 +4,10 @@ #pragma once - +namespace grid_map { namespace signed_distance_field { -constexpr float INF = 1e15; // maximum well below numeric_limits::max +constexpr float INF = 1e15; // maximum well below numeric_limits::max -} \ No newline at end of file +} // namespace signed_distance_field +} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/package.xml b/signed_distance_field/package.xml index 86d78b3a..a6ba2663 100644 --- a/signed_distance_field/package.xml +++ b/signed_distance_field/package.xml @@ -12,6 +12,5 @@ grid_map_core pcl_ros - ocs2_switched_model_interface diff --git a/signed_distance_field/src/GridmapSignedDistanceField.cpp b/signed_distance_field/src/GridmapSignedDistanceField.cpp index 05666083..4fdc296d 100644 --- a/signed_distance_field/src/GridmapSignedDistanceField.cpp +++ b/signed_distance_field/src/GridmapSignedDistanceField.cpp @@ -7,67 +7,71 @@ #include "signed_distance_field/DistanceDerivatives.h" #include "signed_distance_field/SignedDistance2d.h" -namespace signed_distance_field { - -GridmapSignedDistanceField::GridmapSignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, - double minHeight, double maxHeight) { +namespace grid_map { + +// Import from the signed_distance_field namespace +using signed_distance_field::Gridmap3dLookup; +using signed_distance_field::layerFiniteDifference; +using signed_distance_field::columnwiseCentralDifference; +using signed_distance_field::signedDistanceAtHeightTranspose; +using signed_distance_field::layerCentralDifference; + +GridmapSignedDistanceField::GridmapSignedDistanceField(const GridMap& gridMap, const std::string& elevationLayer, double minHeight, + double maxHeight) + : frameId_(gridMap.getFrameId()), timestamp_(gridMap.getTimestamp()) { assert(maxHeight >= minHeight); - grid_map::Position mapOriginXY; + + // Determine origin of the 3D grid + Position mapOriginXY; gridMap.getPosition(Eigen::Vector2i(0, 0), mapOriginXY); - Eigen::Vector3d gridOrigin(mapOriginXY.x(), mapOriginXY.y(), minHeight); + Position3 gridOrigin(mapOriginXY.x(), mapOriginXY.y(), minHeight); - // Take minimum of two layers to enable finite difference in Z direction + // Round up the Z-discretization. We need a minimum of two layers to enable finite difference in Z direction const auto numZLayers = static_cast(std::max(std::ceil((maxHeight - minHeight) / gridMap.getResolution()), 2.0)); const size_t numXrows = gridMap.getSize().x(); const size_t numYrows = gridMap.getSize().y(); Gridmap3dLookup::size_t_3d gridsize = {numXrows, numYrows, numZLayers}; + // Initialize 3D lookup gridmap3DLookup_ = Gridmap3dLookup(gridsize, gridOrigin, gridMap.getResolution()); + // Allocate the internal data structure data_.reserve(gridmap3DLookup_.linearSize()); + + // Check for NaN const auto& elevationData = gridMap.get(elevationLayer); if (elevationData.hasNaN()) { - std::cerr << "[GridmapSignedDistanceField] elevation data contains NaN" << std::endl; + std::cerr << "[GridmapSignedDistanceField] elevation data contains NaN. The generated SDF will be invalid" << std::endl; } - computeSignedDistance(elevationData); -} -GridmapSignedDistanceField::GridmapSignedDistanceField(const GridmapSignedDistanceField& other) - : switched_model::SignedDistanceField(), gridmap3DLookup_(other.gridmap3DLookup_), data_(other.data_) {} - -GridmapSignedDistanceField* GridmapSignedDistanceField::clone() const { - return new GridmapSignedDistanceField(*this); + // Compute the SDF + computeSignedDistance(elevationData); } -switched_model::scalar_t GridmapSignedDistanceField::value(const switched_model::vector3_t& position) const { +double GridmapSignedDistanceField::value(const Position3& position) const noexcept { const auto nodeIndex = gridmap3DLookup_.nearestNode(position); - const Eigen::Vector3d nodePosition = gridmap3DLookup_.nodePosition(nodeIndex); - const node_data_t nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; - const Eigen::Vector3d jacobian = derivative(nodeData); + const auto nodePosition = gridmap3DLookup_.nodePosition(nodeIndex); + const auto nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; + const auto jacobian = derivative(nodeData); return distance(nodeData) + jacobian.dot(position - nodePosition); } -switched_model::vector3_t GridmapSignedDistanceField::derivative(const switched_model::vector3_t& position) const { +GridmapSignedDistanceField::Derivative3 GridmapSignedDistanceField::derivative(const Position3& position) const noexcept { const auto nodeIndex = gridmap3DLookup_.nearestNode(position); - const node_data_t nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; + const auto nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; return derivative(nodeData); } -std::pair GridmapSignedDistanceField::valueAndDerivative( - const switched_model::vector3_t& position) const { +std::pair GridmapSignedDistanceField::valueAndDerivative( + const Position3& position) const noexcept { const auto nodeIndex = gridmap3DLookup_.nearestNode(position); - const Eigen::Vector3d nodePosition = gridmap3DLookup_.nodePosition(nodeIndex); - const node_data_t nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; - const Eigen::Vector3d jacobian = derivative(nodeData); + const auto nodePosition = gridmap3DLookup_.nodePosition(nodeIndex); + const auto nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; + const auto jacobian = derivative(nodeData); return {distance(nodeData) + jacobian.dot(position - nodePosition), jacobian}; } -void GridmapSignedDistanceField::computeSignedDistance(const grid_map::Matrix& elevation) { - using signed_distance_field::columnwiseCentralDifference; - using signed_distance_field::layerCentralDifference; - using signed_distance_field::layerFiniteDifference; - using signed_distance_field::signedDistanceAtHeightTranspose; - +void GridmapSignedDistanceField::computeSignedDistance(const Matrix& elevation) { const auto gridOriginZ = static_cast(gridmap3DLookup_.gridOrigin_.z()); const auto resolution = static_cast(gridmap3DLookup_.resolution_); const auto minHeight = elevation.minCoeff(); @@ -83,20 +87,20 @@ void GridmapSignedDistanceField::computeSignedDistance(const grid_map::Matrix& e */ // Memory needed to compute the SDF at a layer - grid_map::Matrix tmp; // allocated on first use - grid_map::Matrix tmpTranspose; // allocated on first use - grid_map::Matrix sdfTranspose; // allocated on first use + Matrix tmp; // allocated on first use + Matrix tmpTranspose; // allocated on first use + Matrix sdfTranspose; // allocated on first use // Memory needed to keep a buffer of layers. We need 3 due to the central difference - grid_map::Matrix currentLayer; // allocated on first use - grid_map::Matrix nextLayer; // allocated on first use - grid_map::Matrix previousLayer; // allocated on first use + Matrix currentLayer; // allocated on first use + Matrix nextLayer; // allocated on first use + Matrix previousLayer; // allocated on first use // Memory needed to compute finite differences - grid_map::Matrix dxTranspose = grid_map::Matrix::Zero(elevation.cols(), elevation.rows()); - grid_map::Matrix dxNextTranspose = grid_map::Matrix::Zero(elevation.cols(), elevation.rows()); - grid_map::Matrix dy = grid_map::Matrix::Zero(elevation.rows(), elevation.cols()); - grid_map::Matrix dz = grid_map::Matrix::Zero(elevation.rows(), elevation.cols()); + Matrix dxTranspose = Matrix::Zero(elevation.cols(), elevation.rows()); + Matrix dxNextTranspose = Matrix::Zero(elevation.cols(), elevation.rows()); + Matrix dy = Matrix::Zero(elevation.rows(), elevation.cols()); + Matrix dz = Matrix::Zero(elevation.rows(), elevation.cols()); // Compute SDF of first layer computeLayerSdfandDeltaX(elevation, currentLayer, dxTranspose, sdfTranspose, tmp, tmpTranspose, gridOriginZ, resolution, minHeight, @@ -131,7 +135,7 @@ void GridmapSignedDistanceField::computeSignedDistance(const grid_map::Matrix& e emplacebackLayerData(currentLayer, dxTranspose, dy, dz); } - // Circulate layer buffers on last time + // Circulate layer buffers one last time previousLayer.swap(currentLayer); currentLayer.swap(nextLayer); dxTranspose.swap(dxNextTranspose); @@ -143,18 +147,17 @@ void GridmapSignedDistanceField::computeSignedDistance(const grid_map::Matrix& e // Add the data to the 3D structure emplacebackLayerData(currentLayer, dxTranspose, dy, dz); } -void GridmapSignedDistanceField::computeLayerSdfandDeltaX(const grid_map::Matrix& elevation, grid_map::Matrix& currentLayer, - grid_map::Matrix& dxTranspose, grid_map::Matrix& sdfTranspose, - grid_map::Matrix& tmp, grid_map::Matrix& tmpTranspose, const float gridOriginZ, - const float resolution, const float minHeight, const float maxHeight) const { +void GridmapSignedDistanceField::computeLayerSdfandDeltaX(const Matrix& elevation, Matrix& currentLayer, Matrix& dxTranspose, + Matrix& sdfTranspose, Matrix& tmp, Matrix& tmpTranspose, float height, + float resolution, float minHeight, float maxHeight) const { // Compute SDF + dx of layer: compute sdfTranspose -> take dxTranspose -> transpose to get sdf - signedDistanceAtHeightTranspose(elevation, sdfTranspose, tmp, tmpTranspose, gridOriginZ, resolution, minHeight, maxHeight); + signedDistanceAtHeightTranspose(elevation, sdfTranspose, tmp, tmpTranspose, height, resolution, minHeight, maxHeight); columnwiseCentralDifference(sdfTranspose, dxTranspose, -resolution); // dx / drow = -resolution currentLayer = sdfTranspose.transpose(); } -void GridmapSignedDistanceField::emplacebackLayerData(const grid_map::Matrix& signedDistance, const grid_map::Matrix& dxdxTranspose, - const grid_map::Matrix& dy, const grid_map::Matrix& dz) { +void GridmapSignedDistanceField::emplacebackLayerData(const Matrix& signedDistance, const Matrix& dxdxTranspose, const Matrix& dy, + const Matrix& dz) { for (size_t colY = 0; colY < gridmap3DLookup_.gridsize_.y; ++colY) { for (size_t rowX = 0; rowX < gridmap3DLookup_.gridsize_.x; ++rowX) { data_.emplace_back(node_data_t{signedDistance(rowX, colY), dxdxTranspose(colY, rowX), dy(rowX, colY), dz(rowX, colY)}); @@ -165,6 +168,9 @@ void GridmapSignedDistanceField::emplacebackLayerData(const grid_map::Matrix& si pcl::PointCloud GridmapSignedDistanceField::asPointCloud(size_t decimation, const std::function& condition) const { pcl::PointCloud points; + points.header.stamp = timestamp_; + points.header.frame_id = frameId_; + points.reserve(gridmap3DLookup_.linearSize()); for (size_t layerZ = 0; layerZ < gridmap3DLookup_.gridsize_.z; layerZ += decimation) { for (size_t colY = 0; colY < gridmap3DLookup_.gridsize_.y; colY += decimation) { @@ -195,4 +201,4 @@ pcl::PointCloud GridmapSignedDistanceField::obstaclePointCloud(s return asPointCloud(decimation, [](float signedDistance) { return signedDistance <= 0.0F; }); } -} // namespace signed_distance_field +} // namespace grid_map diff --git a/signed_distance_field/src/PixelBorderDistance.cpp b/signed_distance_field/src/PixelBorderDistance.cpp deleted file mode 100644 index 34047f8e..00000000 --- a/signed_distance_field/src/PixelBorderDistance.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// -// Created by rgrandia on 07.08.20. -// - -#include "signed_distance_field/PixelBorderDistance.h" - -namespace signed_distance_field {} \ No newline at end of file diff --git a/signed_distance_field/src/SignedDistance2d.cpp b/signed_distance_field/src/SignedDistance2d.cpp index e4248770..72532d71 100644 --- a/signed_distance_field/src/SignedDistance2d.cpp +++ b/signed_distance_field/src/SignedDistance2d.cpp @@ -6,6 +6,7 @@ #include "signed_distance_field/PixelBorderDistance.h" +namespace grid_map { namespace signed_distance_field { namespace internal { @@ -64,7 +65,7 @@ std::vector::iterator fillLowerBounds(const Eigen::Ref squareDistance1d, const std::vector& lowerBounds, - std::vector::const_iterator lowerBoundIt, Eigen::Index start) { + std::vector::const_iterator lowerBoundIt, Eigen::Index start) { const auto n = squareDistance1d.size(); // Store active bound by value to remove indirection @@ -153,8 +154,7 @@ inline void squaredDistanceTransform_1d_inplace(Eigen::Ref squa * @param squareDistance1d : input as squared distance, output is the distance after sqrt. * @param lowerBounds : work vector */ -inline void distanceTransform_1d_inplace(Eigen::Ref squareDistance1d, - std::vector& lowerBounds) { +inline void distanceTransform_1d_inplace(Eigen::Ref squareDistance1d, std::vector& lowerBounds) { assert(lowerBounds.size() >= squareDistance1d.size()); auto start = lastZeroFromFront(squareDistance1d); @@ -166,7 +166,7 @@ inline void distanceTransform_1d_inplace(Eigen::Ref squareDista } } -void computePixelDistance2dTranspose(grid_map::Matrix& input, grid_map::Matrix& distanceTranspose) { +void computePixelDistance2dTranspose(Matrix& input, Matrix& distanceTranspose) { const size_t n = input.rows(); const size_t m = input.cols(); @@ -187,8 +187,7 @@ void computePixelDistance2dTranspose(grid_map::Matrix& input, grid_map::Matrix& } // Initialize with square distance in height direction in pixel units if above the surface -void initializeObstacleDistance(const grid_map::Matrix& elevationMap, grid_map::Matrix& result, float height, - float resolution) { +void initializeObstacleDistance(const Matrix& elevationMap, Matrix& result, float height, float resolution) { /* Vectorized implementation of: * if (height > elevation) { * const auto diff = (height - elevation) / resolution; @@ -201,8 +200,7 @@ void initializeObstacleDistance(const grid_map::Matrix& elevationMap, grid_map:: } // Initialize with square distance in height direction in pixel units if below the surface -void initializeObstacleFreeDistance(const grid_map::Matrix& elevationMap, grid_map::Matrix& result, float height, - float resolution) { +void initializeObstacleFreeDistance(const Matrix& elevationMap, Matrix& result, float height, float resolution) { /* Vectorized implementation of: * if (height < elevation) { * const auto diff = (height - elevation) / resolution; @@ -214,26 +212,25 @@ void initializeObstacleFreeDistance(const grid_map::Matrix& elevationMap, grid_m result = ((1.0F / resolution) * (height - elevationMap.array()).cwiseMin(0.0F)).square(); } -void pixelDistanceToFreeSpaceTranspose(const grid_map::Matrix& elevationMap, grid_map::Matrix& sdfObstacleFree, grid_map::Matrix& tmp, float height, - float resolution) { +void pixelDistanceToFreeSpaceTranspose(const Matrix& elevationMap, Matrix& sdfObstacleFree, Matrix& tmp, float height, float resolution) { internal::initializeObstacleFreeDistance(elevationMap, tmp, height, resolution); internal::computePixelDistance2dTranspose(tmp, sdfObstacleFree); } -void pixelDistanceToObstacleTranspose(const grid_map::Matrix& elevationMap, grid_map::Matrix& sdfObstacleTranspose, grid_map::Matrix& tmp, float height, - float resolution) { +void pixelDistanceToObstacleTranspose(const Matrix& elevationMap, Matrix& sdfObstacleTranspose, Matrix& tmp, float height, + float resolution) { internal::initializeObstacleDistance(elevationMap, tmp, height, resolution); internal::computePixelDistance2dTranspose(tmp, sdfObstacleTranspose); } -grid_map::Matrix signedDistanceFromOccupancyTranspose(const Eigen::Matrix& occupancyGrid, float resolution) { +Matrix signedDistanceFromOccupancyTranspose(const Eigen::Matrix& occupancyGrid, float resolution) { // Compute pixel distance to obstacles - grid_map::Matrix sdfObstacle; - grid_map::Matrix init = occupancyGrid.unaryExpr([=](bool val) { return (val) ? 0.0F : INF; }); + Matrix sdfObstacle; + Matrix init = occupancyGrid.unaryExpr([=](bool val) { return (val) ? 0.0F : INF; }); internal::computePixelDistance2dTranspose(init, sdfObstacle); // Compute pixel distance to obstacle free space - grid_map::Matrix sdfObstacleFree; + Matrix sdfObstacleFree; init = occupancyGrid.unaryExpr([=](bool val) { return (val) ? INF : 0.0F; }); internal::computePixelDistance2dTranspose(init, sdfObstacleFree); @@ -242,8 +239,8 @@ grid_map::Matrix signedDistanceFromOccupancyTranspose(const Eigen::Matrix maxHeight; @@ -257,23 +254,22 @@ void signedDistanceAtHeightTranspose(const grid_map::Matrix& elevationMap, grid_ sdfTranspose *= resolution; } else { // This layer contains a mix of obstacles and free space internal::pixelDistanceToObstacleTranspose(elevationMap, sdfTranspose, tmp, height, resolution); - internal::pixelDistanceToFreeSpaceTranspose(elevationMap, tmpTranspose, tmp, height, resolution); + internal::pixelDistanceToFreeSpaceTranspose(elevationMap, tmpTranspose, tmp, height, resolution); sdfTranspose = resolution * (sdfTranspose - tmpTranspose); } } -grid_map::Matrix signedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution, float minHeight, - float maxHeight) { - grid_map::Matrix sdfTranspose; - grid_map::Matrix tmp; - grid_map::Matrix tmpTranspose; +Matrix signedDistanceAtHeight(const Matrix& elevationMap, float height, float resolution, float minHeight, float maxHeight) { + Matrix sdfTranspose; + Matrix tmp; + Matrix tmpTranspose; signedDistanceAtHeightTranspose(elevationMap, sdfTranspose, tmp, tmpTranspose, height, resolution, minHeight, maxHeight); return sdfTranspose.transpose(); } -grid_map::Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution) { +Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution) { auto obstacleCount = occupancyGrid.count(); bool hasObstacles = obstacleCount > 0; if (hasObstacles) { @@ -282,12 +278,13 @@ grid_map::Matrix signedDistanceFromOccupancy(const Eigen::Matrix& return internal::signedDistanceFromOccupancyTranspose(occupancyGrid, resolution).transpose(); } else { // Only obstacles -> distance is minus infinity everywhere - return grid_map::Matrix::Constant(occupancyGrid.rows(), occupancyGrid.cols(), -INF); + return Matrix::Constant(occupancyGrid.rows(), occupancyGrid.cols(), -INF); } } else { // No obstacles -> planar distance is infinite - return grid_map::Matrix::Constant(occupancyGrid.rows(), occupancyGrid.cols(), INF); + return Matrix::Constant(occupancyGrid.rows(), occupancyGrid.cols(), INF); } } } // namespace signed_distance_field +} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/test/naiveSignedDistance.h b/signed_distance_field/test/naiveSignedDistance.h index 2ea41685..caf8a6a1 100644 --- a/signed_distance_field/test/naiveSignedDistance.h +++ b/signed_distance_field/test/naiveSignedDistance.h @@ -4,22 +4,23 @@ #pragma once +namespace grid_map { namespace signed_distance_field { -inline Eigen::Matrix occupancyAtHeight(const grid_map::Matrix& elevationMap, float height) { +inline Eigen::Matrix occupancyAtHeight(const Matrix& elevationMap, float height) { Eigen::Matrix occupany = elevationMap.unaryExpr([=](float val) { return val > height; }); return occupany; } -inline bool isEqualSdf(const grid_map::Matrix& sdf0, const grid_map::Matrix& sdf1, float tol) { - grid_map::Matrix error = (sdf0 - sdf1).array().abs(); +inline bool isEqualSdf(const Matrix& sdf0, const Matrix& sdf1, float tol) { + Matrix error = (sdf0 - sdf1).array().abs(); float maxDifference = error.maxCoeff(); return maxDifference < tol; } // N^2 naive implementation, for testing purposes -inline grid_map::Matrix naiveSignedDistanceAtHeight(const grid_map::Matrix& elevationMap, float height, float resolution) { - grid_map::Matrix signedDistance(elevationMap.rows(), elevationMap.cols()); +inline Matrix naiveSignedDistanceAtHeight(const Matrix& elevationMap, float height, float resolution) { + Matrix signedDistance(elevationMap.rows(), elevationMap.cols()); // For each point for (int row = 0; row < elevationMap.rows(); ++row) { @@ -57,8 +58,8 @@ inline grid_map::Matrix naiveSignedDistanceAtHeight(const grid_map::Matrix& elev return signedDistance; } -inline grid_map::Matrix naiveSignedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution) { - grid_map::Matrix signedDistance(occupancyGrid.rows(), occupancyGrid.cols()); +inline Matrix naiveSignedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution) { + Matrix signedDistance(occupancyGrid.rows(), occupancyGrid.cols()); // For each point for (int row = 0; row < occupancyGrid.rows(); ++row) { @@ -95,4 +96,6 @@ inline grid_map::Matrix naiveSignedDistanceFromOccupancy(const Eigen::Matrix Date: Thu, 17 Mar 2022 15:35:16 +0100 Subject: [PATCH 176/504] docs --- .../include/signed_distance_field/Gridmap3dLookup.h | 2 +- .../include/signed_distance_field/GridmapSignedDistanceField.h | 2 +- signed_distance_field/include/signed_distance_field/Utils.h | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h index f0447efe..b652285c 100644 --- a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h +++ b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h @@ -12,7 +12,7 @@ namespace signed_distance_field { /** * Stores 3 dimensional grid information and provides methods to convert between position - 3d Index - linear index. * - * As with grid map, the X-Y position is opposite to the row-col-index: (X,Y) is highest at (0,0) and lowest at (n, m). + * As with the 2D GridMap, the X-Y position is opposite to the row-col-index: (X,Y) is highest at (0,0) and lowest at (n, m). * The z-position is increasing with the layer-index. */ struct Gridmap3dLookup { diff --git a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h index 455b18d1..fb84f613 100644 --- a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h +++ b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h @@ -97,7 +97,7 @@ class GridmapSignedDistanceField { * @param sdfTranspose [tmp] : temporary variable to reuse between calls (allocated on first use) * @param tmp [tmp] : temporary variable (allocated on first use) * @param tmpTranspose [tmp] : temporary variable (allocated on first use) - * @param height [in] : height the signed distance is create for. + * @param height [in] : height the signed distance is created for. * @param resolution [in] : resolution of the map. * @param minHeight [in] : smallest height value in the elevation data. * @param maxHeight [in] : largest height value in the elevation data. diff --git a/signed_distance_field/include/signed_distance_field/Utils.h b/signed_distance_field/include/signed_distance_field/Utils.h index d6953d8c..8e2eb7ed 100644 --- a/signed_distance_field/include/signed_distance_field/Utils.h +++ b/signed_distance_field/include/signed_distance_field/Utils.h @@ -7,7 +7,8 @@ namespace grid_map { namespace signed_distance_field { -constexpr float INF = 1e15; // maximum well below numeric_limits::max +//! Distance value that is considered infinite. Needs to be well below numeric_limits::max to avoid overflow in computation involving ^2 +constexpr float INF = 1e15; } // namespace signed_distance_field } // namespace grid_map \ No newline at end of file From d60cd02bf597faaaa505425e2eb8b5119343eca4 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 17 Mar 2022 15:54:30 +0100 Subject: [PATCH 177/504] Document the lookup class. Move static cast to constructor --- .../signed_distance_field/Gridmap3dLookup.h | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h index b652285c..1e0fff1d 100644 --- a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h +++ b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h @@ -25,8 +25,16 @@ struct Gridmap3dLookup { size_t z; }; + //! 3D size of the grid size_t_3d gridsize_; + + //! Origin position of the grid Position3 gridOrigin_; + + //! Maximum index per dimension stored as double + Position3 gridMaxIndexAsDouble_; + + //! Grid resolution double resolution_; /** @@ -36,7 +44,11 @@ struct Gridmap3dLookup { * @param resolution : (>0.0) size of 1 voxel */ Gridmap3dLookup(const size_t_3d& gridsize, const Position3& gridOrigin, double resolution) - : gridsize_(gridsize), gridOrigin_(gridOrigin), resolution_(resolution) { + : gridsize_(gridsize), + gridOrigin_(gridOrigin), + gridMaxIndexAsDouble_(static_cast(gridsize_.x - 1), static_cast(gridsize_.y - 1), + static_cast(gridsize_.z - 1)), + resolution_(resolution) { assert(resolution_ > 0.0); assert(gridsize_.x > 0); assert(gridsize_.y > 0); @@ -48,10 +60,12 @@ struct Gridmap3dLookup { /** Returns the 3d index of the grid node closest to the query position */ size_t_3d nearestNode(const Position3& position) const noexcept { - Position3 subpixelVector{(gridOrigin_.x() - position.x()) / resolution_, (gridOrigin_.y() - position.y()) / resolution_, - (position.z() - gridOrigin_.z()) / resolution_}; - return {nearestPositiveInteger(subpixelVector.x(), gridsize_.x - 1), nearestPositiveInteger(subpixelVector.y(), gridsize_.y - 1), - nearestPositiveInteger(subpixelVector.z(), gridsize_.z - 1)}; + const double resInv = 1.0 / resolution_; + Position3 subpixelVector{(gridOrigin_.x() - position.x()) * resInv, (gridOrigin_.y() - position.y()) * resInv, + (position.z() - gridOrigin_.z()) * resInv}; + return {nearestPositiveInteger(subpixelVector.x(), gridMaxIndexAsDouble_.x()), + nearestPositiveInteger(subpixelVector.y(), gridMaxIndexAsDouble_.y()), + nearestPositiveInteger(subpixelVector.z(), gridMaxIndexAsDouble_.z())}; } /** Returns the 3d node position from a 3d index */ @@ -66,13 +80,9 @@ struct Gridmap3dLookup { size_t linearSize() const noexcept { return gridsize_.x * gridsize_.y * gridsize_.z; } /** rounds subindex value and clamps it to [0, max] */ - static size_t nearestPositiveInteger(double val, size_t max) noexcept { - // Comparing bounds as double prevents underflow/overflow - if (val > 0.0) { - return static_cast(std::min(std::round(val), static_cast(max))); - } else { - return 0; - } + static size_t nearestPositiveInteger(double val, double max) noexcept { + // Comparing bounds as double prevents underflow/overflow of size_t + return static_cast(std::max(0.0, std::min(std::round(val), max))); } }; From c6f88d8443b46475e1df9ea05c7a06ec97f29fac Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 17 Mar 2022 16:23:53 +0100 Subject: [PATCH 178/504] file headers --- .../DistanceDerivatives.h | 10 +++++-- .../signed_distance_field/Gridmap3dLookup.h | 10 +++++-- .../GridmapSignedDistanceField.h | 10 +++++-- .../PixelBorderDistance.h | 10 +++++-- .../signed_distance_field/SignedDistance2d.h | 10 +++++-- .../include/signed_distance_field/Utils.h | 10 +++++-- .../src/GridmapSignedDistanceField.cpp | 14 +++++---- .../src/SignedDistance2d.cpp | 10 +++++-- .../test/naiveSignedDistance.h | 10 +++++-- signed_distance_field/test/test3dLookup.cpp | 10 +++++-- .../test/testDerivatives.cpp | 17 ++++++----- .../test/testPixelBorderDistance.cpp | 10 +++++-- .../test/testSignedDistance2d.cpp | 29 ++++++++++--------- .../test/testSignedDistance3d.cpp | 16 +++++----- 14 files changed, 113 insertions(+), 63 deletions(-) diff --git a/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h b/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h index 384ccb08..455421b1 100644 --- a/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h +++ b/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 10.08.20. -// +/* + * DistanceDerivatives.h + * + * Created on: Aug 10, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #pragma once diff --git a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h index 1e0fff1d..888a8a07 100644 --- a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h +++ b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 13.08.20. -// +/* + * Gridmap3dLookup.h + * + * Created on: Aug 13, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #pragma once diff --git a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h index fb84f613..a970904c 100644 --- a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h +++ b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 10.07.20. -// +/* + * GridmapSignedDistanceField.h + * + * Created on: Jul 10, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #pragma once diff --git a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h index 97006570..a2c9f93d 100644 --- a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h +++ b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 07.08.20. -// +/* + * PixelBorderDistance.h + * + * Created on: Aug 7, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #pragma once diff --git a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h index ff6b64a6..16bbb916 100644 --- a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h +++ b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 10.07.20. -// +/* + * SignedDistance2d.h + * + * Created on: Jul 10, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #pragma once diff --git a/signed_distance_field/include/signed_distance_field/Utils.h b/signed_distance_field/include/signed_distance_field/Utils.h index 8e2eb7ed..bc753907 100644 --- a/signed_distance_field/include/signed_distance_field/Utils.h +++ b/signed_distance_field/include/signed_distance_field/Utils.h @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 10.07.20. -// +/* + * Utils.h + * + * Created on: Jul 10, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #pragma once diff --git a/signed_distance_field/src/GridmapSignedDistanceField.cpp b/signed_distance_field/src/GridmapSignedDistanceField.cpp index 4fdc296d..fbefb3a9 100644 --- a/signed_distance_field/src/GridmapSignedDistanceField.cpp +++ b/signed_distance_field/src/GridmapSignedDistanceField.cpp @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 10.07.20. -// +/* + * GridmapSignedDistanceField.cpp + * + * Created on: Jul 10, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #include "signed_distance_field/GridmapSignedDistanceField.h" @@ -10,11 +14,11 @@ namespace grid_map { // Import from the signed_distance_field namespace +using signed_distance_field::columnwiseCentralDifference; using signed_distance_field::Gridmap3dLookup; +using signed_distance_field::layerCentralDifference; using signed_distance_field::layerFiniteDifference; -using signed_distance_field::columnwiseCentralDifference; using signed_distance_field::signedDistanceAtHeightTranspose; -using signed_distance_field::layerCentralDifference; GridmapSignedDistanceField::GridmapSignedDistanceField(const GridMap& gridMap, const std::string& elevationLayer, double minHeight, double maxHeight) diff --git a/signed_distance_field/src/SignedDistance2d.cpp b/signed_distance_field/src/SignedDistance2d.cpp index 72532d71..117e8603 100644 --- a/signed_distance_field/src/SignedDistance2d.cpp +++ b/signed_distance_field/src/SignedDistance2d.cpp @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 10.07.20. -// +/* + * SignedDistance2d.cpp + * + * Created on: Jul 10, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #include "signed_distance_field/SignedDistance2d.h" diff --git a/signed_distance_field/test/naiveSignedDistance.h b/signed_distance_field/test/naiveSignedDistance.h index caf8a6a1..a7927b7e 100644 --- a/signed_distance_field/test/naiveSignedDistance.h +++ b/signed_distance_field/test/naiveSignedDistance.h @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 10.08.20. -// +/* + * naiveSignedDistance.h + * + * Created on: Aug 10, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #pragma once diff --git a/signed_distance_field/test/test3dLookup.cpp b/signed_distance_field/test/test3dLookup.cpp index 9c23328c..35b42f8d 100644 --- a/signed_distance_field/test/test3dLookup.cpp +++ b/signed_distance_field/test/test3dLookup.cpp @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 18.08.20. -// +/* + * test3dLookup.cpp + * + * Created on: Aug 18, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #include diff --git a/signed_distance_field/test/testDerivatives.cpp b/signed_distance_field/test/testDerivatives.cpp index 2b224a96..8c1d4ab5 100644 --- a/signed_distance_field/test/testDerivatives.cpp +++ b/signed_distance_field/test/testDerivatives.cpp @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 10.08.20. -// +/* + * testDerivatives.cpp + * + * Created on: Aug 10, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #include @@ -11,15 +15,14 @@ using namespace signed_distance_field; TEST(testDerivatives, columnwise) { Matrix data(2, 3); - data << 1.0, 2.0, 4.0, - 2.0, 4.0, 6.0; + data << 1.0, 2.0, 4.0, 2.0, 4.0, 6.0; float resolution = 0.1; float doubleResolution = 2.0F * resolution; Matrix manualDifference(2, 3); - manualDifference << 1.0 /resolution, 3.0 /doubleResolution, 2.0 /resolution, - 2.0 /resolution, 4.0 /doubleResolution, 2.0 /resolution; + manualDifference << 1.0 / resolution, 3.0 / doubleResolution, 2.0 / resolution, 2.0 / resolution, 4.0 / doubleResolution, + 2.0 / resolution; Matrix computedDifference = Matrix::Zero(data.rows(), data.cols()); columnwiseCentralDifference(data, computedDifference, resolution); diff --git a/signed_distance_field/test/testPixelBorderDistance.cpp b/signed_distance_field/test/testPixelBorderDistance.cpp index bb234c30..4456d6fe 100644 --- a/signed_distance_field/test/testPixelBorderDistance.cpp +++ b/signed_distance_field/test/testPixelBorderDistance.cpp @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 07.08.20. -// +/* + * testPixelBorderDistance.cpp + * + * Created on: Aug 7, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #include diff --git a/signed_distance_field/test/testSignedDistance2d.cpp b/signed_distance_field/test/testSignedDistance2d.cpp index fc4c2549..e3b920a5 100644 --- a/signed_distance_field/test/testSignedDistance2d.cpp +++ b/signed_distance_field/test/testSignedDistance2d.cpp @@ -1,11 +1,15 @@ -// -// Created by rgrandia on 10.07.20. -// +/* + * testSignedDistance2d.cpp + * + * Created on: Jul 10, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #include -#include "signed_distance_field/SignedDistance2d.h" #include "signed_distance_field/PixelBorderDistance.h" +#include "signed_distance_field/SignedDistance2d.h" #include "naiveSignedDistance.h" @@ -53,8 +57,8 @@ TEST(testSignedDistance2d, signedDistance2d_oneObstacle) { const int n = 20; const int m = 30; const float resolution = 0.1; - Matrix map = Matrix::Zero(n, m); - map(n/2, m/2) = 1.0; + Matrix map = Matrix::Zero(n, m); + map(n / 2, m / 2) = 1.0; const auto occupancy = occupancyAtHeight(map, 0.5); const auto naiveSignedDistance = naiveSignedDistanceFromOccupancy(occupancy, resolution); @@ -66,8 +70,8 @@ TEST(testSignedDistance2d, signedDistance2d_oneFreeSpace) { const int n = 20; const int m = 30; const float resolution = 0.1; - Matrix map = Matrix::Ones(n, m); - map(n/2, m/2) = 0.0; + Matrix map = Matrix::Ones(n, m); + map(n / 2, m / 2) = 0.0; const auto occupancy = occupancyAtHeight(map, 0.5); @@ -81,10 +85,7 @@ TEST(testSignedDistance2d, signedDistance2d_debugcase) { const int m = 3; const float resolution = 1.0; Matrix map(n, m); - map << - 1.0, 1.0, 1.0, - 0.0, 1.0, 1.0, - 1.0, 1.0, 0.0; + map << 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0; const auto occupancy = occupancyAtHeight(map, 0.5); @@ -97,11 +98,11 @@ TEST(testSignedDistance2d, signedDistance2d_random) { const int n = 20; const int m = 30; const float resolution = 1.0; - Matrix map = Matrix::Random(n, m); // random [-1.0, 1.0] + Matrix map = Matrix::Random(n, m); // random [-1.0, 1.0] // Check at different heights, resulting in different levels of sparsity. float heightStep = 0.1; - for (float height = -1.0 - heightStep; height < 1.0 + heightStep; height+=heightStep) { + for (float height = -1.0 - heightStep; height < 1.0 + heightStep; height += heightStep) { const auto occupancy = occupancyAtHeight(map, height); const auto naiveSignedDistance = naiveSignedDistanceFromOccupancy(occupancy, resolution); diff --git a/signed_distance_field/test/testSignedDistance3d.cpp b/signed_distance_field/test/testSignedDistance3d.cpp index 9d7db762..01f26463 100644 --- a/signed_distance_field/test/testSignedDistance3d.cpp +++ b/signed_distance_field/test/testSignedDistance3d.cpp @@ -1,6 +1,10 @@ -// -// Created by rgrandia on 10.08.20. -// +/* + * testSignedDistance3d.cpp + * + * Created on: Aug 10, 2020 + * Author: Ruben Grandia + * Institute: ETH Zurich + */ #include @@ -24,14 +28,12 @@ TEST(testSignedDistance3d, flatTerrain) { const float testHeightAboveTerrain = 3.0; const auto naiveSignedDistanceAbove = naiveSignedDistanceAtHeight(map, testHeightAboveTerrain, resolution); - const auto signedDistanceAbove = - signedDistanceAtHeight(map, testHeightAboveTerrain, resolution, minHeight, maxHeight); + const auto signedDistanceAbove = signedDistanceAtHeight(map, testHeightAboveTerrain, resolution, minHeight, maxHeight); ASSERT_TRUE(isEqualSdf(signedDistanceAbove, naiveSignedDistanceAbove, 1e-4)); const float testHeightBelowTerrain = -3.0; const auto naiveSignedDistanceBelow = naiveSignedDistanceAtHeight(map, testHeightBelowTerrain, resolution); - const auto signedDistanceBelow = - signedDistanceAtHeight(map, testHeightBelowTerrain, resolution, minHeight, maxHeight); + const auto signedDistanceBelow = signedDistanceAtHeight(map, testHeightBelowTerrain, resolution, minHeight, maxHeight); ASSERT_TRUE(isEqualSdf(signedDistanceBelow, naiveSignedDistanceBelow, 1e-4)); } From a008f5972d2a08a05ea18ec3ac88d83c97cc8d5a Mon Sep 17 00:00:00 2001 From: rgrandia Date: Fri, 18 Mar 2022 10:50:55 +0100 Subject: [PATCH 179/504] some more cleanup --- .../src/GridmapSignedDistanceField.cpp | 4 +++- .../src/SignedDistance2d.cpp | 20 ++++++++----------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/signed_distance_field/src/GridmapSignedDistanceField.cpp b/signed_distance_field/src/GridmapSignedDistanceField.cpp index fbefb3a9..4b3c4e19 100644 --- a/signed_distance_field/src/GridmapSignedDistanceField.cpp +++ b/signed_distance_field/src/GridmapSignedDistanceField.cpp @@ -45,7 +45,8 @@ GridmapSignedDistanceField::GridmapSignedDistanceField(const GridMap& gridMap, c // Check for NaN const auto& elevationData = gridMap.get(elevationLayer); if (elevationData.hasNaN()) { - std::cerr << "[GridmapSignedDistanceField] elevation data contains NaN. The generated SDF will be invalid" << std::endl; + std::cerr << "[GridmapSignedDistanceField] elevation data contains NaN. The generated SDF will be invalid! Apply inpainting first" + << std::endl; } // Compute the SDF @@ -151,6 +152,7 @@ void GridmapSignedDistanceField::computeSignedDistance(const Matrix& elevation) // Add the data to the 3D structure emplacebackLayerData(currentLayer, dxTranspose, dy, dz); } + void GridmapSignedDistanceField::computeLayerSdfandDeltaX(const Matrix& elevation, Matrix& currentLayer, Matrix& dxTranspose, Matrix& sdfTranspose, Matrix& tmp, Matrix& tmpTranspose, float height, float resolution, float minHeight, float maxHeight) const { diff --git a/signed_distance_field/src/SignedDistance2d.cpp b/signed_distance_field/src/SignedDistance2d.cpp index 117e8603..4cafb909 100644 --- a/signed_distance_field/src/SignedDistance2d.cpp +++ b/signed_distance_field/src/SignedDistance2d.cpp @@ -68,8 +68,8 @@ std::vector::iterator fillLowerBounds(const Eigen::Ref squareDistance1d, const std::vector& lowerBounds, - std::vector::const_iterator lowerBoundIt, Eigen::Index start) { +void extractSquareDistances(Eigen::Ref squareDistance1d, std::vector::const_iterator lowerBoundIt, + Eigen::Index start) { const auto n = squareDistance1d.size(); // Store active bound by value to remove indirection @@ -97,8 +97,8 @@ void extractSquareDistances(Eigen::Ref squareDistance1d, const * Same as extractSquareDistances, but takes the sqrt as a final step. * Because several cells will have a value of 0.0 (obstacle / free space label), we can skip the sqrt computation for those. */ -void extractDistances(Eigen::Ref squareDistance1d, const std::vector& lowerBounds, - std::vector::const_iterator lowerBoundIt, Eigen::Index start) { +void extractDistances(Eigen::Ref squareDistance1d, std::vector::const_iterator lowerBoundIt, + Eigen::Index start) { const auto n = squareDistance1d.size(); // Store active bound by value to remove indirection @@ -142,14 +142,12 @@ Eigen::Index lastZeroFromFront(const Eigen::Ref& squareDistance inline void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDistance1d, std::vector& lowerBounds) { - assert(lowerBounds.size() >= squareDistance1d.size()); - auto start = lastZeroFromFront(squareDistance1d); // Only need to process line if there are nonzero elements. Also the first zeros stay untouched. if (start < squareDistance1d.size()) { auto startIt = fillLowerBounds(squareDistance1d, lowerBounds, start); - extractSquareDistances(squareDistance1d, lowerBounds, startIt, start); + extractSquareDistances(squareDistance1d, startIt, start); } } @@ -159,20 +157,18 @@ inline void squaredDistanceTransform_1d_inplace(Eigen::Ref squa * @param lowerBounds : work vector */ inline void distanceTransform_1d_inplace(Eigen::Ref squareDistance1d, std::vector& lowerBounds) { - assert(lowerBounds.size() >= squareDistance1d.size()); - auto start = lastZeroFromFront(squareDistance1d); // Only need to process line if there are nonzero elements. Also the first zeros stay untouched. if (start < squareDistance1d.size()) { auto startIt = fillLowerBounds(squareDistance1d, lowerBounds, start); - extractDistances(squareDistance1d, lowerBounds, startIt, start); + extractDistances(squareDistance1d, startIt, start); } } void computePixelDistance2dTranspose(Matrix& input, Matrix& distanceTranspose) { - const size_t n = input.rows(); - const size_t m = input.cols(); + const auto n = input.rows(); + const auto m = input.cols(); // Allocate a buffer big enough for processing both rowise and columnwise std::vector lowerBounds(std::max(n, m)); From 9cf2275553e8688979882c2206f4c82945348358 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 23 Mar 2022 09:24:55 +0100 Subject: [PATCH 180/504] reduce median filter repeats to 1 --- convex_plane_decomposition_ros/config/parameters.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/convex_plane_decomposition_ros/config/parameters.yaml index 0ecc3d1d..412d6018 100644 --- a/convex_plane_decomposition_ros/config/parameters.yaml +++ b/convex_plane_decomposition_ros/config/parameters.yaml @@ -1,7 +1,7 @@ preprocessing: resolution: 0.04 # Resampling resolution, set negative to skip, requires inpainting to be used kernelSize: 3 # Kernel size of the median filter, either 3 or 5 - numberOfRepeats: 2 # Number of times to apply the same filter + numberOfRepeats: 1 # Number of times to apply the same filter increasing: False # Increase the kernel size each iteration. sliding_window_plane_extractor: From 3f975aa9aebd2ee68c5bf9bacdcc8bab0bb53510 Mon Sep 17 00:00:00 2001 From: Takahiro Miki Date: Thu, 24 Mar 2022 18:00:26 +0100 Subject: [PATCH 181/504] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..0c612528 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# elevation_mapping_cupy +Elevation Mapping on GPU. From c5fc54b58939124c346d3401cef7a570f5aa3577 Mon Sep 17 00:00:00 2001 From: Takahiro Miki Date: Thu, 24 Mar 2022 18:00:42 +0100 Subject: [PATCH 182/504] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0c612528..9940d900 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # elevation_mapping_cupy Elevation Mapping on GPU. +(Preparing for opensourcing) From f81e7bdb4a0699bc2da0480c530255a844ef280a Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 28 Mar 2022 21:02:47 +0200 Subject: [PATCH 183/504] fix time stamp on pointclouds --- .../SegmentedPlanesTerrainModelRos.h | 1 - .../src/SegmentedPlanesTerrainModelRos.cpp | 3 --- signed_distance_field/src/GridmapSignedDistanceField.cpp | 6 +++++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h index f16aa770..1e9bf0e0 100644 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h +++ b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h @@ -50,7 +50,6 @@ class SegmentedPlanesTerrainModelRos { std::mutex pointCloudMutex_; pcl::PointCloud pointCloud_; - std::string frameId_; ocs2::benchmark::RepeatedTimer callbackTimer_; }; diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp index af91f652..e7def050 100644 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp +++ b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp @@ -58,8 +58,6 @@ void SegmentedPlanesTerrainModelRos::publish() { if (!pointcloud.empty()) { sensor_msgs::PointCloud2 pointCloud2Msg; pcl::toROSMsg(pointcloud, pointCloud2Msg); - - pointCloud2Msg.header = ocs2::getHeaderMsg(frameId_, ros::Time::now()); distanceFieldPublisher_.publish(pointCloud2Msg); } } @@ -83,7 +81,6 @@ void SegmentedPlanesTerrainModelRos::callback(const convex_plane_decomposition_m auto pointCloud = sdfPtr->asPointCloud(1, [](float val) { return -0.05F <= val && val <= 0.0F; }); std::lock_guard lock(pointCloudMutex_); pointCloud_.swap(pointCloud); - frameId_ = terrainPtr->planarTerrain().gridMap.getFrameId(); } { // Move to storage under the lock diff --git a/signed_distance_field/src/GridmapSignedDistanceField.cpp b/signed_distance_field/src/GridmapSignedDistanceField.cpp index 4b3c4e19..cb2b56aa 100644 --- a/signed_distance_field/src/GridmapSignedDistanceField.cpp +++ b/signed_distance_field/src/GridmapSignedDistanceField.cpp @@ -8,6 +8,8 @@ #include "signed_distance_field/GridmapSignedDistanceField.h" +#include + #include "signed_distance_field/DistanceDerivatives.h" #include "signed_distance_field/SignedDistance2d.h" @@ -174,7 +176,9 @@ void GridmapSignedDistanceField::emplacebackLayerData(const Matrix& signedDistan pcl::PointCloud GridmapSignedDistanceField::asPointCloud(size_t decimation, const std::function& condition) const { pcl::PointCloud points; - points.header.stamp = timestamp_; + + // Convert Gridmap time -> ros time -> pcl time + points.header.stamp = pcl_conversions::toPCL(ros::Time().fromNSec(timestamp_)); points.header.frame_id = frameId_; points.reserve(gridmap3DLookup_.linearSize()); From 60c4f3ff3367f457ca5ae67700acc3d73976a339 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 25 Apr 2022 15:56:35 +0200 Subject: [PATCH 184/504] add vtk as exec dep to resolve downstream build issue --- segmented_planes_terrain_model/package.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/segmented_planes_terrain_model/package.xml b/segmented_planes_terrain_model/package.xml index a876d763..3db47322 100644 --- a/segmented_planes_terrain_model/package.xml +++ b/segmented_planes_terrain_model/package.xml @@ -20,5 +20,6 @@ roscpp visualization_msgs sensor_msgs + libvtk7-dev From bcbfd631b116dc9d45b0e64ad94424fe47023b57 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 28 Apr 2022 14:48:05 +0200 Subject: [PATCH 185/504] Removed old file --- jenkins-pipeline | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 jenkins-pipeline diff --git a/jenkins-pipeline b/jenkins-pipeline deleted file mode 100644 index 59d9ff9b..00000000 --- a/jenkins-pipeline +++ /dev/null @@ -1,2 +0,0 @@ -library 'continuous_integration_pipeline' -ciPipeline("") From 0b44278d97baf5cd8a4a214d6687427f706874e0 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 28 Apr 2022 15:39:32 +0200 Subject: [PATCH 186/504] remove comment --- elevation_mapping_cupy/script/plugins/min_filter.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/elevation_mapping_cupy/script/plugins/min_filter.py b/elevation_mapping_cupy/script/plugins/min_filter.py index 460d7832..331b61fc 100644 --- a/elevation_mapping_cupy/script/plugins/min_filter.py +++ b/elevation_mapping_cupy/script/plugins/min_filter.py @@ -63,8 +63,6 @@ def __init__(self, cell_n:int=100, dilation_size:int=5, iteration_n:int=5, **kwa string.Template(''' U h = map[get_map_idx(i, 0)]; U valid = mask[get_map_idx(i, 0)]; - // newmap[get_map_idx(i, 0)] = h; - // newmask[get_map_idx(i, 0)] = valid; if (valid < 0.5) { U min_value = 1000000.0; for (int dy = -${dilation_size}; dy <= ${dilation_size}; dy++) { From e23d38410fe19d246d74793f153dc8fe3c8be2ed Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 3 May 2022 20:11:03 +0200 Subject: [PATCH 187/504] add include guards --- .../include/elevation_mapping_cupy/elevation_mapping_ros.hpp | 3 +++ .../elevation_mapping_cupy/elevation_mapping_wrapper.hpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 4a7cbc97..2de9f917 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -2,6 +2,9 @@ // Copyright (c) 2022, Takahiro Miki. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for details. // + +#pragma once + #include // everything needed for embedding #include #include diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index 1d7d47b5..afb01452 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -2,6 +2,9 @@ // Copyright (c) 2022, Takahiro Miki. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for details. // + +#pragma once + #include // everything needed for embedding #include #include From 7a74217f837f843b246441bf72818e186a85a568 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 3 May 2022 20:40:16 +0200 Subject: [PATCH 188/504] organize includes, run clang-format, fix simple clang-tidy complaints --- .../elevation_mapping_ros.hpp | 202 +++++++------ .../elevation_mapping_wrapper.hpp | 83 ++--- .../src/elevation_mapping_node.cpp | 25 +- .../src/elevation_mapping_ros.cpp | 286 +++++++++--------- .../src/elevation_mapping_wrapper.cpp | 121 +++----- 5 files changed, 342 insertions(+), 375 deletions(-) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 2de9f917..e59375e1 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -5,125 +5,131 @@ #pragma once -#include // everything needed for embedding +// STL #include + +// Boost +#include + +// Eigen #include +// Pybind +#include // everything needed for embedding + +// ROS +#include #include #include -#include #include #include +#include #include #include #include -#include + // Grid Map -#include -#include #include -#include -#include +#include +#include + // PCL -#include #include +#include #include -#include + +#include +#include #include "elevation_mapping_cupy/elevation_mapping_wrapper.hpp" namespace py = pybind11; - -namespace elevation_mapping_cupy{ - +namespace elevation_mapping_cupy { class ElevationMappingNode { - public: - ElevationMappingNode(ros::NodeHandle& nh); - ~ElevationMappingNode() = default; - - private: - void readParameters(); - void setupMapPublishers(); - void pointcloudCallback(const sensor_msgs::PointCloud2& cloud); - void publishAsPointCloud(); - bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); - bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, - elevation_map_msgs::CheckSafety::Response& response); - bool initializeMap(elevation_map_msgs::Initialize::Request& request, - elevation_map_msgs::Initialize::Response& response); - bool clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); - bool clearMapWithInitializer(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); - bool setPublishPoint(std_srvs::SetBool::Request& request, std_srvs::SetBool::Response& response); - void updatePose(const ros::TimerEvent&); - void updateVariance(const ros::TimerEvent&); - void updateTime(const ros::TimerEvent&); - void updateGridMap(const ros::TimerEvent&); - void publishNormalAsArrow(const grid_map::GridMap& map); - void initializeWithTF(); - void publishMapToOdom(double error); - void publishStatistics(const ros::TimerEvent&); - void publishMapOfIndex(int index); - - visualization_msgs::Marker vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id); - ros::NodeHandle nh_; - std::vector pointcloudSubs_; - std::vector mapPubs_; - ros::Publisher alivePub_; - ros::Publisher pointPub_; - ros::Publisher normalPub_; - ros::Publisher statisticsPub_; - ros::ServiceServer rawSubmapService_; - ros::ServiceServer clearMapService_; - ros::ServiceServer clearMapWithInitializerService_; - ros::ServiceServer initializeMapService_; - ros::ServiceServer setPublishPointService_; - ros::ServiceServer checkSafetyService_; - ros::Timer updateVarianceTimer_; - ros::Timer updateTimeTimer_; - ros::Timer updatePoseTimer_; - ros::Timer updateGridMapTimer_; - ros::Timer publishStatisticsTimer_; - ros::Time lastStatisticsPublishedTime_; - tf::TransformListener transformListener_; - ElevationMappingWrapper map_; - std::string mapFrameId_; - std::string correctedMapFrameId_; - std::string baseFrameId_; - grid_map::GridMap gridMap_; - - // map topics info - std::vector> map_topics_; - std::vector> map_layers_; - std::vector> map_basic_layers_; - std::set map_layers_all_; - std::set map_layers_sync_; - std::vector map_fps_; - std::set map_fps_unique_; - std::vector mapTimers_; - - std::vector initialize_frame_id_; - std::vector initialize_tf_offset_; - std::string initializeMethod_; - - Eigen::Vector3d lowpassPosition_; - Eigen::Vector4d lowpassOrientation_; - - boost::recursive_mutex mapMutex_; - - double positionError_; - double orientationError_; - double positionAlpha_; - double orientationAlpha_; - double recordableFps_; - bool enablePointCloudPublishing_; - bool enableNormalArrowPublishing_; - bool enableDriftCorrectedTFPublishing_; - bool useInitializerAtStart_; - bool isGridmapUpdated_; - double initializeTfGridSize_; - int pointCloudProcessCounter_; + public: + ElevationMappingNode(ros::NodeHandle& nh); + + private: + void readParameters(); + void setupMapPublishers(); + void pointcloudCallback(const sensor_msgs::PointCloud2& cloud); + void publishAsPointCloud(); + bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); + bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response); + bool initializeMap(elevation_map_msgs::Initialize::Request& request, elevation_map_msgs::Initialize::Response& response); + bool clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + bool clearMapWithInitializer(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + bool setPublishPoint(std_srvs::SetBool::Request& request, std_srvs::SetBool::Response& response); + void updatePose(const ros::TimerEvent&); + void updateVariance(const ros::TimerEvent&); + void updateTime(const ros::TimerEvent&); + void updateGridMap(const ros::TimerEvent&); + void publishNormalAsArrow(const grid_map::GridMap& map); + void initializeWithTF(); + void publishMapToOdom(double error); + void publishStatistics(const ros::TimerEvent&); + void publishMapOfIndex(int index); + + visualization_msgs::Marker vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id); + ros::NodeHandle nh_; + std::vector pointcloudSubs_; + std::vector mapPubs_; + ros::Publisher alivePub_; + ros::Publisher pointPub_; + ros::Publisher normalPub_; + ros::Publisher statisticsPub_; + ros::ServiceServer rawSubmapService_; + ros::ServiceServer clearMapService_; + ros::ServiceServer clearMapWithInitializerService_; + ros::ServiceServer initializeMapService_; + ros::ServiceServer setPublishPointService_; + ros::ServiceServer checkSafetyService_; + ros::Timer updateVarianceTimer_; + ros::Timer updateTimeTimer_; + ros::Timer updatePoseTimer_; + ros::Timer updateGridMapTimer_; + ros::Timer publishStatisticsTimer_; + ros::Time lastStatisticsPublishedTime_; + tf::TransformListener transformListener_; + ElevationMappingWrapper map_; + std::string mapFrameId_; + std::string correctedMapFrameId_; + std::string baseFrameId_; + grid_map::GridMap gridMap_; + + // map topics info + std::vector> map_topics_; + std::vector> map_layers_; + std::vector> map_basic_layers_; + std::set map_layers_all_; + std::set map_layers_sync_; + std::vector map_fps_; + std::set map_fps_unique_; + std::vector mapTimers_; + + std::vector initialize_frame_id_; + std::vector initialize_tf_offset_; + std::string initializeMethod_; + + Eigen::Vector3d lowpassPosition_; + Eigen::Vector4d lowpassOrientation_; + + boost::recursive_mutex mapMutex_; + + double positionError_; + double orientationError_; + double positionAlpha_; + double orientationAlpha_; + double recordableFps_; + bool enablePointCloudPublishing_; + bool enableNormalArrowPublishing_; + bool enableDriftCorrectedTFPublishing_; + bool useInitializerAtStart_; + bool isGridmapUpdated_; + double initializeTfGridSize_; + int pointCloudProcessCounter_; }; -} +} // namespace elevation_mapping_cupy diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index afb01452..97bec2a5 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -5,61 +5,70 @@ #pragma once -#include // everything needed for embedding +// STL #include + +// Eigen #include +// Pybind +#include // everything needed for embedding + +// ROS +#include #include #include -#include #include #include + // Grid Map -#include -#include #include +#include +#include + // PCL -#include #include +#include #include namespace py = pybind11; +namespace elevation_mapping_cupy { -namespace elevation_mapping_cupy{ +class ElevationMappingWrapper { + public: + using RowMatrixXd = Eigen::Matrix; + using RowMatrixXf = Eigen::Matrix; -using RowMatrixXd = Eigen::Matrix; -using RowMatrixXf = Eigen::Matrix; + ElevationMappingWrapper(); -class ElevationMappingWrapper { - public: - ElevationMappingWrapper(); - ~ElevationMappingWrapper()=default; - void initialize(ros::NodeHandle& nh); + void initialize(ros::NodeHandle& nh); + + void input(const pcl::PointCloud::Ptr& pointCloud, const RowMatrixXd& R, const Eigen::VectorXd& t, + const double positionNoise, const double orientationNoise); + void move_to(const Eigen::VectorXd& p); + void clear(); + void update_variance(); + void update_time(); + bool exists_layer(const std::string& layerName); + void get_layer_data(const std::string& layerName, RowMatrixXf& map); + void get_grid_map(grid_map::GridMap& gridMap, const std::vector& layerNames); + void get_polygon_traversability(std::vector& polygon, Eigen::Vector3d& result, + std::vector& untraversable_polygon); + double get_additive_mean_error(); + void initializeWithPoints(std::vector& points, std::string method); + void pointCloudToMatrix(const pcl::PointCloud::Ptr& pointCloud, RowMatrixXd& points); + void addNormalColorLayer(grid_map::GridMap& map); - void input(const pcl::PointCloud::Ptr& pointCloud, const RowMatrixXd& R, const Eigen::VectorXd& t, - const double positionNoise, const double orientationNoise); - void move_to(const Eigen::VectorXd& p); - void clear(); - void update_variance(); - void update_time(); - bool exists_layer(const std::string& layerName); - void get_layer_data(const std::string& layerName, RowMatrixXf& map); - void get_grid_map(grid_map::GridMap& gridMap, const std::vector& layerNames); - void get_polygon_traversability(std::vector& polygon, Eigen::Vector3d& result, std::vector &untraversable_polygon); - double get_additive_mean_error(); - void initializeWithPoints(std::vector &points, std::string method); - void pointCloudToMatrix(const pcl::PointCloud::Ptr& pointCloud, RowMatrixXd& points); - void addNormalColorLayer(grid_map::GridMap& map); - private: - void setParameters(ros::NodeHandle& nh); - py::object map_; - py::object param_; - double resolution_; - double map_length_; - int map_n_; - bool enable_normal_; - bool enable_normal_color_; + private: + void setParameters(ros::NodeHandle& nh); + py::object map_; + py::object param_; + double resolution_; + double map_length_; + int map_n_; + bool enable_normal_; + bool enable_normal_color_; }; -} +} // namespace elevation_mapping_cupy diff --git a/elevation_mapping_cupy/src/elevation_mapping_node.cpp b/elevation_mapping_cupy/src/elevation_mapping_node.cpp index 83369436..47bef360 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_node.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_node.cpp @@ -2,32 +2,25 @@ // Copyright (c) 2022, Takahiro Miki. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for details. // + +// Pybind +#include // everything needed for embedding + +// ROS #include -#include -// Grid Map -#include -#include -// PCL -#include -#include -#include -#include #include "elevation_mapping_cupy/elevation_mapping_ros.hpp" -using namespace elevation_mapping_cupy; - -int main(int argc, char** argv) -{ +int main(int argc, char** argv) { ros::init(argc, argv, "elevation_mapping"); ros::NodeHandle nh("~"); - py::scoped_interpreter guard{}; // start the interpreter and keep it alive - ElevationMappingNode mapNode(nh); + py::scoped_interpreter guard{}; // start the interpreter and keep it alive + elevation_mapping_cupy::ElevationMappingNode mapNode(nh); py::gil_scoped_release release; // Spin - ros::AsyncSpinner spinner(1); // Use n threads + ros::AsyncSpinner spinner(1); // Use n threads spinner.start(); ros::waitForShutdown(); return 0; diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index b40263d0..8cedfaf0 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -2,31 +2,33 @@ // Copyright (c) 2022, Takahiro Miki. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for details. // + #include "elevation_mapping_cupy/elevation_mapping_ros.hpp" -#include + +// Pybind #include -#include -#include -#include -#include -#include + +// ROS #include -#include -#include +#include +#include -namespace elevation_mapping_cupy{ +// PCL +#include +#include -ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) : - lowpassPosition_(0, 0, 0), - lowpassOrientation_(0, 0, 0, 1), - positionError_(0), - orientationError_(0), - positionAlpha_(0.1), - orientationAlpha_(0.1), - enablePointCloudPublishing_(false), - isGridmapUpdated_(false) -{ +namespace elevation_mapping_cupy { + +ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) + : lowpassPosition_(0, 0, 0), + lowpassOrientation_(0, 0, 0, 1), + positionError_(0), + orientationError_(0), + positionAlpha_(0.1), + orientationAlpha_(0.1), + enablePointCloudPublishing_(false), + isGridmapUpdated_(false) { nh_ = nh; map_.initialize(nh_); std::string pose_topic, map_frame; @@ -57,14 +59,13 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) : nh.param("enable_normal_arrow_publishing", enableNormalArrowPublishing_, false); nh.param("enable_drift_corrected_TF_publishing", enableDriftCorrectedTFPublishing_, false); nh.param("use_initializer_at_start", useInitializerAtStart_, false); - for (const auto& pointcloud_topic: pointcloud_topics) { + for (const auto& pointcloud_topic : pointcloud_topics) { ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, &ElevationMappingNode::pointcloudCallback, this); pointcloudSubs_.push_back(sub); } // register map publishers - for(auto itr = publishers.begin(); itr != publishers.end(); ++itr) - { + for (auto itr = publishers.begin(); itr != publishers.end(); ++itr) { // parse params std::string topic_name = itr->first; std::vector layers_list; @@ -74,14 +75,19 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) : double fps = itr->second["fps"]; if (fps > updateGridMapFps) { - ROS_WARN("[ElevationMappingCupy] fps for topic %s is larger than map_acquire_fps (%f > %f). The topic data will be only updated at %f fps.", topic_name.c_str(), fps, updateGridMapFps, updateGridMapFps); + ROS_WARN( + "[ElevationMappingCupy] fps for topic %s is larger than map_acquire_fps (%f > %f). The topic data will be only updated at %f " + "fps.", + topic_name.c_str(), fps, updateGridMapFps, updateGridMapFps); } for (int32_t i = 0; i < layers.size(); ++i) { layers_list.push_back(static_cast(layers[i])); } - for (int32_t i = 0; i < basic_layers.size(); ++i) + + for (int32_t i = 0; i < basic_layers.size(); ++i) { basic_layers_list.push_back(static_cast(basic_layers[i])); + } // make publishers ros::Publisher pub = nh_.advertise(topic_name, 1); @@ -106,46 +112,41 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) : rawSubmapService_ = nh_.advertiseService("get_raw_submap", &ElevationMappingNode::getSubmap, this); clearMapService_ = nh_.advertiseService("clear_map", &ElevationMappingNode::clearMap, this); initializeMapService_ = nh_.advertiseService("initialize", &ElevationMappingNode::initializeMap, this); - clearMapWithInitializerService_ = nh_.advertiseService("clear_map_with_initializer", &ElevationMappingNode::clearMapWithInitializer, this); + clearMapWithInitializerService_ = + nh_.advertiseService("clear_map_with_initializer", &ElevationMappingNode::clearMapWithInitializer, this); setPublishPointService_ = nh_.advertiseService("set_publish_points", &ElevationMappingNode::setPublishPoint, this); checkSafetyService_ = nh_.advertiseService("check_safety", &ElevationMappingNode::checkSafety, this); if (updateVarianceFps > 0) { double duration = 1.0 / (updateVarianceFps + 0.00001); - updateVarianceTimer_ = nh_.createTimer(ros::Duration(duration), - &ElevationMappingNode::updateVariance, this, false, true); + updateVarianceTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updateVariance, this, false, true); } if (timeInterval > 0) { double duration = timeInterval; - updateTimeTimer_ = nh_.createTimer(ros::Duration(duration), - &ElevationMappingNode::updateTime, this, false, true); + updateTimeTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updateTime, this, false, true); } if (updatePoseFps > 0) { double duration = 1.0 / (updatePoseFps + 0.00001); - updatePoseTimer_ = nh_.createTimer(ros::Duration(duration), - &ElevationMappingNode::updatePose, this, false, true); + updatePoseTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updatePose, this, false, true); } if (updateGridMapFps > 0) { double duration = 1.0 / (updateGridMapFps + 0.00001); - updateGridMapTimer_ = nh_.createTimer(ros::Duration(duration), - &ElevationMappingNode::updateGridMap, this, false, true); + updateGridMapTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updateGridMap, this, false, true); } if (publishStatisticsFps > 0) { double duration = 1.0 / (publishStatisticsFps + 0.00001); - publishStatisticsTimer_ = nh_.createTimer(ros::Duration(duration), - &ElevationMappingNode::publishStatistics, this, false, true); + publishStatisticsTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::publishStatistics, this, false, true); } lastStatisticsPublishedTime_ = ros::Time::now(); ROS_INFO("[ElevationMappingCupy] finish initialization"); } - // setup map publishers void ElevationMappingNode::setupMapPublishers() { // Find the layers with highest fps. float max_fps = -1; // create timers for each unique map frequencies - for(auto fps : map_fps_unique_) { + for (auto fps : map_fps_unique_) { // which publisher to call in the timer callback std::vector indices; // if this fps is max, update the map layers. @@ -153,37 +154,41 @@ void ElevationMappingNode::setupMapPublishers() { max_fps = fps; map_layers_all_.clear(); } - for(int i=0; i= max_fps) { - for (const auto layer: map_layers_[i]) + for (const auto layer : map_layers_[i]) { map_layers_all_.insert(layer); + } } } } // callback funtion. // It publishes to specific topics. - auto cb = [this, indices](const ros::TimerEvent&) { for(int i:indices) { publishMapOfIndex(i); } }; + auto cb = [this, indices](const ros::TimerEvent&) { + for (int i : indices) { + publishMapOfIndex(i); + } + }; double duration = 1.0 / (fps + 0.00001); mapTimers_.push_back(nh_.createTimer(ros::Duration(duration), cb)); } } - void ElevationMappingNode::publishMapOfIndex(int index) { // publish the map layers of index - if(!isGridmapUpdated_) + if (!isGridmapUpdated_) { return; + } grid_map_msgs::GridMap msg; std::vector layers; - for (const auto& layer: map_layers_[index]) { + for (const auto& layer : map_layers_[index]) { const bool is_layer_in_all = map_layers_all_.find(layer) != map_layers_all_.end(); if (is_layer_in_all && gridMap_.exists(layer)) { layers.push_back(layer); - } - else if (map_.exists_layer(layer)) { + } else if (map_.exists_layer(layer)) { // if there are layers which is not in the syncing layer. boost::recursive_mutex::scoped_lock scopedLockForGridMap(mapMutex_); RowMatrixXf map_data; @@ -192,19 +197,17 @@ void ElevationMappingNode::publishMapOfIndex(int index) { layers.push_back(layer); } } - if (layers.size() == 0) + if (layers.empty()) { return; + } boost::recursive_mutex::scoped_lock scopedLockForGridMap(mapMutex_); grid_map::GridMapRosConverter::toMessage(gridMap_, layers, msg); scopedLockForGridMap.unlock(); msg.basic_layers = map_basic_layers_[index]; mapPubs_[index].publish(msg); - return; } - -void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cloud) -{ +void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cloud) { auto start = ros::Time::now(); pcl::PCLPointCloud2 pcl_pc; pcl_conversions::toPCL(cloud, pcl_pc); @@ -219,37 +222,31 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl transformListener_.waitForTransform(mapFrameId_, sensorFrameId, timeStamp, ros::Duration(1.0)); transformListener_.lookupTransform(mapFrameId_, sensorFrameId, timeStamp, transformTf); poseTFToEigen(transformTf, transformationSensorToMap); - } - catch (tf::TransformException &ex) { + } catch (tf::TransformException& ex) { ROS_ERROR("%s", ex.what()); return; } - map_.input(pointCloud, - transformationSensorToMap.rotation(), - transformationSensorToMap.translation(), - positionError_, - orientationError_); - + map_.input(pointCloud, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError_, orientationError_); + if (enableDriftCorrectedTFPublishing_) { publishMapToOdom(map_.get_additive_mean_error()); } - ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed a point cloud (%i points) in %f sec.", static_cast(pointCloud->size()), (ros::Time::now() - start).toSec()); + ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed a point cloud (%i points) in %f sec.", static_cast(pointCloud->size()), + (ros::Time::now() - start).toSec()); ROS_DEBUG_THROTTLE(1.0, "positionError: %f ", positionError_); ROS_DEBUG_THROTTLE(1.0, "orientationError: %f ", orientationError_); // This is used for publishing as statistics. pointCloudProcessCounter_++; } -void ElevationMappingNode::updatePose(const ros::TimerEvent&) -{ +void ElevationMappingNode::updatePose(const ros::TimerEvent&) { tf::StampedTransform transformTf; const auto& timeStamp = ros::Time::now(); try { transformListener_.waitForTransform(mapFrameId_, baseFrameId_, timeStamp, ros::Duration(1.0)); transformListener_.lookupTransform(mapFrameId_, baseFrameId_, timeStamp, transformTf); - } - catch (tf::TransformException &ex) { + } catch (tf::TransformException& ex) { ROS_ERROR("%s", ex.what()); return; } @@ -258,8 +255,8 @@ void ElevationMappingNode::updatePose(const ros::TimerEvent&) Eigen::Vector3d position(transformTf.getOrigin().x(), transformTf.getOrigin().y(), transformTf.getOrigin().z()); map_.move_to(position); Eigen::Vector3d position3(transformTf.getOrigin().x(), transformTf.getOrigin().y(), transformTf.getOrigin().z()); - Eigen::Vector4d orientation(transformTf.getRotation().x(), transformTf.getRotation().y(), - transformTf.getRotation().z(), transformTf.getRotation().w()); + Eigen::Vector4d orientation(transformTf.getRotation().x(), transformTf.getRotation().y(), transformTf.getRotation().z(), + transformTf.getRotation().w()); lowpassPosition_ = positionAlpha_ * position3 + (1 - positionAlpha_) * lowpassPosition_; lowpassOrientation_ = orientationAlpha_ * orientation + (1 - orientationAlpha_) * lowpassOrientation_; positionError_ = (position3 - lowpassPosition_).norm(); @@ -277,8 +274,7 @@ void ElevationMappingNode::publishAsPointCloud() { pointPub_.publish(msg); } -bool ElevationMappingNode::getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response) -{ +bool ElevationMappingNode::getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response) { std::string requestedFrameId = request.frame_id; Eigen::Isometry3d transformationOdomToMap; grid_map::Position requestedSubmapPosition(request.position_x, request.position_y); @@ -289,8 +285,7 @@ bool ElevationMappingNode::getSubmap(grid_map_msgs::GetGridMap::Request& request transformListener_.waitForTransform(requestedFrameId, mapFrameId_, timeStamp, ros::Duration(1.0)); transformListener_.lookupTransform(requestedFrameId, mapFrameId_, timeStamp, transformTf); tf::poseTFToEigen(transformTf, transformationOdomToMap); - } - catch (tf::TransformException &ex) { + } catch (tf::TransformException& ex) { ROS_ERROR("%s", ex.what()); return false; } @@ -300,7 +295,8 @@ bool ElevationMappingNode::getSubmap(grid_map_msgs::GetGridMap::Request& request requestedSubmapPosition.y() = mapP.y(); } grid_map::Length requestedSubmapLength(request.length_x, request.length_y); - ROS_DEBUG("Elevation submap request: Position x=%f, y=%f, Length x=%f, y=%f.", requestedSubmapPosition.x(), requestedSubmapPosition.y(), requestedSubmapLength(0), requestedSubmapLength(1)); + ROS_DEBUG("Elevation submap request: Position x=%f, y=%f, Length x=%f, y=%f.", requestedSubmapPosition.x(), requestedSubmapPosition.y(), + requestedSubmapLength(0), requestedSubmapLength(1)); bool isSuccess; grid_map::Index index; @@ -316,8 +312,7 @@ bool ElevationMappingNode::getSubmap(grid_map_msgs::GetGridMap::Request& request if (request.layers.empty()) { grid_map::GridMapRosConverter::toMessage(subMap, response.map); - } - else { + } else { std::vector layers; for (const auto& layer : request.layers) { layers.push_back(layer); @@ -327,15 +322,13 @@ bool ElevationMappingNode::getSubmap(grid_map_msgs::GetGridMap::Request& request return isSuccess; } -bool ElevationMappingNode::clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) -{ +bool ElevationMappingNode::clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) { ROS_INFO("Clearing map."); map_.clear(); return true; } -bool ElevationMappingNode::clearMapWithInitializer(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) -{ +bool ElevationMappingNode::clearMapWithInitializer(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) { ROS_INFO("Clearing map with initializer."); map_.clear(); initializeWithTF(); @@ -343,45 +336,43 @@ bool ElevationMappingNode::clearMapWithInitializer(std_srvs::Empty::Request& req } void ElevationMappingNode::initializeWithTF() { - std::vector points; - const auto& timeStamp = ros::Time::now(); - int i = 0; - Eigen::Vector3d p; - for (const auto& frame_id: initialize_frame_id_) { - // Get tf from map frame to tf frame - Eigen::Affine3d transformationBaseToMap; - tf::StampedTransform transformTf; - try { - transformListener_.waitForTransform(mapFrameId_, frame_id, timeStamp, ros::Duration(1.0)); - transformListener_.lookupTransform(mapFrameId_, frame_id, timeStamp, transformTf); - poseTFToEigen(transformTf, transformationBaseToMap); - } - catch (tf::TransformException &ex) { - ROS_ERROR("%s", ex.what()); - return; - } - p = transformationBaseToMap.translation(); - p.z() += initialize_tf_offset_[i]; - points.push_back(p); - i++; - } - if (points.size() > 0 && points.size() < 3) { - points.push_back(p + Eigen::Vector3d(initializeTfGridSize_, initializeTfGridSize_, 0)); - points.push_back(p + Eigen::Vector3d(-initializeTfGridSize_, initializeTfGridSize_, 0)); - points.push_back(p + Eigen::Vector3d(initializeTfGridSize_, -initializeTfGridSize_, 0)); - points.push_back(p + Eigen::Vector3d(-initializeTfGridSize_, -initializeTfGridSize_, 0)); + std::vector points; + const auto& timeStamp = ros::Time::now(); + int i = 0; + Eigen::Vector3d p; + for (const auto& frame_id : initialize_frame_id_) { + // Get tf from map frame to tf frame + Eigen::Affine3d transformationBaseToMap; + tf::StampedTransform transformTf; + try { + transformListener_.waitForTransform(mapFrameId_, frame_id, timeStamp, ros::Duration(1.0)); + transformListener_.lookupTransform(mapFrameId_, frame_id, timeStamp, transformTf); + poseTFToEigen(transformTf, transformationBaseToMap); + } catch (tf::TransformException& ex) { + ROS_ERROR("%s", ex.what()); + return; } - ROS_INFO_STREAM("Initializing map with points using " << initializeMethod_); - map_.initializeWithPoints(points, initializeMethod_); + p = transformationBaseToMap.translation(); + p.z() += initialize_tf_offset_[i]; + points.push_back(p); + i++; + } + if (!points.empty() && points.size() < 3) { + points.emplace_back(p + Eigen::Vector3d(initializeTfGridSize_, initializeTfGridSize_, 0)); + points.emplace_back(p + Eigen::Vector3d(-initializeTfGridSize_, initializeTfGridSize_, 0)); + points.emplace_back(p + Eigen::Vector3d(initializeTfGridSize_, -initializeTfGridSize_, 0)); + points.emplace_back(p + Eigen::Vector3d(-initializeTfGridSize_, -initializeTfGridSize_, 0)); + } + ROS_INFO_STREAM("Initializing map with points using " << initializeMethod_); + map_.initializeWithPoints(points, initializeMethod_); } - bool ElevationMappingNode::checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response) { - - for (const auto& polygonstamped: request.polygons) { - if (polygonstamped.polygon.points.size() == 0) + for (const auto& polygonstamped : request.polygons) { + if (polygonstamped.polygon.points.empty()) { continue; + } std::vector polygon; std::vector untraversable_polygon; Eigen::Vector3d result; @@ -390,7 +381,6 @@ bool ElevationMappingNode::checkSafety(elevation_map_msgs::CheckSafety::Request& const auto& timeStamp = polygonstamped.header.stamp; double polygon_z = polygonstamped.polygon.points[0].z; - // Get tf from map frame to polygon frame if (mapFrameId_ != polygonFrameId) { Eigen::Affine3d transformationBaseToMap; @@ -399,20 +389,18 @@ bool ElevationMappingNode::checkSafety(elevation_map_msgs::CheckSafety::Request& transformListener_.waitForTransform(mapFrameId_, polygonFrameId, timeStamp, ros::Duration(1.0)); transformListener_.lookupTransform(mapFrameId_, polygonFrameId, timeStamp, transformTf); poseTFToEigen(transformTf, transformationBaseToMap); - } - catch (tf::TransformException &ex) { + } catch (tf::TransformException& ex) { ROS_ERROR("%s", ex.what()); return false; } - for (const auto& p: polygonstamped.polygon.points) { + for (const auto& p : polygonstamped.polygon.points) { const auto& pvector = Eigen::Vector3d(p.x, p.y, p.z); const auto transformed_p = transformationBaseToMap * pvector; - polygon.push_back(Eigen::Vector2d(transformed_p.x(), transformed_p.y())); + polygon.emplace_back(Eigen::Vector2d(transformed_p.x(), transformed_p.y())); } - } - else { - for (const auto& p: polygonstamped.polygon.points) { - polygon.push_back(Eigen::Vector2d(p.x, p.y)); + } else { + for (const auto& p : polygonstamped.polygon.points) { + polygon.emplace_back(Eigen::Vector2d(p.x, p.y)); } } @@ -421,11 +409,11 @@ bool ElevationMappingNode::checkSafety(elevation_map_msgs::CheckSafety::Request& geometry_msgs::PolygonStamped untraversable_polygonstamped; untraversable_polygonstamped.header.stamp = ros::Time::now(); untraversable_polygonstamped.header.frame_id = mapFrameId_; - for (const auto& p: untraversable_polygon) { + for (const auto& p : untraversable_polygon) { geometry_msgs::Point32 point; - point.x = p.x(); - point.y = p.y(); - point.z = polygon_z; + point.x = static_cast(p.x()); + point.y = static_cast(p.y()); + point.z = static_cast(polygon_z); untraversable_polygonstamped.polygon.points.push_back(point); } // traversability_result; @@ -442,7 +430,6 @@ bool ElevationMappingNode::setPublishPoint(std_srvs::SetBool::Request& request, return true; } - void ElevationMappingNode::updateVariance(const ros::TimerEvent&) { map_.update_variance(); } @@ -457,8 +444,9 @@ void ElevationMappingNode::publishStatistics(const ros::TimerEvent&) { lastStatisticsPublishedTime_ = now; elevation_map_msgs::Statistics msg; msg.header.stamp = now; - if (dt > 0.0) - msg.pointcloud_process_fps = (double)pointCloudProcessCounter_ / dt; + if (dt > 0.0) { + msg.pointcloud_process_fps = pointCloudProcessCounter_ / dt; + } pointCloudProcessCounter_ = 0; statisticsPub_.publish(msg); } @@ -482,11 +470,10 @@ void ElevationMappingNode::updateGridMap(const ros::TimerEvent&) { bool ElevationMappingNode::initializeMap(elevation_map_msgs::Initialize::Request& request, elevation_map_msgs::Initialize::Response& response) { - // If initialize method is points if (request.type == request.POINTS) { std::vector points; - for (const auto& point: request.points) { + for (const auto& point : request.points) { const auto& pointFrameId = point.header.frame_id; const auto& timeStamp = point.header.stamp; const auto& pvector = Eigen::Vector3d(point.point.x, point.point.y, point.point.z); @@ -499,20 +486,18 @@ bool ElevationMappingNode::initializeMap(elevation_map_msgs::Initialize::Request transformListener_.waitForTransform(mapFrameId_, pointFrameId, timeStamp, ros::Duration(1.0)); transformListener_.lookupTransform(mapFrameId_, pointFrameId, timeStamp, transformTf); poseTFToEigen(transformTf, transformationBaseToMap); - } - catch (tf::TransformException &ex) { + } catch (tf::TransformException& ex) { ROS_ERROR("%s", ex.what()); return false; } const auto transformed_p = transformationBaseToMap * pvector; points.push_back(transformed_p); - } - else { + } else { points.push_back(pvector); } } std::string method; - switch (request.method){ + switch (request.method) { case request.NEAREST: method = "nearest"; break; @@ -531,34 +516,36 @@ bool ElevationMappingNode::initializeMap(elevation_map_msgs::Initialize::Request } void ElevationMappingNode::publishNormalAsArrow(const grid_map::GridMap& map) { - auto start = ros::Time::now(); + auto startTime = ros::Time::now(); - auto& normalX = map["normal_x"]; - auto& normalY = map["normal_y"]; - auto& normalZ = map["normal_z"]; + const auto& normalX = map["normal_x"]; + const auto& normalY = map["normal_y"]; + const auto& normalZ = map["normal_z"]; double scale = 0.1; - + visualization_msgs::MarkerArray markerArray; // For each cell in map. for (grid_map::GridMapIterator iterator(map); !iterator.isPastEnd(); ++iterator) { - const int i = iterator.getLinearIndex(); if (!map.isValid(*iterator, "elevation")) { - continue;} + continue; + } grid_map::Position3 p; map.getPosition3("elevation", *iterator, p); - Eigen::Vector3d start = (Eigen::Vector3d)p; + Eigen::Vector3d start = p; + const auto i = iterator.getLinearIndex(); Eigen::Vector3d normal(normalX(i), normalY(i), normalZ(i)); Eigen::Vector3d end = start + normal * scale; if (normal.norm() < 0.1) { - continue;} + continue; + } markerArray.markers.push_back(vectorToArrowMarker(start, end, i)); } normalPub_.publish(markerArray); - ROS_INFO_THROTTLE(1.0, "publish as normal in %f sec.", (ros::Time::now() - start).toSec()); - return; + ROS_INFO_THROTTLE(1.0, "publish as normal in %f sec.", (ros::Time::now() - startTime).toSec()); } -visualization_msgs::Marker ElevationMappingNode::vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id) { +visualization_msgs::Marker ElevationMappingNode::vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, + const int id) { visualization_msgs::Marker marker; marker.header.frame_id = mapFrameId_; marker.header.stamp = ros::Time::now(); @@ -580,7 +567,7 @@ visualization_msgs::Marker ElevationMappingNode::vectorToArrowMarker(const Eigen marker.scale.x = 0.01; marker.scale.y = 0.01; marker.scale.z = 0.01; - marker.color.a = 1.0; // Don't forget to set the alpha! + marker.color.a = 1.0; // Don't forget to set the alpha! marker.color.r = 0.0; marker.color.g = 1.0; marker.color.b = 0.0; @@ -588,15 +575,14 @@ visualization_msgs::Marker ElevationMappingNode::vectorToArrowMarker(const Eigen return marker; } -void ElevationMappingNode::publishMapToOdom(double error) -{ +void ElevationMappingNode::publishMapToOdom(double error) { static tf::TransformBroadcaster br; tf::Transform transform; - transform.setOrigin( tf::Vector3(0.0, 0.0, error) ); + transform.setOrigin(tf::Vector3(0.0, 0.0, error)); tf::Quaternion q; q.setRPY(0, 0, 0); transform.setRotation(q); br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), mapFrameId_, correctedMapFrameId_)); } -} +} // namespace elevation_mapping_cupy diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index e7f53e77..40753a2c 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -2,22 +2,21 @@ // Copyright (c) 2022, Takahiro Miki. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for details. // + #include "elevation_mapping_cupy/elevation_mapping_wrapper.hpp" -#include + +// Pybind #include -#include -#include + +// PCL #include -#include + +// ROS #include -#include -namespace elevation_mapping_cupy{ -using RowMatrixXd = Eigen::Matrix; -using RowMatrixXf = Eigen::Matrix; +namespace elevation_mapping_cupy { -ElevationMappingWrapper::ElevationMappingWrapper() { -} +ElevationMappingWrapper::ElevationMappingWrapper() {} void ElevationMappingWrapper::initialize(ros::NodeHandle& nh) { // Add the elevation_mapping_cupy path to sys.path @@ -37,7 +36,7 @@ void ElevationMappingWrapper::initialize(ros::NodeHandle& nh) { map_ = elevation_mapping.attr("ElevationMap")(param_); } -/* +/** * Load ros parameters into Parameter class. * Search for the same name within the name space. */ @@ -54,23 +53,24 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { std::string name = py::cast(paramNames[i]); if (type == "float") { float param; - if (nh.getParam(name, param)) + if (nh.getParam(name, param)) { param_.attr("set_value")(name, param); - } - else if (type == "str") { + } + } else if (type == "str") { std::string param; - if (nh.getParam(name, param)) + if (nh.getParam(name, param)) { param_.attr("set_value")(name, param); - } - else if (type == "bool") { + } + } else if (type == "bool") { bool param; - if (nh.getParam(name, param)) + if (nh.getParam(name, param)) { param_.attr("set_value")(name, param); - } - else if (type == "int") { + } + } else if (type == "int") { int param; - if (nh.getParam(name, param)) + if (nh.getParam(name, param)) { param_.attr("set_value")(name, param); + } } } @@ -82,24 +82,20 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { nh.param("enable_normal_color", enable_normal_color_, false); } - -void ElevationMappingWrapper::input(const pcl::PointCloud::Ptr& pointCloud, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise) { +void ElevationMappingWrapper::input(const pcl::PointCloud::Ptr& pointCloud, const RowMatrixXd& R, const Eigen::VectorXd& t, + const double positionNoise, const double orientationNoise) { py::gil_scoped_acquire acquire; RowMatrixXd points; pointCloudToMatrix(pointCloud, points); - map_.attr("input")(Eigen::Ref(points), - Eigen::Ref(R), - Eigen::Ref(t), + map_.attr("input")(Eigen::Ref(points), Eigen::Ref(R), Eigen::Ref(t), positionNoise, orientationNoise); } - void ElevationMappingWrapper::move_to(const Eigen::VectorXd& p) { py::gil_scoped_acquire acquire; map_.attr("move_to")(Eigen::Ref(p)); } - void ElevationMappingWrapper::clear() { py::gil_scoped_acquire acquire; map_.attr("clear")(); @@ -107,8 +103,7 @@ void ElevationMappingWrapper::clear() { double ElevationMappingWrapper::get_additive_mean_error() { py::gil_scoped_acquire acquire; - double additive_error = map_.attr("get_additive_mean_error")().cast(); - return additive_error; + return map_.attr("get_additive_mean_error")().cast(); } bool ElevationMappingWrapper::exists_layer(const std::string& layerName) { @@ -119,17 +114,14 @@ bool ElevationMappingWrapper::exists_layer(const std::string& layerName) { void ElevationMappingWrapper::get_layer_data(const std::string& layerName, RowMatrixXf& map) { py::gil_scoped_acquire acquire; map = RowMatrixXf(map_n_, map_n_); - map_.attr("get_map_with_name_ref")( - layerName, - Eigen::Ref(map)); + map_.attr("get_map_with_name_ref")(layerName, Eigen::Ref(map)); } - void ElevationMappingWrapper::get_grid_map(grid_map::GridMap& gridMap, const std::vector& requestLayerNames) { std::vector basicLayerNames; std::vector layerNames = requestLayerNames; std::vector selection; - for (const auto& layerName: layerNames) { + for (const auto& layerName : layerNames) { if (layerName == "elevation") { basicLayerNames.push_back("elevation"); } @@ -143,21 +135,16 @@ void ElevationMappingWrapper::get_grid_map(grid_map::GridMap& gridMap, const std gridMap.setGeometry(length, resolution_, position); std::vector maps; - for (const auto& layerName: layerNames) { + for (const auto& layerName : layerNames) { RowMatrixXf map(map_n_, map_n_); - map_.attr("get_map_with_name_ref")( - layerName, - Eigen::Ref(map)); + map_.attr("get_map_with_name_ref")(layerName, Eigen::Ref(map)); gridMap.add(layerName, map); } if (enable_normal_color_) { RowMatrixXf normal_x(map_n_, map_n_); RowMatrixXf normal_y(map_n_, map_n_); RowMatrixXf normal_z(map_n_, map_n_); - map_.attr("get_normal_ref")( - Eigen::Ref(normal_x), - Eigen::Ref(normal_y), - Eigen::Ref(normal_z)); + map_.attr("get_normal_ref")(Eigen::Ref(normal_x), Eigen::Ref(normal_y), Eigen::Ref(normal_z)); gridMap.add("normal_x", normal_x); gridMap.add("normal_y", normal_y); gridMap.add("normal_z", normal_z); @@ -168,42 +155,39 @@ void ElevationMappingWrapper::get_grid_map(grid_map::GridMap& gridMap, const std } } - -void ElevationMappingWrapper::get_polygon_traversability(std::vector &polygon, Eigen::Vector3d& result, - std::vector &untraversable_polygon) { - RowMatrixXf polygon_m(polygon.size(), 2); - if (polygon.size() < 3) +void ElevationMappingWrapper::get_polygon_traversability(std::vector& polygon, Eigen::Vector3d& result, + std::vector& untraversable_polygon) { + if (polygon.size() < 3) { return; + } + RowMatrixXf polygon_m(polygon.size(), 2); int i = 0; - for (auto& p: polygon) { + for (auto& p : polygon) { polygon_m(i, 0) = p.x(); polygon_m(i, 1) = p.y(); i++; } py::gil_scoped_acquire acquire; - const int untraversable_polygon_num = map_.attr("get_polygon_traversability")( - Eigen::Ref(polygon_m), - Eigen::Ref(result)).cast(); + const int untraversable_polygon_num = + map_.attr("get_polygon_traversability")(Eigen::Ref(polygon_m), Eigen::Ref(result)).cast(); untraversable_polygon.clear(); if (untraversable_polygon_num > 0) { RowMatrixXf untraversable_polygon_m(untraversable_polygon_num, 2); map_.attr("get_untraversable_polygon")(Eigen::Ref(untraversable_polygon_m)); - for (int i = 0; i < untraversable_polygon_num; i++) { + for (int j = 0; j < untraversable_polygon_num; i++) { Eigen::Vector2d p; - p.x() = untraversable_polygon_m(i, 0); - p.y() = untraversable_polygon_m(i, 1); + p.x() = untraversable_polygon_m(j, 0); + p.y() = untraversable_polygon_m(j, 1); untraversable_polygon.push_back(p); } } - - return; } -void ElevationMappingWrapper::initializeWithPoints(std::vector &points, std::string method) { +void ElevationMappingWrapper::initializeWithPoints(std::vector& points, std::string method) { RowMatrixXd points_m(points.size(), 3); int i = 0; - for (auto& p: points) { + for (auto& p : points) { points_m(i, 0) = p.x(); points_m(i, 1) = p.y(); points_m(i, 2) = p.z(); @@ -211,13 +195,9 @@ void ElevationMappingWrapper::initializeWithPoints(std::vector } py::gil_scoped_acquire acquire; map_.attr("initialize_map")(Eigen::Ref(points_m), method); - return; } - -void ElevationMappingWrapper::pointCloudToMatrix(const pcl::PointCloud::Ptr& pointCloud, - RowMatrixXd& points) -{ +void ElevationMappingWrapper::pointCloudToMatrix(const pcl::PointCloud::Ptr& pointCloud, RowMatrixXd& points) { points = RowMatrixXd(pointCloud->size(), 3); for (unsigned int i = 0; i < pointCloud->size(); ++i) { const auto& point = pointCloud->points[i]; @@ -225,11 +205,9 @@ void ElevationMappingWrapper::pointCloudToMatrix(const pcl::PointCloud(point.y); points(i, 2) = static_cast(point.z); } - return; } -void ElevationMappingWrapper::addNormalColorLayer(grid_map::GridMap& map) -{ +void ElevationMappingWrapper::addNormalColorLayer(grid_map::GridMap& map) { const auto& normalX = map["normal_x"]; const auto& normalY = map["normal_y"]; const auto& normalZ = map["normal_z"]; @@ -243,25 +221,20 @@ void ElevationMappingWrapper::addNormalColorLayer(grid_map::GridMap& map) // For each cell in map. for (size_t i = 0; i < color.size(); ++i) { - const Eigen::Vector3f colorVector((normalX(i) + 1.0) / 2.0, - (normalY(i) + 1.0) / 2.0, - (normalZ(i))); + const Eigen::Vector3f colorVector((normalX(i) + 1.0) / 2.0, (normalY(i) + 1.0) / 2.0, (normalZ(i))); Eigen::Vector3i intColorVector = (colorVector * 255.0).cast(); grid_map::colorVectorToValue(intColorVector, color(i)); } - return; } void ElevationMappingWrapper::update_variance() { py::gil_scoped_acquire acquire; map_.attr("update_variance")(); - return; } void ElevationMappingWrapper::update_time() { py::gil_scoped_acquire acquire; map_.attr("update_time")(); - return; } -} +} // namespace elevation_mapping_cupy From 1ff161a0acff81112ea26d38dc79ed2d989b4bad Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 3 May 2022 20:47:45 +0200 Subject: [PATCH 189/504] fix scoping of type --- elevation_mapping_cupy/src/elevation_mapping_ros.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 8cedfaf0..4c9bad59 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -191,7 +191,7 @@ void ElevationMappingNode::publishMapOfIndex(int index) { } else if (map_.exists_layer(layer)) { // if there are layers which is not in the syncing layer. boost::recursive_mutex::scoped_lock scopedLockForGridMap(mapMutex_); - RowMatrixXf map_data; + ElevationMappingWrapper::RowMatrixXf map_data; map_.get_layer_data(layer, map_data); gridMap_.add(layer, map_data); layers.push_back(layer); From f515f47e6d2f67444fa3c17f2a87fa74449c8b73 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 3 May 2022 21:20:37 +0200 Subject: [PATCH 190/504] fix unprotected data sharing. change to simpler lock and mutex. --- .../elevation_mapping_ros.hpp | 12 +++---- .../src/elevation_mapping_ros.cpp | 31 ++++++++++++------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index e59375e1..2f1fa8f0 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -7,9 +7,7 @@ // STL #include - -// Boost -#include +#include // Eigen #include @@ -55,7 +53,7 @@ class ElevationMappingNode { void readParameters(); void setupMapPublishers(); void pointcloudCallback(const sensor_msgs::PointCloud2& cloud); - void publishAsPointCloud(); + void publishAsPointCloud(const grid_map::GridMap& map); bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response); bool initializeMap(elevation_map_msgs::Initialize::Request& request, elevation_map_msgs::Initialize::Response& response); @@ -97,7 +95,6 @@ class ElevationMappingNode { std::string mapFrameId_; std::string correctedMapFrameId_; std::string baseFrameId_; - grid_map::GridMap gridMap_; // map topics info std::vector> map_topics_; @@ -116,7 +113,9 @@ class ElevationMappingNode { Eigen::Vector3d lowpassPosition_; Eigen::Vector4d lowpassOrientation_; - boost::recursive_mutex mapMutex_; + std::mutex mapMutex_; // protects gridMap_ + grid_map::GridMap gridMap_; + std::atomic_bool isGridmapUpdated_; // needs to be atomic (read is protected by mapMutex_) double positionError_; double orientationError_; @@ -127,7 +126,6 @@ class ElevationMappingNode { bool enableNormalArrowPublishing_; bool enableDriftCorrectedTFPublishing_; bool useInitializerAtStart_; - bool isGridmapUpdated_; double initializeTfGridSize_; int pointCloudProcessCounter_; }; diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 4c9bad59..4c324a11 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -186,23 +186,32 @@ void ElevationMappingNode::publishMapOfIndex(int index) { std::vector layers; for (const auto& layer : map_layers_[index]) { const bool is_layer_in_all = map_layers_all_.find(layer) != map_layers_all_.end(); - if (is_layer_in_all && gridMap_.exists(layer)) { + bool layerExistsInMap{false}; + { + std::lock_guard lock(mapMutex_); + layerExistsInMap = gridMap_.exists(layer); + } + + if (is_layer_in_all && layerExistsInMap) { layers.push_back(layer); } else if (map_.exists_layer(layer)) { // if there are layers which is not in the syncing layer. - boost::recursive_mutex::scoped_lock scopedLockForGridMap(mapMutex_); ElevationMappingWrapper::RowMatrixXf map_data; map_.get_layer_data(layer, map_data); - gridMap_.add(layer, map_data); layers.push_back(layer); + std::lock_guard lock(mapMutex_); + gridMap_.add(layer, map_data); } } if (layers.empty()) { return; } - boost::recursive_mutex::scoped_lock scopedLockForGridMap(mapMutex_); - grid_map::GridMapRosConverter::toMessage(gridMap_, layers, msg); - scopedLockForGridMap.unlock(); + + { + std::lock_guard lock(mapMutex_); + grid_map::GridMapRosConverter::toMessage(gridMap_, layers, msg); + } + msg.basic_layers = map_basic_layers_[index]; mapPubs_[index].publish(msg); } @@ -268,9 +277,9 @@ void ElevationMappingNode::updatePose(const ros::TimerEvent&) { } } -void ElevationMappingNode::publishAsPointCloud() { +void ElevationMappingNode::publishAsPointCloud(const grid_map::GridMap& map) { sensor_msgs::PointCloud2 msg; - grid_map::GridMapRosConverter::toPointCloud(gridMap_, "elevation", msg); + grid_map::GridMapRosConverter::toPointCloud(map, "elevation", msg); pointPub_.publish(msg); } @@ -302,7 +311,7 @@ bool ElevationMappingNode::getSubmap(grid_map_msgs::GetGridMap::Request& request grid_map::Index index; grid_map::GridMap subMap; { - boost::recursive_mutex::scoped_lock scopedLockForGridMap(mapMutex_); + std::lock_guard lock(mapMutex_); subMap = gridMap_.getSubmap(requestedSubmapPosition, requestedSubmapLength, index, isSuccess); } const auto& length = subMap.getLength(); @@ -453,14 +462,14 @@ void ElevationMappingNode::publishStatistics(const ros::TimerEvent&) { void ElevationMappingNode::updateGridMap(const ros::TimerEvent&) { std::vector layers(map_layers_all_.begin(), map_layers_all_.end()); - boost::recursive_mutex::scoped_lock scopedLockForGridMap(mapMutex_); + std::lock_guard lock(mapMutex_); map_.get_grid_map(gridMap_, layers); gridMap_.setTimestamp(ros::Time::now().toNSec()); alivePub_.publish(std_msgs::Empty()); // Mostly debug purpose if (enablePointCloudPublishing_) { - publishAsPointCloud(); + publishAsPointCloud(gridMap_); } if (enableNormalArrowPublishing_) { publishNormalAsArrow(gridMap_); From c455c0cef24b800c49ed068b699a5f8fb3718323 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 3 May 2022 22:04:09 +0200 Subject: [PATCH 191/504] fix publishMapOfIndex --- .../src/elevation_mapping_ros.cpp | 39 ++++++++----------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 4c324a11..afabb6e1 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -184,31 +184,26 @@ void ElevationMappingNode::publishMapOfIndex(int index) { } grid_map_msgs::GridMap msg; std::vector layers; - for (const auto& layer : map_layers_[index]) { - const bool is_layer_in_all = map_layers_all_.find(layer) != map_layers_all_.end(); - bool layerExistsInMap{false}; - { - std::lock_guard lock(mapMutex_); - layerExistsInMap = gridMap_.exists(layer); - } - if (is_layer_in_all && layerExistsInMap) { - layers.push_back(layer); - } else if (map_.exists_layer(layer)) { - // if there are layers which is not in the syncing layer. - ElevationMappingWrapper::RowMatrixXf map_data; - map_.get_layer_data(layer, map_data); - layers.push_back(layer); - std::lock_guard lock(mapMutex_); - gridMap_.add(layer, map_data); + { // need continuous lock between adding layers and converting to message. Otherwise updateGridmap can reset the data not in + // map_layers_all_ + std::lock_guard lock(mapMutex_); + for (const auto& layer : map_layers_[index]) { + const bool is_layer_in_all = map_layers_all_.find(layer) != map_layers_all_.end(); + if (is_layer_in_all && gridMap_.exists(layer)) { + layers.push_back(layer); + } else if (map_.exists_layer(layer)) { + // if there are layers which is not in the syncing layer. + ElevationMappingWrapper::RowMatrixXf map_data; + map_.get_layer_data(layer, map_data); + gridMap_.add(layer, map_data); + layers.push_back(layer); + } + } + if (layers.empty()) { + return; } - } - if (layers.empty()) { - return; - } - { - std::lock_guard lock(mapMutex_); grid_map::GridMapRosConverter::toMessage(gridMap_, layers, msg); } From 67d847b59e2479b236100dcaf4ea92a769f010ff Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 3 May 2022 22:36:12 +0200 Subject: [PATCH 192/504] fix typo --- .../include/elevation_mapping_cupy/elevation_mapping_ros.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 2f1fa8f0..31e11481 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -115,7 +115,7 @@ class ElevationMappingNode { std::mutex mapMutex_; // protects gridMap_ grid_map::GridMap gridMap_; - std::atomic_bool isGridmapUpdated_; // needs to be atomic (read is protected by mapMutex_) + std::atomic_bool isGridmapUpdated_; // needs to be atomic (read is not protected by mapMutex_) double positionError_; double orientationError_; From 79c775779b84da8b0e5bc6e861ce3322cd35c4bd Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 4 May 2022 12:24:22 +0200 Subject: [PATCH 193/504] protect shared error state. make counter atomic. make configurable bool atomic --- .../elevation_mapping_ros.hpp | 14 ++++--- .../src/elevation_mapping_ros.cpp | 38 +++++++++++++------ 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 31e11481..7a374437 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -53,7 +53,7 @@ class ElevationMappingNode { void readParameters(); void setupMapPublishers(); void pointcloudCallback(const sensor_msgs::PointCloud2& cloud); - void publishAsPointCloud(const grid_map::GridMap& map); + void publishAsPointCloud(const grid_map::GridMap& map) const; bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response); bool initializeMap(elevation_map_msgs::Initialize::Request& request, elevation_map_msgs::Initialize::Response& response); @@ -64,16 +64,17 @@ class ElevationMappingNode { void updateVariance(const ros::TimerEvent&); void updateTime(const ros::TimerEvent&); void updateGridMap(const ros::TimerEvent&); - void publishNormalAsArrow(const grid_map::GridMap& map); + void publishNormalAsArrow(const grid_map::GridMap& map) const; void initializeWithTF(); void publishMapToOdom(double error); void publishStatistics(const ros::TimerEvent&); void publishMapOfIndex(int index); - visualization_msgs::Marker vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id); + visualization_msgs::Marker vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id) const; ros::NodeHandle nh_; std::vector pointcloudSubs_; std::vector mapPubs_; + tf::TransformBroadcaster tfBroadcaster_; ros::Publisher alivePub_; ros::Publisher pointPub_; ros::Publisher normalPub_; @@ -117,17 +118,20 @@ class ElevationMappingNode { grid_map::GridMap gridMap_; std::atomic_bool isGridmapUpdated_; // needs to be atomic (read is not protected by mapMutex_) + std::mutex errorMutex_; // protects positionError_, and orientationError_ double positionError_; double orientationError_; + double positionAlpha_; double orientationAlpha_; + double recordableFps_; - bool enablePointCloudPublishing_; + std::atomic_bool enablePointCloudPublishing_; bool enableNormalArrowPublishing_; bool enableDriftCorrectedTFPublishing_; bool useInitializerAtStart_; double initializeTfGridSize_; - int pointCloudProcessCounter_; + std::atomic_int pointCloudProcessCounter_; }; } // namespace elevation_mapping_cupy diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index afabb6e1..79941e8f 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -36,6 +36,7 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) std::vector pointcloud_topics; std::vector map_topics; double recordableFps, updateVarianceFps, timeInterval, updatePoseFps, updateGridMapFps, publishStatisticsFps; + bool enablePointCloudPublishing(false); nh.param>("pointcloud_topics", pointcloud_topics, {"points"}); nh.getParam("publishers", publishers); @@ -55,10 +56,13 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) nh.param("initialize_tf_grid_size", initializeTfGridSize_, 0.5); nh.param("map_acquire_fps", updateGridMapFps, 5.0); nh.param("publish_statistics_fps", publishStatisticsFps, 1.0); - nh.param("enable_pointcloud_publishing", enablePointCloudPublishing_, false); + nh.param("enable_pointcloud_publishing", enablePointCloudPublishing, false); nh.param("enable_normal_arrow_publishing", enableNormalArrowPublishing_, false); nh.param("enable_drift_corrected_TF_publishing", enableDriftCorrectedTFPublishing_, false); nh.param("use_initializer_at_start", useInitializerAtStart_, false); + + enablePointCloudPublishing_ = enablePointCloudPublishing; + for (const auto& pointcloud_topic : pointcloud_topics) { ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, &ElevationMappingNode::pointcloudCallback, this); pointcloudSubs_.push_back(sub); @@ -230,7 +234,16 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl ROS_ERROR("%s", ex.what()); return; } - map_.input(pointCloud, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError_, orientationError_); + + double positionError{0.0}; + double orientationError{0.0}; + { + std::lock_guard lock(errorMutex_); + positionError = positionError_; + orientationError = orientationError_; + } + + map_.input(pointCloud, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError, orientationError); if (enableDriftCorrectedTFPublishing_) { publishMapToOdom(map_.get_additive_mean_error()); @@ -238,8 +251,8 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed a point cloud (%i points) in %f sec.", static_cast(pointCloud->size()), (ros::Time::now() - start).toSec()); - ROS_DEBUG_THROTTLE(1.0, "positionError: %f ", positionError_); - ROS_DEBUG_THROTTLE(1.0, "orientationError: %f ", orientationError_); + ROS_DEBUG_THROTTLE(1.0, "positionError: %f ", positionError); + ROS_DEBUG_THROTTLE(1.0, "orientationError: %f ", orientationError); // This is used for publishing as statistics. pointCloudProcessCounter_++; } @@ -263,8 +276,12 @@ void ElevationMappingNode::updatePose(const ros::TimerEvent&) { transformTf.getRotation().w()); lowpassPosition_ = positionAlpha_ * position3 + (1 - positionAlpha_) * lowpassPosition_; lowpassOrientation_ = orientationAlpha_ * orientation + (1 - orientationAlpha_) * lowpassOrientation_; - positionError_ = (position3 - lowpassPosition_).norm(); - orientationError_ = (orientation - lowpassOrientation_).norm(); + { + std::lock_guard lock(errorMutex_); + positionError_ = (position3 - lowpassPosition_).norm(); + orientationError_ = (orientation - lowpassOrientation_).norm(); + } + if (useInitializerAtStart_) { ROS_INFO("Clearing map with initializer."); initializeWithTF(); @@ -272,7 +289,7 @@ void ElevationMappingNode::updatePose(const ros::TimerEvent&) { } } -void ElevationMappingNode::publishAsPointCloud(const grid_map::GridMap& map) { +void ElevationMappingNode::publishAsPointCloud(const grid_map::GridMap& map) const { sensor_msgs::PointCloud2 msg; grid_map::GridMapRosConverter::toPointCloud(map, "elevation", msg); pointPub_.publish(msg); @@ -519,7 +536,7 @@ bool ElevationMappingNode::initializeMap(elevation_map_msgs::Initialize::Request return true; } -void ElevationMappingNode::publishNormalAsArrow(const grid_map::GridMap& map) { +void ElevationMappingNode::publishNormalAsArrow(const grid_map::GridMap& map) const { auto startTime = ros::Time::now(); const auto& normalX = map["normal_x"]; @@ -549,7 +566,7 @@ void ElevationMappingNode::publishNormalAsArrow(const grid_map::GridMap& map) { } visualization_msgs::Marker ElevationMappingNode::vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, - const int id) { + const int id) const { visualization_msgs::Marker marker; marker.header.frame_id = mapFrameId_; marker.header.stamp = ros::Time::now(); @@ -580,13 +597,12 @@ visualization_msgs::Marker ElevationMappingNode::vectorToArrowMarker(const Eigen } void ElevationMappingNode::publishMapToOdom(double error) { - static tf::TransformBroadcaster br; tf::Transform transform; transform.setOrigin(tf::Vector3(0.0, 0.0, error)); tf::Quaternion q; q.setRPY(0, 0, 0); transform.setRotation(q); - br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), mapFrameId_, correctedMapFrameId_)); + tfBroadcaster_.sendTransform(tf::StampedTransform(transform, ros::Time::now(), mapFrameId_, correctedMapFrameId_)); } } // namespace elevation_mapping_cupy From 6864bb04ef8b73e13a2d62a4b87d856c4b0ca792 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 4 May 2022 18:11:26 +0200 Subject: [PATCH 194/504] have tolerance on resolution check --- convex_plane_decomposition/src/GridMapPreprocessing.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/convex_plane_decomposition/src/GridMapPreprocessing.cpp b/convex_plane_decomposition/src/GridMapPreprocessing.cpp index 1dc8c055..48dd31db 100644 --- a/convex_plane_decomposition/src/GridMapPreprocessing.cpp +++ b/convex_plane_decomposition/src/GridMapPreprocessing.cpp @@ -36,7 +36,9 @@ void GridMapPreprocessing::denoise(grid_map::GridMap& gridMap, const std::string } void GridMapPreprocessing::changeResolution(grid_map::GridMap& gridMap, const std::string& layer) const { - if (parameters_.resolution > 0.0 && gridMap.getResolution() != parameters_.resolution) { + bool hasSameResolution = std::abs(gridMap.getResolution() - parameters_.resolution) < 1e-6; + + if (parameters_.resolution > 0.0 && !hasSameResolution) { // Original map info const auto oldPosition = gridMap.getPosition(); const auto oldSize = gridMap.getSize(); From 94379085346f6c7d74c9f654cb6000573ab8992b Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 4 May 2022 19:52:54 +0200 Subject: [PATCH 195/504] Increase initial variance --- elevation_mapping_cupy/config/parameters.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index 0608b970..fccd4509 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -9,7 +9,7 @@ max_drift: 0.1 # drift compensation happens onl drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation time_variance: 0.0001 # add this value when update_variance is called. max_variance: 100.0 # maximum variance for each cell. -initial_variance: 100.0 # initial variance for each cell. +initial_variance: 1000.0 # initial variance for each cell. traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. dilation_size: 3 # dilation filter size before traversability filter. wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. From 3573e969a14c9e43269a9b9b05d1edbae59aa3a3 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 4 May 2022 22:33:21 +0200 Subject: [PATCH 196/504] fix cell indexing --- .../script/custom_kernels.py | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/elevation_mapping_cupy/script/custom_kernels.py b/elevation_mapping_cupy/script/custom_kernels.py index 24c646c5..0d165832 100644 --- a/elevation_mapping_cupy/script/custom_kernels.py +++ b/elevation_mapping_cupy/script/custom_kernels.py @@ -16,9 +16,16 @@ def map_utils(resolution, width, height, sensor_noise_factor, min_valid_distance __device__ float16 round(float16 x) { return (int)x + (int)(2 * (x - (int)x)); } - __device__ int get_xy_idx(float16 x, float16 center) { + __device__ int get_x_idx(float16 x, float16 center) { const float resolution = ${resolution}; - int i = round((x - center) / resolution); + const float width = ${width}; + int i = round((x - center) / resolution + (width - 1.0) / 2); + return i; + } + __device__ int get_y_idx(float16 y, float16 center) { + const float resolution = ${resolution}; + const float height = ${height}; + int i = round((y - center) / resolution + (height - 1.0) / 2); return i; } __device__ bool is_inside(int idx) { @@ -33,8 +40,8 @@ def map_utils(resolution, width, height, sensor_noise_factor, min_valid_distance return true; } __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { - int idx_x = clamp(get_xy_idx(x, center_x) + ${width} / 2, 0, ${width} - 1); - int idx_y = clamp(get_xy_idx(y, center_y) + ${height} / 2, 0, ${height} - 1); + int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); + int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); return ${width} * idx_x + idx_y; } __device__ int get_map_idx(int idx, int layer_n) { @@ -515,14 +522,21 @@ def polygon_mask_kernel(width, height, resolution): __device__ float16 round(float16 x) { return (int)x + (int)(2 * (x - (int)x)); } - __device__ int get_xy_idx(float16 x, float16 center) { + __device__ int get_x_idx(float16 x, float16 center) { + const float resolution = ${resolution}; + const float width = ${width}; + int i = round((x - center) / resolution + width / 2); + return i; + } + __device__ int get_y_idx(float16 y, float16 center) { const float resolution = ${resolution}; - int i = round((x - center) / resolution); + const float height = ${height}; + int i = round((y - center) / resolution + height / 2); return i; } __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { - int idx_x = clamp(get_xy_idx(x, center_x) + ${width} / 2, 0, ${width} - 1); - int idx_y = clamp(get_xy_idx(y, center_y) + ${height} / 2, 0, ${height} - 1); + int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); + int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); return ${width} * idx_x + idx_y; } From 5c1b4dcccf54fc45b61531b5661aa77f59767681 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 5 May 2022 10:32:48 +0200 Subject: [PATCH 197/504] move grid_map_filters to subfolder --- .../grid_map_filters_rsl}/CMakeLists.txt | 0 .../include/grid_map_filters_rsl/GridMapDerivative.hpp | 0 .../include/grid_map_filters_rsl/inpainting.hpp | 0 .../grid_map_filters_rsl}/include/grid_map_filters_rsl/lookup.hpp | 0 .../include/grid_map_filters_rsl/processing.hpp | 0 .../include/grid_map_filters_rsl/smoothing.hpp | 0 .../grid_map_filters_rsl}/package.xml | 0 .../grid_map_filters_rsl}/src/GridMapDerivative.cpp | 0 .../grid_map_filters_rsl}/src/inpainting.cpp | 0 .../grid_map_filters_rsl}/src/lookup.cpp | 0 .../grid_map_filters_rsl}/src/processing.cpp | 0 .../grid_map_filters_rsl}/src/smoothing.cpp | 0 .../grid_map_filters_rsl}/test/TestDerivativeFilter.cpp | 0 .../grid_map_filters_rsl}/test/TestFilters.cpp | 0 .../grid_map_filters_rsl}/test/TestLookup.cpp | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/CMakeLists.txt (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/include/grid_map_filters_rsl/GridMapDerivative.hpp (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/include/grid_map_filters_rsl/inpainting.hpp (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/include/grid_map_filters_rsl/lookup.hpp (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/include/grid_map_filters_rsl/processing.hpp (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/include/grid_map_filters_rsl/smoothing.hpp (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/package.xml (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/src/GridMapDerivative.cpp (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/src/inpainting.cpp (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/src/lookup.cpp (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/src/processing.cpp (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/src/smoothing.cpp (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/test/TestDerivativeFilter.cpp (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/test/TestFilters.cpp (100%) rename {grid_map_filters_rsl => plane_segmentation/grid_map_filters_rsl}/test/TestLookup.cpp (100%) diff --git a/grid_map_filters_rsl/CMakeLists.txt b/plane_segmentation/grid_map_filters_rsl/CMakeLists.txt similarity index 100% rename from grid_map_filters_rsl/CMakeLists.txt rename to plane_segmentation/grid_map_filters_rsl/CMakeLists.txt diff --git a/grid_map_filters_rsl/include/grid_map_filters_rsl/GridMapDerivative.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/GridMapDerivative.hpp similarity index 100% rename from grid_map_filters_rsl/include/grid_map_filters_rsl/GridMapDerivative.hpp rename to plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/GridMapDerivative.hpp diff --git a/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp similarity index 100% rename from grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp rename to plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp diff --git a/grid_map_filters_rsl/include/grid_map_filters_rsl/lookup.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/lookup.hpp similarity index 100% rename from grid_map_filters_rsl/include/grid_map_filters_rsl/lookup.hpp rename to plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/lookup.hpp diff --git a/grid_map_filters_rsl/include/grid_map_filters_rsl/processing.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/processing.hpp similarity index 100% rename from grid_map_filters_rsl/include/grid_map_filters_rsl/processing.hpp rename to plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/processing.hpp diff --git a/grid_map_filters_rsl/include/grid_map_filters_rsl/smoothing.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/smoothing.hpp similarity index 100% rename from grid_map_filters_rsl/include/grid_map_filters_rsl/smoothing.hpp rename to plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/smoothing.hpp diff --git a/grid_map_filters_rsl/package.xml b/plane_segmentation/grid_map_filters_rsl/package.xml similarity index 100% rename from grid_map_filters_rsl/package.xml rename to plane_segmentation/grid_map_filters_rsl/package.xml diff --git a/grid_map_filters_rsl/src/GridMapDerivative.cpp b/plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp similarity index 100% rename from grid_map_filters_rsl/src/GridMapDerivative.cpp rename to plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp diff --git a/grid_map_filters_rsl/src/inpainting.cpp b/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp similarity index 100% rename from grid_map_filters_rsl/src/inpainting.cpp rename to plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp diff --git a/grid_map_filters_rsl/src/lookup.cpp b/plane_segmentation/grid_map_filters_rsl/src/lookup.cpp similarity index 100% rename from grid_map_filters_rsl/src/lookup.cpp rename to plane_segmentation/grid_map_filters_rsl/src/lookup.cpp diff --git a/grid_map_filters_rsl/src/processing.cpp b/plane_segmentation/grid_map_filters_rsl/src/processing.cpp similarity index 100% rename from grid_map_filters_rsl/src/processing.cpp rename to plane_segmentation/grid_map_filters_rsl/src/processing.cpp diff --git a/grid_map_filters_rsl/src/smoothing.cpp b/plane_segmentation/grid_map_filters_rsl/src/smoothing.cpp similarity index 100% rename from grid_map_filters_rsl/src/smoothing.cpp rename to plane_segmentation/grid_map_filters_rsl/src/smoothing.cpp diff --git a/grid_map_filters_rsl/test/TestDerivativeFilter.cpp b/plane_segmentation/grid_map_filters_rsl/test/TestDerivativeFilter.cpp similarity index 100% rename from grid_map_filters_rsl/test/TestDerivativeFilter.cpp rename to plane_segmentation/grid_map_filters_rsl/test/TestDerivativeFilter.cpp diff --git a/grid_map_filters_rsl/test/TestFilters.cpp b/plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp similarity index 100% rename from grid_map_filters_rsl/test/TestFilters.cpp rename to plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp diff --git a/grid_map_filters_rsl/test/TestLookup.cpp b/plane_segmentation/grid_map_filters_rsl/test/TestLookup.cpp similarity index 100% rename from grid_map_filters_rsl/test/TestLookup.cpp rename to plane_segmentation/grid_map_filters_rsl/test/TestLookup.cpp From 89564cfd9efc0a506e363f891865b434905836ca Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 5 May 2022 12:32:58 +0200 Subject: [PATCH 198/504] provide version without rounding, using the floor feature of integer cast --- elevation_mapping_cupy/script/custom_kernels.py | 11 ++++------- .../src/elevation_mapping_wrapper.cpp | 1 + 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/elevation_mapping_cupy/script/custom_kernels.py b/elevation_mapping_cupy/script/custom_kernels.py index 0d165832..149996b5 100644 --- a/elevation_mapping_cupy/script/custom_kernels.py +++ b/elevation_mapping_cupy/script/custom_kernels.py @@ -13,19 +13,16 @@ def map_utils(resolution, width, height, sensor_noise_factor, min_valid_distance return max(min(x, max_x), min_x); } - __device__ float16 round(float16 x) { - return (int)x + (int)(2 * (x - (int)x)); - } __device__ int get_x_idx(float16 x, float16 center) { const float resolution = ${resolution}; const float width = ${width}; - int i = round((x - center) / resolution + (width - 1.0) / 2); + int i = (x - center) / resolution + 0.5 * width; return i; } __device__ int get_y_idx(float16 y, float16 center) { const float resolution = ${resolution}; const float height = ${height}; - int i = round((y - center) / resolution + (height - 1.0) / 2); + int i = (y - center) / resolution + 0.5 * height; return i; } __device__ bool is_inside(int idx) { @@ -525,13 +522,13 @@ def polygon_mask_kernel(width, height, resolution): __device__ int get_x_idx(float16 x, float16 center) { const float resolution = ${resolution}; const float width = ${width}; - int i = round((x - center) / resolution + width / 2); + int i = (x - center) / resolution + 0.5 * width; return i; } __device__ int get_y_idx(float16 y, float16 center) { const float resolution = ${resolution}; const float height = ${height}; - int i = round((y - center) / resolution + height / 2); + int i = (y - center) / resolution + 0.5 * height; return i; } __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 40753a2c..40eb2023 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -77,6 +77,7 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { resolution_ = py::cast(param_.attr("get_value")("resolution")); map_length_ = py::cast(param_.attr("get_value")("map_length")); map_n_ = static_cast(round(map_length_ / resolution_)); + map_length_ = resolution_ * map_n_; // get true length after rounding nh.param("enable_normal", enable_normal_, false); nh.param("enable_normal_color", enable_normal_color_, false); From 7a46fe2b3bd4762102c976a7261e00c0f4e5847c Mon Sep 17 00:00:00 2001 From: Alexander Reimann Date: Thu, 5 May 2022 15:01:52 +0200 Subject: [PATCH 199/504] Specify using python 3 Fixes not working usage of 2.7 under melodic --- elevation_mapping_cupy/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index d93e93a7..88a43627 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.0.2) project(elevation_mapping_cupy) -find_package(PythonInterp REQUIRED) -find_package(PythonLibs REQUIRED) +find_package(PythonInterp 3 REQUIRED) +find_package(PythonLibs 3 REQUIRED) if(PYTHONLIBS_FOUND) message(STATUS "Using Python Libraries at: " ${PYTHON_LIBRARIES}) From ee73d159cf0de301ada61393fe8b497f01d8fffb Mon Sep 17 00:00:00 2001 From: Takahiro Date: Sun, 8 May 2022 18:32:05 +0200 Subject: [PATCH 200/504] Tested in sim. Substitute values instead of creating new variable in the function. --- elevation_mapping_cupy/script/custom_kernels.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/elevation_mapping_cupy/script/custom_kernels.py b/elevation_mapping_cupy/script/custom_kernels.py index 149996b5..c94f6f74 100644 --- a/elevation_mapping_cupy/script/custom_kernels.py +++ b/elevation_mapping_cupy/script/custom_kernels.py @@ -14,15 +14,11 @@ def map_utils(resolution, width, height, sensor_noise_factor, min_valid_distance return max(min(x, max_x), min_x); } __device__ int get_x_idx(float16 x, float16 center) { - const float resolution = ${resolution}; - const float width = ${width}; - int i = (x - center) / resolution + 0.5 * width; + int i = (x - center) / ${resolution} + 0.5 * ${width}; return i; } __device__ int get_y_idx(float16 y, float16 center) { - const float resolution = ${resolution}; - const float height = ${height}; - int i = (y - center) / resolution + 0.5 * height; + int i = (y - center) / ${resolution} + 0.5 * ${height}; return i; } __device__ bool is_inside(int idx) { From d64b8478de74c61629def65527d2a0f8ec8d0f3a Mon Sep 17 00:00:00 2001 From: Takahiro Date: Sun, 8 May 2022 18:54:55 +0200 Subject: [PATCH 201/504] Used formatting tool. --- .../script/custom_kernels.py | 256 ++++++++++++------ .../script/elevation_mapping.py | 256 ++++++++++-------- .../script/map_initializer.py | 28 +- elevation_mapping_cupy/script/parameter.py | 119 ++++---- .../script/plugins/inpainting.py | 18 +- .../script/plugins/min_filter.py | 50 ++-- .../script/plugins/plugin_manager.py | 74 ++--- .../script/plugins/smooth_filter.py | 14 +- .../script/traversability_filter.py | 61 ++--- .../script/traversability_polygon.py | 7 +- 10 files changed, 501 insertions(+), 382 deletions(-) diff --git a/elevation_mapping_cupy/script/custom_kernels.py b/elevation_mapping_cupy/script/custom_kernels.py index c94f6f74..382e4174 100644 --- a/elevation_mapping_cupy/script/custom_kernels.py +++ b/elevation_mapping_cupy/script/custom_kernels.py @@ -6,9 +6,19 @@ import string -def map_utils(resolution, width, height, sensor_noise_factor, min_valid_distance, max_height_range, - ramped_height_range_a, ramped_height_range_b, ramped_height_range_c): - util_preamble = string.Template(''' +def map_utils( + resolution, + width, + height, + sensor_noise_factor, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, +): + util_preamble = string.Template( + """ __device__ float16 clamp(float16 x, float16 min_x, float16 max_x) { return max(min(x, max_x), min_x); @@ -97,32 +107,57 @@ def map_utils(resolution, width, height, sensor_noise_factor, min_valid_distance return product; } - ''').substitute(resolution=resolution, width=width, height=height, - sensor_noise_factor=sensor_noise_factor, - min_valid_distance=min_valid_distance, - max_height_range=max_height_range, - ramped_height_range_a=ramped_height_range_a, - ramped_height_range_b=ramped_height_range_b, - ramped_height_range_c=ramped_height_range_c, - ) + """ + ).substitute( + resolution=resolution, + width=width, + height=height, + sensor_noise_factor=sensor_noise_factor, + min_valid_distance=min_valid_distance, + max_height_range=max_height_range, + ramped_height_range_a=ramped_height_range_a, + ramped_height_range_b=ramped_height_range_b, + ramped_height_range_c=ramped_height_range_c, + ) return util_preamble -def add_points_kernel(resolution, width, height, sensor_noise_factor, - mahalanobis_thresh, outlier_variance, wall_num_thresh, - max_ray_length, cleanup_step, min_valid_distance, - max_height_range, cleanup_cos_thresh, - ramped_height_range_a, ramped_height_range_b, ramped_height_range_c, - enable_edge_shaped=True, enable_visibility_cleanup=True): +def add_points_kernel( + resolution, + width, + height, + sensor_noise_factor, + mahalanobis_thresh, + outlier_variance, + wall_num_thresh, + max_ray_length, + cleanup_step, + min_valid_distance, + max_height_range, + cleanup_cos_thresh, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, + enable_edge_shaped=True, + enable_visibility_cleanup=True, +): add_points_kernel = cp.ElementwiseKernel( - in_params='raw U p, raw U center_x, raw U center_y, raw U R, raw U t, raw U norm_map', - out_params='raw U map, raw T newmap', - preamble=map_utils(resolution, width, height, sensor_noise_factor, min_valid_distance, max_height_range, - ramped_height_range_a, ramped_height_range_b, ramped_height_range_c), - operation=\ - string.Template( - ''' + in_params="raw U p, raw U center_x, raw U center_y, raw U R, raw U t, raw U norm_map", + out_params="raw U map, raw T newmap", + preamble=map_utils( + resolution, + width, + height, + sensor_noise_factor, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, + ), + operation=string.Template( + """ U rx = p[i * 3]; U ry = p[i * 3 + 1]; U rz = p[i * 3 + 2]; @@ -223,33 +258,54 @@ def add_points_kernel(resolution, width, height, sensor_noise_factor, } } } - ''').substitute(mahalanobis_thresh=mahalanobis_thresh, - outlier_variance=outlier_variance, - wall_num_thresh=wall_num_thresh, - ray_step=resolution / 2**0.5, - max_ray_length=max_ray_length, - cleanup_step=cleanup_step, - cleanup_cos_thresh=cleanup_cos_thresh, - enable_edge_shaped=int(enable_edge_shaped), - enable_visibility_cleanup=int(enable_visibility_cleanup)), - name='add_points_kernel') + """ + ).substitute( + mahalanobis_thresh=mahalanobis_thresh, + outlier_variance=outlier_variance, + wall_num_thresh=wall_num_thresh, + ray_step=resolution / 2**0.5, + max_ray_length=max_ray_length, + cleanup_step=cleanup_step, + cleanup_cos_thresh=cleanup_cos_thresh, + enable_edge_shaped=int(enable_edge_shaped), + enable_visibility_cleanup=int(enable_visibility_cleanup), + ), + name="add_points_kernel", + ) return add_points_kernel -def error_counting_kernel(resolution, width, height, sensor_noise_factor, - mahalanobis_thresh, outlier_variance, - traversability_inlier, min_valid_distance, max_height_range, - ramped_height_range_a, ramped_height_range_b, ramped_height_range_c, - ): +def error_counting_kernel( + resolution, + width, + height, + sensor_noise_factor, + mahalanobis_thresh, + outlier_variance, + traversability_inlier, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, +): error_counting_kernel = cp.ElementwiseKernel( - in_params='raw U map, raw U p, raw U center_x, raw U center_y, raw U R, raw U t', - out_params='raw U newmap, raw T error, raw T error_cnt', - preamble=map_utils(resolution, width, height, sensor_noise_factor, min_valid_distance, max_height_range, - ramped_height_range_a, ramped_height_range_b, ramped_height_range_c), - operation=\ - string.Template( - ''' + in_params="raw U map, raw U p, raw U center_x, raw U center_y, raw U R, raw U t", + out_params="raw U newmap, raw T error, raw T error_cnt", + preamble=map_utils( + resolution, + width, + height, + sensor_noise_factor, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, + ), + operation=string.Template( + """ U rx = p[i * 3]; U ry = p[i * 3 + 1]; U rz = p[i * 3 + 2]; @@ -277,26 +333,31 @@ def error_counting_kernel(resolution, width, height, sensor_noise_factor, atomicAdd(&newmap[get_map_idx(idx, 3)], 1.0); } atomicAdd(&newmap[get_map_idx(idx, 4)], 1.0); - ''').substitute(mahalanobis_thresh=mahalanobis_thresh, - outlier_variance=outlier_variance, - traversability_inlier=traversability_inlier), - name='error_counting_kernel') + """ + ).substitute( + mahalanobis_thresh=mahalanobis_thresh, + outlier_variance=outlier_variance, + traversability_inlier=traversability_inlier, + ), + name="error_counting_kernel", + ) return error_counting_kernel def average_map_kernel(width, height, max_variance, initial_variance): average_map_kernel = cp.ElementwiseKernel( - in_params='raw U newmap', - out_params='raw U map', - preamble=\ - string.Template(''' + in_params="raw U newmap", + out_params="raw U map", + preamble=string.Template( + """ __device__ int get_map_idx(int idx, int layer_n) { const int layer = ${width} * ${height}; return layer * layer_n + idx; } - ''').substitute(width=width, height=height), - operation=\ - string.Template(''' + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ U h = map[get_map_idx(i, 0)]; U v = map[get_map_idx(i, 1)]; U valid = map[get_map_idx(i, 2)]; @@ -320,18 +381,19 @@ def average_map_kernel(width, height, max_variance, initial_variance): map[get_map_idx(i, 1)] = ${initial_variance}; map[get_map_idx(i, 2)] = 0; } - ''').substitute(max_variance=max_variance, - initial_variance=initial_variance), - name='average_map_kernel') + """ + ).substitute(max_variance=max_variance, initial_variance=initial_variance), + name="average_map_kernel", + ) return average_map_kernel def dilation_filter_kernel(width, height, dilation_size): dilation_filter_kernel = cp.ElementwiseKernel( - in_params='raw U map, raw U mask', - out_params='raw U newmap, raw U newmask', - preamble=\ - string.Template(''' + in_params="raw U map, raw U mask", + out_params="raw U newmap, raw U newmask", + preamble=string.Template( + """ __device__ int get_map_idx(int idx, int layer_n) { const int layer = ${width} * ${height}; return layer * layer_n + idx; @@ -353,9 +415,10 @@ def dilation_filter_kernel(width, height, dilation_size): } return true; } - ''').substitute(width=width, height=height), - operation=\ - string.Template(''' + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ U h = map[get_map_idx(i, 0)]; U valid = mask[get_map_idx(i, 0)]; newmap[get_map_idx(i, 0)] = h; @@ -378,17 +441,19 @@ def dilation_filter_kernel(width, height, dilation_size): newmask[get_map_idx(i, 0)] = 1.0; } } - ''').substitute(dilation_size=dilation_size), - name='dilation_filter_kernel') + """ + ).substitute(dilation_size=dilation_size), + name="dilation_filter_kernel", + ) return dilation_filter_kernel def normal_filter_kernel(width, height, resolution): normal_filter_kernel = cp.ElementwiseKernel( - in_params='raw U map, raw U mask', - out_params='raw U newmap', - preamble=\ - string.Template(''' + in_params="raw U map, raw U mask", + out_params="raw U newmap", + preamble=string.Template( + """ __device__ int get_map_idx(int idx, int layer_n) { const int layer = ${width} * ${height}; return layer * layer_n + idx; @@ -413,9 +478,10 @@ def normal_filter_kernel(width, height, resolution): __device__ float resolution() { return ${resolution}; } - ''').substitute(width=width, height=height, resolution=resolution), - operation=\ - string.Template(''' + """ + ).substitute(width=width, height=height, resolution=resolution), + operation=string.Template( + """ U h = map[get_map_idx(i, 0)]; U valid = mask[get_map_idx(i, 0)]; if (valid > 0.5) { @@ -432,17 +498,19 @@ def normal_filter_kernel(width, height, resolution): newmap[get_map_idx(i, 1)] = ny / norm; newmap[get_map_idx(i, 2)] = nz / norm; } - ''').substitute(), - name='normal_filter_kernel') + """ + ).substitute(), + name="normal_filter_kernel", + ) return normal_filter_kernel def polygon_mask_kernel(width, height, resolution): polygon_mask_kernel = cp.ElementwiseKernel( - in_params='raw U polygon, raw U center_x, raw U center_y, raw int16 polygon_n, raw U polygon_bbox', - out_params='raw U mask', - preamble=\ - string.Template(''' + in_params="raw U polygon, raw U center_x, raw U center_y, raw int16 polygon_n, raw U polygon_bbox", + out_params="raw U mask", + preamble=string.Template( + """ __device__ struct Point { int x; @@ -533,9 +601,10 @@ def polygon_mask_kernel(width, height, resolution): return ${width} * idx_x + idx_y; } - ''').substitute(width=width, height=height, resolution=resolution), - operation=\ - string.Template(''' + """ + ).substitute(width=width, height=height, resolution=resolution), + operation=string.Template( + """ // Point p = {get_idx_x(i, center_x[0]), get_idx_y(i, center_y[0])}; Point p = {get_idx_x(i), get_idx_y(i)}; Point extreme = {100000, p.y}; @@ -577,19 +646,24 @@ def polygon_mask_kernel(width, height, resolution): if (intersect_cnt % 2 == 0) { mask[i] = 0; } else { mask[i] = 1; } } - ''').substitute(a=1), - name='polygon_mask_kernel') + """ + ).substitute(a=1), + name="polygon_mask_kernel", + ) return polygon_mask_kernel -if __name__ == '__main__': +if __name__ == "__main__": for i in range(10): import random + a = cp.zeros((100, 100)) n = random.randint(3, 5) # polygon = cp.array([[-1, -1], [3, 4], [2, 4], [1, 3]], dtype=float) - polygon = cp.array([[(random.random() - 0.5) * 10, (random.random() - 0.5) * 10] for i in range(n)], dtype=float) + polygon = cp.array( + [[(random.random() - 0.5) * 10, (random.random() - 0.5) * 10] for i in range(n)], dtype=float + ) print(polygon) polygon_min = polygon.min(axis=0) polygon_max = polygon.max(axis=0) @@ -599,10 +673,12 @@ def polygon_mask_kernel(width, height, resolution): # polygon_bbox = cp.array([-5, -5, 5, 5], dtype=float) polygon_mask = polygon_mask_kernel(100, 100, 0.1) import time + start = time.time() - polygon_mask(polygon, 0.0, 0.0, polygon_n, polygon_bbox, a, size=(100*100)) + polygon_mask(polygon, 0.0, 0.0, polygon_n, polygon_bbox, a, size=(100 * 100)) print(time.time() - start) import pylab as plt + print(a) plt.imshow(cp.asnumpy(a)) plt.show() diff --git a/elevation_mapping_cupy/script/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping.py index 6e77fa2c..09734ebd 100644 --- a/elevation_mapping_cupy/script/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping.py @@ -18,7 +18,13 @@ from map_initializer import MapInitializer from plugins.plugin_manager import PluginManger -from traversability_polygon import get_masked_traversability, is_traversable, calculate_area, transform_to_map_position, transform_to_map_index +from traversability_polygon import ( + get_masked_traversability, + is_traversable, + calculate_area, + transform_to_map_position, + transform_to_map_index, +) import cupy as cp import cupyx.scipy as csp @@ -31,9 +37,10 @@ class ElevationMap(object): - """ + """ Core elevation mapping class. """ + def __init__(self, param: Parameter): self.param = param @@ -47,7 +54,15 @@ def __init__(self, param: Parameter): # layers: elevation, variance, is_valid, traversability, time, upper_bound, is_upper_bound self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n)) - self.layer_names = ["elevation", "variance", "is_valid", "traversability", "time", "upper_bound", "is_upper_bound"] + self.layer_names = [ + "elevation", + "variance", + "is_valid", + "traversability", + "time", + "upper_bound", + "is_upper_bound", + ] # buffers self.traversability_buffer = xp.full((self.cell_n, self.cell_n), xp.nan) self.normal_map = xp.zeros((3, self.cell_n, self.cell_n)) @@ -68,7 +83,7 @@ def __init__(self, param: Parameter): self.compile_kernels() - weight_file = subprocess.getoutput("echo \"" + param.weight_file + "\"") + weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') param.load_weights(weight_file) if param.use_chainer: @@ -79,11 +94,10 @@ def __init__(self, param: Parameter): # Plugins self.plugin_manager = PluginManger(cell_n=self.cell_n) - plugin_config_file = subprocess.getoutput("echo \"" + param.plugin_config_file + "\"") + plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') self.plugin_manager.load_plugin_settings(plugin_config_file) - self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, - xp=cp, method='points') + self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") def clear(self): with self.map_lock: @@ -122,20 +136,15 @@ def shift_map_xy(self, delta_pixel): shift_fn = sp.ndimage.interpolation.shift with self.map_lock: # elevation - self.elevation_map[0] = shift_fn(self.elevation_map[0], shift_value, - cval=0.0) + self.elevation_map[0] = shift_fn(self.elevation_map[0], shift_value, cval=0.0) # variance - self.elevation_map[1] = shift_fn(self.elevation_map[1], shift_value, - cval=self.initial_variance) + self.elevation_map[1] = shift_fn(self.elevation_map[1], shift_value, cval=self.initial_variance) # is valid (1 is valid 0 is not valid) - self.elevation_map[2] = shift_fn(self.elevation_map[2], shift_value, - cval=0) + self.elevation_map[2] = shift_fn(self.elevation_map[2], shift_value, cval=0) # upper bound - self.elevation_map[5] = shift_fn(self.elevation_map[5], shift_value, - cval=0) + self.elevation_map[5] = shift_fn(self.elevation_map[5], shift_value, cval=0) # is upper bound - self.elevation_map[6] = shift_fn(self.elevation_map[6], shift_value, - cval=0) + self.elevation_map[6] = shift_fn(self.elevation_map[6], shift_value, cval=0) def shift_map_z(self, delta_z): with self.map_lock: @@ -152,41 +161,47 @@ def compile_kernels(self): self.min_filtered = cp.zeros((self.cell_n, self.cell_n)) self.min_filtered_mask = cp.zeros((self.cell_n, self.cell_n)) self.mask = cp.zeros((self.cell_n, self.cell_n)) - self.add_points_kernel = add_points_kernel(self.resolution, - self.cell_n, - self.cell_n, - self.param.sensor_noise_factor, - self.param.mahalanobis_thresh, - self.param.outlier_variance, - self.param.wall_num_thresh, - self.param.max_ray_length, - self.param.cleanup_step, - self.param.min_valid_distance, - self.param.max_height_range, - self.param.cleanup_cos_thresh, - self.param.ramped_height_range_a, - self.param.ramped_height_range_b, - self.param.ramped_height_range_c, - self.param.enable_edge_sharpen, - self.param.enable_visibility_cleanup) - self.error_counting_kernel = error_counting_kernel(self.resolution, - self.cell_n, - self.cell_n, - self.param.sensor_noise_factor, - self.param.mahalanobis_thresh, - self.param.drift_compensation_variance_inlier, - self.param.traversability_inlier, - self.param.min_valid_distance, - self.param.max_height_range, - self.param.ramped_height_range_a, - self.param.ramped_height_range_b, - self.param.ramped_height_range_c, - ) - self.average_map_kernel = average_map_kernel(self.cell_n, self.cell_n, - self.param.max_variance, self.initial_variance) + self.add_points_kernel = add_points_kernel( + self.resolution, + self.cell_n, + self.cell_n, + self.param.sensor_noise_factor, + self.param.mahalanobis_thresh, + self.param.outlier_variance, + self.param.wall_num_thresh, + self.param.max_ray_length, + self.param.cleanup_step, + self.param.min_valid_distance, + self.param.max_height_range, + self.param.cleanup_cos_thresh, + self.param.ramped_height_range_a, + self.param.ramped_height_range_b, + self.param.ramped_height_range_c, + self.param.enable_edge_sharpen, + self.param.enable_visibility_cleanup, + ) + self.error_counting_kernel = error_counting_kernel( + self.resolution, + self.cell_n, + self.cell_n, + self.param.sensor_noise_factor, + self.param.mahalanobis_thresh, + self.param.drift_compensation_variance_inlier, + self.param.traversability_inlier, + self.param.min_valid_distance, + self.param.max_height_range, + self.param.ramped_height_range_a, + self.param.ramped_height_range_b, + self.param.ramped_height_range_c, + ) + self.average_map_kernel = average_map_kernel( + self.cell_n, self.cell_n, self.param.max_variance, self.initial_variance + ) self.dilation_filter_kernel = dilation_filter_kernel(self.cell_n, self.cell_n, self.param.dilation_size) - self.dilation_filter_kernel_initializer = dilation_filter_kernel(self.cell_n, self.cell_n, self.param.dilation_size_initialize) + self.dilation_filter_kernel_initializer = dilation_filter_kernel( + self.cell_n, self.cell_n, self.param.dilation_size_initialize + ) self.polygon_mask_kernel = polygon_mask_kernel(self.cell_n, self.cell_n, self.resolution) self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) @@ -199,37 +214,60 @@ def update_map_with_kernel(self, points, R, t, position_noise, orientation_noise error_cnt = cp.array([0], dtype=cp.float32) with self.map_lock: self.shift_translation_to_map_center(t) - self.error_counting_kernel(self.elevation_map, points, - cp.array([0.]), cp.array([0.]), R, t, - self.new_map, error, error_cnt, - size=(points.shape[0])) - if (self.param.enable_drift_compensation - and error_cnt > self.param.min_height_drift_cnt - and (position_noise > self.param.position_noise_thresh - or orientation_noise > self.param.orientation_noise_thresh)): + self.error_counting_kernel( + self.elevation_map, + points, + cp.array([0.0]), + cp.array([0.0]), + R, + t, + self.new_map, + error, + error_cnt, + size=(points.shape[0]), + ) + if ( + self.param.enable_drift_compensation + and error_cnt > self.param.min_height_drift_cnt + and ( + position_noise > self.param.position_noise_thresh + or orientation_noise > self.param.orientation_noise_thresh + ) + ): self.mean_error = error / error_cnt self.additive_mean_error += self.mean_error if np.abs(self.mean_error) < self.param.max_drift: self.elevation_map[0] += self.mean_error * self.param.drift_compensation_alpha - self.add_points_kernel(points, cp.array([0.]), cp.array([0.]), R, t, self.normal_map, - self.elevation_map, self.new_map, - size=(points.shape[0])) - self.average_map_kernel(self.new_map, self.elevation_map, - size=(self.cell_n * self.cell_n)) + self.add_points_kernel( + points, + cp.array([0.0]), + cp.array([0.0]), + R, + t, + self.normal_map, + self.elevation_map, + self.new_map, + size=(points.shape[0]), + ) + self.average_map_kernel(self.new_map, self.elevation_map, size=(self.cell_n * self.cell_n)) if self.param.enable_overlap_clearance: self.clear_overlap_map(t) # dilation before traversability_filter self.traversability_input *= 0.0 - self.dilation_filter_kernel(self.elevation_map[5], - self.elevation_map[2]+self.elevation_map[6], - self.traversability_input, - self.traversability_mask_dummy, - size=(self.cell_n * self.cell_n)) + self.dilation_filter_kernel( + self.elevation_map[5], + self.elevation_map[2] + self.elevation_map[6], + self.traversability_input, + self.traversability_mask_dummy, + size=(self.cell_n * self.cell_n), + ) # calculate traversability traversability = self.traversability_filter(self.traversability_input) - self.elevation_map[3][3:-3, 3:-3] = traversability.reshape((traversability.shape[2], traversability.shape[3])) + self.elevation_map[3][3:-3, 3:-3] = traversability.reshape( + (traversability.shape[2], traversability.shape[3]) + ) # calculate normal vectors self.update_normal(self.traversability_input) @@ -238,7 +276,7 @@ def clear_overlap_map(self, t): # Clear overlapping area around center height_min = t[2] - self.param.overlap_clear_range_z height_max = t[2] + self.param.overlap_clear_range_z - near_map = self.elevation_map[:, self.cell_min:self.cell_max, self.cell_min:self.cell_max] + near_map = self.elevation_map[:, self.cell_min : self.cell_max, self.cell_min : self.cell_max] valid_idx = ~cp.logical_or(near_map[0] < height_min, near_map[0] > height_max) near_map[0] = cp.where(valid_idx, near_map[0], 0.0) near_map[1] = cp.where(valid_idx, near_map[1], self.initial_variance) @@ -246,7 +284,7 @@ def clear_overlap_map(self, t): valid_idx = ~cp.logical_or(near_map[5] < height_min, near_map[5] > height_max) near_map[5] = cp.where(valid_idx, near_map[5], 0.0) near_map[6] = cp.where(valid_idx, near_map[6], 0.0) - self.elevation_map[:, self.cell_min:self.cell_max, self.cell_min:self.cell_max] = near_map + self.elevation_map[:, self.cell_min : self.cell_max, self.cell_min : self.cell_max] = near_map def get_additive_mean_error(self): return self.additive_mean_error @@ -271,13 +309,14 @@ def input(self, raw_points, R, t, position_noise, orientation_noise): def update_normal(self, dilated_map): with self.map_lock: self.normal_map *= 0.0 - self.normal_filter_kernel(dilated_map, self.elevation_map[2], self.normal_map, size=(self.cell_n * self.cell_n)) + self.normal_filter_kernel( + dilated_map, self.elevation_map[2], self.normal_map, size=(self.cell_n * self.cell_n) + ) def process_map_for_publish(self, input_map, fill_nan=False, add_z=False, xp=cp): m = input_map.copy() if fill_nan: - m = xp.where(self.elevation_map[2] > 0.5, - m, xp.nan) + m = xp.where(self.elevation_map[2] > 0.5, m, xp.nan) if add_z: m = m + self.center[2] return m[1:-1, 1:-1] @@ -289,9 +328,10 @@ def get_variance(self): return self.process_map_for_publish(self.elevation_map[1], fill_nan=False, add_z=False) def get_traversability(self): - traversability = cp.where((self.elevation_map[2] + self.elevation_map[6]) > 0.5, - self.elevation_map[3].copy(), cp.nan) - self.traversability_buffer[3:-3, 3: -3] = traversability[3:-3, 3:-3] + traversability = cp.where( + (self.elevation_map[2] + self.elevation_map[6]) > 0.5, self.elevation_map[3].copy(), cp.nan + ) + self.traversability_buffer[3:-3, 3:-3] = traversability[3:-3, 3:-3] traversability = self.traversability_buffer[1:-1, 1:-1] return traversability @@ -300,7 +340,9 @@ def get_time(self): def get_upper_bound(self): if self.param.use_only_above_for_upper_bound: - valid = cp.logical_or(cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), self.elevation_map[2] > 0.5) + valid = cp.logical_or( + cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), self.elevation_map[2] > 0.5 + ) else: valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) upper_bound = cp.where(valid, self.elevation_map[5].copy(), cp.nan) @@ -309,7 +351,9 @@ def get_upper_bound(self): def get_is_upper_bound(self): if self.param.use_only_above_for_upper_bound: - valid = cp.logical_or(cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), self.elevation_map[2] > 0.5) + valid = cp.logical_or( + cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), self.elevation_map[2] > 0.5 + ) else: valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) is_upper_bound = cp.where(valid, self.elevation_map[6].copy(), cp.nan) @@ -409,29 +453,30 @@ def get_polygon_traversability(self, polygon, result): polygon_bbox = cp.concatenate([polygon_min, polygon_max]).flatten() polygon_n = polygon.shape[0] clipped_area = calculate_area(polygon) - self.polygon_mask_kernel(polygon, self.center[0], self.center[1], - polygon_n, polygon_bbox, self.mask, - size=(self.cell_n * self.cell_n)) - masked, masked_isvalid = get_masked_traversability(self.elevation_map, - self.mask) + self.polygon_mask_kernel( + polygon, + self.center[0], + self.center[1], + polygon_n, + polygon_bbox, + self.mask, + size=(self.cell_n * self.cell_n), + ) + masked, masked_isvalid = get_masked_traversability(self.elevation_map, self.mask) if masked_isvalid.sum() > 0: t = masked.sum() / masked_isvalid.sum() else: t = 0.0 - is_safe, un_polygon = is_traversable(masked, - self.param.safe_thresh, - self.param.safe_min_thresh, - self.param.max_unsafe_n) + is_safe, un_polygon = is_traversable( + masked, self.param.safe_thresh, self.param.safe_min_thresh, self.param.max_unsafe_n + ) untraversable_polygon_num = 0 if un_polygon is not None: - un_polygon = transform_to_map_position(un_polygon, - self.center[:2], - self.cell_n, - self.resolution) + un_polygon = transform_to_map_position(un_polygon, self.center[:2], self.cell_n, self.resolution) untraversable_polygon_num = un_polygon.shape[0] if clipped_area < 0.001: is_safe = False - print('requested polygon is outside of the map') + print("requested polygon is outside of the map") result[...] = np.array([is_safe, t, area]) self.untraversable_polygon = un_polygon return untraversable_polygon_num @@ -439,28 +484,27 @@ def get_polygon_traversability(self, polygon, result): def get_untraversable_polygon(self, untraversable_polygon): untraversable_polygon[...] = xp.asnumpy(self.untraversable_polygon) - def initialize_map(self, points, method='cubic'): + def initialize_map(self, points, method="cubic"): self.clear() with self.map_lock: points = cp.asarray(points) - indices = transform_to_map_index(points[:, :2], - self.center[:2], - self.cell_n, - self.resolution) + indices = transform_to_map_index(points[:, :2], self.center[:2], self.cell_n, self.resolution) points[:, :2] = indices.astype(points.dtype) points[:, 2] -= self.center[2] self.map_initializer(self.elevation_map, points, method) if self.param.dilation_size_initialize > 0: for i in range(2): - self.dilation_filter_kernel_initializer(self.elevation_map[0], - self.elevation_map[2], - self.elevation_map[0], - self.elevation_map[2], - size=(self.cell_n * self.cell_n)) + self.dilation_filter_kernel_initializer( + self.elevation_map[0], + self.elevation_map[2], + self.elevation_map[0], + self.elevation_map[2], + size=(self.cell_n * self.cell_n), + ) self.update_upper_bound_with_valid_elevation() -if __name__ == '__main__': +if __name__ == "__main__": # Test script for profiling. # $ python -m cProfile -o profile.stats elevation_mapping.py # $ snakeviz profile.stats @@ -470,9 +514,9 @@ def initialize_map(self, points, method='cubic'): t = xp.random.rand(3) print(R, t) param = Parameter(use_chainer=False) - param.load_weights('../config/weights.dat') + param.load_weights("../config/weights.dat") elevation = ElevationMap(param) - layers = ['elevation', 'variance', 'traversability', 'min_filter', 'smooth', 'inpaint'] + layers = ["elevation", "variance", "traversability", "min_filter", "smooth", "inpaint"] data = np.zeros((elevation.cell_n - 2, elevation.cell_n - 2), dtype=np.float32) for i in range(500): elevation.input(points, R, t, 0, 0) diff --git a/elevation_mapping_cupy/script/map_initializer.py b/elevation_mapping_cupy/script/map_initializer.py index a7f3aa4d..c80dc587 100644 --- a/elevation_mapping_cupy/script/map_initializer.py +++ b/elevation_mapping_cupy/script/map_initializer.py @@ -8,7 +8,7 @@ class MapInitializer(object): - def __init__(self, initial_variance, new_variance, xp=np, method='points'): + def __init__(self, initial_variance, new_variance, xp=np, method="points"): self.methods = ["points"] assert method in self.methods, "method should be chosen from {}".format(self.methods) self.method = method @@ -17,12 +17,12 @@ def __init__(self, initial_variance, new_variance, xp=np, method='points'): self.new_variance = new_variance def __call__(self, *args, **kwargs): - if self.method == 'points': + if self.method == "points": self.points_initializer(*args, **kwargs) else: return - def points_initializer(self, elevation_map, points, method='linear'): + def points_initializer(self, elevation_map, points, method="linear"): """ Initialize the map using interpolation between given poitns Args: @@ -52,20 +52,18 @@ def points_initializer(self, elevation_map, points, method='linear'): interpolated = griddata(points_idx, values, (grid_x, grid_y), method=method) if self.xp == cp: interpolated = cp.asarray(interpolated) - + # Update elevation map. elevation_map[0] = self.xp.nan_to_num(interpolated) - elevation_map[1] = self.xp.where(self.xp.invert(self.xp.isnan(interpolated)), - self.new_variance, - self.initial_variance) - elevation_map[2] = self.xp.where(self.xp.invert(self.xp.isnan(interpolated)), - 1.0, - 0.0) + elevation_map[1] = self.xp.where( + self.xp.invert(self.xp.isnan(interpolated)), self.new_variance, self.initial_variance + ) + elevation_map[2] = self.xp.where(self.xp.invert(self.xp.isnan(interpolated)), 1.0, 0.0) return if __name__ == "__main__": - initializer = MapInitializer(100, 10, method='points', xp=cp) + initializer = MapInitializer(100, 10, method="points", xp=cp) m = np.zeros((4, 10, 10)) m[0, 0:5, 2:5] = 0.3 m[2, 0:5, 2:5] = 1.0 @@ -73,12 +71,10 @@ def points_initializer(self, elevation_map, points, method='linear'): print(m[0]) print(m[1]) print(m[2]) - points = cp.array([[0, 0, 0.2], - [8, 0, 0.2], - [6, 9, 0.2]]) - # [3, 3, 0.2]]) + points = cp.array([[0, 0, 0.2], [8, 0, 0.2], [6, 9, 0.2]]) + # [3, 3, 0.2]]) m = cp.asarray(m) - initializer(m, points, method='cubic') + initializer(m, points, method="cubic") print(m[0]) print(m[1]) print(m[2]) diff --git a/elevation_mapping_cupy/script/parameter.py b/elevation_mapping_cupy/script/parameter.py index 0d7e918f..0e79622a 100644 --- a/elevation_mapping_cupy/script/parameter.py +++ b/elevation_mapping_cupy/script/parameter.py @@ -7,74 +7,75 @@ import numpy as np import os + @dataclass class Parameter: resolution: float = 0.02 - map_length:float = 10.0 - sensor_noise_factor:float = 0.05 - mahalanobis_thresh:float = 2.0 - outlier_variance:float = 0.01 - drift_compensation_variance_inlier:float = 0.1 - time_variance:float = 0.01 - time_interval:float = 0.1 - - max_variance:float = 1.0 - dilation_size:float = 2 - dilation_size_initialize:float = 10 - drift_compensation_alpha:float = 1.0 - - traversability_inlier:float = 0.1 - wall_num_thresh:float = 100 - min_height_drift_cnt:float = 100 - - max_ray_length:float = 2.0 - cleanup_step:float = 0.01 - cleanup_cos_thresh:float = 0.5 - min_valid_distance:float = 0.3 - max_height_range:float = 1.0 - ramped_height_range_a:float = 0.3 - ramped_height_range_b:float = 1.0 - ramped_height_range_c:float = 0.2 - - safe_thresh:float = 0.5 - safe_min_thresh:float = 0.5 - max_unsafe_n:int = 20 - - min_filter_size:int = 5 - min_filter_iteration:int = 3 - - max_drift:float = 0.10 - - overlap_clear_range_xy:float = 4.0 - overlap_clear_range_z:float = 2.0 - - enable_edge_sharpen:bool = True - enable_drift_compensation:bool = True - enable_visibility_cleanup:bool = True - enable_overlap_clearance:bool = True + map_length: float = 10.0 + sensor_noise_factor: float = 0.05 + mahalanobis_thresh: float = 2.0 + outlier_variance: float = 0.01 + drift_compensation_variance_inlier: float = 0.1 + time_variance: float = 0.01 + time_interval: float = 0.1 + + max_variance: float = 1.0 + dilation_size: float = 2 + dilation_size_initialize: float = 10 + drift_compensation_alpha: float = 1.0 + + traversability_inlier: float = 0.1 + wall_num_thresh: float = 100 + min_height_drift_cnt: float = 100 + + max_ray_length: float = 2.0 + cleanup_step: float = 0.01 + cleanup_cos_thresh: float = 0.5 + min_valid_distance: float = 0.3 + max_height_range: float = 1.0 + ramped_height_range_a: float = 0.3 + ramped_height_range_b: float = 1.0 + ramped_height_range_c: float = 0.2 + + safe_thresh: float = 0.5 + safe_min_thresh: float = 0.5 + max_unsafe_n: int = 20 + + min_filter_size: int = 5 + min_filter_iteration: int = 3 + + max_drift: float = 0.10 + + overlap_clear_range_xy: float = 4.0 + overlap_clear_range_z: float = 2.0 + + enable_edge_sharpen: bool = True + enable_drift_compensation: bool = True + enable_visibility_cleanup: bool = True + enable_overlap_clearance: bool = True use_only_above_for_upper_bound: bool = True - use_chainer:bool = True - position_noise_thresh:float = 0.1 - orientation_noise_thresh:float = 0.1 + use_chainer: bool = True + position_noise_thresh: float = 0.1 + orientation_noise_thresh: float = 0.1 plugin_config_file: str = "config/plugin_config.yaml" weight_file: str = "config/weights.dat" - initial_variance:float = 10.0 - initialized_variance:float = 10.0 - w1:np.ndarray = np.zeros((4, 1, 3, 3)) - w2:np.ndarray = np.zeros((4, 1, 3, 3)) - w3:np.ndarray = np.zeros((4, 1, 3, 3)) - w_out:np.ndarray = np.zeros((1, 12, 1, 1)) + initial_variance: float = 10.0 + initialized_variance: float = 10.0 + w1: np.ndarray = np.zeros((4, 1, 3, 3)) + w2: np.ndarray = np.zeros((4, 1, 3, 3)) + w3: np.ndarray = np.zeros((4, 1, 3, 3)) + w_out: np.ndarray = np.zeros((1, 12, 1, 1)) def load_weights(self, filename): - with open(filename,'rb') as file: + with open(filename, "rb") as file: weights = pickle.load(file) - self.w1 = weights['conv1.weight'] - self.w2 = weights['conv2.weight'] - self.w3 = weights['conv3.weight'] - self.w_out = weights['conv_final.weight'] + self.w1 = weights["conv1.weight"] + self.w2 = weights["conv2.weight"] + self.w3 = weights["conv3.weight"] + self.w_out = weights["conv_final.weight"] def get_names(self): return list(self.__annotations__.keys()) @@ -93,8 +94,8 @@ def get_value(self, name): param = Parameter() print(param) print(param.resolution) - param.set_value('resolution', 0.1) + param.set_value("resolution", 0.1) print(param.resolution) - print('names ', param.get_names()) - print('types ', param.get_types()) + print("names ", param.get_names()) + print("types ", param.get_types()) diff --git a/elevation_mapping_cupy/script/plugins/inpainting.py b/elevation_mapping_cupy/script/plugins/inpainting.py index ff8c0cda..8c1ac90a 100644 --- a/elevation_mapping_cupy/script/plugins/inpainting.py +++ b/elevation_mapping_cupy/script/plugins/inpainting.py @@ -13,7 +13,7 @@ class Inpainting(PluginBase): - """ This is a filter to smoothen + """This is a filter to smoothen ... @@ -22,7 +22,8 @@ class Inpainting(PluginBase): cell_n: int width and height of the elevation map. """ - def __init__(self, cell_n:int=100, method:str="telea", **kwargs): + + def __init__(self, cell_n: int = 100, method: str = "telea", **kwargs): super().__init__() if method == "telea": self.method = cv.INPAINT_TELEA @@ -31,14 +32,19 @@ def __init__(self, cell_n:int=100, method:str="telea", **kwargs): else: # default method self.method = cv.INPAINT_TELEA - def __call__(self, elevation_map: cp.ndarray, layer_names: List[str], - plugin_layers: cp.ndarray, plugin_layer_names: List[str])->cp.ndarray: - mask = cp.asnumpy((elevation_map[2] < 0.5).astype('uint8')) + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + ) -> cp.ndarray: + mask = cp.asnumpy((elevation_map[2] < 0.5).astype("uint8")) if (mask < 1).any(): h = elevation_map[0] h_max = float(h[mask < 1].max()) h_min = float(h[mask < 1].min()) - h = cp.asnumpy((elevation_map[0] - h_min) * 255 / (h_max - h_min)).astype('uint8') + h = cp.asnumpy((elevation_map[0] - h_min) * 255 / (h_max - h_min)).astype("uint8") dst = np.array(cv.inpaint(h, mask, 1, self.method)) h_inpainted = dst.astype(np.float32) * (h_max - h_min) / 255 + h_min return cp.asarray(h_inpainted).astype(np.float64) diff --git a/elevation_mapping_cupy/script/plugins/min_filter.py b/elevation_mapping_cupy/script/plugins/min_filter.py index 331b61fc..90eeafc1 100644 --- a/elevation_mapping_cupy/script/plugins/min_filter.py +++ b/elevation_mapping_cupy/script/plugins/min_filter.py @@ -10,7 +10,7 @@ class MinFilter(PluginBase): - """ This is a filter to fill in invalid cells with minimum values around. + """This is a filter to fill in invalid cells with minimum values around. ... @@ -25,7 +25,8 @@ class MinFilter(PluginBase): iteration_n: int The number of iteration to repeat the same filter. """ - def __init__(self, cell_n:int=100, dilation_size:int=5, iteration_n:int=5, **kwargs): + + def __init__(self, cell_n: int = 100, dilation_size: int = 5, iteration_n: int = 5, **kwargs): super().__init__() self.iteration_n = iteration_n self.width = cell_n @@ -33,10 +34,10 @@ def __init__(self, cell_n:int=100, dilation_size:int=5, iteration_n:int=5, **kwa self.min_filtered = cp.zeros((self.width, self.height)) self.min_filtered_mask = cp.zeros((self.width, self.height)) self.min_filter_kernel = cp.ElementwiseKernel( - in_params='raw U map, raw U mask', - out_params='raw U newmap, raw U newmask', - preamble=\ - string.Template(''' + in_params="raw U map, raw U mask", + out_params="raw U newmap, raw U newmask", + preamble=string.Template( + """ __device__ int get_map_idx(int idx, int layer_n) { const int layer = ${width} * ${height}; return layer * layer_n + idx; @@ -58,9 +59,10 @@ def __init__(self, cell_n:int=100, dilation_size:int=5, iteration_n:int=5, **kwa } return true; } - ''').substitute(width=self.width, height=self.height), - operation=\ - string.Template(''' + """ + ).substitute(width=self.width, height=self.height), + operation=string.Template( + """ U h = map[get_map_idx(i, 0)]; U valid = mask[get_map_idx(i, 0)]; if (valid < 0.5) { @@ -81,22 +83,30 @@ def __init__(self, cell_n:int=100, dilation_size:int=5, iteration_n:int=5, **kwa newmask[get_map_idx(i, 0)] = 0.6; } } - ''').substitute(dilation_size=dilation_size), - name='min_filter_kernel') + """ + ).substitute(dilation_size=dilation_size), + name="min_filter_kernel", + ) - def __call__(self, elevation_map: cp.ndarray, layer_names: List[str], - plugin_layers: cp.ndarray, plugin_layer_names: List[str])->cp.ndarray: + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + ) -> cp.ndarray: self.min_filtered = elevation_map[0].copy() self.min_filtered_mask = elevation_map[2].copy() for i in range(self.iteration_n): - self.min_filter_kernel(elevation_map[0], - elevation_map[2], - self.min_filtered, - self.min_filtered_mask, - size=(self.width * self.height)) + self.min_filter_kernel( + elevation_map[0], + elevation_map[2], + self.min_filtered, + self.min_filtered_mask, + size=(self.width * self.height), + ) # If there's no more mask, break if (self.min_filtered_mask > 0.5).all(): break - min_filtered = cp.where(self.min_filtered_mask > 0.5, - self.min_filtered.copy(), cp.nan) + min_filtered = cp.where(self.min_filtered_mask > 0.5, self.min_filtered.copy(), cp.nan) return min_filtered diff --git a/elevation_mapping_cupy/script/plugins/plugin_manager.py b/elevation_mapping_cupy/script/plugins/plugin_manager.py index 2ba6ce39..bfaf0829 100644 --- a/elevation_mapping_cupy/script/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/plugins/plugin_manager.py @@ -15,14 +15,15 @@ class PluginParams: name: str layer_name: str - fill_nan: bool = False # fill nan to invalid region - is_height_layer: bool = False # if this is a height layer + fill_nan: bool = False # fill nan to invalid region + is_height_layer: bool = False # if this is a height layer class PluginBase(ABC): - """ + """ This is a base class of Plugins """ + def __init__(self, *args, **kwargs): """ Parameters @@ -31,10 +32,15 @@ def __init__(self, *args, **kwargs): The parameter of callback """ - def __call__(self, elevation_map: cp.ndarray, layer_names: List[str], - plugin_layers: cp.ndarray, plugin_layer_names: List[str])->cp.ndarray: + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + ) -> cp.ndarray: """ - This gets the elevation map data and plugin layers as a cupy array. + This gets the elevation map data and plugin layers as a cupy array. Run your processing here and return the result. layer of elevation_map 0: elevation 1: variance @@ -49,9 +55,10 @@ def __call__(self, elevation_map: cp.ndarray, layer_names: List[str], class PluginManger(object): - """ + """ This manages the plugins. """ + def __init__(self, cell_n: int): self.cell_n = cell_n @@ -60,11 +67,9 @@ def init(self, plugin_params: List[PluginParams], extra_params: List[Dict]): self.plugins = [] for param, extra_param in zip(plugin_params, extra_params): - m = importlib.import_module("." + param.name, package="plugins") # -> 'module' + m = importlib.import_module("." + param.name, package="plugins") # -> 'module' for name, obj in inspect.getmembers(m): - if (inspect.isclass(obj) and - issubclass(obj, PluginBase) and - name != "PluginBase"): + if inspect.isclass(obj) and issubclass(obj, PluginBase) and name != "PluginBase": # Add cell_n to params extra_param["cell_n"] = self.cell_n self.plugins.append(obj(**extra_param)) @@ -75,20 +80,20 @@ def init(self, plugin_params: List[PluginParams], extra_params: List[Dict]): def load_plugin_settings(self, file_path: str): print("Start loading plugins...") - cfg = YAML().load(open(file_path, 'r')) + cfg = YAML().load(open(file_path, "r")) plugin_params = [] extra_params = [] for k, v in cfg.items(): - if v['enable']: + if v["enable"]: plugin_params.append( - PluginParams( - name=k, - layer_name=v['layer_name'], - fill_nan=v['fill_nan'], - is_height_layer=v['is_height_layer'], - ) - ) - extra_params.append(v['extra_params']) + PluginParams( + name=k, + layer_name=v["layer_name"], + fill_nan=v["fill_nan"], + is_height_layer=v["is_height_layer"], + ) + ) + extra_params.append(v["extra_params"]) self.init(plugin_params, extra_params) print("Loaded plugins are ", *self.plugin_names) @@ -104,7 +109,7 @@ def get_plugin_names(self): names.append(obj.name) return names - def get_plugin_index_with_name(self, name: str)->int: + def get_plugin_index_with_name(self, name: str) -> int: try: idx = self.plugin_names.index(name) return idx @@ -112,7 +117,7 @@ def get_plugin_index_with_name(self, name: str)->int: print("Error with plugin {}: {}".format(name, e)) return None - def get_layer_index_with_name(self, name: str)->int: + def get_layer_index_with_name(self, name: str) -> int: try: idx = self.layer_names.index(name) return idx @@ -125,36 +130,33 @@ def update_with_name(self, name: str, elevation_map: cp.ndarray, layer_names: Li if idx is not None: self.layers[idx] = self.plugins[idx](elevation_map, layer_names, self.layers, self.layer_names) - def get_map_with_name(self, name: str)->cp.ndarray: + def get_map_with_name(self, name: str) -> cp.ndarray: idx = self.get_layer_index_with_name(name) if idx is not None: return self.layers[idx] - def get_param_with_name(self, name: str)->PluginParams: + def get_param_with_name(self, name: str) -> PluginParams: idx = self.get_layer_index_with_name(name) if idx is not None: return self.plugin_params[idx] -if __name__ == '__main__': +if __name__ == "__main__": plugins = [ - PluginParams(name="min_filter", layer_name="min_filter"), - PluginParams(name="smooth_filter", layer_name="smooth"), - ] - extra_params = [ - {"dilation_size": 5, "iteration_n": 5}, - {"input_layer_name": "elevation2"} - ] + PluginParams(name="min_filter", layer_name="min_filter"), + PluginParams(name="smooth_filter", layer_name="smooth"), + ] + extra_params = [{"dilation_size": 5, "iteration_n": 5}, {"input_layer_name": "elevation2"}] manager = PluginManger(200) - manager.load_plugin_settings('config/plugin_config.yaml') + manager.load_plugin_settings("config/plugin_config.yaml") print(manager.layer_names) print(manager.plugin_names) elevation_map = cp.zeros((7, 200, 200)).astype(cp.float32) layer_names = ["elevation", "variance", "is_valid", "traversability", "time", "upper_bound", "is_upper_bound"] elevation_map[0] = cp.random.randn(200, 200) elevation_map[2] = cp.abs(cp.random.randn(200, 200)) - print('map', elevation_map[0]) - print('layer map ', manager.layers[0]) + print("map", elevation_map[0]) + print("layer map ", manager.layers[0]) manager.update_with_name("min_filter", elevation_map, layer_names) manager.update_with_name("smooth_filter", elevation_map, layer_names) print(manager.get_map_with_name("smooth")) diff --git a/elevation_mapping_cupy/script/plugins/smooth_filter.py b/elevation_mapping_cupy/script/plugins/smooth_filter.py index 7ce99f90..d9ad76ac 100644 --- a/elevation_mapping_cupy/script/plugins/smooth_filter.py +++ b/elevation_mapping_cupy/script/plugins/smooth_filter.py @@ -10,7 +10,7 @@ class SmoothFilter(PluginBase): - """ This is a filter to smoothen + """This is a filter to smoothen ... @@ -19,12 +19,18 @@ class SmoothFilter(PluginBase): cell_n: int width and height of the elevation map. """ - def __init__(self, cell_n:int=100, input_layer_name:str="elevation", **kwargs): + + def __init__(self, cell_n: int = 100, input_layer_name: str = "elevation", **kwargs): super().__init__() self.input_layer_name = input_layer_name - def __call__(self, elevation_map: cp.ndarray, layer_names: List[str], - plugin_layers: cp.ndarray, plugin_layer_names: List[str])->cp.ndarray: + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + ) -> cp.ndarray: if self.input_layer_name in layer_names: idx = layer_names.index(self.input_layer_name) h = elevation_map[idx] diff --git a/elevation_mapping_cupy/script/traversability_filter.py b/elevation_mapping_cupy/script/traversability_filter.py index 2778bbbe..7dfb47c2 100644 --- a/elevation_mapping_cupy/script/traversability_filter.py +++ b/elevation_mapping_cupy/script/traversability_filter.py @@ -10,7 +10,7 @@ def get_filter_torch(*args, **kwargs): import torch.nn as nn class TraversabilityFilter(nn.Module): - def __init__(self, w1, w2, w3, w_out, device='cuda', use_bias=False): + def __init__(self, w1, w2, w3, w_out, device="cuda", use_bias=False): super(TraversabilityFilter, self).__init__() self.conv1 = nn.Conv2d(1, 4, 3, dilation=1, padding=0, bias=use_bias) self.conv2 = nn.Conv2d(1, 4, 3, dilation=2, padding=0, bias=use_bias) @@ -29,15 +29,9 @@ def __call__(self, elevation_cupy): elevation = torch.as_tensor(elevation_cupy, device=self.conv1.weight.device) with torch.no_grad(): - out1 = self.conv1(elevation.view(-1, 1, - elevation.shape[0], - elevation.shape[1])) - out2 = self.conv2(elevation.view(-1, 1, - elevation.shape[0], - elevation.shape[1])) - out3 = self.conv3(elevation.view(-1, 1, - elevation.shape[0], - elevation.shape[1])) + out1 = self.conv1(elevation.view(-1, 1, elevation.shape[0], elevation.shape[1])) + out2 = self.conv2(elevation.view(-1, 1, elevation.shape[0], elevation.shape[1])) + out3 = self.conv3(elevation.view(-1, 1, elevation.shape[0], elevation.shape[1])) out1 = out1[:, :, 2:-2, 2:-2] out2 = out2[:, :, 1:-1, 1:-1] @@ -55,6 +49,7 @@ def __call__(self, elevation_cupy): def get_filter_chainer(*args, **kwargs): import os + os.environ["CHAINER_WARN_VERSION_MISMATCH"] = "0" import chainer import chainer.links as L @@ -63,14 +58,10 @@ def get_filter_chainer(*args, **kwargs): class TraversabilityFilter(chainer.Chain): def __init__(self, w1, w2, w3, w_out, use_cupy=True): super(TraversabilityFilter, self).__init__() - self.conv1 = L.Convolution2D(1, 4, ksize=3, pad=0, dilate=1, - nobias=True, initialW=w1) - self.conv2 = L.Convolution2D(1, 4, ksize=3, pad=0, dilate=2, - nobias=True, initialW=w2) - self.conv3 = L.Convolution2D(1, 4, ksize=3, pad=0, dilate=3, - nobias=True, initialW=w3) - self.conv_out = L.Convolution2D(12, 1, ksize=1, - nobias=True, initialW=w_out) + self.conv1 = L.Convolution2D(1, 4, ksize=3, pad=0, dilate=1, nobias=True, initialW=w1) + self.conv2 = L.Convolution2D(1, 4, ksize=3, pad=0, dilate=2, nobias=True, initialW=w2) + self.conv3 = L.Convolution2D(1, 4, ksize=3, pad=0, dilate=3, nobias=True, initialW=w3) + self.conv_out = L.Convolution2D(12, 1, ksize=1, nobias=True, initialW=w_out) if use_cupy: self.conv1.to_gpu() @@ -81,15 +72,9 @@ def __init__(self, w1, w2, w3, w_out, use_cupy=True): chainer.config.enable_backprop = False def __call__(self, elevation): - out1 = self.conv1(elevation.reshape(-1, 1, - elevation.shape[0], - elevation.shape[1])) - out2 = self.conv2(elevation.reshape(-1, 1, - elevation.shape[0], - elevation.shape[1])) - out3 = self.conv3(elevation.reshape(-1, 1, - elevation.shape[0], - elevation.shape[1])) + out1 = self.conv1(elevation.reshape(-1, 1, elevation.shape[0], elevation.shape[1])) + out2 = self.conv2(elevation.reshape(-1, 1, elevation.shape[0], elevation.shape[1])) + out3 = self.conv3(elevation.reshape(-1, 1, elevation.shape[0], elevation.shape[1])) out1 = out1[:, :, 2:-2, 2:-2] out2 = out2[:, :, 1:-1, 1:-1] @@ -101,21 +86,15 @@ def __call__(self, elevation): return traversability_filter - -if __name__ == '__main__': +if __name__ == "__main__": import cupy as cp from parameter import Parameter + elevation = cp.random.randn(202, 202, dtype=cp.float32) - print('elevation ', elevation.shape) + print("elevation ", elevation.shape) param = Parameter() - fc = get_filter_chainer(param.w1, - param.w2, - param.w3, - param.w_out) - print('chainer ', fc(elevation)) - - ft = get_filter_torch(param.w1, - param.w2, - param.w3, - param.w_out) - print('torch ', ft(elevation)) + fc = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) + print("chainer ", fc(elevation)) + + ft = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) + print("torch ", ft(elevation)) diff --git a/elevation_mapping_cupy/script/traversability_polygon.py b/elevation_mapping_cupy/script/traversability_polygon.py index f1e6b80a..67a43343 100644 --- a/elevation_mapping_cupy/script/traversability_polygon.py +++ b/elevation_mapping_cupy/script/traversability_polygon.py @@ -39,7 +39,7 @@ def calculate_area(polygon): for i in range(len(polygon)): p1 = polygon[i - 1] p2 = polygon[i] - area += (p1[0] * p2[1] - p1[1] * p2[0]) / 2. + area += (p1[0] * p2[1] - p1[1] * p2[0]) / 2.0 return abs(area) @@ -54,7 +54,7 @@ def calculate_untraversable_polygon(over_thresh): def transform_to_map_position(polygon, center, cell_n, resolution): - polygon = center.reshape(1, 2) + (polygon - cell_n / 2.) * resolution + polygon = center.reshape(1, 2) + (polygon - cell_n / 2.0) * resolution return polygon @@ -63,8 +63,7 @@ def transform_to_map_index(points, center, cell_n, resolution): return indices - -if __name__ == '__main__': +if __name__ == "__main__": polygon = [[0, 0], [2, 0], [0, 2]] print(calculate_area(polygon)) From b38442fff02d1ed89168caa74b73b3c257385fd0 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 11 May 2022 15:15:25 +0200 Subject: [PATCH 202/504] Using cp.roll instead of ndimage shift. --- .../script/elevation_mapping.py | 48 ++++++++++++------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping.py index 09734ebd..af53b9b8 100644 --- a/elevation_mapping_cupy/script/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping.py @@ -27,11 +27,8 @@ ) import cupy as cp -import cupyx.scipy as csp -import cupyx.scipy.ndimage xp = cp -sp = csp pool = cp.cuda.MemoryPool(cp.cuda.malloc_managed) cp.cuda.set_allocator(pool.malloc) @@ -131,20 +128,34 @@ def move_to(self, position): self.shift_map_xy(-delta_pixel) self.shift_map_z(-delta[2]) + def pad_value(self, x, shift_value, idx=None, value=0.0): + if idx is None: + if shift_value[0] > 0: + x[:, : shift_value[0], :] = value + elif shift_value[0] < 0: + x[:, shift_value[0] :, :] = value + if shift_value[1] > 0: + x[:, :, : shift_value[1]] = value + elif shift_value[1] < 0: + x[:, :, shift_value[1] :] = value + else: + if shift_value[0] > 0: + x[idx, : shift_value[0], :] = value + elif shift_value[0] < 0: + x[idx, shift_value[0] :, :] = value + if shift_value[1] > 0: + x[idx, :, : shift_value[1]] = value + elif shift_value[1] < 0: + x[idx, :, shift_value[1] :] = value + def shift_map_xy(self, delta_pixel): - shift_value = delta_pixel - shift_fn = sp.ndimage.interpolation.shift + shift_value = delta_pixel.astype(cp.int) + if shift_value.sum() == 0: + return with self.map_lock: - # elevation - self.elevation_map[0] = shift_fn(self.elevation_map[0], shift_value, cval=0.0) - # variance - self.elevation_map[1] = shift_fn(self.elevation_map[1], shift_value, cval=self.initial_variance) - # is valid (1 is valid 0 is not valid) - self.elevation_map[2] = shift_fn(self.elevation_map[2], shift_value, cval=0) - # upper bound - self.elevation_map[5] = shift_fn(self.elevation_map[5], shift_value, cval=0) - # is upper bound - self.elevation_map[6] = shift_fn(self.elevation_map[6], shift_value, cval=0) + self.elevation_map = cp.roll(self.elevation_map, shift_value, axis=(1, 2)) + self.pad_value(self.elevation_map, shift_value, value=0.0) + self.pad_value(self.elevation_map, shift_value, idx=1, value=self.initial_variance) def shift_map_z(self, delta_z): with self.map_lock: @@ -513,14 +524,17 @@ def initialize_map(self, points, method="cubic"): R = xp.random.rand(3, 3) t = xp.random.rand(3) print(R, t) - param = Parameter(use_chainer=False) - param.load_weights("../config/weights.dat") + param = Parameter( + use_chainer=False, weight_file="../config/weights.dat", plugin_config_file="../config/plugin_config.yaml" + ) elevation = ElevationMap(param) layers = ["elevation", "variance", "traversability", "min_filter", "smooth", "inpaint"] data = np.zeros((elevation.cell_n - 2, elevation.cell_n - 2), dtype=np.float32) for i in range(500): elevation.input(points, R, t, 0, 0) elevation.update_normal(elevation.elevation_map[0]) + pos = np.array([i * 0.01, i * 0.02, i * 0.01]) + elevation.move_to(pos) for layer in layers: elevation.get_map_with_name_ref(layer, data) print(i) From aae39803dec0ca5f659ec6e3ca22d7dca953c95d Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 11 May 2022 21:02:24 +0200 Subject: [PATCH 203/504] Fixed bug in checking shift value length --- elevation_mapping_cupy/script/elevation_mapping.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping.py index af53b9b8..accac0c2 100644 --- a/elevation_mapping_cupy/script/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping.py @@ -150,7 +150,7 @@ def pad_value(self, x, shift_value, idx=None, value=0.0): def shift_map_xy(self, delta_pixel): shift_value = delta_pixel.astype(cp.int) - if shift_value.sum() == 0: + if cp.abs(shift_value).sum() == 0: return with self.map_lock: self.elevation_map = cp.roll(self.elevation_map, shift_value, axis=(1, 2)) From 9a696ae504a9a61dc7695a22b0f692c07689e6c8 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 7 Jun 2022 15:13:58 +0200 Subject: [PATCH 204/504] prepare move to github --- jenkins-pipeline | 4 - segmented_planes_terrain_model/CMakeLists.txt | 101 ------ .../SegmentedPlaneProjection.h | 42 --- .../SegmentedPlanesSignedDistanceField.h | 53 ---- .../SegmentedPlanesTerrainModel.h | 41 --- .../SegmentedPlanesTerrainModelRos.h | 57 ---- .../SegmentedPlanesTerrainVisualization.h | 18 -- .../launch/demo.launch | 15 - segmented_planes_terrain_model/package.xml | 25 -- .../src/DemoNode.cpp | 129 -------- .../src/SegmentedPlaneProjection.cpp | 150 --------- .../src/SegmentedPlanesTerrainModel.cpp | 129 -------- .../src/SegmentedPlanesTerrainModelRos.cpp | 124 -------- .../SegmentedPlanesTerrainVisualization.cpp | 40 --- .../test/signedDistanceTest.cpp | 110 ------- signed_distance_field/CMakeLists.txt | 77 ----- .../DistanceDerivatives.h | 62 ---- .../signed_distance_field/Gridmap3dLookup.h | 94 ------ .../GridmapSignedDistanceField.h | 147 --------- .../PixelBorderDistance.h | 104 ------- .../signed_distance_field/SignedDistance2d.h | 59 ---- .../include/signed_distance_field/Utils.h | 18 -- signed_distance_field/package.xml | 16 - .../src/GridmapSignedDistanceField.cpp | 214 ------------- .../src/SignedDistance2d.cpp | 290 ------------------ .../test/naiveSignedDistance.h | 105 ------- signed_distance_field/test/test3dLookup.cpp | 59 ---- .../test/testDerivatives.cpp | 31 -- .../test/testPixelBorderDistance.cpp | 52 ---- .../test/testSignedDistance2d.cpp | 112 ------- .../test/testSignedDistance3d.cpp | 193 ------------ 31 files changed, 2671 deletions(-) delete mode 100644 jenkins-pipeline delete mode 100644 segmented_planes_terrain_model/CMakeLists.txt delete mode 100644 segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h delete mode 100644 segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h delete mode 100644 segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h delete mode 100644 segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h delete mode 100644 segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h delete mode 100644 segmented_planes_terrain_model/launch/demo.launch delete mode 100644 segmented_planes_terrain_model/package.xml delete mode 100644 segmented_planes_terrain_model/src/DemoNode.cpp delete mode 100644 segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp delete mode 100644 segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp delete mode 100644 segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp delete mode 100644 segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp delete mode 100644 segmented_planes_terrain_model/test/signedDistanceTest.cpp delete mode 100644 signed_distance_field/CMakeLists.txt delete mode 100644 signed_distance_field/include/signed_distance_field/DistanceDerivatives.h delete mode 100644 signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h delete mode 100644 signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h delete mode 100644 signed_distance_field/include/signed_distance_field/PixelBorderDistance.h delete mode 100644 signed_distance_field/include/signed_distance_field/SignedDistance2d.h delete mode 100644 signed_distance_field/include/signed_distance_field/Utils.h delete mode 100644 signed_distance_field/package.xml delete mode 100644 signed_distance_field/src/GridmapSignedDistanceField.cpp delete mode 100644 signed_distance_field/src/SignedDistance2d.cpp delete mode 100644 signed_distance_field/test/naiveSignedDistance.h delete mode 100644 signed_distance_field/test/test3dLookup.cpp delete mode 100644 signed_distance_field/test/testDerivatives.cpp delete mode 100644 signed_distance_field/test/testPixelBorderDistance.cpp delete mode 100644 signed_distance_field/test/testSignedDistance2d.cpp delete mode 100644 signed_distance_field/test/testSignedDistance3d.cpp diff --git a/jenkins-pipeline b/jenkins-pipeline deleted file mode 100644 index f0fe0a26..00000000 --- a/jenkins-pipeline +++ /dev/null @@ -1,4 +0,0 @@ -library 'continuous_integration_pipeline' -ciPipeline("--environment anymal \ - --dependencies 'git@bitbucket.org:leggedrobotics/ocs2_anymal.git;feature/perception;git'\ - 'git@bitbucket.org:leggedrobotics/ocs2_dev;feature/perception;git'") diff --git a/segmented_planes_terrain_model/CMakeLists.txt b/segmented_planes_terrain_model/CMakeLists.txt deleted file mode 100644 index 39d96401..00000000 --- a/segmented_planes_terrain_model/CMakeLists.txt +++ /dev/null @@ -1,101 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(segmented_planes_terrain_model) - -# Catkin dependencies -set(CATKIN_PACKAGE_DEPENDENCIES - grid_map_filters_rsl - ocs2_switched_model_interface - grid_map_sdf - pcl_ros - convex_plane_decomposition - convex_plane_decomposition_msgs - convex_plane_decomposition_ros - signed_distance_field - roscpp - visualization_msgs - sensor_msgs -) - -find_package(catkin REQUIRED COMPONENTS - ${CATKIN_PACKAGE_DEPENDENCIES} -) - -# Cpp standard version -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -################################### -## catkin specific configuration ## -################################### -catkin_package( - INCLUDE_DIRS include - LIBRARIES ${PROJECT_NAME} - CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS -) - -########### -## Build ## -########### - -include_directories( - include - ${catkin_INCLUDE_DIRS} -) - -add_library(${PROJECT_NAME} - src/SegmentedPlaneProjection.cpp - src/SegmentedPlanesTerrainModel.cpp - src/SegmentedPlanesTerrainModelRos.cpp - src/SegmentedPlanesTerrainVisualization.cpp - ) -add_dependencies(${PROJECT_NAME} - ${catkin_EXPORTED_TARGETS} - ) -target_link_libraries(${PROJECT_NAME} - ${catkin_LIBRARIES} - ) -target_compile_options(${PROJECT_NAME} - PUBLIC -DCGAL_HAS_THREADS - ) - -add_executable(${PROJECT_NAME}_demo_node - src/DemoNode.cpp -) -target_link_libraries(${PROJECT_NAME}_demo_node - ${catkin_LIBRARIES} - ${PROJECT_NAME} -) - -############# -## Install ## -############# - -install(TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} - ) -install(DIRECTORY include/${PROJECT_NAME}/ - DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} - ) - -install(TARGETS ${PROJECT_NAME}_demo_node - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -) - -install(DIRECTORY launch - DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} -) - -############# -## Testing ## -############# - -add_executable(${PROJECT_NAME}_signed_distance_test - test/signedDistanceTest.cpp - ) -target_link_libraries(${PROJECT_NAME}_signed_distance_test - ${catkin_LIBRARIES} - ${PROJECT_NAME} - ) \ No newline at end of file diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h deleted file mode 100644 index 25261dd2..00000000 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlaneProjection.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Created by rgrandia on 12.10.21. -// - -#pragma once - -#include -#include - -#include -#include - -namespace switched_model { - -double distanceCost(const vector3_t& query, const vector3_t& terrainPoint); - -double distanceCostLowerbound(double distanceSquared); - -double intervalSquareDistance(double value, double min, double max); - -double squaredDistanceToBoundingBox(const convex_plane_decomposition::CgalPoint2d& point, - const convex_plane_decomposition::CgalBbox2d& boundingBox); - -const convex_plane_decomposition::CgalPolygonWithHoles2d* findInsetContainingThePoint( - const convex_plane_decomposition::CgalPoint2d& point, const std::vector& insets); - -convex_plane_decomposition::CgalPoint2d projectToPlanarRegion(const convex_plane_decomposition::CgalPoint2d& queryProjectedToPlane, - const convex_plane_decomposition::PlanarRegion& planarRegion); - -struct RegionSortingInfo { - const convex_plane_decomposition::PlanarRegion* regionPtr; - convex_plane_decomposition::CgalPoint2d positionInTerrainFrame; - double boundingBoxSquareDistance; -}; -std::vector sortWithBoundingBoxes(const vector3_t& positionInWorld, - const std::vector& planarRegions); - -std::pair getPlanarRegionAtPositionInWorld( - const vector3_t& positionInWorld, const std::vector& planarRegions, - std::function penaltyFunction); - -} // namespace switched_model \ No newline at end of file diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h deleted file mode 100644 index 46aa3e73..00000000 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h +++ /dev/null @@ -1,53 +0,0 @@ -// -// Created by rgrandia on 17.03.22. -// - -#pragma once - -#include - -#include - -namespace switched_model { - -/** - * Simple wrapper class to implement the switched_model::SignedDistanceField interface. - * See the forwarded function for documentation. - */ -class SegmentedPlanesSignedDistanceField : public SignedDistanceField { - public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW - - SegmentedPlanesSignedDistanceField(const grid_map::GridMap& gridMap, const std::string& elevationLayer, double minHeight, - double maxHeight) - : sdf_(gridMap, elevationLayer, minHeight, maxHeight) {} - - ~SegmentedPlanesSignedDistanceField() override = default; - SegmentedPlanesSignedDistanceField* clone() const override { return new SegmentedPlanesSignedDistanceField(*this); }; - - switched_model::scalar_t value(const switched_model::vector3_t& position) const override { return sdf_.value(position); } - - switched_model::vector3_t derivative(const switched_model::vector3_t& position) const override { return sdf_.derivative(position); } - - std::pair valueAndDerivative( - const switched_model::vector3_t& position) const override { - return sdf_.valueAndDerivative(position); - } - - pcl::PointCloud asPointCloud( - size_t decimation = 1, const std::function& condition = [](float) { return true; }) const { - return sdf_.asPointCloud(decimation, condition); - } - - pcl::PointCloud freeSpacePointCloud(size_t decimation = 1) const { return sdf_.freeSpacePointCloud(decimation); } - - pcl::PointCloud obstaclePointCloud(size_t decimation = 1) const { return sdf_.obstaclePointCloud(decimation); } - - protected: - SegmentedPlanesSignedDistanceField(const SegmentedPlanesSignedDistanceField& other) : sdf_(other.sdf_){}; - - private: - grid_map::GridmapSignedDistanceField sdf_; -}; - -} // namespace switched_model \ No newline at end of file diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h deleted file mode 100644 index 1e2240f8..00000000 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// Created by rgrandia on 23.06.20. -// - -#pragma once - -#include -#include - -#include "segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h" - -namespace switched_model { - -class SegmentedPlanesTerrainModel : public switched_model::TerrainModel { - public: - SegmentedPlanesTerrainModel(convex_plane_decomposition::PlanarTerrain planarTerrain); - - TerrainPlane getLocalTerrainAtPositionInWorldAlongGravity(const vector3_t& positionInWorld, - std::function penaltyFunction) const override; - - using switched_model::TerrainModel::getConvexTerrainAtPositionInWorld; - ConvexTerrain getConvexTerrainAtPositionInWorld(const vector3_t& positionInWorld, - std::function penaltyFunction) const override; - - void createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, const Eigen::Vector3d& maxCoordinates); - - const SegmentedPlanesSignedDistanceField* getSignedDistanceField() const override { return signedDistanceField_.get(); } - - vector3_t getHighestObstacleAlongLine(const vector3_t& position1InWorld, const vector3_t& position2InWorld) const override; - - std::vector getHeightProfileAlongLine(const vector3_t& position1InWorld, const vector3_t& position2InWorld) const override; - - const convex_plane_decomposition::PlanarTerrain& planarTerrain() const { return planarTerrain_; } - - private: - const convex_plane_decomposition::PlanarTerrain planarTerrain_; - std::unique_ptr signedDistanceField_; - const grid_map::Matrix* const elevationData_; -}; - -} // namespace switched_model diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h deleted file mode 100644 index 1e9bf0e0..00000000 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h +++ /dev/null @@ -1,57 +0,0 @@ -// -// Created by rgrandia on 24.06.20. -// - -#pragma once - -#include - -#include - -#include -#include - -#include -#include - -#include "SegmentedPlanesTerrainModel.h" - -namespace switched_model { - -class SegmentedPlanesTerrainModelRos { - public: - SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle); - - ~SegmentedPlanesTerrainModelRos(); - - /// Extract the latest terrain model. Resets internal model to a nullptr - std::unique_ptr getTerrainModel(); - - void createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, const Eigen::Vector3d& maxCoordinates); - - void publish(); - - private: - void callback(const convex_plane_decomposition_msgs::PlanarTerrain::ConstPtr& msg); - - std::pair getSignedDistanceRange(const grid_map::GridMap& gridMap, const std::string& elevationLayer); - - ros::Subscriber terrainSubscriber_; - ros::Publisher distanceFieldPublisher_; - - std::mutex updateMutex_; - std::atomic_bool terrainUpdated_; - std::unique_ptr terrainPtr_; - - std::mutex updateCoordinatesMutex_; - Eigen::Vector3d minCoordinates_; - Eigen::Vector3d maxCoordinates_; - bool externalCoordinatesGiven_; - - std::mutex pointCloudMutex_; - pcl::PointCloud pointCloud_; - - ocs2::benchmark::RepeatedTimer callbackTimer_; -}; - -} // namespace switched_model diff --git a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h b/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h deleted file mode 100644 index 6c8acf6b..00000000 --- a/segmented_planes_terrain_model/include/segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// Created by rgrandia on 24.06.20. -// - -#pragma once - -#include -#include - -#include -#include - -namespace switched_model { - -visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, ocs2::Color color, double linewidth, - double normalLength); - -} // namespace switched_model diff --git a/segmented_planes_terrain_model/launch/demo.launch b/segmented_planes_terrain_model/launch/demo.launch deleted file mode 100644 index ef8c03d9..00000000 --- a/segmented_planes_terrain_model/launch/demo.launch +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/segmented_planes_terrain_model/package.xml b/segmented_planes_terrain_model/package.xml deleted file mode 100644 index 3db47322..00000000 --- a/segmented_planes_terrain_model/package.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - segmented_planes_terrain_model - 0.0.0 - The segmented_planes_terrain_model package - - Ruben Grandia - - TODO - - catkin - grid_map_filters_rsl - ocs2_switched_model_interface - grid_map_sdf - pcl_ros - convex_plane_decomposition - convex_plane_decomposition_msgs - convex_plane_decomposition_ros - signed_distance_field - roscpp - visualization_msgs - sensor_msgs - libvtk7-dev - - diff --git a/segmented_planes_terrain_model/src/DemoNode.cpp b/segmented_planes_terrain_model/src/DemoNode.cpp deleted file mode 100644 index edca9ae6..00000000 --- a/segmented_planes_terrain_model/src/DemoNode.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// -// Created by rgrandia on 24.06.20. -// - -#include "segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h" - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h" -#include "segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h" - -const std::string frameId_ = "odom"; -std::unique_ptr messageMap; - -visualization_msgs::MarkerArray toMarker(const switched_model::ConvexTerrain& convexTerrain) { - visualization_msgs::MarkerArray markerArray = switched_model::getConvexTerrainMarkers(convexTerrain, ocs2::Color::orange, 0.005, 0.1); - - // Add headers and Id - const ros::Time timeStamp = ros::Time::now(); - ocs2::assignHeader(markerArray.markers.begin(), markerArray.markers.end(), ocs2::getHeaderMsg(frameId_, timeStamp)); - ocs2::assignIncreasingId(markerArray.markers.begin(), markerArray.markers.end()); - - return markerArray; -} - -visualization_msgs::Marker toMarker(const switched_model::vector3_t& position) { - auto marker = ocs2::getSphereMsg(position, ocs2::Color::green, 0.02); - - const ros::Time timeStamp = ros::Time::now(); - marker.header = ocs2::getHeaderMsg(frameId_, timeStamp); - return marker; -} - -void elevationMappingCallback(const grid_map_msgs::GridMap& message) { - if (!messageMap) { - messageMap = std::make_unique(); - } - grid_map::GridMapRosConverter::fromMessage(message, *messageMap, {"elevation"}, false, false); -} - -float randomFloat(float a, float b) { - float random = ((float)rand()) / (float)RAND_MAX; - float diff = b - a; - float r = random * diff; - return a + r; -} - -int main(int argc, char** argv) { - ros::init(argc, argv, "segmented_planes_demo_node"); - ros::NodeHandle nodeHandle("~"); - - // Subscription to terrain - switched_model::SegmentedPlanesTerrainModelRos segmentedPlanesTerrainModelRos(nodeHandle); - std::unique_ptr terrainModel; - - // Elevation subscription - - // Publishers for visualization - auto positionPublisher_ = nodeHandle.advertise("queryPosition", 1); - auto convexTerrainPublisher_ = nodeHandle.advertise("convex_terrain", 1); - auto regionBoundaryPublisher_ = nodeHandle.advertise("regionBoundary", 1); - auto distanceFieldPublisher = nodeHandle.advertise("signed_distance_field", 1); - auto elevationMapSubscriber = nodeHandle.subscribe("/convex_plane_decomposition_ros/filtered_map", 1, &elevationMappingCallback); - - // Node loop - ros::Rate rate(1. / 5.); - while (ros::ok()) { - if (auto newTerrain = segmentedPlanesTerrainModelRos.getTerrainModel()) { - terrainModel = std::move(newTerrain); - ROS_INFO("Terrain model updated!!"); - } - - if (terrainModel && messageMap) { - switched_model::vector3_t positionInWorld{randomFloat(-2.0, 2.0), randomFloat(-2.0, 2.0), randomFloat(0.0, 1.0)}; - positionPublisher_.publish(toMarker(positionInWorld)); - std::cout << "Query position: " << positionInWorld.transpose() << std::endl; - - auto t0 = std::chrono::high_resolution_clock::now(); - const auto convexTerrain = terrainModel->getConvexTerrainAtPositionInWorld(positionInWorld); - auto t1 = std::chrono::high_resolution_clock::now(); - std::cout << "Query took " << 1e-3 * std::chrono::duration_cast(t1 - t0).count() << " [ms]\n"; - - positionPublisher_.publish(toMarker(positionInWorld)); - convexTerrainPublisher_.publish(toMarker(convexTerrain)); - - double heightClearance = 0.35; - double width = 1.5; - double length = 2.0; - bool success; - grid_map::GridMap localMap = messageMap->getSubmap({convexTerrain.plane.positionInWorld.x(), convexTerrain.plane.positionInWorld.y()}, - Eigen::Array2d(width, length), success); - auto t2 = std::chrono::high_resolution_clock::now(); - switched_model::SegmentedPlanesSignedDistanceField sdf(localMap, "elevation", - convexTerrain.plane.positionInWorld.z() - heightClearance, - convexTerrain.plane.positionInWorld.z() + heightClearance); - auto t3 = std::chrono::high_resolution_clock::now(); - std::cout << "Sdf computation took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() << " [ms]\n"; - - auto t4 = std::chrono::high_resolution_clock::now(); - auto sdfClone = std::unique_ptr(sdf.clone()); - auto t5 = std::chrono::high_resolution_clock::now(); - std::cout << "Sdf.clone() computation took " << 1e-3 * std::chrono::duration_cast(t5 - t4).count() - << " [ms]\n"; - - sensor_msgs::PointCloud2 pointCloud2Msg; - pcl::toROSMsg(sdf.obstaclePointCloud(4), pointCloud2Msg); - pointCloud2Msg.header = ocs2::getHeaderMsg(frameId_, ros::Time::now()); - - distanceFieldPublisher.publish(pointCloud2Msg); - } - - ros::spinOnce(); - rate.sleep(); - } - - return 0; -} \ No newline at end of file diff --git a/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp b/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp deleted file mode 100644 index 1f00659b..00000000 --- a/segmented_planes_terrain_model/src/SegmentedPlaneProjection.cpp +++ /dev/null @@ -1,150 +0,0 @@ -// -// Created by rgrandia on 12.10.21. -// - -#include "segmented_planes_terrain_model/SegmentedPlaneProjection.h" - -#include - -namespace switched_model { - -// alias to avoid long namespace -namespace cpd = convex_plane_decomposition; - -double distanceCost(const vector3_t& query, const vector3_t& terrainPoint) { - const double dx = query.x() - terrainPoint.x(); - const double dy = query.y() - terrainPoint.y(); - const double dz = query.z() - terrainPoint.z(); - return dx * dx + dy * dy + dz * dz; -} - -double distanceCostLowerbound(double distanceSquared) { - return distanceSquared; -} - -double intervalSquareDistance(double value, double min, double max) { - // - | 0 | + - // min max - // Returns 0.0 if between min and max. Returns the distance to one boundary otherwise. - if (value < min) { - double diff = min - value; - return diff * diff; - } else if (value < max) { - return 0.0; - } else { - double diff = max - value; - return diff * diff; - } -} - -double squaredDistanceToBoundingBox(const cpd::CgalPoint2d& point, const cpd::CgalBbox2d& boundingBox) { - double dxdx = intervalSquareDistance(point.x(), boundingBox.xmin(), boundingBox.xmax()); - double dydy = intervalSquareDistance(point.y(), boundingBox.ymin(), boundingBox.ymax()); - return dxdx + dydy; -} - -const cpd::CgalPolygonWithHoles2d* findInsetContainingThePoint(const cpd::CgalPoint2d& point, - const std::vector& insets) { - for (const auto& inset : insets) { - if (cpd::isInside(point, inset.outer_boundary())) { - return &inset; - } - } - return nullptr; -} - -cpd::CgalPoint2d projectToPlanarRegion(const cpd::CgalPoint2d& queryProjectedToPlane, const cpd::PlanarRegion& planarRegion) { - // First search if the projected point is inside any of the insets. - const auto* const insetPtrContainingPoint = findInsetContainingThePoint(queryProjectedToPlane, planarRegion.boundaryWithInset.insets); - - // Compute the projection - cpd::CgalPoint2d projectedPoint; - if (insetPtrContainingPoint == nullptr) { - // Not inside any of the insets. Need to look for the closest one. The projection will be to the boundary - double minDistSquared = std::numeric_limits::max(); - for (const auto& inset : planarRegion.boundaryWithInset.insets) { - const auto closestPoint = cpd::projectToClosestPoint(queryProjectedToPlane, inset.outer_boundary()); - double distSquare = cpd::squaredDistance(closestPoint, queryProjectedToPlane); - if (distSquare < minDistSquared) { - projectedPoint = closestPoint; - minDistSquared = distSquare; - } - } - } else { - // Query point is inside and does not need projection... - projectedPoint = queryProjectedToPlane; - - // ... unless it is inside a hole - for (const auto& hole : insetPtrContainingPoint->holes()) { - if (cpd::isInside(queryProjectedToPlane, hole)) { - projectedPoint = cpd::projectToClosestPoint(queryProjectedToPlane, hole); - break; // No need to search other holes. Holes are not overlapping - } - } - } - - return projectedPoint; -} - -std::vector sortWithBoundingBoxes(const vector3_t& positionInWorld, - const std::vector& planarRegions) { - // Compute distance to bounding boxes - std::vector regionsAndBboxSquareDistances; - regionsAndBboxSquareDistances.reserve(planarRegions.size()); - for (const auto& planarRegion : planarRegions) { - const auto& positionInTerrainFrame = planarRegion.transformPlaneToWorld.inverse() * positionInWorld; - const double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); - - RegionSortingInfo regionSortingInfo; - regionSortingInfo.regionPtr = &planarRegion; - regionSortingInfo.positionInTerrainFrame = {positionInTerrainFrame.x(), positionInTerrainFrame.y()}; - regionSortingInfo.boundingBoxSquareDistance = - squaredDistanceToBoundingBox(regionSortingInfo.positionInTerrainFrame, planarRegion.bbox2d) + dzdz; - - regionsAndBboxSquareDistances.push_back(regionSortingInfo); - } - - // Sort regions close to far - std::sort(regionsAndBboxSquareDistances.begin(), regionsAndBboxSquareDistances.end(), - [](const RegionSortingInfo& lhs, const RegionSortingInfo& rhs) { - return lhs.boundingBoxSquareDistance < rhs.boundingBoxSquareDistance; - }); - - return regionsAndBboxSquareDistances; -} - -std::pair getPlanarRegionAtPositionInWorld( - const vector3_t& positionInWorld, const std::vector& planarRegions, - std::function penaltyFunction) { - const auto sortedRegions = sortWithBoundingBoxes(positionInWorld, planarRegions); - - // Look for closest planar region. - scalar_t minCost = std::numeric_limits::max(); - std::pair closestRegionAndProjection; - for (const auto& regionInfo : sortedRegions) { - // Skip based on lower bound - if (distanceCostLowerbound(regionInfo.boundingBoxSquareDistance) > minCost) { - continue; - } - - // Shorthand - const auto* regionPtr = regionInfo.regionPtr; - - // Project onto planar region - const auto projectedPointInTerrainFrame = projectToPlanarRegion(regionInfo.positionInTerrainFrame, *regionPtr); - - // Express projected point in World frame - const auto projectionInWorldFrame = - convex_plane_decomposition::positionInWorldFrameFromPosition2dInPlane(projectedPointInTerrainFrame, regionPtr->transformPlaneToWorld); - - const scalar_t cost = distanceCost(positionInWorld, projectionInWorldFrame) + penaltyFunction(projectionInWorldFrame); - if (cost < minCost) { - minCost = cost; - closestRegionAndProjection = {regionPtr, projectedPointInTerrainFrame}; - } - } - - return closestRegionAndProjection; -} - -} // namespace switched_model \ No newline at end of file diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp deleted file mode 100644 index 21e3c396..00000000 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModel.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// -// Created by rgrandia on 23.06.20. -// - -#include "segmented_planes_terrain_model/SegmentedPlanesTerrainModel.h" - -#include - -#include - -#include - -#include "segmented_planes_terrain_model/SegmentedPlaneProjection.h" - -namespace switched_model { - -namespace { -const std::string elevationLayerName = "elevation"; -} // namespace - -SegmentedPlanesTerrainModel::SegmentedPlanesTerrainModel(convex_plane_decomposition::PlanarTerrain planarTerrain) - : planarTerrain_(std::move(planarTerrain)), - signedDistanceField_(nullptr), - elevationData_(&planarTerrain_.gridMap.get(elevationLayerName)) {} - -TerrainPlane SegmentedPlanesTerrainModel::getLocalTerrainAtPositionInWorldAlongGravity( - const vector3_t& positionInWorld, std::function penaltyFunction) const { - const auto regionAndSeedPoint = - getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions, std::move(penaltyFunction)); - const auto& region = *regionAndSeedPoint.first; - const auto& seedpoint = regionAndSeedPoint.second; - const auto& seedpointInWorldFrame = - convex_plane_decomposition::positionInWorldFrameFromPosition2dInPlane(seedpoint, region.transformPlaneToWorld); - return TerrainPlane{seedpointInWorldFrame, region.transformPlaneToWorld.linear().transpose()}; -} - -ConvexTerrain SegmentedPlanesTerrainModel::getConvexTerrainAtPositionInWorld( - const vector3_t& positionInWorld, std::function penaltyFunction) const { - const auto regionAndSeedPoint = - getPlanarRegionAtPositionInWorld(positionInWorld, planarTerrain_.planarRegions, std::move(penaltyFunction)); - const auto& region = *regionAndSeedPoint.first; - const auto& seedpoint = regionAndSeedPoint.second; - const auto& seedpointInWorldFrame = - convex_plane_decomposition::positionInWorldFrameFromPosition2dInPlane(seedpoint, region.transformPlaneToWorld); - - // Convert boundary and seedpoint to terrain frame - const int numberOfVertices = 16; // Multiple of 4 is nice for symmetry. - const double growthFactor = 1.05; - const auto convexRegion = convex_plane_decomposition::growConvexPolygonInsideShape(region.boundaryWithInset.boundary, seedpoint, - numberOfVertices, growthFactor); - - // Return convex region with origin at the seedpoint - ConvexTerrain convexTerrain; - convexTerrain.plane = {seedpointInWorldFrame, region.transformPlaneToWorld.linear().transpose()}; // Origin is at the seedpoint - convexTerrain.boundary.reserve(convexRegion.size()); - for (const auto& point : convexRegion) { - convexTerrain.boundary.emplace_back(point.x() - seedpoint.x(), point.y() - seedpoint.y()); // Shift points to new origin - } - return convexTerrain; -} - -void SegmentedPlanesTerrainModel::createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, - const Eigen::Vector3d& maxCoordinates) { - // Compute coordinates of submap - const auto minXY = - grid_map::lookup::projectToMapWithMargin(planarTerrain_.gridMap, grid_map::Position(minCoordinates.x(), minCoordinates.y())); - const auto maxXY = - grid_map::lookup::projectToMapWithMargin(planarTerrain_.gridMap, grid_map::Position(maxCoordinates.x(), maxCoordinates.y())); - const auto centerXY = 0.5 * (minXY + maxXY); - const auto lengths = maxXY - minXY; - - bool success = true; - grid_map::GridMap subMap = planarTerrain_.gridMap.getSubmap(centerXY, lengths, success); - if (success) { - signedDistanceField_ = std::make_unique(subMap, elevationLayerName, - minCoordinates.z(), maxCoordinates.z()); - } else { - std::cerr << "[SegmentedPlanesTerrainModel] Failed to get subMap" << std::endl; - } -} - -vector3_t SegmentedPlanesTerrainModel::getHighestObstacleAlongLine(const vector3_t& position1InWorld, - const vector3_t& position2InWorld) const { - const auto result = grid_map::lookup::maxValueBetweenLocations( - {position1InWorld.x(), position1InWorld.y()}, {position2InWorld.x(), position2InWorld.y()}, planarTerrain_.gridMap, *elevationData_); - if (result.isValid) { - return {result.position.x(), result.position.y(), result.value}; - } else { - // return highest query point if the map didn't work. - if (position1InWorld.z() > position2InWorld.z()) { - return position1InWorld; - } else { - return position2InWorld; - } - } -} - -std::vector SegmentedPlanesTerrainModel::getHeightProfileAlongLine(const vector3_t& position1InWorld, - const vector3_t& position2InWorld) const { - const vector2_t diff2d = position2InWorld.head<2>() - position1InWorld.head<2>(); - const scalar_t diffSquareNorm = diff2d.squaredNorm(); - const auto resolution = planarTerrain_.gridMap.getResolution(); - - if (diffSquareNorm > (resolution * resolution)) { // norm(p2-p1)_XY > resolution - const auto pointsOnLine = - grid_map::lookup::valuesBetweenLocations({position1InWorld.x(), position1InWorld.y()}, {position2InWorld.x(), position2InWorld.y()}, - planarTerrain_.gridMap, *elevationData_); - - std::vector heightProfile; - heightProfile.reserve(pointsOnLine.size()); - - for (const auto& point : pointsOnLine) { - const vector2_t pointDiff = point.head<2>() - position1InWorld.head<2>(); - const scalar_t lineProgress = pointDiff.dot(diff2d) / diffSquareNorm; - if (lineProgress >= 0.0 && lineProgress <= 1.0) { - heightProfile.push_back({lineProgress, point.z()}); - } - } - - return heightProfile; - } else { - grid_map::Index index; - planarTerrain_.gridMap.getIndex({position1InWorld.x(), position1InWorld.y()}, index); - scalar_t heightData = (*elevationData_)(index(0), index(1)); - return {{0.0, heightData}, {1.0, heightData}}; - } -} - -} // namespace switched_model diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp deleted file mode 100644 index e7def050..00000000 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainModelRos.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// -// Created by rgrandia on 24.06.20. -// - -#include "segmented_planes_terrain_model/SegmentedPlanesTerrainModelRos.h" - -#include -#include - -#include -#include -#include - -namespace switched_model { - -SegmentedPlanesTerrainModelRos::SegmentedPlanesTerrainModelRos(ros::NodeHandle& nodehandle) - : terrainUpdated_(false), - minCoordinates_(Eigen::Vector3d::Zero()), - maxCoordinates_(Eigen::Vector3d::Zero()), - externalCoordinatesGiven_(false) { - terrainSubscriber_ = - nodehandle.subscribe("/convex_plane_decomposition_ros/planar_terrain", 1, &SegmentedPlanesTerrainModelRos::callback, this); - distanceFieldPublisher_ = - nodehandle.advertise("/convex_plane_decomposition_ros/signed_distance_field", 1, true); -} - -SegmentedPlanesTerrainModelRos::~SegmentedPlanesTerrainModelRos() { - if (callbackTimer_.getNumTimedIntervals() > 0) { - std::cout << "[SegmentedPlanesTerrainModelRos] Benchmarking terrain Callback\n" - << "\tStatistics computed over " << callbackTimer_.getNumTimedIntervals() << " iterations. \n" - << "\tAverage time [ms] " << callbackTimer_.getAverageInMilliseconds() << "\n" - << "\tMaximum time [ms] " << callbackTimer_.getMaxIntervalInMilliseconds() << std::endl; - } -} - -std::unique_ptr SegmentedPlanesTerrainModelRos::getTerrainModel() { - std::lock_guard lock(updateMutex_); - return std::move(terrainPtr_); -} - -void SegmentedPlanesTerrainModelRos::createSignedDistanceBetween(const Eigen::Vector3d& minCoordinates, - const Eigen::Vector3d& maxCoordinates) { - std::lock_guard lock(updateCoordinatesMutex_); - minCoordinates_ = minCoordinates; - maxCoordinates_ = maxCoordinates; - externalCoordinatesGiven_ = true; -} - -void SegmentedPlanesTerrainModelRos::publish() { - // Extract point cloud. - pcl::PointCloud pointcloud; - { - std::lock_guard lock(pointCloudMutex_); - pointcloud.swap(pointCloud_); - } - - // Publish. - if (!pointcloud.empty()) { - sensor_msgs::PointCloud2 pointCloud2Msg; - pcl::toROSMsg(pointcloud, pointCloud2Msg); - distanceFieldPublisher_.publish(pointCloud2Msg); - } -} - -void SegmentedPlanesTerrainModelRos::callback(const convex_plane_decomposition_msgs::PlanarTerrain::ConstPtr& msg) { - callbackTimer_.startTimer(); - - // Read terrain - auto terrainPtr = std::make_unique(convex_plane_decomposition::fromMessage(*msg)); - - // Create SDF - const std::string elevationLayer = "elevation"; - if (terrainPtr->planarTerrain().gridMap.exists(elevationLayer)) { - const auto sdfRange = getSignedDistanceRange(terrainPtr->planarTerrain().gridMap, elevationLayer); - terrainPtr->createSignedDistanceBetween(sdfRange.first, sdfRange.second); - } - - // Create pointcloud for visualization - const auto* sdfPtr = terrainPtr->getSignedDistanceField(); - if (sdfPtr != nullptr) { - auto pointCloud = sdfPtr->asPointCloud(1, [](float val) { return -0.05F <= val && val <= 0.0F; }); - std::lock_guard lock(pointCloudMutex_); - pointCloud_.swap(pointCloud); - } - - { // Move to storage under the lock - std::lock_guard lock(updateMutex_); - terrainPtr_.swap(terrainPtr); - } - - callbackTimer_.endTimer(); -} - -std::pair SegmentedPlanesTerrainModelRos::getSignedDistanceRange(const grid_map::GridMap& gridMap, - const std::string& elevationLayer) { - // Extract coordinates for signed distance field - Eigen::Vector3d minCoordinates; - Eigen::Vector3d maxCoordinates; - bool externalRangeGiven; - { - std::lock_guard lock(updateCoordinatesMutex_); - minCoordinates = minCoordinates_; - maxCoordinates = maxCoordinates_; - externalRangeGiven = externalCoordinatesGiven_; - } - - if (!externalRangeGiven) { - // Read min-max from elevation map - const float heightMargin = 0.1; - const auto& elevationData = gridMap.get(elevationLayer); - const float minValue = elevationData.minCoeffOfFinites() - heightMargin; - const float maxValue = elevationData.maxCoeffOfFinites() + heightMargin; - auto minXY = grid_map::lookup::projectToMapWithMargin( - gridMap, grid_map::Position(std::numeric_limits::lowest(), std::numeric_limits::lowest())); - auto maxXY = grid_map::lookup::projectToMapWithMargin( - gridMap, grid_map::Position(std::numeric_limits::max(), std::numeric_limits::max())); - minCoordinates = {minXY.x(), minXY.y(), minValue}; - maxCoordinates = {maxXY.x(), maxXY.y(), maxValue}; - }; - - return {minCoordinates, maxCoordinates}; -} - -} // namespace switched_model diff --git a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp b/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp deleted file mode 100644 index b8a576c3..00000000 --- a/segmented_planes_terrain_model/src/SegmentedPlanesTerrainVisualization.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// Created by rgrandia on 24.06.20. -// - -#include "segmented_planes_terrain_model/SegmentedPlanesTerrainVisualization.h" - -#include - -namespace switched_model { - -visualization_msgs::MarkerArray getConvexTerrainMarkers(const ConvexTerrain& convexTerrain, ocs2::Color color, double linewidth, - double normalLength) { - visualization_msgs::MarkerArray markerArray; - markerArray.markers.reserve(2); - - // Mark the surface normal - const vector3_t surfaceNormal = normalLength * surfaceNormalInWorld(convexTerrain.plane); - markerArray.markers.emplace_back(ocs2::getArrowAtPointMsg(surfaceNormal, convexTerrain.plane.positionInWorld, color)); - - // Polygon message - if (!convexTerrain.boundary.empty()) { - std::vector boundary; - boundary.reserve(convexTerrain.boundary.size() + 1); - for (const auto& point : convexTerrain.boundary) { - const auto& pointInWorldFrame = positionInWorldFrameFromPositionInTerrain({point.x(), point.y(), 0.0}, convexTerrain.plane); - boundary.emplace_back(ocs2::getPointMsg(pointInWorldFrame)); - } - // Close the polygon - const auto& pointInWorldFrame = positionInWorldFrameFromPositionInTerrain( - {convexTerrain.boundary.front().x(), convexTerrain.boundary.front().y(), 0.0}, convexTerrain.plane); - boundary.emplace_back(ocs2::getPointMsg(pointInWorldFrame)); - - markerArray.markers.emplace_back(ocs2::getLineMsg(std::move(boundary), color, linewidth)); - } else { - } - - return markerArray; -} - -} // namespace switched_model diff --git a/segmented_planes_terrain_model/test/signedDistanceTest.cpp b/segmented_planes_terrain_model/test/signedDistanceTest.cpp deleted file mode 100644 index 6db3eaa8..00000000 --- a/segmented_planes_terrain_model/test/signedDistanceTest.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// -// Created by rgrandia on 09.07.20. -// - -#include - - -#include -#include - -#include -#include -#include -#include - -#include "segmented_planes_terrain_model/SegmentedPlanesSignedDistanceField.h" - -grid_map::GridMap loadElevationMapFromFile(const std::string& filePath, double resolution, double scale) { - // Read the file - cv::Mat image; - image = cv::imread(filePath, cv::ImreadModes::IMREAD_GRAYSCALE); - - // Check for invalid input - if (!image.data) { - throw std::runtime_error("Could not open or find the image"); - } - - // Min max values - double minValue, maxValue; - cv::minMaxLoc(image, &minValue, &maxValue); - - grid_map::GridMap mapOut({"elevation"}); - mapOut.setFrameId("odom"); - grid_map::GridMapCvConverter::initializeFromImage(image, resolution, mapOut, grid_map::Position(0.0, 0.0)); - grid_map::GridMapCvConverter::addLayerFromImage(image, std::string("elevation"), mapOut, float(0.0), float(scale), 0.5); - return mapOut; -} - -int main(int argc, char** argv) { - std::string folder = "/home/rgrandia/git/anymal/convex_terrain_representation/convex_plane_decomposition_ros/data/"; - // std::string file = "elevationMap_8_139cm.png"; - // double heightScale = 1.39; - std::string file = "demo_map.png"; - double heightScale = 1.25; - // std::string file = "realStairs_125cm.png"; double heightScale = 1.25; - // std::string file = "terrain.png"; double heightScale = 1.25; - // std::string file = "holes.png"; double heightScale = 1.0; - // std::string file = "slope_1m_1m_20cm.png"; double heightScale = 0.2; - // std::string file = "straightStairs_1m_1m_60cm.png"; double heightScale = 0.6; - double resolution = 0.02; - - auto messageMap = loadElevationMapFromFile(folder + file, resolution, heightScale); - - grid_map::SignedDistanceField signedDistanceField; - - double width = 4.0; - bool success; - grid_map::GridMap localMap = messageMap.getSubmap(messageMap.getPosition(), Eigen::Array2d(width, width), success); - - // signedDistanceField.calculateSignedDistanceField(messageMap, "elevation", heightClearance); - const grid_map::GridMap& gridMap = localMap; - const std::string& layer = "elevation"; - const double heightClearance = 0.1; - - // Members - float resolution_; - grid_map::Size size_; - grid_map::Position position_; - std::vector data_; - float zIndexStartHeight_; - float maxDistance_; - const float lowestHeight_ = -1e5; - using grid_map::Matrix; - - // initialization - resolution_ = gridMap.getResolution(); - position_ = gridMap.getPosition(); - size_ = gridMap.getSize(); - Matrix map = gridMap.get(layer); // Copy! - - float minHeight = map.minCoeffOfFinites(); - if (!std::isfinite(minHeight)) minHeight = lowestHeight_; - float maxHeight = map.maxCoeffOfFinites(); - if (!std::isfinite(maxHeight)) maxHeight = lowestHeight_; - - const float valueForEmptyCells = lowestHeight_; // maxHeight, minHeight (TODO Make this an option). - for (size_t i = 0; i < map.size(); ++i) { - if (std::isnan(map(i))) map(i) = valueForEmptyCells; - } - - // Height range of the signed distance field is higher than the max height. - maxHeight += heightClearance; - - auto t2 = std::chrono::high_resolution_clock::now(); - const int N = 50; - for (int rep = 0; rep < N; rep++) { -// // ========================================================= -// data_.clear(); -// -// // Calculate signed distance field from bottom. -// for (float h = minHeight; h < maxHeight; h += resolution_) { -// data_.emplace_back(signed_distance_field::signedDistanceAtHeight(map, h, resolution)); -// } - switched_model::SegmentedPlanesSignedDistanceField sdf(gridMap, layer, minHeight, maxHeight); - - // ========================================================= - } - auto t3 = std::chrono::high_resolution_clock::now(); - std::cout << "Sdf computation took " << 1e-3 * std::chrono::duration_cast(t3 - t2).count() / N << " [ms]\n"; -} \ No newline at end of file diff --git a/signed_distance_field/CMakeLists.txt b/signed_distance_field/CMakeLists.txt deleted file mode 100644 index c9490b9d..00000000 --- a/signed_distance_field/CMakeLists.txt +++ /dev/null @@ -1,77 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(signed_distance_field) - -# Catkin dependencies -set(CATKIN_PACKAGE_DEPENDENCIES - grid_map_core - pcl_ros -) - -find_package(catkin REQUIRED COMPONENTS - ${CATKIN_PACKAGE_DEPENDENCIES} -) - -# Cpp standard version -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -################################### -## catkin specific configuration ## -################################### -catkin_package( - INCLUDE_DIRS include - LIBRARIES ${PROJECT_NAME} - CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS -) - -########### -## Build ## -########### - -include_directories( - include - ${catkin_INCLUDE_DIRS} -) - -add_library(${PROJECT_NAME} - src/GridmapSignedDistanceField.cpp - src/SignedDistance2d.cpp -) -add_dependencies(${PROJECT_NAME} - ${catkin_EXPORTED_TARGETS} -) -target_link_libraries(${PROJECT_NAME} - ${catkin_LIBRARIES} -) - - -############# -## Install ## -############# - -install(TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -) -install(DIRECTORY include/${PROJECT_NAME}/ - DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} -) - -############# -## Testing ## -############# - -add_executable(${PROJECT_NAME}_test - test/test3dLookup.cpp - test/testDerivatives.cpp - test/testPixelBorderDistance.cpp - test/testSignedDistance2d.cpp - test/testSignedDistance3d.cpp -) -target_link_libraries(${PROJECT_NAME}_test - ${catkin_LIBRARIES} - ${PROJECT_NAME} - gtest_main -) \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h b/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h deleted file mode 100644 index 455421b1..00000000 --- a/signed_distance_field/include/signed_distance_field/DistanceDerivatives.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * DistanceDerivatives.h - * - * Created on: Aug 10, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#pragma once - -#include - -namespace grid_map { -namespace signed_distance_field { - -/** - * Takes the columnwise central difference of a matrix. Uses single sided difference at the boundaries. - * diff = (col(i+1) - col(i-1)) / (2 * resolution) - * - * @param data [in] : data to take the difference of. - * @param centralDifference [out] : matrix to store the result in. - * @param resolution [in] : scaling of the distance between two columns. - */ -inline void columnwiseCentralDifference(const Matrix& data, Matrix& centralDifference, float resolution) { - assert(data.cols() >= 2); // Minimum size to take finite differences. - - const int m = data.cols(); - const float resInv = 1.0F / resolution; - const float doubleResInv = 1.0F / (2.0F * resolution); - - // First column - centralDifference.col(0) = resInv * (data.col(1) - data.col(0)); - - // All the middle columns - for (int i = 1; i + 1 < m; ++i) { - centralDifference.col(i) = doubleResInv * (data.col(i + 1) - data.col(i - 1)); - } - - // Last column - centralDifference.col(m - 1) = resInv * (data.col(m - 1) - data.col(m - 2)); -} - -/** - * Takes the finite difference between layers - * result = (data_{k+1} - data{k}) / resolution - */ -inline void layerFiniteDifference(const Matrix& data_k, const Matrix& data_kp1, Matrix& result, float resolution) { - const float resInv = 1.0F / resolution; - result = resInv * (data_kp1 - data_k); -} - -/** - * Takes the central difference between layers - * result = (data_{k+1} - data{k-1}) / (2.0 * resolution) - */ -inline void layerCentralDifference(const Matrix& data_km1, const Matrix& data_kp1, Matrix& result, float resolution) { - const float doubleResInv = 1.0F / (2.0F * resolution); - result = doubleResInv * (data_kp1 - data_km1); -} - -} // namespace signed_distance_field -} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h b/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h deleted file mode 100644 index 888a8a07..00000000 --- a/signed_distance_field/include/signed_distance_field/Gridmap3dLookup.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Gridmap3dLookup.h - * - * Created on: Aug 13, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#pragma once - -#include - -namespace grid_map { -namespace signed_distance_field { - -/** - * Stores 3 dimensional grid information and provides methods to convert between position - 3d Index - linear index. - * - * As with the 2D GridMap, the X-Y position is opposite to the row-col-index: (X,Y) is highest at (0,0) and lowest at (n, m). - * The z-position is increasing with the layer-index. - */ -struct Gridmap3dLookup { - public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW - /// size_t in 3 dimensions - struct size_t_3d { - size_t x; - size_t y; - size_t z; - }; - - //! 3D size of the grid - size_t_3d gridsize_; - - //! Origin position of the grid - Position3 gridOrigin_; - - //! Maximum index per dimension stored as double - Position3 gridMaxIndexAsDouble_; - - //! Grid resolution - double resolution_; - - /** - * Constructor - * @param gridsize : x, y, z size of the grid - * @param gridOrigin : position at x=y=z=0 - * @param resolution : (>0.0) size of 1 voxel - */ - Gridmap3dLookup(const size_t_3d& gridsize, const Position3& gridOrigin, double resolution) - : gridsize_(gridsize), - gridOrigin_(gridOrigin), - gridMaxIndexAsDouble_(static_cast(gridsize_.x - 1), static_cast(gridsize_.y - 1), - static_cast(gridsize_.z - 1)), - resolution_(resolution) { - assert(resolution_ > 0.0); - assert(gridsize_.x > 0); - assert(gridsize_.y > 0); - assert(gridsize_.z > 0); - }; - - /** Default constructor: creates an empty grid */ - Gridmap3dLookup() : Gridmap3dLookup({1, 1, 1}, {0.0, 0.0, 0.0}, 1.0) {} - - /** Returns the 3d index of the grid node closest to the query position */ - size_t_3d nearestNode(const Position3& position) const noexcept { - const double resInv = 1.0 / resolution_; - Position3 subpixelVector{(gridOrigin_.x() - position.x()) * resInv, (gridOrigin_.y() - position.y()) * resInv, - (position.z() - gridOrigin_.z()) * resInv}; - return {nearestPositiveInteger(subpixelVector.x(), gridMaxIndexAsDouble_.x()), - nearestPositiveInteger(subpixelVector.y(), gridMaxIndexAsDouble_.y()), - nearestPositiveInteger(subpixelVector.z(), gridMaxIndexAsDouble_.z())}; - } - - /** Returns the 3d node position from a 3d index */ - Position3 nodePosition(const size_t_3d& index) const noexcept { - return {gridOrigin_.x() - index.x * resolution_, gridOrigin_.y() - index.y * resolution_, gridOrigin_.z() + index.z * resolution_}; - } - - /** Returns the linear node index from a 3d node index */ - size_t linearIndex(const size_t_3d& index) const noexcept { return (index.z * gridsize_.y + index.y) * gridsize_.x + index.x; } - - /** Linear size */ - size_t linearSize() const noexcept { return gridsize_.x * gridsize_.y * gridsize_.z; } - - /** rounds subindex value and clamps it to [0, max] */ - static size_t nearestPositiveInteger(double val, double max) noexcept { - // Comparing bounds as double prevents underflow/overflow of size_t - return static_cast(std::max(0.0, std::min(std::round(val), max))); - } -}; - -} // namespace signed_distance_field -} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h b/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h deleted file mode 100644 index a970904c..00000000 --- a/signed_distance_field/include/signed_distance_field/GridmapSignedDistanceField.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * GridmapSignedDistanceField.h - * - * Created on: Jul 10, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#pragma once - -#include - -#include - -#include -#include - -#include -#include - -#include "Gridmap3dLookup.h" - -namespace grid_map { - -/** - * This class creates a dense 3D signed distance field grid for a given elevation map. - * The 3D grid uses the same resolution as the 2D map. i.e. all voxels are of size (resolution x resolution x resolution). - * The size of the 3D grid is the same as the map in XY direction. The size is Z direction is specified in the constructor. - * - * During the creation of the class all values and derivatives are pre-computed in one go. This makes repeated lookups very cheap. - * Querying a point outside of the constructed grid will result in linear extrapolation. - */ -class GridmapSignedDistanceField { - public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW - using Derivative3 = Eigen::Vector3d; - - /** - * Create a signed distance field and its derivative for an elevation layer in the grid map. - * - * @param gridMap : Input map to create the SDF for. - * @param elevationLayer : Name of the elevation layer. - * @param minHeight : Desired starting height of the 3D SDF grid. - * @param maxHeight : Desired ending height of the 3D SDF grid. (Will be rounded up to match the resolution) - */ - GridmapSignedDistanceField(const GridMap& gridMap, const std::string& elevationLayer, double minHeight, double maxHeight); - - /** - * Get the signed distance value at a 3D position. - * @param position : 3D position in the frame of the gridmap. - * @return signed distance to the elevation surface. - */ - double value(const Position3& position) const noexcept; - - /** - * Get the signed distance derivative at a 3D position. - * @param position : 3D position in the frame of the gridmap. - * @return derivative of the signed distance field. - */ - Derivative3 derivative(const Position3& position) const noexcept; - - /** - * Get both the signed distance value and derivative at a 3D position. - * @param position : 3D position in the frame of the gridmap. - * @return {value, derivative} of the signed distance field. - */ - std::pair valueAndDerivative(const Position3& position) const noexcept; - - /** - * Return the signed distance field as a pointcloud. The signed distance is assigned to the point's intensity. - * @param decimation : specifies how many points are returned. 1: all points, 2: every second point, etc. - * @param condition : specifies the condition on the distance value to add it to the pointcloud (default = any distance is added) - */ - pcl::PointCloud asPointCloud( - size_t decimation = 1, const std::function& condition = [](float) { return true; }) const; - - /** - * Return the signed distance field as a pointcloud where the distance is positive. - * @param decimation : specifies how many points are returned. 1: all points, 2: every second point, etc. - */ - pcl::PointCloud freeSpacePointCloud(size_t decimation = 1) const; - - /** - * Return the signed distance field as a pointcloud where the distance is negative. - * @param decimation : specifies how many points are returned. 1: all points, 2: every second point, etc. - */ - pcl::PointCloud obstaclePointCloud(size_t decimation = 1) const; - - private: - /** - * Implementation of the signed distance field computation in this class. - * @param elevation - */ - void computeSignedDistance(const Matrix& elevation); - - /** - * Simultaneously compute the signed distance and derivative in x direction at a given height - * @param elevation [in] : elevation data - * @param currentLayer [out] : signed distance values - * @param dxTranspose [out] : derivative in x direction (the matrix is transposed) - * @param sdfTranspose [tmp] : temporary variable to reuse between calls (allocated on first use) - * @param tmp [tmp] : temporary variable (allocated on first use) - * @param tmpTranspose [tmp] : temporary variable (allocated on first use) - * @param height [in] : height the signed distance is created for. - * @param resolution [in] : resolution of the map. - * @param minHeight [in] : smallest height value in the elevation data. - * @param maxHeight [in] : largest height value in the elevation data. - */ - void computeLayerSdfandDeltaX(const Matrix& elevation, Matrix& currentLayer, Matrix& dxTranspose, Matrix& sdfTranspose, Matrix& tmp, - Matrix& tmpTranspose, float height, float resolution, float minHeight, float maxHeight) const; - - /** - * Add the computed signed distance values and derivatives at a particular height to the grid. - * Adds the layer to the back of data_ - * @param signedDistance : signed distance values. - * @param dxTranspose : x components of the derivative (matrix is transposed). - * @param dy : y components of the derivative. - * @param dz : z components of the derivative. - */ - void emplacebackLayerData(const Matrix& signedDistance, const Matrix& dxTranspose, const Matrix& dy, const Matrix& dz); - - //! Data structure to store together {signed distance value, derivative}. - using node_data_t = std::array; - - /** Helper function to extract the sdf value */ - static double distance(const node_data_t& nodeData) noexcept { return nodeData[0]; } - - /** Helper function to extract the sdf value as float */ - static float distanceFloat(const node_data_t& nodeData) noexcept { return nodeData[0]; } - - /** Helper function to extract the sdf derivative */ - static Derivative3 derivative(const node_data_t& nodeData) noexcept { return {nodeData[1], nodeData[2], nodeData[3]}; } - - //! Object encoding the 3D grid. - signed_distance_field::Gridmap3dLookup gridmap3DLookup_; - - //! Object encoding the signed distance value and derivative in the grid. - std::vector data_; - - //! Frame id of the grid map. - std::string frameId_; - - //! Timestamp of the grid map (nanoseconds). - Time timestamp_; -}; - -} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h b/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h deleted file mode 100644 index a2c9f93d..00000000 --- a/signed_distance_field/include/signed_distance_field/PixelBorderDistance.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * PixelBorderDistance.h - * - * Created on: Aug 7, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#pragma once - -#include -#include -#include - -namespace grid_map { -namespace signed_distance_field { - -/** - * Returns distance between the center of a pixel and the border of an other pixel. - * Returns zero if the center is inside the other pixel. - * Pixels are assumed to have size 1.0F - * @param i : location of pixel 1 - * @param j : location of pixel 2 - * @return : absolute distance between center of pixel 1 and the border of pixel 2 - */ -inline float pixelBorderDistance(float i, float j) { - return std::max(std::abs(i - j) - 0.5F, 0.0F); -} - -/** - * Returns square pixelBorderDistance, adding offset f. - */ -inline float squarePixelBorderDistance(float i, float j, float f) { - float d = pixelBorderDistance(i, j); - return d * d + f; -} - -namespace internal { - -/** - * Return equidistancepoint between origin and pixel p (with p > 0) with offset fp - */ -inline float intersectionPointRightSideOfOrigin(float p, float fp) { - /* - * There are 5 different solutions - * In decreasing order: - * sol 1 in [p^2, inf] - * sol 2 in [bound, p^2] - * sol 3 in [-bound, bound] - * sol 4 in [-p^2, -bound] - * sol 5 in [-inf, -p^2] - */ - auto pSquared = p * p; - if (fp > pSquared) { - return (pSquared + p + fp) / (2.0F * p); // sol 1 - } else if (fp < -pSquared) { - return (pSquared - p + fp) / (2.0F * p); // sol 5 - } else { - const float bound = pSquared - 2.0F * p + 1.0F; // Always positive because (p > 0) - if (fp > bound) { - return 0.5F + std::sqrt(fp); // sol 2 - } else if (fp < -bound) { - return p - 0.5F - std::sqrt(-fp); // sol 4 - } else { - return (pSquared - p + fp) / (2.0F * p - 2.0F); // sol 3 - } - } -} - -/** - * Return equidistancepoint between origin and pixel p with offset fp - */ -inline float intersectionOffsetFromOrigin(float p, float fp) { - if (p > 0.0F) { - return intersectionPointRightSideOfOrigin(p, fp); - } else { - // call with negative p and flip the result - return -intersectionPointRightSideOfOrigin(-p, fp); - } -} - -} // namespace internal - -/** - * Return the point s in pixel space that is equally far from p and q (taking into account offsets fp, and fq) - * It is the solution to the following equation: - * squarePixelBorderDistance(s, q, fq) == squarePixelBorderDistance(s, p, fp) - */ -inline float equidistancePoint(float q, float fq, float p, float fp) { - assert(q == p || - std::abs(q - p) >= 1.0F); // Check that q and p are proper pixel locations: either the same pixel or non-overlapping pixels - assert((q == p) ? fp == fq : true); // Check when q and p are equal, the offsets are also equal - - if (fp == fq) { // quite common case when both pixels are of the same class (occupied / free) - return 0.5F * (p + q); - } else { - float df = fp - fq; - float dr = p - q; - return internal::intersectionOffsetFromOrigin(dr, df) + q; - } -} - -} // namespace signed_distance_field -} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h b/signed_distance_field/include/signed_distance_field/SignedDistance2d.h deleted file mode 100644 index 16bbb916..00000000 --- a/signed_distance_field/include/signed_distance_field/SignedDistance2d.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * SignedDistance2d.h - * - * Created on: Jul 10, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#pragma once - -#include - -#include - -#include "Utils.h" - -namespace grid_map { -namespace signed_distance_field { - -/** - * Computes the signed distance field at a specified height for a given elevation map. - * - * @param elevationMap : elevation data. - * @param height : height to generate the signed distance at. - * @param resolution : resolution of the elevation map. (The true distance [m] between cells in world frame) - * @param minHeight : the lowest height contained in elevationMap - * @param maxHeight : the maximum height contained in elevationMap - * @return The signed distance field at the query height. - */ -Matrix signedDistanceAtHeight(const Matrix& elevationMap, float height, float resolution, float minHeight, float maxHeight); - -/** - * Same as above, but returns the sdf in transposed form. - * Also takes temporary variables from outside to prevent memory allocation. - * - * @param elevationMap : elevation data. - * @param sdfTranspose : [output] resulting sdf in transposed form (automatically allocated if of wrong size) - * @param tmp : temporary of size elevationMap (automatically allocated if of wrong size) - * @param tmpTranspose : temporary of size elevationMap transpose (automatically allocated if of wrong size) - * @param height : height to generate the signed distance at. - * @param resolution : resolution of the elevation map. (The true distance [m] between cells in world frame) - * @param minHeight : the lowest height contained in elevationMap - * @param maxHeight : the maximum height contained in elevationMap - */ -void signedDistanceAtHeightTranspose(const Matrix& elevationMap, Matrix& sdfTranspose, Matrix& tmp, Matrix& tmpTranspose, float height, - float resolution, float minHeight, float maxHeight); - -/** - * Gets the 2D signed distance from an occupancy grid. - * Returns +INF if there are no obstacles, and -INF if there are only obstacles - * - * @param occupancyGrid : occupancy grid with true = obstacle, false = free space - * @param resolution : resolution of the grid. - * @return signed distance for each point in the grid to the occupancy border. - */ -Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution); - -} // namespace signed_distance_field -} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/include/signed_distance_field/Utils.h b/signed_distance_field/include/signed_distance_field/Utils.h deleted file mode 100644 index bc753907..00000000 --- a/signed_distance_field/include/signed_distance_field/Utils.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Utils.h - * - * Created on: Jul 10, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#pragma once - -namespace grid_map { -namespace signed_distance_field { - -//! Distance value that is considered infinite. Needs to be well below numeric_limits::max to avoid overflow in computation involving ^2 -constexpr float INF = 1e15; - -} // namespace signed_distance_field -} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/package.xml b/signed_distance_field/package.xml deleted file mode 100644 index a6ba2663..00000000 --- a/signed_distance_field/package.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - signed_distance_field - 0.0.0 - The signed_distance_field package - - Ruben Grandia - - TODO - - catkin - - grid_map_core - pcl_ros - - diff --git a/signed_distance_field/src/GridmapSignedDistanceField.cpp b/signed_distance_field/src/GridmapSignedDistanceField.cpp deleted file mode 100644 index cb2b56aa..00000000 --- a/signed_distance_field/src/GridmapSignedDistanceField.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * GridmapSignedDistanceField.cpp - * - * Created on: Jul 10, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#include "signed_distance_field/GridmapSignedDistanceField.h" - -#include - -#include "signed_distance_field/DistanceDerivatives.h" -#include "signed_distance_field/SignedDistance2d.h" - -namespace grid_map { - -// Import from the signed_distance_field namespace -using signed_distance_field::columnwiseCentralDifference; -using signed_distance_field::Gridmap3dLookup; -using signed_distance_field::layerCentralDifference; -using signed_distance_field::layerFiniteDifference; -using signed_distance_field::signedDistanceAtHeightTranspose; - -GridmapSignedDistanceField::GridmapSignedDistanceField(const GridMap& gridMap, const std::string& elevationLayer, double minHeight, - double maxHeight) - : frameId_(gridMap.getFrameId()), timestamp_(gridMap.getTimestamp()) { - assert(maxHeight >= minHeight); - - // Determine origin of the 3D grid - Position mapOriginXY; - gridMap.getPosition(Eigen::Vector2i(0, 0), mapOriginXY); - Position3 gridOrigin(mapOriginXY.x(), mapOriginXY.y(), minHeight); - - // Round up the Z-discretization. We need a minimum of two layers to enable finite difference in Z direction - const auto numZLayers = static_cast(std::max(std::ceil((maxHeight - minHeight) / gridMap.getResolution()), 2.0)); - const size_t numXrows = gridMap.getSize().x(); - const size_t numYrows = gridMap.getSize().y(); - Gridmap3dLookup::size_t_3d gridsize = {numXrows, numYrows, numZLayers}; - - // Initialize 3D lookup - gridmap3DLookup_ = Gridmap3dLookup(gridsize, gridOrigin, gridMap.getResolution()); - - // Allocate the internal data structure - data_.reserve(gridmap3DLookup_.linearSize()); - - // Check for NaN - const auto& elevationData = gridMap.get(elevationLayer); - if (elevationData.hasNaN()) { - std::cerr << "[GridmapSignedDistanceField] elevation data contains NaN. The generated SDF will be invalid! Apply inpainting first" - << std::endl; - } - - // Compute the SDF - computeSignedDistance(elevationData); -} - -double GridmapSignedDistanceField::value(const Position3& position) const noexcept { - const auto nodeIndex = gridmap3DLookup_.nearestNode(position); - const auto nodePosition = gridmap3DLookup_.nodePosition(nodeIndex); - const auto nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; - const auto jacobian = derivative(nodeData); - return distance(nodeData) + jacobian.dot(position - nodePosition); -} - -GridmapSignedDistanceField::Derivative3 GridmapSignedDistanceField::derivative(const Position3& position) const noexcept { - const auto nodeIndex = gridmap3DLookup_.nearestNode(position); - const auto nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; - return derivative(nodeData); -} - -std::pair GridmapSignedDistanceField::valueAndDerivative( - const Position3& position) const noexcept { - const auto nodeIndex = gridmap3DLookup_.nearestNode(position); - const auto nodePosition = gridmap3DLookup_.nodePosition(nodeIndex); - const auto nodeData = data_[gridmap3DLookup_.linearIndex(nodeIndex)]; - const auto jacobian = derivative(nodeData); - return {distance(nodeData) + jacobian.dot(position - nodePosition), jacobian}; -} - -void GridmapSignedDistanceField::computeSignedDistance(const Matrix& elevation) { - const auto gridOriginZ = static_cast(gridmap3DLookup_.gridOrigin_.z()); - const auto resolution = static_cast(gridmap3DLookup_.resolution_); - const auto minHeight = elevation.minCoeff(); - const auto maxHeight = elevation.maxCoeff(); - - /* - * General strategy to reduce the amount of transposing: - * - SDF at a height is in transposed form after computing it. - * - Take the finite difference in dx, now that this data is continuous in memory. - * - Transpose the SDF - * - Take other finite differences. Now dy is efficient. - * - When writing to the 3D structure, keep in mind that dx is still transposed. - */ - - // Memory needed to compute the SDF at a layer - Matrix tmp; // allocated on first use - Matrix tmpTranspose; // allocated on first use - Matrix sdfTranspose; // allocated on first use - - // Memory needed to keep a buffer of layers. We need 3 due to the central difference - Matrix currentLayer; // allocated on first use - Matrix nextLayer; // allocated on first use - Matrix previousLayer; // allocated on first use - - // Memory needed to compute finite differences - Matrix dxTranspose = Matrix::Zero(elevation.cols(), elevation.rows()); - Matrix dxNextTranspose = Matrix::Zero(elevation.cols(), elevation.rows()); - Matrix dy = Matrix::Zero(elevation.rows(), elevation.cols()); - Matrix dz = Matrix::Zero(elevation.rows(), elevation.cols()); - - // Compute SDF of first layer - computeLayerSdfandDeltaX(elevation, currentLayer, dxTranspose, sdfTranspose, tmp, tmpTranspose, gridOriginZ, resolution, minHeight, - maxHeight); - - // Compute SDF of second layer - computeLayerSdfandDeltaX(elevation, nextLayer, dxNextTranspose, sdfTranspose, tmp, tmpTranspose, gridOriginZ + resolution, resolution, - minHeight, maxHeight); - - // First layer: forward difference in z - layerFiniteDifference(currentLayer, nextLayer, dz, resolution); // dz / layer = +resolution - columnwiseCentralDifference(currentLayer, dy, -resolution); // dy / dcol = -resolution - - emplacebackLayerData(currentLayer, dxTranspose, dy, dz); - - // Middle layers: central difference in z - for (size_t layerZ = 1; layerZ + 1 < gridmap3DLookup_.gridsize_.z; ++layerZ) { - // Circulate layer buffers - previousLayer.swap(currentLayer); - currentLayer.swap(nextLayer); - dxTranspose.swap(dxNextTranspose); - - // Compute SDF of next layer - computeLayerSdfandDeltaX(elevation, nextLayer, dxNextTranspose, sdfTranspose, tmp, tmpTranspose, - gridOriginZ + (layerZ + 1) * resolution, resolution, minHeight, maxHeight); - - // Compute other finite differences - layerCentralDifference(previousLayer, nextLayer, dz, resolution); - columnwiseCentralDifference(currentLayer, dy, -resolution); - - // Add the data to the 3D structure - emplacebackLayerData(currentLayer, dxTranspose, dy, dz); - } - - // Circulate layer buffers one last time - previousLayer.swap(currentLayer); - currentLayer.swap(nextLayer); - dxTranspose.swap(dxNextTranspose); - - // Last layer: backward difference in z - layerFiniteDifference(previousLayer, currentLayer, dz, resolution); - columnwiseCentralDifference(currentLayer, dy, -resolution); - - // Add the data to the 3D structure - emplacebackLayerData(currentLayer, dxTranspose, dy, dz); -} - -void GridmapSignedDistanceField::computeLayerSdfandDeltaX(const Matrix& elevation, Matrix& currentLayer, Matrix& dxTranspose, - Matrix& sdfTranspose, Matrix& tmp, Matrix& tmpTranspose, float height, - float resolution, float minHeight, float maxHeight) const { - // Compute SDF + dx of layer: compute sdfTranspose -> take dxTranspose -> transpose to get sdf - signedDistanceAtHeightTranspose(elevation, sdfTranspose, tmp, tmpTranspose, height, resolution, minHeight, maxHeight); - columnwiseCentralDifference(sdfTranspose, dxTranspose, -resolution); // dx / drow = -resolution - currentLayer = sdfTranspose.transpose(); -} - -void GridmapSignedDistanceField::emplacebackLayerData(const Matrix& signedDistance, const Matrix& dxdxTranspose, const Matrix& dy, - const Matrix& dz) { - for (size_t colY = 0; colY < gridmap3DLookup_.gridsize_.y; ++colY) { - for (size_t rowX = 0; rowX < gridmap3DLookup_.gridsize_.x; ++rowX) { - data_.emplace_back(node_data_t{signedDistance(rowX, colY), dxdxTranspose(colY, rowX), dy(rowX, colY), dz(rowX, colY)}); - } - } -} - -pcl::PointCloud GridmapSignedDistanceField::asPointCloud(size_t decimation, - const std::function& condition) const { - pcl::PointCloud points; - - // Convert Gridmap time -> ros time -> pcl time - points.header.stamp = pcl_conversions::toPCL(ros::Time().fromNSec(timestamp_)); - points.header.frame_id = frameId_; - - points.reserve(gridmap3DLookup_.linearSize()); - for (size_t layerZ = 0; layerZ < gridmap3DLookup_.gridsize_.z; layerZ += decimation) { - for (size_t colY = 0; colY < gridmap3DLookup_.gridsize_.y; colY += decimation) { - for (size_t rowX = 0; rowX < gridmap3DLookup_.gridsize_.x; rowX += decimation) { - const Gridmap3dLookup::size_t_3d index3d = {rowX, colY, layerZ}; - const auto index = gridmap3DLookup_.linearIndex(index3d); - const auto signeddistance = distanceFloat(data_[index]); - if (condition(signeddistance)) { - const auto p = gridmap3DLookup_.nodePosition(index3d); - pcl::PointXYZI point; - point.x = p.x(); - point.y = p.y(); - point.z = p.z(); - point.intensity = signeddistance; - points.push_back(point); - } - } - } - } - return points; -} - -pcl::PointCloud GridmapSignedDistanceField::freeSpacePointCloud(size_t decimation) const { - return asPointCloud(decimation, [](float signedDistance) { return signedDistance >= 0.0F; }); -} - -pcl::PointCloud GridmapSignedDistanceField::obstaclePointCloud(size_t decimation) const { - return asPointCloud(decimation, [](float signedDistance) { return signedDistance <= 0.0F; }); -} - -} // namespace grid_map diff --git a/signed_distance_field/src/SignedDistance2d.cpp b/signed_distance_field/src/SignedDistance2d.cpp deleted file mode 100644 index 4cafb909..00000000 --- a/signed_distance_field/src/SignedDistance2d.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/* - * SignedDistance2d.cpp - * - * Created on: Jul 10, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#include "signed_distance_field/SignedDistance2d.h" - -#include "signed_distance_field/PixelBorderDistance.h" - -namespace grid_map { -namespace signed_distance_field { - -namespace internal { -struct DistanceLowerBound { - float v; // origin of bounding function - float f; // functional offset at the origin - float z_lhs; // lhs of interval where this bound holds - float z_rhs; // rhs of interval where this lower bound holds -}; - -/** - * 1D Euclidean Distance Transform based on: http://cs.brown.edu/people/pfelzens/dt/ - * Adapted to work on Eigen objects directly - * Optimized computation of s. - * Some optimization to not keep track of bounds that lie fully outside the grid. - */ -std::vector::iterator fillLowerBounds(const Eigen::Ref& squareDistance1d, - std::vector& lowerBounds, Eigen::Index start) { - const auto n = squareDistance1d.size(); - const auto nFloat = static_cast(n); - const auto startFloat = static_cast(start); - - // Initialize - auto rhsBoundIt = lowerBounds.begin(); - *rhsBoundIt = DistanceLowerBound{startFloat, squareDistance1d[start], -INF, INF}; - auto firstBoundIt = lowerBounds.begin(); - - // Compute bounds to the right of minimum - float qFloat = rhsBoundIt->v + 1.0F; - for (Eigen::Index q = start + 1; q < n; ++q) { - // Storing this by value gives better performance (removed indirection?) - const float fq = squareDistance1d[q]; - - float s = equidistancePoint(qFloat, fq, rhsBoundIt->v, rhsBoundIt->f); - if (s < nFloat) { // Can ignore the lower bound derived from this point if it is only active outsize of [start, n] - // Search backwards in bounds until s is within [z_lhs, z_rhs] - while (s < rhsBoundIt->z_lhs) { - --rhsBoundIt; - s = equidistancePoint(qFloat, fq, rhsBoundIt->v, rhsBoundIt->f); - } - if (s > startFloat) { // Intersection is within [start, n]. Adjust current lowerbound and insert the new one after - rhsBoundIt->z_rhs = s; // Update the bound that comes before - ++rhsBoundIt; // insert new bound after. - *rhsBoundIt = DistanceLowerBound{qFloat, fq, s, INF}; // Valid from s till infinity - } else { // Intersection is outside [0, n]. This means that the new bound dominates all previous bounds - *rhsBoundIt = DistanceLowerBound{qFloat, fq, -INF, INF}; - firstBoundIt = rhsBoundIt; // No need to keep other bounds, so update the first bound iterator to this one. - } - } - - // Increment to follow loop counter as float - qFloat += 1.0F; - } - - return firstBoundIt; -} - -void extractSquareDistances(Eigen::Ref squareDistance1d, std::vector::const_iterator lowerBoundIt, - Eigen::Index start) { - const auto n = squareDistance1d.size(); - - // Store active bound by value to remove indirection - auto lastz = lowerBoundIt->z_rhs; - - auto qFloat = static_cast(start); - for (Eigen::Index q = start; q < n; ++q) { - if (squareDistance1d[q] > 0.0F) { // Observe that if squareDistance1d[q] == 0.0, this is already the minimum and it will stay 0.0 - // Find the new active lower bound if q no longer belongs to current interval - if (qFloat > lastz) { - do { - ++lowerBoundIt; - } while (lowerBoundIt->z_rhs < qFloat); - lastz = lowerBoundIt->z_rhs; - } - - squareDistance1d[q] = squarePixelBorderDistance(qFloat, lowerBoundIt->v, lowerBoundIt->f); - } - - qFloat += 1.0F; - } -} - -/** - * Same as extractSquareDistances, but takes the sqrt as a final step. - * Because several cells will have a value of 0.0 (obstacle / free space label), we can skip the sqrt computation for those. - */ -void extractDistances(Eigen::Ref squareDistance1d, std::vector::const_iterator lowerBoundIt, - Eigen::Index start) { - const auto n = squareDistance1d.size(); - - // Store active bound by value to remove indirection - auto lastz = lowerBoundIt->z_rhs; - - auto qFloat = static_cast(start); - for (Eigen::Index q = start; q < n; ++q) { - if (squareDistance1d[q] > 0.0F) { // Observe that if squareDistance1d[q] == 0.0, this is already the minimum and it will stay 0.0 - // Find the new active lower bound if q no longer belongs to current interval - if (qFloat > lastz) { - do { - ++lowerBoundIt; - } while (lowerBoundIt->z_rhs < qFloat); - lastz = lowerBoundIt->z_rhs; - } - - squareDistance1d[q] = std::sqrt(squarePixelBorderDistance(qFloat, lowerBoundIt->v, lowerBoundIt->f)); - } - - qFloat += 1.0F; - } -} - -/** - * Find the location of the last zero value from the front - */ -Eigen::Index lastZeroFromFront(const Eigen::Ref& squareDistance1d) { - const auto n = squareDistance1d.size(); - - for (Eigen::Index q = 0; q < n; ++q) { - if (squareDistance1d[q] > 0.0F) { - if (q > 0) { - return q - 1; - } else { - return 0; - } - } - } - return n; -} - -inline void squaredDistanceTransform_1d_inplace(Eigen::Ref squareDistance1d, - std::vector& lowerBounds) { - auto start = lastZeroFromFront(squareDistance1d); - - // Only need to process line if there are nonzero elements. Also the first zeros stay untouched. - if (start < squareDistance1d.size()) { - auto startIt = fillLowerBounds(squareDistance1d, lowerBounds, start); - extractSquareDistances(squareDistance1d, startIt, start); - } -} - -/** - * Same as above, but takes sqrt as final step (within the same loop) - * @param squareDistance1d : input as squared distance, output is the distance after sqrt. - * @param lowerBounds : work vector - */ -inline void distanceTransform_1d_inplace(Eigen::Ref squareDistance1d, std::vector& lowerBounds) { - auto start = lastZeroFromFront(squareDistance1d); - - // Only need to process line if there are nonzero elements. Also the first zeros stay untouched. - if (start < squareDistance1d.size()) { - auto startIt = fillLowerBounds(squareDistance1d, lowerBounds, start); - extractDistances(squareDistance1d, startIt, start); - } -} - -void computePixelDistance2dTranspose(Matrix& input, Matrix& distanceTranspose) { - const auto n = input.rows(); - const auto m = input.cols(); - - // Allocate a buffer big enough for processing both rowise and columnwise - std::vector lowerBounds(std::max(n, m)); - - // Process columns - for (Eigen::Index i = 0; i < m; ++i) { - squaredDistanceTransform_1d_inplace(input.col(i), lowerBounds); - } - - // Process rows (= columns after transpose). - distanceTranspose = input.transpose(); - for (Eigen::Index i = 0; i < n; ++i) { - // Fuses square distance algorithm and taking sqrt. - distanceTransform_1d_inplace(distanceTranspose.col(i), lowerBounds); - } -} - -// Initialize with square distance in height direction in pixel units if above the surface -void initializeObstacleDistance(const Matrix& elevationMap, Matrix& result, float height, float resolution) { - /* Vectorized implementation of: - * if (height > elevation) { - * const auto diff = (height - elevation) / resolution; - * return diff * diff; - * } else { - * return 0.0F; - * } - */ - result = ((1.0F / resolution) * (height - elevationMap.array()).cwiseMax(0.0F)).square(); -} - -// Initialize with square distance in height direction in pixel units if below the surface -void initializeObstacleFreeDistance(const Matrix& elevationMap, Matrix& result, float height, float resolution) { - /* Vectorized implementation of: - * if (height < elevation) { - * const auto diff = (height - elevation) / resolution; - * return diff * diff; - * } else { - * return 0.0F; - * } - */ - result = ((1.0F / resolution) * (height - elevationMap.array()).cwiseMin(0.0F)).square(); -} - -void pixelDistanceToFreeSpaceTranspose(const Matrix& elevationMap, Matrix& sdfObstacleFree, Matrix& tmp, float height, float resolution) { - internal::initializeObstacleFreeDistance(elevationMap, tmp, height, resolution); - internal::computePixelDistance2dTranspose(tmp, sdfObstacleFree); -} - -void pixelDistanceToObstacleTranspose(const Matrix& elevationMap, Matrix& sdfObstacleTranspose, Matrix& tmp, float height, - float resolution) { - internal::initializeObstacleDistance(elevationMap, tmp, height, resolution); - internal::computePixelDistance2dTranspose(tmp, sdfObstacleTranspose); -} - -Matrix signedDistanceFromOccupancyTranspose(const Eigen::Matrix& occupancyGrid, float resolution) { - // Compute pixel distance to obstacles - Matrix sdfObstacle; - Matrix init = occupancyGrid.unaryExpr([=](bool val) { return (val) ? 0.0F : INF; }); - internal::computePixelDistance2dTranspose(init, sdfObstacle); - - // Compute pixel distance to obstacle free space - Matrix sdfObstacleFree; - init = occupancyGrid.unaryExpr([=](bool val) { return (val) ? INF : 0.0F; }); - internal::computePixelDistance2dTranspose(init, sdfObstacleFree); - - return resolution * (sdfObstacle - sdfObstacleFree); -} - -} // namespace internal - -void signedDistanceAtHeightTranspose(const Matrix& elevationMap, Matrix& sdfTranspose, Matrix& tmp, Matrix& tmpTranspose, float height, - float resolution, float minHeight, float maxHeight) { - const bool allPixelsAreObstacles = height < minHeight; - const bool allPixelsAreFreeSpace = height > maxHeight; - - if (allPixelsAreObstacles) { - internal::pixelDistanceToFreeSpaceTranspose(elevationMap, sdfTranspose, tmp, height, resolution); - - sdfTranspose *= -resolution; - } else if (allPixelsAreFreeSpace) { - internal::pixelDistanceToObstacleTranspose(elevationMap, sdfTranspose, tmp, height, resolution); - - sdfTranspose *= resolution; - } else { // This layer contains a mix of obstacles and free space - internal::pixelDistanceToObstacleTranspose(elevationMap, sdfTranspose, tmp, height, resolution); - internal::pixelDistanceToFreeSpaceTranspose(elevationMap, tmpTranspose, tmp, height, resolution); - - sdfTranspose = resolution * (sdfTranspose - tmpTranspose); - } -} - -Matrix signedDistanceAtHeight(const Matrix& elevationMap, float height, float resolution, float minHeight, float maxHeight) { - Matrix sdfTranspose; - Matrix tmp; - Matrix tmpTranspose; - - signedDistanceAtHeightTranspose(elevationMap, sdfTranspose, tmp, tmpTranspose, height, resolution, minHeight, maxHeight); - return sdfTranspose.transpose(); -} - -Matrix signedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution) { - auto obstacleCount = occupancyGrid.count(); - bool hasObstacles = obstacleCount > 0; - if (hasObstacles) { - bool hasFreeSpace = obstacleCount < occupancyGrid.size(); - if (hasFreeSpace) { - return internal::signedDistanceFromOccupancyTranspose(occupancyGrid, resolution).transpose(); - } else { - // Only obstacles -> distance is minus infinity everywhere - return Matrix::Constant(occupancyGrid.rows(), occupancyGrid.cols(), -INF); - } - } else { - // No obstacles -> planar distance is infinite - return Matrix::Constant(occupancyGrid.rows(), occupancyGrid.cols(), INF); - } -} - -} // namespace signed_distance_field -} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/test/naiveSignedDistance.h b/signed_distance_field/test/naiveSignedDistance.h deleted file mode 100644 index a7927b7e..00000000 --- a/signed_distance_field/test/naiveSignedDistance.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * naiveSignedDistance.h - * - * Created on: Aug 10, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#pragma once - -namespace grid_map { -namespace signed_distance_field { - -inline Eigen::Matrix occupancyAtHeight(const Matrix& elevationMap, float height) { - Eigen::Matrix occupany = elevationMap.unaryExpr([=](float val) { return val > height; }); - return occupany; -} - -inline bool isEqualSdf(const Matrix& sdf0, const Matrix& sdf1, float tol) { - Matrix error = (sdf0 - sdf1).array().abs(); - float maxDifference = error.maxCoeff(); - return maxDifference < tol; -} - -// N^2 naive implementation, for testing purposes -inline Matrix naiveSignedDistanceAtHeight(const Matrix& elevationMap, float height, float resolution) { - Matrix signedDistance(elevationMap.rows(), elevationMap.cols()); - - // For each point - for (int row = 0; row < elevationMap.rows(); ++row) { - for (int col = 0; col < elevationMap.cols(); ++col) { - if (elevationMap(row, col) >= height) { // point is below surface - signedDistance(row, col) = -INF; - // find closest open space over all other points - for (int i = 0; i < elevationMap.rows(); ++i) { - for (int j = 0; j < elevationMap.cols(); ++j) { - // Compute distance to free cube at location (i, j) - float dx = resolution * pixelBorderDistance(i, row); - float dy = resolution * pixelBorderDistance(j, col); - float dz = std::max(elevationMap(i, j) - height, 0.0F); - float currentSignedDistance = -std::sqrt(dx * dx + dy * dy + dz * dz); - signedDistance(row, col) = std::max(signedDistance(row, col), currentSignedDistance); - } - } - } else { // point is above surface - signedDistance(row, col) = INF; - // find closest object over all other points - for (int i = 0; i < elevationMap.rows(); ++i) { - for (int j = 0; j < elevationMap.cols(); ++j) { - // Compute distance to occupied cube at location (i, j) - float dx = resolution * pixelBorderDistance(i, row); - float dy = resolution * pixelBorderDistance(j, col); - float dz = std::max(height - elevationMap(i, j), 0.0F); - float currentSignedDistance = std::sqrt(dx * dx + dy * dy + dz * dz); - signedDistance(row, col) = std::min(signedDistance(row, col), currentSignedDistance); - } - } - } - } - } - - return signedDistance; -} - -inline Matrix naiveSignedDistanceFromOccupancy(const Eigen::Matrix& occupancyGrid, float resolution) { - Matrix signedDistance(occupancyGrid.rows(), occupancyGrid.cols()); - - // For each point - for (int row = 0; row < occupancyGrid.rows(); ++row) { - for (int col = 0; col < occupancyGrid.cols(); ++col) { - if (occupancyGrid(row, col)) { // This point is an obstable - signedDistance(row, col) = -INF; - // find closest open space over all other points - for (int i = 0; i < occupancyGrid.rows(); ++i) { - for (int j = 0; j < occupancyGrid.cols(); ++j) { - if (!occupancyGrid(i, j)) { - float dx = resolution * pixelBorderDistance(i, row); - float dy = resolution * pixelBorderDistance(j, col); - float currentSignedDistance = -std::sqrt(dx * dx + dy * dy); - signedDistance(row, col) = std::max(signedDistance(row, col), currentSignedDistance); - } - } - } - } else { // This point is in free space - signedDistance(row, col) = INF; - // find closest object over all other points - for (int i = 0; i < occupancyGrid.rows(); ++i) { - for (int j = 0; j < occupancyGrid.cols(); ++j) { - if (occupancyGrid(i, j)) { - float dx = resolution * pixelBorderDistance(i, row); - float dy = resolution * pixelBorderDistance(j, col); - float currentSignedDistance = std::sqrt(dx * dx + dy * dy); - signedDistance(row, col) = std::min(signedDistance(row, col), currentSignedDistance); - } - } - } - } - } - } - - return signedDistance; -} - -} // namespace signed_distance_field -} // namespace grid_map \ No newline at end of file diff --git a/signed_distance_field/test/test3dLookup.cpp b/signed_distance_field/test/test3dLookup.cpp deleted file mode 100644 index 35b42f8d..00000000 --- a/signed_distance_field/test/test3dLookup.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * test3dLookup.cpp - * - * Created on: Aug 18, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#include - -#include "signed_distance_field/Gridmap3dLookup.h" - -using namespace grid_map; -using namespace signed_distance_field; -using size_t_3d = Gridmap3dLookup::size_t_3d; - -TEST(testGridmap3dLookup, nearestNode) { - const size_t_3d gridsize{8, 9, 10}; - const Position3 gridOrigin{-0.1, -0.2, -0.4}; - const double resolution = 0.1; - - Gridmap3dLookup gridmap3DLookup(gridsize, gridOrigin, resolution); - - // Retreive origin - const size_t_3d originNode = gridmap3DLookup.nearestNode(gridOrigin); - ASSERT_EQ(originNode.x, 0); - ASSERT_EQ(originNode.y, 0); - ASSERT_EQ(originNode.z, 0); - - // test underflow - const size_t_3d originNodeProjected = gridmap3DLookup.nearestNode(gridOrigin + Position3{1e20, 1e20, -1e20}); - ASSERT_EQ(originNodeProjected.x, 0); - ASSERT_EQ(originNodeProjected.y, 0); - ASSERT_EQ(originNodeProjected.z, 0); - - // test overflow - const size_t_3d maxNodeProjected = gridmap3DLookup.nearestNode(gridOrigin + Position3{-1e20, -1e20, +1e20}); - ASSERT_EQ(maxNodeProjected.x, gridsize.x - 1); - ASSERT_EQ(maxNodeProjected.y, gridsize.y - 1); - ASSERT_EQ(maxNodeProjected.z, gridsize.z - 1); - - // Nearest neighbour - const size_t_3d nodeIndex{3, 4, 5}; - const Position3 nodePosition = gridmap3DLookup.nodePosition(nodeIndex); - const size_t_3d closestNodeIndex = gridmap3DLookup.nearestNode(nodePosition + 0.49 * Position3::Constant(resolution)); - ASSERT_EQ(closestNodeIndex.x, nodeIndex.x); - ASSERT_EQ(closestNodeIndex.y, nodeIndex.y); - ASSERT_EQ(closestNodeIndex.z, nodeIndex.z); -} - -TEST(testGridmap3dLookup, linearIndex) { - const size_t_3d gridsize{8, 9, 10}; - const Position3 gridOrigin{-0.1, -0.2, -0.4}; - const double resolution = 0.1; - - Gridmap3dLookup gridmap3DLookup(gridsize, gridOrigin, resolution); - ASSERT_EQ(gridmap3DLookup.linearIndex({0, 0, 0}), 0); - ASSERT_EQ(gridmap3DLookup.linearIndex({gridsize.x - 1, gridsize.y - 1, gridsize.z - 1}), gridmap3DLookup.linearSize() - 1); -} \ No newline at end of file diff --git a/signed_distance_field/test/testDerivatives.cpp b/signed_distance_field/test/testDerivatives.cpp deleted file mode 100644 index 8c1d4ab5..00000000 --- a/signed_distance_field/test/testDerivatives.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * testDerivatives.cpp - * - * Created on: Aug 10, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#include - -#include "signed_distance_field/DistanceDerivatives.h" - -using namespace grid_map; -using namespace signed_distance_field; - -TEST(testDerivatives, columnwise) { - Matrix data(2, 3); - data << 1.0, 2.0, 4.0, 2.0, 4.0, 6.0; - - float resolution = 0.1; - float doubleResolution = 2.0F * resolution; - - Matrix manualDifference(2, 3); - manualDifference << 1.0 / resolution, 3.0 / doubleResolution, 2.0 / resolution, 2.0 / resolution, 4.0 / doubleResolution, - 2.0 / resolution; - - Matrix computedDifference = Matrix::Zero(data.rows(), data.cols()); - columnwiseCentralDifference(data, computedDifference, resolution); - - ASSERT_TRUE(manualDifference.isApprox(computedDifference)); -} diff --git a/signed_distance_field/test/testPixelBorderDistance.cpp b/signed_distance_field/test/testPixelBorderDistance.cpp deleted file mode 100644 index 4456d6fe..00000000 --- a/signed_distance_field/test/testPixelBorderDistance.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * testPixelBorderDistance.cpp - * - * Created on: Aug 7, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#include - -#include "signed_distance_field/PixelBorderDistance.h" - -using namespace grid_map; -using namespace signed_distance_field; - -TEST(testPixelBorderDistance, distanceFunction) { - // Basic properties of the distance function - ASSERT_TRUE(pixelBorderDistance(0, 0) == 0.0F); - ASSERT_FLOAT_EQ(pixelBorderDistance(0, 1), 0.5); - ASSERT_FLOAT_EQ(pixelBorderDistance(0, 2), 1.5); - ASSERT_TRUE(pixelBorderDistance(0, 1) == pixelBorderDistance(1, 0)); - ASSERT_TRUE(pixelBorderDistance(-10, 42) == pixelBorderDistance(42, -10)); -} - -TEST(testPixelBorderDistance, equidistantPoint) { - int pixelRange = 10; - float offsetRange = 20.0; - float offsetStep = 0.25; - float tol = 1e-4; - - for (int p = -pixelRange; p < pixelRange; ++p) { - for (float fp = -offsetRange; fp < offsetRange; fp += offsetStep) { - for (int q = -pixelRange; q < pixelRange; ++q) { - for (float fq = -offsetRange; fq < offsetRange; fq += offsetStep) { - // Fix that offset is the same if pixels are the same - if (p == q) { - fp = fq; - } - // Check symmetry of the equidistant point computation - float s0 = equidistancePoint(q, fq, p, fp); - float s1 = equidistancePoint(p, fp, q, fq); - ASSERT_LT(std::abs(s0 - s1), tol); - - // Check that the distance from s0 to p and q is indeed equal - float dp = squarePixelBorderDistance(s0, p, fp); - float dq = squarePixelBorderDistance(s0, q, fq); - ASSERT_LT(std::abs(dp - dq), tol) << "p: " << p << ", q: " << q << ", fp: " << fp << ", fq: " << fq; - } - } - } - } -} diff --git a/signed_distance_field/test/testSignedDistance2d.cpp b/signed_distance_field/test/testSignedDistance2d.cpp deleted file mode 100644 index e3b920a5..00000000 --- a/signed_distance_field/test/testSignedDistance2d.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * testSignedDistance2d.cpp - * - * Created on: Jul 10, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#include - -#include "signed_distance_field/PixelBorderDistance.h" -#include "signed_distance_field/SignedDistance2d.h" - -#include "naiveSignedDistance.h" - -using namespace grid_map; -using namespace signed_distance_field; - -TEST(testSignedDistance2d, signedDistance2d_noObstacles) { - const int n = 3; - const int m = 4; - const float resolution = 0.1; - const Matrix map = Matrix::Ones(n, m); - - const auto occupancy = occupancyAtHeight(map, 2.0); - const auto signedDistance = signedDistanceFromOccupancy(occupancy, resolution); - - ASSERT_TRUE((signedDistance.array() == INF).all()); -} - -TEST(testSignedDistance2d, signedDistance2d_allObstacles) { - const int n = 3; - const int m = 4; - const float resolution = 0.1; - const Matrix map = Matrix::Ones(n, m); - - const auto occupancy = occupancyAtHeight(map, 0.0); - const auto signedDistance = signedDistanceFromOccupancy(occupancy, resolution); - - ASSERT_TRUE((signedDistance.array() == -INF).all()); -} - -TEST(testSignedDistance2d, signedDistance2d_mixed) { - const int n = 2; - const int m = 3; - const float resolution = 1.0; - Matrix map(n, m); - map << 0.0, 1.0, 1.0, 0.0, 0.0, 1.0; - const auto occupancy = occupancyAtHeight(map, 0.5); - - const auto naiveSignedDistance = naiveSignedDistanceFromOccupancy(occupancy, resolution); - const auto signedDistance = signedDistanceFromOccupancy(occupancy, resolution); - ASSERT_TRUE(isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)); -} - -TEST(testSignedDistance2d, signedDistance2d_oneObstacle) { - const int n = 20; - const int m = 30; - const float resolution = 0.1; - Matrix map = Matrix::Zero(n, m); - map(n / 2, m / 2) = 1.0; - const auto occupancy = occupancyAtHeight(map, 0.5); - - const auto naiveSignedDistance = naiveSignedDistanceFromOccupancy(occupancy, resolution); - const auto signedDistance = signedDistanceFromOccupancy(occupancy, resolution); - ASSERT_TRUE(isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)); -} - -TEST(testSignedDistance2d, signedDistance2d_oneFreeSpace) { - const int n = 20; - const int m = 30; - const float resolution = 0.1; - Matrix map = Matrix::Ones(n, m); - map(n / 2, m / 2) = 0.0; - - const auto occupancy = occupancyAtHeight(map, 0.5); - - const auto naiveSignedDistance = naiveSignedDistanceFromOccupancy(occupancy, resolution); - const auto signedDistance = signedDistanceFromOccupancy(occupancy, resolution); - ASSERT_TRUE(isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)); -} - -TEST(testSignedDistance2d, signedDistance2d_debugcase) { - const int n = 3; - const int m = 3; - const float resolution = 1.0; - Matrix map(n, m); - map << 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0; - - const auto occupancy = occupancyAtHeight(map, 0.5); - - const auto naiveSignedDistance = naiveSignedDistanceFromOccupancy(occupancy, resolution); - const auto signedDistance = signedDistanceFromOccupancy(occupancy, resolution); - ASSERT_TRUE(isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)); -} - -TEST(testSignedDistance2d, signedDistance2d_random) { - const int n = 20; - const int m = 30; - const float resolution = 1.0; - Matrix map = Matrix::Random(n, m); // random [-1.0, 1.0] - - // Check at different heights, resulting in different levels of sparsity. - float heightStep = 0.1; - for (float height = -1.0 - heightStep; height < 1.0 + heightStep; height += heightStep) { - const auto occupancy = occupancyAtHeight(map, height); - - const auto naiveSignedDistance = naiveSignedDistanceFromOccupancy(occupancy, resolution); - const auto signedDistance = signedDistanceFromOccupancy(occupancy, resolution); - ASSERT_TRUE(isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)) << "height: " << height; - } -} \ No newline at end of file diff --git a/signed_distance_field/test/testSignedDistance3d.cpp b/signed_distance_field/test/testSignedDistance3d.cpp deleted file mode 100644 index 01f26463..00000000 --- a/signed_distance_field/test/testSignedDistance3d.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - * testSignedDistance3d.cpp - * - * Created on: Aug 10, 2020 - * Author: Ruben Grandia - * Institute: ETH Zurich - */ - -#include - -#include "signed_distance_field/GridmapSignedDistanceField.h" -#include "signed_distance_field/PixelBorderDistance.h" -#include "signed_distance_field/SignedDistance2d.h" - -#include "naiveSignedDistance.h" - -using namespace grid_map; -using namespace signed_distance_field; - -TEST(testSignedDistance3d, flatTerrain) { - const int n = 3; - const int m = 4; - const float resolution = 0.1; - const float terrainHeight = 0.5; - const Matrix map = Matrix::Constant(n, m, terrainHeight); - const float minHeight = map.minCoeff(); - const float maxHeight = map.maxCoeff(); - - const float testHeightAboveTerrain = 3.0; - const auto naiveSignedDistanceAbove = naiveSignedDistanceAtHeight(map, testHeightAboveTerrain, resolution); - const auto signedDistanceAbove = signedDistanceAtHeight(map, testHeightAboveTerrain, resolution, minHeight, maxHeight); - ASSERT_TRUE(isEqualSdf(signedDistanceAbove, naiveSignedDistanceAbove, 1e-4)); - - const float testHeightBelowTerrain = -3.0; - const auto naiveSignedDistanceBelow = naiveSignedDistanceAtHeight(map, testHeightBelowTerrain, resolution); - const auto signedDistanceBelow = signedDistanceAtHeight(map, testHeightBelowTerrain, resolution, minHeight, maxHeight); - ASSERT_TRUE(isEqualSdf(signedDistanceBelow, naiveSignedDistanceBelow, 1e-4)); -} - -TEST(testSignedDistance3d, randomTerrain) { - const int n = 20; - const int m = 30; - const float resolution = 0.1; - Matrix map = Matrix::Random(n, m); // random [-1.0, 1.0] - const float minHeight = map.minCoeff(); - const float maxHeight = map.maxCoeff(); - - // Check at different heights, resulting in different levels of sparsity. - float heightStep = 0.1; - for (float height = -1.0 - heightStep; height < 1.0 + heightStep; height += heightStep) { - const auto naiveSignedDistance = naiveSignedDistanceAtHeight(map, height, resolution); - const auto signedDistance = signedDistanceAtHeight(map, height, resolution, minHeight, maxHeight); - - ASSERT_TRUE(isEqualSdf(signedDistance, naiveSignedDistance, 1e-4)) << "height: " << height; - } -} - -TEST(testSignedDistance3d, randomTerrainInterpolation) { - const int n = 20; - const int m = 30; - const float resolution = 0.1; - GridMap map; - map.setGeometry({n * resolution, m * resolution}, resolution); - map.add("elevation"); - map.get("elevation").setRandom(); // random [-1.0, 1.0] - const Matrix mapData = map.get("elevation"); - const float minHeight = mapData.minCoeff(); - const float maxHeight = mapData.maxCoeff(); - - GridmapSignedDistanceField sdf(map, "elevation", minHeight, maxHeight); - - // Check at different heights/ - for (float height = minHeight; height < maxHeight; height += resolution) { - const auto naiveSignedDistance = naiveSignedDistanceAtHeight(mapData, height, resolution); - - for (int i = 0; i < mapData.rows(); ++i) { - for (int j = 0; j < mapData.rows(); ++j) { - Position position2d; - map.getPosition({i, j}, position2d); - - const auto sdfValue = sdf.value({position2d.x(), position2d.y(), height}); - const auto sdfCheck = naiveSignedDistance(i, j); - ASSERT_LT(std::abs(sdfValue - sdfCheck), 1e-4); - } - } - } -} - -TEST(testSignedDistance3d, randomTerrainDerivative) { - const int n = 10; - const int m = 20; - const float resolution = 0.1; - GridMap map; - map.setGeometry({n * resolution, m * resolution}, resolution); - map.add("elevation"); - map.get("elevation").setRandom(); // random [-1.0, 1.0] - const Matrix mapData = map.get("elevation"); - const float minHeight = mapData.minCoeff(); - const float maxHeight = mapData.maxCoeff(); - - GridmapSignedDistanceField sdf(map, "elevation", minHeight, maxHeight); - - // Check at different heights/ - int numLayers = (maxHeight - minHeight) / resolution; - for (int k = 0; k <= numLayers; ++k) { - const float height = minHeight + k * resolution; - const auto naiveSignedDistance = naiveSignedDistanceAtHeight(mapData, height, resolution); - const auto naiveSignedDistanceNext = naiveSignedDistanceAtHeight(mapData, height + resolution, resolution); - const auto naiveSignedDistancePrevious = naiveSignedDistanceAtHeight(mapData, height - resolution, resolution); - - for (int i = 0; i < mapData.rows(); ++i) { - for (int j = 0; j < mapData.rows(); ++j) { - Position position2d; - map.getPosition({i, j}, position2d); - const auto sdfderivative = sdf.valueAndDerivative(Position3{position2d.x(), position2d.y(), height}); - const auto sdfCheck = naiveSignedDistance(i, j); - ASSERT_LT(std::abs(sdfderivative.first - sdfCheck), 1e-4); - - // Check finite difference - float dx = 0.0; - if (i > 0) { - if (i + 1 < mapData.rows()) { - dx = (naiveSignedDistance(i + 1, j) - naiveSignedDistance(i - 1, j)) / (-2.0 * resolution); - } else { - dx = (naiveSignedDistance(i, j) - naiveSignedDistance(i - 1, j)) / (-resolution); - } - } else { - dx = (naiveSignedDistance(i + 1, j) - naiveSignedDistance(i, j)) / (-resolution); - } - ASSERT_LT(std::abs(dx - sdfderivative.second.x()), 1e-4); - - float dy = 0.0; - if (j > 0) { - if (j + 1 < mapData.cols()) { - dy = (naiveSignedDistance(i, j + 1) - naiveSignedDistance(i, j - 1)) / (-2.0 * resolution); - } else { - dy = (naiveSignedDistance(i, j) - naiveSignedDistance(i, j - 1)) / (-resolution); - } - } else { - dy = (naiveSignedDistance(i, j + 1) - naiveSignedDistance(i, j)) / (-resolution); - } - ASSERT_LT(std::abs(dy - sdfderivative.second.y()), 1e-4); - - float dz = 0.0; - if (k > 0) { - if (k < numLayers) { - dz = (naiveSignedDistanceNext(i, j) - naiveSignedDistancePrevious(i, j)) / (2.0 * resolution); - } else { - dz = (naiveSignedDistance(i, j) - naiveSignedDistancePrevious(i, j)) / (resolution); - } - } else { - dz = (naiveSignedDistanceNext(i, j) - naiveSignedDistance(i, j)) / (resolution); - } - ASSERT_LT(std::abs(dz - sdfderivative.second.z()), 1e-4); - } - } - } -} - -TEST(testSignedDistance3d, extrapolation) { - const int n = 20; - const int m = 30; - const float resolution = 0.1; - const float h = 0.5; - GridMap map; - map.setGeometry({n * resolution, m * resolution}, resolution); - map.add("elevation"); - map.get("elevation").setConstant(h); // random [-1.0, 1.0] - const Matrix mapData = map.get("elevation"); - const float minHeight = h - resolution; - const float maxHeight = h + resolution; - - GridmapSignedDistanceField sdf(map, "elevation", minHeight, maxHeight); - - // Check at different heights/ - for (float height = h - 1.0; height < h + 1.0; height += resolution) { - const auto naiveSignedDistance = naiveSignedDistanceAtHeight(mapData, height, resolution); - - for (int i = 0; i < mapData.rows(); ++i) { - for (int j = 0; j < mapData.rows(); ++j) { - Position position2d; - map.getPosition({i, j}, position2d); - - const auto sdfValueAndDerivative = sdf.valueAndDerivative({position2d.x(), position2d.y(), height}); - const auto sdfCheck = naiveSignedDistance(i, j); - ASSERT_LT(std::abs(sdfValueAndDerivative.first - sdfCheck), 1e-4); - - // Constant terrain, derivative should be up everywhere - ASSERT_LT((sdfValueAndDerivative.second - GridmapSignedDistanceField::Derivative3::UnitZ()).norm(), 1e-4); - } - } - } -} \ No newline at end of file From 3efcc7665548a7f093ea07e094ce91dbe23200dd Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 7 Jun 2022 15:17:02 +0200 Subject: [PATCH 205/504] prepare plane_seg --- README.md => plane_segmentation/README.md | 0 .../cgal5_catkin}/.gitignore | 0 .../cgal5_catkin}/CMakeLists.txt | 0 .../cgal5_catkin}/README.md | 0 .../cgal5_catkin}/cmake/cgal-extras.cmake.in | 0 .../cgal5_catkin}/package.xml | 0 .../convex_plane_decomposition}/CMakeLists.txt | 0 .../ConvexRegionGrowing.h | 0 .../include/convex_plane_decomposition/Draw.h | 0 .../convex_plane_decomposition/GeometryUtils.h | 0 .../GridMapPreprocessing.h | 0 .../LoadGridmapFromImage.h | 0 .../convex_plane_decomposition/PlanarRegion.h | 0 .../PlaneDecompositionPipeline.h | 0 .../convex_plane_decomposition/PolygonTypes.h | 0 .../convex_plane_decomposition/Postprocessing.h | 0 .../convex_plane_decomposition/SegmentedPlanesMap.h | 0 .../include/convex_plane_decomposition/Timer.h | 0 .../contour_extraction/ContourExtraction.h | 0 .../ContourExtractionParameters.h | 0 .../contour_extraction/Upsampling.h | 0 .../ransac/RansacPlaneExtractor.hpp | 0 .../ransac/RansacPlaneExtractorParameters.h | 0 .../SlidingWindowPlaneExtractor.h | 0 .../SlidingWindowPlaneExtractorParameters.h | 0 .../convex_plane_decomposition}/package.xml | 0 .../src/ConvexRegionGrowing.cpp | 0 .../convex_plane_decomposition}/src/Draw.cpp | 0 .../src/GridMapPreprocessing.cpp | 0 .../src/LoadGridmapFromImage.cpp | 0 .../src/PlanarRegion.cpp | 0 .../src/PlaneDecompositionPipeline.cpp | 0 .../src/Postprocessing.cpp | 0 .../src/contour_extraction/ContourExtraction.cpp | 0 .../src/contour_extraction/Upsampling.cpp | 0 .../src/ransac/RansacPlaneExtractor.cpp | 0 .../SlidingWindowPlaneExtractor.cpp | 0 .../test/data/terrain.png | Bin .../test/testPipeline.cpp | 0 .../test/testPlanarRegion.cpp | 0 .../test/testRegionGrowing.cpp | 0 .../test/testUpsampling.cpp | 0 .../convex_plane_decomposition_msgs}/CMakeLists.txt | 0 .../msg/BoundingBox2d.msg | 0 .../msg/PlanarRegion.msg | 0 .../msg/PlanarTerrain.msg | 0 .../msg/Point2d.msg | 0 .../msg/Polygon2d.msg | 0 .../msg/PolygonWithHoles2d.msg | 0 .../convex_plane_decomposition_msgs}/package.xml | 0 .../convex_plane_decomposition_ros}/CMakeLists.txt | 0 .../config/demo_node.yaml | 0 .../config/node.yaml | 0 .../config/parameters.yaml | 0 .../config/standalone_node.yaml | 0 .../data/demo_map.png | Bin .../data/elevationMap_0_107cm.png | Bin .../data/elevationMap_0_148cm.png | Bin .../data/elevationMap_0_44cm.png | Bin .../data/elevationMap_10_277cm.png | Bin .../data/elevationMap_11_278cm.png | Bin .../data/elevationMap_8_139cm.png | Bin .../data/elevationMap_9_308cm.png | Bin .../convex_plane_decomposition_ros}/data/holes.png | Bin .../data/realStairs_125cm.png | Bin .../data/slope_1m_1m_20cm.png | Bin .../data/stepping_stones_65cm.png | Bin .../data/straightStairs_1m_1m_60cm.png | Bin .../data/terrain.png | Bin .../ConvexPlaneDecompositionRos.h | 0 .../MessageConversion.h | 0 .../ParameterLoading.h | 0 .../RosVisualizations.h | 0 .../launch/convex_plane_decomposition.launch | 0 ...vex_plane_decomposition_save_elevationmap.launch | 0 .../launch/demo.launch | 0 .../launch/rviz.launch | 0 .../launch/standalone.launch | 0 .../convex_plane_decomposition_ros}/package.xml | 0 .../rviz/config.rviz | 0 .../rviz/config_demo.rviz | 0 .../src/ConvexPlaneDecompositionNode.cpp | 0 .../src/ConvexPlaneDecompositionRos.cpp | 0 .../src/MessageConversion.cpp | 0 .../src/ParameterLoading.cpp | 0 .../src/RosVisualizations.cpp | 0 .../src/SaveElevationMapAsImageNode.cpp | 0 .../src/noiseNode.cpp | 0 .../test/shapeGrowing.cpp | 0 .../convex_plane_decomposition_ros}/test/test.cpp | 0 .../pcl_catkin}/CMakeLists.txt | 0 .../pcl_catkin}/README.md | 0 .../pcl_catkin}/lib/libpcl_visualization.so | Bin .../pcl_catkin}/lib/libpcl_visualization.so.1.10 | Bin .../pcl_catkin}/lib/libpcl_visualization.so.1.10.0 | Bin .../lib/pkgconfig/pcl_visualization-1.10.pc | 0 .../pcl_catkin}/package.xml | 0 97 files changed, 0 insertions(+), 0 deletions(-) rename README.md => plane_segmentation/README.md (100%) rename {cgal5_catkin => plane_segmentation/cgal5_catkin}/.gitignore (100%) rename {cgal5_catkin => plane_segmentation/cgal5_catkin}/CMakeLists.txt (100%) rename {cgal5_catkin => plane_segmentation/cgal5_catkin}/README.md (100%) rename {cgal5_catkin => plane_segmentation/cgal5_catkin}/cmake/cgal-extras.cmake.in (100%) rename {cgal5_catkin => plane_segmentation/cgal5_catkin}/package.xml (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/CMakeLists.txt (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/ConvexRegionGrowing.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/Draw.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/GeometryUtils.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/GridMapPreprocessing.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/LoadGridmapFromImage.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/PlanarRegion.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/PlaneDecompositionPipeline.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/PolygonTypes.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/Postprocessing.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/SegmentedPlanesMap.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/Timer.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/contour_extraction/Upsampling.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/package.xml (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/src/ConvexRegionGrowing.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/src/Draw.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/src/GridMapPreprocessing.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/src/LoadGridmapFromImage.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/src/PlanarRegion.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/src/PlaneDecompositionPipeline.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/src/Postprocessing.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/src/contour_extraction/ContourExtraction.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/src/contour_extraction/Upsampling.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/src/ransac/RansacPlaneExtractor.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/test/data/terrain.png (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/test/testPipeline.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/test/testPlanarRegion.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/test/testRegionGrowing.cpp (100%) rename {convex_plane_decomposition => plane_segmentation/convex_plane_decomposition}/test/testUpsampling.cpp (100%) rename {convex_plane_decomposition_msgs => plane_segmentation/convex_plane_decomposition_msgs}/CMakeLists.txt (100%) rename {convex_plane_decomposition_msgs => plane_segmentation/convex_plane_decomposition_msgs}/msg/BoundingBox2d.msg (100%) rename {convex_plane_decomposition_msgs => plane_segmentation/convex_plane_decomposition_msgs}/msg/PlanarRegion.msg (100%) rename {convex_plane_decomposition_msgs => plane_segmentation/convex_plane_decomposition_msgs}/msg/PlanarTerrain.msg (100%) rename {convex_plane_decomposition_msgs => plane_segmentation/convex_plane_decomposition_msgs}/msg/Point2d.msg (100%) rename {convex_plane_decomposition_msgs => plane_segmentation/convex_plane_decomposition_msgs}/msg/Polygon2d.msg (100%) rename {convex_plane_decomposition_msgs => plane_segmentation/convex_plane_decomposition_msgs}/msg/PolygonWithHoles2d.msg (100%) rename {convex_plane_decomposition_msgs => plane_segmentation/convex_plane_decomposition_msgs}/package.xml (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/CMakeLists.txt (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/config/demo_node.yaml (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/config/node.yaml (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/config/parameters.yaml (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/config/standalone_node.yaml (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/demo_map.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/elevationMap_0_107cm.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/elevationMap_0_148cm.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/elevationMap_0_44cm.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/elevationMap_10_277cm.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/elevationMap_11_278cm.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/elevationMap_8_139cm.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/elevationMap_9_308cm.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/holes.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/realStairs_125cm.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/slope_1m_1m_20cm.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/stepping_stones_65cm.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/straightStairs_1m_1m_60cm.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/data/terrain.png (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/include/convex_plane_decomposition_ros/MessageConversion.h (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/include/convex_plane_decomposition_ros/ParameterLoading.h (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/include/convex_plane_decomposition_ros/RosVisualizations.h (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/launch/convex_plane_decomposition.launch (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/launch/convex_plane_decomposition_save_elevationmap.launch (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/launch/demo.launch (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/launch/rviz.launch (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/launch/standalone.launch (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/package.xml (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/rviz/config.rviz (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/rviz/config_demo.rviz (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/src/ConvexPlaneDecompositionNode.cpp (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/src/ConvexPlaneDecompositionRos.cpp (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/src/MessageConversion.cpp (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/src/ParameterLoading.cpp (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/src/RosVisualizations.cpp (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/src/SaveElevationMapAsImageNode.cpp (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/src/noiseNode.cpp (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/test/shapeGrowing.cpp (100%) rename {convex_plane_decomposition_ros => plane_segmentation/convex_plane_decomposition_ros}/test/test.cpp (100%) rename {pcl_catkin => plane_segmentation/pcl_catkin}/CMakeLists.txt (100%) rename {pcl_catkin => plane_segmentation/pcl_catkin}/README.md (100%) rename {pcl_catkin => plane_segmentation/pcl_catkin}/lib/libpcl_visualization.so (100%) rename {pcl_catkin => plane_segmentation/pcl_catkin}/lib/libpcl_visualization.so.1.10 (100%) rename {pcl_catkin => plane_segmentation/pcl_catkin}/lib/libpcl_visualization.so.1.10.0 (100%) rename {pcl_catkin => plane_segmentation/pcl_catkin}/lib/pkgconfig/pcl_visualization-1.10.pc (100%) rename {pcl_catkin => plane_segmentation/pcl_catkin}/package.xml (100%) diff --git a/README.md b/plane_segmentation/README.md similarity index 100% rename from README.md rename to plane_segmentation/README.md diff --git a/cgal5_catkin/.gitignore b/plane_segmentation/cgal5_catkin/.gitignore similarity index 100% rename from cgal5_catkin/.gitignore rename to plane_segmentation/cgal5_catkin/.gitignore diff --git a/cgal5_catkin/CMakeLists.txt b/plane_segmentation/cgal5_catkin/CMakeLists.txt similarity index 100% rename from cgal5_catkin/CMakeLists.txt rename to plane_segmentation/cgal5_catkin/CMakeLists.txt diff --git a/cgal5_catkin/README.md b/plane_segmentation/cgal5_catkin/README.md similarity index 100% rename from cgal5_catkin/README.md rename to plane_segmentation/cgal5_catkin/README.md diff --git a/cgal5_catkin/cmake/cgal-extras.cmake.in b/plane_segmentation/cgal5_catkin/cmake/cgal-extras.cmake.in similarity index 100% rename from cgal5_catkin/cmake/cgal-extras.cmake.in rename to plane_segmentation/cgal5_catkin/cmake/cgal-extras.cmake.in diff --git a/cgal5_catkin/package.xml b/plane_segmentation/cgal5_catkin/package.xml similarity index 100% rename from cgal5_catkin/package.xml rename to plane_segmentation/cgal5_catkin/package.xml diff --git a/convex_plane_decomposition/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition/CMakeLists.txt similarity index 100% rename from convex_plane_decomposition/CMakeLists.txt rename to plane_segmentation/convex_plane_decomposition/CMakeLists.txt diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/Draw.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/LoadGridmapFromImage.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/LoadGridmapFromImage.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/LoadGridmapFromImage.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/LoadGridmapFromImage.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/Timer.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Timer.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/Timer.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Timer.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/Upsampling.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/Upsampling.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/Upsampling.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/Upsampling.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h diff --git a/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h similarity index 100% rename from convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h rename to plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h diff --git a/convex_plane_decomposition/package.xml b/plane_segmentation/convex_plane_decomposition/package.xml similarity index 100% rename from convex_plane_decomposition/package.xml rename to plane_segmentation/convex_plane_decomposition/package.xml diff --git a/convex_plane_decomposition/src/ConvexRegionGrowing.cpp b/plane_segmentation/convex_plane_decomposition/src/ConvexRegionGrowing.cpp similarity index 100% rename from convex_plane_decomposition/src/ConvexRegionGrowing.cpp rename to plane_segmentation/convex_plane_decomposition/src/ConvexRegionGrowing.cpp diff --git a/convex_plane_decomposition/src/Draw.cpp b/plane_segmentation/convex_plane_decomposition/src/Draw.cpp similarity index 100% rename from convex_plane_decomposition/src/Draw.cpp rename to plane_segmentation/convex_plane_decomposition/src/Draw.cpp diff --git a/convex_plane_decomposition/src/GridMapPreprocessing.cpp b/plane_segmentation/convex_plane_decomposition/src/GridMapPreprocessing.cpp similarity index 100% rename from convex_plane_decomposition/src/GridMapPreprocessing.cpp rename to plane_segmentation/convex_plane_decomposition/src/GridMapPreprocessing.cpp diff --git a/convex_plane_decomposition/src/LoadGridmapFromImage.cpp b/plane_segmentation/convex_plane_decomposition/src/LoadGridmapFromImage.cpp similarity index 100% rename from convex_plane_decomposition/src/LoadGridmapFromImage.cpp rename to plane_segmentation/convex_plane_decomposition/src/LoadGridmapFromImage.cpp diff --git a/convex_plane_decomposition/src/PlanarRegion.cpp b/plane_segmentation/convex_plane_decomposition/src/PlanarRegion.cpp similarity index 100% rename from convex_plane_decomposition/src/PlanarRegion.cpp rename to plane_segmentation/convex_plane_decomposition/src/PlanarRegion.cpp diff --git a/convex_plane_decomposition/src/PlaneDecompositionPipeline.cpp b/plane_segmentation/convex_plane_decomposition/src/PlaneDecompositionPipeline.cpp similarity index 100% rename from convex_plane_decomposition/src/PlaneDecompositionPipeline.cpp rename to plane_segmentation/convex_plane_decomposition/src/PlaneDecompositionPipeline.cpp diff --git a/convex_plane_decomposition/src/Postprocessing.cpp b/plane_segmentation/convex_plane_decomposition/src/Postprocessing.cpp similarity index 100% rename from convex_plane_decomposition/src/Postprocessing.cpp rename to plane_segmentation/convex_plane_decomposition/src/Postprocessing.cpp diff --git a/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp b/plane_segmentation/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp similarity index 100% rename from convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp rename to plane_segmentation/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp diff --git a/convex_plane_decomposition/src/contour_extraction/Upsampling.cpp b/plane_segmentation/convex_plane_decomposition/src/contour_extraction/Upsampling.cpp similarity index 100% rename from convex_plane_decomposition/src/contour_extraction/Upsampling.cpp rename to plane_segmentation/convex_plane_decomposition/src/contour_extraction/Upsampling.cpp diff --git a/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp b/plane_segmentation/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp similarity index 100% rename from convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp rename to plane_segmentation/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp diff --git a/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/plane_segmentation/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp similarity index 100% rename from convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp rename to plane_segmentation/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp diff --git a/convex_plane_decomposition/test/data/terrain.png b/plane_segmentation/convex_plane_decomposition/test/data/terrain.png similarity index 100% rename from convex_plane_decomposition/test/data/terrain.png rename to plane_segmentation/convex_plane_decomposition/test/data/terrain.png diff --git a/convex_plane_decomposition/test/testPipeline.cpp b/plane_segmentation/convex_plane_decomposition/test/testPipeline.cpp similarity index 100% rename from convex_plane_decomposition/test/testPipeline.cpp rename to plane_segmentation/convex_plane_decomposition/test/testPipeline.cpp diff --git a/convex_plane_decomposition/test/testPlanarRegion.cpp b/plane_segmentation/convex_plane_decomposition/test/testPlanarRegion.cpp similarity index 100% rename from convex_plane_decomposition/test/testPlanarRegion.cpp rename to plane_segmentation/convex_plane_decomposition/test/testPlanarRegion.cpp diff --git a/convex_plane_decomposition/test/testRegionGrowing.cpp b/plane_segmentation/convex_plane_decomposition/test/testRegionGrowing.cpp similarity index 100% rename from convex_plane_decomposition/test/testRegionGrowing.cpp rename to plane_segmentation/convex_plane_decomposition/test/testRegionGrowing.cpp diff --git a/convex_plane_decomposition/test/testUpsampling.cpp b/plane_segmentation/convex_plane_decomposition/test/testUpsampling.cpp similarity index 100% rename from convex_plane_decomposition/test/testUpsampling.cpp rename to plane_segmentation/convex_plane_decomposition/test/testUpsampling.cpp diff --git a/convex_plane_decomposition_msgs/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition_msgs/CMakeLists.txt similarity index 100% rename from convex_plane_decomposition_msgs/CMakeLists.txt rename to plane_segmentation/convex_plane_decomposition_msgs/CMakeLists.txt diff --git a/convex_plane_decomposition_msgs/msg/BoundingBox2d.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/BoundingBox2d.msg similarity index 100% rename from convex_plane_decomposition_msgs/msg/BoundingBox2d.msg rename to plane_segmentation/convex_plane_decomposition_msgs/msg/BoundingBox2d.msg diff --git a/convex_plane_decomposition_msgs/msg/PlanarRegion.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarRegion.msg similarity index 100% rename from convex_plane_decomposition_msgs/msg/PlanarRegion.msg rename to plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarRegion.msg diff --git a/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg similarity index 100% rename from convex_plane_decomposition_msgs/msg/PlanarTerrain.msg rename to plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg diff --git a/convex_plane_decomposition_msgs/msg/Point2d.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/Point2d.msg similarity index 100% rename from convex_plane_decomposition_msgs/msg/Point2d.msg rename to plane_segmentation/convex_plane_decomposition_msgs/msg/Point2d.msg diff --git a/convex_plane_decomposition_msgs/msg/Polygon2d.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/Polygon2d.msg similarity index 100% rename from convex_plane_decomposition_msgs/msg/Polygon2d.msg rename to plane_segmentation/convex_plane_decomposition_msgs/msg/Polygon2d.msg diff --git a/convex_plane_decomposition_msgs/msg/PolygonWithHoles2d.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/PolygonWithHoles2d.msg similarity index 100% rename from convex_plane_decomposition_msgs/msg/PolygonWithHoles2d.msg rename to plane_segmentation/convex_plane_decomposition_msgs/msg/PolygonWithHoles2d.msg diff --git a/convex_plane_decomposition_msgs/package.xml b/plane_segmentation/convex_plane_decomposition_msgs/package.xml similarity index 100% rename from convex_plane_decomposition_msgs/package.xml rename to plane_segmentation/convex_plane_decomposition_msgs/package.xml diff --git a/convex_plane_decomposition_ros/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt similarity index 100% rename from convex_plane_decomposition_ros/CMakeLists.txt rename to plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt diff --git a/convex_plane_decomposition_ros/config/demo_node.yaml b/plane_segmentation/convex_plane_decomposition_ros/config/demo_node.yaml similarity index 100% rename from convex_plane_decomposition_ros/config/demo_node.yaml rename to plane_segmentation/convex_plane_decomposition_ros/config/demo_node.yaml diff --git a/convex_plane_decomposition_ros/config/node.yaml b/plane_segmentation/convex_plane_decomposition_ros/config/node.yaml similarity index 100% rename from convex_plane_decomposition_ros/config/node.yaml rename to plane_segmentation/convex_plane_decomposition_ros/config/node.yaml diff --git a/convex_plane_decomposition_ros/config/parameters.yaml b/plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml similarity index 100% rename from convex_plane_decomposition_ros/config/parameters.yaml rename to plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml diff --git a/convex_plane_decomposition_ros/config/standalone_node.yaml b/plane_segmentation/convex_plane_decomposition_ros/config/standalone_node.yaml similarity index 100% rename from convex_plane_decomposition_ros/config/standalone_node.yaml rename to plane_segmentation/convex_plane_decomposition_ros/config/standalone_node.yaml diff --git a/convex_plane_decomposition_ros/data/demo_map.png b/plane_segmentation/convex_plane_decomposition_ros/data/demo_map.png similarity index 100% rename from convex_plane_decomposition_ros/data/demo_map.png rename to plane_segmentation/convex_plane_decomposition_ros/data/demo_map.png diff --git a/convex_plane_decomposition_ros/data/elevationMap_0_107cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_0_107cm.png similarity index 100% rename from convex_plane_decomposition_ros/data/elevationMap_0_107cm.png rename to plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_0_107cm.png diff --git a/convex_plane_decomposition_ros/data/elevationMap_0_148cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_0_148cm.png similarity index 100% rename from convex_plane_decomposition_ros/data/elevationMap_0_148cm.png rename to plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_0_148cm.png diff --git a/convex_plane_decomposition_ros/data/elevationMap_0_44cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_0_44cm.png similarity index 100% rename from convex_plane_decomposition_ros/data/elevationMap_0_44cm.png rename to plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_0_44cm.png diff --git a/convex_plane_decomposition_ros/data/elevationMap_10_277cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_10_277cm.png similarity index 100% rename from convex_plane_decomposition_ros/data/elevationMap_10_277cm.png rename to plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_10_277cm.png diff --git a/convex_plane_decomposition_ros/data/elevationMap_11_278cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_11_278cm.png similarity index 100% rename from convex_plane_decomposition_ros/data/elevationMap_11_278cm.png rename to plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_11_278cm.png diff --git a/convex_plane_decomposition_ros/data/elevationMap_8_139cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_8_139cm.png similarity index 100% rename from convex_plane_decomposition_ros/data/elevationMap_8_139cm.png rename to plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_8_139cm.png diff --git a/convex_plane_decomposition_ros/data/elevationMap_9_308cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_9_308cm.png similarity index 100% rename from convex_plane_decomposition_ros/data/elevationMap_9_308cm.png rename to plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_9_308cm.png diff --git a/convex_plane_decomposition_ros/data/holes.png b/plane_segmentation/convex_plane_decomposition_ros/data/holes.png similarity index 100% rename from convex_plane_decomposition_ros/data/holes.png rename to plane_segmentation/convex_plane_decomposition_ros/data/holes.png diff --git a/convex_plane_decomposition_ros/data/realStairs_125cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/realStairs_125cm.png similarity index 100% rename from convex_plane_decomposition_ros/data/realStairs_125cm.png rename to plane_segmentation/convex_plane_decomposition_ros/data/realStairs_125cm.png diff --git a/convex_plane_decomposition_ros/data/slope_1m_1m_20cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/slope_1m_1m_20cm.png similarity index 100% rename from convex_plane_decomposition_ros/data/slope_1m_1m_20cm.png rename to plane_segmentation/convex_plane_decomposition_ros/data/slope_1m_1m_20cm.png diff --git a/convex_plane_decomposition_ros/data/stepping_stones_65cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/stepping_stones_65cm.png similarity index 100% rename from convex_plane_decomposition_ros/data/stepping_stones_65cm.png rename to plane_segmentation/convex_plane_decomposition_ros/data/stepping_stones_65cm.png diff --git a/convex_plane_decomposition_ros/data/straightStairs_1m_1m_60cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/straightStairs_1m_1m_60cm.png similarity index 100% rename from convex_plane_decomposition_ros/data/straightStairs_1m_1m_60cm.png rename to plane_segmentation/convex_plane_decomposition_ros/data/straightStairs_1m_1m_60cm.png diff --git a/convex_plane_decomposition_ros/data/terrain.png b/plane_segmentation/convex_plane_decomposition_ros/data/terrain.png similarity index 100% rename from convex_plane_decomposition_ros/data/terrain.png rename to plane_segmentation/convex_plane_decomposition_ros/data/terrain.png diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h similarity index 100% rename from convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h rename to plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h similarity index 100% rename from convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h rename to plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h similarity index 100% rename from convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h rename to plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h diff --git a/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h similarity index 100% rename from convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h rename to plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h diff --git a/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch similarity index 100% rename from convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch rename to plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch diff --git a/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch similarity index 100% rename from convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch rename to plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch diff --git a/convex_plane_decomposition_ros/launch/demo.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch similarity index 100% rename from convex_plane_decomposition_ros/launch/demo.launch rename to plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch diff --git a/convex_plane_decomposition_ros/launch/rviz.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/rviz.launch similarity index 100% rename from convex_plane_decomposition_ros/launch/rviz.launch rename to plane_segmentation/convex_plane_decomposition_ros/launch/rviz.launch diff --git a/convex_plane_decomposition_ros/launch/standalone.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/standalone.launch similarity index 100% rename from convex_plane_decomposition_ros/launch/standalone.launch rename to plane_segmentation/convex_plane_decomposition_ros/launch/standalone.launch diff --git a/convex_plane_decomposition_ros/package.xml b/plane_segmentation/convex_plane_decomposition_ros/package.xml similarity index 100% rename from convex_plane_decomposition_ros/package.xml rename to plane_segmentation/convex_plane_decomposition_ros/package.xml diff --git a/convex_plane_decomposition_ros/rviz/config.rviz b/plane_segmentation/convex_plane_decomposition_ros/rviz/config.rviz similarity index 100% rename from convex_plane_decomposition_ros/rviz/config.rviz rename to plane_segmentation/convex_plane_decomposition_ros/rviz/config.rviz diff --git a/convex_plane_decomposition_ros/rviz/config_demo.rviz b/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz similarity index 100% rename from convex_plane_decomposition_ros/rviz/config_demo.rviz rename to plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp similarity index 100% rename from convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp rename to plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp diff --git a/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp similarity index 100% rename from convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp rename to plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp diff --git a/convex_plane_decomposition_ros/src/MessageConversion.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/MessageConversion.cpp similarity index 100% rename from convex_plane_decomposition_ros/src/MessageConversion.cpp rename to plane_segmentation/convex_plane_decomposition_ros/src/MessageConversion.cpp diff --git a/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/ParameterLoading.cpp similarity index 100% rename from convex_plane_decomposition_ros/src/ParameterLoading.cpp rename to plane_segmentation/convex_plane_decomposition_ros/src/ParameterLoading.cpp diff --git a/convex_plane_decomposition_ros/src/RosVisualizations.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp similarity index 100% rename from convex_plane_decomposition_ros/src/RosVisualizations.cpp rename to plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp diff --git a/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp similarity index 100% rename from convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp rename to plane_segmentation/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp diff --git a/convex_plane_decomposition_ros/src/noiseNode.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/noiseNode.cpp similarity index 100% rename from convex_plane_decomposition_ros/src/noiseNode.cpp rename to plane_segmentation/convex_plane_decomposition_ros/src/noiseNode.cpp diff --git a/convex_plane_decomposition_ros/test/shapeGrowing.cpp b/plane_segmentation/convex_plane_decomposition_ros/test/shapeGrowing.cpp similarity index 100% rename from convex_plane_decomposition_ros/test/shapeGrowing.cpp rename to plane_segmentation/convex_plane_decomposition_ros/test/shapeGrowing.cpp diff --git a/convex_plane_decomposition_ros/test/test.cpp b/plane_segmentation/convex_plane_decomposition_ros/test/test.cpp similarity index 100% rename from convex_plane_decomposition_ros/test/test.cpp rename to plane_segmentation/convex_plane_decomposition_ros/test/test.cpp diff --git a/pcl_catkin/CMakeLists.txt b/plane_segmentation/pcl_catkin/CMakeLists.txt similarity index 100% rename from pcl_catkin/CMakeLists.txt rename to plane_segmentation/pcl_catkin/CMakeLists.txt diff --git a/pcl_catkin/README.md b/plane_segmentation/pcl_catkin/README.md similarity index 100% rename from pcl_catkin/README.md rename to plane_segmentation/pcl_catkin/README.md diff --git a/pcl_catkin/lib/libpcl_visualization.so b/plane_segmentation/pcl_catkin/lib/libpcl_visualization.so similarity index 100% rename from pcl_catkin/lib/libpcl_visualization.so rename to plane_segmentation/pcl_catkin/lib/libpcl_visualization.so diff --git a/pcl_catkin/lib/libpcl_visualization.so.1.10 b/plane_segmentation/pcl_catkin/lib/libpcl_visualization.so.1.10 similarity index 100% rename from pcl_catkin/lib/libpcl_visualization.so.1.10 rename to plane_segmentation/pcl_catkin/lib/libpcl_visualization.so.1.10 diff --git a/pcl_catkin/lib/libpcl_visualization.so.1.10.0 b/plane_segmentation/pcl_catkin/lib/libpcl_visualization.so.1.10.0 similarity index 100% rename from pcl_catkin/lib/libpcl_visualization.so.1.10.0 rename to plane_segmentation/pcl_catkin/lib/libpcl_visualization.so.1.10.0 diff --git a/pcl_catkin/lib/pkgconfig/pcl_visualization-1.10.pc b/plane_segmentation/pcl_catkin/lib/pkgconfig/pcl_visualization-1.10.pc similarity index 100% rename from pcl_catkin/lib/pkgconfig/pcl_visualization-1.10.pc rename to plane_segmentation/pcl_catkin/lib/pkgconfig/pcl_visualization-1.10.pc diff --git a/pcl_catkin/package.xml b/plane_segmentation/pcl_catkin/package.xml similarity index 100% rename from pcl_catkin/package.xml rename to plane_segmentation/pcl_catkin/package.xml From ddc1f8cae360738c12ce8abe5eade63d443e6faa Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 7 Jun 2022 15:44:39 +0200 Subject: [PATCH 206/504] remove unused filters --- .../GridMapDerivative.hpp | 1 + .../grid_map_filters_rsl/inpainting.hpp | 19 +-- .../include/grid_map_filters_rsl/lookup.hpp | 2 +- .../grid_map_filters_rsl/smoothing.hpp | 45 ----- .../src/GridMapDerivative.cpp | 2 + .../grid_map_filters_rsl/src/inpainting.cpp | 158 +----------------- .../grid_map_filters_rsl/src/lookup.cpp | 2 +- .../grid_map_filters_rsl/src/processing.cpp | 1 - .../grid_map_filters_rsl/src/smoothing.cpp | 102 ----------- .../test/TestDerivativeFilter.cpp | 2 +- .../grid_map_filters_rsl/test/TestFilters.cpp | 2 +- .../grid_map_filters_rsl/test/TestLookup.cpp | 2 +- 12 files changed, 10 insertions(+), 328 deletions(-) diff --git a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/GridMapDerivative.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/GridMapDerivative.hpp index aa814d0f..41dd3ac4 100644 --- a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/GridMapDerivative.hpp +++ b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/GridMapDerivative.hpp @@ -14,6 +14,7 @@ namespace grid_map { namespace derivative { + class GridMapDerivative { private: static constexpr int kernelSize_ = 5; diff --git a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp index 0573df4b..9f70cfbd 100644 --- a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp +++ b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp @@ -23,24 +23,6 @@ namespace inpainting { */ void minValues(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut); -/** - * @brief Inpaint missing data using bi-linear interpolation. The neighborhood search is only performed along the column and the row of the - * missing element. In-place operation (layerIn = layerOut) is NOT supported. - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - */ -void biLinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut); - -/** - * @brief nonlinear interpolation (open-cv function). In-place operation (layerIn = layerOut) is supported. - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - * @param inpaintRadius vicinity considered by inpaint filter. - */ -void nonlinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, double inpaintRadius = 0.05); - /** * @brief Up- or down-sample elevation map (open-cv function). In-place operation only. Only the layer with name "layer" is resampled, while * all other layers (if there are any) are left untouched (exception if layer="all", which applies filter to all layers). @@ -49,5 +31,6 @@ void nonlinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, * @param newRes new resolution. */ void resample(grid_map::GridMap& map, const std::string& layer, double newRes); + } // namespace inpainting } // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/lookup.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/lookup.hpp index 7c91c20a..cd3bae45 100644 --- a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/lookup.hpp +++ b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/lookup.hpp @@ -55,4 +55,4 @@ std::vector valuesBetweenLocations(const grid_map::Position grid_map::Position projectToMapWithMargin(const grid_map::GridMap& gridMap, const grid_map::Position& position, double margin = 1e-6); } // namespace lookup -} // namespace grid_map \ No newline at end of file +} // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/smoothing.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/smoothing.hpp index 9f0deebd..99ae3e2b 100644 --- a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/smoothing.hpp +++ b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/smoothing.hpp @@ -46,50 +46,5 @@ void boxBlur(grid_map::GridMap& map, const std::string& layerIn, const std::stri */ void gaussianBlur(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize, double sigma); -/** - * @brief Non-Local means denoising filter (open-cv function). In-place operation (layerIn = layerOut) is supported. Attention: slow (~5ms)! - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - * @param kernelSize size of the smoothing window (must be an odd number) - * @param searchWindow search window (must be an odd number and larger than kernelSize) - * @param w filter strength - */ -void nlm(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize = 3, int searchWindow = 7, - float w = 45.F); - -/** - * @brief Performs image denoising using the Block-Matching and 3D-filtering algorithm (open-cv function). In-place operation (layerIn = - * layerOut) is supported. Attention: very slow (~30ms)! - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - * @param kernelSize size of the smoothing window (must be power of 2) - * @param searchWindow search window (must be larger than kernelSize) - * @param w filter strength - */ -void bm3d(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize = 4, int searchWindow = 6, - float w = 25.F); - -/** - * @brief Bilateral filter (open-cv function). In-place operation (layerIn = layerOut) is supported. Attention: slow (~0.3ms)! - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - * @param kernelSize size of the smoothing window (must be an even number) - * @param w filter strength - */ -void bilateralFilter(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize = 0, double w = 0.2); - -/** - * @brief Optimization based (open-cv function). In-place operation (layerIn = layerOut) is supported. Attention: slow (~15ms)! - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - * @param lambda the smaller the value, the smoother the image - * @param n number of optimization iterations - */ -void tvL1(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, double lambda = 1.0, int n = 60); - } // namespace smoothing } // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp b/plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp index 2fca08e3..3cc8a169 100644 --- a/plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp +++ b/plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp @@ -71,5 +71,7 @@ Eigen::Vector2i GridMapDerivative::getKernelCenter(const grid_map::GridMap& grid } return centerId; } + } // namespace derivative } // namespace grid_map + diff --git a/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp b/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp index c82e82b9..adf6e998 100644 --- a/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp +++ b/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp @@ -10,15 +10,6 @@ #include #include -// open cv. -#include -#include -#include -#include - -// stl. -#include - namespace grid_map { namespace inpainting { @@ -93,154 +84,6 @@ void minValues(grid_map::GridMap& map, const std::string& layerIn, const std::st } } -void biLinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut) { - // Create new layer if missing - if (!map.exists(layerOut)) { - map.add(layerOut, map.get(layerIn)); - } else { - // initialize with a copy - map.get(layerOut) = map.get(layerIn); - } - - // Helper variables. - std::array indices; - std::array values; - Eigen::Matrix4f A; - Eigen::Vector4f b; - A.setOnes(); - Eigen::Vector4f weights; - bool success = true; - constexpr auto infinity = std::numeric_limits::max(); - - // Init. - std::fill(values.begin(), values.end(), NAN); - std::fill(indices.begin(), indices.end(), Eigen::Vector2i(0, 0)); - - // Reference to in and out maps. - const grid_map::Matrix& H_in = map.get(layerIn); - grid_map::Matrix& H_out = map.get(layerOut); - - for (auto colId = 0; colId < H_in.cols(); ++colId) { - for (auto rowId = 0; rowId < H_in.rows(); ++rowId) { - if (std::isnan(H_in(rowId, colId))) { - // Note: if we don't find a valid neighbour, we use the previous index-value pair. - auto minValue = infinity; - const Eigen::Vector2i index0(rowId, colId); - - // Search in negative direction. - for (auto id = rowId - 1; id >= 0; --id) { - auto newValue = H_in(id, colId); - if (!std::isnan(newValue)) { - indices[0] = Eigen::Vector2i(id, colId); - values[0] = newValue; - minValue = std::fmin(minValue, newValue); - break; - } - } - - for (auto id = colId - 1; id >= 0; --id) { - auto newValue = H_in(rowId, id); - if (!std::isnan(newValue)) { - indices[1] = Eigen::Vector2i(rowId, id); - values[1] = newValue; - minValue = std::fmin(minValue, newValue); - break; - } - } - - // Search in positive direction. - for (auto id = rowId + 1; id < H_in.rows(); ++id) { - auto newValue = H_in(id, colId); - if (!std::isnan(newValue)) { - indices[2] = Eigen::Vector2i(id, colId); - values[2] = newValue; - minValue = std::fmin(minValue, newValue); - break; - } - } - - for (auto id = colId + 1; id < H_in.cols(); ++id) { - auto newValue = H_in(rowId, id); - if (!std::isnan(newValue)) { - indices[3] = Eigen::Vector2i(rowId, id); - values[3] = newValue; - minValue = std::fmin(minValue, newValue); - break; - } - } - - // Cannot interpolate if there are not 4 corner points. - if (std::any_of(values.begin(), values.end(), [](float value) { return std::isnan(value); })) { - if (minValue < infinity) { - H_out(rowId, colId) = minValue; - } else { - success = false; - } - continue; - } - - // Interpolation weights (https://en.wikipedia.org/wiki/Bilinear_interpolation). - for (auto id = 0U; id < 4U; ++id) { - A(id, 1U) = static_cast(indices[id].x()); - A(id, 2U) = static_cast(indices[id].y()); - A(id, 3U) = static_cast(indices[id].x() * indices[id].y()); - b(id) = values[id]; - } - weights = A.colPivHouseholderQr().solve(b); - - // Value according to bi-linear interpolation. - H_out(rowId, colId) = weights.dot(Eigen::Vector4f(1.0, static_cast(index0.x()), static_cast(index0.y()), - static_cast(index0.x() * index0.y()))); - } - } - } - - // If failed, try again. - if (!success) { - map.get(layerIn) = map.get(layerOut); - return nonlinearInterpolation(map, layerIn, layerOut); - } -} - -void nonlinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, double inpaintRadius) { - // Create new layer if missing. - if (!map.exists(layerOut)) { - map.add(layerOut); - } - - // Reference to in map. - const grid_map::Matrix& H_in = map.get(layerIn); - - // Create mask. - Eigen::Matrix mask = H_in.unaryExpr([](float val) { return (std::isnan(val)) ? uchar(1) : uchar(0); }); - cv::Mat maskImage; - cv::eigen2cv(mask, maskImage); - - // Convert grid map to image. - cv::Mat elevationImageIn; - const float minValue = H_in.minCoeffOfFinites(); - const float maxValue = H_in.maxCoeffOfFinites(); - grid_map::GridMapCvConverter::toImage(map, layerIn, CV_8UC1, minValue, maxValue, elevationImageIn); - - // Inpainting. - cv::Mat elevationImageOut; - const double radiusInPixels = inpaintRadius / map.getResolution(); - cv::inpaint(elevationImageIn, maskImage, elevationImageOut, radiusInPixels, cv::INPAINT_NS); - - // Get inpainting as float. - cv::Mat filledImageFloat; - constexpr float maxUCharValue = 255.F; - elevationImageOut.convertTo(filledImageFloat, CV_32F, (maxValue - minValue) / maxUCharValue, minValue); - - // Copy inpainted values back to elevation map. - cv::Mat elevationImageFloat; - cv::eigen2cv(H_in, elevationImageFloat); - filledImageFloat.copyTo(elevationImageFloat, maskImage); - - // Set new output layer. - cv::cv2eigen(elevationImageFloat, map.get(layerOut)); -} - void resample(grid_map::GridMap& map, const std::string& layer, double newRes) { // Original map info const auto oldPos = map.getPosition(); @@ -286,5 +129,6 @@ void resample(grid_map::GridMap& map, const std::string& layer, double newRes) { map.get(layer_name) = std::move(elevationMap); } } + } // namespace inpainting } // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/src/lookup.cpp b/plane_segmentation/grid_map_filters_rsl/src/lookup.cpp index f6759902..61409e7a 100644 --- a/plane_segmentation/grid_map_filters_rsl/src/lookup.cpp +++ b/plane_segmentation/grid_map_filters_rsl/src/lookup.cpp @@ -103,4 +103,4 @@ grid_map::Position projectToMapWithMargin(const grid_map::GridMap& gridMap, cons } } // namespace lookup -} // namespace grid_map \ No newline at end of file +} // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/src/processing.cpp b/plane_segmentation/grid_map_filters_rsl/src/processing.cpp index 2535feb5..1249937e 100644 --- a/plane_segmentation/grid_map_filters_rsl/src/processing.cpp +++ b/plane_segmentation/grid_map_filters_rsl/src/processing.cpp @@ -8,7 +8,6 @@ // grid map filters rsl. #include -#include namespace grid_map { namespace processing { diff --git a/plane_segmentation/grid_map_filters_rsl/src/smoothing.cpp b/plane_segmentation/grid_map_filters_rsl/src/smoothing.cpp index 300ad54f..24e89e04 100644 --- a/plane_segmentation/grid_map_filters_rsl/src/smoothing.cpp +++ b/plane_segmentation/grid_map_filters_rsl/src/smoothing.cpp @@ -105,107 +105,5 @@ void gaussianBlur(grid_map::GridMap& map, const std::string& layerIn, const std: cv::cv2eigen(elevationImage, map.get(layerOut)); } -void nlm(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize, int searchWindow, float w) { - // Create new layer if missing. - if (!map.exists(layerOut)) { - map.add(layerOut); - } - - // Get input layer. - const grid_map::Matrix& H_in = map.get(layerIn); - - // Convert grid map to image. - cv::Mat elevationImageIn; - const float minValue = H_in.minCoeffOfFinites(); - const float maxValue = H_in.maxCoeffOfFinites(); - grid_map::GridMapCvConverter::toImage(map, layerIn, CV_8UC1, minValue, maxValue, elevationImageIn); - - // Filter. - cv::Mat elevationImageOut; - cv::fastNlMeansDenoising(elevationImageIn, elevationImageOut, w, kernelSize, searchWindow); - - // Get as float. - cv::Mat elevationImageFloat; - constexpr float maxUCharValue = 255.F; - elevationImageOut.convertTo(elevationImageFloat, CV_32F, (maxValue - minValue) / maxUCharValue, minValue); - - // Set output layer. - cv::cv2eigen(elevationImageFloat, map.get(layerOut)); -} - -void bm3d(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize, int searchWindow, float w) { - // Create new layer if missing. - if (!map.exists(layerOut)) { - map.add(layerOut); - } - - // Get input layer. - const grid_map::Matrix& H_in = map.get(layerIn); - - // Convert grid map to image. - cv::Mat elevationImageIn; - const float minValue = H_in.minCoeffOfFinites(); - const float maxValue = H_in.maxCoeffOfFinites(); - grid_map::GridMapCvConverter::toImage(map, layerIn, CV_8UC1, minValue, maxValue, elevationImageIn); - - // Filter. - cv::Mat elevationImageOut; - cv::xphoto::bm3dDenoising(elevationImageIn, elevationImageOut, w, kernelSize, searchWindow, 2500, 400, 8, 1, 0.0f, cv::NORM_L1, - cv::xphoto::BM3D_STEP1); - - // Get as float. - cv::Mat elevationImageFloat; - constexpr float maxUCharValue = 255.F; - elevationImageOut.convertTo(elevationImageFloat, CV_32F, (maxValue - minValue) / maxUCharValue, minValue); - - // Set output layer. - cv::cv2eigen(elevationImageFloat, map.get(layerOut)); -} - -void bilateralFilter(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize, double w) { - // Create new layer if missing. - if (!map.exists(layerOut)) { - map.add(layerOut); - } - - // Convert to image. - cv::Mat elevationImageIn; - cv::eigen2cv(map.get(layerIn), elevationImageIn); - - // Filter. - cv::Mat elevationImageOut; - cv::bilateralFilter(elevationImageIn, elevationImageOut, kernelSize, w, w); - - // Set output layer. - cv::cv2eigen(elevationImageOut, map.get(layerOut)); -} - -void tvL1(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, double lambda, int n) { - // Create new layer if missing. - if (!map.exists(layerOut)) { - map.add(layerOut); - } - - // Get input layer. - const grid_map::Matrix& H_in = map.get(layerIn); - - // Convert grid map to image. - cv::Mat elevationImageIn; - const float minValue = H_in.minCoeffOfFinites(); - const float maxValue = H_in.maxCoeffOfFinites(); - grid_map::GridMapCvConverter::toImage(map, layerIn, CV_8UC1, minValue, maxValue, elevationImageIn); - - // Filter. - cv::Mat elevationImageOut; - cv::denoise_TVL1({elevationImageIn}, elevationImageOut, lambda, n); - - // Get as float. - cv::Mat elevationImageFloat; - constexpr float maxUCharValue = 255.F; - elevationImageOut.convertTo(elevationImageFloat, CV_32F, (maxValue - minValue) / maxUCharValue, minValue); - - // Set output layer. - cv::cv2eigen(elevationImageFloat, map.get(layerOut)); -} } // namespace smoothing } // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/test/TestDerivativeFilter.cpp b/plane_segmentation/grid_map_filters_rsl/test/TestDerivativeFilter.cpp index d4026c9c..6f04270a 100644 --- a/plane_segmentation/grid_map_filters_rsl/test/TestDerivativeFilter.cpp +++ b/plane_segmentation/grid_map_filters_rsl/test/TestDerivativeFilter.cpp @@ -36,4 +36,4 @@ TEST(TestGridMapDerivative, initialization) { // NOLINT } EXPECT_TRUE(iterator.isPastEnd()); -} \ No newline at end of file +} diff --git a/plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp b/plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp index 6d83fa75..cbe445b8 100644 --- a/plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp +++ b/plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp @@ -74,4 +74,4 @@ TEST(TestInpainting, minValuesOnlyNaN) { // NOLINT EXPECT_TRUE(map.get("filled_min_nan").hasNaN()); EXPECT_DOUBLE_EQ(map.get("filled_min_nonan").minCoeff(), 1.0); -} \ No newline at end of file +} diff --git a/plane_segmentation/grid_map_filters_rsl/test/TestLookup.cpp b/plane_segmentation/grid_map_filters_rsl/test/TestLookup.cpp index 0472b732..b85fb6d3 100644 --- a/plane_segmentation/grid_map_filters_rsl/test/TestLookup.cpp +++ b/plane_segmentation/grid_map_filters_rsl/test/TestLookup.cpp @@ -79,4 +79,4 @@ TEST(TestLookup, maxValue_onlyNaN) { // NOLINT const grid_map::Position position2(0.3, 0.4); const auto result = lookup::maxValueBetweenLocations(position1, position2, map, data); ASSERT_FALSE(result.isValid); -} \ No newline at end of file +} From 4852cea658d970d2c643d0ebc6cdb57424548614 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 7 Jun 2022 16:00:06 +0200 Subject: [PATCH 207/504] add back opencv inpainting --- .../grid_map_filters_rsl/inpainting.hpp | 18 ++ .../src/GridMapDerivative.cpp | 1 - .../grid_map_filters_rsl/src/inpainting.cpp | 158 +++++++++++++++++- 3 files changed, 175 insertions(+), 2 deletions(-) diff --git a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp index 9f70cfbd..f8f89e5f 100644 --- a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp +++ b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp @@ -23,6 +23,24 @@ namespace inpainting { */ void minValues(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut); +/** + * @brief Inpaint missing data using bi-linear interpolation. The neighborhood search is only performed along the column and the row of the + * missing element. In-place operation (layerIn = layerOut) is NOT supported. + * @param map grid map + * @param layerIn reference layer (filter is applied wrt this layer) + * @param layerOut output layer (filtered map is written into this layer) + */ +void biLinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut); + +/** + * @brief nonlinear interpolation (open-cv function). In-place operation (layerIn = layerOut) is supported. + * @param map grid map + * @param layerIn reference layer (filter is applied wrt this layer) + * @param layerOut output layer (filtered map is written into this layer) + * @param inpaintRadius vicinity considered by inpaint filter. + */ +void nonlinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, double inpaintRadius); + /** * @brief Up- or down-sample elevation map (open-cv function). In-place operation only. Only the layer with name "layer" is resampled, while * all other layers (if there are any) are left untouched (exception if layer="all", which applies filter to all layers). diff --git a/plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp b/plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp index 3cc8a169..1796dfde 100644 --- a/plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp +++ b/plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp @@ -74,4 +74,3 @@ Eigen::Vector2i GridMapDerivative::getKernelCenter(const grid_map::GridMap& grid } // namespace derivative } // namespace grid_map - diff --git a/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp b/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp index adf6e998..6df2b258 100644 --- a/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp +++ b/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp @@ -10,6 +10,15 @@ #include #include +// open cv. +#include +#include +#include +#include + +// stl. +#include + namespace grid_map { namespace inpainting { @@ -84,6 +93,154 @@ void minValues(grid_map::GridMap& map, const std::string& layerIn, const std::st } } +void biLinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut) { + // Create new layer if missing + if (!map.exists(layerOut)) { + map.add(layerOut, map.get(layerIn)); + } else { + // initialize with a copy + map.get(layerOut) = map.get(layerIn); + } + + // Helper variables. + std::array indices; + std::array values; + Eigen::Matrix4f A; + Eigen::Vector4f b; + A.setOnes(); + Eigen::Vector4f weights; + bool success = true; + constexpr auto infinity = std::numeric_limits::max(); + + // Init. + std::fill(values.begin(), values.end(), NAN); + std::fill(indices.begin(), indices.end(), Eigen::Vector2i(0, 0)); + + // Reference to in and out maps. + const grid_map::Matrix& H_in = map.get(layerIn); + grid_map::Matrix& H_out = map.get(layerOut); + + for (auto colId = 0; colId < H_in.cols(); ++colId) { + for (auto rowId = 0; rowId < H_in.rows(); ++rowId) { + if (std::isnan(H_in(rowId, colId))) { + // Note: if we don't find a valid neighbour, we use the previous index-value pair. + auto minValue = infinity; + const Eigen::Vector2i index0(rowId, colId); + + // Search in negative direction. + for (auto id = rowId - 1; id >= 0; --id) { + auto newValue = H_in(id, colId); + if (!std::isnan(newValue)) { + indices[0] = Eigen::Vector2i(id, colId); + values[0] = newValue; + minValue = std::fmin(minValue, newValue); + break; + } + } + + for (auto id = colId - 1; id >= 0; --id) { + auto newValue = H_in(rowId, id); + if (!std::isnan(newValue)) { + indices[1] = Eigen::Vector2i(rowId, id); + values[1] = newValue; + minValue = std::fmin(minValue, newValue); + break; + } + } + + // Search in positive direction. + for (auto id = rowId + 1; id < H_in.rows(); ++id) { + auto newValue = H_in(id, colId); + if (!std::isnan(newValue)) { + indices[2] = Eigen::Vector2i(id, colId); + values[2] = newValue; + minValue = std::fmin(minValue, newValue); + break; + } + } + + for (auto id = colId + 1; id < H_in.cols(); ++id) { + auto newValue = H_in(rowId, id); + if (!std::isnan(newValue)) { + indices[3] = Eigen::Vector2i(rowId, id); + values[3] = newValue; + minValue = std::fmin(minValue, newValue); + break; + } + } + + // Cannot interpolate if there are not 4 corner points. + if (std::any_of(values.begin(), values.end(), [](float value) { return std::isnan(value); })) { + if (minValue < infinity) { + H_out(rowId, colId) = minValue; + } else { + success = false; + } + continue; + } + + // Interpolation weights (https://en.wikipedia.org/wiki/Bilinear_interpolation). + for (auto id = 0U; id < 4U; ++id) { + A(id, 1U) = static_cast(indices[id].x()); + A(id, 2U) = static_cast(indices[id].y()); + A(id, 3U) = static_cast(indices[id].x() * indices[id].y()); + b(id) = values[id]; + } + weights = A.colPivHouseholderQr().solve(b); + + // Value according to bi-linear interpolation. + H_out(rowId, colId) = weights.dot(Eigen::Vector4f(1.0, static_cast(index0.x()), static_cast(index0.y()), + static_cast(index0.x() * index0.y()))); + } + } + } + + // If failed, try again. + if (!success) { + map.get(layerIn) = map.get(layerOut); + return nonlinearInterpolation(map, layerIn, layerOut, 2. * map.getResolution()); + } +} + +void nonlinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, double inpaintRadius) { + // Create new layer if missing. + if (!map.exists(layerOut)) { + map.add(layerOut); + } + + // Reference to in map. + const grid_map::Matrix& H_in = map.get(layerIn); + + // Create mask. + Eigen::Matrix mask = H_in.unaryExpr([](float val) { return (std::isnan(val)) ? uchar(1) : uchar(0); }); + cv::Mat maskImage; + cv::eigen2cv(mask, maskImage); + + // Convert grid map to image. + cv::Mat elevationImageIn; + const float minValue = H_in.minCoeffOfFinites(); + const float maxValue = H_in.maxCoeffOfFinites(); + grid_map::GridMapCvConverter::toImage(map, layerIn, CV_8UC1, minValue, maxValue, elevationImageIn); + + // Inpainting. + cv::Mat elevationImageOut; + const double radiusInPixels = inpaintRadius / map.getResolution(); + cv::inpaint(elevationImageIn, maskImage, elevationImageOut, radiusInPixels, cv::INPAINT_NS); + + // Get inpainting as float. + cv::Mat filledImageFloat; + constexpr float maxUCharValue = 255.F; + elevationImageOut.convertTo(filledImageFloat, CV_32F, (maxValue - minValue) / maxUCharValue, minValue); + + // Copy inpainted values back to elevation map. + cv::Mat elevationImageFloat; + cv::eigen2cv(H_in, elevationImageFloat); + filledImageFloat.copyTo(elevationImageFloat, maskImage); + + // Set new output layer. + cv::cv2eigen(elevationImageFloat, map.get(layerOut)); +} + void resample(grid_map::GridMap& map, const std::string& layer, double newRes) { // Original map info const auto oldPos = map.getPosition(); @@ -129,6 +286,5 @@ void resample(grid_map::GridMap& map, const std::string& layer, double newRes) { map.get(layer_name) = std::move(elevationMap); } } - } // namespace inpainting } // namespace grid_map From 48d73753cbbdc2022676bd103201e61e825b6372 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Tue, 7 Jun 2022 16:03:51 +0200 Subject: [PATCH 208/504] rename pcl_catkin to pcl_visualization_catkin --- plane_segmentation/README.md | 4 ++-- .../CMakeLists.txt | 2 +- .../README.md | 2 +- .../lib/libpcl_visualization.so | Bin .../lib/libpcl_visualization.so.1.10 | Bin .../lib/libpcl_visualization.so.1.10.0 | Bin .../lib/pkgconfig/pcl_visualization-1.10.pc | 0 .../package.xml | 4 ++-- 8 files changed, 6 insertions(+), 6 deletions(-) rename plane_segmentation/{pcl_catkin => pcl_visualization_catkin}/CMakeLists.txt (95%) rename plane_segmentation/{pcl_catkin => pcl_visualization_catkin}/README.md (82%) rename plane_segmentation/{pcl_catkin => pcl_visualization_catkin}/lib/libpcl_visualization.so (100%) rename plane_segmentation/{pcl_catkin => pcl_visualization_catkin}/lib/libpcl_visualization.so.1.10 (100%) rename plane_segmentation/{pcl_catkin => pcl_visualization_catkin}/lib/libpcl_visualization.so.1.10.0 (100%) rename plane_segmentation/{pcl_catkin => pcl_visualization_catkin}/lib/pkgconfig/pcl_visualization-1.10.pc (100%) rename plane_segmentation/{pcl_catkin => pcl_visualization_catkin}/package.xml (74%) diff --git a/plane_segmentation/README.md b/plane_segmentation/README.md index df2bef02..a0312dff 100644 --- a/plane_segmentation/README.md +++ b/plane_segmentation/README.md @@ -30,11 +30,11 @@ sudo apt-get install libboost-all-dev #### PCL PCL is required, but the ANYbotics distributed version does not contain visualization components. -With the following commands PCL can be build from source directly into your catkin workspace. +With the following commands, the missing components are provided into your catkin workspace. DO NOT do this on the ANYmal onboard PCs, only on OPC and simulation PCs. ```bash sudo apt-get install libvtk7-dev -catkin build pcl_catkin +catkin build pcl_visualization_catkin ``` ### ROS package dependencies diff --git a/plane_segmentation/pcl_catkin/CMakeLists.txt b/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt similarity index 95% rename from plane_segmentation/pcl_catkin/CMakeLists.txt rename to plane_segmentation/pcl_visualization_catkin/CMakeLists.txt index 89658bd2..623099f6 100644 --- a/plane_segmentation/pcl_catkin/CMakeLists.txt +++ b/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(pcl_catkin) +project(pcl_visualization_catkin) include(GNUInstallDirs) diff --git a/plane_segmentation/pcl_catkin/README.md b/plane_segmentation/pcl_visualization_catkin/README.md similarity index 82% rename from plane_segmentation/pcl_catkin/README.md rename to plane_segmentation/pcl_visualization_catkin/README.md index 36bf8783..9730de36 100644 --- a/plane_segmentation/pcl_catkin/README.md +++ b/plane_segmentation/pcl_visualization_catkin/README.md @@ -1,3 +1,3 @@ -# pcl_catkin +# pcl_visualization_catkin Catkin wrapper of the visualization part of Point Cloud Library (PCL). Just copies the shared library into the catkin workspace. \ No newline at end of file diff --git a/plane_segmentation/pcl_catkin/lib/libpcl_visualization.so b/plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so similarity index 100% rename from plane_segmentation/pcl_catkin/lib/libpcl_visualization.so rename to plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so diff --git a/plane_segmentation/pcl_catkin/lib/libpcl_visualization.so.1.10 b/plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so.1.10 similarity index 100% rename from plane_segmentation/pcl_catkin/lib/libpcl_visualization.so.1.10 rename to plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so.1.10 diff --git a/plane_segmentation/pcl_catkin/lib/libpcl_visualization.so.1.10.0 b/plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so.1.10.0 similarity index 100% rename from plane_segmentation/pcl_catkin/lib/libpcl_visualization.so.1.10.0 rename to plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so.1.10.0 diff --git a/plane_segmentation/pcl_catkin/lib/pkgconfig/pcl_visualization-1.10.pc b/plane_segmentation/pcl_visualization_catkin/lib/pkgconfig/pcl_visualization-1.10.pc similarity index 100% rename from plane_segmentation/pcl_catkin/lib/pkgconfig/pcl_visualization-1.10.pc rename to plane_segmentation/pcl_visualization_catkin/lib/pkgconfig/pcl_visualization-1.10.pc diff --git a/plane_segmentation/pcl_catkin/package.xml b/plane_segmentation/pcl_visualization_catkin/package.xml similarity index 74% rename from plane_segmentation/pcl_catkin/package.xml rename to plane_segmentation/pcl_visualization_catkin/package.xml index afe59140..ebdcc8c3 100644 --- a/plane_segmentation/pcl_catkin/package.xml +++ b/plane_segmentation/pcl_visualization_catkin/package.xml @@ -1,8 +1,8 @@ - pcl_catkin + pcl_visualization_catkin 1.10.0 - Catkin wrapper for PCL. + Catkin wrapper for PCL visualization. Ruben Grandia See package From f956bb68f2b8998f5b8e7aeca30bec10e00604ad Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 09:40:27 +0200 Subject: [PATCH 209/504] add resample size tests --- .../grid_map_filters_rsl/src/inpainting.cpp | 2 +- .../grid_map_filters_rsl/test/TestFilters.cpp | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp b/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp index 6df2b258..a3aaa19b 100644 --- a/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp +++ b/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp @@ -262,7 +262,7 @@ void resample(grid_map::GridMap& map, const std::string& layer, double newRes) { for (const auto& layer_name : layer_names) { Eigen::MatrixXf elevationMap = std::move(map.get(layer_name)); - // Convert elevation map ro open-cv image. + // Convert elevation map to open-cv image. cv::Mat elevationImage; cv::eigen2cv(elevationMap, elevationImage); diff --git a/plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp b/plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp index cbe445b8..c090a1e6 100644 --- a/plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp +++ b/plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp @@ -75,3 +75,70 @@ TEST(TestInpainting, minValuesOnlyNaN) { // NOLINT EXPECT_TRUE(map.get("filled_min_nan").hasNaN()); EXPECT_DOUBLE_EQ(map.get("filled_min_nonan").minCoeff(), 1.0); } + +TEST(TestResampling, resampleSameSize) { // NOLINT + const std::string layerName = "layer"; + + GridMap map; + map.setGeometry(Length(3.0, 2.01), 0.33, Position(0.1, 0.2)); + map.add(layerName); + map.get(layerName).setRandom(); + + GridMap resampleMap = map; + + inpainting::resample(resampleMap, layerName, map.getResolution()); + + // Compare geometry + EXPECT_TRUE(resampleMap.getSize().isApprox(map.getSize())); + EXPECT_TRUE(resampleMap.getPosition().isApprox(map.getPosition())); + EXPECT_DOUBLE_EQ(resampleMap.getResolution(), map.getResolution()); + + // Compare content + EXPECT_TRUE(resampleMap.get(layerName).isApprox(map.get(layerName))); +} + +TEST(TestResampling, resampleUpsample) { // NOLINT + const std::string layerName = "layer"; + const double oldRes = 1.0; + const double newRes = 0.5; + + GridMap map; + map.setGeometry(Length(3.0, 2.0), oldRes, Position(0.1, 0.2)); + map.add(layerName); + map.get(layerName).setRandom(); + + GridMap resampleMap = map; + + inpainting::resample(resampleMap, layerName, newRes); + + // Compare geometry + const Eigen::Vector2d oldTrueSize(map.getResolution() * map.getSize().x(), map.getResolution() * map.getSize().y()); + const Eigen::Vector2d newTrueSize(resampleMap.getResolution() * resampleMap.getSize().x(), + resampleMap.getResolution() * resampleMap.getSize().y()); + EXPECT_TRUE(newTrueSize.isApprox(oldTrueSize)); + EXPECT_TRUE(resampleMap.getPosition().isApprox(map.getPosition())); + EXPECT_DOUBLE_EQ(resampleMap.getResolution(), newRes); +} + +TEST(TestResampling, resampleDownsample) { // NOLINT + const std::string layerName = "layer"; + const double oldRes = 0.5; + const double newRes = 1.0; + + GridMap map; + map.setGeometry(Length(3.0, 2.0), oldRes, Position(0.1, 0.2)); + map.add(layerName); + map.get(layerName).setRandom(); + + GridMap resampleMap = map; + + inpainting::resample(resampleMap, layerName, newRes); + + // Compare geometry + const Eigen::Vector2d oldTrueSize(map.getResolution() * map.getSize().x(), map.getResolution() * map.getSize().y()); + const Eigen::Vector2d newTrueSize(resampleMap.getResolution() * resampleMap.getSize().x(), + resampleMap.getResolution() * resampleMap.getSize().y()); + EXPECT_TRUE(newTrueSize.isApprox(oldTrueSize)); + EXPECT_TRUE(resampleMap.getPosition().isApprox(map.getPosition())); + EXPECT_DOUBLE_EQ(resampleMap.getResolution(), newRes); +} \ No newline at end of file From 548eb7cdd32f774b5efd2096fc276c0b776b67a2 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 09:54:13 +0200 Subject: [PATCH 210/504] improve pcl visualization catkin --- .../pcl_visualization_catkin/CMakeLists.txt | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt b/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt index 623099f6..8c3728b0 100644 --- a/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt +++ b/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt @@ -5,13 +5,23 @@ include(GNUInstallDirs) find_package(catkin REQUIRED) -file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so.1.10 DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so.1.10.0 DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) +find_package(PCL) +message(STATUS "PCL Version: " ${PCL_VERSION}) +message(STATUS "PCL_COMPONENTS: " ${PCL_COMPONENTS}) -file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib/pkgconfig) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/pkgconfig/pcl_visualization-1.10.pc DESTINATION ${CATKIN_DEVEL_PREFIX}/lib/pkgconfig) +if (${PCL_VISUALIZATION_FOUND}) + message(STATUS "pcl_visualization_catkin doing nothing, pcl_visualization is already found") +else() + message(STATUS "pcl_visualization_catkin is copying pcl_visualization 1.10") + + file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so.1.10 DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so.1.10.0 DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) + + file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib/pkgconfig) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/pkgconfig/pcl_visualization-1.10.pc DESTINATION ${CATKIN_DEVEL_PREFIX}/lib/pkgconfig) +endif () catkin_package( INCLUDE_DIRS From a9cac43f2a5c27d27af46a528a914e19fe1a258b Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 09:54:24 +0200 Subject: [PATCH 211/504] clean up demo setup --- .../config/demo_node.yaml | 6 +- .../config/parameters.yaml | 4 +- .../config/standalone_node.yaml | 7 --- .../data/demo_map.png | Bin 74823 -> 0 bytes .../data/elevationMap_0_107cm.png | Bin 1316 -> 0 bytes .../data/elevationMap_0_148cm.png | Bin 797 -> 0 bytes .../data/elevationMap_0_44cm.png | Bin 1175 -> 0 bytes .../data/elevationMap_10_277cm.png | Bin 21378 -> 0 bytes .../data/elevationMap_11_278cm.png | Bin 21764 -> 0 bytes .../data/elevationMap_8_139cm.png | Bin 20686 -> 0 bytes .../data/elevationMap_9_308cm.png | Bin 16873 -> 0 bytes ...Stairs_125cm.png => real_stairs_125cm.png} | Bin .../data/stepping_stones_65cm.png | Bin 2364 -> 0 bytes ...0cm.png => straight_stairs_1m_1m_60cm.png} | Bin .../launch/demo.launch | 12 ++-- .../launch/rviz.launch | 5 -- ...onmap.launch => save_elevation_map.launch} | 2 +- .../launch/standalone.launch | 11 ---- .../package.xml | 4 ++ .../rviz/config_demo.rviz | 59 +++++------------- 20 files changed, 33 insertions(+), 77 deletions(-) delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/config/standalone_node.yaml delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/demo_map.png delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_0_107cm.png delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_0_148cm.png delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_0_44cm.png delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_10_277cm.png delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_11_278cm.png delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_8_139cm.png delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_9_308cm.png rename plane_segmentation/convex_plane_decomposition_ros/data/{realStairs_125cm.png => real_stairs_125cm.png} (100%) delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/stepping_stones_65cm.png rename plane_segmentation/convex_plane_decomposition_ros/data/{straightStairs_1m_1m_60cm.png => straight_stairs_1m_1m_60cm.png} (100%) delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/launch/rviz.launch rename plane_segmentation/convex_plane_decomposition_ros/launch/{convex_plane_decomposition_save_elevationmap.launch => save_elevation_map.launch} (68%) delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/launch/standalone.launch diff --git a/plane_segmentation/convex_plane_decomposition_ros/config/demo_node.yaml b/plane_segmentation/convex_plane_decomposition_ros/config/demo_node.yaml index 214d2a57..6ded383e 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/config/demo_node.yaml +++ b/plane_segmentation/convex_plane_decomposition_ros/config/demo_node.yaml @@ -2,7 +2,7 @@ elevation_topic: '/elevation_mapping/elevation_map_raw' height_layer: 'elevation' target_frame_id: 'odom' submap: - width: 6.0 - length: 6.0 + width: 8.0 + length: 8.0 publish_to_controller: true -frequency: 10.0 +frequency: 1.0 diff --git a/plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml b/plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml index 412d6018..af26a631 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml +++ b/plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml @@ -17,10 +17,10 @@ sliding_window_plane_extractor: global_plane_fit_angle_error_threshold_degrees: 25.0 # [deg] Allowed normal vector deviation for a point w.r.t. the plane normal. If any point violates this, RANSAC is triggered ransac_plane_refinement: - probability: 0.01 # Probability to miss the largest candidate shape. A lower probability provides a higher reliability and determinism at the cost of longer running times + probability: 0.001 # Probability to miss the largest candidate shape. A lower probability provides a higher reliability and determinism at the cost of longer running times min_points: 4 # This minimum number of points per plane. Controls the termination of the algorithm. epsilon: 0.025 # Maximum distance to plane - cluster_epsilon: 0.08 # [m] Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon. Set this higher than resolution + cluster_epsilon: 0.041 # [m] Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon. Set this higher than resolution normal_threshold: 25.0 # [deg] Set maximum normal deviation between cluster surface_normal and point normal. contour_extraction: diff --git a/plane_segmentation/convex_plane_decomposition_ros/config/standalone_node.yaml b/plane_segmentation/convex_plane_decomposition_ros/config/standalone_node.yaml deleted file mode 100644 index f6b76949..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/config/standalone_node.yaml +++ /dev/null @@ -1,7 +0,0 @@ -elevation_topic: '/elevation_mapping/elevation_map_recordable' -height_layer: 'elevation' -submap: - width: 3.0 - length: 3.0 -publish_to_controller: false -frequency: 10.0 diff --git a/plane_segmentation/convex_plane_decomposition_ros/data/demo_map.png b/plane_segmentation/convex_plane_decomposition_ros/data/demo_map.png deleted file mode 100644 index f3911e7b91f2642af22212cd54d5eff712738484..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74823 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

*j>9YiEsg>7?=EQgVe_~zM{hDrM^pv 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 BHv#|v diff --git a/plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_0_148cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/elevationMap_0_148cm.png deleted file mode 100644 index caf91d540f74e3cea59a685c186b0b9f3b504836..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 797 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 Y4?!yjZ)IQf-&u>Wz9E>}lL^2654pL?i2wiq diff --git a/plane_segmentation/convex_plane_decomposition_ros/data/straightStairs_1m_1m_60cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/straight_stairs_1m_1m_60cm.png similarity index 100% rename from plane_segmentation/convex_plane_decomposition_ros/data/straightStairs_1m_1m_60cm.png rename to plane_segmentation/convex_plane_decomposition_ros/data/straight_stairs_1m_1m_60cm.png diff --git a/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch index 09f41c17..6ddfbdfb 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch +++ b/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch @@ -19,10 +19,10 @@ - - - - + + + + @@ -31,7 +31,7 @@ - + @@ -39,6 +39,6 @@ - + diff --git a/plane_segmentation/convex_plane_decomposition_ros/launch/rviz.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/rviz.launch deleted file mode 100644 index b3062364..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/launch/rviz.launch +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/save_elevation_map.launch similarity index 68% rename from plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch rename to plane_segmentation/convex_plane_decomposition_ros/launch/save_elevation_map.launch index d2b9ec81..702525a3 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition_save_elevationmap.launch +++ b/plane_segmentation/convex_plane_decomposition_ros/launch/save_elevation_map.launch @@ -1,6 +1,6 @@ - diff --git a/plane_segmentation/convex_plane_decomposition_ros/launch/standalone.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/standalone.launch deleted file mode 100644 index 06cf11f5..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/launch/standalone.launch +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/plane_segmentation/convex_plane_decomposition_ros/package.xml b/plane_segmentation/convex_plane_decomposition_ros/package.xml index 126edcfe..d7cf3e66 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/package.xml +++ b/plane_segmentation/convex_plane_decomposition_ros/package.xml @@ -9,6 +9,7 @@ TODO catkin + roscpp grid_map_core grid_map_ros @@ -20,4 +21,7 @@ convex_plane_decomposition_msgs tf2_ros + grid_map_demos + pcl_visualization_catkin + diff --git a/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz b/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz index c49630ca..6df62f08 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz +++ b/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz @@ -5,9 +5,8 @@ Panels: Property Tree Widget: Expanded: - /Global Options1 - - /FilteredMap1 - Splitter Ratio: 0.4083484709262848 - Tree Height: 824 + Splitter Ratio: 0.6307384967803955 + Tree Height: 1658 - Class: rviz/Selection Name: Selection - Class: rviz/Tool Properties @@ -91,7 +90,7 @@ Visualization Manager: Color: 200; 200; 200 Color Layer: plane_classification Color Transformer: IntensityLayer - Enabled: true + Enabled: false Grid Cell Decimation: 1 Grid Line Thickness: 0.10000000149011612 Height Layer: elevation_before_postprocess @@ -107,31 +106,7 @@ Visualization Manager: Topic: /convex_plane_decomposition_ros/filtered_map Unreliable: false Use Rainbow: false - Value: true - - Class: rviz/MarkerArray - Enabled: true - Marker Topic: /segmented_planes_terrain_model_demo_node/convex_terrain - Name: ConvexRegion - Namespaces: - {} - Queue Size: 100 - Value: true - - Class: rviz/Marker - Enabled: true - Marker Topic: /segmented_planes_terrain_model_demo_node/queryPosition - Name: queryPosition - Namespaces: - {} - Queue Size: 100 - Value: true - - Class: rviz/MarkerArray - Enabled: true - Marker Topic: /segmented_planes_terrain_model_demo_node/regionBoundary - Name: SelectedRegion - Namespaces: - {} - Queue Size: 100 - Value: true + Value: false Enabled: true Global Options: Background Color: 255; 255; 255 @@ -160,7 +135,7 @@ Visualization Manager: Views: Current: Class: rviz/XYOrbit - Distance: 23.61389923095703 + Distance: 12.910699844360352 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 @@ -168,25 +143,25 @@ Visualization Manager: Value: false Field of View: 0.7853981852531433 Focal Point: - X: 8.348309516906738 - Y: 0.002288922667503357 - Z: 3.0517578125e-05 + X: 0.23195862770080566 + Y: 6.398481369018555 + Z: 3.2901763916015625e-05 Focal Shape Fixed Size: true Focal Shape Size: 0.05000000074505806 Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.8357961773872375 + Pitch: 0.5807958841323853 Target Frame: - Yaw: 0 + Yaw: 1.4850016832351685 Saved: ~ Window Geometry: Displays: - collapsed: true - Height: 1043 - Hide Left Dock: true + collapsed: false + Height: 2032 + Hide Left Dock: false Hide Right Dock: false - QMainWindow State: 000000ff00000000fd00000004000000000000022900000375fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073000000003d00000375000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f00000375fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d00000375000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007380000003efc0100000002fb0000000800540069006d0065010000000000000738000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000007380000037500000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd0000000400000000000001f7000006e8fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b000000b000fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000b0fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000006e000006e80000018200fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f00000375fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d000003750000013200fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e1000001970000000300000e7000000060fc0100000002fb0000000800540069006d0065010000000000000e700000057100fffffffb0000000800540069006d0065010000000000000450000000000000000000000c6d000006e800000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -195,6 +170,6 @@ Window Geometry: collapsed: false Views: collapsed: false - Width: 1848 - X: 72 - Y: 0 + Width: 3696 + X: 3984 + Y: 54 From d06b033e570f119aecd3b9238b47e2c0c0090659 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 10:02:03 +0200 Subject: [PATCH 212/504] fix typo --- .../convex_plane_decomposition/test/testRegionGrowing.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plane_segmentation/convex_plane_decomposition/test/testRegionGrowing.cpp b/plane_segmentation/convex_plane_decomposition/test/testRegionGrowing.cpp index e0932c28..dca141a4 100644 --- a/plane_segmentation/convex_plane_decomposition/test/testRegionGrowing.cpp +++ b/plane_segmentation/convex_plane_decomposition/test/testRegionGrowing.cpp @@ -28,8 +28,8 @@ TEST(TestRegionGrowing, center_on_border) { } TEST(TestRegionGrowing, debug_case) { - // Rare case where the region algorithm go stuck - const int numberOfVertices = 16; // Multiple of 4 is nice for symmetry. + // Rare case where the region algorithm got stuck + const int numberOfVertices = 16; const double growthFactor = 1.05; CgalPoint2d center(-0.147433, 0.800114); From e99f5f585ee9d1ba7970092b8360d33713f6948c Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 10:44:17 +0200 Subject: [PATCH 213/504] remove unused method --- .../ConvexPlaneDecompositionRos.h | 2 -- .../src/ConvexPlaneDecompositionRos.cpp | 10 ---------- 2 files changed, 12 deletions(-) diff --git a/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h index a51ae69a..d57f8d6d 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h +++ b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h @@ -35,8 +35,6 @@ class ConvexPlaneExtractionROS { Eigen::Isometry3d getTransformToTargetFrame(const std::string& sourceFrame, const ros::Time& time); - ros::Time getMessageTime(const grid_map_msgs::GridMap& message) const; - // Parameters std::string elevationMapTopic_; std::string elevationLayer_; diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index ed569c7c..fddddf4d 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -183,14 +183,4 @@ Eigen::Isometry3d ConvexPlaneExtractionROS::getTransformToTargetFrame(const std: return transformation; } -ros::Time ConvexPlaneExtractionROS::getMessageTime(const grid_map_msgs::GridMap& message) const { - try { - ros::Time time; - return time.fromNSec(message.info.header.stamp.toNSec()); - } catch (std::runtime_error& ex) { - ROS_WARN("[ConvexPlaneExtractionROS::getMessageTime] %s", ex.what()); - return ros::Time::now(); - } -} - } // namespace convex_plane_decomposition From 7fe66eb3e14d04fffb8e2264909e39ad1966181d Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 10:44:34 +0200 Subject: [PATCH 214/504] remove growing median filter --- .../GridMapPreprocessing.h | 2 - .../src/GridMapPreprocessing.cpp | 47 ++----------------- .../config/parameters.yaml | 1 - .../src/ParameterLoading.cpp | 1 - 4 files changed, 4 insertions(+), 47 deletions(-) diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h index 5f04874a..ebd34b0f 100644 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h +++ b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h @@ -13,8 +13,6 @@ struct PreprocessingParameters { int kernelSize = 3; /// Number of times the image is filtered int numberOfRepeats = 2; - /// If the kernel size should increase each filter step. - bool increasing = false; }; class GridMapPreprocessing { diff --git a/plane_segmentation/convex_plane_decomposition/src/GridMapPreprocessing.cpp b/plane_segmentation/convex_plane_decomposition/src/GridMapPreprocessing.cpp index 48dd31db..265918e6 100644 --- a/plane_segmentation/convex_plane_decomposition/src/GridMapPreprocessing.cpp +++ b/plane_segmentation/convex_plane_decomposition/src/GridMapPreprocessing.cpp @@ -5,6 +5,7 @@ #include #include +#include namespace convex_plane_decomposition { @@ -17,55 +18,15 @@ void GridMapPreprocessing::preprocess(grid_map::GridMap& gridMap, const std::str } void GridMapPreprocessing::denoise(grid_map::GridMap& gridMap, const std::string& layer) const { - Eigen::MatrixXf& elevation_map = gridMap.get(layer); - - cv::Mat elevationImage; - cv::eigen2cv(elevation_map, elevationImage); // creates CV_32F image - - int kernelSize = parameters_.kernelSize; - - for (int i = 0; i < parameters_.numberOfRepeats; ++i) { - kernelSize = std::max(3, std::min(kernelSize, 5)); // must be 3 or 5 for current image type, see doc of cv::medianBlur - cv::medianBlur(elevationImage, elevationImage, kernelSize); - if (parameters_.increasing) { // TODO (rgrandia) : remove this option or enable kernels of other size than 3 / 5 - kernelSize += 2; - } - } - - cv::cv2eigen(elevationImage, elevation_map); + int kernelSize = std::max(1, std::min(parameters_.kernelSize, 5)); // must be 1, 3 or 5 for current image type, see doc of cv::medianBlur + grid_map::smoothing::median(gridMap, layer, layer, kernelSize, 0, parameters_.numberOfRepeats); } void GridMapPreprocessing::changeResolution(grid_map::GridMap& gridMap, const std::string& layer) const { bool hasSameResolution = std::abs(gridMap.getResolution() - parameters_.resolution) < 1e-6; if (parameters_.resolution > 0.0 && !hasSameResolution) { - // Original map info - const auto oldPosition = gridMap.getPosition(); - const auto oldSize = gridMap.getSize(); - const auto oldResolution = gridMap.getResolution(); - - Eigen::MatrixXf elevation_map = std::move(gridMap.get(layer)); - - cv::Mat elevationImage; - cv::eigen2cv(elevation_map, elevationImage); - - double scaling = oldResolution / parameters_.resolution; - int width = int(elevationImage.size[1] * scaling); - int height = int(elevationImage.size[0] * scaling); - cv::Size dim{width, height}; - - cv::Mat resizedImage; - cv::resize(elevationImage, resizedImage, dim, 0, 0, cv::INTER_LINEAR); - - cv::cv2eigen(resizedImage, elevation_map); - - // Compute true new resolution. Might be slightly different due to rounding. Take average of both dimensions. - grid_map::Size newSize = {elevation_map.rows(), elevation_map.cols()}; - const double newResolution = 0.5 * ((oldSize[0] * oldResolution) / newSize[0] + (oldSize[1] * oldResolution) / newSize[1]); - grid_map::Position newPosition = oldPosition; - - gridMap.setGeometry({newSize[0] * newResolution, newSize[1] * newResolution}, newResolution, newPosition); - gridMap.get(layer) = std::move(elevation_map); + grid_map::inpainting::resample(gridMap, layer, parameters_.resolution); } } diff --git a/plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml b/plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml index af26a631..fa153584 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml +++ b/plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml @@ -2,7 +2,6 @@ preprocessing: resolution: 0.04 # Resampling resolution, set negative to skip, requires inpainting to be used kernelSize: 3 # Kernel size of the median filter, either 3 or 5 numberOfRepeats: 1 # Number of times to apply the same filter - increasing: False # Increase the kernel size each iteration. sliding_window_plane_extractor: kernel_size: 3 # Size of the sliding window patch used for normal vector calculation and planarity detection. Should be an odd number and at least 3. diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/ParameterLoading.cpp index 1859b1df..3fac5d4c 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ b/plane_segmentation/convex_plane_decomposition_ros/src/ParameterLoading.cpp @@ -22,7 +22,6 @@ PreprocessingParameters loadPreprocessingParameters(const ros::NodeHandle& nodeH loadParameter(nodeHandle, prefix, "resolution", preprocessingParameters.resolution); loadParameter(nodeHandle, prefix, "kernelSize", preprocessingParameters.kernelSize); loadParameter(nodeHandle, prefix, "numberOfRepeats", preprocessingParameters.numberOfRepeats); - loadParameter(nodeHandle, prefix, "increasing", preprocessingParameters.increasing); return preprocessingParameters; } From c87bd854ad47be32339ec73b399efce96e00e576 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 10:45:07 +0200 Subject: [PATCH 215/504] add inner approximation demo to readme --- plane_segmentation/README.md | 25 ++- .../CMakeLists.txt | 14 +- ...{shapeGrowing.cpp => TestShapeGrowing.cpp} | 16 +- .../test/test.cpp | 162 ------------------ 4 files changed, 27 insertions(+), 190 deletions(-) rename plane_segmentation/convex_plane_decomposition_ros/test/{shapeGrowing.cpp => TestShapeGrowing.cpp} (80%) delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/test/test.cpp diff --git a/plane_segmentation/README.md b/plane_segmentation/README.md index a0312dff..1b1c5388 100644 --- a/plane_segmentation/README.md +++ b/plane_segmentation/README.md @@ -1,7 +1,9 @@ -# Convex Terrain Representation # +# Plane Segmentation ## Overview -This is a C++ ROS package for extracting convex polygons from elevation maps created by elevation_mapping. +This is a C++ ROS package for extracting convex polygons from elevation maps. +In a first step, the terrain is segmented into planes, and their non-convex contour is extracted. +In a second step, a local convex approximation can be obtained. ## Installation @@ -30,11 +32,10 @@ sudo apt-get install libboost-all-dev #### PCL PCL is required, but the ANYbotics distributed version does not contain visualization components. -With the following commands, the missing components are provided into your catkin workspace. -DO NOT do this on the ANYmal onboard PCs, only on OPC and simulation PCs. +With pcl_visualization_catkin, the missing components are provided into your catkin workspace (for pcl 1.10). +Additionally vtk7 is required, DO NOT install this on the ANYmal onboard PCs, only on OPC and simulation PCs. ```bash sudo apt-get install libvtk7-dev -catkin build pcl_visualization_catkin ``` ### ROS package dependencies @@ -46,7 +47,7 @@ sudo apt-get install ros-noetic-jsk-visualization ``` #### Grid Map -Grid map is available through ANYmal-research, or you can add it to your workspace. You can clone it using: +Grid map is available through ANYmal-research, apt install, or you can add it to your workspace. You can clone it using: ```bash git clone https://github.com/ANYbotics/grid_map.git ``` @@ -56,11 +57,23 @@ git clone https://github.com/ANYbotics/grid_map.git ```bash catkin build convex_plane_decomposition_ros ``` + +### Run as node +```bash +roslaunch convex_plane_decomposition_ros convex_plane_decomposition.launch +``` + ### Run demo ```bash roslaunch convex_plane_decomposition_ros demo.launch ``` +### Convex approximation demo +A simple 2D demo the convex inner approximation is available: +```bash +rosrun convex_plane_decomposition_ros convex_plane_decomposition_ros_TestShapeGrowing +``` + ### Parameters You can select input map topics, pipeline parameters etc. in the respective yaml file in ```bash diff --git a/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt index a30f0a7d..b3c110cb 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt +++ b/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt @@ -111,18 +111,10 @@ install(DIRECTORY config data launch rviz ############# ## Testing ## ############# -add_executable(${PROJECT_NAME}_test - test/test.cpp +add_executable(${PROJECT_NAME}_TestShapeGrowing + test/TestShapeGrowing.cpp ) -target_link_libraries(${PROJECT_NAME}_test - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} -) - -add_executable(${PROJECT_NAME}_shapegrowing - test/shapeGrowing.cpp -) -target_link_libraries(${PROJECT_NAME}_shapegrowing +target_link_libraries(${PROJECT_NAME}_TestShapeGrowing ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} ) \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_ros/test/shapeGrowing.cpp b/plane_segmentation/convex_plane_decomposition_ros/test/TestShapeGrowing.cpp similarity index 80% rename from plane_segmentation/convex_plane_decomposition_ros/test/shapeGrowing.cpp rename to plane_segmentation/convex_plane_decomposition_ros/test/TestShapeGrowing.cpp index 400af2e2..0dcc4c92 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/test/shapeGrowing.cpp +++ b/plane_segmentation/convex_plane_decomposition_ros/test/TestShapeGrowing.cpp @@ -6,8 +6,6 @@ #include #include -#include - using namespace convex_plane_decomposition; int main(int argc, char** argv) { @@ -21,30 +19,26 @@ int main(int argc, char** argv) { parentShape.add_hole(createRegularPolygon(CgalPoint2d(200.0, 200.0), 50, 4)); parentShape.add_hole(createRegularPolygon(CgalPoint2d(600.0, 700.0), 100, 100)); - // bounded_side_2 -> is inside - - int numberOfVertices = 16; // Multiple of 4 is nice. + int numberOfVertices = 16; double growthFactor = 1.05; - CgalPoint2d center{700.0, 300.0}; cv::Size imgSize(1000, 1000); - const auto parentColor = randomColor(); const auto fitColor = randomColor(); int N_test = 10; for (int i = 0; i < N_test; i++) { - center = CgalPoint2d(rand()%1000, rand()%1000); + CgalPoint2d center = CgalPoint2d(rand() % imgSize.width, rand() % imgSize.height); cv::Mat polygonImage(imgSize, CV_8UC3, cv::Vec3b(0, 0, 0)); drawContour(polygonImage, parentShape, &parentColor); drawContour(polygonImage, center, 2, &fitColor); - if (isInside(center, parentShape )) { + if (isInside(center, parentShape)) { const auto fittedPolygon2d = growConvexPolygonInsideShape(parentShape, center, numberOfVertices, growthFactor); drawContour(polygonImage, fittedPolygon2d, &fitColor); } - cv::namedWindow("Polygon", cv::WindowFlags::WINDOW_NORMAL); - cv::imshow("Polygon", polygonImage); + cv::namedWindow("TestShapeGrowing", cv::WindowFlags::WINDOW_NORMAL); + cv::imshow("TestShapeGrowing", polygonImage); cv::waitKey(0); // Wait for a keystroke in the window } diff --git a/plane_segmentation/convex_plane_decomposition_ros/test/test.cpp b/plane_segmentation/convex_plane_decomposition_ros/test/test.cpp deleted file mode 100644 index f952b6d3..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/test/test.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// Created by rgrandia on 04.06.20. -// - -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace convex_plane_decomposition; - -void plotSlidingWindow(const sliding_window_plane_extractor::SlidingWindowPlaneExtractor& planeExtractor) { - cv::namedWindow("Sliding Window binarymap", cv::WindowFlags::WINDOW_NORMAL); - cv::Mat binaryImage = planeExtractor.getBinaryLabeledImage(); - binaryImage.convertTo(binaryImage, CV_8UC1, 255); - cv::imshow("Sliding Window binarymap", binaryImage); - - cv::namedWindow("Sliding Window labels", cv::WindowFlags::WINDOW_NORMAL); - const auto& labelledImage = planeExtractor.getSegmentedPlanesMap().labeledImage; - const auto& labelsAndPlaneParameters = planeExtractor.getSegmentedPlanesMap().labelPlaneParameters; - std::vector colors(planeExtractor.getSegmentedPlanesMap().highestLabel + 1); - - colors[0] = cv::Vec3b(0, 0, 0); // background in white - for (int label = 1; label <= planeExtractor.getSegmentedPlanesMap().highestLabel; ++label) { - const auto labelIt = std::find_if(labelsAndPlaneParameters.begin(), labelsAndPlaneParameters.end(), - [=](const std::pair& x) { return x.first == label; }); - if (labelIt != labelsAndPlaneParameters.end()) { - colors[label] = randomColor(); - } else { - colors[label] = colors[0]; - } - } - cv::Mat colorImg(labelledImage.size(), CV_8UC3); - for (int r = 0; r < colorImg.rows; ++r) { - for (int c = 0; c < colorImg.cols; ++c) { - int label = labelledImage.at(r, c); - auto& pixel = colorImg.at(r, c); - pixel = colors[label]; - } - } - cv::imshow("Sliding Window labels", colorImg); -} - -int main(int argc, char** argv) { - boost::filesystem::path filePath(__FILE__); - std::string folder = filePath.parent_path().parent_path().generic_string() + std::string{"/data/"}; - std::string file = "elevationMap_8_139cm.png"; - double heightScale = 1.39; - // std::string file = "demo_map.png"; double heightScale = 1.25; - // std::string file = "realStairs_125cm.png"; double heightScale = 1.25; - // std::string file = "terrain.png"; double heightScale = 1.25; - // std::string file = "holes.png"; double heightScale = 1.0; - // std::string file = "slope_1m_1m_20cm.png"; double heightScale = 0.2; - // std::string file = "straightStairs_1m_1m_60cm.png"; double heightScale = 0.6; - double resolution = 0.02; - - auto elevationMap = loadGridmapFromImage(folder + file, "elevation", "odom", resolution, heightScale); - - cv::Mat image; - grid_map::GridMapCvConverter::toImage(elevationMap, "elevation", CV_8UC1, 0.0, heightScale, image); - cv::namedWindow("Elevation Map", cv::WindowFlags::WINDOW_NORMAL); - cv::imshow("Elevation Map", image); - - // ================== Filter ======================== // - PreprocessingParameters preprocessingParameters; - preprocessingParameters.kernelSize = 5; - preprocessingParameters.numberOfRepeats = 1; - - GridMapPreprocessing preprocessing(preprocessingParameters); - preprocessing.preprocess(elevationMap, "elevation"); - - grid_map::GridMapCvConverter::toImage(elevationMap, "elevation", CV_8UC1, 0.0, heightScale, image); - cv::namedWindow("Filtered Map", cv::WindowFlags::WINDOW_NORMAL); - cv::imshow("Filtered Map", image); - - // ============== Sliding Window =================== // - sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters swParams; - swParams.kernel_size = 3; - swParams.plane_inclination_threshold = std::cos(45.0 * M_PI / 180); - swParams.plane_patch_error_threshold = 0.005; - swParams.min_number_points_per_label = 10; - swParams.include_ransac_refinement = true; - swParams.global_plane_fit_distance_error_threshold = 0.04; - swParams.global_plane_fit_angle_error_threshold_degrees = 5.0; - - ransac_plane_extractor::RansacPlaneExtractorParameters ransacParameters; - ransacParameters.probability = 0.01; - ransacParameters.min_points = 25; - ransacParameters.epsilon = 0.02; - ransacParameters.cluster_epsilon = 0.05; - ransacParameters.normal_threshold = 0.98; - - sliding_window_plane_extractor::SlidingWindowPlaneExtractor planeExtractor(swParams, ransacParameters); - planeExtractor.runExtraction(elevationMap, "elevation"); - plotSlidingWindow(planeExtractor); - - // ============== Polygons =================== // - const auto& labeled_image = planeExtractor.getSegmentedPlanesMap().labeledImage; - cv::Mat binary_image(labeled_image.size(), CV_8UC1); - - for (const auto& label_plane : planeExtractor.getSegmentedPlanesMap().labelPlaneParameters) { - const int label = label_plane.first; - - binary_image = labeled_image == label; - - // Plot binary image - cv::Mat binaryImagePlot = binary_image; - binaryImagePlot.convertTo(binaryImagePlot, CV_8UC1, 255); - cv::namedWindow("Polygon binary image label", cv::WindowFlags::WINDOW_NORMAL); - cv::imshow("Polygon binary image label", binaryImagePlot); - - // Extract - int erosion_size = 2; // single sided length of the kernel - int erosion_type = cv::MORPH_CROSS; // cv::MORPH_ELLIPSE, cv::MORPH_RECT - cv::Mat element = cv::getStructuringElement(erosion_type, cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1)); - const auto boundariesAndInsets = contour_extraction::extractBoundaryAndInset(binary_image, element); - - // Plot eroded image - cv::Mat erodedImagePlot = binary_image; - erodedImagePlot.convertTo(erodedImagePlot, CV_8UC1, 255); - cv::namedWindow("Polygon binary eroded label", cv::WindowFlags::WINDOW_NORMAL); - cv::imshow("Polygon binary eroded label", erodedImagePlot); - - // Plot contours - int scale = 5; - cv::Size scaledSize = {scale * binary_image.size().width, scale * binary_image.size().height}; // transposed - cv::Mat realPolygonImage(scaledSize, CV_8UC3, cv::Vec3b(0, 0, 0)); - for (const auto& boundaryAndInset : boundariesAndInsets) { - drawContour(realPolygonImage, scaleShape(boundaryAndInset.boundary, scale)); - for (const auto& inset : boundaryAndInset.insets) { - drawContour(realPolygonImage, scaleShape(inset, scale)); - } - } - - cv::namedWindow("Polygon real", cv::WindowFlags::WINDOW_NORMAL); - cv::imshow("Polygon real", realPolygonImage); - cv::waitKey(0); // Wait for a keystroke in the window - } - - // ============== planar regions extraction ================ - contour_extraction::ContourExtractionParameters polyParams; - polyParams.marginSize = 2; - - contour_extraction::ContourExtraction contourExtraction(polyParams); - contourExtraction.extractPlanarRegions(planeExtractor.getSegmentedPlanesMap()); - - return 0; -} \ No newline at end of file From 5611a75c5cd19b78221dcd13018e6d8754ee6c23 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 10:46:56 +0200 Subject: [PATCH 216/504] fix spacing --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index 13f60800..bece82f4 100644 --- a/README.md +++ b/README.md @@ -14,19 +14,12 @@ Code are written in python and uses cupy for GPU calculation. ``` @misc{https://doi.org/10.48550/arxiv.2204.12876, doi = {10.48550/ARXIV.2204.12876}, - url = {https://arxiv.org/abs/2204.12876}, - author = {Miki, Takahiro and Wellhausen, Lorenz and Grandia, Ruben and Jenelten, Fabian and Homberger, Timon and Hutter, Marco}, - keywords = {Robotics (cs.RO), FOS: Computer and information sciences, FOS: Computer and information sciences}, - title = {Elevation Mapping for Locomotion and Navigation using GPU}, - publisher = {arXiv}, - year = {2022}, - copyright = {arXiv.org perpetual, non-exclusive license} } ``` From f641486fb3216c0a70c74ed12999abbb5d8a01ea Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 11:00:40 +0200 Subject: [PATCH 217/504] fix pragma once placement --- .../include/convex_plane_decomposition/GeometryUtils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h index 1a2f432d..bd7c849d 100644 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h +++ b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h @@ -2,11 +2,11 @@ // Created by rgrandia on 09.06.20. // +#pragma once + #include "PlanarRegion.h" #include "PolygonTypes.h" -#pragma once - namespace convex_plane_decomposition { inline bool doEdgesIntersect(const CgalSegment2d& line, const CgalPolygon2d& contour) { From 9b27ad903add1cbee3da74ed439a462a833d8ce5 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 11:00:51 +0200 Subject: [PATCH 218/504] restore git ignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9f11b755..732c5512 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -.idea/ +*.pyc +*.bkp +*.orig From 4ffb2d4791b629bf8a3c22dd99aa963964f3ba28 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 11:01:02 +0200 Subject: [PATCH 219/504] set license --- plane_segmentation/convex_plane_decomposition/package.xml | 2 +- .../convex_plane_decomposition_msgs/package.xml | 3 ++- .../convex_plane_decomposition_ros/package.xml | 2 +- plane_segmentation/grid_map_filters_rsl/package.xml | 7 ++++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/plane_segmentation/convex_plane_decomposition/package.xml b/plane_segmentation/convex_plane_decomposition/package.xml index 38f1d22b..b4627803 100644 --- a/plane_segmentation/convex_plane_decomposition/package.xml +++ b/plane_segmentation/convex_plane_decomposition/package.xml @@ -6,7 +6,7 @@ Ruben Grandia - TODO + MIT catkin cgal5_catkin diff --git a/plane_segmentation/convex_plane_decomposition_msgs/package.xml b/plane_segmentation/convex_plane_decomposition_msgs/package.xml index 3e20ee3b..2af22815 100644 --- a/plane_segmentation/convex_plane_decomposition_msgs/package.xml +++ b/plane_segmentation/convex_plane_decomposition_msgs/package.xml @@ -6,9 +6,10 @@ 0.0.0 Convex plane decomposition message definitions. - TODO Ruben Grandia + MIT + catkin message_generation diff --git a/plane_segmentation/convex_plane_decomposition_ros/package.xml b/plane_segmentation/convex_plane_decomposition_ros/package.xml index d7cf3e66..d83524d5 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/package.xml +++ b/plane_segmentation/convex_plane_decomposition_ros/package.xml @@ -6,7 +6,7 @@ Ruben Grandia - TODO + MIT catkin diff --git a/plane_segmentation/grid_map_filters_rsl/package.xml b/plane_segmentation/grid_map_filters_rsl/package.xml index 0c00cdb8..481135ce 100644 --- a/plane_segmentation/grid_map_filters_rsl/package.xml +++ b/plane_segmentation/grid_map_filters_rsl/package.xml @@ -4,10 +4,11 @@ 0.1.0 Extension of grid map filters package with op-cv filters and others Fabian Jenelten - Proprietary - http://bitbucket.org/leggedrobotics/anymal_rsl_locomotion + Fabian Jenelten - + + MIT + catkin cmake_clang_tools grid_map_cv From 7d0e32420a8e8341bb99a540380703c36a632b8a Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 15:14:31 +0200 Subject: [PATCH 220/504] add segmentation demo --- README.md | 51 ++- .../launch/turtlesim_example.launch | 4 +- .../turtlesim_segmentation_example.launch | 13 + .../rviz/turtle_segmentation_example.rviz | 305 ++++++++++++++++++ 4 files changed, 366 insertions(+), 7 deletions(-) create mode 100644 elevation_mapping_cupy/launch/turtlesim_segmentation_example.launch create mode 100644 elevation_mapping_cupy/rviz/turtle_segmentation_example.rviz diff --git a/README.md b/README.md index bece82f4..b26178c8 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,18 @@ # Elevation Mapping cupy ## Overview + This is a ros package of elevation mapping on GPU. Code are written in python and uses cupy for GPU calculation. ![screenshot](doc/main_repo.png) \* plane segmentation is coming soon. - ## Citing + > Takahiro Miki, Lorenz Wellhausen, Ruben Grandia, Fabian Jenelten, Timon Homberger, Marco Hutter > Elevation Mapping for Locomotion and Navigation using GPU [arXiv](https://arxiv.org/abs/2204.12876) + ``` @misc{https://doi.org/10.48550/arxiv.2204.12876, doi = {10.48550/ARXIV.2204.12876}, @@ -26,7 +28,11 @@ Code are written in python and uses cupy for GPU calculation. ## Installation +The following installation instructions are for elevation mapping. For the plane segmentation, please find additional instructions in the +dedicated README. + ### CUDA & cuDNN + The tested versions are CUDA10.2, 11.6 [CUDA](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#ubuntu-installation) @@ -34,9 +40,9 @@ The tested versions are CUDA10.2, 11.6 Check how to install [here](doc/cuda-installation.md). - ### Python dependencies -You will need + +You will need - [cupy](https://cupy.chainer.org/) - [numpy](https://www.numpy.org/) @@ -53,9 +59,11 @@ Optinally, opencv for inpainting filter. - [opencv-python](https://opencv.org/) Install `numpy`, `scipy`, `shapely`, `opencv-python` with the following command. + ```bash pip3 install -r requirements.txt ``` + #### Cupy cupy can be installed with specific CUDA versions. (On jetson, only "from source" i.e. `pip install cupy` could work) > For CUDA 10.2 @@ -85,8 +93,8 @@ cupy can be installed with specific CUDA versions. (On jetson, only "from source > (Install CuPy from source) > % pip install cupy - #### Traversability filter + You can choose either pytorch, or chainer to run the CNN based traversability filter. Install by following the official documents. @@ -107,23 +115,31 @@ sudo apt install ros-noetic-grid-map-core ros-noetic-grid-map-msgs ``` ## On Jetson + #### CUDA CuDNN + `CUDA` and `cuDNN` can be installed via apt. It comes with nvidia-jetpack. The tested version is jetpack 4.5 with L4T 32.5.0. #### python dependencies + On jetson, you need the version for its CPU arch: + ```bash wget https://nvidia.box.com/shared/static/p57jwntv436lfrd78inwl7iml6p13fzh.whl -O torch-1.8.0-cp36-cp36m-linux_aarch64.whl pip3 install Cython pip3 install numpy==1.19.5 torch-1.8.0-cp36-cp36m-linux_aarch64.whl ``` + Also, you need to install cupy with + ```bash pip3 install cupy ``` + This builds the packages from source so it would take time. #### ROS dependencies + - [pybind11_catkin](https://github.com/ipab-slmc/pybind11_catkin) - [grid_map](https://github.com/ANYbotics/grid_map) @@ -133,6 +149,7 @@ sudo apt install ros-melodic-grid-map-core ros-melodic-grid-map-msgs ``` Also, on jetson you need fortran (should already be installed). + ```bash sudo apt install gfortran ``` @@ -144,13 +161,17 @@ git clone git@github.com:ros/filters.git -b noetic-devel ``` ## Usage + ### Build + ```bash catkin build elevation_mapping_cupy ``` #### Errors -If you get error such as + +If you get error such as + ``` Make Error at /usr/share/cmake-3.16/Modules/FindPackageHandleStandardArgs.cmake:146 (message): Could NOT find PythonInterp: Found unsuitable version "2.7.18", but @@ -158,32 +179,50 @@ Make Error at /usr/share/cmake-3.16/Modules/FindPackageHandleStandardArgs.cmake: ``` Build with option. + ```bash catkin build elevation_mapping_cupy -DPYTHON_EXECUTABLE=$(which python3) ``` ### Run + Basic usage. + ```bash roslaunch elevation_mapping_cupy elevation_mapping_cupy.launch ``` ### Run TurtleBot example + First, install turtlebot simulation. + ```bash sudo apt install ros-noetic-turtlebot3* ``` -Then, you can run the example. + +Then, you can run the examples. For the basic version: + ```bash export TURTLEBOT3_MODEL=waffle roslaunch elevation_mapping_cupy turtlesim_example.launch ``` + +Or, for the version including plane segmentation: + +```bash +catkin build convex_plane_decomposition_ros +export TURTLEBOT3_MODEL=waffle +roslaunch elevation_mapping_cupy turtlesim_segmentation_example.launch +``` + To control the robot with a keyboard, a new terminal window needs to be opened. Then run + ```bash export TURTLEBOT3_MODEL=waffle roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch ``` + Velocity inputs can be sent to the robot by pressing the keys `a`, `w`, `d`, `x`. To stop the robot completely, press `s`. diff --git a/elevation_mapping_cupy/launch/turtlesim_example.launch b/elevation_mapping_cupy/launch/turtlesim_example.launch index 39fb3f97..b63dae53 100644 --- a/elevation_mapping_cupy/launch/turtlesim_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_example.launch @@ -2,6 +2,8 @@ + + @@ -21,6 +23,6 @@ - + diff --git a/elevation_mapping_cupy/launch/turtlesim_segmentation_example.launch b/elevation_mapping_cupy/launch/turtlesim_segmentation_example.launch new file mode 100644 index 00000000..afb7fb01 --- /dev/null +++ b/elevation_mapping_cupy/launch/turtlesim_segmentation_example.launch @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/elevation_mapping_cupy/rviz/turtle_segmentation_example.rviz b/elevation_mapping_cupy/rviz/turtle_segmentation_example.rviz new file mode 100644 index 00000000..b30ae885 --- /dev/null +++ b/elevation_mapping_cupy/rviz/turtle_segmentation_example.rviz @@ -0,0 +1,305 @@ +Panels: + - Class: rviz/Displays + Help Height: 138 + Name: Displays + Property Tree Widget: + Expanded: + - /Global Options1 + Splitter Ratio: 0.5768463015556335 + Tree Height: 991 + - Class: rviz/Selection + Name: Selection + - Class: rviz/Tool Properties + Expanded: + - /2D Pose Estimate1 + - /2D Nav Goal1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz/Time + Experimental: false + Name: Time + SyncMode: 0 + SyncSource: "" +Preferences: + PromptSaveOnExit: true +Toolbars: + toolButtonStyle: 2 +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.029999999329447746 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Alpha: 1 + Autocompute Intensity Bounds: false + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: traversability + Color Transformer: "" + Enabled: true + Grid Cell Decimation: 1 + Grid Line Thickness: 0.10000000149011612 + Height Layer: elevation + Height Transformer: "" + History Length: 1 + Invert Rainbow: false + Max Color: 238; 238; 236 + Max Intensity: 1 + Min Color: 32; 74; 135 + Min Intensity: 0 + Name: ElevationMapRaw + Show Grid Lines: true + Topic: /elevation_mapping/elevation_map_raw + Unreliable: false + Use Rainbow: false + Value: true + - Alpha: 0.10000000149011612 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: min_filter + Color Transformer: GridMapLayer + Enabled: true + Grid Cell Decimation: 1 + Grid Line Thickness: 0.10000000149011612 + Height Layer: min_filter + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 206; 92; 0 + Max Intensity: 10 + Min Color: 255; 255; 255 + Min Intensity: 0 + Name: ElevationMapFilter + Show Grid Lines: true + Topic: /elevation_mapping/elevation_map_filter + Unreliable: false + Use Rainbow: false + Value: true + - Alpha: 1 + Class: rviz/RobotModel + Collision Enabled: false + Enabled: true + Links: + All Links Enabled: true + Expand Joint Details: false + Expand Link Details: false + Expand Tree: false + Link Tree Style: Links in Alphabetic Order + base_footprint: + Alpha: 1 + Show Axes: false + Show Trail: false + base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + base_scan: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + camera_depth_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + camera_depth_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + camera_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + camera_rgb_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + camera_rgb_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + caster_back_left_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + caster_back_right_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + imu_link: + Alpha: 1 + Show Axes: false + Show Trail: false + wheel_left_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + wheel_right_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + Name: RobotModel + Robot Description: robot_description + TF Prefix: "" + Update Interval: 0 + Value: true + Visual Enabled: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Autocompute Value Bounds: + Max Value: 10 + Min Value: -10 + Value: true + Axis: Z + Channel Name: intensity + Class: rviz/PointCloud2 + Color: 255; 255; 255 + Color Transformer: RGB8 + Decay Time: 0 + Enabled: false + Invert Rainbow: false + Max Color: 255; 255; 255 + Min Color: 0; 0; 0 + Name: PointCloud2 + Position Transformer: XYZ + Queue Size: 10 + Selectable: true + Size (Pixels): 3 + Size (m): 0.009999999776482582 + Style: Flat Squares + Topic: /camera/depth/points + Unreliable: false + Use Fixed Frame: true + Use rainbow: true + Value: false + - Alpha: 1 + Class: jsk_rviz_plugin/PolygonArray + Color: 25; 255; 0 + Enabled: true + Name: PlaneBoundaries + Queue Size: 10 + Topic: /convex_plane_decomposition_ros/boundaries + Unreliable: false + Value: true + coloring: Label + enable lighting: true + normal length: 0.10000000149011612 + only border: true + show normal: false + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: segmentation + Color Transformer: GridMapLayer + Enabled: true + Grid Cell Decimation: 1 + Grid Line Thickness: 0.10000000149011612 + Height Layer: elevation_before_postprocess + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 238; 238; 236 + Max Intensity: 10 + Min Color: 32; 74; 135 + Min Intensity: 0 + Name: PlaneSegmentation + Show Grid Lines: true + Topic: /convex_plane_decomposition_ros/filtered_map + Unreliable: false + Use Rainbow: true + Value: true + Enabled: true + Global Options: + Background Color: 255; 255; 255 + Default Light: true + Fixed Frame: odom + Frame Rate: 30 + Name: root + Tools: + - Class: rviz/Interact + Hide Inactive Objects: true + - Class: rviz/MoveCamera + - Class: rviz/Select + - Class: rviz/FocusCamera + - Class: rviz/Measure + - Class: rviz/SetInitialPose + Theta std deviation: 0.2617993950843811 + Topic: /initialpose + X std deviation: 0.5 + Y std deviation: 0.5 + - Class: rviz/SetGoal + Topic: /move_base_simple/goal + - Class: rviz/PublishPoint + Single click: true + Topic: /clicked_point + Value: true + Views: + Current: + Class: rviz/Orbit + Distance: 7.79520845413208 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Field of View: 0.7853981852531433 + Focal Point: + X: 2.046891927719116 + Y: -0.5291382074356079 + Z: -0.3964909017086029 + Focal Shape Fixed Size: true + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 0.5247964859008789 + Target Frame: base_footprint + Yaw: 3.143371820449829 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 1376 + Hide Left Dock: false + Hide Right Dock: true + QMainWindow State: 000000ff00000000fd0000000400000000000001f7000004a6fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000004a6000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000009b80000005afc0100000002fb0000000800540069006d00650100000000000009b8000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000007bb000004a600000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: true + Width: 2488 + X: 72 + Y: 27 From 6700119272622e0bf71c11b6ac825fb1303812f0 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 15:26:15 +0200 Subject: [PATCH 221/504] update readme --- README.md | 47 +++++++++---------- .../config/plugin_config.yaml | 2 +- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index b26178c8..a5192244 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,10 @@ ## Overview -This is a ros package of elevation mapping on GPU. -Code are written in python and uses cupy for GPU calculation. +This is a ROS package for elevation mapping on GPU. The elevation mapping code is written in python and uses cupy for GPU computation. The +plane segmentation is done independently and runs on CPU. ![screenshot](doc/main_repo.png) -\* plane segmentation is coming soon. - ## Citing > Takahiro Miki, Lorenz Wellhausen, Ruben Grandia, Fabian Jenelten, Timon Homberger, Marco Hutter @@ -65,31 +63,32 @@ pip3 install -r requirements.txt ``` #### Cupy -cupy can be installed with specific CUDA versions. (On jetson, only "from source" i.e. `pip install cupy` could work) + +cupy can be installed with specific CUDA versions. (On jetson, only "from source" i.e. `pip install cupy` could work) > For CUDA 10.2 > pip install cupy-cuda102 -> +> > For CUDA 11.0 > pip install cupy-cuda110 -> +> > For CUDA 11.1 > pip install cupy-cuda111 -> +> > For CUDA 11.2 > pip install cupy-cuda112 -> +> > For CUDA 11.3 > pip install cupy-cuda113 -> +> > For CUDA 11.4 > pip install cupy-cuda114 -> +> > For CUDA 11.5 > pip install cupy-cuda115 -> +> > For CUDA 11.6 > pip install cupy-cuda116 -> +> > (Install CuPy from source) > % pip install cupy @@ -225,23 +224,23 @@ roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch Velocity inputs can be sent to the robot by pressing the keys `a`, `w`, `d`, `x`. To stop the robot completely, press `s`. - ### Subscribed Topics * topics specified in **`pointcloud_topics`** in **`parameters.yaml`** ([sensor_msgs/PointCloud2]) - The distance measurements. + The distance measurements. * **`/tf`** ([tf/tfMessage]) - The transformation tree. - + The transformation tree. ### Published Topics + The topics are published as set in the rosparam. You can specify which layers to publish in which fps. Under `publishers`, you can specify the `topic_name`, `layers` `basic_layers` and `fps`. + ```yaml publishers: your_topic_name: @@ -250,30 +249,29 @@ publishers: fps: 5.0 # Publish rate. Use smaller value than `map_acquire_fps`. ``` - Example setting in `config/parameters.yaml`. * **`elevation_map_raw`** ([grid_map_msg/GridMap]) - The entire elevation map. + The entire elevation map. * **`elevation_map_recordable`** ([grid_map_msg/GridMap]) - The entire elevation map with slower update rate for visualization and logging. + The entire elevation map with slower update rate for visualization and logging. * **`elevation_map_filter`** ([grid_map_msg/GridMap]) - The filtered maps using plugins. - - + The filtered maps using plugins. # Plugins + You can create your own plugin to process the elevation map and publish as a layer in GridMap message. Let's look at the example. First, create your plugin file in `elevation_mapping_cupy/script/plugins/` and save as `example.py`. + ```python import cupy as cp from typing import List @@ -294,9 +292,10 @@ class NameOfYourPlugin(PluginBase): ``` Then, add your plugin setting to `config/plugin_config.yaml` + ```yaml example: # Use the same name as your file name. - enable: True # weather to laod this plugin + enable: True # weather to load this plugin fill_nan: True # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "example_layer" # The layer name. diff --git a/elevation_mapping_cupy/config/plugin_config.yaml b/elevation_mapping_cupy/config/plugin_config.yaml index d854c207..733f8c82 100644 --- a/elevation_mapping_cupy/config/plugin_config.yaml +++ b/elevation_mapping_cupy/config/plugin_config.yaml @@ -2,7 +2,7 @@ # min_filter fills in minimum value around the invalid cell. min_filter: - enable: True # weather to laod this plugin + enable: True # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "min_filter" # The layer name. From bed78e4a2b7011822e442a93a35fd230d766494f Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 18:53:55 +0200 Subject: [PATCH 222/504] remove pcl_visualization_catkin from exec depend again --- .../package.xml | 1 - .../pcl_visualization_catkin/CMakeLists.txt | 22 +++++-------------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/plane_segmentation/convex_plane_decomposition_ros/package.xml b/plane_segmentation/convex_plane_decomposition_ros/package.xml index d83524d5..d3f2de29 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/package.xml +++ b/plane_segmentation/convex_plane_decomposition_ros/package.xml @@ -22,6 +22,5 @@ tf2_ros grid_map_demos - pcl_visualization_catkin diff --git a/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt b/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt index 8c3728b0..623099f6 100644 --- a/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt +++ b/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt @@ -5,23 +5,13 @@ include(GNUInstallDirs) find_package(catkin REQUIRED) -find_package(PCL) -message(STATUS "PCL Version: " ${PCL_VERSION}) -message(STATUS "PCL_COMPONENTS: " ${PCL_COMPONENTS}) +file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so.1.10 DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so.1.10.0 DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) -if (${PCL_VISUALIZATION_FOUND}) - message(STATUS "pcl_visualization_catkin doing nothing, pcl_visualization is already found") -else() - message(STATUS "pcl_visualization_catkin is copying pcl_visualization 1.10") - - file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so.1.10 DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so.1.10.0 DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) - - file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib/pkgconfig) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/pkgconfig/pcl_visualization-1.10.pc DESTINATION ${CATKIN_DEVEL_PREFIX}/lib/pkgconfig) -endif () +file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib/pkgconfig) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/pkgconfig/pcl_visualization-1.10.pc DESTINATION ${CATKIN_DEVEL_PREFIX}/lib/pkgconfig) catkin_package( INCLUDE_DIRS From b68f6f1f4ad9561900016e57754d7126f28ccc4e Mon Sep 17 00:00:00 2001 From: rgrandia Date: Wed, 8 Jun 2022 18:54:49 +0200 Subject: [PATCH 223/504] move plane segmentation README to top README --- README.md | 106 +++++++++++++++++++++++++++++------ plane_segmentation/README.md | 47 ---------------- 2 files changed, 88 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index a5192244..0fceae0a 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,7 @@ plane segmentation is done independently and runs on CPU. ## Installation -The following installation instructions are for elevation mapping. For the plane segmentation, please find additional instructions in the -dedicated README. - -### CUDA & cuDNN +#### CUDA & cuDNN The tested versions are CUDA10.2, 11.6 @@ -38,7 +35,7 @@ The tested versions are CUDA10.2, 11.6 Check how to install [here](doc/cuda-installation.md). -### Python dependencies +#### Python dependencies You will need @@ -52,7 +49,7 @@ For traversability filter, either of - [torch](https://pytorch.org/) - [chainer](https://chainer.org/) -Optinally, opencv for inpainting filter. +Optionally, OpenCV for inpainting filter. - [opencv-python](https://opencv.org/) @@ -103,7 +100,7 @@ Install by following the official documents. Pytorch uses ~2GB more GPU memory than Chainer, but runs a bit faster. Use parameter `use_chainer` to select which backend to use. -### ROS package dependencies +#### ROS package dependencies - [pybind11_catkin](https://github.com/ipab-slmc/pybind11_catkin) - [grid_map](https://github.com/ANYbotics/grid_map) @@ -113,7 +110,7 @@ sudo apt install ros-noetic-pybind11-catkin sudo apt install ros-noetic-grid-map-core ros-noetic-grid-map-msgs ``` -## On Jetson +### On Jetson #### CUDA CuDNN @@ -159,12 +156,57 @@ If the Jetson is set up with Jetpack 4.5 with ROS Melodic the following package git clone git@github.com:ros/filters.git -b noetic-devel ``` +### Plane segmentation dependencies + +#### OpenCV + +```bash +sudo apt install libopencv-dev +``` + +#### Eigen + +```bash +sudo apt install libeigen3-dev +``` + +#### CGAL + +CGAL5 is required. It will be automatically downloaded and installed into the catkin workspace by the cgal5_catkin package. Make sure you +have the third-party libaries installed on you machine: + +```bash +sudo apt install libgmp-dev +sudo apt install libmpfr-dev +sudo apt install libboost-all-dev +``` + +#### PCL (for ANYmal research users) + +PCL is required, but the ANYbotics distributed version does not contain visualization components. With pcl_visualization_catkin, the missing +components are provided into your catkin workspace (for pcl 1.10). Additionally vtk7 is required, DO NOT install this on the ANYmal onboard +PCs, only on OPC and simulation PCs. + +```bash +sudo apt install libvtk7-dev +catkin build pcl_visualization_catkin +``` + +#### JSK-visualization + +For rviz-visualization the jsk-library is used. + +```bash +sudo apt-get install ros-noetic-jsk-visualization +``` + ## Usage ### Build ```bash catkin build elevation_mapping_cupy +catkin build convex_plane_decomposition_ros ``` #### Errors @@ -191,6 +233,12 @@ Basic usage. roslaunch elevation_mapping_cupy elevation_mapping_cupy.launch ``` +For the plane segmentation node + +```bash +roslaunch convex_plane_decomposition_ros convex_plane_decomposition.launch +``` + ### Run TurtleBot example First, install turtlebot simulation. @@ -226,7 +274,7 @@ Velocity inputs can be sent to the robot by pressing the keys `a`, `w`, `d`, `x` ### Subscribed Topics -* topics specified in **`pointcloud_topics`** in **`parameters.yaml`** ([sensor_msgs/PointCloud2]) +* topics specified in **`pointcloud_topics`** in **`elevation_mapping_cupy/config/parameters.yaml`** ([sensor_msgs/PointCloud2]) The distance measurements. @@ -234,9 +282,12 @@ Velocity inputs can be sent to the robot by pressing the keys `a`, `w`, `d`, `x` The transformation tree. +* The plane segmentation node subscribes to an elevation map topic ([grid_map_msg/GridMap]). This can be configured in + **`convex_plane_decomposition_ros/config/parameters.yaml`** + ### Published Topics -The topics are published as set in the rosparam. +For elevation_mapping_cupy, topics are published as set in the rosparam. You can specify which layers to publish in which fps. Under `publishers`, you can specify the `topic_name`, `layers` `basic_layers` and `fps`. @@ -244,8 +295,8 @@ Under `publishers`, you can specify the `topic_name`, `layers` `basic_layers` an ```yaml publishers: your_topic_name: - layers: ['list_of_layer_names', 'layer1', 'layer2'] # Choose from 'elevation', 'variance', 'traversability', 'time' + plugin layers - basic_layers: ['list of basic layers', 'layer1'] # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. + layers: [ 'list_of_layer_names', 'layer1', 'layer2' ] # Choose from 'elevation', 'variance', 'traversability', 'time' + plugin layers + basic_layers: [ 'list of basic layers', 'layer1' ] # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. fps: 5.0 # Publish rate. Use smaller value than `map_acquire_fps`. ``` @@ -255,7 +306,6 @@ Example setting in `config/parameters.yaml`. The entire elevation map. - * **`elevation_map_recordable`** ([grid_map_msg/GridMap]) The entire elevation map with slower update rate for visualization and logging. @@ -264,6 +314,26 @@ Example setting in `config/parameters.yaml`. The filtered maps using plugins. +The plane segmentation node publishes the following: + +* **`planar_terrain`** ([convex_plane_decomposition_msgs/PlanarTerrain]) + + A custom message that contains the full segmentation as a map together with the boundary information. + +* **`filtered_map`** ([grid_map_msg/GridMap]) + + A grid map message to visualize the segmentation and some intermediate results. This information is also part of **`planar_terrain`**. + +* **`boundaries`** ([jsk_recognition_msgs/PolygonArray]) + + A set of polygons that trace the boundaries of the segmented region. Holes and boundaries of a single region are published as separate + polygons with the same label. + +* **`insets`** ([jsk_recognition_msgs/PolygonArray]) + + A set of polygons that are at a slight inward offset from **`boundaries`**. There might be more insets than boundaries since the inward + shift can cause a single region to break down into multiple when narrow passages exist. + # Plugins You can create your own plugin to process the elevation map and publish as a layer in GridMap message. @@ -303,11 +373,11 @@ example: # Use the same name as your file n add_value: 2.0 # Example param ``` -Finally, add your layer name to publishers in `config/parameters.yaml`. -You can create a new topic or add to existing topics. +Finally, add your layer name to publishers in `config/parameters.yaml`. You can create a new topic or add to existing topics. + ```yaml - plugin_example: # Topic name - layers: ['elevation', 'example_layer'] - basic_layers: ['example_layer'] + plugin_example: # Topic name + layers: [ 'elevation', 'example_layer' ] + basic_layers: [ 'example_layer' ] fps: 1.0 # The plugin is called with this fps. ``` diff --git a/plane_segmentation/README.md b/plane_segmentation/README.md index 1b1c5388..2d7c2f56 100644 --- a/plane_segmentation/README.md +++ b/plane_segmentation/README.md @@ -5,53 +5,6 @@ This is a C++ ROS package for extracting convex polygons from elevation maps. In a first step, the terrain is segmented into planes, and their non-convex contour is extracted. In a second step, a local convex approximation can be obtained. -## Installation - -### Dependencies - -#### OpenCV -Make sure you have openCV installed. -You can execute the following command to install it. -```bash -sudo apt-get install libopencv-dev -``` - -#### Eigen -```bash -sudo apt install libeigen3-dev -``` - -#### CGAL -CGAL5 is required. It will be automatically downloaded and installed into the catkin workspace by the cgal5_catkin package. -Make sure you have the third-party libaries installed on you machine: -```bash -sudo apt-get install libgmp-dev -sudo apt-get install libmpfr-dev -sudo apt-get install libboost-all-dev -``` - -#### PCL -PCL is required, but the ANYbotics distributed version does not contain visualization components. -With pcl_visualization_catkin, the missing components are provided into your catkin workspace (for pcl 1.10). -Additionally vtk7 is required, DO NOT install this on the ANYmal onboard PCs, only on OPC and simulation PCs. -```bash -sudo apt-get install libvtk7-dev -``` - -### ROS package dependencies - -#### JSK-visualization -For rviz-visualization the jsk-library is used. -```bash -sudo apt-get install ros-noetic-jsk-visualization -``` - -#### Grid Map -Grid map is available through ANYmal-research, apt install, or you can add it to your workspace. You can clone it using: -```bash -git clone https://github.com/ANYbotics/grid_map.git -``` - ## Usage ### Build ```bash From 8e68932631feec4d285ac360a988b4821911d2fc Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 9 Jun 2022 11:57:01 +0200 Subject: [PATCH 224/504] move plane projection code to public repo --- .../convex_plane_decomposition/CMakeLists.txt | 2 + .../SegmentedPlaneProjection.h | 77 +++++++++ .../src/SegmentedPlaneProjection.cpp | 150 ++++++++++++++++++ .../test/testConvexApproximation.cpp | 101 ++++++++++++ 4 files changed, 330 insertions(+) create mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlaneProjection.h create mode 100644 plane_segmentation/convex_plane_decomposition/src/SegmentedPlaneProjection.cpp create mode 100644 plane_segmentation/convex_plane_decomposition/test/testConvexApproximation.cpp diff --git a/plane_segmentation/convex_plane_decomposition/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition/CMakeLists.txt index 2dd3403b..52bb1bc7 100644 --- a/plane_segmentation/convex_plane_decomposition/CMakeLists.txt +++ b/plane_segmentation/convex_plane_decomposition/CMakeLists.txt @@ -65,6 +65,7 @@ add_library(${PROJECT_NAME} src/PlanarRegion.cpp src/PlaneDecompositionPipeline.cpp src/Postprocessing.cpp + src/SegmentedPlaneProjection.cpp ) add_dependencies(${PROJECT_NAME} ${catkin_EXPORTED_TARGETS} @@ -97,6 +98,7 @@ install(DIRECTORY include/${PROJECT_NAME}/ ############# catkin_add_gtest(test_${PROJECT_NAME} + test/testConvexApproximation.cpp test/testPipeline.cpp test/testPlanarRegion.cpp test/testRegionGrowing.cpp diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlaneProjection.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlaneProjection.h new file mode 100644 index 00000000..a48f2236 --- /dev/null +++ b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlaneProjection.h @@ -0,0 +1,77 @@ +// +// Created by rgrandia on 12.10.21. +// + +#pragma once + +#include + +#include +#include + +namespace convex_plane_decomposition { + +/** + * Projects a point in the plane to the closest point on the contour of a planar region. We take the inset (slight inward offset from the + * boundary) as the contour to project to. + * @param queryProjectedToPlane : 2D point in the frame of the planar regions + * @param planarRegion : planar region to project to + * @return projected 2D point in the frame of the planar regions + */ +CgalPoint2d projectToPlanarRegion(const CgalPoint2d& queryProjectedToPlane, const PlanarRegion& planarRegion); + +/** + * Sorting information as an intermediate step to find the best plane projection + */ +struct RegionSortingInfo { + const PlanarRegion* regionPtr{nullptr}; + CgalPoint2d positionInTerrainFrame{0.0, 0.0}; + double boundingBoxSquareDistance{0.0}; +}; + +/** + * Compute sorting info and sort according to the bounding box distances. + * + * @param positionInWorld : Query point in world frame + * @param planarRegions : Candidate planar regions + * @return RegionSortingInfo, sorted according to the bounding box distance + */ +std::vector sortWithBoundingBoxes(const Eigen::Vector3d& positionInWorld, + const std::vector& planarRegions); + +struct PlanarTerrainProjection { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + /// Selected region + const PlanarRegion* regionPtr{nullptr}; + + /// Projected point in terrain frame of the selected region + CgalPoint2d positionInTerrainFrame{0.0, 0.0}; + + /// Projected point in world frame + Eigen::Vector3d positionInWorld{0.0, 0.0, 0.0}; + + /// Projection cost, see getBestPlanarRegionAtPositionInWorld + double cost{0.0}; +}; + +/** + * This function considers the projection of a 3D query point to a set of candidate regions. + * + * The "best" region is picked according to the following cost: + * cost = |p - p_projected|^2 + penaltyFunction(p_projected), + * where p is the query point, and p_projected is the Euclidean projection to the candidate region, both in world frame. + * + * The bounding box of each region is used to find a lower bound on this cost, it is therefore important the user defined penalty is + * non-negative. + * + * @param positionInWorld : Query point in world frame + * @param planarRegions : Candidate planar regions + * @param penaltyFunction : a non-negative (!) scoring function. + * @return Projection and information + */ +PlanarTerrainProjection getBestPlanarRegionAtPositionInWorld(const Eigen::Vector3d& positionInWorld, + const std::vector& planarRegions, + const std::function& penaltyFunction); + +} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/src/SegmentedPlaneProjection.cpp b/plane_segmentation/convex_plane_decomposition/src/SegmentedPlaneProjection.cpp new file mode 100644 index 00000000..ca4a4988 --- /dev/null +++ b/plane_segmentation/convex_plane_decomposition/src/SegmentedPlaneProjection.cpp @@ -0,0 +1,150 @@ +// +// Created by rgrandia on 12.10.21. +// + +#include "convex_plane_decomposition/SegmentedPlaneProjection.h" + +#include "convex_plane_decomposition/GeometryUtils.h" + +namespace convex_plane_decomposition { + +namespace { // Helper functions that only make sense in this context + +double distanceCost(const Eigen::Vector3d& query, const Eigen::Vector3d& terrainPoint) { + const double dx = query.x() - terrainPoint.x(); + const double dy = query.y() - terrainPoint.y(); + const double dz = query.z() - terrainPoint.z(); + return dx * dx + dy * dy + dz * dz; +} + +double distanceCostLowerbound(double distanceSquared) { + return distanceSquared; +} + +double intervalSquareDistance(double value, double min, double max) { + // - | 0 | + + // min max + // Returns 0.0 if between min and max. Returns the distance to one boundary otherwise. + if (value < min) { + double diff = min - value; + return diff * diff; + } else if (value < max) { + return 0.0; + } else { + double diff = max - value; + return diff * diff; + } +} + +double squaredDistanceToBoundingBox(const CgalPoint2d& point, const CgalBbox2d& boundingBox) { + const double dxdx = intervalSquareDistance(point.x(), boundingBox.xmin(), boundingBox.xmax()); + const double dydy = intervalSquareDistance(point.y(), boundingBox.ymin(), boundingBox.ymax()); + return dxdx + dydy; +} + +const CgalPolygonWithHoles2d* findInsetContainingThePoint(const CgalPoint2d& point, const std::vector& insets) { + for (const auto& inset : insets) { + if (isInside(point, inset.outer_boundary())) { + return &inset; + } + } + return nullptr; +} + +} // namespace + +CgalPoint2d projectToPlanarRegion(const CgalPoint2d& queryProjectedToPlane, const PlanarRegion& planarRegion) { + // First search if the projected point is inside any of the insets. + // Note: we know that all insets are non-overlapping, and are not nested (no shape is contained in the hole of another shape) + const auto* const insetPtrContainingPoint = findInsetContainingThePoint(queryProjectedToPlane, planarRegion.boundaryWithInset.insets); + + // Compute the projection + CgalPoint2d projectedPoint; + if (insetPtrContainingPoint == nullptr) { + // Not inside any of the insets. Need to look for the closest one. The projection will be to the boundary + double minDistSquared = std::numeric_limits::max(); + for (const auto& inset : planarRegion.boundaryWithInset.insets) { + const auto closestPoint = projectToClosestPoint(queryProjectedToPlane, inset.outer_boundary()); + double distSquare = squaredDistance(closestPoint, queryProjectedToPlane); + if (distSquare < minDistSquared) { + projectedPoint = closestPoint; + minDistSquared = distSquare; + } + } + } else { + // Query point is inside and does not need projection... + projectedPoint = queryProjectedToPlane; + + // ... unless it is inside a hole + for (const auto& hole : insetPtrContainingPoint->holes()) { + if (isInside(queryProjectedToPlane, hole)) { + projectedPoint = projectToClosestPoint(queryProjectedToPlane, hole); + break; // No need to search other holes. Holes are not overlapping + } + } + } + + return projectedPoint; +} + +std::vector sortWithBoundingBoxes(const Eigen::Vector3d& positionInWorld, + const std::vector& planarRegions) { + // Compute distance to bounding boxes + std::vector regionsAndBboxSquareDistances; + regionsAndBboxSquareDistances.reserve(planarRegions.size()); + for (const auto& planarRegion : planarRegions) { + const Eigen::Vector3d positionInTerrainFrame = planarRegion.transformPlaneToWorld.inverse() * positionInWorld; + const double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); + + RegionSortingInfo regionSortingInfo; + regionSortingInfo.regionPtr = &planarRegion; + regionSortingInfo.positionInTerrainFrame = {positionInTerrainFrame.x(), positionInTerrainFrame.y()}; + regionSortingInfo.boundingBoxSquareDistance = + squaredDistanceToBoundingBox(regionSortingInfo.positionInTerrainFrame, planarRegion.bbox2d) + dzdz; + + regionsAndBboxSquareDistances.push_back(regionSortingInfo); + } + + // Sort regions close to far + std::sort(regionsAndBboxSquareDistances.begin(), regionsAndBboxSquareDistances.end(), + [](const RegionSortingInfo& lhs, const RegionSortingInfo& rhs) { + return lhs.boundingBoxSquareDistance < rhs.boundingBoxSquareDistance; + }); + + return regionsAndBboxSquareDistances; +} + +PlanarTerrainProjection getBestPlanarRegionAtPositionInWorld(const Eigen::Vector3d& positionInWorld, + const std::vector& planarRegions, + const std::function& penaltyFunction) { + const auto sortedRegions = sortWithBoundingBoxes(positionInWorld, planarRegions); + + // Look for closest planar region. + PlanarTerrainProjection projection; + projection.cost = std::numeric_limits::max(); + for (const auto& regionInfo : sortedRegions) { + // Skip based on lower bound + if (distanceCostLowerbound(regionInfo.boundingBoxSquareDistance) > projection.cost) { + continue; + } + + // Project onto planar region + const auto projectedPointInTerrainFrame = projectToPlanarRegion(regionInfo.positionInTerrainFrame, *regionInfo.regionPtr); + + // Express projected point in World frame + const auto projectionInWorldFrame = + positionInWorldFrameFromPosition2dInPlane(projectedPointInTerrainFrame, regionInfo.regionPtr->transformPlaneToWorld); + + const auto cost = distanceCost(positionInWorld, projectionInWorldFrame) + penaltyFunction(projectionInWorldFrame); + if (cost < projection.cost) { + projection.cost = cost; + projection.regionPtr = regionInfo.regionPtr; + projection.positionInTerrainFrame = projectedPointInTerrainFrame; + projection.positionInWorld = projectionInWorldFrame; + } + } + + return projection; +} + +} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/test/testConvexApproximation.cpp b/plane_segmentation/convex_plane_decomposition/test/testConvexApproximation.cpp new file mode 100644 index 00000000..78e80256 --- /dev/null +++ b/plane_segmentation/convex_plane_decomposition/test/testConvexApproximation.cpp @@ -0,0 +1,101 @@ +// +// Created by rgrandia on 08.06.22. +// + +#include + +#include + +#include + +#include "convex_plane_decomposition/ConvexRegionGrowing.h" +#include "convex_plane_decomposition/GeometryUtils.h" +#include "convex_plane_decomposition/LoadGridmapFromImage.h" +#include "convex_plane_decomposition/PlaneDecompositionPipeline.h" +#include "convex_plane_decomposition/SegmentedPlaneProjection.h" + +using namespace convex_plane_decomposition; + +namespace { + +/** + * Brute force version of getBestPlanarRegionAtPositionInWorld, searches through all candidates without shortcuts + */ +PlanarTerrainProjection getBestPlanarRegionAtPositionInWorldNaive(const Eigen::Vector3d& positionInWorld, + const std::vector& planarRegions, + const std::function& penaltyFunction) { + // Do full project per region first + std::vector individualProjections; + std::for_each(planarRegions.begin(), planarRegions.end(), [&](const PlanarRegion& planarRegion) { + const Eigen::Vector3d positionInTerrainFrame = planarRegion.transformPlaneToWorld.inverse() * positionInWorld; + + PlanarTerrainProjection projection; + projection.regionPtr = &planarRegion; + projection.positionInTerrainFrame = projectToPlanarRegion({positionInTerrainFrame.x(), positionInTerrainFrame.y()}, planarRegion); + projection.positionInWorld = + positionInWorldFrameFromPosition2dInPlane(projection.positionInTerrainFrame, planarRegion.transformPlaneToWorld); + projection.cost = (positionInWorld - projection.positionInWorld).squaredNorm() + penaltyFunction(projection.positionInWorld); + individualProjections.push_back(projection); + }); + + // Find the minimum cost projection + return *std::min_element(individualProjections.begin(), individualProjections.end(), + [](const PlanarTerrainProjection& lhs, const PlanarTerrainProjection& rhs) { return lhs.cost < rhs.cost; }); +} +} // namespace + +TEST(TestConvexApproximation, runOnDemoMap) { + // Config + PlaneDecompositionPipeline::Config config; + const auto resolution = config.preprocessingParameters.resolution; + const std::string elevationLayer{"elevation_test"}; + const std::string frameId{"odom_test"}; + const Eigen::Array2d submapSize(3.0, 3.0); + std::string file = "terrain.png"; + double heightScale = 1.25; + + // Terrain Loading + boost::filesystem::path filePath(__FILE__); + std::string folder = filePath.parent_path().generic_string() + std::string{"/data/"}; + const auto loadedMap = loadGridmapFromImage(folder + file, elevationLayer, frameId, resolution, heightScale); + bool success = false; + auto elevationMap = loadedMap.getSubmap(loadedMap.getPosition(), submapSize, success); + ASSERT_TRUE(success); + + // Run pipeline. + PlaneDecompositionPipeline pipeline(config); + pipeline.update(std::move(elevationMap), elevationLayer); + const auto& planarTerrain = pipeline.getPlanarTerrain(); + + // Query a range of points + for (double x = -submapSize.x() / 2.0; x < submapSize.x() / 2.0; x += submapSize.x() / 4.0) { + for (double y = -submapSize.y() / 2.0; y < submapSize.y() / 2.0; y += submapSize.y() / 4.0) { + for (double z = -heightScale; z < heightScale; z += heightScale / 2.0) { + Eigen::Vector3d query{x, y, z}; + auto penaltyFunction = [](const Eigen::Vector3d& projectedPoint) { return 0.1 * std::abs(projectedPoint.z()); }; + + // Run projection and naive projection + const auto projection = getBestPlanarRegionAtPositionInWorld(query, planarTerrain.planarRegions, penaltyFunction); + const auto projectionCheck = getBestPlanarRegionAtPositionInWorldNaive(query, planarTerrain.planarRegions, penaltyFunction); + + // Check they are the same + ASSERT_EQ(projection.regionPtr, projectionCheck.regionPtr); + ASSERT_DOUBLE_EQ(projection.cost, projectionCheck.cost); + ASSERT_DOUBLE_EQ(projection.positionInTerrainFrame.x(), projectionCheck.positionInTerrainFrame.x()); + ASSERT_DOUBLE_EQ(projection.positionInTerrainFrame.y(), projectionCheck.positionInTerrainFrame.y()); + ASSERT_TRUE(projection.positionInWorld.isApprox(projectionCheck.positionInWorld)); + + // Check convex approximation with a range of settings + for (int numberOfVertices = 3; numberOfVertices < 7; ++numberOfVertices) { + for (double growthFactor = 1.01; growthFactor < 1.3; growthFactor += 0.1) { + const auto convexRegion = convex_plane_decomposition::growConvexPolygonInsideShape( + projection.regionPtr->boundaryWithInset.boundary, projection.positionInTerrainFrame, numberOfVertices, growthFactor); + + ASSERT_TRUE(std::all_of(convexRegion.vertices_begin(), convexRegion.vertices_end(), + [&](const CgalPoint2d& p) { return isInside(p, projection.regionPtr->boundaryWithInset.boundary); })); + } + } + } + } + } +} From 2389578823c7b28c10d34a4d382423cf115c9b28 Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 9 Jun 2022 11:57:21 +0200 Subject: [PATCH 225/504] add plane projection and convex approximation to the demo --- README.md | 4 +- doc/convex_approximation.gif | Bin 0 -> 330753 bytes .../CMakeLists.txt | 9 ++ .../RosVisualizations.h | 8 ++ .../launch/demo.launch | 4 + .../rviz/config_demo.rviz | 49 +++++++-- .../src/ConvexApproximationDemoNode.cpp | 100 ++++++++++++++++++ .../src/RosVisualizations.cpp | 17 ++- 8 files changed, 172 insertions(+), 19 deletions(-) create mode 100644 doc/convex_approximation.gif create mode 100644 plane_segmentation/convex_plane_decomposition_ros/src/ConvexApproximationDemoNode.cpp diff --git a/README.md b/README.md index 0fceae0a..31282775 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,10 @@ ## Overview This is a ROS package for elevation mapping on GPU. The elevation mapping code is written in python and uses cupy for GPU computation. The -plane segmentation is done independently and runs on CPU. +plane segmentation is done independently and runs on CPU. When the plane segmentation is generated, local convex approximations of the +terrain can be efficiently generated. ![screenshot](doc/main_repo.png) +![gif](doc/convex_approximation.gif) ## Citing diff --git a/doc/convex_approximation.gif b/doc/convex_approximation.gif new file mode 100644 index 0000000000000000000000000000000000000000..11b19c24d6088488411de8bcca027592e4bb4766 GIT binary patch literal 330753 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

Ow0|RzU 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

^ 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

cGWxTkN& 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


@|7$(u#xUl4>U4(Mgb)HI_uTNTB}K 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 literal 0 HcmV?d00001 diff --git a/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt index b3c110cb..5ad17f16 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt +++ b/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt @@ -87,6 +87,15 @@ target_link_libraries(${PROJECT_NAME}_save_elevationmap ${OpenCV_LIBRARIES} ) +add_executable(${PROJECT_NAME}_approximation_demo_node + src/ConvexApproximationDemoNode.cpp + ) +target_link_libraries(${PROJECT_NAME}_approximation_demo_node + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + ${PROJECT_NAME} + ) + ############# ## Install ## ############# diff --git a/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h index 6495015c..aeb50ebf 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h +++ b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h @@ -1,11 +1,19 @@ #pragma once +#include + #include #include namespace convex_plane_decomposition { +geometry_msgs::PolygonStamped to3dRosPolygon(const CgalPolygon2d& polygon, const Eigen::Isometry3d& transformPlaneToWorld, + const std_msgs::Header& header); + +std::vector to3dRosPolygon(const CgalPolygonWithHoles2d& polygonWithHoles, + const Eigen::Isometry3d& transformPlaneToWorld, const std_msgs::Header& header); + jsk_recognition_msgs::PolygonArray convertBoundariesToRosPolygons(const std::vector& planarRegions, const std::string& frameId, grid_map::Time time); diff --git a/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch index 6ddfbdfb..ede2f06f 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch +++ b/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch @@ -38,6 +38,10 @@ + + + diff --git a/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz b/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz index 6df62f08..13179455 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz +++ b/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz @@ -5,7 +5,7 @@ Panels: Property Tree Widget: Expanded: - /Global Options1 - Splitter Ratio: 0.6307384967803955 + Splitter Ratio: 0.45271122455596924 Tree Height: 1658 - Class: rviz/Selection Name: Selection @@ -107,6 +107,37 @@ Visualization Manager: Unreliable: false Use Rainbow: false Value: false + - Alpha: 1 + Class: rviz/PointStamped + Color: 204; 41; 204 + Enabled: true + History Length: 1 + Name: Query + Queue Size: 10 + Radius: 0.10000000149011612 + Topic: /convex_plane_decomposition_ros_approximation_demo_node/queryPosition + Unreliable: false + Value: true + - Alpha: 1 + Class: rviz/PointStamped + Color: 245; 121; 0 + Enabled: true + History Length: 1 + Name: Projection + Queue Size: 10 + Radius: 0.10000000149011612 + Topic: /convex_plane_decomposition_ros_approximation_demo_node/projectedQueryPosition + Unreliable: false + Value: true + - Alpha: 1 + Class: rviz/Polygon + Color: 245; 121; 0 + Enabled: true + Name: ConvexApproximation + Queue Size: 10 + Topic: /convex_plane_decomposition_ros_approximation_demo_node/convex_terrain + Unreliable: false + Value: true Enabled: true Global Options: Background Color: 255; 255; 255 @@ -135,7 +166,7 @@ Visualization Manager: Views: Current: Class: rviz/XYOrbit - Distance: 12.910699844360352 + Distance: 7.742486953735352 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 @@ -143,17 +174,17 @@ Visualization Manager: Value: false Field of View: 0.7853981852531433 Focal Point: - X: 0.23195862770080566 - Y: 6.398481369018555 - Z: 3.2901763916015625e-05 + X: -3.113455057144165 + Y: 1.4824542999267578 + Z: 3.337860107421875e-05 Focal Shape Fixed Size: true Focal Shape Size: 0.05000000074505806 Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.5807958841323853 + Pitch: 0.3057960569858551 Target Frame: - Yaw: 1.4850016832351685 + Yaw: 2.410000801086426 Saved: ~ Window Geometry: Displays: @@ -161,7 +192,7 @@ Window Geometry: Height: 2032 Hide Left Dock: false Hide Right Dock: false - QMainWindow State: 000000ff00000000fd0000000400000000000001f7000006e8fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b000000b000fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000b0fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000006e000006e80000018200fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f00000375fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d000003750000013200fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e1000001970000000300000e7000000060fc0100000002fb0000000800540069006d0065010000000000000e700000057100fffffffb0000000800540069006d0065010000000000000450000000000000000000000c6d000006e800000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd0000000400000000000002b8000006e8fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b000000b000fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000b0fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000006e000006e80000018200fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f00000375fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d000003750000013200fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e1000001970000000300000e7000000060fc0100000002fb0000000800540069006d0065010000000000000e700000057100fffffffb0000000800540069006d0065010000000000000450000000000000000000000bac000006e800000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -171,5 +202,5 @@ Window Geometry: Views: collapsed: false Width: 3696 - X: 3984 + X: 144 Y: 54 diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/ConvexApproximationDemoNode.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/ConvexApproximationDemoNode.cpp new file mode 100644 index 00000000..3447091f --- /dev/null +++ b/plane_segmentation/convex_plane_decomposition_ros/src/ConvexApproximationDemoNode.cpp @@ -0,0 +1,100 @@ +// +// Created by rgrandia on 24.06.20. +// + +#include + +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +const std::string frameId = "odom"; +std::mutex terrainMutex; +std::unique_ptr planarTerrainPtr; + +void callback(const convex_plane_decomposition_msgs::PlanarTerrain::ConstPtr& msg) { + std::unique_ptr newTerrain( + new convex_plane_decomposition::PlanarTerrain(convex_plane_decomposition::fromMessage(*msg))); + + std::lock_guard lock(terrainMutex); + planarTerrainPtr.swap(newTerrain); +} + +geometry_msgs::PointStamped toMarker(const Eigen::Vector3d& position, const std_msgs::Header& header) { + geometry_msgs::PointStamped sphere; + sphere.header = header; + sphere.point.x = position.x(); + sphere.point.y = position.y(); + sphere.point.z = position.z(); + return sphere; +} + +float randomFloat(float a, float b) { + float random = ((float)rand()) / (float)RAND_MAX; + float diff = b - a; + float r = random * diff; + return a + r; +} + +int main(int argc, char** argv) { + ros::init(argc, argv, "convex_approximation_demo_node"); + ros::NodeHandle nodeHandle("~"); + + // Publishers for visualization + auto positionPublisher = nodeHandle.advertise("queryPosition", 1); + auto projectionPublisher = nodeHandle.advertise("projectedQueryPosition", 1); + auto convexTerrainPublisher = nodeHandle.advertise("convex_terrain", 1); + auto terrainSubscriber = nodeHandle.subscribe("/convex_plane_decomposition_ros/planar_terrain", 1, &callback); + + // Node loop + ros::Rate rate(ros::Duration(1.0)); + while (ros::ok()) { + { + std::lock_guard lock(terrainMutex); + if (planarTerrainPtr) { + const auto& map = planarTerrainPtr->gridMap; + + // Find edges. + double maxX = map.getPosition().x() + map.getLength().x() * 0.5; + double minX = map.getPosition().x() - map.getLength().x() * 0.5; + double maxY = map.getPosition().y() + map.getLength().y() * 0.5; + double minY = map.getPosition().y() - map.getLength().y() * 0.5; + + Eigen::Vector3d query{randomFloat(minX, maxX), randomFloat(minY, maxY), randomFloat(0.0, 1.0)}; + auto penaltyFunction = [](const Eigen::Vector3d& projectedPoint) { return 0.0; }; + + const auto projection = getBestPlanarRegionAtPositionInWorld(query, planarTerrainPtr->planarRegions, penaltyFunction); + + int numberOfVertices = 16; + double growthFactor = 1.05; + const auto convexRegion = convex_plane_decomposition::growConvexPolygonInsideShape( + projection.regionPtr->boundaryWithInset.boundary, projection.positionInTerrainFrame, numberOfVertices, growthFactor); + + std_msgs::Header header; + header.stamp.fromNSec(planarTerrainPtr->gridMap.getTimestamp()); + header.frame_id = frameId; + + auto convexRegionMsg = + convex_plane_decomposition::to3dRosPolygon(convexRegion, projection.regionPtr->transformPlaneToWorld, header); + + convexTerrainPublisher.publish(convexRegionMsg); + positionPublisher.publish(toMarker(query, header)); + projectionPublisher.publish(toMarker(projection.positionInWorld, header)); + } + } + + ros::spinOnce(); + rate.sleep(); + } + + return 0; +} \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp index 83a50e24..754720c8 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp +++ b/plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp @@ -1,12 +1,11 @@ #include "convex_plane_decomposition_ros/RosVisualizations.h" #include -#include namespace convex_plane_decomposition { -inline geometry_msgs::PolygonStamped to3d(const CgalPolygon2d& polygon, const Eigen::Isometry3d& transformPlaneToWorld, - const std_msgs::Header& header) { +geometry_msgs::PolygonStamped to3dRosPolygon(const CgalPolygon2d& polygon, const Eigen::Isometry3d& transformPlaneToWorld, + const std_msgs::Header& header) { geometry_msgs::PolygonStamped polygon3d; polygon3d.header = header; polygon3d.polygon.points.reserve(polygon.size()); @@ -21,15 +20,15 @@ inline geometry_msgs::PolygonStamped to3d(const CgalPolygon2d& polygon, const Ei return polygon3d; } -inline std::vector to3d(const CgalPolygonWithHoles2d& polygonWithHoles, const Eigen::Isometry3d& transformPlaneToWorld, - const std_msgs::Header& header) { +std::vector to3dRosPolygon(const CgalPolygonWithHoles2d& polygonWithHoles, + const Eigen::Isometry3d& transformPlaneToWorld, const std_msgs::Header& header) { std::vector polygons; polygons.reserve(polygonWithHoles.number_of_holes() + 1); - polygons.emplace_back(to3d(polygonWithHoles.outer_boundary(), transformPlaneToWorld, header)); + polygons.emplace_back(to3dRosPolygon(polygonWithHoles.outer_boundary(), transformPlaneToWorld, header)); for (const auto& hole : polygonWithHoles.holes()) { - polygons.emplace_back(to3d(hole, transformPlaneToWorld, header)); + polygons.emplace_back(to3dRosPolygon(hole, transformPlaneToWorld, header)); } return polygons; } @@ -46,7 +45,7 @@ jsk_recognition_msgs::PolygonArray convertBoundariesToRosPolygons(const std::vec polygon_buffer.labels.reserve(planarRegions.size()); uint32_t label = 0; for (const auto& planarRegion : planarRegions) { - auto boundaries = to3d(planarRegion.boundaryWithInset.boundary, planarRegion.transformPlaneToWorld, header); + auto boundaries = to3dRosPolygon(planarRegion.boundaryWithInset.boundary, planarRegion.transformPlaneToWorld, header); std::move(boundaries.begin(), boundaries.end(), std::back_inserter(polygon_buffer.polygons)); for (size_t i = 0; i < boundaries.size(); ++i) { polygon_buffer.labels.push_back(label); @@ -70,7 +69,7 @@ jsk_recognition_msgs::PolygonArray convertInsetsToRosPolygons(const std::vector< uint32_t label = 0; for (const auto& planarRegion : planarRegions) { for (const auto& inset : planarRegion.boundaryWithInset.insets) { - auto insets = to3d(inset, planarRegion.transformPlaneToWorld, header); + auto insets = to3dRosPolygon(inset, planarRegion.transformPlaneToWorld, header); std::move(insets.begin(), insets.end(), std::back_inserter(polygon_buffer.polygons)); for (size_t i = 0; i < insets.size(); ++i) { polygon_buffer.labels.push_back(label); From 71ef07be2e233cd61649be2ef6f677ab7272ec74 Mon Sep 17 00:00:00 2001 From: Alexander Reimann Date: Fri, 10 Jun 2022 08:48:57 +0200 Subject: [PATCH 226/504] Install launch and config folders --- elevation_mapping_cupy/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index 88a43627..14093f82 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -68,3 +68,7 @@ install( ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) + +install( + DIRECTORY launch config + DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) From 6227921dbf76ca01ebf792cc7e289890fc0a2738 Mon Sep 17 00:00:00 2001 From: Alexander Reimann Date: Fri, 10 Jun 2022 08:50:34 +0200 Subject: [PATCH 227/504] Make elevation_mapping_cupy python module and add python setup --- elevation_mapping_cupy/CMakeLists.txt | 2 ++ .../__init__.py | 0 .../custom_kernels.py | 0 .../elevation_mapping.py | 24 +++++++++---------- .../map_initializer.py | 0 .../{ => elevation_mapping_cupy}/parameter.py | 0 .../plugins/__init__.py | 0 .../plugins/inpainting.py | 0 .../plugins/min_filter.py | 0 .../plugins/plugin_manager.py | 2 +- .../plugins/smooth_filter.py | 0 .../traversability_filter.py | 0 .../traversability_polygon.py | 0 elevation_mapping_cupy/setup.py | 11 +++++++++ .../src/elevation_mapping_wrapper.cpp | 4 ++-- 15 files changed, 28 insertions(+), 15 deletions(-) rename elevation_mapping_cupy/script/{plugins => elevation_mapping_cupy}/__init__.py (100%) rename elevation_mapping_cupy/script/{ => elevation_mapping_cupy}/custom_kernels.py (100%) rename elevation_mapping_cupy/script/{ => elevation_mapping_cupy}/elevation_mapping.py (97%) rename elevation_mapping_cupy/script/{ => elevation_mapping_cupy}/map_initializer.py (100%) rename elevation_mapping_cupy/script/{ => elevation_mapping_cupy}/parameter.py (100%) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/__init__.py rename elevation_mapping_cupy/script/{ => elevation_mapping_cupy}/plugins/inpainting.py (100%) rename elevation_mapping_cupy/script/{ => elevation_mapping_cupy}/plugins/min_filter.py (100%) rename elevation_mapping_cupy/script/{ => elevation_mapping_cupy}/plugins/plugin_manager.py (99%) rename elevation_mapping_cupy/script/{ => elevation_mapping_cupy}/plugins/smooth_filter.py (100%) rename elevation_mapping_cupy/script/{ => elevation_mapping_cupy}/traversability_filter.py (100%) rename elevation_mapping_cupy/script/{ => elevation_mapping_cupy}/traversability_polygon.py (100%) create mode 100644 elevation_mapping_cupy/setup.py diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index 14093f82..4aa69cb0 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -63,6 +63,8 @@ target_link_libraries(elevation_mapping_ros ${PYTHON_LIBRARIES} ${catkin_LIBRARI add_executable(elevation_mapping_node src/elevation_mapping_node.cpp) target_link_libraries(elevation_mapping_node elevation_mapping_ros) +catkin_python_setup() + install( TARGETS elevation_mapping_ros elevation_mapping_node ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} diff --git a/elevation_mapping_cupy/script/plugins/__init__.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py similarity index 100% rename from elevation_mapping_cupy/script/plugins/__init__.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py diff --git a/elevation_mapping_cupy/script/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py similarity index 100% rename from elevation_mapping_cupy/script/custom_kernels.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py diff --git a/elevation_mapping_cupy/script/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py similarity index 97% rename from elevation_mapping_cupy/script/elevation_mapping.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index accac0c2..c300b0ca 100644 --- a/elevation_mapping_cupy/script/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -7,18 +7,18 @@ import threading import subprocess -from traversability_filter import get_filter_chainer, get_filter_torch -from parameter import Parameter -from custom_kernels import add_points_kernel -from custom_kernels import error_counting_kernel -from custom_kernels import average_map_kernel -from custom_kernels import dilation_filter_kernel -from custom_kernels import normal_filter_kernel -from custom_kernels import polygon_mask_kernel -from map_initializer import MapInitializer -from plugins.plugin_manager import PluginManger - -from traversability_polygon import ( +from .traversability_filter import get_filter_chainer, get_filter_torch +from .parameter import Parameter +from .custom_kernels import add_points_kernel +from .custom_kernels import error_counting_kernel +from .custom_kernels import average_map_kernel +from .custom_kernels import dilation_filter_kernel +from .custom_kernels import normal_filter_kernel +from .custom_kernels import polygon_mask_kernel +from .map_initializer import MapInitializer +from .plugins.plugin_manager import PluginManger + +from .traversability_polygon import ( get_masked_traversability, is_traversable, calculate_area, diff --git a/elevation_mapping_cupy/script/map_initializer.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/map_initializer.py similarity index 100% rename from elevation_mapping_cupy/script/map_initializer.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/map_initializer.py diff --git a/elevation_mapping_cupy/script/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py similarity index 100% rename from elevation_mapping_cupy/script/parameter.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/__init__.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/elevation_mapping_cupy/script/plugins/inpainting.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py similarity index 100% rename from elevation_mapping_cupy/script/plugins/inpainting.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py diff --git a/elevation_mapping_cupy/script/plugins/min_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py similarity index 100% rename from elevation_mapping_cupy/script/plugins/min_filter.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py diff --git a/elevation_mapping_cupy/script/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py similarity index 99% rename from elevation_mapping_cupy/script/plugins/plugin_manager.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index bfaf0829..7a3d1a6c 100644 --- a/elevation_mapping_cupy/script/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -67,7 +67,7 @@ def init(self, plugin_params: List[PluginParams], extra_params: List[Dict]): self.plugins = [] for param, extra_param in zip(plugin_params, extra_params): - m = importlib.import_module("." + param.name, package="plugins") # -> 'module' + m = importlib.import_module("." + param.name, package="elevation_mapping_cupy.plugins") # -> 'module' for name, obj in inspect.getmembers(m): if inspect.isclass(obj) and issubclass(obj, PluginBase) and name != "PluginBase": # Add cell_n to params diff --git a/elevation_mapping_cupy/script/plugins/smooth_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py similarity index 100% rename from elevation_mapping_cupy/script/plugins/smooth_filter.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py diff --git a/elevation_mapping_cupy/script/traversability_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_filter.py similarity index 100% rename from elevation_mapping_cupy/script/traversability_filter.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_filter.py diff --git a/elevation_mapping_cupy/script/traversability_polygon.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py similarity index 100% rename from elevation_mapping_cupy/script/traversability_polygon.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py diff --git a/elevation_mapping_cupy/setup.py b/elevation_mapping_cupy/setup.py new file mode 100644 index 00000000..51954f5b --- /dev/null +++ b/elevation_mapping_cupy/setup.py @@ -0,0 +1,11 @@ +from distutils.core import setup +from catkin_pkg.python_setup import generate_distutils_setup + +setup_args = generate_distutils_setup( + packages=[ + 'elevation_mapping_cupy', + 'elevation_mapping_cupy.plugins', + ], + package_dir={'': 'script'}) + +setup(**setup_args) diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 40eb2023..d9662833 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -29,8 +29,8 @@ void ElevationMappingWrapper::initialize(ros::NodeHandle& nh) { module_path = module_path + "/script"; path.attr("insert")(0, module_path); - auto elevation_mapping = py::module::import("elevation_mapping"); - auto parameter = py::module::import("parameter"); + auto elevation_mapping = py::module::import("elevation_mapping_cupy.elevation_mapping"); + auto parameter = py::module::import("elevation_mapping_cupy.parameter"); param_ = parameter.attr("Parameter")(); setParameters(nh); map_ = elevation_mapping.attr("ElevationMap")(param_); From 2afd4069e87679761e29905dd73e3fc7c8d46f90 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 16 Jun 2022 12:53:29 +0200 Subject: [PATCH 228/504] Updated turtlebot3 installation to minimum requirement. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 31282775..177307c7 100644 --- a/README.md +++ b/README.md @@ -246,7 +246,7 @@ roslaunch convex_plane_decomposition_ros convex_plane_decomposition.launch First, install turtlebot simulation. ```bash -sudo apt install ros-noetic-turtlebot3* +sudo apt install ros-noetic-turtlebot3-gazebo ros-noetic-turtlebot3-teleop ``` Then, you can run the examples. For the basic version: From 1510ca183436742547b227c75a8b6f9ab1e8f606 Mon Sep 17 00:00:00 2001 From: Yecheng Shao Date: Thu, 23 Jun 2022 15:15:00 +0800 Subject: [PATCH 229/504] add key "type" for filters --- elevation_mapping_cupy/config/plugin_config.yaml | 9 +++++++++ .../elevation_mapping_cupy/plugins/plugin_manager.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/config/plugin_config.yaml b/elevation_mapping_cupy/config/plugin_config.yaml index 733f8c82..1431b300 100644 --- a/elevation_mapping_cupy/config/plugin_config.yaml +++ b/elevation_mapping_cupy/config/plugin_config.yaml @@ -25,3 +25,12 @@ inpainting: layer_name: "inpaint" extra_params: method: "telea" # telea or ns +# Apply smoothing for inpainted layer +smooth_filter_1: + type: "smooth_filter" + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth_1" + extra_params: + input_layer_name: "inpaint" \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index 7a3d1a6c..3bbf3fed 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -87,7 +87,7 @@ def load_plugin_settings(self, file_path: str): if v["enable"]: plugin_params.append( PluginParams( - name=k, + name=k if not "type" in v else v["type"], layer_name=v["layer_name"], fill_nan=v["fill_nan"], is_height_layer=v["is_height_layer"], From a7fbc6b32b10a3e3cf16f32557bf3ceaae4cfddb Mon Sep 17 00:00:00 2001 From: Yecheng Shao Date: Thu, 23 Jun 2022 15:17:18 +0800 Subject: [PATCH 230/504] add end line --- elevation_mapping_cupy/config/plugin_config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/config/plugin_config.yaml b/elevation_mapping_cupy/config/plugin_config.yaml index 1431b300..1e37308c 100644 --- a/elevation_mapping_cupy/config/plugin_config.yaml +++ b/elevation_mapping_cupy/config/plugin_config.yaml @@ -33,4 +33,4 @@ smooth_filter_1: is_height_layer: True layer_name: "smooth_1" extra_params: - input_layer_name: "inpaint" \ No newline at end of file + input_layer_name: "inpaint" From b39fd9003843db162499e3a3848fef52dc16ef1f Mon Sep 17 00:00:00 2001 From: rgrandia Date: Mon, 4 Jul 2022 19:14:47 +0200 Subject: [PATCH 231/504] replace rviz visualization through jsk polygon array to normal visualization markers. This removes the dependency on JSK and the need for pcl_visualization_catkin --- README.md | 25 +- .../rviz/turtle_segmentation_example.rviz | 16 +- .../CMakeLists.txt | 2 +- .../RosVisualizations.h | 16 +- .../package.xml | 2 +- .../rviz/config.rviz | 281 ------------------ .../rviz/config_demo.rviz | 32 +- .../src/ConvexPlaneDecompositionRos.cpp | 13 +- .../src/RosVisualizations.cpp | 128 ++++++-- .../pcl_visualization_catkin/CMakeLists.txt | 23 -- .../pcl_visualization_catkin/README.md | 3 - .../lib/libpcl_visualization.so | Bin 1747408 -> 0 bytes .../lib/libpcl_visualization.so.1.10 | Bin 1747408 -> 0 bytes .../lib/libpcl_visualization.so.1.10.0 | Bin 1747408 -> 0 bytes .../lib/pkgconfig/pcl_visualization-1.10.pc | 13 - .../pcl_visualization_catkin/package.xml | 13 - 16 files changed, 137 insertions(+), 430 deletions(-) delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/rviz/config.rviz delete mode 100644 plane_segmentation/pcl_visualization_catkin/CMakeLists.txt delete mode 100644 plane_segmentation/pcl_visualization_catkin/README.md delete mode 100644 plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so delete mode 100644 plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so.1.10 delete mode 100644 plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so.1.10.0 delete mode 100644 plane_segmentation/pcl_visualization_catkin/lib/pkgconfig/pcl_visualization-1.10.pc delete mode 100644 plane_segmentation/pcl_visualization_catkin/package.xml diff --git a/README.md b/README.md index 177307c7..0f1c94c5 100644 --- a/README.md +++ b/README.md @@ -183,25 +183,6 @@ sudo apt install libmpfr-dev sudo apt install libboost-all-dev ``` -#### PCL (for ANYmal research users) - -PCL is required, but the ANYbotics distributed version does not contain visualization components. With pcl_visualization_catkin, the missing -components are provided into your catkin workspace (for pcl 1.10). Additionally vtk7 is required, DO NOT install this on the ANYmal onboard -PCs, only on OPC and simulation PCs. - -```bash -sudo apt install libvtk7-dev -catkin build pcl_visualization_catkin -``` - -#### JSK-visualization - -For rviz-visualization the jsk-library is used. - -```bash -sudo apt-get install ros-noetic-jsk-visualization -``` - ## Usage ### Build @@ -326,12 +307,12 @@ The plane segmentation node publishes the following: A grid map message to visualize the segmentation and some intermediate results. This information is also part of **`planar_terrain`**. -* **`boundaries`** ([jsk_recognition_msgs/PolygonArray]) +* **`boundaries`** ([visualization_msgs/MarkerArray]) A set of polygons that trace the boundaries of the segmented region. Holes and boundaries of a single region are published as separate - polygons with the same label. + markers with the same color. -* **`insets`** ([jsk_recognition_msgs/PolygonArray]) +* **`insets`** ([visualization_msgs/PolygonArray]) A set of polygons that are at a slight inward offset from **`boundaries`**. There might be more insets than boundaries since the inward shift can cause a single region to break down into multiple when narrow passages exist. diff --git a/elevation_mapping_cupy/rviz/turtle_segmentation_example.rviz b/elevation_mapping_cupy/rviz/turtle_segmentation_example.rviz index b30ae885..04ff4401 100644 --- a/elevation_mapping_cupy/rviz/turtle_segmentation_example.rviz +++ b/elevation_mapping_cupy/rviz/turtle_segmentation_example.rviz @@ -200,20 +200,14 @@ Visualization Manager: Use Fixed Frame: true Use rainbow: true Value: false - - Alpha: 1 - Class: jsk_rviz_plugin/PolygonArray - Color: 25; 255; 0 + - Class: rviz/MarkerArray Enabled: true + Marker Topic: /convex_plane_decomposition_ros/boundaries Name: PlaneBoundaries - Queue Size: 10 - Topic: /convex_plane_decomposition_ros/boundaries - Unreliable: false + Namespaces: + "": true + Queue Size: 100 Value: true - coloring: Label - enable lighting: true - normal length: 0.10000000149011612 - only border: true - show normal: false - Alpha: 1 Autocompute Intensity Bounds: true Class: grid_map_rviz_plugin/GridMap diff --git a/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt index 5ad17f16..d5f762ef 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt +++ b/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt @@ -9,10 +9,10 @@ set(CATKIN_PACKAGE_DEPENDENCIES grid_map_cv grid_map_msgs geometry_msgs - jsk_recognition_msgs convex_plane_decomposition convex_plane_decomposition_msgs tf2_ros + visualization_msgs ) find_package(catkin REQUIRED COMPONENTS diff --git a/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h index aeb50ebf..e3596562 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h +++ b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h @@ -1,23 +1,23 @@ #pragma once #include - -#include +#include +#include #include namespace convex_plane_decomposition { geometry_msgs::PolygonStamped to3dRosPolygon(const CgalPolygon2d& polygon, const Eigen::Isometry3d& transformPlaneToWorld, - const std_msgs::Header& header); + const std_msgs::Header& header); std::vector to3dRosPolygon(const CgalPolygonWithHoles2d& polygonWithHoles, - const Eigen::Isometry3d& transformPlaneToWorld, const std_msgs::Header& header); + const Eigen::Isometry3d& transformPlaneToWorld, const std_msgs::Header& header); -jsk_recognition_msgs::PolygonArray convertBoundariesToRosPolygons(const std::vector& planarRegions, - const std::string& frameId, grid_map::Time time); +visualization_msgs::MarkerArray convertBoundariesToRosMarkers(const std::vector& planarRegions, const std::string& frameId, + grid_map::Time time, double lineWidth); -jsk_recognition_msgs::PolygonArray convertInsetsToRosPolygons(const std::vector& planarRegions, const std::string& frameId, - grid_map::Time time); +visualization_msgs::MarkerArray convertInsetsToRosMarkers(const std::vector& planarRegions, const std::string& frameId, + grid_map::Time time, double lineWidth); } // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition_ros/package.xml b/plane_segmentation/convex_plane_decomposition_ros/package.xml index d3f2de29..fac0c52b 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/package.xml +++ b/plane_segmentation/convex_plane_decomposition_ros/package.xml @@ -16,10 +16,10 @@ grid_map_cv grid_map_msgs geometry_msgs - jsk_recognition_msgs convex_plane_decomposition convex_plane_decomposition_msgs tf2_ros + visualization_msgs grid_map_demos diff --git a/plane_segmentation/convex_plane_decomposition_ros/rviz/config.rviz b/plane_segmentation/convex_plane_decomposition_ros/rviz/config.rviz deleted file mode 100644 index febf095e..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/rviz/config.rviz +++ /dev/null @@ -1,281 +0,0 @@ -Panels: - - Class: rviz/Displays - Help Height: 0 - Name: Displays - Property Tree Widget: - Expanded: - - /Global Options1 - - /PolygonArray1 - - /PolygonArray2 - - /GridMap1 - Splitter Ratio: 0.6114649772644043 - Tree Height: 375 - - Class: rviz/Selection - Name: Selection - - Class: rviz/Tool Properties - Expanded: - - /2D Pose Estimate1 - - /2D Nav Goal1 - - /Publish Point1 - Name: Tool Properties - Splitter Ratio: 0.5886790156364441 - - Class: rviz/Views - Expanded: - - /Current View1 - Name: Views - Splitter Ratio: 0.5 - - Class: rviz/Time - Experimental: false - Name: Time - SyncMode: 0 - SyncSource: "" -Preferences: - PromptSaveOnExit: true -Toolbars: - toolButtonStyle: 2 -Visualization Manager: - Class: "" - Displays: - - Class: rviz/Axes - Enabled: false - Length: 0.20000000298023224 - Name: Axes - Radius: 0.009999999776482582 - Reference Frame: - Value: false - - Alpha: 1 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: elevation - Color Transformer: GridMapLayer - Enabled: false - Height Layer: elevation - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 255; 255; 255 - Max Intensity: 10 - Min Color: 0; 0; 0 - Min Intensity: 0 - Name: Elevation - Show Grid Lines: true - Topic: /grid_map_filter_demo/filtered_map - Unreliable: false - Use Rainbow: true - Value: false - - Alpha: 1 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: normal_color - Color Transformer: ColorLayer - Enabled: false - Height Layer: elevation - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 255; 255; 255 - Max Intensity: 10 - Min Color: 0; 0; 0 - Min Intensity: 0 - Name: Normal mapping - Show Grid Lines: false - Topic: /grid_map_filter_demo/filtered_map - Unreliable: false - Use Rainbow: false - Value: false - - Alpha: 1 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: edges - Color Transformer: IntensityLayer - Enabled: false - Height Layer: elevation - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 255; 0; 0 - Max Intensity: 10 - Min Color: 255; 255; 255 - Min Intensity: 0 - Name: Edges - Show Grid Lines: false - Topic: /grid_map_filter_demo/filtered_map - Unreliable: false - Use Rainbow: false - Value: false - - Alpha: 1 - Autocompute Intensity Bounds: false - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: roughness - Color Transformer: IntensityLayer - Enabled: false - Height Layer: elevation - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 255; 255; 255 - Max Intensity: 0.07999999821186066 - Min Color: 0; 0; 0 - Min Intensity: -0.019999999552965164 - Name: Roughness - Show Grid Lines: false - Topic: /grid_map_filter_demo/filtered_map - Unreliable: false - Use Rainbow: true - Value: false - - Alpha: 1 - Autocompute Intensity Bounds: false - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: traversability - Color Transformer: GridMapLayer - Enabled: false - Height Layer: elevation - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: true - Max Color: 255; 255; 255 - Max Intensity: 1.2000000476837158 - Min Color: 0; 0; 0 - Min Intensity: 0 - Name: Traversability - Show Grid Lines: false - Topic: /grid_map_filter_demo/filtered_map - Unreliable: false - Use Rainbow: true - Value: false - - Class: rviz/Marker - Enabled: false - Marker Topic: /grid_map_visualization/surface_normals - Name: Surface Normals - Namespaces: - {} - Queue Size: 100 - Value: false - - Alpha: 1 - Class: rviz/Map - Color Scheme: map - Draw Behind: false - Enabled: false - Name: Elevation - Topic: /grid_map_visualization/elevation_grid - Unreliable: false - Use Timestamp: false - Value: false - - Alpha: 1 - Class: jsk_rviz_plugin/PolygonArray - Color: 25; 255; 0 - Enabled: true - Name: PolygonArray - Topic: /convex_plane_decomposition_ros/convex_polygons - Unreliable: false - Value: true - coloring: Auto - enable lighting: true - normal length: 0.10000000149011612 - only border: false - show normal: true - - Alpha: 1 - Class: jsk_rviz_plugin/PolygonArray - Color: 25; 255; 0 - Enabled: true - Name: PolygonArray - Topic: /convex_plane_decomposition_ros/outer_contours - Unreliable: false - Value: true - coloring: Auto - enable lighting: true - normal length: 0.10000000149011612 - only border: true - show normal: true - - Alpha: 0.10000000149011612 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: elevation - Color Transformer: GridMapLayer - Enabled: true - Height Layer: elevation - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 255; 255; 255 - Max Intensity: 10 - Min Color: 0; 0; 0 - Min Intensity: 0 - Name: GridMap - Show Grid Lines: true - Topic: /convex_plane_decomposition_ros/convex_plane_decomposition - Unreliable: false - Use Rainbow: true - Value: true - Enabled: true - Global Options: - Background Color: 255; 255; 255 - Default Light: true - Fixed Frame: odom - Frame Rate: 30 - Name: root - Tools: - - Class: rviz/Interact - Hide Inactive Objects: true - - Class: rviz/MoveCamera - - Class: rviz/Select - - Class: rviz/FocusCamera - - Class: rviz/Measure - - Class: rviz/SetInitialPose - Theta std deviation: 0.2617993950843811 - Topic: /initialpose - X std deviation: 0.5 - Y std deviation: 0.5 - - Class: rviz/SetGoal - Topic: /move_base_simple/goal - - Class: rviz/PublishPoint - Single click: true - Topic: /clicked_point - Value: true - Views: - Current: - Class: rviz/Orbit - Distance: 6.349719524383545 - Enable Stereo Rendering: - Stereo Eye Separation: 0.05999999865889549 - Stereo Focal Distance: 1 - Swap Stereo Eyes: false - Value: false - Focal Point: - X: -1 - Y: -1 - Z: 2 - Focal Shape Fixed Size: true - Focal Shape Size: 0.05000000074505806 - Invert Z Axis: false - Name: Current View - Near Clip Distance: 0.009999999776482582 - Pitch: 0.6597966551780701 - Target Frame: - Value: Orbit (rviz) - Yaw: 0 - Saved: ~ -Window Geometry: - Displays: - collapsed: false - Height: 594 - Hide Left Dock: false - Hide Right Dock: true - QMainWindow State: 000000ff00000000fd00000004000000000000016a000001b4fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000001b4000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f0000040efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000280000040e000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000003ec0000003efc0100000002fb0000000800540069006d00650100000000000003ec000002eb00fffffffb0000000800540069006d006501000000000000045000000000000000000000027c000001b400000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 - Selection: - collapsed: false - Time: - collapsed: false - Tool Properties: - collapsed: false - Views: - collapsed: true - Width: 1004 - X: 67 - Y: 27 diff --git a/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz b/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz index 13179455..93666180 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz +++ b/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz @@ -33,34 +33,22 @@ Toolbars: Visualization Manager: Class: "" Displays: - - Alpha: 1 - Class: jsk_rviz_plugin/PolygonArray - Color: 25; 255; 0 + - Class: rviz/MarkerArray Enabled: true + Marker Topic: /convex_plane_decomposition_ros/boundaries Name: Boundaries - Queue Size: 10 - Topic: /convex_plane_decomposition_ros/boundaries - Unreliable: false + Namespaces: + "": true + Queue Size: 100 Value: true - coloring: Label - enable lighting: true - normal length: 0.10000000149011612 - only border: true - show normal: false - - Alpha: 1 - Class: jsk_rviz_plugin/PolygonArray - Color: 25; 255; 0 + - Class: rviz/MarkerArray Enabled: false + Marker Topic: /convex_plane_decomposition_ros/insets Name: Insets - Queue Size: 10 - Topic: /convex_plane_decomposition_ros/insets - Unreliable: false + Namespaces: + {} + Queue Size: 100 Value: false - coloring: Label - enable lighting: true - normal length: 0.10000000149011612 - only border: true - show normal: false - Alpha: 0.10000000149011612 Autocompute Intensity Bounds: true Class: grid_map_rviz_plugin/GridMap diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp index fddddf4d..04c6f2e1 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ b/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp @@ -19,8 +19,8 @@ ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle) if (parametersLoaded) { elevationMapSubscriber_ = nodeHandle.subscribe(elevationMapTopic_, 1, &ConvexPlaneExtractionROS::callback, this); filteredmapPublisher_ = nodeHandle.advertise("filtered_map", 1); - boundaryPublisher_ = nodeHandle.advertise("boundaries", 1); - insetPublisher_ = nodeHandle.advertise("insets", 1); + boundaryPublisher_ = nodeHandle.advertise("boundaries", 1); + insetPublisher_ = nodeHandle.advertise("insets", 1); regionPublisher_ = nodeHandle.advertise("planar_terrain", 1); } } @@ -152,10 +152,11 @@ void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { grid_map::GridMapRosConverter::toMessage(planarTerrain.gridMap, outputMessage); filteredmapPublisher_.publish(outputMessage); - boundaryPublisher_.publish(convertBoundariesToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId(), - planarTerrain.gridMap.getTimestamp())); - insetPublisher_.publish( - convertInsetsToRosPolygons(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId(), planarTerrain.gridMap.getTimestamp())); + const double lineWidth = 0.005; // [m] RViz marker size + boundaryPublisher_.publish(convertBoundariesToRosMarkers(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId(), + planarTerrain.gridMap.getTimestamp(), lineWidth)); + insetPublisher_.publish(convertInsetsToRosMarkers(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId(), + planarTerrain.gridMap.getTimestamp(), lineWidth)); callbackTimer_.endTimer(); } diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp index 754720c8..8cd1b72e 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp +++ b/plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp @@ -33,49 +33,125 @@ std::vector to3dRosPolygon(const CgalPolygonWithH return polygons; } -jsk_recognition_msgs::PolygonArray convertBoundariesToRosPolygons(const std::vector& planarRegions, - const std::string& frameId, grid_map::Time time) { - jsk_recognition_msgs::PolygonArray polygon_buffer; +namespace { // Helper functions for convertBoundariesToRosMarkers and convertInsetsToRosMarkers +std_msgs::ColorRGBA getColor(int id, float alpha = 1.0) { + constexpr int numColors = 7; + using RGB = std::array; + // clang-format off + static const std::array, numColors> colorMap{ + RGB{0.0000F, 0.4470F, 0.7410F}, + RGB{0.8500F, 0.3250F, 0.0980F}, + RGB{0.9290F, 0.6940F, 0.1250F}, + RGB{0.4940F, 0.1840F, 0.5560F}, + RGB{0.4660F, 0.6740F, 0.1880F}, + RGB{0.6350F, 0.0780F, 0.1840F}, + RGB{0.2500F, 0.2500F, 0.2500F} + }; + // clang-format on + + std_msgs::ColorRGBA colorMsg; + const auto& rgb = colorMap[id % numColors]; + colorMsg.r = rgb[0]; + colorMsg.g = rgb[1]; + colorMsg.b = rgb[2]; + colorMsg.a = alpha; + return colorMsg; +} + +visualization_msgs::Marker to3dRosMarker(const CgalPolygon2d& polygon, const Eigen::Isometry3d& transformPlaneToWorld, + const std_msgs::Header& header, const std_msgs::ColorRGBA& color, int id, double lineWidth) { + visualization_msgs::Marker line; + line.id = id; + line.header = header; + line.type = visualization_msgs::Marker::LINE_STRIP; + line.scale.x = lineWidth; + line.color = color; + if (!polygon.is_empty()) { + line.points.reserve(polygon.size() + 1); + for (const auto& point : polygon) { + const auto pointInWorld = positionInWorldFrameFromPosition2dInPlane(point, transformPlaneToWorld); + geometry_msgs::Point point_ros; + point_ros.x = pointInWorld.x(); + point_ros.y = pointInWorld.y(); + point_ros.z = pointInWorld.z(); + line.points.push_back(point_ros); + } + // repeat the first point to close to polygon + const auto pointInWorld = positionInWorldFrameFromPosition2dInPlane(polygon.vertex(0), transformPlaneToWorld); + geometry_msgs::Point point_ros; + point_ros.x = pointInWorld.x(); + point_ros.y = pointInWorld.y(); + point_ros.z = pointInWorld.z(); + line.points.push_back(point_ros); + } + line.pose.orientation.w = 1.0; + line.pose.orientation.x = 0.0; + line.pose.orientation.y = 0.0; + line.pose.orientation.z = 0.0; + return line; +} + +visualization_msgs::MarkerArray to3dRosMarker(const CgalPolygonWithHoles2d& polygonWithHoles, + const Eigen::Isometry3d& transformPlaneToWorld, const std_msgs::Header& header, + const std_msgs::ColorRGBA& color, int id, double lineWidth) { + visualization_msgs::MarkerArray polygons; + + polygons.markers.reserve(polygonWithHoles.number_of_holes() + 1); + polygons.markers.emplace_back(to3dRosMarker(polygonWithHoles.outer_boundary(), transformPlaneToWorld, header, color, id, lineWidth)); + ++id; + + for (const auto& hole : polygonWithHoles.holes()) { + polygons.markers.emplace_back(to3dRosMarker(hole, transformPlaneToWorld, header, color, id, lineWidth)); + ++id; + } + return polygons; +} +} // namespace + +visualization_msgs::MarkerArray convertBoundariesToRosMarkers(const std::vector& planarRegions, const std::string& frameId, + grid_map::Time time, double lineWidth) { std_msgs::Header header; header.stamp.fromNSec(time); header.frame_id = frameId; - polygon_buffer.header = header; - polygon_buffer.polygons.reserve(planarRegions.size()); // lower bound - polygon_buffer.labels.reserve(planarRegions.size()); - uint32_t label = 0; + visualization_msgs::Marker deleteMarker; + deleteMarker.action = visualization_msgs::Marker::DELETEALL; + + visualization_msgs::MarkerArray polygon_buffer; + polygon_buffer.markers.reserve(planarRegions.size() + 1); // lower bound + polygon_buffer.markers.push_back(deleteMarker); + int colorIdx = 0; for (const auto& planarRegion : planarRegions) { - auto boundaries = to3dRosPolygon(planarRegion.boundaryWithInset.boundary, planarRegion.transformPlaneToWorld, header); - std::move(boundaries.begin(), boundaries.end(), std::back_inserter(polygon_buffer.polygons)); - for (size_t i = 0; i < boundaries.size(); ++i) { - polygon_buffer.labels.push_back(label); - } - ++label; + const auto color = getColor(colorIdx++); + int label = polygon_buffer.markers.size(); + auto boundaries = + to3dRosMarker(planarRegion.boundaryWithInset.boundary, planarRegion.transformPlaneToWorld, header, color, label, lineWidth); + std::move(boundaries.markers.begin(), boundaries.markers.end(), std::back_inserter(polygon_buffer.markers)); } return polygon_buffer; } -jsk_recognition_msgs::PolygonArray convertInsetsToRosPolygons(const std::vector& planarRegions, const std::string& frameId, - grid_map::Time time) { - jsk_recognition_msgs::PolygonArray polygon_buffer; +visualization_msgs::MarkerArray convertInsetsToRosMarkers(const std::vector& planarRegions, const std::string& frameId, + grid_map::Time time, double lineWidth) { std_msgs::Header header; header.stamp.fromNSec(time); header.frame_id = frameId; - polygon_buffer.header = header; - polygon_buffer.polygons.reserve(planarRegions.size()); // lower bound - polygon_buffer.labels.reserve(planarRegions.size()); - uint32_t label = 0; + visualization_msgs::Marker deleteMarker; + deleteMarker.action = visualization_msgs::Marker::DELETEALL; + + visualization_msgs::MarkerArray polygon_buffer; + polygon_buffer.markers.reserve(planarRegions.size() + 1); // lower bound + polygon_buffer.markers.push_back(deleteMarker); + int colorIdx = 0; for (const auto& planarRegion : planarRegions) { + const auto color = getColor(colorIdx++); for (const auto& inset : planarRegion.boundaryWithInset.insets) { - auto insets = to3dRosPolygon(inset, planarRegion.transformPlaneToWorld, header); - std::move(insets.begin(), insets.end(), std::back_inserter(polygon_buffer.polygons)); - for (size_t i = 0; i < insets.size(); ++i) { - polygon_buffer.labels.push_back(label); - } + int label = polygon_buffer.markers.size(); + auto insets = to3dRosMarker(inset, planarRegion.transformPlaneToWorld, header, color, label, lineWidth); + std::move(insets.markers.begin(), insets.markers.end(), std::back_inserter(polygon_buffer.markers)); } - ++label; } return polygon_buffer; } diff --git a/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt b/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt deleted file mode 100644 index 623099f6..00000000 --- a/plane_segmentation/pcl_visualization_catkin/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(pcl_visualization_catkin) - -include(GNUInstallDirs) - -find_package(catkin REQUIRED) - -file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so.1.10 DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpcl_visualization.so.1.10.0 DESTINATION ${CATKIN_DEVEL_PREFIX}/lib) - -file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib/pkgconfig) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/pkgconfig/pcl_visualization-1.10.pc DESTINATION ${CATKIN_DEVEL_PREFIX}/lib/pkgconfig) - -catkin_package( - INCLUDE_DIRS -) - -install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib - DESTINATION ${CMAKE_INSTALL_LIBDIR} -) - diff --git a/plane_segmentation/pcl_visualization_catkin/README.md b/plane_segmentation/pcl_visualization_catkin/README.md deleted file mode 100644 index 9730de36..00000000 --- a/plane_segmentation/pcl_visualization_catkin/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# pcl_visualization_catkin -Catkin wrapper of the visualization part of Point Cloud Library (PCL). -Just copies the shared library into the catkin workspace. \ No newline at end of file diff --git a/plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so b/plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so deleted file mode 100644 index 0ddc619760db1b0231a09856a6b147658faefff8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1747408 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%0A}P_+_$9Nw;1~`1Go}Lq*lRzOkbG8 z*aWK|uTz-ib^2qNJ|-e;1ISHhX*=hEOxW6DppA10zU#Qix`j3-jp3v4 zHX205dEj@7th;N&*!_sxFGvqVOT*mJ`a<|q_Se9n<(sqWY6H>`(@FrDij7>sU!UIWp)_M87}8;uuGN|TKCmNj;tKfv@o#Kp9Yg>bZhK#+RjB%@(7@o zWf$1#qp(!I2n+rd{wQ@A{_>iUW%`9=CEr#*|Y@R zR2B+ihX{1LRFqs>*-2mW`JM^r?|wbXS==;TuLG44A3{Mlq(CSVcn8812M>av5|VMP zZF*5{i7=L@wuJaXftBDpN+nr%&*8h8$CbX*W;N(Fw6pq8@pd|a9BgMRkciw5T~!PdRhF&5gAI3oy6mkCJQG*BeStM5uLOuR-?XbE>1z* zECWIzu3(zW_9I-hX)XGpRNxCBBYI~e&Y$6EmsjgI1dC(bT4NFgap;NcTCsxFt@{Wp z2IFn2@x}J6_=cy1*A?Y|VBNdunB{cU(JFIYb&SM?L`t^G%78(NbB65<(EW_TGW|So z1J&*416(!tmOes2$GRCu?-a3lvV;jiG|>(^0FYw?NgOTC?~sjnz%cyikY$C4P1wuu zz;%F!^Kj^J3#a=>C|P!cdp`Vea4{zVc=D^<`#w^B!9vSOGEIyY2G*=xM5*hR~phFzZ0f!czDY&~XF- z*S4Ac6`nX514h7bd4L1?)1&#bVGr`Bd_04a7nCamLwZOw^&zAu#Jq(X;LyzREV)rt z!kP{rirSP5vQ#Y0fxMUoA#PO+lA#};4&2czp)GbMex5!*^Ah2)M19`r_aF>!m!&>` z7td;TN3G8znhD55EBC+{H$2zont?y`$(({ICwBQ>)iXL8m(U99}3_ zpHDrNrGOO9l_cr&tD(+!iaP%mGFKI%T*oSJ{vgbBUf5ooe-cH|U_8d~BYE|alxmnK zk>%9qQ(;wbV6{H)^g5^{`n((Tc{iiayBU4n4f?zr^m#X}&$qx70AUXU;W5ysB9a0h z8dXmsRL1CYGvzDjMkX(HFl}LP7!}jzc@I$FyVO(-^gZAKpdXLb+;b6u9wlr_{VnHv zPLId6JDr+bq$Lbkbuh>gQ|D9E)wu{$uT{gr$3LmgHK#lQ0Z(Sa_Z5GiXV*kVQVMn>aq@TQWWQn@8Zx zxCUH4XE)kvI{Fl%Q^)gLO-p~$5{^e*|BM(Qvwx{S6k&$&0BuE&Vxy*gqWxsC;QC@ULwbXM6_>a6iH7COnX510 zt)~Mq9EDU7IW9MRT7ip2D^PIDX*GBKmP{h6VmhiNlj%X5WO@@YS@&iETNpp1)R;!Z zJtdU#ke~BE?SPsHygJc3VyJW1V1>m5RRE1b27D&)8w)8uAiysXZo2o zbcaH|kOMmpZlw=_bsGGg zxUAthWG~h=>RK%Gy|R*I$aJvU)1amZjfA|dQcK%!4i>jc=@IID3_N-hPlCsN;$ZBz z;J(}7N!}nhvydjRX1IJ51DOTlPPaskay<9Xu6|ICZIe56F6mB^+i8Cet z9oy>mjwkqzXW_<%;Ukb8-|LI{m-T*tILL8Cc(3nroEMKAZu}LSR1UE6=0|+zVPlIX z5kg^p&#mS!#41{otn&SDC#(Bs3c)YOKygBytItjmNd8wrB)G@vWiK|U+Hpw1I z+9Jh@P~OdM)g$MC7{wq)Oh40sxfF{I0Qda`Un=rA*SqB1AmsflGE?{=PB0l4&})fH zFB6~ggX1?u;Qzw$i=3S>en)FazjXYz9TOkFm0Sw{E5`3OX+)3T4bsR@jNg&JKj`uM ztV@04myT9`&G>Qg)Lr}9$n9X#r109)>xS1t_$`5Ciig+s`5kRv&Hv_?z9evIJg#=O zNim$*l0E56d-gHmrvu7Alw5v8XOvH4`CDMKj)NS*&mjCw6eq4t45_(erJsXUM$5wPcH!GDkaH5-$@Yc4|%J;CDa zT&EHD-^86#1li4(OhAE-8VdaaQFnwlxJShME_DG^Co4e&Tn7i$7T;iR@C#`aqCqVO zSAn9}mJM7arnV%9z@&(gZxmwOtMT{y5!*pdiXMG;=tb!FD5^GMk`2P!FwK z&sO{oyHYKFK@HapIH1O5Mf=uZZ`pEEhoPrxnsKW@H!{2F=>)b-t$=KB_dkA|Ug^3Y zzX81-K|J6O(`!cNZ$z&%(agcqYfsAEdJ)mJaxL}nqF0cI|-n)x?%+R5L~Rw`PLL!k1`XQ z5u4d`L*g^K*s8Ab_bAF=<{u_NM>-|x`CW4W22cjawyPO`#SQQ(!d#|dqLME>9&v}* z{g%VXk@fTg#P+rGv9DbPt*km`N289NRqT|)x%n|Fv*umJ`OBmg|ASg;>8kD*;et&a5{40okhL4e?Zfp#P2H?I2A(LfgZrY35$)q^ zo{ycw(W}dD&bCtgxWWmd#{s~ESgYI9WYGF1SkKrWo{&`veeyIua_%YUp6+`L$5)G- zL#B0H4pR9F%Xc^Q7s!4jPBcQG!6Ajec%(ac8vKKv@|w)j{L$%F;4ZwyYWi!yg3wnU zryD1b6}TR`h+bolsv?VG{E4l9*oYTo!QQt5e})gw=~jrVa6G}~k=C@oFxeKC1eW=Z zFLer`wX1wNMFoXfe#IlaEsCAX?2`PxIhd|2Jc%UXYG>BBaj*A8D`BK2SaU0(?yd??WKTwR*pxnIEx*d^gJd%uZaQ zerP9vl| z!wcHhbOVq%=JJAEiDLF*)4`eaJn***Ce6T)6?l#>*z?L|w7K1A(o=j#90`*0>>xtc z5Zi(Zd+FPajTv?@yRs9DWrJ*y&L(pn4qiHmdAX=Fb}PSVW@ zlOaLmV0f~~3Ws;ZMNSy9mFTK-ZVtFAr_h>STWGx+4fDI7-q7#{UaZf{8CL+b8{)-l zb=~eM-`~`_bpsP;0Wkl;V_aiRJ`c?i1;!gcnL%oi5Zac~9d?336dloPH^4QW7;=d$ z(3{B)Y^jd6GaRP%jbfOAB;6#^#4cZ$fhZDv3{+cLcP2_=ojp$7V;3mI#5R+Ea1f(_*{}A zxsb6Pzx>D31-tR9K7wDv>lBnaf51+YRk57g@C^EZI6fRQos1SZ9r9h5S&+p#<%dP1 z3wq*-mwk@HiydU_G8!n%Kq`P&^CE=O{BL|kke9mB1yZh7lt!>SZcOY3zeIN$SytdI zv?_-I5a4tx88BLsQRqK09E63YKg9zPIzsfpaG;|vO!PPx0v@)=#UEuCh#i1ekztrH;7+{J`69!AMj@k$MchMv;q`&iFk^-5=EDIY^J3|ykLE!&&ycl#|aDT zGc#X_r;XzU`ntz-{0QchcVkqoKZ#oHk01iQAg>v`V@$phPEztW`8@nAkk)olGEA#t zgh=&7xVH)1_kj-JhA%=s$GJ4P8*IW`ajqdlz}5_a?4Yc%r`jOZ_x1Sg336bI)WZ$> zsilsc3jn40|Md6u2KTF7?Li_KPy?{=2CG00oSq$C3gQp0jMw)qDIW_nuyKs*gfaaR zzZzK^Z@*CHS9XD&;!#XdS!u<$>Z?n6FCl?#H3e>uty>2k~nr&Macp6j+J_x4XB4%9X=jK zD!utv!RVZeM-U8i6BEOKO1KuI;Etc34&jEvt72Xj<(Ihj z#jQ>Fkch%Kggapp6;fEIhwm45qF$(bj_inVF8d#w58N7X&yXF|d{~hKYk?=z<@^}@ z(YRX+$%q~pgFwF{7!ys{HO(x%-X1^jWlr|TG6TWN+U{$ zZE6jy3zefy3pIm@&Q%D4+Tia>c6(exf*xRHjSl#F?Oj}V0n3hpNa9z z2E%?(&29Ns^pxP&{Q=F(?w@gMLfH9L{~ad7^mDg zv44JsKWWZUsCe-Hr0Fo_egl6}Z;R;um-v&0Wc`QzNqzS32en|>|NrGrs^oe}JD~o* z^d~)kbljix{&)MMVjumKKgq%62()L)A*f*F{73vrlN(TY{ycxuAHUxp_a~izmxJ*q z?cd9CKkZLCgADi^`;)Ff+%qhSf2%*~1`4}h?N1sa5n4atPx=cO4*nz`R2Pm~{FeSC zkB0o<@&EVzNfM7B5nl)TlMZh}>GPxhq(?ao4%(lz5Q}Fza_9#BP5enIoL%m$`5}MO zUKWbu`0w*4-F@Vb`jg5rReq5_=`4Z!FZCxq*@mK{R#{w3|F`>-nr8kof6|IJtoN_= zCw=zq{-5bj8VWzoZ|YAvsU64o-{4QWrS%W_lb(WW8gM37k|<| zaI9JdyPy7(o=p64f6~6MVYWPl^2YbVYDbFgZ2U>hFhcYvy-&|y+@F*ND<$GoAL*=2Br;XVnk zGYIN_rsxrD=3pN|%8!xT%6Pnvn~Gjs1C@hkFZK{~@yor$JpP&pl17B$b%tli0Z%)K zz&)p%-pT1G#c+~!NV*ls#tU4}Ivm9cJdDi`grr~(lDi-{Txy4I#>w`cz{7Anz+JxrXQmJVz{1nScinM$@DRRv zaIYCvvK-#~yVSlJm4Gj{;Cg@r&mv8TQ(m2E=YuE`!vWL4B_aL7MGSYa0<$nwMF6Px ze|bwrM%frZ8={TH+|J7w&Y+y=cXFo9699ASU2)^H{7E)W+mNQK%{vhfn(F%*9{sLJK z+kS$?C`(;N4 z?KBK7T)3wl&T&*cj#u0RhXIapnoQ*KuW&&0!x102%x||>9s~!FMZt67Be2cz!=r)$ zOX%8UHsN+{bT6@HLC{8aephhu%h<`24C(y00$0L8 zZwGP51!pKG7CvKpA(B*NALQs0*q%a1unoKb)O5ql!aUC0u`1k!RpaMUN8@s=Z$=*x zz5>aW`aJ4JtDK>aKYbn*w{65u8g{g3pzzo`Lpt2^sQlImCVL+T(LSN`(y>*}P@C=6 z3mx$tsw&?(z!V$=$;1eN;S^8oX839l!;3hCA^a0h?kP0VTra_C9anU$iY&nOx412E zxm7-#`JrYNgnV4dq4(`6QHz(>Olu z&&gq^>7|5_fv`fJP(FjQ!a?W{Tt1)$?=(V?V6ccI=wA59%FM>?#pMe#A^w9!ik~7c zuR;_DV}jV8onMU5u)lh6-=Q?i7{ZePJk}R-L_@ZA9jb*!00P9c9V%{!Ctk0KyAl~S zX_c>n{BRlxcCS#BIO7uM#dQQx9?6WnR|)sZGO*_X+kGv=d0@7L{cndOV(yIm!Tr8O zc3R(z?6e21lbv3(gSeL�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

FM73XU%g zKL&eF*18)`S)7C=|f$>mXav>^nCz!iIR%=~` zi}>J%e!L2RWCZd4@QZMbxnZA(=x2tR7u`^41#FV!WM{`!hcL)cMj(&p!0DE6oC z`m`WC5=`7{(GMWQcYW&dU7`nXnMdXLfifaF`BqB1_RQL8zhD*CT|^E0L# zUfu(NqD*W3K0JHMer3nl_Ghf!>9IZo0%mwNn$~(J1q}Qy;C~G3=a$Qtm?*%$o_ncG z{atDQxyAkgCr!MYF(Jl8%q_!pZT3<%{*xbo>Sdc;=tOc#$FhR}EMF%uk!FmAkd$N7 z15z%0k`=yy(*9u096;w|;K#nkvp2YwF#;68o8w!b((YSY`DFq;7iM8`Y3#ZYPL-I& zczHTPS2J@!N{8qZ?1 z6=ga?nbK;`Mw#HN^~fe}$Z8nkzu3lYR)F3YK-iaIgIB7!ZV#}csjMjU0*Zh{Dymn&in+M!kgbIAh>WN{b|wmPBKU}ulOz6 z-$KLAVNr4+)FS2BK;%Df>_`O`&F+^9-a`chZYNrF_#R6fyku%8${PYoPuP^x`Y9_i z9|NM6KI13OvaYZo$?gX8yC9qQqBhZ|hb^uE#+Lo_S`p?Dm&Sza5e$01xFgE`SqPa@ zitGstjI#q17%(@!_TH0p1(q zo%WR~c-=5g_YvMIELr2U@2&Oi)AO7Nyv^*&pvQzP-A8!W#)o%B8+e>=)Oi2uFHZX^ z6}+3E;JV?3s^!!&Z!1;oVQ>_}O++QC<-Z&pT&`un_!{f-I1~tnK>^AmOa4?Mufpe? z2tJ$H)j`il%o}ce_8@<*jSuY}LW{_s?ApmCwIfE>4!N*F)>qJC3QF;32<$8~p>JT< zg)Yu(01eJD|o*9M|w$n0LwH+onK4pxQ`K(9{@^Q z4$vBmrQlYvp5yG}3+tTok@Q*ceDvp&__Xy~t3N2$Re!tzbgccbgew)~B&Z&7`t%x9 zBlNUXZ(Ktd0=>7ORL5nq-Z-`KxxNJNH&yM>CKc*ct%+q&y^C?L;UlWvL#cX0S;%Ea zK=W1s7!h&a_4}omaIJ{00PGcK)=D2=MD4sW(?|BHiKq7T%P1kj9Y z5)=sE6XV}#@BRJX#aG`Oz7h3Jjd!l`r+CUcHPGKw7c?46+__v1sQnK#vtXcWf77M# z+xx38)<=~6-@U)8&ByksYyT@dbFyA`2&9ZIvPTfH$D_+M;^!qP|6qXTY0Ro zuwfgKhdAXw5vC5&gE{{D)iY6zFOeW2&t>j(+kT zVlraCP_5khpA(z%)@z!o{J_|hC+w69V^ae52Ii2M6s>wZ%pvv;LR3a z7cvp{SbKg2IUa`20(nk9=-7+j1?T=HMmH+6B*j8lgrfR8=(#3N{xwt%F#!c=K*HWD z=ZMkffJ@!moie^iPkOKdJ^Li@jh+^5N@6mCp4Jv_QEZB{|N7D+(XCheulrARBP9GQ z9ucfnXfO!FRPW$@vH}(V)%FV1-s7$W>QVcW5%Hnq1KVezJ)rA8wyz>4W2Al8#HKjy zTk&wb_Vt+(+dlI9snzlM{XMQZ*vTK?=I}f7C$^LSAv^yQ(fL2AieLZLcK(Uc`JZej z|3Eu`Zgl>#cJg<%^B)|YKd+tqUvmw@_I?+NYH#;;^1oo`e>pn;_p{=+cbc8QDmwow z?d12{`G-d5uWl#*5h}moLv{`_F3d-ppN&SJJMy3X_jM=+KX}Ehp~|hCKYV&EisSw` zp#-Ow+8U;kfeV?4fn0y9g2BbWX!8cbknzjwZZSncFGU5 z%I8Iu|7BEc`^L0W{eB&)q?Qc{5`su~n2g_?;3{d6|RX9PGHZ#cwloAI^uQpGVQ}$r!Nh;&*;b#t8i$iA{0vyDK)u z!EgJ$@$f5di{Gg+RkVxWOSlCW)nccAcgLnU_-&0%aqugNi{CtKfY|i2`0uKiD%!>G zpqPvi`du8G;@~$lHpRhj;XU!_=XK#{^=}KV%(=YWDaqwSsXM6Y`%0Xfe*3IpMyzS4=m9;e4z)5;HBJtK+kewq}KbkT|v)UrOmn(gV3M# zT~Xi%zm^-u(f-1$PyJfKy22$tbfhWr(P7(K&khaD)I;5|RN>ifoJ%mixDaMSzF!y| zp5*VngZs_>ifUTRPxp8Dt}vANNKuEM{eg052l+|OtA?rGcofguAIY&H_Ks zMY81UmLXi(GK=2mdN0C$?Te ziEdpM(oyGXA{9_eouH=|E)3%egXap_ldYKxY_Q8;Q-|Le+c*sIjcGV^#}h7i8^q=Z zBK8azmKz(HD3u`Zbw-pxEO*(X#|b5tKa*v^Jz|Y z!cFEwPFS*CiBB88vQNyMz~i{u{I}t_EnA!ai`fej#Ia9fS7HJ=7Dorzt^p~BPKOQS zNI9zH+)s!YF-1?txn@USW_j~vY>imwF(5TiU-tiD?_I#7s;>V36G=28bz+N3TUw88 zs6itpfItvsA_>gMppk%50h5pnBpNc)%nSrXO-oSHn3`7GYG2zoZ>w)@YioWjwPqy=dCg^-0C`)g_O za8fr-PNSx7nqNg#G~&64w(TAz1X9K06P`-zZ27X@D@4sokPr6UT5x!nLON}&Q%Dss z8xzuL)E`?&pNO0k6Vh?v(^PqXSaKq}og&TiG9IG@U7KDI0nb|$6V9ogmT!nuH+4ql zu?9qG!9dw6xwojJlnA0eCG$xL8P`eE5|cApBLPh^^1aX>bV#84zi5Bxlx?&vqXtqR zVaYAGimq^(Dm+u4DZl4gRzhX5?sxad$3YXyv*%Y!q;ALRyDe+cSkcLL&{^M6dp5P4 zbfft`OE$Hfbfc&=FJx1Txe@D;n7x$x^w2oo8($-#u6MFpte6{xGVOy9a5IZ&*_Y;D ziGnwOTa=w=apP~z4=8$>yfiL=o~Pv&RUevV8d8my6<*E`a}L~8>(W(Voxu1D)d>st zm*jV!BGcNSE=}MQ|>s|ITSp(LCZd(B@_FULE=* z@=_PNT=-gk(Wrn=6yHx&q3dUJ+WG(vTWg6f2Zu>2CL{PHzB=UriIkikkVU@Oq~0p) z4LOZY{!wQwXBy^sV6kqzjHiGDlw&-GkHkeD<3c)Kpz#>a9@jaZmZ{ms0{kU!%dxnZ zyti%j-K(W0eU+5GEo=B<^bU@2jvC*WDRXt=WAgz|>$RE2)ANLo9Alx5^!+*20LFiS zjZo{M)#M24u{d{)-9Dk}u+P&x$+K}zIbQ01qlwTm>%Kw7;`>3d&HItbSoLcAj9BGb z&|ctIaDaRBj-J(MKYHY8y@s7PZx~~|II=%8CeQ|`risbYkLiEILp+l&*A0W_OwLPS8g2UjOPLQ!VGW)gprCE^q5RriYNg&SJ9| zcNQlUpReU7jnHN(X#*b|3mRWm!*mo~j_O!YbS@lDv)EYQT%2dP=r>8x;hGw^M5N@3 ziSBn4-D_7%(J_ce(aFcYrRZKYUaeF`v+Eiungz%rMM1{ZJ<)@ zsS&04c#={)qm(P-7xYF(pcGqTN+EUub>IX9(Fv&#woY&u33sMW@N$D%3lUUGVXH{P zaGG)bAeym0Ni*#BFs2_hwtkckt{(x6h0>2%1NGx?$@=m0BJ^X8=*KP$wip-DkB4{0 zuYYD;r_>K=e~PSiAhL!Awd3Dqva9Q)Do*{8LoLQ9D2r@F`!0#1EEiWFk+RHIYl~2p zze_h-l;ufj1(e}8mE}p(q9_Y;DSg#}%JP#{qAaps!)Zb8qOa*`$+$ro_hBu_uVTv5 zYATD;3`-%fR?33V-$n=x%7Q3u5y_a^!Y#uA@>Zz}x4vvPzTsm?T+t<+JI~nE_QbIV zPV9+w?pd-uS!wIb^1=0Gwrb(9Cj|rb<)yg3=*pga&uR=`1Q}N>ml^T zTx}(SS)?>&nG!=)3QY--9Ga57@`yC$WNAs7(Ub=n5K@}*13K+aP5FT;anr1v5lE#e zU-pZpoRFj`*D!U7rYvJjWdvr0;RYI4X=~)9SPD8UMgvU|5!jkit3(mg6ge{sGh;P2 zgca4OR+?g~Mo=jVj~n7T5^-7q(jDKwCn4b6Tk?;c*F;oL-KN9t%?^BHg5K~6>N^_yjh~;-1_*I>jBy0DeA~E7 zi+{_RA~F~%&j$5wT}^6#SZt`3oj|S|*Ta_Z@X%}_yz`>gF=wcw!sIwzovkzBlNAqq zERB_h#zYvAb4|%#MsX!-WcyFHN15bDNvv_cR)3~3Tbe@A>c2CXqO|%+29&r!lT7E= zvWGd!`7OcW8sPl?WQAz;UC6=d{N5#Fu$J>HIr+mZ;W6g>-gmLwX8f>Tl%6k(+nmOH z-)dX=82<_@2Y923!Z2Li@x3%j6J@kr2KVi`Yk_{DD_ z#J%4zK1O?DWWua5iho4WIJ#53;$Lrz-S&JXel4$V;WnXv`Jw3JFJN#;ef->cwmxna zg)sYCM^_)uQG|!n$J=L0;hOsR%ksm~$9v0#arE&rx+h8>&tI%AV)}T#X?0C~?5s(l zkDn&Rf%hku=TNDg#BUY<9{o{!|CJkFk9*#cVYz}nj#xymWhCY6VnMV{erjMTydui)qJM#|% z+UrACq|(Q?(QBtZPEb6?^zm5b*k_bU?HQqc{5?*aj8=R|?R62Qi9Rlurh3U#{wd`j zhd#diKONQ~KD-PIPe&)v2w<>E;NEZtRlM7wdQL0(BA7wtK}I+S)dm zank|X*1ANr?dBx!@J6)O);2W|b>Czm6jQfvsEjMMi|WFJf?yl{$7diFySj?r#4*#2XlifS?Q zZmE{MwN&df`L=3pl)|@EOC@6sxa$N~L@-P1VX#L+{3p%Y-=^*45G@6xCWJ?v%rjEfT|KtJa^&QmEEs(spf< zITL5cBbRQ1sFp6neKN+mRB)Ai^bx!GohPnR{c|;hSFy(Pv&%`;XusvRA z(#u%Pd&m9_BZDxqJX~~#^Y6|{SpOpHJ3qz?*2hjH9p~b)f$O)dwPbsqPYlTVEo=Y9 zlgV#l`x7RwPKslme}^L!AMdvKe~n&&gMZJLcXq&_@ipmZv|PKy)D2zr<5|0Z27aG& zeb42S67JbT_{qp|E%Wq(wD57(J|@;A&?#Y!L}O6K6wb?-kJSyo#LQ%D>wav$G2#3u zHFv+3DJjllxk9)JQAhS0Mam*F84{ainu#+Qsg~&rS+OFYGWE6G-7bl#WZOmH=Vgp9 zCDcMs%UYSpP&@PIVAJI&sA@SMtDJUfz@bnmai*!nJ>OM1W&Vgb(cQFUd%t1M3#dtf zy+1Mahy6TdDdl;A>ZIH9+>Ns+dD*kfRFVDfNF17yi#D)oo47>7L0 zWT+!jGMqfdEF{!Sr#wRD(lZ!St8sdMe5RA1SiXPk%y)b}x9HPg{I)HL^V_7%j+5W@ z43tDz6E<}DExVLZ7bfxBQpy|@Wh945!M2aUtQ{TE(=f%{wXQ{%8@_npgB>dh}a#;K>pj|b`3vK;641V(*{ALf}_fsR{_uWel zi{Ir8O%KoS<(~Vo_VVY7&4hAVKI{K7eJ#f^4CtHK$w=TR^(CzLs0H5UKgo%-&4*az z=VNQ~CXQ$SvsB>Lshan<{U)vJ8Etgkz0}i@+e2j zY}(sJJ6QNzae#YdB^#?KTT3v$+hjDU;3>rBUY`)Q&cDRlLjULKJKWW2f}WNcYPFDB(V|wn#7+2Sv85+U&5PH6 zxpNwIWe@m1q-7Ii&wVD{2sxj6fLCXfF^0o{w-5hfoUu@DTCdHLwE}aw_O!}TJ+hdx zcnO}6hhbc##Ag{;)~Wn?UIb-94oe?0jj?8o2K4}mr*m)2rU4V@=N#F;kGr-*EpvR; znEnMxR}NG%UcdnnXXaKE+c<|pj)ywQ3?-`#?z2MGNht4ZXQ;gs6fNPp%?jlql(|;) z#EBA=wW3|dBaB?(SnRu84o`SPd>|J8`lT>Dz9S!cT6xSgJ8e4Xh( zh-KUWqe<&bua%Vu!I{=~M^~P?ydJg_17G1pK<72N>$auuAp55_~J=^2g600-u_5p5F*azB1K4iVK!MMJd z(rmppXsnTomTNt#E~>9tr%zL_vW%r>m`r1#T*yvOFBgN2Cv4nTt-dtllS*5Jb;X+A zlPv|6(B)%kR%{x|6`jWlj%}_RE8y1GI`v5cqk4yE1o)1!r}+=Y3{f_@+i9Gw+(f2^ zRZWKBz@$TdaFb*5&Yfi}f99SfWAlA*H-2>S`)g zHZ%*QpR=}jW}Pv)&?ql)VNa_0<1PXiMjDL zA2ixj`uKqOI%;*fk7$ILnw^}bsL|vz^TTV&&o9rA+iNnRhO1BAmZRx~_6#M5e6=zY zEBhMbUy?h#`i%3h6P`&*jww^tYbPQrbltb$82(wD#y{+OATVpCi$|%DnwsqFGj32_ z+YPiz8?37=qh4J(SDLvt{aREpd9_(14>jZEv*2WBu}5xtjuo3>`b`^=6l(GqlW;w0 zJhu8(mYnEh^!(j9KS!VON6(n~*xmCU$B0?sTSC~lYqE@eV#jV{8;R?_XFc0`viKh4 z;?0Y)FWcvbFn-~|s$Z$|UDigx>2PElS(^R9)yiMz$m^R|2f4vU+&`I`T@ zpt;+aj@z{4io#{qdQBhOCFq2_(p?y>@5lK3&73ggtFy5!H?G1(g$w2E9^KP??JiHt zb(x;CF5vhYKG5}^5W7vSH)s&C>p4w6iFHJvJIX4xEX>#XVCf_}H_mYv>$orSJjwiO-! zJ724pPm{cZMtyr*QPb~SO?)Sb7_%l@A!QEzmQHu(PFK?>RUO*p*=DdOs5>KH$#eU* zYqQcDw6tiGhEE;x#{RWS=HmuX1ygsr!eV>IW$q zILkA>I6<1H{c@8dDYz8{E|hJMC(5riUi|Dp5^jlAVw?hru0v`G<+jVCU5}jkc-QZj ziKf=_h0jA*_K-=&*7@$s{G!&YqxsM8J;5HYlIi*$zCyN_kMkU2(VYh^*SEj)-0dj4 z$Y+l{aC=&F_Y_7s&r?oYZJm?mE7%)hsfP@GQ;AsbxJbeeup`HICnfPOKh{lry}EGn;lM!jEQY_I3~u?r;WZB9#w!e)<1zp%(IJ83oJy*k@Fj>p1BCA_cY zYMNYotJwu}#HA@A#rRe;J_u*FrY9-=XZuy3aV!R1s>HpdCHH^NRw{4QNf*l8ZYJK@ z%``XO*2SlB`k2`v*m&>)*A0C2nePloKkIgVn-1FRo{cYd=Rf0aVprRK$XV^(_HEY% z_`+=0``3@BU>?Q}J{H+4e%Z#Cx=C^4tEYL=c6-zQ;4S!LczpgdG5w;E_noY59+TyX zVgwIH_My54o*c%^-&?3YA7tvYpi59Ro#(|@yif(iX0Wkg0~K>k@6E2{s3|5#C-9yu*mR3}G1 z5i6?W!>3#I<>-~uKucj(lcf}(2t_`#B>CR^zqbAD`4wwn9Q%pP{9ccvhzYuzC_Cqj zBR878U&rEgo}2}JxjSLUk80mhR@rYP@6F9d^Jd7EwC{Y_$}ziW*>_3L+;8+*>=65n z=1a^uZbk;A%~Ly#?Dj|60|`%yy>TC{#`O|HdOhm9Tw}7MZJjVIN^~e|j2Kjq*U>f| zgDyQ18Ji$mRwx3XS#7et?!1%Rsc4Z&8y^ZnAuarwoj0lrGA;&IK#oon@loH^wVZ#) zGqp8wY5e;;!k@KW@rYP7;||8P>6topmRiXYO+ra4wXxr|b}j#= zMJh0pr_$YFY>#mze6}6w#~@t_$lL?XERAwY3igLHj7xE%q{QOlSfa`hcOyQ7c{LeY z;usC4_ZwLT^}X$;e=3d~j?lRLXN=ROhiAHZH~=sxH%v20m)yAXY+-{{Pnojv zQqHaCpEMIoRCN*^^m{)g6!!0ZT(nTei2m{&=3e5)*3##gJejjl%&Q88XsbMqFQOt= zQD2b~a?P9ZJ@s-7=Q}j_I>{9~n6<2LI0oNx9*zW&|oJnNw?Y5lzY&qYr22qteohWA+&6$N99dcgckn@jb zAm?{o$a&r;l{;d}+0)$B^R3&Fv#NI@d8d5y4;&rgGT?&_?>A~clS;VjlyEB#N4U2r zmwOoPU7aLc?1?Sc?+uV^1>RUn{S~>sg4`T(l}!$&ooYS*(&@d z#P8`BdwN35o>==wRS8<{Yuw*RY{%lyr5zK$&TPkoA3lu0emzgiDXJ+L=Q;1P%<%Qp zz5M5;E4BAR;iK#6%U|36;_vB*NqfMDpk;%OaUF_ge!_q)Du+0tHOs>YNc0gI1lj)5 zJNL^tN5LbZX}lZ%XW}fAs`&i6pL?43$gv<#8yjCr^Bljs>(R>(Y=80bGk0~px#ZEk z-&N_6GKHJ7lriy#mrLH`@{8%O@Xh!t$re$c$CJRw`@i3mW{$3xjwn*BhvC!As{cDR zx&Moeep~v#S*r7jA!exWjl}-%DWWCJ*bUeJMdj#1Cy;Pk{a;8RGy1q)L-&76i&{g& z_kU>|tS&H9KO&`gFWA`2$Pth1e(;---xOiS>1g?q`oS`5bmAwZykq^~{YqV9{ornO zo6rwFn=-6+G%syK^ndr>V0>*X^jpt=^%vBI?=yNT+9~$ylyAnarStnqZXN!XJ@-aE zcvD(nr3VAs3WjYGH-L;1X0q(^S1wviBV0}LU7h%#yxJSGhDRcXGcX2>nz5M~l2c?I z*2K5HX^hQ_%wz$buepi_p3NdBa`X*W-Z(iHLuW<9I2s+V+J@pw>tQyZ!B`o3fSWv< z8*I6$mTtLlHSLpId#8#^aq}9FgqzzxW^1U%H@;6{wjtpEOw}P#tmi^ zRE$9t&f}pWBqT#N1U8;yfEy9gY?|+RNv`%A+pK|aoXaa!n;H$fl&FnY$18P(7P_If zH(M{BioZzkI?jsQZEO7uXZ++p+Vd;3D}mp@M|`=Th8Z^2;aV8s(fkwOA6q5zZ;4%t zN=)U}wwD9#gV-yTpXAS~%f!oop|PJ2Z5o&@N-;XNROyB_I(F09 zjxkMnOWdk)GT+eSWcQyikXT8KnA_;VC7`6HB7G=!J}e_6`D| zXc#eDVvU#`Z?=yzUiKm%Uw&DQmtk#=K5lJmJuF`nR&wsV@H2eaE@v-#HSJH%A9KA4@CE;TFau#HXGGYFdB z>0_o#H@>G<)no(;M#&tsS|8b@A~6qraKIw~Oa^TDK@_Qr_Aq(Q2fqx-mPY0Nbqur917Te7AyzIsTk+ z|8%6#@|mAcQ^LSxTQOVaWaU4)k`mHX{+mo9aN7@E`BNon%bMp|j_YxbYu&zXnXmeO zK@L??MRrrV;)|#<+M!5dcd8}h>V+z;sL`%`>^Zbj^RbLg*&Qk~Gz>DP;5NioQC>Ht ztLMZukr%BGs%J)-NdSq?$C_Hi5%CO(N+(cgSiGRGq5-hfX|rT0h{;jL^VaKK@z>RH zk!3t+z1|&vt#rxcDI+q~B)%v9S_xe2f)rV=AbnAoD;FlZ?QmQh*0rIl`QeOpXR@}X z#VmHa&IuiKMJbff%Tg-Pl--DMg-dhdw%3LRIK607x&Y!xBK+Fy*9l`dt8kR@?X%R=KoQI?+J z+H^W}di~8He+{cQd8Y_e+i8Ue|v8}jlJ1EDSJZtvVwp{Wxp|>E}X2)QiGgW z4B@T0*j!KYzVW0+ljC5y$D=yNZq0YrJ*oh`+uqCYR{o!7>tgdSLsV%qOcsH6gHpO0 zMCDJeGac7i_I1G{t{Xp}NdQ@D^)^dHn0Q>uDUYLs!~2gBGrdg;vr~w)&f)7X{U@k% zC3mg4%(Lwu$8Z4TLeI9BGCXOIb-lB{lW`;_PUPp-XXfWS2HVX3R z+1a?+yrNY+c&ycV*r~=~t@pRt?{_w~+m{;;9_MP>#vSqRwjb_n?1*1(wJ$dw%yczz zMzI9#v>)zl+!epvZC`FYczifOus!yJosHe`OT)h0cyM%>C6A50_Jf^`{qf6~0?A6w z(+L*WqQ;mK?Q9%}Jmk+e>K;|ZqKm@5R2-3rr{yN~yr{K-dAWIMo@Tl%t?6!7S#6Vw zA<2jt)~7zLit^2j(}!JDq8FHse(^^_|W zJFIL!FO(H|LXBPi)%c%x4@CDq9kUY~$PSB=TIA_hV)nq243n8(Q#n8iVgh`uAM;S* z?j~jLwpTOQR`0`vi-4?t165f9%AZv09LIH@eGTz$c~AaCq!+b}$?;JHLbQl?;+0Bm zY!?*!b-?(k)O8*SX|*hib`~XmWSn9(zRk?i>v7Zxbkk?t{Zm| zQ_h0zwxh`@5A?-eHChzSjNBX?4w94R*miZ>CFz!oljPOLPN(p0_q<~7#~qdOt)Q6^FhWrR#svi7)MXactDMznfOHwdn`)>bK^rBGIZYU2KiiyKxH&_VWeR zcM0%2{*g9yLMHmgTDb@C49S8!k1nYfrExV~^QQFyQG!KxyMDX7r-moC+aQ85Jwn_E z!zJA>Ulx-**pGr3-(hckR*&8H6 z>3719{K>VLZu#q(buh|C$hAG$Al>|3|4nIa6s2uFf6HlHAJ=yvYAnQ6F@BS#o_96DmK2w_`qA9$~UY%J&$`@PV%&P zGi8;WT7SqQ!5yv}>rp7zSA6{IWlAp7%d%4sYbz$cPLsm9g73IoH)>^tS<4w^ zJUzMZI|#m&Wprt;GwlAP8izlW#WZ|Qch_@^US`_;*?I;Am%r9^sO(Yd7K8h{BLCNA zu-@v;WnHYfdXk~RM+x>Z|IHluIyxdFh#yN^#BrjpU3Y2Mn_v9QADT6-H4@FoMKk?T zB6WJya!Jp&7t>|fXF9J5k426>f94`-yqe{tvh2K+#hWtu;^m0*<{rnm409|DP3}z3R+(pH*pz}jU~O#q zw7Bhi?x!wM&zOQ`*kZqN0gbyX{Wh1Wl^iDq4N5UHllX;3{k;RRk+NsdwU~Zc`&kO% zQ3jJXt2AIi7O-a}Fximbx#`h{6I4z|n$rJL9DFVCQUgP#Qzt8mQ4A#XOcfBPU3o(ej!__1$ zg1qod>}R4WUHS%FfAVAV&*Qpx*T#2f@DGu&r{H~8(@Y87d{7*ij4S`w_Fr80U6>u+ zwXy%WwPT7}F3Kr(-8-hSDD6p>TIETJcY7)yr4Qnz50ZXSWzjh~@lj&@!m(-vryAOph;SjY--8Sb(MhSh+IZhS@+pqfFz zvJNva+@69M?UGC-z@*#QeMp4HEjln(o->4X-GV~bz57}{(XQUhAIv~h_A5-?t z|CBoSFtd*{E*up;Q>RNM&a37bRa)Nl#ue$4C6wC?W7WmSB20mx7Upuv7LfULHlk&h z7t4TRp9rU1(cq%mz6i>Nv7JW2bT*WSbys>{6py%*S1fX;_t|GGRAYOwxu%VTkO;bX zC8lq953L>RzcYSZe7i`k-tJ!_*(1zbuZ>-c$^P}g+tlkDikqJ*Td1Lz|&`_G39oOXlBCPnOpMO(nvaU4wrGc7UDgqPb zBk-`A{Kq#25_4+uu{JTK#l@SV*UcCGEo@z@niBk-m>$QpxWzY6iD^=jmH3a5?L#T? z{-KmON(FQ%ad#R@9L^qF)cl6{SYKDYhL{3B%v+_vg%2V^(O`VopQ?xSG~*_EdCVjh zHFw+VE@SJ*)ogp~xr?crN~<{o^Z3v8MT_%a+54+u=1F?S;sY6H;VYrY(t9^%Q*SIq z7Ui9PO~UQj@!K93*Q#Dg@Pc0j$w7E*vqG7rXm2A&>b+xXA{HK}`s4|==Y3qyqsOSl zC}#Vwl5fd)8)x0IKi{~EFf?et6_dKW=komrNWGD3Ydv#Dm+9Q&oFCV-E(N{2lIShA z=!s=s-g8_cJ((}`@=+6eB5;(NP?p67bb118;hmjO1vz)r!+L+!_+&^+&~yz=49fy! z)~5N*1ry&>Qw5JnrD~l;+audD3i@3)>?U!~)^19Hzw5_YbyjYK-JVun5T;d* zh$I`YN1p6D7;ww3!wa+aKEZmMsB6_&r{n zxp@B6i2JvBBqf=(_cYZ8s_}B;b*67(BdfRxGOQ}wp0J2-7~#DKR0qt*10)W!J(r4? z=xfQ%?s;11wVuD{|8M4KFg=}%3J@^)P^1*IIauwg--b5+` z_qTsm2FFZ0I^_QL`+7_sWd?Y2iv8_BJ&EFYQ517T``cv^=p*RX;+P3KE;glGD3ig; zKakHZz0!?U(&L|AdeV2+IScUp<=r;9i2n|MGzy>z{2;~_?>m5^ zId^y@vTh)XU$XeM$>dZiQGI*&aW?5gJ{}fgytz zwWd#ze&&K^Ht44Hd(&7?2A2zHB-nP8AXHUOMDE#$IiR=TY3`Trr(})8NQ?db6pZiz zsm{n=jBw;uLhk*aHqNK-nQxkpDRWW6WoWdj-E!{1Mphe;yN~`plE6n2_(%dDN#G+1 zd?bO7B=C_0K9ayk68K00A4%XN2@EHJHQ}r01Xi!EsH@Ue`Rn}kHI-UuT`25dt*xjC z)l`;+!u2(Et7guu2nPLxS>O+aDpvXRu)iU!N9ropRMgZ~tf=)Tg)UoARvD-xZlp4- z*F|b;^}0YBq&NuZ`KTvAhcwZC3&y;Y0W1^tEf^%d*1HU7$Qpnm4edVk1Y zzs9erpn6b+RYYP*=BnF}zm^!Vs8`gj(}O}dbo%HR85pVeSJc)9D$8o>pcvLFxzob| z-M=~*UZ<}J1VZ7NGgn6HAQGt4w2RMGj|%(^mHwbSDjr&bR`~pBu?S^V{xDL>&#SBr z)cMO0qu)Wp4nKKCMOE2af5p{h!En9feR676_-Pi=b3;KS8>tKXs}d>a=Q&E!LFD2o z!OGhFDQjv%5v0GqLb5bDFIE5uZVm!jQBiqyY9_4oXM}22)m7AnCg)G~Hw0_yNj_8? z2p8M(%AYRzvBg*>LN@8y{F_RZKhp>UOhNk^)Q=@C#>7Bit#612lxDtAdZ;HE2f_UeySvWscG3HNq7Gv=me_gn^_~O#ZW%&gGrMeZhWwjNda2fS3;`gp8 zF0LsJPpzc}dus?+Hp4D1Z)stf#GG4ZrX?iusK0emv#0^31-w?2&s`m%<`);|Pphe0 z6QC4%jftQ%3E+@Y{PM%h|FlBtwwMvL_&+rJG5tEc@}In_J`f2~$!cptVQ*rw<>!T} zE2IKqI8dG`W%=jE%c^WeplY3$Vh&c+*l(qxmaWDpl_{#K=xqf-6U>sGDxnTn)to9c zUvwlvN#vftxGto+Ix_wEkCRVIRXhsfvGpfK`%+-q#+tg70ot~!RJ$q0B$X*1yc8_? zr=V}OU&;hsT$+bfIjjV&ByIY6YwIh5W*d3fOje*cEBICNyNVwx`nA*foyd=E6xv1n zbbhP&)${=*B&jIptfsCeTqACWziN_RQtQVR(v|<^jlIxwCh9BvD+Bes3Dn`p zMKI=*MyquHg~<(<-o*jE9{<;0@2`i?TIF*F>hx7Lw7RG3i^*51KfKTiF()2iklZ2H zNU(}#(-#O_y*Ri?Tu1fi}s`T`=HQ{Q#rb?eRA#?#g zuKF8-juld`3iv~cTy+4t;wF=WK)o)Oqkgq&!)F>6JMKRNh;4l^5L~u zOwNdoU{F-49(rYMO)zNoFILt1V+>2Z7*0?7vZmHQlO#>1pohV;Du9D4l{Hm4%siN;TC$-nG&7YV(#rb4>NsVS5laMvg?4Z= z1RphZkWI~vrftwY{@UQo(Px`~qxINdFjp_(W~Ls(o?=!Ib%j~~&X&G<73CvkMsG@) zMn}xGx%%Y;Vy>k#yi!bK%GhF@Xf*WLsKrDFJqoyV0KHJ8eq}}Fh^aZqU6rd}q{xLU zt|mo&Qpv^h^iW+zFjURp3l%I}P3cGKX~@J%tJ)!T&OxFwSD&LuRGE!YEV!u)=UB1g zD&dH`GFP9g;;yV+Cqh+YG5YF2m4CD&ls{K5R-yb2HDSe3P0T%U1p891eyIvZRS9Ag zs!$ciZ7y3h|BR5n$X~y@rjFLLFc@^w*3UZUY!#`duCm_0nrxm^<+rZ%z#6PMBuuu% zDwxShoTX>!g}z10(TVi|l(nYroB$1(lk}=weV!t13nm0VetlIvjciVU@GDn3OE!|L zFHQ(vOFJJ4>S1Z<;}H}Gfn5C(!kT|Etz6*`ul4&eA2hf@>4&fJpCe+&^&k)R0rB^- z?s`s@e`Q6aHmslT3~KUHpNqkX=S`G4Y*)FZl#mp@DUS2?Yw~h+`Ttt|>rxOLH!SdGHsvwlMDyyMr%GP4{XNP1LneOfqLr zsG1b4Tb1;LCPABHJIC}~>iqiBI)6od?#hb#<+_%uYjfkSt-iD&cU|s!o|jmDY5d7$ z;`d=3V?iv|@T^@JqRE+o|+cUEtizrqw2Z3so)CYnhRpuM`d;Dwt zQQwCC=r1jl>m&KyJxKid>*DmT-_##{`iA~!){W+~-?o_e&70z3KF_;v^SgO-fAoL& zeX`kncidM^{3PhH;*EsQ4=eqt-|dg)^0QH{kLJ%wSFY`!GtI%m$n$KApX4wjjHI^f#5oE5Ey+IPqZu?xY|G5{8MQ-e=75E_3L7j zFWy0B3kD8Ru3>C;sI*7OffP$wE|bcDbO_+jaZ}u23jS5Wpl0RMKxuYkUaAL0O>o6 zWI)Px`FsHSNkx__i4VkoiXu%;!z$kaGh_uaLuXH5G0`Oz#yeO!CCVv5A&v_D0dk5b zaa8E1l#`jpQK3K3G{oj@lIiE$Q+XRG6NU_g9x=5z3wsD!dK z=OygPtdY)kPFJ&?bL`nprZybh7MD&lXFK!C?AgwEX~y}suMV64WL^0;XW_8JEL!^aq2w=h1^L(J@x#nt$_n(a&EEgt>fgv0##t5g z@XB|fM|ybi?P_8>@k6gK{P)!F!xQ0=<^Ml!{a8{{;cUf*URZZ{`5$y;XmYpPZa$8% ze*VYFcc3bdP{fBPU%P(&3sz(fp)vDPEyawLXyV0xZ2pEWu@PtSKQ@1sEqZEWr3A*y_FOuBOImS z_%??@H&P_%MdJ9%h~g)gtAoUd;-@MXi^hoJr;w`|y>a&KYre&2*j{rn;Gy{09nTOvEO=F|ovRrAbc73)0aQi>&Cyh5v! z^{BOF4eQpM`@T|zD>c_gU95s?gNK_FVd>CnjooSfT9}Ea%j(=fy_Kj>-p-W;h+6%s z6|&Aeb-0D|E-W;IrG7up+&X6lsSd3fjE<-DvRG=Sgi_NZJu}==7Q%#Hkhy@rm+pDYfkW2Nr8 zcoOP)j4tU2aqGT8y&U=dIyM*BRX{~e&R;Bji*PI*wZKgy^#%%n1=$vvczEQSf)CbP z`0G}MtJ#2|3P3`s3yX_*d^15Sz4hAg|EUNuxvbNM`_CD^K^y)*lcA)4Q;n}rJ~v)# zldPE9+cK5m_jriODZGk!A}Q(5h{sN%kCi;UBvR3zGC2JN>pGH@Qqs>Klz-DEjfAiz zqEz%JPma@fTJyso8!Ld6^d0hX(qE{o?ct?zIP?!&IOHM~{VC@DUe$Ug@Ncy$hm(WD zp>MZtADI5s)aC1JWk;GuO8y=CnIs>xl^-eb!Q?-Pe#X6xktdLf|6%Npsl8YVF+3^b zJM=rXeMuk@t1GE4QqmvVJ{G9b6-zdxWi(SuNq<=WN1jAV`Xl7u_u=zDY!XMnf4-@n z6o9z3!{i|){bA)l@+4ByA6owTX7x4sABO!S)c=tuaU}dZSIE&t(?I1>J+cx8J78IX;%|lB1!}CAlBvR5JhX1&5 zN@W+^puCF*my-VQ{Es+^l=O$;-!yL0)%Dj7$^4P?KjI{gfPYhZMa2t*_muI6m2UzG z)6pK}-<0%+mhUvDRY?{9aK;}Jh^651gVMJ=JtxZvseEAi!?Z*nn7&ySgEmG-kA7-P z{(;iAa1!2UN~V={z`prNvW2n{#6bRI}O?8Y92?z z;Sq8Uo$QbET~cIjk>gr6hRL&%K<&Dsig1NoFJ?S;Rh_?T4#zB6hth?wUc`ZSu~-t4 z^F9{HIC{NS$k1@DHtDM1Ds9q5CG)gND^>@!Nf$0C(bzS&T4Njb0{Mp*VK#bdlNNdB z&ehIV+vj8|A|z>E!s&YRd<)e9BIXV^ZPA=SpuQ@kaoSTp`Cv1w9Nn>EUDzMeCTS%V zA=#_08V@s{v2BNTR+X3>f-nQvdt(zqY1$?AHEcjtJKpunYpOW*LoaOL+>nY|&e*D2 zr?Xu<6lRa^RZOes{yMfP$(a~6VY@5_i@&xaPJ_MEvb~AJ5vpkOR_UAxSS?2g2#vxp zXATBA)=rA7ibMUvetl4y>Nt?tu_lT&j(AXiOF8at=FBzD82B6sebGvNRX|rqH{?yqlQPMllqWJC zLHxyaS0flX`9kr$j?J^|CzW07H7jfURc1+zfR1wR(E0{_wJ6;R*>3NrRH)T#{ngd1 zgw8<#ir`W-HZFyfavK?6!_%?K!pav#=f{(StB93vIa(*oruQ#JI2r=&*W>%U<7eTh z2_-5+NMu_t+spl&%~3wF*QFr}9n?}p`iJhur&t&aPV!#)zKg?-*o z3Oe>7H8PRjz}Z4o7ud%dsf1#}mxBXM$+I2Us%@q|lvZ=JS4xqmP*u!X(4WAuS$^o{ zP;`b+NweM$8Grbq7kwN&{likl5!<05lQcaNj8Q=Bq* zatx8}<$VaOC#K{3;#>|?`Vf*)^7qx$9d+8mze)Fqr9MrhE_6!dFo+K$^OpWu^pBWP zhkBTHqNcv`!znGZzRa=cA2GvI67_iw=Sm-K@k+UwbdQ)zWy^$)7;WK?qk^qtVl3FIW3FUZDmb8POhAJ5)9ObztEjy@HaQOeH5%s?&*RfK(U`OC!6<{glDzm2ku`2NG4`!pd+~}wgw9B8 zbWOi)g#20b6cy=u;?hV9Yg3OE#7Oy@L(vKmbwp-D&Q&%?oX^E|^d&gTsY=I7;$Zs; z=8;Z`LKFQMVLprHd~>0qx_NT!mv~-s=#VOw38B%ai@MqVxU@*C0(Bg#U#-fJ4q>>4 zLxwCD+_I+x!jn;jo)F>ayEOyyX;o)b&gAiECz&kQ*)v$~JN@@dx$8TL`< zkII>&rbh=MIg&7FiryI@Mg2(TM-9rT!{?k46Dixu;|yUd_z3bF(}BauuTxHyGH_(^ zXww)jT{YYw;}Gh*2sXC^^*&i1^GX)S3{QkpeL16*18Nyf330NbX{+Q>jNov5%;nPw z<{(gQpn}05lLQqiR}Wonp2VtXDL=zmd5*GTCRKN`?WlP(#oXHZW14D*onJ&p*xAr{EWV2Is#aL^TY#yWLO z4N>KCwi>5Ts__y@O=*KlYRGi#A%WNtZArox`!y7wc6>%P)OoHbKr)3j0ek}M>l=|s zO;u>-O!MRchRzu9oH>)xBROoXOa?r2BG!_jv|-!QOWc zMqOMBKK1Uw=${WBjLzjJX*>VUydu>Ic>a_G{h2(Y-oJ|RQ-8f0w6Q)}Fo%&u_2G>Y zwJ|}CSWmGLpkz&P>A7Xai)%}#mKB#dlUCOwOMkkZzT=AtDUu(!k6=LR@%pJ+UQ8Xm zTeEqSV|=B3w^dp3XYC)!&y(iQ`UuFh`1Rl)&aiTtQo4D{TB+f9$5x90vXKWV<0qBQ zxy77Cx}c(_&KC#-7u9h1UraV5iJw1N;>V*T@G*k)^YfXv7$o{g(jQU;w)_WvpC;vT z{v1~|rJm2rAOx#uhNO;s&F|$L@%IB#B$%)l)u!+Ken5&i2{L!ySn=&$Ln-!e3AIQa zEhb|cRb`yq$pV=0^s=(bhKBt7e7@5Y{|u71lEC?5gUUEokj9Q(Mx_;Mt5M2wcIqkL z3)bH?v|Y1*e|cl6y}@ZR`Q?D3Mn3*2`G&maA# zA9T)^e}m`0H2aaabC%uw@N3pSujgie^N(LJPMCC(d_F?+Klx;#xj(CCw%qeQZMOm~ z)530f&ad$yuu=W5HBRN)t!bUtgO067WM`@caTFTPpL)}%{^g%&(tq~z!O)b)b1`|Dw39>Id^?|y_d0JL;G;?YLtz(oYzDe5UKfkBv#bx8|SbGVw+qF!m)7 z8Q!rD16QuBJ;0MVDH}RH<_io;$MzMO8pMB4=j@ta)e!Dt{p5k^+wp?3e2R$?nY>aH zjb?0n07d!o+0^hj)im5~M!r5X=QERR?(%#^MC zD|#b8(L4Fsd-DXH`}4R>`IoBQV}DM{kH$y z?x6UP8NYWB)HHkFvb`_)OR9m}Ysn{>uEmW5Y~X6i{%W~Sto>Zsq6A(k9Z(QA_^&PfN&{bz`QNZ$_BwE4=vP#8?-fyOPXv8uvbG6FG4?>b4i$Y*%zsZS%4mv?{kIyJHceY5MLom*Wl zroK4If1zB6eO4Z{>Y|zx*LLH0#O=kZ+5jKyitiPcgsi_0Y`@L^o83PW5v@+vzeL|T zX>4PFhS{8%XckQ(g`xIuChODT#vl34ox%AV(f&zu-J-dPVF(!{k$i^9hpiz*Ddy^RWdWSM%jEs5$+T>lIB`VsaaNkd?4{118GZnN zvEJ{nRz1!kV70+F>rntmBmU%!;OKKlx3~V3l<{{ArC0j9d25^$~lM&Ye3C6Rou9DJE zF}{?l1nJ%#ux#A`>!{PCw|W$ zmfG#7=0?=V(7ZCwo7%ruuS_-Mi|18U?2lEC)YL5BW@NTS^>)2Q=c|cqb2>$zBg<0N z0y{or!ZeFoU}xz`%6>$0IzA!2Tvw2oLXyjXiI&U`Snh#nv6ic;_NI4)CE3R zjT|oj%jFw$v32>Xg42nsnk2oyEhXeDJo$H}~dwE~P?+(J+ z`L)rqkCT~I;CrXif2*&rSQqO6Rwo%cJ6a4=wWpJ(ISfLQ^-G@4Nfkdo-w}V9L7QRY zry7)rai7}%N=QGMVMkoKOln_Jw*S>QBSQ$-67ltOgkH_U(GUD)`)IdZn}70r@L!Y? z9rBkn{+v7>-O+(g{J;03Is7!PXMhc0*S$mkT!aY{rd{F>@t3N6rkOj8hACN-=n(N! zmh2GWQnG3y8(>#=8FMaezx2Co8>*UwXukm_*rVJbBb1#2ax)rE-4!Nqa?z1c$Yhrn& zbwAF+@q*=tPJd^%_#MLEoC>}%94cjvex-kMk!o^=X>4(Aol81~x1S z%g$6J2iAAioR7_nq~c#qtvQ0GR18ZFDdRIf70aicu|bHWj6bE)6jB)jV5>vs4$32s zKUIV|Nc5Ebul&UHrESgbDnv%c>;!hRjP8k_CMi76xRWB3?bKmMQZcW=V2Q4jORSAQv)O_nN z6}=gAYgRG2Hn}JT6RE<>f)TPTYL_yOot9v#_yt6Vt&l`c^?v%?OCuFkCh1h~^Yc{t ztXmy6`IPkYr_L>|<;#(*bSE$*aL(3(M34fm+bza!5X&+;VALYm-`%Q+Pm+`bt91vJ3suN;V$Uq&klK3GF5xbZ;r zm7u28gTXIp+6|x^*?bSIifG!WnuyOimTu6)VVEy~Gp^CJhD`^eo#5CT4n+IG4)DRR zXxc6?yIIplH}f8R47}~Dns!?YbXzoSWh?J*(zM*0$p`pG+kt4u*EH?eufzY%qzBGw z)3hbv9&qL@2cpZqu4z|*uY7|uGC|)hn)Vei_!CXLTi*X%)B3@FF#A^W{R>UI3EU1o z0G4mjGz07g^=}gYmzw4S?*W^@srPBxR`3qc^Q{BX^j~S(9ow8 znwE3hf#?h1EU@Fxtc?JlcpiCy*)M3?K5zp#^LFG7t^nQthkU@z;2u!>i>AE=zV%m4 z``mZnuNyjG|BISd1vb2de8KFO$p^RrYzN;0w}5xNf}Fu6f2TaacCZ&T!1Vt*5WTxc z(=G$Yy{2hbfgRv=VCFwLs}~G{4}jbEBlkPVS1)o0ZvrQQZ-G9r?RDf0z6*X0yzOmG z+YR2?NBMsDKy*w$dIsM44(0H@15y1T^x7$pL*xhC1>Pa|@8XGp+rd}B-1nGw{+|QU zTftoLU9beKdY^oQPk?uWY(d%?$kj(k6nrk%2d z^7@CS-41R5vwwLY8a_2mbAvB{jo@wL(zG35!>7}?Vlwc z*pZ#4JqV8bLYnrgt(4mtY1%X3vYa&SZSYwz>wfs0n5KOmyaSvD?gPExk~7n^0N4S3 z1ss1?nsyf$2DgF_f{%m2+%)ZV@C9((1H?N!O`8keIz3H$7|fhOI=@Db!7IV7;5}fK zJ58JPAoUjP0ILeqw8_8W9^3-@E~FfPOZ;N;3*I(2P5bOa$Y)-fwjSK#Nz?ua-s4Tv zF77-K&02(9!Rp0n+V{Y`%hI%;gIkv%H*m%mp(FR;Kjr?4H0_ve+=HipGnP`Wau3c0 z^<|VBcoVoD>;}IEE?N#9a2Gh?Ve}K+22Q<_{5?YYWog=&9n|9r(g!=iH9MiRf_#CE z{xq#*7wLfezzr+YwC_AdzQH>mKM*Zhm8Me3J65PSbqgZ8d3HE!YcofXlAp z{ZrH%uold{I!!ac+rX8-!%o$vX~*uyt^|=A_*Mhu3zn=yUf@08N-%SMnsyyn1%3n~uJKLvd-d>Zxi|B%lY;NvgIoBGfT2B{B? zebD?@Id*W);$2f!Sa?I0NheeW2C{|DYS( z43>a*fSq6mxEtIK>iy6K^T2mOH<)!H;lXUM9Gn3LK_A!%mV<3z7;FbOgB{=(svJcpvG5KCl~X0C$fge_-1u;aA>&sxP{10rWr97rhhI z^uA~>m^Gm<>b{up6X6eRo75LIz}|EEqPwXVjd}1>!h3KA*pZL?K=)+mgKc0h7@Pu~ zOL;!EFB$~1&V^68pT>JIIGy(k!5Q!e_7)%)u*8jgOUbXdFSpR{q=p(CNS?B_@w@JUdKJyv6=8-`!|r=O5)!_zQ7wl17ufsXebF|s{rl(#sNYHczeGCVR@8K(OJ#Jdz5^B75YyTAKd*M za&O`N-*|r$_r2t^mHfVme87^o`=Yx*t)F;b0;AXH9yaQ|lJHU2uJJc7Ro2H`oC7f;WNsEXp4&2e*Ko;4W}C_yX7s_JX}&`jw=2KIIQ)fw`a#y1_hf z5$Fc1!4hx-SPr&|Kdfw`a#y1_hf5$Fc1!4hx-SPr&<+J(>s+d-|0^uV!T zCzu2724{iYU| zIT&0(erTU}UyQzjC6}P5au4p2`x46eYVN@tP`?y;fI+Yv>;yM}SqrI8U^%!I>;U(G zS}FAuECI*Wl0G;C>;;#A`XbT?JHT5(_hRZhxEp*0EWZqSt|r{&)HARfya{YyLOFuv zU*vrq@s~mu3@$@nVBT`%4fcW$%KIy+&vFlD26$gae!w8;0Xx8IFsmFsfcZ2#>$Pw%WU%>wfu0~JSA`fs0*jtBQf#m`88Vm-Z-@tpY z8tnZNdIFZ$!v`1)p=awzH;lakJ0jRYuyGCX!K}5=Ur%_j5p*|Tf5F}0m}}r?9sGjY zdg{pr(g7Ply^(SOwJ&2At|i_Lqz~#hqE}$~P3YrwJa45u!OpLv$6(esC?|Oi?g87t zx4>R7^LpZclX?yYzlENGS+^qx!S9lOBXqt;I$(D@`2@8eptoNp-d&^vx_|ip@pd-w zZB=z2&yu@Q)>490tWq^dg(5`)R;gGq+p@LWItWmuK!qR`3RI0yp+e<}uFi?wh+4Hu z)gV)(s-X?pYNIswToBaOg{LlNj z=e`pUhWcnf82vi^^q~hPPn^{!zm1<)&gyO7p z;UEmd-7pGMFb<18OMF-X9qVUxKlH#L^uZ1oggr0}2VfK?U>r`tBrNzG@i)xs<E5Z2}hu#ZdRXw z9_aWy@nIPZ!fF_X4KNBrFb=z5681sIM%ov8U=sS^0t~`Z`coKI!6*#CIBbPUxE(q+ z&FZ_L2gacfj>91I+=afGa=;|)h0%J_fx#`*TQBzW=?5?g`(g9~+6e{&r29qe7gCQf z35Q_xBFgzC>=)B+(9=LZU=ohP=-cThU&j6p$_+i2(2g(($6>UQd_}QeO22`g%cuvK zgi|nZIsM~q$_+g*4r^cv2B5cz^1~nu!zk>92^fR!cajh2gGm^M3or)VU%?NoguW{n z2QUKLpgTzU0gRl!G;i&w+j&gjJ z{J{#CgnsC`o_-F4utV&yN9=Gw>^IQQ#SW*$4hz199hO5+EBzb>VH1qPcG2I%c$437 z1}0(2z3A^{+`}NOhf&x9ldx0l?_=DH9S(^dj)@&ki#B{dz<3`VB>XqX$Agr+pZbG|Z_>^`p#R=azkuFvj29Sxgnkt#{YNP$ z^gK>EevJMz+6{W2p#Q_zFYqV)75(5Rgx}4$fypuE9T@&S^TH#*v$JpdC&&FK*sI(kk|!0=1v^zsqP`^q`J9Y#+j9`v3)r+a=%K5FLlHW;X# z(??+P!a2R{XT)!s(?ig4?VLUgQ|}|(FYyza)3?I_?1dp1gE83jYr?@0^uB*i@08y# z24gq!T$wTSHq!ka@nIVbwa@9(!rRE_@5w(5z-R~gfsxzi^cffmWB&vB`7n0qhRx6e z+o2bB!4#Z;v5(B@HRHtFI;VF-M<>s*`6K0pjWF=hIXw!4ADh!l|3r9L36sz#zqgY= z82vcqhmkwx^pZal?-QgCeO<(dp~#$Glq5ghEt@GG>#U$Ngq zJHhBK>L13xI;W3A_t$6#=z-e*VTU2;xtDb0H*`D$`^YbJ--jOj?i1t#dPe8;0T_o9Fqoje{>krO z&FLM`@n`A>CSXH~{3P)YgMXoY|3!K{GpP@zo}u0Tjh*K!?Vcvy->~nYA3#4$K0Bu` zK;IPQ+DkrQD|A0cd>Dt*FabmR$lo;e0z-T0SF`+{XMDn#V_q+qhb!mxHW)0N*OSn5 z48Iphr+8i;hY|O@?%z*-UNW!u!(hq0UUC5YOXu|tn0VQ|J^>vk&g)*CaIZp#K@U3g zyk=gncdXz9{JcI01yZoX_&0TeiY|p{W5*~V>XJKBif&o|u zBd`g^U!o0CSe=& z>eLgAz+RYwLy)_6^#t_639-W&n1n^YAl`}v-2=n03PxZZjKe1Ab}r~47=oQJ40~V# z_CtqjL61W>+zo?p5=P;I*tG@S&Gx_z%b^ce!yv4OQ8)}^a16%b6ih%zf_%afn1U71 zv2sDLfo>Rp9@q@MupRnf7Yx8C48j2zf+H{t$6*AfU=(WqOZu=B#$hE)Kp#xP2AF~^ z(6MSk?|^O?fgZREdf^~Uz!VG}MSg!pxPk>e2xG7Z#$i8n98Er+B)@Q!-$9s!5x4+j z(9L!-2`iyvHTi*FH~~|zY&X9P7j!QSLqANwM(8P8&|6^;hG7(T!xZd;-eVT@AsB`U z7>5(kT}=Ogp5ti$-(VM#&lD{CE%o{m%8wp{W$5nX$uA7SUi3Ju5xsC#--e7=_W-VuyiKsNZJ^51XO)RQlb&@pBsagGo3E z-KW!@|3N>4b`+jTeF@LT?=*ZP`GLu5`UOn9c|niuA^o>5=mq;o57t1>dE{?~@IKlJ zM%Pdtp`U)pd>>p-dFQB~4fJc6s>Kf7n;37*yD^x8!Fu|oi}~(+`VS0VzQUzxw# z$S;h2ka5F2p6DPSF!B-NF^?y9(tbsR`y}yT;8WBy^Lpg7^e^c7Jmq435BCxdy1z`j zFs}#hVLZd+R~c{2>nYe>g8gfh@1@w`G>qI!JDq@^KJoz_U#Hz+5>CMIHyAHmFP7|Q z9)R8-Fg{ADmxrkD6S4n@azXbn<%O{kewUHn&q;^vhW8ib3x;3>M&T})goDuYOUea< zFbN}Y8b)CO`Axtw=tz(*^g=%j!A2N{tuO(@(DT2HM;L?&==c?WD5nRONx5M)48eLB zg&i;jBhdG2@(06k5XRvsbnGU7Fa%2|e+)<$9}yY##ijuXJ`+HbH84MA0PC8k)fZZ?!W6=BB{rVX6 z!6_Jmj*}=KEP-)Y0o|wU*K1$^2E-1VVG6cG@2UIsE|`QPF!Va|_ZrG|I^~5?7=nSy z{d%wHXY$+}7=Z;RdAL5_ESmkt<-A;zkU1l zHW*w({-I|b`8*9j{{8v@jIH0VYpA@5U-!Wf zY=Cjt0^Lpf^$r+>5g3EJ$zS41{7F8q+ONCMAph^$ulJvYKj`QBOm8#4VE~Rm_q*wD z)x?ACFmes`RRde7ueZVL_v;J7R?_pq_wrj9;`bVOBfnvyjq>^Nd&_=3xPjldl3p$O zzMXJ&r1KH{ZKSC*QCH`d|eNz#15W0T_nO zFaq0Q6n4QljKTyQfJrz4Q*a!*KSq5)57f>i9asu|uo8w~9Sp-J7=a-ehn+A1dtegw z!xW4|$9CEShGCJH-yf$wU>J7D?>op3bi)zof#c8%Q_u%B+ARz{Fb?aa9lMAR9Xn`u z=!KIo0JXEpFZ93&tbsAu2otakreFlRcamSx;RKA_Nxyyrej@ZU=>8=22g7gxrrub01(crXBypCjKe(X(IggYnPP&M@)?#`T-< zd)I!w8hU%_-_ZR<@+UeRg)uk<9bck8>9^=Q={>FtF-?-U<^(9ng2d6dZ)^f&=;} z^ui$mGz=9V(Cgkod0;aP9?N~PFbs#F&wW6j5gnFXLcHS+=mF@1t>s|=A;ecNLF6_1Vhv7~5hY^^7?#&1E1sJbCpnErwKJ>#RY=kM; z3f)@{=waxE-Ova7U;qxm5KO=@oPZHH17omgGyb6mCSeuyoKL$!FKmK77=i)V38SzF z#$Z28!Z`F^KtF;$I0-{=0mh-bp8Ugd$O22Rh5=X)gD?mquni{Rc9?>_&~xDdJqAN? z7>3~(jKL`whmI}yhb1rxD_{!NK*vS2EA+u;7=rCE3cFwuMxp!S1Ns2;!4VjO<1h?U zFaovni3dwz99F^v^uZ)-fSv~08~R`bhG0L8z&MP89b2?Nmc z4)P6yupLHWm)KzxdM_d0Fbqdv0**sZBmQ9sY61MhQs}!B|1bjUU=lV#&t7GzyRT4^n1(;H;~^42nWLtQ!n_5#2II;r1J><5r!V6zrZjY zfR3LM4#s{){P&RGCkO{4urWmXFbdtH%pYQh6VL}|U;q}qm-L|r#$XkU!#bFNO)v>V zFa5v4SkG$1LH6beZOPAg26vv{{Z6F&Kq$ zH~5M~ZrbJ{T1{9D+$W z20j0x{$UWhZ@~^LVG`Cs&%dcJ7=&T5!(Oq&LFoGr<3xVLNf@4{-$BnF{Lzo%up9>W z($Ao0ANhkx7=+Oo$}9F+#;^1@*aE|F7)GE+`WNhgF*pX}u!??`fDxF4Q!oYV=ueJ0 z>J7SKAN|P#hhSiyeA0h{u;YL53)??TxC8iwUN{9q(D4!S0ZU*6R=_x{fe9FZDcB4h zI)0!Vc0mt}LN6SEJ~#pca2y6<3WlJz75}gl#$hE)Kp&K+lr=){3SDo94wtU?i4KQE zhY1*j6EFfDozxR7feF|F1FLj>5(W!&J@8S=wOZE)VXR2kJ=+LZtaDu)_TzLt1yje9 z?#Bpsg09D*`{lY`v7P*$sOu3Jf2FRMQhy0p36szVQ?LO#UZv|T&<*>b7Y@N79D^x1 zCHkv%y&z2ez%m$yUit0O^;Q^x+vWF3x;_k3&_Vk|U!&_aFmN*ArM%_3-t}?pFbV^& zCEw6}8u`0}bYUIzo}udlFbv0G{7hYM`UK@TOV>wW3XVhf+0+A!SCLK^<$e?Sfq`>K z2L@pjhT#y5!URmf3FxRMpF7ZD6%4$Y`jFq}5)L|QbiH~fe%^{77={Bd0!LsBPQW;v zfeBc2C;2*$c7SmhfC(Sz!{l0B_eZd=*Yz0m!eJPMNf?EWPZAyu!uZ>X|0&YFgl7dn zPb2Ljzb~g9KTUmKLHkmFAy^3`&$-*?`IM;tJb&QU ziySN3-78KkI;w!IILgt>_#6549^L&Wz7)GR6qjx~w(ypMu;Xp7IQMmLD1VJamH2-C zVn=fip$O(j^d|oL&>a%r{79HK{zBi|tFN|b+xgy#w$h^Y^1TJE$fCvg-fYu`(SjCD z^3G`$M-$o_=vZIu-s)^vU0hIGDF6M1b;Sk9D!-JqlW=EAI6k74pvBOv`Kv(dN4rLa zGQ!oM6?}iMevGMkU;s@++aTJ8Vt1Fbw%GID)y3}h#RY2$jd*NA9A3g4En)abnhaM* zC7QLYy=WCSErwQZ(}vMJHf;>849%Lx6k4e*oWn_Z(WE})qsouwMkBlGBU%Mo5!&e% ztp-iAREEoIYM(57r!2ihdsOD*M%nEr|_+Ahy}(r=U4vDllXkZzYne4 zrZu2>(X4rFL90Qt=TY**(#jFQc0b>>|7L%x!?m{9)1_@FuGqHn!s5gV=gq5&D@bB} zx}>#*61QX(=Wri9^0<0x4@BVI4zz_4iBIKh&FHjgBUEnF|6ud!kwF zKg!rIlZ;4Olh{K)+^gRx_IuLyOj?^&S{sWCBy0&|Wf#wj~^?%sT7S_8IH}@^XpT@6Xsbr0u1QAvbk!sn|cAv8#=! z_^-z9`OaQ_i`Z{5>|3235?!U=h&`2VkIOUhrK>7?J9aN+y~(0nVDKEC z<-m6bL()1{*A!Q5UFoMU-C}g*%%ELgh>5;76>LarsDmSoCv(AW;(dfZr(L_r9NQ{Qb8LHEwJS1%Tcs%J zbrG+U=aJkh@q$a^)fanR)r;cQ6_yh(K|b4t_v+{K-EpCezkpizT)O%(S^oI>?~u8B z3je)?o8Y@92aBnTCG}cc>}4WcREry=ZtMy^Y8cx!kM7m?(wDS}jmn>O&Y>~3Njq&_ zRa+c!I{Q`^dyV#CS~6zYO@)%L2#c=rUh;3wTh=`J({25~wk*^YUSd<$(QK;kB*ots z_v&X;k5a}vWggrq^WY9`eQ`zC$~DE_ZL9pn)mx9MEe^RpNtIS3kvD=6lxc`IsV%G^ zdL>R9dDe@}1;!YXx?NLv9hG{yRJE#IOk!r?&`a3QN&Ee?PSuAs?X{V-*GSs_;-K@h zwxo?}*-)sqlYOK;#q(vZlC(F=Hd1XL*hX&Eoa@wVAo+acF*>N^b&T+pJcs5o37_rf zs?RykPlq?^NGoD|5mx#_zJ73{t%B)FHf2Mhm*@d}Y4Y3~@ulW)^0`&ER_Rq|=aa~~@e!ML9yLm3pj~4f*^*Qj-Kq7E5v+8@>*x(>rDT(@f(kF=X*0>WP@GIPFB~pncT>CiJR>?&op{I z`3?}bjkt%C?+(KD5cY-0x3t?R{wjF((vPJc)Eud{v#cMlVY+#YVviOVG_b;VbvY&c z0^vsvGkiVaJ&gSpp6T>@T3CBzo!QrzAa=So$@tIqU2}Wlb3UH4r*R-a{DtsW$1|an zzfUjEpY*{|c1$XGw$whp+veWeGjs2{Lg$s~$(LYF{An*?T|_)iMVS3`V`g6{v(2qF zIt#NoQy2#`))!u2>pq(c--*IZPpxO>UMXiI-;vgxhx)5#90hom)RlbK?!#w8vHL1k zMw<)OE|;38n+VfI7#HblcO5KU)dyH4x?Dfa-Da{ou6)MuS$Bfz^GD0~StI#p3~8_3 zr+-PlKW+G2vIb>c?4*E;CQrt+hd6%X$4=j?Z9^=DggLfyuYQMw z=}Cu4?-Lkh>mp1U`S_Tur^9*5rq)H7G2@!ZZp)W!*CgE}K2IXuYb4!E)9I?b;fb}4 z=*$IG6+Hh*#@0H*s5RWWV^;a^bnVpE?^t~J!dn#W+wc_+HU*NU3+p!eth($rI=W)(%57Sg zYe#zfEO~tHH0D{TRge}R*={eK!1nngd-Z!o;Mj@t3&jO)v2ozWJHBtxvA+tmO0<_t zSUwW22CW*cNGXOEK&wLAV9}bFc9tcL2DCUDOR`M5 zEoeh%*0Ob=4Wh|-mXFj+1Z}{k?Lv#$v_Z6fG;6(#qK%-fQQi!HNi^+`i_@J(bJ(;3 zDsF+e*0wA|o3W+gMJpk$HP3!DHyX=$^^tNkq7~V+Rtx2N&c)_ADZOP zstut@{;XO8ZQ7(qS8|{^rG)mBtXx98ypou^0TvCH3{;cg5F#TE6ZAMGj!nLD~ zqMc(&w+n3s%{rGv(aQg{xEup$9yDvX5wvTFsH&5venBaOlb(X4qcMQgH! zt3+!@v!?4q+lBTHOF0_QQfStCZb6$uv({+`+9aBF{6^3wY}zigq)i({8@FkrXk#`l ziMHFOO`|1jTEVMm51UqoHe%DfXu~$mj~2ISjc7wQtrcz1riIZ4Y+5&3%%=6B_1m-| zv_6}bK$G^c*69RV6wSIlnnCNeX+^JQ`)1QTXx%og3N2#O>d?AuS`*rKn-)Urv}v7a zVVl;2)?w57(WL)b%MnLwvuV50LN;v@t<|P2ptaaEw}44J}~PwxiYCv|hA2n-)X!+q7XcpG_M>tFdWQXw^2&!9-AH(@N01Hmw4!(x%m* zRoJuuTDeVYM)TOTcC<2^)`eDT)1qi4Hf;dSZPP~3ifr0AT7gYVp=mZvdyT{4uxX`e z3(UpVzE+7Q^Rrd+p-tPg2DFq-YeAc`X&q>jHZ6iSVbgY@$@a*a?jV|MkF44#nrx4( zS`tmRZ&qy@O}0l?t>9#1dz9AXcuE=C2;uJHyXE*DM>w`=&PzF>!a)g66V?@8kv@k( zUm|D&@udG8NjzCIb`h_KcpTnPAJL*{-8O9iEn?F~(7J5eINElbmO|^aX2;YF;#{Kda_PllHJ`jcC1S9`VOV{I#O> z*|ad)fKBU0i`%q5v{5wcnqmlT#HJCYN>25ra|uILnF`)m#8L6iJhwJNlj zMXR7}b!g+K?=!BCI$w@gb39|KYjd&Zmh|!J^>V!0L)bRLdMb_MMGnGlbzb^Nalv)+ zWfNaiUG)$~+V_Wqmygt6KU%?`vuh|nS{$tkU(ZUQi{-qSI*wAO&Wkm#euTt1@Vk)% zzZ(kISbn`-0?2`2qKWT_D7o`4_3{KRz)5*8NpOIKUxUwJX5QNjc8ru z>vy6tPwbFO7|dfEoVk*7);{OEmK@qp=fk^+8^qu1B(6ICav4X{HgZDSsG9*Zy=`LW zBY7P`n<9?XiF`yGN2^Hg)8D2PLrbAGpjpFdG+@LQt`u#^rd6U%+T!}q%Aex-;FdHR z&;n@IbX(9m(5&fppbgr>MbIW}{&u0c|6=wnvuuNCt!Ouz>DI$|IqgLsJg|~&+~zZv z94oaQ+w^n3_m1qTAnS2v<9x5Uwwwq0`5Uvxm_pXmKyoa}%U|Wo_v-I~+IghSr;fh{ z#+jddat7F;U1{XW?4#;jtZYU&Dar{gf1&fy%#XUl^E2N$%4YcLX9us8<7}hiT=gl= zU0M4S$0hBDCH+gz)1F@_hd*ZUwLre!DLGYrjB}OrFRIW{LdWw>?9*@JyV$lmotx=^ zb%k%||2owTRk#|$^&CdHX2PWoBU~5Z>i&B0bS3Wtgo_exz2uK`V_nW$$vJhyUjp0i zJhmxp1^<^jUcu?C7jxLyU38RV3t?09fT}C5#wysNDnjgj?9qeRo3SSjV(-N6cqYI9 zUD&+`u@7Sp=CR8>Fo8XSo#LyHwDAmDKbo3DRGFMNs5V~1e@^a8g-SS2CH-OY(BbL` z*Kru(LWG+*L^zpCx)|T}f7_=&$an3AN;Q_P`i=MTwhmbs;j<`Z6{{W zndJ8{!`2hF?=Zu*6L$PC!pivFMOgR0vimCxA;+M^XIuA4=^v^NIY+ZW&e7~xxxQ;v z9p`8sTp{OZD2QyECJA59`&6oBzE}N;i-yeWOY4hcE1aAmHZL$$7gq!b<|d)WGxzB+ z($MC)0-ktxIyWu8RzsbGQs=wib1uP?cn{%A_UfEAb!bEQ%+;o1T!NnK+m;r((zkax~R!J)#- z+OUN&7@&WDmG9cvsY~Y;+4eKHkw$&t2h&p<$1VuJi@3w-xX~kvnEeNLq-4;;zP zE9P}!`O}rTpg$egd-!ps|2Ch^{w4KU#CQ2foweex1MSm%*CtLe^OC;q+ZiG!#uxe_X-Pn~ts%x_ zBk_)wK0o_fvkpkZc}?bq5jFnt@B8=S^IC&w9cbx&4yn^ov_7=YOFk~JT_b4hhS8;r zYXl|V3xqG_T|N&;c=BzY=T^rz%zYHEvnPF;n+hPd#H-?8lz77jix;)T<8mXJPl8_B zh%r80KzY|0eHRf4tjj zb|wBc8~$=%d%DiJ?ls_A$AnsKz3$bx-o~G6PJOf@TgL%w6_=2In%HsvF?)4(%N?4N zwE5KV*Tfhcr_R15+me5utm$j>FPYBn==?(0ZrA2%FXK7zz;C$7rJTb7rPetgyN-mPoMljb_Id`uEIL|m1RU%$qjchc9NY}JmW zK4dPa;=NxgA9vyF2-+n?+!o@heBAK-^MM=35dSLYINm06=^K{%+Ekoc;r!L&HIBra z=3mLY8BaUBc+$tK-^~0;yaeAZ+Z44%kjsNu(Po!ZTxBMGru$6p8vAZ)9$L~DnZLHJQftHuxmn}G*=$>n;ch7O z5q&pfeE6j^`g++e9Bb6WPFZ*CaM5qOxVMtE+QqV8>HLy)ZN>JVBPOi7`77r@cH#uy zRb}R9$$lwgL+)$xIeXbH#UrCDv%oX&Q)pt0SH65k|Cft=-2ckleI;8iu328;+M6v{ zW{j~QS}XaIc_W6;u`=FyBxSqX@M&Gw$SH=8Tem~Bq}1;u@dB^nT~(Av`;ZaOS|+uA zB`;f7Z7PmAT_t40elyHw$%FW+s-b>7rmx!N`3mD}<|NbCam({Him%a=O<#W~Q}z9P z$|&2#(zmj|^IH0&)bqWDuRG;h)#rKLe+&M?rqr;;Smqm-x$pfS z+K!Km@8DXtZR=(-*F8yoTk!2hyHB<^g$J9PRDRWcN~MRm7JLYwt#vc{{-g2vtkHLt z%p2Kl*rwvR<~nUgve5#5^+B%ZwYdVu%*{gUtbx69`7x94$hoa9a3neBP|k>{<3c$38YZ{;mW z-lC+@@Q(j(8rpjHm;Z}tG*J$DPk7}eGyj$QL}VV8_l?){e#bYmy*K)anxEJpTJK9T z?-d9+n=?J%y2)gVC*!k#G3(=X_x-?7lPh=^v7?9Ee#mkFkSku7BiU_!TR19l9Z^_)6kyH|ZY39A=q6n7?*t zb@qFZeb-vM1s%vZ3M2e@M`v7G=U8<- zMYc2Yu^hj%77>nPXHscr4zY`MIQxw>?@u067HwGy{~gITUKmtQWa|8f2Tj=e@c z-m3tPf4qSi6ugv z{9XFw1&2(lR{G@Eb8jEiSo7ku1D};Q&FD|cHs=z2syUK#nrrWLZIqLmU8^qOoaRrR za!!-&6u})sEY5qb-lz93p4)8OJacUn%y+B%8g*ZP!4{6^y?dYPJBOIp-J$+PWo4vSm<2%Q8@q5MDyhXJ< z+mCkg_7|D6wi$Dl^q&qYuWsYw`!A(Fx6_FdJ)FmsetP9$^i!@o_*L!!srJ7lt+6!@ z$CLD-SMyyv)5wF2RmX+=?%k(9EWP(o{WR!$W$t8nq9D=h@zwst7iQe|;A{NL%OCgU z4w{HgFNxN@qT819r~Nur88Y8Nnne~b6G%lGxfqfc0mscqua$tLSDH7Y{Z z33V594r1$!aV}k5o5_08Jh#dI($t??!s+F<{CT z#nzn1HiWGuk8KQFYaZJ)woo3MyMg&HkF640dmdXIwvIfuW^Ca+wlKENJhonJ+w<54 zv32FK?Zy_#V@qM{&SNX$AaqY2TLre>JT^bJXdYV-+pave4s3mSY(3ce^VkNk#q!t^ z*aq_0rmzj>u@!Iw<4_)3IktEnn-AM?9$OQ(kvz6`Y@>N>-PjU&Y%y%R^VmkQjpeaT zVjIt6(=K6cl*i`5Hj&3xgKaX8tr6Q)9$Oo>R32Ld+jJgVKem}Xwh?R#d2AEd9L)c@ z<`+jJ^IRTV8McBvwrXred29{X+<9yvY$bVYUD!(V*!r-Q<*^N8^W?E5v6bhsEnut2 zV=KLs?OPsO6*g}kTL4>C9$PE6>O8jX*lP0Fc43q4cdqt}WAo>+jbp3JW1GQNpT|~m z8T*uZY+h^)d2IFA8uQp%ur=kd$@-)do99C_#05AxmEzH;nso1FjSdd}>{E^E|ja-IXC zV&cTO1e3ZaTE*qGPi%QUTJbTsOdm0PRDFAS`IyE>Y?(f)IjCFto#o}D10Q|M^byBL z`FEF>5AB_7znAHw4j*L$%gaX>K6;kvBY}^S?=3GMC0DS1TBeUid=!0udHLwY$M$9V zNa90#V0rl{zmoOqGJUk*V_}&-`ti{|xV*BY@G-qiA5}s2A0B-E`6y#PZO6wHK5pQ< zu}>mZ9 zFS?5LW1jF8*cNQzYtTv`%AKD^Y&FF4Fo-_Iz1hJIxF`Rl6ZU9J)tFLBe) zx1XP%8tSJBKb1e3QTJPFA2R&pxc)Qfe9m@^fFpt>#P7SB`hA3Rl6-euQ|y)_1XX;E zqqm{ITXfaVhrYK#`p*pU`iZB;63+wQ>g3^#T>8K%NOiq-X*2t0*l!cR>KG^sB6UAE z=LpSf2{#m8XME?v_O;wHD6-r*DCKP=e$nvri!WoPhxqlxSLIdDE59Dk#yA?l7RqBw zVC&9fo5D7j$5ucEj_0wJOXWVAJ1;(L<#}vP*y{4w+Of6fv2|mMs53d$EliB<>LQ$vkn# zuoXR#KhHDRE3wUQz_>p_=7K)#^1dEzi*D^J zB%SLzCs#Q4`Afe#e>p)%UOlFwzOSp3Qw;Xrp@0 zdn5j0KR5k7dEn6bK7_wM{3U;B`upng{mtOd{VUU7+w%R@$#~vv`dhbre?9mMJ!$%T z$@2ZlTo4^I{XMmR+3iuySW5if^cP#czwP*Q{BcIVUHaeu9G1VC-2Kn5`k%}N-aniE z&R@R23dU*hDbwF8m+!9~f03t6e^U#G(;f#c?+E_le>L0Vp~Lcb(D7T!PHO5I)88G- z_t%0y&)-ddmoDGmApQbVX8lzhmcN76UqLJL-*aaE_RSwod*rP@FI~Ag#Qc{s&Z!z} z74}7q_a|-4>`d_f4t2zJb8&%M{}X3{IHwU`)*4;TE3)f(8wN(=|fvp_d&mGxi-OT&p+ZmHO$_F;?O&-#bB0k$s^cc)zAZ@x1tdryQoa2>^V#k?mX zbFH_!C!&m~4fu&qXV159b+)h>TT{4!68N#Vyodh8HJLn>gm=-+nQ7t2nwEK8dC+;! z(v(=!RNzNGmTM=^_{WO$yV{C_xt?|4e`=4qzgcS{O+EqsrpZh9^)vb>WUi?<^0MT5 z)9iKg{^H0A*HhWaCbQCFldtZV$#G4dEz*9LFZssO`Me^DzFI_8r$Xg9QX2@IgmKk*)q&72SjvMOPynca|wp_mublz<{Ho>(I<&p_LmVWrv zzi0CiOh1ZU>PGbq(wA|neTj7VNISGMW*zM_`uC&{?ljUrNIR%LxIcFvRM!yvx3mOjIzj(og9(z|CL z|BW^5DETP5ZAQOb>h#m-+5IZDR<>QkFW2BDvsG$c$s1$H&2@++q!W>JK9)_V>PCKZ z?oOp6`ZCjLC!LyfI=30=NFV7XodvGT`;x5vMOW!CKj(gzm!C)4xcai=$6BC#Migl!{i z6LXTKt~Sa33-4v@l6Rz;*Y?-)?jt6D`#!BYJL%-*D`K$j1S^Bo)yPex!?jeuIf{IK zZm%_+T>DA2@_v+ab6+#AuAj>>r~ml>vUQbkT6ghCU&coje?x!TqhAfR4dj6jL(dUv z=lBHW-({A6C-*%tHh4~Cm$p&v#pJz^+>3d=ZES2Py^&?a#N|leNesWoSBjR+sgFth=n&jmeb<=B4R@XbIz| zn|L=$KJNdAio4UvE24MEJ59Ufxj5!?2{+1;a}Rm29~V&Tdhr#+*GSQ<{%`Sh$5LPF zz1%G7y8vZm!Cl`^J)|Y5YtdH>CtE&Sp8lLKPc``RF$POdnAN{1c{<1NWj)8O_9LaG&LBIoP&4Y9b?cf!i616@ z`^(JuPch?v z=g8tqSsIBSKGiJCmzP(TUHB@gH1pDRWO z`Q};uRvC-`epZd2E_rsWdEKoH9R~w2`;au_KFm(ywY}BY)@U~oY+WT+B$)+vGdHf{;}cfNaiE=R<1Ypneo4MWbtJ`JV5-OHM9E4qp5?tjQC5A zYf%<+e_tL^=lXK)d+*dXM11bTXTzpheaC8i_8gv1clI89>v52b&l!A18cd(}zA!%P zJDLBkFnxaih4C51XTf!*&qrSvpVRpC-(>pS{lfUH`zZ6>hfJSOzc4;~@j3J{)2BI} z4%L?q)$S>L&V17JxxyIh%k}Bs##Gcht4|fsKi!At^R|QZc{!G}>kh{9v3qqk?_5yD zdph55Tq8P!KKA{7p!Fv?8S#+6>w#+Bp`j=o8cj+DR78gI03p z{GxZhRiXLNUSkPYht`BvYSEg|TF|WNhR~XA{yNbjXx4Ol(E4p!KiY^*i=$20wB2Y9 z@8Ud9qE({3+>*Zqv}!bUjtyPv%H75Mf_980Tsc|*ZKXx4Myp3V-=fu{ZAV*e(Sm55 zXx6f|p+#-lcC;az){8b~(_(1THf^v^J$0 zd(1S-;TT#G+8aeP?%`i@&$FcAxRdopbXMJuEI&mnK?|d)xTaQt)^7_}gEnXj7eL!h z{;XrA87*Pc+R;XBS{K@gO^c!p+q40+I2wod)kpF?f;ME+#?c0CS_*BzrfCt*&)c+8 zw0@gbiPmS+d}zCDS_4|trnR6+`&#qdf!1TwB52(U4gtqiT*rg_oYESju!{bJ*fc%DUzF5$Oh>#~LKMeE5Eeh^!~E&M3j zV4m=k*y_KycuX&#wWFO&`tqsZ&rPN7LK_evd)+$^!d&6pNs|~S^Xdw{m}>}I{iRtw zE@5e_E_wFuHaRY|Ra^25Xs(Wsz7isipFBP+ap)`7XA3yrVI;6gu3D9M#*-KaM^ydv z5pR@uZ0Wq&i@alU}7JA0fja|s3)0CNFR=47dL zH)n03^w;qS_4O8G`>p-%DYL(FAde0x_66*tHKzSx?5gdZ>Y8e?%Um$})_MH`zH4`9 z>|8r!#IM2Ld!A|kXxjhns((xTCW()oTksv)b(#2?^kpt+dfU9dS?pWV@s0OdN&H^y zUF1);)!JEUI~ORK=?`J=Ab%Uh{?fF)J(K=8_A<)~^0!IsKTg{}n6cN$_@aF0i~Xx<`-d|2ChTRbXU-G*#|`^d=X)~t4)IU< zRQ8fiz z)Fo3DI5X0vx5@=WK9UL(ziQpQ9+Pyl^8rD5A&>c%r}}iVOa>bZ+YFuW@*rRt`@{H% z;$zQZ9~`IT{^o5)j@6vP)zs#k;xBx^@!k47VF%-|(Lb+WM;&Va`ja(3$`?g(okIm? zkJ)T2l)9@XUSz|(ewD=g+tPUT#H&~oudc9?crq6ZetuTJWd-q`CSG>Fm6xDI$sr1N zByBOClhWTqJKZ&F+y}41Ua0zyY+FXK-T%Wqne`sAs7+(LGl4BwXYT6}Z>v21(mduo zO&)fCVOB5E$ivk}-mT{b)Nx*}#BlX8>nu8EU0YZ#_07j}?bFvE&0ZG~uwVP+Cx6Ei zUOSO=_(&auKhJuCZODw-Z_Vo!Y5#4SddPYy1Ch3t{!&5s7~%bQ&+3ihK-Gb|)`a?c zx6z;!oYxJgKArds+c&~KPEhUsKU&)p|FVtpIk#GyldC;)l<7Ca*)sXkFU>5$r{ur$ zVY5tE;osC6zQB5ybW^mekw>26R%g7Ms%w>>$GA19X9&r|-=s{Pgpb@atN%6=UfpX( znOsNHZ8Fu^@_Cv>M_T zF{XOa2Klb-7*};??H9}`>iEAioaq+ihKAy(n$%6{sm#YidyM(;a^mw5zs>m7zGnKp z;K==k@Oxw0?<=!@hw$5)_Iuos`<3^Hwxs?3`41|;(!M2(o!$6lSJ9#U8ePp%<~k?f zG;aoE7NOi86>HIW`20_@eJ3DqWRbd&cHBf-BcV_B)*Y+5R_@St%Cbk&t>Q27&>l6vX+Qiuzl=5AE;dTO zug@;phaN=hKzoe}#o-<}iq?ZRESk!jdd92_bFMWshf%HhMlps-y@dM`>3(BYT@Pt& zH`TFz7FOo9itE(%SXa`^*QGaKsLbesB{7&V^dc4$j zO{Ka}{5&SGYL4+UUsxBV>RM@O^H795K4@Mqd|*s+s;-IcBCV#_tlmTC(4IqQ+?i>S zf9t(Y<~y9YDE;->g|RiQ%(cm~2L3@htv?uP)sdbSW&ZuHu^qOggAZ#u<})FE&P2`< zG5+0>cYF;G%q}|S*^CyqXkNm#qYa@w&38%D9Ot~ZS zH><9>mHxfed9CVqvdtR7){E^GGMLii(!ayir8&PLBa-Es@{uB3_u#C4A;BD1hz|}X zuX#j0Pt?Kq8N;ToH-F@}Dql;k4OZu#)T<8bY1*9UkC}$l$FeT?B+nN-@kH_wS;6fC zmWz0$4@i9k2F>m0m88o@=EDg28F_G4Ka1_6c7c(f9P?qwRX|P_txeYCTALhW$wSD# zHko+9On?4KmAd2i{BaX`}TwQ{Z($i zqxdaI`#m{Z2cCN<-%z#=WV}>-nfVy)5os6wHxA3Q3fIeH3fnixg9SsiJaRC&N**-W zvPK>}*y!5AvS+npGu=R4gDmadhOb@UH|zc<_%b3%@XT`xTa-KHS*`c`h!c5uR-cu! zewH}Y;gWu;=Isq!LVWkqUds9?M<4yi53+qUVCkZ&-X*W@bUwYL$w#(VzFpK0`;FZq zsBxEGk9{Ds$;s@$u+5QiDDm2f*Z(}?#fVqJe%_I!CuN-^UK4fpQrgVYN7XvmwQ5Cr zJEGRVC0}Jc{%}_R5kZYIWv=JGKfM_hpEZP=B;28V%2;Y4?D&sn^$p^ak7ylerSaL! zu}N8Pb>2<+(AxN}C4Oz@)m(4+f{0Gy1{D<~4h#yDVkH_#+hSc>nwy*e^7yD&$Jkj~cF{|Fm zaADny)Q`RW$6TxA>I^*E8bcHZ1hu|143E#}zvZYp&060;lz*&p%ay5wHw zvqxt24!#@d*zPk>>6q7@@y?B0zNCGd@H2>?zl$F}qJ_}9hi5bAFRIZx(PC&HmA;wY zcGVhd%B`zh#cF41UE%ez9otZNkpa_RoVeO!*|nk6<8Cw`+Sz;;e_Ng08eec>=6&VU z*nH{z z+ht>IU-=E%nRMwss-DfYh;_T|b-pjNeWkRl#<{gJqZo(W)OxfY7ajQPdx89sMaL-q z3OL5Ojqk=BPjzr7iQM5SH?l|@OfZME5oQbDwX=U|KF5NyEbAZR%7Sf9d83&RTj_oD z-zR4EpURk2eUtaQZga6O09RZ>uaRRNAfb%&;0V_ta@IxF-FvO zdLze;N~Mj~se^}W3(YoC2Zm%Slse*GTy<|#6@F$YQ+RAvos-edH_BukPx2l$&i!QD zhL|!BR37heeCL~HzD_psRfAr~*iGSYk~Y$gH~d-0O6HhiE4f^>Zr`NtS8c@kd+~cB zzO<=P{u|>jir?+O=Xf6dNgGF3+raExXWRdjd-{e*p?c}==UU_W7o85rYe>g~f34q0 zN7|<3TjYP7IhF55-%rm2TebE~7hA86arg+^{Kr}2otJ8yWWzewWcr}0Yai}Hgx^hg zdA7T4TmC4FguxufRkS-qx6>f#A&zs?>nQ2m-} z&DF1&)ud01(>BlDw@0t%yY?`C_(&g%N@yv9B3@%$Ow^C*=~E zk7b-}ygxfmeA~1x*ACKCeUWfKAziwpL%S@S?rzd;OQ*Z(@X{53vi8}Q_V;STpOmS* zpZN!WL(;d8HT*3(29jNeZJ-aXx;35X3fFAzgw(N?O67S`UGD#8wl1Uj?)Mz{#vXNyO}iwUw~BAF ze)`X>E^V#V9!B0GD_mz}kIh&sK@Qcc_N#uI!*M-ny_(g?8<<4=uOwQg{l=Y(jSHHBBEHzmwx z1g-cE``4Un=CG7{CXlu7ZsvFm2X1g=blqAW{ljgXM)$n9*yDeU139Ct27X>#&_?t& ze5LU9Vm@C;$}mN`eVpGujk+}6tGZ?Jc?st?SYg+iPcE{(zraG0j;oa;5A5M75>)8EVzs0%D&oJj|a&(*gF4<(`?19Pp zB$L-o>OCh_-)H{YH>@SCVCiO!}vN{eDU$} z*Nx`pd~#R>H6Cc?gFG)r;*1cd=?LSbm=79B`x~ek$u--S0 z*hycQZl-^Ib&vjLzH3#);Un{O4P$a>VOD=mwu|NHYEDqc4RZGfo&Hp|o*!1}?3Dcq^L@tIYaL`oF}HLiGl@vwoq2%$rP_J@ zBD4K-KjY0DBLR6ga*kyrlVKCS{2b6pa(;aud6IXlS=R$L4{x3~p5JbNciV>5mY3&kE@VT*>&-{iT#y)G zeD3Gi?Mmv(Wz>~5Z?^SvtvuW2ERGQ5D5;wN%E?PP(>`~)JI~|{Eh_yJ&D(!m0 z^{<%IUoUB&yfkgwJXBlE`lT^<+L<-NFq2%EKJiZJV;A6)kL+&@l9q@1@r!=BkyeiV z4X<<5IwsY=xr#4yfwz8Mf3w6tCmo-@+r|EF`d+uqbf=GI;u|w0YgFm`)r>vwmU*4` zBRaH~rOQg6TrwA$$L4~rv+Yx^xpGkZ&D-%8T{)*ar0(`TVvZ&5XWA*xP%-CLYoB5c z|8?%VBZtQNDz%PwqwY5GTl*(I`2_fzCatQ~bNaoK)}Pa9ZOUxRvwbAHy=c{P_L0mv zy(YiWPMh(s{oP1Q>M6*WYd>~Qe@N>2_vy5<+a{Hkdbg*lC%JJ`E}O~G9oH9D;7>l5 zeScO?ZO`Uunmp}tn|W$qUY;bK9{#2oA1a-TvgtH2h8K>T zGu~Ccc2PQNepK%w&93LwQ@S_`k)!O!vm5(Z7st}+yd;~>FzNV@pVM8^7oCgJ$)3-& zrW0A=?97=?t=dOU&|zBB>HPX9l+HXB_8{w%60_bOL09wr^J`0~w*-BnBAw0`v*~n` zj{k%?mZr0$-h$4CoW)@zNIKO{j)8q;k1qX3yE>cB0_ilpY)cE)a6Q zM>e@K@kyRrS~>24ud~HhdDd49Un3{Z>Af!WlDxidGB@AK*8slWi?6qeFG-(|jLijn zmA%?*&tuV-*`87I`S7ze8VUIt3bz)9HNINJr+iQPLSb zX-@xxwC6pCkq+leEIaCpcT(^t?NG+PU^q=Rx@rQ8BgrAf%+^-mJ(_5izN#tTd^pOJ!Yd*UJ09Rv2hxXrz>+WcZPq zVwsv@QcVadG=NbX_&Y4qZ`s!kLV^X-%MqhuSS4eERl3>8v3>4Yj|= zhrSz0--|Yc&dldZsjE`%NB_9^d<=Sch|eDIDM&o&q;}QbsXc2xmEcq4;#g3h@K7@7GS-<+ihQ zvj_)$sUItmB?WdKos-ul==sg|tdC7euULQKu^-Ii^3Kji$T9j?`pdE z@|f2m);-YWS~&(~%&LRlzoyms3Cf6fHS?82*z$vKl*Y$I#N}Pz>YPT4J*oGHhgghn zOJ>NW)^scBYBJhLhn3dCUz2pwc}ED!_t{&gPd)_$5xeR5%Lw%958DoAztMdj0KhTfu&V9@Ev)Y9Arxmojp|FeUgQUy5 zFQ!2K47s({nFLwTM(A}l&H{Ve;KlB-q1)hSTPjZt@+aKZ>ajtn?wM7cgDwrq$OlwzJ}da{*{; zKY<>e9Q+k*!G1vMNhiMMW#-|rIXt!+{Am76HMw1Ya}gf32u%&v@Fl^3Af3Ahbt$;w zq;n$rN_!N%<=E4|EuAhG`onaqV=|4t^dMzxqCEon8lWs{Q08oewR`k36TQBhAd6R? zbcPT;!d>*F4U;}o7~~!%a@e>2N1|QMpGgnk931G~L-cOe>Csxe2ri`p^u22z{IoKi zuLgKz+FQ91tsS71i*axaVN;)Z+EdP3##$yvsdl%UnH0uU3bM!5V?XtFyjOsF5-nr@ z5_k2%*JnO&>3T&1O-_n{WH%GCzU_`yXAq5_$1!pH8$aebw1KOqJQZ^*E0C0HZ>n1r z%2Rw-tMgIsu`!GM6V5nTk6!Jzqd`}+FmE!?@GsTWw>BgI@_xo1h^qW4z#SFS(le3-@^X5@DA zDc9_VOr@%~aF;GJcL%ak|K>tIvu`-*OeVQ_zJv04#xZmus1(b8$o7)M`em60%n;Ya$RT+uK)70 zkR2X`uZ!u{CCH}YFX2PjBdF6w=sS|jc6%t`Lw9#&ssDtP{|31=?KPv~~e0MNvf zgufc_s=587bBqPNE&=YElilwfjeuL>QJRtEd=h~?wNu~=c-ZkcWLX(4!@ zlp0&E`n8o9cc`Hs$>46I4gm* zNG;X!k61r}ed&Y60owztr_8D6O#;>o>>?9JN1o$1dShdOWdggvlx`xh$-vC? z3V@XX3pS-I16JyjZaJ_jAFKvgy$?o5#*Y9SY@&Arn7zg$1JnjBz=DAdH>C^S1<~=r z;(=v9-Riy{r8m+i1ItG`*#>&ww7Xj+8R^C$T`|(lCmwQ4V$vz0`w^z=-(AKa^u6DL z%2tMaO~@Bb`S6fmVL31duzm#i+#OMeIQyI4>GuGO1LiM%GvX>sz5B-csh&QK=;NVs z!~q)%8fJ`MeJBHVxlE;}O9NKxgN+4t%msXi@8TZOb=QrZsZ1vxL{8(zv= zE)8xr#}be=bvNv7%rPGubjrqy{x z2=LbR<~d@RotA+k>3y7hdNU`FUh&BpCKbPY(I-po8t9rO$Z$ypy>Xy74t!|bXqn)1 z2J-}s`^wKSKD=a&Zk*Ef{%X){S%`bcNar!V4b1*TL+__5ANi<#jDg;uL62!2_x*H_ z-cNO@{RpI?er|x@Vi^9{-a=d8p*juO1OCu8+X(Q;w|s}sc#kVdS>ihN0Yw2<4UN-D z$XALwtugYI(AvOthN#^8+*u{k_J$lejI{06C0_EOeC*fMKz);t{}^cP0j&a}CH23@(jH15(AAfEJ(@p9^iU<@GZk%1$g&; zyVW@ZV_cWf)4cDJrPTQFc1`ihvxvab1YKg5UNFbqM7|O7@H$THQ)zLQ$83XVVkk@5 z=nEN+f2Y-1M6&nUI{*5^v*yag`fjh^vSHOu4wT0K4kbA6=GfcVEj2MmV|*BN2$M$p7VI=~LuYh2vwe2RFDY|qQ% zQw=4Bi9YSXH_Cl&t&}3I;aQ!*Ir$Ve~tP>USg_Roqr|&%tGM)<_S-^ z;5*_8J{9;o*Tv_bIv<*6i}qvwJmPIXl>!TG zkXhe*nHo)V66quD3;gr0e*VR2rM&(nerRK0&k%EDcy`U8{4E z4oQ7E7FfdOR_89tNb8Hy@^wy{B_>&4#t~iYHK`wh z8a&Xw@pBL2;tsYtv#6gW&k-S(p(X0@8Cs!GFX2==qQPJQWxwgIdkB{HAL8;>q&|5P`Wf=wLaKbVEcWriNIQXumWHan#1e9z%pQVA8a|WU|@lgtIoFum=#!n z3EKfo17<2m4i90I8=zx=B@uv!u#yI}w+~hctOyv{XY^3Ibq$a= zU}*&4A*{Xu_Aju@3BW_x{sy$SPr4>x$-+CYb`W+cu#1t0o)rAW0ILA@G6Aw~*j1wU zzi96R-bos?@QDwTFMYw^fUrELHw4MkA-8smL(bdUc2JP{rHuo9j{KWV`IT?*LnlC+ zlq4@@;GJW2IE#q))g(`@eRS6iaS#_c1*n|0NLz=r6_oZ?ue9`41J|zmDAyHI$SM6_ z#K(cWeQgfk_x4f8n~@bKvtgppq@RSeage7fq+J17(@w22*GWJ7{k}U3R^+-q8g~fv zgB|kj829*)?;N5HZllu4b{iFRwJWI4JH_BtfPB}}9>`psmtps1c<=SN_A*uOyDg2O zD!V5gWjTU!l!iIZ^sMVVzf%~jg;dZ=It=-@JDlfp{6N3Xqm_8H1RAB`4kz}W8N-X3v&jB!e^=R^+~nY<4WLK!4Lzpyz!(4HnFm&Pv^QS-^a=T% zv~~^3fF}ok*+)>uPS6WR8yVlxL>qa1|89iOM)(N2+RSUS940D;i5En^uw3w{29Jc! z4(G?jV=VdnJ?C>gc9}6g;6uNehZb}4fn|i2^GsN3*TJ)%;ca~DeKgeV^QU%>I0$+C zy4Cq^B-(k}N~4|O$1uO^A=}y5%c!)e4~6<2LDFCEr=1`8m#3X8ZRUfU#2E!`)_|TgItnVOi9;Lvtf%TLe zbRJ892bN}(B@_SmhU}Jg zayY+M&=)tXIL&x4?&Zl>Z}#XW^O|6|TodHI#n?vlEzNIQFVMq7d`iG4F4Ez&s=zz9 z=i?dUZa!Ce_&~fN4*GZ=CHd?CpZmb47iepTUm`YgTs4DFU9`j5iN@9^z@<*}`040v zM=ah*h3P8QzwhAH2R&mr-{ml-u}kBrRqJ$xrZekaB_^!ErK)cG2Ax_mc?UbKD) z=A2=x!j#bcHI*0yN1ifl(9s@xHK4b@i^G{n^|;g@y&PqqnVkQ6eDi>(9yz|Y@1rih z-!7--lkJxbc`A!_=mE_$!(^hnWT%iW7~9>UpEVe-^D_KL(no9f zk8;$9!GN@|dl2Yj*YN;juY+!9(9#k-bx4PN#rHJEZk($Q{`9jPyYe!nn>=+e4_>*S zOyj8hb6nR1UUK|4E(4lhh;il z8neNW{opudUY^sA3%tuR!_%hb zaeQH3j}UX3!*CrJ1xe?Yq8wJ}Uo2~x_Ak90 zW*;wjO{edr(w=)N_IBHCxud4UJEjKqLWyz5+Gw3O;STVg4Bk@_mb@qFdxjC;LpE;k zUX%3&cFYGG0<6&oqfclZ@xgL|H2^cuOOt^Gk9Bx`kD&xu46pzy4<4FdD}hD$VC#U{ zeXx2z^!EFq*W`zu_CtGmF~EGwmjKMSe5t^E%a`qkUY;L%Q~b~?^+Ruo4?P+;)dszu z)KH^nU5cxkuiPZtY!~9i|aeku(g<{v-6dPrBZ~l6+M)6(FqbU2MoX6sfTe%D}tRSg0A(oPNrR@|7UpL|497&pclp@~v~_ zd*aOVIgroc%6IFT<)b!CZGx=c=)Jbj2A1lBVO6XA0snq1Q<_(V4KBbQhKJy>vNml1jSGJ>}@87*^gy zcM|fZf-c#7dOfmb9cBFym)1dC72?u6h^wdabP#t0aakS2vEvw{9mK^UZmgd;>KoDp z)LyS6tYt5h^)TBGbpJg*Vc;_z7QjxCi4ASKxUGOcxPp=f|vVSLC zD)?3-T?Nu@Kv*9`CjSx|-tetl5p+Mox_c>&zHJGw4wMYajcg9kh?#J9G*X*k|DFYn zz9>f#XxMYGrb5^)*V5NU7quCVD0tT>?P{dmb%ts8BW?MuXGYh00^|9%-%m@nVKUOj z-|lc?$zhZi?<5%CwNs1>ax$ccPGA4zB7FnW*ZE67R_`lw`ZA<1$UXD)byS`^&MbW@ z%FvATwMZ{@m(-)CvGcFrA3NlGNcjcrb*DqVPpkWd{|(7Vci%BL7V#ygiJy%4nhxTV zLBAaF#}HqJus#pCbiHx06&#tve4Lt@NLmM-RW<n?+) z{p@L`f~NKxGTa~`W8SE-dc9avu^Lfdy#~^W1%ZnBk#Wu)|#G^>lL>zf%b!Lc1_oG z_Ym3)=}Jhy^mjOaBRy7&JmBen?Wp=SP2ra7Dm=qr+ocJ~0A=l3i%421ml zQy#K6qf8O~9L`@!&Nj|%r=NV@7ovA+yLi!amkpa$cl%`|ePA)*HPH!uJ>6JOX3*J; zTcpj9i?}J!FC~!o<5Z5zJ1B>&m$9dng-F;^Kk*J?R+VMVg=f6)l z9|KQK1s^=b-vR!?uq`Bi!ezVq>~sAG_|rQfLtXsed)Cc=3goo}Hi+a;_$2^%D3K=!}d;xIg|L{ga8)E*-x27Xf;; zdmwM%Q-!b=qw`5cxQTPtyXfrnQZf!!Rf5Ku=q2Kri}b0G*9{0$y^Qmo@DpS1JA<`q z0GMD1ECS>9-!yKcb^51i8@j_nJ>*A0N#zcjG@l1#F1EP0l2lPBTZv@@HvCc2OG)XTNvSoeR zpf~mG>6L5jNA*oceH%cp5qr8-SNXWDa=nLf6*;a{vn{vzzD&7nHpYpSE+`yC;DzcI#rno2WX z&6i_t+d9VPJ!HHKNMj2R)iDCH+KlqtOZ0~5pG}lMF8SSg74xcB=%<^5r?4roew^{h2UXl8+RYc=UlNJcrEL9;By;k<|X_bykx zGw@9>*Z1mh%(jnfxGbjOBFBpZ^*#sneh9y{YdrN%6Pztsg?ekihjvg#&v;40cV*QR z{>O`44@H3f5*ueZ&v>6vrE=5&FIL*T_Ox~YEAqjP04o3%f;{w4-WFg}fOV0Gjs*wm z^vqa1urj0zHl<4jRtgN=ARnTa4y*)NcM~=aSh-K$d_VMx40@5Kyyd_ueDYQq^vvmM zfh|G0znJpw0=5HKpb2XPw#^4~0ILT^a~VBU4|@=2b-+eTM8|pqW2$!>qyTduo!lET z@@4{yK{|8Z9AMc#c_#tO0%p!z3~ZuL-U?vLee$jbw!|lI9k5!TynBE-eDWRx*5Z?w z1!Ml!yvrN`EDM;q&-(()1ZFPt5MX&ed9#2m@yVMDtkNg%WMDPGY^HWD0agvnJgzE% zt@FXw0bA{Z)dQ>Y!S(}N4vgj%dZ>S!fb9Ziu7?)FS(6VI11wmydF|OJ080VZQ&Q9E zr2@EtN@r(w}5%Yn(Z@_FYn1#vY#=`(@VcaT00ar+ThY0xL0Q-I}J zyz5#DEEkx$97}-Z1M@8hm2n+pxCn8b5Y{@+f+CXdl*+!|k9@_5`>Tm(6R>r_E;3Li7n`scV8H?2SOTyVU>T-#slX=rVA;S{`(Sy%j`?6yfc3R{(<=p*Yr?3GOMq1Z z`v>u*mmu)A@+vlYr&>V8y`p`(PEo(t|yDX*{n6wr+)S1^_3drYl); zM;6OS_r5Hx*Y+UYHl*8zu)aT!x!=4$j}2<9YmDs|-Cdj3?o%~a$-B8p7o?&bGsz}h z`=qq3%LT#^{IO>FY{HQ0_04hogO~ zjPnR`e@TDuLXLUFrG~W0vv9hdcBAwo^##uzh>JkJJE-1rt?fCBh%Z&SSV$fYq#cX2 zeJHKup`SxY!p|5S2%U(y8&P(h4$9~Gc8&77xxP4~Ci@?G%3=HDQ64;mqAC4(CdP_H??Foz94)Dl=tf+z(B5UklRhN4m*WR+p{o{^pi)imoZRGDu!S zdZp`=TU4K<&hVeCb2!6^J|4o-fF=20V}T7ZVF^f=19?jaMlz_ae8Ol~oEwqtitALV za>nAC?7o%;#x9T$9(w)SmCa+HUrqOIr}$qF zf}+0uDg({zwGQVhvd;&0KvUY&#`$~Dywkru?Y={1$s*jXe)kFa9Z{{n-mdxJ7aR$B z=+q{CkkqcT@a_iuB)IRaL>ozd8QfV^Xrb#&y!KXx(TAJ7kSl|3^Fc-g-Qj~^y-GS_ z5@fLVdYmyQ|H*sBp0TLkb%9IhjmzYwB-(FGWGa)3bN&2n!6w`-gL-rZ9c=~j;-Rs! z3-ySvcF4QO^s$YzalnaR6XJR!t{!2kqw)TV=Z?V)c(34h@=}br)Q#vSM8Q5o-dM^j zWhTo_Hyv>`h^wYJNf*u*yl&^dKb+{|76LE2Xak~KguJO69L^}pE9vTc=~UiI#HAtb z&(PhEy!9Q>Z9&{N#O)xSvb@mC#(n3wQ@K!3d8hf57b|$0gOa1M9(%*#>`!@(^2Xq1 zD@ZZ~SU($-j;L`+mxpw6btuP^^t(wvAKn$3E})h0tv1ilLDsaOTTB2p^FSvPf6GCu z2DJ7Wa%!yYJ^cn5P=`W68V!tM!KHRp5RRjGnjGCl?{iVvjzNcH);OF8K~H;dx@-gU zUW_asXck(A(-l-;8m18ED}ly*Mt0<9&NW&*L}gh+OEK zBfuJnZ>-MOcz4I+!;|-^NqLscBf;FzU~a7g{_gehI;>@L{vz^HO|w+{OPv5C3spu->Zm=AR4s z)7~-ae~pVjY!lOW~YW4rG#>Yw4^zaRYTH+%Cx0{*)Qqxt0A_WY&KQue>}A<=boYP}!+5H9IMqV`Y5 zn(}V&?~1T?s*tKLWi|^kTU_sO?xC^v18_OkWM5+(xBEs6UbRts`)8%U`%;FpP2FAf zT%+?LnW_dK_JPAWi})-$9Uo)w5M%mk|BR$xpXyZq5@TC(jXMEu)p?OV?hTphz188o zi2Cnp;8OqTK4jd@w*Dd($Xou<_Paqx$J*k1qBx}*&J zA`o{4)h$S`oB5on{N4=RAc!xNcoZFa2XDU+&q|Dq3&C>~!rIr5;a`1@Yyr>U?f!XM zAvbo!NuFDgN6rs&{UG0q`8}QyXuCic&t)E-6T4x5;G_0DlToH(#Pvj;3MwF$BgT1R z&wDtqo0NaMs)$C10-}7i$T#f|=A$ul40W6c8}fey+GUR3uBWlp#?ak-6a3q1?z35` zkhgNXLG!);49zmoY)1cog^5u6+(lFB3x6^s?+{$>|2E)+! zl-m>jpo2IAr{YJ4bAWpsJ>Y*FjSR9Q`)bgtJK}KrW~qIup#y4x-4FWOGB2CLzl>l! z&{Y|}HWkK$TmKjBWb6>?LViQ-pB|ec=^V_TUwimdz0-i@KYYTu1!4If)du~Zr*Xim zk#;iSsJGc?g15Ddv*_tTIfyPs+TccqekZ?2-^%lKQr}`uRyO(Qc)VSIr4KYBXrhi_ z*{^$bBJkrNH`8xqbYeNr+qGlRgdDYCq}Ykv#`- zx#za&?-0xPlx~OAZGxAwP#Fd5p8B+i_#utUC)pcVIj|aF(ra~K zSv>6J^V*#A5Y!%ru0`Do75b_lY#p4prnx!^8?(ERhHM>u?!Q{DQK-zBh}(lWcwvqH zhFw`m>u2RYmv4h;OhUTUzHRRHQ=y{!uTl|LinwgVU2W)GW6WS3secoEl-chzI>_4( zg*l(-?*fhder-;vgD_PVDtF2(jb@QjWO&e&R^pmqQ0Mp^c`~oVW~nrbC_L(p_Bb=YLL= z=R!$_tJh**8g+OX?XHFC@=oi{2*^yt1#R*>2U?HQ=@vtO<*3hfq*^4OyBT{Kb1#-G z@Db^Js7_Nz{s*-=KNY}lo_?A-dFCH>n)!!#6+yRWLWeCySi1x?@er>@@G3}Y({=yW z_PqX#?r#FG=`P*BTIZDlUODH%e{orxGtSWc<~@1Cj?7o@LW}trucQ|$khkv@o_#nf z`x3}|Z(vf_AAbBa?PRQ9&Oq1a?_q3~OV_^wns|tRTwm;Wq8wJsfVBFSTbieO<>fHo@oL#OG0u9;pML?2I<& z?Zk)d7LRU}d_1yk@WJ|?J{IraL$3R`B48_~gV)2v>n|Q&Ns!O6quQMJS%9DK;wA0U z4EMc#9=mi5?#EN3JUYwVcy8Zx?HI;x0Nq(fGD2`XB*m>c@J{k)#4k1y%>_VMBJ?`4Htd({b~h_xt%MCFBdElkDRn z&|u@*oGXd9>@SZ$%Ht1{{-_MB^qc+m7FKu3$i4%#a>uth^ARRmW_gtNGvVC^T$AJ_ zj+D=OKJ?Qc%t!r_ihRwJ^l#HqzucjBi)^oPh)cP}dw)A0STZp4UVagbaC z&y1x2o8pr<6Bw1Rr-^S4urgr5CTtS0QedQu=%Kn51KaPDt^(K|VCH@K)xfj~-aP7n z#RH@DJv~Hk53o33=Ce4*fQkDimF!MTL2(Zbn zyguuMv4|@{oUUp0GED?#&GFu=F94PXjPxZv#H$QgDKOe6q=&HOz-oZeyh9IRHNYBy znfKs#0L#9$%{fD+(%(Pb1O1S6bDRD?;jaZ!E=uTqb-C||?JUv}rhUhJD47Q*82gT& zAw3=%>j_C1&!8jQO6r;0-1B=n;u7v}e~$;1GZ%4{lfBP|O$Js4%sfU*fGr1R9`lvJ zjsP?F#X4XOz|7;U9+<-?-F{##KIxi(Mf}T~uXX|aeZb7)A_iD6Ft|hHL-j}iX7x#z z3QY6CvVk!lEDso!&&*>AFe;xJD+Siw+H2|abGxKN$M(yXq zsBf(oLjHiAPqmeOi*+i3RPWx1BmVm-4iBYI0ak-L_9Z}$eSHs~;<6F9195UaE8}t{ ztrW!NBQ6bc@hjz%`WXgW|Sum(*4i?PT%?l$=Q5T<&X zeIN9m5Q!W(NuMOutr+QRkp62UeY?EhrUPw0QME=vJc1B~o!dT1PE0&4-?Nd(9-WSqT-$2$u| zbh!R~uyjOEM%v8WHfIEETz$@$zEvN8m9f@KRWJ9LXh@>loM^t`LDY72pcQ|oem=){ zOv!gM>GVgcx$R(kVE2&f#xBBmG}SEzPz11AV7{_IaY=~V)j?b);z<7d<;z1H$-lq2 zBE*sY@fTN#xZWMa)gUgVgSb72%j_Vo8F4us#Mv)~J%KoRW={5DzFWs9Ag&y7a;}nb zIE)4*LG6-`xcwdE%S9afAOAE95ZAkdxC+FjcMw;NxQQLa?Lu5>2XRe^Th~Ec@L<>* z9mMrToTG!dG{nXK8$K(vgFf!@Ju9>ejjtTUqz9l*6JoW(F=7SvrHu+KSbSwq!U*N$=o+5zdKsGDg>v5^0J$q5m zMe0<=EKsQLFnRZQ8f3BVZ*9)IKu23V+0cD1TSMOG;WjpC4ZL4)cFqlktx<^dc&Lra zQHD&E%Qf$l-l_!cJucc4exG)Vg|h?K8?-O?&~658=0n>7+Q(e9yZ%1yGSHsqqTTus z6n|8zXk&A^$3os%p3x?sA+4MbI&PCD(7xV9`*jcPD$vgJp}h{YBV4rS{66i> z0M0tOX#dkg+xl17%RaP87xZ<}9`pOOmxK29>x}ju=%Jkp+B+~7&22Ifw1>E82mL;6 z&C1yf7wzwG;KXR}TF@@?p*Z`xxZd+$IGipP>CD>ZV=Zj&`0tiRy+r$xaN;y}Xrew092=?OmW< z=|g)zXji$)-TJ`qw#g*W{vQ|Z&ygMv$z{?ItS?No2}=W33)*3n2oGUnfz<$$`ve9y z5m>!Xx&mNz!01c>J+!_lhJ5Y-R*kUsH@&Q8dq|$oqPHyJ-tcmp8h*9%#W)Xgt#Pm6 zWqR33e>8w@%3b=pN=x)@gZAeyC&Nj-4s>Fu9HE{zNWK*M5xUydcVzFR0~-gdA4Hw* zqk9Tp_VBtR*yBUXfHeYV1^^f*Zfk~268+|3d^X3tIjY>}_IH>Q!#axxt6K0~g0@3eFoVoodeKD{h*!!JIi75RfPx>W@ zt6bpiAE_q#z+8PmbhiO3_rV%~l>rk(7Z0Ut2386zSR%UZYP}rx3+Cj@2=mzM@Z%P0 z_qr@%L{a`^q|HJ8XiAHR%AXEwBCvi0`1k^H5m$gXm;FrXCj)Z;lkY9b^!VB&aH3y^ zxcC>m>$V(N9Iy)zPfrT|YJjB!dz%21*(@W*-a-<6G1*H-FeZq93-WG5Ub)tm{2!3~ ziEczH261JZ?&I%>Zmv$(z0EqtIP;FYlaTk7)0GLDjLL+sQ-eCj9?C>~OOUtmPv)&h z-f;{6IA2=7v_J>N!?w#Ke|zFTWLrL^z~(XT`1bgWufn|)wOER@lU#Yna(X%TY{s0B zZK{QX4j$^y+$$h|&<$o?I2qUwVA9Su(v<+q0~SIV@lf7MV7WfnI$$I}{bedWT|F?e zAI*991Dg!Y%(n?xkxx2pD8{D`76XjvndK`17|}EHNCh^@CtWtMd|*_5dg%W=U=w|? zDZr?{=5(dNsJ=A6(L-@d40`7JRs$1Iq+v_Un!V zHWt_b585n<`Ap`!_=6mJ|=NOb#O9D+infS|t ztmaHbzZ0)`7cY;z`J7+E_oL(vsh=71N-1~2PcZfd_zVJV?T34bjpVZfe5{3S&UoT; z066;AEZ2Vc{L_DxMoK=Dz-PLPPnCyH3S_FbsLh!~d@9a>Prmwue?EGBro?e}jf>Ac z9zLWCil-a(x%rIvJnWy(2w9&a;M3j3r@x1f74ni=4F3?-C-!uF4F62N`i*}+`kgbG z-8lPp)CuPZ>YraGy89;|eDY=(e7*wSVgH;NpLO8#fs4<(9zJ`(r?kZ2v*zsi#C7Lv zg^SND51&-XWA!Y9&m(8grwDvzxcJ=U;j_n1en=*o`_DUTF`9%Dy@SA91s9T5QIbHwmIofLp+$eq& zn|t5B6zkguGmO3GL7w)iMp^d5ek7UFeNGR%%TbSV*fB3`qjChCt{ifFq>(P)<-Z)# z2Tc8z`W)`BLOBu;*7n^^Tv>1YrDkA0TcqzT>2qf;9qfxACnrtJ21rA5RUXn+Al)F0 zCDZqoN6K$$dOoFjwf>rN)Ujmz-#_~BRe}{eJX_I;W$Fe-{Ol^{lgK{%Q8u!XK-UURr53)zWkXY)O$L+xL zfCZZ{YLh9zVt_5AHbHr?R~;O}M#>MxjYPfjES}c6QhsEVnq;gRgzG4fE;xYp&`}!d zlX}pavK%(MKO5#jRK&1hXkgJ;Zb5p-OU9m#v@4V?7|x>+Ep42bOswBmcx)V!(F9=C zzeBBU8UQBTE*%3$aiW^!$-G2>cA)7#V1GSL;aa>75e|>Ht7$cIue!& ztPU8B8+xdZvw_tDlj{!IC)de7ru6wf=?N<`(uW{S578(GRs$MC2#_@HlQc-@tV3J_ z;+7e4#`n?aUDs#jIERZY3voN3C-Ppw7$%voyz?~e?~(aM{$<{MJ|}$v^xkko=I;be zJgN8_Lh}8ppme2=Uz5yE3SFF!uab6&o{-*?zQ7-p11=;fd~ z*P$F`YcN+*olo3xMsL!h(DL|LRLzQv$-U*6_E2|AGYc5ZC&nF zFMMFFoh?G|QgwJg9_ii|@T%Ey#%m|MUF2t$#v6D^pp`Nj^DWAK3=U9jYpyXLd%ia? zTHZOeDTH2yqJbpa)QNX@(@r?&P(St1+my;xdNtPPAGbMkfwQaVOz`Lsi~F0OX@vpG z0#F%ccnW>KaZfLRB9?SK%?bNKD{oVqbAx+MfXBsnhhM$Zm=lZzo0K!iRZE?&f3^9j zhn$lwIYJ*Md(-ay=pMqO*DI9`kuT_q(Mf;PtYL zSHtb#qW53QwHS|Ax3^cFPR{TbY!{4m6@yr>fs8rlcjMvzjDJkwm0UcjVBH*pFgoR7 zNe=NLTwJ2g=7ixfXq?Ue=MMmXD4SC%dynJNHFkijr5bK+QXkjYVnuyUV{fYJk1E@$ zAt4wh^v3`HQh!ldEmxaV_8C`;HTHy}I#t}mq&}^&*Hraum2EQ8Q=aG>)t3U;uUxGR zz@0jql(_-yg8-eJoxW4_D?h3Hq_LSo$AV`n;&H*&Dq^aj?7?4H#BLia3=lhP^7lRJ zuU7V0zzN=F_4hmdasE7d_7(NI;~{Lm_6z?igq2$&;U5ZEp-c^B1%U!cL*NOt;^ANg ziGC()uP{Ubyf`EbNe+fk67bf}fx@AFiRgvG-8->`^Vy1+tFV_8{MNhS_v4+s)5o05 z&|S8Ar7D=!2O~^$hw)3wxp+UEy~xGRaP}b=Z-%q?6|t!kE+i5w?EEny7TWpuA(Up5 zU9{NQ&vvn`6Pp|EVNd1!@6w+i&aDHL41SY`sdN4VeBvCg{u0L;xq7lI`P8FuR#EFL?3ALOvalIKea*sFS_~o=h)gyD8EGtxJ*}zRI*S6K zz8KCPw~2~ywkA}38_pJ?=R1qH?P6cJK>q{TK%-!3r@#%JAw~RQ4n2{Mz19B|EeH0O zQPpna-hp^*QpbI5W#4Jy7c2WvOasG1Rsn>BgmePc!O8Er6^8vIVrvka%@KNqi?@T= zFMK7E?+{lV4r0qK;39lEOBTD1+FaQEimZ{1?7Ng~hW~ zE#*rDJE>XpQikdbf=f6eU*R+OaYdHiz|90G9HLJOk8}2ro>A+p{~t=)GF3ecmc}r& zCjn{TEBFkREmieY_G{Ix3j2VIcNKO>)@}ZEd^C}Q(t0bLeW{2K!!at8_lL8u)pK46 zXRlk1ipFsEU9eaj&I?0(A-q0RAi6dbO@1=8FM!oy3Q}$kJHYY7n13)IX$kP!y7Zu@ zEe1~IOEktl5qBI6V)d2^bk}U#JN)|~b|Mhw`;4Gq;0uC+0c;L3Dj7e%!*vw=jo{e*AC8iwUYjcDf!w`Q~@w_P<=ZkaLvg zP0l`|&T+NL{P8?H1;4KphpZ^|cUJayu@ci47nsC$D#{`&KdOkmR`$HA6x#T4O>D6+ zhbBI<(1iG*m3=D+f8Gij^;S_8$mRr!@<0#$|Kr`h%}4X0dYhjTX!Gp?ZT^*@HeWBO z&EFMh^T<_#?bF0@!H#HRpI|36@wkP}Bg3T8D!#Y6TA2E`50AYa_)^StoMU|AJt#%M z9aC$v0^~UD_K7C&idTschXdG?7V(=@_WJ_Z4hzm*V053+B;rr1I~8&9gUX)bdz4>Q zHrFt(&Jv}%ouzGa*7^6Ve1}SA=yjrcFngPes=;g@7nOtA4_uTDW{)YNcrbfb5sr&t zUWlfP*|Vzn`eL?N70XiChpJeZf-ky@4+pbqi@*`LW{Y_3A~rKXR9(bB4G@d*uT{*u zh_zV77lZf~o7gpo&kGdwgV;}jqGk{~6)08@VlM`X6@%E4V6p8&RvIccUC6hEisB2{ z(NKXqu~&tOU+}M8e4oU2*v0CBd_lNaHjp0=7xM?Q_dAKF2D06q#E*$=T4(W1A}fjz z<%zgMNj#OvtD?jg32bwe*pNU7r&jyUhFProyWiLE?zp9f8Rq?p36$(#p3h$ zfp{_PJYLmP?Cix3^^AGH7n^e~+O+jtG4DLqe4c3Q%hvW4&3)N|exkM?o7rE??$6#H zAf8KLy9S881K2MKV)OZ|^n9`XeD-RhSf9wg9VqIOm~)^gN@5Ey5YJu6HeMhWUC54J zD89Xr%}o|RC9|qz@oF;Levx?oV%B((Sb8!0YOwfjut|2zYaA2^BH)_M{;a8lF?#{; z`-rm2#tw4j`5;VdDz3i$K@(30@fAWKTofp#1+fB}SzLP9$;S-C&zr=I&g_11suQcg zG}9UP-HKCoh?DweD4Q;n1)bT)0m`z@>{Y9n5zc-I5_7`YtYGn#omB*j<8~|<#JW(1 zkszxQUB|`iDlJuNRra$Y-d9<sr}!n~VYP9wpbL9d5i?`iW2#uyg?+Ay<``U_ zDvrj`lv5GQ>V$YbmhBZ{Wh@EOmRR;;fcP|)J#P~SW7%sq(G<&G2oi-|*oGi6y9-+% zBI>)aPeVja7j`IA9PYxVhKbL*uxh(F)rEa#7stD>@4_kkQYWJP8`(3jMi7B-B8dFd zNFux;l9KF=Bx1is5}Ar9D(splDrS8Y75P9E6|gyq3Ogg33O+9y#8yWW-7V2wLGpNX zR}fne(-nk2h#@i!F+>Mh2L@Usf{gE1dc9LDdJ}vD^eHmBR1BkiT7=o zfx9BS-XdlN@?Qf!qzGdqkH6VKTBdqO;6=SwYNNb|Kt{20nkTCmPzuLLL?!`Qn4qAiRsvWlO=_(AJy z>MLOeYv=rayysZdwux%-xFTlLnp><_s5|#7Y?>;T;^H@#E&ji=Ok^X@zl-PGCccYA zTg{51wmKO}ZM7qk+Um`!;1w z6x(kTOQU#Aps0)FzXTTZ>PYrYr-4Z7l6$mSkM3x$i^N~q$JB0Laq*hMjzI1e_8Zpn zt`?(y{oh(Hf9vlX`BgI%bzwMr2LIaGF08!6*-x4PQe+k7;cU58Sz%`@g9PxeLzHFV z>{JNF9u1wz0i6m{%P|z~VpTXhLi)@!zAxniE0z1#2e7@WS|1?lH1+KOwjV3`05&~9 z09hO$J_``d(u-pathHekqOU*eTXe0<6=_bM6TdH$z0#`- z!iBxN{FcEM_WsMsQLM4|AcR-+siZ`O{klxgWDEP&=M%mnQ9YH()+CCrGTEVl6o%EXaTI&|f}x0Ab77CFQEc~x zFZ1G2Y{CMpm1#I5ENI@xf%J4TAO+dEBixs4KdT{3yM=Kf)hhehw}vx|}M!HMQr$O!iai zeb1oeR}4buCw|HIN^8M|k*(x$S_#$iCr40CfPLqe~+H09@XHzMZMqA#D0za=3VdqYV?1#&3~ul9r2F3UrbZr6RcF& zPENrCSk~$OuS9)B#9ssv10sGVPDJe&s==(MLISW+IV8_(O_&;h~{AS4DB(jv2+4J(%Rb~dL>dl&EMyZ zR(24kl$E_FIwAZ$rLM9(s~~Jj9+)pa#3>5#j`RX)UbVPqo?yGVcuBC2)XoT>pjtdB z1cF4ts725NuteEZF1C4*2%IP&;giJ+I@*s)H~$KL@f%#M)7U94KGHaL2WD#QQ$;M- z$bLt7mMSW!(J1_`DmH1XSflh1UHx&+kL1B*CEtd>Ng~-5^WUX?KJWb=7li@jD*4XB zzftbmZ(;jY@vDV3sbY2j`^-YIMk!?(2cmpeh~X%s+ZsWm4IF_@;(uSZ1(vb;34b|^ zofP7QF!HXv5yln<98mCMSs=2U3j9VznA&+LexmLA@UC#1!10Nuv+&jAcK<7p%8RW; z`FSf*e$7ghU$GM9jaCfBJ}+6>0dfUWVP1p_WY>}*YN;zm1L6_WUloxMa`cM#$UAox`T5q!Qg z5nSAv2$pqbPA&0x1g*9Z3xY3oCW7xquzj|~)(G}#VB*#Y_7NOY5k#;kk}VHS+!etV zhb4Xy!4}vPpX|(vBmR%Y|25SAM@Q6+i@3l!soBb)S>bH9ns_3N&D0XtghL@Dz7)<1 zEs1l(*$gYCX|yJO5ylSN5-Y>mfxtxUZSD<9tP5wmf)l?AV;_W4n%$vdBM`%FOM-Vc ze+jf*k*{Jq=5?+%s%$$~3pBWrRqV{nQPd|iwn|mMRM{HC^p`u!cd1{gY&BOKTt{tw z<8-j5L{X<=C8(;OscZ$Mmui7Z7kAf3SPsq<>2L>sE3lPZXz7IDV#{YRToCVCHHP+u z`FwlSM!dLdtPNc;fuocv&TbWzvbNT4pnkco6aGw$7$&CbhA9z30XinqE@^ZMjvg-H z5hql(fs1ccxSD2mOjwRF0dzG26dDI`23d{)>Am3QTR4Xe8hyY$4a5-RE z^>|r=OD{u;8~glZVb5|0F9^V<&}jTd>1}fdroA``P$TlTg|JJ5J{wH$|-$Y!)w3@U_QZX#OwO&PVVm<1m@lRZmBGuDfw6 zejFBemdCKi11iumUj%ku62qni)deuNy_16Qo=zA#Z+3oQbqw1YfmPwW$OlSdun%!9 z&Ot;4Bja3B^%W{BIl96RXW0#=6iL41Ph&bssCM^@zf3~n1u6}8OB32z1+G+bmu&;6252srcwb+6) zF6wRztF>Gw8z2fhUKlix2aUa=h=UsWe)L|BLeqd|-^cjpD9T|)Ob=pn)KUzGmuzA| z5PRD;0Dd%^m>tAQ1MkrDgaSgI3&{sKMtq{O@wZj0I3*Wdh0`v|IRLPq_MS@A5N=Xp z5nHN?LwdvZL@u<=1^m3e2rcHK7$+IwU{KZH5Z2T;luMinKdcI9@RQV9D3?5G>74&B ze%}}XH;M)u%N0khY$c~4*0ZN<40}i=HueRNTaQDDikNT1$2FsWwBhrT;wLL>R>UqF ze@zveZPf64t$d3nV79^!yu!w@rv`Hteg&-NT7)RD!EhXpu+ckI-fled5%7jZyN}a? z4)=#BVx3|nan663PfADpHR6PgjTi7tpk@fd4e~-D^oS_5Ay-^!Ap40&FO+55C(G6> z%Z6`gqHMEe*|yuLY^!Zlwr^~Fr=Vjf4I<`k8#^V-`GiH(SfMN~K$(paI_LM~(O7sg zwhTMQwjfYHHw7I6ZpUGVmy^Rzu#v06A(? z5Pia?AZbaU0=zsh1mV|YnAi;0*_?Yf{=Z*54H@OxxJC!9`HG73a-9%|hQ+nCQC< zftxe1-N6T~S8=q|zFB3{6#=8ET)6^a9BA8x7E=C#u&GQJ-EuW!&nt8JuYzq*?F%gI zGmLTz`$ipxaJ43ICUcwC3E}lZL7L6j>eqLp;`MgDBp16W3zen(Gs>C@Z+?YlKW<@f zXkse4cZMN6Ux=?P>=n@o;b$!hQod+W5T`Ty|$rTL3E4tG4Gra_mLXwy}w zD@ZPs+3J9s5H7XiL>yaTRS>S0;ZLoR2>&X>K7`<}0-?n=_MG;Fy2ge*b^*85rhr=z zUTswn@qtxAc#jO9utp+0*G9OD(C_Fo=);ZL$XSBV6@ecJb+ZsnIBG@?L(hD21yA0m ziCTHQ?|mCzi!D_vUqCL56;=wqVHMBX)TeFY1si+S7RcB}8v!l?G>G zlYEvEjbp(zN-U1Je5cS6VHhEwTiKJUcpaUsQ5c6_HX)7nCdZHImV}S2C^Cpm3lQI8 zk_mVaFqP;Wc}*$JGf_Ad55GJlUgMzJppj6!CK5Tf!>`>*q_9CiGdwZm_l=WzVToXo z@g^5jHOxk|?)cSQFY=4Wp;0qLHoMc5A7`EqYoauOEfV5!EGlqBBY1`+aZ(BRJ^+1J4rBkM;Y;fEvD{h{JO zlzKc&tcYaa+6Bn$3@5@LbV6whI#Z@aod>@Vg#&LCUK%lYXB3S+gwanlMc414Iz)0C z_0a|eoux;tCLBKOKY3gpG%w)&9#IwtVPi*u!Lm@F*Q9h4^;i=5*j4zyvXFIbwq2irrwkcG=qF)#$o{3?tVWJrhHM?kw zpjR(;qGjx;!<EL6-tWxwP73K)K`hx6^qn5}j)<)?=8$1w%rxSA0A z>}-XIT^`N~(9?Fd)RJ6dXFmnR&J1UBtn|*nH`ZMoKi&@pw;zI))pqtwNG|{@LlvZd zEwn4b3++U6sa=4++rGnDS6XzHaj}Zit{J`og_CleCK5zLN=NzVndTI(Q$3vKZ)2DA0HsCB{YbDP){%zm;(B20qt7tljLHgn#{_bPZ1 zZJOG>WFVICJ=+ptXo2{5c>wQ<&olrBvunG=HS3)wEfd0RvjbWNMf&cc~*TqiB`j?V`v@?2qmKZxr;mcz zulp!K9DOKu&bgtK@>~IG2hPLkP&Tc<*qz8jAI0_@W11uz8EG@4+_N?);=XTOB0I zy5ksY9YKX*cYfT1ZLtf49}DmCLwELW_|@e-*z!*QsP4{Ib{1{jvD8gLxFjM2u}33B zWp{{gKZMsrcH7(oU)7|%tD`7yRm}ZgB3GBuPxN3jVntPVb}ZHcWLj5&*bQBaiRCNZ z6#UrO%?6@gbq!+z4vz7tFs6-i^ID-=<*U>e`7pFTzw6)xylC>HwsQhZ@(T)XWvgu6 zpSl%?yfWSx$KDA%%-X#!r^>iOIR_F~9lzI+0k9`?Mtdpz6Q>5_Tl+2+m} zFO6pfQIGQ@SfEcLpkjAp>c?5xUvVr zFAo1i{V9jd&3Ku=K7oBaYPGUu0-JrUKjV<-y)F@H-@jgluNO$U zek|JmgR$|b;_Mq0)T-h}Wp@r+dZU6Cd+kOAtygoSf;QfAqk^8Ox=Db*@tei6TiHwF z#M)cgYvaV8aqf<#Ijq~qG$lW+iD%_;mbW#sn73=}ke2kdYYQ5}KD3#O%>&sHRs0Cq z#d(l{aOn+h7|7}Z#D;F;;`I==4Q&@pay!F6#U1Utxar-JEqp83JF zxGo8%mj<5;VU;)p5JE1EUBT23$AfvBCe{bDU2r}G^Vt@0I2cof_y|>lX%NEdEXOqb z(2Ixmf$!m7@P3Tbaidl)3KVkVxJpMokaPvE=#70>V+;9{>U#ZXhOus|;E!NJXyCny zV_^`k5_4mjBcRQ;G?ul6-}f8N<#rOU#j?jcPeS;!h*FM-laUHiEr^OhxHhUg!rw)O zAzTnm_?&18uZ`}6@F&sH2scG5$XpzwApA^BCwz`5h7!WG1@LJMMIM#NiI^lHuXT~J zT__fX*ZzvS(U7@8;C1TT1nw;=#=ueVu9|4!w2=;n?Iszf)W(v|*E8nzIx5<%ACJ2b zbf3kmKbpEiY2)iOjx)sHqiwuh6_WL41-{uQusC`OM@`7kD+mw>E~PUAwE-6+NUROl z;W^hg!hZZteO<+R=b$`R5J3K&rL=OWwO)*%DRuYZ7)@}+R4Y&7Ff)z=;6o7$DdpSN z0YE5aEPmnt?$;hf%0o(%0+-Q`@X)**$QIfV_ob~L5O+$9hts}~jB{@1!qU4!G}s|Y z&)~IoQ*kIvGKaJJpKJMVS{P2c|0dX1v_9hB$?yz|Sce5QHN(dyqZb(mysRuyRz|R9 zI6|?*DMV=mn}q`(5qPUqd>X-42E@G|!Rk9v8sd4SUNN%~1$Z65tQS`G+^MzoXHVF~ zFL?1GNGuz`js?e+3}98E;+6jFi_p%McdzjF61)4e@+k2^e^wbS-s;a9qQ(3H3~zEEc6N6G`iHs`ezH5IT+xHLtnEqRtvv}p z+|z31@fr^!H4f&@qg*V+Mwsk z1}w)dy}?#^U&*j>du-eXG+Kd2S2e=rxP(4IdQmVfsWf{a+zsQb@%(2$%gWMK{%gx{ z@6#Z&#r?fyqW|&lbic$c{fGK7iNgZ6=ltq^JoUz}@1>n*8r)oF)O!(_)fni<+V2s; zxh4fg7a;$IZ?wnWqp_sc#nq$ zfF~>bu*pTy}2B#@zmIZK{;?rQ@^9pqxcQ7AT;Ji=}U}c3qhw)~`872pR zdZ+Dva^VG6SWZ55vA)dB3oih;@Uqlgc)@#Ic)_>0@RAE)tCsx!zxip);n@18`gX!e zpND;4_%`E$dq6jRpcUTE;H9XbiP7X4_tUgPykmpU1+be4t_|Q4aBy|N_kur&i}jNO zyJ5VOber{w`dZ=u{2Lz(+g3350V9;n{oxH_g+n9eQ3sng&cW|9}gl3UYh z{?&#x`Nnxhy|d{R{I!bnjE#=)Zz)q7{r*qO)WWjhOJyo+7LTK=SL=&k>gy$DPSHl6 zdO0}wg3mV;Go8Q!TrBbj9?=VG1GtCiem_n|!T@b&uM_=a*Q9X%bB9Y-dK3TS{O9Rs z;FKk%MPv7RDu0|a1m}6$EntG^=6Vqm@J|%!v$1}^Z0$EqI>>w~RzW#&jg7>+> z*AKV;E%W!o&4OD4{Wev{WVGM9>guy2kHqw=3R% z<$KPLXNauQBN#5zf~*S$ug1kJJ;39a|4YJ*JmKrNy#~5%zfCpN+_HY()xb@rYXZO5 zP%Enk@nJI(sjrv@VRW}XZ;Prm*ZZJlc$h`GzAOCka$Fa^F)+Uzd$=H$CFrb04l#z! zdbHA4CSEIh{f~wF_xSN1H}iAssW&*h*5|{5@K1e#=Y5UwzS8(0i&a|g6L{6H`UbLo zY~+DOnAZ3LxU!8K?cTt2NAKITFR}H~|9YO2L~rkP{s*7jF(@$Gr;kSG`}9o&rYzi7 zIykN0;~dAcHGH_q_>pS9hXPnYfIEorI0-Bo39hXX$l%I$wZNtd&3~-W|#OwqOf zyjt+{8UftB`%U%0y6VB7aM?_EQ(Jq~=kP=E`LtG8m474d#>8OdJ00&|^`AchlZL=< zct0IyI54XU>XrL9mzRStDEH(2;&MOUXUnxs0e7)-Sry#D?VrvtnvTHKdb+RRTT-T$ z1n_=Mz>l}v1Nw1TXj@L-L+9dh{8HajzPI&?d0b4c{N363?it_HK3o@`8rZk^yK(sL zW#99@P1wH&@a(e6zZ;G3p7K5WPybGQzTx``lMKga`;oYsG~E}Qf}ZKS*?$$5qLr27 z!|g%+{@$P;@0Z~Q3=;>BtwIUJ@q%xmZ)E@{28!daI}UkV>JMHOzzkPXYVR;>+70Ku z7W%gM?kmIdX7F7;;K$o5%kWe+TT9(nvEK`ws~>YS%eNPH0s7`w-R-4s;rf?eLevo< z>Cy5J{xAFnJLrG&xh((Ob5(x#?W->!^bW2m!)fJ(6*$`ZqC#Qi2qwEr{JVZurY4jH zm*`vdf>_;^E(_)=)N^{cWKODlUdw;@*&+Iz8Kw-*GkSKyLaDE?;L~@H|1&()gELbv zs;|wqM%Yz8d+apd(DU@Z=<;B;ntqPh+qmG0>x8(AB!J7VKCCHytQuwk!B?yKrr^ez zYQBkhOa?Afl?R`$@O@Yj#1YeEJxF|uE74d+q)!9=il%$XwuB?k3f*{&a9v#tflC7Tkgs0<+7PmKz3<1mYI4osrn)LyGl=)AY6jn^tA49l z7w>PW6W?H`fSG4XHJ? zwaqnkf*;mVYxGWGi~jGSuvsnLK7vODuh4#0QzWaTBz2G+cpenu1W4ypR zqHF5tHH^2^!BSDI^i_A@;TCo9T)^N{b@XM^MRoK7uDj}}Y>nsf?GLqsu*5H`x5Lx| z&kHebbl(56b=(J!jeMsjo|Y3>QByw>0M`euF7vO)bJWUk*YWkpcP+izFIh`nSswhp zruw~xzJ#EwxJMh@>1*d4Ue6oAGsG|r!rFU0ZvboW;T+Er!!-~PJO^M>NU!O+C4>jG z>1T{xSKE)(_zP>BZ|m$2vZ`)iR>-$F6vP^Sb0J+i`S1GKWd9w0|G`Hs)mx0`_2E>Z zFZin;%ci7>t5tq3-@pDWglC@6edS;O{iXW%SU`#2pkMHu4ufOv=v;VGr{=e)OIjU;!{*>Ok|LVgUJ*?a? z?Wp(e4%PkRud-kLtHiOy=X=n13Q~4{@Wqh6KzCor_a;ujgw$s^G{L?b&p`|Mp2dS= z%$_}modeFbUgqlF;t-zF5xgOUhYHrmUBtLA z|L(fDA^d|f{h@mB)w*g*jnR0IG4Wa4ZB#Re_tRyFAMue3I*$-_!HOP6f-wey7kxZl6PJmJ=d^tSo0&l8T( zzyHVQ2{rT?HSCK%k?WFtVokNfgX6I<#&|00fKw9i*swD`-{B8F6I4muC=$fui-Yrc z=Mg3&u&6l~OM(5kGKAaU@UdEl;2?E`IH`wK!Z>yIIi7om>wCSXg@R2fg>fX2`5QkH%aCOHQ#Ctp(V;Po=`Cj(pgLb7C zph8=p3dIpV9;k!6jo#5F!B@(#;%S}lY208|rja(+$H>qodey|m!|)XQX9B@%@HCl# zAMd~5^s9^);G6V>)fK~ViECvbcx##ZG~ma3+*~A;r&ZH|_&nJ+Y+9L~zhOuGUBHj` z*Yiw`b=I^m%qIB$%v*bXH9()6f;X%$D#O*O?Y_-r>J=;@L!4zAt+B3qNF;yd-?Y># zSC7+|=PnCk5g1m{%`d}kYM=UMmg$pOTo=|$D$?=*=uuc5h3lq^%Jk*zyKrIApZDET zrmic~T(_Y%mgDrXy7jy36aI$=ad~81@I!Mk>& z+j{u1SXkz3{%{2zM>rbAZVf!`&*JHv<$iqlsJuJgYjgd#GoV;#ir?Y+D|pt|3V-CA zfIjgieQ7t*T2p*}Jf!gf-<6m==wEWk4RtTq1F;_qWuCz~lj868#douO{+IPK!K;hE z`=dn640HajxDEY}KF$)Gjz!6Ma4tf6!`~bsZO|bhE&v?>%^F^-Lw~~;ycwO)-+O{S zeJml1#Xo$H!ZkkM#kf5AG?xDQgIJmTvVZTZchwIT#VTQ}hhKrU!ogsESM@`+;7z-# zYpVxm?uxrS7yH+@P@mKeK98l$J3Z(7zJ*%dAow2EBsamTW8dS=I^fs8Gz(%4^YhJv z@VBkGHoc~WCR18y-!obS;R4w)FZ1^?zVl(3v=G!Zcvw?BQAt;sOZA%_I|ciV2k@Ar zaa$mAeNXPe|7FK=y(E8k zHG^Zfi7MP5pkEnk3UK=je3N$PC(3qci1mfttl#H~N*pgMy6Crad)smwZ-f z(G)d4M?R++pZPKVtNqdCZ7#0&z$5na%=}AjTD0K|`TZaLeYbzqunN0BD{ndDsYLH`DFdYplrm7tKq&*I43siZ z%0MXtr3{oZP|83l1Emal*)euS1UF`5cvBS?6=*?@I4W8ThMZ;Lp}my7B&RS-<)3#%b5RR;6xU z{_Jz&M_CV>rCR%cH_kt6zpCQ5+{RJTQU*#HC}p6Ofl>xa87O6-lz~zPN*O3+pp=19 z21*$yWuTOSQU*#HC}p6Ofl>xa87O6-lz~zPN*O3+pp=1921*$yWuTOSQU*#HC}p6O zfl>xa87O6-lz~zPN*O3+pp=1921*$yW#E5X2JExB^B0tv(Cz2noX?>Pi@$H{eD39Z zKGFGnvGaMR^Z6y`^G4_MR_AkITyZ?@ozMN9&u2TIr#hb>aXzncKL6@`ZaKcV{DYm( z!<^5TIiF`cpPzF+f9QPP>U?f-QE~ZE=ksvqbJF>Ir}Ozy=kv49=atUqwa({F{9K0{ zK&^`hAomgBuP2*VnuuR%qxYzHKkuQMAY?+uO>e?rs8jZ%PYFG(Le6H zJW8-orKC1WHL~Vogjl|$t(45a4x}ayka()o-j?^w){A%;!&P z$oJd%+2(=nN>a)|DFdYplrm7tKq&*I43siZ%0MXtr3{oZP|83l1Ema zqNb@CYL=R#=BWj$dV}Rt!_){hN{vzD)C4t2O;OX-3^hy5QS;OSRlUjbsbOk_8l}dl zacY8^q^788YKEGn=BRmUfvVnO`P48qLXA>m)HpRkO;S_TG&MubQghTiwLn#GvwUip z8lgt1F>0KepeCs)YMPp%W~n)9o?4))cUV3(OpQ>Z)EG5RO;D566g5rFP_xt=HBT*2 z)w?X88m305QEH4DrzWULYKoesW~f(%r-rE!YLptI#;FNvlA5BXsTpdP znxp2a1*&?FQu*sWEDtnxH1BDQcRUp=PN$YMxr4st;H`HB60AqtqBR zPEAmg)D$&M%}}${95qiZP}PSlpBkn{s8MQ+8mA_xNotCkre>&FYL1$x7N}|+%cq8^ z5o(kgqsFNTYLc3wrl}cfmYSpHsRgR~h~-nm)Ce_7jZx#&1T{%bQPb26HA~G=^V9-W zZ)EG5RO;D566g5rFP_xt=HBT*2)yFKK8m305QEH4DrzWULYKoesW~f&FYL1$x7N}|?%cq8^5o(kgqsFNTYLc3wrl}cfmYSpHsRgR~ zg5^`g)Ce_7jZx#&1T{%bQPb26HA~G=^V9-WZDRS&FYL1$x7O3hgmQM{+Bh)B0MvYSw)Fd@UO;a<}EHy{XQwvn}HOr@lsS#?F8l%Rk z32Ks>qNb@CYL=R#=BWj$+QRawVQPdLrN*dnYJ!@irl@IZhMJ}3sCjCEstPQh8m305 zQEH4DrzWULYKoesW~f1OYMh#&CaEcEnwp_zsX1z%TA-?}ET0;tMyOG0j2fpV zs7Y#ynxqNb@CYL=R#=BWj$+RpN+VQPdL zrN*dnYJ!@irl@IZhMJ}3sCjCEs(xbm)G#$djZ$OOI5j~{Qd874HABr(bJRSwKvh4p zd}^2)p+>1OYMh#&CaEcEnwp_zsX1z%TA-?5SUxpOjZmZ17&T5!P?OXYHBHS>v(y|l zPc2Z@uPmP$rbehyYK$7ECa6hjikhZos99=`nx_`1>Nl284O1i3C^bfnQxnuAHAPKR zGt?|KN6k|URP{T{r-rE!YLptI#;FNvlA5BXsTpdPnxp2a1*%fA@;5{cQzO(UHAan7 z6VxO%MNLyP)GRee%~K0h&FYL1$x7N{!7@~L5Jgc_yBsBvn7nxv+vX=;X=rRJ!4 zYJsZCSw1yPwO7N!CwgBWv)})j>bnc{7XHV2eZ1F9ud>%`_VsFcyM`Wb&39V=-b?>h z|3>ay5KH^M@^`jeS&_eEnff>OJMpsP|2jq;yY^MtR{vK2v)tMN89V#gey`)zu~qh= zZT|`{T|XVKj?cbqK5ZQ<+t@l-ra%8P^|QaL+*aC$jls69+kWx?U_v#$kqsx95n2%j9?;7bG*}H>ak9aDh07_Y)3w2%rWOlhH5BzceQ{|ro&{Fok zr(zyd_Wr11UastYM#a2B+53}Q{BtTWpv8$vff)n%C(e?bVrl40-G};q%F7 zfcp?<8ROLD>DPVa0f)av?sxb$a-YKw!;Oqy^$KHq({YAla_8QAQmh(Do;gV3Jeyp{ zrR~*Vv0q7^p?!;k#oqRo!!VF&`>qbZm%IBQhQihLsN z58-&`$IzhdSM(M?S!1o#_2iQd6~2moej^`pSTVl{H*{)0ZTks-nfAYsZ|+~rFT)M0 z+WwIN!fm^(CV$!CVcfu~?bnhY#5hNQ>;9QzzY=dsEhJy#@Nem-@eyMA3FGXBuA}{{ z+l9OR|5K;m+W!BE!)^cn*x|PS=N&$j<^D8K%H5Uqy0oG9c5xT&n;a?jHg7+ZcXoK# zZbxsT;qZEb{s-5U`sT@PJ|~ff-xB+?X}^K|5c;?M{1go3I&UM%W3+#Rdy}IyU~6fd7j+H(*p_A@zgp> z%C+_nllLayi++Y;xYqXL$y4O7kyjfeek||ZKo{}d`!Jpw z7>InTp<42-SfU%4*Ja?^KGdn$Ph0FVHII;6KVO4uKg%6I!*FA|w$JP#ezNrc2Kh$j z&BoaSyI5`ii^K0E4;>?U9!NjcvFp|LCp-LH@`Vonl>8_1cJvd&4f)znt7D7(KTn<@ zxAuFq5c_H52+zE3BY%wCZWr}1P-y?3IQ)9@&~Z|(&BGhyyE(jZSp0Nz_%QMT4xdXN zcldhpu?}zFQv6SJ_>JVV9KM-6Hg4EZDYTc+9@>)T<76M+7D9ldY`=E;Nm=- z+FI;8I{a5~?SG@=f81`u3l84`uFE}$er$W4(MI?QI=UyPmuod4zl_-e~_L$-9!*>LPpwIfhyD zT0p*r+}5iTeyIKY;_!#b!zW8T*1r2*V&B{0&ykOGc(1+1elj^en%AS`S%5;>vNBLky7s6tnYaTNjyzP3(vCPXUW%|CESiOA2H&%74FzqXH(A4>i?dA^Evsqf^|w#!Zqx9w8T;kI2u4!7G;I9Jj99(BINb1CyPjr>ybpV>bzgdfu%ri=YX+S~bd zQ>R=Te-nq>ICpWltyg1*566zr>wL&$#xriL#AEyOo8&i>+xG6Bua!UpqWYo)|BFto`sK#r|7|2V=s=UL^Jl>EDi@ z`Fo1T&ogKrzF6!pqJ8;M;%5dqhE4P8L%xpO?%yYo?|+H-vHWl3x08>fpAgzbkIz}g z6DDs8uJaI`DSqaY+i_+er+saI*xTW@f9~aQ+fTYW{8R+&)lcksq4X2dPq14zFFh>k zIP>Hy$qz8~YO1=?ztlphi&?KamkPn*zj-YoZ%dA8o_TdRTKu0(ZpV!~$UgoA;c$DNc|G|o+S~KYS6(jhSiYWqT3jLgL5vIfb=V2wf8~|J z?-i^bAV2>q;V+UmK>yMC-}h?awx1kLUSNNInfA6n_jdZB?a#d&Zu{*a4!8Zhr^Cmf zTz&i=b@-Vl{r!HP>Vr8GUN(N)&vWFqpQq`+Fa1lcm9qIC%RJaT+x&;F5lhS8V}2Hr zFXDV-pP`b^6DEj#4e~hoi0g#gc3DbZW1?`|F0D{s-7c%iZM{w)&(0Eicbqxe$(wDL zK@PX=a+JeuyTlw`eyVr=$1_HAzv`@6`uk|*vI{wulN zE>3asX7e9+xXtr0hud~J+2MA(ILYCos%V#%;5t7qGk!a6pGcmWE%9IO#DALO-^M?} z;Wqx^4nOBK?|yPU%U$Qh^ECO74*!zlQvAhd)KW+Tq`ke@@<(`EQTB>GrC1V{v_lkw@+l?vBHwoc!DNI@95{ zy+%6R_O~+}Zu{Hm4nJe0cl%z=ICo?GeORwY$w!f6`e$C7$e$wLi@eq8l83JyeiC`B zDUt_kKb!nGhrdlei5!Pl=GF8J@&AUyhmkkAN&H*;x#Xuh{7drt$uTW4ua?M4#7XL5P-i{mRJ9)P4c%H*;dnFuh+xJ|D+jcz1;gPew+wmgCIVdG@+VOBcd5*jj zooghbZGraDUO2^|Jl;RL9TQD*T*AKZ^bT zO2^OHjvrg!vm9>gJKEv5RZ(u5&H}CkV4enDru50Q9?sXhjRlN={es)sVIP0dW@}ukR<-ect(?o3>wzEx*(PP2= zYR7e7C(^z>*B{%gPB6To>ie1;F-@emUk%@JJ=jj?>OAbC+;vv%4c~FSRu^!;$NIPZ zjC~W;&57qs!*?wAQgEeq;L}Vfc>a9tGYC z<3OQF4U@40n76=r!t)E|xCWOq%&RMTZb)78xj*@6@SWf%d8^ouC4Z1S`;^!p&yM>c zcuRdAV{AQR*@yP+&ZnPKY8CMl!F8OepQ;;PLHmJYgeU7sxjT_xNM6`i?5_*R7eA4! zw`v=3C+!CyVC_G>XH7%wI5U$xzLWUJM`0UCkm0)QR;2-@FUXmE%#lh%WbIgpGbeOe)@phoG=t4qrr7N z*`uUgHt@@P$RoSeF~nY+b-nV##6z0=Yud*WQtmwV+utu0|I_l4=f1SR1QQjnJkJH!<>r0jrz!2rao}U> z`<;|4ySng#~U)#^yT&MHdP{lqj9#3uuH}$P1ey|5MuZO{Pz2dc` zUUvMiHBorvTIuHzcHB$Bb-!A^t#~`yV(jU(lI(H4cYV(U*M1hfRNO9)gX=iMjU}Gm z^tHYUKP@MTeYUpL>pKj&UHmj4KMdToBpr3k04)V?D?UR)VxvrC%V)yG{^7GCr_>rKek@8!F9Rmvf9S-EN&O~O%XqNy?g{h_h>R;i;>+J48^W#Fbi|0Wre>?w8hRPvoA|3~nr zW5K=rtOeKQPW!dE+#WZJpK!aH#)BQlCWCAHZkvny?OU|Z-zbrEV7U!$k#@{>m3Hh* zei*ok{}74ukL?lME6zd{eD7PuPu?$a+B~PoW6gzM;FE&u-{$SVOBMVma2;npDD7zb z)ivNc4&+BiXfF0P zp0mlb-%7oLv`>-8#!CCzJiKT9IP>-!W=S5B_e&nc8=PUHtK&&`koc=J5BHH5^aVS- z-ZTFzwGCY7GuB@Cx3r%=TX=f2`2T=;u6CE^JHFb1>vH4uireu@^5{*{&uxELL>^uw zl_EUIH#{Y{Zu6v{rxTI~yFWb(+$#?c8IJw$Wa%fz z`=x+A?qNKyOFZ3J?nrP`-y5Xe`;({0W8X_n#T)KF05|<}j@UP){dU?HvQn=K@*D0I z`@}NwFh3|?_~%Qx*m9krPNaT&utg~ z74$P?fw!M2;5rY<6QrLvW8Mbb=WRa@T-(Q+N{M~gKW`-uA20pc=5uuwezsUYvt>KI zlYYkEFYUF)nFnUUb^ap*B%jkbU)}2g#!#hddto>;ZihaJk*v}*2Ugd6}eRzp%N7WhU&Wps48YX^XtZ$2l zBoEmoVz~$TXv6vAN^(2xQxR#GOW3}VjQB~7mi%19-z)_;+r=JIuhYo`4|~Ty1YB?L zDd#-EEMt%3_g>Oot?1{TD*QYNuFFmE_^u`GH<3r3RHMELFBujB0A3KQptaF@))@G zpI#^9SYPs^u|b)E^B+J53!V&9GY2V>6%y_Cr!?( z!v2OT_+s!mh$rrhSFN9Bzj|KsFq-~P2G{i}^p*DNNPac#bL?-8$R8(<9wB+N+hbRp zSTK3sL;B$$+FwJSdO^4yS1X?N&O@gv_>th+evF5L*;(n=H1oew%d7CSnSRpOOFYu6m1_Jv{j;Bp zpr6CZGn^OM{C@!M)t~FUAbE4o^Na>J?KnlYcRP+fNuI7Pk=!W5z1sUlvCr=<-~+~U z&`ZJ}<^5=OKRXg!_vh3?$;?9L`BB=Zo#Tu5XrEbIJP!1HnR(!GrJc7tPafG*;tBgC zpkrR~&co&4y1t=t(*N!GrK!t>7xaz8c-e93G4jMc(k^|(y?U2C{gCi9dCgb7%k2)X z`$IS+{h=}KM}g~j()FcW3{&Ryh4F(pe-QtNuwJ{Y@b=#YT>Ck&hm0pz)6aDB+BD!i}zDY!F8PB zU&a43Z1PLYSlWI# zhCCgSdUd6rEVv#ge|FAq``+^IpPj&U9>&*@{vW2FBaA(c>qp5rWBp%Eo_$C7EcU}D zZ%dr12P6-B(9ZyHoj0{w>U#_Mqt>3+5n7VJMV@rdH#U5S`Q-7M&Cew8o%q|za+kIL zxw^p>{POX4#ZTDj4^7udKhHlU{d_mt_X79we_R#(a&X;V`E63Jjq~XDy#0&>*Y>H2 zlAoj5uZ~~qZGREC=?`a%{ba`Z7J06z^pm0FSG+IvieD=AI-Gnpxbbtc*xTdB>#^g| zJl$dkxxpx2fI_;wy>Kn@_?OU#saue4| zy>{aM=pAsc{BJWH{c4o-xBcj+!$%TNw>QLpd-6BIb-fCE%Jw^s4YOZfcxJ1#m+gmx z$@9)};(Op;@znlU{KN){|H+L1O!D04avaft{2B5n&sWH|N__+F<-gr0;y=1s_9H!6 zuZuqwo_pUc#?V@76E*In26Ozw^=;sh{ZJ&Nq{Nv~5 zHG%epsbYT}`75-~zQp>H*ZSPMUVB!-j|JD|hMe*6GV+u&4s^#3NZTv!Po*`LI)gmT z>-dK;|5L#Ael35#^v}Z>=XahMTGoa^6Zb*4e3H2_*%+M zt*>Ut6J_$nH1gQfwGFW2^AqGbXT3^#i};B(knwOJ{VxOeivNAurv{3>ohNiGuw8h( zX~&J*!Sy`hU1y%~7VT3tB>!Vr?$zITm%9X9w|nk{n#S@%ZeJa~6&~hwF&lqh%NghC z^uHWjw`11XUS@r#{p|Q!0+QF&tN3X``+7e~oP~19vu*b-;MzVpwwAH9=l>rA*ZuQJr+*f} zb-Rz>P39Xmp87wF|LBl9#*f|qjwX-sdh`Is^CY;=k79lfCHMa#e)6>>&rgyc3$Dv8 zIC;1e+$*1l|0;fB1I5qf+%8@O*M1Vtb(XKdbskc@zTcGPw*8I#Ey?GP91rgR*Zn85 zRQlV=w0{HKv^&?!+5KAc-@W793tan2|0?a0q@R1hb)4;AE#AIv!>U2A`o0CO{iGI4 zKezpG7oX4gS-!G(yE`7-#Q&1yC&(YHHumr_PWr9guAAUQlZn$gUXGI|w}~HnKIB7i zuQ+Q2G{=5wp7gh4Sl=YL&Rd?>ae9%zV(kY?fVSV(Eu){4grcK(T5~{`@FTQ46jrm-_EUqzXCo7{+Bq{RqJ6vpw4qHA^s1hp8I}+)4oSb zKgTr8ydEWwG?woC^)ztoXeATKY{^QPhjDF;iuxyVf@TZr6>o~*P zB|q)T<%>MH&Oz)hYTi{<(B|AMvOF5Hf*TfuezNnRrT zCrbMR>WH716My@<5|46@?=A$_}S6N_sUzdkkl*sn&e>#HnRjpO52s z^#iyrH|LzM7`?N1{FA_S-V#q1=j}moA(eu}+fTu@|G0A;SJ8lZcFx0$0@wcY_lY+< z4nJ)9qr$tfn6C`S@e9}W*?wEMp?CcI8IJwbSCSbU^I70J&diy@d(!_wjlBH~2A_jC zzjNj%Gpev(Q3c;n1#i$;+A;FA>^E(FhlA^O%zwcBHOGNx3@^^T{ ze?i7E`Cq9M$klr?U_8fh@-FhUb6mWdJm#!F{LcF4cqm&F`a=^bH_h_{cK_JEDLL2k z9L1^(2G{*T4Um@VPJS!xV_dgCoBVTdlb>%SKeM@g-PBC{$Ct@=YUk%CHy0l1D(!w9 zw~I+FguB<5KOoPxlI@76W7KiGN}OpvhsqwaTncXT?_5urOP;ST|Z*iP(~Grt-KuKkBLNc-`XT z&AY(8_U|jeO*{>Xx9j?yz3n4a@H4?p|EVwW_h+25$@4tU>cIA04zBxo_DJdHC(^#% zp3;9p>_4`@odd4@XFe4F57B-;xL3WF(Z2AG^ydui4~U4LSZne81o>s)I-jxTlD9PD zTnMiFe~9}{yWjbi_NrEKo_Fga{?pDnqKV*Man1wRc__@4JV>ur>S^m|sKjZncU;`n z+s~pZ_=n&+Zwco(x6NMK56)wJBm0HZBu(lWaGi&wbKa@J-r^@$knIS~XI?Y+5kJv+ z!tH$@YG3d1Z~(ZDC*s7DBF~>8{cs-r&)QGy3yp-gWP5!DuH(<8CH@aMo($_I_UVZ9 z6T5$$*xfsC_k-*FD_%!yLH{ekb)4bdCI2`aGq3Uc3lG&2K8E&t9Kbw$A?5DHc&31R z?HAIt4?QeB%C2YFWH_Bxk`7p)>(ze-gX=h>k4QXrzr2Dx!Sh%4cy_zBcjiSMdocd* zB!1fuPXpKf)6V|uV{-Miw0lp+y4S(7y}aqnGslAKewE6JXS*No8}+W&wcxtk!ZK<1 zJDLCA$W=e7??pUceM?V?Kf&Wc`4yf&18)2{>%f~HB0RE1;$O!21HEYfi?oZKcYO!0 z;}1LMLwfcW`?zy`XEC@}d#wi#;ck!bo%@2nv3@?4$nAN9QHM&o6P@#x_knx)Uj?q~ zn`>OWy)^41elnXR|8`z+2Dl#IDn?5$Ww%xLfP490ZaDVid&z!t9OtWn!@TWVSHTB> zn||e754wyz&+9T>*e-Ly^>!NP`L3?y@6kTy9MAp&uE&QM`-9!TNBT;+*{7u4o6*nF z;JSUgab1D!pErSzi=4yNfL^mwC~A_Vd@lb$#=f zNxK}&ay#}Hu8t5sh&*ZeUc%du-v@5WT_OW~2l7|QBhLAsPYxIR{A7t|AKLFZK=QMO z&l|V-DS&JLNv_{Z)4stGXeeY&Ca+tIYofP3}B6;<%B z>3@N9eK0yu;)#DOd6-ZCi^+4&I^KJa6#K{zG7i|htpL~Y7q%2{NA+UfaUKk=^OJYx zR}(G2K(-^hejs`j%RNiD9nY^Nk2&WFUjmmFXN4$Vf$M&oStEXaWWO3RNcvBh>#6$D z{vL2`A9+_=WB><(cfs}e@QpK`?{c(vefI&^_08oZ&vyQt0@r!l#&t@z|MWaYxN`0n zn*wh7m2tk`FkOSyJ`_kiWj^~9gS_4buKN3s`V9*#Ut@{s5CFFtNe z-3zYcQO)=&`J93NKWw#`s&yIE=#$^QwJ{cbsj&bslogy6Eq#u&;Ki*he3e{4A#biQry&SV#LrZ|R4d zMbzx!;wO8qwEH!jkF5dM{ms3O++c)k?}d%UQ3cO8G4@HG2>OXlrLa>eo4 z@-(>aCtIBDXansdpG!Wkp`Y=md)N0aa2-#ine-FeUPqiEJpWPg_%?~WFhTNpKIcXC zM|%732yXU+t&5Kzj{?`_#@k7pKX4p=n>;h3c)!r>OmF`Ofonh6b>e3r>pOxx$Mv_( z8RvF#^?_`UeQ4iml;raTC!eQ*YyV;AzS@=KG3UBoozY?+bNYGYEbsV_0oVT1-%Fl9 zVLbEB7M|n%fOgz?8{Dhk);~w=^H&$=?RaqAKSQTUeQkS9rhUS>PITe9Ecb5d4`aB! ztWS8CTjM;j4?iOQmookyM8(?c==uV&`f8 z^S$HQr3&5^T<1A-d8iXE*YM)4q3+C%K=p=e1T_ zKTe(>yudsDPr*%pbJjU@xlp#F@cQE8%JJZ)Ue5XU734{0oOybj*r%QI`J2cK&T}^I z8ZY*7jz1g@)vM&mhozs`{dS}NuXN2prte?f?*^$!jwx6#D*W-rb z_!(vX_r2IVZ$ql!6TtQSC;XVqTXv_P#o#8-Tz}Gm{2g$wdFGe2PaYxl?MeHUmx!O7 zbG-92dDwaGP`69HH0N3`ay5uuRKbISO%#*JW zj_R1#^R!Pp=V=>XE`Hqgr9;8>cA7g-&PU0prPSYOA9tQN6}Up|^UKBlX_kAH;S8>l zJP5AiFL0hCTcuL7lj0}ymGqod^s^q^)YrKWz4n!2A6_Zr;S!c{rQwwdI;79M_*he%m!-AL95R-tasCaGjsjnKJIpW8S{FR@ZCC*LHA|&l=)E zex+2W39=n!he-ci%b(V`j`q&}aWr}OD#^dyzE*>Kl^dQYelpHDxeeUQK6Je|ZwapB zkGsbO#vb#uS<<8M(Y%)8jo0?R)!6TtpWP-&p7VTeTbL#>aI>F%TJmP|e7g7-491P=L5UnDD}+`DIN!&0r&D#Yl_&%juLzMU#ULedLFxrv%i=OuJe|2j>~e! z&yM+Nb(8o{93-CY_I}X0vR*FpP4RwnD(z#tN&no+{!l$7ejwehSSx>Txe!|ZB+g)z=_H#J6j>kP7e9hP+ z&tFM9p2+sv=MJe?;R2~|EB2F-;3hx)rT;v^_#Y?F@_uc*u6_%7{4r@4J5O#iP5OVH z*PZRW=v;8GJls?Te+^v66W&YW|A6tlFN9#}f{93^oUlgc%61WOuGd@%uE)2+d>J=3^8lj;CN?^sp+>Tu@^N+QSn@EBL%TAb z+2Gnwg!9M!g7d|H>IbP; zfA+%@7YNS{k$h$t&+FvLMiQs(SKoqr#nbUV)^~rgzlHusf$O}v&tJWnJadWI+w=B) z?x#JE-eM2 z`mtjd3eQ|G+snSRzX9B9ev$_F%G>rTc%ujDpZ6Dcr~fFpm!FZ~djGY=xt_Ana9rXoH^CNKTUUJvT_kmNJW=XHeXe<--l zXWTj7Tm!DRm*h#Z{cfjyLv%>pE*ajxX6FxG!L@yw&#STH@F;MzojUhl=Zrm_R+8Yu z^fOv`NS4+htMQZ*$HWB8lej|k7cFULoXPb4b*{Y`Maz4UeN>)A^CJm(4axT)b&jI+LM1%ueW zbHKI#2(QofXPj>udw!@S+i4#=QpP>IeI15GdFA;Ea8utC#C~X*IP3F_@UZh7fLp+I zy+%6E|M`gaA?Li}%g>6R+;uXJ*?zT&+8L8X+Ag7&Rg1Lg(oITi84AV6(bJ~ zlxR~SBu$RewvK`s{)O$tpzm4k(?6`3> z_#Dhj!_laMM3|KF4lftH>kHezVhZ$!C)5E^Iz81^4RzFVQ~A{YW$BVZHUk z^?t+22fV8HQ%zKq&$oY!?Rzq~m;VdEb^MVRBm=k5&+S#%KW;e2lV?~{=Ck7p?H~J# zPh~sZhx?J~;Ku(5$#ZAUubQr8-kkeNE+J2Ll5y3pYkiA6mzT`j`-?}dqJQT)=`?V! z`Yr+2+i7@&^yhJ`?_R4V{_u;^Pwe{bGr`Sv&Hb;PhumxI`Qu9R8Mvu$J@I4Dw>SNp z^z$E_ett5znJ3>P`8=C>TR|RQCi#4TWi-i&{}|8v+3|BId5ZV3+Hq_axK|#Ytb%Va z9NRCC%Nnu08on;u#Wd%B#vb5$`~AYH*G0x2_qorLJWpW!fj6YSiM-^e3;7Umowow# zEq1^2H}bUeyol;=ihYXrqwPXJZOJ3f{{0hho#%L8DR&C(tGy+D5_}%%c=B_}^Bs%( z;d7QhD*e#r`Ac$lzBK1;$y?mHZ}(MjUEjF#+|KIn2#-4Fdrv3N&XRa=xNTnR!S()b zh_fGg=3U`Q=e*)>YrOlzG2o`(c9QM%bmn1(u}6Q{DE;tr4t!gy@YD1?@uPTM`&Rln zggnmukt0k zKX-rMJ3j-!^*9h>f0kaY)G6dy-e<9qF&*&%^Wcnc3&;z+9%1(vuYl`zY+okV@x%1< zHMrisZgaM;E+2~h8mC_k2G{k?vR~PG?0E7J*VWkbX)loHx=O#Y*KPM+Cw|gxWP7pu z%^$#Z9@1RrY|qDb`$+6lT<_P1@t+8;_nVox)QjCmJq)hvTg_QV`jg=y73On$4x*m} z^Q^D4p8Q;JUEkbu(%>y=KZ88N-DtHN>3O;`^n%sp6o{PvzYdu(>~AfoSU_p@ws;%o&wkH)$btjZ^yCk!EGHY zRZBJ7z<%ZI*W%#XPu^Kqe6!^%C6b|Z_MP#Ab!9w%V)tw9H%h%i&r9Aytk;R;%DJ93 z6^vH9F@v-k;LDtW-^MDyzR zmE<|{h>WQAyu?R_S8j26{~fr_vwBMW;Bel&Mt&{*VaS)V-F4$nGvH?a!223nk$(xU z{S`h!{_{nqw}+P_G-AzrUsKj>HSAGxEr-JknSczC$f%l50_@50sl#d#P?o*yaP)@w3(g5#CVe}O#1`KPT{ z2j!RTk^R&1%fa>bGQ@cf=bk>lX|IG&;%v(O?|J0WmnEJE$MXllb^pop{uCek^Vj5I z-iLJ@^IX?2_ED~Dvh&iz!M*Z49bEU@q<4z9aqL00j>FUF|6y=5 ze_JZ;ZjXPzHoUk_`cp$ZP+I%h#{0jbH0cL!`U%f_+x^$u;9l|nVEo`XsEcGzwqm7f z)sQ@&$UNJ6#lTIw@O;bOEO#Qfm;bxLbv!wa&tuqccdjLVlH;Y^!{}!ixVBGm{f`}o zZyoD8nx2?eBm zZ$8vx4 zAh=iip16zHM+QmYvskY^nn*lRK8Il>%N+==<4Ij4{mNb+uV^Yf!TZ9FrTr-KoU?xB z2J#S}!+8(wH;_l2{dFJQAnz6b@GAJ#;5wfvUYED?@Ylh0{IQc{J593OR?Ve-b5F{4 zZI82#2iNv_=eTb%xbAP^(`37_^Y#MmvsX$!AK-wyt%Y~|ZFUv^Y3F+DL~z~zvwn%k z-oLQSa0XpTHdMiXrvI$te+W*b>w1Nqb%u9$OW; z@?(YD>v)ko;;h50-=6l){Nyfh zuX2|ej#fQh>bsEj{T*Cyr+uCM;9(tDU*|rc@#Hbi&uu>$+>!Rqb<&}`d&hH`;b_MR zvVA2OPZr$d{}|bRzv1}#QYYyrdCqhC)4u*5Vjp(SCyxa;`}Jxe|O1 z`r!y?p7s*B83#C@wEgNEaI?SQ-wj{Dcv|l%{^K>JpV;H3OToR`WvbyA5Bo^FET*4L z*3YkUUSccv3v(mheqI2VEr<>%?;3lw(w7qXLi!1J@%D3!;d;B4{atNNe3yai`l@$% zUWGese^;q*c8c`p6>P7Ddr5mGPmrkAGoIhUb^FGh>o}+GE&iu{A^z=g#C&jV?_M`q zO&)cQAAbY)%5$%M#8288H-h_Wd(?Nf^use5=K63xn2)%`$6Eky&AtSd5F?~;2?=#@%{xnZ|`Gx zrNH_2Y-|6cjBFdYy*vbN`XSH%bfEn^v=8(CDSKVUcd(Qj`(3t+q1-O^BhRfb9{=YX zzGFNuRlz?5*YUX5{l`S5+(d6_uMIX%aBUyq-|@8P{~Pp_c1iN@klO9;C~)0R5+lXW zwd^O)8vBN7jr07gg0bH*{zivLxk=}~n9Io%U&%N#nLkbRV&2N7Cyysz2(IJL^SWe= zyc`Esx}WUojN37AWA9uye*;|CE7el+|1|v^d?@W3NV#^s&szS{aBzc^Z&4nldTy~M{pf~!a46WlJ;4)*FLnLL;F1E?HsmM<9^~N z&F9Y9vq^IplP^dkH{WpJ-@Z=k()A`P=*Cd1pTP z`5?*j5a;>8dmha^bNzs{4yL={UU5zX*ZYespAR6t6wietj~9yPAvKN>{}E^2`#rdq z|GLL|^Hx>x{SC+Qrt`d`bE~kwt_uEm75rCl-7eue(vF9){}hfB9$zQ(kXy-{4HoYH z{pi!kqt5-^XAkkN?=*0o=ah3@Z1(Zq_OF7Qc>?dhIE?Y^e1gPNSS)ec@uWMrwvWz~ z@$+2TFSPc~`12ikcu$#db*24*CrX?Xc|EQ%`T5``Z_YZ&eTVu{YLgwFGu8v#>^D!6 zIG>4#qtHp>NAbB^obIUu!Oi|?p7cO_9_9jT&%ZBh$MexAd(ZQ)0M~KmxxbKB#${Z~ z%ZrakDuzk9`MJgA9zY%+CEPx5XAZdbpKzX&^C7rCkJr~($I>n?_DSctVMl>`Z7-u} zuQ)#sGye;#uzwX?_p2D!z1a3@c8a(ExZ&8oc%6C{{incnz1-*6)IQbQPunW^vEVwM zk`dOONLF5A)W%+E$+kMZBRf422$-hPg#f?o-)^E1)8uY5K6a^5E^ zy-um`$#c#)eB|kpw=}QMHsQQ_0(t&AsjqF{U%+)fL(V$4&Syw{(>xDv^LaG5-X7B{ z#7~BK`wd*rGrRM6#O^oyj+A=koa5FMxb~CjFEwhzd}hIQJn6~8?L2e6v8Pcb37jeZ z3;er{efix|aIfv?9dPYGcc5(V7jk}b_$cv{cGihK0Iuy7pF6sY{%;;Fyx`oA^D(%t zm;0Qn^jY5VybG@VXCIMyei!<0a<=e1?=P^|=?*4WXUP2gMcQ8luKQ2e`MYwP$aBto zpzAr_@!Srs{VZ_SjcfteaVGyJ+gCr9+v;3zKl^}d`+~FG9aDwq9%&D>Q5kvzfUK|9_qBF{PN`c4}!`6)ajzL5T`I1Y@vNbI8nB|k^gel@tZkKQi*$DYqW>SEz}UcWnl_Or>O&hd4# zOT<3x{C$Um$Rm6%mOW2C2HdM%9;kPOa$F?cCUfG`h+g&Mqi8GHK3an>jSR+grAV{Axis^;Mz~b zxgI@@ei}RL7Cxt+)N>LKh8^>2e2sUz^a9uZ)p8jp(e2IaK5$*%zd7~YM0@u>zHZk_ z{E>sDU)?BfRGK`==jd{4Rn;d*xnbw}eiU4{yK;`F&Ik9}j%HXtZHoKnMq`ipNrjA8 z)i{sph6eKTa{;)?gR^}dHc{#odS3jD=l1dlxVF#mJ}+rCrP^LE_OVW4k7bSK^@8C{ zN+o$8T>A;<#X~!OcgQ5ke|6_R{ma2+WUJ%^Z|?;+@i@n=({2!+pI1EYHJB_s@q)Db z@pLyFT#vWQId8P>H5S|}Zxam1{O3{GqF1rLtHE{udE4nfHE#6wvu73jWN;l%g!f-G zXPj3Uj^l3UK8SmbAMD>d7U#eB6z_6R0oVO)q;s6L1YGAc$K%1CEcY|oFL$0p+w3N> zk2=qPxCmVPk2~|R)!=6Syhz&pENKSSJ0*VNd>)0p&*EJ22-i0*WjqVXQ~bj$ACNya zRs6)bKeF?pE#%qp(jV+R&3B8$6T4K#jgz>&915=UpXA@8iPHb|;JST3T zx9I7Te|vqf-mT(4nG^mo`^ja7^T(CsN!rIaj@dq60N43UJLe%+-R9lCpMvZ7)2E7u z^H|1^+a=DlbDeGpxUSbSr{DfWo*=j9AEI}7mpcty=OKTf%N*9{IIjYyaan7O zOZZ$aUt{R)vh##LvJd@|G`3mr;q#dO=f&T9!;kIl{1b4Jw;Cf~;(jAk9(raquXkag zf0)9(oZ-JO55S)RuI9^X|9pIXE#uJ;x3g5{%L(TTUdrXQKY!K*jE@=ed>C+&|FL6u z)as;ZYk}Lw>j8zsPFu+-4p8SsB zH4>jQB<=hcaN_gCH(6rSg3tXak4uTj^FqPz25#%u(^CHGo&E7|+g~K@+>-fxr1W}x0r=fQr)HGr^{cY}9zH7VpUwLGIO*3z zz-iv4jl4kD{#^Lb#(eIOaXjo7_V)AuC;ki>`ty)0S#Q*&S#Qjhe*FNrtzTCM;12}g zuPYq()jcf#`wIQ!FQvcYmk0}fwctZWUg$@4d1F8R4sgT1T#cK};~t9HtJqYI=x zS4jENvw7UL{(MdFka16HyK9(!RP0r~ULOXW=Cv7D^Ny4+*^T?VrS$h#*9spb&zrU% z-VwZ1&SAAYTz#FCH}=u{UeEOo&tkpw5uqQyfy&5MQ#_~$aG3qusrK| z{Vm{XUjK#-XKc6C&%XqpkaGmRzuw^{EHC` zkmyh59_~Smart4xU)KTLW-omcxNRPtuW-x@i4VC*`1U+->TgMs^||&hedcDyhkwX& zg6+BbIph}Mj}ZrW1#nxv_W@UW&xi-xy7mV6ZRh5pfkhm3K5K=5b_kC)zeRNiH$-ws^KTa+1~^}rQ^ zo9}t;dpD0u)VP-#5j<_Ir{%vBK7Wtp`B`cI0C1|;jDLPf@Uc@_&UcgYAHK)l{%YWA zTx7mzeYM5C+|G4Id{>piaXu)1kNt#x2XIA4&eOI3^XI^ADb{^9%V<@XQ3>w#0f zLy{L)+yhR3K=})#d{pwTFP8SdqRK-)-(Ws#fA8+&%>UB!Sg*p|Qa`5yr+O!hJo(S4 z@VetsM{@uBo-?$__cuKUyGzRO{S%ijHQposv*6BlTz-k}^Pib-j=cAw=^q4~+B0UnZ+i-GYR{1I-qUM} zjwYJ>y~kg;yy+Ke5Pb5tJnniN2Y}PMHZkH~moJg>6LQ|C^}O>a)1NTj2PqT0w3X%O z2pRXSALH_erFnjxB2DcVJT3c8y`J6(+%~@+mhvM~ujbp7Vftzkc5KX=(oi%jdB|ry00S9)^G`K1iOQ zL!|s4RC(yhdzk)-(*A9qVfv$z&-{O+d`j>kBkt%P;MC5E7M81CDPQ@ly*&p5CwYsC zKGFNE?*){9R^i~Y+~Yey=5au{NCRIPWo_f zBQEHEDL*Rr{&YJ(^&=WA`S~enXS0+K8T;AOfz!CuT*~qplk#t9 z{9?xSe6M@S&d(JA_*WDT`S~liNAGig0-V}u-dkyZnen0HSTE^wilhI=c*#XfN9&WT zfm8dNkLGr2J?Z@2-p*ZsQ@umRy~Se%FOm2Jy^eo;(oSbSa2l_L#(8DMD?BbGLp)MD ziGTiT;HqB9U#Iu!52*6ObkDE7UuF8u#yRglffJn)!#FWJ8kaZy@DboNznbNK-(1n#4+1AXJZ#u4JG?G*413@V!OipWCj_5d z%=&Xzp?};PT<^HZt(O1G74Bh}{CRHx{*KTYonZM{A>|jm$?Y`H+1CK4em!TL*Iy~+ zqlW#n&0EyY{GZPPCp|N2*a`i>XMY5#XwPkvJL+m(V(7;*L6{Fmu8 z%Y9p|SC0m+K2_hw+i8xkqQoJUR-v;=ggOdYLMpKkk1LI^zvY zN9)xcomq;{Z@uh~!*2sl^oNZ1K~4d#*0o)D93PRYekF89jChzgrTnDvj?BCdP`&Vr z8vCg%9lK8W-by zZLiH4FWrLWU;FEh6WlzP`6+N)zitOk`r%Bmd-Xi}FalR><>vrb<7LEqoFce+-{IF9 zH{NsEY)hsyV$hkj6}M+!v5WNi{=vYh-ex0S?uWohKBJ#u{_D7x>JJHjrE;#los|DC zaN_gCnQUL(AoxumV>-hR@ObSn^KQ<^h5or*Z&J#)D_s8J`L#9xe-t>$$*7$3>h)-+ zZMa{}MqJ!t;I?r&N#WQRNW8j!m-+F4^4o9A?H`ki3p{F$^L2%L8ZLjX1y1w#PQx!T z0i5_YCh;?$mhxL{C+#=#47UKcwf{^hKOyl98KE<#=@|a!e+JOmb9?UB$l*L*ZwZ|? z;3T&r@(xR>;HL;46@9Mp1)t#ZHO9HyD&V&E4+1CtylwF38le+Co7Z=pm;MVoa``6= zKfqUj+vu-VIQAED)|{`&0<#A$P^f+xaqP9gN&ag@&RI$w=PQCchcKQ0irqdYbV48U z>y0-AACmhlyh_5Ig+y(tUc=r<1GlyRd%FB5n7$t0+ca*(y>E>N$cVlpcF1lrUV8~X zX52?UP4J=5FrTjwJL+D+qsBWC{{~KSJ0kgK^g3IO2Y;#F;S*U;zAp7{`YGn8c^_mB za4KIad3s$be}v#^L$0>lmCKJB_VBDymWR^}`H29x@$(xBhkjei>)VfuK0F9GwSUZrS2;tK7owhDFG_jmODqZd$Y)Kv3mths`bUC44xHx2 z?MA=$+{50lFDe}K^dg?WO+x1i;M7j@{HXcUtUo7=c*V7XZ(-Q^F9BEmt>f_>68eYk z$@q}$%-(~svg_PfBA8Dt=ZEAU22He)pPT;iOjZ5B@QlWF6&>1r1aMOL6zL_8F zIN)mj9>(jn-Y*>SS>|)-dTwV_`8j0l~l z1ur%9*iJAEs9#kQ2dnk%5x|K~srZu@Nxhc{?ucH}@^**dBa*KyBjrCZo9VAJ@;TQ5 zS8}zK(mSlIy))>i9Qs;=>N_ z@QervUKQecM~(gXvB1?jCGqomeHj(Jw1mg2N$jp2UHiCPBzS0N9xr{4xjf9}o&A~e zGHK66z^R=f!|!xSnZ3V%2Cl|&Hq+PfB&U?y%U=$h=#Lru-~R-Z|Lhz)oj7o+H!61Z zZqoh}1uvES*kQpR7Ce0$OBBxn=%os#(`=mA^ax)10WMi5@^e9@y*)PrSMnqIw6*@P zuA=hr8yk6e`hipV@ynQRI|}_;T3`jrf5hfZOE!6e;f*`4DanDF3{aAF1H})`;RB_&nD;WaKfv zMewL$4@3{-^3gdgxBX(z+ydOz&X=To&AnV+=TYqVg1!9dz-j#o$-2y~b)3h5lU|(= zJ)qa$iZ9yfGz8!$11CDo@_yf5GRD7DIPQHL?|1w=fX+4t@%Wx3?*(W-%zVLzXKkw} zpDFZ@1y18WBJXt62!6GcA2a5As7Br^=ln0hhc@FCT<51vMQGfye*KVFw9{n%o-cTboU`k7|90RsAER3_AM}3q4OL#4 z;`z1Jd>Jo8FC8QJ@b_5%-zED0)CF9A@?_Rmnx9t#x6O;kq1TPR=V!rQWxN zPU#NJ|BT?_#XK&~lgyuQ%eXwGa4F>Z^?@Z^Z^(#4_$+W6-&O#pehsfH-$UCon=a*cmOR1j|GA9gY~YG-hJCw2$`6UXt?lX`O8F8w7trH=gD!s~ z%Y!_}<%FY5zvQFb{&~WSPaI;g>N?nlz&Ca4_(gkaG9(-$22nkhbEc-+JC!F;r_PMzs7)5z0I

g~TPl~^htwG1RU+{6`{@`iLx%{}{$J=rR<0Dt_Jk{|?!-5Zs zy{h%hF9mNl?(I4&?fm>g0Nw|j+8_N1%Zc{Sym2VwX=7bJ?l8tnjrrbrIOF5SdnMOt z{9*sP?EVjzFZnu;m$pxOfZOKd=?cgG_dJ$|^YzdjA^OCK<6Q)t`c-4(tvVmLjsDGw z4$jBF%JO-L(BJ+@wi7Ng_U}!=iM}Ix^mPd@^6RL#H(F#Z0i|AW@ul9Su6+f?JKInU< zcLBHYVIlzEG{Nnkh_lAic3=XyYX3KRzNe)%-lT;_{`E7hTWOuLGxcj^4+7J5l817KIB@ z&#xx}aA!5^w+jsYHW#?szleWW`xAzMQ~OI#;d*(L9p_S29{vR59gSCk+xYXbPNp+F z!TMb5jq`!4eqGIcSR!`aU4oZ5jO#e(4|Vallsv|klHMr0tDYffL_qo@Wc;2H{&phVju1m%LN(Yk^a}C5HXKT@RN}pTOgCfH2}Rh3E5a zr(U6B^!F0rwsF5-%9k4b{d}L$G482t)o-V>x5CLDU^z@m(+(57*@!d$7I5lsvtge+ zD&@zPGk*>dIv-!dyKBu%6WNe;aV3UnBbh9jE$&;Lfjk=DsR+b@wq`e&iD7 z=l;^)bAi*kHelp8cndhmTXPk+XHweVaV(cVa~rmQMg%_-IF+9~pZVD!`0K#cxEOxX zsxLD>Chsw6es%ySI-ys&oqv&bo+bF$*SJ0U{Q7fW;qqfAaQRE6-n7Ey%bs8BfKz)) zUFJ_%K6?c?@nO=i-#Wj__(JjbYW`mfoajs%aWa|Xq&<>Hw$$$UUzGQvT~w-g%LC+z4+| zKl4stI_7=4wC7xs-q4Tj5g+I%f{^f$-0-VM-E$iA` z!M8d|`12{|!11EzPX|upSSoor_LuVaDqQ~I`L*rI+|Fjn4^S$f%?D0&(v3`irHo4_ zaB5Fz2VSRUvG_Wdox=Et%y-S(r+^b5svh;P@4q{h=}*ciX#eVe1#iBQ2_t+_{T%r% z=1;TmU(3%r;A)=Acx@%+zi=AkV{>@je^B~$GH{zboGaxgjJyHQ2b4eX+uZ&MBmU$> z;MAVc7goe5)o-|4%|&lqvby$_zn^W ztNqE}0B-B=c>(xufK&UO%b4<)r2Vfc`Xx^D93I(OqKE(eJv;qfPPgM<48Xq}fUgU{ z9|TTvweBx|x%$QT?e)G4oXU^B&gIuhzZRT9<*|<&;C1I=38cFdIPqc3@awui5ZuU1 zIqQdPho58E;dQ`?PK|MotP8kpT-HhX^c>c!dR^H4Om6=|<9)^yaBBbXCjNEgGT>D2 zLn)TSuSC+D_%OZnBniT;QYKYX2(KdIDj zKRmB+*g4m-{Om4tK6(z*ape4+wJy?~0jGXVUdQtS*E-bC=09S5;xE!)p>wRl+QYI6aL@I?a_Mg2;ho8 zPw_aOBJDp*@Zs-sz4r zxeYj#cO))F$BS-uA@glS;w7~H+#NWzb5!2j(tKN`%7br`-%RuQ0^q8hMttBqLjO6* z>%N1ubB~`g{pelXz&iy00dN|}F}dHW%U`2#)LX{=eM!n+d=Zy#{ymSNo{uZmaeEx& z{n^U|kN#~7MM2x!*IaD3f1UwO{TjWFB|*!>c9(FyqsF=C8sIj0_@2Tsj@NR36Vm>h zgigm^tRK!4+_{wL-(k>?0bh%8eACdY7pn5G$HZQ`Oz14XjOgH;qL2AjC-}L*)qE5` z{}RE+f!o^uwv?ZgcuQH9oljrR?ObR0k-C8s{it!j?8{f!>0b(*%1?Zr=Zm&a{v~+x zEXH*_@IF7|^5#2S1A>o9JGEXq3pmNuLerlKoaDT;o+bYfnRlCwGCnTvFs>DS6;ik! zq}=Z~aB6>v+~;-Wqtk%Xc)eqc*S)}bL~=CfuTTEmj;{bt?KJcEeib&s;d zhklUr$Ni<6M}bp2Cr@TM3`u`?xRUW^<9zL(z={5(>@W0u{N*pXd{iz7E)zN*`4!`i z5$9YF+$L9t2jJfjI#FXEeHUjcLFEAjT-MA{6m%3ozMN==0@g2snF5;kviaNzKH(O`mIb~^Iz(vVdC zw&11WAJBHx{9C#FsJz>#+rJ7p$-|J5H|!Tue#AI0{+HlRInVTONxjeCX6N&!zp>-H zC>-n2vrI?Z2`2+r{5S3gT@Re*OS9-1Er(nF)=s}1IQ475@P~X^@H35bdG~g%ckE7X zkG3cOCb;u6)`TO{-#zYN`Xz=PH3*#A`D0@}x)wOCFCz)oZ$B0~AH0+CQRDn#U*N=t zky0+N{UP5K+{{z)1aPYNETi7iyO_?nZsB)aKDvnY`Bl=MLxJoTXA9rlaeI4? z2TtuDHsX_S1g`YY2}7ku(MRygkkByh`{y z0em;ebIl5#HKX#K??1%!hhAqr_J_^+gTDhOI-wnSz0>ioi9a%(G0Bq<5js}@r}8zo z`^WK*syy<$%Dzd<^NtVO`F0?1#Rnta_{4znw<#R;%DXnFOM5CGk$xS|?SD?j>k{D9 z&LQL8_hx_MdiUO4_I*;m61Yvz90gqQ$B2jD;m@Quc6Lf7zItzIPb+XL-~1%Yt(NoC zfm46S#E#PT)s?_WZYM8de!e6M=)k|&`PQaz=$VIDuCzY+J#aNHdvd+|NWapLGM*N_ zq1VR?1$VaNk<$9=w}OwzIxB7x=bp!yj`<$_M;^Dg^NR|HKeLqEd7bd*T;SBs@msmS z=Lmj}lplMX$5Fqp+AzW8OFz!@OWWaR11G)>U&rmQ6gu|-w~gbgLdVQ+@VO_XJ#v5N zNue_?_{f$_U&mL>dXnpn%6nnok@Bm7Q@@4`f9zjXc`4-iwfR%hukHN(iUKD&*+SMS zEhlTG{OA(qXS>ka{jc1fu{XJ$dOz3*T(!s8$DJ>DvymU~c16e2K>732Pus`0M&Z!6 zudqHjPtNt82Tt{t8t-&eKf~*6$gtCn15WyCtcgeM5~+9pXYKVKq;S|j64!dQlurph zEPkFn1wT80&V#@ef4(E@iZ7doSDJddh?&dJlb{cj5W z;{+d;^F-E8j&rlZrI6>>hbFn5=@On7+HW=iT&>G;FJ9-9Ip7tpcc_`=YD8!a0$1}Q z&huhi@FfVepm7}fJJbIkvD0o=xThiV=Ys+GOTdY5RonUfS3CWK>6cu~a=44o?*+aV z^Ymh4A2BNB9m&tE+quVUGQP&Ws$Rh-j67+76nsqXTWLS}p09H|#|?eh16;|^$NYR= z`UaODmG^-3xc>mS&3=0TIMFfVr4N5o=*xM8UN_GWyxE8^`aN(pzSr@1eL?uY&0CC5 ztYrKl!CwZh=21P*>#qu*JO0Ub#hBO?ERBwHJ#ZSYA$eaw+xeUSOXwKwc}?&!i9cs9 zInFl!=JKQR4p&&(lK^hx&*cI5g8}&8guZE4@Aw~(>`*D~Jqxbki0Pn9w5ANa4mU%LV){+F&~J)rILRlteQhZ^$sYeffk%Y!^3 zP162ng-%rR6lr^JyLW`o#yLng@KR4d^`9pJr~ZyqvYgb*2Y&!g^KMf7fm#lCbv9A$ zH}BJ}5PWD;E~)j{Pd~7UqI0@2f1d|Vd>As~kU#T5!HxL3&1Nw^(aaL1^}~&Vj~MpG zCYx-+>y8nhGY>e`8(PQw)b?{m@X{R_&j=rWqUdOD<$hlufIla6CLdus`^Z=J+f?c` z;tX#Ud}1E=OW!v)o@cS+TmhWqXUvFmo3%OfAuaFXX}i4>xEl8n z9`^&KotFWpabGL;lD5O&5IRE=hxutK-?|0U89S2c94z?H6~4W5ruZ4o6#Ql2#Q*fS zx#ho-^}2maZvPg>xxw@?&*CUou=JZ+p`_isi0&Hp(!0DlNL(QiJF+oSKT z#6HCMsFBbAbl^7n*8*n_`0Ku3mCs){BU=moS-jqDC-Zvshwb#w22Sl9HuUY_M;IS7 z_D#u;GG1c5dw9Lzj^yRm`uSPGL$dGC_Qoemczm17xpyy0_qP5R(=WZ8b?&;2z1}L|#JAEPv%dYb z$lI9UY2!Wa(QT!?`1f?ZPXecTF)DgY>%%>^<91H&$tC5vGUunjsr(~`-g^=_wZ}2; zo6Opt@o^*G=|8}gy=0t^eBl%J{;pOy=1Yi25Y1LU_X8)tL9?vyAsNRVcaZiN>qQDU z)jMJMi>?K(?7%0OzTPia@5trfGTw(h6Sx{jd1qGZ!zUCjjqv>1dM9qr$et`$$A|*D z2RP9wm3=pV>Nx*ZxQBrJS&0OIHaT1gocKS!8_)M6MIOclpZEn+zES9GwhNa}8}T!X zfKz+M<^BlIV#hgF;rZ?PxzH(njZ5Ay^)`Nz>5PhBMZa5mKXBszfZU7G`|*cAML7Iy zDV~oFQq{h@a``GFPhB5y>aQ8+^O;gEKVjTETLaw2xAOz=yMYt^5{W<5`;P5*v(t$H zr}mHioZBCk_8+UtL%*HFa&?d3pV*!04^1%Nw7#kp+3dn9=>6LDf`{5!ZuLF)JND#$l^XucZ9l_w%=4OK1s{Hp+kd^Z zXTe^=H(B35A^5StsXgX-^xcBj82Lr_-CN2V@k^%)J}mbExfhOerQj3B`SmvYaC;`U zX1!e@e2xk}{wKya6TaOJoZ2}q=bL&y-nXxPd_VYEE2IMo|9 z@{A<{=nMql_XwSk@y^#~`!oIKAF!O__(a9LsIm<<{zP{33AMyj~8R z+V8x=@^*&s`R|Gj?n6mF1Z}^4D#Yc@cZ$~nr};H%#AO}ga``dwceP0SGlG{G=c=az zx3%-vz=?iU3C~}x5C1B3%=e*g33I(ehQ0l>GNyB;?6b1#2yo&rJNuaW&4Yh7Hg{sPw<`Uvw=+eJ$RAKis%?2&rnuK`Z;{hHdzjuh;qQ^ZgDL?T~Zs*5DA705W9d~yVaGIyXmvhPEMW4)CX>b4j0r*1TG=C?> zU!?We*98xKm=W#gIp|P3{Z`;a$1&d1{Dt5n#{H4M3!dJA_46l0KOb@!(-}XU^#jZ; z^>er2roXZ7aN(Q0L!{T=V}aYo@g^zXEPQ5d={PT|^4PDPz#8&)8Q-@5VfxLo-_iV8 z2VBXs5QOOIeV*}{15W|Jd%97oP)dAL;QR0AjZANspL?&t(5U$TJP zsqLR91s|Ku^0{;~CY1UT)0r^x=f414jk{q#92evAR~z{)uLn-@HgYd>U`yf8HqA_@ z#>nG(Ja8NT&s8|qP063E*Q4i!j`_~l;<%m8SAbLdhb8_{kNY_qH}VR;sp!Ce5@)$$ zt~$=57Vht`;cx#5a7AD8Fl+jc1Gn|-A5uOldg(7Rj^S3OW4^C_GjP%mCmZ_VZQwNS z13UQ7RV&+s&K}JFtAzd_aHS^=d;4Zx-Z+0bCqd;)oaQyGhZhN*7Zi?r7KR?%w%y*} zBY{)B9d|G%_ZB+G2|jM@XRiZJ{A~UR&p2)0Znerz|3Ki1|AwFWzrd+p$LR0k4lX}t z_+1Z5+Ub7@xT0_Hr|c-EKW_Mc62M9RON@A=yHt7bQ`WW52p?VpPUHKsF}@Y6?d^#J zSNt^YbNv)JwKHwxL->>6&SuQdou%H&PA)%TtZTb<+3P(BIMEO7!*ZqVmahhsKUd0+ zkMX**TI$`To9Q^COh=FJ(ZH!+4;%RkUIuQPM_Z-r_FFmq@87H zJN*Q3;zP|1+^;W7`SS%2{f7B0$D+U(Q zK$*~gUCK8b_Y2c!E2;F#=V=9f!pL^ox-8#C4auQ zGyf!Xn%`!5(|JYq8W8%D7f7!!4T3kH!R6nS{+=_)v7=3pApGF)*$6~KZeUY z6TFV-efQnKX}+Io%=fL1W&92!ZfzxS;!nwcSl;x0kwt=^Wa#;Qj^p-}ewyX& zSfM{4_^2`N*8?Yco|JpXdOz|yaMBx5c|ScQbV`Sq{%{rZ{|1rsO}-}e%KEGAvCjdw z$yKeCZ|>uEYCrsnaG8Vyf2d&D(N+wSIn9@EVD$ z*Zkl5n|AthfKz|Ro@M!|5&9J$o0N1_^cDDe2FvE$a&cmdnFD>kNX>fZ(;b2KXVe(DK+9zn}E}NJV557Y$Kc>0VjDI&#<2C7CU+6$xLVB zqkjJUT<{X{D{6n&JAy}#_xtPSp2Bn{UuHTw9{vX4N}rs?e9+@Qa4NTF$T$!E8E|U< z1roQT^~^t{{G{UFDHDP={pja ztNDK!a3ycD@6&M$uLCFf95UoH@*R7Bdle3OSjj8ecV%BQ37qJMBu-V=`+7dl3~`o)5$Ut@miebZCG*Mbi<#(ls; zzi+SiXy7zonkCPMwyVzxD1W0WkNt~bXMXDpo<}Dc?;$<_ocK9r#Ety?2aKmrWPSU# z7&=G%ka0%>LskhNMuFS-cBjHYU-HDtF|D)nnfCGr2H@*}Q#*%^dt3id3+NG zS~%WmUOc?Lf1mp@aO&@fAy>DY%jF$od~Z3A>P7iaaeEp>p7;GR(OD~KwA}YOLg>E?+{T|x*D{?N!%p7p ze8wFkPQD(vjn3B<4nEw^8v7;9hYN&`@&4>-f{)0#)o#+xUjQe5hQvQ}y5MgJUSqt! z^Vy$p`I@6x&uBe)gu>;^o?j;dr}1qz@(A4+Q2zM+h_*+JN@1ww}U!jli`uL6*9E0nmzx!~#pBG--2b|=; z!-%sAU(Eb0eVONrj?e!Qa4J7(_-7shuJl7Gm+uq$&6hAX@aJnRCu}7;&WA4Ne(hl7zj_il z(I45|Z;#Es!cKnya8=&87kooN`B^{X@*#PTI3)dT1a518r!M~wp6_o;`5Q)=&V+Hl zY|Ed^cp3Y(GT_us^ZfKk!AFeq?)!n$d>qd3LiA-}T-z@gA3coc`xDZhp8_Yl@mymc z`izu!7IOK$MLv(b(%#?8fKxj|!_5Ba=!_fjkXHh?_3JmlNv^Il z^nU4A1%@ABKaNY(&xzMDf0~Va<9`57?H@Jr znttbc?(c{Ze|{Zs)n7CJ{|#JzoiR_B1E=z1yRu$QNLw!ePW^Hu&)&G;bvJT5Yoa`k zpA&oya4K)UM}Ho0qMw#LPI^6hM9PnK^0=Qaet>OmV*U>a|F!%#0VnxixCzVuIw^k& zaMgZ^$N0Xq=MIgV@pWTdesq8Cul56Pdo$z1;!o4=xd=nS>-x}g1L*W6{N^EPm5rz7`b9+dV(?`C=S<{bUt{$$g||ft`q!V;G`dFBu}iq*Yh>t)Seo7Z%*4wBT|0oB-RgS ziJsr}_fp=tmzM!<8{Z40d~|~4VJ~UVmJe`y9I@vs1wQ~dwI}o%+dukUs?i4-pETkt z{tTS@H7f6G;KWY-to{R+A3KosjJ_xJHgKgUFXn#zRLWO8B;}2Gp=E-P82h`mz-c{g zzKG}VJfZU}aK-1%cm{DTj`O)cGX3FOS)TRz$S;7~`1S`WU$Ym>$t<2`&i0Qmov6Hv zr04Z~;EE6b!}abZ@_C_@uX%;}f7S=Mp*#PH>4e0urT0_I1b2+{%140P+BxgbEa!JT z%Jz)5+y4%n#8t~YAr zyGRQ@u_w#3UN6p>ka3rD4d#;L+zDK@-{Ak)6ZZZ-2b{`}POzNld(Edl$@H7$-M0=| zXMZjD@WU*aTA#R2F`Y?~AHA<{)VPsvykFynANy6o9f>#7`eEC@vObR*=UiU`PV(O@ zc3@cAc?xjq*W|}pP7W4%xL(Q+)vzR-Ciw18GoAE<{(hYbT2H?j6SK}r3K=rzRmf)pw{(hCz`+}l_^I5qk)gbt;&)Vy)22S+Hgua&lHG&Tv zz%{-k6<0mS<;RWt?`HxhK0K`B_Qif42TpeTgkd*+?0KdWGURZZ7Z^A5x9s#H^S`Ep zTd4KGA;5|L{pLC@<(pf$e6R4~MJfMJqx`-valJ#vJ;yHtr+$qYasIbU`BHJv>T``3 z1urq|oLydKIs-=h)zQF7K1XD|`eE-IkCeV=Cq_zJ-t;u$yMF)&Yo~Z zTcS6f>~!6DUvDbb(%0Ue$kaD9#@tX(M?8~gi=}%r_5G1ZL!%pW=k)ZZGKpAsEY)&U zqP4fDe(_OmC?X$LwRi`WOr|3RVLmUYfW|c^v1h;>suDL5Z&3yo=kjph?-rNZtZl-`jb6<@y_Hi@!n*r zI~^(5BFXp#_VV z&YQb97VGJ2iPeKGXmKpfO^zk{6WzVDThnRO*VwzbDi%xP^JFjnxj0+}Vs(j@zEz78 z@zp&`;@$C87#hW()&!L(%T+gDb!Ko`VpS5H9jxt4#Jl^_zQW~M9uTu=80TWd>rq?G zQ?8-0w=x!M9T;$3H{25MNw&s75Z|b8ZR~a3R>(xGHxo}{>|1GYTO*O$a3s2@b=jiE zve*>kRTZsWyh28hx}pc6v3IaD;fAO!NgCZmL^IDm?uF@8_au62<6RiwXgq`8sHKM_ zZB8V)D$!lBB#!;!M%kT-V~-vS0Ee98WL;PhkfBtPrN^2<6rTTQFtyDWLLPnFWnaJO)O5ORxeLC z#alWPb;+J|XM8Zyk{twAWo~(EN1}B#R8?D|6QfPqD^I1rlgP|{(#+)vwl>z#f`st50#b&4D znO;_j|C_sCwkR>!l8R^A{?Brt(z|&5pXEY@UZt_btQQk3b1Ym?!}t{?7PktlzTGfO zdQzF*SZ6Agu8+2MHdM!AtGfGWMVu3hrP4j_oLD_plo+XxSQ39lBK=J<*f>q0Sd+Vc zD`531>&lfgQD(3@D+{a&8YQbWi{?}~)R~I6z4uFkn^ERXBBNBNw)Y~9y*b^f)Gbz2 zzj|GtzL)DtwZbY~uc_D8r|K$QwO3OVuHL3p)~5-Tx(S|XTDS$43B4W-aI2SgtI=NB zkw|pTPi5AqC1ZVL*-LO9_6zGvv2tlQL}Ph6XLK!CF$1#|9R-=X)SB){eGpeAMegv|j=ciF)dUsJ`>?po|9a;$4uWYKOCqzhy*AaAPIbe8>`^-h>giQaE_PpMm=u;mo1n#Kbh!kv)7J&CGFajyTa#7v!2R$WO;&en zO(Hty(8CU2zlm?-OmKCLeVO)nYoY<3LG03L+n={+Ou?N(R)<%vjeZtdrlzQIX5-Pg zFoyr>*21soR;QDR*2J1*Pl8>nnZ8!?G1^tY3^repxrZwUb(zn@7%preJX;9h=)d7=tG&j*p3DXli+`skFGeWwCkq73&fYt<`LEi)|SVJ$y};uI3tCK@E08 zXtC5Cfjc|bVzj?DhW1v)#CeSUE9^G%Q=unK_3vIovEd46=$tHPg?Yt{vt=(~9p-|& zl=pI!r)roCa(+KI?if#}nHXYwGtCh$_V~aJLw?o44{0U%T-c#f3CRtIaE?R!Gv#QB zO^axYjO{SiY0Cr)VS;4~U?r_rQ*QCnIz_>Ah%^mp zS?{{(D7W}}-Ad>Zal58^a5kFij%Ml2Kr_c?s~Pu2g@5_*+&tQw|rQ1zcAoF45VEC^d^AOL2SkZB2veggPK1 z`+T5?3d%y*F85<`%PlrdDHzXLYk}4e%NYx8f5OEc7$Hi@)&-w+vaE3)jB&G9Mf35fF^Jsqhqxkr?k zlFuTma|85O_VW!tBr|N7QmkRDNZGx{47F-8Q%>of91|BGHb2?Pqgwnn4OYl|RkdZ% z{hTbaZ8WPEC%fNM`L046qMh;geIquS%Bf9eT17bD%f$g6mG^p)T;DB9G1HW$!g|%m z8-vZ99Q;3aCjo&9 z_1GcNb%`1FIm=DYO(DAfqirhwo5@G5HdQfZZ5b)hY=lfOyDZTvs)Jc(6xga!U<30b z&sYrV*nDfpX2{X^gdc&z@xO=}aKzGfN1cx(lgn%~iS|LB=t_!f;t(iASJ9y7&X#TA ze#Z7S9PWkR11A7vtU{mSsvLq-zraoDg5_XG3|PfP@TA2kx`Bpu?v)6t56T1B%y zI==RG)GOSc!O4RZCc(@2fP9HSk z`cZ`XMLiQ)mS-7u-r*wq4bY7$qd^UX3h-rn}=9cSQYhCg5;^j@q3lNHx&GFsrd1DY_$QM2g4+>~i876BD{dL3 zqENM|=&Jn6ieKQ+M2kNHTaL0m>?yF>f;9x@*Ed$hltv4wOKYqMkp!Y6-qS&!(WT?W z(MUxTLkbo3Z{)d=91(EiHX<(Hv-$FKJeexMZ5`P*^-)(rCFzD)gHLq=QkY1HiKyc) zc*yWmaJM1F3;U!CQjm3L3Xk%;Kw_${NPJdT_J9*xd!IZ{8 zO^f6dVZrZaAfeS#_sSyc8O!l+K~@?R@_NmOrM$uM9-JcYmHpsUYV*%-WX(z^vKN~y z3%6+`1==mx?8Vk3yD2G!x@}E*sgUMym8v3VQ6dAQyAN@eI!llW&2H*|N!g}?FO8sc zrRn?^l)RoJTPJ*#ZO}UjzM3}BjRapE8|6NNx5nz8j?@}8cw|djmM7b?>av3qZa%s? zt5zGD7R9fK1?SBAHqzt*ll?23<&f-!{?j)!o2DO|FLxD@?e@6riBYd@gq7 z^lmgS#FtTN_Nn{8h5YDc>69nK2d_|5e4m`D(A_!Fp9zh;Sv~_Ie(ClSkX>d)IZ`b8 zmoa8dzgkRW(XqNhT(`apc?o&d@%TTc7u_GO@O)eQEK(Vj573{V$!ZgL>qc%u8}vJYv^9p17tw#IO?dG31ty=s>nZ%FgWTcvd3pwV_}`|8I$b6 z`iwiL0)Goz$v&=ziK|Gx7w=w$IEth2vk|)K`fDYw#`uomp@&6q473rNkd5ZqSY4*j z9XQ%M6C0o1)yN^kd1E47U2+&PhtuD5a7s>n*skqx8iNfj>uxC9ED9veouab@Iv!bif$m0(9}1i6GG~kz8Ju7 zgEZp>yfxtvGR&ax8N>LevM3eu3N1|#o4#kDr)-5)o5C)_y@rMYCB_XM^)I>QS= z#k15U!Cn~eY=7UhC|rgXsjV#DI8Y9N0(@G8+c0*KEAx?+0bk*rLByPDfTnf2)GehKl}PIWlLgF8W*5*-dfLUv=jg z`@EtlRInfy{XOiVRmfw}Uo58xz@ooZ$=PRmrt!sUNVJwTGTBJnJSQ=BVY7Y7S6BWV z@QP<4$)_0>jVB??85}yQ7c~lLLwNr^<;izI;t`?Sb<_Wv$D35t_guQv7U@I|7$mJI zu1c2zKGj!yldW?zt?KK=w7CM`&wj7CuCfe!!hvO9KYc31XI!CdTVERLggno`F#UF@ z0g$P+K5bFAx5!70VVHjHSx=Q`=<@|1&ty1myh4+l;+PtqfNYI^8eWHwj^u!->UeRYjUtF~ZRJ;Q3i2zkmgs!Y#ElP7BXZfu z^dgB?A;`5U*$W3LC{4E|^e)b!Gy2wHMSm-pw{2iw8{IqBJSd)}l@zB>?=2Ar`CXPA zCxt%U0V?cu4jiMYsAgM^yEjFSo1ZPjf$0t&@<6qFtW)46ZxTI#%bdsC^^du5(+?#5%VGe6Dh?f~?O{9C(8Ej=sye+1mLW;HGVgmL)A;jV#{U{eh z@&Y{cq~5Hf16ZUEOM(;la#_r+PGmAj5}NF8PvQUQi8{K{;HqFev{|~O=p&OTLZ`FG zo=fM?Z;Uj>n&!@196|T$4r`dZq`uZsY_ass4YlKrLXS!g zby55|<+_n~yCS%~0?{GL`W3A@M2H6|K>t2cZ3yc^p5jxS_4}eT>Ritk{ZAIUwk^aQ zW%x&;E~NvIO-Z;esHI-NwAUj{)2h+7tDY*0PoAqGsAhkJ7@lOH9Ac?8$aNcOq3>|y zlD>pj>3IW#W@s!;6FjRFbg=?Ytzkk>=c%=DY>KDW^3$9e53Vgx3W8FkXi>p~m6h=0 z;29{WAbD4g(#{~gb}uq9DGj68M3*27xc0RuNKjY43Ud?Pq=)dzTyICP0#squK23@1 z&$tansj6537&@;h7AdEOD#sCQq3I2e^33|9V8Z_Eq?K*So;2ku44Oz&37bAur>Hef z#UF`iCaI@Sa_ggt0#RP4aP@*jFQ0)dPV^(?PamSu@$jckiW*G@imZ44-NRmm`kuLD zHsdQZnlIj|9#HKx9zDp$2H^>hEC;enXLWX|Q*Lgh80L1aN@bG09bK*qZXom@9`l|a z9ti);%X@vMO`cn&K|>uD2mBPnmW?1<41uCf`@;U+3N%PRN<-UHX%&l8;UKFlWfgg+ zRW9OFu{Nqj9{Kp=Y4wN>rbqE1J$i$%2+M)3L{;Xcnz*PoZg{q@F!NG65;^Kx|#?QgR zJVl^YS3QiS5Li(e!_}{#aiJU3bLd&T2u0D<)GSzBKd<)CLt|yL%V&q(>9tr>ZJ zF)%nNf&ocQUBt7@T*2^QDy&*%s%Gz_$H3 zQ1_oBbChjLl(HH-YtDGA9(o)kTb=QCwOc;l;|2}amA7T$Yo=)e7Jj|0;+Pa3F2gHw zXdb-=LYqK5pwM1FRSE?yga+HPJjDi!ykTXz(dP#-L;N5nE~d5NNf8)PE**jS#+fj+ zuYeCXf0dsWX=Gsz#j2^Sf~5&zavDUlmb?j4e~gG)#(eCG0C|EzWdqjG(LD4qlx7{DdzMk#YRyEc@Hq>Z2W)|6vGd z0;&UPe$+_-awg;4AXDD~Vcgbmqq}2pk26+u|E`jmrmotdN8|aZ3vK3r<-vvR!poHE%yE4M4{O33pX8Nh7`JU5ZV zS&H|6+0tUX!N{${E>=azMBCM;MLu!e5$Oni;u-|8zbnVO+>uGGiKY5_aUdmLxAv}H zxO9*4b!K)LXIA)%i#49V(wSNXSByF^Lup@OYOQU4`{JzJ5H?iNL^o|3n9)jaQ#>D! zidzl|fe0ir%i#6t>xqyZVx>#wsK*@EM^oyxD4k9Pj!zuH(Fn|gUT?!&YHH&!lS7`Y zn^ik-gMIClsL$hTZ|qg?earJ>N(O@ZWINl+nifqR-7Z|PtN_+`PUuaLn!34pyR-$q zJG^z_(nJ;4EARGjC6u$r=zmfl0^OFDxdNLG4^tNXRwY&A*Liu)`Rvp1L2NaS-Tp6R zj3rjg%nRZT=a>fdP@}D_p(Uw4I)o#& z4CgG?zoHM%X~){oIA0&0gM{z!T=}iMC!%fzd9UG^p!f^C{D<%>Mp)6dR zN)IYyLS1~F+uNH-wqWHz>TI?lps>^iIZogS2f&^b&RoE`MRI=ge1kFTbuk`3r+gY@)#Q8-wr<<aNmdiBu%|3rd3J4F*K=i--(7*;nt(n(M4f^SzRP1*sE`DIbQ<}#-ed_$q~Du-Hl ziL>dWDIE}&_vqx5yc?=Ej2@S$D__&x>Fw^!RQL&f_MXeFGCRkEk%9G!q07dOsqhxv50ra0|r8`gdXEZ=@K<+LTT| zOLonSpZOzE@~uGGpcZ$Ia`hs1yer;~>wt(F_jzvvyuZH1G!m)cFRLRGTCcVHIM#yj ze#%OPU}c&?Wg(-s7(GADTPtv@|7$M~TP<5_I zZ$*95jp*szkq`wVx#2a5_-X`dbSChxTn%}r$ULlKPeUmiVNm%e$;3@|S1K2%H|sPz z$Z6+?n-EPYCAYZLLZLVone;BTUJ4 zd?Mh%LtH$cnVq3@D!Wx_WH_Quow>uSlb|Tcf;U49$)j<`@gjnT_;``7E~*g7e)DKi z?@0Zfot~#NyFZ=YAbK{DQv|P0c`Zs}SEqLqO1a7C#F#W^)|u^+B9*ltGo0oGl~FEl z>Q6vS{l;*FP1*f?cUW~RpZh1;czrWGu+_NJ(cOz{Bki#CQ)Cj=BhI~>q5<-q9q~q( zvDgdHhic;az4Ce93ZHV-aXTPeos~K=FipX;>Cd9v5JK zewBb35FD~;(<@nC`R9=_EyHs>uNTovhAWyDiC}`|mY0<1P$gRcO|GXSEoGbYy+(^( zwBF;?M!2oK-)PsVgK}5V8Vp%-L%A@qNVG90CjPE_^|O6ZHqJ}*E@bM}z@td?8Rq-h zp2_WWi|X1GI&$iRK~a+aGaHKpOk_tIbY3Qd6*Fjp%>z#RT(&Y!VEFdx9hR!ibt(lfr&a$#c zaA1n%wnFJq+~S7KrkszB4fb%#@-p*L8fx|t3ya~ zJ8>vQd*W#JK9TLfb2)d;=vDx%h3BSQ$A^XK7#DE|hUYFEim)nN%Nb_d9XZvEHBl0a*tSZI92=y>ySV z3|>|-$|x?SCDk^FJsal);!oAZ%ffdZr%WI)^(vsRM0zs_kmaMD^Ogm{o#87?L6dUo zBUzg*rxzJZ162rx+Cutwu-eSA$yZUfWxk{pI5blYoWe%VJ3Gp*p_c9$R-6?%j= zi0=WB{~P7GNXn!X&@QWm3d=pno3NfES5VNgfJ&A(e*!FMJX_~!Sp(`jzAMV%sy#1?2T*E)7dgb3O&yvqEzgK+V`!FH=TI!@@G#6 z>l=ggyBY}#=S%@9gIlgIt%HvvmQASdNoS0&-EBRU%P6Z-^&NI4D{Y<8{w{A^)9h-J zpvK;^*ov@Q&PlU$cpJ@RpBsTQHQ+?wCqy!kVcaq1Qw={A#TXU3wp^~%;&xiwf=se4 zXVH`?7b%6b(>!T<-S_w*@IRWCRcTI;y-oR7>VjTbEGV@%ISYO z+bmnx^;?L7;-JHGC=PlFlJw%NKHY>|L>V0v9c;fekU>+6Q<6;Ft-#(h8qeUoBhkrW z-Rg4E^g{30;^B=iTQjyb)SCpMej%y%hwh0fKbVpj?rN&D`a z6&N61Th*n5z824=1Gy!J2p0TM=arJP?BLX8V!EoQ`r$pRFKV&#X{xNT1jhhnHp<36 zrCN^CiI3drou~TN@JK(UXi%3=R>S?m>5a0)C9n!bRDa1Qu{1-c_R0?CbnyI4g^Ekj z&buTWZ^}nv6FaZpO}UL=C>8533bG4lFdel{v@~@ZK4mlQ4tJlN>cr<8aVd7)}@Ng&x;+LX4n8XAQ$M$OMY0L`?M^mx${Y2r&FVSt;y?3J2|I`!3bHqBuIb>mTdb($j-ZbyN zCj@BmR6?AM7|QL^B}Bt=Wt*n>`othsW)ez$vi`EUlMVK=%!WfsOps`U%r7;5I@XU* z(Q_xExnATcZpu~`3lD^2N5xxHEy-94>}K?M=x5Tc&aVn&cShL~zuw7r8+z{r!ma@N1*v&<+_j*R zZme5kIfKx@Fq-S4*L4GiNXjd}Dw$azEnSMt2GG(D%Ad(P*r`qlC=R3aPs?cU%~y_t zO%DGB4%h8d(ag1p&Q4t0u=qXI9p^U6sG)+wA`paufSFU2k0^hA(??x?W=_+Z-3X_Q zhFp5x&(_=Lp0k`>dcZkrC`+IUrYL^XLRMjZ+!c8YBT2YE{kHvJxSAq+{evzJ-&<4bMl(b`=;#q9D&(b1&Dx^5bjQ{9}(UyLdK zenY=rkkcUk5HQy`N5%+NA{{ldq^AFK%N$cTC28H`yO6f^v-ooyt-Xj{c@8aOmrr&~yGmT_ z=4C8yn1%^+$;o_(5{Z3m(=eI7C6W7ZMo@vwZ-v4y7@Pwgx0vQM)Njr`$HK<>U;4p zODlV^0@v=T9!|)nbDHLC_iLUhElW!{AH~Gb!iCe6Zr|M_IZv6oA)ZoF#iQ`705n<7=`J(@4|o;zpy&7fP4H zeCISXJKWj`w%3&BE`b&p?$FT*0-}48^xmTuNSU`eNoaW~qA3*-7Y^G#R^y*EF%eqzc z5@Op1suub;6w~u#s~SunhIQ9IovExIM=Qfs?yerae^-x~U_Nk9ESwD5Sotz-zI3qnE1x$wEB6fW85AYk&N`8HaVJQs;W3mLtL*0;I`)U8}NRnb}ina$?clJ1TF|@N1^1fCpN(mUgP2_v#_fhHC6;Jpj zVstuPUQavrcG?=`T%5FZr~k;s$$vw~!e>X$McAzPa~b|q4E9}*rUbf+$s0s39Torf z+Z4|3DHmg_zuP!?r%bG#OnJB@V`S6I%6b)LWg;Udo5wCp5-b;|vez$_5L>(>RMcaM zQ5tzQDmf3Tno_xt2l1x3l`!B}bt9Br-5I4vO5~|Zt03AN3Mo0$vu?i_2T4ReaEVr^EId^NP`<;Yro%zQs``{kgqJ#-ByPl46^pH z#~!Gp(D*-{ro>t*jN24+H;ALd)V+f#rvS~K^?v~(-{qrY1?k0_BHw<{&Yqx%QMVil zSf3(OV3F#nZG1d$P-wf=p38gc3js##M0PDRrkVBDv6ev|4DU^wnI6c>GO$uTbJM1@!m>pw ztAHqqT+U;3H*201GT<$)qK)87D7-PUITDB|*$~!g9P}C)gR1m28>_0(4w#i&*+vq;Fyc9g-f`6@NU^z;^wYc`g{E+5ls zpY0x1F79PMLXW~>>>DU;FFhonhC0HpU#LxFK(1exTwU@garTZ+-g^U0^|T7nNjP;| z9fwvdYHOm0OQ9=s`vbf(kWsHkG{V8v+7U^%c^j~>MVIwH}sppkV;TQ1qv+d$}>4gq^yswE+j5FRKQ8}XML8#ngBr~10#;njI z;@twS$IH6ps}0^8mGj<+nx1#68H%Z82s`k4?8UN2nuE$=;dz8La9;|8TAt}KZ-!HL z&S~5X&%J^R50-_!uHi}c?lbc}pjk`O5_hOnO`!xrw(yCm*F@GToP)intmrs(q*h|l z_gpYom>{1|V8CUe8)=3&Wxa2uy^rlbi=HFpl=DE?Gy;}gm53gXXTmLXOrFs;)BaA+ ze~@poZVcxEv_BcXR^NTlMG5|fawE;}>&7mdvOd7^LQASwVa?>uhW2wU!WolwwwGgZ zhZ(3hd-+bIfG1H4t3Z4ymn3b%$+@ ztJe#^XFKdJQ#rBChv5_!{FIFtv!kL z6mFWCM}6jpVxL7|U03y(A8>_tA>Py2o5HC=8}9~GrZBZ(z`>bedXtKRrkE;E8&m*+4ajCOYO7O;f#S8Qt+ne^yy z_K;Y=N=UMni)AKH7=oGSHrCeH&oF|Hgf3s30bS3C=3pH&Wv4ASuZnxHC?GY6aY!Gi z4Sc5@$_}5G>FeoWW!Hh9?36H^$^Ntk2yI*jA91{U6(Td~N+CAtGn?WR<2a+78yo;1 zu;ffV4q4A50_J3DaMna57{jYDS$~uLCBi~$NuEkCb~Rb?|JeK5?zE9*>+_3dA%Wk% zJ&uhhoHz;BICEz17cC63O@e_7*oo)YKf9{BrS4X>B(U>x&b?WgHL;CBYIWDku3fwK z3(VRD`+BtWBLe;;GD8r-deRjkzFQD|(bTOe@%4!iMq>*q>_g4j2jrhaL9}aR;?bL) z^d1*u6g`Sm4I5f@f9SluS+dR}3B*6e&RVlsm0b#R*zd=oQZiuh+_Bq#=Tn zw^_xr*&4jNx(+;Lz4oHF?Xw*Gu$r_Q((zW<6v~wbHZ)D`_?hK;io|@IkDfPFuHMhk zk<%#LxYAGAGA)Shw(b!~EXoXeo30wd$kE3I%Y8)al-RX3f~Uy|f<0-DCHW61D}rKV zDu0La{kXJ(=X+{0C|d)u>`)u?Xf+UijEyWk=b*vX3qwcU0Kg2(B7AayLeD%eJzcyY zALZaDy^o8_{B|o{{hwCRbq_XQ(u0e=M(+WHv)<>MdtPI(lEQE8-sZ)@3*qfDu_dMI z#ivc~3~iA@g0x_JySDB@C;FvDkDo<0EOoWM)xTFK!~{mDoXu*Ie}3Hv*>-jhk31fXyuUlK8<`_5s>j*Gh`Qr zrlOqFX3y&87Fbvc`EQoX&DNuuadr@KtvkkG4fWUhjpx>0Te#sKO`PA+2^-jom%<%8 z5Cr*tW}kM&0Wv&5tyo2MQxnoJW%Jp>_^_2g3+v?_jYO3aLads~AjEpMMDq9Czom3! zuj=0~XM7q912OwkQ!XUT8~EjRJewy6(pEvFL&n69PvmdJ z%a*jLr2O*9cz#C@>i)sHh7KlOjTg_^^7djdk*L;ih?R5fwaY=|9AkJ9V6AO@Z6(P- z+bZiPJQW>xl!RxB%ru~g*oAc&_RdgYf%x79@CV|ZdKX(47kDvI(piI)o39B9K~v+E zW?RCj9bfxF2yN`BsZXfv`zO7>+jTE;DB3!@T4|*CI6~LVWsaupDf6=Z5O*8+U2C-qx>2$Crg2RRf!f0W^m@5kT%7|$Pt zLKp$n>K|D}0h=}%8)8G>qUMOx)oT9Cpih5DHk1mP&9~iAN=>X4Ddo#y*2k=gv z(+1op?wfh^M5(kPX5*7iWQNWQyO+5&q_R}ROCl{tFs7bzqOcfVQssrm=p!w~e1vHy zWADrF(!LeLR6MQ2U$OtswAAax?uJ7h0c^B~=*MrqueK&x%c7m+ts#>2YEIQ`buQG$;P14~>9pjtXQ<5fG_Vh4A=O?tEGMWe}$JSN0W_zc! z$($ewUoP&h$0q-7I+bpHux|F~uI<$B$=5%_4HCo{DbKmN2<-(!mWb^Mzl$Anb;lE` z=3WDVot|!10QY51VVuuSO;b3>2-uPyVh+Ba5ft|@MvpT9IhVCU8+K1x13Pn6MjSxJ0)#UtF51O^8b0nZ^BR0 z6l=gIPHO}|RCU*Tm?S6vmZQo0ktOkye+bJVagUsvzMG-R@=lwhLmaF-;8^_re*|Kku!n)%Jgj?u~FqZ46 z=yC-|1NkepFCS6T^+xOR9et$O@M?6G!R&pEX=AoDY5-3B46;UBEHzY4a^9#9)f&K_IA9v-x329 zsMqfGqDEemlz+8<%|?n9ofbNY>JwS+d-v%K9=dH30NJ)Uhh zgUcIe7v4bh0RP7y62OsP>_1$+lTLeO*dCq|iC%ERN`v+Q8*Dz_-pVsmV;+ewGy)XO z9vDw@N$;6|Smby%Rzw@nUA|=*#LDo!cg&Jx5XPU)R#OxxkWsI}Fy>4+eNcCG9htKz zx(u+a9HR#K1BaegxLIO4H;PTD`-&DAn*Hb@W$a%$)V?OwA%RlsiKuLsKBYvaPYRHC zaGGWl3jRBpjn7;Jm=+_EjfWWRF()mD9_5+18<;IjkMxJaJT9ogJCuI99<-2LD6i9A z$al}mO<)6qaF~r&Xy|=JrJHo?p~7_e;UvrM7LPm?GtDk>TlNs8eIyJxA!Y&&Z}$Qr zYkBducEEc=d7!cE!0QyPu&NOGN6LCdbD;2f*Z~Cli2k zW8xlEx~<5tU){i#qH%F(%c>S(=mlfIO5f3=u%Pp}nElUVZl-r8#VPc%B+}yOS^X0T znSx?65NwH^S>Z|sa0)of$54erf<^Di5*_S;@RL6F`Fj(xWb(QE8zeDIWG^j%!LQx) zKVBE{$&Rabynx;TT-)E3MdMAMNW167<>`kHWc17Y^TWaIe7snkT&CHGAP`E^%L2H& z;-Arq2NfimE06N%;4>*2urLY!HO80PU0=P!_wAF=@BDLl-z92pqVuDt@p?91Y;nn* z?D#7hq|NigS7FQL5nSx#3pbmr$V292JO4@LoWTKRap&{oVePBMLh@L^F!2+Uz}BVjG2#X>Ewmy6t$3gl0$goP3ci@* z+t^Sa1;3O7Pp7Kl{KWw65-TZ(Gf6H;D3OA{^t?BvQ9)uD%&|((>EUuMbWo}smJwp} z;ZQ!*-59QYElOL!Y%B3~zwaGP%~-YM9M_U60;aws!bPSKc?gx^eKz!}5F8^s3Zfz_ z2{eDM=Aqmbj36*OrSO~qlqHM9bB=RucEyjd1M+eHFKU5W%Vk9Zm>SFXS~>@M^y3=9 zs@%beiBr&MD3*jQ#7C$Z{(k8uIB5cNU|0-L3_~~R0xD{2`JG^ukoXf@1O2C18MJ1O zmgH>*pkghybZWE*7i_PSqH8JM3!?4xpn{N)LjBn?=nJ3@DCsPd5!@tyW=9F7k`qwM zx(5bFd0c_uyv*i#UQDc=n_$>Hp~9-LEW@g9#{V+4N8(jdOFiaE7?A#Kpw>1`KNHkjc?1U$e9xzB$jC6+Wy%4z6yI zci}JXp+DT+cL3)&n`DS!@kWuhD+z-8S_IPKxQR`SAGKd+B3=<0Q8Vh#8HJ}f?ieyw zUpKEQh=g{mBLkYq0Pky>Fs5QU1wcaLB zGidTAS+^5>V77#PVtNF#w47_Lc&;B1yC^Zf|G=xEOWpZ#nby&%)YgekrwnRA<%+Vn z3a)TH;I!$Q;58U>IzWmIKN+{sp~rFu2+3L76&I94fkfrrLhN+3D?Xr|~Y3mb%nhtl2J_Tke6O{qSziBL|KK@@rxSMuPB@OMm<&#rFgDkVJqEA=E?JYNi zeOZldd@V#vU3E9Di{V;<1Z_f8?UyMM#f#-eEyPgbP3FHBPs4^M)|17Vrpm(f$0N^^ z0xL$OhzAc6--0V1v)gR&Cs+Y%`euTvGZjGY*5f%31vucEGSAB~Rb>K!J$OZms@il}LZ_pmF*@7k< zIbDrc6ZRsJn+fB0f z1mhB8o#TF!Rp#1_@Qwf9k?fqAF%?j(X0t--Xs_8fW3V9 z4k#1_*d@;*l#hO`@VmLJvWFx9cgg&oqX}d-DcXMq@rIyje~O_wSYq40di@9j(ndOi zY&(68zo(M*%NhE*C19t@>J!9Y5}q({0OYtOhnT*`T*xivj?C8JpM!G({xSWblNv2U zyQ~F{Ah;Sx3r1aVeNp`%n!1bPXg%qIn3-uCWmSu>mW08DU=A<@Zz&7GuqWI5HTuwc zpTV>WL|1-Gh$Enfel0w@Bx8ZvBj2QB#Z127@`qHtv>L{+9`^C`B)G>i6!tpp?IL#l z2>yt`UCUAI4YQ9UOuh&fsDt(b#2fa^yek_O3iN1A9&M@Wz~%*PcsTp^=JEEHLWo$%)4ZLE(h6wd)*EUk%5Pq7GiEZ>4Ep|)CY9@M5K}H$p2f|p zg)`z`SZWnmRW($8v6UT!^mn4fkQ~jS^8#uhH+k^9$CyR(%+?W#*hEBm1p!aJSD+cx z2}akK?3>zvt+?=8{2?>1<{M#qssqx6IS1v7M6ta8lHGz_P;&a2re`c&wLy;(kOkV% zscTu-pu&G9ISHUYltNHnR7mQAZz_XldGnu983{{1Sf8SbG+^SU&qSp?wRf+u`kd146g^KVlR#pUhHz56U5v@q7#|q0Q`OHV3KORxDg3zmfJ`J7eH8 zKRNY??jNDVER3r(=8_HC4#J}2tQp8%a++dFw#E{Uq)hGPGx@GLUL1b-UC3EwNTxZ5 zMiZ#`2hExlPV~|(HdH$eRO|#1E#MQ3Yh)*0i7t-bEa%hj*~_Lq1~uaMLjc0vX2ap6 zn(}+-7xSHvP?!fArdctC6b3A(SVib}`t4rM=$Ok~?5&F&n=w3Hr z^i>I-?Inpxv4^AO8TtXJUVT`tRn%(~CGbT4uYcdD7exB^p$iuDc?uc#;Q_uJf&#LB z{JjC7LFxLJHh&uAgE%f!bNW?xR#0Acvo&p7@j-dWA2#{6a`=_=*$m|9Q(*R~j=G6K zdloV=uQ$(&Nq;zbc<_ocze!J&Jh(CoH2$@n<5Z3HJ{ciFm%DU$PUh71X<>{I_((Y1 zq9PbdA&1Tv3_IX=W58T<3Cr~|K)GYz z6k(mrpL_K=`7aea>0DMqOf&4t$K%T|GYQcw%fq(5@nlo#JrGuvt)}C_(7=dJ08X)q z`%oFuqCr#Rjm=L;v!$+B2^AOo8J%W9^B8tDDUo8D0uOCGBEA@n(iqZuNFNj(fbak} z!8lc4yU&58p6d@_Ge=so4biJ?$+i)Q)5z1_h}mBj3ycJiHD0KR=^N!yo`mm9dJ&vT z4c?U!Ykt!FX_%LSSz@!(Rjv9_@7{L~oZy*$=0McBiA2c1m%7*iOcg}KDISD^*#{cV0Ak4olHQtEb!Mh<`nA{T`?rc0?E`X4IhLtXiFJOx2HPO&{_gDZGje z@`OsqJ_Y4yYJ9Ynsv2XcF6M3U){fGSc(BKRhl4##c%huc;F6BskJq5YZQ^<`9K<-2 z33!kQQw0#jkab~;e);j74S89+D)SOj01>f$&MaTmnG;pr8We4`GF=6SsT&DR|If2P zwe!_+FEP9x@=KYArYdaB`%bnx+ThXDtDr^l%#Cx1G46rf>8fn9(awYD1c4s`JQU=R zSlRC6_x1SZVmW!-p!uPL6LYqFK(FpJKG&;7@E!6qjO)_Vz~=W87@?$@nJrhP(5Ot0 z*luK~(P&(M$7io1fj{Qa*C0&I-l0d7LI1>7u+W+U$ZM&^sLSW3BudA%?U0~Q-)gD} z|2IHf52TCK05oAnG zBbIrj&6i2^;W*_KU?Ovx3kF%fUpd_-u;S&L`0R40IY$c+2qR&thjV{ z+6CQd=kI3Abm#XYVjQ*aA^vC(YSyWrsMEE>95^}j=gnD$t+o?fl1f4w;q7>S%g2zd z9~|CGh8{v-eVpArqTK?u49o&r=i&6S#%tdn`*NcjapRI3ayQs~J2+9K?=ymVmVbT^S4v;H9k38q(v zY$}e~HnpH8T8s-thDj}jT@L@*(^YGksGGuCQp>bgzs2|D-xk$LKGN53Ws2&`*FY00*%18K^|C+1mN=AaZRW@wiLwlI zW=f{g!;oPag$;5*X(0{1c%QHDKuB;0p_a*26RSxN&VL}Y={g`}S7F=Eq)q2z49CT} zl!zbHLokGB>=2LmB`Qn9cwYnyD8otTJH&Unt;sfEX2;oJ@w7yN47BlsE$J8x{`p=l zDkKh(vdXILUpzfQ%9n{>#$70zCk$CnK(v(v&d+T{68cb1vekp`vL5v1jQ-!nXHfXw z&FH5+e24x6CBXa}F$DQzPrLWTm;n**joX5q^?SW^3o01n2Sf&ZLmO=Fl5JW8gi=Q% zQ68)&-ob{yLATU5GH4W%Xr@+eDyZpfLfj_{FqMr96~jK%5V6=tdp@JZd{*tfy9r4XolZYLZp=A6gRfuV z*>L^4&bN3UPulLL2whhE%|HrV|8zX8vI#i8ILqgA?ii!iG5P{3Dh3EGM>)_6>=jr4 zhw#p9kwUEj1mNAF!v#<_tgRUIh+xD*wxXcM6b$9{`+^$wl2xTEZZUidbFhTe z2z?HyH1i&D(B*QuVhVU+BC2~}ul`ZvL_v#5vkY-P+DL^t1O8*SAxOR{6J|4Dqy3a) zCd_rABLg#Lha-`CJknuOF(#fgc+ip#V~!eZAc!~*D`v9|h8Hwu3a_T|Ybcw6#QT;Q zys<;?VQt5RYrQJiX3trzEU_IzWQ%;S75X45_b2&aK`hwL#)4|K%)udJA$%KTWmqai zIL1C~p5bI3ipS%Q5|8{@r>pt%UVWSUeSW3D z8UJiXEF*h2cIttDa&Dl-Hnk|9CkNL*wlyGrx9j@_7;Rcs77MT~2|!t+z{FZcnMQUnH572$=NzaJ_|sA;4s$>$=|PQ8vZb12LEJ|8I9`M0vVz(Qm0x&?|1+FufQq=q z;uv$=8_QH?>-#2Ynx%@Fm!!kftL~PIn&DLrD0S>k7->pUXw!P(xasO+RKJ{-%B5Gz zu@l>t0j0u+@v03F{(=dl(j;`KO&cw==ivI#`2<66tUw%e?J)K-!klU&%AuUp*zgZ; zDq?^(zg&9ZKjTHKjS(bwYJ)wmFaX%`nSt}nIQ%~aMlZDF%k zGN$p_xTOyB8M;DKi{P>n+_4|iVlkHuXA8S;!J&o9Y%vs3VZ*6=#^vC;VHA_u(IeG8 zPkIzeuZcS%{HQ5$@tF(&BnSFG+dOmBhR^=|^YqOiOMdIpIdR-+C%Z(VDKjmLa4?wP zyUPyjsgqH|d2R$uHt?!~E$DTMyft}aw-{**4@n8-2mFBQ!!+2~4E$?8e%)gnKVLTc zdTFXKM3@2sL!x`NdX+VVlC&oSv5>QW`LyDhzvu#4&BxE8`a~C4360~!K&qYD&38x? z3R1n=58G?6U&U3XlYfpU%bVHgk8^75YQU&3XDNhbDBpjCmKaY-=8?|IJvDhMze-l; zQ+(^2lJz~$Z^w^wV}wZ&^%Pxh=nvwwK)D!C^fKu@pohi)OQg1CVGe`vneO%j2J!~? zg3u=hk0-P~q3wH;(XdD7XtpfBN)e1_7Zo&Tm%jfP{JnmKbe@{$Lkx6%rwpQ%QXzk-2(wYRNc#@A?k$jp=ma|ZG?orFFB$}b1}gV z>-ZD65o}RWbb32BvNBXqqPo+!Z%LB0eT=q?kNUAyEWN`8CbmWYOWIc7=@C%sjJIbY zb#`CL(KN^8$@y}dt@GOnMrZ-7bf(_-pRQ=OT%3S<4d+4LkxvPcHD!JtPd)hSGGE-` z7)ieyQNx{vxNdsI1r>M-Di6aki&EWku@G$v*N${h=6sxH1Wl5C^yKR3>md8;_q#G? z0vFb$&KzMgQ*}s&rl;rS_ym(9YWB*vd2N)CCCuXd0ZRwV1QElUjDuG1s@iBR11d0{ zn(1^`uyVqzcP3Fgi(ZVsB?R-2@%$0u{M=(`f!7mT2TKNYP1>C*y&@;$4Hd{UOquXY zX(D|g@e$cgmtrq20 z*)NgLcOh3Nc3k&q>P zWjcHRYKmPcf9Zh<6Y^wub}sr`va_l%bOH+Z|2*cK?I+0AAnq{I{9%K^aL7-}X*rN_ z^ax(rP8{Pg7RjWjL)213{9M#VC1u_=vPpMK4P1cJ^ji3M<{w`jY5r{m{x+NgoLIY~y~C<0c9DMD z8q@(yGs34@uqd>BoeB72TM!BIuhgz%21zlq#MELBN^i$bn(it&{-4M37RES3GaGu5 z$KPff*mB{tBpr;SMGbI)f+JB^!0*5*AF|(V-b1`!eGiML;VQxs$JWIM=#IVJ@*yQf z9w)Pw{`h~*rU0H2Vq>9zHAfSaSRipvsv}A!kMsG(8q|SDs8W@a+-*t(p?nGcg_u($ z0*7o}g3Vz|c0ZumvKi=9Fd!3pn24=z77vCSqD=v#3jtkFv<~kCMUyqOmtcmb+#yEC zQtm%FD9{W6B}~EGf205h*w9I^Vt3LJR2c3SB$F(F2JS7vX~kq$uMkj zf#8uvm1(|WZ~MHWoD}6|(mYBe?}6ls5rU9fYR1>@i(SdA6qSwC3W2Yfj~dQr*qKs# zplBtmhWw-${1zZtk%FO)(BEs0rg7bYcMI)J1OK6tE;O+s1B~fM&>@o!O^C}@B${WE za?ZHhPgnZZNB?VNx{~BB*Mo}-34qGYAP*KM%E@-d(EfWHKk;THLSb&T?!uy!ND5q z)ncT0a)^=Qvng7C|np-Xo3EF~V$UzBaPf4yq=(9C-8Uyg9s7!<~8 znoS9uvf$nrMq)%>Ab5OS=LOTv9Qe@t?T3oapuRcd_SksI{1E$um6JZLB(p=9CMiL{ zw5sG}^eW{RTX}ciTbeWwDazv}$EctQ&?8XIClq`P(0GCPBV$aNhdQ9S^Y_ca8fMAQv7$O5tA<)F_o_?^5Am|t{(`Gx|(ijPbfaKTsZ8!opB`#5z z-0x9E7PCIfLY>LRd;?p5wS{)|yf@n{4|^k_RJyR{q{B&E?K!WB(z|MbEIVHETu@B* zo^fQF?pPml6FE(}yXm|#fv^x_NP0LK4(?IbK?q!tAvG4i;Nzw0blkfGFYdqbY1F+^ zz#uC->+KiF+m&1Vh?X;`Fy%b4({{W-TgLu8n0(O+B0YnD2b3J?tj&Gw5n?6 zkLgIGMbdp-i#;ET&G4=-!X%T(C8?Y2@I&E(Q_1B2c(cjZPtX%TGR+I`#|xB@${9ex z1|t^@wa+`uD&D*we-o_NskRBSV3@;fuY9vfkaT0vN$s{*NcidZ?a>S<$tW5V?y>ht z|K&V-kkhz!VNYMKAK6x}E_CI*(4*~IZLE>LqANnHO#_ah_gxd?n*{Aqz=_q>h$DWG zAxRHf6+Ib$y9ZwN)a!7`k2v|N?u7wjD5(@Yj!qgObcmZJx}k_6G^fdNX1ytLc;inU z!y52#;TQi;fV6kFUSdM#m;5;sWhRtCj6{>5z0eP3Hj3!=4ryZ-TB8dHzzjxs1z8@g z^(Z;$FQ%1FS}o{gwAoYx(LV7|CjAi%v0Za@)tl{ukL)_Rg1Pgcyu!Ml{bU@p#*$V6 z&>q1$941AeEVpb|TQto6`*%weO;T`@^EKqiNu>T{wwhSDa`E^8xOAOo_n5PX=2VVz zPV9F@>NKABkV&XaJZs5-=X}G5U;Pme{kY)Z3n##P55#fVN#}NkgXgxk9D=H{eH2xt zPKH6=sNI9dl-YQuV-e?RPH$AiJBlKl_jBt(y1sF->l$Hq>|F}oFAVUa+ zQk;z4Wz&$rkPl7$ygb=t-i0xWW_L>-{eZ?=(qZ7=Bi)*k>T`T$`b*Kb%Ezij+DIw- zSy7Q6@$&Zf7JU!?u$R5CnJ@zKB*%il!h!`A9Prb;ATcw9eP;ZP&*0NRl-xtNY)*v)TJT*jdNAcsPM(&tX~sn(CK@H2g-&ONlr*zC0^JN1DAkc`p(Gx*&9t>M>z*Go0nbE$ z%-1ksfpi7J>W?NUG>DtB^=Eqo8iL}6UE2sGn(8u}ZS6+9e(9tGOVFRA*BXNk%tUUR zhWO=OAFzUj_dpyHOOoWS4bTh#om+nYb)V;RFn_;7RINll0?U;ivXzo4T4f&0lM>tq zR*AGLu$2>L??diQQfcR>?$7Qy!*sDENfCB2Vh%C;Tz8jbuFJ-FP)EsC2|XlzlF!h>x#6a&)m#EVh`=EU~%h#3tb_%XG2 z(iarDanCY~fLPrWNEJX+k}j4DvaKYpfX#}`7V7JG|3z^U!X2VRTa~R*#4Ppz|CE_r z#a#r)!v*_m!rd1!hWL^An?qrHCME%glP#nOLzF(4-?Zuc{1H?#JIvhu2Xi+l5 z*F~^r=i0PtQ1{8eb{$1ltxzjl-{>TaN3b_=eYE4fj^cegN6CO|Lj!7QNi9&$!suQW zwE`m$8pAQWc*dn!mnW=;1xlc2+BZ2aR6@%N+K&{40#KP2r!2QB_JXx?*jv?b*y`ltk8!}SoO0R^#Udf(VrSOOHi+IL#6%X$_Jo?p@uYo{z<_ej6L@?9l6 z5YMw1`vZsRJPK>Jtg+JJsl<7&YI~|^!_TT*7#~zk>37`XDBSBkwS1&GZ5epM*agIg zf**#G;`{9DY??11)CO6~pmiuo@SyYn4)I~x^aGuZ87651^q63upew^h2|;X9D2q}1 znv@sXDtQGQA0xzPla!+5rDT6}3pH%dXm#%_jPCCkzCzxZHr=EPn8wuuETI$9IU)h%Lh6NU%I{>7Ot0U8z)$L)5r zOmN8TK8IwJdzQ2@)_fRjz7vpvipG6nlN9=db9_bSwY^3mjTj#g8ReP>?7Wr$Ang$4 zc+hGX2^K9TaCJ#s#wN`YkY)gS-%2SY2oZvZXcw?r<9c=IBgl^HF^|K?MNx?V;D%6$ z_DF!^Q3N<7?2&tdH|4pmg<1-qT6LXqbfvJxXR_lQlOveJMKe<6^vi z&Wb*}_Sx)H^!)oBn^thoYTdjF5=SR%jUM{h1B7I#J&U%Pk=WLSR^3vRKSeHjA6~%3 z_2$_c+AUP_DeP)pjFqHNs9$X62zXcyp6kAf!Q81TC`3aWr_>#-7MV!_JQgJ7U1MeK zb{wWbaHMNawCB=`ApnQaH%9~t-hk<{Y|+A(cBi73B0HmO+%s7BzLy-h%9_e=98fw$ zaQBz+-3+IHDpQK-qAHo2iSqp68?c9#P+W=gi1$_;<%^gGfm+BFYEu-NYO$Hz^+B4u z50V++R>uTe5xt~8yyci#Y@#*q-vJLa=jj)ku2TV^_wIswhiT#cPjm7T49AZ?X7ZN; zf^B*TTQyxiU``j&xk?Jbc6=AJc0SCC9i(7mZrQa@Y-fIrlrM!Nv}b6`B6Q?Lg-BXf zPL=cByn6*MU@d}uHtv3DYe54eSku=MfKR0Rq$Yy07c78cTWVm3T+qgnQ+9usl2OAAy4H=W zZ8E#K$}pMNu1s8&K~P<}a=l|=&uEn+3{em`rW}2Zs#Mam4d4&l0WLXV*)%Xih>vC) zObB@o#UOr(5j!7%phImqPff|h47E>$Md%La5~#YMF-r-Hqs<-zUz zaRYI(FcHOJ_s&|PVcxvk8q5CoJ4pT6Qw9cVA2zB6x2O8Gpt-01FQ5ZNVVi2>OB7P+nQcH|T8t2PL zAK`0YnhpI`?yD#)G@y>5fx?m%=8t&Wa2)oHl?PnQl05e13(C>m-pUuBmL`QAbnGlc z$tPnwDBb2~U1k!}pcb6Q3jkM;-|fsc5LSB5mbVwwKh82YNw455BL}(52SfY>T{fgG z-(-dPRk6U?&rgz6I?as`6nB(xGQtS*RlXr{`m}=#olD}YC4d`{=y*OTXP?^HZ>!T# z_-D{S1Msp1vFYG^IY$;OmrTNLLD4=X<)@Mz?6LnSH)s{HC@1Nc>mOD9mU|dtU8Ed> z$A;T;4cjj1>?tp$j|1N5(FOFsrZuA=>e|f{VyAJT0>0^6nXwgCz@D2Q09)5vlqy@V zY#{r0jd(QBiz2(iv<*-c5rg!a%`2}T^3;*k!&Ex1eeW|YYuEra9B9SY*a>CcG;<3L zcrN7yNt4Ezw*D_d14{{bh3L+ZI{Lxng2Efwc44n^OIq{AIrcG$Q6PP_z9MBVk9d=w zlfF&&VUg_0td5pJdcuE8&(Ea%L6vAVtd7+;{JjR?!*tJVXOq+Qgga=YqN0NPX<}F+ zK7Hiq0Z$U-i8lulJRBMnI3)GPh(T~}8D80_N(1Q}lWt#D6MS`FNgSy$ zh}9&LJQ>)+u_XJpvSP;&j?-=Hkulj0Uh2h z>0t91kP*h3*mUX*T&{F`aizmH51$mQnYiKcX4zaimZt~HGp?APQL75O#|pw{XAk+q zWQ7B8|HV9uEd9+$$W_1n-E*mwFizSTGW0jQN2p|QskY9hJ7<_@5fnd`<*Y1!osagesGRKB$F>UU@-{zet5Nn0+MMM&>oe? z)=coEkQFdY53^UqV_^ zE}|`4lEgirM82y6aq;cXsIg<$08q-e0aCY9HO~5?op> z6ocY*cSKpA!%purQPMp=^yZO=sH6wY!=P^#|Y zg8gX%TE2!Rt4lK{-~$Qj7NnQ5J%sw7(e#DkD0Fvf+k?&DHF`+vy;=%yc(J!2-;U0& z8^gW6#xHGcWSR}R`$QH)C>}5&<^*$Dd+A2x!^eicCj75+($uW0x0q1@wVWkfMPby}J`ojVC z+272V)O11b+{Dl9>TPG-}1p?<5d`&q6fYAB7_XiHn{piX%5A^$os$|}6@RtxVMWc!nwactzQvVnpi zH-$3A-E4#CfJ?PS-&CbGM%kQK3E=h8u6?JIqQwro((1K~aGyy8Q>_5ByMC^+x-qD! zhP7h@(+J%yIb{BlJ#JvSMR6|Q3wLSqdns}*>7#3C;3!V$ZAE5AQpDZU(soQSyVsiy zy5s!f)V%g@r#+*lc>M*H?6-(`zK++q2&6C9;401mdc+@@&udRRq^%?H&Tza&K>_tNPO(+No*zbf))u7I05Nw- z0L`n3B3aG~+tDK(oi>q`%&s5p2|`I2JWcZ$X;I2HQ< zkhVd=xh?5Vsff%epB6-y3C&pMip%vmU*@+)$+&Fu;~4}NUNMTEBwILG zAju`j#Y|4HFNtiJR1F4_0}$~EFgt~U0RayEVU1EAX6qe3NwLR>A4C(imRh#4&?VS# zX@|t|jIPCoN?w5f7kp?6dIL*S^mz(x3!onPIbJ2^q0(6Ul3}#7T}n5XvC>VeP;rDY z%I~${p0Jd&J!4t9Gp;_rV8NMd zz(@hB%@ zjs2;NTwap|^-5Bc|~ z@Lu*Nx6~#N3I#7=Wz!AufkxfikcX&)m(jpJR|=?hEKMRu=lRX!o#{IbPrKQOKWz|Z zjoLzh*n?R5fY_UlJw-aTFb6X)?Mwl|Ix2-W?J0XPi^#DGImB8rpACi3u?!2eU1%~S*;00yODhTa(shwo2hR@YBK1fhi`}N-ZK@OW zdimaRGDUB7@bHNE9PcY5iekCmhSmwAb|57U%gR z4J=S!qt{Ame4H%Aikcwc1)36Cv@^1+I?LyCo_Q69V8#{~6&oX<p%3Zidx?R#as|2d*wtqx29cGhSB&|1c& zVTf$#NW+{xuGdIlJaL$oF15h@paO?K?H*w}gW{lt^wy2FTW;r=Cw@OuM zOW5Y1tZdG$$^K#t7C;Nk{^TkHhqYyH;DDUuUr56d7K z!6IDI7WCvpQHh@|5Gqr{#HR8#A|9{9PhK!#`c-OpX&;)UM`EQG#WqAs1QclaIHFyB zUZLTK_gDECC9R0rO;jNa)jIi+DFOzRUAx+-OizHsSe_Hx)twAt!v>V_B1tIt%`m1F z&>N&mg|VC*BFaBQB(boyrnHNPOyeI$aQiD1X6Of-!T~Ak8APHf4QglLfr4!NwlS6Z z;^+GXth_ay5T<3w0>KUhP$X7B33>m)=am}eW93!>MAtAYlM}??6-p3ptkU;G^O5L3 z!i44DLh6bm#&n}ajo&8!uL^oq)BK->c(IAr3`dJPKoH@n>;P^oIlaNdA5YA{$L=}# zn>Qry4@<`RuR04JNeu*0+(zmME|ZKOF_BMXt0{wN(Dq5PIx!y@2nKV|l9y)-65B?_ zb~CvAoKU5Ke|TcYuV6;OSA;7(Dvp90LerAYRK)Bl6&vDPO!Aj2cQ5StYd-#x(F8hN zaRq8RqV?i%6z>nipXc~+=n^Fv%^{{t1q>lqkjTCpc}881sPsG+^VupP1cLr?dV})& z$Mx(E{0ctdHMNfeYUt*5Xw^9sA+hY48`kugScK7XD zhOl?DM41D#0kfx$$1p(XqnMY#k_NrBrt^u{tn}!qz+&dUhVOX2v^#5YcnasoqcPO8 zvsdujuH5tM7@&3`u3oCFAKu|*ptcUpmd56a0HBd*O*uL|n-gd+L7Fu55Hf5D#>+MH z`BA@gRUS@;$kw+Yv)+;(Ie~ZsC_yi_;y;v4cYHCs10l{@+AQBJnp`El{$lDRR}PS#NFVOS<>`kH>;)LlfVfHj1158f7mE|faEz#K zn-6Zuuy=4l{nchR2OiIApZ_Z?gddmlQ}e;53f5FpMQ&=CFU&IYq3j!d$94Wij#eu( z{9!cXNhU~3DV!Tj5lN3`SK1(kedFi<9PEZnJOtZ1StbK6=lSApdoLsV(A8IwEYvyB z4KA*N)pI=0Mv8bNY^0I{gxmBLbtjT;Fq@zPHL6Q+6cgDP+8~puUX?&WTBsBVY5=HZ z!IxTu0*qroH?s{WsI$Kr?QD0fi=mPd-dX-e@K%S6;|SIq_7~Runz*X}puqX0n%JU84Voc4;X}Se1 z$29=loQ8c`=EH2}P+AGm3GA{9*_p&VIkHp1c;eTXlux85{0d|oc)`Og(Ci5LTpw_I z1Kb82BLB)QGB0??+3hV4%wr^uNR4Ai<*wxbko2`x2jF6tG!N;w@8M+*ZH{~|2BUs& zzxxyX0V0d$MriP~p;}X6yGP@m^bm_~j}PK5LaE-*j39liW4_V2_^uv7y+sYxo$Niz z9!Yml<+gZ=%I~DkRN->!5+5J8*4YyJ5@W0sY`ZBI=M<>L>GbpC#^6}UKvw8-xRX{E zTB6_oC@LT#5pQkv0q_nykc`mfyQLA&ffeZa67v0i5B&gKNU02^Oo&o@I$zz7-^{j5 z9y4+o42qx6HebTfnxUK>ggL(Tzx9tsn1Pl5ZHm%d=(kh=0)hB=nod5n5OkC5{rLGN zhvq5GY(`njG{ajIcJPGJfcmlZl@-L_D5!ke16gm*1fU@b0}k{~3hJbX=X@(>A{{0Q z!H|E+6D#N3hR&&}wGx$X8~PVIO|s|2*LZdGy4LuTM{drW~e|xhU)Pn1;}P^+<@6AH~xOPRfd7^wo6w4l;#@$qJpuL1DeqeY?+ZX`x$@Xc~Q737VNhYiva zn$vU+uLda;Aqh3#Xkxfn4Fap^c!ip3S z@YjU~hj{`%n2EU;)7kCw6`GwO>4>UZU>~?ppteWESd+*qOQMaRYtmin5vkXQMX%C7 zGHzu^^#YS8CHy6%ArU@AOVwb%f|d}GU!r4Fh;v!E=DnHHuLYU|gqAV?fA^{q?}=Eq z2)PzOb4wIUpS_r)lJp#)5I8|40x>PA%IEyH%{N2Rx-@r`Pej(E9#zVHqu4G-vX@4;;Cd*_&2GX`$z5o^#~ZQZ}|j7tfCUi z2`ySB&@R&Z);k^$$ckqx)gv5-MttUVI(TY2G{J9?_Q=+~JJ@R68p-HDSg_EnUGu{T zD(X8bcNCCKCAB@FSkuN}AYC)ZFBXZZR4YDLCYT8uShf0ByJT7^y-R`4QUtU47#jIc z<2eSgqHZ>`ETkE-XO~!g!ufRH=F=zudigY^+g$py^uUCtHX`~)VuL^&aTH!4?XE?{ zZYB&h)QxM@Jd7NZa-aggNBu3c;c!yjo?gJ+N1pv^!|7QC7CW-0L@ynBN(`Q)r_*W4 z!AIOpr4|ZJg^R->qdC%&_k@W}(t%6Hh%;bnG=z#d9UYVVAkS2tIZcpsjZ4&V)p1q| za|eEto#P&wpYK3Tq2r^+22DY^#26O%D%=~1unNJZhtB0Gui@@JQ0Tj>f_)qmsr9;D zN?S@s#EWphz`#Lc?~{(B06-Rg4M&cYM=(~A&7D()u7X-rBkhmWgaD5sbOeg?&X%^%ItK~Tu!b#d4YE%mP{rSwv*jEaXmAJJA6KQhsp(h|K$`KW1s3C~^E^g1Fa*CQwc5Nx!VWTcms5@2z zgTjo7_eGtL5qXF>N+zhD0H+p5NjHIK{m-BG^L0qIAub$~=G$|Mgguw$rkD@3Wq`?6 zoY?uBij(dYe#PM_hmQ;LOYukJIUdBkv&F~7L_%*J+pCMKgUpp9fzl6ENxhoT17`tR zd6CCNz}LNpo#v{enXfiL3d;%r{ii0Uh?jAd@_hA?G>xEG_M&Qqnj=S|pPiy+KirQC zA5h@#7Hef0VgXo_1*%prEK{r5Tk)yypr7|~nvpiAM7Qp>QMl{oUF17k6fDUKDy6rh zkBi}KF_GvyuDmPKc0CxsOFMR1240gDImc}!C$Ach%-~ba9QUd5Mb!% zLqeQ{{(8M!pAm!>4Z@r6L0%CQf=jdvejS)MP^Toxuo<@)dn=QXvg2&9cv^lz@9b!M zuze)n>p$PCHrmaMl0&CCnBS{^@$`h=i$gk>_(T3$1*CkP2yYBr%oPR&N+y-q5YXwI zK=OD-4J5?z7(l$(+Jol(zo$Q}A1G`qhPxJki&d!9n9|HL7N~y#;e^p;NveV@ntAbp z$Ar4r4DZju#|*J65*9VZBoz*#c}iv{lvAjRdkk0`2Ar}Tp4wgb^FAdCGEch56fI?E z?>a#2`h2cBB}Z4Jsck80oB@`-t!an0A%wSNnGyZd8@@lx-6qZ}Zq%E&EqqbM<)9cw5y?y&ZFtmS~7f-nucju^h6XLy!$uDYj z>fvx>h!aXZcOp3v%xYaAM;ZGr$fw0u;K12czIlAeQN}ns%eudH_@L1`=)?Mw-U5m= zI3@2!JST`BN08DJ3(I3@8#td3=Rx3HL&I#OW4ITo^zBu(7=BU?XBPDC&1`{+#`4SK zDr4-Q{a5odR}M_O6i>0foQ(a5H1E~J{{l%F*plsD7*5oo?=*STx`+|$keX&m+L(4g zaoPT+pV%65KyvVLaYf^^#I$}g-Nd}(rCicmfXoLpsKkC6;saE8X3GteQ+gb8qk?D3 zf`9&rGu5L@Z(;Ti&QY3^O0WSk^)pBt+XmJFixH02z}wR5`F-q90E+EvfPj-xy&Ju) ziw)`hrRN7C3eALOnx*stUbc2R*&?Xm1O~%wc^caJqo^3MSf8G}!6Ve{FaC@@SyUB2 zqVbOPi`oU;F_^bK=zPV>IVuNwgUf&U=^DnZlXVX+VPZe6uBo~T5-VH*s4$EGIMn7V zg%L!Lntu0DepjAFAxcAv0BJI$w*zmPi!Xid;iXnd!I(&P1fnTm8 zP}|ZJ4OoKQVDyfG2Okln7(wY|4Gc#ddloj>FGN78u=9T*3QA=L&mnjb95!Ao*F2x6 ze|vRLMIB}4$LBfjQszO?CfRY+Cp#z-U zwOd@s5WsZbo*gMb+A*6o%As1MhYXIyZU{M+jvtuSdR(z`;5x;D8#t)s3EtIA^y7&E z2TTbreP6LXF`E^l)S#XZXRCaUhC%6}s&sw~hYYbhy<$QE1DkI)bQFI={#Q#i{%Rio zBf5laQ^jsv0(0nbeXt2dyiQQb%9o`U=k8QHFkV21X1oUJsb-yqm{y#rQEf zucYfpCX)E#%)zugn?Im!;L&WX?SGlQRDFVCHRD(Sl0=98c^!>B zLee8-%pY91H~)%05Syk5v7*yRLi>k#^+33cj-u*0%6b$Dw>W;I(&_Xcl7-Z`@mTs{ zv0fgU#JSzsc=0se2uBb?qf`MVtx=AYjWnM@`~R&RS$Y5*V*-vfiERRhG@b}P2!ey~ zSLp8vv&u8*DFZ)sMv(K%YIroP5(t`5hHTH05`J?eb@5>ZK|{h&4O^Z+hQz&40>#MZ<`bogWAy1H*?)W^dy)tTttmIE8` zi@#9X8#L|yoVE)AQo=L&-RDAhHV6LL8Was@+XD$JvIZhE*zm5efLP=J+2L(?TWcS` zQ>3Wkdwc0I`RR`YEMAU$Xe17R)FG0h0YD_bbxAHn|4HraRq z<&WEo0p5xJptqzCB!J{tr`Z!%l-QDxl!C}PNcFrd<#P8o#QZT-l}Sw6_Sk86R`B4O zv{w7Dx)|4~As$0bQtfM6G!Ud~w&kbV|G(&u{%W&T4)5uLdB3`6b) zL)nxeE!VkvN&33@tSmpLc&S|sRsbCzokCa!qf@hS7h}2|ol;Vg;!1<}8F1ay&3U=om+G_GO zJ6+2Vq5RGd)mdn)bj&!N{Ma}-G#Qyp*e#x%O2Iy13hKyCbXM)1)7w>p2LxL{B%Yjt zLxgC}lx+wGQJsT?Jkd#9awnUuFUT?IvLmF583WQ|2C)$yp1XUWTVyNkWTJe(V>ffO z*T=p9r9Bjt28fA`4ba=Iu@jPxozB6E)k$WP>(tYsA{^bSW83-Eq>4?tZb^!Uc~ZRQ z)WwQ z)Z{JQS8DicE`wH2THYCNY7Vi^TTFGbe3 z*8>mpSu<{jg)V}$mNr0{5p$n$f!mR?yf${LlGZl%gEnuE7)&7!oJ-O`?MZ0X(DSYy zZ*Fp^IxePEeoK1pz;{a^@fYtqNHJK`$($IrG3hxycWJp+t77`qMThf{%{-LjV zA$z!rElZRY@aexl#Oz?vbY<4Gqzp!rpQjFK!hGpmyu7`xhj+2!eU}tQFEN^;F zS`s8R&j~9dZ??oC0X4}vvJHv$<@miUjM|UxN#XJVY7;;`x1T?6w|hpYv6g8!+fhlm z3Mbd{xydEUy(P3bqS%W}b#^nOAs$A;M{nR9eMNPaS0d7BEEbcabBiOH{&Y(-FNl_f z;3hq{!ux{DKFL=_)e@OdF+$IlxQw3;K{(BOhC?fnM?uvB6*5H2GBwk}D1b^xe9D8N zReya1yt>f`dw3nabD7VL1~9i_*CM__k$$O~F&O<9sbk;@dJJ%9U-D;;-Ul-*0}u40 zA)Mp{@WMW|SWlL#XWYeKD2Zk~01XNw(;P1vQjBd^k-y2mG<-M0gedx9vBdmC=5az= zK9U{zRFUHibTnz|11enDSNu=<#aN{yCE-n5H*q$)XSucb$_df3>_a@Gu^T;_HC?N@ z>`6sxsKovQi{kye96jy-fZtt-H~vARrMd|F=9sVqJ59>%*q1bkib*4O0+szCj{Jvf zSOH)xq@6<&FA%#S`FR!LZtCZA8)Lx*uwnSGaR0sh+iFJe^e#)#97M4N>Y#(JRvE#C zV6o(J7J{~+16z=Exe?O>TO4Xe^nNRtI2$s|)Wep5ITQD)IpD#F0{y=Ka(TG?ayO1} zUfVk4z0^bAy)39SidA`vZrl@zFC_g%v;jJTWq8M-1uCVu9)gVmgALbDoos#s?>uAVAMIW!<58E?CI%eCVlc_ts+O^Vh9Nmmd z%~3QU&gZmi+$;7JcPKz+7YirBKEj+Y0W^!;)deeUB&v9NR|_b3z_kKLLekbN_jPB2 zZwZ4|69AK;IRNQI9W7gi{zDn zmz*t^>nTsz9X+EW{}4wb>iG<|_RpM(z_$D;9sJakw-O~D!~HS5pDg_?{q2Buu56;8 zan`~h1P{akuc`;lnj@wVQV;?gdb&kD@dnKt8)mltK40F9=K~C#7Ftkqgn0A-egKZ` zn*$QdO$3wFTtuwYSTpXUhC?K#_|EMyFk3Rry7tEnIHX^7V#3|+6XEyX6p^= zm^Ajya;OyV;3h$C(pCn@j{mWbXD6%F(8$zij!iq01@>)poS+g^=IR_M>{)dE#cLXx zwd9OKd71%}#*(QHh5!a>@{L!mC{2S+th6GK@+pmbCZghDXN83GleltlKb|hX8r?Gj z1_yrCmmG^nC@1K1IPAEQ%37Y#WvlJ=8?z914i>1G-Ra;MpKvh;YpdOi~a-{ z^`eq)HYLA;3_fj2q!GD;JIj{6JhwKpTBTF6Lr zZBApns3NbW0yVMx#F|j$Sh<2yCmX2Jmku5`t^GoP>~y4(!RpHU`IH%Sl1N>dR$2K# z_uvPBimk|rw+L7c7Ul&PVR8>v&9a;QktV62I_U2}w_a`jCR;Xqr#54fVsU^IIONCB%@Yh9*)J!}!x`j$g{7@bV2|>_VTvBBHufrKufI zNHrJC6vDJN;5ml3+kmQ4bCzE20PP#@2%a4g=!6OLtpO2W&% zbWypM7RSdow()usnHL>u*0xkEu&w9N)tM@fc-&Zf)UL@ren~>98+ILe0I(dUs7E~@ zv6&h5J+p@cal7;`Utkd6Bv7|w#UXY+`biD4HeVb%YAga%`)VbYSFD*_{2DcrFuN&c zu&7!=DOi+TuHF=5;*^u)^911QjTDXYQhoMsa)3mP`I#F~{P1s+iaDZZn47wv(Tplli)?V7HoZf0PQ^FdSV;^u_z_%M_uKptPSo6xw$*3$m7Gm^ zP)8Twv`vk&77+?0UQ4=&(g2`hDm?3ja1=?uUTLcEhzT%=wxgn|Z|BvRxUq;C<`SVQ zmll|av~#;&J{aoJ=6X3ok5#@PnuwDdOW#0!(UiO-?XmB}6rm=@7ZzA)BP#2$OA|vO zc5ZhaQ)EGuF+)r^{69w!fQAjINg&>ge5jo_iSex%o@>MX{*bncgbEMCCzPS>uUGa* zK@PJjeB~ZFnLMu1E%La|E80COFeJ}eD}=Wj%BojUC>t*|OAe$-3Fu+arxXVdlb~Kz zEP2>gXY`In56k72Mj}~TtH+X{F{u-JqRz2pG;m}Ff(Fl!9$++`Oh`=bzrFcfX3Mz6 zz|S^nfA^X9ZDJHjeHh45{QlkUN)g`UVEc`&*zOp%VVYk&B9R&n5Jlvvl)9RrT9QkoQyPFl> ziJz<^x0ob&$=keKsS>Qb6i+QXvqX{G z|D7E0c16izDc?3IA}Oj_r0+YBLEuZ=9$7603SvUqI53DF%le}9F9a45pBmrlCke*f zV%{5sQ2 zk<`~`ryKW?o5J=7*3vh%H12_tAnYVNtg|FZSPxdcf3kA>Q3b8T)`DEukVnAXBBCzZ zE!4nP$smH$llH&_Tu%Pje)(kRPzc4RzprPQq*;|MV>P$R3+b^EL7d4p<*uO*uQ=R* zS5zhf$JC~}xWky$ilQL711?JxA$oFjhPH^J9xY%M*VKyg1?Vp^@tlbN^mhc51-XSt z`VepFcbZ+F;#S(#y42e1j~Kb6)ij$JAWeEss`Wlglz4rZ9ah9ye=OiDIqpBL&d_b+?^>*G?WaRwRBE}D6xY! zlP4NNUgekx{0q$QV4^M6x!f?ns@>x2v@qB#=2G_q4KA^xzW z2VnKE+TC*rSN@k;2Jf)a~ACX4uW^v48GVtv!SJHTHy@?AThK@IW9L}V$|&Cli# zf}+_*%*z0;f=!DaH#J8RMSYfL-qRNJQdVM~J2If!rN$~+9#yN7%B#_ex2+3Hn;x=* zuvtO2y!nhEoX6TF=)x#o7cV?2&b9wUd-PD=M|63UgW@A@L}~&r;T7@G!Gbiw&;m44 zM8Xep+B4Kb;Lz|pMRn9Bmo0P9cEN%!1@W_@g;;=%y;tL7($0K2o{F;=jxl~bhcv~8 zG5OtTq4bnM7dV(uQyhfOj;G7)>kJ@FpT{KZZu&^R4V`(Q>`_{x>9_6sgll4w?kg#U z)E9&_5t*7tSoGrRh>}xwvCc_x@bz0EIl)*ksx18LKF{Y68~Qq4TUt;R%4jxeNswb$ zr}H79h=gej7M?WXVej)bFs3^@lcSYU30Ju((!VZ}+&V0eKJc6#+WzZ7zeqqp?;x)a?wUU*ECH%euTV9?MBYu{pW zE!aE^6LU4^^y7#!Wbs$r8@0^`-}*`VFAS=cc6;!WTScHgN28{Uq*#F z#upxNh3a9qjutTo=fDQ{@vOU5tf8!CqpQ@};pJWXix?|Lr>U@AFCcdd@bE3zg3CKZ zbjGcPvHyO4%m^L$=j5kItL~-<(D)1x^w~z`0?W0#N9Ac93H{~c4UZICZ(iE&=GNhC z5-7`D;#3El6-0!PZCP-9pHPJSBa$xEU5+8P(w74au0TxJhLSHIuImraUN z`YfE4@^-Nly`FR$r@XS7Lj2NevcAKQi?jRjTEI}{O5HkTT^G9O0$>v|eH|f@&`+U< zn%|*X7t+_$WUs3|`nX_1qyQ|cW^!{BN(odsfJrcx5+_YNl>DMwYz`QKlqJB#vT2C6 zJ^{_h^jhdn&r>j~S5)Epmh?&Q^6eK{k-UvYr*U0Ar*b$Hr9Mu!sium{4$Ek^mr4B+o`mR)x^0w z*Kr~hrsg=e+9G@SxS%?Z7_*3|NJ^q2mUs-%+$v+UUun}NsT?IYq)<_ry0DI_?+hG| z3mI5sHj^*t&3&jVYR8=4R^l+)uUy-*FD zNRPvdr>DNxocCLrlFQT54|n^h_hKU>J3d6k>K#ME>*Yp~r~SGi1$4n8Z)@MIPiU+he@$t(JU)*R!4ez|yNPnIy-;RaHQ?Q#0KtM8Y=&x;7tj#hK0ZhQ zt+tN_U`W|5sok*8NKFm|cNpD|S3og0`JNX~>(!qjhY<7>qs|@%x0kantU)Rk!3j?6 zUe_FlawPr}NTtTB>lNmmn0eLhO)G2PxB+AHb7$Id@m2*Q4*y99!=<#FZUx`8eFsJR z2D@%=*9X^jT1Sai6=}OJA=N>6=d1kp=yZyU3|%;#F3vK_>8RwZZQvxtfc0_(U--;C zmOk3|gp_WUHvT{kVGREAdPfQ`9oETuPk3(9*hSWa%^4rhLlJBrOyz7Qd^YXB!Mr-i z@R#gYn$c@|_&NR8G5_yT+5`ciZ1QcKp|T5V)^>9L|Nh_EpMRdd8Dzi{b-E=dLUAtgps z_IudKD5VcMq!rk7F{k7PoLA&wP6mYsL;^8q_p|vFbXZL&hLQj?-{qD#v--GOE_!>B zDp^|Nf*UMt7-VAm(lx6~>)j;m5-WV!UXd269tl7;Hqvh%x7+37eEHRg_A8%e`Vg5- zz7GJ+3m-P*mDUoo-kz_QSaND8lAecrZ7iE|HQ`z6ZN^Wz*e%3j($>6ty`HWShM7au zoZ!9i8S2rg$9XR!)1;Ep6em1M7s~~S%M&{lDWCII>}l`hqpH5%q669>)bw;Zb(Lr+ zmZX}sGz##8W7kHafBukNqL)IxVulA-(->8QNdxCDd{HsvIgugH+`G|o%Cm1}(oTVv zvOE2FOWv<9^CV0BmwT+8fzvSIXk-y8K!s-AB(R}_SU*B%BLSNWbM99(-%wUlD_tFY zT!@CxcD%SX`?}P|qa#+yx}yDg)zqz`qr;V#oR`Th85wlovywCLJpnYh3_AnsFk z0*vv5d3gRHk2mLs56mH z*7c|r@lj(_(?{W#tx`7bbN7=4o4Oj$Fav`UIiJ?8ho0VmoN|N9I} zZg5>A5T31;$eL$VND#;-Z>7`s;Y5 zT~)KH-n=<0R65B zpTQWYnr7GRRM`S1rmzr9fc~~S+!Q0XCxeENq;tsNEa_=!2Ov5*4I9D*HOu0>)+bKM zdcirD(4J*l3iueICGP-VSuF6mL2;;H%Jw$qw+-;=Y`)OeoygXv20v#<9|L2P)(Rwb zXiO&daM*UP**u@bRKQ(^j;8*G7o{Y-3?L1`>)1L=wA}mFk|OP>ObkmJZc6KeU;74Ynib>?;;my){iOyiw#u2aUjAhpJ`U2yq{hjTHfkKWl* zU26P|p^m07tt|Xp@?Z@La1}@?MoN2h#FWRj2kp$(yH&oz9`DDe-zm1rj&KG{cCuqT z=@6MSz6$m7kEl%ag@O7Np%{6N1^p)%I)O%h!0}HL1id+A_A_plwr_`*vG@@^5Z;bx z!>5IcLn;IkRm9*JRna4t1_qudMR9$Pc^H{J5mhyv9kuQp6rK8j2w!JiSphS=&+2?# zgCoKth#7;?hT#>Dov_r$#TcSbwjq3gbFA#Gq)?qEk{F(W_@^T+cQz0vga-gyl4n9?NvkObb_yHdg%kIq)vW~!YO)* z(DRj$;F$T+epcYWDj5dC!^hRda8yW@LhP67exnD_EcvRCH+yA1dTdr}WxwjE7E1^5 zYmaUt-sYulF-QF)>EgabnwO(yA~UEq55^c};cd>TIk_N@K4GX$A$@{CM6juq@%ARO z{{<{q0*7iWm>AL0QvRAqnwxb8o7M%31HinT_)|q0%6?f{ftIJ;zU-Idqt)A)TAjnV z6FUT5dTowMWkQWvib6NU=zc(>?_s<^jg3aT7C+ogRHT0>Z^1-FYE7^XBr}R4G_RSC zS+~PKDL)gv;z%F}vnt!#dw`5id zJ~>inOEWISW12sq4E0{tFD2b@i+(#lHnOL_v8TcD z#3KWsIlGym$?#bw4=FA*7JAjUv02suWMrZ#r%{Xm6=(L8+x9EXpzoAwcqnUKl?MSw zCwmJar7eYcFD{-`T^*}W0eX>O5K2s3tU>y?9na?YY>3yQ^(@(JQ9^N4oJcv-Dm>xe zRM<|C>Mo}upqY{O6J#^^2Wcle&u_;xnVi)%r~FgvCq{9^y%>K*q8Ffd^yJOr+E#46#ZOlJkia8x#CfePC8 zn0#q;=gNVv?^Umx@Zq6|5>4iZ&KLY%eQLKDj(FNgzo5)3J2vqD$pOkk7>?E(^!pzL5V2oTv7Z#(mS~H>ZA|i56cR+dCwEHwpy}zip_h+}Hslr+otIebT?c6f zo%_~WXoufL0NnC!>8>4wRfQE00=U|z_-vAnev76b=x16$#o+1Z7=R+|zl@d;Rgq^N(^0aJV3J%LBc#*=;uXbFtm5>6^(68x;vF^Z@3A zYh&P`#Ru;sdTx-K8Acz}!GUACknMd1v1qvDomBn%gcaz)CH1jrW@DNr)`$EW+Wv}l! zDS@sJbkV}@OA?U(teiprK{7rgF`7MMQVLCTpo6`MOH4a391SXwQm^#57 z!uazfTN$=QpB_PGoK4nfuJ|S_R)3!7E7I46kE5em_5yn@BL!_moBG68qz0y5L%Odd z#GmgJ0S|=X41O~L3%jO9k1-N}I76vQ#s%+H4zek^0bVT~F~s@#C*rr+?F^kI zG*KsJV-1z4Mv}pXA=aik@Fj(cYY4AVKrQrS>-a0P5r`T+B26B?9MK7h4*6+i_)UWl z2gE7Po}o_fUzoDbb8Z8>3$hCH}kKeyay$!G?wE^#K4GaayuHAE}N z84c%HA)86EV@nqv%;>~)GH}_Ba9Wb8S~VeUo?JCCqHsKXx#}Z;1!>k`s;VHgTud3M z3^-B=>M^*$U}(aBQHqD_=y)V0WmgD& zpZd5;J6p7G97y}d{p{|3j{h)l``zSk+HNm?rU9r!OhOwbw+PLf&6wlcEN1)5*LIsy zAi3+R4XxNa!vN+&gkoU>152gSeQcwf#3?*26HgX_hy=YVyLzw3`O87@H92k!e}4(p zq@dxuNeRJot_`bY%QfLbWr8X(k7ZUU2KMBF%Yhp+{4!orP@5;B-3ET9(?Qwsi+m0h zunG~q8JsC11yi3pV13rXz3ph0&Sg>|ARH8M!*st;o?B8hE?08EWs>W!OH&e+!nx`> zlio#tKA)i-YI3@s$ZB;7R+c_V5>JL&_V1TzcKV0`04N4z=b+`TA17O`5LcM*J2hto zJ9M9pwp}~3(gP4GCTO^lsn-<3nAi+CyOc`9gG{BJFs!2@Q2DDboI(<|Tyetm#|HrT zDBXM;-^`v8!0_2-hO5Sm0Inpls0p-z{4Vz}Rgfmi#hsN6R!)j5%?B!p8T+g5tCTtD zS12kFC9Yry1O?Cl9FLMahfFMHnB*;l!M~2zxzsC`YbqYGM!;wMiA0kr2_~N{*J!v} zEf-VlRNn2J!kAuPi;~m%!UHUS&P46I|L|JeiZ;uQQ5J2 zSl-(k$tzCG&!qK!Gyy_&M6JbW!S4@aqoHwOIxwhDu;%=q-%Ik3Yf*7WZ3jx<1@wmm zD9tD%D*E%#u?0{q8xLSVBwO`%8hBsMRvRJ{GmarSLVMrcf{3~_s*7-z0e*`8ND8Sm zS!HyZU7`L%3+w}qX^IoVY@zC~3Yu0yzoDGt=8CT&Og?dAXxYpKrDS@D>9)Ymjv_g;G%JBV+05$Mz^`WV3JgOlL0C1CX#B$9| zKRiVsA&nKk8^+}FhRR<~d5TlQFaGA!_@BQ0_hyQ7f`^^W<0VW!f?i!nBYo^2n zfN!Mw@6>iNxK(KjeKer|_GL98HsPvOthRzAG@`6EH>I|iQvJV`&|nZ1yXV$Tkdetk z=!pVSg%ju~nAE&oV6jX&*Y)9h6>=3jSx2~Vf*f1rV8#NbigJ)c`rsU_6p@q~7$jep z>-iM3#$gCK*6=v4rbobXT&a_al4uI>>&3we5^%soi5q^ijG=loTQzNI8sDjSAQ0o% zStL|3W|uz#kt%;r@~LIqsYkLq;nw09to$oS9dsv^5`3p%cn^@3*y?*yZHF!i3JIlb zmK(_7?xs(Z5B2(+8~#=6#k-b#f1tI{^ENlS(~JhMG$*<)QT+{)Xj^F0((NwA_=LKg zGJQ;RPR@YUAY8r^089#zETH5Ej=nY^;uDS-Iph#vM=~5BMI=@N&VroEYVG}_v7cA99Ew?D^M!FnfW~yPqFE*VJ)7PN#Es7z@VHx zQsb8-05vOEh3NLHGh+d7j31pi(WKg3Vk?ZX1T;-}{+URi4S`gED$5hb-?3>l*(|?? ze?Z1Xu`M3zD7Ji$(mySSjsa?QIlghVsv=6ojI+3o>~eeq<-J)xpX$y`HF>fA|9T(c z6A-&y%xy>GxwAXnw$syZVB_%ik9`io_3s+6+$ba#e;-c*7de4VuTlQ_NPi z2{1f0bqQ0c=F_DuuYVLzN=C7x8R~XUl?NqS;yB=FLN==UkzOe}Ib<;E4~*i1<|E5* zX#MG|pyW}J`IgEWh_PdMZ;l4oFfb@U(z7S4NASgO(ECVxM*uD{vLRLzS4g8`V(N6K zG6s+L1h8qDA3Jfl8V&Ek<@gzN-trbn&j=_781(ou6uz zEf=GQ<#Nky3NboXrF~Fj#XWG=!)BqkM`zkC6o4gn3^%>m4!5KzPfxin7~#!8FWa4& z7xDek9)1_r@sk=ax;_AxA2SY$@Q_zlj|1v%jMl}+l?oG9kTZ<7rl|fIVn(l&Wku9# z0-j1qkyp5=DGK7ax<^<#T0Wv!m;C?szNANzElVqyiUI^(2#|_Ft%raXLQN{nJw}N| zWoCHP^Ouu%MC2Q)7lwzsMTBK~xJUUAnNh6Rph7Hw1yTzk)Djz5f#{aHB{nTVOTB{y ze*h$wAQlJ-2~m9KoO{jgy>_mdxo2i%zEY>^l}Ch6Hr#uL?|kPwM8O+eaF*4j~<`|g^n3xN8DE&`Vm;Qmiyprj4i%gHS>}r#}mMU^uhQv!H8hsJ$XRkSfXaB6tn`-iXo|(@&!{M`y7>=ocaT1=#DdDF8Dd20q97RMuC&; z7HyMoJJdWxFO>Tg21oCag1~wo+QO=L@Cwa}jVZUBqDAj*zO2wMH(Go5fCSf{sTRt# zXGFe>XCM@BryZ)p8-yYenwy^x}Aj;Eu&&(!J9Ju z13A!#9CmlJppZk`#uY(9x0RN$$~^7YW>{IEh(yt&OlZ8q2OR~RqlsR$FJz^xTdYhv z^WivOEl#uHd~_w5<+w`iA%=S2gjGx~TI>2Y)X22(hi*?v+HWqEaU;EDGbG!nwes=? z)-$jT-=$Bmxt`|3*`B-E3{^=4E)m{S%eh%=T_Afv_h7Nttlio8iQ;545|JQwy3(RA z6c_m(c_TlL^2O^ij#Ry-_l7+wh}6ENRpL_VQLM`>e3UdvSeabTTf*$y?R47hq!yh_ zs?m14l!rW;j)UzReK@hD)$#)s6;9s_Zyv2K&^T$tlnXXka!-B!raB`1)!?pOLJ9Hp z!iZj&D=e%pf|;T7JBF}i3bF2se7;!roo@bQKTW4Ha}dK}80+Z|*wflw(P1Eryc7}t z94u*vv80_4OWGAIiI7(Av*{0xX(|9-eZ((?Ou*^q=6`^ajM&G;JVO&1%VHsl3`wHu zg7y3&<)PFA$CUuo##c$qZipU!5lS2t%QsgZQCfF4e6u7*+% zbDQ80ze_d3j@lK&M}nc7cTbi#j21oZumIhJ21fym1dcV}#qvbFS~~n%wOw&MFzcn# zZ_SZ-cRSff1hcwv3xgZpc-$ksS`nQ4-s5}@0(R_5VR$w*6Bv4|75hr|Q4S{w=u>Q+ zNyhWe2AvXL3Y*4g!Du08a4dWu))Vhi+s*1su~RfjwoyBRECdrCqiMfyyF1$ zB5FnggOp~&B{LLWF7wF(9fjmR7b|E$&;TEh$Cr7&Try=WS`)>nb0(1g5Yl~D`Dj6? z9-({&#!|kx9WZHm4dzCy%OYq9?9^^dC9b12t?z+W9zK93d51{&RYdsKmDB`S)Sb|R z9Q7gEtafO8P21e5g8<<&U%*uo+dtUv@Q!8JEPAA95K-bdS zXtn^WiyRAD-Qih^&kT)t!YiF(M$Bd{`hR-Y*X_D}cHXJmN7)-eHVUeTz~^yAL}E%+ zLa_}EzK}zS_i2zTgc}JqI0Z@%CljLQn{C~~5|`D^4vE@4rd}5UNVs@09hw1D>NW7f zZI)x)<#~JBoIUMGnqi2t`T++UA#f>&W?Y43#5r}LLur?oi4+F@KQizS_`gxZ2)ZH? za&X#L8m16L70XOVYPhb8r+52J1Y~MAZczu4+`x$b2>CJMEi_5N@@3|vqV_j4-&gV#5 z@ZU8lDNui(NVuho;ROvn163HsUZ|Z>>m5p~&d1NQ3;O~HOd+@7HH78Zj7BI|+TGv` zz8ZReK|6^orN|yzD>V08%WcT7D(TcOcYjJeXr#PgqQnnw9Px+qo|Iz3Cs4**MP`GKU*`Rbu&#&H~Anip?Nuy%3IVLX<0qPNGGNjxw9rMCs;5+>uJo`@?)J6H?hJl0D%|5}TaYE=k3qSzKdszu}Z z-0H29nX14cPA6)S>f%0J!e&d=NqO{05&FowIRMKSymk4Cr5PBH>A5CZIt1S=AkW0?vlM1t~#QRC5`g}xI)#Pvd>s+KcWl&qZuYu z(}njaP5BgLvulLe0~$}QP@Oyz$_GFWDeQe3o&udA=%^$>(QEOMz78TFErhT>c}nau z;@1zjQ}v5}KfBdL0&O%k2owk}cyVFkTbd@iBl4!?O>(3h<23=2ykebNNI?g8!LB9E znERfv6(Qyw=rEcyUMn9j8u+cku-=Zj(bB4M&+m)%SoI*TA<%egHZr1nSET?myb2yF zCz7=k;O9@c^~6Xx*MYRL;!n~=>HBy-yB=^06*jhzU3k%TSQOfcf8`ET8n7CI-zNaL zv0B#-a_csYx<{hC2Qp*YKC$C_;Qvgnu5fhe%_e_-ue;adVr=Re?_qiCX18gHlfkUJ zf$z#>;m#~?tP1FrZ7u|u86HJ9?LiQa z`({kbpzN)6(u?<1RBXP%RaS9*Rk1!Vz-UuU&VG600B1qJj9b%74v6OHkMrn}4B2KL zOGNrgWm}9Lp`L3H`T(I@bfHYwdGjmFC%oCzBvNO8!@Jvr>?-(~#0FORI7KmTiJ7{S zRo2I7LPt8-N4wSqb}bri0hG#uJX|ct#k{^D$`IhmQxQjBX+iMbmVKrFp*S%bPDbnqzZIO=AGzk5^L|Jj_6&-AkWS zT0G81L8#@4Ls1jmR2TD=P3%@?HO#a5aJnGcSm$W(WX2#e8|BbMe(J)dqe%~<^K|i) z8yXanIc0`nSr-Qtu`lKGV>O{byKl2iRtV$t0aMX-VBRJ%KOXHejBA$CX373Ngsg!n zbSTd`uY!>v3?U(O?!X5uP2h1Pv~$Ck8YY4XVfpUvLf~LEP8V0RH@qjKhva@X zlDFAvfv9CN;nw{D?P39Mt_Qa$7&wQxt}~1sz*>pDM3z1W)-11SO#3+u^hB$AdN6(; zAXluoS7dQz@Y58%RuPeV<0J%Lq@l1l=?l?(^TphPLd!B1d2T%-A|FY$RB7@T7P<)p*Uid!yF=9&Q#3b?c&n^@T4hmmc+J6LB6;oXbO07oATKXs~TsMr2rNPJ+T*buGkmjOfk{LTsci^&InwaF68S%rX{YRJ^k#-;K*g`6$>GCPFi})w_?~VE}Mlz&D z!s2_n`|{P!c3AobpQ@YH00XsiCD_Zl7@B)!TJnEL?0|8%C#31+x1DHkyJ5&TKX2r7t_lO`eUiH~E6d(NLWtO{5eG zoxAAI!vyg!c)V^8z*heY_Pi0`i@&^PP8*&Ns9kkY!N!(4G*2I8!bO`H50~*%Q_45X zdhb^1@n$TENnt?(~~Wbep#em}zBav~@s7;1GuxW*{u|c$s%t*NjmtX+*qgVRsH*WeVm5eZvzP3` zsZbQ=2k9aCUm0CYgQ3o6v&9n49dP+H{$oBL-u15}a?%26%!}l%a>pkej#l$qngN=H zvye4|wHAz0fqsn<*FMDXk zv@F`@NKvimtyxtBLaMl^hBVy+ZD^yg+zB5E(vydi%h?>=n%As_&C{Nw@W3d8eHGq@ zXiE8R*9%lxzhwkgGjg-xQ+E~+OfmK`Y>wgC19FVMCalkUWm#@cF{~_i!*?by;~=q9 z6~;6%Gp$XC>fUg$WZiwil}(&U=!M(tg6`+Y%V>mN5m-B7@&Zg`9)x~2`zlA*=p2Q^ z+Yv;YqK+!F^hTNIJ1 z+Ii43OUZSw$9pu5BV5>pIE*5K)vq`@~SP5iVW6eG}l(2l&FJ!Xdo z@yWJah07}-RISr)Rp?OxEBP4ay8&xzb&UgDWPEbfQI9OSN^vJTdvL+sr1c zY`U#Al1*%jc@j!Nuq)brDsX9iap}P5u-#Q+Mql(|@8!*y8cPRE7V4u3Vt&oug!cC) zfmWE@$>+!wDa%^lf`lP*$n88%bvjX#y@}!Vgg&SWT}WMHRGlJxDl8)Xvgz)XphZibg?%`B4<_EtJ^ya*o!g zU2G&nT^G;?9AJt;OC^r8GZYU@=`3HXbOy-_w=DbOe38w8DkldhlbU%5mdFxMid@Lg zrwkqg&I5%I%t45ulxgTl^rXlusi}NZsOH0CQ3Izg$=wOf2n!r?I=-6@uc7-f0#PRf z8T}0YkOpgU(uT=efhGe-7PUE^uY@yT5^!0Z=Fr2RuE%L$^g@{ev&8G9%ghH>0x1Vb zKuNnId$C&HtPGEnjSR)_LYvfr4$XkpN>!l0G^2(#*jJG;AI^P8wtzR zX5kmp9!b_1gof?|i6lz_yu;KdD1NT4q4JBQBp*&rf>AEz0^O*5i|Q&V>!{^1ex|uV zMwMS8;T45ZDhf(T{Gw*0{m$$ro04t>y*%yD7AZ})xyIB7ug)$}ptuOnrZpD_ianN) zOoFdzn^f_1(LP$Aj_L@dQ)FMGZ7Y}{hE!Ajm+be(ml;Gr^YeU?FYjz3s4inia#3VM zG4){1aKPuo$pwpWFTTq0d7?awYr_bsZ27^(W{5Lc25~os!vf~qrY@0maf3rf)Mu-# zo31^IQ%?pX7W*)My}O*f&Zdxvrt0T0fT1ItO}LjeyUOG&1VZuL9EJ& z41u#xvwg+bO&c5evx$>kjJKf9Yf4~H8ouM(2?#F`-GmVG_3$RWe#_*Sgs5SUQ8S&| z*|8l=x?-vn{b6x7qdmNE_O4tiZF)$%wMRxO9}GsDMTP?k*s!u{_yW=q>A~hnV)U(v zOzn^4QLKcAurbG?nCbhDvI4Lfd#UM&rrz2Gw3|PLVI(|;q#ouch{IB}X7khK9R$}I z=;wT&!+lDU6OsWxy%~;ZR*EF-&A5@mR{iHgK%^iB3Hy8u8{~1dG9rXbMQUd=tFd`OwTuTOM-pjp)vNn5z#S%{9Oswd;($a8aF@|}E1%L^iVeR6YmMO^$k>7)k48urcP@`4w!1eR!fbIhL z!^JzJ4fbTTo^3Td4{V9ED5Zv$qcM;zVrF6jSO`H| zw=KdnVbl3d+Of=Zom@Gg+s1$Zn>x96k^vlFX>y6OFe5P~8DsOk|`A_BoT zqKNY0>2f&dDQj}2{Mh>Al!vW`x3b(?_!ilf@GXpYuE~PcmTc?qG_-Zglhc_)ep74A z=U6z_M2DzO2zT_p#$lGze_w3~9_vM{O*Kok*E)22Xc|4rn4i~1_jG-wf zm;?hsTZhb7rS}a694tGpk%}53Bl>WsCa6Y{%KEPfR-sN%CHj_gs)~@>CB=&eSnqqh z;m(l-TXUHHe4&R$tgl(dAkH;ioAIe@%83|5m+Vy-*qXA`bC6gH+Eiyd9n2~7oo6(p zKD|M^{pb!#bI&kN1s#?0XH4b0_AJ+fZkf;|}N?drDc?dmkmU8srE zG#xQtCdbyllxTr4fN3W4T}0ONT_wNk1El?*KsO$=7pXPd1G5+M)4AS_WjpPv$K3Wh zIY!kQG~`5EiyzOI7nPu#;nHWrJEpWon?6jP4hu~nr<*ycBuuK!al5ctjP3M_ zKyN#H_SGxQp54s5GaF2?QLToyR&2Y)W10;Of2EJnwG)@J)PSogssI-0s5Zp6OcV_2 z7pbN;;zL-^wx!XX_t<>;4i09`!#&tpt)bITi?xmKn_IPz=%x#95w=7_oc0vndww%Q zrvuQ1F)Z%*Ih&z-1A~zfKelBGu4RP^@>s!$*`(&tZHkXi`dl&64197n2cR|Ej`nw9T4}SQDqFTX42io8K8B@n3;a0VY6#y z(M5D6y}tI+wyr0mOa2Z6p&8p`O<=lF`eu{m%V=+KK72A2tGxb-vq%3a-|<8ll2=su zwo#C$a@r-vGL!Jz<7_fv6{=V*z=d>O3)ax~WxNqOM<7`^SsRe{f^@PAvVI+CfJe1`F%%JyL=P^`PiQ~^4>gwG{E0UER7*r>2#P}VZ#>>mkDF0J z2anw8PxB>AZUtV^c~tJb2^M_mV5*@dn>yR!T?HEAY0bx$tkAc8S7Hs`_U;Nb?XpF0 zVo|dao)^_fr!&lWmvNGnP+E!oT!ZO;Q+cr+Z*Jo;wMgoIQgG+2>8<)=Hdo4F`6wcd ztKi@Zi<5Sa#?DU;WZJQ9F)0{0A^P-AwMbF0W%RIrMsv4?4{-Jjw`!X4{&bzLlBcS{ zD#Li^Xq~si2bp17lVDUi@%V_Q`iz=x_*NiEjt8eUq_Gy3Fo~1%6y-PoQ&#Ln;@;|3 z`*bipHS_)8uwIAo834Qf7zcnisGeZjIxSyX?_tJR-cTE-mN!&M9CgZh;toJ@*84}_4y9!a&x;Rv6cwf;yLzMV*oTE3BH`k z@91_Z^a?Sgp7g7z_l2%3L-yz`oKR5;NH^Gv#GAksznIbaMJ6-f2T8gH-Kx@~4~<*0 zqF7o$8$gfETPM4?IzDl;}%Zh{!UKA5LntRUSn6SBj~TCYTp~4dR;HzL15RAciGOSJje@-qyE>B%$U<3 z6ZGof8fTYKN(OVH*W2acM=bPaxJYQ}p$lFv8xdTvW4YbdoI1^e9mM4jvdMtuUcK5d#^tF7YG&S!pjbpb6)#|b!>=GyRkF-WPq1@) zlUBtZlpP;b?2eT$Bjur8hu*G}e;T}^sT&7@`z7Z)(N(=B4q zB0u8tc^s1FO;eUP`z41;2N1(6?gmnPxW3B{N#+qJUB*{U1pC1AY@$T5_FOYlMQ4jn zyjsp$lRfw)bWJ{oi9aJn-ws-|$%Ys)w#gm8wCGYS;6VDbnU-6UbR*V&Ei0iRKAYTl zwt_|tdxt?x#2={2p?!c5;o*GoD1)?0MlT^YH>bj-}Za; zap2`wDMUzb>-TH{h zroQp(nXgG_4*Lp&o)S=F5N0;b%+@s19H_hC>mD6ff6fc5F2HW4Ao&N#NXb>NMECcEl zn4ibwfk*}do|@!(@170cen}&FOLQa5niS=D%TeDbS=twUF$1+c%NAFL#Ejd`=u7dZ zjZ!ET|I-;G)x(z+qBN7(fZZ~FV^AeYA{U}!5r>unTj6>XrvMTY z*J@_ch}pE-c5!d*H7#?25=EAHL&0XOD2k|1g=;pw>?9g#OkPP2c|+{%7%5Viy^j8u zqW)EBe?T6KMlCOIG*beDTfSa67p#Cy(1dk$Ejc4UeV78ze_WJF0(>VZ3oej#X9Gx6 z3Bb^%$7bin^l5fsbi{0n4TH;|_${Dvhsek7`93Bn@?O_~`E}CpqTOmuo{3sP@fnV` zAm9!+(+*b!@oTaLwPh$UaMZtma-lfpcuGRO&5u`e5=Gi z+)#qucRi%W6K@$jy)1}-2*`U+{PCb0= z#zYDRnJuNk?%tN{txrx2pgC2E%}FKu8KH`7m~itawm0|=228WP96E$C?xCS=LTc4i zc@qn}AzrIfPFg_cc3J-j*^cMDIjkvKu~EY#MU|=OZrO44*as9g)x309Xtm~r>&nAl z^e%eIZV5e0&cJjLHcb&tdCGK!Y&96aWf=&4vDK+l#$0@0E<1aYS3I7fvYzAeWT(sm zgo3dIHS1>+ur|U|KP;|(|Ke%h1x3BXRP{3a*n2WQBLW8jalE8K%0XyN6DE2$iyZWo z9$zfQ-jx%?cg7GW1x8Q9&`hbea}B8{ zM7nKSq|gfZsMHmFWwtYqvA_LhKD^1^jcUTUcmUWezeHy!whF%qHidu5*{eW2G{< zYGg@b11n2m1h*<{wm2q=yD(IAHOQf;19G4$`=))y_W=a!EdF&g7c(nwry=dkU@Z`vDzFcHqo`csF8@k)#h82v+ za#Wm1kG!{h)G_vC{EBLWV!&D)ue-p|JDGGS1t3)j5-zfmrlNACP5A2o*TYq#A@xub z;Mb`pNC1Kg{k4Ihtzy2)c_!N;P{4F&4%jt$f{0u5gMVVCLbnN(nKA`1gtyG=dhZ{<0c$E4Q@?Ov%F=^bg5mP_2a;wS{1TpxRhVI zN{lR0$)}K*q95xkr$w)^t07HtHoTD?OB%HhrAF$%d~fMCffzhtt_&l4UoQt_fp>s(q)4;Z&Z_u)5dm zIY*L`xN$MP9Z@0cYKYVw)0y#quVgrOp$88K&ST>jW@%|2?O{28w`3jk@POnIgVju5bj{8*99lvI~b7A@gR#zh%-6ddJ>+$UqSI)joj zt9g>e!^^~4Msd-?dPXW&KF-UceSAnC(8H;F>V9f`)^=}ncK6UutzH_}+-Tj@4EI~` zq1vdR-}ojaaS7;shOlIMYA7u)=TJK6$|5YovreAx65!P^Yy0>s4t*JwfpL@n1L93Y%63e|nV zP~8^{)%AMk7$XtOyd5sbA>fy)FxPiQ99MbQV{$H$X3} zip$ljSDRgLuAyjO=UkhFT3n97ScH)B=csAV(B5-xSQGE(uA@LNr4qG+rx`|aFEZs3 zD%`17ta;IE=kLRFy8;U^z|^=hK3QX4V}>>zpwdA9XC$){^B$gF4ac)LcBBEfK?sAg z8tyh;Z9$ZM)qtiO*_MG=izEOdpLfzS|EKR z8m%|2rML^qE@%iHoo#0>F)9&q&=3s9IJ zN?SXzTie!`(7^?fm!8`$?*q_YY04Tb-jaTZ;Ugh9KA#_G-WkaRo!rgU=D@l|?T`bm z(4WT>!Dg=&0{KJDA+K56EVNqBD|8V2(Bo1INF=wJI+Mf^?);hXJz%*y!}jgJy>k_-2 zw=6syJQn^Hn@yBr=F5aSE$lDAMP;t*?RGld*)HUh-J&y@6mPs*K@Tgj56u)=`lUB9 zwJz{v2sqf#d=8X+(ao_LlxmMVx~^HLYqK>`ddE!~=cvOAgHFzbtzgs z*;Xi3>8UtgUg<1N_8(4eu7;2D_6M0Vc0R@;07t8dPbPM{oy?!}HRun?o;;S(et{Ncl(f~^!xgX{{buf}FHrFj^S`9-bq3DNVe?YNxG<_1JBNigfXNCAzN#+Dr#;$B;} z^^Am0^a%ndR1;WihF60J{3V}G7+W6;sWGh7K6K8bguKuRg^rgo}O;1G`jqD4F-;$3x&TC1iw=~Y8q-Ix-Y>e>1mqT!2M*Xx_i=VV|S1HN(i?P>^v#6WL`{smI77ogRkp79|v<8bstZOB9HymU#`ym!Lz_)ymNm zKoQ8|TV1q1;Wvm1Ab3mC!`oRtmMRygU&-xoo};2UVo^n~8g6Hh7o`64c8FcE==e^C zX|2g>k9yCzrfEvCm0^Oq4+~sh;<6^`u3ur`4UuP(V9`d>NJrZH)QI5Vn*%_F)ni%GMbI}eU zR|ON|wM)_iSvDKap{@*mR)4mj|CRuDLUJG0m$^Geh@vBp(yc~cRVj8g#Hn`HU2F}u zxH^@YjJA+Krb18v4FTY;tr8^Q$m$~|?v0U8tMpx86YfQ98$$36Y21nk7B&RVs#(MR zG?_KTZ$cF*dbEpBEE>s}e1yatu6!3_Xa5b2R&e)=iV06K=w#-&vi0V0G%n!YT1aluTC*r=u6p z$GOY4B5Th!3m>c5fvSmaAnY86zk_yLl+u%IDt34w@~;WEv>^XW68?$ zRBkrF#@PyjUCe{&^|+w|V|I8Qc{Lpt@|1!zPp$Jck={SU*{&41naPe-z>+yx1UeSh zx*;F-&d|T+RIi|aw*yND=UQEVwB3+jE9li+2jgH z#F@A}k0I%m@#O~o*2b47RB)sm9z|0^xU)I8*zka6!)T)ctL7DSX?>1HsO{9i%20Nc z8==@eX~0?ovpHGtCaMF^eYz6QVJS3Tr#CBzzge2E4RLD<#haXg(r<}P)ULTuBl;#J zq*Qi636W#1ooEXX8&x{*Ct9-{;AnsX+A0*19&JgicusVe!9Fv zdoXu0Dl5;9%1Ug=#m=cd-tx?Q>|ovz>52Cl!k>6395=*q$xBa>19aQRulVRc;JQ~6 zv-?>6YpOm)i*HnyvMuJkh8X#HxL9P@=OCO6msea^dkVI~b0W*M>zH+83A^1wKBP-{ z2xyVSp#nnZYF`%AmFED>Ae@icB*4Vw;uTigL085X7LtcEOV#CHy{(-K3J7QYfKKi)G&BI$^dz0H32PrACfa$3~Ow zV^bVQau&-P6QX>1jd;eyQw>2X_h02`$bG{TkBOjodOd?898DuMRr1ZwF20Gw4kuQU z`I?&pO}C<|s8NSgg_W3fv3wf_yvvrjkH8AC1KsG&?nsF$igbXj6`LY^L$rY5CA3VX zmxela{g6RBq#E8;fm#&^ZW6_mQ2!CutjkebziLL!8oSuFj}zN6dWZrmPvux72f);( z3$)E#7Zp=rPKW8?&`x?aON3C3o4evgGNbdDK6!xB+;g-SCOeCpNzT<<{_y_kF}{^P zEJ*;p0l#JuXzB?C64mQrV#iY&8xt3A4sc@*@+LH1{329){B*>#5~cF@QPjw72T*l+ z9ZKU(KE0TgLX}hm@tcYmvoZR-TzMm09kAA2=SbvSXj_~Tw}ZJ@dM&wzvf_r}w7LBl zr=bYhkVSaOGKKsl{%rL}2vR4uHCW$*wW3KDY|uk#x5l-JdboDyR8nv_J9|%ixbtE5 zaMSRf5nGVhKJV-M{8_QjUzGb??s8j9TMxqA+v!d=Q#_W@@Uu5F zc0`8Jt@B2@;_E5`5hexYhI*$*J;psz9&~qk1DHqbXC3ZZsdUR$$u< z1bb>b0oQC?w>P38jBwV21T&G?)~_h;@hx9SluI1FufG`pWD$sh8m2^WireIi2El@H zT1mv}GpR0w9x6$ccEi=qGIX<;9t#`UFTTpL#6|A|APfgzR!Z;U;)1&DE7(jDCI{4& zxqi(j7A?Nx(y$#2+C_;l_v-rK;(9W5F~75t>W-&rSCS2|)pipXZ&Ibf&TVwu?}uRV zUfEx<1>%n?L^+m7Rt2}DgaIpCD}r%Y$&`@1psXPOt0{bVG$$4=g%8G9=+mIYI;@E_ zUiGff5h#PV&WK;aNMrBq;K>yQK0Zg7 zP=aF@XNZLdO)MrjEvP9j?Gk<2%!LG$lr&h?3K6&qI5+;4L810NFkU1$XgEqQOYfD3 z*tl^ha&0;MwF;lQQIZXMql6+Y$npAlZNreZaDCBKSHQl8sjOlhu_;#Qi)xBpc*XLI z2xvcmY>*ic$E9-HRBs1_Y3B>*swUh(dJD-IQSyQ=?4~kSw7J&1hBkau-c>K&0AXJT zy0GDmy^&ghdZ!SfvQbUEWl#FYh_Z79%J)u)c<1XlC-@!|CNDd-yhA^e=kDQ_cw# zWjAyo;|9pr?v%oB+_FisbaVq^Whq1xocSszym^{pH^cihoy}l@-7{@Q74O1VKAX`6 zclt=|J~*^EMAAp^scHzcl=o2hOX+fkiff5w9N(I>9Mf-mNf(;Yn2?v=ax*O5nUYP7 zU30#=v?8>6ww3H0_a+lsE2D?=k%iW)bY z$-6MVTWfu;hr$PEbwBXCm#rJ4USh<_HX+I>a9Xf@FlPtd7BY6te(beCw( znewQ~Y<>)T1;BYbUqJWxE}dN*bAJdDYe>?b_R|-|Am}Fgriz79Ub8=PQie=m_&))9jGiR~&5LDM1c!?o zdB%GP7F5!pn?q|MgYgKP#z3DO`z}~w?&-&|XBz?~&%idGSalNaGpVBT zQsy*L$~{s}VrZ@e(Kib~rQ27zNSlKRD%QgX%a{Ea$#6pHyoCALnBWqLAhg41CyL=m z?ja@~FkWb0mI24Ft{9hBzPO{JM`pWqdBm^LenK+9eF-UP9+5Uj3V4X+{urq7Esoh@ zk(N?NUYjpip+wqAh$b?;L@WBsn=$?$ZF`h^@Hc2iGTHkax)Br7jwl+gTpl*9&Su-d z*Tsk7kr;=7oDam8`VAU}*n-GdrTWyUeQ4j&73ZXt&g-;dYQClUN;xG3Yen0!|I`5K ze$agM_8^H|XNcMsHUQU7K z8M)3GtCHZ@VuP%@KulT;vg)Ro1A%34#5*;szgC4jh^@p6;XX94!gl+$%Dt?K1KSk5 zA3rUxeg~Au4ngX2v|hK%6Yg)Kd{(8k1sRSm&*I#8`G$Sgo0%@t;@a(b-XZ{8C&yX-F&H3mgU~OhtCMnC>*pI`@cs3GM{A^^=d^^64Mxh8O zz1g-2cf*KqAq6PMli{T}pT?{33DOk297Bign+#mxqzZx)XKcRLPN-g5G!Ki!iqR3L zizt8CLaZRv(Rs+f)hr2i#bh>Iawzq3nNJp-Z9t(M&K#4jGvBoVW+7>Ke5*?w{ng+dcM1I(jIPhk*8%Ve?apZ-dU*PvT-hkG>B*V$bv8rP-R zwRjM`u-BqPPRmG|U2zaONU2zl;MBULS?hJv{Y?3}<*rzh=m6VM(ZenaMEW(UBbU(r zlChzKA?E&O*fdn`FW31dBuMJ~pjukX1iwSsW-+=HSk#hci7r6LiZe0#D~IqB|;z zdCTQ+G@Q<+IXG+-1R@fL3jgw|htP^hD0@aOZQD*M8E4LQ#N84;5)`)IB7(E}o0dhg z@#J*(hO2VakK}%y_1VIeVrb+%TTn4KcL5SLP*LSEjn|eR%f%9kFSQ*L_*8KM;@>|ikBa($V!VDcj`W<>&9xtz`K=)&lR^Bq#T_=mO#TZ)LYUu*}mKZIH1d>CmG!YE( z5cj7YWK$L&9e)F}Hw~>E8`ieOA&lY-2}83GPa+!)N)T ziiIx?g^@w3sbs&eiH9ms>t+g7UDCbPl!kBctt|XcQa^MqwshPp)=U!KWWnn0?hvW~ zK*|<|x#&hxo6*pS0c4GwvORJH#!3NYP=2{KMi6^%5vw6SvKkK*6aX-`r+ycJozB_9WylgSyh3 zgw}LFHSq+@hDkH5_(w%aL|-CxY_;-|_y9>YmJ9q=xk#E*O$EC8zji2iRmz<1WP~QTzQcH%N1cQ^hY$g1gr)GyLzU&9|VqLq7oAi2NJNo-b z<`Lt>(M#RuyH-$9uB+&{P$MoGO^y$G`B?hb{L^YlXsHPgfZ5%H!kWf%^QsWqt>BDW z8(VPzNQsEQgf&jba(zyo7-vUrOD(UxLl>ClaU7qP(3G9xKncIV$}A&=F*2Jm=Ke8D zn((BNq&gHNGu~24V2~Y>^NBUNL@&xNF3Jxlv-9EP8)>}dK8hAa({F?K2x=^?j90w4 z(7cEEhWj2{A%1wBSiPRVpqszs+i>BlKtro*pCD?r=92e`4L8~2qXnn8NrU7M5rii!$6N<43$latjlm!-Pk}X}>Sb}#Q^1n>x z5+z-j+LH{;4y$rxbW#B&J7kgZF2d;us9c=Qhyl*zEp(}{git!VdR->*-3L4jh^wM_ zBXKezbF+OkAHFeSAQu-R2lDAi4Y`Z@qe={ISFrV@GZHv9WlX&eP?r_9VPjm9T+eQ^ zLf+fak_wZDP*|eOArvqs7JRbq5v>Wa{L-SMxSZw`xVAO--GmF3$a*u-aos7m-Na70 zr2@f<_PK>97wHAcIjzRt0t2EJlJqI+PlenVmsqw9Sbnpd<99+!$}dRIXX86Zj&@Bf z#m?8|!MlhUUy;Y>8@uk1(|uBmz{v}g@+Ft39?!0?A#^~WDXYCOcO}UZ>S|efxk7`K zm_-tQLwR6$L7iOLXtk6XR-I&a{wiGruSS~^U5{i4US|r>_5y|(3)~?bA&Ygc9wD#(le(^tv1ee%$bZbx|c20W!nKDuM_(L;*5pF#ia z_;zsmFum?!>ccgC<}Ld3ic9O4Tz&ZqoH`^Y=0=+iR1_llh*Ey{ZMVFVE!~QJS4pNjL=3_l30;Syy$K55Py^B_~*2 zHnvYl$K=J$a8yhXQY?G`{&n`TTu-ltH<^a+QAW5KvR4$|gTncyU4AyKieq|v=-I^a zPO?X<<#IN)%`0{MoX#9W^i~VQ&Z*WvVQ7$3jWyEFenHwPEv|1CBJ6f^<9?sbvlg3& zMxju=kN6ysaSE|p8ZVXqcttGJ1!l>0070Lpp!v~EdIa&M118=O^<>j7i-t!D!tNuH z`TS9|QNk;yL$%;)_U74aIum8E>gs_X3#;dw?IqX$S{VkZr>gtgPQkJxgCLUOwyD{g zD;#Ua;(}>@k@mkv{b9~WjMj8q-RyEcob*X4!{}0<5CMCKG$wneM^RVkBU{O?89Y3h zu!(VdPy!N?btB3dHCa<}4`NMi-QH9`BIa3eaHczdjss5T;ncDFPQ_HKhaQkfV}5P)87J_WIRfH0pvVY;aW+p5VPcpmH zl(zJIw!qvWD96r#TpXt9<#fekOfk)L3K?a{$y#;g{va=*MZ;6=^(K53(sXu%5w|Jk zea@MG$?rmd4E>73w2-e*!PXjiX}kZM!${3SIJ8Z7Ll>oPo%9$-*JVVXWr~rA+?Q}W z3lq&h&L$Hp$F(lo!^ZRNBHt=B_OYVg%>l8RtL)$G4^Tg`Q6p9}CTpWSn_5B?ox2+2$c+cXqcne)~_azofwHk9u_8_w~u3u_i=(_68aU4}uWYPS1j@8r>o z)Bf2v>C@hqy{Dvn{1a;TSk5YR&R{HCl1Q89AkS#(O^(`0ENN+hidCtDoA5*A5ILZv zOLs{5+&sU;2tm1zu;tt7=flMnD`mm=Zom&&f-RiS`%j?2RV60d*`q?F2W1yuagYLL zUk-CQll0`7S?FD`2WKv|A@O_S88wuy78a^xTuSX$NGq1l?SiZo9=Mx75Ovv= z$)(^(iVB83KsTaN!>E`?tn7dZ)rwhKvO7=6r3u%QGy5)nExA~%7QnZZ$LTQFEAWZh zg7MSW&c2;;_z~IK{w$85!zT? zrW<77u%PkJk^9F%PY|sTT(6A|;hW-2a(%eOXo7Q80~TD15*k5&Y-4J2cQ&S0ry(4k zE@v1{NxBRYU-Dzlsi*ywi{X>HHJiaS30`B5htu2PLJGZ| zqcYBsC}}dZMd0!o?f86i73FXj<~U5ylXvk)n{fNrEwha#J>#5xf1;D|norE346K(62Kzj_gI?aOO%bQ($PsZ5AdastRoAzhUvGi zkeie0#!wE-)sS&f8=U0Bve%|!m@Txc67ZU^;xY(wL{pwCGXZ#TK)yuyXM#qBt3#BY z$HLWNlFpgTxseoEw?Xd!_Z9{!sHo|6CWyYHJmKhVoBD+F7btMkjr9UfYmx$@)Q*Is z8c%BL!Q$>3=_nqNb@Stu{b@Q|W)A=}KDaTngSH+Ne>z{~lkwlo$6NdYO82%NjPIuS zFnL_g`p-f42|cwLh502Y7Vf|9j^B z_VKRC4r}@D?{<9N#gMDB4{ZH`ppTK|i{r~8tyxu+R#;|2y`Z3UTk*qxlK0z3 zT3_xzdmQ#}e-A&n@Bhra-#&hC&%RO~zh{26kN-G$|Mqv}2<@YNo&6O1yM6qp!TWz; z-fthb8ovKugzx`b^8G(BkIVmNub3Qx{a$-K|0;O@Z~o;!%}?3KKWSfR9>eSRug&}I z{omS__uI$cp&R7<`^@>7e*7)`N7vuJ|9AeKyx%@9e}E^Qf8qE4E}nDWfAD|h{q}Ki zO3#-6{Hw9G^&jz+`~IK4_%r-s`}n(~^1bv^`2GI{fBRGTkM=PAyZZO?{;S`R$6x2a zmj7qJ-#-3#JoO9s&%Xb=|3TjO-QP5i;D5OdqJuI diff --git a/plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so.1.10 b/plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so.1.10 deleted file mode 100644 index 0ddc619760db1b0231a09856a6b147658faefff8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1747408 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%0A}P_+_$9Nw;1~`1Go}Lq*lRzOkbG8 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�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

FM73XU%g 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 diff --git a/plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so.1.10.0 b/plane_segmentation/pcl_visualization_catkin/lib/libpcl_visualization.so.1.10.0 deleted file mode 100644 index 0ddc619760db1b0231a09856a6b147658faefff8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1747408 zcmbT;2|SdI_don=7>qUhE@O>Ql4Liw$dWZh3W@A{N))p1OV;drln{y*`x>&gs;KNC zDk91M%za<|pMKw8-{O7^#7hiybm&BJM{1I|IAh+%70G$ zoqyi$pZk+!_~$tCAE_Tg^3VQv{&_ocIO0&t^v`jJ_Wzl&+5cXSKKI}JeLLdSh_}mN zXa46vhRFX+Jo+F1JO6#u5QMlUy7}*$^S=`R&(#ok4F9eFyj>4^yZ=l<^!(pRybofT zO#7Vs|8swa=ZFT{C_R<-HsTe_xIo44;cafUh#Jl zpC`m3-Y@YQ#OI9GvEv9lJT1iC?&{1)sN>G$$yAo4W$I>vM2BqXG!#@Ynr11GHt zo(g-_?vna*5=4WZzCa_N-w0u(jK}-*BfPEZ89}`r$3uc}cpP6C36)4VdrA;usNO@5 zP~!{e@vre*SRADXeX6QLm|Q#F#!wRp;y1z|J&DZxQAw&~NHn1YvtJG=DkfkV$?z=& ziSdaC_z{dz%(ZX$9t#3v^&T<;fy(1>vO0|%IaWx7j$Vy%-VkRPiVb$@;ct~h49oXM z6G)#3MDrn-B!pBLuVF|nh{fmQTPTv%#VKhKoRBe%2#JGfxZpt@ya=NOLLQB2FTkV( zor}T*5lE;cagnMtPS=d_>}uq)rcpQsdIA9#gw@4Zn<9)sl`R2;NJ2yVB~s1&aB_kq z_Glal*;#FPe2nd;D6xn!L!t{pNU0=Xv>n(g`yurFGwkR zcArg$ARahX)EF161>ub&@yHN~I$kOa6V0qjH6}sw zh%6(zg1YAboZUUGZOvCwPJ!1$4&YvCa$_+07|I}iJffR_4N=7*7~`mOm?QbLLI_E8 z5Wx~>j39}ZtvjyKXYAuyR;Oa%LC%pg(c?_u*@?MEnn**&jKgQ*v8wWog~r&H_E-{T z${?g#M0<#uiYdsN5H%dMCls${!<@)Th1g(7@C>QWIK#ut1o}2sVR{l0!m9&}Qi&PN zH%U~*gAl5dnz4G?Y-GkPNK1Z@qAG&J79uV9R#{SAnn~t@$$W%`hJlLegSU5LWCosH zBs7R5D3XL(7)eI9Br#+y^e6f2NXIngXi9JCXAD#?Qj8lmq= zBtL+q=T8j67P4dVPgdJ7+FT+LBJHsgr4n<)%OH547=#A18Yw7f6dsIKO~j-#3aXy8 zVaJ6qAH`EMo(xWS8G8;!X3yPc)r>2 zoi&Rg!IeR41fBMBdc=#fZxPN+pklRZPQ*r%cN1l%N! znFZ+($j2mV`)IXB2Z=Jly9v?8+!H{8jOdLs#Ssl{V@7z&<9Sl{GQ3C>#C$x`!iUgn zkQ9W#$2Li`8A$rri57%%z#-?JEcmxWh6Rdj? zj`I{qJdT`_faoCjN&X-L!jC&(ofsrV%VI6%iIq=0&2B`(a9xL?8vi1Rf^yLD;4m4E zplw9YkC~+-ktXONWRwC_z64xU6m<}D0U3jA5PTk|9YS^^><9y%Oygjvo(HXv(-F*u z5lM?0J-(&*Rf`G2Pj#|K7Csu2h2f&{=P*MBxAaKqDG?HQx8PYjty}mf3?ng;_{lQ< zmQHK>OH@Xod6JB_wvEMnc!6ac56{(n|@Fa3b zq(IL&qMc#L@{}J>r$M2uO3xetA0}J`S|m>)^2aHw=?#U=DMJg&@%YSZd}@d^!In8F zQd>$Sh=Yb88H7i)v1G-#;Hjg6ElE@uN@^0UCsrtEZ=$dxR$QAgv0oamArwp!MbOkN z7Nn!-DW$r*8Wf|At-u@C0KIx&?0OYIz-4)L)5umx2R#PMG$&ZQ8huG z&K`tBmVuX_PZd+hiocu6DdLY;pvU0~tm`oG&J5)*sVR?;VGC%;trJN^C~=-F^fX6z zF(%=VPDDhcC9MN#xk-*N(~PPbs$zn*3lQWd6++JefBRzlNfM_Bs)id$h#`V2#hyJ& z;>^l|&)>tyo`^6N?|B_8o8r(xeB+5<5BLIN`JqYdFGKH-&H<2Dz*P{4?yfdj^ZScE;tF~)Kn^GX4$uHPKo1xJ zv6vuP04rbv?0^dpiyLw`+T$Sw(4Kfq5PBgXjP67rMZsPm2E>5`H~6!JJY0ZsyQKrBnhGr$U+ts!l| zIdC4`IYPPsSKtObffx8)KG0u4=Sz_O;0iilg$xFvAPhu;-xUje96HBCCV}f96{Leq za0C3VEa-DU0Vo0`pcIsWa!>(ofl6=(RDrvo4%`FxK?5Mx12q4g{+~Y|!oCSKgI3TE zIzSg7Ru7tekOSZ;7zD$BSR;_nz;o~tjDt5|5)kVnq+66TZGem;f_i0qo#EixYNSfEzu= z1GyXE(U~7o0PTe!h0$IFQWS`xvjpTmAPEitDIg7GfGi-E9Hau;D?%y(WuO8GKpkj; zBjC@{hFK5Y=|dU-V{|5-cl?i@IG=#|B)T()v;e2j*%Hk&Xj(y913Ppk-u`#l!|ptA zK#w^>I-&jVb6jC|10KK&_<#$*7hDAX;6Ljs>;ln!C}bE22a)KGcz!h6$3Z55B#;bJ zKpMyZSs(`#fZtUJeGw=IrJxMl1jMR|&Tm(z#yn^N`2WgM?PH4J7x}m)Xq!;i37l1Fg2!59z^a0>1x(kB5 zhW5mBLZA-=;pi>`G7`jqSdakHKnD0-S2k_ONL zdUQuTmskuiGXu8&*mJ`y{(0W858 zUDx|@CLr%67U1Wx{M~V4}ktE2t;>5kk>#6hyXDl77!~A zG9Dy@>mVIufJ~4Dvcd1lLHj(&0#FEwKq)8#H$erc1b09Us0DT49=H!4f=8eUG=o+^ zEaH!vy3w9E_d?$X`oSQ&C;qr;1dO8d800hX9K1w#uOQ!ocj!C`IfeGb>&`+y|Hr)W zNB;@>MX(H3z#8}tHo-5j1BfpOkpgl+EDAI!(WHi?0knV)Fac)34mbf9AQm^|Zh!}T zKmZU+5Y2xlcwWOSg6{T0ilhBL$o=2|kOGH*3^)vkB?~DJh(8KcL3i*PHlhi%(V2MO zQRsDn0Wbn4;5aw|P6A?`g0uvu(b)>kvyisn9I!`s4vmy0qjLb7zt6h@^HmT8LO>`81K|K(i$$V942T8sAQ2GjI%En+1sNb4?E_do-903HHjJw~$?vJG^AF3=5#)r;m6H2Wc+ zqWuu$2pC0Y;`w9HKS$>mkgw4GE#w541RuahFb!q_vF0Hc(4IJdf_@P!gH`Yitbuj# z1N;KWzdyDmo{nJ9o&-%YNOFJ!ROpTdO28gAOCb8G}qbJUqFdqS0KpW_SV}MwOkjB6aoB-y4 zSQe0{z-e#>SOXhy77*(kqyySJK{^8$bS55mh29N#059MTd;qb0AuobU;4%mRf#7$+ z&%uyuAQat&L58D!6q+%RaUcOCp*!O3lcB#3(m@8u1UEo7$N{+^4-^4n6{A@Oc@va_ z3UC|T0e@B%%r&4E)Pwt=5fJME5@DjWNufd-+4)a^^4orYa@E#EBBbrl?b6_4UfKT8vAl3@x7qAA_(cK1`#N$7p z-vU3uHrN5gBB6rM0RRh#MGlDrRDc@L09vpMFaTmPLNWmsbY_EO2V8&$-QgkmfdCK$ zdjPRSA@>4tAc5}op(zP@5bdQQWx!z|2Nb}crG(DPkSb`e3aN(n>W~^h3mipv#M|pY zuM6~mAutA}zzh)U1e(PDB=qLM0-Od`z#5zd|8HfB9zXXV=h?w*|HsbZkKP&WT_HVy zC-4Rr0I@DY`hm;fDhLF`3W5v<*U&ix%`nJF5Dj8LEQkZ~APFRc6p#wiK?cYI#L9-u z1$pRP09go%K?x`YW#A?#2e&{aAl4noYETR6z&&suG=N4xtOsa5MDr1vk0F~tGiXJ3 zZIB(H6Lh0H;x(S2eIMiicnXHm-3a6}w0{Bl3hiG*j)S*g0(=0(`Up7#=D;FY1}k6{ zd{t!CLK+64bjCfoDos}R7Xs-^b z3ABL@x;qAG01SZAkU+{1Ee!>1Ma{B z{4P)Ey@4;di0%W>yaE}B_Qdny2eL>o2mzrW3`BrPK&)uU7_^Urj0XwmoD7))Qb8KJ zONYz^IUo<+5wDZ~M_&MaAt(aHpcMSBGU#uDTc8@;1-0NFxDOh^1MmOp zyou&*$SSn2hO7a1K`p2U_ragl0P}-Cc8{TNLFZP;PSAtS#M|{lKL7^75Eurd;29v+ zbI2Fq6&MF^z+3PEOo3@YtQp8zFbC$r0{C5@pkD@`!3w(n0{IQBfpzd5Y=BMh1N;Qr zUWiVBh%&;okE0Q5zM0-f4-D+$Z2?@TB9aaUcB*PZsf zp2}ps(P9_do=eK(&&>8l;d+Lty}R-cfz!b&tH*ZRvle%pAj_OQTDX%Q+{7=n+mh!6 zpM_9X(T?SYrD=oX!BZlTP%)5BAtpe-x;Ztw1*Uzm; zFWW2KQs7j~TrV9w7CXhXJ%f9A|5N3~^iw1LW8DE?Gz5c=(pJ2-k!%vmAZ*O_FWjx! za#Ooz#(QPr5PyDo%*Ha!H~z*e^wV=4*S z$sJl9Yc&$8z4c3wlFchjkIQC|Eg>WeQ~T1^mpM}5QR*5yY$3H@(! zAAC#>sJuYCK<1tI@aqRUVKIxkOH?8KuO|)J>TD_Zd+8b@$1)WCO?&lrG_(D?HVlmT z7BBf(FNhBx*BNaMz#q01iYVZvEn_Pvq6-!BXRgre$!)rYF;k-eBZAq0o;hkhO+rqEG%49iA6xr=Ghmi&U zm&;cDJKrlKs_h%URMdEx|9aG@Z%BUHLciGA;JZkA!)rBS8+C~?w+Q%#$_ip7ZxhF5aBUEr~^AA67KO-8-CD!=SUH|xw zJZsy$4mN2n$0arZNsB)J-QBOx=Oy=zX%C4?%$WNgzgt|EotZ}>yBZExRTd0fK79f2 zw0q>P3C?+ez1f*h*ZIO%1@RpZ56hG(%R31-HnU$;P@U<>VWs`BQLDUF@a*SzTUnCv zLVFSWMhV4{hU798$EF`wb&nJ`KBW$#_P3p~xv4TIjitX<@4s)~>17ky#TOlW^Y^K9 zKE|t!rHwV}uMpZk%m`|(imH(;?Bk7aP?A5WW0g9AO^i-938X1`&M+?H!hLa4_&e{B zHYxgg_pb!P&DBXB=X?DX2v*W{c)DQpV)Bo?eIq7#KV6=yITLf$;e+e5 zU2ifwk5dFpsCdX)2HAX5@*QUODv6%aPb^Y;fk_^1>Eb&Oy*W4ZvzzTu#baS@LqXh; zqnOptE2-BERRkBY1I8R3Cptf3E=nwC-H;k~<6}DAJNzIj!Sq#Rd($jmqlRRU-Sa-iX4Ikgbp;k@eH%9|rk3%-25(HVb^jihOLAhPPQ(sHhQ zLk(GrMWMxv;45}zm(q0>5F0{7X2)IF-se_c1W`?9CMg` zcPM#ccjxs}rxVz-6kimlNIaxbt%+?dEhrq`5lJVQ>mSeu#V8?!{+5pfe|V zl7+tHerWi|`C29!Ik{<$-X8eSPaPt()a z^)?PZDtGPq=yqxQ5`Tz#q7|9M`fc)o{jNju)+ATio5hz)Ev#;z@R$n@_qyGX& zrlI=w#e(20ie`PTdf}#1Ld$CEjl*9h81j4yLx;D_D!jI9wUzXIz3$Gvf2xf^E0?z*Ts!c5uyNp7dQtxF%)Jc~%D4+npI-P> zB&hhyw+LKm)BH3eXt1!SI5V&QSL(v*g}j8oM+W{v*6eDRrB>P>luuxH?Mmii_a4*| z{?Qq0>J*?@e1v7rrZ=PPp4L4x^+R}lr+VkFRa&Dvsoz3NU#PZTlC^A#FnRNZkygHH zb#n0uWygrm7rlGarC95V2jaH|Z~5d0Di3wiie=j$)Yx@NtGM})mN+4YSw*uuC#|R0 zv4!;cQ5L7(*t5#AmpU`tqu1A{#Sf4FYV1F7=dFtbLDXkFCXR9uSN?I$k12XOmep4# zYA>@8eix>_i6MDGjogbD$5%SOBwn8NR%jdTW4g@<`@JzYN`R(`JC+uTs$zE(^7mMWH6ux;U7dY=HC+l61JC8BsTtNZ^DB!o9*rbZzGo-y>JneFAPp!+EuHe)sL=E}bNBkqe#IA)I<9 z_C7@Cgx)>h7phku$&W-BD`wBtguf^(kUW;9#4FPD)s^d3{+EEe3zP0+lvyf%3i~Xk z69+4zaQs3mYfH+mpS#cX?(bSz2zYx>^-^!&+OI7Zb2H%Zz&r|iY1&II1DrnJ&MFU;^ky{YKHk|%an^3kA%cGJ%j zS6P>{bR+i-pRi+D6Y8+2KB{=iLeqSoeqj6K)?haIyA&N?d-e&w)uec^pyS8YFe^3E z(A{$Kme!>2!&$9+-Qk`inH@LYJgah~Vkxo0>^E2<_ANlRItidnOF`afh z{kn!OnXhY8*J`pI8B-44(d^2X7qFp_dD;Bq+dAhGj(muRRR3t6J4;M_VX4ZB1^E?b zJFkJHE~@?+d-sGyD*uE`4O{_be}6{(zTwzBD__5~i~9c3A6#>Vl$u8?M9V6<*{M?k z{K+R@P21&6narGxB#X@42+2&-((JBhzIVw;$Vr%Q>CsqAF8(rh`1HhC3%dnpn-L-$?l0GQU?+MvHyvV#1!flRoc< zE6jgd3l!2|+PB-26=^#MvqD9u3er!9j@w4*;>}Bq9k15v3@C2b%x`TbAB}u39=)@( zcl-5~_ZHWiV!f@?ZoZdO)nwbT#I13KsoTBjIUlFde4|cuaKpVY<1+at2I<2O>?>C* z$saCCnjP(y;b!4`d{mFS--}9^$?2@ZvZm>^!d-oZ)w`Q+CmeDKO}f30#==S_SE!AQ zeP{hEIhSorIzRPcE?!0fwSY>BVljrdiXqR;teGw(@n#MD^ay+NR_y(|l{(H0ohJJ6 z#%Uw9MY5SuJR9?a8UE?s{yp?&j9DsW?OHtje0l>h&!RId8!lgb)xBRi@a+XTo?~is z2e(NkG@YM&dI_{5`%5Zukspm zzBZ)~RSU7R77rf%#aPS4-8gHx6T!GtLeml9QThodu5+Sk&$5~m-6pe&jLb*c5k-2( z+N+mF_`ACV#fK#GU3Pu>LUlGR+cni7to*CTeLcz6XZX$MUuj~SXew_G3qO&lwrPqF z+@k(6MD8{A;XZEQ@|8$3d7qr8?T=40K6*!y)Du3i`^;D8;5=Ws%SX%Q1u_|N*_VtK zezDHkH-A#Qoi5bj$EnHD{QX-K#rG)v{p1%cQ$sR-8cWz`TaRjO?L7G<_T=b`scp;I zE>`CbjTs;1@Rq9Cmp1Rz7c_7gc^%e29O$+9evYPz%v}-ddEIt=nyas?m%}FKlFt^! z6RtZ8EJFdxq;W;hf3Y3!zo}ucXK?7b(X1@p-2B~ktZh2~#@C(ZQ8#>9#SA{+oO;bY zT&agob4)|y8;$#WcTu-(S)XvK+nCk0zID_|Z~dp%c!tPc)|h?g-}$~f#V&h%_DagF z$au--zTWC}_nocUy_GM#}qPnu>jbzNt>TZZ?{ zT)xY*&69mQRpy1Z7{`XTG5+0AjeR0h8}_$zukNT*)%Z&dbM-bqzUpu$f^~##y-NSM z$u#Z5!bk^sY>R?Z-Bhln30ZkXIF;IpJ=X;N8rJ~bG5q>Qnv$+ZoCc0e^)1KeSIQcGEr{#+st}z+iufdtRM?h9~S+j>bPmeJEr7wndHYy4$4pA`6mRo7B_Nh1V~@@+N?P> z4$THHw(ChnDUZ{#bb8Tk?ku;BzaahGPV#E`iM5A#oqMx&LvuX+F~hF?C)M^>k!*)W zl0BBN9{Rdz_wh09w%gXcoBoH0so@fVC%QkgM@Y;1{Wv8b8O=mI)Mviadne|w?xkyE zwKj{MpC3(Y25cYNIL9FN;j!sRNxGb$bt&U{0n5+rEk`|-TH{-)s$ZvAxkb`)mvx3; z4{;o+o|tXuHF!!%k@VRiTYHg;uEj_*>!51QcL{;iu5tNj>5B?ChjgxbPl|9tV2|Z!U*|Gp_{NFKT4?cJ_;H=V5C^RJlp%jtSH= z*p*~y^d8izv80T;M8B*fGqxG$xbK+l!>#Jz692IqhG%rU>d($^&JNOernD7rb47Q( zPjM;VN!`i1@zFUk^ z1)biH8`N=dI+nUN(Rb>iTGh}^E!ib^Eun%+Iq%DH50Ae*w8XaKQzIh2zoYk9%V}2m zHcnBpW?IeS2N{R4Cg%K<4sKt3{Ylr>2Y0D`t!>=ioID)WQA4*oW67{)wq5T`$n1H| z5&7J*`sdFJ=kB^-B!_C)^1inF^e14N)cA5{57JCHd~rG@FBmUU*&0e+A{ZHZcM!R8 zxKHFqfO+6?y=Fh$t-`W8)qkqOX~yXMuKiT4^2&5OeqPA%PD zMK-MTKXZgzaNg<8QQ?qE(XFEWdU2|}9Oo0VxE5+M$$ZQ(`L>??#DH1mWmg6%5ESAY?DN7< z2GG1~ViP=>KD&SGYjF9Is{)lb>JPt-?tHlVZfr`1ZDH%|-R|9oR7c0vNHGqa?wOvU&k7HWQRS=XaNyX>{3)_z{;(cuvDn>HJ@X6{#d zkbfZqTUvjbdl2Ij=uc{CwlsYr#vtgJ2~)?L#S0~DUgWtd#$7Tmik+PN@9brctz-7I zQ7#x^b$`KK<-ZtuuTmmy)|at__mf{WLw~~c&n)!J9-T-*eD=;eooYAB&*j}Vrt*LAT8EhjtB&bfZMl?kdC$iK@6VV|=(Und zz5K#4g`7h|tSC3)b@rWh{7xA+9UG;6&Fx2`B~ z7g!|;7m=+SWh)MCuCsjRZaIwodO~91L6`|yX2T?1N7s$3qG>!9LSmv`Bj$NKmJw^0 z)RZG8Sx*bwH1YW{uSNZciZ?FwyX#!~amV-J#gII;YiZZzu1QUB64?6pYJ6(3+}u{$ z<)N|Ko*sK3hash~pVxvmTri^g+Lpd_J-ORslE(^-945XG6p{PFE0M0%sP1_^HWH$*$vm{G0{{(v8e#X-V5g8YI(i&i5s8f2C%! zWajpd82?3UL;iE055M@57R9d%YiA4Mr8J)K6;KytmRgPlI|Lt#kD&?ioqzwtgK58o zjFt{-4X@52OJ%vC?tuM91M{W^?01AFW3|?J^2-y7xv#US{pg9Z3RNJPx*YK-Gu3X` zgqiP$?nZjyZQGSQ_-*lY^|@)AF=^KLP8LtzPwgSfai{_+-iFI}+|L=augnN#CZ%iasvvt!u4i8N9so z9ecm~cBUc2jb;h_g>4yr`->l?l6LEBxO9g{l=Za<;TRZta1lmL>8u)N1#ddGXW|69 zUgFog<18EZP@nPOc^}}&f5Hv^`C3x!T@B846bUC2*g!n`%&t8lOM&(QV0Y;gnmra{+Tx311|?UoR3#oqQcCJ)miu zbv537XKc5Bh1UhW`thFRr)$hc@MZF!mPYS=U^6K0rWujGtNy*E`c2JLuBS(C+c)}O%quZ=^I_QM{_&S51Cwwd$?S)J5AmL20l4H;VhRl&LLLndAb^duoAw%7J#}y;DI|jfd#&3wDY>Q=^s4&VSv;NIB2N4p(r^ zo0`06+8?SW_?D9?eEj}Z>X!)&FD&ElK4=|tD=!#0+SYIwV^Uh`o6I||Zg*UDU)y!lgCFYegk9gwK;e(+(t7@D*>uePP*KhNqxzvxQq`0qB^K$!1I%8@ zir1-fR(EdQ*nT45&#!Gb_Vv?Zx#|Dn-Wsx)+NJZwj}pQi3Ns4wJvP-h#~wjneUI~OF| z(8s3l`vXUk-Trafp!Crs8#n2Ezzk`-mlJhBQ~wS-25-%zoVb&7;7zuSYj9+mVG`zq zlIQb@5W^?o=V(TmR7%uu5L&9p7B(Fyf_D)*9z^C|%2m+y`SRZ0(^xpAsHu_D^?IhA zVRvai*TOG#e2?n0>6ti|w?U0Pb@q*q+M5Tx&+hf+eWxoJZ%TgJIiPA+;+9CdIWv3F zue8DpvOf3Aw%?TczPK#7VAEgMoj(#vpyF$O#y5lU7kNoqxO;B)u5SAHyF0D?$%aSX zs$8x-aO~NBPmfiSm<{a<41x>kK>G5iBXF0@U;oCOSH>>W+8*dbQlISd%Phtdy1I6^%I(WqzO|!yt zlQakqD6~l~iWy*&ny_infv058T(8q`Pd!^txmr^&ux(`#wHAF&tZG1iy)U&QWIWS11ZXZMM$@dAAVw)PX*-mLUOcCzem%exK@kvFSj@i|4nhgYQn}w_2U@BpIjKIe%`4#AU@0 z&-=9FeWwBKm8$OV)?XLTcq-o+dot$Wmf2xZxl{c&~TDfUv=0o=!1CdtwB;`q)MHvJTlIZZY2XdtLuW z+vAs&gI*ov$t>eWO3O-QC>fQ&-3t%&^fEAF}++oKMJldeBv1IzD;!eAF*1)t}R66Pyua z2zO$uexZJiy?NRz$>$_S%S85P#T|;LzBdzi>xEyQNt%wue&<#gPkVa(-Q0(BAFC2h z@y*j&RHQH~J(zf+(jY%#n%#&I=1qSc`8fsRp~9hXT#WPi6pz+<;U#9~&mx=74eMPcJvSfS4~@$t zrEmN=VO`ouGDCLZwssFS+xge~8YI#;J~e)N*X>TyYn?o-?k{g9T~6UB8q&itsnDYP zV!74Il%JtzW@;rVP{^8~c;vJ6v4X`NyJHVFiW0!2t`+)<0=a#eRto|8eo#`zR)=jQ}inq=`j2>d*~f`Nvf(= zlAxE`YYwUEA2v>~UzxF&X zUZ)US>ybU7uGxL#Xs*GHypGboCTZpyp-lrOcqXS94yWFJdu7?J?_YFzJS7OKw|0Vl z5k58_czcDBdwp?-d};EvXOWSQR%$?9N^o*fSoqbqHI(1NQ}!%1WtylwzR8JGK0MFF z)-_*12n2RqHU*ca1|9rH-nsuir#O?mUfqjA=mmdt24?VH0UZy%5y7VK` znR$2Cjf?S<{IGh=V}3y8QuOxlzP$;Xt6pQRkUn(8FyfwZV%;)Q~5~rVwfASOscDR@|i1|@)B-w%8w=5pgV$61oibKxvKGA)orfmMAMW0@0 zEO-2Tk00k98f#hATqAe(bBZj{i3KfdM=o7kzE^9X)>LO&axBmek9$YpnBTVaSv$o= zS8jZK;NXOQz)#21!E%o@nAci0KIBJz3W{#2ia1q}V2g~U?ZNkTu~Dq(KDe|+5xS#W zU%>8Y^g2iV7x%K3HB0gXM~td3lO;Y+LR5)vZfSSwvj6^Tm;r@Z3l;P9uxXMWhpu=W@tE`qm(Yp+ID)oj%3ulaq3pOfw^}KW3DkbeKV~1QZ|?A@BxTP?oR!ZjokbZd z@3r%`bEog`2}@miv-eftP4$m6qZLu<1+A-7Wsg5+Z$^+clBAfp8ZzIGY_R+gtIf&K zpb&oPs=4Q)V=KG&d8-Sobc%Nr4c_PYb1`-8$=bItYEL;f6LKMAZ>vvrqr!twJBz8P zkDkjkA0K*oreFJJ&-M8WTY7VAO1b538<~Mu-$m{h3s+DmpZ>)>c4+CWe#EX9B7BlR zg%po@Z(lt9;!qoB&Qpuzn6|cPaW~s1)a3PQg1ptahAytcxtGZU_D7j_YggEx;Wb>| zQ60kLKEC-y=xtuxE5V;~yx>V_pJ0QydC7j72?htx3)4c^z1zl{elCvgIq16g@)ezK znGwa~fyWgS?B8FazjIsvnzF~T^YN0cXfraF7v{yLr*${dTH}umy#6_IYIR0$?yd6E zQxiT(o2;Z{5kgr%7te3geqfXjcr~6rVy*HyI}hi{7xql_ljiq{=XY9dPToKFHC0;J zQ*oqI{Ilw^weGL;LKij8pSdO8%yQUYr=lR^{`V8Q)QP#*HI5w-T^Ur-mS6l(hHGAF ziDc5)Vc2#nee%TZmiS@s**#Bm-yFHG;juSiHH>K__E3?8$(igYLuK{}<(*XKmZ~Db ziagA-7JFvv#A@gykCE+WD=JLZ=2*#P^3pi|?WbUy>4=$wZKr}GgBa~;dTLBOMt$AP zVVZW|lpXVW=ptpBf6S|pU~T&rUXc2C$~F?`=YVTn8S+LEhvmnew~#Q<~LLAv_aiW*Ox9+AaLv`7p;zTmc?@MPG; zkd=?7@QuMCezK=mWcvD3ewoGbTI_DzY80lMBv;%OGkG$`x8)(#f|%rwCrbfLAD6!- zaUWh7on_(8ei$Qe7m|KG%-TW1-RA4oW(B=VQ~LFeFS#2rz9j+CoAsx4kl|R`U;Q^q zy;P?UrhR*V(mTZWSHJBpACr^HZJaDW4E&l-_F0=fF}HHI`E=#I@fzJhe}B>&1HP8E zi_c5(YZ)`|$Ina4(;IxO3?I`C`Ci*7O0h{fsw`D3+2uvz`Lg69ceF)qTE3Ih^rbZ; zwzE$tle9LEJk;1Je>yq4=l!E6Z1iz+J0T0%mm19@)Ymx6Xm*z9Z=4KdyQCFwm-ML7 z*r|{stul*NU5iVSPrE5~vbNmyR0}md4^}29dF*=H<#9QV5}&TfDIY$U+`6xoj-f^6 zPoLP^J@cEFK}-exz7KA8^QgSVRI@; zSke9I=J^SadYX2<4v9mDy;(#T9#|hK3sg5C%Ow9U(=spUHG)JVs~E2NRqy=~URPMV zBJis&bGC~gRc|O#6p=F8?kG$%#=N~<#?yG-u29{~gDGBS%5K{K^HAEa(8U_QQKuI$Vr-)OkQR}I$7bf+b#czv*MBjP=6DxjiO1YLJzx;Ce{)z0~U83K;lGbvDIM>yJ;t~=K znEB}HSf)$TgB=N@iNbFpT&w!B_H8z3ZKQK5{^_|tqj8dD1C3(qk(b4IOssDv`@G5(pM#a( zr_Km|>%o@qyFFC9ekDp|MbS9M+d!s5nTGyCjA^LN#S6Wno1+(Pov*;_%{BR>HTPdm z%9&p)rq(`u(n2RvxpJX6pT%^vtHsyI+h6 ztc;B2Z*ZpVr;e`@_!y)vo!QD{R_mPl{kZSaDcTM@eZxaIX`ieep?#NbE60jud+W@n zk5~wvr^rNZBZ2Q2vK^y;{~Oi6B^mtUA;!NPa5<0p>%K<_``5kMmA{|=?Hv67MSr=z zrQzSNv-iKeJyP%sjsA9>(|7)Uzi;aPzCR1Ul;&^O+3oQ6^XK3f#Qg1icl*DeuP6NX z|K2lIe?PzHzdSyRB7eVM3gy3FpYy+5-&El5=STdP>)fFJ`{P{nn&hvK1Ha(k-%ic{ z@;LC>{r&ABg zfnPTDxAR?1|9*bH+uzSWfc^XV|A(&c4tuI--d=i<5=D9o(tALZ4xx7ly+f$dgwTtk zp-G1b3J54cr5B@!R3S7eQi7l$H8cSM2?{TulyA?u@BOap+27go2W6gpW@l$+XJ%(- zck35-ZoeS6^LSena)#IY*_jW)d(Q3OZR$)<$s5k?t-EyH4)eW+VLslt=sd0}xt!^| zY~Y(;UTEjU{~m_USBa^}w`hWRokzcW2=$x8;E#&yM@|5Xh3bE&}| zzFRVd;0@nNwDds-XL_EcaE8~Hzx_rM4ERs>g3j&d%8SRG#&x@sGvBJn%fp=7$MZY$ zzrSI=bT!zMGKP6qHI;L}ljUHY=o!({8D7aS?-q`ArvFY&=YHQe%)3jkI^(H2OrEuI zkV~5!&V0U_(-}V5Fkj}#iz=P?u=5RPJn3sX^QTS)XL!Cj$sFk)WUzaIADrnqBQKtF zqVwPL&h2}ZcBa2dd1pMk4DnmS5Lcu(_~ng-ocj$M+9#KnhdRl3x4}MiHq7_-qn!2U zZG&Ix;aynJ$JeH$w;33b9VF1IthUNUDqCFI44PI$^~b8f%WU_UzzaqjnCA!m6V z*C37BE2YKnL6Q0BJ5?m+viw4ee>{7%T|0jld-6D_kxUN)m zmU{(593_T0_vjb% z!_NGP%S(!#+7Daj3}0B(nQtQ-Irsa4yj;}@e*<~(uoJvOYUlQ24C}!c-JQo(Z-g^E zne@qS2fv)f!2jijc;j=!d>JR_g_FGI8`jZPgfkyXf8-3WE!U4u_zN2Ja8PAuKKy2| zd-Du-@9J=8`5wyWjK88G4zIh#8Bf4qKSvqn%fIhA<4I;%znn1m@i|wV`FwPwGyXOP z|5D?+Gar65#J%a?bk_6U2EYH(Fn^D{;Y{ZmgZ7SKQ5M+Z#(t-sJS!W3LE0Fk+Yrce=h?b zugr5g&Fkt0IaV;};X0QyKXV%F;XH%B^_7={JMkgkYtH&szNIsNsv6dn1sXWxnU=>H z&%tZX`gz0<=TDQ*c{$NP#h{<740)j}@}U4HJUpb)4b#4RR@N$lGr;#JwLI@}j#8^LMKue*4Uj z?`mDbS>HZ=+Zle^u)omQ;5Xlq4@5ZeEoU)jzTGg4Yq^1Mzvg$=^Yey$_$Y&3O);$N zQ?z&HLji-{-jI)PIE{C+A)m8qpfev%8RCJr4f_b2WWP>&{=Px4{xj%*4#Rrnyg?7Q z8tiSNm-D!a%M19O`17Y>{XWjX=h1#=xxX~T=W`9~wdaO-taTG-`mY<}%%2SU^JPJ2 zJcSH&rZf1X1%`Ps*APGFHO%+XhCEvrLwwuNfMlEYv;Mzf$e-jg%*W=Po%Q6r zA>O!L)S1uo40`pAe3ZsX4@(;I1MkW>%4vQ*f7RKKZ#US1eg^+r!$472UF!_rZP>ReVu;@|8~jvv zLtf&DAuqJR5VxN+#8C-@-TUi=^E_Q zXvo`S_`%r@G&bme5kuaitwH}A8T?USL)|$9aZ*wDJb~w$`vu+Ag2-JZibuIo{Z4$bYUj@UxY{9+phzJij&> z)B=>@b{OxjsKb>swo1I+F`nKFq4?M|WuP!%prgOfbPT+uH-|dcUjUU=KEZ(c_}qUfr+$3~Ka$?yr}}!G=`1CLkW1kI^KCNJ5!EvIwF8EDqqZS` zb=r^*ZzcKQWUo>h^yi5of4<&eA3ihi?M_eU`O?6!{@rHCGfy@6yWmh~{x2}hm(_+k z#>s|t&}#<&UQRwT?x;V7o%O1yT&Fnk|5F1!s}1YWE(U$eZ^%zpH`wRj4SWv1?JTdO z27T}t;)*(k{M8jhox|6Lb=;qZeAMfPdf@wpb!alf`lzU3KRSmYZmDUA$MT$Y=G(bH zo&C-sgP$sC*q^FqsLvl~h-Ypa@}=nw_59Ned8$hW`JR=2+)4j$8}gG+_c+g&N?N&FJzqWM9)J5KeHO@1eP{-#(&pfhszl9gq`v^)3e4v&q_laTijsh=NR^V zddqr3Cq7g&oJaV<<4orOLmfzN!#Ze`!R`$)@Ht^@5?xl2=%Pd3Oc*HPY78}-sF@v7W>gudN zvkdecG^}587~+tN20QR-VP|{N&u}hsv%#-zH{=^z8}duT4Exb340gVSea-PV15MIX4M@c+$fk%dI_BSyz+E+@Sw0-4J3L8)KWfr@gT;|xHcWrW;p6CJe zSe)=rhsgJmgi8e9MwF7A_)FDDX}1r4i+;mwKTzi3t#L&!WwIg72_IwILkZh~_V`o2 zb5kUl-9B6#<4s5WgW`buU$-8ClJ8p)&+x;*?@A90if^T}So0{82;Kpnn{1zI6WWL7 zK`uv9;0NQg0Ka;8a0S~ZOAY>qtp`r!mx}P@3oQN5Bog_7N0y)2U#9!uTl^{b_G)s# z&#VUAt?~151@Qmu-{8NJW3QW_CuBY1CcpAPBW{;TE|yFFzZ^jR6Mkd```v?n!EN~# zUm&?HujspI-<0i_zK!-_>tQnaeNH}m&Lp$-;m{q>Bh!8M*G!&Mw&Z9($|oU;|MMn* zKT$pwS&r?;bO3(O0pL%S4nMfx81z@}4|)_oEA6xR;1b?-fXgy(`|I5d^sK%BdKwbm z?F9ObzW`!2-Z{5HXCx>3ZOry9)$$&lB6!t=MV>`5l!-U19>!s~1R{r*GXXI;Xx zEdo8$P9&Ar@Vvn9s{uSUGvF7N=O!Qef}XF*=izrir!OzyG7V*aqv~TG#WzErixZx* z0Px4#0DoKR?ZI}=eC}Nx_~X{&l=7=bJbULt-*Ra4{qkJ!)AJPkRB|ai5BSAS@S(Yl zO}=Tyc_%pUFbesu<7CKDtb`ovvHdxDPS&zl9Udi>HPhy5(Z_ER39z3Ub5c{t&V2VuOyD;Te`Z~J7tXX$x(Gx$@6?K`D{Jqe|R zeoA$+zbk%>H)cJYDZk-LA4pF_(gW)x-yZ7^`QG|BseaZ;MZQ^&uF6l%-z5(L_ZI`- z-m`xy-$_dce#ZFt;wbX%gXX~Rdzy4ylP|*F#;u3qNiu);G#{@nIE-+?m<&nNGLo~_rC z@@Hi!^y{%6d6b`;r#|w*$Hyo?ARivta?B38^`uF|VFq`|T2(e!Og zH`v4FnmwOe7UN2+#JH3mJ{tkP1#5wCYFsUb0q!MS&EFC?Am3nij7#w+))W24*)L{+ ze1k9(+I#XqPr8u*wPoJGqTll>=*dp_(OhUBcmwU_wzB=XKZc%!G&@u21n`72C6(9Z z+Tc&%9^^HPc)ra^`A$Rotb|{&*Qb)tp8!6B@XFmGNB=d9*Lthg`Z8|@{)qK>vHX-= zcK--_g|PpfnSuycw3SFFL$7Qzh`It*{s5bNdr?kgOYRY^z4r?Gb@S0#Wl!$r1O1`K;EYsn``bwU^lADTTLynBVoAqU zO4g5Ac2ax?xhTCF^Ed2d><0KFXQ2J%{{!?SG(E2q3q0T!~Gv1Iq5bYo9aCBtmNeS<3;R=n6ge{s;Q|5xeqJ$6Zfpt?zTW4Li`Q{S-W@wMz<=e@&J;^4* z+PrIK$Kg_2uO`*=uJ1x0eAz%xbN2i63H6~Q^r0%@Szc1^Tt9w9_*c>~*>S}v(9?|Y ztfSFBXg%yMznp|Om4T(j=dksFy8IOXPsx8DzxWXPyp{Tl-i6qCj^h#-ubb^>9|0fSDZ%I5gy-G?xOj>73jR||_{~LJ zzksXqE#Ko9ZzLmnRP!-d19&{v1M%`(%6Zg?{ynbw_rH6>?!~u3j&A$6#1)4W~s`qOa`>{#?4@JGef-6nv}XkE}5 zBt3Of&^}khcvalK_8$1@Ne4abO8!ica<}GtY%uU#C7!hnINl#H-Xes1&yzp7K~F)# zKdA~n$C?4Z8rRaF(Qimwrw=LvzZuc=|IBQ(cWd#+zIEs~J_&Rx|2S|w+PgIWvh8E& ze=%*H9-&?(c0;cQkp5g!(3Zc5KE}9Okw3-kbMew2m4dzcp6$Q-i+WWMd{+6HCdA`@ z3Op*GGp;z~;^qVMYJG9Y$9cCFdMn+o{k~MpvfXB5s*3}*Khjydi5wtTm zr@$|`--8?*kp9)O&drwl4768v;N@4~bK*nrSuTt0uS8kQ>l50%p0ph8qhrusE_3WJ zZ9$Az3q__pNv%n|N{(_R!0If0T;1T*3od-r(gBj*EG`#%#Z)CgieJ z^GB6sU9^Qi2jik*Y+s}j=~)Z8mnM8kEsGD?M5V0o?_uiyBpDc3e2C-%|CRl0)E)R; zjB^?i&tIn@$4DF_T}5~*c|O{bORzQgT!HXXi>N={pg(f^(*9m>9U9Wsp?@=<9Jq}6 zqU=nv*3{?Ulj`#|FW_G0)0BUFXva(0MB3{~{m}yHI4nN6j{~m!=Fc@r=UnvLlk_hc z1$dn68l|_r8UP-gkM^=`#{L$`iEZ)IlRGItr{4$MT?q5#J>vJte^~9KTAbg|-dB?A z-?SL78rM#?PiXCn+ytILYV@n(;g6+#v+yVAzhqj>{tov?JnVlH^14g-knM=yJk?+i zrxQM}4f#O1DF5}Il&6K?$NV{FlYHa;G{zfGhw&x+h5&2kh>=r=vVe_SAF#B?*l$GU_iP11;&+lf_~F7|90sB^gRAN zsh*rohWRorIp&M9^MmI>&%N!?Z-o4*-WPNx4gvpO8k8n-1H$G%^Qhpe%)>}SXTd}N zf&ogeA~Cf0F&-m(MDw!1AKwVh+~fMI8|{OKb{nG>Vqs_C30?s`%1$no6VvYZG$gf? z^#2+~yd7VIan&Jw>`d4t?+1XlB>Z4G@ZY~0`l;gcZCSZ48wz+Y%B%e}j;j&mn45S4 zH$YD!1t?c^j*LJb0x^uYE!)4^3-&Og<+YB{Pld(;|7-MXEfx@u7I%%K-4?XlN^jeR zU>{ssT#=y!=ydNz%Ymfl=vj=*pAF+x^DejsdgZ15G-Ufpa$k74w3F!uf}bQ)v>Xfk zK`lRXbO_`gNrQ1IyI?Fm1OMiU1fM4xvlRLVHhH^efA>?C&t~z*{~Z0Qc`=-MiO5!rS8jXR-z#&#XV(_+ zxg7DN`ilJ5`rT?N~_HbhC`N+bPO}Mx&!*2;uXe8iUnfFledw(PTS#&;W{L^n6_~}{;KFIWl z{k?sL`u`FZuK?*OJRJ5U_$uh%M!wyW^_bq%zjz4$JO}s_cnf--m;A}v0(?%~Pa3!UCC^`2dv_R&n>b8W&q+jVHte{p}mBH?MX!+wf0^rtEDgZM9?N4UVx z;%uMod%*n*K&M=;+TW|W;9taav{(Aj#jc-`br)N}=Q5nvuhYMaXW-jw)RXzFmk=KV z&wcjWyFAA0=Xllnu0(&(pEeHq)qLr=i}qIA--*?Oo`jbJzg)iAU-qliPc47m*^PP8 z?-1}See01Oczo{zk4$^oUu-t?C(ivc6^9%+33!@VEph=|ue;|0C@N z3ksC}WSc;J|=#{^0 z()m>(J>Ur~k1^HG>t+*)%-Cq3o3eu+&5W@w`j zwPilUlDjW2#;fu?Z%(lIDcf>Cs}=G5R2}o$8v&j$;bkh)KQ4w{Rq^BpAA^3cW;Z_zK3}_mxQi-33-J*&_fkJ zoH{_bw*ET7{U)!r-;{=Yi;!=X+3z^kMMSth%}RJBuDd;4cdPiJTT$B2W{5Ly)8QrC z$oP}_*ffkQR_>(Tt^xk2`CDEZc1w;SZ6ED5?qA0&<+!5X-{j z-41#Rkp9Dc!T(4c5>$S?a2d1@egymh)xI_839`UY&C{xkiv;7MifrFy2=IrV0e=SC z)oYbt=e?Sp_w527T(!W5lx%xA_Iv3)&?z*(@aA5? z!&=S$oa13 z-H~1void-l9sDdp`cK^hJ)X~jr$6Dd$AF(c=1I~J-exD@UX9P+ECt^ZgTQCC4tksG zzBuDal^1OkfZvH~e&?AigtqNl4(Pe;&i*D>2mbhM@UuAKGsXihwEDLz{b8?u)%-{| z?vsYIW4zKF+28+0fIr?H;7@hJOPvBe{ z2+BWZEeQTc%V7Stp#Be)^&ytrg;rR2hd@uT8(PZkD*L<0`q%*Tx=QXp?*=_#k(ACBgJ3t@TsNtC@sxRq zA2oegTFsgMt+yeUur@DT@1kGtci@APZ_NUL#|r`OBR^Ad{T|fn^RERFCq$b<-wLt) zxjoR6ep;Swormx23A9Ru+DGl-|j za_}Lb<-vYDOFm~zs{em21Af=Yr1O0;<4+&sPvwvL$aS2h&#|9j$K34q+a|Q1uB7(! z&=%m2eg*uhe(&S=0gr2Wq08iRVkhSHL5}z5KcH{%RN$MktKWYB`?E-^Zy7G@*=)b8 z?Q_i-On=Ay=xU^Y=5gq)ZvgaG#V7l?9u(9!^e#kdxiM|w7Z*Y2H^fu&5Aa_+fE|#_ z8T-rD3VP^gU441ZyX36jj%(}aJ+*;9sL{W^8sz9}4oXyBBE?bA@9z!zRehR=`wOlB z=&VD29^rmjBrV`MNq?)w)VDrK^9?E(H(Oaydfe&dujAE!tMWceu%_sjAT zf6)uH4-1==Bb_E`9QM6A1a>ZU*S8UPmSpz+(%l4UH0o>mo@LGhor+Mi$q%3pD{eov ztE54*`03U1JTu2bUg8e;zn=D?qztgF_OWWP+p?U){$9`?y19R?_}1ew@cT=kz2ft~ z6#*BuA(zvn=c`A6$F=hggI+M6c>qOd%fRsyo@!bLOITW9N!{bmPgt2 zyO<9FH-z{zKj1#rvo&S=PnQGk(boGO)>XP$SJ|BHk7WX%{pT^RvDCMFnV}Cp?R?+0 zO|;LaVV^%Io^dUBE+zo}EC15wRmN|(;P1R_|AABt%MXUNb7~n6fSz~d5zi*>^9Hni-oL9;F4}pe^<#mj1J7$f3POBV7JQ2xK|FAs_*-m%e@tj~IR9iP zoe#h_wU6*no};w%O|VX&0P%dtIxa8$CbUb4`8$Y*^$%*i{p5XX*1U_ZMO@UIcsi|S zywn5m7~!R4U9laoQc_%Ro?Yj|A{w2^u@ecHMKjA}f zK%WC2p?!ex4wb=Ycf+LfqVWdc2~7o_M{GYV8QMp3qP<$zY>`Z_u_>2VIIk^<$3C} z-qokoXSN;)J@IM#INvc}6z>OlVRi^Hv?116an?hYWWNoraemzZol6LB`VQiOIP1wv z5$=)qtXlIZZQ-PTGaK_23D(ssyYaj;{6ZRSKPAs=&>#N*$XBiVJ{t;sPUHpst!N*v zJcQor`(k77LcTsX=#K zWN(6RfjQ`RGwGZ(%$n~qe=-<&ni0<;X<#jV^Zg3B-y%Gfbm$g8Lq}k*zzreZrN8ho zey+>*UF1HgJ>Rz{?bp8__AR2VUkWon;9-71t(&ULfY!pJ(|?TX(6F`+-8BL9i^t$3 zdKV(kJ>c>4yl{|o{&fZNiiM#GGK{ppaC2w+TkW8{wERYghk(1d?=zhEbBzZ)#(b30 zx8%%MM47Kp>-5JS@<%&=bnQ6wC#c2qkE9-2_AQhQa=Z(55xZC?mSCM2tcpB;&;ji| z+aW<^S1YleM6jNuG3k%X`#mhV`*{x0O?XMxbNaWSUp4QJ?gu}^?J?4F)Hm03+C9x5 zNpaco^|1a{?E@Y=47i(h?`pok&v;2NUMfy{+U3D~&%twol8yG)^F!eAKY~8sPa)1S z-|IaOKI|r*F?POA)=x6e<00I~`XXOev{(H3jQcNf&HnG12mSH=2o4t@o>p1mXU}qf zNBQenE73l|_4RzVznl^B3baPQYJckQ5Zb%6yl#d#`0UDu_7lm_%RFx-)&s8mT9set2|E%)^obGbz-y_^w7ieEPYAm8o2p1h})wGXdsxmHiwf8EfJ3Y5OJ(UPYW1 z=?o2#WpDPkT)Gdty%r}7tj~C09_W9D=Aw_x$J*^%U?M6zc4HLq1hn;ZnSW`~z?U(CgIcYWgb$#~VG=eHq{<0QhrmJ0`)Z>&24S7rPu z^}&LBa=@Obba)_@KWQI=v=7SOrkxG^E=}&KULpQ&;QtZQlcfgd(Hu~s z?DI{T0CA$H<~quKVp9IMm-f?c9|9h=ei`y5`03H&=S(Nj-p~APPSP`7uCta)JM7c; zO=>p>o`iO9L)A{upV^xJ?Eeh-BfXQ-IfH(|N54>l{icux)}lWag}eq5K8|(TUe;-= zbxmQJ@3s6zEP*&d*|(qN0@H#gv~zh&7(av=Kd8Lf^vv)h`ueLC?VfL2QoGvw6Uard zzSK=R@5+3g)$i8aj05S9O8yUg2p5L_kE5Mz#`8z+t?+Aa6Hl?fpyvUeL+L~KE#{XJ zT7GHQeBh6D0G}JPeV>u=r|x8+ry=3_o+93hBnLf8Zwvkm{s*;lJpenIKg zV&)aU(&*3M5Oj)9L8q!$>2MMF{jY-0%AT)wb6l;^UT(+O-?u}+&s&_QIY>`U=3N7t zKmDnfbx)m)-!@==O{8Dz6Sd?e>mgYOUV(TD`Jg9J*597SuZcyKA$RdR0J}*~DS6J( z!tXf)xilsGfOM1=en0ow%MkxLsd%N!E#OgNS zLr|-e+~>h~y5%2y9(9wx#(Of%9mc@^|FqRp4}+*kE!`>IugkV}MlR2A>7D?JFN6D z6(M{Q#Hl$^No24{(Ti08k}F+Y{iAcOdwK z-;#NTnWVEB=v)kl%7n#g7|9D?WBC3b`A1P@V+=@XRf>tz6HrQWj7|ij`EgJr6O@^FNOFA89`=`V)IF@6^8efKNcbn{|w8Ui|(p^kKE;cUo44{)lxLQEB#j zo$*7=2mC7kKdV3N?OEPyr1&u4eT>(u)zvH-1UutD0RAX@Qr1BK*0<=_K7-tqo?OWX z{DOIVHD8W4WBV}LD?i>()?Zn1op>#2oG_MkWp37$NwoG?mHR$tG&>ySI>oQWZzl^t zE{Vd>w|#IMqUm+Oy%WG0Szcm){U?I{0P{`-02V7)PagRY?Z;8RQ&?XSV10#J7i^e_ zc@bxQU<=~OB-cCEc&E8B-Z1f0S|8Y5OKMtAP)Z9_-fD+~Tae};m{Wrh6>DueO*=zl%z_uT>LHyVK*Q1N8jbinU#2>f%{zC?fE z5gOl)2iTr@KN;TGU-jAG!y%rlRrB#@83$VW6DtV)QSfdH&_1B8>+|Nb>Vo7sBklgN z5f^B$egr?4v)>V!V7FsuF|L`)kI4HCEWU-l#<-N-yH}BZb3s!3HareIp(U{Y$B2La zOTfb?0hj4?`|IT*Jt;6xGZB8bEA%k(XHtFem!Vx{eWQ}^V4k~)FM$4g*>Aahl$Vy@ zD8TzDg8R|0+85}x2>KAx@(dX$uNZF~mzK-^rmzktQ5N%PbSl8NR)XD*Y4c)=%)eQF z+1&?pRwSM*qcPv3JdanB79rQcAU$GYX z_LJOrw&;oSUL#p{Wq%L8#dxE0FfN&fvcI|=L4QQcx99o(wG zjxBo<;kXpvUZWjLX!l4|%1Zl_4>NHE`wf0TJEr9mN);wOBVlLMdOuq#z+<%lS8?@v zsqof(bZv)SmD~FE_wr598Rj_)WuKQEWWVVkUnQ6O-xB``=vzb5*+W7)B&cFw5X zUGOu=``pwzrP?0!8`AbMGu4H@{iE53N^Z1IFg`EGels!8=AH>U)%xoO<8VLY@Hg20 zn3TUI7r}e9l-)bbylz~}>u&u8jHs3xue7_CKD#yh>Eix~pZiBDzG@@iPqFl&(i2dk z=5PMK7_Tb@^jYQErWOG`u}+{3WE`F&8`~mKN9VOqoJ|Ugjy^G&-pE^oEuJ-kO z($89ai|}6S)x`d(70jd%6IB+~r`mRUPcY?7$P{ zy;yzN@54pV!*ECF;qQe1%Kem}R!5iW2>aFQ89w@(bZT~^@NmpuFV8nMC;mtQ;E8R4 z{ZaavBPIMx^fL5E#f<~cV&26^0iK`p;u7~gMR$x>ZY$W|#~*^vZtZ;EjX|_0tdD9; zdN#|tDN8PXEkCy6Ir{Y-MZYQN@A9bnkXC@_V!xFZf}hb2;O9Bw|BrdRpq9rw)S2^w z_v)zq$8PpI*ChhH*D*iwlvxA&7Si@xo4Y`#{~GjUH0Re(0qQN+M{=2Ff44F~PkcSW zH>E#gnO|C^`OPo?fxJT6z2)o6!q0Zr;=00L0)J3DXOV?g?WFMiU;mWdu7KbJz;0$cC-DZX%0GrtoKv)vpnz5k7;@G zTt%VJkrLpiT95oN8hnUr^$*XMV7zh0b;=Kxk?RzTevh^;8zvRowzpc|=090?VYPq4 zI8fQuYnc!y$9uqU=Aj(j+@DRfM_j7r?`bK23x9z2yd>Ble&zkNXSMih)poRZX>nAF zTc9(h-9K4}b=q#NPOt7f>XmlyXj|qd<6QsdBt0KBf?V!v`nEMe{%H3eWTAcbY3rJ0 z(mq>qPmF}z-=N&b@Vr292Ka{AD#V(BT<=%FJiSADS~WqO{)jw(^fmCSy0R9ZV_ZJo?>d(Krq2dG2k%24q`S1gjEsNc+IfmMbHYA{wEc)B z%sYjccT($@qVGWNW4Ldn^gOu_a*R$uzv~#-ojeOZB$$6t@x!{`L1%0X^xlNarG?XsY3mU9E03D6Ml~S z^)1g8R`Po>wYPJpJy0KasPTziMA^;wkb|yN~h473fd6AndIS3+?aDBSep3rR0IByX8+@ayIB{#gzejLUoxt_w-VzzF3$bs za%{h8JM=lKogaB#4)b~};~9!qoToqXkRBBm-Tnx1soMwoRXlm?I^^QveTgO5Z%gJ+ z_GxzGEc4ZixGsitgg7-C{Er@nTz;c|`nV1XY5B~33n1U1mIu3>lXm72@cha^>b!l9 zRi2k=0{T^)+?4gZI_?l&_odwvzAVS)en{a~9AR zA*%GU{DstU-ZP-~XD6^8Td*Em$#D_uU0qte>*zk9C$RzJ%}7CJ{Skcd@E)hxluPz$ zSikt+2OpXc-Xwu}>W*Wc%IyIA+r6FR)%GJkwD+TBzLEQ4%HDqbJKFm*CFRefpXnDe zU|u(4zwIXhp3v$vQn9Ys`!P879osKp92L(BJSzWOU@+pDAkR-_Wc$09NdId|>FMEt z9dq;kC?&5S>!7{p1%67iY=1ZDHzS(gJamTmGbF`7m3e+I^ZZLm&*m>MU*cN6>s9W1 zh8tj9GF-90{2!vdVBLNJ!XMgoBl3MK?r*Aitk)hZ9+34jYa!p^Y@c=y^ug5te(fgV zX;@b;`k-I@RKCw9Fs^_LeE5j%vu&ikng%^-P5%5k5PBYc0~qcya2dzAE~>?K8D&1r zink-3(OzyZ+F!~t&_nM^NKlps+h2nB>jrslPWkKojS!dS(CU6u$~>Mmf8Aw3zq-HZ z@J6hseE%RmbOXKUL;LBW{ZxFe!~O1HWALXG+jl<-K18U`%HLi43-re?fIliOx;`0l zjA;IA@lW7Gn0!!ryW&;A<2OOS%CF|L&)dp-v9$B}bJ|f)(!yf5V%&260Pu*8;PZOY z->w7Zi&v9N^TTNG_oKbs4zRxs^s|2YS*35kjz_;f=8^DQ@|{Wg>mbLg#+B=H=!wwQ z_18k+XSg-^ru4Hr?=uYY9vHRm-pqVmNXyq1nG5_r-rJm$%Io81M$5C{w^HX)!#V3G`n}T2;zh|?@_EkI@7T}Hp;kBjrZJE%ok4;;FswL z`}_SG;Jzb(A0nQ{F^nrZ2;-Vh{yZHCzb3fvulRGSJNOypyMD?Jr(!-tKTlM*DD)(; z3kGZ``)#v}9db5Le&)$@i)E}Okz;DShm4jahv##R}j;q6Z;5n=11B(qMp4{MnJ@z~0I>zPY zyH_edyzVW)!*4@B)&0gBx?+AMc40&%+3$s4z-N!P|9gw)OvBvQ{)_GB$$4tc3)f}f zQRhsLG5@n$o2R3ma=vE-J++CaM-Xrq@3B<&x#m>B;ILWd}-egFXP*9;rEqX zO3sJ=cvzpT?C{aclvkFdam!J;P_^QRa5>;9K)z*?@w4r(?_uUz` zPY?4akiHNXBEaLGiT3I|{`e>0Pb3BCk;fA4FXJxcRSxmJ2^HU-tpWKS(B%8T-Zzwd zV?B~uCvLL$VWpH>fS(>cC*R%`i?$y}$qxK3Ab)YsJWAoZN#o0uTqZM5X#*UmBJe$IKscfr*BD$Dp> zFg|ZgdNOi-?JI~8Z6W+g9D1m~v%Fvw;ISy$|4D+{FQ&Y-Jo%|CXs^GgoPqJbTZ{ka z<^ugu&O2o%cOM7;1>cJ-PC8#{ihjM{W4>%A|3BUUctU%(*ZVc>YD3Mg9^k%qko($U z;{P~5`b{(iC2D`F*?*ujpxt-9sz2oG(dr><(7$--Uljcl?0OYh$IgALHthG{PUv}v zdamrrrYhiPuo?JYi|x<8h4Jd|I4`8$hN-ue*}mU<(4UZYuB!NWz+>9};OGvpd%>?T zUwRQw&=Gwu2cxj&_yXWaD1R|@F$?vZ=CFf_Mz3#Ls|Z9 ze@n-L{xI)dEI>M^aXlO7dhH|HjgueKZtQ@>mE2p(fY$QA5#Em^)1LM>VG`oW@L2Fc zio^Z}&!QZ8Z=rOT_E(1cvu?htsOb5nCFbc??Oy2H(?EYhi#I-D-fX_+U(UMGKEVC% zR_yoZyBJse2}TqoJiWA^mcNc}g`SjVT;0#!50Y^L-#M+%_Pe)XT)_>H*Lud)cV4pJ z?BM@Swx4kwa39~RRrY@~{jZn)SMg!^7RC=T;2F$$^xz@ntG@?*)B`)hcOevbCC+}-|~Tm$_co?F?)_C2`IB6yGeCxq8v z9yrK6@N0xO*aQ0AT3vK`TYs{NMOytpx$KB@4!wf?FBMn(Is$qU;ywI}h`+X^*V4}b z?}eyEcm`P*Y0c{>>$?=5)pFo=JjwM-d$vC|lJe#JDo6NR69JEE`L|P2Kz1BB2>M@_ z?Q@m|{vhu`QuE>!uA8DfSJ;Q`-@gI=M6~t7?^1y+`ip7vB6b?|=VftN-ix@J z_`l{kpn!G`C@>lRC93g1!To6cedJzWb6nbf>zx4bVfrrOaC6Ee|OtZA>Nq@`h{lCZ%ci% z?0|>obd=ruKq|1MCmwCx;rRjlcQ1n-D8zmnOoTqfSvTI8{ryd?5E9 zEq!xo?~`VrT!MG#ui3sxEzHwJSuju4IipO&F<$*$>7GjfkMUltF7#6k-Ur{@JO|f^ z{OQJhbKf1byi}$VNDMMe{j64qbN^259s&PYWvQ|SWoEJ&Y=&SV%ZIs@N+%V zg?JwG{9|wq;t*~ZiAZvb4>B&Izfg7~eM``z@2gH_9ju?{&1({WTAm-*-n_@QfoM$B_2EPyXX*@73-Fn$2@+?w_GoGVHfM?;qf^OS|vXFZXvW zJ-MZwmuXfB_~X3aPvtktWd;3#B9P-<;`jALd*9dTZHTH@TsjEw;J1LQ`Le%0#ue4h zZQYEbz0mxNkMB=;m!RLu%08R`Js#$N=*Gq6Yrx~u-YZ|a0eo<4_o0QkAK`9%zL<5r=j|dtplAx8}HidfQK2+DEror_5a@KptCFScl;Lg z1X+Ks=JnV1zMgysQ>%}9h5H~O=G$`acuTtZye zAgUCi#(m6}Cz{@N_?!Ct5E*+F&%FK);NmXel}OOzZpf?n8TXP6qAK^VeN|wWX+rQ3pD|5AYe&aE$XT5xvya4I!!F{n{SB&>5;mK}L?zCfD3D5dI#v9Yl zqqSh&nr8;|wi(-JI{-fTH9q8Q3;hYEhGgaP*8cvLg0SbQwr_Ig9O#dH2s+ie_?u#A zFL+Q`rlIVwRdt-t3a(6R|34!Q`bk;%WbresoxA*F73ER_a#VF7;nk3f{{Hn#8Mj+< z40i`TyV>t+H#uId{_uwF*W|ibtBd>eGs<17D|qWY@HwpU`6=x~g7!hlam*Il2c8$G zNP1E=#kgW0!fr37qSr}7{mcr#(13AB`}=4wE^@vzPB_sCah*%MFTFMEilc48hnDQO zLuusC16tit?wXi)pKAJfeh%d5*6evZ?ym*7zgC?1)2#=8^!KvU)B^qCJ{a#Zwtpz? zo+U3g@9XvwzBC8;7GhnoB*Xs3rvrXZCg6EVzSVmQzQwir`JwB9C-D>Fz`DefT)s1C z>9hZP%nP;d3m=C51bcvQYF&Kn2drDe#~~M`=i}Z4eoqMbz<#9Xd>-IWaNa5Y43&ih zR=b+B*BH!X@ zFNb4))nsDFmdkp`Mdi=)@f^)+?Vi<#8OTrVzN07dK(vJ?RseG8N;@`sIQ-5SZ5`J_ z8VXx3THSJo=g_z4o1iBj8RQ;>c^Be28oBJXzp}DU)v{wxXit>CtJj+Pz`VNBhp?<0 zx9!!Jz%RoR`%5+$_HdDQPwZxS521xWN3NvnkxrDmuSrt5|LDQIey+{y1o!p4TAuCE zRoe5fp#NWyo~7v_FTs1^6#ZwfgU>-Np8T~J+6SM2|LXis>IZ1=*XrWxQ;z!k)VIlJ z|Np?BPL$)`{m^Hz{#Bd8&ZM)QoPf4Hxq@WZK{UrcXe>E=F^FMjR(OCEc_&n4fp z#&}h{ck2S^k7)Os6}n9SvJd)z-xA{1yWmgYDfpwtJC=1dKGxMJ`POPddG(<`%7by; zU2BcYCEUG$c?7_sMgxxb65_gsgg1Ezz4CkqPG;nS+t}+5arLFfR8S7*{Q}KeL4V)cjqJEa0ar4eV7$ z`sMG*PapZ2n|K~F{`Y9{|Df0CU+$pan`~c6?!#L1x{?+T&*J*R%evp5Y+sw_XZ3e3 z=J9@S?=O(=RML5z`L~2NPg}~m3rnBltDz?<&$H(^=nQG^bTt2(daj*Ayjz)eTdU9P z^e_17*7mKYay=W@>L^;%Uq|S#Rozz#xI~>e&Ecy2KD2yvg|Cp2QpA-V$qT9hYnnUp>_p_qfdaAcf*jjW( zHNUek75MDEhJKe)f4UR}o%(sP=iEPCt?iR`*v5Iv`^OHF&SXV7FS^4X&Z4~DrXP=W zh2>XzCFH)jCHHuDa6U{t2matX{W0wMYQo$3=|>JhKi$OdlL4EhC(-lZkFxVqcVqs# zm=9O;w;=ssn0~MT@pomuD8_t|f+uJn;(Y&I*@vUOL8n*C*VQfzeg=y`e>RfNlkz~c zt^dsdFGKiF?nlS9ed^b8!oCH04h6p@#Ix}juV1TsEG8Y6&4&}=5}c>0iRbisi+&jou-}sMcB&*`Obc{da z-2YW|Yq$Nhx3^$#*K)jnR)*b+{}1-lO?tlE20jF}yldsyug@Ip(A+xL&j z^Pbv0A#>zG1{=S&U-KR7PkiKC7qYV>3y=H{3H~~CSZ9nU?0)Tr8g9Bf){Vcie zv-zmYt^ zuj+C~orYW@%=4@w{*WwOwE4UPcKasvYVig18<-6JJV^LOsQ^|S71!?Z`y)N*(cjnp zQQj+S@gc^1i?Rc2D?EELVB|C+($&a|0L{&+&!$fsl@j8X~*2!d$_0Dga45@ z=3@=Ezs3A*bSe1LpYT`qf_}fICpWmy65~FLia&dwM*FySUh>-*=oFegl<9n%4{q+8 ztNF6)Ys86m{W#dPu8tcq%UlwdCUA z`GPd$!%|zm(mu3?T&feEgZ5d_KJOvCy$mEQJVKin3vz*;U~kv~m4_M78GMLkhrV?u zp4vSS&lJ+)nNiX~Tlj;#uNYJb@y|>0pZCC5C7zjW84p|l-|7=yV-);XT-&F9T#j~T zHrhXC`-Kv2^Jg{S#R$I_1D;~qKH78X$CpdHdQ6L#Ztj4d3*Kwph$pzWtTyoUWCPYcN9 z4(S|F9Q}G&ztoNJ5qChpSPlEolkk~m&^|)_SM$B&CxH94d`?@|)re!z{}}PCm`#1= z``vF4o@oW*Tj7T$93#BI0r>YrTAj}W`n7)aYmlZ8O*?>Z{sowcCx~Z|JjY?lU4LJ@ zNEzruSlh2D%KAE&c7MounP0N(q?h~hUgB>s0elGXyaTu=#MitZCd~7yDlX0a1=`2R zH#JX-y+=N4`wlH~gZ>EfX`iv*m2zEcjmyt{LuiW-eW!uWhFV-VNfzeW^G>_ZqtMx+1Z1i^}ptrBc{;cl-{jbp0;}>c}&%^!Dz81rpu9Ul%axVZh;)%427CkQB z&nCrce>r(xFT(S5R|tQ66!gcn`@|Z{0zL~*v>W7}hkmWN447>{I3F4^m3U&Z(8!LL zxR>k4At<>GvA%XuBv z=5@Qq;Io_cmiR3p#?GO=)!s9zKE{%-%>N7nopnjio4>#=1$jP2>Dx>f=m~TJ=1P+9 z);DQ3`qkeDpFIxv1^J-xzZV2N%KI)F0*xrldsBV9H>Nq^slEXHZtWc6T*he$z9*&D zJBMXGn61xR{d20fV296Y`%|CG@mlTm_s6e~^Ca zpF_TnsXud1puLax`K$F*nCB(KJTIx@w@aK~VQqfBYzO`He~NyUKWaY=@Wc+l)p`6` z9<1N{vEFPE>D>Ay#^uxMPs-Hmv*oFE}oMOa-WoDLtIbiv-z$_a zr-dj*J@jgNSd00k!&AM z*=v6pWgWX^=i?ipIrpfyOB%yIhc)}0wlw*+A96oRKCk?Q_KI(wNJOpez#ZV>zJP}$@YaO)2?!zuKY`j!}MR;d5s*>eA#|Ys|)&hAjajn zoHP!sF73HBuVXKg!UxFvdo6fBzF(vK``RMFlS5ly=Vl#?pK+0jPdW#!_R{b0{EnC7 zn$Z+^{1=k;`}iLC@He&iM3o}By9;htzel<*>(!8g~N z;M?dF_`xyhD6M|Iyk}VL2X(g3kH~u!wDVK{us+JC`H`LzAg>NQUyy_SHf3Jd%e-zg z!hhUM`+OdDpaO{V?ruf_|^7yoh07nMK!;5g{SUk3-{lJ=3l-%3i@MxLI3;g z_j}e=3hf+mj|$NL;5^WIlkNW-Yt_@{{y+7!S>y(~JzoYOu6wHDYB>Qd`}Rch7k_cx zAs9b{Dj_~t13d|_?zA}j{gHV>w|3vimM7p_kmua%vHkfz@Q=Oe?^K+V$bxaX2Vq>Y zY|{Q}N5IdJ2lA5B-2R@HhuwDn4f~1T65?`d$~P7K-KS_S(%k}{7}wWw+S*?o=Ep*D zv{&o&w5;2ST?c06cP>l)wD=ZQ?^aVETFZQ+y>4QCi^@ynI0AaY+_zHmt~%p{&o#fl zzarwX=wjH7A*AzgdGIGO2lU)0yh~cz)z+}9GQDGedzhDwvR(la}$4xwMA4B^a00&tX^HF4zsZt#5zZSik3b1Uh9J#QrAnp0qgc!Bh5O{Akb<(aw$jDihH*{md5u zo6Pet4$qeNAfn$TY?r4}A^n|m39;N>)mXRLq-Q<>II9}o}NBnNW1>tI5H(@>`pv6nq z=@-JsF6{RXuC?wj0y4D$TGvhyjIqrF>O_nrHScrXg0ps##0-Zzfml()AUYL12r6-d=g};lphrE7czw3CuBSJfz zlkkVEua2>Cf}ZdZ>!k;5aZ7P z^TQt!zKrL3LacKrPI!Yyv@^v(&wGS#UJw4bv^>nL5}-de9_>}Ws9=7y_wjv`ro^-O zRrrN)N?5!>jDH^S9Bbq+_zSiFyLJ-f+fS>1u62X*;(ehX5&y(GjF(n}9+d~{X~#eE zUJFe>9~U7114-%sb|m!YkfuL@hG-w&i1w-uq+VIj6XSXI>!jzep@`E~A3)rz^s_GS z?TPZ<9;%zjw1WK9>SIFE9eQ|#{buHT3~A&2PX;8`{Pk#YeuaM__h2cE zOS&_B<_l<_3%y_MY>t<^nd zegHoBEgL64<#!g^aje|m*YYRp(*)PX3Nji7%-?UTt5pUu)p^Mw9BpyM;if z{{C#}ALvPf^^FaQKNHtqKJDCJHm)mgY3~Lu=K3ft*GD;sr@9yMVS@LADLvUf9sQ2c z_P>_=Mm=Gjt+H1m`oca0;;;|ph~LdRjhJ???{?-_6WaRs$pY{*Q~>ndSwg!o|!)}c=X;;Uk$$0zfyR(!bnKg`p9g!e86eg?)R)rb0XFz*EOOB>k! zCF`uBEx{k@j_vPb#xpL)Gl-gmIL`A*ZY^$^$NRX#+I?IJsh`W``sj|fUdYQju}Zv; zRPpUIIUH-gd$qjWddkbKt+P_uak8wV;5(;vNPlwLb2sg|@)s?8G7d>VE~P0Ke{%3G zRvvs)er@PI*cng3q;_WEHQ4ze?^W=!-<=l#&v7rQ{meXw@k18yS?PKGjL`E?Kj@W; z+rtf!2N+E~R2!ZXzA%QF^$v z3&xe;{Y4u|=ZU{zXI5+W?PLqcH@X9I97j6;*vI@H-=nFd@Qgtm7~cg8wxtMu@L5WX zH;@c+l*?87^UFG9Yd#j!-og2B9`xC#<$-^Z`vR7p`&s~x@(VM#zFw&Dt?L`Wkh2{07ZM8R~;etJ51a0`tO~9dUv*`}ViE zD)<(i3H$|!C(}=$Kd#x;zmGHj$#Xr*K1}Fmy>FXaxO>2^f~!K*{tS5Z_gnLPN4v`V zZ`FDyYem4l+B>#Smcrgf`JVDE(wVm!^>8WlP{m`}xzFO^K8woF-{d=7`a7_n(4Gjc zmz6!4$a_Tn1HflhS2pi2$g#tD*d;INsXUANpy}rU=9gSt_o+O|gb~2w)$Rd!zLxqt zF{wT`tLi-7ksX0YXnOVY3*d=Y1O4j!Y4P6ycV`ED80qiv4*bi1+I)Gf0osfC(32qB z?<$D#hP67k|6Rhoj%eoxOY_`TRI_`_?D}4LUy63m(#Nd7jWX|7jr}I%KkWI=3mw&Z zAypl&U;MCas!rykFF}9gJ@E52>i>NDJ2&UM+Aq$_`UfBDA9Azb?k9mKsNIYElzuHh zzt)HC&m2U1AMLH&CbPeCasg=B0k2ly^;0U+{~G95b}VSuiOIYu&#NkZJ~st?h-&x0 z4dQ-ZjQf3ZJJ0?yPQ*M4@;!95E*swoa?eS*r$%!z_5l5qRtMFV_cR8zah;^!_q~J`k(drFkeJ|*nhcfx4#4ZK+i4GqvE>$(tld|pV$FQn~ZVS7gA9zc#M7rT$1k~ ze+B-8wRPpu-iV9*TAW{(^(|4>w_p^qyktD^d$qXw*irDo!+EOOcc_5&`g^PyH-VlQ z-}!AzetvWjeDL#Ln*XS`x2__u72~_i-PwK!`5(>-{?{aYyqo;d-dF9s5dDU*oZUddKN6_9K!+dW+JX3?f@8SL( zyA{_~V_x`5!GEbbv7INtpAhT!igR3p&!fG2JK8IMROlr2neWCbd%LzW^iwnff8_SG z{cWNCN2&ikNoT!}Ag^#k;8%EpD>0AyY43;?e;xQEd4Ycg@pwJ~9=CSyVj9K|{yo6I zj_tG2j|lCY_{mz}TZj*aTwwdIw!f46R$Bh*c6Rb79r%BYdR6-j=<#ZG1-X+!USYmx zs`&g}75Gh|?NfZudVU}4`B#yisrf*spj}dY3os85*6uBNb|3wUXP{HXIaBQVSm~#< zdVou;w2x`$8iMlttmStijnTd^>6}`dd6FFPgW+WO!BplUquM(K`5E5|#)0fs zw5kby3hn;A^=$!nQND`)BQjl^F74dzTp7n&abuk4k=<;cCLQ{9zXH8V zlL9|T+XMY3c>nfP!V_ho57%fUCg@(?`McpUh`H#e}em=nQGlS z@Ei2&)#l3&<-xa*_6~@T`D7RK$sciCDJVxlIV%6&koSotwELiT$O&cFb+9h9G4TxH zKA`???EM7oNf`RjpY1DFf`4&qdCu?pV7|Nf-UL?VGXEe8)hs>N-&JpQi~cSr{I#l! zTl+rv%=ZQh~8vk7{l-WMo(4E_4vfgSjh^eLlfhNxHCdA*ZTu`N1d>7eIziRU!uT~vFgqZ`+Kg6qDD#9y2H zfciVIQ$Gj&QRY>Yz710OMlGH!x(V%rnx0?&2K0M)-)0N;JN7j6s$ojlz11{ir=NrW z`unZV76X4+%kz9%1M~NhX3w*ir=IZLrCIFv%XiTJXRZCrRG`yW7y7C4=jXo%JbVW8 zT9z}}-%hTl^!H(7%vXe&uc*QHZyf?2{TKZH9)Ird=vaxw|#F50&?cS#tMi z>)B+Jk!J`uhyJMbT`}5oAMH72hY*FhAMKuj`HoQwkyZ-Y!XMG371~{o8f84-&nZG_P2qC-u1s%2Q907j6R-aRl>s$}lxhg(?O(qO2KN7tKeb`LC^`X7>(B3M2{&5J{BqfMU2_Y(f@Pm=bT zWNg>gZpm}>EqRXq zGztHIkZ}=jC*mUhvtMR8^X~6timCI|(eGrr^!6n`S9XBU$GAz3eOTs!?o0T;{;T-; zEve5xme0TZXPDn^eG7Bc|0?Iw~@9IxFa$oRS{(PA{@O=3{<#}0?@pxY^;rz>AVLA+d9qR)y zFNmKHN&m}R{|oa2#F6;f-skm_yr=b_tugKAp!^vw2(!|KBS0&-Z-`_v^}jUy|qOTk;&O^v1V8m*?eOStsXX zlpg-anGPS7aouX)X(ADZ@PAv@OK~Lp*M3TlD{&v06&B*Ly;r|M4GVx%$#~v81{u z@%f~bdvgE6+YG0*&-D3z+1`90;mG>EP5Jzn{xHwWo3hTi%CGsea(^5q_Q$(_k@tmR z;@;aMY`9{66XR<9Fyr&l-_Q8`W!djv_-~j#?|voE3&O_4&(0eXpF|w{-~7FD9%a2X z#m|4^O~&VCX@BO`y0-RPe}MOwm;X~-PxuvO7yV)0H_zpKZT%a@|HFwo!{#4h`2Rj( z-~LyR`1xhR&hQ;y#`5H?pJ#cZ{8m@;e01v*m=nHJ_WJ=$E79#%B2M5Fr9bN(8K127 zg+2@#&nzkO$4${!i$W60;uJCd*DJ?u(8 z9Q-uHfBP#K!yl3D-}ndI{#HUhe-_w@=5Z}CkKZKa&%23y`LBl_OYL9!T;>O5PyUI| zV>mC#`;S0I@$-%EGTmx_jrsPw<$C#pR}80>STEm=xN(wK?~NJ$=SX^fsyOewZ|yyK zFCMRswY87_A@291i8_Q^P}m61cgNhX@|*wS`Z)68|rKmEpYl zi;T~olh1$iEByS;clkNb=Gxi^r2q8R9>Y15?SBdaitu@_$8tmIS0DJtte0LU>Noxz zHaOC^|7k)mdcX8nzLm)D_>>0AjW=Z-*N@14zhBld{^(aQhP=Ah);{yEaQjxGe#-}6 zV?EqW_|rc}%7Nj>^LUjU`2HVdzIrLKPkmKi>RsQ+J*xQmkNyVMi<0-#{c{;td`tQh zm45Xlr)(b^O8c1F-+xl(7r!U-i+_(C?~ng&#^=pMe&~n)Aw-WcvzEApV-jns5 z?@9c>>@DV#R}*^0kAD_Ff9Xk_f4<`>$#cZ1`n=DobLHz_!uZ!HQ5`=Y%jmA%eTV7r zlC-NRd(_bna{IN!c;AqE^{qty=^r~_eAfOV;{&pYpU-+C&)5Hk>F|&E@!G%rB)RVX z5%b}jAI~rT=wE00yqk#A_$L96>m^ygdRM~v)US}^mG^Mnm(M@ta~S_yGA>T>`9J*! z-0zzKuScZ4h@bBFGXC#KKc-rzKk+S+&I$T|k(7sTC*NwoX|u5kchj+{Qe-%FNP_8K3T?@y!7AkxRn0?g+A}^ zFDK&vAAJqWlMhS15!gqw-fh(fBTT>dFx}CKFZGg zDPPX}*GvD5B?*?l_^Iu4zqNnG{P|b-@!GHdL5Y7NPxd$dTh{A-DiLpa@(#m!FL6$J zv@Yo>?d?i_e(RgOet#;FxAKvI`E%;t*h_~0s)saNxPil|DTZch~B!(BZB)w{QUN> zVL9-2B5wa5ek|;?JaNKV|;#>g#XijpZW8xgr4)o zn~cveQTO;GKgsQr_so9vpOW$?5tnuLhk3p}n&7LSmht&-{tQb7b$0jdY z{$EQxzx@3S=fi)M*L7Du|Dmsv@?Y8+*5&hy&*%1U$-2`2gJ{RF6q;fb(p_Ew*T+HjPYqD z&aGGSy!_!r9Kx~U&;N_*^V1Uk&wPWFCyBVGe-8m7_KSo+>+ij!$Mdt>yq|t`BJScZ z{kW8GiMj-T?`tKTL_NJf|0jr_v44Gt=j-R?ct2N;_f}%OU-Zuy{xIPm|1qiWy)Erp zO3wd)tb6lzBERO>pr4Rl@s6~w{xY-0+SmODhJQ=i)xSjI^CSNU)93AkJm3B%rsu5= z^Ml$SNp2B6-;{QBUiE8hN76ojOXjiuUJ3uRq?~+9%E>R1&%fa-8U8zo`-^|>H}dn^ z?_l|Zuwn7@bq4oadxr-Ew}tq52!12}Y$fuQ{_Y;PU;8C)ulV!eV_2{L@c+p>3znPs z`3rx5`Trdm=Zx;e&u0!Kp1)b{%ksJX{VY#Dn#lM0fj7C|mt;JlB>&oveksFw`xkgz ze@epnu75A(YT_QWPlaAY^Y}i8*OxEx{5n~$^6kVq@wa{~#lwK#zL)v!w@diH@$(s< zSKnq#lzbR&OTPV|c%7=e-8W@?)cfSVsm>#B|8u6#OK&kge@w#vy{{AfA(sZ+?}2=N zwZ-)LghbrPZ-OI<_~%_&A3*WXul^l5@A7=7&K>XnBfO5@miONNw-Ubjb4<77y{HeQ zf8mzof0hz!YoB~3>G?B^|My6GeiICFWZ!#L+V^S_{@4FL#^>Fy;rZH-&wu0_8UJA- z4&jf=x*4zjGQIcEO+*AmaK?{NF~ zWP5(Qw)V~M=Xt4pEmQInKZ85|x?g2Jf9r2C1wJa*(MQDj6!m!$=d7RHXZp0{zWm1} z{$F^D>F~ZoNr#W)7oYb%%s)dJPp<5xYnFA^_XgG|u>HWY)~x371FP%!&Y3$39RK*i zUe6mi$M#9j;dlBsR_D^TPThgsbKgM24;^ltc-|=3>^gz%_Kc0u(CT>OLEv<)6MN)r zb)8Y*dsmGMYHQRlf+r78UUNFZZM-x#_q<*YzZ^Li?#T59qsCF&qlWj58d~mo{k}cu znzg%5u-CIkqeHvzGy&U3_YCpA?0$5GLG&dSrg`QJ9N+C&j_-TE)v*KT%=53-2lzhg zJA=U#{mfX8!#8Tq>tpxA?m2^?;U3*TY}YJfL$>h-T{plO8)AGhv@_vIFf|3H>onYa z5Syo%4X3MXs)(c?tXc0mr}nrPC?bS-Q?KE4$LMWrx+6=G9K#<2#YP)jSk08>4#1~_jw7g51jM?WIz0p}n;7OO=oV&-mpCl(Q(#%>zmV!^O>C-D4-CnLwdaD1Z8)$6QM(4JVcf-KP$91gpjyD)UmSKroCtmleiS|R=Rc}WAVrd_?_bu)UvcjlM1Wu#9Lo1&|h+6pAlLr?bc0-a!*qH)nMlo;`$GiCX z)id8SJi*s&z_ZNov$MY&#+eh~FxPW%HfkK*ZwEWU)zE>P z!Q4b@tYl&67xJn!_Z6;;YetAwFO6$Pj=Z%oWwkWyao|}e9Su*o5;?_0xu)+^2eC;vHhsbT}8cjQK z6F_7?QKx^sIofTs?ssT3iLim~=I9tkiifA_eJonQ*g16IyJYvV@L{T8fx%NDXA{u& zROjR%ox~=XwdMf+OA+QUc}f!d(cmfkqt=l#8uuMSPvfdHYfeJsiRfPRvC>+JRZKtl*rq8{l^qoHOSO-W1U=Cm`B@;s`qDSdbJS zgU{9Ph-J}*FPQr13l&z-a9ijcqh_h&6IJwZQbJwgfbg{riFimu$ejh+iWS`s>egd3 z8N8yHw?KzF@e(@Uqp=xk=ZKRa*>il%Al{%eydug)A_~Aod!)Kj9%Xk<0JrV-*+4mMj^m>TLQ~56=?eqY<2g*)HlsUQW7dY z{OmX$MT|&*N|l90>!E|N5~%M-{r+0t=`&5S5O=~=;hm{aD=Dz`h~}_r4AU6*#Dz&Q zX2_0XIzC4i@~$dQNz^%p`HkFxa9ol*CQ&aUl$) z(!gtT0eqRz(hK1f+e0)sErLtR!Hi>AXiy6$bgTol) z_|Q%u`=1lcn7o;Ssl^0lT6ZMF$;2q3-r)$whaNK12pg^#e&Hjgu?4dPEX(~iNYQgB zez?(!XyVBrW14LOz6Cr+Ue7U%ARZ>ScDuvq^YO zsd(WmJG!wU^B}+;$X`HuK=jO9aFUQqfs-)B5&O=mNU~@m;IGlRIASw?8V4Su4GpUu zY+FYsI66B{vvprFy)@V)QW+X5dig$)B`|8^f&2Q{k>SpUrS^WpuZo4+Uq2LDo1HUo*tAB|?Ves)gaC;+#B$KyV-pL~J=i zg-E_l*2@$Z7XvJjyD`j(E%X7BT>?r`aga%+7KTU3OPeG=z_Z~(gZUW8=RV~_#2ynX zi%sB0Elix5AH>HkmSdy6VIkcCTZR-bmWwzkC`s!&ZGrX59wWyW+!%! zl6_86XoNJXqnJ7%t;|{>lzs5O`&fzh1dI(hO`|3!XdvSBo|KD?bu4Zg&8%>?2u}ZU z9-t&j!t{7Hwtei^9VDXpjx366|yt+CWX3h>1P&TWJs5&3}98XL|9x!ft~ zQD_>+&G>e&T{*%m1btO&*2PP!dxZo_nEEtDEaQ<5Z3Io!B}{maPk@8 z+=5{7a2sp6IK@H58`4e&BY5AtfN(A0`ZG4dYknn@sB54d4+w zL5|bGj!(JR zICCd`ezXHxhH>Z}Ifx~4R5q?jz#qZEN*<9hav<;eZg;l_S>p!heZxc^W^*tciwsr? zlaOX7YB-L^(4CyiyS=O7`M%qOJdEIHqJs%QN|t>%4gj&``N*pdLA1Qy6+sT0Ql2We zlmn%-*=CpgGrPWTS0DlPr6rg0a;41)h%lLxmO&#Ds1h0kG~$`8SqI2370RHJ(y=%# zI@~2CV^+55It6S^Wt#$qN;#A1ruDpZQ=N1a$f%%=X8UD2_(1yB!-E2TrQokayr5%T z2bL3`XCtcNtJ7tQ;4d-&D22`Yh$zF3vd$C?S1TczAfYxvcgre}bX$N5O-Y4G_8n1$ zPQ$T7?-$dd7l^Ej3}EYtb0vl@4KDIvtwwoe$d$l@3kv zKAH}_O%jkxLahxd(zT#oN*nrDyz;smTc*85O`v;)~Te}p-E=h_ zp_vYIG}BB2_%_)yW1glL1kEKV1=&SB3g_hZjJOqGOPu(?$U6$#R%l;`)H#AD4OGW* zBa|gDZsfZiWR%`q_i_|GE4`P~W_<`pfh=tT5V5_Sd~kR_@kP~*fk&<Iem0Yo*XIvY0^Qmv=hCZK5S2&wQKUMjhTYdf>R!6;Wu7W zt3{<5Z17PwbPo}0j0fkQ_e30`!3vW(4*ez;-0bWyP1|~6-jf?Q;pPSg*gp+&ij#qoj1DO)l+cVrpC9?(`K*M)S$6hpd4Q!YCVM&o3Cl zm890nE1T&L21QH&!fBxrhDwrQmP5;`V!DLg=Z0$XtI-;tU43Om^qh~nqP&L{cO&iC zUuYjgXiDX@kJ+@ql}*FV&YjfqVg;SK_k7% zK1C+;rPF~!SA;g021+eh$=0TLXIz^K4(0Fk7K zH*4a^L@D3lN!FqQ6^N8h3F4r4k$8`^fDR2O2tVACk9qqS6!uDzc;YHmb=M~6SfW(B zWi^a#ahe@Cmw||Np%U!uGEI@qi=&@T55LI-lpc&3lgAJn0b@a3n6~Bw(U?G#le~Zw zhb?JnCT0?bXA$^AvSkzv%qG?`}22*GJZbS&-N;@_u;KaV3oxoCBBk(nt` zN+`FvhTw)Xpv4CxPjC)#WNC{#(7HC_X~g z@lkkkPe4lP5??4U)dpu}gfp0qC(4Km|JG!J<5=hRm6Y4YEC=Rg=;obX0}&xaESOB< zB|<2^iK|KI_vV6Q(`+!Dfiq>;3YxJB9t#Ag;R)aN)MvDTzIR2{7rI%npaJ`X; zIa;SQcvS==`CMgWa+s5IGCn(S>?flK_5i6)zWPf4R()Hi3jN&szPJYAimOccS9@&F zQ($r%N{Au@KRsE0k1XV2wmuC#%)p<{){i%irS?yy>&M!L3pgJAns)U_+)Tw0!O~il zQVK$R(Uz+|R`X>du@jFUA0prgGWOCwaW4$Y;Ofw=DHh2dA(CP+HS$l2dzG0t5ge&I zL)cVdN)Ci^<@JaT!~JFYRUBg~v@vqENW(cg87#?9)t@r?C6o4IJ!dv*M~k2k z=;ri;ddR{QE6M#AUWXEua_!alLK$qB&gBp>{ix7};J(=Kvf3y(x~)tMR_!aAq6gyr zlqBWRvlNxgpRB|Y!!E0h!mh+3QruMHlayZcC0KO0msqKBwBi+31n2}Z@!A%;&NVGU z7>h_@)|~+;PO`jXZyt9R#3}NejCY~)t5sp1-RZr4!>u^G&zjRN6y)U=^|MBXXN4QI z>r7_=OGL?w-1Jb>RGQjNb!5**1;q;*)x1>Anb@W|7hnlR-LR~SzFt$$7{eT_NfX7t zsNqD|oQB9#vMyXdz-?;KUy~IjH}8n6Q`qR5sC;PD_L1(G(O{=Vbt+KY;FNB!r1NGI zm*@>dhGY_!A=2#p zDO)~p2am-?pCW;|&=>Y)fiLKS#}J!L*jt1*iprq644b36jgu_w>1xPC`z-h-(FJ!> zwtQ430YP!CD_x}~(+~CcdYXj2=9|oZHnsgQsl;@r5ZBz)c24H%8fygsemN?HBRWs|907~UGce}6QdeJ>xx$E0|J$E?7OdZ*SGkJfl z?%Q>``84y}INw!-5#vN1j5_7iX5t~Y3R-Q6@e{Gy;=VmG?KHswmknzrUT@Qbz0C#mL}ToQ_lU}OEHlg!u#{x72x zNY7DMpHUq%<&f)FxEfhAsjlDIEMLX;EEbu@Wp3<0V*v-l%J{H;C}*6#5=gndqc8E;zDdvA;Ok`$gPEzVh3`i5k@>U;^ylR!ci9i;~X=7 z7->V5687nqLs8eEp>IW6++){y3X!O9Ahej4?Sn0x9>z*{9nh8{rXp{@xwfVZ!d(4|GU=XritRQsWQjukW|cZgq@(Qezm(Ay1CY}Fm+2lk26 zQ+uJVE&5BeWuc&HOHBXJccH{ZG+AT1p;$wr<0!Msp;I9Xo|$8>*@qLDi+9kLEQ)?) zHxnEE5l+ARK4$E;xT7etxS|s;IH8Tj?V$V!>6{FiuX~R!zytT}Jb-G++JF2#krLDA zJEO#?#ij8I3Ms5&#fWt*jzDoRVk7WexzL%w#KXIzk<&lvT^)j#!~&(|K+=J6l`gVk z=FM5Jeis)&Pl^z(r0-aPqJoyZoN?=&QBkwv0ta5a^978&4mon-p_p6a0?bPpa7!9> zv5pro;+jx%mOb18y;d2kV*iZXL6m|ik~?VT)#=H#Ip3uWN-$8=@~#RPl@b)!eo)tZ zrt$^KO`NKVqq^pEl`RHu;yhIt(KVl=4B34XC#dXjW|^I9=SI)wPL(|o-NI;7n`s++ zR%lR#4^pGKs*yAUTovq;qH*nJC}W8}A1qph0JCsFv6O>p;jyZKwwVOdjT>y0nN=m( zDp4x@xJu7TsuUx0g43U2hPo~zUHqJCkIKuK*%>vJVjR25(Jg-N^vBF+X7W}#yv5Jn zYIf+QEW4ErZSk|Vf}LS0Q?{CMRhh3G|AgMGt71fGdO$^f2qnIO9$jU38feLE1tdLNG*N(ileri`I{E}E1tVz z2rYfyilMcfIZH_X6;D_JY?eM-1#p_vRH^g$b@h?Xb<@1|gPlL4UHc*5JU-6f0(FkB zo65))M|-0=x#E~_9xG>S1(8MuxGof!KWE)cPFTq@&;~dxV=**Vxeu;#)T?IqRgQfn zEUvfsKl41k(qXTf$yYk~m2mlL&NnNS;wu~Ss=0e*178VeuRu>-DO;~*ysPHv)r>lw zp*59zsJzgz8=x8!U3G&ZRGt11!M$BuT>3JwxhUW|D%Xh8J+GkTC+bs)Dpsg4dx%Pn z@jG(VF(s!M^PIwg@6_gBHb=kBYJ&b2(fPC#TvEpgR-IR`iXET;ibenNb%w zaNS3h&E+?7L>bFx?!&ouezxrCOmnqWV$yVPW+iZHC0{#|X7JNo>8S{C)BFpSW?LEO zD}7v!Qi=InhG9nMmRrI|S7>@$!szt-?=q$nIgM46+j49=ExDhWp{-yAR-Cf*J#DM& zjwW@%V`+rpEz#!Yh39rHb!oIkmw=Ohp2`U02E?#kb02rR>h8TTVw7rJv~kU-@bEuz z8b@@8wy_ZcKjHGLXo53hJ1{pai?5cY3mn5%NY3nuil>XhILWppkd9}qhSZsziaJSg z9q`h~=Q3zbT_-+r&u|S)IyY(ht9IM%7AjC4w)ZUV3YDvkTE`m*nyrAfH?mHwN*T{8<&&EULm=QPnn@VYeW`NY|=beJ8N3Gv6Bz zMZsNlt8>$p3_7c=t07CVPFQ_&JRn|=+P+qSxqi7sO-I)j_36cOBhXGPl^cPxc06q)Tyj1Y^y0AN4I<_wlkj3cNGl?x)`SfqP%XT|+EIHE_(#YeV9n ziwn2ZMOX6vI)umKqPxjG1f{#EH%Gh5yHeyX7GvkodD_HH_V%FTh+9tR!akvi7r0QR zj*nAmQIMv%ZwDpl?|4r$?(8wP_T53Zg#$`g5v<{gd#WNAg@`-dypbzz5#j4`B5xCy zmL%Utt}98t5?4&c?-=1Gv7?HSFyz_8<{te;g%@AkwSCXSKZA1G^<;~2yY(C>cZGcT*Z~ycstox zVUTjkov}sN;!Lji3kj9d-mHOT6Ib?SB4kbmnTN_|0u@R3G)xQ)CaMdgMz@F1Esf?K z;eQQp_Q|@AimoXMFRo%vFD-_QT62JfX!q#KBIX-fiwDjbgd1H%;|R1S@1UH+fPQ*& z%u##SqBr%LFu_bZwdm3*&eNc>RIw|53m}6N&J;43zhiY>Z*>qlJ5=^|D=WXIT-}y(Kpc=m@rmW?q zBEr*p>NQ3-p`R`b)5AJRt;CIWN8^(d5~|RmAlp?<wc-Hc9$qN>E+b`B*voObd|f&p~BzUNJ|MMR)Zw zMZXPRf5xbS_llXL3d*ZzkP7z5>#+4yKzqgPQ2}Gc9aEmWp3zf}E)799)vK@rWn(@a zL^4xk>=I@oA&hUzG-RNC^X5RS=iHQ;$VL9<&4+$VyD1ZrkNuoxBqvxf9}l6nWN&gg zx^@l46?V2g?FDJCbfN+cg(~RKPDS;p2sqQ*fM-n%K4OZ$y`TNQ~VWqsA~EB zI@5M_2v?-AUZ`DX60Z>BiZq^C>LTFOLOTY z9BuR59$8L*7+hI_?c=7x#v39yb=c_{^$T}2rszHqDV80EWvq|v3#Z-j9cM5)hqHrX z(t<6^>RetLhGD{H;&xCJ*hlY7z+=NeM=BWE*tqKi zh-h>#9NC5=sHaIKVeA==qe*b`k+Bg1o8Vpn^^p$s`-dA17jc)H4{Xr*vUz&o)*Jj^ zP5xa+#30Q|-J-YacuN1#TmCl!zt(Joh!aUCXeUETMZjg`bse*^PuFg?Ja>SYOAb1n zG@y9Q$FB4A(Qx{mxq+7mntd6;k8gN`!0u7Y-N6~E4kZJ>O$mqJCb8JW+j#Ug<1s(- zCRw92&uaTmw&k9w)Y34wk7VC3D zw+P@$80$s*oUkqmyb|VG^<++n7lbYG)+~pDi6zr9=+$9OLca^-X2^(eecW+D?=?3?WkEMm2W=L9XrPt)Pt@#t@m0ulUm5yH=sDfbKPjOvRB#{BWt zh3&icAOJmT*0yl73B=C!RAO()95A>O!LLx6 z#Ey=F9M;hZ^kK)TCI^D`q3vSsAPsa$6vjH#Sg4&UVjSEb7&WVn_$1`AjDlwSwuMI= z_fHaq76%?Rwyg&i)MSJpx9~+>A!!Y~t|MB|%vYDWYV8$}xM9<2g}b15qv<0@(E#`Q+R7aeXz?O=z`S$Ly6WYK65HbtF3tC|y?Y zZxcj&hzEV}FR^a!5H~tK$M$KtU{k@z_>Zo(5du#Q>X ztdmLCMMghq9oj}})&X+T#Y%?gw+h=zlAU9(=cN9O^lMT^-?YI{9z+!fiK ztVUs{z)IS-kl-BHZZEpCVC8H(ufvXH1)k7VvCF{dbT0mV*uG;K7=YKce0y-_So8)a zB0#%inKkQ^1R>EOg@9Gt+^fxq#y zPI;ABD_e4H8R84;7X3WJ#+IfW4@ngZM0f>o&Hd&3(~NSzjt zvnj5Rhh50h1J8T%Xn0KgdIyEgdiGW0gqAm1ksd%dMa8mp*xsnwn47VTn!Mk}YqkxF zHDFTe?j0DjU>4d9U=TY&_Wj7Hp%vvN+c5Ttc5(Zjapd&93r<>YwA8#1BC&ScNc?5i zkF_C{U<*3k$m=;9L)bY3up@ja8;=`Dw;#5f#~-u~8jl+Xv=a#%D{GybqpMNigo(c! zfd?yT*TOAo4swF8gvAa})*atR{%-h~rC(^rO)t9@GyXLAsJ1E8b*xKOnXT~W;@rlc zOZ0ichmfZ8n=5ovAhCI`L}GIV3_#xFcD3(F4(8J}X^tvCGt&?jH91o~tzv$rkSIPy zx=)MElFs~Aex~$L7BySi-c~VVT11M^TH5EuW=>;&EI)BtAd8weU1zJ9HXRR(xSK$jAGW-rDGJ=5LQm0DRjcaet2Rk=uO5M6DK2RWPv~K1kDzTrd%9b z(E3rJwg#*4Q`_%O*ejoH!@;BnNvT9-*|F{LsDu?UcET3^ zZ?Uz*zKi0Xv^`%4G zrMN*?ZqR!p)Mj97L`g~+!hW@M5q?Q`VEb1V%8mM+ z^CnF2oyG~yf~IwJAMQ~;_{}2@3*M&(a7w|T;dPXw_8#w07l%8Rbv77_kZ2q-2cF-D zS1dduwa^R)ARNGl4|zUU9~#B}g4;;~v39cbKrITWzK^IBOc&htmMD*Exu?xM!givk z`hvy-vF>oQ0^IIHc#fkO1|O58)-(o%%EpqmwywC2J*$hNAkNVDEd0s6H%PRi zRhUv9NnaJw*y=jc7U(;tqC5lWGPw?;aUt$0GV5oye}ZDWFb4G~-U$w7i=x|vo|@6C z#z3L0BqY={#+)fzPA$)vq1oPOLsFC8#NI%h6dl%%+##GUdofdJwhZibiq8!~e|oRF zF_cf}9_8?ci&6#h;f(jf@P|^zI>R6BO!?HS!y?wHh}XBMc|}F9@4=KIon6W%F*3H1);Aa-L<7kVGAsx> z_|CM&gX{vstFRGUGxjO8Jl7^9-9~hiEQ%KldoBWsR9`UJ(2;uwO8QUs zc#OP4m~|e)a46ktbE1QB)9D~*F}%wNcLb5mOpq4GoLQ}_WC}lmL7XfhN`_C_yD*pW z+*C+Xd?xI04`GEnHnc8CVNP43QS7!wxpfgYMloyNUG3-))0E-(45tGXOu^#|nusZ) z6UpydlH@dH<~m<#)$#hUqQd-130RyzN*1^m7KuWkNai|B5@!y@K2naDH6FOHk16*V z)l2yD^%s;Z7Sx5LFO_L0smQ@z6vPJO&6cu{MK%RkcTO6iYvzRsrx>B1U6!3b8!X%& z_Iz@!{;2YT*h*a$F7|k2a`ot1?aAo{trtS;6-W@1GRz|y1hQ>oY6Se$lOhiycs{-Z zDm5d`=~&G8Fg@@pRVV34K#9VfzKESW9y}w8TSXnGbz|U(swNZzKNwR*|G|L#!N?J? zPJORWCE$=}lIkyRlhN%2CqG?;J9#R1Y>G2$^wMR3MSyDND>M^v@E;( z+ISRL=Z-x@CR(o(u}{hvvki_hqdX+B<%*DYiX7V@v(>RFg7A_?ww>@&@aC>*A;T?d z9*bIKNQ4?(V}ox%g4Kw_@~JAQG-Z}HEvFPx#RfSKbKe>=_X3Y`5M~~2M^qCx98j*2Z1-Z z<2_Zk1JqHzPF3pl{C05FbB?Ld^$Ao@KCfhaJY60)y9%GN8OH-RHE@7Z0W8u!Esew0 z!@-ezb{E?{sT_oa86y^=$ z##qHd6UCoL>ei6>H5r9xIvugnjBnPWgS-vCehP)TFw(QA({6cErtQM~EvMUwq0iRD~HcVb+4JTZN7UnAyoFx<2dIv>5`CrbU z+tV3)5akmVS@z;~9>DH*=d8~NtCKW~> zBN7d6JmkF&F~CL(>syw%Mco*#VM}8blbIaqMCIAo?_C{(X=B@1m+y2E&%)Wn))JeI{)Q|&OWx?w%AuTC65DZqlcRR$#gGym)OVFU$rwkg;`P-T}l+@CSHrElvwJyQpF~V{JLUV zo~FrFe67j4LS)NRRwrYwHFZ~vaCr)A#Nf3i@M`gGm-qTe(O%jz!Qa($56GmYYtbrr zM`AjDr2rJT&yg`rark8fm&~j3+O*`023t&*UCZ2*=NRgrTAsNQ!qXx^UeUG$3MZ6{ zYfj$s*shYc`km#PlejX{tE9Aci@D~6u8Omwvx@QC8c~we7Ek8uI~)#kF`!2 zA5+PB%1KvG9HOICjn*|#aU)8{$uUsRr_=e4G+TfzZm`Aso$q+_MZx06T(0l=jyrc{ zEpFIlx-M{~%}$F_MA}a86!}LUC7v_~T@*Nh2mdgUZer9P4US~B6kL%cGGpljPDn8} z)jN?^F|d16`6?~}jeM~^fmigKtvk-i`0Sxfrk%jr=I5uUoNEzz@xbf4r>?qBE%E{> zJP(eMCnIxnD7hz*5MtDjp3@K)B6nqGj;>W5ttMYKT4s9g3lYGi#HUI7hbO4^eBt;8 zB~;zvYV@28gmkQUl1$#$dt=|n)K&O;vmMxeI0)2CWTK>@y51Oc)d+GMZz#T?tQyCc zxm0POH)N~$v=sG4xfC55I=piw7qg&Mw$3IIK-0x+GLsl(IQ z3_lPVm*ySF!WtH}{7r06x&^Tjen%bE@fnGH{&(s}lo5J-=Tc+=LVlBg#;*zaL0=b; zLvry`WxE2~?>dP)ULgfwXKvOSYQ%FG^JStg0kObWX^DdcKGmiC9g6Gq?m7dXIWkBgismynMaFnI zwG@4+?{Rz5<6Xz=JAr>Cr|JVA{E)t1!^HUZU8mPQwENEOjn3tzA#YdG4yr;IRI;%U z@OnD%_SiqQJInXR+pV=_|bBy0H;hL3_a;o8*CIX3_UG#ZP6I(HV@5kn%D zoh!;wu#3a_U@xyxoFY0l~^T#|&_4#s3jOq*F zn2H_losa_ZQsWS?MaG5XeN!atpp6Slp-+Xb8L!Lk8Y>DJ7wXsRGD!k`dH*>bo=IF#-!_Mkt3VlO&2q+>3)_ns&I#0@TkIm7CEZ8 z#9YjX;(e4IO^Oxoz&=4$TC$tX#~M|!o8lB>DoojM>Eu7hVN~m-_$XLCm>Pw&erF7% zco#LHflPIQV`&EXvRqZElbOeW$zJ>zvO6g}hNxjPYCg|0=a-y?DqYNsf0osEPWWea zQ5^piiKG{I33rdikrE}g-cX&iUfnT;@96lkwzLTEzG9gszzGZ!MmFIynGaUdJ5mi; zd@q`5gmF+a3@{EzT|}iBUjROuaz|om<8p`i)$M2OjDDziqAANNnkTf zOcGSaycFPOtK1v~kah~m& zxAd`Aqhg4r9QDi_WhtBs(10~?70WQw+{8i6FfVaH8SAg`_~ycUjFtj5^Y|2?*~S<0 zLsF{fIIRG^H1N{bL_R#;BEep>9RVU>s?$9JWG0%2!CVM)nPtI5;Zz@06v}*th0wRT z3=44PFf76*odfHYt+ID&877|UU}?lDW}{M8tu)HjQ=sHI1+w;^svt9_r7B3C6rJp< zv-q7dj^}t0vc_EzV#cs5Ld+O-C2M`wpsNAQ7;`m%<%gVY+^;a?9DwDAoC7d@$kBbY zsKX&+z?HzI54RGy@`KHC9aI=>Cb;s0%>JtieP#to3KH#?2P9m_f!j4hF|WLb_#Jh$A_<_AW&CmJu^5pHs{{pPXN zz|u-lU+17aOH~&^DLuw2u2Tl@ zN~)x&>AA=yprvW*(QQ)+zNwVB1gwmcP62SdrZ8-g$1u|<v_gVGo5TW6$EnQD7s|T~cm;6dQym)%$*G%;TmfKA zu|!PzOdvy32-yr~!fnDEG8B9^aN(Tt!kh)Qs1a)xI5DR>8M0;p77{)iP#KO*gd?ks zY(AkO1x&A{aMkIR^TJpQJAFSag*WqMNR4zBr~p-|b{ULS3Tmh}hdS%LAZsZ+Ct8G9 zhsu5i)&+!SNn8s+3^6Q1*8=bg^Hc#?A#QV`9^+PkGs|nJ8T`V%>NL~>Mg_f+8a0L{ zbjvK5X?k3#g*dJ0r;okB9G3xCaoAa+xZ>nU0o)F@t)mkh)EuYzT3eP8zyF$0{pv!2 z!(pywp=cWpYsM&Ow%2i%ljX@@6UQ_>Xlz>#EXSvdOj~GQS0Jr{*LB1vRCXiQ7dqRq znpFPH4X&Di6ovU(4#d|4AC!V;Yyw4hfC6X%Zq0UIA3M#X`{+lF8E9{XXuAOhLub?1 z8Yhj1$Kt@M*|_r-SwfOjKTjqArEi`kG0Nb3mR!0uFOH;IF)d#8pHiuzOHqto^a{_D*!<+!CK1^Or;T~FjhzUT|hnD~(hc+>JbzwZ~qK3&9 zL|B*0Hd^*@=nT4z{#xJZkDT;EN;&IzYV#^-PvpX#`#sO*GE);gBYQ3Vc+icybkRmS+%($)viu23l+Oc=pNGI7CEDqrH9VCp07lN=T98`m)s*x zyvyk^c3_9`Wl6pA;$oA}(mIXWnU+W3aHw1crliBF8s{2Go90rdRh|5o)TvIdSW?&1 zJN>dd4)@+Abv!X)O7r%T`qi3sm(=%U%&LONau#u116j^sna;xDFpmx^9<58JjaH9b z$mnR|jNPy-Z#cq%yNMI1HT0cs6Qx~;ot{xwr6#Fn`lax|;!?My`gU|5r))TEgaUg1eTbqBcg_p}*xIRisY4?ND)F5p*IK4e^rRcuDYPcJDxNFP5Rzp2Mb2|-gc147F zPe68WWhWpT+TMI8AiJ}~1n5-Q>JmE!+`>7#GrU4n%#(7bP;m^^7!RZSRV-vOyQoNI z*5EB(81zbXm&zN}z*S|AYQ4oKP|4u9e5@Geoiht3V38ERN5u|P=b<9JoQa?T=)ym$ zFQy!dRa0E%k7c&-nk$z1R-q~Nu8~8}K{V!HRDQzpzEN`>W_uh- z;@(GV=;1m9T!la+nO9FHxncXm9#)2Rj^KFZ>AZJzA4e2p=sF$esXKBkTp*28;kXl6 zK|9z8=njkKJ;Da(ntiKzPn_cPE>U&>n-d?efE6Bigtzz3P&!Su3R%T1OS7AA3r*(W z(Q)&DF48d7uXJNVqtXM9ZXLyP|uIk;XQQbb)OFK9tw*YIh;xA45vBI#Co?&-mMsd9Kd_vGN+hRN|_ zxmYqR8T5c<<%RT^a$i38>xIRKa;!f0*O7>#uT#B3j^i`S6)yfDFNVWRse6z z2w>emJF#bkvC*TOLbN~<0a1dSq2*(?qwQ>SYKC)4Sd^dA)b9(ElY3dUG}N z%_jS{Lj?j#q2#0TA}|L^LGh6TrJ(r8hEj*3sFfd6szo*&CDRJZ*J8ltLMMgUT*x(d zp{ry4rHWo10%`K1fNrD%w-Pa|MI<$}K3!T`58%qEtn z5GgN{vp^ISG+7`DikA!!JBTWA1|wADC?=3IKq;A5P#PD2G(Vi?K&W|ZzEk6$quN$L zW=?mXCLJmPn?WK}*Mg_VG{0S~l#HB4B#pQ;f}MfP8G?6qhvu9FuR>%7!K(pLR;*}1 zl$9sbATkV{Q(ADyPSaqj3f*)_vr|XmG&_;zuK7+;az#Q{k$;BUMl_dm%^(ftAauhq zty<`Yh|E{$hG1tP^R&>NZ-BsTa(9RA5b^r9oR;1hN3n~Jn z`YPH!^?b{*JLlrM2+KuETJzup@eEterPCP)h<@Pe5_P=Uyb#G_a6YbEVRT6}65_DE zWf@mse*E=@_)F=Om$BctiF(H^ISPS3MS+g4J03BZ8j{vdT~r?h_t49TYI(R0oGf!- zH>jvd%AZE#pl2X@{;<7aHQVH$uoCQ#Xi*;bqLuNv@teRsu(*~EuZz(}grNwa^{<Fu_>SBd>02)T{OqTWl9;G z5-6<3lMzQEZJ(QET-Dvmv14<-?#f#&QU)4J<;h65A^DOUkkq{hw~6G|tjF@j#y0KI z$UPf0TK7dYSKaQX@4VQ4q5oFDOOzHQ5z5VL0p@c_B#lDW1YD+0Io*3I&rCJVy!1)^z99FceqWG( z(!Ng(kSfhP2~sYReI_|xG8b^E95mH?Iuj+EmS>|32n87_142PoN{6t4I;Cgx-^A3c z&PjPLqrZnaQS)P|O5LaO)Rr|B#i`5}#Y`y~0E%%`27qD=r2&v@Y>1tPDp7Qa@+q1R zhPw&o$4Uhh{6ycWe1v6jy$iOAvI4Y?QnVVX1tS z>^y^!nuzoBolzk8sR|>d0w~HzsQ`*HQW}756t;5)XMsLltvoX&sk%IF3N?L{Em|fc zMf*+Vp-7|BDw6)&Vw|J@wiwfBzs(4}D$OjB4wiVHk5xchGOr~24*8`t?UInHth3{` zu4r-IrFh9p6gbCI-Af-+W2%ADW5w1)U2$8SvW3sE3}RKGX>lu~t-+GDcOdo=F%%PS zP^7CLYsohUxO#lqE1;ugR-xMrL}vh~#n5D(L|_;#zg~Kt%fr#*6XBOAJ~+p9y?$w| zszNJ;TeYc-D&WzP=0elrmUf>5EKb7VUzTz+z$=Ac_B9F_3n7vLAEjOaczXQUGBLFd z?m7dQsK+pedi+|bzv8mb zS(JtpSbDtjDVGASD&11R>9OO+X}Y;4&9XYjg?NRzgaVcxuM$*?gPWOZad3LoB)q~Pwl}|H0w5lZ2L(}7yLor4@o_je1)zZP~vCF4iI>f5fONXe(F^7Va$&g{Q z)fcKBlpd>m%ITq1rJ5d^9=9Bd@xC19g3PGN#^C7j$){Celq!MJW0g%M?ugStt5PTl zLyt%9kdk03vQQF?9-C~cgfUo^7g-#F7Kbw4qc}J%WvYXl89RB{%UAHr;HU#SJEo~h z=gc%UQbEs-HFIk*<+c=!QvlBq!J$5dG-A>^7#>QPIpx;`)H*|ayXS)!MHe@69m^v4yDmfLyaFi!N(mWOh2 z)UqW8Y#3-Nq5%ME8+dbs*`?;~j(R)d@t8E|R?iN+f!k?&J-6HT#(u{!On?%e|Q>sJ7Nes06dsP2UP-xPqzK%vBskrC1^4WZMqbB_Oc*tn^F+iu_Ii#lDkX?H zioPYz3f~I0GKp!9oB`PM6&Jw(PsOM)@nA&r*zx=B0OJSk<*cPQH*4tojx%z7r~7Ew z#aBo8uOV>A=*6r7sp-#{=W9TYmI7){8yf(By9Z1${SUmZWDUX9QTz=;;0 zy~$#j9u6^U`>8#=Jw831jGC6_W7l~)^!&geK(}#K#+mPp2i;I&#M&5WqduS(6YhZ^ zs^2l_eYpOW%pnL&eyqVwOyz++3i!dXi+e8yZ3o2{x^mI8ypVEDkZiKZCh|uJ71fBQ zbGLuuI)i|DDGoz0oqKvZ9!XYpG;n41o42VdyuyYJZy=IP#;YNJa z=$<)AK@!J-)+Dux3+oslYC_EOirYmb>!}a|@diZMuz^5DNa;&wMEvy7chB5`npXA3 z5R5@tjQe6i^9Uzz0aF~7Y~DiTuA07pa3aM znvhcuY#+M_Mt9}}f{&*7%%G(%mxW;fvpuKR6HGs$`@zFIVuv(|T&h=LyAw-PEn*UQ zGQi}H9oW0RZ(lV{v4uQrhfj{h&Dp3;a@n|SY_(q>JC3?M+Nc1*AYM>79n%flqsAr8 zBUe6AbwajAL)^waMm%;`)Jd_1T9q%V?`S>jrlkqQYuqteN-wofV@`c)^|}R*vrM1m z#u*8uLX=1RYVWf1lntvWUbx@AJ|2jT5zN=O!FlEL`5R*QY4>fPRXvouA$dYNX`>yi zpWCDJCS5>|EAE}w$9B&OJpLVbBL(Y2+x44tLAkgmsZpE`*Ae&S(p?wnY}ADC6EgAo zQ-2X7C^`qazAMUD!@wS9b)maMFQc2sf}H>d72JDv>MdK|8(V}+&%+jfT`<}qjIh6f zB;61vv4zjPDU}e`3!kJixGZOq%3w6}BxUYMb0U6rAM+$?c26@9>l$ubGf&QS9MgQ5 z;X00N<;!HvRST;aY;I1heU=%GgIQtNb1$5S18JVm`hcu~%DRtl z*pSUyxv}Y7cAO!3cA&J2incqB@1v|Q9c%Ev*Mz46XLzITL%WA%*Anm55gwOT%?gQP z31$XzN1h0&T38|{SzOl)OD(Jt?i)n#{Z@MqcUIF4(#mjF_Opt;Nm){$H?wi+1{JW3 ze^(sM_;-czG&cy(2evza_iIRof4@A^SwISpAPdMmhO^b+lGcqDt@ei}v@rTDalkD* zowI?8vTp{YxNn(Ul+D3#94HZ&dnmt#ThLb59SuGBd)PCO^m=cS%UcP=X=fRSp@g2d zho`3zI59`!X3U+J(GWRiad%!u+j_)Nr;sF0V&}BE^(f7OtQu=Zv>S6}hMiBq8r$rN zp7^O0v`CwssWu^LVy>voxW`LDiu=5_5{(q7CGpz=)P@+>>F;QaDJIy>j?V|irj@>@ z)jBQ`u31@1f3Ef(JA*4%k%{j zNp_IHYFgE)PAaKx96A`}AsHi6ZtwB3_)#-N2{U>G z%kbnfL(e7r{IQ;oNxqru*5UmHaQ=qaqF6&(G<@9@*HLX~a%PjPn6mrE+lu34M%U_qa)R+t84*0c(aNB3Yf4q6UNSxqA%0O6yrBmn!f-{%4@W)L51psXqWKh` zbqFnE8$2?hKs&hVr3$D7_3DCpDq2nxN+ERU@I6rrHjF4oZsCR@V#Vm`v*6Tiiq0c8 z5BRRd1jT|mG#JE!lS`3$D>7a-hKVrfV9T;PmzRcNm?!qg?SRe6iq`DltZ8)4ZQnxV zu^Wt{Nr%xfd*SkYko~9s;42nTR5WPR9cwcboecGF-l{nl&yc{Haw8TqA22W71B%7N9&@2Tg!?G33E#gi{jBGs@bF3jI=B{sLakL zW18-v%#i9eyNfIgZ6xY0qGvOAur+MJFmo&7Z6T6*gz$NzHiW_iulc6dG)$4beSwtkUgz_>bx!@ zzm09g?*)k8vrs|4=UDcoJHo1DO~R;sFRNOw+IO-zn!|r&awUIkeB+ItJ zn-VEOsD0n-hkIY@-lSrH3rn0*UC`dn;dCNhBcH6sHrPviaqMLxA4W+Q1YC|ZrJ-+N zx1zib%JU$?KR&)szNj`L)wQIj=~hrgD=!q|rPF-gnd zC4F?ii@Y%W5u8$Fd*0|w)PWIAp)iaW`ErxLB){W<2RCH5_^0(yC!nuyZwQU9u*zhP zMTU^n9*Vk8s87lqaD1p|DmQGH@99JBbEUu(#*ma(MlYK4g0vU>6kNkbDvY84b|y%~ zbUl{Bn-6Sg&X**B>ka;|CjYKOS0Wv%ZqeIyJf;8WE&sbwRDK$1C{$4XYVLrXnF-ak z;N+WTNQ=FmJG=uel5*Te*a8bu6RNYCQjtgZ@RWF|QT+2BmdF(PMCFB@Xx3Rw6P_)k zafz&~BQf0AL9L9;F>7&{atR8cW5au+EnnsdMqXpkk)i4um zvTX)ju6O`svq46iMWMxQg^4JFI!W*&XGju8<~kjFR13rIIQyOt%aPb(3!f$HBr=ll zIJ>C|xOHOrB)C_Qp?OLt$0`sFg4jOyp2CvQ5IbLieP$DKo7xv#>c*xpcs=HXFrgkC zX-pL&kqs%mbXez58e#J@rk^LcIdet}b{^GEM7ITW4p`k_$HTB54Pf#ZcPOp3d)Ifn z4c+i)F-|oUnvw2JnIW3Aj~*jMc!YFj%BS`QypzzDF}1bOhG9fD54s4OgdS3}bfjFyNu?Jes4>Ju5(MgRvSif8^IE|&yOYXY5iLQbKq`0DyFztp^${pm9 zeuk5X7Mv5MjXT$zfY=YNEC{$6j@isMn2&Jsy z3KHX*@DBVK1Fvp9HVt!h1;bz8!f-oJ>H|-j>@)lUW^GTLQn7*IunMagyK0I$D>hlt znb_*ZIO-(1`KZoZF?ql5Uc!?=lquw4$_O?tWPF-#!=JeBDt#^}Q|U_;5nAnI<)1t8yirg+N><$G zB&)rodT9$riHMtWB&uFb&++T|hY$~?AvV~6W)NH#Z7puz6;tP|R$Oao?qe>_68Jh6)9 zBkR{5IUovj-&2^qcuP}3A4b5Y`JyGNK}Esi zNTwPzkFDbx*oby$iIt|ay6TM8hojbolnMFjK%Gn};!r8(n>Ryjud=d~OI18z<*KHY z6;zXo;jmy7a16>J!%;;l6w|KiW-bQIM!G3Fl4jy+G$I6r4Jj-qb{EDmuSYQ*qSDKp z*r*zIsZ6vEf(a~9zvAH0u~=pGjfh?oH+DogT6gkFlyeg+E)o&F-e#3aR(pewf~@=; zCOta#1RkSeGi~x&0^&q0IWGML1^%QOeF}D3V=McF$A#IvT9^2WO#?fjDnVqW*+3mBszn9u)t6`1R{WEqLyOq-xtI`WE9?^0l-hiDH|x@8L5t*N zT%3j~YfaQmyR6u2Dv!sbTFjba`8o7ikho+YN`xcMGSY&*ij(s>!pwEjZs8k}nb&=_ zWm9yPb9$elb2H*t-3{O{IvEGf$e^-&T#;7!Qc1WeOR9V`S-)bD?)J_+-wn?D#umO7 z&fD-&VS9(M!Rx3^Q@wbBRA6Cms)dc>NTS?fTUaWt18#;C;gp41RnEBWor3W{bLkD5 z<8nJB(I9(_oP0F%u7cI*oMuA7Hnyw>(CLL$9yzXbC}`e0qMeGJV5~AkZAGNJAMRMz z*cidub?-*FKQgIcD3vjx!YbvgwOA08K`JIQ$A7)2;wWDpT2DbfNZj+Yc&^&ROskopm z6<92YDhSdxfHl)P2c*{ZkTgsSg;>`O&1lM$-WStdZ0a_mQx_SpI*BdRa-io(s+d-Y z^H5lAcUJT(pULNpd#c&Va0XO+**ZZz){<#+I4;P7T@=!EX1p|68a3->RK*JjXP{eNJDt?c+pwm+J7MIPFv#4t$f~<- zsU-fI#U~A86vRvNfy)7x%k|;khwVF-v2CHOt_8Q?nPbr#3R9&QX3dfj()_Y3-l|tE zpNawa4t-$_QOCJ+#o)Fk<5mIP2PbeOo*)VZf8%EZA`_ku*~cMj`oaVP*XTr;qE6tX zeL*$Svv|sw>*~_CbmLBeDX^- z`W@aE=E}S}J8LXu_5};e(iD=JCg=89m?59>%o;BlFz=+x;%tjxdy=0*pIEYA4@3|(Bu7yeASrd30P`o_ zFyzSxwU(iHPVX)v)2i7eol#WCp;Q7<)i|r1vN&1_MnZv1(K;WKx{7C*Fd(8oj_<4U zDDjn61EUQ*`?4CX_d++;SV+$iww~tH@JTAN)l^0tZQ~pqjYpEp6^kiQ_~o_ zPRDubj^sv7dxeDp^&3bEgm!c92*0 zD$W!kWXTxoopT45Rj9I~qE5l=1&?#d7V1%3iL%G^d$jEF7Hj7;z!skj7mE1wY7TY9 z8Boq&%J6khcO45?ZQwZ86m4Q>>uSQ7;vb5IT0|@62<6ul>gN<^!osz;i2~tKX5j;v=7?!#EQPw3B5}((0wt!qT`VIO z!HU?Yiu@LVK2xh^!mI^WrZG#`;N%xaStsQvyCW=#bOvtpkM2ub*$aBXOe1r-6Gwm3 z0KwSgifZ95Zr>1kMx)_K7 z5`Kv3vWFCKx&o_Hnk8m4Vu``Osjc1+lWvEhHySz!Sh-dhL0T71 zOc)tSDa{un#tw2GlU9yK#Xt$+9}^M#NSK`nGg0?oat+Poh45ynQ$gr_no1_DW8ceDuV&y@fo}N~d<^}zNhC#HxLc%W+k%jcOj4itT3T7tf6!*4KVsq8> z|5O}g+EISLsSx5j@fHmNcM2_S05ZoZyU$|W9>smiK|yJEDmQ}vos}Cg|Cp-8I1A%v zXmdA!UrCyP{qeKdaREAhiXldlsXaV*{N=Hl$x-Hcy%t<4CY37?>zlH&mAFdNW5f3g zl|dD85{EpphlKG$6}3-6IuUvmLPE+h{H;^F0z!aba!KD6*uulDh@s?WlK6~nszi|m zs*+kTOG503lUY0XAf-fC94$;JJYXVS>)?Y&qCE6us0FvGIbowYK*gt2p_`8u2~w)4 zy6jCLyU${Bg{nM=iz1hXyuo56r_;G%4+%SG8B%Njr6l{F>v!b3TA~(Y-pT8?;N~PW z30VA>#zRUw$n3Ki3lZ+K#vm2k0%z_DJXKCA%``9>eIy2#V$bC>RXp3>uqMGXINF9L z;fa-;zv3IRWv2aHqHKhu<|q#ayW5xr?p%!=+S6yG$S9l(u&CdxD2Hj&5IiZSMP?6_ z!*GSmw+r9<@XE5ANDLA46K9rMj9FTU1IwB*iV|xegXEa5Swuk4(Xk;;_DR;t>LV9^ zTC|VoJU>Pb1#aLTnZ(HP$t6+%lfv>W^U}0lLrJL<*BV`P$sLwc^5nFKm2`9;2{Z^dZByjdfHG^N*Zn|TwacCFaJ%;7I|VvAaLq;o^}zbj5=o##*%eoJ z=c_^K))R?FsN^QY>u1=YBhmMi)DS5GrYeX1nCEW1B`FQYs_xM1+7dvBKu5gr#tC(Y7#!4zv`iI5owN0LF63R+tp~b0$R*r?^fU zRjeW}A`uFx4RfRZ9J%m1l0K2Q1|Grb`%B(f>Qar@;tC$H> z6q6&55(P|8lx#=<+LCx}Q=s{VWqHGqv0x4%po z-~u~3DV!oH2^l6LLFGE)h=drR*tOi#W~&pSog8qD2aFnNP~ln9?$|1mOi{7sj!S%+XrVkHg~D%Xd@;W1_$O9iTpP41#`bchHwVl1w6zCw_|Q>*6;&Voc5REW!@#siK&!MU(L zEMP_olzlSI0BHdz7)O2~7_5*y?f5Vr2z3kv8KaN5mM&Sf(4J;Pm5GUzkr3nAK@-%h zhfHBl2VyJA*5(&yVAN7k7s?68{k>M>Zqjd&hJ#@Y@j0q#3jzxj4vPcTH|(B+2rhbn z+bqUlORA|DAgXhtLm4?FCFrCNwo}b%sEUgwGbe?Dxs8Guq6*B_M0!jz9BHNGIT182P0!^`#T4q)K#W85SwQhLtnP2}UY4j&}RES}$f(9%9{ z9ZpRP2U;}u_mdw)Bvg5>5DSHl3wsc@Oqd-dHAluaVuHB#U^o*Hw>#4^nX25uET+C> zdAr}lL4;)PA&z^vdtumfqZvc{=#_vWwjDepGY%W=dw6^yHkAWnna!j{Y?d(^*LjSR z`r(F)J&n{4K{hO=urg9b0#Ih+5q5p>u-eL}Hd5r4O>Lz33LE@A>meB`g?&=3-5s@S zihbHxkIz2uwn(vs7~Zi*BV1#H8ubNt^ertSP`DbXNQmTJgp6H?M7@GrnD$-_x7DKT zDGL0xP)g{vF%sI&9ecO{t+EFlrJQC-%2bmGer&RSNk|fQ)(EwYI@dz=4YgmXMX)DS zD%dpBM$9Q9EWS}jwnSc?IN%G_TnHnwOCN!0=zGPe3C$ha7NswQbH7cN7u-KJF%>XJ zPWMhYt;buESdS|&;Iawq`qZGJ?jV@3mpGtA&lLu9A#YU{rDT&?ja!^!M6oJoC^YLJ zM3(FnVix0%N-G~k&*I1RxF%_)sgf$FhBQgK-+L(QW2C1%p{5vB(-3^3Ql4U2LOZaz zOHf?xCQK0unJu#>vAHQMRy~RX6bj%%h{<6mDhrCjCMHoQqKe&4k zO;j-rI%BYQ{Rl3+2ll`|!@LXKReUr3(yZefMYYIlReObMw8+OH(T|U#&X(`ow_O*jY@qELn7%BW#pBt07L)On`rxKu4rKAld9U?c7o zU;4(P>3-hAn3mQ8g$J>*1Rt`o&Sp=t^|m)2KzwkuIg$LTctS>J-5i8fMM8p2C<1y>90WDVUtIE9*dM(_$+{EiPb$7B`r4sn&(9e)}m^EzC4;Qsk?c+!@MHi z4-kyF-Kl9{%`Q*>uW4?6h+3_tdGmHZaK|io_5TMp172yJ_YBmx^t(JKLMpa1!1@6+ zJ%ZPrCNlUQYna)L;)STHB3l)l(%i-JsOZ-3U6Ol{%NAE6?L{tIP4c8ShN2oL4`Ip`lra|ELMgmDSpX^QZ=8lb=%FE$j#PQ7I<m7fj{3=i~|^P_5~MpjKLIYBd# z^`~!c$WO{@n$g;%_JI9k&shJMoHC4J)|1}eXOK`?=!nwg=B;*<&K{|?N;tO0jJXX0-=aY?hm$f$K9n} z;YKl)G&DXoVfippYfox2Vaxm$!Fqv=t+L|cK+8m=?Md%`!bzDbn;FmNOR~~WX1yk- zhSUl&)u6Vhu<@1btt#uCk&86Or%sKGyWPg=R@rwSsLJgXXKK8MoQcIk$l@LQ zSCTtyJ!f3JwyUKuuwCv(m}LfJgNp2ZaH7p{hrtg(2G#lh`H9lFtg#=xq>O4h235t^@1G4t)mU23b2gPaG+ru<)TE|mGo)p} zmh6>&N(5!Iq;o;3UWvZ%#0}TGlbQw}B=z#sDZM@4U9($TDr8G0d6!z8C6_c5^LMFs zEx2D>mI~W8_sbf5_t)@NLTg1#s%u|WLPzB?=GnOkYkFag)|rT8a&&Hd+*6lTho9AD zz;w8$yK%_m!=AHZpmRLKA$gNF+GteSJ0!zH^(NQQGX=4CNUd_qmu1tdyo1*of5cv} z@lWdjkZW=Wj;VE|Deupl<)*oQIZ(MrZS=$>G8F0QX>TI?q)N`6j<4P4(M)-2M6MCC z1dn?WpZnHiY6pA?+{f2Mn=HCf6C%#Cp(e7jF2@ zbpd2r4%$R>YM;9qSKfl}aOOK&)IU2i=}f1qRn~{)zVb=6s#1+>^b7vUDY>?GL@vMS zcLqImQu=*eW?NLK>2D<`rve`m>K{l+Bj!G!7jT}O;y0FhdDZB-@`HMRg-Ss!dUd`t z)IE^wl?Sv9H|3|#s7>}-P{x>2b4oJYmep>ub4xC0A2>334ExXJQmbQfi@SF#nVi@p zFK9OnjTL9)rNa$;Rg({94rLf7OWEaJ>*DUS(6w{_jbkUB_j|70PWDXZWhw5=?2Uu+ z?@@2N5#6cpj|nUXcW=H_Z=wV4675=5wIq|89vLgn%`{153~SB}iPTOFvm}z3$R8`N_ppbqeI%@tt0@kQEgC3J$*@%qMmV;p$?MvXOgjC*(PM{hzFBSX^>?)1 z+>ZE;4xGEPy=U~fhV5g-sItxZY zAPDMTRJ@T)%N?wInW+uhT7EdW>+V+G;cVS)djkf;E2YFCw-eW1?b5a3x_D1Moyqxq z`gZw={FrRbl(TANGvc&-9_BoS9J)0*H9esY`BVGNWO0c*2jJDU&`Bk=Q+uRR?&6F= zIcTMJ){36nkaz!;OE!+z2fUi_()qR?gy^;-rb*X*Gb3kZ?X1|XX1HYTntOFs z#JB!k%{;nOEluz;S-CGw&%$umm3;44cK{B^Z?YU9oqvw3$5O`=>A&TC8TS-zsnv2b zt~7Vf5Kte85SXe9&f|K!S(Cjb*+na-2^G&2#^wLihUd}edX=;$m2{-W@~7s`coObN zQN2Jp2YuCsXFlqYS!+GGZO3V*H$VMup-Zhto#Ta;$!Uv1U7U=R>l)`1vL{nA2=kqZ zy8hVA?AX*?ZQpV@^LpoNe^x5v@u8yw$2>ROaI3fAJtdCJPnV{r)Nzsri>1-A{Om|^ zJlQ)rHz8As)AAL3YFv&dlw%O(74)D-XC&csGow?^9IG?-Nw%*`a^`-WUf$H^ zZFf>4gdJ)BJy;c^D;t82qDSMOw_bc-=1ARKTm++AWr_PS zqSc~E2IrTgekF&Db4-4xRhy4&x$Kg4Qf1oNgj#aVRUDSsazq zBgL6J9SikAO#`xOb~<3EK}aq;Ybcb`OS|RrrMU??#a11qF*06ft9G;8@#rS54)Dnx z(`T!?4l)Sb-b~?kP7CMqVVTWytzkuezs0zo^G=*2BVD6ow>vvU75pno|`*KdFZe zaqfplI6JjUX8l1$!69|Hh?AmeI97KVV(^=&W#)IxA1DMj@Fm?FtW+DKXWgP)ARwQ? zydja42T!I;_2@U_TW9aQWm3M#&B=0kIr8y_>7tB!49nfs2jV(G-59%X%L(Vx?Dfty z!b82+%O|xv)g=nyGl9G-LY*ZM{c?)3yAa@%n%HLY zT8<3rqYn+!(TvUUg`uFm;z?QVwemzNLmYwDx4!Z?|t_VHd>+MG-U=( zPK#C_FemWkU(e0i=7!HhQhH1ptRCkfmEgRlH_xzVt;m7ELXco?_AHTP<4@C}RTg`f zY#U2F_AYVzvW>m+a=6JmKV=zC>ii7ZMlC&rr48m zH>uo3Dl08zL5g0kG9>4hs+)=A13|AGd?>3_o_Uk$YhN;{KkTVh$8y5Oe*B?z^&dTZ zwm&ON)YVHy|9)BOs_x~{i(8z}Ug}I2|2-@GnicpM*uTFtRgzVgEj%9VH(Gzbu6=4l zMO`H@=m?IlW&2C*DnPwJ-o0y4zio%qrS-?w@u_L!e1ST1wzhu^v$idy7ra{Fd?&{O zJKt$xwLz;%?bVnOCaC)1t+v=J_4MZX&|gV&}R_>>eXlD*<*1k(D<+D3Rl|7M;?P?&uab z7($`b4Yg*bm}@u~3l`RHwS~I6U8-YAhg2Cpq%_JVHMP4EPF+!n)#br@-6(OC)&);H zJovcq1_T4_yrkbwqw06VErwFqqqVm#*KZ`*|UWV&dXR(Tce&RP?VPS9Bs8*_Cv@bsS7m{c5SWI zO}n19%FsEE&h)0*mbw;NjzER*-q>^-+N9nGA8aATK%~^xRzyiM^kfTZ*44mPa$5gz zD=CM@tVD(HUF~OWl%UtsDN$-GVz3lL$p3Xk54wI0@?%uV%14qv~ zhgBNqL=4?&ARXB%J2Epk>&!h{*M$WvlXdH75j0uEVm->(t2TonfnF zWtLhy;feL1m8FdKadN<{RMJc2rYX5sx^W5#Ez^?vw5MKA{;1o|WGheOR1Q$ISz^Jm zNbdLUWR=-IUC5^Sg8ozWTZUvknH>BgtLL(_G6}97YHh{Up@&+g^*tDt20yeG#*&R- z6MgaJ!s;-!hazZvpl%0iXDeFlb-WcV_CBhimQaJ$ZkEDo+RRf}O?#PQ&(UUv0xH_e zOhAP_BavzibzOv2rdKz1x~U4?aS@s_Z&Vu5l{6@i=t|rY!EUO=kh(#6NS_thKQR4OGU;sHmXi|YGAQqO@@Ab(>cF(V z=OXZutX|^O`I)UsKFPv~M(V0uOs{K86N1s)h!mKW6}@ z+hr~#3cpy}M}1Akw5%qLa?)VjA^k!?OM~3Bpv9h}(9kN%aFF(0fHCY3%uwnAU;A=i zr!i8yxdujNIlO`74^H9j$+a*)(d1efJ!#b7S{V7g;k7WF=t=e1zEer-AK@F-o;L5H zW+at3Jv}wy?k|`*IptgyVE^=z7;4nA>bZ&Y_64RWj)-)4gL2q0@k zo^j6s#=+il@qx*)d|4Y2s*$RZXyZ*B2TiIMe$^i6XVrTJ)MmChcm;O4)wlbwSRjxxqcTOHR$IT>z8ZS05kYx!j93 zKthIIpa==2x;G&bR;ubv+c6SS777x>`)6BIh;1J58d}!gq&^0^O23IT`=*VBl0n~i z=QxJG(K!CBYk9*hxRjZ9;$!;?-18cvD+sq(ZCPPbVzi{q_Rj2=c9j_|Ycz*aH_zLi zlS1`MHRN8z)P3$p3dY~uJTwXaI>YrGo#)N=9yWR}Qc;-lZ~XAywzh~~33h_coPAWM z7@v)nZm==Z#qXW)+IXC2c+gl1jbb>U1JM<|rKr>x0eUUVFbz`^;!TZU8)2 z%#S;#-KJ%=mA5?p@YKYF+;^)_e?B~3ltul{T>$#bgrrGQ-Qw##-7g>ivg)YUV;;q1YhofogJ9XPbAez%g0M2qs7^C&cVDl>Ua5&8l7lLy~rOPADNj^oAkBB3PVSacR0~xB1RrT) zUi|~nY*P-ry)6gUJ=MfQ<@CB|q8X_is2^?3fx$n%Yk)IHL*}R zuzEE%cg~sp&wycY6${-W%rXQu}o; z;2a<4>(JdyQu-OaZSA%~K0khRYWgnONY|F8RDznWmwk9`t4gLtRdH-=Jb(S%?CjK} z-wU>yy9383bt@OvlT?ScX|Jd;gNl;=@~qkxsQU(|f%2QFptPPAA5=ZBTuIIH3W_PE z$ES;Oadl8g6{=48M1DpM22!dc*QHXLa;|modmCTl(eYwQUx@8oN{}B@$HTk#Kh*M~ zh17BV>OT&hl6!Jo1Dtyz0&@CJiR^TKCO>^PukCR?pk;%jQR8b=LB8RnWD#n9^iCO~ z>8s$pt9Sfixc^2?+w5U z(A}u8FG!1QMT6C7%t$h&GSaH;p{F968+yvM&^k8UH!yQZ-L$33!~PPIJa}{dt^wIX ztX`&cd)NFO#J^F(P)LosHMeXn-^CmBhx!fBn$rd$)6g2b-y1&Wg+`(_4p6(pop-?0 zk)cC#a>d+aan`k}M{PxNh6}#f@lt;B2Dt^kt@q1Zn!Hn5-|_;g zduB=vH(O(@C9erZIV(n{N{jw2z`>7u0oAFryLnfQ1}0@<@tj^TadPUG!?Lwa@3^Sj z7Iv^EE3X*dUb2+Cm)^OLT3$Y)1VC+Ze@&xKJw4YjeaV1lY<&4e_^`|wPpdn2YwwS$(RQxfb%q=HY2|SLEkw`Wc`qV^qazKj zj%&#Pwf&kY8vGCluw>7S*Mpxd&hBb2X49mSl2mPex~NAM&7L`MCO4%i%t=*qTTTDRY(X79k&un>mTTMfZ_O`mSFP+v3X zj@%Ea33tCdOlItphEaX!QTJm{%p`kd(q}wBc0!6xHYShf8$YbBS9X(9ABql2+~~ET zGyR1^K~>Z`W7J24!O^^2wy4`5{;u(XLt|q~Rev_6+JHl+2_JK9?h?S@96S@nxHsm7o>jYH#SrlyOtg^6TpP)!w<=Db_a^`)-T7(3rEBN;D! z<lOR0Z{@aLP}%Dzam#FRd?wi=O{=pVzm{&X zDCtJBxktIk*CvM;|0rdmnnCI#2Z?Q0lg1&tp~(PK-?7skd16PfWPmx_k98bpwUk zUG&97?Ou90*HMChj|~d8lg=?6jiVy?M2{@MytDBG0Y4{dnVwPe8nqWlceW#%8>HPo zuWmSSlax$;dZux{f{yT>(X(34d52SSCt>ZizFE(kw0Wi|FV;mho7!JIlb>u7Abanb zKZYm5DepC?{g-Q7XB9|ppBk56!1RLIQz6!PhP(YBluzG#u;3%oOuFo%4S4Z< zW~=F(p&sz~C2F)KJc-}Fmz$dt#W#Csk5lI9nc^8)T``l|?|eH;CLQ2hJu3(G-)J;E zaDcr&H2>g~{scENJ|wHhXNS&?jL+o<&i3~gz0-b+>Y!Wye3ikp%*Eb3cw|W32B1%6 zNU9TBCuQbRzU1`}9#B)YdiHKY76_F4`}NsigNKHsr9P~`+x@_0KphRXXBh}zQt*RV z2;ZkXgv+5>cc>$;ontIi$70%EB8S8|)8}edR`*|evxncs`ybHM$^oA@voyIcc=<$d zS&e(nXHzBnz56e`HDsaXIj)|h`i$pW?`%`?ZB6d?es+I3Qa33bn9tVE3OYnBF>rUk zWb4(*1Ljp*fyu`P%lcH86+uIA$x@_#Zda!OTH3YLndzxHxo>-DT(%hv1e?_)&q%#l zzR)Fm{kBvVLX4f0i^F?LBgJVsS3vzbGd?vtG$E@chO}1QG6ScY0!|I4P@$W$m<#w&i1?cgVYZyV4(E2Bg&=xN-1$`Sg$#oo)|o#I)LMiI)IDLQT5H-MdPcBwzp6AOv)?E=$%7u9QVud`pF@gU>})2C7a^} z%Xdy0DomakQep#xH%fRo;|M2gWqdK%FHHA~`&}(VC2v=nYHdtG%`yKjuk^9h<7h6g zj~Tg`=)8}yE())ox7(U@U*+s=N%rI?WU;rpsmZw*X(CEMBoC;kyx!4&u*cti(_lUA zVRb8#zo52$Sy!V~8T*e<>ZMN3V%*lAP0GW^@~3CRTU%0Um5f@X!8=VP=)ypy<(0MPAZELb`@;#W9v+QRF^W&#w z05GM8ow6)(a#qz@YlI||?k=;NB)%qo7N{nE`HG2Io{mb1EMxUrex>4 zvNuZB(xNenTuPq|;A}G2{mIR96Q^W_tg}JD?+2Vr`;Dt!uCM!>+S0$Qx4GRg4%zQK zA8ZC1tnoF=+gEd%%%AaSmC-KIYamoVYEJF zS)1>y-;hbLx?}nG$-<4K{2v!^oH#uw2jcDbx4=>7f$^!SJLgKW&|NMj8=6sDPh#Wh zCG2!cQ`$thhfh`U<7J~GtWb}cvK+&F2SJc2f)tX6&d$=p^PlfTW$tBKdv7wOkR zDN32j_n)F$JFlObmQ9Ij&5m9a;hWg+?iZ+ADUm$jJR@7$N2iPWL$!=bT1r2)Kj015 zhGtHQXvu}}U$5A&*Tc_Pjn1CF5QeC*sx5H;J{zM~?CZC5IqX2UpA8JU@$_l!p!!1H z7f_+TQ?*+m%w4y+0a5{M?yl|frm>am8msNQaW=)MSl2tjFoSqPp$@QlAkf`JqLLW1g`Nl&9QT^ADQ zg@9hwZZbS2LjBXzQ`3jld4(nkbvRUQ1DUgHOg;yw@AGO;ufL5flzRG*YykB3okf3) ze)7IU7|lwFS-#==tIdsitDznN9UhrHJ2EpkH8(A%WgTgFm}PD4LGT&9MnO(;xJ!q> zI_%InhQlf@j`YQ~BW>m+mD7D$?>sQsps4DU^(hr&N1Q7OpXE+7+KkbMkb0sGZBeCr zLe-GkagG+9YQv`^*jQgp%*&R_leJ_To$zBZ#9vrqcxRBa%?}?lL_ot?HrqpbTwp7X z2Gg82eGTU6tdF=8cQz|{j*?BrFFE&o4U1z#Vd)5mYIP4=LhsCykW6nt=JaXzTY@E3 zKLDFqr^3HhA06QqBESzDo1fg7JX6PLE1rYOARTVuvkp{`Y&(}otM)^WM8$Up+4!| z;H>PBc2_Ozn9>JDgi_LtzwWb(@=4D*X2R*iTWBjS551U6;GeD zT4@@i^hn)++4WY`mzF-vQFqY#mGI=0>z)3h{NtX?7PPG469%j7@^zkX%{;Nro%stI z=pMl=g(52~y!FGytp2!K8yFs+n-zij1dR_ze%2f8w3V>o;fM*Rk|*>AQC*I0q-}lP zRGhs|T8GBRL&@<_(VCxqfBM73ekqK$296P)+kZ=GOfG!J`KC2fyq^rCTkof$rRvwm ziT6Z=7)~Y~o3h2cI^alED}!H?Dc5r6G+DDuk0Ya+n8De6sejC>?SLc6*1(YOq?-+t zjX_GCR5n$TQ|V{(0UHgXNjKfw3RAL+*vX1XOn3M4?MiwOmG;r`ku#Ra|ykJ_83gEFhOuH&sw0w>hS>k>8S&s_Z7XFJ)De#cO~ z>z_!bye3b@K$}k)+XUNaC@BLO-RmSCkW0KkwF*}1Is2I|KiDBhPkEJxSrLeTy5 zq1oB#;wc$!$YsDaXNN+&iTPIFNGGE6;1)(}S`BB;r1rb>DN5mOatck*>A?`G^OdE7 zCX-MaHDqclGHgvpGA-TN)TlIYj#FJ1)ZSIp-*pzcCr%oo!K|?EPtP%C$nWikq~ zmAUewt-w>P=jyDr5t;p&C{0buN;WHN_NuwJu1J=>TUWF`)0Laa&=FjXrmPHaz2V1u zvvPd3dc{$Z>>86gqJqMh_(7cirLLS&CwDcnz^Ej+_1M|9y-OwfJb+#5aE}|=r53%V ze3v@>Q!aL?sP1&PUFzHKeDK(%7C8=M{M?zT$z7_^$D-^~hqv#&k(vm#sNt+(xXP*N zn47~_E;X1X3_sssb}$*NT6M+GSwK^^Ox3$_-b_#E3`SOOU)GQ`Dfd=2nDhs8@78B~ z3m0tj)a>W=({nQgr!7}^eCa<`_vB3N%Mpjp8Ha(kQk_FBy_oZq*LgL0Mo$OcmY2`t z@&Q`?qe7y2j&$1+H9yIunse+Qm+hdkWhHtde&Z80rL;;&)#?81X+8FDo|C%BY$+{u z2v7?-(w##~3Fxz8qPxs%(4wZ{6ph;oMt7RiQ$|fh$C$IgCu)4T&3n`ok_o5aWdI>l zvi71kRb#e9`biBWjAt{WV7omgKZe zJ%b&5b+CIc*r>T@+|0-~O?#<^hKTgF$(g|v+#qPwA(9i#>8Dr$v&Ye-nXI#sI$`*qw#)?Occ zkstM%w&)MI4Nv3;yq+O??%e>7o`O4Uh@OHIAMW}8&D(!Ryg{G_1H|=dYkiE{i{Wmk z2zIG3X)PI@mDV2d&KzycG<}R*OOJT1PHWcrwXwD5ys&KTDeb<XmE2;%`584fhFpc0f z*>Y!|uBeeJfcsEXi(T)Og)i+EqkyvDZpRw%i?6+LJW~ zgX!IQpYuYwtGD60vqQ6bw#?MRn@sQ;^T_fIhA1Zeem7z)PSYa|99wtxtG>x*%vnl1 zG*XhQ5y$$iN5lks3vbNfltI+FK-Jf}#n$%T0b_gwjnf^An~r_PA^42nVDdrpGRN@j zwhDgp76r3pcub%kH?F5N&L%fV%@hz?+^jw50e`q)$%|DyiuT&bAd+%lI*M)#0wQUr zd=&k){yvg+Upk6zKkgcoYtZwdN1~)s*BM7n%=~1OG|~G;@*Cx&==VCo$XN+I5G4iO zK}J^ZOGnYojx&;b_(0vKxJHYfZD07k#eR*K0qoNs+Yc9t<72Xr+4Rxfra#r=u5pu- zwn~NKsH{z%(R)^AoL4Q|bNW1+QMpx1ooIB&9cp^JiRdl*`o_kh`!Yqfty3?8cGnE} z2ctDiW1sq1Ca3k}ojbqU($VXrrA{Gp4peJPOOMv#ob)8iS=!5vW6H7oh*|;Cu9j3% zo8p|crfz(dGHqLzbDXQA%MF=bXmcz(GBqblXAY0+Qimv?lbqvnonsBgl~rFPl63+)=EtyVzF-IdCR*+G93muV?d zQjW2ewf2tii5rvZGC8BRY^IK=-)|a`S*5b`yW#aAeYALHZd$hY z^^B=6;!)Q+sogZX!Ol-N-Wg~}G8uT-K8M!y(FO+)HTwJzNWPJd1}{;Obu^f}4(Mn$ z`xp>*b7y&R4v4Bzh4D=$AmuHaF~0o;BpbZ;sclEj)+YaTayMmITXz~fciWbso}+p_ z$82%*(DZ17cn;3IrVo`$QFpbPz22LOE-8}GFrgn*>)KjN zFyJAX1@ZP&VR@)Jg4Pc>w-9|$D=r`D*J3o2wO^uCs0Iy2w7MpTE;X3n4`f)bkI?I< zf=jGS{xv>^g~QFCNjOQJJXdnJ|G1t^svXm+#Qk5ID@&e%-MVXv{0!DLH-AQ*Xdrc0 zo2HYg87)0u&FF{*sQDOO$6Ix`x~CEkMoVtLj$Ec~I9;CF2S-&Dp`} zsaa2@Zk|H}qWvfI@6O>8O|_+G)D`M>`+D6g)~#0+25V(X++J&S+>w?uI@?#?XR_A0 zut5*svNuLeL<+)BBw8rS34*ehY&!HX6{#th_~7I+bt{Ypu@s(tQ=Ldm&IS z3rC8wWx-kY-?T^$j1^}}<0DaRz$u!_=2U~BcG}q^c6>4~x1i2ChXz~cr~?Jt_&m>$ zQ*_-M8NE|o6frsGv^4Ii7)>*uG(8+SGISLUr5v#&RmaGv(jW}j2lgPG9j6Yver4^iDZxWlry4kWhlE} z9+g43^GKw|LOH-0k>cuk_vS#WkNrVxG)Jhy)x%;x2>m2X(HN||wM#rrk6Q|i1LkN( z>eBL-Kevz)M%d93QuksuTLK-3h+6*L#oy*nNx`~dyb>TNVxGhfJI*q7T_V9{riH0unMd6TytOJXglh+u^Z=qO3)z*jp; z50#5E`o-n?d|~8lamqbW-qgb;)J&G#%p^1B$-tSaji!+74>g!GvOm;dk_ZnqD2s@; zHqsEy@J1STor@MHeBhd3$+fQsGYtBwmV(@Okh{G$Kj3{1liObh^V7w=e~qlA`G<)O zJg39^R$~VQ1;IR8+jufB#G5d4| za;=}i3$p#aI`EK`2_A}4Ly`x?IOmz#eK`>mt37!0h}7Y|T};PZ_0Fifg}iehWWW|B zUk65=)8oW0zln0&*|At@>aGZ((X_$#TfvqZ?0{`O`m)eE8`b25bzYC&sq0i4DXg{H z`&#N?RE(%^DJTOyT{k!(1*2aS^V0(jX3+GA#P|V`IZ50lC(6!F$r@1ii*}Qm+dDcw zrEV3BQj)z=GfwCx+lh7ODc|euoT{$6R4Ju?y@XXxkx~cUxc9COJX69>{T5*&s&`0V z!F{B3+_}2NH_8oHi+&j}G}k^RN7(fD*K{}WXfWVa53hWS1Lu2B$^8SPLvp*K40=w@ zot9C`Y%)12W8tCM>5<~>j0{)=scc}8A8pbniVpvz}!{bwPW9q&bdl^{ER4$}HJQS@fIq#-;mYCixfwZb=-Qd7Ym?U=NM4(W$**#+ z=}>XXVaXb~b4==9o>X3u)NQD&Jn;@I&c zhM!euA}aM6PAQW>?Ri(|cqu=5!?Bb>RZY?&;$UUA&gKora<%_f_Pdv|7N;iV>#}qb zGlnGO^h22fnvrv3)j_mp3=&W?ID2l~3WshWxu_0%kO-xPdS2lxg*B|!0x&k-kC*|7Qak~bKbpyxs zxzUE_9J}139;YUCv0BAcliOIL_HEQuU`|@{DYsxv!DPRxp3=35`&b!u9p0~M-puUS z=#!qLe$#)R8I?X+OX|8kTaX@ftQO{@j@(dwO!5*N8ag#IBR#lO>e!Hsh`iRoyYxi| zmDY8wGz>Q!K0LHfYR(PE2ChFml)5%`(ErbCdu#u_@7kW)fBXNHbpJD#6CFL*hW|{* z4(D=*t{)gmUc2wwwDY_t>L%mE0*DiX+#Rrl;K4_tyXA{N_pcI_?wm{=1|0MDRcE ztM%SD2=!k<=KtlT5|bydz;nJ$3Nk&<21hvfmnW;V-cJkMU;pm|z~Wzugl#3cC2vH^Q`mpag~;G(o}g-`s;0T61ptbsjZ_8D#c4<4|FZ@ z{WyqIH0$p!xj>UF&2lwExtpzI~F zd;Z@&9=OK?_juqQ58UH{dpvND2k!B}Js!Bn1NV5~9uM5(fqOh~j|cAYz&#$g#{>6x z;2sZ{Jn)`#_mVFXu~=OGFZ(0s>E94{5m9eD! zuAZ5Dcu}Te9}s(5P5zSD$Dq&oy#v4BEB1N!_pCfW`!MzV)v=7L@0wy!rhM-oI~mY_ zU;VsF?`1mud&iz#OYh3q-@5wb=h)cJD`n#Op|PU-d_n*HkXYIMyZnJamHa(8_RH?y zMg99Vv6s1jzvyS5D9=AI_Pg%ib6UPL_9pl5X)S+M?C;#aNA%zKi@n$VJFow~BKC3j z?{oV3`^3KB{{5jpy;COdFOTiGf0wkpe2;scL%i>| z9KI6biT~s9)ev8G`C5qg{k9{&9^%_BuY~yes~q`_5HJ0X!#BhH)eheZ@l}^sLp<>s zM}9lRW6KWT3Gqdj$KDYv$KlsH@*N?*?3VB5yF>Es-&-NR>i)g{UqSi4mpk7UH$r^f z<<*4?dA+!Cxzhd+lD?!WS)k#lqJuylUaGcl!3zo-PYdSa`<5 zhb_Ep;fogD^^aydJJIgZ{Excgi>lR*lpV^)*3*WKu&i9-3bX$0zh3721WZ?@I zzHH%Z7QSKORSS=8nDg6Z;Ry@RSopAomo0qJ!dEPO-NH95eA~ho(a$n&S1f$p!mAb@ zL;p+tT^63O@Qj5ITX@;Rmo2a*~Ig)dt8nuTv!c*keV@tm;moQ2O@ z_=<&ZSon^G$L}`VnX&L;3ol#vqJ^(m__~F!V%);=-L&v+3-7?Vg?g4PeAB|WExhBu z&HjvAc-q3_7)R00w1ux@97Xx6g~$HaY-btcCF)tV@QQ_RS@@2H$1xsbx@il~T6n?2 z=Pi86!dET4V&PjBzJT#0^R;Z@YZks`;c1LZsXuGsmHYYQRm#WiZ|0e+%zW6w%ND+9 z;VTxtZsD62zHQ+hoo4&v7M`~7tc7o2{7-*YEj;!(vproFp0MzYg%4YJ`U&QAvlgCv zhu=Ot+gUU(Z!fXfF!&2JasHa@EP;RBnc~zxErWl= z*_NRB0>=O3RkZ))F|^y{T^61|drSF@g|DKXQods08PrqC4_kN+sgs2L0XOA47gSpX$^vB}$%#{A&=;S@7p$9v}x^g8xevzF^_Y7GA*n z7xm9u_>zUMT6o36w=8_e!aMPPL_51JywAdO7GARO1q)xc@HGqHu<)vd$3Ec4C-YlH zeIbuw+(_PK;Ry@RSa>JKht$7_aSr*4g|A!qriE|YINDF9TR@!uDeCDw_~qbB;4eVG zvjRROb=aGK+p_Q~=J_dK#k>%C9P>QnISXI3@Gis&^<*u4!NS)qJb`$l{(^?sq@cMNvLy;VTv%JLvao)YAt$KZAZSW8uRVUa;^^ z#0m9hExcsmT_5zzmwMtB-fiIt3t#@MS^tWKFIO${7QSiWTNYlm@XY7T>1HiFXW?rW zzHZ?a3-A8C*`9=jr!9QR!j~<4#lkzjV78~z!n-WIY~k}3zF^^13*WZz9ShHW(VVYg z3olrB#lkl%eAB|yUozX%XWP6gzGAks z!@>&|Ub67Ag>PE;mW5X>JhN@KKWpJR3ol??%JzKT!j~<)>$_%q;ubz^;ROrdw(uPb z?~M8LGt5_)g)gGt{4VBOmMea~0vzLf^7Plt@*5VuhBc-WdB@dw^@D({ydEL?iKhmz~N8wKKPA%)54eFPs%6YPx4OqjeNzz zSK&{}XW&orIQ&UI4}X$(!Jp*I@Mp=L6H@f7Fjp@>TesJOe+IZ&~;< z{7?Bb{7>EmKa;Ooc;Q}tyitA)Dyz|j!z7jX{%wx^G8}Us4tXud3;+*nv#5ws2;{3UI4_ZTf z$1{01;+%X9aZa8^Jd;-~d+7I z{v=PppX6)s=PS@|RNznYPP7~3X|x;U75JZg7=9+-vG6tcpYmDwpF9CSlUFQ!9_BHUqHJ--i>yH zd>!ou`7qiI@;<~f`KE<0BhD$GMx2wcBhIJMZfqdV$-5Be(cE9{alA z|B|mG&dGC#bMiFenS8^-7ZB%^-$a~~mk{UVIm9{n3gVo+4{=Vui8v=OBhJaY5a;A; zh;#BB;+%X3aZbL7I44ga&dDo?bMgY>oIHbgCf~B~6~sB^`w-{k6~y^F5$BtTbMiRi zoIHa#C*MSzla~C;~-iLT5-?Z>W#5v`+5a;AwsY;+Z^ycqZRM zJd@8Op2_2gXYzH#Gx;#$nLPFgf80pEgm@-TBc91O5YOZ##4~voaZ6sc@KwY!B_JMo{{wH6A|H-@IfAT8)Pd*R-lMlns zG5DW+$-?K+4^n;u?FM-P?FM=58o&OMFQeTc??bymzJ+#!d>-uvc^vHq`5M{{@*LU? z@@=#mQho>i zBwvI-$xHAjc?bMS-U+{vuUPmz{7LyO_>;U0f0D-vEc_;i# zzGC5h@IU2a@H6?6g_q%f%6G#5@p@5n0_UV67#zUw_^UPif4|E7h{yXQ2hsYc3of5WUlhkW&8 z{J(7B!{DDl9IjaSwuLWYy&3fsApcH`D^@Lh$HF^$o%*Ym)=^Ix^7q5{-+AyGupX~s z;hh-IQ$G7NKV9-g==mY6CtL!*8tcQ?z#jqmb?|Q>J~zQXhj`uszX|%Q;4g$9V#wE} zh=&gF9OUERuZKO^r0)mvZpgm^@|{2K%abP{|7EQ6OoRU??Cb+yz@cf-zk@E1e>0{DmF&n56K_^k^5 zv&io@_-UjYNB{DCq?-W$CCI1242K=kglLfyK@wQ~)TNd7pc9?qlKJNRU ze8IvuEWGRA&3c9{e8s}IEj;}Rv;KJtuUL5JC(U|t7QSrZRSQpSne~?~eBHu3u%Dgf zvVs1Kylcmt?y!ZgSopSuXD)Ht0o9Z+-9-!EwD9<)W<3Q9@51~Q(_MeE-!75o5dWKK z2Zq5vg?69-K8<=>27f2&`#ktH(6a#kWYp6|@Cx`c_?uzp3iv^!y9)j(=vfEUMR0V@athu4*cDa9|r#%{67!=6pSktz_aKd7s1~m_IF8rQvWQ4_=1CDTNocI zdGDV!$X^M2miPJff_xqFM`7m%_yYV;#`v5(j`2D9CiHv~_RK>Mc{lWsZ$r=RD90V} z5yW9P^uG&n>zxCq+AH!h(j`wo&x4?6&BEuQhw^F2e-r-f1J5CzH^4t9+>3{5hgj;|7Si2J`10hPkbf`z0Dd?0WWe7K`33L-;%X86 zHHhbB@E=9JTLr%a>8^wSHR}5Y_#Z=l3;ZLnXB+$l&=Y&F-!H!eybJsZ;BoLCq?-W0 zFY?<*j=0T$KOFKo@DCwQhQVKq`c(p7fqWVK4_RK|Yp`bt{Fjig74Z9`yw<=k!PRRO z@Nc3$+yMVJ`jIX0eXwU6{87kn?0tTDeG+!2ExcsmD;C}fek1Jf1|I^?fG@z#Vemgg zxy*x~g8UNr!=Zl-{J-G;4e&b=Kbzp6tTjHdSQY#P>jn53$j9FA`}vKqvjhAE;BgC2 zTX@#OV_0`h{aui+!u|yKD-h=y@Lz#{hQV(KFN2RGUyI-iD3=xR=Yp?;e**Swf^Q-o zw!uG(bUUyw`#+H1IQRm18vH}3M_KS+hW-NhB=pRKzXkqT0^dS=xC;Jx=&6AJ9^!Tj z{3Wnw2mD)*@5H{~FTtLLr~CaHc^vXtv=77Rm&p^5AB5lf!24lO*}_*XylUY&@b4iW z)?p`k0rI~Jzb%447Ceq|Dfu$wp9lF0_%Fh58wY$plW#)aJ=$2e9(}04XP`d=ehvJb z1)qZ-a^O!#ycNKw5f3GBbwaiGPZ|7!=y&G92Vv(T_@m*6CGck;&X>U_V9yHp4}q_N z{~X$fb?^e@E8stid~JZ=7xrv{e*ylifuRh3$!%HMh@&$aSBk#s{I`Rs>(~%eOosPT%-|5Jg@tuym58vs? zH?b~)yo~R3k-UU*B=5lY zR`L~;BY6hpNM1!bk}sef$-7aG5!$M7ATd>Q3J z-i2}@A4a*{igvO9e(5EC!?%d?BHu)Lk*}b<$ahd)QcolnZ(6fxdsp zmryR`36u-@2FiuJgmNM8M7fZ!qFl(cC>Qc7%7uIZQcglnZ$oQcAlnePh%7r|Rav@(w zxsVT|T*!A&F62un7xDzkg?t0$LY_gnkT0NIZa{rmMY)jgpj^lop~q>toW5!eddOp! z`|TU~67)O{A70=pkQ(9`bJJc_!@1 zLJ#>8^pGc@=P78f(%@f*{$c1RUx9w|KInNe#t8-JAzy_a@(lFc1$#=+L%s$* z5A>9whkPA+$aBzhGsj{vQ3~I`oitKo9v+!jCKRW#}KpIHv;r4{SjXc{lWsuS3r_5N}oJAx}UL zc?EiY5B6+B4|y7T$Ty(pm*M9f=ppZe9`XvtQRJJ@|7`d__OE{bPM(2&@-66jDE!s| zJ>*&FA+JKue;Inn*P(|z2R&u9 z!}HKXUV$F+VdzO=+_(TeEFF?U9Nr$UC8jd*@`L%s?fK+nq&=R43t-UmJ8o6vIw%02cmzda|PKH0&ur z5BVzekY}Lhdic2nJ>+Z9L!O16W#}nG5BWOukmsQ1ZO}6hJ>(VWAs>dGzl47lpoe?| zddLgVbLXYLL5t8sz6m|#CFpq#>{)^y@-65gFGEiT_AEmWc@=ud=bJ>=Wa zL%sk#x51uO=po;M9`Z%#`6}#LgC6o&hd=%yUxJ>SF^*k_9`X+8A>V$Q|DI014E+i8 z`xWRX?}UEx73g^&^lU&6c^CAMuR_n&7(Z-64|yDV$k(9f2*%r6&_mu0J>=`q^B9an zs?bB8fFAM+^gI>sYunI6o`xRs4d}t^U2F$>$ors&d=q+N@K5aD{C=D~13lzh(6fRB zI-rL<3q9mj=-H3FF5HcY=Qf@5NoZU^{l&>nVz zp97DBKLq-_!K?630{q*kUup0U!#^4DQN%+Q{E3jyf&V?qs{sBb4foKR`JygKvSag1;Ji*1$gv`E~FN@>KzUDg3+%em(NF1%3?WSOtGI z{Idgo0`U;TIS=1KxpaVE1HW~G-w8Y8;Gcw^Zt$N+x(V=M_@@v2w_tw;{65%+m<2xr zdvf5f1}}hL1^<`8e-i#IgTD#oy8!-QuyYao_3*d_kb>mk1m zel5yt1AGvAHo*_T4_n}eQ7%>Rx5EA%@Ylm{F`WBxGyKp2{#e-41^z|&IS&4#(BBRI zOyoBKehB&M1Ai;zGvNP*bhF?yNOu@~2>B|2|0UwB1pWueZyEgU(6a!3hH(YH0=@+P zeCS^RKLJ0if{&sc*T8=Zepm-zf&LBf7r~xQ@GIcwE%1jy&o=mP!*4s_$6$X9=e^_* zpB>;o3_V@oXCWU4e=Pja4gN)xdm8-Bu)h!d>qs{PemCT^;8&vDhslv{0em0qEP+26 zd>;H2;0xeyf<24i4}<+n;J*udR=^(%z6#!pbl1Q?i2PQ-UyOEa1N;>1+ys9Q7zZLCO z1^fj3wgJ8dJ)7YF3O`iAKZbm5gMSYCcfdakKgV!>)aBrv;J**v1zv{V;^2>fe-hwN z0#AbA1N(=;e;(yh0KWtIDuF*8dOE-9&v%iRA%8!N z0~f&Wf}Km?zkqx#gTDoKu37kog)dZnJE>GPar;b!2cco z?EI8(4|%tR_gQ$(!b=vuVB?=P+tUI0QN&>!d=cf62LBG~Zx;Mkly3q2Quu8i`~{F- z0*|A|X+Z5%@Cr^We|nFZli;UxoZE_wV*e!j@F(DQPX<1qLv>QMpw3E*o;mwXZFl9!?9{;+=m{F^Ap zMeyqo|FJLo`66G2dgj^~I^rY_z69P4{wwf*0{jv1a~iw@{>*}Z z1b)bY{}=o`4E`DTp#c7R@DlicK>sTEpI{ug2L3ga3|=ehj{A* z|9!+y7x>FiUUBe!h{JC1|ArqD;2(e=GT>hZ&w}3y`*YyGhPWCAzXtg#fPV{imcX|m zzX1N%uxAncD@b<<{JyYr8T`TEE8vGvuUEmJgYvC_&x3D(zX5h`g8vTWx4=)r4^{A& zz|L*(Uqd`}pk5SUe<%0`{L=;gS=bo||3%o-4gL+-p8)?C#9;>f=U{&p{8G#_V`+(m*kat1;O6ZS+uR%`% zd>*_6{&o1X44#00=D{Bcp2qqO@&(Ah2643r{s5HkCiqXGo^FAE5BaTvSK-fX@B?Tk zcfdad{V}{JJ{9@OfIkC%%Yy$LeaAA|op@c#RcXjePI4?%wy_#2=n z4*m}0w;TK{>`8#H!p~*!FCm`i!M_dp1@LLuvk3l8*s}!wH_*Qf{s82+3jQ4Ue;fQ? zk?s!o+hJ!6@7<3=x*gyjLp*eXZy_FX;BokK82o|IUjY9)@>K%wN4+S6-+*-I!S9Fs zR=~dk`3>;XNOu$bgV3`DK81W$!LNXw+u(PAr}6&&Vx-##eizCy1ODsqTNeDA(4PZO zAiu-lZ-e{_`0pWKtKgTz&NcAo!$0fb^GLS>ehBt&fIkfJ--UUA1BlN!_}9U^!S94U z3Gm;CKhxmHU{4?TpF__A_>P@*4;LTi8U-jn=UW$Bmf?tuRj{M`B9zCBNbd^h+*QBV88 z520Lg;D3j9av1#2&^{NypN#k{gI|es=fPvJa{;^y_AG(Nz^mYgVdpmZ^U-d^zvlbr zgYa7d{L_%12j8Zh;2p@<8u%pSE8zbJ@?D6lldwMy{;RMj3!Xtd7r?)Te3igIgLD_c z{{!`F3H%7!hh^|tDPQlNpp_6`aQDnq@SdyWy?-i@zYFPRu`hsp1M;7Mo-OdNA|4h{ zzsM8c@XMXN3OzT#Z;Q}Fo`xRs803$jUUY!}IrOK&V<`7^3tvFGl<$N53mI<~z6d>( z&p`gS5La37H^a^?@J|c(;$bJmy?EGpia-CR|Y0e8ruI2@IOO2Zi4qf{}%Y8kgqEEo4|L#UxsvJSPz+od{#gLO3i;gxzZv#yf!_}QcYe#S zciYHU9Q4lfe#?v3i#)d-wp7;hkv%f-w*k1@PqKr4*1() zPv(DpKah8T&p=Nc{A)cn*51;OpSAZ~O7^ z5bzH0w;>+7zzeV^4t^`-yTNaU9}?hy3_qm7ABcG91Mf$EGvF^qoMgezfe(X!3cLh< zCE|P@d>H92fZq-KGvD?7NxlU6pMf7%z+Z_tTm!!w>8^ucf%bgc!aKg>+e7(`g>OL5 z$C0m1@YkVyH<4fRD&!xHa*QF}hr#|X@V`ZVyTN}5eoKIV7VXc@_x${l_d)&z@N*9Q zH(}2(_`4A&G31xL1o=4pQwD!M>emAJCsB`QeMeMFf~zJYVm$#1;5Wc;E8wq0{H$Od7x^mWp8@@A;4cHOfbYQm7~=d_;GYig6~xuNg;#K{ z1?4*-|3=so2Tvp2Zt(jf-30if;O8{>3FNB}{8y1~7W{>f&w>9Y^bdo70Oe8uzc2KZ zz^_C*QwDz<^elk?CH$}i{u_vsW$;btUjhGd*s}`$9q={qHS|*z@UOz24e-B*KR3bu z73*i96Q1P68gKq{{i-QgFhF3 zPJsUhcpChDu(J<*1a@Y@`{17(_)nl*hQSY_TuR{M$X6Nsk6_O{_|>p~0ek}GvIPE2 z*trb;tH{?1coOlv27VvdxeoqRlvf4(4UpdeKaO;_z#otNR>2>Kd~Ji@j(o)~_2X&^ z{_g<47vwv^KaX^~z@H62bc3g0PXhd(A)f}n0s1rG3y{x(zaR0O1OF7teHeTb`6_|W zLVp?j0OD{S{9fRT;B!cK3H%m}Z&$#-1pC*)uY{eO;5+b775qI&H+Gp{zJCSzEckDu z+;iX`g&!8c9|rj)@Y`T#6?_o>*#_T__>bd$t}jDA0scAIvw1&1U*u`XzZdrOf!`Z? zvfwWQ&w+mwb`FET3Vtqw-{gIakbf_OS0TRw{$Z5M2KdjRzAxiGj{l`SI2Y~-NVfp~ zGUzXX-vaqE_}@YQJop`m&js*D!*7e={|x<0;1ej{W$>0*+iBE_A z0{CUnlfm~R@)G3#5b;w6{}%E)4}O2>kK=uTd;#)*4n2$DKZW*T3H&zra~b?EAin~> z2)+vbVDL5Y82q^oz5)3P_#0u*2KY}yeiQulDBmsc1@J2PyU<^3ga0Ay+yVau@OiAy zCy(9NZ#Vu2<=X+i1KtTfhx!0h&%n+M_}?PkHTaV}3;7Y~$${SpdxpU)@bfC>CCCeqzXkQH1fD{F zRKfj;#CZkl6Udh#|23q$0)7&HUIo7n z`V&9q#})Y+68LW;-DU7Mq8uyW=U~qU_#x=o1b-^{7WiYptKg4E zy4&D=NOuSP58=;F^n>KF2l(y7@4!DD;GOVKC-_;!VHfyO@HqH;!MnkSk!}L~%Sbm3 z{vqV65B#<8PX>Gi{>*}(g5PrB_eT5-gHJ%nL;nK!amX)% zABFr9_-XKE@Z;bs;0NKiRq!`JehqvR{#gfq80@ToKLPR^;D@1q6Z{L{Ti_+=se)ex z`EBqe@E!0Nc&C9QXqGrLc1m{4LPG1b#L6 zGWd(2e+B$;(7y`)Sm;>;e;xF!gWnsx0=^Bt0X_-734Sfwy={E&Am4)g*I<7Yd>Zw7 z8~j?dpDQ?zoqPxKpN5{;RepVW7VPW*|7$dSo!~b@ei82}OMZJiF{|W5x2A{?I zLKogo$rF%&6!Mh@KZ$bb1OFq$Ll*qUQD1W4FNb`|#vkYVlkx?~zYO`E2mf!_zX1Mx zjQ5r;e9gkE7T(qA+e!Ty3olvt67;_Z(VmpSuL{7?A>_@BJ{VP-uQ z_@DBHN0{Yfh+E1p!~f*z$C&kO!vB=d{)kyV4!?aE?L#;C3((H5!=L0i_>+7G{v=<5 zKgrYZC;2A)NnVCO$vfds@>TegJOh7{SK&|cVfd3g0l&QyeyhN54)V4I4EC}^Wt zO$9ZIRTR`1JVc>2id7WU=t7KvSPdRxzB$KU4DO7_=X>7wdam!fz8}qx>~-IJtg+@C zbFR79-mo_G5v-r|ji?)aHtI&-kGj!UplPDZ3y3r4#ZuG^d8+{h)wlB`# zZq$vw7P8=+ZuHft8+{7uM&E(D(HEd@^rNU7eF^GDpN+b`hxyiv zy3v=QZuE($8+{AvMxTee(GR0;^mV8keH!XU--Wu-7ou+Tk$uP4H~MnajXsLHoq)Ra zqi*!&s2hDU>PFv&y3rS)ZuFz58+`-nMxTzl(RZV6^u?$feFEx6UxB*O=b>)7I8OuA zjlKePqfbHI=sQq1`a;x=K7#8R`bN}^J_~iD??v6{OHeoZMAVJG8g-*DK;6#8_2Dq; zMqiD((Wjwq^j)YMeKG1rpMbj2H=}O!*{Bh=xh+bHTr zUx&KUr=xE4-KZOV3F=0lh`Q0YplPBCVy3r@2ZuD)a8+{(?Mn8kS-RPT9 zH~J{*MjxPV^wp>veH!XU--Wu-7ou+T5xmc(Z$RDXvrsqs7SxTt0(CnWuM5ej8+{Av zMxTee(GR0;^mV8keLCt!-;KJ_7o%?U38))=BkD$Fims9WCnbc>{*ZuD)a z8+`%lMn8(W(Kn!O^jWAIeJ|=pUxK>PC!%ij&8QoF6m_HTK;7u;P`3-QzNMjV^c|=h zeIe>bAHnBQ^o^(+eKzVw-;cV{m!od<$*3EB3+hInhq}>sp>FgIsM`@ZPt#F1`YzOs zz8H0*Pe9%1n^8CVDC$NZpl>PFv&y3rS)ZuH%#8+{|{hL7PA0|y3tpoZuDuW8+`}rMqh}!(f6Wm^v$T-%~;>EQ8)Tt)Q!Fz zb)!#4-RRp;H~Iq9jeZn$qpw5V=+jX*`YzOsz8H0*??>I}TTr)4P`4=RM&FOR(N~~u z^eLzteFy4BUx>QVNAP(&eFN%7pM|>7ccX6fC8!&HfV$DQp>A*Bbs-ORqYqFw`fAjT zJ`HuF??T<^i%~cF1k{bb5p|=_M&0OpQ8)T>)Qx@^b))Y<-3Bq=3Q#xtVbqPj4t1kX zN8RYVQ8)S$)Qvt7b)#=a-RPsJ8+||OMqh!t(T}2T^j)ai8F)P{MBV5|Q8)Sq)Qvt1 zb))Y^-RR3vH~M7MjlKnSqt8R#=mXS^z8ZC-kL*AGc_w`~>Xwh6R~Dmg^b!30g}xDW zqt8a&==)JO`U=#IJ_U87Z$sVa3s5)uVbqPj4t1kXK;7tjQMczX-%3z7`UKRCz8Q6+ zkD_k$0qRCyjk?jNp>FgYs2hDD>PA0`y3seFZuE($8+||O_GkQjwj6b%Pek45TTnOp zJk*VT7P8=+ZX0l(R-kV5$*3EB8|p@1 zfV$C-qHgpJs2hD2>PFv#~a@37J5p|<)LEY%nP&fLLLu0QO{yhZ!DC)Tk=WiYA zNuP##(s!Yr^u?$reFEx9-;8?FM^R7ue$1TK2Y()pn~r&PJ?hhqc}1U%`1g=M3ZH}eL3}g(_YmI#UxN1Z!as)i1g!s;A%6g$hVwLn zpL3;Ryb|DV!2F5ApMdt{!JmfXmc!qOacPFX9_^{a>(mm&H^6U)_(u3t%#(ijXVIPj z{$R8}5!e5Zqrchk@1xEsc->5#F#fue4!;WR$%3y$o^1GwF%K)?KSF#p{9NR3f&U@m z`{BPp-MaAlUV}Wn@K+$dAATNSBK&W$-WI}Nit#FjzYh5u;1e*8&G37pUoG${@NMuD zFfOC;S*T|OpTC`h_%!%~5MKa)FY1tu>*Na=55F(sOW^Yn-vNIB>d*y03G;9i{tk>| zLfZJ}V>jTq1@KiEmqPfvFfMiQC!n2e2ajL>ccDF9@Yf(uH+(gGFZ>b6(+}SRAHctY zb!-%VD*6?fHr~$5QO^YUGf z$IXMUMxFxrhfwE2_;V0n44;SNmcT!T`j^8OqQ4dJ?Ko~V{K2Sy9egv^jRyEbaXvP} zUyb87!>5eDEJs@4FTs3hgI|sO9q|3APZ#{FsDC&7p*U_Y{7z_RKl~S%R{?w<>M#ud zchod*lHGJGTa8q~QN{(Sfr_@AJiZSb$7 zJst2jqYmBh|3rK*{K2SyKm38HTLAwg@(jcO6?GehPsRL6z~^iq;e1bo??Zet{Do*w z3j7G_mIj{+pAP>y>XQZkDC&?6KMn1S!k>sddGL3@7r^g=_7}pZyjU!z~$@Rwnp_rjOK_ru?T z`~mzn@Wb$5pl+k^qlk~Bk6#bmi`S_H_@5z9B78FHmJEL(@}$6TkN1gb@U56X>F|vh z$1M0)aolY9Yf-l-{BdZ10sOIOXCZtu#=RK61oNi^{&3_khkpolu7FR6uZF({{jGza zf_65-?}hkg_`jl_E$|gsuiD_hMtlc+2Kv+3yazAU+TNNsM~|`~_%dA^cwuUkrZ*domHbxwxgfO(PvUypS@4gM3fKOKGsj++fXfVxHD=b*oN z@I}a90Dlw4y%_#J#FxOoiGG#C&q2Q`;Lk#Rs^Oc^&N}${m~Rd6d!e1p@Y|uCE$~m` zxNYzc;&r?W{$td+8~)#@b1(b=>d+6rGmbk9{}u9#!oQC8M~)buZ;zv%iST`xpULnC z;QUH~zZE_W{!<(`9liniv)~Uv{j=eJfcPkUJ&v0P|7+Bz0KOjWDTbd5UjiRsyvpIX z#k{J3|1I)V!~X&8uY=#jc?iEV#-$Pdhxk3-X86Z3-&)|CFn`+M3z5GAegf*>4Sy}_ z+za1~_wy0hE zj~qEZ4^KtE65zX$KN0?U%&TPh3((Fq_#07&bod!qf3o2JfcR|qN70@r{0BI09{l%_ zrx3msd5YohL3>Kz_s9GxhyM)orvmbYc;P*j$y5TQJeR|=4jn|z3eiQ083_pzV8il_a$Bi5{K5t8qCjovT z+LH)>3i2ewUyb+__;R#A4gN)(@9FS2pgmde=fY>hFT%Wy!XJ&}=E29IodxjkAWtFu zbC}P?@OvS?1pZ4Lw;X;R+FuQS2Iff}d?&`S0sc9(zY)F$$8Cmx8hKjaGm)nQ{%xFJ zUGNWKyn5je!g2fI&&2u=!2bjBqwt5K4hdP~^Ya+Yw?z0`P|sxe58zYahtd8t_&(Gj z9sVA~XTeWK`?KNqLw}?2$(TQR@Ry>U1@JfFxP|a_m~X}K_hGzB;IBo$%Hf|u{%ZKU z5nl&?0ovIB|1I(~!Z)Kn&G6qx{ucO8Fz#*erHJov0_-FC@RRDi4@)W{v zi{lod*{7h<>%eABlRl!C!-Zb-*`Zes;rOiGKCM zzlr<-{A+0EF#P`Tqwt@jJ&~iw=SeZ*6X4%Mf0N-mvF@e7{{#8c;2*;JkOhA;>Yok& zI~+F(--bMS@P9x(3*g_yxEI3r!xzIZL3>Kzcfsen;lIKB zX@T!Rd)nYHLmfKcUqt>c_+ya28~!EKtrz}9jAK9iFVLO@+#h5sSuXFvR- zh!5aTME!^14@RC*_$cOQYNR~2K9-;ABOhi!B0c}0{B|YheG%V(Eeih4$S8g_$tJg!=HlVR=~f7o{&B{EMhhGyH7$7We}(f7;+1vF>%i?*`umpMpAf!+(bJx)**u`r8k`BVLaJ z_)F3LQTQa(GvWC0`Fs|9BK%*GCk1|c)FBOi6!lMsUxD^#!T$jBFdKe*}7?(!)Pq7X( z!~Y$1Xn}tMz775ow7&y>4eH+o--Gk08~$(TZ!i32%;$diz0ltPz8B*=41X~4kHWVh zPujV$`Rw1i)SzGK@ZZDxnk@KTktaDjmdB@9jP|6!BTXa?ehBSMhez2WS@6ZEPd5A? z(f%m>SID0S{~q!b!2b^8UI;%0d5YmN-6AFMC{Lsu{%AZ=0pE`N)$r(6qz?XZw6g&o z-HJ5AUxD~$_@{85w!ot~kv4cNpOFsu@8S1Gy5J|mcf-fyxV`YD=s-XG2Pi}UpM?Cw z@Vml~!cT&ab5 zAwCa23%&sUG@KWO@E2kIDTdz`^PvR(b;Os$e}wU^fS-=`RKp()Uk85-d;|Qk@Qv^@ z;G5y6pq(x7$05EAegN(7fM0<+bip5wJl*j8`?G0iXXBPY{edZ^4&r;^XJXy!hd&qb0sMLJ!|*3_{=?5jeB`9@ z`F}oq0(>ESBK$v)KN-FV@hR{>hfjmQ5I!A#9()%3B&;*p@ONR{qwqUneanOY1@afb z7sD6AUj$zazb)o@3H)04a`=bQo(lLp%(rUzU*WiQ@V|y{fWH{N5q>^=GyGjRzgplg zMSL54DSQX~?pSBK;IBs=y5R@W-(L7Mtdsrl3vk>3el^aQVff1tKMH>pjvL7xpZ}j? zJ}1Ec81pI-{x676hQAWWO@Y4}J`H{$d^-Hu$e#uOJH%(hSHMT%zry(D!B--_0RB`Q zw-7!7<5&#;A;zl&ei8DQ!+(W574YvNPc{5vA{qUPmw*bBd@x$}WJ{!IsJ_r4t^5q-vECL;v3<2L;IWIZ$*3yd=Bc? z27dy42mEcw(*=J!d^h|u_+I!s;QQg5-~;%-zz@UEKz&Bxmm@xM%J}@h2R;G53F}fK z{2r)hGW_o_zA5m>WBo~kzZb_%hu;I|Q5O7th|h+Qe$AkM*Y<{#w+b0zMA?t%kn_@pbSMQ0E5tI`pd%{$FTMGyEf%CoS-;=x-bR zx5(20{}AH4;2(zXhJO^k7ydE$e)!!`=K%h3#1F&ofN>v%|2yI%(ee5J1bhPgzp!p6 z!as@lWca11PYQfH;?v-tf=`Ek8a@mDc=Rh9z60@5_#}Lemj~a8_yYI~QRhPVcFefZrAUErfpq@x}1x zBEAIvN}Lzv@V&@W0skg^HT-0pk9F|>LVN@K+whI>6*#||;a^2NTj1}9Z-XC3e>>pc z!*RRd--qvp{{X%h{(iKxAN~of0|ERu@Wb$ACJ%fOK^TAz;BECC&CxQ zC&LHGp923G+LH!Yk%3qA$&IUD{q_$d4k^5nsP0$%_>5#w73zaH_$@b9B; zCGejjz8ro7dr5N`Cd7BZuS0vf z;71YP4L=#}>4m=o^Q0gCOXLaQzlI-%&&N29!Y5+hMot}{|IeU33GmyZUy1OyBR&~^ zGuo2^Ux4|U2LCPM)8V(kXTk4=<7UJE1mhKjkBb{mlm~wT*0%!qWW0_S!oPv@v>5(s z)Tab~I~=zhz6^D!fR9IfHT(|nb?^!B4e(!~4vp|TBEA{^L$tpIeka7Y!Dr!o?||PK z@m=t*p>EyqNr>--|2}*_{I2i;{14!V;UB>`j>7Mb_{gmB`JW7*0KWqDNrc}6@yYOe z!l%IR1)m1LH+(vL3Vas)KJeM_`@%=zPse(a2R{|@1@Qa97sBrkUksm*^RWaz4e{mh zkKw$lfIkB5tcE`TdFtQ~gl~YKjqz%P-xv9t;de*-Ti_2t{xwu@b97i+3@wq6NNt(dGg?ogD-$T9=;HM8{{vB@5AeC3H&{nhvo3u z$X@|}5$0hv{7HzfgP)3ZxB)&F@s04Oz&FE3;alK;4BrMn3%&z>HhdTSPvE=Z55)P{ z3x6%@)(?LRd;p(^{KN41@T2gj!AE{FKL1aLPk>Lx`IrcQG0ux*_&E3!_#M&yH24QF zf70R4M0>K}e}(fj8@>SXQTV%&KM(#K#23Kdi1WG-{#?Wt!#|9EmB62m_;UE4!B@Z+ z!dJt;g#2~z7a+a?{$#{A!q3C`+YJ8+&bt=)rKnpQ{5%}D1HKpI-UYuWj@u3YOXTT= ze*@=5Km0|A58xx{?=bwY5I+ik8rm88>G=HrHR2QC>oDIE;V(vfGW>k_6!@EwCk_4) z)HxmgQsl{kFM-d7pMmu-3SWx&Jow+E&IRz7A-)j)Ypess@JYy10>2FLm zUkjfFzZgCnz6w4HKN0oMgMS}&D}Zmpc~l60J@OaBe}p=ez<+=|lj@ zCy>7m{&e^T_&BV$jqo+d-wgkI_!jtXybiX(*CM_H{#4ALF8CV}-wppR*1cZ%KJ=>} z{%G_ofPVw=!|?Su?kN0C@R9uS`Ts}w1o-pOuSEDiAwC)YGhCmiz~7H?PlI2IJn8Uz z;JnL%zZvn_@bl2lDEuvm&x5}ez5xDq_(J$^FNP1 zde*_;f%pda+i>1B!Z#wm8U87>rv?7s7_T~C-VeV9 z?F``WL!M#yzrv5g?}>4VoHjoH>#-gtz(0UIiSQ4iKFRPa5T62{jB!bW{~O}d;U9$0 zf^UJ(hJOe?3jZ*C9{eNl1@OPYI#US067j|GCu036fqxUe96rFhS^@txUZ<+z+i=`E z_{ZTJ;QtQa2>%3pGyIeAE%1+FeB0nR!FRy7BTpCnQ}EsJPs8`Zcf$9>KLa1YM=)=P z;YYA;jKbf8@r|55KL4LX{sj0-kv|dsS>#WK{|x783j8SQmInVkj++jDKF-rD_%6g} z!@mF@h5sw^m%zV_Jmv7e#&Ij)UqL&o;eUhtb?|GD zzXARg_(u4bk-r)K=jc}p{Hw^*2HykU0sl|q-w)GZOd675Nbe-rsr;P1xzmImK|Jn8VK<2=fOe+&7u z;iGunjKaT-_&oSN_yYKoF&_%ycSe1R;om`?68JmOo^tqakiP(Tyh_{mt`dg0?RzWwks5g)*xh4XG0 zep}=jg?}FHiJUn;|F=VY0(?AtBK*bZZ!-K2h);n}fKP+p5k4LMc&r0i@H-(s8-8c_ zDEyPCPagb9n70M+6OgA6{)ae!i{U3Cz63rIz8pRYz5@PQjBhpku86OLp9J3kKZ-n! z@Vgi}^;XB|TfbW989^=>zzbE2*;eQ0*4_|{k0sLgd55o^(-5Z79 z3-OV&#^?V!%##H8M#Lw=--Poh89o>FOo2~8`_tf4kUt%MU-&HeQk-|$@KX^Vh5r-g zc^>?Jh%bO&4POYK244(68+9vzKN{^Uhd%&$D&RLGz8ZcQb*_W2M4cPpU&gpM!v6}s znI8FD;HROTZSaS}cfenXI(NYzfOVrAJ{@^_;ctNNhhKy|0sLWzABI01eiZ%>xGstm zjL-jz;1l3eQRhVXOyp07-xj}bp8|g*;?v-df=`G41ntR!&q91Q{L%1H_+#Mn;E#nb zfS-zaSO`A@@x}0egfD?V4!#^d8@>WQ2fiBq1o%4m<1il@;7>w)BYZA=GyEx7ms;TO zLLJ)RkHYm^2mB9kes#e|F@L(@Peyxs;g80+_ruSG58$)lhvA3Oo>BOJ<2;R=JwE?u zqCE-lS*SxI{Ercz4BrBu0)Hxe8vHJ3XFB}PQMWAkS;&(O{}cEq{B0QDJouj?z5qTC zz7Reiz8L;rSU*ePPeXh;{AAR>0{(QwSHo{X`|IFGaNGv?Impupe-X}?X81QTzAf-) zBTpOr7Z{fg`126o1wRer+YSE(`qc~n4CZq`{9NP@;4ekLhT(sP_)+*m_{cfq^M3crTMfS$<5CCTiuyFbFUP!Ugnt%wYld${`&-~w zBfbs(Vzj>lem;B`{3Y<+@R!2(!mmQV`r$`$9tH5F$TJN88~9Q91@MvZ`wab1J&(F2 zz|V(IgfGVUj{k=Jf42Tpf&WzCKNa{-1^!ck|5V^V75GmD{!@YfRN(*b75Hr8USCBQ zeUcEZiT`cUE|F+e$AWFPbVnCGm+-7KeM{zh?$>}eZkhVNdziR)#K#x=XEqKFY}vA< zPT2okaN}T)vVWhkaj;X_zpvRi*sAQ`cWoSOQugojHV)P+`}bcP2P>8R`;Co*rON*O z^v1y=W&i$h<6yqBf4{VGFh|+HkJ&hwq3l1$+c=o2>_4~NIGCjTJ>fXziNYh_j`cTD zctANxxJUW>!kx;y3b!izj~-nAmHiiUyZ$ThCS0k!yKt#;vT%{|4~6rU_Ylre-cvY3 z`A5R3%9DkYl=l*jQ{G#6Wb;`6Q-lYUQ-yn!_Yv+?-dDI)d5Un8@>Jn^<^6;!mG>7e zRZbHwQa(U9U->}c9OZ+AGn5Y&PF0>JoTPk+aGdg?!Xw{|^*>#BKsiIWNBJ<}PUXXe zTa}LxZc_GN?Ci#0`AFeP<)eg4m9vD4l&1^lD<3VKqkN2ThVrq(sme2ila!AWj#EBf zc;xG`{$~phDCY?GD4!tQseGbvtMW<0P0G2#^~xs;S1O+(T&f%uE>fN;oUi<2;T+{t zg)@|A38yO07EV(BiEy0qPlZRm8tZ?a@PKl@aF6n7!kx;e3%4qtA>5=qN4Q@3OyNr9 zvxG~P3xtc5&lb*CK1Vo5`CQ=)<@1D7mFEg4DW5MKr~EVFkuS&kUno4FTqNA1e1UMM z^3R1^l`j--Ql2MVulx()O66Y)mn!=gAh-T2UnHEb{43!c z;Y#J}g-eyIg^QGz2K! z$0^?_Jo5Qi{~Lt|l$(Tmly_^ju2jBPxKz1WxJdav;e6%4 z3g;-_FPx$LfN-kv3gIN>zX``FKPWu%@3H>32oET?3il{KB;2X|uyCvLBf?F}D~0Qo z9~G`teoVMjxlOo8`ElWV<-ZH(C_f>bq5Pz9s&czI7j&<;SA-Mg;SN+2q!7O zA{?jus_@9hvHo`p4=DEt_bC5ExKsI`!mY}$2{$RP6|Pr)UAR*D4dGJdUg09;H-+<+ z|0SHG{FZQr^4r3x%6-B~%I^rrDZeW`GBVcxe&GS-0pT9y_k=r@-xqFG{y?}%d7W^* z@`u8e${z`rDhI+v%7eoB${!2oC=Ur|D1RcHs=Qt}N%>RZIOPq(Bg13;9~K@^9ue+Q z-YDFu{F!j8^1p?fls^})SN=k{QhAebsq(0Bk@AwhH9Uw;iK`!CvZ@Bfvz5$;spR=8DpJK-kfc;R~G?S(6qcMvXB_FsVI zuK$#G6wX)PNjOK@e?gUd|F67@aH{eI;Uwkn3CAf<6dw6>tpAC^1IkIlJ<8t~?o{4Y zxK;TF!cEGPgzJ@e6RuR=UAR;^S-42~hr;>FdkE(!?QwJfNH*+@pM$aHsO&!mY|j2sbHb3fC(i zDO{<1lyIqXmT-~sbm4sEqlI&nj}gvLK2|tYd4_P3@^Qj(%Et?j42|_aTX;Y@N4Q7% z1mRBQ6NOuqPZDlY&K0g#K3TX@`4r(&W&g!RZv2&J3g;{TSU5-dRN)NeS;DExvxSqC zeG{8QnPkH`9-Cp@5>FWjSinsBG`>B6nbX9zbb&k?RyK2x|-`7Gg5%0!aFOyw!uiU-63$WnwQz>=#loq|^M#X?FA;8o0L}y*DF6NT&et+aH(>eaFO!k z!uiU77tT?BLO4VDN#RuGcHt!Dr-b8_pB5f@f2{u>-z_|# z+#}qh{14$y<$nsdD!(S&q`X$RUio$5O650%OO<Uyuk3G-b?^U`cM(oi_BXz|pZ_a=PdHB5-{`t=aO9n_{`(tTUH_H+ zjjgW#%HJ36RQ5Nry8bKwK)6ZS-_Yv%uk3GFb-(|h>~BbQ{Z~#FE>iY4rn>$s?;)I{ z>~A=A{a5xkn!4YAQ1&;Hy8bKs8$~w`#wqVDJkmGTe}Chq>%VfUaF6mn!kx;zwyzH|J!5z_ct)Q{wrq)_bB@t6W#B>DEk`{UH_Gj5N=ZTHx#=5EBhM;UH_H+ zje>6cmHmx?uK&u@h4YpD4S{a{EBhM(-S{i}8vxz-EBhP#T>q8*4Sa6=m5&!5d26iy z{zg96e`S9IpPT>6{>DAmf8`T}Tb2EddhYyJ_BZIc{ww<%d6pjrHH(DCYXF>~9cr{a5xk zfVuuF`y0I6_$!|w+@$Pp+;aU_K2x|-`7Gg5%a0j!a2(43TG($8@62k zmHiD?Zv2(c7mic*H&nU)zd6=_emU-?(UIm*8l&QSI@^0@vh`x|&%|CRlXJ8t}y z{S7;=|Gi`VFA*M4_BZ0V{ww<%a9sbDFB5K6_BZ0V`LA3iT(5k&aHaAU!llaP!bQrz z70y?_QaDHXD&Y*}tA$gQ7YZjSUn3l+{5#>1H^%y3Av~a5Dcqxct#GIEBH>o$#llU> zRl@bk*9liDUoTv$TrFIryhJ!(`3B(}a6ir~IJs$ZKQ$ZxJ3)ZWZoPen_}e`C;K!=0~<=2HPmERC9Rqhoo zQhrl7U-@6cIm&MdXDGidoT}U>oTU7YaGdhH!XrIn{qGkZP#zHOQGQRjQ~7=2R^<KhAUx7N*8gGQ z0p$_l9_5X~oywmHw<`ZzxJmhQ;dQqJfNH;+@t(`;ZEgU zgAl#%pNw{8lH{nX<-Gxh)lZA_ve<+-e3YBHW}rRk&VxKjBK{{e?@F(}atZ4-n2*K2SJE z`5@s8<%5M&m8S_ODIX#nr+ldJ$jf8>PZu6g&JgZVK1{e%`EcP@=Ng`2IMeVn!&41UHayAj1jF%$H@ojHdrUTJuR;pK*x8D46*)^L^Kg@(%v&o?~J@La=l49_;4Yj}p?OvBR*Pc=N*@Fc?% z496SZe54tF!|M&NGu&r*t>HC>R~c?MywdOr!^;gXGrZJrt>G%e3k{bUo^N=b;kkzA z7@lo7*YFI(nTDqso@#iq;Yo%k7>+l*In#{4;q`{s8SXQ@*6drUTJuR;pK*x z8D46*)^L^Kg@(%v&o?~J@La=l49_;4Yj}p?OvBR*Pc=N*@Fc?%496SZe1sW)!|M&N zGu&r*t>HC>R~c?MywdOr!^;gXGrZJrt>G%e3k{bUo^N=b;kkzA7@lo7*YFI(nTDqs zo@#iq;Yo%k7>+l*`EWD-hSwWjXSmPsTElA$uQJ?jc%|VLhL;;&W_YRLTEkU_7aA@z zJm2sNE4X-!6&TyaMwT9OiUS+u5 z@Jhog3@HC>R~c?MywdOr!^;gXGrZJr zt>G%e3k{bUo^N=b;kkzA7@lo7*YFI(nTDqso@#iq;Yo%k7>+l*`A{?dhSwWjXSmPs zTElA$uQJ?jc%|VLhL;;&W_YRLTEkU_7aA@zJm2sixJjw6`!|{eUPc!3hc)j6uhWiY!HN3{~D#PuD zR~lYnc)8(ahL;+yHC$zQq2V&a^9|24JlF6X!?O+N8lGV|)9^IIQw>ixJjw6`!|{eU zA8f|o@Os1R4EGscYj};}RfgLQuQa^E@N&b;3@hT{!yKFEx};q`{s8SXQ@*6drUTJuR;pK*x8D46* z)^L^Kg@(%v&o?~J@La=l49_;4Yj}p?OvBR*Pc=N*@Fc?%496SZe4rVB!|M&NGu&r* zt>HC>R~c?MywdOr!^;gXGrZJrt>G%e3k{bUo^N=b;kkzA7@lo7*YFI(nTDqso@#iq z;Yo%k7>+l*+5Iimt*-wJuQ$BTaG&9|hSwNgWw_n&O2aD*FE_l*@KVFIhN}!OG+btQ zzTtU>=Ng`4c(&nO!!rzL8lGl&s^Q6oCmEh#INtDP^ZOc~8(wdCo#8&iYYne4yvlI9 z;gyD07+!98nc<~|YYkT!UTCkRi9UTb)b;Z=s)4X-r3!tip#%M33yTx+<>@Iu37hUXieXLzpRIfiE& z&NV#4aHipDhNl{yYmbIp8(wL6h2iCfmlmbIp8(wL6h2iCfmlmbIp8(wL6h2iCfml5f5YnyuQS|dc&*_zhF2MGH@wpD3d73{FEhNm< z!>bIp8(wL6h2iCfmlD({)X2ZUT3(^@Y*rXnUizIoYSLAzRr)< zT<`xbg8vI*XGd#p_J5-x+S$L|tlEpW8J<;p!SL+qpInwbvu1umv}*kV_g&<(6Uq*X z*5pQ_OEzrDOLV+T*`CpwIi906CnQIYiBB2cIZ_tC<+Ow$_b16_E?S>B^h9*g6OAtM zPM7Z*t$D&9;+%8m=A4%^ckl@JWmN^S?PsGk+fB`K&rRHU){;%DMz092SifaUwC3t5 z3Bi27wPZuE)_u2K_~bdEdd4Xq6pdDGS+KX?t>1kCls75f#0Nbd-M+WDK=<^}2mWuL z<(x5d$v01DyQ9s?3x4OmF(kTVmHS(2?U7v~vzB}qUDT22`?DlBD>%)4orHVl*Wc_M ziPmH;{@Oj%<|Rj$xE|N$<+;biXw9Sv?r)<<6*o z-g1NOtNXS4*0rsVa#45``M$oV{J_qN6(Z5ypy>uNXc+RH-4H}vGhB0gjjEg)dOw8n z@cDk%fl$p0)tYg2n%|`*d_LF1-F35;_>m5d3Zw6I(ay=7+BbAH-aVD)z9BE%^-6c! zq;Jh{+!KE1Tf4Sw36{F=QXTA0i*p6PdPoC2DY}`^HM2X_Novy0D#B`QteE zzH^}}4pp~PIdf*!UYabkc+TmkMQbii^QY(JXiZtN%N{KABUUrlPvW4*eIHbGN#D>r zvuh5X;?Cv;r@FH_d1lRAch3JGp3y(~1ZT9*ztH8J>2kKXbJx``=e(!#-1z$Q+1+gV zKeWyNy@s*2W&ZEm_Rx@N+kpH2r|)cAgB#KRp>0e3Bnazvi_7!BtlMt3ZMpwl+rDup z)&J18AG-Vc$J(~peaF-PvTav>Z0dHO%lVykD|Bsp%71r6c&6m}1;9;$s9#tYJvqgn zM2Qox^MBnWTJz+TY=>^;ow(Tl`4xXwK8wqWiTgtch-FD7@k*SYNac-kuyq)u3ZtGpLbMJ(%F?5N} zy%@TR&?PwcXy^*X9XrLTyS;La`nCHOz2MId1{Z9R1z~V{_?Y1ywcD4c`D17M{e71! z!!FNt-@)NmiR|ERH|Yky{WkW}^U3&rsn~D9X}(Mcg!@E;OWi(09nKB8bt0_qi_E-Pq7D6{L-gb=~4`q$67a7;vUC?k7w|Y zeQ>o8K5?s{0~s{U2mRa!?G|RVkKb;Nm2&LyQ^(OoS5GN))5rhuE$NLE(*LP1pY8{~ zk8U{5lNX(d*OC-b8I=Ta|0PPh8GOQE~RV3;ML*4hZ7;FaEA=8a;yGe=Zv_q zlj5b%+({C9k^3k(VT5QcpQ;Pj{-`>q}?iy}U|F_W^AH85=wANMHe;buM3BPrL z4)cP+jnas~e_x*;n%}yk=!IZH@NxLMd4bcuSw|1MDy`>;q@1_Vkob;Cp(IwCN zJQ?r$JPX|mm^*=V0X zZtJTsHZ(`d(8_3@>ju`(&(Fda?LB41meGvJ{0t|+wy|AwG(Yo|+G;chp8o%0H23tc z!mfIY+!E*Od%rshM)OCm++P35X+N63cg+lT2<7iW`IvhQHo9_RG=J_-o~=eR)kWFS zoZ+Ij9?gSXlyA?|n_SL2Tuyg%JDNMVz3gay=GJL5nk`S6(Y(_Me}=7go$yyLce=|o zf2`}>Rg&-IgYJ3sJ;fazbEw`OVW`8!`_R|kmtA8g?cFX-#~};CD^jANx*^ zP27c2{l3B1za8tkoSJ`jU!@uj=7L9q0(Z=z2mR5n36FlyDtGh|S067ga?)4zmM@%q z+ey@Lwo4?H8C;-8kkk4I_r&<{J>;GYMxJ!T*X*`j(!sUvG3?r#&ihe}leJ_+FwnQ#qwrgw@E1&Xt#z(Q#@&8Aocu%;re=ltEkqT&%uTg9iuW@lYiUYo`HSyc)d&Xouhb(d%}$3K`zgCjpE&XvHUyxZ|MuW zdt>M}`ERcC*8nNe=^GXt=$rEc_sZwn__lj0cC9mg%YsS%nXlHw5<|L@cA zt&(3~qBX}(3678rf89{KcuIwTL7TqXUFEfhJ6B2CCu8r{j&T=&QJ?zG@Y!FwXTyY_ zxY;BL-?0D$2vG>o%xLy6kx!XN4=JpTWjWH*$^t;L- zHUw8W7f#1WsEVEP^@!G<ueXg|)6Hm$H6t_J#kX%K zAAN?49_scjd&&Rzd~9~Rgy}wEvJdg!Z{^puC2ocCRUUDdygqhlt7D()L%08~V|P9l z+wXCIsqC8TkG+qN?sacwhul?OO#Q&CRbI9G>}~$Phy8zllk>`Vve36_4Qf5xyyg+uj|GReiMYzlPW4pN3 z$@ORYyJe}amA))zxMj>wvtwPvR^#=q@9UW^=}@mS^ONHn7p!6b=;}PvH~)`rmszzB zOsVj)<`H>Q>8~Mo_G_X`UJ&%W?z{AEFx@YxE}}ys-NzVy_Y2!y#aFwnp}+f10NA=1#7~%Ot{BG zmkPH$bQ5Cvr1SM*zAxRm9d`N}3ELE09zOMsd+I6w6N#`(uRP?=s&}4BA2&~W^Ky6* zb$qy+U(d#>eo*NC2)DZ&WA6F|wHF;d!6{?*?$q3yTs!eXK85^~$LifIRekGqZeN*g`C(eD|GyCeQo4_f5B?<|ENlqwa$)jnstG#6XR5~%xcqLFjQZ=}gMHuc3}4l7+PB5+{EXWFB_ah$99Z$ z%y(tt;v;>&)hk@SgZ);!-#RqR-0#3=Zg8(L!RanZ_*PQR=s!N_B4@ZrWPVVV;H#u8 ziwE7cb}--Pd)IA+gSg&Z&&{g2(ElXMjfaON>-;#cb(>)y-IP1ZA6SchK#Y7=_uQV2 ze6{bEoi_!y$)3L2_2E`}aDBLy7Ay?6l7q{_t(4#*zvYhE<33sQv-HacVqEDzgt*uh z2R-VOG}v@*d3Z`c$~<y6ScNiu zzEgd^gTjhm66X8DH7yu$)x@r+#deKN1OH|#Nc6kD=C;P>{*A9lLH$LWxwDU8_>d1~dkO+i%{yD*Gd=T@7s_FN>-eH8fXQQw}k!d-O56u^6fS3-a8Sz+aEXrs`wimU~6o;Ff^sld+u=-A>`4EDiUm4I|Tn zMd4OnY@Z*5`@HQxT8;e#zbM@2Y~AOlTkq5VMC>@t^6{(;%`_ho`!UNtviqiBk8r2- z!2do%Y+PdRul-r}jhwaqY}x3yTvyK-&-QNkWJ<6$+)55!lCXD!!^gwgobpRvi+db; z)#dPK=-nR7o9JWx69O*eVku!T!z?UB_H@McWbHF^TWiijqQB0 z-}x-rc~kJyaOYE8)Kl59mr?)xQTN66J~Xzs#LukR!5z=HRK$H&@8A5%r#FB0Pv7kueMi`Ull<$u3vUS< z;D0JzA`N&l_VY%UqR~G$ef7k}zu4kd`_tUBgXg)eFvDH$x^FPcu^-oLc`<+6?cjU2 z$&Gik=He*@vufOr^JY!|ysXp*g|DDHx)IiR;_ol<^8Q zx?vtXGB(IV?lV#u*%~iXoecRZ&qMi~Hr5nbSWhn<;2UA zd{Cp?^n+D(rR#|AkbiV%hx>@reU2rc$`t#(7p+Pex>=6sf@V#BzpTi&Dk1!gI3YMu z4(eY7cKnMAcNL6t2MarWojXN*pZvvw>(lOGY)UXcd?GRUx!dw5@VWlcUy%*nI@5p7 zBRhQfs2{KAl83JI)2a7vpY39I(Kda^eTp>G%>ik!gg)UyU1O7n-ov%ZJ#J-=HFx6T zv%(=y2MryZZr%cTWsXa9b{$`^}D;ss{I*i>&hxOR9X5 zXic{JWrru@WqWm1mQ!x(`t`+q*fe>q|FEgO#fQs>O;s)K`QUF)N*3SWV4GM+8vXVc ze%aV2*1)YA^QTzGpzIOZ(RV2La)m3K`xOKkmV;eMUGt*;KsD{z{^2{CS5s9G3&@KF zWTXAD?f>%*4o;4hW$@zv(%uCV{3yQgu z-TkDMA2Y0%?)Vw}ez=t#ycurgxeJTn*hb&ctEWVRXT0|F->sdx{|YDlbo1AvUKRwm zxvilG!i&Yd+!;1>UkLSX*&Mpv5Ae;p|NL1x=ZTI_aSzl_}i~aVkF<;`h{}9_Q_uJRT zwtM~dhj+*!D*X1ZV!qmMpC8+<^V_Gzwj2ER$+7K5zkPIUyV-9a65DR^+xx_}+x+%! zvF#4Oy;E$v%Wr?{FXG&V$X9NAV{E(7Z+{ruF8161ifxzp?N|Kvl3q8((_97Iyw7%7 zqBZ5C!GgPlz4pHeT+?3eNCIzkBB&tjB7&lbih?i$2m--O zgz-5VZ%|Zp*VR?l`#{ccBmqwZ4^RRn6;B@Hn@csKVGv0w;bqR_l;BI88 z4=ymQV}h6u5P2h(ADSY8-U!!bBvzgs3}iFT%MPWT(!L2IoM5r(*8zNGd>CGZ7QuV7 z%b0~C4Ae!|^Y|HpJazuxNhHKX@5Hz&`ZM9g-}n~AYo{J78C14OZNiLV7xm^3aVmL& zU$7PhH!W#nWGCt;YA)c z6685hn$B&+Ci<|K4($2mKdl&EPSww8hrdf)A@sB&2xRl?Nb0XN3t(FgMI%IS9nphL zE9Nn*oL+2i;DM!6!o^sV9^Hiv2 znWsF_uN=D88e?@fnjk_ocvmmLt|wL7n?&NTrXw-VI;y!S6XT(yf>Uo!1EsIf#8X@G zLU^MH@ABlTE5x=kZphZGTFI)-@MQdgvMwF>5E3syVnVAA=&IV|D1O1-tV+M2I-gJL z@g%-iv%NW3S1=2f927xlswUqvbM!!F(lUF*ykx0+%~OuL%{=9*GV@fZMwzEPH55;z zAnkb)>-(wtJ%F`<8V2elpuLVftR1hIQIDf!d~om8ZwA9#1#=?&w(dXj;lg)(#ezyF?|fu zm_xFq!uD0hpYvF*#LZGIdeCm`qzx7ZduglQHRJFxdhe zVc`pQH@?on*`=<*FQ@%`I#0~Z-jcUXl`;>81!$;>^z(2&chb*e_}pH~Zc=x#zU(HM z?w85%h(9|`%8$&nL*vp_-b1>xp}JmM(av#!MJ=j!8R?X)*;! z=_l~Umn`*=$#3N5ODsr5EPtHI{{l2JVt$B8T8<xZsfUb5(hmx!1qPo_qDS(68k!m#o6(S!IW+5RQNth2lWl&|x9Od9O@-mBmMZHi+ zg~DzA_7IRPew`FYxV{K|38n9Ak{E8So}p-fVmU&PPir<0%m6r4I<5lZ=Rv72hFgI` z1GSZaNV}tkrEf;GvMgEx*(|DN%_oM%*?pdkufWRcI`+%$Z13RV*|0pn6Xj-vI`H2VoMKDf!tedP;tXUrx!h zpNTQ)V#$iCIi|=44sJ3L z7CZvL{sSHuK|4ej#M-Vm;-o_&cJ;G6t6?Vvvn8F$~(63RWEqqCy)(gJW4Jj=?>k z=m9i%_C8I6nmaTN=0l<-&|od>tQZX*N0}G~_n8VIR7j-3_(Tk5uuvR>7S9?Cu$5s4 zaU#~^beB1Gm?tzbBR)mQ7FRt6#2~=aOY`^n-?g1r(y0zZ^L9g%s97Kkg+>(#UOsO* z)r(b8_Ua)}GIIO{*6KGQwmm+@lfNHttpN^vGN0;DtrqI7RqvTKByfoO4u_ov@?d|( z>&(MB)s#pDsr5By=Ri*Us}7J1!h8!kQU-Dt*k4CLvJ8U<;$8YZN)3prt{K~Y6|4iI@>El zx=HPTOd^a!b+L?Cv63*;B6s=pQT`fQy6KiWSQg#4D89X zq;_4{yTKG_xyk%`VP6a5p0F=UhJCR~E- zurvWS{wc=hoX$eokH!o21;3y|Pt>bQh*PnvR8Lb-cPxxE-8x9&ufwkaX)I;k5~gG}C=I#0A^50my9 z(`Y}*)DXw*`w#0bPe&GM6^jpNJPP|(?$#08Swew_-=^yf(REZM-YL(gK<=qV7)1j5 zEJ5B3gG?t~&pZ%Twt>~wz$!MdIuq7wMg=CqI?lj~VCw(Gf#6x9uJs}B&C`j(uR7#? z&9ik51WyIbdJhEmaDEcE4&p!3xb^(?xV`<4I=Fq0wOPHmy#xX$#e=PoSv@Y7(lSlm zI|X!d()OXRa0(dTS63bdMCNE_VjPFT_$L29fOmQ!g`Lt=U-N28d+=(45)uE6X4R%- zMc7xjY!+p|Gr$iAa5I-4c$$p$WhBD|!$!XjYHk}VnXv!xi%T<>axKFB$G7-Eq{JTe zI)C9NrPq1pDg5Aczf~cwI(^HA?$&a67yzNth48h3kfT})Y`P>}qQ-=E3JoVJ;Nnq4h)tIzQHCLX}`iqB| z*v_Km7XHcGXteC4j^3r#RS3tZRgh%{y?sGlGDBSq zKNNX(4h5Y9&o&1ay8QeD^uDZ=kyGz!-+{@eeGAoI=rzI}1h_yKN9TZ89vKQ=Wn*$^ zTyF#}F#@knKz5%MiP+Hm9uX^llNyX1R@7(9enK3# zzlUJ7$m=hlf0a1?_^CP~uL)q*EApy9^Pj-&VQM>r+d`1!SE`D$>*97jVAhLUw&q=u z`|nS1=n?-Xzq`~l`TbHe(d~HQQ;xdDJY}dc<|$L%AWvzQ*o5Qqj5Nv7;%(tAteSS> z-$kTnnM^E;DboMSOpNh#2pKc`#MHSx0KT{ZQ`zumGqe!CEdKsI3^Q?uCkC1KVWs?d zp^sRoJ>HFw5Xh&oP(huKI_ zn&_QLx=;-Y5#m<76Jl!$n#=1zd<+o7pFjd8fSdQIfa83&0t=9*#sNf_hv6|q1i2SB z8imge`Q4@>^1DfWfnPmjtK}(e>`OxTq(Nz;IsjaG`2E7KkN7A6f_ zKT0|T{|dB(sx<02-6XDq?pNcGm?%!?n1Ox?5E452{v)xD`X;IS(M)(Wh9RNEi@JoN ztj{1aRBS7=vu<&X4(3c(6&S~utg}toLMa;;y$3pDex4vJGa_ASDMWfSN4vxT@ju#G zrrty*aw30Wa=mhSH3%NVb^1gSc&)nERCDF>%P2(7@j~m(uFxJ0%oML~t$#pUuL$RU>RAcvjTa#;uyJKeCJt7|m(v?;Tr zazQ$DqIwWUt3=DCl|g!8v-a}8;z#Tfp12zKG)`QdfdvwE`fk$vb;D7Y1CaLMdvW$y z4uwrHZFDmjW-v!|%9SRkLt>5`sXWi*9B%Lu+-I{FVT0jrD1D9LXEI4zE%-|!hN~gq z)V)}*$1rR|49OL2K20gmls$hQy@)e-WR2;640@S{et8n~afE(`cmohkmcQ0_4ry?o z0ogy1Ff%X@C5jHE($ol3H({AmlF+t^b|au28<1Ne5#YAvmrP_rbs+_+LoM}wD z@5bxV`x*e}kBO(RH|ZbONq@tnFRGLNqDg@0iZ5Ak*KbCcPok%i`%@->m8Im7ePyo?#CQSt+Nk#3OmU8C-lE z%Oxl^p8**L>dU6~OsOqijE<;6yQ4j;I^$tcaJ!qc4xA5|9ml5zuQ7ariEw5bIKKMfgp%P*NQ6_A2%%>A!zAXY+U@nr! zZR)ld%;%93sWrxw*swRSE*ulMh*Or{j4zR>q%Y-xme42iG~TxJF&i+{*8vD;*|^KGs`;+CV4ohtQct@M&~#5W%^(9&%NlcuIY8@qNH(pf zN$Z?Lrs>>NH2r{4-U9^uT-mD!$60~DqZ*qUMLe9D*;RP==FgP#0#?O6c;o2-rl$Cs z6L~%=8>M9^*b`AgXPA^S(>LB-c&teqXwrDXI(s4$Lmtl<2Wct|DRyj%@-_h7yq-oGAmDeF|RHvC;_>iIS#{Ft1s< zi>apaTM##_{DI8ecQY0Qa{}?boTv^R zjz8TszGc${Tu>K07X=01JurFe!}kw_H1{FF_aBc))eCgh=FC}yYM@*SpD*!CsR1;* zL#=Xjsf~y-Q`2>+)qL&=EdsLLrTgAcms)@vL1P5b&|Cd( znRBj&{4k$C^axvj1y4gkL39}k*GI2xLb_dqT9@&Z?4edi>#9weLwg>W>|2WG6Ewc3YJ7Kd zD>BsS3+4>fr9R|ymd5vT-S-u`)LiCtBfgV}>g_k+&(**j_|AAh8vVO2csB|PzDNE5 zzGDdKQ_EB^?=>h{AAR3K0o6g{dz8j^zOMQrb57F@ zJi+Ih5z@fBdZef7QVw&P=~5H;T%~7O1C7QAUFu5aY=jI|$FM^kuE(Fox>tqw3z0m! z;8`p<4+WtVj|QidAp$&&1YcZ}(qKU^iuOmj2Ck@@@cY>iuGkb_J{vz#tH&aEHAZ4G z1{+4+q25o4Y^_JWZ9_1f>MTC1E+;=EO}|qmr22q4=d$Tgm!*9EP&4dW%_&dmQqMA{ ztuFN#pO@=d+CtOr7F}vGa)eF3hW<{Pe+okD$O-<~d9QRQxoLT-1F>$bu`bkDdvw8GC@5IJj>7fvYY8FUOfBSexn7Ij!*tb?m~#uNp;t%qxwXc( zoyJ$q7qX->=Tc(w0Fik7TKpLgoB;0Cdsw2?0$uQ9NK*Aj4eo6|Z_?8>M-yq9F7*;~ zniJgAI|Rs)l>%g}&c27@nCj~*Tf zNvR&1(=v6buFSa|rBp4uvf>*2`3HIia2xLyRJP6IPp2bUaF7PqjL&U!fBI@7F4LvH zrfem``9#=dngo2;qk#IJ^55yQMGK@mbk(KIX{Z~R!{_^NkW!CoP8gy~J;t0*L&ynr zxtGtCTB^LK`+lx2HI_NAqLlh4JM{e!{P_s|L!%kGS4ZlCJy|fsf|-QrbeVRCbo#rw z(&=1g-+-K1DUcDfc^0tavcbW$R!FZ&%fR21!NFFk@)m_$#ar_o_^nCXiob|qf#9*) zCE7<{AYFYA;m`hS(RGJzYZ-Ecbo*g2$H&@gSD0A;Z>&F8*Z+sEe}S%lJ98GHE+{jR z&zD>;tqjl%m!nHv#hmH7R9`;#)KcOuJr)ghsk4zIxQrk!iTeK}*6FOL})TiNItcdG}!axgIzJ+~4jLaL?(2J1BoSGukDg zQdgd?L^1U#^@G#pZ7tev&;VX%&U)D1z-K0(M_nhSCTh;Nb*a0VGZ&@QE~3(qf7Spq zfNQPsX{QSgVZnPexPE-@uEoO?O@uwK3lWN#b3MWBmX&jtn;hxX$2$8MWJ{;cLy>yv zn@#}Dbbt0~0r`loyA@(r9j+1hoX>x|R?vJ-bHW&1s+KwQPpChzE2mwBKh1T2y6LIf zLl=CQ1sAj61sc|CKqRF2niUS4)>^n#N6asY{R}{TYjr@&2IBLXj6~ zv-y+1+t&*A#jPX-HrSg)*IDh#AR1CI*X0-G@6z(+HvY8VZwI&A3%8zQFWlY8Zct;t zx8K(i0Q}Q5fb{4(h|1!4ee!2nm)@wG;y&+-C(Fu3QQ* zf{ar(Mq@npA?)s7;X%L#TjPM4kKma8cC5k(ymouKmWQ)w-z5|pjA*=F__j`PiJYGU z-H69~@);i8AK8IMI-6gPeVAB&_;i5M^025+(IrK_J;4uf-iKuM1{Z^}I3MZFPEYy< zOb)O~BzO0_NbZ}^6R%^)-2pF#+$)_#av#C|3c0(aP}sWU-eXnR%+lm8c5vhmN&dv7 zF?H$vU2$+{oZz4L`DDq$K_}Mm4{lefkK!%y(S%zJ#m{??NPiD%m%@W0RCjI}BG{dL zKN%rkSru=~K*2G^LBYfrYDP`UvA_l?Fjp5qJaDKN&ZrLB8Lbp|4Ll?1)vNk!sQ%>7 z2v%RRaBPc`6nW09{;q|7%ED8lNK1_F>f6$JKL_Pu(R>+TRL{B6{$r|qe8;NbS#%6~ zp5~0=;P#@+iUus!^DH+06R-rRZ~ULu=`#Kj$fWDZyNASTnJxDMyYt=UpD?fQ9n5nG zjP9+KbDC-bhj65m}KQV6GKqZ`+0BGQt z8QNC^TfmG-)#L+ATZn_;rX>qU{JA8He@n9gm_rXCaS^qNQ`Q%p;w1-shl-rHGdMaF zD06_8VUt*)Qlyo_6URaxXJTLVJ$))H{R!YOg}2}5sxO(0o;Zbh_Mr0$?P!%f&EB;~ zO1>Z^A;Fw7?F&qsD8zeD5SW=g1+dj$X>A5;cse!*!{rTrEg|aatpP}f9}J1O&9iZ| zatNfB#&Rgn1;_hyw}5+D_XobQ!)5itnyfYhNT^2v%p1BnI~y%|gWoYMWT?O&3b(K{ z0;+f1>2+ps2vpCB8Yd19E)YU^VGNYKsZ+(^9n%+wyVVzP-aw8?kN1jEhVkn3$mB#B z@&(d8m>hYYK|Z*eHIeq)vg(aSqwVbALM(!<$weGfXJm%gX@vRVZC`6Ij5dU>vnHQR znGN#a;RAvlw?x_pahR)Xda8j+2ewQ4C=Q%gTcPt&kgzz^6yF#kbfcxhw?xu|y+Dfm z?f%&y2HnrY;8u*hEc#EagnE~;6f|}#3%MdB;y_;DcpZChx^#myoF^P!e*KGs>-cFoS6BvsY)VRWxg1LeG4wkR1>(#f zX6EBqxf6U-01e;%J*889>*6Bip$cq+aN4 zzsRmwVcod}#Y-_fqGvb`IJbU!d%M9>J9wxa1jrycN;o-z=fao6(eBE1pB}pvRGJi7 zwsSXSB!pDoRAQY@Sr{nV%Q@!5?Ie3!TD>yGPZsFdNRwlHdUI?cGtgBCI?BKgzK+jaOE+a|sM1mk} z0(L~Ex>$@!b9QSFwfl67!rRC-+<>zV^6`Bis{1g&0~@j;Skq`dLCrNM-s;cU;thN z`>C%}kq4ftsPZ3Ymw(sH3an;<^6#4Cos$L~t;_@iL|V#tp@{E1W?O+wvLfg`Bw-r7 zM=?>pWQ?&UWAwHmvoQYJXtW)?L?#P7w}}iip=a<>eYpUIrOFwVzsjn}pkxYZOSO7; zpQ`HbPE4n5Q<`O_e5~Y70-3agN)-i8EY4098z?*68zdG!G&ORFWAKtmDOV-sinGU*?`~iP7D?|7frx#WS4g=0l|(vPX<0Zt52oP- z6j^8o_k2KOx(|%|NKsR9~!YTsbcbLqk^=hbF zXy6CRWmNvg3#7mV*ivyr{4d!0ul1@XGjWvj;HwehrHQsNry}?Oa(&> zbSRVP#p1xW%ppd<-iNysAc0IL`z zh~k&NYN4~xNDB5;7sGcDF4m#|a<<5NwItWYqkMaVqABv4giZiv)B6DB3H8qMgi5nZ zLnS$SG}V2VVFCwBI?QI1;I)jB9FJ2<8@o8W=Yfd#s*8BvIO3Qf#WEmL`BL>X?DFtK zB2s{-$fxjSnxwJ!tuc8b`50Kvk1#JFGj=t$ogrsH`Sg?l7!IjKuA|UeGgm{&2!^#g8?@%UAN1Ui{nMKKP;5?%J_6H zxlQ>{+VgeZpGthcm}W_ECDzfNU{%Me;`~Ow^nUJo#5q6Rc8U-wRpmd_&VSFkx2hl4 z^LGBZ>GB+JTjYRX?pzS7)5gw!7v%y~zO?+-cyRpyc7Au(k8G@`e#K7fzADqchL_fV zEJRnRvNJd}(p<~Ss#Ms9zB3DQ{W~gl!e#L_&8hnqRqwf>X2};fWxbJFy}P|PTT#Pr z=Nwg(j@#Y#rOIRoL{y2q8An35Hxc+Zj%K;*A%0U9E1--d!H*B9+Ri8xJS5sPiw$6H zZI*ccrV!N`UfL^*)$cIob>VmK>*Ar?oBR}}0g~MDolHra_&%e~`;_GO?uAM4Ldo@= z?qiUx^(WhNCYR~z;CIu$LIQ@^2XSzqorcO-(BiKtUzgv0?mJ+`+8I)h`ocEAHEsIF_%&lp-F@nKlz~MtKLaiI4^IZD1pgY#mnW2W(rP9Gd~lxzfUrepVkUJCJa4#N z7R;P>6x(;dW?KS~O9l|6%b#f{10LLUY`;5ZSDIe{?sYM8FoBZby*-ZecieVepzHR2 z;gJGR_^&qryme~=Mpz_G%(6ozSe5XjPKwrBa9jWIIj9q-b&MZ9!R_#of`LPw=8fU{ zvUbPctOu&vrUa_|)+~sOlsLa3GrSb`Kq5VhdM)6Hfu5Vw)ia`wTv>d8QaqOBEe7{2KRa*f-!peC!>32Jlm6F65B`jdm}$_JkwBy z)Ct}BWnzcl%09$~Cm}=F z2iAxzSXekBTLFx$rG0_{wF2ho@}FT5u7{&Gatt42Ws}gDFP+2lBn&GvQqwPB_qM5)(oG0$ zb(`#+aP8!trNQ(LerN~Z2(O)(Je)@U#qt-_pO5iuH8MWlO?nt+br|G-O~aJPr|N>3sZtBN zdPB$G?8hkBr5Mky9G%&*{Wvvp0ur}k2T$F^l_I7O!07ov@3h>875u38>@sj+DGbgG zd(viVK^mWlidKKs75>zV0I)Q8I^xY>Ha@|UT#8n!KmVDe!}#$^!SdbKXfOUY@SknH z+B>CaN-thDh|Hpz)I(Bu0A?y`#ufEYd(slNsyj;Of@}9c8P-IOsU$k-9qH{?lfbQ> zU}`qJtfKA-7fODYH~1Cks~Um|l3wbZo*lW(j2}4lMjvRjkseK5D|hxNfKSX5-&T>ju-F)qY@tGu{vGraVf3GX7G!`EoD1&=y91{z9h$$lW@_rwS%3rqsy_LY|A*vNQ}RG;|9tN z&4GVt*!GLtoaQ45%opXmLUnR4DO}JO-Ha2B zLJ#z6Y&ROS3e8^6W`o@k*_(D7n{stLz^A=8+HI^pjek;NYt;BFAZHCdLusu57kfzp zxMN+wV}2Cy3W`Fv8w7k40VnFe82(P$8ru0lI*kUdX>TFZjH!eBLw>ZetCAa2&8aM) zM>UHK1JfnY&Xq?PuY`ee()zMN7XyykIWY{x*qJga0in91_5~z+th-&eD+eM|hAxhV z@+8|IXyMD7NME;24&R$dNgBSxW3ARVd_xnPElE)=*=(%iqtGHqZsbh@y{|W|B({7Z z(_-{~$nU<@*X*}9CiIqrJDnmf&Ym(K>(X~Ox!!G&^j#a9214JQSd;b4it@x3W3%FT zG+XJ8Cm`Mjh{^OE$2JnD!y+=go{IGtz-<$oVaFE3U@+@J&hONwsGZ0*dVaS`?#X4b zHtOlg>%)mrY<{cDX_9b~$H#4c_ath@+KOPHJZ6K`H*y7ut%G5{ z5WCl%DJ5t)PEX8#v=f{EbsHM12#G!e7EowUEnZ2FP)(Y_m!JN1NK02q6{ zFs*y7H&<;hiegLNSAc}{#DqT+V{k!#`2uy(rQugg-1*BK z80^qB8h`pzVVvM25dy54|0R=xg?y%6&}!%q=(cm<+KD_U^Z$VI_a>L`%<}0dA07kS zJh~zb3ywcfwdj(u-w;+nmG;Z~vk|UDEsuU~f2Lpk^ZGNC<$tbz zzRGT}cLDW>s>CS3;sgucAi~567{6d|2$`NeU15o37MiNw-GX=j z?X&{hffW~C9RD1zlbtOQGC`!qh8YVneMDmvdV>{#ZtVOloHWZsgMd{ESionoz+w?^ zP_t*tIFQ&A>ak0OAd2F8l0GkYJ^2tJ!0*K^iWq*Ri8y@=C+PmzwIy7;r^qdqkdH(@+*O#hjOnvD=jFl&br+PNUMwz-oXCgB zx9)3}`%vgU^mZT4!$K!gV1{!WN0ckdSM)Mc>Q3-` ztTziSU< z#CNY}={k(q@CO+2B5J^cWW;SC@_~#<8!kqN7$f?Bf)N)9tY5>34-!J05zFwJ@@Va)EQ)9+2p?k9T|J=r5bOG=Y69Kra@Vir!;`V-am@u)d5-48DKLiW z=ffMosXxevG5c_Pv`4z{5KLj%i%|OeWWX}EM@yUe()+vXW03=*Vwzk55sOdu6pG4X z#3AZYdqvl4eJ=i~*h0uzFpJ}3JdJZ?&5!xq+IGsHX9k=~C)(w6X5hK$Xhd@)M9>j# z>^=M*s99+*T$kz%UDa9g6 zOmxVP%aP^XsLL*wqc0~>UCwv)lg0%1Y!OrIR=7E$;ZgXb^P?*w_tv#v^m?9@yBJQ5 zb*Pr$w$a0d^Gs?cj7d;K#Hoyz?Kv_hN!nFds6@#%HGZC-5NPQsx;7 z>SKWviP%>*pN(gvg3N34t)r%+&vg9}D6$H*V=fS@;zRCdPFk`Ksd{%=J3+L4p{|3Z zi!4KD^?S6mZ4D$YBKklAO}kC-en9`&&h3J?U2wZTFBwRuWLfxms@>>z-7_wvgAK$f zUe(I3U(cv%(AW9@9Ck%KX_D)wO8EqUB325`f<0eV8yWi|5M z{(?V1YVya`+ws|^(QU$;kQ?idT^`Bs+dbTt->ZyZb@viD!IAV(j52c z$trU&-`%fDHFeKvTDRVXcEWQ7l|rcTq6T*ULaTfwht33`zyW7l=PG>js_Cc`W4p|a z8H+Qygv5hnU$`k%wdunC8uB8T)45mZ=?O0NpnIMM%f0!FeED|pGsKTNXW7BCZD%Yd z;{2>1zHd^@RK2@Drs|PGf44&t3Itd4_*@K#5Ta37A6&?A~8Cqai(w_hV$^xISsy``8yBvp#9jmdoo?&8QgmOCa7Px3vA z_u~B_Sf}wckhuiQY;Eu#LYDG1?2myBiqyQzG5|$Z_Y`OHQ3(oSQYKj)_;xm4BJ7(JZRT2rmG|3w!oRe?hVru)e&+0 z6Z6!_=`Fs)Ws1r?ck$um&P)(45>^GjnJZZk=&JRDJ0HXjPM!}u(#7W`#C(0(>^51}7>*`V0xra>&XrNQ6F8>|3mnoO;DZ6_L(_J-?3eq}pie$zL`)tu%ktXbfT3%#w~P7)sF24ledOT@g!Wr=!5g z50IBpG#hhRY`o7AeN_@z;Xjs@tx|v~#?y#%0A}P_+_$9Nw;1~`1Go}Lq*lRzOkbG8 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�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

FM73XU%g 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 diff --git a/plane_segmentation/pcl_visualization_catkin/lib/pkgconfig/pcl_visualization-1.10.pc b/plane_segmentation/pcl_visualization_catkin/lib/pkgconfig/pcl_visualization-1.10.pc deleted file mode 100644 index 49fb4aee..00000000 --- a/plane_segmentation/pcl_visualization_catkin/lib/pkgconfig/pcl_visualization-1.10.pc +++ /dev/null @@ -1,13 +0,0 @@ -# This file was generated by CMake for PCL library pcl_visualization -prefix=/usr -exec_prefix=${prefix} -libdir=${prefix}/lib/x86_64-linux-gnu -#includedir=${prefix}/include/pcl-1.10/pcl -includedir=${prefix}/include/pcl-1.10 -Name: pcl_visualization -Description: Point cloud visualization library -Version: 1.10.0 -Requires: libopenni libopenni2 pcl_common-1.10 pcl_io-1.10 pcl_kdtree-1.10 pcl_geometry-1.10 pcl_search-1.10 pcl_octree-1.10 -Libs: -L${libdir} -lpcl_visualization -Cflags: -I${includedir} - diff --git a/plane_segmentation/pcl_visualization_catkin/package.xml b/plane_segmentation/pcl_visualization_catkin/package.xml deleted file mode 100644 index ebdcc8c3..00000000 --- a/plane_segmentation/pcl_visualization_catkin/package.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - pcl_visualization_catkin - 1.10.0 - Catkin wrapper for PCL visualization. - Ruben Grandia - - See package - - catkin - libvtk7-dev - - From 68a519b9386d1b3d25bbce945bd425224af3251d Mon Sep 17 00:00:00 2001 From: Alexander Reimann Date: Tue, 12 Jul 2022 18:12:50 +0200 Subject: [PATCH 232/504] Add fix for ModuleNotFoundError in README --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 0f1c94c5..7f3f9628 100644 --- a/README.md +++ b/README.md @@ -222,6 +222,21 @@ For the plane segmentation node roslaunch convex_plane_decomposition_ros convex_plane_decomposition.launch ``` +#### Errors +If you build with the install flag under ros melodic, you might get issues with the modules not found: + +```bash +terminate called after throwing an instance of 'pybind11::error_already_set' + what(): ModuleNotFoundError: No module named 'elevation_mapping_cupy' +``` +This is because python3 modules are installed into a different location. + +This can be fixed by including also the python3 modules location in the `PYTHONPATH` by adding following line into the launch file: + +```xml + +``` + ### Run TurtleBot example First, install turtlebot simulation. From 4b9c3718b089b77477e8dfcb5b7158dde746ef05 Mon Sep 17 00:00:00 2001 From: Takahiro Miki Date: Sat, 23 Jul 2022 16:09:31 +0200 Subject: [PATCH 233/504] Update README.md --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7f3f9628..589badb9 100644 --- a/README.md +++ b/README.md @@ -362,20 +362,30 @@ class NameOfYourPlugin(PluginBase): Then, add your plugin setting to `config/plugin_config.yaml` ```yaml -example: # Use the same name as your file name. +example: # Name of your filter + type: "example" # Specify the name of your plugin (the name of your file name). enable: True # weather to load this plugin fill_nan: True # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "example_layer" # The layer name. extra_params: # This params are passed to the plugin class on initialization. add_value: 2.0 # Example param + +example_large: # You can apply same filter with different name. + type: "example" # Specify the name of your plugin (the name of your file name). + enable: True # weather to load this plugin + fill_nan: True # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "example_layer_large" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + add_value: 100.0 # Example param with larger value. ``` Finally, add your layer name to publishers in `config/parameters.yaml`. You can create a new topic or add to existing topics. ```yaml plugin_example: # Topic name - layers: [ 'elevation', 'example_layer' ] + layers: [ 'elevation', 'example_layer', 'example_layer_large' ] basic_layers: [ 'example_layer' ] fps: 1.0 # The plugin is called with this fps. ``` From c91e01ebf97f9fb1d8dc82518080c5d49402478f Mon Sep 17 00:00:00 2001 From: Takahiro Miki Date: Sat, 23 Jul 2022 16:09:56 +0200 Subject: [PATCH 234/504] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 589badb9..a4a72310 100644 --- a/README.md +++ b/README.md @@ -376,7 +376,7 @@ example_large: # You can apply same filter with d enable: True # weather to load this plugin fill_nan: True # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "example_layer_large" # The layer name. + layer_name: "example_layer_large" # The layer name. extra_params: # This params are passed to the plugin class on initialization. add_value: 100.0 # Example param with larger value. ``` From 42fb80ccd7f398257557cd3c33a45d721c4acc0b Mon Sep 17 00:00:00 2001 From: rgrandia Date: Thu, 28 Jul 2022 17:46:51 +0200 Subject: [PATCH 235/504] merge 3 loops around edges into 1 --- .../ConvexRegionGrowing.h | 4 - .../src/ConvexRegionGrowing.cpp | 115 +++++++++++++----- 2 files changed, 82 insertions(+), 37 deletions(-) diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h index 498ce95b..a760ecd7 100644 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h +++ b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h @@ -15,10 +15,6 @@ CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygon2d& parentShape, Cga CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygonWithHoles2d& parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor); -template -bool pointCanBeMoved(const CgalPolygon2d& growthShape, int i, const CgalPoint2d& candidatePoint, CgalCircle2d& freeSphere, - const T& parentShape); - void updateMean(CgalPoint2d& mean, const CgalPoint2d& oldValue, const CgalPoint2d& updatedValue, int N); } // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/src/ConvexRegionGrowing.cpp b/plane_segmentation/convex_plane_decomposition/src/ConvexRegionGrowing.cpp index c94282f0..052a0c97 100644 --- a/plane_segmentation/convex_plane_decomposition/src/ConvexRegionGrowing.cpp +++ b/plane_segmentation/convex_plane_decomposition/src/ConvexRegionGrowing.cpp @@ -8,20 +8,7 @@ namespace convex_plane_decomposition { -CgalPolygon2d createRegularPolygon(const CgalPoint2d& center, double radius, int numberOfVertices) { - assert(numberOfVertices > 2); - CgalPolygon2d polygon; - polygon.container().reserve(numberOfVertices); - double angle = (2. * M_PI) / numberOfVertices; - for (int i = 0; i < numberOfVertices; ++i) { - double phi = i * angle; - double px = radius * std::cos(phi) + center.x(); - double py = radius * std::sin(phi) + center.y(); - // Counter clockwise - polygon.push_back({px, py}); - } - return polygon; -} +namespace { int getCounterClockWiseNeighbour(int i, int lastVertex) { return (i > 0) ? i - 1 : lastVertex; @@ -31,12 +18,6 @@ int getClockWiseNeighbour(int i, int lastVertex) { return (i < lastVertex) ? i + 1 : 0; } -void updateMean(CgalPoint2d& mean, const CgalPoint2d& oldValue, const CgalPoint2d& updatedValue, int N) { - // old_mean = 1/N * ( others + old_value); -> others = N*old_mean - old_value - // new_mean = 1/N * ( others + new_value); -> new_mean = old_mean - 1/N * oldValue + 1/N * updatedValue - mean += 1.0 / N * (updatedValue - oldValue); -} - std::array getNeighbours(const CgalPolygon2d& polygon, int i) { assert(i < polygon.size()); assert(polygon.size() > 1); @@ -75,6 +56,55 @@ bool pointAndNeighboursAreWithinFreeSphere(const std::array& nei return isInside(neighbours[0], circle) && isInside(point, circle) && isInside(neighbours[1], circle); } +/** + * Returns {true, 0.0} if either one of the point -> neighbour segments intersects the parent shape + * Returns {false, minSquareDistance} if none of the segments intersects. minSquareDistance is the minimum square distance between the + * point and the parent shape + */ +template +std::pair doEdgesIntersectAndSquareDistance(const std::array& neighbours, const CgalPoint2d& point, + const T& parentShape); + +template <> +std::pair doEdgesIntersectAndSquareDistance(const std::array& neighbours, const CgalPoint2d& point, + const CgalPolygon2d& parentShape) { + CgalSegment2d segment0{neighbours[0], point}; + CgalSegment2d segment1{neighbours[1], point}; + + double minDistSquared = std::numeric_limits::max(); + for (auto edgeIt = parentShape.edges_begin(); edgeIt != parentShape.edges_end(); ++edgeIt) { + const auto edge = *edgeIt; + if (CGAL::do_intersect(segment0, edge) || CGAL::do_intersect(segment1, edge)) { + return {true, 0.0}; + } else { + minDistSquared = std::min(minDistSquared, CGAL::squared_distance(point, edge)); + } + } + + return {false, minDistSquared}; +} + +template <> +std::pair doEdgesIntersectAndSquareDistance(const std::array& neighbours, const CgalPoint2d& point, + const CgalPolygonWithHoles2d& parentShape) { + const auto intersectAndDistance = doEdgesIntersectAndSquareDistance(neighbours, point, parentShape.outer_boundary()); + if (intersectAndDistance.first) { + return {true, 0.0}; + } + + double minDistSquared = intersectAndDistance.second; + for (const auto& hole : parentShape.holes()) { + const auto holeIntersectAndDistance = doEdgesIntersectAndSquareDistance(neighbours, point, hole); + if (holeIntersectAndDistance.first) { + return {true, 0.0}; + } else { + minDistSquared = std::min(minDistSquared, holeIntersectAndDistance.second); + } + } + + return {false, minDistSquared}; +} + template bool pointCanBeMoved(const CgalPolygon2d& growthShape, int i, const CgalPoint2d& candidatePoint, CgalCircle2d& freeSphere, const T& parentShape) { @@ -83,17 +113,15 @@ bool pointCanBeMoved(const CgalPolygon2d& growthShape, int i, const CgalPoint2d& if (pointAndNeighboursAreWithinFreeSphere(neighbours, candidatePoint, freeSphere)) { return true; } else { - // Update free sphere around new point - freeSphere = CgalCircle2d(candidatePoint, squaredDistance(candidatePoint, parentShape)); - CgalSegment2d segment0{neighbours[0], candidatePoint}; - CgalSegment2d segment1{neighbours[1], candidatePoint}; - - bool segment0IsFree = isInside(neighbours[0], freeSphere) || !doEdgesIntersect(segment0, parentShape); - if (segment0IsFree) { - bool segment1IsFree = isInside(neighbours[1], freeSphere) || !doEdgesIntersect(segment1, parentShape); - return segment1IsFree; - } else { + // Look for intersections and minimum distances simultaneously + const auto intersectAndDistance = doEdgesIntersectAndSquareDistance(neighbours, candidatePoint, parentShape); + + if (intersectAndDistance.first) { return false; + } else { + // Update free sphere around new point + freeSphere = CgalCircle2d(candidatePoint, intersectAndDistance.second); + return true; } } } else { @@ -101,7 +129,6 @@ bool pointCanBeMoved(const CgalPolygon2d& growthShape, int i, const CgalPoint2d& } } -namespace { inline std::ostream& operator<<(std::ostream& os, const CgalPolygon2d& p) { os << "CgalPolygon2d: \n"; for (auto it = p.vertices_begin(); it != p.vertices_end(); ++it) { @@ -119,7 +146,6 @@ inline std::ostream& operator<<(std::ostream& os, const CgalPolygonWithHoles2d& } return os; } -} // namespace template CgalPolygon2d growConvexPolygonInsideShape_impl(const T& parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor) { @@ -164,10 +190,26 @@ CgalPolygon2d growConvexPolygonInsideShape_impl(const T& parentShape, CgalPoint2 std::cerr << "Center: " << centerCopy.x() << ", " << centerCopy.y() << "\n"; std::cerr << parentShape << "\n"; } - return growthShape; } +} // namespace + +CgalPolygon2d createRegularPolygon(const CgalPoint2d& center, double radius, int numberOfVertices) { + assert(numberOfVertices > 2); + CgalPolygon2d polygon; + polygon.container().reserve(numberOfVertices); + double angle = (2. * M_PI) / numberOfVertices; + for (int i = 0; i < numberOfVertices; ++i) { + double phi = i * angle; + double px = radius * std::cos(phi) + center.x(); + double py = radius * std::sin(phi) + center.y(); + // Counter clockwise + polygon.push_back({px, py}); + } + return polygon; +} + CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygon2d& parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor) { return growConvexPolygonInsideShape_impl(parentShape, center, numberOfVertices, growthFactor); @@ -177,4 +219,11 @@ CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygonWithHoles2d& parentS double growthFactor) { return growConvexPolygonInsideShape_impl(parentShape, center, numberOfVertices, growthFactor); } + +void updateMean(CgalPoint2d& mean, const CgalPoint2d& oldValue, const CgalPoint2d& updatedValue, int N) { + // old_mean = 1/N * ( others + old_value); -> others = N*old_mean - old_value + // new_mean = 1/N * ( others + new_value); -> new_mean = old_mean - 1/N * oldValue + 1/N * updatedValue + mean += 1.0 / N * (updatedValue - oldValue); +} + } // namespace convex_plane_decomposition From 4d8a346fe77ee1271dea5f3bf25bd867097aeb8f Mon Sep 17 00:00:00 2001 From: Simone Arreghini <45604569+arsimone@users.noreply.github.com> Date: Tue, 6 Sep 2022 17:22:05 +0200 Subject: [PATCH 236/504] Removed typo include Removed include of grid_map_msgs from in PlaneDecompositionPipeline.h, likely a typo --- .../convex_plane_decomposition/PlaneDecompositionPipeline.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h index 459e8f44..78fc52e0 100644 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h +++ b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h @@ -4,8 +4,6 @@ #pragma once -#include - #include "convex_plane_decomposition/GridMapPreprocessing.h" #include "convex_plane_decomposition/PlanarRegion.h" #include "convex_plane_decomposition/Postprocessing.h" @@ -76,4 +74,4 @@ class PlaneDecompositionPipeline { Timer postprocessTimer_; }; -} // namespace convex_plane_decomposition \ No newline at end of file +} // namespace convex_plane_decomposition From 16a2a41e046ee6830a1bc17cd8350c55d3014db3 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Tue, 18 Oct 2022 19:53:35 +0200 Subject: [PATCH 237/504] implemented cpp part for universal semantic mapping. I did not format the code yet as it would be hard to recognize the canges --- .gitignore | 1 + elevation_mapping_cupy/config/parameters.yaml | 16 +- .../config/sensor_parameter.yaml | 9 + .../elevation_mapping_ros.hpp | 1 + .../elevation_mapping_wrapper.hpp | 10 +- .../semantic_elevation_lonomy_single.launch | 23 + .../rviz/lonomy_single.rviz | 475 ++++++++++++++++++ .../elevation_mapping.py | 15 +- .../elevation_mapping_cupy/parameter.py | 6 +- .../plugins/plugin_manager.py | 4 +- .../src/elevation_mapping_ros.cpp | 64 ++- .../src/elevation_mapping_wrapper.cpp | 32 +- 12 files changed, 597 insertions(+), 59 deletions(-) create mode 100644 elevation_mapping_cupy/config/sensor_parameter.yaml create mode 100644 elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch create mode 100644 elevation_mapping_cupy/rviz/lonomy_single.rviz diff --git a/.gitignore b/.gitignore index 732c5512..0f73a391 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.pyc *.bkp *.orig +.idea \ No newline at end of file diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index fccd4509..c25e0ec2 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -40,9 +40,9 @@ max_unsafe_n: 10 # if the number of cells under s overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) -map_frame: 'odom' # The map frame where the odometry source uses. -base_frame: 'base' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'corrected_odom' +map_frame: 'enu' # The map frame where the odometry source uses. +base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. +corrected_map_frame: 'enu' #### Feature toggles ######## enable_edge_sharpen: true @@ -64,13 +64,7 @@ use_only_above_for_upper_bound: false plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/plugin_config.yaml' #### Subscribers ######## -pointcloud_topics: ['/depth_camera_front/depth/color/points', - '/depth_camera_rear/depth/color/points', - '/depth_camera_left/depth/color/points', - '/depth_camera_right/depth/color/points', - '/robot_self_filter/bpearl_front/point_cloud', - '/robot_self_filter/bpearl_rear/point_cloud' - ] + #### Publishers ######## # topic_name: @@ -93,7 +87,7 @@ publishers: #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['RF_FOOT', 'LF_FOOT', 'RH_FOOT', 'LH_FOOT'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 5 # dilation size after the init. initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml new file mode 100644 index 00000000..b39e5743 --- /dev/null +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -0,0 +1,9 @@ +subscribers: +# sensor_name: +# channels: ['feat_0','feat_1'] +# fusion: ['average','average'] +# topic_name: '/elevation_mapping/pointcloud_semantic' + front_cam: + channels: ['feat_0','feat_1'] + fusion: ['average','average'] + topic_name: '/elvation_mapping/pointcloud_semantic' diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 7a374437..faa82719 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -48,6 +48,7 @@ namespace elevation_mapping_cupy { class ElevationMappingNode { public: ElevationMappingNode(ros::NodeHandle& nh); + using RowMatrixXd = Eigen::Matrix; private: void readParameters(); diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index 97bec2a5..e03e705c 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -13,6 +13,7 @@ // Pybind #include // everything needed for embedding +#include // ROS #include @@ -42,11 +43,11 @@ class ElevationMappingWrapper { ElevationMappingWrapper(); - void initialize(ros::NodeHandle& nh); + void initialize(ros::NodeHandle& nh, std::vector additional_layers, std::vector fusion_algorithms); - void input(const pcl::PointCloud::Ptr& pointCloud, const RowMatrixXd& R, const Eigen::VectorXd& t, + void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); - void move_to(const Eigen::VectorXd& p); + void move_to(const Eigen::VectorXd& p, const RowMatrixXd& R); void clear(); void update_variance(); void update_time(); @@ -57,11 +58,10 @@ class ElevationMappingWrapper { std::vector& untraversable_polygon); double get_additive_mean_error(); void initializeWithPoints(std::vector& points, std::string method); - void pointCloudToMatrix(const pcl::PointCloud::Ptr& pointCloud, RowMatrixXd& points); void addNormalColorLayer(grid_map::GridMap& map); private: - void setParameters(ros::NodeHandle& nh); + void setParameters(ros::NodeHandle& nh, std::vector additional_layers, std::vector fusion_algorithms); py::object map_; py::object param_; double resolution_; diff --git a/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch b/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch new file mode 100644 index 00000000..77b4918f --- /dev/null +++ b/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/elevation_mapping_cupy/rviz/lonomy_single.rviz b/elevation_mapping_cupy/rviz/lonomy_single.rviz new file mode 100644 index 00000000..8f890eb7 --- /dev/null +++ b/elevation_mapping_cupy/rviz/lonomy_single.rviz @@ -0,0 +1,475 @@ +Panels: + - Class: rviz/Displays + Help Height: 138 + Name: Displays + Property Tree Widget: + Expanded: + - /ElevationMapFilter1 + - /Image1 + Splitter Ratio: 0.5768463015556335 + Tree Height: 410 + - Class: rviz/Selection + Name: Selection + - Class: rviz/Tool Properties + Expanded: + - /2D Pose Estimate1 + - /2D Nav Goal1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz/Time + Name: Time + SyncMode: 0 + SyncSource: Image +Preferences: + PromptSaveOnExit: true +Toolbars: + toolButtonStyle: 2 +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.029999999329447746 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: smooth + Color Transformer: IntensityLayer + Enabled: true + Height Layer: min_filter + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 255; 255; 255 + Max Intensity: 10 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: ElevationMapFilter + Show Grid Lines: true + Topic: /elevation_mapping/elevation_map_filter + Unreliable: false + Use Rainbow: false + Value: true + - Alpha: 1 + Class: rviz/RobotModel + Collision Enabled: false + Enabled: true + Links: + All Links Enabled: true + Expand Joint Details: false + Expand Link Details: false + Expand Tree: false + GPS_back: + Alpha: 1 + Show Axes: false + Show Trail: false + GPS_front: + Alpha: 1 + Show Axes: false + Show Trail: false + Link Tree Style: Links in Alphabetic Order + alphasense: + Alpha: 1 + Show Axes: false + Show Trail: false + base_footprint: + Alpha: 1 + Show Axes: false + Show Trail: false + base_inertial: + Alpha: 1 + Show Axes: false + Show Trail: false + base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + estimator_imu: + Alpha: 1 + Show Axes: false + Show Trail: false + left_back_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + left_back_wheel_sup: + Alpha: 1 + Show Axes: false + Show Trail: false + left_front_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + left_front_wheel_sup: + Alpha: 1 + Show Axes: false + Show Trail: false + rear_axle_center: + Alpha: 1 + Show Axes: false + Show Trail: false + right_back_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + right_back_wheel_sup: + Alpha: 1 + Show Axes: false + Show Trail: false + right_front_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + right_front_wheel_sup: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_baro_link: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_camera_center: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + zed2i_left_camera_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_left_camera_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_mag_link: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_right_camera_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_right_camera_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_temp_left_link: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_temp_right_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Name: RobotModel + Robot Description: robot_description + TF Prefix: "" + Update Interval: 0 + Value: true + Visual Enabled: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Autocompute Value Bounds: + Max Value: 10 + Min Value: -10 + Value: true + Axis: Z + Channel Name: intensity + Class: rviz/PointCloud2 + Color: 255; 255; 255 + Color Transformer: RGB8 + Decay Time: 0 + Enabled: false + Invert Rainbow: false + Max Color: 255; 255; 255 + Min Color: 0; 0; 0 + Name: PointCloud2 + Position Transformer: XYZ + Queue Size: 10 + Selectable: true + Size (Pixels): 3 + Size (m): 0.009999999776482582 + Style: Flat Squares + Topic: /elvation_mapping/pointcloud_semantic_left + Unreliable: false + Use Fixed Frame: true + Use rainbow: true + Value: false + - Alpha: 1 + Autocompute Intensity Bounds: true + Autocompute Value Bounds: + Max Value: 10 + Min Value: -10 + Value: true + Axis: Z + Channel Name: intensity + Class: rviz/PointCloud2 + Color: 255; 255; 255 + Color Transformer: RGB8 + Decay Time: 0 + Enabled: false + Invert Rainbow: false + Max Color: 255; 255; 255 + Min Color: 0; 0; 0 + Name: PointCloud2 + Position Transformer: XYZ + Queue Size: 10 + Selectable: true + Size (Pixels): 3 + Size (m): 0.009999999776482582 + Style: Flat Squares + Topic: /elvation_mapping/pointcloud_semantic_right + Unreliable: false + Use Fixed Frame: true + Use rainbow: true + Value: false + - Class: rviz/TF + Enabled: true + Frame Timeout: 15 + Frames: + All Enabled: true + GPS_back: + Value: true + GPS_front: + Value: true + alphasense: + Value: true + base_footprint: + Value: true + base_inertial: + Value: true + base_link: + Value: true + enu: + Value: true + estimator_imu: + Value: true + left_back_wheel: + Value: true + left_back_wheel_sup: + Value: true + left_front_wheel: + Value: true + left_front_wheel_sup: + Value: true + rear_axle_center: + Value: true + right_back_wheel: + Value: true + right_back_wheel_sup: + Value: true + right_front_wheel: + Value: true + right_front_wheel_sup: + Value: true + zed2i_baro_link: + Value: true + zed2i_base_link: + Value: true + zed2i_camera_center: + Value: true + zed2i_left_camera_frame: + Value: true + zed2i_left_camera_optical_frame: + Value: true + zed2i_mag_link: + Value: true + zed2i_right_camera_frame: + Value: true + zed2i_right_camera_optical_frame: + Value: true + zed2i_temp_left_link: + Value: true + zed2i_temp_right_link: + Value: true + Marker Alpha: 1 + Marker Scale: 1 + Name: TF + Show Arrows: true + Show Axes: true + Show Names: true + Tree: + enu: + base_link: + base_footprint: + {} + base_inertial: + {} + estimator_imu: + GPS_back: + {} + GPS_front: + {} + alphasense: + {} + left_back_wheel_sup: + left_back_wheel: + {} + left_front_wheel_sup: + left_front_wheel: + {} + rear_axle_center: + {} + right_back_wheel_sup: + right_back_wheel: + {} + right_front_wheel_sup: + right_front_wheel: + {} + zed2i_base_link: + zed2i_camera_center: + zed2i_baro_link: + {} + zed2i_left_camera_frame: + zed2i_left_camera_optical_frame: + {} + zed2i_temp_left_link: + {} + zed2i_mag_link: + {} + zed2i_right_camera_frame: + zed2i_right_camera_optical_frame: + {} + zed2i_temp_right_link: + {} + Update Interval: 0 + Value: true + - Class: rviz/Image + Enabled: true + Image Topic: /zed2i/zed_node/left/image_rect_color + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Queue Size: 2 + Transport Hint: raw + Unreliable: false + Value: true + - Class: rviz/Image + Enabled: false + Image Topic: /zed2i_right/zed_right_node/left_raw/image_raw_color + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Queue Size: 2 + Transport Hint: raw + Unreliable: false + Value: false + - Class: rviz/Marker + Enabled: true + Marker Topic: /visualization_marker_l + Name: Marker + Namespaces: + {} + Queue Size: 100 + Value: true + - Class: rviz/Marker + Enabled: true + Marker Topic: /visualization_marker_r + Name: Marker + Namespaces: + {} + Queue Size: 100 + Value: true + Enabled: true + Global Options: + Background Color: 255; 255; 255 + Default Light: true + Fixed Frame: enu + Frame Rate: 30 + Name: root + Tools: + - Class: rviz/Interact + Hide Inactive Objects: true + - Class: rviz/MoveCamera + - Class: rviz/Select + - Class: rviz/FocusCamera + - Class: rviz/Measure + - Class: rviz/SetInitialPose + Theta std deviation: 0.2617993950843811 + Topic: /initialpose + X std deviation: 0.5 + Y std deviation: 0.5 + - Class: rviz/SetGoal + Topic: /move_base_simple/goal + - Class: rviz/PublishPoint + Single click: true + Topic: /clicked_point + Value: true + Views: + Current: + Class: rviz/Orbit + Distance: 8.01580810546875 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Field of View: 0.7853981852531433 + Focal Point: + X: 0.7929360866546631 + Y: 0.3796532452106476 + Z: -0.4990573823451996 + Focal Shape Fixed Size: true + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 0.34979793429374695 + Target Frame: base_footprint + Yaw: 5.212028980255127 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 1016 + Hide Left Dock: false + Hide Right Dock: true + Image: + collapsed: false + QMainWindow State: 000000ff00000000fd0000000400000000000001f50000039efc0200000009fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000261000000c900fffffffb0000000a0049006d00610067006501000002a4000001370000001600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000073800000131fc0100000003fb0000000a0049006d0061006700650000000394000003a40000005e00fffffffb0000000800540069006d00650000000000000007380000041800fffffffb0000000800540069006d006501000000000000045000000000000000000000053d0000039e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: true + Width: 1848 + X: 1992 + Y: 27 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index c300b0ca..4a50e069 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -16,7 +16,7 @@ from .custom_kernels import normal_filter_kernel from .custom_kernels import polygon_mask_kernel from .map_initializer import MapInitializer -from .plugins.plugin_manager import PluginManger +from .plugins.plugin_manager import PluginManager from .traversability_polygon import ( get_masked_traversability, @@ -48,7 +48,7 @@ def __init__(self, param: Parameter): self.cell_n = int(round(self.map_length / self.resolution)) + 2 self.map_lock = threading.Lock() - + self.additional_layers = dict(zip(self.param.additional_layers, self.param.fusion_algorithms)) # layers: elevation, variance, is_valid, traversability, time, upper_bound, is_upper_bound self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n)) self.layer_names = [ @@ -90,7 +90,7 @@ def __init__(self, param: Parameter): self.untraversable_polygon = xp.zeros((1, 2)) # Plugins - self.plugin_manager = PluginManger(cell_n=self.cell_n) + self.plugin_manager = PluginManager(cell_n=self.cell_n) plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') self.plugin_manager.load_plugin_settings(plugin_config_file) @@ -117,8 +117,9 @@ def move(self, delta_position): self.shift_map_xy(delta_pixel) self.shift_map_z(-delta_position[2]) - def move_to(self, position): + def move_to(self, position, R): # Shift map to the center of robot. + self.base_rotation = xp.asarray(R) position = xp.asarray(position) delta = position - self.center delta_pixel = xp.around(delta[:2] / self.resolution) @@ -311,11 +312,11 @@ def update_upper_bound_with_valid_elevation(self): self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) - def input(self, raw_points, R, t, position_noise, orientation_noise): + def input(self, raw_points,channels, R, t, position_noise, orientation_noise): # Update elevation map using point cloud input. raw_points = cp.asarray(raw_points) raw_points = raw_points[~cp.isnan(raw_points).any(axis=1)] - self.update_map_with_kernel(raw_points, cp.asarray(R), cp.asarray(t), position_noise, orientation_noise) + self.update_map_with_kernel(raw_points[:,:3], cp.asarray(R), cp.asarray(t), position_noise, orientation_noise) def update_normal(self, dilated_map): with self.map_lock: @@ -424,7 +425,7 @@ def get_map_with_name_ref(self, name, data): xp = self.xp_of_array(m) m = self.process_map_for_publish(m, fill_nan=p.fill_nan, add_z=p.is_height_layer, xp=xp) else: - # print("Layer {} is not in the map".format(name)) + print("Layer {} is not in the map".format(name)) return m = xp.flip(m, 0) m = xp.flip(m, 1) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 0e79622a..a00c3ddf 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -5,12 +5,14 @@ from dataclasses import dataclass import pickle import numpy as np -import os +from simple_parsing.helpers import Serializable @dataclass -class Parameter: +class Parameter(Serializable): resolution: float = 0.02 + additional_layers: list = ['feat_0'].copy + fusion_algorithms: list = ['average'].copy map_length: float = 10.0 sensor_noise_factor: float = 0.05 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index 3bbf3fed..719d45c9 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -54,7 +54,7 @@ def __call__( pass -class PluginManger(object): +class PluginManager(object): """ This manages the plugins. """ @@ -147,7 +147,7 @@ def get_param_with_name(self, name: str) -> PluginParams: PluginParams(name="smooth_filter", layer_name="smooth"), ] extra_params = [{"dilation_size": 5, "iteration_n": 5}, {"input_layer_name": "elevation2"}] - manager = PluginManger(200) + manager = PluginManager(200) manager.load_plugin_settings("config/plugin_config.yaml") print(manager.layer_names) print(manager.plugin_names) diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 79941e8f..236c04ea 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -30,15 +30,15 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) enablePointCloudPublishing_(false), isGridmapUpdated_(false) { nh_ = nh; - map_.initialize(nh_); + std::string pose_topic, map_frame; XmlRpc::XmlRpcValue publishers; - std::vector pointcloud_topics; + XmlRpc::XmlRpcValue subscribers; std::vector map_topics; double recordableFps, updateVarianceFps, timeInterval, updatePoseFps, updateGridMapFps, publishStatisticsFps; bool enablePointCloudPublishing(false); - nh.param>("pointcloud_topics", pointcloud_topics, {"points"}); + nh.getParam("subscribers", subscribers); nh.getParam("publishers", publishers); nh.param>("initialize_frame_id", initialize_frame_id_, {"base"}); nh.param>("initialize_tf_offset", initialize_tf_offset_, {0.0}); @@ -63,11 +63,29 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) enablePointCloudPublishing_ = enablePointCloudPublishing; - for (const auto& pointcloud_topic : pointcloud_topics) { + std::vector additional_layers; + std::vector fusion_algorithms; + for (auto & subscriber : subscribers) { + auto channels = subscriber.second["channels"]; + auto fusion = subscriber.second["fusion"]; + for (int32_t i = 0; i < channels.size(); ++i) { + auto name = static_cast(channels[i]); + if (!std::count(additional_layers.begin(), additional_layers.end(), name)){ + additional_layers.push_back(name); + fusion_algorithms.push_back(static_cast(fusion[i])); + } + } + + std::string pointcloud_topic = subscriber.second["topic_name"]; ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, &ElevationMappingNode::pointcloudCallback, this); pointcloudSubs_.push_back(sub); } + for (int i = 0; i < additional_layers.size(); ++i){ + ROS_INFO_STREAM("Additional layers " << additional_layers.at(i)<<" fusion algorithm "<::Ptr pointCloud(new pcl::PointCloud); - pcl::fromPCLPointCloud2(pcl_pc, *pointCloud); +// transform pointcloud into matrix + auto* pcl_pc = new pcl::PCLPointCloud2; + pcl::PCLPointCloud2ConstPtr cloudPtr(pcl_pc); + pcl_conversions::toPCL(cloud, *pcl_pc); + + uint array_dim = pcl_pc->point_step/4;// we assume that they are all float32 or at least 32bits + RowMatrixXd points = RowMatrixXd(pcl_pc->width,array_dim); + + for (unsigned int i = 0; i < pcl_pc->width; ++i) { + for(unsigned int j = 0; jpoint_step + pcl_pc->fields[j].offset; + memcpy(&temp, &pcl_pc->data[point_idx], sizeof(float)); + points(i, j) = static_cast(temp); + } + } +// get channels + auto fields = cloud.fields; + std::vector channels; + for(auto & field: fields){ + channels.push_back(field.name); +// TODO: check that datatype is always 7? + } +// get pose of sensor in map frame tf::StampedTransform transformTf; std::string sensorFrameId = cloud.header.frame_id; auto timeStamp = cloud.header.stamp; @@ -242,14 +279,13 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl positionError = positionError_; orientationError = orientationError_; } - - map_.input(pointCloud, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError, orientationError); + map_.input(points, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError, orientationError); if (enableDriftCorrectedTFPublishing_) { publishMapToOdom(map_.get_additive_mean_error()); } - ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed a point cloud (%i points) in %f sec.", static_cast(pointCloud->size()), + ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed a point cloud (%i points) in %f sec.", static_cast(points.size()), (ros::Time::now() - start).toSec()); ROS_DEBUG_THROTTLE(1.0, "positionError: %f ", positionError); ROS_DEBUG_THROTTLE(1.0, "orientationError: %f ", orientationError); @@ -260,9 +296,11 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl void ElevationMappingNode::updatePose(const ros::TimerEvent&) { tf::StampedTransform transformTf; const auto& timeStamp = ros::Time::now(); + Eigen::Affine3d transformationBaseToMap; try { transformListener_.waitForTransform(mapFrameId_, baseFrameId_, timeStamp, ros::Duration(1.0)); transformListener_.lookupTransform(mapFrameId_, baseFrameId_, timeStamp, transformTf); + poseTFToEigen(transformTf, transformationBaseToMap); } catch (tf::TransformException& ex) { ROS_ERROR("%s", ex.what()); return; @@ -270,7 +308,7 @@ void ElevationMappingNode::updatePose(const ros::TimerEvent&) { // This is to check if the robot is moving. If the robot is not moving, drift compensation is disabled to avoid creating artifacts. Eigen::Vector3d position(transformTf.getOrigin().x(), transformTf.getOrigin().y(), transformTf.getOrigin().z()); - map_.move_to(position); + map_.move_to(position,transformationBaseToMap.rotation().transpose()); Eigen::Vector3d position3(transformTf.getOrigin().x(), transformTf.getOrigin().y(), transformTf.getOrigin().z()); Eigen::Vector4d orientation(transformTf.getRotation().x(), transformTf.getRotation().y(), transformTf.getRotation().z(), transformTf.getRotation().w()); diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index d9662833..3da1d4d2 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -14,11 +14,13 @@ // ROS #include +#include + namespace elevation_mapping_cupy { ElevationMappingWrapper::ElevationMappingWrapper() {} -void ElevationMappingWrapper::initialize(ros::NodeHandle& nh) { +void ElevationMappingWrapper::initialize(ros::NodeHandle& nh, std::vector additional_layers, std::vector fusion_algorithms) { // Add the elevation_mapping_cupy path to sys.path auto threading = py::module::import("threading"); py::gil_scoped_acquire acquire; @@ -32,7 +34,7 @@ void ElevationMappingWrapper::initialize(ros::NodeHandle& nh) { auto elevation_mapping = py::module::import("elevation_mapping_cupy.elevation_mapping"); auto parameter = py::module::import("elevation_mapping_cupy.parameter"); param_ = parameter.attr("Parameter")(); - setParameters(nh); + setParameters(nh, std::move(additional_layers),std::move(fusion_algorithms)); map_ = elevation_mapping.attr("ElevationMap")(param_); } @@ -40,7 +42,7 @@ void ElevationMappingWrapper::initialize(ros::NodeHandle& nh) { * Load ros parameters into Parameter class. * Search for the same name within the name space. */ -void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { +void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh, std::vector additional_layers, std::vector fusion_algorithms) { // Get all parameters names and types. py::list paramNames = param_.attr("get_names")(); py::list paramTypes = param_.attr("get_types")(); @@ -74,6 +76,9 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { } } + param_.attr("set_value")("additional_layers",additional_layers); + param_.attr("set_value")("fusion_algorithms",fusion_algorithms); + resolution_ = py::cast(param_.attr("get_value")("resolution")); map_length_ = py::cast(param_.attr("get_value")("map_length")); map_n_ = static_cast(round(map_length_ / resolution_)); @@ -83,18 +88,16 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { nh.param("enable_normal_color", enable_normal_color_, false); } -void ElevationMappingWrapper::input(const pcl::PointCloud::Ptr& pointCloud, const RowMatrixXd& R, const Eigen::VectorXd& t, +void ElevationMappingWrapper::input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise) { py::gil_scoped_acquire acquire; - RowMatrixXd points; - pointCloudToMatrix(pointCloud, points); - map_.attr("input")(Eigen::Ref(points), Eigen::Ref(R), Eigen::Ref(t), + map_.attr("input")(Eigen::Ref(points),channels, Eigen::Ref(R), Eigen::Ref(t), positionNoise, orientationNoise); } -void ElevationMappingWrapper::move_to(const Eigen::VectorXd& p) { +void ElevationMappingWrapper::move_to(const Eigen::VectorXd& p, const RowMatrixXd& R) { py::gil_scoped_acquire acquire; - map_.attr("move_to")(Eigen::Ref(p)); + map_.attr("move_to")(Eigen::Ref(p), Eigen::Ref(R)); } void ElevationMappingWrapper::clear() { @@ -176,7 +179,7 @@ void ElevationMappingWrapper::get_polygon_traversability(std::vector 0) { RowMatrixXf untraversable_polygon_m(untraversable_polygon_num, 2); map_.attr("get_untraversable_polygon")(Eigen::Ref(untraversable_polygon_m)); - for (int j = 0; j < untraversable_polygon_num; i++) { + for (int j = 0; j < untraversable_polygon_num; j++) { Eigen::Vector2d p; p.x() = untraversable_polygon_m(j, 0); p.y() = untraversable_polygon_m(j, 1); @@ -198,15 +201,6 @@ void ElevationMappingWrapper::initializeWithPoints(std::vector& map_.attr("initialize_map")(Eigen::Ref(points_m), method); } -void ElevationMappingWrapper::pointCloudToMatrix(const pcl::PointCloud::Ptr& pointCloud, RowMatrixXd& points) { - points = RowMatrixXd(pointCloud->size(), 3); - for (unsigned int i = 0; i < pointCloud->size(); ++i) { - const auto& point = pointCloud->points[i]; - points(i, 0) = static_cast(point.x); - points(i, 1) = static_cast(point.y); - points(i, 2) = static_cast(point.z); - } -} void ElevationMappingWrapper::addNormalColorLayer(grid_map::GridMap& map) { const auto& normalX = map["normal_x"]; From f5730200a77115e674da3f8e9db2eaf3fa4f3850 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Wed, 26 Oct 2022 14:03:00 +0200 Subject: [PATCH 238/504] working elevation map in the new workframe with a new kernels, the old workflow embedded in the elevation map is still inside but commented and I started to document the functions and I integrated the first tests --- elevation_mapping_cupy/config/parameters.yaml | 2 +- .../config/sensor_parameter.yaml | 5 +- .../rviz/lonomy_single.rviz | 27 +- .../elevation_mapping_cupy/custom_kernels.py | 266 +++++++++++++++++- .../elevation_mapping.py | 217 +++++++++++++- .../elevation_mapping_cupy/parameter.py | 1 + .../elevation_mapping_cupy/semantic_map.py | 172 +++++++++++ .../elevation_mapping_cupy/tests/__init__.py | 0 .../tests/test_elevation_mapping.py | 85 ++++++ .../tests/test_semantic_map.py | 45 +++ 10 files changed, 787 insertions(+), 33 deletions(-) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/tests/__init__.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index c25e0ec2..24e29141 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -81,7 +81,7 @@ publishers: basic_layers: ['elevation', 'traversability'] fps: 2.0 elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound'] + layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb'] basic_layers: ['min_filter'] fps: 3.0 diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index b39e5743..c982e052 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -4,6 +4,7 @@ subscribers: # fusion: ['average','average'] # topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: - channels: ['feat_0','feat_1'] - fusion: ['average','average'] + channels: ['rgb','feat_0','feat_1'] + fusion: ['color','average','average'] topic_name: '/elvation_mapping/pointcloud_semantic' + diff --git a/elevation_mapping_cupy/rviz/lonomy_single.rviz b/elevation_mapping_cupy/rviz/lonomy_single.rviz index 8f890eb7..da12d689 100644 --- a/elevation_mapping_cupy/rviz/lonomy_single.rviz +++ b/elevation_mapping_cupy/rviz/lonomy_single.rviz @@ -4,10 +4,9 @@ Panels: Name: Displays Property Tree Widget: Expanded: - - /ElevationMapFilter1 - /Image1 Splitter Ratio: 0.5768463015556335 - Tree Height: 410 + Tree Height: 428 - Class: rviz/Selection Name: Selection - Class: rviz/Tool Properties @@ -55,10 +54,10 @@ Visualization Manager: Autocompute Intensity Bounds: true Class: grid_map_rviz_plugin/GridMap Color: 200; 200; 200 - Color Layer: smooth - Color Transformer: IntensityLayer + Color Layer: rgb + Color Transformer: ColorLayer Enabled: true - Height Layer: min_filter + Height Layer: smooth Height Transformer: GridMapLayer History Length: 1 Invert Rainbow: false @@ -221,7 +220,7 @@ Visualization Manager: Size (Pixels): 3 Size (m): 0.009999999776482582 Style: Flat Squares - Topic: /elvation_mapping/pointcloud_semantic_left + Topic: /elvation_mapping/pointcloud_semantic Unreliable: false Use Fixed Frame: true Use rainbow: true @@ -433,7 +432,7 @@ Visualization Manager: Views: Current: Class: rviz/Orbit - Distance: 8.01580810546875 + Distance: 7.847433090209961 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 @@ -449,19 +448,19 @@ Visualization Manager: Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.34979793429374695 + Pitch: 0.12979847192764282 Target Frame: base_footprint - Yaw: 5.212028980255127 + Yaw: 0.9738447666168213 Saved: ~ Window Geometry: Displays: collapsed: false - Height: 1016 + Height: 1043 Hide Left Dock: false Hide Right Dock: true Image: collapsed: false - QMainWindow State: 000000ff00000000fd0000000400000000000001f50000039efc0200000009fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000261000000c900fffffffb0000000a0049006d00610067006501000002a4000001370000001600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000073800000131fc0100000003fb0000000a0049006d0061006700650000000394000003a40000005e00fffffffb0000000800540069006d00650000000000000007380000041800fffffffb0000000800540069006d006501000000000000045000000000000000000000053d0000039e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd0000000400000000000001f5000003b9fc0200000009fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000273000000c900fffffffb0000000a0049006d00610067006501000002b6000001400000001600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000073800000131fc0100000003fb0000000a0049006d0061006700650000000394000003a40000005e00fffffffb0000000800540069006d00650000000000000007380000041800fffffffb0000000800540069006d0065010000000000000450000000000000000000000585000003b900000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -470,6 +469,6 @@ Window Geometry: collapsed: false Views: collapsed: true - Width: 1848 - X: 1992 - Y: 27 + Width: 1920 + X: 0 + Y: 0 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py index 382e4174..57e592ef 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py @@ -143,8 +143,8 @@ def add_points_kernel( ): add_points_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U center_x, raw U center_y, raw U R, raw U t, raw U norm_map", - out_params="raw U map, raw T newmap", + in_params="raw U center_x, raw U center_y, raw U R, raw U t, raw U norm_map", + out_params="raw U p, raw U map, raw T newmap", preamble=map_utils( resolution, width, @@ -165,8 +165,8 @@ def add_points_kernel( U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); U v = z_noise(rz); + int idx = get_idx(x, y, center_x[0], center_y[0]); if (is_valid(x, y, z, t[0], t[1], t[2])) { - int idx = get_idx(x, y, center_x[0], center_y[0]); if (is_inside(idx)) { U map_h = map[get_map_idx(idx, 0)]; U map_v = map[get_map_idx(idx, 1)]; @@ -258,6 +258,9 @@ def add_points_kernel( } } } + p[i * 3]= idx; + p[i * 3 + 1] = is_valid(x, y, z, t[0], t[1], t[2]); + p[i * 3 + 2] = is_inside(idx); """ ).substitute( mahalanobis_thresh=mahalanobis_thresh, @@ -653,6 +656,263 @@ def polygon_mask_kernel(width, height, resolution): return polygon_mask_kernel +def sum_kernel( + resolution, + width, + height, + + ): + # input the list of layers, amount of channels can slo be input through kernel + sum_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U center_x, raw U center_y, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map, raw T newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution,width=width, height=height), + operation=string.Template( + """ + U idx = p[i * pcl_channels[0]]; + U valid = p[i * pcl_channels[0] + 1]; + U inside = p[i * pcl_channels[0] + 2]; + //U x = transform_p(rx, ry, rz, R[0], R[1], R[2], t[0]); + //U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); + //U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); + // U v = z_noise(rz); + //if (valid) { + // int idx = get_idx(x, y, center_x[0], center_y[0]); + U map_h = map[get_map_idx(idx, 0)]; + if (inside) { + for ( int it=0;it 0) { + //U sem_cnt = newmap[get_map_idx(i, 7)]; + //for ( int it=0;it<${amount_features};it++){ + // U orig_f=map[get_map_idx(i, 7+${rgb}+it)]; + // U new_f=newmap[get_map_idx(i, 7+${rgb}+it)]; + // if (orig_f==0){ + // map[get_map_idx(i, 7+${rgb}+it)]=new_f/sem_cnt; + // } + // else{ + // map[get_map_idx(i, 7+${rgb}+it)]=orig_f*0.5+new_f/sem_cnt*0.5; + // } + //} + // int stored_it = 0; + // U highest_probability = 0; + // for ( int it=0;it<${amount_class_prob};it++){ + // U orig_p=map[get_map_idx(i, 7+${rgb}+${amount_features}+it)]; + // U new_p=newmap[get_map_idx(i, 7+${rgb}+${amount_features}+it)]; + // U probability =0; + // if (orig_p==0){ + // probability = new_p/sem_cnt; + // map[get_map_idx(i, 7+${rgb}+${amount_features}+it)]=probability; + // } + // else{ + // probability = orig_p*0.5+new_p/sem_cnt*0.5; + // map[get_map_idx(i, 7+${rgb}+${amount_features}+it)]=probability; + // } + // if(probability>= highest_probability){ + // stored_it = it; + // highest_probability = probability; + // } + // } + // if (${sem_class}){ + // // check max classs prob + // map[get_map_idx(i, 7+${rgb}+${amount_features}+${amount_class_prob})] = stored_it; + // } + } + + """ + ).substitute( + max_variance=max_variance, + initial_variance=initial_variance, + pcl_channels=pcl_channels, + amount_features=amount_features, + amount_class_prob=amount_class_prob, + sem_class=int(sem_class), + rgb=int(rgb), + ), + name="average_map_kernel", + ) + return average_kernel + + +def add_color_kernel( + width, + height, +): + add_color_kernel = cp.ElementwiseKernel( + in_params="raw T p, raw U center_x, raw U center_y, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map, raw V color_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ unsigned int get_color(unsigned int color){ + unsigned int red = 0xFF0000; + unsigned int green = 0xFF00; + unsigned int blue = 0xFF; + unsigned int reds = (color & red) >> 16; + unsigned int greens = (color & green) >> 8; + unsigned int blues = ( color & blue); + unsigned int rgbValue = (reds<<16 ) + (greens << 8) + blues; + // TODO: at the moment it seems to be working, but if we want + //to average over all points we need to use the color layer + //color_out[get_map_idx(idx, 1)] = color; + //[get_map_idx(idx, 2)] = color; + return rgbValue; + } + __device__ unsigned int get_r(unsigned int color){ + unsigned int red = 0xFF0000; + unsigned int reds = (color & red) >> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = ( color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U idx = p[i * pcl_channels[0]]; + U valid = p[i * pcl_channels[0] + 1]; + U inside = p[i * pcl_channels[0] + 2]; + if (true){ + for ( int it=0;it> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = ( color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + unsigned int cnt = color_map[get_map_idx(i, pcl_channels[1]*3)]; + if (cnt>0){ + for ( int it=0;it=0){ + // unsigned int prev_r = get_r(prev_color); + // unsigned int prev_g = get_g(prev_color); + // unsigned int prev_b = get_b(prev_color); + // unsigned int r = prev_r/2 + color_map[get_map_idx(i, it*3)]/(2*cnt); + // unsigned int g = prev_g/2 + color_map[get_map_idx(i, it*3+1)]/(2*cnt); + // unsigned int b = prev_b/2 + color_map[get_map_idx(i, it*3+2)]/(2*cnt); + //} + //unsigned int rgb = (r<<16) + (g << 8) + b; + // map[get_map_idx(i, map_lay[it])] = __uint_as_float(rgb); + } + } + """ + ).substitute( + ), + name="color_average_kernel", + ) + return color_average_kernel + if __name__ == "__main__": for i in range(10): import random diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 4a50e069..d03d3995 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -3,13 +3,16 @@ # Licensed under the MIT license. See LICENSE file in the project root for details. # import os +from typing import List, Any, Tuple, Union + import numpy as np import threading import subprocess from .traversability_filter import get_filter_chainer, get_filter_torch from .parameter import Parameter -from .custom_kernels import add_points_kernel +from .custom_kernels import add_points_kernel, add_color_kernel, color_average_kernel +from .custom_kernels import sum_kernel from .custom_kernels import error_counting_kernel from .custom_kernels import average_map_kernel from .custom_kernels import dilation_filter_kernel @@ -17,6 +20,7 @@ from .custom_kernels import polygon_mask_kernel from .map_initializer import MapInitializer from .plugins.plugin_manager import PluginManager +from .semantic_map import SemanticMap from .traversability_polygon import ( get_masked_traversability, @@ -33,22 +37,31 @@ cp.cuda.set_allocator(pool.malloc) -class ElevationMap(object): +class ElevationMap: """ Core elevation mapping class. """ def __init__(self, param: Parameter): + """ + + Args: + param (elevation_mapping_cupy.parameter.Parameter): + """ self.param = param self.resolution = param.resolution self.center = xp.array([0, 0, 0], dtype=float) self.map_length = param.map_length # +2 is a border for outside map + # TODO self.cell_n = int(round(self.map_length / self.resolution)) + 2 + self.param.cell_n = self.cell_n self.map_lock = threading.Lock() self.additional_layers = dict(zip(self.param.additional_layers, self.param.fusion_algorithms)) + # self.amount_additional_layers = len(self.param.additional_layers) + self.semantic_map = SemanticMap(self.param, self.additional_layers) # layers: elevation, variance, is_valid, traversability, time, upper_bound, is_upper_bound self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n)) self.layer_names = [ @@ -60,6 +73,13 @@ def __init__(self, param: Parameter): "upper_bound", "is_upper_bound", ] + # self.layer_names.extend(list(self.additional_layers.keys())) + + # self.unique_fusion = [] + # for x in list(self.additional_layers.values()): + # if x not in self.unique_fusion: + # self.unique_fusion.append(x) + # print("Fusion algorithms running: ",self.unique_fusion) # buffers self.traversability_buffer = xp.full((self.cell_n, self.cell_n), xp.nan) self.normal_map = xp.zeros((3, self.cell_n, self.cell_n)) @@ -79,6 +99,8 @@ def __init__(self, param: Parameter): self.additive_mean_error = 0.0 self.compile_kernels() + # self.compile_additional_kernels() + self.semantic_map.compile_kernels() weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') param.load_weights(weight_file) @@ -95,12 +117,79 @@ def __init__(self, param: Parameter): self.plugin_manager.load_plugin_settings(plugin_config_file) self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") + # self.color_map = None + # + # def compile_additional_kernels(self) -> None: + # """ + # Returns: + # None: + # + # """ + # if ("average" in self.unique_fusion): + # print("Initialize fusion kernel") + # self.sum_kernel = sum_kernel( + # self.resolution, + # self.cell_n, + # self.cell_n, + # self.param.sensor_noise_factor, + # self.param.min_valid_distance, + # self.param.max_height_range, + # self.param.ramped_height_range_a, + # self.param.ramped_height_range_b, + # self.param.ramped_height_range_c, + # + # ) + # + # if ("color" in self.unique_fusion): + # print("Initialize color kernel") + # self.add_color_kernel = add_color_kernel( + # self.cell_n, + # self.cell_n, + # ) + # self.color_average_kernel = color_average_kernel(self.cell_n,self.cell_n) + + # def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: + # """Get all fusion algorithms that need to be applied to a specific pointcloud + # + # Args: + # channels (List[str]): + # """ + # fusion_list = [] + # for channel in channels: + # x = self.additional_layers[channel] + # if x not in fusion_list: + # fusion_list.append(x) + # return fusion_list + # + # def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): + # """Computes the indices that are used for the additional kernel update of the pcl and the elmap. + # + # Args: + # pcl_channels (List[str]): + # fusion_alg (str): + # + # Returns: + # Union[Tuple[List[int], List[int]], Tuple[cupy._core.core.ndarray, cupy._core.core.ndarray]]: + # + # + # """ + # # this contains exactly the fusion alg type for each channel of the pcl + # pcl_val_list = [self.additional_layers[x] for x in pcl_channels] + # # this contains the indeces of the pointcloud where we have to perform a certain fusion + # pcl_indices = cp.array([idp+3 for idp, x in enumerate(pcl_val_list) if x == fusion_alg],dtype=np.int32) + # # create a list of indeces of the layers that will be updated by the pointcloud with specific fusion alg + # layer_indices = cp.array([], dtype=np.int32) + # for it, (key, val) in enumerate(self.additional_layers.items()): + # if key in pcl_channels and val == fusion_alg: + # layer_indices = cp.append(layer_indices,7+it ).astype(np.int32) + # return pcl_indices, layer_indices def clear(self): with self.map_lock: self.elevation_map *= 0.0 # Initial variance self.elevation_map[1] += self.initial_variance + self.semantic_map.map *= 0.0 self.mean_error = 0.0 self.additive_mean_error = 0.0 @@ -130,6 +219,14 @@ def move_to(self, position, R): self.shift_map_z(-delta[2]) def pad_value(self, x, shift_value, idx=None, value=0.0): + """Create a padding of the map along x,y axis according to amount that has shifted. + + Args: + x (cupy._core.core.ndarray): + shift_value (cupy._core.core.ndarray): + idx (Union[None, int, None, None]): + value (float): + """ if idx is None: if shift_value[0] > 0: x[:, : shift_value[0], :] = value @@ -158,6 +255,9 @@ def shift_map_xy(self, delta_pixel): self.pad_value(self.elevation_map, shift_value, value=0.0) self.pad_value(self.elevation_map, shift_value, idx=1, value=self.initial_variance) + self.semantic_map.map = cp.roll(self.semantic_map.map, shift_value, axis=(1, 2)) + self.pad_value(self.semantic_map.map, shift_value, value=0.0) + def shift_map_z(self, delta_z): with self.map_lock: # elevation @@ -167,7 +267,7 @@ def shift_map_z(self, delta_z): def compile_kernels(self): # Compile custom cuda kernels. - self.new_map = cp.zeros((7, self.cell_n, self.cell_n)) + self.new_map = cp.zeros((self.elevation_map.shape[0], self.cell_n, self.cell_n)) self.traversability_input = cp.zeros((self.cell_n, self.cell_n)) self.traversability_mask_dummy = cp.zeros((self.cell_n, self.cell_n)) self.min_filtered = cp.zeros((self.cell_n, self.cell_n)) @@ -220,10 +320,12 @@ def compile_kernels(self): def shift_translation_to_map_center(self, t): t -= self.center - def update_map_with_kernel(self, points, R, t, position_noise, orientation_noise): + def update_map_with_kernel(self, points_all, channels, R, t, position_noise, orientation_noise): self.new_map *= 0.0 error = cp.array([0.0], dtype=cp.float32) error_cnt = cp.array([0], dtype=cp.float32) + points = points_all[:,:3] + # additional_fusion = self.get_fusion_of_pcl(channels) with self.map_lock: self.shift_translation_to_map_center(t) self.error_counting_kernel( @@ -251,21 +353,23 @@ def update_map_with_kernel(self, points, R, t, position_noise, orientation_noise if np.abs(self.mean_error) < self.param.max_drift: self.elevation_map[0] += self.mean_error * self.param.drift_compensation_alpha self.add_points_kernel( - points, cp.array([0.0]), cp.array([0.0]), R, t, self.normal_map, + points, self.elevation_map, self.new_map, size=(points.shape[0]), ) self.average_map_kernel(self.new_map, self.elevation_map, size=(self.cell_n * self.cell_n)) + # self.update_additional_layers(additional_fusion, points_all, channels, R, t) + self.semantic_map.update_layers(points_all, channels, R, t) + if self.param.enable_overlap_clearance: self.clear_overlap_map(t) - # dilation before traversability_filter self.traversability_input *= 0.0 self.dilation_filter_kernel( @@ -284,6 +388,50 @@ def update_map_with_kernel(self, points, R, t, position_noise, orientation_noise # calculate normal vectors self.update_normal(self.traversability_input) + # def update_additional_layers(self, additional_fusion, points_all,channels,R,t): + # if "average" in additional_fusion: + # pcl_ids, layer_ids = self.get_indices_fusion(channels, "average") + # self.sum_kernel( + # points_all, + # cp.array([0.0]), + # cp.array([0.0]), + # R, + # t, + # self.normal_map, + # pcl_ids, + # layer_ids, + # cp.array([points_all.shape[1],pcl_ids.shape[0]],dtype=np.int32), + # self.elevation_map, + # self.new_map, + # size=(points_all.shape[0]), + # ) + # if "color" in additional_fusion: + # pcl_ids, layer_ids = self.get_indices_fusion(channels, "color") + # if self.color_map is None: + # self.color_map = cp.zeros((1+3*layer_ids.shape[0], self.cell_n, self.cell_n), dtype=np.uint32) + # points_all = cp.asarray(cp.float32(points_all.get())) + # self.add_color_kernel( + # points_all, + # cp.array([0.0]), + # cp.array([0.0]), + # R, + # t, + # self.normal_map, + # pcl_ids, + # layer_ids, + # cp.array([points_all.shape[1],pcl_ids.shape[0]],dtype=np.int32), + # self.elevation_map, + # self.color_map, + # size=(points_all.shape[0]), + # ) + # self.color_average_kernel(self.color_map, + # pcl_ids, + # layer_ids, + # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + # self.elevation_map, + # size=(self.cell_n * self.cell_n), + # ) + def clear_overlap_map(self, t): # Clear overlapping area around center height_min = t[2] - self.param.overlap_clear_range_z @@ -312,11 +460,28 @@ def update_upper_bound_with_valid_elevation(self): self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) - def input(self, raw_points,channels, R, t, position_noise, orientation_noise): + def input(self, raw_points: cp._core.core.ndarray, channels: List[str], R: cp._core.core.ndarray, + t: cp._core.core.ndarray, + position_noise: int, + orientation_noise: int) -> None: + """Input the pointcloud and fuse the new measurements to update the elevation map. + + Args: + raw_points (cupy._core.core.ndarray): + channels (List[str]): + R (cupy._core.core.ndarray): + t (cupy._core.core.ndarray): + position_noise (int): + orientation_noise (int): + + Returns: + None: + """ # Update elevation map using point cloud input. raw_points = cp.asarray(raw_points) + additional_channels = channels[3:] raw_points = raw_points[~cp.isnan(raw_points).any(axis=1)] - self.update_map_with_kernel(raw_points[:,:3], cp.asarray(R), cp.asarray(t), position_noise, orientation_noise) + self.update_map_with_kernel(raw_points, additional_channels, cp.asarray(R), cp.asarray(t), position_noise, orientation_noise) def update_normal(self, dilated_map): with self.map_lock: @@ -390,11 +555,24 @@ def copy_to_cpu(self, array, data, stream=None): def exists_layer(self, name): if name in self.layer_names: return True + elif name in self.additional_layers: + return True elif name in self.plugin_manager.layer_names: return True else: return False + # def get_rgb(self): + # c = self.process_map_for_publish(self.elevation_map[7], fill_nan=False, add_z=False) + # c = xp.uint32(c.get()) + # c.dtype = np.float32 + # return c + # + # def get_semantic(self,name): + # idx = self.layer_names.index(name) + # c = self.process_map_for_publish(self.elevation_map[idx], fill_nan=False, add_z=False) + # return c + def get_map_with_name_ref(self, name, data): use_stream = True xp = cp @@ -418,6 +596,14 @@ def get_map_with_name_ref(self, name, data): m = self.normal_map.copy()[1, 1:-1, 1:-1] elif name == "normal_z": m = self.normal_map.copy()[2, 1:-1, 1:-1] + # elif name in self.additional_layers.keys(): + # if self.additional_layers[name] == "color": + # m = self.get_rgb() + # else: + # m = self.get_semantic() + + elif name in self.additional_layers.keys(): + m = self.semantic_map.get_map_with_name(name) elif name in self.plugin_manager.layer_names: self.plugin_manager.update_with_name(name, self.elevation_map, self.layer_names) m = self.plugin_manager.get_map_with_name(name) @@ -521,21 +707,26 @@ def initialize_map(self, points, method="cubic"): # $ python -m cProfile -o profile.stats elevation_mapping.py # $ snakeviz profile.stats xp.random.seed(123) - points = xp.random.rand(100000, 3) R = xp.random.rand(3, 3) t = xp.random.rand(3) print(R, t) param = Parameter( use_chainer=False, weight_file="../config/weights.dat", plugin_config_file="../config/plugin_config.yaml" ) + param.additional_layers =['feat_0','feat_1', 'rgb'] + param.fusion_algorithms = ['average','average','color'] elevation = ElevationMap(param) - layers = ["elevation", "variance", "traversability", "min_filter", "smooth", "inpaint"] + layers = ["elevation", "variance", "traversability", "min_filter", "smooth", "inpaint","rgb"] + points = xp.random.rand(100000, len(layers)) + + channels = ['x','y','z']+ param.additional_layers + print(channels) data = np.zeros((elevation.cell_n - 2, elevation.cell_n - 2), dtype=np.float32) - for i in range(500): - elevation.input(points, R, t, 0, 0) + for i in range(20): + elevation.input(points,channels, R, t, 0, 0) elevation.update_normal(elevation.elevation_map[0]) pos = np.array([i * 0.01, i * 0.02, i * 0.01]) - elevation.move_to(pos) + elevation.move_to(pos,R) for layer in layers: elevation.get_map_with_name_ref(layer, data) print(i) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index a00c3ddf..5a07f695 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -13,6 +13,7 @@ class Parameter(Serializable): resolution: float = 0.02 additional_layers: list = ['feat_0'].copy fusion_algorithms: list = ['average'].copy + cell_n: int = None map_length: float = 10.0 sensor_noise_factor: float = 0.05 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py new file mode 100644 index 00000000..916cf665 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -0,0 +1,172 @@ +from .parameter import Parameter +import cupy as cp +import numpy as np +from typing import List +from .custom_kernels import sum_kernel, add_color_kernel, color_average_kernel + +xp = cp + + +class SemanticMap: + def __init__(self, param: Parameter, layer_specs: dict): + """ + + Args: + param (elevation_mapping_cupy.parameter.Parameter): + layer_specs (Dict[str, str]): + """ + self.param = param + self.layer_specs = layer_specs + self.amount_additional_layers = len(self.param.additional_layers) + self.map = xp.zeros( + (self.amount_additional_layers, self.param.cell_n, self.param.cell_n) + ) + self.get_unique_fusion() + self.new_map = xp.zeros( + (self.amount_additional_layers, self.param.cell_n, self.param.cell_n) + ) + self.color_map = None + + def get_unique_fusion(self): + self.unique_fusion = [] + for x in list(self.layer_specs.values()): + if x not in self.unique_fusion: + self.unique_fusion.append(x) + print("Fusion algorithms running: ", self.unique_fusion) + + def compile_kernels(self) -> None: + """ + Returns: + None: + + """ + if "average" in self.unique_fusion: + print("Initialize fusion kernel") + self.sum_kernel = sum_kernel( + self.param.resolution, + self.param.cell_n, + self.param.cell_n, + ) + + if "color" in self.unique_fusion: + print("Initialize color kernel") + self.add_color_kernel = add_color_kernel( + self.param.cell_n, + self.param.cell_n, + ) + self.color_average_kernel = color_average_kernel( + self.param.cell_n, self.param.cell_n + ) + + def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: + """Get all fusion algorithms that need to be applied to a specific pointcloud + + Args: + channels (List[str]): + """ + fusion_list = [] + for channel in channels: + x = self.layer_specs[channel] + if x not in fusion_list: + fusion_list.append(x) + return fusion_list + + def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): + """Computes the indices that are used for the additional kernel update of the pcl and the elmap. + + Args: + pcl_channels (List[str]): + fusion_alg (str): + + Returns: + Union[Tuple[List[int], List[int]], Tuple[cupy._core.core.ndarray, cupy._core.core.ndarray]]: + + + """ + # this contains exactly the fusion alg type for each channel of the pcl + pcl_val_list = [self.layer_specs[x] for x in pcl_channels] + # this contains the indeces of the pointcloud where we have to perform a certain fusion + pcl_indices = cp.array( + [idp + 3 for idp, x in enumerate(pcl_val_list) if x == fusion_alg], + dtype=np.int32, + ) + # create a list of indeces of the layers that will be updated by the pointcloud with specific fusion alg + layer_indices = cp.array([], dtype=np.int32) + for it, (key, val) in enumerate(self.layer_specs.items()): + if key in pcl_channels and val == fusion_alg: + layer_indices = cp.append(layer_indices, it).astype(np.int32) + return pcl_indices, layer_indices + + def update_layers(self, points_all, channels, R, t): + additional_fusion = self.get_fusion_of_pcl(channels) + + self.new_map *= 0.0 + + if "average" in additional_fusion: + pcl_ids, layer_ids = self.get_indices_fusion(channels, "average") + self.sum_kernel( + points_all, + cp.array([0.0]), + cp.array([0.0]), + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + self.map, + self.new_map, + size=(points_all.shape[0]), + ) + if "color" in additional_fusion: + pcl_ids, layer_ids = self.get_indices_fusion(channels, "color") + if self.color_map is None: + self.color_map = cp.zeros( + (1 + 3 * layer_ids.shape[0], self.param.cell_n, self.param.cell_n), + dtype=np.uint32, + ) + points_all = cp.asarray(cp.float32(points_all.get())) + self.add_color_kernel( + points_all, + cp.array([0.0]), + cp.array([0.0]), + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + self.map, + self.color_map, + size=(points_all.shape[0]), + ) + self.color_average_kernel( + self.color_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + self.map, + size=(self.param.cell_n * self.param.cell_n), + ) + + def get_map_with_name(self, name): + if self.layer_specs[name] == "color": + m = self.get_rgb(name) + return m + else: + m = self.get_semantic(name) + return m + + def get_rgb(self, name): + idx = self.param.additional_layers.index(name) + c = self.process_map_for_publish(self.map[idx]) + c = xp.uint32(c.get()) + c.dtype = np.float32 + return c + + def get_semantic(self, name): + idx = self.param.additional_layers.index(name) + c = self.process_map_for_publish(self.map[idx]) + return c + + def process_map_for_publish(self, input_map): + m = input_map.copy() + return m[1:-1, 1:-1] diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/__init__.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py new file mode 100644 index 00000000..ee73e103 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -0,0 +1,85 @@ +import pytest +from elevation_mapping_cupy import parameter, elevation_mapping +import cupy as cp +import numpy as np + + +@pytest.fixture() +def elmap_ex(add_lay, fusion_alg): + additional_layer = add_lay + fusion_algorithms = fusion_alg + p = parameter.Parameter( + use_chainer=False, + weight_file="../../../config/weights.dat", + plugin_config_file="../../../config/plugin_config.yaml", + ) + p.additional_layers = additional_layer + p.fusion_algorithms = fusion_algorithms + e = elevation_mapping.ElevationMap(p) + return e + + +@pytest.mark.parametrize( + "add_lay,fusion_alg", + [ + (["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), + (["feat_0", "feat_1"], ["average", "average"]), + ], +) +class TestElevationMap: + def test_elmap_init(self, elmap_ex): + assert len(elmap_ex.layer_names) == elmap_ex.elevation_map.shape[0] + assert elmap_ex.color_map is None + + def test_elmap_input(self, elmap_ex): + channels = ["x", "y", "z"] + elmap_ex.param.additional_layers + points = cp.random.rand(100000, len(channels)) + R = cp.random.rand(3, 3) + t = cp.random.rand(3) + elmap_ex.input(points, channels, R, t, 0, 0) + + def test_elmap_update_normal(self, elmap_ex): + elmap_ex.update_normal(elmap_ex.elevation_map[0]) + + def test_elmap_move_to(self, elmap_ex): + for i in range(20): + pos = np.array([i * 0.01, i * 0.02, i * 0.01]) + R = cp.random.rand(3, 3) + elmap_ex.move_to(pos, R) + + def test_get_map(self, elmap_ex): + layers = [ + "elevation", + "variance", + "traversability", + "min_filter", + "smooth", + "inpaint", + "rgb", + ] + data = np.zeros((elmap_ex.cell_n - 2, elmap_ex.cell_n - 2), dtype=cp.float32) + for layer in layers: + elmap_ex.get_map_with_name_ref(layer, data) + +# @pytest.mark.parametrize( +# "add_lay, fusion_alg,channels", +# [(["feat_0", "feat_1"], ["average", "average"],["feat_0"]), +# (["feat_0", "feat_1"], ["average", "average"],[]), +# (["feat_0", "feat_1", "rgb"], ["average", "average", "color"],["rgb", "feat_0"]), +# ], +# ) +# def test_fusion_of_pcl(elmap_ex, channels): +# fusion = elmap_ex.get_fusion_of_pcl(channels=channels) +# assert len(fusion) <= len(channels) +# assert len(fusion)>0 or len(channels)==0 +# assert all(isinstance(item, str) for item in fusion) +# +# +# @pytest.mark.parametrize( +# "add_lay, fusion_alg", +# [(["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), +# ], +# ) +# @pytest.mark.parametrize("channels", [["rgb"], ["rgb", "feat_0"], []]) +# def test_indices_fusion(elmap_ex, channels,fusion_alg): +# pcl_indices, layer_indices = elmap_ex.get_indices_fusion(pcl_channels=channels,fusion_alg=fusion_alg[0]) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py new file mode 100644 index 00000000..a083a477 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py @@ -0,0 +1,45 @@ +import pytest +from elevation_mapping_cupy import semantic_map, parameter +import cupy as cp +import numpy as np + + +@pytest.fixture() +def semmap_ex(add_lay, fusion_alg): + additional_layer = add_lay + fusion_algorithms = fusion_alg + p = parameter.Parameter( + use_chainer=False, + weight_file="../../../config/weights.dat", + plugin_config_file="../../../config/plugin_config.yaml", + ) + p.additional_layers = additional_layer + p.fusion_algorithms = fusion_algorithms + additional_layers = dict(zip(p.additional_layers, p.fusion_algorithms)) + p.cell_n = int(round(p.map_length / p.resolution)) + 2 + + e = semantic_map.SemanticMap(p,additional_layers) + return e + +@pytest.mark.parametrize( + "add_lay, fusion_alg,channels", + [(["feat_0", "feat_1"], ["average", "average"],["feat_0"]), + (["feat_0", "feat_1"], ["average", "average"],[]), + (["feat_0", "feat_1", "rgb"], ["average", "average", "color"],["rgb", "feat_0"]), + ], +) +def test_fusion_of_pcl(semmap_ex, channels): + fusion = semmap_ex.get_fusion_of_pcl(channels=channels) + assert len(fusion) <= len(channels) + assert len(fusion)>0 or len(channels)==0 + assert all(isinstance(item, str) for item in fusion) + + +@pytest.mark.parametrize( + "add_lay, fusion_alg", + [(["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), + ], +) +@pytest.mark.parametrize("channels", [["rgb"], ["rgb", "feat_0"], []]) +def test_indices_fusion(semmap_ex, channels,fusion_alg): + pcl_indices, layer_indices = semmap_ex.get_indices_fusion(pcl_channels=channels,fusion_alg=fusion_alg[0]) From c70cbed8371a14367c5bbdf7b0b742cf112a80da Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Thu, 27 Oct 2022 11:55:40 +0200 Subject: [PATCH 239/504] fixed polygon checker, added comments to all the functions that are being tested and added tests --- .../config/sensor_parameter.yaml | 4 +- .../elevation_mapping_cupy/custom_kernels.py | 193 +++++------- .../elevation_mapping.py | 276 ++++++++---------- .../elevation_mapping_cupy/map_initializer.py | 12 +- .../elevation_mapping_cupy/parameter.py | 3 + .../plugins/plugin_manager.py | 18 +- .../elevation_mapping_cupy/semantic_map.py | 71 ++++- .../tests/test_elevation_mapping.py | 60 ++-- .../src/elevation_mapping_wrapper.cpp | 2 + 9 files changed, 328 insertions(+), 311 deletions(-) diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index c982e052..8c8c596b 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -4,7 +4,7 @@ subscribers: # fusion: ['average','average'] # topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: - channels: ['rgb','feat_0','feat_1'] - fusion: ['color','average','average'] + channels: ['rgb','feat_0','feat_1','c_prob_0'] + fusion: ['color','average','average','class_average'] topic_name: '/elvation_mapping/pointcloud_semantic' diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py index 57e592ef..f96b45f2 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py @@ -655,16 +655,16 @@ def polygon_mask_kernel(width, height, resolution): ) return polygon_mask_kernel +##################### additional kernels ################################# def sum_kernel( resolution, width, height, - ): # input the list of layers, amount of channels can slo be input through kernel sum_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U center_x, raw U center_y, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", out_params="raw U map, raw T newmap", preamble=string.Template( """ @@ -679,24 +679,16 @@ def sum_kernel( U idx = p[i * pcl_channels[0]]; U valid = p[i * pcl_channels[0] + 1]; U inside = p[i * pcl_channels[0] + 2]; - //U x = transform_p(rx, ry, rz, R[0], R[1], R[2], t[0]); - //U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); - //U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); - // U v = z_noise(rz); - //if (valid) { - // int idx = get_idx(x, y, center_x[0], center_y[0]); - U map_h = map[get_map_idx(idx, 0)]; + if (valid) { if (inside) { for ( int it=0;it 0) { - //U sem_cnt = newmap[get_map_idx(i, 7)]; - //for ( int it=0;it<${amount_features};it++){ - // U orig_f=map[get_map_idx(i, 7+${rgb}+it)]; - // U new_f=newmap[get_map_idx(i, 7+${rgb}+it)]; - // if (orig_f==0){ - // map[get_map_idx(i, 7+${rgb}+it)]=new_f/sem_cnt; - // } - // else{ - // map[get_map_idx(i, 7+${rgb}+it)]=orig_f*0.5+new_f/sem_cnt*0.5; - // } - //} - // int stored_it = 0; - // U highest_probability = 0; - // for ( int it=0;it<${amount_class_prob};it++){ - // U orig_p=map[get_map_idx(i, 7+${rgb}+${amount_features}+it)]; - // U new_p=newmap[get_map_idx(i, 7+${rgb}+${amount_features}+it)]; - // U probability =0; - // if (orig_p==0){ - // probability = new_p/sem_cnt; - // map[get_map_idx(i, 7+${rgb}+${amount_features}+it)]=probability; - // } - // else{ - // probability = orig_p*0.5+new_p/sem_cnt*0.5; - // map[get_map_idx(i, 7+${rgb}+${amount_features}+it)]=probability; - // } - // if(probability>= highest_probability){ - // stored_it = it; - // highest_probability = probability; - // } - // } - // if (${sem_class}){ - // // check max classs prob - // map[get_map_idx(i, 7+${rgb}+${amount_features}+${amount_class_prob})] = stored_it; - // } + U cnt = new_elmap[get_map_idx(i, 2)]; + if (cnt>0){ + for ( int it=0;it0){ + for ( int it=0;it> 16; - unsigned int greens = (color & green) >> 8; - unsigned int blues = ( color & blue); - unsigned int rgbValue = (reds<<16 ) + (greens << 8) + blues; - // TODO: at the moment it seems to be working, but if we want - //to average over all points we need to use the color layer - //color_out[get_map_idx(idx, 1)] = color; - //[get_map_idx(idx, 2)] = color; - return rgbValue; - } __device__ unsigned int get_r(unsigned int color){ - unsigned int red = 0xFF0000; - unsigned int reds = (color & red) >> 16; - return reds; + unsigned int red = 0xFF0000; + unsigned int reds = (color & red) >> 16; + return reds; } __device__ unsigned int get_g(unsigned int color){ - unsigned int green = 0xFF00; - unsigned int greens = (color & green) >> 8; - return greens; + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; } __device__ unsigned int get_b(unsigned int color){ - unsigned int blue = 0xFF; - unsigned int blues = ( color & blue); - return blues; + unsigned int blue = 0xFF; + unsigned int blues = ( color & blue); + return blues; } """ ).substitute(width=width, height=height), @@ -834,17 +799,13 @@ def add_color_kernel( U idx = p[i * pcl_channels[0]]; U valid = p[i * pcl_channels[0] + 1]; U inside = p[i * pcl_channels[0] + 2]; - if (true){ + if (valid && inside){ for ( int it=0;it> 16; - return reds; + unsigned int red = 0xFF0000; + unsigned int reds = (color & red) >> 16; + return reds; } __device__ unsigned int get_g(unsigned int color){ - unsigned int green = 0xFF00; - unsigned int greens = (color & green) >> 8; - return greens; + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; } __device__ unsigned int get_b(unsigned int color){ - unsigned int blue = 0xFF; - unsigned int blues = ( color & blue); - return blues; + unsigned int blue = 0xFF; + unsigned int blues = (color & blue); + return blues; } """ ).substitute(width=width, height=height), @@ -902,8 +863,8 @@ def color_average_kernel( // unsigned int g = prev_g/2 + color_map[get_map_idx(i, it*3+1)]/(2*cnt); // unsigned int b = prev_b/2 + color_map[get_map_idx(i, it*3+2)]/(2*cnt); //} - //unsigned int rgb = (r<<16) + (g << 8) + b; - // map[get_map_idx(i, map_lay[it])] = __uint_as_float(rgb); + unsigned int rgb = (r<<16) + (g << 8) + b; + map[get_map_idx(i, map_lay[it])] = rgb; } } """ @@ -913,6 +874,8 @@ def color_average_kernel( ) return color_average_kernel +# TODO: in future add more kernels e.g. bayesian kernel + if __name__ == "__main__": for i in range(10): import random diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index d03d3995..bc107d4c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -53,16 +53,11 @@ def __init__(self, param: Parameter): self.resolution = param.resolution self.center = xp.array([0, 0, 0], dtype=float) self.map_length = param.map_length - # +2 is a border for outside map - # TODO - self.cell_n = int(round(self.map_length / self.resolution)) + 2 - self.param.cell_n = self.cell_n + self.cell_n = param.cell_n self.map_lock = threading.Lock() self.additional_layers = dict(zip(self.param.additional_layers, self.param.fusion_algorithms)) - # self.amount_additional_layers = len(self.param.additional_layers) self.semantic_map = SemanticMap(self.param, self.additional_layers) - # layers: elevation, variance, is_valid, traversability, time, upper_bound, is_upper_bound self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n)) self.layer_names = [ "elevation", @@ -73,13 +68,7 @@ def __init__(self, param: Parameter): "upper_bound", "is_upper_bound", ] - # self.layer_names.extend(list(self.additional_layers.keys())) - # self.unique_fusion = [] - # for x in list(self.additional_layers.values()): - # if x not in self.unique_fusion: - # self.unique_fusion.append(x) - # print("Fusion algorithms running: ",self.unique_fusion) # buffers self.traversability_buffer = xp.full((self.cell_n, self.cell_n), xp.nan) self.normal_map = xp.zeros((3, self.cell_n, self.cell_n)) @@ -99,7 +88,6 @@ def __init__(self, param: Parameter): self.additive_mean_error = 0.0 self.compile_kernels() - # self.compile_additional_kernels() self.semantic_map.compile_kernels() weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') @@ -117,74 +105,11 @@ def __init__(self, param: Parameter): self.plugin_manager.load_plugin_settings(plugin_config_file) self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") - # self.color_map = None - # - # def compile_additional_kernels(self) -> None: - # """ - # Returns: - # None: - # - # """ - # if ("average" in self.unique_fusion): - # print("Initialize fusion kernel") - # self.sum_kernel = sum_kernel( - # self.resolution, - # self.cell_n, - # self.cell_n, - # self.param.sensor_noise_factor, - # self.param.min_valid_distance, - # self.param.max_height_range, - # self.param.ramped_height_range_a, - # self.param.ramped_height_range_b, - # self.param.ramped_height_range_c, - # - # ) - # - # if ("color" in self.unique_fusion): - # print("Initialize color kernel") - # self.add_color_kernel = add_color_kernel( - # self.cell_n, - # self.cell_n, - # ) - # self.color_average_kernel = color_average_kernel(self.cell_n,self.cell_n) - - # def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: - # """Get all fusion algorithms that need to be applied to a specific pointcloud - # - # Args: - # channels (List[str]): - # """ - # fusion_list = [] - # for channel in channels: - # x = self.additional_layers[channel] - # if x not in fusion_list: - # fusion_list.append(x) - # return fusion_list - # - # def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): - # """Computes the indices that are used for the additional kernel update of the pcl and the elmap. - # - # Args: - # pcl_channels (List[str]): - # fusion_alg (str): - # - # Returns: - # Union[Tuple[List[int], List[int]], Tuple[cupy._core.core.ndarray, cupy._core.core.ndarray]]: - # - # - # """ - # # this contains exactly the fusion alg type for each channel of the pcl - # pcl_val_list = [self.additional_layers[x] for x in pcl_channels] - # # this contains the indeces of the pointcloud where we have to perform a certain fusion - # pcl_indices = cp.array([idp+3 for idp, x in enumerate(pcl_val_list) if x == fusion_alg],dtype=np.int32) - # # create a list of indeces of the layers that will be updated by the pointcloud with specific fusion alg - # layer_indices = cp.array([], dtype=np.int32) - # for it, (key, val) in enumerate(self.additional_layers.items()): - # if key in pcl_channels and val == fusion_alg: - # layer_indices = cp.append(layer_indices,7+it ).astype(np.int32) - # return pcl_indices, layer_indices def clear(self): + """Reset all the layers of the elevation & the semantic map. + + """ with self.map_lock: self.elevation_map *= 0.0 # Initial variance @@ -194,9 +119,20 @@ def clear(self): self.additive_mean_error = 0.0 def get_position(self, position): + """Return the position of the map center. + + Args: + position (numpy.ndarray): + + """ position[0][:] = xp.asnumpy(self.center) def move(self, delta_position): + """Shift the map along all three axes according to the input. + + Args: + delta_position (numpy.ndarray): + """ # Shift map using delta position. delta_position = xp.asarray(delta_position) delta_pixel = xp.round(delta_position[:2] / self.resolution) @@ -207,6 +143,12 @@ def move(self, delta_position): self.shift_map_z(-delta_position[2]) def move_to(self, position, R): + """ Shift the map to an absolute position and update the rotation of the robot. + + Args: + position (numpy.ndarray): + R (cupy._core.core.ndarray): + """ # Shift map to the center of robot. self.base_rotation = xp.asarray(R) position = xp.asarray(position) @@ -219,7 +161,7 @@ def move_to(self, position, R): self.shift_map_z(-delta[2]) def pad_value(self, x, shift_value, idx=None, value=0.0): - """Create a padding of the map along x,y axis according to amount that has shifted. + """Create a padding of the map along x,y-axis according to amount that has shifted. Args: x (cupy._core.core.ndarray): @@ -247,6 +189,12 @@ def pad_value(self, x, shift_value, idx=None, value=0.0): x[idx, :, shift_value[1] :] = value def shift_map_xy(self, delta_pixel): + """Shift the map along the horizontal axes according to the input. + + Args: + delta_pixel (cupy._core.core.ndarray): + + """ shift_value = delta_pixel.astype(cp.int) if cp.abs(shift_value).sum() == 0: return @@ -259,6 +207,11 @@ def shift_map_xy(self, delta_pixel): self.pad_value(self.semantic_map.map, shift_value, value=0.0) def shift_map_z(self, delta_z): + """Shift the relevant layers along the vertical axis. + + Args: + delta_z (cupy._core.core.ndarray): + """ with self.map_lock: # elevation self.elevation_map[0] += delta_z @@ -266,6 +219,9 @@ def shift_map_z(self, delta_z): self.elevation_map[5] += delta_z def compile_kernels(self): + """Compile all kernels belonging to the elevation map. + + """ # Compile custom cuda kernels. self.new_map = cp.zeros((self.elevation_map.shape[0], self.cell_n, self.cell_n)) self.traversability_input = cp.zeros((self.cell_n, self.cell_n)) @@ -318,9 +274,24 @@ def compile_kernels(self): self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) def shift_translation_to_map_center(self, t): + """ Deduct the map center to get the translation of a point w.r.t. the map center. + + Args: + t (cupy._core.core.ndarray): Absolute point position + """ t -= self.center def update_map_with_kernel(self, points_all, channels, R, t, position_noise, orientation_noise): + """Update map with new measurement. + + Args: + points_all (cupy._core.core.ndarray): + channels (List[str]): + R (cupy._core.core.ndarray): + t (cupy._core.core.ndarray): + position_noise (int): + orientation_noise (int): + """ self.new_map *= 0.0 error = cp.array([0.0], dtype=cp.float32) error_cnt = cp.array([0], dtype=cp.float32) @@ -366,7 +337,7 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori self.average_map_kernel(self.new_map, self.elevation_map, size=(self.cell_n * self.cell_n)) # self.update_additional_layers(additional_fusion, points_all, channels, R, t) - self.semantic_map.update_layers(points_all, channels, R, t) + self.semantic_map.update_layers(points_all, channels, R, t,self.new_map) if self.param.enable_overlap_clearance: self.clear_overlap_map(t) @@ -388,50 +359,6 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori # calculate normal vectors self.update_normal(self.traversability_input) - # def update_additional_layers(self, additional_fusion, points_all,channels,R,t): - # if "average" in additional_fusion: - # pcl_ids, layer_ids = self.get_indices_fusion(channels, "average") - # self.sum_kernel( - # points_all, - # cp.array([0.0]), - # cp.array([0.0]), - # R, - # t, - # self.normal_map, - # pcl_ids, - # layer_ids, - # cp.array([points_all.shape[1],pcl_ids.shape[0]],dtype=np.int32), - # self.elevation_map, - # self.new_map, - # size=(points_all.shape[0]), - # ) - # if "color" in additional_fusion: - # pcl_ids, layer_ids = self.get_indices_fusion(channels, "color") - # if self.color_map is None: - # self.color_map = cp.zeros((1+3*layer_ids.shape[0], self.cell_n, self.cell_n), dtype=np.uint32) - # points_all = cp.asarray(cp.float32(points_all.get())) - # self.add_color_kernel( - # points_all, - # cp.array([0.0]), - # cp.array([0.0]), - # R, - # t, - # self.normal_map, - # pcl_ids, - # layer_ids, - # cp.array([points_all.shape[1],pcl_ids.shape[0]],dtype=np.int32), - # self.elevation_map, - # self.color_map, - # size=(points_all.shape[0]), - # ) - # self.color_average_kernel(self.color_map, - # pcl_ids, - # layer_ids, - # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), - # self.elevation_map, - # size=(self.cell_n * self.cell_n), - # ) - def clear_overlap_map(self, t): # Clear overlapping area around center height_min = t[2] - self.param.overlap_clear_range_z @@ -484,6 +411,11 @@ def input(self, raw_points: cp._core.core.ndarray, channels: List[str], R: cp._c self.update_map_with_kernel(raw_points, additional_channels, cp.asarray(R), cp.asarray(t), position_noise, orientation_noise) def update_normal(self, dilated_map): + """ Clear the normal map and then apply the normal kernel with dilated map as input. + + Args: + dilated_map (cupy._core.core.ndarray): + """ with self.map_lock: self.normal_map *= 0.0 self.normal_filter_kernel( @@ -491,6 +423,17 @@ def update_normal(self, dilated_map): ) def process_map_for_publish(self, input_map, fill_nan=False, add_z=False, xp=cp): + """ Process the input_map according to the fill_nan and add_z flags. + + Args: + input_map (cupy._core.core.ndarray): + fill_nan (bool): + add_z (bool): + xp (module): + + Returns: + cupy._core.core.ndarray: + """ m = input_map.copy() if fill_nan: m = xp.where(self.elevation_map[2] > 0.5, m, xp.nan) @@ -538,12 +481,27 @@ def get_is_upper_bound(self): return is_upper_bound def xp_of_array(self, array): + """Indicate which library is used for xp. + + Args: + array (cupy._core.core.ndarray): + + Returns: + module: + """ if type(array) == cp.ndarray: return cp elif type(array) == np.ndarray: return np def copy_to_cpu(self, array, data, stream=None): + """ Transforms the data to float32 and if on gpu loads it to cpu. + + Args: + array (cupy._core.core.ndarray): + data (numpy.ndarray): + stream (Union[None, cupy.cuda.stream.Stream, None, None, None, None, None, None, None]): + """ if type(array) == np.ndarray: data[...] = array.astype(np.float32) elif type(array) == cp.ndarray: @@ -553,6 +511,14 @@ def copy_to_cpu(self, array, data, stream=None): data[...] = cp.asnumpy(array.astype(np.float32)) def exists_layer(self, name): + """ Check if the layer exists in elevation map or in the semantic map. + + Args: + name (str): + + Returns: + bool: + """ if name in self.layer_names: return True elif name in self.additional_layers: @@ -562,18 +528,14 @@ def exists_layer(self, name): else: return False - # def get_rgb(self): - # c = self.process_map_for_publish(self.elevation_map[7], fill_nan=False, add_z=False) - # c = xp.uint32(c.get()) - # c.dtype = np.float32 - # return c - # - # def get_semantic(self,name): - # idx = self.layer_names.index(name) - # c = self.process_map_for_publish(self.elevation_map[idx], fill_nan=False, add_z=False) - # return c - def get_map_with_name_ref(self, name, data): + """Load a layer according to the name input to the data input. + + Args: + name (str): Name of the layer. + data (numpy.ndarray): Data structure that contains layer. + + """ use_stream = True xp = cp with self.map_lock: @@ -596,12 +558,6 @@ def get_map_with_name_ref(self, name, data): m = self.normal_map.copy()[1, 1:-1, 1:-1] elif name == "normal_z": m = self.normal_map.copy()[2, 1:-1, 1:-1] - # elif name in self.additional_layers.keys(): - # if self.additional_layers[name] == "color": - # m = self.get_rgb() - # else: - # m = self.get_semantic() - elif name in self.additional_layers.keys(): m = self.semantic_map.get_map_with_name(name) elif name in self.plugin_manager.layer_names: @@ -640,8 +596,18 @@ def get_normal_ref(self, normal_x_data, normal_y_data, normal_z_data): normal_z_data[...] = xp.asnumpy(maps[2], stream=self.stream) def get_polygon_traversability(self, polygon, result): + """ Check if input polygons are traversable. + + Args: + polygon (cupy._core.core.ndarray): + result (numpy.ndarray): + + Returns: + Union[None, int]: + """ polygon = xp.asarray(polygon) area = calculate_area(polygon) + polygon = polygon.astype(np.float64) pmin = self.center[:2] - self.map_length / 2 + self.resolution pmax = self.center[:2] + self.map_length / 2 - self.resolution polygon[:, 0] = polygon[:, 0].clip(pmin[0], pmax[0]) @@ -649,7 +615,7 @@ def get_polygon_traversability(self, polygon, result): polygon_min = polygon.min(axis=0) polygon_max = polygon.max(axis=0) polygon_bbox = cp.concatenate([polygon_min, polygon_max]).flatten() - polygon_n = polygon.shape[0] + polygon_n = xp.array(polygon.shape[0], dtype=np.int16) clipped_area = calculate_area(polygon) self.polygon_mask_kernel( polygon, @@ -664,7 +630,7 @@ def get_polygon_traversability(self, polygon, result): if masked_isvalid.sum() > 0: t = masked.sum() / masked_isvalid.sum() else: - t = 0.0 + t = cp.asarray(0.0) is_safe, un_polygon = is_traversable( masked, self.param.safe_thresh, self.param.safe_min_thresh, self.param.max_unsafe_n ) @@ -675,14 +641,25 @@ def get_polygon_traversability(self, polygon, result): if clipped_area < 0.001: is_safe = False print("requested polygon is outside of the map") - result[...] = np.array([is_safe, t, area]) + result[...] = np.array([is_safe, t.get(), area.get()]) self.untraversable_polygon = un_polygon return untraversable_polygon_num def get_untraversable_polygon(self, untraversable_polygon): + """ Copy the untraversable polygons to input untraversable_polygons. + + Args: + untraversable_polygon (numpy.ndarray): + """ untraversable_polygon[...] = xp.asnumpy(self.untraversable_polygon) def initialize_map(self, points, method="cubic"): + """Initializes the map according to some points and using an approximation according to method. + + Args: + points (numpy.ndarray): + method (str): Interpolation method ['linear', 'cubic', 'nearest'] + """ self.clear() with self.map_lock: points = cp.asarray(points) @@ -713,8 +690,9 @@ def initialize_map(self, points, method="cubic"): param = Parameter( use_chainer=False, weight_file="../config/weights.dat", plugin_config_file="../config/plugin_config.yaml" ) - param.additional_layers =['feat_0','feat_1', 'rgb'] - param.fusion_algorithms = ['average','average','color'] + param.additional_layers =['feat_0','feat_1', 'rgb','people'] + param.fusion_algorithms = ['average','average','color','class_average'] + param.update() elevation = ElevationMap(param) layers = ["elevation", "variance", "traversability", "min_filter", "smooth", "inpaint","rgb"] points = xp.random.rand(100000, len(layers)) @@ -730,3 +708,7 @@ def initialize_map(self, points, method="cubic"): for layer in layers: elevation.get_map_with_name_ref(layer, data) print(i) + polygon = cp.array([[0, 0], [2, 0], [0, 2]], dtype=np.float64) + result = np.array([0, 0, 0]) + elevation.get_polygon_traversability(polygon, result) + print(result) \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/map_initializer.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/map_initializer.py index c80dc587..8d4ee945 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/map_initializer.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/map_initializer.py @@ -23,14 +23,14 @@ def __call__(self, *args, **kwargs): return def points_initializer(self, elevation_map, points, method="linear"): - """ - Initialize the map using interpolation between given poitns + """ Initialize the map using interpolation between given points + Args: - elevation_map: elevation_map data. - points: points used to interpolate. - method: method for interpolation. (nearest, linear, cubic) - """ + elevation_map (cupy._core.core.ndarray): elevation_map data. + points (cupy._core.core.ndarray): points used to interpolate. + method (str): method for interpolation. (nearest, linear, cubic) + """ # points from existing map. points_idx = self.xp.where(elevation_map[2] > 0.5) values = elevation_map[0, points_idx[0], points_idx[1]] diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 5a07f695..5b58620d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -92,6 +92,9 @@ def set_value(self, name, value): def get_value(self, name): return getattr(self, name) + def update(self): + # +2 is a border for outside map + self.cell_n = int(round(self.map_length / self.resolution)) + 2 if __name__ == "__main__": param = Parameter() diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index 719d45c9..064d267d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -26,9 +26,9 @@ class PluginBase(ABC): def __init__(self, *args, **kwargs): """ - Parameters - ---------- - plugin_params : PluginParams + + Args: + plugin_params : PluginParams The parameter of callback """ @@ -39,8 +39,15 @@ def __call__( plugin_layers: cp.ndarray, plugin_layer_names: List[str], ) -> cp.ndarray: - """ - This gets the elevation map data and plugin layers as a cupy array. + """This gets the elevation map data and plugin layers as a cupy array. + + + Args: + elevation_map (): + layer_names (): + plugin_layers (): + plugin_layer_names (): + Run your processing here and return the result. layer of elevation_map 0: elevation 1: variance @@ -50,6 +57,7 @@ def __call__( 5: upper_bound 6: is_upper_bound You can also access to the other plugins' layer with plugin_layers and plugin_layer_names + """ pass diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 916cf665..9715d2d8 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -2,7 +2,13 @@ import cupy as cp import numpy as np from typing import List -from .custom_kernels import sum_kernel, add_color_kernel, color_average_kernel +from .custom_kernels import ( + sum_kernel, + add_color_kernel, + color_average_kernel, + average_kernel, + class_average_kernel, +) xp = cp @@ -40,6 +46,11 @@ def compile_kernels(self) -> None: None: """ + # TODO: maybe this could be improved by creating functions for each single + # create a base class containing compile kernel as well as update and this then can be created for various + # then for each method this two functions canbe overloaded. and called through a list of all the algporithms + # that need to be called + # but I am not sure as we would need to pass a lot of arguments... check plugin if "average" in self.unique_fusion: print("Initialize fusion kernel") self.sum_kernel = sum_kernel( @@ -47,6 +58,10 @@ def compile_kernels(self) -> None: self.param.cell_n, self.param.cell_n, ) + self.average_kernel = average_kernel( + self.param.cell_n, + self.param.cell_n, + ) if "color" in self.unique_fusion: print("Initialize color kernel") @@ -57,6 +72,17 @@ def compile_kernels(self) -> None: self.color_average_kernel = color_average_kernel( self.param.cell_n, self.param.cell_n ) + if "class_average" in self.unique_fusion: + print("Initialize fusion kernel") + self.sum_kernel = sum_kernel( + self.param.resolution, + self.param.cell_n, + self.param.cell_n, + ) + self.class_average_kernel = class_average_kernel( + self.param.cell_n, + self.param.cell_n, + ) def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: """Get all fusion algorithms that need to be applied to a specific pointcloud @@ -97,17 +123,13 @@ def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): layer_indices = cp.append(layer_indices, it).astype(np.int32) return pcl_indices, layer_indices - def update_layers(self, points_all, channels, R, t): + def update_layers(self, points_all, channels, R, t, elevation_map): additional_fusion = self.get_fusion_of_pcl(channels) - self.new_map *= 0.0 - if "average" in additional_fusion: pcl_ids, layer_ids = self.get_indices_fusion(channels, "average") self.sum_kernel( points_all, - cp.array([0.0]), - cp.array([0.0]), R, t, pcl_ids, @@ -117,6 +139,38 @@ def update_layers(self, points_all, channels, R, t): self.new_map, size=(points_all.shape[0]), ) + self.average_kernel( + self.new_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + elevation_map, + self.map, + size=(self.param.cell_n * self.param.cell_n), + ) + if "class_average" in additional_fusion: + pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_average") + self.sum_kernel( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + self.map, + self.new_map, + size=(points_all.shape[0]), + ) + self.class_average_kernel( + self.new_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + elevation_map, + self.map, + size=(self.param.cell_n * self.param.cell_n), + ) + if "color" in additional_fusion: pcl_ids, layer_ids = self.get_indices_fusion(channels, "color") if self.color_map is None: @@ -124,17 +178,16 @@ def update_layers(self, points_all, channels, R, t): (1 + 3 * layer_ids.shape[0], self.param.cell_n, self.param.cell_n), dtype=np.uint32, ) + self.color_map *= 0 + # TODO this is not a good solution points_all = cp.asarray(cp.float32(points_all.get())) self.add_color_kernel( points_all, - cp.array([0.0]), - cp.array([0.0]), R, t, pcl_ids, layer_ids, cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), - self.map, self.color_map, size=(points_all.shape[0]), ) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py index ee73e103..cafbe906 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -15,6 +15,7 @@ def elmap_ex(add_lay, fusion_alg): ) p.additional_layers = additional_layer p.fusion_algorithms = fusion_algorithms + p.update() e = elevation_mapping.ElevationMap(p) return e @@ -27,21 +28,21 @@ def elmap_ex(add_lay, fusion_alg): ], ) class TestElevationMap: - def test_elmap_init(self, elmap_ex): + def test_init(self, elmap_ex): assert len(elmap_ex.layer_names) == elmap_ex.elevation_map.shape[0] - assert elmap_ex.color_map is None + # assert elmap_ex.color_map is None - def test_elmap_input(self, elmap_ex): + def test_input(self, elmap_ex): channels = ["x", "y", "z"] + elmap_ex.param.additional_layers points = cp.random.rand(100000, len(channels)) R = cp.random.rand(3, 3) t = cp.random.rand(3) elmap_ex.input(points, channels, R, t, 0, 0) - def test_elmap_update_normal(self, elmap_ex): + def test_update_normal(self, elmap_ex): elmap_ex.update_normal(elmap_ex.elevation_map[0]) - def test_elmap_move_to(self, elmap_ex): + def test_move_to(self, elmap_ex): for i in range(20): pos = np.array([i * 0.01, i * 0.02, i * 0.01]) R = cp.random.rand(3, 3) @@ -61,25 +62,30 @@ def test_get_map(self, elmap_ex): for layer in layers: elmap_ex.get_map_with_name_ref(layer, data) -# @pytest.mark.parametrize( -# "add_lay, fusion_alg,channels", -# [(["feat_0", "feat_1"], ["average", "average"],["feat_0"]), -# (["feat_0", "feat_1"], ["average", "average"],[]), -# (["feat_0", "feat_1", "rgb"], ["average", "average", "color"],["rgb", "feat_0"]), -# ], -# ) -# def test_fusion_of_pcl(elmap_ex, channels): -# fusion = elmap_ex.get_fusion_of_pcl(channels=channels) -# assert len(fusion) <= len(channels) -# assert len(fusion)>0 or len(channels)==0 -# assert all(isinstance(item, str) for item in fusion) -# -# -# @pytest.mark.parametrize( -# "add_lay, fusion_alg", -# [(["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), -# ], -# ) -# @pytest.mark.parametrize("channels", [["rgb"], ["rgb", "feat_0"], []]) -# def test_indices_fusion(elmap_ex, channels,fusion_alg): -# pcl_indices, layer_indices = elmap_ex.get_indices_fusion(pcl_channels=channels,fusion_alg=fusion_alg[0]) + def test_get_position(self,elmap_ex): + pos = np.random.rand(1,3) + elmap_ex.get_position(pos) + + def test_clear(self,elmap_ex): + elmap_ex.clear() + + def test_move(self,elmap_ex): + delta_position = np.random.rand(3) + elmap_ex.move(delta_position) + + def test_exists_layer(self,elmap_ex, add_lay): + for layer in add_lay: + assert elmap_ex.exists_layer(layer) + + def test_polygon_traversability(self,elmap_ex): + polygon = cp.array([[0, 0], [2, 0], [0, 2]], dtype=np.float64) + result = np.array([0, 0, 0]) + number_polygons = elmap_ex.get_polygon_traversability(polygon, result) + untraversable_polygon = np.zeros((number_polygons, 2)) + elmap_ex.get_untraversable_polygon(untraversable_polygon) + + def test_initialize_map(self, elmap_ex): + methods = ['linear', 'cubic', 'nearest'] + for method in methods: + points = np.array([[-4.0, 0.0, 0.0],[-4.0, 8.0, 1.0],[4.0, 8.0, 0.0],[4.0, 0.0, 0.0]]) + elmap_ex.initialize_map(points,method) diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 3da1d4d2..a518117b 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -84,6 +84,8 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh, std::vector(round(map_length_ / resolution_)); map_length_ = resolution_ * map_n_; // get true length after rounding + param_.attr("update")(); + nh.param("enable_normal", enable_normal_, false); nh.param("enable_normal_color", enable_normal_color_, false); } From 99ac97080d175c83c698dcb823b66face166dbeb Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Thu, 27 Oct 2022 13:02:25 +0200 Subject: [PATCH 240/504] added actions for python testing --- .github/workflows/python-tests.yml | 33 ++++++++++++++++++++++++++++++ README.md | 1 + requirements.txt | 1 + 3 files changed, 35 insertions(+) create mode 100644 .github/workflows/python-tests.yml diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml new file mode 100644 index 00000000..2159664e --- /dev/null +++ b/.github/workflows/python-tests.yml @@ -0,0 +1,33 @@ +# This workflow will install Python dependencies, run tests and lint with a single version of Python + +name: Python testing + +on: + push: + branches: [ "feature/2_semantic_python" ] +# pull_request: +# branches: [ "main" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.8 + uses: actions/setup-python@v3 + with: + python-version: "3.8" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pytest cupy + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Test with pytest + run: | + cd elevation_mapping_cupy/script/elevation_mapping_cupy/tests/ + pytest \ No newline at end of file diff --git a/README.md b/README.md index a4a72310..85ed128a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Elevation Mapping cupy +![python tests](https://github.com/leggedrobotics/elevation_mapping_semantic_cupy/actions/workflows/python-tests.yml/badge.svg) ## Overview This is a ROS package for elevation mapping on GPU. The elevation mapping code is written in python and uses cupy for GPU computation. The diff --git a/requirements.txt b/requirements.txt index fec90ede..c68be6a1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ scipy dataclasses ruamel.yaml opencv-python +simple_parsing ###### Requirements with Version Specifiers ######` shapely==1.7.1 From 70ad8c60582a8567fa7f14cae32d369ef820ecd1 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Wed, 2 Nov 2022 16:47:56 +0100 Subject: [PATCH 241/504] adding the pointcloud package, with class probability as well as dino feature extractor, additionally I added the first tests --- elevation_mapping_cupy/config/parameters.yaml | 2 +- .../config/sensor_parameter.yaml | 24 +- .../semantic_elevation_lonomy_single.launch | 8 +- .../rviz/lonomy_single.rviz | 13 +- .../elevation_mapping_cupy/custom_kernels.py | 8 +- .../semantic_pointcloud/CMakeLists.txt | 33 ++ .../config/sensor_parameter.yaml | 31 ++ .../launch/semantic_pointcloud.launch | 7 + .../semantic_pointcloud/package.xml | 28 ++ .../semantic_pointcloud/DINO/__init__.py | 0 .../semantic_pointcloud/DINO/modules.py | 112 +++++ .../script/semantic_pointcloud/DINO/utils.py | 46 ++ .../DINO/vision_transformer.py | 418 ++++++++++++++++++ .../script/semantic_pointcloud/__init__.py | 0 .../semantic_pointcloud/pointcloud_node.py | 184 ++++++++ .../pointcloud_parameters.py | 37 ++ .../semantic_pointcloud/tests/__init__.py | 0 .../tests/test_pointcloud.py | 18 + .../semantic_pointcloud/tests/test_utils.py | 41 ++ .../script/semantic_pointcloud/utils.py | 177 ++++++++ .../semantic_pointcloud/setup.py | 11 + 21 files changed, 1181 insertions(+), 17 deletions(-) create mode 100644 sensor_processing/semantic_pointcloud/CMakeLists.txt create mode 100644 sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml create mode 100644 sensor_processing/semantic_pointcloud/launch/semantic_pointcloud.launch create mode 100644 sensor_processing/semantic_pointcloud/package.xml create mode 100644 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/__init__.py create mode 100644 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/modules.py create mode 100644 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/utils.py create mode 100644 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/vision_transformer.py create mode 100644 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/__init__.py create mode 100755 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py create mode 100644 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py create mode 100644 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/__init__.py create mode 100644 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py create mode 100644 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py create mode 100644 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py create mode 100644 sensor_processing/semantic_pointcloud/setup.py diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index 24e29141..dc59828d 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -81,7 +81,7 @@ publishers: basic_layers: ['elevation', 'traversability'] fps: 2.0 elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb'] + layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb','person'] basic_layers: ['min_filter'] fps: 3.0 diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index 8c8c596b..1a9e6642 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -4,7 +4,29 @@ subscribers: # fusion: ['average','average'] # topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: - channels: ['rgb','feat_0','feat_1','c_prob_0'] + channels: ['rgb','feat_0','feat_1','person','grass'] fusion: ['color','average','average','class_average'] topic_name: '/elvation_mapping/pointcloud_semantic' + semantic_segmentation: True + segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' + feature_config: + name: 'DINO' + interpolation: 'bilinear' + model: "vit_small" + patch_size: 16 + dim: 5 + dropout: False + dino_feat_type: "feat" + input_size: [80, 160] + projection_type: "nonlinear" + + cam_info_topic: "/zed2i/zed_node/depth/camera_info" + image_topic: "/zed2i/zed_node/left/image_rect_color" + depth_topic: "/zed2i/zed_node/depth/depth_registered" + cam_frame: "zed2i_right_camera_optical_frame" + confidence_topic: "/zed2i/zed_node/confidence/confidence_map" + confidence_threshold: 10 + + + diff --git a/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch b/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch index 77b4918f..0e644e44 100644 --- a/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch +++ b/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch @@ -5,11 +5,9 @@ - - - - - + + + diff --git a/elevation_mapping_cupy/rviz/lonomy_single.rviz b/elevation_mapping_cupy/rviz/lonomy_single.rviz index da12d689..d35d1a1b 100644 --- a/elevation_mapping_cupy/rviz/lonomy_single.rviz +++ b/elevation_mapping_cupy/rviz/lonomy_single.rviz @@ -4,6 +4,7 @@ Panels: Name: Displays Property Tree Widget: Expanded: + - /ElevationMapFilter1 - /Image1 Splitter Ratio: 0.5768463015556335 Tree Height: 428 @@ -54,16 +55,16 @@ Visualization Manager: Autocompute Intensity Bounds: true Class: grid_map_rviz_plugin/GridMap Color: 200; 200; 200 - Color Layer: rgb - Color Transformer: ColorLayer + Color Layer: person + Color Transformer: IntensityLayer Enabled: true Height Layer: smooth Height Transformer: GridMapLayer History Length: 1 Invert Rainbow: false - Max Color: 255; 255; 255 + Max Color: 204; 0; 0 Max Intensity: 10 - Min Color: 0; 0; 0 + Min Color: 52; 101; 164 Min Intensity: 0 Name: ElevationMapFilter Show Grid Lines: true @@ -448,9 +449,9 @@ Visualization Manager: Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.12979847192764282 + Pitch: 0.5547983050346375 Target Frame: base_footprint - Yaw: 0.9738447666168213 + Yaw: 1.4138503074645996 Saved: ~ Window Geometry: Displays: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py index f96b45f2..8884660f 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py @@ -682,7 +682,7 @@ def sum_kernel( if (valid) { if (inside) { for ( int it=0;it0){ for ( int it=0;it + + + + + \ No newline at end of file diff --git a/sensor_processing/semantic_pointcloud/package.xml b/sensor_processing/semantic_pointcloud/package.xml new file mode 100644 index 00000000..00cb393f --- /dev/null +++ b/sensor_processing/semantic_pointcloud/package.xml @@ -0,0 +1,28 @@ + + + semantic_pointcloud + 0.0.0 + The semantic_pointcloud package + Gian Erni + + + + MIT + + + https://github.com/leggedrobotics/elevation_mapping_semantic_cupy + + + Gian Erni + + catkin + rospy + roslib + tf + tf_conversions + sensor_msgs + std_msgs + geometry_msgs + + + diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/__init__.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/modules.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/modules.py new file mode 100644 index 00000000..f2a9f996 --- /dev/null +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/modules.py @@ -0,0 +1,112 @@ +import semantic_pointcloud.DINO.vision_transformer as vits +# import vision_transformer as vits +import torch.nn as nn +import torch.nn.functional as F +import torch + + +class DinoFeaturizer(nn.Module): + + def __init__(self, weights, cfg): + super().__init__() + self.cfg = cfg + self.dim = cfg.dim + + self.feat_type = self.cfg.dino_feat_type + arch = self.cfg.model + self.model = vits.__dict__[arch]( + patch_size=self.cfg.patch_size, + num_classes=0) + for p in self.model.parameters(): + p.requires_grad = False + self.model.eval().cuda() + self.dropout = torch.nn.Dropout2d(p=.1) + + if arch == "vit_small" and self.cfg.patch_size == 16: + url = "dino_deitsmall16_pretrain/dino_deitsmall16_pretrain.pth" + elif arch == "vit_small" and self.cfg.patch_size == 8: + url = "dino_deitsmall8_300ep_pretrain/dino_deitsmall8_300ep_pretrain.pth" + elif arch == "vit_base" and self.cfg.patch_size == 16: + url = "dino_vitbase16_pretrain/dino_vitbase16_pretrain.pth" + elif arch == "vit_base" and self.cfg.patch_size == 8: + url = "dino_vitbase8_pretrain/dino_vitbase8_pretrain.pth" + else: + raise ValueError("Unknown arch and patch size") + + + # if cfg.pretrained_weights is not None: + # state_dict = torch.load(cfg.pretrained_weights, map_location="cpu") + # state_dict = state_dict["teacher"] + # # remove `module.` prefix + # state_dict = {k.replace("module.", ""): v for k, v in state_dict.items()} + # # remove `backbone.` prefix induced by multicrop wrapper + # state_dict = {k.replace("backbone.", ""): v for k, v in state_dict.items()} + # + # # state_dict = {k.replace("projection_head", "mlp"): v for k, v in state_dict.items()} + # # state_dict = {k.replace("prototypes", "last_layer"): v for k, v in state_dict.items()} + # + # msg = self.model.load_state_dict(state_dict, strict=False) + # print('Pretrained weights found at {} and loaded with msg: {}'.format(cfg.pretrained_weights, msg)) + # else: + # print("Since no pretrained weights have been provided, we load the reference pretrained DINO weights.") + state_dict = torch.hub.load_state_dict_from_url(url="https://dl.fbaipublicfiles.com/dino/" + url) + + self.model.load_state_dict(state_dict, strict=True) + + if arch == "vit_small": + self.n_feats = 384 + else: + self.n_feats = 768 + self.cluster1 = self.make_clusterer(self.n_feats) + self.proj_type = cfg.projection_type + if self.proj_type == "nonlinear": + self.cluster2 = self.make_nonlinear_clusterer(self.n_feats) + + def make_clusterer(self, in_channels): + return torch.nn.Sequential( + torch.nn.Conv2d(in_channels, self.dim, (1, 1))) # , + + def make_nonlinear_clusterer(self, in_channels): + return torch.nn.Sequential( + torch.nn.Conv2d(in_channels, in_channels, (1, 1)), + torch.nn.ReLU(), + torch.nn.Conv2d(in_channels, self.dim, (1, 1))) + + def forward(self, img, n=1, return_class_feat=False): + self.model.eval() + with torch.no_grad(): + assert (img.shape[2] % self.cfg.patch_size == 0) + assert (img.shape[3] % self.cfg.patch_size == 0) + + # get selected layer activations + feat, attn, qkv = self.model.get_intermediate_feat(img, n=n) + feat, attn, qkv = feat[0], attn[0], qkv[0] + + feat_h = img.shape[2] // self.cfg.patch_size + feat_w = img.shape[3] // self.cfg.patch_size + + if self.feat_type == "feat": + image_feat = feat[:, 1:, :].reshape(feat.shape[0], feat_h, feat_w, -1).permute(0, 3, 1, 2) + elif self.feat_type == "KK": + image_k = qkv[1, :, :, 1:, :].reshape(feat.shape[0], 6, feat_h, feat_w, -1) + B, H, I, J, D = image_k.shape + image_feat = image_k.permute(0, 1, 4, 2, 3).reshape(B, H * D, I, J) + else: + raise ValueError("Unknown feat type:{}".format(self.feat_type)) + + if return_class_feat: + return feat[:, :1, :].reshape(feat.shape[0], 1, 1, -1).permute(0, 3, 1, 2) + + if self.proj_type is not None: + code = self.cluster1(self.dropout(image_feat)) + if self.proj_type == "nonlinear": + code += self.cluster2(self.dropout(image_feat)) + else: + code = image_feat + + if self.cfg.dropout: + return self.dropout(image_feat), code + else: + return image_feat, code + + diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/utils.py new file mode 100644 index 00000000..1bc84057 --- /dev/null +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/utils.py @@ -0,0 +1,46 @@ +import torch +import warnings +import math + + +def _no_grad_trunc_normal_(tensor, mean, std, a, b): + # Cut & paste from PyTorch official master until it's in a few official releases - RW + # Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf + def norm_cdf(x): + # Computes standard normal cumulative distribution function + return (1.0 + math.erf(x / math.sqrt(2.0))) / 2.0 + + if (mean < a - 2 * std) or (mean > b + 2 * std): + warnings.warn( + "mean is more than 2 std from [a, b] in nn.init.trunc_normal_. " + "The distribution of values may be incorrect.", + stacklevel=2, + ) + + with torch.no_grad(): + # Values are generated by using a truncated uniform distribution and + # then using the inverse CDF for the normal distribution. + # Get upper and lower cdf values + l = norm_cdf((a - mean) / std) + u = norm_cdf((b - mean) / std) + + # Uniformly fill tensor with values from [l, u], then translate to + # [2l-1, 2u-1]. + tensor.uniform_(2 * l - 1, 2 * u - 1) + + # Use inverse cdf transform for normal distribution to get truncated + # standard normal + tensor.erfinv_() + + # Transform to proper mean, std + tensor.mul_(std * math.sqrt(2.0)) + tensor.add_(mean) + + # Clamp to ensure it's in the proper range + tensor.clamp_(min=a, max=b) + return tensor + + +def trunc_normal_(tensor, mean=0.0, std=1.0, a=-2.0, b=2.0): + # type: (Tensor, float, float, float, float) -> Tensor + return _no_grad_trunc_normal_(tensor, mean, std, a, b) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/vision_transformer.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/vision_transformer.py new file mode 100644 index 00000000..26ad82af --- /dev/null +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/vision_transformer.py @@ -0,0 +1,418 @@ +""" +Mostly copy-paste from timm library. +https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py +""" +import math +from functools import partial + +import torch +import torch.nn as nn +from semantic_pointcloud.DINO.utils import trunc_normal_ + + +def drop_path(x, drop_prob: float = 0.0, training: bool = False): + if drop_prob == 0.0 or not training: + return x + keep_prob = 1 - drop_prob + shape = (x.shape[0],) + (1,) * ( + x.ndim - 1 + ) # work with diff dim tensors, not just 2D ConvNets + random_tensor = keep_prob + torch.rand(shape, dtype=x.dtype, device=x.device) + random_tensor.floor_() # binarize + output = x.div(keep_prob) * random_tensor + return output + + +class DropPath(nn.Module): + """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" + + def __init__(self, drop_prob=None): + super(DropPath, self).__init__() + self.drop_prob = drop_prob + + def forward(self, x): + return drop_path(x, self.drop_prob, self.training) + + +class Mlp(nn.Module): + def __init__( + self, + in_features, + hidden_features=None, + out_features=None, + act_layer=nn.GELU, + drop=0.0, + ): + super().__init__() + out_features = out_features or in_features + hidden_features = hidden_features or in_features + self.fc1 = nn.Linear(in_features, hidden_features) + self.act = act_layer() + self.fc2 = nn.Linear(hidden_features, out_features) + self.drop = nn.Dropout(drop) + + def forward(self, x): + x = self.fc1(x) + x = self.act(x) + x = self.drop(x) + x = self.fc2(x) + x = self.drop(x) + return x + + +class Attention(nn.Module): + def __init__( + self, + dim, + num_heads=8, + qkv_bias=False, + qk_scale=None, + attn_drop=0.0, + proj_drop=0.0, + ): + super().__init__() + self.num_heads = num_heads + head_dim = dim // num_heads + self.scale = qk_scale or head_dim**-0.5 + + self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) + self.attn_drop = nn.Dropout(attn_drop) + self.proj = nn.Linear(dim, dim) + self.proj_drop = nn.Dropout(proj_drop) + + def forward(self, x, return_qkv=False): + B, N, C = x.shape + qkv = ( + self.qkv(x) + .reshape(B, N, 3, self.num_heads, C // self.num_heads) + .permute(2, 0, 3, 1, 4) + ) + q, k, v = qkv[0], qkv[1], qkv[2] + + attn = (q @ k.transpose(-2, -1)) * self.scale + attn = attn.softmax(dim=-1) + attn = self.attn_drop(attn) + + x = (attn @ v).transpose(1, 2).reshape(B, N, C) + x = self.proj(x) + x = self.proj_drop(x) + return x, attn, qkv + + +class Block(nn.Module): + def __init__( + self, + dim, + num_heads, + mlp_ratio=4.0, + qkv_bias=False, + qk_scale=None, + drop=0.0, + attn_drop=0.0, + drop_path=0.0, + act_layer=nn.GELU, + norm_layer=nn.LayerNorm, + ): + super().__init__() + self.norm1 = norm_layer(dim) + self.attn = Attention( + dim, + num_heads=num_heads, + qkv_bias=qkv_bias, + qk_scale=qk_scale, + attn_drop=attn_drop, + proj_drop=drop, + ) + self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity() + self.norm2 = norm_layer(dim) + mlp_hidden_dim = int(dim * mlp_ratio) + self.mlp = Mlp( + in_features=dim, + hidden_features=mlp_hidden_dim, + act_layer=act_layer, + drop=drop, + ) + + def forward(self, x, return_attention=False, return_qkv=False): + y, attn, qkv = self.attn(self.norm1(x)) + if return_attention: + return attn + x = x + self.drop_path(y) + x = x + self.drop_path(self.mlp(self.norm2(x))) + if return_qkv: + return x, attn, qkv + return x + + +class PatchEmbed(nn.Module): + """Image to Patch Embedding""" + + def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768): + super().__init__() + num_patches = (img_size // patch_size) * (img_size // patch_size) + self.img_size = img_size + self.patch_size = patch_size + self.num_patches = num_patches + + self.proj = nn.Conv2d( + in_chans, embed_dim, kernel_size=patch_size, stride=patch_size + ) + + def forward(self, x): + B, C, H, W = x.shape + x = self.proj(x).flatten(2).transpose(1, 2) + return x + + +class VisionTransformer(nn.Module): + """Vision Transformer""" + + def __init__( + self, + img_size=[224], + patch_size=16, + in_chans=3, + num_classes=0, + embed_dim=768, + depth=12, + num_heads=12, + mlp_ratio=4.0, + qkv_bias=False, + qk_scale=None, + drop_rate=0.0, + attn_drop_rate=0.0, + drop_path_rate=0.0, + norm_layer=nn.LayerNorm, + **kwargs + ): + super().__init__() + + self.num_features = self.embed_dim = embed_dim + + self.patch_embed = PatchEmbed( + img_size=img_size[0], + patch_size=patch_size, + in_chans=in_chans, + embed_dim=embed_dim, + ) + num_patches = self.patch_embed.num_patches + + self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim)) + self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim)) + self.pos_drop = nn.Dropout(p=drop_rate) + + dpr = [ + x.item() for x in torch.linspace(0, drop_path_rate, depth) + ] # stochastic depth decay rule + self.blocks = nn.ModuleList( + [ + Block( + dim=embed_dim, + num_heads=num_heads, + mlp_ratio=mlp_ratio, + qkv_bias=qkv_bias, + qk_scale=qk_scale, + drop=drop_rate, + attn_drop=attn_drop_rate, + drop_path=dpr[i], + norm_layer=norm_layer, + ) + for i in range(depth) + ] + ) + self.norm = norm_layer(embed_dim) + + # Classifier head + self.head = ( + nn.Linear(embed_dim, num_classes) if num_classes > 0 else nn.Identity() + ) + + trunc_normal_(self.pos_embed, std=0.02) + trunc_normal_(self.cls_token, std=0.02) + self.apply(self._init_weights) + + def _init_weights(self, m): + if isinstance(m, nn.Linear): + trunc_normal_(m.weight, std=0.02) + if isinstance(m, nn.Linear) and m.bias is not None: + nn.init.constant_(m.bias, 0) + elif isinstance(m, nn.LayerNorm): + nn.init.constant_(m.bias, 0) + nn.init.constant_(m.weight, 1.0) + + def interpolate_pos_encoding(self, x, w, h): + npatch = x.shape[1] - 1 + N = self.pos_embed.shape[1] - 1 + if npatch == N and w == h: + return self.pos_embed + class_pos_embed = self.pos_embed[:, 0] + patch_pos_embed = self.pos_embed[:, 1:] + dim = x.shape[-1] + w0 = w // self.patch_embed.patch_size + h0 = h // self.patch_embed.patch_size + # we add a small number to avoid floating point error in the interpolation + # see discussion at https://github.com/facebookresearch/dino/issues/8 + w0, h0 = w0 + 0.1, h0 + 0.1 + patch_pos_embed = nn.functional.interpolate( + patch_pos_embed.reshape( + 1, int(math.sqrt(N)), int(math.sqrt(N)), dim + ).permute(0, 3, 1, 2), + scale_factor=(w0 / math.sqrt(N), h0 / math.sqrt(N)), + mode="bicubic", + ) + assert ( + int(w0) == patch_pos_embed.shape[-2] + and int(h0) == patch_pos_embed.shape[-1] + ) + patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim) + return torch.cat((class_pos_embed.unsqueeze(0), patch_pos_embed), dim=1) + + def prepare_tokens(self, x): + B, nc, w, h = x.shape + x = self.patch_embed(x) # patch linear embedding + + # add the [CLS] token to the embed patch tokens + cls_tokens = self.cls_token.expand(B, -1, -1) + x = torch.cat((cls_tokens, x), dim=1) + + # add positional encoding to each token + x = x + self.interpolate_pos_encoding(x, w, h) + + return self.pos_drop(x) + + def forward(self, x): + x = self.prepare_tokens(x) + for blk in self.blocks: + x = blk(x) + x = self.norm(x) + return x[:, 0] + + def forward_feats(self, x): + x = self.prepare_tokens(x) + for blk in self.blocks: + x = blk(x) + x = self.norm(x) + return x + + def get_intermediate_feat(self, x, n=1): + x = self.prepare_tokens(x) + # we return the output tokens from the `n` last blocks + feat = [] + attns = [] + qkvs = [] + for i, blk in enumerate(self.blocks): + x, attn, qkv = blk(x, return_qkv=True) + if len(self.blocks) - i <= n: + feat.append(self.norm(x)) + qkvs.append(qkv) + attns.append(attn) + return feat, attns, qkvs + + def get_last_selfattention(self, x): + x = self.prepare_tokens(x) + for i, blk in enumerate(self.blocks): + if i < len(self.blocks) - 1: + x = blk(x) + else: + # return attention of the last block + return blk(x, return_attention=True) + + def get_intermediate_layers(self, x, n=1): + x = self.prepare_tokens(x) + # we return the output tokens from the `n` last blocks + output = [] + for i, blk in enumerate(self.blocks): + x = blk(x) + if len(self.blocks) - i <= n: + output.append(self.norm(x)) + return output + + +def vit_tiny(patch_size=16, **kwargs): + model = VisionTransformer( + patch_size=patch_size, + embed_dim=192, + depth=12, + num_heads=3, + mlp_ratio=4, + qkv_bias=True, + norm_layer=partial(nn.LayerNorm, eps=1e-6), + **kwargs + ) + return model + + +def vit_small(patch_size=16, **kwargs): + model = VisionTransformer( + patch_size=patch_size, + embed_dim=384, + depth=12, + num_heads=6, + mlp_ratio=4, + qkv_bias=True, + norm_layer=partial(nn.LayerNorm, eps=1e-6), + **kwargs + ) + return model + + +def vit_base(patch_size=16, **kwargs): + model = VisionTransformer( + patch_size=patch_size, + embed_dim=768, + depth=12, + num_heads=12, + mlp_ratio=4, + qkv_bias=True, + norm_layer=partial(nn.LayerNorm, eps=1e-6), + **kwargs + ) + return model + + +class DINOHead(nn.Module): + def __init__( + self, + in_dim, + out_dim, + use_bn=False, + norm_last_layer=True, + nlayers=3, + hidden_dim=2048, + bottleneck_dim=256, + ): + super().__init__() + nlayers = max(nlayers, 1) + if nlayers == 1: + self.mlp = nn.Linear(in_dim, bottleneck_dim) + else: + layers = [nn.Linear(in_dim, hidden_dim)] + if use_bn: + layers.append(nn.BatchNorm1d(hidden_dim)) + layers.append(nn.GELU()) + for _ in range(nlayers - 2): + layers.append(nn.Linear(hidden_dim, hidden_dim)) + if use_bn: + layers.append(nn.BatchNorm1d(hidden_dim)) + layers.append(nn.GELU()) + layers.append(nn.Linear(hidden_dim, bottleneck_dim)) + self.mlp = nn.Sequential(*layers) + self.apply(self._init_weights) + self.last_layer = nn.utils.weight_norm( + nn.Linear(bottleneck_dim, out_dim, bias=False) + ) + self.last_layer.weight_g.data.fill_(1) + if norm_last_layer: + self.last_layer.weight_g.requires_grad = False + + def _init_weights(self, m): + if isinstance(m, nn.Linear): + trunc_normal_(m.weight, std=0.02) + if isinstance(m, nn.Linear) and m.bias is not None: + nn.init.constant_(m.bias, 0) + + def forward(self, x): + x = self.mlp(x) + x = nn.functional.normalize(x, dim=-1, p=2) + x = self.last_layer(x) + return x diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/__init__.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py new file mode 100755 index 00000000..c22d8b41 --- /dev/null +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -0,0 +1,184 @@ +import rospy +import sys + +import numpy as np +import cupy as cp +import ros_numpy + +import message_filters +from sensor_msgs.msg import Image, CameraInfo +from sensor_msgs.msg import PointCloud2 +from cv_bridge import CvBridge + +from semantic_pointcloud.pointcloud_parameters import PointcloudParameter +from semantic_pointcloud.utils import resolve_model + + +class PointcloudNode: + def __init__(self, sensor_name): + # TODO: if this is going to be loaded from another package we might need to change namespace + config = rospy.get_param("/semantic_pointcloud/subscribers") + print(config) + print(len(config)) + self.param: PointcloudParameter = PointcloudParameter.from_dict( + config[sensor_name] + ) + self.param.sensor_name = sensor_name + print(self.param.dumps_yaml()) + # setup custom dtype + self.create_custom_dtype() + # setup semantics + self.feature_extractor = None + self.semantic_model = None + self.initialize_semantics() + + # setup pointcloud creation + self.cv_bridge = CvBridge() + self.P = None + + rospy.Subscriber(self.param.cam_info_topic, CameraInfo, self.cam_info_callback) + rgb_sub = message_filters.Subscriber(self.param.image_topic, Image) + depth_sub = message_filters.Subscriber(self.param.depth_topic, Image) + confidence_sub = message_filters.Subscriber(self.param.confidence_topic, Image) + ts = message_filters.ApproximateTimeSynchronizer( + [ + rgb_sub, + depth_sub, + confidence_sub, + ], + queue_size=10, + slop=0.5, + ) + ts.registerCallback(self.image_callback) + + self.pcl_pub = rospy.Publisher(self.param.topic_name, PointCloud2, queue_size=2) + + def initialize_semantics(self): + if self.param.semantic_segmentation: + self.semantic_model = resolve_model(self.param.segmentation_model) + class_to_idx = { + cls: idx + for (idx, cls) in enumerate(self.semantic_model["model"].get_classes()) + } + print( + "Semantic Segmentation possible channels: ", + self.semantic_model["model"].get_classes(), + ) + indices = [] + channels = [] + for chan in self.param.channels: + if chan in [cls for cls in list(class_to_idx.keys())]: + indices.append(class_to_idx[chan]) + channels.append(chan) + self.segmentation_channels = dict(zip(channels, indices)) + if self.param.feature_extractor: + self.feature_channels = [] + for i, fusion in enumerate(self.param.fusion): + if fusion == "average": + self.feature_channels.append(self.param.channels[i]) + assert len(self.feature_channels) > 0 + self.feature_extractor = resolve_model( + self.param.feature_config.name, self.param.feature_config + ) + + def create_custom_dtype(self): + self.dtype = [ + ("x", np.float32), + ("y", np.float32), + ("z", np.float32), + ] + for chan in self.param.channels: + self.dtype.append((chan, np.float32)) + print(self.dtype) + + def cam_info_callback(self, msg): + a = cp.asarray(msg.P) + self.P = cp.resize(a, (3, 4)) + self.height = msg.height + self.width = msg.width + + def image_callback(self, rgb_msg, depth_msg, confidence_msg): + if self.P is None: + print("No cam info topic has been published yet!") + return + image = cp.asarray( + self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8") + ) + depth = cp.asarray( + self.cv_bridge.imgmsg_to_cv2(depth_msg, desired_encoding="passthrough") + ) + confidence = cp.asarray( + self.cv_bridge.imgmsg_to_cv2(confidence_msg, desired_encoding="passthrough") + ) + + pcl = self.create_pcl_from_image(image, depth, confidence) + + self.publish_pointcloud(pcl, depth_msg.header) + + def create_pcl_from_image(self, image, depth, confidence): + u, v = self.get_coordinates(depth, confidence) + + # create pointcloud + world_x = (u.astype(np.float32) - self.P[0, 2]) * depth[v, u] / self.P[0, 0] + world_y = (v.astype(np.float32) - self.P[1, 2]) * depth[v, u] / self.P[1, 1] + world_z = depth[v, u] + points = np.zeros(world_x.shape, dtype=self.dtype) + points["x"] = cp.asnumpy(world_x) + points["y"] = cp.asnumpy(world_y) + points["z"] = cp.asnumpy(world_z) + self.process_image(image, u, v, points) + return points + + def get_coordinates(self, depth, confidence): + pos = cp.where(depth > 0, 1, 0) + low = cp.where(depth < 8, 1, 0) + conf = cp.where(confidence >= self.param.confidence_threshold, 1, 0) + fin = cp.isfinite(depth) + temp = cp.maximum(cp.rint(fin + pos + conf + low - 2.6), 0) + mask = cp.nonzero(temp) + u = mask[1] + v = mask[0] + return u, v + + def publish_pointcloud(self, pcl, header): + pc2 = ros_numpy.msgify(PointCloud2, pcl) + pc2.header = header + pc2.header.frame_id = self.param.cam_frame + self.pcl_pub.publish(pc2) + + def process_image(self, image, u, v, points): + if "color" in self.param.fusion: + valid_rgb = image[v, u].get() + r = np.asarray(valid_rgb[:, 0], dtype=np.uint32) + g = np.asarray(valid_rgb[:, 1], dtype=np.uint32) + b = np.asarray(valid_rgb[:, 2], dtype=np.uint32) + rgb_arr = np.array((r << 16) | (g << 8) | (b << 0), dtype=np.uint32) + rgb_arr.dtype = np.float32 + position = self.param.fusion.index("color") + points[self.param.channels[position]] = rgb_arr + + if self.segmentation_channels is not None: + self.perform_segmentation(image, points, u, v) + if self.feature_channels is not None: + # TODO is no return needed? + self.extract_features(image, points, u, v) + + def perform_segmentation(self, image, points, u, v): + prediction = self.semantic_model["model"](image) + mask = prediction[list(self.segmentation_channels.values())] + values = mask[:, v.get(), u.get()].cpu().detach().numpy() + for it, channel in enumerate(self.segmentation_channels.keys()): + points[channel] = values[it] + + def extract_features(self, image, points, u, v): + prediction = self.feature_extractor["model"](image) + values = prediction[:, v.get(), u.get()].cpu().detach().numpy() + for it, channel in enumerate(self.feature_channels): + points[channel] = values[it] + + +if __name__ == "__main__": + sensor_name = sys.argv[1] + rospy.init_node("semantic_pointcloud_node", anonymous=True, log_level=rospy.INFO) + node = PointcloudNode(sensor_name) + rospy.spin() diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py new file mode 100644 index 00000000..3474f8d4 --- /dev/null +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py @@ -0,0 +1,37 @@ +from dataclasses import dataclass, field +from simple_parsing.helpers import Serializable +from typing import Tuple, List + + +@dataclass +class FeatureExtractorParameter(Serializable): + name: str = "DINO" + interpolation: str = "bilinear" + model: str = "vit_small" + patch_size: int = 16 + dim: int = 5 + dropout: bool = False + dino_feat_type: str = "feat" + projection_type: str = "nonlinear" + input_size: List[int] = field(default_factory=[80, 160].copy) + + +@dataclass +class PointcloudParameter(Serializable): + sensor_name: str = "camera" + topic_name: str = "/elvation_mapping/pointcloud_semantic" + channels: list = ["rgb", "feat_0", "feat_1", "c_prob_0"].copy + fusion: list = ["color", "average", "average", "class_average"].copy + + semantic_segmentation: bool = True + segmentation_model: str = "detectron_coco_panoptic_fpn_R_101_3x" + + cam_info_topic: str = "/zed2i/zed_node/depth/camera_info" + image_topic: str = "/zed2i/zed_node/left/image_rect_color" + depth_topic: str = "/zed2i/zed_node/depth/depth_registered" + cam_frame: str = "zed2i_right_camera_optical_frame" + confidence_topic: str = "/zed2i/zed_node/confidence/confidence_map" + confidence_threshold: int = 10 + + feature_extractor: bool = True + feature_config: FeatureExtractorParameter = FeatureExtractorParameter diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/__init__.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py new file mode 100644 index 00000000..ee5dcf4e --- /dev/null +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py @@ -0,0 +1,18 @@ +import pytest +from ..pointcloud_node import PointcloudNode + + +@pytest.fixture() +def pointcloud_ex(cam_name): + node = PointcloudNode(cam_name) + return node + + +@pytest.mark.parametrize( + "cam_name", + [ + "front_cam", + ], +) +def test_initialize_semantics(pointcloud_ex): + pointcloud_ex.initialize_semantics() diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py new file mode 100644 index 00000000..86ad0899 --- /dev/null +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py @@ -0,0 +1,41 @@ +import pytest +from semantic_pointcloud.utils import resolve_model +import cupy as cp +import torch +from semantic_pointcloud.pointcloud_parameters import FeatureExtractorParameter + + +@pytest.mark.parametrize( + "model_name", + [ + "fcn_resnet50", + "lraspp_mobilenet_v3_large", + "detectron_coco_panoptic_fpn_R_101_3x", + ], +) +def test_semantic_segmentation(model_name): + m = resolve_model(model_name) + im_sz = [360, 640] + image = cp.random.random((im_sz[0], im_sz[1], 3)) + classes = m["model"].get_classes() + assert type(classes) is list + prediction = m["model"](image) + assert prediction.shape == torch.Size([len(classes), im_sz[0], im_sz[1]]) + assert (prediction <= 1).all() + assert (0 <= prediction).all() + + +@pytest.mark.parametrize( + "model_name", + [ + "DINO", + ], +) +def test_feature_extractor(model_name): + param = FeatureExtractorParameter() + m = resolve_model(model_name, param) + im_sz = [320, 640] + image = cp.random.random((im_sz[0], im_sz[1], 3)) + prediction = m["model"](image.get()) + assert prediction.shape == torch.Size([param.dim, im_sz[0], im_sz[1]]) + assert prediction.shape[-2:] == torch.Size([im_sz[0], im_sz[1]]) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py new file mode 100644 index 00000000..9fe62de8 --- /dev/null +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py @@ -0,0 +1,177 @@ +from torchvision.models.segmentation import fcn_resnet50, FCN_ResNet50_Weights +from torchvision.models.segmentation import ( + lraspp_mobilenet_v3_large, + LRASPP_MobileNet_V3_Large_Weights, +) +import torch +import torchvision.transforms.functional as TF +from torchvision.transforms import Resize +import torch.nn.functional as NF +import numpy as np + +# Setup detectron2 logger +# import detectron2 +from detectron2.utils.logger import setup_logger + +setup_logger() + + +# import some common detectron2 utilities +from detectron2 import model_zoo +from detectron2.engine import DefaultPredictor +from detectron2.config import get_cfg +from detectron2.data import MetadataCatalog + +from semantic_pointcloud.DINO.modules import DinoFeaturizer + +# from .DINO.modules import DinoFeaturizer +from semantic_pointcloud.pointcloud_parameters import ( + PointcloudParameter, + FeatureExtractorParameter, +) + +# from .pointcloud_parameters import PointcloudParameter, FeatureExtractorParameter + + +def resolve_model(name, config: FeatureExtractorParameter = None): + """Get the model class based on the name of the pretrained model. + + Args: + name (str): Name of pretrained model + [fcn_resnet50,lraspp_mobilenet_v3_large,detectron_coco_panoptic_fpn_R_101_3x] + + Returns: + Dict[str, str]: + """ + if name == "fcn_resnet50": + weights = FCN_ResNet50_Weights.DEFAULT + net = fcn_resnet50 + model = PytorchModel(net, weights) + return { + "name": "fcn_resnet50", + "model": model, + } + elif name == "lraspp_mobilenet_v3_large": + weights = LRASPP_MobileNet_V3_Large_Weights.DEFAULT + net = lraspp_mobilenet_v3_large + model = PytorchModel(net, weights) + return { + "name": "lraspp_mobilenet_v3_large", + "model": model, + } + elif name == "detectron_coco_panoptic_fpn_R_101_3x": + net = "" + # "Cityscapes/mask_rcnn_R_50_FPN.yaml" + # "Misc/semantic_R_50_FPN_1x.yaml" + # "Cityscapes-SemanticSegmentation/deeplab_v3_plus_R_103_os16_mg124_poly_90k_bs16.yaml" + # "COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml" + weights = "COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml" + model = DetectronModel(net, weights) + return { + "name": "detectron_coco_panoptic_fpn_R_101_3x", + "model": model, + } + elif name == "DINO": + weights = config.model + str(config.patch_size) + model = STEGOModel(weights, config) + return { + "name": config.model + str(config.patch_size), + "model": model, + } + else: + raise NotImplementedError + + +class PytorchModel: + def __init__(self, net, weights): + self.model = net(weights) + self.weights = weights + self.model.eval() + device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") + self.model.to(device=device) + + def __call__(self, image, *args, **kwargs): + """Feewforward image through model. + + Args: + image (cupy._core.core.ndarray): + *args (): + **kwargs (): + + Returns: + torch.Tensor: + """ + batch = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) + batch = TF.convert_image_dtype(batch, torch.float32) + prediction = self.model(batch)["out"] + normalized_masks = torch.squeeze(prediction.softmax(dim=1), dim=0) + return normalized_masks + + def get_classes(self): + """Get list of strings containing all the classes. + + Returns: + List[str]: List of classes + """ + return self.weights.meta["categories"] + + +class DetectronModel: + def __init__(self, net, weights): + self.cfg = get_cfg() + # add project-specific config (e.g., TensorMask) here if you're not running a model in detectron2's core library + self.cfg.merge_from_file(model_zoo.get_config_file(weights)) + self.cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5 # set threshold for this model + # Find a model from detectron2's model zoo. You can use the https://dl.fbaipublicfiles... url as well + self.cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(weights) + self.predictor = DefaultPredictor(self.cfg) + + def __call__(self, image, *args, **kwargs): + # TODO: there are some instruction on how to change input type + prediction = self.predictor(image.get()) + # panoptic_seg, segments_info = self.predictor(image.get())["panoptic_seg"] + normalized_masks = prediction["sem_seg"].softmax(dim=1) + return normalized_masks + + def get_classes(self): + meta = MetadataCatalog.get(self.cfg.DATASETS.TRAIN[0]) + return meta.get("stuff_classes") + + +class STEGOModel: + def __init__(self, weights, cfg): + self.cfg: FeatureExtractorParameter = cfg + self.model = DinoFeaturizer(weights, cfg=self.cfg) + self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") + self.model.to(self.device) + self.model.eval() + self.shrink = Resize(size=(self.cfg.input_size[0], self.cfg.input_size[1])) + + def to_tensor(self, data): + data = data.astype(np.float32) + if len(data.shape) == 3: # transpose image-like data + data = data.transpose(2, 0, 1) + elif len(data.shape) == 2: + data = data.reshape((1,) + data.shape) + if len(data.shape) == 3 and data.shape[0] == 3: # normalization of rgb images + data = data / 255.0 + tens = torch.as_tensor(data, device="cuda") + return tens + + def __call__(self, image, *args, **kwargs): + # image = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) + image = self.to_tensor(image).unsqueeze(0) + reset_size = Resize(image.shape[-2:]) + image = self.shrink(image) + image = TF.normalize( + image, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225) + ) + + feat1, code1 = self.model(image) + feat2, code2 = self.model(image.flip(dims=[3])) + code = (code1 + code2.flip(dims=[3])) / 2 + code = NF.interpolate( + code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False + ).detach() + code = torch.squeeze(reset_size(code), dim=0) + return code diff --git a/sensor_processing/semantic_pointcloud/setup.py b/sensor_processing/semantic_pointcloud/setup.py new file mode 100644 index 00000000..94ad1600 --- /dev/null +++ b/sensor_processing/semantic_pointcloud/setup.py @@ -0,0 +1,11 @@ +from distutils.core import setup +from catkin_pkg.python_setup import generate_distutils_setup + +setup_args = generate_distutils_setup( + packages=[ + 'semantic_pointcloud', + ], + package_dir={'': 'script'}, +) + +setup(**setup_args) From b93c0563909fc754e79152ef212a885dc06fa0ad Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Thu, 3 Nov 2022 12:15:06 +0100 Subject: [PATCH 242/504] first --- .../config/plugin_config.yaml | 2 +- .../config/sensor_parameter.yaml | 7 +- .../plugins/inpainting.py | 1 + .../plugins/min_filter.py | 1 + .../plugins/plugin_manager.py | 64 ++++++++++++++++--- .../plugins/semantic_map.py | 53 +++++++++++++++ .../plugins/smooth_filter.py | 1 + 7 files changed, 117 insertions(+), 12 deletions(-) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_map.py diff --git a/elevation_mapping_cupy/config/plugin_config.yaml b/elevation_mapping_cupy/config/plugin_config.yaml index 1e37308c..42dbc318 100644 --- a/elevation_mapping_cupy/config/plugin_config.yaml +++ b/elevation_mapping_cupy/config/plugin_config.yaml @@ -26,7 +26,7 @@ inpainting: extra_params: method: "telea" # telea or ns # Apply smoothing for inpainted layer -smooth_filter_1: +smooth_filter_1: type: "smooth_filter" enable: True fill_nan: False diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index 1a9e6642..f3a36d9e 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -4,10 +4,10 @@ subscribers: # fusion: ['average','average'] # topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: - channels: ['rgb','feat_0','feat_1','person','grass'] - fusion: ['color','average','average','class_average'] + channels: [] + fusion: [] topic_name: '/elvation_mapping/pointcloud_semantic' - semantic_segmentation: True + semantic_segmentation: False segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' feature_config: name: 'DINO' @@ -26,6 +26,7 @@ subscribers: cam_frame: "zed2i_right_camera_optical_frame" confidence_topic: "/zed2i/zed_node/confidence/confidence_map" confidence_threshold: 10 + feature_extractor: False diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py index 8c1ac90a..76dc2387 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py @@ -38,6 +38,7 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], + **kwargs, ) -> cp.ndarray: mask = cp.asnumpy((elevation_map[2] < 0.5).astype("uint8")) if (mask < 1).any(): diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py index 90eeafc1..e85dd8fc 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py @@ -94,6 +94,7 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], + **kwargs, ) -> cp.ndarray: self.min_filtered = elevation_map[0].copy() self.min_filtered_mask = elevation_map[2].copy() diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index 064d267d..145d1169 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -9,6 +9,7 @@ import inspect from dataclasses import dataclass from ruamel.yaml import YAML +from inspect import signature @dataclass @@ -38,6 +39,7 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], + **kwargs, ) -> cp.ndarray: """This gets the elevation map data and plugin layers as a cupy array. @@ -75,9 +77,15 @@ def init(self, plugin_params: List[PluginParams], extra_params: List[Dict]): self.plugins = [] for param, extra_param in zip(plugin_params, extra_params): - m = importlib.import_module("." + param.name, package="elevation_mapping_cupy.plugins") # -> 'module' + m = importlib.import_module( + "." + param.name, package="elevation_mapping_cupy.plugins" + ) # -> 'module' for name, obj in inspect.getmembers(m): - if inspect.isclass(obj) and issubclass(obj, PluginBase) and name != "PluginBase": + if ( + inspect.isclass(obj) + # and issubclass(obj, PluginBase) + and name != "PluginBase" + ): # Add cell_n to params extra_param["cell_n"] = self.cell_n self.plugins.append(obj(**extra_param)) @@ -102,6 +110,7 @@ def load_plugin_settings(self, file_path: str): ) ) extra_params.append(v["extra_params"]) + print(plugin_params) self.init(plugin_params, extra_params) print("Loaded plugins are ", *self.plugin_names) @@ -133,10 +142,38 @@ def get_layer_index_with_name(self, name: str) -> int: print("Error with layer {}: {}".format(name, e)) return None - def update_with_name(self, name: str, elevation_map: cp.ndarray, layer_names: List[str]): + def update_with_name( + self, + name: str, + elevation_map: cp.ndarray, + layer_names: List[str], + semantic_map=None, + transform=None, + ): idx = self.get_layer_index_with_name(name) if idx is not None: - self.layers[idx] = self.plugins[idx](elevation_map, layer_names, self.layers, self.layer_names) + n_param = len(signature(self.plugins[idx]).parameters) + if n_param == 5: + self.layers[idx] = self.plugins[idx]( + elevation_map, layer_names, self.layers, self.layer_names + ) + elif n_param == 6: + self.layers[idx] = self.plugins[idx]( + elevation_map, + layer_names, + self.layers, + self.layer_names, + semantic_map, + ) + else: + self.layers[idx] = self.plugins[idx]( + elevation_map, + layer_names, + self.layers, + self.layer_names, + semantic_map, + transform, + ) def get_map_with_name(self, name: str) -> cp.ndarray: idx = self.get_layer_index_with_name(name) @@ -154,17 +191,28 @@ def get_param_with_name(self, name: str) -> PluginParams: PluginParams(name="min_filter", layer_name="min_filter"), PluginParams(name="smooth_filter", layer_name="smooth"), ] - extra_params = [{"dilation_size": 5, "iteration_n": 5}, {"input_layer_name": "elevation2"}] + extra_params = [ + {"dilation_size": 5, "iteration_n": 5}, + {"input_layer_name": "elevation2"}, + ] manager = PluginManager(200) - manager.load_plugin_settings("config/plugin_config.yaml") + manager.load_plugin_settings("../config/plugin_config.yaml") print(manager.layer_names) print(manager.plugin_names) elevation_map = cp.zeros((7, 200, 200)).astype(cp.float32) - layer_names = ["elevation", "variance", "is_valid", "traversability", "time", "upper_bound", "is_upper_bound"] + layer_names = [ + "elevation", + "variance", + "is_valid", + "traversability", + "time", + "upper_bound", + "is_upper_bound", + ] elevation_map[0] = cp.random.randn(200, 200) elevation_map[2] = cp.abs(cp.random.randn(200, 200)) print("map", elevation_map[0]) print("layer map ", manager.layers[0]) manager.update_with_name("min_filter", elevation_map, layer_names) - manager.update_with_name("smooth_filter", elevation_map, layer_names) + manager.update_with_name("smooth", elevation_map, layer_names) print(manager.get_map_with_name("smooth")) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_map.py new file mode 100644 index 00000000..9579f8b6 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_map.py @@ -0,0 +1,53 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +from typing import List +import cupyx.scipy.ndimage as ndimage + +from .plugin_manager import PluginBase +from elevation_mapping_cupy.semantic_map import SemanticMap + +class SemanticFilter(PluginBase): + """This is a filter to create colors + + ... + + Attributes + ---------- + cell_n: int + width and height of the elevation map. + """ + + def __init__(self, cell_n: int = 100, input_layer_name: str = "elevation", **kwargs): + super().__init__() + self.input_layer_name = input_layer_name + self.indices = [] + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: SemanticMap, + **kwargs, + ) -> cp.ndarray: + # get indices of all layers that + semantic_map.param.additional_layers + # check which has the highest value + # create color coding + ################## + if self.input_layer_name in layer_names: + idx = layer_names.index(self.input_layer_name) + h = elevation_map[idx] + elif self.input_layer_name in plugin_layer_names: + idx = plugin_layer_names.index(self.input_layer_name) + h = plugin_layers[idx] + else: + print("layer name {} was not found. Using elevation layer.".format(self.input_layer_name)) + h = elevation_map[0] + hs1 = ndimage.uniform_filter(h, size=3) + hs1 = ndimage.uniform_filter(hs1, size=3) + return hs1 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py index d9ad76ac..5ac2f5c4 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py @@ -30,6 +30,7 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], + **kwargs, ) -> cp.ndarray: if self.input_layer_name in layer_names: idx = layer_names.index(self.input_layer_name) From 08160028ef28efd1d951d495bd2a8196833b15aa Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Thu, 3 Nov 2022 13:22:48 +0100 Subject: [PATCH 243/504] fixed two problems in pointcloud --- elevation_mapping_cupy/config/sensor_parameter.yaml | 5 +++-- .../script/semantic_pointcloud/pointcloud_node.py | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index 1a9e6642..a093c1f4 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -4,8 +4,8 @@ subscribers: # fusion: ['average','average'] # topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: - channels: ['rgb','feat_0','feat_1','person','grass'] - fusion: ['color','average','average','class_average'] + channels: [] + fusion: [] topic_name: '/elvation_mapping/pointcloud_semantic' semantic_segmentation: True segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' @@ -26,6 +26,7 @@ subscribers: cam_frame: "zed2i_right_camera_optical_frame" confidence_topic: "/zed2i/zed_node/confidence/confidence_map" confidence_threshold: 10 + feature_extractor: False diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index c22d8b41..e548deba 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -30,6 +30,8 @@ def __init__(self, sensor_name): # setup semantics self.feature_extractor = None self.semantic_model = None + self.segmentation_channels = None + self.feature_channels = None self.initialize_semantics() # setup pointcloud creation From ce611e5c8f1c43916884d626334207c441995326 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Fri, 4 Nov 2022 14:53:49 +0100 Subject: [PATCH 244/504] changed to float32, added the color plugin for the classes and added first plugin tests --- elevation_mapping_cupy/config/parameters.yaml | 2 +- .../config/plugin_config.yaml | 13 +++- .../config/sensor_parameter.yaml | 4 +- .../rviz/lonomy_single.rviz | 8 +-- .../elevation_mapping_cupy/custom_kernels.py | 7 +- .../elevation_mapping.py | 45 ++++++------ .../elevation_mapping_cupy/parameter.py | 1 + .../plugins/plugin_manager.py | 10 +-- .../plugins/semantic_filter.py | 71 +++++++++++++++++++ .../plugins/semantic_map.py | 53 -------------- .../elevation_mapping_cupy/semantic_map.py | 14 ++-- .../tests/test_elevation_mapping.py | 26 +++---- .../tests/test_plugins.py | 61 ++++++++++++++++ .../config/sensor_parameter.yaml | 2 +- 14 files changed, 207 insertions(+), 110 deletions(-) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py delete mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_map.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index dc59828d..945b1486 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -81,7 +81,7 @@ publishers: basic_layers: ['elevation', 'traversability'] fps: 2.0 elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb','person'] + layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb','sem_fil'] basic_layers: ['min_filter'] fps: 3.0 diff --git a/elevation_mapping_cupy/config/plugin_config.yaml b/elevation_mapping_cupy/config/plugin_config.yaml index 42dbc318..06d56bc4 100644 --- a/elevation_mapping_cupy/config/plugin_config.yaml +++ b/elevation_mapping_cupy/config/plugin_config.yaml @@ -18,7 +18,7 @@ smooth_filter: extra_params: input_layer_name: "min_filter" # Apply inpainting using opencv -inpainting: +inpainting: enable: True fill_nan: False is_height_layer: True @@ -34,3 +34,14 @@ smooth_filter_1: layer_name: "smooth_1" extra_params: input_layer_name: "inpaint" + +semantic_filter: + type: "semantic_filter" + enable: False + fill_nan: False + is_height_layer: False + layer_name: "sem_fil" + extra_params: +# TODO make a better link between classes and color + classes: ['grass','tree','fence','person'] + colors: [[0,255,0],[120,120,0],[170,0,20],[0,0,255],[255,0,0]] \ No newline at end of file diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index f3a36d9e..f2074eb7 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -4,8 +4,8 @@ subscribers: # fusion: ['average','average'] # topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: - channels: [] - fusion: [] + channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] + fusion: ['color','average','average','class_average','class_average','class_average','class_average'] topic_name: '/elvation_mapping/pointcloud_semantic' semantic_segmentation: False segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' diff --git a/elevation_mapping_cupy/rviz/lonomy_single.rviz b/elevation_mapping_cupy/rviz/lonomy_single.rviz index d35d1a1b..3474e971 100644 --- a/elevation_mapping_cupy/rviz/lonomy_single.rviz +++ b/elevation_mapping_cupy/rviz/lonomy_single.rviz @@ -55,8 +55,8 @@ Visualization Manager: Autocompute Intensity Bounds: true Class: grid_map_rviz_plugin/GridMap Color: 200; 200; 200 - Color Layer: person - Color Transformer: IntensityLayer + Color Layer: rgb + Color Transformer: ColorLayer Enabled: true Height Layer: smooth Height Transformer: GridMapLayer @@ -449,9 +449,9 @@ Visualization Manager: Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.5547983050346375 + Pitch: 0.6447982788085938 Target Frame: base_footprint - Yaw: 1.4138503074645996 + Yaw: 1.8688498735427856 Saved: ~ Window Geometry: Displays: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py index 8884660f..d8c53eac 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py @@ -665,7 +665,7 @@ def sum_kernel( # input the list of layers, amount of channels can slo be input through kernel sum_kernel = cp.ElementwiseKernel( in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params="raw U map, raw T newmap", + out_params="raw U map, raw U newmap", preamble=string.Template( """ __device__ int get_map_idx(int idx, int layer_n) { @@ -681,7 +681,7 @@ def sum_kernel( U inside = p[i * pcl_channels[0] + 2]; if (valid) { if (inside) { - for ( int it=0;it 0: t = masked.sum() / masked_isvalid.sum() else: - t = cp.asarray(0.0) + t = cp.asarray(0.0,dtype=self.data_type) is_safe, un_polygon = is_traversable( masked, self.param.safe_thresh, self.param.safe_min_thresh, self.param.max_unsafe_n ) @@ -662,7 +661,7 @@ def initialize_map(self, points, method="cubic"): """ self.clear() with self.map_lock: - points = cp.asarray(points) + points = cp.asarray(points,dtype=self.data_type) indices = transform_to_map_index(points[:, :2], self.center[:2], self.cell_n, self.resolution) points[:, :2] = indices.astype(points.dtype) points[:, 2] -= self.center[2] @@ -708,7 +707,7 @@ def initialize_map(self, points, method="cubic"): for layer in layers: elevation.get_map_with_name_ref(layer, data) print(i) - polygon = cp.array([[0, 0], [2, 0], [0, 2]], dtype=np.float64) + polygon = cp.array([[0, 0], [2, 0], [0, 2]], dtype=param.data_type) result = np.array([0, 0, 0]) elevation.get_polygon_traversability(polygon, result) print(result) \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 5b58620d..486e6caa 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -14,6 +14,7 @@ class Parameter(Serializable): additional_layers: list = ['feat_0'].copy fusion_algorithms: list = ['average'].copy cell_n: int = None + data_type: str = np.float32 map_length: float = 10.0 sensor_noise_factor: float = 0.05 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index 145d1169..26a076d9 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -89,8 +89,9 @@ def init(self, plugin_params: List[PluginParams], extra_params: List[Dict]): # Add cell_n to params extra_param["cell_n"] = self.cell_n self.plugins.append(obj(**extra_param)) - - self.layers = cp.zeros((len(self.plugins), self.cell_n, self.cell_n)) + self.layers = cp.zeros( + (len(self.plugins), self.cell_n, self.cell_n), dtype=cp.float32 + ) self.layer_names = self.get_layer_names() self.plugin_names = self.get_plugin_names() @@ -212,7 +213,8 @@ def get_param_with_name(self, name: str) -> PluginParams: elevation_map[0] = cp.random.randn(200, 200) elevation_map[2] = cp.abs(cp.random.randn(200, 200)) print("map", elevation_map[0]) - print("layer map ", manager.layers[0]) + print("layer map ", manager.layers) manager.update_with_name("min_filter", elevation_map, layer_names) - manager.update_with_name("smooth", elevation_map, layer_names) + manager.update_with_name("smooth_filter", elevation_map, layer_names) + # manager.update_with_name("sem_fil", elevation_map, layer_names, semantic_map=semantic_map) print(manager.get_map_with_name("smooth")) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py new file mode 100644 index 00000000..1fb86733 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -0,0 +1,71 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +from typing import List + +from elevation_mapping_cupy.plugins.plugin_manager import PluginBase + + +class SemanticFilter(PluginBase): + """This is a filter to create colors + + ... + + Attributes + ---------- + cell_n: int + width and height of the elevation map. + """ + + def __init__( + self, + cell_n: int = 100, + classes: list = ["person", "grass"], + colors: list = [ + [0, 255, 0], + [0, 255, 255], + [0, 0, 255], + [255, 255, 0], + [255, 0, 0], + ], + **kwargs, + ): + super().__init__() + self.indices = [] + self.classes = classes + color_classes = np.array(colors) + self.color_encoding = self.transform_color(color_classes) + + def transform_color(self, color_classes): + r = np.asarray(color_classes[:, 0], dtype=np.uint32) + g = np.asarray(color_classes[:, 1], dtype=np.uint32) + b = np.asarray(color_classes[:, 2], dtype=np.uint32) + rgb_arr = np.array((r << 16) | (g << 8) | (b << 0), dtype=np.uint32) + rgb_arr.dtype = np.float32 + return cp.asarray(rgb_arr) + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map, + **kwargs, + ) -> cp.ndarray: + # get indices of all layers that + layer_indices = cp.array([], dtype=cp.int32) + for it, fusion_alg in enumerate(semantic_map.param.fusion_algorithms): + if fusion_alg == "class_average" and ( + semantic_map.param.additional_layers[it] in self.classes + ): + layer_indices = cp.append(layer_indices, it).astype(cp.int32) + + # check which has the highest value + class_map = cp.argmax(semantic_map.map[layer_indices], axis=0) + # create color coding + enc = self.color_encoding[class_map] + return enc diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_map.py deleted file mode 100644 index 9579f8b6..00000000 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_map.py +++ /dev/null @@ -1,53 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -from typing import List -import cupyx.scipy.ndimage as ndimage - -from .plugin_manager import PluginBase -from elevation_mapping_cupy.semantic_map import SemanticMap - -class SemanticFilter(PluginBase): - """This is a filter to create colors - - ... - - Attributes - ---------- - cell_n: int - width and height of the elevation map. - """ - - def __init__(self, cell_n: int = 100, input_layer_name: str = "elevation", **kwargs): - super().__init__() - self.input_layer_name = input_layer_name - self.indices = [] - - def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - semantic_map: SemanticMap, - **kwargs, - ) -> cp.ndarray: - # get indices of all layers that - semantic_map.param.additional_layers - # check which has the highest value - # create color coding - ################## - if self.input_layer_name in layer_names: - idx = layer_names.index(self.input_layer_name) - h = elevation_map[idx] - elif self.input_layer_name in plugin_layer_names: - idx = plugin_layer_names.index(self.input_layer_name) - h = plugin_layers[idx] - else: - print("layer name {} was not found. Using elevation layer.".format(self.input_layer_name)) - h = elevation_map[0] - hs1 = ndimage.uniform_filter(h, size=3) - hs1 = ndimage.uniform_filter(hs1, size=3) - return hs1 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 9715d2d8..748fb7ba 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -25,11 +25,13 @@ def __init__(self, param: Parameter, layer_specs: dict): self.layer_specs = layer_specs self.amount_additional_layers = len(self.param.additional_layers) self.map = xp.zeros( - (self.amount_additional_layers, self.param.cell_n, self.param.cell_n) + (self.amount_additional_layers, self.param.cell_n, self.param.cell_n), + dtype=param.data_type, ) self.get_unique_fusion() self.new_map = xp.zeros( - (self.amount_additional_layers, self.param.cell_n, self.param.cell_n) + (self.amount_additional_layers, self.param.cell_n, self.param.cell_n), + param.data_type, ) self.color_map = None @@ -179,8 +181,7 @@ def update_layers(self, points_all, channels, R, t, elevation_map): dtype=np.uint32, ) self.color_map *= 0 - # TODO this is not a good solution - points_all = cp.asarray(cp.float32(points_all.get())) + points_all = points_all.astype(cp.float32) self.add_color_kernel( points_all, R, @@ -211,8 +212,9 @@ def get_map_with_name(self, name): def get_rgb(self, name): idx = self.param.additional_layers.index(name) c = self.process_map_for_publish(self.map[idx]) - c = xp.uint32(c.get()) - c.dtype = np.float32 + c = c.astype(np.float32) + # c = xp.uint32(c.get()) + # c.dtype = np.float32 return c def get_semantic(self, name): diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py index cafbe906..09db6d0d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -34,9 +34,9 @@ def test_init(self, elmap_ex): def test_input(self, elmap_ex): channels = ["x", "y", "z"] + elmap_ex.param.additional_layers - points = cp.random.rand(100000, len(channels)) - R = cp.random.rand(3, 3) - t = cp.random.rand(3) + points = cp.random.rand(100000, len(channels), dtype=elmap_ex.param.data_type) + R = cp.random.rand(3, 3, dtype=elmap_ex.param.data_type) + t = cp.random.rand(3, dtype=elmap_ex.param.data_type) elmap_ex.input(points, channels, R, t, 0, 0) def test_update_normal(self, elmap_ex): @@ -62,22 +62,22 @@ def test_get_map(self, elmap_ex): for layer in layers: elmap_ex.get_map_with_name_ref(layer, data) - def test_get_position(self,elmap_ex): - pos = np.random.rand(1,3) + def test_get_position(self, elmap_ex): + pos = np.random.rand(1, 3) elmap_ex.get_position(pos) - def test_clear(self,elmap_ex): + def test_clear(self, elmap_ex): elmap_ex.clear() - def test_move(self,elmap_ex): + def test_move(self, elmap_ex): delta_position = np.random.rand(3) elmap_ex.move(delta_position) - def test_exists_layer(self,elmap_ex, add_lay): + def test_exists_layer(self, elmap_ex, add_lay): for layer in add_lay: assert elmap_ex.exists_layer(layer) - def test_polygon_traversability(self,elmap_ex): + def test_polygon_traversability(self, elmap_ex): polygon = cp.array([[0, 0], [2, 0], [0, 2]], dtype=np.float64) result = np.array([0, 0, 0]) number_polygons = elmap_ex.get_polygon_traversability(polygon, result) @@ -85,7 +85,9 @@ def test_polygon_traversability(self,elmap_ex): elmap_ex.get_untraversable_polygon(untraversable_polygon) def test_initialize_map(self, elmap_ex): - methods = ['linear', 'cubic', 'nearest'] + methods = ["linear", "cubic", "nearest"] for method in methods: - points = np.array([[-4.0, 0.0, 0.0],[-4.0, 8.0, 1.0],[4.0, 8.0, 0.0],[4.0, 0.0, 0.0]]) - elmap_ex.initialize_map(points,method) + points = np.array( + [[-4.0, 0.0, 0.0], [-4.0, 8.0, 1.0], [4.0, 8.0, 0.0], [4.0, 0.0, 0.0]] + ) + elmap_ex.initialize_map(points, method) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py new file mode 100644 index 00000000..cbd8c091 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -0,0 +1,61 @@ +import pytest +from elevation_mapping_cupy import semantic_map, parameter +import cupy as cp +import numpy as np +from elevation_mapping_cupy.plugins.plugin_manager import PluginManager, PluginParams + +plugin_path = "../../../config/plugin_config.yaml" + + +@pytest.fixture() +def semmap_ex(add_lay, fusion_alg): + additional_layer = add_lay + fusion_algorithms = fusion_alg + p = parameter.Parameter( + use_chainer=False, + weight_file="../../../config/weights.dat", + plugin_config_file=plugin_path, + ) + p.additional_layers = additional_layer + p.fusion_algorithms = fusion_algorithms + additional_layers = dict(zip(p.additional_layers, p.fusion_algorithms)) + p.cell_n = int(round(p.map_length / p.resolution)) + 2 + + e = semantic_map.SemanticMap(p, additional_layers) + return e + + +@pytest.mark.parametrize( + "add_lay, fusion_alg,channels", + [ + (["feat_0", "feat_1"], ["average", "average"], ["feat_0"]), + (["feat_0", "feat_1"], ["average", "average"], []), + ( + ["feat_0", "feat_1", "rgb"], + ["average", "average", "color"], + ["rgb", "feat_0"], + ), + ], +) +def test_plugin_manager(semmap_ex, channels): + manager = PluginManager(200) + manager.load_plugin_settings(plugin_path) + elevation_map = cp.zeros((7, 200, 200)).astype(cp.float32) + layer_names = [ + "elevation", + "variance", + "is_valid", + "traversability", + "time", + "upper_bound", + "is_upper_bound", + ] + elevation_map[0] = cp.random.randn(200, 200) + elevation_map[2] = cp.abs(cp.random.randn(200, 200)) + elevation_map[0] + manager.layers[0] + manager.update_with_name("min_filter", elevation_map, layer_names) + manager.update_with_name("smooth_filter", elevation_map, layer_names) + manager.update_with_name("semantic_filter", elevation_map, layer_names) + + manager.get_map_with_name("smooth") diff --git a/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml b/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml index e0291601..0c50c619 100644 --- a/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml +++ b/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml @@ -5,7 +5,7 @@ subscribers: # topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: channels: ['rgb','feat_0','feat_1','person','grass'] - fusion: ['color','average','average','class_average'] + fusion: ['color','average','average','class_average','class_average'] topic_name: '/elvation_mapping/pointcloud_semantic' semantic_segmentation: True segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' From 13da5d8f6dfaaee8d29a8d815d72f5a6611e0ce5 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Fri, 4 Nov 2022 15:10:59 +0100 Subject: [PATCH 245/504] added self hosted pipeline --- .github/workflows/python-tests.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 2159664e..9457ef2c 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -4,7 +4,7 @@ name: Python testing on: push: - branches: [ "feature/2_semantic_python" ] + branches: [ "feature/2_semantic_python", "feature/**"] # pull_request: # branches: [ "main" ] @@ -14,7 +14,8 @@ permissions: jobs: build: - runs-on: ubuntu-latest +# runs-on: ubuntu-latest + runs-on: [self-hosted, linux, x64] steps: - uses: actions/checkout@v3 From 9ba5d526386798f9fa114941604fa7fe3a591aea Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Fri, 4 Nov 2022 15:11:19 +0100 Subject: [PATCH 246/504] added self hosted pipeline --- .github/workflows/python-tests.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 9457ef2c..70ef3eb9 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -28,7 +28,11 @@ jobs: python -m pip install --upgrade pip pip install pytest cupy if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - name: Test with pytest + - name: Test elevation mapping with pytest run: | cd elevation_mapping_cupy/script/elevation_mapping_cupy/tests/ + pytest + - name: Test semantic_pointcloud with pytest + run: | + cd sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests pytest \ No newline at end of file From 6be9eb5e952fd9a24a0e5c7decbe8dd0318c4fca Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Fri, 4 Nov 2022 15:15:51 +0100 Subject: [PATCH 247/504] changed the runner labels --- .github/workflows/python-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 70ef3eb9..89fdcb30 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -15,7 +15,7 @@ jobs: build: # runs-on: ubuntu-latest - runs-on: [self-hosted, linux, x64] + runs-on: [self-hosted, Linux, X64] steps: - uses: actions/checkout@v3 From 8474abe9e57278f8a3a6be719cbc4742873ab08c Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Sun, 6 Nov 2022 21:10:05 -0800 Subject: [PATCH 248/504] added matias changes --- .gitignore | 4 +++- elevation_mapping_cupy/config/parameters.yaml | 6 +++--- .../config/sensor_parameter.yaml | 20 +++++++++++++++++++ .../launch/elevation_mapping_cupy.launch | 1 + 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 0f73a391..ed51360f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ *.pyc *.bkp *.orig -.idea \ No newline at end of file +.idea* +.vscode* +*.egg-info \ No newline at end of file diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index c25e0ec2..91cd65bc 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -40,9 +40,9 @@ max_unsafe_n: 10 # if the number of cells under s overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) -map_frame: 'enu' # The map frame where the odometry source uses. -base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'enu' +map_frame: 'odom' # The map frame where the odometry source uses. +base_frame: 'base' # The robot's base frame. This frame will be a center of the map. +corrected_map_frame: 'odom_corrected' #### Feature toggles ######## enable_edge_sharpen: true diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index b39e5743..d6da2276 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -7,3 +7,23 @@ subscribers: channels: ['feat_0','feat_1'] fusion: ['average','average'] topic_name: '/elvation_mapping/pointcloud_semantic' + + front_depth: + channels: [] + fusion: ['average'] + topic_name: /depth_camera_front/point_cloud_self_filtered + + rear_depth: + channels: [] + fusion: ['average'] + topic_name: /depth_camera_rear/point_cloud_self_filtered + + left_depth: + channels: [] + fusion: ['average'] + topic_name: /depth_camera_left/point_cloud_self_filtered + + right_depth: + channels: [] + fusion: ['average'] + topic_name: /depth_camera_right/point_cloud_self_filtered \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch index 023962f8..ca49e6e3 100644 --- a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch +++ b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch @@ -2,5 +2,6 @@ + From 26b7f78f16d9a030e1eb8f55eb4e2fcc364efe08 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Mon, 7 Nov 2022 15:38:59 +0100 Subject: [PATCH 249/504] added two plugins: semantic_filter and robot_centric_elevation, I changed a bit the plugin manager to accept different arguments. The datatype has been changed to float32, removed lonomy related files, added a few tests --- elevation_mapping_cupy/config/parameters.yaml | 10 +- .../config/plugin_config.yaml | 12 +- .../config/sensor_parameter.yaml | 21 +- .../semantic_elevation_lonomy_single.launch | 21 - .../launch/turtlesim_pointcloud.launch | 19 + .../turtlesim_semantic_elevation.launch | 19 + .../rviz/lonomy_single.rviz | 475 ------------------ .../rviz/turtle_semantic_example.rviz | 264 ++++++++++ .../elevation_mapping.py | 9 +- .../plugins/inpainting.py | 2 +- .../plugins/min_filter.py | 2 +- .../plugins/plugin_manager.py | 6 +- .../plugins/robot_centric_elevation.py | 96 ++++ .../plugins/semantic_filter.py | 2 +- .../plugins/smooth_filter.py | 2 +- .../elevation_mapping_cupy/semantic_map.py | 1 - .../tests/test_elevation_mapping.py | 6 + .../tests/test_parameter.py | 18 + .../tests/test_plugins.py | 8 +- .../semantic_pointcloud/pointcloud_node.py | 55 +- .../pointcloud_parameters.py | 1 + 21 files changed, 506 insertions(+), 543 deletions(-) delete mode 100644 elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch create mode 100644 elevation_mapping_cupy/launch/turtlesim_pointcloud.launch create mode 100644 elevation_mapping_cupy/launch/turtlesim_semantic_elevation.launch delete mode 100644 elevation_mapping_cupy/rviz/lonomy_single.rviz create mode 100644 elevation_mapping_cupy/rviz/turtle_semantic_example.rviz create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_parameter.py diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index 945b1486..9d49f189 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -40,9 +40,9 @@ max_unsafe_n: 10 # if the number of cells under s overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) -map_frame: 'enu' # The map frame where the odometry source uses. +map_frame: 'odom' # The map frame where the odometry source uses. base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'enu' +corrected_map_frame: 'corrected_odom' #### Feature toggles ######## enable_edge_sharpen: true @@ -81,14 +81,14 @@ publishers: basic_layers: ['elevation', 'traversability'] fps: 2.0 elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb','sem_fil'] + layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb'] basic_layers: ['min_filter'] fps: 3.0 #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. +initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [0.0] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 5 # dilation size after the init. initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/plugin_config.yaml b/elevation_mapping_cupy/config/plugin_config.yaml index 06d56bc4..33ed355c 100644 --- a/elevation_mapping_cupy/config/plugin_config.yaml +++ b/elevation_mapping_cupy/config/plugin_config.yaml @@ -34,7 +34,17 @@ smooth_filter_1: layer_name: "smooth_1" extra_params: input_layer_name: "inpaint" - +robot_centric_elevation: # Use the same name as your file name. +# type: "robot_centric_elevation" + enable: False # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "robot_centric_elevation" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. +# add_value: 2.0 # Example param + resolution: 0.04 + threshold: 1.1 + use_threshold: True semantic_filter: type: "semantic_filter" enable: False diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index f2074eb7..defea85f 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -1,8 +1,10 @@ subscribers: -# sensor_name: -# channels: ['feat_0','feat_1'] -# fusion: ['average','average'] -# topic_name: '/elevation_mapping/pointcloud_semantic' +# sensor_name: #if you have multiple sensors assign different names +# channels: ['features','person'] # names of the channels, for sem seg it should be the same name as the + # pretrained network uses +# fusion: ['average','class_average'] # the fusion algorithm type used. + # Pick between: ['color', 'average','class_average'] +# topic_name: '/elevation_mapping/pointcloud_semantic' # of the published pointcloud subscribed by the el_map front_cam: channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] fusion: ['color','average','average','class_average','class_average','class_average','class_average'] @@ -20,11 +22,12 @@ subscribers: input_size: [80, 160] projection_type: "nonlinear" - cam_info_topic: "/zed2i/zed_node/depth/camera_info" - image_topic: "/zed2i/zed_node/left/image_rect_color" - depth_topic: "/zed2i/zed_node/depth/depth_registered" - cam_frame: "zed2i_right_camera_optical_frame" - confidence_topic: "/zed2i/zed_node/confidence/confidence_map" + cam_info_topic: "/camera/depth/camera_info" + image_topic: "/camera/rgb/image_raw" + depth_topic: "/camera/depth/image_raw" + cam_frame: camera_rgb_optical_frame + confidence: False + confidence_topic: "/camera/depth/image_raw" confidence_threshold: 10 feature_extractor: False diff --git a/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch b/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch deleted file mode 100644 index 0e644e44..00000000 --- a/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch b/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch new file mode 100644 index 00000000..e7b73dde --- /dev/null +++ b/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_elevation.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_elevation.launch new file mode 100644 index 00000000..98940264 --- /dev/null +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_elevation.launch @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/elevation_mapping_cupy/rviz/lonomy_single.rviz b/elevation_mapping_cupy/rviz/lonomy_single.rviz deleted file mode 100644 index 3474e971..00000000 --- a/elevation_mapping_cupy/rviz/lonomy_single.rviz +++ /dev/null @@ -1,475 +0,0 @@ -Panels: - - Class: rviz/Displays - Help Height: 138 - Name: Displays - Property Tree Widget: - Expanded: - - /ElevationMapFilter1 - - /Image1 - Splitter Ratio: 0.5768463015556335 - Tree Height: 428 - - Class: rviz/Selection - Name: Selection - - Class: rviz/Tool Properties - Expanded: - - /2D Pose Estimate1 - - /2D Nav Goal1 - - /Publish Point1 - Name: Tool Properties - Splitter Ratio: 0.5886790156364441 - - Class: rviz/Views - Expanded: - - /Current View1 - Name: Views - Splitter Ratio: 0.5 - - Class: rviz/Time - Name: Time - SyncMode: 0 - SyncSource: Image -Preferences: - PromptSaveOnExit: true -Toolbars: - toolButtonStyle: 2 -Visualization Manager: - Class: "" - Displays: - - Alpha: 0.5 - Cell Size: 1 - Class: rviz/Grid - Color: 160; 160; 164 - Enabled: true - Line Style: - Line Width: 0.029999999329447746 - Value: Lines - Name: Grid - Normal Cell Count: 0 - Offset: - X: 0 - Y: 0 - Z: 0 - Plane: XY - Plane Cell Count: 10 - Reference Frame: - Value: true - - Alpha: 1 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: rgb - Color Transformer: ColorLayer - Enabled: true - Height Layer: smooth - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 204; 0; 0 - Max Intensity: 10 - Min Color: 52; 101; 164 - Min Intensity: 0 - Name: ElevationMapFilter - Show Grid Lines: true - Topic: /elevation_mapping/elevation_map_filter - Unreliable: false - Use Rainbow: false - Value: true - - Alpha: 1 - Class: rviz/RobotModel - Collision Enabled: false - Enabled: true - Links: - All Links Enabled: true - Expand Joint Details: false - Expand Link Details: false - Expand Tree: false - GPS_back: - Alpha: 1 - Show Axes: false - Show Trail: false - GPS_front: - Alpha: 1 - Show Axes: false - Show Trail: false - Link Tree Style: Links in Alphabetic Order - alphasense: - Alpha: 1 - Show Axes: false - Show Trail: false - base_footprint: - Alpha: 1 - Show Axes: false - Show Trail: false - base_inertial: - Alpha: 1 - Show Axes: false - Show Trail: false - base_link: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - estimator_imu: - Alpha: 1 - Show Axes: false - Show Trail: false - left_back_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - left_back_wheel_sup: - Alpha: 1 - Show Axes: false - Show Trail: false - left_front_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - left_front_wheel_sup: - Alpha: 1 - Show Axes: false - Show Trail: false - rear_axle_center: - Alpha: 1 - Show Axes: false - Show Trail: false - right_back_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - right_back_wheel_sup: - Alpha: 1 - Show Axes: false - Show Trail: false - right_front_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - right_front_wheel_sup: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_baro_link: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_base_link: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_camera_center: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - zed2i_left_camera_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_left_camera_optical_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_mag_link: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_right_camera_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_right_camera_optical_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_temp_left_link: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_temp_right_link: - Alpha: 1 - Show Axes: false - Show Trail: false - Name: RobotModel - Robot Description: robot_description - TF Prefix: "" - Update Interval: 0 - Value: true - Visual Enabled: true - - Alpha: 1 - Autocompute Intensity Bounds: true - Autocompute Value Bounds: - Max Value: 10 - Min Value: -10 - Value: true - Axis: Z - Channel Name: intensity - Class: rviz/PointCloud2 - Color: 255; 255; 255 - Color Transformer: RGB8 - Decay Time: 0 - Enabled: false - Invert Rainbow: false - Max Color: 255; 255; 255 - Min Color: 0; 0; 0 - Name: PointCloud2 - Position Transformer: XYZ - Queue Size: 10 - Selectable: true - Size (Pixels): 3 - Size (m): 0.009999999776482582 - Style: Flat Squares - Topic: /elvation_mapping/pointcloud_semantic - Unreliable: false - Use Fixed Frame: true - Use rainbow: true - Value: false - - Alpha: 1 - Autocompute Intensity Bounds: true - Autocompute Value Bounds: - Max Value: 10 - Min Value: -10 - Value: true - Axis: Z - Channel Name: intensity - Class: rviz/PointCloud2 - Color: 255; 255; 255 - Color Transformer: RGB8 - Decay Time: 0 - Enabled: false - Invert Rainbow: false - Max Color: 255; 255; 255 - Min Color: 0; 0; 0 - Name: PointCloud2 - Position Transformer: XYZ - Queue Size: 10 - Selectable: true - Size (Pixels): 3 - Size (m): 0.009999999776482582 - Style: Flat Squares - Topic: /elvation_mapping/pointcloud_semantic_right - Unreliable: false - Use Fixed Frame: true - Use rainbow: true - Value: false - - Class: rviz/TF - Enabled: true - Frame Timeout: 15 - Frames: - All Enabled: true - GPS_back: - Value: true - GPS_front: - Value: true - alphasense: - Value: true - base_footprint: - Value: true - base_inertial: - Value: true - base_link: - Value: true - enu: - Value: true - estimator_imu: - Value: true - left_back_wheel: - Value: true - left_back_wheel_sup: - Value: true - left_front_wheel: - Value: true - left_front_wheel_sup: - Value: true - rear_axle_center: - Value: true - right_back_wheel: - Value: true - right_back_wheel_sup: - Value: true - right_front_wheel: - Value: true - right_front_wheel_sup: - Value: true - zed2i_baro_link: - Value: true - zed2i_base_link: - Value: true - zed2i_camera_center: - Value: true - zed2i_left_camera_frame: - Value: true - zed2i_left_camera_optical_frame: - Value: true - zed2i_mag_link: - Value: true - zed2i_right_camera_frame: - Value: true - zed2i_right_camera_optical_frame: - Value: true - zed2i_temp_left_link: - Value: true - zed2i_temp_right_link: - Value: true - Marker Alpha: 1 - Marker Scale: 1 - Name: TF - Show Arrows: true - Show Axes: true - Show Names: true - Tree: - enu: - base_link: - base_footprint: - {} - base_inertial: - {} - estimator_imu: - GPS_back: - {} - GPS_front: - {} - alphasense: - {} - left_back_wheel_sup: - left_back_wheel: - {} - left_front_wheel_sup: - left_front_wheel: - {} - rear_axle_center: - {} - right_back_wheel_sup: - right_back_wheel: - {} - right_front_wheel_sup: - right_front_wheel: - {} - zed2i_base_link: - zed2i_camera_center: - zed2i_baro_link: - {} - zed2i_left_camera_frame: - zed2i_left_camera_optical_frame: - {} - zed2i_temp_left_link: - {} - zed2i_mag_link: - {} - zed2i_right_camera_frame: - zed2i_right_camera_optical_frame: - {} - zed2i_temp_right_link: - {} - Update Interval: 0 - Value: true - - Class: rviz/Image - Enabled: true - Image Topic: /zed2i/zed_node/left/image_rect_color - Max Value: 1 - Median window: 5 - Min Value: 0 - Name: Image - Normalize Range: true - Queue Size: 2 - Transport Hint: raw - Unreliable: false - Value: true - - Class: rviz/Image - Enabled: false - Image Topic: /zed2i_right/zed_right_node/left_raw/image_raw_color - Max Value: 1 - Median window: 5 - Min Value: 0 - Name: Image - Normalize Range: true - Queue Size: 2 - Transport Hint: raw - Unreliable: false - Value: false - - Class: rviz/Marker - Enabled: true - Marker Topic: /visualization_marker_l - Name: Marker - Namespaces: - {} - Queue Size: 100 - Value: true - - Class: rviz/Marker - Enabled: true - Marker Topic: /visualization_marker_r - Name: Marker - Namespaces: - {} - Queue Size: 100 - Value: true - Enabled: true - Global Options: - Background Color: 255; 255; 255 - Default Light: true - Fixed Frame: enu - Frame Rate: 30 - Name: root - Tools: - - Class: rviz/Interact - Hide Inactive Objects: true - - Class: rviz/MoveCamera - - Class: rviz/Select - - Class: rviz/FocusCamera - - Class: rviz/Measure - - Class: rviz/SetInitialPose - Theta std deviation: 0.2617993950843811 - Topic: /initialpose - X std deviation: 0.5 - Y std deviation: 0.5 - - Class: rviz/SetGoal - Topic: /move_base_simple/goal - - Class: rviz/PublishPoint - Single click: true - Topic: /clicked_point - Value: true - Views: - Current: - Class: rviz/Orbit - Distance: 7.847433090209961 - Enable Stereo Rendering: - Stereo Eye Separation: 0.05999999865889549 - Stereo Focal Distance: 1 - Swap Stereo Eyes: false - Value: false - Field of View: 0.7853981852531433 - Focal Point: - X: 0.7929360866546631 - Y: 0.3796532452106476 - Z: -0.4990573823451996 - Focal Shape Fixed Size: true - Focal Shape Size: 0.05000000074505806 - Invert Z Axis: false - Name: Current View - Near Clip Distance: 0.009999999776482582 - Pitch: 0.6447982788085938 - Target Frame: base_footprint - Yaw: 1.8688498735427856 - Saved: ~ -Window Geometry: - Displays: - collapsed: false - Height: 1043 - Hide Left Dock: false - Hide Right Dock: true - Image: - collapsed: false - QMainWindow State: 000000ff00000000fd0000000400000000000001f5000003b9fc0200000009fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000273000000c900fffffffb0000000a0049006d00610067006501000002b6000001400000001600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000073800000131fc0100000003fb0000000a0049006d0061006700650000000394000003a40000005e00fffffffb0000000800540069006d00650000000000000007380000041800fffffffb0000000800540069006d0065010000000000000450000000000000000000000585000003b900000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 - Selection: - collapsed: false - Time: - collapsed: false - Tool Properties: - collapsed: false - Views: - collapsed: true - Width: 1920 - X: 0 - Y: 0 diff --git a/elevation_mapping_cupy/rviz/turtle_semantic_example.rviz b/elevation_mapping_cupy/rviz/turtle_semantic_example.rviz new file mode 100644 index 00000000..91da7819 --- /dev/null +++ b/elevation_mapping_cupy/rviz/turtle_semantic_example.rviz @@ -0,0 +1,264 @@ +Panels: + - Class: rviz/Displays + Help Height: 138 + Name: Displays + Property Tree Widget: + Expanded: + - /Global Options1 + - /ElevationMapFilter1 + Splitter Ratio: 0.5768463015556335 + Tree Height: 631 + - Class: rviz/Selection + Name: Selection + - Class: rviz/Tool Properties + Expanded: + - /2D Pose Estimate1 + - /2D Nav Goal1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz/Time + Name: Time + SyncMode: 0 + SyncSource: "" +Preferences: + PromptSaveOnExit: true +Toolbars: + toolButtonStyle: 2 +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.029999999329447746 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Alpha: 1 + Autocompute Intensity Bounds: false + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: traversability + Color Transformer: "" + Enabled: false + Height Layer: elevation + Height Transformer: "" + History Length: 1 + Invert Rainbow: false + Max Color: 238; 238; 236 + Max Intensity: 1 + Min Color: 32; 74; 135 + Min Intensity: 0 + Name: ElevationMapRaw + Show Grid Lines: true + Topic: /elevation_mapping/elevation_map_raw + Unreliable: false + Use Rainbow: false + Value: false + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: rgb + Color Transformer: ColorLayer + Enabled: true + Height Layer: min_filter + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 206; 92; 0 + Max Intensity: 10 + Min Color: 255; 255; 255 + Min Intensity: 0 + Name: ElevationMapFilter + Show Grid Lines: true + Topic: /elevation_mapping/elevation_map_filter + Unreliable: false + Use Rainbow: false + Value: true + - Alpha: 1 + Class: rviz/RobotModel + Collision Enabled: false + Enabled: true + Links: + All Links Enabled: true + Expand Joint Details: false + Expand Link Details: false + Expand Tree: false + Link Tree Style: Links in Alphabetic Order + base_footprint: + Alpha: 1 + Show Axes: false + Show Trail: false + base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + base_scan: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + camera_depth_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + camera_depth_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + camera_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + camera_rgb_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + camera_rgb_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + caster_back_left_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + caster_back_right_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + imu_link: + Alpha: 1 + Show Axes: false + Show Trail: false + wheel_left_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + wheel_right_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + Name: RobotModel + Robot Description: robot_description + TF Prefix: "" + Update Interval: 0 + Value: true + Visual Enabled: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Autocompute Value Bounds: + Max Value: 10 + Min Value: -10 + Value: true + Axis: Z + Channel Name: intensity + Class: rviz/PointCloud2 + Color: 255; 255; 255 + Color Transformer: RGB8 + Decay Time: 0 + Enabled: false + Invert Rainbow: false + Max Color: 255; 255; 255 + Min Color: 0; 0; 0 + Name: PointCloud2 + Position Transformer: XYZ + Queue Size: 10 + Selectable: true + Size (Pixels): 3 + Size (m): 0.009999999776482582 + Style: Flat Squares + Topic: /camera/depth/points + Unreliable: false + Use Fixed Frame: true + Use rainbow: true + Value: false + Enabled: true + Global Options: + Background Color: 255; 255; 255 + Default Light: true + Fixed Frame: odom + Frame Rate: 30 + Name: root + Tools: + - Class: rviz/Interact + Hide Inactive Objects: true + - Class: rviz/MoveCamera + - Class: rviz/Select + - Class: rviz/FocusCamera + - Class: rviz/Measure + - Class: rviz/SetInitialPose + Theta std deviation: 0.2617993950843811 + Topic: /initialpose + X std deviation: 0.5 + Y std deviation: 0.5 + - Class: rviz/SetGoal + Topic: /move_base_simple/goal + - Class: rviz/PublishPoint + Single click: true + Topic: /clicked_point + Value: true + Views: + Current: + Class: rviz/Orbit + Distance: 3.499889373779297 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Field of View: 0.7853981852531433 + Focal Point: + X: 2.046891927719116 + Y: -0.5291382074356079 + Z: -0.3964909017086029 + Focal Shape Fixed Size: true + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 0.4947965741157532 + Target Frame: base_footprint + Yaw: 2.893369436264038 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 1016 + Hide Left Dock: false + Hide Right Dock: true + QMainWindow State: 000000ff00000000fd0000000400000000000001f70000033efc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000033e000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007380000005afc0100000002fb0000000800540069006d0065010000000000000738000003bc00fffffffb0000000800540069006d006501000000000000045000000000000000000000053b0000033e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: true + Width: 1848 + X: 1992 + Y: 27 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 69e5b1f1..a3310ba4 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -51,6 +51,7 @@ def __init__(self, param: Parameter): self.data_type = self.param.data_type self.resolution = param.resolution self.center = xp.array([0, 0, 0], dtype=self.data_type) + self.base_rotation = xp.eye(3, dtype=self.data_type) self.map_length = param.map_length self.cell_n = param.cell_n @@ -70,7 +71,7 @@ def __init__(self, param: Parameter): # buffers self.traversability_buffer = xp.full((self.cell_n, self.cell_n), xp.nan) - self.normal_map = xp.zeros((3, self.cell_n, self.cell_n),dtype=self.data_type) + self.normal_map = xp.zeros((3, self.cell_n, self.cell_n), dtype=self.data_type) # Initial variance self.initial_variance = param.initial_variance self.elevation_map[1] += self.initial_variance @@ -149,7 +150,7 @@ def move_to(self, position, R): R (cupy._core.core.ndarray): """ # Shift map to the center of robot. - self.base_rotation = xp.asarray(R) + self.base_rotation = xp.asarray(R,dtype=self.data_type) position = xp.asarray(position) delta = position - self.center delta_pixel = xp.around(delta[:2] / self.resolution) @@ -560,7 +561,7 @@ def get_map_with_name_ref(self, name, data): elif name in self.additional_layers.keys(): m = self.semantic_map.get_map_with_name(name) elif name in self.plugin_manager.layer_names: - self.plugin_manager.update_with_name(name, self.elevation_map, self.layer_names, self.semantic_map) + self.plugin_manager.update_with_name(name, self.elevation_map, self.layer_names, self.semantic_map, self.base_rotation) m = self.plugin_manager.get_map_with_name(name) p = self.plugin_manager.get_param_with_name(name) xp = self.xp_of_array(m) @@ -710,4 +711,4 @@ def initialize_map(self, points, method="cubic"): polygon = cp.array([[0, 0], [2, 0], [0, 2]], dtype=param.data_type) result = np.array([0, 0, 0]) elevation.get_polygon_traversability(polygon, result) - print(result) \ No newline at end of file + print(result) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py index 76dc2387..247041b6 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py @@ -38,7 +38,7 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], - **kwargs, + *args, ) -> cp.ndarray: mask = cp.asnumpy((elevation_map[2] < 0.5).astype("uint8")) if (mask < 1).any(): diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py index e85dd8fc..f50147f6 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py @@ -94,7 +94,7 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], - **kwargs, + *args, ) -> cp.ndarray: self.min_filtered = elevation_map[0].copy() self.min_filtered_mask = elevation_map[2].copy() diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index 26a076d9..b29375cd 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -39,6 +39,7 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], + *args, **kwargs, ) -> cp.ndarray: """This gets the elevation map data and plugin layers as a cupy array. @@ -111,7 +112,6 @@ def load_plugin_settings(self, file_path: str): ) ) extra_params.append(v["extra_params"]) - print(plugin_params) self.init(plugin_params, extra_params) print("Loaded plugins are ", *self.plugin_names) @@ -149,7 +149,7 @@ def update_with_name( elevation_map: cp.ndarray, layer_names: List[str], semantic_map=None, - transform=None, + rotation=None, ): idx = self.get_layer_index_with_name(name) if idx is not None: @@ -173,7 +173,7 @@ def update_with_name( self.layers, self.layer_names, semantic_map, - transform, + rotation, ) def get_map_with_name(self, name: str) -> cp.ndarray: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py new file mode 100644 index 00000000..41d963ce --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py @@ -0,0 +1,96 @@ +import cupy as cp +import string +from typing import List +from .plugin_manager import PluginBase + + +class RobotCentricElevation(PluginBase): + def __init__( + self, cell_n: int = 100, resolution: float = 0.05, threshold: float = 0.4, use_threshold: bool = 0, **kwargs + ): + super().__init__() + self.width = cell_n + self.height = cell_n + self.min_filtered = cp.zeros((self.width, self.height),dtype=cp.float32) + + self.base_elevation_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U mask, raw U R", + out_params="raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x <= 0 || idx_x >= ${width} - 1) { + return false; + } + if (idx_y <= 0 || idx_y >= ${height} - 1) { + return false; + } + return true; + } + __device__ float get_map_x(int idx){ + float idx_x = idx / ${width}* ${resolution}; + return idx_x; + } + __device__ float get_map_y(int idx){ + float idx_y = idx % ${width}* ${resolution}; + return idx_y; + } + __device__ float transform_p(float x, float y, float z, + float r0, float r1, float r2) { + return r0 * x + r1 * y + r2 * z ; + } + """ + ).substitute(width=self.width, height=self.height, resolution=resolution), + operation=string.Template( + """ + U rz = map[get_map_idx(i, 0)]; + U valid = mask[get_map_idx(i, 0)]; + if (valid > 0.5) { + U rx = get_map_x(get_map_idx(i, 0)); + U ry = get_map_y(get_map_idx(i, 0)); + U x_b = transform_p(rx, ry, rz, R[0], R[1], R[2]); + U y_b = transform_p(rx, ry, rz, R[3], R[4], R[5]); + U z_b = transform_p(rx, ry, rz, R[6], R[7], R[8]); + if (${use_threshold} && z_b>= ${threshold} ) { + newmap[get_map_idx(i, 0)] = 1.0; + } + else if (${use_threshold} && z_b< ${threshold} ){ + newmap[get_map_idx(i, 0)] = 0.0; + } + else{ + newmap[get_map_idx(i, 0)] = z_b; + } + } + """ + ).substitute(threshold=threshold, use_threshold=int(use_threshold)), + name="base_elevation_kernel", + ) + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map, + rotation, + *args, + ) -> cp.ndarray: + # Process maps here + # check that transform is a ndarray + self.min_filtered = elevation_map[0].copy() + self.base_elevation_kernel( + elevation_map[0], + elevation_map[2], + rotation, + self.min_filtered, + size=(self.width * self.height), + ) + return self.min_filtered diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index 1fb86733..d91b15fb 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -54,7 +54,7 @@ def __call__( plugin_layers: cp.ndarray, plugin_layer_names: List[str], semantic_map, - **kwargs, + *args, ) -> cp.ndarray: # get indices of all layers that layer_indices = cp.array([], dtype=cp.int32) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py index 5ac2f5c4..65334452 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py @@ -30,7 +30,7 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], - **kwargs, + *args, ) -> cp.ndarray: if self.input_layer_name in layer_names: idx = layer_names.index(self.input_layer_name) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 748fb7ba..e8c3a4af 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -40,7 +40,6 @@ def get_unique_fusion(self): for x in list(self.layer_specs.values()): if x not in self.unique_fusion: self.unique_fusion.append(x) - print("Fusion algorithms running: ", self.unique_fusion) def compile_kernels(self) -> None: """ diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py index 09db6d0d..95a8b1a4 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -91,3 +91,9 @@ def test_initialize_map(self, elmap_ex): [[-4.0, 0.0, 0.0], [-4.0, 8.0, 1.0], [4.0, 8.0, 0.0], [4.0, 0.0, 0.0]] ) elmap_ex.initialize_map(points, method) + + def test_plugins(self, elmap_ex): + layers = elmap_ex.plugin_manager.layer_names + data= np.zeros((500,500),dtype=np.float32) + for layer in layers: + elmap_ex.get_map_with_name_ref(layer, data) \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_parameter.py new file mode 100644 index 00000000..9a12dee4 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_parameter.py @@ -0,0 +1,18 @@ +import pytest +from elevation_mapping_cupy.parameter import Parameter + + +def test_parameter(): + param = Parameter( + use_chainer=False, + weight_file="../../../config/weights.dat", + plugin_config_file="../../../config/plugin_config.yaml", + ) + res = param.resolution + param.set_value("resolution", 0.1) + param.get_types() + param.get_names() + param.update() + assert param.resolution == param.get_value("resolution") + param.load_weights(param.weight_file) + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py index cbd8c091..20381810 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -41,6 +41,7 @@ def test_plugin_manager(semmap_ex, channels): manager = PluginManager(200) manager.load_plugin_settings(plugin_path) elevation_map = cp.zeros((7, 200, 200)).astype(cp.float32) + rotation = cp.eye(3,dtype=cp.float32) layer_names = [ "elevation", "variance", @@ -56,6 +57,9 @@ def test_plugin_manager(semmap_ex, channels): manager.layers[0] manager.update_with_name("min_filter", elevation_map, layer_names) manager.update_with_name("smooth_filter", elevation_map, layer_names) - manager.update_with_name("semantic_filter", elevation_map, layer_names) - + manager.update_with_name("semantic_filter", elevation_map, layer_names,semmap_ex,rotation) manager.get_map_with_name("smooth") + for lay in manager.get_layer_names(): + manager.update_with_name(lay,elevation_map,layer_names,semmap_ex,rotation) + manager.get_map_with_name(lay) + diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index e548deba..93567951 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -18,13 +18,14 @@ class PointcloudNode: def __init__(self, sensor_name): # TODO: if this is going to be loaded from another package we might need to change namespace config = rospy.get_param("/semantic_pointcloud/subscribers") - print(config) - print(len(config)) self.param: PointcloudParameter = PointcloudParameter.from_dict( config[sensor_name] ) self.param.sensor_name = sensor_name + print("--------------Pointcloud Parameters-------------------") print(self.param.dumps_yaml()) + print("--------------End of Parameters-----------------------") + # setup custom dtype self.create_custom_dtype() # setup semantics @@ -41,16 +42,28 @@ def __init__(self, sensor_name): rospy.Subscriber(self.param.cam_info_topic, CameraInfo, self.cam_info_callback) rgb_sub = message_filters.Subscriber(self.param.image_topic, Image) depth_sub = message_filters.Subscriber(self.param.depth_topic, Image) - confidence_sub = message_filters.Subscriber(self.param.confidence_topic, Image) - ts = message_filters.ApproximateTimeSynchronizer( - [ - rgb_sub, - depth_sub, - confidence_sub, - ], - queue_size=10, - slop=0.5, - ) + if self.param.confidence: + confidence_sub = message_filters.Subscriber( + self.param.confidence_topic, Image + ) + ts = message_filters.ApproximateTimeSynchronizer( + [ + rgb_sub, + depth_sub, + confidence_sub, + ], + queue_size=10, + slop=0.5, + ) + else: + ts = message_filters.ApproximateTimeSynchronizer( + [ + rgb_sub, + depth_sub, + ], + queue_size=10, + slop=0.5, + ) ts.registerCallback(self.image_callback) self.pcl_pub = rospy.Publisher(self.param.topic_name, PointCloud2, queue_size=2) @@ -99,9 +112,9 @@ def cam_info_callback(self, msg): self.height = msg.height self.width = msg.width - def image_callback(self, rgb_msg, depth_msg, confidence_msg): + def image_callback(self, rgb_msg, depth_msg, confidence_msg=None): + confidence = None if self.P is None: - print("No cam info topic has been published yet!") return image = cp.asarray( self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8") @@ -109,9 +122,12 @@ def image_callback(self, rgb_msg, depth_msg, confidence_msg): depth = cp.asarray( self.cv_bridge.imgmsg_to_cv2(depth_msg, desired_encoding="passthrough") ) - confidence = cp.asarray( - self.cv_bridge.imgmsg_to_cv2(confidence_msg, desired_encoding="passthrough") - ) + if confidence_msg is not None: + confidence = cp.asarray( + self.cv_bridge.imgmsg_to_cv2( + confidence_msg, desired_encoding="passthrough" + ) + ) pcl = self.create_pcl_from_image(image, depth, confidence) @@ -134,7 +150,10 @@ def create_pcl_from_image(self, image, depth, confidence): def get_coordinates(self, depth, confidence): pos = cp.where(depth > 0, 1, 0) low = cp.where(depth < 8, 1, 0) - conf = cp.where(confidence >= self.param.confidence_threshold, 1, 0) + if confidence is not None: + conf = cp.where(confidence >= self.param.confidence_threshold, 1, 0) + else: + conf = cp.ones(pos.shape) fin = cp.isfinite(depth) temp = cp.maximum(cp.rint(fin + pos + conf + low - 2.6), 0) mask = cp.nonzero(temp) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py index 3474f8d4..e5426b2f 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py @@ -30,6 +30,7 @@ class PointcloudParameter(Serializable): image_topic: str = "/zed2i/zed_node/left/image_rect_color" depth_topic: str = "/zed2i/zed_node/depth/depth_registered" cam_frame: str = "zed2i_right_camera_optical_frame" + confidence: bool = True confidence_topic: str = "/zed2i/zed_node/confidence/confidence_map" confidence_threshold: int = 10 From 3c40c17395f60492f7bb4322140d96d1a8169337 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Mon, 7 Nov 2022 08:55:09 -0800 Subject: [PATCH 250/504] added python wrapper --- .gitignore | 4 +- .../script/elevation_mapping_cupy/__init__.py | 2 + .../elevation_mapping.py | 27 ++-- .../elevation_mapping_ros.py | 140 ++++++++++++++++++ .../elevation_mapping_cupy/parameter.py | 6 +- 5 files changed, 161 insertions(+), 18 deletions(-) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py diff --git a/.gitignore b/.gitignore index 0f73a391..ed51360f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ *.pyc *.bkp *.orig -.idea \ No newline at end of file +.idea* +.vscode* +*.egg-info \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py index e69de29b..6e2735cd 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py @@ -0,0 +1,2 @@ +from .parameter import Parameter +from .elevation_mapping import ElevationMap \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index bc107d4c..3eed7fb5 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -9,20 +9,19 @@ import threading import subprocess -from .traversability_filter import get_filter_chainer, get_filter_torch -from .parameter import Parameter -from .custom_kernels import add_points_kernel, add_color_kernel, color_average_kernel -from .custom_kernels import sum_kernel -from .custom_kernels import error_counting_kernel -from .custom_kernels import average_map_kernel -from .custom_kernels import dilation_filter_kernel -from .custom_kernels import normal_filter_kernel -from .custom_kernels import polygon_mask_kernel -from .map_initializer import MapInitializer -from .plugins.plugin_manager import PluginManager -from .semantic_map import SemanticMap - -from .traversability_polygon import ( +from elevation_mapping_cupy.traversability_filter import get_filter_chainer, get_filter_torch +from elevation_mapping_cupy.parameter import Parameter +from elevation_mapping_cupy.custom_kernels import add_points_kernel, add_color_kernel, color_average_kernel +from elevation_mapping_cupy.custom_kernels import sum_kernel +from elevation_mapping_cupy.custom_kernels import error_counting_kernel +from elevation_mapping_cupy.custom_kernels import average_map_kernel +from elevation_mapping_cupy.custom_kernels import dilation_filter_kernel +from elevation_mapping_cupy.custom_kernels import normal_filter_kernel +from elevation_mapping_cupy.custom_kernels import polygon_mask_kernel +from elevation_mapping_cupy.map_initializer import MapInitializer +from elevation_mapping_cupy.plugins.plugin_manager import PluginManager +from elevation_mapping_cupy.semantic_map import SemanticMap +from elevation_mapping_cupy.traversability_polygon import ( get_masked_traversability, is_traversable, calculate_area, diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py new file mode 100644 index 00000000..aacc1114 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -0,0 +1,140 @@ +from elevation_mapping_cupy import ElevationMap +from elevation_mapping_cupy import Parameter + +# General +import os +import numpy as np + +# ROS +import rospy +import ros_numpy +from tf.transformations import quaternion_matrix +from sensor_msgs.msg import PointCloud2 +import tf2_ros +import rospkg + +class ElevationMapWrapper(): + def __init__(self): + rospack = rospkg.RosPack() + self.root = rospack.get_path("elevation_mapping_cupy") + self.initalize_elevation_mapping() + + # ROS + self.initalize_ros() + self.register_subscribers() + self.register_publishers() + self.register_timers() + + def initalize_elevation_mapping(self): + weight_file = os.path.join(self.root, "config/weights.dat") + plugin_config_file = os.path.join(self.root, "config/plugin_config.yaml") + param = Parameter( use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file ) + self._pointcloud_process_counter = 0 + self._map = ElevationMap(param) + self._map_data = np.zeros((self._map.cell_n - 2, self._map.cell_n - 2), dtype=np.float32) + + def initalize_ros(self): + rospy.init_node("elevation_mapping", anonymous=False) + self._tf_buffer = tf2_ros.Buffer() + self._listener = tf2_ros.TransformListener(self._tf_buffer) + self.get_ros_params() + + def register_subscribers(self): + pointcloud_subs = {} + for config in self.subscribers.values(): + self.subscribers + rospy.Subscriber(config["topic_name"], PointCloud2, self.pointcloud_callback, (config["channels"], config["fusion"])) + + def register_publishers(self): + # TODO publishers + print(self.publishers) + + def register_timers(self): + self.timer_variance = rospy.Timer(rospy.Duration(1/self.update_variance_fps), self.update_variance) + self.timer_pose = rospy.Timer(rospy.Duration(1/self.update_pose_fps), self.update_pose) + self.timer_time = rospy.Timer(rospy.Duration(self.time_interval), self.update_time) + + def pointcloud_callback(self, data, config): + # convert pcd into numpy array + points = ros_numpy.numpify(data) + out = np.copy( np.frombuffer(points.tobytes(), np.dtype(np.float32) )) + out = out.reshape(out.shape[0],-1)[:,:3] + points = points.astype(np.float32) + + # get pose of pointcloud + t = rospy.Time(secs=data.header.stamp.secs, nsecs=data.header.stamp.nsecs) + try: + transform = self._tf_buffer.lookup_transform(self.map_frame, data.header.frame_id, t, rospy.Duration(1.0)) + except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: + print(e) + return + + t = transform.transform.translation + t = np.array( [t.x, t.y, t.z] ) + q = transform.transform.rotation + R = quaternion_matrix([q.w, q.x, q.y, q.z]) + + # process pointcloud + self._map.input(points, 0, R, t, 0, 0) + self._map.update_normal(self._map.elevation_map[0]) + self._pointcloud_process_counter += 1 + + def update_pose(self, t): + # get pose of base + t = rospy.Time.now() + try: + transform = self._tf_buffer.lookup_transform(self.map_frame, self.base_frame, t, rospy.Duration(1.0)) + except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: + print(e) + return + t = transform.transform.translation + trans = np.array( [t.x, t.y, t.z] ) + q = transform.transform.rotation + rot = quaternion_matrix([q.w, q.x, q.y, q.z]) + self._map.move_to(trans, rot) + + def update_variance(self, t): + self._map.update_variance() + + def update_time(self, t): + self._map.update_time() + + def get_ros_params(self): + # TODO fix this here when later launching with launch-file + # This is currently {p} elevation_mapping") + para = os.path.join(self.root, "config/parameters.yaml") + sens = os.path.join(self.root, "config/sensor_parameter.yaml") + os.system(f"rosparam load {para} elevation_mapping") + os.system(f"rosparam load {sens} elevation_mapping") + + self.subscribers = rospy.get_param("~subscribers") + self.publishers = rospy.get_param("~publishers") + self.initialize_frame_id = rospy.get_param("~initialize_frame_id", "base") + self.initialize_tf_offset = rospy.get_param("~initialize_tf_offset", 0.0) + self.pose_topic = rospy.get_param("~pose_topic", "pose") + self.map_frame = rospy.get_param("~map_frame", "map") + self.base_frame = rospy.get_param("~base_frame", "base") + self.corrected_map_frame = rospy.get_param("~corrected_map_frame", "corrected_map") + self.initialize_method = rospy.get_param("~initialize_method", "cubic") + self.position_lowpass_alpha = rospy.get_param("~position_lowpass_alpha", 0.2) + self.orientation_lowpass_alpha = rospy.get_param("~orientation_lowpass_alpha", 0.2) + self.recordable_fps = rospy.get_param("~recordable_fps", 3.0) + self.update_variance_fps = rospy.get_param("~update_variance_fps", 1.0) + self.time_interval = rospy.get_param("~time_interval", 0.1) + self.update_pose_fps = rospy.get_param("~update_pose_fps", 10.0) + self.initialize_tf_grid_size = rospy.get_param("~initialize_tf_grid_size", 0.5) + self.map_acquire_fps = rospy.get_param("~map_acquire_fps", 5.0) + self.publish_statistics_fps = rospy.get_param("~publish_statistics_fps", 1.0) + self.enable_pointcloud_publishing = rospy.get_param("~enable_pointcloud_publishing", False) + self.enable_normal_arrow_publishing = rospy.get_param("~enable_normal_arrow_publishing", False) + self.enable_drift_corrected_TF_publishing = rospy.get_param("~enable_drift_corrected_TF_publishing", False) + self.use_initializer_at_start = rospy.get_param("~use_initializer_at_start", False) + +if __name__ == '__main__': + emw = ElevationMapWrapper() + + while not rospy.is_shutdown(): + try: + rospy.spin() + except rospy.ROSInterruptException: + print("Error") \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 5b58620d..0e29dc9d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -6,13 +6,13 @@ import pickle import numpy as np from simple_parsing.helpers import Serializable - +from dataclasses import field @dataclass class Parameter(Serializable): resolution: float = 0.02 - additional_layers: list = ['feat_0'].copy - fusion_algorithms: list = ['average'].copy + additional_layers: list = field(default_factory=lambda: ["feat_0"]) + fusion_algorithms: list = field(default_factory=lambda: ["average"]) cell_n: int = None map_length: float = 10.0 From f3d4f0c87768b80b945f64aba6649ee5959f282e Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Mon, 7 Nov 2022 08:55:18 -0800 Subject: [PATCH 251/504] added anymal sensors --- .../config/sensor_parameter.yaml | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index 8c8c596b..d88e0358 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -3,8 +3,38 @@ subscribers: # channels: ['feat_0','feat_1'] # fusion: ['average','average'] # topic_name: '/elevation_mapping/pointcloud_semantic' + front_cam: channels: ['rgb','feat_0','feat_1','c_prob_0'] fusion: ['color','average','average','class_average'] topic_name: '/elvation_mapping/pointcloud_semantic' + front_bpearl: + channels: [] + fusion: ['average'] + topic_name: /robot_self_filter/bpearl_front/point_cloud + + rear_bpearl: + channels: [] + fusion: ['average'] + topic_name: /robot_self_filter/bpearl_rear/point_cloud + + front_depth: + channels: [] + fusion: ['average'] + topic_name: /depth_camera_front/point_cloud_self_filtered + + rear_depth: + channels: [] + fusion: ['average'] + topic_name: /depth_camera_rear/point_cloud_self_filtered + + left_depth: + channels: [] + fusion: ['average'] + topic_name: /depth_camera_left/point_cloud_self_filtered + + right_depth: + channels: [] + fusion: ['average'] + topic_name: /depth_camera_right/point_cloud_self_filtered \ No newline at end of file From da9ca6ee358725cf0893884e6a0bfe055772d7c6 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Mon, 7 Nov 2022 14:08:16 -0800 Subject: [PATCH 252/504] updated python wrapper --- elevation_mapping_cupy/config/parameters.yaml | 22 ++--- .../elevation_mapping_ros.py | 85 +++++++++++++++---- 2 files changed, 80 insertions(+), 27 deletions(-) diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index 24e29141..27b5f497 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -40,9 +40,9 @@ max_unsafe_n: 10 # if the number of cells under s overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) -map_frame: 'enu' # The map frame where the odometry source uses. -base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'enu' +map_frame: 'odom' # The map frame where the odometry source uses. +base_frame: 'base' # The robot's base frame. This frame will be a center of the map. +corrected_map_frame: 'odom_corrected' #### Feature toggles ######## enable_edge_sharpen: true @@ -76,14 +76,14 @@ publishers: layers: ['elevation', 'traversability', 'variance'] basic_layers: ['elevation', 'traversability'] fps: 5.0 - elevation_map_recordable: - layers: ['elevation', 'traversability'] - basic_layers: ['elevation', 'traversability'] - fps: 2.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb'] - basic_layers: ['min_filter'] - fps: 3.0 + # elevation_map_recordable: + # layers: ['elevation', 'traversability'] + # basic_layers: ['elevation', 'traversability'] + # fps: 2.0 + # elevation_map_filter: + # layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb'] + # basic_layers: ['min_filter'] + # fps: 3.0 #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index aacc1114..26383a66 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -9,16 +9,21 @@ import rospy import ros_numpy from tf.transformations import quaternion_matrix -from sensor_msgs.msg import PointCloud2 import tf2_ros import rospkg +from sensor_msgs.msg import PointCloud2 +from grid_map_msgs.msg import GridMap +from std_msgs.msg import Float32MultiArray +from std_msgs.msg import MultiArrayLayout as MAL +from std_msgs.msg import MultiArrayDimension as MAD + class ElevationMapWrapper(): def __init__(self): rospack = rospkg.RosPack() self.root = rospack.get_path("elevation_mapping_cupy") self.initalize_elevation_mapping() - + self.node_name = "elevation_mapping" # ROS self.initalize_ros() self.register_subscribers() @@ -29,12 +34,15 @@ def initalize_elevation_mapping(self): weight_file = os.path.join(self.root, "config/weights.dat") plugin_config_file = os.path.join(self.root, "config/plugin_config.yaml") param = Parameter( use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file ) + param.update() self._pointcloud_process_counter = 0 self._map = ElevationMap(param) self._map_data = np.zeros((self._map.cell_n - 2, self._map.cell_n - 2), dtype=np.float32) + self._map_q = None + self._map_t = None def initalize_ros(self): - rospy.init_node("elevation_mapping", anonymous=False) + rospy.init_node(self.node_name, anonymous=False) self._tf_buffer = tf2_ros.Buffer() self._listener = tf2_ros.TransformListener(self._tf_buffer) self.get_ros_params() @@ -47,24 +55,66 @@ def register_subscribers(self): def register_publishers(self): # TODO publishers - print(self.publishers) + self._publishers = {} + self._publishers_timers = [] + for k, v in self.publishers.items(): + print(f"Register Publisher: {k}") + self._publishers[k] = rospy.Publisher(f"/{self.node_name}/{k}", GridMap, queue_size=10) + self._publishers_timers.append( rospy.Timer(rospy.Duration(1/v["fps"]), lambda x: self.publish_map(x, k))) + + def publish_map(self, t, k): + print(k) + if self._map_q is None: + return + gm = GridMap() + gm.info.header.frame_id = self.map_frame + gm.info.header.stamp = rospy.Time.now() + gm.info.header.seq = 0 + gm.info.resolution = self._map.resolution + gm.info.length_x = self._map.map_length + gm.info.length_y = self._map.map_length + gm.info.pose.position.x = self._map_t.x + gm.info.pose.position.y = self._map_t.y + gm.info.pose.position.z = self._map_t.z + gm.info.pose.orientation.w = 1 # self._map_q.w + gm.info.pose.orientation.x = 0 # self._map_q.x + gm.info.pose.orientation.y = 0 # self._map_q.y + gm.info.pose.orientation.z = 0 # self._map_q.z + gm.layers = self.publishers[k]["layers"] + gm.basic_layers = self.publishers[k]["basic_layers"] + + # arr.layout.dim = [int(gm.info.length_x/gm.info.resolution), int(gm.info.length_y/gm.info.resolution)] + + for i, layer in enumerate(gm.layers): + self._map.get_map_with_name_ref(layer, self._map_data) + self._map_data = np.nan_to_num(self._map_data, False, 0) + data = self._map_data.copy() + arr = Float32MultiArray() + arr.layout = MAL() + N = self._map_data.shape[0] + arr.layout.dim.append( MAD(label="column_index",size=N,stride=int(N*N))) + arr.layout.dim.append( MAD(label="row_index",size=N,stride=N)) + arr.data = tuple(np.ascontiguousarray(data).reshape(-1)) + gm.data.append( arr ) + + self._publishers[k].publish( gm ) + def register_timers(self): self.timer_variance = rospy.Timer(rospy.Duration(1/self.update_variance_fps), self.update_variance) self.timer_pose = rospy.Timer(rospy.Duration(1/self.update_pose_fps), self.update_pose) self.timer_time = rospy.Timer(rospy.Duration(self.time_interval), self.update_time) - def pointcloud_callback(self, data, config): + def pointcloud_callback(self, msg, config): # convert pcd into numpy array - points = ros_numpy.numpify(data) - out = np.copy( np.frombuffer(points.tobytes(), np.dtype(np.float32) )) - out = out.reshape(out.shape[0],-1)[:,:3] - points = points.astype(np.float32) + channels = config[0] + fusion = config[1] + points = ros_numpy.point_cloud2.pointcloud2_to_xyz_array(msg) # get pose of pointcloud - t = rospy.Time(secs=data.header.stamp.secs, nsecs=data.header.stamp.nsecs) + t = rospy.Time(secs=msg.header.stamp.secs, nsecs=msg.header.stamp.nsecs) try: - transform = self._tf_buffer.lookup_transform(self.map_frame, data.header.frame_id, t, rospy.Duration(1.0)) + transform = self._tf_buffer.lookup_transform(self.map_frame, msg.header.frame_id, t, rospy.Duration(1.0)) except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: print(e) return @@ -72,12 +122,12 @@ def pointcloud_callback(self, data, config): t = transform.transform.translation t = np.array( [t.x, t.y, t.z] ) q = transform.transform.rotation - R = quaternion_matrix([q.w, q.x, q.y, q.z]) + R = quaternion_matrix([q.w, q.x, q.y, q.z])[:3,:3] # process pointcloud - self._map.input(points, 0, R, t, 0, 0) - self._map.update_normal(self._map.elevation_map[0]) + self._map.input(points, ['x','y','z']+channels, R, t, 0, 0) self._pointcloud_process_counter += 1 + print(self._pointcloud_process_counter) def update_pose(self, t): # get pose of base @@ -90,9 +140,12 @@ def update_pose(self, t): t = transform.transform.translation trans = np.array( [t.x, t.y, t.z] ) q = transform.transform.rotation - rot = quaternion_matrix([q.w, q.x, q.y, q.z]) + rot = quaternion_matrix([q.w, q.x, q.y, q.z])[:3,:3] self._map.move_to(trans, rot) + self._map_t = t + self._map_q = q + def update_variance(self, t): self._map.update_variance() @@ -104,9 +157,9 @@ def get_ros_params(self): # This is currently {p} elevation_mapping") para = os.path.join(self.root, "config/parameters.yaml") sens = os.path.join(self.root, "config/sensor_parameter.yaml") + os.system(f"rosparam delete /{self.node_name}") os.system(f"rosparam load {para} elevation_mapping") os.system(f"rosparam load {sens} elevation_mapping") - self.subscribers = rospy.get_param("~subscribers") self.publishers = rospy.get_param("~publishers") self.initialize_frame_id = rospy.get_param("~initialize_frame_id", "base") From ad3956c9a381395722837a6fd925f45754dff5b6 Mon Sep 17 00:00:00 2001 From: Matias Mattamala Date: Tue, 8 Nov 2022 17:39:46 +0000 Subject: [PATCH 253/504] Change how pybind is included in cpp files --- .../include/elevation_mapping_cupy/elevation_mapping_ros.hpp | 2 +- .../elevation_mapping_cupy/elevation_mapping_wrapper.hpp | 2 +- elevation_mapping_cupy/src/elevation_mapping_node.cpp | 2 +- elevation_mapping_cupy/src/elevation_mapping_ros.cpp | 2 +- elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 7a374437..2107df57 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -13,7 +13,7 @@ #include // Pybind -#include // everything needed for embedding +#include // everything needed for embedding // ROS #include diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index 97bec2a5..0fa68cfd 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -12,7 +12,7 @@ #include // Pybind -#include // everything needed for embedding +#include // everything needed for embedding // ROS #include diff --git a/elevation_mapping_cupy/src/elevation_mapping_node.cpp b/elevation_mapping_cupy/src/elevation_mapping_node.cpp index 47bef360..3d7a778f 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_node.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_node.cpp @@ -4,7 +4,7 @@ // // Pybind -#include // everything needed for embedding +#include // everything needed for embedding // ROS #include diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 79941e8f..ebc3f35e 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -6,7 +6,7 @@ #include "elevation_mapping_cupy/elevation_mapping_ros.hpp" // Pybind -#include +#include // ROS #include diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index d9662833..e943f1b3 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -6,7 +6,7 @@ #include "elevation_mapping_cupy/elevation_mapping_wrapper.hpp" // Pybind -#include +#include // PCL #include From 71d915dd009a69f70e330318b4d5d022a793de9b Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Wed, 9 Nov 2022 11:49:35 +0100 Subject: [PATCH 254/504] added universal checker --- .../config/plugin_config.yaml | 14 +++- .../elevation_mapping.py | 25 +++++-- .../elevation_mapping_cupy/parameter.py | 5 +- .../plugins/semantic_traversability.py | 71 +++++++++++++++++++ .../tests/plugin_config.yaml | 66 +++++++++++++++++ .../tests/test_elevation_mapping.py | 4 +- .../tests/test_plugins.py | 25 +++---- .../traversability_polygon.py | 4 +- 8 files changed, 190 insertions(+), 24 deletions(-) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/tests/plugin_config.yaml diff --git a/elevation_mapping_cupy/config/plugin_config.yaml b/elevation_mapping_cupy/config/plugin_config.yaml index 33ed355c..bcc0cb24 100644 --- a/elevation_mapping_cupy/config/plugin_config.yaml +++ b/elevation_mapping_cupy/config/plugin_config.yaml @@ -52,6 +52,16 @@ semantic_filter: is_height_layer: False layer_name: "sem_fil" extra_params: -# TODO make a better link between classes and color classes: ['grass','tree','fence','person'] - colors: [[0,255,0],[120,120,0],[170,0,20],[0,0,255],[255,0,0]] \ No newline at end of file + colors: [[0,255,0],[120,120,0],[170,0,20],[0,0,255],[255,0,0]] + +semantic_traversability: + type: "semantic_traversability" + enable: False + fill_nan: False + is_height_layer: False + layer_name: "sem_traversability" + extra_params: + layers: ['traversability','robot_centric_elevation'] + thresholds: [0.7,0.5] + type: ['traversability', 'elevation'] diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index a3310ba4..632a3c28 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -595,6 +595,22 @@ def get_normal_ref(self, normal_x_data, normal_y_data, normal_z_data): normal_y_data[...] = xp.asnumpy(maps[1], stream=self.stream) normal_z_data[...] = xp.asnumpy(maps[2], stream=self.stream) + def get_layer(self,name): + if name in self.layer_names: + idx = self.layer_names.index(name) + map = self.elevation_map[idx] + elif name in self.semantic_map.param.additional_layers: + idx = self.semantic_map.param.additional_layers.index(name) + map= self.semantic_map.map[idx] + elif name in self.plugin_manager.layer_names: + self.plugin_manager.update_with_name(name, self.elevation_map, self.layer_names, self.semantic_map, + self.base_rotation) + map = self.plugin_manager.get_map_with_name(name) + else: + print("Layer {} is not in the map, returning traversabiltiy!".format(name)) + return + return map + def get_polygon_traversability(self, polygon, result): """ Check if input polygons are traversable. @@ -626,11 +642,12 @@ def get_polygon_traversability(self, polygon, result): self.mask, size=(self.cell_n * self.cell_n), ) - masked, masked_isvalid = get_masked_traversability(self.elevation_map, self.mask) + map = self.get_layer(self.param.checker_layer) + masked, masked_isvalid = get_masked_traversability(self.elevation_map, self.mask, map) if masked_isvalid.sum() > 0: t = masked.sum() / masked_isvalid.sum() else: - t = cp.asarray(0.0,dtype=self.data_type) + t = cp.asarray(0.0, dtype=self.data_type) is_safe, un_polygon = is_traversable( masked, self.param.safe_thresh, self.param.safe_min_thresh, self.param.max_unsafe_n ) @@ -697,14 +714,14 @@ def initialize_map(self, points, method="cubic"): layers = ["elevation", "variance", "traversability", "min_filter", "smooth", "inpaint","rgb"] points = xp.random.rand(100000, len(layers)) - channels = ['x','y','z']+ param.additional_layers + channels = ['x', 'y', 'z'] + param.additional_layers print(channels) data = np.zeros((elevation.cell_n - 2, elevation.cell_n - 2), dtype=np.float32) for i in range(20): elevation.input(points,channels, R, t, 0, 0) elevation.update_normal(elevation.elevation_map[0]) pos = np.array([i * 0.01, i * 0.02, i * 0.01]) - elevation.move_to(pos,R) + elevation.move_to(pos, R) for layer in layers: elevation.get_map_with_name_ref(layer, data) print(i) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 486e6caa..296adc23 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -10,13 +10,13 @@ @dataclass class Parameter(Serializable): - resolution: float = 0.02 + resolution: float = 0.04 additional_layers: list = ['feat_0'].copy fusion_algorithms: list = ['average'].copy cell_n: int = None data_type: str = np.float32 - map_length: float = 10.0 + map_length: float = 8.0 sensor_noise_factor: float = 0.05 mahalanobis_thresh: float = 2.0 outlier_variance: float = 0.01 @@ -45,6 +45,7 @@ class Parameter(Serializable): safe_thresh: float = 0.5 safe_min_thresh: float = 0.5 max_unsafe_n: int = 20 + checker_layer: str = 'traversability' min_filter_size: int = 5 min_filter_iteration: int = 3 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py new file mode 100644 index 00000000..a9619a4b --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py @@ -0,0 +1,71 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +from typing import List + +from elevation_mapping_cupy.plugins.plugin_manager import PluginBase + + +class SemanticTraversability(PluginBase): + """This is a filter to create colors + + ... + + Attributes + ---------- + cell_n: int + width and height of the elevation map. + """ + + def __init__( + self, + cell_n: int = 100, + layers: list = ["traversability"], + thresholds: list = [0.5], + type: list = ["traversability"], + **kwargs, + ): + super().__init__() + self.layers = layers + self.thresholds = cp.asarray(thresholds) + self.type = type + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map, + *args, + ) -> cp.ndarray: + # get indices of all layers that + map = cp.zeros(elevation_map[2].shape, np.float32) + tempo = cp.zeros(elevation_map[2].shape, np.float32) + for it, name in enumerate(self.layers): + if name in layer_names: + idx = layer_names.index(name) + tempo = elevation_map[idx] + elif name in semantic_map.param.additional_layers: + idx = semantic_map.param.additional_layers.index(name) + tempo = semantic_map.map[idx] + elif name in plugin_layer_names: + idx = plugin_layer_names.index(name) + tempo = plugin_layers[idx] + else: + print( + "Layer {} is not in the map, returning traversabiltiy!".format(name) + ) + return + if self.type[it] == "traversability": + tempo = cp.where(tempo <= self.thresholds[it], 1, 0) + map += tempo + else: + tempo = cp.where(tempo >= self.thresholds[it], 1, 0) + map += tempo + map = cp.where(map <= 0.9, 0.1,1) + + return map diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/plugin_config.yaml b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/plugin_config.yaml new file mode 100644 index 00000000..6d057ec5 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/plugin_config.yaml @@ -0,0 +1,66 @@ +# Settings of the plugins. (The plugins should be stored in script/plugins) + +# min_filter fills in minimum value around the invalid cell. +min_filter: + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations +# Apply smoothing. +smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" +# Apply inpainting using opencv +inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns +# Apply smoothing for inpainted layer +smooth_filter_1: + type: "smooth_filter" + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth_1" + extra_params: + input_layer_name: "inpaint" +robot_centric_elevation: # Use the same name as your file name. +# type: "robot_centric_elevation" + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "robot_centric_elevation" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. +# add_value: 2.0 # Example param + resolution: 0.04 + threshold: 1.1 + use_threshold: True +semantic_filter: + type: "semantic_filter" + enable: True + fill_nan: False + is_height_layer: False + layer_name: "sem_fil" + extra_params: + classes: ['grass','tree','fence','person'] + colors: [[0,255,0],[120,120,0],[170,0,20],[0,0,255],[255,0,0]] +semantic_traversability: + type: "semantic_traversability" + enable: True + fill_nan: False + is_height_layer: False + layer_name: "sem_traversability" + extra_params: + layers: ['traversability','robot_centric_elevation'] + thresholds: [0.7,0.5] + type: ['traversability', 'elevation'] diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py index 95a8b1a4..b9ce3b41 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -94,6 +94,6 @@ def test_initialize_map(self, elmap_ex): def test_plugins(self, elmap_ex): layers = elmap_ex.plugin_manager.layer_names - data= np.zeros((500,500),dtype=np.float32) + data = np.zeros((200, 200), dtype=np.float32) for layer in layers: - elmap_ex.get_map_with_name_ref(layer, data) \ No newline at end of file + elmap_ex.get_map_with_name_ref(layer, data) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py index 20381810..180aa9d5 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -4,7 +4,7 @@ import numpy as np from elevation_mapping_cupy.plugins.plugin_manager import PluginManager, PluginParams -plugin_path = "../../../config/plugin_config.yaml" +plugin_path = "plugin_config.yaml" @pytest.fixture() @@ -28,19 +28,19 @@ def semmap_ex(add_lay, fusion_alg): @pytest.mark.parametrize( "add_lay, fusion_alg,channels", [ - (["feat_0", "feat_1"], ["average", "average"], ["feat_0"]), - (["feat_0", "feat_1"], ["average", "average"], []), - ( - ["feat_0", "feat_1", "rgb"], - ["average", "average", "color"], - ["rgb", "feat_0"], - ), + (['grass','tree','fence','person'], ["class_average", "class_average", "class_average", "class_average"], ["grass"]), + (['grass','tree'], ["class_average", "class_average"], ['grass']), + # ( + # ["feat_0", "feat_1", "rgb"], + # ["average", "average", "color"], + # ["rgb", "feat_0"], + # ), ], ) def test_plugin_manager(semmap_ex, channels): - manager = PluginManager(200) + manager = PluginManager(202) manager.load_plugin_settings(plugin_path) - elevation_map = cp.zeros((7, 200, 200)).astype(cp.float32) + elevation_map = cp.zeros((7, 202, 202)).astype(cp.float32) rotation = cp.eye(3,dtype=cp.float32) layer_names = [ "elevation", @@ -51,13 +51,14 @@ def test_plugin_manager(semmap_ex, channels): "upper_bound", "is_upper_bound", ] - elevation_map[0] = cp.random.randn(200, 200) - elevation_map[2] = cp.abs(cp.random.randn(200, 200)) + elevation_map[0] = cp.random.randn(202, 202) + elevation_map[2] = cp.abs(cp.random.randn(202, 202)) elevation_map[0] manager.layers[0] manager.update_with_name("min_filter", elevation_map, layer_names) manager.update_with_name("smooth_filter", elevation_map, layer_names) manager.update_with_name("semantic_filter", elevation_map, layer_names,semmap_ex,rotation) + manager.update_with_name("semantic_traversability", elevation_map, layer_names,semmap_ex) manager.get_map_with_name("smooth") for lay in manager.get_layer_names(): manager.update_with_name(lay,elevation_map,layer_names,semmap_ex,rotation) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py index 67a43343..4d267535 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py @@ -7,8 +7,8 @@ from shapely.geometry import Polygon, MultiPoint -def get_masked_traversability(map_array, mask): - traversability = map_array[3][1:-1, 1:-1] +def get_masked_traversability(map_array, mask, traversability): + traversability = traversability[1:-1, 1:-1] is_valid = map_array[2][1:-1, 1:-1] mask = mask[1:-1, 1:-1] From 8635861510f83e220dc9b34693152bda544f16a9 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Thu, 10 Nov 2022 10:39:34 +0100 Subject: [PATCH 255/504] working python wrapper but wrong orientation of the elevation map --- .../elevation_mapping_ros.py | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index 26383a66..ee493574 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -22,21 +22,21 @@ class ElevationMapWrapper(): def __init__(self): rospack = rospkg.RosPack() self.root = rospack.get_path("elevation_mapping_cupy") - self.initalize_elevation_mapping() + weight_file = os.path.join(self.root, "config/weights.dat") + plugin_config_file = os.path.join(self.root, "config/plugin_config.yaml") + self.param = Parameter( use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file ) self.node_name = "elevation_mapping" # ROS self.initalize_ros() self.register_subscribers() + self.initalize_elevation_mapping() self.register_publishers() self.register_timers() def initalize_elevation_mapping(self): - weight_file = os.path.join(self.root, "config/weights.dat") - plugin_config_file = os.path.join(self.root, "config/plugin_config.yaml") - param = Parameter( use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file ) - param.update() + self.param.update() self._pointcloud_process_counter = 0 - self._map = ElevationMap(param) + self._map = ElevationMap(self.param) self._map_data = np.zeros((self._map.cell_n - 2, self._map.cell_n - 2), dtype=np.float32) self._map_q = None self._map_t = None @@ -49,10 +49,24 @@ def initalize_ros(self): def register_subscribers(self): pointcloud_subs = {} - for config in self.subscribers.values(): - self.subscribers - rospy.Subscriber(config["topic_name"], PointCloud2, self.pointcloud_callback, (config["channels"], config["fusion"])) - + additional = [] + fusion = [] + for key, config in self.subscribers.items(): + pointcloud_subs[key] = rospy.Subscriber(config["topic_name"], PointCloud2, self.pointcloud_callback, (config["channels"], config["fusion"])) + for chan,fus in zip(config["channels"],config["fusion"]): + if chan not in additional: + additional.append(chan) + fusion.append(fus) + self.param.additional_layers = additional + self.param.fusion_algorithms = fusion + self.dtype = [ + ("x", np.float32), + ("y", np.float32), + ("z", np.float32), + ] + for chan in config["channels"]: + self.dtype.append((chan, np.float32)) + def register_publishers(self): # TODO publishers self._publishers = {} @@ -88,7 +102,7 @@ def publish_map(self, t, k): for i, layer in enumerate(gm.layers): self._map.get_map_with_name_ref(layer, self._map_data) - self._map_data = np.nan_to_num(self._map_data, False, 0) + # self._map_data = np.nan_to_num(self._map_data, False, 0) data = self._map_data.copy() arr = Float32MultiArray() arr.layout = MAL() @@ -107,10 +121,13 @@ def register_timers(self): def pointcloud_callback(self, msg, config): # convert pcd into numpy array - channels = config[0] + channels = ['x','y','z']+config[0] fusion = config[1] - points = ros_numpy.point_cloud2.pointcloud2_to_xyz_array(msg) - + points = ros_numpy.numpify(msg) + pts = np.empty((points.shape[0],0)) + for ch in channels: + pts = np.append(pts,np.expand_dims(points[ch],1),axis=1) + # get pose of pointcloud t = rospy.Time(secs=msg.header.stamp.secs, nsecs=msg.header.stamp.nsecs) try: @@ -123,9 +140,9 @@ def pointcloud_callback(self, msg, config): t = np.array( [t.x, t.y, t.z] ) q = transform.transform.rotation R = quaternion_matrix([q.w, q.x, q.y, q.z])[:3,:3] - + # process pointcloud - self._map.input(points, ['x','y','z']+channels, R, t, 0, 0) + self._map.input(pts, channels, R, t, 0, 0) self._pointcloud_process_counter += 1 print(self._pointcloud_process_counter) From affd8aeb82044e4b1fca84800f3c68586e976658 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Mon, 14 Nov 2022 15:21:22 +0100 Subject: [PATCH 256/504] first documentation --- .gitignore | 5 +- docs/Makefile | 20 +++++++ docs/make.bat | 35 +++++++++++++ {doc => docs/media}/convex_approximation.gif | Bin {doc => docs/media}/cuda-installation.md | 0 {doc => docs/media}/main_repo.png | Bin {doc => docs/media}/processing_time.png | Bin {doc => docs/media}/real.png | Bin {doc => docs/media}/sim.png | Bin docs/source/conf.py | 52 +++++++++++++++++++ docs/source/getting_started/index.rst | 8 +++ docs/source/index.rst | 23 ++++++++ docs/source/python/custom_kernels.rst | 9 ++++ docs/source/python/elevation_mapping.rst | 19 +++++++ docs/source/python/index.rst | 8 +++ docs/source/python/semantic_pointcloud.rst | 8 +++ requirements.txt | 2 +- 17 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 docs/Makefile create mode 100644 docs/make.bat rename {doc => docs/media}/convex_approximation.gif (100%) rename {doc => docs/media}/cuda-installation.md (100%) rename {doc => docs/media}/main_repo.png (100%) rename {doc => docs/media}/processing_time.png (100%) rename {doc => docs/media}/real.png (100%) rename {doc => docs/media}/sim.png (100%) create mode 100644 docs/source/conf.py create mode 100644 docs/source/getting_started/index.rst create mode 100644 docs/source/index.rst create mode 100644 docs/source/python/custom_kernels.rst create mode 100644 docs/source/python/elevation_mapping.rst create mode 100644 docs/source/python/index.rst create mode 100644 docs/source/python/semantic_pointcloud.rst diff --git a/.gitignore b/.gitignore index 0f73a391..e9ff620b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ *.pyc *.bkp *.orig -.idea \ No newline at end of file +.idea +.pytest_cache +.run/ +docs/build diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..d0c3cbf1 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 00000000..747ffb7b --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/doc/convex_approximation.gif b/docs/media/convex_approximation.gif similarity index 100% rename from doc/convex_approximation.gif rename to docs/media/convex_approximation.gif diff --git a/doc/cuda-installation.md b/docs/media/cuda-installation.md similarity index 100% rename from doc/cuda-installation.md rename to docs/media/cuda-installation.md diff --git a/doc/main_repo.png b/docs/media/main_repo.png similarity index 100% rename from doc/main_repo.png rename to docs/media/main_repo.png diff --git a/doc/processing_time.png b/docs/media/processing_time.png similarity index 100% rename from doc/processing_time.png rename to docs/media/processing_time.png diff --git a/doc/real.png b/docs/media/real.png similarity index 100% rename from doc/real.png rename to docs/media/real.png diff --git a/doc/sim.png b/docs/media/sim.png similarity index 100% rename from doc/sim.png rename to docs/media/sim.png diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..a1f29f10 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,52 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +import os, sys +sys.path.insert(0, os.path.abspath('../../elevation_mapping_cupy')) +sys.path.insert(0, os.path.abspath('../../sensor_processing/semantic_pointcloud')) + +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + +if not on_rtd: # only import and set the theme if we're building docs locally + import sphinx_rtd_theme + html_theme = 'sphinx_rtd_theme' + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + + +project = 'elevation_mapping_cupy' +copyright = '2022, Takahiro Miki, Gian Erni' +author = 'Takahiro Miki, Gian Erni' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage', 'sphinx.ext.napoleon'] + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +html_theme_options = { + 'analytics_anonymize_ip': False, + 'logo_only': False, + 'display_version': False, + 'prev_next_buttons_location': 'bottom', + 'style_external_links': False, + 'vcs_pageview_mode': '', + 'style_nav_header_background': '#A00000', + # Toc options + 'collapse_navigation': True, + 'sticky_navigation': True, + 'navigation_depth': 4, + 'includehidden': True, + 'titles_only': False +} + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_static_path = ['_static'] diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst new file mode 100644 index 00000000..2a97ef91 --- /dev/null +++ b/docs/source/getting_started/index.rst @@ -0,0 +1,8 @@ + +Getting Started +================================================== + +.. toctree:: + + + diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..03bb6329 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,23 @@ +################################################## +Welcome to elevation_mapping_cupy's documentation! +################################################## + + +.. toctree:: + :maxdepth: 2 + :caption: Pages: + + + getting_started/index + python/index + +Getting Started +--------------- + +For getting started checkout :doc:`getting_started/index`.. + + +Old Documentation +----------------- + + diff --git a/docs/source/python/custom_kernels.rst b/docs/source/python/custom_kernels.rst new file mode 100644 index 00000000..c8dcd43c --- /dev/null +++ b/docs/source/python/custom_kernels.rst @@ -0,0 +1,9 @@ +.. _custom_kernels: + +Custom kernels +================================================== + +.. automodule:: elevation_mapping_cupy.custom_kernels + :members: + + diff --git a/docs/source/python/elevation_mapping.rst b/docs/source/python/elevation_mapping.rst new file mode 100644 index 00000000..b3403049 --- /dev/null +++ b/docs/source/python/elevation_mapping.rst @@ -0,0 +1,19 @@ +.. _elevation_mapping: + +Elevation mapping cupy +================================================== + +.. automodule:: elevation_mapping_cupy.elevation_mapping + :members: + +.. automodule:: elevation_mapping_cupy.semantic_map + :members: + +.. automodule:: elevation_mapping_cupy.parameter + :members: + +.. automodule:: elevation_mapping_cupy.plugins.plugin_manager + :members: + + + diff --git a/docs/source/python/index.rst b/docs/source/python/index.rst new file mode 100644 index 00000000..4764424c --- /dev/null +++ b/docs/source/python/index.rst @@ -0,0 +1,8 @@ +Python software +================================================== + +.. toctree:: + elevation_mapping + semantic_pointcloud + custom_kernels + diff --git a/docs/source/python/semantic_pointcloud.rst b/docs/source/python/semantic_pointcloud.rst new file mode 100644 index 00000000..9a49c37a --- /dev/null +++ b/docs/source/python/semantic_pointcloud.rst @@ -0,0 +1,8 @@ +.. _semantic_pointcloud: + +Semantic Pointcloud +=================== + + +.. automodule:: semantic_pointcloud.pointcloud_node + :members: diff --git a/requirements.txt b/requirements.txt index c68be6a1..6ac4a197 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ scipy dataclasses ruamel.yaml opencv-python -simple_parsing +simple-parsing ###### Requirements with Version Specifiers ######` shapely==1.7.1 From 1aae1a301efe131e84e196a2fffbb2a9c6ec6eb8 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Mon, 14 Nov 2022 19:20:30 +0100 Subject: [PATCH 257/504] deploy pages and first installation instructions --- .github/workflows/documentation.yml | 22 +++ .gitignore | 1 + docs/source/documentation.rst | 51 ++++++ docs/source/getting_started/index.rst | 5 +- docs/source/getting_started/installation.rst | 171 +++++++++++++++++++ docs/source/getting_started/tutorial.rst | 4 + docs/source/index.rst | 41 +++-- docs/source/usage/parameters.rst | 4 + docs/source/usage/plane_segmentation.rst | 7 + docs/source/usage/plugins.rst | 5 + docs/source/usage/semantics.rst | 4 + 11 files changed, 301 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/documentation.yml create mode 100644 docs/source/documentation.rst create mode 100644 docs/source/getting_started/installation.rst create mode 100644 docs/source/getting_started/tutorial.rst create mode 100644 docs/source/usage/parameters.rst create mode 100644 docs/source/usage/plane_segmentation.rst create mode 100644 docs/source/usage/plugins.rst create mode 100644 docs/source/usage/semantics.rst diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 00000000..a64a015f --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,22 @@ +name: Docs +on: [push, pull_request, workflow_dispatch] +jobs: + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + - name: Install dependencies + run: | + pip install sphinx sphinx_rtd_theme + - name: Sphinx build + run: | + sphinx-build docs/source docs/_build + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + if: ${{ github.event_name == 'push' }} + with: + publish_branch: gh-pages + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: docs/_build/ + force_orphan: true \ No newline at end of file diff --git a/.gitignore b/.gitignore index e9ff620b..321ecd4c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .pytest_cache .run/ docs/build +_build diff --git a/docs/source/documentation.rst b/docs/source/documentation.rst new file mode 100644 index 00000000..046cae8d --- /dev/null +++ b/docs/source/documentation.rst @@ -0,0 +1,51 @@ +################################################## +Elevation Mapping cupy documentation +################################################## +Weclome to Elevation Mapping documentation + +.. image:: https://github.com/leggedrobotics/elevation_mapping_semantic_cupy/actions/workflows/python-tests.yml/badge.svg + :target: https://github.com/leggedrobotics/elevation_mapping_semantic_cupy/actions/workflows/python-tests.yml/badge.svg + :alt: python tests + + +Index +--------------- + +| :doc:`getting_started/index` - What is elevation mapping cupy +| :doc:`getting_started/installation` - How to install the elevation map +| :doc:`getting_started/tutorial` - How to launch the first elevation map + + + + +This is a ROS package for elevation mapping on GPU. The elevation mapping code is written in python and uses cupy for GPU computation. The +plane segmentation is done independently and runs on CPU. When the plane segmentation is generated, local convex approximations of the +terrain can be efficiently generated. + +.. image:: ../media/main_repo.png + :alt: Elevation map examples + + +Citing +--------------- +.. hint:: + + Takahiro Miki, Lorenz Wellhausen, Ruben Grandia, Fabian Jenelten, Timon Homberger, Marco Hutter + + Elevation Mapping for Locomotion and Navigation using GPU `Link `_ + + + +.. code-block:: none + + @misc{https://doi.org/10.48550/arxiv.2204.12876, + doi = {10.48550/ARXIV.2204.12876}, + url = {https://arxiv.org/abs/2204.12876}, + author = {Miki, Takahiro and Wellhausen, Lorenz and Grandia, Ruben and Jenelten, Fabian and Homberger, Timon and Hutter, Marco}, + keywords = {Robotics (cs.RO), FOS: Computer and information sciences, FOS: Computer and information sciences}, + title = {Elevation Mapping for Locomotion and Navigation using GPU}, + publisher = {arXiv}, + year = {2022}, + copyright = {arXiv.org perpetual, non-exclusive license} + } + diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst index 2a97ef91..a7aeaab2 100644 --- a/docs/source/getting_started/index.rst +++ b/docs/source/getting_started/index.rst @@ -1,8 +1,9 @@ +.. _introduction: -Getting Started +Introduction ================================================== -.. toctree:: + diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst new file mode 100644 index 00000000..8bce5994 --- /dev/null +++ b/docs/source/getting_started/installation.rst @@ -0,0 +1,171 @@ +.. _installation: + +Installation +================================================== + +CUDA & cuDNN +----------------------- + +The tested versions are CUDA10.2, 11.6 + +`CUDA `_ +`cuDNN `_ + + +Check how to install :ref:`here`. + +Python dependencies +------------------------------- + +You will need + +* `cupy `_ +* `numpy `_ +* `scipy `_ +* `shapely==1.7.1 `_ + +For traversability filter, either of + +* `torch `_ +* `chainer `_ + +Optionally, OpenCV for inpainting filter. + +* `opencv-python `_ + +Install `numpy`, `scipy`, `shapely`, `opencv-python` with the following command. + +```bash +pip3 install -r requirements.txt +``` + +Cupy +------------------------------- + + +cupy can be installed with specific CUDA versions. (On jetson, only "from source" i.e. `pip install cupy` could work) +> For CUDA 10.2 +> pip install cupy-cuda102 +> +> For CUDA 11.0 +> pip install cupy-cuda110 +> +> For CUDA 11.1 +> pip install cupy-cuda111 +> +> For CUDA 11.2 +> pip install cupy-cuda112 +> +> For CUDA 11.3 +> pip install cupy-cuda113 +> +> For CUDA 11.4 +> pip install cupy-cuda114 +> +> For CUDA 11.5 +> pip install cupy-cuda115 +> +> For CUDA 11.6 +> pip install cupy-cuda116 +> +> (Install CuPy from source) +> % pip install cupy + +Traversability filter +------------------------------- + +You can choose either pytorch, or chainer to run the CNN based traversability filter. +Install by following the official documents. + +* `torch `_ +* `chainer `_ + +Pytorch uses ~2GB more GPU memory than Chainer, but runs a bit faster. +Use parameter `use_chainer` to select which backend to use. + +ROS package dependencies +------------------------------- + +* `pybind11_catkin `_ +* `grid_map `_ + +```bash +sudo apt install ros-noetic-pybind11-catkin +sudo apt install ros-noetic-grid-map-core ros-noetic-grid-map-msgs +``` + +On Jetson +================================================== + +CUDA CuDNN +------------------------------- + +`CUDA` and `cuDNN` can be installed via apt. It comes with nvidia-jetpack. The tested version is jetpack 4.5 with L4T 32.5.0. + +python dependencies +------------------------------- + +On jetson, you need the version for its CPU arch: + +```bash +wget https://nvidia.box.com/shared/static/p57jwntv436lfrd78inwl7iml6p13fzh.whl -O torch-1.8.0-cp36-cp36m-linux_aarch64.whl +pip3 install Cython +pip3 install numpy==1.19.5 torch-1.8.0-cp36-cp36m-linux_aarch64.whl +``` + +Also, you need to install cupy with + +```bash +pip3 install cupy +``` + +This builds the packages from source so it would take time. + +ROS dependencies +------------------------------- + +* `pybind11_catkin `_ +* `grid_map `_ + +```bash +sudo apt install ros-melodic-pybind11-catkin +sudo apt install ros-melodic-grid-map-core ros-melodic-grid-map-msgs +``` + +Also, on jetson you need fortran (should already be installed). + +```bash +sudo apt install gfortran +``` + +If the Jetson is set up with Jetpack 4.5 with ROS Melodic the following package is additionally required: + +```bash +git clone git@github.com:ros/filters.git -b noetic-devel +``` + +### Plane segmentation dependencies + +#### OpenCV + +```bash +sudo apt install libopencv-dev +``` + +#### Eigen + +```bash +sudo apt install libeigen3-dev +``` + +#### CGAL + +CGAL5 is required. It will be automatically downloaded and installed into the catkin workspace by the cgal5_catkin package. Make sure you +have the third-party libaries installed on you machine: + +```bash +sudo apt install libgmp-dev +sudo apt install libmpfr-dev +sudo apt install libboost-all-dev +``` + diff --git a/docs/source/getting_started/tutorial.rst b/docs/source/getting_started/tutorial.rst new file mode 100644 index 00000000..fdd9b2ff --- /dev/null +++ b/docs/source/getting_started/tutorial.rst @@ -0,0 +1,4 @@ +.. _tutorial: + +Tutorial +================================================== diff --git a/docs/source/index.rst b/docs/source/index.rst index 03bb6329..a029dc2a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,23 +1,40 @@ -################################################## -Welcome to elevation_mapping_cupy's documentation! -################################################## +.. include:: documentation.rst .. toctree:: - :maxdepth: 2 - :caption: Pages: + :maxdepth: 1 + :caption: Overview - getting_started/index - python/index +.. toctree:: + :hidden: + :maxdepth: 2 + :caption: Getting Started + + Introduction + Installation + Tutorial + +.. toctree:: + :hidden: + :maxdepth: 2 + :caption: Usage + + Plugins + Parameters + Plane Segmentation + Semantics + + +.. toctree:: + :hidden: + :maxdepth: 2 + :caption: Library + + Python -Getting Started ---------------- -For getting started checkout :doc:`getting_started/index`.. -Old Documentation ------------------ diff --git a/docs/source/usage/parameters.rst b/docs/source/usage/parameters.rst new file mode 100644 index 00000000..edff99a3 --- /dev/null +++ b/docs/source/usage/parameters.rst @@ -0,0 +1,4 @@ +.. _parameters: +Parameters +================================================== + diff --git a/docs/source/usage/plane_segmentation.rst b/docs/source/usage/plane_segmentation.rst new file mode 100644 index 00000000..883b95b1 --- /dev/null +++ b/docs/source/usage/plane_segmentation.rst @@ -0,0 +1,7 @@ +.. _plane_segmentation: + +Plane Segmentation +================================================== + +.. image:: ../media/convex_approximation.gif + :alt: Convex approximation diff --git a/docs/source/usage/plugins.rst b/docs/source/usage/plugins.rst new file mode 100644 index 00000000..8f0e517c --- /dev/null +++ b/docs/source/usage/plugins.rst @@ -0,0 +1,5 @@ +.. _plugins: + +Plugins +================================================== + diff --git a/docs/source/usage/semantics.rst b/docs/source/usage/semantics.rst new file mode 100644 index 00000000..02d30c4e --- /dev/null +++ b/docs/source/usage/semantics.rst @@ -0,0 +1,4 @@ +.. _semantics: + +Semantics +================================================== \ No newline at end of file From ff1423f038cc5036f5da29439d7b6e9560f2cc83 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Mon, 14 Nov 2022 19:25:42 +0100 Subject: [PATCH 258/504] cleaned reade to check deployment --- README.md | 156 ------------------------------------------------------ 1 file changed, 156 deletions(-) diff --git a/README.md b/README.md index 85ed128a..03a7ed52 100644 --- a/README.md +++ b/README.md @@ -27,162 +27,6 @@ terrain can be efficiently generated. } ``` -## Installation - -#### CUDA & cuDNN - -The tested versions are CUDA10.2, 11.6 - -[CUDA](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#ubuntu-installation) -[cuDNN](https://docs.nvidia.com/deeplearning/sdk/cudnn-install/index.html#install-linux). - -Check how to install [here](doc/cuda-installation.md). - -#### Python dependencies - -You will need - -- [cupy](https://cupy.chainer.org/) -- [numpy](https://www.numpy.org/) -- [scipy](https://www.scipy.org/) -- [shapely==1.7.1](https://github.com/Toblerity/Shapely) - -For traversability filter, either of - -- [torch](https://pytorch.org/) -- [chainer](https://chainer.org/) - -Optionally, OpenCV for inpainting filter. - -- [opencv-python](https://opencv.org/) - -Install `numpy`, `scipy`, `shapely`, `opencv-python` with the following command. - -```bash -pip3 install -r requirements.txt -``` - -#### Cupy - -cupy can be installed with specific CUDA versions. (On jetson, only "from source" i.e. `pip install cupy` could work) -> For CUDA 10.2 -> pip install cupy-cuda102 -> -> For CUDA 11.0 -> pip install cupy-cuda110 -> -> For CUDA 11.1 -> pip install cupy-cuda111 -> -> For CUDA 11.2 -> pip install cupy-cuda112 -> -> For CUDA 11.3 -> pip install cupy-cuda113 -> -> For CUDA 11.4 -> pip install cupy-cuda114 -> -> For CUDA 11.5 -> pip install cupy-cuda115 -> -> For CUDA 11.6 -> pip install cupy-cuda116 -> -> (Install CuPy from source) -> % pip install cupy - -#### Traversability filter - -You can choose either pytorch, or chainer to run the CNN based traversability filter. -Install by following the official documents. - -- [torch](https://pytorch.org/) -- [chainer](https://chainer.org/) - -Pytorch uses ~2GB more GPU memory than Chainer, but runs a bit faster. -Use parameter `use_chainer` to select which backend to use. - -#### ROS package dependencies - -- [pybind11_catkin](https://github.com/ipab-slmc/pybind11_catkin) -- [grid_map](https://github.com/ANYbotics/grid_map) - -```bash -sudo apt install ros-noetic-pybind11-catkin -sudo apt install ros-noetic-grid-map-core ros-noetic-grid-map-msgs -``` - -### On Jetson - -#### CUDA CuDNN - -`CUDA` and `cuDNN` can be installed via apt. It comes with nvidia-jetpack. The tested version is jetpack 4.5 with L4T 32.5.0. - -#### python dependencies - -On jetson, you need the version for its CPU arch: - -```bash -wget https://nvidia.box.com/shared/static/p57jwntv436lfrd78inwl7iml6p13fzh.whl -O torch-1.8.0-cp36-cp36m-linux_aarch64.whl -pip3 install Cython -pip3 install numpy==1.19.5 torch-1.8.0-cp36-cp36m-linux_aarch64.whl -``` - -Also, you need to install cupy with - -```bash -pip3 install cupy -``` - -This builds the packages from source so it would take time. - -#### ROS dependencies - -- [pybind11_catkin](https://github.com/ipab-slmc/pybind11_catkin) -- [grid_map](https://github.com/ANYbotics/grid_map) - -```bash -sudo apt install ros-melodic-pybind11-catkin -sudo apt install ros-melodic-grid-map-core ros-melodic-grid-map-msgs -``` - -Also, on jetson you need fortran (should already be installed). - -```bash -sudo apt install gfortran -``` - -If the Jetson is set up with Jetpack 4.5 with ROS Melodic the following package is additionally required: - -```bash -git clone git@github.com:ros/filters.git -b noetic-devel -``` - -### Plane segmentation dependencies - -#### OpenCV - -```bash -sudo apt install libopencv-dev -``` - -#### Eigen - -```bash -sudo apt install libeigen3-dev -``` - -#### CGAL - -CGAL5 is required. It will be automatically downloaded and installed into the catkin workspace by the cgal5_catkin package. Make sure you -have the third-party libaries installed on you machine: - -```bash -sudo apt install libgmp-dev -sudo apt install libmpfr-dev -sudo apt install libboost-all-dev -``` ## Usage From 812fda7a75f300681b6a685282244d32d83f8069 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Mon, 14 Nov 2022 21:30:25 +0100 Subject: [PATCH 259/504] added copy --- .github/workflows/documentation.yml | 2 +- docs/source/conf.py | 2 +- docs/source/getting_started/installation.rst | 23 ++++++++++++-------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index a64a015f..95fa80a3 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/setup-python@v2 - name: Install dependencies run: | - pip install sphinx sphinx_rtd_theme + pip install sphinx sphinx_rtd_theme sphinx-copybutton - name: Sphinx build run: | sphinx-build docs/source docs/_build diff --git a/docs/source/conf.py b/docs/source/conf.py index a1f29f10..9eb4db46 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -25,7 +25,7 @@ # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage', 'sphinx.ext.napoleon'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage', 'sphinx.ext.napoleon','sphinx_copybutton'] templates_path = ['_templates'] exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 8bce5994..02baeb14 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -107,11 +107,12 @@ python dependencies On jetson, you need the version for its CPU arch: -```bash -wget https://nvidia.box.com/shared/static/p57jwntv436lfrd78inwl7iml6p13fzh.whl -O torch-1.8.0-cp36-cp36m-linux_aarch64.whl -pip3 install Cython -pip3 install numpy==1.19.5 torch-1.8.0-cp36-cp36m-linux_aarch64.whl -``` +.. code-block:: bash + + wget https://nvidia.box.com/shared/static/p57jwntv436lfrd78inwl7iml6p13fzh.whl -O torch-1.8.0-cp36-cp36m-linux_aarch64.whl + pip3 install Cython + pip3 install numpy==1.19.5 torch-1.8.0-cp36-cp36m-linux_aarch64.whl + Also, you need to install cupy with @@ -144,21 +145,25 @@ If the Jetson is set up with Jetpack 4.5 with ROS Melodic the following package git clone git@github.com:ros/filters.git -b noetic-devel ``` -### Plane segmentation dependencies +Plane segmentation dependencies +===================================== -#### OpenCV +OpenCV +------------------------------- ```bash sudo apt install libopencv-dev ``` -#### Eigen +Eigen +------------------------------- ```bash sudo apt install libeigen3-dev ``` -#### CGAL +CGAL +------------------------------- CGAL5 is required. It will be automatically downloaded and installed into the catkin workspace by the cgal5_catkin package. Make sure you have the third-party libaries installed on you machine: From bcd2cbbe14dbcfdd7def8a85953d87464cbdea14 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Tue, 15 Nov 2022 16:38:10 +0100 Subject: [PATCH 260/504] added bayesian class kernel and also semantic segmentation image publisher --- .gitignore | 6 +- .../elevation_mapping_cupy/custom_kernels.py | 45 +++++++++++- .../plugins/semantic_filter.py | 37 ++++++---- .../elevation_mapping_cupy/semantic_map.py | 31 ++++++++- .../tests/test_elevation_mapping.py | 2 + .../tests/test_semantic_map.py | 5 +- requirements.txt | 1 + .../semantic_pointcloud/pointcloud_node.py | 68 ++++++++++++++++++- .../pointcloud_parameters.py | 2 + 9 files changed, 177 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 0f73a391..1fbf49f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,8 @@ *.pyc *.bkp *.orig -.idea \ No newline at end of file +.idea +.pytest_cache +.run/ +docs/build +_build \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py index d8c53eac..4caa3cbe 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py @@ -694,6 +694,50 @@ def sum_kernel( ) return sum_kernel +def alpha_kernel( + resolution, + width, + height, + ): + # input the list of layers, amount of channels can slo be input through kernel + alpha_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution,width=width, height=height), + operation=string.Template( + """ + U idx = p[i * pcl_channels[0]]; + U valid = p[i * pcl_channels[0] + 1]; + U inside = p[i * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U theta_max = 0; + W arg_max = 0; + for ( W it=0;it=theta_max){ + arg_max = map_lay[it]; + theta_max = theta; + } + } + atomicAdd(&newmap[get_map_idx(idx, arg_max)], 1.0); + } + } + """ + ).substitute( + ), + name="alpha_kernel", + ) + return alpha_kernel + + def average_kernel( width, @@ -875,7 +919,6 @@ def color_average_kernel( ) return color_average_kernel -# TODO: in future add more kernels e.g. bayesian kernel if __name__ == "__main__": for i in range(10): diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index d91b15fb..2f82ad68 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -24,22 +24,35 @@ def __init__( self, cell_n: int = 100, classes: list = ["person", "grass"], - colors: list = [ - [0, 255, 0], - [0, 255, 255], - [0, 0, 255], - [255, 255, 0], - [255, 0, 0], - ], **kwargs, ): super().__init__() self.indices = [] self.classes = classes - color_classes = np.array(colors) - self.color_encoding = self.transform_color(color_classes) + self.color_encoding = self.transform_color() - def transform_color(self, color_classes): + def color_map(self, N=256, normalized=False): + def bitget(byteval, idx): + return (byteval & (1 << idx)) != 0 + + dtype = "float32" if normalized else "uint8" + cmap = np.zeros((N+1, 3), dtype=dtype) + for i in range(N+1): + r = g = b = 0 + c = i + for j in range(8): + r = r | (bitget(c, 0) << 7 - j) + g = g | (bitget(c, 1) << 7 - j) + b = b | (bitget(c, 2) << 7 - j) + c = c >> 3 + + cmap[i] = np.array([r, g, b]) + + cmap = cmap / 255 if normalized else cmap + return cmap[1:] + + def transform_color(self): + color_classes = self.color_map(len(self.classes)) r = np.asarray(color_classes[:, 0], dtype=np.uint32) g = np.asarray(color_classes[:, 1], dtype=np.uint32) b = np.asarray(color_classes[:, 2], dtype=np.uint32) @@ -59,9 +72,7 @@ def __call__( # get indices of all layers that layer_indices = cp.array([], dtype=cp.int32) for it, fusion_alg in enumerate(semantic_map.param.fusion_algorithms): - if fusion_alg == "class_average" and ( - semantic_map.param.additional_layers[it] in self.classes - ): + if (fusion_alg in ["class_bayesian","class_average"]): layer_indices = cp.append(layer_indices, it).astype(cp.int32) # check which has the highest value diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index e8c3a4af..7ab2b289 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -8,6 +8,7 @@ color_average_kernel, average_kernel, class_average_kernel, + alpha_kernel, ) xp = cp @@ -74,7 +75,7 @@ def compile_kernels(self) -> None: self.param.cell_n, self.param.cell_n ) if "class_average" in self.unique_fusion: - print("Initialize fusion kernel") + print("Initialize class average kernel") self.sum_kernel = sum_kernel( self.param.resolution, self.param.cell_n, @@ -84,6 +85,13 @@ def compile_kernels(self) -> None: self.param.cell_n, self.param.cell_n, ) + if "class_bayesian" in self.unique_fusion: + print("Initialize class bayesian kernel") + self.alpha_kernel = alpha_kernel( + self.param.resolution, + self.param.cell_n, + self.param.cell_n, + ) def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: """Get all fusion algorithms that need to be applied to a specific pointcloud @@ -99,7 +107,7 @@ def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: return fusion_list def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): - """Computes the indices that are used for the additional kernel update of the pcl and the elmap. + """Computes the indices that are used for the additional kernel update of the popintcloud and the semantic map. Args: pcl_channels (List[str]): @@ -172,6 +180,25 @@ def update_layers(self, points_all, channels, R, t, elevation_map): size=(self.param.cell_n * self.param.cell_n), ) + if "class_bayesian" in additional_fusion: + pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_bayesian") + # alpha sum get points as input and calculate for each point to what cell it belongs and then + # adds to the right channel a one + self.alpha_kernel( + points_all, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + self.new_map, + size=(points_all.shape[0]), + ) + # calculate new thetas + sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) + self.map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims( + sum_alpha, axis=0 + ) + # assert cp.unique(cp.sum(self.map[layer_ids], axis=0)) equal to zero or to nan + if "color" in additional_fusion: pcl_ids, layer_ids = self.get_indices_fusion(channels, "color") if self.color_map is None: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py index b9ce3b41..e7e36c19 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -25,6 +25,8 @@ def elmap_ex(add_lay, fusion_alg): [ (["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), (["feat_0", "feat_1"], ["average", "average"]), + (["feat_0", "feat_1"], ["class_average", "class_average"]), + (["feat_0", "feat_1"], ["class_bayesian", "class_bayesian"]), ], ) class TestElevationMap: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py index a083a477..86eba134 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py @@ -26,6 +26,9 @@ def semmap_ex(add_lay, fusion_alg): [(["feat_0", "feat_1"], ["average", "average"],["feat_0"]), (["feat_0", "feat_1"], ["average", "average"],[]), (["feat_0", "feat_1", "rgb"], ["average", "average", "color"],["rgb", "feat_0"]), + (["feat_0", "feat_1", "rgb"], ["class_average", "average", "color"], ["rgb", "feat_0"]), + (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0"]), + (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0", "feat_1"]), ], ) def test_fusion_of_pcl(semmap_ex, channels): @@ -42,4 +45,4 @@ def test_fusion_of_pcl(semmap_ex, channels): ) @pytest.mark.parametrize("channels", [["rgb"], ["rgb", "feat_0"], []]) def test_indices_fusion(semmap_ex, channels,fusion_alg): - pcl_indices, layer_indices = semmap_ex.get_indices_fusion(pcl_channels=channels,fusion_alg=fusion_alg[0]) + pcl_indices, layer_indices = semmap_ex.get_indices_fusion(pcl_channels=channels, fusion_alg=fusion_alg[0]) diff --git a/requirements.txt b/requirements.txt index c68be6a1..f6e3233d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,7 @@ dataclasses ruamel.yaml opencv-python simple_parsing +scikit-image ###### Requirements with Version Specifiers ######` shapely==1.7.1 diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index 93567951..f42983d3 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -4,10 +4,12 @@ import numpy as np import cupy as cp import ros_numpy +import matplotlib.pyplot as plt +from skimage.io import imshow import message_filters from sensor_msgs.msg import Image, CameraInfo -from sensor_msgs.msg import PointCloud2 +from sensor_msgs.msg import PointCloud2, Image from cv_bridge import CvBridge from semantic_pointcloud.pointcloud_parameters import PointcloudParameter @@ -67,6 +69,52 @@ def __init__(self, sensor_name): ts.registerCallback(self.image_callback) self.pcl_pub = rospy.Publisher(self.param.topic_name, PointCloud2, queue_size=2) + if self.param.publish_segmentation_image: + self.seg_pub = rospy.Publisher( + self.param.segmentation_image_topic, Image, queue_size=2 + ) + self.semseg_color_map = self.color_map( + len(list(self.segmentation_channels.keys())) + ) + self.color_map_viz() + + def color_map(self, N=256, normalized=False): + def bitget(byteval, idx): + return (byteval & (1 << idx)) != 0 + + dtype = "float32" if normalized else "uint8" + cmap = np.zeros((N + 1, 3), dtype=dtype) + for i in range(N + 1): + r = g = b = 0 + c = i + for j in range(8): + r = r | (bitget(c, 0) << 7 - j) + g = g | (bitget(c, 1) << 7 - j) + b = b | (bitget(c, 2) << 7 - j) + c = c >> 3 + + cmap[i] = np.array([r, g, b]) + + cmap = cmap / 255 if normalized else cmap + return cmap[1:] + + def color_map_viz(self): + # labels = self.semantic_model["model"].get_classes() + labels = list(self.segmentation_channels.keys()) + nclasses = len(labels) + row_size = 50 + col_size = 500 + cmap = self.semseg_color_map + array = np.empty( + (row_size * (nclasses), col_size, cmap.shape[1]), dtype=cmap.dtype + ) + for i in range(nclasses): + array[i * row_size : i * row_size + row_size, :] = cmap[i] + imshow(array) + plt.yticks([row_size * i + row_size / 2 for i in range(nclasses)], labels) + plt.xticks([]) + plt.show() + # plt.savefig("./labels.png") def initialize_semantics(self): if self.param.semantic_segmentation: @@ -81,10 +129,12 @@ def initialize_semantics(self): ) indices = [] channels = [] - for chan in self.param.channels: + for it, chan in enumerate(self.param.channels): if chan in [cls for cls in list(class_to_idx.keys())]: indices.append(class_to_idx[chan]) channels.append(chan) + elif self.param.fusion[it] in ["class_average", "class_bayesian"]: + print(chan, " is not in the semantic segmentation model.") self.segmentation_channels = dict(zip(channels, indices)) if self.param.feature_extractor: self.feature_channels = [] @@ -111,6 +161,7 @@ def cam_info_callback(self, msg): self.P = cp.resize(a, (3, 4)) self.height = msg.height self.width = msg.width + self.header = msg.header def image_callback(self, rgb_msg, depth_msg, confidence_msg=None): confidence = None @@ -190,6 +241,8 @@ def perform_segmentation(self, image, points, u, v): values = mask[:, v.get(), u.get()].cpu().detach().numpy() for it, channel in enumerate(self.segmentation_channels.keys()): points[channel] = values[it] + if self.param.publish_segmentation_image: + self.publish_segmentation_image(mask) def extract_features(self, image, points, u, v): prediction = self.feature_extractor["model"](image) @@ -197,6 +250,17 @@ def extract_features(self, image, points, u, v): for it, channel in enumerate(self.feature_channels): points[channel] = values[it] + def publish_segmentation_image(self, probabilities): + probabilities = cp.asarray(probabilities) + colors = cp.asarray(self.semseg_color_map) + assert colors.ndim == 2 and colors.shape[1] == 3 + img = cp.argmax(probabilities, axis=0) + img = colors[img].astype(cp.uint8) # N x H x W x 3 + img = img.get() + seg_msg = self.cv_bridge.cv2_to_imgmsg(img, encoding="rgb8") + seg_msg.header.frame_id = self.header.frame_id + self.seg_pub.publish(seg_msg) + if __name__ == "__main__": sensor_name = sys.argv[1] diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py index e5426b2f..2083abf4 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py @@ -25,6 +25,8 @@ class PointcloudParameter(Serializable): semantic_segmentation: bool = True segmentation_model: str = "detectron_coco_panoptic_fpn_R_101_3x" + publish_segmentation_image: bool = True + segmentation_image_topic: str = "/semantic_pointcloud/sem_seg" cam_info_topic: str = "/zed2i/zed_node/depth/camera_info" image_topic: str = "/zed2i/zed_node/left/image_rect_color" From d36581aebdf2b6599861be368785f7576376d1a2 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Wed, 16 Nov 2022 16:56:53 +0100 Subject: [PATCH 261/504] added bayesian inference fusion process --- .../elevation_mapping_cupy/custom_kernels.py | 75 +++++++++++++++++++ .../elevation_mapping_cupy/semantic_map.py | 46 +++++++++++- .../tests/test_elevation_mapping.py | 1 + 3 files changed, 121 insertions(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py index 4caa3cbe..66406271 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py @@ -694,6 +694,43 @@ def sum_kernel( ) return sum_kernel +def sum_compact_kernel( + resolution, + width, + height, + ): + # input the list of layers, amount of channels can slo be input through kernel + sum_compact_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params=" raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution,width=width, height=height), + operation=string.Template( + """ + U idx = p[i * pcl_channels[0]]; + U valid = p[i * pcl_channels[0] + 1]; + U inside = p[i * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + for ( W it=0;it0){ + for ( int it=0;it None: self.param.cell_n, self.param.cell_n, ) - + if "bayesian_inference" in self.unique_fusion: + print("Initialize bayesian inference kernel") + self.sum_mean = xp.ones( + ( + self.param.fusion_algorithms.count("bayesian_inference"), + self.param.cell_n, + self.param.cell_n, + ), + self.param.data_type, + ) + # todo initialize the variance with a value different than 0 + self.sum_compact_kernel = sum_compact_kernel( + self.param.resolution, + self.param.cell_n, + self.param.cell_n, + ) + self.bayesian_inference_kernel = bayesian_inference_kernel( + self.param.cell_n, + self.param.cell_n, + ) if "color" in self.unique_fusion: print("Initialize color kernel") self.add_color_kernel = add_color_kernel( @@ -157,6 +178,29 @@ def update_layers(self, points_all, channels, R, t, elevation_map): self.map, size=(self.param.cell_n * self.param.cell_n), ) + if "bayesian_inference" in additional_fusion: + pcl_ids, layer_ids = self.get_indices_fusion(channels, "bayesian_inference") + self.sum_mean *= 0 + self.sum_compact_kernel( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + self.sum_mean, + size=(points_all.shape[0]), + ) + self.bayesian_inference_kernel( + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + elevation_map, + self.new_map, + self.sum_mean, + self.map, + size=(self.param.cell_n * self.param.cell_n), + ) if "class_average" in additional_fusion: pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_average") self.sum_kernel( diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py index e7e36c19..71559122 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -27,6 +27,7 @@ def elmap_ex(add_lay, fusion_alg): (["feat_0", "feat_1"], ["average", "average"]), (["feat_0", "feat_1"], ["class_average", "class_average"]), (["feat_0", "feat_1"], ["class_bayesian", "class_bayesian"]), + (["feat_0", "feat_1"], ["bayesian_inference", "bayesian_inference"]), ], ) class TestElevationMap: From 96bf424b27c4581d1fb959951a45f4a965ff67d2 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Wed, 16 Nov 2022 17:42:14 +0100 Subject: [PATCH 262/504] change from few to all classes on image pub --- .../semantic_pointcloud/pointcloud_node.py | 19 +++++++++++-------- .../pointcloud_parameters.py | 1 + 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index f42983d3..932e34d7 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -73,9 +73,11 @@ def __init__(self, sensor_name): self.seg_pub = rospy.Publisher( self.param.segmentation_image_topic, Image, queue_size=2 ) - self.semseg_color_map = self.color_map( - len(list(self.segmentation_channels.keys())) - ) + if self.param.pub_all: + self.labels = self.semantic_model["model"].get_classes() + else: + self.labels = list(self.segmentation_channels.keys()) + self.semseg_color_map = self.color_map(len(self.labels)) self.color_map_viz() def color_map(self, N=256, normalized=False): @@ -99,9 +101,7 @@ def bitget(byteval, idx): return cmap[1:] def color_map_viz(self): - # labels = self.semantic_model["model"].get_classes() - labels = list(self.segmentation_channels.keys()) - nclasses = len(labels) + nclasses = len(self.labels) row_size = 50 col_size = 500 cmap = self.semseg_color_map @@ -111,7 +111,7 @@ def color_map_viz(self): for i in range(nclasses): array[i * row_size : i * row_size + row_size, :] = cmap[i] imshow(array) - plt.yticks([row_size * i + row_size / 2 for i in range(nclasses)], labels) + plt.yticks([row_size * i + row_size / 2 for i in range(nclasses)], self.labels) plt.xticks([]) plt.show() # plt.savefig("./labels.png") @@ -242,7 +242,10 @@ def perform_segmentation(self, image, points, u, v): for it, channel in enumerate(self.segmentation_channels.keys()): points[channel] = values[it] if self.param.publish_segmentation_image: - self.publish_segmentation_image(mask) + if self.param.pub_all: + self.publish_segmentation_image(prediction) + else: + self.publish_segmentation_image(mask) def extract_features(self, image, points, u, v): prediction = self.feature_extractor["model"](image) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py index 2083abf4..abdf0491 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py @@ -27,6 +27,7 @@ class PointcloudParameter(Serializable): segmentation_model: str = "detectron_coco_panoptic_fpn_R_101_3x" publish_segmentation_image: bool = True segmentation_image_topic: str = "/semantic_pointcloud/sem_seg" + pub_all: bool = False cam_info_topic: str = "/zed2i/zed_node/depth/camera_info" image_topic: str = "/zed2i/zed_node/left/image_rect_color" From c53f09030c0a0273c09dc9995c61385473b61e4a Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Wed, 16 Nov 2022 19:16:36 +0100 Subject: [PATCH 263/504] added everything that was already present --- README.md | 207 ------------------ docs/media/cuda-installation.md | 21 -- .../getting_started/cuda_installation.rst | 30 +++ docs/source/getting_started/index.rst | 62 +++++- docs/source/getting_started/installation.rst | 180 +++++++++------ docs/source/getting_started/tutorial.rst | 108 ++++++++- docs/source/python/custom_kernels.rst | 2 +- docs/source/python/elevation_mapping.rst | 2 +- docs/source/python/index.rst | 2 +- docs/source/python/semantic_pointcloud.rst | 2 +- docs/source/usage/parameters.rst | 3 +- docs/source/usage/plane_segmentation.rst | 2 +- docs/source/usage/plugins.rst | 63 +++++- docs/source/usage/semantics.rst | 2 +- 14 files changed, 375 insertions(+), 311 deletions(-) delete mode 100644 docs/media/cuda-installation.md create mode 100644 docs/source/getting_started/cuda_installation.rst diff --git a/README.md b/README.md index 03a7ed52..9dba2ed3 100644 --- a/README.md +++ b/README.md @@ -27,210 +27,3 @@ terrain can be efficiently generated. } ``` - -## Usage - -### Build - -```bash -catkin build elevation_mapping_cupy -catkin build convex_plane_decomposition_ros -``` - -#### Errors - -If you get error such as - -``` -Make Error at /usr/share/cmake-3.16/Modules/FindPackageHandleStandardArgs.cmake:146 (message): - Could NOT find PythonInterp: Found unsuitable version "2.7.18", but - required is at least "3" (found /usr/bin/python) -``` - -Build with option. - -```bash -catkin build elevation_mapping_cupy -DPYTHON_EXECUTABLE=$(which python3) -``` - -### Run - -Basic usage. - -```bash -roslaunch elevation_mapping_cupy elevation_mapping_cupy.launch -``` - -For the plane segmentation node - -```bash -roslaunch convex_plane_decomposition_ros convex_plane_decomposition.launch -``` - -#### Errors -If you build with the install flag under ros melodic, you might get issues with the modules not found: - -```bash -terminate called after throwing an instance of 'pybind11::error_already_set' - what(): ModuleNotFoundError: No module named 'elevation_mapping_cupy' -``` -This is because python3 modules are installed into a different location. - -This can be fixed by including also the python3 modules location in the `PYTHONPATH` by adding following line into the launch file: - -```xml - -``` - -### Run TurtleBot example - -First, install turtlebot simulation. - -```bash -sudo apt install ros-noetic-turtlebot3-gazebo ros-noetic-turtlebot3-teleop -``` - -Then, you can run the examples. For the basic version: - -```bash -export TURTLEBOT3_MODEL=waffle -roslaunch elevation_mapping_cupy turtlesim_example.launch -``` - -Or, for the version including plane segmentation: - -```bash -catkin build convex_plane_decomposition_ros -export TURTLEBOT3_MODEL=waffle -roslaunch elevation_mapping_cupy turtlesim_segmentation_example.launch -``` - -To control the robot with a keyboard, a new terminal window needs to be opened. -Then run - -```bash -export TURTLEBOT3_MODEL=waffle -roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch -``` - -Velocity inputs can be sent to the robot by pressing the keys `a`, `w`, `d`, `x`. To stop the robot completely, press `s`. - -### Subscribed Topics - -* topics specified in **`pointcloud_topics`** in **`elevation_mapping_cupy/config/parameters.yaml`** ([sensor_msgs/PointCloud2]) - - The distance measurements. - -* **`/tf`** ([tf/tfMessage]) - - The transformation tree. - -* The plane segmentation node subscribes to an elevation map topic ([grid_map_msg/GridMap]). This can be configured in - **`convex_plane_decomposition_ros/config/parameters.yaml`** - -### Published Topics - -For elevation_mapping_cupy, topics are published as set in the rosparam. -You can specify which layers to publish in which fps. - -Under `publishers`, you can specify the `topic_name`, `layers` `basic_layers` and `fps`. - -```yaml -publishers: - your_topic_name: - layers: [ 'list_of_layer_names', 'layer1', 'layer2' ] # Choose from 'elevation', 'variance', 'traversability', 'time' + plugin layers - basic_layers: [ 'list of basic layers', 'layer1' ] # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. - fps: 5.0 # Publish rate. Use smaller value than `map_acquire_fps`. -``` - -Example setting in `config/parameters.yaml`. - -* **`elevation_map_raw`** ([grid_map_msg/GridMap]) - - The entire elevation map. - -* **`elevation_map_recordable`** ([grid_map_msg/GridMap]) - - The entire elevation map with slower update rate for visualization and logging. - -* **`elevation_map_filter`** ([grid_map_msg/GridMap]) - - The filtered maps using plugins. - -The plane segmentation node publishes the following: - -* **`planar_terrain`** ([convex_plane_decomposition_msgs/PlanarTerrain]) - - A custom message that contains the full segmentation as a map together with the boundary information. - -* **`filtered_map`** ([grid_map_msg/GridMap]) - - A grid map message to visualize the segmentation and some intermediate results. This information is also part of **`planar_terrain`**. - -* **`boundaries`** ([visualization_msgs/MarkerArray]) - - A set of polygons that trace the boundaries of the segmented region. Holes and boundaries of a single region are published as separate - markers with the same color. - -* **`insets`** ([visualization_msgs/PolygonArray]) - - A set of polygons that are at a slight inward offset from **`boundaries`**. There might be more insets than boundaries since the inward - shift can cause a single region to break down into multiple when narrow passages exist. - -# Plugins - -You can create your own plugin to process the elevation map and publish as a layer in GridMap message. - -Let's look at the example. - -First, create your plugin file in `elevation_mapping_cupy/script/plugins/` and save as `example.py`. - -```python -import cupy as cp -from typing import List -from .plugin_manager import PluginBase - - -class NameOfYourPlugin(PluginBase): - def __init__(self, add_value:float=1.0, **kwargs): - super().__init__() - self.add_value = float(add_value) - - def __call__(self, elevation_map: cp.ndarray, layer_names: List[str], - plugin_layers: cp.ndarray, plugin_layer_names: List[str])->cp.ndarray: - # Process maps here - # You can also use the other plugin's data through plugin_layers. - new_elevation = elevation_map[0] + self.add_value - return new_elevation -``` - -Then, add your plugin setting to `config/plugin_config.yaml` - -```yaml -example: # Name of your filter - type: "example" # Specify the name of your plugin (the name of your file name). - enable: True # weather to load this plugin - fill_nan: True # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "example_layer" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - add_value: 2.0 # Example param - -example_large: # You can apply same filter with different name. - type: "example" # Specify the name of your plugin (the name of your file name). - enable: True # weather to load this plugin - fill_nan: True # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "example_layer_large" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - add_value: 100.0 # Example param with larger value. -``` - -Finally, add your layer name to publishers in `config/parameters.yaml`. You can create a new topic or add to existing topics. - -```yaml - plugin_example: # Topic name - layers: [ 'elevation', 'example_layer', 'example_layer_large' ] - basic_layers: [ 'example_layer' ] - fps: 1.0 # The plugin is called with this fps. -``` diff --git a/docs/media/cuda-installation.md b/docs/media/cuda-installation.md deleted file mode 100644 index 17fe2481..00000000 --- a/docs/media/cuda-installation.md +++ /dev/null @@ -1,21 +0,0 @@ -#### CUDA -You can download CUDA10.2 from [here](https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin). -You can follow the instruction. -```bash -wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin -sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600 -sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub -sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/ /" -sudo apt-get update -sudo apt-get -y install cuda -``` - -#### cuDNN -You can download specific version from [here](https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/). -For example, the tested version is with `libcudnn8_8.0.0.180-1+cuda10.2_amd64.deb`. - -Then install them using the command below. -```bash -sudo dpkg -i libcudnn8_8.0.0.180-1+cuda10.2_amd64.deb -sudo dpkg -i libcudnn8-dev_8.0.0.180-1+cuda10.2_amd64.deb -``` diff --git a/docs/source/getting_started/cuda_installation.rst b/docs/source/getting_started/cuda_installation.rst new file mode 100644 index 00000000..cc656f63 --- /dev/null +++ b/docs/source/getting_started/cuda_installation.rst @@ -0,0 +1,30 @@ +.. _cuda_installation: + +TODO add this to the +CUDA +****************************************************************** + +You can download CUDA10.2 from [here](https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin). +You can follow the instruction. +.. code-block:: bash + + wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin + sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600 + sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub + sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/ /" + sudo apt-get update + sudo apt-get -y install cuda + + +cuDNN +****************************************************************** + +You can download specific version from [here](https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/). +For example, the tested version is with `libcudnn8_8.0.0.180-1+cuda10.2_amd64.deb`. + +Then install them using the command below. +.. code-block:: bash + + sudo dpkg -i libcudnn8_8.0.0.180-1+cuda10.2_amd64.deb + sudo dpkg -i libcudnn8-dev_8.0.0.180-1+cuda10.2_amd64.deb + diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst index a7aeaab2..7b0ec137 100644 --- a/docs/source/getting_started/index.rst +++ b/docs/source/getting_started/index.rst @@ -1,9 +1,69 @@ .. _introduction: Introduction -================================================== +****************************************************************** +Subscribed Topics +------------------------------------------------------------------- +* topics specified in **`pointcloud_topics`** in **`elevation_mapping_cupy/config/parameters.yaml`** ([sensor_msgs/PointCloud2]) + The distance measurements. +* **`/tf`** ([tf/tfMessage]) + + The transformation tree. + +* The plane segmentation node subscribes to an elevation map topic ([grid_map_msg/GridMap]). This can be configured in + **`convex_plane_decomposition_ros/config/parameters.yaml`** + +Published Topics +------------------------------------------------------------------- +For elevation_mapping_cupy, topics are published as set in the rosparam. +You can specify which layers to publish in which fps. + +Under `publishers`, you can specify the `topic_name`, `layers` `basic_layers` and `fps`. + +.. code-block:: yaml + + publishers: + your_topic_name: + layers: [ 'list_of_layer_names', 'layer1', 'layer2' ] # Choose from 'elevation', 'variance', 'traversability', 'time' + plugin layers + basic_layers: [ 'list of basic layers', 'layer1' ] # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. + fps: 5.0 # Publish rate. Use smaller value than `map_acquire_fps`. + + +Example setting in `config/parameters.yaml`. + +* **`elevation_map_raw`** ([grid_map_msg/GridMap]) + + The entire elevation map. + +* **`elevation_map_recordable`** ([grid_map_msg/GridMap]) + + The entire elevation map with slower update rate for visualization and logging. + +* **`elevation_map_filter`** ([grid_map_msg/GridMap]) + + The filtered maps using plugins. + +The plane segmentation node publishes the following: + +* **`planar_terrain`** ([convex_plane_decomposition_msgs/PlanarTerrain]) + + A custom message that contains the full segmentation as a map together with the boundary information. + +* **`filtered_map`** ([grid_map_msg/GridMap]) + + A grid map message to visualize the segmentation and some intermediate results. This information is also part of **`planar_terrain`**. + +* **`boundaries`** ([visualization_msgs/MarkerArray]) + + A set of polygons that trace the boundaries of the segmented region. Holes and boundaries of a single region are published as separate + markers with the same color. + +* **`insets`** ([visualization_msgs/PolygonArray]) + + A set of polygons that are at a slight inward offset from **`boundaries`**. There might be more insets than boundaries since the inward + shift can cause a single region to break down into multiple when narrow passages exist. diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 02baeb14..f4bbcfeb 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -1,10 +1,10 @@ .. _installation: Installation -================================================== +****************************************************************** CUDA & cuDNN ------------------------ +================================================================== The tested versions are CUDA10.2, 11.6 @@ -12,10 +12,10 @@ The tested versions are CUDA10.2, 11.6 `cuDNN `_ -Check how to install :ref:`here`. +Check how to install :ref:`here`. Python dependencies -------------------------------- +------------------------------------------------------------------- You will need @@ -35,44 +35,72 @@ Optionally, OpenCV for inpainting filter. Install `numpy`, `scipy`, `shapely`, `opencv-python` with the following command. -```bash -pip3 install -r requirements.txt -``` +.. code-block:: bash + + pip3 install -r requirements.txt + Cupy -------------------------------- +------------------------------------------------------------------- cupy can be installed with specific CUDA versions. (On jetson, only "from source" i.e. `pip install cupy` could work) -> For CUDA 10.2 -> pip install cupy-cuda102 -> -> For CUDA 11.0 -> pip install cupy-cuda110 -> -> For CUDA 11.1 -> pip install cupy-cuda111 -> -> For CUDA 11.2 -> pip install cupy-cuda112 -> -> For CUDA 11.3 -> pip install cupy-cuda113 -> -> For CUDA 11.4 -> pip install cupy-cuda114 -> -> For CUDA 11.5 -> pip install cupy-cuda115 -> -> For CUDA 11.6 -> pip install cupy-cuda116 -> -> (Install CuPy from source) -> % pip install cupy +For CUDA 10.2 + +.. code-block:: bash + + pip install cupy-cuda102 + +For CUDA 11.0 + +.. code-block:: bash + + pip install cupy-cuda110 + +For CUDA 11.1 + +.. code-block:: bash + + pip install cupy-cuda111 + +For CUDA 11.2 + +.. code-block:: bash + + pip install cupy-cuda112 + +For CUDA 11.3 + +.. code-block:: bash + + pip install cupy-cuda113 + +For CUDA 11.4 + +.. code-block:: bash + + pip install cupy-cuda114 + +For CUDA 11.5 + +.. code-block:: bash + + pip install cupy-cuda115 + +For CUDA 11.6 + +.. code-block:: bash + + pip install cupy-cuda116 + +(Install CuPy from source) + +.. code-block:: bash + + pip install cupy Traversability filter -------------------------------- +------------------------------------------------------------------- You can choose either pytorch, or chainer to run the CNN based traversability filter. Install by following the official documents. @@ -84,26 +112,27 @@ Pytorch uses ~2GB more GPU memory than Chainer, but runs a bit faster. Use parameter `use_chainer` to select which backend to use. ROS package dependencies -------------------------------- +------------------------------------------------------------------- * `pybind11_catkin `_ * `grid_map `_ -```bash -sudo apt install ros-noetic-pybind11-catkin -sudo apt install ros-noetic-grid-map-core ros-noetic-grid-map-msgs -``` +.. code-block:: bash + + sudo apt install ros-noetic-pybind11-catkin + sudo apt install ros-noetic-grid-map-core ros-noetic-grid-map-msgs + On Jetson -================================================== +================================================================== CUDA CuDNN -------------------------------- +------------------------------------------------------------------- `CUDA` and `cuDNN` can be installed via apt. It comes with nvidia-jetpack. The tested version is jetpack 4.5 with L4T 32.5.0. -python dependencies -------------------------------- +Python dependencies +------------------------------------------------------------------- On jetson, you need the version for its CPU arch: @@ -116,61 +145,66 @@ On jetson, you need the version for its CPU arch: Also, you need to install cupy with -```bash -pip3 install cupy -``` +.. code-block:: bash + + pip3 install cupy + This builds the packages from source so it would take time. ROS dependencies -------------------------------- +----------------------- * `pybind11_catkin `_ * `grid_map `_ -```bash -sudo apt install ros-melodic-pybind11-catkin -sudo apt install ros-melodic-grid-map-core ros-melodic-grid-map-msgs -``` +.. code-block:: bash + + sudo apt install ros-melodic-pybind11-catkin + sudo apt install ros-melodic-grid-map-core ros-melodic-grid-map-msgs + Also, on jetson you need fortran (should already be installed). -```bash -sudo apt install gfortran -``` +.. code-block:: bash + + sudo apt install gfortran + If the Jetson is set up with Jetpack 4.5 with ROS Melodic the following package is additionally required: -```bash -git clone git@github.com:ros/filters.git -b noetic-devel -``` +.. code-block:: bash + + git clone git@github.com:ros/filters.git -b noetic-devel + Plane segmentation dependencies -===================================== +================================================================== OpenCV -------------------------------- +------------------------------------------------------------------- -```bash -sudo apt install libopencv-dev -``` +.. code-block:: bash + + sudo apt install libopencv-dev Eigen -------------------------------- +------------------------------------------------------------------- + +.. code-block:: bash -```bash -sudo apt install libeigen3-dev -``` + sudo apt install libeigen3-dev CGAL -------------------------------- +------------------------------------------------------------------- CGAL5 is required. It will be automatically downloaded and installed into the catkin workspace by the cgal5_catkin package. Make sure you have the third-party libaries installed on you machine: -```bash -sudo apt install libgmp-dev -sudo apt install libmpfr-dev -sudo apt install libboost-all-dev -``` +.. code-block:: bash + + sudo apt install libgmp-dev + sudo apt install libmpfr-dev + sudo apt install libboost-all-dev + diff --git a/docs/source/getting_started/tutorial.rst b/docs/source/getting_started/tutorial.rst index fdd9b2ff..e5ea68f7 100644 --- a/docs/source/getting_started/tutorial.rst +++ b/docs/source/getting_started/tutorial.rst @@ -1,4 +1,110 @@ .. _tutorial: Tutorial -================================================== +****************************************************************** + + + +Build +================================================================== + +.. code-block:: bash + + catkin build elevation_mapping_cupy + catkin build convex_plane_decomposition_ros + + +Errors +""""""""""""" + +If you get error such as + +.. code-block:: none + + Make Error at /usr/share/cmake-3.16/Modules/FindPackageHandleStandardArgs.cmake:146 (message): + Could NOT find PythonInterp: Found unsuitable version "2.7.18", but + required is at least "3" (found /usr/bin/python) + + +Build with option. + +.. code-block:: bash + + catkin build elevation_mapping_cupy -DPYTHON_EXECUTABLE=$(which python3) + + +Run +================================================================== + +Basic usage. + +.. code-block:: bash + + roslaunch elevation_mapping_cupy elevation_mapping_cupy.launch + + +For the plane segmentation node + +.. code-block:: bash + + roslaunch convex_plane_decomposition_ros convex_plane_decomposition.launch + + +Errors +""""""""""""" + +If you build with the install flag under ros melodic, you might get issues with the modules not found: + +.. code-block:: bash + + terminate called after throwing an instance of 'pybind11::error_already_set' + what(): ModuleNotFoundError: No module named 'elevation_mapping_cupy' + +This is because python3 modules are installed into a different location. + +This can be fixed by including also the python3 modules location in the `PYTHONPATH` by adding following line into the launch file: + +.. code-block:: xml + + + + +Run TurtleBot example +================================================================== + +First, install turtlebot simulation. + +.. code-block:: bash + + sudo apt install ros-noetic-turtlebot3-gazebo ros-noetic-turtlebot3-teleop + + +Then, you can run the examples. For the basic version: + +.. code-block:: bash + + export TURTLEBOT3_MODEL=waffle + roslaunch elevation_mapping_cupy turtlesim_example.launch + + +Or, for the version including plane segmentation: + +.. code-block:: bash + + catkin build convex_plane_decomposition_ros + export TURTLEBOT3_MODEL=waffle + roslaunch elevation_mapping_cupy turtlesim_segmentation_example.launch + + +To control the robot with a keyboard, a new terminal window needs to be opened. +Then run + +.. code-block:: bash + + export TURTLEBOT3_MODEL=waffle + roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch + + +Velocity inputs can be sent to the robot by pressing the keys `a`, `w`, `d`, `x`. To stop the robot completely, press `s`. + + diff --git a/docs/source/python/custom_kernels.rst b/docs/source/python/custom_kernels.rst index c8dcd43c..d0367329 100644 --- a/docs/source/python/custom_kernels.rst +++ b/docs/source/python/custom_kernels.rst @@ -1,7 +1,7 @@ .. _custom_kernels: Custom kernels -================================================== +****************************************************************** .. automodule:: elevation_mapping_cupy.custom_kernels :members: diff --git a/docs/source/python/elevation_mapping.rst b/docs/source/python/elevation_mapping.rst index b3403049..0283d01c 100644 --- a/docs/source/python/elevation_mapping.rst +++ b/docs/source/python/elevation_mapping.rst @@ -1,7 +1,7 @@ .. _elevation_mapping: Elevation mapping cupy -================================================== +****************************************************************** .. automodule:: elevation_mapping_cupy.elevation_mapping :members: diff --git a/docs/source/python/index.rst b/docs/source/python/index.rst index 4764424c..f20f2e59 100644 --- a/docs/source/python/index.rst +++ b/docs/source/python/index.rst @@ -1,5 +1,5 @@ Python software -================================================== +****************************************************************** .. toctree:: elevation_mapping diff --git a/docs/source/python/semantic_pointcloud.rst b/docs/source/python/semantic_pointcloud.rst index 9a49c37a..03de3521 100644 --- a/docs/source/python/semantic_pointcloud.rst +++ b/docs/source/python/semantic_pointcloud.rst @@ -1,7 +1,7 @@ .. _semantic_pointcloud: Semantic Pointcloud -=================== +****************************************************************** .. automodule:: semantic_pointcloud.pointcloud_node diff --git a/docs/source/usage/parameters.rst b/docs/source/usage/parameters.rst index edff99a3..f1ce26ca 100644 --- a/docs/source/usage/parameters.rst +++ b/docs/source/usage/parameters.rst @@ -1,4 +1,5 @@ .. _parameters: + Parameters -================================================== +****************************************************************** diff --git a/docs/source/usage/plane_segmentation.rst b/docs/source/usage/plane_segmentation.rst index 883b95b1..35c2efd7 100644 --- a/docs/source/usage/plane_segmentation.rst +++ b/docs/source/usage/plane_segmentation.rst @@ -1,7 +1,7 @@ .. _plane_segmentation: Plane Segmentation -================================================== +****************************************************************** .. image:: ../media/convex_approximation.gif :alt: Convex approximation diff --git a/docs/source/usage/plugins.rst b/docs/source/usage/plugins.rst index 8f0e517c..dd684b6b 100644 --- a/docs/source/usage/plugins.rst +++ b/docs/source/usage/plugins.rst @@ -1,5 +1,66 @@ .. _plugins: Plugins -================================================== +****************************************************************** + + +You can create your own plugin to process the elevation map and publish as a layer in GridMap message. + +Let's look at the example. + +First, create your plugin file in `elevation_mapping_cupy/script/plugins/` and save as `example.py`. + +.. code-block:: python + + import cupy as cp + from typing import List + from .plugin_manager import PluginBase + + + class NameOfYourPlugin(PluginBase): + def __init__(self, add_value:float=1.0, **kwargs): + super().__init__() + self.add_value = float(add_value) + + def __call__(self, elevation_map: cp.ndarray, layer_names: List[str], + plugin_layers: cp.ndarray, plugin_layer_names: List[str])->cp.ndarray: + # Process maps here + # You can also use the other plugin's data through plugin_layers. + new_elevation = elevation_map[0] + self.add_value + return new_elevation + +Then, add your plugin setting to `config/plugin_config.yaml` + +.. code-block:: yaml + + example: # Name of your filter + type: "example" # Specify the name of your plugin (the name of your file name). + enable: True # weather to load this plugin + fill_nan: True # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "example_layer" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + add_value: 2.0 # Example param + + example_large: # You can apply same filter with different name. + type: "example" # Specify the name of your plugin (the name of your file name). + enable: True # weather to load this plugin + fill_nan: True # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "example_layer_large" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + add_value: 100.0 # Example param with larger value. + + +Finally, add your layer name to publishers in `config/parameters.yaml`. You can create a new topic or add to existing topics. + +.. code-block:: yaml + + plugin_example: # Topic name + layers: [ 'elevation', 'example_layer', 'example_layer_large' ] + basic_layers: [ 'example_layer' ] + fps: 1.0 # The plugin is called with this fps. + + + diff --git a/docs/source/usage/semantics.rst b/docs/source/usage/semantics.rst index 02d30c4e..7429a111 100644 --- a/docs/source/usage/semantics.rst +++ b/docs/source/usage/semantics.rst @@ -1,4 +1,4 @@ .. _semantics: Semantics -================================================== \ No newline at end of file +****************************************************************** \ No newline at end of file From 0dc5a5a00a22acec35741703e613a89828515d74 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Thu, 17 Nov 2022 16:57:44 +0100 Subject: [PATCH 264/504] updated documentation --- docs/source/conf.py | 61 +++++++++------ docs/source/documentation.rst | 3 + .../getting_started/cuda_installation.rst | 21 +++-- docs/source/getting_started/index.rst | 2 + docs/source/getting_started/installation.rst | 13 +++- docs/source/index.rst | 2 +- docs/source/usage/parameters.rst | 35 +++++++++ docs/source/usage/plugins.rst | 44 +++++++++++ docs/source/usage/semantics.rst | 77 ++++++++++++++++++- .../plugins/inpainting.py | 33 +++++--- .../plugins/min_filter.py | 35 +++++---- .../plugins/robot_centric_elevation.py | 23 ++++++ .../plugins/semantic_filter.py | 36 +++++---- .../plugins/semantic_traversability.py | 31 +++++--- .../plugins/smooth_filter.py | 28 ++++--- 15 files changed, 356 insertions(+), 88 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 9eb4db46..37693134 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -7,46 +7,61 @@ # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information import os, sys -sys.path.insert(0, os.path.abspath('../../elevation_mapping_cupy')) -sys.path.insert(0, os.path.abspath('../../sensor_processing/semantic_pointcloud')) -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' +sys.path.insert(0, os.path.abspath("../../elevation_mapping_cupy")) +sys.path.insert(0, os.path.abspath("../../sensor_processing/semantic_pointcloud")) + +on_rtd = os.environ.get("READTHEDOCS", None) == "True" if not on_rtd: # only import and set the theme if we're building docs locally import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' + + html_theme = "sphinx_rtd_theme" html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] -project = 'elevation_mapping_cupy' -copyright = '2022, Takahiro Miki, Gian Erni' -author = 'Takahiro Miki, Gian Erni' +project = "elevation_mapping_cupy" +copyright = "2022, Takahiro Miki, Gian Erni" +author = "Takahiro Miki, Gian Erni" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage', 'sphinx.ext.napoleon','sphinx_copybutton'] +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.coverage", + "sphinx.ext.napoleon", + "sphinx_copybutton", +] -templates_path = ['_templates'] -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] html_theme_options = { - 'analytics_anonymize_ip': False, - 'logo_only': False, - 'display_version': False, - 'prev_next_buttons_location': 'bottom', - 'style_external_links': False, - 'vcs_pageview_mode': '', - 'style_nav_header_background': '#A00000', + "analytics_anonymize_ip": False, + "logo_only": False, + "display_version": False, + "prev_next_buttons_location": "bottom", + "style_external_links": False, + "vcs_pageview_mode": "", + "style_nav_header_background": "#A00000", # Toc options - 'collapse_navigation': True, - 'sticky_navigation': True, - 'navigation_depth': 4, - 'includehidden': True, - 'titles_only': False + "collapse_navigation": True, + "sticky_navigation": True, + "navigation_depth": 4, + "includehidden": True, + "titles_only": False, } # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_static_path = ['_static'] +html_static_path = ["_static"] + +autodoc_default_options = { + "members": True, + "member-order": "bysource", + "special-members": "__init__", + "undoc-members": True, + "exclude-members": "__weakref__", +} diff --git a/docs/source/documentation.rst b/docs/source/documentation.rst index 046cae8d..e38e938b 100644 --- a/docs/source/documentation.rst +++ b/docs/source/documentation.rst @@ -7,6 +7,9 @@ Weclome to Elevation Mapping documentation :target: https://github.com/leggedrobotics/elevation_mapping_semantic_cupy/actions/workflows/python-tests.yml/badge.svg :alt: python tests +.. image:: https://github.com/leggedrobotics/elevation_mapping_semantic_cupy/actions/workflows/documentation.yml/badge.svg + :target: https://github.com/leggedrobotics/elevation_mapping_semantic_cupy/actions/workflows/documentation.yml/badge.svg + :alt: documentation Index --------------- diff --git a/docs/source/getting_started/cuda_installation.rst b/docs/source/getting_started/cuda_installation.rst index cc656f63..a4a6c1f6 100644 --- a/docs/source/getting_started/cuda_installation.rst +++ b/docs/source/getting_started/cuda_installation.rst @@ -1,30 +1,41 @@ + +Cuda installation +================================================================== .. _cuda_installation: -TODO add this to the + CUDA -****************************************************************** +------------------------------------------------------------------- -You can download CUDA10.2 from [here](https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin). +You can download CUDA10.2 from `here `_. You can follow the instruction. + .. code-block:: bash wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin + sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600 + sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub + sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/ /" + sudo apt-get update + sudo apt-get -y install cuda cuDNN -****************************************************************** +------------------------------------------------------------------- -You can download specific version from [here](https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/). +You can download specific version from `here `_. For example, the tested version is with `libcudnn8_8.0.0.180-1+cuda10.2_amd64.deb`. Then install them using the command below. + .. code-block:: bash sudo dpkg -i libcudnn8_8.0.0.180-1+cuda10.2_amd64.deb + sudo dpkg -i libcudnn8-dev_8.0.0.180-1+cuda10.2_amd64.deb diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst index 7b0ec137..94693b43 100644 --- a/docs/source/getting_started/index.rst +++ b/docs/source/getting_started/index.rst @@ -1,5 +1,7 @@ .. _introduction: + + Introduction ****************************************************************** diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index f4bbcfeb..255fff74 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -1,5 +1,14 @@ .. _installation: + +.. toctree:: + :hidden: + :maxdepth: 2 + + Cuda installation + + + Installation ****************************************************************** @@ -12,7 +21,9 @@ The tested versions are CUDA10.2, 11.6 `cuDNN `_ -Check how to install :ref:`here`. +Check how to install :ref:`here`. + + Python dependencies ------------------------------------------------------------------- diff --git a/docs/source/index.rst b/docs/source/index.rst index a029dc2a..fa842a9a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -8,7 +8,7 @@ .. toctree:: :hidden: - :maxdepth: 2 + :maxdepth: 3 :caption: Getting Started Introduction diff --git a/docs/source/usage/parameters.rst b/docs/source/usage/parameters.rst index f1ce26ca..57836bb7 100644 --- a/docs/source/usage/parameters.rst +++ b/docs/source/usage/parameters.rst @@ -3,3 +3,38 @@ Parameters ****************************************************************** +There are three parameter files: + +1. `Parameters`_ + +2. `Plugin configurations`_ + +3. `Sensor parameter`_ + + + +Parameters +================================================ + +.. include:: ../../../elevation_mapping_cupy/config/parameters.yaml + :code: yaml + +Plugin configurations +================================================ + +More informations on the plugins can be found in :ref:`plugins`. + +.. include:: ../../../elevation_mapping_cupy/config/plugin_config.yaml + :code: yaml + + + +Sensor parameter +================================================ + +More informations on the sensor configurations can be found in :ref:`semantics`. + +.. include:: ../../../elevation_mapping_cupy/config/sensor_parameter.yaml + :code: yaml + + diff --git a/docs/source/usage/plugins.rst b/docs/source/usage/plugins.rst index dd684b6b..410ad623 100644 --- a/docs/source/usage/plugins.rst +++ b/docs/source/usage/plugins.rst @@ -3,7 +3,51 @@ Plugins ****************************************************************** +This page is structured in two parts: +* `Existing plugins`_ + +* `Create a plugin`_ + +Existing plugins +================================================================== + +1. Min filter +------------------------------------------------------------------- +.. automodule:: elevation_mapping_cupy.plugins.min_filter + :members: + +2. Inpainting +------------------------------------------------------------------- + +.. automodule:: elevation_mapping_cupy.plugins.inpainting + :members: + +3. Smooth Filter +------------------------------------------------------------------- +.. automodule:: elevation_mapping_cupy.plugins.smooth_filter + :members: + +4. Robot centric elevation +------------------------------------------------------------------- +.. automodule:: elevation_mapping_cupy.plugins.robot_centric_elevation + :members: + +5. Semantic Filter +------------------------------------------------------------------- +.. automodule:: elevation_mapping_cupy.plugins.semantic_filter + :members: + +6. Semantic traversability +------------------------------------------------------------------- +.. automodule:: elevation_mapping_cupy.plugins.semantic_traversability + :members: + + + + +Create a plugin +================================================================== You can create your own plugin to process the elevation map and publish as a layer in GridMap message. Let's look at the example. diff --git a/docs/source/usage/semantics.rst b/docs/source/usage/semantics.rst index 7429a111..24616a10 100644 --- a/docs/source/usage/semantics.rst +++ b/docs/source/usage/semantics.rst @@ -1,4 +1,79 @@ .. _semantics: Semantics -****************************************************************** \ No newline at end of file +****************************************************************** + +The elevation map is also able to include semantic information. +The workflow consists in two elements: + +* semantic extension of the elevation map +* semantic pointcloud + +semantic extension of the elevation map +========================================== + +The semantics of the elevation map can be configured in the sensor parameter file. +The sensor parameter file contains all the topics the map subscribes to. + +The channels and fusion lists are the parameters that define the semantics of the elevation map. +The channel is a list that contains the name of the semantic layers as well as the name of the channel +of the data that the elevation map node subscribes to. +The fusion list indicates the fusion algorithm type which is applied to the data to fuse the +sensor data into the map. + +There are different fusion algorithms types: + +* average +"""""""""""""""""""""""""" + + Takes the average of all the points that fall within the same cell and average them + and then takes a weighted average of the existing value. + + use case: semantic features + +* bayesian_inference: +"""""""""""""""""""""""""" + + Employs a gaussian bayesian inference at each iteration. Where we use the psoterior + of the previous iteration as the prior to the new iteration. + + use case: semantic features + + +* class_average +"""""""""""""""""""""""""" + + Takes the average of all the points that fall within the same cell and average them + and then takes a weighted average of the existing value. If the previous value is zero + it weights the previous value with a zero weight. + + use case: class probabilities + +* class_bayesian +"""""""""""""""""""""""""" + + Employs a bayesian inference of a categorical distribution with a dirichlet prior. + The alpha hyperparameters of the dirichlet prior are updated at every iteration, + such that the posterior of iteration t-1 is the prior of t. + + use case: class probabilities + + +* color +"""""""""""""""""""""""""" + + The color is subscribed as a uint32. The color of the cell is the result of the average of + all the points within that cell. + + use case: rgb color information + +Semantic pointcloud +======================================= + +Sensors do not always directly provide all semantic information. +The semantic pointcloud is a ROS node that subscribes to stereo cameras and generates a +multichannel pointcloud containing semantic information additionally to the goemteric position of +the points. +The pointcloud is also configured from the sensor_parameter file. + + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py index 247041b6..97d8d09a 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py @@ -13,17 +13,14 @@ class Inpainting(PluginBase): - """This is a filter to smoothen - - ... - - Attributes - ---------- - cell_n: int - width and height of the elevation map. - """ - def __init__(self, cell_n: int = 100, method: str = "telea", **kwargs): + """ + + Args: + cell_n (int): + method (str): + **kwargs (): + """ super().__init__() if method == "telea": self.method = cv.INPAINT_TELEA @@ -40,12 +37,26 @@ def __call__( plugin_layer_names: List[str], *args, ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + *args (): + + Returns: + cupy._core.core.ndarray: + """ mask = cp.asnumpy((elevation_map[2] < 0.5).astype("uint8")) if (mask < 1).any(): h = elevation_map[0] h_max = float(h[mask < 1].max()) h_min = float(h[mask < 1].min()) - h = cp.asnumpy((elevation_map[0] - h_min) * 255 / (h_max - h_min)).astype("uint8") + h = cp.asnumpy((elevation_map[0] - h_min) * 255 / (h_max - h_min)).astype( + "uint8" + ) dst = np.array(cv.inpaint(h, mask, 1, self.method)) h_inpainted = dst.astype(np.float32) * (h_max - h_min) / 255 + h_min return cp.asarray(h_inpainted).astype(np.float64) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py index f50147f6..b3eba4ff 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py @@ -10,23 +10,16 @@ class MinFilter(PluginBase): - """This is a filter to fill in invalid cells with minimum values around. - - ... - - Attributes - ---------- - width: int - width of the elevation map. - height: int - height of the elevation map. - dilation_size: int - The size of the patch to search for minimum value for each iteration. - iteration_n: int - The number of iteration to repeat the same filter. - """ def __init__(self, cell_n: int = 100, dilation_size: int = 5, iteration_n: int = 5, **kwargs): + """ This is a filter to fill in invalid cells with minimum values around. + + Args: + cell_n (int): width of the elevation map. + dilation_size (int): The size of the patch to search for minimum value for each iteration. + iteration_n (int): The number of iteration to repeat the same filter. + **kwargs (): + """ super().__init__() self.iteration_n = iteration_n self.width = cell_n @@ -96,6 +89,18 @@ def __call__( plugin_layer_names: List[str], *args, ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + *args (): + + Returns: + cupy._core.core.ndarray: + """ self.min_filtered = elevation_map[0].copy() self.min_filtered_mask = elevation_map[2].copy() for i in range(self.iteration_n): diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py index 41d963ce..2b0de613 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py @@ -8,6 +8,15 @@ class RobotCentricElevation(PluginBase): def __init__( self, cell_n: int = 100, resolution: float = 0.05, threshold: float = 0.4, use_threshold: bool = 0, **kwargs ): + """ Generates an elevation map with respect to the robot frame. + + Args: + cell_n (int): + resolution (ruamel.yaml.scalarfloat.ScalarFloat): + threshold (ruamel.yaml.scalarfloat.ScalarFloat): + use_threshold (bool): + **kwargs (): + """ super().__init__() self.width = cell_n self.height = cell_n @@ -83,6 +92,20 @@ def __call__( rotation, *args, ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): + rotation (cupy._core.core.ndarray): + *args (): + + Returns: + cupy._core.core.ndarray: + """ # Process maps here # check that transform is a ndarray self.min_filtered = elevation_map[0].copy() diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index 2f82ad68..784d977e 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -10,22 +10,19 @@ class SemanticFilter(PluginBase): - """This is a filter to create colors - - ... - - Attributes - ---------- - cell_n: int - width and height of the elevation map. - """ - def __init__( self, cell_n: int = 100, classes: list = ["person", "grass"], **kwargs, ): + """This is a filter to create a one hot encoded map of the class probabilities. + + Args: + cell_n (int): width and height of the elevation map. + classes (ruamel.yaml.comments.CommentedSeq): + **kwargs (): + """ super().__init__() self.indices = [] self.classes = classes @@ -36,8 +33,8 @@ def bitget(byteval, idx): return (byteval & (1 << idx)) != 0 dtype = "float32" if normalized else "uint8" - cmap = np.zeros((N+1, 3), dtype=dtype) - for i in range(N+1): + cmap = np.zeros((N + 1, 3), dtype=dtype) + for i in range(N + 1): r = g = b = 0 c = i for j in range(8): @@ -69,10 +66,23 @@ def __call__( semantic_map, *args, ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): + *args (): + + Returns: + cupy._core.core.ndarray: + """ # get indices of all layers that layer_indices = cp.array([], dtype=cp.int32) for it, fusion_alg in enumerate(semantic_map.param.fusion_algorithms): - if (fusion_alg in ["class_bayesian","class_average"]): + if fusion_alg in ["class_bayesian", "class_average"]: layer_indices = cp.append(layer_indices, it).astype(cp.int32) # check which has the highest value diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py index a9619a4b..4fb842d2 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py @@ -10,15 +10,6 @@ class SemanticTraversability(PluginBase): - """This is a filter to create colors - - ... - - Attributes - ---------- - cell_n: int - width and height of the elevation map. - """ def __init__( self, @@ -28,6 +19,15 @@ def __init__( type: list = ["traversability"], **kwargs, ): + """ Extracts traversability and elevations from layers and generates an updated traversability that can be used by checker. + + Args: + cell_n (int): + layers (ruamel.yaml.comments.CommentedSeq): + thresholds (ruamel.yaml.comments.CommentedSeq): + type (ruamel.yaml.comments.CommentedSeq): + **kwargs (): + """ super().__init__() self.layers = layers self.thresholds = cp.asarray(thresholds) @@ -42,6 +42,19 @@ def __call__( semantic_map, *args, ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): + *args (): + + Returns: + cupy._core.core.ndarray: + """ # get indices of all layers that map = cp.zeros(elevation_map[2].shape, np.float32) tempo = cp.zeros(elevation_map[2].shape, np.float32) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py index 65334452..fb03ad28 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py @@ -10,17 +10,15 @@ class SmoothFilter(PluginBase): - """This is a filter to smoothen - - ... - - Attributes - ---------- - cell_n: int - width and height of the elevation map. - """ def __init__(self, cell_n: int = 100, input_layer_name: str = "elevation", **kwargs): + """ This filters smoothees elevation map. + + Args: + cell_n (int): + input_layer_name (str): + **kwargs (): + """ super().__init__() self.input_layer_name = input_layer_name @@ -32,6 +30,18 @@ def __call__( plugin_layer_names: List[str], *args, ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + *args (): + + Returns: + cupy._core.core.ndarray: + """ if self.input_layer_name in layer_names: idx = layer_names.index(self.input_layer_name) h = elevation_map[idx] From ba347793a366a1e6dbd56f76707f3f94c1b8c581 Mon Sep 17 00:00:00 2001 From: Takahiro Miki Date: Fri, 18 Nov 2022 15:52:02 +0100 Subject: [PATCH 265/504] Update citation info. --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a4a72310..6e921cfb 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,13 @@ terrain can be efficiently generated. > Elevation Mapping for Locomotion and Navigation using GPU [arXiv](https://arxiv.org/abs/2204.12876) ``` -@misc{https://doi.org/10.48550/arxiv.2204.12876, +@misc{mikielevation2022, doi = {10.48550/ARXIV.2204.12876}, - url = {https://arxiv.org/abs/2204.12876}, author = {Miki, Takahiro and Wellhausen, Lorenz and Grandia, Ruben and Jenelten, Fabian and Homberger, Timon and Hutter, Marco}, keywords = {Robotics (cs.RO), FOS: Computer and information sciences, FOS: Computer and information sciences}, title = {Elevation Mapping for Locomotion and Navigation using GPU}, - publisher = {arXiv}, + publisher = {International Conference on Intelligent Robots and Systems (IROS)}, year = {2022}, - copyright = {arXiv.org perpetual, non-exclusive license} } ``` From 60baf5bdae35e60d6c389a3fdb90f822a6057e63 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Sun, 20 Nov 2022 09:51:45 -0800 Subject: [PATCH 266/504] fixed oubslishing only rgb --- .../script/semantic_pointcloud/pointcloud_node.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index f42983d3..29476d09 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -73,10 +73,11 @@ def __init__(self, sensor_name): self.seg_pub = rospy.Publisher( self.param.segmentation_image_topic, Image, queue_size=2 ) - self.semseg_color_map = self.color_map( - len(list(self.segmentation_channels.keys())) - ) - self.color_map_viz() + if self.segmentation_channels is not None: + self.semseg_color_map = self.color_map( + len(list(self.segmentation_channels.keys())) + ) + self.color_map_viz() def color_map(self, N=256, normalized=False): def bitget(byteval, idx): From 9083c2b168a770a518255eee6940d759ecf8bec5 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Sun, 20 Nov 2022 09:52:03 -0800 Subject: [PATCH 267/504] fixed quaternion convention and gridmap transpose --- .../elevation_mapping_ros.py | 136 +++++++++++------- 1 file changed, 86 insertions(+), 50 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index ee493574..39220152 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -2,7 +2,7 @@ from elevation_mapping_cupy import Parameter # General -import os +import os import numpy as np # ROS @@ -18,13 +18,27 @@ from std_msgs.msg import MultiArrayLayout as MAL from std_msgs.msg import MultiArrayDimension as MAD -class ElevationMapWrapper(): +import numpy as np + +PDC_DATATYPE = { + "1": np.int8, + "2": np.uint8, + "3": np.int16, + "4": np.uint16, + "5": np.int32, + "6": np.uint32, + "7": np.float32, + "8": np.float64, +} + + +class ElevationMapWrapper: def __init__(self): rospack = rospkg.RosPack() self.root = rospack.get_path("elevation_mapping_cupy") weight_file = os.path.join(self.root, "config/weights.dat") plugin_config_file = os.path.join(self.root, "config/plugin_config.yaml") - self.param = Parameter( use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file ) + self.param = Parameter(use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file) self.node_name = "elevation_mapping" # ROS self.initalize_ros() @@ -33,6 +47,8 @@ def __init__(self): self.register_publishers() self.register_timers() + self._last_t = None + def initalize_elevation_mapping(self): self.param.update() self._pointcloud_process_counter = 0 @@ -40,20 +56,22 @@ def initalize_elevation_mapping(self): self._map_data = np.zeros((self._map.cell_n - 2, self._map.cell_n - 2), dtype=np.float32) self._map_q = None self._map_t = None - + def initalize_ros(self): rospy.init_node(self.node_name, anonymous=False) self._tf_buffer = tf2_ros.Buffer() self._listener = tf2_ros.TransformListener(self._tf_buffer) self.get_ros_params() - + def register_subscribers(self): pointcloud_subs = {} additional = [] fusion = [] for key, config in self.subscribers.items(): - pointcloud_subs[key] = rospy.Subscriber(config["topic_name"], PointCloud2, self.pointcloud_callback, (config["channels"], config["fusion"])) - for chan,fus in zip(config["channels"],config["fusion"]): + pointcloud_subs[key] = rospy.Subscriber( + config["topic_name"], PointCloud2, self.pointcloud_callback, (config["channels"], config["fusion"]) + ) + for chan, fus in zip(config["channels"], config["fusion"]): if chan not in additional: additional.append(chan) fusion.append(fus) @@ -74,13 +92,13 @@ def register_publishers(self): for k, v in self.publishers.items(): print(f"Register Publisher: {k}") self._publishers[k] = rospy.Publisher(f"/{self.node_name}/{k}", GridMap, queue_size=10) - self._publishers_timers.append( rospy.Timer(rospy.Duration(1/v["fps"]), lambda x: self.publish_map(x, k))) - + self._publishers_timers.append(rospy.Timer(rospy.Duration(1 / v["fps"]), lambda x: self.publish_map(x, k))) + def publish_map(self, t, k): - print(k) + print("Publish map") if self._map_q is None: return - + gm = GridMap() gm.info.header.frame_id = self.map_frame gm.info.header.stamp = rospy.Time.now() @@ -90,11 +108,11 @@ def publish_map(self, t, k): gm.info.length_y = self._map.map_length gm.info.pose.position.x = self._map_t.x gm.info.pose.position.y = self._map_t.y - gm.info.pose.position.z = self._map_t.z - gm.info.pose.orientation.w = 1 # self._map_q.w - gm.info.pose.orientation.x = 0 # self._map_q.x - gm.info.pose.orientation.y = 0 # self._map_q.y - gm.info.pose.orientation.z = 0 # self._map_q.z + gm.info.pose.position.z = 0.0 + gm.info.pose.orientation.w = 1.0 # self._map_q.w + gm.info.pose.orientation.x = 0.0 # self._map_q.x + gm.info.pose.orientation.y = 0.0 # self._map_q.y + gm.info.pose.orientation.z = 0.0 # self._map_q.z gm.layers = self.publishers[k]["layers"] gm.basic_layers = self.publishers[k]["basic_layers"] @@ -103,72 +121,89 @@ def publish_map(self, t, k): for i, layer in enumerate(gm.layers): self._map.get_map_with_name_ref(layer, self._map_data) # self._map_data = np.nan_to_num(self._map_data, False, 0) - data = self._map_data.copy() + data = self._map_data.copy() arr = Float32MultiArray() arr.layout = MAL() N = self._map_data.shape[0] - arr.layout.dim.append( MAD(label="column_index",size=N,stride=int(N*N))) - arr.layout.dim.append( MAD(label="row_index",size=N,stride=N)) - arr.data = tuple(np.ascontiguousarray(data).reshape(-1)) - gm.data.append( arr ) - - self._publishers[k].publish( gm ) - + arr.layout.dim.append(MAD(label="column_index", size=N, stride=int(N * N))) + arr.layout.dim.append(MAD(label="row_index", size=N, stride=N)) + arr.data = tuple(np.ascontiguousarray(data.T).reshape(-1)) + gm.data.append(arr) + gm.outer_start_index = 0 + gm.inner_start_index = 0 + + self._publishers[k].publish(gm) + def register_timers(self): - self.timer_variance = rospy.Timer(rospy.Duration(1/self.update_variance_fps), self.update_variance) - self.timer_pose = rospy.Timer(rospy.Duration(1/self.update_pose_fps), self.update_pose) + self.timer_variance = rospy.Timer(rospy.Duration(1 / self.update_variance_fps), self.update_variance) + self.timer_pose = rospy.Timer(rospy.Duration(1 / self.update_pose_fps), self.update_pose) self.timer_time = rospy.Timer(rospy.Duration(self.time_interval), self.update_time) - + def pointcloud_callback(self, msg, config): # convert pcd into numpy array - channels = ['x','y','z']+config[0] + # output = {} + # total_bytes = msg.fields[-1].offset + PDC_DATATYPE[str(msg.fields[-1].datatype)](1).nbytes + # res = np.frombuffer(msg.data, np.dtype(np.uint8)).reshape((-1, msg.point_step)) + # for field in msg.fields: + # assert field.count == 1, "If this is not case, maybe does not work" + # PDC_DATATYPE[str(field.datatype)] + # dtype = PDC_DATATYPE[str(field.datatype)] + # nbytes = dtype(1).nbytes + # data = res[:, field.offset : field.offset + nbytes] + # output[field.name] = np.frombuffer(data.copy(), np.dtype(dtype)).reshape((-1)) + channels = ["x", "y", "z"] + config[0] fusion = config[1] points = ros_numpy.numpify(msg) - pts = np.empty((points.shape[0],0)) + pts = np.empty((points.shape[0], 0)) for ch in channels: - pts = np.append(pts,np.expand_dims(points[ch],1),axis=1) + pts = np.append(pts, np.expand_dims(points[ch], 1), axis=1) # get pose of pointcloud - t = rospy.Time(secs=msg.header.stamp.secs, nsecs=msg.header.stamp.nsecs) + ti = rospy.Time(secs=msg.header.stamp.secs, nsecs=msg.header.stamp.nsecs) + self._last_t = ti try: - transform = self._tf_buffer.lookup_transform(self.map_frame, msg.header.frame_id, t, rospy.Duration(1.0)) + transform = self._tf_buffer.lookup_transform(self.map_frame, msg.header.frame_id, ti, rospy.Duration(1.0)) except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - print(e) + print("pointcloud_callback error:", e) return t = transform.transform.translation - t = np.array( [t.x, t.y, t.z] ) + t = np.array([t.x, t.y, t.z]) q = transform.transform.rotation - R = quaternion_matrix([q.w, q.x, q.y, q.z])[:3,:3] + R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] # process pointcloud self._map.input(pts, channels, R, t, 0, 0) self._pointcloud_process_counter += 1 print(self._pointcloud_process_counter) - + def update_pose(self, t): # get pose of base - t = rospy.Time.now() + # t = rospy.Time.now() + if self._last_t is None: + return try: - transform = self._tf_buffer.lookup_transform(self.map_frame, self.base_frame, t, rospy.Duration(1.0)) + transform = self._tf_buffer.lookup_transform( + self.map_frame, self.base_frame, self._last_t, rospy.Duration(1.0) + ) except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - print(e) - return + print("update_pose error: ", e) + return t = transform.transform.translation - trans = np.array( [t.x, t.y, t.z] ) + trans = np.array([t.x, t.y, t.z]) q = transform.transform.rotation - rot = quaternion_matrix([q.w, q.x, q.y, q.z])[:3,:3] + rot = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] self._map.move_to(trans, rot) - + self._map_t = t self._map_q = q - + def update_variance(self, t): self._map.update_variance() - + def update_time(self, t): self._map.update_time() - + def get_ros_params(self): # TODO fix this here when later launching with launch-file # This is currently {p} elevation_mapping") @@ -199,12 +234,13 @@ def get_ros_params(self): self.enable_normal_arrow_publishing = rospy.get_param("~enable_normal_arrow_publishing", False) self.enable_drift_corrected_TF_publishing = rospy.get_param("~enable_drift_corrected_TF_publishing", False) self.use_initializer_at_start = rospy.get_param("~use_initializer_at_start", False) - -if __name__ == '__main__': + + +if __name__ == "__main__": emw = ElevationMapWrapper() - + while not rospy.is_shutdown(): try: rospy.spin() except rospy.ROSInterruptException: - print("Error") \ No newline at end of file + print("Error") From b03142e81ce51e51bfd66d6f3a1910bf6aa09fe7 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Sun, 20 Nov 2022 09:52:28 -0800 Subject: [PATCH 268/504] updated configuration for lonomy stack --- elevation_mapping_cupy/config/parameters.yaml | 6 +-- .../config/sensor_parameter.yaml | 54 +++++++++---------- .../config/sensor_parameter.yaml | 9 ++-- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index b8826d53..9e7ccd0d 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -40,9 +40,9 @@ max_unsafe_n: 10 # if the number of cells under s overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) -map_frame: 'odom' # The map frame where the odometry source uses. -base_frame: 'base' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'odom_corrected' +map_frame: 'enu' # The map frame where the odometry source uses. +base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. +corrected_map_frame: 'enu' #### Feature toggles ######## enable_edge_sharpen: true diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index 6a5e85d7..30460667 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -1,34 +1,34 @@ subscribers: - sensor_name: - channels: ['feat_0','feat_1'] - fusion: ['average','average'] - topic_name: '/elevation_mapping/pointcloud_semantic' - front_cam: - channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] - fusion: ['color','average','average','class_average','class_average','class_average','class_average'] + channels: ['rgb'] + fusion: ['color'] topic_name: '/elvation_mapping/pointcloud_semantic' - semantic_segmentation: False - segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' - feature_config: - name: 'DINO' - interpolation: 'bilinear' - model: "vit_small" - patch_size: 16 - dim: 5 - dropout: False - dino_feat_type: "feat" - input_size: [80, 160] - projection_type: "nonlinear" + + # front_cam: + # channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] + # fusion: ['color','average','average','class_average','class_average','class_average','class_average'] + # topic_name: '/elvation_mapping/pointcloud_semantic' + # semantic_segmentation: False + # segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' + # feature_config: + # name: 'DINO' + # interpolation: 'bilinear' + # model: "vit_small" + # patch_size: 16 + # dim: 5 + # dropout: False + # dino_feat_type: "feat" + # input_size: [80, 160] + # projection_type: "nonlinear" - cam_info_topic: "/camera/depth/camera_info" - image_topic: "/camera/rgb/image_raw" - depth_topic: "/camera/depth/image_raw" - cam_frame: camera_rgb_optical_frame - confidence: False - confidence_topic: "/camera/depth/image_raw" - confidence_threshold: 10 - feature_extractor: False + # cam_info_topic: "/camera/depth/camera_info" + # image_topic: "/camera/rgb/image_raw" + # depth_topic: "/camera/depth/image_raw" + # cam_frame: camera_rgb_optical_frame + # confidence: False + # confidence_topic: "/camera/depth/image_raw" + # confidence_threshold: 10 + # feature_extractor: False front_bpearl: channels: [] diff --git a/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml b/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml index 0c50c619..de553513 100644 --- a/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml +++ b/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml @@ -4,11 +4,13 @@ subscribers: # fusion: ['average','average'] # topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: - channels: ['rgb','feat_0','feat_1','person','grass'] - fusion: ['color','average','average','class_average','class_average'] + channels: ['rgb'] #'feat_0','feat_1','person','grass'] + fusion: ['color'] #'average','average','class_average','class_average'] topic_name: '/elvation_mapping/pointcloud_semantic' - semantic_segmentation: True + semantic_segmentation: False segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' + publish_segmentation_image: True + feature_extractor: False feature_config: name: 'DINO' interpolation: 'bilinear' @@ -28,4 +30,3 @@ subscribers: confidence_threshold: 10 - From 5c6c20a8bd94f61292efae029323380ce9960a82 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Sun, 20 Nov 2022 15:26:09 -0800 Subject: [PATCH 269/504] fixing multi-publisher, adding semantic image --- elevation_mapping_cupy/config/parameters.yaml | 7 +- .../config/sensor_parameter.yaml | 35 +++++- .../elevation_mapping.py | 31 +++++- .../elevation_mapping_ros.py | 100 ++++++++++++++---- 4 files changed, 146 insertions(+), 27 deletions(-) diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index 9e7ccd0d..91a45819 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -75,7 +75,12 @@ publishers: elevation_map_raw: layers: ['elevation', 'traversability', 'variance'] basic_layers: ['elevation', 'traversability'] - fps: 5.0 + fps: 2.0 + + semantic_map_raw: + layers: ['elevation', 'traversability', 'variance', 'single_channel_semantic'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 # elevation_map_recordable: # layers: ['elevation', 'traversability'] # basic_layers: ['elevation', 'traversability'] diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index 30460667..48850236 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -1,8 +1,27 @@ subscribers: + # Single-channel or multi-channel input (Depth or RGB) + # Case 1: 1 channel image - into single semantic layer + # Case 2: 3 channel image - into 3 individual semantic layer + # Case 3: 3 channel image - into RGB color layer + + # Fusion: + # exponential averaging + # using neigborhodd to reduce artifacts + + # Collision checking during raycasting from map to camera + + debug_image: + fusion: ['image_exponential'] + topic_name_camera: /debug_image + topic_name_camera_info: /zed2i/zed_node/right/camera_info + channels: ["single_channel_semantic"] + type: image + front_cam: channels: ['rgb'] fusion: ['color'] topic_name: '/elvation_mapping/pointcloud_semantic' + type: pointcloud # front_cam: # channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] @@ -34,28 +53,34 @@ subscribers: channels: [] fusion: ['average'] topic_name: /robot_self_filter/bpearl_front/point_cloud + type: pointcloud rear_bpearl: channels: [] fusion: ['average'] topic_name: /robot_self_filter/bpearl_rear/point_cloud - + type: pointcloud + front_depth: channels: [] fusion: ['average'] topic_name: /depth_camera_front/point_cloud_self_filtered - + type: pointcloud + rear_depth: channels: [] fusion: ['average'] topic_name: /depth_camera_rear/point_cloud_self_filtered - + type: pointcloud + left_depth: channels: [] fusion: ['average'] topic_name: /depth_camera_left/point_cloud_self_filtered - + type: pointcloud + right_depth: channels: [] fusion: ['average'] - topic_name: /depth_camera_right/point_cloud_self_filtered \ No newline at end of file + topic_name: /depth_camera_right/point_cloud_self_filtered + type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index e9a39a93..663d4a73 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -358,6 +358,19 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori # calculate normal vectors self.update_normal(self.traversability_input) + + def update_map_with_semantic_kernel(self, semantic_image, K, channels, R, t): + """Update map with new measurement from semantic image. + + Args: + semantic_image (cupy._core.core.ndarray): + K (cupy._core.core.ndarray): + channels (List[str]): + R (cupy._core.core.ndarray): + t (cupy._core.core.ndarray): + """ + print("not implemented") + def clear_overlap_map(self, t): # Clear overlapping area around center height_min = t[2] - self.param.overlap_clear_range_z @@ -385,7 +398,7 @@ def update_upper_bound_with_valid_elevation(self): mask = self.elevation_map[2] > 0.5 self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) - + def input(self, raw_points: cp._core.core.ndarray, channels: List[str], R: cp._core.core.ndarray, t: cp._core.core.ndarray, position_noise: int, @@ -409,6 +422,22 @@ def input(self, raw_points: cp._core.core.ndarray, channels: List[str], R: cp._c raw_points = raw_points[~cp.isnan(raw_points).any(axis=1)] self.update_map_with_kernel(raw_points, additional_channels, cp.asarray(R,dtype=self.data_type), cp.asarray(t,dtype=self.data_type), position_noise, orientation_noise) + def input_semantic_image(self, + semantic_image: cp._core.core.ndarray, + K: cp._core.core.ndarray, + channels: List[str], + R: cp._core.core.ndarray, + t: cp._core.core.ndarray + ): + + semantic_image = cp.asarray(semantic_image, dtype=self.data_type) + K = cp.asarray(K, dtype=self.data_type) + R = cp.asarray(R,dtype=self.data_type) + t = cp.asarray(t,dtype=self.data_type) + + self.update_map_with_semantic_kernel(semantic_image, K, channels, R, t) + + def update_normal(self, dilated_map): """ Clear the normal map and then apply the normal kernel with dilated map as input. diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index 39220152..df8f48b8 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -11,14 +11,17 @@ from tf.transformations import quaternion_matrix import tf2_ros import rospkg +import message_filters +from cv_bridge import CvBridge -from sensor_msgs.msg import PointCloud2 +from sensor_msgs.msg import PointCloud2, Image, CameraInfo from grid_map_msgs.msg import GridMap from std_msgs.msg import Float32MultiArray from std_msgs.msg import MultiArrayLayout as MAL from std_msgs.msg import MultiArrayDimension as MAD import numpy as np +from functools import partial PDC_DATATYPE = { "1": np.int8, @@ -42,16 +45,24 @@ def __init__(self): self.node_name = "elevation_mapping" # ROS self.initalize_ros() - self.register_subscribers() + self.overwrite_elevation_mapping_params() + self.setup_cv_bride() self.initalize_elevation_mapping() + self.register_subscribers() self.register_publishers() self.register_timers() self._last_t = None + def setup_cv_bride(self): + if self.semantic_image_data: + self.cv_bridge = CvBridge() + def initalize_elevation_mapping(self): self.param.update() + # TODO add statistics across processed topics self._pointcloud_process_counter = 0 + self._image_process_counter = 0 self._map = ElevationMap(self.param) self._map_data = np.zeros((self._map.cell_n - 2, self._map.cell_n - 2), dtype=np.float32) self._map_q = None @@ -63,18 +74,29 @@ def initalize_ros(self): self._listener = tf2_ros.TransformListener(self._tf_buffer) self.get_ros_params() - def register_subscribers(self): - pointcloud_subs = {} + def overwrite_elevation_mapping_params(self): additional = [] fusion = [] + self.semantic_image_data = False for key, config in self.subscribers.items(): - pointcloud_subs[key] = rospy.Subscriber( - config["topic_name"], PointCloud2, self.pointcloud_callback, (config["channels"], config["fusion"]) - ) - for chan, fus in zip(config["channels"], config["fusion"]): - if chan not in additional: - additional.append(chan) - fusion.append(fus) + if config["type"] == "image": + self.semantic_image_data = True + for chan, fus in zip(config["channels"], config["fusion"]): + if chan not in additional: + additional.append(chan) + if fus not in fusion: + fusion.append(fus) + + elif config["type"] == "pointcloud": + for chan, fus in zip(config["channels"], config["fusion"]): + if chan not in additional: + additional.append(chan) + if fus not in fusion: + fusion.append(fus) + else: + typ = config["type"] + raise ValueError(f"{typ} unknown, only pointcloud and image defined.") + self.param.additional_layers = additional self.param.fusion_algorithms = fusion self.dtype = [ @@ -84,21 +106,36 @@ def register_subscribers(self): ] for chan in config["channels"]: self.dtype.append((chan, np.float32)) + + + def register_subscribers(self): + pointcloud_subs = {} + image_subs = {} + for key, config in self.subscribers.items(): + if config["type"] == "image": + camera_sub = message_filters.Subscriber(config["topic_name_camera"], Image) + camera_info_sub = message_filters.Subscriber(config["topic_name_camera_info"], CameraInfo) + image_subs[key] = message_filters.ApproximateTimeSynchronizer( + [ camera_sub, camera_info_sub], queue_size=10,slop=0.5 + ) + image_subs[key].registerCallback(self.image_callback, (config["channels"], config["fusion"])) + + elif config["type"] == "pointcloud": + pointcloud_subs[key] = rospy.Subscriber( + config["topic_name"], PointCloud2, self.pointcloud_callback, (config["channels"], config["fusion"]) + ) def register_publishers(self): - # TODO publishers self._publishers = {} self._publishers_timers = [] for k, v in self.publishers.items(): - print(f"Register Publisher: {k}") self._publishers[k] = rospy.Publisher(f"/{self.node_name}/{k}", GridMap, queue_size=10) - self._publishers_timers.append(rospy.Timer(rospy.Duration(1 / v["fps"]), lambda x: self.publish_map(x, k))) + # partial(.) allows to pass a default argument to a callback + self._publishers_timers.append(rospy.Timer(rospy.Duration(1 / v["fps"]), partial(self.publish_map, k))) - def publish_map(self, t, k): - print("Publish map") + def publish_map(self, k, t): if self._map_q is None: return - gm = GridMap() gm.info.header.frame_id = self.map_frame gm.info.header.stamp = rospy.Time.now() @@ -115,9 +152,6 @@ def publish_map(self, t, k): gm.info.pose.orientation.z = 0.0 # self._map_q.z gm.layers = self.publishers[k]["layers"] gm.basic_layers = self.publishers[k]["basic_layers"] - - # arr.layout.dim = [int(gm.info.length_x/gm.info.resolution), int(gm.info.length_y/gm.info.resolution)] - for i, layer in enumerate(gm.layers): self._map.get_map_with_name_ref(layer, self._map_data) # self._map_data = np.nan_to_num(self._map_data, False, 0) @@ -139,7 +173,33 @@ def register_timers(self): self.timer_pose = rospy.Timer(rospy.Duration(1 / self.update_pose_fps), self.update_pose) self.timer_time = rospy.Timer(rospy.Duration(self.time_interval), self.update_time) + def image_callback(self, camera_msg, camera_info_msg, config): + fusion = config[1] + # get pose of image + ti = rospy.Time(secs=camera_msg.header.stamp.secs, nsecs=camera_msg.header.stamp.nsecs) + self._last_t = ti + try: + transform = self._tf_buffer.lookup_transform(self.map_frame, camera_msg.header.frame_id, ti, rospy.Duration(1.0)) + except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: + print("pointcloud_callback error:", e) + return + + t = transform.transform.translation + t = np.array([t.x, t.y, t.z]) + q = transform.transform.rotation + R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] + + + semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") + + assert np.all( np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" + K = np.array( camera_info_msg.K , dtype=np.float32).reshape(3,3) + # process pointcloud + self._map.input_semantic_image(semantic_img, K, config[0], R, t) + self._image_process_counter += 1 + def pointcloud_callback(self, msg, config): + print("receive pointcloud") # convert pcd into numpy array # output = {} # total_bytes = msg.fields[-1].offset + PDC_DATATYPE[str(msg.fields[-1].datatype)](1).nbytes From 3e4ec6880c0aa423c63bc24f1c46a311d2b80e1b Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Sun, 20 Nov 2022 15:26:18 -0800 Subject: [PATCH 270/504] added small debug node --- .../debug_publisher/image_debug_node.py | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 sensor_processing/debug_publisher/image_debug_node.py diff --git a/sensor_processing/debug_publisher/image_debug_node.py b/sensor_processing/debug_publisher/image_debug_node.py new file mode 100644 index 00000000..982ba83a --- /dev/null +++ b/sensor_processing/debug_publisher/image_debug_node.py @@ -0,0 +1,39 @@ +import rospy +import sys + +import numpy as np +import ros_numpy +import matplotlib.pyplot as plt +from skimage.io import imshow + +import message_filters +from sensor_msgs.msg import Image, CameraInfo +from sensor_msgs.msg import PointCloud2, Image +from cv_bridge import CvBridge + + +class ImageDebugNode: + def __init__(self): + # setup pointcloud creation + self.cv_bridge = CvBridge() + # rospy.Subscriber("", CameraInfo, self.cam_info_callback) + rospy.Subscriber("/zed2i/zed_node/right/image_rect_color", Image, self.image_callback) + self.debug_pub = rospy.Publisher("/debug_image" , Image, queue_size=2) + + + def image_callback(self, rgb_msg): + img = self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8") + out = np.zeros((img.shape[0],img.shape[1]), dtype=np.uint16) + out[:int(img.shape[0]/2)] = 1 + seg_msg = self.cv_bridge.cv2_to_imgmsg(out, encoding="mono16") + seg_msg.header = rgb_msg.header + self.debug_pub.publish(seg_msg) + # seg_msg.header.frame_id = self.header.frame_id + # self.seg_pub.publish(seg_msg) + + +if __name__ == "__main__": + rospy.init_node("image_debug_node", anonymous=True, log_level=rospy.INFO) + print("Start Debug Image Node") + node = ImageDebugNode() + rospy.spin() From d85277fa6a7525d9ffffc8ff2c4286d290cfc27a Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Sun, 20 Nov 2022 21:54:05 -0800 Subject: [PATCH 271/504] learning cupy, implemnting collision checking --- .../custom_semantic_image_kernerls.py | 162 ++++++++++++++++++ .../elevation_mapping.py | 25 ++- .../elevation_mapping_ros.py | 5 +- 3 files changed, 186 insertions(+), 6 deletions(-) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py new file mode 100644 index 00000000..e7ec2afd --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py @@ -0,0 +1,162 @@ +import cupy as cp +import string + + +def image_to_map_corrospondence_kernel( + resolution, + width, + height +): + image_to_map_corrospondence_kernel = cp.ElementwiseKernel( + in_params="raw U center_x, raw U center_y, raw U R, raw U t, raw U norm_map", + out_params="raw U p, raw U map, raw T newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + """ + ).substitute( + ), + name="image_to_map_corrospondence_kernel", + ) + return image_to_map_corrospondence_kernel + + +def test_kernel( + resolution, + width, + height, + tolerance_z_collision +): + test_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U x1, raw U y1, raw U z1", + out_params="raw U newmap, raw U debug1, raw U debug2", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ int get_x_idx(float16 x, float16 center) { + int i = (x - center) / ${resolution} + 0.5 * ${width}; + return i; + } + __device__ int get_y_idx(float16 y, float16 center) { + int i = (y - center) / ${resolution} + 0.5 * ${height}; + return i; + } + """ + ).substitute(width=width, height=height, resolution=resolution), + operation=string.Template( + """ + // for each cell use Bersenham to calculate projection + unsigned int y0 = i % ${width}; + unsigned int x0 = i / ${width}; + + unsigned int y0_c = y0; + unsigned int x0_c = x0; + + + float z0 = map[get_map_idx(i, 0)]; + float t1 = x1-x0_c; + float t2 = y1 - y0_c; + float total_dis = sqrt( t1*t1 + t2*t2); + debug2[get_map_idx(i, 0)] = total_dis; + + if (total_dis == 0){ + return; + } + float delta_z = z1-z0; + + + // following plotLine implementation wikipedia https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm + + unsigned int dx = abs(x1-x0); + unsigned int sx = x0 < x1 ? 1 : -1; + unsigned int dy = -abs(y1 - y0); + unsigned int sy = y0 < y1 ? 1 : -1; + unsigned int error = dx + dy; + + unsigned int k = 0; + while (1){ + // TODO do here the calculation + k++; + debug1[get_map_idx(i, 0)] = k; + + unsigned int idx = y0 + (x0 * ${width}); + + float t1 = x0 - x0_c; + float t2 = y0 - y0_c; + + float dis = sqrt( t1*t1 + t2*t2); + float rayheight = z0 + dis/total_dis * (delta_z); + + if ( map[ get_map_idx(idx, 0)] > rayheight-${tolerance_z_collision}){ + newmap[get_map_idx(i, 0)] = 0; + } + + if (x0 == x1 && y0 == y1){ + return; + } + unsigned int e2 = 2 * error; + if (e2 >= dy){ + if(x0 == x1){ + return; + } + error = error + dy; + x0 = x0 + sx; + } + if (e2 <= dx){ + if (y0 == y1){ + return; + } + error = error + dx; + y0 = y0 + sy; + } + } + """ + ).substitute( + height=height, width=width, resolution=resolution, tolerance_z_collision=tolerance_z_collision + ), + name="test_kernel", + ) + return test_kernel + + + + +if __name__ == "__main__": + import numpy as np + kernel = test_kernel( + resolution = 0.1, + width = 100, + height = 100, + tolerance_z_collision = 0.0 + ) + arr1 = cp.asarray( np.ones( (100,100), dtype=np.float32), dtype=np.float32) + arr1[:2,:2] = 10 + + + arr_out = cp.asarray( np.ones( (100,100), dtype=np.float32), dtype=np.float32) + + debug1 = cp.asarray( np.ones( (100,100), dtype=np.float32), dtype=np.float32) + debug2 = cp.asarray( np.ones( (100,100), dtype=np.float32), dtype=np.float32) + camera_x_idx = cp.uint32( 0 ) + camera_y_idx = cp.uint32( 10 ) + camera_z_meter = cp.float32( 2.0 ) + kernel(arr1, camera_x_idx, camera_y_idx, camera_z_meter, arr_out, debug1, debug2, size=int(arr1.shape[0] * arr1.shape[1]) ) + + print(arr1) + print(arr_out) + + print("K") + print(debug1) + + print("distance") + print(debug2) \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 663d4a73..cb32eb27 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -18,6 +18,9 @@ from elevation_mapping_cupy.custom_kernels import dilation_filter_kernel from elevation_mapping_cupy.custom_kernels import normal_filter_kernel from elevation_mapping_cupy.custom_kernels import polygon_mask_kernel +from elevation_mapping_cupy.custom_semantic_image_kernels import image_to_map_corrospondence_kernel + + from elevation_mapping_cupy.map_initializer import MapInitializer from elevation_mapping_cupy.plugins.plugin_manager import PluginManager from elevation_mapping_cupy.semantic_map import SemanticMap @@ -272,6 +275,16 @@ def compile_kernels(self): self.polygon_mask_kernel = polygon_mask_kernel(self.cell_n, self.cell_n, self.resolution) self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) + def compile_semantic_image_kernels(self): + self.corrospondence_map = cp.zeros((self.elevation_map.shape[0], self.cell_n, self.cell_n),dtype=self.data_type) + + self.image_to_map_corrospondence_kernel = image_to_map_corrospondence_kernel( + self.resolution, + self.cell_n, + self.cell_n + ) + + def shift_translation_to_map_center(self, t): """ Deduct the map center to get the translation of a point w.r.t. the map center. @@ -359,7 +372,7 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori self.update_normal(self.traversability_input) - def update_map_with_semantic_kernel(self, semantic_image, K, channels, R, t): + def update_map_with_semantic_image_kernel(self, semantic_image, K, channels, R, t): """Update map with new measurement from semantic image. Args: @@ -369,7 +382,13 @@ def update_map_with_semantic_kernel(self, semantic_image, K, channels, R, t): R (cupy._core.core.ndarray): t (cupy._core.core.ndarray): """ - print("not implemented") + self.corrospondence_map *= 0 + # TODO Speedup 1. Compute frustrum mask + + # TODO Minimal 2. Compute corrospondences based on visibilitz check (map to image) + self.image_to_map_corrospondence_kernel(H,W,K,R,t, self.corrospondence_map) + # TODO Minimal 3. Update the semantic layer based on calculated image to map corrospondences + def clear_overlap_map(self, t): # Clear overlapping area around center @@ -435,7 +454,7 @@ def input_semantic_image(self, R = cp.asarray(R,dtype=self.data_type) t = cp.asarray(t,dtype=self.data_type) - self.update_map_with_semantic_kernel(semantic_image, K, channels, R, t) + self.update_map_with_semantic_image_kernel(semantic_image, K, channels, R, t) def update_normal(self, dilated_map): diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index df8f48b8..d3bd5511 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -96,7 +96,7 @@ def overwrite_elevation_mapping_params(self): else: typ = config["type"] raise ValueError(f"{typ} unknown, only pointcloud and image defined.") - + self.param.additional_layers = additional self.param.fusion_algorithms = fusion self.dtype = [ @@ -199,7 +199,6 @@ def image_callback(self, camera_msg, camera_info_msg, config): self._image_process_counter += 1 def pointcloud_callback(self, msg, config): - print("receive pointcloud") # convert pcd into numpy array # output = {} # total_bytes = msg.fields[-1].offset + PDC_DATATYPE[str(msg.fields[-1].datatype)](1).nbytes @@ -235,7 +234,7 @@ def pointcloud_callback(self, msg, config): # process pointcloud self._map.input(pts, channels, R, t, 0, 0) self._pointcloud_process_counter += 1 - print(self._pointcloud_process_counter) + print("Pointclouds processed: ", self._pointcloud_process_counter) def update_pose(self, t): # get pose of base From 77fbd74406f9d906916cf0bc74d72ad02c90b4a7 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Mon, 21 Nov 2022 22:49:57 -0800 Subject: [PATCH 272/504] semantic image working version --- .../custom_semantic_image_kernerls.py | 211 +++++++++--------- .../elevation_mapping.py | 89 +++++--- .../elevation_mapping_ros.py | 4 +- .../elevation_mapping_cupy/semantic_map.py | 3 + 4 files changed, 171 insertions(+), 136 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py index e7ec2afd..1acd778c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py @@ -1,162 +1,159 @@ import cupy as cp import string - def image_to_map_corrospondence_kernel( - resolution, - width, - height -): - image_to_map_corrospondence_kernel = cp.ElementwiseKernel( - in_params="raw U center_x, raw U center_y, raw U R, raw U t, raw U norm_map", - out_params="raw U p, raw U map, raw T newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - """ - ).substitute( - ), - name="image_to_map_corrospondence_kernel", - ) - return image_to_map_corrospondence_kernel - - -def test_kernel( resolution, width, height, tolerance_z_collision ): - test_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U x1, raw U y1, raw U z1", - out_params="raw U newmap, raw U debug1, raw U debug2", + image_to_map_corrospondence_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U image_height, raw U image_width, raw U center", + out_params="raw U uv_corrospondence, raw B vaild_corrospondence", preamble=string.Template( """ __device__ int get_map_idx(int idx, int layer_n) { const int layer = ${width} * ${height}; return layer * layer_n + idx; } - __device__ int get_x_idx(float16 x, float16 center) { - int i = (x - center) / ${resolution} + 0.5 * ${width}; - return i; + __device__ bool is_inside_map(int x, int y) { + return (x >= 0 && y >= 0 && x<${width} && x<${height}); } - __device__ int get_y_idx(float16 y, float16 center) { - int i = (y - center) / ${resolution} + 0.5 * ${height}; - return i; + __device__ float get_l2_distance(int x0, int y0, int x1, int y1) { + float dx = x0-x1; + float dy = y0-y1; + return sqrt( dx*dx + dy*dy); } """ ).substitute(width=width, height=height, resolution=resolution), operation=string.Template( """ - // for each cell use Bersenham to calculate projection - unsigned int y0 = i % ${width}; - unsigned int x0 = i / ${width}; + int cell_idx = get_map_idx(i, 0); - unsigned int y0_c = y0; - unsigned int x0_c = x0; + // return if gridcell has no valid height + if (map[get_map_idx(i, 2)] != 1){ + return; + } + // get current cell position + int y0 = i % ${width}; + int x0 = i / ${width}; - float z0 = map[get_map_idx(i, 0)]; - float t1 = x1-x0_c; - float t2 = y1 - y0_c; - float total_dis = sqrt( t1*t1 + t2*t2); - debug2[get_map_idx(i, 0)] = total_dis; + // gridcell 3D point in worldframe TODO reverse x and y + float p1 = (x0-(${width}/2)) * ${resolution} + center[0]; + float p2 = (y0-(${height}/2)) * ${resolution} + center[1]; + float p3 = map[cell_idx] + center[2]; - if (total_dis == 0){ + // reproject 3D point into image plane + float u = p1 * P[0] + p2 * P[1] + p3 * P[2] + P[3]; + float v = p1 * P[4] + p2 * P[5] + p3 * P[6] + P[7]; + float d = p1 * P[8] + p2 * P[9] + p3 * P[10] + P[11]; + + // filter point behind image plane + if (d <= 0) { return; } - float delta_z = z1-z0; + u = u/d; + v = v/d; + // filter point nexto image plane + if ((u < 0) || (v < 0) || (u >= image_width) || (v >= image_height)){ + return; + } - // following plotLine implementation wikipedia https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm + int y0_c = y0; + int x0_c = x0; + float total_dis = get_l2_distance(x0_c, y0_c, x1,y1); + float z0 = map[cell_idx]; + float delta_z = z1-z0; - unsigned int dx = abs(x1-x0); - unsigned int sx = x0 < x1 ? 1 : -1; - unsigned int dy = -abs(y1 - y0); - unsigned int sy = y0 < y1 ? 1 : -1; - unsigned int error = dx + dy; - unsigned int k = 0; - while (1){ - // TODO do here the calculation - k++; - debug1[get_map_idx(i, 0)] = k; - - unsigned int idx = y0 + (x0 * ${width}); - - float t1 = x0 - x0_c; - float t2 = y0 - y0_c; + // bresenham algorithm to iterate over cells in line between camera center and current gridmap cell + // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm + int dx = abs(x1-x0); + int sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0); + int sy = y0 < y1 ? 1 : -1; + int error = dx + dy; - float dis = sqrt( t1*t1 + t2*t2); - float rayheight = z0 + dis/total_dis * (delta_z); - - if ( map[ get_map_idx(idx, 0)] > rayheight-${tolerance_z_collision}){ - newmap[get_map_idx(i, 0)] = 0; + // iterate over all cells along line + while (1){ + // assumption we do not need to check the height for camera center cell + if (x0 == x1 && y0 == y1){ + break; } - if (x0 == x1 && y0 == y1){ - return; + // check if height is invalid + if (is_inside_map(x0,y0)){ + int idx = y0 + (x0 * ${width}); + if (map[get_map_idx(idx, 2)]){ + float dis = get_l2_distance(x0_c, y0_c, x0, y0); + float rayheight = z0 + ( dis / total_dis * delta_z); + if ( map[idx] - ${tolerance_z_collision} > rayheight){ + break; + } + } } - unsigned int e2 = 2 * error; + + + // computation of next gridcell index in line + int e2 = 2 * error; if (e2 >= dy){ if(x0 == x1){ - return; + break; } error = error + dy; x0 = x0 + sx; } if (e2 <= dx){ if (y0 == y1){ - return; + break; } error = error + dx; - y0 = y0 + sy; + y0 = y0 + sy; } } + + // mark the corrospondence + uv_corrospondence[get_map_idx(i, 0)] = u; + uv_corrospondence[get_map_idx(i, 1)] = v; + vaild_corrospondence[get_map_idx(i, 0)] = 1; """ ).substitute( height=height, width=width, resolution=resolution, tolerance_z_collision=tolerance_z_collision ), - name="test_kernel", + name="image_to_map_corrospondence_kernel", ) - return test_kernel - - + return image_to_map_corrospondence_kernel -if __name__ == "__main__": - import numpy as np - kernel = test_kernel( - resolution = 0.1, - width = 100, - height = 100, - tolerance_z_collision = 0.0 +def average_corrospondences_to_map_kernel( + resolution, + width, + height +): + average_corrospondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U semantic_image, raw U uv_corrospondence, raw B vaild_corrospondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + int cell_idx_2 = get_map_idx(i, 1); + if (vaild_corrospondence[cell_idx]){ + int idx = int(uv_corrospondence[cell_idx]) + int(uv_corrospondence[cell_idx_2]) * image_width; + new_sem_map[cell_idx] = semantic_image[idx]; + } + """ + ).substitute( + ), + name="average_corrospondences_to_map_kernel", ) - arr1 = cp.asarray( np.ones( (100,100), dtype=np.float32), dtype=np.float32) - arr1[:2,:2] = 10 - - - arr_out = cp.asarray( np.ones( (100,100), dtype=np.float32), dtype=np.float32) - - debug1 = cp.asarray( np.ones( (100,100), dtype=np.float32), dtype=np.float32) - debug2 = cp.asarray( np.ones( (100,100), dtype=np.float32), dtype=np.float32) - camera_x_idx = cp.uint32( 0 ) - camera_y_idx = cp.uint32( 10 ) - camera_z_meter = cp.float32( 2.0 ) - kernel(arr1, camera_x_idx, camera_y_idx, camera_z_meter, arr_out, debug1, debug2, size=int(arr1.shape[0] * arr1.shape[1]) ) - - print(arr1) - print(arr_out) - - print("K") - print(debug1) - - print("distance") - print(debug2) \ No newline at end of file + return average_corrospondences_to_map_kernel diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index cb32eb27..fb77c4a8 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -18,7 +18,9 @@ from elevation_mapping_cupy.custom_kernels import dilation_filter_kernel from elevation_mapping_cupy.custom_kernels import normal_filter_kernel from elevation_mapping_cupy.custom_kernels import polygon_mask_kernel -from elevation_mapping_cupy.custom_semantic_image_kernels import image_to_map_corrospondence_kernel + +from elevation_mapping_cupy.custom_semantic_image_kernerls import image_to_map_corrospondence_kernel +from elevation_mapping_cupy.custom_semantic_image_kernerls import average_corrospondences_to_map_kernel from elevation_mapping_cupy.map_initializer import MapInitializer @@ -90,6 +92,7 @@ def __init__(self, param: Parameter): self.additive_mean_error = 0.0 self.compile_kernels() + self.compile_semantic_image_kernels() self.semantic_map.compile_kernels() weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') @@ -276,12 +279,21 @@ def compile_kernels(self): self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) def compile_semantic_image_kernels(self): - self.corrospondence_map = cp.zeros((self.elevation_map.shape[0], self.cell_n, self.cell_n),dtype=self.data_type) - + self.new_sem_map = cp.asarray( np.zeros( ( self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) + self.vaild_corrospondence = cp.asarray( np.zeros( ( self.cell_n, self.cell_n), dtype=np.bool), dtype=np.bool) + self.uv_corrospondence = cp.asarray( np.zeros( ( 2, self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) + self.image_to_map_corrospondence_kernel = image_to_map_corrospondence_kernel( - self.resolution, - self.cell_n, - self.cell_n + resolution = self.resolution, + width = self.cell_n, + height = self.cell_n, + tolerance_z_collision = 0.1 + ) + + self.average_corrospondences_to_map_kernel = average_corrospondences_to_map_kernel( + resolution = self.resolution, + width = self.cell_n, + height = self.cell_n ) @@ -372,23 +384,50 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori self.update_normal(self.traversability_input) - def update_map_with_semantic_image_kernel(self, semantic_image, K, channels, R, t): + def update_map_with_semantic_image_kernel(self, semantic_image, K, channels, R, t, image_height, image_width): """Update map with new measurement from semantic image. - - Args: - semantic_image (cupy._core.core.ndarray): - K (cupy._core.core.ndarray): - channels (List[str]): - R (cupy._core.core.ndarray): - t (cupy._core.core.ndarray): """ - self.corrospondence_map *= 0 - # TODO Speedup 1. Compute frustrum mask + P = cp.asarray( K @ np.concatenate([R, t[:, None]], 1), dtype=np.float32) + + t_cam_map = -R.T@t + t_cam_map -= self.center.get() + + x1 = cp.uint32((self.cell_n/2) + ((t_cam_map[0])/self.resolution)) + y1 = cp.uint32((self.cell_n/2) + ((t_cam_map[1])/self.resolution)) + z1 = cp.float32(t_cam_map[2]) + + semantic_image = cp.asarray( semantic_image, dtype=np.float32) - # TODO Minimal 2. Compute corrospondences based on visibilitz check (map to image) - self.image_to_map_corrospondence_kernel(H,W,K,R,t, self.corrospondence_map) - # TODO Minimal 3. Update the semantic layer based on calculated image to map corrospondences + self.new_sem_map *= 0 + self.uv_corrospondence *= 0 + self.vaild_corrospondence[:,:] = False + with self.map_lock: + sem_map_idx = self.semantic_map.get_index(channels[0]) + self.image_to_map_corrospondence_kernel( + self.elevation_map, + x1,y1,z1, + P.reshape(-1), + cp.float32(image_height), + cp.float32(image_width), + self.center, + self.uv_corrospondence, + self.vaild_corrospondence, + size=int(self.elevation_map.shape[1] * self.elevation_map.shape[2]) + ) + + self.average_corrospondences_to_map_kernel( + self.semantic_map.map[sem_map_idx], + semantic_image, + self.uv_corrospondence, + self.vaild_corrospondence, + cp.float32(image_height), + cp.float32(image_width), + self.new_sem_map, + size=int(self.elevation_map.shape[1] * self.elevation_map.shape[2]) + ) + + self.semantic_map.map[sem_map_idx] = self.new_sem_map def clear_overlap_map(self, t): # Clear overlapping area around center @@ -446,15 +485,11 @@ def input_semantic_image(self, K: cp._core.core.ndarray, channels: List[str], R: cp._core.core.ndarray, - t: cp._core.core.ndarray + t: cp._core.core.ndarray, + image_height : int, + image_width : int ): - - semantic_image = cp.asarray(semantic_image, dtype=self.data_type) - K = cp.asarray(K, dtype=self.data_type) - R = cp.asarray(R,dtype=self.data_type) - t = cp.asarray(t,dtype=self.data_type) - - self.update_map_with_semantic_image_kernel(semantic_image, K, channels, R, t) + self.update_map_with_semantic_image_kernel(semantic_image, K, channels, R, t, image_height, image_width) def update_normal(self, dilated_map): diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index d3bd5511..aab73635 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -179,7 +179,7 @@ def image_callback(self, camera_msg, camera_info_msg, config): ti = rospy.Time(secs=camera_msg.header.stamp.secs, nsecs=camera_msg.header.stamp.nsecs) self._last_t = ti try: - transform = self._tf_buffer.lookup_transform(self.map_frame, camera_msg.header.frame_id, ti, rospy.Duration(1.0)) + transform = self._tf_buffer.lookup_transform(camera_msg.header.frame_id, self.map_frame, ti, rospy.Duration(1.0)) except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: print("pointcloud_callback error:", e) return @@ -195,7 +195,7 @@ def image_callback(self, camera_msg, camera_info_msg, config): assert np.all( np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" K = np.array( camera_info_msg.K , dtype=np.float32).reshape(3,3) # process pointcloud - self._map.input_semantic_image(semantic_img, K, config[0], R, t) + self._map.input_semantic_image(semantic_img, K, config[0], R, t, camera_info_msg.height, camera_info_msg.width) self._image_process_counter += 1 def pointcloud_callback(self, msg, config): diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 7ab2b289..017ef9b0 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -251,3 +251,6 @@ def get_semantic(self, name): def process_map_for_publish(self, input_map): m = input_map.copy() return m[1:-1, 1:-1] + + def get_index(self, name): + return self.param.additional_layers.index(name) From 36ee89c77b27ec7c3d08c0623c0270884d63d332 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Mon, 21 Nov 2022 23:02:27 -0800 Subject: [PATCH 273/504] black formatting --- .../custom_semantic_image_kernerls.py | 21 +- .../elevation_mapping.py | 226 +++++++++--------- .../elevation_mapping_ros.py | 28 +-- .../elevation_mapping_cupy/semantic_map.py | 10 +- 4 files changed, 138 insertions(+), 147 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py index 1acd778c..88b5ddf2 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py @@ -1,12 +1,8 @@ import cupy as cp import string -def image_to_map_corrospondence_kernel( - resolution, - width, - height, - tolerance_z_collision -): + +def image_to_map_corrospondence_kernel(resolution, width, height, tolerance_z_collision): image_to_map_corrospondence_kernel = cp.ElementwiseKernel( in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U image_height, raw U image_width, raw U center", out_params="raw U uv_corrospondence, raw B vaild_corrospondence", @@ -119,19 +115,13 @@ def image_to_map_corrospondence_kernel( uv_corrospondence[get_map_idx(i, 1)] = v; vaild_corrospondence[get_map_idx(i, 0)] = 1; """ - ).substitute( - height=height, width=width, resolution=resolution, tolerance_z_collision=tolerance_z_collision - ), + ).substitute(height=height, width=width, resolution=resolution, tolerance_z_collision=tolerance_z_collision), name="image_to_map_corrospondence_kernel", ) return image_to_map_corrospondence_kernel -def average_corrospondences_to_map_kernel( - resolution, - width, - height -): +def average_corrospondences_to_map_kernel(resolution, width, height): average_corrospondences_to_map_kernel = cp.ElementwiseKernel( in_params="raw U sem_map, raw U semantic_image, raw U uv_corrospondence, raw B vaild_corrospondence, raw U image_height, raw U image_width", out_params="raw U new_sem_map", @@ -152,8 +142,7 @@ def average_corrospondences_to_map_kernel( new_sem_map[cell_idx] = semantic_image[idx]; } """ - ).substitute( - ), + ).substitute(), name="average_corrospondences_to_map_kernel", ) return average_corrospondences_to_map_kernel diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index fb77c4a8..d6e8a38d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -40,6 +40,7 @@ pool = cp.cuda.MemoryPool(cp.cuda.malloc_managed) cp.cuda.set_allocator(pool.malloc) + class ElevationMap: """ Core elevation mapping class. @@ -62,7 +63,7 @@ def __init__(self, param: Parameter): self.map_lock = threading.Lock() self.additional_layers = dict(zip(self.param.additional_layers, self.param.fusion_algorithms)) self.semantic_map = SemanticMap(self.param, self.additional_layers) - self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n),dtype=self.data_type) + self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n), dtype=self.data_type) self.layer_names = [ "elevation", "variance", @@ -112,9 +113,7 @@ def __init__(self, param: Parameter): self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") def clear(self): - """Reset all the layers of the elevation & the semantic map. - - """ + """Reset all the layers of the elevation & the semantic map.""" with self.map_lock: self.elevation_map *= 0.0 # Initial variance @@ -148,14 +147,14 @@ def move(self, delta_position): self.shift_map_z(-delta_position[2]) def move_to(self, position, R): - """ Shift the map to an absolute position and update the rotation of the robot. + """Shift the map to an absolute position and update the rotation of the robot. Args: position (numpy.ndarray): R (cupy._core.core.ndarray): """ # Shift map to the center of robot. - self.base_rotation = xp.asarray(R,dtype=self.data_type) + self.base_rotation = xp.asarray(R, dtype=self.data_type) position = xp.asarray(position) delta = position - self.center delta_pixel = xp.around(delta[:2] / self.resolution) @@ -224,16 +223,14 @@ def shift_map_z(self, delta_z): self.elevation_map[5] += delta_z def compile_kernels(self): - """Compile all kernels belonging to the elevation map. - - """ + """Compile all kernels belonging to the elevation map.""" # Compile custom cuda kernels. - self.new_map = cp.zeros((self.elevation_map.shape[0], self.cell_n, self.cell_n),dtype=self.data_type) - self.traversability_input = cp.zeros((self.cell_n, self.cell_n),dtype=self.data_type) - self.traversability_mask_dummy = cp.zeros((self.cell_n, self.cell_n),dtype=self.data_type) - self.min_filtered = cp.zeros((self.cell_n, self.cell_n),dtype=self.data_type) - self.min_filtered_mask = cp.zeros((self.cell_n, self.cell_n),dtype=self.data_type) - self.mask = cp.zeros((self.cell_n, self.cell_n),dtype=self.data_type) + self.new_map = cp.zeros((self.elevation_map.shape[0], self.cell_n, self.cell_n), dtype=self.data_type) + self.traversability_input = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + self.traversability_mask_dummy = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + self.min_filtered = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + self.min_filtered_mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + self.mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) self.add_points_kernel = add_points_kernel( self.resolution, self.cell_n, @@ -279,26 +276,20 @@ def compile_kernels(self): self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) def compile_semantic_image_kernels(self): - self.new_sem_map = cp.asarray( np.zeros( ( self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) - self.vaild_corrospondence = cp.asarray( np.zeros( ( self.cell_n, self.cell_n), dtype=np.bool), dtype=np.bool) - self.uv_corrospondence = cp.asarray( np.zeros( ( 2, self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) - + self.new_sem_map = cp.asarray(np.zeros((self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) + self.vaild_corrospondence = cp.asarray(np.zeros((self.cell_n, self.cell_n), dtype=np.bool), dtype=np.bool) + self.uv_corrospondence = cp.asarray(np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) + self.image_to_map_corrospondence_kernel = image_to_map_corrospondence_kernel( - resolution = self.resolution, - width = self.cell_n, - height = self.cell_n, - tolerance_z_collision = 0.1 + resolution=self.resolution, width=self.cell_n, height=self.cell_n, tolerance_z_collision=0.1 ) - + self.average_corrospondences_to_map_kernel = average_corrospondences_to_map_kernel( - resolution = self.resolution, - width = self.cell_n, - height = self.cell_n + resolution=self.resolution, width=self.cell_n, height=self.cell_n ) - def shift_translation_to_map_center(self, t): - """ Deduct the map center to get the translation of a point w.r.t. the map center. + """Deduct the map center to get the translation of a point w.r.t. the map center. Args: t (cupy._core.core.ndarray): Absolute point position @@ -306,28 +297,28 @@ def shift_translation_to_map_center(self, t): t -= self.center def update_map_with_kernel(self, points_all, channels, R, t, position_noise, orientation_noise): - """Update map with new measurement. + """Update map with new measurement. Args: - points_all (cupy._core.core.ndarray): - channels (List[str]): - R (cupy._core.core.ndarray): - t (cupy._core.core.ndarray): - position_noise (int): - orientation_noise (int): + points_all (cupy._core.core.ndarray): + channels (List[str]): + R (cupy._core.core.ndarray): + t (cupy._core.core.ndarray): + position_noise (int): + orientation_noise (int): """ self.new_map *= 0.0 error = cp.array([0.0], dtype=cp.float32) error_cnt = cp.array([0], dtype=cp.float32) - points = points_all[:,:3] + points = points_all[:, :3] # additional_fusion = self.get_fusion_of_pcl(channels) with self.map_lock: self.shift_translation_to_map_center(t) self.error_counting_kernel( self.elevation_map, points, - cp.array([0.0],dtype=self.data_type), - cp.array([0.0],dtype=self.data_type), + cp.array([0.0], dtype=self.data_type), + cp.array([0.0], dtype=self.data_type), R, t, self.new_map, @@ -348,8 +339,8 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori if np.abs(self.mean_error) < self.param.max_drift: self.elevation_map[0] += self.mean_error * self.param.drift_compensation_alpha self.add_points_kernel( - cp.array([0.0],dtype=self.data_type), - cp.array([0.0],dtype=self.data_type), + cp.array([0.0], dtype=self.data_type), + cp.array([0.0], dtype=self.data_type), R, t, self.normal_map, @@ -383,52 +374,52 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori # calculate normal vectors self.update_normal(self.traversability_input) - def update_map_with_semantic_image_kernel(self, semantic_image, K, channels, R, t, image_height, image_width): - """Update map with new measurement from semantic image. - """ - P = cp.asarray( K @ np.concatenate([R, t[:, None]], 1), dtype=np.float32) - - t_cam_map = -R.T@t + """Update map with new measurement from semantic image.""" + P = cp.asarray(K @ np.concatenate([R, t[:, None]], 1), dtype=np.float32) + + t_cam_map = -R.T @ t t_cam_map -= self.center.get() - - x1 = cp.uint32((self.cell_n/2) + ((t_cam_map[0])/self.resolution)) - y1 = cp.uint32((self.cell_n/2) + ((t_cam_map[1])/self.resolution)) + + x1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[0]) / self.resolution)) + y1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[1]) / self.resolution)) z1 = cp.float32(t_cam_map[2]) - - semantic_image = cp.asarray( semantic_image, dtype=np.float32) - + + semantic_image = cp.asarray(semantic_image, dtype=np.float32) + self.new_sem_map *= 0 self.uv_corrospondence *= 0 - self.vaild_corrospondence[:,:] = False - + self.vaild_corrospondence[:, :] = False + with self.map_lock: sem_map_idx = self.semantic_map.get_index(channels[0]) self.image_to_map_corrospondence_kernel( - self.elevation_map, - x1,y1,z1, - P.reshape(-1), - cp.float32(image_height), - cp.float32(image_width), + self.elevation_map, + x1, + y1, + z1, + P.reshape(-1), + cp.float32(image_height), + cp.float32(image_width), self.center, self.uv_corrospondence, self.vaild_corrospondence, - size=int(self.elevation_map.shape[1] * self.elevation_map.shape[2]) + size=int(self.elevation_map.shape[1] * self.elevation_map.shape[2]), ) - + self.average_corrospondences_to_map_kernel( self.semantic_map.map[sem_map_idx], semantic_image, self.uv_corrospondence, self.vaild_corrospondence, - cp.float32(image_height), + cp.float32(image_height), cp.float32(image_width), self.new_sem_map, - size=int(self.elevation_map.shape[1] * self.elevation_map.shape[2]) + size=int(self.elevation_map.shape[1] * self.elevation_map.shape[2]), ) - + self.semantic_map.map[sem_map_idx] = self.new_sem_map - + def clear_overlap_map(self, t): # Clear overlapping area around center height_min = t[2] - self.param.overlap_clear_range_z @@ -456,47 +447,59 @@ def update_upper_bound_with_valid_elevation(self): mask = self.elevation_map[2] > 0.5 self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) - - def input(self, raw_points: cp._core.core.ndarray, channels: List[str], R: cp._core.core.ndarray, - t: cp._core.core.ndarray, - position_noise: int, - orientation_noise: int) -> None: + + def input( + self, + raw_points: cp._core.core.ndarray, + channels: List[str], + R: cp._core.core.ndarray, + t: cp._core.core.ndarray, + position_noise: int, + orientation_noise: int, + ) -> None: """Input the pointcloud and fuse the new measurements to update the elevation map. Args: - raw_points (cupy._core.core.ndarray): - channels (List[str]): + raw_points (cupy._core.core.ndarray): + channels (List[str]): R (cupy._core.core.ndarray): - t (cupy._core.core.ndarray): - position_noise (int): - orientation_noise (int): + t (cupy._core.core.ndarray): + position_noise (int): + orientation_noise (int): Returns: - None: + None: """ # Update elevation map using point cloud input. raw_points = cp.asarray(raw_points, dtype=self.data_type) additional_channels = channels[3:] raw_points = raw_points[~cp.isnan(raw_points).any(axis=1)] - self.update_map_with_kernel(raw_points, additional_channels, cp.asarray(R,dtype=self.data_type), cp.asarray(t,dtype=self.data_type), position_noise, orientation_noise) + self.update_map_with_kernel( + raw_points, + additional_channels, + cp.asarray(R, dtype=self.data_type), + cp.asarray(t, dtype=self.data_type), + position_noise, + orientation_noise, + ) - def input_semantic_image(self, - semantic_image: cp._core.core.ndarray, - K: cp._core.core.ndarray, - channels: List[str], + def input_semantic_image( + self, + semantic_image: cp._core.core.ndarray, + K: cp._core.core.ndarray, + channels: List[str], R: cp._core.core.ndarray, t: cp._core.core.ndarray, - image_height : int, - image_width : int - ): + image_height: int, + image_width: int, + ): self.update_map_with_semantic_image_kernel(semantic_image, K, channels, R, t, image_height, image_width) - - + def update_normal(self, dilated_map): - """ Clear the normal map and then apply the normal kernel with dilated map as input. + """Clear the normal map and then apply the normal kernel with dilated map as input. Args: - dilated_map (cupy._core.core.ndarray): + dilated_map (cupy._core.core.ndarray): """ with self.map_lock: self.normal_map *= 0.0 @@ -505,16 +508,16 @@ def update_normal(self, dilated_map): ) def process_map_for_publish(self, input_map, fill_nan=False, add_z=False, xp=cp): - """ Process the input_map according to the fill_nan and add_z flags. + """Process the input_map according to the fill_nan and add_z flags. Args: - input_map (cupy._core.core.ndarray): - fill_nan (bool): - add_z (bool): - xp (module): + input_map (cupy._core.core.ndarray): + fill_nan (bool): + add_z (bool): + xp (module): Returns: - cupy._core.core.ndarray: + cupy._core.core.ndarray: """ m = input_map.copy() if fill_nan: @@ -577,7 +580,7 @@ def xp_of_array(self, array): return np def copy_to_cpu(self, array, data, stream=None): - """ Transforms the data to float32 and if on gpu loads it to cpu. + """Transforms the data to float32 and if on gpu loads it to cpu. Args: array (cupy._core.core.ndarray): @@ -593,7 +596,7 @@ def copy_to_cpu(self, array, data, stream=None): data[...] = cp.asnumpy(array.astype(np.float32)) def exists_layer(self, name): - """ Check if the layer exists in elevation map or in the semantic map. + """Check if the layer exists in elevation map or in the semantic map. Args: name (str): @@ -643,7 +646,9 @@ def get_map_with_name_ref(self, name, data): elif name in self.additional_layers.keys(): m = self.semantic_map.get_map_with_name(name) elif name in self.plugin_manager.layer_names: - self.plugin_manager.update_with_name(name, self.elevation_map, self.layer_names, self.semantic_map, self.base_rotation) + self.plugin_manager.update_with_name( + name, self.elevation_map, self.layer_names, self.semantic_map, self.base_rotation + ) m = self.plugin_manager.get_map_with_name(name) p = self.plugin_manager.get_param_with_name(name) xp = self.xp_of_array(m) @@ -677,16 +682,17 @@ def get_normal_ref(self, normal_x_data, normal_y_data, normal_z_data): normal_y_data[...] = xp.asnumpy(maps[1], stream=self.stream) normal_z_data[...] = xp.asnumpy(maps[2], stream=self.stream) - def get_layer(self,name): + def get_layer(self, name): if name in self.layer_names: idx = self.layer_names.index(name) map = self.elevation_map[idx] elif name in self.semantic_map.param.additional_layers: idx = self.semantic_map.param.additional_layers.index(name) - map= self.semantic_map.map[idx] + map = self.semantic_map.map[idx] elif name in self.plugin_manager.layer_names: - self.plugin_manager.update_with_name(name, self.elevation_map, self.layer_names, self.semantic_map, - self.base_rotation) + self.plugin_manager.update_with_name( + name, self.elevation_map, self.layer_names, self.semantic_map, self.base_rotation + ) map = self.plugin_manager.get_map_with_name(name) else: print("Layer {} is not in the map, returning traversabiltiy!".format(name)) @@ -694,7 +700,7 @@ def get_layer(self,name): return map def get_polygon_traversability(self, polygon, result): - """ Check if input polygons are traversable. + """Check if input polygons are traversable. Args: polygon (cupy._core.core.ndarray): @@ -745,7 +751,7 @@ def get_polygon_traversability(self, polygon, result): return untraversable_polygon_num def get_untraversable_polygon(self, untraversable_polygon): - """ Copy the untraversable polygons to input untraversable_polygons. + """Copy the untraversable polygons to input untraversable_polygons. Args: untraversable_polygon (numpy.ndarray): @@ -761,7 +767,7 @@ def initialize_map(self, points, method="cubic"): """ self.clear() with self.map_lock: - points = cp.asarray(points,dtype=self.data_type) + points = cp.asarray(points, dtype=self.data_type) indices = transform_to_map_index(points[:, :2], self.center[:2], self.cell_n, self.resolution) points[:, :2] = indices.astype(points.dtype) points[:, 2] -= self.center[2] @@ -789,18 +795,18 @@ def initialize_map(self, points, method="cubic"): param = Parameter( use_chainer=False, weight_file="../config/weights.dat", plugin_config_file="../config/plugin_config.yaml" ) - param.additional_layers =['feat_0','feat_1', 'rgb','people'] - param.fusion_algorithms = ['average','average','color','class_average'] + param.additional_layers = ["feat_0", "feat_1", "rgb", "people"] + param.fusion_algorithms = ["average", "average", "color", "class_average"] param.update() elevation = ElevationMap(param) - layers = ["elevation", "variance", "traversability", "min_filter", "smooth", "inpaint","rgb"] + layers = ["elevation", "variance", "traversability", "min_filter", "smooth", "inpaint", "rgb"] points = xp.random.rand(100000, len(layers)) - channels = ['x', 'y', 'z'] + param.additional_layers + channels = ["x", "y", "z"] + param.additional_layers print(channels) data = np.zeros((elevation.cell_n - 2, elevation.cell_n - 2), dtype=np.float32) for i in range(20): - elevation.input(points,channels, R, t, 0, 0) + elevation.input(points, channels, R, t, 0, 0) elevation.update_normal(elevation.elevation_map[0]) pos = np.array([i * 0.01, i * 0.02, i * 0.01]) elevation.move_to(pos, R) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index aab73635..0b8904a2 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -86,8 +86,8 @@ def overwrite_elevation_mapping_params(self): additional.append(chan) if fus not in fusion: fusion.append(fus) - - elif config["type"] == "pointcloud": + + elif config["type"] == "pointcloud": for chan, fus in zip(config["channels"], config["fusion"]): if chan not in additional: additional.append(chan) @@ -96,7 +96,7 @@ def overwrite_elevation_mapping_params(self): else: typ = config["type"] raise ValueError(f"{typ} unknown, only pointcloud and image defined.") - + self.param.additional_layers = additional self.param.fusion_algorithms = fusion self.dtype = [ @@ -106,8 +106,7 @@ def overwrite_elevation_mapping_params(self): ] for chan in config["channels"]: self.dtype.append((chan, np.float32)) - - + def register_subscribers(self): pointcloud_subs = {} image_subs = {} @@ -116,11 +115,11 @@ def register_subscribers(self): camera_sub = message_filters.Subscriber(config["topic_name_camera"], Image) camera_info_sub = message_filters.Subscriber(config["topic_name_camera_info"], CameraInfo) image_subs[key] = message_filters.ApproximateTimeSynchronizer( - [ camera_sub, camera_info_sub], queue_size=10,slop=0.5 + [camera_sub, camera_info_sub], queue_size=10, slop=0.5 ) image_subs[key].registerCallback(self.image_callback, (config["channels"], config["fusion"])) - - elif config["type"] == "pointcloud": + + elif config["type"] == "pointcloud": pointcloud_subs[key] = rospy.Subscriber( config["topic_name"], PointCloud2, self.pointcloud_callback, (config["channels"], config["fusion"]) ) @@ -179,7 +178,9 @@ def image_callback(self, camera_msg, camera_info_msg, config): ti = rospy.Time(secs=camera_msg.header.stamp.secs, nsecs=camera_msg.header.stamp.nsecs) self._last_t = ti try: - transform = self._tf_buffer.lookup_transform(camera_msg.header.frame_id, self.map_frame, ti, rospy.Duration(1.0)) + transform = self._tf_buffer.lookup_transform( + camera_msg.header.frame_id, self.map_frame, ti, rospy.Duration(1.0) + ) except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: print("pointcloud_callback error:", e) return @@ -189,15 +190,14 @@ def image_callback(self, camera_msg, camera_info_msg, config): q = transform.transform.rotation R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] + semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") - semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") - - assert np.all( np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" - K = np.array( camera_info_msg.K , dtype=np.float32).reshape(3,3) + assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" + K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) # process pointcloud self._map.input_semantic_image(semantic_img, K, config[0], R, t, camera_info_msg.height, camera_info_msg.width) self._image_process_counter += 1 - + def pointcloud_callback(self, msg, config): # convert pcd into numpy array # output = {} diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 017ef9b0..3d13ffe7 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -71,9 +71,7 @@ def compile_kernels(self) -> None: self.param.cell_n, self.param.cell_n, ) - self.color_average_kernel = color_average_kernel( - self.param.cell_n, self.param.cell_n - ) + self.color_average_kernel = color_average_kernel(self.param.cell_n, self.param.cell_n) if "class_average" in self.unique_fusion: print("Initialize class average kernel") self.sum_kernel = sum_kernel( @@ -194,9 +192,7 @@ def update_layers(self, points_all, channels, R, t, elevation_map): ) # calculate new thetas sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) - self.map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims( - sum_alpha, axis=0 - ) + self.map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) # assert cp.unique(cp.sum(self.map[layer_ids], axis=0)) equal to zero or to nan if "color" in additional_fusion: @@ -251,6 +247,6 @@ def get_semantic(self, name): def process_map_for_publish(self, input_map): m = input_map.copy() return m[1:-1, 1:-1] - + def get_index(self, name): return self.param.additional_layers.index(name) From 241d90bc7fa3f0b55c47be9fb86f0abe84add114 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Wed, 23 Nov 2022 15:00:14 +0100 Subject: [PATCH 274/504] detectron properly working also with the instances --- .../semantic_pointcloud/tests/test_utils.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py index 86ad0899..51513b72 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py @@ -2,7 +2,10 @@ from semantic_pointcloud.utils import resolve_model import cupy as cp import torch -from semantic_pointcloud.pointcloud_parameters import FeatureExtractorParameter +from semantic_pointcloud.pointcloud_parameters import ( + FeatureExtractorParameter, + PointcloudParameter, +) @pytest.mark.parametrize( @@ -14,15 +17,17 @@ ], ) def test_semantic_segmentation(model_name): - m = resolve_model(model_name) + param = PointcloudParameter() + param.segmentation_model = model_name + m = resolve_model(model_name, param) im_sz = [360, 640] image = cp.random.random((im_sz[0], im_sz[1], 3)) classes = m["model"].get_classes() assert type(classes) is list prediction = m["model"](image) - assert prediction.shape == torch.Size([len(classes), im_sz[0], im_sz[1]]) - assert (prediction <= 1).all() - assert (0 <= prediction).all() + # assert prediction.shape == torch.Size([len(param.channels), im_sz[0], im_sz[1]]) + # assert (prediction <= 1).all() + # assert (0 <= prediction).all() @pytest.mark.parametrize( @@ -33,6 +38,7 @@ def test_semantic_segmentation(model_name): ) def test_feature_extractor(model_name): param = FeatureExtractorParameter() + param.name = model_name m = resolve_model(model_name, param) im_sz = [320, 640] image = cp.random.random((im_sz[0], im_sz[1], 3)) From d6dd2fe8c8ae8aa18d9894e9b6d242cd23bf5e59 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Wed, 23 Nov 2022 15:00:40 +0100 Subject: [PATCH 275/504] detectron properly working also with the instances --- .../semantic_pointcloud/pointcloud_node.py | 35 +----- .../pointcloud_parameters.py | 4 +- .../script/semantic_pointcloud/utils.py | 106 +++++++++++++++--- 3 files changed, 101 insertions(+), 44 deletions(-) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index 932e34d7..4e4c0472 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -73,10 +73,7 @@ def __init__(self, sensor_name): self.seg_pub = rospy.Publisher( self.param.segmentation_image_topic, Image, queue_size=2 ) - if self.param.pub_all: - self.labels = self.semantic_model["model"].get_classes() - else: - self.labels = list(self.segmentation_channels.keys()) + self.labels = list(self.segmentation_channels.keys()) self.semseg_color_map = self.color_map(len(self.labels)) self.color_map_viz() @@ -118,24 +115,8 @@ def color_map_viz(self): def initialize_semantics(self): if self.param.semantic_segmentation: - self.semantic_model = resolve_model(self.param.segmentation_model) - class_to_idx = { - cls: idx - for (idx, cls) in enumerate(self.semantic_model["model"].get_classes()) - } - print( - "Semantic Segmentation possible channels: ", - self.semantic_model["model"].get_classes(), - ) - indices = [] - channels = [] - for it, chan in enumerate(self.param.channels): - if chan in [cls for cls in list(class_to_idx.keys())]: - indices.append(class_to_idx[chan]) - channels.append(chan) - elif self.param.fusion[it] in ["class_average", "class_bayesian"]: - print(chan, " is not in the semantic segmentation model.") - self.segmentation_channels = dict(zip(channels, indices)) + self.semantic_model = resolve_model(self.param.segmentation_model, self.param) + self.segmentation_channels = self.semantic_model["model"].segmentation_channels if self.param.feature_extractor: self.feature_channels = [] for i, fusion in enumerate(self.param.fusion): @@ -237,15 +218,11 @@ def process_image(self, image, u, v, points): def perform_segmentation(self, image, points, u, v): prediction = self.semantic_model["model"](image) - mask = prediction[list(self.segmentation_channels.values())] - values = mask[:, v.get(), u.get()].cpu().detach().numpy() + values = prediction[:, v.get(), u.get()].get()#.cpu().detach().numpy() for it, channel in enumerate(self.segmentation_channels.keys()): points[channel] = values[it] if self.param.publish_segmentation_image: - if self.param.pub_all: - self.publish_segmentation_image(prediction) - else: - self.publish_segmentation_image(mask) + self.publish_segmentation_image(prediction) def extract_features(self, image, points, u, v): prediction = self.feature_extractor["model"](image) @@ -254,7 +231,7 @@ def extract_features(self, image, points, u, v): points[channel] = values[it] def publish_segmentation_image(self, probabilities): - probabilities = cp.asarray(probabilities) + probabilities = cp.asarray(probabilities.get())# cpu().detach().numpy()) colors = cp.asarray(self.semseg_color_map) assert colors.ndim == 2 and colors.shape[1] == 3 img = cp.argmax(probabilities, axis=0) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py index abdf0491..0d3c035a 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py @@ -20,8 +20,8 @@ class FeatureExtractorParameter(Serializable): class PointcloudParameter(Serializable): sensor_name: str = "camera" topic_name: str = "/elvation_mapping/pointcloud_semantic" - channels: list = ["rgb", "feat_0", "feat_1", "c_prob_0"].copy - fusion: list = ["color", "average", "average", "class_average"].copy + channels: list = field(default_factory=lambda: ["rgb", "person", "grass", "tree"]) + fusion: list = field(default_factory=lambda: ["color", "class_average", "class_average", "class_average"]) semantic_segmentation: bool = True segmentation_model: str = "detectron_coco_panoptic_fpn_R_101_3x" diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py index 9fe62de8..b0e703f6 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py @@ -8,6 +8,7 @@ from torchvision.transforms import Resize import torch.nn.functional as NF import numpy as np +import cupy as cp # Setup detectron2 logger # import detectron2 @@ -33,7 +34,7 @@ # from .pointcloud_parameters import PointcloudParameter, FeatureExtractorParameter -def resolve_model(name, config: FeatureExtractorParameter = None): +def resolve_model(name, config = None): """Get the model class based on the name of the pretrained model. Args: @@ -46,7 +47,7 @@ def resolve_model(name, config: FeatureExtractorParameter = None): if name == "fcn_resnet50": weights = FCN_ResNet50_Weights.DEFAULT net = fcn_resnet50 - model = PytorchModel(net, weights) + model = PytorchModel(net, weights, config) return { "name": "fcn_resnet50", "model": model, @@ -54,19 +55,18 @@ def resolve_model(name, config: FeatureExtractorParameter = None): elif name == "lraspp_mobilenet_v3_large": weights = LRASPP_MobileNet_V3_Large_Weights.DEFAULT net = lraspp_mobilenet_v3_large - model = PytorchModel(net, weights) + model = PytorchModel(net, weights, config) return { "name": "lraspp_mobilenet_v3_large", "model": model, } elif name == "detectron_coco_panoptic_fpn_R_101_3x": - net = "" # "Cityscapes/mask_rcnn_R_50_FPN.yaml" # "Misc/semantic_R_50_FPN_1x.yaml" # "Cityscapes-SemanticSegmentation/deeplab_v3_plus_R_103_os16_mg124_poly_90k_bs16.yaml" # "COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml" weights = "COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml" - model = DetectronModel(net, weights) + model = DetectronModel(weights, config) return { "name": "detectron_coco_panoptic_fpn_R_101_3x", "model": model, @@ -83,12 +83,35 @@ def resolve_model(name, config: FeatureExtractorParameter = None): class PytorchModel: - def __init__(self, net, weights): + def __init__(self, net, weights, param): self.model = net(weights) self.weights = weights + self.param = param self.model.eval() device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") self.model.to(device=device) + self.resolve_cateories() + + def resolve_cateories(self): + class_to_idx = { + cls: idx + for (idx, cls) in enumerate(self.get_classes()) + } + print( + "Semantic Segmentation possible channels: ", + self.get_classes(), + ) + indices = [] + channels = [] + for it, chan in enumerate(self.param.channels): + if chan in [cls for cls in list(class_to_idx.keys())]: + indices.append(class_to_idx[chan]) + channels.append(chan) + elif self.param.fusion[it] in ["class_average", "class_bayesian"]: + print(chan, " is not in the semantic segmentation model.") + self.stuff_categories = dict(zip(channels, indices)) + self.segmentation_channels = self.stuff_categories + def __call__(self, image, *args, **kwargs): """Feewforward image through model. @@ -105,7 +128,8 @@ def __call__(self, image, *args, **kwargs): batch = TF.convert_image_dtype(batch, torch.float32) prediction = self.model(batch)["out"] normalized_masks = torch.squeeze(prediction.softmax(dim=1), dim=0) - return normalized_masks + selected_masks = normalized_masks[list(self.stuff_categories.values())] + return selected_masks def get_classes(self): """Get list of strings containing all the classes. @@ -117,25 +141,81 @@ def get_classes(self): class DetectronModel: - def __init__(self, net, weights): + def __init__(self, weights, param): self.cfg = get_cfg() + self.param = param + # add project-specific config (e.g., TensorMask) here if you're not running a model in detectron2's core library self.cfg.merge_from_file(model_zoo.get_config_file(weights)) self.cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5 # set threshold for this model # Find a model from detectron2's model zoo. You can use the https://dl.fbaipublicfiles... url as well self.cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(weights) self.predictor = DefaultPredictor(self.cfg) + self.meta = MetadataCatalog.get(self.cfg.DATASETS.TRAIN[0]) + self.stuff_categories, self.is_stuff =self.resolve_cateories("stuff_classes") + self.thing_categories, self.is_thing = self.resolve_cateories("thing_classes") + self.segmentation_channels = {} + for chan in self.param.channels: + if chan in self.stuff_categories.keys(): + self.segmentation_channels[chan] = self.stuff_categories[chan] + elif chan in self.thing_categories.keys(): + self.segmentation_channels[chan] = self.thing_categories[chan] + else: + # remove it + pass + + def resolve_cateories(self, name): + classes = self.get_cat(name) + class_to_idx = { + cls: idx + for (idx, cls) in enumerate(classes) + } + print( + "Semantic Segmentation possible channels: ", + classes, + ) + indices = [] + channels = [] + is_thing = [] + for it, chan in enumerate(self.param.channels): + if chan in [cls for cls in list(class_to_idx.keys())]: + indices.append(class_to_idx[chan]) + channels.append(chan) + is_thing.append(True) + elif self.param.fusion[it] in ["class_average", "class_bayesian"]: + is_thing.append(False) + print(chan, " is not in the semantic segmentation model.") + categories = dict(zip(channels, indices)) + cat_isthing = dict(zip(self.param.channels, is_thing)) + return categories, cat_isthing def __call__(self, image, *args, **kwargs): # TODO: there are some instruction on how to change input type + image = cp.flip(image, axis=2) prediction = self.predictor(image.get()) - # panoptic_seg, segments_info = self.predictor(image.get())["panoptic_seg"] - normalized_masks = prediction["sem_seg"].softmax(dim=1) - return normalized_masks + probabilities = cp.asarray(torch.softmax(prediction["sem_seg"], dim=0)) + output = cp.zeros((len(self.segmentation_channels), probabilities.shape[1], probabilities.shape[2])) + # add semseg + output[cp.array(list(self.is_stuff.values()))] = probabilities[list(self.stuff_categories.values())] + # add instances + indices, insta_info = prediction["panoptic_seg"] + # TODO dont know why i need temp, look into how to avoid + temp = output[cp.array(list(self.is_thing.values()))] + for i,insta in enumerate(insta_info): + if insta is None or not insta["isthing"]: + continue + mask = cp.asarray((indices == insta["id"]).int()) + if insta["instance_id"] in self.thing_categories.values(): + temp[i] = mask * insta["score"] + output[cp.array(list(self.is_thing.values()))] = temp + return output + + def get_cat(self,name): + return self.meta.get(name) + def get_classes(self): - meta = MetadataCatalog.get(self.cfg.DATASETS.TRAIN[0]) - return meta.get("stuff_classes") + return self.get_cat("thing_classes")+self.get_cat("stuff_classes") class STEGOModel: From d24f9bf9cfbd1ee983f4b1aad78475b8f4202325 Mon Sep 17 00:00:00 2001 From: Matias Mattamala Date: Mon, 5 Dec 2022 01:27:19 +0000 Subject: [PATCH 276/504] Ongoing implementation of cpp interfaces --- .../elevation_mapping_ros.hpp | 25 +++- .../elevation_mapping_wrapper.hpp | 7 +- .../launch/elevation_mapping_cupy.launch | 1 + ...rnerls.py => custom_image_mono_kernels.py} | 34 ++--- .../elevation_mapping.py | 62 +++++---- .../elevation_mapping_ros.py | 8 +- .../src/elevation_mapping_node.cpp | 2 +- .../src/elevation_mapping_ros.cpp | 118 +++++++++++++++--- .../src/elevation_mapping_wrapper.cpp | 44 ++++++- 9 files changed, 231 insertions(+), 70 deletions(-) rename elevation_mapping_cupy/script/elevation_mapping_cupy/{custom_semantic_image_kernerls.py => custom_image_mono_kernels.py} (81%) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index faa82719..1aea9e0b 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -13,11 +13,16 @@ #include // Pybind -#include // everything needed for embedding +#include // everything needed for embedding // ROS #include +#include +#include +#include #include +#include +#include #include #include #include @@ -36,6 +41,10 @@ #include #include +// OpenCV +#include +#include + #include #include @@ -49,11 +58,21 @@ class ElevationMappingNode { public: ElevationMappingNode(ros::NodeHandle& nh); using RowMatrixXd = Eigen::Matrix; + using ColMatrixXf = Eigen::Matrix; + + using ImageSubscriber = message_filters::Subscriber; + using ImageSubscriberPtr = std::shared_ptr; + using CameraInfoSubscriber = message_filters::Subscriber; + using CameraInfoSubscriberPtr = std::shared_ptr; + using CameraPolicy = message_filters::sync_policies::ApproximateTime; + using CameraSync = message_filters::Synchronizer; + using CameraSyncPtr = std::shared_ptr; private: void readParameters(); void setupMapPublishers(); void pointcloudCallback(const sensor_msgs::PointCloud2& cloud); + void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::vector& channels); void publishAsPointCloud(const grid_map::GridMap& map) const; bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response); @@ -72,8 +91,12 @@ class ElevationMappingNode { void publishMapOfIndex(int index); visualization_msgs::Marker vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id) const; + ros::NodeHandle nh_; std::vector pointcloudSubs_; + std::vector imageSubs_; + std::vector cameraInfoSubs_; + std::vector cameraSyncs_; std::vector mapPubs_; tf::TransformBroadcaster tfBroadcaster_; ros::Publisher alivePub_; diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index e03e705c..e7fa6f79 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -12,7 +12,7 @@ #include // Pybind -#include // everything needed for embedding +#include // everything needed for embedding #include // ROS @@ -40,6 +40,7 @@ class ElevationMappingWrapper { public: using RowMatrixXd = Eigen::Matrix; using RowMatrixXf = Eigen::Matrix; + using ColMatrixXf = Eigen::Matrix; ElevationMappingWrapper(); @@ -47,6 +48,10 @@ class ElevationMappingWrapper { void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); + void input_image_mono(const RowMatrixXf& image, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, + const RowMatrixXd& cameraMatrix, int height, int width); + void input_image_rgb(const RowMatrixXf& image_r, const RowMatrixXf& image_g, const RowMatrixXf& image_b, + const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, int height, int width); void move_to(const Eigen::VectorXd& p, const RowMatrixXd& R); void clear(); void update_variance(); diff --git a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch index 023962f8..ca49e6e3 100644 --- a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch +++ b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch @@ -2,5 +2,6 @@ + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_image_mono_kernels.py similarity index 81% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/custom_image_mono_kernels.py index 88b5ddf2..3fcf28d6 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_semantic_image_kernerls.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_image_mono_kernels.py @@ -2,10 +2,10 @@ import string -def image_to_map_corrospondence_kernel(resolution, width, height, tolerance_z_collision): - image_to_map_corrospondence_kernel = cp.ElementwiseKernel( +def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_collision): + image_to_map_correspondence_kernel = cp.ElementwiseKernel( in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U image_height, raw U image_width, raw U center", - out_params="raw U uv_corrospondence, raw B vaild_corrospondence", + out_params="raw U uv_correspondence, raw B valid_correspondence", preamble=string.Template( """ __device__ int get_map_idx(int idx, int layer_n) { @@ -110,20 +110,20 @@ def image_to_map_corrospondence_kernel(resolution, width, height, tolerance_z_co } } - // mark the corrospondence - uv_corrospondence[get_map_idx(i, 0)] = u; - uv_corrospondence[get_map_idx(i, 1)] = v; - vaild_corrospondence[get_map_idx(i, 0)] = 1; + // mark the correspondence + uv_correspondence[get_map_idx(i, 0)] = u; + uv_correspondence[get_map_idx(i, 1)] = v; + valid_correspondence[get_map_idx(i, 0)] = 1; """ ).substitute(height=height, width=width, resolution=resolution, tolerance_z_collision=tolerance_z_collision), - name="image_to_map_corrospondence_kernel", + name="image_to_map_correspondence_kernel", ) - return image_to_map_corrospondence_kernel + return image_to_map_correspondence_kernel -def average_corrospondences_to_map_kernel(resolution, width, height): - average_corrospondences_to_map_kernel = cp.ElementwiseKernel( - in_params="raw U sem_map, raw U semantic_image, raw U uv_corrospondence, raw B vaild_corrospondence, raw U image_height, raw U image_width", +def average_correspondences_to_map_kernel(resolution, width, height): + average_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", out_params="raw U new_sem_map", preamble=string.Template( """ @@ -137,12 +137,12 @@ def average_corrospondences_to_map_kernel(resolution, width, height): """ int cell_idx = get_map_idx(i, 0); int cell_idx_2 = get_map_idx(i, 1); - if (vaild_corrospondence[cell_idx]){ - int idx = int(uv_corrospondence[cell_idx]) + int(uv_corrospondence[cell_idx_2]) * image_width; - new_sem_map[cell_idx] = semantic_image[idx]; + if (valid_correspondence[cell_idx]){ + int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + new_sem_map[cell_idx] = image_mono[idx]; } """ ).substitute(), - name="average_corrospondences_to_map_kernel", + name="average_correspondences_to_map_kernel", ) - return average_corrospondences_to_map_kernel + return average_correspondences_to_map_kernel diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index d6e8a38d..66e30943 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -19,8 +19,8 @@ from elevation_mapping_cupy.custom_kernels import normal_filter_kernel from elevation_mapping_cupy.custom_kernels import polygon_mask_kernel -from elevation_mapping_cupy.custom_semantic_image_kernerls import image_to_map_corrospondence_kernel -from elevation_mapping_cupy.custom_semantic_image_kernerls import average_corrospondences_to_map_kernel +from elevation_mapping_cupy.custom_image_mono_kernels import image_to_map_correspondence_kernel +from elevation_mapping_cupy.custom_image_mono_kernels import average_correspondences_to_map_kernel from elevation_mapping_cupy.map_initializer import MapInitializer @@ -93,7 +93,7 @@ def __init__(self, param: Parameter): self.additive_mean_error = 0.0 self.compile_kernels() - self.compile_semantic_image_kernels() + self.compile_image_mono_kernels() self.semantic_map.compile_kernels() weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') @@ -275,16 +275,16 @@ def compile_kernels(self): self.polygon_mask_kernel = polygon_mask_kernel(self.cell_n, self.cell_n, self.resolution) self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) - def compile_semantic_image_kernels(self): + def compile_image_mono_kernels(self): self.new_sem_map = cp.asarray(np.zeros((self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) - self.vaild_corrospondence = cp.asarray(np.zeros((self.cell_n, self.cell_n), dtype=np.bool), dtype=np.bool) - self.uv_corrospondence = cp.asarray(np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) + self.valid_correspondence = cp.asarray(np.zeros((self.cell_n, self.cell_n), dtype=np.bool), dtype=np.bool) + self.uv_correspondence = cp.asarray(np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) - self.image_to_map_corrospondence_kernel = image_to_map_corrospondence_kernel( + self.image_to_map_correspondence_kernel = image_to_map_correspondence_kernel( resolution=self.resolution, width=self.cell_n, height=self.cell_n, tolerance_z_collision=0.1 ) - self.average_corrospondences_to_map_kernel = average_corrospondences_to_map_kernel( + self.average_correspondences_to_map_kernel = average_correspondences_to_map_kernel( resolution=self.resolution, width=self.cell_n, height=self.cell_n ) @@ -374,26 +374,22 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori # calculate normal vectors self.update_normal(self.traversability_input) - def update_map_with_semantic_image_kernel(self, semantic_image, K, channels, R, t, image_height, image_width): + def update_map_with_image_mono_kernel(self, image_mono, K, channels, R, t, image_height, image_width): """Update map with new measurement from semantic image.""" P = cp.asarray(K @ np.concatenate([R, t[:, None]], 1), dtype=np.float32) - t_cam_map = -R.T @ t t_cam_map -= self.center.get() - x1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[0]) / self.resolution)) y1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[1]) / self.resolution)) z1 = cp.float32(t_cam_map[2]) - - semantic_image = cp.asarray(semantic_image, dtype=np.float32) + image_mono = cp.asarray(image_mono, dtype=np.float32) self.new_sem_map *= 0 - self.uv_corrospondence *= 0 - self.vaild_corrospondence[:, :] = False - + self.uv_correspondence *= 0 + self.valid_correspondence[:, :] = False with self.map_lock: sem_map_idx = self.semantic_map.get_index(channels[0]) - self.image_to_map_corrospondence_kernel( + self.image_to_map_correspondence_kernel( self.elevation_map, x1, y1, @@ -402,16 +398,16 @@ def update_map_with_semantic_image_kernel(self, semantic_image, K, channels, R, cp.float32(image_height), cp.float32(image_width), self.center, - self.uv_corrospondence, - self.vaild_corrospondence, + self.uv_correspondence, + self.valid_correspondence, size=int(self.elevation_map.shape[1] * self.elevation_map.shape[2]), ) - self.average_corrospondences_to_map_kernel( + self.average_correspondences_to_map_kernel( self.semantic_map.map[sem_map_idx], - semantic_image, - self.uv_corrospondence, - self.vaild_corrospondence, + image_mono, + self.uv_correspondence, + self.valid_correspondence, cp.float32(image_height), cp.float32(image_width), self.new_sem_map, @@ -483,17 +479,31 @@ def input( orientation_noise, ) - def input_semantic_image( + def input_image_mono( self, - semantic_image: cp._core.core.ndarray, + image_mono: cp._core.core.ndarray, + channels: List[str], + R: cp._core.core.ndarray, + t: cp._core.core.ndarray, K: cp._core.core.ndarray, + image_height: int, + image_width: int, + ): + self.update_map_with_image_mono_kernel(image_mono, K, channels, R, t, image_height, image_width) + + def input_image_rgb( + self, + image_r: cp._core.core.ndarray, + image_g: cp._core.core.ndarray, + image_b: cp._core.core.ndarray, channels: List[str], R: cp._core.core.ndarray, t: cp._core.core.ndarray, + K: cp._core.core.ndarray, image_height: int, image_width: int, ): - self.update_map_with_semantic_image_kernel(semantic_image, K, channels, R, t, image_height, image_width) + self.update_map_with_image_mono_kernel(image_r, K, channels, R, t, image_height, image_width) def update_normal(self, dilated_map): """Clear the normal map and then apply the normal kernel with dilated map as input. diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index 0b8904a2..c2b7842e 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -55,7 +55,7 @@ def __init__(self): self._last_t = None def setup_cv_bride(self): - if self.semantic_image_data: + if self.image_mono_data: self.cv_bridge = CvBridge() def initalize_elevation_mapping(self): @@ -77,10 +77,10 @@ def initalize_ros(self): def overwrite_elevation_mapping_params(self): additional = [] fusion = [] - self.semantic_image_data = False + self.image_mono_data = False for key, config in self.subscribers.items(): if config["type"] == "image": - self.semantic_image_data = True + self.image_mono_data = True for chan, fus in zip(config["channels"], config["fusion"]): if chan not in additional: additional.append(chan) @@ -195,7 +195,7 @@ def image_callback(self, camera_msg, camera_info_msg, config): assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) # process pointcloud - self._map.input_semantic_image(semantic_img, K, config[0], R, t, camera_info_msg.height, camera_info_msg.width) + self._map.input_image_mono(semantic_img, config[0], R, t, K, camera_info_msg.height, camera_info_msg.width) self._image_process_counter += 1 def pointcloud_callback(self, msg, config): diff --git a/elevation_mapping_cupy/src/elevation_mapping_node.cpp b/elevation_mapping_cupy/src/elevation_mapping_node.cpp index 47bef360..3d7a778f 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_node.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_node.cpp @@ -4,7 +4,7 @@ // // Pybind -#include // everything needed for embedding +#include // everything needed for embedding // ROS #include diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 236c04ea..e1dc560c 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -6,7 +6,7 @@ #include "elevation_mapping_cupy/elevation_mapping_ros.hpp" // Pybind -#include +#include // ROS #include @@ -38,8 +38,15 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) double recordableFps, updateVarianceFps, timeInterval, updatePoseFps, updateGridMapFps, publishStatisticsFps; bool enablePointCloudPublishing(false); + // Read parameters nh.getParam("subscribers", subscribers); nh.getParam("publishers", publishers); + if(!subscribers.valid()) { + ROS_FATAL("There aren't any subscribers to be configured, the elevation mapping cannot be configured. Exit"); + } + if(!publishers.valid()) { + ROS_FATAL("There aren't any publishers to be configured, the elevation mapping cannot be configured. Exit"); + } nh.param>("initialize_frame_id", initialize_frame_id_, {"base"}); nh.param>("initialize_tf_offset", initialize_tf_offset_, {0.0}); nh.param("pose_topic", pose_topic, "pose"); @@ -63,32 +70,57 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) enablePointCloudPublishing_ = enablePointCloudPublishing; + // Iterate all the subscribers std::vector additional_layers; std::vector fusion_algorithms; for (auto & subscriber : subscribers) { auto channels = subscriber.second["channels"]; auto fusion = subscriber.second["fusion"]; + auto type = static_cast(subscriber.second["type"]); + std::vector channels_str; + for (int32_t i = 0; i < channels.size(); ++i) { auto name = static_cast(channels[i]); + channels_str.push_back(name); if (!std::count(additional_layers.begin(), additional_layers.end(), name)){ additional_layers.push_back(name); fusion_algorithms.push_back(static_cast(fusion[i])); } } - std::string pointcloud_topic = subscriber.second["topic_name"]; - ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, &ElevationMappingNode::pointcloudCallback, this); - pointcloudSubs_.push_back(sub); + // Initialize subscribers depending on the type + if (type == "pointcloud") { + std::string pointcloud_topic = subscriber.second["topic_name"]; + ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, &ElevationMappingNode::pointcloudCallback, this); + pointcloudSubs_.push_back(sub); + + } else if (type == "image") { + std::string camera_topic = subscriber.second["topic_name_camera"]; + std::string info_topic = subscriber.second["topic_name_camera_info"]; + + ImageSubscriberPtr image_sub = std::make_shared(nh_, camera_topic, 1); + CameraInfoSubscriberPtr cam_info_sub = std::make_shared(nh_, info_topic, 1); + imageSubs_.push_back(image_sub); + cameraInfoSubs_.push_back(cam_info_sub); + + CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); + sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2, channels_str)); + cameraSyncs_.push_back(sync); + + } else { + ROS_WARN_STREAM("Subscriber type [" << type << "] Not valid. Supported types: pointcloud, image"); + continue; + } } for (int i = 0; i < additional_layers.size(); ++i){ - ROS_INFO_STREAM("Additional layers " << additional_layers.at(i)<<" fusion algorithm "<first; std::vector layers_list; std::vector basic_layers_list; @@ -111,15 +143,15 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) basic_layers_list.push_back(static_cast(basic_layers[i])); } - // make publishers + // Make publishers ros::Publisher pub = nh_.advertise(topic_name, 1); mapPubs_.push_back(pub); - // register map layers + // Register map layers map_layers_.push_back(layers_list); map_basic_layers_.push_back(basic_layers_list); - // register map fps + // Register map fps map_fps_.push_back(fps); map_fps_unique_.insert(fps); } @@ -163,15 +195,15 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) ROS_INFO("[ElevationMappingCupy] finish initialization"); } -// setup map publishers +// Setup map publishers void ElevationMappingNode::setupMapPublishers() { // Find the layers with highest fps. float max_fps = -1; - // create timers for each unique map frequencies + // Create timers for each unique map frequencies for (auto fps : map_fps_unique_) { - // which publisher to call in the timer callback + // Which publisher to call in the timer callback std::vector indices; - // if this fps is max, update the map layers. + // If this fps is max, update the map layers. if (fps >= max_fps) { max_fps = fps; map_layers_all_.clear(); @@ -179,7 +211,7 @@ void ElevationMappingNode::setupMapPublishers() { for (int i = 0; i < map_fps_.size(); i++) { if (map_fps_[i] == fps) { indices.push_back(i); - // if this fps is max, add layers + // If this fps is max, add layers if (fps >= max_fps) { for (const auto layer : map_layers_[i]) { map_layers_all_.insert(layer); @@ -187,7 +219,7 @@ void ElevationMappingNode::setupMapPublishers() { } } } - // callback funtion. + // Callback funtion. // It publishes to specific topics. auto cb = [this, indices](const ros::TimerEvent&) { for (int i : indices) { @@ -293,6 +325,58 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl pointCloudProcessCounter_++; } +void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::vector& channels) { + auto start = ros::Time::now(); + + // Get image + cv::Mat image = cv_bridge::toCvShare(image_msg, image_msg->encoding)->image; + + // Extract camera matrix + Eigen::Map> cameraMatrix(&camera_info_msg->K[0]); + + // Get pose of sensor in map frame + tf::StampedTransform transformTf; + std::string sensorFrameId = image_msg->header.frame_id; + auto timeStamp = image_msg->header.stamp; + Eigen::Affine3d transformationSensorToMap; + try { + transformListener_.waitForTransform(mapFrameId_, sensorFrameId, timeStamp, ros::Duration(1.0)); + transformListener_.lookupTransform(mapFrameId_, sensorFrameId, timeStamp, transformTf); + poseTFToEigen(transformTf, transformationSensorToMap); + } catch (tf::TransformException& ex) { + ROS_ERROR("%s", ex.what()); + return; + } + + + // Transform to Eigen matrix and input to pipeline + if (image.channels() == 1) { + ColMatrixXf eigen_image; + cv::cv2eigen(image, eigen_image); + // std::vector channels{"mono"}; + + map_.input_image_mono(eigen_image, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), cameraMatrix, image.rows, image.cols); + + } else if (image.channels() == 3) { + cv::Mat bgr[3]; + cv::split(image, bgr); + ColMatrixXf eigen_image_b; + cv::cv2eigen(bgr[0], eigen_image_b); + ColMatrixXf eigen_image_g; + cv::cv2eigen(bgr[1], eigen_image_g); + ColMatrixXf eigen_image_r; + cv::cv2eigen(bgr[2], eigen_image_r); + // std::vector channels{"r", "g", "b"}; + + map_.input_image_rgb(eigen_image_r, eigen_image_g, eigen_image_b, channels, + transformationSensorToMap.rotation(), transformationSensorToMap.translation(), cameraMatrix, image.rows, image.cols); + } else { + ROS_WARN_STREAM("Invalid number of channels [" << image.channels() << "]. Only allowed 1 (mono) or 3 (rgb)"); + } + + ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); +} + void ElevationMappingNode::updatePose(const ros::TimerEvent&) { tf::StampedTransform transformTf; const auto& timeStamp = ros::Time::now(); diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index a518117b..5774729c 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -6,7 +6,7 @@ #include "elevation_mapping_cupy/elevation_mapping_wrapper.hpp" // Pybind -#include +#include // PCL #include @@ -34,7 +34,7 @@ void ElevationMappingWrapper::initialize(ros::NodeHandle& nh, std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise) { py::gil_scoped_acquire acquire; - map_.attr("input")(Eigen::Ref(points),channels, Eigen::Ref(R), Eigen::Ref(t), + map_.attr("input")(Eigen::Ref(points), channels, Eigen::Ref(R), Eigen::Ref(t), positionNoise, orientationNoise); } +void ElevationMappingWrapper::input_image_mono(const RowMatrixXf& image, + const std::vector& channels, + const RowMatrixXd& R, + const Eigen::VectorXd& t, + const RowMatrixXd& cameraMatrix, + int height, + int width) { + py::gil_scoped_acquire acquire; + map_.attr("input_image_mono")(Eigen::Ref(image), + channels, + Eigen::Ref(R), + Eigen::Ref(t), + Eigen::Ref(cameraMatrix), + height, + width); +} + +void ElevationMappingWrapper::input_image_rgb(const RowMatrixXf& image_r, + const RowMatrixXf& image_g, + const RowMatrixXf& image_b, + const std::vector& channels, + const RowMatrixXd& R, + const Eigen::VectorXd& t, + const RowMatrixXd& cameraMatrix, + int height, + int width) { + py::gil_scoped_acquire acquire; + map_.attr("input_image_rgb")(Eigen::Ref(image_r), + Eigen::Ref(image_g), + Eigen::Ref(image_b), + channels, + Eigen::Ref(R), + Eigen::Ref(t), + Eigen::Ref(cameraMatrix), + height, + width); +} + void ElevationMappingWrapper::move_to(const Eigen::VectorXd& p, const RowMatrixXd& R) { py::gil_scoped_acquire acquire; map_.attr("move_to")(Eigen::Ref(p), Eigen::Ref(R)); From 11b0f5a5f08b0e4295eff2f0a11a011be628d56c Mon Sep 17 00:00:00 2001 From: Matias Mattamala Date: Mon, 5 Dec 2022 17:44:41 +0000 Subject: [PATCH 277/504] Simplify input image interface --- .../elevation_mapping_wrapper.hpp | 4 +- ...ono_kernels.py => custom_image_kernels.py} | 0 .../elevation_mapping.py | 46 ++++++++----------- .../src/elevation_mapping_ros.cpp | 18 ++++---- .../src/elevation_mapping_wrapper.cpp | 37 ++++----------- 5 files changed, 39 insertions(+), 66 deletions(-) rename elevation_mapping_cupy/script/elevation_mapping_cupy/{custom_image_mono_kernels.py => custom_image_kernels.py} (100%) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index e7fa6f79..4c4e93f7 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -48,10 +48,8 @@ class ElevationMappingWrapper { void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); - void input_image_mono(const RowMatrixXf& image, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, + void input_image(const std::vector& image, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, int height, int width); - void input_image_rgb(const RowMatrixXf& image_r, const RowMatrixXf& image_g, const RowMatrixXf& image_b, - const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, int height, int width); void move_to(const Eigen::VectorXd& p, const RowMatrixXd& R); void clear(); void update_variance(); diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_image_mono_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_image_kernels.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/custom_image_mono_kernels.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/custom_image_kernels.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 66e30943..62480005 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -19,8 +19,8 @@ from elevation_mapping_cupy.custom_kernels import normal_filter_kernel from elevation_mapping_cupy.custom_kernels import polygon_mask_kernel -from elevation_mapping_cupy.custom_image_mono_kernels import image_to_map_correspondence_kernel -from elevation_mapping_cupy.custom_image_mono_kernels import average_correspondences_to_map_kernel +from elevation_mapping_cupy.custom_image_kernels import image_to_map_correspondence_kernel +from elevation_mapping_cupy.custom_image_kernels import average_correspondences_to_map_kernel from elevation_mapping_cupy.map_initializer import MapInitializer @@ -93,7 +93,7 @@ def __init__(self, param: Parameter): self.additive_mean_error = 0.0 self.compile_kernels() - self.compile_image_mono_kernels() + self.compile_image_kernels() self.semantic_map.compile_kernels() weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') @@ -275,7 +275,7 @@ def compile_kernels(self): self.polygon_mask_kernel = polygon_mask_kernel(self.cell_n, self.cell_n, self.resolution) self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) - def compile_image_mono_kernels(self): + def compile_image_kernels(self): self.new_sem_map = cp.asarray(np.zeros((self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) self.valid_correspondence = cp.asarray(np.zeros((self.cell_n, self.cell_n), dtype=np.bool), dtype=np.bool) self.uv_correspondence = cp.asarray(np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) @@ -374,15 +374,16 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori # calculate normal vectors self.update_normal(self.traversability_input) - def update_map_with_image_mono_kernel(self, image_mono, K, channels, R, t, image_height, image_width): + def update_map_with_image_kernel(self, image, K, channels, R, t, image_height, image_width): """Update map with new measurement from semantic image.""" P = cp.asarray(K @ np.concatenate([R, t[:, None]], 1), dtype=np.float32) - t_cam_map = -R.T @ t - t_cam_map -= self.center.get() + t_cam_map = -R.T @ t - self.center + t_cam_map = t_cam_map.get() x1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[0]) / self.resolution)) y1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[1]) / self.resolution)) z1 = cp.float32(t_cam_map[2]) - image_mono = cp.asarray(image_mono, dtype=np.float32) + + image = cp.asarray(image, dtype=np.float32) self.new_sem_map *= 0 self.uv_correspondence *= 0 @@ -405,7 +406,7 @@ def update_map_with_image_mono_kernel(self, image_mono, K, channels, R, t, image self.average_correspondences_to_map_kernel( self.semantic_map.map[sem_map_idx], - image_mono, + image, self.uv_correspondence, self.valid_correspondence, cp.float32(image_height), @@ -479,23 +480,9 @@ def input( orientation_noise, ) - def input_image_mono( - self, - image_mono: cp._core.core.ndarray, - channels: List[str], - R: cp._core.core.ndarray, - t: cp._core.core.ndarray, - K: cp._core.core.ndarray, - image_height: int, - image_width: int, - ): - self.update_map_with_image_mono_kernel(image_mono, K, channels, R, t, image_height, image_width) - - def input_image_rgb( + def input_image( self, - image_r: cp._core.core.ndarray, - image_g: cp._core.core.ndarray, - image_b: cp._core.core.ndarray, + image: cp._core.core.ndarray, channels: List[str], R: cp._core.core.ndarray, t: cp._core.core.ndarray, @@ -503,7 +490,14 @@ def input_image_rgb( image_height: int, image_width: int, ): - self.update_map_with_image_mono_kernel(image_r, K, channels, R, t, image_height, image_width) + image = np.stack(image, axis=0) + self.update_map_with_image_kernel(cp.asarray(image, dtype=self.data_type), + cp.asarray(K, dtype=self.data_type), + channels, + cp.asarray(R, dtype=self.data_type), + cp.asarray(t, dtype=self.data_type), + image_height, + image_width) def update_normal(self, dilated_map): """Clear the normal map and then apply the normal kernel with dilated map as input. diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index e1dc560c..297be4f7 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -348,14 +348,12 @@ void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image return; } - - // Transform to Eigen matrix and input to pipeline + // Transform to vector of Eigen matrices + std::vector multichannel_image; if (image.channels() == 1) { ColMatrixXf eigen_image; cv::cv2eigen(image, eigen_image); - // std::vector channels{"mono"}; - - map_.input_image_mono(eigen_image, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), cameraMatrix, image.rows, image.cols); + multichannel_image.push_back(eigen_image); } else if (image.channels() == 3) { cv::Mat bgr[3]; @@ -366,14 +364,18 @@ void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image cv::cv2eigen(bgr[1], eigen_image_g); ColMatrixXf eigen_image_r; cv::cv2eigen(bgr[2], eigen_image_r); - // std::vector channels{"r", "g", "b"}; - map_.input_image_rgb(eigen_image_r, eigen_image_g, eigen_image_b, channels, - transformationSensorToMap.rotation(), transformationSensorToMap.translation(), cameraMatrix, image.rows, image.cols); + multichannel_image.push_back(eigen_image_r); + multichannel_image.push_back(eigen_image_g); + multichannel_image.push_back(eigen_image_b); + } else { ROS_WARN_STREAM("Invalid number of channels [" << image.channels() << "]. Only allowed 1 (mono) or 3 (rgb)"); } + // Pass image to pipeline + map_.input_image(multichannel_image, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), cameraMatrix, image.rows, image.cols); + ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); } diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 5774729c..2b11d52c 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -97,7 +97,7 @@ void ElevationMappingWrapper::input(const RowMatrixXd& points, const std::vector positionNoise, orientationNoise); } -void ElevationMappingWrapper::input_image_mono(const RowMatrixXf& image, +void ElevationMappingWrapper::input_image(const std::vector& multichannel_image, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, @@ -105,34 +105,13 @@ void ElevationMappingWrapper::input_image_mono(const RowMatrixXf& image, int height, int width) { py::gil_scoped_acquire acquire; - map_.attr("input_image_mono")(Eigen::Ref(image), - channels, - Eigen::Ref(R), - Eigen::Ref(t), - Eigen::Ref(cameraMatrix), - height, - width); -} - -void ElevationMappingWrapper::input_image_rgb(const RowMatrixXf& image_r, - const RowMatrixXf& image_g, - const RowMatrixXf& image_b, - const std::vector& channels, - const RowMatrixXd& R, - const Eigen::VectorXd& t, - const RowMatrixXd& cameraMatrix, - int height, - int width) { - py::gil_scoped_acquire acquire; - map_.attr("input_image_rgb")(Eigen::Ref(image_r), - Eigen::Ref(image_g), - Eigen::Ref(image_b), - channels, - Eigen::Ref(R), - Eigen::Ref(t), - Eigen::Ref(cameraMatrix), - height, - width); + map_.attr("input_image")(multichannel_image, + channels, + Eigen::Ref(R), + Eigen::Ref(t), + Eigen::Ref(cameraMatrix), + height, + width); } void ElevationMappingWrapper::move_to(const Eigen::VectorXd& p, const RowMatrixXd& R) { From db613a4fab317dadf7be7af8b6c9acef5aa0788c Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Tue, 6 Dec 2022 10:28:41 +0100 Subject: [PATCH 278/504] max working but only with one max for the moment --- .../elevation_mapping_cupy/custom_kernels.py | 43 ++++++++- .../plugins/semantic_filter.py | 25 +++-- .../elevation_mapping_cupy/semantic_map.py | 83 ++++++++++++++++- .../tests/test_elevation_mapping.py | 24 ++++- .../tests/test_plugins.py | 2 + .../tests/test_semantic_map.py | 1 + .../semantic_pointcloud/pointcloud_node.py | 51 ++++++++-- .../pointcloud_parameters.py | 4 +- .../tests/test_pointcloud.py | 16 ++++ .../script/semantic_pointcloud/utils.py | 92 ++++++++++++++----- 10 files changed, 296 insertions(+), 45 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py index 66406271..c4a64718 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py @@ -731,6 +731,47 @@ def sum_compact_kernel( ) return sum_compact_kernel + +def sum_max_kernel( + resolution, + width, + height, + ): + # input the list of layers, amount of channels can slo be input through kernel + sum_max_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U max_pt, raw T max_id, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params=" raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution,width=width, height=height), + operation=string.Template( + """ + U idx = p[i * pcl_channels[0]]; + U valid = p[i * pcl_channels[0] + 1]; + U inside = p[i * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + // for every max value + for ( W it=0;it cp.ndarray: # get indices of all layers that layer_indices = cp.array([], dtype=cp.int32) + max_idcs = cp.array([], dtype=cp.int32) for it, fusion_alg in enumerate(semantic_map.param.fusion_algorithms): - if (fusion_alg in ["class_bayesian","class_average"]): + if fusion_alg in ["class_bayesian", "class_average"]: layer_indices = cp.append(layer_indices, it).astype(cp.int32) + if fusion_alg in ["class_max"]: + max_idcs = cp.append(max_idcs, it).astype(cp.int32) # check which has the highest value - class_map = cp.argmax(semantic_map.map[layer_indices], axis=0) + # todo we are using the new_map because of the bayesian + class_map = cp.amax(semantic_map.new_map[layer_indices], axis=0) + class_map_id = cp.argmax(semantic_map.map[layer_indices], axis=0) + + if "class_max" in semantic_map.param.fusion_algorithms: + # todo here is only cosideredx the case where we only have one max + max_map = cp.amax(semantic_map.new_map[max_idcs], axis=0) + max_map_id = semantic_map.unique_id[semantic_map.id_max[max_idcs]] + map = cp.where(max_map > class_map, max_map_id, class_map_id) + else: + map = class_map # create color coding - enc = self.color_encoding[class_map] + enc = self.color_encoding[map] return enc diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 104a4f25..3919b5a8 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -11,6 +11,7 @@ alpha_kernel, bayesian_inference_kernel, sum_compact_kernel, + sum_max_kernel, ) xp = cp @@ -113,6 +114,19 @@ def compile_kernels(self) -> None: self.param.cell_n, self.param.cell_n, ) + if "class_max" in self.unique_fusion: + print("Initialize class max kernel") + self.sum_max_kernel = sum_max_kernel( + self.param.resolution, + self.param.cell_n, + self.param.cell_n, + ) + layer_cnt = self.param.fusion_algorithms.count("class_max") + self.id_max = cp.zeros( + (layer_cnt, self.param.cell_n, self.param.cell_n), + dtype=np.uint32, + ) + self.unique_id = cp.array([0]) def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: """Get all fusion algorithms that need to be applied to a specific pointcloud @@ -128,11 +142,11 @@ def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: return fusion_list def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): - """Computes the indices that are used for the additional kernel update of the popintcloud and the semantic map. + """Computes the indices of the channels of the pointcloud and the layers of the semantic map of type fusion_alg. Args: - pcl_channels (List[str]): - fusion_alg (str): + pcl_channels (List[str]): list of all channel names + fusion_alg (str): fusion algorithm type we want to use for channel selection Returns: Union[Tuple[List[int], List[int]], Tuple[cupy._core.core.ndarray, cupy._core.core.ndarray]]: @@ -238,10 +252,64 @@ def update_layers(self, points_all, channels, R, t, elevation_map): ) # calculate new thetas sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) + sum_alpha[sum_alpha == 0] = 1 self.map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims( sum_alpha, axis=0 ) # assert cp.unique(cp.sum(self.map[layer_ids], axis=0)) equal to zero or to nan + if "class_max" in additional_fusion: + # get indices that are of type class_max in pointclopud and in layers + pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_max") + # decode float32 into to float16 + max_pt, pt_id = self.decode_max(points_all[:, pcl_ids]) + # find unique ids in new measurement and in map + unique_idm = cp.unique(pt_id) + unique_ida = cp.unique(self.unique_id[self.id_max]) + # get all unique ids, where index is the position in the prob_Sum and the value + # the value in the NN class + self.unique_id = cp.unique(cp.concatenate((unique_idm, unique_ida))) + # contains the sum of the new measurement probabilities + self.prob_sum = cp.zeros( + (len(self.unique_id), self.param.cell_n, self.param.cell_n), + dtype=np.float32, + ) + # transform the index matrix of the classes to the index matrix of the prob_sum + pt_id_zero = pt_id.copy() + for it, val in enumerate(self.unique_id): + pt_id_zero[pt_id_zero == val] = it + + # sum all measurements probabilities + self.sum_max_kernel( + points_all, + max_pt, + pt_id_zero, + pcl_ids, + layer_ids, + cp.array( + [points_all.shape[1], pcl_ids.shape[0], pt_id.shape[1]], + dtype=np.int32, + ), + self.prob_sum, + size=(points_all.shape[0]), + ) + # add the previous alpha + for i, lay in enumerate(layer_ids): + # todo add residual of prev alpha to the prob_sum + c = cp.mgrid[0: self.new_map.shape[1], 0: self.new_map.shape[2]] + self.prob_sum[self.id_max[i], c[0], c[1]] = self.new_map[lay] + + # find the alpha we want to keep + for i, lay in enumerate(layer_ids): + self.new_map[lay] = cp.amax(self.prob_sum, axis=0) + self.id_max[i] = cp.argmax(self.prob_sum, axis=0) + self.prob_sum[cp.argmax(self.prob_sum, axis=0)] = 0 + # + # update map calculate new thetas + sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) + sum_alpha[sum_alpha==0]=1 + self.map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims( + sum_alpha, axis=0 + ) if "color" in additional_fusion: pcl_ids, layer_ids = self.get_indices_fusion(channels, "color") @@ -271,6 +339,15 @@ def update_layers(self, points_all, channels, R, t, elevation_map): size=(self.param.cell_n * self.param.cell_n), ) + def decode_max(self, mer): + mer = mer.astype(cp.float32) + mer = mer.view(dtype=cp.uint32) + ma = cp.bitwise_and(mer, 0xFFFF, dtype=np.uint16) + ma = ma.view(np.float16) + ma = ma.astype(np.float32) + ind = cp.right_shift(mer, 16) + return ma, ind + def get_map_with_name(self, name): if self.layer_specs[name] == "color": m = self.get_rgb(name) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py index 71559122..45d22609 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -4,6 +4,20 @@ import numpy as np +def encode_max(maxim, index): + maxim, index = cp.asarray(maxim, dtype=cp.float32), cp.asarray( + index, dtype=cp.uint32 + ) + # fuse them + maxim = maxim.astype(cp.float16) + maxim = maxim.view(cp.uint16) + maxim = maxim.astype(cp.uint32) + index = index.astype(cp.uint32) + mer = cp.array(cp.left_shift(index, 16) | maxim, dtype=cp.uint32) + mer = mer.view(cp.float32) + return mer + + @pytest.fixture() def elmap_ex(add_lay, fusion_alg): additional_layer = add_lay @@ -27,6 +41,7 @@ def elmap_ex(add_lay, fusion_alg): (["feat_0", "feat_1"], ["average", "average"]), (["feat_0", "feat_1"], ["class_average", "class_average"]), (["feat_0", "feat_1"], ["class_bayesian", "class_bayesian"]), + (["feat_0", "feat_1"], ["class_bayesian", "class_max"]), (["feat_0", "feat_1"], ["bayesian_inference", "bayesian_inference"]), ], ) @@ -37,7 +52,14 @@ def test_init(self, elmap_ex): def test_input(self, elmap_ex): channels = ["x", "y", "z"] + elmap_ex.param.additional_layers - points = cp.random.rand(100000, len(channels), dtype=elmap_ex.param.data_type) + if "class_max" in elmap_ex.param.fusion_algorithms: + val = cp.random.rand(100000, len(channels), dtype=cp.float32).astype(cp.float16) + ind = cp.random.randint(0, 2, (100000, len(channels)), dtype=cp.uint32).astype(cp.float32) + points = encode_max(val, ind) + else: + points = cp.random.rand( + 100000, len(channels), dtype=elmap_ex.param.data_type + ) R = cp.random.rand(3, 3, dtype=elmap_ex.param.data_type) t = cp.random.rand(3, dtype=elmap_ex.param.data_type) elmap_ex.input(points, channels, R, t, 0, 0) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py index 180aa9d5..4e02734e 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -22,6 +22,7 @@ def semmap_ex(add_lay, fusion_alg): p.cell_n = int(round(p.map_length / p.resolution)) + 2 e = semantic_map.SemanticMap(p, additional_layers) + e.compile_kernels() return e @@ -30,6 +31,7 @@ def semmap_ex(add_lay, fusion_alg): [ (['grass','tree','fence','person'], ["class_average", "class_average", "class_average", "class_average"], ["grass"]), (['grass','tree'], ["class_average", "class_average"], ['grass']), + (['grass','tree'], ["class_average", "class_max"], ['tree']), # ( # ["feat_0", "feat_1", "rgb"], # ["average", "average", "color"], diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py index 86eba134..ae94e068 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py @@ -29,6 +29,7 @@ def semmap_ex(add_lay, fusion_alg): (["feat_0", "feat_1", "rgb"], ["class_average", "average", "color"], ["rgb", "feat_0"]), (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0"]), (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0", "feat_1"]), + (["feat_0", "feat_1", "rgb"], ["class_bayesian", "class_max", "color"], ["rgb", "feat_0", "feat_1"]), ], ) def test_fusion_of_pcl(semmap_ex, channels): diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index 4e4c0472..12c15042 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -13,7 +13,7 @@ from cv_bridge import CvBridge from semantic_pointcloud.pointcloud_parameters import PointcloudParameter -from semantic_pointcloud.utils import resolve_model +from semantic_pointcloud.utils import resolve_model, decode_max class PointcloudNode: @@ -73,7 +73,10 @@ def __init__(self, sensor_name): self.seg_pub = rospy.Publisher( self.param.segmentation_image_topic, Image, queue_size=2 ) - self.labels = list(self.segmentation_channels.keys()) + if "class_max" in self.param.fusion: + self.labels = self.semantic_model["model"].get_classes() + else: + self.labels = list(self.segmentation_channels.keys()) self.semseg_color_map = self.color_map(len(self.labels)) self.color_map_viz() @@ -115,8 +118,16 @@ def color_map_viz(self): def initialize_semantics(self): if self.param.semantic_segmentation: - self.semantic_model = resolve_model(self.param.segmentation_model, self.param) - self.segmentation_channels = self.semantic_model["model"].segmentation_channels + self.semantic_model = resolve_model( + self.param.segmentation_model, self.param + ) + # todo (done) rewrite the segmenation channel such that keys are channels of seg and values are the fusion + self.segmentation_channels = {} + for i, (chan, fus) in enumerate( + zip(self.param.channels, self.param.fusion) + ): + if fus in ["class_bayesian", "class_average", "class_max"]: + self.segmentation_channels[chan] = fus if self.param.feature_extractor: self.feature_channels = [] for i, fusion in enumerate(self.param.fusion): @@ -133,7 +144,7 @@ def create_custom_dtype(self): ("y", np.float32), ("z", np.float32), ] - for chan in self.param.channels: + for chan, fus in zip(self.param.channels, self.param.fusion): self.dtype.append((chan, np.float32)) print(self.dtype) @@ -218,7 +229,7 @@ def process_image(self, image, u, v, points): def perform_segmentation(self, image, points, u, v): prediction = self.semantic_model["model"](image) - values = prediction[:, v.get(), u.get()].get()#.cpu().detach().numpy() + values = prediction[:, v.get(), u.get()].get() for it, channel in enumerate(self.segmentation_channels.keys()): points[channel] = values[it] if self.param.publish_segmentation_image: @@ -231,10 +242,34 @@ def extract_features(self, image, points, u, v): points[channel] = values[it] def publish_segmentation_image(self, probabilities): - probabilities = cp.asarray(probabilities.get())# cpu().detach().numpy()) colors = cp.asarray(self.semseg_color_map) assert colors.ndim == 2 and colors.shape[1] == 3 - img = cp.argmax(probabilities, axis=0) + # img = 0 + prob = cp.zeros((len(self.labels),) + probabilities.shape[1:]) + if "class_max" in self.param.fusion: + # decode, create an array with all possible classes and insert probabilities + it = 0 + for iit, (chan, fuse) in enumerate( + zip(self.param.channels, self.param.fusion) + ): + if fuse == "class_max": + temp = probabilities[it] + temp_p, temp_i = decode_max(temp) + temp_i.choose(prob) + c = cp.mgrid[0 : temp_i.shape[0], 0 : temp_i.shape[1]] + prob[temp_i, c[0], c[1]] = temp_p + it += 1 + elif fuse in ["class_bayesian", "class_average"]: + # assign fixed probability to correct index + if chan in self.semantic_model["model"].segmentation_channels: + prob[ + self.semantic_model["model"].segmentation_channels[chan] + ] = probabilities[it] + it += 1 + img = cp.argmax(prob, axis=0) + + else: + img = cp.argmax(probabilities, axis=0) img = colors[img].astype(cp.uint8) # N x H x W x 3 img = img.get() seg_msg = self.cv_bridge.cv2_to_imgmsg(img, encoding="rgb8") diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py index 0d3c035a..b08e4d1d 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py @@ -20,8 +20,8 @@ class FeatureExtractorParameter(Serializable): class PointcloudParameter(Serializable): sensor_name: str = "camera" topic_name: str = "/elvation_mapping/pointcloud_semantic" - channels: list = field(default_factory=lambda: ["rgb", "person", "grass", "tree"]) - fusion: list = field(default_factory=lambda: ["color", "class_average", "class_average", "class_average"]) + channels: list = field(default_factory=lambda: ["rgb", "person", "grass", "tree","max"]) + fusion: list = field(default_factory=lambda: ["color", "class_average", "class_average", "class_average","class_max"]) semantic_segmentation: bool = True segmentation_model: str = "detectron_coco_panoptic_fpn_R_101_3x" diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py index ee5dcf4e..8ed1bfd4 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py @@ -1,5 +1,6 @@ import pytest from ..pointcloud_node import PointcloudNode +import cupy as cp @pytest.fixture() @@ -16,3 +17,18 @@ def pointcloud_ex(cam_name): ) def test_initialize_semantics(pointcloud_ex): pointcloud_ex.initialize_semantics() + + +@pytest.mark.parametrize( + "cam_name", + [ + "front_cam", + ], +) +def test_pub_seg(pointcloud_ex): + # TODO we have to encode the max class other wise it is going to make problem + amount = len( + pointcloud_ex.segmentation_channels.keys() + ) + pointcloud_ex.param.fusion.count("max_class")+1 + prob = cp.random.rand(amount, 360, 640) + pointcloud_ex.publish_segmentation_image(prob) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py index b0e703f6..740bbaea 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py @@ -32,9 +32,31 @@ ) # from .pointcloud_parameters import PointcloudParameter, FeatureExtractorParameter - - -def resolve_model(name, config = None): +def encode_max(maxim, index): + maxim, index = cp.asarray(maxim, dtype=cp.float32), cp.asarray( + index, dtype=cp.uint32 + ) + # fuse them + maxim = maxim.astype(cp.float16) + maxim = maxim.view(cp.uint16) + maxim = maxim.astype(cp.uint32) + index = index.astype(cp.uint32) + mer = cp.array(cp.left_shift(index, 16) | maxim, dtype=cp.uint32) + mer = mer.view(cp.float32) + return mer + + +def decode_max(mer): + mer = mer.astype(cp.float32) + mer = mer.view(dtype=cp.uint32) + ma = cp.bitwise_and(mer, 0xFFFF, dtype=np.uint16) + ma = ma.view(np.float16) + ma = ma.astype(np.float32) + ind = cp.right_shift(mer, 16) + return ma, ind + + +def resolve_model(name, config=None): """Get the model class based on the name of the pretrained model. Args: @@ -93,10 +115,7 @@ def __init__(self, net, weights, param): self.resolve_cateories() def resolve_cateories(self): - class_to_idx = { - cls: idx - for (idx, cls) in enumerate(self.get_classes()) - } + class_to_idx = {cls: idx for (idx, cls) in enumerate(self.get_classes())} print( "Semantic Segmentation possible channels: ", self.get_classes(), @@ -109,10 +128,16 @@ def resolve_cateories(self): channels.append(chan) elif self.param.fusion[it] in ["class_average", "class_bayesian"]: print(chan, " is not in the semantic segmentation model.") + # for argamax + for it, chan in enumerate(self.param.channels): + if chan in [cls for cls in list(class_to_idx.keys())]: + indices.append(class_to_idx[chan]) + channels.append(chan) + elif self.param.fusion[it] in ["class_max"]: + print(chan, " is not in the semantic segmentation model.") self.stuff_categories = dict(zip(channels, indices)) self.segmentation_channels = self.stuff_categories - def __call__(self, image, *args, **kwargs): """Feewforward image through model. @@ -126,10 +151,25 @@ def __call__(self, image, *args, **kwargs): """ batch = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) batch = TF.convert_image_dtype(batch, torch.float32) - prediction = self.model(batch)["out"] - normalized_masks = torch.squeeze(prediction.softmax(dim=1), dim=0) - selected_masks = normalized_masks[list(self.stuff_categories.values())] - return selected_masks + with torch.no_grad(): + prediction = self.model(batch)["out"] + normalized_masks = torch.squeeze(prediction.softmax(dim=1), dim=0) + # get masks of fix classes + selected_masks = cp.asarray( + normalized_masks[list(self.stuff_categories.values())] + ) + + # get values of max, first remove the ones we already have + normalized_masks[list(self.stuff_categories.values())] = 0 + for i in range(self.param.fusion.count("class_max")): + maxim, index = torch.max(normalized_masks, dim=0) + mer = encode_max(maxim, index) + selected_masks = cp.concatenate( + (selected_masks, cp.expand_dims(mer, axis=0)), axis=0 + ) + # TODO set to zero the max + # normalized_masks[index] = 0 + return cp.asarray(selected_masks) def get_classes(self): """Get list of strings containing all the classes. @@ -152,7 +192,7 @@ def __init__(self, weights, param): self.cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(weights) self.predictor = DefaultPredictor(self.cfg) self.meta = MetadataCatalog.get(self.cfg.DATASETS.TRAIN[0]) - self.stuff_categories, self.is_stuff =self.resolve_cateories("stuff_classes") + self.stuff_categories, self.is_stuff = self.resolve_cateories("stuff_classes") self.thing_categories, self.is_thing = self.resolve_cateories("thing_classes") self.segmentation_channels = {} for chan in self.param.channels: @@ -166,10 +206,7 @@ def __init__(self, weights, param): def resolve_cateories(self, name): classes = self.get_cat(name) - class_to_idx = { - cls: idx - for (idx, cls) in enumerate(classes) - } + class_to_idx = {cls: idx for (idx, cls) in enumerate(classes)} print( "Semantic Segmentation possible channels: ", classes, @@ -194,14 +231,22 @@ def __call__(self, image, *args, **kwargs): image = cp.flip(image, axis=2) prediction = self.predictor(image.get()) probabilities = cp.asarray(torch.softmax(prediction["sem_seg"], dim=0)) - output = cp.zeros((len(self.segmentation_channels), probabilities.shape[1], probabilities.shape[2])) + output = cp.zeros( + ( + len(self.segmentation_channels), + probabilities.shape[1], + probabilities.shape[2], + ) + ) # add semseg - output[cp.array(list(self.is_stuff.values()))] = probabilities[list(self.stuff_categories.values())] + output[cp.array(list(self.is_stuff.values()))] = probabilities[ + list(self.stuff_categories.values()) + ] # add instances indices, insta_info = prediction["panoptic_seg"] # TODO dont know why i need temp, look into how to avoid temp = output[cp.array(list(self.is_thing.values()))] - for i,insta in enumerate(insta_info): + for i, insta in enumerate(insta_info): if insta is None or not insta["isthing"]: continue mask = cp.asarray((indices == insta["id"]).int()) @@ -210,12 +255,11 @@ def __call__(self, image, *args, **kwargs): output[cp.array(list(self.is_thing.values()))] = temp return output - - def get_cat(self,name): + def get_cat(self, name): return self.meta.get(name) - + def get_classes(self): - return self.get_cat("thing_classes")+self.get_cat("stuff_classes") + return self.get_cat("thing_classes") + self.get_cat("stuff_classes") class STEGOModel: From d0e5f5e5ac82bbc1509de0aa6f848eb452cdb33e Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Tue, 6 Dec 2022 14:26:46 +0100 Subject: [PATCH 279/504] working semantic filter, the pointcloud is fully working but the elevation map has still some work to do for the fusion and the filter onlyworks for one max class, all test should work --- .../elevation_mapping_cupy/custom_kernels.py | 5 +- .../elevation_mapping_cupy/parameter.py | 1 + .../plugins/semantic_filter.py | 4 +- .../elevation_mapping_cupy/semantic_map.py | 14 +++-- .../tests/test_semantic_map.py | 52 ++++++++++++++----- .../semantic_pointcloud/pointcloud_node.py | 28 ++++++---- .../pointcloud_parameters.py | 22 ++++++-- .../tests/test_pointcloud.py | 13 +++-- .../script/semantic_pointcloud/utils.py | 12 +++-- 9 files changed, 106 insertions(+), 45 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py index c4a64718..4bed4902 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py @@ -889,6 +889,7 @@ def bayesian_inference_kernel( def class_average_kernel( width, height, + alpha, ): class_average_kernel = cp.ElementwiseKernel( in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", @@ -912,13 +913,13 @@ def class_average_kernel( map[get_map_idx(i, map_lay[it])] = val; } else{ - U val = prev_val /2 + newmap[get_map_idx(i, map_lay[it])]/(2*cnt); + U val = ${alpha} *prev_val + ${alpha} * newmap[get_map_idx(i, map_lay[it])]/(cnt); map[get_map_idx(i, map_lay[it])] = val; } } } """ - ).substitute( + ).substitute(alpha=alpha, ), name="class_average_kernel", ) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 296adc23..960eeea6 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -15,6 +15,7 @@ class Parameter(Serializable): fusion_algorithms: list = ['average'].copy cell_n: int = None data_type: str = np.float32 + average_weight: float = 0.5 map_length: float = 8.0 sensor_noise_factor: float = 0.05 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index f80e1cd6..5ce3c7d9 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -84,12 +84,12 @@ def __call__( class_map_id = cp.argmax(semantic_map.map[layer_indices], axis=0) if "class_max" in semantic_map.param.fusion_algorithms: - # todo here is only cosideredx the case where we only have one max + # todo here is only cosidered the case where we only have one max max_map = cp.amax(semantic_map.new_map[max_idcs], axis=0) max_map_id = semantic_map.unique_id[semantic_map.id_max[max_idcs]] map = cp.where(max_map > class_map, max_map_id, class_map_id) else: - map = class_map + map = class_map_id # create color coding enc = self.color_encoding[map] return enc diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 3919b5a8..0c45a09b 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -106,6 +106,7 @@ def compile_kernels(self) -> None: self.class_average_kernel = class_average_kernel( self.param.cell_n, self.param.cell_n, + self.param.average_weight, ) if "class_bayesian" in self.unique_fusion: print("Initialize class bayesian kernel") @@ -252,6 +253,7 @@ def update_layers(self, points_all, channels, R, t, elevation_map): ) # calculate new thetas sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) + # do not divide by zero sum_alpha[sum_alpha == 0] = 1 self.map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims( sum_alpha, axis=0 @@ -265,8 +267,7 @@ def update_layers(self, points_all, channels, R, t, elevation_map): # find unique ids in new measurement and in map unique_idm = cp.unique(pt_id) unique_ida = cp.unique(self.unique_id[self.id_max]) - # get all unique ids, where index is the position in the prob_Sum and the value - # the value in the NN class + # get all unique ids, where index is the position in the prob_sum and the value in the NN class self.unique_id = cp.unique(cp.concatenate((unique_idm, unique_ida))) # contains the sum of the new measurement probabilities self.prob_sum = cp.zeros( @@ -294,9 +295,11 @@ def update_layers(self, points_all, channels, R, t, elevation_map): ) # add the previous alpha for i, lay in enumerate(layer_ids): - # todo add residual of prev alpha to the prob_sum - c = cp.mgrid[0: self.new_map.shape[1], 0: self.new_map.shape[2]] + c = cp.mgrid[0 : self.new_map.shape[1], 0 : self.new_map.shape[2]] self.prob_sum[self.id_max[i], c[0], c[1]] = self.new_map[lay] + # todo add residual of prev alpha to the prob_sum + # res = 1- self.new_map[lay] + # res /= (len(self.unique_id)-1) # find the alpha we want to keep for i, lay in enumerate(layer_ids): @@ -306,7 +309,8 @@ def update_layers(self, points_all, channels, R, t, elevation_map): # # update map calculate new thetas sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) - sum_alpha[sum_alpha==0]=1 + # do not divide by zero + sum_alpha[sum_alpha == 0] = 1 self.map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims( sum_alpha, axis=0 ) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py index ae94e068..18926337 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py @@ -18,32 +18,56 @@ def semmap_ex(add_lay, fusion_alg): additional_layers = dict(zip(p.additional_layers, p.fusion_algorithms)) p.cell_n = int(round(p.map_length / p.resolution)) + 2 - e = semantic_map.SemanticMap(p,additional_layers) + e = semantic_map.SemanticMap(p, additional_layers) return e @pytest.mark.parametrize( "add_lay, fusion_alg,channels", - [(["feat_0", "feat_1"], ["average", "average"],["feat_0"]), - (["feat_0", "feat_1"], ["average", "average"],[]), - (["feat_0", "feat_1", "rgb"], ["average", "average", "color"],["rgb", "feat_0"]), - (["feat_0", "feat_1", "rgb"], ["class_average", "average", "color"], ["rgb", "feat_0"]), - (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0"]), - (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0", "feat_1"]), - (["feat_0", "feat_1", "rgb"], ["class_bayesian", "class_max", "color"], ["rgb", "feat_0", "feat_1"]), - ], + [ + (["feat_0", "feat_1"], ["average", "average"], ["feat_0"]), + (["feat_0", "feat_1"], ["average", "average"], []), + ( + ["feat_0", "feat_1", "rgb"], + ["average", "average", "color"], + ["rgb", "feat_0"], + ), + ( + ["feat_0", "feat_1", "rgb"], + ["class_average", "average", "color"], + ["rgb", "feat_0"], + ), + ( + ["feat_0", "feat_1", "rgb"], + ["class_bayesian", "average", "color"], + ["rgb", "feat_0"], + ), + ( + ["feat_0", "feat_1", "rgb"], + ["class_bayesian", "average", "color"], + ["rgb", "feat_0", "feat_1"], + ), + ( + ["feat_0", "feat_1", "rgb"], + ["class_bayesian", "class_max", "color"], + ["rgb", "feat_0", "feat_1"], + ), + ], ) def test_fusion_of_pcl(semmap_ex, channels): fusion = semmap_ex.get_fusion_of_pcl(channels=channels) assert len(fusion) <= len(channels) - assert len(fusion)>0 or len(channels)==0 + assert len(fusion) > 0 or len(channels) == 0 assert all(isinstance(item, str) for item in fusion) @pytest.mark.parametrize( "add_lay, fusion_alg", - [(["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), - ], + [ + (["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), + ], ) @pytest.mark.parametrize("channels", [["rgb"], ["rgb", "feat_0"], []]) -def test_indices_fusion(semmap_ex, channels,fusion_alg): - pcl_indices, layer_indices = semmap_ex.get_indices_fusion(pcl_channels=channels, fusion_alg=fusion_alg[0]) +def test_indices_fusion(semmap_ex, channels, fusion_alg): + pcl_indices, layer_indices = semmap_ex.get_indices_fusion( + pcl_channels=channels, fusion_alg=fusion_alg[0] + ) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index 12c15042..1a96ec3e 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -19,10 +19,16 @@ class PointcloudNode: def __init__(self, sensor_name): # TODO: if this is going to be loaded from another package we might need to change namespace - config = rospy.get_param("/semantic_pointcloud/subscribers") - self.param: PointcloudParameter = PointcloudParameter.from_dict( - config[sensor_name] - ) + self.param: PointcloudParameter = PointcloudParameter() + # try catch for pytests + try: + config = rospy.get_param("/semantic_pointcloud/subscribers") + self.param: PointcloudParameter = PointcloudParameter.from_dict( + config[sensor_name] + ) + except: + print("NO ROS ENV found.") + self.param.sensor_name = sensor_name print("--------------Pointcloud Parameters-------------------") print(self.param.dumps_yaml()) @@ -40,6 +46,7 @@ def __init__(self, sensor_name): # setup pointcloud creation self.cv_bridge = CvBridge() self.P = None + self.header = None rospy.Subscriber(self.param.cam_info_topic, CameraInfo, self.cam_info_callback) rgb_sub = message_filters.Subscriber(self.param.image_topic, Image) @@ -78,7 +85,8 @@ def __init__(self, sensor_name): else: self.labels = list(self.segmentation_channels.keys()) self.semseg_color_map = self.color_map(len(self.labels)) - self.color_map_viz() + if self.param.show_label_legend: + self.color_map_viz() def color_map(self, N=256, normalized=False): def bitget(byteval, idx): @@ -114,14 +122,12 @@ def color_map_viz(self): plt.yticks([row_size * i + row_size / 2 for i in range(nclasses)], self.labels) plt.xticks([]) plt.show() - # plt.savefig("./labels.png") def initialize_semantics(self): if self.param.semantic_segmentation: self.semantic_model = resolve_model( self.param.segmentation_model, self.param ) - # todo (done) rewrite the segmenation channel such that keys are channels of seg and values are the fusion self.segmentation_channels = {} for i, (chan, fus) in enumerate( zip(self.param.channels, self.param.fusion) @@ -224,7 +230,6 @@ def process_image(self, image, u, v, points): if self.segmentation_channels is not None: self.perform_segmentation(image, points, u, v) if self.feature_channels is not None: - # TODO is no return needed? self.extract_features(image, points, u, v) def perform_segmentation(self, image, points, u, v): @@ -244,7 +249,8 @@ def extract_features(self, image, points, u, v): def publish_segmentation_image(self, probabilities): colors = cp.asarray(self.semseg_color_map) assert colors.ndim == 2 and colors.shape[1] == 3 - # img = 0 + if self.P is None: + return prob = cp.zeros((len(self.labels),) + probabilities.shape[1:]) if "class_max" in self.param.fusion: # decode, create an array with all possible classes and insert probabilities @@ -252,11 +258,11 @@ def publish_segmentation_image(self, probabilities): for iit, (chan, fuse) in enumerate( zip(self.param.channels, self.param.fusion) ): - if fuse == "class_max": + if fuse in ["class_max"]: temp = probabilities[it] temp_p, temp_i = decode_max(temp) temp_i.choose(prob) - c = cp.mgrid[0 : temp_i.shape[0], 0 : temp_i.shape[1]] + c = cp.mgrid[0: temp_i.shape[0], 0: temp_i.shape[1]] prob[temp_i, c[0], c[1]] = temp_p it += 1 elif fuse in ["class_bayesian", "class_average"]: diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py index b08e4d1d..c957e736 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py @@ -13,21 +13,35 @@ class FeatureExtractorParameter(Serializable): dropout: bool = False dino_feat_type: str = "feat" projection_type: str = "nonlinear" - input_size: List[int] = field(default_factory=[80, 160].copy) + # input_size: list = field(default_factory=[80, 160].copy) + input_size: list = field( + default_factory=lambda: [80, 160] + ) @dataclass class PointcloudParameter(Serializable): sensor_name: str = "camera" topic_name: str = "/elvation_mapping/pointcloud_semantic" - channels: list = field(default_factory=lambda: ["rgb", "person", "grass", "tree","max"]) - fusion: list = field(default_factory=lambda: ["color", "class_average", "class_average", "class_average","class_max"]) + channels: list = field( + default_factory=lambda: ["rgb", "person", "grass", "tree", "max"] + ) + fusion: list = field( + default_factory=lambda: [ + "color", + "class_average", + "class_average", + "class_average", + "class_max", + ] + ) semantic_segmentation: bool = True segmentation_model: str = "detectron_coco_panoptic_fpn_R_101_3x" publish_segmentation_image: bool = True segmentation_image_topic: str = "/semantic_pointcloud/sem_seg" pub_all: bool = False + show_label_legend: bool = False cam_info_topic: str = "/zed2i/zed_node/depth/camera_info" image_topic: str = "/zed2i/zed_node/left/image_rect_color" @@ -37,5 +51,5 @@ class PointcloudParameter(Serializable): confidence_topic: str = "/zed2i/zed_node/confidence/confidence_map" confidence_threshold: int = 10 - feature_extractor: bool = True + feature_extractor: bool = False feature_config: FeatureExtractorParameter = FeatureExtractorParameter diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py index 8ed1bfd4..8273467f 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py @@ -1,8 +1,10 @@ import pytest from ..pointcloud_node import PointcloudNode import cupy as cp +from ..utils import encode_max - +"""This test file only works if ros is installed +""" @pytest.fixture() def pointcloud_ex(cam_name): node = PointcloudNode(cam_name) @@ -29,6 +31,11 @@ def test_pub_seg(pointcloud_ex): # TODO we have to encode the max class other wise it is going to make problem amount = len( pointcloud_ex.segmentation_channels.keys() - ) + pointcloud_ex.param.fusion.count("max_class")+1 - prob = cp.random.rand(amount, 360, 640) + ) + pointcloud_ex.param.fusion.count("max_class") + if "class_max" in pointcloud_ex.param.fusion: + val = cp.random.rand(amount, 360, 640, dtype=cp.float32).astype(cp.float16) + ind = cp.random.randint(0, 2, (amount, 360, 640), dtype=cp.uint32).astype(cp.float32) + prob = encode_max(val, ind) + else: + prob = cp.random.rand(amount, 360, 640) pointcloud_ex.publish_segmentation_image(prob) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py index 740bbaea..e44f908d 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py @@ -128,13 +128,16 @@ def resolve_cateories(self): channels.append(chan) elif self.param.fusion[it] in ["class_average", "class_bayesian"]: print(chan, " is not in the semantic segmentation model.") - # for argamax for it, chan in enumerate(self.param.channels): if chan in [cls for cls in list(class_to_idx.keys())]: indices.append(class_to_idx[chan]) channels.append(chan) elif self.param.fusion[it] in ["class_max"]: + pass + print(chan, " is not in the semantic segmentation model but is a max channel.") + else: print(chan, " is not in the semantic segmentation model.") + self.stuff_categories = dict(zip(channels, indices)) self.segmentation_channels = self.stuff_categories @@ -158,7 +161,6 @@ def __call__(self, image, *args, **kwargs): selected_masks = cp.asarray( normalized_masks[list(self.stuff_categories.values())] ) - # get values of max, first remove the ones we already have normalized_masks[list(self.stuff_categories.values())] = 0 for i in range(self.param.fusion.count("class_max")): @@ -167,8 +169,10 @@ def __call__(self, image, *args, **kwargs): selected_masks = cp.concatenate( (selected_masks, cp.expand_dims(mer, axis=0)), axis=0 ) - # TODO set to zero the max - # normalized_masks[index] = 0 + x = torch.arange(0, index.shape[0]) + y = torch.arange(0, index.shape[1]) + c = torch.meshgrid(x, y) + normalized_masks[index, c[0], c[1]] = 0 return cp.asarray(selected_masks) def get_classes(self): From 2d320e395ddc75dd685eed15e5e35fd748f5d199 Mon Sep 17 00:00:00 2001 From: Gian <43470810+gerni17@users.noreply.github.com> Date: Tue, 6 Dec 2022 14:45:13 +0100 Subject: [PATCH 280/504] Update python-tests.yml --- .github/workflows/python-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 89fdcb30..451775e3 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -26,7 +26,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install pytest cupy + pip install pytest cupy-cuda114 if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Test elevation mapping with pytest run: | @@ -35,4 +35,4 @@ jobs: - name: Test semantic_pointcloud with pytest run: | cd sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests - pytest \ No newline at end of file + pytest From b4f935f41b6a4420b36321b5af581ecf2fde6776 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Tue, 6 Dec 2022 14:52:33 +0100 Subject: [PATCH 281/504] addded torch installation to action container --- .github/workflows/python-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 451775e3..514ccf73 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -27,6 +27,7 @@ jobs: run: | python -m pip install --upgrade pip pip install pytest cupy-cuda114 + pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu116 if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Test elevation mapping with pytest run: | From 5b3b6402c2f0472aaf3152d8037b4cec66180187 Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 6 Dec 2022 17:06:14 +0100 Subject: [PATCH 282/504] added a few dependecies --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f6e3233d..39e669bf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,12 @@ ###### Requirements without Version Specifiers ######` numpy -scipy +scipy==1.7 dataclasses ruamel.yaml opencv-python simple_parsing scikit-image +matplotlib ###### Requirements with Version Specifiers ######` shapely==1.7.1 From ed1ccb0bf3c828e92e2fb7e04ad16373acfc7264 Mon Sep 17 00:00:00 2001 From: Gian <43470810+gerni17@users.noreply.github.com> Date: Tue, 6 Dec 2022 17:10:15 +0100 Subject: [PATCH 283/504] Update python-tests.yml --- .github/workflows/python-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 514ccf73..e99dfb8e 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -26,8 +26,8 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install pytest cupy-cuda114 - pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu116 + pip install pytest cupy-cuda11x + pip install torch torchvision torchaudio if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Test elevation mapping with pytest run: | From d8845a665ccf21e3b413a42fcca1acd86d08c72e Mon Sep 17 00:00:00 2001 From: Gian <43470810+gerni17@users.noreply.github.com> Date: Tue, 6 Dec 2022 17:13:26 +0100 Subject: [PATCH 284/504] Update python-tests.yml --- .github/workflows/python-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index e99dfb8e..e61da073 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -27,6 +27,7 @@ jobs: run: | python -m pip install --upgrade pip pip install pytest cupy-cuda11x + python -m pip install 'git+https://github.com/facebookresearch/detectron2.git' pip install torch torchvision torchaudio if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Test elevation mapping with pytest From 9d512902f75f7e8029efd016c3ff94926ed3ef55 Mon Sep 17 00:00:00 2001 From: Gian <43470810+gerni17@users.noreply.github.com> Date: Tue, 6 Dec 2022 17:16:53 +0100 Subject: [PATCH 285/504] Update python-tests.yml --- .github/workflows/python-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index e61da073..de9a6a47 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -37,4 +37,4 @@ jobs: - name: Test semantic_pointcloud with pytest run: | cd sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests - pytest + pytest test_utils.py From 09f3e5d6282af51d606b9377f3184b24c888ef3e Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Tue, 6 Dec 2022 17:05:33 -0800 Subject: [PATCH 286/504] code formatting blacked 120 --- .../config/sensor_parameter.yaml | 39 +++- .../script/elevation_mapping_cupy/__init__.py | 2 +- .../elevation_mapping.py | 169 +++++++++--------- .../elevation_mapping_ros.py | 79 ++------ .../kernels/__init__.py | 2 + .../{ => kernels}/custom_image_kernels.py | 32 +++- .../{ => kernels}/custom_kernels.py | 62 ++++--- .../elevation_mapping_cupy/map_initializer.py | 2 +- .../elevation_mapping_cupy/parameter.py | 8 +- .../plugins/inpainting.py | 4 +- .../plugins/min_filter.py | 3 +- .../plugins/plugin_manager.py | 12 +- .../plugins/robot_centric_elevation.py | 4 +- .../plugins/semantic_traversability.py | 9 +- .../plugins/smooth_filter.py | 3 +- .../elevation_mapping_cupy/semantic_map.py | 149 ++++++++++----- .../tests/test_elevation_mapping.py | 4 +- .../tests/test_parameter.py | 1 - .../tests/test_plugins.py | 17 +- .../tests/test_semantic_map.py | 27 +-- elevation_mapping_cupy/setup.py | 7 +- .../debug_publisher/image_debug_node.py | 2 +- 22 files changed, 347 insertions(+), 290 deletions(-) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/__init__.py rename elevation_mapping_cupy/script/elevation_mapping_cupy/{ => kernels}/custom_image_kernels.py (79%) rename elevation_mapping_cupy/script/elevation_mapping_cupy/{ => kernels}/custom_kernels.py (98%) diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index 48850236..2be606d2 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -10,18 +10,39 @@ subscribers: # Collision checking during raycasting from map to camera - debug_image: + debug_rgb: + fusion: ['image_color'] + topic_name_camera: /zed2i/zed_node/right/image + topic_name_camera_info: /zed2i/zed_node/right/camera_info + channels: ["nice_rgb_channel"] + data_type: image + + debug_rgb_3_seperate: + fusion: ['image_exponential','image_exponential','image_exponential'] + topic_name_camera: /zed2i/zed_node/right/image + topic_name_camera_info: /zed2i/zed_node/right/camera_info + channels: ["r_channel", "g_channel", "b_channel"] + data_type: image + + debug_rgb_2_seperate: + fusion: ['image_exponential', 'image_exponential'] + topic_name_camera: /zed2i/zed_node/right/image + topic_name_camera_info: /zed2i/zed_node/right/camera_info + channels: ["r_channel", "g_channel"] + data_type: image + + debug_mono_exponential: fusion: ['image_exponential'] topic_name_camera: /debug_image topic_name_camera_info: /zed2i/zed_node/right/camera_info channels: ["single_channel_semantic"] - type: image + data_type: image front_cam: channels: ['rgb'] fusion: ['color'] topic_name: '/elvation_mapping/pointcloud_semantic' - type: pointcloud + data_type: pointcloud # front_cam: # channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] @@ -53,34 +74,34 @@ subscribers: channels: [] fusion: ['average'] topic_name: /robot_self_filter/bpearl_front/point_cloud - type: pointcloud + data_type: pointcloud rear_bpearl: channels: [] fusion: ['average'] topic_name: /robot_self_filter/bpearl_rear/point_cloud - type: pointcloud + data_type: pointcloud front_depth: channels: [] fusion: ['average'] topic_name: /depth_camera_front/point_cloud_self_filtered - type: pointcloud + data_type: pointcloud rear_depth: channels: [] fusion: ['average'] topic_name: /depth_camera_rear/point_cloud_self_filtered - type: pointcloud + data_type: pointcloud left_depth: channels: [] fusion: ['average'] topic_name: /depth_camera_left/point_cloud_self_filtered - type: pointcloud + data_type: pointcloud right_depth: channels: [] fusion: ['average'] topic_name: /depth_camera_right/point_cloud_self_filtered - type: pointcloud \ No newline at end of file + data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py index 6e2735cd..a16e894d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py @@ -1,2 +1,2 @@ from .parameter import Parameter -from .elevation_mapping import ElevationMap \ No newline at end of file +from .elevation_mapping import ElevationMap diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 62480005..017e2640 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -11,16 +11,15 @@ from elevation_mapping_cupy.traversability_filter import get_filter_chainer, get_filter_torch from elevation_mapping_cupy.parameter import Parameter -from elevation_mapping_cupy.custom_kernels import add_points_kernel, add_color_kernel, color_average_kernel -from elevation_mapping_cupy.custom_kernels import sum_kernel -from elevation_mapping_cupy.custom_kernels import error_counting_kernel -from elevation_mapping_cupy.custom_kernels import average_map_kernel -from elevation_mapping_cupy.custom_kernels import dilation_filter_kernel -from elevation_mapping_cupy.custom_kernels import normal_filter_kernel -from elevation_mapping_cupy.custom_kernels import polygon_mask_kernel -from elevation_mapping_cupy.custom_image_kernels import image_to_map_correspondence_kernel -from elevation_mapping_cupy.custom_image_kernels import average_correspondences_to_map_kernel +from elevation_mapping_cupy.kernels import add_points_kernel, add_color_kernel, color_average_kernel +from elevation_mapping_cupy.kernels import sum_kernel +from elevation_mapping_cupy.kernels import error_counting_kernel +from elevation_mapping_cupy.kernels import average_map_kernel +from elevation_mapping_cupy.kernels import dilation_filter_kernel +from elevation_mapping_cupy.kernels import normal_filter_kernel +from elevation_mapping_cupy.kernels import polygon_mask_kernel +from elevation_mapping_cupy.kernels import image_to_map_correspondence_kernel from elevation_mapping_cupy.map_initializer import MapInitializer @@ -61,8 +60,7 @@ def __init__(self, param: Parameter): self.cell_n = param.cell_n self.map_lock = threading.Lock() - self.additional_layers = dict(zip(self.param.additional_layers, self.param.fusion_algorithms)) - self.semantic_map = SemanticMap(self.param, self.additional_layers) + self.semantic_map = SemanticMap(self.param) self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n), dtype=self.data_type) self.layer_names = [ "elevation", @@ -93,7 +91,9 @@ def __init__(self, param: Parameter): self.additive_mean_error = 0.0 self.compile_kernels() + self.compile_image_kernels() + self.semantic_map.compile_kernels() weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') @@ -118,7 +118,8 @@ def clear(self): self.elevation_map *= 0.0 # Initial variance self.elevation_map[1] += self.initial_variance - self.semantic_map.map *= 0.0 + self.semantic_map.clear() + self.mean_error = 0.0 self.additive_mean_error = 0.0 @@ -207,8 +208,9 @@ def shift_map_xy(self, delta_pixel): self.pad_value(self.elevation_map, shift_value, value=0.0) self.pad_value(self.elevation_map, shift_value, idx=1, value=self.initial_variance) - self.semantic_map.map = cp.roll(self.semantic_map.map, shift_value, axis=(1, 2)) - self.pad_value(self.semantic_map.map, shift_value, value=0.0) + # TODO: This in general is not best practice. This should be layered + self.semantic_map.semantic_map = cp.roll(self.semantic_map.semantic_map, shift_value, axis=(1, 2)) + self.pad_value(self.semantic_map.semantic_map, shift_value, value=0.0) def shift_map_z(self, delta_z): """Shift the relevant layers along the vertical axis. @@ -276,17 +278,19 @@ def compile_kernels(self): self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) def compile_image_kernels(self): - self.new_sem_map = cp.asarray(np.zeros((self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) - self.valid_correspondence = cp.asarray(np.zeros((self.cell_n, self.cell_n), dtype=np.bool), dtype=np.bool) - self.uv_correspondence = cp.asarray(np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32) - - self.image_to_map_correspondence_kernel = image_to_map_correspondence_kernel( - resolution=self.resolution, width=self.cell_n, height=self.cell_n, tolerance_z_collision=0.1 - ) - - self.average_correspondences_to_map_kernel = average_correspondences_to_map_kernel( - resolution=self.resolution, width=self.cell_n, height=self.cell_n - ) + for config in self.param.subscriber_cfg.values(): + if config["data_type"] == "image": + self.valid_correspondence = cp.asarray( + np.zeros((self.cell_n, self.cell_n), dtype=np.bool), dtype=np.bool + ) + self.uv_correspondence = cp.asarray( + np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32 + ) + # TODO tolerance_z_collision add parameter + self.image_to_map_correspondence_kernel = image_to_map_correspondence_kernel( + resolution=self.resolution, width=self.cell_n, height=self.cell_n, tolerance_z_collision=0.1 + ) + break def shift_translation_to_map_center(self, t): """Deduct the map center to get the translation of a point w.r.t. the map center. @@ -352,7 +356,7 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori self.average_map_kernel(self.new_map, self.elevation_map, size=(self.cell_n * self.cell_n)) # self.update_additional_layers(additional_fusion, points_all, channels, R, t) - self.semantic_map.update_layers(points_all, channels, R, t, self.new_map) + self.semantic_map.update_layers_pointcloud(points_all, channels, R, t, self.new_map) if self.param.enable_overlap_clearance: self.clear_overlap_map(t) @@ -374,49 +378,6 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori # calculate normal vectors self.update_normal(self.traversability_input) - def update_map_with_image_kernel(self, image, K, channels, R, t, image_height, image_width): - """Update map with new measurement from semantic image.""" - P = cp.asarray(K @ np.concatenate([R, t[:, None]], 1), dtype=np.float32) - t_cam_map = -R.T @ t - self.center - t_cam_map = t_cam_map.get() - x1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[0]) / self.resolution)) - y1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[1]) / self.resolution)) - z1 = cp.float32(t_cam_map[2]) - - image = cp.asarray(image, dtype=np.float32) - - self.new_sem_map *= 0 - self.uv_correspondence *= 0 - self.valid_correspondence[:, :] = False - with self.map_lock: - sem_map_idx = self.semantic_map.get_index(channels[0]) - self.image_to_map_correspondence_kernel( - self.elevation_map, - x1, - y1, - z1, - P.reshape(-1), - cp.float32(image_height), - cp.float32(image_width), - self.center, - self.uv_correspondence, - self.valid_correspondence, - size=int(self.elevation_map.shape[1] * self.elevation_map.shape[2]), - ) - - self.average_correspondences_to_map_kernel( - self.semantic_map.map[sem_map_idx], - image, - self.uv_correspondence, - self.valid_correspondence, - cp.float32(image_height), - cp.float32(image_width), - self.new_sem_map, - size=int(self.elevation_map.shape[1] * self.elevation_map.shape[2]), - ) - - self.semantic_map.map[sem_map_idx] = self.new_sem_map - def clear_overlap_map(self, t): # Clear overlapping area around center height_min = t[2] - self.param.overlap_clear_range_z @@ -453,7 +414,7 @@ def input( t: cp._core.core.ndarray, position_noise: int, orientation_noise: int, - ) -> None: + ): """Input the pointcloud and fuse the new measurements to update the elevation map. Args: @@ -482,8 +443,8 @@ def input( def input_image( self, + sub_key: str, image: cp._core.core.ndarray, - channels: List[str], R: cp._core.core.ndarray, t: cp._core.core.ndarray, K: cp._core.core.ndarray, @@ -491,13 +452,45 @@ def input_image( image_width: int, ): image = np.stack(image, axis=0) - self.update_map_with_image_kernel(cp.asarray(image, dtype=self.data_type), - cp.asarray(K, dtype=self.data_type), - channels, - cp.asarray(R, dtype=self.data_type), - cp.asarray(t, dtype=self.data_type), - image_height, - image_width) + if len(image.shape) == 2: + image = image[None] + + # Convert to cupy + image = cp.asarray(image, dtype=self.data_type) + K = cp.asarray(K, dtype=self.data_type) + R = cp.asarray(R, dtype=self.data_type) + t = cp.asarray(t, dtype=self.data_type) + image_height = cp.float32(image_height) + image_width = cp.float32(image_width) + + # Calculate transformation matrix + P = cp.asarray(K @ cp.concatenate([R, t[:, None]], 1), dtype=np.float32) + t_cam_map = -R.T @ t - self.center + t_cam_map = t_cam_map.get() + x1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[0]) / self.resolution)) + y1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[1]) / self.resolution)) + z1 = cp.float32(t_cam_map[2]) + + self.uv_correspondence *= 0 + self.valid_correspondence[:, :] = False + + with self.map_lock: + self.image_to_map_correspondence_kernel( + self.elevation_map, + x1, + y1, + z1, + P.reshape(-1), + image_height, + image_width, + self.center, + self.uv_correspondence, + self.valid_correspondence, + size=int(self.cell_n * self.cell_n), + ) + self.semantic_map.update_layers_image( + sub_key, image, self.uv_correspondence, self.valid_correspondence, image_height, image_width + ) def update_normal(self, dilated_map): """Clear the normal map and then apply the normal kernel with dilated map as input. @@ -610,7 +603,7 @@ def exists_layer(self, name): """ if name in self.layer_names: return True - elif name in self.additional_layers: + elif name in self.semantic_map.layer_names: return True elif name in self.plugin_manager.layer_names: return True @@ -647,7 +640,7 @@ def get_map_with_name_ref(self, name, data): m = self.normal_map.copy()[1, 1:-1, 1:-1] elif name == "normal_z": m = self.normal_map.copy()[2, 1:-1, 1:-1] - elif name in self.additional_layers.keys(): + elif name in self.semantic_map.layer_names: m = self.semantic_map.get_map_with_name(name) elif name in self.plugin_manager.layer_names: self.plugin_manager.update_with_name( @@ -689,19 +682,19 @@ def get_normal_ref(self, normal_x_data, normal_y_data, normal_z_data): def get_layer(self, name): if name in self.layer_names: idx = self.layer_names.index(name) - map = self.elevation_map[idx] - elif name in self.semantic_map.param.additional_layers: - idx = self.semantic_map.param.additional_layers.index(name) - map = self.semantic_map.map[idx] + return_map = self.elevation_map[idx] + elif name in self.semantic_map.layer_names: + idx = self.semantic_map.layer_names.index(name) + return_map = self.semantic_map.semantic_map[idx] elif name in self.plugin_manager.layer_names: self.plugin_manager.update_with_name( name, self.elevation_map, self.layer_names, self.semantic_map, self.base_rotation ) - map = self.plugin_manager.get_map_with_name(name) + return_map = self.plugin_manager.get_map_with_name(name) else: print("Layer {} is not in the map, returning traversabiltiy!".format(name)) return - return map + return return_map def get_polygon_traversability(self, polygon, result): """Check if input polygons are traversable. @@ -734,8 +727,8 @@ def get_polygon_traversability(self, polygon, result): self.mask, size=(self.cell_n * self.cell_n), ) - map = self.get_layer(self.param.checker_layer) - masked, masked_isvalid = get_masked_traversability(self.elevation_map, self.mask, map) + tmp_map = self.get_layer(self.param.checker_layer) + masked, masked_isvalid = get_masked_traversability(self.elevation_map, self.mask, tmp_map) if masked_isvalid.sum() > 0: t = masked.sum() / masked_isvalid.sum() else: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index c2b7842e..71d322d6 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -42,11 +42,13 @@ def __init__(self): weight_file = os.path.join(self.root, "config/weights.dat") plugin_config_file = os.path.join(self.root, "config/plugin_config.yaml") self.param = Parameter(use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file) + self.node_name = "elevation_mapping" + # ROS self.initalize_ros() - self.overwrite_elevation_mapping_params() - self.setup_cv_bride() + self.param.subscriber_cfg = self.subscribers + self.initalize_elevation_mapping() self.register_subscribers() self.register_publishers() @@ -54,10 +56,6 @@ def __init__(self): self._last_t = None - def setup_cv_bride(self): - if self.image_mono_data: - self.cv_bridge = CvBridge() - def initalize_elevation_mapping(self): self.param.update() # TODO add statistics across processed topics @@ -74,54 +72,27 @@ def initalize_ros(self): self._listener = tf2_ros.TransformListener(self._tf_buffer) self.get_ros_params() - def overwrite_elevation_mapping_params(self): - additional = [] - fusion = [] - self.image_mono_data = False - for key, config in self.subscribers.items(): - if config["type"] == "image": - self.image_mono_data = True - for chan, fus in zip(config["channels"], config["fusion"]): - if chan not in additional: - additional.append(chan) - if fus not in fusion: - fusion.append(fus) - - elif config["type"] == "pointcloud": - for chan, fus in zip(config["channels"], config["fusion"]): - if chan not in additional: - additional.append(chan) - if fus not in fusion: - fusion.append(fus) - else: - typ = config["type"] - raise ValueError(f"{typ} unknown, only pointcloud and image defined.") - - self.param.additional_layers = additional - self.param.fusion_algorithms = fusion - self.dtype = [ - ("x", np.float32), - ("y", np.float32), - ("z", np.float32), - ] - for chan in config["channels"]: - self.dtype.append((chan, np.float32)) - def register_subscribers(self): + # check if CV bridge is needed + for config in self.param.subscriber_cfg.values(): + if config["data_type"] == "image": + self.cv_bridge = CvBridge() + break + pointcloud_subs = {} image_subs = {} for key, config in self.subscribers.items(): - if config["type"] == "image": + if config["data_type"] == "image": camera_sub = message_filters.Subscriber(config["topic_name_camera"], Image) camera_info_sub = message_filters.Subscriber(config["topic_name_camera_info"], CameraInfo) image_subs[key] = message_filters.ApproximateTimeSynchronizer( [camera_sub, camera_info_sub], queue_size=10, slop=0.5 ) - image_subs[key].registerCallback(self.image_callback, (config["channels"], config["fusion"])) + image_subs[key].registerCallback(self.image_callback, key) - elif config["type"] == "pointcloud": + elif config["data_type"] == "pointcloud": pointcloud_subs[key] = rospy.Subscriber( - config["topic_name"], PointCloud2, self.pointcloud_callback, (config["channels"], config["fusion"]) + config["topic_name"], PointCloud2, self.pointcloud_callback, key ) def register_publishers(self): @@ -172,8 +143,7 @@ def register_timers(self): self.timer_pose = rospy.Timer(rospy.Duration(1 / self.update_pose_fps), self.update_pose) self.timer_time = rospy.Timer(rospy.Duration(self.time_interval), self.update_time) - def image_callback(self, camera_msg, camera_info_msg, config): - fusion = config[1] + def image_callback(self, camera_msg, camera_info_msg, sub_key): # get pose of image ti = rospy.Time(secs=camera_msg.header.stamp.secs, nsecs=camera_msg.header.stamp.nsecs) self._last_t = ti @@ -195,23 +165,12 @@ def image_callback(self, camera_msg, camera_info_msg, config): assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) # process pointcloud - self._map.input_image_mono(semantic_img, config[0], R, t, K, camera_info_msg.height, camera_info_msg.width) + self._map.input_image(sub_key, semantic_img, R, t, K, camera_info_msg.height, camera_info_msg.width) self._image_process_counter += 1 - def pointcloud_callback(self, msg, config): - # convert pcd into numpy array - # output = {} - # total_bytes = msg.fields[-1].offset + PDC_DATATYPE[str(msg.fields[-1].datatype)](1).nbytes - # res = np.frombuffer(msg.data, np.dtype(np.uint8)).reshape((-1, msg.point_step)) - # for field in msg.fields: - # assert field.count == 1, "If this is not case, maybe does not work" - # PDC_DATATYPE[str(field.datatype)] - # dtype = PDC_DATATYPE[str(field.datatype)] - # nbytes = dtype(1).nbytes - # data = res[:, field.offset : field.offset + nbytes] - # output[field.name] = np.frombuffer(data.copy(), np.dtype(dtype)).reshape((-1)) - channels = ["x", "y", "z"] + config[0] - fusion = config[1] + def pointcloud_callback(self, msg, sub_key): + channels = ["x", "y", "z"] + self.param.subscriber_cfg[sub_key]["channels"] + points = ros_numpy.numpify(msg) pts = np.empty((points.shape[0], 0)) for ch in channels: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/__init__.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/__init__.py new file mode 100644 index 00000000..5a58d6db --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/__init__.py @@ -0,0 +1,2 @@ +from .custom_image_kernels import * +from .custom_kernels import * diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_image_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py similarity index 79% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/custom_image_kernels.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py index 3fcf28d6..75ff85c2 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_image_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py @@ -123,7 +123,7 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_co def average_correspondences_to_map_kernel(resolution, width, height): average_correspondences_to_map_kernel = cp.ElementwiseKernel( - in_params="raw U sem_map, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", out_params="raw U new_sem_map", preamble=string.Template( """ @@ -136,13 +136,41 @@ def average_correspondences_to_map_kernel(resolution, width, height): operation=string.Template( """ int cell_idx = get_map_idx(i, 0); + int target_idx = get_map_idx(i, map_idx); int cell_idx_2 = get_map_idx(i, 1); if (valid_correspondence[cell_idx]){ int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; - new_sem_map[cell_idx] = image_mono[idx]; + new_sem_map[target_idx] = image_mono[idx]; } """ ).substitute(), name="average_correspondences_to_map_kernel", ) return average_correspondences_to_map_kernel + + +def color_correspondences_to_map_kernel(resolution, width, height): + color_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw W map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + int cell_idx_2 = get_map_idx(i, 1); + if (valid_correspondence[cell_idx]){ + int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + new_sem_map[cell_idx] = image_rgb[idx]; + } + """ + ).substitute(), + name="color_correspondences_to_map_kernel", + ) + return color_correspondences_to_map_kernel diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py similarity index 98% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py index 4caa3cbe..a6076ac5 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py @@ -655,13 +655,15 @@ def polygon_mask_kernel(width, height, resolution): ) return polygon_mask_kernel + ##################### additional kernels ################################# + def sum_kernel( - resolution, - width, - height, - ): + resolution, + width, + height, +): # input the list of layers, amount of channels can slo be input through kernel sum_kernel = cp.ElementwiseKernel( in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", @@ -673,7 +675,7 @@ def sum_kernel( return layer * layer_n + idx; } """ - ).substitute(resolution=resolution,width=width, height=height), + ).substitute(resolution=resolution, width=width, height=height), operation=string.Template( """ U idx = p[i * pcl_channels[0]]; @@ -688,17 +690,17 @@ def sum_kernel( } } """ - ).substitute( - ), + ).substitute(), name="sum_kernel", ) return sum_kernel + def alpha_kernel( - resolution, - width, - height, - ): + resolution, + width, + height, +): # input the list of layers, amount of channels can slo be input through kernel alpha_kernel = cp.ElementwiseKernel( in_params="raw U p, raw W pcl_chan, raw W map_lay, raw W pcl_channels", @@ -710,7 +712,7 @@ def alpha_kernel( return layer * layer_n + idx; } """ - ).substitute(resolution=resolution,width=width, height=height), + ).substitute(resolution=resolution, width=width, height=height), operation=string.Template( """ U idx = p[i * pcl_channels[0]]; @@ -731,17 +733,15 @@ def alpha_kernel( } } """ - ).substitute( - ), + ).substitute(), name="alpha_kernel", ) return alpha_kernel - def average_kernel( - width, - height, + width, + height, ): average_kernel = cp.ElementwiseKernel( in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", @@ -764,15 +764,15 @@ def average_kernel( } } """ - ).substitute( - ), + ).substitute(), name="average_map_kernel", ) return average_kernel + def class_average_kernel( - width, - height, + width, + height, ): class_average_kernel = cp.ElementwiseKernel( in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", @@ -802,15 +802,15 @@ def class_average_kernel( } } """ - ).substitute( - ), + ).substitute(), name="class_average_kernel", ) return class_average_kernel + def add_color_kernel( - width, - height, + width, + height, ): add_color_kernel = cp.ElementwiseKernel( in_params="raw T p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", @@ -853,16 +853,15 @@ def add_color_kernel( } } """ - ).substitute( - width=width - ), + ).substitute(width=width), name="add_color_kernel", ) return add_color_kernel + def color_average_kernel( - width, - height, + width, + height, ): color_average_kernel = cp.ElementwiseKernel( in_params="raw V color_map, raw W pcl_chan, raw W map_lay, raw W pcl_channels", @@ -913,8 +912,7 @@ def color_average_kernel( } } """ - ).substitute( - ), + ).substitute(), name="color_average_kernel", ) return color_average_kernel diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/map_initializer.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/map_initializer.py index 8d4ee945..0139ea76 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/map_initializer.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/map_initializer.py @@ -23,7 +23,7 @@ def __call__(self, *args, **kwargs): return def points_initializer(self, elevation_map, points, method="linear"): - """ Initialize the map using interpolation between given points + """Initialize the map using interpolation between given points Args: elevation_map (cupy._core.core.ndarray): elevation_map data. diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 2a92168f..40fc9fd8 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -8,11 +8,12 @@ from simple_parsing.helpers import Serializable from dataclasses import field + @dataclass class Parameter(Serializable): + subscriber_cfg: dict = field(default_factory=lambda: {}) + resolution: float = 0.04 - additional_layers: list = field(default_factory=lambda: ["feat_0"]) - fusion_algorithms: list = field(default_factory=lambda: ["average"]) cell_n: int = None data_type: str = np.float32 @@ -45,7 +46,7 @@ class Parameter(Serializable): safe_thresh: float = 0.5 safe_min_thresh: float = 0.5 max_unsafe_n: int = 20 - checker_layer: str = 'traversability' + checker_layer: str = "traversability" min_filter_size: int = 5 min_filter_iteration: int = 3 @@ -98,6 +99,7 @@ def update(self): # +2 is a border for outside map self.cell_n = int(round(self.map_length / self.resolution)) + 2 + if __name__ == "__main__": param = Parameter() print(param) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py index 97d8d09a..8da8c29c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py @@ -54,9 +54,7 @@ def __call__( h = elevation_map[0] h_max = float(h[mask < 1].max()) h_min = float(h[mask < 1].min()) - h = cp.asnumpy((elevation_map[0] - h_min) * 255 / (h_max - h_min)).astype( - "uint8" - ) + h = cp.asnumpy((elevation_map[0] - h_min) * 255 / (h_max - h_min)).astype("uint8") dst = np.array(cv.inpaint(h, mask, 1, self.method)) h_inpainted = dst.astype(np.float32) * (h_max - h_min) / 255 + h_min return cp.asarray(h_inpainted).astype(np.float64) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py index b3eba4ff..6c479b03 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py @@ -10,9 +10,8 @@ class MinFilter(PluginBase): - def __init__(self, cell_n: int = 100, dilation_size: int = 5, iteration_n: int = 5, **kwargs): - """ This is a filter to fill in invalid cells with minimum values around. + """This is a filter to fill in invalid cells with minimum values around. Args: cell_n (int): width of the elevation map. diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index b29375cd..faa74ebb 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -78,9 +78,7 @@ def init(self, plugin_params: List[PluginParams], extra_params: List[Dict]): self.plugins = [] for param, extra_param in zip(plugin_params, extra_params): - m = importlib.import_module( - "." + param.name, package="elevation_mapping_cupy.plugins" - ) # -> 'module' + m = importlib.import_module("." + param.name, package="elevation_mapping_cupy.plugins") # -> 'module' for name, obj in inspect.getmembers(m): if ( inspect.isclass(obj) @@ -90,9 +88,7 @@ def init(self, plugin_params: List[PluginParams], extra_params: List[Dict]): # Add cell_n to params extra_param["cell_n"] = self.cell_n self.plugins.append(obj(**extra_param)) - self.layers = cp.zeros( - (len(self.plugins), self.cell_n, self.cell_n), dtype=cp.float32 - ) + self.layers = cp.zeros((len(self.plugins), self.cell_n, self.cell_n), dtype=cp.float32) self.layer_names = self.get_layer_names() self.plugin_names = self.get_plugin_names() @@ -155,9 +151,7 @@ def update_with_name( if idx is not None: n_param = len(signature(self.plugins[idx]).parameters) if n_param == 5: - self.layers[idx] = self.plugins[idx]( - elevation_map, layer_names, self.layers, self.layer_names - ) + self.layers[idx] = self.plugins[idx](elevation_map, layer_names, self.layers, self.layer_names) elif n_param == 6: self.layers[idx] = self.plugins[idx]( elevation_map, diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py index 2b0de613..aea7df13 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py @@ -8,7 +8,7 @@ class RobotCentricElevation(PluginBase): def __init__( self, cell_n: int = 100, resolution: float = 0.05, threshold: float = 0.4, use_threshold: bool = 0, **kwargs ): - """ Generates an elevation map with respect to the robot frame. + """Generates an elevation map with respect to the robot frame. Args: cell_n (int): @@ -20,7 +20,7 @@ def __init__( super().__init__() self.width = cell_n self.height = cell_n - self.min_filtered = cp.zeros((self.width, self.height),dtype=cp.float32) + self.min_filtered = cp.zeros((self.width, self.height), dtype=cp.float32) self.base_elevation_kernel = cp.ElementwiseKernel( in_params="raw U map, raw U mask, raw U R", diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py index 4fb842d2..17a15277 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py @@ -10,7 +10,6 @@ class SemanticTraversability(PluginBase): - def __init__( self, cell_n: int = 100, @@ -19,7 +18,7 @@ def __init__( type: list = ["traversability"], **kwargs, ): - """ Extracts traversability and elevations from layers and generates an updated traversability that can be used by checker. + """Extracts traversability and elevations from layers and generates an updated traversability that can be used by checker. Args: cell_n (int): @@ -69,9 +68,7 @@ def __call__( idx = plugin_layer_names.index(name) tempo = plugin_layers[idx] else: - print( - "Layer {} is not in the map, returning traversabiltiy!".format(name) - ) + print("Layer {} is not in the map, returning traversabiltiy!".format(name)) return if self.type[it] == "traversability": tempo = cp.where(tempo <= self.thresholds[it], 1, 0) @@ -79,6 +76,6 @@ def __call__( else: tempo = cp.where(tempo >= self.thresholds[it], 1, 0) map += tempo - map = cp.where(map <= 0.9, 0.1,1) + map = cp.where(map <= 0.9, 0.1, 1) return map diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py index fb03ad28..79d0be80 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py @@ -10,9 +10,8 @@ class SmoothFilter(PluginBase): - def __init__(self, cell_n: int = 100, input_layer_name: str = "elevation", **kwargs): - """ This filters smoothees elevation map. + """This filters smoothees elevation map. Args: cell_n (int): diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 3d13ffe7..a4e51dd2 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -1,52 +1,58 @@ -from .parameter import Parameter +from elevation_mapping_cupy.parameter import Parameter import cupy as cp import numpy as np from typing import List -from .custom_kernels import ( - sum_kernel, - add_color_kernel, - color_average_kernel, - average_kernel, - class_average_kernel, - alpha_kernel, -) +from elevation_mapping_cupy.kernels import sum_kernel, add_color_kernel, color_average_kernel +from elevation_mapping_cupy.kernels import average_kernel, class_average_kernel, alpha_kernel +from elevation_mapping_cupy.kernels import average_correspondences_to_map_kernel, color_correspondences_to_map_kernel xp = cp class SemanticMap: - def __init__(self, param: Parameter, layer_specs: dict): + def __init__(self, param: Parameter): """ Args: param (elevation_mapping_cupy.parameter.Parameter): - layer_specs (Dict[str, str]): """ + self.param = param - self.layer_specs = layer_specs - self.amount_additional_layers = len(self.param.additional_layers) - self.map = xp.zeros( - (self.amount_additional_layers, self.param.cell_n, self.param.cell_n), + + # TODO: maps channel to fusion strategy (maybe rename) + self.layer_specs = {} + self.layer_names = [] + self.unique_fusion = [] + + for k, config in self.param.subscriber_cfg.items(): + for f, c in zip(config["fusion"], config["channels"]): + if c not in self.layer_names: + self.layer_names.append(c) + self.layer_specs[c] = f + else: + assert self.layer_specs[c] == f, "Error: Single layer has multiple fusion algorithms!" + + if f not in self.unique_fusion: + self.unique_fusion.append(f) + + self.amount_layer_names = len(self.layer_names) + + self.semantic_map = xp.zeros( + (self.amount_layer_names, self.param.cell_n, self.param.cell_n), dtype=param.data_type, ) - self.get_unique_fusion() self.new_map = xp.zeros( - (self.amount_additional_layers, self.param.cell_n, self.param.cell_n), + (self.amount_layer_names, self.param.cell_n, self.param.cell_n), param.data_type, ) - self.color_map = None - def get_unique_fusion(self): - self.unique_fusion = [] - for x in list(self.layer_specs.values()): - if x not in self.unique_fusion: - self.unique_fusion.append(x) + def clear(self): + self.semantic_map *= 0.0 def compile_kernels(self) -> None: """ Returns: None: - """ # TODO: maybe this could be improved by creating functions for each single # create a base class containing compile kernel as well as update and this then can be created for various @@ -67,6 +73,7 @@ def compile_kernels(self) -> None: if "color" in self.unique_fusion: print("Initialize color kernel") + self.add_color_kernel = add_color_kernel( self.param.cell_n, self.param.cell_n, @@ -91,6 +98,16 @@ def compile_kernels(self) -> None: self.param.cell_n, ) + if "image_exponential" in self.unique_fusion: + self.average_correspondences_to_map_kernel = average_correspondences_to_map_kernel( + resolution=self.param.resolution, width=self.param.cell_n, height=self.param.cell_n + ) + + if "image_color" in self.unique_fusion: + self.color_correspondences_to_map_kernel = color_correspondences_to_map_kernel( + resolution=self.param.resolution, width=self.param.cell_n, height=self.param.cell_n + ) + def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: """Get all fusion algorithms that need to be applied to a specific pointcloud @@ -130,7 +147,7 @@ def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): layer_indices = cp.append(layer_indices, it).astype(np.int32) return pcl_indices, layer_indices - def update_layers(self, points_all, channels, R, t, elevation_map): + def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): additional_fusion = self.get_fusion_of_pcl(channels) self.new_map *= 0.0 if "average" in additional_fusion: @@ -142,7 +159,7 @@ def update_layers(self, points_all, channels, R, t, elevation_map): pcl_ids, layer_ids, cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), - self.map, + self.semantic_map, self.new_map, size=(points_all.shape[0]), ) @@ -152,7 +169,7 @@ def update_layers(self, points_all, channels, R, t, elevation_map): layer_ids, cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), elevation_map, - self.map, + self.semantic_map, size=(self.param.cell_n * self.param.cell_n), ) if "class_average" in additional_fusion: @@ -164,7 +181,7 @@ def update_layers(self, points_all, channels, R, t, elevation_map): pcl_ids, layer_ids, cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), - self.map, + self.semantic_map, self.new_map, size=(points_all.shape[0]), ) @@ -174,7 +191,7 @@ def update_layers(self, points_all, channels, R, t, elevation_map): layer_ids, cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), elevation_map, - self.map, + self.semantic_map, size=(self.param.cell_n * self.param.cell_n), ) @@ -192,17 +209,16 @@ def update_layers(self, points_all, channels, R, t, elevation_map): ) # calculate new thetas sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) - self.map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) - # assert cp.unique(cp.sum(self.map[layer_ids], axis=0)) equal to zero or to nan + self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) + # assert cp.unique(cp.sum(self.semantic_map[layer_ids], axis=0)) equal to zero or to nan if "color" in additional_fusion: pcl_ids, layer_ids = self.get_indices_fusion(channels, "color") - if self.color_map is None: - self.color_map = cp.zeros( - (1 + 3 * layer_ids.shape[0], self.param.cell_n, self.param.cell_n), - dtype=np.uint32, - ) - self.color_map *= 0 + self.color_map = cp.zeros( + (1 + 3 * layer_ids.shape[0], self.param.cell_n, self.param.cell_n), + dtype=np.uint32, + ) + points_all = points_all.astype(cp.float32) self.add_color_kernel( points_all, @@ -219,10 +235,57 @@ def update_layers(self, points_all, channels, R, t, elevation_map): pcl_ids, layer_ids, cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), - self.map, + self.semantic_map, size=(self.param.cell_n * self.param.cell_n), ) + def update_layers_image( + self, + sub_key: str, + image: cp._core.core.ndarray, + uv_correspondence: cp._core.core.ndarray, + valid_correspondence: cp._core.core.ndarray, + image_height: cp._core.core.ndarray, + image_width: cp._core.core.ndarray, + ): + + self.new_map *= 0 + config = self.param.subscriber_cfg[sub_key] + + for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): + sem_map_idx = self.get_index(channel) + + if fusion == "image_exponential": + self.average_correspondences_to_map_kernel( + self.semantic_map, + cp.uint64(sem_map_idx), + image[j], + uv_correspondence, + valid_correspondence, + image_height, + image_width, + self.new_map, + size=int(self.param.cell_n * self.param.cell_n), + ) + self.semantic_map[sem_map_idx] = self.new_map[sem_map_idx] + + elif fusion == "image_color": + self.color_correspondences_to_map_kernel( + self.semantic_map, + cp.uint64(sem_map_idx), + image, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + self.new_map, + size=int(self.param.cell_n * self.param.cell_n), + ) + self.semantic_map[sem_map_idx] = self.new_map[sem_map_idx] + + else: + raise ValueError("Fusion for image is unkown.") + def get_map_with_name(self, name): if self.layer_specs[name] == "color": m = self.get_rgb(name) @@ -232,16 +295,16 @@ def get_map_with_name(self, name): return m def get_rgb(self, name): - idx = self.param.additional_layers.index(name) - c = self.process_map_for_publish(self.map[idx]) + idx = self.layer_names.index(name) + c = self.process_map_for_publish(self.semantic_map[idx]) c = c.astype(np.float32) # c = xp.uint32(c.get()) # c.dtype = np.float32 return c def get_semantic(self, name): - idx = self.param.additional_layers.index(name) - c = self.process_map_for_publish(self.map[idx]) + idx = self.layer_names.index(name) + c = self.process_map_for_publish(self.semantic_map[idx]) return c def process_map_for_publish(self, input_map): @@ -249,4 +312,4 @@ def process_map_for_publish(self, input_map): return m[1:-1, 1:-1] def get_index(self, name): - return self.param.additional_layers.index(name) + return self.layer_names.index(name) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py index e7e36c19..0ed14ee7 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -89,9 +89,7 @@ def test_polygon_traversability(self, elmap_ex): def test_initialize_map(self, elmap_ex): methods = ["linear", "cubic", "nearest"] for method in methods: - points = np.array( - [[-4.0, 0.0, 0.0], [-4.0, 8.0, 1.0], [4.0, 8.0, 0.0], [4.0, 0.0, 0.0]] - ) + points = np.array([[-4.0, 0.0, 0.0], [-4.0, 8.0, 1.0], [4.0, 8.0, 0.0], [4.0, 0.0, 0.0]]) elmap_ex.initialize_map(points, method) def test_plugins(self, elmap_ex): diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_parameter.py index 9a12dee4..4c497349 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_parameter.py @@ -15,4 +15,3 @@ def test_parameter(): param.update() assert param.resolution == param.get_value("resolution") param.load_weights(param.weight_file) - diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py index 180aa9d5..9d6c41cf 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -28,8 +28,12 @@ def semmap_ex(add_lay, fusion_alg): @pytest.mark.parametrize( "add_lay, fusion_alg,channels", [ - (['grass','tree','fence','person'], ["class_average", "class_average", "class_average", "class_average"], ["grass"]), - (['grass','tree'], ["class_average", "class_average"], ['grass']), + ( + ["grass", "tree", "fence", "person"], + ["class_average", "class_average", "class_average", "class_average"], + ["grass"], + ), + (["grass", "tree"], ["class_average", "class_average"], ["grass"]), # ( # ["feat_0", "feat_1", "rgb"], # ["average", "average", "color"], @@ -41,7 +45,7 @@ def test_plugin_manager(semmap_ex, channels): manager = PluginManager(202) manager.load_plugin_settings(plugin_path) elevation_map = cp.zeros((7, 202, 202)).astype(cp.float32) - rotation = cp.eye(3,dtype=cp.float32) + rotation = cp.eye(3, dtype=cp.float32) layer_names = [ "elevation", "variance", @@ -57,10 +61,9 @@ def test_plugin_manager(semmap_ex, channels): manager.layers[0] manager.update_with_name("min_filter", elevation_map, layer_names) manager.update_with_name("smooth_filter", elevation_map, layer_names) - manager.update_with_name("semantic_filter", elevation_map, layer_names,semmap_ex,rotation) - manager.update_with_name("semantic_traversability", elevation_map, layer_names,semmap_ex) + manager.update_with_name("semantic_filter", elevation_map, layer_names, semmap_ex, rotation) + manager.update_with_name("semantic_traversability", elevation_map, layer_names, semmap_ex) manager.get_map_with_name("smooth") for lay in manager.get_layer_names(): - manager.update_with_name(lay,elevation_map,layer_names,semmap_ex,rotation) + manager.update_with_name(lay, elevation_map, layer_names, semmap_ex, rotation) manager.get_map_with_name(lay) - diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py index 86eba134..161bb203 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py @@ -18,31 +18,34 @@ def semmap_ex(add_lay, fusion_alg): additional_layers = dict(zip(p.additional_layers, p.fusion_algorithms)) p.cell_n = int(round(p.map_length / p.resolution)) + 2 - e = semantic_map.SemanticMap(p,additional_layers) + e = semantic_map.SemanticMap(p, additional_layers) return e + @pytest.mark.parametrize( "add_lay, fusion_alg,channels", - [(["feat_0", "feat_1"], ["average", "average"],["feat_0"]), - (["feat_0", "feat_1"], ["average", "average"],[]), - (["feat_0", "feat_1", "rgb"], ["average", "average", "color"],["rgb", "feat_0"]), - (["feat_0", "feat_1", "rgb"], ["class_average", "average", "color"], ["rgb", "feat_0"]), - (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0"]), - (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0", "feat_1"]), - ], + [ + (["feat_0", "feat_1"], ["average", "average"], ["feat_0"]), + (["feat_0", "feat_1"], ["average", "average"], []), + (["feat_0", "feat_1", "rgb"], ["average", "average", "color"], ["rgb", "feat_0"]), + (["feat_0", "feat_1", "rgb"], ["class_average", "average", "color"], ["rgb", "feat_0"]), + (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0"]), + (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0", "feat_1"]), + ], ) def test_fusion_of_pcl(semmap_ex, channels): fusion = semmap_ex.get_fusion_of_pcl(channels=channels) assert len(fusion) <= len(channels) - assert len(fusion)>0 or len(channels)==0 + assert len(fusion) > 0 or len(channels) == 0 assert all(isinstance(item, str) for item in fusion) @pytest.mark.parametrize( "add_lay, fusion_alg", - [(["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), - ], + [ + (["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), + ], ) @pytest.mark.parametrize("channels", [["rgb"], ["rgb", "feat_0"], []]) -def test_indices_fusion(semmap_ex, channels,fusion_alg): +def test_indices_fusion(semmap_ex, channels, fusion_alg): pcl_indices, layer_indices = semmap_ex.get_indices_fusion(pcl_channels=channels, fusion_alg=fusion_alg[0]) diff --git a/elevation_mapping_cupy/setup.py b/elevation_mapping_cupy/setup.py index 51954f5b..f225f03a 100644 --- a/elevation_mapping_cupy/setup.py +++ b/elevation_mapping_cupy/setup.py @@ -3,9 +3,10 @@ setup_args = generate_distutils_setup( packages=[ - 'elevation_mapping_cupy', - 'elevation_mapping_cupy.plugins', + "elevation_mapping_cupy", + "elevation_mapping_cupy.plugins", ], - package_dir={'': 'script'}) + package_dir={"": "script"}, +) setup(**setup_args) diff --git a/sensor_processing/debug_publisher/image_debug_node.py b/sensor_processing/debug_publisher/image_debug_node.py index 982ba83a..91743acb 100644 --- a/sensor_processing/debug_publisher/image_debug_node.py +++ b/sensor_processing/debug_publisher/image_debug_node.py @@ -24,7 +24,7 @@ def __init__(self): def image_callback(self, rgb_msg): img = self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8") out = np.zeros((img.shape[0],img.shape[1]), dtype=np.uint16) - out[:int(img.shape[0]/2)] = 1 + out[:, :int(img.shape[1]/2)] = 1 seg_msg = self.cv_bridge.cv2_to_imgmsg(out, encoding="mono16") seg_msg.header = rgb_msg.header self.debug_pub.publish(seg_msg) From 612c352da8f6eb3de973cf145441fd0b40f9da04 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Tue, 6 Dec 2022 17:59:39 -0800 Subject: [PATCH 287/504] updated cfg to default rgb version --- elevation_mapping_cupy/config/parameters.yaml | 2 +- .../config/sensor_parameter.yaml | 51 ++++++++----------- .../elevation_mapping_ros.py | 1 + .../kernels/custom_image_kernels.py | 28 +++++++--- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index 91a45819..57b6ea1d 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -78,7 +78,7 @@ publishers: fps: 2.0 semantic_map_raw: - layers: ['elevation', 'traversability', 'variance', 'single_channel_semantic'] + layers: ['elevation', 'traversability', 'variance', 'rgb_image'] basic_layers: ['elevation', 'traversability'] fps: 2.0 # elevation_map_recordable: diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index 2be606d2..abc12c58 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -1,42 +1,31 @@ subscribers: - # Single-channel or multi-channel input (Depth or RGB) - # Case 1: 1 channel image - into single semantic layer - # Case 2: 3 channel image - into 3 individual semantic layer - # Case 3: 3 channel image - into RGB color layer - - # Fusion: - # exponential averaging - # using neigborhodd to reduce artifacts - - # Collision checking during raycasting from map to camera - debug_rgb: fusion: ['image_color'] - topic_name_camera: /zed2i/zed_node/right/image + topic_name_camera: /zed2i/zed_node/left/image_rect_color topic_name_camera_info: /zed2i/zed_node/right/camera_info - channels: ["nice_rgb_channel"] + channels: ["rgb_image"] data_type: image - debug_rgb_3_seperate: - fusion: ['image_exponential','image_exponential','image_exponential'] - topic_name_camera: /zed2i/zed_node/right/image - topic_name_camera_info: /zed2i/zed_node/right/camera_info - channels: ["r_channel", "g_channel", "b_channel"] - data_type: image + # debug_rgb_3_seperate: + # fusion: ['image_exponential','image_exponential','image_exponential'] + # topic_name_camera: /zed2i/zed_node/right/image + # topic_name_camera_info: /zed2i/zed_node/right/camera_info + # channels: ["r_channel", "g_channel", "b_channel"] + # data_type: image - debug_rgb_2_seperate: - fusion: ['image_exponential', 'image_exponential'] - topic_name_camera: /zed2i/zed_node/right/image - topic_name_camera_info: /zed2i/zed_node/right/camera_info - channels: ["r_channel", "g_channel"] - data_type: image + # debug_rgb_2_seperate: + # fusion: ['image_exponential', 'image_exponential'] + # topic_name_camera: /zed2i/zed_node/left/image_rect_color + # topic_name_camera_info: /zed2i/zed_node/right/camera_info + # channels: ["r_channel", "g_channel"] + # data_type: image - debug_mono_exponential: - fusion: ['image_exponential'] - topic_name_camera: /debug_image - topic_name_camera_info: /zed2i/zed_node/right/camera_info - channels: ["single_channel_semantic"] - data_type: image + # debug_mono_exponential: + # fusion: ['image_exponential'] + # topic_name_camera: /debug_image + # topic_name_camera_info: /zed2i/zed_node/right/camera_info + # channels: ["single_channel_semantic"] + # data_type: image front_cam: channels: ['rgb'] diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index 71d322d6..b9e2a6e1 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -161,6 +161,7 @@ def image_callback(self, camera_msg, camera_info_msg, sub_key): R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") + semantic_img = [semantic_img[:, :, k] for k in range(3)] assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py index 75ff85c2..47770488 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py @@ -136,12 +136,14 @@ def average_correspondences_to_map_kernel(resolution, width, height): operation=string.Template( """ int cell_idx = get_map_idx(i, 0); - int target_idx = get_map_idx(i, map_idx); - int cell_idx_2 = get_map_idx(i, 1); if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; - new_sem_map[target_idx] = image_mono[idx]; + new_sem_map[get_map_idx(i, map_idx)] = image_mono[idx]; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; } + """ ).substitute(), name="average_correspondences_to_map_kernel", @@ -151,7 +153,7 @@ def average_correspondences_to_map_kernel(resolution, width, height): def color_correspondences_to_map_kernel(resolution, width, height): color_correspondences_to_map_kernel = cp.ElementwiseKernel( - in_params="raw U sem_map, raw W map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", out_params="raw U new_sem_map", preamble=string.Template( """ @@ -164,10 +166,22 @@ def color_correspondences_to_map_kernel(resolution, width, height): operation=string.Template( """ int cell_idx = get_map_idx(i, 0); - int cell_idx_2 = get_map_idx(i, 1); if (valid_correspondence[cell_idx]){ - int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; - new_sem_map[cell_idx] = image_rgb[idx]; + int cell_idx_2 = get_map_idx(i, 1); + + int idx_red = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + int idx_green = image_width * image_height + idx_red; + int idx_blue = image_width * image_height * 2 + idx_red; + + unsigned int r = image_rgb[idx_red]; + unsigned int g = image_rgb[idx_green]; + unsigned int b = image_rgb[idx_blue]; + + unsigned int rgb = (r<<16) + (g << 8) + b; + float rgb_ = __uint_as_float(rgb); + new_sem_map[get_map_idx(i, map_idx)] = rgb_; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; } """ ).substitute(), From e05a5d113c330c7a3b17acc86c2f07bbd4a0243f Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Wed, 7 Dec 2022 15:24:55 +0100 Subject: [PATCH 288/504] removed parameter logic from cpp --- elevation_mapping_cupy/config/parameters.yaml | 3 --- elevation_mapping_cupy/config/sensor_parameter.yaml | 1 + .../script/elevation_mapping_cupy/parameter.py | 11 ++++++++++- .../src/elevation_mapping_wrapper.cpp | 9 ++++----- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index 9d49f189..dc6e8752 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -63,9 +63,6 @@ use_only_above_for_upper_bound: false #### Plugins ######## plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/plugin_config.yaml' -#### Subscribers ######## - - #### Publishers ######## # topic_name: # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index defea85f..1c3ef4e0 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -1,3 +1,4 @@ +#### Subscribers ######## subscribers: # sensor_name: #if you have multiple sensors assign different names # channels: ['features','person'] # names of the channels, for sem seg it should be the same name as the diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 960eeea6..e90e6db3 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -13,7 +13,6 @@ class Parameter(Serializable): resolution: float = 0.04 additional_layers: list = ['feat_0'].copy fusion_algorithms: list = ['average'].copy - cell_n: int = None data_type: str = np.float32 average_weight: float = 0.5 @@ -75,6 +74,12 @@ class Parameter(Serializable): w3: np.ndarray = np.zeros((4, 1, 3, 3)) w_out: np.ndarray = np.zeros((1, 12, 1, 1)) + # # not configurable params + true_map_length: float = None + cell_n: int = None + true_cell_n: int = None + + def load_weights(self, filename): with open(filename, "rb") as file: weights = pickle.load(file) @@ -98,6 +103,10 @@ def get_value(self, name): def update(self): # +2 is a border for outside map self.cell_n = int(round(self.map_length / self.resolution)) + 2 + self.true_cell_n = round(self.map_length / self.resolution) + self.true_map_length = self.true_cell_n * self.resolution + + if __name__ == "__main__": param = Parameter() diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index a518117b..9d8fe968 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -79,12 +79,11 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh, std::vector(param_.attr("get_value")("resolution")); - map_length_ = py::cast(param_.attr("get_value")("map_length")); - map_n_ = static_cast(round(map_length_ / resolution_)); - map_length_ = resolution_ * map_n_; // get true length after rounding - param_.attr("update")(); + resolution_ = py::cast(param_.attr("get_value")("resolution")); + map_length_ = py::cast(param_.attr("get_value")("true_map_length")); + map_n_ = py::cast(param_.attr("get_value")("true_cell_n")); + ROS_WARN_STREAM(resolution_<("enable_normal", enable_normal_, false); nh.param("enable_normal_color", enable_normal_color_, false); From 06b5fafe4da9b9114834850a6caa4b24788da143 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Wed, 7 Dec 2022 17:47:06 +0100 Subject: [PATCH 289/504] added the dictionary for the subscribers, not perfect way to handle it --- .../script/elevation_mapping_cupy/parameter.py | 6 +++++- elevation_mapping_cupy/src/elevation_mapping_ros.cpp | 1 + elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp | 5 ++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index e90e6db3..9166ed12 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -6,7 +6,8 @@ import pickle import numpy as np from simple_parsing.helpers import Serializable - +import xml.etree.ElementTree as ET +import xmltodict @dataclass class Parameter(Serializable): @@ -78,6 +79,8 @@ class Parameter(Serializable): true_map_length: float = None cell_n: int = None true_cell_n: int = None + subscribers: ET = None + subscribers_dict: dict = None def load_weights(self, filename): @@ -105,6 +108,7 @@ def update(self): self.cell_n = int(round(self.map_length / self.resolution)) + 2 self.true_cell_n = round(self.map_length / self.resolution) self.true_map_length = self.true_cell_n * self.resolution + self.subscribers_dict = xmltodict.parse(self.subscribers) diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 236c04ea..42aa080b 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -63,6 +63,7 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) enablePointCloudPublishing_ = enablePointCloudPublishing; +// TODO in the longterm remove this and add it directly in the elevation map config std::vector additional_layers; std::vector fusion_algorithms; for (auto & subscriber : subscribers) { diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 9d8fe968..5f236f0b 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -76,6 +76,10 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh, std::vector(param_.attr("get_value")("resolution")); map_length_ = py::cast(param_.attr("get_value")("true_map_length")); map_n_ = py::cast(param_.attr("get_value")("true_cell_n")); - ROS_WARN_STREAM(resolution_<("enable_normal", enable_normal_, false); nh.param("enable_normal_color", enable_normal_color_, false); From 46e1009d8a3711fde9dc633b463111980bab612a Mon Sep 17 00:00:00 2001 From: Gian <43470810+gerni17@users.noreply.github.com> Date: Wed, 7 Dec 2022 18:51:20 +0100 Subject: [PATCH 290/504] Update requirements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 39e669bf..db7bcbbd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ opencv-python simple_parsing scikit-image matplotlib +xmltodict ###### Requirements with Version Specifiers ######` shapely==1.7.1 From 70baae786ac7fa6869b84d1b56bfee4ead95a9d7 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Thu, 8 Dec 2022 13:51:48 +0100 Subject: [PATCH 291/504] added parsing of xmlrpg in cpp and removed from python --- .../elevation_mapping_cupy/parameter.py | 7 +-- .../src/elevation_mapping_wrapper.cpp | 43 ++++++++++++++++++- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 3778543f..78d9a42a 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -6,8 +6,6 @@ import pickle import numpy as np from simple_parsing.helpers import Serializable -import xml.etree.ElementTree as ET -import xmltodict from dataclasses import field @dataclass @@ -80,8 +78,7 @@ class Parameter(Serializable): true_map_length: float = None cell_n: int = None true_cell_n: int = None - subscribers: ET = None - subscribers_dict: dict = None + subscribers: dict = None def load_weights(self, filename): @@ -109,8 +106,6 @@ def update(self): self.cell_n = int(round(self.map_length / self.resolution)) + 2 self.true_cell_n = round(self.map_length / self.resolution) self.true_map_length = self.true_cell_n * self.resolution - self.subscribers_dict = xmltodict.parse(self.subscribers) - if __name__ == "__main__": diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 5f236f0b..a1619e06 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -78,7 +78,48 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh, std::vector arr; + switch (val.getType()) { + case XmlRpc::XmlRpcValue::TypeString: + sub_dict[name][key] = static_cast(val); + break; + case XmlRpc::XmlRpcValue::TypeInt: + sub_dict[name][key] = static_cast(val); + break; + case XmlRpc::XmlRpcValue::TypeDouble: + sub_dict[name][key] = static_cast(val); + break; + case XmlRpc::XmlRpcValue::TypeBoolean: + sub_dict[name][key] = static_cast(val); + break; + case XmlRpc::XmlRpcValue::TypeArray: + for (int32_t i = 0; i < val.size(); ++i) { + auto elem = static_cast(val[i]); + arr.push_back(elem); + } + sub_dict[name][key] = arr; + arr.clear(); + break; + case XmlRpc::XmlRpcValue::TypeStruct: + break; + default: + sub_dict[name][key] = py::cast(val); + break; + } + } + } + param_.attr("subscribers") = sub_dict; param_.attr("set_value")("additional_layers",additional_layers); param_.attr("set_value")("fusion_algorithms",fusion_algorithms); From 20d6383c9160d35b9de22122fe04ebec28b8a14c Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Thu, 8 Dec 2022 14:51:14 +0100 Subject: [PATCH 292/504] removed parameter dependency --- .../elevation_mapping_wrapper.hpp | 4 ++-- .../elevation_mapping.py | 17 ++++++++++++++++- .../src/elevation_mapping_ros.cpp | 18 +----------------- .../src/elevation_mapping_wrapper.cpp | 9 +++------ 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index e03e705c..ef0681c4 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -43,7 +43,7 @@ class ElevationMappingWrapper { ElevationMappingWrapper(); - void initialize(ros::NodeHandle& nh, std::vector additional_layers, std::vector fusion_algorithms); + void initialize(ros::NodeHandle& nh); void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); @@ -61,7 +61,7 @@ class ElevationMappingWrapper { void addNormalColorLayer(grid_map::GridMap& map); private: - void setParameters(ros::NodeHandle& nh, std::vector additional_layers, std::vector fusion_algorithms); + void setParameters(ros::NodeHandle& nh); py::object map_; py::object param_; double resolution_; diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index e9a39a93..5ca8f6de 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -55,7 +55,22 @@ def __init__(self, param: Parameter): self.cell_n = param.cell_n self.map_lock = threading.Lock() - self.additional_layers = dict(zip(self.param.additional_layers, self.param.fusion_algorithms)) + # # get unique channels + semantic_layers = [] + fusion_algorithms = [] + for subscriber,sub_val in self.param.subscribers.items(): + + channels = sub_val["channels"] + fusion = sub_val["fusion"] + for i in range(len(channels)): + name = channels[i] + if name not in semantic_layers: + semantic_layers.append(name) + fusion_algorithms.append(fusion[i]) + self.param.additional_layers = semantic_layers + self.param.fusion_algorithms = fusion_algorithms + self.additional_layers = dict(zip(semantic_layers, fusion_algorithms)) + self.semantic_map = SemanticMap(self.param, self.additional_layers) self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n),dtype=self.data_type) self.layer_names = [ diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 42aa080b..44259ff1 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -63,29 +63,13 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) enablePointCloudPublishing_ = enablePointCloudPublishing; -// TODO in the longterm remove this and add it directly in the elevation map config - std::vector additional_layers; - std::vector fusion_algorithms; for (auto & subscriber : subscribers) { - auto channels = subscriber.second["channels"]; - auto fusion = subscriber.second["fusion"]; - for (int32_t i = 0; i < channels.size(); ++i) { - auto name = static_cast(channels[i]); - if (!std::count(additional_layers.begin(), additional_layers.end(), name)){ - additional_layers.push_back(name); - fusion_algorithms.push_back(static_cast(fusion[i])); - } - } - std::string pointcloud_topic = subscriber.second["topic_name"]; ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, &ElevationMappingNode::pointcloudCallback, this); pointcloudSubs_.push_back(sub); } - for (int i = 0; i < additional_layers.size(); ++i){ - ROS_INFO_STREAM("Additional layers " << additional_layers.at(i)<<" fusion algorithm "< additional_layers, std::vector fusion_algorithms) { +void ElevationMappingWrapper::initialize(ros::NodeHandle& nh) { // Add the elevation_mapping_cupy path to sys.path auto threading = py::module::import("threading"); py::gil_scoped_acquire acquire; @@ -34,7 +34,7 @@ void ElevationMappingWrapper::initialize(ros::NodeHandle& nh, std::vector additional_layers, std::vector fusion_algorithms) { +void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { // Get all parameters names and types. py::list paramNames = param_.attr("get_names")(); py::list paramTypes = param_.attr("get_types")(); @@ -121,9 +121,6 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh, std::vector(param_.attr("get_value")("resolution")); map_length_ = py::cast(param_.attr("get_value")("true_map_length")); From 77fff393165005c08c6218c38249ea9992732a8c Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Thu, 8 Dec 2022 15:36:56 +0100 Subject: [PATCH 293/504] fixed tests --- .../elevation_mapping.py | 16 ++--------- .../elevation_mapping_cupy/parameter.py | 27 +++++++++++++++++-- .../tests/test_elevation_mapping.py | 4 +-- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 5ca8f6de..72e820e3 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -56,20 +56,8 @@ def __init__(self, param: Parameter): self.map_lock = threading.Lock() # # get unique channels - semantic_layers = [] - fusion_algorithms = [] - for subscriber,sub_val in self.param.subscribers.items(): - - channels = sub_val["channels"] - fusion = sub_val["fusion"] - for i in range(len(channels)): - name = channels[i] - if name not in semantic_layers: - semantic_layers.append(name) - fusion_algorithms.append(fusion[i]) - self.param.additional_layers = semantic_layers - self.param.fusion_algorithms = fusion_algorithms - self.additional_layers = dict(zip(semantic_layers, fusion_algorithms)) + + self.additional_layers = dict(zip(self.param.additional_layers, self.param.fusion_algorithms)) self.semantic_map = SemanticMap(self.param, self.additional_layers) self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n),dtype=self.data_type) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 78d9a42a..41c2592e 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -8,9 +8,22 @@ from simple_parsing.helpers import Serializable from dataclasses import field +# todo add this for the future +@dataclass +class Subscriber(Serializable): + sensor_name: str = "front_cam" + channels: list = field(default_factory=lambda: ["feat_0"]) + fusion: list = field(default_factory=lambda: ["average"]) + topic_name: str = '/elevation_mapping/pointcloud_semantic' + +@dataclass +class Subscribers(Serializable): + front_cam: Subscriber = Subscriber + @dataclass class Parameter(Serializable): resolution: float = 0.04 + subscribers: dict = field(default_factory=lambda: {'front_cam': {'cam_frame': 'zed2i_right_camera_optical_frame', 'cam_info_topic': '/zed2i/zed_node/depth/camera_info', 'channels': ['rgb', 'person'], 'confidence': True, 'confidence_threshold': 10, 'confidence_topic': '/zed2i/zed_node/confidence/confidence_map', 'depth_topic': '/zed2i/zed_node/depth/depth_registered', 'feature_extractor': False, 'fusion': ['color', 'class_average'], 'image_topic': '/zed2i/zed_node/left/image_rect_color', 'segmentation_model': 'lraspp_mobilenet_v3_large', 'semantic_segmentation': True, 'show_label_legend': True, 'topic_name': '/elvation_mapping/pointcloud_semantic'}}) additional_layers: list = field(default_factory=lambda: ["feat_0"]) fusion_algorithms: list = field(default_factory=lambda: ["average"]) data_type: str = np.float32 @@ -78,8 +91,6 @@ class Parameter(Serializable): true_map_length: float = None cell_n: int = None true_cell_n: int = None - subscribers: dict = None - def load_weights(self, filename): with open(filename, "rb") as file: @@ -106,6 +117,18 @@ def update(self): self.cell_n = int(round(self.map_length / self.resolution)) + 2 self.true_cell_n = round(self.map_length / self.resolution) self.true_map_length = self.true_cell_n * self.resolution + semantic_layers = [] + fusion_algorithms = [] + for subscriber,sub_val in self.subscribers.items(): + channels = sub_val["channels"] + fusion = sub_val["fusion"] + for i in range(len(channels)): + name = channels[i] + if name not in semantic_layers: + semantic_layers.append(name) + fusion_algorithms.append(fusion[i]) + self.additional_layers = semantic_layers + self.fusion_algorithms = fusion_algorithms if __name__ == "__main__": diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py index 45d22609..cbe869b2 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -27,8 +27,8 @@ def elmap_ex(add_lay, fusion_alg): weight_file="../../../config/weights.dat", plugin_config_file="../../../config/plugin_config.yaml", ) - p.additional_layers = additional_layer - p.fusion_algorithms = fusion_algorithms + p.subscribers["front_cam"]["channels"] = additional_layer + p.subscribers["front_cam"]["fusion"] = fusion_algorithms p.update() e = elevation_mapping.ElevationMap(p) return e From 50bfd19b160b24950b51a11613d59e4de330919c Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Fri, 9 Dec 2022 15:22:13 +0100 Subject: [PATCH 294/504] workin cpp wrapper with jonas stuff and gians latest stuff --- .../config/sensor_parameter.yaml | 5 ++ .../elevation_mapping_ros.hpp | 2 +- .../elevation_mapping_wrapper.hpp | 2 +- .../elevation_mapping_cupy/parameter.py | 6 +- .../src/elevation_mapping_ros.cpp | 37 ++++---- .../src/elevation_mapping_wrapper.cpp | 89 +++++++++---------- .../semantic_pointcloud/pointcloud_node.py | 23 ++--- 7 files changed, 84 insertions(+), 80 deletions(-) diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index 61078e2d..beefa91c 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -6,6 +6,11 @@ subscribers: topic_name_camera_info: /zed2i/zed_node/right/camera_info channels: ["rgb_image"] data_type: image + fusion_types: + array_fusion: [] + channels: [] + + # debug_rgb_3_seperate: # fusion: ['image_exponential','image_exponential','image_exponential'] diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 1aea9e0b..db262e41 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -72,7 +72,7 @@ class ElevationMappingNode { void readParameters(); void setupMapPublishers(); void pointcloudCallback(const sensor_msgs::PointCloud2& cloud); - void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::vector& channels); + void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::string& key); void publishAsPointCloud(const grid_map::GridMap& map) const; bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response); diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index e5b3ba34..5a8e1cf1 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -48,7 +48,7 @@ class ElevationMappingWrapper { void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); - void input_image(const std::vector& image, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, + void input_image(const std::string& key, const std::vector& image, const RowMatrixXd& R, const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, int height, int width); void move_to(const Eigen::VectorXd& p, const RowMatrixXd& R); void clear(); diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index f9155144..ab9af4d1 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -23,10 +23,8 @@ class Subscribers(Serializable): @dataclass class Parameter(Serializable): # todo: fix subscriber - subscriber_cfg: dict = field(default_factory=lambda: {}) - resolution: float = 0.04 - subscribers: dict = field(default_factory=lambda: {'front_cam': {'cam_frame': 'zed2i_right_camera_optical_frame', 'cam_info_topic': '/zed2i/zed_node/depth/camera_info', 'channels': ['rgb', 'person'], 'confidence': True, 'confidence_threshold': 10, 'confidence_topic': '/zed2i/zed_node/confidence/confidence_map', 'depth_topic': '/zed2i/zed_node/depth/depth_registered', 'feature_extractor': False, 'fusion': ['color', 'class_average'], 'image_topic': '/zed2i/zed_node/left/image_rect_color', 'segmentation_model': 'lraspp_mobilenet_v3_large', 'semantic_segmentation': True, 'show_label_legend': True, 'topic_name': '/elvation_mapping/pointcloud_semantic'}}) + subscriber_cfg: dict = field(default_factory=lambda: {'front_cam': {'cam_frame': 'zed2i_right_camera_optical_frame', 'cam_info_topic': '/zed2i/zed_node/depth/camera_info', 'channels': ['rgb', 'person'], 'confidence': True, 'confidence_threshold': 10, 'confidence_topic': '/zed2i/zed_node/confidence/confidence_map', 'depth_topic': '/zed2i/zed_node/depth/depth_registered', 'feature_extractor': False, 'fusion': ['color', 'class_average'], 'image_topic': '/zed2i/zed_node/left/image_rect_color', 'segmentation_model': 'lraspp_mobilenet_v3_large', 'semantic_segmentation': True, 'show_label_legend': True, 'topic_name': '/elvation_mapping/pointcloud_semantic'}}) additional_layers: list = field(default_factory=lambda: ["feat_0"]) fusion_algorithms: list = field(default_factory=lambda: ["average"]) data_type: str = np.float32 @@ -122,7 +120,7 @@ def update(self): self.true_map_length = self.true_cell_n * self.resolution semantic_layers = [] fusion_algorithms = [] - for subscriber,sub_val in self.subscribers.items(): + for subscriber,sub_val in self.subscriber_cfg.items(): channels = sub_val["channels"] fusion = sub_val["fusion"] for i in range(len(channels)): diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index e4165f27..de9314a9 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -73,19 +73,9 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) // Iterate all the subscribers // here we have to remove all the stuff for (auto & subscriber : subscribers) { - auto channels = subscriber.second["channels"]; - auto fusion = subscriber.second["fusion"]; + std::string key = subscriber.first; auto type = static_cast(subscriber.second["data_type"]); - std::vector channels_str; - - for (int32_t i = 0; i < channels.size(); ++i) { - auto name = static_cast(channels[i]); - channels_str.push_back(name); - if (!std::count(additional_layers.begin(), additional_layers.end(), name)){ - additional_layers.push_back(name); - fusion_algorithms.push_back(static_cast(fusion[i])); - } - } + // Initialize subscribers depending on the type if (type == "pointcloud") { @@ -103,7 +93,7 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) cameraInfoSubs_.push_back(cam_info_sub); CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); - sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2, channels_str)); + sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2, key)); cameraSyncs_.push_back(sync); } else { @@ -112,9 +102,6 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) } } - for (int i = 0; i < additional_layers.size(); ++i){ - ROS_INFO_STREAM("Additional layers " << additional_layers.at(i) << " fusion algorithm "<& channels) { +void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::string& key) { auto start = ros::Time::now(); // Get image @@ -368,12 +355,26 @@ void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image multichannel_image.push_back(eigen_image_g); multichannel_image.push_back(eigen_image_b); + } else if (image.channels() == 4) { + cv::Mat bgr[4]; + cv::split(image, bgr); + ColMatrixXf eigen_image_b; + cv::cv2eigen(bgr[0], eigen_image_b); + ColMatrixXf eigen_image_g; + cv::cv2eigen(bgr[1], eigen_image_g); + ColMatrixXf eigen_image_r; + cv::cv2eigen(bgr[2], eigen_image_r); + + multichannel_image.push_back(eigen_image_r); + multichannel_image.push_back(eigen_image_g); + multichannel_image.push_back(eigen_image_b); + } else { ROS_WARN_STREAM("Invalid number of channels [" << image.channels() << "]. Only allowed 1 (mono) or 3 (rgb)"); } // Pass image to pipeline - map_.input_image(multichannel_image, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), cameraMatrix, image.rows, image.cols); + map_.input_image(key, multichannel_image, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), cameraMatrix, image.rows, image.cols); ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); } diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 478c4709..1e5541ed 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -79,47 +79,47 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { XmlRpc::XmlRpcValue subscribers; nh.getParam("subscribers", subscribers); - py::dict sub_dict; - for (auto & subscriber : subscribers) { - const char *const name = subscriber.first.c_str(); - const auto & subscriber_params = subscriber.second; - if (!sub_dict.contains(name)) { - sub_dict[name] = py::dict(); - } - for(auto iterat : subscriber_params){ - const char *const key = iterat.first.c_str(); - const auto val = iterat.second; - std::vector arr; - switch (val.getType()) { - case XmlRpc::XmlRpcValue::TypeString: - sub_dict[name][key] = static_cast(val); - break; - case XmlRpc::XmlRpcValue::TypeInt: - sub_dict[name][key] = static_cast(val); - break; - case XmlRpc::XmlRpcValue::TypeDouble: - sub_dict[name][key] = static_cast(val); - break; - case XmlRpc::XmlRpcValue::TypeBoolean: - sub_dict[name][key] = static_cast(val); - break; - case XmlRpc::XmlRpcValue::TypeArray: - for (int32_t i = 0; i < val.size(); ++i) { - auto elem = static_cast(val[i]); - arr.push_back(elem); - } - sub_dict[name][key] = arr; - arr.clear(); - break; - case XmlRpc::XmlRpcValue::TypeStruct: - break; - default: - sub_dict[name][key] = py::cast(val); - break; - } - } + py::dict sub_dict; + for (auto & subscriber : subscribers) { + const char *const name = subscriber.first.c_str(); + const auto & subscriber_params = subscriber.second; + if (!sub_dict.contains(name)) { + sub_dict[name] = py::dict(); + } + for(auto iterat : subscriber_params){ + const char *const key = iterat.first.c_str(); + const auto val = iterat.second; + std::vector arr; + switch (val.getType()) { + case XmlRpc::XmlRpcValue::TypeString: + sub_dict[name][key] = static_cast(val); + break; + case XmlRpc::XmlRpcValue::TypeInt: + sub_dict[name][key] = static_cast(val); + break; + case XmlRpc::XmlRpcValue::TypeDouble: + sub_dict[name][key] = static_cast(val); + break; + case XmlRpc::XmlRpcValue::TypeBoolean: + sub_dict[name][key] = static_cast(val); + break; + case XmlRpc::XmlRpcValue::TypeArray: + for (int32_t i = 0; i < val.size(); ++i) { + auto elem = static_cast(val[i]); + arr.push_back(elem); + } + sub_dict[name][key] = arr; + arr.clear(); + break; + case XmlRpc::XmlRpcValue::TypeStruct: + break; + default: + sub_dict[name][key] = py::cast(val); + break; } - param_.attr("subscribers") = sub_dict; + } + } + param_.attr("subscriber_cfg") = sub_dict; param_.attr("update")(); resolution_ = py::cast(param_.attr("get_value")("resolution")); @@ -137,17 +137,16 @@ void ElevationMappingWrapper::input(const RowMatrixXd& points, const std::vector positionNoise, orientationNoise); } -void ElevationMappingWrapper::input_image(const std::vector& multichannel_image, - const std::vector& channels, +void ElevationMappingWrapper::input_image(const std::string& key, const std::vector& multichannel_image, const RowMatrixXd& R, const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, int height, int width) { py::gil_scoped_acquire acquire; - map_.attr("input_image")(multichannel_image, - channels, - Eigen::Ref(R), + map_.attr("input_image")(key, + multichannel_image, + Eigen::Ref(R), Eigen::Ref(t), Eigen::Ref(cameraMatrix), height, diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index 1a96ec3e..51341abd 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -76,17 +76,18 @@ def __init__(self, sensor_name): ts.registerCallback(self.image_callback) self.pcl_pub = rospy.Publisher(self.param.topic_name, PointCloud2, queue_size=2) - if self.param.publish_segmentation_image: - self.seg_pub = rospy.Publisher( - self.param.segmentation_image_topic, Image, queue_size=2 - ) - if "class_max" in self.param.fusion: - self.labels = self.semantic_model["model"].get_classes() - else: - self.labels = list(self.segmentation_channels.keys()) - self.semseg_color_map = self.color_map(len(self.labels)) - if self.param.show_label_legend: - self.color_map_viz() + if self.param.semantic_segmentation: + if self.param.publish_segmentation_image: + self.seg_pub = rospy.Publisher( + self.param.segmentation_image_topic, Image, queue_size=2 + ) + if "class_max" in self.param.fusion: + self.labels = self.semantic_model["model"].get_classes() + else: + self.labels = list(self.segmentation_channels.keys()) + self.semseg_color_map = self.color_map(len(self.labels)) + if self.param.show_label_legend: + self.color_map_viz() def color_map(self, N=256, normalized=False): def bitget(byteval, idx): From 9a493860b31fe344d44469b906335cf8ee7c1be8 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Fri, 9 Dec 2022 17:14:16 +0100 Subject: [PATCH 295/504] passing all tests and also working with lonomy configurations --- .../elevation_mapping_cupy/parameter.py | 31 +++++++++-- .../plugins/semantic_filter.py | 2 +- .../plugins/semantic_traversability.py | 6 ++- .../elevation_mapping_cupy/semantic_map.py | 53 ++++++++++++++----- .../tests/test_elevation_mapping.py | 4 +- .../tests/test_plugins.py | 30 ++++++----- .../tests/test_semantic_map.py | 19 +++---- requirements.txt | 1 - .../tests/test_pointcloud.py | 27 ++++++---- 9 files changed, 115 insertions(+), 58 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index ab9af4d1..6a307208 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -14,18 +14,40 @@ class Subscriber(Serializable): sensor_name: str = "front_cam" channels: list = field(default_factory=lambda: ["feat_0"]) fusion: list = field(default_factory=lambda: ["average"]) - topic_name: str = '/elevation_mapping/pointcloud_semantic' + topic_name: str = "/elevation_mapping/pointcloud_semantic" + @dataclass class Subscribers(Serializable): front_cam: Subscriber = Subscriber + @dataclass class Parameter(Serializable): # todo: fix subscriber resolution: float = 0.04 - subscriber_cfg: dict = field(default_factory=lambda: {'front_cam': {'cam_frame': 'zed2i_right_camera_optical_frame', 'cam_info_topic': '/zed2i/zed_node/depth/camera_info', 'channels': ['rgb', 'person'], 'confidence': True, 'confidence_threshold': 10, 'confidence_topic': '/zed2i/zed_node/confidence/confidence_map', 'depth_topic': '/zed2i/zed_node/depth/depth_registered', 'feature_extractor': False, 'fusion': ['color', 'class_average'], 'image_topic': '/zed2i/zed_node/left/image_rect_color', 'segmentation_model': 'lraspp_mobilenet_v3_large', 'semantic_segmentation': True, 'show_label_legend': True, 'topic_name': '/elvation_mapping/pointcloud_semantic'}}) - additional_layers: list = field(default_factory=lambda: ["feat_0"]) + subscriber_cfg: dict = field( + default_factory=lambda: { + "front_cam": { + "cam_frame": "zed2i_right_camera_optical_frame", + "cam_info_topic": "/zed2i/zed_node/depth/camera_info", + "channels": ["rgb", "person"], + "confidence": True, + "confidence_threshold": 10, + "confidence_topic": "/zed2i/zed_node/confidence/confidence_map", + "depth_topic": "/zed2i/zed_node/depth/depth_registered", + "feature_extractor": False, + "fusion": ["color", "class_average"], + "image_topic": "/zed2i/zed_node/left/image_rect_color", + "segmentation_model": "lraspp_mobilenet_v3_large", + "semantic_segmentation": True, + "show_label_legend": True, + "topic_name": "/elvation_mapping/pointcloud_semantic", + "data_type": "pointcloud", + } + } + ) + additional_layers: list = field(default_factory=lambda: ["feat_0"]) fusion_algorithms: list = field(default_factory=lambda: ["average"]) data_type: str = np.float32 average_weight: float = 0.5 @@ -120,7 +142,7 @@ def update(self): self.true_map_length = self.true_cell_n * self.resolution semantic_layers = [] fusion_algorithms = [] - for subscriber,sub_val in self.subscriber_cfg.items(): + for subscriber, sub_val in self.subscriber_cfg.items(): channels = sub_val["channels"] fusion = sub_val["fusion"] for i in range(len(channels)): @@ -132,7 +154,6 @@ def update(self): self.fusion_algorithms = fusion_algorithms - if __name__ == "__main__": param = Parameter() print(param) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index 97c46ab1..cc797410 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -91,7 +91,7 @@ def __call__( # check which has the highest value # todo we are using the new_map because of the bayesian class_map = cp.amax(semantic_map.new_map[layer_indices], axis=0) - class_map_id = cp.argmax(semantic_map.map[layer_indices], axis=0) + class_map_id = cp.argmax(semantic_map.semantic_map[layer_indices], axis=0) if "class_max" in semantic_map.param.fusion_algorithms: # todo here is only cosidered the case where we only have one max diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py index 17a15277..f54c714c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py @@ -63,12 +63,14 @@ def __call__( tempo = elevation_map[idx] elif name in semantic_map.param.additional_layers: idx = semantic_map.param.additional_layers.index(name) - tempo = semantic_map.map[idx] + tempo = semantic_map.semantic_map[idx] elif name in plugin_layer_names: idx = plugin_layer_names.index(name) tempo = plugin_layers[idx] else: - print("Layer {} is not in the map, returning traversabiltiy!".format(name)) + print( + "Layer {} is not in the map, returning traversabiltiy!".format(name) + ) return if self.type[it] == "traversability": tempo = cp.where(tempo <= self.thresholds[it], 1, 0) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index df6a000c..e7792405 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -2,10 +2,22 @@ import cupy as cp import numpy as np from typing import List -from elevation_mapping_cupy.kernels import sum_kernel, add_color_kernel, color_average_kernel,bayesian_inference_kernel +from elevation_mapping_cupy.kernels import ( + sum_kernel, + add_color_kernel, + color_average_kernel, + bayesian_inference_kernel, +) from elevation_mapping_cupy.kernels import sum_compact_kernel, sum_max_kernel -from elevation_mapping_cupy.kernels import average_kernel, class_average_kernel, alpha_kernel -from elevation_mapping_cupy.kernels import average_correspondences_to_map_kernel, color_correspondences_to_map_kernel +from elevation_mapping_cupy.kernels import ( + average_kernel, + class_average_kernel, + alpha_kernel, +) +from elevation_mapping_cupy.kernels import ( + average_correspondences_to_map_kernel, + color_correspondences_to_map_kernel, +) xp = cp @@ -32,7 +44,9 @@ def __init__(self, param: Parameter): self.layer_names.append(c) self.layer_specs[c] = f else: - assert self.layer_specs[c] == f, "Error: Single layer has multiple fusion algorithms!" + assert ( + self.layer_specs[c] == f + ), "Error: Single layer has multiple fusion algorithms!" if f not in self.unique_fusion: self.unique_fusion.append(f) @@ -99,7 +113,9 @@ def compile_kernels(self) -> None: self.param.cell_n, self.param.cell_n, ) - self.color_average_kernel = color_average_kernel(self.param.cell_n, self.param.cell_n) + self.color_average_kernel = color_average_kernel( + self.param.cell_n, self.param.cell_n + ) if "class_average" in self.unique_fusion: print("Initialize class average kernel") self.sum_kernel = sum_kernel( @@ -134,13 +150,21 @@ def compile_kernels(self) -> None: self.unique_id = cp.array([0]) if "image_exponential" in self.unique_fusion: - self.average_correspondences_to_map_kernel = average_correspondences_to_map_kernel( - resolution=self.param.resolution, width=self.param.cell_n, height=self.param.cell_n + self.average_correspondences_to_map_kernel = ( + average_correspondences_to_map_kernel( + resolution=self.param.resolution, + width=self.param.cell_n, + height=self.param.cell_n, + ) ) if "image_color" in self.unique_fusion: - self.color_correspondences_to_map_kernel = color_correspondences_to_map_kernel( - resolution=self.param.resolution, width=self.param.cell_n, height=self.param.cell_n + self.color_correspondences_to_map_kernel = ( + color_correspondences_to_map_kernel( + resolution=self.param.resolution, + width=self.param.cell_n, + height=self.param.cell_n, + ) ) def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: @@ -227,7 +251,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): elevation_map, self.new_map, self.sum_mean, - self.map, + self.semantic_map, size=(self.param.cell_n * self.param.cell_n), ) if "class_average" in additional_fusion: @@ -269,7 +293,9 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) # do not divide by zero sum_alpha[sum_alpha == 0] = 1 - self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) + self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims( + sum_alpha, axis=0 + ) # assert cp.unique(cp.sum(self.map[layer_ids], axis=0)) equal to zero or to nan if "class_max" in additional_fusion: @@ -368,7 +394,9 @@ def update_layers_image( self.new_map *= 0 config = self.param.subscriber_cfg[sub_key] - for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): + for j, (fusion, channel) in enumerate( + zip(config["fusion"], config["channels"]) + ): sem_map_idx = self.get_index(channel) if fusion == "image_exponential": @@ -401,6 +429,7 @@ def update_layers_image( else: raise ValueError("Fusion for image is unkown.") + def decode_max(self, mer): mer = mer.astype(cp.float32) mer = mer.view(dtype=cp.uint32) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py index 1ad01c22..550713b7 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -27,8 +27,8 @@ def elmap_ex(add_lay, fusion_alg): weight_file="../../../config/weights.dat", plugin_config_file="../../../config/plugin_config.yaml", ) - p.subscribers["front_cam"]["channels"] = additional_layer - p.subscribers["front_cam"]["fusion"] = fusion_algorithms + p.subscriber_cfg["front_cam"]["channels"] = additional_layer + p.subscriber_cfg["front_cam"]["fusion"] = fusion_algorithms p.update() e = elevation_mapping.ElevationMap(p) return e diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py index 3a7f6611..0a040ea1 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -9,19 +9,15 @@ @pytest.fixture() def semmap_ex(add_lay, fusion_alg): - additional_layer = add_lay - fusion_algorithms = fusion_alg p = parameter.Parameter( use_chainer=False, weight_file="../../../config/weights.dat", plugin_config_file=plugin_path, ) - p.additional_layers = additional_layer - p.fusion_algorithms = fusion_algorithms - additional_layers = dict(zip(p.additional_layers, p.fusion_algorithms)) - p.cell_n = int(round(p.map_length / p.resolution)) + 2 - - e = semantic_map.SemanticMap(p, additional_layers) + p.additional_layers = add_lay + p.fusion_algorithms = fusion_alg + p.update() + e = semantic_map.SemanticMap(p) e.compile_kernels() return e @@ -29,9 +25,13 @@ def semmap_ex(add_lay, fusion_alg): @pytest.mark.parametrize( "add_lay, fusion_alg,channels", [ - (['grass','tree','fence','person'], ["class_average", "class_average", "class_average", "class_average"], ["grass"]), - (['grass','tree'], ["class_average", "class_average"], ['grass']), - (['grass','tree'], ["class_average", "class_max"], ['tree']), + ( + ["grass", "tree", "fence", "person"], + ["class_average", "class_average", "class_average", "class_average"], + ["grass"], + ), + (["grass", "tree"], ["class_average", "class_average"], ["grass"]), + (["grass", "tree"], ["class_average", "class_max"], ["tree"]), # ( # ["feat_0", "feat_1", "rgb"], # ["average", "average", "color"], @@ -59,8 +59,12 @@ def test_plugin_manager(semmap_ex, channels): manager.layers[0] manager.update_with_name("min_filter", elevation_map, layer_names) manager.update_with_name("smooth_filter", elevation_map, layer_names) - manager.update_with_name("semantic_filter", elevation_map, layer_names, semmap_ex, rotation) - manager.update_with_name("semantic_traversability", elevation_map, layer_names, semmap_ex) + manager.update_with_name( + "semantic_filter", elevation_map, layer_names, semmap_ex, rotation + ) + manager.update_with_name( + "semantic_traversability", elevation_map, layer_names, semmap_ex + ) manager.get_map_with_name("smooth") for lay in manager.get_layer_names(): manager.update_with_name(lay, elevation_map, layer_names, semmap_ex, rotation) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py index c8376d73..a63723fa 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py @@ -5,25 +5,22 @@ @pytest.fixture() -def semmap_ex(add_lay, fusion_alg): - additional_layer = add_lay - fusion_algorithms = fusion_alg +def semmap_ex(sem_lay, fusion_alg): p = parameter.Parameter( use_chainer=False, weight_file="../../../config/weights.dat", plugin_config_file="../../../config/plugin_config.yaml", ) - p.additional_layers = additional_layer - p.fusion_algorithms = fusion_algorithms - additional_layers = dict(zip(p.additional_layers, p.fusion_algorithms)) - p.cell_n = int(round(p.map_length / p.resolution)) + 2 - - e = semantic_map.SemanticMap(p, additional_layers) + for subs, value in p.subscriber_cfg.items(): + value["channels"] = sem_lay + value["fusion"] = fusion_alg + p.update() + e = semantic_map.SemanticMap(p) return e @pytest.mark.parametrize( - "add_lay, fusion_alg,channels", + "sem_lay, fusion_alg,channels", [ (["feat_0", "feat_1"], ["average", "average"], ["feat_0"]), (["feat_0", "feat_1"], ["average", "average"], []), @@ -62,7 +59,7 @@ def test_fusion_of_pcl(semmap_ex, channels): @pytest.mark.parametrize( - "add_lay, fusion_alg", + "sem_lay, fusion_alg", [ (["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), ], diff --git a/requirements.txt b/requirements.txt index db7bcbbd..39e669bf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,6 @@ opencv-python simple_parsing scikit-image matplotlib -xmltodict ###### Requirements with Version Specifiers ######` shapely==1.7.1 diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py index 8273467f..01ec9bad 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py @@ -5,9 +5,12 @@ """This test file only works if ros is installed """ + + @pytest.fixture() def pointcloud_ex(cam_name): node = PointcloudNode(cam_name) + node.initialize_semantics() return node @@ -24,18 +27,20 @@ def test_initialize_semantics(pointcloud_ex): @pytest.mark.parametrize( "cam_name", [ - "front_cam", + ("front_cam"), ], ) def test_pub_seg(pointcloud_ex): # TODO we have to encode the max class other wise it is going to make problem - amount = len( - pointcloud_ex.segmentation_channels.keys() - ) + pointcloud_ex.param.fusion.count("max_class") - if "class_max" in pointcloud_ex.param.fusion: - val = cp.random.rand(amount, 360, 640, dtype=cp.float32).astype(cp.float16) - ind = cp.random.randint(0, 2, (amount, 360, 640), dtype=cp.uint32).astype(cp.float32) - prob = encode_max(val, ind) - else: - prob = cp.random.rand(amount, 360, 640) - pointcloud_ex.publish_segmentation_image(prob) + if pointcloud_ex.param.semantic_segmentation: + seg_chan = len(pointcloud_ex.segmentation_channels.keys()) + amount = seg_chan + pointcloud_ex.param.fusion.count("max_class") + if "class_max" in pointcloud_ex.param.fusion: + val = cp.random.rand(amount, 360, 640, dtype=cp.float32).astype(cp.float16) + ind = cp.random.randint(0, 2, (amount, 360, 640), dtype=cp.uint32).astype( + cp.float32 + ) + prob = encode_max(val, ind) + else: + prob = cp.random.rand(amount, 360, 640) + pointcloud_ex.publish_segmentation_image(prob) From 0381e6aab1d584b5bb37ad13f866ae4e9dcaee3b Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Fri, 9 Dec 2022 17:15:32 +0100 Subject: [PATCH 296/504] add dev branches to workflow --- .github/workflows/python-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index de9a6a47..23f732bf 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -4,7 +4,7 @@ name: Python testing on: push: - branches: [ "feature/2_semantic_python", "feature/**"] + branches: [ "feature/2_semantic_python", "feature/**","dev/**"] # pull_request: # branches: [ "main" ] From 506ab3a181954df2aeed95ce27d002e3bce7cbdd Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Fri, 9 Dec 2022 17:42:13 +0100 Subject: [PATCH 297/504] split kernel files, and moved all semantic logic to semantic map class --- .../elevation_mapping.py | 202 +++++++--- .../kernels/__init__.py | 1 + .../kernels/custom_kernels.py | 378 ------------------ .../kernels/custom_semantic_kernels.py | 376 +++++++++++++++++ .../elevation_mapping_cupy/semantic_map.py | 46 ++- 5 files changed, 570 insertions(+), 433 deletions(-) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 017e2640..5a68edb1 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -9,10 +9,17 @@ import threading import subprocess -from elevation_mapping_cupy.traversability_filter import get_filter_chainer, get_filter_torch +from elevation_mapping_cupy.traversability_filter import ( + get_filter_chainer, + get_filter_torch, +) from elevation_mapping_cupy.parameter import Parameter -from elevation_mapping_cupy.kernels import add_points_kernel, add_color_kernel, color_average_kernel +from elevation_mapping_cupy.kernels import ( + add_points_kernel, + add_color_kernel, + color_average_kernel, +) from elevation_mapping_cupy.kernels import sum_kernel from elevation_mapping_cupy.kernels import error_counting_kernel from elevation_mapping_cupy.kernels import average_map_kernel @@ -61,7 +68,9 @@ def __init__(self, param: Parameter): self.map_lock = threading.Lock() self.semantic_map = SemanticMap(self.param) - self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n), dtype=self.data_type) + self.elevation_map = xp.zeros( + (7, self.cell_n, self.cell_n), dtype=self.data_type + ) self.layer_names = [ "elevation", "variance", @@ -100,17 +109,25 @@ def __init__(self, param: Parameter): param.load_weights(weight_file) if param.use_chainer: - self.traversability_filter = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) + self.traversability_filter = get_filter_chainer( + param.w1, param.w2, param.w3, param.w_out + ) else: - self.traversability_filter = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) + self.traversability_filter = get_filter_torch( + param.w1, param.w2, param.w3, param.w_out + ) self.untraversable_polygon = xp.zeros((1, 2)) # Plugins self.plugin_manager = PluginManager(cell_n=self.cell_n) - plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') + plugin_config_file = subprocess.getoutput( + 'echo "' + param.plugin_config_file + '"' + ) self.plugin_manager.load_plugin_settings(plugin_config_file) - self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") + self.map_initializer = MapInitializer( + self.initial_variance, param.initialized_variance, xp=cp, method="points" + ) def clear(self): """Reset all the layers of the elevation & the semantic map.""" @@ -206,11 +223,10 @@ def shift_map_xy(self, delta_pixel): with self.map_lock: self.elevation_map = cp.roll(self.elevation_map, shift_value, axis=(1, 2)) self.pad_value(self.elevation_map, shift_value, value=0.0) - self.pad_value(self.elevation_map, shift_value, idx=1, value=self.initial_variance) - - # TODO: This in general is not best practice. This should be layered - self.semantic_map.semantic_map = cp.roll(self.semantic_map.semantic_map, shift_value, axis=(1, 2)) - self.pad_value(self.semantic_map.semantic_map, shift_value, value=0.0) + self.pad_value( + self.elevation_map, shift_value, idx=1, value=self.initial_variance + ) + self.semantic_map.shift_map_xy(shift_value) def shift_map_z(self, delta_z): """Shift the relevant layers along the vertical axis. @@ -227,11 +243,20 @@ def shift_map_z(self, delta_z): def compile_kernels(self): """Compile all kernels belonging to the elevation map.""" # Compile custom cuda kernels. - self.new_map = cp.zeros((self.elevation_map.shape[0], self.cell_n, self.cell_n), dtype=self.data_type) - self.traversability_input = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) - self.traversability_mask_dummy = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + self.new_map = cp.zeros( + (self.elevation_map.shape[0], self.cell_n, self.cell_n), + dtype=self.data_type, + ) + self.traversability_input = cp.zeros( + (self.cell_n, self.cell_n), dtype=self.data_type + ) + self.traversability_mask_dummy = cp.zeros( + (self.cell_n, self.cell_n), dtype=self.data_type + ) self.min_filtered = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) - self.min_filtered_mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + self.min_filtered_mask = cp.zeros( + (self.cell_n, self.cell_n), dtype=self.data_type + ) self.mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) self.add_points_kernel = add_points_kernel( self.resolution, @@ -270,12 +295,18 @@ def compile_kernels(self): self.cell_n, self.cell_n, self.param.max_variance, self.initial_variance ) - self.dilation_filter_kernel = dilation_filter_kernel(self.cell_n, self.cell_n, self.param.dilation_size) + self.dilation_filter_kernel = dilation_filter_kernel( + self.cell_n, self.cell_n, self.param.dilation_size + ) self.dilation_filter_kernel_initializer = dilation_filter_kernel( self.cell_n, self.cell_n, self.param.dilation_size_initialize ) - self.polygon_mask_kernel = polygon_mask_kernel(self.cell_n, self.cell_n, self.resolution) - self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) + self.polygon_mask_kernel = polygon_mask_kernel( + self.cell_n, self.cell_n, self.resolution + ) + self.normal_filter_kernel = normal_filter_kernel( + self.cell_n, self.cell_n, self.resolution + ) def compile_image_kernels(self): for config in self.param.subscriber_cfg.values(): @@ -284,11 +315,17 @@ def compile_image_kernels(self): np.zeros((self.cell_n, self.cell_n), dtype=np.bool), dtype=np.bool ) self.uv_correspondence = cp.asarray( - np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32 + np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), + dtype=np.float32, ) # TODO tolerance_z_collision add parameter - self.image_to_map_correspondence_kernel = image_to_map_correspondence_kernel( - resolution=self.resolution, width=self.cell_n, height=self.cell_n, tolerance_z_collision=0.1 + self.image_to_map_correspondence_kernel = ( + image_to_map_correspondence_kernel( + resolution=self.resolution, + width=self.cell_n, + height=self.cell_n, + tolerance_z_collision=0.1, + ) ) break @@ -300,7 +337,9 @@ def shift_translation_to_map_center(self, t): """ t -= self.center - def update_map_with_kernel(self, points_all, channels, R, t, position_noise, orientation_noise): + def update_map_with_kernel( + self, points_all, channels, R, t, position_noise, orientation_noise + ): """Update map with new measurement. Args: @@ -341,7 +380,9 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori self.mean_error = error / error_cnt self.additive_mean_error += self.mean_error if np.abs(self.mean_error) < self.param.max_drift: - self.elevation_map[0] += self.mean_error * self.param.drift_compensation_alpha + self.elevation_map[0] += ( + self.mean_error * self.param.drift_compensation_alpha + ) self.add_points_kernel( cp.array([0.0], dtype=self.data_type), cp.array([0.0], dtype=self.data_type), @@ -353,10 +394,14 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori self.new_map, size=(points.shape[0]), ) - self.average_map_kernel(self.new_map, self.elevation_map, size=(self.cell_n * self.cell_n)) + self.average_map_kernel( + self.new_map, self.elevation_map, size=(self.cell_n * self.cell_n) + ) # self.update_additional_layers(additional_fusion, points_all, channels, R, t) - self.semantic_map.update_layers_pointcloud(points_all, channels, R, t, self.new_map) + self.semantic_map.update_layers_pointcloud( + points_all, channels, R, t, self.new_map + ) if self.param.enable_overlap_clearance: self.clear_overlap_map(t) @@ -382,7 +427,9 @@ def clear_overlap_map(self, t): # Clear overlapping area around center height_min = t[2] - self.param.overlap_clear_range_z height_max = t[2] + self.param.overlap_clear_range_z - near_map = self.elevation_map[:, self.cell_min : self.cell_max, self.cell_min : self.cell_max] + near_map = self.elevation_map[ + :, self.cell_min : self.cell_max, self.cell_min : self.cell_max + ] valid_idx = ~cp.logical_or(near_map[0] < height_min, near_map[0] > height_max) near_map[0] = cp.where(valid_idx, near_map[0], 0.0) near_map[1] = cp.where(valid_idx, near_map[1], self.initial_variance) @@ -390,7 +437,9 @@ def clear_overlap_map(self, t): valid_idx = ~cp.logical_or(near_map[5] < height_min, near_map[5] > height_max) near_map[5] = cp.where(valid_idx, near_map[5], 0.0) near_map[6] = cp.where(valid_idx, near_map[6], 0.0) - self.elevation_map[:, self.cell_min : self.cell_max, self.cell_min : self.cell_max] = near_map + self.elevation_map[ + :, self.cell_min : self.cell_max, self.cell_min : self.cell_max + ] = near_map def get_additive_mean_error(self): return self.additive_mean_error @@ -403,7 +452,9 @@ def update_time(self): def update_upper_bound_with_valid_elevation(self): mask = self.elevation_map[2] > 0.5 - self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) + self.elevation_map[5] = cp.where( + mask, self.elevation_map[0], self.elevation_map[5] + ) self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) def input( @@ -489,7 +540,12 @@ def input_image( size=int(self.cell_n * self.cell_n), ) self.semantic_map.update_layers_image( - sub_key, image, self.uv_correspondence, self.valid_correspondence, image_height, image_width + sub_key, + image, + self.uv_correspondence, + self.valid_correspondence, + image_height, + image_width, ) def update_normal(self, dilated_map): @@ -501,7 +557,10 @@ def update_normal(self, dilated_map): with self.map_lock: self.normal_map *= 0.0 self.normal_filter_kernel( - dilated_map, self.elevation_map[2], self.normal_map, size=(self.cell_n * self.cell_n) + dilated_map, + self.elevation_map[2], + self.normal_map, + size=(self.cell_n * self.cell_n), ) def process_map_for_publish(self, input_map, fill_nan=False, add_z=False, xp=cp): @@ -524,29 +583,42 @@ def process_map_for_publish(self, input_map, fill_nan=False, add_z=False, xp=cp) return m[1:-1, 1:-1] def get_elevation(self): - return self.process_map_for_publish(self.elevation_map[0], fill_nan=True, add_z=True) + return self.process_map_for_publish( + self.elevation_map[0], fill_nan=True, add_z=True + ) def get_variance(self): - return self.process_map_for_publish(self.elevation_map[1], fill_nan=False, add_z=False) + return self.process_map_for_publish( + self.elevation_map[1], fill_nan=False, add_z=False + ) def get_traversability(self): traversability = cp.where( - (self.elevation_map[2] + self.elevation_map[6]) > 0.5, self.elevation_map[3].copy(), cp.nan + (self.elevation_map[2] + self.elevation_map[6]) > 0.5, + self.elevation_map[3].copy(), + cp.nan, ) self.traversability_buffer[3:-3, 3:-3] = traversability[3:-3, 3:-3] traversability = self.traversability_buffer[1:-1, 1:-1] return traversability def get_time(self): - return self.process_map_for_publish(self.elevation_map[4], fill_nan=False, add_z=False) + return self.process_map_for_publish( + self.elevation_map[4], fill_nan=False, add_z=False + ) def get_upper_bound(self): if self.param.use_only_above_for_upper_bound: valid = cp.logical_or( - cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), self.elevation_map[2] > 0.5 + cp.logical_and( + self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5 + ), + self.elevation_map[2] > 0.5, ) else: - valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) + valid = cp.logical_or( + self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5 + ) upper_bound = cp.where(valid, self.elevation_map[5].copy(), cp.nan) upper_bound = upper_bound[1:-1, 1:-1] + self.center[2] return upper_bound @@ -554,10 +626,15 @@ def get_upper_bound(self): def get_is_upper_bound(self): if self.param.use_only_above_for_upper_bound: valid = cp.logical_or( - cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), self.elevation_map[2] > 0.5 + cp.logical_and( + self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5 + ), + self.elevation_map[2] > 0.5, ) else: - valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) + valid = cp.logical_or( + self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5 + ) is_upper_bound = cp.where(valid, self.elevation_map[6].copy(), cp.nan) is_upper_bound = is_upper_bound[1:-1, 1:-1] return is_upper_bound @@ -644,12 +721,18 @@ def get_map_with_name_ref(self, name, data): m = self.semantic_map.get_map_with_name(name) elif name in self.plugin_manager.layer_names: self.plugin_manager.update_with_name( - name, self.elevation_map, self.layer_names, self.semantic_map, self.base_rotation + name, + self.elevation_map, + self.layer_names, + self.semantic_map, + self.base_rotation, ) m = self.plugin_manager.get_map_with_name(name) p = self.plugin_manager.get_param_with_name(name) xp = self.xp_of_array(m) - m = self.process_map_for_publish(m, fill_nan=p.fill_nan, add_z=p.is_height_layer, xp=xp) + m = self.process_map_for_publish( + m, fill_nan=p.fill_nan, add_z=p.is_height_layer, xp=xp + ) else: print("Layer {} is not in the map".format(name)) return @@ -688,7 +771,11 @@ def get_layer(self, name): return_map = self.semantic_map.semantic_map[idx] elif name in self.plugin_manager.layer_names: self.plugin_manager.update_with_name( - name, self.elevation_map, self.layer_names, self.semantic_map, self.base_rotation + name, + self.elevation_map, + self.layer_names, + self.semantic_map, + self.base_rotation, ) return_map = self.plugin_manager.get_map_with_name(name) else: @@ -728,17 +815,24 @@ def get_polygon_traversability(self, polygon, result): size=(self.cell_n * self.cell_n), ) tmp_map = self.get_layer(self.param.checker_layer) - masked, masked_isvalid = get_masked_traversability(self.elevation_map, self.mask, tmp_map) + masked, masked_isvalid = get_masked_traversability( + self.elevation_map, self.mask, tmp_map + ) if masked_isvalid.sum() > 0: t = masked.sum() / masked_isvalid.sum() else: t = cp.asarray(0.0, dtype=self.data_type) is_safe, un_polygon = is_traversable( - masked, self.param.safe_thresh, self.param.safe_min_thresh, self.param.max_unsafe_n + masked, + self.param.safe_thresh, + self.param.safe_min_thresh, + self.param.max_unsafe_n, ) untraversable_polygon_num = 0 if un_polygon is not None: - un_polygon = transform_to_map_position(un_polygon, self.center[:2], self.cell_n, self.resolution) + un_polygon = transform_to_map_position( + un_polygon, self.center[:2], self.cell_n, self.resolution + ) untraversable_polygon_num = un_polygon.shape[0] if clipped_area < 0.001: is_safe = False @@ -765,7 +859,9 @@ def initialize_map(self, points, method="cubic"): self.clear() with self.map_lock: points = cp.asarray(points, dtype=self.data_type) - indices = transform_to_map_index(points[:, :2], self.center[:2], self.cell_n, self.resolution) + indices = transform_to_map_index( + points[:, :2], self.center[:2], self.cell_n, self.resolution + ) points[:, :2] = indices.astype(points.dtype) points[:, 2] -= self.center[2] self.map_initializer(self.elevation_map, points, method) @@ -790,13 +886,23 @@ def initialize_map(self, points, method="cubic"): t = xp.random.rand(3) print(R, t) param = Parameter( - use_chainer=False, weight_file="../config/weights.dat", plugin_config_file="../config/plugin_config.yaml" + use_chainer=False, + weight_file="../config/weights.dat", + plugin_config_file="../config/plugin_config.yaml", ) param.additional_layers = ["feat_0", "feat_1", "rgb", "people"] param.fusion_algorithms = ["average", "average", "color", "class_average"] param.update() elevation = ElevationMap(param) - layers = ["elevation", "variance", "traversability", "min_filter", "smooth", "inpaint", "rgb"] + layers = [ + "elevation", + "variance", + "traversability", + "min_filter", + "smooth", + "inpaint", + "rgb", + ] points = xp.random.rand(100000, len(layers)) channels = ["x", "y", "z"] + param.additional_layers diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/__init__.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/__init__.py index 5a58d6db..06eecc38 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/__init__.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/__init__.py @@ -1,2 +1,3 @@ from .custom_image_kernels import * from .custom_kernels import * +from .custom_semantic_kernels import * diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py index 3f89a06c..10e65eb0 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py @@ -656,384 +656,6 @@ def polygon_mask_kernel(width, height, resolution): return polygon_mask_kernel -##################### additional kernels ################################# - - -def sum_kernel( - resolution, - width, - height, -): - # input the list of layers, amount of channels can slo be input through kernel - sum_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params="raw U map, raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(resolution=resolution, width=width, height=height), - operation=string.Template( - """ - U idx = p[i * pcl_channels[0]]; - U valid = p[i * pcl_channels[0] + 1]; - U inside = p[i * pcl_channels[0] + 2]; - if (valid) { - if (inside) { - for ( W it=0;it=theta_max){ - arg_max = map_lay[it]; - theta_max = theta; - } - } - atomicAdd(&newmap[get_map_idx(idx, arg_max)], theta_max); - } - } - """ - ).substitute(), - name="alpha_kernel", - ) - return alpha_kernel - - -def average_kernel( - width, - height, -): - average_kernel = cp.ElementwiseKernel( - in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", - out_params="raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U cnt = new_elmap[get_map_idx(i, 2)]; - if (cnt>0){ - for ( int it=0;it0){ - for ( int it=0;it0){ - for ( int it=0;it> 16; - return reds; - } - __device__ unsigned int get_g(unsigned int color){ - unsigned int green = 0xFF00; - unsigned int greens = (color & green) >> 8; - return greens; - } - __device__ unsigned int get_b(unsigned int color){ - unsigned int blue = 0xFF; - unsigned int blues = ( color & blue); - return blues; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U idx = p[i * pcl_channels[0]]; - U valid = p[i * pcl_channels[0] + 1]; - U inside = p[i * pcl_channels[0] + 2]; - if (valid && inside){ - for ( int it=0;it> 16; - return reds; - } - __device__ unsigned int get_g(unsigned int color){ - unsigned int green = 0xFF00; - unsigned int greens = (color & green) >> 8; - return greens; - } - __device__ unsigned int get_b(unsigned int color){ - unsigned int blue = 0xFF; - unsigned int blues = (color & blue); - return blues; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - unsigned int cnt = color_map[get_map_idx(i, pcl_channels[1]*3)]; - if (cnt>0){ - for ( int it=0;it=0){ - // unsigned int prev_r = get_r(prev_color); - // unsigned int prev_g = get_g(prev_color); - // unsigned int prev_b = get_b(prev_color); - // unsigned int r = prev_r/2 + color_map[get_map_idx(i, it*3)]/(2*cnt); - // unsigned int g = prev_g/2 + color_map[get_map_idx(i, it*3+1)]/(2*cnt); - // unsigned int b = prev_b/2 + color_map[get_map_idx(i, it*3+2)]/(2*cnt); - //} - unsigned int rgb = (r<<16) + (g << 8) + b; - float rgb_ = __uint_as_float(rgb); - map[get_map_idx(i, map_lay[it])] = rgb_; - } - } - """ - ).substitute(), - name="color_average_kernel", - ) - return color_average_kernel - - if __name__ == "__main__": for i in range(10): import random diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py new file mode 100644 index 00000000..e562c263 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py @@ -0,0 +1,376 @@ +import cupy as cp +import string + +def sum_kernel( + resolution, + width, + height, +): + # input the list of layers, amount of channels can slo be input through kernel + sum_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map, raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U idx = p[i * pcl_channels[0]]; + U valid = p[i * pcl_channels[0] + 1]; + U inside = p[i * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + for ( W it=0;it=theta_max){ + arg_max = map_lay[it]; + theta_max = theta; + } + } + atomicAdd(&newmap[get_map_idx(idx, arg_max)], theta_max); + } + } + """ + ).substitute(), + name="alpha_kernel", + ) + return alpha_kernel + + +def average_kernel( + width, + height, +): + average_kernel = cp.ElementwiseKernel( + in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U cnt = new_elmap[get_map_idx(i, 2)]; + if (cnt>0){ + for ( int it=0;it0){ + for ( int it=0;it0){ + for ( int it=0;it> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = ( color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U idx = p[i * pcl_channels[0]]; + U valid = p[i * pcl_channels[0] + 1]; + U inside = p[i * pcl_channels[0] + 2]; + if (valid && inside){ + for ( int it=0;it> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = (color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + unsigned int cnt = color_map[get_map_idx(i, pcl_channels[1]*3)]; + if (cnt>0){ + for ( int it=0;it=0){ + // unsigned int prev_r = get_r(prev_color); + // unsigned int prev_g = get_g(prev_color); + // unsigned int prev_b = get_b(prev_color); + // unsigned int r = prev_r/2 + color_map[get_map_idx(i, it*3)]/(2*cnt); + // unsigned int g = prev_g/2 + color_map[get_map_idx(i, it*3+1)]/(2*cnt); + // unsigned int b = prev_b/2 + color_map[get_map_idx(i, it*3+2)]/(2*cnt); + //} + unsigned int rgb = (r<<16) + (g << 8) + b; + float rgb_ = __uint_as_float(rgb); + map[get_map_idx(i, map_lay[it])] = rgb_; + } + } + """ + ).substitute(), + name="color_average_kernel", + ) + return color_average_kernel diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index e7792405..9ff5f5b9 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -2,17 +2,17 @@ import cupy as cp import numpy as np from typing import List -from elevation_mapping_cupy.kernels import ( - sum_kernel, - add_color_kernel, - color_average_kernel, - bayesian_inference_kernel, -) -from elevation_mapping_cupy.kernels import sum_compact_kernel, sum_max_kernel + from elevation_mapping_cupy.kernels import ( average_kernel, class_average_kernel, alpha_kernel, + bayesian_inference_kernel, + add_color_kernel, + color_average_kernel, + sum_compact_kernel, + sum_max_kernel, + sum_kernel, ) from elevation_mapping_cupy.kernels import ( average_correspondences_to_map_kernel, @@ -167,6 +167,38 @@ def compile_kernels(self) -> None: ) ) + def pad_value(self, x, shift_value, idx=None, value=0.0): + """Create a padding of the map along x,y-axis according to amount that has shifted. + + Args: + x (cupy._core.core.ndarray): + shift_value (cupy._core.core.ndarray): + idx (Union[None, int, None, None]): + value (float): + """ + if idx is None: + if shift_value[0] > 0: + x[:, : shift_value[0], :] = value + elif shift_value[0] < 0: + x[:, shift_value[0] :, :] = value + if shift_value[1] > 0: + x[:, :, : shift_value[1]] = value + elif shift_value[1] < 0: + x[:, :, shift_value[1] :] = value + else: + if shift_value[0] > 0: + x[idx, : shift_value[0], :] = value + elif shift_value[0] < 0: + x[idx, shift_value[0] :, :] = value + if shift_value[1] > 0: + x[idx, :, : shift_value[1]] = value + elif shift_value[1] < 0: + x[idx, :, shift_value[1] :] = value + + def shift_map_xy(self, shift_value): + self.semantic_map = cp.roll(self.semantic_map, shift_value, axis=(1, 2)) + self.pad_value(self.semantic_map, shift_value, value=0.0) + def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: """Get all fusion algorithms that need to be applied to a specific pointcloud From 6c85ac1e4fd25899639bf6f3429f5b3b080d5420 Mon Sep 17 00:00:00 2001 From: Gian Erni Date: Fri, 9 Dec 2022 19:07:18 +0100 Subject: [PATCH 298/504] removed one todo --- .../script/elevation_mapping_cupy/parameter.py | 13 ++++++++++++- .../src/elevation_mapping_ros.cpp | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 6a307208..9edbf012 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -11,10 +11,21 @@ # todo add this for the future @dataclass class Subscriber(Serializable): - sensor_name: str = "front_cam" channels: list = field(default_factory=lambda: ["feat_0"]) fusion: list = field(default_factory=lambda: ["average"]) topic_name: str = "/elevation_mapping/pointcloud_semantic" + cam_frame: str = "zed2i_right_camera_optical_frame" + cam_info_topic: str = "/zed2i/zed_node/depth/camera_info" + confidence: bool = True + confidence_threshold: int = 10 + confidence_topic: str = "/zed2i/zed_node/confidence/confidence_map" + depth_topic: str = "/zed2i/zed_node/depth/depth_registered" + feature_extractor: bool = False + image_topic: str = "/zed2i/zed_node/left/image_rect_color" + segmentation_model: str = "lraspp_mobilenet_v3_large" + semantic_segmentation: bool = True + show_label_legend: bool = True + data_type: str = "pointcloud" @dataclass diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index de9314a9..9aba3faa 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -274,7 +274,7 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl std::vector channels; for(auto & field: fields){ channels.push_back(field.name); -// TODO: check that datatype is always 7? + ROS_ASSERT(field.datatype == 7); } // get pose of sensor in map frame tf::StampedTransform transformTf; From 08e814b8626cbe49f98ba74c10e6882ab58a90c8 Mon Sep 17 00:00:00 2001 From: Matias Mattamala Date: Sun, 11 Dec 2022 14:56:21 +0000 Subject: [PATCH 299/504] Minor TF listener fix --- .../elevation_mapping_cupy/elevation_mapping_ros.py | 2 +- elevation_mapping_cupy/src/elevation_mapping_ros.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index b9e2a6e1..8a61123e 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -152,7 +152,7 @@ def image_callback(self, camera_msg, camera_info_msg, sub_key): camera_msg.header.frame_id, self.map_frame, ti, rospy.Duration(1.0) ) except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - print("pointcloud_callback error:", e) + print("image_callback error:", e) return t = transform.transform.translation diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 9aba3faa..f70fb80e 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -97,7 +97,7 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) cameraSyncs_.push_back(sync); } else { - ROS_WARN_STREAM("Subscriber type [" << type << "] Not valid. Supported types: pointcloud, image"); + ROS_WARN_STREAM("Subscriber data_type [" << type << "] Not valid. Supported types: pointcloud, image"); continue; } } @@ -326,8 +326,10 @@ void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image auto timeStamp = image_msg->header.stamp; Eigen::Affine3d transformationSensorToMap; try { - transformListener_.waitForTransform(mapFrameId_, sensorFrameId, timeStamp, ros::Duration(1.0)); - transformListener_.lookupTransform(mapFrameId_, sensorFrameId, timeStamp, transformTf); + // transformListener_.waitForTransform(mapFrameId_, sensorFrameId, timeStamp, ros::Duration(1.0)); + // transformListener_.lookupTransform(mapFrameId_, sensorFrameId, timeStamp, transformTf); + transformListener_.waitForTransform(sensorFrameId, mapFrameId_, timeStamp, ros::Duration(1.0)); + transformListener_.lookupTransform(sensorFrameId, mapFrameId_, timeStamp, transformTf); poseTFToEigen(transformTf, transformationSensorToMap); } catch (tf::TransformException& ex) { ROS_ERROR("%s", ex.what()); From 2a4f9e1432584cf441a48bb3df8f700b1903f980 Mon Sep 17 00:00:00 2001 From: Matias Mattamala Date: Sun, 11 Dec 2022 15:39:33 +0000 Subject: [PATCH 300/504] Fix names in tf listener, fix multichannel conversion --- .../src/elevation_mapping_ros.cpp | 58 ++++++------------- 1 file changed, 17 insertions(+), 41 deletions(-) diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index f70fb80e..d5a72247 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -317,6 +317,13 @@ void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image // Get image cv::Mat image = cv_bridge::toCvShare(image_msg, image_msg->encoding)->image; + // Change encoding to RGB/RGBA + if (image_msg->encoding == "bgr8") { + cv::cvtColor(image, image, CV_BGR2RGB); + } else if (image_msg->encoding == "bgra8") { + cv::cvtColor(image, image, CV_BGRA2RGBA); + } + // Extract camera matrix Eigen::Map> cameraMatrix(&camera_info_msg->K[0]); @@ -324,59 +331,28 @@ void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image tf::StampedTransform transformTf; std::string sensorFrameId = image_msg->header.frame_id; auto timeStamp = image_msg->header.stamp; - Eigen::Affine3d transformationSensorToMap; + Eigen::Affine3d transformationMapToSensor; try { - // transformListener_.waitForTransform(mapFrameId_, sensorFrameId, timeStamp, ros::Duration(1.0)); - // transformListener_.lookupTransform(mapFrameId_, sensorFrameId, timeStamp, transformTf); transformListener_.waitForTransform(sensorFrameId, mapFrameId_, timeStamp, ros::Duration(1.0)); transformListener_.lookupTransform(sensorFrameId, mapFrameId_, timeStamp, transformTf); - poseTFToEigen(transformTf, transformationSensorToMap); + poseTFToEigen(transformTf, transformationMapToSensor); } catch (tf::TransformException& ex) { ROS_ERROR("%s", ex.what()); return; } - // Transform to vector of Eigen matrices + // Transform image to vector of Eigen matrices for easy pybind conversion + std::vector image_split; std::vector multichannel_image; - if (image.channels() == 1) { - ColMatrixXf eigen_image; - cv::cv2eigen(image, eigen_image); - multichannel_image.push_back(eigen_image); - - } else if (image.channels() == 3) { - cv::Mat bgr[3]; - cv::split(image, bgr); - ColMatrixXf eigen_image_b; - cv::cv2eigen(bgr[0], eigen_image_b); - ColMatrixXf eigen_image_g; - cv::cv2eigen(bgr[1], eigen_image_g); - ColMatrixXf eigen_image_r; - cv::cv2eigen(bgr[2], eigen_image_r); - - multichannel_image.push_back(eigen_image_r); - multichannel_image.push_back(eigen_image_g); - multichannel_image.push_back(eigen_image_b); - - } else if (image.channels() == 4) { - cv::Mat bgr[4]; - cv::split(image, bgr); - ColMatrixXf eigen_image_b; - cv::cv2eigen(bgr[0], eigen_image_b); - ColMatrixXf eigen_image_g; - cv::cv2eigen(bgr[1], eigen_image_g); - ColMatrixXf eigen_image_r; - cv::cv2eigen(bgr[2], eigen_image_r); - - multichannel_image.push_back(eigen_image_r); - multichannel_image.push_back(eigen_image_g); - multichannel_image.push_back(eigen_image_b); - - } else { - ROS_WARN_STREAM("Invalid number of channels [" << image.channels() << "]. Only allowed 1 (mono) or 3 (rgb)"); + cv::split(image, image_split); + for (auto img : image_split) { + ColMatrixXf eigen_img; + cv::cv2eigen(img, eigen_img); + multichannel_image.push_back(eigen_img); } // Pass image to pipeline - map_.input_image(key, multichannel_image, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), cameraMatrix, image.rows, image.cols); + map_.input_image(key, multichannel_image, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, image.rows, image.cols); ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); } From ba783fce7aa9a23c4d3db8b56bca85ba33b270b5 Mon Sep 17 00:00:00 2001 From: Gian Date: Mon, 12 Dec 2022 15:52:17 +0100 Subject: [PATCH 301/504] added parameter file to make experiments repeatable --- README.md | 29 + .../config/anymal_parameters.yaml | 96 +++ .../config/anymal_sensor_parameter.yaml | 137 +++++ .../config/lonomy_parameters.yaml | 94 +++ .../config/lonomy_plugin_config.yaml | 61 ++ .../config/lonomy_sensor_parameter.yaml | 28 + .../anymal_semantic_elevation_single.launch | 21 + .../launch/lonomy_pointcloud.launch | 16 + .../lonomy_semantic_elevation_single.launch | 21 + elevation_mapping_cupy/rviz/anymal.rviz | 570 ++++++++++++++++++ .../rviz/lonomy_single.rviz | 494 +++++++++++++++ 11 files changed, 1567 insertions(+) create mode 100644 elevation_mapping_cupy/config/anymal_parameters.yaml create mode 100644 elevation_mapping_cupy/config/anymal_sensor_parameter.yaml create mode 100644 elevation_mapping_cupy/config/lonomy_parameters.yaml create mode 100644 elevation_mapping_cupy/config/lonomy_plugin_config.yaml create mode 100644 elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml create mode 100644 elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch create mode 100644 elevation_mapping_cupy/launch/lonomy_pointcloud.launch create mode 100644 elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch create mode 100644 elevation_mapping_cupy/rviz/anymal.rviz create mode 100644 elevation_mapping_cupy/rviz/lonomy_single.rviz diff --git a/README.md b/README.md index 9dba2ed3..ecb9b977 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,32 @@ terrain can be efficiently generated. } ``` + +## Quick instructions to run: + +For the lonomy bag: + +CPP wrapper: +```zsh + roslaunch elevation_mapping_cupy lonomy_semantic_elevation_single.launch use_sim_true:=true + rosbag play --clock ~/bags/good_working_wine_field_zed_topcom_rtk_person_9_2022-07-15-14-37-05.bag +``` + +Python wrapper: +````zsh + python -m elevation_mapping_cupy.elevation_mapping_ros + roslaunch elevation_mapping_cupy lonomy_pointcloud.launch use_sim_time:=true + rosbag play --clock ~/bags/good_working_wine_field_zed_topcom_rtk_person_9_2022-07-15-14-37-05.bag +```` + + + +For the anymal bag: + + +```zsh + roslaunch elevation_mapping_cupy anymal_semantic_elevation_single.launch use_sim_time:=true + rosbag play --clock ~/bags/anymal_coyote_2022-12-11-20-01-46.bag +``` + + diff --git a/elevation_mapping_cupy/config/anymal_parameters.yaml b/elevation_mapping_cupy/config/anymal_parameters.yaml new file mode 100644 index 00000000..4941a011 --- /dev/null +++ b/elevation_mapping_cupy/config/anymal_parameters.yaml @@ -0,0 +1,96 @@ +#### Basic parameters ######## +resolution: 0.04 # resolution in m. +map_length: 8 # map's size in m. +sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). +mahalanobis_thresh: 2.0 # points outside this distance is outlier. +outlier_variance: 0.01 # if point is outlier, add this value to the cell. +drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. +max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) +drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation +time_variance: 0.0001 # add this value when update_variance is called. +max_variance: 100.0 # maximum variance for each cell. +initial_variance: 1000.0 # initial variance for each cell. +traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. +dilation_size: 3 # dilation filter size before traversability filter. +wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. +min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. +position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. +orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. +position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. +orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. +min_valid_distance: 0.5 # points with shorter distance will be filtered out. +max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. +ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +update_variance_fps: 5.0 # fps for updating variance. +update_pose_fps: 10.0 # fps for updating pose and shift the center of map. +time_interval: 0.1 # Time layer is updated with this interval. +map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. +publish_statistics_fps: 1.0 # Publish statistics topic in this fps. + +max_ray_length: 10.0 # maximum length for ray tracing. +cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. +cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + +safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. +safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. +max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + +overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) +overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + +map_frame: 'odom' # The map frame where the odometry source uses. +base_frame: 'base' # The robot's base frame. This frame will be a center of the map. +corrected_map_frame: 'odom_corrected' + +#### Feature toggles ######## +enable_edge_sharpen: true +enable_visibility_cleanup: true +enable_drift_compensation: true +enable_overlap_clearance: true +enable_pointcloud_publishing: false +enable_drift_corrected_TF_publishing: false +enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + +#### Traversability filter ######## +use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. +weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter + +#### Upper bound ######## +use_only_above_for_upper_bound: false + +#### Plugins ######## +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/plugin_config.yaml' + +#### Publishers ######## +# topic_name: +# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names +# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. +# fps: # Publish rate. Use smaller value than `map_acquire_fps`. +publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + + semantic_map_raw: + layers: ['elevation', 'traversability', 'variance', 'rgb_image'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + # elevation_map_recordable: + # layers: ['elevation', 'traversability'] + # basic_layers: ['elevation', 'traversability'] + # fps: 2.0 + # elevation_map_filter: + # layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb'] + # basic_layers: ['min_filter'] + # fps: 3.0 + +#### Initializer ######## +initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' +initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [0.0] # z direction. Should be same number as initialize_frame_id. +dilation_size_initialize: 5 # dilation size after the init. +initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. +use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml new file mode 100644 index 00000000..edae6030 --- /dev/null +++ b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml @@ -0,0 +1,137 @@ +#### Subscribers ######## +subscribers: + # debug_rgb: + # fusion: ['image_color'] + # topic_name_camera: /zed2i/zed_node/left/image_rect_color + # topic_name_camera_info: /zed2i/zed_node/right/camera_info + # channels: ["rgb_image"] + # data_type: image + # fusion_types: + # array_fusion: [] + # channels: [] + + # debug_rgb_3_seperate: + # fusion: ['image_exponential','image_exponential','image_exponential'] + # topic_name_camera: /zed2i/zed_node/right/image + # topic_name_camera_info: /zed2i/zed_node/right/camera_info + # channels: ["r_channel", "g_channel", "b_channel"] + # data_type: image + + # debug_rgb_2_seperate: + # fusion: ['image_exponential', 'image_exponential'] + # topic_name_camera: /zed2i/zed_node/left/image_rect_color + # topic_name_camera_info: /zed2i/zed_node/right/camera_info + # channels: ["r_channel", "g_channel"] + # data_type: image + + # debug_mono_exponential: + # fusion: ['image_exponential'] + # topic_name_camera: /debug_image + # topic_name_camera_info: /zed2i/zed_node/right/camera_info + # channels: ["single_channel_semantic"] + # data_type: image + +# front_cam: +# channels: ['rgb'] +# fusion: ['color'] +# topic_name: '/elevation_mapping/pointcloud_semantic' +# data_type: pointcloud + + alphasense_front_rgb: + fusion: ['image_color'] + topic_name_camera: /alphasense_driver_ros/cam4/debayered + topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info + channels: ["rgb_image"] + data_type: image + fusion_types: + array_fusion: [] + channels: [] + + alphasense_left_rgb: + fusion: ['image_color'] + topic_name_camera: /alphasense_driver_ros/cam3/debayered + topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info + channels: ["rgb_image"] + data_type: image + fusion_types: + array_fusion: [] + channels: [] + + alphasense_right_rgb: + fusion: ['image_color'] + topic_name_camera: /alphasense_driver_ros/cam5/debayered + topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info + channels: ["rgb_image"] + data_type: image + fusion_types: + array_fusion: [] + channels: [] + + wvn_prediction: + fusion: ['image_exponential'] + topic_name_camera: '/wild_visual_navigation_node/current_prediction' + topic_name_camera_info: '/wild_visual_navigation_node/camera_info' + channels: ["visual_traversability"] + data_type: image + + # front_cam: + # channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] + # fusion: ['color','average','average','class_average','class_average','class_average','class_average'] + # topic_name: '/elvation_mapping/pointcloud_semantic' + # semantic_segmentation: False + # segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' + # feature_config: + # name: 'DINO' + # interpolation: 'bilinear' + # model: "vit_small" + # patch_size: 16 + # dim: 5 + # dropout: False + # dino_feat_type: "feat" + # input_size: [80, 160] + # projection_type: "nonlinear" + + # cam_info_topic: "/camera/depth/camera_info" + # image_topic: "/camera/rgb/image_raw" + # depth_topic: "/camera/depth/image_raw" + # cam_frame: camera_rgb_optical_frame + # confidence: False + # confidence_topic: "/camera/depth/image_raw" + # confidence_threshold: 10 + # feature_extractor: False + + # front_bpearl: + # channels: [] + # fusion: ['average'] + # topic_name: /robot_self_filter/bpearl_front/point_cloud + # type: pointcloud + + # rear_bpearl: + # channels: [] + # fusion: ['average'] + # topic_name: /robot_self_filter/bpearl_rear/point_cloud + # type: pointcloud + + front_depth: + channels: [] + fusion: ['average'] + topic_name: /depth_camera_front/point_cloud_self_filtered + data_type: pointcloud + + rear_depth: + channels: [] + fusion: ['average'] + topic_name: /depth_camera_rear/point_cloud_self_filtered + data_type: pointcloud + + left_depth: + channels: [] + fusion: ['average'] + topic_name: /depth_camera_left/point_cloud_self_filtered + data_type: pointcloud + + right_depth: + channels: [] + fusion: ['average'] + topic_name: /depth_camera_right/point_cloud_self_filtered + data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/config/lonomy_parameters.yaml b/elevation_mapping_cupy/config/lonomy_parameters.yaml new file mode 100644 index 00000000..a7cbeaee --- /dev/null +++ b/elevation_mapping_cupy/config/lonomy_parameters.yaml @@ -0,0 +1,94 @@ +#### Basic parameters ######## +resolution: 0.04 # resolution in m. +map_length: 8.0 # map's size in m. +sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). +mahalanobis_thresh: 2.0 # points outside this distance is outlier. +outlier_variance: 0.01 # if point is outlier, add this value to the cell. +drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. +max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) +drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation +time_variance: 0.0001 # add this value when update_variance is called. +max_variance: 100.0 # maximum variance for each cell. +initial_variance: 1000.0 # initial variance for each cell. +traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. +dilation_size: 3 # dilation filter size before traversability filter. +wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. +min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. +position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. +orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. +position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. +orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. +min_valid_distance: 0.5 # points with shorter distance will be filtered out. +max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. +ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +update_variance_fps: 5.0 # fps for updating variance. +update_pose_fps: 10.0 # fps for updating pose and shift the center of map. +time_interval: 0.1 # Time layer is updated with this interval. +map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. +publish_statistics_fps: 1.0 # Publish statistics topic in this fps. + +max_ray_length: 10.0 # maximum length for ray tracing. +cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. +cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + +safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. +safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. +max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + +overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) +overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + +map_frame: 'enu' # The map frame where the odometry source uses. +base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. +corrected_map_frame: 'enu' + +#### Feature toggles ######## +enable_edge_sharpen: true +enable_visibility_cleanup: true +enable_drift_compensation: true +enable_overlap_clearance: true +enable_pointcloud_publishing: false +enable_drift_corrected_TF_publishing: false +enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + +#### Traversability filter ######## +use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. +weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter + +#### Upper bound ######## +use_only_above_for_upper_bound: false + +#### Plugins ######## +plugin_config_file: '$(rospack find lonomy_configuration)/elevation_map/config/plugin_config.yaml' + +#### Subscribers ######## + + +#### Publishers ######## +# topic_name: +# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names +# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. +# fps: # Publish rate. Use smaller value than `map_acquire_fps`. +publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','sem_fil'] + basic_layers: ['elevation', 'traversability'] + fps: 5.0 + elevation_map_recordable: + layers: ['elevation', 'traversability'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb','robot_centric_elevation','sem_fil','sem_traversability'] + basic_layers: ['min_filter'] + fps: 3.0 + +#### Initializer ######## +initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' +initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. +dilation_size_initialize: 5 # dilation size after the init. +initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. +use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/lonomy_plugin_config.yaml b/elevation_mapping_cupy/config/lonomy_plugin_config.yaml new file mode 100644 index 00000000..37553806 --- /dev/null +++ b/elevation_mapping_cupy/config/lonomy_plugin_config.yaml @@ -0,0 +1,61 @@ +# Settings of the plugins. (The plugins should be stored in script/plugins) + +# min_filter fills in minimum value around the invalid cell. +min_filter: + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations +# Apply smoothing. +smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" +# Apply inpainting using opencv +inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns +# Apply smoothing for inpainted layer + +robot_centric_elevation: # Use the same name as your file name. +# type: "robot_centric_elevation" + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "robot_centric_elevation" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. +# add_value: 2.0 # Example param + resolution: 0.04 + threshold: 1.1 + use_threshold: True + +semantic_filter: + type: "semantic_filter" + enable: True + fill_nan: False + is_height_layer: False + layer_name: "sem_fil" + extra_params: + classes: ['grass','tree','fence','dirt'] + +semantic_traversability: + type: "semantic_traversability" + enable: True + fill_nan: False + is_height_layer: False + layer_name: "sem_traversability" + extra_params: + layers: ['traversability','robot_centric_elevation'] + thresholds: [0.3,0.5] + type: ['traversability', 'elevation'] + diff --git a/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml b/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml new file mode 100644 index 00000000..30b3caf4 --- /dev/null +++ b/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml @@ -0,0 +1,28 @@ +subscribers: + front_cam: + channels: [ 'rgb','feat_0','feat_1','__background__','car',"max" ] + fusion: [ 'color','bayesian_inference','bayesian_inference','class_average','class_average',"class_max" ] + topic_name: '/elvation_mapping/pointcloud_semantic' + semantic_segmentation: True + segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large + show_label_legend: True + data_type: pointcloud + feature_config: + name: 'DINO' + interpolation: 'bilinear' + model: "vit_small" + patch_size: 16 + dim: 5 + dropout: False + dino_feat_type: "feat" + input_size: [80, 160] + projection_type: "nonlinear" + + cam_info_topic: "/zed2i/zed_node/depth/camera_info" + image_topic: "/zed2i/zed_node/left/image_rect_color" + depth_topic: "/zed2i/zed_node/depth/depth_registered" + cam_frame: "zed2i_right_camera_optical_frame" + confidence: True + confidence_topic: "/zed2i/zed_node/confidence/confidence_map" + confidence_threshold: 10 + feature_extractor: False diff --git a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch new file mode 100644 index 00000000..2e1d7575 --- /dev/null +++ b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/lonomy_pointcloud.launch b/elevation_mapping_cupy/launch/lonomy_pointcloud.launch new file mode 100644 index 00000000..a93792b0 --- /dev/null +++ b/elevation_mapping_cupy/launch/lonomy_pointcloud.launch @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch new file mode 100644 index 00000000..a093c904 --- /dev/null +++ b/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/elevation_mapping_cupy/rviz/anymal.rviz b/elevation_mapping_cupy/rviz/anymal.rviz new file mode 100644 index 00000000..e8023f37 --- /dev/null +++ b/elevation_mapping_cupy/rviz/anymal.rviz @@ -0,0 +1,570 @@ +Panels: + - Class: rviz/Displays + Help Height: 138 + Name: Displays + Property Tree Widget: + Expanded: ~ + Splitter Ratio: 0.5768463015556335 + Tree Height: 469 + - Class: rviz/Selection + Name: Selection + - Class: rviz/Tool Properties + Expanded: + - /2D Pose Estimate1 + - /2D Nav Goal1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz/Time + Name: Time + SyncMode: 0 + SyncSource: "" +Preferences: + PromptSaveOnExit: true +Toolbars: + toolButtonStyle: 2 +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.029999999329447746 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: rgb_image + Color Transformer: ColorLayer + Enabled: true + Height Layer: elevation + Height Transformer: Layer + History Length: 1 + Invert Rainbow: false + Max Color: 204; 0; 0 + Max Intensity: 10 + Min Color: 52; 101; 164 + Min Intensity: 0 + Name: ElevationMapFilter + Show Grid Lines: true + Topic: /elevation_mapping/semantic_map_raw + Unreliable: false + Use Rainbow: false + Value: true + - Class: rviz/TF + Enabled: true + Frame Timeout: 15 + Frames: + All Enabled: true + LF_FOOT: + Value: true + LF_HAA: + Value: true + LF_HFE: + Value: true + LF_HIP: + Value: true + LF_KFE: + Value: true + LF_SHANK: + Value: true + LF_THIGH: + Value: true + LF_hip_fixed: + Value: true + LF_shank_fixed: + Value: true + LF_thigh_fixed: + Value: true + LH_FOOT: + Value: true + LH_HAA: + Value: true + LH_HFE: + Value: true + LH_HIP: + Value: true + LH_KFE: + Value: true + LH_SHANK: + Value: true + LH_THIGH: + Value: true + LH_hip_fixed: + Value: true + LH_shank_fixed: + Value: true + LH_thigh_fixed: + Value: true + RF_FOOT: + Value: true + RF_HAA: + Value: true + RF_HFE: + Value: true + RF_HIP: + Value: true + RF_KFE: + Value: true + RF_SHANK: + Value: true + RF_THIGH: + Value: true + RF_hip_fixed: + Value: true + RF_shank_fixed: + Value: true + RF_thigh_fixed: + Value: true + RH_FOOT: + Value: true + RH_HAA: + Value: true + RH_HFE: + Value: true + RH_HIP: + Value: true + RH_KFE: + Value: true + RH_SHANK: + Value: true + RH_THIGH: + Value: true + RH_hip_fixed: + Value: true + RH_shank_fixed: + Value: true + RH_thigh_fixed: + Value: true + alphasense_mesh: + Value: true + base: + Value: true + base_inertia: + Value: true + base_inverted: + Value: true + battery: + Value: true + body_top: + Value: true + bottom_shell: + Value: true + cam0_sensor_frame: + Value: true + cam1_sensor_frame: + Value: true + cam2_sensor_frame: + Value: true + cam3_sensor_frame: + Value: true + cam3_sensor_frame_helper: + Value: true + cam4_sensor_frame: + Value: true + cam4_sensor_frame_helper: + Value: true + cam5_sensor_frame: + Value: true + cam5_sensor_frame_helper: + Value: true + cam6_sensor_frame: + Value: true + cam6_sensor_frame_helper: + Value: true + camera_init: + Value: true + camera_init_CORRECTED: + Value: true + depth_camera_front_camera: + Value: true + depth_camera_front_camera_parent: + Value: true + depth_camera_front_depth_frame: + Value: true + depth_camera_front_depth_optical_frame: + Value: true + depth_camera_front_infra1_frame: + Value: true + depth_camera_front_infra1_optical_frame: + Value: true + depth_camera_front_infra2_frame: + Value: true + depth_camera_front_infra2_optical_frame: + Value: true + depth_camera_left_camera: + Value: true + depth_camera_left_camera_parent: + Value: true + depth_camera_left_depth_frame: + Value: true + depth_camera_left_depth_optical_frame: + Value: true + depth_camera_left_infra1_frame: + Value: true + depth_camera_left_infra1_optical_frame: + Value: true + depth_camera_left_infra2_frame: + Value: true + depth_camera_left_infra2_optical_frame: + Value: true + depth_camera_rear_camera: + Value: true + depth_camera_rear_camera_parent: + Value: true + depth_camera_rear_depth_frame: + Value: true + depth_camera_rear_depth_optical_frame: + Value: true + depth_camera_rear_infra1_frame: + Value: true + depth_camera_rear_infra1_optical_frame: + Value: true + depth_camera_rear_infra2_frame: + Value: true + depth_camera_rear_infra2_optical_frame: + Value: true + depth_camera_right_camera: + Value: true + depth_camera_right_camera_parent: + Value: true + depth_camera_right_depth_frame: + Value: true + depth_camera_right_depth_optical_frame: + Value: true + depth_camera_right_infra1_frame: + Value: true + depth_camera_right_infra1_optical_frame: + Value: true + depth_camera_right_infra2_frame: + Value: true + depth_camera_right_infra2_optical_frame: + Value: true + docking_hatch_cover: + Value: true + face_front: + Value: true + face_rear: + Value: true + feetcenter: + Value: true + footprint: + Value: true + front_handle: + Value: true + handle: + Value: true + hatch: + Value: true + imu_link: + Value: true + imu_sensor_frame: + Value: true + interface_hatch: + Value: true + lidar: + Value: true + map: + Value: true + mira_spectrometer: + Value: true + msf_body_imu_map: + Value: true + odom: + Value: true + perception_head_cage: + Value: true + remote: + Value: true + top_shell: + Value: true + wide_angle_camera_front_camera: + Value: true + wide_angle_camera_front_camera_parent: + Value: true + wide_angle_camera_rear_camera: + Value: true + wide_angle_camera_rear_camera_parent: + Value: true + Marker Alpha: 1 + Marker Scale: 1 + Name: TF + Show Arrows: true + Show Axes: true + Show Names: true + Tree: + odom: + base: + LF_HAA: + LF_HIP: + LF_hip_fixed: + LF_HFE: + LF_THIGH: + LF_thigh_fixed: + LF_KFE: + LF_SHANK: + LF_shank_fixed: + LF_FOOT: + {} + LH_HAA: + LH_HIP: + LH_hip_fixed: + LH_HFE: + LH_THIGH: + LH_thigh_fixed: + LH_KFE: + LH_SHANK: + LH_shank_fixed: + LH_FOOT: + {} + RF_HAA: + RF_HIP: + RF_hip_fixed: + RF_HFE: + RF_THIGH: + RF_thigh_fixed: + RF_KFE: + RF_SHANK: + RF_shank_fixed: + RF_FOOT: + {} + RH_HAA: + RH_HIP: + RH_hip_fixed: + RH_HFE: + RH_THIGH: + RH_thigh_fixed: + RH_KFE: + RH_SHANK: + RH_shank_fixed: + RH_FOOT: + {} + alphasense_mesh: + {} + base_inertia: + {} + base_inverted: + {} + battery: + {} + body_top: + {} + bottom_shell: + {} + depth_camera_left_camera: + depth_camera_left_camera_parent: + depth_camera_left_depth_frame: + depth_camera_left_depth_optical_frame: + {} + depth_camera_left_infra1_frame: + depth_camera_left_infra1_optical_frame: + {} + depth_camera_left_infra2_frame: + depth_camera_left_infra2_optical_frame: + {} + depth_camera_right_camera: + depth_camera_right_camera_parent: + depth_camera_right_depth_frame: + depth_camera_right_depth_optical_frame: + {} + depth_camera_right_infra1_frame: + depth_camera_right_infra1_optical_frame: + {} + depth_camera_right_infra2_frame: + depth_camera_right_infra2_optical_frame: + {} + docking_hatch_cover: + {} + face_front: + depth_camera_front_camera: + depth_camera_front_camera_parent: + depth_camera_front_depth_frame: + depth_camera_front_depth_optical_frame: + {} + depth_camera_front_infra1_frame: + depth_camera_front_infra1_optical_frame: + {} + depth_camera_front_infra2_frame: + depth_camera_front_infra2_optical_frame: + {} + wide_angle_camera_front_camera: + wide_angle_camera_front_camera_parent: + {} + face_rear: + depth_camera_rear_camera: + depth_camera_rear_camera_parent: + depth_camera_rear_depth_frame: + depth_camera_rear_depth_optical_frame: + {} + depth_camera_rear_infra1_frame: + depth_camera_rear_infra1_optical_frame: + {} + depth_camera_rear_infra2_frame: + depth_camera_rear_infra2_optical_frame: + {} + wide_angle_camera_rear_camera: + wide_angle_camera_rear_camera_parent: + {} + front_handle: + {} + handle: + {} + imu_link: + {} + interface_hatch: + hatch: + {} + mira_spectrometer: + {} + perception_head_cage: + lidar: + imu_sensor_frame: + cam0_sensor_frame: + {} + cam1_sensor_frame: + {} + cam2_sensor_frame: + {} + cam3_sensor_frame_helper: + cam3_sensor_frame: + {} + cam4_sensor_frame_helper: + cam4_sensor_frame: + {} + cam5_sensor_frame_helper: + cam5_sensor_frame: + {} + cam6_sensor_frame_helper: + cam6_sensor_frame: + {} + remote: + {} + top_shell: + {} + feetcenter: + {} + footprint: + {} + map: + camera_init_CORRECTED: + camera_init: + {} + msf_body_imu_map: + {} + Update Interval: 0 + Value: true + - Class: rviz/Image + Enabled: true + Image Topic: /alphasense_driver_ros/cam4/debayered + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Queue Size: 2 + Transport Hint: raw + Unreliable: false + Value: true + - Class: rviz/Marker + Enabled: true + Marker Topic: /visualization_marker_l + Name: Marker + Namespaces: + {} + Queue Size: 100 + Value: true + - Class: rviz/Marker + Enabled: true + Marker Topic: /visualization_marker_r + Name: Marker + Namespaces: + {} + Queue Size: 100 + Value: true + Enabled: true + Global Options: + Background Color: 255; 255; 255 + Default Light: true + Fixed Frame: map + Frame Rate: 30 + Name: root + Tools: + - Class: rviz/Interact + Hide Inactive Objects: true + - Class: rviz/MoveCamera + - Class: rviz/Select + - Class: rviz/FocusCamera + - Class: rviz/Measure + - Class: rviz/SetInitialPose + Theta std deviation: 0.2617993950843811 + Topic: /initialpose + X std deviation: 0.5 + Y std deviation: 0.5 + - Class: rviz/SetGoal + Topic: /move_base_simple/goal + - Class: rviz/PublishPoint + Single click: true + Topic: /clicked_point + Value: true + Views: + Current: + Class: rviz/Orbit + Distance: 18.912090301513672 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Field of View: 0.7853981852531433 + Focal Point: + X: 0.7929360866546631 + Y: 0.3796532452106476 + Z: -0.4990573823451996 + Focal Shape Fixed Size: true + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 0.23979759216308594 + Target Frame: base_footprint + Yaw: 5.103874206542969 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 1016 + Hide Left Dock: false + Hide Right Dock: true + Image: + collapsed: false + QMainWindow State: 000000ff00000000fd0000000400000000000001f50000039efc020000000cfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000029c000000c900fffffffb0000000a0049006d00610067006501000002df000000fc0000001600fffffffb0000000a0049006d00610067006501000002af0000012c0000000000000000fb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d0061006700650000000325000000d10000000000000000fb0000000a0049006d006100670065010000032a000000cc0000000000000000000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000078000000131fc0100000002fb0000000800540069006d00650000000000000007380000041800fffffffb0000000800540069006d006501000000000000045000000000000000000000053d0000039e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: true + Width: 1848 + X: 72 + Y: 27 diff --git a/elevation_mapping_cupy/rviz/lonomy_single.rviz b/elevation_mapping_cupy/rviz/lonomy_single.rviz new file mode 100644 index 00000000..05d3d87d --- /dev/null +++ b/elevation_mapping_cupy/rviz/lonomy_single.rviz @@ -0,0 +1,494 @@ +Panels: + - Class: rviz/Displays + Help Height: 138 + Name: Displays + Property Tree Widget: + Expanded: ~ + Splitter Ratio: 0.5768463015556335 + Tree Height: 260 + - Class: rviz/Selection + Name: Selection + - Class: rviz/Tool Properties + Expanded: + - /2D Pose Estimate1 + - /2D Nav Goal1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz/Time + Name: Time + SyncMode: 0 + SyncSource: Image +Preferences: + PromptSaveOnExit: true +Toolbars: + toolButtonStyle: 2 +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.029999999329447746 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: sem_fil + Color Transformer: ColorLayer + Enabled: true + Height Layer: elevation + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 204; 0; 0 + Max Intensity: 10 + Min Color: 52; 101; 164 + Min Intensity: 0 + Name: ElevationMapFilter + Show Grid Lines: true + Topic: /elevation_mapping/elevation_map_raw + Unreliable: false + Use Rainbow: false + Value: true + - Alpha: 1 + Class: rviz/RobotModel + Collision Enabled: false + Enabled: true + Links: + All Links Enabled: true + Expand Joint Details: false + Expand Link Details: false + Expand Tree: false + GPS_back: + Alpha: 1 + Show Axes: false + Show Trail: false + GPS_front: + Alpha: 1 + Show Axes: false + Show Trail: false + Link Tree Style: Links in Alphabetic Order + alphasense: + Alpha: 1 + Show Axes: false + Show Trail: false + base_footprint: + Alpha: 1 + Show Axes: false + Show Trail: false + base_inertial: + Alpha: 1 + Show Axes: false + Show Trail: false + base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + estimator_imu: + Alpha: 1 + Show Axes: false + Show Trail: false + left_back_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + left_back_wheel_sup: + Alpha: 1 + Show Axes: false + Show Trail: false + left_front_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + left_front_wheel_sup: + Alpha: 1 + Show Axes: false + Show Trail: false + rear_axle_center: + Alpha: 1 + Show Axes: false + Show Trail: false + right_back_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + right_back_wheel_sup: + Alpha: 1 + Show Axes: false + Show Trail: false + right_front_wheel: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + right_front_wheel_sup: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_baro_link: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_camera_center: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + zed2i_left_camera_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_left_camera_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_mag_link: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_right_camera_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_right_camera_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_temp_left_link: + Alpha: 1 + Show Axes: false + Show Trail: false + zed2i_temp_right_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Name: RobotModel + Robot Description: robot_description + TF Prefix: "" + Update Interval: 0 + Value: true + Visual Enabled: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Autocompute Value Bounds: + Max Value: 10 + Min Value: -10 + Value: true + Axis: Z + Channel Name: intensity + Class: rviz/PointCloud2 + Color: 255; 255; 255 + Color Transformer: RGB8 + Decay Time: 0 + Enabled: false + Invert Rainbow: false + Max Color: 255; 255; 255 + Min Color: 0; 0; 0 + Name: PointCloud2 + Position Transformer: XYZ + Queue Size: 10 + Selectable: true + Size (Pixels): 3 + Size (m): 0.009999999776482582 + Style: Flat Squares + Topic: /elvation_mapping/pointcloud_semantic + Unreliable: false + Use Fixed Frame: true + Use rainbow: true + Value: false + - Alpha: 1 + Autocompute Intensity Bounds: true + Autocompute Value Bounds: + Max Value: 10 + Min Value: -10 + Value: true + Axis: Z + Channel Name: intensity + Class: rviz/PointCloud2 + Color: 255; 255; 255 + Color Transformer: RGB8 + Decay Time: 0 + Enabled: false + Invert Rainbow: false + Max Color: 255; 255; 255 + Min Color: 0; 0; 0 + Name: PointCloud2 + Position Transformer: XYZ + Queue Size: 10 + Selectable: true + Size (Pixels): 3 + Size (m): 0.009999999776482582 + Style: Flat Squares + Topic: /elvation_mapping/pointcloud_semantic_right + Unreliable: false + Use Fixed Frame: true + Use rainbow: true + Value: false + - Class: rviz/TF + Enabled: true + Frame Timeout: 15 + Frames: + All Enabled: true + GPS_back: + Value: true + GPS_front: + Value: true + alphasense: + Value: true + base_footprint: + Value: true + base_inertial: + Value: true + base_link: + Value: true + enu: + Value: true + estimator_imu: + Value: true + left_back_wheel: + Value: true + left_back_wheel_sup: + Value: true + left_front_wheel: + Value: true + left_front_wheel_sup: + Value: true + rear_axle_center: + Value: true + right_back_wheel: + Value: true + right_back_wheel_sup: + Value: true + right_front_wheel: + Value: true + right_front_wheel_sup: + Value: true + zed2i_baro_link: + Value: true + zed2i_base_link: + Value: true + zed2i_camera_center: + Value: true + zed2i_left_camera_frame: + Value: true + zed2i_left_camera_optical_frame: + Value: true + zed2i_mag_link: + Value: true + zed2i_right_camera_frame: + Value: true + zed2i_right_camera_optical_frame: + Value: true + zed2i_temp_left_link: + Value: true + zed2i_temp_right_link: + Value: true + Marker Alpha: 1 + Marker Scale: 1 + Name: TF + Show Arrows: true + Show Axes: true + Show Names: true + Tree: + enu: + base_link: + base_footprint: + {} + base_inertial: + {} + estimator_imu: + GPS_back: + {} + GPS_front: + {} + alphasense: + {} + left_back_wheel_sup: + left_back_wheel: + {} + left_front_wheel_sup: + left_front_wheel: + {} + rear_axle_center: + {} + right_back_wheel_sup: + right_back_wheel: + {} + right_front_wheel_sup: + right_front_wheel: + {} + zed2i_base_link: + zed2i_camera_center: + zed2i_baro_link: + {} + zed2i_left_camera_frame: + zed2i_left_camera_optical_frame: + {} + zed2i_temp_left_link: + {} + zed2i_mag_link: + {} + zed2i_right_camera_frame: + zed2i_right_camera_optical_frame: + {} + zed2i_temp_right_link: + {} + Update Interval: 0 + Value: true + - Class: rviz/Image + Enabled: true + Image Topic: /zed2i/zed_node/left/image_rect_color + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Queue Size: 2 + Transport Hint: raw + Unreliable: false + Value: true + - Class: rviz/Image + Enabled: true + Image Topic: /semantic_pointcloud/sem_seg + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Queue Size: 2 + Transport Hint: raw + Unreliable: false + Value: true + - Class: rviz/Marker + Enabled: true + Marker Topic: /visualization_marker_l + Name: Marker + Namespaces: + {} + Queue Size: 100 + Value: true + - Class: rviz/Marker + Enabled: true + Marker Topic: /visualization_marker_r + Name: Marker + Namespaces: + {} + Queue Size: 100 + Value: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: traversability + Color Transformer: GridMapLayer + Enabled: false + Height Layer: elevation + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 255; 255; 255 + Max Intensity: 10 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: GridMap + Show Grid Lines: true + Topic: /elevation_mapping/elevation_map_raw + Unreliable: false + Use Rainbow: true + Value: false + Enabled: true + Global Options: + Background Color: 255; 255; 255 + Default Light: true + Fixed Frame: enu + Frame Rate: 30 + Name: root + Tools: + - Class: rviz/Interact + Hide Inactive Objects: true + - Class: rviz/MoveCamera + - Class: rviz/Select + - Class: rviz/FocusCamera + - Class: rviz/Measure + - Class: rviz/SetInitialPose + Theta std deviation: 0.2617993950843811 + Topic: /initialpose + X std deviation: 0.5 + Y std deviation: 0.5 + - Class: rviz/SetGoal + Topic: /move_base_simple/goal + - Class: rviz/PublishPoint + Single click: true + Topic: /clicked_point + Value: true + Views: + Current: + Class: rviz/Orbit + Distance: 7.332578659057617 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Field of View: 0.7853981852531433 + Focal Point: + X: 0.7929360866546631 + Y: 0.3796532452106476 + Z: -0.4990573823451996 + Focal Shape Fixed Size: true + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 0.43979740142822266 + Target Frame: base_footprint + Yaw: 2.8488521575927734 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 1043 + Hide Left Dock: false + Hide Right Dock: true + Image: + collapsed: false + QMainWindow State: 000000ff00000000fd0000000400000000000001f5000003b9fc020000000cfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000001cb000000c900fffffffb0000000a0049006d006100670065010000020e000001040000001600fffffffb0000000a0049006d0061006700650100000318000000de0000001600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d0061006700650000000325000000d10000000000000000fb0000000a0049006d006100670065010000032a000000cc0000000000000000000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000078000000131fc0100000002fb0000000800540069006d00650000000000000007380000041800fffffffb0000000800540069006d0065010000000000000450000000000000000000000585000003b900000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: true + Width: 1920 + X: 0 + Y: 0 From 8d0e2397adb1652f5e8f660cc3fc423fd9f5a150 Mon Sep 17 00:00:00 2001 From: Gian Date: Mon, 12 Dec 2022 16:30:09 +0100 Subject: [PATCH 302/504] removed artifacts Jonas mentioned and added image layers to lonomy --- .../config/anymal_sensor_parameter.yaml | 14 ++++-------- .../config/lonomy_parameters.yaml | 2 +- .../config/lonomy_sensor_parameter.yaml | 14 ++++++++++++ .../config/sensor_parameter.yaml | 5 ----- .../rviz/lonomy_single.rviz | 22 +++++++++---------- 5 files changed, 30 insertions(+), 27 deletions(-) diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml index edae6030..d80d9611 100644 --- a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml @@ -41,11 +41,9 @@ subscribers: fusion: ['image_color'] topic_name_camera: /alphasense_driver_ros/cam4/debayered topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info - channels: ["rgb_image"] + channels: ["rgb_image"] data_type: image - fusion_types: - array_fusion: [] - channels: [] + alphasense_left_rgb: fusion: ['image_color'] @@ -53,9 +51,7 @@ subscribers: topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info channels: ["rgb_image"] data_type: image - fusion_types: - array_fusion: [] - channels: [] + alphasense_right_rgb: fusion: ['image_color'] @@ -63,9 +59,7 @@ subscribers: topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info channels: ["rgb_image"] data_type: image - fusion_types: - array_fusion: [] - channels: [] + wvn_prediction: fusion: ['image_exponential'] diff --git a/elevation_mapping_cupy/config/lonomy_parameters.yaml b/elevation_mapping_cupy/config/lonomy_parameters.yaml index a7cbeaee..55ce14cd 100644 --- a/elevation_mapping_cupy/config/lonomy_parameters.yaml +++ b/elevation_mapping_cupy/config/lonomy_parameters.yaml @@ -81,7 +81,7 @@ publishers: basic_layers: ['elevation', 'traversability'] fps: 2.0 elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb','robot_centric_elevation','sem_fil','sem_traversability'] + layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb','robot_centric_elevation','sem_fil','sem_traversability','rgb_image','gray_image'] basic_layers: ['min_filter'] fps: 3.0 diff --git a/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml b/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml index 30b3caf4..74db3453 100644 --- a/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml @@ -26,3 +26,17 @@ subscribers: confidence_topic: "/zed2i/zed_node/confidence/confidence_map" confidence_threshold: 10 feature_extractor: False + + rgb_cam: + fusion: [ 'image_color' ] + topic_name_camera: "/zed2i/zed_node/left/image_rect_color" + topic_name_camera_info: "/zed2i/zed_node/depth/camera_info" + channels: [ "rgb_image" ] + data_type: image + + grey_cam: + fusion: [ 'image_exponential' ] + topic_name_camera: "/zed2i/zed_node/left/image_rect_gray" + topic_name_camera_info: "/zed2i/zed_node/depth/camera_info" + channels: [ "gray_image" ] + data_type: image \ No newline at end of file diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index beefa91c..61078e2d 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -6,11 +6,6 @@ subscribers: topic_name_camera_info: /zed2i/zed_node/right/camera_info channels: ["rgb_image"] data_type: image - fusion_types: - array_fusion: [] - channels: [] - - # debug_rgb_3_seperate: # fusion: ['image_exponential','image_exponential','image_exponential'] diff --git a/elevation_mapping_cupy/rviz/lonomy_single.rviz b/elevation_mapping_cupy/rviz/lonomy_single.rviz index 05d3d87d..a3ec715d 100644 --- a/elevation_mapping_cupy/rviz/lonomy_single.rviz +++ b/elevation_mapping_cupy/rviz/lonomy_single.rviz @@ -3,9 +3,10 @@ Panels: Help Height: 138 Name: Displays Property Tree Widget: - Expanded: ~ + Expanded: + - /ElevationMapFilter1 Splitter Ratio: 0.5768463015556335 - Tree Height: 260 + Tree Height: 247 - Class: rviz/Selection Name: Selection - Class: rviz/Tool Properties @@ -53,10 +54,10 @@ Visualization Manager: Autocompute Intensity Bounds: true Class: grid_map_rviz_plugin/GridMap Color: 200; 200; 200 - Color Layer: sem_fil + Color Layer: rgb Color Transformer: ColorLayer Enabled: true - Height Layer: elevation + Height Layer: min_filter Height Transformer: GridMapLayer History Length: 1 Invert Rainbow: false @@ -66,7 +67,7 @@ Visualization Manager: Min Intensity: 0 Name: ElevationMapFilter Show Grid Lines: true - Topic: /elevation_mapping/elevation_map_raw + Topic: /elevation_mapping/elevation_map_filter Unreliable: false Use Rainbow: false Value: true @@ -161,7 +162,6 @@ Visualization Manager: Alpha: 1 Show Axes: false Show Trail: false - Value: true zed2i_left_camera_frame: Alpha: 1 Show Axes: false @@ -475,12 +475,12 @@ Visualization Manager: Window Geometry: Displays: collapsed: false - Height: 1043 + Height: 1016 Hide Left Dock: false Hide Right Dock: true Image: collapsed: false - QMainWindow State: 000000ff00000000fd0000000400000000000001f5000003b9fc020000000cfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000001cb000000c900fffffffb0000000a0049006d006100670065010000020e000001040000001600fffffffb0000000a0049006d0061006700650100000318000000de0000001600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d0061006700650000000325000000d10000000000000000fb0000000a0049006d006100670065010000032a000000cc0000000000000000000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000078000000131fc0100000002fb0000000800540069006d00650000000000000007380000041800fffffffb0000000800540069006d0065010000000000000450000000000000000000000585000003b900000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd0000000400000000000001f50000039efc020000000cfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000001be000000c900fffffffb0000000a0049006d0061006700650100000201000000fc0000001600fffffffb0000000a0049006d0061006700650100000303000000d80000001600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d0061006700650000000325000000d10000000000000000fb0000000a0049006d006100670065010000032a000000cc0000000000000000000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000078000000131fc0100000002fb0000000800540069006d00650000000000000007380000041800fffffffb0000000800540069006d006501000000000000045000000000000000000000053d0000039e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -489,6 +489,6 @@ Window Geometry: collapsed: false Views: collapsed: true - Width: 1920 - X: 0 - Y: 0 + Width: 1848 + X: 72 + Y: 27 From 5564671c9f634518176066706ea2fea89fc101e9 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Mon, 12 Dec 2022 12:39:44 -0800 Subject: [PATCH 303/504] fixed bugs in configuration --- .../config/anymal_sensor_parameter.yaml | 20 +++++++++---------- .../config/lonomy_parameters.yaml | 2 +- .../elevation_mapping_ros.py | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml index d80d9611..f4a318ec 100644 --- a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml @@ -94,17 +94,17 @@ subscribers: # confidence_threshold: 10 # feature_extractor: False - # front_bpearl: - # channels: [] - # fusion: ['average'] - # topic_name: /robot_self_filter/bpearl_front/point_cloud - # type: pointcloud + front_bpearl: + channels: [] + fusion: ['average'] + topic_name: /robot_self_filter/bpearl_front/point_cloud + data_type: pointcloud - # rear_bpearl: - # channels: [] - # fusion: ['average'] - # topic_name: /robot_self_filter/bpearl_rear/point_cloud - # type: pointcloud + rear_bpearl: + channels: [] + fusion: ['average'] + topic_name: /robot_self_filter/bpearl_rear/point_cloud + data_type: pointcloud front_depth: channels: [] diff --git a/elevation_mapping_cupy/config/lonomy_parameters.yaml b/elevation_mapping_cupy/config/lonomy_parameters.yaml index 55ce14cd..cdc1ec2f 100644 --- a/elevation_mapping_cupy/config/lonomy_parameters.yaml +++ b/elevation_mapping_cupy/config/lonomy_parameters.yaml @@ -61,7 +61,7 @@ weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' use_only_above_for_upper_bound: false #### Plugins ######## -plugin_config_file: '$(rospack find lonomy_configuration)/elevation_map/config/plugin_config.yaml' +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/lonomy_plugin_config.yaml' #### Subscribers ######## diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index 8a61123e..c1f95192 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -175,7 +175,7 @@ def pointcloud_callback(self, msg, sub_key): points = ros_numpy.numpify(msg) pts = np.empty((points.shape[0], 0)) for ch in channels: - pts = np.append(pts, np.expand_dims(points[ch], 1), axis=1) + pts = np.append(pts, points[ch], axis=1) # get pose of pointcloud ti = rospy.Time(secs=msg.header.stamp.secs, nsecs=msg.header.stamp.nsecs) @@ -226,8 +226,8 @@ def update_time(self, t): def get_ros_params(self): # TODO fix this here when later launching with launch-file # This is currently {p} elevation_mapping") - para = os.path.join(self.root, "config/parameters.yaml") - sens = os.path.join(self.root, "config/sensor_parameter.yaml") + para = os.path.join(self.root, "config/anymal_parameters.yaml") + sens = os.path.join(self.root, "config/anymal_sensor_parameter.yaml") os.system(f"rosparam delete /{self.node_name}") os.system(f"rosparam load {para} elevation_mapping") os.system(f"rosparam load {sens} elevation_mapping") From 8ffde09605804385f4b0f11c0df0f78f92814175 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Mon, 12 Dec 2022 13:16:44 -0800 Subject: [PATCH 304/504] updated the wrapper --- .../elevation_mapping_ros.py | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index c1f95192..ee4f0e41 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -161,8 +161,13 @@ def image_callback(self, camera_msg, camera_info_msg, sub_key): R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") - semantic_img = [semantic_img[:, :, k] for k in range(3)] - + + if len(semantic_img.shape) != 2: + semantic_img = [semantic_img[:, :, k] for k in range(3)] + + else: + semantic_img = [semantic_img] + assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) # process pointcloud @@ -175,7 +180,10 @@ def pointcloud_callback(self, msg, sub_key): points = ros_numpy.numpify(msg) pts = np.empty((points.shape[0], 0)) for ch in channels: - pts = np.append(pts, points[ch], axis=1) + p = points[ch] + if len(p.shape) == 1: + p = p[:,None] + pts = np.append(pts, p, axis=1) # get pose of pointcloud ti = rospy.Time(secs=msg.header.stamp.secs, nsecs=msg.header.stamp.nsecs) @@ -226,11 +234,15 @@ def update_time(self, t): def get_ros_params(self): # TODO fix this here when later launching with launch-file # This is currently {p} elevation_mapping") - para = os.path.join(self.root, "config/anymal_parameters.yaml") - sens = os.path.join(self.root, "config/anymal_sensor_parameter.yaml") + typ = "lonomy" + para = os.path.join(self.root, f"config/{typ}_parameters.yaml") + sens = os.path.join(self.root, f"config/{typ}_sensor_parameter.yaml") + plugin = os.path.join(self.root, f"config/{typ}_plugin_config.yaml") + os.system(f"rosparam delete /{self.node_name}") os.system(f"rosparam load {para} elevation_mapping") os.system(f"rosparam load {sens} elevation_mapping") + os.system(f"rosparam load {plugin} elevation_mapping") self.subscribers = rospy.get_param("~subscribers") self.publishers = rospy.get_param("~publishers") self.initialize_frame_id = rospy.get_param("~initialize_frame_id", "base") From ab68c3cb1bff7be8090d1c635512980fc2ee4981 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Mon, 12 Dec 2022 14:31:47 -0800 Subject: [PATCH 305/504] bug fix with black formatting --- .../config/anymal_parameters.yaml | 2 +- .../config/anymal_plugin_config.yaml | 61 ++++++++ .../config/anymal_sensor_parameter.yaml | 102 +++++++------- .../config/lonomy_parameters.yaml | 6 +- .../config/lonomy_sensor_parameter.yaml | 6 +- .../anymal_semantic_elevation_single.launch | 2 +- .../launch/lonomy_pointcloud.launch | 4 +- .../elevation_mapping.py | 132 +++++------------- .../elevation_mapping_ros.py | 49 ++++--- .../kernels/custom_semantic_kernels.py | 46 +++--- .../plugins/semantic_traversability.py | 4 +- .../elevation_mapping_cupy/semantic_map.py | 40 ++---- .../tests/test_elevation_mapping.py | 8 +- .../tests/test_plugins.py | 8 +- 14 files changed, 226 insertions(+), 244 deletions(-) create mode 100644 elevation_mapping_cupy/config/anymal_plugin_config.yaml diff --git a/elevation_mapping_cupy/config/anymal_parameters.yaml b/elevation_mapping_cupy/config/anymal_parameters.yaml index 4941a011..b92bb6da 100644 --- a/elevation_mapping_cupy/config/anymal_parameters.yaml +++ b/elevation_mapping_cupy/config/anymal_parameters.yaml @@ -61,7 +61,7 @@ weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' use_only_above_for_upper_bound: false #### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/plugin_config.yaml' +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin_config.yaml' #### Publishers ######## # topic_name: diff --git a/elevation_mapping_cupy/config/anymal_plugin_config.yaml b/elevation_mapping_cupy/config/anymal_plugin_config.yaml new file mode 100644 index 00000000..07f34e6a --- /dev/null +++ b/elevation_mapping_cupy/config/anymal_plugin_config.yaml @@ -0,0 +1,61 @@ +# Settings of the plugins. (The plugins should be stored in script/plugins) + +# min_filter fills in minimum value around the invalid cell. +min_filter: + enable: False # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations +# Apply smoothing. +smooth_filter: + enable: False + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" +# Apply inpainting using opencv +inpainting: + enable: False + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns +# Apply smoothing for inpainted layer + +robot_centric_elevation: # Use the same name as your file name. +# type: "robot_centric_elevation" + enable: False # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "robot_centric_elevation" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. +# add_value: 2.0 # Example param + resolution: 0.04 + threshold: 1.1 + use_threshold: True + +semantic_filter: + type: "semantic_filter" + enable: False + fill_nan: False + is_height_layer: False + layer_name: "sem_fil" + extra_params: + classes: ['grass','tree','fence','dirt'] + +semantic_traversability: + type: "semantic_traversability" + enable: False + fill_nan: False + is_height_layer: False + layer_name: "sem_traversability" + extra_params: + layers: ['traversability','robot_centric_elevation'] + thresholds: [0.3,0.5] + type: ['traversability', 'elevation'] + diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml index f4a318ec..4363a22e 100644 --- a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml @@ -37,36 +37,36 @@ subscribers: # topic_name: '/elevation_mapping/pointcloud_semantic' # data_type: pointcloud - alphasense_front_rgb: - fusion: ['image_color'] - topic_name_camera: /alphasense_driver_ros/cam4/debayered - topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info - channels: ["rgb_image"] - data_type: image + # alphasense_front_rgb: + # fusion: ['image_color'] + # topic_name_camera: /alphasense_driver_ros/cam4/debayered + # topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info + # channels: ["rgb_image"] + # data_type: image - alphasense_left_rgb: - fusion: ['image_color'] - topic_name_camera: /alphasense_driver_ros/cam3/debayered - topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info - channels: ["rgb_image"] - data_type: image + # alphasense_left_rgb: + # fusion: ['image_color'] + # topic_name_camera: /alphasense_driver_ros/cam3/debayered + # topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info + # channels: ["rgb_image"] + # data_type: image - alphasense_right_rgb: - fusion: ['image_color'] - topic_name_camera: /alphasense_driver_ros/cam5/debayered - topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info - channels: ["rgb_image"] - data_type: image + # alphasense_right_rgb: + # fusion: ['image_color'] + # topic_name_camera: /alphasense_driver_ros/cam5/debayered + # topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info + # channels: ["rgb_image"] + # data_type: image - wvn_prediction: - fusion: ['image_exponential'] - topic_name_camera: '/wild_visual_navigation_node/current_prediction' - topic_name_camera_info: '/wild_visual_navigation_node/camera_info' - channels: ["visual_traversability"] - data_type: image + # wvn_prediction: + # fusion: ['image_exponential'] + # topic_name_camera: '/wild_visual_navigation_node/current_prediction' + # topic_name_camera_info: '/wild_visual_navigation_node/camera_info' + # channels: ["visual_traversability"] + # data_type: image # front_cam: # channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] @@ -96,36 +96,36 @@ subscribers: front_bpearl: channels: [] - fusion: ['average'] - topic_name: /robot_self_filter/bpearl_front/point_cloud + fusion: [] + topic_name: /point_cloud_filter_rsl/filter_and_merger_rsl data_type: pointcloud - rear_bpearl: - channels: [] - fusion: ['average'] - topic_name: /robot_self_filter/bpearl_rear/point_cloud - data_type: pointcloud + # rear_bpearl: + # channels: [] + # fusion: [] + # topic_name: /robot_self_filter/bpearl_rear/point_cloud + # data_type: pointcloud - front_depth: - channels: [] - fusion: ['average'] - topic_name: /depth_camera_front/point_cloud_self_filtered - data_type: pointcloud + # front_depth: + # channels: [] + # fusion: [] + # topic_name: /depth_camera_front/point_cloud_self_filtered + # data_type: pointcloud - rear_depth: - channels: [] - fusion: ['average'] - topic_name: /depth_camera_rear/point_cloud_self_filtered - data_type: pointcloud + # rear_depth: + # channels: [] + # fusion: [] + # topic_name: /depth_camera_rear/point_cloud_self_filtered + # data_type: pointcloud - left_depth: - channels: [] - fusion: ['average'] - topic_name: /depth_camera_left/point_cloud_self_filtered - data_type: pointcloud + # left_depth: + # channels: [] + # fusion: [] + # topic_name: /depth_camera_left/point_cloud_self_filtered + # data_type: pointcloud - right_depth: - channels: [] - fusion: ['average'] - topic_name: /depth_camera_right/point_cloud_self_filtered - data_type: pointcloud \ No newline at end of file + # right_depth: + # channels: [] + # fusion: [] + # topic_name: /depth_camera_right/point_cloud_self_filtered + # data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/config/lonomy_parameters.yaml b/elevation_mapping_cupy/config/lonomy_parameters.yaml index cdc1ec2f..ea94002f 100644 --- a/elevation_mapping_cupy/config/lonomy_parameters.yaml +++ b/elevation_mapping_cupy/config/lonomy_parameters.yaml @@ -73,7 +73,7 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/lonomy_plugin # fps: # Publish rate. Use smaller value than `map_acquire_fps`. publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','sem_fil'] + layers: ['elevation', 'traversability', 'variance'] basic_layers: ['elevation', 'traversability'] fps: 5.0 elevation_map_recordable: @@ -81,8 +81,8 @@ publishers: basic_layers: ['elevation', 'traversability'] fps: 2.0 elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb','robot_centric_elevation','sem_fil','sem_traversability','rgb_image','gray_image'] - basic_layers: ['min_filter'] + layers: [elevation, 'min_filter', 'smooth', 'inpaint', 'upper_bound','rgb_image', 'gray_image'] + basic_layers: [elevation, 'min_filter'] fps: 3.0 #### Initializer ######## diff --git a/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml b/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml index 74db3453..58581b42 100644 --- a/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml @@ -1,9 +1,9 @@ subscribers: front_cam: - channels: [ 'rgb','feat_0','feat_1','__background__','car',"max" ] - fusion: [ 'color','bayesian_inference','bayesian_inference','class_average','class_average',"class_max" ] + channels: [ 'rgb','feat_0','feat_1'] + fusion: [ 'color','bayesian_inference','bayesian_inference'] topic_name: '/elvation_mapping/pointcloud_semantic' - semantic_segmentation: True + semantic_segmentation: False segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large show_label_legend: True data_type: pointcloud diff --git a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch index 2e1d7575..7c3fcc1b 100644 --- a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch +++ b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch @@ -16,6 +16,6 @@ - + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/lonomy_pointcloud.launch b/elevation_mapping_cupy/launch/lonomy_pointcloud.launch index a93792b0..8e9568c8 100644 --- a/elevation_mapping_cupy/launch/lonomy_pointcloud.launch +++ b/elevation_mapping_cupy/launch/lonomy_pointcloud.launch @@ -9,8 +9,6 @@ - - - + \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 5a68edb1..23922213 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -68,9 +68,7 @@ def __init__(self, param: Parameter): self.map_lock = threading.Lock() self.semantic_map = SemanticMap(self.param) - self.elevation_map = xp.zeros( - (7, self.cell_n, self.cell_n), dtype=self.data_type - ) + self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n), dtype=self.data_type) self.layer_names = [ "elevation", "variance", @@ -109,25 +107,17 @@ def __init__(self, param: Parameter): param.load_weights(weight_file) if param.use_chainer: - self.traversability_filter = get_filter_chainer( - param.w1, param.w2, param.w3, param.w_out - ) + self.traversability_filter = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) else: - self.traversability_filter = get_filter_torch( - param.w1, param.w2, param.w3, param.w_out - ) + self.traversability_filter = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) self.untraversable_polygon = xp.zeros((1, 2)) # Plugins self.plugin_manager = PluginManager(cell_n=self.cell_n) - plugin_config_file = subprocess.getoutput( - 'echo "' + param.plugin_config_file + '"' - ) + plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') self.plugin_manager.load_plugin_settings(plugin_config_file) - self.map_initializer = MapInitializer( - self.initial_variance, param.initialized_variance, xp=cp, method="points" - ) + self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") def clear(self): """Reset all the layers of the elevation & the semantic map.""" @@ -223,9 +213,7 @@ def shift_map_xy(self, delta_pixel): with self.map_lock: self.elevation_map = cp.roll(self.elevation_map, shift_value, axis=(1, 2)) self.pad_value(self.elevation_map, shift_value, value=0.0) - self.pad_value( - self.elevation_map, shift_value, idx=1, value=self.initial_variance - ) + self.pad_value(self.elevation_map, shift_value, idx=1, value=self.initial_variance) self.semantic_map.shift_map_xy(shift_value) def shift_map_z(self, delta_z): @@ -247,16 +235,10 @@ def compile_kernels(self): (self.elevation_map.shape[0], self.cell_n, self.cell_n), dtype=self.data_type, ) - self.traversability_input = cp.zeros( - (self.cell_n, self.cell_n), dtype=self.data_type - ) - self.traversability_mask_dummy = cp.zeros( - (self.cell_n, self.cell_n), dtype=self.data_type - ) + self.traversability_input = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + self.traversability_mask_dummy = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) self.min_filtered = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) - self.min_filtered_mask = cp.zeros( - (self.cell_n, self.cell_n), dtype=self.data_type - ) + self.min_filtered_mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) self.mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) self.add_points_kernel = add_points_kernel( self.resolution, @@ -295,18 +277,12 @@ def compile_kernels(self): self.cell_n, self.cell_n, self.param.max_variance, self.initial_variance ) - self.dilation_filter_kernel = dilation_filter_kernel( - self.cell_n, self.cell_n, self.param.dilation_size - ) + self.dilation_filter_kernel = dilation_filter_kernel(self.cell_n, self.cell_n, self.param.dilation_size) self.dilation_filter_kernel_initializer = dilation_filter_kernel( self.cell_n, self.cell_n, self.param.dilation_size_initialize ) - self.polygon_mask_kernel = polygon_mask_kernel( - self.cell_n, self.cell_n, self.resolution - ) - self.normal_filter_kernel = normal_filter_kernel( - self.cell_n, self.cell_n, self.resolution - ) + self.polygon_mask_kernel = polygon_mask_kernel(self.cell_n, self.cell_n, self.resolution) + self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) def compile_image_kernels(self): for config in self.param.subscriber_cfg.values(): @@ -319,13 +295,11 @@ def compile_image_kernels(self): dtype=np.float32, ) # TODO tolerance_z_collision add parameter - self.image_to_map_correspondence_kernel = ( - image_to_map_correspondence_kernel( - resolution=self.resolution, - width=self.cell_n, - height=self.cell_n, - tolerance_z_collision=0.1, - ) + self.image_to_map_correspondence_kernel = image_to_map_correspondence_kernel( + resolution=self.resolution, + width=self.cell_n, + height=self.cell_n, + tolerance_z_collision=0.1, ) break @@ -337,9 +311,7 @@ def shift_translation_to_map_center(self, t): """ t -= self.center - def update_map_with_kernel( - self, points_all, channels, R, t, position_noise, orientation_noise - ): + def update_map_with_kernel(self, points_all, channels, R, t, position_noise, orientation_noise): """Update map with new measurement. Args: @@ -380,9 +352,7 @@ def update_map_with_kernel( self.mean_error = error / error_cnt self.additive_mean_error += self.mean_error if np.abs(self.mean_error) < self.param.max_drift: - self.elevation_map[0] += ( - self.mean_error * self.param.drift_compensation_alpha - ) + self.elevation_map[0] += self.mean_error * self.param.drift_compensation_alpha self.add_points_kernel( cp.array([0.0], dtype=self.data_type), cp.array([0.0], dtype=self.data_type), @@ -394,14 +364,10 @@ def update_map_with_kernel( self.new_map, size=(points.shape[0]), ) - self.average_map_kernel( - self.new_map, self.elevation_map, size=(self.cell_n * self.cell_n) - ) + self.average_map_kernel(self.new_map, self.elevation_map, size=(self.cell_n * self.cell_n)) # self.update_additional_layers(additional_fusion, points_all, channels, R, t) - self.semantic_map.update_layers_pointcloud( - points_all, channels, R, t, self.new_map - ) + self.semantic_map.update_layers_pointcloud(points_all, channels, R, t, self.new_map) if self.param.enable_overlap_clearance: self.clear_overlap_map(t) @@ -427,9 +393,7 @@ def clear_overlap_map(self, t): # Clear overlapping area around center height_min = t[2] - self.param.overlap_clear_range_z height_max = t[2] + self.param.overlap_clear_range_z - near_map = self.elevation_map[ - :, self.cell_min : self.cell_max, self.cell_min : self.cell_max - ] + near_map = self.elevation_map[:, self.cell_min : self.cell_max, self.cell_min : self.cell_max] valid_idx = ~cp.logical_or(near_map[0] < height_min, near_map[0] > height_max) near_map[0] = cp.where(valid_idx, near_map[0], 0.0) near_map[1] = cp.where(valid_idx, near_map[1], self.initial_variance) @@ -437,9 +401,7 @@ def clear_overlap_map(self, t): valid_idx = ~cp.logical_or(near_map[5] < height_min, near_map[5] > height_max) near_map[5] = cp.where(valid_idx, near_map[5], 0.0) near_map[6] = cp.where(valid_idx, near_map[6], 0.0) - self.elevation_map[ - :, self.cell_min : self.cell_max, self.cell_min : self.cell_max - ] = near_map + self.elevation_map[:, self.cell_min : self.cell_max, self.cell_min : self.cell_max] = near_map def get_additive_mean_error(self): return self.additive_mean_error @@ -452,9 +414,7 @@ def update_time(self): def update_upper_bound_with_valid_elevation(self): mask = self.elevation_map[2] > 0.5 - self.elevation_map[5] = cp.where( - mask, self.elevation_map[0], self.elevation_map[5] - ) + self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) def input( @@ -583,14 +543,10 @@ def process_map_for_publish(self, input_map, fill_nan=False, add_z=False, xp=cp) return m[1:-1, 1:-1] def get_elevation(self): - return self.process_map_for_publish( - self.elevation_map[0], fill_nan=True, add_z=True - ) + return self.process_map_for_publish(self.elevation_map[0], fill_nan=True, add_z=True) def get_variance(self): - return self.process_map_for_publish( - self.elevation_map[1], fill_nan=False, add_z=False - ) + return self.process_map_for_publish(self.elevation_map[1], fill_nan=False, add_z=False) def get_traversability(self): traversability = cp.where( @@ -603,22 +559,16 @@ def get_traversability(self): return traversability def get_time(self): - return self.process_map_for_publish( - self.elevation_map[4], fill_nan=False, add_z=False - ) + return self.process_map_for_publish(self.elevation_map[4], fill_nan=False, add_z=False) def get_upper_bound(self): if self.param.use_only_above_for_upper_bound: valid = cp.logical_or( - cp.logical_and( - self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5 - ), + cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), self.elevation_map[2] > 0.5, ) else: - valid = cp.logical_or( - self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5 - ) + valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) upper_bound = cp.where(valid, self.elevation_map[5].copy(), cp.nan) upper_bound = upper_bound[1:-1, 1:-1] + self.center[2] return upper_bound @@ -626,15 +576,11 @@ def get_upper_bound(self): def get_is_upper_bound(self): if self.param.use_only_above_for_upper_bound: valid = cp.logical_or( - cp.logical_and( - self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5 - ), + cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), self.elevation_map[2] > 0.5, ) else: - valid = cp.logical_or( - self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5 - ) + valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) is_upper_bound = cp.where(valid, self.elevation_map[6].copy(), cp.nan) is_upper_bound = is_upper_bound[1:-1, 1:-1] return is_upper_bound @@ -730,9 +676,7 @@ def get_map_with_name_ref(self, name, data): m = self.plugin_manager.get_map_with_name(name) p = self.plugin_manager.get_param_with_name(name) xp = self.xp_of_array(m) - m = self.process_map_for_publish( - m, fill_nan=p.fill_nan, add_z=p.is_height_layer, xp=xp - ) + m = self.process_map_for_publish(m, fill_nan=p.fill_nan, add_z=p.is_height_layer, xp=xp) else: print("Layer {} is not in the map".format(name)) return @@ -815,9 +759,7 @@ def get_polygon_traversability(self, polygon, result): size=(self.cell_n * self.cell_n), ) tmp_map = self.get_layer(self.param.checker_layer) - masked, masked_isvalid = get_masked_traversability( - self.elevation_map, self.mask, tmp_map - ) + masked, masked_isvalid = get_masked_traversability(self.elevation_map, self.mask, tmp_map) if masked_isvalid.sum() > 0: t = masked.sum() / masked_isvalid.sum() else: @@ -830,9 +772,7 @@ def get_polygon_traversability(self, polygon, result): ) untraversable_polygon_num = 0 if un_polygon is not None: - un_polygon = transform_to_map_position( - un_polygon, self.center[:2], self.cell_n, self.resolution - ) + un_polygon = transform_to_map_position(un_polygon, self.center[:2], self.cell_n, self.resolution) untraversable_polygon_num = un_polygon.shape[0] if clipped_area < 0.001: is_safe = False @@ -859,9 +799,7 @@ def initialize_map(self, points, method="cubic"): self.clear() with self.map_lock: points = cp.asarray(points, dtype=self.data_type) - indices = transform_to_map_index( - points[:, :2], self.center[:2], self.cell_n, self.resolution - ) + indices = transform_to_map_index(points[:, :2], self.center[:2], self.cell_n, self.resolution) points[:, :2] = indices.astype(points.dtype) points[:, 2] -= self.center[2] self.map_initializer(self.elevation_map, points, method) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index ee4f0e41..aab2d115 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -104,6 +104,7 @@ def register_publishers(self): self._publishers_timers.append(rospy.Timer(rospy.Duration(1 / v["fps"]), partial(self.publish_map, k))) def publish_map(self, k, t): + print("publish_map") if self._map_q is None: return gm = GridMap() @@ -120,19 +121,24 @@ def publish_map(self, k, t): gm.info.pose.orientation.x = 0.0 # self._map_q.x gm.info.pose.orientation.y = 0.0 # self._map_q.y gm.info.pose.orientation.z = 0.0 # self._map_q.z - gm.layers = self.publishers[k]["layers"] + gm.layers = [] gm.basic_layers = self.publishers[k]["basic_layers"] - for i, layer in enumerate(gm.layers): - self._map.get_map_with_name_ref(layer, self._map_data) - # self._map_data = np.nan_to_num(self._map_data, False, 0) - data = self._map_data.copy() - arr = Float32MultiArray() - arr.layout = MAL() - N = self._map_data.shape[0] - arr.layout.dim.append(MAD(label="column_index", size=N, stride=int(N * N))) - arr.layout.dim.append(MAD(label="row_index", size=N, stride=N)) - arr.data = tuple(np.ascontiguousarray(data.T).reshape(-1)) - gm.data.append(arr) + for i, layer in enumerate(self.publishers[k]["layers"]): + gm.layers.append(layer) + try: + self._map.get_map_with_name_ref(layer, self._map_data) + data = self._map_data.copy() + arr = Float32MultiArray() + arr.layout = MAL() + N = self._map_data.shape[0] + arr.layout.dim.append(MAD(label="column_index", size=N, stride=int(N * N))) + arr.layout.dim.append(MAD(label="row_index", size=N, stride=N)) + arr.data = tuple(np.ascontiguousarray(data.T).reshape(-1)) + gm.data.append(arr) + except: + if layer in gm.basic_layers: + print("Error: Missed Layer in basic layers") + gm.outer_start_index = 0 gm.inner_start_index = 0 @@ -152,7 +158,7 @@ def image_callback(self, camera_msg, camera_info_msg, sub_key): camera_msg.header.frame_id, self.map_frame, ti, rospy.Duration(1.0) ) except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - print("image_callback error:", e) + print("Error: image_callback:", e) return t = transform.transform.translation @@ -161,13 +167,13 @@ def image_callback(self, camera_msg, camera_info_msg, sub_key): R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") - + if len(semantic_img.shape) != 2: semantic_img = [semantic_img[:, :, k] for k in range(3)] - + else: semantic_img = [semantic_img] - + assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) # process pointcloud @@ -182,7 +188,7 @@ def pointcloud_callback(self, msg, sub_key): for ch in channels: p = points[ch] if len(p.shape) == 1: - p = p[:,None] + p = p[:, None] pts = np.append(pts, p, axis=1) # get pose of pointcloud @@ -191,7 +197,7 @@ def pointcloud_callback(self, msg, sub_key): try: transform = self._tf_buffer.lookup_transform(self.map_frame, msg.header.frame_id, ti, rospy.Duration(1.0)) except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - print("pointcloud_callback error:", e) + print("Error: pointcloud_callback: ", e) return t = transform.transform.translation @@ -214,7 +220,7 @@ def update_pose(self, t): self.map_frame, self.base_frame, self._last_t, rospy.Duration(1.0) ) except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - print("update_pose error: ", e) + print("Error: update_pose error: ", e) return t = transform.transform.translation trans = np.array([t.x, t.y, t.z]) @@ -234,15 +240,16 @@ def update_time(self, t): def get_ros_params(self): # TODO fix this here when later launching with launch-file # This is currently {p} elevation_mapping") - typ = "lonomy" + typ = "anymal" para = os.path.join(self.root, f"config/{typ}_parameters.yaml") sens = os.path.join(self.root, f"config/{typ}_sensor_parameter.yaml") plugin = os.path.join(self.root, f"config/{typ}_plugin_config.yaml") - + os.system(f"rosparam delete /{self.node_name}") os.system(f"rosparam load {para} elevation_mapping") os.system(f"rosparam load {sens} elevation_mapping") os.system(f"rosparam load {plugin} elevation_mapping") + self.subscribers = rospy.get_param("~subscribers") self.publishers = rospy.get_param("~publishers") self.initialize_frame_id = rospy.get_param("~initialize_frame_id", "base") diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py index e562c263..8aae5d02 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py @@ -1,6 +1,7 @@ import cupy as cp import string + def sum_kernel( resolution, width, @@ -37,11 +38,12 @@ def sum_kernel( ) return sum_kernel + def sum_compact_kernel( - resolution, - width, - height, - ): + resolution, + width, + height, +): # input the list of layers, amount of channels can slo be input through kernel sum_compact_kernel = cp.ElementwiseKernel( in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", @@ -53,7 +55,7 @@ def sum_compact_kernel( return layer * layer_n + idx; } """ - ).substitute(resolution=resolution,width=width, height=height), + ).substitute(resolution=resolution, width=width, height=height), operation=string.Template( """ U idx = p[i * pcl_channels[0]]; @@ -68,18 +70,17 @@ def sum_compact_kernel( } } """ - ).substitute( - ), + ).substitute(), name="sum_compact_kernel", ) return sum_compact_kernel def sum_max_kernel( - resolution, - width, - height, - ): + resolution, + width, + height, +): # input the list of layers, amount of channels can slo be input through kernel sum_max_kernel = cp.ElementwiseKernel( in_params="raw U p, raw U max_pt, raw T max_id, raw W pcl_chan, raw W map_lay, raw W pcl_channels", @@ -91,7 +92,7 @@ def sum_max_kernel( return layer * layer_n + idx; } """ - ).substitute(resolution=resolution,width=width, height=height), + ).substitute(resolution=resolution, width=width, height=height), operation=string.Template( """ U idx = p[i * pcl_channels[0]]; @@ -109,12 +110,12 @@ def sum_max_kernel( } } """ - ).substitute( - ), + ).substitute(), name="sum_max_kernel", ) return sum_max_kernel + def alpha_kernel( resolution, width, @@ -190,8 +191,8 @@ def average_kernel( def bayesian_inference_kernel( - width, - height, + width, + height, ): bayesian_inference_kernel = cp.ElementwiseKernel( in_params=" raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", @@ -220,16 +221,16 @@ def bayesian_inference_kernel( } } """ - ).substitute( - ), + ).substitute(), name="bayesian_inference_kernel", ) return bayesian_inference_kernel + def class_average_kernel( - width, - height, - alpha, + width, + height, + alpha, ): class_average_kernel = cp.ElementwiseKernel( in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", @@ -259,7 +260,8 @@ def class_average_kernel( } } """ - ).substitute(alpha=alpha, + ).substitute( + alpha=alpha, ), name="class_average_kernel", ) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py index f54c714c..2d0b9832 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py @@ -68,9 +68,7 @@ def __call__( idx = plugin_layer_names.index(name) tempo = plugin_layers[idx] else: - print( - "Layer {} is not in the map, returning traversabiltiy!".format(name) - ) + print("Layer {} is not in the map, returning traversabiltiy!".format(name)) return if self.type[it] == "traversability": tempo = cp.where(tempo <= self.thresholds[it], 1, 0) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 9ff5f5b9..7f52541f 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -44,9 +44,7 @@ def __init__(self, param: Parameter): self.layer_names.append(c) self.layer_specs[c] = f else: - assert ( - self.layer_specs[c] == f - ), "Error: Single layer has multiple fusion algorithms!" + assert self.layer_specs[c] == f, "Error: Single layer has multiple fusion algorithms!" if f not in self.unique_fusion: self.unique_fusion.append(f) @@ -113,9 +111,7 @@ def compile_kernels(self) -> None: self.param.cell_n, self.param.cell_n, ) - self.color_average_kernel = color_average_kernel( - self.param.cell_n, self.param.cell_n - ) + self.color_average_kernel = color_average_kernel(self.param.cell_n, self.param.cell_n) if "class_average" in self.unique_fusion: print("Initialize class average kernel") self.sum_kernel = sum_kernel( @@ -150,21 +146,17 @@ def compile_kernels(self) -> None: self.unique_id = cp.array([0]) if "image_exponential" in self.unique_fusion: - self.average_correspondences_to_map_kernel = ( - average_correspondences_to_map_kernel( - resolution=self.param.resolution, - width=self.param.cell_n, - height=self.param.cell_n, - ) + self.average_correspondences_to_map_kernel = average_correspondences_to_map_kernel( + resolution=self.param.resolution, + width=self.param.cell_n, + height=self.param.cell_n, ) if "image_color" in self.unique_fusion: - self.color_correspondences_to_map_kernel = ( - color_correspondences_to_map_kernel( - resolution=self.param.resolution, - width=self.param.cell_n, - height=self.param.cell_n, - ) + self.color_correspondences_to_map_kernel = color_correspondences_to_map_kernel( + resolution=self.param.resolution, + width=self.param.cell_n, + height=self.param.cell_n, ) def pad_value(self, x, shift_value, idx=None, value=0.0): @@ -325,9 +317,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) # do not divide by zero sum_alpha[sum_alpha == 0] = 1 - self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims( - sum_alpha, axis=0 - ) + self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) # assert cp.unique(cp.sum(self.map[layer_ids], axis=0)) equal to zero or to nan if "class_max" in additional_fusion: @@ -382,9 +372,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) # do not divide by zero sum_alpha[sum_alpha == 0] = 1 - self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims( - sum_alpha, axis=0 - ) + self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) if "color" in additional_fusion: pcl_ids, layer_ids = self.get_indices_fusion(channels, "color") @@ -426,9 +414,7 @@ def update_layers_image( self.new_map *= 0 config = self.param.subscriber_cfg[sub_key] - for j, (fusion, channel) in enumerate( - zip(config["fusion"], config["channels"]) - ): + for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): sem_map_idx = self.get_index(channel) if fusion == "image_exponential": diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py index 550713b7..7a74b8ab 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -5,9 +5,7 @@ def encode_max(maxim, index): - maxim, index = cp.asarray(maxim, dtype=cp.float32), cp.asarray( - index, dtype=cp.uint32 - ) + maxim, index = cp.asarray(maxim, dtype=cp.float32), cp.asarray(index, dtype=cp.uint32) # fuse them maxim = maxim.astype(cp.float16) maxim = maxim.view(cp.uint16) @@ -57,9 +55,7 @@ def test_input(self, elmap_ex): ind = cp.random.randint(0, 2, (100000, len(channels)), dtype=cp.uint32).astype(cp.float32) points = encode_max(val, ind) else: - points = cp.random.rand( - 100000, len(channels), dtype=elmap_ex.param.data_type - ) + points = cp.random.rand(100000, len(channels), dtype=elmap_ex.param.data_type) R = cp.random.rand(3, 3, dtype=elmap_ex.param.data_type) t = cp.random.rand(3, dtype=elmap_ex.param.data_type) elmap_ex.input(points, channels, R, t, 0, 0) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py index 0a040ea1..5aac5542 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -59,12 +59,8 @@ def test_plugin_manager(semmap_ex, channels): manager.layers[0] manager.update_with_name("min_filter", elevation_map, layer_names) manager.update_with_name("smooth_filter", elevation_map, layer_names) - manager.update_with_name( - "semantic_filter", elevation_map, layer_names, semmap_ex, rotation - ) - manager.update_with_name( - "semantic_traversability", elevation_map, layer_names, semmap_ex - ) + manager.update_with_name("semantic_filter", elevation_map, layer_names, semmap_ex, rotation) + manager.update_with_name("semantic_traversability", elevation_map, layer_names, semmap_ex) manager.get_map_with_name("smooth") for lay in manager.get_layer_names(): manager.update_with_name(lay, elevation_map, layer_names, semmap_ex, rotation) From 81a9aa148e5d52305e016bda97018dd70522e2f5 Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 13 Dec 2022 10:21:27 +0100 Subject: [PATCH 306/504] cleaning pointcloud removing python warnings --- .../semantic_pointcloud/pointcloud_node.py | 68 ++++++++++++------- .../tests/test_pointcloud.py | 4 +- .../script/semantic_pointcloud/utils.py | 16 ++--- 3 files changed, 54 insertions(+), 34 deletions(-) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index 51341abd..00a90bdc 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -18,6 +18,11 @@ class PointcloudNode: def __init__(self, sensor_name): + """ Get parameter from server, initialize variables and semantics, register publishers and subscribers. + + Args: + sensor_name (str): Name of the sensor in the ros param server. + """ # TODO: if this is going to be loaded from another package we might need to change namespace self.param: PointcloudParameter = PointcloudParameter() # try catch for pytests @@ -47,7 +52,42 @@ def __init__(self, sensor_name): self.cv_bridge = CvBridge() self.P = None self.header = None + self.register_sub_pub() + + def initialize_semantics(self): + """Resolve the feature and segmentation mode and create segmentation_channel and feature_channels. + + - segmentation_channels: is a dictionary that contains the segmentation channel names as key and the fusion algorithm as value. + - feature_channels: is a dictionary that contains the features channel names as key and the fusion algorithm as value. + """ + if self.param.semantic_segmentation: + self.semantic_model = resolve_model( + self.param.segmentation_model, self.param + ) + self.segmentation_channels = {} + for i, (chan, fusion) in enumerate( + zip(self.param.channels, self.param.fusion) + ): + if fusion in ["class_bayesian", "class_average", "class_max"]: + self.segmentation_channels[chan] = fusion + assert len(self.segmentation_channels.keys()) > 0 + if self.param.feature_extractor: + self.feature_extractor = resolve_model( + self.param.feature_config.name, self.param.feature_config + ) + self.feature_channels = {} + for i, (chan, fusion) in enumerate( + zip(self.param.channels, self.param.fusion) + ): + if fusion in ["average"]: + self.feature_channels[chan] = fusion + assert len(self.feature_channels.keys()) > 0 + + def register_sub_pub(self): + """Register publishers and subscribers. + """ + # subscribers rospy.Subscriber(self.param.cam_info_topic, CameraInfo, self.cam_info_callback) rgb_sub = message_filters.Subscriber(self.param.image_topic, Image) depth_sub = message_filters.Subscriber(self.param.depth_topic, Image) @@ -76,6 +116,7 @@ def __init__(self, sensor_name): ts.registerCallback(self.image_callback) self.pcl_pub = rospy.Publisher(self.param.topic_name, PointCloud2, queue_size=2) + # publishers if self.param.semantic_segmentation: if self.param.publish_segmentation_image: self.seg_pub = rospy.Publisher( @@ -118,33 +159,12 @@ def color_map_viz(self): (row_size * (nclasses), col_size, cmap.shape[1]), dtype=cmap.dtype ) for i in range(nclasses): - array[i * row_size : i * row_size + row_size, :] = cmap[i] + array[i * row_size: i * row_size + row_size, :] = cmap[i] imshow(array) plt.yticks([row_size * i + row_size / 2 for i in range(nclasses)], self.labels) plt.xticks([]) plt.show() - def initialize_semantics(self): - if self.param.semantic_segmentation: - self.semantic_model = resolve_model( - self.param.segmentation_model, self.param - ) - self.segmentation_channels = {} - for i, (chan, fus) in enumerate( - zip(self.param.channels, self.param.fusion) - ): - if fus in ["class_bayesian", "class_average", "class_max"]: - self.segmentation_channels[chan] = fus - if self.param.feature_extractor: - self.feature_channels = [] - for i, fusion in enumerate(self.param.fusion): - if fusion == "average": - self.feature_channels.append(self.param.channels[i]) - assert len(self.feature_channels) > 0 - self.feature_extractor = resolve_model( - self.param.feature_config.name, self.param.feature_config - ) - def create_custom_dtype(self): self.dtype = [ ("x", np.float32), @@ -244,7 +264,7 @@ def perform_segmentation(self, image, points, u, v): def extract_features(self, image, points, u, v): prediction = self.feature_extractor["model"](image) values = prediction[:, v.get(), u.get()].cpu().detach().numpy() - for it, channel in enumerate(self.feature_channels): + for it, channel in enumerate(self.feature_channels.keys()): points[channel] = values[it] def publish_segmentation_image(self, probabilities): @@ -257,7 +277,7 @@ def publish_segmentation_image(self, probabilities): # decode, create an array with all possible classes and insert probabilities it = 0 for iit, (chan, fuse) in enumerate( - zip(self.param.channels, self.param.fusion) + zip(self.param.channels, self.param.fusion) ): if fuse in ["class_max"]: temp = probabilities[it] diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py index 01ec9bad..59996cf5 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py @@ -20,8 +20,10 @@ def pointcloud_ex(cam_name): "front_cam", ], ) -def test_initialize_semantics(pointcloud_ex): +def test_initialize(pointcloud_ex): + # todo here we can add more test pointcloud_ex.initialize_semantics() + pointcloud_ex.register_sub_pub() @pytest.mark.parametrize( diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py index e44f908d..a3c321f6 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py @@ -17,7 +17,6 @@ setup_logger() -# import some common detectron2 utilities from detectron2 import model_zoo from detectron2.engine import DefaultPredictor from detectron2.config import get_cfg @@ -31,7 +30,6 @@ FeatureExtractorParameter, ) -# from .pointcloud_parameters import PointcloudParameter, FeatureExtractorParameter def encode_max(maxim, index): maxim, index = cp.asarray(maxim, dtype=cp.float32), cp.asarray( index, dtype=cp.uint32 @@ -106,15 +104,15 @@ def resolve_model(name, config=None): class PytorchModel: def __init__(self, net, weights, param): - self.model = net(weights) + self.model = net(weights=weights) self.weights = weights self.param = param self.model.eval() device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") self.model.to(device=device) - self.resolve_cateories() + self.resolve_categories() - def resolve_cateories(self): + def resolve_categories(self): class_to_idx = {cls: idx for (idx, cls) in enumerate(self.get_classes())} print( "Semantic Segmentation possible channels: ", @@ -171,7 +169,7 @@ def __call__(self, image, *args, **kwargs): ) x = torch.arange(0, index.shape[0]) y = torch.arange(0, index.shape[1]) - c = torch.meshgrid(x, y) + c = torch.meshgrid(x, y, indexing='ij') normalized_masks[index, c[0], c[1]] = 0 return cp.asarray(selected_masks) @@ -196,8 +194,8 @@ def __init__(self, weights, param): self.cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(weights) self.predictor = DefaultPredictor(self.cfg) self.meta = MetadataCatalog.get(self.cfg.DATASETS.TRAIN[0]) - self.stuff_categories, self.is_stuff = self.resolve_cateories("stuff_classes") - self.thing_categories, self.is_thing = self.resolve_cateories("thing_classes") + self.stuff_categories, self.is_stuff = self.resolve_categories("stuff_classes") + self.thing_categories, self.is_thing = self.resolve_categories("thing_classes") self.segmentation_channels = {} for chan in self.param.channels: if chan in self.stuff_categories.keys(): @@ -208,7 +206,7 @@ def __init__(self, weights, param): # remove it pass - def resolve_cateories(self, name): + def resolve_categories(self, name): classes = self.get_cat(name) class_to_idx = {cls: idx for (idx, cls) in enumerate(classes)} print( From f5d3a148100806170c4de0b7cb538ad479dbe41f Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 13 Dec 2022 16:36:15 +0100 Subject: [PATCH 307/504] fixed the cpp wrapper such that it is able to accept also pointclouds that contain different fields e.g. rings. Added also configuration for anymal bag and anymal sim --- .../config/anymal_plugin_config.yaml | 6 +- .../config/anymal_sensor_parameter.yaml | 98 ++++++------- .../config/sim_parameters.yaml | 96 +++++++++++++ .../config/sim_sensor_parameter.yaml | 131 ++++++++++++++++++ .../elevation_mapping_ros.hpp | 4 +- .../anymal_semantic_elevation_single.launch | 2 +- .../sim_semantic_elevation_single.launch | 21 +++ .../src/elevation_mapping_ros.cpp | 50 +++++-- 8 files changed, 339 insertions(+), 69 deletions(-) create mode 100644 elevation_mapping_cupy/config/sim_parameters.yaml create mode 100644 elevation_mapping_cupy/config/sim_sensor_parameter.yaml create mode 100644 elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch diff --git a/elevation_mapping_cupy/config/anymal_plugin_config.yaml b/elevation_mapping_cupy/config/anymal_plugin_config.yaml index 07f34e6a..e18df155 100644 --- a/elevation_mapping_cupy/config/anymal_plugin_config.yaml +++ b/elevation_mapping_cupy/config/anymal_plugin_config.yaml @@ -2,7 +2,7 @@ # min_filter fills in minimum value around the invalid cell. min_filter: - enable: False # weather to load this plugin + enable: True # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "min_filter" # The layer name. @@ -11,7 +11,7 @@ min_filter: iteration_n: 30 # The number of iterations # Apply smoothing. smooth_filter: - enable: False + enable: True fill_nan: False is_height_layer: True layer_name: "smooth" @@ -19,7 +19,7 @@ smooth_filter: input_layer_name: "min_filter" # Apply inpainting using opencv inpainting: - enable: False + enable: True fill_nan: False is_height_layer: True layer_name: "inpaint" diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml index 4363a22e..0ad1fa10 100644 --- a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml @@ -37,36 +37,36 @@ subscribers: # topic_name: '/elevation_mapping/pointcloud_semantic' # data_type: pointcloud - # alphasense_front_rgb: - # fusion: ['image_color'] - # topic_name_camera: /alphasense_driver_ros/cam4/debayered - # topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info - # channels: ["rgb_image"] - # data_type: image + alphasense_front_rgb: + fusion: ['image_color'] + topic_name_camera: /alphasense_driver_ros/cam4/debayered + topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info + channels: ["rgb_image"] + data_type: image - # alphasense_left_rgb: - # fusion: ['image_color'] - # topic_name_camera: /alphasense_driver_ros/cam3/debayered - # topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info - # channels: ["rgb_image"] - # data_type: image + alphasense_left_rgb: + fusion: ['image_color'] + topic_name_camera: /alphasense_driver_ros/cam3/debayered + topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info + channels: ["rgb_image"] + data_type: image - # alphasense_right_rgb: - # fusion: ['image_color'] - # topic_name_camera: /alphasense_driver_ros/cam5/debayered - # topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info - # channels: ["rgb_image"] - # data_type: image + alphasense_right_rgb: + fusion: ['image_color'] + topic_name_camera: /alphasense_driver_ros/cam5/debayered + topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info + channels: ["rgb_image"] + data_type: image - # wvn_prediction: - # fusion: ['image_exponential'] - # topic_name_camera: '/wild_visual_navigation_node/current_prediction' - # topic_name_camera_info: '/wild_visual_navigation_node/camera_info' - # channels: ["visual_traversability"] - # data_type: image + wvn_prediction: + fusion: ['image_exponential'] + topic_name_camera: '/wild_visual_navigation_node/current_prediction' + topic_name_camera_info: '/wild_visual_navigation_node/camera_info' + channels: ["visual_traversability"] + data_type: image # front_cam: # channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] @@ -94,11 +94,11 @@ subscribers: # confidence_threshold: 10 # feature_extractor: False - front_bpearl: - channels: [] - fusion: [] - topic_name: /point_cloud_filter_rsl/filter_and_merger_rsl - data_type: pointcloud +# front_bpearl: +# channels: [] +# fusion: [] +# topic_name: /point_cloud_filter_rsl/filter_and_merger_rsl +# data_type: pointcloud # rear_bpearl: # channels: [] @@ -106,26 +106,26 @@ subscribers: # topic_name: /robot_self_filter/bpearl_rear/point_cloud # data_type: pointcloud - # front_depth: - # channels: [] - # fusion: [] - # topic_name: /depth_camera_front/point_cloud_self_filtered - # data_type: pointcloud + front_depth: + channels: [] + fusion: [] + topic_name: /depth_camera_front/point_cloud_self_filtered + data_type: pointcloud - # rear_depth: - # channels: [] - # fusion: [] - # topic_name: /depth_camera_rear/point_cloud_self_filtered - # data_type: pointcloud + rear_depth: + channels: [] + fusion: [] + topic_name: /depth_camera_rear/point_cloud_self_filtered + data_type: pointcloud - # left_depth: - # channels: [] - # fusion: [] - # topic_name: /depth_camera_left/point_cloud_self_filtered - # data_type: pointcloud + left_depth: + channels: [] + fusion: [] + topic_name: /depth_camera_left/point_cloud_self_filtered + data_type: pointcloud - # right_depth: - # channels: [] - # fusion: [] - # topic_name: /depth_camera_right/point_cloud_self_filtered - # data_type: pointcloud \ No newline at end of file + right_depth: + channels: [] + fusion: [] + topic_name: /depth_camera_right/point_cloud_self_filtered + data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/config/sim_parameters.yaml b/elevation_mapping_cupy/config/sim_parameters.yaml new file mode 100644 index 00000000..b92bb6da --- /dev/null +++ b/elevation_mapping_cupy/config/sim_parameters.yaml @@ -0,0 +1,96 @@ +#### Basic parameters ######## +resolution: 0.04 # resolution in m. +map_length: 8 # map's size in m. +sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). +mahalanobis_thresh: 2.0 # points outside this distance is outlier. +outlier_variance: 0.01 # if point is outlier, add this value to the cell. +drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. +max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) +drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation +time_variance: 0.0001 # add this value when update_variance is called. +max_variance: 100.0 # maximum variance for each cell. +initial_variance: 1000.0 # initial variance for each cell. +traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. +dilation_size: 3 # dilation filter size before traversability filter. +wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. +min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. +position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. +orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. +position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. +orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. +min_valid_distance: 0.5 # points with shorter distance will be filtered out. +max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. +ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +update_variance_fps: 5.0 # fps for updating variance. +update_pose_fps: 10.0 # fps for updating pose and shift the center of map. +time_interval: 0.1 # Time layer is updated with this interval. +map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. +publish_statistics_fps: 1.0 # Publish statistics topic in this fps. + +max_ray_length: 10.0 # maximum length for ray tracing. +cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. +cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + +safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. +safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. +max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + +overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) +overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + +map_frame: 'odom' # The map frame where the odometry source uses. +base_frame: 'base' # The robot's base frame. This frame will be a center of the map. +corrected_map_frame: 'odom_corrected' + +#### Feature toggles ######## +enable_edge_sharpen: true +enable_visibility_cleanup: true +enable_drift_compensation: true +enable_overlap_clearance: true +enable_pointcloud_publishing: false +enable_drift_corrected_TF_publishing: false +enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + +#### Traversability filter ######## +use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. +weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter + +#### Upper bound ######## +use_only_above_for_upper_bound: false + +#### Plugins ######## +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin_config.yaml' + +#### Publishers ######## +# topic_name: +# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names +# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. +# fps: # Publish rate. Use smaller value than `map_acquire_fps`. +publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + + semantic_map_raw: + layers: ['elevation', 'traversability', 'variance', 'rgb_image'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + # elevation_map_recordable: + # layers: ['elevation', 'traversability'] + # basic_layers: ['elevation', 'traversability'] + # fps: 2.0 + # elevation_map_filter: + # layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb'] + # basic_layers: ['min_filter'] + # fps: 3.0 + +#### Initializer ######## +initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' +initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [0.0] # z direction. Should be same number as initialize_frame_id. +dilation_size_initialize: 5 # dilation size after the init. +initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. +use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/sim_sensor_parameter.yaml b/elevation_mapping_cupy/config/sim_sensor_parameter.yaml new file mode 100644 index 00000000..4363a22e --- /dev/null +++ b/elevation_mapping_cupy/config/sim_sensor_parameter.yaml @@ -0,0 +1,131 @@ +#### Subscribers ######## +subscribers: + # debug_rgb: + # fusion: ['image_color'] + # topic_name_camera: /zed2i/zed_node/left/image_rect_color + # topic_name_camera_info: /zed2i/zed_node/right/camera_info + # channels: ["rgb_image"] + # data_type: image + # fusion_types: + # array_fusion: [] + # channels: [] + + # debug_rgb_3_seperate: + # fusion: ['image_exponential','image_exponential','image_exponential'] + # topic_name_camera: /zed2i/zed_node/right/image + # topic_name_camera_info: /zed2i/zed_node/right/camera_info + # channels: ["r_channel", "g_channel", "b_channel"] + # data_type: image + + # debug_rgb_2_seperate: + # fusion: ['image_exponential', 'image_exponential'] + # topic_name_camera: /zed2i/zed_node/left/image_rect_color + # topic_name_camera_info: /zed2i/zed_node/right/camera_info + # channels: ["r_channel", "g_channel"] + # data_type: image + + # debug_mono_exponential: + # fusion: ['image_exponential'] + # topic_name_camera: /debug_image + # topic_name_camera_info: /zed2i/zed_node/right/camera_info + # channels: ["single_channel_semantic"] + # data_type: image + +# front_cam: +# channels: ['rgb'] +# fusion: ['color'] +# topic_name: '/elevation_mapping/pointcloud_semantic' +# data_type: pointcloud + + # alphasense_front_rgb: + # fusion: ['image_color'] + # topic_name_camera: /alphasense_driver_ros/cam4/debayered + # topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info + # channels: ["rgb_image"] + # data_type: image + + + # alphasense_left_rgb: + # fusion: ['image_color'] + # topic_name_camera: /alphasense_driver_ros/cam3/debayered + # topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info + # channels: ["rgb_image"] + # data_type: image + + + # alphasense_right_rgb: + # fusion: ['image_color'] + # topic_name_camera: /alphasense_driver_ros/cam5/debayered + # topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info + # channels: ["rgb_image"] + # data_type: image + + + # wvn_prediction: + # fusion: ['image_exponential'] + # topic_name_camera: '/wild_visual_navigation_node/current_prediction' + # topic_name_camera_info: '/wild_visual_navigation_node/camera_info' + # channels: ["visual_traversability"] + # data_type: image + + # front_cam: + # channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] + # fusion: ['color','average','average','class_average','class_average','class_average','class_average'] + # topic_name: '/elvation_mapping/pointcloud_semantic' + # semantic_segmentation: False + # segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' + # feature_config: + # name: 'DINO' + # interpolation: 'bilinear' + # model: "vit_small" + # patch_size: 16 + # dim: 5 + # dropout: False + # dino_feat_type: "feat" + # input_size: [80, 160] + # projection_type: "nonlinear" + + # cam_info_topic: "/camera/depth/camera_info" + # image_topic: "/camera/rgb/image_raw" + # depth_topic: "/camera/depth/image_raw" + # cam_frame: camera_rgb_optical_frame + # confidence: False + # confidence_topic: "/camera/depth/image_raw" + # confidence_threshold: 10 + # feature_extractor: False + + front_bpearl: + channels: [] + fusion: [] + topic_name: /point_cloud_filter_rsl/filter_and_merger_rsl + data_type: pointcloud + + # rear_bpearl: + # channels: [] + # fusion: [] + # topic_name: /robot_self_filter/bpearl_rear/point_cloud + # data_type: pointcloud + + # front_depth: + # channels: [] + # fusion: [] + # topic_name: /depth_camera_front/point_cloud_self_filtered + # data_type: pointcloud + + # rear_depth: + # channels: [] + # fusion: [] + # topic_name: /depth_camera_rear/point_cloud_self_filtered + # data_type: pointcloud + + # left_depth: + # channels: [] + # fusion: [] + # topic_name: /depth_camera_left/point_cloud_self_filtered + # data_type: pointcloud + + # right_depth: + # channels: [] + # fusion: [] + # topic_name: /depth_camera_right/point_cloud_self_filtered + # data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index db262e41..0d70a531 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -71,7 +71,7 @@ class ElevationMappingNode { private: void readParameters(); void setupMapPublishers(); - void pointcloudCallback(const sensor_msgs::PointCloud2& cloud); + void pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key); void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::string& key); void publishAsPointCloud(const grid_map::GridMap& map) const; bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); @@ -130,6 +130,8 @@ class ElevationMappingNode { std::vector map_fps_; std::set map_fps_unique_; std::vector mapTimers_; + std::map> channels_; + std::vector initialize_frame_id_; std::vector initialize_tf_offset_; diff --git a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch index 7c3fcc1b..b4c0fcbf 100644 --- a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch +++ b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch @@ -16,6 +16,6 @@ - + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch new file mode 100644 index 00000000..81ae677d --- /dev/null +++ b/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index d5a72247..fe637354 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -80,8 +80,17 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) // Initialize subscribers depending on the type if (type == "pointcloud") { std::string pointcloud_topic = subscriber.second["topic_name"]; - ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, &ElevationMappingNode::pointcloudCallback, this); + boost::function f = boost::bind(&ElevationMappingNode::pointcloudCallback,this, _1, key); + ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1,f); pointcloudSubs_.push_back(sub); + const auto & channels = subscriber.second["channels"]; + channels_[key].push_back("x"); + channels_[key].push_back("y"); + channels_[key].push_back("z"); + for (int32_t i = 0; i < channels.size(); ++i) { + auto elem = static_cast(channels[i]); + channels_[key].push_back(elem); + } } else if (type == "image") { std::string camera_topic = subscriber.second["topic_name_camera"]; @@ -251,31 +260,42 @@ void ElevationMappingNode::publishMapOfIndex(int index) { mapPubs_[index].publish(msg); } -void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cloud) { +void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key) { auto start = ros::Time::now(); // transform pointcloud into matrix auto* pcl_pc = new pcl::PCLPointCloud2; pcl::PCLPointCloud2ConstPtr cloudPtr(pcl_pc); pcl_conversions::toPCL(cloud, *pcl_pc); - uint array_dim = pcl_pc->point_step/4;// we assume that they are all float32 or at least 32bits + // get channels + auto fields = cloud.fields; + std::vector channels; + std::vector add_element; + + for(int it =0;itwidth,array_dim); for (unsigned int i = 0; i < pcl_pc->width; ++i) { - for(unsigned int j = 0; jpoint_step + pcl_pc->fields[j].offset; - memcpy(&temp, &pcl_pc->data[point_idx], sizeof(float)); - points(i, j) = static_cast(temp); + int jit = 0; + for(unsigned int j = 0; jpoint_step + pcl_pc->fields[j].offset; + memcpy(&temp, &pcl_pc->data[point_idx], sizeof(float)); + points(i, jit) = static_cast(temp); + jit++; + } } } -// get channels - auto fields = cloud.fields; - std::vector channels; - for(auto & field: fields){ - channels.push_back(field.name); - ROS_ASSERT(field.datatype == 7); - } // get pose of sensor in map frame tf::StampedTransform transformTf; std::string sensorFrameId = cloud.header.frame_id; From fdf265cfc596a7b94935d239b36892c8c8997c75 Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 13 Dec 2022 17:05:53 +0100 Subject: [PATCH 308/504] make python wrapper config --- .../config/sim_plugin_config.yaml | 61 +++++++++++++++++++ .../elevation_mapping_ros.py | 2 +- 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 elevation_mapping_cupy/config/sim_plugin_config.yaml diff --git a/elevation_mapping_cupy/config/sim_plugin_config.yaml b/elevation_mapping_cupy/config/sim_plugin_config.yaml new file mode 100644 index 00000000..e18df155 --- /dev/null +++ b/elevation_mapping_cupy/config/sim_plugin_config.yaml @@ -0,0 +1,61 @@ +# Settings of the plugins. (The plugins should be stored in script/plugins) + +# min_filter fills in minimum value around the invalid cell. +min_filter: + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations +# Apply smoothing. +smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" +# Apply inpainting using opencv +inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns +# Apply smoothing for inpainted layer + +robot_centric_elevation: # Use the same name as your file name. +# type: "robot_centric_elevation" + enable: False # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "robot_centric_elevation" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. +# add_value: 2.0 # Example param + resolution: 0.04 + threshold: 1.1 + use_threshold: True + +semantic_filter: + type: "semantic_filter" + enable: False + fill_nan: False + is_height_layer: False + layer_name: "sem_fil" + extra_params: + classes: ['grass','tree','fence','dirt'] + +semantic_traversability: + type: "semantic_traversability" + enable: False + fill_nan: False + is_height_layer: False + layer_name: "sem_traversability" + extra_params: + layers: ['traversability','robot_centric_elevation'] + thresholds: [0.3,0.5] + type: ['traversability', 'elevation'] + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index aab2d115..8cd63b52 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -240,7 +240,7 @@ def update_time(self, t): def get_ros_params(self): # TODO fix this here when later launching with launch-file # This is currently {p} elevation_mapping") - typ = "anymal" + typ = "sim" para = os.path.join(self.root, f"config/{typ}_parameters.yaml") sens = os.path.join(self.root, f"config/{typ}_sensor_parameter.yaml") plugin = os.path.join(self.root, f"config/{typ}_plugin_config.yaml") From a63ff0452de5748a6e8aae3bf6010147ea22a246 Mon Sep 17 00:00:00 2001 From: Gian Date: Wed, 14 Dec 2022 13:39:42 +0100 Subject: [PATCH 309/504] reviewed pointcloud and added few tests --- .../semantic_pointcloud/pointcloud_node.py | 102 ++++++++++++++---- .../pointcloud_parameters.py | 8 +- .../tests/test_pointcloud.py | 90 ++++++++++++---- .../semantic_pointcloud/tests/test_utils.py | 10 +- .../script/semantic_pointcloud/utils.py | 29 +++-- 5 files changed, 177 insertions(+), 62 deletions(-) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index 00a90bdc..4e5cb0a3 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -18,20 +18,20 @@ class PointcloudNode: def __init__(self, sensor_name): - """ Get parameter from server, initialize variables and semantics, register publishers and subscribers. + """Get parameter from server, initialize variables and semantics, register publishers and subscribers. Args: sensor_name (str): Name of the sensor in the ros param server. """ # TODO: if this is going to be loaded from another package we might need to change namespace self.param: PointcloudParameter = PointcloudParameter() - # try catch for pytests - try: + if rospy.has_param("/semantic_pointcloud/subscribers"): config = rospy.get_param("/semantic_pointcloud/subscribers") self.param: PointcloudParameter = PointcloudParameter.from_dict( config[sensor_name] ) - except: + else: + self.param.feature_config.input_size = [80, 160] print("NO ROS ENV found.") self.param.sensor_name = sensor_name @@ -53,6 +53,7 @@ def __init__(self, sensor_name): self.P = None self.header = None self.register_sub_pub() + self.prediction_img = None def initialize_semantics(self): """Resolve the feature and segmentation mode and create segmentation_channel and feature_channels. @@ -66,7 +67,7 @@ def initialize_semantics(self): ) self.segmentation_channels = {} for i, (chan, fusion) in enumerate( - zip(self.param.channels, self.param.fusion) + zip(self.param.channels, self.param.fusion) ): if fusion in ["class_bayesian", "class_average", "class_max"]: self.segmentation_channels[chan] = fusion @@ -77,16 +78,14 @@ def initialize_semantics(self): ) self.feature_channels = {} for i, (chan, fusion) in enumerate( - zip(self.param.channels, self.param.fusion) + zip(self.param.channels, self.param.fusion) ): if fusion in ["average"]: self.feature_channels[chan] = fusion assert len(self.feature_channels.keys()) > 0 def register_sub_pub(self): - """Register publishers and subscribers. - - """ + """Register publishers and subscribers.""" # subscribers rospy.Subscriber(self.param.cam_info_topic, CameraInfo, self.cam_info_callback) rgb_sub = message_filters.Subscriber(self.param.image_topic, Image) @@ -131,6 +130,13 @@ def register_sub_pub(self): self.color_map_viz() def color_map(self, N=256, normalized=False): + """Create a color map for the class labels. + + Args: + N (int): + normalized (bool): + """ + def bitget(byteval, idx): return (byteval & (1 << idx)) != 0 @@ -151,6 +157,7 @@ def bitget(byteval, idx): return cmap[1:] def color_map_viz(self): + """Display the color map of the classes.""" nclasses = len(self.labels) row_size = 50 col_size = 500 @@ -159,13 +166,17 @@ def color_map_viz(self): (row_size * (nclasses), col_size, cmap.shape[1]), dtype=cmap.dtype ) for i in range(nclasses): - array[i * row_size: i * row_size + row_size, :] = cmap[i] + array[i * row_size : i * row_size + row_size, :] = cmap[i] imshow(array) plt.yticks([row_size * i + row_size / 2 for i in range(nclasses)], self.labels) plt.xticks([]) plt.show() def create_custom_dtype(self): + """Generate a new dtype according to the channels in the params. + + Some channels might remain empty. + """ self.dtype = [ ("x", np.float32), ("y", np.float32), @@ -176,6 +187,11 @@ def create_custom_dtype(self): print(self.dtype) def cam_info_callback(self, msg): + """Subscribe to the camera infos to get projection matrix and header. + + Args: + msg: + """ a = cp.asarray(msg.P) self.P = cp.resize(a, (3, 4)) self.height = msg.height @@ -200,10 +216,21 @@ def image_callback(self, rgb_msg, depth_msg, confidence_msg=None): ) pcl = self.create_pcl_from_image(image, depth, confidence) - + if self.param.publish_segmentation_image: + self.publish_segmentation_image(self.prediction_img) self.publish_pointcloud(pcl, depth_msg.header) def create_pcl_from_image(self, image, depth, confidence): + """Generate the pointcloud from the depth map and process the image. + + Args: + image: + depth: + confidence: + + Returns: + + """ u, v = self.get_coordinates(depth, confidence) # create pointcloud @@ -218,6 +245,15 @@ def create_pcl_from_image(self, image, depth, confidence): return points def get_coordinates(self, depth, confidence): + """Define which pixels are valid to generate the pointcloud. + + Args: + depth: + confidence: + + Returns: + + """ pos = cp.where(depth > 0, 1, 0) low = cp.where(depth < 8, 1, 0) if confidence is not None: @@ -231,13 +267,15 @@ def get_coordinates(self, depth, confidence): v = mask[0] return u, v - def publish_pointcloud(self, pcl, header): - pc2 = ros_numpy.msgify(PointCloud2, pcl) - pc2.header = header - pc2.header.frame_id = self.param.cam_frame - self.pcl_pub.publish(pc2) - def process_image(self, image, u, v, points): + """Depending on setting generate color, semantic segmentation or feature channels. + + Args: + image: + u: + v: + points: + """ if "color" in self.param.fusion: valid_rgb = image[v, u].get() r = np.asarray(valid_rgb[:, 0], dtype=np.uint32) @@ -254,14 +292,30 @@ def process_image(self, image, u, v, points): self.extract_features(image, points, u, v) def perform_segmentation(self, image, points, u, v): + """Feedforward image through semseg NN and then append pixels to pcl and save image for publication. + + Args: + image: + points: + u: + v: + """ prediction = self.semantic_model["model"](image) values = prediction[:, v.get(), u.get()].get() - for it, channel in enumerate(self.segmentation_channels.keys()): + for it, channel in enumerate(self.semantic_model["model"].actual_channels): points[channel] = values[it] if self.param.publish_segmentation_image: - self.publish_segmentation_image(prediction) + self.prediction_img = prediction def extract_features(self, image, points, u, v): + """Feedforward image through feature extraction NN and then append pixels to pcl. + + Args: + image: + points: + u: + v: + """ prediction = self.feature_extractor["model"](image) values = prediction[:, v.get(), u.get()].cpu().detach().numpy() for it, channel in enumerate(self.feature_channels.keys()): @@ -277,13 +331,13 @@ def publish_segmentation_image(self, probabilities): # decode, create an array with all possible classes and insert probabilities it = 0 for iit, (chan, fuse) in enumerate( - zip(self.param.channels, self.param.fusion) + zip(self.param.channels, self.param.fusion) ): if fuse in ["class_max"]: temp = probabilities[it] temp_p, temp_i = decode_max(temp) temp_i.choose(prob) - c = cp.mgrid[0: temp_i.shape[0], 0: temp_i.shape[1]] + c = cp.mgrid[0 : temp_i.shape[0], 0 : temp_i.shape[1]] prob[temp_i, c[0], c[1]] = temp_p it += 1 elif fuse in ["class_bayesian", "class_average"]: @@ -303,6 +357,12 @@ def publish_segmentation_image(self, probabilities): seg_msg.header.frame_id = self.header.frame_id self.seg_pub.publish(seg_msg) + def publish_pointcloud(self, pcl, header): + pc2 = ros_numpy.msgify(PointCloud2, pcl) + pc2.header = header + pc2.header.frame_id = self.param.cam_frame + self.pcl_pub.publish(pc2) + if __name__ == "__main__": sensor_name = sys.argv[1] diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py index c957e736..bb58b1ae 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py @@ -13,10 +13,7 @@ class FeatureExtractorParameter(Serializable): dropout: bool = False dino_feat_type: str = "feat" projection_type: str = "nonlinear" - # input_size: list = field(default_factory=[80, 160].copy) - input_size: list = field( - default_factory=lambda: [80, 160] - ) + input_size: list = field(default_factory=lambda: [80, 160]) @dataclass @@ -37,7 +34,7 @@ class PointcloudParameter(Serializable): ) semantic_segmentation: bool = True - segmentation_model: str = "detectron_coco_panoptic_fpn_R_101_3x" + segmentation_model: str = "lraspp_mobilenet_v3_large" publish_segmentation_image: bool = True segmentation_image_topic: str = "/semantic_pointcloud/sem_seg" pub_all: bool = False @@ -53,3 +50,4 @@ class PointcloudParameter(Serializable): feature_extractor: bool = False feature_config: FeatureExtractorParameter = FeatureExtractorParameter + feature_config.input_size: list = field(default_factory=lambda: [80, 160]) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py index 59996cf5..6c4cd94a 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py @@ -3,46 +3,94 @@ import cupy as cp from ..utils import encode_max -"""This test file only works if ros is installed +"""This test file only works if ros is installed and the ros master is running. """ @pytest.fixture() -def pointcloud_ex(cam_name): +def pointcloud_ex(cam_name, channels, fusion, semseg, segpub, showlbl): node = PointcloudNode(cam_name) - node.initialize_semantics() + node.param.channels = channels + node.param.fusion = fusion + node.param.semantic_segmentation = semseg + node.param.show_label_legend = showlbl + node.param.publish_segmentation_image = segpub + node.__init__(cam_name) return node @pytest.mark.parametrize( - "cam_name", + "cam_name,channels, fusion,semseg", [ - "front_cam", + ("front_cam", ["feat_0", "feat_1"], ["average", "average"], False), + ("front_cam", ["feat_0", "feat_1"], ["class_max", "average"], True), + ("front_cam", ["feat_0", "feat_1"], ["class_bayesian", "average"], True), ], ) +@pytest.mark.parametrize( + "segpub", + [True, False], +) +@pytest.mark.parametrize( + "showlbl", + [True, False], +) def test_initialize(pointcloud_ex): # todo here we can add more test + # params: semseg, channels, class max, publish seg, showlabellegend pointcloud_ex.initialize_semantics() pointcloud_ex.register_sub_pub() +# if semseg then segpub and showlbl might be displayed @pytest.mark.parametrize( - "cam_name", + "cam_name,channels, fusion,semseg,segpub,showlbl", [ - ("front_cam"), + ( + "front_cam", + ["feat_0", "feat_1"], + ["average", "average"], + False, + False, + False, + ), + ("front_cam", ["feat_0", "feat_1"], ["class_max", "average"], True, True, True), + ( + "front_cam", + ["feat_0", "feat_1"], + ["class_max", "average"], + True, + False, + False, + ), + ( + "front_cam", + ["feat_0", "feat_1"], + ["class_bayesian", "average"], + True, + True, + True, + ), + ( + "front_cam", + ["feat_0", "feat_1"], + ["class_bayesian", "average"], + True, + False, + False, + ), ], ) -def test_pub_seg(pointcloud_ex): - # TODO we have to encode the max class other wise it is going to make problem - if pointcloud_ex.param.semantic_segmentation: - seg_chan = len(pointcloud_ex.segmentation_channels.keys()) - amount = seg_chan + pointcloud_ex.param.fusion.count("max_class") - if "class_max" in pointcloud_ex.param.fusion: - val = cp.random.rand(amount, 360, 640, dtype=cp.float32).astype(cp.float16) - ind = cp.random.randint(0, 2, (amount, 360, 640), dtype=cp.uint32).astype( - cp.float32 - ) - prob = encode_max(val, ind) - else: - prob = cp.random.rand(amount, 360, 640) - pointcloud_ex.publish_segmentation_image(prob) +def test_pcl_creation(pointcloud_ex, channels, fusion, semseg, segpub, showlbl): + amount = 3 + if "class_max" in pointcloud_ex.param.fusion: + val = cp.random.rand(360, 640, amount, dtype=cp.float32).astype(cp.float16) + ind = cp.random.randint(0, 2, (360, 640, amount), dtype=cp.uint32).astype( + cp.float32 + ) + img = encode_max(val, ind) + else: + img = (cp.random.rand(360, 640, amount) * 255).astype(cp.int) + pointcloud_ex.P = cp.random.rand(3, 4) + depth = cp.random.rand(360, 640) * 8 + pointcloud_ex.create_pcl_from_image(img, depth, None) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py index 51513b72..eb4d0de8 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py @@ -9,14 +9,14 @@ @pytest.mark.parametrize( - "model_name", + "model_name,channels, fusion", [ - "fcn_resnet50", - "lraspp_mobilenet_v3_large", - "detectron_coco_panoptic_fpn_R_101_3x", + ("fcn_resnet50",[],[]), + ("lraspp_mobilenet_v3_large",[],[]), + ("detectron_coco_panoptic_fpn_R_101_3x",[],[]), ], ) -def test_semantic_segmentation(model_name): +def test_semantic_segmentation(model_name,channels, fusion): param = PointcloudParameter() param.segmentation_model = model_name m = resolve_model(model_name, param) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py index a3c321f6..86609c79 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py @@ -103,6 +103,11 @@ def resolve_model(name, config=None): class PytorchModel: + """ + + segemntation_cahnnels contains only classes + actual_channels: array of all channels of output + """ def __init__(self, net, weights, param): self.model = net(weights=weights) self.weights = weights @@ -113,6 +118,10 @@ def __init__(self, net, weights, param): self.resolve_categories() def resolve_categories(self): + """ Create a segmentation_channels containing the actual values that are processed. + + """ + # get all classes class_to_idx = {cls: idx for (idx, cls) in enumerate(self.get_classes())} print( "Semantic Segmentation possible channels: ", @@ -120,27 +129,26 @@ def resolve_categories(self): ) indices = [] channels = [] + self.actual_channels= [] + # check correspondence of semseg and paramter classes, class_max for it, chan in enumerate(self.param.channels): if chan in [cls for cls in list(class_to_idx.keys())]: indices.append(class_to_idx[chan]) channels.append(chan) + self.actual_channels.append(chan) elif self.param.fusion[it] in ["class_average", "class_bayesian"]: print(chan, " is not in the semantic segmentation model.") for it, chan in enumerate(self.param.channels): - if chan in [cls for cls in list(class_to_idx.keys())]: - indices.append(class_to_idx[chan]) - channels.append(chan) - elif self.param.fusion[it] in ["class_max"]: - pass + if self.param.fusion[it] in ["class_max"]: + self.actual_channels.append(chan) print(chan, " is not in the semantic segmentation model but is a max channel.") else: - print(chan, " is not in the semantic segmentation model.") - + pass self.stuff_categories = dict(zip(channels, indices)) - self.segmentation_channels = self.stuff_categories + self.segmentation_channels = dict(zip(channels, indices)) def __call__(self, image, *args, **kwargs): - """Feewforward image through model. + """Feewforward image through model and then create channels Args: image (cupy._core.core.ndarray): @@ -171,6 +179,7 @@ def __call__(self, image, *args, **kwargs): y = torch.arange(0, index.shape[1]) c = torch.meshgrid(x, y, indexing='ij') normalized_masks[index, c[0], c[1]] = 0 + assert len(self.actual_channels) == selected_masks.shape[0] return cp.asarray(selected_masks) def get_classes(self): @@ -205,7 +214,7 @@ def __init__(self, weights, param): else: # remove it pass - + self.actual_channels = self.segmentation_channels.keys() def resolve_categories(self, name): classes = self.get_cat(name) class_to_idx = {cls: idx for (idx, cls) in enumerate(classes)} From 5800415bc691677b18cb5471dc89d60808cf1462 Mon Sep 17 00:00:00 2001 From: Gian Date: Wed, 14 Dec 2022 13:48:32 +0100 Subject: [PATCH 310/504] minor restructuring of pcl --- .../script/semantic_pointcloud/networks.py | 288 ++++++++++++++++++ .../semantic_pointcloud/pointcloud_node.py | 3 +- .../pointcloud_parameters.py | 1 - .../semantic_pointcloud/tests/test_utils.py | 2 +- .../script/semantic_pointcloud/utils.py | 281 ----------------- 5 files changed, 291 insertions(+), 284 deletions(-) create mode 100644 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py new file mode 100644 index 00000000..91e33fa6 --- /dev/null +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py @@ -0,0 +1,288 @@ +from torchvision.models.segmentation import fcn_resnet50, FCN_ResNet50_Weights +from torchvision.models.segmentation import ( + lraspp_mobilenet_v3_large, + LRASPP_MobileNet_V3_Large_Weights, +) +import torch +import torchvision.transforms.functional as TF +from torchvision.transforms import Resize +import torch.nn.functional as NF +import numpy as np +import cupy as cp + +from detectron2.utils.logger import setup_logger + +setup_logger() + +from detectron2 import model_zoo +from detectron2.engine import DefaultPredictor +from detectron2.config import get_cfg +from detectron2.data import MetadataCatalog + +from semantic_pointcloud.DINO.modules import DinoFeaturizer + +from semantic_pointcloud.pointcloud_parameters import ( + PointcloudParameter, + FeatureExtractorParameter, +) +from semantic_pointcloud.utils import encode_max + +def resolve_model(name, config=None): + """Get the model class based on the name of the pretrained model. + + Args: + name (str): Name of pretrained model + [fcn_resnet50,lraspp_mobilenet_v3_large,detectron_coco_panoptic_fpn_R_101_3x] + + Returns: + Dict[str, str]: + """ + if name == "fcn_resnet50": + weights = FCN_ResNet50_Weights.DEFAULT + net = fcn_resnet50 + model = PytorchModel(net, weights, config) + return { + "name": "fcn_resnet50", + "model": model, + } + elif name == "lraspp_mobilenet_v3_large": + weights = LRASPP_MobileNet_V3_Large_Weights.DEFAULT + net = lraspp_mobilenet_v3_large + model = PytorchModel(net, weights, config) + return { + "name": "lraspp_mobilenet_v3_large", + "model": model, + } + elif name == "detectron_coco_panoptic_fpn_R_101_3x": + # "Cityscapes/mask_rcnn_R_50_FPN.yaml" + # "Misc/semantic_R_50_FPN_1x.yaml" + # "Cityscapes-SemanticSegmentation/deeplab_v3_plus_R_103_os16_mg124_poly_90k_bs16.yaml" + # "COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml" + weights = "COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml" + model = DetectronModel(weights, config) + return { + "name": "detectron_coco_panoptic_fpn_R_101_3x", + "model": model, + } + elif name == "DINO": + weights = config.model + str(config.patch_size) + model = STEGOModel(weights, config) + return { + "name": config.model + str(config.patch_size), + "model": model, + } + else: + raise NotImplementedError + + +class PytorchModel: + """ + + segemntation_cahnnels contains only classes + actual_channels: array of all channels of output + """ + + def __init__(self, net, weights, param): + self.model = net(weights=weights) + self.weights = weights + self.param = param + self.model.eval() + device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") + self.model.to(device=device) + self.resolve_categories() + + def resolve_categories(self): + """Create a segmentation_channels containing the actual values that are processed.""" + # get all classes + class_to_idx = {cls: idx for (idx, cls) in enumerate(self.get_classes())} + print( + "Semantic Segmentation possible channels: ", + self.get_classes(), + ) + indices = [] + channels = [] + self.actual_channels = [] + # check correspondence of semseg and paramter classes, class_max + for it, chan in enumerate(self.param.channels): + if chan in [cls for cls in list(class_to_idx.keys())]: + indices.append(class_to_idx[chan]) + channels.append(chan) + self.actual_channels.append(chan) + elif self.param.fusion[it] in ["class_average", "class_bayesian"]: + print(chan, " is not in the semantic segmentation model.") + for it, chan in enumerate(self.param.channels): + if self.param.fusion[it] in ["class_max"]: + self.actual_channels.append(chan) + print( + chan, + " is not in the semantic segmentation model but is a max channel.", + ) + else: + pass + self.stuff_categories = dict(zip(channels, indices)) + self.segmentation_channels = dict(zip(channels, indices)) + + def __call__(self, image, *args, **kwargs): + """Feewforward image through model and then create channels + + Args: + image (cupy._core.core.ndarray): + *args (): + **kwargs (): + + Returns: + torch.Tensor: + """ + batch = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) + batch = TF.convert_image_dtype(batch, torch.float32) + with torch.no_grad(): + prediction = self.model(batch)["out"] + normalized_masks = torch.squeeze(prediction.softmax(dim=1), dim=0) + # get masks of fix classes + selected_masks = cp.asarray( + normalized_masks[list(self.stuff_categories.values())] + ) + # get values of max, first remove the ones we already have + normalized_masks[list(self.stuff_categories.values())] = 0 + for i in range(self.param.fusion.count("class_max")): + maxim, index = torch.max(normalized_masks, dim=0) + mer = encode_max(maxim, index) + selected_masks = cp.concatenate( + (selected_masks, cp.expand_dims(mer, axis=0)), axis=0 + ) + x = torch.arange(0, index.shape[0]) + y = torch.arange(0, index.shape[1]) + c = torch.meshgrid(x, y, indexing="ij") + normalized_masks[index, c[0], c[1]] = 0 + assert len(self.actual_channels) == selected_masks.shape[0] + return cp.asarray(selected_masks) + + def get_classes(self): + """Get list of strings containing all the classes. + + Returns: + List[str]: List of classes + """ + return self.weights.meta["categories"] + + +class DetectronModel: + def __init__(self, weights, param): + self.cfg = get_cfg() + self.param = param + + # add project-specific config (e.g., TensorMask) here if you're not running a model in detectron2's core library + self.cfg.merge_from_file(model_zoo.get_config_file(weights)) + self.cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5 # set threshold for this model + # Find a model from detectron2's model zoo. You can use the https://dl.fbaipublicfiles... url as well + self.cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(weights) + self.predictor = DefaultPredictor(self.cfg) + self.meta = MetadataCatalog.get(self.cfg.DATASETS.TRAIN[0]) + self.stuff_categories, self.is_stuff = self.resolve_categories("stuff_classes") + self.thing_categories, self.is_thing = self.resolve_categories("thing_classes") + self.segmentation_channels = {} + for chan in self.param.channels: + if chan in self.stuff_categories.keys(): + self.segmentation_channels[chan] = self.stuff_categories[chan] + elif chan in self.thing_categories.keys(): + self.segmentation_channels[chan] = self.thing_categories[chan] + else: + # remove it + pass + self.actual_channels = self.segmentation_channels.keys() + + def resolve_categories(self, name): + classes = self.get_cat(name) + class_to_idx = {cls: idx for (idx, cls) in enumerate(classes)} + print( + "Semantic Segmentation possible channels: ", + classes, + ) + indices = [] + channels = [] + is_thing = [] + for it, chan in enumerate(self.param.channels): + if chan in [cls for cls in list(class_to_idx.keys())]: + indices.append(class_to_idx[chan]) + channels.append(chan) + is_thing.append(True) + elif self.param.fusion[it] in ["class_average", "class_bayesian"]: + is_thing.append(False) + print(chan, " is not in the semantic segmentation model.") + categories = dict(zip(channels, indices)) + cat_isthing = dict(zip(self.param.channels, is_thing)) + return categories, cat_isthing + + def __call__(self, image, *args, **kwargs): + # TODO: there are some instruction on how to change input type + image = cp.flip(image, axis=2) + prediction = self.predictor(image.get()) + probabilities = cp.asarray(torch.softmax(prediction["sem_seg"], dim=0)) + output = cp.zeros( + ( + len(self.segmentation_channels), + probabilities.shape[1], + probabilities.shape[2], + ) + ) + # add semseg + output[cp.array(list(self.is_stuff.values()))] = probabilities[ + list(self.stuff_categories.values()) + ] + # add instances + indices, insta_info = prediction["panoptic_seg"] + # TODO dont know why i need temp, look into how to avoid + temp = output[cp.array(list(self.is_thing.values()))] + for i, insta in enumerate(insta_info): + if insta is None or not insta["isthing"]: + continue + mask = cp.asarray((indices == insta["id"]).int()) + if insta["instance_id"] in self.thing_categories.values(): + temp[i] = mask * insta["score"] + output[cp.array(list(self.is_thing.values()))] = temp + return output + + def get_cat(self, name): + return self.meta.get(name) + + def get_classes(self): + return self.get_cat("thing_classes") + self.get_cat("stuff_classes") + + +class STEGOModel: + def __init__(self, weights, cfg): + self.cfg: FeatureExtractorParameter = cfg + self.model = DinoFeaturizer(weights, cfg=self.cfg) + self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") + self.model.to(self.device) + self.model.eval() + self.shrink = Resize(size=(self.cfg.input_size[0], self.cfg.input_size[1])) + + def to_tensor(self, data): + data = data.astype(np.float32) + if len(data.shape) == 3: # transpose image-like data + data = data.transpose(2, 0, 1) + elif len(data.shape) == 2: + data = data.reshape((1,) + data.shape) + if len(data.shape) == 3 and data.shape[0] == 3: # normalization of rgb images + data = data / 255.0 + tens = torch.as_tensor(data, device="cuda") + return tens + + def __call__(self, image, *args, **kwargs): + # image = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) + image = self.to_tensor(image).unsqueeze(0) + reset_size = Resize(image.shape[-2:]) + image = self.shrink(image) + image = TF.normalize( + image, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225) + ) + + feat1, code1 = self.model(image) + feat2, code2 = self.model(image.flip(dims=[3])) + code = (code1 + code2.flip(dims=[3])) / 2 + code = NF.interpolate( + code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False + ).detach() + code = torch.squeeze(reset_size(code), dim=0) + return code diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index 4e5cb0a3..b956b5f9 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -13,7 +13,8 @@ from cv_bridge import CvBridge from semantic_pointcloud.pointcloud_parameters import PointcloudParameter -from semantic_pointcloud.utils import resolve_model, decode_max +from semantic_pointcloud.networks import resolve_model +from semantic_pointcloud.utils import decode_max class PointcloudNode: diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py index bb58b1ae..b47159e4 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py @@ -1,6 +1,5 @@ from dataclasses import dataclass, field from simple_parsing.helpers import Serializable -from typing import Tuple, List @dataclass diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py index eb4d0de8..9ccba424 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py @@ -1,5 +1,5 @@ import pytest -from semantic_pointcloud.utils import resolve_model +from semantic_pointcloud.networks import resolve_model import cupy as cp import torch from semantic_pointcloud.pointcloud_parameters import ( diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py index 86609c79..69be02ab 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py @@ -1,35 +1,11 @@ -from torchvision.models.segmentation import fcn_resnet50, FCN_ResNet50_Weights -from torchvision.models.segmentation import ( - lraspp_mobilenet_v3_large, - LRASPP_MobileNet_V3_Large_Weights, -) -import torch -import torchvision.transforms.functional as TF -from torchvision.transforms import Resize -import torch.nn.functional as NF import numpy as np import cupy as cp -# Setup detectron2 logger -# import detectron2 from detectron2.utils.logger import setup_logger setup_logger() -from detectron2 import model_zoo -from detectron2.engine import DefaultPredictor -from detectron2.config import get_cfg -from detectron2.data import MetadataCatalog - -from semantic_pointcloud.DINO.modules import DinoFeaturizer - -# from .DINO.modules import DinoFeaturizer -from semantic_pointcloud.pointcloud_parameters import ( - PointcloudParameter, - FeatureExtractorParameter, -) - def encode_max(maxim, index): maxim, index = cp.asarray(maxim, dtype=cp.float32), cp.asarray( index, dtype=cp.uint32 @@ -53,260 +29,3 @@ def decode_max(mer): ind = cp.right_shift(mer, 16) return ma, ind - -def resolve_model(name, config=None): - """Get the model class based on the name of the pretrained model. - - Args: - name (str): Name of pretrained model - [fcn_resnet50,lraspp_mobilenet_v3_large,detectron_coco_panoptic_fpn_R_101_3x] - - Returns: - Dict[str, str]: - """ - if name == "fcn_resnet50": - weights = FCN_ResNet50_Weights.DEFAULT - net = fcn_resnet50 - model = PytorchModel(net, weights, config) - return { - "name": "fcn_resnet50", - "model": model, - } - elif name == "lraspp_mobilenet_v3_large": - weights = LRASPP_MobileNet_V3_Large_Weights.DEFAULT - net = lraspp_mobilenet_v3_large - model = PytorchModel(net, weights, config) - return { - "name": "lraspp_mobilenet_v3_large", - "model": model, - } - elif name == "detectron_coco_panoptic_fpn_R_101_3x": - # "Cityscapes/mask_rcnn_R_50_FPN.yaml" - # "Misc/semantic_R_50_FPN_1x.yaml" - # "Cityscapes-SemanticSegmentation/deeplab_v3_plus_R_103_os16_mg124_poly_90k_bs16.yaml" - # "COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml" - weights = "COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml" - model = DetectronModel(weights, config) - return { - "name": "detectron_coco_panoptic_fpn_R_101_3x", - "model": model, - } - elif name == "DINO": - weights = config.model + str(config.patch_size) - model = STEGOModel(weights, config) - return { - "name": config.model + str(config.patch_size), - "model": model, - } - else: - raise NotImplementedError - - -class PytorchModel: - """ - - segemntation_cahnnels contains only classes - actual_channels: array of all channels of output - """ - def __init__(self, net, weights, param): - self.model = net(weights=weights) - self.weights = weights - self.param = param - self.model.eval() - device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") - self.model.to(device=device) - self.resolve_categories() - - def resolve_categories(self): - """ Create a segmentation_channels containing the actual values that are processed. - - """ - # get all classes - class_to_idx = {cls: idx for (idx, cls) in enumerate(self.get_classes())} - print( - "Semantic Segmentation possible channels: ", - self.get_classes(), - ) - indices = [] - channels = [] - self.actual_channels= [] - # check correspondence of semseg and paramter classes, class_max - for it, chan in enumerate(self.param.channels): - if chan in [cls for cls in list(class_to_idx.keys())]: - indices.append(class_to_idx[chan]) - channels.append(chan) - self.actual_channels.append(chan) - elif self.param.fusion[it] in ["class_average", "class_bayesian"]: - print(chan, " is not in the semantic segmentation model.") - for it, chan in enumerate(self.param.channels): - if self.param.fusion[it] in ["class_max"]: - self.actual_channels.append(chan) - print(chan, " is not in the semantic segmentation model but is a max channel.") - else: - pass - self.stuff_categories = dict(zip(channels, indices)) - self.segmentation_channels = dict(zip(channels, indices)) - - def __call__(self, image, *args, **kwargs): - """Feewforward image through model and then create channels - - Args: - image (cupy._core.core.ndarray): - *args (): - **kwargs (): - - Returns: - torch.Tensor: - """ - batch = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) - batch = TF.convert_image_dtype(batch, torch.float32) - with torch.no_grad(): - prediction = self.model(batch)["out"] - normalized_masks = torch.squeeze(prediction.softmax(dim=1), dim=0) - # get masks of fix classes - selected_masks = cp.asarray( - normalized_masks[list(self.stuff_categories.values())] - ) - # get values of max, first remove the ones we already have - normalized_masks[list(self.stuff_categories.values())] = 0 - for i in range(self.param.fusion.count("class_max")): - maxim, index = torch.max(normalized_masks, dim=0) - mer = encode_max(maxim, index) - selected_masks = cp.concatenate( - (selected_masks, cp.expand_dims(mer, axis=0)), axis=0 - ) - x = torch.arange(0, index.shape[0]) - y = torch.arange(0, index.shape[1]) - c = torch.meshgrid(x, y, indexing='ij') - normalized_masks[index, c[0], c[1]] = 0 - assert len(self.actual_channels) == selected_masks.shape[0] - return cp.asarray(selected_masks) - - def get_classes(self): - """Get list of strings containing all the classes. - - Returns: - List[str]: List of classes - """ - return self.weights.meta["categories"] - - -class DetectronModel: - def __init__(self, weights, param): - self.cfg = get_cfg() - self.param = param - - # add project-specific config (e.g., TensorMask) here if you're not running a model in detectron2's core library - self.cfg.merge_from_file(model_zoo.get_config_file(weights)) - self.cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5 # set threshold for this model - # Find a model from detectron2's model zoo. You can use the https://dl.fbaipublicfiles... url as well - self.cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(weights) - self.predictor = DefaultPredictor(self.cfg) - self.meta = MetadataCatalog.get(self.cfg.DATASETS.TRAIN[0]) - self.stuff_categories, self.is_stuff = self.resolve_categories("stuff_classes") - self.thing_categories, self.is_thing = self.resolve_categories("thing_classes") - self.segmentation_channels = {} - for chan in self.param.channels: - if chan in self.stuff_categories.keys(): - self.segmentation_channels[chan] = self.stuff_categories[chan] - elif chan in self.thing_categories.keys(): - self.segmentation_channels[chan] = self.thing_categories[chan] - else: - # remove it - pass - self.actual_channels = self.segmentation_channels.keys() - def resolve_categories(self, name): - classes = self.get_cat(name) - class_to_idx = {cls: idx for (idx, cls) in enumerate(classes)} - print( - "Semantic Segmentation possible channels: ", - classes, - ) - indices = [] - channels = [] - is_thing = [] - for it, chan in enumerate(self.param.channels): - if chan in [cls for cls in list(class_to_idx.keys())]: - indices.append(class_to_idx[chan]) - channels.append(chan) - is_thing.append(True) - elif self.param.fusion[it] in ["class_average", "class_bayesian"]: - is_thing.append(False) - print(chan, " is not in the semantic segmentation model.") - categories = dict(zip(channels, indices)) - cat_isthing = dict(zip(self.param.channels, is_thing)) - return categories, cat_isthing - - def __call__(self, image, *args, **kwargs): - # TODO: there are some instruction on how to change input type - image = cp.flip(image, axis=2) - prediction = self.predictor(image.get()) - probabilities = cp.asarray(torch.softmax(prediction["sem_seg"], dim=0)) - output = cp.zeros( - ( - len(self.segmentation_channels), - probabilities.shape[1], - probabilities.shape[2], - ) - ) - # add semseg - output[cp.array(list(self.is_stuff.values()))] = probabilities[ - list(self.stuff_categories.values()) - ] - # add instances - indices, insta_info = prediction["panoptic_seg"] - # TODO dont know why i need temp, look into how to avoid - temp = output[cp.array(list(self.is_thing.values()))] - for i, insta in enumerate(insta_info): - if insta is None or not insta["isthing"]: - continue - mask = cp.asarray((indices == insta["id"]).int()) - if insta["instance_id"] in self.thing_categories.values(): - temp[i] = mask * insta["score"] - output[cp.array(list(self.is_thing.values()))] = temp - return output - - def get_cat(self, name): - return self.meta.get(name) - - def get_classes(self): - return self.get_cat("thing_classes") + self.get_cat("stuff_classes") - - -class STEGOModel: - def __init__(self, weights, cfg): - self.cfg: FeatureExtractorParameter = cfg - self.model = DinoFeaturizer(weights, cfg=self.cfg) - self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") - self.model.to(self.device) - self.model.eval() - self.shrink = Resize(size=(self.cfg.input_size[0], self.cfg.input_size[1])) - - def to_tensor(self, data): - data = data.astype(np.float32) - if len(data.shape) == 3: # transpose image-like data - data = data.transpose(2, 0, 1) - elif len(data.shape) == 2: - data = data.reshape((1,) + data.shape) - if len(data.shape) == 3 and data.shape[0] == 3: # normalization of rgb images - data = data / 255.0 - tens = torch.as_tensor(data, device="cuda") - return tens - - def __call__(self, image, *args, **kwargs): - # image = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) - image = self.to_tensor(image).unsqueeze(0) - reset_size = Resize(image.shape[-2:]) - image = self.shrink(image) - image = TF.normalize( - image, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225) - ) - - feat1, code1 = self.model(image) - feat2, code2 = self.model(image.flip(dims=[3])) - code = (code1 + code2.flip(dims=[3])) / 2 - code = NF.interpolate( - code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False - ).detach() - code = torch.squeeze(reset_size(code), dim=0) - return code From a34f5770b8b0b00809bb90f8a055525382864e7b Mon Sep 17 00:00:00 2001 From: Gian Date: Wed, 14 Dec 2022 13:48:38 +0100 Subject: [PATCH 311/504] minor restructuring of pcl --- .../semantic_pointcloud/script/semantic_pointcloud/networks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py index 91e33fa6..e9212b7c 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py @@ -27,6 +27,7 @@ ) from semantic_pointcloud.utils import encode_max + def resolve_model(name, config=None): """Get the model class based on the name of the pretrained model. From 26c67e13cd3b816d2b036d9d29345c0f882be1ad Mon Sep 17 00:00:00 2001 From: Gian Date: Wed, 14 Dec 2022 13:59:09 +0100 Subject: [PATCH 312/504] reformatting with line length 120 --- .../semantic_pointcloud/DINO/modules.py | 22 +++----- .../DINO/vision_transformer.py | 35 +++--------- .../script/semantic_pointcloud/networks.py | 20 ++----- .../semantic_pointcloud/pointcloud_node.py | 54 +++++-------------- .../pointcloud_parameters.py | 4 +- .../tests/test_pointcloud.py | 4 +- .../semantic_pointcloud/tests/test_utils.py | 8 +-- .../script/semantic_pointcloud/utils.py | 5 +- 8 files changed, 40 insertions(+), 112 deletions(-) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/modules.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/modules.py index f2a9f996..70603751 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/modules.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/modules.py @@ -1,12 +1,9 @@ import semantic_pointcloud.DINO.vision_transformer as vits -# import vision_transformer as vits import torch.nn as nn -import torch.nn.functional as F import torch class DinoFeaturizer(nn.Module): - def __init__(self, weights, cfg): super().__init__() self.cfg = cfg @@ -14,13 +11,11 @@ def __init__(self, weights, cfg): self.feat_type = self.cfg.dino_feat_type arch = self.cfg.model - self.model = vits.__dict__[arch]( - patch_size=self.cfg.patch_size, - num_classes=0) + self.model = vits.__dict__[arch](patch_size=self.cfg.patch_size, num_classes=0) for p in self.model.parameters(): p.requires_grad = False self.model.eval().cuda() - self.dropout = torch.nn.Dropout2d(p=.1) + self.dropout = torch.nn.Dropout2d(p=0.1) if arch == "vit_small" and self.cfg.patch_size == 16: url = "dino_deitsmall16_pretrain/dino_deitsmall16_pretrain.pth" @@ -33,7 +28,6 @@ def __init__(self, weights, cfg): else: raise ValueError("Unknown arch and patch size") - # if cfg.pretrained_weights is not None: # state_dict = torch.load(cfg.pretrained_weights, map_location="cpu") # state_dict = state_dict["teacher"] @@ -63,20 +57,20 @@ def __init__(self, weights, cfg): self.cluster2 = self.make_nonlinear_clusterer(self.n_feats) def make_clusterer(self, in_channels): - return torch.nn.Sequential( - torch.nn.Conv2d(in_channels, self.dim, (1, 1))) # , + return torch.nn.Sequential(torch.nn.Conv2d(in_channels, self.dim, (1, 1))) # , def make_nonlinear_clusterer(self, in_channels): return torch.nn.Sequential( torch.nn.Conv2d(in_channels, in_channels, (1, 1)), torch.nn.ReLU(), - torch.nn.Conv2d(in_channels, self.dim, (1, 1))) + torch.nn.Conv2d(in_channels, self.dim, (1, 1)), + ) def forward(self, img, n=1, return_class_feat=False): self.model.eval() with torch.no_grad(): - assert (img.shape[2] % self.cfg.patch_size == 0) - assert (img.shape[3] % self.cfg.patch_size == 0) + assert img.shape[2] % self.cfg.patch_size == 0 + assert img.shape[3] % self.cfg.patch_size == 0 # get selected layer activations feat, attn, qkv = self.model.get_intermediate_feat(img, n=n) @@ -108,5 +102,3 @@ def forward(self, img, n=1, return_class_feat=False): return self.dropout(image_feat), code else: return image_feat, code - - diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/vision_transformer.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/vision_transformer.py index 26ad82af..399b7c1d 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/vision_transformer.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/vision_transformer.py @@ -14,9 +14,7 @@ def drop_path(x, drop_prob: float = 0.0, training: bool = False): if drop_prob == 0.0 or not training: return x keep_prob = 1 - drop_prob - shape = (x.shape[0],) + (1,) * ( - x.ndim - 1 - ) # work with diff dim tensors, not just 2D ConvNets + shape = (x.shape[0],) + (1,) * (x.ndim - 1) # work with diff dim tensors, not just 2D ConvNets random_tensor = keep_prob + torch.rand(shape, dtype=x.dtype, device=x.device) random_tensor.floor_() # binarize output = x.div(keep_prob) * random_tensor @@ -82,11 +80,7 @@ def __init__( def forward(self, x, return_qkv=False): B, N, C = x.shape - qkv = ( - self.qkv(x) - .reshape(B, N, 3, self.num_heads, C // self.num_heads) - .permute(2, 0, 3, 1, 4) - ) + qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) q, k, v = qkv[0], qkv[1], qkv[2] attn = (q @ k.transpose(-2, -1)) * self.scale @@ -154,9 +148,7 @@ def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768): self.patch_size = patch_size self.num_patches = num_patches - self.proj = nn.Conv2d( - in_chans, embed_dim, kernel_size=patch_size, stride=patch_size - ) + self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) def forward(self, x): B, C, H, W = x.shape @@ -201,9 +193,7 @@ def __init__( self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim)) self.pos_drop = nn.Dropout(p=drop_rate) - dpr = [ - x.item() for x in torch.linspace(0, drop_path_rate, depth) - ] # stochastic depth decay rule + dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)] # stochastic depth decay rule self.blocks = nn.ModuleList( [ Block( @@ -223,9 +213,7 @@ def __init__( self.norm = norm_layer(embed_dim) # Classifier head - self.head = ( - nn.Linear(embed_dim, num_classes) if num_classes > 0 else nn.Identity() - ) + self.head = nn.Linear(embed_dim, num_classes) if num_classes > 0 else nn.Identity() trunc_normal_(self.pos_embed, std=0.02) trunc_normal_(self.cls_token, std=0.02) @@ -254,16 +242,11 @@ def interpolate_pos_encoding(self, x, w, h): # see discussion at https://github.com/facebookresearch/dino/issues/8 w0, h0 = w0 + 0.1, h0 + 0.1 patch_pos_embed = nn.functional.interpolate( - patch_pos_embed.reshape( - 1, int(math.sqrt(N)), int(math.sqrt(N)), dim - ).permute(0, 3, 1, 2), + patch_pos_embed.reshape(1, int(math.sqrt(N)), int(math.sqrt(N)), dim).permute(0, 3, 1, 2), scale_factor=(w0 / math.sqrt(N), h0 / math.sqrt(N)), mode="bicubic", ) - assert ( - int(w0) == patch_pos_embed.shape[-2] - and int(h0) == patch_pos_embed.shape[-1] - ) + assert int(w0) == patch_pos_embed.shape[-2] and int(h0) == patch_pos_embed.shape[-1] patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim) return torch.cat((class_pos_embed.unsqueeze(0), patch_pos_embed), dim=1) @@ -398,9 +381,7 @@ def __init__( layers.append(nn.Linear(hidden_dim, bottleneck_dim)) self.mlp = nn.Sequential(*layers) self.apply(self._init_weights) - self.last_layer = nn.utils.weight_norm( - nn.Linear(bottleneck_dim, out_dim, bias=False) - ) + self.last_layer = nn.utils.weight_norm(nn.Linear(bottleneck_dim, out_dim, bias=False)) self.last_layer.weight_g.data.fill_(1) if norm_last_layer: self.last_layer.weight_g.requires_grad = False diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py index e9212b7c..06c48503 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py @@ -140,17 +140,13 @@ def __call__(self, image, *args, **kwargs): prediction = self.model(batch)["out"] normalized_masks = torch.squeeze(prediction.softmax(dim=1), dim=0) # get masks of fix classes - selected_masks = cp.asarray( - normalized_masks[list(self.stuff_categories.values())] - ) + selected_masks = cp.asarray(normalized_masks[list(self.stuff_categories.values())]) # get values of max, first remove the ones we already have normalized_masks[list(self.stuff_categories.values())] = 0 for i in range(self.param.fusion.count("class_max")): maxim, index = torch.max(normalized_masks, dim=0) mer = encode_max(maxim, index) - selected_masks = cp.concatenate( - (selected_masks, cp.expand_dims(mer, axis=0)), axis=0 - ) + selected_masks = cp.concatenate((selected_masks, cp.expand_dims(mer, axis=0)), axis=0) x = torch.arange(0, index.shape[0]) y = torch.arange(0, index.shape[1]) c = torch.meshgrid(x, y, indexing="ij") @@ -227,9 +223,7 @@ def __call__(self, image, *args, **kwargs): ) ) # add semseg - output[cp.array(list(self.is_stuff.values()))] = probabilities[ - list(self.stuff_categories.values()) - ] + output[cp.array(list(self.is_stuff.values()))] = probabilities[list(self.stuff_categories.values())] # add instances indices, insta_info = prediction["panoptic_seg"] # TODO dont know why i need temp, look into how to avoid @@ -275,15 +269,11 @@ def __call__(self, image, *args, **kwargs): image = self.to_tensor(image).unsqueeze(0) reset_size = Resize(image.shape[-2:]) image = self.shrink(image) - image = TF.normalize( - image, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225) - ) + image = TF.normalize(image, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)) feat1, code1 = self.model(image) feat2, code2 = self.model(image.flip(dims=[3])) code = (code1 + code2.flip(dims=[3])) / 2 - code = NF.interpolate( - code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False - ).detach() + code = NF.interpolate(code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False).detach() code = torch.squeeze(reset_size(code), dim=0) return code diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index b956b5f9..61c803a0 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -28,9 +28,7 @@ def __init__(self, sensor_name): self.param: PointcloudParameter = PointcloudParameter() if rospy.has_param("/semantic_pointcloud/subscribers"): config = rospy.get_param("/semantic_pointcloud/subscribers") - self.param: PointcloudParameter = PointcloudParameter.from_dict( - config[sensor_name] - ) + self.param: PointcloudParameter = PointcloudParameter.from_dict(config[sensor_name]) else: self.param.feature_config.input_size = [80, 160] print("NO ROS ENV found.") @@ -63,24 +61,16 @@ def initialize_semantics(self): - feature_channels: is a dictionary that contains the features channel names as key and the fusion algorithm as value. """ if self.param.semantic_segmentation: - self.semantic_model = resolve_model( - self.param.segmentation_model, self.param - ) + self.semantic_model = resolve_model(self.param.segmentation_model, self.param) self.segmentation_channels = {} - for i, (chan, fusion) in enumerate( - zip(self.param.channels, self.param.fusion) - ): + for i, (chan, fusion) in enumerate(zip(self.param.channels, self.param.fusion)): if fusion in ["class_bayesian", "class_average", "class_max"]: self.segmentation_channels[chan] = fusion assert len(self.segmentation_channels.keys()) > 0 if self.param.feature_extractor: - self.feature_extractor = resolve_model( - self.param.feature_config.name, self.param.feature_config - ) + self.feature_extractor = resolve_model(self.param.feature_config.name, self.param.feature_config) self.feature_channels = {} - for i, (chan, fusion) in enumerate( - zip(self.param.channels, self.param.fusion) - ): + for i, (chan, fusion) in enumerate(zip(self.param.channels, self.param.fusion)): if fusion in ["average"]: self.feature_channels[chan] = fusion assert len(self.feature_channels.keys()) > 0 @@ -92,9 +82,7 @@ def register_sub_pub(self): rgb_sub = message_filters.Subscriber(self.param.image_topic, Image) depth_sub = message_filters.Subscriber(self.param.depth_topic, Image) if self.param.confidence: - confidence_sub = message_filters.Subscriber( - self.param.confidence_topic, Image - ) + confidence_sub = message_filters.Subscriber(self.param.confidence_topic, Image) ts = message_filters.ApproximateTimeSynchronizer( [ rgb_sub, @@ -119,9 +107,7 @@ def register_sub_pub(self): # publishers if self.param.semantic_segmentation: if self.param.publish_segmentation_image: - self.seg_pub = rospy.Publisher( - self.param.segmentation_image_topic, Image, queue_size=2 - ) + self.seg_pub = rospy.Publisher(self.param.segmentation_image_topic, Image, queue_size=2) if "class_max" in self.param.fusion: self.labels = self.semantic_model["model"].get_classes() else: @@ -163,9 +149,7 @@ def color_map_viz(self): row_size = 50 col_size = 500 cmap = self.semseg_color_map - array = np.empty( - (row_size * (nclasses), col_size, cmap.shape[1]), dtype=cmap.dtype - ) + array = np.empty((row_size * (nclasses), col_size, cmap.shape[1]), dtype=cmap.dtype) for i in range(nclasses): array[i * row_size : i * row_size + row_size, :] = cmap[i] imshow(array) @@ -203,18 +187,10 @@ def image_callback(self, rgb_msg, depth_msg, confidence_msg=None): confidence = None if self.P is None: return - image = cp.asarray( - self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8") - ) - depth = cp.asarray( - self.cv_bridge.imgmsg_to_cv2(depth_msg, desired_encoding="passthrough") - ) + image = cp.asarray(self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8")) + depth = cp.asarray(self.cv_bridge.imgmsg_to_cv2(depth_msg, desired_encoding="passthrough")) if confidence_msg is not None: - confidence = cp.asarray( - self.cv_bridge.imgmsg_to_cv2( - confidence_msg, desired_encoding="passthrough" - ) - ) + confidence = cp.asarray(self.cv_bridge.imgmsg_to_cv2(confidence_msg, desired_encoding="passthrough")) pcl = self.create_pcl_from_image(image, depth, confidence) if self.param.publish_segmentation_image: @@ -331,9 +307,7 @@ def publish_segmentation_image(self, probabilities): if "class_max" in self.param.fusion: # decode, create an array with all possible classes and insert probabilities it = 0 - for iit, (chan, fuse) in enumerate( - zip(self.param.channels, self.param.fusion) - ): + for iit, (chan, fuse) in enumerate(zip(self.param.channels, self.param.fusion)): if fuse in ["class_max"]: temp = probabilities[it] temp_p, temp_i = decode_max(temp) @@ -344,9 +318,7 @@ def publish_segmentation_image(self, probabilities): elif fuse in ["class_bayesian", "class_average"]: # assign fixed probability to correct index if chan in self.semantic_model["model"].segmentation_channels: - prob[ - self.semantic_model["model"].segmentation_channels[chan] - ] = probabilities[it] + prob[self.semantic_model["model"].segmentation_channels[chan]] = probabilities[it] it += 1 img = cp.argmax(prob, axis=0) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py index b47159e4..c503ca4e 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py @@ -19,9 +19,7 @@ class FeatureExtractorParameter(Serializable): class PointcloudParameter(Serializable): sensor_name: str = "camera" topic_name: str = "/elvation_mapping/pointcloud_semantic" - channels: list = field( - default_factory=lambda: ["rgb", "person", "grass", "tree", "max"] - ) + channels: list = field(default_factory=lambda: ["rgb", "person", "grass", "tree", "max"]) fusion: list = field( default_factory=lambda: [ "color", diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py index 6c4cd94a..419ee55a 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py @@ -85,9 +85,7 @@ def test_pcl_creation(pointcloud_ex, channels, fusion, semseg, segpub, showlbl): amount = 3 if "class_max" in pointcloud_ex.param.fusion: val = cp.random.rand(360, 640, amount, dtype=cp.float32).astype(cp.float16) - ind = cp.random.randint(0, 2, (360, 640, amount), dtype=cp.uint32).astype( - cp.float32 - ) + ind = cp.random.randint(0, 2, (360, 640, amount), dtype=cp.uint32).astype(cp.float32) img = encode_max(val, ind) else: img = (cp.random.rand(360, 640, amount) * 255).astype(cp.int) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py index 9ccba424..0bebfcc6 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py @@ -11,12 +11,12 @@ @pytest.mark.parametrize( "model_name,channels, fusion", [ - ("fcn_resnet50",[],[]), - ("lraspp_mobilenet_v3_large",[],[]), - ("detectron_coco_panoptic_fpn_R_101_3x",[],[]), + ("fcn_resnet50", [], []), + ("lraspp_mobilenet_v3_large", [], []), + ("detectron_coco_panoptic_fpn_R_101_3x", [], []), ], ) -def test_semantic_segmentation(model_name,channels, fusion): +def test_semantic_segmentation(model_name, channels, fusion): param = PointcloudParameter() param.segmentation_model = model_name m = resolve_model(model_name, param) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py index 69be02ab..9959213f 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py @@ -7,9 +7,7 @@ def encode_max(maxim, index): - maxim, index = cp.asarray(maxim, dtype=cp.float32), cp.asarray( - index, dtype=cp.uint32 - ) + maxim, index = cp.asarray(maxim, dtype=cp.float32), cp.asarray(index, dtype=cp.uint32) # fuse them maxim = maxim.astype(cp.float16) maxim = maxim.view(cp.uint16) @@ -28,4 +26,3 @@ def decode_max(mer): ma = ma.astype(np.float32) ind = cp.right_shift(mer, 16) return ma, ind - From a1a743eb79b9038e87ba3ec564fda547234f3ef5 Mon Sep 17 00:00:00 2001 From: Gian Date: Wed, 14 Dec 2022 16:25:37 +0100 Subject: [PATCH 313/504] fixed sem filter for max only and adapted tests --- .../plugins/semantic_filter.py | 14 +++++++++----- .../tests/test_plugins.py | 19 ++++++------------- .../tests/test_semantic_map.py | 5 +++++ 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index cc797410..07fcab07 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -79,22 +79,26 @@ def __call__( Returns: cupy._core.core.ndarray: """ - # get indices of all layers that + # get indices of all layers that contain semantic class information layer_indices = cp.array([], dtype=cp.int32) max_idcs = cp.array([], dtype=cp.int32) for it, fusion_alg in enumerate(semantic_map.param.fusion_algorithms): if fusion_alg in ["class_bayesian", "class_average"]: layer_indices = cp.append(layer_indices, it).astype(cp.int32) - if fusion_alg in ["class_max"]: + # we care only for the first max in the display + if fusion_alg in ["class_max"] and len(max_idcs)<1: max_idcs = cp.append(max_idcs, it).astype(cp.int32) # check which has the highest value # todo we are using the new_map because of the bayesian - class_map = cp.amax(semantic_map.new_map[layer_indices], axis=0) - class_map_id = cp.argmax(semantic_map.semantic_map[layer_indices], axis=0) + if len(layer_indices)>0: + class_map = cp.amax(semantic_map.new_map[layer_indices], axis=0) + class_map_id = cp.argmax(semantic_map.semantic_map[layer_indices], axis=0) + else: + class_map = cp.zeros_like(semantic_map.new_map[0]) + class_map_id = cp.zeros_like(semantic_map.new_map[0],dtype=cp.int32) if "class_max" in semantic_map.param.fusion_algorithms: - # todo here is only cosidered the case where we only have one max max_map = cp.amax(semantic_map.new_map[max_idcs], axis=0) max_map_id = semantic_map.unique_id[semantic_map.id_max[max_idcs]] map = cp.where(max_map > class_map, max_map_id, class_map_id) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py index 0a040ea1..7c594ea9 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -14,8 +14,8 @@ def semmap_ex(add_lay, fusion_alg): weight_file="../../../config/weights.dat", plugin_config_file=plugin_path, ) - p.additional_layers = add_lay - p.fusion_algorithms = fusion_alg + p.subscriber_cfg["front_cam"]["channels"] = add_lay + p.subscriber_cfg["front_cam"]["fusion"] = fusion_alg p.update() e = semantic_map.SemanticMap(p) e.compile_kernels() @@ -32,11 +32,8 @@ def semmap_ex(add_lay, fusion_alg): ), (["grass", "tree"], ["class_average", "class_average"], ["grass"]), (["grass", "tree"], ["class_average", "class_max"], ["tree"]), - # ( - # ["feat_0", "feat_1", "rgb"], - # ["average", "average", "color"], - # ["rgb", "feat_0"], - # ), + (["max1","max2"], ["class_max", "class_max"], ["max1","max2"]), + ], ) def test_plugin_manager(semmap_ex, channels): @@ -59,12 +56,8 @@ def test_plugin_manager(semmap_ex, channels): manager.layers[0] manager.update_with_name("min_filter", elevation_map, layer_names) manager.update_with_name("smooth_filter", elevation_map, layer_names) - manager.update_with_name( - "semantic_filter", elevation_map, layer_names, semmap_ex, rotation - ) - manager.update_with_name( - "semantic_traversability", elevation_map, layer_names, semmap_ex - ) + manager.update_with_name("semantic_filter", elevation_map, layer_names, semmap_ex, rotation) + manager.update_with_name("semantic_traversability", elevation_map, layer_names, semmap_ex) manager.get_map_with_name("smooth") for lay in manager.get_layer_names(): manager.update_with_name(lay, elevation_map, layer_names, semmap_ex, rotation) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py index a63723fa..f38bc73e 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py @@ -49,6 +49,11 @@ def semmap_ex(sem_lay, fusion_alg): ["class_bayesian", "class_max", "color"], ["rgb", "feat_0", "feat_1"], ), + ( + ["max1", "max2", "rgb"], + ["class_max", "class_max", "color"], + ["rgb", "max1", "max2"], + ), ], ) def test_fusion_of_pcl(semmap_ex, channels): From d08f37f917f3a7efbcbf831b7676fed671655657 Mon Sep 17 00:00:00 2001 From: Gian Date: Mon, 19 Dec 2022 18:07:15 +0100 Subject: [PATCH 314/504] working but the bayesian max approach is not using prior --- .../elevation_mapping.py | 6 +- .../kernels/custom_semantic_kernels.py | 3 +- .../plugins/semantic_filter.py | 10 +-- .../elevation_mapping_cupy/semantic_map.py | 72 ++++++++++--------- 4 files changed, 49 insertions(+), 42 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 5a68edb1..8f44ae9c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -890,8 +890,8 @@ def initialize_map(self, points, method="cubic"): weight_file="../config/weights.dat", plugin_config_file="../config/plugin_config.yaml", ) - param.additional_layers = ["feat_0", "feat_1", "rgb", "people"] - param.fusion_algorithms = ["average", "average", "color", "class_average"] + param.additional_layers = ["rgb", "grass", "tree", "people"] + param.fusion_algorithms = ["color", "class_bayesian", "class_bayesian", "class_bayesian"] param.update() elevation = ElevationMap(param) layers = [ @@ -908,7 +908,7 @@ def initialize_map(self, points, method="cubic"): channels = ["x", "y", "z"] + param.additional_layers print(channels) data = np.zeros((elevation.cell_n - 2, elevation.cell_n - 2), dtype=np.float32) - for i in range(20): + for i in range(50): elevation.input(points, channels, R, t, 0, 0) elevation.update_normal(elevation.elevation_map[0]) pos = np.array([i * 0.01, i * 0.02, i * 0.01]) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py index e562c263..f6e8d3ad 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py @@ -99,9 +99,8 @@ def sum_max_kernel( U inside = p[i * pcl_channels[0] + 2]; if (valid) { if (inside) { - // for every max value + // for every max value for ( W it=0;it0: - class_map = cp.amax(semantic_map.new_map[layer_indices], axis=0) + class_map = cp.amax(semantic_map.semantic_map[layer_indices], axis=0) class_map_id = cp.argmax(semantic_map.semantic_map[layer_indices], axis=0) else: - class_map = cp.zeros_like(semantic_map.new_map[0]) - class_map_id = cp.zeros_like(semantic_map.new_map[0],dtype=cp.int32) + class_map = cp.zeros_like(semantic_map.semantic_map[0]) + class_map_id = cp.zeros_like(semantic_map.semantic_map[0],dtype=cp.int32) if "class_max" in semantic_map.param.fusion_algorithms: - max_map = cp.amax(semantic_map.new_map[max_idcs], axis=0) - max_map_id = semantic_map.unique_id[semantic_map.id_max[max_idcs]] + max_map = cp.amax(semantic_map.semantic_map[max_idcs], axis=0) + max_map_id = semantic_map.elements_to_shift["id_max"][max_idcs] map = cp.where(max_map > class_map, max_map_id, class_map_id) else: map = class_map_id diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 9ff5f5b9..703da98b 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -19,7 +19,6 @@ color_correspondences_to_map_kernel, ) - xp = cp @@ -37,6 +36,7 @@ def __init__(self, param: Parameter): self.layer_specs = {} self.layer_names = [] self.unique_fusion = [] + self.elements_to_shift = {} for k, config in self.param.subscriber_cfg.items(): for f, c in zip(config["fusion"], config["channels"]): @@ -44,9 +44,7 @@ def __init__(self, param: Parameter): self.layer_names.append(c) self.layer_specs[c] = f else: - assert ( - self.layer_specs[c] == f - ), "Error: Single layer has multiple fusion algorithms!" + assert self.layer_specs[c] == f, "Error: Single layer has multiple fusion algorithms!" if f not in self.unique_fusion: self.unique_fusion.append(f) @@ -61,6 +59,9 @@ def __init__(self, param: Parameter): (self.amount_layer_names, self.param.cell_n, self.param.cell_n), param.data_type, ) + # which layers should be deleted at each measurement, per default everyone, if a layer should be kept then + # set it at compile kernels + self.delete_new_layers = cp.ones(self.new_map.shape[0], cp.bool8) def clear(self): self.semantic_map *= 0.0 @@ -113,9 +114,7 @@ def compile_kernels(self) -> None: self.param.cell_n, self.param.cell_n, ) - self.color_average_kernel = color_average_kernel( - self.param.cell_n, self.param.cell_n - ) + self.color_average_kernel = color_average_kernel(self.param.cell_n, self.param.cell_n) if "class_average" in self.unique_fusion: print("Initialize class average kernel") self.sum_kernel = sum_kernel( @@ -130,6 +129,8 @@ def compile_kernels(self) -> None: ) if "class_bayesian" in self.unique_fusion: print("Initialize class bayesian kernel") + pcl_ids = self.get_layer_indices("class_bayesian") + self.delete_new_layers[pcl_ids] = 0 self.alpha_kernel = alpha_kernel( self.param.resolution, self.param.cell_n, @@ -137,34 +138,33 @@ def compile_kernels(self) -> None: ) if "class_max" in self.unique_fusion: print("Initialize class max kernel") + pcl_ids = self.get_layer_indices("class_max") + self.delete_new_layers[pcl_ids] = 0 self.sum_max_kernel = sum_max_kernel( self.param.resolution, self.param.cell_n, self.param.cell_n, ) layer_cnt = self.param.fusion_algorithms.count("class_max") - self.id_max = cp.zeros( + id_max = cp.zeros( (layer_cnt, self.param.cell_n, self.param.cell_n), dtype=np.uint32, ) + self.elements_to_shift["id_max"] = id_max self.unique_id = cp.array([0]) if "image_exponential" in self.unique_fusion: - self.average_correspondences_to_map_kernel = ( - average_correspondences_to_map_kernel( - resolution=self.param.resolution, - width=self.param.cell_n, - height=self.param.cell_n, - ) + self.average_correspondences_to_map_kernel = average_correspondences_to_map_kernel( + resolution=self.param.resolution, + width=self.param.cell_n, + height=self.param.cell_n, ) if "image_color" in self.unique_fusion: - self.color_correspondences_to_map_kernel = ( - color_correspondences_to_map_kernel( - resolution=self.param.resolution, - width=self.param.cell_n, - height=self.param.cell_n, - ) + self.color_correspondences_to_map_kernel = color_correspondences_to_map_kernel( + resolution=self.param.resolution, + width=self.param.cell_n, + height=self.param.cell_n, ) def pad_value(self, x, shift_value, idx=None, value=0.0): @@ -198,6 +198,11 @@ def pad_value(self, x, shift_value, idx=None, value=0.0): def shift_map_xy(self, shift_value): self.semantic_map = cp.roll(self.semantic_map, shift_value, axis=(1, 2)) self.pad_value(self.semantic_map, shift_value, value=0.0) + self.new_map = cp.roll(self.new_map, shift_value, axis=(1, 2)) + self.pad_value(self.new_map, shift_value, value=0.0) + for el in self.elements_to_shift.values(): + el = cp.roll(el, shift_value, axis=(1, 2)) + self.pad_value(el, shift_value, value=0.0) def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: """Get all fusion algorithms that need to be applied to a specific pointcloud @@ -212,6 +217,13 @@ def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: fusion_list.append(x) return fusion_list + def get_layer_indices(self, fusion_alg): + layer_indices = cp.array([], dtype=np.int32) + for it, (key, val) in enumerate(self.layer_specs.items()): + if key in val == fusion_alg: + layer_indices = cp.append(layer_indices, it).astype(np.int32) + return layer_indices + def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): """Computes the indices of the channels of the pointcloud and the layers of the semantic map of type fusion_alg. @@ -240,7 +252,7 @@ def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): additional_fusion = self.get_fusion_of_pcl(channels) - self.new_map *= 0.0 + self.new_map[self.delete_new_layers] = 0.0 if "average" in additional_fusion: pcl_ids, layer_ids = self.get_indices_fusion(channels, "average") self.sum_kernel( @@ -325,19 +337,18 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) # do not divide by zero sum_alpha[sum_alpha == 0] = 1 - self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims( - sum_alpha, axis=0 - ) + self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) # assert cp.unique(cp.sum(self.map[layer_ids], axis=0)) equal to zero or to nan + if "class_max" in additional_fusion: # get indices that are of type class_max in pointclopud and in layers pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_max") # decode float32 into to float16 max_pt, pt_id = self.decode_max(points_all[:, pcl_ids]) - # find unique ids in new measurement and in map + # find unique ids in new measurement and in existing map unique_idm = cp.unique(pt_id) - unique_ida = cp.unique(self.unique_id[self.id_max]) + unique_ida = cp.unique(self.unique_id[self.elements_to_shift["id_max"]]) # get all unique ids, where index is the position in the prob_sum and the value in the NN class self.unique_id = cp.unique(cp.concatenate((unique_idm, unique_ida))) # contains the sum of the new measurement probabilities @@ -367,7 +378,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): # add the previous alpha for i, lay in enumerate(layer_ids): c = cp.mgrid[0 : self.new_map.shape[1], 0 : self.new_map.shape[2]] - self.prob_sum[self.id_max[i], c[0], c[1]] = self.new_map[lay] + # self.prob_sum[self.elements_to_shift["id_max"][i], c[0], c[1]] += self.new_map[lay] # todo add residual of prev alpha to the prob_sum # res = 1- self.new_map[lay] # res /= (len(self.unique_id)-1) @@ -375,9 +386,8 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): # find the alpha we want to keep for i, lay in enumerate(layer_ids): self.new_map[lay] = cp.amax(self.prob_sum, axis=0) - self.id_max[i] = cp.argmax(self.prob_sum, axis=0) + self.elements_to_shift["id_max"][lay] = self.unique_id[cp.argmax(self.prob_sum, axis=0)] self.prob_sum[cp.argmax(self.prob_sum, axis=0)] = 0 - # # update map calculate new thetas sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) # do not divide by zero @@ -426,9 +436,7 @@ def update_layers_image( self.new_map *= 0 config = self.param.subscriber_cfg[sub_key] - for j, (fusion, channel) in enumerate( - zip(config["fusion"], config["channels"]) - ): + for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): sem_map_idx = self.get_index(channel) if fusion == "image_exponential": From d790fc19ce088df40128f83e88efa4d53f8500cc Mon Sep 17 00:00:00 2001 From: Gian Date: Mon, 19 Dec 2022 19:19:09 +0100 Subject: [PATCH 315/504] black formatting --- .../script/elevation_mapping_cupy/custom_kernels.py | 2 -- .../script/elevation_mapping_cupy/elevation_mapping.py | 4 ++-- .../script/elevation_mapping_cupy/parameter.py | 4 ++-- .../script/elevation_mapping_cupy/plugins/inpainting.py | 1 - 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py index 382e4174..8323fa67 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/custom_kernels.py @@ -141,7 +141,6 @@ def add_points_kernel( enable_edge_shaped=True, enable_visibility_cleanup=True, ): - add_points_kernel = cp.ElementwiseKernel( in_params="raw U p, raw U center_x, raw U center_y, raw U R, raw U t, raw U norm_map", out_params="raw U map, raw T newmap", @@ -289,7 +288,6 @@ def error_counting_kernel( ramped_height_range_b, ramped_height_range_c, ): - error_counting_kernel = cp.ElementwiseKernel( in_params="raw U map, raw U p, raw U center_x, raw U center_y, raw U R, raw U t", out_params="raw U newmap, raw T error, raw T error_cnt", diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 4a50e069..ea2c47cf 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -312,11 +312,11 @@ def update_upper_bound_with_valid_elevation(self): self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) - def input(self, raw_points,channels, R, t, position_noise, orientation_noise): + def input(self, raw_points, channels, R, t, position_noise, orientation_noise): # Update elevation map using point cloud input. raw_points = cp.asarray(raw_points) raw_points = raw_points[~cp.isnan(raw_points).any(axis=1)] - self.update_map_with_kernel(raw_points[:,:3], cp.asarray(R), cp.asarray(t), position_noise, orientation_noise) + self.update_map_with_kernel(raw_points[:, :3], cp.asarray(R), cp.asarray(t), position_noise, orientation_noise) def update_normal(self, dilated_map): with self.map_lock: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index a00c3ddf..62b4ffeb 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -11,8 +11,8 @@ @dataclass class Parameter(Serializable): resolution: float = 0.02 - additional_layers: list = ['feat_0'].copy - fusion_algorithms: list = ['average'].copy + additional_layers: list = ["feat_0"].copy + fusion_algorithms: list = ["average"].copy map_length: float = 10.0 sensor_noise_factor: float = 0.05 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py index 8c1ac90a..f15b8b02 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py @@ -8,7 +8,6 @@ import numpy as np import cv2 as cv - from .plugin_manager import PluginBase From 12b30159ec811224ab8e88d0ff185a3fc7a1c890 Mon Sep 17 00:00:00 2001 From: Matias Mattamala Date: Thu, 22 Dec 2022 17:02:50 +0100 Subject: [PATCH 316/504] Add subscriber hints --- .../config/anymal_parameters.yaml | 6 +-- .../config/anymal_sensor_parameter.yaml | 46 +++++++++---------- .../elevation_mapping_ros.hpp | 1 + .../anymal_semantic_elevation_single.launch | 13 ++---- .../src/elevation_mapping_ros.cpp | 19 +++++++- 5 files changed, 50 insertions(+), 35 deletions(-) diff --git a/elevation_mapping_cupy/config/anymal_parameters.yaml b/elevation_mapping_cupy/config/anymal_parameters.yaml index 4941a011..324c2208 100644 --- a/elevation_mapping_cupy/config/anymal_parameters.yaml +++ b/elevation_mapping_cupy/config/anymal_parameters.yaml @@ -75,7 +75,7 @@ publishers: fps: 2.0 semantic_map_raw: - layers: ['elevation', 'traversability', 'variance', 'rgb_image'] + layers: ['elevation', 'traversability', 'variance', 'rgb_image', 'visual_traversability'] basic_layers: ['elevation', 'traversability'] fps: 2.0 # elevation_map_recordable: @@ -89,8 +89,8 @@ publishers: #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [0.0] # z direction. Should be same number as initialize_frame_id. +initialize_frame_id: ['RF_FOOT', 'LF_FOOT', 'RH_FOOT', 'LH_FOOT'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 5 # dilation size after the init. initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml index d80d9611..4804a9e2 100644 --- a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml @@ -37,33 +37,33 @@ subscribers: # topic_name: '/elevation_mapping/pointcloud_semantic' # data_type: pointcloud - alphasense_front_rgb: - fusion: ['image_color'] - topic_name_camera: /alphasense_driver_ros/cam4/debayered - topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info - channels: ["rgb_image"] - data_type: image + # alphasense_front_rgb: + # fusion: ['image_color'] + # topic_name_camera: /alphasense_driver_ros/cam4/debayered/compressed + # topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info + # channels: ["rgb_image"] + # data_type: image - alphasense_left_rgb: - fusion: ['image_color'] - topic_name_camera: /alphasense_driver_ros/cam3/debayered - topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info - channels: ["rgb_image"] - data_type: image + # alphasense_left_rgb: + # fusion: ['image_color'] + # topic_name_camera: /alphasense_driver_ros/cam3/debayered/compressed + # topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info + # channels: ["rgb_image"] + # data_type: image - alphasense_right_rgb: - fusion: ['image_color'] - topic_name_camera: /alphasense_driver_ros/cam5/debayered - topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info - channels: ["rgb_image"] - data_type: image + # alphasense_right_rgb: + # fusion: ['image_color'] + # topic_name_camera: /alphasense_driver_ros/cam5/debayered/compressed + # topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info + # channels: ["rgb_image"] + # data_type: image wvn_prediction: fusion: ['image_exponential'] - topic_name_camera: '/wild_visual_navigation_node/current_prediction' + topic_name_camera: '/wild_visual_navigation_node/traversability_raw' topic_name_camera_info: '/wild_visual_navigation_node/camera_info' channels: ["visual_traversability"] data_type: image @@ -108,24 +108,24 @@ subscribers: front_depth: channels: [] - fusion: ['average'] + fusion: [] topic_name: /depth_camera_front/point_cloud_self_filtered data_type: pointcloud rear_depth: channels: [] - fusion: ['average'] + fusion: [] topic_name: /depth_camera_rear/point_cloud_self_filtered data_type: pointcloud left_depth: channels: [] - fusion: ['average'] + fusion: [] topic_name: /depth_camera_left/point_cloud_self_filtered data_type: pointcloud right_depth: channels: [] - fusion: ['average'] + fusion: [] topic_name: /depth_camera_right/point_cloud_self_filtered data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index db262e41..fa519920 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -17,6 +17,7 @@ // ROS #include +#include #include #include #include diff --git a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch index 2e1d7575..e2600f50 100644 --- a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch +++ b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch @@ -1,13 +1,9 @@ - + + - - - - - @@ -15,7 +11,8 @@ - - + + + \ No newline at end of file diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index d5a72247..13e4d571 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -87,7 +87,24 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) std::string camera_topic = subscriber.second["topic_name_camera"]; std::string info_topic = subscriber.second["topic_name_camera_info"]; - ImageSubscriberPtr image_sub = std::make_shared(nh_, camera_topic, 1); + std::cout << "pre camera_topic: " << camera_topic << std::endl; + + // Handle compressed images + std::string image_transport_hint = "compressed"; + std::size_t ind = camera_topic.find(image_transport_hint); + if (ind != std::string::npos) { + image_transport_hint = camera_topic.substr(ind, camera_topic.length()); + camera_topic.erase(ind-1, camera_topic.length()); + } else { + image_transport_hint = "raw"; + } + + std::cout << "post camera_topic: " << camera_topic << std::endl; + std::cout << "image_transport_hint: " << image_transport_hint << std::endl; + + // Setup subscriber + const auto hint = image_transport::TransportHints(image_transport_hint, ros::TransportHints(), ros::NodeHandle(camera_topic)); + ImageSubscriberPtr image_sub = std::make_shared(nh_, camera_topic, 1, hint.getRosHints()); CameraInfoSubscriberPtr cam_info_sub = std::make_shared(nh_, info_topic, 1); imageSubs_.push_back(image_sub); cameraInfoSubs_.push_back(cam_info_sub); From a4b486bee2c74236f8c7061873ee5bfe63bc22e5 Mon Sep 17 00:00:00 2001 From: Matias Mattamala Date: Thu, 22 Dec 2022 20:25:01 +0100 Subject: [PATCH 317/504] Enable subscription of compressed images --- elevation_mapping_cupy/CMakeLists.txt | 2 + .../config/anymal_sensor_parameter.yaml | 62 ++++++++++--------- .../elevation_mapping_ros.hpp | 4 +- elevation_mapping_cupy/package.xml | 1 + .../src/elevation_mapping_ros.cpp | 30 ++++----- 5 files changed, 55 insertions(+), 44 deletions(-) diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index 4aa69cb0..2b4cc858 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -25,6 +25,7 @@ find_package(catkin REQUIRED elevation_map_msgs grid_map_msgs grid_map_ros + image_transport pcl_ros pybind11_catkin ) @@ -43,6 +44,7 @@ catkin_package( geometry_msgs elevation_map_msgs grid_map_ros + image_transport pcl_ros pybind11_catkin ) diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml index 4804a9e2..8d7ac369 100644 --- a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml @@ -31,34 +31,34 @@ subscribers: # channels: ["single_channel_semantic"] # data_type: image -# front_cam: -# channels: ['rgb'] -# fusion: ['color'] -# topic_name: '/elevation_mapping/pointcloud_semantic' -# data_type: pointcloud + # front_cam: + # channels: ['rgb'] + # fusion: ['color'] + # topic_name: '/elevation_mapping/pointcloud_semantic' + # data_type: pointcloud - # alphasense_front_rgb: - # fusion: ['image_color'] - # topic_name_camera: /alphasense_driver_ros/cam4/debayered/compressed - # topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info - # channels: ["rgb_image"] - # data_type: image + alphasense_front_rgb: + fusion: ['image_color'] + topic_name_camera: /alphasense_driver_ros/cam4/debayered/compressed + topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info + channels: ["rgb_image"] + data_type: image - # alphasense_left_rgb: - # fusion: ['image_color'] - # topic_name_camera: /alphasense_driver_ros/cam3/debayered/compressed - # topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info - # channels: ["rgb_image"] - # data_type: image + alphasense_left_rgb: + fusion: ['image_color'] + topic_name_camera: /alphasense_driver_ros/cam3/debayered/compressed + topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info + channels: ["rgb_image"] + data_type: image - # alphasense_right_rgb: - # fusion: ['image_color'] - # topic_name_camera: /alphasense_driver_ros/cam5/debayered/compressed - # topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info - # channels: ["rgb_image"] - # data_type: image + alphasense_right_rgb: + fusion: ['image_color'] + topic_name_camera: /alphasense_driver_ros/cam5/debayered/compressed + topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info + channels: ["rgb_image"] + data_type: image wvn_prediction: @@ -108,24 +108,30 @@ subscribers: front_depth: channels: [] - fusion: [] + fusion: ['average'] topic_name: /depth_camera_front/point_cloud_self_filtered data_type: pointcloud rear_depth: channels: [] - fusion: [] + fusion: ['average'] topic_name: /depth_camera_rear/point_cloud_self_filtered data_type: pointcloud left_depth: channels: [] - fusion: [] + fusion: ['average'] topic_name: /depth_camera_left/point_cloud_self_filtered data_type: pointcloud right_depth: channels: [] - fusion: [] + fusion: ['average'] topic_name: /depth_camera_right/point_cloud_self_filtered - data_type: pointcloud \ No newline at end of file + data_type: pointcloud + + velodyne: + channels: [] + fusion: ['average'] + topic_name: /point_cloud_filter/lidar/point_cloud_filtered + data_type: pointcloud diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index fa519920..4a6b09ba 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -18,6 +18,7 @@ // ROS #include #include +#include #include #include #include @@ -61,7 +62,7 @@ class ElevationMappingNode { using RowMatrixXd = Eigen::Matrix; using ColMatrixXf = Eigen::Matrix; - using ImageSubscriber = message_filters::Subscriber; + using ImageSubscriber = image_transport::SubscriberFilter; using ImageSubscriberPtr = std::shared_ptr; using CameraInfoSubscriber = message_filters::Subscriber; using CameraInfoSubscriberPtr = std::shared_ptr; @@ -94,6 +95,7 @@ class ElevationMappingNode { visualization_msgs::Marker vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id) const; ros::NodeHandle nh_; + image_transport::ImageTransport it_; std::vector pointcloudSubs_; std::vector imageSubs_; std::vector cameraInfoSubs_; diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index 7af4624c..614d711a 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -19,6 +19,7 @@ grid_map_msgs elevation_map_msgs grid_map_ros + image_transport pcl_ros pybind11_catkin diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 13e4d571..7e9c807b 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -21,7 +21,8 @@ namespace elevation_mapping_cupy { ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) - : lowpassPosition_(0, 0, 0), + : it_(nh), + lowpassPosition_(0, 0, 0), lowpassOrientation_(0, 0, 0, 1), positionError_(0), orientationError_(0), @@ -87,26 +88,25 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) std::string camera_topic = subscriber.second["topic_name_camera"]; std::string info_topic = subscriber.second["topic_name_camera_info"]; - std::cout << "pre camera_topic: " << camera_topic << std::endl; - - // Handle compressed images - std::string image_transport_hint = "compressed"; - std::size_t ind = camera_topic.find(image_transport_hint); + // Handle compressed images with transport hints + // We obtain the hint from the last part of the topic name + std::string transport_hint = "compressed"; + std::size_t ind = camera_topic.find(transport_hint); // Find if compressed is in the topic name if (ind != std::string::npos) { - image_transport_hint = camera_topic.substr(ind, camera_topic.length()); - camera_topic.erase(ind-1, camera_topic.length()); + transport_hint = camera_topic.substr(ind, camera_topic.length()); // Get the hint as the last part + camera_topic.erase(ind - 1, camera_topic.length()); // We remove the hint from the topic } else { - image_transport_hint = "raw"; + transport_hint = "raw"; // In the default case we assume raw topic } - std::cout << "post camera_topic: " << camera_topic << std::endl; - std::cout << "image_transport_hint: " << image_transport_hint << std::endl; - // Setup subscriber - const auto hint = image_transport::TransportHints(image_transport_hint, ros::TransportHints(), ros::NodeHandle(camera_topic)); - ImageSubscriberPtr image_sub = std::make_shared(nh_, camera_topic, 1, hint.getRosHints()); - CameraInfoSubscriberPtr cam_info_sub = std::make_shared(nh_, info_topic, 1); + const auto hint = image_transport::TransportHints(transport_hint, ros::TransportHints(), ros::NodeHandle(camera_topic)); + ImageSubscriberPtr image_sub = std::make_shared(); + image_sub->subscribe(it_, camera_topic, 1, hint); imageSubs_.push_back(image_sub); + + CameraInfoSubscriberPtr cam_info_sub = std::make_shared(); + cam_info_sub->subscribe(nh_, info_topic, 1); cameraInfoSubs_.push_back(cam_info_sub); CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); From 84c708440e2dd1243b71e20a54631eac8d540a7a Mon Sep 17 00:00:00 2001 From: Gian Date: Fri, 23 Dec 2022 18:12:45 +0100 Subject: [PATCH 318/504] config fix --- elevation_mapping_cupy/config/anymal_sensor_parameter.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml index 688c623a..76ee262f 100644 --- a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml @@ -39,7 +39,7 @@ subscribers: alphasense_front_rgb: fusion: ['image_color'] - topic_name_camera: /alphasense_driver_ros/cam4/debayered/compressed + topic_name_camera: /alphasense_driver_ros/cam4/debayered topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info channels: ["rgb_image"] data_type: image @@ -47,7 +47,7 @@ subscribers: alphasense_left_rgb: fusion: ['image_color'] - topic_name_camera: /alphasense_driver_ros/cam3/debayered/compressed + topic_name_camera: /alphasense_driver_ros/cam3/debayered topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info channels: ["rgb_image"] data_type: image @@ -55,7 +55,7 @@ subscribers: alphasense_right_rgb: fusion: ['image_color'] - topic_name_camera: /alphasense_driver_ros/cam5/debayered/compressed + topic_name_camera: /alphasense_driver_ros/cam5/debayered topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info channels: ["rgb_image"] data_type: image From 57d1d52f63b1c32b3829cbb8dedd562492af6f25 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Wed, 4 Jan 2023 12:21:59 +0100 Subject: [PATCH 319/504] applied black formatting --- .../elevation_mapping_cupy/plugins/semantic_filter.py | 6 +++--- .../elevation_mapping_cupy/tests/test_plugins.py | 3 +-- sensor_processing/debug_publisher/image_debug_node.py | 11 +++++------ sensor_processing/semantic_pointcloud/setup.py | 4 ++-- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index 9a61432d..045f536a 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -86,17 +86,17 @@ def __call__( if fusion_alg in ["class_bayesian", "class_average"]: layer_indices = cp.append(layer_indices, it).astype(cp.int32) # we care only for the first max in the display - if fusion_alg in ["class_max"] and len(max_idcs)<1: + if fusion_alg in ["class_max"] and len(max_idcs) < 1: max_idcs = cp.append(max_idcs, it).astype(cp.int32) # check which has the highest value # todo we are using the new_map because of the bayesian - if len(layer_indices)>0: + if len(layer_indices) > 0: class_map = cp.amax(semantic_map.semantic_map[layer_indices], axis=0) class_map_id = cp.argmax(semantic_map.semantic_map[layer_indices], axis=0) else: class_map = cp.zeros_like(semantic_map.semantic_map[0]) - class_map_id = cp.zeros_like(semantic_map.semantic_map[0],dtype=cp.int32) + class_map_id = cp.zeros_like(semantic_map.semantic_map[0], dtype=cp.int32) if "class_max" in semantic_map.param.fusion_algorithms: max_map = cp.amax(semantic_map.semantic_map[max_idcs], axis=0) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py index 7c594ea9..25c0619c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -32,8 +32,7 @@ def semmap_ex(add_lay, fusion_alg): ), (["grass", "tree"], ["class_average", "class_average"], ["grass"]), (["grass", "tree"], ["class_average", "class_max"], ["tree"]), - (["max1","max2"], ["class_max", "class_max"], ["max1","max2"]), - + (["max1", "max2"], ["class_max", "class_max"], ["max1", "max2"]), ], ) def test_plugin_manager(semmap_ex, channels): diff --git a/sensor_processing/debug_publisher/image_debug_node.py b/sensor_processing/debug_publisher/image_debug_node.py index 91743acb..6d625a68 100644 --- a/sensor_processing/debug_publisher/image_debug_node.py +++ b/sensor_processing/debug_publisher/image_debug_node.py @@ -18,13 +18,12 @@ def __init__(self): self.cv_bridge = CvBridge() # rospy.Subscriber("", CameraInfo, self.cam_info_callback) rospy.Subscriber("/zed2i/zed_node/right/image_rect_color", Image, self.image_callback) - self.debug_pub = rospy.Publisher("/debug_image" , Image, queue_size=2) - - + self.debug_pub = rospy.Publisher("/debug_image", Image, queue_size=2) + def image_callback(self, rgb_msg): - img = self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8") - out = np.zeros((img.shape[0],img.shape[1]), dtype=np.uint16) - out[:, :int(img.shape[1]/2)] = 1 + img = self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8") + out = np.zeros((img.shape[0], img.shape[1]), dtype=np.uint16) + out[:, : int(img.shape[1] / 2)] = 1 seg_msg = self.cv_bridge.cv2_to_imgmsg(out, encoding="mono16") seg_msg.header = rgb_msg.header self.debug_pub.publish(seg_msg) diff --git a/sensor_processing/semantic_pointcloud/setup.py b/sensor_processing/semantic_pointcloud/setup.py index 94ad1600..1af8da13 100644 --- a/sensor_processing/semantic_pointcloud/setup.py +++ b/sensor_processing/semantic_pointcloud/setup.py @@ -3,9 +3,9 @@ setup_args = generate_distutils_setup( packages=[ - 'semantic_pointcloud', + "semantic_pointcloud", ], - package_dir={'': 'script'}, + package_dir={"": "script"}, ) setup(**setup_args) From c00d4182c67e1ff1dde79ea2958f74c0bc700a14 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Wed, 4 Jan 2023 12:45:22 +0100 Subject: [PATCH 320/504] black formatting main branch --- .../script/elevation_mapping_cupy/elevation_mapping.py | 4 ++-- .../script/elevation_mapping_cupy/parameter.py | 4 ++-- elevation_mapping_cupy/setup.py | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 4a50e069..ea2c47cf 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -312,11 +312,11 @@ def update_upper_bound_with_valid_elevation(self): self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) - def input(self, raw_points,channels, R, t, position_noise, orientation_noise): + def input(self, raw_points, channels, R, t, position_noise, orientation_noise): # Update elevation map using point cloud input. raw_points = cp.asarray(raw_points) raw_points = raw_points[~cp.isnan(raw_points).any(axis=1)] - self.update_map_with_kernel(raw_points[:,:3], cp.asarray(R), cp.asarray(t), position_noise, orientation_noise) + self.update_map_with_kernel(raw_points[:, :3], cp.asarray(R), cp.asarray(t), position_noise, orientation_noise) def update_normal(self, dilated_map): with self.map_lock: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index a00c3ddf..62b4ffeb 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -11,8 +11,8 @@ @dataclass class Parameter(Serializable): resolution: float = 0.02 - additional_layers: list = ['feat_0'].copy - fusion_algorithms: list = ['average'].copy + additional_layers: list = ["feat_0"].copy + fusion_algorithms: list = ["average"].copy map_length: float = 10.0 sensor_noise_factor: float = 0.05 diff --git a/elevation_mapping_cupy/setup.py b/elevation_mapping_cupy/setup.py index 51954f5b..f225f03a 100644 --- a/elevation_mapping_cupy/setup.py +++ b/elevation_mapping_cupy/setup.py @@ -3,9 +3,10 @@ setup_args = generate_distutils_setup( packages=[ - 'elevation_mapping_cupy', - 'elevation_mapping_cupy.plugins', + "elevation_mapping_cupy", + "elevation_mapping_cupy.plugins", ], - package_dir={'': 'script'}) + package_dir={"": "script"}, +) setup(**setup_args) From 2f6f2103109c0d8717c0b660bdceacec0a4600b0 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Wed, 4 Jan 2023 14:22:17 +0100 Subject: [PATCH 321/504] Added some comments --- .../elevation_mapping.py | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index b27c8e70..38ca9836 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -48,9 +48,7 @@ class ElevationMap: - """ - Core elevation mapping class. - """ + """Core elevation mapping class.""" def __init__(self, param: Parameter): """ @@ -230,7 +228,7 @@ def shift_map_z(self, delta_z): def compile_kernels(self): """Compile all kernels belonging to the elevation map.""" - # Compile custom cuda kernels. + self.new_map = cp.zeros( (self.elevation_map.shape[0], self.cell_n, self.cell_n), dtype=self.data_type, @@ -285,6 +283,8 @@ def compile_kernels(self): self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) def compile_image_kernels(self): + """Compile kernels related to processing image messages.""" + for config in self.param.subscriber_cfg.values(): if config["data_type"] == "image": self.valid_correspondence = cp.asarray( @@ -390,7 +390,12 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori self.update_normal(self.traversability_input) def clear_overlap_map(self, t): - # Clear overlapping area around center + """Clear overlapping areas around the map center. + + Args: + t (cupy._core.core.ndarray): Absolute point position + """ + height_min = t[2] - self.param.overlap_clear_range_z height_max = t[2] + self.param.overlap_clear_range_z near_map = self.elevation_map[:, self.cell_min : self.cell_max, self.cell_min : self.cell_max] @@ -439,7 +444,6 @@ def input( Returns: None: """ - # Update elevation map using point cloud input. raw_points = cp.asarray(raw_points, dtype=self.data_type) additional_channels = channels[3:] raw_points = raw_points[~cp.isnan(raw_points).any(axis=1)] @@ -455,13 +459,27 @@ def input( def input_image( self, sub_key: str, - image: cp._core.core.ndarray, + image: List[cp._core.core.ndarray], R: cp._core.core.ndarray, t: cp._core.core.ndarray, K: cp._core.core.ndarray, image_height: int, image_width: int, ): + """Input image and fuse the new measurements to update the elevation map. + + Args: + sub_key (str): Key used to identify the subscriber configuration + image (List[cupy._core.core.ndarray]): List of array containing the individual image input channels + R (cupy._core.core.ndarray): Camera optical center rotation + t (cupy._core.core.ndarray): Camera optical center translation + K (cupy._core.core.ndarray): Camera intrinsics + image_height (int): Image height + image_width (int): Image width + + Returns: + None: + """ image = np.stack(image, axis=0) if len(image.shape) == 2: image = image[None] @@ -619,10 +637,10 @@ def exists_layer(self, name): """Check if the layer exists in elevation map or in the semantic map. Args: - name (str): + name (str): Layer name Returns: - bool: + bool: Indicates if layer exists. """ if name in self.layer_names: return True From fb01fdad73d33eb332c1fd382c6168a45a1a087c Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 10 Jan 2023 18:57:48 +0100 Subject: [PATCH 322/504] added ordered pointclouds and xyz pointclouds in pcl publisher --- elevation_mapping_cupy/src/elevation_mapping_ros.cpp | 4 ++-- .../script/semantic_pointcloud/pointcloud_node.py | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 3a06fae9..b8760628 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -299,9 +299,9 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl } uint array_dim = channels.size(); - RowMatrixXd points = RowMatrixXd(pcl_pc->width,array_dim); + RowMatrixXd points = RowMatrixXd(pcl_pc->width*pcl_pc->height,array_dim); - for (unsigned int i = 0; i < pcl_pc->width; ++i) { + for (unsigned int i = 0; i < pcl_pc->width*pcl_pc->height; ++i) { int jit = 0; for(unsigned int j = 0; j Date: Mon, 16 Jan 2023 14:40:09 +0100 Subject: [PATCH 323/504] fixed a few pointcloud features and added a network and added anymal urdf --- .../config/anymal_sensor_parameter.yaml | 22 +++++++++---------- .../anymal_semantic_elevation_single.launch | 7 ++++++ .../script/semantic_pointcloud/networks.py | 9 ++++++++ .../semantic_pointcloud/pointcloud_node.py | 14 +++++++----- .../pointcloud_parameters.py | 6 ++--- 5 files changed, 38 insertions(+), 20 deletions(-) diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml index 76ee262f..27bd064a 100644 --- a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml @@ -94,17 +94,17 @@ subscribers: # confidence_threshold: 10 # feature_extractor: False - # front_bpearl: - # channels: [] - # fusion: [] - # topic_name: /point_cloud_filter_rsl/filter_and_merger_rsl - # data_type: pointcloud - - # rear_bpearl: - # channels: [] - # fusion: [] - # topic_name: /robot_self_filter/bpearl_rear/point_cloud - # data_type: pointcloud + front_bpearl: + channels: [] + fusion: [] + topic_name: /robot_self_filter/bpearl_front/point_cloud + data_type: pointcloud + + rear_bpearl: + channels: [] + fusion: [] + topic_name: /robot_self_filter/bpearl_rear/point_cloud + data_type: pointcloud front_depth: channels: [] diff --git a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch index e2600f50..725c96bd 100644 --- a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch +++ b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch @@ -1,7 +1,14 @@ + + + + + + + diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py index 06c48503..ebd9dcc8 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py @@ -3,6 +3,7 @@ lraspp_mobilenet_v3_large, LRASPP_MobileNet_V3_Large_Weights, ) +from torchvision.models.segmentation import (deeplabv3_mobilenet_v3_large, DeepLabV3_MobileNet_V3_Large_Weights ) import torch import torchvision.transforms.functional as TF from torchvision.transforms import Resize @@ -54,6 +55,14 @@ def resolve_model(name, config=None): "name": "lraspp_mobilenet_v3_large", "model": model, } + elif name == "deeplabv3_mobilenet_v3_large": + weights = DeepLabV3_MobileNet_V3_Large_Weights.COCO_WITH_VOC_LABELS_V1 + net = deeplabv3_mobilenet_v3_large + model = PytorchModel(net, weights, config) + return { + "name": "deeplabv3_mobilenet_v3_large", + "model": model, + } elif name == "detectron_coco_panoptic_fpn_R_101_3x": # "Cityscapes/mask_rcnn_R_50_FPN.yaml" # "Misc/semantic_R_50_FPN_1x.yaml" diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index 15872de9..42ad5085 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -26,11 +26,11 @@ def __init__(self, sensor_name): """ # TODO: if this is going to be loaded from another package we might need to change namespace self.param: PointcloudParameter = PointcloudParameter() + self.param.feature_config.input_size = [80, 160] if rospy.has_param("/semantic_pointcloud/subscribers"): config = rospy.get_param("/semantic_pointcloud/subscribers") self.param: PointcloudParameter = PointcloudParameter.from_dict(config[sensor_name]) else: - self.param.feature_config.input_size = [80, 160] print("NO ROS ENV found.") self.param.sensor_name = sensor_name @@ -85,8 +85,8 @@ def register_sub_pub(self): confidence_sub = message_filters.Subscriber(self.param.confidence_topic, Image) ts = message_filters.ApproximateTimeSynchronizer( [ - rgb_sub, depth_sub, + rgb_sub, confidence_sub, ], queue_size=10, @@ -95,8 +95,8 @@ def register_sub_pub(self): else: ts = message_filters.ApproximateTimeSynchronizer( [ - rgb_sub, depth_sub, + rgb_sub, ], queue_size=10, slop=0.5, @@ -184,11 +184,13 @@ def cam_info_callback(self, msg): self.width = msg.width self.header = msg.header - def image_callback(self, rgb_msg, depth_msg, confidence_msg=None): + def image_callback(self, depth_msg, rgb_msg=None,confidence_msg=None): confidence = None + image = None if self.P is None: return - image = cp.asarray(self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8")) + if rgb_msg is not None: + image = cp.asarray(self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8")) depth = cp.asarray(self.cv_bridge.imgmsg_to_cv2(depth_msg, desired_encoding="passthrough")) if confidence_msg is not None: confidence = cp.asarray(self.cv_bridge.imgmsg_to_cv2(confidence_msg, desired_encoding="passthrough")) @@ -335,7 +337,7 @@ def publish_segmentation_image(self, probabilities): def publish_pointcloud(self, pcl, header): pc2 = ros_numpy.msgify(PointCloud2, pcl) pc2.header = header - pc2.header.frame_id = self.param.cam_frame + # pc2.header.frame_id = self.param.cam_frame self.pcl_pub.publish(pc2) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py index c503ca4e..d7448181 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py @@ -30,9 +30,9 @@ class PointcloudParameter(Serializable): ] ) - semantic_segmentation: bool = True + semantic_segmentation: bool = False segmentation_model: str = "lraspp_mobilenet_v3_large" - publish_segmentation_image: bool = True + publish_segmentation_image: bool = False segmentation_image_topic: str = "/semantic_pointcloud/sem_seg" pub_all: bool = False show_label_legend: bool = False @@ -41,7 +41,7 @@ class PointcloudParameter(Serializable): image_topic: str = "/zed2i/zed_node/left/image_rect_color" depth_topic: str = "/zed2i/zed_node/depth/depth_registered" cam_frame: str = "zed2i_right_camera_optical_frame" - confidence: bool = True + confidence: bool = False confidence_topic: str = "/zed2i/zed_node/confidence/confidence_map" confidence_threshold: int = 10 From 3800fa398943fe64634aa7d004966420f2c126a3 Mon Sep 17 00:00:00 2001 From: Gian Date: Thu, 19 Jan 2023 15:48:53 +0100 Subject: [PATCH 324/504] typos, dead code and todo cleanup --- .../elevation_mapping.py | 10 +++---- .../elevation_mapping_cupy/parameter.py | 3 ++- .../plugins/semantic_filter.py | 1 - .../elevation_mapping_cupy/semantic_map.py | 26 ++++++------------- 4 files changed, 14 insertions(+), 26 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 38ca9836..d449af62 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -28,7 +28,6 @@ from elevation_mapping_cupy.kernels import polygon_mask_kernel from elevation_mapping_cupy.kernels import image_to_map_correspondence_kernel - from elevation_mapping_cupy.map_initializer import MapInitializer from elevation_mapping_cupy.plugins.plugin_manager import PluginManager from elevation_mapping_cupy.semantic_map import SemanticMap @@ -366,7 +365,6 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori ) self.average_map_kernel(self.new_map, self.elevation_map, size=(self.cell_n * self.cell_n)) - # self.update_additional_layers(additional_fusion, points_all, channels, R, t) self.semantic_map.update_layers_pointcloud(points_all, channels, R, t, self.new_map) if self.param.enable_overlap_clearance: @@ -428,8 +426,8 @@ def input( channels: List[str], R: cp._core.core.ndarray, t: cp._core.core.ndarray, - position_noise: int, - orientation_noise: int, + position_noise: float, + orientation_noise: float, ): """Input the pointcloud and fuse the new measurements to update the elevation map. @@ -438,8 +436,8 @@ def input( channels (List[str]): R (cupy._core.core.ndarray): t (cupy._core.core.ndarray): - position_noise (int): - orientation_noise (int): + position_noise (float): + orientation_noise (float): Returns: None: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 9edbf012..6ef6daf6 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -8,7 +8,8 @@ from simple_parsing.helpers import Serializable from dataclasses import field -# todo add this for the future + +# todo add these dataclasses @dataclass class Subscriber(Serializable): channels: list = field(default_factory=lambda: ["feat_0"]) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index 045f536a..5ea2cc07 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -90,7 +90,6 @@ def __call__( max_idcs = cp.append(max_idcs, it).astype(cp.int32) # check which has the highest value - # todo we are using the new_map because of the bayesian if len(layer_indices) > 0: class_map = cp.amax(semantic_map.semantic_map[layer_indices], axis=0) class_map_id = cp.argmax(semantic_map.semantic_map[layer_indices], axis=0) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 3a00f5a6..1eea84b8 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -32,7 +32,6 @@ def __init__(self, param: Parameter): self.param = param - # TODO: maps channel to fusion strategy (maybe rename) self.layer_specs = {} self.layer_names = [] self.unique_fusion = [] @@ -45,7 +44,6 @@ def __init__(self, param: Parameter): self.layer_specs[c] = f else: assert self.layer_specs[c] == f, "Error: Single layer has multiple fusion algorithms!" - if f not in self.unique_fusion: self.unique_fusion.append(f) @@ -59,8 +57,8 @@ def __init__(self, param: Parameter): (self.amount_layer_names, self.param.cell_n, self.param.cell_n), param.data_type, ) - # which layers should be deleted at each measurement, per default everyone, if a layer should be kept then - # set it at compile kernels + # which layers should be reset to zero at each update, per default everyone, + # if a layer should not be reset, it is defined in compile_kernels function self.delete_new_layers = cp.ones(self.new_map.shape[0], cp.bool8) def clear(self): @@ -71,11 +69,7 @@ def compile_kernels(self) -> None: Returns: None: """ - # TODO: maybe this could be improved by creating functions for each single - # create a base class containing compile kernel as well as update and this then can be created for various - # then for each method this two functions canbe overloaded. and called through a list of all the algporithms - # that need to be called - # but I am not sure as we would need to pass a lot of arguments... check plugin + # TODO: maybe this could be improved by creating functions for each single fusion algorithm if "average" in self.unique_fusion: print("Initialize fusion kernel") self.sum_kernel = sum_kernel( @@ -97,7 +91,7 @@ def compile_kernels(self) -> None: ), self.param.data_type, ) - # todo initialize the variance with a value different than 0 + # TODO initialize the variance with a value different than 0 self.sum_compact_kernel = sum_compact_kernel( self.param.resolution, self.param.cell_n, @@ -238,12 +232,12 @@ def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): """ # this contains exactly the fusion alg type for each channel of the pcl pcl_val_list = [self.layer_specs[x] for x in pcl_channels] - # this contains the indeces of the pointcloud where we have to perform a certain fusion + # this contains the indices of the point cloud where we have to perform a certain fusion pcl_indices = cp.array( [idp + 3 for idp, x in enumerate(pcl_val_list) if x == fusion_alg], dtype=np.int32, ) - # create a list of indeces of the layers that will be updated by the pointcloud with specific fusion alg + # create a list of indices of the layers that will be updated by the point cloud with specific fusion alg layer_indices = cp.array([], dtype=np.int32) for it, (key, val) in enumerate(self.layer_specs.items()): if key in pcl_channels and val == fusion_alg: @@ -339,8 +333,6 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): sum_alpha[sum_alpha == 0] = 1 self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) - # assert cp.unique(cp.sum(self.map[layer_ids], axis=0)) equal to zero or to nan - if "class_max" in additional_fusion: # get indices that are of type class_max in pointclopud and in layers pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_max") @@ -379,7 +371,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): for i, lay in enumerate(layer_ids): c = cp.mgrid[0 : self.new_map.shape[1], 0 : self.new_map.shape[2]] # self.prob_sum[self.elements_to_shift["id_max"][i], c[0], c[1]] += self.new_map[lay] - # todo add residual of prev alpha to the prob_sum + # TODO add residual of prev alpha to the prob_sum # res = 1- self.new_map[lay] # res /= (len(self.unique_id)-1) @@ -466,7 +458,7 @@ def update_layers_image( self.semantic_map[sem_map_idx] = self.new_map[sem_map_idx] else: - raise ValueError("Fusion for image is unkown.") + raise ValueError("Fusion for image is unknown.") def decode_max(self, mer): mer = mer.astype(cp.float32) @@ -489,8 +481,6 @@ def get_rgb(self, name): idx = self.layer_names.index(name) c = self.process_map_for_publish(self.semantic_map[idx]) c = c.astype(np.float32) - # c = xp.uint32(c.get()) - # c.dtype = np.float32 return c def get_semantic(self, name): From e2e2f8e36404e07397e2daf51810492267688875 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Mon, 23 Jan 2023 19:08:26 +0100 Subject: [PATCH 325/504] added exponential averaging --- .../script/elevation_mapping_cupy/semantic_map.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 1eea84b8..f5c2ca4f 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -16,6 +16,7 @@ ) from elevation_mapping_cupy.kernels import ( average_correspondences_to_map_kernel, + exponential_correspondences_to_map_kernel, color_correspondences_to_map_kernel, ) @@ -148,10 +149,11 @@ def compile_kernels(self) -> None: self.unique_id = cp.array([0]) if "image_exponential" in self.unique_fusion: - self.average_correspondences_to_map_kernel = average_correspondences_to_map_kernel( + self.exponential_correspondences_to_map_kernel = exponential_correspondences_to_map_kernel( resolution=self.param.resolution, width=self.param.cell_n, height=self.param.cell_n, + alpha=0.7 ) if "image_color" in self.unique_fusion: @@ -430,7 +432,7 @@ def update_layers_image( sem_map_idx = self.get_index(channel) if fusion == "image_exponential": - self.average_correspondences_to_map_kernel( + self.exponential_correspondences_to_map_kernel( self.semantic_map, cp.uint64(sem_map_idx), image[j], From bdceaba50a41d65b77a56559ad9aef7ab1ed5f32 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Mon, 23 Jan 2023 19:08:47 +0100 Subject: [PATCH 326/504] added kernel --- .../kernels/custom_image_kernels.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py index 47770488..07a275e1 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py @@ -151,6 +151,35 @@ def average_correspondences_to_map_kernel(resolution, width, height): return average_correspondences_to_map_kernel +def exponential_correspondences_to_map_kernel(resolution, width, height, alpha): + exponential_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + new_sem_map[get_map_idx(i, map_idx)] = new_sem_map[get_map_idx(i, map_idx)] * (1-${alpha}) + ${alpha} * image_mono[idx]; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + + """ + ).substitute(alpha=alpha), + name="exponential_correspondences_to_map_kernel", + ) + return exponential_correspondences_to_map_kernel + def color_correspondences_to_map_kernel(resolution, width, height): color_correspondences_to_map_kernel = cp.ElementwiseKernel( in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", From 92427d1d10d9ac3a19071e40950241c2db85af9b Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Mon, 23 Jan 2023 21:28:18 +0100 Subject: [PATCH 327/504] fixed bug in exponential averaging --- .../elevation_mapping_cupy/kernels/custom_image_kernels.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py index 07a275e1..526de667 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py @@ -169,7 +169,7 @@ def exponential_correspondences_to_map_kernel(resolution, width, height, alpha): if (valid_correspondence[cell_idx]){ int cell_idx_2 = get_map_idx(i, 1); int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; - new_sem_map[get_map_idx(i, map_idx)] = new_sem_map[get_map_idx(i, map_idx)] * (1-${alpha}) + ${alpha} * image_mono[idx]; + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)] * (1-${alpha}) + ${alpha} * image_mono[idx]; }else{ new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; } From fef135107996c5b40e603c493f7f58ebca04d4ef Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 24 Jan 2023 09:12:08 +0100 Subject: [PATCH 328/504] little detail --- .../script/elevation_mapping_cupy/plugins/plugin_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index faa74ebb..d780a59f 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -82,7 +82,7 @@ def init(self, plugin_params: List[PluginParams], extra_params: List[Dict]): for name, obj in inspect.getmembers(m): if ( inspect.isclass(obj) - # and issubclass(obj, PluginBase) + and issubclass(obj, PluginBase) and name != "PluginBase" ): # Add cell_n to params From 939f9ecaa06aea74f0d0a42f2f4cf510d61d08e6 Mon Sep 17 00:00:00 2001 From: Gian Date: Sun, 29 Jan 2023 14:54:40 +0100 Subject: [PATCH 329/504] added tests and removed for loops in kernels --- .../elevation_mapping.py | 2 +- .../kernels/custom_semantic_kernels.py | 140 +++---- .../kernels/playground.py | 360 ++++++++++++++++++ .../elevation_mapping_cupy/semantic_map.py | 38 +- 4 files changed, 455 insertions(+), 85 deletions(-) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/playground.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 690b41a0..f48e39ef 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -429,7 +429,7 @@ def input( position_noise: float, orientation_noise: float, ): - """Input the pointcloud and fuse the new measurements to update the elevation map. + """Input the point cloud and fuse the new measurements to update the elevation map. Args: raw_points (cupy._core.core.ndarray): diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py index cbcba587..91f91e6c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py @@ -7,6 +7,16 @@ def sum_kernel( width, height, ): + """Sums the semantic values of the classes for the exponentiala verage or for the average. + + Args: + resolution: + width: + height: + + Returns: + + """ # input the list of layers, amount of channels can slo be input through kernel sum_kernel = cp.ElementwiseKernel( in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", @@ -21,15 +31,15 @@ def sum_kernel( ).substitute(resolution=resolution, width=width, height=height), operation=string.Template( """ - U idx = p[i * pcl_channels[0]]; - U valid = p[i * pcl_channels[0] + 1]; - U inside = p[i * pcl_channels[0] + 2]; + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; if (valid) { if (inside) { - for ( W it=0;it=theta_max){ - arg_max = map_lay[it]; + arg_max = map_lay[layer]; theta_max = theta; } - } atomicAdd(&newmap[get_map_idx(idx, arg_max)], theta_max); } } @@ -175,12 +185,12 @@ def average_kernel( ).substitute(width=width, height=height), operation=string.Template( """ - U cnt = new_elmap[get_map_idx(i, 2)]; + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; if (cnt>0){ - for ( int it=0;it0){ - for ( int it=0;it0){ - for ( int it=0;it0){ - for ( int it=0;it=0){ // unsigned int prev_r = get_r(prev_color); // unsigned int prev_g = get_g(prev_color); // unsigned int prev_b = get_b(prev_color); - // unsigned int r = prev_r/2 + color_map[get_map_idx(i, it*3)]/(2*cnt); - // unsigned int g = prev_g/2 + color_map[get_map_idx(i, it*3+1)]/(2*cnt); - // unsigned int b = prev_b/2 + color_map[get_map_idx(i, it*3+2)]/(2*cnt); + // unsigned int r = prev_r/2 + color_map[get_map_idx(i, layer*3)]/(2*cnt); + // unsigned int g = prev_g/2 + color_map[get_map_idx(i, layer*3+1)]/(2*cnt); + // unsigned int b = prev_b/2 + color_map[get_map_idx(i, layer*3+2)]/(2*cnt); //} unsigned int rgb = (r<<16) + (g << 8) + b; float rgb_ = __uint_as_float(rgb); - map[get_map_idx(i, map_lay[it])] = rgb_; - } + map[get_map_idx(id, map_lay[layer])] = rgb_; } """ ).substitute(), diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/playground.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/playground.py new file mode 100644 index 00000000..6ee8c623 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/playground.py @@ -0,0 +1,360 @@ +import cupy as cp + +from elevation_mapping_cupy.parameter import Parameter + +from elevation_mapping_cupy.kernels import ( + add_points_kernel, + +) +from elevation_mapping_cupy.kernels import ( + average_kernel, + class_average_kernel, + alpha_kernel, + bayesian_inference_kernel, + add_color_kernel, + color_average_kernel, + sum_compact_kernel, + sum_max_kernel, + sum_kernel, +) + +def add_points_to_map(points_all): + """Add points to map. + TODO fine tune the parameters to make it work""" + param = Parameter() + param.ramped_height_range_a = 10 + param.ramped_height_range_b = 0.001 + param.ramped_height_range_c = 10 + param.min_valid_distance = 0.001 + param.max_height_range = 10.0 + add_points_kernel_ = add_points_kernel( + 0.2, + 4, + 4, + param.sensor_noise_factor, + param.mahalanobis_thresh, + param.outlier_variance, + param.wall_num_thresh, + param.max_ray_length, + param.cleanup_step, + param.min_valid_distance, + param.max_height_range, + param.cleanup_cos_thresh, + param.ramped_height_range_a, + param.ramped_height_range_b, + param.ramped_height_range_c, + param.enable_edge_sharpen, + param.enable_visibility_cleanup, + ) + # create points + points_all = cp.array([[0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) + points = points_all[:, :3] + elevation_map = cp.zeros((3, 3, 3), dtype=cp.float32) + normal_map = cp.zeros((3, 3, 3), dtype=cp.float32) + new_map = cp.zeros((3, 3, 3), dtype=cp.float32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + + add_points_kernel_( + cp.array([0.0], dtype=cp.float32), + cp.array([0.0], dtype=cp.float32), + R, + t, + normal_map, + points, + elevation_map, + new_map, + size=(points.shape[0]), + ) + print("idx, valid, inside, values") + points_all[:, 0] = 1 + points_all[:, 1:3] = 1.0 + print("points all after", points_all) + + +def sum_kernel_fct(): + # create points + points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) + points = points_all[:, :3] + # arguments for kernel + semantic_map = cp.zeros((1, 3, 3), dtype=cp.float32) + new_map = cp.zeros((1, 3, 3), dtype=cp.float32) + pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + # compile kernel + sum_kernel_ = sum_kernel( + 0.9, + 4, + 4, + ) + # simulating adding the points + print("idx, valid, inside, values") + points_all[:, 0] = 1 + points_all[:, 1:3] = 1.0 + print("points all after ", points_all) + # run the kernel + sum_kernel_( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + new_map, + size=(points_all.shape[0]*pcl_ids.shape[0]), + ) + print("semantic_map", semantic_map) + print("new_map", new_map) + + +def average_kernel_fct(): + points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) + elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) + elevation_map[2] = 12 + semantic_map = cp.zeros((1,4, 4), dtype=cp.float32) + new_map = cp.ones((1, 4, 4), dtype=cp.float32) + pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + # compile kernel + average_kernel_ = average_kernel( + 4, + 4, + ) + cell_n = 4 + print("new_map", new_map) + print("semantic_map", semantic_map) + print("elevation_map", elevation_map) + + average_kernel_( + new_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + elevation_map, + semantic_map, + size=(cell_n * cell_n*pcl_ids.shape[0]), + ) + print("semantic_map", semantic_map) + +def color_kernel(): + # params + cell_n = 4 + pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) + semantic_map = cp.zeros((1,4, 4), dtype=cp.float32) + + # compile kernel + add_color_kernel_ = add_color_kernel( + cell_n, + cell_n, + ) + color_average_kernel_ = color_average_kernel(cell_n, cell_n) + + # updatelayer + color_map = cp.zeros( + (1 + 3 * layer_ids.shape[0], cell_n, cell_n), + dtype=cp.uint32, + ) + + points_all = points_all.astype(cp.float32) + add_color_kernel_( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + color_map, + size=(points_all.shape[0]*pcl_ids.shape[0]), + ) + color_average_kernel_( + color_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + size=(cell_n * cell_n*pcl_ids.shape[0]), + ) + print(color_map) + +def bayesian_inference_kernel_fct(): + # params + cell_n = 4 + resolution = 0.9 + elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) + elevation_map[2] = 12 + semantic_map = cp.zeros((1,4, 4), dtype=cp.float32) + new_map = cp.ones((1, 4, 4), dtype=cp.float32) + pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) + semantic_map = cp.zeros((1,4, 4), dtype=cp.float32) + + # compile kernel + sum_mean = cp.ones( + ( + pcl_ids.shape[0], + cell_n, + cell_n, + ), + cp.float32, + ) + # TODO initialize the variance with a value different than 0 + sum_compact_kernel_ = sum_compact_kernel( + resolution, + cell_n, + cell_n, + ) + bayesian_inference_kernel_ = bayesian_inference_kernel( + cell_n, + cell_n, + ) + + # updatelayer + sum_mean *= 0 + sum_compact_kernel_( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + sum_mean, + size=(points_all.shape[0]*pcl_ids.shape[0]), + ) + bayesian_inference_kernel_( + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + elevation_map, + new_map, + sum_mean, + semantic_map, + size=(cell_n * cell_n*pcl_ids.shape[0]), + ) + print("semantic_map", semantic_map) + + +def class_average_kernel_fct(): + # params + cell_n = 4 + resolution = 0.9 + average_weight = 0.5 + map_shape = (4, 4, 4) + elevation_map = cp.zeros((3,4,4), dtype=cp.float32) + elevation_map[2] = 3 + semantic_map = cp.zeros(map_shape, dtype=cp.float32) + new_map = cp.zeros(map_shape, dtype=cp.float32) + pcl_ids, layer_ids = cp.array([3,4], dtype=cp.int32), cp.array([1,2], dtype=cp.int32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + points_all = cp.array([[0.1, 0.1, 0.1, 0.3,0.3], [0.1, 0.1, 0.1, 0.1,0.2], [0.1, 0.1, 0.1, 0.1,0.2]], dtype=cp.float32) + # compile kernel + sum_kernel_ = sum_kernel( + 0.9, + 4, + 4, + ) + class_average_kernel_ = class_average_kernel( + cell_n, + cell_n, + average_weight, + ) + print("x,y,z,class") + print("points all after ", points_all) + + # simulating adding the points + print("idx, valid, inside, values") + points_all[:, 0] = 1 + points_all[:, 1:3] = 1.0 + print("points all after ", points_all) + # run the kernel + sum_kernel_( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + new_map, + size=(points_all.shape[0]*pcl_ids.shape[0]), + ) + print("new_map bef", new_map) + print("pcl_ids.shape[0]", pcl_ids.shape[0]) + class_average_kernel_( + new_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + elevation_map, + semantic_map, + size=(cell_n * cell_n*pcl_ids.shape[0]), + ) + print("semantic_map", semantic_map) + print("new_map", new_map) + +def class_bayesian_inference_fct(): + # params + cell_n = 4 + resolution = 0.9 + average_weight = 0.5 + elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) + elevation_map[2] = 3 + semantic_map = cp.zeros((1,4, 4), dtype=cp.float32) + new_map = cp.zeros((1, 4, 4), dtype=cp.float32) + pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) + semantic_map = cp.zeros((1,4, 4), dtype=cp.float32) + # compile kernel + alpha_kernel_ = alpha_kernel( + resolution, + cell_n, + cell_n, + ) + # simulating adding the points + print("idx, valid, inside, values") + points_all[:, 0] = 1 + points_all[:, 1:3] = 1.0 + print("points all after ", points_all) + # run the kernel + alpha_kernel_( + points_all, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + new_map, + size=(points_all.shape[0]*pcl_ids.shape[0]), + ) + # calculate new thetas + sum_alpha = cp.sum(new_map[layer_ids], axis=0) + # do not divide by zero + sum_alpha[sum_alpha == 0] = 1 + semantic_map[layer_ids] = new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) + print("semantic_map", semantic_map) + print("new_map", new_map) + + + + +if __name__ == "__main__": + # average + sum_kernel_fct() + average_kernel_fct() + # color kernel + color_kernel() + # bayesian inference + bayesian_inference_kernel_fct() + # class average + class_average_kernel_fct() + # class bayesian inference + class_bayesian_inference_fct() + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 1eea84b8..6e0b5dc7 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -142,7 +142,7 @@ def compile_kernels(self) -> None: layer_cnt = self.param.fusion_algorithms.count("class_max") id_max = cp.zeros( (layer_cnt, self.param.cell_n, self.param.cell_n), - dtype=np.uint32, + dtype=cp.uint32, ) self.elements_to_shift["id_max"] = id_max self.unique_id = cp.array([0]) @@ -212,10 +212,10 @@ def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: return fusion_list def get_layer_indices(self, fusion_alg): - layer_indices = cp.array([], dtype=np.int32) + layer_indices = cp.array([], dtype=cp.int32) for it, (key, val) in enumerate(self.layer_specs.items()): if key in val == fusion_alg: - layer_indices = cp.append(layer_indices, it).astype(np.int32) + layer_indices = cp.append(layer_indices, it).astype(cp.int32) return layer_indices def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): @@ -235,13 +235,13 @@ def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): # this contains the indices of the point cloud where we have to perform a certain fusion pcl_indices = cp.array( [idp + 3 for idp, x in enumerate(pcl_val_list) if x == fusion_alg], - dtype=np.int32, + dtype=cp.int32, ) # create a list of indices of the layers that will be updated by the point cloud with specific fusion alg - layer_indices = cp.array([], dtype=np.int32) + layer_indices = cp.array([], dtype=cp.int32) for it, (key, val) in enumerate(self.layer_specs.items()): if key in pcl_channels and val == fusion_alg: - layer_indices = cp.append(layer_indices, it).astype(np.int32) + layer_indices = cp.append(layer_indices, it).astype(cp.int32) return pcl_indices, layer_indices def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): @@ -255,7 +255,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): t, pcl_ids, layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), self.semantic_map, self.new_map, size=(points_all.shape[0]), @@ -264,7 +264,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): self.new_map, pcl_ids, layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), elevation_map, self.semantic_map, size=(self.param.cell_n * self.param.cell_n), @@ -278,14 +278,14 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): t, pcl_ids, layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), self.sum_mean, size=(points_all.shape[0]), ) self.bayesian_inference_kernel( pcl_ids, layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), elevation_map, self.new_map, self.sum_mean, @@ -300,19 +300,19 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): t, pcl_ids, layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), self.semantic_map, self.new_map, - size=(points_all.shape[0]), + size=(points_all.shape[0]*pcl_ids.shape[0]), ) self.class_average_kernel( self.new_map, pcl_ids, layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), elevation_map, self.semantic_map, - size=(self.param.cell_n * self.param.cell_n), + size=(self.param.cell_n * self.param.cell_n*pcl_ids.shape[0]), ) if "class_bayesian" in additional_fusion: @@ -323,7 +323,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): points_all, pcl_ids, layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), self.new_map, size=(points_all.shape[0]), ) @@ -362,7 +362,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): layer_ids, cp.array( [points_all.shape[1], pcl_ids.shape[0], pt_id.shape[1]], - dtype=np.int32, + dtype=cp.int32, ), self.prob_sum, size=(points_all.shape[0]), @@ -390,7 +390,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): pcl_ids, layer_ids = self.get_indices_fusion(channels, "color") self.color_map = cp.zeros( (1 + 3 * layer_ids.shape[0], self.param.cell_n, self.param.cell_n), - dtype=np.uint32, + dtype=cp.uint32, ) points_all = points_all.astype(cp.float32) @@ -400,7 +400,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): t, pcl_ids, layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), self.color_map, size=(points_all.shape[0]), ) @@ -408,7 +408,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): self.color_map, pcl_ids, layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=np.int32), + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), self.semantic_map, size=(self.param.cell_n * self.param.cell_n), ) From f974688cc75d63637fb859479fc977b211c98a31 Mon Sep 17 00:00:00 2001 From: Gian Date: Mon, 30 Jan 2023 14:34:24 +0100 Subject: [PATCH 330/504] added kernel tests --- .../kernels/custom_semantic_kernels.py | 2 +- .../test_semantic_kernels.py} | 280 +++++++++--------- 2 files changed, 135 insertions(+), 147 deletions(-) rename elevation_mapping_cupy/script/elevation_mapping_cupy/{kernels/playground.py => tests/test_semantic_kernels.py} (57%) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py index 91f91e6c..38910c53 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py @@ -264,7 +264,7 @@ def class_average_kernel( map[get_map_idx(id, map_lay[layer])] = val; } else{ - U val = ${alpha} *prev_val + ${alpha} * newmap[get_map_idx(id, map_lay[layer])]/(cnt); + U val = ${alpha} *prev_val + (1-${alpha}) * newmap[get_map_idx(id, map_lay[layer])]/(cnt); map[get_map_idx(id, map_lay[layer])] = val; } } diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/playground.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py similarity index 57% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/playground.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py index 6ee8c623..2e01a901 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/playground.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py @@ -1,10 +1,11 @@ +import pytest +from elevation_mapping_cupy import parameter, elevation_mapping import cupy as cp from elevation_mapping_cupy.parameter import Parameter from elevation_mapping_cupy.kernels import ( add_points_kernel, - ) from elevation_mapping_cupy.kernels import ( average_kernel, @@ -18,68 +19,75 @@ sum_kernel, ) -def add_points_to_map(points_all): - """Add points to map. - TODO fine tune the parameters to make it work""" - param = Parameter() - param.ramped_height_range_a = 10 - param.ramped_height_range_b = 0.001 - param.ramped_height_range_c = 10 - param.min_valid_distance = 0.001 - param.max_height_range = 10.0 - add_points_kernel_ = add_points_kernel( - 0.2, - 4, - 4, - param.sensor_noise_factor, - param.mahalanobis_thresh, - param.outlier_variance, - param.wall_num_thresh, - param.max_ray_length, - param.cleanup_step, - param.min_valid_distance, - param.max_height_range, - param.cleanup_cos_thresh, - param.ramped_height_range_a, - param.ramped_height_range_b, - param.ramped_height_range_c, - param.enable_edge_sharpen, - param.enable_visibility_cleanup, - ) - # create points - points_all = cp.array([[0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) - points = points_all[:, :3] - elevation_map = cp.zeros((3, 3, 3), dtype=cp.float32) - normal_map = cp.zeros((3, 3, 3), dtype=cp.float32) - new_map = cp.zeros((3, 3, 3), dtype=cp.float32) + +# to check output run: pytest -rP test_semantic_kernels.py + + +# only kernel where we test only one layer +def test_color_kernel(): + # params + cell_n = 4 + pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) R = cp.eye(3, dtype=cp.float32) t = cp.array([0, 0, 0], dtype=cp.float32) + points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) + semantic_map = cp.zeros((1, 4, 4), dtype=cp.float32) - add_points_kernel_( - cp.array([0.0], dtype=cp.float32), - cp.array([0.0], dtype=cp.float32), + # compile kernel + add_color_kernel_ = add_color_kernel( + cell_n, + cell_n, + ) + color_average_kernel_ = color_average_kernel(cell_n, cell_n) + + # updatelayer + color_map = cp.zeros( + (1 + 3 * layer_ids.shape[0], cell_n, cell_n), + dtype=cp.uint32, + ) + + points_all = points_all.astype(cp.float32) + add_color_kernel_( + points_all, R, t, - normal_map, - points, - elevation_map, - new_map, - size=(points.shape[0]), + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + color_map, + size=(points_all.shape[0] * pcl_ids.shape[0]), ) - print("idx, valid, inside, values") - points_all[:, 0] = 1 - points_all[:, 1:3] = 1.0 - print("points all after", points_all) + color_average_kernel_( + color_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + size=(cell_n * cell_n * pcl_ids.shape[0]), + ) + print(color_map) -def sum_kernel_fct(): +@pytest.mark.parametrize( + "map_shape, points_all,pcl_ids, layer_ids", + [ + ( + (3, 4, 4), + cp.array( + [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 + ), + cp.array([3], dtype=cp.int32), + cp.array([0], dtype=cp.int32), + ), + ], +) +def test_sum_kernel(map_shape, points_all, pcl_ids, layer_ids): # create points - points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) + resolution = 0.9 points = points_all[:, :3] # arguments for kernel - semantic_map = cp.zeros((1, 3, 3), dtype=cp.float32) - new_map = cp.zeros((1, 3, 3), dtype=cp.float32) - pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) + semantic_map = cp.zeros(map_shape, dtype=cp.float32) + new_map = cp.zeros(map_shape, dtype=cp.float32) R = cp.eye(3, dtype=cp.float32) t = cp.array([0, 0, 0], dtype=cp.float32) # compile kernel @@ -103,19 +111,30 @@ def sum_kernel_fct(): cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), semantic_map, new_map, - size=(points_all.shape[0]*pcl_ids.shape[0]), + size=(points_all.shape[0] * pcl_ids.shape[0]), ) print("semantic_map", semantic_map) print("new_map", new_map) -def average_kernel_fct(): - points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) +@pytest.mark.parametrize( + "map_shape, points_all,pcl_ids, layer_ids", + [ + ( + (3, 4, 4), + cp.array( + [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 + ), + cp.array([3], dtype=cp.int32), + cp.array([0], dtype=cp.int32), + ), + ], +) +def test_average_kernel(map_shape, points_all, pcl_ids, layer_ids): elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) - elevation_map[2] = 12 - semantic_map = cp.zeros((1,4, 4), dtype=cp.float32) - new_map = cp.ones((1, 4, 4), dtype=cp.float32) - pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) + elevation_map[2] = points_all.shape[0] + semantic_map = cp.zeros(map_shape, dtype=cp.float32) + new_map = cp.ones(map_shape, dtype=cp.float32) R = cp.eye(3, dtype=cp.float32) t = cp.array([0, 0, 0], dtype=cp.float32) # compile kernel @@ -135,66 +154,34 @@ def average_kernel_fct(): cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), elevation_map, semantic_map, - size=(cell_n * cell_n*pcl_ids.shape[0]), + size=(cell_n * cell_n * pcl_ids.shape[0]), ) print("semantic_map", semantic_map) -def color_kernel(): - # params - cell_n = 4 - pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) - R = cp.eye(3, dtype=cp.float32) - t = cp.array([0, 0, 0], dtype=cp.float32) - points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) - semantic_map = cp.zeros((1,4, 4), dtype=cp.float32) - - # compile kernel - add_color_kernel_ = add_color_kernel( - cell_n, - cell_n, - ) - color_average_kernel_ = color_average_kernel(cell_n, cell_n) - - # updatelayer - color_map = cp.zeros( - (1 + 3 * layer_ids.shape[0], cell_n, cell_n), - dtype=cp.uint32, - ) - - points_all = points_all.astype(cp.float32) - add_color_kernel_( - points_all, - R, - t, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - color_map, - size=(points_all.shape[0]*pcl_ids.shape[0]), - ) - color_average_kernel_( - color_map, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - semantic_map, - size=(cell_n * cell_n*pcl_ids.shape[0]), - ) - print(color_map) -def bayesian_inference_kernel_fct(): +@pytest.mark.parametrize( + "map_shape, points_all,pcl_ids, layer_ids", + [ + ( + (3, 4, 4), + cp.array( + [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 + ), + cp.array([3], dtype=cp.int32), + cp.array([0], dtype=cp.int32), + ), + ], +) +def test_bayesian_inference_kernel(map_shape, points_all, pcl_ids, layer_ids): # params cell_n = 4 resolution = 0.9 elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) - elevation_map[2] = 12 - semantic_map = cp.zeros((1,4, 4), dtype=cp.float32) - new_map = cp.ones((1, 4, 4), dtype=cp.float32) - pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) + elevation_map[2] = points_all.shape[0] + semantic_map = cp.zeros(map_shape, dtype=cp.float32) + new_map = cp.ones(map_shape, dtype=cp.float32) R = cp.eye(3, dtype=cp.float32) t = cp.array([0, 0, 0], dtype=cp.float32) - points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) - semantic_map = cp.zeros((1,4, 4), dtype=cp.float32) # compile kernel sum_mean = cp.ones( @@ -205,7 +192,6 @@ def bayesian_inference_kernel_fct(): ), cp.float32, ) - # TODO initialize the variance with a value different than 0 sum_compact_kernel_ = sum_compact_kernel( resolution, cell_n, @@ -215,7 +201,6 @@ def bayesian_inference_kernel_fct(): cell_n, cell_n, ) - # updatelayer sum_mean *= 0 sum_compact_kernel_( @@ -226,7 +211,7 @@ def bayesian_inference_kernel_fct(): layer_ids, cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), sum_mean, - size=(points_all.shape[0]*pcl_ids.shape[0]), + size=(points_all.shape[0] * pcl_ids.shape[0]), ) bayesian_inference_kernel_( pcl_ids, @@ -236,25 +221,35 @@ def bayesian_inference_kernel_fct(): new_map, sum_mean, semantic_map, - size=(cell_n * cell_n*pcl_ids.shape[0]), + size=(cell_n * cell_n * pcl_ids.shape[0]), ) print("semantic_map", semantic_map) -def class_average_kernel_fct(): +@pytest.mark.parametrize( + "map_shape, points_all,pcl_ids, layer_ids", + [ + ( + (4, 4, 4), + cp.array( + [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 + ), + cp.array([3, 4], dtype=cp.int32), + cp.array([1, 2], dtype=cp.int32), + ), + ], +) +def test_class_average_kernel(map_shape, points_all, pcl_ids, layer_ids): # params cell_n = 4 resolution = 0.9 average_weight = 0.5 - map_shape = (4, 4, 4) - elevation_map = cp.zeros((3,4,4), dtype=cp.float32) + elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) elevation_map[2] = 3 semantic_map = cp.zeros(map_shape, dtype=cp.float32) new_map = cp.zeros(map_shape, dtype=cp.float32) - pcl_ids, layer_ids = cp.array([3,4], dtype=cp.int32), cp.array([1,2], dtype=cp.int32) R = cp.eye(3, dtype=cp.float32) t = cp.array([0, 0, 0], dtype=cp.float32) - points_all = cp.array([[0.1, 0.1, 0.1, 0.3,0.3], [0.1, 0.1, 0.1, 0.1,0.2], [0.1, 0.1, 0.1, 0.1,0.2]], dtype=cp.float32) # compile kernel sum_kernel_ = sum_kernel( 0.9, @@ -284,7 +279,7 @@ def class_average_kernel_fct(): cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), semantic_map, new_map, - size=(points_all.shape[0]*pcl_ids.shape[0]), + size=(points_all.shape[0] * pcl_ids.shape[0]), ) print("new_map bef", new_map) print("pcl_ids.shape[0]", pcl_ids.shape[0]) @@ -295,25 +290,35 @@ def class_average_kernel_fct(): cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), elevation_map, semantic_map, - size=(cell_n * cell_n*pcl_ids.shape[0]), + size=(cell_n * cell_n * pcl_ids.shape[0]), ) print("semantic_map", semantic_map) print("new_map", new_map) -def class_bayesian_inference_fct(): + +@pytest.mark.parametrize( + "map_shape, points_all,pcl_ids, layer_ids", + [ + ( + (4, 4, 4), + cp.array( + [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 + ), + cp.array([3, 4], dtype=cp.int32), + cp.array([1, 2], dtype=cp.int32), + ), + ], +) +def test_class_bayesian_inference_fct(map_shape, points_all, pcl_ids, layer_ids): # params cell_n = 4 resolution = 0.9 - average_weight = 0.5 elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) - elevation_map[2] = 3 - semantic_map = cp.zeros((1,4, 4), dtype=cp.float32) - new_map = cp.zeros((1, 4, 4), dtype=cp.float32) - pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) + elevation_map[2] = points_all.shape[0] + semantic_map = cp.zeros(map_shape, dtype=cp.float32) + new_map = cp.zeros(map_shape, dtype=cp.float32) R = cp.eye(3, dtype=cp.float32) t = cp.array([0, 0, 0], dtype=cp.float32) - points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) - semantic_map = cp.zeros((1,4, 4), dtype=cp.float32) # compile kernel alpha_kernel_ = alpha_kernel( resolution, @@ -332,7 +337,7 @@ def class_bayesian_inference_fct(): layer_ids, cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), new_map, - size=(points_all.shape[0]*pcl_ids.shape[0]), + size=(points_all.shape[0] * pcl_ids.shape[0]), ) # calculate new thetas sum_alpha = cp.sum(new_map[layer_ids], axis=0) @@ -341,20 +346,3 @@ def class_bayesian_inference_fct(): semantic_map[layer_ids] = new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) print("semantic_map", semantic_map) print("new_map", new_map) - - - - -if __name__ == "__main__": - # average - sum_kernel_fct() - average_kernel_fct() - # color kernel - color_kernel() - # bayesian inference - bayesian_inference_kernel_fct() - # class average - class_average_kernel_fct() - # class bayesian inference - class_bayesian_inference_fct() - From 94cdbbd22ada2fc07743878451594ae1805e3a83 Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 31 Jan 2023 14:41:59 +0100 Subject: [PATCH 331/504] added docstring and moved parameters to issues --- .../elevation_mapping.py | 65 +++++++++++++- .../elevation_mapping_cupy/parameter.py | 26 ------ .../elevation_mapping_cupy/semantic_map.py | 85 ++++++++++++++++++- 3 files changed, 148 insertions(+), 28 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index f48e39ef..3d4d12d1 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -407,15 +407,26 @@ def clear_overlap_map(self, t): self.elevation_map[:, self.cell_min : self.cell_max, self.cell_min : self.cell_max] = near_map def get_additive_mean_error(self): + """Returns the additive mean error. + + Returns: + + """ return self.additive_mean_error def update_variance(self): + """Adds the time variacne to the valid cells. + """ self.elevation_map[1] += self.param.time_variance * self.elevation_map[2] def update_time(self): + """adds the time interval to the time layer. + """ self.elevation_map[4] += self.param.time_interval def update_upper_bound_with_valid_elevation(self): + """Filters all invalid cell's upper_bound and is_upper_bound layers. + """ mask = self.elevation_map[2] > 0.5 self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) @@ -559,12 +570,28 @@ def process_map_for_publish(self, input_map, fill_nan=False, add_z=False, xp=cp) return m[1:-1, 1:-1] def get_elevation(self): + """Get the elevation layer. + + Returns: + elevation layer + + """ return self.process_map_for_publish(self.elevation_map[0], fill_nan=True, add_z=True) def get_variance(self): + """Get the variance layer. + + Returns: + variance layer + """ return self.process_map_for_publish(self.elevation_map[1], fill_nan=False, add_z=False) def get_traversability(self): + """Get the traversability layer. + + Returns: + traversability layer + """ traversability = cp.where( (self.elevation_map[2] + self.elevation_map[6]) > 0.5, self.elevation_map[3].copy(), @@ -575,9 +602,19 @@ def get_traversability(self): return traversability def get_time(self): + """Get the time layer. + + Returns: + time layer + """ return self.process_map_for_publish(self.elevation_map[4], fill_nan=False, add_z=False) def get_upper_bound(self): + """Get the upper bound layer. + + Returns: + upper_bound: upper bound layer + """ if self.param.use_only_above_for_upper_bound: valid = cp.logical_or( cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), @@ -590,6 +627,11 @@ def get_upper_bound(self): return upper_bound def get_is_upper_bound(self): + """Get the is upper bound layer. + + Returns: + is_upper_bound: layer + """ if self.param.use_only_above_for_upper_bound: valid = cp.logical_or( cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), @@ -608,7 +650,7 @@ def xp_of_array(self, array): array (cupy._core.core.ndarray): Returns: - module: + module: either np or cp """ if type(array) == cp.ndarray: return cp @@ -705,6 +747,11 @@ def get_map_with_name_ref(self, name, data): self.copy_to_cpu(m, data, stream=stream) def get_normal_maps(self): + """Get the normal maps. + + Returns: + maps: the three normal values for each cell + """ normal = self.normal_map.copy() normal_x = normal[0, 1:-1, 1:-1] normal_y = normal[1, 1:-1, 1:-1] @@ -716,6 +763,13 @@ def get_normal_maps(self): return maps def get_normal_ref(self, normal_x_data, normal_y_data, normal_z_data): + """Get the normal maps as reference. + + Args: + normal_x_data: + normal_y_data: + normal_z_data: + """ maps = self.get_normal_maps() self.stream = cp.cuda.Stream(non_blocking=True) normal_x_data[...] = xp.asnumpy(maps[0], stream=self.stream) @@ -723,6 +777,15 @@ def get_normal_ref(self, normal_x_data, normal_y_data, normal_z_data): normal_z_data[...] = xp.asnumpy(maps[2], stream=self.stream) def get_layer(self, name): + """Return the layer with the name input. + + Args: + name: The layers name. + + Returns: + return_map: The rqeuested layer. + + """ if name in self.layer_names: idx = self.layer_names.index(name) return_map = self.elevation_map[idx] diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 6ef6daf6..165395ff 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -9,34 +9,8 @@ from dataclasses import field -# todo add these dataclasses -@dataclass -class Subscriber(Serializable): - channels: list = field(default_factory=lambda: ["feat_0"]) - fusion: list = field(default_factory=lambda: ["average"]) - topic_name: str = "/elevation_mapping/pointcloud_semantic" - cam_frame: str = "zed2i_right_camera_optical_frame" - cam_info_topic: str = "/zed2i/zed_node/depth/camera_info" - confidence: bool = True - confidence_threshold: int = 10 - confidence_topic: str = "/zed2i/zed_node/confidence/confidence_map" - depth_topic: str = "/zed2i/zed_node/depth/depth_registered" - feature_extractor: bool = False - image_topic: str = "/zed2i/zed_node/left/image_rect_color" - segmentation_model: str = "lraspp_mobilenet_v3_large" - semantic_segmentation: bool = True - show_label_legend: bool = True - data_type: str = "pointcloud" - - -@dataclass -class Subscribers(Serializable): - front_cam: Subscriber = Subscriber - - @dataclass class Parameter(Serializable): - # todo: fix subscriber resolution: float = 0.04 subscriber_cfg: dict = field( default_factory=lambda: { diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index d5dec269..133c209b 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -63,6 +63,9 @@ def __init__(self, param: Parameter): self.delete_new_layers = cp.ones(self.new_map.shape[0], cp.bool8) def clear(self): + """Clear the semantic map. + + """ self.semantic_map *= 0.0 def compile_kernels(self) -> None: @@ -192,6 +195,11 @@ def pad_value(self, x, shift_value, idx=None, value=0.0): x[idx, :, shift_value[1] :] = value def shift_map_xy(self, shift_value): + """Shift the map along x,y-axis according to shift values. + + Args: + shift_value: + """ self.semantic_map = cp.roll(self.semantic_map, shift_value, axis=(1, 2)) self.pad_value(self.semantic_map, shift_value, value=0.0) self.new_map = cp.roll(self.new_map, shift_value, axis=(1, 2)) @@ -201,7 +209,7 @@ def shift_map_xy(self, shift_value): self.pad_value(el, shift_value, value=0.0) def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: - """Get all fusion algorithms that need to be applied to a specific pointcloud + """Get all fusion algorithms that need to be applied to a specific pointcloud. Args: channels (List[str]): @@ -214,6 +222,14 @@ def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: return fusion_list def get_layer_indices(self, fusion_alg): + """Get the indices of the layers that are used for a specific fusion algorithm. + + Args: + fusion_alg(str): fusion algorithm name + + Returns: + cp.array: indices of the layers + """ layer_indices = cp.array([], dtype=cp.int32) for it, (key, val) in enumerate(self.layer_specs.items()): if key in val == fusion_alg: @@ -247,6 +263,15 @@ def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): return pcl_indices, layer_indices def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): + """Update the semantic map with the pointcloud. + + Args: + points_all: semantic point cloud + channels: list of channel names + R: rotation matrix + t: translation vector + elevation_map: elevation map object + """ additional_fusion = self.get_fusion_of_pcl(channels) self.new_map[self.delete_new_layers] = 0.0 if "average" in additional_fusion: @@ -424,7 +449,16 @@ def update_layers_image( image_height: cp._core.core.ndarray, image_width: cp._core.core.ndarray, ): + """Update the semantic map with the new image. + Args: + sub_key: + image: + uv_correspondence: + valid_correspondence: + image_height: + image_width: + """ self.new_map *= 0 config = self.param.subscriber_cfg[sub_key] @@ -463,6 +497,15 @@ def update_layers_image( raise ValueError("Fusion for image is unknown.") def decode_max(self, mer): + """Decode the float32 value into two 16 bit value containing the class probability and the class id. + + Args: + mer: + + Returns: + cp.array: probability + cp.array: class id + """ mer = mer.astype(cp.float32) mer = mer.view(dtype=cp.uint32) ma = cp.bitwise_and(mer, 0xFFFF, dtype=np.uint16) @@ -472,6 +515,14 @@ def decode_max(self, mer): return ma, ind def get_map_with_name(self, name): + """Return the map with the given name. + + Args: + name: layer name + + Returns: + cp.array: map + """ if self.layer_specs[name] == "color": m = self.get_rgb(name) return m @@ -480,19 +531,51 @@ def get_map_with_name(self, name): return m def get_rgb(self, name): + """Return the rgb map with the given name. + + Args: + name: + + Returns: + cp.array: rgb map + """ idx = self.layer_names.index(name) c = self.process_map_for_publish(self.semantic_map[idx]) c = c.astype(np.float32) return c def get_semantic(self, name): + """Return the semantic map layer with the given name. + + Args: + name(str): layer name + + Returns: + cp.array: semantic map layer + """ idx = self.layer_names.index(name) c = self.process_map_for_publish(self.semantic_map[idx]) return c def process_map_for_publish(self, input_map): + """Remove padding. + + Args: + input_map(cp.array): map layer + + Returns: + cp.array: map layer without padding + """ m = input_map.copy() return m[1:-1, 1:-1] def get_index(self, name): + """Return the index of the layer with the given name. + + Args: + name(str): + + Returns: + int: index + """ return self.layer_names.index(name) From 2b2a4d55aa299671ebb65b39c3f4d96098c7726c Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 31 Jan 2023 16:43:41 +0100 Subject: [PATCH 332/504] added heap config --- .../config/heap_parameters.yaml | 94 +++ .../config/heap_plugin_config.yaml | 61 ++ .../config/heap_sensor_parameter.yaml | 31 + .../launch/heap_launch.launch | 18 + elevation_mapping_cupy/rviz/heap.rviz | 600 ++++++++++++++++++ 5 files changed, 804 insertions(+) create mode 100644 elevation_mapping_cupy/config/heap_parameters.yaml create mode 100644 elevation_mapping_cupy/config/heap_plugin_config.yaml create mode 100644 elevation_mapping_cupy/config/heap_sensor_parameter.yaml create mode 100644 elevation_mapping_cupy/launch/heap_launch.launch create mode 100644 elevation_mapping_cupy/rviz/heap.rviz diff --git a/elevation_mapping_cupy/config/heap_parameters.yaml b/elevation_mapping_cupy/config/heap_parameters.yaml new file mode 100644 index 00000000..064e1bb4 --- /dev/null +++ b/elevation_mapping_cupy/config/heap_parameters.yaml @@ -0,0 +1,94 @@ +#### Basic parameters ######## +resolution: 0.04 # resolution in m. +map_length: 20.0 # map's size in m. +sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). +mahalanobis_thresh: 2.0 # points outside this distance is outlier. +outlier_variance: 0.01 # if point is outlier, add this value to the cell. +drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. +max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) +drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation +time_variance: 0.0001 # add this value when update_variance is called. +max_variance: 100.0 # maximum variance for each cell. +initial_variance: 1000.0 # initial variance for each cell. +traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. +dilation_size: 3 # dilation filter size before traversability filter. +wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. +min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. +position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. +orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. +position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. +orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. +min_valid_distance: 0.5 # points with shorter distance will be filtered out. +max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. +ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +update_variance_fps: 5.0 # fps for updating variance. +update_pose_fps: 10.0 # fps for updating pose and shift the center of map. +time_interval: 0.1 # Time layer is updated with this interval. +map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. +publish_statistics_fps: 1.0 # Publish statistics topic in this fps. + +max_ray_length: 10.0 # maximum length for ray tracing. +cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. +cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + +safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. +safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. +max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + +overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) +overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + +map_frame: 'map' # The map frame where the odometry source uses. +base_frame: 'BASE' # The robot's base frame. This frame will be a center of the map. +corrected_map_frame: 'map' + +#### Feature toggles ######## +enable_edge_sharpen: true +enable_visibility_cleanup: true +enable_drift_compensation: true +enable_overlap_clearance: false +enable_pointcloud_publishing: false +enable_drift_corrected_TF_publishing: false +enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + +#### Traversability filter ######## +use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. +weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter + +#### Upper bound ######## +use_only_above_for_upper_bound: false + +#### Plugins ######## +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/heap_plugin_config.yaml' + +#### Subscribers ######## + + +#### Publishers ######## +# topic_name: +# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names +# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. +# fps: # Publish rate. Use smaller value than `map_acquire_fps`. +publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance'] + basic_layers: ['elevation', 'traversability'] + fps: 5.0 +# elevation_map_recordable: +# layers: ['elevation', 'traversability'] +# basic_layers: ['elevation', 'traversability'] +# fps: 2.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb_image','sem_fil'] + basic_layers: ['min_filter'] + fps: 3.0 + +#### Initializer ######## +initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' +initialize_frame_id: ['RH_WHEEL_CONTACT','RF_WHEEL_CONTACT','LH_WHEEL_CONTACT','LF_WHEEL_CONTACT'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. +dilation_size_initialize: 5 # dilation size after the init. +initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. +use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/heap_plugin_config.yaml b/elevation_mapping_cupy/config/heap_plugin_config.yaml new file mode 100644 index 00000000..e18df155 --- /dev/null +++ b/elevation_mapping_cupy/config/heap_plugin_config.yaml @@ -0,0 +1,61 @@ +# Settings of the plugins. (The plugins should be stored in script/plugins) + +# min_filter fills in minimum value around the invalid cell. +min_filter: + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations +# Apply smoothing. +smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" +# Apply inpainting using opencv +inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns +# Apply smoothing for inpainted layer + +robot_centric_elevation: # Use the same name as your file name. +# type: "robot_centric_elevation" + enable: False # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "robot_centric_elevation" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. +# add_value: 2.0 # Example param + resolution: 0.04 + threshold: 1.1 + use_threshold: True + +semantic_filter: + type: "semantic_filter" + enable: False + fill_nan: False + is_height_layer: False + layer_name: "sem_fil" + extra_params: + classes: ['grass','tree','fence','dirt'] + +semantic_traversability: + type: "semantic_traversability" + enable: False + fill_nan: False + is_height_layer: False + layer_name: "sem_traversability" + extra_params: + layers: ['traversability','robot_centric_elevation'] + thresholds: [0.3,0.5] + type: ['traversability', 'elevation'] + diff --git a/elevation_mapping_cupy/config/heap_sensor_parameter.yaml b/elevation_mapping_cupy/config/heap_sensor_parameter.yaml new file mode 100644 index 00000000..a0478682 --- /dev/null +++ b/elevation_mapping_cupy/config/heap_sensor_parameter.yaml @@ -0,0 +1,31 @@ +subscribers: + + front_cam: + channels: [] + fusion: [] + topic_name: '/ouster_points_self_filtered' + data_type: pointcloud + +# camera_right_rgb: +# fusion: ['image_color'] +# topic_name_camera: /camUSBRightView/Downsampled +# topic_name_camera_info: /camera_info +# channels: ["rgb_image"] +# data_type: image + + camera_main_rgb: + fusion: ['image_color'] + topic_name_camera: /camMainView/Downsampled + topic_name_camera_info: /camera_info + channels: ["rgb_image"] + data_type: image + + +# camera_cnn: +# topic_name_camera: /src/image +# topic_name_camera_info: /camera_info +# channels: ["mono"] +# fusion: [ 'image_exponential' ] +# data_type: image + + diff --git a/elevation_mapping_cupy/launch/heap_launch.launch b/elevation_mapping_cupy/launch/heap_launch.launch new file mode 100644 index 00000000..c700bbda --- /dev/null +++ b/elevation_mapping_cupy/launch/heap_launch.launch @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/elevation_mapping_cupy/rviz/heap.rviz b/elevation_mapping_cupy/rviz/heap.rviz new file mode 100644 index 00000000..268b264f --- /dev/null +++ b/elevation_mapping_cupy/rviz/heap.rviz @@ -0,0 +1,600 @@ +Panels: + - Class: rviz/Displays + Help Height: 78 + Name: Displays + Property Tree Widget: + Expanded: ~ + Splitter Ratio: 0.5 + Tree Height: 288 + - Class: rviz/Selection + Name: Selection + - Class: rviz/Tool Properties + Expanded: + - /2D Pose Estimate1 + - /2D Nav Goal1 + - /Publish Point1 + - /Interact1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.4944238066673279 + - Class: rviz/Time + Experimental: false + Name: Time + SyncMode: 0 + SyncSource: Image +Preferences: + PromptSaveOnExit: true +Toolbars: + toolButtonStyle: 2 +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz/Grid + Color: 160; 160; 164 + Enabled: false + Line Style: + Line Width: 0.029999999329447746 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: false + - Class: rviz/Image + Enabled: true + Image Topic: /camUSBRightView/Downsampled + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Queue Size: 2 + Transport Hint: raw + Unreliable: false + Value: true + - Class: rviz/TF + Enabled: true + Frame Timeout: 15 + Frames: + All Enabled: true + BASE: + Value: true + BASE_inertia: + Value: true + BOOM: + Value: true + CABIN: + Value: true + DIPPER: + Value: true + ENDEFFECTOR: + Value: true + ENDEFFECTOR_CONTACT: + Value: true + GNSS_L: + Value: true + GNSS_R: + Value: true + IMU_base_link: + Value: true + IMU_link: + Value: true + LF_BEAM: + Value: true + LF_BEARING: + Value: true + LF_KNUCKLE: + Value: true + LF_PARALLEL: + Value: true + LF_SWIVEL: + Value: true + LF_WHEEL: + Value: true + LF_WHEEL_CONTACT: + Value: true + LH_BEAM: + Value: true + LH_KNUCKLE: + Value: true + LH_OUTRIGGER: + Value: true + LH_ROTATOR: + Value: true + LH_WHEEL: + Value: true + LH_WHEEL_CONTACT: + Value: true + RF_BEAM: + Value: true + RF_BEARING: + Value: true + RF_KNUCKLE: + Value: true + RF_PARALLEL: + Value: true + RF_SWIVEL: + Value: true + RF_WHEEL: + Value: true + RF_WHEEL_CONTACT: + Value: true + RH_BEAM: + Value: true + RH_KNUCKLE: + Value: true + RH_OUTRIGGER: + Value: true + RH_ROTATOR: + Value: true + RH_WHEEL: + Value: true + RH_WHEEL_CONTACT: + Value: true + ROTO: + Value: true + ROTO_BASE: + Value: true + SHOVEL: + Value: true + TELE: + Value: true + camMainView: + Value: true + compslam_lio/aft_mapped: + Value: true + compslam_lio/aft_mapped_to_init_CORRECTED: + Value: true + compslam_lio/camera: + Value: true + compslam_lio/camera_CORRECTED: + Value: true + compslam_lio/camera_init: + Value: true + compslam_lio/camera_init_CORRECTED: + Value: true + compslam_lio/camera_init_GRAVITY_ALIGNED: + Value: true + compslam_lio/laser_odom: + Value: true + compslam_lio/laser_odom_CORRECTED: + Value: true + imu_box_base_link: + Value: true + imu_box_link: + Value: true + livox_frame: + Value: true + map: + Value: true + odom: + Value: true + os_imu: + Value: true + os_lidar: + Value: true + os_sensor: + Value: true + roof_top_box: + Value: true + Marker Alpha: 1 + Marker Scale: 1 + Name: TF + Show Arrows: true + Show Axes: true + Show Names: true + Tree: + map: + compslam_lio/camera_init_CORRECTED: + compslam_lio/aft_mapped_to_init_CORRECTED: + {} + compslam_lio/camera_CORRECTED: + {} + compslam_lio/camera_init: + compslam_lio/aft_mapped: + {} + compslam_lio/camera: + {} + compslam_lio/laser_odom: + {} + compslam_lio/camera_init_GRAVITY_ALIGNED: + {} + compslam_lio/laser_odom_CORRECTED: + {} + odom: + BASE: + BASE_inertia: + {} + CABIN: + BOOM: + DIPPER: + TELE: + ROTO_BASE: + ROTO: + ENDEFFECTOR: + SHOVEL: + ENDEFFECTOR_CONTACT: + {} + GNSS_L: + {} + GNSS_R: + {} + camMainView: + livox_frame: + {} + os_sensor: + os_imu: + {} + os_lidar: + {} + roof_top_box: + imu_box_base_link: + imu_box_link: + {} + IMU_base_link: + IMU_link: + {} + LF_SWIVEL: + LF_BEAM: + LF_BEARING: + LF_KNUCKLE: + LF_WHEEL: + LF_WHEEL_CONTACT: + {} + LF_PARALLEL: + {} + LH_ROTATOR: + LH_BEAM: + LH_KNUCKLE: + LH_OUTRIGGER: + {} + LH_WHEEL: + LH_WHEEL_CONTACT: + {} + RF_SWIVEL: + RF_BEAM: + RF_BEARING: + RF_KNUCKLE: + RF_WHEEL: + RF_WHEEL_CONTACT: + {} + RF_PARALLEL: + {} + RH_ROTATOR: + RH_BEAM: + RH_KNUCKLE: + RH_OUTRIGGER: + {} + RH_WHEEL: + RH_WHEEL_CONTACT: + {} + Update Interval: 0 + Value: true + - Class: rviz/Image + Enabled: true + Image Topic: /camMainView/Downsampled + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Queue Size: 2 + Transport Hint: raw + Unreliable: false + Value: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: rgb_image + Color Transformer: ColorLayer + ColorMap: default + Enabled: true + Grid Cell Decimation: 1 + Grid Line Thickness: 0.10000000149011612 + Height Layer: smooth + Height Transformer: GridMapLayer + History Length: 1 + Invert ColorMap: false + Max Color: 255; 255; 255 + Max Intensity: 10 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: GridMap + Show Grid Lines: true + Topic: /elevation_mapping/elevation_map_filter + Unreliable: false + Use ColorMap: true + Value: true + - Alpha: 1 + Class: rviz/RobotModel + Collision Enabled: false + Enabled: true + Links: + All Links Enabled: true + BASE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + BASE_inertia: + Alpha: 1 + Show Axes: false + Show Trail: false + BOOM: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + CABIN: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + DIPPER: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + ENDEFFECTOR: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + ENDEFFECTOR_CONTACT: + Alpha: 1 + Show Axes: false + Show Trail: false + Expand Joint Details: false + Expand Link Details: false + Expand Tree: false + GNSS_L: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + GNSS_R: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + IMU_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + IMU_link: + Alpha: 1 + Show Axes: false + Show Trail: false + LF_BEAM: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LF_BEARING: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LF_KNUCKLE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LF_PARALLEL: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LF_SWIVEL: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LF_WHEEL: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LF_WHEEL_CONTACT: + Alpha: 1 + Show Axes: false + Show Trail: false + LH_BEAM: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LH_KNUCKLE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LH_OUTRIGGER: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LH_ROTATOR: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LH_WHEEL: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + LH_WHEEL_CONTACT: + Alpha: 1 + Show Axes: false + Show Trail: false + Link Tree Style: Links in Alphabetic Order + RF_BEAM: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RF_BEARING: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RF_KNUCKLE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RF_PARALLEL: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RF_SWIVEL: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RF_WHEEL: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RF_WHEEL_CONTACT: + Alpha: 1 + Show Axes: false + Show Trail: false + RH_BEAM: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RH_KNUCKLE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RH_OUTRIGGER: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RH_ROTATOR: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RH_WHEEL: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + RH_WHEEL_CONTACT: + Alpha: 1 + Show Axes: false + Show Trail: false + ROTO: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + ROTO_BASE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + SHOVEL: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + TELE: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + Name: RobotModel + Robot Description: mm_description + TF Prefix: "" + Update Interval: 0 + Value: true + Visual Enabled: true + Enabled: true + Global Options: + Background Color: 255; 255; 255 + Default Light: true + Fixed Frame: map + Frame Rate: 30 + Name: root + Tools: + - Class: rviz/Select + - Class: rviz/SetInitialPose + Theta std deviation: 0.2617993950843811 + Topic: /initialpose + X std deviation: 0.5 + Y std deviation: 0.5 + - Class: rviz/SetGoal + Topic: /move_base_simple/goal + - Class: rviz/PublishPoint + Single click: true + Topic: /clicked_point + - Class: rviz/MoveCamera + - Class: rviz/FocusCamera + - Class: rviz/Interact + Hide Inactive Objects: true + Value: true + Views: + Current: + Class: rviz/Orbit + Distance: 27.363513946533203 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Field of View: 1 + Focal Point: + X: 4.949670314788818 + Y: 8.161603927612305 + Z: -4.364292144775391 + Focal Shape Fixed Size: false + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 0.7703982591629028 + Target Frame: + Yaw: 2.9804012775421143 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 1016 + Hide Left Dock: false + Hide Right Dock: false + Image: + collapsed: false + QMainWindow State: 000000ff00000000fd0000000400000000000001560000035afc020000000afb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000001ab000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d00610067006501000001ee0000012f0000001600fffffffb0000000a0049006d0061006700650100000323000000740000001600ffffff000000010000010f0000035afc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d0000035a000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007380000003efc0100000002fb0000000800540069006d0065010000000000000738000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000004c70000035a00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: false + Width: 1848 + X: 72 + Y: 27 From 563ba2f4d205f0fca53ae7e9bee6f6d2c9d6d03b Mon Sep 17 00:00:00 2001 From: Gian Date: Wed, 1 Feb 2023 11:04:15 +0100 Subject: [PATCH 333/504] added sem seg --- .../plugins/semantic_filter.py | 2 +- .../semantic_segmentation_node.py | 197 ++++++++++++++++++ .../semantic_segmentation_parameters.py | 33 +++ 3 files changed, 231 insertions(+), 1 deletion(-) create mode 100755 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_node.py create mode 100644 sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_parameters.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index 5ea2cc07..0eccf639 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -83,7 +83,7 @@ def __call__( layer_indices = cp.array([], dtype=cp.int32) max_idcs = cp.array([], dtype=cp.int32) for it, fusion_alg in enumerate(semantic_map.param.fusion_algorithms): - if fusion_alg in ["class_bayesian", "class_average"]: + if fusion_alg in ["class_bayesian", "class_average", "image_exponential"]: layer_indices = cp.append(layer_indices, it).astype(cp.int32) # we care only for the first max in the display if fusion_alg in ["class_max"] and len(max_idcs) < 1: diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_node.py new file mode 100755 index 00000000..028eb05d --- /dev/null +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_node.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python + +import rospy +import sys + +import numpy as np +import cupy as cp +import ros_numpy +import matplotlib.pyplot as plt +from skimage.io import imshow + +import message_filters +from sensor_msgs.msg import Image, CameraInfo +from sensor_msgs.msg import PointCloud2, Image +from cv_bridge import CvBridge + +from semantic_pointcloud.semantic_segmentation_parameters import SemanticSegmentationParameter +from semantic_pointcloud.networks import resolve_model +from semantic_pointcloud.utils import decode_max + + +class SemanticSegmentationNode: + def __init__(self, sensor_name): + """Get parameter from server, initialize variables and semantics, register publishers and subscribers. + + Args: + sensor_name (str): Name of the sensor in the ros param server. + """ + # TODO: if this is going to be loaded from another package we might need to change namespace + self.param: SemanticSegmentationParameter = SemanticSegmentationParameter() + self.param.feature_config.input_size = [80, 160] + namesp = rospy.get_name() + if rospy.has_param(namesp + "/subscribers"): + config = rospy.get_param(namesp + "/subscribers") + self.param: SemanticSegmentationParameter = SemanticSegmentationParameter.from_dict(config[sensor_name]) + else: + print("NO ROS ENV found.") + + print("--------------Pointcloud Parameters-------------------") + print(self.param.dumps_yaml()) + print("--------------End of Parameters-----------------------") + self.semseg_color_map = None + # setup custom dtype + # setup semantics + self.feature_extractor = None + self.semantic_model = None + self.initialize_semantics() + + # setup pointcloud creation + self.cv_bridge = CvBridge() + self.P = None + self.header = None + self.register_sub_pub() + self.prediction_img = None + + def initialize_semantics(self): + if self.param.semantic_segmentation: + self.semantic_model = resolve_model(self.param.segmentation_model, self.param) + + if self.param.feature_extractor: + self.feature_extractor = resolve_model(self.param.feature_config.name, self.param.feature_config) + + def register_sub_pub(self): + """Register publishers and subscribers.""" + # subscribers + rospy.Subscriber(self.param.image_topic, Image, self.image_callback) + + # publishers + if self.param.semantic_segmentation: + self.seg_pub = rospy.Publisher(self.param.sem_seg_topic, Image, queue_size=2) + self.seg_im_pub = rospy.Publisher(self.param.sem_seg_image_topic, Image, queue_size=2) + self.semseg_color_map = self.color_map(len(self.param.channels)) + if self.param.show_label_legend: + self.color_map_viz() + if self.param.feature_extractor: + self.feature_pub = rospy.Publisher(self.param.feature_topic, Image, queue_size=2) + + def color_map(self, N=256, normalized=False): + """Create a color map for the class labels. + + Args: + N (int): + normalized (bool): + """ + + def bitget(byteval, idx): + return (byteval & (1 << idx)) != 0 + + dtype = "float32" if normalized else "uint8" + cmap = np.zeros((N + 1, 3), dtype=dtype) + for i in range(N + 1): + r = g = b = 0 + c = i + for j in range(8): + r = r | (bitget(c, 0) << 7 - j) + g = g | (bitget(c, 1) << 7 - j) + b = b | (bitget(c, 2) << 7 - j) + c = c >> 3 + + cmap[i] = np.array([r, g, b]) + + cmap = cmap / 255 if normalized else cmap + return cmap[1:] + + def color_map_viz(self): + """Display the color map of the classes.""" + nclasses = len(self.param.channels) + row_size = 50 + col_size = 500 + if self.param.semantic_segmentation: + cmap = self.semseg_color_map + array = np.empty((row_size * (nclasses), col_size, cmap.shape[1]), dtype=cmap.dtype) + for i in range(nclasses): + array[i * row_size : i * row_size + row_size, :] = cmap[i] + imshow(array) + plt.yticks([row_size * i + row_size / 2 for i in range(nclasses)], self.param.channels) + plt.xticks([]) + plt.show() + + def image_callback(self, rgb_msg): + image = cp.asarray(self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8")) + self.header = rgb_msg.header + self.process_image(image) + + if self.param.semantic_segmentation: + self.publish_segmentation() + self.publish_segmentation_image() + # if self.param.feature_extractor: + # self.publish_feature_image() + + def process_image(self, image): + """Depending on setting generate color, semantic segmentation or feature channels. + + Args: + image: + u: + v: + points: + """ + + if self.param.semantic_segmentation: + self.sem_seg = self.semantic_model["model"](image) + + # if self.feature_channels is not None: + # prediction = self.feature_extractor["model"](image) + + def publish_segmentation(self): + probabilities = self.sem_seg + img = probabilities.get() + img = np.transpose(img, (1, 2, 0)).astype(np.float32) + seg_msg = self.cv_bridge.cv2_to_imgmsg(img, encoding="passthrough") + seg_msg.header.frame_id = self.header.frame_id + seg_msg.header.stamp = self.header.stamp + self.seg_pub.publish(seg_msg) + + def publish_segmentation_image(self): + colors = None + probabilities = self.sem_seg + if self.param.semantic_segmentation: + colors = cp.asarray(self.semseg_color_map) + assert colors.ndim == 2 and colors.shape[1] == 3 + + # prob = cp.zeros((len(self.param.channels),) + probabilities.shape[1:]) + # if "class_max" in self.param.fusion: + # # decode, create an array with all possible classes and insert probabilities + # it = 0 + # for iit, (chan, fuse) in enumerate(zip(self.param.channels, self.param.fusion)): + # if fuse in ["class_max"]: + # temp = probabilities[it] + # temp_p, temp_i = decode_max(temp) + # temp_i.choose(prob) + # c = cp.mgrid[0 : temp_i.shape[0], 0 : temp_i.shape[1]] + # prob[temp_i, c[0], c[1]] = temp_p + # it += 1 + # elif fuse in ["class_bayesian", "class_average"]: + # # assign fixed probability to correct index + # if chan in self.semantic_model["model"].segmentation_channels: + # prob[self.semantic_model["model"].segmentation_channels[chan]] = probabilities[it] + # it += 1 + # img = cp.argmax(prob, axis=0) + # + # else: + img = cp.argmax(probabilities, axis=0) + img = colors[img].astype(cp.uint8) # N x H x W x 3 + img = img.get() + seg_msg = self.cv_bridge.cv2_to_imgmsg(img, encoding="rgb8") + seg_msg.header.frame_id = self.header.frame_id + seg_msg.header.stamp = self.header.stamp + self.seg_im_pub.publish(seg_msg) + + +if __name__ == "__main__": + arg = sys.argv[1] + sensor_name = arg + rospy.init_node("semantic_segmentation_node", anonymous=True, log_level=rospy.INFO) + node = SemanticSegmentationNode(sensor_name) + rospy.spin() diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_parameters.py new file mode 100644 index 00000000..fc8aeccd --- /dev/null +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_parameters.py @@ -0,0 +1,33 @@ +from dataclasses import dataclass, field +from simple_parsing.helpers import Serializable + + +@dataclass +class FeatureExtractorParameter(Serializable): + name: str = "DINO" + interpolation: str = "bilinear" + model: str = "vit_small" + patch_size: int = 16 + dim: int = 5 + dropout: bool = False + dino_feat_type: str = "feat" + projection_type: str = "nonlinear" + input_size: list = field(default_factory=lambda: [80, 160]) + + +@dataclass +class SemanticSegmentationParameter(Serializable): + image_topic: str = "/alphasense_driver_ros/cam4/debayered" + + semantic_segmentation: bool = True + sem_seg_topic: str = "/elevation_mapping/semantic_seg" + sem_seg_image_topic: str = "/elevation_mapping/semantic_seg_im" + segmentation_model: str = "detectron_coco_panoptic_fpn_R_101_3x" + show_label_legend: bool = False + channels: list = field(default_factory=lambda: ["grass", "road", "tree", "sky"]) + fusion: list = field(default_factory=lambda: ["class_average", "class_average", "class_average", "class_average"]) + + feature_extractor: bool = False + feature_config: FeatureExtractorParameter = FeatureExtractorParameter + # feature_config.input_size: list = field(default_factory=lambda: [80, 160]) + feature_topic: str = "/elevation_mapping/semantic_seg_feat" From be154147ffaa4a96a7b0c9557698e14b0032b93a Mon Sep 17 00:00:00 2001 From: Gian Date: Fri, 3 Feb 2023 18:05:30 +0100 Subject: [PATCH 334/504] not working pca has some weird stuff --- .../plugins/features_pca.py | 78 +++++++++++++++++++ .../elevation_mapping_cupy/semantic_map.py | 4 +- .../semantic_pointcloud/pointcloud_node.py | 33 +++++++- .../pointcloud_parameters.py | 1 + 4 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py new file mode 100644 index 00000000..69b246b5 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py @@ -0,0 +1,78 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +from typing import List + +from elevation_mapping_cupy.plugins.plugin_manager import PluginBase +from sklearn.decomposition import PCA + + +class FeaturesPca(PluginBase): + def __init__( + self, + cell_n: int = 100, + **kwargs, + ): + """This is a filter to create a pca layer of the semantic features in the map. + + Args: + cell_n (int): width and height of the elevation map. + classes (ruamel.yaml.comments.CommentedSeq): + **kwargs (): + """ + super().__init__() + self.indices = [] + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map, + *args, + ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): + *args (): + + Returns: + cupy._core.core.ndarray: + """ + # get indices of all layers that contain semantic features information + layer_indices = cp.array([], dtype=cp.int32) + for it, fusion_alg in enumerate(semantic_map.param.fusion_algorithms): + if fusion_alg in ["average", "bayesian_inference"]: + layer_indices = cp.append(layer_indices, it).astype(cp.int32) + + n_c = semantic_map.semantic_map[layer_indices].shape[1] + comp_img = np.zeros((n_c, n_c, 3), dtype=np.float32) + # check which has the highest value + if len(layer_indices) > 0: + data = cp.reshape(semantic_map.semantic_map[layer_indices], (len(layer_indices), -1)).T.get() + n_components = 3 + pca = PCA(n_components=n_components).fit(data) + pca_descriptors = pca.transform(data) + img_pca = pca_descriptors.reshape(n_c, n_c, n_components) + comp = img_pca # [:, :, -3:] + var = comp.std(axis=(0, 1)) + comp_min = comp.min(axis=(0, 1)) + comp_max = comp.max(axis=(0, 1)) + if (comp_max - comp_min).any() != 0: + comp_img = np.divide((comp - comp_min), (comp_max - comp_min)) + map = (comp_img * 255).astype(np.uint8) + r = np.asarray(map[:, :, 0], dtype=np.uint32) + g = np.asarray(map[:, :, 1], dtype=np.uint32) + b = np.asarray(map[:, :, 2], dtype=np.uint32) + rgb_arr = np.array((r << 16) | (g << 8) | (b << 0), dtype=np.uint32) + rgb_arr.dtype = np.float32 + return cp.asarray(rgb_arr) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 133c209b..1f858509 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -285,7 +285,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), self.semantic_map, self.new_map, - size=(points_all.shape[0]), + size=(points_all.shape[0]*pcl_ids.shape[0]), ) self.average_kernel( self.new_map, @@ -294,7 +294,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), elevation_map, self.semantic_map, - size=(self.param.cell_n * self.param.cell_n), + size=(self.param.cell_n * self.param.cell_n*pcl_ids.shape[0]), ) if "bayesian_inference" in additional_fusion: pcl_ids, layer_ids = self.get_indices_fusion(channels, "bayesian_inference") diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index 42ad5085..8b2e0c10 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -15,6 +15,7 @@ from semantic_pointcloud.pointcloud_parameters import PointcloudParameter from semantic_pointcloud.networks import resolve_model from semantic_pointcloud.utils import decode_max +from sklearn.decomposition import PCA class PointcloudNode: @@ -53,6 +54,8 @@ def __init__(self, sensor_name): self.header = None self.register_sub_pub() self.prediction_img = None + self.feat_img = None + def initialize_semantics(self): """Resolve the feature and segmentation mode and create segmentation_channel and feature_channels. @@ -115,6 +118,10 @@ def register_sub_pub(self): self.semseg_color_map = self.color_map(len(self.labels)) if self.param.show_label_legend: self.color_map_viz() + if self.param.feature_extractor: + # todo + if True: + self.feat_pub = rospy.Publisher(self.param.feature_config.feature_image_topic, Image, queue_size=2) def color_map(self, N=256, normalized=False): """Create a color map for the class labels. @@ -196,9 +203,13 @@ def image_callback(self, depth_msg, rgb_msg=None,confidence_msg=None): confidence = cp.asarray(self.cv_bridge.imgmsg_to_cv2(confidence_msg, desired_encoding="passthrough")) pcl = self.create_pcl_from_image(image, depth, confidence) + self.publish_pointcloud(pcl, depth_msg.header) + if self.param.publish_segmentation_image: self.publish_segmentation_image(self.prediction_img) - self.publish_pointcloud(pcl, depth_msg.header) + # todo + if False and self.param.feature_extractor: + self.publish_feature_image(self.feat_img) def create_pcl_from_image(self, image, depth, confidence): """Generate the pointcloud from the depth map and process the image. @@ -300,7 +311,9 @@ def extract_features(self, image, points, u, v): values = prediction[:, v.get(), u.get()].cpu().detach().numpy() for it, channel in enumerate(self.feature_channels.keys()): points[channel] = values[it] - + # todo + if False and self.param.feature_extractor: + self.feat_img = prediction def publish_segmentation_image(self, probabilities): if self.param.semantic_segmentation: colors = cp.asarray(self.semseg_color_map) @@ -334,6 +347,22 @@ def publish_segmentation_image(self, probabilities): seg_msg.header.frame_id = self.header.frame_id self.seg_pub.publish(seg_msg) + def publish_feature_image(self, features): + data = np.reshape(features.cpu().detach().numpy(), (features.shape[0], -1)).T + n_components = 3 + pca = PCA(n_components=n_components).fit(data) + pca_descriptors = pca.transform(data) + img_pca = pca_descriptors.reshape(features.shape[1], features.shape[2], n_components) + comp = img_pca #[:, :, -3:] + comp_min = comp.min(axis=(0, 1)) + comp_max = comp.max(axis=(0, 1)) + comp_img = (comp - comp_min) / (comp_max - comp_min) + comp_img = (comp_img * 255).astype(np.uint8) + feat_msg = self.cv_bridge.cv2_to_imgmsg(comp_img, encoding="passthrough") + feat_msg.header.frame_id = self.header.frame_id + self.feat_pub.publish(feat_msg) + + def publish_pointcloud(self, pcl, header): pc2 = ros_numpy.msgify(PointCloud2, pcl) pc2.header = header diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py index d7448181..9a329e19 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py @@ -13,6 +13,7 @@ class FeatureExtractorParameter(Serializable): dino_feat_type: str = "feat" projection_type: str = "nonlinear" input_size: list = field(default_factory=lambda: [80, 160]) + feature_image_topic: str = "/semantic_pointcloud/feature_image" @dataclass From 7475e94352b353ecc22379d15dd18eded4f91f67 Mon Sep 17 00:00:00 2001 From: Gian Date: Mon, 6 Feb 2023 15:01:35 +0100 Subject: [PATCH 335/504] visualization --- .../elevation_mapping_cupy/plugins/features_pca.py | 1 + .../script/elevation_mapping_cupy/semantic_map.py | 1 + .../tests/test_semantic_kernels.py | 12 ++++++------ 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py index 69b246b5..1c65e264 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py @@ -59,6 +59,7 @@ def __call__( # check which has the highest value if len(layer_indices) > 0: data = cp.reshape(semantic_map.semantic_map[layer_indices], (len(layer_indices), -1)).T.get() + data = np.clip(data, -1, 1) n_components = 3 pca = PCA(n_components=n_components).fit(data) pca_descriptors = pca.transform(data) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 1f858509..288bcc27 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -296,6 +296,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): self.semantic_map, size=(self.param.cell_n * self.param.cell_n*pcl_ids.shape[0]), ) + np.save("features.npy",self.semantic_map[layer_ids]) if "bayesian_inference" in additional_fusion: pcl_ids, layer_ids = self.get_indices_fusion(channels, "bayesian_inference") self.sum_mean *= 0 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py index 2e01a901..ed7eb85c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py @@ -72,12 +72,12 @@ def test_color_kernel(): "map_shape, points_all,pcl_ids, layer_ids", [ ( - (3, 4, 4), + (4, 4, 4), cp.array( [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 ), - cp.array([3], dtype=cp.int32), - cp.array([0], dtype=cp.int32), + cp.array([3, 4], dtype=cp.int32), + cp.array([1, 2], dtype=cp.int32), ), ], ) @@ -121,12 +121,12 @@ def test_sum_kernel(map_shape, points_all, pcl_ids, layer_ids): "map_shape, points_all,pcl_ids, layer_ids", [ ( - (3, 4, 4), + (4, 4, 4), cp.array( [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 ), - cp.array([3], dtype=cp.int32), - cp.array([0], dtype=cp.int32), + cp.array([3, 4], dtype=cp.int32), + cp.array([1, 2], dtype=cp.int32), ), ], ) From 4b1a5c42f6dccca12006b5523ed647607b76289e Mon Sep 17 00:00:00 2001 From: Gian Date: Fri, 10 Feb 2023 09:35:58 +0100 Subject: [PATCH 336/504] added pca from moncular cameras --- .../plugins/features_pca.py | 2 +- .../script/semantic_pointcloud/networks.py | 3 +- .../semantic_segmentation_node.py | 53 ++++++++++++++++--- .../semantic_segmentation_parameters.py | 4 +- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py index 1c65e264..f6e6506d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py @@ -51,7 +51,7 @@ def __call__( # get indices of all layers that contain semantic features information layer_indices = cp.array([], dtype=cp.int32) for it, fusion_alg in enumerate(semantic_map.param.fusion_algorithms): - if fusion_alg in ["average", "bayesian_inference"]: + if fusion_alg in ["average", "bayesian_inference","image_exponential"]: layer_indices = cp.append(layer_indices, it).astype(cp.int32) n_c = semantic_map.semantic_map[layer_indices].shape[1] diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py index ebd9dcc8..6ddcdb80 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py @@ -284,5 +284,6 @@ def __call__(self, image, *args, **kwargs): feat2, code2 = self.model(image.flip(dims=[3])) code = (code1 + code2.flip(dims=[3])) / 2 code = NF.interpolate(code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False).detach() - code = torch.squeeze(reset_size(code), dim=0) + code = reset_size(code) + code = torch.squeeze(code , dim=0) return code diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_node.py index 028eb05d..c373f84f 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_node.py @@ -11,12 +11,12 @@ import message_filters from sensor_msgs.msg import Image, CameraInfo -from sensor_msgs.msg import PointCloud2, Image +from sensor_msgs.msg import PointCloud2, Image, CompressedImage from cv_bridge import CvBridge from semantic_pointcloud.semantic_segmentation_parameters import SemanticSegmentationParameter from semantic_pointcloud.networks import resolve_model -from semantic_pointcloud.utils import decode_max +from sklearn.decomposition import PCA class SemanticSegmentationNode: @@ -63,7 +63,14 @@ def initialize_semantics(self): def register_sub_pub(self): """Register publishers and subscribers.""" # subscribers - rospy.Subscriber(self.param.image_topic, Image, self.image_callback) + if "compressed" in self.param.image_topic: + self.compressed = True + self.subscriber = rospy.Subscriber(self.param.image_topic, + CompressedImage, self.image_callback, queue_size=2) + print("Subscribing to compressed image topic: {}".format(self.param.image_topic)) + else: + self.compressed = False + rospy.Subscriber(self.param.image_topic, Image, self.image_callback) # publishers if self.param.semantic_segmentation: @@ -74,6 +81,8 @@ def register_sub_pub(self): self.color_map_viz() if self.param.feature_extractor: self.feature_pub = rospy.Publisher(self.param.feature_topic, Image, queue_size=2) + self.feat_im_pub = rospy.Publisher(self.param.feat_image_topic, Image, queue_size=2) + def color_map(self, N=256, normalized=False): """Create a color map for the class labels. @@ -118,15 +127,19 @@ def color_map_viz(self): plt.show() def image_callback(self, rgb_msg): - image = cp.asarray(self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8")) + if self.compressed: + image = cp.asarray(self.cv_bridge.compressed_imgmsg_to_cv2(rgb_msg)) + else: + image = cp.asarray(self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8")) self.header = rgb_msg.header self.process_image(image) if self.param.semantic_segmentation: self.publish_segmentation() self.publish_segmentation_image() - # if self.param.feature_extractor: - # self.publish_feature_image() + if self.param.feature_extractor: + self.publish_feature() + self.publish_feature_image(self.features) def process_image(self, image): """Depending on setting generate color, semantic segmentation or feature channels. @@ -141,8 +154,8 @@ def process_image(self, image): if self.param.semantic_segmentation: self.sem_seg = self.semantic_model["model"](image) - # if self.feature_channels is not None: - # prediction = self.feature_extractor["model"](image) + if self.param.feature_extractor: + self.features = self.feature_extractor["model"](image) def publish_segmentation(self): probabilities = self.sem_seg @@ -153,6 +166,16 @@ def publish_segmentation(self): seg_msg.header.stamp = self.header.stamp self.seg_pub.publish(seg_msg) + def publish_feature(self): + features = self.features + img = features.cpu().detach().numpy() + img = np.transpose(img, (1, 2, 0)).astype(np.float32) + feature_msg = self.cv_bridge.cv2_to_imgmsg(img, encoding="passthrough") + feature_msg.header.frame_id = self.header.frame_id + feature_msg.header.stamp = self.header.stamp + self.feature_pub.publish(feature_msg) + + def publish_segmentation_image(self): colors = None probabilities = self.sem_seg @@ -188,6 +211,20 @@ def publish_segmentation_image(self): seg_msg.header.stamp = self.header.stamp self.seg_im_pub.publish(seg_msg) + def publish_feature_image(self, features): + data = np.reshape(features.cpu().detach().numpy(), (features.shape[0], -1)).T + n_components = 3 + pca = PCA(n_components=n_components).fit(data) + pca_descriptors = pca.transform(data) + img_pca = pca_descriptors.reshape(features.shape[1], features.shape[2], n_components) + comp = img_pca #[:, :, -3:] + comp_min = comp.min(axis=(0, 1)) + comp_max = comp.max(axis=(0, 1)) + comp_img = (comp - comp_min) / (comp_max - comp_min) + comp_img = (comp_img * 255).astype(np.uint8) + feat_msg = self.cv_bridge.cv2_to_imgmsg(comp_img, encoding="passthrough") + feat_msg.header.frame_id = self.header.frame_id + self.feat_im_pub.publish(feat_msg) if __name__ == "__main__": arg = sys.argv[1] diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_parameters.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_parameters.py index fc8aeccd..4075eb99 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_parameters.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_parameters.py @@ -8,7 +8,7 @@ class FeatureExtractorParameter(Serializable): interpolation: str = "bilinear" model: str = "vit_small" patch_size: int = 16 - dim: int = 5 + dim: int = 10 dropout: bool = False dino_feat_type: str = "feat" projection_type: str = "nonlinear" @@ -31,3 +31,5 @@ class SemanticSegmentationParameter(Serializable): feature_config: FeatureExtractorParameter = FeatureExtractorParameter # feature_config.input_size: list = field(default_factory=lambda: [80, 160]) feature_topic: str = "/elevation_mapping/semantic_seg_feat" + feat_image_topic: str = "/elevation_mapping/semantic_seg_feat_im" + From 43c35279e8c0b9920c640a15c6d4f795b747e214 Mon Sep 17 00:00:00 2001 From: Gian Date: Fri, 10 Feb 2023 10:01:03 +0100 Subject: [PATCH 337/504] reformatted code --- .github/workflows/documentation.yml | 2 +- .github/workflows/python-tests.yml | 46 +++---- README.md | 13 +- docs/source/conf.py | 1 - .../getting_started/cuda_installation.rst | 1 - docs/source/index.rst | 1 - elevation_map_msgs/package.xml | 28 ++--- .../config/anymal_parameters.yaml | 12 +- .../config/anymal_plugin_config.yaml | 22 ++-- .../config/anymal_sensor_parameter.yaml | 96 +++++++-------- .../config/heap_parameters.yaml | 20 ++-- .../config/heap_plugin_config.yaml | 22 ++-- .../config/heap_sensor_parameter.yaml | 20 ++-- .../config/lonomy_parameters.yaml | 16 +-- .../config/lonomy_plugin_config.yaml | 22 ++-- .../config/lonomy_sensor_parameter.yaml | 8 +- elevation_mapping_cupy/config/parameters.yaml | 12 +- .../config/plugin_config.yaml | 24 ++-- .../config/sensor_parameter.yaml | 4 +- .../config/sim_parameters.yaml | 12 +- .../config/sim_plugin_config.yaml | 22 ++-- .../config/sim_sensor_parameter.yaml | 20 ++-- .../elevation_mapping_ros.hpp | 12 +- .../elevation_mapping_wrapper.hpp | 2 +- .../anymal_semantic_elevation_single.launch | 23 ++-- .../launch/elevation_mapping_cupy.launch | 10 +- .../launch/heap_launch.launch | 19 ++- .../launch/lonomy_pointcloud.launch | 15 +-- .../lonomy_semantic_elevation_single.launch | 25 ++-- .../sim_semantic_elevation_single.launch | 26 ++-- .../launch/turtlesim_example.launch | 36 +++--- .../launch/turtlesim_pointcloud.launch | 23 ++-- .../turtlesim_segmentation_example.launch | 12 +- .../turtlesim_semantic_elevation.launch | 17 ++- elevation_mapping_cupy/package.xml | 38 +++--- elevation_mapping_cupy/rviz/anymal.rviz | 90 +++++++------- elevation_mapping_cupy/rviz/heap.rviz | 48 ++++---- .../rviz/lonomy_single.rviz | 36 +++--- .../elevation_mapping.py | 9 +- .../kernels/custom_image_kernels.py | 1 + .../plugins/plugin_manager.py | 6 +- .../elevation_mapping_cupy/semantic_map.py | 13 +- .../tests/plugin_config.yaml | 24 ++-- .../src/elevation_mapping_ros.cpp | 70 +++++------ .../src/elevation_mapping_wrapper.cpp | 42 +++---- plane_segmentation/README.md | 10 ++ plane_segmentation/cgal5_catkin/README.md | 1 + plane_segmentation/cgal5_catkin/package.xml | 16 +-- .../convex_plane_decomposition/CMakeLists.txt | 56 ++++----- .../convex_plane_decomposition/package.xml | 20 ++-- .../CMakeLists.txt | 112 +++++++++--------- .../launch/convex_plane_decomposition.launch | 17 +-- .../launch/demo.launch | 92 +++++++------- .../launch/save_elevation_map.launch | 12 +- .../rviz/config_demo.rviz | 2 +- .../grid_map_filters_rsl/package.xml | 24 ++-- .../config/sensor_parameter.yaml | 16 +-- .../launch/semantic_pointcloud.launch | 6 +- .../semantic_pointcloud/package.xml | 31 +++-- .../script/semantic_pointcloud/networks.py | 2 +- .../semantic_pointcloud/pointcloud_node.py | 2 +- 61 files changed, 718 insertions(+), 722 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 95fa80a3..9da81809 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -1,5 +1,5 @@ name: Docs -on: [push, pull_request, workflow_dispatch] +on: [ push, pull_request, workflow_dispatch ] jobs: docs: runs-on: ubuntu-latest diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 23f732bf..00e81d4a 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -4,7 +4,7 @@ name: Python testing on: push: - branches: [ "feature/2_semantic_python", "feature/**","dev/**"] + branches: [ "feature/2_semantic_python", "feature/**","dev/**" ] # pull_request: # branches: [ "main" ] @@ -14,27 +14,27 @@ permissions: jobs: build: -# runs-on: ubuntu-latest - runs-on: [self-hosted, Linux, X64] + # runs-on: ubuntu-latest + runs-on: [ self-hosted, Linux, X64 ] steps: - - uses: actions/checkout@v3 - - name: Set up Python 3.8 - uses: actions/setup-python@v3 - with: - python-version: "3.8" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install pytest cupy-cuda11x - python -m pip install 'git+https://github.com/facebookresearch/detectron2.git' - pip install torch torchvision torchaudio - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - name: Test elevation mapping with pytest - run: | - cd elevation_mapping_cupy/script/elevation_mapping_cupy/tests/ - pytest - - name: Test semantic_pointcloud with pytest - run: | - cd sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests - pytest test_utils.py + - uses: actions/checkout@v3 + - name: Set up Python 3.8 + uses: actions/setup-python@v3 + with: + python-version: "3.8" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pytest cupy-cuda11x + python -m pip install 'git+https://github.com/facebookresearch/detectron2.git' + pip install torch torchvision torchaudio + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Test elevation mapping with pytest + run: | + cd elevation_mapping_cupy/script/elevation_mapping_cupy/tests/ + pytest + - name: Test semantic_pointcloud with pytest + run: | + cd sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests + pytest test_utils.py diff --git a/README.md b/README.md index ecb9b977..0811bdf5 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,13 @@ # Elevation Mapping cupy ![python tests](https://github.com/leggedrobotics/elevation_mapping_semantic_cupy/actions/workflows/python-tests.yml/badge.svg) + ## Overview -This is a ROS package for elevation mapping on GPU. The elevation mapping code is written in python and uses cupy for GPU computation. The -plane segmentation is done independently and runs on CPU. When the plane segmentation is generated, local convex approximations of the +This is a ROS package for elevation mapping on GPU. The elevation mapping code is written in python and uses cupy for +GPU computation. The +plane segmentation is done independently and runs on CPU. When the plane segmentation is generated, local convex +approximations of the terrain can be efficiently generated. ![screenshot](doc/main_repo.png) ![gif](doc/convex_approximation.gif) @@ -27,29 +30,27 @@ terrain can be efficiently generated. } ``` - ## Quick instructions to run: For the lonomy bag: CPP wrapper: + ```zsh roslaunch elevation_mapping_cupy lonomy_semantic_elevation_single.launch use_sim_true:=true rosbag play --clock ~/bags/good_working_wine_field_zed_topcom_rtk_person_9_2022-07-15-14-37-05.bag ``` Python wrapper: + ````zsh python -m elevation_mapping_cupy.elevation_mapping_ros roslaunch elevation_mapping_cupy lonomy_pointcloud.launch use_sim_time:=true rosbag play --clock ~/bags/good_working_wine_field_zed_topcom_rtk_person_9_2022-07-15-14-37-05.bag ```` - - For the anymal bag: - ```zsh roslaunch elevation_mapping_cupy anymal_semantic_elevation_single.launch use_sim_time:=true rosbag play --clock ~/bags/anymal_coyote_2022-12-11-20-01-46.bag diff --git a/docs/source/conf.py b/docs/source/conf.py index 37693134..d761f2ff 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,7 +19,6 @@ html_theme = "sphinx_rtd_theme" html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] - project = "elevation_mapping_cupy" copyright = "2022, Takahiro Miki, Gian Erni" author = "Takahiro Miki, Gian Erni" diff --git a/docs/source/getting_started/cuda_installation.rst b/docs/source/getting_started/cuda_installation.rst index a4a6c1f6..0c4ede99 100644 --- a/docs/source/getting_started/cuda_installation.rst +++ b/docs/source/getting_started/cuda_installation.rst @@ -1,4 +1,3 @@ - Cuda installation ================================================================== .. _cuda_installation: diff --git a/docs/source/index.rst b/docs/source/index.rst index fa842a9a..bef11bf9 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,4 +1,3 @@ - .. include:: documentation.rst .. toctree:: diff --git a/elevation_map_msgs/package.xml b/elevation_map_msgs/package.xml index 0dc57b6c..5fa7a60a 100644 --- a/elevation_map_msgs/package.xml +++ b/elevation_map_msgs/package.xml @@ -1,19 +1,19 @@ - elevation_map_msgs - 0.0.0 - ROS Message definitions for elevation mapping. - Takahiro Miki - Takahiro Miki - MIT + elevation_map_msgs + 0.0.0 + ROS Message definitions for elevation mapping. + Takahiro Miki + Takahiro Miki + MIT - catkin - - geometry_msgs - message_generation - - geometry_msgs + catkin - - + geometry_msgs + message_generation + + geometry_msgs + + + diff --git a/elevation_mapping_cupy/config/anymal_parameters.yaml b/elevation_mapping_cupy/config/anymal_parameters.yaml index 078214ce..ae2a86e4 100644 --- a/elevation_mapping_cupy/config/anymal_parameters.yaml +++ b/elevation_mapping_cupy/config/anymal_parameters.yaml @@ -70,13 +70,13 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin # fps: # Publish rate. Use smaller value than `map_acquire_fps`. publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance'] - basic_layers: ['elevation', 'traversability'] + layers: [ 'elevation', 'traversability', 'variance' ] + basic_layers: [ 'elevation', 'traversability' ] fps: 2.0 semantic_map_raw: - layers: ['elevation', 'traversability', 'variance', 'rgb_image', 'visual_traversability'] - basic_layers: ['elevation', 'traversability'] + layers: [ 'elevation', 'traversability', 'variance', 'rgb_image', 'visual_traversability' ] + basic_layers: [ 'elevation', 'traversability' ] fps: 2.0 # elevation_map_recordable: # layers: ['elevation', 'traversability'] @@ -89,8 +89,8 @@ publishers: #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['RF_FOOT', 'LF_FOOT', 'RH_FOOT', 'LH_FOOT'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. +initialize_frame_id: [ 'RF_FOOT', 'LF_FOOT', 'RH_FOOT', 'LH_FOOT' ] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [ 0.0, 0.0, 0.0, 0.0 ] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 5 # dilation size after the init. initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/anymal_plugin_config.yaml b/elevation_mapping_cupy/config/anymal_plugin_config.yaml index e18df155..9630f496 100644 --- a/elevation_mapping_cupy/config/anymal_plugin_config.yaml +++ b/elevation_mapping_cupy/config/anymal_plugin_config.yaml @@ -1,16 +1,16 @@ # Settings of the plugins. (The plugins should be stored in script/plugins) # min_filter fills in minimum value around the invalid cell. -min_filter: +min_filter: enable: True # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. + extra_params: # This params are passed to the plugin class on initialization. dilation_size: 1 # The patch size to apply iteration_n: 30 # The number of iterations # Apply smoothing. -smooth_filter: +smooth_filter: enable: True fill_nan: False is_height_layer: True @@ -27,14 +27,14 @@ inpainting: method: "telea" # telea or ns # Apply smoothing for inpainted layer -robot_centric_elevation: # Use the same name as your file name. -# type: "robot_centric_elevation" +robot_centric_elevation: # Use the same name as your file name. + # type: "robot_centric_elevation" enable: False # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. -# add_value: 2.0 # Example param + extra_params: # This params are passed to the plugin class on initialization. + # add_value: 2.0 # Example param resolution: 0.04 threshold: 1.1 use_threshold: True @@ -46,7 +46,7 @@ semantic_filter: is_height_layer: False layer_name: "sem_fil" extra_params: - classes: ['grass','tree','fence','dirt'] + classes: [ 'grass','tree','fence','dirt' ] semantic_traversability: type: "semantic_traversability" @@ -55,7 +55,7 @@ semantic_traversability: is_height_layer: False layer_name: "sem_traversability" extra_params: - layers: ['traversability','robot_centric_elevation'] - thresholds: [0.3,0.5] - type: ['traversability', 'elevation'] + layers: [ 'traversability','robot_centric_elevation' ] + thresholds: [ 0.3,0.5 ] + type: [ 'traversability', 'elevation' ] diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml index 27bd064a..4d5b6708 100644 --- a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml @@ -30,7 +30,7 @@ subscribers: # topic_name_camera_info: /zed2i/zed_node/right/camera_info # channels: ["single_channel_semantic"] # data_type: image - + # front_cam: # channels: ['rgb'] # fusion: ['color'] @@ -38,100 +38,100 @@ subscribers: # data_type: pointcloud alphasense_front_rgb: - fusion: ['image_color'] + fusion: [ 'image_color' ] topic_name_camera: /alphasense_driver_ros/cam4/debayered topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info - channels: ["rgb_image"] + channels: [ "rgb_image" ] data_type: image alphasense_left_rgb: - fusion: ['image_color'] + fusion: [ 'image_color' ] topic_name_camera: /alphasense_driver_ros/cam3/debayered topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info - channels: ["rgb_image"] + channels: [ "rgb_image" ] data_type: image alphasense_right_rgb: - fusion: ['image_color'] + fusion: [ 'image_color' ] topic_name_camera: /alphasense_driver_ros/cam5/debayered topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info - channels: ["rgb_image"] + channels: [ "rgb_image" ] data_type: image wvn_prediction: - fusion: ['image_exponential'] + fusion: [ 'image_exponential' ] topic_name_camera: '/wild_visual_navigation_node/traversability_raw' topic_name_camera_info: '/wild_visual_navigation_node/camera_info' - channels: ["visual_traversability"] + channels: [ "visual_traversability" ] data_type: image - # front_cam: - # channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] - # fusion: ['color','average','average','class_average','class_average','class_average','class_average'] - # topic_name: '/elvation_mapping/pointcloud_semantic' - # semantic_segmentation: False - # segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' - # feature_config: - # name: 'DINO' - # interpolation: 'bilinear' - # model: "vit_small" - # patch_size: 16 - # dim: 5 - # dropout: False - # dino_feat_type: "feat" - # input_size: [80, 160] - # projection_type: "nonlinear" + # front_cam: + # channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] + # fusion: ['color','average','average','class_average','class_average','class_average','class_average'] + # topic_name: '/elvation_mapping/pointcloud_semantic' + # semantic_segmentation: False + # segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' + # feature_config: + # name: 'DINO' + # interpolation: 'bilinear' + # model: "vit_small" + # patch_size: 16 + # dim: 5 + # dropout: False + # dino_feat_type: "feat" + # input_size: [80, 160] + # projection_type: "nonlinear" + + # cam_info_topic: "/camera/depth/camera_info" + # image_topic: "/camera/rgb/image_raw" + # depth_topic: "/camera/depth/image_raw" + # cam_frame: camera_rgb_optical_frame + # confidence: False + # confidence_topic: "/camera/depth/image_raw" + # confidence_threshold: 10 + # feature_extractor: False - # cam_info_topic: "/camera/depth/camera_info" - # image_topic: "/camera/rgb/image_raw" - # depth_topic: "/camera/depth/image_raw" - # cam_frame: camera_rgb_optical_frame - # confidence: False - # confidence_topic: "/camera/depth/image_raw" - # confidence_threshold: 10 - # feature_extractor: False - front_bpearl: - channels: [] - fusion: [] + channels: [ ] + fusion: [ ] topic_name: /robot_self_filter/bpearl_front/point_cloud data_type: pointcloud rear_bpearl: - channels: [] - fusion: [] + channels: [ ] + fusion: [ ] topic_name: /robot_self_filter/bpearl_rear/point_cloud data_type: pointcloud front_depth: - channels: [] - fusion: [] + channels: [ ] + fusion: [ ] topic_name: /depth_camera_front/point_cloud_self_filtered data_type: pointcloud rear_depth: - channels: [] - fusion: [] + channels: [ ] + fusion: [ ] topic_name: /depth_camera_rear/point_cloud_self_filtered data_type: pointcloud left_depth: - channels: [] - fusion: [] + channels: [ ] + fusion: [ ] topic_name: /depth_camera_left/point_cloud_self_filtered data_type: pointcloud right_depth: - channels: [] - fusion: [] + channels: [ ] + fusion: [ ] topic_name: /depth_camera_right/point_cloud_self_filtered data_type: pointcloud velodyne: - channels: [] - fusion: [] + channels: [ ] + fusion: [ ] topic_name: /point_cloud_filter/lidar/point_cloud_filtered data_type: pointcloud diff --git a/elevation_mapping_cupy/config/heap_parameters.yaml b/elevation_mapping_cupy/config/heap_parameters.yaml index 064e1bb4..55de512d 100644 --- a/elevation_mapping_cupy/config/heap_parameters.yaml +++ b/elevation_mapping_cupy/config/heap_parameters.yaml @@ -73,22 +73,22 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/heap_plugin_c # fps: # Publish rate. Use smaller value than `map_acquire_fps`. publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance'] - basic_layers: ['elevation', 'traversability'] + layers: [ 'elevation', 'traversability', 'variance' ] + basic_layers: [ 'elevation', 'traversability' ] fps: 5.0 -# elevation_map_recordable: -# layers: ['elevation', 'traversability'] -# basic_layers: ['elevation', 'traversability'] -# fps: 2.0 + # elevation_map_recordable: + # layers: ['elevation', 'traversability'] + # basic_layers: ['elevation', 'traversability'] + # fps: 2.0 elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb_image','sem_fil'] - basic_layers: ['min_filter'] + layers: [ 'min_filter', 'smooth', 'inpaint', 'elevation','rgb_image','sem_fil' ] + basic_layers: [ 'min_filter' ] fps: 3.0 #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['RH_WHEEL_CONTACT','RF_WHEEL_CONTACT','LH_WHEEL_CONTACT','LF_WHEEL_CONTACT'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. +initialize_frame_id: [ 'RH_WHEEL_CONTACT','RF_WHEEL_CONTACT','LH_WHEEL_CONTACT','LF_WHEEL_CONTACT' ] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [ 0.0, 0.0, 0.0, 0.0 ] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 5 # dilation size after the init. initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/heap_plugin_config.yaml b/elevation_mapping_cupy/config/heap_plugin_config.yaml index e18df155..9630f496 100644 --- a/elevation_mapping_cupy/config/heap_plugin_config.yaml +++ b/elevation_mapping_cupy/config/heap_plugin_config.yaml @@ -1,16 +1,16 @@ # Settings of the plugins. (The plugins should be stored in script/plugins) # min_filter fills in minimum value around the invalid cell. -min_filter: +min_filter: enable: True # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. + extra_params: # This params are passed to the plugin class on initialization. dilation_size: 1 # The patch size to apply iteration_n: 30 # The number of iterations # Apply smoothing. -smooth_filter: +smooth_filter: enable: True fill_nan: False is_height_layer: True @@ -27,14 +27,14 @@ inpainting: method: "telea" # telea or ns # Apply smoothing for inpainted layer -robot_centric_elevation: # Use the same name as your file name. -# type: "robot_centric_elevation" +robot_centric_elevation: # Use the same name as your file name. + # type: "robot_centric_elevation" enable: False # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. -# add_value: 2.0 # Example param + extra_params: # This params are passed to the plugin class on initialization. + # add_value: 2.0 # Example param resolution: 0.04 threshold: 1.1 use_threshold: True @@ -46,7 +46,7 @@ semantic_filter: is_height_layer: False layer_name: "sem_fil" extra_params: - classes: ['grass','tree','fence','dirt'] + classes: [ 'grass','tree','fence','dirt' ] semantic_traversability: type: "semantic_traversability" @@ -55,7 +55,7 @@ semantic_traversability: is_height_layer: False layer_name: "sem_traversability" extra_params: - layers: ['traversability','robot_centric_elevation'] - thresholds: [0.3,0.5] - type: ['traversability', 'elevation'] + layers: [ 'traversability','robot_centric_elevation' ] + thresholds: [ 0.3,0.5 ] + type: [ 'traversability', 'elevation' ] diff --git a/elevation_mapping_cupy/config/heap_sensor_parameter.yaml b/elevation_mapping_cupy/config/heap_sensor_parameter.yaml index a0478682..9fd09452 100644 --- a/elevation_mapping_cupy/config/heap_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/heap_sensor_parameter.yaml @@ -1,23 +1,23 @@ subscribers: front_cam: - channels: [] - fusion: [] + channels: [ ] + fusion: [ ] topic_name: '/ouster_points_self_filtered' data_type: pointcloud -# camera_right_rgb: -# fusion: ['image_color'] -# topic_name_camera: /camUSBRightView/Downsampled -# topic_name_camera_info: /camera_info -# channels: ["rgb_image"] -# data_type: image + # camera_right_rgb: + # fusion: ['image_color'] + # topic_name_camera: /camUSBRightView/Downsampled + # topic_name_camera_info: /camera_info + # channels: ["rgb_image"] + # data_type: image camera_main_rgb: - fusion: ['image_color'] + fusion: [ 'image_color' ] topic_name_camera: /camMainView/Downsampled topic_name_camera_info: /camera_info - channels: ["rgb_image"] + channels: [ "rgb_image" ] data_type: image diff --git a/elevation_mapping_cupy/config/lonomy_parameters.yaml b/elevation_mapping_cupy/config/lonomy_parameters.yaml index ea94002f..e1d71f9b 100644 --- a/elevation_mapping_cupy/config/lonomy_parameters.yaml +++ b/elevation_mapping_cupy/config/lonomy_parameters.yaml @@ -73,22 +73,22 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/lonomy_plugin # fps: # Publish rate. Use smaller value than `map_acquire_fps`. publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance'] - basic_layers: ['elevation', 'traversability'] + layers: [ 'elevation', 'traversability', 'variance' ] + basic_layers: [ 'elevation', 'traversability' ] fps: 5.0 elevation_map_recordable: - layers: ['elevation', 'traversability'] - basic_layers: ['elevation', 'traversability'] + layers: [ 'elevation', 'traversability' ] + basic_layers: [ 'elevation', 'traversability' ] fps: 2.0 elevation_map_filter: - layers: [elevation, 'min_filter', 'smooth', 'inpaint', 'upper_bound','rgb_image', 'gray_image'] - basic_layers: [elevation, 'min_filter'] + layers: [ elevation, 'min_filter', 'smooth', 'inpaint', 'upper_bound','rgb_image', 'gray_image' ] + basic_layers: [ elevation, 'min_filter' ] fps: 3.0 #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. +initialize_frame_id: [ 'base_footprint' ] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [ 0.0, 0.0, 0.0, 0.0 ] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 5 # dilation size after the init. initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/lonomy_plugin_config.yaml b/elevation_mapping_cupy/config/lonomy_plugin_config.yaml index 37553806..7bcc17f0 100644 --- a/elevation_mapping_cupy/config/lonomy_plugin_config.yaml +++ b/elevation_mapping_cupy/config/lonomy_plugin_config.yaml @@ -1,16 +1,16 @@ # Settings of the plugins. (The plugins should be stored in script/plugins) # min_filter fills in minimum value around the invalid cell. -min_filter: +min_filter: enable: True # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. + extra_params: # This params are passed to the plugin class on initialization. dilation_size: 1 # The patch size to apply iteration_n: 30 # The number of iterations # Apply smoothing. -smooth_filter: +smooth_filter: enable: True fill_nan: False is_height_layer: True @@ -27,14 +27,14 @@ inpainting: method: "telea" # telea or ns # Apply smoothing for inpainted layer -robot_centric_elevation: # Use the same name as your file name. -# type: "robot_centric_elevation" +robot_centric_elevation: # Use the same name as your file name. + # type: "robot_centric_elevation" enable: True # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. -# add_value: 2.0 # Example param + extra_params: # This params are passed to the plugin class on initialization. + # add_value: 2.0 # Example param resolution: 0.04 threshold: 1.1 use_threshold: True @@ -46,7 +46,7 @@ semantic_filter: is_height_layer: False layer_name: "sem_fil" extra_params: - classes: ['grass','tree','fence','dirt'] + classes: [ 'grass','tree','fence','dirt' ] semantic_traversability: type: "semantic_traversability" @@ -55,7 +55,7 @@ semantic_traversability: is_height_layer: False layer_name: "sem_traversability" extra_params: - layers: ['traversability','robot_centric_elevation'] - thresholds: [0.3,0.5] - type: ['traversability', 'elevation'] + layers: [ 'traversability','robot_centric_elevation' ] + thresholds: [ 0.3,0.5 ] + type: [ 'traversability', 'elevation' ] diff --git a/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml b/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml index 58581b42..34e7e0c9 100644 --- a/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml @@ -1,7 +1,7 @@ subscribers: front_cam: - channels: [ 'rgb','feat_0','feat_1'] - fusion: [ 'color','bayesian_inference','bayesian_inference'] + channels: [ 'rgb','feat_0','feat_1' ] + fusion: [ 'color','bayesian_inference','bayesian_inference' ] topic_name: '/elvation_mapping/pointcloud_semantic' semantic_segmentation: False segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large @@ -11,11 +11,11 @@ subscribers: name: 'DINO' interpolation: 'bilinear' model: "vit_small" - patch_size: 16 + patch_size: 16 dim: 5 dropout: False dino_feat_type: "feat" - input_size: [80, 160] + input_size: [ 80, 160 ] projection_type: "nonlinear" cam_info_topic: "/zed2i/zed_node/depth/camera_info" diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index 4941a011..614e530f 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -70,13 +70,13 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/plugin_config # fps: # Publish rate. Use smaller value than `map_acquire_fps`. publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance'] - basic_layers: ['elevation', 'traversability'] + layers: [ 'elevation', 'traversability', 'variance' ] + basic_layers: [ 'elevation', 'traversability' ] fps: 2.0 semantic_map_raw: - layers: ['elevation', 'traversability', 'variance', 'rgb_image'] - basic_layers: ['elevation', 'traversability'] + layers: [ 'elevation', 'traversability', 'variance', 'rgb_image' ] + basic_layers: [ 'elevation', 'traversability' ] fps: 2.0 # elevation_map_recordable: # layers: ['elevation', 'traversability'] @@ -89,8 +89,8 @@ publishers: #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [0.0] # z direction. Should be same number as initialize_frame_id. +initialize_frame_id: [ 'base_footprint' ] # One tf (like ['footprint'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [ 0.0 ] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 5 # dilation size after the init. initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/plugin_config.yaml b/elevation_mapping_cupy/config/plugin_config.yaml index bcc0cb24..fde55c58 100644 --- a/elevation_mapping_cupy/config/plugin_config.yaml +++ b/elevation_mapping_cupy/config/plugin_config.yaml @@ -1,16 +1,16 @@ # Settings of the plugins. (The plugins should be stored in script/plugins) # min_filter fills in minimum value around the invalid cell. -min_filter: +min_filter: enable: True # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. + extra_params: # This params are passed to the plugin class on initialization. dilation_size: 1 # The patch size to apply iteration_n: 30 # The number of iterations # Apply smoothing. -smooth_filter: +smooth_filter: enable: True fill_nan: False is_height_layer: True @@ -34,14 +34,14 @@ smooth_filter_1: layer_name: "smooth_1" extra_params: input_layer_name: "inpaint" -robot_centric_elevation: # Use the same name as your file name. -# type: "robot_centric_elevation" +robot_centric_elevation: # Use the same name as your file name. + # type: "robot_centric_elevation" enable: False # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. -# add_value: 2.0 # Example param + extra_params: # This params are passed to the plugin class on initialization. + # add_value: 2.0 # Example param resolution: 0.04 threshold: 1.1 use_threshold: True @@ -52,8 +52,8 @@ semantic_filter: is_height_layer: False layer_name: "sem_fil" extra_params: - classes: ['grass','tree','fence','person'] - colors: [[0,255,0],[120,120,0],[170,0,20],[0,0,255],[255,0,0]] + classes: [ 'grass','tree','fence','person' ] + colors: [ [ 0,255,0 ],[ 120,120,0 ],[ 170,0,20 ],[ 0,0,255 ],[ 255,0,0 ] ] semantic_traversability: type: "semantic_traversability" @@ -62,6 +62,6 @@ semantic_traversability: is_height_layer: False layer_name: "sem_traversability" extra_params: - layers: ['traversability','robot_centric_elevation'] - thresholds: [0.7,0.5] - type: ['traversability', 'elevation'] + layers: [ 'traversability','robot_centric_elevation' ] + thresholds: [ 0.7,0.5 ] + type: [ 'traversability', 'elevation' ] diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index a31f2759..e263a810 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -1,8 +1,8 @@ #### Subscribers ######## subscribers: front_cam: - channels: [ 'rgb'] - fusion: [ 'color'] + channels: [ 'rgb' ] + fusion: [ 'color' ] topic_name: '/elvation_mapping/pointcloud_semantic' semantic_segmentation: False segmentation_model: 'lraspp_mobilenet_v3_large' diff --git a/elevation_mapping_cupy/config/sim_parameters.yaml b/elevation_mapping_cupy/config/sim_parameters.yaml index b92bb6da..0a51fc78 100644 --- a/elevation_mapping_cupy/config/sim_parameters.yaml +++ b/elevation_mapping_cupy/config/sim_parameters.yaml @@ -70,13 +70,13 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin # fps: # Publish rate. Use smaller value than `map_acquire_fps`. publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance'] - basic_layers: ['elevation', 'traversability'] + layers: [ 'elevation', 'traversability', 'variance' ] + basic_layers: [ 'elevation', 'traversability' ] fps: 2.0 semantic_map_raw: - layers: ['elevation', 'traversability', 'variance', 'rgb_image'] - basic_layers: ['elevation', 'traversability'] + layers: [ 'elevation', 'traversability', 'variance', 'rgb_image' ] + basic_layers: [ 'elevation', 'traversability' ] fps: 2.0 # elevation_map_recordable: # layers: ['elevation', 'traversability'] @@ -89,8 +89,8 @@ publishers: #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [0.0] # z direction. Should be same number as initialize_frame_id. +initialize_frame_id: [ 'base_footprint' ] # One tf (like ['footprint'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [ 0.0 ] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 5 # dilation size after the init. initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/sim_plugin_config.yaml b/elevation_mapping_cupy/config/sim_plugin_config.yaml index e18df155..9630f496 100644 --- a/elevation_mapping_cupy/config/sim_plugin_config.yaml +++ b/elevation_mapping_cupy/config/sim_plugin_config.yaml @@ -1,16 +1,16 @@ # Settings of the plugins. (The plugins should be stored in script/plugins) # min_filter fills in minimum value around the invalid cell. -min_filter: +min_filter: enable: True # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. + extra_params: # This params are passed to the plugin class on initialization. dilation_size: 1 # The patch size to apply iteration_n: 30 # The number of iterations # Apply smoothing. -smooth_filter: +smooth_filter: enable: True fill_nan: False is_height_layer: True @@ -27,14 +27,14 @@ inpainting: method: "telea" # telea or ns # Apply smoothing for inpainted layer -robot_centric_elevation: # Use the same name as your file name. -# type: "robot_centric_elevation" +robot_centric_elevation: # Use the same name as your file name. + # type: "robot_centric_elevation" enable: False # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. -# add_value: 2.0 # Example param + extra_params: # This params are passed to the plugin class on initialization. + # add_value: 2.0 # Example param resolution: 0.04 threshold: 1.1 use_threshold: True @@ -46,7 +46,7 @@ semantic_filter: is_height_layer: False layer_name: "sem_fil" extra_params: - classes: ['grass','tree','fence','dirt'] + classes: [ 'grass','tree','fence','dirt' ] semantic_traversability: type: "semantic_traversability" @@ -55,7 +55,7 @@ semantic_traversability: is_height_layer: False layer_name: "sem_traversability" extra_params: - layers: ['traversability','robot_centric_elevation'] - thresholds: [0.3,0.5] - type: ['traversability', 'elevation'] + layers: [ 'traversability','robot_centric_elevation' ] + thresholds: [ 0.3,0.5 ] + type: [ 'traversability', 'elevation' ] diff --git a/elevation_mapping_cupy/config/sim_sensor_parameter.yaml b/elevation_mapping_cupy/config/sim_sensor_parameter.yaml index 4363a22e..f954e0b1 100644 --- a/elevation_mapping_cupy/config/sim_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sim_sensor_parameter.yaml @@ -30,12 +30,12 @@ subscribers: # topic_name_camera_info: /zed2i/zed_node/right/camera_info # channels: ["single_channel_semantic"] # data_type: image - -# front_cam: -# channels: ['rgb'] -# fusion: ['color'] -# topic_name: '/elevation_mapping/pointcloud_semantic' -# data_type: pointcloud + + # front_cam: + # channels: ['rgb'] + # fusion: ['color'] + # topic_name: '/elevation_mapping/pointcloud_semantic' + # data_type: pointcloud # alphasense_front_rgb: # fusion: ['image_color'] @@ -67,7 +67,7 @@ subscribers: # topic_name_camera_info: '/wild_visual_navigation_node/camera_info' # channels: ["visual_traversability"] # data_type: image - + # front_cam: # channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] # fusion: ['color','average','average','class_average','class_average','class_average','class_average'] @@ -93,10 +93,10 @@ subscribers: # confidence_topic: "/camera/depth/image_raw" # confidence_threshold: 10 # feature_extractor: False - + front_bpearl: - channels: [] - fusion: [] + channels: [ ] + fusion: [ ] topic_name: /point_cloud_filter_rsl/filter_and_merger_rsl data_type: pointcloud diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 5371ce88..5811b05b 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -20,8 +20,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -61,7 +61,7 @@ class ElevationMappingNode { ElevationMappingNode(ros::NodeHandle& nh); using RowMatrixXd = Eigen::Matrix; using ColMatrixXf = Eigen::Matrix; - + using ImageSubscriber = image_transport::SubscriberFilter; using ImageSubscriberPtr = std::shared_ptr; using CameraInfoSubscriber = message_filters::Subscriber; @@ -74,7 +74,8 @@ class ElevationMappingNode { void readParameters(); void setupMapPublishers(); void pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key); - void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::string& key); + void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, + const std::string& key); void publishAsPointCloud(const grid_map::GridMap& map) const; bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response); @@ -133,8 +134,7 @@ class ElevationMappingNode { std::vector map_fps_; std::set map_fps_unique_; std::vector mapTimers_; - std::map> channels_; - + std::map> channels_; std::vector initialize_frame_id_; std::vector initialize_tf_offset_; @@ -147,7 +147,7 @@ class ElevationMappingNode { grid_map::GridMap gridMap_; std::atomic_bool isGridmapUpdated_; // needs to be atomic (read is not protected by mapMutex_) - std::mutex errorMutex_; // protects positionError_, and orientationError_ + std::mutex errorMutex_; // protects positionError_, and orientationError_ double positionError_; double orientationError_; diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index 5a8e1cf1..ff92db66 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -49,7 +49,7 @@ class ElevationMappingWrapper { void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); void input_image(const std::string& key, const std::vector& image, const RowMatrixXd& R, const Eigen::VectorXd& t, - const RowMatrixXd& cameraMatrix, int height, int width); + const RowMatrixXd& cameraMatrix, int height, int width); void move_to(const Eigen::VectorXd& p, const RowMatrixXd& R); void clear(); void update_variance(); diff --git a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch index 725c96bd..983bc978 100644 --- a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch +++ b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch @@ -1,25 +1,26 @@ - + - + - + - + - - - - + + + + - + - + - \ No newline at end of file + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch index ca49e6e3..386dfdff 100644 --- a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch +++ b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch @@ -1,7 +1,7 @@ - - - - - + + + + + diff --git a/elevation_mapping_cupy/launch/heap_launch.launch b/elevation_mapping_cupy/launch/heap_launch.launch index c700bbda..2218c409 100644 --- a/elevation_mapping_cupy/launch/heap_launch.launch +++ b/elevation_mapping_cupy/launch/heap_launch.launch @@ -1,18 +1,17 @@ - - - - - + + + + - - - - + + + + - + diff --git a/elevation_mapping_cupy/launch/lonomy_pointcloud.launch b/elevation_mapping_cupy/launch/lonomy_pointcloud.launch index 8e9568c8..d9ad8ecd 100644 --- a/elevation_mapping_cupy/launch/lonomy_pointcloud.launch +++ b/elevation_mapping_cupy/launch/lonomy_pointcloud.launch @@ -1,14 +1,15 @@ - - + + - - + + - - + + - \ No newline at end of file + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch index a093c904..eac2fc20 100644 --- a/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch +++ b/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch @@ -1,21 +1,22 @@ - - + + - - + + - - + + - - - - + + + + - + - \ No newline at end of file + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch index 81ae677d..cc16152c 100644 --- a/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch +++ b/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch @@ -1,21 +1,21 @@ - - + + - - + + - - - + + + - - - - + + + + - + - \ No newline at end of file + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_example.launch b/elevation_mapping_cupy/launch/turtlesim_example.launch index b63dae53..f36001bd 100644 --- a/elevation_mapping_cupy/launch/turtlesim_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_example.launch @@ -2,27 +2,27 @@ - + - - + + - - + + - - - - - map_frame: odom - base_frame: base_footprint - pointcloud_topics: ["/camera/depth/points"] - initialize_frame_id: ['base_footprint'] - initialize_tf_offset: [0.0] - - + + + + + map_frame: odom + base_frame: base_footprint + pointcloud_topics: ["/camera/depth/points"] + initialize_frame_id: ['base_footprint'] + initialize_tf_offset: [0.0] + + - - + + diff --git a/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch b/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch index e7b73dde..8a1e7893 100644 --- a/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch +++ b/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch @@ -1,19 +1,20 @@ - - - + + + - - + + - - + + - - - + + + - + diff --git a/elevation_mapping_cupy/launch/turtlesim_segmentation_example.launch b/elevation_mapping_cupy/launch/turtlesim_segmentation_example.launch index afb7fb01..0cbd561b 100644 --- a/elevation_mapping_cupy/launch/turtlesim_segmentation_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_segmentation_example.launch @@ -2,12 +2,12 @@ - - - - + + + + - - + + diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_elevation.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_elevation.launch index 98940264..651edf2c 100644 --- a/elevation_mapping_cupy/launch/turtlesim_semantic_elevation.launch +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_elevation.launch @@ -1,18 +1,17 @@ - - - + + + - - + - - - - + + + + diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index 614d711a..6a5985f8 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -1,26 +1,26 @@ - elevation_mapping_cupy - 1.0.0 - The elevation mapping by cupy + elevation_mapping_cupy + 1.0.0 + The elevation mapping by cupy - Takahiro Miki + Takahiro Miki - MIT + MIT - catkin - roscpp - rospy - tf - tf_conversions - sensor_msgs - std_msgs - geometry_msgs - grid_map_msgs - elevation_map_msgs - grid_map_ros - image_transport - pcl_ros - pybind11_catkin + catkin + roscpp + rospy + tf + tf_conversions + sensor_msgs + std_msgs + geometry_msgs + grid_map_msgs + elevation_map_msgs + grid_map_ros + image_transport + pcl_ros + pybind11_catkin diff --git a/elevation_mapping_cupy/rviz/anymal.rviz b/elevation_mapping_cupy/rviz/anymal.rviz index e8023f37..88da0693 100644 --- a/elevation_mapping_cupy/rviz/anymal.rviz +++ b/elevation_mapping_cupy/rviz/anymal.rviz @@ -324,7 +324,7 @@ Visualization Manager: LF_SHANK: LF_shank_fixed: LF_FOOT: - {} + { } LH_HAA: LH_HIP: LH_hip_fixed: @@ -335,7 +335,7 @@ Visualization Manager: LH_SHANK: LH_shank_fixed: LH_FOOT: - {} + { } RF_HAA: RF_HIP: RF_hip_fixed: @@ -346,7 +346,7 @@ Visualization Manager: RF_SHANK: RF_shank_fixed: RF_FOOT: - {} + { } RH_HAA: RH_HIP: RH_hip_fixed: @@ -357,119 +357,119 @@ Visualization Manager: RH_SHANK: RH_shank_fixed: RH_FOOT: - {} + { } alphasense_mesh: - {} + { } base_inertia: - {} + { } base_inverted: - {} + { } battery: - {} + { } body_top: - {} + { } bottom_shell: - {} + { } depth_camera_left_camera: depth_camera_left_camera_parent: depth_camera_left_depth_frame: depth_camera_left_depth_optical_frame: - {} + { } depth_camera_left_infra1_frame: depth_camera_left_infra1_optical_frame: - {} + { } depth_camera_left_infra2_frame: depth_camera_left_infra2_optical_frame: - {} + { } depth_camera_right_camera: depth_camera_right_camera_parent: depth_camera_right_depth_frame: depth_camera_right_depth_optical_frame: - {} + { } depth_camera_right_infra1_frame: depth_camera_right_infra1_optical_frame: - {} + { } depth_camera_right_infra2_frame: depth_camera_right_infra2_optical_frame: - {} + { } docking_hatch_cover: - {} + { } face_front: depth_camera_front_camera: depth_camera_front_camera_parent: depth_camera_front_depth_frame: depth_camera_front_depth_optical_frame: - {} + { } depth_camera_front_infra1_frame: depth_camera_front_infra1_optical_frame: - {} + { } depth_camera_front_infra2_frame: depth_camera_front_infra2_optical_frame: - {} + { } wide_angle_camera_front_camera: wide_angle_camera_front_camera_parent: - {} + { } face_rear: depth_camera_rear_camera: depth_camera_rear_camera_parent: depth_camera_rear_depth_frame: depth_camera_rear_depth_optical_frame: - {} + { } depth_camera_rear_infra1_frame: depth_camera_rear_infra1_optical_frame: - {} + { } depth_camera_rear_infra2_frame: depth_camera_rear_infra2_optical_frame: - {} + { } wide_angle_camera_rear_camera: wide_angle_camera_rear_camera_parent: - {} + { } front_handle: - {} + { } handle: - {} + { } imu_link: - {} + { } interface_hatch: hatch: - {} + { } mira_spectrometer: - {} + { } perception_head_cage: lidar: imu_sensor_frame: cam0_sensor_frame: - {} + { } cam1_sensor_frame: - {} + { } cam2_sensor_frame: - {} + { } cam3_sensor_frame_helper: cam3_sensor_frame: - {} + { } cam4_sensor_frame_helper: cam4_sensor_frame: - {} + { } cam5_sensor_frame_helper: cam5_sensor_frame: - {} + { } cam6_sensor_frame_helper: cam6_sensor_frame: - {} + { } remote: - {} + { } top_shell: - {} + { } feetcenter: - {} + { } footprint: - {} + { } map: camera_init_CORRECTED: camera_init: - {} + { } msf_body_imu_map: - {} + { } Update Interval: 0 Value: true - Class: rviz/Image @@ -489,7 +489,7 @@ Visualization Manager: Marker Topic: /visualization_marker_l Name: Marker Namespaces: - {} + { } Queue Size: 100 Value: true - Class: rviz/Marker @@ -497,7 +497,7 @@ Visualization Manager: Marker Topic: /visualization_marker_r Name: Marker Namespaces: - {} + { } Queue Size: 100 Value: true Enabled: true diff --git a/elevation_mapping_cupy/rviz/heap.rviz b/elevation_mapping_cupy/rviz/heap.rviz index 268b264f..a2e695df 100644 --- a/elevation_mapping_cupy/rviz/heap.rviz +++ b/elevation_mapping_cupy/rviz/heap.rviz @@ -198,24 +198,24 @@ Visualization Manager: map: compslam_lio/camera_init_CORRECTED: compslam_lio/aft_mapped_to_init_CORRECTED: - {} + { } compslam_lio/camera_CORRECTED: - {} + { } compslam_lio/camera_init: compslam_lio/aft_mapped: - {} + { } compslam_lio/camera: - {} + { } compslam_lio/laser_odom: - {} + { } compslam_lio/camera_init_GRAVITY_ALIGNED: - {} + { } compslam_lio/laser_odom_CORRECTED: - {} + { } odom: BASE: BASE_inertia: - {} + { } CABIN: BOOM: DIPPER: @@ -225,60 +225,60 @@ Visualization Manager: ENDEFFECTOR: SHOVEL: ENDEFFECTOR_CONTACT: - {} + { } GNSS_L: - {} + { } GNSS_R: - {} + { } camMainView: livox_frame: - {} + { } os_sensor: os_imu: - {} + { } os_lidar: - {} + { } roof_top_box: imu_box_base_link: imu_box_link: - {} + { } IMU_base_link: IMU_link: - {} + { } LF_SWIVEL: LF_BEAM: LF_BEARING: LF_KNUCKLE: LF_WHEEL: LF_WHEEL_CONTACT: - {} + { } LF_PARALLEL: - {} + { } LH_ROTATOR: LH_BEAM: LH_KNUCKLE: LH_OUTRIGGER: - {} + { } LH_WHEEL: LH_WHEEL_CONTACT: - {} + { } RF_SWIVEL: RF_BEAM: RF_BEARING: RF_KNUCKLE: RF_WHEEL: RF_WHEEL_CONTACT: - {} + { } RF_PARALLEL: - {} + { } RH_ROTATOR: RH_BEAM: RH_KNUCKLE: RH_OUTRIGGER: - {} + { } RH_WHEEL: RH_WHEEL_CONTACT: - {} + { } Update Interval: 0 Value: true - Class: rviz/Image diff --git a/elevation_mapping_cupy/rviz/lonomy_single.rviz b/elevation_mapping_cupy/rviz/lonomy_single.rviz index a3ec715d..5907e933 100644 --- a/elevation_mapping_cupy/rviz/lonomy_single.rviz +++ b/elevation_mapping_cupy/rviz/lonomy_single.rviz @@ -321,46 +321,46 @@ Visualization Manager: enu: base_link: base_footprint: - {} + { } base_inertial: - {} + { } estimator_imu: GPS_back: - {} + { } GPS_front: - {} + { } alphasense: - {} + { } left_back_wheel_sup: left_back_wheel: - {} + { } left_front_wheel_sup: left_front_wheel: - {} + { } rear_axle_center: - {} + { } right_back_wheel_sup: right_back_wheel: - {} + { } right_front_wheel_sup: right_front_wheel: - {} + { } zed2i_base_link: zed2i_camera_center: zed2i_baro_link: - {} + { } zed2i_left_camera_frame: zed2i_left_camera_optical_frame: - {} + { } zed2i_temp_left_link: - {} + { } zed2i_mag_link: - {} + { } zed2i_right_camera_frame: zed2i_right_camera_optical_frame: - {} + { } zed2i_temp_right_link: - {} + { } Update Interval: 0 Value: true - Class: rviz/Image @@ -392,7 +392,7 @@ Visualization Manager: Marker Topic: /visualization_marker_l Name: Marker Namespaces: - {} + { } Queue Size: 100 Value: true - Class: rviz/Marker @@ -400,7 +400,7 @@ Visualization Manager: Marker Topic: /visualization_marker_r Name: Marker Namespaces: - {} + { } Queue Size: 100 Value: true - Alpha: 1 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 3d4d12d1..b1115eef 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -415,18 +415,15 @@ def get_additive_mean_error(self): return self.additive_mean_error def update_variance(self): - """Adds the time variacne to the valid cells. - """ + """Adds the time variacne to the valid cells.""" self.elevation_map[1] += self.param.time_variance * self.elevation_map[2] def update_time(self): - """adds the time interval to the time layer. - """ + """adds the time interval to the time layer.""" self.elevation_map[4] += self.param.time_interval def update_upper_bound_with_valid_elevation(self): - """Filters all invalid cell's upper_bound and is_upper_bound layers. - """ + """Filters all invalid cell's upper_bound and is_upper_bound layers.""" mask = self.elevation_map[2] > 0.5 self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py index 526de667..62f32c70 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py @@ -180,6 +180,7 @@ def exponential_correspondences_to_map_kernel(resolution, width, height, alpha): ) return exponential_correspondences_to_map_kernel + def color_correspondences_to_map_kernel(resolution, width, height): color_correspondences_to_map_kernel = cp.ElementwiseKernel( in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index d780a59f..ce8c990d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -80,11 +80,7 @@ def init(self, plugin_params: List[PluginParams], extra_params: List[Dict]): for param, extra_param in zip(plugin_params, extra_params): m = importlib.import_module("." + param.name, package="elevation_mapping_cupy.plugins") # -> 'module' for name, obj in inspect.getmembers(m): - if ( - inspect.isclass(obj) - and issubclass(obj, PluginBase) - and name != "PluginBase" - ): + if inspect.isclass(obj) and issubclass(obj, PluginBase) and name != "PluginBase": # Add cell_n to params extra_param["cell_n"] = self.cell_n self.plugins.append(obj(**extra_param)) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 133c209b..ca9baa4f 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -63,9 +63,7 @@ def __init__(self, param: Parameter): self.delete_new_layers = cp.ones(self.new_map.shape[0], cp.bool8) def clear(self): - """Clear the semantic map. - - """ + """Clear the semantic map.""" self.semantic_map *= 0.0 def compile_kernels(self) -> None: @@ -153,10 +151,7 @@ def compile_kernels(self) -> None: if "image_exponential" in self.unique_fusion: self.exponential_correspondences_to_map_kernel = exponential_correspondences_to_map_kernel( - resolution=self.param.resolution, - width=self.param.cell_n, - height=self.param.cell_n, - alpha=0.7 + resolution=self.param.resolution, width=self.param.cell_n, height=self.param.cell_n, alpha=0.7 ) if "image_color" in self.unique_fusion: @@ -330,7 +325,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), self.semantic_map, self.new_map, - size=(points_all.shape[0]*pcl_ids.shape[0]), + size=(points_all.shape[0] * pcl_ids.shape[0]), ) self.class_average_kernel( self.new_map, @@ -339,7 +334,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), elevation_map, self.semantic_map, - size=(self.param.cell_n * self.param.cell_n*pcl_ids.shape[0]), + size=(self.param.cell_n * self.param.cell_n * pcl_ids.shape[0]), ) if "class_bayesian" in additional_fusion: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/plugin_config.yaml b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/plugin_config.yaml index 6d057ec5..0e8f67c9 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/plugin_config.yaml +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/plugin_config.yaml @@ -1,16 +1,16 @@ # Settings of the plugins. (The plugins should be stored in script/plugins) # min_filter fills in minimum value around the invalid cell. -min_filter: +min_filter: enable: True # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. + extra_params: # This params are passed to the plugin class on initialization. dilation_size: 1 # The patch size to apply iteration_n: 30 # The number of iterations # Apply smoothing. -smooth_filter: +smooth_filter: enable: True fill_nan: False is_height_layer: True @@ -34,14 +34,14 @@ smooth_filter_1: layer_name: "smooth_1" extra_params: input_layer_name: "inpaint" -robot_centric_elevation: # Use the same name as your file name. -# type: "robot_centric_elevation" +robot_centric_elevation: # Use the same name as your file name. + # type: "robot_centric_elevation" enable: True # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. -# add_value: 2.0 # Example param + extra_params: # This params are passed to the plugin class on initialization. + # add_value: 2.0 # Example param resolution: 0.04 threshold: 1.1 use_threshold: True @@ -52,8 +52,8 @@ semantic_filter: is_height_layer: False layer_name: "sem_fil" extra_params: - classes: ['grass','tree','fence','person'] - colors: [[0,255,0],[120,120,0],[170,0,20],[0,0,255],[255,0,0]] + classes: [ 'grass','tree','fence','person' ] + colors: [ [ 0,255,0 ],[ 120,120,0 ],[ 170,0,20 ],[ 0,0,255 ],[ 255,0,0 ] ] semantic_traversability: type: "semantic_traversability" enable: True @@ -61,6 +61,6 @@ semantic_traversability: is_height_layer: False layer_name: "sem_traversability" extra_params: - layers: ['traversability','robot_centric_elevation'] - thresholds: [0.7,0.5] - type: ['traversability', 'elevation'] + layers: [ 'traversability','robot_centric_elevation' ] + thresholds: [ 0.7,0.5 ] + type: [ 'traversability', 'elevation' ] diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index b8760628..1b6c6dfa 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -42,10 +42,10 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) // Read parameters nh.getParam("subscribers", subscribers); nh.getParam("publishers", publishers); - if(!subscribers.valid()) { + if (!subscribers.valid()) { ROS_FATAL("There aren't any subscribers to be configured, the elevation mapping cannot be configured. Exit"); } - if(!publishers.valid()) { + if (!publishers.valid()) { ROS_FATAL("There aren't any publishers to be configured, the elevation mapping cannot be configured. Exit"); } nh.param>("initialize_frame_id", initialize_frame_id_, {"base"}); @@ -73,25 +73,24 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) // Iterate all the subscribers // here we have to remove all the stuff - for (auto & subscriber : subscribers) { + for (auto& subscriber : subscribers) { std::string key = subscriber.first; auto type = static_cast(subscriber.second["data_type"]); - // Initialize subscribers depending on the type if (type == "pointcloud") { std::string pointcloud_topic = subscriber.second["topic_name"]; - boost::function f = boost::bind(&ElevationMappingNode::pointcloudCallback,this, _1, key); - ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1,f); + boost::function f = boost::bind(&ElevationMappingNode::pointcloudCallback, this, _1, key); + ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, f); pointcloudSubs_.push_back(sub); - const auto & channels = subscriber.second["channels"]; + const auto& channels = subscriber.second["channels"]; channels_[key].push_back("x"); channels_[key].push_back("y"); channels_[key].push_back("z"); for (int32_t i = 0; i < channels.size(); ++i) { auto elem = static_cast(channels[i]); channels_[key].push_back(elem); - } + } } else if (type == "image") { std::string camera_topic = subscriber.second["topic_name_camera"]; @@ -100,12 +99,12 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) // Handle compressed images with transport hints // We obtain the hint from the last part of the topic name std::string transport_hint = "compressed"; - std::size_t ind = camera_topic.find(transport_hint); // Find if compressed is in the topic name + std::size_t ind = camera_topic.find(transport_hint); // Find if compressed is in the topic name if (ind != std::string::npos) { - transport_hint = camera_topic.substr(ind, camera_topic.length()); // Get the hint as the last part - camera_topic.erase(ind - 1, camera_topic.length()); // We remove the hint from the topic + transport_hint = camera_topic.substr(ind, camera_topic.length()); // Get the hint as the last part + camera_topic.erase(ind - 1, camera_topic.length()); // We remove the hint from the topic } else { - transport_hint = "raw"; // In the default case we assume raw topic + transport_hint = "raw"; // In the default case we assume raw topic } // Setup subscriber @@ -279,7 +278,7 @@ void ElevationMappingNode::publishMapOfIndex(int index) { void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key) { auto start = ros::Time::now(); -// transform pointcloud into matrix + // transform pointcloud into matrix auto* pcl_pc = new pcl::PCLPointCloud2; pcl::PCLPointCloud2ConstPtr cloudPtr(pcl_pc); pcl_conversions::toPCL(cloud, *pcl_pc); @@ -289,31 +288,31 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl std::vector channels; std::vector add_element; - for(int it =0;itwidth*pcl_pc->height,array_dim); + RowMatrixXd points = RowMatrixXd(pcl_pc->width * pcl_pc->height, array_dim); - for (unsigned int i = 0; i < pcl_pc->width*pcl_pc->height; ++i) { + for (unsigned int i = 0; i < pcl_pc->width * pcl_pc->height; ++i) { int jit = 0; - for(unsigned int j = 0; jpoint_step + pcl_pc->fields[j].offset; - memcpy(&temp, &pcl_pc->data[point_idx], sizeof(float)); - points(i, jit) = static_cast(temp); - jit++; - } + for (unsigned int j = 0; j < add_element.size(); ++j) { + if (add_element[j]) { + float temp; + uint point_idx = i * pcl_pc->point_step + pcl_pc->fields[j].offset; + memcpy(&temp, &pcl_pc->data[point_idx], sizeof(float)); + points(i, jit) = static_cast(temp); + jit++; + } } } -// get pose of sensor in map frame + // get pose of sensor in map frame tf::StampedTransform transformTf; std::string sensorFrameId = cloud.header.frame_id; auto timeStamp = cloud.header.stamp; @@ -334,7 +333,8 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl positionError = positionError_; orientationError = orientationError_; } - map_.input(points, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError, orientationError); + map_.input(points, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError, + orientationError); if (enableDriftCorrectedTFPublishing_) { publishMapToOdom(map_.get_additive_mean_error()); @@ -348,7 +348,8 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl pointCloudProcessCounter_++; } -void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::string& key) { +void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image_msg, + const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::string& key) { auto start = ros::Time::now(); // Get image @@ -362,7 +363,7 @@ void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image } // Extract camera matrix - Eigen::Map> cameraMatrix(&camera_info_msg->K[0]); + Eigen::Map> cameraMatrix(&camera_info_msg->K[0]); // Get pose of sensor in map frame tf::StampedTransform transformTf; @@ -389,7 +390,8 @@ void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image } // Pass image to pipeline - map_.input_image(key, multichannel_image, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, image.rows, image.cols); + map_.input_image(key, multichannel_image, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, + image.rows, image.cols); ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); } @@ -409,7 +411,7 @@ void ElevationMappingNode::updatePose(const ros::TimerEvent&) { // This is to check if the robot is moving. If the robot is not moving, drift compensation is disabled to avoid creating artifacts. Eigen::Vector3d position(transformTf.getOrigin().x(), transformTf.getOrigin().y(), transformTf.getOrigin().z()); - map_.move_to(position,transformationBaseToMap.rotation().transpose()); + map_.move_to(position, transformationBaseToMap.rotation().transpose()); Eigen::Vector3d position3(transformTf.getOrigin().x(), transformTf.getOrigin().y(), transformTf.getOrigin().z()); Eigen::Vector4d orientation(transformTf.getRotation().x(), transformTf.getRotation().y(), transformTf.getRotation().z(), transformTf.getRotation().w()); diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 1e5541ed..74027bb9 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -80,14 +80,14 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { nh.getParam("subscribers", subscribers); py::dict sub_dict; - for (auto & subscriber : subscribers) { - const char *const name = subscriber.first.c_str(); - const auto & subscriber_params = subscriber.second; + for (auto& subscriber : subscribers) { + const char* const name = subscriber.first.c_str(); + const auto& subscriber_params = subscriber.second; if (!sub_dict.contains(name)) { sub_dict[name] = py::dict(); } - for(auto iterat : subscriber_params){ - const char *const key = iterat.first.c_str(); + for (auto iterat : subscriber_params) { + const char* const key = iterat.first.c_str(); const auto val = iterat.second; std::vector arr; switch (val.getType()) { @@ -107,7 +107,7 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { for (int32_t i = 0; i < val.size(); ++i) { auto elem = static_cast(val[i]); arr.push_back(elem); - } + } sub_dict[name][key] = arr; arr.clear(); break; @@ -130,32 +130,23 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { nh.param("enable_normal_color", enable_normal_color_, false); } -void ElevationMappingWrapper::input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, - const double positionNoise, const double orientationNoise) { +void ElevationMappingWrapper::input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, + const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise) { py::gil_scoped_acquire acquire; - map_.attr("input")(Eigen::Ref(points), channels, Eigen::Ref(R), Eigen::Ref(t), - positionNoise, orientationNoise); + map_.attr("input")(Eigen::Ref(points), channels, Eigen::Ref(R), + Eigen::Ref(t), positionNoise, orientationNoise); } -void ElevationMappingWrapper::input_image(const std::string& key, const std::vector& multichannel_image, - const RowMatrixXd& R, - const Eigen::VectorXd& t, - const RowMatrixXd& cameraMatrix, - int height, - int width) { +void ElevationMappingWrapper::input_image(const std::string& key, const std::vector& multichannel_image, const RowMatrixXd& R, + const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, int height, int width) { py::gil_scoped_acquire acquire; - map_.attr("input_image")(key, - multichannel_image, - Eigen::Ref(R), - Eigen::Ref(t), - Eigen::Ref(cameraMatrix), - height, - width); + map_.attr("input_image")(key, multichannel_image, Eigen::Ref(R), Eigen::Ref(t), + Eigen::Ref(cameraMatrix), height, width); } -void ElevationMappingWrapper::move_to(const Eigen::VectorXd& p, const RowMatrixXd& R) { +void ElevationMappingWrapper::move_to(const Eigen::VectorXd& p, const RowMatrixXd& R) { py::gil_scoped_acquire acquire; - map_.attr("move_to")(Eigen::Ref(p), Eigen::Ref(R)); + map_.attr("move_to")(Eigen::Ref(p), Eigen::Ref(R)); } void ElevationMappingWrapper::clear() { @@ -259,7 +250,6 @@ void ElevationMappingWrapper::initializeWithPoints(std::vector& map_.attr("initialize_map")(Eigen::Ref(points_m), method); } - void ElevationMappingWrapper::addNormalColorLayer(grid_map::GridMap& map) { const auto& normalX = map["normal_x"]; const auto& normalY = map["normal_y"]; diff --git a/plane_segmentation/README.md b/plane_segmentation/README.md index 2d7c2f56..d9c17ae7 100644 --- a/plane_segmentation/README.md +++ b/plane_segmentation/README.md @@ -1,35 +1,45 @@ # Plane Segmentation ## Overview + This is a C++ ROS package for extracting convex polygons from elevation maps. In a first step, the terrain is segmented into planes, and their non-convex contour is extracted. In a second step, a local convex approximation can be obtained. ## Usage + ### Build + ```bash catkin build convex_plane_decomposition_ros ``` ### Run as node + ```bash roslaunch convex_plane_decomposition_ros convex_plane_decomposition.launch ``` ### Run demo + ```bash roslaunch convex_plane_decomposition_ros demo.launch ``` ### Convex approximation demo + A simple 2D demo the convex inner approximation is available: + ```bash rosrun convex_plane_decomposition_ros convex_plane_decomposition_ros_TestShapeGrowing ``` ### Parameters + You can select input map topics, pipeline parameters etc. in the respective yaml file in + ```bash convex_plane_decomposition_ros/config/ ``` + Some other parameters are set through the launch files. diff --git a/plane_segmentation/cgal5_catkin/README.md b/plane_segmentation/cgal5_catkin/README.md index 6079c91e..af601fd7 100644 --- a/plane_segmentation/cgal5_catkin/README.md +++ b/plane_segmentation/cgal5_catkin/README.md @@ -1,2 +1,3 @@ # cgal5_catkin + Catkin wrapper of the Computational Geometry Algorithms Library (CGAL) diff --git a/plane_segmentation/cgal5_catkin/package.xml b/plane_segmentation/cgal5_catkin/package.xml index 4cbb5614..9c3cf37a 100644 --- a/plane_segmentation/cgal5_catkin/package.xml +++ b/plane_segmentation/cgal5_catkin/package.xml @@ -1,13 +1,13 @@ - cgal5_catkin - 5.0.2 - Catkin wrapper for CGAL 5. - Ruben Grandia + cgal5_catkin + 5.0.2 + Catkin wrapper for CGAL 5. + Ruben Grandia - See package + See package - catkin - libgmp-dev - libmpfr-dev + catkin + libgmp-dev + libmpfr-dev diff --git a/plane_segmentation/convex_plane_decomposition/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition/CMakeLists.txt index 52bb1bc7..2deb335a 100644 --- a/plane_segmentation/convex_plane_decomposition/CMakeLists.txt +++ b/plane_segmentation/convex_plane_decomposition/CMakeLists.txt @@ -3,10 +3,10 @@ project(convex_plane_decomposition) # Catkin dependencies set(CATKIN_PACKAGE_DEPENDENCIES - cgal5_catkin - grid_map_core - grid_map_cv - grid_map_filters_rsl + cgal5_catkin + grid_map_core + grid_map_cv + grid_map_filters_rsl ) find_package(catkin REQUIRED COMPONENTS @@ -33,14 +33,14 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) ################################### catkin_package( INCLUDE_DIRS - include - ${EIGEN3_INCLUDE_DIRS} + include + ${EIGEN3_INCLUDE_DIRS} LIBRARIES - ${PROJECT_NAME} + ${PROJECT_NAME} CATKIN_DEPENDS - ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS - OpenCV GMP MPFR Boost + ${CATKIN_PACKAGE_DEPENDENCIES} + DEPENDS + OpenCV GMP MPFR Boost ) ########### @@ -68,16 +68,16 @@ add_library(${PROJECT_NAME} src/SegmentedPlaneProjection.cpp ) add_dependencies(${PROJECT_NAME} - ${catkin_EXPORTED_TARGETS} + ${catkin_EXPORTED_TARGETS} ) target_link_libraries(${PROJECT_NAME} - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - gmp - mpfr + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + gmp + mpfr ) target_compile_options(${PROJECT_NAME} - PUBLIC -DCGAL_HAS_THREADS + PUBLIC -DCGAL_HAS_THREADS ) ############# @@ -90,7 +90,7 @@ install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) install(DIRECTORY include/${PROJECT_NAME}/ - DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} ) ############# @@ -98,17 +98,17 @@ install(DIRECTORY include/${PROJECT_NAME}/ ############# catkin_add_gtest(test_${PROJECT_NAME} - test/testConvexApproximation.cpp - test/testPipeline.cpp - test/testPlanarRegion.cpp - test/testRegionGrowing.cpp - test/testUpsampling.cpp + test/testConvexApproximation.cpp + test/testPipeline.cpp + test/testPlanarRegion.cpp + test/testRegionGrowing.cpp + test/testUpsampling.cpp ) target_link_libraries(test_${PROJECT_NAME} - ${PROJECT_NAME} - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - gmp - mpfr - gtest_main + ${PROJECT_NAME} + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + gmp + mpfr + gtest_main ) diff --git a/plane_segmentation/convex_plane_decomposition/package.xml b/plane_segmentation/convex_plane_decomposition/package.xml index b4627803..5ccbe03f 100644 --- a/plane_segmentation/convex_plane_decomposition/package.xml +++ b/plane_segmentation/convex_plane_decomposition/package.xml @@ -1,17 +1,17 @@ - convex_plane_decomposition - 0.0.0 - The convex_plane_decomposition package + convex_plane_decomposition + 0.0.0 + The convex_plane_decomposition package - Ruben Grandia + Ruben Grandia - MIT + MIT - catkin - cgal5_catkin - grid_map_core - grid_map_cv - grid_map_filters_rsl + catkin + cgal5_catkin + grid_map_core + grid_map_cv + grid_map_filters_rsl diff --git a/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt index d5f762ef..f94b85c6 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt +++ b/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt @@ -3,20 +3,20 @@ project(convex_plane_decomposition_ros) # Catkin dependencies set(CATKIN_PACKAGE_DEPENDENCIES - roscpp - grid_map_core - grid_map_ros - grid_map_cv - grid_map_msgs - geometry_msgs - convex_plane_decomposition - convex_plane_decomposition_msgs - tf2_ros - visualization_msgs + roscpp + grid_map_core + grid_map_ros + grid_map_cv + grid_map_msgs + geometry_msgs + convex_plane_decomposition + convex_plane_decomposition_msgs + tf2_ros + visualization_msgs ) find_package(catkin REQUIRED COMPONENTS - ${CATKIN_PACKAGE_DEPENDENCIES} + ${CATKIN_PACKAGE_DEPENDENCIES} ) # OpenCv @@ -33,10 +33,10 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) ## catkin specific configuration ## ################################### catkin_package( - INCLUDE_DIRS include ${EIGEN3_INCLUDE_DIRS} - LIBRARIES ${PROJECT_NAME} - CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS OpenCV + INCLUDE_DIRS include ${EIGEN3_INCLUDE_DIRS} + LIBRARIES ${PROJECT_NAME} + CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} + DEPENDS OpenCV ) ########### @@ -44,86 +44,86 @@ catkin_package( ########### include_directories( - include - ${EIGEN3_INCLUDE_DIRS} - ${catkin_INCLUDE_DIRS} + include + ${EIGEN3_INCLUDE_DIRS} + ${catkin_INCLUDE_DIRS} ) add_library(${PROJECT_NAME} - src/ConvexPlaneDecompositionRos.cpp - src/MessageConversion.cpp - src/ParameterLoading.cpp - src/RosVisualizations.cpp - ) + src/ConvexPlaneDecompositionRos.cpp + src/MessageConversion.cpp + src/ParameterLoading.cpp + src/RosVisualizations.cpp + ) add_dependencies(${PROJECT_NAME} - ${catkin_EXPORTED_TARGETS} - ) + ${catkin_EXPORTED_TARGETS} + ) target_link_libraries(${PROJECT_NAME} - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - ) + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + ) add_executable(${PROJECT_NAME}_node - src/ConvexPlaneDecompositionNode.cpp + src/ConvexPlaneDecompositionNode.cpp ) target_link_libraries(${PROJECT_NAME}_node - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - ${PROJECT_NAME} + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + ${PROJECT_NAME} ) add_executable(${PROJECT_NAME}_add_noise - src/noiseNode.cpp + src/noiseNode.cpp ) target_link_libraries(${PROJECT_NAME}_add_noise - ${catkin_LIBRARIES} + ${catkin_LIBRARIES} ) add_executable(${PROJECT_NAME}_save_elevationmap - src/SaveElevationMapAsImageNode.cpp - ) + src/SaveElevationMapAsImageNode.cpp + ) target_link_libraries(${PROJECT_NAME}_save_elevationmap - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - ) + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + ) add_executable(${PROJECT_NAME}_approximation_demo_node - src/ConvexApproximationDemoNode.cpp - ) + src/ConvexApproximationDemoNode.cpp + ) target_link_libraries(${PROJECT_NAME}_approximation_demo_node - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - ${PROJECT_NAME} - ) + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} + ${PROJECT_NAME} + ) ############# ## Install ## ############# install(TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} - ) + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} + ) install(DIRECTORY include/${PROJECT_NAME}/ - DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} - ) + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} + ) install(TARGETS ${PROJECT_NAME}_node - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) install(DIRECTORY config data launch rviz - DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} + DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} ) ############# ## Testing ## ############# add_executable(${PROJECT_NAME}_TestShapeGrowing - test/TestShapeGrowing.cpp + test/TestShapeGrowing.cpp ) target_link_libraries(${PROJECT_NAME}_TestShapeGrowing - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} + ${catkin_LIBRARIES} + ${OpenCV_LIBRARIES} ) \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch index d72f65e1..6f7053b6 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch +++ b/plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch @@ -1,13 +1,14 @@ - - + + - - - - - + + + + + diff --git a/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch index ede2f06f..d592db55 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch +++ b/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch @@ -1,48 +1,52 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plane_segmentation/convex_plane_decomposition_ros/launch/save_elevation_map.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/save_elevation_map.launch index 702525a3..4197e474 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/launch/save_elevation_map.launch +++ b/plane_segmentation/convex_plane_decomposition_ros/launch/save_elevation_map.launch @@ -1,11 +1,11 @@ - - - - - + + + + + diff --git a/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz b/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz index 93666180..0d306212 100644 --- a/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz +++ b/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz @@ -46,7 +46,7 @@ Visualization Manager: Marker Topic: /convex_plane_decomposition_ros/insets Name: Insets Namespaces: - {} + { } Queue Size: 100 Value: false - Alpha: 0.10000000149011612 diff --git a/plane_segmentation/grid_map_filters_rsl/package.xml b/plane_segmentation/grid_map_filters_rsl/package.xml index 481135ce..3df62480 100644 --- a/plane_segmentation/grid_map_filters_rsl/package.xml +++ b/plane_segmentation/grid_map_filters_rsl/package.xml @@ -1,19 +1,19 @@ - grid_map_filters_rsl - 0.1.0 - Extension of grid map filters package with op-cv filters and others - Fabian Jenelten + grid_map_filters_rsl + 0.1.0 + Extension of grid map filters package with op-cv filters and others + Fabian Jenelten - Fabian Jenelten + Fabian Jenelten - MIT + MIT - catkin - cmake_clang_tools - grid_map_cv - grid_map_core + catkin + cmake_clang_tools + grid_map_cv + grid_map_core - gtest - cmake_code_coverage + gtest + cmake_code_coverage diff --git a/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml b/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml index de553513..e448f9ab 100644 --- a/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml +++ b/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml @@ -1,11 +1,11 @@ subscribers: -# sensor_name: -# channels: ['feat_0','feat_1'] -# fusion: ['average','average'] -# topic_name: '/elevation_mapping/pointcloud_semantic' + # sensor_name: + # channels: ['feat_0','feat_1'] + # fusion: ['average','average'] + # topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: - channels: ['rgb'] #'feat_0','feat_1','person','grass'] - fusion: ['color'] #'average','average','class_average','class_average'] + channels: [ 'rgb' ] #'feat_0','feat_1','person','grass'] + fusion: [ 'color' ] #'average','average','class_average','class_average'] topic_name: '/elvation_mapping/pointcloud_semantic' semantic_segmentation: False segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' @@ -15,11 +15,11 @@ subscribers: name: 'DINO' interpolation: 'bilinear' model: "vit_small" - patch_size: 16 + patch_size: 16 dim: 5 dropout: False dino_feat_type: "feat" - input_size: [80, 160] + input_size: [ 80, 160 ] projection_type: "nonlinear" cam_info_topic: "/zed2i/zed_node/depth/camera_info" diff --git a/sensor_processing/semantic_pointcloud/launch/semantic_pointcloud.launch b/sensor_processing/semantic_pointcloud/launch/semantic_pointcloud.launch index ec49e082..e1aa1b85 100644 --- a/sensor_processing/semantic_pointcloud/launch/semantic_pointcloud.launch +++ b/sensor_processing/semantic_pointcloud/launch/semantic_pointcloud.launch @@ -1,7 +1,7 @@ - - - + + \ No newline at end of file diff --git a/sensor_processing/semantic_pointcloud/package.xml b/sensor_processing/semantic_pointcloud/package.xml index 00cb393f..ce51aa4a 100644 --- a/sensor_processing/semantic_pointcloud/package.xml +++ b/sensor_processing/semantic_pointcloud/package.xml @@ -1,28 +1,27 @@ - semantic_pointcloud - 0.0.0 - The semantic_pointcloud package - Gian Erni + semantic_pointcloud + 0.0.0 + The semantic_pointcloud package + Gian Erni + MIT - MIT + https://github.com/leggedrobotics/elevation_mapping_semantic_cupy - https://github.com/leggedrobotics/elevation_mapping_semantic_cupy + Gian Erni - Gian Erni - - catkin - rospy - roslib - tf - tf_conversions - sensor_msgs - std_msgs - geometry_msgs + catkin + rospy + roslib + tf + tf_conversions + sensor_msgs + std_msgs + geometry_msgs diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py index ebd9dcc8..e047d3df 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py @@ -3,7 +3,7 @@ lraspp_mobilenet_v3_large, LRASPP_MobileNet_V3_Large_Weights, ) -from torchvision.models.segmentation import (deeplabv3_mobilenet_v3_large, DeepLabV3_MobileNet_V3_Large_Weights ) +from torchvision.models.segmentation import deeplabv3_mobilenet_v3_large, DeepLabV3_MobileNet_V3_Large_Weights import torch import torchvision.transforms.functional as TF from torchvision.transforms import Resize diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py index 42ad5085..8e0bcc5f 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py @@ -184,7 +184,7 @@ def cam_info_callback(self, msg): self.width = msg.width self.header = msg.header - def image_callback(self, depth_msg, rgb_msg=None,confidence_msg=None): + def image_callback(self, depth_msg, rgb_msg=None, confidence_msg=None): confidence = None image = None if self.P is None: From 0cdc97f462d8357ddb222949c2d8bed388e24320 Mon Sep 17 00:00:00 2001 From: Gian Date: Fri, 10 Feb 2023 14:38:37 +0100 Subject: [PATCH 338/504] added resize but there is still some error in resize --- .github/workflows/python-tests.yml | 4 +- docs/source/conf.py | 2 +- docs/source/python/index.rst | 2 +- ...tic_pointcloud.rst => semantic_sensor.rst} | 4 +- .../launch/lonomy_pointcloud.launch | 2 +- .../lonomy_semantic_elevation_single.launch | 2 +- .../sim_semantic_elevation_single.launch | 2 +- .../launch/turtlesim_pointcloud.launch | 2 +- .../rviz/lonomy_single.rviz | 2 +- .../plugins/features_pca.py | 2 +- .../launch/semantic_pointcloud.launch | 7 --- .../CMakeLists.txt | 4 +- .../config/sensor_parameter.yaml | 0 .../launch/semantic_pointcloud.launch | 7 +++ .../package.xml | 4 +- .../script/semantic_sensor}/DINO/__init__.py | 0 .../script/semantic_sensor}/DINO/modules.py | 2 +- .../script/semantic_sensor}/DINO/utils.py | 0 .../DINO/vision_transformer.py | 2 +- .../script/semantic_sensor}/__init__.py | 0 .../script/semantic_sensor/image_node.py} | 59 +++++++++++++++---- .../semantic_sensor/image_parameters.py} | 5 +- .../script/semantic_sensor}/networks.py | 10 ++-- .../semantic_sensor}/pointcloud_node.py | 10 ++-- .../semantic_sensor}/pointcloud_parameters.py | 5 +- .../script/semantic_sensor}/tests/__init__.py | 0 .../semantic_sensor}/tests/test_pointcloud.py | 0 .../semantic_sensor}/tests/test_utils.py | 4 +- .../script/semantic_sensor}/utils.py | 0 .../setup.py | 2 +- 30 files changed, 92 insertions(+), 53 deletions(-) rename docs/source/python/{semantic_pointcloud.rst => semantic_sensor.rst} (57%) delete mode 100644 sensor_processing/semantic_pointcloud/launch/semantic_pointcloud.launch rename sensor_processing/{semantic_pointcloud => semantic_sensor}/CMakeLists.txt (81%) rename sensor_processing/{semantic_pointcloud => semantic_sensor}/config/sensor_parameter.yaml (100%) create mode 100644 sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch rename sensor_processing/{semantic_pointcloud => semantic_sensor}/package.xml (85%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud => semantic_sensor/script/semantic_sensor}/DINO/__init__.py (100%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud => semantic_sensor/script/semantic_sensor}/DINO/modules.py (98%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud => semantic_sensor/script/semantic_sensor}/DINO/utils.py (100%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud => semantic_sensor/script/semantic_sensor}/DINO/vision_transformer.py (99%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud => semantic_sensor/script/semantic_sensor}/__init__.py (100%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_node.py => semantic_sensor/script/semantic_sensor/image_node.py} (81%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_parameters.py => semantic_sensor/script/semantic_sensor/image_parameters.py} (90%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud => semantic_sensor/script/semantic_sensor}/networks.py (97%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud => semantic_sensor/script/semantic_sensor}/pointcloud_node.py (97%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud => semantic_sensor/script/semantic_sensor}/pointcloud_parameters.py (91%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud => semantic_sensor/script/semantic_sensor}/tests/__init__.py (100%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud => semantic_sensor/script/semantic_sensor}/tests/test_pointcloud.py (100%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud => semantic_sensor/script/semantic_sensor}/tests/test_utils.py (92%) rename sensor_processing/{semantic_pointcloud/script/semantic_pointcloud => semantic_sensor/script/semantic_sensor}/utils.py (100%) rename sensor_processing/{semantic_pointcloud => semantic_sensor}/setup.py (87%) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 00e81d4a..0f341544 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -34,7 +34,7 @@ jobs: run: | cd elevation_mapping_cupy/script/elevation_mapping_cupy/tests/ pytest - - name: Test semantic_pointcloud with pytest + - name: Test semantic_sensor with pytest run: | - cd sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests + cd sensor_processing/semantic_sensor/script/semantic_sensor/tests pytest test_utils.py diff --git a/docs/source/conf.py b/docs/source/conf.py index d761f2ff..c2b0da13 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -9,7 +9,7 @@ import os, sys sys.path.insert(0, os.path.abspath("../../elevation_mapping_cupy")) -sys.path.insert(0, os.path.abspath("../../sensor_processing/semantic_pointcloud")) +sys.path.insert(0, os.path.abspath("../../sensor_processing/semantic_sensor")) on_rtd = os.environ.get("READTHEDOCS", None) == "True" diff --git a/docs/source/python/index.rst b/docs/source/python/index.rst index f20f2e59..bf697bf9 100644 --- a/docs/source/python/index.rst +++ b/docs/source/python/index.rst @@ -3,6 +3,6 @@ Python software .. toctree:: elevation_mapping - semantic_pointcloud + semantic_sensor custom_kernels diff --git a/docs/source/python/semantic_pointcloud.rst b/docs/source/python/semantic_sensor.rst similarity index 57% rename from docs/source/python/semantic_pointcloud.rst rename to docs/source/python/semantic_sensor.rst index 03de3521..f3f8aa5e 100644 --- a/docs/source/python/semantic_pointcloud.rst +++ b/docs/source/python/semantic_sensor.rst @@ -1,8 +1,8 @@ -.. _semantic_pointcloud: +.. _semantic_sensor: Semantic Pointcloud ****************************************************************** -.. automodule:: semantic_pointcloud.pointcloud_node +.. automodule:: semantic_sensor.pointcloud_node :members: diff --git a/elevation_mapping_cupy/launch/lonomy_pointcloud.launch b/elevation_mapping_cupy/launch/lonomy_pointcloud.launch index d9ad8ecd..fe16229d 100644 --- a/elevation_mapping_cupy/launch/lonomy_pointcloud.launch +++ b/elevation_mapping_cupy/launch/lonomy_pointcloud.launch @@ -5,7 +5,7 @@ - diff --git a/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch index eac2fc20..dbd98f95 100644 --- a/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch +++ b/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch @@ -5,7 +5,7 @@ - diff --git a/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch index cc16152c..632b4bfd 100644 --- a/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch +++ b/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch @@ -5,7 +5,7 @@ - + diff --git a/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch b/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch index 8a1e7893..225b5b79 100644 --- a/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch +++ b/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch @@ -10,7 +10,7 @@ - diff --git a/elevation_mapping_cupy/rviz/lonomy_single.rviz b/elevation_mapping_cupy/rviz/lonomy_single.rviz index 5907e933..2544ffe9 100644 --- a/elevation_mapping_cupy/rviz/lonomy_single.rviz +++ b/elevation_mapping_cupy/rviz/lonomy_single.rviz @@ -377,7 +377,7 @@ Visualization Manager: Value: true - Class: rviz/Image Enabled: true - Image Topic: /semantic_pointcloud/sem_seg + Image Topic: /semantic_sensor/sem_seg Max Value: 1 Median window: 5 Min Value: 0 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py index f6e6506d..b0228870 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py @@ -59,7 +59,7 @@ def __call__( # check which has the highest value if len(layer_indices) > 0: data = cp.reshape(semantic_map.semantic_map[layer_indices], (len(layer_indices), -1)).T.get() - data = np.clip(data, -1, 1) + # data = np.clip(data, -1, 1) n_components = 3 pca = PCA(n_components=n_components).fit(data) pca_descriptors = pca.transform(data) diff --git a/sensor_processing/semantic_pointcloud/launch/semantic_pointcloud.launch b/sensor_processing/semantic_pointcloud/launch/semantic_pointcloud.launch deleted file mode 100644 index e1aa1b85..00000000 --- a/sensor_processing/semantic_pointcloud/launch/semantic_pointcloud.launch +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/sensor_processing/semantic_pointcloud/CMakeLists.txt b/sensor_processing/semantic_sensor/CMakeLists.txt similarity index 81% rename from sensor_processing/semantic_pointcloud/CMakeLists.txt rename to sensor_processing/semantic_sensor/CMakeLists.txt index de10670f..bdc8a1b7 100644 --- a/sensor_processing/semantic_pointcloud/CMakeLists.txt +++ b/sensor_processing/semantic_sensor/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.0.2) -project(semantic_pointcloud) +project(semantic_sensor) find_package(PythonInterp 3 REQUIRED) find_package(PythonLibs 3 REQUIRED) @@ -28,6 +28,6 @@ catkin_python_setup() -catkin_install_python(PROGRAMS script/semantic_pointcloud/pointcloud_node.py +catkin_install_python(PROGRAMS script/semantic_sensor/pointcloud_node.py script/semantic_sensor/image_node.py DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) diff --git a/sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml b/sensor_processing/semantic_sensor/config/sensor_parameter.yaml similarity index 100% rename from sensor_processing/semantic_pointcloud/config/sensor_parameter.yaml rename to sensor_processing/semantic_sensor/config/sensor_parameter.yaml diff --git a/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch b/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch new file mode 100644 index 00000000..550638ff --- /dev/null +++ b/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/sensor_processing/semantic_pointcloud/package.xml b/sensor_processing/semantic_sensor/package.xml similarity index 85% rename from sensor_processing/semantic_pointcloud/package.xml rename to sensor_processing/semantic_sensor/package.xml index ce51aa4a..635775eb 100644 --- a/sensor_processing/semantic_pointcloud/package.xml +++ b/sensor_processing/semantic_sensor/package.xml @@ -1,8 +1,8 @@ - semantic_pointcloud + semantic_sensor 0.0.0 - The semantic_pointcloud package + The semantic_sensor package Gian Erni diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/__init__.py b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/__init__.py similarity index 100% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/__init__.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/DINO/__init__.py diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/modules.py b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py similarity index 98% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/modules.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py index 70603751..0f6edb44 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/modules.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py @@ -1,4 +1,4 @@ -import semantic_pointcloud.DINO.vision_transformer as vits +import semantic_sensor.DINO.vision_transformer as vits import torch.nn as nn import torch diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/utils.py b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/utils.py similarity index 100% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/utils.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/DINO/utils.py diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/vision_transformer.py b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py similarity index 99% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/vision_transformer.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py index 399b7c1d..7604c1cd 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/DINO/vision_transformer.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py @@ -7,7 +7,7 @@ import torch import torch.nn as nn -from semantic_pointcloud.DINO.utils import trunc_normal_ +from semantic_sensor.DINO.utils import trunc_normal_ def drop_path(x, drop_prob: float = 0.0, training: bool = False): diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/__init__.py b/sensor_processing/semantic_sensor/script/semantic_sensor/__init__.py similarity index 100% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/__init__.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/__init__.py diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py similarity index 81% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_node.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py index c373f84f..20716a6f 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_node.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py @@ -5,6 +5,7 @@ import numpy as np import cupy as cp +import cv2 import ros_numpy import matplotlib.pyplot as plt from skimage.io import imshow @@ -14,8 +15,8 @@ from sensor_msgs.msg import PointCloud2, Image, CompressedImage from cv_bridge import CvBridge -from semantic_pointcloud.semantic_segmentation_parameters import SemanticSegmentationParameter -from semantic_pointcloud.networks import resolve_model +from semantic_sensor.image_parameters import ImageParameter +from semantic_sensor.networks import resolve_model from sklearn.decomposition import PCA @@ -27,12 +28,12 @@ def __init__(self, sensor_name): sensor_name (str): Name of the sensor in the ros param server. """ # TODO: if this is going to be loaded from another package we might need to change namespace - self.param: SemanticSegmentationParameter = SemanticSegmentationParameter() + self.param: ImageParameter = ImageParameter() self.param.feature_config.input_size = [80, 160] namesp = rospy.get_name() if rospy.has_param(namesp + "/subscribers"): config = rospy.get_param(namesp + "/subscribers") - self.param: SemanticSegmentationParameter = SemanticSegmentationParameter.from_dict(config[sensor_name]) + self.param: ImageParameter = ImageParameter.from_dict(config[sensor_name]) else: print("NO ROS ENV found.") @@ -63,11 +64,15 @@ def initialize_semantics(self): def register_sub_pub(self): """Register publishers and subscribers.""" # subscribers + if self.param.image_info_topic is not None and self.param.resize is not None: + rospy.Subscriber(self.param.image_info_topic, CameraInfo, self.image_info_callback) + self.feat_im_info_pub = rospy.Publisher(self.param.image_info_topic + "_resized", CameraInfo, queue_size=2) + if "compressed" in self.param.image_topic: self.compressed = True - self.subscriber = rospy.Subscriber(self.param.image_topic, - CompressedImage, self.image_callback, queue_size=2) - print("Subscribing to compressed image topic: {}".format(self.param.image_topic)) + self.subscriber = rospy.Subscriber( + self.param.image_topic, CompressedImage, self.image_callback, queue_size=2 + ) else: self.compressed = False rospy.Subscriber(self.param.image_topic, Image, self.image_callback) @@ -83,7 +88,6 @@ def register_sub_pub(self): self.feature_pub = rospy.Publisher(self.param.feature_topic, Image, queue_size=2) self.feat_im_pub = rospy.Publisher(self.param.feat_image_topic, Image, queue_size=2) - def color_map(self, N=256, normalized=False): """Create a color map for the class labels. @@ -126,11 +130,30 @@ def color_map_viz(self): plt.xticks([]) plt.show() + def image_info_callback(self, msg): + """Callback for camera info. + + Args: + msg (CameraInfo): + """ + self.P = np.array(msg.P).reshape(3, 4) + self.height = int(self.param.resize * msg.height) + self.width = int(self.param.resize * msg.width) + self.info = msg + def image_callback(self, rgb_msg): + if self.P is None: + return if self.compressed: - image = cp.asarray(self.cv_bridge.compressed_imgmsg_to_cv2(rgb_msg)) + image = self.cv_bridge.compressed_imgmsg_to_cv2(rgb_msg) + if self.param.resize is not None: + image = cv2.resize(image, dsize=(self.width, self.height)) + image = cp.asarray(image) else: - image = cp.asarray(self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8")) + image = self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8") + if self.param.resize is not None: + image = cv2.resize(image, dsize=(self.width, self.height)) + image = cp.asarray(image) self.header = rgb_msg.header self.process_image(image) @@ -140,6 +163,17 @@ def image_callback(self, rgb_msg): if self.param.feature_extractor: self.publish_feature() self.publish_feature_image(self.features) + if self.param.resize is not None: + self.pub_info() + + def pub_info(self): + info_msg = self.info + info_msg.height = self.height + info_msg.width = self.width + self.P[:2, :] *= self.param.resize + info_msg.K = self.P[:3, :3].flatten().tolist() + info_msg.P = self.P.flatten().tolist() + self.feat_im_info_pub.publish(info_msg) def process_image(self, image): """Depending on setting generate color, semantic segmentation or feature channels. @@ -150,7 +184,6 @@ def process_image(self, image): v: points: """ - if self.param.semantic_segmentation: self.sem_seg = self.semantic_model["model"](image) @@ -175,7 +208,6 @@ def publish_feature(self): feature_msg.header.stamp = self.header.stamp self.feature_pub.publish(feature_msg) - def publish_segmentation_image(self): colors = None probabilities = self.sem_seg @@ -217,7 +249,7 @@ def publish_feature_image(self, features): pca = PCA(n_components=n_components).fit(data) pca_descriptors = pca.transform(data) img_pca = pca_descriptors.reshape(features.shape[1], features.shape[2], n_components) - comp = img_pca #[:, :, -3:] + comp = img_pca # [:, :, -3:] comp_min = comp.min(axis=(0, 1)) comp_max = comp.max(axis=(0, 1)) comp_img = (comp - comp_min) / (comp_max - comp_min) @@ -226,6 +258,7 @@ def publish_feature_image(self, features): feat_msg.header.frame_id = self.header.frame_id self.feat_im_pub.publish(feat_msg) + if __name__ == "__main__": arg = sys.argv[1] sensor_name = arg diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_parameters.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py similarity index 90% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_parameters.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py index 4075eb99..0df6fe57 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/semantic_segmentation_parameters.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py @@ -13,10 +13,11 @@ class FeatureExtractorParameter(Serializable): dino_feat_type: str = "feat" projection_type: str = "nonlinear" input_size: list = field(default_factory=lambda: [80, 160]) + pcl: bool = False @dataclass -class SemanticSegmentationParameter(Serializable): +class ImageParameter(Serializable): image_topic: str = "/alphasense_driver_ros/cam4/debayered" semantic_segmentation: bool = True @@ -32,4 +33,6 @@ class SemanticSegmentationParameter(Serializable): # feature_config.input_size: list = field(default_factory=lambda: [80, 160]) feature_topic: str = "/elevation_mapping/semantic_seg_feat" feat_image_topic: str = "/elevation_mapping/semantic_seg_feat_im" + resize: float = None + image_info_topic: str = "/elevation_mapping/image_info" diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py similarity index 97% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/networks.py index e04ea9c1..f3fc0b50 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/networks.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py @@ -20,13 +20,13 @@ from detectron2.config import get_cfg from detectron2.data import MetadataCatalog -from semantic_pointcloud.DINO.modules import DinoFeaturizer +from semantic_sensor.DINO.modules import DinoFeaturizer -from semantic_pointcloud.pointcloud_parameters import ( +from semantic_sensor.pointcloud_parameters import ( PointcloudParameter, FeatureExtractorParameter, ) -from semantic_pointcloud.utils import encode_max +from semantic_sensor.utils import encode_max def resolve_model(name, config=None): @@ -276,6 +276,7 @@ def to_tensor(self, data): def __call__(self, image, *args, **kwargs): # image = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) image = self.to_tensor(image).unsqueeze(0) + # if self.cfg.pcl: reset_size = Resize(image.shape[-2:]) image = self.shrink(image) image = TF.normalize(image, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)) @@ -284,6 +285,7 @@ def __call__(self, image, *args, **kwargs): feat2, code2 = self.model(image.flip(dims=[3])) code = (code1 + code2.flip(dims=[3])) / 2 code = NF.interpolate(code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False).detach() + # if self.cfg.pcl: code = reset_size(code) - code = torch.squeeze(code , dim=0) + code = torch.squeeze(code, dim=0) return code diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py similarity index 97% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py index 596d4671..7d991a2d 100755 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_node.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py @@ -12,9 +12,9 @@ from sensor_msgs.msg import PointCloud2, Image from cv_bridge import CvBridge -from semantic_pointcloud.pointcloud_parameters import PointcloudParameter -from semantic_pointcloud.networks import resolve_model -from semantic_pointcloud.utils import decode_max +from semantic_sensor.pointcloud_parameters import PointcloudParameter +from semantic_sensor.networks import resolve_model +from semantic_sensor.utils import decode_max from sklearn.decomposition import PCA @@ -28,8 +28,8 @@ def __init__(self, sensor_name): # TODO: if this is going to be loaded from another package we might need to change namespace self.param: PointcloudParameter = PointcloudParameter() self.param.feature_config.input_size = [80, 160] - if rospy.has_param("/semantic_pointcloud/subscribers"): - config = rospy.get_param("/semantic_pointcloud/subscribers") + if rospy.has_param("/semantic_sensor/subscribers"): + config = rospy.get_param("/semantic_sensor/subscribers") self.param: PointcloudParameter = PointcloudParameter.from_dict(config[sensor_name]) else: print("NO ROS ENV found.") diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py similarity index 91% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py index 9a329e19..08ac4541 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/pointcloud_parameters.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py @@ -13,7 +13,8 @@ class FeatureExtractorParameter(Serializable): dino_feat_type: str = "feat" projection_type: str = "nonlinear" input_size: list = field(default_factory=lambda: [80, 160]) - feature_image_topic: str = "/semantic_pointcloud/feature_image" + feature_image_topic: str = "/semantic_sensor/feature_image" + pcl: bool = True @dataclass @@ -34,7 +35,7 @@ class PointcloudParameter(Serializable): semantic_segmentation: bool = False segmentation_model: str = "lraspp_mobilenet_v3_large" publish_segmentation_image: bool = False - segmentation_image_topic: str = "/semantic_pointcloud/sem_seg" + segmentation_image_topic: str = "/semantic_sensor/sem_seg" pub_all: bool = False show_label_legend: bool = False diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/__init__.py b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/__init__.py similarity index 100% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/__init__.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/tests/__init__.py diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py similarity index 100% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_pointcloud.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py similarity index 92% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py index 0bebfcc6..fdcc4c91 100644 --- a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/tests/test_utils.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py @@ -1,8 +1,8 @@ import pytest -from semantic_pointcloud.networks import resolve_model +from semantic_sensor.networks import resolve_model import cupy as cp import torch -from semantic_pointcloud.pointcloud_parameters import ( +from semantic_sensor.pointcloud_parameters import ( FeatureExtractorParameter, PointcloudParameter, ) diff --git a/sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py b/sensor_processing/semantic_sensor/script/semantic_sensor/utils.py similarity index 100% rename from sensor_processing/semantic_pointcloud/script/semantic_pointcloud/utils.py rename to sensor_processing/semantic_sensor/script/semantic_sensor/utils.py diff --git a/sensor_processing/semantic_pointcloud/setup.py b/sensor_processing/semantic_sensor/setup.py similarity index 87% rename from sensor_processing/semantic_pointcloud/setup.py rename to sensor_processing/semantic_sensor/setup.py index 1af8da13..e9e4d498 100644 --- a/sensor_processing/semantic_pointcloud/setup.py +++ b/sensor_processing/semantic_sensor/setup.py @@ -3,7 +3,7 @@ setup_args = generate_distutils_setup( packages=[ - "semantic_pointcloud", + "semantic_sensor", ], package_dir={"": "script"}, ) From 9bb1bd5d4a9148245c08bfad506965b4b98c6c27 Mon Sep 17 00:00:00 2001 From: Gian Date: Mon, 13 Feb 2023 20:42:22 +0100 Subject: [PATCH 339/504] fixing the projection --- .../script/semantic_sensor/DINO/modules.py | 52 +++- .../DINO/vision_transformer.py | 19 +- .../script/semantic_sensor/feature.ipynb | 263 ++++++++++++++++++ .../script/semantic_sensor/image_node.py | 14 +- .../script/semantic_sensor/networks.py | 14 +- .../semantic_sensor/pointcloud_parameters.py | 2 +- .../script/semantic_sensor/profile.stats | Bin 0 -> 2189606 bytes 7 files changed, 336 insertions(+), 28 deletions(-) create mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/feature.ipynb create mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/profile.stats diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py index 0f6edb44..24e4bff9 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py @@ -28,21 +28,6 @@ def __init__(self, weights, cfg): else: raise ValueError("Unknown arch and patch size") - # if cfg.pretrained_weights is not None: - # state_dict = torch.load(cfg.pretrained_weights, map_location="cpu") - # state_dict = state_dict["teacher"] - # # remove `module.` prefix - # state_dict = {k.replace("module.", ""): v for k, v in state_dict.items()} - # # remove `backbone.` prefix induced by multicrop wrapper - # state_dict = {k.replace("backbone.", ""): v for k, v in state_dict.items()} - # - # # state_dict = {k.replace("projection_head", "mlp"): v for k, v in state_dict.items()} - # # state_dict = {k.replace("prototypes", "last_layer"): v for k, v in state_dict.items()} - # - # msg = self.model.load_state_dict(state_dict, strict=False) - # print('Pretrained weights found at {} and loaded with msg: {}'.format(cfg.pretrained_weights, msg)) - # else: - # print("Since no pretrained weights have been provided, we load the reference pretrained DINO weights.") state_dict = torch.hub.load_state_dict_from_url(url="https://dl.fbaipublicfiles.com/dino/" + url) self.model.load_state_dict(state_dict, strict=True) @@ -57,9 +42,29 @@ def __init__(self, weights, cfg): self.cluster2 = self.make_nonlinear_clusterer(self.n_feats) def make_clusterer(self, in_channels): + """ + Function to make the clusterer model which consists of a single Conv2d layer. + The input channels are taken as the argument, and the output channels are equal to the `dim` of the model. + + Parameters: + in_channels (int): The number of input channels. + + Returns: + nn.Sequential: A sequential model consisting of a single Conv2d layer.""" + return torch.nn.Sequential(torch.nn.Conv2d(in_channels, self.dim, (1, 1))) # , def make_nonlinear_clusterer(self, in_channels): + """ + Function to make the nonlinear clusterer model which consists of a series of Conv2d and ReLU layers. + The input channels are taken as the argument, and the output channels are equal to the `dim` of the model. + + Parameters: + in_channels (int): The number of input channels. + + Returns: + nn.Sequential: A sequential model consisting of a Conv2d layer, a ReLU layer, and another Conv2d layer. + """ return torch.nn.Sequential( torch.nn.Conv2d(in_channels, in_channels, (1, 1)), torch.nn.ReLU(), @@ -67,6 +72,22 @@ def make_nonlinear_clusterer(self, in_channels): ) def forward(self, img, n=1, return_class_feat=False): + """ + Forward pass of the model. + The input image is passed through the `model` to get the intermediate features. + The intermediate features are then processed to get the final image feature and code. + If `return_class_feat` is set to True, the class features are returned instead. + + Parameters: + img (torch.Tensor): The input image tensor. + n (int, optional): The number of intermediate features to get. Default value is 1. 1 means only the features of the last block. + return_class_feat (bool, optional): Whether to return the class features. Default value is False. + + Returns: + tuple: If `cfg.dropout` is True, a tuple containing the final image feature and code is returned. + Otherwise, only the final image feature is returned. + If `return_class_feat` is True, the class features are returned instead. + """ self.model.eval() with torch.no_grad(): assert img.shape[2] % self.cfg.patch_size == 0 @@ -80,6 +101,7 @@ def forward(self, img, n=1, return_class_feat=False): feat_w = img.shape[3] // self.cfg.patch_size if self.feat_type == "feat": + # deflatten image_feat = feat[:, 1:, :].reshape(feat.shape[0], feat_h, feat_w, -1).permute(0, 3, 1, 2) elif self.feat_type == "KK": image_k = qkv[1, :, :, 1:, :].reshape(feat.shape[0], 6, feat_h, feat_w, -1) diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py index 7604c1cd..711c5b4e 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py @@ -69,28 +69,45 @@ def __init__( proj_drop=0.0, ): super().__init__() + # number of attention heads self.num_heads = num_heads + # dimension of each head head_dim = dim // num_heads + # scale factor for the attention scores self.scale = qk_scale or head_dim**-0.5 + # linear layer to project the input to 3 times the dimension self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) + # dropout layer to drop out activations in the attention mechanism self.attn_drop = nn.Dropout(attn_drop) + # linear layer to project the output back to the original dimension self.proj = nn.Linear(dim, dim) + # dropout layer to drop out activations in the projection layer self.proj_drop = nn.Dropout(proj_drop) def forward(self, x, return_qkv=False): + # get the batch size, sequence length, and input dimension B, N, C = x.shape + # project the input to 3 times the dimension, multiplication with W matrix qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) + # separate the input into queries: info about word in relation to others, keys: how one word influences others, and values: how word sees itself q, k, v = qkv[0], qkv[1], qkv[2] + # compute the attention scores attn = (q @ k.transpose(-2, -1)) * self.scale attn = attn.softmax(dim=-1) + # drop out activations in the attention mechanism attn = self.attn_drop(attn) + # compute the weighted sum of values x = (attn @ v).transpose(1, 2).reshape(B, N, C) + # project the output back to the original dimension x = self.proj(x) + # drop out activations in the projection layer x = self.proj_drop(x) - return x, attn, qkv + + # return the attention mechanism and the projected input + return x, attn, qkv if return_qkv else x class Block(nn.Module): diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/feature.ipynb b/sensor_processing/semantic_sensor/script/semantic_sensor/feature.ipynb new file mode 100644 index 00000000..5290835d --- /dev/null +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/feature.ipynb @@ -0,0 +1,263 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import torch\n", + "from semantic_sensor.networks import resolve_model\n", + "import os,yaml\n", + "from semantic_sensor.image_parameters import ImageParameter\n", + "from PIL import Image\n", + "import numpy as np\n", + "import cupy as cp\n", + "from sklearn.decomposition import PCA\n", + "import matplotlib.pyplot as plt\n", + "import cv2" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "channels:\n", + "- feat_0\n", + "- feat_1\n", + "- feat_2\n", + "- feat_3\n", + "- feat_4\n", + "- feat_5\n", + "- feat_6\n", + "- feat_7\n", + "- feat_8\n", + "- feat_9\n", + "feat_image_topic: /elevation_mapping/feat_im_f\n", + "feature_config:\n", + " dim: 10\n", + " dino_feat_type: feat\n", + " dropout: false\n", + " input_size:\n", + " - 160\n", + " - 320\n", + " interpolation: bilinear\n", + " model: vit_small\n", + " name: DINO\n", + " patch_size: 16\n", + " pcl: false\n", + " projection_type: nonlinear\n", + "feature_extractor: true\n", + "feature_topic: /elevation_mapping/feat_f\n", + "fusion:\n", + "- average\n", + "- average\n", + "- average\n", + "- average\n", + "- average\n", + "- average\n", + "- average\n", + "- average\n", + "- average\n", + "- average\n", + "image_info_topic: /alphasense_driver_ros/cam4/camera_info\n", + "image_topic: /alphasense_driver_ros/cam4/debayered/compressed\n", + "resize: 0.1\n", + "segmentation_model: detectron_coco_panoptic_fpn_R_101_3x\n", + "sem_seg_image_topic: /elevation_mapping/semantic_seg_im\n", + "sem_seg_topic: /elevation_mapping/semantic_seg\n", + "semantic_segmentation: false\n", + "show_label_legend: false\n", + "\n" + ] + } + ], + "source": [ + "param = ImageParameter()\n", + "with open(\"/home/melon/workspaces/gian_ws/src/lonomy_configuration/elevation_map/config/oxford_semantics.yaml\") as file:\n", + " data = yaml.safe_load(file)[\"subscribers\"]\n", + "param = ImageParameter.from_dict(data[\"feat_pred_front\"])\n", + "param.feature_config.input_size = [160, 320]\n", + "param.resize = 0.1\n", + "print(param.dumps_yaml())\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "feature_extractor = resolve_model(param.feature_config.name, param.feature_config)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(551, 976, 3)\n", + "(55, 97, 3)\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "

" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "im_p = \"/home/melon/Pictures/Screenshot from 2023-02-06 15-07-57.png\"\n", + "im_p = \"/home/melon/Pictures/Screenshot from 2023-01-18 10-36-14.png\"\n", + "image = Image.open(im_p)\n", + "if image.mode != 'RGB':\n", + " image = image.convert('RGB')\n", + "\n", + "\n", + "image_array = np.array(image)\n", + "print(image_array.shape)\n", + "\n", + "height = int(param.resize * image_array.shape[0])\n", + "width = int(param.resize * image_array.shape[1])\n", + "if param.resize is not None:\n", + " image_array = cv2.resize(image_array, dsize=(width, height))\n", + "print(image_array.shape)\n", + "plt.imshow(image_array)\n", + "image_array = cp.asarray(image_array)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "features = feature_extractor[\"model\"](image_array)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(5335, 10)\n", + "(55, 97, 3)\n" + ] + }, + { + "data": { + "text/plain": "" + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": "
", + "image/png": "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wQcfTH/n7/ydtHfv3nT69OnVNu9+97vTnj170pEjR9KXvvSldOWVV6Yf+IEfOI9n/eLiC1/4QnrVq16VLrvssnTTTTet1t0v54cnnngivfKVr0w//uM/nh544IH0Z3/2Z+nTn/50+vrXv77a5vbbb0/z8/Ppt3/7t9Mf/dEfpb/7d/9uuuSSS9LKysp5PPMXNu9///vThRdemD75yU+mhx9+ON1zzz1p27Zt6Zd/+ZdX27hfZs+mnHy88Y1vTAcOHFj9/7Zt00UXXZQOHjx4Hs/qxc3jjz+eJKV77703pZTSyZMnU1VV6Z577llt87//9/9OktJ99913vk7zRcPi4mJ69atfnT7zmc+kv/k3/+bq5MP9cv74uZ/7ufTmN7+598+7rku7d+9OH/jAB1ZrJ0+eTMPhMP2X//JfZnGKL0re/va3p3/8j//xmto111yTrrvuupSS++V8sen+2WU6nero0aPav3//ai3Pc+3fv1/33XffeTyzFzcLCwuSpAsuuECSdPToUdV1vaafLr30Uu3du9f9NAMOHDigt7/97Wuuv+R+OZ/8t//23/T6179ef//v/329/OUv1/d93/fpox/96OqfP/zwwzp+/Piavpmfn9cVV1zhvnkO+YEf+AEdOXJEf/qnfypJ+qM/+iN9/vOf19VXXy3J/XK+2HS72n7zm99U27batWvXmvquXbv0J3/yJ+fprF7cdF2nm2++WW9605v0ute9TpJ0/PhxDQYD7dy5c03bXbt26fjx4+fhLF88HD58WH/4h3+oL37xi+HP3C/njz/7sz/THXfcoVtvvVU///M/ry9+8Yv6p//0n2owGOj6669fvf70bHPfPHe85z3v0alTp3TppZeqKAq1bav3v//9uu666yTJ/XKe2HSTD7P5OHDggL7yla/o85///Pk+lRc9x44d00033aTPfOYzGo1G5/t0zJPouk6vf/3r9Uu/9EuSpO/7vu/TV77yFf3qr/6qrr/++vN8di9efuu3fku/+Zu/qbvvvluvfe1r9eCDD+rmm2/WRRdd5H45j2y6f3Z56UtfqqIogp1/4sQJ7d69+zyd1YuXG264QZ/85Cf1e7/3e7r44otX67t379Z0OtXJkyfXtHc/PbccPXpUjz/+uL7/+79fZVmqLEvde++9+vCHP6yyLLVr1y73y3niFa94hb77u797Te01r3mNHnnkEUlavf5+ts2Wf/7P/7ne85736Ed/9Ef1Pd/zPfqH//Af6pZbbtHBgwcluV/OF5tu8jEYDHT55ZfryJEjq7Wu63TkyBHt27fvPJ7Zi4uUkm644QZ9/OMf12c/+1ldcskla/788ssvV1VVa/rpoYce0iOPPOJ+eg5529vepi9/+ct68MEHV39e//rX67rrrlv9b/fL+eFNb3pTWI7+p3/6p3rlK18pSbrkkku0e/fuNX1z6tQpPfDAA+6b55Dl5WXl+dqvuqIo1HWdJPfLeeN8G6/E4cOH03A4TB/72MfSV7/61fRTP/VTaefOnen48ePn+9ReNPz0T/90mp+fT5/73OfSY489tvqzvLy82ubd73532rt3b/rsZz+bvvSlL6V9+/alffv2ncezfnHy5NUuKblfzhdf+MIXUlmW6f3vf3/62te+ln7zN38zbdmyJf3n//yfV9vcfvvtaefOnel3fud30v/6X/8rveMd7/CSzueY66+/Pn3Hd3zH6lLb//pf/2t66Utfmn72Z392tY37ZfZsyslHSin9yq/8Stq7d28aDAbpjW98Y7r//vvP9ym9qJCEP3fddddqm5WVlfRP/sk/SS95yUvSli1b0t/7e38vPfbYY+fvpF+kPHXy4X45f3ziE59Ir3vd69JwOEyXXnpp+vVf//U1f951XXrve9+bdu3alYbDYXrb296WHnroofN0ti8OTp06lW666aa0d+/eNBqN0nd+53emf/Ev/kWaTCarbdwvsydL6Ukxb8YYY4wxzzGbzvkwxhhjzAsbTz6MMcYYM1M8+TDGGGPMTPHkwxhjjDEzxZMPY4wxxswUTz6MMcYYM1M8+TDGGGPMTPHkwxhjjDEzxZMPY4wxxswUTz6MMcYYM1M8+TDGGGPMTPn/AU7XK/w0LKwbAAAAAElFTkSuQmCC\n" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "data = np.reshape(features.cpu().detach().numpy(), (features.shape[0], -1)).T\n", + "print(data.shape)\n", + "n_components = 3\n", + "pca = PCA(n_components=n_components).fit(data)\n", + "pca_descriptors = pca.transform(data)\n", + "img_pca = pca_descriptors.reshape(features.shape[1], features.shape[2], n_components)\n", + "print(img_pca.shape)\n", + "comp = img_pca # [:, :, -3:]\n", + "comp_min = comp.min(axis=(0, 1))\n", + "comp_max = comp.max(axis=(0, 1))\n", + "comp_img = (comp - comp_min) / (comp_max - comp_min)\n", + "comp_img = (comp_img * 255).astype(np.uint8)\n", + "plt.imshow(comp_img,interpolation='nearest')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "torch_38", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.15" + }, + "vscode": { + "interpreter": { + "hash": "a37eea1dce3a8c689ddbeeaef84a6dd0c46135a0b5c7a3537ea3e1718bef5fe2" + } + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py index 20716a6f..23dd65c6 100755 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py @@ -140,6 +140,12 @@ def image_info_callback(self, msg): self.height = int(self.param.resize * msg.height) self.width = int(self.param.resize * msg.width) self.info = msg + self.info.height = self.height + self.info.width = self.width + self.P = np.array(msg.P).reshape(3, 4) + self.P[:2,:3] = self.P[:2,:3]*self.param.resize + self.info.K = self.P[:3,:3].flatten().tolist() + self.info.P = self.P.flatten().tolist() def image_callback(self, rgb_msg): if self.P is None: @@ -167,13 +173,7 @@ def image_callback(self, rgb_msg): self.pub_info() def pub_info(self): - info_msg = self.info - info_msg.height = self.height - info_msg.width = self.width - self.P[:2, :] *= self.param.resize - info_msg.K = self.P[:3, :3].flatten().tolist() - info_msg.P = self.P.flatten().tolist() - self.feat_im_info_pub.publish(info_msg) + self.feat_im_info_pub.publish(self.info) def process_image(self, image): """Depending on setting generate color, semantic segmentation or feature channels. diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py index f3fc0b50..ef47e2f8 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py @@ -277,15 +277,21 @@ def __call__(self, image, *args, **kwargs): # image = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) image = self.to_tensor(image).unsqueeze(0) # if self.cfg.pcl: - reset_size = Resize(image.shape[-2:]) + reset_size = Resize(image.shape[-2:],interpolation=TF.InterpolationMode.NEAREST) + im_size = image.shape[-2:] image = self.shrink(image) image = TF.normalize(image, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)) feat1, code1 = self.model(image) feat2, code2 = self.model(image.flip(dims=[3])) - code = (code1 + code2.flip(dims=[3])) / 2 - code = NF.interpolate(code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False).detach() + + # code = (code1 + code2.flip(dims=[3])) / 2 + # code = NF.interpolate(code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False).detach() + code = (feat1[:,:10] + feat2[:,:10].flip(dims=[3])) / 2 + # code = NF.interpolate(code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False).detach() + + # if self.cfg.pcl: - code = reset_size(code) + code = NF.interpolate(code, im_size, mode=self.cfg.interpolation, align_corners=False).detach() code = torch.squeeze(code, dim=0) return code diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py index 08ac4541..43ddd9df 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py @@ -5,7 +5,7 @@ @dataclass class FeatureExtractorParameter(Serializable): name: str = "DINO" - interpolation: str = "bilinear" + interpolation: str = "nearest-exact" model: str = "vit_small" patch_size: int = 16 dim: int = 5 diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/profile.stats b/sensor_processing/semantic_sensor/script/semantic_sensor/profile.stats new file mode 100644 index 0000000000000000000000000000000000000000..aff9bc099e2ddc6db9ba102855c3eb7c32b3caba GIT binary patch literal 2189606 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%0AvoJ6LwK(EIN^m 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�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

+p5R~)a>X)!2svu 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

B|03%{8eIqN4b4>E83f771MR&~B#tY3f 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

Kv@L|KTjeI@h2j`b3mM>kI4LBSnV6pHDEWz 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
92t;TNA`WT&S6kJk+$A+Taf^;$PvV#~IQP&ME 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

wN3*ic0_IPq@ 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�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 literal 0 HcmV?d00001 From d352eafea9415f03f09a0bfbdb22b4f86f1769df Mon Sep 17 00:00:00 2001 From: Gian Date: Thu, 23 Feb 2023 15:15:29 +0100 Subject: [PATCH 340/504] some fixes of the pcl and image node --- .../elevation_mapping_cupy/plugins/semantic_filter.py | 3 +++ .../script/semantic_sensor/image_node.py | 8 +++++--- .../script/semantic_sensor/pointcloud_node.py | 11 +++++++---- .../script/semantic_sensor/pointcloud_parameters.py | 1 + 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index 0eccf639..223ba210 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -46,6 +46,9 @@ def bitget(byteval, idx): cmap[i] = np.array([r, g, b]) cmap = cmap / 255 if normalized else cmap + cmap[1] = np.array([81, 113, 162]) + cmap[2] = np.array([81, 113, 162]) + cmap[3] = np.array([188, 63, 59]) return cmap[1:] def transform_color(self): diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py index 23dd65c6..6ee22a94 100755 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py @@ -111,7 +111,9 @@ def bitget(byteval, idx): c = c >> 3 cmap[i] = np.array([r, g, b]) - + cmap[1] = np.array([81, 113, 162]) + cmap[2] = np.array([81, 113, 162]) + cmap[3] = np.array([188, 63, 59]) cmap = cmap / 255 if normalized else cmap return cmap[1:] @@ -143,8 +145,8 @@ def image_info_callback(self, msg): self.info.height = self.height self.info.width = self.width self.P = np.array(msg.P).reshape(3, 4) - self.P[:2,:3] = self.P[:2,:3]*self.param.resize - self.info.K = self.P[:3,:3].flatten().tolist() + self.P[:2, :3] = self.P[:2, :3] * self.param.resize + self.info.K = self.P[:3, :3].flatten().tolist() self.info.P = self.P.flatten().tolist() def image_callback(self, rgb_msg): diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py index 7d991a2d..9bc4232f 100755 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py @@ -28,8 +28,9 @@ def __init__(self, sensor_name): # TODO: if this is going to be loaded from another package we might need to change namespace self.param: PointcloudParameter = PointcloudParameter() self.param.feature_config.input_size = [80, 160] - if rospy.has_param("/semantic_sensor/subscribers"): - config = rospy.get_param("/semantic_sensor/subscribers") + namesp = rospy.get_name() + if rospy.has_param(namesp + "/subscribers"): + config = rospy.get_param(namesp + "/subscribers") self.param: PointcloudParameter = PointcloudParameter.from_dict(config[sensor_name]) else: print("NO ROS ENV found.") @@ -146,7 +147,9 @@ def bitget(byteval, idx): c = c >> 3 cmap[i] = np.array([r, g, b]) - + cmap[1] = np.array([188,63,59]) + cmap[2] = np.array([81,113,162]) + cmap[3] = np.array([136,49,132]) cmap = cmap / 255 if normalized else cmap return cmap[1:] @@ -208,7 +211,7 @@ def image_callback(self, depth_msg, rgb_msg=None, confidence_msg=None): if self.param.publish_segmentation_image: self.publish_segmentation_image(self.prediction_img) # todo - if False and self.param.feature_extractor: + if self.param.publish_feature_image and self.param.feature_extractor: self.publish_feature_image(self.feat_img) def create_pcl_from_image(self, image, depth, confidence): diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py index 43ddd9df..e38a05d5 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py @@ -48,5 +48,6 @@ class PointcloudParameter(Serializable): confidence_threshold: int = 10 feature_extractor: bool = False + publish_feature_image: bool = False feature_config: FeatureExtractorParameter = FeatureExtractorParameter feature_config.input_size: list = field(default_factory=lambda: [80, 160]) From 8b760068a795d89376a44885607663b97e983c3e Mon Sep 17 00:00:00 2001 From: Lorenz Wellhausen Date: Tue, 2 May 2023 14:01:41 +0200 Subject: [PATCH 341/504] Fix extra params loading with disabled plugins --- .../script/elevation_mapping_cupy/plugins/plugin_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index 3bbf3fed..30bb7581 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -93,7 +93,7 @@ def load_plugin_settings(self, file_path: str): is_height_layer=v["is_height_layer"], ) ) - extra_params.append(v["extra_params"]) + extra_params.append(v["extra_params"]) self.init(plugin_params, extra_params) print("Loaded plugins are ", *self.plugin_names) From e2ebfc24900de12e31b1ae425dd547add7a8b2de Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 23 May 2023 12:26:50 +0200 Subject: [PATCH 342/504] fix tests and make it ready for integration into development branch --- .../elevation_mapping_cupy/semantic_map.py | 1 - .../script/semantic_sensor/feature.ipynb | 263 ------------------ .../script/semantic_sensor/networks.py | 9 +- .../semantic_sensor/pointcloud_parameters.py | 2 +- .../script/semantic_sensor/profile.stats | Bin 2189606 -> 0 bytes 5 files changed, 5 insertions(+), 270 deletions(-) delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/feature.ipynb delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/profile.stats diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index d655bf92..b1a554d3 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -291,7 +291,6 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): self.semantic_map, size=(self.param.cell_n * self.param.cell_n*pcl_ids.shape[0]), ) - np.save("features.npy",self.semantic_map[layer_ids]) if "bayesian_inference" in additional_fusion: pcl_ids, layer_ids = self.get_indices_fusion(channels, "bayesian_inference") self.sum_mean *= 0 diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/feature.ipynb b/sensor_processing/semantic_sensor/script/semantic_sensor/feature.ipynb deleted file mode 100644 index 5290835d..00000000 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/feature.ipynb +++ /dev/null @@ -1,263 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 38, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "import torch\n", - "from semantic_sensor.networks import resolve_model\n", - "import os,yaml\n", - "from semantic_sensor.image_parameters import ImageParameter\n", - "from PIL import Image\n", - "import numpy as np\n", - "import cupy as cp\n", - "from sklearn.decomposition import PCA\n", - "import matplotlib.pyplot as plt\n", - "import cv2" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "channels:\n", - "- feat_0\n", - "- feat_1\n", - "- feat_2\n", - "- feat_3\n", - "- feat_4\n", - "- feat_5\n", - "- feat_6\n", - "- feat_7\n", - "- feat_8\n", - "- feat_9\n", - "feat_image_topic: /elevation_mapping/feat_im_f\n", - "feature_config:\n", - " dim: 10\n", - " dino_feat_type: feat\n", - " dropout: false\n", - " input_size:\n", - " - 160\n", - " - 320\n", - " interpolation: bilinear\n", - " model: vit_small\n", - " name: DINO\n", - " patch_size: 16\n", - " pcl: false\n", - " projection_type: nonlinear\n", - "feature_extractor: true\n", - "feature_topic: /elevation_mapping/feat_f\n", - "fusion:\n", - "- average\n", - "- average\n", - "- average\n", - "- average\n", - "- average\n", - "- average\n", - "- average\n", - "- average\n", - "- average\n", - "- average\n", - "image_info_topic: /alphasense_driver_ros/cam4/camera_info\n", - "image_topic: /alphasense_driver_ros/cam4/debayered/compressed\n", - "resize: 0.1\n", - "segmentation_model: detectron_coco_panoptic_fpn_R_101_3x\n", - "sem_seg_image_topic: /elevation_mapping/semantic_seg_im\n", - "sem_seg_topic: /elevation_mapping/semantic_seg\n", - "semantic_segmentation: false\n", - "show_label_legend: false\n", - "\n" - ] - } - ], - "source": [ - "param = ImageParameter()\n", - "with open(\"/home/melon/workspaces/gian_ws/src/lonomy_configuration/elevation_map/config/oxford_semantics.yaml\") as file:\n", - " data = yaml.safe_load(file)[\"subscribers\"]\n", - "param = ImageParameter.from_dict(data[\"feat_pred_front\"])\n", - "param.feature_config.input_size = [160, 320]\n", - "param.resize = 0.1\n", - "print(param.dumps_yaml())\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "feature_extractor = resolve_model(param.feature_config.name, param.feature_config)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": false - }, - "source": [] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(551, 976, 3)\n", - "(55, 97, 3)\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "

" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "im_p = \"/home/melon/Pictures/Screenshot from 2023-02-06 15-07-57.png\"\n", - "im_p = \"/home/melon/Pictures/Screenshot from 2023-01-18 10-36-14.png\"\n", - "image = Image.open(im_p)\n", - "if image.mode != 'RGB':\n", - " image = image.convert('RGB')\n", - "\n", - "\n", - "image_array = np.array(image)\n", - "print(image_array.shape)\n", - "\n", - "height = int(param.resize * image_array.shape[0])\n", - "width = int(param.resize * image_array.shape[1])\n", - "if param.resize is not None:\n", - " image_array = cv2.resize(image_array, dsize=(width, height))\n", - "print(image_array.shape)\n", - "plt.imshow(image_array)\n", - "image_array = cp.asarray(image_array)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "features = feature_extractor[\"model\"](image_array)" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(5335, 10)\n", - "(55, 97, 3)\n" - ] - }, - { - "data": { - "text/plain": "" - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": "
", - "image/png": "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wQcfTH/n7/ydtHfv3nT69OnVNu9+97vTnj170pEjR9KXvvSldOWVV6Yf+IEfOI9n/eLiC1/4QnrVq16VLrvssnTTTTet1t0v54cnnngivfKVr0w//uM/nh544IH0Z3/2Z+nTn/50+vrXv77a5vbbb0/z8/Ppt3/7t9Mf/dEfpb/7d/9uuuSSS9LKysp5PPMXNu9///vThRdemD75yU+mhx9+ON1zzz1p27Zt6Zd/+ZdX27hfZs+mnHy88Y1vTAcOHFj9/7Zt00UXXZQOHjx4Hs/qxc3jjz+eJKV77703pZTSyZMnU1VV6Z577llt87//9/9OktJ99913vk7zRcPi4mJ69atfnT7zmc+kv/k3/+bq5MP9cv74uZ/7ufTmN7+598+7rku7d+9OH/jAB1ZrJ0+eTMPhMP2X//JfZnGKL0re/va3p3/8j//xmto111yTrrvuupSS++V8sen+2WU6nero0aPav3//ai3Pc+3fv1/33XffeTyzFzcLCwuSpAsuuECSdPToUdV1vaafLr30Uu3du9f9NAMOHDigt7/97Wuuv+R+OZ/8t//23/T6179ef//v/329/OUv1/d93/fpox/96OqfP/zwwzp+/Piavpmfn9cVV1zhvnkO+YEf+AEdOXJEf/qnfypJ+qM/+iN9/vOf19VXXy3J/XK+2HS72n7zm99U27batWvXmvquXbv0J3/yJ+fprF7cdF2nm2++WW9605v0ute9TpJ0/PhxDQYD7dy5c03bXbt26fjx4+fhLF88HD58WH/4h3+oL37xi+HP3C/njz/7sz/THXfcoVtvvVU///M/ry9+8Yv6p//0n2owGOj6669fvf70bHPfPHe85z3v0alTp3TppZeqKAq1bav3v//9uu666yTJ/XKe2HSTD7P5OHDggL7yla/o85///Pk+lRc9x44d00033aTPfOYzGo1G5/t0zJPouk6vf/3r9Uu/9EuSpO/7vu/TV77yFf3qr/6qrr/++vN8di9efuu3fku/+Zu/qbvvvluvfe1r9eCDD+rmm2/WRRdd5H45j2y6f3Z56UtfqqIogp1/4sQJ7d69+zyd1YuXG264QZ/85Cf1e7/3e7r44otX67t379Z0OtXJkyfXtHc/PbccPXpUjz/+uL7/+79fZVmqLEvde++9+vCHP6yyLLVr1y73y3niFa94hb77u797Te01r3mNHnnkEUlavf5+ts2Wf/7P/7ne85736Ed/9Ef1Pd/zPfqH//Af6pZbbtHBgwcluV/OF5tu8jEYDHT55ZfryJEjq7Wu63TkyBHt27fvPJ7Zi4uUkm644QZ9/OMf12c/+1ldcskla/788ssvV1VVa/rpoYce0iOPPOJ+eg5529vepi9/+ct68MEHV39e//rX67rrrlv9b/fL+eFNb3pTWI7+p3/6p3rlK18pSbrkkku0e/fuNX1z6tQpPfDAA+6b55Dl5WXl+dqvuqIo1HWdJPfLeeN8G6/E4cOH03A4TB/72MfSV7/61fRTP/VTaefOnen48ePn+9ReNPz0T/90mp+fT5/73OfSY489tvqzvLy82ubd73532rt3b/rsZz+bvvSlL6V9+/alffv2ncezfnHy5NUuKblfzhdf+MIXUlmW6f3vf3/62te+ln7zN38zbdmyJf3n//yfV9vcfvvtaefOnel3fud30v/6X/8rveMd7/CSzueY66+/Pn3Hd3zH6lLb//pf/2t66Utfmn72Z392tY37ZfZsyslHSin9yq/8Stq7d28aDAbpjW98Y7r//vvP9ym9qJCEP3fddddqm5WVlfRP/sk/SS95yUvSli1b0t/7e38vPfbYY+fvpF+kPHXy4X45f3ziE59Ir3vd69JwOEyXXnpp+vVf//U1f951XXrve9+bdu3alYbDYXrb296WHnroofN0ti8OTp06lW666aa0d+/eNBqN0nd+53emf/Ev/kWaTCarbdwvsydL6Ukxb8YYY4wxzzGbzvkwxhhjzAsbTz6MMcYYM1M8+TDGGGPMTPHkwxhjjDEzxZMPY4wxxswUTz6MMcYYM1M8+TDGGGPMTPHkwxhjjDEzxZMPY4wxxswUTz6MMcYYM1M8+TDGGGPMTPn/AU7XK/w0LKwbAAAAAElFTkSuQmCC\n" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "data = np.reshape(features.cpu().detach().numpy(), (features.shape[0], -1)).T\n", - "print(data.shape)\n", - "n_components = 3\n", - "pca = PCA(n_components=n_components).fit(data)\n", - "pca_descriptors = pca.transform(data)\n", - "img_pca = pca_descriptors.reshape(features.shape[1], features.shape[2], n_components)\n", - "print(img_pca.shape)\n", - "comp = img_pca # [:, :, -3:]\n", - "comp_min = comp.min(axis=(0, 1))\n", - "comp_max = comp.max(axis=(0, 1))\n", - "comp_img = (comp - comp_min) / (comp_max - comp_min)\n", - "comp_img = (comp_img * 255).astype(np.uint8)\n", - "plt.imshow(comp_img,interpolation='nearest')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "torch_38", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.15" - }, - "vscode": { - "interpreter": { - "hash": "a37eea1dce3a8c689ddbeeaef84a6dd0c46135a0b5c7a3537ea3e1718bef5fe2" - } - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py index ef47e2f8..39847e68 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py @@ -277,7 +277,7 @@ def __call__(self, image, *args, **kwargs): # image = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) image = self.to_tensor(image).unsqueeze(0) # if self.cfg.pcl: - reset_size = Resize(image.shape[-2:],interpolation=TF.InterpolationMode.NEAREST) + reset_size = Resize(image.shape[-2:], interpolation=TF.InterpolationMode.NEAREST) im_size = image.shape[-2:] image = self.shrink(image) image = TF.normalize(image, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)) @@ -285,11 +285,10 @@ def __call__(self, image, *args, **kwargs): feat1, code1 = self.model(image) feat2, code2 = self.model(image.flip(dims=[3])) - # code = (code1 + code2.flip(dims=[3])) / 2 + code = (code1 + code2.flip(dims=[3])) / 2 # code = NF.interpolate(code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False).detach() - code = (feat1[:,:10] + feat2[:,:10].flip(dims=[3])) / 2 - # code = NF.interpolate(code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False).detach() - + # if we just use first ten + # code = (feat1[:,:10] + feat2[:,:10].flip(dims=[3])) / 2 # if self.cfg.pcl: code = NF.interpolate(code, im_size, mode=self.cfg.interpolation, align_corners=False).detach() diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py index e38a05d5..dfb81228 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py @@ -5,7 +5,7 @@ @dataclass class FeatureExtractorParameter(Serializable): name: str = "DINO" - interpolation: str = "nearest-exact" + interpolation: str = "bilinear" model: str = "vit_small" patch_size: int = 16 dim: int = 5 diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/profile.stats b/sensor_processing/semantic_sensor/script/semantic_sensor/profile.stats deleted file mode 100644 index aff9bc099e2ddc6db9ba102855c3eb7c32b3caba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2189606 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%0AvoJ6LwK(EIN^m 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�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

+p5R~)a>X)!2svu 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

B|03%{8eIqN4b4>E83f771MR&~B#tY3f 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

Kv@L|KTjeI@h2j`b3mM>kI4LBSnV6pHDEWz zz53prg>F5PnO(pT^G{@kM>;Ki0;GBifwm=j3m9TAfg^wi>J0Z_;Z<=cR^eC>#WLiA zBnO_PaDj4YiaF%PCj}w+rRoven=DXKYeR(>2s?1hAi7=E`5c`^d zK;O2>=b-idFjwb-xcGG=_5P(gRi-4hA%$Q3qhvp#9Nb|hF zVu=fqjCc}ZC?gAIo@2`Nt^43VB>q~75n`Xeq{KLYo*xF8|rNrWL%51g{4_X-Vl zJevAu{mP>EGQq_rE=Xv35@Cq86w;;>-uv9!dP>E>da#AT1qmrnA`FoRuub!W z8J!3*lB|M+lP3{|I7{G6)u{=-w59ugQ}@h0E4q&}C|r=R@+86#YbC}SEU*f$A_=R2 zA=XC7nyzs~yk1r9lHqKF!UYK_Pa+JFnvm4Fi8s_$GrU}{Gs31*i4|wGhuffBkTCNk z!Vt5CF$YVT%kFFu&}|hI8W$wYJc%&G9Lo&R42D3RxAr&x0Isr*DVKDM0W^_>q zor3nFGDN!Jf`pzY5r*iuAiX=%!y+HvFLms45>FI2@3{r+T#&HyB*GAT518_*6CFne z&F#4h8gY)z3%Yidt~><{ac;yFk&DR>4m`0NMLJt+_b>MVb&IF>q7J{1^$!Aus8^!8 zGhy1U;~dhv{h1O!(;1b!PcGyr-a>kSQ^0V}WRBEjt@N>=f9=#p)!Fes|}N6W)?6+&(=Z0dHtvDwqzOo=rtVkjZSyN>5lZZ zGyy|qE{D$0^eyA#U?QqhHOJ4d{Y&?Pl?4|h6__UxhG?1h)=8Z82Ug!TYwgZ8@Y1i7=GKEIeJ6%^?ds z;;74`#2|Z6D4AI}kDWaRHX+X;sK2f2# z@Y30)*!i2T{taOy-~)W@N7)yf>1C_tRg6le4Bu}S%;9Im zFaX(MbJ5ZUFi9@p)i#B}OS@s_(&kG_)rdY zvDa67D-DhSHI4c5pk4QNpzmB9L+txn0mC_y86UPiyLquo78rAumI_!|Ww$hpkAOkW z1+3~}aisNXAB`wK)sG`M&)SUd8xLakiI1(V32bW zj<=cM>|#;|Ux<_y?64w>e%9!6zGiTeh6@s#@+86#Z(10%tmC)^51g?dB`h@6H5m-MrBRKZr4(E zDh{QlwF1jN#NdxI%s=;Uj%yZreN~-|B=l3Og62?xQos;rVc>*E{V*mP3j-#(PhIfxl4XUSz~Of;NR;MD zgrN+u6xHGtuotl_LyvNCzQ>zaHYyPbJHHHU>&tHWdjQmO6?>h`_(+0%3y2^0dT6>i z;0nnY@$GYghHEk8%K~I(Pj6H#-~eBlt7X8pH=7_>?SoB)cJ4h)@TPbewvq<79Vi~U zJ>+DsI9L&HpE+Xtl1lsWeb25ips7W$3LJvK1)z)#UTOZKWp(PoK@#_|Ggf!|bC*HQ zUdTa#q&0tR>~jd_VR;J7sMzzydSt{`wA3mqGf_ zZAR=w_*fj3_MrmV(J^FijR7-{cvj2=6>r&{vJc`v9>mX!N4t5WN%G_3+`gWMWuLdY z_*FRj{bp0soOvIfLwIk5v$LNCG73HlzwASJ zKZLVWriC5ZHBSsIaT@-JI#4izu@53;iaWy36pi28-xU^HsZ6EJ@6Mk<_8|zbjh|OS zgR|&*_@kUZwAj+A^Le=E^knm$s|W8P{CCEVV|7Pd%GtkAxVA%!fE;09cSH9h(?@ha zf^a;^uNFZ#^9kBN?(*@h&*jqb&~Ro1XL+4qJc;m;qCp7oPS*^|hHZamitPRr;bRd#2J2aA4Q{Kn+F@6yf+)}tjn|a4%zWXY3$rA;J14K56T#~cXahLsLT{%FR#IwQSnC^ac1uG6)1Da#$x$-9}4B78c+nPnE0L*{9A%IMcVXqcYn2VsM&!PL>AkIuvKh z%q4gg4bGOV_@mSwdaiXs>MJm&%-*=5fX^dTW50x z<-b&FY3^rNk)8P@nC`VSxUE#bADFeec`z6u2g{a9gR;?X9LmyVbVtjuJ975dMgGb&sbbV5xNbkM z>;ccvt*ioXKseLAuEuUNd#8MezEL?9J{J>d~gk0fSPp-nAC)iOlYM7#u5smj<`l zeewn8ccroJm2ZQmtowF{S>^yK+!nJ4wT zK{eH5sQV#=vtnwf!EME)1$o_IPzq;o?mgU_^^r%2-N#XxG)}Wt|9NaXJlWkR=0NCZ zW|?E8dm{~QYpWxseHavFh8j7ywQumMS*)#|Ab4X(_~5LshVCB-O}o^?+!cmZVenH3 zp8*Q1O&oQvU14~2r&-{F;LmBnr!sgXjJ;}84Gw>9eNe66*;hlmx-WvUDTnjB(kEA= zWf;6V^g?Pg4Q?B?e@|7)ym$=wXnrbg@6t5i%Hfs@SjGGt;dg5V`=xCL4x_x?I-i{T zW;?>qpzf@SwbJ0WJ0msL&Mr576ofC@Q@+x@dQ~nX{4By5q_v~&vl>Mno=^-r>_O)r z507zXUFvy+v-<9@!P(fNe3oYJNd~`;a8`laI4bk9=P}R2DpcT(ZR5OZ zd|(~+O@g;|gkK-*dpW=WhFpB9Wk9BW?aS!uMQVfbE}#ASZSVy)ma=N~1J+ThwZTCS)>=qUAm)ADDxi6r^;q!F zGC(Rbm@uu+lJ1b_r#w&#`O1sKS;2ck2MW_QTcxek;#2>hs{!87*lTa}-R%bMsj&5h zF+bCPY+M&=-p*NRcCM;$!Jw9hzlY`KCaBl!M`^P;Qwxv33LBLZYhS;7-nJ5p9>x}^ zCan9~O*0EdWn(|ec%%F7P0NZIN$98E1_J?S3K&{01taGj#5-AVy~lo(;oevNHpdh< zDqlV|Z_qh6L=9YNT_iV41M9bprtpy1a8tJ^_ADib-7$bd4K(u1?I$8n$m^CwZ*zcG)bN^rOy=O##Ot%<$&Kmxo5d z@ej}gh^)6BH)^*YQ^3=AhQVJ!1Q&<^2WQAEz04rRpij@XW?gJf8aeW98KZJ5Tkjta zyc)x@{XVl}N*LlF4*b?zo0ekeO~4=J{_(!^A1y6wB!S;7ObJ7ry^(V?uC1LcS3qVz z%9c-&+skYSG%BZ-U!V0hX$I(d*HO>oUDCL}oZrBxtlg&0&hcTmQT&t<=L0rhX?|8%`Zdi1tQ9I?U9_tvEk+z$a`WGB1|?uYs(JBlc69*X!h=Y5%mV|j zyvJG;*y^)P236RP@@J=OB_;(z%isdJZsy@%x?2Cz0-hwO{VDt%Ss4FLt%e#pS>|9q z_@jJVG%MG`$u*72;}vOxrx&PC7ETF6oPTS&pcbYWj1~vne;_yhD7y!&o_TL-Nh1mL z4OzjcTI)`i5}xw;jJjLhd$t0IY3N;d!>OW1g$t6}!IKC>oX)6&_3kn2o#A*93`_{I(;=G)P78Noo+k=Z=_0Lz0Y;4!s1PpOL!f(Ha_0^uU z$>d%gcSb_3f1iDD?(k-#fm85I2^iwcPxiOx^i5Um;;4>!j0zVdy#h}n3~}a0&VL;B zOj9-US93x+qcYZQ(JHZ8M2?7`V)@s%*vXs&;^XWXSHVv7~;fELaoBumR*@vZ9gQ{ zTovq@uvLATeOMnGr>zbP7~;gyN3E!F+H{!prtpe9d!8DUsQi2THg~fdtx`dgOLEpm ztB^2o>)Q20!e3D?0gwx9{#ar)A8ar5N?WSKRzCYtN|z|L%H0bF3NFC=wYbZY&axY- zCHql&e{WjV|Ff%+1U}9uU{8QQ%BgNa1$H!mmdXXnzXRs)iuq$FqGewVv&SE0Q>(Ir z&SilylnavV{~qiybJC{_MuiJJ`#zXG{wUw?oT=Qlcs_Vu#41qs%o8~szsSk58u9p} zY+bPa^|01H;P%b4{z(3|!BBA4sY?nN;+%^GS0NMQw3%R1^^+$P*S0Y#Gh>sK;OfzA z%ZrULoghoz8K!_I{+Gyql7%U?9K%w;AEiO=rvuK90uyH$@+I}9E;XpKrGz2Q?^q0( zw8|4}jx$9;_;l!R(qRZ^{846l)%*7QW0>%8f!aq37@|*2pXg*)D`yuS(Pxn7Yk2k6 zD)dupV12i*xjcz5#EJD?ttqsRn=LjK>jqmsQ$O69{(e7hBMI$zmLrBZZAD?B2(7~CVTiLN za#mwAMZ3PXQdHosN5-y3<4PpUwl%Leh`#_!B&b(5+X{H%x8d#Uz{Y+j9}g`K zFBGLt=XU(j9pG29K(hl*+xoL@wpOi{t%B%4X@idC?`LjrR57*`Kx~V$W%G+YE{}H1ZzK?E(7Abp3IdNj@4FvJ>~Xl zr_wa#{Rb?T9^*YE4qZ@pkMZ|nUQ)n7JPXj|3bU#WGq_Gq)Sq2oGZ zgD+4g!*)dlKX0}W>{bK5L#N2ggFU@|rdbA$#rGWX^yi>TMs=Dagg@G+6z?-}Mf;ZZ zjiU9*m&OHkzE(gsyEUzRDsl2bSV8yjj;?jIjK5KJax9>lFBg@5^c{RRwY?0x4T$~6e~ZyDYu*r>*65S!`f5Krrf$V&SMfL-DpA^jJvTvl%s zI7s&2-@f|I{2E5Jw+69Q|ES+y|7>#|4&A1k^DS@i!}5~qzo29B$H%fj-R6Qi!jYwJ z-4WXZp1_9Xp1{1rpJyy*R6U^X=?b7hv5!BMR#3Masg|&13(6SPypE8Wv6~lcTDcfT ziW6^Qb6qTLRL5u#+eaI}_1fzZ1Mb;Ji#Gavs@~YBo^WLO_f*h1_W@ASy%z2J^ekI( zqk78`(*LO2yMQUs=GR7KJ)T$=>{1BawK{d_X`A28-5=FGQp>3NIzqH(D8bDg{;*t^ z{j=bsowaVkX5B9zk9ZCaS_1JK3;gt*|Gkt^E$IlMio1|b3|2#WHo2AfW;$dvaB$$9{`XpI#dtMjyhR(o$Ntb> zHfb_uckc)_Jwy$WtzQc@!p6Kiyk`bLdl{jI?A~|YVQBDDxE0lPjc?6wz%oh=p|0&I zZ7Tc@$_t%j3G4@s3Z)h+7sv-3CSkHh?jqbZcM&s2GS}vLb+6hl> zp)pKUL*z?TP)El$wQ)~)3FU$p0L?0(*XX6yORrr7FMRzexIemhRjoKx4UzARL%H~s zyVtFox0_Z>{42z&)U8YTqX05P4H?~gciGoTkkO`vv$R!LxoE{%YKZ&Ejz0IIAfxcs z)s{T9Y^oKL)DSs#0$eT-4u5oA@d4DGtA?}*yj^hoD;Qs9zPfqnXXQ#-alRTNzs>|1 z+1=aIGjbX9fQ4#^><0lg-RJn5h8JwAXvM{9h#bfTn$*LtJ1#f>3IqI7HRMV2Xm^ha z&@k=&4pe@9xsFy`u7*5&^kibTBMcrbDmIB|oDJo&QVpRst+%PO+-^90(P}k>4u=Dm z)ACvjvn(diRN=r$qwGRy9O^ZXO^LTGf1FmjQixyBZ>&w?GAmHZS`= zU*@b8lhqLV;^Bn`)501|feyP%4WV4`vQY% zni?Ye6Tla>9C!SBd^yPIq#7bS90QBNp^C?ht#!5HX*EQCGXdJm&ZHufb7j_}YtUA> zOvN8zaIn60>YlS2A-jIQitX?DXvOntmNN}n+*$AkI*I?~_@|XJfaRhZGN`5Pr+M3< zlZ-#_{OWu;_~>*sg!Uuvq1TTTeg)I#6*WYD$^@EJ=6uho1;0U`zNUtR{j&YkL<=M4 z0lT}}UWZ_4zM+Q57h<3vJ-$}I$e&bb-nY~c`3@xv@YYXzcCV2SYTBTN(36>G&5GWy zyAtZ?jv7M0s9&+^1F~T6Dc(~<<_(+gcFY-C-R1D%nU{yavf`B*^0L-x__obx|i$;CsP&J>u*d_V}5Zand$`-Lg_TJ(AUPnt%oAZcl`bIh`8dAn@c?;7Fs zv_U%_4$P-~xg%!X3L-&+*+-8duJA{wc7OVqxSoz$A)->dDt^z=zq7wwno8x%W7}bk zu)%5D`^RLvW>=Aez#-i(=4sW?~9Sp)%YDwAVfT8s>134Gr zS6Q005ue>&vpv`4(+cyadS2>y)?cchY7o*B*Ri=o_&)QFl(^fr{=qYs;qjIwBj;3Z z07GV?8X|Yyti2mAo@?zXFXzl-)TmluZ0H|w$T%$E+H z5n;Q%I*G7oV0^@f<#|$V!THCqv!8Xfud8Jp@VNcoK5gxf_d)zabYXBCA=*63jj6T6 zQ2PFq*9RYJgrQ?=%zm|^0j)=qGBkDJ&97-v=Hrnp7)CyOe{%ld0+sTr8L#Z=2h$W0IJHQUD2DPbMBY3-g3T!DHj4-x zN|GcHfl}JTpl-z34oXK^n!n%KPMaY7kktZ@8y;u4Q9l?A z$>1*?+Ar)}{mNaSIfS1-adi2{*1QhQV1V;`q+3X2xXuk8kB*FR3l9h%5D*+G3OYAk z#NcQ*c&{Na#J^r+H+V?TEh-@
92t;TNA`WT&S6kJk+$A+Taf^;$PvV#~IQP&ME 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

wN3*ic0_IPq@ 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�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 From 7166197a23332d8fa6321b37132c049f04dc3281 Mon Sep 17 00:00:00 2001 From: Gian Date: Mon, 5 Jun 2023 14:21:55 +0200 Subject: [PATCH 343/504] created plugin system for inputs and renamed pointcloud input --- .../elevation_mapping.py | 6 +- .../elevation_mapping_cupy/fusion/__init__.py | 0 .../elevation_mapping_cupy/fusion/average.py | 123 ++++ .../fusion/bayesian_inference.py | 137 ++++ .../fusion/class_average.py | 139 ++++ .../fusion/class_bayesian.py | 83 +++ .../fusion/class_max.py | 135 ++++ .../elevation_mapping_cupy/fusion/color.py | 166 +++++ .../fusion/fusion_manager.py | 106 +++ .../fusion/image_exponential.py | 75 +++ .../elevation_mapping_cupy/fusion/template.py | 22 + .../elevation_mapping_cupy/semantic_map.py | 636 ++++++++++-------- .../tests/test_elevation_mapping.py | 2 +- .../tests/test_plugins.py | 2 +- .../src/elevation_mapping_wrapper.cpp | 2 +- 15 files changed, 1349 insertions(+), 285 deletions(-) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/__init__.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/average.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/bayesian_inference.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_average.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_bayesian.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_max.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/color.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/template.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index b1115eef..d6a7c87f 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -98,7 +98,7 @@ def __init__(self, param: Parameter): self.compile_image_kernels() - self.semantic_map.compile_kernels() + self.semantic_map.initialize_fusion() weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') param.load_weights(weight_file) @@ -428,7 +428,7 @@ def update_upper_bound_with_valid_elevation(self): self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) - def input( + def input_pointcloud( self, raw_points: cp._core.core.ndarray, channels: List[str], @@ -923,7 +923,7 @@ def initialize_map(self, points, method="cubic"): print(channels) data = np.zeros((elevation.cell_n - 2, elevation.cell_n - 2), dtype=np.float32) for i in range(50): - elevation.input(points, channels, R, t, 0, 0) + elevation.input_pointcloud(points, channels, R, t, 0, 0) elevation.update_normal(elevation.elevation_map[0]) pos = np.array([i * 0.01, i * 0.02, i * 0.01]) elevation.move_to(pos, R) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/__init__.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/average.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/average.py new file mode 100644 index 00000000..140ef8b9 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/average.py @@ -0,0 +1,123 @@ +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + +def sum_kernel( + resolution, + width, + height, +): + """Sums the semantic values of the classes for the exponentiala verage or for the average. + + Args: + resolution: + width: + height: + + Returns: + + """ + # input the list of layers, amount of channels can slo be input through kernel + sum_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map, raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; + atomicAdd(&newmap[get_map_idx(idx, map_lay[layer])], feat); + } + } + """ + ).substitute(), + name="sum_kernel", + ) + return sum_kernel + + +def average_kernel( + width, + height, +): + average_kernel = cp.ElementwiseKernel( + in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U feat = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); + map[get_map_idx(id, map_lay[layer])] = feat; + } + """ + ).substitute(), + name="average_map_kernel", + ) + return average_kernel + + +class Average(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + print("Initialize fusion kernel") + self.name = "average" + self.cell_n = params.cell_n + self.resolution = params.resolution + self.sum_kernel = sum_kernel( + self.resolution, + self.cell_n, + self.cell_n, + ) + self.average_kernel = average_kernel( + self.cell_n, + self.cell_n, + ) + + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,*args): + self.sum_kernel( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + new_map, + size=(points_all.shape[0] * pcl_ids.shape[0]), + ) + self.average_kernel( + new_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + elevation_map, + semantic_map, + size=(self.cell_n * self.cell_n * pcl_ids.shape[0]), + ) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/bayesian_inference.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/bayesian_inference.py new file mode 100644 index 00000000..ac066554 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/bayesian_inference.py @@ -0,0 +1,137 @@ +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + +def sum_compact_kernel( + resolution, + width, + height, +): + # input the list of layers, amount of channels can slo be input through kernel + sum_compact_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params=" raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; + atomicAdd(&newmap[get_map_idx(idx, layer)], feat); + } + } + """ + ).substitute(), + name="sum_compact_kernel", + ) + return sum_compact_kernel + + + +def bayesian_inference_kernel( + width, + height, +): + bayesian_inference_kernel = cp.ElementwiseKernel( + in_params=" raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U newmap, raw U sum_mean, raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U feat_ml = sum_mean[get_map_idx(id, layer)]/cnt; + U feat_old = map[get_map_idx(id, map_lay[layer])]; + U sigma_old = newmap[get_map_idx(id, map_lay[layer])]; + U sigma = 1.0; + U feat_new = sigma*feat_old /(cnt*sigma_old + sigma) +cnt*sigma_old *feat_ml /(cnt*sigma_old+sigma); + U sigma_new = sigma*sigma_old /(cnt*sigma_old +sigma); + map[get_map_idx(id, map_lay[layer])] = feat_new; + newmap[get_map_idx(id, map_lay[layer])] = sigma_new; + } + """ + ).substitute(), + name="bayesian_inference_kernel", + ) + return bayesian_inference_kernel + + + +class BayesianInference(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + print("Initialize bayesian inference kernel") + self.name = "bayesian_inference" + + self.cell_n = params.cell_n + self.resolution = params.resolution + self.fusion_algorithms = params.fusion_algorithms + self.data_type = params.data_type + + self.sum_mean = cp.ones( + ( + self.fusion_algorithms.count("bayesian_inference"), + self.cell_n, + self.cell_n, + ), + self.data_type, + ) + # TODO initialize the variance with a value different than 0 + self.sum_compact_kernel = sum_compact_kernel( + self.resolution, + self.cell_n, + self.cell_n, + ) + self.bayesian_inference_kernel = bayesian_inference_kernel( + self.cell_n, + self.cell_n, + ) + + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,*args): + self.sum_mean *= 0 + self.sum_compact_kernel( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + self.sum_mean, + size=(points_all.shape[0]), + ) + self.bayesian_inference_kernel( + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + elevation_map, + new_map, + self.sum_mean, + semantic_map, + size=(self.cell_n * self.cell_n), + ) + + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_average.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_average.py new file mode 100644 index 00000000..8705234f --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_average.py @@ -0,0 +1,139 @@ +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + +def sum_kernel( + resolution, + width, + height, +): + """Sums the semantic values of the classes for the exponentiala verage or for the average. + + Args: + resolution: + width: + height: + + Returns: + + """ + # input the list of layers, amount of channels can slo be input through kernel + sum_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map, raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; + atomicAdd(&newmap[get_map_idx(idx, map_lay[layer])], feat); + } + } + """ + ).substitute(), + name="sum_kernel", + ) + return sum_kernel + + +def class_average_kernel( + width, + height, + alpha, +): + class_average_kernel = cp.ElementwiseKernel( + in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U prev_val = map[get_map_idx(id, map_lay[layer])]; + if (prev_val==0){ + U val = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); + map[get_map_idx(id, map_lay[layer])] = val; + } + else{ + U val = ${alpha} *prev_val + (1-${alpha}) * newmap[get_map_idx(id, map_lay[layer])]/(cnt); + map[get_map_idx(id, map_lay[layer])] = val; + } + } + """ + ).substitute( + alpha=alpha, + ), + name="class_average_kernel", + ) + return class_average_kernel + + + +class ClassAverage(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + print("Initialize fusion kernel") + self.name = "class_average" + self.cell_n = params.cell_n + self.resolution = params.resolution + self.average_weight = params.average_weight + + self.sum_kernel = sum_kernel( + self.resolution, + self.cell_n, + self.cell_n, + ) + self.class_average_kernel = class_average_kernel( + self.cell_n, + self.cell_n, + self.average_weight, + ) + + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,*args): + self.sum_kernel( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + new_map, + size=(points_all.shape[0] * pcl_ids.shape[0]), + ) + self.class_average_kernel( + new_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + elevation_map, + semantic_map, + size=(self.cell_n * self.cell_n * pcl_ids.shape[0]), + ) + + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_bayesian.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_bayesian.py new file mode 100644 index 00000000..f3074783 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_bayesian.py @@ -0,0 +1,83 @@ +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + + +def alpha_kernel( + resolution, + width, + height, +): + # input the list of layers, amount of channels can slo be input through kernel + alpha_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U theta_max = 0; + W arg_max = 0; + U theta = p[id * pcl_channels[0] + pcl_chan[layer]]; + if (theta >=theta_max){ + arg_max = map_lay[layer]; + theta_max = theta; + } + atomicAdd(&newmap[get_map_idx(idx, arg_max)], theta_max); + } + } + """ + ).substitute(), + name="alpha_kernel", + ) + return alpha_kernel + + + +class ClassBayesian(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + print("Initialize fusion kernel") + self.name = "class_bayesian" + self.cell_n = params.cell_n + self.resolution = params.resolution + self.alpha_kernel = alpha_kernel( + self.resolution, + self.cell_n, + self.cell_n, + ) + + + + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,*args): + self.alpha_kernel( + points_all, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + new_map, + size=(points_all.shape[0]), + ) + # calculate new thetas + sum_alpha = cp.sum(new_map[layer_ids], axis=0) + # do not divide by zero + sum_alpha[sum_alpha == 0] = 1 + semantic_map[layer_ids] = new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) + + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_max.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_max.py new file mode 100644 index 00000000..d7230518 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_max.py @@ -0,0 +1,135 @@ +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + + + +def sum_max_kernel( + resolution, + width, + height, +): + # input the list of layers, amount of channels can slo be input through kernel + sum_max_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U max_pt, raw T max_id, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params=" raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U idx = p[i * pcl_channels[0]]; + U valid = p[i * pcl_channels[0] + 1]; + U inside = p[i * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + // for every max value + for ( W it=0;it> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = ( color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid && inside){ + unsigned int color = __float_as_uint(p[id * pcl_channels[0] + pcl_chan[layer]]); + atomicAdd(&color_map[get_map_idx(idx, layer*3)], get_r(color)); + atomicAdd(&color_map[get_map_idx(idx, layer*3+1)], get_g(color)); + atomicAdd(&color_map[get_map_idx(idx, layer*3 + 2)], get_b(color)); + atomicAdd(&color_map[get_map_idx(idx, pcl_channels[1]*3)], 1); + } + """ + ).substitute(width=width), + name="add_color_kernel", + ) + return add_color_kernel + + + +def color_average_kernel( + width, + height, +): + color_average_kernel = cp.ElementwiseKernel( + in_params="raw V color_map, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ unsigned int get_r(unsigned int color){ + unsigned int red = 0xFF0000; + unsigned int reds = (color & red) >> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = (color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + unsigned int cnt = color_map[get_map_idx(id, pcl_channels[1]*3)]; + if (cnt>0){ + // U prev_color = map[get_map_idx(id, map_lay[layer])]; + unsigned int r = color_map[get_map_idx(id, layer*3)]/(1*cnt); + unsigned int g = color_map[get_map_idx(id, layer*3+1)]/(1*cnt); + unsigned int b = color_map[get_map_idx(id, layer*3+2)]/(1*cnt); + //if (prev_color>=0){ + // unsigned int prev_r = get_r(prev_color); + // unsigned int prev_g = get_g(prev_color); + // unsigned int prev_b = get_b(prev_color); + // unsigned int r = prev_r/2 + color_map[get_map_idx(i, layer*3)]/(2*cnt); + // unsigned int g = prev_g/2 + color_map[get_map_idx(i, layer*3+1)]/(2*cnt); + // unsigned int b = prev_b/2 + color_map[get_map_idx(i, layer*3+2)]/(2*cnt); + //} + unsigned int rgb = (r<<16) + (g << 8) + b; + float rgb_ = __uint_as_float(rgb); + map[get_map_idx(id, map_lay[layer])] = rgb_; + } + """ + ).substitute(), + name="color_average_kernel", + ) + return color_average_kernel + + + +class Color(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + print("Initialize fusion kernel") + self.name = "color" + self.cell_n = params.cell_n + self.resolution = params.resolution + + self.add_color_kernel = add_color_kernel( + params.cell_n, + params.cell_n, + ) + self.color_average_kernel = color_average_kernel(self.cell_n, self.cell_n) + + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,*args): + self.color_map = cp.zeros( + (1 + 3 * layer_ids.shape[0], self.cell_n, self.cell_n), + dtype=cp.uint32, + ) + + points_all = points_all.astype(cp.float32) + self.add_color_kernel( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + self.color_map, + size=(points_all.shape[0]), + ) + self.color_average_kernel( + self.color_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + size=(self.cell_n * self.cell_n), + ) + + + + + + + + + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py new file mode 100644 index 00000000..1378ec6d --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py @@ -0,0 +1,106 @@ +from abc import ABC, abstractmethod +import cupy as cp +from typing import List, Dict, Any +from dataclasses import dataclass +import importlib +import inspect + + +# @dataclass +# class FusionParams: +# name: str + + +class FusionBase(ABC): + """ + This is a base class of Fusion + """ + + @abstractmethod + def __init__(self, *args, **kwargs): + """ + + Args: + fusion_params : FusionParams + The parameter of callback + """ + self.name = None + + @abstractmethod + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map): + pass + + +class FusionManager(object): + def __init__(self, params): + self.fusion_plugins: Dict[str, FusionBase] = {} + self.params = params + self.plugins = [] + + def register_plugin(self, plugin): + """ + Register a new fusion plugin + """ + try: + m = importlib.import_module("." + plugin, package="elevation_mapping_cupy.fusion") # -> 'module' + except: + raise ValueError("Plugin {} does not exist.".format(plugin)) + for name, obj in inspect.getmembers(m): + + if inspect.isclass(obj) and issubclass(obj, FusionBase) and name != "FusionBase": + self.plugins.append(obj(self.params)) + + def get_plugin_idx(self, name: str): + """ + Get a registered fusion plugin + """ + for idx, plugin in enumerate(self.plugins): + if plugin.name == name: + return idx + + + def execute_plugin( + self, name: str, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, elements_to_shift + ): + """ + Execute a registered fusion plugin + """ + idx = self.get_plugin_idx(name) + if idx is not None: + self.plugins[idx]( + points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, elements_to_shift + ) + else: + raise ValueError("Plugin {} is not registered".format(name)) + + def execute_image_plugin( + self, + name: str, + sem_map_idx, + image, + j, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + semantic_map, + new_map, + ): + """ + Execute a registered fusion plugin + """ + idx = self.get_plugin_idx(name) + if idx is not None: + self.plugins[idx]( + sem_map_idx, + image, + j, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + semantic_map, + new_map, + ) + else: + raise ValueError("Plugin {} is not registered".format(name)) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py new file mode 100644 index 00000000..19061ce1 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py @@ -0,0 +1,75 @@ +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + +def exponential_correspondences_to_map_kernel(resolution, width, height, alpha): + exponential_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)] * (1-${alpha}) + ${alpha} * image_mono[idx]; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + + """ + ).substitute(alpha=alpha), + name="exponential_correspondences_to_map_kernel", + ) + return exponential_correspondences_to_map_kernel + + +class ImageExponential(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + print("Initialize fusion kernel") + self.name = "image_exponential" + self.cell_n = params.cell_n + self.resolution = params.resolution + + self.exponential_correspondences_to_map_kernel = exponential_correspondences_to_map_kernel( + resolution=self.resolution, + width=self.cell_n, + height=self.cell_n, + alpha=0.7, + ) + + def __call__(self, sem_map_idx,image, j,uv_correspondence, valid_correspondence, image_height, image_width , semantic_map, new_map): + self.exponential_correspondences_to_map_kernel( + semantic_map, + sem_map_idx, + image[j], + uv_correspondence, + valid_correspondence, + image_height, + image_width, + new_map, + size=int(self.cell_n * self.cell_n), + ) + semantic_map[sem_map_idx] = new_map[sem_map_idx] + + + + + + + + + + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/template.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/template.py new file mode 100644 index 00000000..8cfcec82 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/template.py @@ -0,0 +1,22 @@ +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + + + + +class Color(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + print("Initialize fusion kernel") + self.cell_n = params.cell_n + self.resolution = params.resolution + + + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,*args): + pass + + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index b1a554d3..7dc59f84 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -20,6 +20,7 @@ color_correspondences_to_map_kernel, ) +from elevation_mapping_cupy.fusion.fusion_manager import FusionManager xp = cp @@ -61,105 +62,128 @@ def __init__(self, param: Parameter): # which layers should be reset to zero at each update, per default everyone, # if a layer should not be reset, it is defined in compile_kernels function self.delete_new_layers = cp.ones(self.new_map.shape[0], cp.bool8) + self.fusion_manager = FusionManager(self.param) def clear(self): """Clear the semantic map.""" self.semantic_map *= 0.0 - def compile_kernels(self) -> None: - """ - Returns: - None: - """ - # TODO: maybe this could be improved by creating functions for each single fusion algorithm - if "average" in self.unique_fusion: - print("Initialize fusion kernel") - self.sum_kernel = sum_kernel( - self.param.resolution, - self.param.cell_n, - self.param.cell_n, - ) - self.average_kernel = average_kernel( - self.param.cell_n, - self.param.cell_n, - ) - if "bayesian_inference" in self.unique_fusion: - print("Initialize bayesian inference kernel") - self.sum_mean = xp.ones( - ( - self.param.fusion_algorithms.count("bayesian_inference"), - self.param.cell_n, - self.param.cell_n, - ), - self.param.data_type, - ) - # TODO initialize the variance with a value different than 0 - self.sum_compact_kernel = sum_compact_kernel( - self.param.resolution, - self.param.cell_n, - self.param.cell_n, - ) - self.bayesian_inference_kernel = bayesian_inference_kernel( - self.param.cell_n, - self.param.cell_n, - ) - if "color" in self.unique_fusion: - print("Initialize color kernel") - - self.add_color_kernel = add_color_kernel( - self.param.cell_n, - self.param.cell_n, - ) - self.color_average_kernel = color_average_kernel(self.param.cell_n, self.param.cell_n) - if "class_average" in self.unique_fusion: - print("Initialize class average kernel") - self.sum_kernel = sum_kernel( - self.param.resolution, - self.param.cell_n, - self.param.cell_n, - ) - self.class_average_kernel = class_average_kernel( - self.param.cell_n, - self.param.cell_n, - self.param.average_weight, - ) - if "class_bayesian" in self.unique_fusion: - print("Initialize class bayesian kernel") - pcl_ids = self.get_layer_indices("class_bayesian") - self.delete_new_layers[pcl_ids] = 0 - self.alpha_kernel = alpha_kernel( - self.param.resolution, - self.param.cell_n, - self.param.cell_n, - ) - if "class_max" in self.unique_fusion: - print("Initialize class max kernel") - pcl_ids = self.get_layer_indices("class_max") - self.delete_new_layers[pcl_ids] = 0 - self.sum_max_kernel = sum_max_kernel( - self.param.resolution, - self.param.cell_n, - self.param.cell_n, - ) - layer_cnt = self.param.fusion_algorithms.count("class_max") - id_max = cp.zeros( - (layer_cnt, self.param.cell_n, self.param.cell_n), - dtype=cp.uint32, - ) - self.elements_to_shift["id_max"] = id_max - self.unique_id = cp.array([0]) - - if "image_exponential" in self.unique_fusion: - self.exponential_correspondences_to_map_kernel = exponential_correspondences_to_map_kernel( - resolution=self.param.resolution, width=self.param.cell_n, height=self.param.cell_n, alpha=0.7 - ) - - if "image_color" in self.unique_fusion: - self.color_correspondences_to_map_kernel = color_correspondences_to_map_kernel( - resolution=self.param.resolution, - width=self.param.cell_n, - height=self.param.cell_n, - ) + def initialize_fusion(self): + """Initialize the fusion algorithms.""" + + for fusion in self.unique_fusion: + if "class_bayesian" == fusion: + pcl_ids = self.get_layer_indices("class_bayesian") + self.delete_new_layers[pcl_ids] = 0 + if "class_max" == fusion: + pcl_ids = self.get_layer_indices("class_max") + self.delete_new_layers[pcl_ids] = 0 + layer_cnt = self.param.fusion_algorithms.count("class_max") + id_max = cp.zeros( + (layer_cnt, self.param.cell_n, self.param.cell_n), + dtype=cp.uint32, + ) + self.elements_to_shift["id_max"] = id_max + self.fusion_manager.register_plugin(fusion) + + # def compile_kernels(self) -> None: + # """ + # Returns: + # None: + # """ + # # TODO: maybe this could be improved by creating functions for each single fusion algorithm + # + # if "average" in self.unique_fusion: + # print("Initialize fusion kernel") + # self.sum_kernel = sum_kernel( + # self.param.resolution, + # self.param.cell_n, + # self.param.cell_n, + # ) + # self.average_kernel = average_kernel( + # self.param.cell_n, + # self.param.cell_n, + # ) + # if "bayesian_inference" in self.unique_fusion: + # print("Initialize bayesian inference kernel") + # self.sum_mean = xp.ones( + # ( + # self.param.fusion_algorithms.count("bayesian_inference"), + # self.param.cell_n, + # self.param.cell_n, + # ), + # self.param.data_type, + # ) + # # TODO initialize the variance with a value different than 0 + # self.sum_compact_kernel = sum_compact_kernel( + # self.param.resolution, + # self.param.cell_n, + # self.param.cell_n, + # ) + # self.bayesian_inference_kernel = bayesian_inference_kernel( + # self.param.cell_n, + # self.param.cell_n, + # ) + # if "color" in self.unique_fusion: + # print("Initialize color kernel") + # + # self.add_color_kernel = add_color_kernel( + # self.param.cell_n, + # self.param.cell_n, + # ) + # self.color_average_kernel = color_average_kernel(self.param.cell_n, self.param.cell_n) + # if "class_average" in self.unique_fusion: + # print("Initialize class average kernel") + # self.sum_kernel = sum_kernel( + # self.param.resolution, + # self.param.cell_n, + # self.param.cell_n, + # ) + # self.class_average_kernel = class_average_kernel( + # self.param.cell_n, + # self.param.cell_n, + # self.param.average_weight, + # ) + # if "class_bayesian" in self.unique_fusion: + # print("Initialize class bayesian kernel") + # pcl_ids = self.get_layer_indices("class_bayesian") + # self.delete_new_layers[pcl_ids] = 0 + # self.alpha_kernel = alpha_kernel( + # self.param.resolution, + # self.param.cell_n, + # self.param.cell_n, + # ) + # if "class_max" in self.unique_fusion: + # print("Initialize class max kernel") + # pcl_ids = self.get_layer_indices("class_max") + # self.delete_new_layers[pcl_ids] = 0 + # self.sum_max_kernel = sum_max_kernel( + # self.param.resolution, + # self.param.cell_n, + # self.param.cell_n, + # ) + # layer_cnt = self.param.fusion_algorithms.count("class_max") + # id_max = cp.zeros( + # (layer_cnt, self.param.cell_n, self.param.cell_n), + # dtype=cp.uint32, + # ) + # self.elements_to_shift["id_max"] = id_max + # self.unique_id = cp.array([0]) + # + # if "image_exponential" in self.unique_fusion: + # self.exponential_correspondences_to_map_kernel = exponential_correspondences_to_map_kernel( + # resolution=self.param.resolution, + # width=self.param.cell_n, + # height=self.param.cell_n, + # alpha=0.7, + # ) + # + # if "image_color" in self.unique_fusion: + # self.color_correspondences_to_map_kernel = color_correspondences_to_map_kernel( + # resolution=self.param.resolution, + # width=self.param.cell_n, + # height=self.param.cell_n, + # ) def pad_value(self, x, shift_value, idx=None, value=0.0): """Create a padding of the map along x,y-axis according to amount that has shifted. @@ -269,171 +293,201 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): """ additional_fusion = self.get_fusion_of_pcl(channels) self.new_map[self.delete_new_layers] = 0.0 - if "average" in additional_fusion: - pcl_ids, layer_ids = self.get_indices_fusion(channels, "average") - self.sum_kernel( + for fusion in list(set(additional_fusion)): + print(f"fusion: {fusion}") + # which layers need to be updated with this fusion algorithm + pcl_ids, layer_ids = self.get_indices_fusion(channels, fusion) + # update the layers with the fusion algorithm + self.fusion_manager.execute_plugin( + fusion, points_all, R, t, pcl_ids, layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - self.semantic_map, - self.new_map, - size=(points_all.shape[0]*pcl_ids.shape[0]), - ) - self.average_kernel( - self.new_map, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), elevation_map, self.semantic_map, - size=(self.param.cell_n * self.param.cell_n*pcl_ids.shape[0]), - ) - if "bayesian_inference" in additional_fusion: - pcl_ids, layer_ids = self.get_indices_fusion(channels, "bayesian_inference") - self.sum_mean *= 0 - self.sum_compact_kernel( - points_all, - R, - t, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - self.sum_mean, - size=(points_all.shape[0]), - ) - self.bayesian_inference_kernel( - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - elevation_map, self.new_map, - self.sum_mean, - self.semantic_map, - size=(self.param.cell_n * self.param.cell_n), - ) - if "class_average" in additional_fusion: - pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_average") - self.sum_kernel( - points_all, - R, - t, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - self.semantic_map, - self.new_map, - size=(points_all.shape[0] * pcl_ids.shape[0]), - ) - self.class_average_kernel( - self.new_map, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - elevation_map, - self.semantic_map, - size=(self.param.cell_n * self.param.cell_n * pcl_ids.shape[0]), - ) - - if "class_bayesian" in additional_fusion: - pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_bayesian") - # alpha sum get points as input and calculate for each point to what cell it belongs and then - # adds to the right channel a one - self.alpha_kernel( - points_all, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - self.new_map, - size=(points_all.shape[0]), - ) - # calculate new thetas - sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) - # do not divide by zero - sum_alpha[sum_alpha == 0] = 1 - self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) - - if "class_max" in additional_fusion: - # get indices that are of type class_max in pointclopud and in layers - pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_max") - # decode float32 into to float16 - max_pt, pt_id = self.decode_max(points_all[:, pcl_ids]) - # find unique ids in new measurement and in existing map - unique_idm = cp.unique(pt_id) - unique_ida = cp.unique(self.unique_id[self.elements_to_shift["id_max"]]) - # get all unique ids, where index is the position in the prob_sum and the value in the NN class - self.unique_id = cp.unique(cp.concatenate((unique_idm, unique_ida))) - # contains the sum of the new measurement probabilities - self.prob_sum = cp.zeros( - (len(self.unique_id), self.param.cell_n, self.param.cell_n), - dtype=np.float32, - ) - # transform the index matrix of the classes to the index matrix of the prob_sum - pt_id_zero = pt_id.copy() - for it, val in enumerate(self.unique_id): - pt_id_zero[pt_id_zero == val] = it - - # sum all measurements probabilities - self.sum_max_kernel( - points_all, - max_pt, - pt_id_zero, - pcl_ids, - layer_ids, - cp.array( - [points_all.shape[1], pcl_ids.shape[0], pt_id.shape[1]], - dtype=cp.int32, - ), - self.prob_sum, - size=(points_all.shape[0]), - ) - # add the previous alpha - for i, lay in enumerate(layer_ids): - c = cp.mgrid[0 : self.new_map.shape[1], 0 : self.new_map.shape[2]] - # self.prob_sum[self.elements_to_shift["id_max"][i], c[0], c[1]] += self.new_map[lay] - # TODO add residual of prev alpha to the prob_sum - # res = 1- self.new_map[lay] - # res /= (len(self.unique_id)-1) - - # find the alpha we want to keep - for i, lay in enumerate(layer_ids): - self.new_map[lay] = cp.amax(self.prob_sum, axis=0) - self.elements_to_shift["id_max"][lay] = self.unique_id[cp.argmax(self.prob_sum, axis=0)] - self.prob_sum[cp.argmax(self.prob_sum, axis=0)] = 0 - # update map calculate new thetas - sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) - # do not divide by zero - sum_alpha[sum_alpha == 0] = 1 - self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) - - if "color" in additional_fusion: - pcl_ids, layer_ids = self.get_indices_fusion(channels, "color") - self.color_map = cp.zeros( - (1 + 3 * layer_ids.shape[0], self.param.cell_n, self.param.cell_n), - dtype=cp.uint32, + self.elements_to_shift, ) - points_all = points_all.astype(cp.float32) - self.add_color_kernel( - points_all, - R, - t, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - self.color_map, - size=(points_all.shape[0]), - ) - self.color_average_kernel( - self.color_map, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - self.semantic_map, - size=(self.param.cell_n * self.param.cell_n), - ) + # def update_layers_pointcloud_o(self, points_all, channels, R, t, elevation_map): + # """Update the semantic map with the pointcloud. + # + # Args: + # points_all: semantic point cloud + # channels: list of channel names + # R: rotation matrix + # t: translation vector + # elevation_map: elevation map object + # """ + # additional_fusion = self.get_fusion_of_pcl(channels) + # self.new_map[self.delete_new_layers] = 0.0 + # if "average" in additional_fusion: + # pcl_ids, layer_ids = self.get_indices_fusion(channels, "average") + # self.sum_kernel( + # points_all, + # R, + # t, + # pcl_ids, + # layer_ids, + # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + # self.semantic_map, + # self.new_map, + # size=(points_all.shape[0] * pcl_ids.shape[0]), + # ) + # self.average_kernel( + # self.new_map, + # pcl_ids, + # layer_ids, + # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + # elevation_map, + # self.semantic_map, + # size=(self.param.cell_n * self.param.cell_n * pcl_ids.shape[0]), + # ) + # if "bayesian_inference" in additional_fusion: + # pcl_ids, layer_ids = self.get_indices_fusion(channels, "bayesian_inference") + # self.sum_mean *= 0 + # self.sum_compact_kernel( + # points_all, + # R, + # t, + # pcl_ids, + # layer_ids, + # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + # self.sum_mean, + # size=(points_all.shape[0]), + # ) + # self.bayesian_inference_kernel( + # pcl_ids, + # layer_ids, + # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + # elevation_map, + # self.new_map, + # self.sum_mean, + # self.semantic_map, + # size=(self.param.cell_n * self.param.cell_n), + # ) + # if "class_average" in additional_fusion: + # pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_average") + # self.sum_kernel( + # points_all, + # R, + # t, + # pcl_ids, + # layer_ids, + # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + # self.semantic_map, + # self.new_map, + # size=(points_all.shape[0] * pcl_ids.shape[0]), + # ) + # self.class_average_kernel( + # self.new_map, + # pcl_ids, + # layer_ids, + # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + # elevation_map, + # self.semantic_map, + # size=(self.param.cell_n * self.param.cell_n * pcl_ids.shape[0]), + # ) + # + # if "class_bayesian" in additional_fusion: + # pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_bayesian") + # # alpha sum get points as input and calculate for each point to what cell it belongs and then + # # adds to the right channel a one + # self.alpha_kernel( + # points_all, + # pcl_ids, + # layer_ids, + # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + # self.new_map, + # size=(points_all.shape[0]), + # ) + # # calculate new thetas + # sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) + # # do not divide by zero + # sum_alpha[sum_alpha == 0] = 1 + # self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) + # + # if "class_max" in additional_fusion: + # # get indices that are of type class_max in pointclopud and in layers + # pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_max") + # # decode float32 into to float16 + # max_pt, pt_id = self.decode_max(points_all[:, pcl_ids]) + # # find unique ids in new measurement and in existing map + # unique_idm = cp.unique(pt_id) + # unique_ida = cp.unique(self.unique_id[self.elements_to_shift["id_max"]]) + # # get all unique ids, where index is the position in the prob_sum and the value in the NN class + # self.unique_id = cp.unique(cp.concatenate((unique_idm, unique_ida))) + # # contains the sum of the new measurement probabilities + # self.prob_sum = cp.zeros( + # (len(self.unique_id), self.param.cell_n, self.param.cell_n), + # dtype=np.float32, + # ) + # # transform the index matrix of the classes to the index matrix of the prob_sum + # pt_id_zero = pt_id.copy() + # for it, val in enumerate(self.unique_id): + # pt_id_zero[pt_id_zero == val] = it + # + # # sum all measurements probabilities + # self.sum_max_kernel( + # points_all, + # max_pt, + # pt_id_zero, + # pcl_ids, + # layer_ids, + # cp.array( + # [points_all.shape[1], pcl_ids.shape[0], pt_id.shape[1]], + # dtype=cp.int32, + # ), + # self.prob_sum, + # size=(points_all.shape[0]), + # ) + # # add the previous alpha + # for i, lay in enumerate(layer_ids): + # c = cp.mgrid[0 : self.new_map.shape[1], 0 : self.new_map.shape[2]] + # # self.prob_sum[self.elements_to_shift["id_max"][i], c[0], c[1]] += self.new_map[lay] + # # TODO add residual of prev alpha to the prob_sum + # # res = 1- self.new_map[lay] + # # res /= (len(self.unique_id)-1) + # + # # find the alpha we want to keep + # for i, lay in enumerate(layer_ids): + # self.new_map[lay] = cp.amax(self.prob_sum, axis=0) + # self.elements_to_shift["id_max"][lay] = self.unique_id[cp.argmax(self.prob_sum, axis=0)] + # self.prob_sum[cp.argmax(self.prob_sum, axis=0)] = 0 + # # update map calculate new thetas + # sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) + # # do not divide by zero + # sum_alpha[sum_alpha == 0] = 1 + # self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) + # + # if "color" in additional_fusion: + # pcl_ids, layer_ids = self.get_indices_fusion(channels, "color") + # self.color_map = cp.zeros( + # (1 + 3 * layer_ids.shape[0], self.param.cell_n, self.param.cell_n), + # dtype=cp.uint32, + # ) + # + # points_all = points_all.astype(cp.float32) + # self.add_color_kernel( + # points_all, + # R, + # t, + # pcl_ids, + # layer_ids, + # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + # self.color_map, + # size=(points_all.shape[0]), + # ) + # self.color_average_kernel( + # self.color_map, + # pcl_ids, + # layer_ids, + # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + # self.semantic_map, + # size=(self.param.cell_n * self.param.cell_n), + # ) def update_layers_image( self, @@ -454,42 +508,66 @@ def update_layers_image( image_height: image_width: """ - self.new_map *= 0 + + # additional_fusion = self.get_fusion_of_pcl(channels) + self.new_map[self.delete_new_layers] = 0.0 config = self.param.subscriber_cfg[sub_key] for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): sem_map_idx = self.get_index(channel) - if fusion == "image_exponential": - self.exponential_correspondences_to_map_kernel( - self.semantic_map, - cp.uint64(sem_map_idx), - image[j], - uv_correspondence, - valid_correspondence, - image_height, - image_width, - self.new_map, - size=int(self.param.cell_n * self.param.cell_n), - ) - self.semantic_map[sem_map_idx] = self.new_map[sem_map_idx] - - elif fusion == "image_color": - self.color_correspondences_to_map_kernel( - self.semantic_map, - cp.uint64(sem_map_idx), - image, - uv_correspondence, - valid_correspondence, - image_height, - image_width, - self.new_map, - size=int(self.param.cell_n * self.param.cell_n), - ) - self.semantic_map[sem_map_idx] = self.new_map[sem_map_idx] - else: - raise ValueError("Fusion for image is unknown.") + # which layers need to be updated with this fusion algorithm + # pcl_ids, layer_ids = self.get_indices_fusion(channels, fusion) + # update the layers with the fusion algorithm + self.fusion_manager.execute_image_plugin( + fusion, + cp.uint64(sem_map_idx), + image, + j, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + self.semantic_map, + self.new_map, + ) + # self.new_map *= 0 + # config = self.param.subscriber_cfg[sub_key] + # + # for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): + # sem_map_idx = self.get_index(channel) + # + # if fusion == "image_exponential": + # self.exponential_correspondences_to_map_kernel( + # self.semantic_map, + # cp.uint64(sem_map_idx), + # image[j], + # uv_correspondence, + # valid_correspondence, + # image_height, + # image_width, + # self.new_map, + # size=int(self.param.cell_n * self.param.cell_n), + # ) + # self.semantic_map[sem_map_idx] = self.new_map[sem_map_idx] + # + # elif fusion == "image_color": + # self.color_correspondences_to_map_kernel( + # self.semantic_map, + # cp.uint64(sem_map_idx), + # image, + # uv_correspondence, + # valid_correspondence, + # image_height, + # image_width, + # self.new_map, + # size=int(self.param.cell_n * self.param.cell_n), + # ) + # self.semantic_map[sem_map_idx] = self.new_map[sem_map_idx] + # + # else: + # raise ValueError("Fusion for image is unknown.") def decode_max(self, mer): """Decode the float32 value into two 16 bit value containing the class probability and the class id. diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py index 7a74b8ab..7bdbb20b 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -58,7 +58,7 @@ def test_input(self, elmap_ex): points = cp.random.rand(100000, len(channels), dtype=elmap_ex.param.data_type) R = cp.random.rand(3, 3, dtype=elmap_ex.param.data_type) t = cp.random.rand(3, dtype=elmap_ex.param.data_type) - elmap_ex.input(points, channels, R, t, 0, 0) + elmap_ex.input_pointcloud(points, channels, R, t, 0, 0) def test_update_normal(self, elmap_ex): elmap_ex.update_normal(elmap_ex.elevation_map[0]) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py index 25c0619c..9e608cfe 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -18,7 +18,7 @@ def semmap_ex(add_lay, fusion_alg): p.subscriber_cfg["front_cam"]["fusion"] = fusion_alg p.update() e = semantic_map.SemanticMap(p) - e.compile_kernels() + e.initialize_fusion() return e diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 74027bb9..51cf073e 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -133,7 +133,7 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { void ElevationMappingWrapper::input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise) { py::gil_scoped_acquire acquire; - map_.attr("input")(Eigen::Ref(points), channels, Eigen::Ref(R), + map_.attr("input_pointcloud")(Eigen::Ref(points), channels, Eigen::Ref(R), Eigen::Ref(t), positionNoise, orientationNoise); } From 26dc1db3bd7a60ce4148d3b0d6895c8a7a42dd87 Mon Sep 17 00:00:00 2001 From: Gian Date: Mon, 5 Jun 2023 14:24:29 +0200 Subject: [PATCH 344/504] removed commented code that was replaced by plugin --- .../elevation_mapping_cupy/semantic_map.py | 332 +----------------- 1 file changed, 1 insertion(+), 331 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 7dc59f84..9e4b553f 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -3,24 +3,8 @@ import numpy as np from typing import List -from elevation_mapping_cupy.kernels import ( - average_kernel, - class_average_kernel, - alpha_kernel, - bayesian_inference_kernel, - add_color_kernel, - color_average_kernel, - sum_compact_kernel, - sum_max_kernel, - sum_kernel, -) -from elevation_mapping_cupy.kernels import ( - average_correspondences_to_map_kernel, - exponential_correspondences_to_map_kernel, - color_correspondences_to_map_kernel, -) - from elevation_mapping_cupy.fusion.fusion_manager import FusionManager + xp = cp @@ -86,105 +70,6 @@ def initialize_fusion(self): self.elements_to_shift["id_max"] = id_max self.fusion_manager.register_plugin(fusion) - # def compile_kernels(self) -> None: - # """ - # Returns: - # None: - # """ - # # TODO: maybe this could be improved by creating functions for each single fusion algorithm - # - # if "average" in self.unique_fusion: - # print("Initialize fusion kernel") - # self.sum_kernel = sum_kernel( - # self.param.resolution, - # self.param.cell_n, - # self.param.cell_n, - # ) - # self.average_kernel = average_kernel( - # self.param.cell_n, - # self.param.cell_n, - # ) - # if "bayesian_inference" in self.unique_fusion: - # print("Initialize bayesian inference kernel") - # self.sum_mean = xp.ones( - # ( - # self.param.fusion_algorithms.count("bayesian_inference"), - # self.param.cell_n, - # self.param.cell_n, - # ), - # self.param.data_type, - # ) - # # TODO initialize the variance with a value different than 0 - # self.sum_compact_kernel = sum_compact_kernel( - # self.param.resolution, - # self.param.cell_n, - # self.param.cell_n, - # ) - # self.bayesian_inference_kernel = bayesian_inference_kernel( - # self.param.cell_n, - # self.param.cell_n, - # ) - # if "color" in self.unique_fusion: - # print("Initialize color kernel") - # - # self.add_color_kernel = add_color_kernel( - # self.param.cell_n, - # self.param.cell_n, - # ) - # self.color_average_kernel = color_average_kernel(self.param.cell_n, self.param.cell_n) - # if "class_average" in self.unique_fusion: - # print("Initialize class average kernel") - # self.sum_kernel = sum_kernel( - # self.param.resolution, - # self.param.cell_n, - # self.param.cell_n, - # ) - # self.class_average_kernel = class_average_kernel( - # self.param.cell_n, - # self.param.cell_n, - # self.param.average_weight, - # ) - # if "class_bayesian" in self.unique_fusion: - # print("Initialize class bayesian kernel") - # pcl_ids = self.get_layer_indices("class_bayesian") - # self.delete_new_layers[pcl_ids] = 0 - # self.alpha_kernel = alpha_kernel( - # self.param.resolution, - # self.param.cell_n, - # self.param.cell_n, - # ) - # if "class_max" in self.unique_fusion: - # print("Initialize class max kernel") - # pcl_ids = self.get_layer_indices("class_max") - # self.delete_new_layers[pcl_ids] = 0 - # self.sum_max_kernel = sum_max_kernel( - # self.param.resolution, - # self.param.cell_n, - # self.param.cell_n, - # ) - # layer_cnt = self.param.fusion_algorithms.count("class_max") - # id_max = cp.zeros( - # (layer_cnt, self.param.cell_n, self.param.cell_n), - # dtype=cp.uint32, - # ) - # self.elements_to_shift["id_max"] = id_max - # self.unique_id = cp.array([0]) - # - # if "image_exponential" in self.unique_fusion: - # self.exponential_correspondences_to_map_kernel = exponential_correspondences_to_map_kernel( - # resolution=self.param.resolution, - # width=self.param.cell_n, - # height=self.param.cell_n, - # alpha=0.7, - # ) - # - # if "image_color" in self.unique_fusion: - # self.color_correspondences_to_map_kernel = color_correspondences_to_map_kernel( - # resolution=self.param.resolution, - # width=self.param.cell_n, - # height=self.param.cell_n, - # ) - def pad_value(self, x, shift_value, idx=None, value=0.0): """Create a padding of the map along x,y-axis according to amount that has shifted. @@ -311,184 +196,6 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): self.elements_to_shift, ) - # def update_layers_pointcloud_o(self, points_all, channels, R, t, elevation_map): - # """Update the semantic map with the pointcloud. - # - # Args: - # points_all: semantic point cloud - # channels: list of channel names - # R: rotation matrix - # t: translation vector - # elevation_map: elevation map object - # """ - # additional_fusion = self.get_fusion_of_pcl(channels) - # self.new_map[self.delete_new_layers] = 0.0 - # if "average" in additional_fusion: - # pcl_ids, layer_ids = self.get_indices_fusion(channels, "average") - # self.sum_kernel( - # points_all, - # R, - # t, - # pcl_ids, - # layer_ids, - # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - # self.semantic_map, - # self.new_map, - # size=(points_all.shape[0] * pcl_ids.shape[0]), - # ) - # self.average_kernel( - # self.new_map, - # pcl_ids, - # layer_ids, - # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - # elevation_map, - # self.semantic_map, - # size=(self.param.cell_n * self.param.cell_n * pcl_ids.shape[0]), - # ) - # if "bayesian_inference" in additional_fusion: - # pcl_ids, layer_ids = self.get_indices_fusion(channels, "bayesian_inference") - # self.sum_mean *= 0 - # self.sum_compact_kernel( - # points_all, - # R, - # t, - # pcl_ids, - # layer_ids, - # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - # self.sum_mean, - # size=(points_all.shape[0]), - # ) - # self.bayesian_inference_kernel( - # pcl_ids, - # layer_ids, - # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - # elevation_map, - # self.new_map, - # self.sum_mean, - # self.semantic_map, - # size=(self.param.cell_n * self.param.cell_n), - # ) - # if "class_average" in additional_fusion: - # pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_average") - # self.sum_kernel( - # points_all, - # R, - # t, - # pcl_ids, - # layer_ids, - # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - # self.semantic_map, - # self.new_map, - # size=(points_all.shape[0] * pcl_ids.shape[0]), - # ) - # self.class_average_kernel( - # self.new_map, - # pcl_ids, - # layer_ids, - # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - # elevation_map, - # self.semantic_map, - # size=(self.param.cell_n * self.param.cell_n * pcl_ids.shape[0]), - # ) - # - # if "class_bayesian" in additional_fusion: - # pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_bayesian") - # # alpha sum get points as input and calculate for each point to what cell it belongs and then - # # adds to the right channel a one - # self.alpha_kernel( - # points_all, - # pcl_ids, - # layer_ids, - # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - # self.new_map, - # size=(points_all.shape[0]), - # ) - # # calculate new thetas - # sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) - # # do not divide by zero - # sum_alpha[sum_alpha == 0] = 1 - # self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) - # - # if "class_max" in additional_fusion: - # # get indices that are of type class_max in pointclopud and in layers - # pcl_ids, layer_ids = self.get_indices_fusion(channels, "class_max") - # # decode float32 into to float16 - # max_pt, pt_id = self.decode_max(points_all[:, pcl_ids]) - # # find unique ids in new measurement and in existing map - # unique_idm = cp.unique(pt_id) - # unique_ida = cp.unique(self.unique_id[self.elements_to_shift["id_max"]]) - # # get all unique ids, where index is the position in the prob_sum and the value in the NN class - # self.unique_id = cp.unique(cp.concatenate((unique_idm, unique_ida))) - # # contains the sum of the new measurement probabilities - # self.prob_sum = cp.zeros( - # (len(self.unique_id), self.param.cell_n, self.param.cell_n), - # dtype=np.float32, - # ) - # # transform the index matrix of the classes to the index matrix of the prob_sum - # pt_id_zero = pt_id.copy() - # for it, val in enumerate(self.unique_id): - # pt_id_zero[pt_id_zero == val] = it - # - # # sum all measurements probabilities - # self.sum_max_kernel( - # points_all, - # max_pt, - # pt_id_zero, - # pcl_ids, - # layer_ids, - # cp.array( - # [points_all.shape[1], pcl_ids.shape[0], pt_id.shape[1]], - # dtype=cp.int32, - # ), - # self.prob_sum, - # size=(points_all.shape[0]), - # ) - # # add the previous alpha - # for i, lay in enumerate(layer_ids): - # c = cp.mgrid[0 : self.new_map.shape[1], 0 : self.new_map.shape[2]] - # # self.prob_sum[self.elements_to_shift["id_max"][i], c[0], c[1]] += self.new_map[lay] - # # TODO add residual of prev alpha to the prob_sum - # # res = 1- self.new_map[lay] - # # res /= (len(self.unique_id)-1) - # - # # find the alpha we want to keep - # for i, lay in enumerate(layer_ids): - # self.new_map[lay] = cp.amax(self.prob_sum, axis=0) - # self.elements_to_shift["id_max"][lay] = self.unique_id[cp.argmax(self.prob_sum, axis=0)] - # self.prob_sum[cp.argmax(self.prob_sum, axis=0)] = 0 - # # update map calculate new thetas - # sum_alpha = cp.sum(self.new_map[layer_ids], axis=0) - # # do not divide by zero - # sum_alpha[sum_alpha == 0] = 1 - # self.semantic_map[layer_ids] = self.new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) - # - # if "color" in additional_fusion: - # pcl_ids, layer_ids = self.get_indices_fusion(channels, "color") - # self.color_map = cp.zeros( - # (1 + 3 * layer_ids.shape[0], self.param.cell_n, self.param.cell_n), - # dtype=cp.uint32, - # ) - # - # points_all = points_all.astype(cp.float32) - # self.add_color_kernel( - # points_all, - # R, - # t, - # pcl_ids, - # layer_ids, - # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - # self.color_map, - # size=(points_all.shape[0]), - # ) - # self.color_average_kernel( - # self.color_map, - # pcl_ids, - # layer_ids, - # cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - # self.semantic_map, - # size=(self.param.cell_n * self.param.cell_n), - # ) - def update_layers_image( self, sub_key: str, @@ -516,7 +223,6 @@ def update_layers_image( for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): sem_map_idx = self.get_index(channel) - # which layers need to be updated with this fusion algorithm # pcl_ids, layer_ids = self.get_indices_fusion(channels, fusion) # update the layers with the fusion algorithm @@ -532,42 +238,6 @@ def update_layers_image( self.semantic_map, self.new_map, ) - # self.new_map *= 0 - # config = self.param.subscriber_cfg[sub_key] - # - # for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): - # sem_map_idx = self.get_index(channel) - # - # if fusion == "image_exponential": - # self.exponential_correspondences_to_map_kernel( - # self.semantic_map, - # cp.uint64(sem_map_idx), - # image[j], - # uv_correspondence, - # valid_correspondence, - # image_height, - # image_width, - # self.new_map, - # size=int(self.param.cell_n * self.param.cell_n), - # ) - # self.semantic_map[sem_map_idx] = self.new_map[sem_map_idx] - # - # elif fusion == "image_color": - # self.color_correspondences_to_map_kernel( - # self.semantic_map, - # cp.uint64(sem_map_idx), - # image, - # uv_correspondence, - # valid_correspondence, - # image_height, - # image_width, - # self.new_map, - # size=int(self.param.cell_n * self.param.cell_n), - # ) - # self.semantic_map[sem_map_idx] = self.new_map[sem_map_idx] - # - # else: - # raise ValueError("Fusion for image is unknown.") def decode_max(self, mer): """Decode the float32 value into two 16 bit value containing the class probability and the class id. From 4ccd82412a7c76dea27f4d68bd756159963ad341 Mon Sep 17 00:00:00 2001 From: Gian Date: Mon, 5 Jun 2023 14:41:34 +0200 Subject: [PATCH 345/504] documentation --- docs/source/documentation.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/documentation.rst b/docs/source/documentation.rst index e38e938b..211f6594 100644 --- a/docs/source/documentation.rst +++ b/docs/source/documentation.rst @@ -1,7 +1,7 @@ ################################################## -Elevation Mapping cupy documentation +Multi-modal elevation mapping's documentation ################################################## -Weclome to Elevation Mapping documentation +Weclome to elevation mapping documentation .. image:: https://github.com/leggedrobotics/elevation_mapping_semantic_cupy/actions/workflows/python-tests.yml/badge.svg :target: https://github.com/leggedrobotics/elevation_mapping_semantic_cupy/actions/workflows/python-tests.yml/badge.svg From 0244e88e299f92fff5ec08c551f13a9b4065fab9 Mon Sep 17 00:00:00 2001 From: Gian Date: Mon, 5 Jun 2023 14:46:34 +0200 Subject: [PATCH 346/504] documentation --- docs/source/documentation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/documentation.rst b/docs/source/documentation.rst index 211f6594..a825a87c 100644 --- a/docs/source/documentation.rst +++ b/docs/source/documentation.rst @@ -1,7 +1,7 @@ ################################################## Multi-modal elevation mapping's documentation ################################################## -Weclome to elevation mapping documentation +Welcome to elevation mapping documentation .. image:: https://github.com/leggedrobotics/elevation_mapping_semantic_cupy/actions/workflows/python-tests.yml/badge.svg :target: https://github.com/leggedrobotics/elevation_mapping_semantic_cupy/actions/workflows/python-tests.yml/badge.svg From cc07209b8f11d4fe4a464de14bfb9162b8f11f3b Mon Sep 17 00:00:00 2001 From: Gian Date: Mon, 5 Jun 2023 15:26:27 +0200 Subject: [PATCH 347/504] updated a bit the documentation --- docs/source/index.rst | 2 +- docs/source/python/custom_kernels.rst | 9 ------ docs/source/python/elevation_mapping.rst | 14 +++++++-- docs/source/python/index.rst | 2 +- docs/source/python/semantic_sensor.rst | 39 ++++++++++++++++++++++++ 5 files changed, 53 insertions(+), 13 deletions(-) delete mode 100644 docs/source/python/custom_kernels.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index bef11bf9..808139c6 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -27,7 +27,7 @@ .. toctree:: :hidden: - :maxdepth: 2 + :maxdepth: 3 :caption: Library Python diff --git a/docs/source/python/custom_kernels.rst b/docs/source/python/custom_kernels.rst deleted file mode 100644 index d0367329..00000000 --- a/docs/source/python/custom_kernels.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. _custom_kernels: - -Custom kernels -****************************************************************** - -.. automodule:: elevation_mapping_cupy.custom_kernels - :members: - - diff --git a/docs/source/python/elevation_mapping.rst b/docs/source/python/elevation_mapping.rst index 0283d01c..03bb1e28 100644 --- a/docs/source/python/elevation_mapping.rst +++ b/docs/source/python/elevation_mapping.rst @@ -5,15 +5,25 @@ Elevation mapping cupy .. automodule:: elevation_mapping_cupy.elevation_mapping :members: + :undoc-members: + :show-inheritance: .. automodule:: elevation_mapping_cupy.semantic_map :members: + :undoc-members: + :show-inheritance: .. automodule:: elevation_mapping_cupy.parameter :members: + :undoc-members: + :show-inheritance: .. automodule:: elevation_mapping_cupy.plugins.plugin_manager :members: + :undoc-members: + :show-inheritance: - - +.. automodule:: elevation_mapping_cupy.fusion + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/python/index.rst b/docs/source/python/index.rst index bf697bf9..d2eb5593 100644 --- a/docs/source/python/index.rst +++ b/docs/source/python/index.rst @@ -4,5 +4,5 @@ Python software .. toctree:: elevation_mapping semantic_sensor - custom_kernels + diff --git a/docs/source/python/semantic_sensor.rst b/docs/source/python/semantic_sensor.rst index f3f8aa5e..37904e19 100644 --- a/docs/source/python/semantic_sensor.rst +++ b/docs/source/python/semantic_sensor.rst @@ -6,3 +6,42 @@ Semantic Pointcloud .. automodule:: semantic_sensor.pointcloud_node :members: + :undoc-members: + :show-inheritance: + + +.. automodule:: semantic_sensor.pointcloud_parameters + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: semantic_sensor.image_node + :members: + :undoc-members: + :show-inheritance: + + +.. automodule:: semantic_sensor.image_parameters + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: semantic_sensor.networks + :members: + :undoc-members: + :show-inheritance: + + +.. automodule:: semantic_sensor.utils + :members: + :undoc-members: + :show-inheritance: + + + + + + + + + From 2ce9a62b257c95d9970d80ac357e86ef180eac86 Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 6 Jun 2023 10:50:44 +0200 Subject: [PATCH 348/504] removed differentation of img and pcl in config --- .../fusion/fusion_manager.py | 10 +++++---- .../{average.py => pointcloud_average.py} | 2 +- ...ce.py => pointcloud_bayesian_inference.py} | 2 +- ...average.py => pointcloud_class_average.py} | 2 +- ...yesian.py => pointcloud_class_bayesian.py} | 2 +- .../{class_max.py => pointcloud_class_max.py} | 2 +- .../fusion/{color.py => pointcloud_color.py} | 2 +- .../elevation_mapping_cupy/fusion/template.py | 22 ------------------- .../elevation_mapping_cupy/semantic_map.py | 9 ++++---- 9 files changed, 17 insertions(+), 36 deletions(-) rename elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/{average.py => pointcloud_average.py} (98%) rename elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/{bayesian_inference.py => pointcloud_bayesian_inference.py} (98%) rename elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/{class_average.py => pointcloud_class_average.py} (98%) rename elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/{class_bayesian.py => pointcloud_class_bayesian.py} (98%) rename elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/{class_max.py => pointcloud_class_max.py} (99%) rename elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/{color.py => pointcloud_color.py} (99%) delete mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/template.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py index 1378ec6d..7910096d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py @@ -50,14 +50,16 @@ def register_plugin(self, plugin): if inspect.isclass(obj) and issubclass(obj, FusionBase) and name != "FusionBase": self.plugins.append(obj(self.params)) - def get_plugin_idx(self, name: str): + def get_plugin_idx(self, name: str, data_type: str): """ Get a registered fusion plugin """ + name = data_type + "_" + name for idx, plugin in enumerate(self.plugins): if plugin.name == name: return idx - + print("Plugin {} is not in the list: {}".format(name, self.plugins)) + return None def execute_plugin( self, name: str, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, elements_to_shift @@ -65,7 +67,7 @@ def execute_plugin( """ Execute a registered fusion plugin """ - idx = self.get_plugin_idx(name) + idx = self.get_plugin_idx(name, "pointcloud") if idx is not None: self.plugins[idx]( points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, elements_to_shift @@ -89,7 +91,7 @@ def execute_image_plugin( """ Execute a registered fusion plugin """ - idx = self.get_plugin_idx(name) + idx = self.get_plugin_idx(name, "image") if idx is not None: self.plugins[idx]( sem_map_idx, diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/average.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py similarity index 98% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/average.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py index 140ef8b9..3d2e25e4 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/average.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py @@ -87,7 +87,7 @@ class Average(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) print("Initialize fusion kernel") - self.name = "average" + self.name = "pointcloud_average" self.cell_n = params.cell_n self.resolution = params.resolution self.sum_kernel = sum_kernel( diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/bayesian_inference.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py similarity index 98% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/bayesian_inference.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py index ac066554..6cecd03b 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/bayesian_inference.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py @@ -85,7 +85,7 @@ class BayesianInference(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) print("Initialize bayesian inference kernel") - self.name = "bayesian_inference" + self.name = "pointcloud_bayesian_inference" self.cell_n = params.cell_n self.resolution = params.resolution diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_average.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py similarity index 98% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_average.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py index 8705234f..ba45d034 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_average.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py @@ -98,7 +98,7 @@ class ClassAverage(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) print("Initialize fusion kernel") - self.name = "class_average" + self.name = "pointcloud_class_average" self.cell_n = params.cell_n self.resolution = params.resolution self.average_weight = params.average_weight diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_bayesian.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py similarity index 98% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_bayesian.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py index f3074783..5ae9d2b4 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_bayesian.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py @@ -54,7 +54,7 @@ class ClassBayesian(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) print("Initialize fusion kernel") - self.name = "class_bayesian" + self.name = "pointcloud_class_bayesian" self.cell_n = params.cell_n self.resolution = params.resolution self.alpha_kernel = alpha_kernel( diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_max.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py similarity index 99% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_max.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py index d7230518..65a4df03 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/class_max.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py @@ -50,7 +50,7 @@ class ClassMax(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) print("Initialize fusion kernel") - self.name = "class_max" + self.name = "pointcloud_class_max" self.cell_n = params.cell_n self.resolution = params.resolution self.fusion_algorithms = params.fusion_algorithms diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/color.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py similarity index 99% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/color.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py index e622900b..a6c0cb1f 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/color.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py @@ -120,7 +120,7 @@ class Color(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) print("Initialize fusion kernel") - self.name = "color" + self.name = "pointcloud_color" self.cell_n = params.cell_n self.resolution = params.resolution diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/template.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/template.py deleted file mode 100644 index 8cfcec82..00000000 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/template.py +++ /dev/null @@ -1,22 +0,0 @@ -import cupy as cp -import numpy as np -import string - -from .fusion_manager import FusionBase - - - - - -class Color(FusionBase): - def __init__(self, params, *args, **kwargs): - # super().__init__(fusion_params, *args, **kwargs) - print("Initialize fusion kernel") - self.cell_n = params.cell_n - self.resolution = params.resolution - - - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,*args): - pass - - diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 9e4b553f..50ff5839 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -21,6 +21,7 @@ def __init__(self, param: Parameter): self.layer_specs = {} self.layer_names = [] self.unique_fusion = [] + self.unique_data = [] self.elements_to_shift = {} for k, config in self.param.subscriber_cfg.items(): @@ -31,7 +32,8 @@ def __init__(self, param: Parameter): else: assert self.layer_specs[c] == f, "Error: Single layer has multiple fusion algorithms!" if f not in self.unique_fusion: - self.unique_fusion.append(f) + dt = config["data_type"] + self.unique_fusion.append(dt+"_"+f) self.amount_layer_names = len(self.layer_names) @@ -54,12 +56,11 @@ def clear(self): def initialize_fusion(self): """Initialize the fusion algorithms.""" - for fusion in self.unique_fusion: - if "class_bayesian" == fusion: + if "pointcloud_class_bayesian" == fusion: pcl_ids = self.get_layer_indices("class_bayesian") self.delete_new_layers[pcl_ids] = 0 - if "class_max" == fusion: + if "pointcloud_class_max" == fusion: pcl_ids = self.get_layer_indices("class_max") self.delete_new_layers[pcl_ids] = 0 layer_cnt = self.param.fusion_algorithms.count("class_max") From fceaad177b0fa779b969543ea787d30db2a236ac Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 6 Jun 2023 13:50:12 +0200 Subject: [PATCH 349/504] changed a few things on the plugins --- .../elevation_mapping.py | 4 +- .../plugins/features_pca.py | 9 ++-- .../plugins/plugin_manager.py | 43 +++++++++++++------ .../plugins/robot_centric_elevation.py | 1 + .../plugins/semantic_filter.py | 27 ++++++------ .../plugins/semantic_traversability.py | 10 +++-- .../elevation_mapping_cupy/semantic_map.py | 1 - .../tests/test_plugins.py | 2 +- 8 files changed, 60 insertions(+), 37 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index d6a7c87f..16504f53 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -725,8 +725,10 @@ def get_map_with_name_ref(self, name, data): name, self.elevation_map, self.layer_names, - self.semantic_map, + self.semantic_map.semantic_map, + self.semantic_map.param, self.base_rotation, + self.semantic_map.elements_to_shift, ) m = self.plugin_manager.get_map_with_name(name) p = self.plugin_manager.get_param_with_name(name) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py index b0228870..b62ead31 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py @@ -33,6 +33,7 @@ def __call__( plugin_layers: cp.ndarray, plugin_layer_names: List[str], semantic_map, + semantic_params, *args, ) -> cp.ndarray: """ @@ -50,15 +51,15 @@ def __call__( """ # get indices of all layers that contain semantic features information layer_indices = cp.array([], dtype=cp.int32) - for it, fusion_alg in enumerate(semantic_map.param.fusion_algorithms): - if fusion_alg in ["average", "bayesian_inference","image_exponential"]: + for it, fusion_alg in enumerate(semantic_params.fusion_algorithms): + if fusion_alg in ["average", "bayesian_inference", "image_exponential"]: layer_indices = cp.append(layer_indices, it).astype(cp.int32) - n_c = semantic_map.semantic_map[layer_indices].shape[1] + n_c = semantic_map[layer_indices].shape[1] comp_img = np.zeros((n_c, n_c, 3), dtype=np.float32) # check which has the highest value if len(layer_indices) > 0: - data = cp.reshape(semantic_map.semantic_map[layer_indices], (len(layer_indices), -1)).T.get() + data = cp.reshape(semantic_map[layer_indices], (len(layer_indices), -1)).T.get() # data = np.clip(data, -1, 1) n_components = 3 pca = PCA(n_components=n_components).fit(data) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index ce8c990d..c04497e5 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -34,13 +34,13 @@ def __init__(self, *args, **kwargs): """ def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - *args, - **kwargs, + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + *args, + **kwargs, ) -> cp.ndarray: """This gets the elevation map data and plugin layers as a cupy array. @@ -136,25 +136,38 @@ def get_layer_index_with_name(self, name: str) -> int: return None def update_with_name( - self, - name: str, - elevation_map: cp.ndarray, - layer_names: List[str], - semantic_map=None, - rotation=None, + self, + name: str, + elevation_map: cp.ndarray, + layer_names: List[str], + semantic_map=None, + semantic_params=None, + rotation=None, + elements_to_shift={}, ): idx = self.get_layer_index_with_name(name) if idx is not None: n_param = len(signature(self.plugins[idx]).parameters) if n_param == 5: self.layers[idx] = self.plugins[idx](elevation_map, layer_names, self.layers, self.layer_names) - elif n_param == 6: + elif n_param == 7: self.layers[idx] = self.plugins[idx]( elevation_map, layer_names, self.layers, self.layer_names, semantic_map, + semantic_params, + ) + elif n_param == 8: + self.layers[idx] = self.plugins[idx]( + elevation_map, + layer_names, + self.layers, + self.layer_names, + semantic_map, + semantic_params, + rotation, ) else: self.layers[idx] = self.plugins[idx]( @@ -163,7 +176,9 @@ def update_with_name( self.layers, self.layer_names, semantic_map, + semantic_params, rotation, + elements_to_shift, ) def get_map_with_name(self, name: str) -> cp.ndarray: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py index aea7df13..47ac799a 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py @@ -89,6 +89,7 @@ def __call__( plugin_layers: cp.ndarray, plugin_layer_names: List[str], semantic_map, + semantic_params, rotation, *args, ) -> cp.ndarray: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index 223ba210..f7176169 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -66,8 +66,12 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], - semantic_map, - *args, + semantic_map: cp.ndarray, + semantic_params, + rotation, + elements_to_shift, + *args, + ) -> cp.ndarray: """ @@ -85,8 +89,8 @@ def __call__( # get indices of all layers that contain semantic class information layer_indices = cp.array([], dtype=cp.int32) max_idcs = cp.array([], dtype=cp.int32) - for it, fusion_alg in enumerate(semantic_map.param.fusion_algorithms): - if fusion_alg in ["class_bayesian", "class_average", "image_exponential"]: + for it, fusion_alg in enumerate(semantic_params.fusion_algorithms): + if fusion_alg in ["class_bayesian", "class_average", "exponential"]: layer_indices = cp.append(layer_indices, it).astype(cp.int32) # we care only for the first max in the display if fusion_alg in ["class_max"] and len(max_idcs) < 1: @@ -94,15 +98,14 @@ def __call__( # check which has the highest value if len(layer_indices) > 0: - class_map = cp.amax(semantic_map.semantic_map[layer_indices], axis=0) - class_map_id = cp.argmax(semantic_map.semantic_map[layer_indices], axis=0) + class_map = cp.amax(semantic_map[layer_indices], axis=0) + class_map_id = cp.argmax(semantic_map[layer_indices], axis=0) else: - class_map = cp.zeros_like(semantic_map.semantic_map[0]) - class_map_id = cp.zeros_like(semantic_map.semantic_map[0], dtype=cp.int32) - - if "class_max" in semantic_map.param.fusion_algorithms: - max_map = cp.amax(semantic_map.semantic_map[max_idcs], axis=0) - max_map_id = semantic_map.elements_to_shift["id_max"][max_idcs] + class_map = cp.zeros_like(semantic_map[0]) + class_map_id = cp.zeros_like(semantic_map[0], dtype=cp.int32) + if "class_max" in semantic_params.fusion_algorithms: + max_map = cp.amax(semantic_map[max_idcs], axis=0) + max_map_id = elements_to_shift["id_max"][max_idcs] map = cp.where(max_map > class_map, max_map_id, class_map_id) else: map = class_map_id diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py index 2d0b9832..7abbf714 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py @@ -39,7 +39,9 @@ def __call__( plugin_layers: cp.ndarray, plugin_layer_names: List[str], semantic_map, - *args, + semantic_params, + *args, + ) -> cp.ndarray: """ @@ -61,9 +63,9 @@ def __call__( if name in layer_names: idx = layer_names.index(name) tempo = elevation_map[idx] - elif name in semantic_map.param.additional_layers: - idx = semantic_map.param.additional_layers.index(name) - tempo = semantic_map.semantic_map[idx] + elif name in semantic_params.additional_layers: + idx = semantic_params.additional_layers.index(name) + tempo = semantic_map[idx] elif name in plugin_layer_names: idx = plugin_layer_names.index(name) tempo = plugin_layers[idx] diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 50ff5839..4aca6e62 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -180,7 +180,6 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): additional_fusion = self.get_fusion_of_pcl(channels) self.new_map[self.delete_new_layers] = 0.0 for fusion in list(set(additional_fusion)): - print(f"fusion: {fusion}") # which layers need to be updated with this fusion algorithm pcl_ids, layer_ids = self.get_indices_fusion(channels, fusion) # update the layers with the fusion algorithm diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py index 9e608cfe..6aab26ed 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -59,5 +59,5 @@ def test_plugin_manager(semmap_ex, channels): manager.update_with_name("semantic_traversability", elevation_map, layer_names, semmap_ex) manager.get_map_with_name("smooth") for lay in manager.get_layer_names(): - manager.update_with_name(lay, elevation_map, layer_names, semmap_ex, rotation) + manager.update_with_name(lay, elevation_map, layer_names, semmap_ex.semantic_map,semmap_ex.param, rotation, semmap_ex.elements_to_shift) manager.get_map_with_name(lay) From 35bbc550718ee941d299e766b4596255a26ffcd9 Mon Sep 17 00:00:00 2001 From: Gian Date: Wed, 7 Jun 2023 10:27:58 +0200 Subject: [PATCH 350/504] added the config and launch files I am actually using --- .../config/anymal_parameters.yaml | 26 ++- .../config/anymal_plugin_config.yaml | 24 +-- .../config/anymal_semantics.yaml | 111 ++++++++++ .../config/anymal_sensor_parameter.yaml | 194 +++++++++--------- elevation_mapping_cupy/config/parameters.yaml | 46 ++--- .../config/plugin_config.yaml | 40 ++-- .../config/sensor_parameter.yaml | 27 ++- .../launch/semantic_elevation_anymal.launch | 26 +++ .../semantic_elevation_lonomy_single.launch | 20 ++ 9 files changed, 340 insertions(+), 174 deletions(-) create mode 100644 elevation_mapping_cupy/config/anymal_semantics.yaml create mode 100644 elevation_mapping_cupy/launch/semantic_elevation_anymal.launch create mode 100644 elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch diff --git a/elevation_mapping_cupy/config/anymal_parameters.yaml b/elevation_mapping_cupy/config/anymal_parameters.yaml index ae2a86e4..ff53845a 100644 --- a/elevation_mapping_cupy/config/anymal_parameters.yaml +++ b/elevation_mapping_cupy/config/anymal_parameters.yaml @@ -50,7 +50,7 @@ enable_visibility_cleanup: true enable_drift_compensation: true enable_overlap_clearance: true enable_pointcloud_publishing: false -enable_drift_corrected_TF_publishing: false +enable_drift_corrected_TF_publishing: true enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. #### Traversability filter ######## @@ -61,7 +61,7 @@ weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' use_only_above_for_upper_bound: false #### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin_config.yaml' +plugin_config_file: '$(rospack find lonomy_configuration)/elevation_map/config/anymal_plugin_config.yaml' #### Publishers ######## # topic_name: @@ -70,22 +70,20 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin # fps: # Publish rate. Use smaller value than `map_acquire_fps`. publishers: elevation_map_raw: - layers: [ 'elevation', 'traversability', 'variance' ] + layers: [ 'elevation', 'traversability', 'smooth','sem_fil' ] basic_layers: [ 'elevation', 'traversability' ] fps: 2.0 - semantic_map_raw: - layers: [ 'elevation', 'traversability', 'variance', 'rgb_image', 'visual_traversability' ] - basic_layers: [ 'elevation', 'traversability' ] + + elevation_map_recordable: + layers: ['elevation', 'traversability'] + basic_layers: ['elevation', 'traversability'] fps: 2.0 - # elevation_map_recordable: - # layers: ['elevation', 'traversability'] - # basic_layers: ['elevation', 'traversability'] - # fps: 2.0 - # elevation_map_filter: - # layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb'] - # basic_layers: ['min_filter'] - # fps: 3.0 + elevation_map_filter: + layers: [ 'min_filter', 'smooth', 'inpaint', 'upper_bound','sem_fil' ] + basic_layers: [ 'min_filter' ] + fps: 2.0 + #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' diff --git a/elevation_mapping_cupy/config/anymal_plugin_config.yaml b/elevation_mapping_cupy/config/anymal_plugin_config.yaml index 9630f496..e68b8fdf 100644 --- a/elevation_mapping_cupy/config/anymal_plugin_config.yaml +++ b/elevation_mapping_cupy/config/anymal_plugin_config.yaml @@ -1,16 +1,16 @@ # Settings of the plugins. (The plugins should be stored in script/plugins) # min_filter fills in minimum value around the invalid cell. -min_filter: +min_filter: enable: True # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. + extra_params: # This params are passed to the plugin class on initialization. dilation_size: 1 # The patch size to apply iteration_n: 30 # The number of iterations # Apply smoothing. -smooth_filter: +smooth_filter: enable: True fill_nan: False is_height_layer: True @@ -27,26 +27,26 @@ inpainting: method: "telea" # telea or ns # Apply smoothing for inpainted layer -robot_centric_elevation: # Use the same name as your file name. - # type: "robot_centric_elevation" +robot_centric_elevation: # Use the same name as your file name. +# type: "robot_centric_elevation" enable: False # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - # add_value: 2.0 # Example param + extra_params: # This params are passed to the plugin class on initialization. +# add_value: 2.0 # Example param resolution: 0.04 threshold: 1.1 use_threshold: True semantic_filter: type: "semantic_filter" - enable: False + enable: True fill_nan: False is_height_layer: False layer_name: "sem_fil" extra_params: - classes: [ 'grass','tree','fence','dirt' ] + classes: ['grass','tree','fence','dirt'] semantic_traversability: type: "semantic_traversability" @@ -55,7 +55,7 @@ semantic_traversability: is_height_layer: False layer_name: "sem_traversability" extra_params: - layers: [ 'traversability','robot_centric_elevation' ] - thresholds: [ 0.3,0.5 ] - type: [ 'traversability', 'elevation' ] + layers: ['traversability','robot_centric_elevation'] + thresholds: [0.3,0.5] + type: ['traversability', 'elevation'] diff --git a/elevation_mapping_cupy/config/anymal_semantics.yaml b/elevation_mapping_cupy/config/anymal_semantics.yaml new file mode 100644 index 00000000..9e798b7a --- /dev/null +++ b/elevation_mapping_cupy/config/anymal_semantics.yaml @@ -0,0 +1,111 @@ +#### Subscribers ######## +subscribers: + sem_front: + fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] + image_topic: "/alphasense_driver_ros/cam4/debayered" + semantic_segmentation: True + sem_seg_topic: "/elevation_mapping/semantic_seg_f" + sem_seg_image_topic: "/elevation_mapping/semantic_seg_im_f" + segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" + show_label_legend: False + channels: [ 'grass','dirt','tree','sky','road','sand' ] + image_info_topic: "/alphasense_driver_ros/cam4/camera_info" + resize: 0.25 + + sem_right: + fusion: [ "class_average","class_average","class_average","class_average" ,"class_average","class_average" ] + image_topic: "/alphasense_driver_ros/cam5/debayered" + semantic_segmentation: True + sem_seg_topic: "/elevation_mapping/semantic_seg_r" + sem_seg_image_topic: "/elevation_mapping/semantic_seg_im_r" + segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" + show_label_legend: False + channels: [ 'grass','dirt','tree','sky','road','sand' ] + image_info_topic: "/alphasense_driver_ros/cam5/camera_info" + resize: 0.5 + + sem_left: + fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] + image_topic: "/alphasense_driver_ros/cam3/debayered" + semantic_segmentation: True + sem_seg_topic: "/elevation_mapping/semantic_seg_l" + sem_seg_image_topic: "/elevation_mapping/semantic_seg_im_l" + segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" + show_label_legend: False + channels: [ 'grass','dirt','tree','sky','road','sand' ] + image_info_topic: "/alphasense_driver_ros/cam3/camera_info" + resize: 0.5 + +# sem_depth_front: +# fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] +# image_topic: "/depth_camera_front/color/image_raw" +# semantic_segmentation: True +# sem_seg_topic: "/elevation_mapping/depth_semantic_seg_f" +# sem_seg_image_topic: "/elevation_mapping/depth_semantic_seg_im_f" +# segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" +# show_label_legend: False +# channels: [ 'grass','dirt','tree','sky','road','sand' ] +# image_info_topic: "/depth_camera_front/color/camera_info" +# resize: 0.5 +# +# sem_depth_left: +# fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] +# image_topic: "/depth_camera_left/color/image_raw/compressed" +# semantic_segmentation: True +# sem_seg_topic: "/elevation_mapping/depth_semantic_seg_r" +# sem_seg_image_topic: "/elevation_mapping/depth_semantic_seg_im_r" +# segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" +# show_label_legend: False +# channels: [ 'grass','dirt','tree','sky','road','sand' ] +# image_info_topic: "/depth_camera_left/color/camera_info" +# resize: 0.5 +# +# sem_depth_right: +# fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] +# image_topic: "/depth_camera_right/color/image_raw/compressed" +# semantic_segmentation: True +# sem_seg_topic: "/elevation_mapping/depth_semantic_seg_r" +# sem_seg_image_topic: "/elevation_mapping/depth_semantic_seg_im_r" +# segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" +# show_label_legend: False +# channels: [ 'grass','dirt','tree','sky','road','sand' ] +# image_info_topic: "/depth_camera_right/color/camera_info" +# resize: 0.5 + +# sem_wide_front: +# fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] +# image_topic: "/depth_camera_right/color/image_raw/compressed" +# semantic_segmentation: True +# sem_seg_topic: "/elevation_mapping/semantic_wide_seg_f" +# sem_seg_image_topic: "/elevation_mapping/depth_semantic_seg_im_r" +# segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" +# show_label_legend: False +# channels: [ 'grass','dirt','tree','sky','road','sand' ] +# image_info_topic: "/depth_camera_right/color/camera_info" +# resize: 0.5 +# +# sem_wide_back: +# fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] +# image_topic: "/depth_camera_right/color/image_raw/compressed" +# semantic_segmentation: True +# sem_seg_topic: "/elevation_mapping/semantic_wide_seg_b" +# sem_seg_image_topic: "/elevation_mapping/depth_semantic_seg_im_r" +# segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" +# show_label_legend: False +# channels: [ 'grass','dirt','tree','sky','road','sand' ] +# image_info_topic: "/depth_camera_right/color/camera_info" +# resize: 0.5 + +# sem_back: +# fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] +# image_topic: "/alphasense_driver_ros/cam6/debayered/compressed" +# semantic_segmentation: True +# sem_seg_topic: "/elevation_mapping/semantic_seg_b" +# sem_seg_image_topic: "/elevation_mapping/semantic_seg_im_b" +# segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" +# show_label_legend: False +# channels: ["grass","road",'tree','sky','sand','dirt'] +# image_info_topic: "/alphasense_driver_ros/cam6/camera_info" +# resize: 1.0 + + diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml index 4d5b6708..d756cf9e 100644 --- a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml @@ -1,122 +1,114 @@ #### Subscribers ######## subscribers: - # debug_rgb: - # fusion: ['image_color'] - # topic_name_camera: /zed2i/zed_node/left/image_rect_color - # topic_name_camera_info: /zed2i/zed_node/right/camera_info - # channels: ["rgb_image"] - # data_type: image - # fusion_types: - # array_fusion: [] - # channels: [] + # alphasense_front_rgb: + # fusion: ['image_color'] + # topic_name_camera: /alphasense_driver_ros/cam4/debayered/compressed + # topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info + # channels: ["rgb_image"] + # data_type: image + # + # alphasense_left_rgb: + # fusion: ['image_color'] + # topic_name_camera: /alphasense_driver_ros/cam3/debayered/compressed + # topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info + # channels: ["rgb_image"] + # data_type: image + # + # alphasense_right_rgb: + # fusion: ['image_color'] + # topic_name_camera: /alphasense_driver_ros/cam5/debayered/compressed + # topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info + # channels: ["rgb_image"] + # data_type: image - # debug_rgb_3_seperate: - # fusion: ['image_exponential','image_exponential','image_exponential'] - # topic_name_camera: /zed2i/zed_node/right/image - # topic_name_camera_info: /zed2i/zed_node/right/camera_info - # channels: ["r_channel", "g_channel", "b_channel"] - # data_type: image - - # debug_rgb_2_seperate: - # fusion: ['image_exponential', 'image_exponential'] - # topic_name_camera: /zed2i/zed_node/left/image_rect_color - # topic_name_camera_info: /zed2i/zed_node/right/camera_info - # channels: ["r_channel", "g_channel"] - # data_type: image + # color_depth_front: + # fusion: ['exponential','exponential','exponential','exponential','exponential','exponential'] + # topic_name_camera: /elevation_mapping/depth_semantic_seg_f + # topic_name_camera_info: /depth_camera_front/color/camera_info_resized + # channels: [ 'dirt', 'grass','tree','sky','road','sand' ] + # data_type: image + # + # color_depth_left: + # fusion: ['exponential','exponential','exponential','exponential','exponential','exponential'] + # topic_name_camera: /elevation_mapping/depth_semantic_seg_l + # topic_name_camera_info: /depth_camera_left/color/camera_info_resized + # channels: [ 'dirt', 'grass','tree','sky','road','sand' ] + # data_type: image + # + # color_depth_right: + # fusion: ['exponential','exponential','exponential','exponential','exponential','exponential'] + # topic_name_camera: /elevation_mapping/depth_semantic_seg_r + # topic_name_camera_info: /depth_camera_right/color/camera_info_resized + # channels: [ 'dirt', 'grass','tree','sky','road','sand' ] + # data_type: image - # debug_mono_exponential: - # fusion: ['image_exponential'] - # topic_name_camera: /debug_image - # topic_name_camera_info: /zed2i/zed_node/right/camera_info - # channels: ["single_channel_semantic"] - # data_type: image + wide_sem_front: + fusion: [ 'exponential','exponential','exponential','exponential','exponential','exponential' ] + topic_name_camera: /elevation_mapping/semantic_wide_seg_f + topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info_resized + channels: [ 'grass','dirt','tree','sky','road','sand' ] + data_type: image - # front_cam: - # channels: ['rgb'] - # fusion: ['color'] - # topic_name: '/elevation_mapping/pointcloud_semantic' - # data_type: pointcloud - - alphasense_front_rgb: - fusion: [ 'image_color' ] - topic_name_camera: /alphasense_driver_ros/cam4/debayered - topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info - channels: [ "rgb_image" ] + wide_sem_back: + fusion: [ 'exponential','exponential','exponential','exponential','exponential','exponential' ] + topic_name_camera: /elevation_mapping/semantic_wide_seg_b + topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info_resized + channels: [ 'grass','dirt','tree','sky','road','sand' ] data_type: image - - alphasense_left_rgb: - fusion: [ 'image_color' ] - topic_name_camera: /alphasense_driver_ros/cam3/debayered - topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info - channels: [ "rgb_image" ] + sem_pred_front: + fusion: [ 'exponential','exponential','exponential','exponential','exponential','exponential' ] + topic_name_camera: /elevation_mapping/semantic_seg_f + topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info_resized + channels: [ 'grass','dirt','tree','sky','road','sand' ] data_type: image + sem_pred_right: + fusion: [ 'exponential','exponential','exponential','exponential','exponential','exponential' ] + topic_name_camera: /elevation_mapping/semantic_seg_r + topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info_resized + channels: [ 'grass','dirt','tree','sky','road','sand' ] + data_type: image - alphasense_right_rgb: - fusion: [ 'image_color' ] - topic_name_camera: /alphasense_driver_ros/cam5/debayered - topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info - channels: [ "rgb_image" ] + sem_pred_left: + fusion: [ 'exponential','exponential','exponential','exponential','exponential','exponential' ] + topic_name_camera: /elevation_mapping/semantic_seg_l + topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info_resized + channels: [ 'grass','dirt','tree','sky','road','sand' ] data_type: image - wvn_prediction: - fusion: [ 'image_exponential' ] - topic_name_camera: '/wild_visual_navigation_node/traversability_raw' - topic_name_camera_info: '/wild_visual_navigation_node/camera_info' - channels: [ "visual_traversability" ] - data_type: image - - # front_cam: - # channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] - # fusion: ['color','average','average','class_average','class_average','class_average','class_average'] - # topic_name: '/elvation_mapping/pointcloud_semantic' - # semantic_segmentation: False - # segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' - # feature_config: - # name: 'DINO' - # interpolation: 'bilinear' - # model: "vit_small" - # patch_size: 16 - # dim: 5 - # dropout: False - # dino_feat_type: "feat" - # input_size: [80, 160] - # projection_type: "nonlinear" - # cam_info_topic: "/camera/depth/camera_info" - # image_topic: "/camera/rgb/image_raw" - # depth_topic: "/camera/depth/image_raw" - # cam_frame: camera_rgb_optical_frame - # confidence: False - # confidence_topic: "/camera/depth/image_raw" - # confidence_threshold: 10 - # feature_extractor: False + # sem_pred_left: + # fusion: ['exponential','exponential','exponential','exponential','exponential','exponential'] + # topic_name_camera: /elevation_mapping/semantic_seg_b + # topic_name_camera_info: /alphasense_driver_ros/cam6/camera_info + # channels: ["grass","road",'tree','sky','sand','dirt'] + # data_type: image front_bpearl: - channels: [ ] - fusion: [ ] + channels: [] + fusion: [] topic_name: /robot_self_filter/bpearl_front/point_cloud data_type: pointcloud rear_bpearl: - channels: [ ] - fusion: [ ] + channels: [] + fusion: [] topic_name: /robot_self_filter/bpearl_rear/point_cloud data_type: pointcloud - + # front_depth: channels: [ ] fusion: [ ] topic_name: /depth_camera_front/point_cloud_self_filtered data_type: pointcloud - - rear_depth: - channels: [ ] - fusion: [ ] - topic_name: /depth_camera_rear/point_cloud_self_filtered - data_type: pointcloud + # + # rear_depth: + # channels: [] + # fusion: [] + # topic_name: /depth_camera_rear/point_cloud_self_filtered + # data_type: pointcloud left_depth: channels: [ ] @@ -129,9 +121,15 @@ subscribers: fusion: [ ] topic_name: /depth_camera_right/point_cloud_self_filtered data_type: pointcloud - - velodyne: - channels: [ ] - fusion: [ ] - topic_name: /point_cloud_filter/lidar/point_cloud_filtered - data_type: pointcloud + +# velodyne: +# channels: [] +# fusion: [] +# topic_name: /point_cloud_filter/lidar/point_cloud_filtered +# data_type: pointcloud + +# vel_nofil: +# channels: [ ] +# fusion: [ ] +# topic_name: /lidar/point_cloud +# data_type: pointcloud diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index 614e530f..8a6fee36 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -1,6 +1,6 @@ #### Basic parameters ######## resolution: 0.04 # resolution in m. -map_length: 8 # map's size in m. +map_length: 8.0 # map's size in m. sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). mahalanobis_thresh: 2.0 # points outside this distance is outlier. outlier_variance: 0.01 # if point is outlier, add this value to the cell. @@ -40,9 +40,9 @@ max_unsafe_n: 10 # if the number of cells under s overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) -map_frame: 'odom' # The map frame where the odometry source uses. -base_frame: 'base' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'odom_corrected' +map_frame: 'enu' # The map frame where the odometry source uses. +base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. +corrected_map_frame: 'enu' #### Feature toggles ######## enable_edge_sharpen: true @@ -61,7 +61,10 @@ weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' use_only_above_for_upper_bound: false #### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/plugin_config.yaml' +plugin_config_file: '$(rospack find lonomy_configuration)/elevation_map/config/plugin_config.yaml' + +#### Subscribers ######## + #### Publishers ######## # topic_name: @@ -70,27 +73,22 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/plugin_config # fps: # Publish rate. Use smaller value than `map_acquire_fps`. publishers: elevation_map_raw: - layers: [ 'elevation', 'traversability', 'variance' ] - basic_layers: [ 'elevation', 'traversability' ] - fps: 2.0 - - semantic_map_raw: - layers: [ 'elevation', 'traversability', 'variance', 'rgb_image' ] - basic_layers: [ 'elevation', 'traversability' ] - fps: 2.0 - # elevation_map_recordable: - # layers: ['elevation', 'traversability'] - # basic_layers: ['elevation', 'traversability'] - # fps: 2.0 - # elevation_map_filter: - # layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb'] - # basic_layers: ['min_filter'] - # fps: 3.0 + layers: ['elevation', 'traversability', 'variance','rgb','sem_fil'] + basic_layers: ['elevation', 'traversability'] + fps: 5.0 +# elevation_map_recordable: +# layers: ['elevation', 'traversability'] +# basic_layers: ['elevation', 'traversability'] +# fps: 2.0 +# elevation_map_filter: +# layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','robot_centric_elevation','sem_fil','sem_traversability'] +# basic_layers: ['min_filter'] +# fps: 3.0 #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: [ 'base_footprint' ] # One tf (like ['footprint'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [ 0.0 ] # z direction. Should be same number as initialize_frame_id. +initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 5 # dilation size after the init. -initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. +initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/plugin_config.yaml b/elevation_mapping_cupy/config/plugin_config.yaml index fde55c58..881d9fdf 100644 --- a/elevation_mapping_cupy/config/plugin_config.yaml +++ b/elevation_mapping_cupy/config/plugin_config.yaml @@ -1,12 +1,12 @@ # Settings of the plugins. (The plugins should be stored in script/plugins) # min_filter fills in minimum value around the invalid cell. -min_filter: +min_filter: enable: True # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. + extra_params: # This params are passed to the plugin class on initialization. dilation_size: 1 # The patch size to apply iteration_n: 30 # The number of iterations # Apply smoothing. @@ -26,34 +26,25 @@ inpainting: extra_params: method: "telea" # telea or ns # Apply smoothing for inpainted layer -smooth_filter_1: - type: "smooth_filter" - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth_1" - extra_params: - input_layer_name: "inpaint" -robot_centric_elevation: # Use the same name as your file name. - # type: "robot_centric_elevation" + +robot_centric_elevation: # Use the same name as your file name. enable: False # weather to load this plugin fill_nan: False # Fill nans to invalid cells of elevation layer. is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - # add_value: 2.0 # Example param + extra_params: # This params are passed to the plugin class on initialization. resolution: 0.04 threshold: 1.1 use_threshold: True + semantic_filter: type: "semantic_filter" - enable: False + enable: True fill_nan: False is_height_layer: False layer_name: "sem_fil" extra_params: - classes: [ 'grass','tree','fence','person' ] - colors: [ [ 0,255,0 ],[ 120,120,0 ],[ 170,0,20 ],[ 0,0,255 ],[ 255,0,0 ] ] + classes: ['grass','tree','fence','dirt'] semantic_traversability: type: "semantic_traversability" @@ -62,6 +53,15 @@ semantic_traversability: is_height_layer: False layer_name: "sem_traversability" extra_params: - layers: [ 'traversability','robot_centric_elevation' ] - thresholds: [ 0.7,0.5 ] - type: [ 'traversability', 'elevation' ] + layers: ['traversability','robot_centric_elevation'] + thresholds: [0.3,0.5] + type: ['traversability', 'elevation'] + +features_pca: + type: "features_pca" + enable: False + fill_nan: False + is_height_layer: False + layer_name: "pca" + extra_params: + classes: ['grass','tree','fence','dirt'] diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index e263a810..469cf6d4 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -1,13 +1,28 @@ -#### Subscribers ######## subscribers: +# sensor_name: +# channels: ['feat_0','feat_1'] +# fusion: ['average','average'] +# topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: - channels: [ 'rgb' ] - fusion: [ 'color' ] + channels: ['rgb', 'grass','tree',"person" ] + fusion: [ 'color','class_average','class_average','class_average' ] topic_name: '/elvation_mapping/pointcloud_semantic' - semantic_segmentation: False - segmentation_model: 'lraspp_mobilenet_v3_large' + semantic_segmentation: True + publish_segmentation_image: True + segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large show_label_legend: False data_type: pointcloud + feature_config: + name: 'DINO' + interpolation: 'bilinear' + model: "vit_small" + patch_size: 16 + dim: 5 + dropout: False + dino_feat_type: "feat" + input_size: [80, 160] + projection_type: "nonlinear" + cam_info_topic: "/zed2i/zed_node/depth/camera_info" image_topic: "/zed2i/zed_node/left/image_rect_color" depth_topic: "/zed2i/zed_node/depth/depth_registered" @@ -15,4 +30,4 @@ subscribers: confidence: True confidence_topic: "/zed2i/zed_node/confidence/confidence_map" confidence_threshold: 10 - feature_extractor: False \ No newline at end of file + feature_extractor: False diff --git a/elevation_mapping_cupy/launch/semantic_elevation_anymal.launch b/elevation_mapping_cupy/launch/semantic_elevation_anymal.launch new file mode 100644 index 00000000..8d2f44d6 --- /dev/null +++ b/elevation_mapping_cupy/launch/semantic_elevation_anymal.launch @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch b/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch new file mode 100644 index 00000000..8c389af5 --- /dev/null +++ b/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + From cc025549371cd703bcb29e2587997d01709a801d Mon Sep 17 00:00:00 2001 From: Takahiro Miki Date: Tue, 27 Jun 2023 21:41:57 +0200 Subject: [PATCH 351/504] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6e921cfb..65eee4be 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ terrain can be efficiently generated. ![screenshot](doc/main_repo.png) ![gif](doc/convex_approximation.gif) +Large update is coming soon. Stay tuned. + ## Citing > Takahiro Miki, Lorenz Wellhausen, Ruben Grandia, Fabian Jenelten, Timon Homberger, Marco Hutter From a5adb28f08e0eff97f9f82a62d49c743712706cb Mon Sep 17 00:00:00 2001 From: Gian Date: Wed, 28 Jun 2023 20:16:03 +0200 Subject: [PATCH 352/504] created a few launch files --- README.md | 2 +- docs/media/turtlebot.png | Bin 0 -> 407607 bytes docs/source/getting_started/tutorial.rst | 30 + .../config/anymal_parameters.yaml | 94 --- .../config/anymal_plugin_config.yaml | 61 -- .../config/anymal_semantics.yaml | 111 ---- .../config/anymal_sensor_parameter.yaml | 135 ---- .../config/heap_parameters.yaml | 94 --- .../config/heap_plugin_config.yaml | 61 -- .../config/heap_sensor_parameter.yaml | 31 - .../config/image_semantics.yaml | 19 + .../config/lonomy_plugin_config.yaml | 61 -- .../config/lonomy_sensor_parameter.yaml | 42 -- elevation_mapping_cupy/config/parameters.yaml | 20 +- .../config/plugin_config.yaml | 9 +- .../semantic_image_sensor_parameter.yaml | 25 + ...rameters.yaml => semantic_parameters.yaml} | 26 +- .../config/semantic_sensor_parameter.yaml | 19 + .../config/sensor_parameter.yaml | 32 +- .../config/sim_parameters.yaml | 96 --- .../config/sim_plugin_config.yaml | 61 -- .../config/sim_sensor_parameter.yaml | 131 ---- .../anymal_semantic_elevation_single.launch | 26 - .../launch/heap_launch.launch | 17 - .../launch/lonomy_pointcloud.launch | 15 - .../lonomy_semantic_elevation_single.launch | 22 - .../launch/semantic_elevation_anymal.launch | 26 - .../semantic_elevation_lonomy_single.launch | 20 - .../sim_semantic_elevation_single.launch | 21 - .../launch/turtlesim_example.launch | 27 +- ...ointcloud.launch => turtlesim_init.launch} | 8 +- .../turtlesim_semantic_elevation.launch | 18 - .../launch/turtlesim_semantic_example.launch | 18 + .../turtlesim_semantic_image_example.launch | 19 + elevation_mapping_cupy/rviz/anymal.rviz | 570 ----------------- elevation_mapping_cupy/rviz/heap.rviz | 600 ------------------ .../rviz/lonomy_single.rviz | 494 -------------- .../rviz/turtle_example.rviz | 46 +- .../rviz/turtle_segmentation_example.rviz | 37 +- .../rviz/turtle_semantic_example.rviz | 54 +- .../fusion/image_color.py | 84 +++ .../elevation_mapping_cupy/parameter.py | 2 +- 42 files changed, 311 insertions(+), 2973 deletions(-) create mode 100644 docs/media/turtlebot.png delete mode 100644 elevation_mapping_cupy/config/anymal_parameters.yaml delete mode 100644 elevation_mapping_cupy/config/anymal_plugin_config.yaml delete mode 100644 elevation_mapping_cupy/config/anymal_semantics.yaml delete mode 100644 elevation_mapping_cupy/config/anymal_sensor_parameter.yaml delete mode 100644 elevation_mapping_cupy/config/heap_parameters.yaml delete mode 100644 elevation_mapping_cupy/config/heap_plugin_config.yaml delete mode 100644 elevation_mapping_cupy/config/heap_sensor_parameter.yaml create mode 100644 elevation_mapping_cupy/config/image_semantics.yaml delete mode 100644 elevation_mapping_cupy/config/lonomy_plugin_config.yaml delete mode 100644 elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml create mode 100644 elevation_mapping_cupy/config/semantic_image_sensor_parameter.yaml rename elevation_mapping_cupy/config/{lonomy_parameters.yaml => semantic_parameters.yaml} (88%) create mode 100644 elevation_mapping_cupy/config/semantic_sensor_parameter.yaml delete mode 100644 elevation_mapping_cupy/config/sim_parameters.yaml delete mode 100644 elevation_mapping_cupy/config/sim_plugin_config.yaml delete mode 100644 elevation_mapping_cupy/config/sim_sensor_parameter.yaml delete mode 100644 elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch delete mode 100644 elevation_mapping_cupy/launch/heap_launch.launch delete mode 100644 elevation_mapping_cupy/launch/lonomy_pointcloud.launch delete mode 100644 elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch delete mode 100644 elevation_mapping_cupy/launch/semantic_elevation_anymal.launch delete mode 100644 elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch delete mode 100644 elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch rename elevation_mapping_cupy/launch/{turtlesim_pointcloud.launch => turtlesim_init.launch} (59%) delete mode 100644 elevation_mapping_cupy/launch/turtlesim_semantic_elevation.launch create mode 100644 elevation_mapping_cupy/launch/turtlesim_semantic_example.launch create mode 100644 elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch delete mode 100644 elevation_mapping_cupy/rviz/anymal.rviz delete mode 100644 elevation_mapping_cupy/rviz/heap.rviz delete mode 100644 elevation_mapping_cupy/rviz/lonomy_single.rviz create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py diff --git a/README.md b/README.md index 0811bdf5..3b86f5dd 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Python wrapper: ````zsh python -m elevation_mapping_cupy.elevation_mapping_ros - roslaunch elevation_mapping_cupy lonomy_pointcloud.launch use_sim_time:=true + roslaunch elevation_mapping_cupy pointcloud.launch use_sim_time:=true rosbag play --clock ~/bags/good_working_wine_field_zed_topcom_rtk_person_9_2022-07-15-14-37-05.bag ```` diff --git a/docs/media/turtlebot.png b/docs/media/turtlebot.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b550aa70c5371a40cfe7e7db06787bd0cf55ac GIT binary patch literal 407607 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

-l%O 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Š(frY2>P6KB)49KVL2|iC2}iF;7^# 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

5=lrE$0N%dkl~l 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%0A`v)svIC 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

^y^t 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

4RJtHm914rob+)2yRh4iOtj3oyG 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 literal 0 HcmV?d00001 diff --git a/docs/source/getting_started/tutorial.rst b/docs/source/getting_started/tutorial.rst index e5ea68f7..12e6cb91 100644 --- a/docs/source/getting_started/tutorial.rst +++ b/docs/source/getting_started/tutorial.rst @@ -49,6 +49,13 @@ For the plane segmentation node roslaunch convex_plane_decomposition_ros convex_plane_decomposition.launch +For the sensor node + +.. code-block:: bash + + roslaunch elevation_mapping_cupy pointlcoud.launch + roslaunch elevation_mapping_cupy image.launch + Errors """"""""""""" @@ -87,8 +94,30 @@ Then, you can run the examples. For the basic version: roslaunch elevation_mapping_cupy turtlesim_example.launch +For fusing semantics into the map such as rgb from a multi modal pointcloud: + +.. image:: ../../media/turtlebot.png + :alt: Elevation map examples + +.. code-block:: bash + + export TURTLEBOT3_MODEL=waffle + roslaunch elevation_mapping_cupy turtlesim_semantic_example.launch + +For fusing semantics into the map such as rgb from an image: + +.. code-block:: bash + + export TURTLEBOT3_MODEL=waffle + roslaunch elevation_mapping_cupy turtlesim_semantic_image_example.launch + + + + Or, for the version including plane segmentation: + + .. code-block:: bash catkin build convex_plane_decomposition_ros @@ -96,6 +125,7 @@ Or, for the version including plane segmentation: roslaunch elevation_mapping_cupy turtlesim_segmentation_example.launch + To control the robot with a keyboard, a new terminal window needs to be opened. Then run diff --git a/elevation_mapping_cupy/config/anymal_parameters.yaml b/elevation_mapping_cupy/config/anymal_parameters.yaml deleted file mode 100644 index ff53845a..00000000 --- a/elevation_mapping_cupy/config/anymal_parameters.yaml +++ /dev/null @@ -1,94 +0,0 @@ -#### Basic parameters ######## -resolution: 0.04 # resolution in m. -map_length: 8 # map's size in m. -sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). -mahalanobis_thresh: 2.0 # points outside this distance is outlier. -outlier_variance: 0.01 # if point is outlier, add this value to the cell. -drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. -max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) -drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation -time_variance: 0.0001 # add this value when update_variance is called. -max_variance: 100.0 # maximum variance for each cell. -initial_variance: 1000.0 # initial variance for each cell. -traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. -dilation_size: 3 # dilation filter size before traversability filter. -wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. -min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. -position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. -orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. -position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -min_valid_distance: 0.5 # points with shorter distance will be filtered out. -max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. -ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -update_variance_fps: 5.0 # fps for updating variance. -update_pose_fps: 10.0 # fps for updating pose and shift the center of map. -time_interval: 0.1 # Time layer is updated with this interval. -map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. -publish_statistics_fps: 1.0 # Publish statistics topic in this fps. - -max_ray_length: 10.0 # maximum length for ray tracing. -cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. -cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. - -safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. -safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. -max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. - -overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) -overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - -map_frame: 'odom' # The map frame where the odometry source uses. -base_frame: 'base' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'odom_corrected' - -#### Feature toggles ######## -enable_edge_sharpen: true -enable_visibility_cleanup: true -enable_drift_compensation: true -enable_overlap_clearance: true -enable_pointcloud_publishing: false -enable_drift_corrected_TF_publishing: true -enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. - -#### Traversability filter ######## -use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. -weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter - -#### Upper bound ######## -use_only_above_for_upper_bound: false - -#### Plugins ######## -plugin_config_file: '$(rospack find lonomy_configuration)/elevation_map/config/anymal_plugin_config.yaml' - -#### Publishers ######## -# topic_name: -# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names -# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. -# fps: # Publish rate. Use smaller value than `map_acquire_fps`. -publishers: - elevation_map_raw: - layers: [ 'elevation', 'traversability', 'smooth','sem_fil' ] - basic_layers: [ 'elevation', 'traversability' ] - fps: 2.0 - - - elevation_map_recordable: - layers: ['elevation', 'traversability'] - basic_layers: ['elevation', 'traversability'] - fps: 2.0 - elevation_map_filter: - layers: [ 'min_filter', 'smooth', 'inpaint', 'upper_bound','sem_fil' ] - basic_layers: [ 'min_filter' ] - fps: 2.0 - - -#### Initializer ######## -initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: [ 'RF_FOOT', 'LF_FOOT', 'RH_FOOT', 'LH_FOOT' ] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [ 0.0, 0.0, 0.0, 0.0 ] # z direction. Should be same number as initialize_frame_id. -dilation_size_initialize: 5 # dilation size after the init. -initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. -use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/anymal_plugin_config.yaml b/elevation_mapping_cupy/config/anymal_plugin_config.yaml deleted file mode 100644 index e68b8fdf..00000000 --- a/elevation_mapping_cupy/config/anymal_plugin_config.yaml +++ /dev/null @@ -1,61 +0,0 @@ -# Settings of the plugins. (The plugins should be stored in script/plugins) - -# min_filter fills in minimum value around the invalid cell. -min_filter: - enable: True # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - dilation_size: 1 # The patch size to apply - iteration_n: 30 # The number of iterations -# Apply smoothing. -smooth_filter: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth" - extra_params: - input_layer_name: "min_filter" -# Apply inpainting using opencv -inpainting: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "inpaint" - extra_params: - method: "telea" # telea or ns -# Apply smoothing for inpainted layer - -robot_centric_elevation: # Use the same name as your file name. -# type: "robot_centric_elevation" - enable: False # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. -# add_value: 2.0 # Example param - resolution: 0.04 - threshold: 1.1 - use_threshold: True - -semantic_filter: - type: "semantic_filter" - enable: True - fill_nan: False - is_height_layer: False - layer_name: "sem_fil" - extra_params: - classes: ['grass','tree','fence','dirt'] - -semantic_traversability: - type: "semantic_traversability" - enable: False - fill_nan: False - is_height_layer: False - layer_name: "sem_traversability" - extra_params: - layers: ['traversability','robot_centric_elevation'] - thresholds: [0.3,0.5] - type: ['traversability', 'elevation'] - diff --git a/elevation_mapping_cupy/config/anymal_semantics.yaml b/elevation_mapping_cupy/config/anymal_semantics.yaml deleted file mode 100644 index 9e798b7a..00000000 --- a/elevation_mapping_cupy/config/anymal_semantics.yaml +++ /dev/null @@ -1,111 +0,0 @@ -#### Subscribers ######## -subscribers: - sem_front: - fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] - image_topic: "/alphasense_driver_ros/cam4/debayered" - semantic_segmentation: True - sem_seg_topic: "/elevation_mapping/semantic_seg_f" - sem_seg_image_topic: "/elevation_mapping/semantic_seg_im_f" - segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" - show_label_legend: False - channels: [ 'grass','dirt','tree','sky','road','sand' ] - image_info_topic: "/alphasense_driver_ros/cam4/camera_info" - resize: 0.25 - - sem_right: - fusion: [ "class_average","class_average","class_average","class_average" ,"class_average","class_average" ] - image_topic: "/alphasense_driver_ros/cam5/debayered" - semantic_segmentation: True - sem_seg_topic: "/elevation_mapping/semantic_seg_r" - sem_seg_image_topic: "/elevation_mapping/semantic_seg_im_r" - segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" - show_label_legend: False - channels: [ 'grass','dirt','tree','sky','road','sand' ] - image_info_topic: "/alphasense_driver_ros/cam5/camera_info" - resize: 0.5 - - sem_left: - fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] - image_topic: "/alphasense_driver_ros/cam3/debayered" - semantic_segmentation: True - sem_seg_topic: "/elevation_mapping/semantic_seg_l" - sem_seg_image_topic: "/elevation_mapping/semantic_seg_im_l" - segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" - show_label_legend: False - channels: [ 'grass','dirt','tree','sky','road','sand' ] - image_info_topic: "/alphasense_driver_ros/cam3/camera_info" - resize: 0.5 - -# sem_depth_front: -# fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] -# image_topic: "/depth_camera_front/color/image_raw" -# semantic_segmentation: True -# sem_seg_topic: "/elevation_mapping/depth_semantic_seg_f" -# sem_seg_image_topic: "/elevation_mapping/depth_semantic_seg_im_f" -# segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" -# show_label_legend: False -# channels: [ 'grass','dirt','tree','sky','road','sand' ] -# image_info_topic: "/depth_camera_front/color/camera_info" -# resize: 0.5 -# -# sem_depth_left: -# fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] -# image_topic: "/depth_camera_left/color/image_raw/compressed" -# semantic_segmentation: True -# sem_seg_topic: "/elevation_mapping/depth_semantic_seg_r" -# sem_seg_image_topic: "/elevation_mapping/depth_semantic_seg_im_r" -# segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" -# show_label_legend: False -# channels: [ 'grass','dirt','tree','sky','road','sand' ] -# image_info_topic: "/depth_camera_left/color/camera_info" -# resize: 0.5 -# -# sem_depth_right: -# fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] -# image_topic: "/depth_camera_right/color/image_raw/compressed" -# semantic_segmentation: True -# sem_seg_topic: "/elevation_mapping/depth_semantic_seg_r" -# sem_seg_image_topic: "/elevation_mapping/depth_semantic_seg_im_r" -# segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" -# show_label_legend: False -# channels: [ 'grass','dirt','tree','sky','road','sand' ] -# image_info_topic: "/depth_camera_right/color/camera_info" -# resize: 0.5 - -# sem_wide_front: -# fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] -# image_topic: "/depth_camera_right/color/image_raw/compressed" -# semantic_segmentation: True -# sem_seg_topic: "/elevation_mapping/semantic_wide_seg_f" -# sem_seg_image_topic: "/elevation_mapping/depth_semantic_seg_im_r" -# segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" -# show_label_legend: False -# channels: [ 'grass','dirt','tree','sky','road','sand' ] -# image_info_topic: "/depth_camera_right/color/camera_info" -# resize: 0.5 -# -# sem_wide_back: -# fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] -# image_topic: "/depth_camera_right/color/image_raw/compressed" -# semantic_segmentation: True -# sem_seg_topic: "/elevation_mapping/semantic_wide_seg_b" -# sem_seg_image_topic: "/elevation_mapping/depth_semantic_seg_im_r" -# segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" -# show_label_legend: False -# channels: [ 'grass','dirt','tree','sky','road','sand' ] -# image_info_topic: "/depth_camera_right/color/camera_info" -# resize: 0.5 - -# sem_back: -# fusion: [ "class_average","class_average","class_average","class_average","class_average","class_average" ] -# image_topic: "/alphasense_driver_ros/cam6/debayered/compressed" -# semantic_segmentation: True -# sem_seg_topic: "/elevation_mapping/semantic_seg_b" -# sem_seg_image_topic: "/elevation_mapping/semantic_seg_im_b" -# segmentation_model: "detectron_coco_panoptic_fpn_R_101_3x" -# show_label_legend: False -# channels: ["grass","road",'tree','sky','sand','dirt'] -# image_info_topic: "/alphasense_driver_ros/cam6/camera_info" -# resize: 1.0 - - diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml deleted file mode 100644 index d756cf9e..00000000 --- a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml +++ /dev/null @@ -1,135 +0,0 @@ -#### Subscribers ######## -subscribers: - # alphasense_front_rgb: - # fusion: ['image_color'] - # topic_name_camera: /alphasense_driver_ros/cam4/debayered/compressed - # topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info - # channels: ["rgb_image"] - # data_type: image - # - # alphasense_left_rgb: - # fusion: ['image_color'] - # topic_name_camera: /alphasense_driver_ros/cam3/debayered/compressed - # topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info - # channels: ["rgb_image"] - # data_type: image - # - # alphasense_right_rgb: - # fusion: ['image_color'] - # topic_name_camera: /alphasense_driver_ros/cam5/debayered/compressed - # topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info - # channels: ["rgb_image"] - # data_type: image - - # color_depth_front: - # fusion: ['exponential','exponential','exponential','exponential','exponential','exponential'] - # topic_name_camera: /elevation_mapping/depth_semantic_seg_f - # topic_name_camera_info: /depth_camera_front/color/camera_info_resized - # channels: [ 'dirt', 'grass','tree','sky','road','sand' ] - # data_type: image - # - # color_depth_left: - # fusion: ['exponential','exponential','exponential','exponential','exponential','exponential'] - # topic_name_camera: /elevation_mapping/depth_semantic_seg_l - # topic_name_camera_info: /depth_camera_left/color/camera_info_resized - # channels: [ 'dirt', 'grass','tree','sky','road','sand' ] - # data_type: image - # - # color_depth_right: - # fusion: ['exponential','exponential','exponential','exponential','exponential','exponential'] - # topic_name_camera: /elevation_mapping/depth_semantic_seg_r - # topic_name_camera_info: /depth_camera_right/color/camera_info_resized - # channels: [ 'dirt', 'grass','tree','sky','road','sand' ] - # data_type: image - - wide_sem_front: - fusion: [ 'exponential','exponential','exponential','exponential','exponential','exponential' ] - topic_name_camera: /elevation_mapping/semantic_wide_seg_f - topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info_resized - channels: [ 'grass','dirt','tree','sky','road','sand' ] - data_type: image - - wide_sem_back: - fusion: [ 'exponential','exponential','exponential','exponential','exponential','exponential' ] - topic_name_camera: /elevation_mapping/semantic_wide_seg_b - topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info_resized - channels: [ 'grass','dirt','tree','sky','road','sand' ] - data_type: image - - sem_pred_front: - fusion: [ 'exponential','exponential','exponential','exponential','exponential','exponential' ] - topic_name_camera: /elevation_mapping/semantic_seg_f - topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info_resized - channels: [ 'grass','dirt','tree','sky','road','sand' ] - data_type: image - - sem_pred_right: - fusion: [ 'exponential','exponential','exponential','exponential','exponential','exponential' ] - topic_name_camera: /elevation_mapping/semantic_seg_r - topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info_resized - channels: [ 'grass','dirt','tree','sky','road','sand' ] - data_type: image - - sem_pred_left: - fusion: [ 'exponential','exponential','exponential','exponential','exponential','exponential' ] - topic_name_camera: /elevation_mapping/semantic_seg_l - topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info_resized - channels: [ 'grass','dirt','tree','sky','road','sand' ] - data_type: image - - - - # sem_pred_left: - # fusion: ['exponential','exponential','exponential','exponential','exponential','exponential'] - # topic_name_camera: /elevation_mapping/semantic_seg_b - # topic_name_camera_info: /alphasense_driver_ros/cam6/camera_info - # channels: ["grass","road",'tree','sky','sand','dirt'] - # data_type: image - - front_bpearl: - channels: [] - fusion: [] - topic_name: /robot_self_filter/bpearl_front/point_cloud - data_type: pointcloud - - rear_bpearl: - channels: [] - fusion: [] - topic_name: /robot_self_filter/bpearl_rear/point_cloud - data_type: pointcloud - # - front_depth: - channels: [ ] - fusion: [ ] - topic_name: /depth_camera_front/point_cloud_self_filtered - data_type: pointcloud - # - # rear_depth: - # channels: [] - # fusion: [] - # topic_name: /depth_camera_rear/point_cloud_self_filtered - # data_type: pointcloud - - left_depth: - channels: [ ] - fusion: [ ] - topic_name: /depth_camera_left/point_cloud_self_filtered - data_type: pointcloud - - right_depth: - channels: [ ] - fusion: [ ] - topic_name: /depth_camera_right/point_cloud_self_filtered - data_type: pointcloud - -# velodyne: -# channels: [] -# fusion: [] -# topic_name: /point_cloud_filter/lidar/point_cloud_filtered -# data_type: pointcloud - -# vel_nofil: -# channels: [ ] -# fusion: [ ] -# topic_name: /lidar/point_cloud -# data_type: pointcloud diff --git a/elevation_mapping_cupy/config/heap_parameters.yaml b/elevation_mapping_cupy/config/heap_parameters.yaml deleted file mode 100644 index 55de512d..00000000 --- a/elevation_mapping_cupy/config/heap_parameters.yaml +++ /dev/null @@ -1,94 +0,0 @@ -#### Basic parameters ######## -resolution: 0.04 # resolution in m. -map_length: 20.0 # map's size in m. -sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). -mahalanobis_thresh: 2.0 # points outside this distance is outlier. -outlier_variance: 0.01 # if point is outlier, add this value to the cell. -drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. -max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) -drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation -time_variance: 0.0001 # add this value when update_variance is called. -max_variance: 100.0 # maximum variance for each cell. -initial_variance: 1000.0 # initial variance for each cell. -traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. -dilation_size: 3 # dilation filter size before traversability filter. -wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. -min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. -position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. -orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. -position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -min_valid_distance: 0.5 # points with shorter distance will be filtered out. -max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. -ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -update_variance_fps: 5.0 # fps for updating variance. -update_pose_fps: 10.0 # fps for updating pose and shift the center of map. -time_interval: 0.1 # Time layer is updated with this interval. -map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. -publish_statistics_fps: 1.0 # Publish statistics topic in this fps. - -max_ray_length: 10.0 # maximum length for ray tracing. -cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. -cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. - -safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. -safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. -max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. - -overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) -overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - -map_frame: 'map' # The map frame where the odometry source uses. -base_frame: 'BASE' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'map' - -#### Feature toggles ######## -enable_edge_sharpen: true -enable_visibility_cleanup: true -enable_drift_compensation: true -enable_overlap_clearance: false -enable_pointcloud_publishing: false -enable_drift_corrected_TF_publishing: false -enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. - -#### Traversability filter ######## -use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. -weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter - -#### Upper bound ######## -use_only_above_for_upper_bound: false - -#### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/heap_plugin_config.yaml' - -#### Subscribers ######## - - -#### Publishers ######## -# topic_name: -# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names -# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. -# fps: # Publish rate. Use smaller value than `map_acquire_fps`. -publishers: - elevation_map_raw: - layers: [ 'elevation', 'traversability', 'variance' ] - basic_layers: [ 'elevation', 'traversability' ] - fps: 5.0 - # elevation_map_recordable: - # layers: ['elevation', 'traversability'] - # basic_layers: ['elevation', 'traversability'] - # fps: 2.0 - elevation_map_filter: - layers: [ 'min_filter', 'smooth', 'inpaint', 'elevation','rgb_image','sem_fil' ] - basic_layers: [ 'min_filter' ] - fps: 3.0 - -#### Initializer ######## -initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: [ 'RH_WHEEL_CONTACT','RF_WHEEL_CONTACT','LH_WHEEL_CONTACT','LF_WHEEL_CONTACT' ] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [ 0.0, 0.0, 0.0, 0.0 ] # z direction. Should be same number as initialize_frame_id. -dilation_size_initialize: 5 # dilation size after the init. -initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. -use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/heap_plugin_config.yaml b/elevation_mapping_cupy/config/heap_plugin_config.yaml deleted file mode 100644 index 9630f496..00000000 --- a/elevation_mapping_cupy/config/heap_plugin_config.yaml +++ /dev/null @@ -1,61 +0,0 @@ -# Settings of the plugins. (The plugins should be stored in script/plugins) - -# min_filter fills in minimum value around the invalid cell. -min_filter: - enable: True # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - dilation_size: 1 # The patch size to apply - iteration_n: 30 # The number of iterations -# Apply smoothing. -smooth_filter: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth" - extra_params: - input_layer_name: "min_filter" -# Apply inpainting using opencv -inpainting: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "inpaint" - extra_params: - method: "telea" # telea or ns -# Apply smoothing for inpainted layer - -robot_centric_elevation: # Use the same name as your file name. - # type: "robot_centric_elevation" - enable: False # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - # add_value: 2.0 # Example param - resolution: 0.04 - threshold: 1.1 - use_threshold: True - -semantic_filter: - type: "semantic_filter" - enable: False - fill_nan: False - is_height_layer: False - layer_name: "sem_fil" - extra_params: - classes: [ 'grass','tree','fence','dirt' ] - -semantic_traversability: - type: "semantic_traversability" - enable: False - fill_nan: False - is_height_layer: False - layer_name: "sem_traversability" - extra_params: - layers: [ 'traversability','robot_centric_elevation' ] - thresholds: [ 0.3,0.5 ] - type: [ 'traversability', 'elevation' ] - diff --git a/elevation_mapping_cupy/config/heap_sensor_parameter.yaml b/elevation_mapping_cupy/config/heap_sensor_parameter.yaml deleted file mode 100644 index 9fd09452..00000000 --- a/elevation_mapping_cupy/config/heap_sensor_parameter.yaml +++ /dev/null @@ -1,31 +0,0 @@ -subscribers: - - front_cam: - channels: [ ] - fusion: [ ] - topic_name: '/ouster_points_self_filtered' - data_type: pointcloud - - # camera_right_rgb: - # fusion: ['image_color'] - # topic_name_camera: /camUSBRightView/Downsampled - # topic_name_camera_info: /camera_info - # channels: ["rgb_image"] - # data_type: image - - camera_main_rgb: - fusion: [ 'image_color' ] - topic_name_camera: /camMainView/Downsampled - topic_name_camera_info: /camera_info - channels: [ "rgb_image" ] - data_type: image - - -# camera_cnn: -# topic_name_camera: /src/image -# topic_name_camera_info: /camera_info -# channels: ["mono"] -# fusion: [ 'image_exponential' ] -# data_type: image - - diff --git a/elevation_mapping_cupy/config/image_semantics.yaml b/elevation_mapping_cupy/config/image_semantics.yaml new file mode 100644 index 00000000..6354cc3a --- /dev/null +++ b/elevation_mapping_cupy/config/image_semantics.yaml @@ -0,0 +1,19 @@ +#### Subscribers ######## +subscribers: + front_cam: + channels: ['rgb'] + fusion: [ 'color' ] + semantic_segmentation: False + publish_segmentation_image: True + segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large + show_label_legend: False + data_type: image + image_info_topic: "/wide_angle_camera_front/camera_info" + resize: 0.5 + + cam_info_topic: "/camera/depth/camera_info" + image_topic: "/camera/rgb/image_raw" + depth_topic: "/camera/depth/image_raw" + cam_frame: "camera_rgb_optical_frame" + sem_seg_topic: "/elevation_mapping/semantic_wide_seg_f" + sem_seg_image_topic: "/elevation_mapping/semantic_wide_seg_im_f" \ No newline at end of file diff --git a/elevation_mapping_cupy/config/lonomy_plugin_config.yaml b/elevation_mapping_cupy/config/lonomy_plugin_config.yaml deleted file mode 100644 index 7bcc17f0..00000000 --- a/elevation_mapping_cupy/config/lonomy_plugin_config.yaml +++ /dev/null @@ -1,61 +0,0 @@ -# Settings of the plugins. (The plugins should be stored in script/plugins) - -# min_filter fills in minimum value around the invalid cell. -min_filter: - enable: True # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - dilation_size: 1 # The patch size to apply - iteration_n: 30 # The number of iterations -# Apply smoothing. -smooth_filter: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth" - extra_params: - input_layer_name: "min_filter" -# Apply inpainting using opencv -inpainting: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "inpaint" - extra_params: - method: "telea" # telea or ns -# Apply smoothing for inpainted layer - -robot_centric_elevation: # Use the same name as your file name. - # type: "robot_centric_elevation" - enable: True # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - # add_value: 2.0 # Example param - resolution: 0.04 - threshold: 1.1 - use_threshold: True - -semantic_filter: - type: "semantic_filter" - enable: True - fill_nan: False - is_height_layer: False - layer_name: "sem_fil" - extra_params: - classes: [ 'grass','tree','fence','dirt' ] - -semantic_traversability: - type: "semantic_traversability" - enable: True - fill_nan: False - is_height_layer: False - layer_name: "sem_traversability" - extra_params: - layers: [ 'traversability','robot_centric_elevation' ] - thresholds: [ 0.3,0.5 ] - type: [ 'traversability', 'elevation' ] - diff --git a/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml b/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml deleted file mode 100644 index 34e7e0c9..00000000 --- a/elevation_mapping_cupy/config/lonomy_sensor_parameter.yaml +++ /dev/null @@ -1,42 +0,0 @@ -subscribers: - front_cam: - channels: [ 'rgb','feat_0','feat_1' ] - fusion: [ 'color','bayesian_inference','bayesian_inference' ] - topic_name: '/elvation_mapping/pointcloud_semantic' - semantic_segmentation: False - segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large - show_label_legend: True - data_type: pointcloud - feature_config: - name: 'DINO' - interpolation: 'bilinear' - model: "vit_small" - patch_size: 16 - dim: 5 - dropout: False - dino_feat_type: "feat" - input_size: [ 80, 160 ] - projection_type: "nonlinear" - - cam_info_topic: "/zed2i/zed_node/depth/camera_info" - image_topic: "/zed2i/zed_node/left/image_rect_color" - depth_topic: "/zed2i/zed_node/depth/depth_registered" - cam_frame: "zed2i_right_camera_optical_frame" - confidence: True - confidence_topic: "/zed2i/zed_node/confidence/confidence_map" - confidence_threshold: 10 - feature_extractor: False - - rgb_cam: - fusion: [ 'image_color' ] - topic_name_camera: "/zed2i/zed_node/left/image_rect_color" - topic_name_camera_info: "/zed2i/zed_node/depth/camera_info" - channels: [ "rgb_image" ] - data_type: image - - grey_cam: - fusion: [ 'image_exponential' ] - topic_name_camera: "/zed2i/zed_node/left/image_rect_gray" - topic_name_camera_info: "/zed2i/zed_node/depth/camera_info" - channels: [ "gray_image" ] - data_type: image \ No newline at end of file diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/parameters.yaml index 8a6fee36..8354b36f 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/parameters.yaml @@ -40,9 +40,9 @@ max_unsafe_n: 10 # if the number of cells under s overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) -map_frame: 'enu' # The map frame where the odometry source uses. +map_frame: 'odom' # The map frame where the odometry source uses. base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'enu' +corrected_map_frame: 'odom' #### Feature toggles ######## enable_edge_sharpen: true @@ -61,7 +61,7 @@ weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' use_only_above_for_upper_bound: false #### Plugins ######## -plugin_config_file: '$(rospack find lonomy_configuration)/elevation_map/config/plugin_config.yaml' +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/plugin_config.yaml' #### Subscribers ######## @@ -73,22 +73,22 @@ plugin_config_file: '$(rospack find lonomy_configuration)/elevation_map/config/p # fps: # Publish rate. Use smaller value than `map_acquire_fps`. publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb','sem_fil'] - basic_layers: ['elevation', 'traversability'] + layers: ['elevation', 'traversability', 'variance','rgb'] + basic_layers: ['elevation'] fps: 5.0 # elevation_map_recordable: # layers: ['elevation', 'traversability'] # basic_layers: ['elevation', 'traversability'] # fps: 2.0 -# elevation_map_filter: -# layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','robot_centric_elevation','sem_fil','sem_traversability'] -# basic_layers: ['min_filter'] -# fps: 3.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + basic_layers: ['min_filter'] + fps: 3.0 #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. -dilation_size_initialize: 5 # dilation size after the init. +dilation_size_initialize: 2 # dilation size after the init. initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/plugin_config.yaml b/elevation_mapping_cupy/config/plugin_config.yaml index 881d9fdf..a4aa684a 100644 --- a/elevation_mapping_cupy/config/plugin_config.yaml +++ b/elevation_mapping_cupy/config/plugin_config.yaml @@ -57,11 +57,4 @@ semantic_traversability: thresholds: [0.3,0.5] type: ['traversability', 'elevation'] -features_pca: - type: "features_pca" - enable: False - fill_nan: False - is_height_layer: False - layer_name: "pca" - extra_params: - classes: ['grass','tree','fence','dirt'] + diff --git a/elevation_mapping_cupy/config/semantic_image_sensor_parameter.yaml b/elevation_mapping_cupy/config/semantic_image_sensor_parameter.yaml new file mode 100644 index 00000000..75c690f4 --- /dev/null +++ b/elevation_mapping_cupy/config/semantic_image_sensor_parameter.yaml @@ -0,0 +1,25 @@ +subscribers: +# sensor_name: +# channels: ['feat_0','feat_1'] +# fusion: ['average','average'] +# topic_name: '/elevation_mapping/pointcloud_semantic' + front_cam: + channels: ['rgb', 'grass','tree',"person" ] + fusion: [ 'color','exponential','exponential','exponential' ] + topic_name: '/elevation_mapping/pointcloud_semantic' + semantic_segmentation: True + publish_segmentation_image: True + segmentation_model: 'lraspp_mobilenet_v3_large' + show_label_legend: False + data_type: image + + cam_info_topic: "/camera/depth/camera_info" + image_topic: "/camera/rgb/image_raw" + depth_topic: "/camera/depth/image_raw" + cam_frame: "camera_rgb_optical_frame" + + pointcloud: + channels: [] + fusion: [] + topic_name: '/elevation_mapping/pointcloud_semantic' + data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/config/lonomy_parameters.yaml b/elevation_mapping_cupy/config/semantic_parameters.yaml similarity index 88% rename from elevation_mapping_cupy/config/lonomy_parameters.yaml rename to elevation_mapping_cupy/config/semantic_parameters.yaml index e1d71f9b..c471af5d 100644 --- a/elevation_mapping_cupy/config/lonomy_parameters.yaml +++ b/elevation_mapping_cupy/config/semantic_parameters.yaml @@ -40,9 +40,9 @@ max_unsafe_n: 10 # if the number of cells under s overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) -map_frame: 'enu' # The map frame where the odometry source uses. +map_frame: 'odom' # The map frame where the odometry source uses. base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'enu' +corrected_map_frame: 'odom' #### Feature toggles ######## enable_edge_sharpen: true @@ -61,7 +61,7 @@ weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' use_only_above_for_upper_bound: false #### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/lonomy_plugin_config.yaml' +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/plugin_config.yaml' #### Subscribers ######## @@ -73,22 +73,22 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/lonomy_plugin # fps: # Publish rate. Use smaller value than `map_acquire_fps`. publishers: elevation_map_raw: - layers: [ 'elevation', 'traversability', 'variance' ] - basic_layers: [ 'elevation', 'traversability' ] + layers: ['elevation', 'traversability', 'variance','rgb','sem_fil'] + basic_layers: ['elevation'] fps: 5.0 - elevation_map_recordable: - layers: [ 'elevation', 'traversability' ] - basic_layers: [ 'elevation', 'traversability' ] - fps: 2.0 +# elevation_map_recordable: +# layers: ['elevation', 'traversability'] +# basic_layers: ['elevation', 'traversability'] +# fps: 2.0 elevation_map_filter: - layers: [ elevation, 'min_filter', 'smooth', 'inpaint', 'upper_bound','rgb_image', 'gray_image' ] - basic_layers: [ elevation, 'min_filter' ] + layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','robot_centric_elevation','sem_fil','sem_traversability'] + basic_layers: ['min_filter'] fps: 3.0 #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: [ 'base_footprint' ] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [ 0.0, 0.0, 0.0, 0.0 ] # z direction. Should be same number as initialize_frame_id. +initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 5 # dilation size after the init. initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/semantic_sensor_parameter.yaml b/elevation_mapping_cupy/config/semantic_sensor_parameter.yaml new file mode 100644 index 00000000..11a8de8e --- /dev/null +++ b/elevation_mapping_cupy/config/semantic_sensor_parameter.yaml @@ -0,0 +1,19 @@ +subscribers: +# sensor_name: +# channels: ['feat_0','feat_1'] +# fusion: ['average','average'] +# topic_name: '/elevation_mapping/pointcloud_semantic' + front_cam: + channels: ['rgb', 'grass','tree',"person" ] + fusion: [ 'color','class_average','class_average','class_average' ] + topic_name: '/elevation_mapping/pointcloud_semantic' + semantic_segmentation: True + publish_segmentation_image: True + segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large + show_label_legend: False + data_type: pointcloud + + cam_info_topic: "/camera/depth/camera_info" + image_topic: "/camera/rgb/image_raw" + depth_topic: "/camera/depth/image_raw" + cam_frame: "camera_rgb_optical_frame" diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml index 469cf6d4..3aa14712 100644 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/sensor_parameter.yaml @@ -4,30 +4,12 @@ subscribers: # fusion: ['average','average'] # topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: - channels: ['rgb', 'grass','tree',"person" ] - fusion: [ 'color','class_average','class_average','class_average' ] - topic_name: '/elvation_mapping/pointcloud_semantic' - semantic_segmentation: True - publish_segmentation_image: True - segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large - show_label_legend: False + channels: ['rgb' ] + fusion: [ 'color'] + topic_name: '/elevation_mapping/pointcloud_semantic' data_type: pointcloud - feature_config: - name: 'DINO' - interpolation: 'bilinear' - model: "vit_small" - patch_size: 16 - dim: 5 - dropout: False - dino_feat_type: "feat" - input_size: [80, 160] - projection_type: "nonlinear" - cam_info_topic: "/zed2i/zed_node/depth/camera_info" - image_topic: "/zed2i/zed_node/left/image_rect_color" - depth_topic: "/zed2i/zed_node/depth/depth_registered" - cam_frame: "zed2i_right_camera_optical_frame" - confidence: True - confidence_topic: "/zed2i/zed_node/confidence/confidence_map" - confidence_threshold: 10 - feature_extractor: False + cam_info_topic: "/camera/depth/camera_info" + image_topic: "/camera/rgb/image_raw" + depth_topic: "/camera/depth/image_raw" + cam_frame: "camera_rgb_optical_frame" diff --git a/elevation_mapping_cupy/config/sim_parameters.yaml b/elevation_mapping_cupy/config/sim_parameters.yaml deleted file mode 100644 index 0a51fc78..00000000 --- a/elevation_mapping_cupy/config/sim_parameters.yaml +++ /dev/null @@ -1,96 +0,0 @@ -#### Basic parameters ######## -resolution: 0.04 # resolution in m. -map_length: 8 # map's size in m. -sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). -mahalanobis_thresh: 2.0 # points outside this distance is outlier. -outlier_variance: 0.01 # if point is outlier, add this value to the cell. -drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. -max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) -drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation -time_variance: 0.0001 # add this value when update_variance is called. -max_variance: 100.0 # maximum variance for each cell. -initial_variance: 1000.0 # initial variance for each cell. -traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. -dilation_size: 3 # dilation filter size before traversability filter. -wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. -min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. -position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. -orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. -position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -min_valid_distance: 0.5 # points with shorter distance will be filtered out. -max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. -ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -update_variance_fps: 5.0 # fps for updating variance. -update_pose_fps: 10.0 # fps for updating pose and shift the center of map. -time_interval: 0.1 # Time layer is updated with this interval. -map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. -publish_statistics_fps: 1.0 # Publish statistics topic in this fps. - -max_ray_length: 10.0 # maximum length for ray tracing. -cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. -cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. - -safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. -safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. -max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. - -overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) -overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - -map_frame: 'odom' # The map frame where the odometry source uses. -base_frame: 'base' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'odom_corrected' - -#### Feature toggles ######## -enable_edge_sharpen: true -enable_visibility_cleanup: true -enable_drift_compensation: true -enable_overlap_clearance: true -enable_pointcloud_publishing: false -enable_drift_corrected_TF_publishing: false -enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. - -#### Traversability filter ######## -use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. -weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter - -#### Upper bound ######## -use_only_above_for_upper_bound: false - -#### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin_config.yaml' - -#### Publishers ######## -# topic_name: -# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names -# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. -# fps: # Publish rate. Use smaller value than `map_acquire_fps`. -publishers: - elevation_map_raw: - layers: [ 'elevation', 'traversability', 'variance' ] - basic_layers: [ 'elevation', 'traversability' ] - fps: 2.0 - - semantic_map_raw: - layers: [ 'elevation', 'traversability', 'variance', 'rgb_image' ] - basic_layers: [ 'elevation', 'traversability' ] - fps: 2.0 - # elevation_map_recordable: - # layers: ['elevation', 'traversability'] - # basic_layers: ['elevation', 'traversability'] - # fps: 2.0 - # elevation_map_filter: - # layers: ['min_filter', 'smooth', 'inpaint', 'upper_bound','rgb'] - # basic_layers: ['min_filter'] - # fps: 3.0 - -#### Initializer ######## -initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: [ 'base_footprint' ] # One tf (like ['footprint'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [ 0.0 ] # z direction. Should be same number as initialize_frame_id. -dilation_size_initialize: 5 # dilation size after the init. -initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. -use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/sim_plugin_config.yaml b/elevation_mapping_cupy/config/sim_plugin_config.yaml deleted file mode 100644 index 9630f496..00000000 --- a/elevation_mapping_cupy/config/sim_plugin_config.yaml +++ /dev/null @@ -1,61 +0,0 @@ -# Settings of the plugins. (The plugins should be stored in script/plugins) - -# min_filter fills in minimum value around the invalid cell. -min_filter: - enable: True # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - dilation_size: 1 # The patch size to apply - iteration_n: 30 # The number of iterations -# Apply smoothing. -smooth_filter: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth" - extra_params: - input_layer_name: "min_filter" -# Apply inpainting using opencv -inpainting: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "inpaint" - extra_params: - method: "telea" # telea or ns -# Apply smoothing for inpainted layer - -robot_centric_elevation: # Use the same name as your file name. - # type: "robot_centric_elevation" - enable: False # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - # add_value: 2.0 # Example param - resolution: 0.04 - threshold: 1.1 - use_threshold: True - -semantic_filter: - type: "semantic_filter" - enable: False - fill_nan: False - is_height_layer: False - layer_name: "sem_fil" - extra_params: - classes: [ 'grass','tree','fence','dirt' ] - -semantic_traversability: - type: "semantic_traversability" - enable: False - fill_nan: False - is_height_layer: False - layer_name: "sem_traversability" - extra_params: - layers: [ 'traversability','robot_centric_elevation' ] - thresholds: [ 0.3,0.5 ] - type: [ 'traversability', 'elevation' ] - diff --git a/elevation_mapping_cupy/config/sim_sensor_parameter.yaml b/elevation_mapping_cupy/config/sim_sensor_parameter.yaml deleted file mode 100644 index f954e0b1..00000000 --- a/elevation_mapping_cupy/config/sim_sensor_parameter.yaml +++ /dev/null @@ -1,131 +0,0 @@ -#### Subscribers ######## -subscribers: - # debug_rgb: - # fusion: ['image_color'] - # topic_name_camera: /zed2i/zed_node/left/image_rect_color - # topic_name_camera_info: /zed2i/zed_node/right/camera_info - # channels: ["rgb_image"] - # data_type: image - # fusion_types: - # array_fusion: [] - # channels: [] - - # debug_rgb_3_seperate: - # fusion: ['image_exponential','image_exponential','image_exponential'] - # topic_name_camera: /zed2i/zed_node/right/image - # topic_name_camera_info: /zed2i/zed_node/right/camera_info - # channels: ["r_channel", "g_channel", "b_channel"] - # data_type: image - - # debug_rgb_2_seperate: - # fusion: ['image_exponential', 'image_exponential'] - # topic_name_camera: /zed2i/zed_node/left/image_rect_color - # topic_name_camera_info: /zed2i/zed_node/right/camera_info - # channels: ["r_channel", "g_channel"] - # data_type: image - - # debug_mono_exponential: - # fusion: ['image_exponential'] - # topic_name_camera: /debug_image - # topic_name_camera_info: /zed2i/zed_node/right/camera_info - # channels: ["single_channel_semantic"] - # data_type: image - - # front_cam: - # channels: ['rgb'] - # fusion: ['color'] - # topic_name: '/elevation_mapping/pointcloud_semantic' - # data_type: pointcloud - - # alphasense_front_rgb: - # fusion: ['image_color'] - # topic_name_camera: /alphasense_driver_ros/cam4/debayered - # topic_name_camera_info: /alphasense_driver_ros/cam4/camera_info - # channels: ["rgb_image"] - # data_type: image - - - # alphasense_left_rgb: - # fusion: ['image_color'] - # topic_name_camera: /alphasense_driver_ros/cam3/debayered - # topic_name_camera_info: /alphasense_driver_ros/cam3/camera_info - # channels: ["rgb_image"] - # data_type: image - - - # alphasense_right_rgb: - # fusion: ['image_color'] - # topic_name_camera: /alphasense_driver_ros/cam5/debayered - # topic_name_camera_info: /alphasense_driver_ros/cam5/camera_info - # channels: ["rgb_image"] - # data_type: image - - - # wvn_prediction: - # fusion: ['image_exponential'] - # topic_name_camera: '/wild_visual_navigation_node/current_prediction' - # topic_name_camera_info: '/wild_visual_navigation_node/camera_info' - # channels: ["visual_traversability"] - # data_type: image - - # front_cam: - # channels: ['rgb','feat_0','feat_1','grass','tree','fence','person'] - # fusion: ['color','average','average','class_average','class_average','class_average','class_average'] - # topic_name: '/elvation_mapping/pointcloud_semantic' - # semantic_segmentation: False - # segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' - # feature_config: - # name: 'DINO' - # interpolation: 'bilinear' - # model: "vit_small" - # patch_size: 16 - # dim: 5 - # dropout: False - # dino_feat_type: "feat" - # input_size: [80, 160] - # projection_type: "nonlinear" - - # cam_info_topic: "/camera/depth/camera_info" - # image_topic: "/camera/rgb/image_raw" - # depth_topic: "/camera/depth/image_raw" - # cam_frame: camera_rgb_optical_frame - # confidence: False - # confidence_topic: "/camera/depth/image_raw" - # confidence_threshold: 10 - # feature_extractor: False - - front_bpearl: - channels: [ ] - fusion: [ ] - topic_name: /point_cloud_filter_rsl/filter_and_merger_rsl - data_type: pointcloud - - # rear_bpearl: - # channels: [] - # fusion: [] - # topic_name: /robot_self_filter/bpearl_rear/point_cloud - # data_type: pointcloud - - # front_depth: - # channels: [] - # fusion: [] - # topic_name: /depth_camera_front/point_cloud_self_filtered - # data_type: pointcloud - - # rear_depth: - # channels: [] - # fusion: [] - # topic_name: /depth_camera_rear/point_cloud_self_filtered - # data_type: pointcloud - - # left_depth: - # channels: [] - # fusion: [] - # topic_name: /depth_camera_left/point_cloud_self_filtered - # data_type: pointcloud - - # right_depth: - # channels: [] - # fusion: [] - # topic_name: /depth_camera_right/point_cloud_self_filtered - # data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch deleted file mode 100644 index 983bc978..00000000 --- a/elevation_mapping_cupy/launch/anymal_semantic_elevation_single.launch +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/heap_launch.launch b/elevation_mapping_cupy/launch/heap_launch.launch deleted file mode 100644 index 2218c409..00000000 --- a/elevation_mapping_cupy/launch/heap_launch.launch +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/elevation_mapping_cupy/launch/lonomy_pointcloud.launch b/elevation_mapping_cupy/launch/lonomy_pointcloud.launch deleted file mode 100644 index fe16229d..00000000 --- a/elevation_mapping_cupy/launch/lonomy_pointcloud.launch +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch deleted file mode 100644 index dbd98f95..00000000 --- a/elevation_mapping_cupy/launch/lonomy_semantic_elevation_single.launch +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/semantic_elevation_anymal.launch b/elevation_mapping_cupy/launch/semantic_elevation_anymal.launch deleted file mode 100644 index 8d2f44d6..00000000 --- a/elevation_mapping_cupy/launch/semantic_elevation_anymal.launch +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch b/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch deleted file mode 100644 index 8c389af5..00000000 --- a/elevation_mapping_cupy/launch/semantic_elevation_lonomy_single.launch +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch b/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch deleted file mode 100644 index 632b4bfd..00000000 --- a/elevation_mapping_cupy/launch/sim_semantic_elevation_single.launch +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_example.launch b/elevation_mapping_cupy/launch/turtlesim_example.launch index f36001bd..d672f6de 100644 --- a/elevation_mapping_cupy/launch/turtlesim_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_example.launch @@ -2,27 +2,18 @@ - - - - + + + + + + + - - - - - map_frame: odom - base_frame: base_footprint - pointcloud_topics: ["/camera/depth/points"] - initialize_frame_id: ['base_footprint'] - initialize_tf_offset: [0.0] - + - - - - diff --git a/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch b/elevation_mapping_cupy/launch/turtlesim_init.launch similarity index 59% rename from elevation_mapping_cupy/launch/turtlesim_pointcloud.launch rename to elevation_mapping_cupy/launch/turtlesim_init.launch index 225b5b79..7a118a00 100644 --- a/elevation_mapping_cupy/launch/turtlesim_pointcloud.launch +++ b/elevation_mapping_cupy/launch/turtlesim_init.launch @@ -5,16 +5,12 @@ - + - - - - + diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_elevation.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_elevation.launch deleted file mode 100644 index 651edf2c..00000000 --- a/elevation_mapping_cupy/launch/turtlesim_semantic_elevation.launch +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch new file mode 100644 index 00000000..176ec061 --- /dev/null +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch new file mode 100644 index 00000000..4e60fee8 --- /dev/null +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/elevation_mapping_cupy/rviz/anymal.rviz b/elevation_mapping_cupy/rviz/anymal.rviz deleted file mode 100644 index 88da0693..00000000 --- a/elevation_mapping_cupy/rviz/anymal.rviz +++ /dev/null @@ -1,570 +0,0 @@ -Panels: - - Class: rviz/Displays - Help Height: 138 - Name: Displays - Property Tree Widget: - Expanded: ~ - Splitter Ratio: 0.5768463015556335 - Tree Height: 469 - - Class: rviz/Selection - Name: Selection - - Class: rviz/Tool Properties - Expanded: - - /2D Pose Estimate1 - - /2D Nav Goal1 - - /Publish Point1 - Name: Tool Properties - Splitter Ratio: 0.5886790156364441 - - Class: rviz/Views - Expanded: - - /Current View1 - Name: Views - Splitter Ratio: 0.5 - - Class: rviz/Time - Name: Time - SyncMode: 0 - SyncSource: "" -Preferences: - PromptSaveOnExit: true -Toolbars: - toolButtonStyle: 2 -Visualization Manager: - Class: "" - Displays: - - Alpha: 0.5 - Cell Size: 1 - Class: rviz/Grid - Color: 160; 160; 164 - Enabled: true - Line Style: - Line Width: 0.029999999329447746 - Value: Lines - Name: Grid - Normal Cell Count: 0 - Offset: - X: 0 - Y: 0 - Z: 0 - Plane: XY - Plane Cell Count: 10 - Reference Frame: - Value: true - - Alpha: 1 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: rgb_image - Color Transformer: ColorLayer - Enabled: true - Height Layer: elevation - Height Transformer: Layer - History Length: 1 - Invert Rainbow: false - Max Color: 204; 0; 0 - Max Intensity: 10 - Min Color: 52; 101; 164 - Min Intensity: 0 - Name: ElevationMapFilter - Show Grid Lines: true - Topic: /elevation_mapping/semantic_map_raw - Unreliable: false - Use Rainbow: false - Value: true - - Class: rviz/TF - Enabled: true - Frame Timeout: 15 - Frames: - All Enabled: true - LF_FOOT: - Value: true - LF_HAA: - Value: true - LF_HFE: - Value: true - LF_HIP: - Value: true - LF_KFE: - Value: true - LF_SHANK: - Value: true - LF_THIGH: - Value: true - LF_hip_fixed: - Value: true - LF_shank_fixed: - Value: true - LF_thigh_fixed: - Value: true - LH_FOOT: - Value: true - LH_HAA: - Value: true - LH_HFE: - Value: true - LH_HIP: - Value: true - LH_KFE: - Value: true - LH_SHANK: - Value: true - LH_THIGH: - Value: true - LH_hip_fixed: - Value: true - LH_shank_fixed: - Value: true - LH_thigh_fixed: - Value: true - RF_FOOT: - Value: true - RF_HAA: - Value: true - RF_HFE: - Value: true - RF_HIP: - Value: true - RF_KFE: - Value: true - RF_SHANK: - Value: true - RF_THIGH: - Value: true - RF_hip_fixed: - Value: true - RF_shank_fixed: - Value: true - RF_thigh_fixed: - Value: true - RH_FOOT: - Value: true - RH_HAA: - Value: true - RH_HFE: - Value: true - RH_HIP: - Value: true - RH_KFE: - Value: true - RH_SHANK: - Value: true - RH_THIGH: - Value: true - RH_hip_fixed: - Value: true - RH_shank_fixed: - Value: true - RH_thigh_fixed: - Value: true - alphasense_mesh: - Value: true - base: - Value: true - base_inertia: - Value: true - base_inverted: - Value: true - battery: - Value: true - body_top: - Value: true - bottom_shell: - Value: true - cam0_sensor_frame: - Value: true - cam1_sensor_frame: - Value: true - cam2_sensor_frame: - Value: true - cam3_sensor_frame: - Value: true - cam3_sensor_frame_helper: - Value: true - cam4_sensor_frame: - Value: true - cam4_sensor_frame_helper: - Value: true - cam5_sensor_frame: - Value: true - cam5_sensor_frame_helper: - Value: true - cam6_sensor_frame: - Value: true - cam6_sensor_frame_helper: - Value: true - camera_init: - Value: true - camera_init_CORRECTED: - Value: true - depth_camera_front_camera: - Value: true - depth_camera_front_camera_parent: - Value: true - depth_camera_front_depth_frame: - Value: true - depth_camera_front_depth_optical_frame: - Value: true - depth_camera_front_infra1_frame: - Value: true - depth_camera_front_infra1_optical_frame: - Value: true - depth_camera_front_infra2_frame: - Value: true - depth_camera_front_infra2_optical_frame: - Value: true - depth_camera_left_camera: - Value: true - depth_camera_left_camera_parent: - Value: true - depth_camera_left_depth_frame: - Value: true - depth_camera_left_depth_optical_frame: - Value: true - depth_camera_left_infra1_frame: - Value: true - depth_camera_left_infra1_optical_frame: - Value: true - depth_camera_left_infra2_frame: - Value: true - depth_camera_left_infra2_optical_frame: - Value: true - depth_camera_rear_camera: - Value: true - depth_camera_rear_camera_parent: - Value: true - depth_camera_rear_depth_frame: - Value: true - depth_camera_rear_depth_optical_frame: - Value: true - depth_camera_rear_infra1_frame: - Value: true - depth_camera_rear_infra1_optical_frame: - Value: true - depth_camera_rear_infra2_frame: - Value: true - depth_camera_rear_infra2_optical_frame: - Value: true - depth_camera_right_camera: - Value: true - depth_camera_right_camera_parent: - Value: true - depth_camera_right_depth_frame: - Value: true - depth_camera_right_depth_optical_frame: - Value: true - depth_camera_right_infra1_frame: - Value: true - depth_camera_right_infra1_optical_frame: - Value: true - depth_camera_right_infra2_frame: - Value: true - depth_camera_right_infra2_optical_frame: - Value: true - docking_hatch_cover: - Value: true - face_front: - Value: true - face_rear: - Value: true - feetcenter: - Value: true - footprint: - Value: true - front_handle: - Value: true - handle: - Value: true - hatch: - Value: true - imu_link: - Value: true - imu_sensor_frame: - Value: true - interface_hatch: - Value: true - lidar: - Value: true - map: - Value: true - mira_spectrometer: - Value: true - msf_body_imu_map: - Value: true - odom: - Value: true - perception_head_cage: - Value: true - remote: - Value: true - top_shell: - Value: true - wide_angle_camera_front_camera: - Value: true - wide_angle_camera_front_camera_parent: - Value: true - wide_angle_camera_rear_camera: - Value: true - wide_angle_camera_rear_camera_parent: - Value: true - Marker Alpha: 1 - Marker Scale: 1 - Name: TF - Show Arrows: true - Show Axes: true - Show Names: true - Tree: - odom: - base: - LF_HAA: - LF_HIP: - LF_hip_fixed: - LF_HFE: - LF_THIGH: - LF_thigh_fixed: - LF_KFE: - LF_SHANK: - LF_shank_fixed: - LF_FOOT: - { } - LH_HAA: - LH_HIP: - LH_hip_fixed: - LH_HFE: - LH_THIGH: - LH_thigh_fixed: - LH_KFE: - LH_SHANK: - LH_shank_fixed: - LH_FOOT: - { } - RF_HAA: - RF_HIP: - RF_hip_fixed: - RF_HFE: - RF_THIGH: - RF_thigh_fixed: - RF_KFE: - RF_SHANK: - RF_shank_fixed: - RF_FOOT: - { } - RH_HAA: - RH_HIP: - RH_hip_fixed: - RH_HFE: - RH_THIGH: - RH_thigh_fixed: - RH_KFE: - RH_SHANK: - RH_shank_fixed: - RH_FOOT: - { } - alphasense_mesh: - { } - base_inertia: - { } - base_inverted: - { } - battery: - { } - body_top: - { } - bottom_shell: - { } - depth_camera_left_camera: - depth_camera_left_camera_parent: - depth_camera_left_depth_frame: - depth_camera_left_depth_optical_frame: - { } - depth_camera_left_infra1_frame: - depth_camera_left_infra1_optical_frame: - { } - depth_camera_left_infra2_frame: - depth_camera_left_infra2_optical_frame: - { } - depth_camera_right_camera: - depth_camera_right_camera_parent: - depth_camera_right_depth_frame: - depth_camera_right_depth_optical_frame: - { } - depth_camera_right_infra1_frame: - depth_camera_right_infra1_optical_frame: - { } - depth_camera_right_infra2_frame: - depth_camera_right_infra2_optical_frame: - { } - docking_hatch_cover: - { } - face_front: - depth_camera_front_camera: - depth_camera_front_camera_parent: - depth_camera_front_depth_frame: - depth_camera_front_depth_optical_frame: - { } - depth_camera_front_infra1_frame: - depth_camera_front_infra1_optical_frame: - { } - depth_camera_front_infra2_frame: - depth_camera_front_infra2_optical_frame: - { } - wide_angle_camera_front_camera: - wide_angle_camera_front_camera_parent: - { } - face_rear: - depth_camera_rear_camera: - depth_camera_rear_camera_parent: - depth_camera_rear_depth_frame: - depth_camera_rear_depth_optical_frame: - { } - depth_camera_rear_infra1_frame: - depth_camera_rear_infra1_optical_frame: - { } - depth_camera_rear_infra2_frame: - depth_camera_rear_infra2_optical_frame: - { } - wide_angle_camera_rear_camera: - wide_angle_camera_rear_camera_parent: - { } - front_handle: - { } - handle: - { } - imu_link: - { } - interface_hatch: - hatch: - { } - mira_spectrometer: - { } - perception_head_cage: - lidar: - imu_sensor_frame: - cam0_sensor_frame: - { } - cam1_sensor_frame: - { } - cam2_sensor_frame: - { } - cam3_sensor_frame_helper: - cam3_sensor_frame: - { } - cam4_sensor_frame_helper: - cam4_sensor_frame: - { } - cam5_sensor_frame_helper: - cam5_sensor_frame: - { } - cam6_sensor_frame_helper: - cam6_sensor_frame: - { } - remote: - { } - top_shell: - { } - feetcenter: - { } - footprint: - { } - map: - camera_init_CORRECTED: - camera_init: - { } - msf_body_imu_map: - { } - Update Interval: 0 - Value: true - - Class: rviz/Image - Enabled: true - Image Topic: /alphasense_driver_ros/cam4/debayered - Max Value: 1 - Median window: 5 - Min Value: 0 - Name: Image - Normalize Range: true - Queue Size: 2 - Transport Hint: raw - Unreliable: false - Value: true - - Class: rviz/Marker - Enabled: true - Marker Topic: /visualization_marker_l - Name: Marker - Namespaces: - { } - Queue Size: 100 - Value: true - - Class: rviz/Marker - Enabled: true - Marker Topic: /visualization_marker_r - Name: Marker - Namespaces: - { } - Queue Size: 100 - Value: true - Enabled: true - Global Options: - Background Color: 255; 255; 255 - Default Light: true - Fixed Frame: map - Frame Rate: 30 - Name: root - Tools: - - Class: rviz/Interact - Hide Inactive Objects: true - - Class: rviz/MoveCamera - - Class: rviz/Select - - Class: rviz/FocusCamera - - Class: rviz/Measure - - Class: rviz/SetInitialPose - Theta std deviation: 0.2617993950843811 - Topic: /initialpose - X std deviation: 0.5 - Y std deviation: 0.5 - - Class: rviz/SetGoal - Topic: /move_base_simple/goal - - Class: rviz/PublishPoint - Single click: true - Topic: /clicked_point - Value: true - Views: - Current: - Class: rviz/Orbit - Distance: 18.912090301513672 - Enable Stereo Rendering: - Stereo Eye Separation: 0.05999999865889549 - Stereo Focal Distance: 1 - Swap Stereo Eyes: false - Value: false - Field of View: 0.7853981852531433 - Focal Point: - X: 0.7929360866546631 - Y: 0.3796532452106476 - Z: -0.4990573823451996 - Focal Shape Fixed Size: true - Focal Shape Size: 0.05000000074505806 - Invert Z Axis: false - Name: Current View - Near Clip Distance: 0.009999999776482582 - Pitch: 0.23979759216308594 - Target Frame: base_footprint - Yaw: 5.103874206542969 - Saved: ~ -Window Geometry: - Displays: - collapsed: false - Height: 1016 - Hide Left Dock: false - Hide Right Dock: true - Image: - collapsed: false - QMainWindow State: 000000ff00000000fd0000000400000000000001f50000039efc020000000cfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000029c000000c900fffffffb0000000a0049006d00610067006501000002df000000fc0000001600fffffffb0000000a0049006d00610067006501000002af0000012c0000000000000000fb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d0061006700650000000325000000d10000000000000000fb0000000a0049006d006100670065010000032a000000cc0000000000000000000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000078000000131fc0100000002fb0000000800540069006d00650000000000000007380000041800fffffffb0000000800540069006d006501000000000000045000000000000000000000053d0000039e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 - Selection: - collapsed: false - Time: - collapsed: false - Tool Properties: - collapsed: false - Views: - collapsed: true - Width: 1848 - X: 72 - Y: 27 diff --git a/elevation_mapping_cupy/rviz/heap.rviz b/elevation_mapping_cupy/rviz/heap.rviz deleted file mode 100644 index a2e695df..00000000 --- a/elevation_mapping_cupy/rviz/heap.rviz +++ /dev/null @@ -1,600 +0,0 @@ -Panels: - - Class: rviz/Displays - Help Height: 78 - Name: Displays - Property Tree Widget: - Expanded: ~ - Splitter Ratio: 0.5 - Tree Height: 288 - - Class: rviz/Selection - Name: Selection - - Class: rviz/Tool Properties - Expanded: - - /2D Pose Estimate1 - - /2D Nav Goal1 - - /Publish Point1 - - /Interact1 - Name: Tool Properties - Splitter Ratio: 0.5886790156364441 - - Class: rviz/Views - Expanded: - - /Current View1 - Name: Views - Splitter Ratio: 0.4944238066673279 - - Class: rviz/Time - Experimental: false - Name: Time - SyncMode: 0 - SyncSource: Image -Preferences: - PromptSaveOnExit: true -Toolbars: - toolButtonStyle: 2 -Visualization Manager: - Class: "" - Displays: - - Alpha: 0.5 - Cell Size: 1 - Class: rviz/Grid - Color: 160; 160; 164 - Enabled: false - Line Style: - Line Width: 0.029999999329447746 - Value: Lines - Name: Grid - Normal Cell Count: 0 - Offset: - X: 0 - Y: 0 - Z: 0 - Plane: XY - Plane Cell Count: 10 - Reference Frame: - Value: false - - Class: rviz/Image - Enabled: true - Image Topic: /camUSBRightView/Downsampled - Max Value: 1 - Median window: 5 - Min Value: 0 - Name: Image - Normalize Range: true - Queue Size: 2 - Transport Hint: raw - Unreliable: false - Value: true - - Class: rviz/TF - Enabled: true - Frame Timeout: 15 - Frames: - All Enabled: true - BASE: - Value: true - BASE_inertia: - Value: true - BOOM: - Value: true - CABIN: - Value: true - DIPPER: - Value: true - ENDEFFECTOR: - Value: true - ENDEFFECTOR_CONTACT: - Value: true - GNSS_L: - Value: true - GNSS_R: - Value: true - IMU_base_link: - Value: true - IMU_link: - Value: true - LF_BEAM: - Value: true - LF_BEARING: - Value: true - LF_KNUCKLE: - Value: true - LF_PARALLEL: - Value: true - LF_SWIVEL: - Value: true - LF_WHEEL: - Value: true - LF_WHEEL_CONTACT: - Value: true - LH_BEAM: - Value: true - LH_KNUCKLE: - Value: true - LH_OUTRIGGER: - Value: true - LH_ROTATOR: - Value: true - LH_WHEEL: - Value: true - LH_WHEEL_CONTACT: - Value: true - RF_BEAM: - Value: true - RF_BEARING: - Value: true - RF_KNUCKLE: - Value: true - RF_PARALLEL: - Value: true - RF_SWIVEL: - Value: true - RF_WHEEL: - Value: true - RF_WHEEL_CONTACT: - Value: true - RH_BEAM: - Value: true - RH_KNUCKLE: - Value: true - RH_OUTRIGGER: - Value: true - RH_ROTATOR: - Value: true - RH_WHEEL: - Value: true - RH_WHEEL_CONTACT: - Value: true - ROTO: - Value: true - ROTO_BASE: - Value: true - SHOVEL: - Value: true - TELE: - Value: true - camMainView: - Value: true - compslam_lio/aft_mapped: - Value: true - compslam_lio/aft_mapped_to_init_CORRECTED: - Value: true - compslam_lio/camera: - Value: true - compslam_lio/camera_CORRECTED: - Value: true - compslam_lio/camera_init: - Value: true - compslam_lio/camera_init_CORRECTED: - Value: true - compslam_lio/camera_init_GRAVITY_ALIGNED: - Value: true - compslam_lio/laser_odom: - Value: true - compslam_lio/laser_odom_CORRECTED: - Value: true - imu_box_base_link: - Value: true - imu_box_link: - Value: true - livox_frame: - Value: true - map: - Value: true - odom: - Value: true - os_imu: - Value: true - os_lidar: - Value: true - os_sensor: - Value: true - roof_top_box: - Value: true - Marker Alpha: 1 - Marker Scale: 1 - Name: TF - Show Arrows: true - Show Axes: true - Show Names: true - Tree: - map: - compslam_lio/camera_init_CORRECTED: - compslam_lio/aft_mapped_to_init_CORRECTED: - { } - compslam_lio/camera_CORRECTED: - { } - compslam_lio/camera_init: - compslam_lio/aft_mapped: - { } - compslam_lio/camera: - { } - compslam_lio/laser_odom: - { } - compslam_lio/camera_init_GRAVITY_ALIGNED: - { } - compslam_lio/laser_odom_CORRECTED: - { } - odom: - BASE: - BASE_inertia: - { } - CABIN: - BOOM: - DIPPER: - TELE: - ROTO_BASE: - ROTO: - ENDEFFECTOR: - SHOVEL: - ENDEFFECTOR_CONTACT: - { } - GNSS_L: - { } - GNSS_R: - { } - camMainView: - livox_frame: - { } - os_sensor: - os_imu: - { } - os_lidar: - { } - roof_top_box: - imu_box_base_link: - imu_box_link: - { } - IMU_base_link: - IMU_link: - { } - LF_SWIVEL: - LF_BEAM: - LF_BEARING: - LF_KNUCKLE: - LF_WHEEL: - LF_WHEEL_CONTACT: - { } - LF_PARALLEL: - { } - LH_ROTATOR: - LH_BEAM: - LH_KNUCKLE: - LH_OUTRIGGER: - { } - LH_WHEEL: - LH_WHEEL_CONTACT: - { } - RF_SWIVEL: - RF_BEAM: - RF_BEARING: - RF_KNUCKLE: - RF_WHEEL: - RF_WHEEL_CONTACT: - { } - RF_PARALLEL: - { } - RH_ROTATOR: - RH_BEAM: - RH_KNUCKLE: - RH_OUTRIGGER: - { } - RH_WHEEL: - RH_WHEEL_CONTACT: - { } - Update Interval: 0 - Value: true - - Class: rviz/Image - Enabled: true - Image Topic: /camMainView/Downsampled - Max Value: 1 - Median window: 5 - Min Value: 0 - Name: Image - Normalize Range: true - Queue Size: 2 - Transport Hint: raw - Unreliable: false - Value: true - - Alpha: 1 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: rgb_image - Color Transformer: ColorLayer - ColorMap: default - Enabled: true - Grid Cell Decimation: 1 - Grid Line Thickness: 0.10000000149011612 - Height Layer: smooth - Height Transformer: GridMapLayer - History Length: 1 - Invert ColorMap: false - Max Color: 255; 255; 255 - Max Intensity: 10 - Min Color: 0; 0; 0 - Min Intensity: 0 - Name: GridMap - Show Grid Lines: true - Topic: /elevation_mapping/elevation_map_filter - Unreliable: false - Use ColorMap: true - Value: true - - Alpha: 1 - Class: rviz/RobotModel - Collision Enabled: false - Enabled: true - Links: - All Links Enabled: true - BASE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - BASE_inertia: - Alpha: 1 - Show Axes: false - Show Trail: false - BOOM: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - CABIN: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - DIPPER: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - ENDEFFECTOR: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - ENDEFFECTOR_CONTACT: - Alpha: 1 - Show Axes: false - Show Trail: false - Expand Joint Details: false - Expand Link Details: false - Expand Tree: false - GNSS_L: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - GNSS_R: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - IMU_base_link: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - IMU_link: - Alpha: 1 - Show Axes: false - Show Trail: false - LF_BEAM: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LF_BEARING: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LF_KNUCKLE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LF_PARALLEL: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LF_SWIVEL: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LF_WHEEL: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LF_WHEEL_CONTACT: - Alpha: 1 - Show Axes: false - Show Trail: false - LH_BEAM: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LH_KNUCKLE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LH_OUTRIGGER: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LH_ROTATOR: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LH_WHEEL: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - LH_WHEEL_CONTACT: - Alpha: 1 - Show Axes: false - Show Trail: false - Link Tree Style: Links in Alphabetic Order - RF_BEAM: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RF_BEARING: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RF_KNUCKLE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RF_PARALLEL: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RF_SWIVEL: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RF_WHEEL: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RF_WHEEL_CONTACT: - Alpha: 1 - Show Axes: false - Show Trail: false - RH_BEAM: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RH_KNUCKLE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RH_OUTRIGGER: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RH_ROTATOR: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RH_WHEEL: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - RH_WHEEL_CONTACT: - Alpha: 1 - Show Axes: false - Show Trail: false - ROTO: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - ROTO_BASE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - SHOVEL: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - TELE: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - Name: RobotModel - Robot Description: mm_description - TF Prefix: "" - Update Interval: 0 - Value: true - Visual Enabled: true - Enabled: true - Global Options: - Background Color: 255; 255; 255 - Default Light: true - Fixed Frame: map - Frame Rate: 30 - Name: root - Tools: - - Class: rviz/Select - - Class: rviz/SetInitialPose - Theta std deviation: 0.2617993950843811 - Topic: /initialpose - X std deviation: 0.5 - Y std deviation: 0.5 - - Class: rviz/SetGoal - Topic: /move_base_simple/goal - - Class: rviz/PublishPoint - Single click: true - Topic: /clicked_point - - Class: rviz/MoveCamera - - Class: rviz/FocusCamera - - Class: rviz/Interact - Hide Inactive Objects: true - Value: true - Views: - Current: - Class: rviz/Orbit - Distance: 27.363513946533203 - Enable Stereo Rendering: - Stereo Eye Separation: 0.05999999865889549 - Stereo Focal Distance: 1 - Swap Stereo Eyes: false - Value: false - Field of View: 1 - Focal Point: - X: 4.949670314788818 - Y: 8.161603927612305 - Z: -4.364292144775391 - Focal Shape Fixed Size: false - Focal Shape Size: 0.05000000074505806 - Invert Z Axis: false - Name: Current View - Near Clip Distance: 0.009999999776482582 - Pitch: 0.7703982591629028 - Target Frame: - Yaw: 2.9804012775421143 - Saved: ~ -Window Geometry: - Displays: - collapsed: false - Height: 1016 - Hide Left Dock: false - Hide Right Dock: false - Image: - collapsed: false - QMainWindow State: 000000ff00000000fd0000000400000000000001560000035afc020000000afb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000001ab000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d00610067006501000001ee0000012f0000001600fffffffb0000000a0049006d0061006700650100000323000000740000001600ffffff000000010000010f0000035afc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d0000035a000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007380000003efc0100000002fb0000000800540069006d0065010000000000000738000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000004c70000035a00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 - Selection: - collapsed: false - Time: - collapsed: false - Tool Properties: - collapsed: false - Views: - collapsed: false - Width: 1848 - X: 72 - Y: 27 diff --git a/elevation_mapping_cupy/rviz/lonomy_single.rviz b/elevation_mapping_cupy/rviz/lonomy_single.rviz deleted file mode 100644 index 2544ffe9..00000000 --- a/elevation_mapping_cupy/rviz/lonomy_single.rviz +++ /dev/null @@ -1,494 +0,0 @@ -Panels: - - Class: rviz/Displays - Help Height: 138 - Name: Displays - Property Tree Widget: - Expanded: - - /ElevationMapFilter1 - Splitter Ratio: 0.5768463015556335 - Tree Height: 247 - - Class: rviz/Selection - Name: Selection - - Class: rviz/Tool Properties - Expanded: - - /2D Pose Estimate1 - - /2D Nav Goal1 - - /Publish Point1 - Name: Tool Properties - Splitter Ratio: 0.5886790156364441 - - Class: rviz/Views - Expanded: - - /Current View1 - Name: Views - Splitter Ratio: 0.5 - - Class: rviz/Time - Name: Time - SyncMode: 0 - SyncSource: Image -Preferences: - PromptSaveOnExit: true -Toolbars: - toolButtonStyle: 2 -Visualization Manager: - Class: "" - Displays: - - Alpha: 0.5 - Cell Size: 1 - Class: rviz/Grid - Color: 160; 160; 164 - Enabled: true - Line Style: - Line Width: 0.029999999329447746 - Value: Lines - Name: Grid - Normal Cell Count: 0 - Offset: - X: 0 - Y: 0 - Z: 0 - Plane: XY - Plane Cell Count: 10 - Reference Frame: - Value: true - - Alpha: 1 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: rgb - Color Transformer: ColorLayer - Enabled: true - Height Layer: min_filter - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 204; 0; 0 - Max Intensity: 10 - Min Color: 52; 101; 164 - Min Intensity: 0 - Name: ElevationMapFilter - Show Grid Lines: true - Topic: /elevation_mapping/elevation_map_filter - Unreliable: false - Use Rainbow: false - Value: true - - Alpha: 1 - Class: rviz/RobotModel - Collision Enabled: false - Enabled: true - Links: - All Links Enabled: true - Expand Joint Details: false - Expand Link Details: false - Expand Tree: false - GPS_back: - Alpha: 1 - Show Axes: false - Show Trail: false - GPS_front: - Alpha: 1 - Show Axes: false - Show Trail: false - Link Tree Style: Links in Alphabetic Order - alphasense: - Alpha: 1 - Show Axes: false - Show Trail: false - base_footprint: - Alpha: 1 - Show Axes: false - Show Trail: false - base_inertial: - Alpha: 1 - Show Axes: false - Show Trail: false - base_link: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - estimator_imu: - Alpha: 1 - Show Axes: false - Show Trail: false - left_back_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - left_back_wheel_sup: - Alpha: 1 - Show Axes: false - Show Trail: false - left_front_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - left_front_wheel_sup: - Alpha: 1 - Show Axes: false - Show Trail: false - rear_axle_center: - Alpha: 1 - Show Axes: false - Show Trail: false - right_back_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - right_back_wheel_sup: - Alpha: 1 - Show Axes: false - Show Trail: false - right_front_wheel: - Alpha: 1 - Show Axes: false - Show Trail: false - Value: true - right_front_wheel_sup: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_baro_link: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_base_link: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_camera_center: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_left_camera_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_left_camera_optical_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_mag_link: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_right_camera_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_right_camera_optical_frame: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_temp_left_link: - Alpha: 1 - Show Axes: false - Show Trail: false - zed2i_temp_right_link: - Alpha: 1 - Show Axes: false - Show Trail: false - Name: RobotModel - Robot Description: robot_description - TF Prefix: "" - Update Interval: 0 - Value: true - Visual Enabled: true - - Alpha: 1 - Autocompute Intensity Bounds: true - Autocompute Value Bounds: - Max Value: 10 - Min Value: -10 - Value: true - Axis: Z - Channel Name: intensity - Class: rviz/PointCloud2 - Color: 255; 255; 255 - Color Transformer: RGB8 - Decay Time: 0 - Enabled: false - Invert Rainbow: false - Max Color: 255; 255; 255 - Min Color: 0; 0; 0 - Name: PointCloud2 - Position Transformer: XYZ - Queue Size: 10 - Selectable: true - Size (Pixels): 3 - Size (m): 0.009999999776482582 - Style: Flat Squares - Topic: /elvation_mapping/pointcloud_semantic - Unreliable: false - Use Fixed Frame: true - Use rainbow: true - Value: false - - Alpha: 1 - Autocompute Intensity Bounds: true - Autocompute Value Bounds: - Max Value: 10 - Min Value: -10 - Value: true - Axis: Z - Channel Name: intensity - Class: rviz/PointCloud2 - Color: 255; 255; 255 - Color Transformer: RGB8 - Decay Time: 0 - Enabled: false - Invert Rainbow: false - Max Color: 255; 255; 255 - Min Color: 0; 0; 0 - Name: PointCloud2 - Position Transformer: XYZ - Queue Size: 10 - Selectable: true - Size (Pixels): 3 - Size (m): 0.009999999776482582 - Style: Flat Squares - Topic: /elvation_mapping/pointcloud_semantic_right - Unreliable: false - Use Fixed Frame: true - Use rainbow: true - Value: false - - Class: rviz/TF - Enabled: true - Frame Timeout: 15 - Frames: - All Enabled: true - GPS_back: - Value: true - GPS_front: - Value: true - alphasense: - Value: true - base_footprint: - Value: true - base_inertial: - Value: true - base_link: - Value: true - enu: - Value: true - estimator_imu: - Value: true - left_back_wheel: - Value: true - left_back_wheel_sup: - Value: true - left_front_wheel: - Value: true - left_front_wheel_sup: - Value: true - rear_axle_center: - Value: true - right_back_wheel: - Value: true - right_back_wheel_sup: - Value: true - right_front_wheel: - Value: true - right_front_wheel_sup: - Value: true - zed2i_baro_link: - Value: true - zed2i_base_link: - Value: true - zed2i_camera_center: - Value: true - zed2i_left_camera_frame: - Value: true - zed2i_left_camera_optical_frame: - Value: true - zed2i_mag_link: - Value: true - zed2i_right_camera_frame: - Value: true - zed2i_right_camera_optical_frame: - Value: true - zed2i_temp_left_link: - Value: true - zed2i_temp_right_link: - Value: true - Marker Alpha: 1 - Marker Scale: 1 - Name: TF - Show Arrows: true - Show Axes: true - Show Names: true - Tree: - enu: - base_link: - base_footprint: - { } - base_inertial: - { } - estimator_imu: - GPS_back: - { } - GPS_front: - { } - alphasense: - { } - left_back_wheel_sup: - left_back_wheel: - { } - left_front_wheel_sup: - left_front_wheel: - { } - rear_axle_center: - { } - right_back_wheel_sup: - right_back_wheel: - { } - right_front_wheel_sup: - right_front_wheel: - { } - zed2i_base_link: - zed2i_camera_center: - zed2i_baro_link: - { } - zed2i_left_camera_frame: - zed2i_left_camera_optical_frame: - { } - zed2i_temp_left_link: - { } - zed2i_mag_link: - { } - zed2i_right_camera_frame: - zed2i_right_camera_optical_frame: - { } - zed2i_temp_right_link: - { } - Update Interval: 0 - Value: true - - Class: rviz/Image - Enabled: true - Image Topic: /zed2i/zed_node/left/image_rect_color - Max Value: 1 - Median window: 5 - Min Value: 0 - Name: Image - Normalize Range: true - Queue Size: 2 - Transport Hint: raw - Unreliable: false - Value: true - - Class: rviz/Image - Enabled: true - Image Topic: /semantic_sensor/sem_seg - Max Value: 1 - Median window: 5 - Min Value: 0 - Name: Image - Normalize Range: true - Queue Size: 2 - Transport Hint: raw - Unreliable: false - Value: true - - Class: rviz/Marker - Enabled: true - Marker Topic: /visualization_marker_l - Name: Marker - Namespaces: - { } - Queue Size: 100 - Value: true - - Class: rviz/Marker - Enabled: true - Marker Topic: /visualization_marker_r - Name: Marker - Namespaces: - { } - Queue Size: 100 - Value: true - - Alpha: 1 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: traversability - Color Transformer: GridMapLayer - Enabled: false - Height Layer: elevation - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 255; 255; 255 - Max Intensity: 10 - Min Color: 0; 0; 0 - Min Intensity: 0 - Name: GridMap - Show Grid Lines: true - Topic: /elevation_mapping/elevation_map_raw - Unreliable: false - Use Rainbow: true - Value: false - Enabled: true - Global Options: - Background Color: 255; 255; 255 - Default Light: true - Fixed Frame: enu - Frame Rate: 30 - Name: root - Tools: - - Class: rviz/Interact - Hide Inactive Objects: true - - Class: rviz/MoveCamera - - Class: rviz/Select - - Class: rviz/FocusCamera - - Class: rviz/Measure - - Class: rviz/SetInitialPose - Theta std deviation: 0.2617993950843811 - Topic: /initialpose - X std deviation: 0.5 - Y std deviation: 0.5 - - Class: rviz/SetGoal - Topic: /move_base_simple/goal - - Class: rviz/PublishPoint - Single click: true - Topic: /clicked_point - Value: true - Views: - Current: - Class: rviz/Orbit - Distance: 7.332578659057617 - Enable Stereo Rendering: - Stereo Eye Separation: 0.05999999865889549 - Stereo Focal Distance: 1 - Swap Stereo Eyes: false - Value: false - Field of View: 0.7853981852531433 - Focal Point: - X: 0.7929360866546631 - Y: 0.3796532452106476 - Z: -0.4990573823451996 - Focal Shape Fixed Size: true - Focal Shape Size: 0.05000000074505806 - Invert Z Axis: false - Name: Current View - Near Clip Distance: 0.009999999776482582 - Pitch: 0.43979740142822266 - Target Frame: base_footprint - Yaw: 2.8488521575927734 - Saved: ~ -Window Geometry: - Displays: - collapsed: false - Height: 1016 - Hide Left Dock: false - Hide Right Dock: true - Image: - collapsed: false - QMainWindow State: 000000ff00000000fd0000000400000000000001f50000039efc020000000cfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000001be000000c900fffffffb0000000a0049006d0061006700650100000201000000fc0000001600fffffffb0000000a0049006d0061006700650100000303000000d80000001600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d0061006700650000000325000000d10000000000000000fb0000000a0049006d006100670065010000032a000000cc0000000000000000000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000078000000131fc0100000002fb0000000800540069006d00650000000000000007380000041800fffffffb0000000800540069006d006501000000000000045000000000000000000000053d0000039e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 - Selection: - collapsed: false - Time: - collapsed: false - Tool Properties: - collapsed: false - Views: - collapsed: true - Width: 1848 - X: 72 - Y: 27 diff --git a/elevation_mapping_cupy/rviz/turtle_example.rviz b/elevation_mapping_cupy/rviz/turtle_example.rviz index 27c1aa4b..b5b19b90 100644 --- a/elevation_mapping_cupy/rviz/turtle_example.rviz +++ b/elevation_mapping_cupy/rviz/turtle_example.rviz @@ -6,7 +6,7 @@ Panels: Expanded: - /Global Options1 Splitter Ratio: 0.5768463015556335 - Tree Height: 1115 + Tree Height: 658 - Class: rviz/Selection Name: Selection - Class: rviz/Tool Properties @@ -25,7 +25,7 @@ Panels: Experimental: false Name: Time SyncMode: 0 - SyncSource: PointCloud2 + SyncSource: "" Preferences: PromptSaveOnExit: true Toolbars: @@ -55,13 +55,16 @@ Visualization Manager: Autocompute Intensity Bounds: false Class: grid_map_rviz_plugin/GridMap Color: 200; 200; 200 - Color Layer: traversability - Color Transformer: "" + Color Layer: rgb + Color Transformer: ColorLayer + ColorMap: default Enabled: true + Grid Cell Decimation: 1 + Grid Line Thickness: 0.10000000149011612 Height Layer: elevation Height Transformer: "" History Length: 1 - Invert Rainbow: false + Invert ColorMap: false Max Color: 238; 238; 236 Max Intensity: 1 Min Color: 32; 74; 135 @@ -70,28 +73,7 @@ Visualization Manager: Show Grid Lines: true Topic: /elevation_mapping/elevation_map_raw Unreliable: false - Use Rainbow: false - Value: true - - Alpha: 0.10000000149011612 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: min_filter - Color Transformer: GridMapLayer - Enabled: true - Height Layer: min_filter - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 206; 92; 0 - Max Intensity: 10 - Min Color: 255; 255; 255 - Min Intensity: 0 - Name: ElevationMapFilter - Show Grid Lines: true - Topic: /elevation_mapping/elevation_map_filter - Unreliable: false - Use Rainbow: false + Use ColorMap: true Value: true - Alpha: 1 Class: rviz/RobotModel @@ -247,10 +229,10 @@ Visualization Manager: Window Geometry: Displays: collapsed: false - Height: 1562 + Height: 1043 Hide Left Dock: false Hide Right Dock: true - QMainWindow State: 000000ff00000000fd0000000400000000000001f70000053bfc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000008600fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c00610079007301000000560000053b0000012600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000ec00fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e1000001970000000300000b0a0000005afc0100000002fb0000000800540069006d0065010000000000000b0a0000042b00fffffffb0000000800540069006d006501000000000000045000000000000000000000090a0000053b00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd0000000400000000000001f700000359fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000359000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007800000005afc0100000002fb0000000800540069006d0065010000000000000780000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000005830000035900000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -259,6 +241,6 @@ Window Geometry: collapsed: false Views: collapsed: true - Width: 2826 - X: 776 - Y: 185 + Width: 1920 + X: 1920 + Y: 0 diff --git a/elevation_mapping_cupy/rviz/turtle_segmentation_example.rviz b/elevation_mapping_cupy/rviz/turtle_segmentation_example.rviz index 04ff4401..df44f1b6 100644 --- a/elevation_mapping_cupy/rviz/turtle_segmentation_example.rviz +++ b/elevation_mapping_cupy/rviz/turtle_segmentation_example.rviz @@ -5,8 +5,10 @@ Panels: Property Tree Widget: Expanded: - /Global Options1 + - /ElevationMapRaw1 + - /ElevationMapFilter1 Splitter Ratio: 0.5768463015556335 - Tree Height: 991 + Tree Height: 631 - Class: rviz/Selection Name: Selection - Class: rviz/Tool Properties @@ -55,15 +57,16 @@ Visualization Manager: Autocompute Intensity Bounds: false Class: grid_map_rviz_plugin/GridMap Color: 200; 200; 200 - Color Layer: traversability - Color Transformer: "" + Color Layer: rgb + Color Transformer: ColorLayer + ColorMap: default Enabled: true Grid Cell Decimation: 1 Grid Line Thickness: 0.10000000149011612 Height Layer: elevation Height Transformer: "" History Length: 1 - Invert Rainbow: false + Invert ColorMap: false Max Color: 238; 238; 236 Max Intensity: 1 Min Color: 32; 74; 135 @@ -72,7 +75,7 @@ Visualization Manager: Show Grid Lines: true Topic: /elevation_mapping/elevation_map_raw Unreliable: false - Use Rainbow: false + Use ColorMap: true Value: true - Alpha: 0.10000000149011612 Autocompute Intensity Bounds: true @@ -80,13 +83,14 @@ Visualization Manager: Color: 200; 200; 200 Color Layer: min_filter Color Transformer: GridMapLayer + ColorMap: default Enabled: true Grid Cell Decimation: 1 Grid Line Thickness: 0.10000000149011612 Height Layer: min_filter Height Transformer: GridMapLayer History Length: 1 - Invert Rainbow: false + Invert ColorMap: false Max Color: 206; 92; 0 Max Intensity: 10 Min Color: 255; 255; 255 @@ -95,7 +99,7 @@ Visualization Manager: Show Grid Lines: true Topic: /elevation_mapping/elevation_map_filter Unreliable: false - Use Rainbow: false + Use ColorMap: true Value: true - Alpha: 1 Class: rviz/RobotModel @@ -205,7 +209,7 @@ Visualization Manager: Marker Topic: /convex_plane_decomposition_ros/boundaries Name: PlaneBoundaries Namespaces: - "": true + {} Queue Size: 100 Value: true - Alpha: 1 @@ -214,13 +218,14 @@ Visualization Manager: Color: 200; 200; 200 Color Layer: segmentation Color Transformer: GridMapLayer + ColorMap: default Enabled: true Grid Cell Decimation: 1 Grid Line Thickness: 0.10000000149011612 Height Layer: elevation_before_postprocess Height Transformer: GridMapLayer History Length: 1 - Invert Rainbow: false + Invert ColorMap: false Max Color: 238; 238; 236 Max Intensity: 10 Min Color: 32; 74; 135 @@ -229,7 +234,7 @@ Visualization Manager: Show Grid Lines: true Topic: /convex_plane_decomposition_ros/filtered_map Unreliable: false - Use Rainbow: true + Use ColorMap: true Value: true Enabled: true Global Options: @@ -259,7 +264,7 @@ Visualization Manager: Views: Current: Class: rviz/Orbit - Distance: 7.79520845413208 + Distance: 6.288029193878174 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 @@ -275,17 +280,17 @@ Visualization Manager: Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.5247964859008789 + Pitch: 0.5447964668273926 Target Frame: base_footprint - Yaw: 3.143371820449829 + Yaw: 3.108370780944824 Saved: ~ Window Geometry: Displays: collapsed: false - Height: 1376 + Height: 1016 Hide Left Dock: false Hide Right Dock: true - QMainWindow State: 000000ff00000000fd0000000400000000000001f7000004a6fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000004a6000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000009b80000005afc0100000002fb0000000800540069006d00650100000000000009b8000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000007bb000004a600000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd0000000400000000000001f70000033efc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000033e000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007380000005afc0100000002fb0000000800540069006d0065010000000000000738000002eb00fffffffb0000000800540069006d006501000000000000045000000000000000000000053b0000033e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -294,6 +299,6 @@ Window Geometry: collapsed: false Views: collapsed: true - Width: 2488 + Width: 1848 X: 72 Y: 27 diff --git a/elevation_mapping_cupy/rviz/turtle_semantic_example.rviz b/elevation_mapping_cupy/rviz/turtle_semantic_example.rviz index 91da7819..b5b19b90 100644 --- a/elevation_mapping_cupy/rviz/turtle_semantic_example.rviz +++ b/elevation_mapping_cupy/rviz/turtle_semantic_example.rviz @@ -5,9 +5,8 @@ Panels: Property Tree Widget: Expanded: - /Global Options1 - - /ElevationMapFilter1 Splitter Ratio: 0.5768463015556335 - Tree Height: 631 + Tree Height: 658 - Class: rviz/Selection Name: Selection - Class: rviz/Tool Properties @@ -23,6 +22,7 @@ Panels: Name: Views Splitter Ratio: 0.5 - Class: rviz/Time + Experimental: false Name: Time SyncMode: 0 SyncSource: "" @@ -55,13 +55,16 @@ Visualization Manager: Autocompute Intensity Bounds: false Class: grid_map_rviz_plugin/GridMap Color: 200; 200; 200 - Color Layer: traversability - Color Transformer: "" - Enabled: false + Color Layer: rgb + Color Transformer: ColorLayer + ColorMap: default + Enabled: true + Grid Cell Decimation: 1 + Grid Line Thickness: 0.10000000149011612 Height Layer: elevation Height Transformer: "" History Length: 1 - Invert Rainbow: false + Invert ColorMap: false Max Color: 238; 238; 236 Max Intensity: 1 Min Color: 32; 74; 135 @@ -70,28 +73,7 @@ Visualization Manager: Show Grid Lines: true Topic: /elevation_mapping/elevation_map_raw Unreliable: false - Use Rainbow: false - Value: false - - Alpha: 1 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: rgb - Color Transformer: ColorLayer - Enabled: true - Height Layer: min_filter - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 206; 92; 0 - Max Intensity: 10 - Min Color: 255; 255; 255 - Min Intensity: 0 - Name: ElevationMapFilter - Show Grid Lines: true - Topic: /elevation_mapping/elevation_map_filter - Unreliable: false - Use Rainbow: false + Use ColorMap: true Value: true - Alpha: 1 Class: rviz/RobotModel @@ -224,7 +206,7 @@ Visualization Manager: Views: Current: Class: rviz/Orbit - Distance: 3.499889373779297 + Distance: 9.118926048278809 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 @@ -240,17 +222,17 @@ Visualization Manager: Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.4947965741157532 + Pitch: 0.5947964191436768 Target Frame: base_footprint - Yaw: 2.893369436264038 + Yaw: 3.0983715057373047 Saved: ~ Window Geometry: Displays: collapsed: false - Height: 1016 + Height: 1043 Hide Left Dock: false Hide Right Dock: true - QMainWindow State: 000000ff00000000fd0000000400000000000001f70000033efc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000033e000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007380000005afc0100000002fb0000000800540069006d0065010000000000000738000003bc00fffffffb0000000800540069006d006501000000000000045000000000000000000000053b0000033e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd0000000400000000000001f700000359fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000359000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007800000005afc0100000002fb0000000800540069006d0065010000000000000780000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000005830000035900000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -259,6 +241,6 @@ Window Geometry: collapsed: false Views: collapsed: true - Width: 1848 - X: 1992 - Y: 27 + Width: 1920 + X: 1920 + Y: 0 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py new file mode 100644 index 00000000..68e2313c --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py @@ -0,0 +1,84 @@ +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + + +def color_correspondences_to_map_kernel(resolution, width, height): + color_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + + int idx_red = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + int idx_green = image_width * image_height + idx_red; + int idx_blue = image_width * image_height * 2 + idx_red; + + unsigned int r = image_rgb[idx_red]; + unsigned int g = image_rgb[idx_green]; + unsigned int b = image_rgb[idx_blue]; + + unsigned int rgb = (r<<16) + (g << 8) + b; + float rgb_ = __uint_as_float(rgb); + new_sem_map[get_map_idx(i, map_idx)] = rgb_; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + """ + ).substitute(), + name="color_correspondences_to_map_kernel", + ) + return color_correspondences_to_map_kernel + +class ImageColor(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + print("Initialize fusion kernel") + self.name = "image_color" + self.cell_n = params.cell_n + self.resolution = params.resolution + + self.color_correspondences_to_map_kernel = color_correspondences_to_map_kernel( + resolution=self.resolution, + width=self.cell_n, + height=self.cell_n, + ) + + + def __call__(self, sem_map_idx,image, j,uv_correspondence, valid_correspondence, image_height, image_width , semantic_map, new_map): + self.color_correspondences_to_map_kernel( + semantic_map, + cp.uint64(sem_map_idx), + image, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + new_map, + size=int(self.cell_n * self.cell_n), + ) + semantic_map[sem_map_idx] = new_map[sem_map_idx] + + + + + + + + + + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 165395ff..2d23a6d2 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -28,7 +28,7 @@ class Parameter(Serializable): "segmentation_model": "lraspp_mobilenet_v3_large", "semantic_segmentation": True, "show_label_legend": True, - "topic_name": "/elvation_mapping/pointcloud_semantic", + "topic_name": "/elevation_mapping/pointcloud_semantic", "data_type": "pointcloud", } } From d9c42519bd0fa77b6937ef253da736816dc7c065 Mon Sep 17 00:00:00 2001 From: Gian Date: Fri, 14 Jul 2023 14:37:03 +0200 Subject: [PATCH 353/504] adapted to new cupy version --- elevation_mapping_cupy/launch/turtlesim_init.launch | 2 +- .../script/elevation_mapping_cupy/elevation_mapping.py | 2 +- .../script/elevation_mapping_cupy/traversability_polygon.py | 2 +- .../script/semantic_sensor/tests/test_pointcloud.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/elevation_mapping_cupy/launch/turtlesim_init.launch b/elevation_mapping_cupy/launch/turtlesim_init.launch index 7a118a00..fc166d22 100644 --- a/elevation_mapping_cupy/launch/turtlesim_init.launch +++ b/elevation_mapping_cupy/launch/turtlesim_init.launch @@ -11,6 +11,6 @@ - + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 16504f53..bde7ce93 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -204,7 +204,7 @@ def shift_map_xy(self, delta_pixel): delta_pixel (cupy._core.core.ndarray): """ - shift_value = delta_pixel.astype(cp.int) + shift_value = delta_pixel.astype(cp.int32) if cp.abs(shift_value).sum() == 0: return with self.map_lock: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py index 4d267535..f39c99cc 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py @@ -59,7 +59,7 @@ def transform_to_map_position(polygon, center, cell_n, resolution): def transform_to_map_index(points, center, cell_n, resolution): - indices = ((points - center.reshape(1, 2)) / resolution + cell_n / 2).astype(cp.int) + indices = ((points - center.reshape(1, 2)) / resolution + cell_n / 2).astype(cp.int32) return indices diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py index 419ee55a..544c2eeb 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py @@ -88,7 +88,7 @@ def test_pcl_creation(pointcloud_ex, channels, fusion, semseg, segpub, showlbl): ind = cp.random.randint(0, 2, (360, 640, amount), dtype=cp.uint32).astype(cp.float32) img = encode_max(val, ind) else: - img = (cp.random.rand(360, 640, amount) * 255).astype(cp.int) + img = (cp.random.rand(360, 640, amount) * 255).astype(cp.int32) pointcloud_ex.P = cp.random.rand(3, 4) depth = cp.random.rand(360, 640) * 8 pointcloud_ex.create_pcl_from_image(img, depth, None) From fc12c43c9be411b250520c856e8420dcbfad0a1c Mon Sep 17 00:00:00 2001 From: Gian Date: Fri, 21 Jul 2023 16:47:59 +0200 Subject: [PATCH 354/504] everything running --- .../config/image_semantics.yaml | 21 +++++++---------- .../semantic_image_sensor_parameter.yaml | 23 +++++++++---------- .../config/semantic_parameters.yaml | 2 +- .../launch/turtlesim_semantic_example.launch | 2 +- .../turtlesim_semantic_image_example.launch | 2 +- 5 files changed, 22 insertions(+), 28 deletions(-) diff --git a/elevation_mapping_cupy/config/image_semantics.yaml b/elevation_mapping_cupy/config/image_semantics.yaml index 6354cc3a..76b4295a 100644 --- a/elevation_mapping_cupy/config/image_semantics.yaml +++ b/elevation_mapping_cupy/config/image_semantics.yaml @@ -1,19 +1,14 @@ #### Subscribers ######## subscribers: front_cam: - channels: ['rgb'] - fusion: [ 'color' ] - semantic_segmentation: False - publish_segmentation_image: True - segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large + channels: ['grass','tree',"person" ] + fusion: ['class_average','class_average','class_average' ] + semantic_segmentation: True + segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large show_label_legend: False - data_type: image - image_info_topic: "/wide_angle_camera_front/camera_info" + image_topic: "/camera/rgb/image_raw" + image_info_topic: "/camera/depth/camera_info" resize: 0.5 - cam_info_topic: "/camera/depth/camera_info" - image_topic: "/camera/rgb/image_raw" - depth_topic: "/camera/depth/image_raw" - cam_frame: "camera_rgb_optical_frame" - sem_seg_topic: "/elevation_mapping/semantic_wide_seg_f" - sem_seg_image_topic: "/elevation_mapping/semantic_wide_seg_im_f" \ No newline at end of file + sem_seg_topic: "/elevation_mapping/semantic_front" + sem_seg_image_topic: "/elevation_mapping/semantic_image_front" \ No newline at end of file diff --git a/elevation_mapping_cupy/config/semantic_image_sensor_parameter.yaml b/elevation_mapping_cupy/config/semantic_image_sensor_parameter.yaml index 75c690f4..5965c88a 100644 --- a/elevation_mapping_cupy/config/semantic_image_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/semantic_image_sensor_parameter.yaml @@ -4,22 +4,21 @@ subscribers: # fusion: ['average','average'] # topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: - channels: ['rgb', 'grass','tree',"person" ] - fusion: [ 'color','exponential','exponential','exponential' ] - topic_name: '/elevation_mapping/pointcloud_semantic' - semantic_segmentation: True - publish_segmentation_image: True - segmentation_model: 'lraspp_mobilenet_v3_large' - show_label_legend: False + channels: [ 'grass','tree',"person" ] + fusion: [ 'exponential','exponential','exponential' ] + topic_name_camera: '/elevation_mapping/semantic_front' + topic_name_camera_info: '/camera/depth/camera_info' data_type: image - cam_info_topic: "/camera/depth/camera_info" - image_topic: "/camera/rgb/image_raw" - depth_topic: "/camera/depth/image_raw" - cam_frame: "camera_rgb_optical_frame" + color_cam: # for color camera + channels: ['rgb'] + fusion: ['color'] + topic_name_camera: '/camera/rgb/image_raw' + topic_name_camera_info: '/camera/depth/camera_info' + data_type: image pointcloud: channels: [] fusion: [] - topic_name: '/elevation_mapping/pointcloud_semantic' + topic_name: '/camera/depth/points' data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/config/semantic_parameters.yaml b/elevation_mapping_cupy/config/semantic_parameters.yaml index c471af5d..b4eae18c 100644 --- a/elevation_mapping_cupy/config/semantic_parameters.yaml +++ b/elevation_mapping_cupy/config/semantic_parameters.yaml @@ -81,7 +81,7 @@ publishers: # basic_layers: ['elevation', 'traversability'] # fps: 2.0 elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','robot_centric_elevation','sem_fil','sem_traversability'] + layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','sem_fil'] basic_layers: ['min_filter'] fps: 3.0 diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch index 176ec061..6fc21735 100644 --- a/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch @@ -6,7 +6,7 @@ - diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch index 4e60fee8..936696a2 100644 --- a/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch @@ -13,7 +13,7 @@ - + \ No newline at end of file From ed97e20ab903fc229367bfc01cfb481d10e4e3db Mon Sep 17 00:00:00 2001 From: CihatAltiparmak Date: Mon, 24 Jul 2023 22:28:03 +0300 Subject: [PATCH 355/504] Fixed cupy.int as cupy.int32 --- .../script/elevation_mapping_cupy/elevation_mapping.py | 2 +- .../script/elevation_mapping_cupy/traversability_polygon.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index c300b0ca..d006ce20 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -149,7 +149,7 @@ def pad_value(self, x, shift_value, idx=None, value=0.0): x[idx, :, shift_value[1] :] = value def shift_map_xy(self, delta_pixel): - shift_value = delta_pixel.astype(cp.int) + shift_value = delta_pixel.astype(cp.int32) if cp.abs(shift_value).sum() == 0: return with self.map_lock: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py index 67a43343..e40462b7 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py @@ -59,7 +59,7 @@ def transform_to_map_position(polygon, center, cell_n, resolution): def transform_to_map_index(points, center, cell_n, resolution): - indices = ((points - center.reshape(1, 2)) / resolution + cell_n / 2).astype(cp.int) + indices = ((points - center.reshape(1, 2)) / resolution + cell_n / 2).astype(cp.int32) return indices From cca0028fe84cf7374775eb05bbafe4f8cfe82411 Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 1 Aug 2023 10:36:08 +0200 Subject: [PATCH 356/504] added last example --- docs/source/getting_started/tutorial.rst | 5 + .../config/features_parameters.yaml | 94 +++++++ .../config/features_plugin_config.yaml | 70 +++++ .../config/features_semantics.yaml | 32 +++ .../config/features_sensor_parameter.yaml | 13 + ...l => image_semantic_sensor_parameter.yaml} | 0 .../turtlesim_features_image_example.launch | 18 ++ .../turtlesim_semantic_image_example.launch | 2 +- .../rviz/turtle_features_example.rviz | 247 ++++++++++++++++++ .../plugins/features_pca.py | 3 +- 10 files changed, 481 insertions(+), 3 deletions(-) create mode 100644 elevation_mapping_cupy/config/features_parameters.yaml create mode 100644 elevation_mapping_cupy/config/features_plugin_config.yaml create mode 100644 elevation_mapping_cupy/config/features_semantics.yaml create mode 100644 elevation_mapping_cupy/config/features_sensor_parameter.yaml rename elevation_mapping_cupy/config/{semantic_image_sensor_parameter.yaml => image_semantic_sensor_parameter.yaml} (100%) create mode 100644 elevation_mapping_cupy/launch/turtlesim_features_image_example.launch create mode 100644 elevation_mapping_cupy/rviz/turtle_features_example.rviz diff --git a/docs/source/getting_started/tutorial.rst b/docs/source/getting_started/tutorial.rst index 12e6cb91..abefdf8d 100644 --- a/docs/source/getting_started/tutorial.rst +++ b/docs/source/getting_started/tutorial.rst @@ -111,7 +111,12 @@ For fusing semantics into the map such as rgb from an image: export TURTLEBOT3_MODEL=waffle roslaunch elevation_mapping_cupy turtlesim_semantic_image_example.launch +For fusing features extracted with a feature extractor from an image: +.. code-block:: bash + + export TURTLEBOT3_MODEL=waffle + roslaunch elevation_mapping_cupy turtlesim_features_image_example.launch Or, for the version including plane segmentation: diff --git a/elevation_mapping_cupy/config/features_parameters.yaml b/elevation_mapping_cupy/config/features_parameters.yaml new file mode 100644 index 00000000..e1c4c881 --- /dev/null +++ b/elevation_mapping_cupy/config/features_parameters.yaml @@ -0,0 +1,94 @@ +#### Basic parameters ######## +resolution: 0.04 # resolution in m. +map_length: 8.0 # map's size in m. +sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). +mahalanobis_thresh: 2.0 # points outside this distance is outlier. +outlier_variance: 0.01 # if point is outlier, add this value to the cell. +drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. +max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) +drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation +time_variance: 0.0001 # add this value when update_variance is called. +max_variance: 100.0 # maximum variance for each cell. +initial_variance: 1000.0 # initial variance for each cell. +traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. +dilation_size: 3 # dilation filter size before traversability filter. +wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. +min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. +position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. +orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. +position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. +orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. +min_valid_distance: 0.5 # points with shorter distance will be filtered out. +max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. +ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +update_variance_fps: 5.0 # fps for updating variance. +update_pose_fps: 10.0 # fps for updating pose and shift the center of map. +time_interval: 0.1 # Time layer is updated with this interval. +map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. +publish_statistics_fps: 1.0 # Publish statistics topic in this fps. + +max_ray_length: 10.0 # maximum length for ray tracing. +cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. +cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + +safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. +safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. +max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + +overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) +overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + +map_frame: 'odom' # The map frame where the odometry source uses. +base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. +corrected_map_frame: 'odom' + +#### Feature toggles ######## +enable_edge_sharpen: true +enable_visibility_cleanup: true +enable_drift_compensation: true +enable_overlap_clearance: true +enable_pointcloud_publishing: false +enable_drift_corrected_TF_publishing: false +enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + +#### Traversability filter ######## +use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. +weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter + +#### Upper bound ######## +use_only_above_for_upper_bound: false + +#### Plugins ######## +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/features_plugin_config.yaml' + +#### Subscribers ######## + + +#### Publishers ######## +# topic_name: +# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names +# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. +# fps: # Publish rate. Use smaller value than `map_acquire_fps`. +publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','pca'] + basic_layers: ['elevation'] + fps: 5.0 +# elevation_map_recordable: +# layers: ['elevation', 'traversability'] +# basic_layers: ['elevation', 'traversability'] +# fps: 2.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation','pca'] + basic_layers: ['min_filter'] + fps: 3.0 + +#### Initializer ######## +initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' +initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. +dilation_size_initialize: 5 # dilation size after the init. +initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. +use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/features_plugin_config.yaml b/elevation_mapping_cupy/config/features_plugin_config.yaml new file mode 100644 index 00000000..6bf79c0a --- /dev/null +++ b/elevation_mapping_cupy/config/features_plugin_config.yaml @@ -0,0 +1,70 @@ +# Settings of the plugins. (The plugins should be stored in script/plugins) + +# min_filter fills in minimum value around the invalid cell. +min_filter: + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations +# Apply smoothing. +smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" +# Apply inpainting using opencv +inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns +# Apply smoothing for inpainted layer + +robot_centric_elevation: # Use the same name as your file name. +# type: "robot_centric_elevation" + enable: False # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "robot_centric_elevation" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. +# add_value: 2.0 # Example param + resolution: 0.04 + threshold: 1.1 + use_threshold: True + +semantic_filter: + type: "semantic_filter" + enable: False + fill_nan: False + is_height_layer: False + layer_name: "sem_fil" + extra_params: + classes: ['grass','tree','fence','dirt'] + +semantic_traversability: + type: "semantic_traversability" + enable: False + fill_nan: False + is_height_layer: False + layer_name: "sem_traversability" + extra_params: + layers: ['traversability','robot_centric_elevation'] + thresholds: [0.3,0.5] + type: ['traversability', 'elevation'] + +features_pca: + type: "features_pca" + enable: True + fill_nan: False + is_height_layer: False + layer_name: "pca" + extra_params: + classes: [] + diff --git a/elevation_mapping_cupy/config/features_semantics.yaml b/elevation_mapping_cupy/config/features_semantics.yaml new file mode 100644 index 00000000..4cd5365f --- /dev/null +++ b/elevation_mapping_cupy/config/features_semantics.yaml @@ -0,0 +1,32 @@ +#### Subscribers ######## +subscribers: + + feat_front: + fusion: ['average','average','average','average','average','average','average','average','average','average'] + image_topic: "/camera/rgb/image_raw" + image_info_topic: "/camera/depth/camera_info" + semantic_segmentation: False + feature_extractor: True + feature_topic: "/elevation_mapping/feat_f" + feat_image_topic: "/elevation_mapping/feat_im_f" + show_label_legend: True + channels: [ 'feat_0','feat_1','feat_2','feat_3','feat_4','feat_5','feat_6','feat_7','feat_8','feat_9' ] + resize: 0.5 + input_size: [160,320] + +# sem_wide_back: +# fusion: ['average','average','average','average','average','average','average','average','average','average'] +# image_topic: "/wide_angle_camera_rear/image_color_rect/compressed" +# semantic_segmentation: False +# feature_extractor: True +# feature_topic: "/elevation_mapping/feat_b" +# feat_image_topic: "/elevation_mapping/feat_im_b" +# show_label_legend: False +# channels: [ 'feat_0','feat_1','feat_2','feat_3','feat_4','feat_5','feat_6','feat_7','feat_8','feat_9' ] +# image_info_topic: "/wide_angle_camera_rear/camera_info" +# resize: 0.5 +# input_size: [160,320] + + + + diff --git a/elevation_mapping_cupy/config/features_sensor_parameter.yaml b/elevation_mapping_cupy/config/features_sensor_parameter.yaml new file mode 100644 index 00000000..d09cc6b6 --- /dev/null +++ b/elevation_mapping_cupy/config/features_sensor_parameter.yaml @@ -0,0 +1,13 @@ +subscribers: + feat_front: + fusion: [ 'exponential','exponential','exponential','exponential','exponential','exponential','exponential','exponential','exponential','exponential' ] + topic_name_camera: /elevation_mapping/feat_f + topic_name_camera_info: "/camera/depth/camera_info" + channels: [ 'feat_0','feat_1','feat_2','feat_3','feat_4','feat_5','feat_6','feat_7','feat_8','feat_9' ] + data_type: image + pointcloud: + channels: [ ] + fusion: [ ] + topic_name: '/camera/depth/points' + data_type: pointcloud + diff --git a/elevation_mapping_cupy/config/semantic_image_sensor_parameter.yaml b/elevation_mapping_cupy/config/image_semantic_sensor_parameter.yaml similarity index 100% rename from elevation_mapping_cupy/config/semantic_image_sensor_parameter.yaml rename to elevation_mapping_cupy/config/image_semantic_sensor_parameter.yaml diff --git a/elevation_mapping_cupy/launch/turtlesim_features_image_example.launch b/elevation_mapping_cupy/launch/turtlesim_features_image_example.launch new file mode 100644 index 00000000..d4b7af3c --- /dev/null +++ b/elevation_mapping_cupy/launch/turtlesim_features_image_example.launch @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch index 936696a2..17eb97c3 100644 --- a/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch @@ -14,6 +14,6 @@ - + \ No newline at end of file diff --git a/elevation_mapping_cupy/rviz/turtle_features_example.rviz b/elevation_mapping_cupy/rviz/turtle_features_example.rviz new file mode 100644 index 00000000..95e38105 --- /dev/null +++ b/elevation_mapping_cupy/rviz/turtle_features_example.rviz @@ -0,0 +1,247 @@ +Panels: + - Class: rviz/Displays + Help Height: 138 + Name: Displays + Property Tree Widget: + Expanded: + - /Global Options1 + - /ElevationMapRaw1 + Splitter Ratio: 0.5768463015556335 + Tree Height: 631 + - Class: rviz/Selection + Name: Selection + - Class: rviz/Tool Properties + Expanded: + - /2D Pose Estimate1 + - /2D Nav Goal1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz/Time + Experimental: false + Name: Time + SyncMode: 0 + SyncSource: "" +Preferences: + PromptSaveOnExit: true +Toolbars: + toolButtonStyle: 2 +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.029999999329447746 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Alpha: 1 + Autocompute Intensity Bounds: false + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: pca + Color Transformer: ColorLayer + ColorMap: default + Enabled: true + Grid Cell Decimation: 1 + Grid Line Thickness: 0.10000000149011612 + Height Layer: elevation + Height Transformer: "" + History Length: 1 + Invert ColorMap: false + Max Color: 238; 238; 236 + Max Intensity: 1 + Min Color: 32; 74; 135 + Min Intensity: 0 + Name: ElevationMapRaw + Show Grid Lines: true + Topic: /elevation_mapping/elevation_map_raw + Unreliable: false + Use ColorMap: true + Value: true + - Alpha: 1 + Class: rviz/RobotModel + Collision Enabled: false + Enabled: true + Links: + All Links Enabled: true + Expand Joint Details: false + Expand Link Details: false + Expand Tree: false + Link Tree Style: Links in Alphabetic Order + base_footprint: + Alpha: 1 + Show Axes: false + Show Trail: false + base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + base_scan: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + camera_depth_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + camera_depth_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + camera_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + camera_rgb_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + camera_rgb_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + caster_back_left_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + caster_back_right_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + imu_link: + Alpha: 1 + Show Axes: false + Show Trail: false + wheel_left_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + wheel_right_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + Name: RobotModel + Robot Description: robot_description + TF Prefix: "" + Update Interval: 0 + Value: true + Visual Enabled: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Autocompute Value Bounds: + Max Value: 10 + Min Value: -10 + Value: true + Axis: Z + Channel Name: intensity + Class: rviz/PointCloud2 + Color: 255; 255; 255 + Color Transformer: RGB8 + Decay Time: 0 + Enabled: false + Invert Rainbow: false + Max Color: 255; 255; 255 + Min Color: 0; 0; 0 + Name: PointCloud2 + Position Transformer: XYZ + Queue Size: 10 + Selectable: true + Size (Pixels): 3 + Size (m): 0.009999999776482582 + Style: Flat Squares + Topic: /camera/depth/points + Unreliable: false + Use Fixed Frame: true + Use rainbow: true + Value: false + Enabled: true + Global Options: + Background Color: 255; 255; 255 + Default Light: true + Fixed Frame: odom + Frame Rate: 30 + Name: root + Tools: + - Class: rviz/Interact + Hide Inactive Objects: true + - Class: rviz/MoveCamera + - Class: rviz/Select + - Class: rviz/FocusCamera + - Class: rviz/Measure + - Class: rviz/SetInitialPose + Theta std deviation: 0.2617993950843811 + Topic: /initialpose + X std deviation: 0.5 + Y std deviation: 0.5 + - Class: rviz/SetGoal + Topic: /move_base_simple/goal + - Class: rviz/PublishPoint + Single click: true + Topic: /clicked_point + Value: true + Views: + Current: + Class: rviz/Orbit + Distance: 9.118926048278809 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Field of View: 0.7853981852531433 + Focal Point: + X: 2.046891927719116 + Y: -0.5291382074356079 + Z: -0.3964909017086029 + Focal Shape Fixed Size: true + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 0.4647965431213379 + Target Frame: base_footprint + Yaw: 2.9933695793151855 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 1016 + Hide Left Dock: false + Hide Right Dock: true + QMainWindow State: 000000ff00000000fd0000000400000000000001f70000033efc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000033e000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007380000005afc0100000002fb0000000800540069006d0065010000000000000738000002eb00fffffffb0000000800540069006d006501000000000000045000000000000000000000053b0000033e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: true + Width: 1848 + X: 72 + Y: 27 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py index b62ead31..5422a39c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py @@ -13,7 +13,6 @@ class FeaturesPca(PluginBase): def __init__( self, - cell_n: int = 100, **kwargs, ): """This is a filter to create a pca layer of the semantic features in the map. @@ -52,7 +51,7 @@ def __call__( # get indices of all layers that contain semantic features information layer_indices = cp.array([], dtype=cp.int32) for it, fusion_alg in enumerate(semantic_params.fusion_algorithms): - if fusion_alg in ["average", "bayesian_inference", "image_exponential"]: + if fusion_alg in ["average", "bayesian_inference", "exponential"]: layer_indices = cp.append(layer_indices, it).astype(cp.int32) n_c = semantic_map[layer_indices].shape[1] From 0bf3fa021f37aafc3869ccc0ecf6267b1febb38e Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 1 Aug 2023 10:43:05 +0200 Subject: [PATCH 357/504] formatted code --- .../fusion/image_color.py | 26 ++++++++-------- .../fusion/image_exponential.py | 23 +++++++------- .../fusion/pointcloud_average.py | 2 +- .../fusion/pointcloud_bayesian_inference.py | 8 ++--- .../fusion/pointcloud_class_average.py | 7 ++--- .../fusion/pointcloud_class_bayesian.py | 8 +---- .../fusion/pointcloud_class_max.py | 8 ++--- .../fusion/pointcloud_color.py | 14 ++------- .../plugins/plugin_manager.py | 30 +++++++++---------- .../plugins/semantic_filter.py | 5 ++-- .../plugins/semantic_traversability.py | 3 +- .../elevation_mapping_cupy/semantic_map.py | 2 +- .../tests/test_plugins.py | 10 ++++++- .../semantic_sensor/image_parameters.py | 1 - .../script/semantic_sensor/pointcloud_node.py | 11 ++++--- 15 files changed, 68 insertions(+), 90 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py index 68e2313c..317530d5 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py @@ -5,7 +5,6 @@ from .fusion_manager import FusionBase - def color_correspondences_to_map_kernel(resolution, width, height): color_correspondences_to_map_kernel = cp.ElementwiseKernel( in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", @@ -44,6 +43,7 @@ def color_correspondences_to_map_kernel(resolution, width, height): ) return color_correspondences_to_map_kernel + class ImageColor(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) @@ -58,8 +58,18 @@ def __init__(self, params, *args, **kwargs): height=self.cell_n, ) - - def __call__(self, sem_map_idx,image, j,uv_correspondence, valid_correspondence, image_height, image_width , semantic_map, new_map): + def __call__( + self, + sem_map_idx, + image, + j, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + semantic_map, + new_map, + ): self.color_correspondences_to_map_kernel( semantic_map, cp.uint64(sem_map_idx), @@ -72,13 +82,3 @@ def __call__(self, sem_map_idx,image, j,uv_correspondence, valid_correspondence, size=int(self.cell_n * self.cell_n), ) semantic_map[sem_map_idx] = new_map[sem_map_idx] - - - - - - - - - - diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py index 19061ce1..d9ad1ce7 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py @@ -50,7 +50,18 @@ def __init__(self, params, *args, **kwargs): alpha=0.7, ) - def __call__(self, sem_map_idx,image, j,uv_correspondence, valid_correspondence, image_height, image_width , semantic_map, new_map): + def __call__( + self, + sem_map_idx, + image, + j, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + semantic_map, + new_map, + ): self.exponential_correspondences_to_map_kernel( semantic_map, sem_map_idx, @@ -63,13 +74,3 @@ def __call__(self, sem_map_idx,image, j,uv_correspondence, valid_correspondence, size=int(self.cell_n * self.cell_n), ) semantic_map[sem_map_idx] = new_map[sem_map_idx] - - - - - - - - - - diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py index 3d2e25e4..cda9af96 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py @@ -100,7 +100,7 @@ def __init__(self, params, *args, **kwargs): self.cell_n, ) - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,*args): + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): self.sum_kernel( points_all, R, diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py index 6cecd03b..f9f07b4a 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py @@ -42,7 +42,6 @@ def sum_compact_kernel( return sum_compact_kernel - def bayesian_inference_kernel( width, height, @@ -80,7 +79,6 @@ def bayesian_inference_kernel( return bayesian_inference_kernel - class BayesianInference(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) @@ -109,9 +107,9 @@ def __init__(self, params, *args, **kwargs): self.bayesian_inference_kernel = bayesian_inference_kernel( self.cell_n, self.cell_n, - ) + ) - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,*args): + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): self.sum_mean *= 0 self.sum_compact_kernel( points_all, @@ -133,5 +131,3 @@ def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_ semantic_map, size=(self.cell_n * self.cell_n), ) - - diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py index ba45d034..a28c98db 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py @@ -93,7 +93,6 @@ def class_average_kernel( return class_average_kernel - class ClassAverage(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) @@ -112,9 +111,9 @@ def __init__(self, params, *args, **kwargs): self.cell_n, self.cell_n, self.average_weight, - ) + ) - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,*args): + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): self.sum_kernel( points_all, R, @@ -135,5 +134,3 @@ def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_ semantic_map, size=(self.cell_n * self.cell_n * pcl_ids.shape[0]), ) - - diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py index 5ae9d2b4..eeae2324 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py @@ -5,7 +5,6 @@ from .fusion_manager import FusionBase - def alpha_kernel( resolution, width, @@ -49,7 +48,6 @@ def alpha_kernel( return alpha_kernel - class ClassBayesian(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) @@ -63,9 +61,7 @@ def __init__(self, params, *args, **kwargs): self.cell_n, ) - - - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,*args): + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): self.alpha_kernel( points_all, pcl_ids, @@ -79,5 +75,3 @@ def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_ # do not divide by zero sum_alpha[sum_alpha == 0] = 1 semantic_map[layer_ids] = new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) - - diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py index 65a4df03..ea8d0c5c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py @@ -5,8 +5,6 @@ from .fusion_manager import FusionBase - - def sum_max_kernel( resolution, width, @@ -82,7 +80,7 @@ def decode_max(self, mer): ind = cp.right_shift(mer, 16) return ma, ind - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,elements_to_shift): + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, elements_to_shift): max_pt, pt_id = self.decode_max(points_all[:, pcl_ids]) # find unique ids in new measurement and in existing map unique_idm = cp.unique(pt_id) @@ -115,7 +113,7 @@ def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_ ) # add the previous alpha for i, lay in enumerate(layer_ids): - c = cp.mgrid[0: new_map.shape[1], 0: new_map.shape[2]] + c = cp.mgrid[0 : new_map.shape[1], 0 : new_map.shape[2]] # self.prob_sum[self.elements_to_shift["id_max"][i], c[0], c[1]] += self.new_map[lay] # TODO add residual of prev alpha to the prob_sum # res = 1- self.new_map[lay] @@ -131,5 +129,3 @@ def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_ # do not divide by zero sum_alpha[sum_alpha == 0] = 1 semantic_map[layer_ids] = new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) - - diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py index a6c0cb1f..1c24fedb 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py @@ -4,6 +4,7 @@ from .fusion_manager import FusionBase + def add_color_kernel( width, height, @@ -55,7 +56,6 @@ def add_color_kernel( return add_color_kernel - def color_average_kernel( width, height, @@ -115,7 +115,6 @@ def color_average_kernel( return color_average_kernel - class Color(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) @@ -130,7 +129,7 @@ def __init__(self, params, *args, **kwargs): ) self.color_average_kernel = color_average_kernel(self.cell_n, self.cell_n) - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_map, new_map,*args): + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): self.color_map = cp.zeros( (1 + 3 * layer_ids.shape[0], self.cell_n, self.cell_n), dtype=cp.uint32, @@ -155,12 +154,3 @@ def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map,semantic_ semantic_map, size=(self.cell_n * self.cell_n), ) - - - - - - - - - diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index c04497e5..fd1185e1 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -34,13 +34,13 @@ def __init__(self, *args, **kwargs): """ def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - *args, - **kwargs, + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + *args, + **kwargs, ) -> cp.ndarray: """This gets the elevation map data and plugin layers as a cupy array. @@ -136,14 +136,14 @@ def get_layer_index_with_name(self, name: str) -> int: return None def update_with_name( - self, - name: str, - elevation_map: cp.ndarray, - layer_names: List[str], - semantic_map=None, - semantic_params=None, - rotation=None, - elements_to_shift={}, + self, + name: str, + elevation_map: cp.ndarray, + layer_names: List[str], + semantic_map=None, + semantic_params=None, + rotation=None, + elements_to_shift={}, ): idx = self.get_layer_index_with_name(name) if idx is not None: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index f7176169..eeb2a0ea 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -69,9 +69,8 @@ def __call__( semantic_map: cp.ndarray, semantic_params, rotation, - elements_to_shift, - *args, - + elements_to_shift, + *args, ) -> cp.ndarray: """ diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py index 7abbf714..01d3e882 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py @@ -40,8 +40,7 @@ def __call__( plugin_layer_names: List[str], semantic_map, semantic_params, - *args, - + *args, ) -> cp.ndarray: """ diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 4aca6e62..d090416c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -33,7 +33,7 @@ def __init__(self, param: Parameter): assert self.layer_specs[c] == f, "Error: Single layer has multiple fusion algorithms!" if f not in self.unique_fusion: dt = config["data_type"] - self.unique_fusion.append(dt+"_"+f) + self.unique_fusion.append(dt + "_" + f) self.amount_layer_names = len(self.layer_names) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py index 6aab26ed..7c1dc945 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -59,5 +59,13 @@ def test_plugin_manager(semmap_ex, channels): manager.update_with_name("semantic_traversability", elevation_map, layer_names, semmap_ex) manager.get_map_with_name("smooth") for lay in manager.get_layer_names(): - manager.update_with_name(lay, elevation_map, layer_names, semmap_ex.semantic_map,semmap_ex.param, rotation, semmap_ex.elements_to_shift) + manager.update_with_name( + lay, + elevation_map, + layer_names, + semmap_ex.semantic_map, + semmap_ex.param, + rotation, + semmap_ex.elements_to_shift, + ) manager.get_map_with_name(lay) diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py index 0df6fe57..01f68cfa 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py @@ -35,4 +35,3 @@ class ImageParameter(Serializable): feat_image_topic: str = "/elevation_mapping/semantic_seg_feat_im" resize: float = None image_info_topic: str = "/elevation_mapping/image_info" - diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py index 9bc4232f..cad57758 100755 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py @@ -57,7 +57,6 @@ def __init__(self, sensor_name): self.prediction_img = None self.feat_img = None - def initialize_semantics(self): """Resolve the feature and segmentation mode and create segmentation_channel and feature_channels. @@ -147,9 +146,9 @@ def bitget(byteval, idx): c = c >> 3 cmap[i] = np.array([r, g, b]) - cmap[1] = np.array([188,63,59]) - cmap[2] = np.array([81,113,162]) - cmap[3] = np.array([136,49,132]) + cmap[1] = np.array([188, 63, 59]) + cmap[2] = np.array([81, 113, 162]) + cmap[3] = np.array([136, 49, 132]) cmap = cmap / 255 if normalized else cmap return cmap[1:] @@ -317,6 +316,7 @@ def extract_features(self, image, points, u, v): # todo if False and self.param.feature_extractor: self.feat_img = prediction + def publish_segmentation_image(self, probabilities): if self.param.semantic_segmentation: colors = cp.asarray(self.semseg_color_map) @@ -356,7 +356,7 @@ def publish_feature_image(self, features): pca = PCA(n_components=n_components).fit(data) pca_descriptors = pca.transform(data) img_pca = pca_descriptors.reshape(features.shape[1], features.shape[2], n_components) - comp = img_pca #[:, :, -3:] + comp = img_pca # [:, :, -3:] comp_min = comp.min(axis=(0, 1)) comp_max = comp.max(axis=(0, 1)) comp_img = (comp - comp_min) / (comp_max - comp_min) @@ -365,7 +365,6 @@ def publish_feature_image(self, features): feat_msg.header.frame_id = self.header.frame_id self.feat_pub.publish(feat_msg) - def publish_pointcloud(self, pcl, header): pc2 = ros_numpy.msgify(PointCloud2, pcl) pc2.header = header From 38a3aa56048964954022e409f42256fc9b048ab0 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Fri, 4 Aug 2023 09:58:31 +0200 Subject: [PATCH 358/504] fixed simple parsing dependency --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 39e669bf..e9d43858 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ scipy==1.7 dataclasses ruamel.yaml opencv-python -simple_parsing +simple-parsing scikit-image matplotlib From edaab5cccfb08e51ff7bbfdf0a9c2921e4295525 Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Fri, 4 Aug 2023 10:22:17 +0200 Subject: [PATCH 359/504] added configuration for anymal --- .../config/anymal_parameters.yaml | 89 +++++++++++++++++++ .../config/anymal_plugin_config.yaml | 28 ++++++ .../config/anymal_sensor_parameter.yaml | 43 +++++++++ elevation_mapping_cupy/launch/anymal.launch | 7 ++ 4 files changed, 167 insertions(+) create mode 100644 elevation_mapping_cupy/config/anymal_parameters.yaml create mode 100644 elevation_mapping_cupy/config/anymal_plugin_config.yaml create mode 100644 elevation_mapping_cupy/config/anymal_sensor_parameter.yaml create mode 100644 elevation_mapping_cupy/launch/anymal.launch diff --git a/elevation_mapping_cupy/config/anymal_parameters.yaml b/elevation_mapping_cupy/config/anymal_parameters.yaml new file mode 100644 index 00000000..c1aa165b --- /dev/null +++ b/elevation_mapping_cupy/config/anymal_parameters.yaml @@ -0,0 +1,89 @@ +#### Basic parameters ######## +resolution: 0.04 # resolution in m. +map_length: 8 # map's size in m. +sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). +mahalanobis_thresh: 2.0 # points outside this distance is outlier. +outlier_variance: 0.01 # if point is outlier, add this value to the cell. +drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. +max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) +drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation +time_variance: 0.0001 # add this value when update_variance is called. +max_variance: 100.0 # maximum variance for each cell. +initial_variance: 1000.0 # initial variance for each cell. +traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. +dilation_size: 3 # dilation filter size before traversability filter. +wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. +min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. +position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. +orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. +position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. +orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. +min_valid_distance: 0.5 # points with shorter distance will be filtered out. +max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. +ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. +update_variance_fps: 5.0 # fps for updating variance. +update_pose_fps: 10.0 # fps for updating pose and shift the center of map. +time_interval: 0.1 # Time layer is updated with this interval. +map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. +publish_statistics_fps: 1.0 # Publish statistics topic in this fps. + +max_ray_length: 10.0 # maximum length for ray tracing. +cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. +cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + +safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. +safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. +max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + +overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) +overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + +map_frame: 'odom' # The map frame where the odometry source uses. +base_frame: 'base' # The robot's base frame. This frame will be a center of the map. +corrected_map_frame: 'odom_corrected' + +#### Feature toggles ######## +enable_edge_sharpen: true +enable_visibility_cleanup: true +enable_drift_compensation: true +enable_overlap_clearance: true +enable_pointcloud_publishing: false +enable_drift_corrected_TF_publishing: false +enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + +#### Traversability filter ######## +use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. +weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter + +#### Upper bound ######## +use_only_above_for_upper_bound: false + +#### Plugins ######## +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin_config.yaml' + +#### Publishers ######## +# topic_name: +# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names +# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. +# fps: # Publish rate. Use smaller value than `map_acquire_fps`. + +publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance'] + basic_layers: ['elevation', 'traversability'] + fps: 5.0 + + semantic_map_raw: + layers: ['elevation', 'traversability'] + basic_layers: ['elevation', 'traversability'] + fps: 5.0 + +#### Initializer ######## +initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' +initialize_frame_id: ['RF_FOOT', 'LF_FOOT', 'RH_FOOT', 'LH_FOOT'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. +dilation_size_initialize: 5 # dilation size after the init. +initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. +use_initializer_at_start: true # Use initializer when the node starts. \ No newline at end of file diff --git a/elevation_mapping_cupy/config/anymal_plugin_config.yaml b/elevation_mapping_cupy/config/anymal_plugin_config.yaml new file mode 100644 index 00000000..d5da9e67 --- /dev/null +++ b/elevation_mapping_cupy/config/anymal_plugin_config.yaml @@ -0,0 +1,28 @@ +# Settings of the plugins. (The plugins should be stored in script/plugins) +# min_filter fills in minimum value around the invalid cell. +min_filter: + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations + +# Apply smoothing. +smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" + +# Apply inpainting using opencv +inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml new file mode 100644 index 00000000..ecb96c73 --- /dev/null +++ b/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml @@ -0,0 +1,43 @@ +#### Subscribers ######## +subscribers: + front_depth: + channels: [] + fusion: [] + topic_name: /depth_camera_front/point_cloud_self_filtered + data_type: pointcloud + + rear_depth: + channels: [] + fusion: [] + topic_name: /depth_camera_rear/point_cloud_self_filtered + data_type: pointcloud + + left_depth: + channels: [] + fusion: [] + topic_name: /depth_camera_left/point_cloud_self_filtered + data_type: pointcloud + + right_depth: + channels: [] + fusion: [] + topic_name: /depth_camera_right/point_cloud_self_filtered + data_type: pointcloud + + velodyne: + channels: [] + fusion: [] + topic_name: /point_cloud_filter/lidar/point_cloud_filtered + data_type: pointcloud + + front_bpearl: + channels: [] + fusion: [] + topic_name: /robot_self_filter/bpearl_front/point_cloud + data_type: pointcloud + + rear_bpearl: + channels: [] + fusion: [] + topic_name: /robot_self_filter/bpearl_rear/point_cloud + data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/anymal.launch b/elevation_mapping_cupy/launch/anymal.launch new file mode 100644 index 00000000..cc598ea2 --- /dev/null +++ b/elevation_mapping_cupy/launch/anymal.launch @@ -0,0 +1,7 @@ + + + + + + + From 1ae86f2fba8e411df8b50e13782899435337e6c7 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Sun, 20 Aug 2023 23:10:41 +0200 Subject: [PATCH 360/504] Updated documents for plugins. --- .../plugins/features_pca.py | 14 +++++----- .../plugins/inpainting.py | 19 ++++++++------ .../plugins/min_filter.py | 16 ++++++------ .../plugins/robot_centric_elevation.py | 18 ++++++------- .../plugins/semantic_filter.py | 14 +++++----- .../plugins/semantic_traversability.py | 22 +++++++++------- .../plugins/smooth_filter.py | 26 +++++++++++++------ 7 files changed, 72 insertions(+), 57 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py index 5422a39c..ad1236bf 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py @@ -11,17 +11,17 @@ class FeaturesPca(PluginBase): + """This is a filter to create a pca layer of the semantic features in the map. + + Args: + cell_n (int): width and height of the elevation map. + classes (ruamel.yaml.comments.CommentedSeq): + **kwargs (): + """ def __init__( self, **kwargs, ): - """This is a filter to create a pca layer of the semantic features in the map. - - Args: - cell_n (int): width and height of the elevation map. - classes (ruamel.yaml.comments.CommentedSeq): - **kwargs (): - """ super().__init__() self.indices = [] diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py index 4b6dc2f5..622c0150 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py @@ -12,14 +12,15 @@ class Inpainting(PluginBase): - def __init__(self, cell_n: int = 100, method: str = "telea", **kwargs): - """ + """ + This class is used for inpainting, a process of reconstructing lost or deteriorated parts of images and videos. - Args: - cell_n (int): - method (str): - **kwargs (): - """ + Args: + cell_n (int): The number of cells. Default is 100. + method (str): The inpainting method. Options are 'telea' or 'ns' (Navier-Stokes). Default is 'telea'. + **kwargs (): Additional keyword arguments. + """ + def __init__(self, cell_n: int = 100, method: str = "telea", **kwargs): super().__init__() if method == "telea": self.method = cv.INPAINT_TELEA @@ -53,7 +54,9 @@ def __call__( h = elevation_map[0] h_max = float(h[mask < 1].max()) h_min = float(h[mask < 1].min()) - h = cp.asnumpy((elevation_map[0] - h_min) * 255 / (h_max - h_min)).astype("uint8") + h = cp.asnumpy((elevation_map[0] - h_min) * 255 / (h_max - h_min)).astype( + "uint8" + ) dst = np.array(cv.inpaint(h, mask, 1, self.method)) h_inpainted = dst.astype(np.float32) * (h_max - h_min) / 255 + h_min return cp.asarray(h_inpainted).astype(np.float64) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py index 6c479b03..c685eed6 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py @@ -10,15 +10,15 @@ class MinFilter(PluginBase): - def __init__(self, cell_n: int = 100, dilation_size: int = 5, iteration_n: int = 5, **kwargs): - """This is a filter to fill in invalid cells with minimum values around. + """This is a filter to fill in invalid cells with minimum values around. - Args: - cell_n (int): width of the elevation map. - dilation_size (int): The size of the patch to search for minimum value for each iteration. - iteration_n (int): The number of iteration to repeat the same filter. - **kwargs (): - """ + Args: + cell_n (int): width of the elevation map. + dilation_size (int): The size of the patch to search for minimum value for each iteration. + iteration_n (int): The number of iteration to repeat the same filter. + **kwargs (): + """ + def __init__(self, cell_n: int = 100, dilation_size: int = 5, iteration_n: int = 5, **kwargs): super().__init__() self.iteration_n = iteration_n self.width = cell_n diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py index 47ac799a..e9b43266 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py @@ -5,18 +5,18 @@ class RobotCentricElevation(PluginBase): + """Generates an elevation map with respect to the robot frame. + + Args: + cell_n (int): + resolution (ruamel.yaml.scalarfloat.ScalarFloat): + threshold (ruamel.yaml.scalarfloat.ScalarFloat): + use_threshold (bool): + **kwargs (): + """ def __init__( self, cell_n: int = 100, resolution: float = 0.05, threshold: float = 0.4, use_threshold: bool = 0, **kwargs ): - """Generates an elevation map with respect to the robot frame. - - Args: - cell_n (int): - resolution (ruamel.yaml.scalarfloat.ScalarFloat): - threshold (ruamel.yaml.scalarfloat.ScalarFloat): - use_threshold (bool): - **kwargs (): - """ super().__init__() self.width = cell_n self.height = cell_n diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index eeb2a0ea..3331afe7 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -10,19 +10,19 @@ class SemanticFilter(PluginBase): + """This is a filter to create a one hot encoded map of the class probabilities. + + Args: + cell_n (int): width and height of the elevation map. + classes (list): List of classes for semantic filtering. Default is ["person", "grass"]. + **kwargs: Additional keyword arguments. + """ def __init__( self, cell_n: int = 100, classes: list = ["person", "grass"], **kwargs, ): - """This is a filter to create a one hot encoded map of the class probabilities. - - Args: - cell_n (int): width and height of the elevation map. - classes (ruamel.yaml.comments.CommentedSeq): - **kwargs (): - """ super().__init__() self.indices = [] self.classes = classes diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py index 01d3e882..0c9af601 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py @@ -10,6 +10,15 @@ class SemanticTraversability(PluginBase): + """Extracts traversability and elevations from layers and generates an updated traversability that can be used by checker. + + Args: + cell_n (int): The width and height of the elevation map. + layers (list): List of layers for semantic traversability. Default is ["traversability"]. + thresholds (list): List of thresholds for each layer. Default is [0.5]. + type (list): List of types for each layer. Default is ["traversability"]. + **kwargs: Additional keyword arguments. + """ def __init__( self, cell_n: int = 100, @@ -18,15 +27,6 @@ def __init__( type: list = ["traversability"], **kwargs, ): - """Extracts traversability and elevations from layers and generates an updated traversability that can be used by checker. - - Args: - cell_n (int): - layers (ruamel.yaml.comments.CommentedSeq): - thresholds (ruamel.yaml.comments.CommentedSeq): - type (ruamel.yaml.comments.CommentedSeq): - **kwargs (): - """ super().__init__() self.layers = layers self.thresholds = cp.asarray(thresholds) @@ -69,7 +69,9 @@ def __call__( idx = plugin_layer_names.index(name) tempo = plugin_layers[idx] else: - print("Layer {} is not in the map, returning traversabiltiy!".format(name)) + print( + "Layer {} is not in the map, returning traversabiltiy!".format(name) + ) return if self.type[it] == "traversability": tempo = cp.where(tempo <= self.thresholds[it], 1, 0) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py index 79d0be80..f728d557 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py @@ -10,14 +10,20 @@ class SmoothFilter(PluginBase): - def __init__(self, cell_n: int = 100, input_layer_name: str = "elevation", **kwargs): - """This filters smoothees elevation map. + """ + SmoothFilter is a class that applies a smoothing filter + to the elevation map. The filter is applied to the layer specified by the input_layer_name parameter. + If the specified layer is not found, the filter is applied to the elevation layer. - Args: - cell_n (int): - input_layer_name (str): - **kwargs (): - """ + Args: + cell_n (int): The width and height of the elevation map. Default is 100. + input_layer_name (str): The name of the layer to which the filter should be applied. Default is "elevation". + **kwargs: Additional keyword arguments. + """ + + def __init__( + self, cell_n: int = 100, input_layer_name: str = "elevation", **kwargs + ): super().__init__() self.input_layer_name = input_layer_name @@ -48,7 +54,11 @@ def __call__( idx = plugin_layer_names.index(self.input_layer_name) h = plugin_layers[idx] else: - print("layer name {} was not found. Using elevation layer.".format(self.input_layer_name)) + print( + "layer name {} was not found. Using elevation layer.".format( + self.input_layer_name + ) + ) h = elevation_map[0] hs1 = ndimage.uniform_filter(h, size=3) hs1 = ndimage.uniform_filter(hs1, size=3) From 6f3a0028ed2455157f13b40b5827ecb58b8e3576 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Sun, 20 Aug 2023 23:10:58 +0200 Subject: [PATCH 361/504] Added missing cupy dependency. --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index e9d43858..1b84c227 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ opencv-python simple-parsing scikit-image matplotlib +cupy ###### Requirements with Version Specifiers ######` shapely==1.7.1 From 71ddbd3c1b546559e580d644cfd3897b0c1f0218 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Sun, 20 Aug 2023 23:11:44 +0200 Subject: [PATCH 362/504] Added missing requirements for semantic_sensor --- sensor_processing/semantic_sensor/setup.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sensor_processing/semantic_sensor/setup.py b/sensor_processing/semantic_sensor/setup.py index e9e4d498..e042fa90 100644 --- a/sensor_processing/semantic_sensor/setup.py +++ b/sensor_processing/semantic_sensor/setup.py @@ -5,6 +5,10 @@ packages=[ "semantic_sensor", ], + install_requires=[ + "torch", + "torchvision", + ], package_dir={"": "script"}, ) From 9a13ec5c2c1d5a6fe99e1e59400636d7138f23fa Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 24 Aug 2023 05:34:52 +0200 Subject: [PATCH 363/504] Fixed np.float issue. --- .../semantic_sensor/script/semantic_sensor/pointcloud_node.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py index cad57758..597cc080 100755 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py @@ -3,6 +3,7 @@ import numpy as np import cupy as cp +np.float = np.float64 # temp fix for following import suggested at https://github.com/eric-wieser/ros_numpy/issues/37 import ros_numpy import matplotlib.pyplot as plt from skimage.io import imshow From 1fd53bb7c946b97be639d514fa37f9801d0757dd Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 24 Aug 2023 06:24:55 +0200 Subject: [PATCH 364/504] Added some installation docs. --- docs/source/getting_started/installation.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 255fff74..9d65d6b7 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -219,3 +219,20 @@ have the third-party libaries installed on you machine: sudo apt install libboost-all-dev +Semantic Sensors +================================================================== +Elevation mapping node can receive multi-modal point cloud and image topics. +In this example, we use semantic segmentation models to process color images and publish those topics. + +Python dependencies +------------------------------------------------------------------- + +.. code-block:: bash + + pip3 install torchvision scikit-learn + +Detectron + +.. code-block:: bash + + python3 -m pip install 'git+https://github.com/facebookresearch/detectron2.git' \ No newline at end of file From b7a8f308878e226cec8b9faf88a47e8ca1d443c9 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 24 Aug 2023 06:25:32 +0200 Subject: [PATCH 365/504] Cleaning up config files. (wip) --- .../{parameters.yaml => core/core_param.yaml} | 30 +----- .../config/core/example_setup.yaml | 35 +++++++ .../config/core/plugin_config.yaml | 28 ++++++ .../config/{ => core}/weights.dat | Bin .../image_semantic_sensor_parameter.yaml | 24 ----- .../config/semantic_parameters.yaml | 94 ------------------ .../config/sensor_parameter.yaml | 15 --- .../anymal}/anymal_parameters.yaml | 0 .../anymal}/anymal_plugin_config.yaml | 0 .../anymal}/anymal_sensor_parameter.yaml | 0 .../features}/features_parameters.yaml | 0 .../features}/features_plugin_config.yaml | 0 .../features}/features_semantics.yaml | 0 .../features}/features_sensor_parameter.yaml | 0 .../features}/image_semantics.yaml | 0 .../turtle_bot}/plugin_config.yaml | 0 .../turtle_bot_image_semantics.yaml | 57 +++++++++++ .../turtle_bot/turtle_bot_semantics.yaml} | 20 +++- .../setups/turtle_bot/turtle_bot_simple.yaml | 20 ++++ .../launch/turtlesim_example.launch | 9 +- .../launch/turtlesim_semantic_example.launch | 6 +- .../turtlesim_semantic_image_example.launch | 9 +- ...rtlesim_semantic_pointcloud_example.launch | 19 ++++ .../elevation_mapping.py | 2 +- .../script/semantic_sensor/image_node.py | 3 + 25 files changed, 194 insertions(+), 177 deletions(-) rename elevation_mapping_cupy/config/{parameters.yaml => core/core_param.yaml} (85%) create mode 100644 elevation_mapping_cupy/config/core/example_setup.yaml create mode 100644 elevation_mapping_cupy/config/core/plugin_config.yaml rename elevation_mapping_cupy/config/{ => core}/weights.dat (100%) delete mode 100644 elevation_mapping_cupy/config/image_semantic_sensor_parameter.yaml delete mode 100644 elevation_mapping_cupy/config/semantic_parameters.yaml delete mode 100644 elevation_mapping_cupy/config/sensor_parameter.yaml rename elevation_mapping_cupy/config/{ => setups/anymal}/anymal_parameters.yaml (100%) rename elevation_mapping_cupy/config/{ => setups/anymal}/anymal_plugin_config.yaml (100%) rename elevation_mapping_cupy/config/{ => setups/anymal}/anymal_sensor_parameter.yaml (100%) rename elevation_mapping_cupy/config/{ => setups/features}/features_parameters.yaml (100%) rename elevation_mapping_cupy/config/{ => setups/features}/features_plugin_config.yaml (100%) rename elevation_mapping_cupy/config/{ => setups/features}/features_semantics.yaml (100%) rename elevation_mapping_cupy/config/{ => setups/features}/features_sensor_parameter.yaml (100%) rename elevation_mapping_cupy/config/{ => setups/features}/image_semantics.yaml (100%) rename elevation_mapping_cupy/config/{ => setups/turtle_bot}/plugin_config.yaml (100%) create mode 100644 elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_image_semantics.yaml rename elevation_mapping_cupy/config/{semantic_sensor_parameter.yaml => setups/turtle_bot/turtle_bot_semantics.yaml} (56%) create mode 100644 elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml create mode 100644 elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch diff --git a/elevation_mapping_cupy/config/parameters.yaml b/elevation_mapping_cupy/config/core/core_param.yaml similarity index 85% rename from elevation_mapping_cupy/config/parameters.yaml rename to elevation_mapping_cupy/config/core/core_param.yaml index 8354b36f..6bbede56 100644 --- a/elevation_mapping_cupy/config/parameters.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -55,36 +55,11 @@ enable_normal_color: false # If true, the map contains 'col #### Traversability filter ######## use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. -weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter +weight_file: '$(rospack find elevation_mapping_cupy)/config/core/weights.dat' # Weight file for traversability filter #### Upper bound ######## use_only_above_for_upper_bound: false -#### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/plugin_config.yaml' - -#### Subscribers ######## - - -#### Publishers ######## -# topic_name: -# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names -# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. -# fps: # Publish rate. Use smaller value than `map_acquire_fps`. -publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb'] - basic_layers: ['elevation'] - fps: 5.0 -# elevation_map_recordable: -# layers: ['elevation', 'traversability'] -# basic_layers: ['elevation', 'traversability'] -# fps: 2.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] - basic_layers: ['min_filter'] - fps: 3.0 - #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. @@ -92,3 +67,6 @@ initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z directio dilation_size_initialize: 2 # dilation size after the init. initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. + +#### Default Plugins ######## +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/core/plugin_config.yaml' \ No newline at end of file diff --git a/elevation_mapping_cupy/config/core/example_setup.yaml b/elevation_mapping_cupy/config/core/example_setup.yaml new file mode 100644 index 00000000..d31eb1e4 --- /dev/null +++ b/elevation_mapping_cupy/config/core/example_setup.yaml @@ -0,0 +1,35 @@ +#### Plugins ######## +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/core/plugin_config.yaml' + +#### Subscribers ######## +# sensor_name: +# channels: ['feat_0','feat_1'] +# fusion: ['average','average'] +# topic_name: '/elevation_mapping/pointcloud_semantic' + +subscribers: + front_cam: + channels: ['rgb' ] + fusion: [ 'color'] + topic_name: '/camera/depth/points' + data_type: pointcloud + +#### Publishers ######## +# topic_name: +# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names +# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. +# fps: # Publish rate. Use smaller value than `map_acquire_fps`. + +publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_recordable: + layers: ['elevation', 'traversability'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + basic_layers: ['min_filter'] + fps: 3.0 \ No newline at end of file diff --git a/elevation_mapping_cupy/config/core/plugin_config.yaml b/elevation_mapping_cupy/config/core/plugin_config.yaml new file mode 100644 index 00000000..7eb62c4c --- /dev/null +++ b/elevation_mapping_cupy/config/core/plugin_config.yaml @@ -0,0 +1,28 @@ +# Settings of the plugins. (The plugins should be stored in script/plugins) + +# min_filter fills in minimum value around the invalid cell. +min_filter: + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations +# Apply smoothing. +smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" +# Apply inpainting using opencv +inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns +# Apply smoothing for inpainted layer \ No newline at end of file diff --git a/elevation_mapping_cupy/config/weights.dat b/elevation_mapping_cupy/config/core/weights.dat similarity index 100% rename from elevation_mapping_cupy/config/weights.dat rename to elevation_mapping_cupy/config/core/weights.dat diff --git a/elevation_mapping_cupy/config/image_semantic_sensor_parameter.yaml b/elevation_mapping_cupy/config/image_semantic_sensor_parameter.yaml deleted file mode 100644 index 5965c88a..00000000 --- a/elevation_mapping_cupy/config/image_semantic_sensor_parameter.yaml +++ /dev/null @@ -1,24 +0,0 @@ -subscribers: -# sensor_name: -# channels: ['feat_0','feat_1'] -# fusion: ['average','average'] -# topic_name: '/elevation_mapping/pointcloud_semantic' - front_cam: - channels: [ 'grass','tree',"person" ] - fusion: [ 'exponential','exponential','exponential' ] - topic_name_camera: '/elevation_mapping/semantic_front' - topic_name_camera_info: '/camera/depth/camera_info' - data_type: image - - color_cam: # for color camera - channels: ['rgb'] - fusion: ['color'] - topic_name_camera: '/camera/rgb/image_raw' - topic_name_camera_info: '/camera/depth/camera_info' - data_type: image - - pointcloud: - channels: [] - fusion: [] - topic_name: '/camera/depth/points' - data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/config/semantic_parameters.yaml b/elevation_mapping_cupy/config/semantic_parameters.yaml deleted file mode 100644 index b4eae18c..00000000 --- a/elevation_mapping_cupy/config/semantic_parameters.yaml +++ /dev/null @@ -1,94 +0,0 @@ -#### Basic parameters ######## -resolution: 0.04 # resolution in m. -map_length: 8.0 # map's size in m. -sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). -mahalanobis_thresh: 2.0 # points outside this distance is outlier. -outlier_variance: 0.01 # if point is outlier, add this value to the cell. -drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. -max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) -drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation -time_variance: 0.0001 # add this value when update_variance is called. -max_variance: 100.0 # maximum variance for each cell. -initial_variance: 1000.0 # initial variance for each cell. -traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. -dilation_size: 3 # dilation filter size before traversability filter. -wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. -min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. -position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. -orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. -position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -min_valid_distance: 0.5 # points with shorter distance will be filtered out. -max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. -ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -update_variance_fps: 5.0 # fps for updating variance. -update_pose_fps: 10.0 # fps for updating pose and shift the center of map. -time_interval: 0.1 # Time layer is updated with this interval. -map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. -publish_statistics_fps: 1.0 # Publish statistics topic in this fps. - -max_ray_length: 10.0 # maximum length for ray tracing. -cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. -cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. - -safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. -safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. -max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. - -overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) -overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - -map_frame: 'odom' # The map frame where the odometry source uses. -base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'odom' - -#### Feature toggles ######## -enable_edge_sharpen: true -enable_visibility_cleanup: true -enable_drift_compensation: true -enable_overlap_clearance: true -enable_pointcloud_publishing: false -enable_drift_corrected_TF_publishing: false -enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. - -#### Traversability filter ######## -use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. -weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter - -#### Upper bound ######## -use_only_above_for_upper_bound: false - -#### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/plugin_config.yaml' - -#### Subscribers ######## - - -#### Publishers ######## -# topic_name: -# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names -# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. -# fps: # Publish rate. Use smaller value than `map_acquire_fps`. -publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb','sem_fil'] - basic_layers: ['elevation'] - fps: 5.0 -# elevation_map_recordable: -# layers: ['elevation', 'traversability'] -# basic_layers: ['elevation', 'traversability'] -# fps: 2.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','sem_fil'] - basic_layers: ['min_filter'] - fps: 3.0 - -#### Initializer ######## -initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. -dilation_size_initialize: 5 # dilation size after the init. -initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. -use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/sensor_parameter.yaml b/elevation_mapping_cupy/config/sensor_parameter.yaml deleted file mode 100644 index 3aa14712..00000000 --- a/elevation_mapping_cupy/config/sensor_parameter.yaml +++ /dev/null @@ -1,15 +0,0 @@ -subscribers: -# sensor_name: -# channels: ['feat_0','feat_1'] -# fusion: ['average','average'] -# topic_name: '/elevation_mapping/pointcloud_semantic' - front_cam: - channels: ['rgb' ] - fusion: [ 'color'] - topic_name: '/elevation_mapping/pointcloud_semantic' - data_type: pointcloud - - cam_info_topic: "/camera/depth/camera_info" - image_topic: "/camera/rgb/image_raw" - depth_topic: "/camera/depth/image_raw" - cam_frame: "camera_rgb_optical_frame" diff --git a/elevation_mapping_cupy/config/anymal_parameters.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml similarity index 100% rename from elevation_mapping_cupy/config/anymal_parameters.yaml rename to elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml diff --git a/elevation_mapping_cupy/config/anymal_plugin_config.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_plugin_config.yaml similarity index 100% rename from elevation_mapping_cupy/config/anymal_plugin_config.yaml rename to elevation_mapping_cupy/config/setups/anymal/anymal_plugin_config.yaml diff --git a/elevation_mapping_cupy/config/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml similarity index 100% rename from elevation_mapping_cupy/config/anymal_sensor_parameter.yaml rename to elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml diff --git a/elevation_mapping_cupy/config/features_parameters.yaml b/elevation_mapping_cupy/config/setups/features/features_parameters.yaml similarity index 100% rename from elevation_mapping_cupy/config/features_parameters.yaml rename to elevation_mapping_cupy/config/setups/features/features_parameters.yaml diff --git a/elevation_mapping_cupy/config/features_plugin_config.yaml b/elevation_mapping_cupy/config/setups/features/features_plugin_config.yaml similarity index 100% rename from elevation_mapping_cupy/config/features_plugin_config.yaml rename to elevation_mapping_cupy/config/setups/features/features_plugin_config.yaml diff --git a/elevation_mapping_cupy/config/features_semantics.yaml b/elevation_mapping_cupy/config/setups/features/features_semantics.yaml similarity index 100% rename from elevation_mapping_cupy/config/features_semantics.yaml rename to elevation_mapping_cupy/config/setups/features/features_semantics.yaml diff --git a/elevation_mapping_cupy/config/features_sensor_parameter.yaml b/elevation_mapping_cupy/config/setups/features/features_sensor_parameter.yaml similarity index 100% rename from elevation_mapping_cupy/config/features_sensor_parameter.yaml rename to elevation_mapping_cupy/config/setups/features/features_sensor_parameter.yaml diff --git a/elevation_mapping_cupy/config/image_semantics.yaml b/elevation_mapping_cupy/config/setups/features/image_semantics.yaml similarity index 100% rename from elevation_mapping_cupy/config/image_semantics.yaml rename to elevation_mapping_cupy/config/setups/features/image_semantics.yaml diff --git a/elevation_mapping_cupy/config/plugin_config.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/plugin_config.yaml similarity index 100% rename from elevation_mapping_cupy/config/plugin_config.yaml rename to elevation_mapping_cupy/config/setups/turtle_bot/plugin_config.yaml diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_image_semantics.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_image_semantics.yaml new file mode 100644 index 00000000..d4451a5d --- /dev/null +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_image_semantics.yaml @@ -0,0 +1,57 @@ +#### Plugins ######## +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/turtle_bot/plugin_config.yaml' + +#### Subscribers ######## +subscribers: +# sensor_name: +# channels: ['feat_0','feat_1'] +# fusion: ['average','average'] +# topic_name: '/elevation_mapping/pointcloud_semantic' + front_cam_2: + channels: [ 'grass','tree',"person" ] + fusion: [ 'exponential','exponential','exponential' ] + topic_name_camera: '/elevation_mapping/semantic_front' + topic_name_camera_info: '/camera/depth/camera_info' + data_type: image + + color_cam: # for color camera + channels: ['rgb'] + fusion: ['color'] + topic_name_camera: '/camera/rgb/image_raw' + topic_name_camera_info: '/camera/depth/camera_info' + data_type: image + + pointcloud: + channels: [] + fusion: [] + topic_name: '/camera/depth/points' + data_type: pointcloud + + front_cam: + channels: ['grass','tree',"person"] + fusion: ['exponential','exponential','exponential'] + topic_name_camera: '/elevation_mapping/semantic_front' + topic_name_camera_info: '/camera/depth/camera_info' + data_type: image + + semantic_segmentation: True + # segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large + segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large + show_label_legend: False + image_topic: "/camera/rgb/image_raw" + image_info_topic: "/camera/depth/camera_info" + resize: 0.5 + + sem_seg_topic: "/elevation_mapping/semantic_front" + sem_seg_image_topic: "/elevation_mapping/semantic_image_front" + +#### Publishers ######## +publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb','sem_fil'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','sem_fil'] + basic_layers: ['min_filter'] + fps: 3.0 \ No newline at end of file diff --git a/elevation_mapping_cupy/config/semantic_sensor_parameter.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml similarity index 56% rename from elevation_mapping_cupy/config/semantic_sensor_parameter.yaml rename to elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml index 11a8de8e..4cffcde2 100644 --- a/elevation_mapping_cupy/config/semantic_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml @@ -1,8 +1,8 @@ +#### Plugins ######## +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/turtle_bot/plugin_config.yaml' + +#### Subscribers ######## subscribers: -# sensor_name: -# channels: ['feat_0','feat_1'] -# fusion: ['average','average'] -# topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: channels: ['rgb', 'grass','tree',"person" ] fusion: [ 'color','class_average','class_average','class_average' ] @@ -17,3 +17,15 @@ subscribers: image_topic: "/camera/rgb/image_raw" depth_topic: "/camera/depth/image_raw" cam_frame: "camera_rgb_optical_frame" + + +#### Publishers ######## +publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb','sem_fil'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','sem_fil'] + basic_layers: ['min_filter'] + fps: 3.0 \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml new file mode 100644 index 00000000..cfa3b3cb --- /dev/null +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml @@ -0,0 +1,20 @@ +subscribers: +# sensor_name: +# channels: ['feat_0','feat_1'] +# fusion: ['average','average'] +# topic_name: '/elevation_mapping/pointcloud_semantic' + front_cam: + channels: ['rgb' ] + fusion: [ 'color'] + topic_name: '/camera/depth/points' + data_type: pointcloud + +publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + basic_layers: ['min_filter'] + fps: 3.0 \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_example.launch b/elevation_mapping_cupy/launch/turtlesim_example.launch index d672f6de..068a2962 100644 --- a/elevation_mapping_cupy/launch/turtlesim_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_example.launch @@ -6,14 +6,9 @@ - - - - - - + + diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch index 6fc21735..d071ddbb 100644 --- a/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch @@ -8,11 +8,11 @@ - + - - + + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch index 17eb97c3..1f680224 100644 --- a/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch @@ -9,11 +9,14 @@ - + + - - + + + + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch new file mode 100644 index 00000000..d672f6de --- /dev/null +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index bde7ce93..c76bff7b 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -287,7 +287,7 @@ def compile_image_kernels(self): for config in self.param.subscriber_cfg.values(): if config["data_type"] == "image": self.valid_correspondence = cp.asarray( - np.zeros((self.cell_n, self.cell_n), dtype=np.bool), dtype=np.bool + np.zeros((self.cell_n, self.cell_n), dtype=np.bool_), dtype=np.bool_ ) self.uv_correspondence = cp.asarray( np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py index 6ee22a94..8c0934e1 100755 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py @@ -6,6 +6,9 @@ import numpy as np import cupy as cp import cv2 + +np.float = np.float64 # temp fix for following import suggested at https://github.com/eric-wieser/ros_numpy/issues/37 +np.bool = np.bool_ import ros_numpy import matplotlib.pyplot as plt from skimage.io import imshow From e6de165303586de2ff2c459ae51148bfe56fb9c1 Mon Sep 17 00:00:00 2001 From: Lucas Walter Date: Fri, 25 Aug 2023 16:00:25 -0700 Subject: [PATCH 366/504] make parameter.py dataclass work with python 3.11 --- .../script/elevation_mapping_cupy/parameter.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 0e79622a..fe062a6f 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -2,7 +2,7 @@ # Copyright (c) 2022, Takahiro Miki. All rights reserved. # Licensed under the MIT license. See LICENSE file in the project root for details. # -from dataclasses import dataclass +from dataclasses import dataclass, field import pickle import numpy as np import os @@ -64,10 +64,10 @@ class Parameter: initial_variance: float = 10.0 initialized_variance: float = 10.0 - w1: np.ndarray = np.zeros((4, 1, 3, 3)) - w2: np.ndarray = np.zeros((4, 1, 3, 3)) - w3: np.ndarray = np.zeros((4, 1, 3, 3)) - w_out: np.ndarray = np.zeros((1, 12, 1, 1)) + w1: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) + w2: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) + w3: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) + w_out: np.ndarray = field(default_factory=lambda: np.zeros((1, 12, 1, 1))) def load_weights(self, filename): with open(filename, "rb") as file: From 7ae6c0b07e2c152d8ea4b44a273bc7178bbe3ab3 Mon Sep 17 00:00:00 2001 From: Takahiro Miki Date: Tue, 3 Oct 2023 03:43:04 +0200 Subject: [PATCH 367/504] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 65eee4be..44f83509 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,10 @@ terrain can be efficiently generated. ![screenshot](doc/main_repo.png) ![gif](doc/convex_approximation.gif) -Large update is coming soon. Stay tuned. +## MEM: Multi-Modal Elevation Mapping +We are preparing for merging the extended map with multi-modal layers such as semantics. +If you want to use the feature now, please checkout 'refactor/semantic_layers' branch. +Also check this [paper](https://arxiv.org/abs/2309.16818) about the new extention. ## Citing From cd0024349843bb141c2fa4e2d49ec731ee6f64af Mon Sep 17 00:00:00 2001 From: Takahiro Miki Date: Tue, 3 Oct 2023 03:45:05 +0200 Subject: [PATCH 368/504] Add files via upload Added an overview image --- doc/overview.png | Bin 0 -> 1371047 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/overview.png diff --git a/doc/overview.png b/doc/overview.png new file mode 100644 index 0000000000000000000000000000000000000000..94d9d0b596f5c9a18a592726a872666f5f5256cf GIT binary patch literal 1371047 zcmd>mg;$kr^d%N3=_RB?LZrJ>X;3<(rMtNxtso^O-6h@94bt7+otKbq?mYPYX04g| z7v^24tP5{H=bU}^-p4?BSqU^`0%QaP1T-m0QAGpJgdMzFKi{% z!G~Jn4}TtEM~S=xAL2WTeR5Q?F?Mv;vo}I;c6Meov$k+B(6cpSw6QlyJm4olKp;bq z5`CxqWp;1D`3v^MHPT<_sw|s`kJLDr8qXPgbsj&J7k*Y8z`l|H{0HvKGv~%1pHID` zQD{H6_@QyURm{R7JN^0e`6ETCucvi1^)sv|HwLX`mQGw&W6L)#U%tGlXDeshO5))w zKcqqJvU>_H>i^u{JpcLseq>BmhW>y43If7sbaL4L{RzV6|8Kt(n#&+$X>bwp-j6EO zh{rF$0FPY%C(^@H8E#=|w<8h}ZMS_)9-~(w-6F%o^xBAEr_~olwB0UAm~5FlbdB4u z#pl0A=(xEh>bF8_bqV)rg{MZTpMkt4xcAjBM`T zo4Qt`diQmx&g%^sLmNx((?{Si%T0CZCfxc`{V#A0n?#95*GOn+Xr!|ujMVv`{X5Ga zA0LbgtZ>CVB0+a<%*+;Q3E%hWsn!Sx1G)BrZ|Ug^Lj)_%%nOEmIDZQF*|nz`@ILG| zzjbk3=!bPrx37!wh4rt;*u%LH5WWUnUdnv=!X42n{Qmvp_d5um-?{6abLQG;QkC7S z49Tg-tbDkbho}ebdF*$btG*{ppB4|kMSR#Z^n*&?=%l&1Of*L=hepxlHZKvR&GvDT ztzPF7F6rB=ldY?x8hPb^r&+$AY*6TB(c(W`?}=1ZRYiM~CQSA+P!zT8`P0YWguf~x z{rzg79%G~)y2eg`)>no$S&i)b>r5Q2)Yi~LWEk;v>Df&#itqcJ#lZtTlHw=x#PvM0 zuG8s64@Vc?s*j#3o2V}6D~`t2dHc3bUf!i(w40bSTycQ0zI5-M2?OGGcMl~nG_ z;d(8`u;5_PcMsu>@byN-)z#I-g$Hs}?!#3h*ky-djC($oBNx=6uQU|)K7DxhVbh?0 z1wKfZ5BT*ALENlTqf(WZ~Pas zBt(IMfka)U^cI_eJKuhkB*t@mAP=9OnVFfL{n3Fphlh|LQlvUHKCY~$R-jC)1pDNK z?9?YZ$#r%c^~tZ+`O-P;`B2l)MdTS&r0L;S|9Au&)HW#9(j+oP>o9SADLD7sYq0hd zvB=V32x%FnN~ zn&o&)60cMO*0`yubJEhtqW&jId4P4!!NDP3|NCUjcpr8cXJ=_%G5COjmrO#WV2vzx?%Z$Ue)# zFu?2V>5-z1PDoWnMM&G=4vp;F02|^v+agsy)8VvN2Mt%@XLxV2x!=Z~zTYmsTkvaO zo1bh$cX@~o1dKB86BiS;6vY^tGn)p!!wOiopI3GFlNS#^MELWhW4vMQVqhJ1M*7;y z%F2i}UXt?t!4u)c5mWZ8tSkfX9xqb5TE#*)v2NR;9L9Yu69^%pg^i7Fv&^HuG6)3HZS?PSUpIN250WG)^GVZ6 zOG{s%qaQSE84X*55Ui=GnVv}(d4o_9w!6C<5rKKvGo^{AWn*l3*GH0CR=59jd@J75 zBLx<;_wS^`Beaz{i`*&Bv}%V`2fqEXSXx4E=Y=DT&-C>4y0!j0TTH={S2D(oC#yQypC_naQ^+?AH|4>hzbp>yD2{HL}Q;E zNhBmBTwL6BCIrWq9UUEDfijdBClaZ{^I_D5l7AEyR6TIfwgs9oj-Nd2|L3i0k-$-J zskeiRv-KaTw+wEAo+=W8#u<80aJB!=U`mD9*w}*^`KX%8r*?vvm^e8(IlKsAI6W%% zVS_b~29wq&a57w1H#SWKNaCtuBrQJCgZ|ssfoooWb8vS2p35 zx|$gse!c}K6-o@6JAQM?zxTl|Y{^7&e*ZSS=+i~-);mJp&Gbo(g1PBwR3h$|@z4KV z$Z-DdP|+ZB@Cc-X7u)A=b9s5WGOd{PW8p5!Xz4Q_7*Q7oN6q5*?rSw|p%D&V%()={ zd*@7HdSQ}(yR&z<481;$e!h^3+UC*WJ~4t`=IIsC-`~Hy{Q18yLl7o>j`FavZ8t22 z`@pt_Qm07U7e^j8$klTM;&^4+2^)lVJ1s>;#WgOQ_oiBO#@n*~XH6(b)6i0h-G8rx zUGdL)af(R&_(COC4w|B4ZkvpxBy-#Z6Ft3UXE1&@_rI(8TBY24;>y-ZXZ-}1QS0UN zgU-0Uy*=jV{0NT7tnvMWgR&Pn;u&V{gxQ_qlg-a>*9Z4@DPc4yNsGig|Dew>WqQeX zl%nrYFXmH~FOEn&zb`Mp-047wy7ct_dvRaS_5X@?+G!!})fO*tYm$f8)YXx%A*7Yt zLZLW89cLEhh#Z_{gFBV{1i$%{Agq#(4_Ef}P3eW*wqV9oGM}Zm(&B6Jo`NOKMo*0Y z0v^Fs=FH!>MCh9u->6OM0CR9+qGsfKB?N^10?&@=SG%Anl|p?Oa1{^l!z zyTurV5%F3=#B`i*QAiQeA_=gF>F6V|`XG=OJbnfNYXO(Ic;w`MPf;Ndw=IT8cI_{_ zUP?Unqj)4^4k?IvzAE?yd*{XQ7qBv~!z@wTC@Co&e@bxP)xU}VkPW+jfiSEtNr{Pz z8@sxye=iqfM5uDZu}O0jlqOfhSGm4@X29>~_|E>n7b-VecR9XPeA1`!=wkFNYadD( z%c!kbFyWkvmO!Y=HNlbY0-@(gyjVrsAydd6@>g`Jul-g6uznY+l9BV)tSBhIKoF;*q{MSKsJhwH zzCQA_u&|JmlQUG3I9Ur5>g?!%jEu<%30O`u`|Qm%xUfOc2-vr0Oj5-(CYs-ASD1pw zP`+Wd$z`o0)j@w{Zoj7nN~45b@#t_hRa=4&sfH2Ii-t%*19`6IT^Dc)W-Zg{^6&N!fUvl zKSKi6a*#Iy0xYH8e^?k#Pdb24;?G_U>hOfVUd8+N)gZ8wVFprpIv7N`9H8Z3;RW|V zWJO8K5Kzg=$$>d%fGkmT7f3CeG~MLE2MHAY#bGfSAo@$(`f@~q6x1om$Zx$i60h4M zr2J{E8rzjHp?k7l3K`<~qLVg@4L!{rW%T5*vr_uLoUoDZ>r#WR%Qq-;0%yudVTDUg z9*IH_-}m3T>+o6Q>6w`1)W)(iGoK0 z!k9%v1yC`Fs?(FBg4ug!OiavExFKHWZKTNDb|%}2-lgeRSv#xMW6=flzhs0byVl}u z$e)T2rnD_yK!*v!4_7-_M6+}va*g-^2G>{r762_1s-wkJe}R$q`}gm1lc8PzNG7eC z;n0Q2zP>)F?g2VFI%Z&IrO?RI5

a}~*)gv)xqJrIkqTt!xPP=eH>-G;+#H1noV zx#4V56CeyxY>>qf+3;*y+s*mu~jhdjq)&#dsb! zj`QLH`Gl-@nY5#Li$dKvw2^CkFjGBF964-&>C>DT0d)wQ*@ zwzj!@Nqv3&Iw&l=p32tV-aLrfRH#|6&F_fV*X!bC1p3 z%EzSwJv!Z-FjCb|&uDBPkzF;lp{k7BzUP?^5F>vCnVAc~Cr|%bTAF_ouHI*loaGl_ zKA{oqNA-&!tFBC3TOlh#tzdm3|A%>Wg9cTJf{OA4XT}dB?$rQ1KXwhN@zLaV+a%TH z)%;rzoL_ska1;!TX4@6-Jd-+3EIhp2`giuWwx;E6aRP3fr0Pq}US3jCfk8nsKF)T{ zcjtu7{0^HR?qW7D0=SmkPqJcl$jLDq%wE4(N-KF%f$|;pbLXq2tMD=*QX1NKrrX}0*~pU4?;j!$8J<1v zlre^Fm~XuC zdAYgrdCDLcb)5_e*?8VXQp*{en4I*1XXK6`6O{O{5f&2!!A7%WOn8*}`07DhV5m+Z zm8Ga%4Lu>)D=)5dBSyEC=ygKg@ya~XgPL)5DZmLWU}iz=EDg>jsy%FU0g`0cWE{cy zy~WB=v;mR@t%uU!$rQCh({2WQW<=XD=VDUbu20SG%>I6g2?+==oser!Ye7J`AO%H+ zxTSpx-E;zZwYz6FL+Wlc%PB(G#!QXLY>IL84`b-P4!Y`Ul{Jj!)eHB9eUAmSdI#)i zI#!1b_1fcpEf?eBTUEVi@wtF{Bfp3Dml1RDIe^=br{Z2A>SYbQKaPds_3L+VSWO7E z*3==pjfF*l(3zV>c~zC?UTN2*de%d%B2vIKtF1S1{ZR2o8{M3-Nf4OjC^131r>drQ zQV9d?^v64`N#TwzpeoO^L}bhIaZW@X!Mh`(&e|J-UjiJ!9gN6F5 z4fS&43EkI%g7+oO_dkMy=m33@pKot(zdKPdC4wQq?sjfzVbMllzt$N-MMWiA@#RP# zV2}Cv`Bbm_E09QQYiq%6wfSRAi5-EG@bDlhBtkPYGnG|TSWwqi|7}}axDd$E-!_b! z>uUmmWl-FSxowxn^OW-P@<6F12mzfQ4KuUtc&@_9=70kfI-z@Ycd?|Fr_95{bDJu3 z`?oEeLgG~I%jJqc1v$CX!F&&Hbe>WUIuZA8{1++F(KuLGScHUbVCNq{kUlC;<9YgdV$5SiT;`#D-8SF4RI!a4Rd+D$@lF`*2PO&wZY~lFD%O`56yL-CKNXF9A zQb&iRjk&3*2?LyzZHS*DvS-)E?e_9$dioPN0gHb7bg6-bxw+@fes%NxH60sUd0E-$ zz<|~EaJrn(og*7Tw&hG26&qV*K#I#IzL%Gml3MRdoBzfBob$na?XO?IK#~H@n4H|u z&!0cRC5GU$W#6AZ1qbz3HJ&Wryb8TpTXdI+(nF|6V}> z(pPqHaPR~P-F-b=;?2hd!+gK1%|sjPrKSOD@31gAGqar`A$S9LD~Vh-ljGxGTwKry zIrn^Vb(qI;sTdip=c=p#8B%Stq)Hnd8X5{v{=z~dAO{RUSHNR$sL44$Qd(WTMFBH( z>I^|lz_UTV7LB!qb02>nR<+Dqqia;O-=6WfJ&xKBn{m~vF$+(W^_?GA=83?FXu@2jv@i^45`(b+~ zLq;nf3<1zn-=8FYqCc1_(d~1dTQ1=V*_kp8PyQ6s@;aX9YiG&Kx&KGJh3or)=j$91 zxgkm=_#6&Mg>#R1OQ=%yb|z~C<9U^G4)Z5#{0&{(=a(elw1L@jB}S6fB^(ga*ivVP|*GI z3^o2UuEJDJd$R5({T{pI(5~%GB`pG3g7=e7B2(9Jy4^FA90e z=%j*LT(%w_oSdA8jTejawGPmd%d4xS6Zgd9`7>1jjoYa8rNI5}p6R1~aeV5Um^ce!Y6=JrX8&@R5hi%O?1K?tdUd=3 zK<_0WB9)Ys&?X_zp9Z~R_z@b)`L;)+C?+*Y=PmXtY-~JB4(RT9O$|5sEC9iOSK45y zveMGM5mYjOTlkQC2<{2I-4b{&s7>HHddmv)_;x|o0+3NcRTWxZLI3IZ=bQ6=<5Bm$ z>C$HS{mqgWT)<|LpFDxx40DOLLm1#tQ1(bkNo^ddpCF=MUc*YBJbt{}%%Ru%RIs?& zW=XJ8qw#Z#_wB8_4^)(V1faRy*vN#01n>s+hEfEKL*f3Uo^kAX#N^IIT?-8^O0ke^ z0-XQ?*Qc0&_iqc6ix}`!{Z+G6%wbK7h2j4gAL1yViv|20ZUw?SlGm7lrv`YhUKDVN z!_Wxk8-7-0d0SsXKq5LjpR>VI`0$~>H=3?Pe+}|e z*Xu4?H;xyY@A>KOe1C2%`{SBVrRX?VpPqNuGt<-9*w{ouo(*MX$Ka>%%Pt{+mi^EO zRlTaa!bl&Ag?db7Y3a^Vb2A`z7!%?mB3PXdw4$ZOL;*<+3d!m5vAvU1ac*w+;9wJ| zJ?iT5BO(*#mF}Ok>0g0F?|itpFfyW0q-tVfk}BY)nx{;Q{llm)=7sNj?eAr}&7R1< zgd?m+EN3Am3oI5x<=7v+b(9{cOi*9<$Towkn0Ci1PT=MF69d(DHAxY5=I2}=Bk-^c@x%ZzJC1* zYSir9Tux37DWB7aEJYk#+@WMXXOKM+_g^~#yl*m)5S^TCWnuzaByLjDRItFOr>DKW zAIBJRS??cx-uQp6WyG_x|sVn`eK=M8YD%fq@*I>d<4<1_W5&KUb0rL z{YFvsVt!tpoxMFW21cxOmang`$xw<)!305w@l2VKfa@u9fE>(!!tHc>1fX`$cJJ2K z)&g)t^-e{^hkx+>O3TZ~IFea7$lQGzcVM!@mP^?zv;F%!zJbp~L8q41XL~qXHao6c zvMA_Oke%jNG@((e?)KgF+=a1y@Wxtgwl}GFyoly%>o{5rS+-5RR^1tYl4||xk?Npo zwqO>22U-3IpeS*H8OX$oj9Y)I>)ooTDd8yk3=f2foKp=X`U3DxnKWC!asjO1~k z9>Hek!XS^Wh>A|E=)^M>6V;S)-FI&xqJ?;~-R#Xr&Z_r2TI9zh8*7Bnp&C-qXR7nD z1xUWy8(r(saX0Ikk5-7MP*WL4rh0FtCXs6ADPVH;3a`)9#aOKOqDRzl%WBD4&ujH9 zc)sUL@yAKhf_6l=S)N#r>xQ;_o`=l0MCmfspF1E!r0RJQ;cV^7M||bGl)CDup(NQd zqu;|;10_|mR&{GH)xEnnQ-1vFiflA&VXW~5I-Ke2(zXRc%Xf+W6`tpN>USd*mnQeB zqvO+3CPa*v_js!{_%q|(&sFCtvP`ei7rk6&JIzdI8mzM(&$Nn^b>|Yk;#o!%%Bmd8 zWPqJl(V*_9WFl+|K!}wz$o25_1NtS#t%}4TjRJ^gPGQ^ouOl@C$adCDZ8%(oV@ICU z(I<}_YRJyiMzuQ7Jj>(i8<;dO?34Z#vrmTRX4=Lc#Zn`5u#M+e>$syx$euU}e_v5r zY8H!?%HyyJfc1nq)XwfGUBsWn^K#`H_V-A`)8%|`rfzD&{H%OPun$Dh+3p$O#&*KO zbrckiK*8#2Zy%qWWYnr*W@H>38L{Qw3b?;J^lCmGm8rvi%gFfV7Zf&m6gI7t zBYStb7M7fpbjmeuUI}uspyT$>k;vVpX813$pf|EfZ=)BnqG;&oG%L+??d;USM?gM2OSE&p-pM&^h6A~d zPPGt^|BEd^0|ezmfFtrn!Ih0;Zb^d(OG))4+BDT#&2f^u?pIEAhJpGU^KGI)jSaON zl#;C!H(6(9pr--FtJ(dkOfgTZ;ftM?R?>+66(9`rCw6mlb3+KZb~}?m9{>k83UZ{V zsIKRgk+Sl59E*WQiX)fJqWk%b$<=RHkkBTJG);!{8Y?Os0U7}536Zd_zP=eC-LagC zM0_Av{O1LbpbLIAyerlL{GemU|32i(x7QoT0Bru3d*d^S{Z zADf@z8R~$a{Pzg1z;0(ZcOb#Cn8PX`rw`n4-iYb1j0{}*Ph{be zm$)|bH7pjBg%uU-O%tu4Wy;eO;^B$MDB$DewVo-<@*Ei$8iMavF9nDGUE&1ohhsQY z2?HgBI7er`ig*$Q3&kFNo{YSUj5;v+^7IF{*wKQNBla^6uKU3TD80#gSGfBvpM`U$ zFUC+Qt*TdY@cvG9*b>Q!OO#J)IN4FS7*bFqYEX%4R?%Ql{$Nork8PWC5`0;uZP(uz z#@Nt1i`5qvt;JZU$)uLoH`doX)>r0af(rlac+^3DkDcV!8!SF4qa;1lxP)!%@>&iH)+Pbj$|ww9PtesGP#Q$G(UWk zAf8^_0KQ%i&Bl*7I2|@Iq36PBj){1@bga`!v`Nu;&pHF$BE#3*`srjWt|o|XGhd@z zC+pzHy4_9+X}Y7m#j!EkOpQ=(lkpq_G!6cj3ea~@ z?W-Ls*pcW^%~WVKB`%Cw)=XLod`+hGE5JIZYY05`ls8n56YJ4!+3?k=SEuxzI#a+b z8BBhX)l#D(nH`aA_;dqPfNTDdfRL~iEDP@<^#dr_m>+j}ms z+)29YqqL~Ogf@2(JX@_PGDl>)CX~zIP?QIC^QT26W|MmK1?#?2iEbHBT;G!xN=P>{ z{BmgINxkUlag7k7n+?gguP@MlK11r>l-rF~Q}m!`;o>}Ux-LS-iiUWZ(BoA*=6ub7 zFa{Q=7QGMmk)@`m|KRoEQq_u68(xs4hqsVBZq*MO-1!>2+fN68AmJcTU#f%BdF9^U z-#>7njZH>V7HEeJ17WA@!M%bUPEw8I{ zg-sSQHC^gk}I1iACi;D}uuRi{fbS*6jy?JBY9smKYI7mt$ zp6^hY8a_MDfi?%U^kU7!(v%U-i!M1eHJ2AlUev#~w@rgYCzo8dl1E1s@2AfX7Bs#7 zBE)|<-zy)QT>4v3(!}a&L5mrf;<`%{D0)09!vq=G97w$CcJ13=Y`g(ok^9OmXv|Pu zjl)O;u48pQFJt`#nx=;A8&%`is@C`?`~>- zeR^$IaZE7TVe|eg41r7hEgAX8kT(bL&(m)0ALnjA0D9|<+9a~Up_t17Qg<~x9c6ng<+EFeo`}%p$ zgZd+wEoZ!2NZs2Y-k~eQQd=tKz0xSG>zv1hBkG&8Qgk4(M-sH8 zs@3*o$APD4NsEnrZ%I9EAFH+sFU7B%@iz=Ml+}EV_In%d`&265dz||E0C@MFF5NBHf9X3y$!i^Q zO^8>y+s=vTUEJvcQDN>z+wLSICpc`K?9MCh#(H?0cCuUVrE$ZL)`V#){{kD8T^pk< zvn|ZkUA#|Ih93;+M&-!wQ+-iNV}jiFO%>jM6Q;C%VRsaAd=YwDdGvc@iN0RPmGL?% zzDS+Hc{c=$s;A>|_#cO#Y8Ua1k8_^!IF;N?mPpd^osa5Ow(38*XV%Xyt_awrMcUF~ z^*Jq#QD55x1uktv^g0}BekKb8CWGs+r`ZXF)hJI#_>w!FhpZMCcO`z~`I$NKA*`#R zD7AT;O}mz-RI7<|-8g6(h@MuB96jkTic-z}kTxL7Fo$31NDXodxzal*U8$`k>5$hD z+TGnkpbb9`XG6)950NU@@`nC}q4EWjPSCB{#3gRd#s1iUVKtQ>cj$_26nd~mox`dH z(oe_Xoo%_Z0p@M>!_m?ID5#nLiSm&Z{D z?(H#vNkF%&GYk$5-HZj*UBk;4L?Yf(XDA@>0)PSvf>ix4iH{zhXX_X8QM94Oe8;>8 zcGBl}-C&tf-z8&*+xcF2-v)zF7nMv*oR9=C&j?mn{+XD70%GF!7*G?YyA-NL8b%ci zl8%n-O9Q+-JTv_j+aZo1(}2G1xDPa3R-# z<@H?{d#I7y;ERLm+-7UX)6uBWH6~I8mGS(7aVZ$%dP*G?HVP6W#vvz%WVIgX032*m z^(!r1T-68DEt`+-5#6dTst(UT$^XeLRvnx~+;aDTO~?>Nax)}4ubvl8Cklo)A!~*++qzfAq4Hmye1`KhLzyU8|8NSC2eQ88I#6b-SQc_#=8Lx2ERc{UxCYy?uphsH(g7Uczb4FXeZl zB8&Jd%UfSHRe%>^veC}wF6^gtmKA>+?{%`XIht|mJB-2e0qc|0(827GtJ3TiE2!Bg zp~~=9Vz&A@0VUowH3V8L(D)2f)~;ij7|y_Pv)2b>;` z)r2m`jXC8QDa|VC1{F$75~3Q>`txPYc$h>Q@V61@yg}XFl6TgyA_0CkOUptZk%f}> z{RzEfF2Hv=J6`~XAVmD6i`0u=qe2qCu+|lJqU4J5^zofe6`)epxWZ}H zoSk6d=UH8@`2#Nr1pLJ&k9yStz}5neLK#I!jVsgL-o9)Ehs14u1 z!TFy(dqzUy_l**e6l%WDQUsw}+!CC^W`e$?1Gv-ly1H4@f^bkL6K46Dng1Sd^oh3XM%2;y z>Rtlio#J_Irl~oH{;6I=U42J`IWs2*>De>A!B6=soOnr<3$uGF=sASHmmT} zz_)I?uUOdElOc$YK7&AX$+0$pCyR-4g@{c`6tl5ZJrNNwx!C-4FzP2t-g`+gKvq_) zVmelxb=>zFz#Ht#`~&0D!yAM zbT(?dU-&8v@SR>b;or?nyJ<)=kHdAJ$S~r((gl6!o=1E(IgF?;(6T)|HMsJ`j`{7% zF71Rb#vo)QL_ob|==-$m?3y1YVD&#NMs7cQ!cOq9o=Akk05h4&I^8P?QK-bRb6Doi zfYZS{h5-kSBrs2o>-oOsuKZzNx4OaT@NKUZsS^8%9U4h`{P8eic`H{LDi@y=p;yQ} z7t~D#Swu;w)!oQ@nYY4kdwUxz>q!^GN&ucxM_-F7t6;0i=>s%Px_3EgBc_1qpPO&r9r9dg5=jGY4}3Ob z%lVq{06?|j`gGS7mt29Cw4t#PS^`@Q04fga(!gw27d0JS&{|DlA-zwxD-a4kTAhJD z`>3%o76<~Mx`2a-ii>mRP1ys+yTu17GBPsg$B$Da%3;u)TkKbWhTUR}+^ z#KcvZos&b|{HI#YG!vN90Qv^55bRg4j!6yWT|av0fB90A_kenVe+F0>AtPBbu@7DM z?^dAG4WO33Bq14;m^`~t;R-9xk}1z=WMX7otar8no-kQiSuwF^eT&2k^09-rrY8)J z`?DN^_VnSB{T0-B%%2fR4JJ+5dwP1V9q6`CcPIMBH{FHY>YTrZ01Yd!L%&i3unj~c zB!XV|x1epmzq=v)pgY}kTELxwYakI;7?ibo&*VGlwE$oF+73Osjgw^b&#3iEgsTDZh(ucV$&MxHK;cb!mr9gzMT z9yHBm!DXlHQBQmLp?Jgv#PVfr)5Z6RkI(N-bnkweP4_g4JQ;&T)lq!GW4WxI%Tj_YozwEzuErP@(6rGKH~|-<;U$_iOD|2 z0i2QIFekR>1t*VlpmIww8sQ3q<}<;~tk;aYVf9jA(KGJ?G2=R{P@L3%7UjCKx?bF` zeRoUQXJL{7)0+~V!pqj`PODml!cQH7i;&zWs>=Yt$k#~IJw^J zoBif9{XZf28Li~CW1PO}d9{e2M-skwGS0LxKj}Wz+P!1Ojf@Dnp< zzlmks(EhJoP(Ln`dx~>a@dvP9_XTTKMH+EP2qlL)`k-6?U2eHvn2d~w(3sw-3ZM0` zF9mG$QTQ2T-sibsrP=DwNgf}#&@66GnAHm{oWde$3JWV`#csGbh3JMV~tS5Ep^tA6m zPu*?S{<(36+lp(b$5baS zcuV+f$?f7KesP1fR3ts7@EE}h#bRyE&Ek7TPkf2G)+Qp+JT~URazvp}-NIm0FEQ!k z{h%aVsy+kUgLb1U2mBf+NjS*QAb_rvOJJAsitPM=qyy)fUB=PQ{4Ho=vIUy{2O01| zpI_>UUaJ}Zw*iiGwx?&O16Nn8%rMY8_)#)gYk>3nt0yCfw^XFbMNLgDAtAAldqc=+ zxm?dwef}}P8hx)*sbB)F*kPkLx{JguIIM*Ybqt6{U%w)NUk96DVPDxE5VZP}(ymzA zpigM=_H`^he?2{!;|weg-of}g+#SK`u-Ok3`x7s~NBV#N&dtXM*uPz;N|PZH!B(qq z)-*!qw3e1>D8-*d=~UzS@6DI1LEpZ81GM4DM_aPkJ`57ziC=D+(s5&8Wj$VSUfKuY z#5c*DELe7shC9kx*pXCtIb3OdZrvu+TEN)HAzhibT)|&XezP2M49ntp#zElgH!)AF zonBSQIGsnU6tSq+T@ItgRky(%TVkU;i;bbgo$|_ASJdvqb<@qe`q>;lqDb+Eq4|(?#Nh zgvc!L=F>(W{m@Krsuik#oA;Ylvsl4&oWmJr7gA=euAOJy#cFwIb-ZVJh^=tf#@XPv z-!A*@4e2kf>q#ShF=PA(Yc>0-#LpNZMvYx((i%8>C7pv$a$F)Yt%%7O;#f||*l!gH zqeC)|4|J7RUu=J9)ng;B6I28p$vD}fLJat`tt}W5*vGwQbFE2OH8WLUkf5h)6z&mM z2u0R!F9A%QPopkod@E?T+P;rexywcV6VsD7Nn4w_NArf z7HABU?x6pKL>Nh<)BY@2Y(6;H$i7z&;~!nEls|sduKtjL^{v`)?#+l;3-rb^6Rhn7 zjDq^wS`Wa>D<~+O9SW6b*LO-xGQ6Lf70y#m&>i#M$*=)=8eC!nDA|jRZgMI7F2IeY zUH=_ukT0;_0CO0r4BZnNO`fkzX7zoO)wIYwc`s8PB zYoox`+g&!79D723#LCr_6x1;%^cH1gJ%t0opO$TN6uh&g4Q5Kwz$#g83I`H39Mls-P0zZkxTmc+ z$ubfF%p81zCW8Hbh@=cms2Ixi_;z2TB)XD9KtvNyD_m>wuGLO+z@4wS+^1J-TO!eKH8lWTKq%w*E*@9+ zA9J86t2H20*E%5zKnMb|F{jmRR8rChQ6vnK`6{cq{&+Sh-PZbg62D7CKvHrtuv(eq zjY~?50jhD*@$yfZme#IoWbcN(OqQa#Ic+Laad9#5EBTBdSou(tZf$K{z@~=!>uw)aKw*9&4#EKQLSbCWr1e~+2z%8IrYcgj*U#Q5-{{ha5pakF;dwBui z;43DZM~@x>!gUoGJ90-%F|n`=^z}Wjcc{VGmHb;BfP2B{N+|Q&*b$`CP(cw4iI6X@ zmaen;v?>y~B%{6)`we@IeqXLWK7S6#xr^JE_o*Rn+I{k&jazu1R2JfB-_toTls|oA zEVR01YNJ7(%W(C)NMW3~Ij?vfdbk*fWbwf<=auC55c;oZB^0KE8+LXgs~tm_m%r<# zW%qdh3;+)D??_sTgZCBD9&2m;Sd`w_ch${==70lsft63PDk?Hybs(H=3w?L~Zt8#4 zlNhc`jAZbkAm%Cd*Q(l8g497`S_zGM;i}Wx5<9bre5u){tBDwBeHQYQT_RH%gI8U_ zy4Scbo{972^UX@7xKUnqRsTxC!~Oo-wSIg5@b;X|hqGDG>GUh3xCM4793HM@WV(6|CxBrTR-k!YNsx$-k)b zx!J_QV}9brYZFmmAlh> zN^U?a#>L^0gG4W{qq7L2^>PaM2sOPne*b0$_LJDY4g0HN?Rt<77LB`TUOop}CvK3x<}xS_=P0@AboGNZG5L5Z3}vBriw z(H-HzcK2O5fpG_m)9+g(FMv^3WM@+BdQymDl8Klnt-fFc=c$I%?I>{=<9tYkH~KG? zn+Ss1r%#Ega@qCUpL<5wgou|L_FxK{GK5RsABB01>#CE7^WW^1-yYA|G;4qQWZKd- zji|OM(yVMFX{B9p{P0$s?Lia+1lqSPxG+C|>D$o2kCMF$)b~qYo2IKbfR@_G%jA<# z@&Gm{p@(kjgs;~1EPuoi__P5X#?s6WjJHZ$W&i}TxaOvMoZ~N1&kYUP0D+3(LtTo1 z+pagPr0F`JacscB*7m0)rD&%7+h8ZslKgy)M%T(K*3ZNG87zRdZey}sY?v{H^bQQ% z?G}_=8f6rzBy_pQuW%2JcZ{Z6Uy`<`qr zCPa_KA{~UrVK%G`h9fPn?zjY%-HyX)?h|3tRZY- zz}(}Cq<0E=_UID*vc@z|V&gj1JAFBQ0GZNpw2s*K5pTT&?g2@&B~q!lpO*=qvHSPK z7#syTfq4{zX6H|@7Ys?8*>Br${hxi|#mk!yFfXiJi@Ejv?v0+?V!D0jc$l78e!D%A zam$KOBJsby0Ii@Q%}k`9|FhZ=bS3F-ZG8Ze^#>|t4UJh~a8oP%G;&GNGcb_MZMO=V zju0n$Mp{~pW>0};e)I9Sch#+JZCAPGPEO~*e~V_FG?>K027HH2YnC2$rCnaPM-ok8 zC1M{^_~S7!rY0u^kJ_>LoDbMt`PAg)!EBHpFfnq}w1Fn`q;Uc`B!Rub@OL$!W8o*M zaLfL0jliOiBbz+xC6+D^JO)2Wkr#V<%v!vkWmgF}ZVv-o%AVjRo*o()2z(g~&A=~e zAHoR0gv5u z7+75!8yWzwsIIOqE-ns4ZPL7nvu&$PFc}Rzt$!95JwddC9KAo96%-Qk5l|Dro(Bw% z0~k|>TU#bC#he@+lYj*VjKYYB0;?V1@(#g*USC^N0tghCVSy{(fvDPcrS(A%zn}jL zj6oiN87U|zDAB5AH6147`nL)4-lc{J1!VQ#BFbUN|dV)mio(B74^%*=Z zz#c7vxgG$EKrKB0ccrLk4{$YzkSPxf2{8_i`j0zPB};&>sR3&rj9rol@PfJUqqQ!7 zKR-a<00%E<@j=I9Xly(P*jX@XRaf+iNvEH*AKVc+IeCivanGMW!Xe@g;PL=C2KLXh zow2UAwl(0kMkEC|n#+E@8yp~4IUj@oFCU+qtLt(4T|htpko=bV(}AJE^ZsfJH1}$> z(O}8|AFy4Z`@0I{~FL{I{CAf9q=bsLq07A+Vcm*b@9crUp__ZLhoX+l@jZH z-K3uoZE(?6(C%NsQ}Ao8gYVzYiz<6I?p;q7WOG)ZIQ=D<^i75Htz?`iED2e%S9x4W zsr2FRHTyn(gQ#^&|4v1rK*5yJO7i*5#qu?b^7int&}3bRf6>L;CG@yJ%&t0?D;cF9 zchpc0dt}nCa@xoz>2oy`145uylzl-^#H`-vghYv;d%xRZYhRq zx@rM79{o3b^c?eC$O!CtkIg0?zj%v^@QVGoLqJu(Xe5-(T9$L@!wxadLD1-IEojVo z+8&FeZ6CKa!T4kiOD{sbdLS=2W{>)uh_v8%qsX)28bz-HMKP9(pkVezJQ&XojN09U zsnj7BgU&d0Axg@1@c%{(30x2f)y;vZ1v7#sjsu$^qS`7dl>lyo;G6I&06teC_-(n5 zj~+WMFYh%_rrmA!+S^5a^tOx#lkka&?|_apxs+Z|0DGVXz8tLr-+qy5Vk+2lrzU>a z)QGK7_5CxWFag^?IE!dhLPBpfXYSCMNtF>Y}v|jYx-dw@9aShm?RI zN()GLcXx+$NGb>i>Fx#r>28qj?r-tld&l_vB@BhV_t|UBIiFfUZ}R}Of!Q91^`K2G z{Z!ervIuU>6Rh!9O$ix*2g}P_A7pLS*42f+XLxqa(B~0?E&CZCdjJrpJ;}!pAI_h3 zhONXTB=w?W!rQg(N`XtzVBoXi+yy(31?(0r7H?E!J zdh$Nz&)J7;Wr@#XjX3{;wAe^`f-b=~Fg5kMNt1`-)>C$R7Wq6qkqo_SHFEWuBz z_Ac)}0W}vui@@IMe!9_rTRANwC54BJiy2px)u^kh3xp;B!v}wWVjM`!8?4U($xc-%v6$NBOAGU`K(U2livNLIuj)XArh?lyCu9lej=( zF#}XG*h~9IMy8FufaE>wClIiLnn^(gB=fgOe_9KORhNE`IoMu5n-Oqup0VC%5?iO! z326afv%qepoWW-Y^mI}E)WFI}D&Ty)l@b@%-pcSQ0yt`cibKS1O|n$uZpJVME3Sxg zmN57Rc+;NIHgJ)kGMy9|SXl`H+#l52GojKU0-*K;RcNYAuhn5oslLhja1jO$@lUph z4`}(M=~>sudrj?#xJ+Y9OPO~RDQ#BbWXK2s-2wDk;M$IWrhYFNyQ;bx4GrzNm3)?V z{qDCYYkoyW_6Q_y8Nj!|D=cPfdkj`!i|wj76VtEIP~=DbrlvzeM9}rKf@jLZ0|tsp zQ0*tI1~KSY4iAU3`@p9aMYanpV$TrcX0jeAy?dZ79pT46d$RWxz!+LI?8 z1(*}=1Z2qxK=%o20gZl+huu&bH+cMS-A*?EH(pUu0ZRUP*$_YipUn@?y!y(d5?rgb zCCY6etGYFuV2>x3aXSXfe`cP<^Kx(= zZv>QW+Wrv{YaE>O&M>y{U9A-_(TGXfw7_mdUcJ^#h8=!#lJnu1#_F zEQSu#JSIl1PHy8e^u0ffwKK8$I6xfM6 zta$TbjgiN8$g%cBHP`lb2A;wqa!pYo2Z2ZQpWbQ_?rUc;i}2a7>h%O-=XlhGG?#t& z_5NdiaBO%(#&Zz>&eK)8s}o?Sf;Ax-OC;l zqh3Z-tM`VTUhAVljTV+w(gLpMJ9Hiw{eCTEm$C(SaJ{2TU!l~#=&p+*?rKP1aU2WA^aXQY)DiA%su<(cA*Uz8GYYj)70M)jzV8R0J>jCjPyaWIW z5g@?O6mW!x_yRQe&^<)uN8tV1E5Fb`|Agebsz)+fUTF1@XW`c-?G-iUt z($KHM?=_xAU|^>Ve|+hci8drjspZS=fX6br|E>q&$e^S5;l`%ddj`PZh}-%8 ze(7a_$x}g|<$y7D?|&C8L?q=^U;69)F-mv4GaUa<7O(Jtgts3B!)g{jX<*FXPH&Og z_moplFx+|yp|>YTlLJ5Zk?&JnE!o7StQLI~bcidw_ zyT5q3Z60#_y=lP5TR(9XBqI;h02lC3;Qk5^??5O2fyGg$tZ3Gww-tDz7sC>l^!9g> z84AtN0sGl{USa%6AcS`YN#Yk2dg$9|z0Yf`6GJ5N)j68p`odEBqz;?)09MpdGaJA9 zl=0hYI2&Z9+sk}J;;RPINOhf>!dYionueX^=3K~>W7G1h>kE!dyeLL8=dt5*6LMJO zf`oygx)+d~iX~P;>VGjrJTBKs_&l{`)^_nA_9f5hq`{5a-*ZOiUFj#Ii_gs)zvJCv z{yc5(VAQtM6+ArDKu>-3lS9I#dj@}~PiAs8c|eXA^LImw7k-mKQp$xn>o_xqnl@ij zFOxK{jyf?PS-T|YlyWmg|0Hr4o~a0H*1M%vU;Vxw-gCGM$09T}+nQ4>JWpN}g=id( zvBRk=c~Teu-DD|JM} zy0iEE=AM(AFX_JF&knrHmVftUDhglO=b_okMWmvF`O~)DBDS^nVMq5MT>7ds@)XS2u-NcT%J-R}^_$Hd)b-gC>?%$F~+1=mQ zRk$VC7RpFr<0`TK`y3Y$O8?zwdxvl+VypRNF_cD&4LP^HGs|dXagU+P18bM?1J|`T zN==hM;p4u?^?nWi&)oK--lY9eJCQq@-Rd=nQ~>$5oTI)}!18!e!w+!P)@-PM3zY4S z*{;HW&>%0E@kvVDf=5B_Q#X+3@;-LB9y|l{egU**T?5^wD@UjH_xqd;x$SVin7PZ} zE=DZ4T)XuPr%jI=<-jw*3tu#t9$iW0z_hPo5`SR$1=l8{Y>jGkVe4eX+gZ;U5L7Jg zk&|-yvY|Ajm4 z$Y3df80VMwgY$1e&n0AICg62{-p#tb#oqO6ZXvnpyu3^H#(#IkHC8<)>uit;*KO@V z)b`f&zWvSE)vj=h%-8!5#FzXyNRGEh|58Y{MK{A?8fq}Q^ta1|ezAJvhT5)mbVsr? zx)7jdth&)h2|aDtMP78KEC3_6!-!C=QGfjH?QKmBkK~)zuZcikjU_{J(#`5^*M)r1 zVrOf&khm)mjQ4QvSGznvQ`3nD2lK{oxPv~cb&KoyrkW_I;d zn=*L!H&!P(e|1)8&N8W`tEE3(jt2Kmxf5bQ_KW|{IAEyPsQ$NM=e*y?=iAbOZ4Nq=Ic@zCBfaBYwF*((cuY(8;NrM5uN*T) z>Qwh)Tj0P&!mMn)+Rg|0Nr8t=mQ#7G)^$&*+$}RF z?ZgI$crj1whvVudjEJ~Bn$s~YVy8OQ;wOXvyi#&-;Dkt0#R-)P0P1;MNdOIkF7zSH zG2C04anD0}-lNp&sJaEN4Q<$JXvAaeVWYhNO~uzm`x3ILZ#mDU>-jUkLtr#cX0!d> ztTo#k-p9gKqx%xWz7c_$M6g&@@6>a8fF%Llp4Rdxjn|gLHii!EC!xs28)u=gTNj1P z>4k-Ab&=|!cN*lV0S3x0Q1=6ht&PE~F|^8%U;K~^4#OE^6Ge_F@4oVDV3x^rn)+mA zmFYbKOyC&+tafv&FEnFjW(I_a+u0Cr5T<-GOC}hH3}b|x|D~D~0|(`-378fIKq$q- zuM#+jiR*9%JC1bHl5ql%-E}89V6|<#oh_ zqnydzq=#M(d<0-do^{fJ@Bz5p23!Z2#4Z`er=~6&!8;HwaA<06?MxzbF-T$5(HFn0 z?Qjnil>ds+N(FSkd~cphd1#h-x?!S)GX2+EK=KkVnvG67iV|8}T<43EqAy5;qW#Bp zArMaM9_cP76V&o|Z;YwBO(?YqK`FL{AWussa{upViztE=(AG*mV)wg#^cR_+ZyN7+ zlV))7L7mET(!6@3iP^XNQP*t~P?xiN zZy1=Fn{Ri2u{NKN0hFQGo3IL3W@x_E<@_k?ab*>M>d5wlVx__E^eWr+Q0beq&hvW} z4u=PxxlmvE{&9FkCsQIL?t_x0(f!YK6GnmmTZZT!G>zyP`VMVjdma-j?cZNB;+;WA z3mR>ngh&(ayrw#{d@ggO*B?nyJ%j>3#E?``bYuj@;CzYcnoW@Yrt2~qN6TK>ihjPQ z_tenRLI(LdlI7J)>ay={D@_&mbl3VcxOL`*cPwbLGgbg(?3QL`AVUCvWdf^#IN=c@ zo7BENJv{*5^9JZObT276c_fW{55NXT)wDOBEk#8yo*Ux4Q3l8xy%rGNu~`a&F}S(u zvs~8z>(rQRV{Yz#Sic2?9{GE>03QJIQ+oSh7onXcfCo?O`8?zNk>w2y4LC}C1^~Md z;H`Vl;F^U50YS##Di&)&gdI^Z3FkVD)`pT znGwm|TqMUkBw45H$hBEvrWzL~B&A|PzQ*?NDk-;8@&ck;-4wMFJ_in>^gB=swCyhP z?T2%lZ1i}GJN>#ZOz2Ag?(g)5zAWMkpkfRkpCTl*@>N28Vyf*o2SEA*s?KTMw{>YienwEB#n@U61kplU9=8D`d2tU5WQl>Gi%F1-tgg-t^iDv1@ywQ7 zJv1IRFky!+*mk1*$aJ0qMt6%(Q-E*fQq-!qH)cupc+ONhFJNs31c<=ky~y3{2$)mJ z5i0FL0uA6&F1((AOT^s9=4qY$>3T}b=9wS`=}}^^o=^&u* zExKJyer&yJKDuckkLlgp1wkJ0SW;ARFInnVl3VXLfk_Owzn;ShGnLOkcn)~0rXec} z4kKuu=Pub;ljR;z{!5W3mz&+F10fcn0f+zHs;~+bzCZUr&n0nRZvdkVmCF1zZnlWC zGom_G(sOA*eCq(!w47^TmAv{^Q?z(rO8CG6`aU54BYNZc>Juph3X}n&8rh(H0p|Fb z5c-kjZVuKnkhltg$R3!LRFkZF5SQ5a5lcJ+m`?plyocXzadC0I`Bbq1Jfnb^-LvsN zBUT(29BBj!El~I7_podlb_x~f&VGnI6y@Zsegj)F$OHmPLR}3FM2O3RT`z{ubtj;n zE(e&(767*ayzaW-ra^DjHtRK6tnPEaPVTXPFyixg2HswI$q-U!5Q;U(V>xsDhjZi} zIPk$H)&O9AtY_?S`F5(dVL;@xkNR1*0tho0{eeVA^25HI5VASLC-B>i1<8DXdT0c!}m6zgm4!cf?j}?ReP1Iw`Q;&eKf?s8k!}18_2bF+B@l}_WX#~ z+Qb?EXN`cbx*w6S?%a)w{`cX}nEYv8W1QEIZVV{VC93sqIey96^AWuZD*$y5V%tX< zvVWljuH6>AR&Z?qJH==C4a9<(s^+Oah5b3h2d1%YHEkOVne-OmCk@-1D5TnvGN?^ zpnyQ%E_JbCYt!z`X!QvUzp00ZNyf2j)0G5BLRcHkbUp2-Z%n=!vhk)4g!l>^HC4(q zxj^(IbwGCt0T#C`ugh8J1z6)gzisEOYVC$SCK~oD2EnR?td#eX$^RG^;N4F#j85gX z(T(}0cfW=ofG~U$#k(|PXaN>0rrpD{rn%*j)#pYYvvUV9S{O}B9>-vn*L{@pzIwY? zQu!>V+AD0c5=vDN24QeQJVM~T1399#H?h3= z9$WTZeMIS^GZV~rt=Yqn1l$Z%Sm)}~b+z5OfJBa;)dI}lRGquUq`D3V9~_tN{0`}> zJIiE-F&0MZoQ1rFdtE7>R$G>5Gtc`Yd^726^=U;R6cjJu<7p(?hKrObUif`?K!J(f zzQ;lKPlZ1}L4g;Ch1H)hbIJeCNMZ&IESq#6jSM8dj|M_vcZ?P4CwWYWi4;abfC<+wMuAC7NCON;OX<0ny)_o-BaNXTuqs}ylSaQScYZd@(@M67& zlarI}cfg4}#}H`igT4%`@=KrvYAo|y4Z`;i0)tfP^ks5V5}EUi0cgiQgWhjx_GUs& z`M_cv?BYP%F}twf3HEreb>ijimYtTnLpWc}H<#6AUI&#|7mPA!Okt_KkITf++RkZW zdfmq^Mc!tQPBh-1WiR8Cwe=4t3#y)|&Ne?)SFqO|Yyk0HEH4o1R|~5tE*`KA#6tl| zZfL6EvNRt)f3OUC30NTRi{i^mSgK*+$L;U|l;Aq+2fD$DymC`6a{+|j3ajP8nyRll z(-Pn4&8PhCzd(8JZmkEF7ulmO}#8%g{puke^wAiynHV{Zfn@~t<-#3#~Q07zhZ&8)g zt(|w|+{SPkK*On!;T;+t>xVE8%vdT<)i^6zR!vM`hpq4QWQcx{vcf%=*x zE0Wo=!~1>#;wd;49xHTW{wBM5jpeI1<7svqDv>AJETrt6^9l7T4*#_6=j0^bipF&%Y~BzyRB5q(2Lt^H{Dq9^Kx<6f@TWl?*MaYyB# zOOBcnv?U57Q?8e%^fJ z=gP$KXZ6xUfequw!A2bnm84cML9L^yuHSNL`ftsfVP7-Y0{X?K^ch5cf>l|* z+(CtoArsUgLXLcRnD90B&Xss0nb&y#`uMiL&$<(Y;a9}V!+BOkvAOXh)9IX_Vk6ir zOvEbPQM`YJs`j$cEk-cv#+{1P&02m?1pLnxUcnw*crMj;W;5{6?c z$q$nN!IpJI+2Hs)EcL^mMM}n_BF7+IO&0qF6)ZNY7X?MULP1oIn~CSvusf_p)@5d`ZUC@6aa| zY?Lr;0y)h1n?PL4T;=ppdi7`)q3>VGvB2zxM#v#4B*Ta%hC|w9?Xi#S!}W<3U<2E;1(P5IlP~V- z-E`q|u4YNe)$N2ifi&>E(j|BajVC1~!TKKE0S<*V6tbfCbc+u$O?!1cb@lG=9Q5*t z5eTpjEfNd}mhb=ZK4S!6#&`h#Y8se10xp2;3td>44>XO`ak8zBSLdCteJ(RoMIN(_ z-FlB6oi`^h87pnvcd~g&%INa`!z}^`6;oHvhPSrdfnmE#bck+WWBT+p2cwOBY8B18!> zRM{)xY~8)7_hGq_7ap-<3Pe4-X-Xe*6K^^`cPO;V7WQeeAylPv>QqK4><)iD7(B&m zS#D`zs;F4SVClMfyUku&dKkQwmGkXL`DRXPlXGj9DSM&{Q$lMzm&jj^D$9H_uYe-x z{9q~xKJHC8zVTk|kN8xqu~)Qi z3@4i(pWHU8QopHB&ZpJj%iJ_<>D3*l(m(Cdi@Y`0X4cO}fB36-y7cMoVawMm9xN>9 z24a`+z04p&#J!V*24vAt1`7)+6=FxG4cyZtE6VkT9_IO_xe7(<2^~r~SrrI{oTxaq zFGVl|EzCQy4VbO8uQ3c^$umvUYJ1h2i^@%99YO;>#dT0gzZf(a5;>0HdNHsS^`2q+ zI+*1^3jGQx;V58yBiTh+M*l6qPs6QJNr?X0bQldq^OcO1&8Ld{Z8b+^0zHoN!-S{7 zB9ueDm3n8EhR8t^tcuN1=tqWP$7DpO$_$msun44h;i)H^FD}*qRnyjpjDNbt66|rJsDsvJl%q#f+ndO~`+N;RNRw`uEH;R&~9w z&!a;EoeU)y8wG(abvRW+N1&vcJx*?uG&ou-78@J_#F6?=x|C`Wx!x_u?hie-#XSG6 zxlGTWzZ6Hd;~N<;RP^zYl$dOgo|JVwObG2LJv?@lM&!w#dFe$C0V1Xv)6rZVa+ZXC_?KalRGJKoj61(A+6rb z-_9By3SpPB>UIj#6Sw{cR0$v~C?SXUDxp^{R6R+eA_{V!x+`Wzvq0Hf>z+Khyo_ePK)cbV(#5?S#EF?eD<$PFd`-0ac7!X>fRI_3 zt4n)izG~-zQr&Q&i8#FbYsUFzDyfxC(`iTL)dC7PHNLkSe=Kw_7#c(qx6UVFUVLiZ z&Vw5EL03Jizn;}fS7f-0U2V5RqYr(juwYhtHtDwX>ral)xFQe4dQW3-gFJjLe(^5r z5WXO^Iw+bmaAIa28q|1GR#f!Xes=;~-5Mr(Sy9VH@AOFPaYtFEAk!B@onl+P)8k<+ z5A|`6?Z4UkulynNG=3x)B*~xcJMfJhO5ThqX4=x*5n<7Y8NbnGDXoT*S6IzgrM^P! z&s**L>l#-mMy4~qB?%iyj~wI}N+1W@!)K@pYuc6)(mlG%5m2d2G@BQsGqiNG;4)sO z(>$^q5ccK;3;_i!2mA!r3K7-|%2Q|vgQEnjy>u6!VW=>iD7rtp1P%hO-x*9CuCRZw zZ)nO0o})FUA1eavF45J)3LLsPeAlq=i4Ln42^etEAOz##Yj}Z)12y5W(@u!6r%?F~ zJ4FjC3xqaTIb=vECZPm0od~AiKcNy84#94?vw)U;dBpg$0MTBm@l;}vFESwo2Nh!& z>UgXwM>OO+alQ(a*joAm0+N)*pm0lukDQ@0vq>oa^2y$owtclm1852FEb8!squtdS7lu*R` z9sytb_g?37Huf2PTkk;avWu?L$eBAX8HK-*E0CFq+^=G|=x`849WGKjKfqY%=zvt- zGmx}Z1Zb3Fut32PS~s4Len?~x-<|OvS9pd#WrPA%+gr)x4nt*0H9s;Atvn07?5F23 zo-dIBHvkhXPu%;J44mF3_d!D&?S-TmCJTm3w2sdAeOGVodT3?fAcUU{(#;kwzc*Kl z-MUBV&@l)2#v-_-651oKV#`;E7Z+3;q?0oBZ#}&48zq1>WoAAIHUrV*-9P)d-VCQ4 zy-<`GxypxEoCa|tU&>RCUiPq&MPT|R#ydpzP{(P`{6;S&Q)OC+Qq-E3rXF>DLuEu2 zXUd6IQ*EHel3nqG9BY90ro1j^N0=3D7ISC~I7`h>4=BmbzOZvzDx^6j%GQ>a>Ln4Z_p8Ym{L1CUtq!LRQ%eF)%p)yI1V{b?(y*fNF4GZ$*HQE zV^I5ea(uVe@;G0?Sd#9WolvqYkInMs75MrSXn9ObCj_fjP{odgh|}pzucjgN@o`X46wW(KZq0oA+u}j(a{2y< z+u5rO;gwV{2!2r5`9J$!6197N3Vu~$tb zTiWZ|vZp~m?4l!0D%})c#w8;6VTPFz#lpu8ZdsmkZ{(ZxeM*rcd>fsBT`%4&pQd7Kg5`#;#EdZ{P@A*8AMF+77ODcLTNJBrYv>w(#CPG~3!~dMq^19dOQ9;IaI}kc5b9l@ zke89D5-Yt{W4MHgr&#}JnNJkFa3T~XI$dQi#IF$Co6@~%ur8yN`d&-REaY=#eMyc- zs^#mgSMO1xFrAn`YrKk)uBml#bfigYetgzt^JAlBSy(Nk=-gQ6AuL4W*;!M>8xXcI z!H7=RLwD4_;dS6g=CBI(Xfha4i8GL}qm6S_@6L_lRj)^9ac=!GVNG$~z$!QO+}~z* zk_f4(shytYwJut|Js%&jUaTo_TWoErJ_>BVC@6szWjb#&oW6WP-zDj{{?K ze{ae+-J2?mA3M#>U7ItY_C8HWAATArq7M0xUttA-CUTHPyo~XFx)X^c5z4J9;Yt5P zqNStSy0N+UbcKP-u$(PvdUQ^4Kvvl-u=sS()oO*J>n{H#Rj|30c0B%F)mDNMWxu^! z(jbq`e2cRd%a)4mwe`}OD(wCFq28PM>!hBDIy}xlzp=(Tu;wS~EiD?4mZW@i?`y02 z@R3j39LVZf_}$`MJa_OtSz{o=l`r*UN|?kbARWzPo6Z_*jq^FvwkPj2j$Tq>=5Mvb zgY#A;QB`ED*@wOo@k)H<`;vxel9fnC^Asj}11QI&qsGZSxc;CLMOH-)~*PEq* z8rE`D2aaq!I3Nu(3P~Or@C=5*@-;{sjYXjG>i46evS<3Bs-pHm$Unf30@IkSz!R2~ zYglZY{S}5Ez~TbWX>e%@PNUcBT3BN#skR&b@k0yuw8v4$iG-V=xg`@EsCusLB$Hf9 z@oBX-wQuC76)BDW{LL`3AFnyM%e{jH24+x$+vrFhL!uNzo_2D8;!b#cyAAGfqzw2; zxgKd})W>Ityy7uWR9ju+a!o_)3m*#~FZwPXUNT-576Oyd_D23=WpV5FVN(8klIvPL z+F#G0>=!osG2;lU<{u@G-`1sdTl7y`6#n8wbOV+Z0?FEXSi^6fY0L!RFB)VCaDGPi zF3XRzHA2q&GvAZ;8k&O+ALFPeQ|Hhnq3KcK!p|yH_L`_mJ>g>m9>6{J&(2 zCKdLI8_aVN`m##4U(G4b5!LeaIvLyrzj_hEK1ylzOY_|%5_joN|+$)gwN>JhgNgDUnPH-8cGv* zn#z7w7;Ixvzmq7`=-Y}{n!;OK?IqK_og2&Pd_6Dl`E*D8Y`1#rsdwb*cHp&~D20f( zoZ@0$-chvuLb8kimTWFYS_TG@gOczjJ_+;DmnEc;t(FP<*nYm!19ZoPNm@BE*J0&D zuX}PEw1}9S5ri#6!8Byzd`@{@OqKC{$JgcVJH$53K7%;XxGl$0EwO(#;uWKY$gRy6 zmQ-v$c6=m7c4t%$rTuMbHZ7LJbgO>0*iXX8f03TwOa8aWGMt(X<0 zc*m%t$A=(;++J5m__gGx(RFA}`A@4){Durc=W^I8@)q*1zi}uoUI{VgCl8k1{LJA_ zC9T7ffxJz&kB(K1O=Nfh@O13&@Ra#S{h7Z?X2)ix;@IoCOG;q54msiBUj@DvWeLod zFW}rk^@>asmtEzzZnqQC!^WhLP~@${p1Ml_lOiKE1N!fD8FGff=ZVwRPnAdIPs?qQ zZT^oE@6$+w<+p}wEjE8JypIFgRPF#p?Ftf*F27)aTx%rAv=f+Z^bWjBf#@F#65qd} z_jsC|SzA+6!=l?n0C~;C1TsT3D>Izu%-TBu4bm)w7l5G}z;%#~)uXwR^$2KZApl(i ztM6;bGZP4RJG2)&cC7QV^*t`T^LN^se*57s~dS**{ohbuAOEGxFd;SJ{pZCtXq6=~H@8@y11AvE^}_N*nS-B7q> z-LS&oN`?nC!`$;cisPb^Mv%}J zOh_O1;mc*Vp|J}4MYb4$%dUPLll<}b8XBs)pRuC@Yb|Hz;!KnKYOHMj@PObnv&z40 zTj8-eXup1v2g3TI5>ymTDfkLYcEmbL}b7+N{K?UXS(o3Rzr~B$a`EQfQ(| z8D>QayVb^n(vc)&VS$Xvlal}FuS9CTI*j+S`p4?Kcul#8O?%KP$L`fN9K*-%yjViH8;uRIOlA5d6CV3yLEgxRJ&`*nl}*+O5#*uxBsR*+eyE- zP{YP^5R66&_XjD-1_nyn|G+wYIY7_xYP^_faD7wiZ|Zr=FBkq!HKWS6VjDgI`)r*K7ToOv<~S##rZL*`%ukzM_V%s zQs@EOO$RyldP-DNx&hSmax#uHPdc9Xe$yjRkD38<6jb*J406vA?RRNd z)Y2dq%gd|PGwBwPpyOQyC3> z5mKUgVsBv)VLY2|CNG?9V`V|E8WsEJwv5Yoz~UwIkX4OP7uUPeitx2H-YLsJKWcp* z-jkjsX|)aP4iuaJDO9x(o9h_)2SNHa_uJw+f5izy-fQY$i5vo*f@YHA$pV6Pt zLJZ!!4zKm@t`4fJso{BL2NX_VBL?rw`(tDNL23@s7Hj<`Zj7UnIWO#l=D@k zCpJ&lcYzWZ5%U@>v-Xx;j(bBQPXqoA|Hwor&37`_jL7AB@7$^XYI)mH`76%9%+a30 z@=rMSQbz8V#gu@@^i4~@KnY%-t(h&lYC0cLba}XZq-xz(R$ef8Wu_YXc{ypro*A8g zOV+6~7)T+L0;i{Des6R$s4hDEpBBK_kS^MAXJUNhF)wxmi(`c09gTzIf=WU!S}BU zTW#FSjMrmVae|#(Z`T{l?39Q&Pv24o()jwTnVOnUpmGw0n`UrAUHY3;v9Z{P!}zJ$ z^}pj#Q(#eG#$k&4ZV=sO*`&~YCyQVg_|lM-J&d9VN11YjPcl;bhS4j#;1rr8H*)bw z)8r@nBA0loc2>R`9wlxh4MAZ$AJQ@_u6?AR*|t(n+vr#L42z^9{8QB}BDjAyEml$s zkuv@qVd!yq89N0hl#v!B+`$W6rN!azLw|h!tU883kB_Rf>aGN$(fYzoQ30P=uhCkN zQ&m;WM|9xA+^`~t7*Al3Eb^*f)CR=z$zg{I6Rw9z=H!^AOV8zmph-lFcF;&uU~!9v zL6XdH?O7mh&;*5it9faRIe~ap2o`qkkufDvOdx9K-$~Nn%Vy^0L>xw;6#@U@GAL3a z6+n|N(bEgg7i%ob;I`|-7)}qrJDOer5|u`vDFK`JW<}MTv7p#cxM{ov__l~@tJ&6hMAL8qIo`7>4M1a>%^Uc)gX!&z= zrhKyS<%}UX2g20MtlUcACpaf6@L8G$Z9FV4D-*fh&U>a|fL%DabM^U`wm$B)0u9<* z2muJs<(}5A#CUVu28W@LEew=;4?t|=2|VJ@dPo38C4c)yo6ry9@k@cU0wiud^@=>6 z0JazqLnXhaV%Uh>nj!8eOjg_)w^dc zPl1b3kp>5E(>OS%mOia=){#rK`}35vQ}e~aG<68Mx+>Axr_pQnJWCto@C(6LC?V8V zrHnfCt9Lxpf;xjnr+Ly7=D~~c3iJtYDL2kfsCmk)NZ7xG=2S9k?UuSK(DScXu{K|? zRf=C1eb`;F(ZxpF3c&~ql#rs?WdGq=WZkhUpVV~Qp{I9vT$zRyE*%lyA3dGSN-p63 z2N?T>7wU@M7_~g^cg6@_ZY$d~c)BXmI*(`Gp}brUSgNULTF0-5rVjk)v9hJJj1`|k z5gZ6n#dxu^sm;3jZhiw2`=^ojVM8e#2ma!)rP1$*>_@z7UI>jI_IGRBURowqbL;O55=rSh2)y4hz$h+>k z8Rt~wih`pDl`$xr$(Igr#)?~!VkUKt*brIS&^|tP#6Dz*FUY_XJoU<^w(Ws9A)0<# zbrno}SE$|VM527V!LQVDh7*==*0cXU6!UFtV!T~6DoiMh#1vsX3=CGBT_Odyj>L{U zm5i*CDt2m;8CxfI2a4H_BUScDS`wqs>RmLemyXGw5!+zhU}C|13nG}8vq^~jqKI5Q zZ?6P%;$mnBsi;sWnVAB`&jhhsC^}60?8iDPP^JI$^C@s5yPBEF$;cB)ifxqVHYLHO z{Ir9@{dTnrGwVt?NDWN5@RBsjFzdi7a-8GI#S+LGc}rxtb2&Bj?{c-;N#m*B{iPgD z!AhVcMUasyc21&XAk7OHzkHhPHc<#fZ!GB+5!P)xr!!SaR1{v@kOeb2GvPY}nX>;I zTzi^(ZJza4C@m2*SfT9j6o0vfc$mk>{QPGSfiV7m<(Uk)4-q^qrXF|b==3s?Os$8x zW*G+~%YKpNz@4v{%CXt72i@D=)&yz20E4=F{j5ZPy7GB)iMe#hWKxKt^8iWbU zXxvh0zH30z^L7~IGDZV=fP{G!n&mkrr$yR4qcd-E<5EHPUZJV#3z z?28@BelADNxUZ?1_g->PcBhM)lGBohr#dm|1DV$!_7=xlZf+YJYcZpiBhIdmSspFc zT|nGR$ix*v`E~5ZmJ3x()Q(Q*ln+O;&nZbM{}e%nH*#P=l{s$M@wcN#508Qn5v<%v z?%Mml$BsX&mNw?r=4QoE=AVJ3^#ME>weeJaV8Ms@LbLryjK zd=0ma#mwnKUQ8sp&&=O(Wiz?2;T@DcLutix<6GG+&KDY%=CTEqEvzKGNNrO-RnGgA zhG3Ly{W`=y&+|HBChF<#?he}cc?-2su3hNE>LOMcmKbv1hS#}}BG4QZ^aeu2Bq_us z^bwh2xkeeUMMWuKvRqHBR;(ARP9%!=SCHXxIU}pqZKXp)Y2wCJI1BOY>lH835l%dZ z4HS@Q)*>B_JImu=toKBh9ij-M{nmk!=*7~7Ft?z-TxASpA3MF!u#^y0K06+5s) zL*J1yu!kE0f$vFyh|}~CP$BC<;KWoponZUDmah;f>fH3Upbp!Ni6~l)Qtn8zvv*G7-pP)2y zaLDX*>*K|d&(mF;Y<{oGm+~24c!Gg=$xQ>LmfVkVpgP}m0-Tr5d#^2I7!XgRU2Q%I z1hr(YD}K)>)Og6=gIpP(n?XI{^+?WW;oI#)b%pWgOSu8s;2m%R{ml@boAhW zuni$(?{s3ByO+d40c3qRI5?=NjQS(Iyfi+FAy={Qb;X`zp0n?aPx6u zL!Bg}X)){eiHFC!{~zG8!vkX3%a7fte_=$(Agceeo!%k#5xT{1r&hX29GGp*thAXs zZ$B!$OO@vSa!Hu{a2arM;52{^*UntK!O~D?iiBSr0X`|Kk*m{sPvPuoCka`XwZKntvaS<-tIjHK(ubrRg+9Mh66j|;Hm&No z@Lau9YUi{PB8rfuJgfINPFI?PQA#trg<^=dusS8q3)GbAKD4j>cq}o?EfuP7E)Yr| z+Ep0m8m<$*k4*^2$khC(p>4v;E+lL{Q5T9=M5M7NWO3~t0+}*ucDelGH-KDs@TZ+5e$@8A?to6-G zekXtS%-%C|UpFuIr-%qDk)Ol6ulFMx-skH`M>x@$(AJKx+B!+YG<=-+UN=!8${dzma_chpYVDf)O#jUI?f&uHgF_pzW*%C{2XZ2 z(4YTBprL|y`1N+brSibk_-t$_Iur`dnSc~)NW z6R&%J8|UqIzpD+QYyTR+3i3YX(|GB}JfqXaD0N3qX?cKip zuWu&pcUOW|Skrxxe74Q z7~ooffEt1D;(_olsa(kZ;4mO1Shun5v6tp33%+MaOi`JTGyw-!bZ{5&J1!-?>_rOS zDGHqiJ?1Z}+!>{NzVTbEqE~mmzK125Ig7*F>$B4JuSVUro9hkXqpb;b4jA)uwPx@l-Lc=!Tx4@Hd)49qr~rl^84Q)xPji^< z97okrH*LG$-r{t&oLlzH%g?)AGxa|T;o0Fu@3_G{Ztd-{05GaqXlQ7(J37K|e0==< z{rw)cGL2H03j?N1tglS!*gh7707)zrtky#vm+1bbENOf7JLO#x_m8;&Or6U`dx>#1f;pN6Q+GCD5Q1I zyt}VZBEL!`?Har#ZQnZAZLsI$h%p0SX!1nswHe<3^_qeG6pbuEL}Fa{$$x)$v^Ep& zgeJ>bYyd~-)G%6Z=<%0=N%k}k1xd^w`le>;8GEb8%mHQnPt_JIgfvPP6f{3ZB^DiK zG0l?-!=D~YJD__302yb2a({ogLFLNEM?`wPmqQ$^ixK^Y>DgH)+z|Vo#?{Mr_#IcL zaaUP)y0fO%JNRk2@~FE=a%ll(Er#mM1Oh4~{S7Opb%*5+^}k1u3=@B1A*Hk4N9SGj zt5#Rq9V5Wnu3p>Y9^SWhkn6_1G4EoVvo+uRx#$Q4J~yZW((T44PAxL;zwZ83wedgX zz%+!%h~NxmLJ6;Aid!x3Q)*YlW-H*&jGK`sE(fW8C>oI*&->-3$akWZln@yjxX zzcSiM%lU&VNqRLt7uJUlcQESA12b?mst28!g1N{8=D!Z4@MG}% z0bO6>vQ)ArL=l9iI8s~np6HVmW7q~E^s)O%`C01M6HE4p`1utj{>6*T%X^^!X%ns} z5mKeX{O{hsA8w)gUrIO_M(BLdzWm)+jxOb?$tY2Eh}``&Jbru~jQ|+2JaPB~lk!(a z?R;d|&;r;km@GhMe~|lO$$~)OE=s_zv2$;zFZ&8u$xiP+M(H6_hqY7_b^Xovz+FiJ zrq}Y?fVqdm!q)%&g6VMj%=_KWGbG`2|8ALrN+n%**RdU9XfN`kkPp2BX@1 ztm`6P;Yy%3pA2Ez$Yn|#Q;_0-X@)L8jIxvXe77ek$&O!T6@}W6hnEX1jfL$baItCN z`$^yJCenA$IO~D;eZ8U4{do@2ib8P{i3|siqm#YGPB^{Ijidh=QrK=^lKjKI!w4rC zAQ7#@&T?cVV{6MFN3o>gYvjm?t)XGDuK`84ctJbH3L6Fi0X{12Ctfa?1VhP=^{V~p z4igiTY`NX+dNqqWNKVqVg)VyMYFxng?e(Clbz@m(x{ol4#TDZeaz4lK8jR-pk!8KN zLY-mX;LEa3B|b!Mj}WelJpmc5*7(;tWHXU8-be(yIsg!s)wx#@{PH9X@3F-v@Z+Nf zaW)U@mkRtSZgdr4XrQ>^X*(&9!cw&eS(y;W6Xxs$5t)E@1Ip!-KRpbxY-HMZdW%UI zNa~*{FlAHGU;{!?yZBr{C^`6|aC4sT(I~E6Q1de(@8iI-R)b}-)B$1gMkrq2iq!=& zCjXG`CxVD*WU-H|;TG?uz$gZi*m`T45>1VTUquv9Mf|#|jp_5d3CDVnkJAbB;>@dj z4RVA7K^=D1he48w;(jz+v+p7LG`Z`rznF`=r0#*JUmg}!Q+$<(a=F}pOp;$b2O|&p zrz3L~7ONR~?cqft5YQPCx-ZAJd}Aem*^zC6`sJE+!}()udcyqtf~Z&`V9yH8_cD1P z2`0%>`{P*8{G}sW?K@v>KCT5FFra!0V}{`pTvG5HD4)lq5QYqtSUkE}C#z-=_1%k2 zmJd!+NW4hsjL?eQ8y)&D?o;-kH|}8+2UP6a?LrMH969*&Ckx!|by-Qiy}W})VdB?}|J5>vnU9e_ zEe--UO;|mb7z@)cXLO=@IhmU=KZS&ukk-5^arEcxo~Cba@Bv2#IWERvaSLO4)S<6_yk?0^H#J<7S39ZGS^z~ zyq;Dz+%F_qiQcD@5dO1kY^CY~p6rc}9{1eZq#2lY_?RD9d7f&QHR9GMPWL4YI!>6+L_dR7^Eli76w_f%7ui(^JYl8f;mu$y2kevSWt3^~5 zJe3r#eHcTO40_POZxHNmE|T0t^V!en(jfvj#{rqqC=)K+17RddRnFqaHlVD&r$`0` zh)wC2%nFL>(t%F1xT+=dL*GYB<;{&k9sA`ZJxg4DLnr{E@rx8^IbkOf(QI|&Kpjd$ zEHyU14F;-&nPcnWY|-JDB(J|v8g1R*Hx3cB_1tybb3r2`Bld)ad#VMvS|Nmsenwad zzx%3z#)aIZ2??ez4n6sGgVM;pD{~|U# ztMi(ln^1EUplR`VK6b2K=>za|39aJ;Rz5`90!<7p2 zsA^~@H=1FcPpKIKjqko^B)|dm?|TSftOS@3)H6)Y4~a3R@|f^kznaO=@?5YQPuD&^ z=F`&mjcGZ*RPw&?CNNuJ+Hu=l7U#4Ij$#$Ed17j?8G59l-nplow3IGy$zQc^kVJF?W~ zyK&F>{3UDduJGhYntJ)rQ@I$r*0fnI)tw#VRu`d4os-BiwBGLq*}hIN76ZNY!?-I< zq)xuB#e5xV?^-PEyL&!5t?PA`ap(0=D}MHn2N|WWN@V8NVm%RPGc<~N7Mr7&Kr}e& z;WaI{(eF&jO0DndcX)Gat1|n`EiQ*K;eBnKm6A@_xfvi5P;lo zmEWy5+`Y5&U7L*y8AvC*X?|K=Sn-!ZXJhQ?2fe?YfFI1 z#R_~R_I_)FTIX}{@TGy_J9}(Va0o_w?(UKUEt^bPFPAp0cNu~nFgD%mkqZ0zS?uj+ z@dnoNiz&k7$Mg11N2#1+&4H(l=Of=$jD+98SMR>42X zmBCwg15ix1no8e)Zf_nUKhV*0%}qY26C(Tfv)2MVbPja=Ga_+D)@+BxiqL#S$GbjS%OAPh0?+2sJEt+kCow~(|ANn&D zF{xD2b<%i=wHy4zhL|xVw-tFTIgvdwOK$K4V*kkvL~V0dZ0ZCQ@~|kKS;BXM z$|HMiYZZwbKmYU#o<*Tk*=5?JtXRFFr0VGj7}8Nor7=npJ8@jD-Xt_i8y)-jz^};& zT2>xsZAhLmEuFIsQR&9OjHVl>WDqIiS$Rk=RQYN(qrAwD)hrP)=O9ep6>BFWrFT(? z2CNA)ZU_J>ieO;@4e~l>4?^54*@XFmy3Uo)O6pbe(|;nv0|BXBcfZRyhzH>dWUSs! zJ!APp=WD)Ghtns+AR;i*IPFnr)PGS(SJ`rz+AoEXA`18k2X0IHeTx+Q<>fd!M)Oov zLR;t3rG4jdoec$HXbAeYom^A?hHF*}#TctwXl%QnEj;G;AicV-1l9GUwx%#F<4o+E{r*Cw!A z?tuLWvC`7x$-zV57zV)0HRs}wO@dOe`_N}?$h!Lr+WO1ivyT7%G(A36SO$(b27^NV zr7p|K2Wh^-ez?N_JaTeUPlmf32}C%9TOyeKDi z>Q_#T3M5iAw->zTv#g%;Yj9+qIH zH|)UrxvP8@!~G7gr{YMxyx$e&=5l3}_zwQxF2Jo2kO9=~(7Kg!du-H8Slh(qy;fM^ zKJJ)#;#pvmWK*t@&@#)TCA>2_GdO@)(eZd_lmnaTOy1cw+jy9&7>a~IV5#qfcQ5K& zE6cgJ-47#G|Bv{W1HXBXQNt9^WGi^$Xdvc~v-KDI_}Age_OMy;@kmNPCe0Tw z$z=t(bY}^yze@s&8Zpwr-b#6N;N!|`>H${w+i|^)YxdFWK|RrZ=FqUiiO%r}Z6BU!81><;Sq@D2+v1mpBig2BGWcpC5=221nL~wWw z#lxK$ss32hG!bf)N-FF=ka2#6n=?{_l0l*k948PcI=Pz~dL%{&Y+B zy1Z+zJe=mx&9wiS(hSfwGt2`5G>hDwk{#E>`#F;gU;uLabVdM^7;11;iu{Jl$24P# z*o8_G{z>%_TFB!)6(bb{BDj>@PT9|MOqp3Hgi4Hhj(Y^qUoA&pGaVoQmAcxDc+eR~ zhlhu|w4OY@qR^+Ghw!v*ZAWHdcbv<0KV{i@&KJBLSDyu=R>P9s>Sum5Fn3#C%1*2ndghJzhrxME7y4ePxGue-nVcRi9qsx2;$=o-;gI zUtz+}FZ0AiO1Q=H8011t76D$6NjW~QlWeVN-p5_@8Bib9Uo zH7mzXxqI%SBBDxA*xuQYjsPbojH5p&6+((k?Jv_IQZz)1E*k?+TwtNUA>z%xTxD?t zTcfC7`*8sCcx-u*ZWXv#9UVPB@w9!}vT235-$-xV&Nm7_HAB0F-l^uOa&d64ThwEa z3VZEDZ|Lfj&@(ce*e%uB{9xUp%mSA1a(Z2a*=1hh>1vYsbGlAuaxq#nnkB z)3wfMF>%Q6Tx`HCsCjeoI%Vzjx=(b3yiE9Z&X(bn5O+31JvTb<@=pr=a5JycuRbI> zP--3p%~nnQ07qe<>s<(R+OG{l92U9*!w!fFPwr>m>EECQ+tmNHTm5m;>Aii3*>;Di zC}1KWypF<5_4#l9Z)67hV^sm?eD{+=TbXzXX#d0)*e=SI>)8uSQp4Nbh`#$cXDAld zZnsG^2w*ig-4IRu$JS0gDZ)SA=r5sa$0gWMvMdSGv|ZlZmONqQ#encciIxk|AY&(a z?LNCVe;-TEyh0O`L^Xj1?uO&12{un*H~Bu|7gJ}11t>_|MGJvzn=N3BfIkPLV0msk zrTW<$z(w*}g@avUt+k*eRjRr5AMo3BS;BIEmfO_BQtWM=y<**b2NVyL*m^p8``3;- z!T??MPSaY9bz|*nI(Zr)6TSn*A`@q2U7UK5q=?bcrRZk(nQFgAKOjkG47683jmC{- zprv=(pc{`Fu_>A4p#3E(KHa#g2eEs`wD_zZbwr(B`ntL?D<;@1RRYU$LZ+nvp-H_-nbW-fgA$mnS$7V`9E=uzg`rd?>)C(i#*Ohe!WSGtWYw zo#^trDl(pCh@gcOi}CskD!ui)K70pSTP_SA*jtlF=j8EnTi^Fy336?C%oHp9v;?(T zOpEt+evU3Y`wBHOn@j=m~*ogC@a-vlX) z7XX^P2X9XV8ZvyAIV)QZvzF&h$D@s(FiDD~$9~wpl0(iRyi;cnFObyVB-$klY4T$Z z`dEo@T~~?%1vm}1Ev|+SL!)8=?s2jDjwfB=X3tAs-W=vOy#93wdG5y?pEzyqpKY|j z%(Ix*UqZUR@MLz_!_0EOdrxFYKOs)T%ym@K2!%Y&vuBDody1~PJ0b4v` zuj9PVtu(zq*W$8M0OTSdr=W0V=aHgBl3EM%@BH{H%}j+bDqgnVXWxKS8~`D66EYVe z@~q_--jWitqy;>S9R!MWI+R*!)p6F{CbP|kbRagE!2k+dG}UqY?yKpP96SJ- z3P?#SE0$e1Z;{AgqO6=AhEVP2*VCma!)WH8Qjg*QhkZb@r$*2(yBgl2VV$1udb(6D zh;uJmtXefMrBXLrM4v8Jsajaey;roNt5cO38k`Q{Ro2$g!v3`t=QF_xj0zBCNuEIJ z7xS_AN&WlS?DgJNts2~%LXCuF(7UL?I<(Zc3`%qZG5`x;kaAX6wS{QaQkn0zKHc{P zWAwIJLW0DNJ6sAW)oYf{w5x0+Kg~N0;(1N~a7A#b2s4-~B@H>wJEw+E@2bjYHgU1% znwkDVc-ivL$<_Z?zz1L}BOF2ai6G)ihf z6ClMBw0L5`0<Gmjhd>U4RL>?f{{mC4 z_QeeC!%>zHPWiQzg7K}T+a8B&t&Z|)o+4ScCFi9ZV0KXQ_Cp%vdEQ#uBi?=dY>jQ5 zfVpDD>p|qr*UsHkc*sH6e&ca~;C226piLSPRrs;(bR28A1vZ4c z51Ch(8BsH)Vk4F|Eo0-pT-)G%t9;uhwwq|7+CdRTb)N`J*1=0DPGQ7h{$Y|HKRaVn zJ%8swiZVUxk4Qs0nL=vEvOP z@FgF5!9_?$8P9iUen@__-08~5@||iHopg2Ec>U_~RyA|VA>KZ9zt7X@ynGqc(IIR# zqgu?s;8%nU>fxQX5R2X$S8ZQ6=R&lscg%9XU0t1qzFj%mxgQZbKD5{}l0dzgr(2+^kqA?-yP#RXqE{vOH_z)B6mgoZTl2 zR=JinTg+JWcVlB4*k=fTsMXZyv)nB6RL<&>)6hnIZ#CcUw;;Ys#lQ8ZIL}xs$T{^% zuMlQFt5WRMS+H_boB7pA1?RVk@i{w8_nB_wWmr~y zba?~{1e~V^-D=6_L;A+)V#{B;qcNA_!;jEWl_~ip9298|`S+N_z@|tN!~6xx9>Nw_ zAb=5q2vw>`5Ee+p;{s7ehP#1VQCry^lp7Ss3^ZodA|=9ugY!pbw_y8h&UaFon84Nj zD8^)oR*O^3-k66Grz%COQlfI#Ga-5-rGtT>-9>95fFe}>VXv+BV%kdxBAlOyZD;`g zk@@$FTs_yjujRBGyIS!y5%G)eQl!F8-)Dl((%MX9)#&l9hX>fOJQx&nc)|8?vbEKV zh?P1=`ZbXj^d?Z{AX192bR#UZY%!#9VgMIL`9odHD0aj}S|E5}txdm1)`*lhjU-d9 z!Dg|nie8b^4@e^#r^oi@&Cfj&LBm4T9vU=Mtp&h0H2cVj2A@p<@HgFWgW@3b!WkI& zuS>`<={LecSuPPCbp}BqUFZO8{~}7qUnx8Zuxv zOcp>C2k`St2?BtAg8@Ns$hf_7CxGA~2AcLxdWNnhsv2@T8rk@0E{^{q6Qp-jVudgD z4i&ie#@!?>&1lCRmDr%9(Ws=s6O+gtohWpro<$}dq(fWuC4ltn<3girkJFpe)#m4; zuFprOz0vK`zw&mc{tQzCsJ{emeM|m^=@)k0e`oS3K8r??ykyn8sM_bL1*%ZM3JLOs&jwPa93#g=_n@FRXgV1xuOa#72z3K&v1{muF5L~*kk=Drofw9N7*&R z#w{5I1r$4H*fwf0BW7xz9EpSTqUVSClK)_pEZ*y}6go<($xQL2Y7g&;b^QKnEg4vE zxKZTqKgF4K5rCFS+D2vbA6PCFgKXLN$3&0nl@$*edx^umw%NX8b08AtTC1-wPmF+J z@=uU%fn`XWSbP(!_sKvd%)c#A{H61@MYH{^@-<(T)a$Q2%X*W$c&Zk}YFK6RW4AEo=Rd7fG`PtZ{6u$f=a#&{^{&5 zXvil$sy_eW(SIDNzALbTTqRZd(q23>K`y7>UZB4226vc_I#tXsFW!Lv}tUF|vsrLF6iUtS8vzBW`nYaYhCw0e(}^TeV@XI9yiYX3`gc-`x??@wcSs;^ao zEb*Y8`|MxVmsN#E8IThli6inrsgh4uAYXEgz-|SqvVs};_SMR6XIXl3rQ9<}GB-?} za9Bae^mLY)?88@+v>4_Udl4OB$k-7Sxqu2cU5WWa9AO=zr|t=_rYA(QP!^xJub`Nt zJVH3UTmZmwb~+7C;alpT;~W4boC{vAnm+|HT@$b7xDS6#DBo)XPtOF`Hu`l|YAJ0(0+_bed^}ck#$+3Cmy9RNiO%@*; zX}vf$=;QmpKVw8?awzczCoNr37WoQg5jrL&O|j@LTGzM+Fx!AN4Ds!rcd_WPc#iHm zd?f~BgzIW0nq&KI^V471GJ!B499%AgM$ylpC?I@5Sv|~n4%7!X#D8{QQiI`;q9 zQGeuHvcn7!WO93#H;dFbULheNe*V;VeE-V=KG?eFX<4)xK#FLO*(V(zr;WlL_+Yh0 z7|gZImW;`ch$;DUeddo6DqpR!yv^XR<-_2>&mW!c$iA&Z)>a*}JD$2!d1_*BQ^i*+ zMk&7^L#NID-nZQGuH7<-Rcv8?*M5*cexe1AqCuiYZ=I7sJtnPBBAzdGskGMR_`e@TE2mIN+DSeiF$92GnEJH0P)YBOHTcsR(&fvXDBxmm8u5-1i3 zsP?%^jV6D-BonEwPX&r6#T=3&Q^+WPkr_)M{M8lfrR2aT@fXL4^6bkno|pj*tQuDj z#qTpMHe zA=lTjUUib=@1Jl5LKO)~#t+mYT}A1?^`v-if>eNo zaN)?f7GPYdh5!+OOg>6tJ+mU5A2K^N0|58~oq`45P}N|_+#o)&50z=iz4_e^aW9ue zed?G?DRKSG(EhX6bp1TPlp#LI&`37piz4M?hiH}TZ!$ivdi!25D$D4{lAMyWC**As z><#}i3;I6E)>XNTEwTCH$Mz* z?f1{8rY`J%{MbDWvQ>`5Ib&yHu(@PW%V#s4mvRqLZudo&&IkTWEln}r+lGA)E z6iVE9_O-=(W4k+Lo?4F+9)Nv^&`Y4_B80{~Sew%K+UL+MP*Gl1I*bB<&EMKya}#P{ zm7l1fa##Oh-|Y1ksk8ZYHr-Kgp7Z}#^Dn@kW4x~HHk@8*$(yK;BBBP-P<|ZecJ)SR z{tG$|V*Y@Vi>s^eEE8p~@(*JjC)Va%Ub5=;I}~b7A`#BwCP&HUNr-#tZZ$I%m!n8; zP3hd4!!8q~NCNL3F+Gd2QtYj^qPQHv4ER8K{HKSRPeD?@TBh2-VVUNHJJPE0D^5Z} z8n-Pg9@N)q@Z*U_?UJ>Qm6}xojY7G};4#UEST)6jKDwE_yk49g>d;uSj{Ob0`(QME z^^bTiXB}%3$s_&oV(gg*5{C6!b*U3Rw@c;UALhxueZ9PZfaJrQ;Qrul(UMMh|Q=`mAMf8i4 zbfnYiDt=x0xZTBl{K`#$3VWNLG5x|OPws61%Gy}-Hrd=|lG303&eBJ|wC%m`LVCSO zWn%FZTHk2scm-N}%LxLgBFxnFeT!EVVdjWP4&D!4eua**7d=^!IZRw&g&^J9nr`3J#ah2wtZTCOrSz(xc~PyuK$!h*GxDHM%a&t(!Qu>4IB z>8WzL0;sDcg8ro=^M-VRTCBGho%u;A>KG%%4Sz%d!f4`i&9U)Ak)yl_*{m~L7EJS8S=fhBjz7>RR?9$J&MwzO=B+WJ78Ot;{nD7a4v>~ z9}=zrg0W#Dl;flsB^srul70TXAhX1V$J{nTQl!%d?D&}>U&uYDVb zMik5A#S#3=bL1qJlCs~E0UxA{X_l~;Ep@ruG$LS8O`(!RLWxM@fM8tgIn8(AoMZqd zMOWLlni-tI&&=;EOdO5K0m`fnqg9HJI+5Nsd0K9IY>hN-t|T; zez0BDYmPOPU@XrDKB1=fNz)~DP%Q6GtkOoCo0Sds=KtMr zxoF;Wg_L6>(PYbbRC5i|K#yjWicS`F1z;}8;lw2!D%#}OTYuuFVV_{=XJD5Xb(`_q z^vTmN+m+TPJIe<`SB9a(ewj~%>&_21+eO^O-@KjoMPBTiFNc|w2z^gqi}!Wp+0E8p zmTSXm(uz5KLilW~PBd9pUoTi!y*K(Xx?olQY5J+=^Zox?15xy`pS364%rE<2-X1ca zFE_s`xp>E|3N}eSL^UI zIpxL%m%5s}8mG-k(kGx>JX4ZN4zT$oM!>NHX6#~v8}ajx$L}C}%il?2RwhrkII330 zNBglM1*w>PO0*|l8-7qVYsn>sx*U}xu5S$$y`#N(qQ$x^P0dC>iu4+9268_k>>(I$ z2G{(g)97+qc{kXALkBy>>T-6!NxtgYzO21H3{`d>*l>o%_*_bBe!G?@h>gNT8_G%P zH^{GCaVF+gXxrA*v!9YA;7%si{C2}y>*yHvV{`JG%mL)(O5b;T*{ac6XfHQemxE&o z`V}wO!(ik`Yp;HreIw%vD*na`3=K0+eD{2=_~l@v`_h0B^#gU|x|8dMR(&NabRlAd zuQf-QPlz)?!mynC;;Ws+8{oKeSynzHL593*X(4>pc&n1&~yH=j_eH zDv@Lye&~3o`f<9!(nna4#0sbd{rK%F5t1L$&V6@nZkbCSI9MKIw(krswO)1vf1L#R zg$)ldTYoI}6Jf-}L#uIKV-uq+NTf2EgoFP862Sse;D+^T5rUm6hiH()am?Td{bfN8 zKK@JW;_+b|RH>5%eiGS>lvQj3RN@lFC#aUt=`PL=JMbj!rYe(IexhjLzu(wBcsvdA zw7-I69Q@4^oIE^iy`0#>w;vQ6J2l4k5|R5XO2ENO6YlW!aHpkBLu1R5!5CrNE>r+c zM`@_(FJR@O{(J6aaT+)_fBRx9E^5%UUqV8j?5H89m?Wr}QX2VWFXlE%N<5W8gq7VM zmm_fMp?WJvebu2I$63|NzdUl=mM~Zfq1k~&0bB9@)ElXeJ&ijCyGw`2QA=CTIpprW z=R4%gSRMBO)%S!pp%<#9LcHoZ^_oL1TDO_B>6$S-yUsbM=p_W~UH?Efqu7A%$2QpB zZO5Nfw4Rp4$0TxHZ}A|#^Zpho5H4K4-n2lONgo;o2OI}76&M*FD~%T}TqG3#yx`iuA;`GS5HN+^>h%_+2%h)NIv;Zg%rX+<{)>y-{To56~8H<21hD;oyZ1i06`o!gc~#hCVt8pa)5CJA2-pd`y<3 z&+zI|t^LHWTX73LjJqlI$%&$yELV)5_>$fyo5-U>xmzAxlGNc+>V2DHhOCK6u4iPo zGfxUF_~T%g;|6r$M>@M*xza70B`{qMy(`#?S2%fvze>Q_8%rB_+bZ#OyAxm~%_4ak z(CoY)CD7+k9?I}sj_D2kf(2*douA1EHosaJLNi`5&^7)mrLW8G%z z=waWWC1hBn&ZtD1f(qmm=Fa)-LwU9kBJB(1OZGjJ=h?V#wXnyS69q91hN>1S)2f*HP=47>8u`?VRlVZ7*>yi} zIB`ZQVWm+s_j?}CL|4PrR1`oX8e}xZ%eZ@m3OYse)MrmcL#_0fM9?sCPFxqy1%IqW z-U@fNUbA$Nteh1XiWvN+fkAwLr=brmBG9TWx#My+Y&%mC(dMIPXM>q!vf_~eg7WVu z_~<35kYoHk+^?hBt=+_SjWZ@<(87wAtbdK{S^xXLM~>mYg4|i{^oN3}+nG8dl#cvg zZ3AYeFRj zpx%+ChHbNvr7X0aPybilKeNdf)_x{Te)=%>xW;mDb=4m*n4=(AiA!stJXGsvRBf@# z{>!UVwRD$}YR4)#`_ui0=<-6FT4GK|_N)o0!)%npGLFceDs?fyC3wdc^pG2-%!5jO zj*5zq&I=Ifu}#E}k}_NR%@yaR=PDkFY+)IwyNOLIrDE$KKC54pfHKsV8-d@_?_e=f zJQimo{)eOfX$2T=+_-vZo+lOZ*!dc5r~h1&tP_?x6DqB^7%>EE2xLgIDqw4TP?aIc zS0;SV^4deoTAc+GgSal7Z7O*D zWmRzXK#K-@3hkypPr5Ml>d%~oI+L;QTea_70W|9_ic`_M%IJC1W7ld#blh{^Q3^g5 za5_^lzaZ>e#DB!JdzEh-9KppIfl3`odu8sDDa{xJNd+Ea`Yb;Jo{c5CA*nPEg+klB z3ZwwHj^qI>faMNcpfgoj8J;>QtP3!@?I!{c+>)DbWJCF2&k!)m90iid4hq%^7neoI z2&0A}=Ma^%@pw%~c8m31Y^j1jACm+G=$*KL%cD$08jM84jo=y-54y}N(R9Lp!tco> znhC~!vZ5fK6Dk?rlNDWm^D7n3HticV= z(Z~e1s;j2CY`Y9PBR=BFl_k=n_h1CKuKo1V=Y-?MLaYL5FjDq0$l_XJu_Gq%)@yK4 z+M||{_Vqg$06+1xnRi!5(<4q~gQ*08fjv&rG*Y|M+G#Nv>)v z_4L2d>XtWjTn748r6O*Ws&@x5^tG3xb(KyLR4q@BWFv_LcZK;0`3e9~sj;a9jmX*r zGh)9>96RyDdQ$%@h2~A0qzfOE{RH547w1$FOPismBu~vVQi^Mt ztc%+(2$U)sw_&I9rSrJmz3tnaGqibr`RTK(&sBCIiY&TOCcQB_vN6d-wQRb>DxRxR zYw0#+gcQ*xA{xanE3!!^eK)cN0XW2%2I#zq#$6O5em_B}gFKzCP|oA_ zg+s_`!Zm<$x33AvuYWHCC0lbn^FGRKpEwuj-0(O*_&X+GI?C>T95l!-XY+VZDpNx^ zu^YXp6g=Uz&l$WKJx^MBxF~X=-wAzgCN zOpgYOD;x^Vc}K8H*r-VP%Pg5Dw> ze57H%4Oz?8j+EeFTPqu0;RWkfTYmfQRE=N#<#d#c8=A{%f4xRhE$g=}!v1Oxc0jeQ zX1ExWP{&$)i||~{ZqXUk7?byD_@QSQbSW*< zL(6>~)+mChMYMNck;tMl`FLASk0UEv|KJrS>D)xr(z}porCW`OG)E&8IH@y8lujsz zVvdix;(O_qrfXSAOAq{ZH}tu9w5pg@$%g;J65=f`p7nZN2)WA=cHNwu?Vt|*Okzg2 z^7@ZDq5jgHn5TgsX_)shx)O3ec}WM5Tak;CLXF`)hbnZbq>Ar6+?JY4|hU3QSqh9aoi2ZBOAhP;-U@ zi13Fw+{zlEQ&M6Ba~xwbF6(nMgWlzXMZ<9laN)jdEV@K<8t#5Y{V5Y@tcosdo*nT4 zQSVoMUtNZ*+F(IE!QjF5_2{{>e&dV=C=*qN8U-0m=QbU_P-q%Z#C3y-9vB$BB(>0> zQkrjLof@v3w@$(C1I9!1p6655ifOYQd~Y0#4yFcBB2xaT=44?KSsW?66T$?2PSub% zkr1O4E2x9Hff-$HI>j&dRckS!XK08sRf6$IU6XDI@bOdW$cRfx71SY?>;n64I;iH! z#_OCQ<@W#+?VoMT#b;D*%wRo$+rie9h})!&p%Io0TqJxldx+a;P7D>G>G+eR-YoF7 zD2X)I;>52#`<@n#3=B|-c^wQ3Lq=Y$9iWE6e9686C_o{4VnRQWsVT3qKPd_urz66< zczAex|4svW9{LLlK1$dEj2T&aCo&kfLrnbIa;np4XJ{ z%ii#plSRQc=fhX}SnGB6T3vLXsi`RB+hFQ6;R|Pk(^JS_;tyF--*@ubK4AKuH?;Bc{VyuHAL2~L8U2TnvtIV> z-UgE2&YASvp$}g#19sEX8KPi}ublzM3GBfc&RQj*c4t!;7yBGqKNYrx^^2;sBKLv| zXT7Sdi1*vVX1N_zquS*Wa*V7J1;w3Vhc(Z15HnM&)HiG=V%SPJPZ3o8Thk*|=zc8K5j*h;< zhi-1>1PU|?-VNPNUz*$ReF$|s2~mO3U$*>>B7YXA(~#oU8X5K9rzU+D7_%jLT<;L_ zM0y%dI&Av*;7yyQa<&2C6jW!?w90xM(~oRjWA(Z16ned$@0Xe(v~} z|Jhf2vIfJ9ZOzgqTYIfU6Ho^rcc{)dd8wFPC)fIQp4VW)oonfD#P!+~gu#Wmd(8K= zsIB?@>O7W>+9`A>Kg0EgvO-ND85draItLS<>6ixyt-h76HNbk{N_;D}0+Qe$N;bfI z)3IC`MhVHVe_QcQiXy}B>1a%=ER;BC@xh@(e!%f?F@1kAX*qYAWj-Vf|DR!9SZoZ+ z7Dig>#ss)Ps0fLlI2FezgI=|6&Adz6NBvJS7Bn@YyC`sx$OU?YVQd1_ecTGI4O+A5 zd|-;gMF4XBN_b@)kPCy9scry1n##O9^u5q0F5aI~^-ZL$O`-@K)!{pY)~O9T->f5o zc7vHKNGvbRP07l55r3oujW<0zG=XNMfE@W9^@Kv_p<$2wZhLH3p>kQIozlVdtpoAe z6AjCcXoV?%%M{vV@OmPUS7_FJo76rKJci1#u7<@%?#q{O1KF5U7Cb%bkddibEucfd z9(nJ1PdWDq?+%)3d68jWkHiOsOjZRk9&B&&cg|pM&1bs#uE;EnOR*zT1yKS%cJP^;R zory8JVxa~p?c`)y`u_q-FH%tkeKvn4Z}buT6J z3`ir5bV#RkNQZQHmvjwC49$RagLJ2Kcf+3V-+Qlv_w+ql>#6&>?n_u`MjRNw5?;sn z8g6Q8s?uH&uG-i7SLWR9~qg9_DKh z!yGI798zr#sj_u(irl+;?HDDi)vf@VYnx)8121uyP6IQ5aR)AFsH&bF(-)v!#kbW* z42rL#8;f_%gnXgbnPMf9=Bqj)qZF_mXnZQYJ2T*FRpL7WCZ}tpxk?pdl3*+0_m4LS z@p)`Z(Q2I3*snw1q9I3j)!kC2PUm6@I64k%Vr+uI+L+VH6doff=~AG+$9i}29+ENeJ%6)f|B`!) zMx@XfRfXuw^{ESQG}uVsv5-_inW`XPqLg@bVwx&bu5uz(P4s;LcG$w?-diOO$4DnPPOsp>OzS{)FTw$36A z2dJ$IOoV6t;nd#6ivgea5t$D3jiwJ3OA<*k&~Z95nGMIdDMd1Y(j%#C-%>hYQ60UP z8F*yJ;kd$u5G9TH2V`r&oS+&L5~>y{9KD^~XZ_7}TsKSlEBLb${3xsDLLF*k-JIYB zjasbE0+0(M3L(i|%DOiI-YO5T%!|e3he&?&VfS={!3x-4H@_$V07k*2|yjp^Z9MrB8D@p3P}b+U$-u@*mIg4U#L|55T85Ko&WeB z%~r0%SXt6Sz8mF3XTo0Jo}hhcLJi_wAxQqy4A9Vsmc6SMs9*NxFROvqe+xYXpZl;^ zoHY$ov*$mg6uhxC8Qgmt`S~pBz}Y?in?HNm_W0NLUtAv=^87lKa+6INBXP0e(EipR zH=g&V;D4bKc4gZvz|b%7!)stufrH<}#zyc|=^dtqt*7Rfky0`ntWfssSgmsF;SBlo0NXr`KOZ^Kd!Pizk-6|>@)avjmh zCE8DP?7NugJhAqp@n)`hul?AB6uiD+72euLa;XdlL7N8Q2Bm&Y%9bbphC}Tf;!hBQyrVNyJFZ z2|5KK&PA5;Fq=4y*Zv05{I-Ax5g_q$nO33m1 zM$VQK)vYuoB{COp-rBu=kjN=q&`COq@fuufqLW<%il7oYC241Y)YYI5a`G7rz(_uco9KU`lwog{7FOrJa$RE!UwOP$XS>d~AH_B8%no`o!Rxc6Nm4Q5gC0U@zp*A) z`2G12=&`s#a5S#{GCHjsYW(}D_N39}x2UI?LjC@OArP_NrGCPGnU{0Y|8{W?^WD2g zzXf~uMAjSe_CW;q@d&qQDzJT%o~k836D;c5~_ zX!LG|y|tuvPyAEJIJ^B?yXgW9fju=4R*{Zp+B-vq}v8~Z57+!6NLMOx%F$jy*!Ax#Ec()sw}vbc=>ku;`P|`XED!v=YOEmD%It)2|vI@bwOv_+mD<<{>cPP6u-x08STa! zi9X(_LJ+^G3wNFUE!9lk8Z1FocAFMiY*IRFT};715)^65n~toSPmz&KYNDGV#;>ny z)9yDT?Z@N$Vnumv80U;*hD@mcv4#Vw`>xj+Uz`EZkpkcSp1O_-z=;r1Pq^?o)HG%m z&XMUIl+VU+!Hi-vJ=yQNr>j;ugo-ghhO8Llmnj{bI6a6EBw;}ZqSlCxrkXiwTEhS{ zNa8!P-VevRZcSV4vDDelSHtLYdskXYN=oC_gWvO7e4YMw9+-AeoJBYYu>?PcD$uXF zpJcwnn{79Fd)5(9d+cj+cwV;`dHMxbU-zp zxjzxVKzd1B^Sa55njjzME6Sedd%N9Zf8B6cw_Uw(d2hMZ&ielfT;`U#+^aYS*5kGx z*DVaCmuBE>qMsn~4YzH6h5A2%fi^8L3!g}r>eYjp;T>H_iSW&2Pu$vhKcAgs``aIs ztP?^&bWDus)95V~dUf;j6nH{ZofUsV)O&kyKO9m$YafU*PCOuuW6_@qahI0~VZ>}N zqWBCKF*z^K%0gq2Mw(@@7@1P2V^LaSK^}D$1|JljTUt*nj`E$tEhRD_LjZr94kG@$ zUi)2zC01-qMVYhNfO=Xs^M zsH$+^*{(GXqjU4LR8bM-j>&DK8}=4?ZhR=Ee315X{QtnrwW}a;qKz%O)y3|2&nrH} zp1d`q8l&R4eN|M--jgp0B@pu1pg=wr?D?^{X7j66r|3kv46comGplXoBUItnG*@wE0~f-Cgav z?ymp3_gzO8T#kIwHzF*K^~)EbvCz!bM2}IcGt+rXFnX5p-HkKjn;^JOB9K8v%#dO- zl5CjkrW&2A)tte&v*%d~q@1Zhi0Mm(A&B>EkpN>w>g<~2x>@cReyS{r@F5u5jy8gIFKUD!7m?b!e?*cUAu4{$p;%%$x$_nfF!`Kmc(Z8GzCOINqMO3I?;P_yJU$1&76xwBh0Tz*)4KJw;NpmbRE%dD zdX@09?s@&KBPI9#8r6K7;S}`8TkHu-;N_z)yQsqsc3zI??e9+9*R5r~-DTzRqufpC ze%e~?#oN>2oOu%5%KcD{Ki@>~#Q)8cX9r<=$c93u4&oIT5o@f^1qoMZ@IYm z%jeKKgmH}*Ck9ce`HYw6XHhv8ecKL`++ty46GRqcjEhksC9x_bNdgdz&cqy>YdSkM ztBaiGVukvg|C(ituyQ|1)l45)$ff>RgVB}C@vXtOki@+g%E)~B#_N?3ET z&)k8Q6?yK)vvIrlLnPLduDCXuT#o;0%BS^(@#ksmqQ4*&lE_e*>#oQy^2|yP>Ch)a zBEn9$y{6I}}7NBHp)V>+LS9nV-11>$$JOI&WjzpiX-pYfrh${rw!s4l70K$RDn*_xFb_ z^L*=67!|7oqsYEvq93u0)x52yE$7^`IXq=lspn>889}_HTGSMi{>?S5KR@4sty5pN zN<}a4JFrDtb`C^jZedx)3|SUsv%l-kA;dCgS!cofjh2`8ZE0jKx5J`g9*shI=H1Kw zY$nlIh7xuB9qPMOk4W(UJMgp6?-B1+Huv$> z*;O#-XBgIFt`?)DWTY%wm^>5BrHGn5iD|c*r(a2~tKzD=&rXOc{)1}UqGF6W3&m+T z0;2r$m%^zfj!+~zGeY;NX`N|0gis0XZ#^bb_z?&=aFXb#!M$iv@J>1IDENS1bBuFK zqfAEi^>PeO-Qo}nm4~2QZ6{>eVi0T5WKWr0jCzQ3;!vD-rW(y==V( z9es8JVPyehnKBSiRUHnK1kUVl0OJNZi$+&8jDaRA`H`Pr13jrIOO`%=vZTMr!rsr% z*xoqbp?97@{F^07dV=r7QR7mPYrcXVTL4zFUV4^Gsx3s-dDx8n@t4F-_VqiB){}G{ zY5LHmF-@UUx@=}MOM|xBeWLE)Dvl+34j=I}ZB&2ZldspsW%b1|bWwf}Vt1?(d%V=# zho=f!Y2#!;50pX#;Q=E22s8h`79c7=K(DUi&JVbmZv2uy%swzcK^_-k^hhVealP@k z@n|4Za!{>D1thJLsU{nY?YmH{Lc7Ib)Lc3Vg$^ekdfzXSRhc|>Gcn%Ddy_O42V zTferEyRkYM{hlYlPV(cWzI?A;z6$IuN6s|h7J~T%i2ST*J3M|@DNW>e@cHd&Wo5-+ zz4L6S^!?g%FZSzmR9?qxt8KNw*>j)^yYxw6o!hZeFvt*wjo4Unil&&(wjP}r_YBkm z&(7u6uIaQn@3elcoHO)T&1w{_-^nP=^L$(!&^z(!SbMG)d#W)lWU25?c{@KaLJ0Rb z@vB%AEYjeg6eCx54;|MnN0`mDJ6=%tKmYS2sN?P9V`B1Lr3>ctHygI@uz$(KU>Bai z?m3`Ma(F%Pu=jdm3&T2j%i?(R6@Q-L!8%*x5)sj1OX1kBnZ@(G-rP-1DPU{$8D04Ot}@rRR=AiJs&(v#2wU`5wm7&7wm zSS(k@2qq~!Rc#K>V8aypr$FT*->KY7$UL_mZKNqJAUGd{RtFEVRAn&<1cl`XiwF0S z;4o}VT5M@^FO6T*F~!SENnq#X#}gu!6rX6TXqQ841Gu?LRx@w@BK9%P@CXW9DYh6?a7N#~!v&&5Mop0gq6Q zd(-lvexs0fGFnNg2*iwA>>K5BMO5o0O@I(n_2NnY77N(hBR#*T6_y*<5+T^XkwH z0i^%h6E{K+v^0}G4e8=09}AR0L8W08J&I=A&*fgJyGkJ^*o-Uw^Z86P!gSkar~-enfzWcWZPa$Ayq-eDu*XBKIDOao_Tow5>})tK4D+-Ik=Xp?@+H^bSU`+j^yc)= z;ekV$Z_30llH5XRYi3$7x;ypA&eP&3SH#-^dNW3p?V`EzefF^;c;>*p0^!9e`!Sc9 zfEF=wyJ7lp#rLiwPIT@r*Q3MN)zxYp`V;n=l+W7im~0NQDT8fuxITVdv1w{sJzav> zhJ{vOV1Qx9VC$cqUm&_|(_dv};U!0vdOw6tlG5xDNr;{6fg5X)(Q?dfr=S;KeG6IW ze|BFtj`{opW?L!%PtI!RMCksZ*ng-<=TkB=r$*Br0Ft!nKs zGm%|FLfw-&-}RT*Ikt&*7%<9YYo$yu{To+FJ|NLtr;vhD(1%~Z716}{lODXREDH8< z%YEXAu)%S|7Buj%WzT@~<40YG@h{4in}2?lZgp^9O*^f;=Dh7StzW2%eG>3&R%sa5 zwU86HAR-J6Ljm;)ET1;R%JJ7Yzk67KrX(dN)vfo+F}8xhpfFq!rW(X481(9u<13Ea ziVj}S<)t3)eb~cYKQYe{Sy;r9lNbnaE!$TevmCDqby%#Pe>1`X#K+!Q>f6hOY0b5G z_q$z4%os@C=Ew{0F31WX3YTZTM5^7%Jzq2U?2dHwMO58Bbou^eB-|^q9JX-mZ+&R# z)ActZMjWqGBaN>zmCA(}I2M6u3kde2UF&B0uMi-CCMx!G%d76vvbmSKa#hLfp;B9z zlNBKEfAvTM@Urp^G-Gq{G=Ly=R(LED5OD&cT+(lC7OXxTK|~BHLG&mlE8bdb_jn9a zaTcVNC}k>YIE(<)DsDjWSKy7RCW`b_CPi}POWAKIzp24)ww|^XL=XH+6jdXkVK2Kb zKt3J35IxPWSQYqXfsTpcVhuA__e!X|{k3@75_TE04C?k#G=8 z9q+i>I>t-%2T-^vTI9ck`8E>d^ng^>oxu*^4>+7}aHnW^c- zmyjldw%zaZ)l5rjV_`w%55O5Z!r2f{=b-CBF88(13v`gH%xyoZwGX)w>>^*QWn>%U3bzkkmQ|7)a^ ziSs;&y^T%gtv`fxu3y%Beo}Ig%%8Qf%n&aq14>hy&G|fy*Q{OKrBZ`a6`EFWr+@a~ z^_YIP#?8V^qCF z!@?{qEh}b+BQL(H&deXXvJ?aU;*k7NVj{MX9{!T2DZWt}5S}02FfTvVV&7EwsqRNu zmX2vVJ>c)od`zB;XYKSUtbHIJyO)K+qVjL^D{@CVhzWRs*q*LWj_ft-`7>R!VCdpv zvn6D)udhXcqvi13{2KniYG=nw&3mtZVPn+~6M1h@ROi+0TT6G)1B%umbIo++6QkC%8vx2nDyiKv_?a13+?&?$1*^lbg)~NW{ zFN&gVCoMTb9z+`g@9 zk8Rg}?vu6n=+mLitiimaS^4*b?lbLAzIK=CPY!-PcTktRrZcZ^zt+$ZmTr6RJnSmL zLVKg~#F-k|md5fzSVTO7o>e?~b8Egc;BvP(__ z+n)wYPMTRbJCh>f?>pDx?st*SM+&9uZ~?GzB0m2uLv!7i8I8rKh5;hDr~|3UN@2it zk?)J}035U9Y!^n>0(F*rABFcR6^LIa%*i=|_F8jhJ_C)0)I1!HA4*9ARTGTPC*vc1 z#W?4*wl6q|YGzx#&Oqy%L9|usX3> zR`Lq}G!vD}D&q7$ZMAdysR9H5qDcap=k+BJ0cB0*gKBj?95EXU+*feVQ!QAfB_+}@ zpKZ1OZeV+E^9gqo2m23P=y9yWi{wq|dc$eI0)v;#SAkLl+X0r&OKzgqk*3_27?eA| zo4^j(RC}us9uClQkmLc_@U0nujx_o1-Uir=%(q{)LRi8S9vTx|S}$tWeAf{4VzoV< z>9cH-^RWK=8SHn=Wy=1K(+m%L1FzR%9skz0tgKI#$6+Y)k`^}qKRPUL_J)P}t(&nU zS}*akc`B%IggQu$#R{LgEiFCIeRMD=~j0ISSQHo;cbv#F|rUP5#dh@c=KhAPHa%*ym z!OOR7w~FyJF|xT^YQ|kiRmLwFS`>>f_s`qd8#B-g=knpJ{o$KG5h@8tjP*JRN;g_J znV>v9Geo&kWI@iL0?;&@GDJUD(9PBe;GKOtTyePQm#x}PiSDMzD;hVvSEiB z^YU{}+DySLKS$S}Cmhz@=CR-3uO&^0iG8Xy`Ck0-d>@-q=&Fjl0wN0J0dk zvp+|uAsg5+F*mM;G%w_2eHVp3w44atR_S$Eyga&~ggt&=0%I!sY|v8bX-9k5`@_sN zOY^*JdP3pW!yvZf_&{lGy9SnGlNL3v*OnaPGLdyM9pC;PB7II(@Tq9CORaHK%He1( zLQH><8ms)_YX6@ejKuCq#|&VcyOP*ATF%i3?snR1^~A_OyGk96U-_ugzd9}2g98xn z)tH{>U^oXx@6Lv&ry-+fIu;}O#3Gu~LfXdJm`=|P0f`XV?m^bk?$k6~G~&9MnWGq` z`fb)I0w+|=<4F=A1{HdGcryPNL7h?(k7cL)7YXfajd*uOLQ9=)dUv^|EH^y-M$IBi z9+}B9xFL(``LtEiCb}`)T5h>)YFt2n4rVg8JRUrJ1PwMY=N-n^qz1c6I2~N(DLa)x zFTaU)aMwe&SFo`*>T|qoU_PYWrCRrZc4`T`PdCdMmmw-Dik+J@S<|p>5#;pVlRdfnN!Pwy>VNK)XFHy=98}KzAcR-IU~irAy`cc-#s=yy0%|CDMPbz`NX}D3iYRo zw|usGE*}rC4fw=eDE52lbfiSczaT1nAjq9}qN5PoLcWhg2n!4a850@o$*FV{ckFW2=P_qG~odp>7vb8`I*XTTn@Ha_Sd zb!`Cf<1auYJUzaIIDSab;GtE!*e@VwfmQOF{Hz{mpKar>vYQW__a8!;?X9%aXn>?R zkWQzr6OW4B7g<8vt0wK~Ez&JT?S6s>Xjo=^J62`svHwztlR#9lvUQw+!<|zGAxp*en%9*Nlzsy(N17T;oz~aawCL9%WXS7I zt4m$#ZCIZ^KAF6Eoqap1fp%P6_thg+I%+NZbT-0Hd0-#wz5Urmn{8Zqr?uRVvQDkzpwsj2mCLuqiXMm#wz<^ z57|g~3Qng z;7Wb&)%IT1>|Jilp||q;g-?s5B?DnvjFTf3ak<=yd;_s01zH(RZV ziPClN^NY%AR{Y2iixvUVH7&*&_z+{_kKC{?05x!GmDMd4r*_^s9ZeYEG>$Hr8z!l< zE76G`174W)H*gv0QLpDl$-6%tT>4~OHaxDah6I2^>lwV`!i3oxZlH)anLbkiF2av{ zzi}@3bG2ENxwFlbW}WnR+^xOcW50iTFnW%k5Co40Tg+O8Hs*Wcs*WmuB z^Pw$fFWc=%kN0KP$oKTHvbycEA}jl+1T_t_zRS%g*zo7&Iq$7+aNnw9EquFqZC}uR z9Y&wFt%gc@vLwu?>v?qB?ZNsWmU~#o-tNolPE#6@$%$0w+T?Il!wEg=z6g-A4Y$@+ z9)+;b{%h1c^=3zBn@4CLn*|hW_{@C^;pr}}D&2~2dHixyp?a2Be_kGP;X22{R&cT4lgfNLSbhnS4*=B{eKcq4_S3iV6pm z!;j2oL=5>dni>ue&%T#j;&8U&Qpg#ra*4XSne(wVv%*INhKCdG?$wO~;ebK1nI+S! z2ND{@jPoT7*k4Cxn@~uK#SFjSwv+Iwl z)V@{w((P=5j{zi%2ml(?aO+g-b=tmI^@jZrYDUbj8qU^*%LGXQx7nY{`8h7L@qlS= ze_)Mg0xCF8AgHFY6_qo9lasbbZMXHBaHF|*yh@TM3I|AtkIXWR&W;gCwEsykZ5ur6 zy{!-%!!3O1a0ZstX>Ev_!oUN;Y3v^3Lbgx8|qOgO=Fc5F^eF1A=#O3JgOn80;H5ffFWGb0%TXtR)pHU2w>F2mJg8TbJvvPEl zZ7tXdZD{~iCP~F|b2g1+V}$U(lajgL75T=g;J^cmGcq!BZyM&cD(?f&vOgCD$g=eH zpNctJ-L3iRR_cOp8}nLcr(tEd$LTU(&Ijz!kV#VSp<<%D*<09z-{{9?U!MfETw?h_ z$qtr5O9|$FvdJ>M-of(%;uDX;A9ua2QAv|`PyIJBO*!SYH7;hSwK7d7 zUd|RHv@9HLHda>c`Uf0eh4bB8)L01>jSLC!rrI}>vKHwd$f^MC#u_d1%} zA+(%xy<}_eJcp#p&o4a1$9YZ$+w9Hrx;$t*h4KyU*72Xvua+N_ufG+Fy~K51W%bPN z2gQ)>mOp2`U0iiOU-);}&qiWH?;4dD>iZ@8WZ_ivS50USIcQM>@;+2#l$^knv%e~g zP;0zK#?lP^Z(d*8PG5IF$7s&i%)E!5{rUAPp?3B~c!TiFVPEZScJE77`o0+bRJI9= zE0BbY<7<-?eZ(}#8r*tg$MjBD>Fb5gtKo?7#RKZo(3kCfYa>a?Y$_|YQOp3=?$L1p zQxcqjKeYf_c#{bSEI^QsMFLtNej;Zi9=s$K-IrE+>)F6Rv^AZA`?fV-9ZIcjJ}Pnd z^okP`o4Vx(QC)vF>J|8A%EtK3;`hq5VN5_kTs|Ud1_{~%V;WTg>MtS_H%^K3B2&RA zrzX>-o8M~Z!eC)K8lXxUzKt;)B0ws*pPG4HX4;4X#+Bf5DqXE^`fda34Pp|)R^_y( zawP)oN$WQaD}LU(rk0=_h4qJqwK@$HH|kcwVc>e|S{G|p>;JW<$G~v2AjGc1OIrFF zhFzrtk!JbIh)8$?MUd%dkd_czsXYqd7_r@G zC9;SF@SB!v2E??>z~;Vl9xL zmWpn$pBfKT19`X*JsfFmAHIyOp&7A63O0TDP-IzfW_`^V6c7zFPzhpGkRuU!M~PUL zh7jlIie;?-u?Yixr|^ajR$KFPNc?yAY}5GskB`1^Ec|7+ys>)t*_4}OdnmwB0Nl@8 zZP)~B)x0htctbBcR#*RhVDf^;eS`_zZ(fJ49o}vs;2P}IZici~&~LAX=ebI)y=Bn2 zb(H3Hd0xwY)9Vp-T3!O|QJ6pT6>$&xpT2(R!Kh_oOd164Hk?UF)h-CgyANpZw58s|^I&Gg=G-)#@JOcBWE9R#3Z<)y0W@sBcZKXkXyAaNt{F?z4v6OjRmRc0ELBw|1IHl(gdmmrjbZkCfR3F2ls(ggf$}N0)d52W$}ne zk_Znw&`6}L{u}$sm_$vjWbtN8H5r&TMphQlL^c_LW&kzcS8M|sIE>1lo0p-NZQwZ0 zHp&rBZP`~$7?YpRZ~0vs@T;`6)H2+utTQgDN}DkZt~LNNenl%bQ!Gz?X>1Rb!xAC5 z#m0)q1U-_dlPjUw`Q5wtqXVu3773_;gws5v14!J{cjx&cCJk6VM;wiw;;z`KKqy13BS8(a6`J* zwksT5fa>7KQaQp9W8i}-HJv2zz#T?(@!ffMdysl+(f>j2&@Uzuh^VM99P@#7C?eS`pt<%KDM%V6` zGJaHF6gzY>Gvv4Sn&UVU0EQA*8|HEsJgNOtdtqz?S%SR@c#s*gTRM)oB|iQi&rYXZw`}DBY`5oR@#y?QZbs8@Kow9T zkDR1h(t&K)@+w~#o=2JP(aZJty?-Y9~IK#$fkwP!cJWMWCA&TW_JM zVNdJsB|HHvm(CV=DLmlh%7v{XQtLTVVv;mJGm}AAyO%0#)M5x#8J#q&KA?~;k~Ihi0PaH5w{_dFrD9=?_>@Q$$d2ETWu2Q& z4v0pg`6C-3iN;Jtffu5xF`a8QKoDhxM8NDS8wG)ZtQE&vbcq$eq-p~~?8xVtQ@+rf zZmSehruGfBv{Gv<8_3P+1RzNTAi=C0*a|u8@;M_J@#_dlR7la5LV!}lAb>Uq?zk=_ z4_!MCx6MO@-aVugVQ|I;0SPq_5RXX8hoz{~W=flD2tW*00R$$Htus%d*2=&ELRP{p zh?2F=W3DY%moY-R_xG(HzbMGb$$28g{E6+j?~iWwetEQEc{~%dUUWh!$@Cg#DM)wY z;P+f)lDRdwih?w~dQ~3RzN#X|w%toBIN$A*LN~|R3(E;Rh!Z;7Yj*OBt);t@@$dH+ zSvXp@pd_pMu@Cz<9{xMm4d!b9JFnVB!(PLce^j6RPs(08-IpCiJs)!3(i{8p5YYSH zNq|0x%D{GsC5uk)J&>Hd#=uP>ZVg&`49uwQ9iDO)gcU zi4ERy{#5n#XjXUiuKf#;xKW;IqDO+-AtTTC_MtS_k3KSKM}d&i>Au4AYIntF%1ZgL9{4WZ&W}Y3oqd}7- zgMwd=F2}`*UMiZ)^h@_4yBIl@v2Y~RRaQBFb!p)=neDyt1lf&4I!x3XRciXVoI2>) z0!iZ-NX(s`x7Zv6ymqou?UxwOM6YVv8?nS39iAsDb(eLqbKiCy{I*?sehMiRw;rYH z>gj5(za3$>`!D8rtU|tRw(q9Sd4cI^GNPAfV19(x&G7(9Utfw4i8*Ya@U7il2@mLf zrCV0&*wOw8bEB(An6X{-jlRQJ3E1Ye1>`0q zVVvFiY#+7I3;cfkG;5W+&HG>~WZu9-!Oi)%hEgMVS%qY2ZS@mh+E^@^Uh4p>-qh^$ z^p+PEPx3qo`ctl8liI>s1{YaI0}y>y5&T|2C(e-9@VQTWfduZT6a0@dKlbd#V47?i zbem=<1qZ}ss6}IDsSG~)Y1j1$P{<3&TWPqr>h9&Ne0!Uti^dxXPbkbDnvyJm*!uX4-U%1$6C!`3 z`cdUjcBPzQ%`<=W|PB3^ec&< zHFP1@+5-I3I$wXevd1V9^xH-ZC+4BYC_PdeA*GRR^$|mhc11t} zz+AV~L9#ju$m*%FD|SALVVcKOX3bRop&~?FbxJHL(lt zHA_J&r$Xf)I;4Tp6O>A9wp-gw7ELX{~njzEYn+z{w+2lXZqjq|Dt9tvNO9K{8P+(a_h~@eZ(oR zxpe0&#ymU=pI)x7V#sfE~iA*ZVdN0Q=}3GP6| zkynd;iGKAx2}jyQFFh0f$DW=WX|=syzi@1In3(aMi{&Ajm3#y))pHL%_9JtzkRv`) z+pERn_7;~|!OL)6{+ad8lajpk#Ea#al+)_*78jyuOoxH-kbDZb6qld+ED-5JG8q)3 zK?wbgqtyU!CmU?*^C~G&cRCRVgU#42TVFBV=_`3l06x&g0RiwEwvJLYQ&Blf_(-#O?Rp@whf*c-^wZ zNv?AvJ=wQ+^PF&89r%xA(;b93Z?74N`zrND8CW za9w`>=U#w30)n1G*EcpjTB`^|w7+MnVRs4GYv1PQ6JxTk2Y< z;29oXrQP^NLbHJj7dtMNvAd)!KAnFM-}I-`m<>32o30i~D)z|Tt>NR~`MzW_9U*mu zNfPnSz8x@`1r6sP#ehdC#TyA?JP8{D>XHH6(J14VH6SXy05O<4mVcXu_cD)CFbfmFJ)P^Z!=c(F69!X-cj>ngi>Vd zPbmu2?`2v@rm_wDRW&ncyvgsl-v}x`x{0HR-)ZI4X(E1_m#3NI8@U3j?Ow-M=G{EFjJ8sAHJ&4CZIWHSpf$i)fnf zzrXLoZ5+Qjx;Ef{P#Q(9A_gWDaS#4vG^ZXWDrVZ-je;oJO7nGa@-5(&?Nrm)Np7O| z_XE{<2d!uZZhVSa%m=>z1t0>d)AE)plOpQut?wwVlS$HiqEm*-=*y&p#)@)V_e9_L zus>Ml7}Jn}=J2k$TRdGX#}@B4-o;fZu|^dz!)t6EsG~zJtpK>Ev3}hW1>Bf8iPW6d3^#K2a zs$qw$?+>fyYJOyPe{?}qwj>~G8ywt>)*tY7EC#%F0B2eqUMe6QO%PS0)wd5OX!zVz z2%J=SXtY2K_@Bfka5xx%pfZuV(7oYf2)zn$ei)f z^EtUm8mW-kA_MBwNOClIn8v_%Y_<8?l8y#DNa7lq4U7P7a58r_o-`NFr&{6w$zIN| zR09d{C!4T>W($Fc#uVA9VY};nXyAMrgf5&oXkmJpVa(|HSW>t2e9(q2g-txg+psNr7 z1BmkQ+(?JFqMkbc9O%FL#_S-Z^g?YN_CnF)3+B%F0@hT>qWSM;-3;l8J*rE2Pn1Kg zG%tEeYqV?gKYcGw7DEp^S$3P8ip@G*f9}xBtqkFSG~iGLY_mg$GWSnwa&EjtVUFdm zwAjKoi2*lP%JK+v>S~5&7uhA|zHAdvPTr0_s?xE<|DDSLny+)}h6t(bZHMbC5&jPk zX)?BKo%QD{5A$$E!;fT`w&u2PpkiF4z~!lxO@UxpRI->07Ool-2c5jS9#Lh@~+1dQU9?Q^f^p@t7mGi~Y_wS#S%cA$B z-w(12BS}Kcta$`C9Mk%*e-;XbHHIwnK|C7e2A-K^tA@+Eee|-hR=h+$(xWkeg*rcL zQ!5GAw;)rkUM1Oeh>~QzpY7dpcXh9?H7&k$T){QV*=B#)lh3wmd+7Xr-<|0lS~+%m zUhJ@DJzJdj97gH$Yv*FXfe+YU`_!AH+{nYW)V$f^>TE)QP-)Xpt97AGk;QBg5y!E@|L)yRWu8}WaG&;;ivevxr zLnxaapEepf-lo@$-9E-8jrA30d||JcH?>U+hf|p^O!$LS!!*CR>U(>@FqgQ5fGyl& z+|xQ#yJQg$v%1+`(k(!;xGuNxTb&eV+4FG42LzPBYae`o=MCDk#x=ED<)nTPVu8pf z+RoL?gxfWNuEY`qb0bf^Lv#wfOxW-e=CD5E8q-P>mq@9@!NW_6i%TL(+Wp&*M%ou- zhcBSP!8Z$8qM?mY!-7XeL)9VtO%p_87h_&q7C=6;WRCOAiJXtiNdtqg^Y_mP3azHb zPe}?8F9_k+*0dk%Q&cH$@@#ZC^2Ut1S8GD}nv8>x?03&JwQA(k=_ zs-A~HXwga>MB=G)UG1EVtoQg2SBt|udnNz)p_E#ILuJMJFSJ|vKVniF;A5LphVpYj zKIPa%mG&@}jekgfE-8nYuJdxONm>3zLjrAU3%7$naU-AWkwc>d!X|tuDZht={7L)s zCL}ed@$u6Z@R=tahOFNFmjQetui7mZOTimThE&e zJ@Jpf-jk9Cb$6X& z_D#^z{?Z)XyCNgo7<|dw8^=#qvV0Cc=p7~x-o0c9dcC0WzNrbGyGM~I!ERy4N1FLv zD;#>rO{`<b`7ZvZ=!w)`%g7 zAK(Lv#P| zQ4v?ip%-$Cz)i^vPhFCYv(!M{n-S_seG9B;#9^|6gYR=B+VPvzMIj7Ph`=*%uBvJ- z5-VU+PE=0YkszR*-&kASC?t)emn$m9Uu0=BDpa2s7-IYc5M~xmS@NXOxaE{124Jo) zoO_B*2IXmE{kMLx>Zy2M_3`*4t`;D9%uvD@&ioF~W5j8X06=mkM(!+)A0$^4?&;$$aP;Y{JPgEOiI% z{ZQ5N*TphXta-azUB!N!Zf)igmE?bM;pxAJq|Gb|wL8p3tjmR>rz!t~x%m6CoI2$G zi!!m-zhvI)mnRL=i3tg9)oZh}vl|;-0gqRfi30oI!{5&deq;5M8E|{y3%=$9xdQW- zyEM{n5!n!+DLs0RcT)QSk8)s>WsTKq-8nakF08Ecmm~X{78>ZjTEWYr5*!5jM5Z)n z$U$e#_vD8%{%nw+jn$lwRPw(hLXPUSF73*I6Y$n0kp@1dSFrnLbLJcJC`5@9YCayL zhu3LV%ME>%Wh>sl^O`#POHM{+*izS{nT^(8TU7N4{B08c{f}BuXc3t>O!IsG{IcvB zH_|Fk3rAigamv(7<6#((4L&^WLN!hsF2m~Wh5_AY%)nu?XamwO9K3N=EUGEA*Za3a zZkz)8UZfir?}N@(Jac)S^qY>prm6{g2Uy%Ro33*U*o;)1F9%U@uiWjQ*_@I8thHtE z01=60#q98pG)+xE(_b$7QM!}rf~_ohu$bqHD>=vwkBO~`2F&}TkdQ0TU?fBjxL~eY z(2e+x(q};Zv)>hx4(P4ez%nOddG#&dg8w?K~6-30ULbUuF|sQcATr* z9Xn`{SP$x_k-GKkYQOI{}CTqH)6kIM_Y!#YIfJOg$H#z%3#ppz;+I@{6f9~Y7Rz1O=FHh|u zMRoMB)O`vTZTPQ{n9&XCvux^D7ACRRt9$Hm(;=(3X;K(fG|XfW5+#*2ET2Nkz%rv^ zJc111#G$nSDKUmfQldj)HRT=Cc@XvM5F8$=;gW&oVG!~UZprk}S@T*nw28`yLDlk= z7z+tByHi+q3mj?9kUrLla3NWgNnmF2JY<2#gt%@9MO>3z>f|s$mS%{OHiPx69ZhTq z#5rn!I!y*s28M=EoQe`PLyr*Mb;r4Bgw+uXD;{BRP9EkxZ?l);1)hzWMxvIZ(}$!) zhNjWb-=}1QkluMu)s)uiuMUe>56iB+xj0({v1zn!r26=Bse2>3qD=DG?_v20T;7r9 zvo7jkBYspy8^A;+mZSrTQ`&`r3_Di0TTRL{^&Dvx5LqcH!>Hwz7qzz~>)2vx{#(Ai zR>b;98FRo`_Lc05lvWZ9VSIV!#~ph_%$Y^nIsGM=tip1*6YQmAB33>}l&_d*sj$8r zT~FF6x5i_w%BXu`AHRL-y7bG$cu8x0kACi*1(_v*+1EOHsvbB>@QWxTN2Tsqc+hn~ zn1=s4oMSMl%XJx&&9;Ar2Bc}+{FL133L%o@$wxIiGw$hKYUwyN$Bw($2d2F zhOaHr?U&fhB7Oh+khI}C-1F_}=?R!;SWP$2es8$k{MlKsPeEY?l|s;IP{uTfV@(hx z|Dwma=k$w<5%_yyUv}^9Piq_AFuW* zbgG{2T6(&oOC~GE{+1P(FyeLtKktefc0DRD0|x$foVBx@zGw2M`&ZCdZnhl-_joKq zyU*@|p?5R~Cr#pY){|{6J+4Y6$GRk2DZEQ02-2T5;J(nQOH*?&E<#qhD_WE=E7Qq@ z-VHH~9Yb6^MTRlfeH%LB9$`U>nl&UOazDr%KkUbR#$`x^46R!5=CbU|NLONwe6JpK z!yXpb{JC^wxhdV?4pX~IEQj)I(Le+(bwoKMN_HqAhEfx3*sX)n&*+wJF^(bnkn4Ze zMu8MNwN8aU}o4mgdNo-C>!(40Csrl+&KllUHBE>It(l61|7z4g4 zL_rzX27Wz4W&2luhd-6N5!;ee(7-4kOS*?7_ToH5Brm>pg(y;m-V%BA)9Pf467SZ^ z>YeVn*k$ID&OW>75d-wCDs*<1R6t~dtorz@$9-_4r}I3+@XXHs@$TJ}fKYk*0h=jq z?J!&0U2=ZO11FZay_FC8qiKNQ@4y18oYEJuV(ItPIc^ zj68$Q1;P&LcO+yB1;xtPV8h9RSm}rK>X5&OV3#B(>l2@+%vpK5*Td6RpSO1BvRI+Z zY3O|!_F^P3TEa2IHv=bQDhM!A|45d{jf0iI$HeE5jzH^;5jchApv_26l(2_^{Q^q# zN{H2?2IJvqNj=aZNGFyiCYFvC(z;&LzzL=B>rhtjFornta&d5o^72;Si0k@CFAq!u zi>Vwf%r4hK3QSdc5ou>fM~>$a235@-2kKQO=tb@49ghK)78|gbKN7Z=y*7Wt)6a`?hD z#LH-GdJ5|bM2v(`Y9TKn2&-c;DE1;HFY}jHHn2RHj*?#&X2i(fMDQ(H4w4Jcxwjn6t@C&L*m(tW%P7c%|L*I8VT1u2lY?Jc%xF zSHuS&Qa?PS#Ugl}g%BLLjV%X7?niNH+sn{W6X8+71|6QAi9Q_`*-qvxuCEJoa$eoc ztBC<^jEfFUMjxWhvrL#k%dKuZ-@G@GK|NIxn00loY)D~zM~&Zq^az_5SiaBle8gC) z)Q8UL`@_HpzipEw#F{c>FHMU+Gi=6X9v<3~HBfeGXldS!rL?ISJ7tF^uioI3EX~^h zFOaUWvGL~a?rq8f*xwG3ct>_KZu-WF)(`dH>!_-7dRp=`HQfRRV1g)fC#Sv%-6z@6 zFU-zLG~O4MLY~;)w%N%8E`BfR=)4P=nwrYU$XL1~gw&Wq|HBCOnatrSDk`#1l3!5@ zR>-B?yY0<(@rVBV2O*0NzVP=xY0K0;)e3go);A?(XE0gSaY4#*YSICQsk8Q(qa(0I zw8guq{2E#O{OMm`VJti6LgKMJXYe5+wGJM zmGUJ7R`JY0;(L@o6qE_uSB%sdci}8s&PmTE_FAOV&!+Ciq}#;L>`FNGtD-EJ7hUaq z`V1g(IXTzehE`zNVTNtS{JgxE^J5oSP|3pY=o2n))taJP%OsJhzC^Fp{GNXBx6_ts z@*&9y`gvSnB6lMY*J7z?QwgPMAoPqyJ5AKMp7i068}2aHa?Hgd&A`6fehFoWOTZZf zT;o!}^(^Az3myt*{6MFnURBOkva2%wG-dFl;B9fST4Ms)*qC2jx&0579Vu+PROQus z!(F$}IZPGWJQ+%{i?VW7?OWyKG%<8bDz@Xh%EtRHb!RUeL)2&RDxA5gE}Go$kOKNQ z4pPdpDwy-(Z3M~{JZqumGb-B9?TwgGP53`Az;(Zql#EOo;Yb?wDI)zZ8xg*X!%3yB zmtGnG#)QPqPR1y_MyP@V&)%_=%nd9TBQ<+Bqn#0sS-rx&511c&y*IvJ&*;#FI()Vw z{dILBr51Xz&3ArX!64V5X1mrQm?#=hu7jdM1;RX=PhA0&gW{YSrO$1mqWHCxRMaEN zaF3Z&YLi(LkH%s56R`6iZrGvK+7iKZNNRL=1d=e$NZ%Ec^Pn#D!m|0%o!^SC3N)45KeG_Gsf4rHF6KIe5=M_v!-|TT67Fe`?pL60- ziW%EFAVHtsziN4J{lDBSv0?gc)GkwKZ|O=iV-nnUv*D7nlnzZL7blFOc=_{=r2eT) z^tN0r=qfdFXM$DzLuL(-xts^xcVs1InG#800#lLz(jj@X`GkO7_$A{VU-0petwW*j z=sEB~+h_^eEj2ZHtX_KIS9_=kgdQh)&a>Nk?!GtP%-)PqC0n+IhZcQqtPC2e0j@YYrv@`!X~sMur>*TIck^VkgY$%v0lTg^75FgA{TO#F|x z6-%@k_wkryVu-mPPQOW1nOIg6=ZgJz%7C5}(X#dSI;!~4HXZy{KQ4*`8QT7+3UAY5 zGi#Sh30oU-j2YWXJl*xDa}y5Z^|!95E-?>|WoovgcpSI72--WZMBKQx!cYy&g=&X0 zJJH>kaENG=^G@lc1}>dK>)m6*_`M;qPRi&vAc0!1wOA3}x`z>$&MVzUVp^gd(kvF= z-kMJJoesGYp_#gm_uB#!`Z2daO=9FNdO={hQ)~gOtkSNxHma{Eu`!a8vq+3Use>l1 zIwYZ!wctp~&>LT=7q9dI6iNpJUo->yh*iWrpp}l9BIyo73ehKBl2Fniq?C|`v8i)R zmf%-ztZ33vtQepTiJ_%-q#+{8XT|M=l_FdU&U+dS`qhTth5_3jk?OjyHWx75)9;YGF3}w4jYd zI|?n`o;AONwfBb|Z5vv3!gEE-3{B0uFinTOvGmi^Q($q4n(*a-v%jH%K?a*)#-xp$ ztZcsDQ8|C&mq80}Z|^!iv@o;L6gm)K<(xjh`%razwKopbGO4sHKn_%@lAA?@bujg9 zZGJu#I95(>sm9dwL#F8{mY0{;2gBz0nEarpzrTO~9+F-1Bw#mL-`so;67oJX0%q56 zO$(RPDP?^2_BI6HuXh|jf5T@pprt;BR0#peUxCkdtY6^Rx&`p$K*U;f@C06Qq@?+H z1{?4jU^D{VYNNmWQ^1S~?~`R1kOU^HLF3P^E|J6?;Mvegc)3O8!CkKZ^@WDQSWW=7 zGSFMc>$182b2oj5f2uDMwWGZq)6LG#?sT;&LFNYlJ}%rR6MfhFlTrf&CO!ZQHJuL} zE;;P>^!!{9{Ps9R)zsYF+|p8G+yQ*`zT6&Mbh!O5n!=>nQQy{;uwjk&nfgdPB_SRpdZWba8NSVA{Wq%!7p=aCg+MG){_h60mfH^!JvPTI6yF^av=y zk!$z!7c5kmi^L8qeu9q~AR;LsBqyIC*YCe3xZzLStPA|fZJy@k{5;t2y?z&S+@_Ry z=5ZyY+DLuB>Fx6O@36>LSBqGK%2C05qhf){T9CUoCJQmb77z8_+2j-9rg0kPS>?(fs1C4wrfHsk!v3QK&m-g@JKkcaR7iD>vfFkvkB;Iw1< z2e9dyB*@RBBy3jtZ}MW&Lw?J{9b-S>33>* zAcu~kAkB%Ws@j;3p?aEt2b&JQ&H{Oc-vG-Tdyx){>YJ03E+ucA15JM_&YFmr9rJD# z&x8()e>XuUE0qI+g?=)v!bw{wHKsYd8>yU7brUi+oO}~7B5`JQfN*1BVVA#q$G(0* z$G|WrC%3`P@m;hWPzTjCjX~mPgGAg|?Z+(!kv?KEOJWg`5mo4QnEeg|)@`GJVm<*0 zrcKQDS2V#x%w$Pg?J>6or~Go;p(t4*>6BvZp@^S>JqDZ_ZTYudVKrF2-s%i)lFXK& z2*_xJ5;^}Nidj!|D_IQ_bmaA-r5k%q2B08Oql`6Pbsvi*cV&(8aVjfYTNhB3>{LH# z1+iE-oBxFxUq7vYLk+JDMuI?ZYyqVQ3=LSP6anywCYHD0; z9)Yo*TW-T-Yb`F`#@>s+J`I!mpSXCiI4M&=pO$(yfmr(I4<+^8%?+vB0M_$q%a#eM zAs8rO;Xq_$WDT~{h#?6ie4Bp9RYG1TuEyTL=rM+TpKa%|kNo`0TU$LI2Wh=83tDRE z7#M2jr)Ou*0jZqVJ4s@q4f`UoKMr+!o)(LeLsv9f5K1 zlCD~?%F`@QOO0WRr^S;s#{rr5%*o9qpkG|kKs~maA4vFwuPx+MReAut>Amj!!rt8q zyc4djGxx8ls)F`rW@dipmp~%AYF`#<&d~v3zel^Zxc$ zA1nqW(LlH7W~VR3(@b>SpoQhj33!Kls z$F#`(m7LFEVKg~#)!^XZ*x1-?^L_XK4MuuL?h_L8q36XNe0q5JQ}b6>SK#yAX{KqA zZK{uw% z?DBHfaXWBv0W|9X_Lc#tWW||j4#p3i|?zS-#jcm=@u1DBmx zM#J0tJ_?p8k@`W_%iTmTR!a>~i{mHC*dMhgFCv+Mi)*-j?(futpH z<&)bgrHgdRz{1gNSX%=!Q=CN=ZrlbZu=VOMfCFK ziE@WMpHHYdI*9(zacS45`+yO)1Qr`SlAS)OKO}SQm(T>;8t7_e;TR_1>^#-d__@`D zJ{J}7-Mjh~N5aVbbHuOSWWyM+HO{hfQAIjP$G3NqA`%&r!Wx=Q4)njSq}#gpB4M!H zL>3npGe)iWTsBM75JS;P_=29G&p)V-PEWi4gmDQ^>o@GjK9l>@R<)Is@5P#mxT@*u z-iJMY*`F|GoT$#6w&JARZf>-%cBpqF%~rS9ZKxf0#-&eZEY}S&(3S&t`wmJ(S1z+F zZ2P;sQK2V_cpi($<$EcYG99$;w&tPAGqvdCVx}Y1Cf*6zPI`Z~Iq20B;Upu|NE@hd zX%kS8y+&ZnOtH=P_X}|U-qtpV@shgrn3b$7H`0D)9`I{ zN+CpPDJvefLivU@x(9cjCO(&@nGDR(zzuZ6<}P*S>`Q-dTz}i!siVM)Obn6Q{a9cx$&t zFFbqd1Y(4cI-MkNQ%n{t!%Rrn2^I(xMlCK)IScy}nd}rnKSCB8808`BND9`qS1C3^ zi2I$QiH47b$B#6i*j9{_m>nS_@B^KY55!_M$oU1vYQHuIM1>`wiYbdPAHG~m?y^x& z7HV7|*kKr3to!p zXIEJc8H+8qKmD#b$!7d>bTMYvUx%~@HDoM(b@{>T6drDo3ft_Gh*TOJ|IzTY{q!`_ z>ohT83B*>fk}~2JC|;4Km7hhsXC+e5$V=Jn^;JG)!24VNnHPBC;g2h+ZbGtV*M2)O zX$z-G4Yd_)&EX@2co=0aEmKI(nO0=W+Li?rwmdS(L_H&)@?I6lztBL2f31ruDw5R#!`{)$x+$m}qBBVN@t9bHHH2r+G zcJIqmFgho)?yiOyT|nzR43|0W!W zZ!5qJ7>Ag{sebTvD*t>9sRLG(I%nmh3T4p3cP53o&r;pGeO&;3 znVFe!?r87m=y@1q|EC*$1MD*482LaB@Bhv4{P3`KFT?OX5Mgysbp-Y&yPl_99$$Ep zMC#1%E9-tP)DdjCF5#7RKXut3Pi0Eqesi}fIQV%(l?nh`-e>8pPkbWa$3ce8%gmRX z#BsHMVwiQ#ysA*u|JTA+0j4@3rVJ>dkQwr3M(*k@2IGK2=XyWa$U5F8Q7y$R^PRre{}i}ypXU_Bo@SF8Arx;H(Z)-!>j$DOp2s?%5t{~pC*nGuuxSW> zZV3jQ1(!9@r<&K-*Jx6AB#>p)mKz@9S1=5fiiFd}nd+C4- z?{0iQrvywPo!}A!Zis-}3e#`zQB3QtMr8<$KLhacFM&x=OcXr&Sy9vdR5wfx7vkNy zLspjOJ_ZzW6n=+=x;~!OU3aSha#eFYoE#lJJq(Kl4H4NI0oVy}SfW=WH1}J<(7(Ul zi`=MBU!V0r-+-IqFW`K5`j-Fs4xTJ)^G<3Ppzezw7zgmhFP|PLx`T6^k5OB~T{Ofe^R8kx6hXzcI#;|9ji}^kR z`{^e}?RPrgVlA(CwMdfqg$vMOmpnn@V3*&O`PGn8cRHgExADV6=|3IsKA2`uVMk2e z;Y*?&|HlR9Q@Qg3Ow6E?rY7|C_W{uY^t96EGu3hvCqF=f4efwq$3T*++xIw1^2>X0 zx28;37Nx6a<={KBCC>zo?V|wj7m`n5o!YSVLm7_i+DJy4bTmyfl;U~I{B_~sG%=Qx zGqVt*sz}JH@*g;H=pC8qQ;W;Qw~fH5m9m!R=96WPT2I5^E(3~Xffytj8fbJEUsA&l z{(ERa*)KnV=M&WaTBI0CLTz<*HwpbTR>0@irXMuB&Kh)`;Ai}!O@W(!Kj+Z%(LTi` zr9z)4DAi6I6JV=L|MXFh&j?;;#m_ zBnz9e@hCsit``hC8kn!wZ&^EM5%k@dtuE$szW6HH4NR7;-WzcYnd7dY^ECjM!3AZD;$fppGd&d~2j0Ru|#qF0RVhI+~r5 z|Dl~+j)=$6DxQN1Nu5g_L@e$x6BF^12=luQJpr0VsCySS987OA2?#BjP#zJ4(vJy- z9h^1$9$N@+HIkN+2V<%1P!)@*fn$eY5KizAGx0G?^QU!h2;7hJ2dC#%w(*}8YQ&_% zTb@eQn7eJ#R?pqCh{<|{imGS=j24BT+ThK^6;tU;(shg!5OUz>rE|FT5f93(m=6Dr z7r%Z_t3?MzN+YEd&f&@$aZw^0c+le@cO3F7GRx$r$v9tp7SwWop;V8**5({U&=q8g zkjX*9<;sdwW~!`G!+Z>E6At+^kv2AO1q&}vNrxN`XFnAWTr-yz_!LbAki|&IcRg1^ z0qPP*p(*}rTCG1*85*USECFyJ#T(f zTanDZe|kfSxNIEPTRBMMzVW+RNJ;g-y*>lLwg}|s0Qr0Ee}9HPxKHDIT-5?VQ(S zcwz}~UP6vnzZ<4SJN#}Pq)7$bcSn+Gie~K$4c8!5h7BtxW9ckq%Gve6@6!z4hKp&x zt~A)P8#c3&Cq>Ja9xv6LpPp{?1ViaEjp_l=o-LA#K36W$WXN-sba8Q^PlXAgl8Qod zvjbJNw?7dE;XVVfuP<O?2GjUk?s5J9`_J~QvE&RpX%n6sSIi+4K^xv zr&7`$`xDv1zV59@KfZie1x{$a%|mKWD06%g5Mpz{)%JFFjE40TqeQlO$;$K;zPrg+ z3+(}-6z$y@+zIUIim3Rkt#_+n;NkD*w^)A#JPDUoSofTh7K&-gB`i#Z&F%I(Nzx8agJdAX}Ne9`nQes zx>|4=@6A?A1HwW&tXq~WP`NvQ5Y+OcvPbs+bHeu@(x9zkh?%vk?4&3c6>43i>CWPx!W%R_T(Q@>no9SiiH? zS8FZYY`7N&JLUqjjY`X&#kI6jH3zbtWWX>Wtkl?6$m%8BxQfGs^!kq-pCH>RO?537 zZ@*LY*od7rx@k7t&M+n78P8WZKN?tY`x~#lYu2pAk9nhTbZtxyD2mo z=?Ogl4xv!F`*UxQN;Hu^i{EM276bcohf^w*;~FpP8gJ{?Vrml&seGocNLiGCCF*dB?C<8pTcU+V8(+u7DO^LY{{|Lc+zF^hrPq`;f`7+ESqN$wm& zVnRz@Xw5M@^n@q>;N{`%9bad+=kU;L;NPwSXrE{K>JU=Pn!g{(kJ~^xF*=9zIQ{zX zcs88bKI@g$<-z8c6kE$(M<=%|(_+w01st)~qEiqI`mgep4zMY=g~~&(LVt7-$rMgn7i2HCk!ea<6Lu-U(kf&mMo2lD0XR-6JFaq|T-`m%=S#v0X z2ttI>)FATkKVf1y#9_G!xh#-jPvM>a*i#X5Va0I$i4l*-4CU7vLB_2Mp~6fdpp1n4 zcSwRrvjC$Y^SwzEtx>1@0ET9Fl@qPxRh$YNv3tFz$Jn8OOHoJW_((I+@aX7>QyEd7 z8b^8u{{XYWsRSmONd*+2Mh`m&lR9@v1Sf-HGz=%crOOzCMBAV7pOl1RkG3>u;G?$T zs5qx8$jJWGPX=V3Rj1ARx7ArRQzk9)#}0pWN^vZFv?SAkZ!z~uv$56^{P#5Nh`w3` zDai8r`i!t1&S&yNMtqcNB3pR1|9Js+n25MBh%Jc1s2(KDkhC1OdwDoY;bv${rV)@n z0E|OshZJ;}moA0x}8&aU9@TiD?1y@1^d$CijskAXe7^n6w0V1OZt| z7@&A;r}BJv_o0^*&}7Aue-aQXd*?@1{qBIrla+?+#}~kD(`G*pv`;T>dM+9Bt-DI; zWdlI>Peuj|djnaGkO_q7^JW7_*9A|mq7c=+yVI`}|n3)xsR7^pssy;iK@7;u0S zI9Td=^Yqoer$DAQahv@)uUgr2yi{@TNw)7HE}Z@CF}*D~;E;k_dVWRYv#`ENo^W*? zy}km0@qZg`*Ty|TpWg&oOtw1yuB@NoofqIhm;M$ZG9Sacjy7Eb>j$^T=rjspLA0r( z^0f5;mFOO;>2SW;1u%}Fj{y%rHuO51L=MOU!#f~#Q&Z^sv8S0rsdP;_6~=sJ`ZBcw zQLmF_ZRSBj)bv%cipppUFL}XlQ+w_S2??N&76UQ=kQQ)+W-G&nSnKB>MB;%$LQN## z%B!lnfKvAEd<&Xd@KWq(hZ`$x7Sf|3Z)j-v=$RELjQb!}zrqSC)+`6mT{)Mxs=S;D z|4ZZ|VV0Dw*_uO@_vz}V{1G44#^z?#0@1FfCZ2Rfm=OD%Jdde1O^3g8CA!9*pFBJ~ z03HCipazD9{{VG=-)6iXkePs5Qfd^8h)$d)Puu4KA958D&I5)R1zZk79}A#u0D=J` z9FQDc);8W(A7=s;ykKuIXT1|Yf$m`AS=b& zo~%$IfebPo3kb|t4;#bMG)33MkwzUPG)y7~GWt<^SaB^^SXxO+ClsmgGbv%>4io|w z-|6hq_~;w|Z=hb)?_zQVx4%H)AYJe79fmC2 zROZ||KeuOcj8M`#=AvdaQa76y+RSAdyeo!*iA!XF6Z`R+g||ovr@%GxC2r|YFB7>QwF5`+0KT*@y?eZTKg7!g-0{vWM{$mcftQ^M~q z@ZPY~G}C2&{;Pd@-Vv-TeS@O+yi|!+7RZ>gJG@@0a9x{=5*(d)8=#*-D<-Y=e`JJx$a4~ynj{I*254V zqO%Y5^`70N(`RQW0Vo`h!+Jl)_jH%@Ij;ju+8ZV)3XP~9ptbrxUjiw0u1mMCnF2qa z*-$(YpaeadcMuDHKI}z-?g+TaFDCW)z4d$Wi8S3@z*rC7L@tST9sUlE;Ccb)LI*U0 z@6ycEsG`i*1Fk3Yt^rXIFj8bFmhA8E10+;K zaPv9V(Vn$pNs7}Njck1D-_l&b)gbJ$*=h9Qp#7}TeqI%z`)XHRBa}_(<9k}1{QoF- zUrc6Lqpu&0NQ8$nh4xJj#}i%0ss&g8K72KiTW!&T`#>lS#p6hC{DNKIhSmP*`ru?@ABJ+y z_96cvJg)wY+@~H%Cq3r=&RS$z?V$cregRt;pU-#+Ih^yGMY*2)PMv%N7wm#2q9#4g zB}4)p{kAFpxXl0A@2UQ8H>;&yy7FrC%Eo-|q}7Rhaa(y^cQ-G2% z{O@h<+oUTjk*_ua?qiJ;(ED?8qE41&`Y=D$9WoXDVzgUnbqvy73%XhS^CajRFw~j` zl&WM&$S@J{TwCY?TP0WB`d&OiyHL& zb1ulmbSRNHm-l?R4ZLx1gIxqb|2eFM$& zA80T%iz78K;}`ktk<5?oBGM%~^-?FK`6;Kh?z1MRCI&RFg`hHRY*;$i@vwB3EkX_p zy$^<*(v9uB*$TGEt|K!NJQO()jgj-!1|iq3{Lizx$YMx}V=7PG(TFVV!K;}?hz3UA zVFoD86j`b|LyD~i(5Z^Aieb?;i+1Dn83~bw`0vV6sX>$3)C;{JLbwHu@vp18W4h$7 z;as7GHGCgNQpGqjdr!c$Au4k@ZshI2aUBz-l(G#%t&2TFcFHeZGp z|ISkz9@k7yEl#dVPN`BHikXb+>}D=ge2!49-A@euBJnk@VKd(u_Nv5+REci*l9Yv* z2EK&$9ez$JNf;I-mK{Q=J)o(2f4-B~Z93he_@cw|F(F2Mq;WwrssRa;5cMk3=r>N3 z%vgFi%6Rg}OtwK~EcwB&9J`7L#JwLUwLQ}h5H$rgnZ7D2S>@5%OVB2_&Ixk2VTiSU zR28}DI&b;RAPM{94R0?+Jq~01`P(iG2&0;qe~^Ac^5YEon;OjuOIsh*A?9a816SUW z$v>hC?@h)l$#uV4Q{tE+UYHZz++quuNe8Bni4 zfq=(85EcL)VxhkoMP@rHDhdDvu-sWgbMqa*zqA2I0=}#jKt1-k_|w06!4AD*hqJ!@ z3bg$MUgvJXhgfm?&a3c|H3J!MomBMu4dCMfvY2dKByLGW(4p7;Kleh zeRlqPHJK87`47Woy>-?NaAG#cQ;5CQxExSGABN4B4$nHyMKfHlYYjct4dM+Dp;yC0 z!Ddz)flzPb>O%^hYt))Rn@cGQswW{GvoocRmL@Vzp30iIJkj>;4v+QZNt^zVzMa%i zPC~w-^A@#(R4&!d13oYd4LKe&se-9#0pzJxn0@d3Oqo7awT#05q|Uo(TA3avL3ZcT zXT?U?YUC>wIyyR_U;%RtbDw)=6DMV>OG|CGx&!xIHgj@vstjBHl~RKimw@)ld|<~; zf)#1uYHVzrCHnFaP#h=#rwEC2D=_BAB><3k`i3nJ6M>pwOEoE22mqq_&CR!qevHft z0PoDx#VVb)1jK_W0l5SPB>eCve6Jh>=uyz|b;5)PATSTOEMW+!^eQ=xjw_r@)`SXB zh@p$f{kq4ndrW?Q{=c^oDAp*jV+ZhbjV_au0<3^QUYH4eUg%Y ztqK=52O77h5Z$y!abPJ8Y^`=LxdpcDdN?D6@-&r8sCbt9sK<|?)`U`seEFPb(kfpk_l$=p3BDP%v)802v+sEfR=GHxs~*Va&2U@jfjO;p zKgqGpOMZ|C!_KV2)g~9w4a`tYCQN#Ut(e3%k=ae-T`@GiPt;@Tj~OTmTnS*(1Y?Di z(7;eRI6+Wg`ToXOWO}7(<;Ee#S^*8fnZnHO3>SX)>A)rp%r7z(U{;ldrDJ%`NA?5(z1~WJB9U#^rlgHtG?tFbGyi>BWZEic&Kdo^D5)snS)OBFG$DR} zdbB*>6x3SpcU_$vZ{^;_hUF^kge0LJheETYiDX`!IdkUSop`S;k?*? zX?cMHcrDbQyl$7e-=GrIk8@mVH+P@WR2B$O+rPfs^5ChBA)B;)u3u61UOH=r^N&U+ z^F8{jRa6&qfY9{mAkVcAzDzIcenD$mtRZ0KnnkX_E2qludi4W78vF>JJI^BI=WLOf z(Dv?d@KXdZn}1Vtjw8O+TA#(#pwZIM(^KVDK#TpNBw1OuDJtc-I0xKwGdSMT{k9Jn zKTNmUSFRiAbop1Z;ydL3c-~cQeIph4$?Q;16RxtQ$}U!aL1rPu-veag z#FHV!G4Vl;W=$UaW)kK+9wCz0k2+Pcs2sUt$?NF|u<-6_covcN<9STM=r zbnxuB#`7_hDC4|QI*Tk-#<6)EQ_{y@ZLq0x&yZp5-LxFOqHx>K<#0&-5-%4=oWp2z zl1qs-7(&1zj&hRIG|(`0X|55^do0Wf#R{({b%cG^vx1lF9l9Q2kyzuUd7`S2p-IVfDUkCfjGk& zlfzm7r;*@55Ey831vhqG9d2)KX37npK=`ai#O%M-41qH|LF@a2+SzEWnL);5B$hUZ zf1CYzo_|b0BnoIKR=F8}Os-nttBN}~l-^RCG<`W;gzGd0uYaEfm(M&B;}EIO)WyX&yaNqczd zzpg5N;wf_0W9ZNO&9^@>FG}05jneb(EUwq7bzP~~;e4CpMPjjz!qNT3Zl?d=TyOs$ zuW_yd&v5uM!Q&8Sf(8NYCF{d>8lZV`q-)5@$-{7{saS{ML@`(e(Qv55#-38*?NTx& zmKipCz}MFzReumEMNJO7XJ)bZAhAU?CHfAKT1h`bRWpUh>kbYU>vMo%j@0?Pw6wH0 zhMGDVSUBszldx6%`ZB zFej4dt_(YO2Vxg&KUcpo?-8wd`y73uhqSW@_*|eZR!@B6?>o6NH~C&wSI$Tzx#>u= z9ONukQ6Y5NL+%|!Q_23LWTDz&V@gvayP_sBzJc;{ml@BbF-5;1R&oDnkZJ#@xoe!Y zxwF#bx46#Q!gidQ?~7v@{phrBy?qBubcA?%=h^!&B?ypFeoV7HyrJZ=>G;kbk z69YlwvI5bl#I0`a{aYu-dT-UxaIJu3B84t9W$1`5V@3ww4!EEQ?2h`}(07K`68~!i zWY?veC;h*LnGuasQfcN1qHxm=Rt!$E_}V!~&q1u_3wt)=lXm?w>2_X@$r{Yb0ZVi3 z31rB#dus*}M*vAemRk^=u}7I z@ns9NW_0$uq33R|1nK9g_f*eA|MY+0*il^&I4UzOUb}V_KYFH7oE{qYxD#j8gZZPV zx9y*i1Z%<3*@r&ero;;i?z2RmPH}Ea+3}X!m7HXZ^4A({2k)uaE*$i7RxcSzKcX55 zn;=`k_}i~YBmU^hQA(rSbA?+}99v2DaA<UgfGy5 zdxVG<-&kpF=M?K2r3daCTEB`llKF)a#`w4I)h zh)HPu1$LeN6cWccEX*^48y;&@d^16Mj6}Drr9&hT5?`&=_tfBNfbx1m_(HG-&oHS= zXeQ~vR-lK$YKnN%vqfZJjfYYcFpS{gLc?8>OB8K7XrMK+J+ZN#M-s3Ow}J`9UVQYJ z_T7V|d}Wg)u~Bx5jT5rZA_>EY1o?gLNVBI;P}-WBM(XGSLM@&^EYtB|>)zGPY#j0* zO&blW%28t*FkrTrJ`M~7lAe;N8mu7*F6Nnw!1fZBQez{xD+NuQwuSvVWHr2B;!45| zlS)J?J=?HrO!GvEuKk`CPAMRnjk)^e*rA zatuouO$bv+Jio}StyoMuYVDDjBFF3!zPum5HNSCJC8+GA{!!O(u33~L(7M}DVryu) z48(U&@C%A$rOQT-cIj&l-O9D=og5tP3or$>A~go`Ijjqyj5gjNvlBCoi72*d^lmM6YqG_*Ozsb#p z0YB}9w+FDXukJyxWC`p!D{hl2TtAOHT77Tn;`+cV83D03eW#Xl%C2)T+OHL;Q$H++ zOUlbvDov0enAGAw0RRk+!XRV=g!D~dV<^dh==+69)jy}+wO=3MCIry7`2_{xcr0*S z0oWa<@hVH?9C#Cc=hHf1Z{TXZ`VDlCl9G~2i8_F?D{(dgfegq}BbWDi(qSUeKfoXU z69=~QAs8042Ot7)m6kGwoME+%fD zZHkKwJeSVj-Jh^J8?JtT@?E92u74Q$dA*$hUd#=6pBn&brpqn}lrE_}Zf99b0Q>@< zxaTuDz`JH#x%i{{9)XVnHt64OB9t+`U~hbDXm~#+jYC=Y2v}mVG-bz?pN$n2TygS4 zna_WKw*ArUhgTzj@FGF}1;Rlc-GH#8i<4h+9pp&TFGSP=SB4`)y76)+zpFu^`}Lxv zLSZTsYiA`pYFzutsOi@TFb8dSRU@Y=t$`g3Utbgzx1M5T4LcPWVb$<^vAmX`8C+(I zHy(6U6{S|6u>@{KnyRmTKuEHrB(iJ&z1Yl38Y&HE>OcOtix+jia-($)%j80}Ss!|e z&15m_=z~Zh#v~#INI9`KobpN|hL*eP#j-}zb@iT%rC(ZiYTb{3K_V;9E5m7znIF@> zA8*5lg!}9h6FrSe=VdMV6}0w5##7MBIr&`+tlwwk)L{1f=X>^rrMbD3{)TL)H;h(y zj}H$DlQpuRNiG^o#aq^ghZhB#ZUs3k4G&%`NoguP&o+UwnI<4ka))BsmZUW8v~zxB zDIVun>5Yq%ry%9&L7;*9phhFdDfZav>5BeJt()Y1V~| zyfiZ8_p$nLz0YY+*rD(HS$%TP{iW-_rB7aoU)PlUWhAbRGB73&-AnQrJ$W(9ji0?2 zEpFrEzFcX)b7)%J_k4!}{jU8|U6VJC+u?_nYsp@zEGG5&-@Oc_fh0Zj=(;`q30`|X zPnwpB;;I5#OK9#G4;fx;wC^!AhHenycQe84>iY1Rc(mI~$Os%rj2qJeqf8rD zzJSn%qrj3v%?{B#3L(xIZ6ihf2_poiyJQ-Q&FqX+z%aYChWa!L1wUVm&{m4(nZ=Lm zcpYAcuT3I7%CgAe!R=5j|EvIE#ot||(81$^qFQrs*MLQ5qQelUC=ehK2xeW+cx08i zX+}~RP01Siv5fG7wsQqoiY3|N6&92G^`O5x2E z4Ge_h^Fwft+9JmURTB7iMZz&~0VTyf5^!$xT_!jeorEAWgP0~awB#nVTsZ>n@pR*@bq{mt(YZzbPdNn;;RJ@$OurGgADT>lcq z!3p_(=@f{>IrdM(LjF%hVN1*Xw{*GxykcQl&gPBF7T@i-RRwxIjn$i_{OyG~7yWmg z+>FYp+$J5tT)w+X-WU6ge@jZ=`kcIkG=Pj@MdNn*dogS@td|JJARK3Md?N~&ml)n- zhOTk1f4b$Ji*DyJ50w638}bEOKhEuwWD5a)ek~pNkFeV}HP(1|lxf6gSuyAJ!0-)Q zw_e{2Ff+N>p9d=w_}F$JW};Xyad&;%DY*ms5x~-O2iGZN>*xHt1nB3mbd-gwYX64$ z&*An-^wSI`X8YaqJ)yqpTfGQhT*SDZpndKt4Wb>$(Icu;e=HaknRg8a0{hCrcuR~JMVd3m6_5C0CPi-B;q*p~dLuo+B3B#r& z^RS0=!oy&32UapzO<8AO3_Sdg1xQi^a?PiwT-dj?z+|8#$$SwjN9|ivR(1e<(&zVQ zlS%~>aPI3rV(SdF?W_?1BHBv)l(g3cz**onuj+fZL5*`i2jHjyf>jV##M3LZ`Y{j0 zED*gU0C$kbAuI7t67bQ1$9*YUb`BIVDp02bc5#(dZrZF@62P8^90%g~&@6QVn0Rt> z@*UW9egA6a{PTTm4@AoQ-s*X@;`+3-zW#E>`{;g?N#Z$pTUQ@0>e*g@Z`h1if`2&Y z?cZP(M_s7%&aMY|Qec{ZYvU656EG=>r9f;4yc&_c?*KXi(WLKrc_wSnPCx+Q#`MAi zCGW*r0nL{4a8|TMns&r3i$}KWwAymk^z!C`qcU4V`3GciU8xTuxsRw2T#G~g>3=zImJt8AcOft?R1YvMVp zzz_kz@&JJlyxIsb2g$0>GxgLPjabhf+l%=nLoPWtUU{7ffl>}~Q7*5wn9KJit~}H_ z)|=KYpJ-VNaPde#$>2xiAAA4`25gpJeJ+j$nh&Op@7cxIIj~yJhoZpR-}Ji>aR)m8 zM(^Zzg)t|A>pAUFVu^+e9k5sO)V4)9A*=st^F7$`iyCwEsiX15T{ksFJx!RtL+A$-_IPn*B20sdD+$Eu@tdpAoo7+fa=o zLK0`x>kFHhvZCYycnYQivsR?jl!r|BuV}hH3TjIQ$io0&Ned<_HT_dw75r500 z!s*5(1Xwk@64Y$v)2PtwbUijT#dw4kuYydGvhZ%wtRS&P73{6S$Jef_fp14gF&#g1 zcp0LzxzAi};|))nXmMSHeSIKZ89{hhPH&gCD7;v#1?8NybbC1TjF8PJyue?ePMU^y zm;@0~0Z}cyT{wslH45R$OKp{|0L+mnYhT}a%+s#$@(;|6BNYLm$n@l*2LE6>i?2%%Tq`Q%6Y#_6jiP#OWU&zoL7t|;`x*b>m zW-J&C9M6GB2v%#lErnRJ#AHRK*>eQ`_!?xh01Y07E$_qZ7Y?Xo^r7__-$ySzyrVai zB;=2F3}6g_ie4RS!Cm7fscVpQS~Gb)dU~uV1Vkv!>M2qI=A?!=OCEX}_j^t0>9<5v z0zx%McAmbo(LLcjt2&CPZ*#qFFlq&A>xf3JZXyc;5Twn4=YTYv>OfX*^Xx|3XEPi# zpuR>B$$2&D_QDO!8s%FH{cZ*AQ}y}v~HCQLA-IWJRdb5 zwSusr4@i^4gOexkYJHCPO}>V`UOnk6rEDqa^h;D}yVwo!*Zj1r()`fn^Ux9Tku4@` zBhb##7Xn!j^&aHe>;3TW-}BQ4UA~Kt_u2w0F%x|#1aeFFSB3wANszBZua*D1x7`C$ zcD6#|Z;3|n+3o7%1KhEWEA<1rPs=iP?F@V?`O%4KetEbIM5)pCco5c;@HqkT`jjWs zpseG#8!(<7LU;RC5~BZ@|Fhc7``hDz;cBzC7x;-5?t`~?+Y9Q8e**c)(Nvy|A-++} zmw#NlrGTM;!#3aQ>#d7lNZ{36sHORh!#%%U0zm<3}Fk;EId4uKFB6L>K#f{2A(tW|<#DB?0? zVHbUPodr{Yubmvc+0v>ZRUo#n%T5+*LqW!p+nyvwY!j@P<0cbs&i=bO`sgMtXflf< zDKc8Hs^zP`9fStPkLl>V_ampNy1?QacNdzK{}3-d+6A~+7MYzdfPrT>qJ*tk^UtAT z0(V`K-H7V$?0VJo>LwZG=AmohB*@}$H$`s4MMbunk&cK5%s^loQ`T1(KfEh0F2mxp z%x-iWNtiCSjUmNZ@?T7^tr*VuQNq+xndfpvs>!)BTj%b7+j>~;ILYnz@0jbm^@CBx z&+OQ0U*G<}w!Z{|9I2)@y?ITmjwGD@tNy&W=^JhJ8uZ0`5|;D)hZ?hoC)u@>(;8al zr>0OaSH2a=kRzm{ytUQMZjZaOoui`dWRSzj;AWh3Cr5}p|0xZoZF#iZuXoyO4R0r8 zzV^lDk$lz>@I(HF0fotNTy1)bQWl$jkHzkIrejv_Ta|kPGI}^$Z9;R=Ji6+ zgDi~UGbRL=6ysGS1omVk4oXOhNhJM|4><%AFB~tAaSf6$`3`2TXs42kKuSVU@H&}R z7?DX9fhIiw62*WVOlVz<2W1A`3>c&`Qh~3vx=cOTO};`qf1}e-5UOED1PGf|g%?NI zsXgmmN9CPL{#Ecg962156k_vRk98ysMT*vWGw357!*GFVHewkPg#P#iovGf}8CVyf zYy|X@hvjEyrg%EqIlQ9v`*tE59mnF8EQ=u=lT#Q9+~uTZeI&u0m{1v+@XRNhK>_Fq z=cR)(0l9&(CN(16ik2lJ(~B8`97vKm&K+Y?Rbv^P3TZ;ax?<`Zx2;EL+0-;-l$2Ru z9CfHL9xF@ZFH&4w(hfSTA;C}_QArjMUYf7^szUQ)Lz`8tHB6EwX)Ip>N}!_op)fI; z8oAB{!I(v7pM9I$Rzo0ykT!RwgFiNKMvvulCITxWb{F5vQOi(^egmoi&8f&Py6wE5 zf05nBp0%#hQQ<`H->;yCDQuu6T?a-?;k03~@m{Y|$+%Gz0RsfInGx*GsjjEx1@M3BRhb8_qkf9 zhwQp}8F!5P6W2K~CG>+O0vz@{Yx8W3ho68L@W&jXOX}jA3 z0uq&u&fvFS#ndZqE1v$>H|b^mrZ@;FAJi2ax|f++%l6-2j8F0Zy{#VoK@pLmqf8S2>W4 zZc)zLIn```>-md!tYt1@Fg+A-KCH${a50a16aGv=p*$i^gO&I*NwSS=Ct6O2!o9qr zP1o4-GzArWVI)T=9&1??I&H&-$apvha=kJi@o5OI#urI-BSkvgpqF%Yi4#e?29hGr zlJ_QC6BYM3^hFjHvh5tdi`<{ZnaO66d`7p7GbW5BmFFf+&-9LGm(1)+RsSmDwJ`bO zxwQQ3VAsaD7VEPDDH)k5On$T)m5*j!b)SVVKmAE0kgW0y`d*Il|a&-;@c>9@wx znM<;dWgRNCJaGuE)6-5xNb3_T=5DpB1VFPV(`E+~X6J@2mg z%*M6E;_Ph&`O<#xh+n3yinruC+&1}Eut)0=%kSQb2W&M>5O<){Xs?p&ufAa~LY6ZcsTyGw>zvvHzIp4?>C zc1N3>$CWg=t3B~wl%Mu|mi*XVcYJi}bATND4G;2W4zr7tl}<(mxey&9EJtOVABk** z7`J;YXwrw9invVuCt44IP8t#lRpd5BY($mpl1D-^mxpz=o96}w8>cHE9uTmUp$EVk zqt6WLH^bi#2s%ufhhv7j=^DyFw2(0Zk=58uudDMBQNGn;r_#`>;UPfeAPjWIQM9}x z0ib)^ngJCVhJhz(Yhn%5fwCLEV7agAYF)xegz{vNjjH#&#GVPo+0odmY$%S@15hOD zGzE|wh^lg~q??LMO6+@%V2g~%jmZa1M0G8|s6j>UPL27_l!6xB7l3X#=aEE7v~+N| zOB5HLyuEhQQ+I*gwkfZI`CR%{Fbvw4s1=AQX4Gva#r-P)ofh(~s=SIR>ohYyV^>;= zGB#O{O;!;hFutp?`0mRY(lGlNS;#Tsbi#-%)?(d3Wm6PSd^)bclZ}l)zO_~ll+ zdYiI$146+Z!Q)OB(I$27A|xWR_wU$p#e{;e`*+q2{ZqF@vECcD3Yx&yd6x5u%pxUX zX1pFB?g0p$RQMlXXlB);vrQxFGoYg~(R5Ivu<`1fZ%nq<^Hr&-mAv#A$@JX&s~cMXGZ9lpDw16ea*T03HRP6%XAkIsmeO*T}*b0ssJl z(gW|4?x#ux8uJVn!n8zuM>i9RVLSFW_n#JVZaJ!cdUiaU9q~W>_33dydf$4KFiYBO z%PQI-av>>h$e;fcF^9-dg(-kt)<5|gUSD>x2uIWJ53p-oUDd?d)wPJPy(+s?D*-EP zP9;1LJD7am65|R&VbrzsXkbF=eO0VH!(r>KBV-O7;@X`b+lb@@(7`KLE|Ab$_lMSM z>pyN(lj_uEJs!opIAHxTLGx&UTN%scQNX8Y+sPkaoN7VRFJo{+Wy7tE7b6#9l8X!Z z7XDXLofh*;fJeJQkIw5wsnl1Wy7DqoPF zoV|0C4S_9MM%k2|zTwLmeX1C(5n`~SYPGO4w0MaIYHnrs`y#&TWsvVNWxDd}3YxSx zLX4%@=<#3dcDe9EeI&Tqg@|kU=9L*2b=ZlKc6&=g8H7i-`7l3-WyhA}*Tzk0>EPEM zyg~h*wSdG_g8Npl>Ek<88O2{Z<&S^2avDHgR8dV0rgr2PfzB^+?MaP2g_~Aw$0wnM zwBABTD?h!Jtcvdcm2kKV@NlH;J9zJH@+9n+h!Caf?Y=Krh?;g>ZJmC%d}z=4dU_L= z(|fnTFw5~>-6^ce+ggC@!^8JMt1_>DmxK}e3f23Bye@~`JJ{4>=HB8hriXR}R+-l* zx1rSjw-=^W&3T2EBTFyMUZwN?>vCx{-AzhT?b*OO-R8LM)Etc>S>ZqEz`>#v6eQ!* zlAczfulVN+{+*$!#Qj4&m1CP5)A-~fgWeJ>wzdLq(P7cFcO_4JRzj>?;w z7WyAf`f{@?$-g=i`n&#OEy~phww?842uS*J1_V=LM~#RYZ=j%ov}5%a%;6T zKK?d<(jsml;O`h9@z5YzT1z8i{=%%0MvQYSAGLx)1IX%*=BAGy=e&>Jw?x`L`j@56 zZ_TTUwiIQb!Jx&#gfMzTMcnnbGLjX6doRn|iJnC2+^hej0~2#m28q_$h$AQB06-Ir z49(ACV0wO^StQXstk))S(XRldMdf^X_MvTrx_M}5h0p53&vMjiMz0pcZI|LPQuC{k zgO$xwtE-Av_!D!ul9qh_n3St=$E8)*?et{kYoYS-RPqyIY&DfLUPz-_;2R63u%Xz8 zwo)S}cf=N#lnaV-!=x}2!tvGeOD5|mJq5N<2TuN)e~n$%ueYNs)_OE%+}0AUGXLgI zE0HT>Z(YevQ_ZtjQf^yQR$~HHE2%ArNNX{*`BpK@;k~^4@#~`fA~*6A)<_Q2f<}iJxG@WCYcfrZq}bWE&(S)3T0t zNOM`7+dZd*1jKp12o!DkMUND20>1ZNIHeTdIO=s*l3y=hUQ(-H8?ICoQMoufSAxo! z2~b(A^{rCE=g+(P(>*_v9>Hf^qC2rY>1~>w!`zscWdD4S=_2p^5nSwsD$>&bhu1riDh3Q#WeU?sL5OzT`_1dYWM}f8ap|FLjSKHev$7BDmJLTiMJyZyH=HCv-Ju1v1FX}Cy z^=e?fZKLtpIr*yEo;0J)+-245fGUSR#KM;NVav(gGf}tm50iQ-=b6-pH>r9zjiOWy z+rf$w6<{?MmCRFXxcfJVhK6=2oUK@}ve48y`}8e4F&ZlB%Behz=mEVLU=R;^B(rtD zJ)cJZTk6qleUvH?Sdk7+{QTM7x=*TH*x|Qu?8NE)Ltx&oyzkiV4i4^SzIw=7|Kdnf zX$=jNxIWMZn!Qm>^IPj?C&wd|lq3EM)flMOmxAyoCddody&?MXk%rw{gxJ#|S!UBa z5vH_9b4DIas1ez~@z>Tat#%K)Q9Q2DfG1&)c+kShx=;V~cc?bk&nA!M(t>y{^hxq`xFKZu%Fl*l=S~p^BWwA4@d8tY9QThF#w##^ZvA4EARcQH8M5fCTv@ww zD_L&7fZl8U?Fh}-l!{`=Ve#T$jNi`(q58WD`BWRxi*WW1>ud-jW3q5%@Y$Y^%*lRc-tW zEnXnyZjOU!^YP(#U3$FepGLYkbD7?1tj@#%=fSO1Ga<%|I&8;=fB$k~R7zs}ZkF^b z+7#!%7{tejdvK*LaP^o)p8_@HBt(ERI`W0rs^To0|L=`QmZXqxnGFf@&n$Hc7*(mB zUY*^Y+5t0_w`(FS=6MMtiH_8t(~c!Io|MsN3GVI!?g{C#6$=lx;yQhnyoCjIKdaY6 zwAl<-$tN1~acWt2(M0yHwY7)khE#V>3qV#@@XSicJ$PeiNjUY!R@HGZ^xz53iw0Il z8g6WFTK~?63(L=gY=P64rAf%?b=)K`xSUOiA-L~IWHm%t3KDryg1Z931B^-H1rjU? z@eyL71>u2Op>Z* z10@mOq%p^kCL?oIdYc{i#&wAYOR3wQARvGw77GD+C_NaaM3$UKqCM~KyNYIBjLW}X zIsQ{iLmrZgD;aP6EZ>UcTU?;jD9*Bmr;bf78m>I;%xmpg?Oyq>5aeXU;N5S!-$NDX zXFr5!;J*KeL^?uPu<2H!$NDj?0J*mc0hxrSAdyiqUqivh&CLZiHz}GM{*jq702eVI zmsuVOBQM|W<1Y?U&7r41`M!Z@i-W?as@9_IcKJLD(C<^$uypD(CywT;88`7U2nWlXY z5>D}}+KiYw;dn%Xs`v+R41~*R-sD=R1u1Wv9G68Ppzcw(()d?jF>vQMLF|#?3w-_a z2cj16!;WwEO-Raht4u-g?Z}#_Cx-eF$a4ks|p6)xAuW@LOR5S$ndtPr) zKhBXxN7v0d42pa0I8nbp=SZ)<`>ksC+kIoTG}3;xZtJM)&Am{Y`@yu%A)A`i-hRxC zipZCZa;{csA!jx3bH0jwjYg7h6QgWEqr{e!p&t+N*nyX~fXw(qOo(0CrQZ7xj3ex% z;vS4gYi4>UvMoi?pF7-DGkR(G`IvX@r}yb4ZntxF#R-e#wxz+b8Vab#_i9i=MForW z(9cjr7&>jNX%Gj(PzR1QT|CAMA!A5y1RINkv|>br%$IUT3zlbrDAh!KSkfegQv69Z z`TR+F!MK>=13b#2j`IT3ua%T+hf@DmZESEj$U2n0u$Z_)DpIj7t?)k1EAsm=dE|E+ zw%F|LWw?rkC;^o!Gb5bKCrF2e<5gCzWb(E=%f|F{Ynz&^cig);FVJAYlu}LJXZ@W& zC}N?j&C{I6l4SqAoEO%mOmAsAKiQaxX7Pp-S?J+k4_o=&ilOHUS}uWm9l!a|E4^f8 zhToxD8w-2M?CFmoTs|IJW{d4J{}TKS4gcML&Zu*9I&wvl(t_k-eo|m9s|lrBKO6u2 z=rO_@{^{{yX7s0&V4y`=ocwJo7eloJ|MYArI+_YVvzJRL^+lWWx#POn_Jr%tSoc6)g(%`1H-8F+iV1EMqTjxG`^TDda$NNKA-u8rYf=9Nlm&e zvZ3nl=Qfxg_Rg1lfQs*d1yKd!aB;rdHm{%agLKwiiHxC-cXf z)rRD?wzk*)TwSPbuk5l8wC-n9i@}f+S9^MSlx4J5jj!GM#B0IO1 zd^p*&42);^uFTwtLHRVa@(}u17%|B~JS?^^)L661!g;78b(n{o{o@7?8&SO}swH3A zLu+eb;0pIKe6oykp9VJ_I?ui!C40z8YB2+v-*c#9>rRlRWB^P95enl?h!qOe*7P}Wlx8C)35n#nRUCk-GW zrIk|}%7~mbY8@}Rk{}22YFTpYuoHzt-@w9^5lK;)jg^I8IcR6ubfMk+*fJ128^}YY zWTxb`A!KH^;R|G(QBDtlCH;gU$*f#Q1dyf*BS$a?#}-;BMD%Tj?I*vO$ScbG6QT?o z>Kf`&Zsx^DI1s^;!~`xo8;LkF#qP;?4(ixAs_deC1GRrr@3o59RrvDqa+1e?H)-D( zv6O88-aQVp=yZvj$ahcgUJU*nC*0(yU*d&}`+Sx@yGlk)2X%{}^f2wIkcym*&0gR`&UFb4>-K7P z$kpABgg;=9LGSr$%LAa3+a7KJUgfb$N)XY-<$tY2D?<_ruQ~?*7M_Oy7!~N$v>Z-{ zmo5TGH|~ih1W3ekpcxZ*&2TUZ7&$-N+KlYL)9_vOy`%)W3}8~@Lo$6Y=AE3TS3E3L z${!D}Km9E=_4adCXgqu8*;>mhbcvn3WSkf(3uV!w!9?c_r#Z%wMn?}q&@H5tR#zzvjfGn3Ty2=tq-%#=aPz7Znz$!D|@*q$>2{g?R|SJ!%Oq4W1UT{>|M-YXlHGX7&7Uf>GqrGQV9<&n5ekv&{KZ zVk(ix0MZ0|Q42kECfW#hjw#>mphstl(t4)bj`ZHF&>r42t{2x!bt4Dwh^ag(mFGQ{ zW)Zdw+q6cKeSa|M+bx3pKHrG0M@c-DCWV?jt%#rle-;^%npXYYVs*Fvj!J@>*m|;2 z&w-ng=449SS&{&k*yBNITLxwR-vx!n5-pE|j|Hwfi4k9QDtvyip`3102I4CgbSSAh zk%+c%YHK@*j+`)2x^MEx{k)T!P49iE{@cA%YP+N(Bqm~^SR!bc@U7Zz4?p$$(b4eP zg`*v)sPHPStEGm;Q2#lBvqE5;iFJFM$ zr=b9|#O)%(Q-_+Os<6YXv0s`?lre-dz-XX|93e1sDPv<<%Nc|!Y;^uW2n-(sfdqw@ zk4`%OHHPsSrkhZvMR^O$@1)7WiM;;Z4y!ko@7dT5Ch$}al)|7@ zL$E`NN}eGm?7(3$8dB~UBz8njAcs1n%qL{G?CR{#(={tmf#?Hs1nBwaemTARgT&B|Gd>Z+H7V=DQ)FJNvNe`A3Hc&EDULy_XruN%K2@o|~@bvIjN}IS7>v^<) z1bh-!QI6jYSeGZja&<9pb>vsl*mw>46f=0tLT7Fcnhd}<6S!%+fMI<^pSr;{n2Ej@ zUXC%6#%HzqAqI@Xfy1l7A=o#q0d-Cp}}SXdCH74UH9~+9MQkA- zojh9iulJo@LIdC-RmLDb?%XUQv^$rqs_X3BuKD|WdM@YFuk;`u0g5Lk`>~}X)Z57a zFZry*`;q5h+*Ueh{%g9g;*eOh>bLxY4e>kPNs;hhQAktXc5o`6*UUiRZ!dqzN-cJT zgY#hgreG27QGxj3t?JAF7Ru5Pw*tHs&>^wclekGg5m_NJThZv4c)tu1`9>nmiE)ZXAmuq@$iBWTs_ohv-FljGYL$e zvJe04SG;0E`i$QDy|^SEACKl(j1b>qGny>dm^HDrU^)G-PZh{QZN>MQyXx)T^rY(! z31S_1W$%0_FRJ(OcsRBaQva5e$N1_SxrF1{*{-Gr`ZHuj69!5?22*nuZMtXyf%9w~ zPNGkCv-U(C@uAMPr38gZU} z@C>j8B4QCD;?dD7CgMvWVnd)cbdb-RA)L@ej3k6m!f(h>OIU0`JcKkDf*S?Je?yCe zPKnElyE`VN!h)O&Q~4ek-hMi;yo_RrxT&kGTesDvg3|dCBM})BDn%CAA5|2NRQ6G$ zD!6L`W#)NLk8rBe+T%y1TPJ!yCu-`}Pc4 zY;JzU5s^q}pYdvlhn)@To@a0|KBk=hhK&Zw&yDd5f+^pQI9|Q4W|mu9j7;+}F(lJ2 zjfZf68^LcG3ZK91`StkuLOd6;bjHtr_6voU2zaW0!I5ZJr z8Ho`kBh6WfgR-JTrF50!jxO<7e074|=WG-KoV+ZKizMqZLm%fm=M{wKtoxdJeB9G< z&5!Jj*3iuAP{QaP=O4QNA_;z*0AV@*xI=!oK$N2x`RT!8J8V1J%Sg)v4DIWscsI1{ z2~K0no)QmN8@|52^hNoJ1Wd2Q!0+Ihr8wxG_p#CAxe@%*39nQKvvBOdiIcuJp?@>} znG$I6%qMvDUZoPAn+2>OQv2H^TA8SkXmFIRNU?Kr$^n=^Z`u<5Ec`wWdIa9S8y29y zR0FLOAj0LhLB0yE_o)JQuSr6^yJS){WM|0)Y>ys`L9LWf)ASS02KX2Ycmon>8vQYE z-)Mjukes}3y($&%oA?u$IoGEqErd&@@m*MFyl9&ej-YnjLx4_wS21;Ef{pz(s}z>8|{t~aX(fA*J4 zwb}qR+N2h?B*+{S-YvbCL~qV0NEn3$J~q2 ztg3HybsnqddTt$73x(7xMhgYszkX{70%zI#F5shYHXVY{iH=RACn9YZsI}z=brayJ z0`=qWI80(m?l&NMx%^H(!4>1f&Yzw+;LXW)pLqlCh-lSmZ21a^uD#6!RXEZ0@F58E zH3$v>8~;97&&m}=)NwI+D-56o1Kg=3&wAKDDx^fX|6##ao8dt=fimm5LXtW1ZREo< z5$Wkdv!w(R*%N&VWd7XhB|Jrz!g$62^f2GD+aL3;#fh(af;F_YPt4hq*^&)a*#a%u z(IFaARh#%W^oh?X=`cEZIEcJZ7i`e*BEGR^Ny*^8>3m{4%x`0;V@Et_(zuC*nK;uj z@#8S5HH_-5sH3vJne@T;k5*)gti`Zu-n7&JT^9N@#bL3Amijg$1+HU`=r=IJo>-b} z<*;b#vuz9;rtK?_ojRJpeshWe$C-1Cd4oFpsjip%g+{A4LmM$QQDp9$XfdQhAF4_D zc%?srZ+>m2?p&N1;?K2LJEGgURh513 zyZ2#&8H>MS{r?qD&(qTBy&F(?XgJv@OC|O46EmS#dgrro{WMc_Z22}J=W#o|6auW2hE8bp(33ynyEArHA*ctj1nvMpc! zs(CPd=7S^PyE^l?S!v&!uy(d%)&AwCM6*VPhS*ka$ERat+tMR`LMuL|h8etgt|2!f*i4hwSHC zknEP|O}YekaZhC*{iR_?;{M1;2aVuIV9~tR19O#eg3Uie+woD5zS5Y^h{$jUG^!nA zywuT|#(**5@nI^3ea|;X#P8EXlCIO@-Oo>C{0PBfpMU4R79yGZX3xG*z7>^oN(aru z7b#$kn~)i|onKq?-Mc>@UM#=JI`q&)C;h8dSwV_`@T=V+8B-)TU6TiaS$=phkUw-tgqO_jV~Yw?NNv{)dozmRea=!QKMAduUCo8v*d!l z>m(2Sl(t`O1ub8u#INC}ujZ>ivrd%uD|}7P6Fd*Mny1+5YM0_AeW3FbL{CBOn=6Eb zjEszggqiqLzj<{*L3iCjTbl3ht_Uz|ECwOB4gMo14Hz@wLqE~vDBY*jUhf92`KCW_ZyV{JMYsCcb~Owc;Ge1jf|pVBQX8 z|4v13-GOh)(!#>cJ$$Ug>Z6~LkrBvtu_l4av4!PHzbQiaC;|{PLxsppfj&~u+bYih zs>$e$&W^ZDlW%(3hMNy@>>T~wPN{NqsBe}WE{%S)CGYwB<~7^p3RjEz`Z(Mji7s?V zV5&MfBha|Lv;0}dUpc>2jI2Lxb{SWy#{BbPO)N*Zhe{iS+Jr`h1$Arq{iR- z>XpL-(qR9yuOP_W_UFr|m8`+xG`^ibUt=D?V`&4Lbjw4{0qFA@1mUq2{WmYj$k_^x zUu1Q|bHs2_7rYhAph54EUDb5ULJPdx^^~Z|ir8mXbxwPdiOJ8@!_)t2`5LOIXm>hO z7@F#^b;jn`{$j{SV0Kfp`-yqy4R)drRVejAO*}g{bHu@cgJ$7$ zQ9^_a-J7IxRGGoL-p`c!%$ppOe-Cz9nzwE&MVV8wbiZTTlXuia*=Q~n%53`tg5eH1?=Cs7aA{)#IlWe+YMKYxCV0~IoaQZ#oj{vS7L|XSAQzxGB-;;)Jbr? z(RjsJijL25zU#&+{!YVT71lGlu}pr0IEung(K{xhoL?eXzNojT#^(TLX72ty_&Cp$ z<7M&fot=~67qO{?S3~Pv1S%i59A4`;9H3Y*k0U5!6gADT{tau$%sO)aWjxOn;{3?)Q@> zf0b8Pl=@*}N5VG38;mjW*6*{QWUDG`(9jUNX4@3{uHG(FUXBVo|NYam0CIf^u5vmq zrkcx@T-JUB*o&)udcM^CU;eRG-@MH>MGPFGOQ(}042LKx&;}FyaM2~TFik|n)uoZ^ z7oKW|(saN2YK|I3c$51b1rgyWvFFVXm@Fey`e|GN3zjA?exRi+i@Kd5dx|urEtC`; zmqcKo&yidg47v@<|Ha%MO@7j#0+Zr~uA_1Ck%dM`Ap{lD9J_z(da(^@H8;+u18?B>a3!&Ca|GEqc7b2$_Nw~wBfSHKRdf=bPns}SUj@~X{`ATc7J;_TYK~RTk<`Jl3V_W9q=9+4;-@Y9?!bW|0 zz(CN)nsWXuxKQKX_oEA2a(Hh9EZ3NhC5c~MVSZ*|ySdvn59arrUuqPKUt0k(SOu3!dv=M_yb->W>}j{j2iV&B!af=R)CA9#QOzVV@ys z^i0i|&7$6`Hg)1(iaRU6zF(=JF2Hbl=mb<|X=7vK|6BYJ2vg>1QG83$_qSO!t>Wj+4nvJ0C;xHr#A3{4{#?t9yTSmqGK-*9C zz@yl)SHC!m7rD-kimD&r6BpdK=&z%D6U?4wzgt+}b!*zH91U}fb`RHhUb|5}zYoR} zJ^XGe%V|4aVjct;WN?G%K6<$88!ew#3iK4KlAbU2HF7ccj>!-^n%H~1>XU67!-3q7 zE|WM({5#utIxTIn?Hq-4mZkMr2kx{?;=|I4}Lpyc)JleeNT5qq=!FAZm@G2*^wA3^=7x zgRT=JP%<6!+fg=HNXYCKvC}>e&SmyOb9L!0Dc9N63Zm`9NwO=|3;_e%t+EfO`+`NL zXrF${o}ow_e<1v$6EF7PoCPJ00 z76DDIdiq*by8m8OsIl`(Tg}2A>r9LH59Ssqt!L}(8M8)H)J#F%4|Gl&%+|91C@2s} z83fWM71@x2MUBAh)YOzn9Xd2ZtGayT;9xI7gS=2#PrF})K4n-ni`&s#HAm;)KtZ)W ztJ8c9hfwOvh%Om>DsBgjp=eN7-jiZg-9lOdm`!JADXQS!mZZn7kaoO-#Mg>NoLK8lTyuhzuSqq2=L*}fv^qpJ8t zX~w|U{lH-^F|k^kYK!8ps*imK{y+UIAE&>HUw0F=UB7l(ZEuJ`Yi)3(R1okUx%*#b;*kX--klt8;T+hpon`-JhspGnLVOff0 z7Pwnmn^#VVrVIADgRYWWDLO5jzM9BXbxXD47xtBMm1KCm{jp@h0|_`U3cCAWeTT?~ zkn-hYD3BgUXr`cG!)z0&RinfG423ndVK1XrO%BUFj1S7jlxi{e1rJW2W~c%=26^28`p3q3 z*b&mwRFNq3*)U<=j{>;Xi{E5PLd>R3gCS|M+GL>rC^h9v0TQ!GD2>B}|2UC~WB-QR zzVZdJ{n%Nk20xC?I4f134BZL3klD@?*~CUgdnxi=T512(8VR@h(5M)BXkdOFj%7Rh&a@XAuk zWXJd;QbY}5bnxN?h^9AyIbFFM&V{~6JVm9Vh>>l{F1xOB!Z0TpP9*k5QH{l7^(0

s$KH~sB&&)PZY_YK)=27#=89b0*};2ZB{8KC=b@xj&3NUm^F z65KioOP}YkLW6uaKi+2jBo8`#?=^Y))F(-C9TV zKPsnm48en{+JkFHfgHOc&RvM-{5joPhE-L*(1(uki>TzvK#jD4OL^mkFe%u%qVWyDuxswqDB$SS_IcCJP8-Fq72 zAFEAVfq(GY1;$-F6syt{hGS>5jtr?%in=wWuPqO*cd7d!9r({iKE<*0asS$N+R7K7 zv}_5Bo3K4Ll17#ZLiF` zng}eVCIq8Hq4uBp+kb^w_I-+)M0ab!n`xYWvpJWfI-)@lI4)^m2Lo>LlEAqD`pv+y zLl@?>{NoA`TR=Y|Kd9LUJ_;E*Ik_fd(9AyqkYy;y-pm2(V?cC^pHu~H!XO_zZ=3h& z)>|yD4pa^Rwt<(I*TI-XELi6()Z2qsg#dQ*8EC<=jjf$OA4bCLk3B zel+kR4x|cyFk&*1fiaLu1LA1omoLoOBa)y>3GBH)z>MncG(kWWq*DR?a~U|)mX?qu z3Se{J+uQr{ikY|y?_8mvDg6qHv!wTbKBM5?Wxkn#>T$&BY(*izz+icnU`;n zpCQm#HwXfG3e6W%f=}MGc1n>OXPQ6UNMo_KI0U5BwooA?gxJ)g4!!g)ZgkHR$Y zYKALE45!30{{{Nzk!Rx1r?aB*N@7_Zy{xalLIenD!$CP0&LrLWIl*JR^P5~LuhHRJ zqqh#u%e9qtLFW0DaJAiWo^Xq9RTbWEZ!A9jH-Pu1(fy)yO*e4Wmj5N&C(v{Bqu%4a zqKlK7@BU|l&RR+qNqC@af&Q?~`$ezQ)Uc{>Dx+U>-+YGR{FhJef?r(8@B}P$|8!KC zk4%jdB1?+#^*Uv?M3`5NujHMf=BRdS!Dl%1T04h}78bIyv)2dpFLtJ0xtJ0(Ikr7l z=`ZpSKOzNTmJ_q=eN4-3i8Df2Y!)na3X6D7=ooWS0?K{ zz9w)zO;jRF7<#e=ch0>~Gz-$Un7+uWD5T%JB2iJ0rbo4A)5j9P?}4yJIz`0DDAPTm zhrSIV3dSmd;DcR14-~@6795=rPK#hoK(`AC4Jo{wMV&~9Rw{Um{|372PghEZ7EP@& zqRN^<2$fz{*L^}y>>1jBN(Pa6^oai1@k{1ZB~ew2VFBan3OT0?42X(#jBFt)ZAd=P z@l=(XJ#?4H93@FVU8T+J7>_C0)rgi<*3eUx<4I(j88?3f(Y&f~?xus9A!h!IL{Cfh zX-OQq6oCme`Y{4aSu}am{1*;vB^nBC`j*mDv1DJ^G)Q1RvmSUiIMx5>1rV7Q#ln6W z;vpTbL>>;Iw_&3@l${cIA=eQ~3ZWg3orKUqLZV6Oj?1}8qam5Cg#`H!l5g++eK*Ks zeF9P~A_>xlm<0!sU+_YHa-l~H2xO>qi=2LMW`BZ_EB}*KYulZk@Zey7XMg)eDhjPY zoz1u^UNA(yD{wK@-kT1MZXOQ{8kt4f?M#2I9<*P5Wo4N%A(g<(XTDf3fzw^QwxWB9INPrdjjPSz=O;p2l567N%L1)|5 z7AA{u!}W6I^M8^bKMe;>x!sj;Wj+%ki2H{q{^vSU2J>qZQ(}19e6=K*j1IXBqqz95 zB7XI%{>FK6QUxX01FQF&ljvZp@X4%<$m^NcUc*oFu6L?wnztu|u8v)D7F-vvS8P%n zb=Y6FZ82EtIvrxfA)+E9A+*apnl~k-v$ph4#3kS6=IzSxibu5F)P^k$I0gI-=MT!x zy-)m#Z<-;Be4iT1Fw{tjb7~$m0+CNKrb#kdOqFQT)e`oqv6= z0dyB6PgAc#-*t$qQ9wut1OTyth+)iVgZvX1C+NWd_xTL+Qs?-%PlW&Mvn zn*I9W^Bxq3YVBlL#fboX9n!A?94(;e0$IKZd^oP8k(z6u&Y6EycpV8P(AAxZcxI}v zt9u4&m6#f&URqiJjeD z;+Sx#fdS0? z9q>*Yo`K#(Z=l`-F$nD402N6Bl=FeOB*PjKnFzo^l?HWR^f?jJ(;yfb1UTXVNC8P0 z+iYoRLE>CL)S4D_-X!rqHS=7=eUg24K}yg4bcq%Vx9TI-%s}x0Ci<+CT?GT`BXI&W z)Y;d1R-_5j1*~+igbsniLGLg_gpW_s}=}y&Q4fnNAldRJloQrQA?fKLgQq?zW4Q5a3 z=6`WidpgejxEn`5i5B3sujCr4sDcT-5WH+#k>YuG(8{r3Xt=BWN&S~#%I_N)C>jiV z)&m@8BFeOxoey>-&DYRaeVA4b4tA*CnN-^INF@weYYtW}nhznI_&9S~Z>Ln!{J*yN z-Ke$SySnJTGU2?RP1P>8$CeN2H`R>Z;oV!87&~A~5xaJu$K{-w+w#SP3!Z(e<*L)@ z-_|hV{aE~c{ikjGXMV5yjH7je>>GG_`^2;%j`37I@rYH9j?>x)Gf5$fL0PX|SbXR{ zmBjN7+$io0?ZKw@=Dmx6M^|xii&;khF~1@=S(&ybHSbN*8g%EoDtnc)I6Jj6vor-? zSFYCKeu5iPoylg6D1H$I8*Feb5_`YvdyV-*`V$i--mk2IS6`P-IJ{P_=OyVY4%SyC zNAK(U3^3yqq6*?HzcSFjrI#z~pA&yeEyqUIBl%2}??!=0mR1Q(R=!&)7#$(gKU^Wl z#^j(@%!HG`3VDK6C=G#OXa0gdf^N~Cl94ioph`ng_2u{5$r5>M-4tZ4!C%S9(E02z z5LqWa)%x!1uBk8)UNMaPp^YS}x?&PAK_Ikj6S7bK)4<`wdxWk;M!-gkL_~#w13e94##fDZREwwnE3TB2lziENTg1dg z)nEsx@Y~mP;3T-Lt&AzN>O3^Rv2h3=Rj%KWE>82-OPU!K!ePTNlRto8Z3$OJorG(Q=&_V05UHk~X+nJ!QU6J_2 z%sPcUuaUzs<^K=IAUOpg=Jq?9D8!dN*bOpsL)reW!oI)U*_5oZpOP#$;84mX=+KX) zO|wcZhfHd&WO_6kp<$qUrGDa)chlSY{4FHmOHo*D_Pnzm95tBdU%r6AnukAu0;9D{ ze7qecvQXiyJqJjPc+&yE_t7RmcC41YN7PNQk9)LopeF=5?xVfH&r z)V1|L!f5#q{xB2uUmq3yC;b|)fP^K>;y%(N@|yQ=r0x4)@7J`1>RQKd-U7$Y?V7av z;$+o-;L;b6@&G?rCL+PS_-{}TPSc?1r|^4@Ch#xFZ2y&4tZ?V2{pY=A%Y}QdM*iAb zfJjs9t_!lN(@3{=cd^p`?zbuDU$_~0=4wKu341DgKpPMgBEaRyAM`)Pqq;rpw%_j- zzWfNt4v*P3z^(5NlvzB0M!IpsM;)NBP6}X0kPCQ8s7$~#5@q)U;ZblU`$OgRi*P1@pp)kZFvfx=xC(Hkl~2zW^WuhpdGEjH zV0I!-K$!mAEbvdFA`&$YI^>0fKsIrzC4GEuj&xuS!UJp|$R01G#TPI!NSDUIJY_Jr z2J?#asv4UP%7vYoZa9tOK70K8W~V51HK`_W_U(C?0f^68i)G^Ii7J zt<9g63s4UJ2XH!&sB;ix1t#EnFuDofw1Rp`ppSmZcFqFR80>6az@-mqifB9qMu;_F zQ8RAwbV_jp$15aF9SC>ebc1B2gRVo@VzWKM73A?{?RJE~s@)_FONJKH- zV?8z3aC@XCn$D47GkkWdlN!eYMR8h0dnZ!7qrYqQO5BXS>B_&Xw0s43AjP%oX$K{m z=mw*}HXk|f;)H0ze^DsuNfBWecrFiR%~&US@XZaS=*Vqc+cySsIUUt{lC?Ys>;qYw+1X827y zGtd?{dOc87>A38=R`@6VLr>`LQ&{dn^H}wedY-2eAUwDh8QM~MzjHBbbehi*6ZKPk zadCR;G*5EhzOo|VtGe_r?CA`mv4L4R z5g#ALBcHCjJt{BhRYX^Xn_T_4;>y@{u^q=SY!qs1Feoa66GAd=gY+!4a5M}&~p!elq zqyOyYeW9K5p#3LZFX&)`+A-cEV&%CXCAP9oJ6s=RNlA= ztkI{(dPMb>mX456hL#5xn^l8>mCb-?5E?8)hZPp0fm$?%#TqQ~p+_ya*x(tiMcF^W z>C%!v-kg7ZndruOp71{^Oh{tF*5XWYqL?5LB>ZNBHXWl+8LY~7bB&QHrxKG{9UJ3KVDvx_%Y8eVF$<@gDkb zXW1)OWb>`3-}!d-PWjii{NO@1R{NCK_VT&p#DzlSQZTnx$y13|)8y>zjO=WRR+`)~ zfvj#jjUqxc869cXV%7!rg|}bhcCx4P>c*U33vE)a-_?xHd+cbu!;QE^y}1#|JIVBe zzaN1kmK{b`DBEQ!u%o{cy<;|e=RbB9Af=~NuRzzu7$Yu(Fzgc-7X9PnEV=ks)PSib z!3&?TC^j^qL#81uye2DpAedy_pg)RNHzYDjaUg+lg;cN?rh_Fb5_je%8auZojIchN z2z#`Epxk%~hlcZFL`EvwT%7ZOy4;rznT{$dqseUtS6BYdW1|vTT(w7;*fAB+_{~KA zOi`80xaM3%P}y+Je;h8&IHMg9G}^dVjFu=$c-ukNxx+tlpOQ_HdgkI;ylN+cl7>vm z^4r{vFsC~xSPR-u{&5;S%eyT*b?u$nDm36SyYIp^JT|Qh$Py6os1kQkm)yO*Y7}yK z|0A0krRwr@i6C$q8grI_|qMLG0Vf3gg+e>6#yO5ET|V(PJF` zlV7{${=W2w_dhj*2R3_8q%NP8%{eCL(>=+XMyG=O^6!gf6T}9`;vm2#Z`D-1IO#Ke zo05FJ6)SOWax5Y=d;co0A>(lCL|fSs%;iv!ILgHw6k*W8(=rKDf#^r6wz9f z|JeU4W?TQ3T;D97rRT)`n{0qx<6;9AWUBrMK(8{ct4_N7f>voABLDymG z$4b-I1=r7DGb;wCVJQR#!d+m{69v_Ulg(7(-aM%_D6}uSRvMg)me_G0DO_m zzFXZ3jEU*g7Y&C$ZVyu3x|NQij7Kfw9M#KeGR%CBSKoPq)lvtF}R zCfh)ld&#zOzK7(RY~KXFwSuC_Fbw&{GgT7dYJ=MLP|4TcQJ^QZOa;TEC>0G--hEozLic*LCpQftP&#Hnd zy)c_v#_+>B>cp4b0xKf?YIg`CTK!~JG#i^WVdYr$SVUEx3~r`sB&RZ4YKpR@aUT^G zSIOWQpIl41;_l@|Nt1(+~QS8C>u(g0lm5Ss0D^4SNbMx5s zZhbAB5-4+l{0`u4pHuC=_Gz14STN*%)$RJPnHxfjS}5J^$Q;HR9qqVgTN_uN5gnbP z73;lS@(fl69x0yxeyunES63wQHEKwY^JC#0`YXJhs7kgD0PbkBVXO7hlQ zlU>oSZ(8`V2raA)*0B>fwU=>Bul<nHSk$puJu`I%aN12`#Eo0jn^b5)J~GXtz_pg@a#wD`-(ZOBzeS+qvU#1 z9JG@suiY+?4u+7r=?~Te5LZNOe5#R=o7Kk7sytZ;`cCJMrU?4`{R984eSlb0U5ZGP z34f~*20oEYuCdY9+kIXui!(C|GbV;V+%wftrPdqkNqP&(32{Su7h(@|+1DB;77w3cj^jS)7Axjgv@ zJ{}fYF(Z*a9bvExk7ky84%7gZn4f6+zZpy3s8A}lPc_ov$;xXXC?PV1B($U%VDqj; zo0J7(jIZQEhag-j(L7LAmFm;#$nq+xUJtsGD5tPSXY?=7DkYIF7#>%o)I`R}@X!}R ztt-IlVe&~;LV+OMSBLXSYKlB#F&Y{amC2@V-r&7kZ`RMmBVR6@F8RKMF$!k0@40WD zq86tR>86HcR>0-)h)~cVgzuNnBH~lspvg~I=W7LfHPtJeK9ka#TNa3?OwZ4Y2zFu^ z)5$VB;dNU$a-q-@#(# zNw}%v(JUK%ZrPC>z{Vd!cLzwHo^$)%d9V3L)(@bF zF<=GR>ihmSN(&3J_3xjmmnaX&Rr=3fjo2)aO78F8vV;zY+NqdRw(iO}}el0?zS)VIkLU!iw! zxbuRl){%_AEq%Z`WbPuss*-~bQ47W5)WDi`5b$_>MlpG-CV9KFBqJaz*4p70zG z5AV{{=J%}+?%z?h*mLpr*X0{0Jyw05GrJ*LZtlfIis7{Hn;adCekR?`2ekhVTPoO~i z^x4(eog!O!O})or+@j0F)ulds^Asq%warf3gN0?$O&^oan<5=sB?&Q7eNAp!onYRI z*O+Oedw~}6US1<(uJZ#TuHq9DlCu{}tM49OJgb@)c(>)d`TGSd6cC31rqBpCUUUCmEb3O$zv;c26rAMjzQ&}!wZb|j*TGY zlA5r6)53&`4T+unJnE4Dl(ix1WU|D@lDB7dlfc3f zR;GupDt*Rtwt1};Y94|YDpS0Fj3zBhOREwS9IP!WLSG2MkVi#*ii%EO_o>KQAf~0o zke4d4h@sDwksix_fHs(fl}7^08e;j5ieLhTnQ6ScfJEymuvb_0X-K~klRRmJe0cPN zA@fIwES4f0vzVZ%vkMoD;lCMj+@Ha12^}3Nkth7Tbmo$I%2@x+#2DA~5a%*|jP5nu zV5OVW9<7)UfGFX~aFJ10WmtC($vgEV4YLklEPd9c<|VZnAa^L%fW*2w*2NjkCa!xY z;nOF;VOPXg0y*yQi?L#up-N|BBt z=yjen%J7w}g=3-WXN5!tR70nV1TCB~S9n7&RFoD{0WXu4^w7>(eGp-4l-uD?Xl`aG z1wjSsFI=9T?AmMBf4a468tj^XJ{Srp%nR9177r|j6Wq^JiR_MU4TuG3-kABjIUyW8 z3&3>XaJ&Do|8O63@^DF$7nf`w|1>r|=sGv5%`=qiwnN|PqTr~vuPx5ls3tS$w_5Q* z(%AO3ewBl(F^vx{AtRi&%%X)FC2rsYwP!y}_MYhs3_3J-sXxkJTc zZ3=(LxF(a+r^w77E0ftf`;PF_kMj*pGa*!v)xQfR$*!eYk0A|+bd-+E%gdnq1m{kqj)35Qg~zR9>R-QAgQE7+iofep&k3>*Oftkb}!0V?D6 z0d_={%`#K zk88NnhX^MY8GkFCz`p?{%0--POu}k|Xyqa%IukCKyGcZZ3S+CRp)zqo*XvQXq$h%X zmtA0t)4Vi|BrA~~P?g2vk*UDM#89)ev?@+%Qss@F(-dKz^?0L$e@^+Y8tv!m_*bn# zkN1WYIdiHCY$dUX;0%v|v9mS(?{NuQOol$WE|nJMP`nNpoY-jgjSgJ+Lqx&{KE#~< zE^5;xIoCfEFNwhQPwCyRV5Y)NtKayW)e>p3m-$OQ!jok$3x5ZHmn>ed^PddjJ(-WU zw>~TeHTrwWoZF&TkoOWiT}<75>)m|E+EuB?zSQme=j*$y?5}hRg}MLaG?`Sk`=6H8 zjTukOniA#oEXyiKHqVUgFV^TiQPcCvmdj;-8ZfqawH9~qaG2+{x6BzX?pyJ2?Xa@T zy7kY0?C_9RD%p#&RA=WUbTc>To{S^yd*I*I0*1xBU#GT%_`eClb|?yw`_mm6`hS&rDu- zJ`q`Y+1@G;bY8KEX_+4!T*R|{*dK{WWmZO%gPPC4;En9*#Ee;wgt+YHX#5zS5$_L2vB(%{nF^sq*@{ppU z)VTA|H*Tp`m8r6Ha-s=}1tfUMzt5EzNi_|UvE-O?kUaLP|spmloHFB(g(ScrAz0+(r~rwim|SLQ2NT2rx+n`9qY;&vibFNuo}~& znyH+NCC;Hz17?^L>_IlaWBuc8gay~jtRNGfLY=sE6mpxP;a+ne|3Y!mxMI?mL@X$C zzVOdOPm{ZOc=T(#(+v1<=qfhkT@?!HtwVWg;!uIJq_>uYOiqZlS&|OhtJW0@ zH#-c<=j$o#@l(2w z9G*hQ`K1kq!NL+^m+msHKLJf4#SASNSMs<~z2S-LF_rXZRRhc{@ut^NQ=jH3J_K5w z{rr6-^oNwjduK!8E}q3$5gl^Ts_}||#RO9Fp*LROtyWeGGgtBZu!+0*bM$1)0+yK~ z*|B5fUdpbsf8WfL(}x9;LLjkw*>iPpmDlzBS1z+z`hI!jc4^|i+3j_gC~4jVUrna} z{MDuy;OmK%e!FBZpp;H9eTqW*&26;?(W6(~a0reaq`C8dkzMG5%-@h&TTpOI17BnbJflcqRym6h4S{JE*UmO)s3U;@)gn_)FtS7>z zlFm&lQ8wzb-UtjVK9fekqEJ7+SpqvibEfP@%**`iuLW=qx7sRkk=5O9F$dAu~ zLl1ZWOzp9AajNW5&r;6M*KMff>w!Z805~8W;OQ%QoEZNZxLt`nI&yVzGFsdXl(%aJPIBiRi~4eOM11LyM}Up zdYS?&IS4rL+x9?*@cX(6I?lZVn?oS|7$7NxZh!iJhG9;9N{5vIe`uQ z)Dkkt-?2Po;Sdt|)CNe6UJ>VU^@WQ7~y z&z)TpX+Ug%idOa`BRD#OBm?6=239m?TB_QZ%znm#8P}4hl;V?8TGY=;j`vDJwfJz7 zS=D1Fh6MyfO>x(15^HxwJP4}*7HH0SWvk*2IQZ& z*_l$cx;r3oyWew5i%-R$Z{EC^9&}Afl7S+2J^EZtW>u0Hu^zFNB*|ixr6kD~LLtFg zw82cftmv`|XNOl@VnUKN_OqkuyKvtUEln-Qm70^Dy+wx7O{(_08x`&rL4bnTk@EK( zWjY`poQmPnqlY~1+&WAQQRNL9(Vg`e&NLaew!JvZZMB@A?7>adS(y9zv*2yzG6KOT zEa3a_Tu>6e?c=aV5O^7O5cpvBaDH&F2Sr1D$!$bSOhJrllpt#~H9zBVbR!7s~ zzi}Lvoy&>XQH-08r>;7s*(K=8nlNPFANEE!L!pSXvS~mlXl^x2*5sJ6-`;zqx8&ds zS%p>Y{yk}8#4cnVY_PpBfF@KTYAWGptwKL8x@g+$5kH!^<^^X5R1$Zk1o;G-OO5C2 z9Qugm6)0?AMd32oER)!L)rQNiy_v1>`=YE0=$7}Wck$IM7Jp7vTzjvyvh#m#)rjB@ zPEM?kq0;&V(jp0IGDNVX$91$MPoEUf(p4ldG8WLve{>{^nWrbGmlNa_bY)b+)`Hey z)DB~e;~-QQc1Y*27-NPVQ>>wA(yaP8PdhqZW2f~;GyX(nQY8<8VkMySg~~9a;W|b@ zLMqT$Lm-U7Ogt1S2p9wkg&vP)K*q59Z9f7>^3zy0$_wD?IVXA z(%M1I7{Q`-;?%b}kVu6{%&4gNa~fVpY)ALDj{m|zxS4tJ|ZIt4mbMFu? z;*!xj)nQe%lr&Ovx0YcvRmjs|^V(mRbs6fIsJAP3FMJrh;dFcd+Y_bv-pi2gp4o_p zaBp$k$A76_X%N8=OgrCvH|A?ziK9 z!OHw42_V2k3>;bu4%PTwhkz6T`3CIbAWUDaU$Zv-2r>2CXzYaCVhU`741t<_icSqG zp1>jo=*3_?W1H*498fIfLU}g6% z%9MQo@{|R7uXas%?_wNdHCah;klFN8bexDzV2oo4GV^}`58eHP1F4>)r)9-U!r8Dg zGFuC8Z|}{~9AvB=xEO>S=MvPxv|$kw6SLJR(&rQ%9WF4OcSM~0*iH}UwYiQl0(P_A z=Ew(=DSr{iW5l2M>Z^9}C~BK^j9MW&yKjvYK@ihODQwUx55IbGO;|S;$ zYlN&)d@%=UijYN8ccHE_F6?Kof(6(-QNKJ|m2R3#@}TNFF&=XjA9LXPW7x82%i-0h z5*2Z1GFCaW)1<0^RgjVtrv=N@7pp2t>C$;4{WI21!?)zM5Z;{KM_E?3iZ@P`>#Tx^ zZzI)=WIO79}{H z|3M9;)~9y|Ug)(CxlZ?Qt@dw?gT>pJacifmj>Ok=_4ciNAt@|{=Jecl^P`rhT#_z! zeav5Hop?k=NydzpO}Nv?#NN-O-(SA+$d|fpb3nuWm@$-6n^~dJwnwDk&|tH)z;Cwf z#beh0GLeib=j%+ENeh8^?a`4X?*W!i@6HwOQ|_jkYiVjqkMW>B?so9adq0d%`$4AWf!22Qr7UQLx*RrR zdrn3_c78ny%O;{~`0FM*-W1yIsJ=3yxB1|6;w$z}2`A5>O8jova_E-{gO!cr%H>vn zfYi$6+83v1?I&63rgKA?71~v36}U~RYtqA>735G)Zhg*Y1LxoNSqW)HAAbc6Kt}!8 z#l6vIvnLsDp|z3>7y;M6^l)Ffd~v~)&TN1rlc4gd<>vO1g(YaQvCVy<>ygcehH?c% zqcNZmu39vRIisLFbDW%94C6GT*2WT3iN2CX?q;|JE2J2jruz0U4t4UY7e*2)3Yp9! zX;D-~S}Z0qrTlN^+Cp9!ME$Jca11nc!$e$*c`OXNd{NDjXKu2ENl6totWb0w5iMo3 zp;&1=)P#Xz?xRjaI|nYhT6I*XB&9`v?vK)lw=71g;kIi3Y(4~j`Ew&;LW4=-NSu?9 z=Nda9BILEzAw$1q=Yk1QNYM(lR$!yD$Rx|xAD-z#1Al@GMt-M``=t9;7ABiHa+RBB z&v8!wJ#^kMY)gr0L3D9JG?j>(Nh1eqXyf>BJfpg{Dmn4rwU&+e7VU^Ix%M(W+>{YKzgX;})m1NOKQE=xu&J<&XHB;+)T*PVZ1SQ3IT?BwmT8-$+6F;2}Fruf+>AdwQd+-qsEdH%8 zX+q-le$UluZpf=`0V8kGmxrr(P!uAhy3SJi>SGv7wrcA;(duJ9b>}J*#nkk3{8qM= zGYI6H#Yr4%1_VN-3wHjn_p`+lJ7t59A+gCb4CPa+e%pUdnZj#*O1AyLqFvXXw6<1WOLc-?*fZ_&xY&K|+OA=o@TJG|WEV~m!DZE!aWLt+R##V% zh^3XQoR#g}UC>`)l*9;BWUxcI2F-$b7#0V=n%)Cw;F#2dKYPUfQp>Di_Rt1+)Rt(k z41uIe0PtM_Pj6lTC}#zhUt}!|Pzy#u#-^qNoYO&q=XHhtQ9nbxK#~R00eufv=qIH? z*QH1b+~uWrnU3KP?<4S20ORzT(9U5V@E{{M>Y!B6tk!w}tZxEV%o-f$K?N)vq~rmI zY2{rPJ`!68{JOrNHlQSC?0;0lbQ8~cAW|qODoTt2f7A)c9s$P5V+ha@K%#p2qUU)a z?~E(Zrje-DHXZg>P%aI^_+}tq59m$=l){HDL21BpeC1Hp)O&F^o2nV;?fqS=?3e$^ z2mmw{ryL^{bTG!;`GbL2h?FRRicU>KgGBj>iHhD|0|YzC(i!NdK0jD_02K)NrKO4v zpv-Frh|pw1;=nl$@UQPlUVcu~TE=U(9we_NT+_mrBZr!h{(^ ziS*|QOz~{8)~kqyB$k0fR0z|XYwK6cHYs+WbcpoxQ_}Q>)k)CnY`qwQH=7NOq~q3v z@vNK%6|c!W4~TIV7scM5^^;B+IugQ~CwZ;IwJbpX4h^sRb-cDbwCsUB=nF+FDq`>nYEb{-U)A!Y z7@e7?056vJ{oixE#{}PDDexolYOOMNchM$eqsk=cRfOz>o*V0;2)zS|u6s>b#6WFy z>o0iT^{e=Y!>EA{o0SV#G&=(#xBcxmvlY*=G0BIcvE_Foer+C`>4k(=3{zR}lNcvr za)n&f^}IGe8hL)M@wNAOC(i~ySWSfbIMy3hVq(VQ)sr;d-P%%sgNB#hW~$zgQn-Lh znd7J}vHs}S^Yb+DDf#ekW?_7Fe7q_L)63cK_U7TTT3@;O2Bt{B+%dXp?(S-&NE*3B zHD3fujfXg%ELK+1r$|V?iPZ4gU~W0))`>p z*IG=gE>l&1aE~0-3lWEn!+F7$?blWzt84jlDZ-v;GL(3(y0qmnGf^FPNTIHkJ@;nq|tv@#0V1tdhNaKlhyMQkx5NMCtk zjcT+tuexg7PhBmMCd1Y^2ocygO^5ZL)frNlH%Rw$5|WZ}@}bc3Lz0!Alc0RHa!M)f zKE2)2wmAf@rjGE~ZrYG&4M_3*VSj(hb!RF1XJhKg-&DbP!e#IWmjlG#rCW^i$L?NU zLW>2+U9Il&*|wj}AJT36vHR**l@1)fBfY@#^l9Vx{a^W-yPyN_qwqM(aIb*#N0PtA7@4%)Y$3wEYp`)JXqS$(k>tob~^e5MJp z<{NyDh-*twr5qS*IegLZ@NDJB^F_&^>lCu1Ey2uTcS)w!N5!ZoF{-oc^E+1S0~BtT zpIRS5ri$$(_^6E^evf(NUi}>WS-O~RI-$?UPLt!9R+hyGw`ebUrI@-Mw~z04$T08Inms#p! zCGG7GDxlo42RLlO2mxw!xmFnxr)M9x2juJNw{W3iSI}p60P1xDz*m8WTs^xBmPyO) zK~fO$!;VL;l*mFI;PL_Db|*u;xZB8!SxVt|`NrHFC4WbAK#7e}^(+l&u?3c)Vwppr z5(J&w1~q_TV9ae>c{e{6=y`eg8(ConD#*ZH3u)3Nk0XG9tdM?_f2d0zKq8JSJ$(#0 z^SuLa4k;H3TFuQ!W?=_YuW#-Uo(G>~qcz*%gTpYj#PgO#r1znbZ zk%A(am1{&J*tlPT8Zl0jW`Pfd6B85d4>#?=Q#CB!+Vhx7)Ex{hPQ!XT;FVTR`nTMA zL$Pw%+uyGw3REMwm6a88SZDh`5=cE`c2RTdkwEUoEHj6QpFqvIJn9=z-|h6{;mMkh zdY}{GqDjYulA%HQjO6LUQ*a2C`RSuHJBRlwODrXg`Y%!6By?+97Scu&Im8B9Ebi}D zX>qaJ*822$;LLyKRiF)(k?wyJpeQ`3sYxOt`_`$D@f~FpFvgHu#k!hA4Uk&SYHtb0 z?e>al$|@jmwznBIVG0WnItp@Xibm^H`H~dGg1(A1Zc|~ohowNUJ7sFu=iTpGN*K}W zq`}}E6v3`no+|uTOT`HO8n@)b>DR&fO;)?H|M2V*L>d1%i8&4Uq*Gtde~ep4?fTgj z#XjQ;&3Hd%aJKrK`Wg`*L^Nt}Tl3NRa-&tM+>?6vZ=GhLgj5$~$z;!{p}n~LD03*? zy6*nAN#e}+I~Zz%@^DjJObjos454x@wgaClhdN)q;q1E0tld$W7+3?p7Rk%FZ1g_{ z;K@6d3-_N%3c5O%c>ZtU&AIL7^=pw@txTwNlW|pD3~T`o-oiyYjx@gGNS75)r^S%QWI|GT z6c|Dh3RA`?DP_icmF(-`k)%q^I3<0CMGRz3EiES*4KdjDOzASHMEu%Wi@Aw}+HAiP zNKg~tHHJpp9mOf5Q}0Vk-9%n3pg}{F>dJ}V$wii~mmf|CskRb-(K**1tXqyX2nuT> z$pC(5VD!jRn?NcX)afg3Lb<|E%Zqv*27`Wlt4pyLR0op`W40>08vkz3gvGrbN9AFo zT#713nEQY$Z}!8;vj($l5P@`At~pYS|EHTtui8^2uc7ileK~i$$j5!8_*!O<91o8jA+CxvZv@9N>gof=gE|Ry?V?1;G3B^`8Cn@ zj;8&+-{Rmdgm$)$J!h?PGn5W1i;(&ITBXd^H-m zG3;L?>2I|f0@@Pd;@CfVGL%!uY~s&eOv_15iHcR>Wqe%|rozf!|FHgqu!AuKyA*!% z$3a+CRaKyq=3;L#3Nkn#z;2x^-ArcwG1`Jet#Q5YZ^j>HHB*AFt}d@7kJ(eURM?yA zlrT(!FFqA!17KwW%sxT^gUHAKhZ~djz<{D3K;R~`^p~rAB?1&(@a1&hQK7FhZ;`fO zv!)G&tP`Q)i&f-N-fkH`dJEJIAXEPo+T>iGlk6qHS)-cXWmcI>AaOb#%T^r_sy=us zN+SXu%8A7ONOv2#5qL2mzqA7?h1SV~0@kJSn9d*)c~O7Z3Pg$*J0ilu-iuC+Ilc}w zU>p&`Y0!S=cr9O%Q<&A+;L{6MtWs?5HUTN(&G)O=r{%M|{OV?p#!i6C$_vzdo-8sS zz122wIeyw&n`2l<7#PMFBkAt_RihswYwM8ByPz-F0r@=e2m2+F;^2G#?Y9lGFmnx} zCr~D)?rysxG>0|T3AmwCy|`xijM0aPtGebok#<(9y(=u=vHK6Zc$9NSo&o8ReJ5>Z z=dGU)TB2;1u(?p~0>~%-7jn zOakf#$7kG*+q>B>1YhHKeN7l)j|#dUmy0?NsAm3Gdmab#)6?@Ba{Ns(;d#AtLhx(0 z_F??@&w}F!hxGW^Slzc1Oe)plgI#;Lwg)2K?%U#`yAN%@Gu5(hqRw>{2PtTlYs_7% z>dNP4bmvYc3*=E4#BcsJFn#=M;`_6S*owF}hJrhvOGL1ub-tUPv^|}8@9YD0ZYvUB3|#C)IT4H2){vm{ zGS2EJJvLW3Ni&C^+KY=zFUA7R`qqAO`1I+yU-nloUB%Tnv7$$advQpAXaL#Yz>oSE zF6$$zL)`8w{C4hSD^#(PV5~E{ifJ6B#S)WI=geR0--#`&Q$Uy$31k2tlNP#r&011o ziAV#GQB0fc_zbEdz}E+H6H?RA;t^I)Gf=aVCu0P=79d7MvQd|j(F*-WmCA)zyB1i< zbPnP(X<$%O$P1wan|3B6BL!L#Cx=+l$kmm#qPJH;Z~ z0U!UXFp}%~o%E>5f`N>_2M&Eb>?@Ds1tGunW&Bs4AH6KjGLsuVW)xJEzsIwz)dzto zN`WV^?+8+W|MMPj!rvi-5~A}4L20)|ZP9PiXMittGr1?{ww%>K`A*mA4%fNq zaJPetO1!>M0y|#K{a`QMLz+&G8YHO@R;E^X92(+7+wPfvy5)Zxu|ZN?x;i<8&3c6* zC5-KMn-KrwpHv&SonUBaUw)v#4y3FHV-Ry zZotz;2}$L*M8E?r*2_*NT}`f>eXE@Pju?_^G%E9&bHyp2XFYQ&)O-Fp-9%Y6y+!ua z4@d^y0gvJgV9&7f_;2Oin@!bqz}AxiP>TUF3l_rjOU`hHKqbJ%`S0un#3yU4`r9jg zfZPt~WdC)bH;m2!@{BX*vnAwwis=z<)KViqJTTaB4Xpej4{q|h{Ob44!I3)^LO!n& z=xeff$Sgo(cudT~28JL7roiy(>EtpZx+S(f&}trMkQ|zm<1KYuXl}PlJKkF0P@|twX}8mqio4knZD~t<{W&M!Y3#5yIcRcjF<1hb-CHJvG?SP z!P@cs-Ow?WXI{EW%OyDCbY%32GN8*nx1lt@ve|8Va7#Hk8C6d1Wee5ArskWCkH(LB ziMs^<4{fE3_rML6eW0?CF{*b*m-MqQPdV*{VfFgGY_X zh1VR-yVo3z)*lcc$%KrAXdnl&M3$kGK`^DD&&;eW`w*-G;^x(_v1AL@Km#d(s^42e zu&L3g!IB^YqIhaBd=X|CHXPCKa|M6 zFCdgoGN2>>$O7$kQ5pVCN8fwV>d?!VF56q83oRvo1K~*p*WPqct7Buv#xMESC!W>x zIIzB94?$$TfWeJIWizDmQ>*yJxs50-sC{{I^_AX)5i4Va=TRl6IT&FFPxtQU>ez6i zg6145M7v&5m%UQnv=RGl#q_&(KKI=O5;gS|LYz{NeLPy@rXyO1u zsZj(_Dju>*NO>_ceDZRC?DTDFoN-psYfw@5)%NIdJ3TPC1LnSeUu^-`sA1@k^W8wC zNqkvl+hZ8XJM7;X@9qRvX>~cVX`b>;-g?+mlx9-}aqO}`iwI`|qVIUMi|IZkIno-U zq_ZyMrGx6j;|1e2N?*3e0`bzMvI=k9pfqQ3c=!R~8TT!}cF{*bWc_R$7mx{|jOR=&7AH z*BiT9Oq0hcR1yv&L1Gq@)P%u(P!&*{&G829$lC`C0bo)L%SFSktgUw^bEhmRggTg z%x4~YjY=TDRvc$LXJ@FrpH9o=SE8S*u|1c@5!0bkiu|y?3w6_ zn{P-c1$6;;=p^zW|9c`dNvvM5MU*LiuZoNkTAzC&Ej^3oE*kRafzzl#Y2X~NTy|@X zO!;S7lNM=aSUMF2B_y1-haNXNDQA4BNJK2JzVZfP$!yv@sxVAy0xys{OE>)zOTEej zXeb)GYe*(s@dK_~n@Q=+r@j*U;eM%HP^XGwCKU@xJ>0&Wv9&S{-!U(N2?sKbZi-+z zFi#bUpQ~9;_?cnj!FZvpO+5VfKCK`PBK1y%V7uG5>&ROFOLhNguQS+Rk!*o{p9r_M z1N(AAWqMHK{tpl2_qObgD_`r#E!7V)AJ&yQIa*I&EKdGy9R1m^Jv;Hh_7S|uDvrFd z4#1C*2DVZ_L*|Lw zWPri6j(v;7%GVwqELMEn&{r>Y@P$TE;}iVg*=>*l>pqVh&;2F`4tW`vN-}pv-Jng)gu4$gKr4^$&T5OlNr70n z$W$blq4@y2D}brzKi)fOL|p?@I{7h;MH>G_tncE9n4)X>A(E%V2Eq`I0~<~O;Ek!pKotr4OHQuWl;5Gh`{**4obYDo?Xt4MkR zQ#=PFo4kakri|!FSzhYOseRIwm<=XPoN;bk?{+kG$LkE2&GrhSXIujKzF;&c&~2o! zV=fmWiOdm8{V)B(5EImo7KgWOv`C6a7ND)_gg2>m;uphxkcprL7eMg&Dm77WBANLnDE#nJ+3A!brSQ*=Fi7@-^$Dc#OtngK+3?@ff0&PDZ8iAdhN(I+`n~+sG}Aa7k*5Y zoyZ-`S2J$ksaR4DhU3++a_bFvW!~FTFjiqj(f^Flgo(xw&5=V49TERc-~sl#u?|WsW7jK>fb4f0nY@pE0+|yt zS`I|TfhgYuJcowhY9H5|>&07VOK)zT|LSq1e5YzW8u^FHxYl$c+TW<~y)F*DMmSZJ zY0*e&eV@tHH%1Y$awE7_UBv8Qo3gZo+jjp`v;7sO$r#cYp{&LV>;;ol!b0@`sksO@ z<|8lrP}})mM}b9OAj&pZm3VbRX#oG^z-}$^bt$Ie>D*7k>vM`?kO;!_MN#vpsNHyq z_|>s_wIGl1Hms(kWUnNwsi5{Uz83zpfGy8!vg5u3%FQ1v!!Zmgi4`VaNjNgf*dK}+ z&yv`KXnEUp-yZTdPRI7X*T*(0VqFhHzla=q=jcbhBtF_lNo%umI?=#zH9)A|ez}-1 z%gQOz1FntL;Y=A?dAJ*ko@sfBOh|TN{98mRaa>R<{&IvWetWG;{IjR^;a=$b!bu}0 zG0%Z|anfl0byq?$8u=to7V>B96?J6LM$Dr2u9#0-l*CR24aIJ{R-Xtq6@_` z2@f9lZ(HjR_l57e{g(MV{x!(+N;8pz6#fu?yDxT4V#!tY=ndY%iMa7V_>uH7A7ZaX+}e5xB#CcgnWWA4jX+Y{Yz3>bwbfrkuTo z49R+YSpd<7c)Msc-=O?ioP4 zhW3I`W33Y6o#u62O^8{gw(pZ<>#)^ zt1e(7S0PJ6$q)8l^KyB3xVOV26VuE&CO@ramCG_`a#LXRuFFjCC%IY~kkV3&WQopn zesL@!&xIyW6QF~GV&{s?OCtKWfim?3rnk5j#wEy_KMekjS}(%u5iNjPjnXu((?%-tU<{UMG&p%#2ID-k(RCn^ObD z?COiv^-Mb+t+z48QBY;)m#GzW4x`Z?nO&D;tMZXNj35)1q-c@0e4~oP1(BBHf=MU8 z(?F7P3^fyCr#FQ1q2Fi0AF2~wy>yS`fZ-u3rqZaI4(lMq_qgL%pqS6~j_cg<@yK>^ z(O#M>Ua;5_g_)S>apSTB99Z&fDfyYZ`sQUGE?)GjAH$k=`T4w-zL6NVG#>oXeR8QD zvyU1~;proBgXnO!KIUn$@NVtxl{gxD_#axl#QnPsksTTlKfYxzthY4h-0`*bZ2yyT z!L#A*irs53th>8;<-H3t1{f=Whr?gY)Bm{Vmv1OL4ohl(3R3Oyof%upsxO2UYTG+= z5WC)aB1TW`|5Wk~xrXKYjjaAU=tbvs2? zDxG;Ug1$oeY#IV)KsZ(zR3RNCWT6o78v%Wcz(Nwu64@p~5eygACL+yz$PulChP#y*32`}f$Dy<(dgmyzmo0+Zx|WyBqu_LZHMrnvLk7Ul^nc%1T7!Sr(u-)am7?qHeD5VDO~CJ+RjR55I(E1Y%9 zQdBw_lNePIY#Tj+FPp68l6HCGciXE!>G^1|3o{+rvaIuM2I7O4~F|D?(h?f&N50js(S{jdKH{S%b% z(}tH7Mfsv23e=)#FJ+AS-$!%kR5**3-xhA8&7fm-j2@D3zR)!bK|}8KZn9PUPvrc3xFX`*A}Z+RdRk^1b-DaI8P6-|Aov{Y<;`PY1uzFDE}{}gya@@nZBXRDVh=&7dK`2+#B=64Dx+` za|4o8G9A5W1aXZD^^X>OPB_uBDNSFvPleW|`)9iRyRJI;U zT>XAUw4P$@9eC}0g~WgMt~x3x-KN;sxjF{LLQJ5aH!c>0&O7|S=G+PF4eU2suQ#pK zM7jt$Q**^kIf{#A14X7oYr|{4J1oOc8Y&N8ibU8YzGR~igI~TBr0g?qZTuI;TK5C^ z#i#@&Nc`EPLEWLXZ7bd%R2un1^GKW~KEj&v5Wj0b*kR8p^80@u0NnqavU2#}d^~r5 zg=M?-iHeE&0n1o{`{NsIZ0jelFvAg7C&Aoy*WFo-ZPcRGJRc(9gAsiZ=2B#&mesr; z<{{ytm_O-%^O+p>MPGMhbkof%v(|hY%eCSS(-!c8gDCO@VufRF3zqmLnc?t8?D%L9 z#cAx`5>1tl8=y_$BT0=I$>dMTz%XeH#xF4kzx8C`Gx~XR!m{qCn`@6^Wqgi+%3`Jh2 z++eQ3Hw``yHZ0L0<}^;EvtP(>{!V2KwYS4VF4S}xh)*^sueVerp~3uaYwH3 zZ*VCou<|!Ip``?|X}+SuI!Dag_;$;|>$*gVFZ;-k-2cdQPHRVBf*wc}WhU0JwC2h2 z6qFEb1rfOY<#G|&s8G2igRx@ut-0Y5eCTm<40z}r zmSX6DxXe8?2F|z0k07MtM(FOq&lJf-m!aD<9W#I=Y9OOwc@9p{uvl3jLa=GLv+q>{ zzH62Wa--0ba^MA0)8@^!Ys$Vu1QYaQBOv0}P$_*OU@32`>b0eErLc}dS?}+_({~Ku zMvw`ph{fsBE5wj7uzSsnh|l^eoM$5!FS*|U6D@j(dHmmQkC~t8pM6W^Gzad5Io>+| zhF3Cc7*)Ln%voG&qN8rUxLBxB2Bb3sWE8r8`?ZE|#Ip28(!S8k%X9`J)3Zfj8K`Iz zprGpn?aOQ`#qjQVIYG1nxqAZzH@dFGW^7C&9Ejkh78cnbF@pKvwn+W246FtMrcge7 zAg6EJ**rJ)DguWXipKMGxG6lZqy?L7ZCM|^zCfc}-`8s^bv zmF@i8qu}N{0Ylt!721O2@9BTKYLOGg#viS(%-nln25FF!9I2oR>5GrOKAeOh7vK5nZS@`%CH}`tAc8 zaRMDspT^z=$mz=$YomVm(kBki&Jxe(xKuo^w^klI4e|UXFE3L*i28;1kBqV_VCLoN z%ir9Ii*37Oq&b?YfC3UANC93cw?r2x511OHp1fms*c`}-Kl|1SK83i**JcNBTL0V-Ea!d|rH51(iVl4MDPahT6 z%%Hbvoo2$;A8usO#K31W>7);ca*(}nhS4LYEjkNc9Bun6K^6OH)0gM>o%;MK`Y>~J zc?NP=p2zq^j~JoWKVb8jnoatKlr$=SHcqYjL;vQZ(TK9PcKOV{du*3#V#(Bg@7Qej zJA}Im%t+yd1#~Q1$Flm4Iyg+F-YA-`HlU@j1XkSqGyKuP_jK&nS;-!S$OEjSe%t$N zN&XigBQ~#DHjI^~(wh*hiayP5?e?vtD;K?eeND~Yi9bN58l!pDXVpg{ z*HiYL6-!S~sHi4i_q@JKOEVJ1sK?7FaD-TpYcVxN|HR_`WUN@~S;W&?>7T-=Y!)lz zc`5-!3Drc7rhF^LYCT=RzonQN$%~z@e)K2{7c(%nT^xxpGI|h>(=MDG8Tw*0@Jx;q zghJ_l0br8Cp_CoE91b>(uYMZtXaWV;18Icjei3JB45!!I;mWG@gxz!G7PDVnJT?Ek)`F>Dg=z^I|Sg# zfPj7qIfcc5YP>M0`L7Vn&_TIQ!nT z#eCc2V4T4KZFR~&Kjj#U@bH{xiyA$r)g_ofg3dqAMKw!D>R zQk!z2d2Hkf$=QDzb@};E%%=y+49Y@naq+Y6C3bf9cAfY9PK&cEEB@mLD=SU=i(eF3 zYSrlXxKb#LDHk&K1mA)h1q`pfVlFLw=Xa=Er3^Obnq@BN+Se@{HYYtMuiHD!o_F^n zef}wnKl!h`0s$5lHJH&ekOPQ;HsKv;sXbW$Wj3igQeg?Al^y**q<0G#! z=kr)sFXjq6+cH<%&2jzK8*2y+9nCHsGU#K@rSi|l1ZFm&Lh*WCk_FJ}f3$}kkrl7C z9Dh0MjMn6&a5T?%7P$D0m*mGZh^;nXA<@I<#cx{rS09w7Sr5Eoz`EBfR%xBX6Qu#*gxjBs6 z+q>zozJV$hWm_5dyN}NQc>z?2h%oP{e$(z04CwvLG^~k7Ct75Q8s?E%%`Br&(^xAo z>q^blbBK#ZD!@P2d}Cf=W$o>qS@uzbrg7&!JG+F$&lp=Olp9bbjk%2$HZ zDtiDP4Nod}j0`~MN{V$U;98Sn6PmVdJM&ir z_i)xd_AIVM<4q?PNMfgK^1JsEn3r3KBDfPB5`EJWS*;(cjoD>iXncMljBY+v(QRKo zzdZgnH1I&mM*d-4R&35e4f3%xxpzN5h@SBMQA_{fXnMuod^UWWwz>qBP;S#r|2tZc znI+(C*45&ptUHL_*2%*Bo@*WcRTS>O!7dS5{?g!oSD(9a+uU}==kK7xOp6&ZPOIK> z?M~UabNwQI+ud=`=j-eFC%^KfadMQd5VdG9=kBn4-aJp+L%x1jM567YxY$w9WhmK^ zu}thZV(B5)OiQaI@dO!^RjKn!2eWIW$C1&!!YmRS=a^O3_Os_Gd&9TN)>e_6q51}B z&dvITVR{C@nMX{%VmtP`f>{1K_2$U*7Mndk%?H-T1Igc;Vhv<{Zp2-$VLNm`=JO`Z ziVtO+3d!m>Ge84i@`~RM8IH{Cv}AFay5D01yt+8m6Q_T?ML5MOa#6onyirlk9&D6& zl6D;=lsKVe93ab2N+hsh(r!_@O9-QwXnn<9z?(!qv4_XsUXuqFOM0E2g*^M zms2`|cajB$W4(tkr)ppXOc)VJ!>NM!f&`@r5JOn?()T#}<7JU-u`R%_u0Gg7*l85P zgn}^Jr{XX6(=jpZ-;+<#cFQor<54=y-A2f0XbPcx{09$_+*F~+z46n;aY*!*fzH_+i(=XDLh(+DKw%H87Ew)H zWf0R>T#R)lyR;OMkd+N?P{PN@$o^dg^}D;gQ~~#-VKGz_>+7&3D@bRq_IC&(1kuY= zq4JAq4LpPx6egcxnDL=-;Rpwbm;(R(aXmSn4cIWMDNA%BzXrLAdbEfp+6ehTMmk3H zY8z|B2Vr9$Lqd{rthmTOIuNr&E~|HWRD_{WbLJT0Mtpo^+Yp{mUStr28s1$H*F}p# z8pNH9hM%f2-xS+>`|oVEwvx-;yEsuLO#h!S{>b2%7S3{4LiwuA%U_|nd(N3Mf!UiC zjCDaLqF?_#!lTz8+wVBK5{|Fo*YzzM(~JVgpf|Rw`rYf-iw`Sb_C+KfcnfV%%gPG< zn~pnU+N}Jj4*+dJr*yi~??s$7qb9m_wa(a-WA^rubvg6XWtZ(`bs}@0%EH-CH%_sK z?wQtOcN+)2uYZ5&R(xu{ewz8l?X#^6a3vQeCR}gW1^yFqbWQxOq+W}FWHbPD)rR5C zbn-O?V0=i{TJ*5ia1u8ZYRQ-yF7=0vv(1bD+kE6pdABfcgeFAn_v-IdzUxnQfB*G1ay6%la&oTRbQe?Y-1 zMlRQX)Sv$LO?;mNN-L^QGA~9&c7D{xEVTM}2&<0Ij@$r<%M;IsLvFzTy#){+6Njv3 z+)3nOBnbbPHG25t^otOrX>~o^p_4j>O8HlPpH5sMumwS{FP8|9c}ky z(R96Mj#(Ss75J?3P{2?9cz2xoM3b#Gu}~mB4Lfu6cbgulY&tBPdA^c3$-+~sze`wo zX|Q$mC)atJprJWPA=WRQwC^MIS%m9LJf0n`9E(4xvZO~Pt8>POG*_r!rX)Ln0t!j| znM%~4by70bh@r_$Of&$@N&wJA*x>T~b^OQ&B`AphftF|%f^fA;#J;W$drso7as z{-i0z$#?BEI%~4g$MZb9q4g>W7ziyaXx!|XD!=VC|I~l+^MAS84JuAB*8|U(7t*r2v-qV|8X`w`)T_UMZIDgD7Iu5VvB}%KGwAq= zNC^59Tzx-_3PkWhwlY*zZiKJdq>)1dk`WN>90_HIbAXye74+Z|BM*bNLLI%hp zv4TOSY}o78!C2w6AkygJpnoD#zg`DXgMT91dz&L_V-eR)*y$Ricu{rECrSvQsqpkR zo)-QMq^6EO-h!p?Du&7pY>KM?j84&DYnN*m=CBi=Yv9rA#i+t+ zOWhp+TDvRp&09gL_Z&w?-xkmMLaN{HQx?v0eF2f;W9;cER~#UsI~9T&jDHR$1fFbS z%=v0hwlOA7M1M~FA*LJjH!33Vi&%gXY?xFqUO8H-YFkr_|EDE3N!|x0;`3yMQYMwW z-#V31QEE-mm~CTxR2ER0zX%9rAu^B@5iA&y6hw(Yw&MNfAh@u6HJmv@{7sEofTS%u zfd#S*ak##+LO6d?Q?d9dX1}{gN~#k+8;D9zX5qHbpO~A6C;t8?|9>KYXxQhq>As2m zrE=hmpJR@;j9LeDf!d#h4+a%pM+1~CWN8J|5-V={O2O@`uQ)*gt}sy{ zApkb!ItqU-eK|b$Xg&D!9=ziAvVmkV{XjYYb;i%|c}vU0Yw5ta;p@>n71}*&Z~J8- zC-<81O<{&$&`h;XAGEFQ#KdbWDSJm&gQ(BN-`^jAdVtN}UH7Ksw7G7TBCI<4UxkK5 zx&xAVe?J-s@OMI-ZwIdX#GgEzzumoAdFml4x5MmvNK(qH&bpIj%%F><=rerXGtJE* z)|-`hdzp(0($+p}3DPjTM>C*Y7%CX0kYJAS-CB4udAP-b zo?YHRUDN(h`;$}b1p7k%{5Zys`G5wL+4{=^z=DEe2_D-{ZYTwjMUgB!dc*pH`fyeJ zw=o5H))=5?Dv%r;8%>>A25Qd`l_4Gw2m+EEk&W0%aeSw^N-V5mBvRy|sqw(+ADgL_ zSL{|ZnR#WBOOf*lGD80hrf#l?$$~zIC^s$qx6RIZ9*Ms14_~QgDFNUi38wST2BAi& zjZW@m`4|>myQy1EnkZuEMOw|z#aVcbxHElt|NW*R?7X0cqq$lZvK_|3hl^R36nocOtIhYNFL%TydEDo{66 zF@S3ZK(|0?eafO^NI$~%|2QvynM{hR%$G1NpcSR1rEOUDJ^;dO^Gy9GC?rOoJ4tOa zU9P5e1(e1mk^I57TnD2fc;mL0kWtCU6rfdIjcpz>Baxyxi?5pBm-G7b$VD0(K0+=$ zlp8*!4fs09NeM-ta?n|~QK4l}wksmJDmYiD0&&`ul2EkF8UdlC0@mwT?iPax@ZZP| z^AWxY3p6=>I*hWoXa`p}^0uxq z96u~nE>BNLN+n4MAqk@4#b5;VR=HW*#k98!jILB)Q4eGtp`sM^%6;TxQB%L5LkTz= zD3PLWXe_ocwd7JWS66y{ps7Vo%Y%xGZB-y5_-@W)Jp#rsw|H3T0xZ~013gENnKGLW z` z$PJ^hQ5g({vr*Glkp)sCRUw<=j}=+38Sqlku?o@B^)l0MqoaY9-b)6=>r=_lP+4H% zp^ub9Gijwu2M7@KG06w)5s_;Y0{Rg;65w1Mg1KvC1ax#DnQfnFZsPDne#s85e|vJs ztCEo}$g3S%tgf#ads$>kL+E*I19%S_7tJb$d;{NoEdShXKy*M?ZGah8m{~oM?sn|0 zR%Wg&(_g0=^`Hmt2@qAOOZk^4Lk$~URDvp**_Lsrk0NW-HO^WPVMS>-rCh0?K=<{^ zVTD5ISGT*Kkc@9eIUR(WObCI9W3X!v4lPLA5gK z%}h3~bqyjOTXgO%k)V8UIUsMG+TC!bP~yT2ZoaJ#pc7G7?Z(Nv)V8<8Ns0rLu5?k z5{<`9?IlD|fzxTbOzpDivVSwc9fJTn&#C{-FBPkc?afINUYa`82fn+UCfdWW|J@`f zNF(|yyzg{gDk+cCO?bEzPo55AM)VU%NwfC%nSesOhPpZ+feHc@R5;Jo6l$|TojffB zdC@>uPYpvw;(V>`m6eeUV zdm)tVb_-L-3z^$({=OG?&0miIdL@v}Y~4%aXhX@E_a% zGFG1NFP?8FqDt8BIyyS^{m-Cv)fh!F=nL8I6b%gjh$_`DeL_Znr}dOMMO-1nsY&Bm z{Zxtg!hFUQ!}{QF6NAgM1OLapjCuxW#2LE@C?J051oxkL9ndd7P-Br5# z+$>XWG|qafD5Kq#mtuEy*C(TNU;X!u%M^(@Bu>hrX8caEd(6*%uE6A{i@PHH)PA9Y zz=Xz=JRmd%T#QPp)}Tv_wP8~p=!)GjQh=%F8xWDtsIjL4X4d{>;*Cw-V^lhnuf8Kj z=*jDcSo+&Uw}^A~()qAgN;e@7=kw7Sl`m5xhTM}nMqehhyq-Q=bMX-9Q}WCcAItxd`*|wshllOoD6R+5ZKD zsj}%@)OZ+zr-#?jd2C!6(y}$bOY_Ea9e~4Gnr|qtMZ>6v_;w`oMss(==`=wfhIf#^ zd$UiON+Ocb;3PD`bGdeuP|C>YlZGQpLREf*zlXbjjF*9qVT?fV?X{p*Cc;j?gg=tN zq<9mA86y;kBcSgZ_>(fJD(K=+b^0Ql93e6JAJ97Ecq-hk^)m>PKAT2pOlt9J5aGrQ zA1+^*mRQu)oz=Mtxg_ox!W-ZMVIJv4ZEWZy#nK!yy1G8pDTXlbh|?w^l5nPAB+$c+ z8V)W%hl_06zKmMw3wtU9i;8}Ge5H%yByoEl^D^}B{wGtT}4gEYI$ysTTG0w=j_*aBvzfWZ;xkLcabmsBdDDId$RJq zeWVZ^`>T>P(!%IP_mhg|lc%(UXIl*q^%7=(fT{b%-6PDsdH;6HkClYlLYMhzFAezO zE$A6lLXKb)XJW5Qf2CEy=zI(@dCEeFKmN9Y?=e}++1MB6*Z-uH$IO!BPme?x$0F1NnQd(u&nRSFoc%?Wx6lAk+oU7!YjZ#IKqjG<%ig zs$j{7FO3)qPgj^Lldo7c4L}>fb9EK$RVpsIsg*mf)i|)*6#l2Vw-?h_7TDcVk+to< zzt=|;@cEa7=)Atxoz3(6^aUxT_Sd%MZ)AZlH%d0ECqT66n^shBQ|@kmNx&8>pObST zvt7MGt!(=|{k(SG8iO^;3G+A6%n_a4(+xxYRa$!B@4w!zN&xEk^>3ziU_!MDsOT*k2sobChF3+KB}OkBoIGhkpBeLm_6qp% zN3i(WB`AQ(1J)gjcC+X*)w#=%zU%0Q*6oB9n4EPw&hzOfN6yDuKxew&m-tk3R_6`^ zorc)3bXjKFxqQFze}0C4+!?v(nMtNEv?cSYZVCKS;@cocJScKSFV;Nr=_mCunkD80Pu zCiECBp8vae8B`!XuvJD9l;CJ5viB!~@%UTOhLJ*p&4Mn$doNSS!+q(*FRbq3$vIk% z=FPu*Rz-thi-nB2B?wf~$jDj9h_6Z1_D74ch;@uDwd-Q_8={JfcY1ywjh{3CB#V!b zr}LEd7L8;R5`fC|ALEF z0q8)0Hwjkpur1I|3Ibce=Ye7#kDKGATItV`t$V7@O)t+6KrG?gR+6ros_GGd&WKm$ z*gHI2tg%wIvDs;8e>(cFFcs)g>`eut&P%RC>>5NAZlb`jAqT|Y{t2u+)}*vL0Q?Go zQ2`Y0!2po!H+1&g+wTdTc;ruglf`bdPzpK{*Z<*5hrTM1?jBfSRuK z>|y_hO^V5GgRv_sGu$a2Id>_yHfK)Ukqaq@x((4}t zhf-V=7_rA?N!-7D@jWnH@xC0Fe?wx7)Xw=9>8cAl#FzVBuU4*!r@lxBePfpDgS$CHI3eJ!5=159 z**&roP>h%P;iERVZJI|ePZ0l;P0^~TEhE^)p`1IEHlad=z_FiAf2urQFQZ>CKZ#}Y zJcv65lR>tCT4_HVjLc^h`GtIwE&4xGJe16Jd17L{X@rF%7*CEkefH$U5xRirK?u<<`?e^Z0FYdiD#rOsp?h1 zni2L_-s=&4(PjF3-uf2nRA{{ny=n$77z-xo!VX%>Q_B_K_hl*^(~b?AZEP#kNk=yI zsZ%mC$$qRimcX>jr+LIjx;sPs&wKv{!fsY1G|G`3+5c&2B_*hfn;rIhD!aMa*eL(f zyC0l!T8pfgXmg(Y2|rncz9A((*Dt(U&ptkj7;`a7NL?POui_Wufu0{VA`@IdAO7=bG8{QTef#(xnBE1QJ~16UIWl-q`pt$FO{rD?yM5i0DZ}tl38$PJVH$`7)i2U zkf!RgR?dz8jD>s9pcJ@V`QXGgI8@X~tl`{M!v+>w(~bNQ^oVl(fnYSyN{XDFB{4FO z6a<@WHCz%UFt8enlsbMqITj>HB~PQQu!@NaEdB{VdaR^2ZX{7q$zC2Doi|m9-ej>* ztT8=oNlmmb!MKQH4FSDzS4~pAanv-id`7Oy!mXvF%<{eMR|Ms zdN%5Ac%&SHG_`1^)aVC_41d8$h!ze7DhWAZA0Q(zFyqti!uuxl5A@p}dBK#^nKAJTo6(^Es z-Yf`IrfS~9i<6VlVUB>_*>xCiZ+hPV zMuCT~9tbC%SNGES)4-p*u(qY7Y~8jmTQCyiiOb>G*IkgN9R zVopH0wsGRlp8f0k2^4GJ21{5|W60uq`cbRv)V?811>M7b87W|FmD(CZ;#qn12XGSL zy0`3>TTb_6z?W-FaX{szBS)U&h5}hrKIZa0{N)ss6mQ?YZE?HE2d%ztb~i!-5vsYY zC70$iX8V*5dz6$s)y!HnrWARL!0LhNVWw?x07?%%J8F1&=>DJ7qz^wR3I;Bq&zk#J80vRcqJewjWIZ@lQoeM`PQF{9B#cGYfD zYqxXrJnAm63_Fa+1@0{!l(&eyBA0a@C(FDhFD2UR4)GlZPYI*#c3VG;LAU)9Ew4fR zEvI!75A6~&X0p@8Et)YHMQNAY?$ek&{o@1toKuE>Gn*(tngS0t@xMkTz8BL8d+?NS zypUWrCP1v*EZyuGaw^QD2#n3VPuCp!0DE&+V;vm8cp487>l#0zgFa|%9SHadG;e-^ zTon-5s!HC1zu)bv-1 z?RC2)8SET$xf>mHAKS`IuDm?0`0q+n{+YHn0~nOzVknT4~yC5NU< zhGbcc7^cg@#g!YagaG0}eLtlA6}9kQpEC2UMQr9y0ffLFYk+GYHVRe4^D$bLSqdb8KX8^hK4q;+>PSnt~_At!PjQ&VpXtc@1+czAh#3p(klwnp=yf7Q{IRWeL;b-_V< zXXN^Ir}C_U%OvN0s$2W>uU~}&K)VL3{f$spWfTi$xcL|2~yX=*!wer(7xz zWujcR47TP4Qg}qPh)S9xq(ZruX*K7Pd9Dr$C>OHEUt*?P8cwaYJqjmJSy*EJIk${i z>Fm;Ao`bJk6$=NQXT0VVa7~@wiQ&(^-7szAz_e1DN!0){Spv}l?*~4WNjpzZ#7;#UuAeeGgR7=g7{=PQ$@TP?{vy|EeTczmz_%U6oq6Y33#Zv{c@gTl>8r z7wB?0n6>OaUe?e)2>6e?XPWziz8PGilntO2k&rp^*gOYcuk)@X6?fr3_He?uFMhu| z2{=;uubNKbW$6qrHw2~M>>D!AGFsN&Co=K+vbCVcmG|O?Z3jb*uf4ptO`P(&iP(@; z$D86B{tJ1uzyS807?lM-v<7Nf7F?(qQt9&zzR6|{T-ctTV7Q1eblIfs716IXiOwNMjwICc zR6v(b$&nPPndE_jq)>48C37NQx`1{1>|7_-BX54;NqM5Qt1+#rhAz+va z2pWOB9nA|uF+*VR`kP56{U<0E^98~KjiE*oLPWeG#8k|)lv_ukE7GLja>D=^Qw7AQ z2JJtEeua$stJJ3cL@R|zXfauU@rcxXxAedt3DmKe`ivUQwIJ9EpEDpCArQ|3b$k2e zz4bk6wC=a_Lgf4P)BmNYc7OV+E*Uvo(U)?lxHiA)rl(zkes5Q+IlhG?!OR`X_d5h? zoMw-`jKNGuqR^?|OimNo${fjfSr~sIVmU&B&q9G7EjaGJ$If{CqLWwkE7Mrj2yVk{k5{yfLnTk;4!%@`3 z2MusDK7~hlvuRY@nNR2J)nE$VZ)wcYL}H|B=r4Y4rdhJ$c}0de5=D99d0LMFz@Y%F z{3sfT=WLe7t_I((U)Wsfnu=cYIR9KY%B1x3!6+g)+_=5X7C--l>p7?Go%8d1@WW5d z(wQ}eslbD&RS{pYOWK z--eqYpdJeP?7IHA#kg)=iwauR*OB~_-8j>i^5uQ@3)2ftkeYY{e^p#1^~r>4@a1$; z5y@(k8sGCx@AC6^@$Qin^ssX^>!1#iAmE5``svF02_NKiSNW_)(fgI!b?&b6e82Ab zdN1K&#u=f9SaL?J;(|J~SP7PV{ToC&>~}*G2_6x8MPAS@_OLp060O`FwivEld>R`N4yUMjeMDBfJH1=xofcheBHqj4 zNHi&@YgH7wkQzZI0;^l;KSI1#_)=$NTJN5!Z%u|~t^KrhEK3orkSu z<~ydZ_p7VrC~)oaqrN*IWkx>^2bja2Xx1zAg8{KdnGt2vIxQH27MQ*LjXB$s!|lnh z?ed3HYwvk#{Xd&fcimsfGk>6h7j7U849&vRIf55J*VNZ9Uj6_T>>u5-2Y6F(4-k_Z z0V_HXy!w|&0{vKA^acoD-EtAh$;rWgKLzWZ{s5>0w4nK;D`3VJXD4y8KmOM)1rU$V zq{`a0Sb!GzKwObi5a=hM_Pu9hy=NVOiwQtZ?jE;p^Z>OfK+*e4MwJ{;NPXb3eXY(B z1;S^9zxQ?$&|0AB-5F-5eS@zt>J2Dk=AEeP~~6tqrn#9c5I zP*?nqyxehA2Y@d}{$VA%?$;2Mq@)H024K+piE5LpDuC@=1kg8+orCXnd+!#2gjeU% z;X!%+Q>y80D!|-*0=UR1AwVU;zv-RR<_Y*uC0{sFV=CoS_B8M@KG-GO@3uQ3HQ_ON z-aUrw>I*jKp`bldY=B?qvj^VK!5>#YIxOn>r!@uzw8!v3D{OINmUw3pba|0&1zMj` zfTRCgP7?G`?}-W7H3#dU$czC=kaAgq4NmZL-;;so?-ku1{5v6nwoL2%C=a%ESe5~OY%voH4r0A~ z==OWp0*+$XhziH^9;XgZYUR!;_htgic1?rscAbQXoK3_rKP`pzd(?OUhl`_ zF}L@2b{0YJf?RB%7=X3==v(38>FEyu`rSIWd~->Q8{C*mpNXhn$Uc6uE5%Nf{qy^l z)!Xz{xGoz9JO1p}*6e{MD{XN$L-|J`R?qd8TdBzo2zBifZ8iMI5Wkk1G)gUTwjd3# z9y$pNKD+VyGhpQ(3=i;dI@tJ+a#cNI)6T`m(pC5UD`A=fRZZK7k#u9sG)68xBIBGB zMLh79ZuvJR8O$aD294@LCI}c4%nge1k-$}>v&4#i=^6`@gS-fl(feE&sb;-b>#3gx zgMbMs&tPT*0%inECz#;TekQgWXgGwo2#N=x0e`igDH8EfX6oOH$er%~0>XkO{WZeF zXR)FqK$`#9!~puG4Wq)qYg?kAruG>I>5JgAl<0IW9JEN2CqZB1p{s}V0cBDapd~{( zjd1GEhK6No(c>w7B$}1OLebnuT_G>CciWrSt#Y!03S%KhaVaUxsjN0Aat^cFB}kyC z6dk!}xuG5W7&%!w^|bTRvK|q3+!R{UKHll&P{<)n)VQ+n8&Y~>B6KOKwW1jeujsnS zRT2I{Ut2-C;I`MyJ)uLA!l3+n8C?=;6G4r25i_;SG(T1JIvf%%EoT9V!$cl3>B!Y- zoFPI}Ul*(=M5dciBHW`acLe0CHUPz zuzAQ938rSuj`37WX22e8sS$0-Ne92crk_g7K~4bbaVU8hv0+G`Q9XR8>mJ^|#+-W( z_XjeP>D=poou5c~9Rm`xNoybO(CeNhc|HQ^*iTfi_!4x29+4NHr>uLL>r&oFbMzj> zzrW8XUwUH6_g-v&2U3&F;j_jnTJuWNezpMg&Ws5w2GJx~{b6a^JJUFE00)$NYfCtY zitapDrkKs==%pHLy=EKWim+yMdTd_!R{GycGsI)WM;g`DbCuoJz2yrGk-d`4XC0-3 zZcx0UC)p5ldb(5Jx|TXTAx5zP2#eU?{1XJ*leqeE%?|GB{GM^XHz3cFmTke~I9T^j zu)MYxpcLj(-&R0+=fy3zLi;7eDzNK`b;<~E9m(3y_KHI*pV;|poHWF>$)7|M@}3Uf z<|}o^-Sj>`?%}S0m_j_z?(TFL3yHd(BAD7PzVPW}EZle53y*VJnDr!vn2L8GG8=nN z(0c7M*G-J-#jE0OyA0QF%X%tBL8oa60WJG3*?h`c*=<*gLNRYu#V_w=Li^q z#1R^t#)(}3P;QC^%ojo3%}3!Lu64kde{_7t$J|2yl5l5yK$ydiTBf!9O0)Dyeu*nc zZ)tq7oQkCFA+F61w{^uhqV-|enAn|mYI~Qz$RD|qNPgpp2%KU4*qN2t>4pAuqq54-mpsA^Oe}f1f5ngWq z*#3{ebAU|@Ao+dsOkIZvZ-6No5V>L|Az<9T8AtWO1q$R@|9nPa8vJ|z$g~R^jHL#-W_eaYiv3+}KlN4S z>HN^0-sx}W)68At`SAHrmg0gGsa{()L*9^Yr{lO*r@k(lBhfwx34|&_igv2wh9(W6 zr5&aFyxY#T`jfO4v)<}jf>e^4mtoS<*Rp-#kfoM@#tytED|>fTJ4h`nTN|y3v?K*8 zASk>kkYkp9V*=7!$(0s~mMbVMQ6`WzK6-oSQ8&NKzU|wIW#GFjfVp(f=B{`}gjcFB z_8*@@Nh}6bi(g)bfMreo-fc_7e3nj@k-!E;Kw27RUwfdy3Fb5A3vfu z&%##@-prjDb@G12x!ASL_TJkMc~tN(t^|iW@qEL*50B3 zVmFps;`d?CM{9_#z;n}|=f9Ij@_bKz04&z0DctJ(r(c~Xw_B!?c>y;Kj1%n|Jm| zX4exA%`4t_ms{7l#ltR1ZEQOlTK0Ux!mXyawT$^I4W9S?{aZ_Vyv@FEv&Lp%G?VOb1yjZT$#@<%jQ7@uX$cz9Xt(16tf!M%|lf~A*{{%VTe$Vj0od`a!O0c9QUI# z;!1(2!4rQRPIBIwCA7?)d}-sNtBoZ1j3j|KO!xgW+biTP#dl0h)W4RP>EP1Cpx+_V z(R$Kkaj+>r83Nf-qRMJ72jA;t(0)@V2s2!b>-(&i zF5bcCF}@w0V$q))p9=6&W+YiEQqV%#nqPcFw!;XOuLdoz@Y0|-FGukRMJj1Ar;^1H zw(voU3PZm+Sr4sDFe%J7X+&Wx?dULnZI6MyVNwepNcNga9dN5&7 z<7lJ|U-qYyg+Wy=uxIeA`obBwzzT(49K`9%Z3HzPi2CIndo-}DY!cgn5J=sIPCoHs zBJtWJlYCAYxxrH`S!A!kVb#;_{XTE8Y=Y2ar={|w)5`RUEZdYnK|4f-e^3?w+Cd}k9_{mb~o2)@M!Qu1Y3;uM)vPD7B%TtYE_QlxVy_WH(t#6GO z`+;HGFVi;y?tW|o`Xsk#iW%N_gE&IPgi^UVorv^dt;t5-#aGN)}07M%5z`R zX@=$vmZ%K2Yi_A1`yf!&J+!x0A~pxinC9icAjj?3j=2SU*@=Cx zDD&v+pD4$8mH7e0;e`TGu?xUnH6M~KKLU8u3()0cp_GwMF$)7o0wVK8nR-&c8=S4Qme_OvB!u3u8%3Ph`0D{V}!crhqsEZI@^1)7{uvx z{i^;1C^Qw`<8Rd`3q<<9zqzmPf{D3>1qvu=*E(o-4H0y6R}Q?DtUW+i%4Ad8<}aGD zso}KNM+244%2=^^3gv#-<@`)1Px4XbUun@(W8S`p5Ndf3Kp_EU z*qDff?$^7~taYOo55OY(Su9&rNa)U8{Kj3_`^14STSm=~&_x7bSw61#3laI7iUVj;}M0AXQab=%kcU-hLAr*fOxOu*?j z+Piq!^Q%zxTol_FE!wOQIl1%inj44fi#-t|lhX>s_M4g%D-hH>CokuPCRwj%wI+dap|<2=`WMZ_#`Cx+?kB_2<8DMID4qw!dm# zFvL3cVx1(Fv`JL6AK04ZrFRxP^A8U2BYG>_xVkRFaT|aCe9{Skfv2%wtl!5_J)Mer zx27G*!&N@aGHH9%62-;Gmf8B9E`4j?+oE&iWNS%F8)x1t#HbDX!L&QuQfpYf<8vQR zv7^y7Ym*}uh(`0&V85Y7vAm)$h*N;PomHE5@c`^6%GR84FC)C@ggm~~c*>)YPQoW9 zDpktw4|Sh2T5CKOmQ!bc^i^h--M9vu@^Ii#K22pNGg|Fh6JP&nFI!#Mabt$q%$3c| z@i5vgZ-t-)YT4~c3KMdqKc6Lzu%@1;)voDwnd=Jbz?Tbq5-kZ9mERS7fWRQXkeC$b zuFb8_+IL1)MHcPa+>RKXSAzaf?ZqE7t?v&$7W)c4V-n`+8yHPpg!l+#syHBb>g*)F zOaX5v9UCv`+Zw@{b4!{6!`&^Zt%|#}xFcWfJw$ISUi!z%(VXKq$fPfagFH0FXb1c{IZ4*|sv`8_doAcG|Rnr^fP z!kr)`rxo57_T?=Nf*mYyBuNq>FAaqvg+{!>!z1ud2w88GvH+REG4Z6AuwMFubSAK2 z6E8rS-|or72mR?1_M3_DzHp4Q8}2EE$eCetaS5wl4as3OwqAAc;YZ3e=&xLHj6hMA zu>8}pFsWg+b~~YFyYmhwuch{>FlDw%cc!*}iX7aPHJnAzf6s-);IoGt98p8M(|Hw* zS)tIQ%vwm4Msz4ItS}x{tTt3uBOHUC2>53)y-FLc6 z@8Fd(`!3S8ChBvdasgXI2r^+!85o3IfX+D8KG>Y7Uqd3U@#1SL8;zA0DWReXY}DvP zQmtWE`bU_6%NAafY+7VggrbQxbqyTv~jf zsVX{FMKi1eW0A_)&EM@C;Q_$JiK>k-E<3No+&cWLjk=oEylXG)Wa+igz={;otu2}3 zty|O+B_(P~y2Q4=QgU)g;ia!d7W1iPx#Yyrt|-g<)fdhz-nNSoAhkIwuW)I?OKf>+A2W_a9o3z`@hf&KkxSz%r`f`4Dox4Qv6}nt zUNuD%CeZpIa_+MA*n8djR+nxT0N1tWIX_&9%t^wM00A)^zRypNhrfj;a&U78&t&3= zLv^-Sr)k3QKt}6GBpeKa{Ho$uJM54GB_*?AnFLi311gk*eFP*cbXnLHv zm#f8y*>gt7)FL@%DFls zmzVQvTye(dKQ8AVA06HAzZDk}?i6bMlbrwX`>y<76_3f|;lF_C0w7_+UVr}f6Zfd` zE(zXLssw(+e@)^pQ(0Xk7|9|s{Mt>}JBRap|BjOJ)!n)V z=cZdPMmYmY zgd*W(L=Zq3s$9Y07LY7=s)&EL(fJZIMo z`>^KqqnuWBJvlF|RDoVD$)kXP z(bm6o*{yw2Birh20#y|H9XjLiuu$&h@b_FE#v`CtX>TyF1(4Pf5>$h3o}7&XFSOI0JIp;iv|=bLQ;};2m|_)P zD~e8X@BQ2w(;x}24_c@uO7Hk-(@y(#Saz74F>-gQL31j|-Odh-*X0dAJfMBsA>ZM+ zDp5&*HU{@TTuD6p?^wy0(Gipvw^X|qHDIz;wP$g91Lc?N;yo)#FIOfX-O!JKN_c##;Blzy<5;;Ogu$ zlmhwJ{?lx1((_Pe!HQIuBRxw#eItyq^+TN%`B;3=j1+pw-QOb7A#m9Myb|S6 zYex|%1|A-Xq%_Ln!}^e~7nrT@3roZ)7~IbW>to9^c1pzLri9E0>$+?}s9}*Xh)y_x z{yV570o1|@#-?@AFNN846Zxx)5h|@NJu#7oB>%2KoM2jFPz8nS2O6e)7crs>=GX|7 zN#Gm zAD@X^;KE2F`+^87Oiw5p4bRBCoSiz2T8&}(yj&soVLx>S5~_`PTW|NXtftqpw$hGi z=}B!y9H=``MHCBOW>`eDT-Z$?2n^Sc=&0B6WDc>GoBM&%A1SSGmuUE|0z>peh+L9Y zzexmA61ap3+i=p$D7r`@G=$3+QB3{EOK8E3`GCPh02`bw{Ib9rPP$;n$igg@zU#4V{od9yUs@ z;k}IEqftZvl7uq$*ASwFj=AqeO8@Ym#?%e|sXi!_mPhuG0EW4(yGZ=&of%L> za(>wHpEA72Tjl7y>iBLl{ZI11(toMMd&DgN+1lNw=HBJ_814_nTt$Ra zfR@U(jQtPv_C_BAb-O!7x&}%o18(KG+8UXZgs>Uw6c2e)4}G4~$Y$@DO%GKMdAxSy z{)t>BMan14PuEgCMv*1J-t|9jyd=9kKTMFqqvkuu31EdPtTDW|wlcWjYke>=5DWsn zY<)6O;0UPmTc!&bE5Y7`gF_#bv(J9;8CS83`#X!c8v83lO>L<_pfkQBwki!~>^HUl zflBn(b*ozp*m(jX#LrqgeAOI#arj&Yh`9%kG_HygH|`^58TNK+@*nqqlJea(<(eLM{2Zwhr^5?BF8*hMHET@%vU)KK5YgIn0YtQ(f;%*n5 zeOY>4A8Q-uG9|C};^uAqAvbc9Mg=mDq=UjyJ> zfdBa75n&0KauY<(M}=y|0JHfSiE5sR@1LcHf4p=+zI^kDtq{P5mTx$6RJQyMxb^85 z0JlE;zZ?0Z!K0)mJxxNOu08lhz;tczt?4t9^Sth2n|to+W`BE{b^hzAZxK$XE}?D| zd|EySQ&sr#9c!V5J%wTxR@C@JG<2AFw*MJY$dIVf;vvZqR5&Gh&;1lm2sfam0YUKX zq|lQ0^gENiIw{atixQEfd8=d_!#)P=a`C<>;f#iS3w8Dqj^^Uh#vP?3e}6)e6zw*h z7bOT&>TYeJ@AJO(KwdON07`+m=u z8M9F#f+9lb06~sm`-2pTPWKJJHz(l@}poIa59d4m6QN<6NiJRXSm6{AFq$Dw+ zKO44rkRJoroc!O}-u4w1>!%@)#v4BdrcPp>(+Qs%A_AVj9UKIfC*+F6Q*W}GsEY=j ztC6fECiXm?m?beh?`S^D*asf}SKoDZ$NxBh{8o`(SY(9}xjFG$B|ZP50e2S=CqL;b1H;{GA%ZbN=tJ18@Hrx!C2!xjA08hkTK%7N>9i86;bc&n3iYkUramZzGj4 zZB!5^P~8MB;8j#eJYO4*dc*pTAZdJe*Xk4cCk6GCy-C^5>My?=+z)zmG5>b`<;FK8 zl90q3+=>ghnu-GJNP{Rskk4T8xrARRy9%g_Krs+xTFmH+^@bar@ECs(2wHFxOJ{$h zf+U4%Uv|1B&ujsO(p;;ckU%o^kq8|+1aPa`_P7-j=U>3&sPi(rsj(oDAfza20;@9+ zs0ad;50?)4(Fi7@AplKXG|egJc!P-~)G(5CqoH5ERP!^O|7n^jlU+{-MT;)8DW{^1 zJ9MkgPGCU_qGI8AK2|FHxN)AzHHmw^XrL;BY!$c$WQ^o|Uq&TgaI!+dwG=3sA`>h^ zk%rp5S9np=_5+!u6ou&>MjtIJj42hY`in;?IR)S|qNZkaZB zytYIA;iGUFSD8YT;aF^3wh8tq8~o{Y`_kDa!z0#aVI_$_js;+69-7pWS9q`e-&qlr zijZ7R2}$e)kfdNAa3rBMC$aA+BT8rC?C3&~Fyv^Z&*lmo#8QY?GM`BX?KvS!@6;8b zdeV>#g3sUtY|ID}-FEi`OlhMeAsE3ok?A;iiQJO#bb;LG!gPYaw1dFU83soG0Bt~$ zPBp%fJtz3{sgZ#|x=v&dx2-12|8v{CD%5!qv~9Y6ig;e74PxJ7jNO{-tTQ#J93ag! z$mm9v*qF~VR|YH_hyYDVl^f+_dHeUMsbp8GvX9CC_Kci)aMjFnvy~k7E7eq|zt9@I zhL%qJD^;SxT{W9#@1BFpH@&?FrVrT_!C&Xa7X&&;EeuJfs;OVF3;=)K#?0=>FvuHl z?g+=cjrn;~^wIpAbn^!S&cDBaV=Hhoe0XeW{Fx^%U8lL`6%&OHEC{>0^`skDr?_ie zPb0O+e*w-O3hWcMuH_@f>y9Q2`#CHw$_88awH?Y8fWBpwj=pV>Mf(``7}(6#I_Y)) zx02`B%l;e_1cDh%5^R`d2IYY}m;QrwN0L3r#&=b))a1P+@le;k8D_iw5XC7J?RdB6 zts49k{1XerP?cHHVu$fV+;S|;VXj}RK;R*cr2UrIL(5R)^6EoK@XRLbM|X-f&fhIq ziGGq5#7_@oxYmKUe>a|XTk;>)%sqZEuy)Lw)&N$bh)MrSA@adMGJ0XM$%~jb94x&q zoMghaLFSwwt&w^*9Ve~l;`nGB#f8GA?pTPcXWOXG8&EBiEeC2U4X7cvw9Od{#sWh^ z|B+4Wj}d>@RblgJlq2ZAyY7#mprBwc+r4z5AtENu_ub80b?$v!w$2yzyR>QGj^F2^1+C) zh_$}!9C$6lM8MX9KU3Sfei!E)P|Otkt1oobsZ-fL5O{(J=3H~~25Qiy2PcLz{?T&w zhHykKf4rf3_=Voc_RrUXsd_&G+zsP}PyVH_Zh)A{NUcsa6Q7V!bR_V_bjMTyXKTOK ze#Kwb8ozD!KGj;#r-y<};g3HmOmoE2v55G#`bn;0oFa*nLnVUCifEPAT+H=Be*ohN(a)xH!WJOZ&f=7i#nrM-A5wWZ7)`P za{^67%8)?<$M~q*P(blsy-b8xG{G#@B?cQ&Br_~B-$raPFb;o2yZ;*Rd-7|>uC%`& zD@Kv0d?De2iaxrA&ny$BBoI53z*m|wyRX=Z10nNG#x?&HbnyGC?DJn@o4lF33wCB>D zD!{bcbvO87NY~AtD#*dtfy~aOL$7Kv`NR#%nXXe;;OId?OVF$#HcEMrDVjRU7ae@3Vbwqp-?(&!&}#L z7k%)48o%9*-U`tSk5P1wo*x`sI#|{mNtm|ERBTj2X~IWx5u;jby6W3}n`rPdyo%4~ zSKmdsCA~+pUv;J7D`YY62NzEV$eA2HW_D>oG98CECEbszxhsWG$qj|hV&i&9ChDg< z^_NL`T#?{%YvL7suu09hu11vt^EeMm?mY3<1disQu_@1vO5^g0$6Sic>Fgt=p#*`n z8J+}yCbn6icRbExqWp}dV*Gi?+9Zc~WM5Jmgw$1l4t+=D)t{EztVc3P3vR@>IJM_j zX4X2I00Y7!7fs@UCMj(NCmrJPM3)fbk`e zcxSl6_Sz_F+!ih+UCWCEN%AE6CM{`JJFaQEKaU5Jm-|7B&Y&>M z$3z^`FTrS=C9hJF+q$m-`qQF8D4W5!63M?cM1u)qMWyW02tlC~tzE(3`lukMRy?Bw zf%`KWIhc3b(BUCT0y{aIqAgy5YZZ~k2T(Dp=)(`{BETze>a}e7|F(i)XS&mm!TwWO z8Wq8S2ZilTxgsqDp3E0Tyc<$ezFf!%g5`kB7mP!5;d5oQSxgP0M1ujH9s8ZM$27S1IUGw_c>*>4&!@g}tAAS|$|n-` zl&2-laI=l+Hg+zV?&Po^0j3}>XU>(9JnuAZX!>0_ibS|Eoa0K>H{Fvcf#}uoV|s6t zT(i|p@(Uzt%9UXbRUNDFTxQ&e)XkIG*Al??&aG>1xjf=gqcKzH)%YLt?o3PHtP(cB zjcT*+XL5HPk#i%{J=U$faC08_oF||PY$925=|Ml#YX!n0>H7B_HS%dFhQkaUSG39q z7KR;G=w>Ik6a3Tq3wr+AlZ_P5usY7FF+_iAS#7E;UWqaM>7V^&yh|BQv9|brk^h6S z7hin0$msfPR)dJY;RMeYTOP_@r@-Wz?k`g{z&Y`JpMx+B>06nywvb}DvjrSWF)Ze} z$WZ`K-<^XAclgaJC!0=wP(kn_8PGYQtS4*4&p-@PGtc#;`2c}4)DIUJg$H9HYamqI zZNH+4_Z@M=IM~^7Uc4ZE?`Q0-9&qBGe-CgI&Z~Rxsu@-Dj7&^U5QzM&tQ8g?LaYo^hF43%pqat|OnsfwR-(Hl6Otb1c&iX3QkSIZ8+EViRkp@ciPy%NztfPV^@GaVFxbko?)jJ% ztTYSqG$qlQovt6vw;y1oK0YZR@LpSR|@98Zmnet#cjW8+e>(7(LA zJDiZC(C0>H}k-Mby#{^h`LRiAp#)@GE8b&b51i&fX%*M8UO zR6j;^KHc{RXfWeG&-Mmc*W$L(%Y$s)>jnnmwITmWy0#l;v~C2Q?@K&~fIhvmNV0M} zTy8k4z3+Kcb_~&?pMHGk--*u1m5!0S=TL8eGn0;_|W&$=K?2`uf(HqnVg*b ztFOwA&FTFagk!~{UV;nURh^b3Tyu8 za1Q#Swu5bK19kiPn=Eu2W=a(zKFD0*cg$3kG#AE;$tAtgved=kZCV&R=->yrY5!+&=tz>uXS zE1*bUelLIh>oog1^m<+JnoTF%J^zaUY}7zrk6R8bB!Tii_KL;3-LnR~@W(4Rot%j+ z)!qJkg+@F4#3EI}w{+n@Ni~ikR-hK0WG`=T*Sgj+VrFo#f}uZliR>MMBCG(6OlLNP z;jxk#s;0+FYChtN|53esT}G`0L%OE9l!z{C-k+CNTLoHNELXnG!ZFF{ zw%%)pnhRVH(cws*PQc6qRU4mZWlA*;Jf;3Oc=b8<2H@r#`P@2hxF7$PYhUC6#xb`+ z^q{TiZgiqN;g&A3G@gd5X!!Z7(l;P#iv0?MSiaxKGBCjDAck0(asxJe2V=3A=IPB1 zE@NLQ)_RvMDbhW`geZ@O9%_6$Z!1SqWKe6`Ku_i2l2bY#UQ`N_gvQ5i?J^XY z`UVPSXGGu-bdohrcwImgcS*T1Ri`t#WZhpXy67}3ELex{8$Z(4fa#=H?@>{)KAF7t zst|>8cLDQdgr5h+!ub?;2+B@jSL5#sX;gYm%1ge6TuZ`1n3B*R4pFLw;n|vEj|wGe zArIRa4>gL;Sq9J5JS_B2CKZhyz~m8t&C8bL$3Zn8Pt_&>g!If@O*F9P#^fBAh;!pmhjw=2|m z(&#nMj|9qL{Pt@~8;9$IV%AZBm*m5z1$Ako)-aP=-&)FSKC~nh1Tuv6 z1=WVNaG;dD9k5zHJq6WX0m?}hHw+xVikbX=g`(&ApR@xHSivJO5FUF??@E&ccdok5 z6Fa`?pd)K*YXtD}x3{+!D;I+=Rda~Xo-XH97muomdV(+bgD-%#8pLv=wV7GL+=0l` z-)&X#M-RMx4p{#4!yY<1IxdBf7J*p6-&14nwFMjAp1lK=q~CzD|4gKP3o7{Xp%-8r z#l8l5+yl?QGdg#j4fmS_T}@dX_xFQ&fZT&y;7;M2PeDhmK}R3SoH8;ppozdl3OGim zCni9B>AerYaJsXe3Lj8>DQfi?Y$YOs5bJr)-?e2TemJ%!p$>i~B88kDYjTPw6yQEO ze@lNF6T7JSg*xWeMXgOSy|Z|Rx_=#4^MG}BmVTK03XXQ~Za*iYIc5_YB8Qq734(!H z;y_UQH8~ADHQDB@IJ(BEc8%{4TRI?z6&Z;#CTQ(0>Rz>puZ>ec%B;{9TyQw6gdtr5 zeu-(`x$bZ)f=xS3K15G&7RoTlec+Xss1dSsz>v+4Q__x0YdQB*e{s~204-JGrP(k! zs7(LReFF`T$U0Zuu1&|@yThU)wVih|sfKk+ccoT=z$tB?(Xg@+w?3Oq)J;8 zKE}~PI=uh%?H!#30x2qUfQdBv!_Lm#;NaiW)6X=2tlIfxE&L_5;YV?ai8N9gEH=$Q zFFo#lufLgUx1*nOM4=7~Yvze@x78||9sHB29}>vF*7kUr8Ri`Dc!X+WegU6Jrj1;3 z@N(+eyc6MkJl+W29*o*)v&au#7r)JAM7w`F`~Anr=ELH;+sJoKQ(QH&ZASidyJn_i zG*DBL-~lPF6q74+OZ!~()4wd?QqqM8uK&i3VaI*V%}>XZ+*cFe32cdw@epbmjTC7` zI{HkQtqj~;Mty5krBtJmi*QIgD#^4mg@t)J)y?5Ca=bE$HIabWas*Zy{#BY-HxVTH zSq}q@jBVBHed2ZvbRY#@6eEnLut8CkgC&rh^0Kn28 zB~2|!Ko8XqdBywHTQ<=g4<(7j9Kr@Ns|8C)f+VbnK0_cMU>`zcHL;QKV6;43Z)q@< zqW7uaiOS|O#V3a1B}!w2B>V@qDUB$CU`B>O3uSkjzeeH1r9v}7G?F+_q@n~BeH5td z4zgCN(q1WusaCp)+D>umtvV@50K|x3&1wAB?n~1Ih+z_67o-vS^VmzE>MUq8AhzGL zE?T{g*?XtOYRYJ?wwOLb3RtEB?QMOT(8nvbc1KR}^&1v!vH|wm9&3$E| zNVs~^%k$`bNR@>VN~P=?feG-akRc(1Lx}Sme3%=6+$?^Zz@gC42gVAZIxAESIINr6 zq6!?D!R@`zld&Yy`-M&reaipz=>0U(dv#lciB6F6ToJ1^s&y##w?SF+&L6y)`?i?iz= zvk}Wvb}Qmp2qPPf?)#Bxe)g1Y`$@E)0Vk$4V(0eCL_Py$M>TI(__jPjHs&k1Yrl}F zj~$s-?L^jN$Tmdo)_bu)3xECoTSE&`Qx-njQ+l=#?9o94b$VXDTh(6+yfdZr{jEEn zcpvzB?1m%j>3do8zTa32Y44rYaZ4kq@r(m5)4)*A@;x{45F1MKEiK|3mbkA6d!!M2 zb@kS)B)mGBR-TdOVfN&Um#q^sH_Q&l! zCcShV{ps)ATCQqktv3ck8|$H!f*iJjN?QNl3!wat47|E`KlvA##`0_FuuAatSbE@p zjue4QC8GJbj@HdtPTui95i#l&Wems6tFyM88|^Nm@{G7am%nlvGPyI`>B)N)6N7&h z=UvOaf~|et0KWY<)xD(4zuLxc8o#-=5rTsM{_)qVzFz6}sjmNF(LHc7czvgzjwoN# zmg1G)yOs*H?vm;WKCgeq{nWTpeM1@KG^LSzJzE;~qjVK{8_}cTP~9DLeQq7}{?YmA z2H*Hib*H(x;bYu_6I?$_`E9t*PNw)I-}I5gD`;R({?*B-50Me{$T{n26>&$1cu#dt z0t(nB+t4F8hHjtzjWK=LGJctPTUnmx2bdB}x&w?Cr^TNiHuE_F2!bMKx5wYTcbeXW zzRu2wy5?BfV%>UTkV(+(&c{u$K>&W>j2pPI^6%j{8R&bxZ0-C!=l`5l?em`$JnjDJ;ueVn%q8{mR$Mk zl7PhAX`iMOGNd0vL~R}?^XKfV&n`^Ox{_af(mj|#;OB1iaP_457@O?1|DOC)Dn0+Z z0vYD=+jl2D2KW?g9>gjVTGS(*LMNDW&38oHMMQB1!rZjVP{ z8vHTHubcND-mlO_o-mS+!xMHoDV4K%wD|A(G>lA3U!zRF%hD}SW6o{TbQ5bP!q^GP z#oIH^(@pixE8LiBQfG&+mG&g$rC^8&n8ti*K+}tbuQ~BI2q_+)7l@M|Bg0^#&s(S< z+t!syMWSdZ4F4mw0duWKb?OjQACzL-${WMg*vvOvkSa?jA@zBGyV%sfrmhRZR4QD1 zecPJ9L51V&VC;MQol*SZrTA-7#(}e)^1LUV-bLEO7K7ue_4d6b2KS})Wz|`f8NWU8 z=LpW;tJ;x#{~-Q0E^-7;hi&Ve|HDzf@~X%5ncAWnk$m}rV{1|shpuidmXJH&7Ykb$ z)cblwAg6{(zj0Vc+cCD;wkWa-*PfMCK8uZ=-O`rtm1+PsoK%W1^F2hj&P4RmIBU&1AI>`GJbUl|Z$HmfP}%IP9D2m{`P>3MDN18!MY?`+!+FN; zx#Ea*o^40dC$R$qD`g7BduZ#_qs}QNP(eqM3d@#*;4ISNo?LqMXXFiyPKsTY7@c)} zy_0FmYwZ+g^_0!QOu^5~Q1Hrx3RfX%U3cB1D~uj}1iW&)NaL z|7pkP9;bRnm@5P%74y}KD8DL@>H{7bC?=kQ&RL5GY>JSH85qb9H>Rn73Hy%Op5QY1Kvo3K2My6{TulpB8|UnLkTWD;g)3K2aklN`NVW zv+xzaS{fN^C_xG7q4-3M{zoxk2?9{)o_=r+7a!VyiNJTyo}Ps879XohR}rz^%lvLG z6qQ_NZMXH9s^S40l4~hbr-Ga8+qv1>+daP{2PL;}zQ+SiqZnw6L9XzQ*;`#iE=Pu+ z*jDDLzDPKNlT&36`}|-Z)@u`Q1s9x@1MpcJI&=UBn+L@H_5{Xy{4>(2PYJAjXINKkSuLTh|dR= zVv`yMf<4a`15H194v(HIj2&j^>uqFg(r{>D3+<*y)m83BdA*iu=tmsjlRCvk7 zh>Pf=zLwMsnA0Cc>x<4Enl}s89)2nU_%%pPKC4!zrMN}{;B+e!d-ybCJRtlRPb>Cvf z%e1|?W^tsRf6I9_N(!(RfOzESeG2%c{5OXBTLwdSr&2@AZ&XH|u2SjDpbWX$7wOqL ze?A7>#fmts4m3Ee{THxcYj3|GThINi{Q)cGz$Fdk-M@nUj_U=jzuZ*&BitUq`NBe; za5X*kB{fuXA9T~e{e6#__okwuat(M;|Kbfj**?jN7?iA}`U?l0N`Dt5ohP`sMg|XB zqF<0i%HR+MEc)#8c0oX$<4>{vS7m>us#R4s0xOZ*v4s)@k&0ynn~PBs6%J8+7Tk|D z$gKq*es8Zh4IJ&CA;zb`$uTK8lHw}!Y#h<}|8%Ba@^7x=2n%^oDbV018!Zi3(#Kkz;!b#EYU8!{!E4e6Q}#i%_SqV2G(1 z%52rQ@@nzrgNT2IKHFPGs$af4o?N^sy5cD7r@z>EfVJevm}$~}W{6Zps{h%kYrF0E zRWETICwMT@opl{ge|x?rad)xgzPH{5eT((hyPT?TB|x4URMtBltQ?$bA!}ud=4G(Q z0ylGncSrW#n|_SggSZ>J*~jSW>gvX3G81PE3RSVYt<0hQ$hL6o;>~Lbr++;eyoC#f z)f1noKWaaW16Gc_t-V-2PdNI8>u71EUftY=^rvng44KACxJ7w>eyOir>lA@tD@YP^ z{9q=sso&h(@9iU!{w}Y-w5E&I`lxZ!O+4@5J7*bFRpD4PSorL-r#(GH2f}PLieMo!ec6Qietl5-5 zKO@rk$;o={S!JE@I0vQNVmmPC;vA`Gx9i3_`h8B8k`jy~AxEEQ8jgcQtCI^0i;#(D z;PX0o=Duc+ZvhU1$peNaJ*$|urwnN z7~sjtA&8)Tkxsh`IoO+Q}C6>~Ibpxr`5g z1qsW?OAZbT%jJYS=9y8Ek&}}b2;g$?iR+0M*8pH1GEmrrn6(?c!(Eq2Q+Fa+5mo1E z^=-gEkQ%SQue(RZTU!0QYEe+Uxd-q1lk`6x_oO+30$=qjivCf;Wz*ND?c~_k<@Cf` ztt~ilv``2m4ku@mDT^Lg@>e%8LAj~FBi9Jy9gh6N%EW^W5CVtsfN}xC3KQUmd4ZN* zp0kd2(&n^{37aewYHozXB*nyw9p_h{0uWjM;Pg21kKxowPlp4bVUSv~r-ELbbWniE z3b^0(*i=!i{D)eqLQXWki41sTJj;~AR;G^?V1V!8LU zEe?hK0N^ahyF1pmB`_@e-IVQZ*KOzWk#Oz@#bkR9hgZI6I|{Kkko;2ZF+81{MwOUZ zeD5kEX=R;8uDR-wea{TftcGG}9wTyUA}7l(k1yKfod^%1a6`PamMmVl+QvFZ)_wFi z|53kT!4PwGo^y%U=FQivP*1zr{`YJejV%XSq%IElIIOe8E-}tL#bYa8Bia|^-AzT9 z2LKr^`~bwZYf@$JDX+*vyE*k(;h0mI+36zgCEcdSi`gab*=GydF_kB(*Kr8L`-XBp z6<^(HY~7AP$yV<)4OIf(roAtb7Nd>X7Na__k9eGzTM0Ed&+N*9L=dq!7or^a0#d(Lt;G#j| z$+WiEj!-C&EIp=G=(7HH&&N!K8E$2tmtmJ#POm>g3nL{(FcG}%`rtDf-q}7vah00X ztM*73i>81Jz*i%(P2Tk2NS<_Z+j?vx2BaBW%j~t%-wh3B3jj-z!%$=3&(O#?=MxTeDv? zo}{R=Np(&h51={D<|V3^PVMQ+FNJh{d~bRk&wgRm%W{?jw76Pek-BhehxlMv`Q!zi z$Ymoe*v29E@q)rtH^kV_&03V+#namD)R7p|P)R7`+RP7mxVO%HqqT%f$ zhPpP*Gs_ex4;*<)kj*HOac2nT3kEV|Ai6QQfxOJ%iKD(r1GZ#V&9ClZ#B8`FE&qsZ za>cExC3{mFZP$K&5Lgm`T9cXEzNPqUDHc0`6wnMy*KpYgTtle&r&n3m<`DHvB=E|y znbok8gTVJ7xVZ9A#HbRRErJ@Dn3zCmWlc9_s6DNFGJJ*>DA~%dSQc)**baZ#?RIt= zkt?7zY!PxK5u8J=-|CGI%JOowM)`fzu(v(cPQ^I>JFHFhru*_B(dyuqUi6}%())zO z@OIg6zl>hEuwA>t`!e?KgBTYg4LmtPAU9iGZ1M2=E4}AhG>x92&#^Vy!+m9$BfK_0 zg$TX!Bc9%KYuKRS)*}0IK>Lj?`rZ=>Kibe>aQ{XEf#)^a@4Lqb6^<8~-xT|rIo;e& zflkZFFpmBpj>#@!MX9Kf8(%jkCq|Wo(o^6Y-#hs@q1~6gE?G;18kq~f!o z7SFBE13#5gtJ8p47@$ra2karLw zJVl6<49xf!11k()iZ~zufChxg2Agt0(&!RkFUfzm$A?J0OM^gQT~p1(4?*z|f6TZ0245bePsL|~0j2&9ZH&ke2M zQ<*3b0W|M^yh*s0fEpqqfCFYukiye%p;$Wo>cfN1cpp6O4ymeA5>WaIX8jNPwR6H$ zP5Blp42MCfGBvvB;)9sJo}npT$^5OuHY0xy5MLG8sV-7%Q2CcQE0#D$ZM;?nuF}(& zkw2+(^vkA3SX+v{(Qeed3o`8>BXjW~?OkNK2rG_xJOmCB)~*=unlupH+g8w0H{pWv z$m0pjz!7Ajob9>{Y*7X@#!w}_T;HSY~wzIbYk6Vqobo`*(l!`1?=(qEiZ#(|MzbArj z{I3IQ=G`~E9u?1O6PSCHOc+ax*xHh>7#9q!4wsEx;YoS<{VCe@f@jATk7-QDc6*FQ z{7huFZ(^4!JpT=NcAfbd%dElaiZr}jDRpyNb!+|S5t2%g<)T2+Q0z(?=_;L{VOP`= z{cf$WQ<}!-V*=T6LvjEZ(vt_HL1P%cCBj`dWB6o+lES4@}i$V zR-4UokiC$%*TV&1X3nESmA>}@F_s1GVb>X&2SkK1L(di_x8K%YJ%6^aW-;448onMu zy_w%s5wS(>C_b}RS{ku&-LT*Xd$rIuSIJ64eG^c-G8&qxc{61>DlCV1epH#=pv~yB zysNTyHLS&F1VWAHX_B7XIBkyVGcvBf5O=igXK-{J?- zoo=m1$jbVE^mhmJZJ2Ta70KhT54a*4q=FW1<`;YhH}Xc-o9zGnH_mgj;%;llkz{?x zvt_S*9%6Z^c|J3F&LXJ{?2|}V`rc*ByC+YJH!C$itGxT|If+wgP@djzKk<=7fm~4_ zK{}cYfbfp1U5YC`gTve7gQ!s0(e1l8?6&+U+IJ|yc%1g0?UxQiEG6Mt(vW!n;Fo|} zN1#+7gdFo&o1^p~!~6i0jt5YfXpS>ftAFRu5N_xvir0upZ|Wj5DOAA==amC7Fm-^X zq$Cgp-x&JCli)H^P=Fj^Q_rW}r1q;v8G(}n&IssIVxtQB_73%^_^`aT0(oZe3#?Sa zsnXb@S~uv4N|;5zCg#Q)zh|1R(b4$5Hb`Jj1L4o z5PLeR1bjK-br3L#60K`E*xoO&tAFu?k`7P%3KB?ZQ#(7RgRwK?{hVsp5L~QEyU^@` zJ|4O+&q(D{YV><+ccNB9(d0@8XCiIGn^NvdQ}fCEbFoZ)!7l%tSPQL`lj3_w*KR^? zn1nkpzjtCcm!>Mm%k5Zp@ z6rjPO>*A>|`B)wVVU1(}x9L=x7;(e=kCDb3h<2RctWEe}5VeS01l+(Ml&*k)gh^9Z zJ-VR-2I0YgrS)ciSU8D#+Jla1b^ivVv&jhRh6hsaUC+xWDD$2qK1BiGNN^-krP7rCE-Pcm}OefJU&-oc;K8RAk zk(EIdOEUmOIj&GCCR-gUB~bb#4g!oI(zKheXfbba!!4=4-!~%GS9$Zlw zYH2NaADCefDR>BzgLNt%g~rE(jA$HO=tLZ?6i zj?y60$&J&-%6M*o;@PivE3%5PEk$s%s+Gz-o1J~Mj81Xxdz2A!3{H&g6t3c-b`6<8a#uG!85KboC zF@w_!P@5|Ac-Yqr%Bxgz;~qEXyZl{RC}{=t^hEp06}z5R-Ab9xsKLQ_lEPoEg}fgd zXG+JYl|)+oJSBV77aTz9cqRBHUBB^+Br#y+_4IAxbb+MsP2$GlcfRS}#O&?t8zX*v zV04_n^-GPG>PAiXk6JBNwprqp8d^ism=5V8ebU<9Y$+m@7!mn3?AvbF@rO|gD^3#h zh5cvDEsWSUsWoC!VsZ(}W`w#vwiRBG9aZT2;DbD6PNlb{_lV0wBQ*_U zK>kUxqtl1s-fMwao0(T)Co5BfZYp);K1*e62_N}-^01#XmoWpO{xh~j&A(e+bu^{7 zyAq>8N*LR83~Zq(?NpdXRvcsQ>Y~uAoo8L+Sems%OM521vUk7VZl=E~1CxMQ(10y$ z3UAv=O#LfK&-b~q|6?qUy&cT9IFq{)OR-)~(|Wq?=N4gw@Yq6)=ob9_xJywb3Ir(L2Zg~mYZVw}%|HyD?kl4dOposo z;FLH$fws?GogO_1o!Oi7w(>A5z#1uRXsx(*4mlJ`Z!KteyDAdo9a7O!2m{h z29wq2^N3iCBccz?!>9d3&m8Mzfh`CHb>%?}3Q1bT(67hRKq-W*0K!{6P}ax(;!|>j ze@->LdvniLwL~NIqjq2zi7gYK+@uStcGG!AQ`6<4-k&eJ znW-nIx3?G!tK-}({bxwyJjI@9mAO!6tu89FNqk=QZl?By2Ak0V{ml&bspt9eo2Klm zZPPv91-&iyev8|zH)prevA&D^cbENlt4^^uqr-lP^iRWS)x`cWd41EqaExSMOHw81*_^>}1mS*p}*CQ*i~Gc}y|Q6Sb&JX`D}2Xm5p zEvwOUJ3I>J$Gu}ke4W!I!Uor;X4Z`!Sw)H(n&T^FlWDdo)70OG`gPM?n~?b>!RPHa zX9nN*I}c2|Uz4h0=d3&T-4Z)>t$p_Qd?v*|x&GU*zrn12?16$P9Fj*ir%Jq5kGyMq(1#M8=YNE= z-#_AH>6(yGj%=Q{vahI|FYxd@^4AG8m0`MnFWQmr`zP6lmed>I?ZdvSMl%g?M*u^Z zT7pg)^~)Y8jJJ_>jaM#wWSlg;YN<32L5UYOlE(wcg}d*Qa>L*O(hQ8ntE-!g?0CV{ zxYRGPJH`W3Q8mU;f7W;%07@exiI6#5q+t;vTZ8}z2qKq^&NO(+*;j$woU&g%*Fp*| z128R8tA)cOAQbB4@X>+gFK1r~0D2q{J8lO+oBHhjOk-YJ{N8Xt8{5;srrUpk@ip^;JNk|&lGJZiCX0q z%OaIm+NiU=;zR5`h2uos*@5LVtzpAUJ#ZkA5a_5kL1dPHv5ryFy-CE*on|z9+Z}rx&Lw!8; zNTc;rzW5r}vxFqPg7LmXlfoL9#-hRmf)ox#X#&c;5iF7MztAu7?&S*NhaoJrfO_4pR(2L)=h1@;wP5x1&m24Utz2*4 zAWTRVEl?Tr16soZt}D@rqHo7Ochw=syIAI^{>ptpo(d^@HDuXw%*vTXsmdTT%O3!J zAIA5S)l_&NrD0EdS~d=ECPqS!P!`p-^>3SoGjA1*V=5FHx1P~&=Fj)!<#D46{+@UX zZ=R&uqg!CfV>fT3lSAR;G-PAKIOhGY$?}%WD!{ZZQ ze^epi<@_4@0+Z%OCzZrB0w1L-zYfx_xIyO0W18mtyagEG1k@q!xr58||IY&CCc8!n zg=M=yfy9jj0Myc_u$Hq)nkh|s>A(f2WjBL&V5ecEr3&bi#V zl?l7p{pPF6xaz(-8wlvGIEParQZA!KJa$TXLs- z`G?-S@93>9UEui&Cx+09Z& zPW^?kJa)s}jP)LFMw$6|_@I+T4R0^c0+V7)$iI&g`Q!Ax97M3o z0a0NCabS&pqoN>&#I$Ckq!1 z*#^3!=;`%di>$}ViOJ);(HwQ9KP`L8`g>=eH1BOKczcM1Q$6#}n;&{yXD{;jVSL%v z(yjY*NBN0KdavWHvY?ZerPc|4>#EtRJ&$3%3XJzkO~A;cTjf%Ts=f-Fff+ zlEgPMR`7J_QEA3tq4>`itLxZ<=%ea#pAUO;8f~%bLs>8EqDo3Hu>p}Tf-gJ{gTs`I z#yEe5Vq8B6WjD>p@6|su(68D^Lw;iH@IiScZU}T0C$aaHBGnf!oC(Gbl-ZEAGeRm6 z)!SzSeeLX;h=U!~_qx0KO}98u7u`=+y{{=k4EU@>%aq!#j?sELg|4pFDUQGCnR>}{ zEd$>*^j%cj33kz$3+-k{Kz4G-*s3B!!i+WGpPEulk(3W^c4Qa>wx!7*Xf^J>F!7EMjQyc zAr3;C;AtR~2=1EgLdejfsCc$)V1|{_&>1i;8Q3^uvtAn8v0;~0u=#Q=o(20Xeb8Mf^RD3Bfe{fpA zx}0C$r(8c{^*F7EHG+UKkfj3V9;*&gh~gYjh6hB;;VHfe$`5(zu$YTwMi3%mvZGeB z5Fj`>j{}JhZtn!OGnPV3OpEE$72~C%pe9iY2$MK4+!|jF*M$5y|0#p!m5dr&P{mxV zvaZ!?&-!6Ca|pw?Sl%k7uY{I1xF!%#Of8=EeKrIfsMGQ{`O6OZSXBG5KG7qKqhQQ6 z^(BCad4@0#uPwrFxbne+>SMFRrm9RMHL#ry&I0cBAHP$1hc(Mm!`uCatC$n2{}rPr zx4Yf+p2vE^^=A(>s*?G-RbRO8jFL#uUtSEpBc<6pw%MQ#72B`{{4@8;I7!9@CXUop zl5Ho^bhD3P3AUB%HH1KG#>7}=pE(eB9FxP>N`2uy1=*P&Buwtzyr}4eY>GN4r^Za5 zDis%2P+vLf^_;4<7JU_+)@I(h=v_G-ar^wyBz4akZ(1!j$>-aW(bh&CAJ?pboEgI8 z7+;>g)Qa^qEme7jWc+Q>3)0$i96&+GPzBVU|6$>%-nx&V>o+v1ub{w-U zanbu9mY^R{Pg_TWf4#G#{da46F|F4#bYzBBY4m<&?8&;ug#HU2y-2s?X(81^;P-WjM0HdVck%DpUROcn{ORVCXZhlZy8Zy5oWjDVibhZ*z^O%dfEUYDzj!~wK*s<9%^sIcOx5VS$=u||I^j~&;>}Gb z!&{9_pV(p)Xj zo(^3kKm98sg=4+lH>y$D_D2<+I{ECeZ9?Z~$eKq?n2Tn#+(XpK#Gud7PAW@cx|0N+ zZOyJrBQ`5wA9I!EchE7O%la~{P*H|yCJi}1|6>&PiXTSqPyN@D&%T!5xI)S8y7M5f ztpCW{ps9U8PuQ(HQBg+|>-gb&rAL3gY5JN{^HDn16Qs3Coc48*OR_z!4r=poZu*2J z>slz1y(~iQ>4fs?(S>(Kw9=Tfm6g9j(28_Q!NhuPZSq*r>&c30p-1;ao0`0irstTk z-B~QlSgK*`pT5ys4L=W$M@$9{o<6kQn!9dC7Z^+Di_M8mjkRvfjgZAe;TSEXuHNm- z5vK{+)_c|nxNUtP9?GSk8GEbxIa({WN?Y&d8X7rUj%0OQ#gIR8u%hRo{_a(4#Zx(R zIpvp&&8+>U<(rTFNAn9H7o5YX1U}L(e^&?V zCO(GbW`!LCiH z$Ae7hA71g^s@_ju-1lpo6l@Ak>{S49;FwF{ z6+jdKAT0m_;z0GxtkhU)kRSA6gr^wYr`y~k&cT)aXCcr=M=L>`1qKV0${;7{f`lms zC`A!D0i7Za+yj}efzQ4>dt8qzgOb@cCstw16!& zzqPk%!a4{gKXu=~%Q_iqyIOMkzX=*yiDvfsMg5)d-M^8aY_F`(qR#63XXIy5k&5Da zjz=xjFTHMTTAe_Ex1he*0r-l2p$W@Z-JM@xM(S~-8l5>88X%?9-fO>xE*o}NgMN3K z*Qb_^2+rzYOK@AQPZ#`c#sp_{SdKYiNE&{E9hV)CANMe}jp|B_C|gZvV)=mB?ANI= zKQ6J?2;3>h!O9fKeT?`mBvm;3{6&+u;Tt&MaB*w1rN_JjwHkX2w67=2{|Aj{pBY@wEgpMi8iG9O9y-nI zy!Mp0t9P&`jj*j0kZ%+HP`2iK?NCu!h;62@e|?|0_{1muo+{njMIqPbkw|&%xf3t) ztz}9yY40LA9FCbF^4J3(2sSu-3}c4{oAary*CJi#O*;WH}U`J#NB@g^8Jv7RtTl6 zNGHo(d)r|j9WUZs7a@YVygOmqKD;Dp7R#aAdq0v{$DJJ#boL`ywgLYaeaLE-VoU_#$#R@=;`VRMA~!lRfgiYQLfi)4 zPZcL&`{?18cS*mhOkbf=ZpS3A27cO0wn+34gxTDKZL_%gtgMf}I`|V_-*$ZHtJBDT zhB9nj#heUzNglD}dA)Ak>3H??Z}*d_=|^pQKh7jh1`4!hTB~Z0qWh^LbK!7nl_+&< z{&xn47_T){71Fh-lwFFqE6HqR!&Q8Kw{J6N{Ntpie#%OG^f>h+=zD#_n4e4EN;msF z)_%PyOXR|?s%6y(PHm$q-6|KR%$@TaI3wuR#_~D)JYmq>9697n^6h8{$rzklCQR1g z^y+3XIy#lxfHTsh$rUwGsv$=+w#NWt&-*OSt9sf}7Vt=l_i)I8#oaziact=BCnmE? zH%0%<#~Rgg_Gs^X_3Y!5%=v9QEwro#*GC>%rSN+r0VW|~aD|xrveJ-8#0l-Z5Lj3O z5P{D~f6W$VJN*dS@5tE`b-y33m!w?HRxMxM)L7QIDm+fJ>)q9IrhDOF&{FZF_+306 zzy8_T(o(a}XRo2wvn;RE%e@mrO@mAJ%4RD6*WTB?MU>ojyD7%htv-KO!+q~|XoL@| zqnyj?Hjh~(F%d6?iC){3(?20CE!9wZQO(F@NJJ);xP5<7D(wY7p|n(SdyvI%g1+*9 zqh4#$Q#q$m(@WnoRAmV(p1n^gV1OFwq`-iV4$ds1c8>=bMiQZFF=8lBBrFHWg%PW%_@AB-&dc0zRGh#=HFD!FQ*2CT}5b5O0AfEa@KeaH*zQtZm~lnD_t6B3oybutDV_RrDo2pGAHQ~~Sn(h|!` zH6pz{0alzmK@fU)ia`3e!e|f9JxtX%1^x?APu!;=c?7%K*RcW@a9|jxjrFT43u8PG zxfJZaTv^9zmMnk{Oy-rgiJ0Nz@lt0-$P_@5Wq?0Ds=;)^PK=O%oD|};WUYuWnp8z7 z!ZH-a`nJ{#RaM?EwN=gfg8wVokNkO!;ALL$58dvL*xmYbug~-I^R>0L9+Cs;{Ab*vF*E*Cq6Y%N+r+D4=SIg8+C4nfQ@;56 z5DsR{YT57&S^CuK%StD0v+-LR={w~nx5i$c(>hiHH+5Rvr;!%%HG`oi+fw+wRVm!? zizU=IG(lLjz;3^~=jKC&Mq2x=Z<>Ro{x2rqKu!ZUMm_e}59+>blWo}SHO9bzww^6Xe6$I2{4e@U|@ilj4HgSi8x4XlBZRLCA z#8_AH60HE{?rNQ+d$~}ec2)`z(!j;@!WqtYdRJogD@-;T1B&uDiPM;qMrsC)Iq{Oe z&k`Qb`@}md^f5)QIsaicJN!92-6FaD<%(hSYs?J0!ed3RlLo^>mx{oA-ulX}OyrRy zeB1d?3HqhB>a=Ellp+<7(;GFZUX(@Wt`|r87o!O2J*{w?q-XS$r#H8cEja#g@LsUN z9xW~LJ@J{oRDnt(BtH^EDMXXz{KGs*PRng2xCKRu8AWL(9t&RDtcfGXvU}VN_w>(~ z&iuf(5;Z)}v%E&mbEOj}vz`g*YdygzH1!YSg?wu{{$}p;;iA>eXXDSq;2zdNCISr* z;5_l{;a82$xqAsuXfM7-T{t!)E8eq*W^OFA!8H)2E&r|w@ffdS@0ft^jfmjr*y}i8 zuI;jEqtBFB9l{!hp}Uv1U?eecJz;;7GVvG?5)#VtIi2y8iZ_4K+;94q(-wNRzPx965>S14Kydy$e&J2i&B*f z)Q7jtcP&~c>*=T8J9R~4I*&N;4zye-H42eNh_^0WoE=i&v1YYkj~&0ONJCF-?yB!H_w_Z) z=&6HAO!~5I6HKYgi zut;9`;3y{;wpDrky&MuYOu%$#XwtcNn`u^^|A1wGn8s3b_f2bRSJ1-}Z#0ufGr+EU zd!D4pq=kP=blymw@!#!EwjFHhO;$X4LYkVIdUhRS>c+f<9f8ZQ=6=rH;DP+o6u=7^u={(Z|6P%;R%QRyiUaa z#;c+|+r4p9g@?3Jq>zHK3DXB=W+N$R#q?;4>LC|R@x5iHXZ>RRk^Duf_d|WHy_#$J zy_T!S#J#RG^%&OlPqf6Kf;6NHW7dIz1y*MCL^p5p|vM*lwlod=Gvum?*+(prKxoP&Yr#b+HrhiX`7 zBp3(m=?dV%Fyc%mKYkdcnf>Y*)y+&Q(}!5a$t6}gNF3-91xCdJX<0Ic;}&X|?B z6hO)`rrf#R^6jC~j~S2d=Y!^8robInF&9xXXpWOskTljb16Nny06SK%u0T2k zkm6EYY9vi8OMjJ7F`1sIORofQz-oGH`UP>pNJ}!~y#n^K-_&m{QJP?N>OfXKaYCVC z4wbmB!U~R0Dd1*wm?il{6zAwb)Bg5-a1a$R+Bv{Ui&sTaj-nX;^mu&8!>E&3QPfzE zFE{5G>stgQWQI4)ost<;08y&}Y2?(DY-vDO%$BAg@s*BPJ53ckFv00^>dK>=6H-- zUz~clbaeq1C9LZA?{vI!GN?W=+G1)ltaKz__IqvPh}aQr6R~2G*qQ`9GhQ?4b&U%>R)nh@HCyNpdEfN`4}0-xaB{8knxMgKLI}GDv<^j%6o!kfe4xToZCRAY+Gf&?zthq)zgr|2ptmC#2zIXb>%zT^ zEi`jg1!oDhFT@_`^BLmAOWp2r18{havFS<=P4bAG&Z!!nWL77-zB z(5u8DrP3uJMO}pMt>LUlm2GW9ue`WB@9L1DHu#7wm~xp+T{wni^NkuT=8MZG7tYky zzM%h#Lryj0{>^f;&dg_^Z$lt6>#iRzvGOi?X8|x3+D4-Dgu0 zi_s|+?@O7_^vY5s8jMzGq`;LOy&ge7ou5 z`Yxt!H2D>Ze^}7#^d&+@rk+$PVM8FunDDsUTkEEcf9t6Sueft;+QI(1J*q7e6IZ5GWrM?+WS|}*f3KH3 zkLra8*<_NVf7S?#O@-vJRM-?U4y?f?HKk)mSTqeni-lRW>`pxkiXihS)n>E`@v!-4hIazBn2wh=Zcy3 zq}bGI`p>-Ss7N(iSNtS?b~b3ly}7lbtkkjYbXzCCjsn1!HqzIh)UtYk-Pbu%8gb_f zhvzAZ#(pBt1DoE%NWXp2>U+^Z5<5PO4i7OO)7S?qbc z(V?-1@7w&ox%t+jYnscWGgKm(NH1?bi1cx=B)il)4H$%ceOsPnp!*Js&+#Ggq_ao% zcIdb1KR%>}^j0^sMmVhvZ_{H?eWQ5Nn#sXfKSw;*%@BRs&k6`7@x5P-aBkgCkzsw! zU+~joJ@}BjyF2(@nwn-ZT(sp#(fT%zw$grW!>iMcH$|*!7DHKZ&$qIopab~@Gh*f9 zpXF(SiQ$hYT`75VHFXASANDU(gUI9Dp~DKDF~~4(j_?sZ60ET*juhl0=L{4J#Q{3) z!j<99Zpkm+ss%{s^=iCjAGXrvki{E)D{3JJF*5HC)6koZsI5efF#jf~GBFOZjB-@XsDI#(4kOiwh%zMft_gYDZJ4{)Zh=Gi+3J9~%zzfbw zpT;F7nH`0P^Dr`i2|j(W?jJzIV>=+^2t|b>k&!b3?$-0==TA+ruezTcs~P>15U#Uj z!}IHhM|N1nc==lR{_Rh{t-Q9=wl?Rv(GAz8S1d>0^@d3^l$XDuKOPyoIvg#|9L*bv`{FTO)L-%p+28UjG(1FYU;)JEI7 zC+;@iBpbfszIK1{z3TedP(abo`Aim2NFBnJ8bdI5|33@h>VW=aZJ!VYEt#(OI#e=E z&w7RwR&1lSrN|p({N%PWy1pAJ-gYNEYaub;ay%^uv7H;5PKmw}1EPctK>!64qOn1a zsx!`~fJp7dgq^ICW=F;+|IUH#0*?e&ns9JQ58r9lv@p8FdT&-2KR;`;hGocXNOb9{ z_Gh9b!M7uaP_Ml!ZC{CPBxh*mFH5x7>DZtdj{ng^KtcPNV9UG!JDpHV)m@)G05JF8 zI4vx^PaO=c_(HakQ~T$7ZjX%boTiv`IY%cw;%2>VbP3PF6Co?~dt-o;uu1-QP6HyD$UkiJ<5BB&S zyF(u@WY@*)RrEjGyCQk8ad7lU1c1qethZRpuKw%VEURqQ^%79x_kuf4AZJ97RKIpn zgN>{pX}ql4sW}y}-)R~f`6$eVm1&=~P6oR^q_ zx4&SFD(mLFsFt+j+tG^TIkNZPlaldXcP1Qv6YH%nTdrQ~&2EAI5$l_olU^;)aE`BT zD%sCG^ef7YZmmWKSSe1y;>K-#V#(YXKiWn1WQ;8i?W~lIDC8Y zn7k##AZtz9h?JC+#Z*%-)pg*5r*Jq9@xZ3;b;)ae&!v$1idGjcTdrr$S2|e_j>x43lACJx%b8jlP0ji5pB(JH#w^j;Bb(0e@AXA%o9cZImhm<4 z0F=PVvV7jg=_x4#JL)s8@#>YAaIEB_tWNcr5*O{0C#(fwYHWh(gU!zIE}G+VO}8B~ zO=DR@23xLgB!jr`ehB~N`F^&F`nBTA5k^u_{irM4z);`LO=+z=uc{XfR~P#&7B;Xv zI?7Sm;&|EFwPlYnUFBzaZNIZy^Y<;=%JiDc&0wm5ZPAu)Ls6EmqZno$Gffd+uwn;M z&q_|*hyv9A?Hf^3LyQZ^$pU)joAjhVh*|aPiKkf&v#F}ngz(IYw5SgpvRW3QYF-`> z+P54>-i{y{7_|U@u(D;J&dScGl_PV^y@tMVw9*&cy%8sl=-x!CSk9ar@~jy1e<57j zX7>j={aLqL&Pcz0ie6;oa3A)U0WSjn$exjHT8NA~0tW{Z4o-B!@bW`p{9pmOgD^0Y z6xbgIlPU&7I$zRexQ@ycs5=Oxd1~k24NU;xh+x??O$f~0I93YyV(|zck5w02EBp^l z*BQ;`AGRNRlNhD8R8d=vDrz-m?HaZBrl`GY6G~B(+Org~SM5==My(jJ)gGz6dGmkY z^L}~0u;0pZCzMVYsKwC=<|O_xsnkDN!@;SQhv@Tj9VIja(P;PiHBOllcDb@@?WSk? zJacdG{hs!{J%&5NeE$<9?ky!b*^r&a_M0QQ===dL7b-v31})VeAIu+NfWf6%a@d$q z=($R+5^)v#sXUJSGdEpFEXKY9l|*ehYgx+#>_7gHZvH8&)?iOYtcDUyEkzYEZEF)8 z&Ey#ztZ+A@D`l>c80=Xrl_3K>4E#p1XE*Z(L@~+Z+e+B)!WD!6_@Ni@2IGT3U?Rh3 z^5{H=S_Nc3 z3Kva+^2cf0c=lK1-v+gTz0n}dM&aE3yO#Q^Dy4u*TRb*nyI+>3TN_s1J98Ztzm*>5 za&*`lu0TL~=r-WWir9SZ!#s;6UBK1fmei0rRU5V$JVNAasN%g;6-Kuc!KALs%e3`) zuS9Us*Yft-CHpGc^sK?mu&?b&%S}|bE*Yk#&a^Ns2IeomrR5w9&LXCPa+;?}jH~zoECPc$+#^N{wp^xp=wQ2^}vLje#u$#5?Z^ zG0`>Sh0g7yd6TRP8u8&jr=utR; z`4$5co9WibkJ0mrdOf}l3gc5@$in5CX~(~$pmmOKjETlaxtG`CdHp4AC6qruloUwj zGh4W8Dko|c;(zLDJ0G(4^RBlD)YRoL>#R`PfK%5Pwdr&X!K-5lL~g z*4RFOz%j7`<(gPRn84K*qaF23c_S?wvSmhdex|W71WlO zr6|#6D@R8Te)(tcd=BRB26mY#?pX{_9S7snaTyvr@UvEL%%1UI(?+urwVp^?`SB1F zz&^@)>CWW|=~a*-VPhEG^BoAGDGfB#N|s@X9$} zA%NoY_f=yN~5}3f76L@SzOxBF$vte9`Qmih4>BtpKF`jUGGoh#4~)Y zNmj0Rl^Z7?e`aqeMX%mXO%;Oi);_l{X4IjVYm2zI=(so^5npm^tmXfvviC(n#C!DB z&Cw^Mp?Dd!p2&+vwXAn1XS4o?7k<9RySx0KwZEzl<%6UxyK9Tp9X7sxee|NSA{G@v<{8*igl+@7PZ?*eM;e{;&_8d{}i71^q zAma#<#s-0<3&J>ZHrs1DiI@7#Y2+BpEKm_b%wP3&RnL3y%Z6%fDb3Bz#udIzDjFo? zVY84a;sc?W9E3_Nm@zQ?D(`I2obRLf;BHL7{D~PB2nH}MHb!880h}&hvyi@-wv_Mq z_}xn_kPQB}NzIFy<6)-qR*?lUYr$@mG2~F#+b6$*V`HGc*yq2p_iBdsnk}?SK$?Pv zeA%E_fqI@E4ku58!ma`ixLo-5fW{J$V3pT>e4vBQ9fZ8aIh{aGps)gBu-$Y{vHc)VSeR46ZJ zZiiVgD~^qEG^zA;<0WB#;s=C40XQCFt-q~75-Tw}cBNm zaUPLg=l)rrG6qOM2XcyNPetI{ThfbzUH4mi>awN~k#1&=bl4$PR2I(3uhpHD3f!~5 zMaXD8)eOcrx7uyS1!0ey=cd@4kI)kpX`o$d$rIK(H5bP>qs>Gl@IfxwQp-^t!obsVqodgq08j+O>hu((nH5G)*5S41VrAV*nej zNpo((0*gs;dcH50blEEUGGrVhJnSZL^hTT{wb@7~aL$E+G><%bm)bIwg-^|UbBIsl z$Lm%Q^y?zhMFnULaRTX_4jPJiJOW)jD``0_b80^OFeN^2cOd4(GSMw4wQQ8dBVQu) zO)-2BTCmqqwiaQxx^Sl1!k}4wG9kskSqt~+D6L);(0Ljlw6ep?`%J5_WWYxGnI1C9 zzV$67A-|(9-!M|zR6)QebBN!cn)d)APa*{=m*8#`D1-p zdQ_lyFX!$GaP%Xm|BY^6r;4;cP`C1Y*Rbwsy7{aS z_;OxLQ{0}@lg)8_T=@^QT+i+sETytlQonvRIH0_Z zeY`eH&qzF>JHO`z_w4)2T-Ds(T-|J-*XxmfVBFSF{Z;bnQo&`RT@5M&`U0_WfsfU4 z+RG_Xww)i$OoZF|x}6|atwgwvA*yeS>iBacJvR>*#j_s+7l+HH#>RvN?;NvIg~@sN z;CUJ?+$hvC_c4SRYs-PPAQ|spOzz~tY_mp38#A4U}V7y7I;N!(6Ul&j7 zaeZnz^Q_c8qQ$!|enJmQoZ2?5H4t`WPad3y8KkU}N<;GqYR)!gfEIz_d@nK5e3T_L z&8E2auB;Q`NrS7b**No3RMe?{LV`Cxr(sdl!i}!u<$~mCzyHozBXD=!rIn9 z(nhb13H+@`gE*vdkAkgY(Kjyy z4aa7d0nN{USJFZ@^EwL_$%3m>6&+ETnA(M$jv@N3-fKA6l;klm1soUzkd>vagAfff zGiE{-X>JO%WEta_s|hG26pwqYNqb=5> znF=vyy{F4J3mY95>XnR*K=tNcb2#qYEiE`5|Rm-j6;^b($hjR

3E*u{I;JwkMHdFg0Co(j)BhcA!G@}Pj5WJ@qS0qckxRxp$4`euxfC@ zA%0clyxr$%_wTZcW9!lQ{kn=p*(gQ9x}1IlnhWmy{sI=e&O>b7f}F3HD7l?dZO>nY zVg~1Car7Pk&FQ^NRFsja8Jy_f!C`XHK+S(yL-ls>zyFJFy;7vsqm`C?wn~W5@{~0m z`iD+BlXUg=F4$KnPC1T%{8T=8e*&FU#c8tNNK>bQ_PsQ*`{E_>tj}?B#_zYv?x zAYTO9?sYRQV+ket{v4k50%@hb8}#EQjS5 zW^i=)(FIR-NN|_W=%Y1_uH*vT* ziY%bnpKt^lKuv`WTg*i^DjY|%>>B-By-J>rkbvM9=SokYen(@yPVPehCKj5RL$ktD z3nw!^3i&F=-)hlO`4_I7fsKEUyKqg5-xBsR6o1_5@%`40PbmJ4As1~BZ^wKtfQg>2 z@IxJmO1>iqOJ>zz<|cp>AT7VM)Y&0Lb>6r=7eFcQ8oOBI+mrL z=DpNAdszh8J6P2?G4jnagswL5dhqdF7GZum_+)I~t&oN;IxbOPx8_@G*83y}@7~`aJhk zadDo~Vn(D>$({s2e$K=}r>flO4KJy9nnJmHg~!&nTAYRYT8+w-6j`$b(Pc>~j;d>+ z*}DdB#=h%ROLLad5v^K-P7lrPo$K2ChN7ahut4)3@*eUEkEj9>-`nR0!}qKzaj(3y zV<13!2#wzxORZzNG_7)F@!AaD5O)M&Y>kwY$%y)LEb zXf#PIfD4ff+Kw+fiE4uSM2yFNx%#R{LNwW|Ip^kPpkq z3)4qpUXx#Ay0;ciTl2&3RQOH5PI^0aEGn$y>h*Aoq*w$okUuJrx8@1_yzU<`s|`BbRvQ~a|Ae~Lu=hAHFZJwSvj8YJH(Am+(kKW) z>YY;1i@G0e>dyo$=FLSKxg@?Q=P3=GyNK_Bp|ocMQ~f4;Y$()Hc;N%jZR^&wl2TUB z2+5k+vyHu~lvFXaNwie*wD#jB4H8o1`s}nxtTTkX!U&~&;lYd01l#A>su{?jxNYgu z`D@saf4`TBn_ii}AM`txDbnIOb$dOKZwnudsPvqq>vNojMRyZzrU1~8;D#8L_9Wv5 zLh2hp2%6v(7l{g@yq~XzUFF2lp+qN_te?6tKfTv_>>pAKREeIHr0#|6^{X;aepmnM z?F~zvX^&ma@`1*1RQJ#9GRbhHs459kzpZOnhWuEkM#EmnPloVj?|l(R4`Dx}<%tv+ zKs9a%x=)+cZ9>jtfAJC6-JQgE7@-HQJ@9hUC`|cLZU!Px$@L)eAiP1z9mUL6T&Nv$D zWaeF*Q_xCF(F)(!^Nq=f$-yrN-Esh(Mg2#C<K^1Ls*Kaw;iF z3vovcsmGz&AnEwYtA-?v_nk|jqrMI;7Hx%y1BM#g1oi}cA~K`3b%B+o%^X(Q@T`-V zuHL})JBpX7Qm|jJa9-f<>S#)$*SXKz1^5+?dh7CPHrMM}DB9;BMBlqQaE7#cherv?yPxFCEhyEYM+-7G-RSK6r?3NyJyssx3uaqqr zr(uO>KKz;yI5@4gq~e4>4bBg~Jf%o5 z>^@7~Hp(ELY3*wNf05>ck{DM51Ztr%r}?_0Dy^n5L=%3 zgDDv)6*kNsCp<2A?e2CWjkGaKxpk@&|JP?4hwkxEfpCLj0kdE;K`(l{>dKiaH93D~$d0I0^aWl#9S)m=yCbk`-q+dLj zJx}i{_r_HbaiX($vJxVmJ;=V)X0Q_+E)pY_RKq7BP$7T#UKmLn@Jq2tt;_@s1zrl4 z7s<4m-1dl)lL{8Q?HKq04vQenwogYg)nXPO7_GIjJ>@EkvA2ScC(B0=jf9Z-hZBHJ zY~rW`yF!elK0z6`CzxNQ(X<-3H<58qF}44#R&`0?=d>5uTJYav8!JCk4_Y zw5l`=W-BrjS7$CxVrcSwvl9{y-N3}`-#;-@8sqZxONY6+Pf?8?e# zGe-v0)!M}=%EFd@Z*mi}K+oUv@})fLz9wc&zZbcF@VwmQRa|R?1CU0RTl88|W0_gp z-8Sv{$?|d+)>ySFalb7Zb#`ebYAj+AWB)7cH?3gU>pf~jMJ>I~{~YDj7a)jI94=2N z9TJCRG@)OO_aR0wp@nOTK6Zc+3F1J{j0h=K%vFfjQ9SU0>WIQQv*llFHJG(nen=^p z%vk$p3T>aT&X8qg39rrb=rB(c*N}^&o0N@WS~roicRU5u>aZU9H*JQAnbv4kEvF(v zXf_Y*yHvy;wap2d^?w%Hxvq6_ny|4rF!zYp+(B+|G>ieE(Zmulr@KhP`)IFMuAbzbpiO0rH-tH{oCGA3J{6D zTDHC%#vF1h;y9COjJu89^ZCH|ITU?h)FPW;_-$4YeqNjyHlF)q_uijoEig*B263$~ zEqR1EhgYvp2G<5l6i+>1!h28_ddLOEIeZ49M~lh&Lh36e`MnzVN?mwqG+Ei~x3WTK z@Q`3=#QN_LsIpVgeLDk@77K@K93Ypl)yD|bf*rV1f@r)#o-Zr#svmriDM5k_>XdXS ztGR3=fS;~n^-h=h%Yw)i@>Mi2X0kM>^t4J9R&oi@=voEr9BE#hrv{Q`Ts6a7q2!0*UTR84aN$`GLNm3Cda;=#fI zi2a#Q>DoA?#!Hk5H}Y=lEp%uaA;+8yJ~y94#o8@PskWnfH?KZuZ&m#Dt*!FlU)eNa zwNckRG}L#X2*UAIgrNniD0fy>fiTiDu+;AM=M! zaq;Br$vFV3zC2$+yz}m|1uPmn6iRQ8RW8Im_YSvuB>{q-i-&}5;%$(QQDg7<^%kJ` z`&A%e-%X{(w#sJnQxU~hi`QV59!TBvZNau3FeKuu0E= zTQoTwo$BAnvf*=^xKD+~4;4Y+WTad0ZT?r5^!@eV{O(S!zbU;>o$lbk+kS2ER?v4J za_o<~E02fv;Ldkos}Dqa!ynue{RnL9ZP~>CABw$OjRgneYdb@TC<8nX2vcCVNVkH) zy>Q|i;@8jfX&H5=LM?=A_m}?<``1lkD&>A#9tDkLAAZVn9}NsKkqhuyjtXA&o^usV zFem?_C+qMNkcy*~9WRjpf(ZfoJt(d#8+EYfoa|U32$4owF?)VTAVvTD{!{1w-vt9r*&)HtXkISxYFX_894@kkssJO7Nt)hNdJWvRh1BfB90U zN&yPzW#mlb_@`p`cjn|pykFzS8CBzSSZ5yYFqS}`R2JUB!D7G5c!b2$=JgbdN^k&Z z2w9X|)R7~3u9p#TQ@uyjlJR`hG)*{v>)q(Mr%YC^AtOXga|#7j2Po9AqzDo_jKJs+ zFC16^Rg{`R;=sz#A|fVrD8EUZBur8adKe6is!epfl?11ZqGW&S^`a>e3QhtIYEy)! zy>?-$YjtNtZb6QKtHqwjU7&I)+Go+g$}i#F5oT+@w*9>ek&W zk73~FsjIW8zdM(56*_0c$6`L0{mDh9Zof5jGq#gwWf@Q@)pm2ZWC7-ELRRhYy_1Fby8Z4NNAL1 zGQ&)jB!?Mg7)ope#v8pV@|GbHSdlP*=6MG+*!q|nwmPn<5v;IO=9C#qsTMtGw385?fB{uPtP%6UV=VwMDC15Bj0aX!C!%B=Af#u7E(EwWD_#7Zv;KY~5}li}h*B!F zAt9|8sYsO_+Mw`vKnDc|XHRhAP^9bG&)Dy3IH`0Jy=hNyz4g<#YA2;yADDd zx{j9w=l>>#6vitpzxKP%RHR;9JwK>g6aKBuUNR-dna|c)lav9}s=X&Wc`5e#qn&?BTe>#K{OJ;m{>SzxSWTL|6vxo~Kglnw1^k63Z8d4uS(W)YovvsHe4Yn@Jw^r>3I$}vGpTOPO_7T z(8(@P>6uorf34d)zNY>jJf74jyBkVc*W*Vw^*00nq(lq6D0>lqu4t(B$?oQHhR6bR za&y0WKk!DO#aCF5^&`cVNRnW|l!B;9%}x_IAbZ&yhUTiA$yR5_(`m6CW7BrnOxrqE zo30W_67W=oBB<^#Sdw&+%%97J%Xq-ayycDDHcUsAAK2 zKEhW7Ad;B_VKToN>fVaF^i)9n5&fS5B-x&n&=QB!>4W*Z>}*d8QRm_3uM&@Swm>#L z&!d>)7k)tWFH|g;Leib@1oF=u7K_UQF;99t!D69bEu0Oj<{GKkm0Grjs}W>=qK`_z z6X|g?!z+`EiHeJ~Tr@YiJ-s&Yq>_f^o2#86LCwc0iz$2J!N*&Q!8c)E{oiWRANraX zT{krCRp3IRDB54*+>Hvx4_VKRs?sqo*4^jzgAIi)XfU_B{*`>g$$4lpe(?ij<`Y>1 ziai_ZT_&EtdaY}BKj^*un-mD<&H=wpZ@+CqyXe@7Yc04}m-`MD$|+vP?`u@b7PCs~ zhnYb9S}dg%F;~_FkK@DO?g_UWWaZ6f-^sl9?Wz6wM932%4(6-OGsa+9)69C8^(bQP zi;j7(v^(SI)Rd@bC+qL!>h3MG(S#%ZeAimK`E$;bn}WAT**8!yDY+rAK1NnV0FEJ% zj7+yP4yzRG9K4%_UY_>{;NTF6MKq|=E%>r`Wc~Ok0VC}L5;9*l?40qGeo0I<{y;fE zS4S*j?zwFoc#}o`lK3!Z3B)kGP3j7|6>xNe2x?SmZa=g+th$ZUol89bkI@UJITkM? ziNx&j2#Zc6ovlCo{0`drOcAhST-$Cvx@?@e&1K(g`{48cXj*l!$9B9|$Mfayr!oFp z_dT-jkJb!xr&9*rw^bop!H>J^U%#oz&<4!n#%H>#s#Chv=uuHKr56AF^SKLkSf~pc zd+D}kjN`WTxL8EYvc{V2vBp)@wfXC(x*SvKT`_``l?*k2lA5Y?$xD%{S|=$dZAD~R z3JC!?Vq@M6l+x*-p@QMDZZr&pnL_=&54$I2Vj)t+eF0X#_XJ3YiRt1b2*dohYdCleH%ffeo&u`07(SUtNO za|u>)9#J`A%+Ad{0g*z%a;e`Hns|J2e5zi{BmT|6fU(5CCt+r0yqITlWCYb4ao{c{M`-h(1dI6{X)H)qo21`bMs^f?t;EPi-ATS@R}5^)uwfW%vDg>vIbOP zXmj4|I8c5OM*h~u$Dpr7^jw-V+w^um&aCymxprORmP6ot4$`*;k2-aXFYKqRx8?UA z!-aeWEBieB_f)!k^i%E z{BAK1u%Wv+bd%mAj_m=fhhw9pBt!-Qaa4~XrK|)i6zegK!|Lsf2B5m$Df=-$X#%X< zqo=U^Dg2fj0{M=IEQ`dzni}B}uIgZBj~9QR>{wH*h83gaOpzqv@Hj}LR@PP!PE8e| zN~_^$3L{T#(pm0ocXVGt=uMx08CBp@&EGd?p!WCh$o>ZPn@F3=`3f*Q6N3$iB+|B# zwGUKr+O{*U>)3D9dVvN$6fY@m2l-uI$$kpNmP0O)kfVelrRxT}3!LXb<0+bc;{*C{ z|9nOWzw>bx91P=>LmL3trdH(lzI+tLQe~!nKlAS1BIw;4y)iFFr+8eM{#BgHkj6lc znEE|WmelMvyko|nGh2*aM;pbjan#0ha)<_&rN~J66 zucYX;E}`Ci_tqbC3#al@?Vw+v&^=nG%e=rqbOE1NZLoa)4zjar(GdlyIB(MB!KjLJ zI5d1^>z}Hkg-G`RS+C~iRO!iHC5kRevXq>p`rL72igCd1Nzra8NFd)b7*B6=)A=a{ z^BoEXv`ENF^<1v?!7lraRiAjpMSO3{YiS0Q=)0iPS2|QULEV0xabVZ3N`E^|S*Dg^ z&J(kQoJ_c4U%vie&&npN)13UO=#`t7g{O{z5zk6Y{9}O9c7N)2$T;AY1knCwUhu?0 z(LL|F0fi!t?N@o}-&%^^fl#OwyxBnA3f>&8eXRjG5WbD%@UOIB?M}JRZ2OD|QMA9| zhAGPQzAgv9md?I4kdGN$ji6^K-NRA5Ju-ZPY&$wCFc|I^ziZV7?!WPKigoAsGrP0OXOEXVUk1k+Z)c%6MqFm*BRFn!wZ+Y zFYbm1q?)9XrPZU43j8z_lGTYK!Q#SibMD`uh(WIVu-Mo1M5FCwvv}HPM|7+l_!hbR z2GrNW?vYxzK1LS^=-d2K)BZ0uGG{HFP2Z^xa_<%Ozuk&gQp$HYP$!g7gz48-c}uo! zf8tdo;W&SMZY4L~F5|9z`MdRc9pJ>9K|Ed2tZqxUh*H63>-^sa$N$ziZ1&#OTrB?S zk);o~G#Cl$u#&T~^)}bHyBpa<>Z*(C{GVv*5&|*JOs3Tp9BkgAe`bCq0>(pK{O)9k zKTE1Ii9^b*M-V)VeO7C(9o6ZciZRt!ZNaMvg$ zgT^cL+gVFBq z4!DV>bTK_T433W{ma1BQ6CC&yAuRt|?mPV}}^RiNDy!@-KIK_{a>SiT8I8x9IFb?MEio9}Twk z`<_#wS>CCj?|TvOuG0N`;SB zM=C8*Z`7+R71dVIUA_zGrOCU4G-rUPv{~?}erCnblgW}p!Xk!0;NZy?frJ6nIn!yA zAK+&w5n3kB<_FzThYi^ESy^G-=`)}~A_s4wRHL5oD1&-_70?nHcs_aRycxMKl0Bcq z#X){S^eN{bPt8nIQ`d%~f2YR&T3N&5amSMR=$kJ-qeN{fslXz2;e8EdR*d#aq=-XuW)3npOw(yQsLMFo(*-#Dwx zSbjS5$J81uK9(6dW}GMu)JD;cnb)(0pQ=^&eU5!N@)pzgxvuDW_#}FXQD=Q;hoIam z+gPq5_dz0B@M`0Rq34OsOFtU6+AS^IGq!bE-)0P$l_IYkqSfRiPLsUUp}P*{4ZSwK z6VFF#EzzUyOEQuJRRUm{n|Nvz0sSb?`sY|@Os1GsYz{{vPVqkF zX#8|0{+c)oWq$hJ$7jo$gzUG1Afryt*V6@SK8Hf+lV1DcFN0O@JBiLRLj|8awnge5 z*_QA0M!maQ#RWKd(Ett}-_9_4dLXVVoZ)Tj>mI-kFV=^9#qFiPPjJ*;p56=}ugj|q z6Or7T7NZ6Ae+R!5!SVdK!^K!5u6p_8wKP(jyZknJppEZ8>F4~jxemW;&ItT{73XFbFdI)WW`0FiYsr%r&jj+FUD4Hvkyg3`i6f^i7b%m zg8Y2!q4jqs3;+g=hx7*3u$pAN*g<=D1gBNXbkG&AxJZzD00v;eFa1laip!lj?O&u> z8~}jT!v7r&B^kv*q6@fo8s|x-SOFkP`we6UaCSOaR{!{(>sBhIz7*E4Y1E>{k%m$W zqM?Qpsb#_c(pm&OYQ9>tYf3_gBYh!`rHsIrmHW)iX@d2GijrwiA`VF+j<&tJIL2&T z<43we1IBNe(R5Ah@L@e9H7u0kuLr}{U?Fbbkl$3+Z8hA0=)#AUy?7u>v8hlK1wbA{QOS)(C=ExRsLB9Ii>9kYl~wfO7iZXudJ22$y{sy% zzm@&Fp20#HNwxdWaO%$ZV}D&ArXeB<0hN-{y7J?vbk`Yu zkdg4e&buayJVJe*Q?EaaOPw`rM`q6BDOcxZOMi@t|8~Xi6ZB^)c7Yh>%20l)Dhn8s zShJ>@;iSr&J&mUJIYk+|duJ6H_KUab{Ye+N&7D;kSYVr7Us=&&nD{noX5wn$p#}4M z?+Z~TOITzh99)u`7(`e|z(GU~LliO&rh@^%saJn9nFy5N#Gs%c0^syhs>CKlX4CTQsOtG-$Bvj>x0qMr|3?YA0DY7S-unx774!!^0Oji{)94>J@R}T_U#2 zFR|e$H4RMrv%bDwgQ0ltM6HZVRyGuCCh;bzA~I$s2FfJKQY?Z7t4sX{g-Yagwf|*< z?`4;KSZ2KcN5m6#p}vL8Tr)IgVrYmgV41&34*@nXvkOQ81biRU#6s!`pOXv0rUE9k z^g;s^FP85|Tb}o)*EkvYN1Gm)y6qnXoJ4A1o*)Vo1t$13dy#4z+b?}(lF{t`A(f=M ziMDhnvmx=Kb&%?*-w}v_6rR2plMH|m1V9MnvV@(Ia%Asm2Q=}-P!W-zO=p0@$}UAF z+~8cjBTDfpR*sI~p9x19wa~Zz&5*ut7~~T{gI3yRL2_lrCx1N~`XmC?*uDqrp)+Y1 zO<*vw1fK;jqJlcHBsGIAjTU|C|J{w%NCeK*VDwu?oBOf$&;X=kNMsmk)yQQLC7^g# zbrFLV6^5TDnLW@d)~02(X(j$TYd^S<9JeX)dRB9A&dtpfAV;INKYmcAHFtDP-?F8y zlEFDTRe|*j(b-mScy`8`fqIUhPtWme_9YdVd<*^qV-z zHh@RTwEYaY>^{ohx{32x;}C6mBciS5zgVhzv;#n-;7{Okk-LA;9#d0_mBJV2bVzCW z4dx50bLSby^GX)bJ?ily^So?&)!)ifXWQl`1s;N%my=)ncny#Mx?K+w$eVX)6hgj` zhfsZzPx@_ayn@1B`#HCpDHDfrXTOq{pn8^nd}9@QdAwD5JFi&k=#5j!*cr(eg$$@| z7i)EWbX|SiT3O^I?|1QzhY;Amkmh&p$*>CD{-tD827MXfk})^$c=q@>rqud)&OFk0 zd?(t>nqGs3mdt;D-3mA@Bz?R)a)1t;3OK}m5bEexj_kM*URwVMx#|LwXi<FKry#C|SNhH;sR+Y8Q$p9rkWyqL3;l|(|IP7E0d-*{9YT6sC7<(S z&upz3!f)S?F4A?c5y9%^CXXE-QDF?JAyk^wqBEB75BEzfHXqEhgITpzx*z{ur`~RF z<86h5{CcuVw;bPc(fyz5+*yHQG|BYoVI9>Kqtda z79v-yrWR~84U)zCN=(Xs<4hp^=GX6NTgA+4l_Je$fmJqXcyJhtb?*S*G;3#bqYOo+ zsixBoS-E@o;vjPN0Vk?d4(2Ky5YbJjk%_u&tK5lh6fUMEPos69EQAEiJ}ry2`toHH z{)PvVr;dIZ0{bP3hsqZ#Qbn!6Ml#=St&>Waj@d!K$m{fWMggPLz?_gyH_lu)q zfK&h^6Us1Ed1B^81xR%05(}I;oHzp2E+1ZG79pUJPZ>LlFDrvDC9coVSf6WrIEqkK zR>GLguuu`x%@(DW{dK*ty+4v3hh7B{>vK^`^2MmdptR4Q1&MKXN4=_)UN*9MD6@?l z)R3y`OZ14Km|clOFvJOvD3-ub>ey2bMuX&IVGzjuL~%7n<>?QKP*}+V<0zzDziT1vU?8eV$NDy$M`Gig1FOUOtc^0Gm?k`}eTJwf$` z_U~`q&%Ervo59O?tJW8n9gvn8Hs=%7`?|=Qxo+A+4v{E#jeUrnv`vW*$I;KmNiB+< zD}#}){J_hl&f0$=f`1nNEP9U}ecX7Yp)EDg!}ngXl5ohv0fCY{AD*TltO46W8#j1% z+5?HoOFrdRy~(57USIYNLBP;&H!KMt5)2glp>Bo~94$jwK>ZXmx)>GC3I17}AtO8TL^XhKS2@)~ zj1biz&8tixK@nWsPGk^gcCcHs6>PWMaC$1XpmM}141H~H1vDEz!vSy#ekog^rW&&j z4It~TiAILYklM8gbQE?K{wH+zN_+KuuPf@f@lj3mis(tO4fbzi!Ii>H07QaB8+Fb# z!TNmq?|HvxZJ1#?78xI?W(j4!>>bJp{Paz~{MbN4YOjW`cwgBzUd#-~P+Vh#wh0;YEMz7AL|Dy#+H8v_J zFE!xbbmCPa43{4KMdy2LaLIRtntq2KYv^MBy;vhBhv4HR-v3|I*k--QR2(jCwea5g z(n>0i?J5dD<@L2dzP07Gh73(*m`2if90Dx_8zn(<#GcoRNzR|wMX|=f3W4= zN%j{`vd&Du$ztPc-mQn788b$r7|&?kDTDV3(e+n+-mZt!EuS;NDxBB?M6zA0QirCn z3%0AEm&;Y(%co!jK+)C3`u+OzoU)7<#k%X@p&x6f=gn!O3?$(7IKm^p^{H_Jn{){M zQs!``cuW=ppfUPojYmT0qmS4B2x6c5IWC?zFk%z!V@kwv@y|@$$1?lB#Y)}(nc&YK z!nb{V5;hBUu;nFZIAcN}`6-v329(|H7%)q!7Xc0-L3ar{!`t{8W6d z^F`P%Mu1>~WiTfKRqBsI3|MI+f_Yc%s91IU zXQW_qhHDhd^nh>@RETkq$cqX+_rXq&P0gx~2IC3mt=m@(5fqc+bv`6vQ6)O+wyza4 znB#^7h=g_s0>SKo2p}6VE@|Xn4bHGbxD!(HHtraLrczQUMM05L)G;Mzy}pf)x1|9% zBp}nEKJ(hT85#*g2{Pj-)oOSY?h0jz1`LhSz)({zA{avw_B!@eCt~?h)H61o))b_( zov>>Dc5S+gRsJqt%co;YgDcr1dZML7Ri~ozFz;eDgAC?x^4}`=)!?Lo z3Zz2`CX3w7z$lLf&+46IrsMas&1Ri_CC(&(ITR39n@&_|Pv)AQ^Sc`kvK3j{YL^;v z($doM^5^*{w4@+Mj#!|<)ZNlpQIx^|SpS`s6oV>_2~sw^L@OkLrrc0aJ~7D2l=Co` z640%h1ngKEEcJ%S0BbCMJ2?4^%q7bm)Ger4U7XND^ocg)f549BPS#uRAr{^4EqZkF zFw|6^Anc^>1noc|u5YOM;!+s`=J;_ia8oY)Rm#jbvw25tSmKrw@?Hf|VcV`W_z~PP zcPT@`rTI;qT<0Ob=*U9*USlwDII)q+8DRljiYQR*KaB0T06d;}!PcFp&w2UIXJE2) zdG@HF-o%wM%20~zi{EL{c~?GNTGb02E9=Y4H)^d#dhxM{{cSSzTnUp0>i$(~^uS*` z!%kskONTUZ)@J8$rSuaO@Uo7qDv-%_4F zrqsV#w7zt97PrrBoY*FW`fa6?ks(k}Py|C_&VSvytvll9CK84dew8L^Cj4sT7$lB~ zAixAIs|{sD8@2M_>V4IS25G~sNx)5cD@Ww&+4u9B zQn3j$zcV#8CL&y5j4aXl4qw_uB%MZ+33Ra6RZJ0~Nt}sp8a3aNR16?d4tj=PG7Mx@ z2Fa|@{EHYW1|=5m{^KPv4~@nnHb#@-{ZW?xh8qg4Vx8=p;-{VgMUNjD0*A|zgZNdBp|)MX|?C)Kh(MHOZpZW4?yZ=Y~QYGQKh7f zQBBla`wdC8tYMesBUqSlxdufBlP{hodqT3iTcff6IegsRGmnU;fA`J2ZqG)fut*_mhnCKTYdfr&YVvPD z9SyGM7b6J=+=(plkgL`cBVhfM77yI3zZs6+WE1|*=za*7#!QmA%`-y%q)zz7E zVI?johdK-wIs4Xb?e02S48ah=SNU1+%r zPvf}v=_1p+`7uoXjt{ux$EwH6wU_T60QS1%Yw98zf#j&A$OxV zuIfE#r_;wB;vz{&o8uj);{{faZz&tErOg8Z99o~VYG*de^L_V2=O%#wsyY&Q9iv|I zh_`KB-p?+5Cz-ZYUN2lFdBiTeCjovJ`J`>OV?H9DcF}Sq&xdGn=bP*vj?3d5zU~M8 z0UrbL>$k@sfTLbIck-^1m>|~c`J%(eK!hkVz{lf?nBbH0y$Q$7l*q%cfUXmTfDaW> zF46SxcJxUi9<2o-%I??oIY@M2c2r~_27C5IW+B_(f}JPPR1`vE})X0$vGQG|PoQ zUT;6Z0y!V78ZO-jX}X&aT@Sz>lXzkGMIDRA0CK_K7&||fm_ZzRZSN7~7Jqi$$F|qI z+a7it^kzR({|fO1KvK&jZ2Tbdk!!2+%BIz42dZ}rc=AVu$8tY(V8j*{oEzFtOm5Zo zL2q5V#s$s)y$KkX08ATd3urYwgs!k|JQa(^Vq5gpN{FV&b4)5da!dB|VPUZ+fH)^p zlaNwsV4b(2?AD-)Q+_nte#am3b~FSAOCv{dS*gieZB(c@p!7(={l*TYL4}#n^VrU@ zDF%ok00G0=Ow<@gg&d4nUm0@MKr3;QSpYF?r(UH__uExc1lzSm5OlDbp)L;v`On3_ ze9&Tpf6FWkULX6rGnR!f1?*ef%w~S=q-;c`g(1kxe9E9y1sY)kF@P9OQW7v4U0Tv` zMg)vERW5}3$J^6{;G)A;gPCJZyli`B&R(0(kTlYYvB*}UOWj^! zA@m!x%G+U7VLZP;oS$KelS`%|5SEX=RFnSW^g1`}J;tuKOaLlTtGYO_DL!WMgwB2c zHm6pRhjC99Ln+2#PAt30-YN9kcu`^`IeU0*QdWc6N+|ffOaBRC&KV<1`HLpDhYJ&G z07O6Qgad5}Wf=LB3o0f)*4#O>i(eRQ{XNN9jm7cM{MOKEOzw*lF`T}P1wO`8*Azx^ zN}OGLRXO**0<|f@i8cb6BZmAMB!J%Cb$ncdGc#CS9`}cE-c@NME)1CO-)vdOUP-H+ z4Rr|F@x_G}gXYh(Mv#n3H7hQ|2>($`<`W%_r??HZ2}O^&n>F5-#4E21=pPHV#eXL5 z@TH)V$%A5ae~J-#bS*k5TIzx%afaxZbRKpOH`)jP_#3)RW@IFvGP$PKWuB8qhYNR0 z;4Cq68XXVRuD>oft*)CC6dt$?0xi>8>`@gQ%=W7*BkWdnnO8@$Ln;@qQdv z6Qq3GGC z?s<%}RYzNQxu)Ef0yW8BgUvg$c^Smx_FD1vkR9|Z23HXb$Floeh4KD`Oq|0qH_y&=Z}Yqy3y6N9&sbI zY$lE8yJMg^G%V@|{ap{px*^_Gbtao$<>sdmn zE7tO2ss*4!0j4j@UP}MN7k32UH;uJP^Ft?@5MYbM7`2zNV6Om7P%T8;Ok+t+%yxpw z6VUi{o)U`+8!ppMGfLF;-vB*&I{i!0#b_Z5y^u3OXHWpP#mL}~H=(n5U{3O+p}_5I z3Ha!9TScRQ&o3&N&E;{wK;^))5=Ot?UU$JeL9`{dI;|mHBAX!p*P$(+v4tgoD)AQ^ zeg7s9eZJS_K;@&aweejNwh`hA75*C z^q4#)w6o8NxV`1@GMRbQ>7=|xM)vAH5skj-Gh`%_@3_YsKs*HbdmkwJ-Ic7YJL%!d zH0=Q(#ZytwEr&&J3;x}u_e;+Fj!RO&Lvb(V&)V#(je3*K*C*z7AepmzS-|6Se1|u8 z@|fgYeH@@mYwYj_AQqbcmYqHRD#y9vwE53>lHgYvR^XNQ6+G(b6h6{nWC;a^q|o#6 z9=}BlIRK4SyTxXxDev7&^cj3uNtp^=HUFg)E#UEn62{^~g)|(W8RR<2e?;txX;Sf~ zJ4;$0r?>ocVKeo7gRb@A{xbgFy)z9<+DV%)4zSE6CeKO;<^5QaS9%00JQxJ=;=gKT z6W4TkPCUQ%fOWO_hG~2aERu@DV%EM5XWZWPAKwRb2W&y?ao&+l`({0BhjHcs09^T06R5Dw(9=>INk;%En$@VvcY&M4cbor1t2q$PUi(CLNJ~b{7 zxrhwq_t#t;K6p5Wq#wxST>@&4R+5gmlYajOe(_01RuVoPV0WDcPTARxWh%{b9u9$5SXh*W-cxA$$7s zGn~J6*`vJNB;Ve`W~=bHG{thGNjyf*h{#F#%m#KJmfFN~m%;JG)pDnB?g*;e_*$dS z(zNPg-Gw3xH^0t8R)rcZ23F7bU4_{Zo-1*)*Tp4Sg@(>V5j9<~5@(~1w8Hnq-2}Ly zCQpJP9(*DmJC=B@FcVZX*I@hoj+d{;5&olfQLY4GJ$z8?kUK$9RMZ7HBCs~I@6cu_ z(;$#KaTP%60~7I}qKsF5v#w8d8j|Birm&pk!q+aJ;%l;5L6L=|I1^IN_SK~nk^M#< z1OBD^=O?P|c$`FrAn0=lr{AehpDy5o5u~drjbnNa@hilJ%EaKICmESW_catql?Osu zfD)<51_{WlDpM&$5dfi@Vm-wgX&48f%H^*x#Zi1fxyo2zBFZs<3IJ6iXHzW4IE7v; zJ>9Uph}29-me(sZh3Ph z$=ZF|Ya{yDKFL_{vM_@Q4c3)mEn^7~lLP;)%V$zLU5T&sGwVn1%9Sq;#R!v_8P|8V zCBj5+*3OD<)4=PwWb=M;v5_5lU?m`q{`HZQ^(~UHSE4xG9f!8>_gLNJF`Wn(dn%?7 zt*5efw6o4++oGmT;ga7Ct|*R#Ez~rKvH1DIumrBfbeP7?H!EupW=($Y*1)&pM;X=VBlVW;?O;B=-;>yO)xTg-_+ zrAHZ2p5z+Q0E=|Cdup z18jYJV#02ZZ@tZFW6+It@+4a~Gk5jK&w(j6&+~3c0Zp*P!Emz>{k2ZB+|=dCTmmU3 z_OffIp7ik?b!#W4+TeD#jxtW^d=J5Kpj`w8FsF`f@Oa$*@yz(~Ts!pvO~C<|(_YKUrycS4GK#PcyMe4Pz1dUws5fri2z z^(ZnWusv%g<2bok>2(c>sR|zyk`w#eSl!`xN_a$;C2(d~(-!55S=D}+iXSI%=ovDF zxl@)J@4x-wo5RU9*Ae(>VLiHd)@4e_>!!>C5ExUaceEbRws&v>I_oA%aQ;hMEpRwq z`0@cj@2AamorTb}&U;qa57KWQ?BGW9{P&4={ilUFLC_ktxbV-4HM)y=rm*SPz6Olr z!M~Ug8?y=4Eaqi8vxN+sP?*RGCH;Cyh)vu}W%WlnxVE*wC?Yh_l;Q3*4$V?5)S9_s zK~mA54Ke~kD`^x?5LCO1hQSn9 zyeN={gn&a27=(>aovp=-GmIQ>D$;=2Z>c(3fIY%n`ea9DmebPiZomH*pOv4OuB^rW zye3ww4U{bwn6@+?%Uk!ek*D^T+8|(MxO-0(D@^bC6MFvh2-0nrlN)W1E z%7?ic3Bzt>ijak%9mpq{HlG*+^@S?bj9uX*QZk`QHMz>ltN`P8Vi6Cp zz#u-xM5%}Uk_oSmO%-Hw=rW1MZ`-r0x$%HR66T{Ngn=|OGvoJnN9KvUTeFM~R=-n# zQxJPd#2E%R5rzANE-6R@m;6-#`QDqm>|P!hP7O0mo^kr`v|EKQxe^us&^7nkXv_tLP2NdC#$*=DVYuQwNQ-cr=}jIp9K|4LAFp8xL36~A@NXyO&GoHzBM=^J;#nf((vkmO8Uyv?va`ikWlhqHB;`k-0W?|$9!QR50w9I^@B>B>u$&xnFE}Z#5ObL4KpGioVCS}Add`Bp? z8pF`W7>_{{7Ng0vX&>%GmDSz4{*G2~3i)_acbvDnOaLxf`_C*A}auN;Zvhw_b}ZwRGonanspjF@K&NHt%3s*jFvzS9=-D>xxX zA@0ndHM$BYfShQ=5N2_PYB7FuS(WvgXEp3CXOSK76{*sP^$=p~Z&RAYu$SSmnd>h= zVdpSnZ|Rl88U4;lx$8v0a5+(|nod;4N7t#dZPLHYn%h|r%0wGvQ13*3X`6#pf>l+m ze6XJG(%Nh&rKL}d`Gt9r?WkngyBSp}M1BcJo85B(S@YR-i99^jiiCEqD}R3mph$A3 z9l&Igs`_=L7SO!nf@A~w>XSX)>mxKDIuH?6o|Czn76WxAu6s4Sv4b^e%vMh$BNB7#`6#xtYcMF1$g))`$}z7m-MG=zV^}flgM65Yi&bY> zGaV`QYY+8$Y@r_DsaBh@d(|_G(y?}&4IXtMfHxP>_o|$v*qL|*A;O$vYAOvmO$^ZM zx!I(ilYhcTDb98b8z1g;o1CXsmSUy@QdiH4jgW8S; zU-huEh#P^=n2_WMNp-Z<1p59+gG>=AJnIp}pnckTL{`klcrodU>-^1$zJ!e=n5 z&g#i&%y#V+8k9(RE>h+tP^N81KeIorbrn~eok|vB2ug~j(WiV0cZ1;Db*Fcg1={?d zmu&$6G1HjvjEPb|WI_%Qc;18JMM}1j^k#o=BGz8ks{c-6D*R?30{hjh0=(8)n9M4C zzn~V#_De=Hu%+)hC(8%>PON z$e82(cTuhPkmliQsJsQh==gVzoo1Ka3GBI9GH81qk%747N17;CX)$(p9nq#8_+Gqt ztTjPL?iIG5HCi{}u2HT#t$9H3GdkVi?Y-+=ynhgNU*!JpTv3eOnw7GK6pXg_@>d%J zzfFQ6;QfNK%wLOq@AIO$G)gEkA#iqtis*}P$OnAHVLYUu$;Y*>jSmFegi&DTI6phv zUP82Wx$cMja0geL_4VBW!%|q>oT_Z;Fnyd-q4^u{Z=93f-|J&kIKSnQLuIX`1hRqB zL?0JQvYJUXuZG(L9)gnb(Q#I%PVL@A>R?_TQ)SQ}4!T_)vK9?^B@hLEcGR=R?Wm}J zxCx_iu9-ntRn9FkYe$VA>;JAJ{!v<7`+up_e|!ph0H!qjED|9QnLLB+m+Bx-Jy#+| z)71;eW;(X{SBw*MMsZ9l&{;}ixv;SP@D6-{OcH7N=XW-5t-O_bO})`pUpNVI!-x~D z1jNfqK6w#^pKv;k%%qIoc_SrB&9Rq2@^1zXkevKT&x&w}eUFZhb{64hqj8SQq#Wi^ zhm)d|?eamU8NXzIgu{BxDvW7fJHk<#;lD| zR(mpXI?rUG$Uxr$fJ^J4yEzNW-&G!*@Rrvs2d8AG|K($lX3{LeRh4?ulXjfMRL7%5 zq|O$wo6ymV>uE|1lxfV0NN`eLA%iFbftbs9bEtbL^p$7g31g(-x8rZ$DQ44NPIkT9}7MFkj!9RrmaBoglRpf3^Xy9 zCvl+|pDsh|o`ja*g+dj4f0}m$D_=(TgE5b_Snbm(5`l+>unLqS%)yE?#C@z2g+AM@ zkwUBJS>blm@#JP@rFOE_Q9>8G>$T{U%u$8 zJQxzdCGTN_M?JeV)Y>$eQg-TPNsa2sr@TIgFKZ3SvZ&!E6$P#;`DY16fwa!R!#Z_sl3 z8t+o4r$GV(;`jU<0f0j@T;+eQtZ7$IT74sEDPT`a18Tpr`z$DcBun~2(=@N8U$=7` zu9>#=Os?RP%0Xx(mbZgPu4u~Djp#UA!|qD>m9D==cg&eq9e(_R@V-VJae8w`qVo0)pp1SfyPH-HONG7zDz`U3b#BdWx4AsB(LY_~Nl zETngQL7yU@cJ{OfwxdigQ){{L`uNSO$HS}5TPFx*>F7EZ+z(F{C(a{$7Ix(+ zXzo&^+us7o19JhHr~4z7NBjFIkU_MA>TXwCSCvjphzOWdeXlgf>%EpXHxc6xwz3Zi zAm(D@ZQIWy$MKY30Zr6gdCL&024kC5^r`u5sl&71qMCnqIr(F^`jd+>*2_y&X|8&; zmgr4hG)u?bX*8>k%;2DzQwA z$z1V|$e!;H1up?zudmT0Lvk3;(2V}?jYJ|ImtpD7gNCGZGE#gu8G8oa?`3-`LT}-$ ze!Klk`a^`AE}seeE3=oTIK!rZfNh8Bm%m5vhcxvUD)w*b&HCWaLry5F7AU;-+RdgX zJCyD2C}@+E63~-ML*YlPp4;#3tlo3FCyc>p$NLMf-6|J1_rl7G*I!JT4sazT zy6yEAy{&7}8+^L(uodv}3_g1}U*QxH(PzR-XVP)*g~iu%8o*66Ypm+9nkzAQ-Ni50 zs^-~xzbh5}-e|qh6(Eq#%(=3Gjg2h|vAu#U4=$7ZJE7S6KGO^3kS}KG{r?p} zR|QmuzcR)m$lLV7Ceo-$Sq9HHs)1|+zv$28xQ0SH$FV(2t&_(HP&c4LpC zFcZsWl%*nn08ELkHio}ZNt=?12G$~2&ywW66&tHGws}lsRsMluniPl|(_Ys)hr=7u zCdUrM!{G9yO6qs?ZW;~BgdX8@R(B_WH9E!=ub^bDKw6uy;E1G%W3PbYrp8&$O5l_R ztp!tJ$jpPtF)UA6l#kMwLgt1{;>A*|%jnw^NF>$?Xv_Vh}M zjI$t{Vk(M9{ajtm0@WUrWrUF2jkgF_Qvbe=#N0jgdfcgU2S|<^?^!cPc#IJ%?!5cQ zN;*$C6JT;0Z@o_SrLc!MaXpxj?rP*WH}M%|Br z@pZl4*j?|z@&cMNiEd(8_1-pAUG34j*~M^XpW9*$Ef1^r>4YD$jy|i^uud5hxO17W z^W&eT7FXta6Vn;ZCZ#Hj&}2~jDBf)nGX>cw3H%^pp9d60*&fQC$b6Lw3})Z%uqyr%7tsZEXrZ@9V>E z$(tXU1m6>J*6u7$2hVyyD6UkCWHL*3-wtA&QeVFkN5_hbjh-*ok372Tu54&(7<~QY zA$vZLa_CKhp9N7qN?Ry9JQq=ZLWs={%%2@rl^#2+RMZYom3ZGzis(Fz>v;|a3r?I= zrhR5zTw18$$T9`kuJ$?mqH1r#xs{-nA`{GGYT0sP%>qV85REvSmdXR%OU4uEFDRP{ z$Smzd!U;{LmQK?!y0db+z`u*V6l75&F)+!uH_48jNYGU4D(5)LhN!G6{kC|+e(36; zU_N$THMQL8o_Ge27a%q%nN&4*r&eUoSjMjNax4k7rYD&~B@-H67Mm)LzlQHK&}xxp zVSfUt1IL%f0(|`#U{&IKO9AiL+im~}fL0HX0N||3lam>t7frIN7gqFFY}Q`6lpCVW zC;|BkG*x=(h&4Ele0}2gW7J#^xGBC;fwh@y^L?cN0LHAhU52bwZO5P#&b3UxBPQ}b+F$jh1$`UnTFOa-v9mBDSb|aT4|L z7J0a(-rZmCubSSm6q5o;Gw^S9`)c^eLIF76=-exKxe~hi#fZnGe-FXaj)vzEY-K^( z5%~b{fWAz;7FVe`4%yVCgpRwnGOYmd2`R&%O+Z%Ez=hhB6Wrz6*VB58>=(Y8N!}?=uW?7U( z*=>4!1-s~fi|lzwfa-cKGO z`}slV?BQ2^fH-9lq5|3Z_Rd`(&c+^odp^zC>W_~W@8O*0pIbJ;n>KmgyNPp?zPT%i zk~x{gTlF?R#9=v{>S7xyFXAu?Ee;)bH&m#f0p8w+0I^08d9W=DJV5T!_shZ6_fGz_ z7pLw$w2SxM{M-aNoq!yb$tj`R@%Bw{RV)!N4RbcHga2WsMc2pMm4W9@nCRPy3Ub(6 ziPvM7sF08l1mJr7^L#E_*BrXv#thzXHaxaEZCC1w{4Q1-^Pk2ok{r;7e|JBhmZO5# z+dZmvE^G{5R>eo2u~meOG+X}lA?uDjL!%2h_M<|k6jHVHpUPDHPTRNM?Ca>VCuj_+ zb(=3w%d7oQiqk<4tq?e0vv0qEK;qleRKVuiTKm?NGDgR3?p4QGRlELLvfyP4G~g8M zEs*;Tt@m>-{`}?iga4u}z|Xwo6HTmIe}zo3s8LJR$wS51%y7ij#f4c+V}QE-|Fj8{ z!T(poaMk)ujQ$G@73By)vKoCcABUl(4xSYhOc~Bk0Dur4ufCCLNO_1UNsWCF*l-=J zK>rm8oIkCP)MmQl^3z3-qWQX*QJb;-8yHAQv4?_ypwmd4)hsLp*p{p(sEoogBUZB- zs)Mm0{xqE#x;^+zmug;w`Bgr%Ljo^tfWXFcAIL?>iUS2q)NgrQZohimNtBG>w_1|3 zp!flUUF_OCR&3)`nKF+>7|jJ(kzF^7DNuGPXsly0LKOd5D2uh6yr({3TOy6=VjLah zc;hxOm$v7~c++?g>DrsikPgwwutUYh@Nx8J#PFTkkNJ2{F%3<6v(03VkdRF`ndjqhMI=D^%|K1A~ED~6-Ek)Cw6b!wR{dn!E&(j@axE-@+PFIyVj z%0-OjeJMBdCcMY4qXo&Sv4h<&Z;N?lD`cuext?@mPEvf&ca%fYG6FBpnxY@)PD7u+ zl`pjk`0UaRAGvgC5oK&SAS%e~RB1@xpL;njgj2h;2fA*=%h}MUrpY^E{!Ki3>BEvh zC~m-yARi1-fRC*BJ~B5<<|XTTa>2=Hn|;}(pIj`LIX<`efD`3?>S8Q6qnU7uO>GFOUG>2K;W$V z&vjJJ!j|@8{W(@DK~j?*wZv~&XEs{q4<4)(}qiMi12Po{Z2${|>~g?&Z= z^QbQ`W4h2I*xjBs^G|hSBoW?YsJ&LMq%p;@be-|qs2g2L^p(dF8Tv{}*e9o3> z#5xz~wnjT9=3@gU`u9J3`gL5nG9hQ!7WG!68Wx0yITa2I0Q3-R{*<@7ok}_ffh1qh zExF!K2=p^fNj7WzP2JZ@I9a@O1+=p@54P+x1kA)u2v7x^?ZjXvgV^aJ5+*KW7V#ef zsfohD?1;CzzqVm}2-6zNzM5{N^#%W}pCkY*oHgboODriJ#&IeC?fE)rURvrM9!})8 zNPS5#O9aj%0 zz)<$-O1u7>T&+7Gum-Lu*(5BHLlhtE?RJ%yd-dEytMmf#qg-q5z6tA(6CqC?0rvcN z{NQ^$ccRF$GJ!di^LiRx9w&5Y3V1vq5q(`j@Af}}W+i&g9Xq)4+&&0+ADY^F-U#rW ziV*R;1usGM;XAzIiy20$4aRU2AJcr=*oQWAdFtKyGBy=3H#3xad(K+%bk;pwyvSZjSUjgp64)oNK`z7h!8~HQsuKdQd&>rJ9czC z5#u2hs#i5lbudhj=XBr7+THS;Kpnv@CBZdif)I&M8Sw8!+L4cnlbT`8ohxHndb0YlyxQDOrS#abPQ@hmt4nE5D(3g=JdVGA$ z_1Jt`cbR&7Uh3|G%szY$c)ivnYE!fJ^%csV$n)6r8Y1yn&*67TQG=8YeI9or@&n$V zAh??c*|B!sscC7Y>jYfy4&+0ase#u)s=>$e62Nicn-(e>8jX+O^Ks!v>EwZe!Sifo z^XBTp0=R^?(`vKBOI=;Pu&~g4hOxTC`F_P>YJ42fb8|4p+VQV1FE8)p_+@t-m3^EBZ8|@~NWBa^_ca=Y<_I9+M-n#lz*sTC>A{B-`U+6&%r_sBoCt z^;F9#`q24JaOlqqOK3P@yu1}gK$dH6(hb%}C&pKs4Vtt6X;@DGKl}gFy<7yg9S}9& zF<+1w_hB00aD+D{FREcd62lqH>f{J5wLX-bt)v>WY&!W8wCOGUDiIrc^Y zWEVTL%v@M9QrN9aQVw(E$_OYVm9u2AIrf7&2MaPqVup)iqL%rO^gI04%41x%4du3b z#8s*MCiyJVOq>9_@=*AR6ymEv3H%a_W@~uRRKJ{C4@-!RTxiX3)ygtK|7P1NZ;zOB zBG3EbI0ze}kzhkk6{-J;+nAl}{cz>}9pQu{tDsH6XsR+q%(QQ@BvjGL0RMhxOM**T zNoWyXL1_Zw^?d^T=ElT0QcP6l*A&S<$l-Tq`2D2cnWx;IR@`j2=D8asGXU;!uS}4b zV&#-r8~xSO3LT=@_cel~$!u=2k=2%Y;;bV5tPjfkj6c)s7LBkZA|RxvNaK4hiPh3b zks8U<2GZaI29)QFiBsI$mtF)oB- z+A^kRvV$2=EMFW9M9I(2&WBCcFE>Bq(ih(?56f=DJK>limE9>as1J`{k*b2?E(y=h zF3NolnzSr2w5x|7Xw{sZC-{yQ8eRyv4E?X8B zR7dRpS*V)zDIe`r+{;~asP@RK(HocSQ+{3!$lzW`#pVL`?97NNF{QZuS#9HOfI1pK zc2)J3_gv{|>Ah9hT*@ygYxgi{CQPVb)b#H@^K$%a!K zjZ`aLGn>_E9((Y)mzp5=ROa!PH5mSAz)LfmeQ$q;LlfNLss#TXuG%GbcnNO={3I|z zA^cUU5n-}mf@}Q+P><=tzZckvw?*T|lJ0Zi)VTP+xO&T=w)?PII0P*YrMPRMP`tPl zQoPXO?(QzZ-6<5eAT3bbio3fP0>ueZ2=30w{hWE`edpvu5+)y#4E)*OwY%4@uASQq zUjFJxWjevyU!FX0dY5FD1yAXJh`G;F zqVhGXDnd9~0PO7n@g)tUngF=nND1S8#Hg`M*!(J;8z(wC0j{vQ+ zD}VZs8eGTFBrV%DC+g0V3b*x)k?jPL{W!*UD!}s=19a8n!Rw^sBGRh;c&qDid;LSB zqffifVX&{`?IC~O^SJ=0?}P99`SlIGqUgV0VS3AYVczZ=QFH}5p|5f#o75b z+)4}LJ-ReZPDeQSf&;L6-?b4vL@jv!4`x3!P`vNAU&lb>zp;i8g-Snepykkb9KMq1 zIP$f6FY&VOcz6AyyoqnDu&?^K1%3!MNOZVE;zM-HC=`65wVkwKb9P4H$fX zmfrQaqhpnuTH$uo01Y^H%WFFuq|mC=y-Kb2+i}Z#Sm_ivm-5>aS@*eV zTSpksuDh=O?PfbY_p^xCT1`Q+9b5MYDV+F@BB?wV;|12d$2giu>z|#~!CSpnT!xs^^}n;x&of|Bwp^S z1E1iPvhR0YSfgW^8fg zr|+{O0ExVVl$Mz!qghds@~Q?3iZ-Vj{p<_~^_y;?Js_!bqpx49e)*M$yL)O(7@wGkS&486 zsW;o$$3YY03ccctw@vnAbp*6A>dY*11JYu-I?${b?gTTHfq;M8vpNG|fcPl#->;H1 zBuyxxrgdf;A&AV}{r#HV2i=(k#BR3w2U#`4+>{R`lcZW?#k7w0_-_0OnH$yd zPbU0@(JQb+rCbSLFr&kgW`kyI5mZc&i&qH3`KDxODA@gd9{k@vCYuHa!&M|6={I*tC$fzL(dLx(Sz7!5SOGRB1WoyF$|c5WH5Ex6 z%Pq!pbFT+ft?=h5mm#DyJ8_YQMB4PZ%1Ot+ls-e*>Q_7b^ZBjV7ZflkxJ={Z3y*xS z-P2<_+`#l?0%dQw*tanQHa-{rm@LtoXGsVD8pbS^Hd zCR>CAm?B7UJuNSaO!30On;}2^IWuw~85xUnGeXvS0DyuW?N-i!O9ek2`9Y|{K*(~q zDIG%TXQm}9Ghk4oSU3hvCeZTlYA5j#_wMSLCIm2jy@3PNmvu(Ee z{)aE3J-;e7Hj`&hrupDa%zN3Se)R&OYsr&M;M`;wv$j}tl#_=+_LQzQYx@D()oT$E z(?PbRL+6Uz-bRPzc5RhW2f=-ISdPn#$nTAUwv!qTf}yjS@bL0fp=2Lt_+9=k#yQ5as@qVdA9#<}-W9if;2+H5(PYM7mB=m)>MOgU@;&lD$rnr7b zfpcrlPSH{@( z6!{~{x|zaz&U>#LCT()G$!gulLF*4NN-|_15pV@cq!T%K zC@86Ua3nn>j}7mTrP9mG=~imo^}&_yeo08;9n6aGP_k%jzg(f~!%C$3=S~BjKtzJC zfI4Y@Pu@>LNta3t+un73PxO#_sDO5yEu8pUSbLu#{5H1K`ZAs;&1YCN!pGb7RRQa= z>t~(c2zywnec(GM&Aa_`lOKa31FtSLzDWr31)j-D_`+l*ykJ*(ciqt?5S;jFM7`ch zbE`nLk=x{*lkQ#KyR^JOdE_bv+{tVS;ktSP-tQGEawu--5o_0zUANzSPyG6_*A^Jh z65nmN`R+Qe4Xdd%KZlbT5l3ty7+71_EC8^@v6=YF_=X{6aB^o2~+TWVCdvu6809NG04Y>kW3UhINsn%HN zyjSQj)C)L9wLCZ4Ql}x!LByTm0XiQL<*I)BJIJ9I#}7LO2=dnT0=v0B=db#a&5mc( zX^#Mn%aRV(a}y-$q-F0v?sYFemYJD3uHaE`{eEG17z424I>v!M?Fee$jG#c2ecf#* zs|3I()^Gomh%Ch@u zX*cK^!M8f}Mc@FO5kS{u>ha^7|DoACt*Z8iDe$my|EBp4WsswEZ4~OC^2$UDjPmj8>P+y zel;|5e3X>T=TBlT`kkU`SNVHZH<_Nk(iBG$GS6 zU$N+w^ep$+(ME?c)SZ$q^9+!qliUCw1~+d6dTqzeAN2Iwf7a32Y+i8HcbMn$@S1I;KfA3G`5QL@G#ySEmOOpr{eL9HmYhYm%CNxSdM7o_k zem84~;`=Wxv$*Hx@7~-5L=1#sfSCA+KYW*>cvjSQkn7(I4-aO!e+|UCVXz6HM0VirqcTg;Pg<9;DiO1saJPDHo~ED>$rUwGnfkIF0?LunZ$p z&{jgDPA=4Z_r`8u{@ns((QSNN#+Qc*pNmWOTS8;Q=gUi6mcKlnd;#{CZ++g=%G zbOh0nOWjI3<`?hoYQER$2auVe5E40~!7kKfOI&|2)UyokkyHuxE6i(P8cZEUm&pA2 zO(91^M2|VyVn~TZ#xoeU5fP02hFjAM9+1yIhFF{0+J7re98acCx}(ZrG;GB~w&N?6 z(P*)U)uJGtZmp<@K_t&$t4O~sdYS{`vB?mf$)r{7NP+}3ok&pMe>?7h;Oym1^;B%z z8V(?Q0<0t#347{es8i*r{DHeIE58Kx!EK7lt6wG1l8Gx11T^fI&Rg{$MyI&E+fgAd zefTJhMfBlPqzdxT3$lz(797-JZ91)umFp+T3@J3Ee<34?0~4rU$ci%DIF6ehWFD~* zG>lDWS7%thYgsQv8mvbqA^stI!l~WVOtw{^cfy=rvns_uAm%fl(4y7v8{1~zEHM)D z)XLXl{=z@Sw&4?*2PGCIkz67u+Y=r`1<@(+cw5a%AD^gJHx&3uvoUVZF7R3z0)WyjP z?G~@c`xjR(f8rNvR&qro!1NQNmU2A)YBpJr#rY_-D8&Ccz^0>B1&M!EX5++|yhs0K z=oR&kZ_HazYi?%_zgax7=0e)6Rhc$O2K>?cPi?{^ep93wNiV;(_L`__f&YxE|4x|5 zYxqBQ6_tqNKru~NEM-*+3m!-WT1}4h0YDjy?9O814@kb4KI||s?TawEJ;*ikzOnqJ zEP2RzJU9Mqi&#B8@H)o&rmIDR0q=(o*ohkOv=UeA^3}rAr@oD^`tdNC6#M~apwXak zeGiX+M>2fhv25%hf`Q6NGP~hq*L%R+J&%1uQEczM&?X`rjI}}8^1ch`@DysjWWpt_ zCg%Hjf*Z0gIfgbSGX@a{H+wxrXv?zTdvF?Xw_Md?+i5RPSq6>+-TSvl<4qZh#o&M% zV{M7lp%TL_Wf?7PqjSPfE6`l-BJbU@oaFRYm?FR%>Ohm7NuHNUesWAD=xP2^;uyGW zAmPVDt-_w@6ec46a6{927w_bM6DiPf;IaOEK=S-x^a8ubdOzubf3-phr|^G4e>vQD&|CN3DQd(0 zd_X9sa-4Oy$tjaH1u(lUaS}W6pok0@a>_pGd~gJ4*P0GoL5%`;^+A5?4{J9F&C}J= zau)$&f_6t2yjKXK_qhZilJ@uaZ*Q9$8Lc~=J0m2^M&4SmcLo&|)rtR!?^Npsf~^I= zJl#NT8!Gjh4BaO90f{5*k2C8{PU|OsSnHLZ!*3iOd%YmbjlRM;zc5@i{>cUPyu6&p zo@kZURH;}fay0x=RV*p}w4i5OT9l^yzjtaxDB^octltTPg4}RHIWE923JOJu1>b`? zQ&ngAKCj&U_Qum^d6fG2E`QjnhAD6lMoT6c$Jun^O?>S`=|sFkFlT7D zmV&&>yumBlR~W zvO@LL*Ven_a#^~bAL|(#QE^G?a$iG5qhUo zjE-mJL3(}on{rJ;mTeg=JOLa>OsrRgBPe?t^KaK?gm{IL4u=;l8E2BzAqOoifnN@4HrHRTvx4VP%sy*B-&M)rX>_IMigZDo3ZY{u(k^SeA=gOfKkesaJqtWqk z%h;j=Nv(7TP|SdW=e=`r$xwoKrcz{zgOIbLh0E6ItFB`@E=RI}RRN`1zlqtUGaa<{ z4hC^Ch*?^LZ8Lo1-^`L~gZ>54*NryJUx`x;JOW>styIw>jI)SE?^cxO5_}E2e*%FK z`B9Wmx{%;tq^YyN3`uz%&iR^N(L~&hL2RTzd}LRHDV_;Q1=a7#^kgaJ4RZa10Ndc# zv7quRa9O1q31$4C>4530D5fnJ-sDUOwPMkCbJCBMrkTYiTzyeK5IEa<<3y`owYqHr ze0#V4=EA|T)k0B)5M?l&G zbX*>y`0s-;L{{UaP*N)ed3tHm5K)#d!Kw<}_(0+1?`)?^bLt9o8$c;KRfH-JEJX>j zA=h^%d)p(l*IOzCagRWYfb%oVE%&?+X$)SHO=YtxBppFqpRtsxgQ}Tk)2L zTFWgj2kjP#b|udl92FxAS;HKIlCmU((Jg3wOpN(tr<(R?tikiVYC3<>4(^~Pe^0iT zS!FmVw5QL?&o3;c;5w;Q@_qOVfw$@>GQ0Zm=c-B8A+l2FknL5L>ZelAlydm-Y&m80f11c(F=~J0pLfXU!2@3Zi|U z;~#*o7PY-MziZ9&@bR$TJ`hmBgDsWZ96q}Fj0Rhi-f9M+f8IbE2PY=~hHZ?L0$2;Uz!`G%esF{8K1n)$LtTj&9}> zH^4;Q{SEs`kU&>dknxRmye!m5O)^?&2 zMAshH!U$dGCxYVpGXVH%gxf)X9y6Q8JS@fiI*2+`z60e$%)Cyzjr`9WJt*F{9At6a zh}XT&miqv>yuu53Ny=@51cH~R0{>>TP3MuJ36&y_aTH+&?Ss!_2!Z@@a!4yX{mdIs~czp<(SlI3V;^K z1H3Jl7am^RBG+AX+-`UyXnY^;synPtn|u}h?sn1x|4Gvb!`Tg{Ol@rs{>}UVoboIk zB4)g*fLh<1W8RVb&A!Myzw;3W*@P4Yrm2hG==*^`fBraSR5-1*-;GBn!0gvMsQ~ZW z4(m>RkA(#L zCWwPwe#m0{3mCCzGYXjhd6K4X zHWuVDxJa>f8nN(gD=h%|9^t^fk2QKM^cnpRd6ylU8on;t$;Qx!H{{yES4eqLe zcj5&IXk+`TnO`>Z3jFM9@Vv7cR#K)&cs8-T| z$y*?IdJGZ~=7sN#nD1m(d<1?g?jEaiM-n+(k(4?LM$pH6?Dr`t!6}Ungh?mpz4$yB zqdddi&8K{@;4tfWB%14Sbgwvf|0mO z&1ZA*rv`!VoD30P%hdHbM^HJ_$G-BilBU2NH-v&uXnE8YRTXF@^4_5?bYj=2ha=s$#DAle32;C2m9? z4C*ISK<$?&B=`>G3Bv%SsOocx$pllNscpAbZLD0ici#|>sQ=tW`;ep>_pwOVu+~&Z zc-|6=dj)FsD%nM*KelCMpW2Gh*eS;}#6y}}2Z}A-0ghC4n;K~*e2B6ONrjM(y^H*Qo%tAH=n>aQ}?ZY=BS-=$Z)gWBfKEG9@l5YF^#i%s=RYia56XtHUrHR$^C zASt*Z4Who&$RVoFGzJqzpfG;I1ds}#!Viw*t!AgFh1K1H3uqH0^HV^yXhDb;^q%JP zCrP#{7j)Ai)hYL4Q&HWD`ItLbKH_gO4)nA|M5R$SBeXSYNeYdkPE&FNq(PO1q(R3= z*6d$L_gw2=pMlCW%Y6cZex5HqPS2(W8S4^|d3T=gTOosvHv~G8P`BD4WK1}@G zy0k(+@guPMqpe6f-Xm+RP zMwha?UDpkhVu75msG^q%eWiD6bgE*!#MA&nG5-mT)`G7rBG^t6IEru`@`Vp9F_E1< zg8ZWTFIwo6Mjm?tlNHI8MNk@5lOwqWJG-he>hp8wBxf-1GagIC-JQznUAX0mN3+wM zucs~H<1p1p*RjY=xXm^Bw!n=^vl&C1(R9Vzw{OgH+$8C>3BQR8^7Cp{Hd*n|5zrNS z*Tr)i5Qk|f+-dWvx*e38)rQfXL#8ks`olKzpf$LR}MkfPV=mXgK~d5}Mj&-97eK_fdNlitdh4WsgS zS`wde_ov|3f`AlXPuU5}5m5T$wZcGhqetmRoa=s)3{aHsd=1X|abYUQ+j7anb#%h_ zX06H4VpfEUCa%_;=jyU5sWu5F9h=q-#Fa&9-tnigRyTxp z>wU8UNuG*9U2@EM-W>aByXxU#Ov{epQ-e>}jm}235d8(HfOW(KPIEgvL`!)KI4$bB zk5%!zzi{e2MtkzKci(QYYOK_06VDqnbY0ptcQwhKId%)dZ4*K}~+Q^pr20SMxBtNeQ@`p~+|l-LcWo%RgDS#fq1xHJt<^t3zE zU97=@lF1VQEvstxROZu(3`DM)*i^7oy4-U(Xe@=UYQ*Wk*C6?Jh| z+I25}cg{Bm$a64i+XcSI*6&`&NlKv87#>Nd-lI%;sO*{9e&;4vPe8%T%6SNauKZ0 z6T6co0f2p6-q?$N1@?(`N{U}VAhk%(V~wz0u5cu59cC&;X0-^DRJ(9+PrPoS7T%Rx+;mrXZe-~2ULU%=n z4s}N@HYl?Nx%hqyrv1J?T5mDm7h)W5Ijhyk&D?w={gszHJ-b4yytghWk?w6NeXaHf z5iPd)kZzJR`R_8yIT$~U-fp)(pcfAg-W>YORJIih{gn{aW=;DM-9ITU8==WwzOZw+ zZSJIEwc&#t`{3%f1c6NYw|TkHDd&)W_9{Y0yGPIuzW0&L->Be+$NYkDii4P9)9{s* zg-R6*;Vt;2jzDtmklzR5CYF++Xyrrslkv|k(+9WzER3l38ZN-2j}=*bXgl(+__ zErPLO%lb@nAW?xaK-a14j z6?$Sm);}xTCSn$&wozyCAN$urV@e^%&zUVYd_Ju|LXl%j=8i_NfhiX|?!r113k*jy zwne6&=#{vp%8Oo?#;8Su3U_qnNsHxR-*Gy2X}czcHU$!DtosroWv>8KR;|^3tZD%H;*rmX3DIE>U;| zo1~6a?YKBz%@JFhsuMed4PN?9PM%?KG_V6$8XUvCVnXL;U@roy%#x2xI8Ahx?i<3! zF$`EmFn~DI6K|HXt-|HBr!d`ivl&KJvfqTROBb;Lx9`_)KXGhERLuit%hamNsER5Aevz&kJvR$0;8%&CvUn3?Q+~J5( z`@wcktn1$$nsK_tfs;N8evk{DX201d3BlH#)!GE*o>Qf|fYS}6qCeA2*?o_X)73OG zD}AN4NZ>yq5nB_oKd02aw|W!Aj`ZPY==YVKh%N}X{~0XbFJi;`P(8kdi{QimJp}+aw03DT8m3m zXP-lA?Y%E$Q05{YlH*%|2-P^j2R95D^w+l&H1Q`YjzrDVeXyOV*2oy{s{hsTi4%u<)e(@#+>b5MeS zvwz5ekCQjj46IZHSCJ?LUg9t6m74O5-^nXq2h;yMIG%GNIE|L2Y2WXl(Wl*sigMnW zht?!BQVX}WCecmzKFyYh-*>V!(%{U&2znYTWeP?6x6U>{De@hH`o-Fe^nZJoK8r>? zeBc+FfkN>%hrpXJJ#~j9UZPEBvlG}ZVB5l`E*f$Hn<%aiAO1=R#-Sh@(BTyCn+21U z4tA=R&li%7@FjOt_Ys|gqz7OL5DJ$dpD34LyQ9xZ)A4h_Vr|>Ey_dU9v$9v^*=P@s zz5<5LW$>G=Mj=MY1lYgekDLrpvAc#Qx4lWN_N_PMIn{<8VAx>1!~fihZGhc~=zvqF zmusi#u<}4N;d)x|g-L7GvLBIED)e&V^gn~@Py!Xr%k2=2|K-=IiiD-=#mHaqQSQH1?=9eGsCTMj27O|18LC9o zBAg(Hzyv$>Zp?!~ITVnSH;Unq;{bZvLdiQs;aj03TWQ_W(i3`PwSG$v{;t%ow*<6= z_{g-3O}hjIs*n@~^mjZ7QO4R40r{2PTpXeMWl%y7F>j#iPf}w>;+ZtCDkeb^_tXuk zSp=8+0;`o$5`#1S~AVRs|QjQqs%b^PQ3Va}jDTdVtRMCYtuwPYVvIKJC`6 z5qI=ZVLB85W~P)Jh=DP+N2gIY(=C?!e9R-yh1q}xBPf`DBZ^W8iPr2V5faZJzMNOo z3F?UVxSPR{$6Oj!G{|abNO3@+MgKK0y;>U=8}E3@pxV1uJ4})+?U%-ZkK2NqLCL|f z&-0xey)EQ$rLl^6QN-{4N|zNSs^tv zAcr3@Sz&K@YqP36@Jke9>i3@+M6G@05iV6Y@GIL)#Fn-ZMJ-1DdyCJbttnNi5LJZ| z8D!@W3>ev*_p#H9?Y`dHhr82nIDH2P2lOG0jUPZcnVGo2z}tA}{&*lx%T?!U;04b8 zO0FiBB#rCEV$}5EnqP6&)QnBXU+hWgeLH6JJ*&;k`bijs2 z^TwYRC)BrTJ+h}r2Wa}j7{2<=mkU$3UIBDCHRQB-H8{qk#>hd?#dwek4bbNT=DM{w ztI_e*sy#4s(ZiTtvet5^>=*m^;Zlp^-7LAvym#Sil|yku0|{&q*^S-U?$J=4kf*uR z(YJ}(-3Ksgc3Ykb3v4z-05sDE^PHaiDY@>=BqO-&7TEBOkF7TcpjPl8&=Upm;vnSC zDA4VQMLaTYKd>ZKH?r9MW)+|Xko@r-Twf}7S#34t{Ocqloa<3doind48YE(cjqm>T zLPlw1#My)1z@AFb4Dh8q6?SI62q2(d^E{>LI)?_H&!~hS8F^o)KOsxEiqZcm+Zhxl z$?!LN*%+VpUbPVQgBh34vPJ@cpk zb~qYl2Su>0n*$~!S64Uy#0L1k>C;n*Cm7W5=3W2?8;1btKu;bBSUh{I|GS}#qT;li zMJ9Ta7YNoaQ(HMe)MON{lT_dWOytkM1zi4US`T;_6L9qO4MYGJYpO!A&6@8?ht<}& zlRsQ9tKuac4wb&zG+A?>`;4%o?iqHvWH{%0AOccFZ#O~_4%Q@DYM-rW7Ha>?nNV~* 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

p|lJecScV-%msO>Wj_I*-~634+kb= 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

0v5x``&EZL==e=Tti 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 z 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Ĭ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�@o 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

    wR!+)ts(rn_+9FB>h9^pRcVKg`2}1AKOV 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�@)Z!0czjZx*|*1FI)`!!x_UVFcVHFU@oI&dSs{& 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 z z@NDW7lyA(qi9(>n5&K@j-tS>9%#@

    S`l!_u-IMenoq8&A4S1VW?Sp+3Bm_pOCXB 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

    VtMdJ-R_i@@It>K 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 %CFh^(6#7QRbVgQyCT^gffhn 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≈>Iuw?T_$dU>Iyu29eO# z!-%T?cF^;`0Ft)-c`4&*)vqsPk$Dp%Ct17Av7MXPZ4_zIAo2=N2=|9n0;b`9SQ%z= zBIAX$s2~A0Cbm4_wKp7tk;;BH_$;kuEps0;$#MYva5h^nIeK;fTYQr%XQP8HG7m^k zhIS$0ziP5Xr3P28fgTeHy)YEodG_*|-zEY<%REaM^E;eEAH>QzYSU`Mo5mLE+A??O zu^&IguMrEgNG|R1GAN&3lQXhaQ$lm0(G=br)f>(zf=yTJQd1zRukL!H-?zL@_1o8J zXgPOv4lbLidnr#nM%CLRN2W-CV^haG9I-p1D{@GTb0;nGNi{`^kl@8;9doYKuNf-B zyLPc*H?69RQ2-DB*zNnt6s?9vBYfTtKjoa}z~4})>Fd3XT?A09z7G8@RX@anLD^lB zHrw3Et|EVv9XerFRD|e#kfOB_Cji)N=Zd`dnqbX>yFsijjZd@7Nzocf$w?tE1BQ_HPSoR)2*+Juv_`%isFLatQ6(ZP+yPXlN=q-$~U zia%Ni>QF7J&v$)&_eX1v*|U#u{i~B_r|1BTsTgL-on92Xu2;Uph zgX#%=$Nv*jAlcV_upq~32%XAvfmj$6{NUh7F|TV7UYIFYls_U-~$-H*s{pwhC@O5vi`%H&2oF$pC zBr*$Mw>nRe{iXCGHIamRu-x65g!jdL2Aw3#W42Iaql;?yE_!^1uG+-lC*06Rai_~A zUy=ot4vPlZ7uE#tb3tI_jO^sGcXx|}M(W1KC;n!*?*cogp!!3h!n1R8@i51~oUD_$ ziQB&@v6z*%z00+#(g}LZpR+3`6OSTFjcTBdX(|v$HfuDvMfR?vOjb5@!Q=dAjg-e# z*106dfYZ~rNYqXlg#J7f2)Z#-ucslhI5Q!M2>JnQbYZ0Ns?)7Tv^Pr7@@JX5-jAJ5 zoo_SNL4nk)ogQ^Bb&^QF@~rIqn=w=c(6cZyCfQt(zOe5?7mAeCpvOf6q|XX+F)$Zt z*|{-V+sA{8OP(>vQOa*BD+DKEv&gHeiDLsem;~``=q=C_qi_eh&j~hy5*^^^vvu-j zsUh*$1PWi{7(!QM>)fpH6zrbGDNr#3l)o#hh*#Jt_HvH`0Hj&7l$LJDqXs*ek!}=# z9&sK})9K~>b8(-uJTogPFC~fyie;VoQY9IPFk(@bpbsUd%B#gcn^9AuDn1bZ;f-Xo zVMPNZSGj~}CCi+^h6vGW6E}42An$0!BGFi1;S-vSjPORwM~K)|x_y2P2z9~T;g-dU4AmOBL1(x?`&fcMU{Wji#yoI(-7ZkfYPhS#!+gb97QJk& zX{@QBjo%}6KaQ(hIQmp%P!$+zHs>_F)EI0AY1f&8D!pgT#p zBFiRNGaseMKcpXfG1W7Dw}ZNRdEbm9-rkJ$5Tj0uTD%#0`n(9b%!gIa$JooXc%9Zy zCsyn`CQi=TMTFyDqz#?ON)%*=O?1w#EG{00sYR9p&*`2T z-LEPmyVc;GtUh6}MdibW`GBY@41rTeI@io0Zc ziYVQ?pckSv^Yac4PKOKNC)&BvzTKW_TEEBLjOxx!F~C=-lO{q`P-tYN7AE3#Nb3Xy z8rl7=`7yre=;?7}A98UpGD3d@vHjK1;Pz#ggkR=%C*#T_fQw~WhaoE9bkrzYnn zbou6^b%o4XH61GVCSv(6FJT#cEd5_Dbl^sRz{#(5w#F;{ip#Tsb6kK81?%)1y|~ro zhrH#_Kp^kS;WQO%JBzJ}KWWpQtL}QO1QdL)fp7iXajJ**YF3Pt?*`cl{Qj**b_Ps+ z!ui&j9336)w6OoJXy>Ks+w&}hiLpgTYwKP7pF2MPU6hL}fkx8fUO(_spGtN}e`&AN z@8*mPfAa%HZl`dD|vlAH2&`3#X&)MJSWt}JavtWc` z02nO*9vZj;6|#(S09hr4m6_i^uwRg(B}UP5K}ZI#AEXee+d}m^t{3?_xcz3(OFsxW zls!lrS0LtV#t;r*J9GADE2Bo72ax0^c*JY#9*aOsL~`FdSYAbp+GCA*Sjhe?9(i#8 zw`jt5l0oc2SwPW>#> zTLV6|FOnj%EO?3Aj}DI7sL;Z>e4RMA_*4N=5_dbs6s{d$#!q$Z$KrF($Ioc=+${y z!C4Zb%A~ouQeYJr;6uQs|xBP*(>*@0_O9Q2SevcDD1@0jgtUJYS8_f00MM z84-OYt?A9V%a$hZ{C*?rw5XOQ4Czv6aNzL^ND}sEO_eX#Nlh)kdDqImY503(d>_)00J31) zSXTN9RT`sRP(|oV8(FGTqcNgp*AE;V2DiGR%;eGn0)~=-M;0(Wf}YytqkO53FUd>D zmiQl(g&63YFN?!n$BCJk(AOta`AmOk>NYe!Z|{i&z0pIqTZkVwW?c$_5U<4o+6*dn zhbu_PN=OtLM;sQ0u8e#Q%S4@7E6Iemhs|O(G`@EN>1_ZG2&9UPHx73fU_^SDdu*L;UfNVJf(7y!SfP)ym(ohu)f6S zsO!jqKFH0F%6)}SETGmLCVgLvlN^_qWj4vHremICrYx9Yu+-0SUV4({KbSuK7ycx{E zG(#1HIc1Vt^N;L{YfG#wWl)lDBMCZSz+8ps<8k}3mwusvzJdmxa}aW4AoWO`n`&dB zmmSlfC+NU!ITex`<+t~jU@{=nI?KaxqpW-6pbDmxDuBshfyn_V)D%#$es9i&4v<2e z`!8SnGyXQqH2e~&Fj586FwC(25}lTcE?_2TVyzMNqoy!OH$tw6U3=hL30c;0hMd5* z`?~4Hf*R4e_yL*8-;AH=kg{+ZpN&xVF9p&c&TKV*tZ+kC9NPCmE4>mQ%bpF0`$avhSyePHW$&iX>IKvL(f_?j)0(NGKA z$Q7@gQmD^~?!4z7%8eORG0lLWBl#z8rH8f;3&t1gE%<3h1y~moLo8^BvQ~?ew=biqT&&;5tqN8olyt_pmH(3mP#_-8L zEq-_&MT{2stfEfzivr16(hyAi$S5@hLEJW(`x&;5bKj+r5tOHg;Wgb0)YZwa2#v$L%y7{xM`4c?a?g6fO zKsr4YBBa4AhBw0nfoB~!M;p;A2PUeZvO0|Zono}UJBZifJ%or;D7!BC(25+g|kzPf~Sj&?9m6O zNBH!Y4C1yaYS%|iY4?8Grl-v#HoeNUac%zY%A@w}wLh^_ zc9$3D+mSu1stGmsy$SckPxA<1w2&zf*l`WVA#rK-J>@bDxc}DbvRo?L{7n`B^pfsqiR2PG&MG&Jlvv3?spx5hX*L}{yfIt>;AO=zXYDn z$7d%=A3APYw)1gTAQ}}&+U>4}X2JJ<>8K7ur2WC@r5Uimr|E^c$;uW4Tl zBbVopgV!Bb3XhVEqbVx~tQgxvP|Lbz9aV%%`S_Ab@EoQ6XG(0tY!wn4>#evavwBD5e+%&9*K=Ok;HuJl&@Vo zmiO2TU&Y%sNiNtQYED-MXyN<)Y;VNq>Q344miMmYGB(WCt@vZkCgZoZatpB-I( z%dc^Jw^+=Uz9y#4X^@*I(syAcv)ha7m zmd3=bM!GV{*!;XB%OSA*xnrL9?mZacfs-etS(U1s`^UQ!ir1a!r;IP#we;BWvvi6Y zU7keA@++S@(WrVON(Naa!P@3!>zbV%{7wH!g)H_De@wDiHARe2eF~qc!KJjgfcAUa zcYHK^V!O?#DdB5+wdB~+J}1OzlpOynOcIBp^!6d&8sy_`L8DkFVW__D7UZHR*gwE=mSedNMYMC4>vcwYIkPGyh&weshWlFZ9LE|+JR5$g;%tKL8M9&JZR zJ@zhXfFHXENuOJQIt!@uD>if2aUmj-WKLw@?jF;6?gtg@P8?NsNaERQDB)_7C z)4fzx&OQ7p;?(@OGdl{?EfYE?Xl-q6*T|t&Ww27<)#B^)8-#3~JY!p5b#{GR39kpa z2X-k;PQI|MZoNBAN?{{Sj7pKBwkdVF_yRM^=T=D0qGjTz7hq%%#OPNJ8RNuHxeHkP zlP5OZuzh2k1J&SaT=9eGYFlKd7I*z|0sA`yIypVu+d}=)n_JqodD3u{e>JunbB3Gx z-9~G%GjfplE}EALd7zx;RucQfck%Z9v`~Gi9eO1a+M*B5k`av5)^65!5@9)i)-!|M#42>!@7dM2SMTbx&m7P~V zbr-gq+-5YNylIpM{p3(}RuN+~yPx(6mcGNIY*NV_vn7cCJX!(39Q2!>5IfU(ePO0W z)2}B`=E6*jMrUp!An`}VqkprAkpC})uV%sS`IYz5w)cgj5VG$zO#_cMOpkRv@%!wa z#D1KByt3v{TKMeLC69C4>`{$_a4dK0B|PU1@3D)adVJnnalUQV^wK^_kZ9vl+h4OZ z9a~0bm(zuL?|0!6Asv2h}X|a z^t&>bK_`*kfVTuBRitXkE@re|BQ{y!IkZG~+bx=);W~6~gowceGO@mo=;Jb)8RfZ# zg6w~Y{vBL=`I^G=!KdbOXg^PXNy@k&%l_yqL0OCY&dP)0lV_fJ?y1_l0ep0nzk|6* zZY`~t`~xSxX)?f3#HBValnG$fmw_?yDIAHmSE57qIx62hhKXsvklrRQm>wa3!D2xxZl3ut%Bzm$3l>8DIUe@C{_;Th+!Od1;vVu-iG=+#~BXQ0{X>XC^NP! zm}_{Au=Qn5lLWh&F%={7?@B$04BDB(j|nmU_B|&pa)XO+lLY5le~*q5&`B3?05e4N zdBVL(FwH4BA#p!duzM&0PgI;2Md)YnqhTuns35Zy4W^8=47IPMK~;Cg7K84(w53gIc!7hnv!IT6c4{H zm^0->UYW&po0#|bCstM|o%YLj(Mt-g$OD&b3f~ zqf1J5R{Vb~0J?k_*Wh6WyavoF0ezg;o^AH?;!qXZ#Y68;WU8fm+9k$#HaS6xOX6bb z05-S%opg6Qo$t5ZN=I{4Ik|VA@N_1+_WOJ7mX#vlw_Wm|pj7KP0n3pwkRQy*w^{eJ zk3I95A0~S)69Dsv(#_alvFb2EI=2baP{0jA;8yNC1rF=vl4I}XVu15mspZpN!4o3t zE6N%X8j92xb?Ug>NLlu>8B3t^U4GXipYPZtDj@PkNK{-+T_)iC*~5~VzdP90`{y!k z?jw?mOO$4Ae$hz{Nh3zDH0kE=UaZ5zN0a4Y6}4lGXg^s<;ahawGbn$xbUHTZ(dvJ@ znK3CGaJnn1r!n$)w|sNBx>WP}p2F1cbo|4z;&iI-w)fH95@ZUcBdOvl1w|6^bY3F8 zr+E;mn6PN&$=BDAGU{6rzl}XL^r%U=1f59!>z@Z*CLuI4}rw zxHNhaH6#GAst0~A*kt$3iEPZYQCD!28X4k2dG(U)Wb)BggS@)*zxmLoZ?j9RiB)D8_-GDcd@~wCThSF zGcH!HCTCMo23~^dGIwWls5Y18g zmB+kqcs3%$hXrFF723UF9UYo_?p~!UFDXf`5S9-{CTShJaXitrucGtv9)#6tWLr~=44uDag(JTw5T?@g zh8ig00VLomoL+|zeIg!F4_?vwB4=(Us{mbU%2oUh*LwpId}&kn+u5`3wr!j=JLvQQ zX56y-S*o%tr0qc!Ro!`iE>zQT6I^hI=b%m&UUt+Do!YfhY7e!6>TT;7*{3W8M{WpZ zXXR_u>AEcKyPtEXsW25;K#V-;wNSt_r0D`$|IHU&la(bMwEXRy@`x`u4Vrf4<4^^knNR zohYIM{hCy5PyQhLO9{$D2(sS2#tD@|B)-dK4h`shyF?<7YPAhE-3WKV9x#L&KNzGy zb%z$2$Jw@;p|&vtWvjB)?yQa=|0` z@D%QIznaA(nzvHZ)K*v-pVd=TxgaX){P866-R;M|M9iSNabY^I1=wLPZ z0@dZD5p5#>4h)@g6DWu(YOq}6>of=%+J4ncApJDB(cWe6o799xV; zHD1iw%X}sE?xGPrlqo2a0ok|@4K`2wp&NEtedNPTim zZ_fF}t$x_OpxTZCSBv1H#TnZBGjJ!dL0DM?gy0|OU9F-e%~79%-@=UhR!I+^E>|GY zev~v>s{UJQ@d8z-Rs6f2TxI-28u2oRBVp2)if911c;5`aNH5=wQ?5Ug`bQ3H-I&({ z*PTO{LP#Y-VL?#v0AJc(F0Z?5f1c}sf&J6h=H5K_5T+#hEu|O1iV9rMnl>;o>`}$5 z_`_nm^6c9%4h9nTi1CZ}KKTsTZ%Fa^H<<}vhM+%>!^fNm;fPg8b$L!i3zEm}8K
    >|hBd1nu?jQ|5kGN<@ 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
    Og#`IVJURk|9LFsb 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
    <`2?UJHvJhgVL5j_06v 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

    +7l#j)XKt;amg)hVObv61u9nraL*7QDsRc zI21H=T{bOsYBWnQibaD{V;QUv1rvqHl1z|5`9g^hQY@E(nySc%3RWoO0I1_wl7wvA z^q6mGI!Gi}C}JdGOb~`r!OmyOYA}!r>#8cr63UO4>Si>^v2b%+yDG_oGb0kI*8}x+ zb?J24W3KNz&ph*5=E%eqD;9*$PBVc*=^BI(B1CYe1_GG+EN9up(t$m_T}KC7=hdqb z0s376{iyQrxvE^NAqTa~+`j_xEi1!=FO+aYNGr;h<$z9LG@* z%8w3}EGsC1&PA!1K}eKyMI=jQvrJUAG2QgZPuV5u!zcrfnO6u%w)@=4D*iG_FQgpR+3GnQv^| zVwvTpjt=e%f{AB2LLf{qma)S?bB%6Yjy?CoKuteqIo z5J{>@rANodR9PZI&Q9fOQYlp>p64;fnwwhIzUP8hU)^xd*(+R5bwW7jgvdmZ5diZU z!Gu%pdcGvfoP%lEf-^+0LgenQL(z1&Ioa$9AxTQm(1V7~IcF49MMVIqWP)HKBH_uw zkytu;=Bm^4mHcz-{&3dXb2QB`kZp@?3JQ@mzWYy7$;!!v1`zGWZFJCAi z41{2Xdor?254>2}5Za^~ndwNJ3p=C}65tA=j^j9EatBMJ!+!YHDQ)z-Cd-?1$a)H&yrQo(Vqm<1t& z@PR8Jp<1K}-=7+u+*&Avi8KRCY6eAQS&N1Buyl?hfsBBW+PdgKZ|}j^pVc(2n%GSU zA%rwFwiI$xzE3+kI#oRgh)O_3U2|LyI2;%jDp6e-M^)M}v$MXT$+xVZ{M#39xao_r zSlTc`2yui6M4Q5jtj5w2L)VC`YMLfXAqdnqG`QRfA#8*bu~-6#>{=C`nW&g})X1Ss zfQX9j>19CyQH(MiDul7xO2!^V1p<<$`m®Aq~`g_0+xrg*lF1T|N*+A&)elAtA7 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

    OnoLx906cLC}$iXo6W_e(N9hF=>PyA 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

    2Nc#IoCDEGW(Lzp%X^ANXg98XPJqlrs|~rf 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

    mSvgeYmEECz9zw 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è*$lcbTzxF>qMWRVW2vNGTjJFmTFj&R8b1EX%S~ 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 VI#U3oCj0pT Date: Tue, 3 Oct 2023 03:46:14 +0200 Subject: [PATCH 369/504] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 44f83509..205b95f5 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ terrain can be efficiently generated. We are preparing for merging the extended map with multi-modal layers such as semantics. If you want to use the feature now, please checkout 'refactor/semantic_layers' branch. Also check this [paper](https://arxiv.org/abs/2309.16818) about the new extention. +![screenshot](doc/overview.png) ## Citing From ae83cc32a1364eb77109da1660180e7f324fc7ef Mon Sep 17 00:00:00 2001 From: Takahiro Miki Date: Tue, 3 Oct 2023 03:48:10 +0200 Subject: [PATCH 370/504] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 205b95f5..d2139c83 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ terrain can be efficiently generated. ## MEM: Multi-Modal Elevation Mapping We are preparing for merging the extended map with multi-modal layers such as semantics. -If you want to use the feature now, please checkout 'refactor/semantic_layers' branch. +If you want to use the feature now, please checkout `refactor/semantic_layers` branch. Also check this [paper](https://arxiv.org/abs/2309.16818) about the new extention. ![screenshot](doc/overview.png) From 2e36f825be69741b2ab34cd55a2e9e626e67059b Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 23 Nov 2023 18:43:50 +0100 Subject: [PATCH 371/504] Added Dockerfile.x86 for building a Docker image with CUDA and PyTorch support. Added build.sh script for building the Docker image. Added run.sh script for launching a container from the Docker image. Modified turtlesim_example.launch to accept an argument for the RViz configuration file. Modified turtlesim_init.launch to include the turtlebot3_gazebo launch file and spawn the turtlebot3 model. Modified requirements.txt to comment out the cupy package. --- docker/Dockerfile.x86 | 46 +++++++++++++++++ docker/build.sh | 3 ++ docker/run.sh | 49 +++++++++++++++++++ .../launch/turtlesim_example.launch | 3 +- .../launch/turtlesim_init.launch | 21 ++++++-- requirements.txt | 2 +- 6 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 docker/Dockerfile.x86 create mode 100755 docker/build.sh create mode 100755 docker/run.sh diff --git a/docker/Dockerfile.x86 b/docker/Dockerfile.x86 new file mode 100644 index 00000000..05cad5c7 --- /dev/null +++ b/docker/Dockerfile.x86 @@ -0,0 +1,46 @@ +FROM nvidia/cuda:11.6.2-cudnn8-devel-ubuntu20.04 + +# Set noninteractive mode for apt-get +ENV DEBIAN_FRONTEND=noninteractive + +# Preconfigure tzdata +RUN echo "Etc/UTC" > /etc/timezone && \ + ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime && \ + apt-get update && apt-get install -y tzdata && \ + dpkg-reconfigure --frontend noninteractive tzdata + +# Install Python +RUN apt-get update && apt-get install -y \ + python3.8 \ + python3-pip \ + git + +# Install PyTorch +RUN pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 +COPY requirements.txt /tmp/requirements.txt +RUN pip3 install -r /tmp/requirements.txt + +# Install other Python packages +RUN pip3 install cupy-cuda11x scikit-learn +RUN pip3 install 'git+https://github.com/facebookresearch/detectron2.git' + +# Install ROS +RUN apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 +RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu focal main" > /etc/apt/sources.list.d/ros-latest.list' + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ros-noetic-desktop-full + +# Install ROS packages +RUN apt install -y ros-noetic-pybind11-catkin \ + ros-noetic-grid-map-core ros-noetic-grid-map-msgs ros-noetic-grid-map-ros ros-noetic-grid-map-rviz-plugin \ + libopencv-dev \ + libeigen3-dev \ + libgmp-dev \ + libmpfr-dev \ + libboost-all-dev \ + ros-noetic-turtlebot3-gazebo ros-noetic-turtlebot3-teleop \ + ros-noetic-ros-numpy + +RUN pip3 install catkin-tools +ENV TURTLEBOT3_MODEL=waffle \ No newline at end of file diff --git a/docker/build.sh b/docker/build.sh new file mode 100755 index 00000000..0cd07383 --- /dev/null +++ b/docker/build.sh @@ -0,0 +1,3 @@ +#! /bin/bash +home=`realpath "$(dirname "$0")"/../` +cd $home && sudo docker build -t elevation_mapping_cupy -f docker/Dockerfile.x86 --no-cache . \ No newline at end of file diff --git a/docker/run.sh b/docker/run.sh new file mode 100755 index 00000000..32587aa0 --- /dev/null +++ b/docker/run.sh @@ -0,0 +1,49 @@ +#!/bin/bash +IMAGE_NAME="elevation_mapping_cupy:latest" + +# Define environment variables for enabling graphical output for the container. +XSOCK=/tmp/.X11-unix +XAUTH=/tmp/.docker.xauth +if [ ! -f $XAUTH ] +then + touch $XAUTH + xauth_list=$(xauth nlist :0 | sed -e 's/^..../ffff/') + xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge - + chmod a+r $XAUTH +fi + +#== +# Launch container +#== + +# Create symlinks to user configs within the build context. +mkdir -p .etc && cd .etc +ln -sf /etc/passwd . +ln -sf /etc/shadow . +ln -sf /etc/group . +cd .. + +# Launch a container from the prebuilt image. +echo "---------------------" +RUN_COMMAND="docker run \ + --volume=$XSOCK:$XSOCK:rw \ + --volume=$XAUTH:$XAUTH:rw \ + --env="QT_X11_NO_MITSHM=1" \ + --env="XAUTHORITY=$XAUTH" \ + --env="DISPLAY=$DISPLAY" \ + --ulimit rtprio=99 \ + --cap-add=sys_nice \ + --privileged \ + --net=host \ + -eHOST_USERNAME=$(whoami) \ + -v$HOME:$HOME \ + -v$(pwd)/.etc/shadow:/etc/shadow \ + -v$(pwd)/.etc/passwd:/etc/passwd \ + -v$(pwd)/.etc/group:/etc/group \ + -v/media:/media \ + --gpus all \ + -it $IMAGE_NAME" +echo -e "[run.sh]: \e[1;32mThe final run command is\n\e[0;35m$RUN_COMMAND\e[0m." +$RUN_COMMAND +echo -e "[run.sh]: \e[1;32mDocker terminal closed.\e[0m" +# --entrypoint=$ENTRYPOINT \ \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_example.launch b/elevation_mapping_cupy/launch/turtlesim_example.launch index 068a2962..5fd6e529 100644 --- a/elevation_mapping_cupy/launch/turtlesim_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_example.launch @@ -1,10 +1,11 @@ + - + diff --git a/elevation_mapping_cupy/launch/turtlesim_init.launch b/elevation_mapping_cupy/launch/turtlesim_init.launch index fc166d22..86e2909b 100644 --- a/elevation_mapping_cupy/launch/turtlesim_init.launch +++ b/elevation_mapping_cupy/launch/turtlesim_init.launch @@ -1,16 +1,29 @@ + + + + + + + + + + + + + + + - - + - - + diff --git a/requirements.txt b/requirements.txt index 1b84c227..45fb53ea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ opencv-python simple-parsing scikit-image matplotlib -cupy +# cupy ###### Requirements with Version Specifiers ######` shapely==1.7.1 From eda65e9c1954ad0dcdf937b0096e3b6d9fbf9c29 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Fri, 24 Nov 2023 02:01:28 +0100 Subject: [PATCH 372/504] Work in progress for inputting the channel and fusion from the topic. Improved error handling. Added feature for adding layer online instead of initializing from config. --- .../turtle_bot/turtle_bot_semantics.yaml | 11 +- .../elevation_mapping_ros.hpp | 5 +- .../elevation_mapping_wrapper.hpp | 4 +- .../elevation_mapping.py | 11 +- .../fusion/fusion_manager.py | 12 +- .../elevation_mapping_cupy/parameter.py | 40 ++++-- .../elevation_mapping_cupy/semantic_map.py | 123 +++++++++++++++--- .../src/elevation_mapping_ros.cpp | 22 +++- .../src/elevation_mapping_wrapper.cpp | 31 ++++- 9 files changed, 202 insertions(+), 57 deletions(-) diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml index 4cffcde2..566fc4d3 100644 --- a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml @@ -1,10 +1,17 @@ #### Plugins ######## plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/turtle_bot/plugin_config.yaml' +pointcloud_channel_fusion: + rgb: 'pointcloud_color' + default: 'pointcloud_average' + sheep: 'pointcloud_average' + sofa: 'pointcloud_class_average' + person: 'pointcloud_class_average' + #### Subscribers ######## subscribers: front_cam: - channels: ['rgb', 'grass','tree',"person" ] + channels: ['rgb', 'sheep','sofa',"person" ] fusion: [ 'color','class_average','class_average','class_average' ] topic_name: '/elevation_mapping/pointcloud_semantic' semantic_segmentation: True @@ -22,7 +29,7 @@ subscribers: #### Publishers ######## publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb','sem_fil'] + layers: ['elevation', 'traversability', 'variance','rgb','sem_fil', 'person', 'sheep', 'sofa'] basic_layers: ['elevation'] fps: 5.0 elevation_map_filter: diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 5811b05b..4345f04e 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -74,8 +74,9 @@ class ElevationMappingNode { void readParameters(); void setupMapPublishers(); void pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key); - void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, - const std::string& key); + void inputImage(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, + const std::vector& channels, const std::vector& fusion_methods); + void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg); void publishAsPointCloud(const grid_map::GridMap& map) const; bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response); diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index ff92db66..b6d633da 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -48,8 +48,8 @@ class ElevationMappingWrapper { void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); - void input_image(const std::string& key, const std::vector& image, const RowMatrixXd& R, const Eigen::VectorXd& t, - const RowMatrixXd& cameraMatrix, int height, int width); + void input_image(const std::vector& multichannel_image, const std::vector& channels, const std::vector& fusion_methods, const RowMatrixXd& R, + const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, int height, int width); void move_to(const Eigen::VectorXd& p, const RowMatrixXd& R); void clear(); void update_variance(); diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index c76bff7b..0f926c9a 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -452,6 +452,7 @@ def input_pointcloud( """ raw_points = cp.asarray(raw_points, dtype=self.data_type) additional_channels = channels[3:] + print("additional_channels", additional_channels) raw_points = raw_points[~cp.isnan(raw_points).any(axis=1)] self.update_map_with_kernel( raw_points, @@ -464,8 +465,9 @@ def input_pointcloud( def input_image( self, - sub_key: str, image: List[cp._core.core.ndarray], + channels: List[str], + fusion_methods: List[str], R: cp._core.core.ndarray, t: cp._core.core.ndarray, K: cp._core.core.ndarray, @@ -509,6 +511,9 @@ def input_image( self.uv_correspondence *= 0 self.valid_correspondence[:, :] = False + print("channels", channels) + print("fusion_methods", fusion_methods) + with self.map_lock: self.image_to_map_correspondence_kernel( self.elevation_map, @@ -524,8 +529,10 @@ def input_image( size=int(self.cell_n * self.cell_n), ) self.semantic_map.update_layers_image( - sub_key, + # sub_key, image, + channels, + fusion_methods, self.uv_correspondence, self.valid_correspondence, image_height, diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py index 7910096d..0596af35 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py @@ -54,11 +54,11 @@ def get_plugin_idx(self, name: str, data_type: str): """ Get a registered fusion plugin """ - name = data_type + "_" + name + # name = data_type + "_" + name for idx, plugin in enumerate(self.plugins): if plugin.name == name: return idx - print("Plugin {} is not in the list: {}".format(name, self.plugins)) + print("[WARNING] Plugin {} is not in the list: {}".format(name, self.plugins)) return None def execute_plugin( @@ -72,8 +72,8 @@ def execute_plugin( self.plugins[idx]( points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, elements_to_shift ) - else: - raise ValueError("Plugin {} is not registered".format(name)) + # else: + # raise ValueError("Plugin {} is not registered".format(name)) def execute_image_plugin( self, @@ -104,5 +104,5 @@ def execute_image_plugin( semantic_map, new_map, ) - else: - raise ValueError("Plugin {} is not registered".format(name)) + # else: + # raise ValueError("Plugin {} is not registered".format(name)) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 2d23a6d2..40ac3dd9 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -7,6 +7,7 @@ import numpy as np from simple_parsing.helpers import Serializable from dataclasses import field +from typing import Tuple @dataclass @@ -33,8 +34,19 @@ class Parameter(Serializable): } } ) - additional_layers: list = field(default_factory=lambda: ["feat_0"]) - fusion_algorithms: list = field(default_factory=lambda: ["average"]) + # additional_layers: list = field(default_factory=lambda: ["feat_0"]) + # fusion_algorithms: list = field(default_factory=lambda: ["average"]) + additional_layers: list = field(default_factory=lambda: ["color"]) + fusion_algorithms: list = field(default_factory=lambda: [ + "image_color", + "image_exponential", + "pointcloud_average", + "pointcloud_bayesian_inference", + "pointcloud_class_average", + "pointcloud_class_bayesian", + "pointcloud_class_max", + "pointcloud_color"]) + pointcloud_channel_fusion: dict = field(default_factory=lambda: {"rgb": "pointcloud_color", "default": "pointcloud_class_average"}) data_type: str = np.float32 average_weight: float = 0.5 @@ -126,18 +138,18 @@ def update(self): self.cell_n = int(round(self.map_length / self.resolution)) + 2 self.true_cell_n = round(self.map_length / self.resolution) self.true_map_length = self.true_cell_n * self.resolution - semantic_layers = [] - fusion_algorithms = [] - for subscriber, sub_val in self.subscriber_cfg.items(): - channels = sub_val["channels"] - fusion = sub_val["fusion"] - for i in range(len(channels)): - name = channels[i] - if name not in semantic_layers: - semantic_layers.append(name) - fusion_algorithms.append(fusion[i]) - self.additional_layers = semantic_layers - self.fusion_algorithms = fusion_algorithms + # semantic_layers = [] + # fusion_algorithms = [] + # for subscriber, sub_val in self.subscriber_cfg.items(): + # channels = sub_val["channels"] + # fusion = sub_val["fusion"] + # for i in range(len(channels)): + # name = channels[i] + # if name not in semantic_layers: + # semantic_layers.append(name) + # fusion_algorithms.append(fusion[i]) + # self.additional_layers = semantic_layers + # self.fusion_algorithms = fusion_algorithms if __name__ == "__main__": diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index d090416c..131ab0b9 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -24,16 +24,31 @@ def __init__(self, param: Parameter): self.unique_data = [] self.elements_to_shift = {} - for k, config in self.param.subscriber_cfg.items(): - for f, c in zip(config["fusion"], config["channels"]): - if c not in self.layer_names: - self.layer_names.append(c) - self.layer_specs[c] = f - else: - assert self.layer_specs[c] == f, "Error: Single layer has multiple fusion algorithms!" - if f not in self.unique_fusion: - dt = config["data_type"] - self.unique_fusion.append(dt + "_" + f) + # for k, config in self.param.subscriber_cfg.items(): + # for f, c in zip(config["fusion"], config["channels"]): + # if c not in self.layer_names: + # self.layer_names.append(c) + # self.layer_specs[c] = f + # else: + # assert self.layer_specs[c] == f, "Error: Single layer has multiple fusion algorithms!" + # if f not in self.unique_fusion: + # dt = config["data_type"] + # self.unique_fusion.append(dt + "_" + f) + for channel, fusion in self.param.pointcloud_channel_fusion.items(): + if channel not in self.layer_names: + if channel != "default": + self.layer_names.append(channel) + self.layer_specs[channel] = fusion + else: + assert self.layer_specs[channel] == fusion, "Error: Single layer has multiple fusion algorithms!" + # for f, c in zip(config["fusion"], config["channels"]): + # else: + # assert self.layer_specs[c] == f, "Error: Single layer has multiple fusion algorithms!" + # if f not in self.unique_fusion: + # dt = config["data_type"] + # self.unique_fusion.append(dt + "_" + f) + self.layer_names += self.param.additional_layers + self.unique_fusion = self.param.fusion_algorithms self.amount_layer_names = len(self.layer_names) @@ -71,6 +86,43 @@ def initialize_fusion(self): self.elements_to_shift["id_max"] = id_max self.fusion_manager.register_plugin(fusion) + def update_fusion_setting(self): + for fusion in self.unique_fusion: + if "pointcloud_class_bayesian" == fusion: + pcl_ids = self.get_layer_indices("class_bayesian") + self.delete_new_layers[pcl_ids] = 0 + if "pointcloud_class_max" == fusion: + pcl_ids = self.get_layer_indices("class_max") + self.delete_new_layers[pcl_ids] = 0 + layer_cnt = self.param.fusion_algorithms.count("class_max") + id_max = cp.zeros( + (layer_cnt, self.param.cell_n, self.param.cell_n), + dtype=cp.uint32, + ) + self.elements_to_shift["id_max"] = id_max + + def add_layer(self, name): + """ + Add a new layer to the semantic map. + + Args: + name (str): The name of the new layer. + """ + if name not in self.layer_names: + self.layer_names.append(name) + self.semantic_map = cp.append( + self.semantic_map, + cp.zeros((1, self.param.cell_n, self.param.cell_n), dtype=self.param.data_type), + axis=0, + ) + self.new_map = cp.append( + self.new_map, + cp.zeros((1, self.param.cell_n, self.param.cell_n), dtype=self.param.data_type), + axis=0, + ) + self.delete_new_layers = cp.append(self.delete_new_layers, cp.array([1], dtype=cp.bool8)) + + def pad_value(self, x, shift_value, idx=None, value=0.0): """Create a padding of the map along x,y-axis according to amount that has shifted. @@ -120,11 +172,22 @@ def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: channels (List[str]): """ fusion_list = [] + process_channels = [] for channel in channels: + if channel not in self.layer_specs: + if "default" in self.param.pointcloud_channel_fusion: + default_fusion = self.param.pointcloud_channel_fusion["default"] + print(f"[WARNING] Layer {channel} not found in layer_specs. Using {default_fusion} algorithm as default.") + self.layer_specs[channel] = default_fusion + self.update_fusion_setting() + else: + print(f"[WARNING] Layer {channel} not found in layer_specs. Skipping.") + continue x = self.layer_specs[channel] if x not in fusion_list: fusion_list.append(x) - return fusion_list + process_channels.append(channel) + return process_channels, fusion_list def get_layer_indices(self, fusion_alg): """Get the indices of the layers that are used for a specific fusion algorithm. @@ -177,11 +240,15 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): t: translation vector elevation_map: elevation map object """ - additional_fusion = self.get_fusion_of_pcl(channels) + process_channels, additional_fusion = self.get_fusion_of_pcl(channels) + for channel in process_channels: + if channel not in self.layer_names: + print(f"Layer {channel} not found, adding it to the semantic map") + self.add_layer(channel) self.new_map[self.delete_new_layers] = 0.0 for fusion in list(set(additional_fusion)): # which layers need to be updated with this fusion algorithm - pcl_ids, layer_ids = self.get_indices_fusion(channels, fusion) + pcl_ids, layer_ids = self.get_indices_fusion(process_channels, fusion) # update the layers with the fusion algorithm self.fusion_manager.execute_plugin( fusion, @@ -198,8 +265,10 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): def update_layers_image( self, - sub_key: str, + # sub_key: str, image: cp._core.core.ndarray, + channels: List[str], + fusion_methods: List[str], uv_correspondence: cp._core.core.ndarray, valid_correspondence: cp._core.core.ndarray, image_height: cp._core.core.ndarray, @@ -216,13 +285,26 @@ def update_layers_image( image_width: """ + # print("sub_key", sub_key) + # print("delete_new_layers", self.delete_new_layers) + # additional_fusion = self.get_fusion_of_pcl(channels) self.new_map[self.delete_new_layers] = 0.0 - config = self.param.subscriber_cfg[sub_key] + # config = self.param.subscriber_cfg[sub_key] - for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): + # print("config", config) + + # for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): + for j, (fusion, channel) in enumerate(zip(fusion_methods, channels)): + if channel not in self.layer_names: + print(f"Layer {channel} not found, adding it to the semantic map") + self.add_layer(channel) sem_map_idx = self.get_index(channel) + if sem_map_idx == -1: + print(f"Layer {channel} not found!") + return + # which layers need to be updated with this fusion algorithm # pcl_ids, layer_ids = self.get_indices_fusion(channels, fusion) # update the layers with the fusion algorithm @@ -266,7 +348,9 @@ def get_map_with_name(self, name): Returns: cp.array: map """ - if self.layer_specs[name] == "color": + print("[get_map_with_name] name", name, self.layer_specs) + if name in self.layer_specs and (self.layer_specs[name] == "image_color" or self.layer_specs[name] == "pointcloud_color"): + print("this is a color map") m = self.get_rgb(name) return m else: @@ -321,4 +405,7 @@ def get_index(self, name): Returns: int: index """ - return self.layer_names.index(name) + if name not in self.layer_names: + return -1 + else: + return self.layer_names.index(name) diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 1b6c6dfa..5f926373 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -118,7 +118,7 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) cameraInfoSubs_.push_back(cam_info_sub); CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); - sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2, key)); + sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2)); cameraSyncs_.push_back(sync); } else { @@ -348,10 +348,10 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl pointCloudProcessCounter_++; } -void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image_msg, - const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::string& key) { - auto start = ros::Time::now(); - +void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_msg, + const sensor_msgs::CameraInfoConstPtr& camera_info_msg, + const std::vector& channels, + const std::vector& fusion_methods) { // Get image cv::Mat image = cv_bridge::toCvShare(image_msg, image_msg->encoding)->image; @@ -390,9 +390,19 @@ void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image } // Pass image to pipeline - map_.input_image(key, multichannel_image, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, + map_.input_image(multichannel_image, channels, fusion_methods, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, image.rows, image.cols); +} +void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image_msg, + const sensor_msgs::CameraInfoConstPtr& camera_info_msg) { + auto start = ros::Time::now(); + // Default channels and fusion methods for image is rgb and image_color + std::vector channels; + std::vector fusion_methods; + channels.push_back("rgb"); + fusion_methods.push_back("image_color"); + inputImage(image_msg, camera_info_msg, channels, fusion_methods); ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); } diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 51cf073e..2fd31770 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -121,6 +121,24 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { } param_.attr("subscriber_cfg") = sub_dict; + if (!nh.hasParam("pointcloud_channel_fusion")) { + ROS_WARN("No pointcloud_channel_fusion parameter found. Using default values."); + } + else { + XmlRpc::XmlRpcValue pointcloud_channel_fusion; + nh.getParam("pointcloud_channel_fusion", pointcloud_channel_fusion); + + py::dict pointcloud_channel_fusion_dict; + for (auto& channel_fusion : pointcloud_channel_fusion) { + const char* const name = channel_fusion.first.c_str(); + std::string fusion = static_cast(channel_fusion.second); + if (!pointcloud_channel_fusion_dict.contains(name)) { + pointcloud_channel_fusion_dict[name] = fusion; + } + } + param_.attr("pointcloud_channel_fusion") = pointcloud_channel_fusion_dict; + } + param_.attr("update")(); resolution_ = py::cast(param_.attr("get_value")("resolution")); map_length_ = py::cast(param_.attr("get_value")("true_map_length")); @@ -137,10 +155,10 @@ void ElevationMappingWrapper::input(const RowMatrixXd& points, const std::vector Eigen::Ref(t), positionNoise, orientationNoise); } -void ElevationMappingWrapper::input_image(const std::string& key, const std::vector& multichannel_image, const RowMatrixXd& R, +void ElevationMappingWrapper::input_image(const std::vector& multichannel_image, const std::vector& channels, const std::vector& fusion_methods, const RowMatrixXd& R, const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, int height, int width) { py::gil_scoped_acquire acquire; - map_.attr("input_image")(key, multichannel_image, Eigen::Ref(R), Eigen::Ref(t), + map_.attr("input_image")(multichannel_image, channels, fusion_methods, Eigen::Ref(R), Eigen::Ref(t), Eigen::Ref(cameraMatrix), height, width); } @@ -189,9 +207,12 @@ void ElevationMappingWrapper::get_grid_map(grid_map::GridMap& gridMap, const std std::vector maps; for (const auto& layerName : layerNames) { - RowMatrixXf map(map_n_, map_n_); - map_.attr("get_map_with_name_ref")(layerName, Eigen::Ref(map)); - gridMap.add(layerName, map); + bool exists = map_.attr("exists_layer")(layerName).cast(); + if (exists) { + RowMatrixXf map(map_n_, map_n_); + map_.attr("get_map_with_name_ref")(layerName, Eigen::Ref(map)); + gridMap.add(layerName, map); + } } if (enable_normal_color_) { RowMatrixXf normal_x(map_n_, map_n_); From 26331d66b115aa147dfd2f6aa2d4baf38eb21aa0 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Fri, 24 Nov 2023 02:35:54 +0100 Subject: [PATCH 373/504] Removed some printing. --- .../script/elevation_mapping_cupy/fusion/image_color.py | 2 +- .../script/elevation_mapping_cupy/fusion/image_exponential.py | 2 +- .../script/elevation_mapping_cupy/fusion/pointcloud_average.py | 2 +- .../fusion/pointcloud_bayesian_inference.py | 2 +- .../elevation_mapping_cupy/fusion/pointcloud_class_average.py | 2 +- .../elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py | 2 +- .../elevation_mapping_cupy/fusion/pointcloud_class_max.py | 2 +- .../script/elevation_mapping_cupy/fusion/pointcloud_color.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py index 317530d5..8eea8eb2 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py @@ -47,7 +47,7 @@ def color_correspondences_to_map_kernel(resolution, width, height): class ImageColor(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) - print("Initialize fusion kernel") + # print("Initialize fusion kernel") self.name = "image_color" self.cell_n = params.cell_n self.resolution = params.resolution diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py index d9ad1ce7..480b943d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py @@ -38,7 +38,7 @@ def exponential_correspondences_to_map_kernel(resolution, width, height, alpha): class ImageExponential(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) - print("Initialize fusion kernel") + # print("Initialize fusion kernel") self.name = "image_exponential" self.cell_n = params.cell_n self.resolution = params.resolution diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py index cda9af96..a823b258 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py @@ -86,7 +86,7 @@ def average_kernel( class Average(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) - print("Initialize fusion kernel") + # print("Initialize fusion kernel") self.name = "pointcloud_average" self.cell_n = params.cell_n self.resolution = params.resolution diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py index f9f07b4a..c8da65d9 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py @@ -82,7 +82,7 @@ def bayesian_inference_kernel( class BayesianInference(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) - print("Initialize bayesian inference kernel") + # print("Initialize bayesian inference kernel") self.name = "pointcloud_bayesian_inference" self.cell_n = params.cell_n diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py index a28c98db..b8ad5cb8 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py @@ -96,7 +96,7 @@ def class_average_kernel( class ClassAverage(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) - print("Initialize fusion kernel") + # print("Initialize fusion kernel") self.name = "pointcloud_class_average" self.cell_n = params.cell_n self.resolution = params.resolution diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py index eeae2324..6e507194 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py @@ -51,7 +51,7 @@ def alpha_kernel( class ClassBayesian(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) - print("Initialize fusion kernel") + # print("Initialize fusion kernel") self.name = "pointcloud_class_bayesian" self.cell_n = params.cell_n self.resolution = params.resolution diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py index ea8d0c5c..630c2ae6 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py @@ -47,7 +47,7 @@ def sum_max_kernel( class ClassMax(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) - print("Initialize fusion kernel") + # print("Initialize fusion kernel") self.name = "pointcloud_class_max" self.cell_n = params.cell_n self.resolution = params.resolution diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py index 1c24fedb..9b7c1b34 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py @@ -118,7 +118,7 @@ def color_average_kernel( class Color(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) - print("Initialize fusion kernel") + # print("Initialize fusion kernel") self.name = "pointcloud_color" self.cell_n = params.cell_n self.resolution = params.resolution From 7e875aaa30995cc9e08f29708842e2b3c755b93f Mon Sep 17 00:00:00 2001 From: Takahiro Date: Fri, 24 Nov 2023 02:36:05 +0100 Subject: [PATCH 374/504] Removed some printing --- .../script/elevation_mapping_cupy/elevation_mapping.py | 1 - 1 file changed, 1 deletion(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 0f926c9a..4f49f86b 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -452,7 +452,6 @@ def input_pointcloud( """ raw_points = cp.asarray(raw_points, dtype=self.data_type) additional_channels = channels[3:] - print("additional_channels", additional_channels) raw_points = raw_points[~cp.isnan(raw_points).any(axis=1)] self.update_map_with_kernel( raw_points, From e8eeddf319ef9e0e9065e9fefc1b425d6e0ccebc Mon Sep 17 00:00:00 2001 From: Takahiro Date: Fri, 24 Nov 2023 02:36:19 +0100 Subject: [PATCH 375/504] Fixed a bug in the layer index handling. --- .../elevation_mapping_cupy/semantic_map.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 131ab0b9..e33585f1 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -175,11 +175,13 @@ def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: process_channels = [] for channel in channels: if channel not in self.layer_specs: + # If the channel is not in the layer_specs, we use the default fusion algorithm if "default" in self.param.pointcloud_channel_fusion: default_fusion = self.param.pointcloud_channel_fusion["default"] print(f"[WARNING] Layer {channel} not found in layer_specs. Using {default_fusion} algorithm as default.") self.layer_specs[channel] = default_fusion self.update_fusion_setting() + # If there's no default fusion algorithm, we skip this channel else: print(f"[WARNING] Layer {channel} not found in layer_specs. Skipping.") continue @@ -227,7 +229,8 @@ def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): layer_indices = cp.array([], dtype=cp.int32) for it, (key, val) in enumerate(self.layer_specs.items()): if key in pcl_channels and val == fusion_alg: - layer_indices = cp.append(layer_indices, it).astype(cp.int32) + layer_idx = self.layer_names.index(key) + layer_indices = cp.append(layer_indices, layer_idx).astype(cp.int32) return pcl_indices, layer_indices def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): @@ -241,10 +244,13 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): elevation_map: elevation map object """ process_channels, additional_fusion = self.get_fusion_of_pcl(channels) + # If channels has a new layer that is not in the semantic map, add it for channel in process_channels: if channel not in self.layer_names: print(f"Layer {channel} not found, adding it to the semantic map") self.add_layer(channel) + + # Resetting new_map for the layers that are to be deleted self.new_map[self.delete_new_layers] = 0.0 for fusion in list(set(additional_fusion)): # which layers need to be updated with this fusion algorithm @@ -285,15 +291,10 @@ def update_layers_image( image_width: """ - # print("sub_key", sub_key) - # print("delete_new_layers", self.delete_new_layers) - # additional_fusion = self.get_fusion_of_pcl(channels) self.new_map[self.delete_new_layers] = 0.0 # config = self.param.subscriber_cfg[sub_key] - # print("config", config) - # for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): for j, (fusion, channel) in enumerate(zip(fusion_methods, channels)): if channel not in self.layer_names: @@ -348,9 +349,8 @@ def get_map_with_name(self, name): Returns: cp.array: map """ - print("[get_map_with_name] name", name, self.layer_specs) + # If the layer is a color layer, return the rgb map if name in self.layer_specs and (self.layer_specs[name] == "image_color" or self.layer_specs[name] == "pointcloud_color"): - print("this is a color map") m = self.get_rgb(name) return m else: From 2a5bd37617b56d08b1e8b8429601633c34bdf310 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 29 Nov 2023 15:46:00 +0100 Subject: [PATCH 376/504] Added FusionInfo.msg --- elevation_map_msgs/CMakeLists.txt | 1 + elevation_map_msgs/msg/FusionInfo.msg | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 elevation_map_msgs/msg/FusionInfo.msg diff --git a/elevation_map_msgs/CMakeLists.txt b/elevation_map_msgs/CMakeLists.txt index 1dd3bcaa..653174ef 100644 --- a/elevation_map_msgs/CMakeLists.txt +++ b/elevation_map_msgs/CMakeLists.txt @@ -11,6 +11,7 @@ find_package(catkin REQUIRED COMPONENTS add_message_files( FILES Statistics.msg + FusionInfo.msg ) ## Generate services in the 'srv' folder diff --git a/elevation_map_msgs/msg/FusionInfo.msg b/elevation_map_msgs/msg/FusionInfo.msg new file mode 100644 index 00000000..4cfd1718 --- /dev/null +++ b/elevation_map_msgs/msg/FusionInfo.msg @@ -0,0 +1,3 @@ +Header header +string[] channels # channel names for each layer +string[] fusion_methods # fusion methods to use for each channel \ No newline at end of file From 4dbbcb20528211a416178845dbf6c962a2ab8475 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 29 Nov 2023 20:07:32 +0100 Subject: [PATCH 377/504] Work in progress for adding FusionInfo pub and sub. --- .../setups/anymal/anymal_parameters.yaml | 22 ++--- .../anymal/anymal_sensor_parameter.yaml | 49 ++++++++-- .../turtle_bot/turtle_bot_semantics.yaml | 56 ++++++++---- .../elevation_mapping_ros.hpp | 11 +++ elevation_mapping_cupy/launch/anymal.launch | 4 +- .../launch/turtlesim_init.launch | 5 +- .../turtlesim_semantic_image_example.launch | 8 +- .../rviz/turtle_example.rviz | 48 +++++++--- .../elevation_mapping.py | 11 ++- .../fusion/fusion_manager.py | 2 +- .../kernels/custom_image_kernels.py | 49 +++++++--- .../src/elevation_mapping_ros.cpp | 43 +++++++-- .../config/sensor_parameter.yaml | 91 +++++++++++++------ .../launch/semantic_image.launch | 7 ++ .../script/semantic_sensor/image_node.py | 32 +++++-- .../semantic_sensor/image_parameters.py | 16 ++-- .../script/semantic_sensor/networks.py | 46 +++++----- 17 files changed, 353 insertions(+), 147 deletions(-) create mode 100644 sensor_processing/semantic_sensor/launch/semantic_image.launch diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml index c1aa165b..5d1ad988 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml @@ -55,13 +55,13 @@ enable_normal_color: false # If true, the map contains 'col #### Traversability filter ######## use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. -weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter +weight_file: '$(rospack find elevation_mapping_cupy)/config/core/weights.dat' # Weight file for traversability filter #### Upper bound ######## use_only_above_for_upper_bound: false #### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin_config.yaml' +# plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin_config.yaml' #### Publishers ######## # topic_name: @@ -69,16 +69,16 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin # basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. # fps: # Publish rate. Use smaller value than `map_acquire_fps`. -publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance'] - basic_layers: ['elevation', 'traversability'] - fps: 5.0 +# publishers: +# elevation_map_raw: +# layers: ['elevation', 'traversability', 'variance'] +# basic_layers: ['elevation', 'traversability'] +# fps: 5.0 - semantic_map_raw: - layers: ['elevation', 'traversability'] - basic_layers: ['elevation', 'traversability'] - fps: 5.0 +# semantic_map_raw: +# layers: ['elevation', 'traversability'] +# basic_layers: ['elevation', 'traversability'] +# fps: 5.0 #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml index ecb96c73..90cc74fb 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml @@ -1,15 +1,46 @@ +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/anymal/anymal_plugin_config.yaml' + +#### Publishers ######## +# topic_name: +# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names +# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. +# fps: # Publish rate. Use smaller value than `map_acquire_fps`. + +publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance'] + basic_layers: ['elevation', 'traversability'] + fps: 5.0 + + semantic_map_raw: + layers: ['elevation', 'traversability'] + basic_layers: ['elevation', 'traversability'] + fps: 5.0 + #### Subscribers ######## subscribers: - front_depth: + front_upper_depth: + channels: [] + fusion: [] + topic_name: /depth_camera_front_upper/point_cloud_self_filtered + data_type: pointcloud + + front_lower_depth: channels: [] fusion: [] - topic_name: /depth_camera_front/point_cloud_self_filtered + topic_name: /depth_camera_front_lower/point_cloud_self_filtered data_type: pointcloud - rear_depth: + rear_upper_depth: channels: [] fusion: [] - topic_name: /depth_camera_rear/point_cloud_self_filtered + topic_name: /depth_camera_rear_upper/point_cloud_self_filtered + data_type: pointcloud + + rear_lower_depth: + channels: [] + fusion: [] + topic_name: /depth_camera_rear_lower/point_cloud_self_filtered data_type: pointcloud left_depth: @@ -24,11 +55,11 @@ subscribers: topic_name: /depth_camera_right/point_cloud_self_filtered data_type: pointcloud - velodyne: - channels: [] - fusion: [] - topic_name: /point_cloud_filter/lidar/point_cloud_filtered - data_type: pointcloud + # velodyne: + # channels: [] + # fusion: [] + # topic_name: /point_cloud_filter/lidar/point_cloud_filtered + # data_type: pointcloud front_bpearl: channels: [] diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml index 566fc4d3..9c4019bb 100644 --- a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml @@ -2,34 +2,52 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/turtle_bot/plugin_config.yaml' pointcloud_channel_fusion: - rgb: 'pointcloud_color' - default: 'pointcloud_average' - sheep: 'pointcloud_average' - sofa: 'pointcloud_class_average' - person: 'pointcloud_class_average' + rgb: 'color' + default: 'average' + sheep: 'average' + sofa: 'class_average' + person: 'class_average' #### Subscribers ######## subscribers: - front_cam: - channels: ['rgb', 'sheep','sofa',"person" ] - fusion: [ 'color','class_average','class_average','class_average' ] - topic_name: '/elevation_mapping/pointcloud_semantic' - semantic_segmentation: True - publish_segmentation_image: True - segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large - show_label_legend: False - data_type: pointcloud + color_cam: # for color camera + # channels: ['rgb'] + # fusion: ['color'] + topic_name: '/camera/rgb/image_raw' + camera_info_topic_name: '/camera/depth/camera_info' + data_type: image + # front_cam: + # channels: ['rgb', 'sheep','sofa',"person" ] + # fusion: [ 'color','class_average','class_average','class_average' ] + # topic_name: '/elevation_mapping/pointcloud_semantic' + # semantic_segmentation: True + # publish_segmentation_image: True + # segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large + # show_label_legend: False - cam_info_topic: "/camera/depth/camera_info" - image_topic: "/camera/rgb/image_raw" - depth_topic: "/camera/depth/image_raw" - cam_frame: "camera_rgb_optical_frame" + # cam_info_topic: "/camera/rgb/camera_info" + # image_topic: "/camera/rgb/image_raw" + # cam_frame: "camera_rgb_optical_frame" + # data_type: image + # depth_topic: "/camera/depth/image_raw" + semantic_cam: # for color camera + # channels: ['rgb'] + # fusion: ['color'] + topic_name: '/front_cam/semantic_image' + camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' + fusion_info_topic_name: '/front_cam/fusion_info' + data_type: image + front_cam_pointcloud: + channels: [] + fusion: [] + topic_name: '/camera/depth/points' + data_type: pointcloud #### Publishers ######## publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb','sem_fil', 'person', 'sheep', 'sofa'] + layers: ['elevation', 'traversability', 'variance','rgb','sem_fil', 'person', 'chair', 'sofa'] basic_layers: ['elevation'] fps: 5.0 elevation_map_filter: diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 4345f04e..ab873aa1 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -49,6 +49,7 @@ #include #include +#include #include "elevation_mapping_cupy/elevation_mapping_wrapper.hpp" @@ -70,6 +71,12 @@ class ElevationMappingNode { using CameraSync = message_filters::Synchronizer; using CameraSyncPtr = std::shared_ptr; + using FusionInfoSubscriber = message_filters::Subscriber; + using FusionInfoSubscriberPtr = std::shared_ptr; + using CameraFusionPolicy = message_filters::sync_policies::ApproximateTime; + using CameraFusionSync = message_filters::Synchronizer; + using CameraFusionSyncPtr = std::shared_ptr; + private: void readParameters(); void setupMapPublishers(); @@ -77,6 +84,8 @@ class ElevationMappingNode { void inputImage(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::vector& channels, const std::vector& fusion_methods); void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg); + void imageFusionCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const elevation_map_msgs::FusionInfoConstPtr& fusion_info_msg); + // void multiLayerImageCallback(const elevation_map_msgs::MultiLayerImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg); void publishAsPointCloud(const grid_map::GridMap& map) const; bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response); @@ -101,7 +110,9 @@ class ElevationMappingNode { std::vector pointcloudSubs_; std::vector imageSubs_; std::vector cameraInfoSubs_; + std::vector fusionInfoSubs_; std::vector cameraSyncs_; + std::vector cameraFusionSyncs_; std::vector mapPubs_; tf::TransformBroadcaster tfBroadcaster_; ros::Publisher alivePub_; diff --git a/elevation_mapping_cupy/launch/anymal.launch b/elevation_mapping_cupy/launch/anymal.launch index cc598ea2..67c2f147 100644 --- a/elevation_mapping_cupy/launch/anymal.launch +++ b/elevation_mapping_cupy/launch/anymal.launch @@ -1,7 +1,7 @@ - - + + diff --git a/elevation_mapping_cupy/launch/turtlesim_init.launch b/elevation_mapping_cupy/launch/turtlesim_init.launch index 86e2909b..0679d174 100644 --- a/elevation_mapping_cupy/launch/turtlesim_init.launch +++ b/elevation_mapping_cupy/launch/turtlesim_init.launch @@ -3,13 +3,14 @@ - + - + + diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch index 1f680224..30741b50 100644 --- a/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch @@ -7,16 +7,16 @@ - - - + + - + \ No newline at end of file diff --git a/elevation_mapping_cupy/rviz/turtle_example.rviz b/elevation_mapping_cupy/rviz/turtle_example.rviz index b5b19b90..fe4c79bb 100644 --- a/elevation_mapping_cupy/rviz/turtle_example.rviz +++ b/elevation_mapping_cupy/rviz/turtle_example.rviz @@ -6,7 +6,7 @@ Panels: Expanded: - /Global Options1 Splitter Ratio: 0.5768463015556335 - Tree Height: 658 + Tree Height: 229 - Class: rviz/Selection Name: Selection - Class: rviz/Tool Properties @@ -22,10 +22,9 @@ Panels: Name: Views Splitter Ratio: 0.5 - Class: rviz/Time - Experimental: false Name: Time SyncMode: 0 - SyncSource: "" + SyncSource: Image Preferences: PromptSaveOnExit: true Toolbars: @@ -57,14 +56,11 @@ Visualization Manager: Color: 200; 200; 200 Color Layer: rgb Color Transformer: ColorLayer - ColorMap: default Enabled: true - Grid Cell Decimation: 1 - Grid Line Thickness: 0.10000000149011612 Height Layer: elevation Height Transformer: "" History Length: 1 - Invert ColorMap: false + Invert Rainbow: false Max Color: 238; 238; 236 Max Intensity: 1 Min Color: 32; 74; 135 @@ -73,7 +69,7 @@ Visualization Manager: Show Grid Lines: true Topic: /elevation_mapping/elevation_map_raw Unreliable: false - Use ColorMap: true + Use Rainbow: true Value: true - Alpha: 1 Class: rviz/RobotModel @@ -178,6 +174,30 @@ Visualization Manager: Use Fixed Frame: true Use rainbow: true Value: false + - Class: rviz/Image + Enabled: true + Image Topic: /camera/rgb/image_raw + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Queue Size: 2 + Transport Hint: raw + Unreliable: false + Value: true + - Class: rviz/Image + Enabled: true + Image Topic: /front_cam/elevation_mapping/semantic_image_front + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Queue Size: 2 + Transport Hint: raw + Unreliable: false + Value: true Enabled: true Global Options: Background Color: 255; 255; 255 @@ -222,9 +242,9 @@ Visualization Manager: Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.5947964191436768 + Pitch: 0.5147963762283325 Target Frame: base_footprint - Yaw: 3.0983715057373047 + Yaw: 3.1033706665039062 Saved: ~ Window Geometry: Displays: @@ -232,7 +252,9 @@ Window Geometry: Height: 1043 Hide Left Dock: false Hide Right Dock: true - QMainWindow State: 000000ff00000000fd0000000400000000000001f700000359fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000359000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007800000005afc0100000002fb0000000800540069006d0065010000000000000780000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000005830000035900000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Image: + collapsed: false + QMainWindow State: 000000ff00000000fd0000000400000000000001f70000035dfc020000000afb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003b000001aa000000c700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d00610067006501000001eb000000d30000001600fffffffb0000000a0049006d00610067006501000002c4000000d40000001600ffffff000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007800000005afc0100000002fb0000000800540069006d00650100000000000007800000030700fffffffb0000000800540069006d00650100000000000004500000000000000000000005830000035d00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -242,5 +264,5 @@ Window Geometry: Views: collapsed: true Width: 1920 - X: 1920 - Y: 0 + X: 2280 + Y: 105 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 4f49f86b..22fde76a 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -293,12 +293,15 @@ def compile_image_kernels(self): np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32, ) + # self.distance_correspondence = cp.asarray( + # np.zeros((self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32 + # ) # TODO tolerance_z_collision add parameter self.image_to_map_correspondence_kernel = image_to_map_correspondence_kernel( resolution=self.resolution, width=self.cell_n, height=self.cell_n, - tolerance_z_collision=0.1, + tolerance_z_collision=0.10, ) break @@ -487,6 +490,9 @@ def input_image( Returns: None: """ + print("input_image") + print("channels", channels) + print("fusion_methods", fusion_methods) image = np.stack(image, axis=0) if len(image.shape) == 2: image = image[None] @@ -509,6 +515,7 @@ def input_image( self.uv_correspondence *= 0 self.valid_correspondence[:, :] = False + # self.distance_correspondence *= 0.0 print("channels", channels) print("fusion_methods", fusion_methods) @@ -525,8 +532,10 @@ def input_image( self.center, self.uv_correspondence, self.valid_correspondence, + # self.distance_correspondence, size=int(self.cell_n * self.cell_n), ) + # print("distance_correspondence", self.distance_correspondence) self.semantic_map.update_layers_image( # sub_key, image, diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py index 0596af35..152e37bd 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py @@ -54,7 +54,7 @@ def get_plugin_idx(self, name: str, data_type: str): """ Get a registered fusion plugin """ - # name = data_type + "_" + name + name = data_type + "_" + name for idx, plugin in enumerate(self.plugins): if plugin.name == name: return idx diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py index 62f32c70..18873aa7 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py @@ -3,7 +3,12 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_collision): - image_to_map_correspondence_kernel = cp.ElementwiseKernel( + """ + This function calculates the correspondence between the image and the map. + It takes in the resolution, width, height, and tolerance_z_collision as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _image_to_map_correspondence_kernel = cp.ElementwiseKernel( in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U image_height, raw U image_width, raw U center", out_params="raw U uv_correspondence, raw B valid_correspondence", preamble=string.Template( @@ -52,7 +57,7 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_co u = u/d; v = v/d; - // filter point nexto image plane + // filter point next to image plane if ((u < 0) || (v < 0) || (u >= image_width) || (v >= image_height)){ return; } @@ -71,6 +76,8 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_co int dy = -abs(y1 - y0); int sy = y0 < y1 ? 1 : -1; int error = dx + dy; + + bool is_valid = true; // iterate over all cells along line while (1){ @@ -86,6 +93,7 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_co float dis = get_l2_distance(x0_c, y0_c, x0, y0); float rayheight = z0 + ( dis / total_dis * delta_z); if ( map[idx] - ${tolerance_z_collision} > rayheight){ + is_valid = false; break; } } @@ -113,16 +121,21 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_co // mark the correspondence uv_correspondence[get_map_idx(i, 0)] = u; uv_correspondence[get_map_idx(i, 1)] = v; - valid_correspondence[get_map_idx(i, 0)] = 1; + valid_correspondence[get_map_idx(i, 0)] = is_valid; """ ).substitute(height=height, width=width, resolution=resolution, tolerance_z_collision=tolerance_z_collision), name="image_to_map_correspondence_kernel", ) - return image_to_map_correspondence_kernel + return _image_to_map_correspondence_kernel -def average_correspondences_to_map_kernel(resolution, width, height): - average_correspondences_to_map_kernel = cp.ElementwiseKernel( +def average_correspondences_to_map_kernel(width, height): + """ + This function calculates the average correspondences to the map. + It takes in the width and height as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _average_correspondences_to_map_kernel = cp.ElementwiseKernel( in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", out_params="raw U new_sem_map", preamble=string.Template( @@ -148,11 +161,16 @@ def average_correspondences_to_map_kernel(resolution, width, height): ).substitute(), name="average_correspondences_to_map_kernel", ) - return average_correspondences_to_map_kernel + return _average_correspondences_to_map_kernel -def exponential_correspondences_to_map_kernel(resolution, width, height, alpha): - exponential_correspondences_to_map_kernel = cp.ElementwiseKernel( +def exponential_correspondences_to_map_kernel(width, height, alpha): + """ + This function calculates the exponential correspondences to the map. + It takes in the width, height, and alpha as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _exponential_correspondences_to_map_kernel = cp.ElementwiseKernel( in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", out_params="raw U new_sem_map", preamble=string.Template( @@ -178,11 +196,16 @@ def exponential_correspondences_to_map_kernel(resolution, width, height, alpha): ).substitute(alpha=alpha), name="exponential_correspondences_to_map_kernel", ) - return exponential_correspondences_to_map_kernel + return _exponential_correspondences_to_map_kernel -def color_correspondences_to_map_kernel(resolution, width, height): - color_correspondences_to_map_kernel = cp.ElementwiseKernel( +def color_correspondences_to_map_kernel(width, height): + """ + This function calculates the color correspondences to the map. + It takes in the width and height as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _color_correspondences_to_map_kernel = cp.ElementwiseKernel( in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", out_params="raw U new_sem_map", preamble=string.Template( @@ -217,4 +240,4 @@ def color_correspondences_to_map_kernel(resolution, width, height): ).substitute(), name="color_correspondences_to_map_kernel", ) - return color_correspondences_to_map_kernel + return _color_correspondences_to_map_kernel diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 5f926373..849f0022 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -93,8 +93,8 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) } } else if (type == "image") { - std::string camera_topic = subscriber.second["topic_name_camera"]; - std::string info_topic = subscriber.second["topic_name_camera_info"]; + std::string camera_topic = subscriber.second["topic_name"]; + std::string info_topic = subscriber.second["camera_info_topic_name"]; // Handle compressed images with transport hints // We obtain the hint from the last part of the topic name @@ -117,9 +117,23 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) cam_info_sub->subscribe(nh_, info_topic, 1); cameraInfoSubs_.push_back(cam_info_sub); - CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); - sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2)); - cameraSyncs_.push_back(sync); + std::string fusion_info_topic; + if (subscriber.second.hasMember("fusion_info_topic_name")) { + std::string fusion_info_topic = subscriber.second["fusion_info_topic_name"]; + FusionInfoSubscriberPtr fusion_info_sub = std::make_shared(); + fusion_info_sub->subscribe(nh_, fusion_info_topic, 1); + fusionInfoSubs_.push_back(fusion_info_sub); + CameraFusionSyncPtr sync = std::make_shared(CameraFusionPolicy(10), *image_sub, *cam_info_sub, *fusion_info_sub); + sync->registerCallback(boost::bind(&ElevationMappingNode::imageFusionCallback, this, _1, _2, _3)); + cameraFusionSyncs_.push_back(sync); + } + else { + ROS_INFO_STREAM("Fusion info topic not found"); + CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); + sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2)); + cameraSyncs_.push_back(sync); + } + } else { ROS_WARN_STREAM("Subscriber data_type [" << type << "] Not valid. Supported types: pointcloud, image"); @@ -401,7 +415,24 @@ void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image std::vector channels; std::vector fusion_methods; channels.push_back("rgb"); - fusion_methods.push_back("image_color"); + fusion_methods.push_back("color"); + inputImage(image_msg, camera_info_msg, channels, fusion_methods); + ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); +} + +void ElevationMappingNode::imageFusionCallback(const sensor_msgs::ImageConstPtr& image_msg, + const sensor_msgs::CameraInfoConstPtr& camera_info_msg, + const elevation_map_msgs::FusionInfoConstPtr& fusion_info_msg) { + auto start = ros::Time::now(); + // Default channels and fusion methods for image is rgb and image_color + std::vector channels; + std::vector fusion_methods; + channels = fusion_info_msg->channels; + fusion_methods = fusion_info_msg->fusion_methods; + ROS_INFO_STREAM("Channels: " << boost::algorithm::join(channels, ", ")); + ROS_INFO_STREAM("Fusion methods: " << boost::algorithm::join(fusion_methods, ", ")); + // channels.push_back("rgb"); + // fusion_methods.push_back("color"); inputImage(image_msg, camera_info_msg, channels, fusion_methods); ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); } diff --git a/sensor_processing/semantic_sensor/config/sensor_parameter.yaml b/sensor_processing/semantic_sensor/config/sensor_parameter.yaml index e448f9ab..ec21d93c 100644 --- a/sensor_processing/semantic_sensor/config/sensor_parameter.yaml +++ b/sensor_processing/semantic_sensor/config/sensor_parameter.yaml @@ -1,32 +1,65 @@ -subscribers: - # sensor_name: - # channels: ['feat_0','feat_1'] - # fusion: ['average','average'] - # topic_name: '/elevation_mapping/pointcloud_semantic' - front_cam: - channels: [ 'rgb' ] #'feat_0','feat_1','person','grass'] - fusion: [ 'color' ] #'average','average','class_average','class_average'] - topic_name: '/elvation_mapping/pointcloud_semantic' - semantic_segmentation: False - segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' - publish_segmentation_image: True - feature_extractor: False - feature_config: - name: 'DINO' - interpolation: 'bilinear' - model: "vit_small" - patch_size: 16 - dim: 5 - dropout: False - dino_feat_type: "feat" - input_size: [ 80, 160 ] - projection_type: "nonlinear" +# subscribers: +# # sensor_name: +# # channels: ['feat_0','feat_1'] +# # fusion: ['average','average'] +# # topic_name: '/elevation_mapping/pointcloud_semantic' +# front_cam: +# channels: [ 'rgb' ] #'feat_0','feat_1','person','grass'] +# fusion: [ 'color' ] #'average','average','class_average','class_average'] +# topic_name: '/elvation_mapping/pointcloud_semantic' +# semantic_segmentation: False +# segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' +# publish_segmentation_image: True +# feature_extractor: False +# feature_config: +# name: 'DINO' +# interpolation: 'bilinear' +# model: "vit_small" +# patch_size: 16 +# dim: 5 +# dropout: False +# dino_feat_type: "feat" +# input_size: [ 80, 160 ] +# projection_type: "nonlinear" - cam_info_topic: "/zed2i/zed_node/depth/camera_info" - image_topic: "/zed2i/zed_node/left/image_rect_color" - depth_topic: "/zed2i/zed_node/depth/depth_registered" - cam_frame: "zed2i_right_camera_optical_frame" - confidence_topic: "/zed2i/zed_node/confidence/confidence_map" - confidence_threshold: 10 +# cam_info_topic: "/zed2i/zed_node/depth/camera_info" +# image_topic: "/zed2i/zed_node/left/image_rect_color" +# depth_topic: "/zed2i/zed_node/depth/depth_registered" +# cam_frame: "zed2i_right_camera_optical_frame" +# confidence_topic: "/zed2i/zed_node/confidence/confidence_map" +# confidence_threshold: 10 +front_cam_pointcloud: + channels: ['rgb', 'chair','sofa',"person" ] + fusion: ['color','class_average','class_average','class_average'] + topic_name: 'front_camera/semantic_pointcloud' + semantic_segmentation: True + publish_segmentation_image: True + segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large + show_label_legend: False + data_type: pointcloud + cam_info_topic: "/camera/depth/camera_info" + image_topic: "/camera/rgb/image_raw" + depth_topic: "/camera/depth/image_raw" + cam_frame: "camera_rgb_optical_frame" + +front_cam_image: + channels: ['chair','sofa',"person"] + fusion_methods: ['exponential','exponential','exponential'] + publish_topic: 'semantic_image' + publish_image_topic: "semantic_image_debug" + publish_camera_info_topic: 'semantic_image_info' + publish_fusion_info_topic: 'semantic_image_fusion_info' + data_type: image + + semantic_segmentation: True + # segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large + segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large + show_label_legend: False + image_topic: "/camera/rgb/image_raw" + image_info_topic: "/camera/depth/camera_info" + resize: 0.5 + + # sem_seg_topic: "semantic_front" + # sem_seg_image_topic: "semantic_image_front" diff --git a/sensor_processing/semantic_sensor/launch/semantic_image.launch b/sensor_processing/semantic_sensor/launch/semantic_image.launch new file mode 100644 index 00000000..8b6c01a1 --- /dev/null +++ b/sensor_processing/semantic_sensor/launch/semantic_image.launch @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py index 8c0934e1..8a89c81e 100755 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py @@ -22,6 +22,8 @@ from semantic_sensor.networks import resolve_model from sklearn.decomposition import PCA +from elevation_map_msgs.msg import FusionInfo + class SemanticSegmentationNode: def __init__(self, sensor_name): @@ -33,9 +35,9 @@ def __init__(self, sensor_name): # TODO: if this is going to be loaded from another package we might need to change namespace self.param: ImageParameter = ImageParameter() self.param.feature_config.input_size = [80, 160] - namesp = rospy.get_name() - if rospy.has_param(namesp + "/subscribers"): - config = rospy.get_param(namesp + "/subscribers") + namespace = rospy.get_name() + if rospy.has_param(namespace): + config = rospy.get_param(namespace) self.param: ImageParameter = ImageParameter.from_dict(config[sensor_name]) else: print("NO ROS ENV found.") @@ -66,10 +68,12 @@ def initialize_semantics(self): def register_sub_pub(self): """Register publishers and subscribers.""" + + node_name = rospy.get_name() # subscribers if self.param.image_info_topic is not None and self.param.resize is not None: rospy.Subscriber(self.param.image_info_topic, CameraInfo, self.image_info_callback) - self.feat_im_info_pub = rospy.Publisher(self.param.image_info_topic + "_resized", CameraInfo, queue_size=2) + self.feat_im_info_pub = rospy.Publisher(node_name + "/" + self.param.image_info_topic + "_resized", CameraInfo, queue_size=2) if "compressed" in self.param.image_topic: self.compressed = True @@ -82,14 +86,16 @@ def register_sub_pub(self): # publishers if self.param.semantic_segmentation: - self.seg_pub = rospy.Publisher(self.param.sem_seg_topic, Image, queue_size=2) - self.seg_im_pub = rospy.Publisher(self.param.sem_seg_image_topic, Image, queue_size=2) + self.seg_pub = rospy.Publisher(node_name + "/" + self.param.publish_topic, Image, queue_size=2) + self.seg_im_pub = rospy.Publisher(node_name + "/" + self.param.publish_image_topic, Image, queue_size=2) self.semseg_color_map = self.color_map(len(self.param.channels)) if self.param.show_label_legend: self.color_map_viz() if self.param.feature_extractor: - self.feature_pub = rospy.Publisher(self.param.feature_topic, Image, queue_size=2) - self.feat_im_pub = rospy.Publisher(self.param.feat_image_topic, Image, queue_size=2) + self.feature_pub = rospy.Publisher(node_name + "/" + self.param.feature_topic, Image, queue_size=2) + self.feat_im_pub = rospy.Publisher(node_name + "/" + self.param.feat_image_topic, Image, queue_size=2) + + self.fusion_info_pub = rospy.Publisher(node_name + "/" + self.param.fusion_info_topic, FusionInfo, queue_size=2) def color_map(self, N=256, normalized=False): """Create a color map for the class labels. @@ -171,15 +177,25 @@ def image_callback(self, rgb_msg): if self.param.semantic_segmentation: self.publish_segmentation() self.publish_segmentation_image() + self.publish_fusion_info() if self.param.feature_extractor: self.publish_feature() self.publish_feature_image(self.features) + self.publish_fusion_info() if self.param.resize is not None: self.pub_info() def pub_info(self): self.feat_im_info_pub.publish(self.info) + def publish_fusion_info(self): + """Publish fusion info.""" + info = FusionInfo() + info.header = self.header + info.channels = self.param.channels + info.fusion_methods = self.param.fusion_methods + self.fusion_info_pub.publish(info) + def process_image(self, image): """Depending on setting generate color, semantic segmentation or feature channels. diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py index 01f68cfa..014bd9b9 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py @@ -21,17 +21,21 @@ class ImageParameter(Serializable): image_topic: str = "/alphasense_driver_ros/cam4/debayered" semantic_segmentation: bool = True - sem_seg_topic: str = "/elevation_mapping/semantic_seg" - sem_seg_image_topic: str = "/elevation_mapping/semantic_seg_im" + # sem_seg_topic: str = "semantic_seg" + # sem_seg_image_topic: str = "semantic_seg_im" + publish_topic: str = "semantic_seg" + publish_image_topic: str = "semantic_seg_img" + # publish_camera_info_topic: str = "semantic_seg/camera_info" segmentation_model: str = "detectron_coco_panoptic_fpn_R_101_3x" show_label_legend: bool = False channels: list = field(default_factory=lambda: ["grass", "road", "tree", "sky"]) - fusion: list = field(default_factory=lambda: ["class_average", "class_average", "class_average", "class_average"]) + fusion_methods: list = field(default_factory=lambda: ["class_average", "class_average", "class_average", "class_average"]) feature_extractor: bool = False feature_config: FeatureExtractorParameter = FeatureExtractorParameter # feature_config.input_size: list = field(default_factory=lambda: [80, 160]) - feature_topic: str = "/elevation_mapping/semantic_seg_feat" - feat_image_topic: str = "/elevation_mapping/semantic_seg_feat_im" + feature_topic: str = "semantic_seg_feat" + feat_image_topic: str = "semantic_seg_feat_im" + fusion_info_topic: str = "fusion_info" resize: float = None - image_info_topic: str = "/elevation_mapping/image_info" + image_info_topic: str = "image_info" \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py index 39847e68..df7c578c 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py @@ -118,10 +118,10 @@ def resolve_categories(self): indices.append(class_to_idx[chan]) channels.append(chan) self.actual_channels.append(chan) - elif self.param.fusion[it] in ["class_average", "class_bayesian"]: + elif self.param.fusion_methods[it] in ["class_average", "class_bayesian"]: print(chan, " is not in the semantic segmentation model.") for it, chan in enumerate(self.param.channels): - if self.param.fusion[it] in ["class_max"]: + if self.param.fusion_methods[it] in ["class_max"]: self.actual_channels.append(chan) print( chan, @@ -133,7 +133,7 @@ def resolve_categories(self): self.segmentation_channels = dict(zip(channels, indices)) def __call__(self, image, *args, **kwargs): - """Feewforward image through model and then create channels + """Feedforward image through model and then create channels Args: image (cupy._core.core.ndarray): @@ -152,7 +152,7 @@ def __call__(self, image, *args, **kwargs): selected_masks = cp.asarray(normalized_masks[list(self.stuff_categories.values())]) # get values of max, first remove the ones we already have normalized_masks[list(self.stuff_categories.values())] = 0 - for i in range(self.param.fusion.count("class_max")): + for i in range(self.param.fusion_methods.count("class_max")): maxim, index = torch.max(normalized_masks, dim=0) mer = encode_max(maxim, index) selected_masks = cp.concatenate((selected_masks, cp.expand_dims(mer, axis=0)), axis=0) @@ -183,7 +183,7 @@ def __init__(self, weights, param): # Find a model from detectron2's model zoo. You can use the https://dl.fbaipublicfiles... url as well self.cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(weights) self.predictor = DefaultPredictor(self.cfg) - self.meta = MetadataCatalog.get(self.cfg.DATASETS.TRAIN[0]) + self.metadata = MetadataCatalog.get(self.cfg.DATASETS.TRAIN[0]) self.stuff_categories, self.is_stuff = self.resolve_categories("stuff_classes") self.thing_categories, self.is_thing = self.resolve_categories("thing_classes") self.segmentation_channels = {} @@ -198,7 +198,7 @@ def __init__(self, weights, param): self.actual_channels = self.segmentation_channels.keys() def resolve_categories(self, name): - classes = self.get_cat(name) + classes = self.get_category(name) class_to_idx = {cls: idx for (idx, cls) in enumerate(classes)} print( "Semantic Segmentation possible channels: ", @@ -207,17 +207,17 @@ def resolve_categories(self, name): indices = [] channels = [] is_thing = [] - for it, chan in enumerate(self.param.channels): - if chan in [cls for cls in list(class_to_idx.keys())]: - indices.append(class_to_idx[chan]) - channels.append(chan) + for it, channel in enumerate(self.param.channels): + if channel in [cls for cls in list(class_to_idx.keys())]: + indices.append(class_to_idx[channel]) + channels.append(channel) is_thing.append(True) - elif self.param.fusion[it] in ["class_average", "class_bayesian"]: + elif self.param.fusion_methods[it] in ["class_average", "class_bayesian"]: is_thing.append(False) - print(chan, " is not in the semantic segmentation model.") + print(channel, " is not in the semantic segmentation model.") categories = dict(zip(channels, indices)) - cat_isthing = dict(zip(self.param.channels, is_thing)) - return categories, cat_isthing + category_isthing = dict(zip(self.param.channels, is_thing)) + return categories, category_isthing def __call__(self, image, *args, **kwargs): # TODO: there are some instruction on how to change input type @@ -234,23 +234,23 @@ def __call__(self, image, *args, **kwargs): # add semseg output[cp.array(list(self.is_stuff.values()))] = probabilities[list(self.stuff_categories.values())] # add instances - indices, insta_info = prediction["panoptic_seg"] + indices, instance_info = prediction["panoptic_seg"] # TODO dont know why i need temp, look into how to avoid temp = output[cp.array(list(self.is_thing.values()))] - for i, insta in enumerate(insta_info): - if insta is None or not insta["isthing"]: + for i, instance in enumerate(instance_info): + if instance is None or not instance["isthing"]: continue - mask = cp.asarray((indices == insta["id"]).int()) - if insta["instance_id"] in self.thing_categories.values(): - temp[i] = mask * insta["score"] + mask = cp.asarray((indices == instance["id"]).int()) + if instance["instance_id"] in self.thing_categories.values(): + temp[i] = mask * instance["score"] output[cp.array(list(self.is_thing.values()))] = temp return output - def get_cat(self, name): - return self.meta.get(name) + def get_category(self, name): + return self.metadata.get(name) def get_classes(self): - return self.get_cat("thing_classes") + self.get_cat("stuff_classes") + return self.get_category("thing_classes") + self.get_category("stuff_classes") class STEGOModel: From 79a123c78b4268e071c18abedf8c60b18047ccca Mon Sep 17 00:00:00 2001 From: Takahiro Date: Mon, 4 Dec 2023 14:05:13 +0100 Subject: [PATCH 378/504] Cleaned up and using channel_info for image topic. --- elevation_map_msgs/CMakeLists.txt | 2 +- elevation_map_msgs/msg/ChannelInfo.msg | 2 + elevation_map_msgs/msg/FusionInfo.msg | 3 - elevation_mapping_cupy/compile_commands.json | 1 + .../anymal/anymal_sensor_parameter.yaml | 40 ++--- .../turtle_bot/turtle_bot_semantics.yaml | 47 +++--- .../setups/turtle_bot/turtle_bot_simple.yaml | 15 +- .../elevation_mapping_ros.hpp | 36 +++-- .../elevation_mapping_wrapper.hpp | 2 +- .../elevation_mapping.py | 12 +- .../elevation_mapping_cupy/parameter.py | 29 +--- .../plugins/plugin_manager.py | 2 +- .../elevation_mapping_cupy/semantic_map.py | 102 ++++++------- .../src/elevation_mapping_ros.cpp | 137 ++++++++++-------- .../src/elevation_mapping_wrapper.cpp | 34 ++++- 15 files changed, 236 insertions(+), 228 deletions(-) create mode 100644 elevation_map_msgs/msg/ChannelInfo.msg delete mode 100644 elevation_map_msgs/msg/FusionInfo.msg create mode 120000 elevation_mapping_cupy/compile_commands.json diff --git a/elevation_map_msgs/CMakeLists.txt b/elevation_map_msgs/CMakeLists.txt index 653174ef..2d73f5e5 100644 --- a/elevation_map_msgs/CMakeLists.txt +++ b/elevation_map_msgs/CMakeLists.txt @@ -11,7 +11,7 @@ find_package(catkin REQUIRED COMPONENTS add_message_files( FILES Statistics.msg - FusionInfo.msg + ChannelInfo.msg ) ## Generate services in the 'srv' folder diff --git a/elevation_map_msgs/msg/ChannelInfo.msg b/elevation_map_msgs/msg/ChannelInfo.msg new file mode 100644 index 00000000..bccf1447 --- /dev/null +++ b/elevation_map_msgs/msg/ChannelInfo.msg @@ -0,0 +1,2 @@ +Header header +string[] channels # channel names for each layer \ No newline at end of file diff --git a/elevation_map_msgs/msg/FusionInfo.msg b/elevation_map_msgs/msg/FusionInfo.msg deleted file mode 100644 index 4cfd1718..00000000 --- a/elevation_map_msgs/msg/FusionInfo.msg +++ /dev/null @@ -1,3 +0,0 @@ -Header header -string[] channels # channel names for each layer -string[] fusion_methods # fusion methods to use for each channel \ No newline at end of file diff --git a/elevation_mapping_cupy/compile_commands.json b/elevation_mapping_cupy/compile_commands.json new file mode 120000 index 00000000..2fdee343 --- /dev/null +++ b/elevation_mapping_cupy/compile_commands.json @@ -0,0 +1 @@ +/home/takahiro/catkin_ws/build/elevation_mapping_cupy/compile_commands.json \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml index 90cc74fb..4ad52176 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml @@ -1,5 +1,15 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/anymal/anymal_plugin_config.yaml' +pointcloud_channel_fusions: + rgb: 'color' + default: 'average' + +image_channel_fusions: + rgb: 'color' + default: 'exponential' + feat_.*: 'exponential' + sem_.*: 'exponential' + #### Publishers ######## # topic_name: # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names @@ -8,7 +18,7 @@ plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/anymal publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance'] + layers: ['elevation', 'traversability', 'variance', 'rgb'] basic_layers: ['elevation', 'traversability'] fps: 5.0 @@ -20,55 +30,47 @@ publishers: #### Subscribers ######## subscribers: front_upper_depth: - channels: [] - fusion: [] topic_name: /depth_camera_front_upper/point_cloud_self_filtered data_type: pointcloud front_lower_depth: - channels: [] - fusion: [] topic_name: /depth_camera_front_lower/point_cloud_self_filtered data_type: pointcloud rear_upper_depth: - channels: [] - fusion: [] topic_name: /depth_camera_rear_upper/point_cloud_self_filtered data_type: pointcloud rear_lower_depth: - channels: [] - fusion: [] topic_name: /depth_camera_rear_lower/point_cloud_self_filtered data_type: pointcloud left_depth: - channels: [] - fusion: [] topic_name: /depth_camera_left/point_cloud_self_filtered data_type: pointcloud right_depth: - channels: [] - fusion: [] topic_name: /depth_camera_right/point_cloud_self_filtered data_type: pointcloud + front_wide_angle: + topic_name: /wide_angle_camera_front/image_raw + camera_info_topic_name: /wide_angle_camera_front/camera_info + data_type: image + + rear_wide_angle: + topic_name: /wide_angle_camera_rear/image_raw + camera_info_topic_name: /wide_angle_camera_rear/camera_info + data_type: image + # velodyne: - # channels: [] - # fusion: [] # topic_name: /point_cloud_filter/lidar/point_cloud_filtered # data_type: pointcloud front_bpearl: - channels: [] - fusion: [] topic_name: /robot_self_filter/bpearl_front/point_cloud data_type: pointcloud rear_bpearl: - channels: [] - fusion: [] topic_name: /robot_self_filter/bpearl_rear/point_cloud data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml index 9c4019bb..63d3b2b9 100644 --- a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml @@ -1,47 +1,40 @@ #### Plugins ######## plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/turtle_bot/plugin_config.yaml' -pointcloud_channel_fusion: +pointcloud_channel_fusions: + none: 'none' + # rgb: 'color' + # default: 'average' + +image_channel_fusions: rgb: 'color' - default: 'average' - sheep: 'average' - sofa: 'class_average' - person: 'class_average' + default: 'exponential' + feat_.*: 'exponential' #### Subscribers ######## subscribers: color_cam: # for color camera - # channels: ['rgb'] - # fusion: ['color'] topic_name: '/camera/rgb/image_raw' camera_info_topic_name: '/camera/depth/camera_info' data_type: image - # front_cam: - # channels: ['rgb', 'sheep','sofa',"person" ] - # fusion: [ 'color','class_average','class_average','class_average' ] - # topic_name: '/elevation_mapping/pointcloud_semantic' - # semantic_segmentation: True - # publish_segmentation_image: True - # segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large - # show_label_legend: False - - # cam_info_topic: "/camera/rgb/camera_info" - # image_topic: "/camera/rgb/image_raw" - # cam_frame: "camera_rgb_optical_frame" - # data_type: image - # depth_topic: "/camera/depth/image_raw" - semantic_cam: # for color camera - # channels: ['rgb'] - # fusion: ['color'] + semantic_cam: # for semantic images topic_name: '/front_cam/semantic_image' camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' - fusion_info_topic_name: '/front_cam/fusion_info' + channel_info_topic_name: '/front_cam/channel_info' data_type: image + # fixed_semantic_cam: # for semantic images + # topic_name: '/front_cam/semantic_image' + # camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' + # channels: ["test", "test2", "test3"] + # data_type: image front_cam_pointcloud: - channels: [] - fusion: [] topic_name: '/camera/depth/points' data_type: pointcloud + feat_front: + topic_name: /elevation_mapping/feat_f + camera_info_topic_name: "/camera/depth/camera_info" + channels: [ 'feat_0','feat_1','feat_2','feat_3','feat_4','feat_5','feat_6','feat_7','feat_8','feat_9' ] + data_type: image #### Publishers ######## diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml index cfa3b3cb..a76fcc61 100644 --- a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml @@ -1,11 +1,14 @@ +pointcloud_channel_fusions: + rgb: 'color' + default: 'average' + +image_channel_fusions: + rgb: 'color' + default: 'exponential' + feat_.*: 'exponential' + subscribers: -# sensor_name: -# channels: ['feat_0','feat_1'] -# fusion: ['average','average'] -# topic_name: '/elevation_mapping/pointcloud_semantic' front_cam: - channels: ['rgb' ] - fusion: [ 'color'] topic_name: '/camera/depth/points' data_type: pointcloud diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index ab873aa1..0149ffad 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -49,7 +49,7 @@ #include #include -#include +#include #include "elevation_mapping_cupy/elevation_mapping_wrapper.hpp" @@ -65,26 +65,37 @@ class ElevationMappingNode { using ImageSubscriber = image_transport::SubscriberFilter; using ImageSubscriberPtr = std::shared_ptr; + + // Subscriber and Synchronizer for CameraInfo messages using CameraInfoSubscriber = message_filters::Subscriber; using CameraInfoSubscriberPtr = std::shared_ptr; using CameraPolicy = message_filters::sync_policies::ApproximateTime; using CameraSync = message_filters::Synchronizer; using CameraSyncPtr = std::shared_ptr; - using FusionInfoSubscriber = message_filters::Subscriber; - using FusionInfoSubscriberPtr = std::shared_ptr; - using CameraFusionPolicy = message_filters::sync_policies::ApproximateTime; - using CameraFusionSync = message_filters::Synchronizer; - using CameraFusionSyncPtr = std::shared_ptr; + // Subscriber and Synchronizer for ChannelInfo messages + using ChannelInfoSubscriber = message_filters::Subscriber; + using ChannelInfoSubscriberPtr = std::shared_ptr; + using CameraChannelPolicy = message_filters::sync_policies::ApproximateTime; + using CameraChannelSync = message_filters::Synchronizer; + using CameraChannelSyncPtr = std::shared_ptr; + + // Subscriber and Synchronizer for Pointcloud messages + using PointCloudSubscriber = message_filters::Subscriber; + using PointCloudSubscriberPtr = std::shared_ptr; + using PointCloudPolicy = message_filters::sync_policies::ApproximateTime; + using PointCloudSync = message_filters::Synchronizer; + using PointCloudSyncPtr = std::shared_ptr; private: void readParameters(); void setupMapPublishers(); void pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key); - void inputImage(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, - const std::vector& channels, const std::vector& fusion_methods); - void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg); - void imageFusionCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const elevation_map_msgs::FusionInfoConstPtr& fusion_info_msg); + void inputPointCloud(const sensor_msgs::PointCloud2& cloud, const std::vector& channels); + void inputImage(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::vector& channels); + void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::string& key); + void imageChannelCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg); + void pointCloudChannelCallback(const sensor_msgs::PointCloud2& cloud, const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg); // void multiLayerImageCallback(const elevation_map_msgs::MultiLayerImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg); void publishAsPointCloud(const grid_map::GridMap& map) const; bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); @@ -110,9 +121,10 @@ class ElevationMappingNode { std::vector pointcloudSubs_; std::vector imageSubs_; std::vector cameraInfoSubs_; - std::vector fusionInfoSubs_; + std::vector channelInfoSubs_; std::vector cameraSyncs_; - std::vector cameraFusionSyncs_; + std::vector cameraChannelSyncs_; + std::vector pointCloudSyncs_; std::vector mapPubs_; tf::TransformBroadcaster tfBroadcaster_; ros::Publisher alivePub_; diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index b6d633da..116403e6 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -48,7 +48,7 @@ class ElevationMappingWrapper { void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); - void input_image(const std::vector& multichannel_image, const std::vector& channels, const std::vector& fusion_methods, const RowMatrixXd& R, + void input_image(const std::vector& multichannel_image, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, int height, int width); void move_to(const Eigen::VectorXd& p, const RowMatrixXd& R); void clear(); diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 22fde76a..e7011529 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -469,7 +469,7 @@ def input_image( self, image: List[cp._core.core.ndarray], channels: List[str], - fusion_methods: List[str], + # fusion_methods: List[str], R: cp._core.core.ndarray, t: cp._core.core.ndarray, K: cp._core.core.ndarray, @@ -490,9 +490,6 @@ def input_image( Returns: None: """ - print("input_image") - print("channels", channels) - print("fusion_methods", fusion_methods) image = np.stack(image, axis=0) if len(image.shape) == 2: image = image[None] @@ -517,9 +514,6 @@ def input_image( self.valid_correspondence[:, :] = False # self.distance_correspondence *= 0.0 - print("channels", channels) - print("fusion_methods", fusion_methods) - with self.map_lock: self.image_to_map_correspondence_kernel( self.elevation_map, @@ -532,15 +526,11 @@ def input_image( self.center, self.uv_correspondence, self.valid_correspondence, - # self.distance_correspondence, size=int(self.cell_n * self.cell_n), ) - # print("distance_correspondence", self.distance_correspondence) self.semantic_map.update_layers_image( - # sub_key, image, channels, - fusion_methods, self.uv_correspondence, self.valid_correspondence, image_height, diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 40ac3dd9..88b111ed 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -16,26 +16,12 @@ class Parameter(Serializable): subscriber_cfg: dict = field( default_factory=lambda: { "front_cam": { - "cam_frame": "zed2i_right_camera_optical_frame", - "cam_info_topic": "/zed2i/zed_node/depth/camera_info", "channels": ["rgb", "person"], - "confidence": True, - "confidence_threshold": 10, - "confidence_topic": "/zed2i/zed_node/confidence/confidence_map", - "depth_topic": "/zed2i/zed_node/depth/depth_registered", - "feature_extractor": False, - "fusion": ["color", "class_average"], - "image_topic": "/zed2i/zed_node/left/image_rect_color", - "segmentation_model": "lraspp_mobilenet_v3_large", - "semantic_segmentation": True, - "show_label_legend": True, "topic_name": "/elevation_mapping/pointcloud_semantic", "data_type": "pointcloud", } } ) - # additional_layers: list = field(default_factory=lambda: ["feat_0"]) - # fusion_algorithms: list = field(default_factory=lambda: ["average"]) additional_layers: list = field(default_factory=lambda: ["color"]) fusion_algorithms: list = field(default_factory=lambda: [ "image_color", @@ -46,7 +32,8 @@ class Parameter(Serializable): "pointcloud_class_bayesian", "pointcloud_class_max", "pointcloud_color"]) - pointcloud_channel_fusion: dict = field(default_factory=lambda: {"rgb": "pointcloud_color", "default": "pointcloud_class_average"}) + pointcloud_channel_fusions: dict = field(default_factory=lambda: {"rgb": "color", "default": "class_average"}) + image_channel_fusions: dict = field(default_factory=lambda: {"rgb": "color", "default": "exponential"}) data_type: str = np.float32 average_weight: float = 0.5 @@ -138,18 +125,6 @@ def update(self): self.cell_n = int(round(self.map_length / self.resolution)) + 2 self.true_cell_n = round(self.map_length / self.resolution) self.true_map_length = self.true_cell_n * self.resolution - # semantic_layers = [] - # fusion_algorithms = [] - # for subscriber, sub_val in self.subscriber_cfg.items(): - # channels = sub_val["channels"] - # fusion = sub_val["fusion"] - # for i in range(len(channels)): - # name = channels[i] - # if name not in semantic_layers: - # semantic_layers.append(name) - # fusion_algorithms.append(fusion[i]) - # self.additional_layers = semantic_layers - # self.fusion_algorithms = fusion_algorithms if __name__ == "__main__": diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index fd1185e1..b5c2d313 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -146,7 +146,7 @@ def update_with_name( elements_to_shift={}, ): idx = self.get_layer_index_with_name(name) - if idx is not None: + if idx is not None and idx < len(self.plugins): n_param = len(signature(self.plugins[idx]).parameters) if n_param == 5: self.layers[idx] = self.plugins[idx](elevation_map, layer_names, self.layers, self.layer_names) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index e33585f1..6b7291ca 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -1,7 +1,9 @@ from elevation_mapping_cupy.parameter import Parameter import cupy as cp import numpy as np -from typing import List +from typing import List, Dict +import re + from elevation_mapping_cupy.fusion.fusion_manager import FusionManager @@ -18,36 +20,13 @@ def __init__(self, param: Parameter): self.param = param - self.layer_specs = {} + self.layer_specs_points = {} + self.layer_specs_image = {} self.layer_names = [] self.unique_fusion = [] self.unique_data = [] self.elements_to_shift = {} - # for k, config in self.param.subscriber_cfg.items(): - # for f, c in zip(config["fusion"], config["channels"]): - # if c not in self.layer_names: - # self.layer_names.append(c) - # self.layer_specs[c] = f - # else: - # assert self.layer_specs[c] == f, "Error: Single layer has multiple fusion algorithms!" - # if f not in self.unique_fusion: - # dt = config["data_type"] - # self.unique_fusion.append(dt + "_" + f) - for channel, fusion in self.param.pointcloud_channel_fusion.items(): - if channel not in self.layer_names: - if channel != "default": - self.layer_names.append(channel) - self.layer_specs[channel] = fusion - else: - assert self.layer_specs[channel] == fusion, "Error: Single layer has multiple fusion algorithms!" - # for f, c in zip(config["fusion"], config["channels"]): - # else: - # assert self.layer_specs[c] == f, "Error: Single layer has multiple fusion algorithms!" - # if f not in self.unique_fusion: - # dt = config["data_type"] - # self.unique_fusion.append(dt + "_" + f) - self.layer_names += self.param.additional_layers self.unique_fusion = self.param.fusion_algorithms self.amount_layer_names = len(self.layer_names) @@ -73,10 +52,10 @@ def initialize_fusion(self): """Initialize the fusion algorithms.""" for fusion in self.unique_fusion: if "pointcloud_class_bayesian" == fusion: - pcl_ids = self.get_layer_indices("class_bayesian") + pcl_ids = self.get_layer_indices("class_bayesian", self.layer_specs_points) self.delete_new_layers[pcl_ids] = 0 if "pointcloud_class_max" == fusion: - pcl_ids = self.get_layer_indices("class_max") + pcl_ids = self.get_layer_indices("class_max", self.layer_specs_points) self.delete_new_layers[pcl_ids] = 0 layer_cnt = self.param.fusion_algorithms.count("class_max") id_max = cp.zeros( @@ -87,12 +66,15 @@ def initialize_fusion(self): self.fusion_manager.register_plugin(fusion) def update_fusion_setting(self): + """ + Update the fusion settings. + """ for fusion in self.unique_fusion: if "pointcloud_class_bayesian" == fusion: - pcl_ids = self.get_layer_indices("class_bayesian") + pcl_ids = self.get_layer_indices("class_bayesian", self.layer_specs_points) self.delete_new_layers[pcl_ids] = 0 if "pointcloud_class_max" == fusion: - pcl_ids = self.get_layer_indices("class_max") + pcl_ids = self.get_layer_indices("class_max", self.layer_specs_points) self.delete_new_layers[pcl_ids] = 0 layer_cnt = self.param.fusion_algorithms.count("class_max") id_max = cp.zeros( @@ -165,7 +147,7 @@ def shift_map_xy(self, shift_value): el = cp.roll(el, shift_value, axis=(1, 2)) self.pad_value(el, shift_value, value=0.0) - def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: + def get_fusion(self, channels: List[str], channel_fusions: Dict[str, str], layer_specs: Dict[str, str]) -> List[str]: """Get all fusion algorithms that need to be applied to a specific pointcloud. Args: @@ -174,24 +156,38 @@ def get_fusion_of_pcl(self, channels: List[str]) -> List[str]: fusion_list = [] process_channels = [] for channel in channels: - if channel not in self.layer_specs: + if channel not in layer_specs: # If the channel is not in the layer_specs, we use the default fusion algorithm - if "default" in self.param.pointcloud_channel_fusion: - default_fusion = self.param.pointcloud_channel_fusion["default"] - print(f"[WARNING] Layer {channel} not found in layer_specs. Using {default_fusion} algorithm as default.") - self.layer_specs[channel] = default_fusion - self.update_fusion_setting() - # If there's no default fusion algorithm, we skip this channel + matched_fusion = self.get_matching_fusion(channel, channel_fusions) + if matched_fusion is None: + if "default" in channel_fusions: + default_fusion = channel_fusions["default"] + print(f"[WARNING] Layer {channel} not found in layer_specs. Using {default_fusion} algorithm as default.") + layer_specs[channel] = default_fusion + self.update_fusion_setting() + # If there's no default fusion algorithm, we skip this channel + else: + print(f"[WARNING] Layer {channel} not found in layer_specs ({layer_specs}) and no default fusion is configured. Skipping.") + continue else: - print(f"[WARNING] Layer {channel} not found in layer_specs. Skipping.") - continue - x = self.layer_specs[channel] + layer_specs[channel] = matched_fusion + self.update_fusion_setting() + x = layer_specs[channel] if x not in fusion_list: fusion_list.append(x) process_channels.append(channel) return process_channels, fusion_list - def get_layer_indices(self, fusion_alg): + + def get_matching_fusion(self, channel: str, fusion_algs: Dict[str, str]): + """ Use regular expression to check if the fusion algorithm matches the channel name.""" + for fusion_alg, alg_value in fusion_algs.items(): + if re.match(f"^{fusion_alg}$", channel): + return alg_value + return None + + + def get_layer_indices(self, fusion_alg, layer_specs): """Get the indices of the layers that are used for a specific fusion algorithm. Args: @@ -201,12 +197,12 @@ def get_layer_indices(self, fusion_alg): cp.array: indices of the layers """ layer_indices = cp.array([], dtype=cp.int32) - for it, (key, val) in enumerate(self.layer_specs.items()): + for it, (key, val) in enumerate(layer_specs.items()): if key in val == fusion_alg: layer_indices = cp.append(layer_indices, it).astype(cp.int32) return layer_indices - def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): + def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str, layer_specs: Dict[str, str]): """Computes the indices of the channels of the pointcloud and the layers of the semantic map of type fusion_alg. Args: @@ -219,7 +215,7 @@ def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): """ # this contains exactly the fusion alg type for each channel of the pcl - pcl_val_list = [self.layer_specs[x] for x in pcl_channels] + pcl_val_list = [layer_specs[x] for x in pcl_channels] # this contains the indices of the point cloud where we have to perform a certain fusion pcl_indices = cp.array( [idp + 3 for idp, x in enumerate(pcl_val_list) if x == fusion_alg], @@ -227,7 +223,7 @@ def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str): ) # create a list of indices of the layers that will be updated by the point cloud with specific fusion alg layer_indices = cp.array([], dtype=cp.int32) - for it, (key, val) in enumerate(self.layer_specs.items()): + for it, (key, val) in enumerate(layer_specs.items()): if key in pcl_channels and val == fusion_alg: layer_idx = self.layer_names.index(key) layer_indices = cp.append(layer_indices, layer_idx).astype(cp.int32) @@ -243,7 +239,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): t: translation vector elevation_map: elevation map object """ - process_channels, additional_fusion = self.get_fusion_of_pcl(channels) + process_channels, additional_fusion = self.get_fusion(channels, self.param.pointcloud_channel_fusions, self.layer_specs_points) # If channels has a new layer that is not in the semantic map, add it for channel in process_channels: if channel not in self.layer_names: @@ -254,7 +250,7 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): self.new_map[self.delete_new_layers] = 0.0 for fusion in list(set(additional_fusion)): # which layers need to be updated with this fusion algorithm - pcl_ids, layer_ids = self.get_indices_fusion(process_channels, fusion) + pcl_ids, layer_ids = self.get_indices_fusion(process_channels, fusion, self.layer_specs_points) # update the layers with the fusion algorithm self.fusion_manager.execute_plugin( fusion, @@ -274,7 +270,7 @@ def update_layers_image( # sub_key: str, image: cp._core.core.ndarray, channels: List[str], - fusion_methods: List[str], + # fusion_methods: List[str], uv_correspondence: cp._core.core.ndarray, valid_correspondence: cp._core.core.ndarray, image_height: cp._core.core.ndarray, @@ -292,11 +288,12 @@ def update_layers_image( """ # additional_fusion = self.get_fusion_of_pcl(channels) + process_channels, fusion_methods = self.get_fusion(channels, self.param.image_channel_fusions, self.layer_specs_image) self.new_map[self.delete_new_layers] = 0.0 # config = self.param.subscriber_cfg[sub_key] # for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): - for j, (fusion, channel) in enumerate(zip(fusion_methods, channels)): + for j, (fusion, channel) in enumerate(zip(fusion_methods, process_channels)): if channel not in self.layer_names: print(f"Layer {channel} not found, adding it to the semantic map") self.add_layer(channel) @@ -350,7 +347,10 @@ def get_map_with_name(self, name): cp.array: map """ # If the layer is a color layer, return the rgb map - if name in self.layer_specs and (self.layer_specs[name] == "image_color" or self.layer_specs[name] == "pointcloud_color"): + if name in self.layer_specs_points and self.layer_specs_points[name] == "color": + m = self.get_rgb(name) + return m + elif name in self.layer_specs_image and self.layer_specs_image[name] == "color": m = self.get_rgb(name) return m else: diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 849f0022..21412e95 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -80,19 +80,14 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) // Initialize subscribers depending on the type if (type == "pointcloud") { std::string pointcloud_topic = subscriber.second["topic_name"]; - boost::function f = boost::bind(&ElevationMappingNode::pointcloudCallback, this, _1, key); - ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, f); - pointcloudSubs_.push_back(sub); - const auto& channels = subscriber.second["channels"]; channels_[key].push_back("x"); channels_[key].push_back("y"); channels_[key].push_back("z"); - for (int32_t i = 0; i < channels.size(); ++i) { - auto elem = static_cast(channels[i]); - channels_[key].push_back(elem); - } - - } else if (type == "image") { + boost::function f = boost::bind(&ElevationMappingNode::pointcloudCallback, this, _1, key); + ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, f); + pointcloudSubs_.push_back(sub); + } + else if (type == "image") { std::string camera_topic = subscriber.second["topic_name"]; std::string info_topic = subscriber.second["camera_info_topic_name"]; @@ -117,20 +112,32 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) cam_info_sub->subscribe(nh_, info_topic, 1); cameraInfoSubs_.push_back(cam_info_sub); - std::string fusion_info_topic; - if (subscriber.second.hasMember("fusion_info_topic_name")) { - std::string fusion_info_topic = subscriber.second["fusion_info_topic_name"]; - FusionInfoSubscriberPtr fusion_info_sub = std::make_shared(); - fusion_info_sub->subscribe(nh_, fusion_info_topic, 1); - fusionInfoSubs_.push_back(fusion_info_sub); - CameraFusionSyncPtr sync = std::make_shared(CameraFusionPolicy(10), *image_sub, *cam_info_sub, *fusion_info_sub); - sync->registerCallback(boost::bind(&ElevationMappingNode::imageFusionCallback, this, _1, _2, _3)); - cameraFusionSyncs_.push_back(sync); + std::string channel_info_topic; + // If there is channel info topic setting, we use it. + if (subscriber.second.hasMember("channel_info_topic_name")) { + std::string channel_info_topic = subscriber.second["channel_info_topic_name"]; + ChannelInfoSubscriberPtr channel_info_sub = std::make_shared(); + channel_info_sub->subscribe(nh_, channel_info_topic, 1); + channelInfoSubs_.push_back(channel_info_sub); + CameraChannelSyncPtr sync = std::make_shared(CameraChannelPolicy(10), *image_sub, *cam_info_sub, *channel_info_sub); + sync->registerCallback(boost::bind(&ElevationMappingNode::imageChannelCallback, this, _1, _2, _3)); + cameraChannelSyncs_.push_back(sync); } else { - ROS_INFO_STREAM("Fusion info topic not found"); + // If there is channels setting, we use it. Otherwise, we use rgb as default. + if (subscriber.second.hasMember("channels")) { + const auto& channels = subscriber.second["channels"]; + for (int32_t i = 0; i < channels.size(); ++i) { + auto elem = static_cast(channels[i]); + channels_[key].push_back(elem); + } + } + else { + channels_[key].push_back("rgb"); + } + ROS_INFO_STREAM("Channel info topic not found for " << camera_topic << ". Using channels: " << boost::algorithm::join(channels_[key], ", ")); CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); - sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2)); + sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2, key)); cameraSyncs_.push_back(sync); } @@ -291,39 +298,40 @@ void ElevationMappingNode::publishMapOfIndex(int index) { } void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key) { - auto start = ros::Time::now(); - // transform pointcloud into matrix - auto* pcl_pc = new pcl::PCLPointCloud2; - pcl::PCLPointCloud2ConstPtr cloudPtr(pcl_pc); - pcl_conversions::toPCL(cloud, *pcl_pc); // get channels auto fields = cloud.fields; std::vector channels; - std::vector add_element; for (int it = 0; it < fields.size(); it++) { auto& field = fields[it]; - if ((std::find(channels_[key].begin(), channels_[key].end(), field.name) != channels_[key].end()) && (field.datatype == 7)) { - add_element.push_back(true); - channels.push_back(field.name); - } else - add_element.push_back(false); + channels.push_back(field.name); } + inputPointCloud(cloud, channels); + + // This is used for publishing as statistics. + pointCloudProcessCounter_++; +} + +void ElevationMappingNode::inputPointCloud(const sensor_msgs::PointCloud2& cloud, + const std::vector& channels) { + auto start = ros::Time::now(); + auto* pcl_pc = new pcl::PCLPointCloud2; + pcl::PCLPointCloud2ConstPtr cloudPtr(pcl_pc); + pcl_conversions::toPCL(cloud, *pcl_pc); + + // get channels + auto fields = cloud.fields; uint array_dim = channels.size(); RowMatrixXd points = RowMatrixXd(pcl_pc->width * pcl_pc->height, array_dim); for (unsigned int i = 0; i < pcl_pc->width * pcl_pc->height; ++i) { - int jit = 0; - for (unsigned int j = 0; j < add_element.size(); ++j) { - if (add_element[j]) { - float temp; - uint point_idx = i * pcl_pc->point_step + pcl_pc->fields[j].offset; - memcpy(&temp, &pcl_pc->data[point_idx], sizeof(float)); - points(i, jit) = static_cast(temp); - jit++; - } + for (unsigned int j = 0; j < channels.size(); ++j) { + float temp; + uint point_idx = i * pcl_pc->point_step + pcl_pc->fields[j].offset; + memcpy(&temp, &pcl_pc->data[point_idx], sizeof(float)); + points(i, j) = static_cast(temp); } } // get pose of sensor in map frame @@ -358,14 +366,12 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl (ros::Time::now() - start).toSec()); ROS_DEBUG_THROTTLE(1.0, "positionError: %f ", positionError); ROS_DEBUG_THROTTLE(1.0, "orientationError: %f ", orientationError); - // This is used for publishing as statistics. - pointCloudProcessCounter_++; + } void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, - const std::vector& channels, - const std::vector& fusion_methods) { + const std::vector& channels) { // Get image cv::Mat image = cv_bridge::toCvShare(image_msg, image_msg->encoding)->image; @@ -403,37 +409,42 @@ void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_ms multichannel_image.push_back(eigen_img); } + // Check if the size of multichannel_image and channels and channel_methods matches. "rgb" counts for 3 layers. + int total_channels = 0; + for (const auto& channel : channels) { + if (channel == "rgb") { + total_channels += 3; + } else { + total_channels += 1; + } + } + if (total_channels != multichannel_image.size()) { + ROS_ERROR("Mismatch in the size of multichannel_image (%d), channels (%d). Please check the input.", multichannel_image.size(), channels.size()); + ROS_ERROR_STREAM("Current Channels: " << boost::algorithm::join(channels, ", ")); + return; + } + // Pass image to pipeline - map_.input_image(multichannel_image, channels, fusion_methods, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, + map_.input_image(multichannel_image, channels, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, image.rows, image.cols); } void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image_msg, - const sensor_msgs::CameraInfoConstPtr& camera_info_msg) { + const sensor_msgs::CameraInfoConstPtr& camera_info_msg, + const std::string& key) { auto start = ros::Time::now(); - // Default channels and fusion methods for image is rgb and image_color - std::vector channels; - std::vector fusion_methods; - channels.push_back("rgb"); - fusion_methods.push_back("color"); - inputImage(image_msg, camera_info_msg, channels, fusion_methods); + inputImage(image_msg, camera_info_msg, channels_[key]); ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); } -void ElevationMappingNode::imageFusionCallback(const sensor_msgs::ImageConstPtr& image_msg, +void ElevationMappingNode::imageChannelCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, - const elevation_map_msgs::FusionInfoConstPtr& fusion_info_msg) { + const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg) { auto start = ros::Time::now(); // Default channels and fusion methods for image is rgb and image_color std::vector channels; - std::vector fusion_methods; - channels = fusion_info_msg->channels; - fusion_methods = fusion_info_msg->fusion_methods; - ROS_INFO_STREAM("Channels: " << boost::algorithm::join(channels, ", ")); - ROS_INFO_STREAM("Fusion methods: " << boost::algorithm::join(fusion_methods, ", ")); - // channels.push_back("rgb"); - // fusion_methods.push_back("color"); - inputImage(image_msg, camera_info_msg, channels, fusion_methods); + channels = channel_info_msg->channels; + inputImage(image_msg, camera_info_msg, channels); ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); } diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 2fd31770..f66f9a79 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -121,12 +121,13 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { } param_.attr("subscriber_cfg") = sub_dict; - if (!nh.hasParam("pointcloud_channel_fusion")) { - ROS_WARN("No pointcloud_channel_fusion parameter found. Using default values."); + // point cloud channel fusion + if (!nh.hasParam("pointcloud_channel_fusions")) { + ROS_WARN("No pointcloud_channel_fusions parameter found. Using default values."); } else { XmlRpc::XmlRpcValue pointcloud_channel_fusion; - nh.getParam("pointcloud_channel_fusion", pointcloud_channel_fusion); + nh.getParam("pointcloud_channel_fusions", pointcloud_channel_fusion); py::dict pointcloud_channel_fusion_dict; for (auto& channel_fusion : pointcloud_channel_fusion) { @@ -136,7 +137,28 @@ void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { pointcloud_channel_fusion_dict[name] = fusion; } } - param_.attr("pointcloud_channel_fusion") = pointcloud_channel_fusion_dict; + ROS_INFO_STREAM("pointcloud_channel_fusion_dict: " << pointcloud_channel_fusion_dict); + param_.attr("pointcloud_channel_fusions") = pointcloud_channel_fusion_dict; + } + + // image channel fusion + if (!nh.hasParam("image_channel_fusions")) { + ROS_WARN("No image_channel_fusions parameter found. Using default values."); + } + else { + XmlRpc::XmlRpcValue image_channel_fusion; + nh.getParam("image_channel_fusions", image_channel_fusion); + + py::dict image_channel_fusion_dict; + for (auto& channel_fusion : image_channel_fusion) { + const char* const name = channel_fusion.first.c_str(); + std::string fusion = static_cast(channel_fusion.second); + if (!image_channel_fusion_dict.contains(name)) { + image_channel_fusion_dict[name] = fusion; + } + } + ROS_INFO_STREAM("image_channel_fusion_dict: " << image_channel_fusion_dict); + param_.attr("image_channel_fusions") = image_channel_fusion_dict; } param_.attr("update")(); @@ -155,10 +177,10 @@ void ElevationMappingWrapper::input(const RowMatrixXd& points, const std::vector Eigen::Ref(t), positionNoise, orientationNoise); } -void ElevationMappingWrapper::input_image(const std::vector& multichannel_image, const std::vector& channels, const std::vector& fusion_methods, const RowMatrixXd& R, +void ElevationMappingWrapper::input_image(const std::vector& multichannel_image, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, int height, int width) { py::gil_scoped_acquire acquire; - map_.attr("input_image")(multichannel_image, channels, fusion_methods, Eigen::Ref(R), Eigen::Ref(t), + map_.attr("input_image")(multichannel_image, channels, Eigen::Ref(R), Eigen::Ref(t), Eigen::Ref(cameraMatrix), height, width); } From ed0f049f1509db13960eb8a584500f6b71907f66 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Mon, 4 Dec 2023 14:15:48 +0100 Subject: [PATCH 379/504] Updated some example config. --- .../config/core/example_setup.yaml | 35 +++++++++++++++---- .../config/sensor_parameter.yaml | 6 +--- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/elevation_mapping_cupy/config/core/example_setup.yaml b/elevation_mapping_cupy/config/core/example_setup.yaml index d31eb1e4..eb4aa3dd 100644 --- a/elevation_mapping_cupy/config/core/example_setup.yaml +++ b/elevation_mapping_cupy/config/core/example_setup.yaml @@ -1,18 +1,41 @@ #### Plugins ######## plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/core/plugin_config.yaml' +#### Channel Fusions ######## +pointcloud_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'average' # 'average' fusion is used for channels not listed here + +image_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'exponential' # 'exponential' fusion is used for channels not listed here + feat_.*: 'exponential' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names + #### Subscribers ######## -# sensor_name: -# channels: ['feat_0','feat_1'] -# fusion: ['average','average'] -# topic_name: '/elevation_mapping/pointcloud_semantic' +# pointcloud_sensor_name: +# topic_name: '/sensor/pointcloud_semantic' +# data_type: pointcloud # pointcloud or image +# +# image_sensor_name: +# topic_name: '/camera/image_semantic' +# data_type: image # pointcloud or image +# camera_info_topic_name: '/camera/depth/camera_info' +# channel_info_topic_name: '/camera/channel_info' + subscribers: front_cam: - channels: ['rgb' ] - fusion: [ 'color'] topic_name: '/camera/depth/points' data_type: pointcloud + color_cam: # for color camera + topic_name: '/camera/rgb/image_raw' + camera_info_topic_name: '/camera/depth/camera_info' + data_type: image + semantic_cam: # for semantic images + topic_name: '/front_cam/semantic_image' + camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' + channel_info_topic_name: '/front_cam/channel_info' + data_type: image #### Publishers ######## # topic_name: diff --git a/sensor_processing/semantic_sensor/config/sensor_parameter.yaml b/sensor_processing/semantic_sensor/config/sensor_parameter.yaml index ec21d93c..4f3f9ebf 100644 --- a/sensor_processing/semantic_sensor/config/sensor_parameter.yaml +++ b/sensor_processing/semantic_sensor/config/sensor_parameter.yaml @@ -58,8 +58,4 @@ front_cam_image: show_label_legend: False image_topic: "/camera/rgb/image_raw" image_info_topic: "/camera/depth/camera_info" - resize: 0.5 - - # sem_seg_topic: "semantic_front" - # sem_seg_image_topic: "semantic_image_front" - + resize: 0.5 \ No newline at end of file From 0207803a4be53d962335f2709d11658565b63359 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Mon, 4 Dec 2023 18:52:55 +0100 Subject: [PATCH 380/504] Fixed bug in plugin manager. Fixed and cleaned up pca and semantic plugins. Cleaned up configs and launch files. --- .../setups/turtle_bot/plugin_config.yaml | 15 ++-- .../turtle_bot_image_semantics.yaml | 57 --------------- ...s.yaml => turtle_bot_semantics_image.yaml} | 15 ++-- .../turtle_bot_semantics_pointcloud.yaml | 28 ++++++++ .../launch/elevation_mapping_cupy.launch | 6 +- .../turtlesim_features_image_example.launch | 18 ----- ...tlesim_plane_decomposition_example.launch} | 0 .../launch/turtlesim_semantic_example.launch | 18 ----- .../turtlesim_semantic_image_example.launch | 5 +- ...rtlesim_semantic_pointcloud_example.launch | 11 +-- ...launch => turtlesim_simple_example.launch} | 0 .../rviz/turtle_example.rviz | 44 ++++++++---- .../elevation_mapping.py | 2 +- .../plugins/features_pca.py | 63 ++++++++++------ .../plugins/plugin_manager.py | 2 +- .../plugins/robot_centric_elevation.py | 4 +- .../plugins/semantic_filter.py | 72 ++++++++++++------- .../plugins/semantic_traversability.py | 10 +-- .../elevation_mapping_cupy/semantic_map.py | 9 +-- .../src/elevation_mapping_ros.cpp | 4 +- .../config/sensor_parameter.yaml | 12 ++-- .../script/semantic_sensor/image_node.py | 24 +++---- .../semantic_sensor/image_parameters.py | 11 +-- .../script/semantic_sensor/networks.py | 43 +++++------ 24 files changed, 233 insertions(+), 240 deletions(-) delete mode 100644 elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_image_semantics.yaml rename elevation_mapping_cupy/config/setups/turtle_bot/{turtle_bot_semantics.yaml => turtle_bot_semantics_image.yaml} (66%) create mode 100644 elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_pointcloud.yaml delete mode 100644 elevation_mapping_cupy/launch/turtlesim_features_image_example.launch rename elevation_mapping_cupy/launch/{turtlesim_segmentation_example.launch => turtlesim_plane_decomposition_example.launch} (100%) delete mode 100644 elevation_mapping_cupy/launch/turtlesim_semantic_example.launch rename elevation_mapping_cupy/launch/{turtlesim_example.launch => turtlesim_simple_example.launch} (100%) diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/plugin_config.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/plugin_config.yaml index a4aa684a..fd745524 100644 --- a/elevation_mapping_cupy/config/setups/turtle_bot/plugin_config.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/plugin_config.yaml @@ -42,19 +42,26 @@ semantic_filter: enable: True fill_nan: False is_height_layer: False - layer_name: "sem_fil" + layer_name: "max_categories" extra_params: - classes: ['grass','tree','fence','dirt'] + classes: ['^sem_.*$'] semantic_traversability: type: "semantic_traversability" enable: False fill_nan: False is_height_layer: False - layer_name: "sem_traversability" + layer_name: "semantic_traversability" extra_params: layers: ['traversability','robot_centric_elevation'] thresholds: [0.3,0.5] type: ['traversability', 'elevation'] - +features_pca: + type: "features_pca" + enable: True + fill_nan: False + is_height_layer: False + layer_name: "pca" + extra_params: + process_layer_names: ["^feat_.*$"] \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_image_semantics.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_image_semantics.yaml deleted file mode 100644 index d4451a5d..00000000 --- a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_image_semantics.yaml +++ /dev/null @@ -1,57 +0,0 @@ -#### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/turtle_bot/plugin_config.yaml' - -#### Subscribers ######## -subscribers: -# sensor_name: -# channels: ['feat_0','feat_1'] -# fusion: ['average','average'] -# topic_name: '/elevation_mapping/pointcloud_semantic' - front_cam_2: - channels: [ 'grass','tree',"person" ] - fusion: [ 'exponential','exponential','exponential' ] - topic_name_camera: '/elevation_mapping/semantic_front' - topic_name_camera_info: '/camera/depth/camera_info' - data_type: image - - color_cam: # for color camera - channels: ['rgb'] - fusion: ['color'] - topic_name_camera: '/camera/rgb/image_raw' - topic_name_camera_info: '/camera/depth/camera_info' - data_type: image - - pointcloud: - channels: [] - fusion: [] - topic_name: '/camera/depth/points' - data_type: pointcloud - - front_cam: - channels: ['grass','tree',"person"] - fusion: ['exponential','exponential','exponential'] - topic_name_camera: '/elevation_mapping/semantic_front' - topic_name_camera_info: '/camera/depth/camera_info' - data_type: image - - semantic_segmentation: True - # segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large - segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large - show_label_legend: False - image_topic: "/camera/rgb/image_raw" - image_info_topic: "/camera/depth/camera_info" - resize: 0.5 - - sem_seg_topic: "/elevation_mapping/semantic_front" - sem_seg_image_topic: "/elevation_mapping/semantic_image_front" - -#### Publishers ######## -publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb','sem_fil'] - basic_layers: ['elevation'] - fps: 5.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','sem_fil'] - basic_layers: ['min_filter'] - fps: 3.0 \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_image.yaml similarity index 66% rename from elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml rename to elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_image.yaml index 63d3b2b9..0fd7d215 100644 --- a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_image.yaml @@ -22,28 +22,23 @@ subscribers: camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' channel_info_topic_name: '/front_cam/channel_info' data_type: image - # fixed_semantic_cam: # for semantic images - # topic_name: '/front_cam/semantic_image' - # camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' - # channels: ["test", "test2", "test3"] - # data_type: image front_cam_pointcloud: topic_name: '/camera/depth/points' data_type: pointcloud feat_front: - topic_name: /elevation_mapping/feat_f - camera_info_topic_name: "/camera/depth/camera_info" - channels: [ 'feat_0','feat_1','feat_2','feat_3','feat_4','feat_5','feat_6','feat_7','feat_8','feat_9' ] + topic_name: '/front_cam/semantic_seg_feat' + camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' + channel_info_topic_name: '/front_cam/feat_channel_info' data_type: image #### Publishers ######## publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb','sem_fil', 'person', 'chair', 'sofa'] + layers: ['elevation', 'traversability', 'variance','rgb','max_categories', 'pca'] basic_layers: ['elevation'] fps: 5.0 elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','sem_fil'] + layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','max_categories'] basic_layers: ['min_filter'] fps: 3.0 \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_pointcloud.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_pointcloud.yaml new file mode 100644 index 00000000..19db1159 --- /dev/null +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_pointcloud.yaml @@ -0,0 +1,28 @@ +#### Plugins ######## +plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/turtle_bot/plugin_config.yaml' + +pointcloud_channel_fusions: + rgb: 'color' + default: 'average' + +image_channel_fusions: + rgb: 'color' + default: 'exponential' + +#### Subscribers ######## +subscribers: + front_cam_pointcloud: + topic_name: '/camera/depth/points' + data_type: pointcloud + + +#### Publishers ######## +publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb','max_categories'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','max_categories'] + basic_layers: ['min_filter'] + fps: 3.0 \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch index 386dfdff..b0fb53c9 100644 --- a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch +++ b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch @@ -1,7 +1,7 @@ - - + + - + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_features_image_example.launch b/elevation_mapping_cupy/launch/turtlesim_features_image_example.launch deleted file mode 100644 index d4b7af3c..00000000 --- a/elevation_mapping_cupy/launch/turtlesim_features_image_example.launch +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/elevation_mapping_cupy/launch/turtlesim_segmentation_example.launch b/elevation_mapping_cupy/launch/turtlesim_plane_decomposition_example.launch similarity index 100% rename from elevation_mapping_cupy/launch/turtlesim_segmentation_example.launch rename to elevation_mapping_cupy/launch/turtlesim_plane_decomposition_example.launch diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch deleted file mode 100644 index d071ddbb..00000000 --- a/elevation_mapping_cupy/launch/turtlesim_semantic_example.launch +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch index 30741b50..05064d0a 100644 --- a/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch @@ -10,13 +10,10 @@ - - - - + \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch index d672f6de..65142465 100644 --- a/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch @@ -6,14 +6,17 @@ - - + --> + + + - - + + diff --git a/elevation_mapping_cupy/launch/turtlesim_example.launch b/elevation_mapping_cupy/launch/turtlesim_simple_example.launch similarity index 100% rename from elevation_mapping_cupy/launch/turtlesim_example.launch rename to elevation_mapping_cupy/launch/turtlesim_simple_example.launch diff --git a/elevation_mapping_cupy/rviz/turtle_example.rviz b/elevation_mapping_cupy/rviz/turtle_example.rviz index fe4c79bb..0cd124c8 100644 --- a/elevation_mapping_cupy/rviz/turtle_example.rviz +++ b/elevation_mapping_cupy/rviz/turtle_example.rviz @@ -1,12 +1,14 @@ Panels: - Class: rviz/Displays - Help Height: 138 + Help Height: 70 Name: Displays Property Tree Widget: Expanded: - /Global Options1 + - /ElevationMapRaw1 + - /Feature1 Splitter Ratio: 0.5768463015556335 - Tree Height: 229 + Tree Height: 234 - Class: rviz/Selection Name: Selection - Class: rviz/Tool Properties @@ -24,7 +26,7 @@ Panels: - Class: rviz/Time Name: Time SyncMode: 0 - SyncSource: Image + SyncSource: Color Preferences: PromptSaveOnExit: true Toolbars: @@ -69,7 +71,7 @@ Visualization Manager: Show Grid Lines: true Topic: /elevation_mapping/elevation_map_raw Unreliable: false - Use Rainbow: true + Use Rainbow: false Value: true - Alpha: 1 Class: rviz/RobotModel @@ -180,7 +182,7 @@ Visualization Manager: Max Value: 1 Median window: 5 Min Value: 0 - Name: Image + Name: Color Normalize Range: true Queue Size: 2 Transport Hint: raw @@ -188,11 +190,23 @@ Visualization Manager: Value: true - Class: rviz/Image Enabled: true - Image Topic: /front_cam/elevation_mapping/semantic_image_front + Image Topic: /front_cam/semantic_image_debug Max Value: 1 Median window: 5 Min Value: 0 - Name: Image + Name: Segmentation + Normalize Range: true + Queue Size: 2 + Transport Hint: raw + Unreliable: false + Value: true + - Class: rviz/Image + Enabled: true + Image Topic: /front_cam/semantic_seg_feat_im + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Feature Normalize Range: true Queue Size: 2 Transport Hint: raw @@ -242,19 +256,23 @@ Visualization Manager: Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.5147963762283325 + Pitch: 0.4647962152957916 Target Frame: base_footprint - Yaw: 3.1033706665039062 + Yaw: 3.113370418548584 Saved: ~ Window Geometry: + Color: + collapsed: false Displays: collapsed: false - Height: 1043 + Feature: + collapsed: false + Height: 1306 Hide Left Dock: false Hide Right Dock: true - Image: + QMainWindow State: 000000ff00000000fd0000000400000000000001f700000464fc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003b0000016b000000c700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0043006f006c006f007201000001ac000000fd0000001600fffffffb00000018005300650067006d0065006e0074006100740069006f006e01000002af000000e40000001600fffffffb0000000e00460065006100740075007200650100000399000001060000001600ffffff000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007800000005afc0100000002fb0000000800540069006d00650100000000000007800000030700fffffffb0000000800540069006d00650100000000000004500000000000000000000005830000046400000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Segmentation: collapsed: false - QMainWindow State: 000000ff00000000fd0000000400000000000001f70000035dfc020000000afb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003b000001aa000000c700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d00610067006501000001eb000000d30000001600fffffffb0000000a0049006d00610067006501000002c4000000d40000001600ffffff000000010000015f0000053bfc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007300000000560000053b000000a000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007800000005afc0100000002fb0000000800540069006d00650100000000000007800000030700fffffffb0000000800540069006d00650100000000000004500000000000000000000005830000035d00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -265,4 +283,4 @@ Window Geometry: collapsed: true Width: 1920 X: 2280 - Y: 105 + Y: 68 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index e7011529..42c81c04 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -731,7 +731,7 @@ def get_map_with_name_ref(self, name, data): self.elevation_map, self.layer_names, self.semantic_map.semantic_map, - self.semantic_map.param, + self.semantic_map.layer_names, self.base_rotation, self.semantic_map.elements_to_shift, ) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py index ad1236bf..8ea2d54a 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py @@ -5,6 +5,7 @@ import cupy as cp import numpy as np from typing import List +import re from elevation_mapping_cupy.plugins.plugin_manager import PluginBase from sklearn.decomposition import PCA @@ -20,10 +21,26 @@ class FeaturesPca(PluginBase): """ def __init__( self, + cell_n: int = 100, + process_layer_names: List[str]=[], **kwargs, ): super().__init__() - self.indices = [] + self.process_layer_names = process_layer_names + + def get_layer_indices(self, layer_names: List[str]) -> List[int]: + """ Get the indices of the layers that are to be processed using regular expressions. + Args: + layer_names (List[str]): List of layer names. + Returns: + List[int]: List of layer indices. + """ + indices = [] + for i, layer_name in enumerate(layer_names): + if any(re.match(pattern, layer_name) for pattern in self.process_layer_names): + indices.append(i) + return indices + def __call__( self, @@ -31,8 +48,8 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], - semantic_map, - semantic_params, + semantic_map: cp.ndarray, + semantic_layer_names: List[str], *args, ) -> cp.ndarray: """ @@ -49,31 +66,33 @@ def __call__( cupy._core.core.ndarray: """ # get indices of all layers that contain semantic features information - layer_indices = cp.array([], dtype=cp.int32) - for it, fusion_alg in enumerate(semantic_params.fusion_algorithms): - if fusion_alg in ["average", "bayesian_inference", "exponential"]: - layer_indices = cp.append(layer_indices, it).astype(cp.int32) - - n_c = semantic_map[layer_indices].shape[1] - comp_img = np.zeros((n_c, n_c, 3), dtype=np.float32) - # check which has the highest value - if len(layer_indices) > 0: - data = cp.reshape(semantic_map[layer_indices], (len(layer_indices), -1)).T.get() - # data = np.clip(data, -1, 1) + data = [] + for m, layer_names in zip([elevation_map, plugin_layers, semantic_map], + [layer_names, plugin_layer_names, semantic_layer_names]): + layer_indices = self.get_layer_indices(layer_names) + if len(layer_indices) > 0: + n_c = m[layer_indices].shape[1] + data_i = cp.reshape(m[layer_indices], (len(layer_indices), -1)).T.get() + data_i = np.clip(data_i, -1, 1) + data.append(data_i) + if len(data) > 0: + data = np.concatenate(data, axis=1) + # check which has the highest value n_components = 3 pca = PCA(n_components=n_components).fit(data) pca_descriptors = pca.transform(data) img_pca = pca_descriptors.reshape(n_c, n_c, n_components) comp = img_pca # [:, :, -3:] - var = comp.std(axis=(0, 1)) comp_min = comp.min(axis=(0, 1)) comp_max = comp.max(axis=(0, 1)) if (comp_max - comp_min).any() != 0: comp_img = np.divide((comp - comp_min), (comp_max - comp_min)) - map = (comp_img * 255).astype(np.uint8) - r = np.asarray(map[:, :, 0], dtype=np.uint32) - g = np.asarray(map[:, :, 1], dtype=np.uint32) - b = np.asarray(map[:, :, 2], dtype=np.uint32) - rgb_arr = np.array((r << 16) | (g << 8) | (b << 0), dtype=np.uint32) - rgb_arr.dtype = np.float32 - return cp.asarray(rgb_arr) + pca_map = (comp_img * 255).astype(np.uint8) + r = np.asarray(pca_map[:, :, 0], dtype=np.uint32) + g = np.asarray(pca_map[:, :, 1], dtype=np.uint32) + b = np.asarray(pca_map[:, :, 2], dtype=np.uint32) + rgb_arr = np.array((r << 16) | (g << 8) | (b << 0), dtype=np.uint32) + rgb_arr.dtype = np.float32 + return cp.asarray(rgb_arr) + else: + return cp.zeros_like(elevation_map[0]) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index b5c2d313..01e3aea8 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -103,7 +103,7 @@ def load_plugin_settings(self, file_path: str): is_height_layer=v["is_height_layer"], ) ) - extra_params.append(v["extra_params"]) + extra_params.append(v["extra_params"]) self.init(plugin_params, extra_params) print("Loaded plugins are ", *self.plugin_names) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py index e9b43266..334085f0 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py @@ -88,8 +88,8 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], - semantic_map, - semantic_params, + semantic_map: cp.ndarray, + semantic_layer_names: List[str], rotation, *args, ) -> cp.ndarray: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index 3331afe7..7085f558 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -5,6 +5,7 @@ import cupy as cp import numpy as np from typing import List +import re from elevation_mapping_cupy.plugins.plugin_manager import PluginBase @@ -28,7 +29,17 @@ def __init__( self.classes = classes self.color_encoding = self.transform_color() - def color_map(self, N=256, normalized=False): + def color_map(self, N:int =256, normalized: bool=False): + """ + Creates a color map with N different colors. + + Args: + N (int, optional): The number of colors in the map. Defaults to 256. + normalized (bool, optional): If True, the colors are normalized to the range [0,1]. Defaults to False. + + Returns: + np.ndarray: The color map. + """ def bitget(byteval, idx): return (byteval & (1 << idx)) != 0 @@ -52,6 +63,12 @@ def bitget(byteval, idx): return cmap[1:] def transform_color(self): + """ + Transforms the color map into a format that can be used for semantic filtering. + + Returns: + cp.ndarray: The transformed color map. + """ color_classes = self.color_map(255) r = np.asarray(color_classes[:, 0], dtype=np.uint32) g = np.asarray(color_classes[:, 1], dtype=np.uint32) @@ -60,6 +77,19 @@ def transform_color(self): rgb_arr.dtype = np.float32 return cp.asarray(rgb_arr) + def get_layer_indices(self, layer_names: List[str]) -> List[int]: + """ Get the indices of the layers that are to be processed using regular expressions. + Args: + layer_names (List[str]): List of layer names. + Returns: + List[int]: List of layer indices. + """ + indices = [] + for i, layer_name in enumerate(layer_names): + if any(re.match(pattern, layer_name) for pattern in self.classes): + indices.append(i) + return indices + def __call__( self, elevation_map: cp.ndarray, @@ -67,7 +97,7 @@ def __call__( plugin_layers: cp.ndarray, plugin_layer_names: List[str], semantic_map: cp.ndarray, - semantic_params, + semantic_layer_names: List[str], rotation, elements_to_shift, *args, @@ -86,28 +116,18 @@ def __call__( cupy._core.core.ndarray: """ # get indices of all layers that contain semantic class information - layer_indices = cp.array([], dtype=cp.int32) - max_idcs = cp.array([], dtype=cp.int32) - for it, fusion_alg in enumerate(semantic_params.fusion_algorithms): - if fusion_alg in ["class_bayesian", "class_average", "exponential"]: - layer_indices = cp.append(layer_indices, it).astype(cp.int32) - # we care only for the first max in the display - if fusion_alg in ["class_max"] and len(max_idcs) < 1: - max_idcs = cp.append(max_idcs, it).astype(cp.int32) - - # check which has the highest value - if len(layer_indices) > 0: - class_map = cp.amax(semantic_map[layer_indices], axis=0) - class_map_id = cp.argmax(semantic_map[layer_indices], axis=0) - else: - class_map = cp.zeros_like(semantic_map[0]) - class_map_id = cp.zeros_like(semantic_map[0], dtype=cp.int32) - if "class_max" in semantic_params.fusion_algorithms: - max_map = cp.amax(semantic_map[max_idcs], axis=0) - max_map_id = elements_to_shift["id_max"][max_idcs] - map = cp.where(max_map > class_map, max_map_id, class_map_id) + data = [] + for m, layer_names in zip([elevation_map, plugin_layers, semantic_map], + [layer_names, plugin_layer_names, semantic_layer_names]): + layer_indices = self.get_layer_indices(layer_names) + if len(layer_indices) > 0: + data.append(m[layer_indices]) + if len(data) > 0: + data = cp.concatenate(data, axis=0) + class_map = cp.amax(data, axis=0) + class_map_id = cp.argmax(data, axis=0) else: - map = class_map_id - # create color coding - enc = self.color_encoding[map] - return enc + class_map = cp.zeros_like(elevation_map[0]) + class_map_id = cp.zeros_like(elevation_map[0], dtype=cp.int32) + enc = self.color_encoding[class_map_id] + return enc \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py index 0c9af601..842d3b16 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py @@ -38,8 +38,8 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], - semantic_map, - semantic_params, + semantic_map: cp.ndarray, + semantic_layer_names: List[str], *args, ) -> cp.ndarray: """ @@ -62,9 +62,9 @@ def __call__( if name in layer_names: idx = layer_names.index(name) tempo = elevation_map[idx] - elif name in semantic_params.additional_layers: - idx = semantic_params.additional_layers.index(name) - tempo = semantic_map[idx] + # elif name in semantic_params.additional_layers: + # idx = semantic_params.additional_layers.index(name) + # tempo = semantic_map[idx] elif name in plugin_layer_names: idx = plugin_layer_names.index(name) tempo = plugin_layers[idx] diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 6b7291ca..1d2eb838 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -173,8 +173,7 @@ def get_fusion(self, channels: List[str], channel_fusions: Dict[str, str], layer layer_specs[channel] = matched_fusion self.update_fusion_setting() x = layer_specs[channel] - if x not in fusion_list: - fusion_list.append(x) + fusion_list.append(x) process_channels.append(channel) return process_channels, fusion_list @@ -287,12 +286,8 @@ def update_layers_image( image_width: """ - # additional_fusion = self.get_fusion_of_pcl(channels) process_channels, fusion_methods = self.get_fusion(channels, self.param.image_channel_fusions, self.layer_specs_image) self.new_map[self.delete_new_layers] = 0.0 - # config = self.param.subscriber_cfg[sub_key] - - # for j, (fusion, channel) in enumerate(zip(config["fusion"], config["channels"])): for j, (fusion, channel) in enumerate(zip(fusion_methods, process_channels)): if channel not in self.layer_names: print(f"Layer {channel} not found, adding it to the semantic map") @@ -303,8 +298,6 @@ def update_layers_image( print(f"Layer {channel} not found!") return - # which layers need to be updated with this fusion algorithm - # pcl_ids, layer_ids = self.get_indices_fusion(channels, fusion) # update the layers with the fusion algorithm self.fusion_manager.execute_image_plugin( fusion, diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 21412e95..4a72e8c6 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -86,6 +86,7 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) boost::function f = boost::bind(&ElevationMappingNode::pointcloudCallback, this, _1, key); ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, f); pointcloudSubs_.push_back(sub); + ROS_INFO_STREAM("Subscribed to PointCloud2 topic: " << pointcloud_topic); } else if (type == "image") { std::string camera_topic = subscriber.second["topic_name"]; @@ -122,6 +123,7 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) CameraChannelSyncPtr sync = std::make_shared(CameraChannelPolicy(10), *image_sub, *cam_info_sub, *channel_info_sub); sync->registerCallback(boost::bind(&ElevationMappingNode::imageChannelCallback, this, _1, _2, _3)); cameraChannelSyncs_.push_back(sync); + ROS_INFO_STREAM("Subscribed to Image topic: " << camera_topic << ", Camera info topic: " << info_topic << ", Channel info topic: " << channel_info_topic); } else { // If there is channels setting, we use it. Otherwise, we use rgb as default. @@ -135,7 +137,7 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) else { channels_[key].push_back("rgb"); } - ROS_INFO_STREAM("Channel info topic not found for " << camera_topic << ". Using channels: " << boost::algorithm::join(channels_[key], ", ")); + ROS_INFO_STREAM("Subscribed to Image topic: " << camera_topic << ", Camera info topic: " << info_topic << ". Channel info topic: " << (channel_info_topic.empty() ? ("Not found. Using channels: " + boost::algorithm::join(channels_[key], ", ")) : channel_info_topic)); CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2, key)); cameraSyncs_.push_back(sync); diff --git a/sensor_processing/semantic_sensor/config/sensor_parameter.yaml b/sensor_processing/semantic_sensor/config/sensor_parameter.yaml index 4f3f9ebf..c497564c 100644 --- a/sensor_processing/semantic_sensor/config/sensor_parameter.yaml +++ b/sensor_processing/semantic_sensor/config/sensor_parameter.yaml @@ -38,9 +38,9 @@ front_cam_pointcloud: show_label_legend: False data_type: pointcloud - cam_info_topic: "/camera/depth/camera_info" - image_topic: "/camera/rgb/image_raw" - depth_topic: "/camera/depth/image_raw" + cam_info_topic: "camera/depth/camera_info" + image_topic: "camera/rgb/image_raw" + depth_topic: "camera/depth/image_raw" cam_frame: "camera_rgb_optical_frame" front_cam_image: @@ -53,9 +53,9 @@ front_cam_image: data_type: image semantic_segmentation: True - # segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large + feature_extractor: True segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large show_label_legend: False - image_topic: "/camera/rgb/image_raw" - image_info_topic: "/camera/depth/camera_info" + image_topic: "camera/rgb/image_raw" + camera_info_topic: "camera/depth/camera_info" resize: 0.5 \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py index 8a89c81e..d59840ba 100755 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py @@ -22,7 +22,7 @@ from semantic_sensor.networks import resolve_model from sklearn.decomposition import PCA -from elevation_map_msgs.msg import FusionInfo +from elevation_map_msgs.msg import ChannelInfo class SemanticSegmentationNode: @@ -71,9 +71,9 @@ def register_sub_pub(self): node_name = rospy.get_name() # subscribers - if self.param.image_info_topic is not None and self.param.resize is not None: - rospy.Subscriber(self.param.image_info_topic, CameraInfo, self.image_info_callback) - self.feat_im_info_pub = rospy.Publisher(node_name + "/" + self.param.image_info_topic + "_resized", CameraInfo, queue_size=2) + if self.param.camera_info_topic is not None and self.param.resize is not None: + rospy.Subscriber(self.param.camera_info_topic, CameraInfo, self.image_info_callback) + self.feat_im_info_pub = rospy.Publisher(node_name + "/" + self.param.camera_info_topic + "_resized", CameraInfo, queue_size=2) if "compressed" in self.param.image_topic: self.compressed = True @@ -94,8 +94,9 @@ def register_sub_pub(self): if self.param.feature_extractor: self.feature_pub = rospy.Publisher(node_name + "/" + self.param.feature_topic, Image, queue_size=2) self.feat_im_pub = rospy.Publisher(node_name + "/" + self.param.feat_image_topic, Image, queue_size=2) + self.feat_channel_info_pub = rospy.Publisher(node_name + "/" + self.param.feat_channel_info_topic, ChannelInfo, queue_size=2) - self.fusion_info_pub = rospy.Publisher(node_name + "/" + self.param.fusion_info_topic, FusionInfo, queue_size=2) + self.channel_info_pub = rospy.Publisher(node_name + "/" + self.param.channel_info_topic, ChannelInfo, queue_size=2) def color_map(self, N=256, normalized=False): """Create a color map for the class labels. @@ -177,24 +178,23 @@ def image_callback(self, rgb_msg): if self.param.semantic_segmentation: self.publish_segmentation() self.publish_segmentation_image() - self.publish_fusion_info() + self.publish_channel_info([f"sem_{c}" for c in self.param.channels], self.channel_info_pub) if self.param.feature_extractor: self.publish_feature() self.publish_feature_image(self.features) - self.publish_fusion_info() + self.publish_channel_info([f"feat_{i}" for i in range(self.features.shape[0])], self.feat_channel_info_pub) if self.param.resize is not None: self.pub_info() def pub_info(self): self.feat_im_info_pub.publish(self.info) - def publish_fusion_info(self): + def publish_channel_info(self, channels, pub): """Publish fusion info.""" - info = FusionInfo() + info = ChannelInfo() info.header = self.header - info.channels = self.param.channels - info.fusion_methods = self.param.fusion_methods - self.fusion_info_pub.publish(info) + info.channels = channels + pub.publish(info) def process_image(self, image): """Depending on setting generate color, semantic segmentation or feature channels. diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py index 014bd9b9..aacb152c 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py @@ -23,19 +23,20 @@ class ImageParameter(Serializable): semantic_segmentation: bool = True # sem_seg_topic: str = "semantic_seg" # sem_seg_image_topic: str = "semantic_seg_im" - publish_topic: str = "semantic_seg" - publish_image_topic: str = "semantic_seg_img" # publish_camera_info_topic: str = "semantic_seg/camera_info" segmentation_model: str = "detectron_coco_panoptic_fpn_R_101_3x" show_label_legend: bool = False channels: list = field(default_factory=lambda: ["grass", "road", "tree", "sky"]) - fusion_methods: list = field(default_factory=lambda: ["class_average", "class_average", "class_average", "class_average"]) + + publish_topic: str = "semantic_seg" + publish_image_topic: str = "semantic_seg_img" + channel_info_topic: str = "channel_info" feature_extractor: bool = False feature_config: FeatureExtractorParameter = FeatureExtractorParameter # feature_config.input_size: list = field(default_factory=lambda: [80, 160]) feature_topic: str = "semantic_seg_feat" feat_image_topic: str = "semantic_seg_feat_im" - fusion_info_topic: str = "fusion_info" + feat_channel_info_topic: str = "feat_channel_info" resize: float = None - image_info_topic: str = "image_info" \ No newline at end of file + camera_info_topic: str = "camera_info" \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py index df7c578c..0c666a3e 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py @@ -118,17 +118,20 @@ def resolve_categories(self): indices.append(class_to_idx[chan]) channels.append(chan) self.actual_channels.append(chan) - elif self.param.fusion_methods[it] in ["class_average", "class_bayesian"]: - print(chan, " is not in the semantic segmentation model.") - for it, chan in enumerate(self.param.channels): - if self.param.fusion_methods[it] in ["class_max"]: - self.actual_channels.append(chan) - print( - chan, - " is not in the semantic segmentation model but is a max channel.", - ) else: - pass + self.actual_channels.append(chan) + # elif self.param.fusion_methods[it] in ["class_average", "class_bayesian"]: + # print(chan, " is not in the semantic segmentation model.") + # for it, chan in enumerate(self.param.channels): + # self.actual_channels.append(chan) + # if self.param.fusion_methods[it] in ["class_max"]: + # self.actual_channels.append(chan) + # print( + # chan, + # " is not in the semantic segmentation model but is a max channel.", + # ) + # else: + # pass self.stuff_categories = dict(zip(channels, indices)) self.segmentation_channels = dict(zip(channels, indices)) @@ -152,14 +155,14 @@ def __call__(self, image, *args, **kwargs): selected_masks = cp.asarray(normalized_masks[list(self.stuff_categories.values())]) # get values of max, first remove the ones we already have normalized_masks[list(self.stuff_categories.values())] = 0 - for i in range(self.param.fusion_methods.count("class_max")): - maxim, index = torch.max(normalized_masks, dim=0) - mer = encode_max(maxim, index) - selected_masks = cp.concatenate((selected_masks, cp.expand_dims(mer, axis=0)), axis=0) - x = torch.arange(0, index.shape[0]) - y = torch.arange(0, index.shape[1]) - c = torch.meshgrid(x, y, indexing="ij") - normalized_masks[index, c[0], c[1]] = 0 + # for i in range(self.param.fusion_methods.count("class_max")): + # maxim, index = torch.max(normalized_masks, dim=0) + # mer = encode_max(maxim, index) + # selected_masks = cp.concatenate((selected_masks, cp.expand_dims(mer, axis=0)), axis=0) + # x = torch.arange(0, index.shape[0]) + # y = torch.arange(0, index.shape[1]) + # c = torch.meshgrid(x, y, indexing="ij") + # normalized_masks[index, c[0], c[1]] = 0 assert len(self.actual_channels) == selected_masks.shape[0] return cp.asarray(selected_masks) @@ -260,7 +263,7 @@ def __init__(self, weights, cfg): self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") self.model.to(self.device) self.model.eval() - self.shrink = Resize(size=(self.cfg.input_size[0], self.cfg.input_size[1])) + self.shrink = Resize(size=(self.cfg.input_size[0], self.cfg.input_size[1]), antialias=True) def to_tensor(self, data): data = data.astype(np.float32) @@ -277,7 +280,7 @@ def __call__(self, image, *args, **kwargs): # image = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) image = self.to_tensor(image).unsqueeze(0) # if self.cfg.pcl: - reset_size = Resize(image.shape[-2:], interpolation=TF.InterpolationMode.NEAREST) + reset_size = Resize(image.shape[-2:], interpolation=TF.InterpolationMode.NEAREST, antialias=True) im_size = image.shape[-2:] image = self.shrink(image) image = TF.normalize(image, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)) From 702188cb9feb8fd25f80a5b8f3d1bad1f337fc25 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Mon, 4 Dec 2023 23:56:53 +0100 Subject: [PATCH 381/504] Modified the anymal example. --- .../setups/anymal/anymal_sensor_parameter.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml index 4ad52176..a130607f 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml @@ -22,9 +22,9 @@ publishers: basic_layers: ['elevation', 'traversability'] fps: 5.0 - semantic_map_raw: - layers: ['elevation', 'traversability'] - basic_layers: ['elevation', 'traversability'] + filtered_elevation_map: + layers: ['inpaint', 'smooth', 'min_filter'] + basic_layers: ['inpaint'] fps: 5.0 #### Subscribers ######## @@ -54,18 +54,18 @@ subscribers: data_type: pointcloud front_wide_angle: - topic_name: /wide_angle_camera_front/image_raw + topic_name: /wide_angle_camera_front/image_color_rect/compressed camera_info_topic_name: /wide_angle_camera_front/camera_info data_type: image rear_wide_angle: - topic_name: /wide_angle_camera_rear/image_raw + topic_name: /wide_angle_camera_rear/image_color_rect/compressed camera_info_topic_name: /wide_angle_camera_rear/camera_info data_type: image - # velodyne: - # topic_name: /point_cloud_filter/lidar/point_cloud_filtered - # data_type: pointcloud + velodyne: + topic_name: /point_cloud_filter/lidar/point_cloud_filtered + data_type: pointcloud front_bpearl: topic_name: /robot_self_filter/bpearl_front/point_cloud From befa1d70eda530afe49450d9c8e52fa6cc8a2d0d Mon Sep 17 00:00:00 2001 From: Takahiro Date: Tue, 5 Dec 2023 23:49:46 +0100 Subject: [PATCH 382/504] Updating documents. --- docs/media/main_mem.png | Bin 0 -> 382124 bytes docs/media/overview.png | Bin 0 -> 2745718 bytes docs/source/documentation.rst | 45 ++++-- docs/source/getting_started/index.rst | 71 ---------- docs/source/getting_started/installation.rst | 61 ++++++-- docs/source/getting_started/introduction.rst | 132 ++++++++++++++++++ docs/source/getting_started/tutorial.rst | 110 ++++++--------- docs/source/index.rst | 2 +- docs/source/usage/parameters.rst | 20 ++- docs/source/usage/plugins.rst | 97 +++++++------ .../config/sensor_parameter.yaml | 30 ---- 11 files changed, 328 insertions(+), 240 deletions(-) create mode 100644 docs/media/main_mem.png create mode 100644 docs/media/overview.png delete mode 100644 docs/source/getting_started/index.rst create mode 100644 docs/source/getting_started/introduction.rst diff --git a/docs/media/main_mem.png b/docs/media/main_mem.png new file mode 100644 index 0000000000000000000000000000000000000000..cda6a5002f70d3fb6ebb6852d165cf8934f9168a GIT binary patch literal 382124 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

    BU zqa#+eW!nbMF5{MQINfJ+c^wOruEoh%ko#cq0dn6_h>lU7ax|H6|NbeDpS;7SbA0mo zOEz7g4RG7EBpuAR*A#i6t6P*xutFe{B$C_`2|=N=gw{o`+&E29E6*sO!OZaU@4d%l z@=lbPI>BbuA=t86-|%QC>Dn#UbfEPe?Mn#3;mHG>OxSMbSO-ewm@ek&Slg21Ii{;H z&JemKlOki1j##W~>fB+QmdaO1-;oT)eEOFigXuAY$wQWxf5h-`#H7fW&$l$DBatOK zoiZLu4riX!1^&*@KP0i1S0A7AC zkr12%8Rau^*e*~yp>ArjOd*4$P>OY95M_Z=C5;OV(Ky$k6V;o`<7Za~)k6#PU4Dvi zwr|=}tcO%YNs$u70jbhB>!T-CWjNpBoh8wM5WbP|L_Du$kDC_#ea9m~B+*|$+&su6 z!L(a+nta0$?g?S%v5UpExHOsd|~uxn2sd?Wns8!ikHC5PWk2H(k}yx3)G zcwC4|jBxkwxXa(#`6hOLOWRc#V@Y(1*3rM|y+-69@9%T=<_z1kWLb_3 zVEREPL}}dav%LFE#1>4Dq$y76{%7`Vw_Bu)&A^}>;Y2{Il%h~{o#|B@QNm`7;qBYE zJbv;B>nz(%h4((j3P{yU>vldGN0ubfKVdqi(+S3OgrLwmWxHt*A}Su};Ebo3eCC??g?gPYj^1QZg@kp+2=CQaKL=9QfGz1}d z_2vx{!Ohug>h(4M@E70b7oNl)^vCs(&wqMOZDP=#H38);x@#Dxl3)DRL%uzXAJMr< z_+S6ozhr%V%_P_C?+-CrVZ37%3_&G$Yf;{DG|6ewfX^g9``r(?y1quJ6e$!+5sRjt zpPeL%qR5zx2duYSQY9FUN60jfNLG`?byC}s=rK|T+Rm`8Ti#y1ptBvLB4aQpxxT$- zI4ZflxuLEb9zA@_^5T-L9B_3Vlc9g`!yl6k2b9ApH#fJueDM~<7H0#CRgKP4ya;TY zj{El~=xjrvV?2V@re=9_!Q$qI$z+VNj^%RA>(}Qzxqn30S;{P?oeJS2a#IL`^D&T1 z=@>^Z6Y9EQZ+{3tSrlAf-*9-i-zPTZrDD1tCQ06wwP| zx?Qe@>H~24>3C0(*m)A@FYp+&x9jdB-qyR&)3bI7-SH@^>-ukfT~$?-BsC3Mr~MSa zy~Eyyo+1@B`@Lsl_p*J|z{dkKV2r^ydlv%eeUu9g2LpzgM&ocnk_1In*C^pR+@B(p zqFS|R9Z{vO-yXDWi%w&J&twuqbn3e9=|YiAwOXy>cEfa76NxCp;gHQ{6HVd)=JPrC z@86Gfq^1F)Kcj7H_V)HzE|&-)Sg+S?HdVigh`(=Rqu#%5Tc*<~S(edtCK}~*%G-+z z{_v0gnE&A)|BnoZC9~O-gTq6nlPQOXN6cnZ_V)KVIM^pkHLqX4=J?@zOb#C+q}mO) zI6gWiQ3aadQvieUSjrKm`<7NrBO zi`PauQ5+l$=**g~byy>DF3Ky$qXA0C#CxqJ7jNfuCZVb#+E5Yr@cpMuM zzkhH<)pmUUuRo%74krb^4_Jfv8I(Fsn4IlUN{}WhZWLwQ`dwVS#hD5%J=1YUnrk+d zq3bLJNoPDa%Ucesx7^&W8Bb;mXRy3IC!dVCe{X`!0?)sENumb?Z<$S|2&vg_wk&R! z=$~;YZQ0wOa(TXGesfJeEb&cEP&y_J4@O*6HP1hPPUj#^QmV?4PDgY?gV4;5@1t-L zqR<)Ex3{deEv<2k%7UZO6s0x8V#4LsH7BPJ`SE9;bNcit+DSU+P+BvZ%$UrMnCP6k z>+mw31wtqY4MJFkqlDmVl(5`C9ifEf>Uz#*z3oAF5q9Bhzs(Yo&88-Lu@p`yLMLfk z&mh(0lRbdQr zfq&;a-{xdiva&7L+m?+&}8$a|Y5s|-L;`z@0 zj9>ruhl~>qm5Ccuosi0w-}v=k<*Sz$ti9#c^#xsL(J~<)4_GahbZtxLJe#J%dy5dz zdWWe3Rz%$GgRcvx{gKZ^xa6N5-kPWCZV&!eZu{N;~+!h>wc`Sm%gwqsTl z&=ar%lKZERP{jbxg3)kDNeRLBhe&!`Br*{ox#2%Wz2hub_I#|2B{UnNvv_GG*A=?b=`uD3GCxM z;db4SvPY*%WRm0XNF{r4K-`MTopebOw-F(}CK)2>&WMauBzPa`Vp2+k?+}Tkbr!D+ zyecrh1?Ncnu*D!1KB!pIdk7)QETcU_;)TWvMdv(HM2W5Q0_);+5<;vI`q;m?5$SWU zqDZNSTJL-mArhGU-Nqr@?Li<0QTkm|;sZf`y_wj_w1nK@Z+D)Ro;-Ocv)W0qd@py7 znynqo#CzX+OaeubV~n9QmLy5zw%FSz1Nia>zapRTjff6{hTb<3t+V?#^VZ5U672oy3DWV%F+ zN>*;u%XJ-E#sO_rMWDd25Aao5adfc9)y)|p2wKyUqzVT4(G@UUV2+DGZ zvLhCoImzH%(%~4r-c-HAA6gT!ncfGii!`ELQ3o*xz*>v&27zVkHNX4kFZh=~a3~q* zh6l8J_sBbg^A_m^-gHQ7K?VMwkDu|=G6!ccLDME9=9`MPZAf)Qsbxt9okfd))&g%D za-k`5$wjr~!M#HsKYGZzGW^`n{XKs0{r{JyY0*i_>4OupJY%(9N3V$Ybk?z{TUM(z z^Xp57x#r8WYf|-q)6;_(YUDhhe)>ax-cPqCH4#H=MP5X-VQ?OYr1KtQ9Wr=|G^MF)kb=5x?@+u#q-^bmEX(@G z(X3W0#^W)0QP9*i#u$pC;QIQS@o0ipN$=5!*U)0IxZ7s5Z5ua8+v<)KmLv&n8|h-( zZN+lA#9D_|2};GEN%U)Mr8L{^mZHde-%EVV^=ge)3C0B8ynf5u^9u%pH{U?%8H_cA zAb9_ScUUf#{LcUUzwrD2`rojBaL_mKfj*)HRW)P z)+vY-*Tprs)Co=qHtQCgAWP#RL@#&i+7{aAq8tntp^f}<=oPFRw3K$*w) zrfn-SEqQS7kY;fOVnR|^2m)Vhwa5s zC+Eza?7$k!y`w{%ZICkI?Ba%t%LT#rxK}MvLbAO%=kVZ|y^&4Y>%S*?~NNy%p2^mI8zIm-F?Z(cJRk4a0zy+BvJ;@a_lSX1Q6j zSuP2_Lg+4Tp5>JJvLek3Y+JIe4H8M728y)9VQ~)XxZyi;Jd%@OUPmt^Hr=R$%o9F zCAFz|`+7}nJ#7$Vz=e9maTCVx(`VHMD&zUbbY@K1zZgJkCP)H%sy-C>X zNOSbPw}D?u#pnab#(Z>n!D89)dq4dfK6`V+dR?)p z);J~kPk-eXd+AYBA|%Ct$M1i@dDo&9Xrb^SpoPM@NNP*cA)W0Q4@#`j_V*qUj_7z`#2H8OK`GsJ( zH{@ZOk-0X$*P@7091%#99$oIEcOiHW(&HRRk%6$3rJ^;yHx=mq9@Lw(WegJZUf`WT zV=>*DBxsB*k)&APMy^zdDeQ6c-%rka=!oz!drXH8;XOv=c$pzW9rp;%B7=#WWSwAw zz{(OQmS~8N8?U(75O^02=2>ojlu{IDYWfwTQlTQi0 zk%{5^Cnl2p#Lks|x9QmVI@sAi`oBXj!?wM2Dk5Tgw?_2O#dZ*ciXoYO6BK&+mh2mi z-Ge&kDTd{p3@WM>B3#A$uay!)2$stQ&Kd%iuI?zylFQpUO=~HO^6s^NGl)1E#S@0Z zAy?ndN83Ttos za9(i-_t{o8s;{-Q)({{UC50R#vW(VknG7|Lj)$a)>G9_|Itw(Nq^c$Dydo82vTVi6 z+b@|+@AI3#^;`VTKmMP{lZ>{t=rrwzx^c)_4);)rCn(FdZg_hC37c)h>HTl;U*JI7$DF%V+p!oQ_p#Mz2RtYM2DjCyAC^Q`-9Z1E5mS5vZtz<73*h z3-4_iBwQ~mnkohoUSHj!Wt=3hmn*Do z;|;#+aL&^?6+SrXwvC-P(dhi{`|okMe@JUOzIyS3o0}_&qNHhK z2$K+k&1S<7zW;rG=~wod9ZwmI#@sBIyq$ZDRlNM_HS_Ch@ z%`G2(@E$6v(DB~I@SeLuUGz9ukF&0qLpfHfHC0vh$&vw`Xc8YoT6QVQJ8Z1z8;w{n zN9mQZmJs557pH~v6OW$Ea!1<;y@bj}BUV%QQ~6#I8Y0?OAnuwPsT8J*o`*ay`bmMj z!|Zll7cZD^G$S#|uHE*G1`B9DX*@wLu$C)F}OVvB_o&^Jj!N;aMC z8|s*BU$>5No^UYRBlKzOUDq)hPuQ+k@u0{unl`3|U*Fttba=?l0B)VTL);cc(aXPl zPp^v4m1WsoGe4b9*^y9!kmPyJ?d=w09XB_(WLZ3Tvn-?9R{hN&9@si5?+(hHesqDf#BZp2mJPL|09He?RLw0wPL+mu-R<6ytyIIb6&rGjTf4?=Wp0M*uR@+ z2?S3cKjqK<@-L$tY$UJ-w%Zy^&fercmzQtYKS=1B1u_`!-Mdd+H#BvJ={ze}QxqB( z6t+)Q6$r|~5PC94mSnWvQxuB*gE1Eu3l{SQN$Ti~#S^f>V1v24Nfm|Q!GnDsJ)TfE zH>7FKgNHL#s|{@z(aD>2hc%YAi;||cwJcXHRU^rB&1^5lb{(#37-R_#jt>!SO`b@) z?HVcK=UD3)h}LeG9Pdq7u2;BiMdvJOqA<3lvj(XWCgTxVqDU1O-%(X@;_6&L$%ON> zGg1u!Mbp?=K=uR}=R9>~xjL`8x7RU0|B50@&}qW6FJ5D;#!HJafu^-66)4J#&1S>n zCm-E(QJ@f(P zanfP1gj^#>k|NK@y#Ok7Q)7dLJf$gz{J~E?<$BfPrK0Wi+E_y(LOcg$f;S#H$oRvL ze#Bo2@*fbr+#YwF|VS|Q#QZAfBIvcUn-qE%lgW-Ty2$Is@2N-4-vO^4^zVoOY*>7e&JAtmp8@ByFx`Ja%K zyF}y&0w}UFV(wjwF*VnVEs204O;}eQgJDV#iegZZ3eR@6B3R28KY50l%=zBwnC1Ku zDQl7>r)>gcjx>+@@x9TQW!3WLIjDORbdmGr?V6*bj1mK6u}+C&DWsBARfo()pDPe4 zQoe^oAYxFOwYG0c4SYAq0YcD=!H$;BCOi z1U!gYic%P_@G45hg#Zx*UdC;LR7qdNf9-}4GCD3C z3ZYYs^CS|4648S|Z~Gz=uB>+m74BqHcjk=U#v;U~tY13xb%yT;bzdWCW1~VG;D{K@ z;eto@O_%(J4?o^>cVem-+UbMr!vK4OdhZbpeFG!<=2i;XqwF)h=58onbbY0Y8MjdzCqU%Xq`l_v0p1u8JUcNpjNU*l$2jBlb=jWFg3u^mPD_aENgo>&+$_ zWYUzgvkMZPlV?MY4o zxoxQGj^QvP^wTRZdJ}hFOh;XQz?zQLaz&bD{dBwNrvfn_Bg$-i z$-UF4n@w^|?Z6vmql`ex+p{x@LBep5LnbKlJqBgL_{j->^;aJO8O|wI>k8-NCdu}p zOHJG2Yz#~+iy^b=6rEVQX2Z$JF{|}!s&+}|JW8iPPWiz{AJds=486R*K?O@9 z1&8-$jK(9Di!E(qFqtMe&xhan8UEzY{*tB>2oeYeDI+%8d54i5oogu-l-Zi6-Z(HPgqLTRjK>pZlY+C0 zbE>VUZX~VoIN{JT=?fLvr`$&>R3bIwY)IGEY!)5Q{2Pqx7?neO>#<#n$cGHZ$J}lu zc6~|cTGG)71_KfVIf24kGOw{gur(T7LOzPkaC`QaqBW2RIs%P%tc1ZUL6U2PH>iU> zM4ppm8Dj*Z9N@MJ`OF?Ih2>w-V=mpl;}uuA!^yxX3gfs3#NI>cC}(S zo?zORB6~^46@MdYF0VG|y(8XS2x=$##|GyNsD!O| zRBekv^6_V1_1ApFFpFq<bl8hn`OjW{id5LrnS$A8?dW%R}217xfmbli?IaqCO2tMazcF1a8^Z92D znLgsPvrE1+Eg0&!fl;1b3baF|$L&rm=p{jlehTf-I)I20kH$K@knvjUML|9YCX<5m z%Z5=Y@vfyT3*KB+WTO#5X1E~wYs2;1-Y9AI-r<$LlO+)hI&!0MGR4dEuE0)|#I_Y8 z^+=Uroy4Ir0n&b$N9fVYUdCps_gWfjP;wCOYeC@pVXW+jHeLv{j`>=6k4PdqUiQUw z)Q)|<@wjte^v@f!igpOvos;8hq<-ihCn^ZS-BxEO#|C=Cct7N0=Z%37EY9~?zrB2k zU2pS^uiCaFSixpfA&^{O-LP7%c=z3R5x~X81+9rid{sqn#PRVl)BPFO*EbmN@TkAl zRE6+$Kwt=gG)pOqqW7cpnIKyANZcqP8w`ebVS7ze--QY9HXN}Dk$u>%!S#6;o6Q#4 z|K3M~64M!!(v(F`+jjl$SJJi}UAN$)zxjyw-hB_9Xabho+e>ujzy&VfEEwf`q*Bsu z4K{aF)dp+Zm?xs53^|0rXgCI`sOy@xiT70NS|+1?R;!8-1cUT|RNdoxaf{HF)Mk9^ z!Mps;r(ZHE3d)Itx+Y63c@B@B9PsA+EAHLD$A9vl{T9zY`I6uL-+njdiB%P&>42uI zF}A_E4fpqs_~Iv@AQQu6{E+kc8Q=QZZ*h446zzTgChS&!#L%0#j8!D5?rA~0RwH(^ z1Lv4|&l_*3)c~!ss8KXAtb_oUZ{MPNoty~J`WDD3q@k+jl$#qKCV`Q)+&j9@?aeJ` zXRm47n&E6hq9tup#csCl$kUSd9zEuEv81z>P2KX*$DeY2earom)Bg1jd3^GiL?~1y z2+|>C%gJ;AgHsaW$hBfJDfrHJzDwP;TramcwL!>)t~31f*()IM^3B_?DFr?T1BKwJ z?1n7OqA5B!v`*NY&G5i-af>Y`)a@4IDu%-W+igZ$ulegA{5gq|eD^!w;eY?#f5L+Y z_wf+dr^a%9b;a#s$zV9dG&SFPbV@Opk{8jWE&7XFDh)D4>1Y(L>n&|(dG-1Y_wS$3 znvSF6Q(Opi)FAf2?TPBYfaa6z3EM1O_XX7qOLznvZyf?ip{o; zn*-64Hhg?t_&|}SNaDuD6MBL;Pm$;3S%#95s?XTy+Ss^VUS1<*q-a!4#URb_Z8W+e z0#&skNg|&+&vMr54aQm4>)155ZG8Tn;W&mxiT+QG_klbw@gCAFWwBgxu)oiL^WXm0 z+`D&(^9J9W#k~u(ZHwtz7Rx19H`mOsZ@9d?WVCm{&Fv-k9zJBJg9pizhwtG#K~q;~ znUd!zqp|33I-1dBLaq}Avy>-~?{j@|L#_jV{};c|n%ART#^JD^$B{@PU zrn3=wp(uxYlx2#;aH0AE3%zGfNg&VUf)slayu;}w^08)h>_ktPiDg7Hvtus`K? ze$M^VAzwXTp+t$tV0}%Hk`#>=o^7{f-F4i1e8|b;N9?~06r=NK9N)wnPF`lH#PIL` zdq2l!wc(Hc^b>BbYf|=DEVe+7Ah4-wn%dz_Y@~$-Ed*IUM5P7RcZ|j!)&RkWRnGLyE&;UK85b>+hMXP079 z3>Y6B@%HU&goVjqit`SY=UgwA_}X&t;Xc>r8JHSeVm_F3T`M;VigBkQGA)X&EP`BA`OtuC~e{>MhOrYwn#sU@Hw~KF8G! zT4hW`!gz1U@uOp|t);qMfC)$ybDA=hlIx5_rL@Z9g(T@EOc3R&St2={OsMMxr9b2J zxa9mw;ic!ztA=0_a6w(~z z=6(F^i6Cj6CzT!@zzBi%8wC4UnbUap&t2p?r&aj>~FfQudpuCRSLUEF+F z(j=#8S_tu;w%t~AUB_&1kI?I-*F99EGnVCQ!@ZLSY)rt{QRW{9lqt>!g76p{@1FsI zF^~o37qi^+iq8U{PBJMMc;a6dVo(1!h3%C;DrDDSALP-`Pct~#nmP2 z^_n6}Q8G@n^P+&@$cutJSA72Y54m@+PogDhF=Dx{7*FB+{0&{#a(Q{lua{)yl-BteucH%$Ob9qsl3=?g7S3LfB&wfU zw@k)kj*pJW^9(5jZPQV=4b^tbM<0F4>Csfqp-pp#+1yom6S5{RGd?dJfkSLw2dH& zQ_?u0ELQY-Bec*wef&91`xz4)EZ+$sw*ZKxTQ+iY|p9NIS=1B;Nzzgblh@& zwjvc7RTbnN+qK1*kmUh%(@@P|&;##?lt6lqt(KIw=4#P!eE%IxN9MtSZ)(y=Qxz*( zTcEOFdQPH*wpbJQ`dBw(FznGE-sS1j6K3;*vI$ulrZu!?gA|H#TXS``q%2FWE;poc z23}wqOH)~#38rfBG_}LI@bkdA^dL;2%C(-lYI$+;0&#o7odA1o%B&r!sn-_ERCnK z0#po9j2R87l9*(73~5XrDO#PPq@vc6Ry(AZ#5!d<+{ZRgxIdcEEKB;LW^~{fd&QrA z_kE5Z9I{wGV{&W4wrUU}Mc9y$poFI~hL@K!hDTF`zeb+J>ur5XxgLq!At3wku#= z@FymT#5RJqt%y44xwp7NUMTSUv_@)ffp>EPI!_gDYE9)TY zJOoPOnk^!A7?B3LlyAdeO*&+kIbpn`MdOH(A=)}@D7?X`K2GXxGVi)UTsMUmf>uhB zw1=xUC?RRB$Hh7{q26~0@b0d^*=oG1AO8f*Oc4@_g!y6oI^;@HQqL;5JF91j14$kA2Ks&Lmjf-tN|DdhbSFUo8T#2E|z!? zWmyGkoP&b{ z+O`g7dIy2YvW%uEXq%R*tOIUd>Ki$*lp%mMO>?rmhqI2NtXQv>ZV~VnbPD*N>M+w-hR(LNM zPsiw3Q!Ik7<=)+UELU5ep1!1wE&cI;)0da*j)%xN?!Uujnv(TIeqe8pQdT4$_*0F;r;`D zvQXnP#tAF(`iIreH=rbDa(Yk=t8&Ah*8BXs-~)OGm#>$;)W%Wm+#lgWfAis>iYT1P)ixqIg}o|dOipOVBe_wG(OKRYE$Lt42to+!!@qR(u7$(wK7<>`|XcE&lg zMT>Dz8_S@}g_2T*38u4bwiQ}ev{gydSn@%RiW1JwXK0-=aDqFBQxd1y9qnPOnmp;# zAMa2#TZGgdm&LI&%<%+_v5FMa>5y%8#=Bp7fRfL-x;SUp??Ke^*2CNU=*N$72E0^A zB}vj4>znX3Xe!=(a~JPMeE)qBy52J?Tl5rEVHnL$O&A zOG7Um;(dg*YbMiOA{lhuo5B<69e(?tenfxpFx*_1ptNZsPxmL$zdlNhTrk~B;h zFE5u!9aA+kdZ{8&jy%)Bpow935@YKN)*FM0QYvey7MD!>374}CUclsF%xrl@Jl`Sli-E zh%4~cf-}J*CIMRR-Mhuf=}VLq-Nh_8I3AFshNfQ8RG$5v0q5s)44$LiJ;sTqk&fJK z$fQ8V1ERf@)6*Ht)r{U`!2IGIZ#4rIAzedDgY<&+<(y<|LLqJ|WIn=KixvXYwruJ! z1hH8+!EFU`7HEiCLTwE_E2uUr;+1%s`}~6Y`%~)5aCC6Y@!>A4YF@U2 zHdc5aiad+w$;(sTI@$qwP3RHCd7pc4yvfD$&yilz8iNp?x~xgkoG2MmEH23h2Ph1K zG^I)vag;!uk*kcxN#tsUmIhnH{9?(APcL}$D`QkOLkmyah7j7O=|aG~KnX+QYu5E+ z$|qaCG|?2>oXa{VmpPsiM}_ecDKa3)N6RuGMFXrP+#hiq-wfA+Fc<{#W@>#c8P-vd z4XLg$MWV z@%-5{d|h=}9yZ+h&e1l(8zYs%v~75v{dF7VZ)%q`P0rX(b;0@6#WU0t6JeRFCAO%$u zGBuj2rl~5DSX0&>6;^meDh;whEr=7vc2yuJp+4AbHuML57V8x|qcOeFkjI}rM#Pfo zV3+l}V3_YQ$YXlbHIF`0{P2&Sb9{TBS-If((@!`)ew~Bc_n0qceE8n?NRpVt!(D#n z=YE#E_wVv={-5u$TCAB}u9=-Z<8t>UO;z#9y)UE7V#D#_5%=!g;qhmW!i(-hr{%f^ z;rdDWV$ChgRD9BG_?-{l zN2VETonRFqA@sALO&<*gltn?DXdGc`wb^Vi&Tw>ez_S+@+&Vf!2*GeP33LUidG_Lz zqC5@8Dj(iRUW5pHZ!Jnd9QSA!o+Of?!N^mDca%lRwg~9JavO}l{XC_=Hz1B;M0dal z5xzL`EMvV|lO-cAE-tyXa{$T_=P6iE8s$jWG8pu@xH#vnhYuKJ5xc{EY#YcFu5AO^ z%X_2?9jyo_6)I10t>e+-=iI&b8cs;Eeom}nq>PyE>~ntkF@w>V?RE=NaOci#cEl(%gvG`3Eq|AuuoBJh~tDLiUO&sKR`>xu-B()TQ)^`(|oCp zAkj1dOWd|i2<542wALXNGzyo%bx2`r9chxXEw)5a%yhEDK7V{k z*01=R|HaSoTmSp_c>c5^O9ZCz)U}~5TaFL!aPotXu`bZ8j196(DHTbQP!Tcw#7Nk>BUPXyBSYTK4voPFBpCJ&soQ6)$}8F*&-vhk zCu}#8rj;~y!SJxpWSnz)vBG)7FZ}$wWSQst?|*`+1WoOjU9Oo<#%#B1=CcK_zwv<4 z(S*9*($<2@t0lLO57-u0tdbT9p-D9~} zlZ=K4r4T{|JZ@_^m^8?wqF6hM?Uq0IH$UXT!#8>M!3q7_uhHAt;nQtHK}@AI4ycU5 z_y!S0d~!bL*8tsZiLcMuYV(9q+~@vu zOtto$G%F^9wrdg$rd<<7A*;#xkg_aQxI?dfdf{#Yybaz5A#vBq(4CSXO*P9|jf^D{ zL#hmQSX}cm_09Yd7kj`ObhSNE&yy}`mL2%;$I-zkE zBNDvIa5UXUBcw!I5o5h3k`{sM?of;O3WvnX5D0r6wrgdIl)>z;qi_ed*5JJ)Qu5|J z4+mP3;rH^;d0y=9citWwD2XPGs2tSYG7}o^lO26O7ITL(21a*h) z=#Pc5HxL`qeO-+PJv>XNdluwHQI-hCcF z`i#TFefpywi(*MHj_CJtl&En{PO+$&zue-h6Gr1hvZPPHmr!g9VwG_J-UFnPn5NGyNuIAXJ$lP6J_0z?Aa zglPM^sVM6*7`E}B$_kO+1rL+-zE%-Q@DuRK-J@{=EZ0^abgpZY4Zb;HLWeM+${xT0n} zP4Uk1OTYLFeD}K_P}U8<`@8RRc3IIl&1!4F8HS@>gv`0PSP(@i7>n=t@v#mGyIB%b zZkIQnlJ(l4iLq8t*A`mRYq?l#7+8qolx@+lF1Og$5j%;HhCChfCx7w-tjlAmXeE&~BU^p1ETrSD;1WC;0#fGNx?C$1RS27$18=BT)ye3s1B?PIC8DxEgaF_<(cBOnbL%08yGPtTKH`nn?sGZ2WK(QdZx?vk z(CY{Jh*U#_uvC>L&mhaD*tWv9nmiq0ni;-r$diOGy>XwN$%NCz1xjG|-O26hK2BN4+efm|_j4Xux;ge8hK+8Pq?kWI_#V$Lw{ zF`n#p5=F~my`?7f49B9_tsnd=#Rcb-G(6BI8M-7ktk@I4gG%1W;w&y3@sH-Yc}f@ zlW|5aBG$st#0hHah*ZmPoKqV|yRj4qw5W*^hmw}EDbXqmJ^>WoM{YXo^OVp}xy2feO9yuK~Mq&|tl@Wz_(J6>J~xq((5t)R7# zdP^o7q-$xsrdBzrOpt9&EUwFE-x<*D&G5@h4_Jh$(XOSGJzA9$#M!p<@KoXH)hT6B z(yF8j_iKoJN6hlzWP(AWz3cv82#pJg1TjWLT~ipG*4Aqz>c-0;Iybhp4()=RQ^@O0 z_4R)`nbVCLK;6`Q;SmOii^Ya)59e=8-@^OOBh$&1-K%XyXgUJm_EqE3(M@kCR@ZW> z@bTl}h`l7nIT+?W%p^2d&O4Ggp{i;Q4-SHa&w1zwjFmCia>J@F$rKn|@S9kRv%#}5 z91Tg+2-BF(UrE<+i5p3k6p|!~X*(4DE2xXR0qIB)hKO+#(X>stm%XDkEzY|T(yAm% zgd}+(p{NV2ccET&j=BxtkLv;GwIU-(sx(R}mWw%~@rcsY^!hy_86@9r6W}Qp$7DQ4 zMw+N$2NqSjEz1gCK;NbQi zzxK<&#CQJaJzktVB{4CgwK(C>AN}M*(lp`p?35%;!xN{tGKr8%^5=i? zBZh+ktM!&hDZJDyR$F47pmc&U4Odq)c6K7By*}0i&Oj(|C5`f|nwr&Sfv}Eo7Q$?- z32%Z}E2I)=6_Y0k)A5Ld{R4J(cDnGw5E-wdPEsTlk&YQpcKGg}z0ZXdoSmOD8cz^X zadLLXWOqW^3vcT7dByT<4lLQG6?cwzLXeD9JbU_-ewwf|?1O7D*MW7S3jtDs!&^s) z?oA?qILf$p_a2RDxVSi@Z5>D(!t1OfPBXIJfc1LKbZ3WgzsIwabM74N6DJ8*mlwz= zbjV2@Go4Q9_xt2|&Tu#c9|G-q{UB{hl7yxW(|o)SI&jgEXM8X}3&J)+DH+)1-ZNj! zL%O_Dco`1&C=M%Z9cjF`H*c&s32z!}gJkO3=o}KtMM&5F!di8^-4Z7`#UF|DPl>dx3JXqy)2J#Afg;XZUz7J+R&yVE_4?~uD~*lJ{1 zM$^tFv0Q5=(|8Bd-(V>le~(MO+f^5QvFQxiu)LU|q9B!uA2H{T-3a+03r@OaGr zt(>}9lSHtdFM0gr6VB#;ffo^3o{^k$Nkw!X)@C|KSVOmL5tkEKv3WZQ? z)+NKf=KSJ36wtLr>xMY?WNC`Dj#vt^T+>UlpwCfsYj%&j7EgKKHMRo00T-c#!qZ@# zW9MjqQii6ji6TcF)o2lu2+6QFV7{L5)9*}aZNXw)uqwjkv$dXKzQaHKCx5`z*^)Sd zNVK@xP}hck``z#I*4+_*E$WY@q~M~?ot$M zv=+QPJLQKz_<&x2%>9SA8H{(yvWPcdbG&$R#*61CJbzlTcQB>bPdVH_LMTB|uDQH= z$!u{-T^BrjaGTT9C&Wp@bevOex0n*flRipWh9kjvu!9ty+0}w-vtn!3v{n(T3?bT( z(!SKpmn#N&#@B!9tK9OtoSeQOO(a&%Xnjhrd4^s)%Byo^ZP_1;Iae_+MT3oVc1I)3 zc8hfyDnMmn@~l=X(f)}&dAQG%G3wrq)o;>|mUynFwU-~aXpoR?=t=F7AZ`gfzK$5NzvIbF;#1btd zM3*07@MszI_C+HZ^?P`^X1l8CI)`NsiYUO|_s0T@xcgUQe{cZRNUcK_WfM zl{mReBVvqKcp-_TLpEE8Elwyb5mu&HnPA!taVW*{LIzW{hzO@f*c2cFg4Yq@WQ@=e z&eTEsFC!wQv27Ue(hZ~n*rQW-T>B{ewP)d4J{3Oy>oecq{5*UQGeFUOjO?KMl4}8w z=XzuGYC4a<_HDRVfB($@yOU1&0B-T#asKiI9chG@H(RIcA?UTz$P$zc-nsDaTSx0! zoDF9`(0MduhkOq;#@*Lm!+6JJG~)Qy5zilg+I^_Iscof{yz$1HJo@Yjv#VJ*`23>0 zDF9nW!#+hB?t7(mkio_=b<+g&uj%r?k_f4~nyP`KD#^3_=Kc@toi48`io#~TuCUfJ zo$drrMjTT&6<&qsHAxeirY7rWBx8e$BS<}ax9>1pZTb4ozQt_ugeM=ZaIGcDW7dmh zc=?g^`y=wf6z?5M3!L4s*qo5&ik-b7B8|!R9QjehPJO`QVnbbT=;u2$?WR+z81g*B zm@UOt^1~ngDSz+>D|UD9fUcQLr|j&#I@h_b>-vb8+*Im-r#kG5HxLjb11cK6OJ<#ka641_GVQX&Zv%` zah*JVeJ=WIPIoX{U9ZorwP6CDru6zf=F4?w+V%(~P+p@P>`bOu0yfxM+hJpU_nfF3 zmUdNzL!qwgF2P)PL4%e&4=BQ>X^7*fd#*j+TdJz<-{#<8%%-l{7B#cEC(SjW7*9t0 z^w-{II5wo|l;8em-{t&#!~5U=03A0BMpK?W+n|(YG|GAF&10TFe@1_h;9SA2gPh*D z|H1cJHIkyS zY+J*pkCrIudE@>bzxu0hbGUz(fAo+4MUZ{?mU1)Wt#=|0j~+1p#~<j6pAEFi?1>8T6-U9pkKHGCC%T654i4KO1tm zbBDd%UDm55%hj5uHSFx~aQF5x)6ocLYwEV;{A$Bwyi2c_^1)wxz`EG7p3RBIl5$-# z>`wxkTY6ekay8#DpU)WehV1X{FrMymczla@-ZflYUh?AP1)n{sxpjENpx0x6f0zB; z9g3o5Hos)E-XK+s)(O@{9PB*g?(w@cO~HC~${P>AMq{=h6vO_Qx@xiB(AtWJ50A*R z2x}VN{qmbg4I-}atqb0(1iVmO%vR_)quqKw{PUl1F+XRzmoU0LVLG&!dP{k6!e(9} zy+gMUU936C`{a`$>2yNlT26ey+La<-(mKkUZap~O16 zb4=SdY|8>C3|V8J5`GA+HoGyCGTko(o`Y;M<$>WS{Jq<%9*fX5y59+(FhfXUtE<3FqCw*2~V5=~%3mp+0F^UY@>WvbWE8XF?oD9N)ejBvQ@=X?53VTmw+vdFLG- zefo%t%QLJEY7;3%hnx?ajMf;kUQTN*I*MpagK-9rqTdgJfpHSE-fZyRGaL;=VXpxW?+jYgJb__d&_3O1W9)7=TJ50L@Os})BFhas@I5a=|av@Oav?CnTq_2*P& z%bduBW^%zekAzP!Xw^|QgNh)u+Tra7XEvMi42i*I5 z!M)dhir0_6#sB$R|0_y2y#CHzc6O&69PN{3DRot|UTruzdCpO?$7FKAFZ|L^GrPLt zPrvgXmrv*9QGz}>eaX)5F5}^ddRqjHXt!h(f}7$mNn-MTk2FbxhEGZ6al&fxDcZFR zhC6)qr@v0tAMpM6-)A|y`a+TXMU#=IaSq!q$%G`bf~{|OcKH%XC~k$2R87PAY!tdlC9Bn%-Y`SzK6?iTeERqYEVnDR zi}%=;B@_i&uZOh_MN#qm*;8JB?KPf0`JA2UgpWS{gx$#)?^~R=cpo+d#u%*eD5<)m zp_?enfRanIoXxf(OA{Isf)r!Z;=Seg_HAsZHP41442Jo(i`ugaQenf6-AnUzt3i~ zp(u(QL|vZe)OAgs=bd*V#+WTqO8Wgi-g_=CE=eNCX1fVKBx}2j5yfh?AW0ImPSBzy zO*O_EvOGr#NfHOcc@)KHt*NW#X7f~*1(DYDdwFNH7pyj0?mc+G(-%*rBUpDY>n9H~;oxx==Cy~!@8FRxHZOtIO}%VYL-2WVwz$_>4&2dc$VljQ?i zW6;_L^Lee1tezA*&?KE4+r#w1ZRkduw~c`Wl2Ke982d&lQBXoylwDJNk7p@ zQ{(D}m21W;{+X((~a*&oE7o%d-=*;V!XM zc7-ajBymRomHHk+6~{G%t#)-`wU-{x?C%B{U%s$O0-_^RcH zKXCNNeSY>^zrynq$80fYkZE3jc*Jx(;OUc>6j9A;W4L$!F2liyi}O=f%ZRJlk~q># zCj0E~?J>KYadC0Q>T1bL5s_tm9^Sc6q#fhoC7(TdiEjpc?Mv_S(Z`QiF6TU%J>liE zGp5ri`v?2%?(Hxb_5#}6G%V&`16lBzWspxgIkQp14hHQDa)4giwl;kQ?fKg z%ZSmi$KL)PI!e9}Kx&!KmK4=F#x8m5oeAfs&uQ9%EIy_#T4wW?931X)`QnPhgCp+U z?-6Ge=O-(w#?Y2^klqPMlN6yX1MA51KHe&dq9jUoxqI)BC=$H)-e2(G?mp9@;GHkO z!@qs+5nC)z&#xHxIR`uUDJ~wP`WZ*#5#>e0#%;)D$td>J+a+yjN%ehNq4?=Y%xgUNO5&y ziM8P4c1b^RJpcRx9rfuA))+tL_x|vV#U>%vIk<$g)fr7Xp-MC@4OU82mQb6Tm#a0m z_9tCY7pOq_U`mt^=+#@i&X7V_-&tZJ%_W8)R0eb9-as7kUp zA&C=;?S>>#R zkw!L1{|5Wi@es8>#WgKNGGteHfs>(TYON*K5#eHL(XIp`DP+z#%J6lCmL7#g`;J~E z1(i)`;~2d%h(r*n&gd_PcoiXx3)y3hL27@~2Uud9Oz?IEx($trj6#DV)QtzhIEV4! zbM-R83ei1oiIZv9*aW(flYP98(Jpuc8!w1`7&IE`F)~oc0yRsZxgJs)oD*ErN}UaK zEYZoe+NQ=C3-VgV7LvsqYiQbrrVRm|(uFCaH75MnMGIW}ZLb@G>t-Vi5Cb&9v=z=> z(=`Q6Ybe^9I8FHY!yoY<{q?`jgNF~8OsDh*gFxf7HZ=2bMhJ=)C@Fd8-M4W+GR)^! zq)7-QzE=9Q){$ljDoVnz9mx6v?0SQiDv(Qs!%4xdySG`+7Z_7xY)hW?aKe)JGM0-a zy*x(=aWk}xq6p^`JP|L?&gk_sin1a}5>}fH&WA0^W?Rr~Ds~QH+D(pBYbK)sKYDM* z=H*9dCuyXi5h2-pFz!<~1)n{8%|V%k_-9D!~R_^sVD#PEKB+R1_pP!jmK!d6u(TuUT&jv{Gz} zHS^^h+Zl3ty&g)+z>e;4u1(W+diXB)AUqNT(C_uxY&SQ!Gbtp`UYt_3mY@0N*El>l zd&5HrtBv&MwG^z2p0ARtuhg{wX`t0TziD zVeOrlC2d{PTF-30rm0K%y_7VGxF$}-aZFW~TwGkxx|Zc~Nuo4Qo}BR6qfhwRpZNw+ zlCj*ZIlsK%>T1qrz2IwK{SppPQFKGBvhI~9BS_Vvke1!Gq;(f)=W!kB$x#$#m+l?V zDAqa<3Z;U!Qb|eFQM*FguEbd%HX0+m5|O1D zn=auqY%uIicwevA3!2jLIN+g`x(N|lEEdFZFo4%}&33!RIY(n!taIeO-i=Jon6NRK z&llas!y;wGxIZFJ(;NBRd^QibWfO8RJmIyb2yy@bAOJ~3K~(e9T2hr&FakPDlw>UC zOaAq@|Cs;jH~&7~wd_o$+_`gyx8He(hYug}+QZk`+uNr<$iw48u(y8@raPTM&8etc zg}(wS40=5d_XoWBP8LGO20e;x#l!oDyz^Ing_9RAc>f2Vu-;lWTZgq*sJ0?Wci3zy z_VyH$wVspQClekN=`&va7Ku-hTT&O`B7-OCEo+rf3y=(_>zqU16lHv7*(0=w{I^Bm@gq zY!Cw0Y>?PAh%I!3nkF0Qp{A_Ns;tU-nfa!8Q_SJB`yJ1Gj+wEr8~%FXA$LW{J^bEt z?3n$(@B4jqP8vyeZ*DVvb&fU?KOJC|#ORW)tC7mbv(Q;dUDk+T#k=1)J4?mEU`I7NykH%O&`uroBR-pU|zSPuJ zi4qeKg8o2~mlbVeSj<<>7S(m^Z12!Cnxa_o$)itr=gl`TR`BM-H#j*x;pNdQ@+zY# zGj8A7BTW=43P+VPIaddjjvzJeiQgZ*!0XJ^kU^v>K zKiK4!wOmdw`SZX0GwL!&NJZ0hYh}`5ne!}1c`g(R;QIk_oRDQJ+E!CHEorY}XSKuS z{Fv{4|7}i>7Oc)MxO0EPXqZss1GaY}=JP4dMagne(;xLn(}cS2$g`3xEAf>iN&*ux7srCxyhL{r+M3AI+}a*PKj7$S zit;0xN@KM}iWQ!>z&8z2HuQQOqr_)=1sjK7Bk?jWPtQn(84uqXa&cO5dfun837b0! zmw70-`P`R2V_tecPkNc(*@cXqfqevFlZFiaeMO1DTtwCQL} zN0TqeMaSmmE<+h(g`#X~JQPPK7u-5Hz@h*T-zuyYoSrpo?KJFcXa;eJrxao6VQm4n zplN+JHY1`qMvDdSyq%I~hRT%0u}4v8vQ{!2M)Z6|SuF5~(8AE`$1ImQs*^}h6Na!_ zbc}`}LFiMrj!5L5CH6Y#EZT1$e2+1SgVnqLTg7sd#$p6g@kp( zFKHWu)oAIXW#|Sx9thJQt;R^Oo=0b6S{>n8R~BiFcDQaC(aC6?z38sHrx4H~=|qTD zv3p(DsNB#CDe9I%;`Tt&^QfzmKsc*YhoTb_&(%Xuc=;EJID$cgf(cZ(MDp7ShIgELTfJ0&X7_t+?cp0ybuV_!}kM5RLW=di$6MRMUgtZ6vqkG}?Of>``qmiEFE5Dwl+I{O>8#Cpp7WPK|2Z35o17h= zuv%q|`@Qv^P+S-NN+I2IR|?*J_gy~w>{Dj5E3%>>O%wbuAdt?c+;tt}iR%I~*3#?u z@T7<5`^;A}nx>(yYNt|0A#GVxRRz6%%H`RmQ1&Y%9| z&$ybOJHnUn5W+($g;X8eTYKbXMmG2P>pyCF=bI^yKl_~V$miyrKE-LntK&JI*Jmr( z<#K*bf5Ycub%bpK?(Tn+aeu^ew&X-#&?(nu=Joo0e9!%$qoX5t!dtf|E9JThl;=7B zSP)zXi3A|EB}r4RmP?0(eH|p`D?-(4pS?q?x;NBH7(_Ai)sm)Zu-am!n=)fHP1_Mf z5x(cIJ(WJf2N+P00&d^9#eB7-ES77j)V(jh=h10{=PMV2RxYTn))^bC zUGt{ttZO$H?od(JwX+PZ7aN50kUCZ5bu%m&tMPHNK0;7bHCb7+%**xnQ}}^TTQzvn zsc5F{h=PDP2obuYm!zx~b9ATw4XmAOKX01GbyiqQS(Y?SbDh!Xx{lFk-CvVr{q=3(a9N4p1-6jo&CxWJT@mIe&=_7o2F^_^2^8Eym{zaR!3uk zwC^x{;}tmT!G@E63qxBOgbFcT%V5;w__$=bToFdl*o;w}koGsJDu;-~ zXv$(iT}$%ZBT6Gz0Bk{%zUF2;BF|@;wH)s6lIIIX{T&d3Cr?hOn}(w3D5jSr`Yv)P zm~5s*Y0LKJCYyUVd2}(u)D2dxACyS6wFqlaNR)6?xQ(qLj~~Bem32(E;O3hiFP;}H zE)g0A&i^opB@H|S{CJ=mf#1+)2#FCIT) zu{>vg|0Yos)3L;hYTp0#&yh+p*%&jKY!W1jsxxHECClZ4m#-c%81%5l5Jf3cDK4i| zgp_n`i;#kTzen9PXydX_T6ZXXw9pPX;lZ*h$;!+2(og;-u^aEpFXGUJZ8%a zcH4mIRYeqc^oKP^ujaIE$L4mx*4BWcl$1q_r#!lD#b6Low+3TIgki|-dqd{ahN7&9 zW6R#CuhTC5*&bac*_iz%x`jPNE5y(N=DpV$X|`IOmoK`3J^H9I>g#j?eh zmSTCv&UQeOc!UX5Wy${NHVO|T8lrwgS*|!aJE5w4lHLJ}vS2ifc=E*~V(H`in$CD+ zWq>jY!Oa^HtNaLG0X75_Sy6K_D?yd?qaIyZvpE`( z=QI4!$FvQhH|AV=kXBt=gQO62x^q+U^=l|hi?l7Rj2(SS zNLL_eDzG(HNIL0J7)h%V&@i+LH~z6`p{P|thfgFrgy{f{Py#I^jSOjJMAun_G<4FV zH6C6RU2ptB(P@pa3WK2&5-ma`4a#L_X7s~A))U|F{Sj@N{qO+uQp9b z+qp8-*ZTouKzb781z=o0FNi~=kfc??a56!9ivD=S>G3f^7;t)a#*cseW4`v*+v^T5 zaeb*9t=CpCLswU5<0GZu!Gj09|Ne@m)yS&B_aoQ5Z7fCUI@tox=j7~!$;Jj+8_KG{ zbegX1u&M=X2>i8GJS!-QOKfMkrd{DWwyd?JNlH;>#Bo3`NC}jW7fG6`WmPPRlLQYz zS2l=7l3g`yP9oYO;oi;fFq-tRM)30GbC$~$4<9_>;hS%eB zhquY{oYiv9`Na|22LlX}t{(8@lQX=qWAi}qjo%Jfp55icUmXzy9)g-E?(>5;zsu$H z8Hf7^v@4j;SM2N_a5Y^p8V(4f2=A?T-u{Zzv)<5N7r3pb>92#}ZlU;!zT@GF{q}C$ zU{^p@HY}I(bvV~`3cU8Sd!FMsmvzPEuEe}9**(cFLd2D{t0@Z;a3ZF4RzPKW}@ z(W~bS`eRm$1s9i>YtQovYaF2{&lPQ5b8xWF&ejH1S>k&h7)hs%Ys&U~`u)hAU=jF% z_toJ+>+9gST_4(varT#&FJCg7&A4~}{<^8z5c)A?)8Z?S`)|C-#l;m`TZ96uErY=r z+t%pL`GS3=7>~vzQOs(!BnkqOIO4B=`70NgTRS(kcA=~w3fWEe7*EF3S;_gu8J@4$ z+??>@%Ls!D>uqir1uSt+-W&t|iAhlVSgE6b83PTgj$gR(3b4Tls(L7XHkmId?qlE4os ztBUV^=bQW&|M`DL9LHQ>nQT zU;bDB4d4C2Z?65T4p+QA+C|p}-C3k(@I`~=f^U6y53v0B$1f2^lLP^KTN_-RE*Zor z9+&`SKDe1nFSF*3KTQ)rzOjjws3o>y?`_evf?j`swkxdZ_~=)k@E`r%KcMSUrc=%3RC0B3#c%!A zeXN1mWyy;dPsytjh7*mk5sSstk3ITBk0f!|eh|uahN(kJjqhu;ZaF)DNz*Oq4^o!P1*_H4HNh*7Wq!$LUw%q| z*vAVhny%#Jd_fTQSmsNzktpj$pdr0dspDmee z##~-b8Esh}JiNihc}`tb%w{=B(j&7=4sP~2JRI}EuV1lTl?+BPC&wjM7a46M+1%Nr zmk3^*o|7#zdZQ8F*%~8Nim{fB!H8Ecj+ssu+`D%hjpET4k69H3lhlQymzOPCw#?>J zw61WEz>2nZh|@d7J5-u=dp*x$Or&wutyuBwVfJtG+>WHUoHb1;Iv z-9Em5M4a@QT^1B8IJ~<>QDtP)8Fd$Mc44ShMig%F^5s*Mj5&EcLlg^=AYeId84b5- zR}JG)pRJvkp%2yS)NM|Mx*jMZ;Nb3U%DN`>6h^=@D@mgev_=TG(b84GXfPtHa~f;# zCA8Eu%?jT)WMxBO1iD+8<-)0%+MAVJ#|%78RA#zG@PwD3??<12;0V04EOmJWrLA)e>c z=nkhVNR05XwnCzj7@E398g~e5d`Txmtk76d&eZPm5?inuywAv!2b6Xg@R?CERhe)V;fUko zQ+79ZoO-a9Q(y0UU*|rRd<{SnL{Y@|zW;ripSDb=Q}=)MeVV#LA}CflUg+a1h3;CX zS^>V03~VIQ4$fOc=F^iMVSMzxw*L}^)xOlTURt)cikCr{qcG=TidIOJR=GM zg484M147?-^d}|h_xtpE2~ilWLtf^3Q|g85(DHiPEu~x^blk_6Uq0sI@`^im?%?|# z=jZ4A_V4@_-}?5q_~3&NDC>r@DERQ#AMnj@ex0M^FBpz@dGPQ7#@77e7r&t2_ZW;6 zAAEE|k>})Dj+A?JZAZ3RkrxH4#e%A;ST2|NzDJU#EawaE+`dUaN$96N{B_X2u4~$^ zz4qt5CVe@2f~9Sp!m*ZxkV?5gyYJ*hS1u%&UQNleU-82q{*XbxPZ-6NRg0HINaeG) zf3TJuJE!lW>Gubirlf3^*Qi=Q@UIcP%2RyryWb{^LKpC|79qX$%`a%W7SHzyh8}Se zGM!zqSS*R-n7y4n9zS``%ada)mSMl|HmhrNsI|_9C2;*0T5F`|(HZ^KLW0DT9#$B% zaorLQ6YIMyhH(pn!4d{O(sS3NTzf!`(QAbV{4iQiV2qnC1U{kfqYadGM_v}l^l1ZM${oyFoXt z>)%-8^0d|@X+%@Ej7CF;Ij$?(wO_MY7xhTxt?3mtLJ9_hKE^~YD5w;5?G}68b?okJ z^Y8w9f1CSvZcwad2-C8=J>mAv1LEih_qL8pNDT8(lr&rfFFZk$n>f~dL6Qp zjKcv}XLIsr8Acn7jk$O4CQmOfSTswf7ng)dO5pqSClfroKzWuS|7!YN9wGFP0pg zp0anCaDH*lGSkeK1?5VTl^ZB8pe#!kvl&V{z((3nczJwA^TH{1rn9tlhw>D0qCgnh z)sh=GwrNXCkO<0rjv;a?Hkwwqges&rl&n@c^W_y~qe#<;yvUp{+LPqVhB)*PO4FKx zHm@0v$BZ|6OwV#IFE0pu52I_A%N0==BM=M+W1c)dW^a3w(a6JEMNupmO(L3l$$R$? zSIoo$rX9Lrcx8B@C${648$W|rWw?-6I#m$@hOqb7* zl`D?(ml?jwFx`}`osiAZ18nCgL;E{@KL6w|xSSr-8;<$>!_V24o3seBMS)Na>4WJ9R(-K;VMdDlcZ0ZoGMkB0Y)m8L7 zfu_NWTE?D-$pz?OJ%|jjU4bT}(>||WUUB=tGE7IboyHG+wCFH2AOeC=kY{s@_SxAU za(Uh`y~-GE#++Q7voRjhlq2SgDgA!PVpTC5rc5t#27^9=j^#XKJa!0XW=qc~K z`)%I++Sj?fxT30B;^Bzn#f(4yz21G#%mx0_la6RY{c>*mWuI zY`Vf&!F%t%$NA;?I#VLApKqS;qt=cGH`+AoKgG2>#;(KLc5S^D!toL9`t!VSS>wR- zTnV-36GjpJK_40TlvTy2k3MC0V{&cVT)PCZ*4eoA8hm4|p{h#aDCW0+^Edg~&wj>i zHedI0*mbV8qgm&bOxF>G5v#=#VV$C6jiIRHwZ>khxJF2F}A zkE*Wdv~#;?ZD^a8C@n&F;|y!1kmrtNM-nxFPY7jy#3a@yz$mIxpVgpUp)UQ zA3XY({t>tCkRdaYO(w1YK&b@*5>Iu_O)8?G0lYHF6NjMZ|1>DII;EOk|}TrMc` zoVu>ATN=gMLM4?`IzrDU3PPeNq!&l@l9*9{z_8zAG#Ie6waNbO4tu-1j0OYO;~`u@ zlDFP`g<**A``75v!1qzgy;-jHS}-1u+1qot#Q)&${QHas1194!ZBsLzY;b&X%Gck0 zkHib8iYtt6X^iFaYR>JucX{#Z3kHLLlj9fU`3j>gUE8v=v&H$@1w~P^TCM00`WWLV z0~?zg1Z$+MZClbLAzRGJvz#n*o6)AJuPrtJRaLtd@^weUa5!Wz7?36@!8#D^-WbPy z#)2oEm+$oSl#R)RIEfuWBk)P0h%gLM%3os|EM^_` z()UolPud?**DdqeI=tk0>o#+7$@uT1U9lrP7Z*y>Pi|vEM^)m0Q z59?f$;HJb^JzyAY;bb2;?=8XNL6xpGh}yri?Yl~6OS~GkixAS!dgsciNh4nk2yLn zxtezPz8gH4&JYEHyZ2M9xFifEhll%wq2TmnN?nI2DVU5R@@&RxS)#j?tE&QwX0|wI z)wL9z#P?GSio94Mb;ld`_gOB_XglpJWnPTMBOTPJsNvmrf5BCL0M! zFW~Wu&v|}yL{Y9N>MNqeGM%1E=MJ0z03ZNKL_t)N=a=js42cs-RWB)<708Mx@i9Qt z6%6`guBHq8$Wl}bX7i~-CsqxX1{GSOBw&><-LzLr%G{NBrbEHOtpUqyK~=dv2H#i2 ziDhqZNT&<#-aWvW3L!cslRo`Hf>MUftuaNu;_&bW#dGyH(X3Hz?+})ySGM38{gJPMrJb$r5`5sm@cz(lV(&v+pU*HE@ES4o8hy$36 zH3$11+dC0;QxJtQ@gSw?W<)(rLr&2xxOIENH@<@Bh&sv$~vuQqH0x1;W_%-&-zLbEpb}&@$~xgq5^)fgggg zB~{z9Y)br4(2E0-FraNKYzw0#Cp5ell;nI0`EDvj0^ zY3xz18lq6HyNWDQDnR4=F>TwCq%QB-G@3MZ!?z$%U<_##pp@qZDi+uLE?cDZ$X7Lf z6jP{_LhWFrPbzZ;IwPk+ZjG3ZDXjzF}b%# zr98Begr;T4j6i4vmQp5^Y8x#iq0Ye6l-`g+jajJ)jfg>bC{y9-f~;vF-NvGDZ9*EX zp|gro2Q)Iqcp+B>ygXh~E^FFS(`k=3Z)uhlO{J;ojw~ywmn9dk&Up6pDS!2szhE(4 zu$nD6KfmDV(F;z_PnpjboE#ld<^_3{p*zd-XGiEojVxL`1Zfb_^Fm^wXjeHG7neNx z>{AA#5e7?HmF(^95e1%%uwI*8Q zWQ{SdP&W)IvJ7QmZ+9C3v~B0C>0!tsTOrmi9wET@Ji@?ZJQ{F#u+Qx3isdpxtQ|m( z3hBIDzUR4~E~7~!XR*~<69gV%9FY|{gI=FruSby=YqUSteH{Y#Jw4we=_LpyiPMxg ziqV~+Ygz)|1-1doszY1w1M7yO+IPYMEgkNl{=M(N$HO=8A_K|eCoib#j{A3SQRX?P z#~03$sUq6O4bZSYM@N^$X^-*NkiYz^f5C?z`~o3ryeOxvFS$6W$QFvj8(X~b@Bw+T zM5_~C96dr?kGgRf{xnIrdw3V`bpaWy@m}kL#p@S9>#qvbu1j3(x~xU64;r+q5Ip27%+T}|VdC=3Za7edyib1jK&#cR0g zYZ}(;!WJpr%`JrU(SPSV-{BwslmCP9c;Y$;*140d$r#Vu#8wp#?%c*m!79%w%aU(> z^V{6Hdyk*~tAB-VFNo8aqMK10pUv%U#*+lyEoj`BsNI-8Rh1-(I! z`E0>}KFSmH(;oe_&&y|zDZ+s5tqDrHLz1y;+@6%~z!bUW$-1tuJ^U9J7f#;O=KAFQ z8si#AvD=^ui7y-z`pJFrjU(5X$G((FyzeJA_ey5TK+$N_UgQi6Tj2iX!JSaKxm3 zKW01{xSQ5rs}a`H)D50;_OPOGfq54+V|}dzR8{TrAxf}ZE?tkt`UNoB9ki^lL}BQ> zvTM(yHSPd}6?neSDx31)!F|-@=X7mN6vxcx3rCAc5?0y5EgV)eo{X?KgHn>ZuG!w+W;UC% zx3|Y?m9bnx+qBLyxL!=_x~A*23(MCvVd$Z?Cd&#eaCv#j&6|g0`I259fHZ_*Oqiq$ zq<4J}Yptoun#+p|7E?{yOSy5d&+Os?&v*F^KN&fC%5^SFphU>oS&p_9oj$?HBQCQK zF}g=qD5O{L!K1%Gc_C#rWwHs{pK^X#a&NNDe7@rN_>5b3H^}NKuU>cdm1@2js=SwErBW~S&z;b@ZYEe*k z=LB)Y)#(i14~U{3SutmGr%zQT{2F>`%6Rb4Tk&uMjv?+K32uh`nz zVq@sjlwWe^!2~O6is}SkS&E`07CSup#WUW1Z_L3BNiP+gzNpyW7<2sUl%lPv!x1+p zBld0v%%%;u!##F~HGWX>=35WY*3vc|Z5J+j%%!6S5s3=DzQ1OggssCA2|GzLu)cO%C6;w<1d%Gx7ifqcs%bMqd zg7Kz7c$TEsLsS;2BdWO~TQw-(DdJ7pA`u`BLWGz`GwS8wvMZ}5Ea$b`3JesEC zV!C2`bBI!|WU*=te&AsmfskOW1S!^S$1PTBr0@wmAJer+RWe9@7L~>%A<~Z#y2Q10 z+jR~>U&RA_9-e{w?15#yd#iGwBZyUB@5(i+|3uFCVkF zeZb%SJO3d+_>CVD3}P3a_5+l)6swGnKKX?I_P_t{c>MS=_a5GNkQmRyN~cViuEVZv z(Qc^CwF~Co?ACgH=6K!yE!LkaA*ieBI`>)CHT|@QF_yaPuolLnF}87(MyxxSx(vFw z9%TDrz~;t;!y5-oh6A>@H;~5i?f1UP|L{NlPh4DHt@q6WrF^>1x}r-g{u-b(nM}yC z6;@c3rx*=~WLeJD)r_`k5D3Pj$@O8K_0Nsdh#(G$l8`h`(T%}Z0iKjpRe24}5z-PT zAwp;(1Z@M#Q@r!eL+;$Y!_#M<^5g&KpYi6K4|wwIC6n?~F8MHH{Iw_FFkZHv_oo0TLn z{eDWXpOU7@^#s@jzy+QkFdUBA+}vV3o-iDY=%)#36wr$!hJzmCai6V?F}*lONr}Nx zbd0s@5-umxz77aEsR=wJW=%4ZR$-(-G@2(bUU2^MnB$`(I&BzlZqXkNxYz5mZ8TRW zXLP1w|G`5}ULE6kK6h?DpcRJm^HZjmEBc$;?!v`zc~2@+^BQX_gezL~1D~=i@RVe+ znB#jMMt9VeYklvUhRyL9VGaE>1*2)|3g1(7O-)nR*GgAWwuC_!octuldC<|BTi?Mn%sFBE!+E8LMT@Xwc{7^DC-4 z#}66~4txO;Dx&B+%1q)&fT(%1#7tmE?XgvIWPnMjXPg!ObWJ1(mktP+9 zR}l6ZD!X95no^e$$45117X@+TGuevBtBUbD8t}>K=#rA>V{(~KK?eXGq#+&!P z&iTbNws!)aK3%dq+2J?8`z}R3<>7#jhWznC(b zB>0IU2okESV$k;qV?myEeEiWd!>G^A?LO6Nfs`XwrN?41!`PgS?LJAbVq?1?i4|vO z7ZhcI@idd|h^?_=Z@bT=+C-Sj<)gVT2GpuC7YvvpL1e1z^V;F+l`@SJUqa zdcBAakBe!;#%P=O-gs->{@fuEcwWT+_s{+*XU{(;?I$P|p^c(x9mX~AG%A2VDSBZK z)kzu*gYkr7+0nKQNfOf0pn$4z$Y|9z)Q!dqGzW(%<8j2G9}|QXo@WW8O>`U4btP@x zVLLwOUp_H>d zDd{qkT6YKyo^ZbZvexLJN2xZ+s}LDkl$YUSux(8!!N<@@pOwFbCBkbfY85jN_Q?Hh zYLQaQh*mlauhlJ;>{ACLN;SdCgtjj6{D4|Un69JoB1$hs6VWM;LdFzoo0-_6vLUXp z1J{EP49Gg4#_Q1$(rJY@9@g(u1tTuIkWvgVB0=RHepRp=2W)sDv4!2Xg#p;kC=`-0G^XTJW^WyQBoSq%?jc>k7TQ>ap&wkEFpMJ*eyLb7U zzx#VUxO1P;a6~VS2_hdniB*zbf57I(Hb4F2KjhiT3l47Frp|M2?(Go9Db^aa&~76w zq$5GC-Sujn%pa%dAzNINS*~J{77^~(-}gP| zJZG1iH*VlrjgpXO1#y&+Wew2f$3OlJzWnMd>bfE?Q!G<&aj_Dq1*X*7hVhKDDk<`u zB#K!rR%oG#!vw7@glG({di&-byq3rA!H6^u z`QXEM3BwILyA2uay>~z0yC3|3asQCN`|H2w*3oTDY4P&abCh%mf|4jnIX*gKG}xt1 z+x+NzzsJq}+q{441AME^PH%|b+1VjUk~gi!RaFtkF+zxK-hnL>T5S6@Kr4yVO><*e zRTOV7t&L?$DuLs;^tyI)afWTsw?;}(0$j_+we2QgTQq}Z93{=eZOc)9fBs*R1`)G3;**Ep@UqVM;DZcy9+ph1YVJObT4b z=5T+HZm&b9?IUE(FF*Nvq9kF^^(pe4#eBZKep@K5vCwo{exm|ygZK@N!PweknifW_ znm31(P1&H>GOGW1YOiT~RFs`A5ANT`REppK*Z*0wxQoWuD5czXOl&g_bxm2-Xv^j8 z4?g0-*Pm0i9lGrnwGbGFwY@M%THPLRzxO__=kSl8{4Hl^XZ+xM-^FivZ-#8!w8)F5 z}pw+sd|ntHolmXo`J`g5_dC zztd zQAwk@RBC&BMQRQW!<`n-&njM>OeiHhd-j6mT(YxsNU!T+-tCZNSKPlhWpZNB-!W)) zEkscvRn6lk&si=Najd8)IKH+=QDzkRef)vN{&Aa~vCYdTGn8l`0)DGYo=)(*7Ml>F zG$stArbWH3w-h6&s}iZ2*4`H{z9n2O86UJMi7?Czr6p+;pzRihSaJ9L7XR?qFGvzt z&K88RAX+A*>l88c*n|-uygeoiUs1&tPtPx*Dv_!tNzeJM-~9k>u5rB$R=Z?1tGKvK zIeB?SQIsfC&}lntHaT$`U>I#oTk`%#JH+WF=dThjPbN54kMT~6O>oNIu7ffS>gpM= zqN?UxySBq@x@I#MF)k$YpP&84Z1cC`K9vkyP~B zWBLPw)hxl%9?DQ8>6-Cq#M1}oRI=vA{xv8|j7p+aP1koQDurn(_VydgT&L@E{n{>j zM>Wg&lDaN%43AXTNEBV)pvpINJB{DQj5*d2@-srCEbo@v6ypsc!a7H%X!I;Kj6vB4gG<^XeeoUio7Zr9~itkU62VneXrG|$)~VrSGwiyCQ^gwX_u zs2me*C`?NcCsT@gO_*jlrNC?3w7Y!_<#G1vinvHPxN)7u^n!lR=jE#zmGH@ml7~;8 zHFH}f5mIlTtAac4+~upk`v0Jmn6AZQwI+@dEL~yR8c%DKYg0u9jxs5AjnT3>@_NKU zNLmJXx+J0kEh+MXQluzZ62}FXXB9V(M^G)0WEfI#a(YTISG4^Gk=jfl&5^}%Aq<)# zwNB4qF-!1Wn|{||yGV1Svrj64fC=)gg#_Y}6g*`GUSZWGyz7Sx#vVSsNp?*kI>2IbBxzh*jMo zp-);F$Xv4$HeGL*tae#t4pCJijT}R3E+P|0?h+av(6&Q z?vRBNEYq4$Ie4alS}(Cy12$pIY?a`JC13yi@A-`%|0`OxfmJ}h2>G*r|EIiqal!{5 zen7`|XgMymZi3O4=W*x8O}avnX9-alQj|Hhs>o!4Ms8gSiW>PwwRoKkMu>(gww){A z%z|6&ZZm^yv%B@S*IX)sFkm>?q0?58iv9r!Svz`tliz z`5f1AIXXI`HE83xHknFW`S5-I_LIM-77cnfuga}$8-ggnG7VlQO$@UkdI>aT zQRDlaH!y;tD45Kzux$&|G10bSxYJ{`s@bep6lG2&%*MLCwbUDRO`ayCdB$kig|fo$ zc?|dalys@@HnOd*ezdqpQi+c=44%d$EG8*2ck}1)8&f~{3 z+N~iUzWWZzIHk;TRKM5%A>5QcAKkA<3ExZ@I;vR#i^xQao5piXH-oTkm>8zUu`PQ2E|-^=JbC<>+jnkbTIL(fuiUbzrBY2Mf9uFC zs*3UMn6tAJsLrk$Qq?3RaH~g%|f<6 z-lgAdHSOS1AO)0pK~cihWWgrMSZ^YdB;|)c{2@x|ErBfCHfA?yzHqhRC%^tZdR=e( zI}vodT~@0VQV6nbMgt(v8_2=y<;k*|yhgj-W;&f>7zUfoh9C&uD11sOu3x*(!NESx zmN>OqtynCVByo%s64SPclZ3LW2!enlP7qR}Rim0zWr-BxO@GXTZy&JPgmgL`dc8ia zmQT0SZ8Av*`&_?qjicj3`hz}6lJfH8gn#<%Q$G9b9zXy2U-K7#`B!{%|649DFG;f; z+jh40G==H5(1ryS!MA~n=if$azmjx@{lOM2ZN$}kC|r1_935{{3@+`s<>%j{x%lEI)u z7Ds&Vd&i6qC2_Q2&@pkX2rV`o9GO^Fh1>G63=>N#_QpQL9h-`PvH-);wEG9-Rhw@g zUhw?IIYGL__G{XHizJIES>w4rUQ6TnE8;k$Ol+P%nUcf-mYL(YIXABFL*+7GPwBRs zGN(8WnOsCfn~aaX+heq6(ra7nbUR!--f1NHjbgoOGI6HSW_Ps9d@)69hf3shdo9vz zgP}@}4tHod27{sI`i(xs?wmYL)=!5 zYa8T6h>$g{mW`H;TH@F_Wf_q~imEO-J$u4pzGkslqjb(>dO;~_4CxT86I@?oIXOz3 z%;p;mTM|bBJ9{14J%R03bbOm6TG8v-TRKlOz@DBgk){zSN7p?5;nOd;nieRn zxx6@IHIL{In%49rs#r`j^0MS|k}(_#TqmH@jX)+K+B|z2vzVt_YlK9|4BO5~;*dC2 zq-Bj#2GJ(e2?9?503ZNKL_t)iE^K#5s?-Nt+vK*w|RB?jIs{MiimEv#p%fjZQli&;pOynLc23U zS2e%$o4*CGKlf>dyy^K%{^tMrQ(A5tZD^t-B+C*EZDJZ0vR33$qqRkrWGpr-QUkhP z8_((?EfZ0eq_u%1J2am}1*R;pWD8jeM!PlLZcSB4AYrwssS5)`m#A%E*feeOJj1XA zNvzPi#A_)`?XsE%*j9Yi->Kf;)B-BOt&iR(j5fS_@swZx$*&VEHcZzuu7U}*qp2Lt zGL3os;yKS=Jm>k7C*+q`oL!#dc6wx0#=+4pmT5P5T`4K6X3lt>g@mn&QB_U>;mSKF4!y!p(xo)hW-OKIGGX`h>E`$?}TJ$sD)kV^}8R{XKTZJ1E^yGLZtu zbE)czy}dE}dxuTOOuK_+JG9$AzTYBAA}q&ZyuV8&N|H1tP9yrm0ZIvyEGGyD7VHRSiJYqTkIa}a(Fo6!;jwP`t>{P?j3P)F{ACbxqbUx zcKSQarEl@)*Wi(eorlhyo^ve*!XF{hWW5Jtr0VnQtic@}w4j}9pEjJ(MC&Ue0x+TYvz?^s_l7bDXGfsa*|~fTUrvb$qESMHe{W93uUIS=Xr-F#S`^Xgc6slk5BP&W{4W^q?XkbJOJA5+X+e<0 zyo#3GdH-#!D5a`%CUJ;Q&E@$S7wMAQcWx0c67nJ^FH&qn;k8X#u4c8IvRp^>dlshU zF`KW+$_TGz5(XKD_PBHVHl}H^S}fQfkLh>2C;?H_}ZD{hWY3=qr7uz(%sgut|#fSaKeYHOJ)>x#N;e8pLs;nqT|{8UVsxQ??8e>K1F*NTkeIK**+l#=Cg z*-(47;kA65^Vn=Q+_-Urz40!--=f#=W7*C7sMTsAgk-*4Fq_ZWYywVC&p5xhAPfVh z(<$rCn)PZ$631kDO0h*b`+l3UtO$dE%gZZfvnk8@f;bMTDbS{%)As0eTa0#x9335S z_wFtB#`~Ct#d^Krv(LZa&;IOZ{NMlKKk)DVJa~ZL?sEOct>*Z!T{Ix# zn}>fxw_6e?GrBzw*OlD7wa1;C$CO#ZKm6jKh@*(^sK)e7ymp`QXpdXB-{ReOKjz!V z_fba0!SMlkvEtUzn78g6GM@yTy;{=mdyGbH@;s$KXi-%O-Cl>@V2BU~t4+w&WWwcT zz}01fHcf9Aj9pT4!w525!g0@_ZgYJK_1OD{>^J zZII^?e#^pfCHwokeDT>g^annMnPOQUNt|)>_CB4C$=mN-LkhTm?>WIHp+9OPsaVe= zCX*?q_PKs-#QwE4-HyW69#yI-iiVih@oy1EDZ^nO5S(8<$Fe=1J-cEs_Hi78(^nIA zhC^&iVkkj>;2>3wG8JXvAZwqp2OYbzNXO7MrL*YDG~7^x8ev z>otqjlHtyPUeCoqvRVbSe49?sK&TXHmN-7REqMI!g8r}ts^HN#6J}R2hX)>`J%yAx z$P~j$fen^f5k;GZ!ji|lI(vZQS?nKNCkj$b!@{)9CTCOR?C&2inVr+_*{s)Vmg|7M z!+qi?WwBf{+!;`n1ArF_x6AsP~=HP-|Hjm5-D;FT|=E=84^j(Z~yo= z5z;^kfv5$QsG&&t)BpYdz_ksuA&8OyrJFe+j#Er!p)&br7jl%^^QTAoXZ z=IUxenl}x}S{i6oqv{q~w#f21H*ODcET5`OC~L)Hmf|=9(=fNsA-Tp%sX5Z18_%8zOhWvrbT7+Skw-=*&{4nmZeSZjL21+xb|2T4lxSbb}%HANdRRA zQd26IT$yAQ)I~`Wgw5q&nIyH?&IA@9sPY8KYn*F^X{rYCzNI(jMUG)M1*>tIVoHIL zXUtAcud2z}8=a2aG*+ag5{Fr+W9&!KS zV}AaNU-Dvl$!a#?n(gsodWq5LAuGYn<3nuAd2>W=oKQ_q7F9z%e0};B+hb-`HA_ZS zRa8YumLwE;j#7#=%MemGp>6@xq5x~R zdhCyO$9PdP7=%kHN_2JKy~-qv3#O&mPfjx9D|x zjCS|&TRpM_sG5cK&hfAD;XChh@AFTg)+~cd{BDI~bxHDspZ@-BMh7+zzPY5+Iz(!X z<+%L#N8jh|cWyA7o|8lo;U>U$ebnw~_m5vM7q6MbuM_;$c8HRqVF^1m+$$Qn}{IJS*#S@gR-3~lhsU;Ki$ z-)48b_hw=Em&mwki@t6Akb}X1#cD&l*GFy36M4OCZ1HZEZ8IK^=?{i{`|U%%{NhV? zcgIL6Fif*iO}3DM*Z&tZmY*mTbrE1v~7C50i8}4&-3W_dU&3PZCQ0ajKRQXwO(*?`V!O5 zxN-fM!N_I*`VLpq5UCw5&M!DSKjHlHij!BDq^ace^nza7K_m%M=7eF$@wK~Db%xRv zT4`!xY};Tmo3dU9Tuvq|=1Y{JS*~&>leEDC)+I`chBS5PF}-?0n&wW zaxJvcSU@i(SG2o5vP|*p@j0&5=Jb4tP>Kf+?s4<(K6}Rwi*QPilvtjmC_|RZC2q&U z?tr!pOv}V-dAvM*i83XplS}ft$?dcpmmhrZdn9qfU;X)K1gjdubol1$ri zkrY=*E!aD3kryQ=rz?`Y!nWH~g~{Y%PP=V2bR4C4b#}pW6O$(%$-<#1V*0x^JG(8S zP1)E4-5jM;q^@{*c229k&+}&&v^<9_DTv|#ZQ4A3@*J&lv@D3Sh~AEY>Ey&|#>0nK zn7W5jR?`<$ReXK_32Ef9nuqlI6}NBoxj0+kxSG7!AViIp9*6sHaelVp)!8ZIgC4fq z;{0;TdcC5qb2h;O)0PNPkt8WC-(|j<(CzlIZJ)2czE4($99v8;yT?onARFer`6*B{onpqiey7p z#2_2OQWS-am%ajJSyW2W)lELnZh2%SATumwP)VCKPRK2yjo0c?R+=b{Fv5k9=TK$m833fl5mMwO)#P*R$XIla=b97Ti1k}1%)ALcRLI%7Z1tV;FYtSx^D8uS(YJ`LTTOn?u0-KL7C@teV0MEjUg&_du_@r zCQl+(%PFhnjM?Op^Yc??^C{tG-DFv*w?LwtqOADzi?4Wfc12dytb+BHHl}bLw^=l% zGn8uPsbcUr(4i9&*4WB5?`R3t6p1pcZ z6qWS4`?NbA|K?x+SG;xidsG-)%uk8Sb8Ii+(YH^ycr_skL!Lc(ju19dDSr3&ewU-e zI~-l#r`1y=i6&S(IBti%y*>8!_6dR|j~+gt=l6N%_WRsCdW+jP?xJCv+TV6)ye`*M zN};#X)tfB98&_O&|2CAywoGix#4sAWPgRysqzEDKTnnvTw4qU2V``11n(T)X+vag4 zxAo`EoA3>PTE0$%H0lZn5R$#!2H%#I6_=AKfBDycL#N;2=Rf~BKYZ^ac5)4A%qPG6 zghR8_AXt-vq2ZFO*Ob0bnnsu?uq{dq2CW^8LNTAu7jjQwfvm~ngd#0a(k4qX z(pV8D8-{yL=shzfnTF@jUm#G-=Sw~hzTl$|KBVpYTwYB$K0YE%Q(ioOPLU>5MULsX zIF3iB?PD5}LAQ(RI#`yC<2cR3BrnlQW0=hYhq`&Nd#?S4P#{E8fG1>=k7x$^>W%fS zu1cyJY{O)Cu)|;c`Jb~1LVn{nf0ME-e&zSCYm}&{McpvE>!y6?=B+zOZEXn$+nkL6 zA*<~JKu}4=-r*5{@P~iI7oYwUfBGN)f_LA)%lq%Wi(~)GT+Qp(*z0n|s;nsTypbB4 zzcN+XV0rT-Cr>l7sw7Gy;y9r!Dzu}}vL;-wDP_p+cn|8bLE-|g=QWJ&y4pUJ3+lQ= zNzk$>_8azlxRyz{UO`o2TNV;DUAyfrrK@bFQmLjbbRLwGOnkJs-Q4|H9=P{qp zQL4ca=Xw67^TYRj%Ce-@Y7qnhhS^x$nzrwzpf3oUk{ri%F-nWqjpO6-n5wE88coso zanmFrier?NO@UcaG#u}E)0p3cqT|~Pdbb;DTqRkpLKe#<)7hNma>?n{6d?tcYj4#^ z6UTLNT?f-Nn?+u{MOKuwd;NwZ?zY|#&$Kpp_r05(FTdo@+t>K&{$tj0j^n#{ZG&JF zpc4;m2)=pnjIy$s&L+%fF+!H?j!kM(e6LNGCcJvKLRXp~mAJma`PGE=a?al9`v@vL zuVyiyvs!KN{F>uydt6@3*~B^8sDT`<m>VVX5H zisgFA=_fU=YjO8ho8fNFGTzW1&$y*s;$n$aJ1E0uwVojj4W;1l?h*6FnzmPCwrqNi zBF+Qibd9WPq$p|oJ(5j8CQ6<>euP#Q6m5R@U;Px*f#o_tYQ@F*4A)aAB0NjeYxg-k z^lA5D6D2t2kU{T|O;B@sazz@Z%&&Z2oG#GD4i8^GXF6Xo-ZMGam$dvAmzO0$n90;{bF^u2F}=j^3|NL0P_Vqb;?ZYIdPBJJ_C8@eV>Pds&eq(# zy^mp~Oy`$KL-XX}Go~kN@}%UgxAz$AwwO#qo<5y&>&6(<3m7;pPR>p-4Fkv6VRv*u znx?FS38Ov9X4R)!-dPPy1TQ+9h}(!k^5V!`dZw~5vz)A>`5 z`|n|z7Nw}Dq^7I{!MeaOQw(im7*JOso?Rms5x|YV+dRl9N}L?DXEIsz8aFQdAh8Pp8-6 zYI8-Jlf)s0aH*6{-|MlaB2)@#)D%Ft3AWGq8pG0LMT{(KJjXyP zNf4U6e7T|5Q`EJ@(k3lek!C4U8rv9Njb$5zalXx@Xo8IZ8B6%(L1-WtrqIVOFoc_om8+$6vb|jv*#zA zoSgD@36oDgrDJP;YPwwaJ0u++<+bpYLscu@x^bP~{kOl5{Omr1zo^NIgj@SJ*z5Kh zill0+^G#WAO)aZ8{TOv!Z7t3X#=Iz-Ij7!2V_wg&ugOtVHFZ@t{S@0nnXGG0U%X(@ zZzIZrufF&a%Wkl`LMi&g0a+5G4UK6S9338^WfRzLA|f^GIN@(Ty-$>6q9)+&Q4F7<9w0f`7VRufH2%J zxwvF6AVKK<(N`TEf>*gKRA+a9-XUq{q7WtsDb|INQ)Hji=K zHb(~^GM~+fvVv&svYM~?=)3Ro*MIvnrpq<^dt(;!2~xn#U9e z(&F9s-sjbmhg4-w+m_h6>3~=VOFYjZFDfb=9Lq%MHuL3zR>#6|ZK9wgOTlqGo;`cP zc(h9#H)yqY-hBtH6iFP>?f7(kpS|5Nd*faDgCTeCzQyfZH*qZ!-}A5x6G=_D3D~UG zTumm-=5wwtFPTm!+mLRf2FNDG-KaxSHH%rrw!E#OPzeE4^=lIxS{pd7%j3t7S*_RH zxOwBvqS0*a+xY$Vf}pjgtU;OPn`MUA@uq6qP+nD(fK~>sV+GiOt`zESu0(wasEANldTTYce}Yf|8;sJ`5x3stLwlTwL(8KmSXlvbb^M7DopM z9PI63I}TygltU&_K(JYnWkqu>NE1xMpr~OThHw1Fb(N!~Bns9{t}aR9kgBe>K4XpV z+WgjU{1C0`=3!sgn1+SehV!ek!rlh5%d&i)oQt7wOkTK@tcL!b{v$_eEfqS(rWwL zCqR?!d4B#Sr<3R0yZ@YZP$ErD5UZ2qh;c0ZLos zd5#nsrD{e)P0KTw&L_lqincWC^_=le2Pq29F0Po(OXiD|-bm5gNlB9pownfiU5^@z zhmX$4tBf+YiGqsdI-{&Kahmh|}o(&>t!~ z{Wi9@%gc*7CueKg9nG+BAu5k&Pjj9>zaptvhhq5flvKrfHQ>ImuE$~Xx?22nQcd*S}9zVJwjTKR}||wlcB|Ja>obY{}POJ)+wg5d|xDhGWtU!Z76I^c>F{B5I3Z zld)bG%qJOjVE~$}5RArqv^s(?o)bkGw!K3oHke*R+F8vO?Co0Iy4fR+VLB1K|K4x& zlOO#KySoFj>Xg~+6e(IPmy*+q1ws{cJCfsT&5`ZoBxSQyMA3%23^0t6I1K2vJ>oEC zwTduI#ddRd@&)4 zC97aXStYDy8GE}U-g)aS4BcGui@YLB5)O}t%$8GHZHt}V9ZpXtJbZLUmb!fL`4g@k zzsFm*--o*S9H{_V!{bjs;qm=@%^@W%@cb^G>yxG#MV_J!O<6S5y|&@txovW3P$>(i z)uQb<#ASx41l^uboGdWv1kdou@)#u(%6!Sup@nTgk{3i_jpHZ93d>LwNlY3BC=rw{fArH9~4zX+bq)ps%F}<3=`9`pn{#@4xN_Iv**vqit<-> zuc`^J84$7sAqyVD`qY#8nC zu(yAJ-|8R=O%h}{u8E+;@g$@19+$HzS{vj=K&O)sWmkOq)nD@U(@)9klGUQ*r$6~4 zKK|&pv3&z!XE<%m<@Ag!uZe<+x|VeM9^X9v60=qE+1G!`baq9{9nfkwR{rDTBVN3C zN|q&z55~NG=Pv5Tjaz@Lv}zfg8FMZ)Zpr7Ik!-g;1h5=W*WjCr^gQ`*` zDMw|J$(fAt%;TOXU#uN0!A2kuKrqhc!8!Y^wZ89r-{*~kHJXxh|K1x6TWx&XK~Xem zRtq;QS96}fddbU|FW7DZ(llcoY*_?b^0LIT9nvhPKOE9%wQ;=$m4GBkFbq>lnd)Gh zvZ~Mw9Z?}seF$l&($rciB~8Sx>+hwBe zg*q&!k{{+u-ZKi4B&BK^p5I`1?||`S&R_o3UojXC81#A)%ZebYQF1{T5~nG{ogw>s zJ0wZWd_H9|8568GY&UC?G(iZ3Fo^3yM5RKYXgZGHWM^j&QB_3YmMkraqlEEzBq?S| zj%L~n20Qq!gQY7twn5W(aV#A}6KJBs_dN_Xx*v^?FTG z8~oIIis(2Fx~`*X8m{XS$I^73BnfGnVwyI+Zl6Jah~s)#mQAbE#k6h7@KywdWuWOg znx?-lV5(Bei)_u1reLQr3$F%jJUEWJIvt@X^OVVz_%C8);OO z1w`qXm!oevKaZJAW47B6(KJ2d?vRcX*{mUKHdZyrVmS@6JfW;&%A%y*Y~%ZaFiO}vX_Ay%DpBFPg2UY=RZ`OM z3{(Yn_Zkca9SX7GeDsJY60BDSql=Q$)0pobtq4*4=k?Z7efqy;+eK8keJhv=FqKKK*W&OG(m-m#?m9+a~Yc+2OF?Ww{E-D#68Uj@xiCO`WXBsD#dF9C3NMB@HFY+G@tA zRSJcL+o-sIcgV~0DXVEfvpb+F6ZX22X!Lx%WHJvpdpSo{9ik{Bh(g*ug*$glmgAU3 zP$5WYdM%zmpJFu{Y{MmS8lu=GX&7?(a>18hy+rd1PTuJ8{K=SLUGntt6_uiKa(jS+ z&3Lrp{BlN=rPyAM@3=(k6-gY^>33PJ=S;6&u)o`6yGa;Nrl@90vbA~ea6*k!rQRAj`&_zI@JR9k2^r&G4k4972d<4qUCFiDaG+o@>!UD8a$ za0@)oMN=Xk{QioINzO9c(&=<)T0_X-@@mY>S94ZD&a)S16jgKlvG(&5}De@7B|34MoTh*B7sz^VM&DM;3%+MTt;!T6U|}_veVBpb{mk zXoaR|_=bZj6at~pXmp^?Z)%thme9x*oumqJwi`;dBCR$QrJ&ch@qL>pNyv+eAdInH z9m|rE>#Bk>S11&)wSpqg@tO{XCYS^{rUssCkY}Ko1w}3>l9EDKiR~e!?hp!}tv(>O zc37nvNiI{(1tpqR%U<%5I7v`Ys0!(uL=?nv0+kGN({&Z9Qu-qE48t(d4HH$97*%Xmg4%Jl!GZ6qAV#3DOXo@U3#F(f~*du)pQl1>WE56e_mP0eYu9T zQ01&npJ5o9M8hg7c@8Bym1-kYn=~yzRq-u@GT4wAf_V~R23wRUASEZHLeEu{N@i#z z2pT&F7=t!WmeLz9X;30uoxgbeCHr^Zzz8#TO@o~xXOJcAR0XXvr>Uy+ZIfo4VqJ|< zmkWyZ4DHsC(QM5(iz%(0UH0C&&oqtd9F2;&C`r-;qxNB>0vRY>$~`_wGlDQ6jw30{ z&vS&LkY+h)p0f?5U((QZ$~xPEszenP!DfY}>o}%`<+#|6gQ}}Iu1|$ZQ7JfXLn;h( z`Cb~9%)inM15}MKe*Zwq)r$f{m)Km#k@Ehs%0UkR4PTDb9r&ebh;tf6f|3Hc6K^Ee*7KN$(Ssa zLBI$5`*eCu&aYk(2O;Yqz;G?j&R@{5O$?#&?9pS^(2U0Hec}a^cDMiH&8!%_x>*$u1&+WXnGF4w$H)tfa9Zm-nw(Z-P?!k^cyrh z9bL`P)ErY6n5KbYT0D647{A@+$%|L~&8NTSyQj~1_VN{@@tA|XU7C)~pa1-y@&5fg z+&tPtAd{(OCWc0(Xq2dw=pb~~Vay~5xLU2*1|h!VP?ZJWeEWbR&p6oG!So$$!(wM| zkG;Kpe)hAUVb~U)s$p+4Ch?jz8BN2ZTy9B=khbR#A&B#Wu4|J-8A52Bym`XeXpCwa zWT{MZ)GC?QZI}jmmCMB8nqwYDC5ByLI-nZ@UALezS*;>0!(wM=z%~fTlY}gapoqDB z^N{6y%49TQxn7YK1v!$UVd@&1qR?zKa6OMGj!Cn$4rP-@d|fwaHCr{^sH7+|DPIy$ zltnFNtX^k2TnF1+OX98*GxM5KRF(yeW`m213r^2oa`Wa*4BY@BtMRhdIbQoQbWM|a z8`s^1`ueXWSBgM=ZQ`n4`wdQxPcTfK$z;ThnK8DI2h9F_DGYs#@}YLC{k5?->1{(Bp&*&<*Y1PEYvI3zDsE-p5# z)-h4M#jr|(EW~m;Y}S&Z6$OyQI$>0hq!n3FVS66oxti^Vx)8 zn-GUOqEc|3oV$0A(G-&?s<^xiL6I~rRZ&T@1lv`}vxMz3gIwSk8hd*~k|am31jCk# zZ`te*8g!Zt^HEF^Wn7#`oSkn7V~_DHqO2T>!ezZlNYa@8z~}06j;4B)RgPsjgi*qL z8KKZ%a=Any;P#y^-~Rq3FP0(V73l^)2Br!qgG+Hi`s~LG% z5rr}5S2Kbw#G%6BaRurjrIrx5q z*>uio6{8ys(zswgTcf)kMOjg#IZ;#)Y+_oD!Juj5Sq+{(J7=>^dHVQ*Mx!Z>;hN2K zx@EJjxV#9cN(bL|&>aoi)>*6;WGUFfq1WyaCMA)mn9UNt{puyFO^l{nWLqe+0^hMv z(0J#=J?_8PVKyG|>iHDRisPG2(j?=HFJ6*lC4*s?hSy;-4xlXRFwYc0$!0NQZ!jcD zQjTu!AoPUMcwT?TW6}irI}P4?r$eLRk|hSC@s`>03fHk{HXM3=i_6O^lC(n892S$1 zc0=LEA0P1X_XoJ1;OlR$n9oaE4TJIM8D|$yux*#o#gc==6QU%+_A)wc!Q^yK6l&yo z$~HE6{;Xsbq^P>ZW*s5ajE{bJ%=yJ*{H8{?XHpab%ambrvq`{oykuuzXZKK}5*bkv z(&~DQ#&e=ryxA^qeU!fW`cS(=dLiCiaLhs}14tL7jws>*__q$m@P zj%^yAiLP2TlqMt3p(xeYM8ha4FjU!Wi_-#CcPRB1L6G9w5Um5syrdF2rXhn*E5l)f z%fi@arVd$^E(MyDh$HvS)oLZ>GKxH~tBOJxgmS_xz;SHZ^eRj8EJalnDYr3<*8=l2 zl^_#cH!uuC2Ck+FRVkq;nkM(uB$a@i>pZivDCKm!&XbaRubeWcHIzqA$RW=%k~k)c zV~KSaFdt8GRGm1@z%Z$Vj*5w@nJ7AF4He6T`PnJIKYz-LYRe{E6QmK_Bw(4xY()V& zC{(zXhn@($w8ERLFoT#_QJ9SuoGn+J#tB7OkX%iW1yi>$ZI2=?iNb_J zGpIg%AN$Y$IY;lk!+ZTbKK|oR*lBb*{pK;_FkrKZSS>fqmrE9#HH*cP^?c2Gy<)Lk zuvx9yY&L8*8{#O$&@?Cu)~mJ5iisrlwWz?f?0=G%Q(D&EZZb60&W~0 zGrCw{87`yggwH?|;lc`|(F8 z>N%}m!sF+UP!z#?Z@C8>x zhNkMWqE>YfDy7g^2N8eq%m14&Nx8VXWVo|Kuh+xYHQs*XHb43P`!s9~$52p2Cet?+ zjUdd3l9E>!W4?R(f^Qx?=5PP**L?cf7yRzQLxM0Q4`aIRCZ6Z8zcXYw=;B%?m8j5! z#^3zvQ~ve8{kN0?g6)R)PHtl?Lke5xSKoZWZf}SYJf8K|m3o@xww`^@Ka+N~yw z#gyY4M@+9SINTrLI~Kn0A{0SVUH{dje&Um@8S=zxt3+o9}ciA8{4vL>})*(trznw%V@Tm zavKv0nx=yg*tYbln5H2=;8lgHz_8zCcX!Bkvu3$mNIY*TeI>T-&}_9)G?mqQL!Ot! zNy>aSXT6aOdPOKSd=KCE>Oi~%UDt@Bi0yX6jiV#peeWI8EaU9_9E47VLw-lHN!Gab!sxn=t{eECPqW#Sg-neami{PFUsEEN>&$qn zGQ%LO4k{>3EUSTK`;5jLz-BUCFqsA9X-TK2((c$)1vpmDpeK0u{%sUduvjb* zO3waaoAoNd(i_B)!h;7R6xAlpQpyqxQztLis3KuIU(<91@4tIMQLIR^jAu_rD2mBy zu|%ODj3-RzTP`OXlGws)?9%NW$??4cZ`{4h>G>t50eKej;`xF&l7_w@iZE@HS1*aPG*z5Z= zJ&$crQ06L*YttKOnC_Ns5Rk++7Z+o8cN-YG3>{l-rlgs|W)1z`K91XByM@hiOQ$2( zt*BfwiWcI!ZPHYO+$C7A_%Hs=`@D5m zrRl4D_PZHhe-)8s3Y+DatQ>LkjV@sjeWy#muVQF1^XUS|anUqEyVXP!CW;#2H*>f&= zgof8esZ^q<s<%EJ`RuMM24IyCm174^wCg%WzG%(PR@OR7#3gM&y}=RtcgsWB1U+cXBMFQBMLA zC=IGoqa;JuRN}ZqR|SeLSgZ;(t3zowSjSMtAq_{Ou+t(#sWfyYCCUo2#tCN(S*v~G zLQZVbI3R6v|% z*shCZ7;;}Lat8e#mZ`H|uhI2da<0I7y}@rZKtNF!eAj;EvZ_#2jS6`dDl7QauYXN{ zFvM^AY=VF!O@Ip1Fc7K&LZQfWdhIqRCnr39@`TNHOI69tIls{$$x~EaL8ua(Q&t6W zEIpx3uT8^s`S63cSj-lbMaI#|4vnVI%a^B2CNs*iV!I3|vW(%NgKnyHx-EA1_HbOA zkG{9ZWIDq0y7-RG&wly|$458#kH7p&R2AO7{~^mo$a1>o#j`UmE=E|c!EAAfY3scG z-YysCFX=Ro`0)>aOs_p;vtF_e=Ac(xPR_9m!PToLEXEh)d4}C`s8oxWPhax0pZu7A z_`BcIYV4uz^xD4|PbREaYp%v4&Mz)FJ3Hs%a>Uu?l;< z9=+h<;}<-6cFJtF1S(W2x-E|n-o4N9;XWUK_&zrdb}=-WUR@zIjS|bIa(Ol7;iG4q zUyb_gVbFAZF0Lk=kEb+;L*~Jn z`?qc}R1MPe39B;W>+w0gR)?-;Q{*9S$E3HrM_#E|g`ijR~z=_Vnrr{j1krASc}jqSQ%wTRJm4a=4kfI+{9CItPqPoBm^ zQG)Hb>>nS|9&{Z0X3uu(|zkC5GL zx#*VC6kTg06-8G1^{_)8Vuh4Z8McMzdd%i?x!@Mk+@&fCv+0zos%SPFb)HA{dU7D@ zMcVg08CIyPXo`I9rlGOFw?nVjXEGYI4FZb1kdqiiV3-#D{s2|g*lf14Aj@*5lL_1H zR*v0^0@rit_Ijv_AWbv!Jm>!Xx9Jatpr~lNMU-S*T}=q1NV4J;nctx(3c8`bew}qg zq8E*t&ZVg;RV4!+rJp0O@xIFI42Xum`o=N8cmmj!yym8{*DJKK}kv&<^)?CN}E>8U^<)e{Mi`W)p-7NMw;oodH;YLCwnB> z7Q317?k69jbdJ!i7Vcoc?;p+i=JV%l*9DD66J6Cv!W>OA5K2nRcL=u;%k`4kbit#C zBU-H?tyY^TJm=>>KLJv{`F6>_``;e1jT}%bEEn#*-=fvk$P))jhbT!YvL?@-#4HyX zcqYg1zE2sKh_cCgRkEDV38F2IQ_yK!G(17egM0T5*chh9G%y|EM zyBr>MFpyi*_z8>Nfd!;n3%4K-ttfm2Do<)aBlA5-ae+?*`t{o48wx9W?|*9b9{_l zs03Nb!qF%U66YP<94$p&kK6J9!I-- z((6FQu-|1dpAp9q-A-E`j%^3qb>%*pr7}OPZmw6dYx+8vTA&aoDZlyrGmza_~}pom@LcC6hRz>ESD=5>lKT|oHR)Yf{@jEjqNy8q9jgYk|dWjSG5FG z%DkfKyR_Rj^TmRly&jFO#d5u18-yGlo-phWDDns)GIT@G?leJBxN&?N*YnvwsxS;4 zN|ViE#l`6hzWV$Nma8?lZk?d%f`)Ga1$hzE?RR8OnNT>|zsJ2hAK*7MI{rSU-lohH zo;`cQXJ3BJWU*my=YWqt`~egd%f*^Uk1xp8ib`M7^jr9jOOTAY^Ts{Yz1^K(6hKi) zgk4pqGNNcyib|!apvj+=svvX?MKw?~6HSv9c++<|-rwc>@4e0O{vLyFmwWf_vRJJ_ z(@6^0#u<58VdxqHL95y3^Dn>P_MJQQheLkw<4-s~IilV0P|}iKZlKNsEXR^hzJk02 z!*GZfF@>V@;Mr4pJNvAnfN(y=3KR4&B>*1ICfvPq7b^v&N^wO_Au6&Q2ogk*lO-vx zW0Ge%ckbTi@zZB0nxJE=c&L8uC-3UQjq?>f+J zG#;~AZ%C6A!!&6%n)LxRm%%)>luD~*PS>(2>8tpssRotIC=o))DS@isdmdSq^7U6= z)9rTH*%`{h5J@o-*E-Pa>y`g>-Rls#KSbAxdLc##P*o5rtxgw3G3v+2LS{U^lJ`%m zMV=ROaaL5aG(}Nlkyjz)LS5&CXqqbXGx8i&z~1f-j%~AAEZA;0P{~E8D#0)fdfhI% zrm@`yWO+fJXDk*Amdh1sUQiYiHQej>aU7QqKl(m{ogF}+s4^|v^_!@w#&|N3CUpdw zZc>#Mny$;D(6%Yd63e!Tq6piTp;AelU>Gt1)N|ch%5*K)(kOCCwlYnVW}``2R`nRR zAc`Vdtrn`PVi-DEo{=O8agyMAz6>EM3QSAl=fW_eqO3PY6la#g*c8wUdYff z2?lTp!wA=Lu}llYw9r+F6E;l)1(}zU7A0@J_aVAzaV-e0RFz--<{$a}qi?vlSW^}* z(YB)7HCZf|Y}O(DUW36N_-&QdvShmn$Py^4oPtQo4sw}&k(U`+l2a5VmTe#^L6w)> zx_N_7KmC>{Z1e2-h%8f?&kBMl;^N|r-~Hw#tBrC$^oBcNY=l}8@8cu|z3c78VUU$ep{OSR^k+ZYwfLPM>D<)SL+`iLe zy-r!KGNL#K3~XEB_U#kiy89;2o;>5zzyAlIU=uD8T1psi=%BAm!l1=HA;4dR+qn1nY{;x?&r}Jb!-1tLJMr zONSteScL&$qBEYxw0jMLZN_|(5XTX^t8leR*}ZX-R5jRS7N!lllH%GOR?Cp>Voe@y z*&WK{@>RIPumyK+9dWR;k8d^Dt~Y3wU=s#ho~3x&8%z=n?XW>^XjF+qoL1;+h$Rx@ zWXVpy2YEujZ%V@<-~QbN-Tfi$9go#^iQ7^+xZyyh zV{(g~-d%3pzRhwK@#4i9m^q&QH%7 z4tAL@xAgWx-hQ{iYIDimxAt&tjp-x=6+Zjz1wzqqT$kx+j;4h)n*~X+K{qvCK3mZA znyi-+0e*h5VE<^qd>#=;5vm$89C%DeOTPK~luCz^f-r`cFXm{5&3o^C$g`&-!f?f~ zeS=$v@4n700O=w7yI=m2@#!nj1bLJ|Js}Um02P60SX8>kHVB|7sj8eXSQBO`DbVc? zNb?*8D6*7Jx5wpd0ZEE&WE5qNX$m$=!ERqeH!9*dV7m>_bsfvrNb{7c1Wl+US&pg- zOs~l#6r{pIZS>^dP!Iebfy*%d%cKnzBsNA05Y)az5Y@FrT0%-((*i@K)oZhwPEnJLG>!0DK8C836fs%2#X{RZD9fppDXBdby=617(Av6p$imbrapzFB&X1nI!XCY4v zi?25u##Homn^qyG4q>n+nJ>vM=LF9$*#7<-qJR91mK3|&PN3e@kBPz0(f$*F0c^ZD0bvVU;Mcse7` zGHgR<(CJVXIolxM*6o{Y*DF4J?>%nayhWDhj7B4zdismv0|EC5a2tASGM{_->Q_&JJNz((mlz`;aCYqe;oZ;Z62>w@_~!?*2k*{AE|V zswFI zZ8mAS20Pszx~1~y`3szeOG^jSR1ivu&=g6KP%BJJ!L${kIFdnhib|Z6#GyhIR{ZGW zkNNc1|3J6fWp8(n#eB|oEqVWYhezBzKH=oXi5$}=In&9E(P+fOhu<gH?(I?uWcVGjdvNW^xDI!`4y60TjDWuNHR_nB_1laEb zt#-yJLtnNLRS!Nsy;9*y#tTwW3!NIwMt9|+%hqOBgZMl~!}n}p)`LSgq5p`(!1ar? zU^O0ta(s=#&UyF$k?i0_BSGSXURCl0p@0-5ceeD#1(ywc32Qs^`wI1)KVuQc1$q68 zar^-?=NgtZC1gf2P=b0uqQw6h>yn2%b_#A?wkPi&$uWRw>jMKFhlRqvah?ZA=u}1dJ&V%BmlZTNa2fwj; zuNA{!8>GF}-79aHHAW@>Q2*IK_=lfMNEzFdn|76{ZY=53%^HYGk?=NNgXDx@ehk`Z zy6PYJ>w=VgAc=Pd9C?PxC)oI7<0szV=OEA3HnB`8;@0pY zd8eLzo4BoefN-huegcVK(GSakN5I!zDn&>?c6Zz2_i8{=UJR}_=*eTubIqPOUczlf zS_P6VVwCWm8R~F(X(yRHu-xJreM4=@8_%i#zHq6?`I5rIEPlZz>94`!JB*ZMo#DAf z#7gDn#{sHv8T)Av6|-p_^FTcWITlMJ?|gsiQ(n9A&q(D_qPa#eSunA+IiFu0#0Y(1VLdZxMSjq;gMy|yYW=89 z!xsXk=sCK(wJsp(CYpms)w@EJKZ-d6MQb&->gvvS9LVe#@xJCUCTAwgY>3R`1sBvs ziu25gvyxhCP|hE6X2)ndY9S62SF5d)pQ^Noc(lVnawW`0T=)HG%t^yu!B8>7ZI<14 z8I=GXvF}QZA78URge7Ig7N8r;b=MEts;~6bW_UFYW;kM~$cquvyDdRZS2|@lj4o%C zL^luW-y`OJ9A@S_;vF0$UkxbkkIjH|{sY`D*Io}UBRgK-pi2v#V-Jf#!-D$R)$e+^ zSG(@8JQYP@V$SOBo)i>*w}KNCBF4BCOjkjg^`U!h$pi(?;@OtgaR51f8?2zQZ7vmL z)}{{sX4$43G=wInvME6CoL+BW2PGjXgyka0L30j~;`D&Qo<$YRk_yh|l!@h?B9WbF zi3YDyE<;P4qW*19ZO8Xvp-QP;*HjBPMT66zh?b7nAywTrVV{+{pK7FV<8Rq;#{4Aa ze@l&1hr7RT8bl^s?UuymF_jU$Sw#gSz8?CMZE*l%_A1%ppra7B9Z3RY6{NG-&6xEC4Y!?6^ z^KYBu)o^?uf|hO1T#9{K&D8*_$E}Cp!dj~8ZC=8{QW^Dv-NM>hK8q`8aCgPmaRW|| zMpr2v%(yV^aL?nHD)4vOfgh*^dDM#$ORK&~FnH8*6*?i((3o-}uLG6mzbEjUr%@`j zx{G$~9B3fhy`s~>yXrj)>=WynnA<@bJqa6)<_5y)G~-6?ra}}~>r(*qQxcb13`a$i z5ZD}oC`M#l7x!y*Rc6o=HrDEC^ZdPp48r{uc@Pq@JijQQ_EK z79by~t|imj53XLvu2&x64igqa=>Q|bvN7%Q{p-f-$4}g?D@3oC6R$|EWs_?w8&@bs z9LEn&7bu@igbkc|yS9g;KVeMm`8oy$`5alFy;t6{4J`p?v+|`p1O$;*5@HhF>b(C> zh?*S8H~2x8(R5dH@bY2x=|T$8UH%{bfV1PW`u_C6wb7)nW?qK%lVV()07!^7(o8`@ zOoiEQ2~piA3$XaM8{^tR?~vQO0#W=ERi)|vn8Z&|_yb$V5K8~Ect$Nw-NAg`;|+D8 z3`X--c>QXHfMDxze-d|{cynFpLOvu9>>axcD@I00awr~4HS+Jya9k~%Cr>Ek3>K>% zFf0f8UZ*j{Q`9cXK8(vy`b$+RrCCzs!Ns!NRRd;0_KZ7{ z*%M<)_;5^01O7wYAIGrrvM|-9WGRt<8sCM=3&z=1Z0Ox}WNBJdwT`lBu&aLrULZkJ zTwSg#4a|pPrNeff)N;Fj%51$FSq;6uJ(y!0LF;uZm>S`jg5YbY0GkanKtLZ55Vz+; z+$ycHJDsHBi4UN<`7v4&08X#Y(8phOl4|C~#VmylHT!RrFySpJnC^Vp);APnv}qm25r63P&wjxMf@LS&QG} zdG4`nsZi&cJj9W;5I$iEQ`hhuU>TKG*&eVU4(q$0%Ycv#R=VyoeuOkPvJ+@AkB*V1wxnEv910jwA+cH1=`gZ!ci;^%+@N#U}tgO^}D*I;! z_2krBPef-fNTjBm$-=3XE-H}gFQQ=Y(bHeLn=f9v&(?j! zS*LH0CF%JTw&-q##icWfqtdo{Y$_QkrJ>vIcM}ulSf5#-pFNJ6 zPq;N4v8DIQuIKpI3=GfSGjQx9_3c|!I!*t{F46(=rZ(6dVBJR9T zA6r2_zDSMOc(EQegXJ^H)SR-L5m)t}>Kcqe6jNybKB_U>OTa9*OD9Zoi6MW~#jQkH zBe#M)-tX2&3~O8QFoD(f?+ohNKaSE(yChDdjM>raQExrnWR8`IYh!5y4lNwkPwU3a zz}=}nvML{a@JUaqLeq8ll?D6*TtX)a!HN9$*7Pm^-x#kIG zo{-H8S@}aXvMh6Fr`|a*hXk#-0v-(*^}$EP3NpCt+4f(wmji9Fo3c1s;?iRzxkK5} ztEw$!{gko77V{MBRs*izgg^TJw!{xnX3?@`Rt;f%r|6UHk@_&oX@5sd z)0p1-@%j)r+U*p7*7-_~<>}*hd9X+OLAz0@(k6;_Ykc_4`}b<6p!R;|?CFy`rt)2r z?SrIG)5^v4Jr^#WHLHB(i8nld{zm-JZb-8)nJ%3trYJ4O^<*V8VTz)bCopd#Ecb6(QTSv6t6yLJb zOkD5{*-cPhyca_sYKV$I+O(Oe)Zy6<6M- zgThRGDa3i4mw3h)qwpqfGCGg==$zg{OAkq>KbARw$Ta5s6qriO;CYNg(FmhFQ;p9; z_P&%XMJ803_+xdzy(}?&{bT;jijed&|5{qzjpX35}M@ zNm(wYrD;orvZ1kbNJb!RWE7NHTDaYhaGfhTTrj*|Pk0eJrd3lXPkUW%zoUFTH+u;W zeE96*o5N~i-@AwmMi06X(W_zvQ${&ylNqe$L(u6x@N zH$KCjFYCVTeiuP{GBN_w>r?rIe$U6Gu!fJLXi;?tR6y_=G}i37$7UqrKjK0@ec~=C z^w+8-`{L;VU7@`HVg;W^EuY22rDOZ@2C-wB(=Dr8jPhsbr>xB7-R(bb4E1_F&=DAZ zH3A13GdJEHJ;#pTGtp-{aP6&f%x+H0X>B4{<7Zjeltmn zSe2{O@X{#YskmLJ%aV{zc50tMo$mfHBUN@uynG(CK#4a&!VcH*FyLSplsUn@O{)sam*#E;t4#X0w}7Aj~!)xBPw+d`0*C1FdE$bC$pNM}nw zk4`{RGz+jUli}a24OYVSR$1RMd`0P(+gI6i~Nr8VlxfhHRKauvB$r%Q@Xs zS_Zw6P1EV;-@ni7^cj135xqJ{>%WG#$_{NNfLN^oq|)6Ts*t@~sq5{(nEL4X|GjyJ z9j(6_SbRE&;L7)k(I$@AkR){gGj}v|c1L`Tk`^YWk^;%~>F8-3L&j&}kz^%#+$R$J z)Od|j8)H%B!#5&umJ(-d#$*%HvBSNV=~G*@>ZgX-V*6Q4N6oMV6HQhx+QGfWav zWiRx!t`u04r3#%5I^k?PC^d(QcL5M22P(H%JmTXs?uA8~D17O8v#30Axo9qS)Lv97 zcyNkxf`wowrSi6521g%&g9~h4%#r_QLL#Z6kYcg)R&vIbQvrX;L%UiFQLN@fr}?)f zH_K=b2gWo{E=#n1p8^9ImVwu5!Hf56&PJ+yPMk@KI1Et?{oDF#2MU1{7{>_rNgh-rW(<>_$&Av4v8hk(WlI`xXUk})8pQ56pQwek;9c+kGdi^vvyhY&@Gqz1C zE!3G-k|rT1XxC)B-dG12H9XbGak3^cIaWg25hvNZw!2Z`ZveWUr`O#I(OGB5=*>gOg?ry~lc(3S z&{p8HR&@)Bt+{*u)P;eeXyCx5(BAP*&}v+;rRH`hHJF^}DwBn6GL$wN{ZM?Pja53I zFvZrXZU!MSuZ_3UK1oA}d2MgKW^~K(#@Rk;YA&se!`c(0Km!L+q=!SCghaTPY744Z z$UC5I@MpQxc3l{6;;>d5jjc+CKxe$SEnaq$VE)~{=aRy%)^cZ?1Oc1!F2!hUUIk*M zOnjQ~o9_pS=1ALg(s-sJ^2g$d(sbEYm-m(AJTy@4Te?{da7uBSwzjIN&YK^8|Ii?R zGrKy?1@UkYOC(Z*GIi%mdX+;OCXR_Y@PCsfMKU0Sve_0R9R zItzZ&!6}^lTTD8ttWVrf+hb7f{t|?m)=zu4G(;?g)5f_dFtgy-y3R?^SJEc0hjed+Ut(M97};0bebEz&Q9n>%I)$&o9xhZzYmt^Kox1bmR;eN6K)G ziKHY{>&P=$V&P-W2;{Lm6Sb{xdS)&Rz=d+kY|#aIvV6_bp(Y=QM=T5qj?a$Bux;#& zOk_#R|HyulO5anrh@E!h1BaRTZ1-4D`Jr(e8<5hD^fj`mr>j`enWQOe+mEbxYPWbU zsuStJX_8x=r57E7S+u^uikjo1p*pbyO%6jUVT)vZ7&8SdXov0At%2@y*Swj?$Eq3@ z+?k)y^ydeXg)DRuXr~}7#TVS#V*?-A8L!9;=AHeqdwIY~*LUXPOo?#C6bn7aNslBd zlEd#+wk35r5%?IT`8q`1<7`>aZ-G@`i?+#!KM)}?68hdOgFoPyU4e=zFgbSq5MmjR&`&!0m}Xbqd?C7TiF<;0%m*{u0235@meaOrRzyKd4B z+!PEXmd@(3*%I8vns#Uky34OV@hnOn!#AAr3AC#;XItY;4wgk%Y2xt#2O`<%<-+2D z>7&rhMF?}{hpbqfLTV*74-Zdgg!d3MfIU}Z|3jQ`b|A($?R>kbSn>$oeNL3Y(c3_4 z@%^%Yrkc^_n`N5hFnrPU_eMACChf+~L%pSKG2+ZrRO1p|Ecfm0Kal_JyZ8CHDtWSH zF$e$P4GK==KUkui?ZXwVBA^Q_noJH>|J}gbP&}v3$jF~%)yCd_pLKIXbe}t~c{^x4 zc`G2euyI;Rqx&sbZ%E}fj8cl*c1V?A6^zTjV) z2bX@!C1^Y~^%aG-ORGU>`)3gNw$i}u+b%BsC*4#iMbUFyR2tUe#ZGQPVn4QRVn)zR zA!bR0ZmjXliYj4>?ciFwAK5cjobQJ72^WPV(Z~lIOG?vNC0Lpu{7#(iVlXS&ToY}+ z8QP+`qxB3yWn;KYG(~x>NJhU;+>QgMb8Flr#^vwr@e@Z*l6bN2#6{i0j$M!@^79Vt zu2@CxN~bpR<&=1b53>lDWqlW*FyXfp%Uu&IZFd(U@i#Wzb8`{zCltNCeMT(nfh}<6 zQTeB;YW8%<00A^?7BSAAix>#yDVGgH(JD=r>Yvl88+MU8V!LOT-ZxE}OSs^WXw;W9 z=L#=0h8G>Q`#eYO*o*NlaIa7{( zfQXfJL2O`~whLdCOeip!JZ%6TSQa_}u?|=dIpe#lcJW8IM`G)yv>2!bZwbZD_t|br zX79N=c}3s|rD_4J`v(|DOvF|)&uGL<^3f4z*Ta}&x`NgJSWxo80#T)hMLgrT9HvWr z8jED8ti3ryBn>uX4A(xf&FpbzZU9o5O=Y$Mb_FV4aagmH0TOs73&|U6Po#s+X^O>O z*)rKy1<)u}4vP4u6+9H*Hr5NW)Ek>IA&d)Ma>Y{-J0b2RF-gO{r(^!Wa0ezp$HG;< zaB!pSE|rLO39_(a_%ib`lACB0^R=JSKOB2aaMygImy7wbtmg>hOZ`+~x9JCbh9y|@ z!4@)Gxl^z3+CQ^^r>(9XegJJ>%|0$hf@*ScUCyau&ZEL^Q((8u75*sFS`}Hg7g1*! zIKLPEYKJ{BQ96e;F=55h8>A$vb9oI$C3gEOy0=$-VSqk?d;LfOn575mbf31XyNb5f zWajAGeCgL711KRO2^nr}LOr@B+C)`vd>`q-cq&#%VCskR*Lz_()3ETM3ZT+L6g?c) z@yrH>b7oW?obiVUuc0seF50&kd3pItJ;PA}KaCqrawPJ*-3b$@ALbhNsm~*9j*;H` zt)-RL2x*QZzP@A3e6#byX>*qlYMJMTZD2iX@l6NaPebi@l?pVX=$*d7-o?pVeZAg< zU5}_#ll__{(&+sPi%f5g|1@LaPSb(=-()FiO(vH4eiyQWJvAizKBxG;YbFcQ33spCom9L1 z1Y$m)lmsHa`@z1#etNn6d)zf|qsu82iT1eh^?Sa0sc}6|M{cF{2arhz#l>Pjp;nUZ z5ZZVVNxFN4SZEY}-AP@(L;~+J=^Rwv1O)|(J zIAeoynO?{zzSKH*o>wj@VkMj)aa1o}zcaGvsb8scQ$w9&;iB2!RQV<@!jpoF8;i4p z2(03C){PrI6-9!+a(r>Qh{r_xDC{r#lJt3FwNkXR%k*_3pIij^C zJ{ibuvcHNzo5iey1jbZ;=2Ri6&VykMk=t--iAN^%5a}6LW#uE7do~rTE4nu>V{ab* zeV7 z8~kNwaK@H4bU$yh9C4I`cxDD`fw`Rx+F}{~a>%U4+%-K}@wa64omjV9h+`hh=lyKS z8hQ*c)%(tH9LPHzrqKT`S?pCAQ>0o#gL&?}rLrwz08~Pg9x(GxOy$+lFmw0gf>8Og zMm0+Oy^Rz$xYUe(pxJBFY_P{ zZ{7^Ge*Z#`a!Y#iL13%0QY_J#N%hGD}=e#W00P5wTlKtLWbGO~jaAZ?Tb| zB8+Iib0t%8fgB?d);~5T@Tx1xvFgSbzeqQ6cZ9X>9}eyknrUVZEXQ zjp6mHeM{R?Nio1rHgqV%L|5m#+h2RoeDF#4G%se}Vp@39>G|2~%4?(riMoYY_1wnE zVEp~l%-Th9;I&Nq^EpNQ>B>M2`OClJ&kRg1n+3ITU2oPHH!Cj$5xhPfEtKW z;&h)gxn>3-3JOEJkGB{Fp}LNgLGnV%Fkt9%Um>XNg~Wx8y$4=|t^(@csOkVu$mHLh z)ead%v1njh9#b*Gl$>|sxe%f@0_y$a4_eA4NAx?(Kg&M|8jL?Pg9jNpqF}~fMZ4zt zMb6a?o03b#x8@m%v6T1gVQ_4H}*-$Sm9v}R*DVx&`WHO%Y;aC2*ed=L-MFp$sr*Zh15 zmeI}Ctffq{Q|`{zU$wsnBA_T0(};zt1W~Go7-Lk!j3$}YE$yA#-Rn3_6`Xenc^m^+ zgbvmHT!!5Kw`kubPLO_o(+hs13v>FZTc=z3!2@~QBDPwg%n8yMxv;d@@4`}7_hlZ! z0(~n8B~nWz?9fCRt&1#&Su__NWf17drO=N_7O~*qO~QNhviUhH%7_|tACtd};oN(5 zj;^kX`UFxALB;RVia~?()vC-zY6%9w~EJ zWgE2@Y^4WtZ_?65sq(3a6ZiK))nwaR0o(`4#jWt!Qy>;z&5g&C6&A_ZXhBO&Cllq7 zo{+Tbxv_lQWa1Kf$=M?+#7xx4<=-KpyT;6^8;MKgAC8KA>)_kMs7gv|~7`L2MtC_MXaLcK}cG zH5t40)T!H)MSWvnu(-m^0DToxs0GPVUW;$N&6&sJ7qyqyaH(GY=028D?dtilSeA(< zbD|T=C6yF9lV;!xH+AAsQUsGIBiZjuGzOA;w-_oi2`ufg-SRW?L{*;F> z+7!Vom?lHUWGJ8C2>1GDe-_@V4t$cYl1aTrd84A5XZyy&1h>i!gZn=SZ>^XKwHxCM z_iCWlB}1TJhQsKNQlQswZV?tGnBG$e z>{74g@b=%P%nJ@{C}b6t#7UU^O%s0Ww^s0xVL0cvTr!UN6=qpUx)oEWMSVJ}wiFU6 zlw36YA0@MxL@%K#zmhr0T6W% zWT9gIUW_z^7E=vbjI^?9cqCIUwV)Mj-dvy<{d0%A%$}%q6jZKFs7$#^y&@9yM-*9z zIr;;J|MZ3YsiDE8VYabWlnbF+D5rg?8i8QA;;&%YNnJW?jkrPrIU7cDMlNP5uMXjL zD2a==^Z32bh)XSCwYvEC1iNq>KZsT{6!i_0igcV+UyPz1_r5--Du2jyDDL;;qSt3_ z3A|(5dq1D1y0y{ktGw3$LNVa6ywv57*d$(Rgd!PA+_IogGY;_l&iDbz>}!sbCzEQ> z53f45n)(&W1qbh&wK*IS( z@etU*nBrBL@*RaJHYw?(qLS+~7>fW(mp z3B~89`-$Nz#Q75!mq)#25usmqa@k!k$i*bo2WK}+fU z`D-1EGkGcsHigsUxING@1k@k^f!0(geG=LvyM?NDD3BtfGH+cbS)PkWax2ZyxlogU zWTmy|cXm(ZPJrhdrONokOAGC(6qYH_LZ_v7ZyN3PTfve z8_+UUtplL1(nHu3IBCfQvhVi`*eEjIL(TiB(isv9j~6l#+mguJ@u0j zCeA)W>La@eV8d=;f@<%h6O`tv{_21W;OLV(a|>-UKn@mFC04M)XJcn0j+d@T{WM)7 zR>5kCudXxs4ncp0`W-&em7p^j4Uc~`yS??7u+<#J#py`RQQqA79&Oam&NrIGvcu-C;j)M*VgV~6}`lRcD07I)@9p9 zz<@JscrH!p^XDC{u74q24+oA51suz5qtWkEw@dSo-Fk~kfUpRF#c}a#9*uuJ{H*$( zuESwihBC{kW{nCbSJ$um};n=~u4y@N#R{TNb+uJXk`P0Scj`bIw0+pDm zWJEs|Rl#3mhzUz#8c*^Wcx?z1_EnsY)tpLd=65%h2FbQ2*a&5`CcM~8 z$&#p96^tD6vDs^Mv%eZKG_O8npO|>FS)}LhA*p0ik*DrZ_tlWRikttX^@)xps$pdQ z>nrL$$k4Y9s`V181>ewIT1zz@IaAPQN+Gq-N7~@$f=@+6O}wfHkCy2wXtNq4XIz?L zL~7L#bJFCWVLYq=Qe|<*byOc?|Gyn=w^_ob=sl2-bBoslJdOzfRQDZWu07vUp1&-u zS#pU=G?`9v2V9Jo$hcLok+T#^v-sTk8|3GC*jAI;ci9Le#z#en<4E_x2RY=rH&; ziS8yps7^GCr>Ca=^Wz9XIYio!G^DV*p-!8XreYudIG*`SHhoxx{?zPGLnKCa z1;rWY&`4BkMdTLoyt5M-iorZ7nz4?lY-G!g7GOD%Oo-mx&1Pu2?r$wCDUYHaZNk&M zLXIszbosP|pQed#uL1bPEl?|42Ghd6nZR=h`Zb5FWFswfWPxp-v#Y^;W7eqU44cE` zfrdt}CKtm`f)G?R?bPFP<>AM8mc=a! z;<)G%nbR})s^hR^J^s;p%cX0fc9?eP;P#V_lzjx7PIKfbNR+V@;NOG%{{bG8w|P#z zQ({-3$L&!iLC}H;kItk6O2Gv@c!kP+PJ1q&k$$Ai-cR2o4JNSsQC(`?8*(<~0XJ00 z-ulbu4L8mpI)V&UzrJ{4czO!>zr>(;#sQbt2!Z8E`=9qO;ea7*!K$WdB0liab$nok zb;Qs_4+{)4kqu5c`&M=jWcVZr*fm+nOuxJ6WsW?=>AHDfBmPd4>v;~Y>nVHKwFDsA7*Fx%2{YUda z@%-Pr-Z=U1OuChP?nq&U#713~fp=JCZu_mG@sz7uHxK;xVp2RzsHuXV3~RvBPsfg; z8^<^39@xm*Vci#}@BRfo_kMm#G_gj#@HI)LKOBHpK)cRtQNQ7lSdYE;@$l|mT>MbK z7}W1KU?;RwUY&ip^B%zE&MRqGrKDM2QEnM~rk0m~a$EXxNS{A%hUIZr%ZmclMQoAq zYBYy#x3>q3dETBTO3E+y5|tu5atZX=Up0KP8I2jntm-2loK>o=#1d9MdnLO@fqrVz3HyH8<%boa;)TNsf(%c_;Wuv>)YUP%PbckWA zHRUKvk*DTd8^cM}Z}vS}2{gcX4EuVWKNqGmlWmT7ewL|}WCW*+^OlHxi5So_Aw>p& zgopvZ{6uM%?Iv-yq2s+W*e(8die?LgcVfRA;5TQ7 zA2kb9McXgxZK{Fc7WxJT-0AEbkm#JbZcJT*!p)r{?tt4Xqw|B}ABo#YK(ii_y05C5 zasx^KJW7JzqB;kZ!|l-5#~{Gapohbb-V!QD9L66pAP^Usx4$c03>_Pg9~r14bJ*N9 z$$^N$CXPx#O$Mp!+d|Q}5=m-=DoaHhFuk z1=++}Fe=8yAGjm1$XoqnE@dW%@T}1k&NVDWdDR2+|05-@2gr!2rWwhjfY=Yid1Dve zt%rI}u=RQ~U%7jaaq}R*Qufvo@>#ooczr6m^t|BFO%#vbNAhM8_95VtWb@nd!+a8M zxs%kWj`hY)w}v?8hRtb-vE&}m5Kdx zo2CEv1h!9nT1?bUC0MPqO^<1;D1}Tsxg4w+b*d3^`Hnwv!@d<|RMZh$4fg9Q={)Zu z%?U}TvX!1Qf_^xC$aP1ks968!76&~OGf6TWpV}nr3HcJ-DmRJ!*ryZZV4IxJt68E3 z&XTjEoRy39s-x$2N2~0)wAY`Z8y82A=V(xXf#`9CdRIlO9O{QZRvCsuNK{NyKD|tH=-U3UHCR!f~}3VaDoL-A&Me&sH9Z3oQ->>D1og? zlL`-|*n>%1b&=i!s`_+FH)j)UKWn{*?$&FZ71TL}BfpTTNHq#QyXn4|vP1dI3Qpm4 zIZL}AeV4If-0OPy&`T4nYsdKM+urT{x*jD>a_7%N-mcE4CwxHd$n8co2^F#yR|lrrC5%U8 z*HJ9&z&`XBHsfd}k9-X|O74e>Bn)7nO~^imT2HWs88Jg3!2}HaT2<4EOj{Su*8>0m zbh1Wdp**6XPPVda{IXsCB9_GmGhyV`*@HQBpMF#o$qH*uE(csal(dxKy#?j@WDBw6 z0@=}?TD#vTM7fOeFj}$s8)-7zr6qd__nE-9NN#(6^jUYBuiyU>vA;Ybc%~Ez#I4xn zHl3$XPcTK%bKMjnRwdi`kXk5aTPtXnC?zO>C-@ukBUI6D->8Ex&h!gBGewbB?k__eeK_+n=lIK-}jMhH&n5s&THxR!QZ^i zSvjdCv-r*6sxZo6$Z+g&H}!f<8F(k-$TH!sv9^7G#L9d_3D3ceYOUIL{|jmkj6Vyw z7d-=YP6P`#fj83vs^!~OOhH+j53Db@#h?EtCEwOt^J$l=(j2k~<*mXkk21}Kjhp7} zacAno?&wl8m?&=@zA@IKV5QsQ#YwcbLLQyMAB4nvdqj^fo<`TGtE={jiLx|PH9A-^ z_jv8N?D&82Vz3Z|Vaa`O(2vXopo@u-yJBM=kYq;Z!W<%`X_%}|zDh1Mh-YH4?_Cuo z5AvXHPRS%B>%lJ;j~AY+&6es_)&Fver3K`fT+fJxNS0hDF{4#A%r(BzyJvTJjr-uk zQa*$ln)=`^d45T1coc~{%|4%!IlH>Qcze3s*1s_Jp;#DIStD)MqHpYgTV6z^ z;;4Qb7T0)_vftX6HOB9p6UOq#jg_a;d!1kwRpnb5oJP_>Z9aBZX`UB{7fg1wJ*?)i z))~I{h-u`bm-aFtRUBe1T1HP=yK;v8F{+NGB+B%Y>+R?I#vvHzfG9) z&`-Fodf$;_#lF`%qg^W_W6|;obBY~q@Y5i9TvA|bBu)o3`s($?yqOmQozH^ze^JK z;aD0pdP0Jr4L}@9|C=!iQ7lv%^(LZG?{e>T8&?JeZ;kx`kx%Baskt-TNyKMB_-tjb zsY?(E6jEewq=cFOw0Ol`CF5#0Y6a5C&wx}PXS^>)JfX;51CFu0l^z+2O~E@hZU{-f zO?SXb_tUr$y>`mzNtRA_BPg$7g!UG=bemS3h4ZO!pxeXV)y+pHS2#3EKTW(G7~y_IMU9oay8aK#;t^-!7Tl8n5y+eM zJNIbTWfT|kLW$>m@-OoVUtY7AZe;Y!pe-BvR6>r<)Bme>QVNpIUjSloVw!<*4PRhl zrypq-_CIC3V-L8=j4tNpOBK9ep~6;EuSyIPEccepR4-5wuZtPNm(oR#c|=iX5P>o0 z6VWwVBw7KqvEY%K26zL@&}9&Z?j{mFb@|k0kmj1>wkcR_@1!j)juwqpqdM5xt8d3e z5j^Y%>el29Lr*MD()|>6hs`v=`H!U^8|k7R_f+hCn^}GonG8R;I(4=&Y~~85Rg91q zS0Xj)@q{9!CW4=o!Y#K_gM~ke`L_vc%?Y14fuwVvO(JYw$OKhI+gKM_YKN;_xDSo1 z*Bri`3?CLy-*9x1Fi{JCTO)#7l> z=hNaecZXFap=%$7AcN~TDBY^e)kgEXoQ;mlXbSoY7w8uUMl<`f@S!7d=lM@e2?yeY zDeVDS{h~6H^l*Ix zg%8LkVl`%NXq@Z{DewS`OiWpUv7XR3W< zOp`W>tl?`|*UM3tDNZ<|9PR@}=e$ANXkO0+Eu3Vh)fj{rBqcPcyAoPo*%NE3sR5ov zpVG{m{~G_%gULP4@k<(!(d?`y2g%@Ztp13;+C1wB;Vkuf9l6sgma^E7Sd(852e?vy z5@@MHyM}4~dO{yjd$Owj!{%tseIMQ&F!@I7FVT!m2$Cb@dsH6k8j$plI&gDQ+a?<1 z6pt9U)Yaf|@6SnfBPzG0rcs`Ae^2bGt|fHDcv#kB9m{8sZbKl=f4d$S@TXbP>J5O` z@85SgcP5h}_;>UaCT8r2{DBE6?r7O~@`|O9S(9;wLr^FWK6dVhP1x6vM;a1m)L}{- zdc8@J?RKurQy$|dDzV1|Y5ZD78~J!&CH0p`OOVlIQi$e<5nd_Uig|OV(k6<2z>T01 zP3kXgG^*igvEi_mbckJ|cU_{PwEN-?9R2HtRB2b!WhUo9N!@O54-A@Y>Ez^gPC( znNKfO{cv*h75cv|)|b22Ep}y-ct*7Q;I&uW&T_`1AV3biiGn8s&HJzOW@U-s26l4d z+b-B@ZtEKkn&3q45%@T!3do{Wh^Y(dM&HLszw`C<_+TIFgz%$$IOaXO5f|AtF$UhP zhexgKDjB(&2JhY3O8*_f%z@xAqj3N)LsrEC#q~vIRBJ~c>}q)MhwIOMwAw4VyewCb zGsbbnl&5vyz=$F1q`tvm0#6;E%! zGp0kO*L9T7M;saCZ%itwE7v@`czWROOcO$=cDe+}GS)tc6T3BokHB6ri9zWc0eeFL z2n!7T8KBR|FvG&e^19xqD(BhpXowcBAJWWih@OUdsBA$aJ&Ol3VH;(1k$$Ljt}@D* z#gb5TQqJ#d-#kbsrZYP&^GiPzIrd^5t(R|r9MJa*UAbqo z6@e+YOb%WoJ>O2>&`nbxEtL=s}PFNW=1RJNGK-EUhY!|8s+sW>uCY#qIn%q65ck z+Qv9c+4F;bwl4h_`fc!~Qtv+C*H*C-aohm^8y|axCTFPd&AKjKNg0eW>Kt@O-$q+4 z|2+iJtfZWTs#Otxr9nW^3OhPKLWSJ~MB?)Jht+SbR|Q5JM~pRyXre$I>h*2np`Whn zey93=KS^o0F6hFm@AP!F)xT}Yp{1&x&6^qMxwS%t281f2vBbjIclMQ(YWoY||4 zYcj19+N)=e14qN#?WQngKb1tm%Iwluxpd1*^rGD`o(0weUnpNQDWA^`0xq{a zBZHBEU4jAw2H)-dO*OXH^I^>Aha_z8$CL1FVH5?U1#pgT|{ZO5fP$W{Y66^GV<&zEZ~C9 zN;_fbAGzgWqp1_*M&3wiS4XnCBX?4p;LkQkAJZiJ@15c{&d{4HdHJmO+V3p=7qm!) zfA>ZtvVVvOqP-o?Yg@-4W}t#<=KWK;@ce;u46?A{7ra3xL&mzf#ljyn4NDmycEc=p z124oc9^SokA9dq|YSQ z=(SaNm|8w^TH>hPnbH@D#Uqk>BEY{HJK2W681_A%tx0`uA4>|nAP{yUW+6<9$NE@b zFv_&i@unk7v=NGP6|`xMP%C4}D~;|}BnCFkb(-M5oS_SFK#fxxQYuQO&pZ1+0BJ#% zzDJaKO%n(%&rUJg#|;8XQ=+^G|9yU(pKq?Za~{c2*)t)SL}ENn_fU&XUy{yA1s%i0~h{|Y`ZxOyntD({@{Wze|C8BBwl))Ds zsF>+;&f5icPNMU8Z`Iv=XFQ#c=l#$IUGcicOBq9y2+lay*O_^!h_w zue1M_WkpptIF8eGU#M<*l4TjD)f82iW%C@De!mCU?uN7|P*M{3{>`?7wdtR5ZsOxHNdFmEdp63#V0Y+=8s=l%7`kvP**~YA`!Q!Sc z&{2{&?!wAV+hSUS)*U83^jxyZgmQX?S}WO36d_%gVL!n)n&a0m*}r{<)(Wz`>dp{d zgJ>zM6;|r5^*!`(0bOaVZBeGe6eWE};JR?NTC%JPCa<6KVG!aOOL%XW>hy}u7B=dJ zxGm_FHF0HVg+V1geJ7w;6VtXwPLZ95K1P0J@>8yFanSNrc7F>V~o| z5W+GT4Ophjbw8LQ3=>|yJm7M2MHqP9qS0~q^tWG-=T+D1g~R#zC1q1^adFCMI3Vst zNFm7coZENqQk501lw^wq8-qSd2&$@JH0m>*T(LPCb8>vb#pH@RckW`1CCv+d`N?Oz zKDh*?7!DG)Mm?~dg|@9rT%q~V55L3Z)fvk)XLI8LpMQSLV%czfeA3;A8O_GlChxxg z9-HGa5ANOO>5~VHH)4MO55G^%jLX>>J3F`O54H&Wkm=-#JX?`x1!uK0-}dE*IRr_m~g9{rkkDh^zStUZ^?0JYZuq=G8ZsjJEDG zT^xd$5qgs0&X`~S=Iiwm+aU=9UcG$5Vpj0_^>e=e?eC%f%RlB!Yh-#K{RhR7V?o*ymDbtiB2ym4_ITEEj+9qWbD;#5S+z``fd{5wdg0eK^RZS2I zqS&Q2HLb89U7E(=d4A{Z^(AG~pivY>gXj1N;dEOO)3Cj@!@KXjN1o;!9UO9Td_l1) zdHCcl?%uvjwpg**AF?qR@c6+4`bmtfE2^xfE*k2x#54_7x3qP`)#Ze<;|nI|Q;rVL zI61!L;%rLW7*5a6IX*q%>gtO5d`4N6Y>YP+OEW*OdsN)~bo^ zeDqwCsn*Je>Bt(^bgkjqn440*AoS_?`zYm*7ZuN*J!7?4v9+~@H3r{z*1Z+o&!DWD zj#Ab%>jqcwgAPsTcrLBcAO%9L1N2xNYlz~AC-1+H??)X$Wv%XAx1e7)pjTCi5a9dX zS}_qf%774ZofEK>b=7$?ZC83|?RBq+i|+?SaYCFV1cA?JG^Cfr_@0aJy7c0hes4e! zMR-AoHj>weZ}|Dof5C4){shHhziz4PraKh zWL%z3Nb`bT7%(1ah9ieC-r%ceM>wv}x4-j=p_ZcEy$XLzx=B&`Q(#13i#2F?{IaM^7XSEO-!R3EG-6$=R=uafv$M>-N)?S z-o^=Cu4XGNg5Ch$e)~4Z2Pb5UjEl=Rw5Fo61+6KGgM`U^L1Q#XhecL%dNN^=7aU!j zqFWbb4NcV`JVDgA>m`!a@mqb1I{YRWz~=civI2`s>b3eMe1~Uo1W`oL`zi^43h-k zaam?LZCMj3!FZ6MJePb`;w~EOvt#`8OCl;9r^4tOy{^W&zSegw?%l>!SP1>DbW^&W zLY;daZR8=tt|(DD9=7S4n60g`MMHVMBG?|&6gjZ~?OCkvP_%~2)=&gK!jHHr3Uq5J zYmLqpZ0~Hbk_s6|Ol-kSG!%iuf{JO~qE|Uh-ar^3@AnAr3=ob>dbz|N&Iyf6qdaQQ zr|}(RJJH9c2T zv7G&jjb_*(U_*T*v5i3q)kSMz@>+6Eaz7RZ#@}e^n$tynB_6YW|x=sn3e3& zdL!m)lh@UVnYT~j^a%Qc4oh3NxYF&00H@0|ASL0tEH=;c?wU=v!4ARzB?NU@v7Alu zT#qD9y2kJ|c~iG7Wl>O;Jus)8~v3H%U$ea+Ub z#&O(rDO}gD)Kj1*cZ9`Tq~{X% z`$VCKat+Gs7JI(GE|hIs%=%u*0#O_?9*<~s_p@0nm$-o>NkX=FcDS4@dHMQ?;b@Ff z4wHFC((f}E4M_R{NiSkKU*dZ{apVz&2?|M;t~fe8=xlpoM58rZndxmjH;2sk{3B`(~_ktqR_{46tk-- zS_`5mLJG@#Hb=KzG-6|;&-RYX$ zNK6~?^4S5u_=jKd!Mnf5GAo&;GlcTFwX=uBB1Mi7Gp=SAjQh8Fc>ggUy!S5ZU;pus zekR4bL0UOIa7Rt2s&5Abo*Ne41R~PYe+bt}hsE z4!Am>aC&~lJKud5Ta*-6OKxxMk+vbD(qqZgI2OXH8p5)09s>`IH9_A21pY)-vw3vSDww{C2(R z|6S93xBbKZPVunCAw&R-9sn!_k@|VzAcWx?UGDmx}vuJwZ9%n!waGfSNVA@-}pvtsn@9ZawRPd?*6{mtKT@a7aRN>GkV6o#-SRFy@B6c$&)WHKSmbDE~5X}UpVI2xnY z2-A+JQ8Aw{3H*SvsF+P>Na;|dIZdMx(!sWty4Ae*{cm@Ha4Wz{r0ekN=vUl-X!*S# z?eOUCm~!=kAAEn0@pzM8{_-_hX+Rkc4lXGQ$g-wmzB?8n4EOKdK?y@!%-QN&_C_8% z+b(BUOI{xz@Z{-TqTY!A?SK6xAN@LKxu_WQ9B%J#@^^p#TMmv|8tvhE0f8SNgkfV- zG9GwLP8ZzT+2gxEcn_%z^J&4o{X3i;Jx4ike0+&@1drc+$XDN-P@9@}o{mvYhVcZG z#T3&THn%pAoN!cTN0|#o$vy6F zzt7(0T{;|0H*NU7$G`ix|Mmv)>Nze!;9(Isj?d|Qf-stm{+Ol%{B?-YrlM|YD&3H# zE0SJ9T4!wS?jT%;i>pg~UlAt(t!eRuhb}A%mq^5%&*w-KuU;3N7Gq{|mona?c4IDP zDHrpW(j??fM`5h$nkbG)k_2PA%%yS^Wl>;^rfF)V5QJf{?jtHY)w=AmaQ%LdAPBG) z@*?lt3r&rbUC7%H0{kGLsXIjNHC^hu!$>KKRFbOd(57OYZj9pyN4Z!FMNuH6yiw4l zl*qNpQr9(kk>BJs!Z5ta;?;GHUMuy`fmehSI0)*hgWEJsLmUPyrZeg+M;OKIYDu=r z$>s}eRT2jt%WQ=e4!z!xwyMBbPLI!6tybL`>|9%rWtU;JE$#aCQ06JwYQ_D9VPmyq z)K=UNTw>2f3I}|jCh@2SE_tL`xt5g@EPaQ?W{=}h!Z&fm$J%l!Bqj_Hy_j%gh~JCX zxyO(&=+5e+!#6Zljjn5K+hsQDrXgJ|8N?C3Qk)zf;(H#m*@WeC!P&`a2jm!U(jSbm z#$2yFxqW+&$<;a7hO?7X4qqLyyL+q4#)dJo$%MMf7!G`hW-b@6k3j|LuSC=PZ}gPBGaW^X$cQ-g)vCJL3(qJmuv4ln=lA zJwE^Pt971DvC5Yu{iNI0DnY3$PA|`idNEm1tnbx)>cZjPy<7B$P&G@mwn!N;-q_&w z-F>{!W4@TPv9ZAiAH2tCG$cz?di_4P_J;(1jBW$ctmXcL$HW8Jy|u;p#hlN6`z4=# z`kdRlAMnoGA98r|1=IP2)k<@8e8sKX4>-G+Q&dZ&*WmaYxS_|>4+C5;!gITOnYSLi zh5EBU{>jhMyk@q{`24G{Ik~vx~=0E=J zKl1Z``iPgWUo%}SnM~#g({lgeeY_x|Z3Jk^?b~;Gw7E}pz94XX8fy`*q^=7@ZLn>P zSS|>G*0(rGh*?U4nIU$4JO%DJ=-`3fm>k+nV zDL3m2SQqftYnlh5BY$-_j@8=Sg;lcNm29`aQNbH*Zu9S4pBcW-uJ#2O)9NCyaX> zpI>y;s*gV<%R3~V>$>ahvmputnx-a>V)WYME9jcgSLuo@%~&j!G9b9T2|_BLwXd$P^lTOl8Qc#Ga}z-M2c zQ8gaNrwfX#MH`9ZDzvU~6zHbu8gR>$|L)J<=YRP(Kj7(uP4;e&`TWH(@hIWw&4kZC zzvPSG)>JLL`@xtGKfHtE_+)v+%YzklE5RyEV@Ub|!=b?u1?94#DI4zI*`umUR*Rfr zPccaP9KXp?ZbWMvE-t4ut;Ta}zW2cpSEaPlCGZsGd_@%ZIK4QhtP8@vWS*~Z`aNzx z{Wh6Q$igiO6pS{ou17kXF&ynu6#KRHgXqzhTQA9D)kI;^y6p}(q zCRv3HL;O%8d`TfJt#m-Za1^o1CbSluFvQPVBIzNLm^^Qg%0&r5Q8qNSp)M+<5cI+T z&vOyVL3%DuTHzdB5*H;_)CjMmc1a|z5?uzzg6nip2v;c-a!rft1`XXdI99-Bf*keG zQZcOxoIqi8i66KGC2+aK+ZZsf^GJxbu zuURq<1!a-4k{(7YjOVh|mkc9;juPB(fGb==&!-)RG~U+q3pGFI$)g87PMd11*gArv_qwAK|G&rH8r6NfpHaB-r*3g$L5=XH}`Zzs@ zO?`zcuXy+n>|vUEI3 z%csBk6c`1-ToNiyP!4FcD)ykY0$!=o0eg(hgOP88{$Eq z)-F%`++hdWI z_+E(CEvF~PG)+UR+s-Dn?tXBj)1C2j)KFJgduAG__2e(IpCzxEVp-X zfA9M&@7>}uidZBuhfT|Q;Bz_}@I`C+BCk1DK85FS`{`p;KS4x3m1$X|i*-Q1;c7A= zFA8R}32C}yv7E77&RJv`tNENJ&w2aNBX+m8x)Q%AqN!?jwzk;czfEhQ)&}4ASuGaq z?CxN6%jww>X}Um2*cflJwY5c>=agwm9C(!ZihjSx_U?i)S#ff72HIh@D3C%ho1L>t7xdyW!{IJhlPfm1`)qD*vRtju zt!6g6;Q5O$D2fF^=yK=o175s%&0^NDxp@nr9RBH}&$yb-ah)Mq+VKAS-=(d64i7H4 znjW!CkC{woZ13D>cW;~d{E|2cxtx8%Wc7@r)0Fdz2}<!X+K-`+)Q!~Om?%fmBhx}BG{EkWo) zt*?C91Kcs{%iW7;kLw`rxn& zQYnSdHSzivHSjH?o`Yx_>IRGu`2Co)))*Oba&ba3R>YA@V;bsp?}U^J*OmBD$Sk!~ zjZ4#dw8q8gZnK-FIZfTr)RrREl$m5Xvn-}?byhOF$e3JZTwE+UI=bZec*10oFXOE`SY;8Op|=s^MGC(cfF}_i?A+dF`_=}+1w2qLC}pYYoV-Y>nub~n{?q^WkNot% z`YHeNKl>y8PLx zVQ2pit?s_J&N|hF$FKj7T4x@*$KGwmq>?v}^?EP^sGI8M*=w8j=Hp6r785JFOq5s? zLZnhyz+WGBNfOiV_t@ANF&YgS4Tl7tkK-yvg8{u>Lg0DCNe_hL*~{1b&ENhVUq5?} zQZD`B7$F_%d=wLzz%4rTTPyqC@Uz7nn&-x z&2VdQ%`V2GnNCl5{rVI3c6`t^%lV4!y-mJ)e!@Tg>Lo=XDT@ZBEK+HL(4hm`$&OG{ zYZ6cKKm7OKDRv3x1&KN02Y(40}U<@$-*qYK`Y<-v8hM)9I8?KmL+13~-!^FfiCwGaL>HT!%R9 zvv+r&q~~*ba!G3)Dg>=w@Xo`S+0_gi?X!v=G4J1jt$lji513{Ft_+E6%|_CvDGd>j zef=8z0FyY>3R3A~y^t1(kpg_x6=pVqx;3a!5cU+htWd2a%?nxwg2=(PEqN=EL4uRF zRI7~4(Kl`OZC0XxENe1pS<23$=qs05mO@$Js_r$P z&I_7Mvpk$a*|I!1CF=LNI+;VXffJ2!GHB0d^eW5UAmoo8?xO07td1!za(r1*O(w|Q z9;-TMqjgY|f;ulryb%9vN`DYjN0K}%x)QSnL>z+OFx(nZMH>`XC9BU4sEe8+ad5{y zq9mrWHGb&P>qoeLgQ!xfRodB(+YTCH`yocUv?v_cP}>%N)Bzw|p>XM30<|?rUt&b3 z>RSY=%;?(*#q5ea+Tn7pF{hVo4;-SNWMgQF{1I)FvlN;)VvML`dR56nYc5I`rClO_ zlWDHem8LZY$Ftno-NH{?R9N$NBDm+b?B5!oq#_D>2%+$Uh@vRT(;8RxxV%`9Wfw$V z#81BWXJDOwwlESLeDjiVFJrqvZjbk|{H z4K5ZVU9!4C`94-kin1o@4++B_SJMn9gnDsA=vWqMNhUqgG@`5oQ4_RpJ^;E2X^YdBS!C!@6xS0)i;) zauaJX33T?Z480$uQBo6f~%^#T!rhpo!YLPPL-(}jI}tPhfs?jlF8LM+dG?NSx&Jk@bIvWmJ+=d_jk3ao{tjK9wP1AHQ?y{;`tWqu~Q=Y$k#WycrGnp-T z`T8|4UcF+rT=1`c`ctOU2|xaWALDr*Uw`$C+qduY@W~^NCeQi9KYfqQoiVRo9`VlB zLzai<_`<~t0~X5}!(pGMC=hLfbOhQOT+fnh^t)!<%y4Uao5ga$%kx7v24i}aLzCz9 z!jN>n!b^Jeha(nQ%5*j%aIb%vTBH;pELAx}nv6gQ8f|HeU{O`1RYjoc7+S*VzhE{hT zU&ryWTF^G2YbX{irjj`LC@XLUR87_GkCY`Zmgu&kZL4kyZfeT9KnsnPfOI%JzoJMh z_V4VIRwZ74L?IN17ZVy`iISL4KL0IG-+77*Hj7u-HyqSYI5w zo5YUy-T7X>{`za;IAVYQ_Ift4YbD|OvtExX*9Voo88oal>x_mWP1Cj2sAG|LG>+@y zA%W}p7;8zA9-Et6G_7WpW_| z;ztS5V2H7Trq(xgS2zD(xB6xX>C_OlM$&c% z&CLMhbO>Ojy55&-2K!(zV9-k#4F~LQZ*|zjwjuC6`fHT2asuL{N1k^|&)@#tKX86A zVZ5=y#^x46D&~tNK@hGVdzZ&Cy0aM6RYTiqM#C|>H8|3xNb@cjT6Z=f(-`(2J!I$Z zEx=h1j*6GB4*2btKj)oqZF6xorEDCOKjLrx{v~e?HEFhFZ!e-3$F#cZj%izi(Gn$G zJXf*3IpFm0IUj!T9@Dho)31*(dWYGCL25~!ru0Xa(Wb|v`|tAL_S@8T$>#2DzWV9{ zYrCH_)>1V!o-cWPe~0gV`w2&fha4ZRh~k8eZ9$M2KKkTi?%vyG|F%PtH0i%34I#GAJ$1`3xt`aD}DOCCURQ=rRhm zY0qi-Nw{1)8OqIx~bUO?KE#7Tl~1zw}b53g|gF`4WLd__@^ zmKj6W!w-EL1IuMWo;I{s1)&pA%Fb^Sg$eZ_VU?Hg*#Y636SzvT&#$=n;u{WM9g)pj zs`D%MpKO!44I*-hrX}(`#c2gs7Z>c^+rwlT#t|GBOPq0^WHi9hf~;u?w?_0fx6vx1 zxm*xTa-;z^6WonHeiBhp<0yk8TMQMhX`reIk{BmUu#SgOvgP`52b0k2=o(AwuJcgY90 z3EUo{wM^<9M+x@)2$^PVg$3E{l#9yJR+@1V;kpf;zu<0fN|MwpGQsS8!EBPTtPIxi zaID8L3~Abi2M-^xw>O|F8vf)b|20bb-4bR^otvMZ@$dfP|D-?aQ`MTma6r0RVB4Bj z8BE{ z54?5ISW=c{*FPknDytjCL3%DxuSe(yv}HxUOljH{>nNn7IxCJ+#7TmblIeU-mUpew zy(Gc+J({|{u@x6p7Xoi}*W)l8j|hAp-L%Z6Q;M=A2m_*I9X4<3&hl)zAqQ%$y9H{{ zQ77xVrpP*_#1BKFD7*=dBLra_V}O&>BSOzbA!)5Zc@du1qqnh1)KAEZ6zM^KG$4#4 z(1xZiaizd_T>{@nIfB+UNT5a_!XCb#P{tvXz#;hdcbJTCaa2m)%xd18Pr01WdH&{r zMP)H=%&cyCb2-ByB=kd^#O2nbyI9#}Et;m`@^XS7#u&QR_73V}5K7^N0bvp|7>^kY z$MkwV(lr&zbsToKx5!p2dU217i!;(ZMYs-r7;*gOi1}>B`DD)7#Rau4v7*8A1>=n& zlgmr0ti-kkM>&i)M$}D>R4zuhY;KK+!+>5AldYB*U1Lqja2V4c44KX6yg5GM^zwrK za7>)^Y3i2cY=MK|&8tJ+dGCF`e*TKtBIVWLF=rQ7xSofQn*X1x_iBx62^8tBug^1-YRJeH4BPg}#8Uq!6VDh8Q7{OHt&^?AV@Z z@6afi@>N;sj(4vvPFD3u7ZpGR3YA$0sB_-u`J10*K^S^0<})rX4ten4E~kg5lyN~k zp3}4qMU$hPoICe#aXCIG>}ei6+@qo5=B+#2y>pN8`GhbCu(V-yqeq-9I665+Sp%f# z@#4i(^0Z(v%ZY|P9zMLs<=Hu&Js?RIERr);N9#O!{p&0iHNLmP^fG0oKjf{ieTP5! z(ZA>855DBH&knGyh@JIKe)xkQ5>IlD51$iH3*LP6y)L6sWGSI%^XB8%_}c6Dd365{ z4{qP&!Tr1Rf`Hj%N-v72TSHORXv=1DIpyH+kf;~%^(T*s!jRSVO@8;mN6e;k-uT)R zE|U}Pe$C_S-`^t5YO>hkhPz66Hlt?;!63_l97v`?0FmA2aHNa98al(J}yAj@)W%TP5bwg*87p4(tK6`n6KqM#Kyy@AFH zDr~R9m;@;+ELY(M5-*elJx$oR@qC5nNmfQaqm>Ay1zI`OrD8T~iRUS0wxG-l%AzDs za;m(ctw1Xq%XTqJAa&RKbol%Qp451j#sB=j{4Gz9&e?kKn7{w$e?{6hs~fAl|H1n_ zdi@bx4Pb~ai(m{AuB}pEwMBI-l@3rRm(5Nc7)Yt^&uzN{zPnAi1iwZOyfcaaCR0)}0C~7>&->c&|*Hwd8 z^|Dv(A<)75x|XT0woFyk(YWinzJ54dF)-R?(48vu+8vWr4MO9;r zU_M(=76o+!Qfg+iMQ4o@iX@IPbxWR?*xDhVrKE9&zcS?h*Pkp$M?+VdZ1J~$_qPNC zkAMEjOa9>>Uh?8q!_R*Hl%i5>Z}*{zsWL-VRJ0Amiwe^y+O}c$#s=U0-Xr?GAD(sZ_aq}iYzU$l;JP`-8;+{89)E^D;ld$X={jXa~>~v{_ImG)qvr{ zuOmYbD|9%D9S)j196L`qwO5H7MVr@%Mx%v=XdC9!DP>-=$Qq_1LMxkS(on=TRb*ov ziI)h9>4H{(X*;z^s)nX9ke94G4x2&5>1;tRG>z62Qqoic(MqI6XJG}Xx~zb#!3sl~ zX$sn=sSFm9s;%hT7Ogg@rp6g(=oe#F(iXEwx2$E;~6vj&XDR8XEw5UvHG16D_ec7;M{ zMXMFUa;fT;Y>|SaDMumo#(>h7tla5iMGa+>Fz`Zxe#qox#{Bu5bev#nMe8_-`Hb!D z4HkX7gM58^!5@7NaNMq}|*^37RjU4o=*|P|jU8Io!_XZ{g;L~2L0wgtx*^ZMbhN>(vO+zmX84Xu(J(s#!F1*@KZIw%og4X)FVz&eAb_;-B z7~)zU%C;!mPF?YB2hXyxq(Ugg%GwG|opE`3f}<>qu_?-y-b$a>o;+r2Z=2ED3RTWVa3(9{K<>mu5gvdE~LlAaS$Nloc?weOA!aE5)twKeAB1+`$+DE=lVd#B zqpqutEut-?>O$s@;~bBz5(J_PJ3X}0AgMNgt6iric z&1h|f z_00jk=WzV;lz}(Iv<6`rtVlE381nGpEq?stx7plSVP&+=$>|u|^~jTyql42fyJ{)& zJmuBVIa#i`n9MmpJEIr+T#nCi-GE-t!*Uj^uZ6tz))Q{uyiedoB#V-j;VNm?@{j-W z58S+Uiy-K+xwXT^_>?DaKH=%JeOlA7wYka0`Z|;GltJ$%p1Z@7$8Vwj?1yjvjbmwC zTM;^fo@+7e^%$*;7>x$pzIlVkj~?-juYa9Ef53D)r>+gt*$mHfnN6nbKYK=;B)mF0 z=Ecib+`e^(TlaUV^ecYwZ|~Bo1!b(TKvgVP8aYJ{wC z`T?r62({0_(GjD5pN*9jR=o&agR2xan(=JT&fXT&=_QkN!6@kCD%Huten8cfIG%-R zQY=wGRbwlUs*xwh zR2F4BxL$~MTx{QCk!6g>GZyiTtje)eR~z{B(=T{9?DMc6@@RJ#H|UY2CGq7YTGsf= z(2F8gH&&6-Ae-)x+bkuEtHbWK_8`Qy;&3%+v`v@akV~cGYV+=UE_t5w;^j-8KYz}n zM~|^=>sr4Mzc*i8aUBpW>-ySj`MGVnfL^=IFkDwIF9#K|Y`@a7BceKZXP~((3oxu2@RkHf7Zk^adEEsar!` zc69V^nD{E#ca=@)*diK3dwq>MUPX5S>$)2>y6~I$bB_l_hQ65Kj{VuZNU2kH7m(gzg%<5H*c4 z{I7razwyQXm-x{dpM5^()zJ)8gX4fwn%TJI=GH9+(SVDS3Ch^i!k`_Ct+kN*cQ<+S z>rWW1?eNQYKVmrCq^>iz2P;=v6 zG4tp##|wwUbjV@3!6MpZW`#^EFgl>jOEfl7-y<(-(s{+~JSJ^Dj*%D%I<7E6vv38e zsmY$76Tdh_4FZhN9U0x$lx2;q8+>69O~qwXvY?^DP)l%a2OE&8rfwUw)QGl4C`n$` zv_jBR4y}~bRgGf=jcCzQ67+pssR$Phm%sU#_WX?6WVBApqwn44_M5kP@a7wA-n_x) z?hbpmb~zazaWOvYlvLR@xM{7am*oO_u)^@Q+xR=H%-V*zQWV-kS}u80(_|IqVnQ@@ zFpfY3F1BY=&I(dvusollYH6w#(>8=#BMMi6RG2I$8u-Y%LOLEr=u@u+Byoyv1lp7g z*DZp3o7ANt&Jq#@fpF;c0`lpCJTJKQ@Gi+@N_8;C2}0(&Wn*Ux*XrybWl^Cl9|8@s z<>tnKe%WyL**RjRkJ%hxltft?t-y0^ED1(+O>9QEET$#OSY)#~_!f<78Pz$(@i~^) zr(7(^%bYR{u>zm0uF(Q)Q(#pyynIYGdq$hh&`Pju`9J=5Ci8PF z+e0de?`ynJ;X4xB?EtJ=IT*{s2557%w8+zn%+$D!#Bnszc5%WLvZ`gUGN3VnAnfA? z1B6kmZ{I-VhIUrcmL;awSrR|vAS4J*~zn7SsXini@aIl_K~P+gm0m6uR=m9ugQigg?Z$8o5ens^ak!~Vh` z#Pb{wkS-gex;De^8K9NI4}1d8!x+PCHX~guP)ZSm0ZLmGWl33;*Q~Q{nN?y;i|yFB zj*FC%IF4DwF_z=txektHb!tS_v8N2sni|hi6lqF4nd4XvmR6uzcJAJ!F*QmWgoMRB zrYTAm=O)@7NBXeEbQX7xEW>`5$nC2qSH7-MYnlzxfTJ*PVA- zV`$pW0RSxRU8=K%x840@I-OBf6~kVLper~8MidpW(+=QJ2@+_^=ZFPP_Zdi{VjO*lV0 zCkkDPG-W!T^TT(3#I1X`QGt#0H4h)W!Q_0#uYdVF4iBc(jfd}#h=M-PpFid3;DGt` z5@~5BaY3BqR5^q_4@(LzPR?<(pdSWgSwa$z8J{JLR)+Y_8lQghg5SLRQ>x~Y*{mS! z4H0N=-nheu?|;BAe(@9XD(3Y37}s}kESI_xRAtG-`>*pSfA}Zd+`WtX(|5l8H=UKD zqb&*}Fxq7t7oa-d_Iy6)^UuHF^z@AWV1=XOW3nvcKmYY#vAVv>YmZ+iP7?N?KPL=5 zZr;AZr!RlWfBft3;Mo!0Vg>8KVNKqqd47R7o07F9y&%MuHfCv;vW>zvhFldW8noNP zQ6b6MjH1j~8}+c1BF`%tV+dT2`DKi|65^VYvPii|Vs-}Woy;Xb;?PhaMFn+9=zua% zRFXyrDq~2C2FD4ow4$jB2L39x3b>rih=v|QcUuG7c4;t_jbxrw5H8sd3D zk!Q^3Q?zXpdLd3vVRe|-3eAf8e*hEI=A`QA<7+gO%l>dFNIMEk>}+eHgMV!*QH$m_j0?jj$|?wy2txrf$G+oy)lL++Jln zleI`*<4> zg=na?MQd!DqC^Qp)>f33qSYFKLP?FV><%c_b^~6Gpe`GlqNJ~Fur<1@uq6~lL2JOR z1(h_EZHqD*WqC*ndLriG{Vl%p7k|tffAlA8z5WKJ6*7qhAAkCiXRl5;PUh@9evR$> z57>S5IyW9aCfHcT8b#P^5$pH1x%t{IYeR=@a*S*X>NJMBz|sO^2?kbxn2uQ)NxYs1 zK}41n2x;R6UgyCsT0%df5rS44>asywC3kPG(c}eLU17_VfsU!$l$Ff^Lu-m_pRoBj zz`D_A5m(6Kl3vrYGSvv*q83o59EtGE2 zjbYul7~}L7M@he1OXvhis+qiq*;!Livn9NzXDzVw2VWwJm_ZnJxwk^o)CIm5bK~Zaw#=~{!OopcELGE7 zUeJ~^Mz^+U2dngp2_{XMOf%wH$^K`jEHX)dO9A>ER^W1H`3BX zQ4dR7WN|`~l^6qoA0U+mC2?FA-}BIx?1qh|K`Du4J9wUlq2pTBRlO|u5X4Ecd}gVx zsmgJ?%G@j=OH=$_NH2Z)WmnRG*gZFL{6Ls^x~CR37haSgCF%N9o= z1x-_9>Y6M`Y3mvzzzckQzYB9OW;0CNk{8AG602z&XzBP=QN-E#F;p3jGAPHQuqC#w zpv)<<1&bwrqs@~pbGW>QO;fYBx<p6NWvcFcf9ZWH#sYY>a3HrmFB< z3(s{pJG~&CB~(QX(xTUkux-s?IOqU}LL#KY`T3L^x9)Q1!9!YQ^K}0eQdoTS!Edp3 z$Nf^;K}t>A)|6$ArLC^!UTG}HWs#+%MNV6{oF5-@`^FyI+j|_HUvhAKjMADs&A73( z#qAqA*p^~E9ka2y$z(Fa^M`D1Y_eEPNs=kgUwp}MWq@VdRD~g#CwQ*K^Ov8|h?=wU zoWLJ4+FW7Qmh2xK^X8)mxYDI48W!;kKM48BFMmmYw8qNHDznLyGSB$-cfLhhW}MG1 zSlL>mZVY8!QN{(?JYjZu$#A8|cs?d;Dh^N2@ckZ#FJ5teGDYhimKQRM=bW7!QOskG zPmYnMCeLRG*W+RVsDgYkC7w(vlY~JK;wX!6e&bEzbdE7L_wGKTDl3Ap$NAYYmzT!` z-jH{``y;;p)(`MK56^XYc>e*fUcBV=?39b~1siMY>}+o{8m;45J@&tNMLJ8ld*?3d z&)@mx-*o?h6^)UUMshYu_>({X_q;qh=NG?uk6D~hHl1Xe*9ET*4`_|y=FOY*miYGh zV!?Pk;pWYo6z!aU_n+P&Yh)J2Xf zplSeqL4m#tBn@sa;{1F@d^sl?h76*RS-hY%0?To@9FOUF0jP$$Sm0P1W!X42R7KXw zjLHI4(U=_HvGDAc(D$j(EQ%6oyG-I3FAQlhBzejx?9((gj@Mb8+(1*c722|qT3|#? zG>A}^OW*|z2OeA7J)*us+jKQ-W@*8)EQBy94UVhOR>zyrwuA3Q*p`Ru_#L@dXwsxW zTYfi`q%E^?NwTQOv##DQ@O$K0&HOxOJe@L|&4`~L)1Hj!#}(VHU|}Th9*=oGPr3i- zO>W=4!z@oRLa?>9!{gT;5?TsZTS#LNZ9{9S?&gnJR@Hu$)3{P0t^j*i6w~Y60bGZo zJ(G~Uj zY5;H?htcY47osZ*UcEfv>9c*dw{|*_JI6prp48!aEhFDhpw#F<;>0brof#vHizmAlh z?Ml$`K+IJou(-CgU0Jh$Ya+PTnysyEf*_zMy2hcwpwIf+Is$>MZ3fW*&-FMyKIW%C z{jYrR!N&-x@%K2=8JPyS9h4rVuXaIX(^jIZ@=+?-R%K6Q}*r+_~So(osWO}K2lc9;~9Q$g{sv2 z?Em~VvUb_M;c)L>pV6kpbQX6Z)$><`1H;8ECK}!2m%n>KB@6tpQ-R8+C0HrAeb=F< zB~6oa=ix)E-hr8eYE_a^1!M)dC=gn`v#cQuU;^y`?BTF*=>_g0A zN`OLT6}IOwM>97X+j7xbVcT7GwP}`x5LH22mh}CAm4N`WKsr{Jdq~IJa-q!|5iK~_tUnyT#JX<44r z*a}Nasx+g&x=Gzi)|6tSD!4c}W`UuW3QIw+DOrh2cK2>m8BH4Pab#Ax$Thx_43Y`0 zH^5unX3H_mE}xSmAJZGmS&15=<^(yunUv@$#L;!6J(L%h?*N4n^<~s?*1rw_g6pT z*$3~D=QUO^B+E+r{S~UJ1uQ&w&}A0uma1G}w*^JIpj>i&Y**u064zV78}xC5kjhB5 z_I8*oN}RyKQgC#1&hCxdl<9)W@ge0Rrp_)HRxM!x^R$4~A$oO4QP)&Og=J}s6eM|u zQC)tkDoU!R#}k z7Z@*#va40Ey3K#o>*4zzK@c!o%$dz*OIxdp6q2ecacrBxU_jF}OsCUjh`Ye^x=LQl zwyCO;c(I@?yU({(*8nASmkDuPo4TqfvYb54uq=yyKe~R_7J0rb|BxURjp=MovS~Ow zdWkU&?r5D!krVZL6pJ}|yx{P~3+l8$Sr%b$1%yRiwFoKcg+8{W(6&Z7HmwkR>)YSK zvTZ(p`jj|NDa#x!yGr9HPhLk$#qrSztud5UMK9{%2O+C#BMc2K4YnV0=iWo|qT$|y zhupq*kGyI*J~^Ww`F!!|2UrSx*JnOUP{L58bLz6hh)&VY>x!bTxENoOq$zQ-U^*RR zguw6hF+wq$EEo*>%olUs`N8*?PA};VB6?AewuQsPBkn(Vz~$u`heyxpMLyd*8zfmw z8c&IQ$#NOUb4h~M3#tBZ~p0N zZtwB%;X|r2$F(%S`mev}&O1`Fy}d_a6h*6vh8Dv?$mIBvVKk!O>rpou^JGezmppp- zm`^``mtnupmrp-tfBzYywTQRg`WElK_ZwW-=Yx+wWMwp9KA#eX9=Gn?;`W_;XcaQP zm=XjLw{P9&$3OfrN-A8(>&W2qtl}~*IGe`h6}gE{Nk8fnt1l$^QOxilU(3?=xR4D4U$W_)kAzxNf+k?sN9j3E{%WEiAG! z$JUx&&!g6zf3ojIxZ0s?DvC5CkQQ~FVJk!3woIoB)>cNWuCLJ6C5uJO>BSgrJ1DK# zT3uzHT!JaFv_+a`*ex_oi6vFXjj&tlra+1onv7vIpf;N6JOQalvXsHf3T7FQ-dtJ1 z(h{Xwlv5+^hO#cvj!Ri|a=ucEB5SdES2yDYmd@((}ygyC?&=EmmlbyqF_R%@=wr)CKqDvE-# zD7tW+ysF!6uMgN)D#O+9uinFzd@6(>>h}qPkfv^lleB}}X^ZWxEwp7(*Cq4WoWS#O zT$d!Tu>F9_K;5*R=XROH0Iq+92C0_AhP+~ea6N!sz1J?pcD8J&vQbhmVNCkEE>|uY zHR6hbbyXp}97e7N39WTkGiq5~ZiBCQ99P%js!v@hh3|KCW@BJ|eVxIukCKw6s`0&` zQ!pG4tu#to1Ytze8eYCQg;V;t!~qtJA1CVOw*Wn*U>#B#tg zlJWQjzy94n@%A_0#`kT8{UL{kQ(n9}!f{-bgu8od+}#Q2@A_=M^_Y!EH<8YOv{nS8 zH7?SI!$}H(CW|M`rzx*}YY*kO{L|0g=Xjcv@d+(&A#U%VoI9-1y)H6iz@U9aq9 zaalDKUf1YX)fGkF9p0o=EEWkE2waya@Nq?pXc~-gD20V>B$2Y2)D{Mq-{ak7AQ+}T$xIcr46-|Xr+;DgR3=KOSI?WR0ZX;=lDXf zxw*!@VMvrMI6FFFo;Fy<_Tk2!hu zIbP2&@Ke@8Lulr#+73tiuRuz)V|9&iZNcNmTbQQg>BmQ$9w+3jpppYdciw@`$4JL# zefJ)2bd#Ya&;!Y%Z|re*FW~US3zEVRPc9i*9zXovzd=YBAx!t9F9a{1KjYp1@_$p7 z4UKkD(!p|kJU_x13)cxL@&aiLS+T$|B~_MzmV|yl**3UJqHT%O8&I?j(p5|s8D(2j zG&%iVM9>?O)-`V6a{TNWPEjGNhOM<-7Omn$Tg1H{Sq*JgBbLfU)C=*n)3vBsnpQ%Z zq|{YK-84v{t{bAX(${&7G)btN>N=z7xgNgbQ56N_%S(!)V_!L*ixizzM60e*N{EgW zKDoT?o*$Mb2m`d$dHsu`AWKt}QZ#Ktnq}9OyT0#(5R6aH$%~w_X$S{>`hz}>)UHJGbsYsIqDFk)h5C#F-(G*!mI$KaA2~tYJK@XImDNFLQBrm&W$DU_1JwGCg=LpMT zw7EtZ$CxzZ{P=`C&hec9Y1!0`WH{PHYn!Gn8T3P%B@@ST9k%ywut*Xnvl)wIL0J{u zbJMh}uddJw0xr(anNJs;C7P~X>&A^ef}peQgn@_a_mGxLniT}SkX|n&P7+Q}&ls-w zJbU^HdAdNf0%4%7ayCXiZtv`IdU8r-TC%d}6r8HYG%dokgkcZQ^9cf<(V&lKOU4&x z9G#vrzBuRZy}O)`$4uvQc6as=qGPbk<`bHxVtad&gQJ6G6>-7Nmd|)PMY{vCQnIym zi@lv)o;-Po<7?K|H;8(Dl37d|C)~Pulj-FJj&0E&^x56sW_o!^oFv@7e~(YT_=2LT zu^fw{Drp--uQ$Z?16Ed7aXgDwblfi~Z4?%HnvrHHw&h?coAKoZ&tE)aHl1Q?>za7K zSR|ZW9N>qVjnxnfO{hZp;egZQGtSSaOfF;6Jm==kJxozB7-;IMWjdMh;K6;WHbER!peLz;GY;SI(?%lil zH_r~w7{@u|$&9nJGxqoQ`TXhUJb$^*BA%0`F&KE`$s6QJ)&)h|W=Ut1tPDq#Rd-0# zR>7O!UZ)>9T)Z0-?Cymo+2Gl3M;unV3&MDUx-DqyiojJ2!afF#lDhi` zQ4+_puq;hg!$cmhWrFnLIPOrCe zy?Hm?QK+MgN_o|(^i{TEIdFV+0B?V92$8p)&-MRjJV+;s& ztz=xO8r8C+}m5`maoNvDE@bHn%t*xBx zzRT~vFnrMtm|7#I$|kV~q~QP=hD@h|ra$2H@`Rzk!o3Ht(`wDLXGg^IfFkSBls0)@ zpfzNRjCj`2l#l*X)7;k(*ZI}3)16BvH8I^Ff&%M=S zl%+v$kY_mshO(*9%A#ovRokK+uM1mB4P{MWX>8RUSRBj66b+&5s&5xXK`8}kUE+4^ zX(~atUG!|s#f1K+r-VsOZ)26%*JNdj<@z-9n4TpF;+X&T`+vlDAAXJdJG%s7gdGmq z*?#s-b6xhM)mCRkq?;s!O}yf3kWhP>?YPk;X*zxlp9 zT*i{`eC@}$cF^5p4Hzj&lQ}>6yT7Bzb4nu_4ObCb<3|IkrnAMCSw@y5pbfTZ@m+^b z3N)l;j+QOxmR4$}X^hwN$*PKtopoB-qNGFAA96H4#VEzu!4WDgsIrFI@6oKU6T1#+ zQ6tKR$aP8boIFXv80^49+ZLjzkyVS|@8NnLS)P$332oC}6Th3bCQV~3%ffX$(j+5^ zQx@|Da;ez&2ZQT8Mps>%5%>XGsZNn73OvsviXx0@nan1nX-Z31LgKn^$5L8mK+3ZG z%BI^i)J@G`ZG`9hc-rFl`Ae$2!0|l1D8Tky5Kt8*u4Pj#8xFPBh_XUTK{)K=_5y@7 zET&VMG{bcryuil@fu#hFY$)cJG)c?C!;rIA9iv9{jXz?urr zu|P@kqM*of1cpUCMGC`DfATK~Dm=>&PcBfx(3T}zYeQCg4m<0c6nU46@mv>E*R*-T zzz@4(5Z^}#xPRv++LWxV1bDv9`Q@yG6CNF7yACf84w+rfu(VB*W{k&Uv{uaKbD9<| zCNo?sz?K24o4cfC&PSho2%^R`8S#7uwZgQLm;28!b;HfwZ6r14$7g)--iN&T#@AV2 z+vK;u`+)I$!G}-3WR}DT0fz?%*p^~zYqJ9cyDnKWCre}2*LT?3y3P19A+Jl)Vvg;5 zJbwHJX_j+vc+hd%mYGs*YwD^Zi5I;7c$J$wE{pSXPG3wZlajS{pV7KQV{(MjG^WOw ziY%V+_P6h|wmM{g{~5i$rYIBc-oDGu&K4hi{4u}!^{<#OE^sWU>w=<8SzQlNR?9cu z`Z~Ao+{dv!S_5}(-$A|p=)vFYKYziqXZx7CV0Uw!$B!T4x(*+F@Bx;kSzljcb+pQ# z{hL2SD~nG){D`g1Rc`F$a#LEi?p^IyIT#PTVEluFNguX}9)|lnSI?EEY zrO}qe^#v6f(h?XY$jcbV)6{iIo~N{?09E0K7Ez>V+6<{$%BExy$JDhzV579%9c1a` z%e*XUO+!_;owVdAg2=~qHMVCH^`rlnt2bM+?7Gi8e|xPx4`+biYN7;*APEvPPz6*~jwkcXdtO6d z?2`qs&uyNn+-q0G-v8nIejh@*WP=PZatV_@`9|{T$JflSx-hQl>Y9gIv%kJVl?wt@ zk+~7iw8Jyg;w1^aB;o#p``o*8oAG!;U6rJpHOcIX@u0__{rnyN;iD&9UM)LPMi?R; z=Y=!8o1S+Yh%bM>FpAr)55a5$?$|aZf;3IGiRUekA3tWbTyy{4{cVt6*Fe}USwpFA z`q0$Pc0zAnNRe)u7%AlzD=UBFXE)L+tU+!Ypsq=Q@pyvo2LLQr8-Dh)x0&qhG9HhS z(xX+1*)k_gQnY1jHkWv=`+~}QBk{UvuB7X2B~a!Co$Kav6V|7-CQY+WGG(`Cwa~GM zzmQA4*ofe~@PXX8)vL0?_XCVENZ0L*@i+dBt-D?+wQXPw&K8YpOo!DqrjsW`QQSRv zT$kZ+gzI&a-KwmJqmX{qBlIHzHzJKvk|4$!IC*x)^mNAc#RAnD!X#l+m88QVU;CZk z>W<bCfB; zby<}jdE;SQhw;vYqq`|qwyfg=p1J$X<(Sfqae`<|qS07w$g&<~S)jM~OqrHslHmtF zRaFs%A*;Hfv5GKEh&1TWp5U%OMkh7dc%Qqe$IE*u7Z(MmZI0M~iIbJVNQcFyL`lh} zsc{fU$HiEI@B*acpf($P3tkYQh3J}5Wf66a8^v`)7bDNV~zIYb{_ zU{@7l*h7ta?{e++VO+d>7tG)Lgu~u|O$8MR+PV;WRH;Yf`S|gW`C>&W0<@4g+7h}Q zL2l4bSsRyBEU=pyZ82baaYk=1;Lb}uCOdmPd#?{+BVAP9(iee$Xyic?%EC^l>Ax-0gKwn(~s7Ht%*V=%hG z4--TrNe4s1D8q3L%BXIGIo>6V0#@r8^E_uf*<*Tgf``MbT649Wl3!jBwk>Uwvr;9| zXu^1RhpMWXo}SU>C0W0R7l-Ip(KZcH95b5ifCKa8f}$u8!XeADEzwEidLD6_5JeGn zQ*$++y}-SvTa>NzTsC=!yA^J?Wp1|{6N@G5Wdu=2X3UG6^?HSrE@_%<>5bhGX}w-= zH`txTOKjf}lieMXG^HrJh9_UHa0G;Lj0`-iv7j`~@pHaV0mL*tg z*lgBV-4Y0k)GgI&fvzf=x&kQ}#4&ANkZ*FlAYm{VasQ?JhzpXKK+Q}qXWMFjjwZkHKi_>jQb(4KfKFin4s#ChcDmeU^1X8OQI;ms1{S#eD$^0 zm<;=@7uTIkJcy|4hRtfhdOl?|9xz|7XmyvOuC?LW^Aqmgy-&W{V3p?jdd7nXFL(0v zqGYux=ncoL@)D&W&ib64T~ZY_5ANN=ce{=BWN?II;G+-TBT0IA9*jr5ZrI#dK7aO{ zIL&x^az@c=yfmXIOUfdrpQSjCLtRxoKRMyqvuEh0CW%vo2zlkv*I2AJT+S|7l{11c zqRdO0s^*61Gn>!x`~Yl=kS&2HxOX?3U zI8ICMSFA$CwJA7JYbsCE$Oc7)>p2KdFk3IMjzHHAslUT~vA~#$alc2A=R`@$!O=pxF2LxWcYeuw zlhYscv4HeL{4hov3kcjTj`xK}Eb7>*B2Zg$E=Do)}>;ZH>hUKWT5!gcZV1e@y^fYJo%vJ@84RoJXhQqRvhij zX{M+2Rf!G-Rp9bqr$W?S(H+T(2fy_re*Ls$yf?t41E!6k$s4Y(m-KdC!ryy9JlP{( zU32g5KDC}<;~~$*gd**sVvl86Q@0+qb|~_SILvTek4CrXR-s)*VjvOqq&wno~wOUI%K`fsVjkU99%1Kt)MX$9r%F6 zHBM*hE=oM<4V#^gL&^6Qd!7SbU*1( zt&YW?E&29WUggo=6YUIHV*63ve+ojt~XrHbIzv) zr3AJM7;*E%%P;b_Mqmlxz`3T(iy zKe}XZcfz~xJmsSga8`o=DIAB41` zqGv3>{M9AD{$$2rA!)Vg zHq+MO#So}fY6~nGkftfBRa{Lk(Z-OZ2}zQWrYXi+q!5^u^1+k9d6$`;&^|Dok2$GN+Rh}YzlIv zdE;B(E0g4hdUe{>>;gY*h`q_Ij5&5v{i*K9q!$^&8HuKL{)7#+8rW1 zpH)#2`aUPm&zLQ8o;BTukS&{?^2a^LPgAvn<=SV3q#-l7YJbnI{|M6e_Yi7$iP1Er7{F>g*4tHO=|Du*S zIlEw8R0uD?^?mN&f0@;KgT=uLiFG2R_1pKkeK+G^{}#R8F0IOW`OyKpyAxcI z;K_h6G1P5I5PI}_DNWO2wBq9Ig3q3QP8dms{eY(2Fg?GgF{Zz2ES```R=5(R9Q3(n8acz$|D*}~huco)@JK7ab0FpT-?n{P6o&-k0a z_z6Gyy&rHe86t(GRhq2V=NIq%ii?YLkPgxn>`f+QzK@6_N+FpSE959Z9;GFi&5GZ2^t-x9V(h|i!OV?;}%%Fcvj4UPmMCDM~rO^y|vX<2DS5V{EIfPf(IFh-N6DSqf; zXz&9`-Bx&kWW8C@nwqLEu*MRlF-2XFB|S_nakY!@`7}kzp{}^wY}j*LV%Mb}jhMw5 zb6>J9YEI8DsI8)|E1JBdURCr%pNIPc+UqHPnDN2oHI?t74Geo3NBa}Nbd(FTrLl^x z;CFDgL-nr6m0vQ3+pTWY=q-lN=?F@m=b^TV-+8{_{Op{E4e9#vgqt>o-t%K!Yo{3}G@(h2Lj4OSk^xv~|W=Px|KwvncxqX;l9#`-$J6Iec;%bN>^zM4=(B5*HlT3??kMIsEvQc$ zK7Ufu497ez4bQJ<_;JRGiJ8lkst~j~#MlIx3^AdLT`yT)ol~r5WV^@AWQMTC`)ZZ5MoHT#0riO6d+AECnsyq*&l! zTTO^S;$W0T2nYj@UTJCHeTv&!+%(1=53#Y2Xlss>h=2Bje}t(@%GH{SkDp)`1qWFl zzb&!Ff;6xk@9fZbC3|T|&vi&$NL`0v9FX-~;?yJXCF|9SBuPPoX$) zyj&A2hd2vRUbmq!)T-rClju9jj=Tm zkOloM(_Yi>MM&);M1-4Wl!3w7TprqdZ%OPILC zgO=m_nttCB2OfJndn{*yd>yb{%;`rJ4_`ZAQ&`@8`;348A3x&RsivRyX!8w5xXiB> z==qda_U`cd!*6V#i2wrMb9w70f6C(z-^T%pqQ*LcXxOJQEm0g|jX`=|N1M`yqS#>T zn!Kpc7A!6ZK^#p8;y&xT#yXO=t!SmDFZ+bv3`7*K7EF`77u=?!{d4XUna^MXLQ4EjBSDCmBM z!S_7kFu)I7q+_wBlRpjmJ$4WF86OB%X1UE@bFyN3t3p}$Q__qvUaG2Q!CX{6hsq}!%J3P{qJFbojV!4CqY@8bml zRjtU&md~F)!xNHzzsKEIUT3m1=J9*)5Qc);?2@)^I6ph(!}s6AF_uTKKVolpm#fQ5 z@_fT)wL}VsUK;bYH(zD3Tr<6zb8vXXY&K_8)Xe4!;?yOH9HeL&_D4K>dd6h3gDasw z$Y_;9SK?}lpFR1M zx+-bPhI@A&a5cT6-IVy+aQgXEhQkqQ+M}ryR%s58CWL{M4;wq}TUQT9GCbv)$9<>8~- z2%%7F!@YY0tX}c8uRP@8OD`jT?|a|+F*s;z3FDOU?h#Kt6$HXtc(W9`Anm0qZek|U zE`A{Ke3#3`6h95ARcG4D%My(t&3ZV}MM@Vh5Fm9|NVE-6-02}bzeBKTWf86*j68f_ z(CcTkRgF@Xx-rb>ORN=CRgHAL4kK$Ut`kr;3gfg$&%@Rps**Sugw!OeVpm$SDCwp= z(#6Ip%Q)iVYD2y$2zw!ZmJ*1BM%4_Wgt0HUJxuug;+l^OP33wB$Kk85Kct`dfC1ql z5V&;t4L1#i<8(&mF3sC+rBLEUG21HD`3Sa#W(P|gM_AJp6lg1(+9qYY+aNo(R3^DC)^Cb?=OzH~MT=oErb81tP8Z&nWhqJACGr+U z%};;&ckCV z=0ziRBP;u|!TrV6-sEa*gZgf^GdIDAa+}Jowdv02I5e$7$Qwe{7xxCbB=k|TvKoGFt<4-n}!As=hSMiRHdF7TN^#d+~yL{a2Fc-J! z?cS$NCtNRclyNzoO3p7D=GhLH%2L%Wo3)}yLUPZe3{vFo9zr`5XXp6VP=0m++7P-H zY1fR7_Nc7Ktw^xf54oDIu#KW0xSjdZ4_RzBzzxF}%BsNwdRa)^3%jXep5uywIPz&o zSkwWH7SyUD?ZwR28%hn<3u&y66NDXE$?v>hlohtD@#DCY##l*fHGu%v>AV|S2-J3} zSywd;me3Eul}KZ;WsN`}w8eG7Lz9)3`d6P58;cAB+9*UO9&ugq!+-Q0oVG$QHb~(z zJD-xoKD*;ST6Y`1EbS2o5rL4<Z6qe<*=?w$_LIA7ytku07*naR94ZphI*r!6%E=C z@I0S*r;q>YA$k;$VA$=gNX0q%&!5wrtRYTtqL^VA64jt)8|v%FWWunRu4or)OnJhr zIHk992Z4`K3mPNnyDrzhhX$%u$!gUiTtSjZd`Ho2G?jEInhFyt+%m_VpCWC;@vZw@ zo}Qzv2g;+aJ+4j`qR{CM_Y6p^5qKE z)I@Pa5C*iWWwl%qhfznd3Om%TsvDZ7?R;)ow@Ed|qO~E*GK{vgt?JO}O0&$@g#DB_ zi3vRy+bY(p1+njwL?KBO&^8sWE7&{OW4JTMj{@?|igL52+HB}0DOhNgV!4{Ln9mW8 zL*2C0TC=KaYAnX-LU4}{59tqkT%Mm(t_vK;A&Dbw+i>sRUGQ9{iy2i_Qq~RG&V=#N zKG}Fke>kA2>n@Z~b{-TdVLTo%?)TXl4LH~vaqDQG$#{Tt0MWeNVbGlmtfLs1m0i-L7tvRdbazK^tq zJGT$mtj};MIhbTLRe>WUqwz77afo^ejU*+`qGnA0He#9v4lLi47rziNH!`^s@)qIUrnz|~%f)E}TXH%N_ijnVO zwW2l_gXF7kyou)~y#MY8eE<93=H9&{v{^77k0{m>&xPInG4Fry4s{K^!1F3h z)3R9$Hie+q3s|krm|k7d>+Lh0mc&uYcswES6ROtYdI?dOaCLdXOE0~`n{PfKOIz+8 z?=tC)Io^MO{NeY$`D0@=f$!mY0cG7Voz8gr^mCFl;c#b<`;Q**pZ?^JxHx&vZ-3|8 zv=U~^6>og~oBZidenPD@)9Y(mtvk5~f#*kkv>B#^`SRAXcqDAP6Vc_F=0;Rj6bXJyBjpEk9A;X;^7t;&s zwo8Lfk_cZ4vM6GdWJJPek#BH4i!IHIFhXlrR&16JZ~wf0JD>b4~>Dy()Wikh}HNXG*!Q3_OR zQMJV}lD28UDqP{CYDK@-XEtATdi|ypwFJXx;UKR)8W{g*%D z(d&=+-Zy@S=ci9-Ryq5w$K7#8|JE&jdU8r>EotoY?Qgz`FfBJW4dFOAj@>4t%k7k& z-+*@e#HHI_d1>WRz6i%HLYr2YyfUhuV3CK z+;}u@4AEcSW_;lr`AvCOH!bq9fFJk_21ArKXk!@+#~dCWW9jG}P2D1e+ci9!cI z+ch&cP0CGE(``JyXw0nbrbtS6jgmGNZ7fE2FEyJRXGRyJ(L@;ks(RBqI&)qsw6NKZlm$MjK$RjakauXn(3yZkuI+5;CntIjA)I;5uHS!Xj;55pl&OY zI6*fprdAjOP88CbP6Fo$h^53-HAZW!l$1@4?+3V2fZL&#kq$`|LEYdQi)amPBr&>W zm|N6`&+(1L2uT|T_>sfQdm|19J$xKuHz0~)ZXX{pnT#;HOHS6N^Rj*P;rp!DbC# zz@exWd9DfL9#v5h?(X9sj*0IiDBtDyR-Yuiq+Bg=i-`5KV!Z+5x|qBrKVMK?&*=Fr zJ`J054QtK*WJ0z#Vo?nUqal0y9w+BBdfA9GEx1}3>PFHwnnXGzuFpXdAymuryk=Dw zNMDlVmmIlQ^rL`#cfZ1?Po9AoBV~`_;cfD~APOyB4+>XPR6fzknjj9jmMvvfPXF`v(9q+l=^v$?#Y7x=ht!mr=G;^R*j ztXGDkqXDnHHspGK#W%n98kfrjvsH_uG@f(`oRBa`cNiMUwOoqN5X5Wlrb_Oxx0G^&$hp_ks?S z9fv4s*i;+RG{NN8Rk669(UvvC!2mDtQA(kjrh|QKCBdHS0c?RHqRa4b96agL z)-{{u3e{Bfvy{MdJLz51lBEd;2m7R1=hrBNtqD9$mD7v>h zMoKWoVLaJG3fSEnkj5@nH>9D*WRQ_>)_A^;2vTO7irI3_cs!z?^~pDD@?t~3*JC=p z=4kJThp#+929ndolwbV%ZBo(lqwl^+7&v@(d5M-T2!|~5Dar+9U1654M@K_8t0|lHg2AxIY_?%~xn}>M$MtNA zH33nuhfywdRdIGUWpQ25YC~SMY}RYAU8=f}ea6G1ZHAbjmyWtn;KZeFmc;RZEICBA z;5aTtu_8?-Oh$K*Km7hTf7}s$Ix5t~)r|K({Fv4l(lp`aJUG6~M%C<$h9puD3XAjwxDHKSQ8$X*XvTvHlktcTKKqbj zwW84)B)G1?6W}OC>;;5L%ycoslNvu1-FE_yMk`$3#W)tL1%W5gy214wigrVx3bH{) zQRLm!+jnuKgX>A8Cvbg9l*H6ci}bp*&_*>c=tz07#*u=e%C`y6f}$vh!U&@@O6gAb z-)e*-@Vx-lTH+)iOGA9OGwtTpigi&^=7K?xv7ZVKZNq)*k{W>#K9P3O#t`iG`8WUT zzv20NpYRud_r^Wmv`-%5A!>(Vf3VDTU|y2uHG7t-2;-`yv9crZbpJM|9FQBQUMOw1#|@ z)08cB(U3+N0RdPCH}Gjx+adI1K8LsVX!CQz^^A$WAgiB~oEKcZeM%IDOfNQ==hyU< zL)cGn8in0d=*UNTKB1pblUQgHj@s413KSO7Zr}{VO;^z!D<6rbE&e5(DMl# zfvYTfSztyHo@41R8hCPvXcbntxcxp>6znA~qpW*wNYVMxu)6zyYBj6P>V>!G-~QYG zji0^!7XR?~f6LF`{s;c%r$6P-{`}AR_IJKZ7KJ39Pap)oaB!?46fT~%oIF3_-S^)| zI|3^t!_f{Oe(*6yS@tHoSPl6qr)@0xrp6I22YUxR{pe$Ce}GtnSmtEAF(UKW)D38l zFimjtmgQ%c6s5wXF(Qm98p|*Xs5WyH4q=qiwi_H>qCJm_nkcc4I`57CTvC$GK1mC^m@wFq3Q~*^$s=kKdXpdiiazd5tASVNA0ltug zi6GcZI6t3K8$ozF!%rluSfIU-q*ds5f6dkGnq@p8%_26NlHJVVrF%7d`!2B`Ae@L| ztx=668XVJ0j%lVXvtmix!sSzkQM$u;7%&_roSZzP*$7S_Uv`}SP|){Q+&NCkl9Jx%jH70^*Jm2Oc@OIz1?zE3*n6NCY)#e(VS1yxbv zdmd>V6Zk<_v^6bNU3EjLZFW?#UQy;bX%vzr2~iSI=LPv+Hk%_=f-hFuQwp{Vy-UdJbwC|N;&v`%+>QV=4Tgt`t&*1RY`Am$fl}k zRX3QG9=!R+>y&xL)zuYRw|JgJIsy#XR?+i3q*kofYbpzl=OP^#_FVS%Vg`c@r7W}A zn#;?arVe@K!B?2g7R+ZARW5n{{1j{8VD}zz6jKxp%gu^34VYh5^ao>H-{rHG-^S?`3B5PY`ZP7!0_ap0ipm34DvOHTydc3BwrqgYSL&$I1#SWtgu^PA_Mi zTuiAN#h~BAX%&rD2m}A<)i=4bv(MA>Q$9O6;e+=-WImgdZ*m+2cW>XLZ8cq%LWrp< z(kNh@^$4;EWxB~}68Jc6gVZgKYCty}A0JXT4X%&~0|x;JXfM zS7Squwx~e3WWxzoDbAJ)98+=?1*{mG5#rol?h| z)NQ$46nNH9I8dmPo`hoon_s-c=xWMC+wi+t$Pcm+zrEYz&3=q%YKm&fIQBVy^b#Tp zFiNon#%>Y6-8+J9aeGskXsyw@lLG1O=0b0?Fq&pdk+NSHl~vmno{hQkWW4BF@H5l7XY^^mQoGqdktaVUY z6DJAl^$k1vK5?92?9Ev_`qYiz!4b}jkieVpKD+gAe0d{rlN8=HT;|2b!CJQI>fKd~ z|6kDGP2=$8P{MB8(Rp5^6x>Lkx+a9*X!snUED9XN7NuNKRTZx5p|tJpmldeC#po{g zLTig{?Y7a-prOudTr1JFL6r&|L2DFktLa63LJ<&nKCM+$vgZ5$;-7#}oxIF~??wF4 z&)=hREd3~DTpQfyQ_STCr*#|;b<4%aIsHh}3u-*QOV#X? zD~qEA!j_1t#HIm8TSTGJIOLI}@@yB@WCd#>*!VtJ|NkTF&3Y`$((}A$t-bcV&lqz= zPL)-aRn=A9B%5jxoGekMc_SMz3<3T-{2_*XW!>1mF)aavY(aEOv^jJ)ySv7$svILC zV>)rhJ+8?Y`$Sf?m_Q9T|JC?|a|(c@g!R+j_y^{f{w&U0!Y~Qk7B#InE5A z5s>DHBBgU3*64mnL@*gmaL$sal1Z$X42P5=K*R+}m=X*pEC_ogsH~BJq7#D2Xuu$i zX{!xVdZe&;*CE5G50W=6opngn7ktS$#A%Ik2D%n+Ju*;Ra*P9KiPIP*Wl!3Z65lkK zb&Xti$Vr0fYWBJSUfv+B#W;Z+4k+7eme;TN#jk$O7hiqF_3bUUvum7f@B*|oL`g!N z(77AlgID!>#x4zbW@Vte@NqNf>2=M zh%yqm-64jM%!T+@GxA6=I@zJLnz&iBx4fhdB36SFf`P&a7|W7(4;DOmG$l_CIDa!| zclQ|Ef|~4OTgm#XE7}s!5%nfucVBSwu%KBhRtvpd7Oof^rVK_2@88RK^5KB@KZq!b zgsTflHb~gNXK0%xQsn&J@B9fxGR1q_6X$?DP56s{^S>Z%L!5_XX^fKwsUXZ#=2gXD zG(yEue}A)%;b;s}FddFa^8sm^kR}mQfrtX4!2rSt6{Z;9ae8saaJq+=G2u4!nvHhY zIXR{cBa-nB-S+T&y4s357sfhZ9h)`+kEU2*~oBC<>9P&x*uZLXxJq z&ak+hW7-aDY`^`_bBZj-Z0{8+46)wh0B zss8>S#}Tno#9;`|VRVZ%nj(oAO^56p?vW)a?Q(;$hIL)znhx7(j5e&-8&sSy+TA4| z4G28k%x);F5)lMUrW3Nf&y1)*P-H37$%r@#d$7nBsou3MW!+H>#?);?mc*2s4eP~% z_2QPr>V`lG4iAnHf#AIl-($I6AaJBvM4pBuktB;0c@h$MhwfUe?Z7+mj@{h}ySq~c zgPfws*xlXX{{0h9PLA2z=>as>wQmQ9BzlyECF(UNRaEST9#d1bW-dE~La7 zL#TQrvG9T~zW5S+K;1N`C}2LHQ`a@4(TEo>UxA3o^D#x9p<7Fl4`|z#!=pXYIHGM@ ztd%U5a{|>d-3ckOn0jr<@;$yjJ*R3kb!)LsP}Ma`g{&4U&Mz)WvVyv4Cl|w>@*+#_$RakJU@Gb_5rJP!(y@I_~?+Pta$$HC2iZ%G&OM; z;*9Gv$X!PsDqP#qT8oP#gz6jS6P2*uEGRc6h={6g`1aXz&d#qGk8?)jjH+xoKfR$W z*BGOD_wf_1uHG=&OV~8$J-IB2i4z!(J*ErLwWQv3WNEeUM#-T#EM*O%PC|31Me3I6=-{DRA?8&;c|x-;C|&hcLI@rNJr=JJZhXx@AH4x=z3 ziXz5Gdn9?m{{B8YJ5xdxG8|1fJv(PK9P?lQSO1*b`3zlGxUOZV7$8)?c@3l_mJ)>{ z0;IDv=>XvcE|gSFi(P3R9Gp;>8$zv#;()7m#d@=0kQS&kWqvb5w;dME zbTS~?`rP*?6TGloEUwv^46#<(C(icOXa13eyeEQ1*M&H+Z42Ti-Zk=o~B`pp=mpwK7GpJ;bAXJn?B@xN1l@3E9jHo z8#L}R8h7eOA5wSQgTDPvUGTndYuzdh{Qz)Rh9{U#rv!n-I{WtfW1IOvepeKDHw4^e zPx{xC+m4UBfy-{y4u>}SErIH8FzSbf?}m%J@3FUt^+Sj;_HCH_j!tn$)&hQG;JZ^r zoOdKyj&Z#;&wAgNcF_mIz4g>}OCVM61#S(lbGXj-T>y>7)P^`n`T@j9I@7V*EXkuB zWfjs(jJLSRVTI$L{r7*;4}raQLMRn~_2o}#V$GAd=H&L2$7#qP{^(u8q($g!W@l#v z#`9peK(r0#i;fp|pY{Gb+)$D4q?m9AXJf+ljGOb9tTrXNh!~8=7zDO5NCN62po_r* z%jKFdO0l93P!9(&W#I6;hfoZdcb2O2+=d1Ev}E(*itOl+Is&giNkO}52o1zS(o`k7 z?P#^3NkTS(qmlvZ*t19js?IQSVCxOxbWG~bk3SrU^dNhdu@2)vNgTH}o) ziXw;ugtiQ_qz`kp8jmE5BCIup64E>)QXzHI5Fk)qU^X>!Rg+B$I^D7(6VmIFX0b$T zkH|ALE8^I)?i#A5Ww~B(eR0a`*Dv|z`7@rsdd2fsuQule-r&zUV|{OO#D^ z@lH}!ns!w)*`1I?Av^mCu3J;L0iq~Soh7d%$-M`>e0I(A|M)2@?-7HHVpAhyO>wBm zPdbM86OJE^u)0Cm5>YJ)4Ctn2_U$!xE|_-)4o7r_LQ2E27d#q|dDYa&9NOgqIXR$o zl5rwA5NF&k9KyuxpFF}39}*tiqg>n&Wd-)|kP1PYNK6`$m4@JTO|fX%AExN8!Yr;i zo=Qk#R>eMR1kotv@nplhMMHHS^RNG>zv1Ra(6oY^+ZwlX#A@9UpRI_>0B=*W@h&F1 zV!c@N`qK@GQiNkglt_-=negL(@|X`EMx=3#Zr9Y6Gw?6uP zPWB&dapJv78)p&!&%gaY3A%>ya6siX-da!!5yfa9U}S)&w+A(Ki&7!F?fPYukT`FN z;($QXZZyc)*IuJY6buRAOJ~3K~$nBB+ina5~W+D5KJdyiXx|J z8>(%QpZA{8aEOY+{=Tmb0RkB+EFKs1&y1$5QBw3)n(3Gz3|OodG)>*(ShJKQ?!)p; zU6LdT!bhBS)_qY38-~*zyn|T5 zXpphDzu!X{suj|Er1annN(ds=7sn1qLk7bkS(^66fkobDFt=GuV=T+%imS^j&Q9NO zb$!F_?JZ5yTg`0iuom_oeaK{#^Q)izHRq?Nn9edRMvRAJiaaL>6tnq~*Jp3|{EM%c z-7fh2^QV0N8vKrGQRod8P>HB zSgx*bdG`Dz7gv`U>1iZ1-l1*4e6E@9>@yrC;5$~c1yK+(o896OWLegOUmPeI5-Pb4HxZN39&gUiIXT(o^z>^w zQ*-zrW;z*i{bs@G^J|U|Ck%>RzWMqk@4fpGy7k0i&iUyzzxcaIHV8q$^8@f(29t`>XvoFbaCcL@6WOq7c zwwUn`Uw^@EQ(}z97>#w7qvK=tk56!c;-CKbCw%hoF<(6Wf@-M2aMB<+trelZV;6w zO%krk8M{SJ90bH+$Rtk5iiEjd6X1!%fVHj|r3nERfyN0-qyg9QU0Hfxh{9Ofi`S&<1+nh>ju0I9j>rZGZ>YPPzkj{q|9)}7Ac1f^q!s~MD$EvdE4;wj z9$|Esxwt#*ewP=J-)-)<#d3F>ckkUcOx=InZ3h8k4PN$^q)r=*^L+E|w|%R3QT)b1 zS_a?YZ2^L9!}j+x8rvQJKRSrt4Iy?rAPEsr*A2JxIo|j3WSXXLakhTT_i%RulK3wy zRKJn^xI@X_U61dskF{ny?3nG4<`Gi#gNFZ33Awvg-g{J_z~2oT4yD4k!^K@+#@)~0 zE)R024D|z0&?`b(<2~QAvst>f121sa_uCL{LHoCxv1-#0$`Gu;n;y|zwG|#uB4f}! zU&={O*_9-5%5VR(-=!E9+mBlig0q`n(_DSVc=HO?o^dh%jQbA?K6>u~`#V#dZOCMW z7;5789<#{zSrtcAMTCkiA5CK3eEkj5ThiFD2{P2~5h{p5gmi(T+0+PaF~fu)&#=a$ z%Z@Bcu)?E-MT8)dgdmMDzQYC?%hu9_iYQRHNc9JD(R%}=RG3y$*A1=jFc_Sclx+`K zPyt(@LxAoKcHQ^B=rAD2N9fLicL*G-azhYC;5@6vf;MoB@`Ac)`>j*g2R>yI5*mm? ziFbx_QxXWZRqzC(BJFLRO^cTj;UOZxRvp2rW;z{XLy(O@yt<}ctiVZBo*|QtF!ro% zf0#>>fLQeT3gfmN2p(F~QFjeUL7F8LSwddKo#PCAWj6%w{+c_POoU&Ic0TC*DYDCmXvQ6Wa)@%-C>gy zcQm54EzW9c?~&_;Bk-DkGwSbuxXC(e0eH2$&pBY3meMw`^Wl=(7mB?tl=Qj)R>e zeF?;bG zCqM(8^OQ}8N(Myvgta#0afWc7vTMOP0_!Q8svk70!Ri_n2%;EH`NH2%>1)r;%Wd;nk~GY&Pq@fG^94k^}*m zwj+=MQUw^%I|H=V)J=`UGnq~qkH_SBPPyLDwJodVlAYZhCetxtq-eUDFbPpx+MV}M zH4Sy$V6-Jl5=P@OMP8r+#d@`*Z5qNrk;V~|(U53c^qQmzqtTc+i7~pP+*GVq8@!hY zq0rW`T$hxainFr|%FPBP1#uGLg+e6>qrDxDAH2`r{yts3AdMwj!@& zCw-BzkgV4mma7%>`JBaK!PWIuABc7iqb*h0aC^Jp`ew#rzM}0cwl`B?jHfJ1bZtN? z_8vT8JRb1#|M#z0&KKy`vR-azn||=yY&IAvdHv>sP1W$}=U;NWSkhXL@q*QS#bUlB zjbo~M!)iST;TaA`oSk1XNF2vI84pkHGrwIkU(V=!$#7h7@8n%xJUiufeoGhxq)CBw zmN@dRqY;-^Gd}(DIU>qfu1lP^ zs3^jD$?a^(Y&Ii`BxxLgX?gG7F`-h#Y0)Fio#WA?M_gT8;hmuE8YV@KXpZ@+Q1Ytl~HUvshj0UV$OOhyJSd6%to%8C|7d(0Iea>FLrqdhVfAT)B zUtg2NBOX86XMZ;*3_MONj_=C9e@G-%E_osjK=V}{vZJLhrn;B`8@aY#{^li=$9s!=0uU~L+J!4%r1d(Jg7|=Ei z=Qo%9!EgVVsS7xH=K=ri@BcA>`)~gpHy5ulou)H}qsfpgiD`7lpvVbv=%yr=AiYI+ zL0dPJbwk;Fo#u^ZPk<4;l;hZB%B;!elbuE={$VNGJ+xC*@ zmO`Pe+lISqiouXLj!`N=1Y#Qu_Dm*|Elo&}W_fRG3HuwDwwf%@NV6WXR}=+d6!nKv z)zgF;)01#I4c~ro#`>}$Qz3iD2W*xb!ploW%JGYfTW)sVWs?rsv6}sQ#lTAn`mj(E z35p_S7!;(DA`_lPJmP;neZ$$hWM?oU&IdHYW4D`+yHKduhLi8eMX*J%T8s5}`+D&< z`2ALm_d^aFPGendlf&k+T!nz*u zXdS}4-ag_SQ5-NFCU`G;OGgmljAN9?_^KhR3_H_;Y?wpqD8D*KuF4*05vRz3!zxR; zu8~#}N`+JrNl}pH1EQiJjAM#4>j(EhqJ+TtzT~lo9`q2HQ8BLNB?M^W==JtBUyzEGejKfigDgvam;5u~O(R6~wI);Ogz;=udj;Pm$ z^34+U;R9-`>7Kn}|A&uQ?CnwAdxAN72S41QIot5qGnx-$6Y& zqRj;t^ErtZ1Yf+Nd47$U43OiT)t9G4Dk3;880CsRr%|2e^v#-&-v52(H#08ZoUslZ ztrO6CCRt7)9TT_a@|QowtpuwspnGQrcQB!PdP6kY$4z(WI!zJ8c-QjY;SEoY1>gR< zWqA=YosLMt43VWY`xAmFp?z~sFqRDWM_3)=^@ih}oYi%UXah1IaFXp&p9)_6a>n)3 zhN~|Cx47^swd7#ffb%N-+ar{pZ$#1 z7y=n_wOHcA5L8SQh(KZ54h6JTjRhS2Qmrm4^1Pt+j^WOPT6=`_$WRi- zDJsg?)E&ktgmc_n&e%ITAsLTZE*69yyt9;B3e;dUCMq(5IL2zn)!7@2=@{fWNf=_f zj^$!OoTcm@?o$i~s373_@{;9zK`|&8jmQ1-T=Pvki`jy%sj13U-zGlH zx23mz4o>*(vMdb9vWzHHG*v}gRqPz@lMjdNPA3TOxw^PywOlYL3bHuEI8SSA-}SM* zeyuf7x7fN5sMl>nIxGkW8Bv}POW3T}v|US*qy$RggT%5&sWrS%lvl9 z&Gn4Bsu+#NjK?E(cc!R7_JekjG2NXo7>;`SlkfRcw1*;v{2dXP;-!Us87#F9U)oM5=&#RdR9h28-kJ;(|zpWO>4JwIB>* zQdbh`4T^xI7*gw&qkD(US2L_{s5UhrDbcpJ;Nu_v2$WAZ-=sJ zIXK#7HJ^dkEaoLq8sg}9^5I7;SDIolrK)OncP9h_s^uE3w>`aRCgYrsKm35E+)(5( zgW-s>ZkaFU{j$+o#={X>cVzj1P%7%O#5w2y8AZH0J*BQHUZ0+^T9gPB!{LywYuMc# z6Q>p-Esx)Qfb$JM_`wedRl>cKM_4SIs^ai)huhgL7{R*_KS7evYRSRjkem4%l2qZf zV|M|cH6@e5is-9Y5q@^mCC@HW)(6kMC5|N}KPIN@EKt1fb|QG|1jsw%PG5`>Dj(-eaO6++il#7Ts)hA@mtl9ak>5CWtK zsOuUKqB3xEr z6t7iGcJB#=@O&gS$6dpGy#A={Hhr7Bu?E4mi^O|`?1v2TJsZ=V@*t%ocpKJc+wX9P!o8bF`op)7 z5^eiU{i|26nT*Gb#-purAwl+j*ep#^K_9mKZeZbUzTqxA(bJVIN~!HN-xlHFshft) zW<#I?wCRxBz`1j-NA}(g5&uPh#@*NW&A|D0DoRr~+jexpdbRqVs`LG_!`^6gH^h9O zn)Q7p=jq$-PTrS-YOh-icQ;gINuYp+NP!NS?t4N&O+O?2qCe?VYlILuRXT1 zXl+=nmZU+7XeHhXI%il`3$iF9atYE0I4o9J+O{Q)Q=Eqf??2@J$M^fvKHm>*^Lot} zpZ%13djo#>!Mh+V=dVwB{P1`An@@ku7vKH^@i5_h?J%Pg=7iWl5GaQco=_|D;Ss07 z4%b&5vV-tyK{%`FHXVaeMm%dUGDL)uU~fp>_QRD60<;PMNftgi0cFy0-II!)&^N#1+R ztv3B;4uv(g&w7kjNXj?Xk_muFOqns(i=SZ=spZCETf%ol5}mdhUE zv8vf@N?L8O+F*>wbQY~Gy6b)DffQ&Qv6FpHpRIq6p*6Rk*Ii&FT-2rXWGQU~SJ-*N7AVuw_?2Qzw z)q=~{S8QIaxP5j`=ryfWEIxY3;wU5EP3WpMX)+*_A?q(*psSAL@dc%n{THmR3@=`u;<_8!S1&mz285e6QB#wThuq5)kCK|te*O0h^7~{b@31;3 zXa+ICH#3Bl)M<=b)KE9ZUE&UkqAfX!;b^kmA(xM1ovov%2( zdIoXFM&Gb|oDroNAOH9V96a(o`6Oa~eT9$}lf#xc@>Da))$^L?zdGaMMZ+ZA#auYGJ1gz`*82=zn7ScKA_jw;d{~gAG17T9izQe~(=-ewBcuqZ z%96HgLH0zkG)`DASKQprDXaQzrX$O9R2242>rIUl9u@yq`bX`NJ0`~THI5{~akRER} z-gf(Hn=tnH) z*BtI2^YL$e#Il?5;_96JodZ7j;77bVe}M{PrlTR}rXT9(TV#t7;fZf{z;78dh4_wJqG ztRNqbNm9vbeZyclAWH|tQL+X0XsXQ|({*TDasS?9KKk%IieX4+BuB?12ye-f30XSD z*^c|ipP;_}<^^rjGTPl^c6G(gY{jb=XADL|9=-FB)$I)*zyE;gAO0c#+tpv7gyUbl z`ySuSZ@FHTeEj%B2EuWeI4)*4BtBu1h76p?wl(?QVeh5iZk4^W=+2XbAswJ(K%Q@> zS?8#3X2|U!&r1kL8MbjK5i$rD=;!+62f?20T7K{!GsNt1{u44Btz zV%4MUuI6)gcP2!k>^2!jJ4FQMg}RnM+cmK{WaCH;-`Q4|1mDcsBBC*nQ}8b=U6%(4^rg$lGoQW{_fQ? zgokOGqmlucHB3#*P8<+ScL+CYK8XX)CI$7*l;L>D{ia4`6Rw`WBnf+N{QUL`Aq-K} zZ!5ePNZ|=WNt|SFTde!sgMYiF_f8;Xz}+9YE!{Jww-(i#ip63{({@yC+sm+V%)kG? z{sTYx$xry`qYqJGUyRpVlkD3=`S($}-?vcx2734HVZ0>_L#%V#qCkxYw9&+a_&Y+@ zwh-<6WUD)?k`UspUFjd&sJ?45*Saqrbk33I`P+f$ZN|d;-xxB!Z%6z7;Pjm(N|GeW zTT9s8d+fV21l<;gsyqEwz3HmCoL4Ke|QQ_!0_;xff1C_A~r2@ z7$cmZ(FPq!r0_UvFoC4OqP8S5C%3&TBEWb{9t1e;v9=|vmJ~_IQiN2c!=)*MKqAmo zx3>hXCLE@SO-XY58dXd3@e$XXmKwo+7%+}KL7uQ)ZLr>Btiub3)dswzX*?!?G>q6& z39F4pI&huGd(jUQNZNIc)L^Vb$-Z1MjB;+53$%#|5Okf`63!%Dsku!&T@;X~0Z0f4 z@YWKEfWU$B0xLj^-Y#dFik08cDFJ~basn%4PgN8B{WuVygy;vLAYd}i`N2m|xSFkb z`Q{BuMMP183KU@^Nb}_F?}V}TZO%wwF;?TG2V?NgP_=#eSdhfXpjYgiaKw`#RjCQO z4jBy)HlQ^DwFBEg;J`%Sbj>u+*{5KVr^xb}rfrDwoOWKaS~eJ!5M~)w?N}^Y@;E|! z&C$mPG?Awa5`rInKz*`LynfB^9xOP?G#Bk2pN}E={YS{phb+H+M%6CRO+)P>mR(62 zhWH@HI!B$vG*N|@lE^E%bbu4u=;#W@@3ycBp(EvUfm+ggvIilng*TcJQ%-& z)GIDGPl?2cI8QiV-@u!cBYT3lcb`kSLR^-J%3=mB^}!Bu_aV=}JmtYCWVcX!^xi$L z7BhbTgJVXAJDknmaN6B6P9i3|dsLlZwraVqT5i{KuD*H7AN=tlpZw{49{u=;YVA2Z za)eIt)BpW~r+=%sxX}2KL}ec1T6V`1Sa+p$984lk-gyUsV6|9q zdUlR8mYw}QhSLdNYpPXmYZ{J+jHY9(F|6lvRxe&-@a*5e$7FAU1dR3Q#vrYvm`rHv z5?@saDd^ho6z}QoPOns_8CO>~besOnG2P$ANlAzAyKRELDLxECx~^Betu_ci1p$NI zF-ejT$pGm*&ALQt%XlLOl^WvN5gvlOWZAfLusESCloU*LY zWrt}caTGEb2a0qq@L3T~GR zX1BN8T;DJp4oRYjrfRvmTJ#P8sYql%EF@LA;b%Yp6+1;ix2hpcu}bjl_;`q@C@4SDHaM9Nhyu5nB#?D#2s<^GLdGC{l>`W)jnvzey`df}B zL-H`^mp}gntEJ)LI}gZ)F;Ny!H-^(!=iEEKM?}PKrWlV04AX%3-?`6MX~^@_FPUAO z?{##+zh@R&GUQDOi9AOJ~3K~!av8^{Gaoo35n+_Fun%0oz2~pUfB1wg&6c*Dq zWLeJ5q9Rc#d($aZ+ix&BuX~?f6rzHVRhD}xXynf@}TFLH$;BDK{Y14N+Y!R$NN}AS? zL?OTY<*yM^@`H~*LMnlE8s+6%{`mL9*>?@$-|zFd!^VD>o3I2*p;SncB&^nJj5Q34 z;kM(%BgEDgC4+4v`FD1y@2e0($bU5Cd>=gR>uG9H7~{0Z8^Cyc=W*K8nGV}%Vv*x@ zFV1w{ur4=bNkQOMZ$tAQCp=BpBOLL9z)5CjH#qGP+km^oF^LN{b-{o7%Cb=n+0Kv^ z2RJ4ie)K!Y^@2Pa@&5fOFO0-{K@#Q&=V?kyOTg8OSBzhjsEHzcc#KRV3h9VriJz?z z(x7#TEY| zr@dH`ANKbH5yT{e5TpWaAXT^!q%#cjn4LjJqZM7#KoTL9W4bp)s{ySNcr-GEQ86H> zB8o{uy_r)?ha{av>2v<*WXYdASX0CaKYe-5X%jL2;DGjUA9pn2;^|l9(vf&invV%^ zY+K%xs;q3qT zIXn9av1-_z4;iV1va49XJYzg_EQbxWykj-ZI6HjABY&Taob`Oo`fASc zy(v>U#g!X2%>uPouyTeH&2m|@vwK7o572(i#~%*)AOF=y5ZsU^8;pr4h7u_)KlyKd z$WQZQ6Ck{|(M z%S5hszvmpkxB$CaU?4~UiHszWdG7h2=Xrh)+5Q3PWX9&r8$2fvogt>r0j+OuQ9(>J z^r)ML!FWXI2VB(^;b1_1onyM1?WVwb3f+46(*f4BNT(30#L0?mG^SnMaQ@~c2ktpu znsRvZke~egR}827J=#-g!YE{v&faw%U0z;cP0MsTWi%YpIm>Fj2B`?+n5WMt2xD2V zSDb$JB^G$_-~kT~ju8T?s$^Fcs6obq!+lKMP;a(K&!cD?v<`^0COLY5RuX3iEN>Sq zZ&x^L2%?B+kWpLHtIwTdI2a?wz4F(T75RLJkb=QvL@*qX3e^uWO+%R%JxMJHXxola zoFQ#*k&;Rh4^lc~xZEu%E(*$`L;zWu62+RfX$YeTLjH!sep ziXG!&#&kMnG)$P^T(i8n!c!h;ni6P5-C!blcPR&c<1An_wDQLh^wnhloX7IDM1#}ILqtJ8Mf{)fYh4(**>Cc zS+#3slQB(Ivp?G-jbiqO1J2IRKnh--E;&4WNSekZ$&lBtUZPvW(R9k(b}VhpqoZTa z&foI!cb}u^|9xM=*lEts zt{9F7XeDS{P1hv^k>vH|TgtNJ{U?u@91N(7F`X$XZW>(T^W@Pd)Xf}J&DC5FNXLA=VW<=G%N4;m;q}|sByq%}!y^zKS(=3PDbG5?L4(WURYPDoI-6yn$P-|*ui98=^4ZZ+jI>RVd1 z7$t;Zgp>-;_vnlzFRFK&U1Kc>fw7j&c7wD1zt@`$p63$;Ayrx7c>%^k-C3Mf#L+h_R1yv|OiGy+B7X`(iuTs3ss zM?Tu4@g<_Du_GU=JgTB#qI|j+mkb^ZiJs4(vlO?t$fPGAmb*D|GQdwVx~5}!Jx7NF zY75#~+D%SdSjY{Xa4fopRu~4GE1EZd&%gdeGfCmiYsF80{Dz}(#xT8Nxw_y=#^~oy zF^Qye4cZ?dn~FgqSglsQ`n)%0sV#*9qZD=IA(TUekWHryKY31^D5lS9HGUJ|y7uymA*ElH>u9L1=y&vvn){`v~Js|d>+LB}$Ztgg-&h#F6O zJbm;Ct2-vMDUGR!Mw$=af5v2#QP*3pujXuTx6DREKKby7fA?ok$i}x=l_PXV68i`Y zi)+b$`1cpQzUWXxSc{H$JmTnR#AFH|fA&3ujClV1Bb?~1b;9-Q8m~t>S6yFluu_RO;Kaojx0-vlL%Yaw9c{3cSKRhY=4i@WK3Qb%&%`)Uf-~{zekd#NG++G zie0|L4}6Y~kC{%U?D8#5+fbDyT4|=U8CjYV`aawhq1JWX6B1RQ_p(jR`gX}?y(Jls z@x~*9Bxb!{vstdVy_ggEA!(K&L!S;ySyvd_G0ZaVmQafAu2)rdIl>7><1s-PUW0;JOHtQ!O-B^=dC#h-VUEpiQ{Q8O?{@@R2tBSfTpx*M}a7LOXq{9J^pFHKe-}`-x6^N#Rx@0g& zxY*soAYxT+d2n(_tsA^SLbkU@Wei_@^##k-97jhyiYc3hT~V`M<mGTSeF&Yk50H*Ug8gjG&;dcGwQbF z>Ep*#b%7TKZ1b8VoFHvaXB|W#o>Ek8%k64K7=}bqjFuW5XzI3N?_kRD$wTV4=HmPf zv9I~)qwn$X_z_7GQ&uIL%^K6T#8HTI6+xhT3%T@&;t{8(mz=-7;q%Y`5g`<_@dK9g z9aY(KdwbQ#CekB@gP31`^(BqWi8G(b?@-Fp7|C{R`0A_A34;m82j8J<97%G77S3XX zVzbLR9Lx}TjYwcJ8WYDcKmGYX^8FuvMwlcNS1bPT>4&8AH#Aj;xxT{x!6(d{nBwgk zjbhQ{JQxg+(nq=e#Io`w`@T=yv<%XeEcB>XORO_YMq{jl&RR_85Lt#!!hYg)uqaAO z&yd@i`0j*xON+16yUd5D1WE_gCPxP$p47Crn|?EATRbm7S&MNkT7wXdAW+nGNfyR< zLiHz+en4LBFrvW;clQoK;E~E+#t%G?Ac^~C%&Gz{=&S)Lu%egAJ8PMY#t2VS)ique z_Fnn2!4E=&(yUe+ywJxAM_KRC+Cznk&RNo=UvzHo0#6D-6#6vA5hWgx4*AMIB_6~G zt$FzP5sSq&Z(e*s{`HqU^A!^zP#8if33b5j@|tY3;zg%;6lpT2@jCD@bgp5wS+jom z8}?@hoIE(;>#x5i3?tgSCUQPjG!#`!U95V-LDkZBEy`2xHofkybfRLHC<=# zxU+qCh`l=jd$+0zhfsn5VL_h0FbFw1I=;&i7}6|bwOZnP9$$a`HP#yb_>cYt@g1h_ z+ZLv8s{r?wqx%8lUKO~v8?|>9sebV2L!`Yza%aO55@*c2LE~OUxF=xsJsSP}S;V{h z{in*w{pY{kmGRpa^*%^1rR)R2h|~{w-b@?*5-mgOCc-*>@S0rs>I3 zQ4mq(HPR?t4W>3=9A#NxYD?%su!`FB4fIXjkOnED6&T|X^xXNXtWZiL={@=i&E{rB zxhaUJ$z3wvq0#7gpH(u)28z9Lz@w&QmIiziCFsd9&930~^-H$5ig0jD8w+IUqX^j6 z7VmgO@`FPTMgeu!kbU-m?ZuZ=)?@bzizqu>=wl4H#TFT8!u^cOgVuGlu3=EsxZnJY zE{gCUA28A$Nu$UHL*8^1sWvwIhbJ9nTcDMPX zN~99~1+p!%TB8!5Lbh1ZU^O`3P%BWOddK*8raz4|QqjqdI+3_2MH+z;Ae=+BEm(&z zuBTPB248BVvAF9UqP5tLKL6473I|vce@J_|!n6s4j~`L33S$m0`)DH(P-DFqE%1Ov3Euz_WU(v*MO&ISmk;w`d-ZbbWCz~gP%8ye8thhLl)X0PsRvo zIIJA`D5X{<1Le`(Y-!%E86F-`h?c-ryt#ZqC0o|pHI-?>>kqF2m2q-7<@uARY}O8k z;n@cPPoAtOyQVLl_50`6?bVq7{eL^B(|~j^WK|WUgN)H^k9xJn*AmlKNZ$t~ z0EsgWI!CeIVUiH*Ia*UuR{>eF$HmPB``HMmHM9LgilU&XDmG1pY7DdEBa$S-I>&Oo z2I26ckmKXD=!Fa-KZyzl+#ja$x*%0^<;c(nrc&m!V^)*sJ6ekR`gdpx8XVArz z>kaj0ODzS~IimfLx~}Mq;dZq|O3CQxu)j8S9YtC98ARtuk_46ZWr|T0Vok?xyTSK8 zl#(P-z#xh7l<4y$RSm-HySY3;6osre8$jT*qcx5=R*~Hw&(><`hNE z_4NW@^*^_CoH1W4*bh={XYUAHlJ}oJWS!@Pqm1***93XR%hzui#wkKdE-r7FFV`fafWcnG za5!cZ4Tz2$zxw%C1S&5C(wFfzRn42XZ)la` z>UM#rg1*FgGU8AE&Hun({-^(!)3XbPqal<119ar!2k_O`zhp4XsGBVZ`xC0NX17`6 zMxLdlo|6p%l&dHfXRPN1#=wggOKui0j!)2D z&1B#5i?6<6GMw=1FJ80RS6H{=_;H2$=imSA&y5o-w*_ez;cX2?s7Qt>Ro(jn&u=gB zb;ze5e9YkN3a?t>3yIv7bmfk2xneh8vNJUsO7@bBU%x%)o1$PgIzTJS@a_cPSVLRn z*rui}OO%wPS%%VzvMBo^F4GW)Ao*3f< zVG{OXECh||XuB5eYX-v%&(|PakEiuLtTV)MgfWKoW{0>7Qm)o(yr2)fgT(Vaf-oe{ zbDBGF3wo57QFxbL;TCPjLC7b zp(`NP100UWdo!j{NGJuy30$bT*=_j3YW|@Os5~FrbqoeWzWnAJS}SN8ixirw+Ob(L zsLO(;Zt1C03JYk@$GZM+V;y->Fc=QW%L<`;>}tO;?i=XuL(xv~?zCPA$9lcu>gt-+ zaz$R`IM){%X{}kW*IZv+^W@2U@6dhDxp$lX`vCgAB5=R)zrW2p%&oOO!nE#(qpGS1 zgQySR3-PWfP)d1U%<*oM|4-Eu?oho#^ljc%RrR@(viw#so!?a{+`T9w-l-V(L@M3| z%zyj#?f#6mZN62O*bg(kO{zx=cb&oB1?ux%P8bAO1E%ha?@Zm%RPCLuZQBnSorg36 z;|#aOir90Wsdv zsz+%CcPf+=me7+_n-bv%y?w4K$0<}xY^#Y*%p8Ubq5G&9nw=Y9vBJQ z(+E!?BOmE|Sm`iWI$^OItP%{Q;#enKxSA{7(kelt46U|wp2B(xs|76%>1$eRsM`jw zwFn38odRlYZ(mcwaWI?UZGqM&c<-byGYmm!328#(6zy(@?HaI>HVdhwLH*{MNf2Yk z85IuYJ2uOb(n)+jq$x_!5mri6*RZ*`!Q~aYZg62p?JK%nfo&YtAF(V0LhX}puen;c z;HEq~ddTJF6?2=?9vu@X#c+PkQM^KXmL(}gVbQI_WW>?XzU@>p7#$)UcxfYi8z-Op)f}P{jKX}3q|L}XP@`@L)F4$Zwcn}OZR6b3j zV35(}6@ee%-R$VPnuiakM1znZ8L?e0nI0SxWg~nIS2vfe7CT%iiG|=h&raB%c^G+0 z!y4lx!gX}(nE&{{l>G9)M9k9X*sbQ1XCF|uH=KOn7>siq5tnu!=TG>fPk)FK68CN$ zGu)hh!$16&zXs7EXs}Iq1Cl|C)C!CxUvIcPJ7=|CBcl)bAr1S!4o@k3sp#sOmPnyOAzGAyt(p0@l zb9FtZvx*>$c=FyOvMgaboeFnsE0Scu+3PcKy*+I>98#1!;y7Yk zY}b$_yIu@@#N`y>^2+P zre?ERffq2?o8YGri{+B#V#Q{=BTX~jfAXB|YRBew-2-y`kcaO*WwR^!-giIc`1k|f zzFn|e=Zpsj{Oa>B8K#>5>EC?94?df5w6AbPynb`e!-xCi-InLydBz`ncgCj=Q$Bfk zXIb)NDkQsY&i>?x<$O!qw8W9m>o>1?`1mpF&78xdDeK#uufI5Fn9ca~(@#0vpYhep zZzxPlG#pZz4xxI7%(kkyU9LGlzrgnshT|z^-Ew((!4H1$0Z*SEQdBF((*eHcF~6GA zlr6@etAg}rj$iV)wDPf@cPvSb-rab^${Xw zG@h_2ZaKf0b8zsG)%KF-?>|B+$>q&Uj*cIr{>2aen?J8x$MtfnMtXs%g;L#{yF6eo<{2R;wja3evPkc^*D^fD=Atz2)NKEvA;- zT%D8eR=hra!3e`~6r$RiaR>XJ&v6=Yq$EBKzJlPvgxXWw7|DNJZuvZKxmhmR-`{7O zm)x$lbWXf$J#DKMrfvEm;f|W5J%u$bopHo*N?q4D9Dd-_S%XvpsrpU6xbw^QNBR9` zyANO6yY7lUbgZ@Ro3o|l@Nl2eAjKMk6oR}gdGq>|laq%;QHXQq-2kD~J7f5r;?ce< z&y!Ma*!G+N03ZNKL_t&_g}PguExSCYEDLt|7EgP9w~Lg0vE7{_aBs8vmOJWqhKzRv zDIqcUjo{xJEbfPZ`(fwXNZk8B@{T|y-wi>g|GC)S#}0Q^DR*zn>I2#L_}=>(z`l^s z&~>IKEY(eqqrD?xiB=+7MO*bvs$JPa1A&bIN!vBlZHW~S2p?heyRHu>EOlFh08e@J zMe719z(~jJ@r1lSO7+vPLZj0%*qyfk-M_kY_s{MW`fVvBj)*1V>Y}Py|L$FV?uSMYWbz zz~18_jcd4`-(aoR51_S$#$X$Rtvmcq;5QaoHn_Y()*W7LkhMX#4%In)D>%es=m%Vs z8#c!D);ZCat7*~qdl+LdZA)h?U3Uj0s4UzO(3IAgu0y$wG*mo)`he~03gHh39zVbj ze5zRBq@o+d{p+!;F}@@k#Keh@l#ck-l2m&XM+r8Sn7U=NC6&>4hOLRCzHin>SFfDk)A(h?YCj(rtPY|Tk*Ox5TH*AtUy74h?yP^8!SL~Zh zo;*EfB?jb0#dMG|4Lq_m#)TeAfk#Uax9kl=lr+#8szTuA72Va6+uJRk49UA3Z{FVVM`KU%y_TC-SG@f7DKB5V!tM&n%O&mAlKI6YtGZzP2hVAfg!wmb@vfGn%IDzW zkg6&9^pk(a$M1iDk|}R)wgf_8x)znE4B~+CFu{`&>neh=Lxef*uC0A@J>kXQWW4(6 zobtRPYy%EY#!Mauv|`Em>m~Dr;Wk%9*^EE_?mr{&g1a@WKV+ziEr0zV{!c``CEwN< zD{!W}yS{6RrXicoFbFQMt~oe3zzclN-<%?aBhZr7az$D8y)o%%fb#=%JRnNPk;JT-hcmnZf>r5cyi2kyWyixzQggu z2YmOF?-2POb!$lXPM8c6BH5CqF`lOw3{pP&&UZLCK0${eo85->X2W*7rEW_0_b0sn z!4n=F?eX;e5Bc(&7hK*f*grVN+MXN;FrH12cwD``?G^bzGQYj0F)d&I<^{fW#IEGg z{um_!ZdW;jVaB6FpCl~Ut>MQ%{)TLL1SlTt#q8EsEVox|t{05;nxlP>mzNiuUT)du z4L4Ug+jT`%wJf(eI|HX@r<^<)Gd^|@8kTE^^b)GB<>ODD&~%1X(V)VB&h*5nAPfoO zgt}ak!~;+Po7*LIQBqVTr>Ezfzr7|&Ge*NP%iASoUQw1Md&hh1?`MpLqy8Eac-+jd z*;R9n9*sFYJtqt@jOpl1Pj$S!xMf>5Twh$^>V}V=J)y}Bw~HmGXJ>Rq(>4}gOPpyL zrV;bY1t-U!pq*6Ewv@{){;^Nt4130BSQ$Qh@0gP$Bw20wCR}mg2?A3SIElhT#e!NI z!T?$iCQ*iIEV-&k(}WZ0ql86R@Rf&_z2xqk!MXclw~obPPB<8_-mOtpNn;FMl;Tv6 zN7YiXF1OTvf_08~Fk<%jA^-Saf6AU8ka>bA(4>QmrfG6%cqa*0n@B zqP2al!uJ(UShN-xVQK0RY+lw&h;Ka0iLH= zuUC{!gT4!2HEm0hC4ghM+w`OCnE<>$7t@E0L-n^x8T{wk2WUfioEAm`+Db$0Kg8uen|CD9hsRRHZ{GL0y!L zMngcn8wRB8L(BIzBBcdFc)xS;qaVexNeMeaX$|JI*!-*y&QB$O~3-g&;AzNIbB4ga7@9Jo=+Q<@)xNx35llbn=wtufIVrLv~k&(pSXKkI;ux+81AtUA^GR zSff43KYVe4*aftDKp`x8G^NTiyfh;4eY{8!`kGXRm{48x*CfhkP53LNfeUfD9Z+GJCyJdTKD;cIH2$aY8+84 zBZxxcyrOd!rCO?LjT9}@S;~B2F`elH-nIt;h{_@=uv&oX*F5Dl2&J%6VX#;!=x_wn z8A0M9ZY%t{q>&mSK-2ZlW9tyc;3JS$AdJH{EwTezi@Z}9g$3yZlWf3V9I_50S}#WA z1?%-1v3Ei(=+}I}a{?zNb-5$%ETd_PlN~f2b=}~RAg!jXDiUkaGV1dnZ9||ug!b^F z2<=-^=dh+ANHnGb-!qIxDdUp~RtDVcB;{d%E|#?IlHqX7DvZf3c%fqloV}jopIj3? zc-UtRF^p10rwnbNXoy&E8logbq1hD$N_ZF~!SFpQdq&soAj?q3v9Sg3O$HdY=vXj5 zQ2gHT1M02gi4yFO_xQ{I=O=vgi%Vp-M|?8DJWNO)j7dgQvTv@)iiWt0c=p}*FioF< z`s(F|vrWr~fA|>tP0rr*h%hpEPNR*-?e&gdUY+vYA39`LQ&kgw^rNr&=b!%1eEzqm zXa^6T2nHu`n(sJ&v&Pl~2I(OWXOB4h@|U#b3Zmpro&}s_dUQ;Z1!yOsQ&{N{`97<~ z4e7xFwrOdKf=*~6Kj6iySIqWi7*FFojgYR#+13qCD3;4L{w%~4HL5HSK~F!@o=-NG z)a91te8J%GkRb6{zd2_(o8Tfvnq+jQV>B63ZMGDE@k zhg9oZHp^RDXBm#i2y1c1GGEWhtCH4q3=R))O~>M9j$LjLwm%R}heME0R(K?Hf z&@?rnACo0vPwY%%y0*cXhDT2y_s$0)Sk4z{rKr~1UcEOR*Eb8gPGGFYDIe1stT9|I z)@Y?LU4sC2+YQs{gypuNHgI!w%^*p6^ZE@3`}?exOM)<_+^*R>+~?x;YaX9GCrC4@ zsNGLgXtQQEMYQ9nT*GTVZds=p=}LGRFiL4eMT-x@w8+xOeyOfMOCuP zmwfR4Q`*k4+2(Wx#*-2a}m$^Oxh>&r_{9v%`0V|LpJOwI9wN9;BQ&{Ezm5yodd*IX?YI6uT!35k~yYaiA5 zoPTpmerfsO2+ z;&9ebJ3|q_Y^?GE8F{*PtY%kxw?-XOqvlxnA@5rC4uhWs5M5wyLob zWT07XmUPB2oKBIxPt~@JCPSLeu-+9!L4fjo^19|Ol}u+^yuf3BG(~HlU0I?$NnMwe zRZWs*jD`c0(iBBa82MaZpM#2!+7iVc+x&{At!W#}e7WJ5g8(ravHao(ik(w@gT&~Nw#oU`uYZLXCLBIE=IZL2w&^iw(pvJez!L&r3x-*S zQi{oB%&zLEbA+O*8nPfH%Z7BFLrVM3`g4Dxf4`}|w-eoymF_KL*Ecs9({Xv#hl3}h z5!1<-^?HLbk|MA8i~r*<__zP#zvblQh_34gmbPuN)=^azzVE*)!|ONX286rg`1d%` zeg^2(g?Ea>-N5rMXQB1GVc_1zbpP?U%lqyJrTf9+omK1Ze(rw;_aX3iE#G$=HG6L> zZ0{PtokLhlUAMpe-us-#?*z~Lp~_f`HICgjC-6dS*Hfl!>u}9oZ$@V+Hzk4eajl{4 zECxqemiWp?p}~rGA$EkNZCkX|{mG^4RUhdbLJK5t{`!n}4TlJDfDcpK+()53?3cu)!)59ymWYk_(4D?Em!dj zZ!pHD1J-X#Zk`;l-j&p4L7PrUj~<~S#kJ6Mae&v=Oh*~(a)FmAk}x2ijtJ|Ht6~k6 zK`9MdaU3F^8-6&u2#1`Jvyc*@dv6;5<`DxfG^oS-j`G%bT4 zgXz^qO>bXBN-Vu%W$%V*FA)Ttrn}f;w|S41rYE#1A&^S-8!LKsgU--39oB(x792?9 z`o}MOfW`4-k1x7ws&+&DMUDz%P#QH&X{|-+9+==ujp-~^QIiZJ;z(lJnn5(AlMzLo z6K4_GC}p!P5lUn3UMrbmYngH#eB=&ZbtlU28)VFC1gMN9_vv<^;e(c zziiRQW21ep&ja+hV=|p1e8u1Y_!q3K$9S-!&RLNXl=$)qASmYeGfX5)RF@NswQ z>|{D48)oF|H>83_ z7cfYMTx@ob?r^r_;>$~t(S+6t{4C+->WcB+9!@*FLEI0>dBc3QCK+ao?i%cs>vIVg zZ{MP&W-uO-j0XMn$XIr}oP3)ThA~gxe@?#Ja(lf%h(61w!i3Ru58(`v?-To)sxDc~ zZ}2^d?JTqX3BvdLp(HQRPB1w>LTN#lR}`xaFMsg`c~x@!-edG2McRJ(biN{pQltUx zd$dhKomXUj-$cIJtcjC|2Tz}nq!E$w@hmJZuTe@84-p3i(RBQvWqD~B4odTz2wku=327}SLw zl&|~(zV;*V34HAbP=p=fu;nSj5=qOVL`&)x*+W%#S7lXYRSrO6KJ%XUTFV#fAiJ6; z0s&+MfCSFj*y}%h-|y4Ps}2mbUB@QR3A94TAz>8pkhARwRch zfBO5sMYZyo6W5nZ)~g0u$(LVzMXFLB9KXx`hYwhV{>oq+XXic>GOtkry<|AVSCb@{Gi^2;1`f;*66*FpV?z zdLzu2XV_#;7KJoTL8=4J7At=A>N(#!zRz?JqN55Wpv)z)Qp7^>^yZQ*OSc&a9Z4LM zZ*pYUkcOJpc^QgQnk-FNt#ecmg0MK}h-X$jK|9cb1?j?@8Z68R!R zCq!vX)3z)YGoQk(6iNwprek{j0d><*6f1hY0ifvjBFf6~~b@3UIxIP0ZC|L6byfAD92_NTo2?qfPyq||Rp-md+%iCO?o zh%Md6BDJDv8^S2urm*{;XWM1?=0Wls&BfOnrLPD0-8K`qO~BW^AzyDgZoMS8UuT@% zYHGa+-Qs*I`Sx>eP2j(7Ec}Y$)}LXFp)(yyDnB7_JL;xEBBAqH46bvyPSQ3VrfzA9 z4%Z0prD+|F?PzRE)3o%{0m5u6v#l)4I^Sr7QH&7EBS!%zr2jkv=cgCg%6e_R1B7Lu zL-wMK7qdAy#jKOuncgM6_lVDP#U?Xgd{VCxEw(GUS``ciJ1mwt{b5EB2%>W@&49SNht^!Hm9Gx|!Nkk9F?sUu|pVNyaLiw#g zlnrpHqBxs@wV))ff=WAv!x2#+m`+p5qQhCA0PeDorgliz(C<0!42B45mM<>}%no4` zcv~+KxLYL}#F>Sk5*C zLh$(A_sKhp(=9>=n7Sm;pmczXA_l{R;Km@M5RqlnS`tn&;#AYxj>ahRx}q1w3@2l< zZi36_w6-8l1;x@JMZm$)lv!P}T5m|>J|Yp!$~FDTfG$$hZB8I-lT9ZJ(NJlNyn%P$xt z3E60f>?}$;f3|dj!@UDG&LX9kZFa5mStbH@r&Cr}S4`i!%j95(ufBN3C`x$m$wOok zQoD|JOF2x^gm-qHV4b5{Z>Z)=B!bRavcZsSINWX)J7gFz9uH9nf4xh^AW;N5!gPkb z*bsyv_a8q7e1Z4stCy7Pk|gUf-P_0M03)F+a%S@dZBa2k*k|Mn^ZATuwIS(c6kP`n zrU!e3X$sCE+m`wDHJ^R*lqillzH^6c(8D=cFE(7|1?46uOA^u~;riq?P1~WZV7c|S zMrp$J)^|dh;tIez>c&fu>Y`*g=uy`NaTHM5hVOsxn+WIF-`i!iT+&MeLNR1C=<|(t zA9@G`j;5~t(AKojN#dhDKKbQS?%vJFS8EotO9sP`NQLy0kWfdobwk-0(l}!0$s+=# zw-if*?F?m6P~;U|RWj5O)17@RPqC&W){@n1h7JSDrURiE4F+Ukh;17%n&0}tZ}aN( zD_*>KMlXwa@BMcX0{Xo^N#bj#r%%7cb~Qiv{&(nQ{{@@Xiog4h{}2Dy+262Pt+_4> zzWLq}-~HeYi;F8HmfAU9p3dlO%Hw+W{XAQ%s&u@L} zJ}+ONW2+T`3P_WVoneGAP%Rf6j3!iFO)rsz+53EXdO~}1#>0`NA8rugE+>~IC&ep< zy_Df7BI^zK^jBZ<@a-pPRd9B3PAzKw$sc{d&wu)qakNK2s~IE-t}Q7xH|$KG@aO;R zzhZZM$m`eVG^QesGah}gLsRFRoW3HC`=m)mG##+nRQ#)d^|zR=qnE~L9TG(e`grdE zoa4RmJ}>_6CyZpD#q1JiEHgEv9S(TCSn};8VuHfv8!ESEV@lSM<}w-Zcc(XeTO>H2 zA51ctAgh8*Yx;3a-P9CKovVWpL#a;D6YDtYg&{F5L(fi zjwlScsOFT)7nw!dAUYV0clqksFL>+zJ^DIes8g2I7}Fr>Jc3mCZABO>1U^X0+7@HG z?KHW?bp{=R+?J|MQxIWrswL8b{k<{9)}BYL9m}$2*zXf(8O^pJGp*%%eZ!_GhlqUajbyqn~AjaY9*FXcbTvIeAgw1U?O0YhOevuNAH9nk>x_0`h!=k`8Gl zFFwCw{$fMu0<3W;1y(CW2Q~?4dkMcNF8R*gA+B{an}(=Wyt!>us1oxh>q%FP67`=a_cX$5qStJjz8JwALx5sNLn zJ)H8RlV{{*MIJhCLdV>~l?<>-)8!38pon`3UDZ*w4fVRCu0o2kB#Bz~c2h8trc2m3 zkEo3FI7^OJv5w{Cx*t>g=uxnUFlBF|nkPs~b;x3>WrZh)G z>dHY6cx%kEioh9C8PiS%)JSTfaYB%G72SMIHXgBfeMKu<7F|a=8v9L*RtRTNaZEGc z5F`OoNV?7u#EL*Tv;!STKRs+~qDZ2RBMK#>orJx9M973Rcg)Ua#KV{c0p1V*03ZNK zL_t*aV27se{55SYSs3E9MnnoDK?KrEos{=ADWS1WP;44rEV%ZjIT+Qy_==E*#h z2v?8Unfw4T?z6!`QKGFRl0z~bA!G~H4CiVJ1WH5*t#%Hu$4spe7KBwAk=msfmI$^COKfY{e#=E=>LOK+I z1*G*&s+8P&@Q7zW{u?^eqO~RnAq^r{%QfZ7Pyk(&(v>ALim2O~-Gd$K{T)nMFxVYK zQB!T!td=X{{vOI%;vizPJqK$CQYds1fK)6NKDFD%0goO(BEP!f`uZB9AR7;e!iZj! z`pva<66J$5D|Z^#9@ z*0Pw*8H^_E?!^>E#o75eopmUo$jgE#OG$Uf9&c_edr8J-cEj@WiXe%Y9v;xO6~)bl zx@(!umWa-Bbnh<0!R-2mmoHy=GGS{-`xzqA7}GJE&q#F0_01f0s~B*OZetjY$285B z5SauV?u^Oen7zpaiDh5 zu^Nv8-mWSx&##z_59#+uB(b31OOSM!uJzEHa7YjYZvuN)tA&@0Z~cc!5~HNRXFNB| zZmyWdQzoM!v$IQ3g5h*R*6*XV#^N};yu@{e#bSoig2{NubUH#RK^O)^fyUvy9BiC1 z8TAPi9PLe!yNA5{_-+35pZ+;N{!c&VtIt10b_?dSIZ4z<3dQHoPWk(ve@cI_$HTYZ zAx$#|p+#H6?DB@FUy#=!pUAAFB@9^U2o z^Dj7<_E@hAR2uN~)8{l5yf}NwlSc=*~<-klaTA{1utK|Vzpdzb9G5S z9T7!>s;hYQ@|@K&quf;7%okj5>-a$&aWP+THJhQ2cJEMJUvu{C6M7bucJzBa-pl&@ zxGiXt6sI*&RpPpevMLd_rpZ8w9>>Rzc)nioFTebZfBv0s;Vy2_aY$!Y5L#s0lBj?* zOKEH8Cvy&*@kEkaD$wlan$0GsKbo*uu2DK53}cM(lZ;`%$0x<7y#M}(7$FFxLKu)b zVR~@PqN$i>8A>UxR|{Map|vE^Y8!uGeRz}tgk#W4U~5DcIBzC)ov*cwA&C=undemd z!(4JRUlGTB7S)C@P$=bS>XODU9Ggu+xW&abT}!^n>GuZ=20f1U?va!mL|2og174lJ z#5hOnLds3Ypg-i~?1sC$2aK`-MdP^MEcy84IYtS3S>NAOwV>@d8$alF&i^!8Xr6!h zoc+fKTmObn=)OOipw~0v@eV2tAyjlgxhiOzf_|LhV#iuooQmiwpUEzzzc-}WkhZl{ zb&IhPy|7269aXzRgbt0smJM+v=?4MDrtn)BV`$onY}!MO2Xt+Pv6ik=MDOg=h?-%i zX@-hbB%x7AQ=`Hdx`Iw9P8K;b3dx-E6My9pL4a9S%x6nmB|_PW2|jBzgRF>JIbm;IxknV)>1VM z7KiK%wy0>oC%EB8;>$X8?@2ycv zAXP__X~IkcEz;Elu4A)kiKEz)`Uug(gfP&kWr2z_TmaTdL@2Hq4zN1Js!5R$XH{MtP8&tjTDT=eQ+(!vY}b6X!;Qsree^KX!AAK>ws<* zV2?+XVMu5TiY{li%DHS4n#wV*4XIXKmzJgztUHVB1aT0PWg2M}rm_TKOdW(&&Qc1& zg@8^$%=W0^DN4_5N<>@)IEJAEbs?+D#yde%l^6H9b zU;Tt1{Py>-?wsi0oVd~qc5~XR94l&)eufoLTg~gbL`Er}ZdSC;5(qy$5r7o|cke&J zSV^E1oi)UfqH30;Sw^v_=_M&^({b_gB|`!Ioe4MB*Nk^}SiC+V>W{Iiz;>3VYS^si z^pY5zrHpz#!v2uURf&!>f+R%s1k;@{byG2!j97O$OKVB`J|M`V6|8> z8jtA&tUBWdkJho7FX@^V87Pu0#dJRKwXPZhr3ptP#>dAjZf19lJ`mEPW?%X{jO_Mh;7)*;XmN?QR z(GVdNb=^`FGmNneM?LP{IpnSX`oE-D{}Dg^@sBw@`-HM-Sj^U(zs~6=`#ie;kVg*= z2(@FioKe)5z>>u$4d*XArs)p5^CN0mP_8SI-aS6Q9`n)bHQ)W_6P#Eguq@{b9^SuC zlUEG-A=BNI#l^39aA$|AShBmn&-0hhc>X0kd2pB7SXvf*^zn~~)s)S8O;zO_?2cJ? zCDXBGG@9_ozw?Cg=!}Q=5-J^%4pT0!&KRV9rn`N{<1s(~=wpuW?GgoEP8s(S=2zGB z(jL9TjM@B#$4}no?DZw%=^jEzKKbNF>`eD~{OBGpUp?jEXv+Ed3>Ec3LZm|W_jdX8 z=2yJ`%}3lU7Tmdem%6OTS1YQnM%~}J^Os+~K4D!I1jf=+F-_UgAC9@K)`)>-C%1e{ z3RHeWQ&l(&wa_eE#X^S+CVQwj;up`qVmLWqnhlYr^!T=( zKx;`=`2(t|8-~LXVH~r`3omOC0_8lbdtR2@-#?}n23;HI9Kr}1*C0$zCLDo+vzrSB zy&l3jL@0}0I2OcAtqzR}1B^_zva~6bzruBz?-F4KiA+I+W zYiODl9cZkugi%18#I&ZNEOUY__ErZ9p)^U7kmm*0^Ba;RA?x>u;usJFI-u>mW;%*| zSf6P-f*>SLQ-UbOI>+vGhhCOa*B!-5QmtC*a>ZaY;ogJ$tTqL$u((hW#vySppqO28 zy_|D;b;G)>SS&W!(lVXyFuilc+xOqWHjeLp`&;bp?lByV`0jVV&)L}-byX2*&C&i2 z_wU^y41BQN^A|5En-1dyUDqPquSeZ(%U1^v!Trb0gxDIQh2)LL;OqGj-ZU*)E$2u9 zaTNN3+!3Lgnc&$zt2o+ZJyYy!Sv#q)=}p zQqFA^K*FbsH*JG_Lz()`_g_y8XDbi$TZ!(?*5lS39&C;Ow{N#i(Cx;gX__}%i(5SJ zZ_2a$R>E3KS(a}apRVg@+m_8HCk#R_o2m`21=~1WX=uxa^=3^RBQacM_LeX^8p(BVx zWE2x*A&27;C5E%bjB=G@ZWhE!F*@FX!1MT9E2%_?OA;7mR6|KU%!oz}*wbI=GM&ejP*gZBd%AyFz~Z7h^ET3QPr0}_MFl?V zqwQ)>Xfsf`kY&*#14ouQ;;?0$X~x5d-D!`>Fd>NrX(}0vVzQnhjU7@pgsDJk0nU;M z&37Jtz*j$cNwJ1bSd`Fk?~t+=pw|^{+@p#Vwr>6XInZDrFpli>ie|Av-#^0iQ;>qX zt&oAn8AmS)kPh0`5JU-e*P>&^z5O1DiaObDU}ke({^}VfOsS(7*9wBVV-RN~Nyf5W zQc8oMWA^HbvJFu(A+ibMbi(TM3-V=y9*?L(fk-uJ(8suxx-p1W5hQ(9MM=F4Dy&T7 z$%{_FphsvObx)GNHHKEwoz76EWzj4sc@|1u67l%Cj zu)uN6d*8o9wx4k4oqIfa=MGWthJW_o-s5{eJmBQ=f`9v;e#Pf67hGopRuU3@T ziuZnaz@Poa+x*~%38Vc>f}vr#a8$&Mzx6hsEfjjXM{g1kh=8_@sY*e=-@|nkfARiz ziQa%Tytk(!G5E(RA`AsC03C!_DOt zyJEV-OcIKw_4wD$f>b`M zNO%uJs3M{u1Oe+Z$KV)ECJaYoCI=(>{S;+8y7h)$81n9;N8C9+A`UgvL7!nSWismX z;GKKy?oSaIv}qAtgX?O9u%uZ`ltk!25d|Sp98;I|R^?&PI`G@$xyq{)cMbcfC~bfzH;!!4B2XNia{K0b^hjIoq;P2Dy= zQ>`oMx|+7i`N>ay&H!9NqrT@a&RE=BFk3IU`}SRuNRUL5eirfU*)v9?5xdg?&b1Wf znk-8_<`?e?bJoks(F$`PpS|Gi zx9)RzI3`e*S~l$T`(!S|nhjOmVMNVrSyFb2qvN|6*D~J8NP8ixO~b|cif?}JK8xj& z<=jg>(==o_7_zs!@8cbez+!2-1w}r?wSulLeIOP*KWM~ETMuQ|T6&+q-g z54l-haCQ9}9S8)D?|=V?sPEjl|Cgs_K^2CWx?zeYuwExV%V!wX^6<`GV%uVtm*fIY zT*O?)Y&yt8iIbAJlPDb#_Xj+=dxt1=4C0tx(8Ht&y2C{nat zNt^_LMTeR&4hRE{R01UhS(Xq+db>`QD39sJ3QOD7G^VB3%Q(H7vEFQm6Ky+MY=Z!uDhLW{>2HY9SR!AM6McPyChG&JZZgpx5(+3ISoDee)XlB0Y>k zlvcEDOAu;qW;0GsPU-gtBw2l&rhwvpLx zDNKjyI?OgJ1N^q*b_1rRMsy%Mg{>T-70_C`x?#RtAzesJ?5QW#Fv}MNIwB+hBi@84 zTH#-tvMRRT48KY7Eu+8wdVmG;QOjX-(JSk`Su{8X*x9WFSeB5q0Ybk_-ZkFb;*p&acQs z2-0DK7?KR96vlQaEm7L1#+%Mzg`_hMX&nKOgz@%zatwMYs$JeRnznUBQ9vdFl#@g?Jm}x& z*~h1JwV*~Ir(=qvAr47>lN0TZ5Ys+IRiU((&l+RMkjSsj5$g(hr$;r6sH`B1K&lvP z1*WYKuBI&J0}iHLg)1_6U!z?sm@=Oxw273tv!y+0(35}Zm{FD+3JkryRKXqHt&Edb#qDS;4Z zYiUe_8ue)Rhlt}TVK1S3eoZ7oMtdpJIz(&11n4fN3l&j+Len`8`|(gIyNa3syfnp)MQ`9vt!DgNW>4!R*V9 zkNy^3e-*PSB$K_n+%y&X?i7{8I0IGZX!6QSTTI8Fyz>F$DE1OJFH9m19RK(K{4Z$p z+{>1wqV4?PND0NDKcYX{p+kX^U>&1_eTwZpugnW3gCVYMQBqKqB~hHx7>83Hq++b0 z$T#d99^kYhOjEKn!&yTT2P8>IRW=msHP#x2J5z>x6RN6YetC(>b06j^CD~v|7^Q%u zZ9B@QCXylR#TtQRIGUith)q#a)h(}IpR-u3u}(4^PnmCW&R(8U%;%JOj+KJ(&V(e( z{I(xSQ#MGcX-!9G4Ru+1Nm8Jwi=3(~&|%1Qe~;dH!eF|CXd9NZ8_F`L-^;c@7)caq z0$~Z2V!AWo(c?$#Oea*EHQE`5aRAoe3wy&JNa5d{AQXbGX*@AbYpm(E*&dFjZhR(3 zuTPkyBx#SPZt3a7!#;z4#%Mgjp!oQc&&i7hp#zr71&0T_ymjx0 zP(v7MCX)&IW`h=zD2V8#eY6a4)+6n$7aO2dfU^=Q13=Ps{;V$Z8fPW*#d1plbskI< z#+<#l;Q08EyejFZ5&MIfG)`Eob537;!F;~t7AvV6`rzx57|h{T3u zQIFl}fTMSN^ag#(biX}gA-iv}G`P{v|IN2nCPeEJ1>?I=sd zYPCkHgdj}m^;6;`AdOP;^@b=*u~uO_OP0Xw?1s1ZpYZWVKj!eQAzEwZvn6RdpsGvu z4~IN??;W0h^$L*m`$OU=^M0VB=JBKVQAd0Ge_2V1Pyv}#92!L`HD%M`oTUHYE%I!@ z-~I9_uj>+X|1Q6r7udmw93Th?gNUy7sKX-PAj*>Ki&NS>$JUmMre=|^ad}A?XmF0I zEC{?1592IFRns&LkyaoC*NYW#lA)zUIe`>lO^fLaX_$JX=C)XEiUKVSsWMnw`pEV; zMoLK#NT8#$6>;nvi_Z8$A?d}at$xpk=lN>VPjwBQY01k1w4~QdS#8$TZAX8QF&Jd@ zhAEwCsG5q=Xh;x-zDU$QqJFVj&@>g}@rc1_h;xECNzj3!wJpvG(yX_YMm02D>$Qo_ z&>3&6R$9_DHDy&2M&tT!8y zC}MASXWLvUR+|lFSy8N4SW_XDVKf?f$&m`kvXozZ{4?$y?-K_C;aY#s(%y5CrYQ#p zdyGdzj*pLd@ZbUcL7%JZOF#9#-C{_AbHWSMoX>>t8q!}WG#0mc7QeB1 z5uU2!tZx*g`ug?Z8x1LZL+GC~y}jvriWJVhc@E@lMhCpva@>A=+c44h1> z2!s<`&y2tJTjNc_Q4n%VF1H6b9Qt`|N^oHehW_y36O3pIlH^A*)bettSr6Hgl};WH@0hfz)WN zJy+fsmg@~=>k-C5YY4QTo)>jPjleY)Q@6BDO`s%k5D;5Iq#S9ixxBbyINb4D%qT)C zpVsc2rMsEa>y5CHWz#uYm7uiph3R;}{@w)J8YG&!Gkz;71g^96vkWN}o%11y&2oc^ zLR6emR~<-0KUD-e#39+Ny<9}0*qmIGA)77%K(I(@XSM z7l=G(pe3elF{Yuvo3W{Kgiv%MA{p-!Im>E(gJ~`Ka)D_I>bmCa;)W>evs!NuLXt#1 zW{VB4FK)P)FSn@V0;LUsGkp2UN1VR;ioEJTYQi9<*fdv8&OfwL03KPCLZyR>(PxSJe%wxs{)n5Ar~s>%;%0*Nynx-|sPuh3=7 z;K>p7I722Wwq9Zhs5?s%YMQE`t)T5{0&S_+6-m@59*oFa%Q7$Nsuo>!>`iwl7ca?X zUm)h!Os0qQ_cHd?j389ZtxsYPqX9dCh0RNv;T|U5qswdDC}4cFPq{3aEtU)iJ*J}} zW!G^&y8#_wg(FZNu^R`PP-}=3U7Cvx>W;8}_GQZ9-lvv`(p-4cTNxuNU&-^PE*>sl|p@%YySdM(-XH4h<9cj4;~p z>Cd0@#plmBzB}aSe^v0=Pc^GfF`E^fpWM)m1KNWjGVY;JG_^w!qN5NEeAwUP!OkAH z)H&xMjsyPcfBhfn@*7XDa|$nXRJ4^r5Me~XEH4P+h{gPd{?3%DY1!T1^O;cs>OA)} zNMq}8-epipSKx<)F0uC!H6KS|MHz1PSMdpitY9(%NvaAP=O+e z6SVL$s>RKms%x3-?vi9FTKR!*zFM-54_)LHeaBF2&FX6 zSZ-zuR_lVre8t7pHK(sH*sMx^`s07#^yO>HJm>uM1xH7_9NjrU2bw_pb2141pbzOh zR@eFv#W0G9;sl3Ag$W;h{0Z~<0)!xq1b_GkKV;a8&>Ex!tpcJbVL4x7tn;2rA+b)- z8uR9ibXKrft|^PkdsbTGCCgtB4pMFM~M3i~K>(?*1S)6;=NSzZgC(U{+ z3d!q>C1;m4SMv%d0uU{W<%aV!M^!oQ9Un29 z-4EYqJjw`y9M#O(Q2`I$e#9W`Sk~7hgFT8`uqtY*vZ7pcbgD0rB9zXue$#~2lOAvL*VWUWm!bwFG^|*-z|M2Wf{^66)d47I@5pX!1Vv~^B zcE#7zKIO9PNwuDheO)mqQ?wQ+7nkRI2VGk5FmKZnvjuYfLb7 zz9-KztWhj?ThyrI_2LD^C`T88)%K2?yGv%X2_Js&epE#i%%)==oS&j(z`B;F@0=mA zEbdlV>-gQ@{XUcN5aD}@L?CgreFZWch9Gz72#AOLA}?d>dkEa#E#FF{;!x)FFCX6@ z=VSgr9!lv1aVwH&MZg~h34!;qWqY$-b9H@<^MS!2c9Ps%hwg1mWm(cRE%z3tyTu(Z zUcBJZqsJsk`nGpM5C@kK0$G;Dn=1DNtZ*1i;(Fi5ij%iiu(yri9F&dw!6HPDX$=2H z>Xftg?bqB}tkNudJK)@RZS;Nr--X1DiLWh5V!;1x=^v2?)R`U^qV=me{M}?}PB0*? zz&0LlLbTd+mi2Z|DKeCiAYw-5dbeRzj7Xe1 zb}hv?;u}Th=r?<;G1Qw4cE2T2j@fiTnx;sl$%jLF?+`%k_9&_Gm8TN{Z6mfZlq0}0 zkcLNRQ_4K$^6Cm>11im8-UmV7wzO^YmLS)6hBQdL6nLG`bsfV|PLe8aZ#SS4+P}8LhKcXd^_E=c_(UPCN8jz~H*1o0?I#~RgT3VLx}x(SKYqgg z*&Lfo{KXw+v!OW~PS2ZI^ke)I%II4GX+F7fjp{WY(@{uPN51SBD7R;!MBZ)jRe z=RLB>sZGnt=`p*yW_EPMrrOb3Lz*O*ro$PFw3eoBNQ;u;(HtWcKFvsnBf8!pvy9sG z)NPAEaC>#lcsK%~sG0_69hVoEbWMl%f!XO9t@ljFQ@;M}OH6Ab8eB@|rzaR2a8k0| z@7e8Z+NvW#Q|Bx;`)YWzoXi2na^h=g8|M5q*e$KxB4I$PsY^M9$Y+Q zDIu_ZM^#toBFF0#bV6r5FJ4^m^G|=l&p!Pn*S9O)TrXH}_H1`G%k_?%>s!9~>`R1q zXcg$19YvXN{_rf8Xm&kWo*|?}CmJE5iy;7AZ|N=UYr|*1{+gfs^Urwx^$WI}C4(a2 zfBB#PM?U%H2Po+w*h9~lLrG0hl+;yxCIuoG;y$ODCK(_o%M$OS_9lcROS9PdWqP)| zEw^`fIO|v~Ry=rk#$cGR-7Wa?s|)&O$AdG?*UvBbyB~jnQwhCO1R+=~SG1ku^z0!j z8FKNaLFj@{zWZ;H=>V)@b9o2rA2CQasL2_RK6r=S;vbo*ud(YJ26;nX?C83huJ1^* znzQp$7OMsIddIJSbx8cDXgb4swdeNL9jQv#te5O}4e!4Hh|cYp zot)Ae!^;svH4}b8z zZzHxV@}}n0DRM7Jl|~FQZu(mu9i=?Y1m8YA;;9Zi(+R~ek^+jXU@{zH+7^i<*C`{V z2&O|GeCkFCS^|Yqq*_LG!dlXUick(qc6Ei8l3|gv-ELWKwn&wbB`Hcsg!g#Ub8~gg z$;m0!#qh51g1V|GQ%$Y|Wf~90v!e-Frs(?yr3I7e5TRmAbe_j1^3KG;!-qg;4eRX& zk4I=wiJ}~q1Uz+HVN4&(_GApwHf_yrzr(nAF!mm1vkCL#8EKZqK<5FQ>Rli&bMibk z-quYWrDh?KQh^9eXGb6eP1j&u^v3HXK}ce7*;$&lq3t`eETeNh-Ukw`I6Ha5uRnW^ zVM9LF7}q0|qptUiMGVHq!C15@sBXOjuX1!RmuN(gS&;Oj8n>XBD zy&_RjeTWUl0&$?)R8>RM^{h8LUcP?K>x(zMdGiLTBE~fcagfX7LH6ESB@f8U!*V|E z!Xm8vHxBht?!7P1lOif1<)CCXof5*o&~5Gm+EPmLJg05DXk&7YYF}}AdCh}|579}A zI0P4ikJh^1#NYl)zsJ3#a>$Fk-PhgA9UQ{y;=c=civz8y>$<2+9EOAY*M|I;Mse>W zy4IL@4aGqjF~-E^ZevN){5Qhq5jGHQUk>ME>Dy|#Ay0BdP=wACIxw}t8!)YdcUs|64( zKu=2YLBeb{BrTHo-tP^Y-Hs3(NtV+#I}!&XXp}I7i(fJt7T7XlR7y(OGcIGkYu`Dx zjlqY2H3n-vUE6^VpV@%E?P=dE89h1T zEcb-o(F)*KpP}AdB2G>qA5h#jn9nbuYLQ(R@2`2vU?w?v_n4ceApuM}r8s#^w_dQ> zZ0W3{GkqM`f}&~#oy;LiY3nVMQHmA@(^pv2(N!BS+jY;y zv)HbWC73cQgoC_byKhk0ga?n_A@MDVf)AgZL#?>I*y4vn%=wI4)dN0y#UC8ePcobg zD6Nr2hUg5biG_put2ZR;26cYMZkS=xgz+TD_#WR|l+$rd-~&ErdTVK#E!i*y>F9&S zILZ39!f&A%PI>bF13r0lOtV?A(<#Z58OP;@HWh3+rQdgqiVWX&JStcGn{Qb@oNoA? z?|#HW7hKgIpOp-Bj_PCJJ)gv!k8BK?)C8#_l&kaLJ&DrD03lD%GEiJBDYrZN-Dmu} zKOXVJA5N%t8-DobKj7QH|1oJ95a(m=hOqA%bkp%qKmHkx3B{3Q>qn@}G8uS2|GeXJ zv&IO|ix(V zJbDKh5`2O+8bUl=+1@a6@P{9Lf(nOw_+g3k@~fZo>5u;wNhAX*oslIY+Q#AnWaR*n zB{a6@?74f!a&2T!!C{1NONjauzT7ph61hPD1 zP?S7=_=w$Z&#UJzxqW%TAS;l0#`ruA7{hWzT{k!vG2Ka)QSYObN-B+Uo~CN3Hailb z8BHeSqY=~7IVw@C?iQ@C?-*nSM@L5_!y@9og{0|vHroxe<2mz(r)Z_vUEkt+gYA2& z-42vwbTUWfIU2!uc7(&TTdZiS3KBs+C`gk8g{Rr?xxTt&JQ;I*cFJ%vCQT&OcF%gb zqTcPu(v;cJ44tHS1S&{0f_7gs7!Jq>1&hs^GEM2*776V3JCs(Wc}4)zEC-=jt#({r z-B7h1jp>1||&XGzpnNFEbW-L}~>Z-=K1|oNC)pd&jofQ!lp62N|1vO6^Ld+%hdBX^`CAUa;6z%#Y9c!%xQC zE-y*v4=G1u)|)+fnv*4IRDFWLTgC15in1)3P9{vor<6s)o6E1+ZyQd}bHFkl4Y;|v zr-`u-&f+(xFw9;WxW2gYk$m$!U$D?^~wR5lNb`Z)>Xkjv(Vvv+i2*GLJ3F zZG-U+m8Cp9e@K!SY?}t56<&GjdPCJ&hT|DR=WMH*s%;<@_@F?=Ax#$roe6BKJwZwO zwuM8v+8YXG@Hca zsuA?Yu-n&cx4VNR4Vg?LYBxzqbir?ZG$tJ$p%cyW?v^ZxP3~3axVu|W)%BsX!M)8o zyroFV*aZ=s1q4Bgw{)U=7C%JUTI&NuSj1vF4mkjO->eM;ZzE$VIMO2L@uR049nCPd zk5a>7IQY!~xe$WcY|3)EBAEC(Zf|e-&;R+q@aKR2XN<>Vl)i5USHQi>5f0&R`8J$Q z2!{Z+dpk@x@3^0F?x|1ruS1H6$h{vjy!Qwt-+r!6lY??`Z!_?3iEELTqX^!{p)@ZK zO381`J%@n!eIUH9Ypij|EWx%0S6dRN5KdxyPq47xMD(i<0&6`E%dV}M6;p(b_M|xf zc|x2z==wHl()Wa^aOhKz2dknC?Dji`g9(`~322(I=lK_}c=r8g$iw9hB5;2GkZ+n9 z-zmrZ^zS6UWQ$D_Tv-r~1~fCxw%?KB@mbDI3FSxcWb0P7^4*;%jiYV()3Kd#w&qwhEyt? zF$CvG47j#ICK+jOIL%T>J;Qm%>G2W$>JFu0wcFs7#tKW3rib5`z?+n6yF+Fvy^ElP zpaflAGn!3tA*F2$YM`l_9wiM;)q)Th<;g^#Z(DY&J02e$u~}^x4~7i$4Byn$(i3() z)lXlLyxEc?5JJ&P&^lm*VQ==RL?V3bO{uGf&ICwGoRz3Tv1@lY8)%(EcuAS&l&K-u zHQ)cvH&}0WTwLCf7X{T`B2c{hIOp#6*SvW31wA!ENxHf{{K5%#S3G3VET)e(PB|W?C8!o>7 zjOjOj52sSBAChMUp%K(Rr(1Ton`?gWJ2{_xXeedR^UX`@?IVQA5Z#L1uI6++!6gAp z&#cJVuY1~Mg-CNK3-;TVvPe*!rMW@Aq zeLCP`?Fmzd)sp3|qHGHcCv5jaY`0?m{zrVV$oaTzd612`*u7%e7*3jk$!Lhz3fF`7 zfqm_GZA%KjXEw|@e=ukHtB7Nred`12+lFD9vm1jiGGIWdPw=im<{l9Qo$CpOJZ640!}vfi6$ptA0i_IO5u3fcrpFk^Y&Jy%!DhWCILl}@Bg-?;f|H^^ zHVx~|iv2ope0oZrXP_k3da9~twOF&bTSVfb*wJ(iUDGhk2Lum&ZzzfZQb~dcq$1k3 zOxLmA?Qq`k=yDUMMLN(o~~#L7wG^Lz!&g-gazbKv@U^?f`FzSoT5hi1DG-8w&T)bH_NmH_Xz;DeO& zzTp4)$6v6iTI@$t=6=cbO@p@4x>Z+x3R+dP#7WzO|g4 zJ>c^%z9cBiH=e!6d^#j_68fC&szN0&8jLA2Ns(vt&5|eQ4;W=b)~icy@2*Ky!gM;} z_U@XdF?_Guqkr)1L)Jh0ly1F3BS`UdiWsup)a15cUEMIx4d?S?irUgi&&B4N*Bz7( z-z7^VQY)HGjkcCL5rnQKca}_OrfJ4T3ba%tQj+Ewoq$m}06bY1eSe8kcxzBXG8qnN z*Za5`Rtjf&Qasb~kj5EA$YRRJ2im?RPc>ONVlW)yx)puf$1a5+v2911X5@v!*p{Z* zQ|6jPgm}|49eI}0w-wjdYYd+0EOMB;zGqk#WJMM!QwqwWK&A=%s$zF@O_FD1Wr^1j zp{KHf?RG1;&5Is)~6iwlzRXoyG>e9+u37bLl6x7*``;_CX2C+|Lv zTb8;$U@j&8u;m_)M<}V;^*4O@(IfupZx;xsP#S_&XrVFAVLFQw9+hf>6L{ldNe+(5 zcub;n^yl}U$L~C*?OI;Fe!+fmNnO=!YJ)iBDXjDOgA{SdIwONe1R1STGH%J8_lFLX zd;5`ylm`G2QMF15yz_+M5cq@DD$;mTtr?F;OlMOjqajKPyf?@LKKGvR1iZz`CP@Oo zd_L!Hv7&8Tyoc3t&0qZ2zu-^)_>VZ6&kx&-LnAmboOW;Rk}<(}_`iQqF=B%^2k903 z!R~ZF?AQ=+Hol&FCB`4HwMmk^#oivoo42jxQS}lC5px(?C%=Ks{TH0Bb5XrB<~|Em zF&U1ry~WfP9-}1N?T$f~p$@dRa6jbo_{gNo}SSi zY4kT9(oZwIX;GxK2(m=5wgPh=!@1Tw)UKuuHKW-H&U$PJU_G|CF;t(W$Wh6#9CK$n zTrs3q0pIqNv^qE!aj@3X1+Z8Gl2I8k z)2q#zP8cSW0YU`qwqxZbJ&@gO$@Y?R`iN{D*najBc~?amooh*g#N%k2icWM4nMB5ndFlDn!R5r*IS_J{oO?|%UOhP%8Y*Apg_BYysi zub9n__~9RXg0*{+alt=-vE(0q@`Aff%d{+Mnm*#AwIC}Mor7E@B>9+52(kcgF5mF_ za!KchbazWcp7QAZ52*^l#`ZMUQa3d&cyyBERt@Q^HOhc{dW?6VfqvJZ4g=P5SyNg~ z=`{pTrVVm;LB1W)OwY;2Lz288X$z|53e=X?8k|_u?AKhpP^`V?dYh8i0re%UF4oAY z<#w{;Y8{x1l040j<%HLl&&l#YB}#NUXSi=zU%x`-1+8n@?Q04-q3ZTAt97*^=>+P* zF>4u+wL>pAbpP!$hQlk4reiiQ7ZgoOCK!5R zq-9`Vdp`Z!m( z+x-^ZHH@bvzH1O^!p-d!#c;&U^)0ibBg)Z`v$L~!&pm|AH<#CZ`qzKU$%Aw9$rxQ` zSbz|fC2M=Cx@J5WkR=Jr)h|CIQ7PrHWPUtHXoVFL83f*0R_hH% zC#Pgt&U&-u`HP6Bx5lyCHKbXNPBV--^wA^*i7sgO60LFDZ)HiajVx27^KDtMZ<*EEtW(q=`lZ zPnM-f$yWie+xBExj zbchd@G)-~VB1#Fe=H>GXv@!hnr$0uBgbzdcgDNuX*^+gik*CEz)elcE3VM z#URgd=aR}+Y`1Iv`5%AEXgFZE-g9|LzcBvco2anqXD0N^@1ubQAxi*001BWNklA0Y$r!y_q#h_;2bhLfNa8xo% zhHUpcyzMFT1eq$VhtrcIWSY|U9Xinr1|>-27_yRI@42>Ia!`kwKc1% zV>FwQ=2;xt1Y~6yi>9_aI^&tnk4RGuM$j3DvnC!qde3MyB*_z;fY-0D$?`G=p;SER zmZKq3YdT|D?{-LGBW|~^ILdNH#hg47sH`VAu)Renfk*|3(0Ci-fj>={&yEqPfB2_dU0?D1fZ8P zNt_;_L(X<*v2`5IvLb*9B>rG86cK)qCMiCMIAkCh|a}@B+^Es)mdGEo5(65*b6iG6}i-ga9_7&gx#xr*N z9e?>>{+i$YgJ)QF?3uHXN*%#$x*p?@ENs>0Mx24p7pQi9JV2 zOM=4XlDtst>J=fl7(h2VB1J<&2nIdS7=6Oz8{ebSL+&b1wi8jgO%>7y&<2x@_~$QM zI$bfFCtOvReASiIO~dB$hLdl7k6NWvZI9hMe3p>pl6hLP_{X19E_a;ygtY6}S8MWh zPx|TxE0+wtph#NM-GIBFFZkd7{>Qv*_Dp{G$Lxld#cE6a`I7Q|ttb%V8Mya&_{8wtrv=ad?wSYBju{mt zfBC<^;qw;_m6+3;1lJp^-(Y1VMG_KnTFoIiV))!iLi({S?S3At2sRfAAE zZqlDV#RiM-J05k0FMstpO;eMXCFhUMAxW?ymhIK+9o|~TPpOtmKL7M* z9F51Eot<)i{*Z0k(U|D|Fik_XT4URWvK;dI_6Gm;SIp-}46>ZQZjch*d-fDr4yk*? zYFp9wft%|EbyYJQ4$wM5NP*NUB50kXt}BYcklAR2HrU_aqY}X@!&1OxKD5T6tv?S39IE!$eG*u)z+R~km z6i0cmRVPV?Ck_#9U&Y0r1#4p8$Nlmz_I1Q=ufDe^CF$ChuImvYe6 zCy!9xvRSQhJA-I0Sg#aLLza!`O^&vZq;PffoW`YGUapu;CYVm(y`W4}#)aoxcFa$5 z_NPN850BW{mZ?^J_Sp;a(HU1a4X)bq;WtLOuxQy;`R2!*o!>GX=DdFSlEGw%Pzgau(m_L+rf3kSh8jttIG)J*=AsgrLZ?NM6IU zt9ML_f>a2E2qY33YmjM<5CPw{WITOSwYVs^0NhBdy(lh}CZP(+x z<#3TS+r<(T9L=XBc|vbH zbQ(!kb(qR(C5@;mOJjEfoS!+qdy15){&bGbV2 z6c`c}TVYj#44y=524&8B?>ylfA3vikGVl&>d+vd^T0)j;60Oi$U`~zo0iA4<9~4NTTE_!rPL(`xU-* z_ATux98`>O2$bI|8E*%W!*(o$L(6$^hYW{*Yy0!TALv?O4m}%Dy&x)9ZHx03sq{gy za=3#%&3TXWF*{+b;q~iROv@?KO6VaNK`;W*#XQ2kYDi^D?h=CYSP|H5b_|OV(nku6 zzn3fsacGjB-dXajL4%BV|IG6m(6C^M>H!wMIyiH09lQ9y1sgcpUp} zP2V_7@9BfX>44Ud1V;!KxveOCK$el5krf5G${5U#sRh{1K-Ho$MJFYR6xj8OY>;8< zhD>T)@T3kBDKWNVaOk+{yo;rrS|fFe5E*qBFhOI2r0p#>Niklag`#gGz7nDEPN4dl zG*h^$A*h5dO%Q->T1LeP7t8^B>SE82Old#AMDz*z*%?73$e&%KuNR2ELGN26J$Qrg zCN>x-VhNwrI1?hi)|Z^k<~)Ayh|TRS1C?MJ$Lm+OthXE1>m|203zmxoD(smLQ|_*> z84Odp&T{>#<{$p*6{S1o?$rjO4MkC=penWQJ-BQ z1f(Zp{Htq{bxkM|#N%W9sKnusd3xv}=o#jL`DjcfG#gpa*(BN~Fxaj|1VwM7!r0e) z(%}GEjHq0okr};~Onk$5I$@(qinL&m!T`hLqm+5NU^ESMWzKa~vbbF{c=8ZCn$Wa6 zqzkldhqr;&27+_A+gsAMLS0$4-3`WSrQ{;m2gQu*+oYyOlEhbbtP$UET ze!#`oYpyRZDW;nF$(%P|F42s++N?>RJ)}CD;)Vl)0-31julIp$P~e)H)zuZ>d-N`! zJb6l#ybmP7Ao#!k^1pI@ae-`MG(4rqCuB*93yP-e3BY2rqjjF;Zc9EKlb0o<;fT6w zIDh;E;{}5xMTLN=YfMwI*={J0=hPuSYmVo~q*>10?HwXOv#;1J*I47pivii7M5ZYs zQIwMr$_KWu-!K^tIXOS&==_vyP@s|oC7`crE-!BwPG?My=0IR^ca0(tI>XJ?6-q0H zlPNkcK`4Zj=do@%paIG!;)o|DXG6j@4FSG;-tf_}T@ zXgp>-pCZZ>V=al+cx%}#S4_qegid*JdCBeVO$3ox%Vxdi?)HxHcuX-IA(D)=D3Mar z?P{)Gy~f&}@oda^HX%t9+PX#x$@5niq~(zDd`?p2SnJuXwg_V}T}{*M8PDSPjn-m8 zqNCbx4&n7-nexu#2mIE@AMlM2p7OzybLNvF4<4QI;L!u7vnhkJB-POx+_w!`mXV~I zG)dU)b`(WPmS(Z-U8nI{C{5qnNG>~2S!^E{kuC&+P!J?tYcai}GZrcJ;ar!HCMjA) zFvRuk4cAvUOs7+B7^;rk!3S}qTk?g_Ke2(#aj1W7p@p+*UdeaF7> zR3R`L51A$cx393hU@|$T+OO$5k4hxD6TEzN$G#j6cR$0H^a!Dg{#G#+yL z;Ec!bpE8~mn7-rri% zpcs-TIhjhxg$CzH^9*cHnMWExCIz?EjzKadRf;4@>5U=JGJFKuW2HiQOG?0dLy-ua zF_gnG3ePAhu>^)fuwFzYSKS|ww`I;wX&T#;Cz8A6j^on_b=%XMJy|Xpjwk2@ny$fH zi%jD--B?di6r_2Aqi3~V6GR{>G+7GP3uH2+Z4F)B(U_WIl#rDvLgmz*C(DO12<$sL z+cTVu@ls+5?3+GL@}@zhIo^2A&d#Vi!`;;lciRo8=MSTG=%5&6Sx!~&@gk}#ts7g=a7vA{;Dk z?odjhyyVHdAJ7`Z?d`!+suiiyn6}3SkOZdF3De1l$#{g8f~Suku-xpZ>jr=%$tlW` z+uJ)fn+*@n9`W?a6S6Fg+jAFDq#<~88f`+s#@29SVhgu17Kr#)Yh&q|NF&jy?=1*- z=&0b(si9)#B1HLF>jdLG;5j~yEw4@80}>$uzxc&3anA8?|INQ9SU`z`5^=D39jI3S z|9`*P@_j#qD5bE*L}~Ys!SLR`?Yg)Rf^*1tfQo%EMS-<8Qa3!*O-)ghZ`BQVpjkN= zVo3Nuyx0vEbzwRWnkYnTU92F6OL}eVEypP-L zSX;~0dPA0LGUG_3KG3Zksj`?53lNq5|G0Xu9?P=)%I~+$@z;mTNL#+xhPG!!5HkW~ zsRz9Y(4)S~d?W#qFc3J@NaAp2=o-ytH@mC4Dyz~&W`?`=`0eztZ)THvN+2(ABjVh9 z_St*=*ZQs4=8RAnH!{f*w9F_@@>slQE&X~x2Fu0SDVy6nq>Ckk?fsr|RpO+;3qfrx z={O?tDoz}{C5$~XmC+&>JXxxdRf)2JBFShrJErqly!HrGmSFplEK5Miqj&%T!=dRS zWI!j_@J}YK!I7vK_SZ6@s#40bpx)Gsy@iS3&^0LM*d4YQH=-sJGMyl0%3vI7zM$E4 zxcY!ja+1-ZgF{FQN&K!`W1|%>O=3o9v`7_mKdH~zzG=8$-}9hY;9cO4|K-2n-~GRT zOH5N8TaiQjjHNUD`18+rclDOP__JT4Y)a-&S>!*Ye!B(PvAKOmH7oe#U%kft{Wtim zBti1)Z(h?6K5j^53PO?>p2 zxs=n7QXYPM!cYI>&yc%&xHk;{pzuPXcO8qO#4Hl_!f`ND+SMiF*du$xdZ`ExpJIlQ zdHOkB+ViW{Qg?>h-4TWnQ^oSd!`@TgTyX!gqrV)<=374b$wS)YmdAR^w{pY5&luV$ zQqdb!5S&fVaHAnr2{K5oy9OITiKE~m1Uk!DJ^q+q{`Buy&Zac=K$&Z#NXWB{qM9-a z&%xHnG-VVac2Z3yq}mHkRtg#%SrSA2MUpbCH{5;qg7YtbNZ*V!-7SMsWKwhW z@+Bfk_~`RbA&rxEDFqsdaGtSgS=kno0WSSgvYyo3N+Cxp(wJaZA#$s0MIBa(K+YMQk;RMJ$W%lTTAO*@p z<^+9^SRpulbcwT;>$^LqvniA51aCc?+qWpKnO~eC(*)rImsQ0$cD#H2hGx6xbaleh zN0(R$2I552IJ$j{&NNSc=Sy-esS?fMZi|>kk?!jCRm9mQIp&yo)J4WbNp|adgf~2S zc*(`XOYV2uBfKXbeDaeSr)MWDr&EHB&dz2S~CkI$Y|*9%~|vOeb-FWUa>xBSY6C2xLW$PE#ZTA0m-a3W+s_ z$z+OFn(x1V!NZ4_2=&|2UFR+8m=yw|8$+pxeHS7E9YO#s&p!Et$$ZJ(%^iK)^76YE zZ0^^`BIcUf87?0@X1-csT}RiqeDv&T>{%0zckY&(d&%w4^YQEi+w7QCIkin#J@|+h zU;ms(bHPvk_y^oL`W_pD{K)iHey%YX-)lMQ3G( zm{jENP5K>VnSYx@lenDUNR8`L9gLB+q znG{ppXlV8gSyA$bfAkZs-n`}Z?k=hVTJfVVe+NHW-dw-q?(UAeyBqK$Ri@Etijsnp z#gyfIO5gXaw>!T6>N%5Y%J2T@OBSD*g~(gH+m?6l6IWK@Pj zh@W)~{RdK|L2HaN40a&Pa+K0Yc`Ubc(b^RK4^VH`k-a_!hPsWJC2x^MMi>m<#?J#G5oyZkEZP{Pcla<;>I|tsy1=B&@n*z& z%YM7(?9oHk-cktYokJOe>*Is0ND|NqP1B;#3`39Sw_|!KBraG85!0;Fltc&0qM%T5 z`neZ^Jk9Yz;iW>SAXAO)qjD$GjNUk82qe=AbGJk6S~$%aQb8gl$~mmCXqg;;c2qW9 z@X_lX99kr3G|obi%}J7ief^5{{*It6j##?s-e0Q_$n%_fx99VxpKQkD|pmN8sGYDPs=)n_Co>lza*H?_jAa#ZpE_$JzW3^iHhrf5p^IyE=U;oh$Sxqt$ zm+{R%d`H{X%oh{-Zj68hZ;?(QU0^mC%I|KuJ2aTa(ZAi3Ear5l1x5#imJvE(9m;w1 z@!rc)g;pb@cUU}`p3~c!>0*KjEignrf2-*Fk$f_v>lCB&jAKWM=jm$BH{V~yLQR$9 zgaqly70ikfIXL=k!q0CHs8Mh_%jr9hmVzYJO!JEEZjTh2OeKunKw1>Y(M1xA^t8z> zlP4MB({osq@awl^dIm;OR`Bufo%45B|C#ziak0=mdzjM=J!VjBh6&RrbH1ss*xP~B zXbL?e(-r83$~(l+u;~nICrHy7mKqlNs)CuS3XS{m%j&eDtTAk9~++(wx&31?I z@cI|OMp{L2`H0Rt1|^xEo%8X7b4DfE-rce~J7qST(X`Fc|6g)(a)Kiu^Nf=uC3GWK zFJAJ_7#=)*%-O{$hrXk0he&1{E&XnX)`~};ev0#s{dP-z{f^mc6*GVYrpqOhlf{S4 zvE_`RX5khRQM?eEgK` zWKNJ#9Fho3aMb&TNj2yE>;YZhbM^L`YC0j$Q`}%^hMu#h4@jhn;qxrP^d0qP$FF|= zYldN9adJXFsjznZkZm0Lo)9dLK6=En%Lkk-X7p`?@;zl0ZN4X~)zQfT3Q(k&VL)dI z)|glwFpg-g$d4Fggrx6!s(Tt-xLRkU`&umtqv?fVX9zK3Tv)gm?`ie|RgpD-G`}I9}k)Va7X6rFg(%GE5 zM)PPPczd&E2ql}{JwN?V{}-=cJml$gtX=^Oh&)E9iSfkPN#m8^2?|tgtrc_Qe+2UGw((j$M6VFoyee zL+1m#-f*@$K?O-$A6Tvy^j*w!>cei&+2!Xv{JlRwWjTNM@>|k8XMMlLCW2*E(Rslv zn~{|X!~Vd_H!sMS3)1#vzCmXM@u`VpDuoE9aH0URjVDbcT~pIrOWh45hW(|K$42xN|AA~2 zmHZ@4@Gc$}-sdm`F|V-O?NB;mMbk9@5CFH<9@X#!JI42y?_E%UmWuQ9Q}(+9>-8Ef z60X<^4?>tCDZvaO9IY%nz}jKzubqyKYv_s+wkI;(UeoycBOtKW8NV0N{4A3<#LMbeg_3i*7;Ccf}qb4PGw1oEu*1W)( zfnW^58S*m2nSmq}qi|3$@ z_uWx}4nAVYcZUP@UB}RPXh(*8i^)g42v~2)&?Gve8%Jz!>H7nH-y&oLRQThBOp3U% zoR-hf!f`UmS>^>l{fn6|nK85-`B(QSQpz-k)r>o5n3M|! z9S^8jk1`(NW0UU$O(qQywIR4)H{9QCS3=D*P(p?7@=Bx?}(1hDqI$d@Ol>_qTlcFCOz3|KU03zn}0g|J4$y zJ3`|4+4q5O&6bI;D8~tj^Az>K?QTsU9Ld2^T?f?3f}u(%Hv!{DG3vT63z zjpFRV1tF{0m{^EcCL`D1e#6Z4%q}iiRC6#rqLnNbb55pn>ivQBX2<#COUl^m|Lx{hHSIeBtPlBe8l?zwxrwD%dlC5N-sSh=N7^%uBs>m=Zpv#mq<}|l!uD*LkQfQuh@(e8lL0E>N0UxICk|&QIvY3_-0+VS)kw|Wjf@{6sF<;E1%YZ0!7&|hW zf%!Zhwxkf)uBC6yhs}A4Pm?Gb5-p+QFwhT% z^>&9dCiWjm5#1cYqlBO+s|XKro}up$QpOIgqn%nwL7HateaHULFqu@5kQyt_0YRE2 zv40~G48w2~8{az~BE`yh!`KJXGGiiVTwI)S^YRtVc7r-v$bAU3U60Z!E;!0b+^5a6 zbKLcs!`pZK^yP>tXB@CdreFhCSNEjFgx))v{+B%cbjI205l!ppY~bk^pR?U< zHUy_J!+Q#vXXq`?L6KLe|K;;P{5PxVf{-WNY;L&v%fIIH#R;iQIX_t;yayzMl5EEY zgrb`+xt&khjGje0McIHK2I{`0$};>o;G98OL!u;FNy@6=dVNn;+Rcd#F(Bcujm{Yr4TNltRu((Leq5}4`*|%vux{{X;qO(D5?r$ z4Nco%tYtc%ptB?@1QK+X(+(rOHH>Z~uS%-P91_W)Zs~eUKRB|Y1R1+H@+xCrAE?_N zAybN~L~6l+?iKH`fnzN9LuBZk#Q(!-Hbp_Do*8gT&-^0x(d?-!)sZss{&hiETC z3eqga9?4AOIO3f9K*I3eBZzoqAp}X99_?QmrQ*axCvp1G^*uVx2p(?l?l~OxESF32 zJVOZiPpD50AH;{C_&=R$M4{&RJM-IvQvBT=(!ZaA92YA1&>Am}`5$5x4BOp~JkR4q z!@tMs`VS#;=RNPvBpnPwA&i#dnZ4w%tUW+h6*;=SM_ zfkOyzc#zPxEk#~Hh{}BY;~*$7!E!k4SuIWwL{P!I?MtfUf@yY!5Dp~*AxNs_oZtU1 zKR*WE-*6Bk4<9ao9w|I^-6B=WXkjpcLtV%Gjfm5Z;z%eNo#T4D#x?^< zko4n7XC00>t#ZSFX?iRIsS~VmBxQvYks>7osNiwVBDCVL-IJ6PoHyiBFt#lrO|hLp zBq>G;JOUE}LTNIcV2_7mOQenwBvDI=-$k55NlBIjP8Ktq_3U;HZQnCG10j$og&79M zt|u!i(&+@{1Kxsm3Ty+xQKo`(+mP3m%|G5C?mNcod&0{b7A<%);)6L-YTkF#2+~xO zr5TxyRu2J`X~FWroW+xp=dWJy(Z?V2_4jYswE=&`7ssv?$HT`X z!O4-qI$Tf~XRy9U6c(HH-0wzSU+oY&C5V8Kkt~-b&^0?W39H$R?Yjeq8;|J)&WosA zy6C@d`z})5h!(hjkL9jXArg)2M!LEsyIeB9euvz)AT;58MZ3rurRDr=$~2E+S6dr4 zuebC~$LwOlY>}gLjWwQbKVXbQrU|K(hU91XD8g=Ut_Hy(;C~2Y;Ny4>pX&l4??+h2-Y@SKPjQ!(uk0 zT+E<|Ju?!4w~oGUu*1j?fA|9~AD$t-Bav`=wq&uGA-rc=RP3##wJTGXQj(S(4m14Kskmor`5(|cv)EE;x z(u^5tnwAh?yWR2X)ob39772l-ZOO9OH&YZjv+0zgEYVtVIMkTYM9|8yJIY!|qEn<2 zmnN zeW+PH`7z($*L2?U>czLz`!#(#QszsR^K+aT+3)UHPBrcRmVMpvn|(ojAD9e1e!oQu z&E>@z?QYLxb&3)r-~93~NfXV@#xou}wPsb0q#;S7yJVhcWTir-bKbn(@c4W|<~HOw z3_Tw`UeWJ&y!_^xrgxO9Q-(3)`s$Xu-GK+sp5RsB&>pZppk$6Q5M12zot~aBjw8Vb zKL7j&s2|VH{>=~0PVsNv^0)u@f8f)}f+>Q>7Y}&dx6u;f0;V4MzTI(HOzD?rY}1@^ zgi}?J_&}Z{+&2xCPRW!)67YRbp2l7cYYf}I!D`7gFLBON4;^V2BP_1!&Lk&&bdl?eL2MQVxE`Z($f$V4Ji#b7Omw!?T&G08y& zjB}AZ;spH&K_uuba?OrVpvdUg^-H%W<$N-<6VHDS+Dne z`S}l#Qt>x`^H*3qfN*^F=`-Zf(j=86%Tn?@M@q$DEYDxO;H$5{Www~}!yo^Evx~E6 z$#CX~agE5$NZ|>`7H0J!-(ajmtJn@o;JC?+L46-$Z$vEaiyPn37`nbc;zQdHn{i`e z3uxE33}YXsJ%^gMYa^@tP*d+~4*Qz6>yS!goyU5QahA)2eqrElW;;iMo~ zkFpluwzzhPy!^1%t4?JZq9GFZjn11d`x2LsMAndZ2@r>Lfc zJR?OTJR~Zo%;SSJ4VLliUy+%F(G>JAZ%FU%NcLO8=}<^5oB zE`k^=mg;22^nAj*+XFW@O?*G45F(PcoHKX})pUwdlCS>Z70rFzTpXH?rt2b=FwL=J z>^w@6gaD)>kV(xLncB$CL;>OHDemePweL`9#Df!tiwSa?u~@_$PTP5uD9{58rek)w zqL^ficEDJH>mknyk|JeVRD{kT#*Qq7`IBd;<%-$qoZC0Itm}ciN|7RZ#@%j9wop_u zkiWTQ=+?}?c*4F9oIIFvdNQHk?zvs>IatH6-4U7|Z3W5JqV7i~c@Fc6?7<^cHDw_a z&hr$JY_OA>N1x8fQpu0L{DidH(}pdZy+hk2@Ad`H52v)&Q_OPq7K&$=)KcL`&!kdR zRnMbY$0z3=#w%vt(V$6^1E)ENNJ*0fDFcQ9bRbiTet!Th_?J&VaKL7;e#BK@16{|v7L+uLg@rBFhW zqfIX;LeKIn{# zPd=r*IEQJ437$kN4%;oaZ{E=z8ZI9`q&i(8(uj1oqv7t|EpJ|4(bPSs7nhJEtncno zgrn`Kk6ADTCue7xvXwB|GlBQfdx@2AN7>z+_L760kZs7jSTa;9s zKYB>9m~paPvN%~$R0Y>BUbDYl1A=vZV0=IA7jfdd*{lh{@%ZTzvZKXHg+LewQX#0f zI})9emlbGrw10=#s2yOp-5inj8m*J#vphm$hH+#Z4U=g+P^DSMbULN3Yn=1+eNS0U z$n%UONn#e_C_MIkPnKomdGTSxkBBtCJWI**EFx`n!stAQwqw2Cu;1+?Xb4D>lq}7T zT`OsH4|o@w!$Y)V?e+)8K3b!OaXbp1;)69ztCXUs==%{RHCdLErdbrw#({q5>4y&M zEC`8I3DsnZ7oK-_ckG)Ehom13yTgvUZ|Qr>bUr7UEqL~WpK$rfGp?>);B3#yYQd+U zf634rf(>kLZ<&@ka_FgdHGzVYvnBnZMGlH-fN$Ttrgj~(Omi>;b$^RBcigW#ZZ?J> z0y>4+Y{qWWv)?xqC0s1$OlRk8c7|!5qI^r4X?FYQt{M7{wz1^plJ8#M@SEp1ynVZ) z??>9+aea4>^_I~%%rO+MwWcT%@?7)rCr{b$w-{si@sEEGJ)58La{HFMS1&jZDKiqP zNkUR+wwsR0tmN?Sj%-xeMZrEVKqY9v7*EI`o0N3zft$NK&K^xcMz(P{D#=~fBcxzb zP58~bw=AE2jFJMSCG+WwL=jJHMb1j=t+a!tStVz9`XIfyx5?a3IYqZZ`*-rpG$N`Gb<)jJV)&1XicZ zm>I}40Y_F%(22r&Ph0osGzF;$N@C22CE`%uyuHH{7@gz%;R95bV;#J?zD1-t+rxph ztZ0Xklam!X%VIv|Zbw-aj6+9ORv2Sh%xB0Xj#ZnkgWyprMWq^@YO3k%xM&QR(NQ0I zyzfcplHK=~!=~r)M|0M@*A$|lX`*$j>!QC=CP%A|4ImW{9zEjv?K|FFy<)nYFrQ5# zks*X*?oFU|g0r5hH*b0M>NP?rzWBipI5}NJYtw!kGY#SWBtqc5V;DyCG1v`~BuN;D zSkj2#s1^kD`$LHLjLv-Uj%uB<-yg8nGPFIb0?8AT%=-t zBOEvI0b?!FT3kP%M1pgcw{Nfcvp@fH{)a#P(+{K47|j0X0r21@H00u9_&%fIJs4xSyS?N5?3{Mjk*N$nI>Hzy z8Q#REcjr7>#2)WKcy?Vwnq{%qJID{gyeNT3(wh$+b7Y{u-zE4E5x-sty0IonBzcm9 zO)#qGZg7M4BLo3YN8&L@MmqlZdE3rfGsw8O@QL z1K_NsoR-+3XE~d*-gZcxVuomOGFFl(Ly(YV3N0P`wuRQAG*Q*d(m0J#8K?P@+c$f{ zY(_Poz-Ei5qZI)yG^JEHDN#zIRe}hPB2SUT@40u9B*~&3V;H!*wG6%E=Rf}nsj}n4 zP%w6Ttcij4vaA^Q1KujUvxH!=0qjsYXi|QBxmT;VG#d}0E zj0&$byS`)7j3kE!Ee%0vyns}S$g@v0N_vC_Yb=czNo)+`Cy7D}N#-T(rlU0$dA#Nr z8)e9)hb5{fgojLJPt$11C!Gkdbwgf_9RX-Q;Pe$TW;@rMxOx+DHO?I*w;6d zvcNPWdm#D6x3_F2 zUm)`d`~88gcgSW=Yb2y8`DbT@+m`F^UNDg-oP0FFhJuYO>83f4e*c1*hH)F%ee;^k z-f|`j`an$CAW}tDPGj+|ibagoWJ29E%(6LN1kya=)6YNQ`tE=( zQu6r((JoQ@9f{U7yM}hxFss~M2oY8R4BbGp-jY{2 zpZw?t3|-H=?_M&grc~1zhrY*zz+^g$9a1vVCqsb6a>e@Q9d;a$S%Q(Clz;-#AQ{`1 zH`nhtJwGEWBVglV7OkG`%`I2^R|Fw=^yCR+02=~#yB+;Fa59~;zgaV1oPrQsy?x7e zyJb>MD9Vb_IqvT7IXyomP2;+VR`lZ-pJn~X%QtUWE*9j~G_Ik+M=Bx$X9t2eoL@X3 z%?kRyr5}eVS`;}$-;<;%X;I>lD6LROtMMYtSl?|pJ39vfP1}+t30ayPsg04gC1lLM zsYHE1%G+_E?>q85$2!mLo42?ixLa>`K*=)wiszM({i`$!fd~hrl^Y`jt#DaUz z>Dd`tr4b|}Vw*K0ijPXi2J_${$qMf7@33}cGN}+!pcF{0D5?^Cz?dj7-tBjsUOuET zmhZlQ#p@T}(=;`sY54NfPiPK-{dCH-O8EY}=j3VNi;o_$uUDKsIA^=vAXUJdmMSj^ zL!b$o?fQUIkQW21#~Clb+4I%S$U!H3tYLF_h4V{(_WU{8?AYuD^F@V~Io;S1(wuq> z42>nJ5?(iZo>VK+L^8OBTazR5b9@>&Rc9FCSnpm@4?V`G9QKZ&Qe+ZgEr-p4aU8g~ zJVT(dqhlCqRF(1I;*59iUh?qK1@GS8pp-y=c5=f1`Rl(T9eRE;T_FXOy2OTr(_+r^ zSMPXM%}Fzu=aSxm+_x-~95q`}O)PEWtb%4X4f*GW@O$|r3E`HNwbtBO$h>wHx#MB1xq3&QpX2ZmMI2c z=sk;hhMX_hwma5WHAya6O-m9SP9y|5kmot;T}!}{WQy~PGtwmDNb9y?Jd%t=k}=qx z*=m9(^8D{M_YB6678yyJk(5*VaU@le``wn&!=dSqDu|3ElS7U58C@UHV!#bORaG)y zO&DxoyE)*5q|zXQCQZ`gG$jVr+hJh0-=nh>l_p4`Xu1xeL3#~|W7FJnefy4Wm~ir> zpbdMrhXcxIcmz&(44$OOP(I~!v0!<&;vfG0ryv|6MAFf2TT`S-JODVs{;=lx^Ka?9 zj*mY2h?A2QN=mx6Id0~C#KS2?bd=aAw`zeul9!YcSRA^{NM#wzdXCuu?;J%^;GL)N zK9W78!a9#iGm^YS>4NpHW;&fP4)#c9MJK}L;Gkx@i z6A5V^Zhrj@E(rd+|K`6s<{08;+=XZZ^WnD#4d)$N$RqaleJ@2o_&{(T?*&0Pl++A^ zJr-yj+pa}Cz!*H+!=Bah1n**A!})-9=ELFU`t4g*vjxIKSJza<8KDPnJl1%;4K&-D zSvEsjjTav4V+mzhu8Ul%J3mY28{|1k0qc9gXZpP$D>b|1Qj8-c*n!#ob z1wnYGWzN~G0L(PrZ!=f4}U zWrCFsKMbUKfkYsbj1-ns;FV`MIC7^kiNM*O(#6kP12%{_^$Z=-#~eXBv=9s`NTz8< zt|duc;3RYo=naKRsfPxU1T-4b6e%=LYD5t9U4tzGZD+`p=5#7B21X&+x1OqSf!Mo47>RorgEf-LWR7-O3LXuyQb&yJPv{NIv%pM!&pZM@$l#bSm_wrEuYEHx!qo2g#;V~g%37< zzX=5Ic=Yg+Tnk?D4y{t0)1V+Yj|-C8kF;*26dAen7&9kh(x*0IuU_)HD5SmN} ziX6fi;(By*i{IWdoNPE*uIMt@nHp3ISek=jxAqK0%G-6%Wd)foXm=HT3&|pjB)H~) zP>!4ZE@o%ajNT1sQ)8UrZL{W+#S+^HL@vnlip9CdcXy;hGy7f7j~-s~>SwR8JBbJm zkttH0FlvcS;*{MwL#j_W3>%!0BuX-POAsB(9SAn?T^&nq^W(bmzI*3AZ;)Igdkyin*_LY1X7LXuV!^3{@LwPdrtXY4x!f{VvbW02Vf=Btv)Xn6C@cW5nH zo~*chc*eHv*)~1FJ9My&W@O*iBvSH&-~AEyx3}D^Z+CeoGIhsa@jKnFOxeu*O>wWMv1JluSwHkQzjsQH}duRlxvsTjWphBHnB z7)8Ba5JTkt{+_I?(AJ=Z;osK!^IwM8_ zAqi}aHi=|6tN8q*aKquykmot|Jg1tKJbQjcT_@ozAu?Ys7>AZ=8b3v;Tu42;5Cc)BjhY+BG`Q6o z7bQ*G)3-fC*CC0B2vu3&eBf+#1`_m14CtIAsDPG=>(5{F?z?Z9uh)F3EJa!J@!bc6 zxS*_-OnO9DHHUGaZFgMQIm%cTwPEbiIp*SgNiH?bvE^@m{vVl@8MP^B#mJ_yAP2(i zj=|*|?~nZU?{>U?dB*$44-8~{d=yBtOz8;$)?~yO8Ty9RdX=^;E~AS*ZQSzg;+*a{ zv4461IkDO7X-CiNO9j5goz3{+AOA5An+;$6>J9gI9WLf%I-@Rf1|T;DftJw?+-iF^47X2PG9rVYFzY2VAz3vC!gk>5Y(-X8><&k| z%@#4VC^vGsSg@!HCPtb=lcw4>W${BeWpc;#09h=Ty!r4QtJPVO^oT$gMlxZUmlbbs zKSH+RtjK8mfCofBkVWXH0iWgI9Aa{KAqiR&hQK1L`LMZ5eOQ&FGK><=S%4^Mpd#Y@I<#MlC*QuiVHz&N;MAuTej z`o7cPQ76jMFbp(JPZW^nc`BxR7~7A~DL(%00b5vY28I>ZYzd47>LMI=P73=l~ZD8$5@Z{G0YN9#`) zB`G8q`I4tY&*Q_6Wu0+xzQD{1WPhZ2|AA_GK_4P}M%LaklY(AMl>3(W?E{WT{OLCx4Rpku5C(kBczE~2ckutL!_YJN0^u1?n8kSX!l9Ajflmk^1 zOnt+ILP?E|iacoiBip8igcbp)C=dV_p^H zMJmvCA>oZp6bPL$iIJJE=||7cfBrXYn}IQ&gqtG0)`*_vyk@&AxLU1H#v(*O3VrI{ zgmh_$frumufwCFbudaCa@rj6`Ud#|ulb7Y`jd!9w9&pj|xIJ)I&(hE3bdmLm=r(!( zDgJeATZAmIMx&I$4HF_$^utIH22o{5qp^90>w2WNgweqi5Ykf4D*EO~KaR*aGKGm* zoiX_d=?vX4lADroO#KW$`V^;QBnI%`94Id$*$-=s9O%TrYFS}PIqRc<(Migq#kSCN z6VtLJG@890=wccSxe)NtVI#yM=i%m_tL2&~1Jb5VR6a#`XlZ}_mg0{;V|spx$VR5k z4PDm|t0iOHaq;Ye=dUtcU-9bMm)z3wO+I5p^Y+6>X4>K#kY$e1Jr;vjU~A2OY#5pI z;>R=Y2a8koiB)MLeLS|DUtbUeG|Ewwil@gratXG|apQ!NhU)5!Xme(Z1@Cry z6K;qvMlp(IWOX3?{M zeB#|#zo9faby;z7b;%$iop-2^E`Ht6)9)M3UcE$X#r|PK-0WDame?Xgg@B(Xmd~%4 z&1X0nQMO=R6)5j{xWA`wkIZH@S(y`EM94^pBO~d3{jhuD^70a`BnUVj8@w7RY{uvV z&O2sho#IO}_3~EBWrD(-o&_#=+Fe6Y6o{Bg<8DgvUZV~B!;z+G7{-b9`5D*Go@1>g z&lU4|o$TJ9|xHUxz$B_hO7_ou+QnI1;?adC%Ck^kc&LD+F~tBQrW7d=WVB zlec796HUVMd!Jw$fi$3g`T8}7{hqw2m@gJQd-ja|;c%h?2JY|gX_|)0TDDDt^q$qM z=EKJioL{Dh;PKE<*Gn!h9c?pm`?P01J2C{#<#WxCf0ps}Zzq2Je#_Ogpw=y4zR<8; zQsyh(eY|68_cTL~)P~zPJ)gh$46Ow7<%0YBN8Y}B&+FGqHtn9eTr*4oAuR8YxAcc2 z#i04=mzK|edcptlfBavppZ^#aBf_;9?{Te1a?SDSiQOR$-KAEj+;jQE6*u?q*$)%L z=urRq{Ifsz{lLRbXjfW<5^q1}lf6a{3)qO|7i{XGIfrZmT);oA>y2yKs%f>>vGH&Gj# zCIM2>j*-zv!ZcA>l?X*r(6lW@Rw5>eckt%jTh7nc9ETB+8QQ+3GL~6ha~$EJ^OS|g zSeVTVMmMlrFEBPy2fEQQh4gz3C!r8Zq4S)2m(guXor?;rkPw|90kLe z;soW)VsZ#V@b=vkMK#9*%1WAc;Q7nv6qRKddY(30x<2Lgg;b;g>4Y+dt{+YX^&XRD z$$}t6lIoGlYHkWNO~;$Rx#6&D>HL9LKX}2RJ5bCj#?v7_0>+rMsS%og{Ez>DVHo(U zzy9}(ene=AP?Gs-i3^@@-@fC}b-e!Kb6&i9!4y1g-_vv*yW^4Fv0>kI9J`Lqe$V4} z%l2^Oaku4hd*JTriO21ZhwYa8rwxz012^}N?3qn&2X}XGF@;<$$bTV)nn~LI);!{#;q}KGqh|N#V3Yi`X<20s=@9FS83`4ry zj3d@qo;FW>^UXJW{`nW5dKjOGQt>1Z;(G+{iPUtuV8oDqT%2N1lb@0`HOo^@)F*?5 z4}qu6hN`SUq#jCIPp1yhFivbYd)A9Hf{$z-o|u^#Vibfv;wO(EJ>9;evNKfF1Q8j- z$lyk*e1>#79q(j3A^Oq>8&BN~7p9bB4GKw$zBu7Ij7J2puxAJgT3ViVA9z-OffNNX zN~Ab>M^J!ClW^HGyUO@S|Li9~B*=)2lFcykzy0mc=_qJ}=CB_*j*-{|9)9^->Uzec z6j4SB1Z9+P^N9WG4fbKjXfpWnDt&HbWO2D5FH-q0tkMNe`n2NingQ|*p)_t7kh#GL zFg7PBiJlzBkEkLtt1X365MlJ`*C=N>Q<&1_C4v@$IC=VJBwJk2O@XS+d3JF|o#o6- z#k^P`jG-Ocgp{l*qEU=~N_Ju&aHm2e?Ldwt21B@OF-B1@D}3;{$s^xw@xOQrT~8KA zk_{l;1(5=)6SA_ zhGloNLyQu6a@hza)1T?ng%rvnXI56s${Km1&V?xGhCr`1=4wrFBjMN~gu+)9?$rg| zOyc86a2{h6vpUE45mOjKZizru*7)9&nFK4*LJ&kGn;dM9WZ&#qbPlx)R9OV0u=$KS zn{((!CaK7sWRcAYn-S+NLsil3jz}vh&gM+x#0jv6QW75m!^4I}HAjsQA6oo&hYA9N zqCGU&mly2UIpe&Bi)Re0E9})P{_vmvBi0L;x}M|Sa=RNC%QNmLNi>%J(4bKGK48i@ z%0~(g{P@~aOOLW8QATuGpkMrBjv?oZQZOCv7!F_aCx5o0yl#=RhV0U_cx}sI3{OwEu|v-)5C)y+^v)qNOEI5w|M)~%&%tP9Sz)pqqcwN8H!S9JY+jNt zSJ=@4j-4ZH0I2%KMD5RJiP8MCV3@&1R4N5-~i>UxH*C(HBno-9&d zA}yg$ZYm)t%bb8<>_@7iOekm>>5oTT*OSlZDFvZ5v$~?nGjH!wdD7H`Xj3O zj36UHoB{@8gLq zmdKG3IPUj&=g>AI2!Ym?JTKtXoA8t8=Ho{e^En_>+!{e$*DRI`=8KxFu$--ypCZlP zCx2L$Wv9-lr<&D3>eXaD2N4$Aq(1zKxD3>29~iOA?iKD__P z-R(WU{M%n~_qgHR&3iVx4O&Ug&!6-0VaMBtCpPVz`@Q6|>jkB_klTCDd*lFWKfe9&=aM$z*oh1^M z4E+83Z`kfO+&$ir7dav-rYJZJ9cLHkG);>Y0;T~+z$wMsclW%!c*VtKNjbM{_Kyf7 zF?j}3r4B<#ncmSmp7uMsp+jhy%+p#kOb(S<2Jboc9o;k{t-;u24vr{pA0Clb5=201 z%lQdeYhphOBTx-V>Q}XT!<{!XZRQyM#r~r-ZGolv|W!2kwep-qBZ{X zEr8G|i+_^Pblu3%Pdpy((DTUE=NIHNi_i+CHO_gOre*S}$fJ$s^=Gdc#)0=YAK14C zn!YDWK{t#%Y_@m=^=g6ClHQGcxV@npdv?u%?eRc6O$>fw-?r)E*Y`-P>D@%{JSa^! zPN*!SX$Me=Umt`-*$f{eMP1WR6XWUsM`>J0t7dI1LP&;bB+ClMaU{=k+O}mJ2DH|v za#=;&H3T9}+a&sw(HxEk5Q462Da!)yJ!MgRk`kH|naXB16>7Di>pI?l_`vza1?mJQ z5JKRcBgSwdtcXu5+Hk_^1@BXQ$|XldKaCW#>Qmn%0zM`?_-?nOt{3=Eu8h++=Xrd1 zVqVSBLNoOf?Y?DZX2c#CB7XEVyA~@fRun`J4#)Pep(;wa^k=F*MFMw z`XZu&LKg-9>woySG#*ANiBWUkwkQ{IcU$Z%2Om*~2DUBop{0JeXHn$npS&Rd`~}Pl zw1AKc=B1&|HSOUD(qOD*41qxjhG9Zy7Na$>>yRhmmm=a-M0v+}Y>}rDV#0Dt04qV% zzQ)Pn+MdOH&M>5cUVRn9UsMo;DgMc!xHI|M1s;$#fbJ%+6MP`0fpBZ7DK?$O`7mGlW+3VPcYk ztSk}6(hei#d`^@SrEThS=#1OP9rLS~_-xL%k58z@oW=7OlDnXJY5_$?(|361**gL!mujky|-XVpgC`%TL1+!Tyl1CXZ)?#!ToJy(C#^AkAoz7t(Kl!$V zkZJhmCMG{I4%3N#s8L3LIzy?GvrS3Cc#2~CkWv-ir=iHz#YGZKX4$9nm)7QV(bA_O zNlFmR<_n6dqUjnA$0PgWkuQJrL;m#7{)`YJZ{ECR>>8$_M?|RW1s`wkIkp3BH-gkC zX;?3=`0TSU*c}_bdw1Z_Mt1jme(>2jZF^)sf6l-Ce}BQv?T);d@#7!AWL8#u{BTR~ zf*>V7{r#WuSO4)Z`TX-2Y>w|4!j9f|tj{lTz!*~}xtyId38>Fr^Xso}l8{wolx2y| zN}@aRqsx-BdCvd*Z~hIRT`hTbCiyS^+dqC5nKScfaSD*d4aGurm z1;76GE3OwSR?9ioC?+LwCgTtys>m>_l84PbPlpFqN+HUE+1VL7KtJ^y+5;*k*@{wv z;3ldfBZhFoc6x-CblxGf(i^(Tn1W#6Oz5Jd znOeSi`#Y*q^XmGHdY<#<%{P4Y<_(ioY>r2AlTj$mi}Q1WpLiOMY^MSG$WJd`vuW;- zxuB>^qDoBuyZa}auE*x-3(3f?*m6(K9;7Z&5M7DQmZ zUQ(7h=jUt6GN&jq*6Stn*^K3UjDJ z&tkS94uS5_puEBcLudohr6Qv1CQ4Hxe3F>8W19}ovOq_ZY9S(|1J|dGh9E?Lk|J3I ziBc6sAgIV@zojTjGCf1ZoSl1M9389jH72T5XiOHv)a?+GpaQ)=^0>WYeSX0||L^`; z>I|JaA6jev&tLv0Hm;}ZItny#a8zv|+qSe%JBlEgyh{X=+aCS%5Af76UM=9uE3ThC zLk-DQqjF7I=Hx*kCP7q^o&hr&4euGH0{9H zjXXX+rO(0S(IR0`V~8wQ6;V$_84^*+q(46aQYx?~%SW=(5oONy(Bh_Kg`bG@ZbAn> z6(MtDSZ5{E{SGe_@%WttWVY|oL3^%3AZ3qFYHAZWko3J*C zM#s_94e63$tRnacB!n25rpTe|m}H>$fhi=ct>Ak?T0l!l;Stox*J+C?T9nv{QH(=)##^^+RlZk$}-)}MB zZ`XV1-+biv|H%)ye6?b;Z~1LEuv4kb+U@pqU4s`RmV~Fi%he+zD5EUmlt%02d3kW&zC)4zVI}|1NAH?n>D-}6pwAr_N!l@ znl zAqnG1@Q&SnkJ6g6t4o&aGj8wi`RZ4{A-ceByQgh?s>On0K2Jz|5s?8zh_vmIh@hxu zOhg<|orj%0E(9$V+~fwL_Hg))C0*hb(T|A z1zDz9Rx?b9Twk8EIA5cSocX*)L^y1>G`l^A`$x2rRLeOinTAYKA(cca#pB}x>-Cy! zR&r?3eK5h6XXT%TdG?DTUDWu7B^;Ql6E9=?Cc1m}st6THU<$23i3dBOxQ zmrIUqL!M`8a3G-{daN~Q{rx5_MVsUaQJ-Kc4j&S+@^DPDzvE%gFbs@tq^joB^_;9I zP}(4Ma=J9fBaaXF6lFsVajG`=(zsshtUu8~~c$u~xqnkcOw|tDLyK53?zhxLxOx_qto@?4>$A|YH$!yN`)f$cB2bZsT z`FuskoDdfD#~n|b9*;qn>GI=TiTARc+bt_Uv~JSzd7c{2VQg z^p78Taj~E@o_RjQm~*&#N#05cNM?zW(#cP2}3JYY%*O{VZ9yBaBKhDMN92!Qb7yA*g`wJL)KSHm_xv zdrtrWAOJ~3K~%YEjzn$oP0#+gr|UcBMUGaHwG>&#tgPtzAw@IrY}$tVr!61$ z2d>s@ip(;#J1z=Cj4q+wl%cFeBE>;VWlAF65CZ7tLd0AqMj6h_&-Jy+TiX%}c z$(B@_qNs?c{A1q@X)+(fCuCffWkeB}+{olcx~?TJa@Ok=`K%zGq&z|irfFocT=2Br zP*g>_!Ao%7Ayt~<36)CvQcJWoi7TBYs)Wrfh?wM#nZa6(wT7awR8^TCb_CAPRxFlt z>Z&Bq4YR6bKA*8%)T|bBmh+nRa=~Igqbky6qbl>{P9UO$K%J(x-c2VT3@2VlBnF3b z6Jy_fijYj>NnA%b9jpXG3hwV87{`&b_3BfOUBWmjYW17 zQ_~`SM7xN8+A!Wfv3&6ibGfEm)d*t=N?~k4oFYxzA+!d^r_N9G6X)jzdFH6AB##=$ zfjraHxnWjVtcDl^(-ir5w`Gii;8T3D^Nv8EG?p^6WIDaM>&fFDcBr~SJv8WdPn7C3 zjcXku%kUSo6leOdJw=!x`Uxph?3576tU`+9BZ^*7l{LXnR8_)q3zd+?(-3J#$0P$z z3kH|G9?3fs6B<`3%3#QyNiUF7oauCHIQ^JBHFHiBHXuepBOPP({O7uA`p#%W=`?vX z=$M3vUZg^_5-P=~#A!qF4=*T6oGz#Vl^a6zDDMf*aX9YqO-t@UDa&LGqHE7Ha% zhV-niGx~=Iqy{;!$jXdmZpodaIA1cM*lc*$id+^d+MS@+#PUF2ecDt zQxJ&swZy+#A+#dsiA)OWyuh7c7}hDuz32AdeT6=|AXb*^tLMnRXNZE^H*YbfXASCK_DC6GPoYXNL~%N^$QwTQ#N1oU;UR0e)7c}6C};iQ`9-yP8b;ouHtvUYY62v zL$zkm5}EY%=qykb$@tv0j$yM$<(e);P=+5b&-sI^m!u<~`1Bh2&9~oj|Fk`!$}RJ= zYwqvwQB#ld0bvYS3)YY=YGh`~$_j)c3V|s~gvkiX;Dn-D)*PCKXD?qe>ZE5h%A91L z4ZH0QsWi`DykL2D#+!HVvBqGn!Dxwd1CRIjfMC8{l9eScq-Q{w0@6o5y#I*vf%EHY zgf#>y5g}lFq;HNqK0cDqD(2^BWc8e?p5xub!@IXkUBlD;9gD@1vYwy1Ndo_U53%cc zdU#}gb;11XjCSZaHV4Y0AXf^Ujn;p`7E?++9{MB<-=VxdiC=|?R6~6BYeb2>eg_%{UyB5-B-ku81$K&Bs z=TYml{rP@dHH`zu{>s!jIr0?3~^0FB+icdr@Ap~x6bX|9% zT*B_yu-orxjtza^rE`eUEEh}iyh73*rE~NE}RO-|vQS|)? z>O?0D0U^{0ODvPH@Pw*Qw(=Ci^DgNOuCA}?x}L|!CyJur_V$Lh9cYgoAK%^b;lnM* zen1(`)x{;&TDH4A!!#g-<^JZLXXi_<7iZMvjCOzE{-Nc!zx@@N^*nW+(Fw>5N?D3L z=lN$Z@G4R-=gjK`y`Q+byF~_IkYuvNxri4NudnCKL}35$L|sn2ytHh$JK8a@d))By z*^)nct$AHK8lUkOfAcNt#WjkIfA=4LNnpmJuzY^qv0hc=^B<%B$Metre2ku}*@ALj zb8HT*@)8vS#}m;~&1_ zCs%872K+Rnym*|r*&mpUAh$E}QE|3dC7(dsB9&om2YfdnfWg82c7tQ$&>ir?QPl;? z2!c}Vn--Z_x^co2*&UB*{U=D{OaaO!WZmJ=;E@b2GGES+HsIpKp*gbMca*akI+GN| z8l^LICP6vIabg%F{opV*LugG@&<`UK#pFClPA}#p_%qfpo6i`A5g|2Q-=AU#Dfe8Q z*0)4Kv+D>xrihZ!DLYBBV}9S$&|2feskcBtYeiM%TtB-cFD((z9-iyfI{o@537-I>Pre0W{B+rH&M|op zHchI6fauc!?$~x54hPC|#xy1gV<1I!-hTIn=U2}VL8bWB;OX`al`e^6#0`$F=@3DX zs~j06J_dH(ma@pnghly;1$J^e9TerKH+~@#F-u7WF?kPy2#jK6f84W}tN!T=Jh!uD1Q1+UvU0>g@_SPnpnO0`aM7Y-~S)n z-+#az8w5}&jfkFdR^f}1v6QGfPa7{6=%r_Tv7lQNY=@CaD8dwRo0iQtAL;uZXGEf$ zd4ZLh!_EB(Fd#r`Y>`23IGz>g^@2>NEbOt}Q`QUo6qu$d#RX95V5=p;4J_vxBL^}a zsI!cVOUu=zVZBz&XOiG2M6@&qKxYYeJvzpI#7lwDia1U%jTCuCX)H5oXg=QKw8S=! z@vD!NHwXN_rQA)#U%w|i3>02cs*2oZOzjbZLnAOcqb}6J5L`xlL?F}&x6jz9WIh3o|HzUkOD zEuZ~podk@OynlD(uYdj)%9kAVlAa8Y#RrAW!AgmD3g;m-171eF(v_;kny04?0?p#$k|-mOZ{9N3hM*)E%K+^9j%FC?C&%(^&EsZEv0Ndt z0<6W0z+u0k%ni3UA2@&gir@o&a5URJe)23AORCu%r!+!o=JT5Ue#_It9TLybx0s@& zp3jL&eu@&`eE7)C{T>eI4MyKKCtR%`LStUfY zP&7@;Fio62zowoqX%0u4?Ut*vHOpm9S!Vc$Jy+LPte#&{t`^C?l@}})b8-!De)ARG zZcka26!V(#6lSmrTP*ZZe|xY@aqP&(_$Y0HaXGBXAxGmX~RR zt|C$hK79DVyq;4QMcN>T!00BLCb_lxVc_ZUF}cc|XL5lo%ULYuTwY$VTrSdZL!`-@ z(rLRENUPigdT|)7&^Dv%dLocz$pO=}E#v60HalUxQ{T*m@X5P0O)f>Mq-2^V`hEbQ zu4}ya6@ORJ2Hid=byh~8a;lPcz5?eZZo#`8qR?FEfozI+V=)4zF*1pcUwwVcAN}Mx+g+e%;xHX~ zwY)-k&wlFp_U;4gvS#uDBPF@1m>5yn3`B?X8kJ|XhbJzsE)gbS8k@dLSXwF2MkAD9 z*EKB97F1bA;XK>jk#3q0!C`WVRTaCYqo@nIsiQCpMi-buq+S-dI59cF!^06FEH3WJ zs|utb%L|Mx8J$a|;m13&q9g=|CPPM@kaO#b7$iQz$D13pHHbKz`XUx>4fFE_z3&*> z9^*8#ixp*FqC&cz9}Wk!wD=()g`%(-F$QvNPKS%+K~XYIG}P(e!~Vc}y~YJct z&35g|(ks1hwyWLkX~@Ga+RT)cjg;k-gc1zcb>)JuEc?oD;K#_9@Ke~ZA-F-gDFcQJ zg+f6oRaK@^nbAj(LGrY_U+rvsF&CLdfHy%hHo?8u-1Gm(7~hC!3`5uBr6&LcfshuD zPil$_2r1A~rHigH1R~x!l(hsE>0F1E3Y%-JF*pK33q+VCYXK@(m|T$wg%uiE6!+EM)n5Rrnd4^b7Y;JVSI)cj@ETZsmN5Gh8Z!%HoYS0JAxnrQAI{S zPRfKt$dscH5f1H^qO8%rBxu21cZa|-&*u|PHL0A5hG-CsAR?_F*bN7soqtF^7I^Qt zeR<@EzW{_r2S9l~&1&K|H|VE1{?DG!%ogx)!d+iu7KV^{{NT`o!7WS1pFHFA?JIO) z5GF$fuvx~?cASP2^}0gb?kHAI*zWhJ#-ZnPqL9?w zboe0Xl}Hw(p+!ZTiVY*6EiYdmSS<_Ib4!d3RvI!b=tf5nI@uhNND**Oum5c}d>lci^0--6(tD2>BjME@-beH-W1KB0pI*>!9>}h5@vq;&51%8>7pT5Ov<+bs zP=YB>qbahSw%Ze;ONDyf36oWHU7yqpWe5ref5eHAA@mH+p@c@bWS#065mAvjgLP&q z=}WMHDTI_}fcI_~F%>cXL5%=`l&QU!m>>yON$`%?`_wt0rqZpz)BrB9Q`>IpqnWZA zMEWtQyFvzx2y|VK$}DZ)AfqR@0%-+Zvm;QT8VF;-^*tz4vfrLkhA2wx7%{C(_-X<^ z_UI@E!J!915xO&~SLWW#?MjwkIzgLCYz7b0l*eU%za4d8v3D?)l)uB~gNDKq!YUbNUCv zzxw~a!0VB=-%^zs)w$z-zv18i+k1pu;DY6J5_D?7tY!%i(i+-9pz{)`0-hr=3XGNz zTfW^~GXgouhWSndd-3!sP1`Xs$`k#yB=f%Lg0uT zwmb3=S(GKlmXuk=;jp7#YOa6#8MFDE5m;SbaBO>`v4og_1CgZK&1Mx{bKvI98=gFU zfm0?8(xci#CQ&fAE9UZ6(vi@%+&lw16E)5U`nILHz2)-LkIpqnK1J71{0fbZv*VIemX*90O;UmsqPYN`MG7-AGxl z((Af`Q`@Awg^~!J3Wu#V3BimcpU>&qp8M^d^3H?sD~6%xkRAEt*%SVszxfxeYr*AAAgpEQC9|`d+4&69!bi_vAj64oUVlxCqCIpR zU%x??Im=mOQ5b&s;Rj?z#m6r`q3d_-Zaco*K0uq%ZT4JW-!q#l7IlU;Yor^wyYJ~1 zIrh;r&hsO`|J^I<`#subeEIT*t&N;5u6Xr!&*h(j`mdk=(JzGx%&kR8#mPB}vcgs+ zr+(z~-5tOC>MO#j#rcur!#zJZzhr3y_f1bxoRP)AI1Z_8S0vW6l!9a1kVkGRvrRmZniH2nLpC3ug0*DB)qZC(A0L@c7ts z?2fn?spm_Onx-Fk*zPE*lDsPM5e}yYq@Y@qj4sf%u-gyJS2c^ZWwuOByx+e3iYOyp zKjMR893{qPtj`wc%;LP~{$YzU=>lxC9AnajDK84f(b050AtX6Jkr0wvWUXPfUZnu1 z3*27cVYFeksIZygY<l_<+CWmQs@6-8B`jY>Z6=z)Zkiy=_V3WP}Q z-XTVswn-NntB7i%5Llf`4pow3$6>^j7HJGwS&-*BKBi!xFbZod)+8KoUX@sDQ>ooM zT%1UKELKUh5Gk~+6~Q^857b3PaDEybLDWI|%4LQJiyAtWo* z_1zuk=NBoP5tEm`IW_EeJJyRc@RI1j_nzbKKxrx%(;>S%Zpmau&h&2?1>0uJvR);7 zQ;@vNsK0ZvL_{J_k;)3SN_`H=3=`PPEv^l$igO~0CbsO3TQ1jEsF)#10~J#?BV9%% zqa3*1e8>6XDTOK!A#I7ON1C7f5*AZKeOq-*Op)n(r6^mHw{>UAkc3QgP-M8vw|vD6pI{WpfC#4byVva zv&paT`;m6vW9vClcy#ayiLAJ7*3Qo;P#4wIfmGh(+DNEx< zoOg_aV-yi(G*&{PH8RRnb`-$h>==$6aamzrJVIS8F-FtAd_(qdzzmLdvxD0`@or1r zJB)WJ0GipP3W$i!^z?Ql!jV)GZ48LyNlw^gPZvh|3HC9JBl6wgDIkxE+8gx9M4=PY zrT;(rF}b4Bkno4%M|V55So4?b_I6hjWhDc9_8Yd=-+)#p%w9iM>I1@eO?gS9$8q%z9mS((6@+jWL{Wu8~EWL{eXTf*dHri9+vFg z8Qa&d`T8HfAheOZ*TFkCck>l$*dWbC7MJyltOSiwg_F& zokoUjLqH&{Wdvm7_~(E0XDp0O1Lw zQ7i1M!VAHONP*PZoNr&fLK=g~av&1I_Ws)zjy!E-tZojy4MEBXV$byCcqxTt2!?KKph= zD1}!EsL>oxoHlz*p0T>PNT-=h-+yIYVTIz=SKn|rop}1uM<}J3^gV(EqT{sP5QdR@ zxk6Vpv(=iu88~h>Fbv2LXqzK>l`~(>K?}~-D`sVhQ7I8K_WgSs^zqox^*z$2qC81t ze|LxLIu;jaDQ}=OtM!`2YQbT@<9PqT@&1<8`I>xI;bjV>%ODY>#|YT&cLbw&{>di< zpgA@S#}kT3t~FiLGL9p&#eygm(j*g|5`wBMkw{*?dWCZyA=LYYqgLrVXdHW*_QW`4 zFqKwR^BU(|g4c{Aid0~Gc79G>&!_W*)NL}1bX`Z&G$>>6AyCyd{Wy?k8MC^^D8cD; zqAZH{P!pzeKx>mMTvMM$qUnigk&=p0iKHG8qsfXqxlp8H^kG8ryJ^8WVvHrkK-Z?m z@o^jxBDqPt3rJ}gM#r1CH%M*x_S^5dyWg^y&-v)1kBB}|CD+R}d6DQ{Z{OY$g`^)H zkDor}n{Quov)ggAKk?@7$md@_FoZeXU$Kq3lUdfYIm@y_D~m2Hr?FuSj<>hB*fNEEf*2Xx$nMy%J9T7L zMN|Q4VT^)mUL%cR-<&u!4IU`x1?VAp{!GTH>rh6}4G~1ie&3SUhWVmG+YE%E>5gQj zK^i#)iF_LJvJ4-RB-jrli{*;4sF{?j7f~}lHal{$}F_KMNZa288W!y9LJ!0~A8ewkGs}p>G*Z1GSwYeDbB9#uJ&z$V83|$sd}A zi=fu*%Nfg8MNc>aL=+@Q^*<>ElQ|qxJb84DI!it z_QN$w23GbFG8(*$AOfb2{N;cCGlZH#<02q4%fEd2dv5ER{pcBV1g+3Wyn)fXL;~v^ z!5A7DDU88RwzLo}>SWM7UD|~wXDk_T!XHC-A2*MK277S+vzEn7)F-1Xi9yN@_ zu18E%GUrDYvqkDlP!g3qUJT6_{oZL=IM$x+gMYrW^CI7t{bRl3p|0`3v|@9 zgQJ|6^xYAYS!9vUe3Zh3kgS>}OM}xeG9FKeA)t00b~7X_&$491ArB{teZx~PxjI)U z9(Z=CXqpY*e{qNY`ha=)hOEetKYEUNvShxl8QPv8CF9s4Bq*WqWDM1kLw?5Jeb@8v zzft_=o5*dyrni^e-S4Q*ub^7X~gZ@WF685RhHB$;}`2Ip0C!^eq$Oiwc>yM-~ShcRuq|~A9~8w8dJ|` z4@ZXm5#>C2IeGo-nqxoWm122*!JF&1JbruyQsad{Wm)Q#5Q1u5BZc7p%{9yAl6D-D zwRRkNxVvTOd(JN}QO1Ihh{;MR;>g|W*J!PH^1%n#EJv&KT_B?e=ec?PhIu_>v0kIf zoMJY|jgH^{<3A#uc8avtjIea%0oN zMI@{77oY#0_1QVI#Tp?~Ib@z^6q#XncgJqCr9CyQ&(0DkM9O5poUBN}d$!vh>-9OK zPv^>Ew?`fI_?>+T= zMp;!XS1YR7jCxk%$C1qHMtUy{kX2?!I({21+4$ z^5`68Wx|kGM_xQroDO@c@|^qcw-l;jcBbiqpvnq9c=nt|7zSy$c=inS*H1tFCBUkl zv8ZcK`vbqZe$B7nzT%^&AM?{EA5v+PIx)OvJzMdcS6_3!thnuZM7AUgflc30DSyz zVk*o2v`>8t%F>Sm7{T&uYB(I*gxBb86e^L#^nBo}wzS z6QkODkFt`oPKw0-u;<&)zhgF=@#3TB)U%4REE)Rb5%e)_?2WPsn zCx$~ys0;LRfmzNGT2X63ZX+Vo^n-`q6C1~HY|&-O5F%Mo!!Qzkk18dGR3<8vB}Sj{ zt1vstbeH|%$RK61kQ@f$ zsmDKB5EK+ghx^SpRC;$GwdiSg24(s<-k+mJE<07%A}>iB2LW7cYQKK3Y_$y zB2guUMFTTsnA?KfCp%VBwwNv-sqhjxk*ub{M!qAs#q|5us|8wsA4lqXmTXo&a6C33 zB__EqPTVoumr_CpE_ATs?V2E(KO+td>i_6Z(Pi z)M8PXW5V!3sp%Vuyh;M#Ol}YO&`+?|Ai_-%%VC{D-=l}3qf*)C)pJA%BeTQ_669W6qmfdd0#q($A*^I?} zN$4ESc84E2z_Z=mbAEA-K$7X4-~cHI6X;2bv<%eNa(8z}@E-k+`s7oG$-~1vRaN5w zlVxO8K{cNfgXehI(KSbmQk<<HFr9#R? zdn(G3s;)H zNfpY{@H#q2KaTI+C)Q?ERl36&li@?))vH$&MTt_9Q7M=<13;{rR7g z7a3Pqj}Z!v#{=V#1}LorXUip5k1x5odBerU89)2UkJ&yv@bR-333ILjPhVUygpQ^? z@lXHq7d+g&LZK+>DE;^B_usSa1=aEczJ2+I&tARdZ3i#69bdkDP19@%u3^1AXLq{i zp&jXcq|O41xh4{j&U5uFCyWp5HXZl(M;H#Q7Y(M$k!Hp`FUT@O8x_a?z$ZWa81>(N z^3z|=s*1{H++M$->)I67&PzU7Kfy#mfg_}C&=4^ye=?(TCZ4FAx$SK7y2yS_@`YBIAe#v`#$arXR_QlEctZiomLp)FvmJ zY3}z&j-6w@o^iWv2sl1mFVIqOb2xIi8yL2Gy6(jJqf4?P$2&)E3~n45eNscTHr(wt zEY4TtmBm`aX1k{wd-5tv+pnqXVGLpNIu8kFOJH@jVsW;_<{ACq*zWfr72PnTO^^{R z&MKZfU(*dIj!nbsw|5LGy1t`Y z%#cPihJ;${y(4N#)bjmnLdVU7>@G9 z{eH`{#fPY95hx;(K$!lFBqDJ#aJ&7I)#8d=&PiiS00}AvdOz^z|Ln)iR#nPmlb-We zZ~iUq@iW$!GomPInjWv92@$NpZ}#YRL}Z2#p_2htC1c++Tdg=YE!k>Lw32Xau-4G@ zJ@$OfAS4>drDX6UE=rWh5Kbappx+)@KE0w3X(N=yg!9aoCAl_8FH(~*j;hWOB4CXm zgb||^d0tEuH%SaIj)AJ2vEQ9g(vsN(tk6PG>5TT&5`CaD2JgmX!4nc86tZ)$Zy8HX zR%B%Rf%wH6?DmKh0q-28vPcrlAhG3LYO_@e?*skN6JkgiscAE3vsC^RMMS8GcOHpG zqEi@ABxe1*T2QDA;{|2_6ZQMN&>w73@5a`5=vk2Rohrfm->bDm3CN70vX;3msAWbL z6mk^rFE+_8H7O$Rf68fV8YbIR`Xmt{GYV@J<1nB^0%Ld=i7|2VWl(f3GOm~K(FKhO zL>CCt))41${XjKepoC;r7Dyqei-OTPaDk!i2%$sYzvcROZ~5J49pdUQ`0ggKIgIEc zC-g^bW;yje`@22$>YOpRWF}|Wb_AQ@k<90Fd~kG!15%mP<{k#dro%No21(v~)P6(` zp7L@{b-Ctne~)WUWVxlzDt`FmCv0!O=iAR;F}&GhUvDV~OIH+(fBX>#Wvs(WYP-B6HypM25p#?q7eyo9`buoC2pqlf3qM zg}MBQzPx0V21g1^E1?m>Fb;vrWT??i3PVAV0kz%ni7olXAO9H18r3MVC}zQ@H#Ue}Dyad~-3HmiwNA%#SR_s-CF zM;u>$_64)qjI)a~w6#g0j)A60g?;m?V0nIqw>c)H1=@T$XLEPUtFOOeXd5oiFDREw z1|?F)GzNS>vb%fWi!Z*y))kk}p0YeYr)gUrZf~(lp@=+O-yn!A&(E-VK9%D}d<<#9 z7XzW|kVKA$J$5#u$SVqCn3V-aM8@uj5s~K~e}v96gcQu?GiFuAVYB7k7E&d#~DI$2mo&)9VI!$98+wB3jknoT$G^7e+RTx0Rv9rh?0xm+)qR~1cj z;?y_HZJz8KJ~as|qlv+zY|iVuJMto9ktu2&F(M|QlL!cD7-LMB*f?-mm$=Zd$TU(q z&euzR`}G^nA6@Y3w&laioKmJzx=tzFX5f>{EB1#S(i)-=^j(iN)1*5k9OZ;1I}Rso zsTlebS#79iH3-dS*Ra{`F}Y^8EU|f-Xb;CkfEZlboDa^i+aFk8%$Thz=8F}>2;2P; z&&UuOq{;|b#?e#F(q^fEnS=ZlsdC?Lr32a?Cy5V7t5*3L#4^vdr*SG zCwtR7gssXfQ3_P95k@lvPd7Sx9MWjKk96ZmdA`Dw1^wt~+m5E|(nV59gf=*z!sAY) za|(J1`%UiEHdi~%QOvfoJ<-9RKVc#kbJqEDBrwBDY z7-O*3(sdn>%ECm1zV8{`_}(7U^({(8L=0$|@6=zYf(U7_5F`&O$z~HK($qUEl_zk&-*Q$xLP(8Mk?YMZkLJ(F zDJBp7BvXs`$qONNB9mc;^s7qNPTP)K8?1p=o=Fg5LE=31wMMxug*xVQ?K%r7fKdA}JbO zpHR78puB|6WBQ2o5*5;y$sF*Aa%1Dl1S*gEbt79<)N`IU**D?QFe7WI7#nK5)0$aoQdb zF|s&6WAXSLtu?Q{{1U4o&2dlDoG@9&e7VHtIYJ~w*K3I0aeCO&G##_$DlIqqfvT+2 z?-@o8+Z|ti{sqo^&d(oXikeX>yi8@p^E~6`yYKk^yYD!=x}cbqsn9YCgfT=38F0M0 zLrB4+7f-l+@|ed@udqn^_Qc~yYfNwq`#siJ)=#e9W5Jmq2~tSLabR@G4m^${Wm%<$ zZ7EW|3c+c+!;8rL@(d?IXwBLBoVu*oJv?yx>NV|l$K~ZCY+Zp$s$*IoB&%)PH9Xuu z@WG1@G0L#nY}g$Rsh`7ItW?}x-%?dGs>L$(PpH)6QP(BfXo!Kk>+1xTDRRt2y^KPj zr6g0DvG0k&vs$mnstRc=gZG?{C)(o)5#ZrAwZvy-g_uZUk<{6vwL&TqscSZ)ZCg&K z(|emflO^+XJf_lLWAJezNsha2Rvb;#kwi+T*%CjT`179@e0W*#{mXmWm=?4a%c3f&S8F;7 zqRwc7<2XvRsAyYHHY>?h!DhP$nbEfcFTeYSCoeui{q@ry{PM8bA;uA91bJPcN6Gi? ziGAN-gCLW7(gsy}v!$k})(9t9&K8ulp(+bDn_G&^k|}`{usiOlvJ|pW)08KqfZ&N* zade&-9A`yFsX&Qv)?286YH5pSh%+T3v-O%U-rTW0bo~6|6@Ex1 zDIzbp|8~Q(`6`v}3GfKUVWcW@f&i%mio}}F%A7v-*iuuL8A7MMVxzdumqk1&}4*|Bf-Y!3%kXDgJIbfe>V4D1grvqedkLsnQo z^83$TrE)M5A`%q4{gKt#8Xp5q+wt(QBOpLczCxMyjq}Bvs!kKWF&X!Fn?xQp5oxDV zH7{7KR@gd2D~%gGzxnk)Bu}M`$xE&?_78iMF${i~0^M=i04TIINUdr6o_V0MbwgGmzvC72#hMyJCC+gsM8o^Zs~$cVdxNXF`$bKX*4EJ1&^ssRwP8MO1^Gw z3|NJiF*TdJk--fJBN?NoEK7`1?@QC(Sv(S^U%a<)^uzFe2pQgOOot(b^|S&3{n%ry zCNm~^$3s9!iOq`yJD4^Xr>?~a#kf0>ON-K)=6GT*^>nEWs38)1$K7$y?BaaF4@X|V ze$A|&Q)DH+b#$jD5yeJ9b83(w(L7GaBi382&JaQ2!bsB}Sd?>QOjy#O(k1R)F5}%+ zT8N}33XwWN5NR+tv_}eEk=Y7_+&DL%vv`%N*5qxVLu{>m|E~E%Vh9r7c|u_yEyMWK4lkN#wY_C$5&Dtc z{s>A@RyCvR(s|Z9v@*EpiPu|-JV%uoVT|@?jmgc=`ml|@JY=%=NBmPGgERjG708%A&HTaRt>IAKj z=}a7*C&-Wh6P^S27a0bOK)d5IxU$@s-`M3gcy-PIE^&NCSku_%l7Vui|5bMMMf*)^zUmjOO_dg zj0hhYPH6y*+XHIvC}l>MD^5D1x&d*s#SSAfht1m~Z+?5jtj$q7%h)Sg83;v&_~{4K z7d6$`vbtPQ8O109Q5IBE@#(_S{r>NfFF)r`A7zxMZ`i&0l74;8sZcD(d-D6wc{Z>4 zPyhU9_6V$g}|De5ED^Jg@IhdAR<~@eBYC8A2=iM zS3mzt3Y9FA;ay%V1pcT0@qgy(`7=~qq4J!ntPn^7Fslo`|N0v$lT&6nqY}s>!(=(q zW~^6h-n@Oy;$qFrfAIpF7X%^k zLg7O|$D}-M9yX{f=j`H=vR+Ux*R);FH(z{7YzJ;$e$VaAEsvgDVP`c?Dq;ZPLAum= z^yd0|W>v{2AAQWj?HzSpVv3xiDk-eNdXFD^uAV*R(W6Jq>Kd6_bXBmZ3zjzH-~F3^ zL*F)BK6`?&IYMRWIZJ*+VhG&b-64eJ?BblW^K)kNId9&)neeFTVt;#cLou(ZXLBSH zBMp5&plyaQ8W~1PsmYY);jl;K8B!#;O28q#V|R0lZ$}o$mJcMr2<_ zR+UK6qD@E^1p^i=z!SlqdS<}CgulrnLx2Rx0~O5FG zvNVmjK*T*~@3p?>eV_N?@quyntXXTYLgCsTKTcd+UJw8;BokzbwXqnXc>3^=Q^<=F zVRVM%#MwtC@&KgoI+n{NQhv67Q0Rg{ z;A!{7(n|jHvkNZPfw((SXoHi6c8HuU7hIn=7}H>i6}xSV_X6h>etcnyJumHv)60?L zabg%F-M*u&Dt`L&KSBME>oOn|*`OjIAN)SjO^%H& zdAnZm824PpNI_!T9jK+q1(t-Ow!|3FNkLSE6p1eEO9NKWxgH+_ z7n^gE3m9c`61vDmjGxV8B3I!*`ZzwysiaUp8W??;D4XKP04h@yM3Lx*7F%R8*Zy#% zw1&%~p&SLrL*8;#2uhg`{}dw1r~Ez`L%CeyrJy|=7>9|=)j9oXR)|@@AoJ(7+*JJ8 zU;YfCA|H*RyWsiX|Nd8;`oyV^q?7}W#7y2w$zh+5#L^-@yTOzd#ug9*!(orQxnhzE z)pv}KubAsA#Z(F$uiS9;CXmxN(9cIc$$;T_CK+#}O$M zAqs@bM3lI15n7V!3bP-Ozki}=9Wn~|k37jR)2sC9FazL5LBbvWy@hKxRlnzO?5?bUu5TFHJpz6qr$uLP%nW z^R{e;4$QK-m~u#H-kOChvq~aQ59fDFONEk#l(Ixt>yMPQJoFJl&G$gQ%pw0Dnx;Z) zLGOBYrz2VwSXH8z4eIlAx(22&QRo7ZO%TzBIo}T%K|LfoL_22%A=j}66IGXy% z|L`w=$~V8er(RY}UXgD9n7y#rQlk`v=tvP#2v{L7VW6;*PC6=UDa?}i;XNzm`4|7y zzhG6?BoRq7_7o}jxButA<8VB%T(8i!BBN<$%8 zUM~6O>%Ze>eNNS^s4lLsWevpqyu`rk(=*dBp|s`Z%P-iRUGRK=j~_=CO`TESm=ed=7p7_Clg~fn z;>}y?%^7!hH^gb8-)}i3tL>M*0fkl=SNljr3`u&kYD-NdvAqA?k zz{h}+xhZN7Cr-N~=hrtlt+GjZb3s*>bf+U}>=}-GV(?j_l@eYEGV>!MV&0hU_6M5v z8e5h4;Mu*t(4BfVs|BSs5ChLo&pDYrK;N|#MFmnJWFEAqdBY!4BqAuP8a1mZ#(v0y&KPk% zpk;=PNG-9I%?a)yu{yuvG)~-acl>bwz|+esyTg$WA0Bw#Zt)~8Z*M5;nzPLr``s2& z@-0@3$-p%edR}?jL>&c-9-srhr=hz|CgI_3D*{iu~u_ z6@2%tL&Tnu$nG?9w_Xy{0u|tVeV~w+q;$sHFRu}W!Yj++b%%_weSIO~>0O{t`EE;t zU|Fp(ZY0vPS!;g!)z47>)9p|GN=rd0B`%DF7#O4AX&hM9D-MSpy3lBmk#!*noD>{} zj?481Z6&+Y3mXKDvAE!|Idh~hrg5rA@JkC^{S#20Zqhei8U(g z>x{|ze<_*VL}9WP(x;Gp7SVISGIlMWT`tk4U~-uh@UjamWPw7_35bPd><3nLjVW^i zvC#&l4amfl9Nl~{4BpXo9iB+BDDsq8=Ddoswp?7FA&ud??_YU-*%A{hRt>T+2xA#T zKvxAQ=-j~Q99{1y$^u)MITgF4?N2n#l71KoY0BYZa{x?L)%3&2@zC-3@Iq5pTwI;A zUawdzS9q7rGs86gxTYJ&fx0dcTA`FdDofW-bi+WHw?q=jyLa!oy}Lt{iev<)u24mZ ztx8_@FC4lfO5~TLSuPMdPp!R=^xc4SSw^LcY?cy66GC8go_6fKsx@+-%mBRuh%T zD^;bl^vDN_vY_vJQu;`gnx_@U;^s*O^RzV+d?Hebj6F5EIEpb#Kl0D{oNf-Bjwg)P zlql4gND*G=1E4V_VP2`GkSDnj5Jod9c>i$E?Zq|Yw&UryKVX8yNJ}Y8B#M3-Xk^9V z*ivCJ$>L&e>c(-TDVsU>Acv%V6fA$-X5{8$w)UokmV$&LsKEC4!e()aq#|g?!|MZ= ztG8HL=h?QQ%%=2@<*G`7_J;?G%L~%=IcUQaBSYVkQh?QpASKp~jQb zUIe2VhJneC6!Z6=iDNy}I8xLlrqH-)qOc_o56@_0u~kW-6>iG89Vo>(Inv7!-#lW1ptX?x>@&ije2TxjpuW3CSk!H3v1&*ppVPt7Snug0!baRZeSYW14 z%@^`4gPwo(4+J+Mviu>&^rQbHrChM&Iw?}v?0<0~4_J&cOv8kTiOqULt3iEr%e1tp zDUeP{a@7}+s^V!Q5h6$;%WObY-2muijQ$M1PBk~vs&J(Q0UDPP8 z5RY5*FrlQ#-`Q+b6-ws!34vd25P$L&U2vrRf%V-59zjf!vMzbPe?cBPhR63TYsun# z$!fjg?$a;WnJadxMjSf){d<1#N59|~fBI+q$N%>~aCf&v&?0Tepa0Wan)NkX`3bJ5 zXqL^7&5x1-EkTQf5&65Ys|Aay!3`s4ZqH{|EB@%qf6VQ2GoJ?%nFqRj{hQzLpMLc# zuJ7(hDhH&E(|`~GVJvo0@%sA2X}4v)-eAfar3+kHA)AVNy(T8uz3jQZxkVcbGs^tw z;eqyLPhD0lFVB&6i4X>?X1QL|ACA0!xThaZv|++7R-A7xan7@AI}UA&??z%j^7`^j z6oR`iKWB4&#dqJmL-@dE(I7=6`ia-q7v6sMDQ`c0OVuXV5RM{}?9l!hL8_vptI1QYJmW$gPq%FuqmV6=; za#8;L_=q)@x$FUD~G2S zl8{`#eM8V$y&_Xi8&5IhY^e7ixPJQvbH1i&7IcRbPtQ+iDRZFU;lT6L6PK44NTV4h zM_~(;Qdq62tCFGX*zJ#u-jl?vgb+ZC$OOc|)8i8{Cd#UsZ(T{fSkZSaV?WTIPPC^J z7Z;ZlMVSe2MrE+f4E-60p2<1Z=VvHu>Bo`7@tC*IvoCD?=mV;2T#BG_?Io2$D2dUU zwr#U-gZYx3Ygi?68z!a59*)`np{=GU^Y84uV;G10PLndaKQXH*N?vz6dMMP5Fwz85y=Z_@{Df9^5TxO&0DtHEn_&5 zCP%F;tEytzR7|dCQ7^by-f%pQT)t_jOiNuxKK*3P>g)^D|MK~t{FM^9TuJlfcZzUK zfkqd&=;_=@WlBsE1PR-*M+m{Ds+hEA+`n>OS_}ePXiohp^Ma=dt3;+&*b=EVf{-V@ zQq4)aJr~P{S__PVy0RFZ^>e2-XEj)@=*JE%1xC&nUxFY7AG(ocW7rfL@3S5~Aehj^ zK8MK!Yk28emdm^X)Yjl*mfkoY7~F^#2}eL#gR}*`8_|W%({!m2x@3RsDH=&2WWq^d zK}ob#xEMM1BU8-luJfx+4rD4UJ|#xy=hWfcM13R`6qUi&7NIOJuP6G!vsgA%ji#<@ z3SFZlT-{vcjez$UQ*bzLxxPJPvB)Hb(`jJ0Z7J-Mh-C7Cwi`K|I_kxeD4^{-_J=Mv zafM|_o*{UGkO*zDbxFNmP}C(MCcc07L*7bgNJe2*!Rc^fwO-+f49;ataY`s_a>G(u zVobEBHU|!B3D)3a&HxZfBTK{JM$#Bar-?B-id9393DuMYm#5ICDLHmW91%ZFIry` zL?wwAg6+6PD#1!#5R~A#eWEHBEbS#43nZdYL@Bb7I3=Qtbm_pUf8}cVDGHN6Sn<(| z82`{{kfmzJam#=Ium2KNe%uKOw9@?hU;T=&j|Yq@bHG`Otd~p1X+jB@4ks3G-*7OR zAQV1Crans*qp{h9H*|z)!d#pqr-?9(uw3G$B_fEcj|!p|qf?Yf4-3 z@Zkw#3)Y(zlE~ydg9}8Rx4L@Q)ASKjmFTA<;rkaH3G?L*>%aJ8*wlz5s9dBzIfnZu zc0ar)j4dHdAQDy45d4gWHHNl5&8F}IDKZN_rbLWjbk0I?Qy%wArE}vgMOJIh@}-a1 z+L-cPkmXZi#wO>6GQU#=!G|9c#&fTdn|$Ui#>WB3#|>g$l*D=1B(PS`w6}??Yo_BkW^&6fkkf)LE+u!p1_{{(J z%U`3FZ7j>XxAWG!V~aeZ}(A#(rSwBy{EVWh^3*>j zqIVQFgGWAm{{u>EKKt@Zs;Xx9y61E}P?i=c0@Kj(!@D0Sii-1_TawnX4YTgR~@snEgR1aX23HAhfh345lnFHY4xd zI5G|cecQ3zoMl;S%JGi*SjZV--Z_MnG);q$l5z6v_Xkq+2tv+`n?{t9XlsZu5aK+N zlmewRMN#0r%ao~Z$f$JWeEwOM%LU#~D5a4yo5zi{G>Zk=8j7l9eRjs>)fL~rd&lRW ze@=Hgp#k9otM!U;n0S7A;pKJ5GAw;R8_-2`zL?S z*MI#>j;|*Sid7l-v(FlC&X#=h?ulaaIqHAD{^GB!(#Q~VqmdF*i0r*%VG2ZH*tbWP zW$x6yfNi_yZhc0rHTQ={)=E<7Y$g;^%!pHocaGXxWC9;E%iWe1Z8V;gQ=e0yw3^Z= zv`nPr@jgekhmcoul1M-HRAqq@8Q&=oB&GQMONUB{mDRcUlmZ_T$0;!EJ%yX}n`noT<$6WY6ey$VC&%Ca<_DBjG;57CMNXk@Ph8w? zFf~XE<0N>0f6wLh2B9UWyxQu&;?D_9jS* z6b0v(8;UZA#7vXt{rd+HimGa6IfEu4XqF8^!Rz*wh*Y!hflOOSNCJW}W^;6y zJjrLh^%Oi)aJfK}2IoANHy3yrISm8dq2=M-2hOj~QB8ravM*#9CR~d2VPuLS8>W29 ztHeUn&me)W??DJ`Rc1t?)`Zs4jsr<1y5o`HJthg9o2V~VxtX&HkzoJ2%}o!1M5HJ! zQjni1J=2jwAdQ}7QD^O`^AI8-MCzs{c+WKFaRl!(O^1x!^f3^k2bC~I#v)1~8Qs9~ zxTl$$41^&1kPqn1nj#29>j^#)y{A-$FnOkFqOK}Z2*^mDtWE)u6n>1v?LaZX$~J6I z0~ggf)8rWaKvOmxUXGmE4I*fg%%87JBFjUPoC~@c9r_VtJIm-k`UhhANQ}{pspmAE zST>i~Skc9nb{M#5Zqf6!ED4=WcgA7HseSc5+vFcBtep(scqQi;HY5j3S_eZ8ce1|*UNiWCB)5ol}C z0otx-aueSBYyxzSs;coJCt4#kr_;nZME2Vw(RnV<&akCnnnq&G-|zNiHz&fH?C}tp z-Vox>?7mx*siW$A+u67M{E#y^U=F;q(At%10&j~gP= zEa95nBT~%tmE5spUzGfVe`UTG)Z7qf(|PuqWt!HorAkqK+_RzPc&zmMecG2lhw zcxu5%tWoUy6BjqP9N#@*zJAYQ7Z8h@>9QeMNg$$&B9ptkN2u)2^WJ4rSWI~5sS6Ft zFa&{Dip`>690lE|h|#lHmSmBHW|{;q_aBg@K{O36hWxvbaHFRv>YN{tLLLRoz7~!H zy350_WDR~(5eo@VJJQn@73RioK4XN;pCw8%TrWv~d`pU+u|2UqJIA?5Fou4bNbQk^ z7CpUEGtm?kpS}H*<<&Va=7Oy<*siDl?jO)1(RO=ot_^?s=NH`GSZtAqq2X_T+wslr zjQd^7a&twwJkMEB5!&OCX>=U6dm@TqjA(0__IsAcd)Au;-d^$-U;I&)oC-CY`vvbF z9(mm#`1RL+$CqDynS;*!gij7@vL8fPNmW{0KhT_CBF-;qZtqY3 z=IQ(IIla6vv@N%9-cYSppmUx>Zoo6%_Ha1xx_#yPlTW$4y5au)2g2wmjHW0wQboGs zf$et3?VC4oHYN^DV*$RLWYYcaN@ZkpLI zInBj?mfRZ@ecPg>!d4|y2nc0RDibBO%6Va@`%P=u;=k6Po7D?YnBqknnNPd0`!Nu>OQdVPob-+uPz zf3>U|!Z_k%PK`}Ta_}RCwmHZogp7u@1;dnslWrDkl$Lz^@Evc~E2PZYx?Fe&wue1c zRZ>}tX4YT}W(}{*p(rxoTu*yCpoO5Y7DS$KosKPwrlBkgLJZlwS{8`em>6TkNqE>D zx!f!%lpv}3GC>iPWPflNnT=q{T6~D~L(gd(cz%6lb9SClWqG9oQZo68<8Z>31={M_ z2LRW%mpN5i2zJMoF$^RdKs$VlBrLD{BUd*U6tyObhzp)>$k~43b5ELkfp{HB_=8S zFfk;LGXiNeA_@+#dzKex#6say!cUIL1%%ew<5CnDn=ktiBR&RP3d9HuVa^>n!&uGW z9f#eKwmTu4A``HzqErSyjBGA8pfjeHS%#5fn9ZpXEd(+~yw6Q-P87`v=WW-`Sh)qNMPkhD3iHP(o6OEK!Tj z$r|*`1zQEjMVEcmglSC)Uk1m0Y7fQl^AP$T*w)0#QnK-3PQa ztg5?AmijN6iVU=m%(mY=1=k6eM&A7K9iRQt8xSFru}Hkz@A!A$e9dCLqW2Rv$?O9n z61zSd8|xZxGLeQppSA??#>2{4dZ>TghKfGdp z`+;J+r*R%D5=skD5vdYV8niNSxj>)*03ZNKL_t(clOx7RVa;q8ynFg3pK!D_tCkOn__oKH++_O;bbg;Xlbq?~85TA{~CI(bB#>5CT)VpEYG zU*Y~WHyX1-13*cI6p)l)cyosT>Kx@gVV-1G)>54xkTFz|(HWFaP#e><>G9h&0P3WAHP4 z!BWn-I@O|Px8Jh7xI|rC%xVIKmYVzT--DE#U0!f|eN7xDzWd=li;Fcv3*69C7bS5R z*gZWmx{1~01$Dj1=dqC3s-o7KAHMl5$LA+jn+2PjOSI8HW>I7x28?aXhYugH%bJ^; zyPSHhBu@_yMDMA~65sbceEW{7uDQIu!)Q&Cl1aoLWubm@45yYb<`CX$u_S7V8wT3r zG0R$G;Qfd9*urxA<_%@BKp4aN>H=LCY+s+*Ki(5hM`99O-`=2$f_|Fv(2iWf=n#2& zdPEq-&F7yIBph}-(&TB%iX;+JCA$3q-}kI8E}_V0LlT0h1l3}Zak|ehv@bhW>ou~e zvI#muav=wR4g>qwE#ok9d2>zKzeL#B6!cu?JYuUq{(UoqZFmJ z*txkAQX-9^8wXs>a2F{hDP)<_IQ9&~NZm9DlQ+v+n+*LB64wv3r0 zu16}BV-;fdG{gj(vvZ1~B1Ra;f#cx_A)$rjbUYAK!q}1|@^CguftXbkxq(R7qRgoI znRaE2&U95NF;cVJZn0&BP#WhWuiH%aJij>0L!l5j?DwBfn};e_{*o7-D9=NGui(X~C7S9iR*+pyg~^22?{ z>&fAgpj?zJ7ia8tuk5z3yu57L?^}+?mbU9aDK?9m&puz$wh^gUeE;x7=OW*J_@1UI zSXP!w3aoG_(el-s1?Ng|d%a+DUGntsOu4AJyZaf{@)GsGe)T7RrKM)-Iua2PBOp1Z zkda^stjR^1o*B$%&5Fusw!;aZCN|bk$h^u?GcDmTj$jmvs-!Xo7qVVhNDxWjL!d4T zN~@@fg0Aa1wkOIe{~ODu$=eI>GG)h)RMsL%xRetaClZdx`D(-AxW`sGCSJxY%X2F4KB9$P$;!3DInxES-l(-cSx^)l;8@9z(2Q{^x>BT-V& z4K3@76=hWtA{-Abhy97m%L|IiP%TQ9iv`o<(Yj!_KjM4@G9jVsJ1(!UDC?4{s*ys_ z?t7Hc1ewE*O55O5Vs({Qho6SvDpzl1^$fe;0x<1^U+`LkgHx1y+%&f}$$%&QYE(X@{1! z?~pFgy&fnR6&RTld9})DU!MbblJ}_jW^?3#vZ}68QZfw_aWV~uO5)(@zlAsdEh)fz8H9_{Yp`{&8TyH)_ zr>w`%#Iujvj5s$NX`WU~QkrOo6E~mT@r(cZryv3%DiDI#;P^Mc`VW{zO+OAuPd0@L zP?Kk|Trvr;O%2f#hY_?S$v_-EbyE>{Tg+yGT`UkjCoij69_Zpo+;`N?V$KW^6j5T1 z9s8#Ts&z>+6^GH~?bflyF6voIA?Uh}7;{0oSS$!3Fbq=;D|3z*68mF^5Q?U*Xc|pn z1<5&-k{K$HG+jI76y(){AZ2EucLQZp69F>@iog4Se}B(VD$LJ5A#5tfuYX7Qe}2vK zyJu=Zj6EWGq%{m~B7~f1J`5A%=zh%CD6Ap)384i2tml;~`y-5==}mJpYG-c0)!8I& zjr@@W_0fYN$tHa%1X^p9l3CI!1xm@B)@#gMvOZf`q;W8tPAA+NW6c+x(sXh zC`VIDAyOVr>3{T7`nwhGc;w=ILkt5}2UfRBR&~MsZ@$I|&CS(MIX<`8YGi$(dG}#Y zIQxXQP@FOHRu7EFEk-D=E+aqr*@o>y0e&=RZLf6}qT6o=*8Z^^U_^C`w4yuNH%lod({UiUld)e3D2Br@Z=r;(TE2acyb zpM3rqrl>(15DKd;>-Cz`cE|Sqp5yB)Z@&B-q4V}~oS_KHd6LT}=Hq_H&*S4GtJRA2W&`tG83EM%z7++h?Uu3aSZ&TT4NT|aJUE9H5)lF~ z5099#WPN#wum)`l*2@*qO}sqbqoQZ`@RTR%*H=WPh)K*|ntXQ-L(eo#lvT;)?KPbn z**`t!VIGM%O!V!Ehx|T~EmP@WL&N*MNczpi@W7qM;=buwnb@nYP zF%KZ}M!D~Mw);Idcem859A+z(q&=RpL{=(N%o~EUi_2_MpD9;LXW)$07BT0S)vE>D zxp-GnqqL%LJFLmlsh8I+=T}!Gsqkb;w=OJYkHR*GR98ONT}@rafZH%=V;J@21h7^Wi2 zPo=;m&tdn9_X$%rM5TCnJu*%KsX!C?>a$Bed28v8o`3lJ_Z<6)x+(a{+bf3SD_Sbv zf7nqpH|#rj+3z@8R=n(weE+%wwFXtOdp>Y>af>!W&+5mUIz;VDMYkPTx~Xd`~1N9qCxvOPpl#$<@KFRiR2tw<{+?g zz2bN}@!k6eKDk)`SUg&j@wj0|bmk)?A_N5The-_h80JGwpafVch(@q&Tb5-*@&PFn zWAxZ6(`<~N|O`i4@V029qnm3;>*{n;(anFZ$2R6$~ zY+2@Nm7GE@RY~6s_%P8OC#DdYM#sbBD?j_iAF;Vu5oO|Zn)v4Lzh!f|VH|skx<(|4 z^AlB7a&~@3I~^H@0V@U7vO(9DqN-RdmbAx?cdy?wHjdCoMnl-%8@H(`V zT7ytbU7x?Z6f?ymCR7OE90ZTD1yLJ>b4Z!bCJ(rNpvqd9+>jWVC0`1(8<=pI#R`(7 zs@IsaJ9aNE*Ee5qh$njI>4p(~8qq>y$~=K~(}bJyL|KT$Ftns7NiGr9e7VI$z@w}} z5Lgu1K>U%uW(&*ibf6msoRY+liD!x&a3__-TEoICw%FV9(S7PP;A;QW;HF<3=P zlYI=`*yBT@Dk@w%v0OED?SP*1V|?(qX+-#Jbd*LDBUv&eB1T!XR(V~Y1Q4mqlENsC zeamvu5XuZ}7>6-S#bn-02$44?LS&DI5^~;NYqZWNS?_!{K!!jfpcV7bBNup5sEjJs zIeSD{L0Q_*WWIE5p;0QKmBna{G6L82 zI6Q6`S>4`HpkNGiK9khSvI1q$N|M}2KMoY4#>GIjs8C+uPCZkM_>?epfv61rG-PkX z+^`$1QE2ww)0|x~lr>a))@KGO{h$`(?xS4GLub_MV8=l*+SWn zYzQz610};Rp%>xn=t7re_`(J=R9LQBV~xC@#*p+7nyJ@oedWq!?P%=@YJbL}!v`w=4er z|NEA|{Wl$v4a_}J=ZL~!2S?kt5G5f5jF$MA21BhRS_`sVp|vCv2`m5jxTk5(JoFtG zd68^3({t+TV#8{&q7$AnH=GVztkJlTY?><5#2_*G9JRC*hZC>=;rA?WZ&@xEL@%hy ziXbI{q|!+tDCRSsJ%7gE|INR}NBGe%e!=zEFY!vD0%(`6V=n@acOQr@vfNyf6&Xef zR;LqhzkAJmwc_T<6V8VdhvvxU<|2^>QHUrBA>|_sk!H6iI?sH$;NjC9hsPcD#fAZk zLL-TI=ce~%$<51atdImGx~_P!USQ7+A78&F#>nDg%{SkCm8?`E&0@(Oo|d=$@r>(7 zZf?IKuS#~0dtQC_L&Dsy7aYzfq?8=Cj})sl^>5mwW6vG)a)w;52tZNS>G`6jo{SjM z!CdIN2JzdMM+UsNS$g0M2y@&Y^mxwJ|t_D5Q4IvA!Vd*8}^3-?YSk- z3#zK3=?83d6nUDTKEFQgFk*_5BF`ww5+7mc28MAU5~!+z;KnrXe(s<#ntZuJO2hSF z=^ppAP0O42@8CXgv$+5tXqy8n(+pw3@?uHRZ>bgwUVQTte)H@9hx4Ju3!Q9tQWIQc z937i_MvMa=-<)~>L&w)IpY#3Q2Qp>3xw_!y@+%&;TYh@+g16tlBPrR zmbW{{v3o=B9itohtLqo&O6B;NBtsu#!jzFHGoStI#6VpXd^~<)Weh?Y8bG*_Rq!|k z5{;D+9ReaamL_9U<_vbAP&snij`{G%@-H6(hJcnHAp-MKa%utriHshi$3{Vv8G6DV z3T2XyE_#|i(sv_LMO=)e=CFvDF3JD0M`jlsy+eD*qUIPn7PE9y6h($!)Et@vZ$5qC z;_8xRu|!9K9S6p~XE|ST@;&?GnLav#3e49PsI=K$)*FI3GrO8`?mL>tGqc$ok0+~2 zqK*VHaPd?#w3^Io4u_s>&|E)V6QshKk;S@13P)KMJgsKz9$JQuMA^}amEVsov*j%1 z6NCb3c=f|uZlB+9I-OC&fY6e>n(@syFA*BiKNtb3Bf$C~)VF%t*#yIgMv3S#UMqAfv$bj%q!_7=;UtZNDYNKt50K10^+W z(-6F8v0Tx2eX_-v#KrE~j=G+w`@_Z5!{NJhE&G6!Y2YFVL{!8e2~o2>^@z^1oUO?1 zRN@yq3T3EVfe!*LG&u!@E)Y&*Rma&itnwAwC8|c00G|u;n2NDt+Cq~yJxn2SPvqDg zSViJSi)dUUKgON@!Xvg|q3!qe15i86Y}~@PWb@be_|O zkxY7Yus8(7j2JaRNR%#!eT!dYXq6GPLPn24L-bTtP7DLWfo~&&?Wrn*-AjDT==#8N zGiP2Jy0&L;2gya@P0~SS22!V05$SD_9 z6j?ef37s}*U6=A1G9jm9bW~-=FpOXXNR<%ADqXiO`gAx_66unPQkV>HErA3~@Pnf? z1(3GrCevsw80|nko8fv-mT6)fh`~|hRocE5HPV8}G=uRB{gG}wq2-)eIj3zpWLe=e zjYdzH^>nyxhK{Htv!Wmu8WRG2B$ae3fe{XqIiyy2+p(E1xIc8nVMG(@fS>3OvQYRq09rw%z96%Vs;n6D2G>NQ_n;I`XDB6+>V?#yRmnbI(&&5vSlc))1?CO;ybKczERMYQx(<{Enae#P!P;yn6jQ4Yzfj5XKRt2sDQihtq-iDiIs46+|i1 zys}vE)1TLT|J(n_-~8S0_|eaP&hzKDSScAp!jp?&(MI9>k^TK6AqFmUvrMxIXAVY-c zdAPsFNXh2v0#y3D7FU-nH)~E058Soxo12_q$$$rAos3XYFkn)8|KXU~u(<8n49+JWue9fyZ|R;v}pXmYgPH0(_X1-oyhmO;J%lWVe z1k2R|>qP48K_N1MP=Y+y42PD>>uW@jR0=|5XgZF&9g#>io2Bc|_f*veF9boRXRDfu z8g)5G>Vmd+1S#20*kC(4`nF-dSOO9s0;jfNv)*74M09e{lqE7Vi0J8>6X)ZB<$8rs z7G(^Wa!H0(f-LYl8$f-<&a*=AS>DeQ$duHMdd2x>_ zYGk#*pCUF`2suF%9BqaUG6iAnI5I{{u96hIa0a7QqRt3`L|}&=GZ*~r@W}7)cl>Ad z41u8X0;eXASqLa2i6T-cg>75HGEq=+DboW$B@elX0b)Q*p2*IRJXtN-wMXjZENw_# z@`)$UYLXMJ9g%?d>Pu)bOul@RX_%y_%h`g%V<6@QV@#O|JuAs)6~<(E5pixL#K80C zxAa5Dr;i_*U#vJcN3uFg@{%&Fss)FxAr#OwJ?&xS`u2kD`M{|kSzo3bC!g1}ZO;#{ zw#?TRPxB2rGZ-xxi_n)_m0!y#Qt&1`EX`&xdsvO1Y|dG-krJm$xC9P2;<1{cpz69u{3xAy2w$vKn6*6 zy<#-rn}*Rk%6x_&Epe_;Wl3J=R4&jSI@Ozj==Gg2!%0VG4ASHvY$UNXm(lc;|7!Qsvbb z!p(BEq92Fk?<8^UiIKzcKv@*TkcM+_(?C|qH5eEO8{4bIOxd^Qsz0cyu|r{5Q@SKcmksv z&^mRC7{|#{CR6{0sSM7haKDs-s>qTe7}GO5$ViBu)oMl8C$zA$ zkz8j)4|!Ihlq3X))PlOGvC`o~KuC|$0i#k5&gc@MN_P7*UZ=ydvm<4d;rk|m9-0v! zBc{wj8=MV9ACV!V@yu&OEd{o-NR`ujPYgC~JU>3rbsgPk*%UKovzkgPgoHysGPW&> zKv86PZwVqGGmY00<&#xSNrf&;;$nu>JBksM%Fua^?;S@waL7Gb-BB&UA3VxLY##{D zA$=g1j$B%1jHvE}_8{-_WOaT9=WwK+6=Xxkrx?+*j3^wxvMn0xThmx9d zQNgG8)awmDy!`=tK5%hy!{OMXE)^(^AeB*yJZE)r!4JRrJzxJ9e@@6HW(=4ZK}C++ zE&J_(#bU|L%a>@SP({tqHGKOYf5T6I`X@xCcz5>+VGLK#pQB{T*m*Zlm=fvCcqP#yJ)o_aN-wqIxZTt44qSe9n{3g2&-+)ei6L_P_18#~?%lf& zAGqFJkW4D6iI>k9*q3BYkk#0A)y7f-wZVcSP$sJnpc4&&Bm6P8(V~ zvVQiAFj|g>10V11xmvGi+m27@Z!Y_GO38u%qFD3ibyOC z$K#RlaAvhwpo^R+pjfVGn}+*0uc_;b#bQp=HtF!D3c9iX<1#x&WN?&u#$vNU8^dC; zV6>LL>shZi0>}8k(D%Im^nvwyiJv;Sg6B(S zF_7N7&AG*t)tCI|q-dbB001BWNklM7a_PM$CtwH> z%GsQ*>oK~ZId=@>fh^AxI@~9~Qc!~V^(FuP|Mbu4+m?U#Z~iU&yGKf~z>O9m;MJSA zWJSr%`U$)3mcy>0u4|-nM48|iCO0%)LsS_q!nqr8on`xYB3gwAif-sBqULniF3t5zx}%{edAI8!_y!Asxmpp!-36whN(0&m9ZTMs@Vda zCHjsaa^D=dUatA!I;Z^VmecodxSh=@CoCaaqP$D}1|m=zO=%3Hh)AV~HU)n}NZU{$ z0$M~eofzFi-=^U@Smw(G!l&JAh>;--EUE(M1F4MxnyAn!GAoOOV3d#>lLjEA7_8uK zA8|T8bc0f;TobG(Nbp2X=QE4tGI@}*45c)G_uU^*TBGwERBA}>hU9;)7u95G(tO(P zICc$-%QZnqtVnIvkNZ7OZm(EeEZ82-D3vqxio7<+I^yJr$}(oNIYLJ)J^f&DQJ{2A zKaP}jnf&rH70&pOHrMBK%ehT#=hLZ4jo@Xv38PHjPAxT?%L~qZOFxb@$A+%yxq9-1 z)w65%ZNu1(gl^>cuw#9(A*vLt5+bz(&z4Je=L7A;qZU0pe!6GzlUtk;(+03&v?Igl zh(2wuq|`(kxPSAW^;gfKG-O3dduVuk^8uM>h)jbJDNr62r`>_8=Qnuo=niN4bIWiz zQ&knkydtY}X7!BopDmo4FouyRVCV;C5XtdEGKvG+-96WrH)v5H zNN7|c(lGZ&GyfC{|D4qzaBB9Hb&U+k^7He5{39-(t-qj3qmcYz|G@wE=37*mqhml> zhtdk48)Tj%28Xr|Pe4^AXpNMDxi)llMzGeBD@_bASc}$? zve3ApO|9}$({??GRLWG>GZxx#ZX5Pv$J|L~-#(DNd1SnMBz9+{_v!Ew(r~Y|VsHaR zW~S1*Ohaz<+f)ilJ?ZAw3^)0oF4@W>Rrr*HVdwWffSiG}%03 z5Q1U7ME}`OsegG*eKjWz4Mj0W$r5|&5!F2X+&3R7K5faIM~x2G4UA2XSXPuzYUb;L zu^-ruIa~RJt-s*?Ub8zY_Q!_14=09GL~XuioZVnUK$(o*S*%Y~0FjzC0gcR3iD#}e z!u|Ki$Je-ghF!m4ndkg>Klw+@7|NoOXiC?$~q4FJ^j!Vz317>7nF+yBFph8LhxK&Y?xOizx(yC z+3g;A@%2}!cPa@AcpuR!p;X)RiN}Wr)|Z!DJh?%YC7Y`&j{6p2~d3`5Ve+go%|5VfS4ATh)Qg{Z26x36B2=Q*>*oU*J?TBm_lCG}DX!D)BI zXwBvIHNj|1S#Wi^A%w_&yTuJ7W7{!yJvYyuC*1gi*LL0}on0!FfaCGN?aP-8c4WKV zL5yUXNf{6(3g)?`Ih@$sT;npGdSehMt(ny|ecN*P;RA>L9;qaK-%-!%1g6ss}KHw(D!G3?>+%)OB$~0wNVr}a3SZtOQRmuLa=h^cYNRx2+>x(tJ$47+sEUOtp zDt6mFhy8x~UIAk?Ax1_wa>X2 z9vOY$hq=Vag4wA>j4jKm!nlaa6-LSQ<)USlWhmg`c);WZl0Q-?q>?BZ(ZVBTY6bUw zPgWUnrD%s9qcmE`soW(nD{}f_B+7^olE=a%+$a1wLuX6G#LkUBB>OczmaX_0KAvA6bM43wXWL}W#oG^HP|M&mE#nlz3 zre$+^g~==0c3`*NQ)D^k!wFNANTnIZ5tHX+Mf!sfX)EX*YFR-H1n(KGWmKuhcj!`> zvhN36(__y)^Xm(G4InA=lGCRx^Q#N2jEw!j*bjvBfID~8mn&i>DeH=&t~h+WBRWsp zHF)pPnL*?QK}O6f{my(03|&umZYfQc4mv7%q>H@3PYuS_B@TZSX)rM+Pgb8e$=ND- z?t>55aip$hsklreDuj?J)aYEm*}!3UU^QQ&LP*=gA>f;VTf!+^T>!@@^mRj$=94HcL>OVbXd=6cP=nxZu zZGS#cW(CreJcK)5J^q2K>M57`Gl(*^@}d%BUIvg!<=da%B~XB=ks?d&&Vr~?k+EqIO5wA#RaVX; zttAK$MKOiN1#uYYKHejhAueYON|Gr_Y+DK+a9ZPyMhu=XI*P?SQH$J&YZ`{f1Kr?h zW+j7>WJ*v2MHHyK;BfA6wx=i}MJ_oXTeQ?v<&5*m;(el&p%tOXAyeQ6s>~!JPXy-$ zZJ+uFgfdv?IkzXAcjS4=MHA4!c|&}AkL)^BNE@d>#NnqVcZU>_(j+1aknpialTGcj zGG$Xi1#BFNBI3gMWw0Rzl#pcFkV%7)CiPwjk!*)PWihg;Xex@dNzSs27?W~Ql_~J; ztwpP(4%u-`!+J99e*f%Y^ zW1EbO!DFg9yT;PCT~ZN41Q+miLCkf^k_-(uKd$*lfB7SR{EKTkeWqP#>c99U{Nfwb zYDGInPWL;6p5vY7;ll%6)Sxr`x9^c39*N$9w+U_CjyR=Q|MUtokGQ_W#hihPUd`CL z8=CGZE-pDABg$5kS3jq(E*boY$_%4VLthN3|H|1BlVzYKxPbJM{@p9G<0G+NVlQ4& z7bSo7r+-0uB2UW^V7I;JfB!%KHRWo<>UzWP{^oDExOv9%>KdaH?p$V?$HN{M9L5+n z>zcR!@GZU{IF2Kxu3646sAo%p{H*4tYpH7*2!Z$S-tz3lbBK}S_P}Pf!AQ+06P6oi zxxc%E2sbx36m|UtJFTLm-Yig=;`_h-E#sl#=JuA&%?(})yof}Z!qX;1gmpZ={Xkxp zES_AU=QY)0!Qp;OvpcYy&rzgY&;5rxuC6Z8Wq~Nml;?(FGT9JSg#OD@af%qhGRpsKTsAWo9jz_5_PfOCENOF z$+boyX}g9OU%zCz*)WWj-EL1^loZ-92`QZR2QrhhST6BW5R^=d6xVd82 zHB(`7`Y?JT+0E*TuIspYa)S_p4Ek#k16$LuWDazz%DXSV& z77zma`v*?@Bb&_z5vL^v5p4|JFr?RQh$u2qhS8pRQAr(=?W=>uX#P^h3ZAu%V}{DtZC+?3&@!;<}cyG87ljQUCST z*S}IqqXF$K(GCpW@wz`Hye-KH?qcNa*it`##`m_Nj+&p&mbm7?VpdT|NpzOZ*(r?c z$yC~eNu}rqi!s@B$Vdo7BL%5zB@HZg>?w>v2pHOdA$SU0I~Q23H;mSD|FBCG6Bnqe8mS~gfyz_Jmnd1TS17G$+n%xa zwC92K#RXPGkQylz21(!cJh{Dv2&dhV{?u{WpLqWKmSVLeal4&LykrVk8-tJ% zQ&!AoHC?nc=QGkn)P^3wWNGlvG^VO3@&aAv9H&sWk(%HGhwXvldJT(I&SXr6=so+p z2Z9U)BgvE|Xi1b%ua^|78f4`7>4Dffy6v9%lTD&KY4ydzh+eJ)8Wf_^t z(b^zYvPK+_4ddtuHYAj9KQMG7&FRc$wMjNS?{G0-R4QU}J|GbEUC%g-EN63sb!ab9 zPQVbzq)CkYkT&;GYHWma(=)3Uh#)2#k|F@FPoF5LxUQ~IQ6pqR02AQQ98pTL(97gq z7hxLkN$V>9(;&8pNmU5MMC=$kM(>%I3%28q@AiLB9xJ|D{G427X^SGJ=H|3;#0yX7 z8k*t6#o`)8mJTGJX>r0&O62DsoG4X7L_D6+4$P`qQhz2i)$FF^&;Iexr!!IdL0&2T z<-h)4@tI*(&l$(G?dqaJn*vQ>=$aIc)EPn>Vh9B97(PB?iX5?CGLWDW#*S1&ND_Tj zqP)QMJ$YRrltwE_w?D$EPZ-km3}*zH6yyO!Yblq@RM_MOlunR}p>_1FqbN$8g~KTg zoK8TWN@OVzlvye`%(8+!Pep3YFcO5oI*-aVMUYgdk@B2j2n#eCvlFBqE%VV-ursrbHWK6+bsn9}UZBpe@I5g4?9eI&s zolPymAvKDB9_)?QQ=y(q8%gKBw1xv@c}7*&(|->W#VK{WM8H}{ZZecq=}_Sk=)q`> zQJNwz6FejY>axO2y*71KGmJyRmyb5(NG5NB)|%k#mqWHP8N=ww%NZeRvg;?9Kl_U2 zqQuP$g!P!wqP5_3I;4U=1THv~F*u(NUC}%G{Skle$fZUX1y)PQHH%qJ9tWI{oNdmr zixj#fn=E9lOL%kX0(p@F(Cug$eHs?}=8P4JKBV$Vyhp_d!DCBJEHsEfnH%Kl0z0p1 zG<>sqn=;UoLfdD*1`Edyu#d{r_x1{HrC@vCq~52 zZgK01?%blHMpa;KM|khBzdJDg?t#bOenf{2r;8hgs|BaSo~Tm3PHRK1Q%1qtL?bHe z0!9Zz#C~{7|KS}&R->N%gnk_Ot6%;FYn^?8L_k7<{;U7_uNl3kUZomt}CG?n{jeEgy1>scNnc1oyX(_bv;8VnYzY&Aj`630X?5tUR)%U@h~tt zm+lK9LP_e`jKyL_JzugvHw-S26(v_UPZ_MGTrK&_fAUXp-t+KyPv12tDG|t%qzvb$jGXiOJl;J}FPG@m43QhEs;1H<-~Q(J z7-_J8)AGv(G{h9P79s^lwaL)NP}L=RR#7b%6j3vTh*E|SV)6@0fuAf`a$X|q)E?Yh z%NPQ}Mf9>x(yx?wEs_?(c z%2pteh~~?Al2FGH5e0qQr$9EzmXQ>X#NVzad01U%F9_NMN zuse`VIVKYYI)HKlWdWO7z=f1p1mjc)w3sbXLK9t*T?LX}1RmNQ7kYzq2}1}5qDKTt z5P>2q$X%H>-pZx_SI9592;h(QDU!FHiOO_pTIS0YdwbyR_B~gdXH=o!vV4h%8A2!` ziYR<4tVH7Jc-Vhny}BW%Mn;vyYBe1yrj8B;Ag4?giRv=i9&HRt7=(4CGm!0;VC| zCske14lQ29bV!Mb9_I06d5%C%)+$Tz9_Lec0*KU$qY`0CnPj($BIRy^2d(rpya&cH z6=51>@Gc-lLO5!vv7=2iF9hQ-Chs=l%e~z9LwcS>=*KaA|Gr14bln?a5GbsR_#iRG z439!BmTWI_n%g<+AKfwrnClAfBUVeYEXSw}fh04E_I$z(16WU-$~@7UtS%DMNGhVy zNEMlxi1UKOsIjp`1riNSz*1lFj$&je@FQ+ z;3o1_jG977Y!Puk{f2H;p^pRN)sb@0lo6_ZhyC}jsb3v1_h-g~pxdl*H%SfFS)R(r zoI^(vg;GfJqQr%PICSJfVor~^hxahs;I6-B90&f}mw&?7%k{LBNQjD}n(?px`meFk zBG9a_pYZVR71uAmLFWZRNX}i$=p4)CisfQOHea#6dWvrs1m_4+GF#541C3&xN)BxKLynpwWuYdX@WH!m8)4N4$MO~LD4S)Fd z9~irydNBv35;Q1$MpuJUntn(nb5EW=<3v`f#-yQMN5S!Q;`+rcyXHu9JW)!GAr18D*&Nwzw?rvetT#9ziP8{+b5{L~zeC}YSLGxV&atZRn8XSdtp28$MwswjE;<_(*x z3uKn#nF?_y$AgdxlVxN|gLCx#z;?f*>k~-EPq{beQYXmquxE35K{cPFi)7Ky%7U`0 zi9*nIExX+#ZXBq}dfG3hMUVGsxdV|XH99XbMTy8Vf;Jpa4TJSuJ-=mj^Mv`;4YT!z zwjX%^?gO9h?pV*}#1JrRXIXQjLI0h0jyv>l6LmIj&#qY!l0 zD}HEBRI4?n%*a1JaN{E<+aP_QC<>aU!5B@YB~pfD&j^6f^v;thl?Db0xr`_skRsqh zlE!l;>$ph_@jiH}*&O_c6fT_-O{z{mJHhqkf@PhdOvV_J6g8X8D6)*MYxuAonawYg zMC3HCp-IY(%b3JfEh+m_3#Yw9v(C${?o$L)#pzTx)k zZ<19d8T;r5$K%76r(eC~csg+0?l>RLWDXYV6^r!>T@Wf zATELj#k6@8Da`%389Dt+@^E+0#cGZ80fRt!&<@j~#F<+)FA_{>@ zWQPE~aBQ0+Pm8BGXBY=ho)yU&75{&t-mBNL?L58@HH2!&oI%j&~plP zibNww+qsA!3P}*2?eRTjF{7|6G-f&|6Vg=3@Nt_hr{?jbig=>%v~5FPIc3to;T=jrRuyDLMceyCyK)1=!-o8H z#aNa|G*$}o;0aGVf-#I`o{E|37O5qJmdS_TJ51X%wl(&A&7gJKnj+v(qcV**X$TN8 zFmxS~L_v`Tq6l;Wax~gU{OGU&awYIObt7a-Q5ci9pA(igIFIQAi%pOC-COMS2I)tf zQi{u}001BWNklcX{1ybk^J7#C(DS^Dt#}7WNik3DXLx zd3@*xv{6`Nu#=+Te3)8mQ(5NV2ZTs`{;9_{DGx#>Q%N6|mQ(TcT-yiY+@mI*-zenF4nb!gF*m8K-fbjI%5zqm}QQP<#ur_3v~5Cmlz5zMMN?QTz7*W_hR3@Pgw`i`fY z8}|Dx&tAU5WEpM@gjCpt6wtLt$~7o_09w(6P7qc>fN5l-G=IX&1}7>i%jZMMYdDXd}WJ2smQ&tAMrZRIj$ zK3z;oZ&~DYbprvG>lK?rJ=Bu(Grg+M7yHCvDuCB5_XA<+9k zQO&rzyu?~V(>7#Mljj9~beM?>xISIc_AO^8OZMB%bPhx!3h$D2+~{;hXJtuS4~(5> z=z1RScf_Hjse6uXN8jgs_if|5K>hol{`p@Yn}%E%OjdAop2zw~Jv!!DmFOTu zda03!hp z;*zmz=-dclq;a53q#s)5d5P9J`=%j80YWhhBUM?FTSJ*yOqS7hJ^THE<$8rN6Z@W| zaGXCo<>Y+DY&K^Y0&m{mf|gXvlBi%L5R^#mma{n?M?2OGT|mj4yT=Xds}+NGcpK5B zB^MQs*By0iuvLbY83M)jwq|y|CRTyUT8b>^ux}X0w7u3kLkf))n&YuyzE}`7*m=QX zz9bVFzy8(lu%HBlRWc>IQCcE+>n6_2}XPODd#I7f({C^V2{T}PzzPYkYQHG7Wn z84*X6{^P$RQj$154@5{0YAHbm`k}^ZgO(W|w3aA6PscmDSo2^0xBmt6^&FWdQKXdo z?bpBK*P91aGor>ow>=m7)e%TAVNsWQiQ%9ut71~^@tzuiEnOEZA%;nLQJfaG@B=N zC@Jg_t<&b;x%8e3FgILb3^b*j751Y*PK0 zvUeW<8XyOH4~ph zPOm2rg22T9TH+mRtbOBK^p011So<;M#&&WqBaS^VK>nA0;w{P zflLbGIHdBc(IJh(mIV?)f2b3xGSdVi{oqkW$tXa$Wbv$uq@H-A2u3o?N{;ti>Y-;b zU*Qf7GE+z+p>wn@4GR5upszbzjHq1F?2fcvQE#@`Z@=d>My!bRt|vrKmW_-ni~YrG ze6>I{E!nSs$Ko&&9!Cyu?lGgs4?R|9)DrriJx8tPbj^X2t7rHiXm8)4d}Muj!Mw`R zrDl~WV4%t(+4ev;4ip!ka6G$2j*8E-f`9w7pC|Q4gpW&+?|%G|o4bdEpq3Jymwfa0 z{|_&I@-r|QUFe8HuwJh4%o}q2I zdi5GHEg(`gfdH*3=M}~~9&fL?zrEp$FTVh-8OMa_k0RM`jgW+4;Ja_W<^19jl@|z` zvtFH0=#2f-hTV2cR%EnILw!6@&1TrFK$`?@SS*$pYtTlafO@}UR+h}>3l4_^espBk zBD5q#j~fTHl-$01&wRB`mRF&OLL#(DzgHH-q2uB9mfO2KUVZW@%BIk^5CVK!f<%?@ z(OuJWcmKfot5?{?lEr++SRZ+~zoBUx%DhBIxPAYY<;fbR-k}6jOyzu0Bl-dFFTomu z6cA&A8BNdmQADDPxOO04Ezx;~wTTS4-|pCLw}~byBvPoPTx*jQ?hw=RP%3nmp^WBO zA9?@wEz5aDS!9gPQP)QV&>b3%+atLx5^CG#=$L>Oo86x6Rv_3wWA7k_;?9yxYxlCGr08A;doEQ%6DL`lJ@ z6!qDh`{u}tm#_H!H^1jk&o5ZjM}!QNdBMBghLib>T&BV%HHH4-6uOmJ#&`Q2%c>+7 z5LCd%WX-7ihDBLn5!l?2XBO9ww1a0;*SvauL1vPVG7yPM^WDuoXD4%vg3+g&+o5i$ z%95_B8NEYj%e(uUMP-pV=7ml^;k=+99oKhv1R*DXZ5r?#p0;Uu{_F~3;O_Pg?*-lq z7R!?Ji<5L&vKiVMIzOOtO&5KV=A>qDsjNij5?N}@ET|* zo{OKJlAq*sZOi8S4RV)p92yoEOLB@dd>ZI`$LYx#QV80nW9%IDuBEMeR?9VBfHW2% z4YzlXTs?om>5D6#jyvw&->};psbs-&wMNczgfS%ZsbIg^^74Yba=atfg|Sy52TX9TM`^c`K-B?TdflwXj7K|#zC<2rUDySoQu zmErt=&{OMm-Q#4yo-Pnt(H?5@A#!-yFuOWS8`;QIRwropHD~AN2y1bJqdB&8#}?O( zlv$pJG@0xuMjHI!C-3=47y|@}ii+qb`2xW-FHRxxk>jz&je(2x3Bo(X2x5#V55lDy zyD>(NT~Are$dpaJB&0rply}fLsrcdWp3`zo$s8xs<}Hk=6j0|DuL4ny$@b-QMAQW7 zC%aP8e53Fnl3RIjj%XyqAd#lz+r#f!=$udHKj-L<$Y7Y|rzqjlWoJUd1Oh>{Y!45t zmah`vHtLU7Df!`&@j*xtAY@4HE$Q*Tf#}F>p7JLGf*xtzf!$`yda>dcfA$M5UY#;s zk&r>~!(q$c{qDDvhk*O>o^f=Ti!(Z-@iOH`v=rbx4v+8-x38&|D=0r)C>2@+GVd^T zPuGq3B+8_25uqJ#@kwp(T3nW zd6uU`G9)y#l*uO^5e$AzUx$?FsS(Pw;e(z3ug2Vt2Ca7GzkpRH61d`=_AA-82XOfWT`+k1e_1#CL<0W z*LO&*(p;`pqR;f>q%2$f*q~jHQeXlLp!nA> z2`hshJ?=MeIox&BjX-$P_CE^pte`J);x9g9T$Fg>kwuPChW(o#6G2a@q`nyqVPF(J z!Z~74%wB!YQ`9thMd1{SuH%3Bi@!=#Ch;%Cx!cDFe*L?zKuMIfl+}#xP}4kYx%}xD zbiGGdLtYh-<&3T8@o7s|=4830vYPLH{ZF);N1CDI`Ky;yC#%!}=2MxO)8O|9HV=>F zMaBC3948YAGswv4*$HpH`<`xlpxxH2)+fwPPw-kLr644{F~JkPW53_?czw;u=^53_ zXPjO=g_OwN@{-jxBoX+r)Mlq zPm_`=6Om0wfmdJ=95!1vPa9smeo0gsQx;UKB|^${nGuo7TJ}#*GB1kh!_Kh-5x>Y{U`eI4+k@;dp zRTTW}Pkv5W6c{9nlNEZgK>fR){Ka2~(Q$X!QrH|3pf?gXIOchVkO8YTgAhE;E$=o@ ztk2H*-S5BRC#P%9+5ts6K|FmIg45ig5703ug1>Mka zHeaGiD72w#$&@9Z&1qcE>B$lqJTgu_148oV{*mWbXNcgayABrwV~i*%iNS#YsSHoY zhIt`b&Mmo4mF`Nx*taZKOUB?i*7XNp2*h(0{>L{wzc@|BRU&QP z4^2&0&$W=A$FanjTIf!?KjiODjSr)wT}Pc*JWDb4YrA+Icc?g>I* z%A9I`!uMa@Ql012L&qYUBdsJ1uzfl(U(Ya^!f4GbpV9XtAw=#TcI2}nDK&lI?b~bC z=Vy2gXw9NpqGZP1yE{~#ny0lf1Q+Rsk;m&Bmggq~El{~7%L>|uJ>9WI$f?y`D}*t$ z&e4T1^%IO}YsvFG-Kdqo6geW#5K_@~1IOI~5tAiD$*GaL_4HlG@{5;5D{);;Wk>v2_@mO+SB4VG4}UJlsAov;zWx6bX+hg1`+P zYqGQ{7M5{vjQyB8F}jhqN!x+Je`uwbblpf*R^(dY`yLw%#)0xv*;s&m*MXE&rbI>k z@uC4b1vG=C#dF&|@;tl1go-F7Au6P|jKSlFK&~^CkO^lfJwXQk1#6o^*hy&+#2}Eu z;AD;$6+di$LunMRtDg~N#@+rc>*5lvilj!6Iy|BfMCEwg{zzG#V)dM4g-NupT)v_ZIhU```0QVOn(QA*)L_&0{D=SW zw}h|nF||isoiMIu^hSNm)W{f^=UK`?^gY9_B|BLY%|s=N9t~tMV(XE^{zzQSX$3G0 zSmy}F5VS_O1O91;IJRi5sm@Pnm7p62^3gFIj@V^I9XditE!##Xn~u>LAt+owu)H|q zVYkBwMUaG7#U*9+hj@usmCRTIBoi4 z>NRqn&W$)fwIEALo@FVBs#NN=h$&z@4kO+Lyh~O>DH2`HYK!*?Wee$2u9QmN^cc`8 zh3rL4mdZG7tfW#5Lr;u>Vd$oY@pOo(gc(as-%8W_KG_qUpFY4I`*Se}&_E$|vd+u|Qaa+v`SoV|cyi1=|}s7lPAd`?$cL??Or zyWg_Ey+>=y#rm8u1|$+698E6aPrsm@6?CpAXidAX@%Q(bs)Dj$6b_*U{g9sd!^06t z&XCQyA3anviWbbV<$wIkzoazDSI?x;HeJvE@gM(|W7{$~k1Yz$&d&MzpZ}TJ)g{Lv zkmp${YPBUrS>lJ0MP8tWf$p$p99rJK`;kRfuzq%hGM2IJQCbnTLepZxMo2ScRq23BWhM5WTRcM9wa@4$I(-e2Q`N4%6{~7aNKRZvnV#1&1k@O~`QZ%$!B2nj#|#3#|NeVQn^WXDK~5yM z08h8KXr(y6yh!DaM1m9uttx{QEj0h!gM3j~&7kGF8 zQbDc0e?vX?TwGp}l_k}DLDQz*Fz?0*(LJ!=?l`}=Oo3mmF(ymugH@@_Rtba)^mW74 z#U=NTPxQk;S(THcH(kPIObY$b4~dW@1YXGW`m~^$SI7v5rwxb6rgL$5HDyoI(<0^a z!~{5ifcFENrw4SF@qDuRwQb9OyQ4YmDUC%4P(rZZrs7Sf6+Wg6WfZA6 zQyWcQn~D{^FX zcm#v8ynlM)`Q<4?mjYxc!*+j2Uh(+Bj-YsRz2R(SnH7pm2eg*>;YelzMW!jsoTAKW z+9bDC)tuZGd?=9`{lNX>9Y6cypCN;z=~}v>V;Is9pff|~S~}O_oM#+8hoL;I59}n!edoqzRY>$jY zmRD!kEF%+|pbVRbEvvQCUvg zCtJq;{t@9*@md(tC9k?%BelY2d19jmWu%J)AGZam3H-z6Kp|u#!~rS5s2oUiq(INz_8qJB zoSB-TyreoS_|yOFPeDqQh~aTYK($@ zTjRSCy;^`)DP^K0GDL(6h;4)Gdg8KR&>AZx*)S&jWo}Tt!`1`Y;FG_*%xMct>m8~a zkb|Q?KTI==!R>D!LkV!>{IM8{+SGe%Je$#OYE=N2U;{pcXG$j+l5 zYSir(GmOOG=>34uiLRz&QZ$s(bQ3l-GWm36YP}V5>bD{FUdRZUH8?+Fjl~V)$FSwR zT9BEH7}BLfYlBkBq9TO&_12x{baK%@|>n^k}egK z5`##WpmYh*6Yf$YVnl00krxbI#|IaO(h8{+DH#`#S|!GQ41|!r-qA%en=v|1-wlKi z8HcpU5K7?30ZB|D_aHC<^ccuhj(34}91%xHxpjy>QahKdpjzRqMl5IaQedpX>SXVb zA<%UlDzoY98w1K3MlF!eF%HAWi^kB@#NhEFB0{o}5z__B$TSd0V=z+FH61F;2uc!N zzzT5PfVEk&6l;r;sq>`S9~fmMD{|(m8Cr>C|BHe8up{~d8J-|U>`dd`h$)sZN)#=x zUtKYqJ@ViEPcJyecQ_Hb6EJ-81v^=CxOMcu`T^7KDUCrnC`?Y*9FaQG<&yTNFW6c| zJ9Gpk3C+Ox?mcF;K$Ima3}jN`2f;9E;zNTL8p@L1LogY6ACcRJ|NcMuGuHER(lI|= zHR11n`74}{I05Bs#{B$@+q-L?c01P3USOO@T7{JsBLjVN;Nksyp6(woHsk!|3toNx z84o|c=l!=ou)a7a7=g$%w_kljE+m(qzC_y8HjR*}E5Qd2n+?}*-!oe*SzVly%}W08 z&9@X;mU?1zT5$AD%lmilSgz)rUz{VY#Yu$>0)xVdfL#v3v{u6@_ynOvCUBZo- za;=e|K!%9vJ=fp-!0E{et7jJsg{D|6I9aW@e}6->KX9^KLO=5O?iyWWtk2JgS`uZ- zYKa&V{xpJ!fwnnvdVWef^z08cWl>?I!i$KPAz3?JKn5JXxo5_g|$>}LlX*}RVQf!zo!Rl?+oh_F5DL>XW4Q)Rljh&Q|$kY8D%hi(87ca3@#j&Y5?03w{ zBK?e&MhkfN?j5W330YAx_<)O~99fhIt*G*XMOpF9*MFd#&1n0U+-69TY)})|J1Ka< z^TRh^^YZm42$OKmd0A2}=ExX$dU#~JeL{?$zU?UH$;OwUd($&nsVUD!Qe32z+{ znx}^?e)QydhAAyBjzpcPMxAraPfu_n(zgSTHydVIh8udaMTW{P)+&~#OH9o9?caZk zFo9xW(-09g-a%bA%vKA6jOn(kN;db0H0zpFoTIRqtm69Hx4iu9GxR)XF`JRuobBU| z?|%6kR;TCaGKXA~BDk72|MUlzpFhLrnrtygX~WnJ3{B6hs)#0ipz^#RGnTIH5;dl2 zab1%2gi;J4Vylv3IY(rMIu(scN#74Bt*4EI zOnC_j5ZLZ_AO*!NL)%2kkv?EN_%Yypq_ibE>f|xkmeEC&N*K7{Q}glr{SB+^f~8s` zumrCdq#($FXnKb7$UDB~UjN9ped4NoN$x9xNZ#EXW|LJ$Ov}e)(@H_`e^EE26e)Zz0>jvm zWfNjiMZ6ez+}t7*oXpplpwgjYJ%9CI|JBDvYeZ@a{+oaNM|QcQf4-(&SzK<=LZL>V zhE5T2eNQF~{lktiMrN0%DFD`ZkUrIdK@r|ni!CSpwaB`r0XwlrObREnnVan50^G~Bu*%1VhTdSL~)6v5WbYj zqwbS3T@(e{Xq6>NL zLq`}!;^?qtp57bI5!xp8Xo#f9ipeJ8M@JY(WSN0TOEn`Rp>65MmcqbduCNmJU5%|Q z!bPN-;Tuoy?m0UNl|{gXiML;6j{YM4$PJX z>T1p5ib~Z` z`r}{l>e&ebNsJREN=W|UAOD%CB>fa}ciK>$t@!OPf5jjD@z0rOC3pAt9G@OI+}|UB zvuDpZdG?HKJ|`g1+Ol|lg^hx*|F8cS6+D}_?>T+>jP>Oey-0(tA4g;e_^#vT-FrlY z7tdeOjt(=gPm;lTCH4bMM$MZTQl1Rxc{r%TE5WCd>Icfb4xo^Ee> z{l#Y#t7RItleC-)Lwq0;0)K3Ie|y9H*#*o>s>PB_8GiWc50jNK;@kjT&yU}HOSN3F zJU>rFMWqQcS(rg!j7AZ0O;1r)eEZ$^WO;_oY(l0>@G+o6Aoe}?*VjCI@e)0s<77G? zv&^!X&k@1%?%VGPUC-mgJuhCqK&pffj?+RSJtsUOz&H$Swp*^AKVz|86Q$(+n}nw| z)+Fn_5cqDO+3i_hUJ#We#E6d*1Z7e{$}C3)c>ne-P1`0XIFVds%w}`)sz7N)rZi*I zaQ|@6>o2~8q+aLEwh#qY;+kN2BX}r)Fle0TE^uvgZihbW> z7Av%fDXg6vL*J$}j3G77emv<&1IBzlc}cFz|lYntdeS+7wpq>WZ^C?rxz`mSR&uNa9_<8Fk^F#5=T z+cKUF#2Cr)jA0znTGMqsvpnMi^*uO;b3M!ToWTX|uD3ikiceoJ$c0A_BcdB9w4+*9 zxVgbI<7waUPhWk-<;6M6CmYltO!RBVm z<@4w44?7+n?hx7_vx4D}J_x<^)8H*IMS+d5Kh_8bfP? z9ezlKFELA9B*m;`@%jb#U;mIuH7*4Kh0cnQB}^|WaQ!m^;GljtFKvTL8cYC z&LBioNY;cbD-(o5MTSEvo!lQA<^nRErHzv|oSvO?*lh?x@UVZv2!#~}U0V8a1eLb4 zf`Ag~Gvb0nXo=U60Y^4B_%PBBjzd$koSmYAMtjLX>OYYx1r*beC+K`nCq`cCQw9`K zjVMv#Wy4tQ2=kVQ_B--($^HEkVmD(Pr#~;J{D=_5paDY+8H4oPw%=2?Pkes%3(Qy% zlthC0%3r7$SY-w0fASf>TPT{&p_NYf!H|ZJ6#J35 zVdQXsWOx0<*-u`h6nNJokmwNULPTZ-L3K%i8GG#XI;D_UAIWWj2xH0+2#M-E{@4=z zDk%s)QlRM%9Y>P}`ysYmovfHu74^QEXl;^accAY)wyKE16UTyD^i(ou-)t#u+7=l% zVls_KB>SMTsl8lCf=tC(S|+O{F`}maAm=&cW%c@CSx$B9ob z@X@EC$_i#>i3@?g@9D-a9gafKPqrLmERkVSI~3jrqL1|b05OH3y^GAMIc^-%MFN3~ z9%EGsy7wJbQ4&Jx>iEDxmk5lpNFg!C(DyyYXu6?8OGB2KWG9HpDyF3T*wGP#B#MZU zGU0HwM(IQt)LP+&fFC`&lz0P51gvwYe#At<l1`U%cY2tqD?46f?$&dMF(DVL(jyUPWZ^E-64oLGMNkk%_!y_wXpbh62`KW6r@MQMO+ns1II;vn1=9D!8iR-fzU%4hJ?&;gdA?*e zGXyyxqoT4)q%cI^)9f~AA5hv-tvr8pUh(+YrbSlf=(>R+7)Bw}!OS+;6uWOTnNtQCUQ6Qm>1W$--((I#XOmA95U?EDnU-p4H8f@rOTfJYS+N|2(ZL zM)>~wH~iZ_`$X?x4>-C!d?{EHh7Oy^Mu{>e5Dwv&~ zr=Ap_-d`blP=b*NCgI@4o$(fBZlHj%S~~=F2a?z^QZ@Ors@4ACjRb2JYTnW6(T%{V5pDX*H*q z&H45Ze_*j*@!98}fqsS}PV87u?-mQ`ZL;vl-=VhKK?;^xWUw@a50{h|QtFhNN~| zZSWzL0G9I^&p&<1n{U4-&vPCg?>RZYK&XUoP1AX5;dbN5+jsAI_3Bkp`$A;CTBS0? z5V(JLO<^-uCu<(I8%{6I8G^^V54}B}aTpkek;P(;3W3dj&lf-YBTSL;_U4+yea%U= zq*|XKtWIRB2-ol4bNT!gW0W`_A(AYiGBRJUnJw3BZg2U+Z-2wZ^B3%QJIcihHshyUu&wxY8GQ-W9sK zI`ABV6h+YjNQo8=S%4gGd`-}UE(py) z3^E;Zvn&A%{_?9o`&HdG_@O6?lrGm=G5DUsYNQA#paC|^ivRC7e@izwV(^^Kr(E=o zg^J)kj=;odIs#S%GCWZROjfdu5f=nUMS+TeqL82hg|XCq$E2_nN_;Af5+nBOZo6hN zEm0<8y&=$I z?Qsqkiz!XJ;`n5N)&{KtdPM$KlPN}9wwp}~Cl)1#x<&w1nWL1Tn&cEkLD!{VdoeH2 zxy9NP)I2l?vT1?NHBqIo=Wbo&8(36xg6;{{5n>ul54(=@r_bnP$I$lahgeo@UavX+ za*ECsWl>U>KU^OPsQAi#iSE=trYg*^9RY@N` zAycRz;@+P=j^uu>r%)OC%0o|KdHq1Wlw9!L+i{dULk zlM6y%41D)kVd(3gA}jDd`HrQ~WIAVP2CT{HT1OZ>GD?(Cv`x)yF`=4fXq|lGZQt?m zxFXAPl-5Z_7?A0$YW>Y`# z#qtj*WtF_VC|a?m9`-DXCx~c}2!ixD5vYd;2G=mJo{s3<@M*D-@}tXPl)68Kt&-g( zs)X&Flw}I;%Sh`FJg%=fJ3hxqn{bKJ6J*ao&!7H_KchIBe7X$EDEO;~_xyT&!{8&v zn(<{mAQVgr%cLr)gkgXCh!C)Net{=I6nN(mA=2RyQj+%pzu)7Gf~rg}wz?w|5^ojC zMRenky~FPhM6KzMCuCKYO4JS=-UWs-CrXJKhe#nM`?|pmo*{zG3x<$FxH>Zwr6r%{ zR1x~NONSDYC)Vr+)cY0c!y4K4=;+boOVyY}W$```Lcj+{jENrB_x+fQ7?q8X5SG>$ za+@c5)2PZ1-qCa&ZP$R5sgyGKacLO?jWF7iQUE;9v()1LQI40RsvrfqwZssT3K>%N zqR2~>QVc^kHk_yYP>cye5MoR=#IdQi>)Mgr66yLb;i5?&bMPML94;i4z`KYsmcH|Z zkn%=;?A8b&QsjABM!fr^7zF%ySriZg`N-FA+6L9M6zzam?-4FAOmld)q$wrS*_6fE z5qdsBl^F(wY#h!7hD_oFm>{u2qcTfSf+zys4XHfPTBH`3m?%nlR+4GW>FFuc`2^p0 zbh{lvsuVsRJgys(-62LQlM&Wi!r;iKa}Hgf>>nfbOOG89K+y`(%jMt*fc z43ItaT;w_b^`HIY@dC>yMdQ_**IeJ-(s@to{a6erxp;cX?T0H~{^A#0UOs^gTB*=M zW1~hON7`CaRWm1e`@>IEC&!%q;!ARs@i%|{*J!O-Oy)3j{P@i`OcoXMi!-#%h*IIk zT+_5H&{7~|FF^_n6wN?fwG3< zqa)VWw_Lq`&3?aOc6`M0>?{qsLLh@ci4mI}L5IN2`}g#I;NpwV$tDwuykLF1VzXLP zlsORb!LwPf@jh^Jc|m4#thQL8Qzk2uI2AdnCREz+(|6zFLg4cG^JL+P(2oH*Eg~jD zv)Qt~f8_a#7Yw;h7Gar+^Q_X`-QIHb{yoP<$=mmDc>2ZX$UIAqlDefV3gU<|m&8;u z{BY03v!_&xIRSY8{sVneGp{D2FyoOi^8U>`PR`E}S|_TW(xX*bb7*VMj*r26zWL4H zu{~^=9L?2!!(}Dagx;?QYNY^$mGuDKbkW(#NDs4{b|*s5w48$0Z-> zxQHlhUZnPMrPw|^@cQ*D&Mu!|@_fwA37i`kydUkC5!#LqKfU7O>n~ANg(*vv6s$LE zetz|a5AWZzoXyFMN&R0{HU9UK@`Moh@q0GJq(tX=j?D_%Vc`D$k-lkpSZ%252Aky! z-s6Z=lZwOcKJ&L!ZiMnurT>>{AQWhXZZf6TL@h zLn{T@a*6uOumAb4y2F9sha`z~H7YmsT}NglIxTwiQt@rSJGGQ7A zLJSPvGtm;Mq3b&)CjG-o8(ux!vzRSe<`z?ANeV79KCIScx#eV%7LX(nCNEkX)ro0o z2r|)KUf-^$%8XSraA8cckAV_H1hDk9+AP~|qM9IziK-UIh=!rJx55GDl z*Mj5I6K-y?AY)ZMD(X~B& z>nKFV{hJ%eBxY8!^Bn`pqud?#lt*(OcN@059Ys;3cH!X1;Xh#VoP1i*cRlU)fJUZZ zyb_3*LSQXG(^H)+k-2858#cQg%0==aq8C$~N;pk>G{ICQ^vND_xP7F|D+CfJK{bwI zQW1#SEoW0UI9t5NVr+JU0kEpfiE83X>VO zyDipc9O^pp*2f>({ccB9rVy4?f*=x3PuMXq-A8mZNOWS^M+MO!M+?`W1CRBNyqIDp zf;c}Ao*k&q?%0I)wEn>Sq(DkRTSr#6dpRPy<)%H(VTjfsHxxV|a})hQAYHQH;t0GLDGK zq?ozTk?9;GGNOp|qT%M|0~be^6f#c~G8qs!g!FjjdH##fdG^IKbWE4LDB$L><=?;g zo=zxaZaJ)1gnEw>k*U<+9l9A<-`%nN?2$hRi@a zU`Z;H8o;+9HBku;>n-YfOLnz`509we2w@=jfQ*9qbVB@OMM@XC)O4H*@B{)e zX5}(t$g`X>&oM^f{Xjdk^lqT(TH9HIvwDNM>w41Qo3dfZqnD9aqQ z#5y-FPm+`65dqJ`=7DyuWn3Fu4_okwUv)Ddkg&E7$mGH_lDxT`zf{PmAS5s<3l?GIZH`kdYD z89|f?={fUTzPgz5`p37JYKA(Kh%7)b#FsCKFQ3uS!{8{CVG$i|S99^~bLxG~!+uNC z?AYIaKsF7-fBu2#q2XwrGt3m_*U!@z`L1EoMgIGL^`|H;$DBs0oZRnr{O0fehOY1E z2A9h6g2xB={N*or^TW?fCKcLd7?bek*5o(>K|yp5d1!g}^G_@;&N(`NPSeBe?1Zns zddY|HzUAj{{tJionqU6OpJ1kQyi9o_F><HupbN&83 z)9D0Ta({Qr`tgCbu2ZH5!H2hRxOnmetO2dY^4o|H;E|~YKq>ayHJ`osjHc^(ynmpn z56H31vFkg$h(y;@U*FLj8nUMsNSQKj`J`labj7>wb!&4%mEmg#It*S6@W_!nP)Mb$UBVW8_fDr+cZWbi$iH5eq@ z*mHXbe0g?;R*bdp9`I;uSwGx!IxC6ZCyy_TzCOunv%wlkJ2<2gZ0ZIfVBN#=%14sI z;jrcWY{`5!p=r7lWG3V0)jiK%K0z2yFNYKyHJbi`O_zq%W5111W{_unnNu2;;Dj|m~M_GN&m4O(h) zWpTZyZw445u?xtLR|_c-K_RhdnbEc_b#p*z&_<$6YO5by$9y>>D++@5Y`1#`=h*GG zRFe{GbwZ8ekUBNUE2G)fH72)sBHkMm8OA3st~Z{2)^RU)WKVOliyn8pVrN!79@c0q zCyOJZPI$h}>VSxm)5$S%v&8x-bq`Khj3}@{@(@07Q@`ce@=Hp2jEW`^goyMavOU~z zHv0@2ReCAONDzU$^*fgHV=_7C9{{8I82V21kVLskIrtH*0EFQ1uEppgU4T@_{q{Xo zQ82M{Bp>q}5urR$dAxKK^OAr3Pycwd*Q8&&w&nl)-G5<-po~gadjwTc;d{qn+b|s3 zbVZ+4NNdUSA{8<Q9y*5gj;I8K)u^ICIo9$=?f?KF07*naRF4@I+IDv! zN0EC$_qf7j26r;0&kTbL*u#K4bjU(c%?fg(h)p7&c_GO1ini$xLNSbOu~w^eh>?Q2 z>(M$xD2>evOcRhFHs}u<^u9ra9*HOVL_3Qij`(kx9@t~BI#JNl0B$rWnTqv{P0$J- z9R1LPNSN5VZpT4hG7JOGr>=>r%9G6?28`7Rnfj27*2EAP+(6s4q_JO;XL&*(ju|(t zHN@1c9K*+)Qc_U7^Jt~UehZIto}w%OD2kFS%ZMRmHz1YoDXB)PRw^0{(KEJ=rSCzX z)CvJ;oeBXnYf~mD_)jzyrDQ^Chd@=7Xr(CflCDo5yLXP#qye=n48>Q^QJq4G2lEa+*Hkg~rD~v$~=59en$SGp(tL zo?$A;zW$6X%drnF;bzVM@<0DethGo!K1&2`ec<2y-~SdL9Jw|4x~Ho62$DV>t{Rsz`)D?F0RK!<(Oe=IPg8Q%t6bT3PSOvvduw_j`^P74P1>qgo!3 z&E`qPjvq0!1KLF%K3ub1t$Fg_A)i&uFVDvJ zlN?L>Qnn})3K<1A*H_ea&5M^WIXXS#;qj5x%^lOc#LGw@JT4?u_jliYN41=Dc5#^& zZkc|gB!fzU+{$LW`Ths`y5-{H0$~(RrC>N8vE!t``NNwJbbjE;^UpwOq&6%T3lM_$ z@7|LmnA(i}X3c87;`z&$c%90Al@|;ub)BSKo?zJRxq0`Fum9)|K`L%uy(2U|c~z!f zq1~1&x6lu~{oyArPR}SOQ@WV!s#*xV6zHnJ^${WAP_>Kts$uN zyt7K-Lc$6k9iM>IERIjGCgbM%hQt0qndMk1u|n|f_0N>cC8jJvD&oh$tWO1mPJ%6S z`a{k9^n}%JN4Gm*%7SQRQf>*j=uzI&tXGM+HJc`76G87C^W~DsbPhhSy}4!ca0f9a zq^$%u7C=S!JO5AWV_ba{y=3UrY(IM3t#0}r=%SgDf2tp)e*-gEicXB5Xr z2yH-otW=eR5Xtk5BG0Jn8l7eAw>#F4k1(p_>3b;603J`*HaPFlHi2mB!-4H)%lYLK zj!#Y!IH+srx)wJK1Roj3!sXyRWtJn5DT}O<9eO&cDD#Zzq+(JP<8wM$EaSN1G5py+-x>;F49F~F-!wGj%w`jeZwVn?1A|P%(q{HGtKeQ9IG_z)tdEsgOoaj6|GC2`z(Tt zNUd3Kw+w!u8(K`36G+s6;5({9lPSnEOKx-eW=Njq+#qbErB7C@UB>kfcRcy8E;%|q zMGkQN=7z5AY3hdAa)!g>d_XJ9B0uK)?_cra>z7)`inH@edO`}T zYD-~DRu3y;Vc8sZXk*EZMMT(cw^XwkPI-hBNnweCy6d=KtthJr!l!0nuVnHqTZ^_9 zi0qr1x@ib5ri)x*(-k46=I-bMeK&CO;yKO_wA($0$2Hmux;HmWpPVyTi8hw3tk4Ly z@9)3~hTfs_B8{#=G8{TeTPBK&NQHfUJy7o(B8<3A@LnL$BdRl?v|w9raG|3p6+sNi zE1o54PnKt?46kk3ZFfLqa6QiTw0%e89ZeY6cP&wYDKdo2@C3Z@bh@LP^th9NeJ0_w zCD@wY4cy(Yna$=@bAuBtN+gc{&DEMoRWQ{v^zH~blz5pDT7wLcO@71At8aKZ|C}TF z6dCh`dyNnztcQDy)>QHsAtFI2yb|o%TS6F^7f+DLzwgHQgs%NKRE{C=QR(=&Y&1=i z=to);l;d%KPe0V0EKbl-BSc8Qr6)>HHS@C*f)H3^=-UP%N%j#0UDuNZfm>}*LJ*1!@(kev-F8i- zG_Gx#nUc6|h=(m@VQ{k?eX^kQ16k`Zy93jcDSBcFu0!+#G77ZK@GcM>G<8eYv_zkV zZ7GuaBW+IaBSA>|ejsln`f5k~@QADr7#WjiTx+5SYwf5w3?r5>r|UY3EJp~H*z6+U zol7X+aXIiI1tHU)Ar1H5&tau+>3bbc-TxJAOqzq1G5;|3mi-ME}tu=ku5kkty zNhwD}xJL>}mYGk*W!jkWuPcIgiT)ORD)<|lz=IFud4ZCWs;cllb!+%>3F`Zv!KG&I z++-<~oF@ycRuU;=I<9nWq6JAoktZLsR3h1oR3f0b!Q)*(XE|+j^lo4}nb6h^y?3b? z&pBMzbNH~r+}7w<_k`D1h^`?H4lOOJN?icC)CA|~{4i$h49lWmakOML^aQQ2eP9?o zy2vp~F$_IbS>n2m$GZnQpc}yr!{I<)q)bD?Zz`JJp^E}#48HFvOlr7~(bEqdv)KeI zBTDwn78zNk5M6+%38G-zNSZq3Aoi;@#iAl)6(%}%@82O?Nz*v2(X_h6J^37A3zk*I zNxfm%U$Gw=9N^TzYFM$;67k|CT_HGKShRC^A6VbrVr)h%rv$ADTH+C?&QbLn^v|z3 z$qYj8=_Z!^_kPL4?V9jmL%3b@KmB+AlKCRJ3qH=qu5bB2{`dcl=u=swbB@6|Op%dK zN~-AuZ4?jp_Y_BSs%nyyt0Ay@`<||8IQ#kq(WD%vm4bbE>}T}{s;feQg2lMSieAIPPosHWUK++$6aoF{@$1G*lA z?^jn>oS$EUN_oyG6(Tdt7jrVD+1%VwZ#NtcJC-NMsG_8I9%D0nNLh!ElDv?S$JL6% z{=k#ZUNBoOky3K=aL4NUmWk9DYw#j18rL`1%q~xfN)r&o@#Co5HWdd~1+(Rpht(rO zEADP@!FgtRff$c6K6u)u#&sR{cX#Afg`G@rqoukiN~&tYq^f9|1M7!-!Z7e~b;IYs z_&uaDscD|S2S-Gi(C^l09v&W;EtV`#jwycV!pI?b z>ZTdr8H(Luht4gR&z>TsPWWV3j z^&LZ>y4Ji;&*b&~z`AXyiW2p2zWnoF?dtuwGo_~6U3;J&S}JX@Mq!O&=LUWpcHAF! zsIh43{^o|~RnC#`5i$MqR;H_HG=ciikxwn(Z+cG3lBtfguA}P*L>w?$(m9ugZLJ_A z{(Fp(u6Jzq2V9KU%zR=4m(v+C%lYQjinHSi%YctQHRH-L7#ReQ>xRWNM@mIjD5TJs zJmc!-h9{?sN5+Ricb1G6Hh(h8$Ine>VL(Dxjj9MNm7p+JpKA9i{%m8 zSnfXD(5@Ob4;#*(UeZSx5VX!yw+(#^oIOp9?Y3^Yy}Cw|ywSy^B*(iunxJ z_UyiYN0C=xOe#W*0v#2yixi7FQd`#756CXHCkF>2q++}{<|4GRSeqjwxS{_<>=|7k z^j%9esmOA};2Iv*w-ghDiz&=2MS7ScV6m7Ji7b{2vOHZ)wJnfYp04ea35TxXZu>|O zf!;dY0>YVq3yGVyICTISIBXjZyPC7pW3-OruozReBuG{dJC2X$6y%7_338Ysq68v0 z!w0_G{AWHp{)%(;HOkv`#ZeA~!vX95J@euWizNy}P?0t^JZ?U4y7&we^D&o^)QhBG zgim>lkG84QQk!xci3BAurXa|k{qVqcyXDF0vve&K15qR@P!x`!9NT)$?ZXWxCrA9t z|M6cF#MrbhAh#L+&)e_WsgFG*5#>e7)nt~aQ&>~02;*{NjG=7~Xrs~t-6z_YjROC$ z!Gs7!#$Zx$ooEiorp0Q*BrA!B7TMKIbB!w$>T*Fo%{k68vVBcHEnt?>xgIMuR;AGB z>h6)=Lzd^b-mzV8&`M!*gO34g3kDw;Vj%P$yX`R#HU4&s?ptE$N7A7jKkG3SR1%rZ zW<(hVq_KKb;$ACh%arMB?C?@&r6Yhw&}Kag2Xp5;WKA9}P> zlzH)~ucPk=lvMOXpN4kt#-$(?&;{=?M$@%Tx^NByeV?)(MyJ0=DxE+at|!a0Pnnax z8xqyYJG!pN`_x7rLb`c*=P^PhI+c`oH<0C)yvRO5K#HPB2b|HmB4wh`2uA#*PMsIl zBsH_JHrZ&04kaZPiP&{y+aC2$Q|>(O^)0-;#T;s^1-wT)K_(Qc9uWJEC?cUU^uZI_ zmPwwo+aKt4YAVirI)o`}M$dAh@5u;l*P$~@|53;79C?-@&G`93vfdoXvYb52P%#kw zkQU1^EL#;Bg_abVMrR6TGu&RX-3-*7rVBYS8l-nv708a4bWtLM!|iwU+XMKX-nIDY zIqvilX$;G1!eY0<`W1JN=`t*pVW6Zs{fhF7m&~8ciQR$Q5BF$W5Sk_({>lohW>5hq z1aaT996aUCJB(ZtlwhYPbmyPZ93pnr5%0JB$shfa7hivteiqY3gR;o@cmLPF<@V-= z{q8{1)XXOpU7I>?TyUHo9kIH;W^@0@)923!&hh@cpUBFbm4LZc9Aq=PZv#Nc`N z{ZEv6!OK7VeXdsbY#&z4X7jWZ_|)Npa~!r?uCK2-yEtQUbd1SU5wA3foRrN<7H7vi zy!pWGZ-2nJz~$F3@J6T1V%sNRg-q(QiV@iktnVM0pPoQ&v6G6E<5RY)6*oVSqsWK{oavtpiu5S48 z+u!lx>o1XcYK$JVzzZm;X*A_@%F%4b_U4ZD<0E=9L2HZ93O#~6;>SguKnR}oX3Np(Ior0zmIc*x!fd{v zuo>IcnyWYOF)^~ee`HdWse4S2N?EOCUpEZirNu3?6gKDn{*I%wGkWjY*Ly;6C=ppM zX4JcFLXP`LUgivam(*vaXzGTltmylJ&2E=Uhqa*{JdcMx%lQ)ZmtX$*ul9#Mh=3lq zOwD+q32?*_i>x2&6*Nm+1uyyW?_r~L8rC!EK0b;`6Ph8|)>s>DfN)qCD< zcl?tlCxFL~R+<#Oy&haO+Et)ZwalUYub9v26KaP)nLkB(3I=rCG} zkm=HbOeJJ}x&TH67(o|1%JT|!tQn@BS~o-!&@r;T-5{l9cCy4vj}RW|B6{>x4y|MJ zxaI8h1nnfO&rw4O1UB-PANGICiG9X}{DRD8v7_&I%=$48hpOl~E{ul-S;q}k_)E^Le4ta)&if&uOv_KIlr6e$*N3a4T z@u-}XASJ`#P{zXGkedVI&?2jX!CH_J-8SUyz+^gQ=mtdN(S1*)Bz9WhPI8=z$hN~@ zJrZNYE~j)dd0xA2VBfTO=jmhmntSia$4&>6XGpEUC%d8d9$EKf4-N8mPh206O-+pM z6Vf#zkV-I&1F?{T&1Oqc772u*;s}yR7D7J`KU&Ka6vn59Y?G`-N{Cc)rZtDd0jXvB z8X$1a6I`OE`9786Ar!`B4E=!8lEDuM5z$&Ds+34a8#ykUL!TCfbS(ryvV0{Qm`Qd} z5$S!8^PbFRD5=QvEGZnL;_*@SKnOCK`YNn3Xf2Ui;qmx!KzBan{_I#@M+EOZ!6%xQ z_X$hwy`!xg;^3JolRgfUywXyLq*x5V-r)~5_5D4%Z&5>+Ug9z0onzSSakm@7uA!V% zh$>5M>N2%VI_Jl(pk%93S|f}heEix7nHuG-!3XGLvK=TFD2f6X!-yV^Y_~fyZ7@P2 zNhGEiBU%ciBB6VYVp>%UQSz{9z?aHEX)QPRw@lAZSe~7NP>3i{-q9Tn3E{e!^WyU_ zl47D$j8UQp!f^WhGurKrzxjXvJ&Us$XJ5P|43WwdC=$BXk$PNYa5Sqek2m+skB-Tg zbM|3ivRL4|f!jClm=*#@W6{NzapE>61{A@O-0YvpsoI-p07V# zVYEqhBxwkN^f`?Xtf5@YnM^0#zq{h$>W<^(F~(*nr4ax(LCC%lVvGcr@Zdw|5Fzm4 z)ho^}F41{9H0IMON0%2UrMbSo;bHxVRmtjCA8L-z&ly}uWug3o-$Ep%UMSxE@Dne8 z?`x{Xl83t$tL>JqZYZryGe=AggWWc@l27J~WS?qk5CW|M?o#@+HUT=UhH}%6u_T%Z3t6CKXNB;)6g*$)qX~G0-&~ zN@<#=rR#cvNVLGd?HEF&_JJptPf-8ni$DL>zTP85BvS&TB(lob^#{&pGi)ZYM$s$5 zdYEoUqz= zoE=R;1%%MF-GOx-sE2{`qXJ`6^Q*}+ri(d`>m84qhA0EmN|Ra1WRjz;!bi{h>sw?N zu^A(g3i_eLg@LlNXcL(&(x3a?j>r24F3wKUkfhS~ii&s!mPZQ=g1dJQh-TolTHy8_ zg*7M>Q7XN-@=D`Bz|aQ{u0dLlQG#wC=(e7A-7;Ag=ps^0GnVCyVbyc<<27IW@&)99 z7$iE+QO5G_$17g^{@3U#BZNqIXgO^6Xe84~MbrW(BLfgbBuc1ei3>hBPrW;^yI)Z# zgHi$~Vro8>5>e%lS&Fhi#MCDel|br|z_jZ)3?2D$hRVi=l8|(D%g_%@Y@TG(bWcwn z@0%5i%L`OlV2Xn1BkgL3U$w~0BCN%GP(dJ-#-L${DaUbW>6;-Dm4ZmLDHYLqz!q}6 zpeTIr*=={p9wY@*Uf;@sb$^|j<)F_K-YAsysvB7?++t3FJi4iTSY!C5Tzvu zhqM8YOAV(3Jlt-`Cl$q96GVdw5*aih`t))XlE>Q((MOi^1-Vqj)dh5x&eXhG|Aynq z5l`$dh^=Cv#fu(m6aqyrHM{-x@-my4Yq=75IFaF6Nq^4T|A|y%r z+xvU|>i!BLG|k|k@$`q5VNsy1MhcG~TC}m_Wj_tgw#aDvE`^Gf0q2pcJ^lR}pBY@4 zW6K=VwVVh|REoCl&^=K1%#>vi0e>+iT7ep%Y6PJjh(*ReI$Q|sn+BO>c)$sbww8K- zpvVi1)i@Dxc*5Xuen1A$+ZOTe5qoz)Zd%0962}Z#x`?G0cN8HF0wFz|jkT0jK|i!e zoeClc-=nl(J}W5;jWL1{2FfDCTAex|x_0cY3HabCs+1!Vk#R70L?pSjxM4sFg-KE&~=C@{w0hD4-Fo@R|z8e=qp$RNh~I0guT z!8u}tK`LTa(CxP<*W&vcFFjohI1vC(Av9vwL6Z>a197w#3G^f*&vVMWN|djrfhaIp zmKxN(XTRMrn@tHKQM7cH$`oVMCuFVBV}LTI=3SB08DhldmbPnY>lSpxW{RpT2tm*| zN#hk(TOvMTc5P0IqC5J-3b)-rd!Qc-dpSd#oH4!pjOyeCeO6%4POwI??;7Olo)^oU zTnaXiD{Rs6Cx5!+`5}gQ8#WkVvRz^f6gT1Ok0Hpzq$`e)t{z(DCf$ zXY|>O8#$w|9mV4gaeqJq|LTAEZ_>;sQU(Aac>C@hKfivDE~c2-6kApZZJ3{5uzYff z*NVC@7Y&~n?dC0XzT z81|K5pbhw0&dc}#bS3-7h9O&qt(J7uXRaz1$s}`P4v`ttp4Q-twOJMm1Xv`&U@~H_ z^&h_P_Z0{fB1vwq&Un0A@#>q`ByF%oITq#Pz(gdBRBTocJU*=W`l~OwySN zA0jGQ6#LhNMLn&N$5Lfiv?v_B)fHMQ<_AkMuw8)C)YA#pXs#~K z*+1N&NW6LX6Gu-^sirfMFe6+=fl?SDaZ;m%o%OBSvm22a~GJbC(zqz!RQZcj>L zoa115NIjd-Y}WkvcfVs+);VLSEC?bGq|(pNLw>*d{f_IikDR>z5?Pc~lX>=#M9=ld z4{Wy^se$Iz6Qqinbpp$`V%=SZis!p1b>1_Ns+}(D&#OKmWOAuj-0E3=BgK zkuB>fZHycqEKz^+i+}oS?*}Lp53!}J3S42?HCvohEUZNt#Xd!@rH9&au$a>{JB08Y z78R527T-5a3x~5RhjaJ=BRo}Ea5^^XVD4e4xN=#7_ z$$1`q-_rX&U#cYb{QwdsR!~@tF^ak_sOu7I9BR~~Ig`*bZzNnjceJ`wkU6+qg)HeeTNVdXL=j2J6H>&eL|Q3)2+WQ%mQ9cf#$ z?JR{Wsmq$}X3eMDE4=rkJVWK~S;~1hD3Aon14@EW2B{T2HJf`zujY{%+fZKkTxN8K-+{AiK;5;!@y>< zK`3xeGYor-QKXdDv4t&BLgI|2unt?8Y>aYcZd{Z^8JWZXjAp;vQk50NOx5^weZ$d{ zC#b>@=}{?;21S*V+lderAKzVYax|lMHQGDaA2ax#_m97)vNN6)-=c#-D1nbXee{&B zK%y8_;;wnmQTZGx3_*JOxMQ=u=V1DDY%;{So${j(BTq^s2`RG|Ddn3j|E$OcdE@d1 zXSKP(8qIt%N2P?ogUT#zWF!jD)!h}guql%(oB z-Uo&uBDzG}^|W^n2;j-z`jO$TdPDK1DQp+KEDdyyDC9^@buIn5;8Z#e03?3yFWl>N# z&2&vqg5uS3^~C&4iOO~8jX~B3&H30f6Nh}(I?8n;jA5T zw?qE(MV80vkq)P&#`}Ok;;bY1#B^Fy6a^yX<|w9!D+~JM5v69|?hzyg?X%0-lNfdzoYF{JuvLO!9U>%R-{-swtLb}>-wy~^pblrOeNRdfoM9UVRPP}~%1Moo zIi=pDL{%8dx~3>g7PA??YuRr$ym;{fMtNKEfi!rWRP=3&GCAQ`8kMs{WPaX~giqHu zSXbf6TQm^@P19nlSw@z-i0@WZrDZy)(M8QRBv$>vHfeTIQO-(SX^5fEaq7CzuOXqo`3N-|NZC%8%??hnzrNL|LzaSvLX}(x}GpOJi;CvP#zvq zA01<-bB>-p=c~W`OCDE`+npze<~4FYXE8nC_y70*lclZ)bEJ`!O2U56`u2v&Y{Aj1mq=}LvoM;AwaI=gWfaw< z;_A&?lu{hOdubJ#{Tg8%Nyvj6_2Eh!KLvhc!M%=7&q78jWT}PEJnv>CfNew>vhs zx4iuB>x}acpMRSq41qoj?Dj3YhX=0SzT@uphSS$yp(axf4v&#aaQ*2M?RJNiGJ7^t z;_Cd8#pzRIQIbZ;g_h&iRj6#PSAxn|?#@3kfAx&Bvk!S|qYTz+yi8dQAw(W7emp0{ zz~a?&lE|Mur4*(tI6jzTO~u8Z;v%wCQt##DDT#tT$c zCW0x$#l;1Wt2;CqT2v^>`s#*3B)rtz-LKiT9Z`u4#EF5ja8zXpgU32USrl~pmPu9T z5K}Q`EDfHjs*zIC44$3uIhh}z{^sj{{OjaBZyv7rKQI1FSr#0+l1fS@)==miKD3iC zJY8_#>~To6vxK2z>Lx7qdqfWTl6DeZ~qlwTn^bMsmnY->i z!4I_kK-+sB*BhKwND(vsD+W3#*=}2`Q%s6H0h~;$y!s=r`~!lfZ;8=U8iSOHpb8$g zd%k#fh=~Ij#o!Zd=jr-^BqK$s>AHc*EGK$LA-P$tu!Y4MiINdhXtd~w3^C^uyHH;;r)(hUuZ<`s+Sg6^T^=EI8R@f1_!fEyh(2FZ`V`N-nsg2ib?RZn@`?D%wc z#rD&hdcMF`xx0>1Lz099!YGcO9^$lNzu&UoZ5a9vLY5&Una0U&1P!v#lyw0__L~j; zc8@D-l+B5fN=v*7P~^nT$JIT}!(z);)RdJ25;6AdcbiN)Q5oeKdY=a?NsLmm&!0K@b66suFPjuG%COxwS=-)q96ecr z@Q4_YDEQ2VPosX_2f|>uI{(Cr7bp3UPl`B5E^f{N$;tE^be!a7On8!1gd`aHfU%k_ z4|pG#+b4)*@T%isvtl+m#3?uCTRve`Xw zv^+$QZF*9HDE#>M2|R38w0*qoSBkKE0Sg-M^MUYcn#VBQv2&7b`lrs}1lNw{xI6V{D#9!9g#HTe?QRD!{l*uB) zFd&sg2~7-f#6ptI%VmKd#-=7^3RB;9h?pm>`Lm`mN;3>SAq<2V7>1mW(f2(_N!xX~ z$d_5#@!1G&t;vS=Q9>AFV7K4nV?arrzmGtJn6gxWQEF9|7NaZ*jm!!vjLr$>pS@Et z1X38YR)iu9F-sqPLXO@*Qp#j5GIn|hVcgIK`mV+MOv2K7+=8XZFtm^Yp&w94%w)p! z<#UoLX*Ug|fD}1Ft8WKXFHn;S;h@GllV3+?lXuaNh}9w!2aU)Ol+s!1x@O*I7zB?G50r(&AQ*NH{g9KywbLkPP%$wnONJO2x`B4PLu-qfOwdj; zoeDG!LFY}|(04@NW355Df@ma@sik|or`zmFZJ;!oT6w;H@r2|%Et(ba&o-cVkdmugvKGikxs}~GL<~Q*TE01PRH%`P;w6YlSUqbWtL#Lsd0VTg+rmF$Fq0r zA66XCr)=-48A-sCr%#De;+0^sI6wn$e*Xug%x3`6^Wn`;IBPk2`ZRC*gaEBD z|G?_{6N|-y>ERMD$4!cmKZkV!7^x5;^6~5gPhLDjl{IBGp|FO>`#W}i}{?*{fe&Hv-6(q;}(2AA9_Eq9omfWH=4OCxc=~w zC(oZ!A1tz4Ie~VL*};O^m8|aW`1I)-L!@n54xXIkbBHm4O6IWQ7{^V8ANcs@EwjZT z^{b~G9UU<#E8hM1hP%64Tv1RejnEoG;KLvO$jh(4L`|mzHD;~|k$ol-gsn1eSOBl!@!m(;Q9Mw;fXEVv-bC6cdiR4&UxsxPlZ1 zBoQN_FqxhbQq1ufA}1;$vL-i?h+&{`IkhpyteK5T5R;(md&*)AXksLy6a^8%@^DFA zI)miNxzQ+MQOSIbWKqd8SNz#7gyK3_~IC;vrgR=fn3azWDMKX*@!CNCA@)7K^K zF-oW`d2_qK?(&X$J|k+0Dl4S3c{0@nx^7_DcUZEKGA6)BhV`DZp5UaTwo^hI**?gG{WS`vs8(~Y0AQqVj%iJyX#0n zawJ+tI=2<#|hP_;T;dkJn$2&R}Fm|Ib0q9 zf)IOdKdlID!SjQ^#4!gi5k!)Vqj^{|q(l=NKJCwWI{79iZ7W!}8>Em_#T1!zer*vE zDWDjWZdH$09Z?MgnK9QQ6E96FUf`dKoSRAAR{xw*OF z)$`}M&5QXv2vni@$N$Yg0VT%(5$P*~DGL0qBO$>R^nIZ3{b=^f%RE2IbEFUmA2H{T6mM_PH!Eb<=D|x=GUWFp z<-7_(LMzFnD)WS%^s^^I%PiOHng*>$Q+rAb!4qQ|r~J7{*Q1na@Iz*(hg^^gDY4q% zw4<~Im8+17p9y`RG2%n;KW{=lgE$f?8?VPS@))2l>uf|9DG!G7dIoC^Mr(wU$Wgv3 zmHb)O<$c7MOs!I5;b1|T0&JFN+v)y}-bp=&fprs-V z16paieM3jo{pON{LK{w|MFk`E8JuP zx&Tw4s~YJF)F^>!`W{&bhPGkY?|J{zk1Q5*HmenJ-?Du1jARvQ^r&d1QBoj!&&T)g zDaw+Q7camXgi=|8gd$qY$;lDhv-f=b-S2RRbDn+sE!bjYAI03zik$CZ6VSArz5R(| zHevbfl%y4|sF+tXKK%3srzJ&E;YSSV?bRiHv*YCXbA++Pls6-SEN2oaA+%&#Pe@J2 z)!Pr0wq$mANHinj|FfS9kUns6_5oKEEKi?|!MO_WBO&I@tHt3VtGinsK3=lDTTva% zSiE>jG7@XDL0w6OMW7@^4gG%0#hZ7$`1Y5m$&~4GNmUeFygy^NTQgnG2r8jNWZ3Sw zy}RYf)6<;eK|YrvITs{I@F`^Jl#j$dhl%#yKv)%gZb7Ztj>Aj*sUbIeGaUtRW(hN#z0Lh?DmHfFClt`|ZawzW&88nAZzJ zAGp6?!B{&Mg~Mu{w_d9i+B%L-PieX?hqWpRF^4K*HM4^S^J>EPfBG}d8oG8zHK_<= z(s}T?*~l1L57Be>=N~!w?(6LJ&}dQ(f|aM$T&x>^9A&CdZEZEnnJ6rOBWGm)c6Qy z$#6=!z#qJ)a2De3rnH)-YjIUY1|7(8I-AX4+s0E(9QXt&P){7* z!)E(PpYo*M6j|?UY=P1er3160C9Cz8AAWqt!E%W$3{s~t+{$skS}~bAib_+@DsJy? z>4qMZ#1xWpVn{NQWG3)ri(}x6S1-^4_Uj!wDXenbTz;Z198v|^KF7;XCk`hZLpz{N z%v%BkDoJ!u++E+XIGt0~1&0R{hF0)!dCSAQEt|)dFMf554?Q6Th7>W?0}aoNk^oSxT0XOJfQb2_m`IpyN<$Ebly|WDr6}U zHc=IpYB|AcXu5`W-{Q0-3P~iJ!G%^tqbLp*=mfiq8^op~Z9BSML-phUpHe28NP!jt z-A7bWfHX9lhV9)0Y1hELIz62HK`$)3vCOwU-isj^IbKjW!8a zN^BvBbVSk8`z_jlEhJJ#lt>t(@m_zu#wa zPhlyG3W1<)_DrWW5OP5}rdN#Z24ZYh0PgQ@sVmE*DiBeiqCqxu7Wx}1mdK!T^Ushk zLZMM9f8KUt&36CDlllmw5-lsX`!&nSAxh}ccoqoc_jzE=&fjp~UvRrWW3@eJ*W6;X z$10oYKfXg7O(Jl6f5qZpg4MY=5~REZQGuibLmD{0`pEOArxeN{Lqev{D`k*M^4I_T zzr+?rZc;=fAod8T#ypf20Ks(Ej5}Lfa-M1ZW1Ru$pz%HU6 z_M{;oW)*4Ta$y_-sULD7-44uDfoun?lypu~yf~(p;5Q9s-IKJUsVu@+3N%9>NQI+o z2N;v9Qwk76Mwbo&Nn)ZLv$IF^59f&87LojDq|cgnQl@k$DX=5eNlAzy=R#zkkIr(@ zw#8aQRh2k9ZhVI@lKEoR{gWG8DP?Avk16$%(Kwg{g>`6U@`Rm4l3@%994|4S32b$h z^}mDnNTqPDK#;d9MirwGF<`VH_#Pz`O6pNwk}rD1=SgKwI#*-bZ$?a#WmX{}r6!TG z);Gm$UYEIP)y80z$whlgl-A|vS8H~oF*!@XG<`Q9rJ`?p`hGx5{j(g)7(;0tB0(5D z$Xq}wCD20BYW$=|l98YOfmhNdK30;R531KZ!2!hWI zz|eQu!yqI>*HVu}Eg=Nb7}}vncum{%bRm0oO6L$Mxp$V7wG>?0RS0|i2d(Pf>@YNGy zJ!6oXI}`9nGm6tCfA#t+{@%-%|7o8ALh!%-Z~uEvVy>r%qC_}{sV8WcJ%!F%V$9@_5Fx*I)DIcYmaRc;x6sp6n+?M#c66@BYK@I5;`V0d6u=m=YN>BBdat zK!5kZ<}v@7?|=A-qtg?F%XFi>g(VlyA{(UN|M^G0{_Z>K`J9l*xKRXBTjsMFHV@KR#ml@;UX)c4$s^EA&W4C(9nJv>AH>ok&f=>h`a4GMTl8B@+ z#O}-QzC+a0{BrHnoHDt``Wd%CXU<+ravN`Cs`C*t4{Mx&iU_<$VpbG^B} z!M7dL7tateXM^RlQlgv#qd9u=1e4&0fBze_)f_y{N$ENBCD#X0<%vVjo8SI{ zm*4$@eu$j^`3;4!OqU0=F|h4gq7>M&B&ERl*V%xFVY%=93 zNlsFr-)&hqmrdR>KS(hQ^nFJk2BL^C=3GRPjiBw&Q8)KrgffQv$1TPBx9CFf!;fc7=M%Ke+nP)R%ElU7 zIJAlsMPfQ}bo+r1Z#S&(8jg<^S<-_fDM1ngkDD#WCkvc)TwUF<--KK+ddu!%&Gayb zvnT175#yFShG#+uTRGa%X&N-|x6s4uC3#z)LC@f0n=`JzRw0jow8Hq4ToWSRI3A)v3XMpSBnKXbdulO7hCJ!M+1zkAeTtQt zq}7Wxcg-2wc+Tzq4eM~uZS#)3xW&{x)0tp-V3<^SDjb3!M1?krPj}~3m19!PQHX35 zmkDIX*aim9KE7qKm@};>S*jCrGJFz=Bm`j?_^W^Rk2BLg2@*NA^tTu1{NdqKo-jFu z*zQUD4mGQCc8k_nA&^uw1Y7_BAOJ~3K~!4fBcvfAmBIu40DYgSU9#!1>xS-OjhK~$ z%23q>VZA~3J)QUH2uo8T+JVrtM5`GNDq16;_qbi2vZnL7l^YfM9SL?MAjc`oqZX(3CI)EvamQkB3`vdk{c0c9dgt@ zTWx5Y2Bi#In@kx?|G#9f@B6Wk)%1OjbNSalXG~PC%*_NjtT9RG`VOfi{V*^LnNAf$ zz&VQ>H$^F>EN2P&+wk-TvpMtq_|1dV`S?Cj~M^0(m$ijY3GxU^Mz*ssHv_v}$M$iLjFF>d&Rpobf!(&v($kRWq$N#e z*h16!h&p&qJbsGTg4p*YDcG+!xYFef(PB#FER(`uf@l51dj=`6&revK9#PB+9@{;7 zx?m>~dl_h@AXO#5JXrEizWN6BxyeZR2>j{%BmdXG`&;aCiJi}o&LOnPVX-N4b8*Sz z-2;bP`|l>{PY zb%vLKHXJOLtZy#4{PQ1~FD6V*Pe{okgdU*_1y9KU=Oy`pT$@ZA{TGpQXC&}_|+>IBF)Vz zX93kk&dCrlZ>$H;`Hye-^7YrKx*GqApSKedAvDew9339=cy-C2|J{G&%a^aP2QvmG zPzj9Gc$qgZN`Q_qY<66JIOpZ7FS6lVDRf=3ST0%L+|k^xFxH`sW@s8N&Oh+<<@4+( zNOF{8#xbQljoZb*Zo44?i-QCH{QEyL>^lw*4pGLS3yakGys%2q?e?^7$MWzPAG6dt zrbHBiqN+GJI3T9P<@p8I@6MRb511~OSsEz8MaF7-A~FfC-hbfe^pxZZq%N5s z=WM4>7Z;%oPYlV$InmEbq!)1$c#1wMp@{#+cT{z9v)Xb{pKsKR}Vbi ztZ+UtaRuVDG&hY(oo3IEzxypGUw(zEX7tfBgn=O@in8Efc|aUIch@&O+}%?bC9}yC zDI_T-`jGR1`V>gPBU2_ycKaP~{_s7g-~NL7=!BCOPZ>hw?T(}7)W+3)sr`#n(#+R$U9<&;FTd1P5QQs@|lp1$uh){vOB>=J~O zd8(@NR^xHKVLq#HM&X>n7>!l}B^7PgGo4ORG9h)AD+K{QB-YKI#cYCAx!`ylLy=^5 zOy&P1Y&uWdd8$cGH*|DEzF<#vCG6OQh1wXA3G@@ZqNmR@XZwWyNAzWV(-(NCLE$^=8K}{?RLvfFJ&N#?bGm z$|Ee8ivm?okMBoT7Q93|)PKk)4@zhQ`bu0EaNQ%6~9x@JdJIf4oVxT!1 z^$zJ1Mj7NPGpSLA;8T|1BuNyK_U4|`*RO~~_79Jkka7Vk6z%4b@~CE7Tgply9r*p8 zhx>b^7HBO{8jKNHZ)_uNw_`f1a}vCQw%O5kEm}y1wxcu!Iw^FNSPV`%Vjn2W0_!x& z3WN+}6Od3=pp1ePxx2gL4L3;(Dk_e zfJIS1J*G*4K&Aw_vLJ+9vJ5e1KEAWW81O#QJv=bIZs3P2T+?DqL}-b^5JSkg$!vb1 zbPi`to<>b-1W*kP)){CdU^MwDwm44Diy`a$GKeJRUaX;g+2#B4YXWEq(61H(Q`JCqbSA(0{C>H;+_Gd+<+ zIiDh(!HA5KRE0$=MIj`8yJPWWiK|PDtZ+IBLeHD;s5>Z-_c2!FBZ6}r1PG4@85BL z{*lwCCrpo);4D!6DWb>#hpWpA+NR;?*;Ax7#3XRW;fzHa&15-e zwwSWH{KWUa`7Pi5H+@ZnK7ERv&+}jRc=3_P+gt9huleTnYx)=wO6OGS z;PX~5=Eh0p=>wOS7d-pLcNFtE$0w&aWBKs@9Wq90=TJ(ZQX&P<`*-hn`SK-cl#t3e z9w0*I7z8De&QVk)sUO(+j@4$3bNTFzdH7+Av$p z&{lJQd&|eO52(R&`|$%`{N;BfA&DtNGdz(fatgack(6Myx?|mLc=q}=^Tm>BJ>l~F zoU5y=>=9BDC37Uq<~2cEJPF|(2Pa3&4;F0h?|8htLdS@!D$dW&`1xFvatNLx~85@m?XhODuh$4 zx(0tV=hJSDLePbQfq;mD*Hy{>@t&GQ@NIthgcuEw@t-32NMcGo*5lLL}9=;Yb1_EZZ?HCLFb;Mwyf&T8(iSG@cFjIX|Y z1yw{ypFK1vZg1|{?;DPuKS50mv%@)BCYtpFSMT3(u$W>Cm76L7LU=;zsb?jowv-1G z9=980*VF9w6qQ5iT)Zb6i6$YOpj=cKsc2U_hHa0=Vnz0Wh)u`-an0o0=a^ZUHLJUx z{mldWcb7!0o zOjO}#&G^mjEz9Krc}|l?THj}1M*guBg1g&$R7xyoC3s2liWCGYObE>(Vr1Ay6hfKN z92@Z|u}fQ`htkbx(kIUSkMv>1s{4uC_6It9Nx9sye4;oyp0Zrbm`^I4loS|rP+6vh z85iInv?q$5+xrzy4xgfssL_vs3}dt5S#KZMY#uo|KE_6s=^j#!Eq}&`lJenw{OXji zfA!0}nHHHSw2kn;{PcYeY_kTs4&C{@;hIla&KC^39i8`C6Bz})&zF%T7h^`qj1qm^ z<2O4}RUl?1i=#Pu2D0H6cZ3ftT!nP%8NqV-Romt}GNe^4ZzQZkNbVkxi81^mC zPM&gocSndY#7I>Y)Ky7}k-`<2eM9-- zS(~>SW8(>6v_)%^zdmb_QechFQ&nm3;~;171AX5UhWz;oX(0FjDL0FK-!jA@o3_UU zamI5}t4w}NF=n2+5cm*&_C4fpt{yF$n4m-jM zM>rI;NOJ;+Mx#+(bLBjo`Rr*8zF0dGyvV5N?&_?{bM{&58{YSMOPb#NsbrLyL^OF! z5O3QGZ3N1Qm^b4b);aJV+lp8uj7zG4A`D{cuyUSZS&|HLs;-UApA;B~811&9IqYJd zf|7LB(bg8>Vgr6?s)&d59s?vrPAdbxiCz?yCXwV)MRaaZ&~-K1SrQG|I76lekHL46 z&RIs|31Qc;`FI(N(ITf!4T;G?Xbw$_FuKP-1lc#rmhtIr>(_d6aveL*%pX1;jD`!}!I++8vn z4twvZr>h%2fBZd{joMkWddbUkK61 zp|oK-8nV5;A+#+nc#6@GAPq_-=tM@JmNXctP{8NU9~q6uWW^AqCL~e)aP;ViwyXL4 z;T@uN43d-7 zbi$E3!P)n3S)808hXZ_1_3}Nv3nWS>l#?m5#hmkRe*?iG@|1iqic-=3|B+J0ToNC! zT5x-I&LBxCCo_UH1SQC(C4=#h+pA07efu4zgJDr{{pkatt$FgzH>h-gG6ErWelK~OY%N)^}T^s#(W_QjWk zAOk`PbZXEh!DI{p^gNTEK&&KxlM5Dz>~)d1hy|6B>{;? zVXfoj@rX2&TwUL?S~>E3!g9S~G8-Y4i>7TAkjjvyBVPaTiKcV-5KZkdQvsH%ElHY_ z6b7_oGMzD<4cTsLmbW#NaS~(b@yNbF-E3;ILB`9ko}rB5_U4YOvnvLwV7J;bosT04 zM@6G>Vlwiy*&5OLQVhjY5l*&mTUM0q;9&V{gBGOk{l#UmXcY#qk#&@2> zW{+qExhzP8!nKw`IzWi~;=2PyG-~6JGO%48SR74bL*rvcNMD0Mu>IkuI6b{$HXe~@ zy>G*bC{yYtgu?{A*qxg5g|V7qNk(WGvPn?%A@WLY|0|bG(IuLA#mm*O| z-&z~-ti8EXwGO>+@v9xuXu>FkQloK9oTP1XEmB*|q z+#q9T0#Yl6Dnpx`&E|mjF?qTu3$iRhBal@`xeJ*0x44TN2=UKx*3)^9RMCx7WGRV` z!yIE2&Up@p8fD_Ty{Zlb@4?f{hx7woD^i_)?~71c;zF-Y7DP%{U-Z)lc0HhIMKo!8 zA5Gv8u$}F}8y@H421DM{PNXFC3Ex?o;`+(F?EMiSFlmBy@f>aHhAhkaq;VZ%-(AG; zDizJu);g5z2~*z3bDPjNRiT$m1hg?Ut;N}1zSVUE=yN^d^JuM$TJGRkZC1!663a}Q z&~*;mTC_5xNfL8K@;s8Vg2$McyOAd;!g)H^A`Mh^O#n=qacCNZlHdbc8m!j1#TZ{E zXeDWy=;PV94ULQ2Kj|UU1|tPNfXRzE)eV80s~ZmciY(6wMiE>z7Fp{N#t^)tU2mzH z9r>h0B#Kbggv}Nu9Xb_=c25Wvtt7fgNV4RC)Ya~4q%oAkF|+BMayVk|EJ46nO4`j9 zktMh+1!X9Tf-*PkZm*Gffz1l6Fm!c|>00W$6@x*6@Eu8#kg9}qJRB0g3D3_8rQhk z2>5`bhvGL4pWgmJo)=7yAJYm!+rcQ}u?mc}+zzNNE{BnXyQ*A#<-ufF~o3w-$a znIg?7lN7H)gwFUl?rPS1_M08^7f;brqx&otAr&@w2BQ&+lN0LAjyJEr2XA@){29W; zFkrO0Uz`(^?8h14x`z5tQO*~5sZdGApd2wB&sg8CxHvl_NfepVbo&E!+cJInC|U=c zkN(4Z8-R|8T`48fTF&15z&C&PuV{tl)BBImcI2tSD0)SU#7nTD;^N!y`Qk@kbGzMu zgtoItonX?G$$ZY^=Pw8-KE3~e^KXC6(HF0nK6-+amM(M=j3WiMS4H?9VI1~Nq>>4N z(1yWqL{XMpou6}gafXtCLKg@l*nWCPV`~<#Ua_lcf{k}~W)kMJ8OkKRqNU(yJmU8H z2A>VM-7P7KA+f;CEV81@_@%?AsefY%1%?0->A51$am;6%!yZg}=&g2eU3p6k0_k4jS7xa2=oi{sUkB*;k}_&h_;L zsDM^c%He{GX~?3N#A%PpG+AmmbTvXivp=Aax6^G@9Zqp!az@OidKbqnSNhT~s7LdvzwV?BsX*t3- z4ZGbfI(4K&fldOu?UKPL$16`#B#cJ`vP`kxZ@Ia;j$0NbFj5g+>;c<&+Jj{@9Fb=k zGAO#r5^76(uw*7D(Hdi9B>M=DP;oON39MHYlW7UE!Fz!cGH%_1C*Y!4%xRXl8|I5S z8W&CMPNTg-HB&gufN1EB>tBmiH7;pjxWtz4p}ga!eNQMh$Yje`U(Xo~5|j$Kt|K!! z(#zf-5n`4_RF=esLq70%W24b$e8`|4NFY%M=|Fip8cr`iadL7@mZZJ$+xOZC|8Uve z_a-8MP7QzhKm9vM6upQLD+K?~``>cgwXxV$0kJx&d2q$jEz#$wQ=4a zVw!Xo1aep7m%I3#XG6N22rD=^Y#qHfsng_6LsgR{334%_IT}O~$+m@yEp;N1M?-{w zp)P2HVsmJs#=30~wnO_s;=u13Dn$5-TXaXBOa*t+GizW z+IW`6l-Nj1lTqR%6kXR*)zt${snM(RMExb;#| z+qvI2uqs~AZP!Lmg;EbREf2I^iw_>#cD)2j^$k=%i0;#Zo%iT8A;dlzrDIaKZ7m}7 z1T3OCbu@^tyAKX21(}J{_0F|4Ha>Ss8|tQws8|=hIyixo1{Nd4Bqn@|zCi1o#d@%H zhie*?3)rfnww|D4$f>s$jf~I$?~&HiYz}mdB^eBmsfoUjuAv+k=s`-rW2~b+?9qwA z;yB#hF&LHDt|c261fr}YZp~t2(*#damTaqL0ueOuvBv{DlG6^r4B zWSEiMt=PW(z<>OU|Cv|E#}8YwARN-e-@JK`DTa)Wk5OqxF`Cfz_kZvK>ny%=2;b+s zh=3Lnb_Xs$eB|iGGX^KejE|0393S)c`|sJ^-ZGg_*(-*%i|p0iplK?o9+;)11G-(WX87GHivGAvO>k(v}O6O=Rr z5j|kZV90cubN=0TB=Zx_&n{6SFf7ZsnHG==h4JyValx})uSv5aZaRb@D1|hd`O$*e z(Hz?zSYEHWT3xYx{ac39DYK_vkmxK9r4;0&L8J+afcD_6!?!id<&v*{_H*)K#_Ddv zdc8p!O_F7CxT0dByA6(}ZJC`MqyE$LfBuX8VaL1}B2|<-C<0qsbJuJm{RY7&BQmybogZ2p1F+VzCUnzd~ z_5;sfonUl481CPQLsMg&WilS2(}cUbHFfLA218bx4a%sPu^@ecoMYM2H=1AjkqKlWSO7IBsL4ipVc87|Kvm45+Kr6}B%^kBx6MWJlGMLR~ zOo|E1^@{I*{R2;5osgFaCN-f7Ovj{J(QfzbK3p*#&EnKK0f9v-&_+OJ7$!M~^%^tEu=Rn%dd)CR$&A8p z4(yvfgOk{Vm`RQ>8o%$@y*rCW(K4en5-%I%K!UV{rY86fJv5ksMg~vaF42hv(NL5L z()fs>6ChGcF-&OMJ)`k}?P|?txy6u>COL+bYS&U01%!a<mU^caAJc8JLvO(JZEDYsJ2)`V12w1eA@92CE(3 zM?<&EB(w3Du-sFxcHjfKNEpeK>TX3-)yQeV;HxK~K<^rwvs>D(BY%EOJ}fzGE0)^> z6%Kc(m|B6k+A`dB6m_7vS)o7OqOX^jrs)^hv4bBU(>en9Q2+;U9+zacziDalC9vW+L|Dtbsep@Y!5r?Hfn-p zZw8NYv=pu4b9|^9q!4H++3)sr)}xI+YP1d1 zH+Lux)P&SA#s~^+(;*uzdd>Th%=N zgRdzDQ_vcvC8;!#m`R9I!Mb95bwjq8F?;rek8eIOnv79eqltb(Aq3h-(aYV{6;;#n z;$>_y0^mZ3`49y1LBU`+;>|yP%Q#6mY}cgYlF7+2LMj9b;Ulrk%1HTC0(9qi_q#U? zrW1xoM}$N(8BYkE0mYdU4@}gk!=mbZclvh<9)4IK3y#C~J}u8RtuGz^Ai%=Wm)W)TM#orqhYVKHPh7;=4e#qDYtvn7(4ALeB*0i@6N4$-^y?Js}D zPk;7DRNk}R?P*&}mS>FTGqOD6^7Nd;YD->bEI)l_esWAYnZ$6$K4|YAgDiURK#-E% z?G>l*-}5j3{a-Mf9&vqr&Dn=js9VZ%fC!KT5q&ncrK=m#Vi3cWWgmPiqfb~WMLrrZ znH)1372N#rn$AN$7?YY5QE0L>B^46Y%VfPEN=vIf*B6(}o<1iS!Far&7>&5PyOa5u<6ndjDEi2EsUlibWrp8gd|)yf(^M^gy}IPP(^CYB zR!I<1cV>g&cv|vhund($^<90I8WN+Bs;AEMTMHqhUasj{bfQr@>i4)eP0=?UBCeOb z0E?%#mNqz)js`!6=OLcH4WcAXNbntK$Ok36Ltwkx(mI$QFM33xL-gI|)y)mXFk?{WB$?s!`4v@V31|*=!)!4@ zXa@=$p1~kvwish=lz+9gi&6}02|>_QDVLX9j-EzbsWc&m?*zr|%?e{O@*>3~CI-0# zfshHGK3{YEXi8cb2IYY1Xvo>eTUMJ5MQJEU1AG7>0<~!nMk0-1IvIn2<;^X|Yjhg3 zB+h>Ond8|J#j62(RS|+kNQub|+Gw_$4ZGEbEKNugg;gPj^lkS&3K)VBFiIF7&$)d6 ziRC~3z|m|%Viev8go-%|Y2(WIK>hQh+*^*=u)f?DFzpZJiJ+s+}a#%1P zjcD7J+q+x3+Ob>hnU2P21j;F-HJD&x>iVH&I-ZiJ8F^k%zk|_7#OwpUJf%^0w5sFu;sRqb zj!qUxrTP5visO?pd76ON{h=lCF5p^6V$$Cy&i<1ogCP3mBc`E?e-e7w>yzRH1>gEn( z1Bp~rzGd|431&K=TkR?80J|1DE9f-b-mbV^uH!~_TVX!mF}pmFeYnGaxFA^_5SMqT zKDe}ME0RG*=qIz*#|?)PlEi2dZKBjmMdDPVC5bUO8w2Z{ck$&`660^<7!||tAduw-XJcCJs2pMvgLCd7$0KeJVs4SqCgylZLDMwUbrmyTq{Lc_ zF;N4Ynk>rndP!5BN2;9^GG;C~8}oHigOZ|`&BnLhm^3zo_x_V8mVRis=}CcARrmis z`kTD>@gDH~O&n3e;(X6d51y{Gm^6DZ z#@B5dN4mre67M|13p(qOUdBy@66{lf8y8p;KQTtfOr1oV_Z%vMg{Y5}6`_ay$a>7|ur#G~zUe zsv|f@suHwR$SlR;kex+a%XBnAIS0;>r#Yc>)awmwYKlq_)(2$WQP&kR%}B=+)F5YU zQbMBXtVfBITcc>az~Bh`9fMJU^x(3T_2JNy$|5@0WQwp^vHA7~%phm*<1aZLjQEQ` z`dRcy^~I|Yfe%;Lyt%%nNON?OvRW>qUv!Y;+cpLkh6o-Ahnlk=-XaKm@zbvfNk)RE z^NwH?i5E2612?M`Uw-+D)3@(Ae*6fPC*UJGT}eaayLr6txcc~!yZ5Jj@dsZcMkQ5n zC?CTxi^-VB&mZ&lH{ap+I~LP1pI*OVJehI)@=LrnQAQ;~AA2vg8z;H6*{KIDsyB*WXC_))Rz3zk^B+X~-1HI=OqQ@Xn)3P| ze~qhZ9zA{9|6D3IYBKa@W`S@X={)b>{J{L^h~d$33~WWF*R{>@J~di9*$X3N=!4|r>tjfXLSS<1-E zX&fKkzGePsfzFFa>~j6ir5|J|ttsbIM#X^l|M+XF<&sCwpQ3ac&jI=wSRigz1Slb> z_FHc6ZaI1Kj1GZCkqrjS=QFBm&&8)tbo&DX6H(dM%R45IkLk4JKCM3V^he(VKmr19 z9hX3ATxo)oG$POjk83;jw@Yl(GCV#)q$z1$(Dg$Wr4vM| zna^en^McdUk6e8JhT+K(gW)LVbM=y0-+OREzp*4ZK7ao`Svg?-{7Yn#GCi4d{OBol zwdeBejMefEsU%sJP+i@|uP&r9$AhGFBR6q zdb?vZ9+BoLsev?4A;e3}`HJJ?G4siY>QJ-U?+GaCt|QAcloAAN)Y=QdU{G+VS~};s zTdt5&qEk%}8s`Pqw>ONZLps~gc}FoEqLYG8pU$Y8hRJM%(x43Fg+QBxL)Bo?gu!UY zcE9KR@{a8`Fc=hEoUM5FVu;B?97U+;9!*TnzG|u4hTFS4lu1dl93>+O=jQg3qmvnq zHX3w=WHKumjB=cV>#G}FV;N>+tOA1OusM*GIg=+NvQfrnzh=3+h0byP`i7@pJwweE zK}PS4B{qD@D2ic8(kFMW@9xNxjMOCY!W)-(1y*>x283fWn{a4rlvb>-Z=ki5X^K&T z#0qXMu9?0#!P21zDZ}{)Wh8Fba{K*T7AI4(H0si|3LrX~YKNDK^4T$EQ6Pe++AnGM z8IU$(Ax$(v1+1_nnW7kEq$cC??2_hC z;VMfm3o@BU#Gw-$b`6?)BP{U?kCK|aDA?~iia|n>3WD#8c1K*ihB!v~{PB#V`HVrP z`_yy`iNvQZqOgRb!WFmp^ng_zE(q3}irecAv+;=exIn6ouE$u;7X?biWN{Ir4N!dp zWAB@daG&TQ`|X8}@&aOm@vzbOCtvZ9hy9^qu{es-C>P~Y4@G1@vy8tvHXif^2Ep_4 zn;-M!t1tTFAYL|SyET7(^_g8&Q?)e+$L-ZMLMTS_8A=Ma%N3RD2qNltb)p##N3?Z| zwefP*mBVan+Vz2SHbRaQvO$L5S5#*=m8y#KyX+aNpvbrXswMyn?CH)sQ8@aJmtfF zFEYBWK?sRSGXl`{A%o6Z5~Y!S$eJ+;U5~oGPdI-l_`~mmHbcMvvewad4RzDd+76|o z*TwYmj;3u1Azq5kd9u7ADsp1>5}& zGb~6ZC3%{lou@t==tML;r%6I41oeJPKFDYe6&-=9?&#WxclL*xrmBJ1+%!#tJ5=C0 zOkuFL0cYtBHQl~qh(_NX5EnbjgCnatGHDo0CcX6P!1DY8pK8zv2PfEOQDS1cj%K~4 z7!T1%cHVQa4hSd*CP-W=DHBb5b;bPE7uea9%nAO}pZqH_Njz8jJAAp_^Q*US==L?i zIZTmpd3MfxI3g=EuJ5kFdQ9th|J&cOSS(mPdxBSr+$)5ZG`)A__UwY~-HJc>={F?v zIfLnl-~QEqXIP|ArU<8zoxrvg^_`z>ps5iU7cegH?#&y<^Eu=B42kZgV=>pvd4~^yaymvy!LR=EuV{8VUi{>1T$W&z zA=fEMn)K&}?&EF(!8u<4@S3lG@)J~Ia8i;?M~r4u*4H=Oo?XNMIVF)HaD8z>S`?Iv zdECB)IHVB0+~+>R)e4XDp8egDXFvH7Z{K}Dw4OnlBeZ&u9Y=_YM+DE+#Ra4B7?b7^ zWh?uQjuI53lJRs(*S36o|AEzV$)GGLiXxJ(9JjdZtrf`o?bASjmbyD zhgY`eZ4ijk>qtQqg!aG>zxg#U{_qbOojhi8G$S<$XXj^JUtVGBhC!O6i1fDg)dg); zvv~HBR#=2g;@KZOC`~z;G8mNHTwZf^eu0*X=P$lM{g2PS`9+arXrZvy(%O!??E|xl z0dJP)6tAB0tJ_nyT}@sj{Pg8>zQ{8E{70{Nq!o{R$Co3679J^LxK|JXsYTTM%P6N3 zO5OjwXrrT?sy82sKEbf*T5Q+Rg`UwPh^|=~GbZSfa#8US!`<%3r#^V9rsmLg3}-Wh z^l?4xHFxVJ^TjYqcZ6b44$x`JyH7XN)-zj7Vw)A>G*PLjPeux+(=kPvbGN?Z>~hIq zFy#HmGp6$?LB*fd2cj7T$!61W@@PWS9jFe0`C^O@79k4G&(};BGg?=nQb9Q$Af({) zhZU!v?)dV{C!~3SNd!oT50a*dYyRnc%wSkjH63-`Vsy%8vtv4&qEkVT@$f*#*QN80 zyet?DN}Ag8`TYf{C@7K<*Kh8aznIbJ11@)zlY+@&jI0G8e)$PCQ_P;sNnA>>(fAF~ zY=i)*6r<^wJkMBP-LSq}q7s81=IBHdtnEKA4r>EdXPG=+P>v#caCLr3y{#!8?pHXdy{6!*En^dwa{> z?Hxs$p;dxwJWbX1(ho;xJzYPo2?5rtnzlVK9OeWYi%pG=LfsGuooBb%a(r?W11^yW zjK`!)Y?xJBL#cY>Tft(lkTn32CC~ni`R6iXtaZGf;6$<6WSxyC?~& zI?_#p+Z-Z}bf_52N_2p9TNApLs%_|2dyEx`+QroEX^wj|W`C#Ix1HqBuvU7F2shvOfxzc`6miNstrXRb6H{+=KB&_ zU`&E1&;`$GyP@gYcm^SQiIc{9OV@VD`->XUqqHNIF;bjtZ@iW?Jx2CEP_Jof=%q+a z8zo91c;FEB|<>S=-ZG=$4y4)8~&aaWxGhOa?X>c8P2*s5j|3|@;t+s1SJ&0N0}2r#7%Wp z#H@(cQq?g;FH19w(qvhRHiq?P8w`F+sn=KGX$CKVnET|5LNE1^E*LDoFI53@$*{oJkcBnMYdV+^`xuR-XL>e<*$~?zNfzCC_tU%?OOlx$Iv{ggc z>_~18sM9t2e8r?wF^#>*XiQ9GR^D^yTAJ2z(3&ny5J8~o25d(FR}0#^*#TwL+L{hNQsDAD~eF>ZzSRmFe%%m0_V)g8_LK+uXH0-MWgW{U-h z(X^{ApI*P^iywVOI-BBqa*q^I8`P~fy#M8|DTV`%Up~hQa7dC-&S*B|yZ`TR7)Z@% zI_+_uJKp^ATOL1p!pT=Ju}VdW5THfO$UsC&Qt+PBkDnNfhs@`5zWe2Gm>(Y@@(60t z_nTo65vJ98#p&Dkym1d_3do{ETujCesGxJ<7xTx9^xtXN-^L zQG(SuI-(@*u-u@0KqLyU1?^@-W)en^j#;g?6oV3zXmp4n%MSy95NTT<-n{1M@d@d0 z_^=5Nu`pn=m}Am}v(r;nmlq5Y!+O2q_~|peO5%I}u=NfPMLqHj`g#MiKL~ou#5Sl|wCI9)K z5KI<_!)d}~wqQ6KvD@yr`23mW`6bhGNVi?nR5g>wPYJ3A)+iB^)P;<>CP~6;lN%XN0kc#!bVlo?ZyS&3_8O@j? zB?Q5Gvt~3NAa(R149c8*FyzhKOFGvv9G5*}Og=ERy^qD}vu6v&(-BfiZf|z@P_W&$ zc+sI!ixmwH5K@t*l4>j2Zz}>VpfO3-U+9L-=D?sVK(t5=Sy7OsDVx=bx~?flWqcrI zlv2f_G;nC5sU0my1_|?%8LQ2P-M&J$4l~gR9gs?riVSH2X_vG4wB^~qe$3mqA82kZ zMn|a?LPX7VaJ0fx`3|oIgYkrXShD(bPVf-Ah^Mp!yccMZu({hXoD5N^#Fdg_I%HUm zx&HMVZeM@q$+Jfkg9Ixro{p4&@UXqUX8z4{MqeDE2wcDYMA+73%5b>2W&H94kwEKe zbSBZcL}vn1Ksia-tZ$Kcv9Lr713sMv0IBuSja_^#{8%<=hJ z@0U!DONvQGF)r9#ZCKrIkU_Ivu9=J{*x+KQWUsAt&eOI~RXb+W5#EZZkM11(ejEtQ zCetXD@lj3{GY2#hgK&VAXe8CX=JfM9+87=^eiG#~QsH$xeAa7Ak_d)_6p6&UhA4j$ z4^k;YTot!<+vgo<9vroOLvl~Yh#$1yHy&{#6Xkp|-VKDFTqHzzIAFv5HUl1{Q}H1U zs50SC|Ki{OzR?KKDarrwn_sdEfn8UVdQaHbcp>mQ2H6GY2wG4S1DdME_jB%G;ZQXM zFEF(w*;KgI9#tk3k4F^ql6t#E+-z{R0j+WC8V)V(`hf2|n=Bw-9pSYkSv81`YwvRa z01^>NL_t)mE!{ZdCXceSL(|b7Dx`Io){`7s#Ab)vZsP1oIIQ&KNkXAa%&(9N**Q8a z!8??Q7wkR$RcRfKz^%oY1nWGl?O1Ks)ULsaNH&o|;%qd$TW_PN+21dT0$Con$U;SV zTMw3sD{^aN27wefXCqS92huD`yV|bB`j#}!NOaPJCqnOi39%@=pAM-&=esC36auXc z)xI6)UVMjNE}h|V$_PmsnSv_X3p6N9CsYc2KuKvP%b zMUKpJLSw0x8%&xYitHh4p}M(>y7<t20}U@^Zqfb{fuTD|tC3RWRS_Mu#O3L+`VmPE+RV-77Nm49O&o3y7 z0yoI17HdM5(i%mgIu~mcI$EsvT%Mld1_P3;&w75wKmYPqZ1-~6W3B?95cu7H{uh_4 z6%Ar&7h>RSxnTC>@naHe*?s#RdXpOr z`#E3#@%Qwcp*I+!$WbZ*0?XqQoi*iL5b3={T4mlELcYjM%n# zZAtqBLN|M$lstDz%YD)z&{S)lJ$lG{citxJZ9ouBf9o`Zy)m(Ec=p9N*bpePj0cY& zQH+KRwzd#3n!;Pq3NkH5l4aA77dh?aiqltz-2U-h(%}XhgAudmFIg=wN&1DH4@&lN zOXSga_t@SXva`K|M-#Qs3Zsu$qiJJAXDO5M7*kjL{y%=pJ0HG>PIHV(W&QD{dl}W0 z%rbC(ct}3zQ*4hh-e97^^>a3M$CQh6o;-YrOC4FB<6F@zZ>84NdwCb>E}uSC+gBq3BDg9a0M`OST9eeyB2F_^@W^fI=#w@4Gq zvxkqkoS$DCw7!1!g!0uf2S5KSqIN<&!wWh+c6JU%_Uo9y^!`I`zjp^$6nyj5SK`}a zj7aX0crPkNqBM)+R~$b5o)13xOSDOa^@0Jd(bm!*4cQuRk@s`H`|du+Pao6EdJHDJ zq(z1^5-S;`VGxjld+f|i*Gs3XBZ(1DO!?mhSpyQ;Xm zHDOmfHj{*^oRcMnLE%s;(rSgb372I_&|td>bgvCwX|&5|m8Q{}Dn`};N*}30q(RC5 z(}J*VmBt&5H>Pu66$|&EHKB96j-Bf^CIOeCtP>~75b5{(WO>fh*XO*PU80?1V=S3w z)It~VI_1^zjP1#oqL)z=Jua6O^TnF9=&@LrWc?mdYichGv1%g?26SX=XUx&`H8#!A zNlM~!vaH98!$a=8d(d@U5Sc@oGe28%`0|MHc&n=zYIIB>CWPqt?%P*<^66dPy1hf| zTTWjun4K(1T|wpw5@#hQ?W)T#7#=hjp|;BucTor9$r*3MRbwz3t+*RONH@Lcm#hUfSIcecYhkbl% zxHvyYuWS6e5>#&$(CeCdu@cRHVHw=nBkT9@i;8BpAX<$Y5AaG6+7?~cjGD-J8Bj-a z!r2A&<)w5%wV2CgiBN>vj$!P*$S{5DNs^Q_&9F%VO3}2nRLhj2tSXw&O1CBW>k7QI z^#xDcJ;EeOf-)MLSkWv4CNU@j*2#PA1FWhwjju6@p>90hN9v{#DIpQ9Wlp578-kBy zS&mB`K1h%(1q+Q=9xUiYW1Xe-@>)&P0-7|>&_)0sd6AQ41qw~wc*?2J;?lG;zNI6}(wUWcrc9>8DHWgFCvMxcv#(0CB-E9)9 zF-Dw+fkq{|zN1i+C)si$ot`hR1N7gH(AeG3qG|M$v zmea&Q8v@EG7Rz&58nTTcr}GO;QDC&f`Us09yFM5!!~+qa$XAulV%mpHMkR zP?`kkIH+dHvxg5UGRKYEH%Uf)&>9PZoEBpUtTtG!xwXB`fB){c)YDTw{hPn0$uf*h zu^sJ6X@%;%MO~ZhwuLzgtOt!WNvEtRo(FF`S)xMdSq6N++?yYU}L0R zEP3|qId2^tkY$C`89I5R_d=j6@`By%9cD+bc<{|v?BCqu#{OHVuApI+;K~z3${MvI zv<-P3c=6&n2k*R#N}LpejAl66pl%vw(7Gqm#n46rMuY zvD8qPOi!lV{n00!o}KaX@Q6WT>7@yw+kPII;s#Hx7O-S@k~ROIaaGBo8t+`N5`zrP8m2MZi!M_ zhR_qE2)<%@azcMNq(2@@7f5v|c%?|JWoxoSnrEENPno@Z$??PcjCZ!#+`rYCdU~Sw zScJl+V!#CPOfuz?M_+uw?N5G6F`01l_5o2TUOoGs*Uz4jY1rszLXtvrar}a+EZM*N zu@uZZnjPMQk8&Ti!u4`?Z|74Pcebmc) zPowL!!%~pw%2z5t@OTrch_qEn-#ILjc}8u;tOegyEyWc%c34?;HQ=qH7;`C!ykmUR zCcExVTyH!-9RKfP8Qw^v;JVm#^+)%q{(r9*L1~(xxx8FaZTR#x-n=gLt_z{8BxkWD>%(7LRak@oD);67&TS3#^p|0uPP8#L}6*YVqMl~ ztFaEE^4Gyy^oq;Nn$d7bRHb|^I6@Ody5oeH;ji8sItPMaXnZSyZD(wBB~J**CS z&vSI{XbgxcoUFOFsc?yTbCF(muEsUiYK)cjcD;%^iH~msiMFVyXqpCXCGb`n%CaO) zQ(4n7phLg}g9(m$6)@4t;HuRqW2AYjJb{+7USplXXpJT5o`rDzv#&NTt;7pK=C0*u z6Xi;)&fzn$lI%jKRYiA+0n}yHU8Cw~OidT~ca@5Gl|20L(KAxbyULEQAGoUok# zfB%kAyiy`9O34td{QK4QUwsa$?OxKt-oZZDtFH%q(EQuyf8fjNl4V;%Y%vS*9#}UO z`Dl|QDpt!g(ovtfm5tEogrYZOdU{5^YRE4=*>p`aontbC-5;~wa?sTD&(}03XY@u} zG>Z~DU&5jS6sxTa{fj%q!jYV;=^w6GG$rNx+nn1-XrNwR;w~!&r!~px5_P$PwnS?= zNKBLf$2!NlsRZ}ixkxuvO_ru)PNX!!x1?!G+qOU0|KxVJtw@>@XDO=+ap#cS4lg`MstQr|Qwi@pn@KPP~ zzQs9*O%lp_jW&kDIhwkWAkK>sG96|2>nG)u{{jI7AfQ4{JGrNlv9W>BE6 zYN|%aT}|zAsUgOeJQvTD$_G@UuRDshOIc4wl>2>ro`6drNT);(3eM`1OgnV#Au%*~ zXamE%Kxxg{ddVvBkyggn#gLmeiu~qZf5RXC=W|+@(BItRczVjKlPMqE{g7&Q#`$W_TYvF0lu585 z(A1ve@9(pB>wt~P4(H1SNtzPrgq~gUu9U_T@T(QmukVp$n&bPA+5O2+$ZqV>FJ!pB zHK7Zb6~QRN@`Be-o-*3sr#ILVExR$ap&|MP8xzXq8PC7`3~v%flL>WMapT}!qD@4_ z5dzv6R^^(0F+gJl>QSzE@$eCo+xw)wfmDu(gw>LlPoJ>+_5r%rM|WqWZal9ZKV`VR zjdzyRI0<&Gbn8$`D#}JWALlQg5v!8dCnwx|{{se-J%Tn^3zO-*WKN zk4f`BF?KV$L5w_Okoe>5@Q_x^>{vNHa2=Rsbdw%E^LTY%LTD*Df%0PAf2j<`6)?JQ0z?5iR)b9#hmp1 zpFZQGPkst61!H8-ixJbgqlXx!v#KC0S3Ldv&*Z&6lMg<|4u%AxfI3Vfowra+d}B22 z=^+pQ_$Pk+_rHc-pSo>HjiFsGsV^>geRRmWT65#h9frLzFYkRu+rs$nk15NFw(Idl z50lAmXPPR?B&7n!4<52HC`bmIRA&ojM^7;un~e5uk!QImg;3J@Ue!E*{FwKD`3wFR XqRFhkGf9$o00000NkvXXu0mjf+KmGd literal 0 HcmV?d00001 diff --git a/docs/media/overview.png b/docs/media/overview.png new file mode 100644 index 0000000000000000000000000000000000000000..8bc6d2b73270e74d195618aad781039c4c6a0976 GIT binary patch literal 2745718 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

    g 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�VBGrxe@^P^^iY<}ia)%))3i$9duY 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

    ^DQRY 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

    g&J2i$n*e=dAO=2>Z#=~x&N$IF4Q7ZnBM z8#jrgFOBN;tDn2%qrN*Y{McX03uXLR6gpxPCq|q2jRYoI53KRcTLq8uz%a&hHj8OY zri>3?{cXLJ&cp_OGKLjt)~p5eQ;(&oPtIUNc2;aIj~zRP1>n8Yp@$wAo7JL0^W}?F z0RsS_FlEZa>7IKYpwC~zDfUaEZ=JO5wrTtAw@Thk3U|1m9CxFo&l z4Tq$6pPU!bOe54blrR2t_n*^ak55aFKRG=uMp|dbbWf9dC4+PJ@){HZJ7Ta{kntGL9f`4#AFT6%a_5QeLNe;MZce^ z;r{~Rz+g-QYDUE^#($yFdm#-^+|LZh;P96h|csm}HUVG$2-Y#dR-B)jSNunuc<3V<%DdllX1eR{ zKg4(?{ull5>*@S2{vh)E$&W6`h6E%S2A`jL+UZfDwG+6zx(Gs{V}}C%-`4d@g$mJUn|QktkhB?sVR&f z3UKr<ThI`=vks`5qMB+EB8}9tu5GTzQyDFN$|~ibFAOB;K+nZZjcd z>X4H$o^ihDN7-8CGEd_#6$FeiCPAK7(W)IqKaS~O%>?5b6!TPU)WAu_H0KDeMY?`f zhvJ)ctpUElJ}vO)nPsuJ%kwIpS9(|u-U~`|#W31O8ML#vHg)2X!~DZQhkWcAV@?G; z#|h!s_m_w0d+DQdJxI??(}MQpafMx87bXhhBxzRmF6tm474_Fg9`G;TW<10x#uF;m zzar#1wA|ocdJ}yncb)ATFJ+@Zjnwtz=dfCg_kA$H$@1|NA7KUz^0NMX>{lG-z`eZX z{KR=sbrp3&zp8Sao-TTwr}1$;+;p)iNd2qKD5X_Si|b0#;dR1%^+X?@(3qQa$xkT# zwYK5YfjP8u72|}$D>NzaS7FW!TvzpQlf_FGq705v5ORi|)l`mKvu16KV;vYNc&LvC zOD!15`Rn{mgF%Dy*deSxj2bp7ykpd&Twa4A!kWglC>^qv059m#asj8)Iu^^%8X)O0 zUhfUkURpSx);p#Ojjm^OcIG);C+{so_DY!NlcpE{7?+`48~p8hhx1G4|3d~1M>!a! zPP~2SS#jRH1tJ=U8R@-X`Ld zKWuJUmnu<=ZEtHx z7;sRv~BB$T)oct`3uQP zokd*J{)|)bxN{XTkN(04v@O#My9%RC>0i@r9eRjWYgz|gRPc3;LFL@e@Diyp0t(G2 zC^s~~b3Avwv$hg1BKAkr4OIm1(H4OnRZe@eExDFtyIYCk`!?HbL;FB^n%pblv22h_ zLhng5f_iX`$8lmU?Orb%DpqSqB){4Jbq9GU4?Nz5A+x;j#Pk)w*tDSH^}(;*XVW4N z#2TQ$i<|Y<}H|;o?x%JsbwW1qTZKihcr@+ z6>RWXRx?=%GC$7UGa#ebM#)`6Z43f5j8mR-tOupFA#T5Qq%u zxQGmx54Owq=A^N7D{|-J6-(2-_uRue1^sW0@)3|21B_$;D{S-4>%}~z9F8SD7@{bQ zfGYTaD}A1L1upbmmQ&*p;mnykhc%1E$TW;~7{GL6u~0?d(~EaNKT^4xF=*OTQyGV9 z)3~u)r9ng7KXgwrQ^~pzd=dJu`>%?3FT`)o)zUe>F=lCe#Tet9z-K{=D48Rl^_1(X zlEVq)1&uj8(!tXC&43=?UIlD;sRJXfRm*0i1#_mPRZFI)%|{_?0H@LuzZge5)*{0r zTWKm)KVnE~Zfr`8%T}kAi&v-SRm>L{uNb=VeAkv{O`DYlVSQKGh8Jh*rUzMNW*8OKu~&8$mH(+7=!27R<-+qeJ5n#($t#QO9BJx87=56kIU^K`0k6jzV+TM8ZxovC> zo|oscrrI!M5Kib?ftUFP!bHNzhbv{6+>Zn%sUDePE%TkG)oZB__<;SU3fh0U{8!sJ zFSU=|G`$Or8O635xzK!KuH!XmxVPn6S(Jy0a}MnM(gVMo#{_QhxVS4f*6>bQq-GuR zAM|j(Qh08+PNPiZ;o&5e9|N^11V1pLOGg z*@G*cSGZSeh`AbN&=4^W`a!PAaw;#$CkOcw*x;|MC0zSBKhEjmkW!zLk8*BxZRQ2j zMt?~8H43y&Ex&V(4$3N{dmxEv=$YeCkc!Oc8TZn+bDnw++WdjpvI?=Ojn7$GjR^in-PZ#~473twH?yq=wh;?rQX=h!u zw?lL5g87La+nt9<%e-b`Eb0xOt?1Q*owBiWYWg>xal?8!IMLtOxWw5#i7LE2cGYqZ zY3&QmQ=={GOr8v{-+Met6_el!Kv@$H3{I@;AQLwQ-+u)@In%ieazczTb4_@ zJEtAuni1FGkr3QFXy4M_b|OA{QZ#Sp`ptMcH6srr>E)SxD~{17p|Sc0_C=1r&O=EV zd4*wq@TYw5L1TFTWWAuZr6cC>wrz2A&)M||WdZ4I`?oDPuTaj=NLz!<&Bu5!{h**- z@Hse2cjtT^^eN)10jzVsHQ-m}`ibq7a(Za2zpi=drLdtJ@0jG_zI z*+;a}4@&2H4mGN)v%SMNmJXQWWSOn&;jF#$6W4J8&xZHV=tp@TWwb7(L$Gzsp$5rs zd^D_;ubi*S9~x);HDUi(?fKV4ABa0ZfdL8(P+))p&m#pK2lTq8Zr`Ur{psk(3-GJ( zKI~^>K_i_HeBc8~PkMhTeDj;%3~zdc$1i1?!UJEC#yx)Hz2hD4C?2i%yXT&Jrl0=w zr|B(kc}tAVzI^DRhvKtd#L~^tM<1Oox#W^(yxI@Fy$KU0^cj~KK?efr#c6D)^MRMW z>}BbiYpzM}eeZkGDOemZeD7ytK?A1?FT8MLum0tqxkqZfJo3mR@!1ezY4v;b9yPlB zYs2$V@8-Gfw%c-u)B~X}xgp;;_bS3iKJt<9Bv=@dX+$;<{(1@&MwT8>E+n8sk2n27$u=PipT4JqLbY zd=!W!zZW0cFC4~OY&9NZsK+Bi4XkFeXujP}S&{Lt#bWV-`RNNEIb%HoC1ET>$#B}E zk0cGt-hJjr(sA!R^if zp?LKB-~2M2^Y!n9L1TFwugmd$&7nu6Yf)ys5u?WP5aoXC(RAGvm!-46`b`Y!UfcKD z1*9t`|ETZ2xR^hC7SCrDx13Tmq0b;t+{)9OaMG!W( zV@!ATWtXI%pm-|$=L)y}_S!z09P{@7euhC{IW7Ltbtiv*?Ngr!qstBPUdYCf#-TsI z@cZclpZwHDJ?a%{6sUjkqYLBXqF8y*cv3!l%e&qa3rq#gUEJH4LEzuR_vQI+c>U15 z_w+s5SiZh2HxS)=(st?Ccf7MN&A-aU-(w6|lwps(_X&eQ7c?Kn(Di^r4lP~{{QjF# zz*FB`j9o9d=*nLX`B$FsWN_AL`LO6udv-zD6L0yC5Q^VS*ds0ruKpHK+|+jQJvL}q zxwUT)7*PUd7w-F)1$nQ^4ZG6fI`Lh&-Y{f%MK1mdfXyg2By|B^gh`XOC2u!C zFyemr(J*)`-ktciw_?0CnuTpQ=-fnbQ`60)jF0i$STHYX<+bCT*M59%8W+gRgNycA z=?A?04|?R&hRPQ%G_VTVl@gnG-pJXYygb*S?-!R}-j~gB$Gtgl3FTHu`sm}2Guh1V z4?pbCFiJb?!yjd#p3R<8(Ae)OP6PbmML$j#{^0wZnzv25^G|L zPQPQK{gp3$IqkCBu9UT(H(ca@YT8rjyf2)eW)pA2Fn|91IK}6pAN?qudB&OPsH2W% zv0o1b)PHr}P;s+UzL+sfd`rJ{U-h2Pkx+!Jo*2Eccl4A@BD8n22Ks6 z_=P@hbX@+6%PHGMB_8X?O4#?^cVD`alUy#i;DWTp*eyzR%?1gZH`bAgl|?MMawnUU(ocmBHTE9w_9YyNDhMW2dSz;gfg!k}i<~J@&0~p+scM-W4Lgr*4 z6So9E`sOm20vE1E(dN|8a{?&k6YzlGZZQ!87O#Hs^Xt+Ne{gB^S;8s8+&K%<{r62t zS6_8Q`o=du$0FxuC=J-Y#HA90?OEvyU-(9vGiPp*r0;jZf(7Z1oKp5P7MV}~f2XIT zk31T@7^C>KcQ&QVuK0Oh+~Q&$ia3{D-VbZsxN+&kw`Ol>Q&@n#5zk7Lp&l%JK|2h_zK3aJSLy;<|ESCU;6>Z zeh)@`zm{WcXLL8L{ad(bY5MTlU&Q!sR$m-1Gzxqa1Hmh=xgnkP|4vQsJn^`QAALZ1 zOvw!_dP^>VXay0bJo-eM{Ie_K`k12*4MX$ye&`dSC=d_%(!lb`Y17kpFPxkvfB!pa zA}90R{>Qu1XU_XVC?pi|{GB;#R=SQ83cvWd&!v}n7!PHL{td#YnDN~o{4cm(9er)w0AI~QeUislB}Ku|LPPUwiGcN62+1 zv3?CIm0er%yyyM4<0q!KAN|&V-Pb~*0)?Fw996FKIx@2kB2#~TPp-W3w@}h9kjz=y z^0=Z|7VXY)D#jTR$Zz8+?xO$ip*}~mVRIUX2Yf5uJ@W7a>A?s7lm-tSp6)4mK=j4C z-g^d$@FU6H+zMjk>*CoSc)!&k(EK0y^F!%?gI-76jAbrL#?<6FjYTcND?nO&9z{RH zFSn6ne&~x5T>^&Ci`?Uqy9@|%G8Ax(F%bSeC?H?C(KT}9$e36Bdz7lb6e>kEHm*P} z)60qS?#4s3r43&B%zm`|o&AUXk#zHr3xm({{4BSu;=M*qHk~&e^EOV(Uw|yz#=NkV zO=OhcIyL&iV2C+W53*txGO|jsDp9Gdr8@`>(UvS;fs$EUTDD|WC^ije^UjSZ*Qx4J z5+6QdGmM%v9^xc)jkYjksjN_WkQ4AZSzU!UH;J5=gkqtxOUR#DnX97%1vgJp$D4w9 zdq_x>s#Hcj!4Jal%DJVAP9uhIPCu+NSby0a-D8ZGHl@Czpo{a8AOhdw6m@_+l4)eW zlKU3pZ!AQAO}c;#eB}^+g66p|e`YHCEBkZhZIuhf!8FengynoPM?|LZk96%AHOWJH zQt(V5rXwf%Rw~jwp`WrC*B8u*CeMeQw{;=AXb5DS2I`~|&+t?a zu;4BJSQ-gM{2Jy+Do-|`-07T2FASZqavjEi9%|s)g?+n9qZ$!Oapy@L7z9?qD+Mhy z_%D>vRH*DgQM+2hHkhy#-dT%cb2G+6DlLw{o54g3h@_#0b{Yp6no-!6U-bOe+|)aM=Q#iC=)7!Rn@ek zsJJE!nDn}!vY=}~8ald`Qdc{e!)Nq5LEX7d1Z`9-ZeF!KwWGwWl5z)iHEbkGr9(zw z^f&}hL?|LcyVad7C~UW8V_lU<`8Zcr8M6*!#2OSR?MKY3v)B4V0W*wtQFy2BKsfV` z-G^Ni#F49{6aO#)U-B7sY<*atvQ+RD7xG38ea2us9n?X?s-{|GJv~g=#^uYXl89eH zTv!iWQR(H{b`=7SaY}iZsUANpuS&(m`x=aZ2V+R7HyypOtcKotS+IVT#Z`6Dz0-JQ2}Wo}T^$3ce^`V%)mZZhNMey=0F#*kS~S zFV!`mJW07!npfGr17%=&rB*K?ypsl^pOs2c=%h|NsqZ#;)wKe;RrtA?Ym`JOOD{^o z+ig2B4TkSjvbFp@$cJHoL7!O#k7*oO;o2Z|ND(3f`KzLao2UoYJYpTs1C_j%yb%%j z_8U?+YL9o;8||GxTXaFk>{Z=(ye4}MD)r*Ab}a@rEgAvaUts{g*@*DUXI-%RN&C_e z7sFAqt3r|5b%Z+m6L{A4-rI{|qtzMtv!(>Ejl|H>wUZ@_mtpL?g2PNUBMyB&@f-A( zLC6ZUJ@oSp@OA@+$gQ+l3^Y(&t{?6?V=kYSTtNnqGRClWyalxH(dsUoY z(W~fp>;voR*Y(Dv5e&^Yj}v{_W?9ACkXuT>-c?~lV;`<@M=zG>j20l``fZj=RQitq zLcR2P?erDxjIAQ&IO964-bu4eS{ePmYq-W}YFnG`dGPLZ&)t7YQ>UR*u*U?934~7{ zL4lnw_I7{~eV}rPYvsyE70NS=-JKowvj8HlV;$KOOa!H{EU`~>jP7hkE}qj&U&A$q z`KbbYhA8u(=&w;VhK15j&)bhbIfZPx(ou&Wf^3avMedA2c=|KU~dYVHz7;aMCZ;3K*S#EDUTX?EkhY1OrIDlE31dl4_hY6 z<{AfoK|Yzou>j-n?v`b#Y5AjR@$9?P{2BM9Ek<_XK?&K$^>{!0Gs1GIC%Vow|EVR6 zmv|RjgS^{<{7K!_v`{zPDjK(~qh66wXRK~a3+FLs9A3qk1>T5!3{60iEo&`K>OuFR zwY3?!sw>r7Pn3Q6+y&{f$v@`6;%W?$YSZ}f!>KC|qjA5B`ASgKxPv^kCrMwsINkkWZ#AWI97#9pfeAzZ6=xwh=jXT^hH|wn0}7Swctz+DZMSsTR4(K&<0AiX_!$8Hj$heayyVBpBFhPGrxTn=R6 ze&x~?Y2Mtq#D`|^xyJH-c#ABVqZ-}zpy8E#Ya8fgAXP-L-uxKXLi>y%pZP*(TDNK~ zo)WpZclX#h_;PjQN@zZhxx%nGOsAp(IWgodXbGWf zf!8}o<1W|#0yOg@<~qo1A@{RCYyCGc-|%(F#q@pE+?&5~?0@8g9^@?VJ=E1hRXk|H z{p2-xP*YCRbDf8_DRX=1W+5(xj7eODGG(xO4C!>eW}jTk{J^=nA@<0qaC$fD6k^K+ z0O`dL-2H9muNqK_j|O|vrN_P;dbH7IFc)Or*AO@{D+=DwE8QSG%s6fU6rQR~W44?K ze`stw8pGLU=4M^Uhg*>r<16~zrgf|M?ch*V4x8gsOPjLYcDwM3(bez~W75#!qgi*r z%Nuh64V?7wCto`!a19~vOCuM9o9p#@gi}t|(9JPKKJb7T+gu%O#rPTvx;D{7Mac`6 zHx7w`X3lY(vnu!JgN^j^N819WksKfzUahG>>v-^xq2ckd8P9(njw;Pf<4gB4M_|l2 zhJ&YFgVEp>a;DW7e5t1;zqzK852+cJhGP6BPR<=%ukmow70g?d@$(*^2g?kj?5x8u zUzSfitar|w*)e8%c+SLaw*~il`jtj_1%qMuV9PDXfmTdd%KclJ2Hn)j}ed02~WM4Yx7za=yq%$U;?#u&@cPf$jZ*S6SVOX_=U z&|NR-ixw@$V{K!aFmXcAc^sYy*D!u~XpskHZ8K5teR#cXZG_^zX&8qU&9V<=t||Wx zfxm2n)`@lC`i=7+iWp;t<*SZ&)DFLy?=@`92F})n^YIGWj&YZB@Z+Y2iCb@xwjR&C zdLRr?V1NPx6d0huKa~P{{VELH^uV`l*|Lq|muRH-gCG1L#-AdM86`*D#;7|u^g9n-g)Q1 z-*Ut{a{ueN8qPZJ%{Sj1xEEdvec`w_bLPzOX6U^Jg?cYM^UO2DI8Yg3!=T5&4}S22 z0c*o|-n-^sg!1d+S@Bz5R>xrF%fA$aqoJ0eJl$W4|7_3o-1wW{{3g6RN>^ooB3Lih z*V$*EoeyL#Ui^jMjg{~Ds&}*0VDz@zZc9J;$xng@9(?dYbSP) zIZev1OVQT**%X?*knMdvQ9_Dg@d<)&vC0~T@o{loRYP1|g@U3%-O?=62E z*DFwBEQ|qFY8i*&feSaY=`3AfHE6{6v3H-8et6||F@cYVrLS^)zxJt*hX=m$_vP1? z{c~r2Fn#}uE5T>`cx7JFC{A=LkNkID|Mr)cr;EP+O5 z*Lv^jQEYPYN97TNhK?gjO0eF$K)hl2d-;Atc;)wxmKi~45Vv8_`{n``8H@1h*B=&} z4#oYy)9)U8?USzk#idasX+B^O`0rG^8!wAOstQFpxG`MB<0Aj_z=xc`#|Dc1feY8M z(ZgbPEQXgBUsd{yjRbcuN#cfp!8G>6wJ3H0Cf+#?x(VQO`^?^m>w;~@!Oa{u6TBBz zEcO!D-y#Ut_ij-5+lLps6?fnDCpN(H7-Rfhciolu#;;0K9)6?%5xDKQ-@dV!?FNHm zhW(%L;?zWNZ~|J-Mu7|KHEeonn3$EY*yJakc&ebc;iSpU7Z_ku+&W+dDF@hY|AIZ0&!EpI&gDKg*{LFFT!-j*-xJR z>45FCf?maYCzYT3{COCTd@!AV{`s+yvaxucO!V+8 zHi1d+gzvQXeIPbieD6X}rJG{GVp7>>gVIMn`q6az?SCjhghAv^JMEO_&zp~Tggkc5 zW%Ky7(@sm@`|kHSg=s5LppKxuo;~C*HyhjVPUvRYP&OengtcxT#4xc4FVXOWAUk%s z;YgZ$@6EZtO>Rdv2-EthXLAn{64-j;!n#yROjs@= ziKqN#S>xADOcXba8>!r-BY3){A2&;-UH*^)c04=SWZf{>5ez?b$Q~;l)XT zL2Rcw#q%*h3uasV%bwp4B^fPC37|S2}4RA+}9G-UEaZ;MUU~yW6w>-mK6nOsM|9moi z=eu7Blp+3+_J=n93GtV zSUT$yUtp2VQ*-SrD$~vwBCGuI#MGxlN#5t*{NCi);D7(S-vK^BZJr7T`J>c#WMli% zJIXYqY>x5dw5QV@cYU_c7%W55mLIYxf!v!BNy z0SN#AKmbWZK~zn@`uSxjqN4;tkSA0cTFPdHN_+<8t?^rp4+Vf(vuA~(w$GoK_GJ2> zk9{cp;)g$tI8X66 zd=UIVB3ch0X)h<_I>>BA=J7b!mG8sAhiCDg_7i{J5K(%FX9S*Qr4XKT&0Vx94cCjB zJL;$t(hWCUl@=_R6G?vd)9*8$_Ak8e@sfSg!LP?yHqvKQ`U#Su$ius1_j%KH~FbGx6T9_|2D;4eIbddJV1({f3XF z^p;cugMsjGMFDxxjlA#_zCl0wVlJqC((2W#Xse~R@GOO~Efmc=N3+G)CW`(cKaD=s z24>(Vj8T{~)z+5U3=hL-7=Y1V@L1!Pqu+2sy7lJYqil({2j$54C_CEDfaP2kc{93E z+L+KZZc(Xr-MW^vv}$>@VT}yK^AqE!ic0l^G!V)Ckn_bb5~06#v$SqdJ~$@kj*MS= zSg0qB^GoFyWl;M`*Ta-~#YtWej$^b&S0USa&&M=jIEdydP6AOw)R2e%76mP46Cp3F ztZ2t#7h)Nrf8#=0C<|wKm>1G1#${i6-ygiSE;8-CE31d7kNyNfI;~?a+sr(%MTOZg%*yq-4uisujz*N*8KqHp4E~_3 zdh}~R=~OvW<2jWL#Z%)zWf8|-Pv#$t67JfyO~^YM5e@?%RAXr$dJs@KyS0URA^hG= zd$Jxk-<-n^po_){;y7~T2=)i?h9P}{U(GvZ637aTz=v_Y9R+0)OLUaEyHZQl%Gm$t zhJL*@dN;%X4JF$S+UZb?sVc$CnvnlPVZnN5{vL|8wkhYpc(KXjEp*gijJOpjms>y8 z)Lm`VdtT$wUQn7ELgw%uUWoYzX{Cdi*^c4T*fezwrPc}hb{y<#i(>WxVc3bqB6EGwyt3KT}8tpL*cQh~dpBhQmH8eLX8IKq5FVYbvy z>G67(op;1oa7-wI>g8q0(q-vkWSTbCVN{&8J_iq_?)kN!${sS5W2uSIT(uk;e`eZf z5Gvnh#b4V$N~H9A2G`nJJ5fd-HHypXw&EcJo^m}0m%;kLOd? z=cqA0)GuVW?@+l}`5#OqsTC5RSSOH}&_B}9ncG(=H<1L7gJNWw{K@<+U*)>&!TXh2zj(H=O0Q#aoDx-jz4IM;lwyV^SY2--!jJWgI1#wf#z zy>gny3WJ6XLNS>7#MpNk^xkZ<(clCBk>0f>u~Bh2K@O7MWlj2U(DieyTpT(BC%EH)+12h;Z8-x8Z%@ z!8Bpg_%IH!Pjh^*|EVHE6=RthIkt&d@^?!)LO9aHE(G=?#PvaAIKbJ35zPUZJ5 z4A#1O@ZP5U!k}1F;~^K(!A7|qPtC%uq?VROPRjp7dih?j#(;(W322}fK|!w{{;~C4 zo>$a;9|Czq&z#2I4F)QDQj9Uyp@={0!*M&-s=ZU@&Vy0uIWRQTfzDyE2eF)Y^k}55 zCnUV|Et>mCy7i`Cq_*ZIKx#_E2KA=Fj2T^czSG!0_yxL1a}8TG6zpyX9)^I`8ai-U zub~LCTc_R}ts~?E&RIyU&3J-Z;ogG#5Ag<5Krzo{i!qP=fgTPV!L=mtIVcJH^X_)! zr8QltiMpzvgg4q2#xoAK&?ck(DxGrjDQV*NJEqYbQea!?V85Xa1G_dn zd5EdD-Rvb>Ntz z=0vuW70XtnCG!@fC36#rgcd|1i=^y5nWtlcV%&1z}qR)#$S;yM+U z<5(sjr0O<|;PjTw0UDbU)~#KYww|;@$hQkt&5QjW=csYWOx+-8k?S_gNyz39yfAdE z`~U2{2cVusmAF5*m-I?12?@Q3bR#IXpR$UmxYo4*c2QI;3%V+(U_)KS6|wGGcK^Gp ztd$izilVrJA~isI0;xC2ExG;vpXbc`e)r2IU+8$h^AvHeg7+ZJ=l>Y_>9;jk#cI@D= z1IAoGbj`y@Vx8xjg|%0G9S4yBkl4!wtiquUxn>hM(Mfsg)+i5?|M9>C6@uLZZD#zC zbMTi#;=o{U9L~`KZ`Z^DA~@De8z#?U>};SNlQ3SR#pJOAub7T;gM4;>1AHpP-B)dO ztS2zc8iJ9a6io1EGvObp|!?Rex2gG1Ip6ELXKyR24U zdQoc~H<7aO&e?*jwz)q|(_3gg#(nUY)nOedc4*4L7RXfh;Zl; z3o#_5ogl0@+sL}jwXI~>b#qrIYXo4WQR4taL0TXm?D|KzZNmu8Hp-*7^K-m+Vvr{v z=}&m*>6--LyK65FYe5Ft3q6xZHO@o~%`8(q?&!N<%E0dlLyqYNg_J|7@Lhoqd!iCZI z%HK6674K}D>nH0J$Ot6EP@Jd!A?9MgGfrF!yAC&a^*|lrq@meez{2n2SWAbo9{8O` zOl#jU&oW+IV+}y>l~1Ts;26@dvz2jH58igM7L&c0F_XFjN8#(b+PH>oPg}rI( znEMs6w6_6I%C`R;%huO2r5}3y^@aNxbOhzFrpE}+{+NIax1U2J)g$mA+E|}bzKXzl zf|PDfrVnDTihKuI%W0gwW%Jrt-@B%DO(X1VQ$M^)C-mC-I%XGesA9{0`=@I;#9-6r z4fO9&9D1~P-+iNA8fvaxcO%f2H>$^=u_N7j^DR*iX2f*MO*ezrc~8uJ4E0Aea#p5d z-eX?;rt|v#`|lrK_MH26H<<1xKluqfLT`AY)0j*BJiT){ zr<9?b_si$8*JF-32Kn<3!YEFUeYf3qTkP?fmtF*S$GAqlwd=3H9vSu;4vAQcLHu|Q z@85eT9Y4#R3csUQLW8<(8a3%~VBWlWX}|sU3mC-5d-(Hqbmsj1x!@uAf3DqS9@WNC z<-7ZHwH?3y^{?UeI0WhHtHasD;>C;8p@$xNH+WQ+qp{uY)cJwxcgvR7cF=I`GQiyp;=}z7yD~B@^W0tBG5+bNpB}$5?ftzvuHW^pcZK1f zhJnBT{qJM_;kXfB?n@ZkC#Riu+HNPm@WKnzdFP#%Zo28FkaKvTx^q40+ ziG{4o^?MG3Y{q=@{qLz510IM%`g=cdamAR*?-yTiet2Com#<&?ne-&QLuiCo1~&rB zP#Oci;1#b*&wc4>Vc2!`&wrZ!`TY09=8^F}_>XTbqo8IcSZoEJ4#3!b+-u2$N_m7)1yBn6>dP}j7^{%0p+z=iwnm)`u|_md~yu-Le!3{NF;kbWigTS5JTATM)!d+0!iUG2OnLmR5$1 zgiV|jny2opdoL9-@U!DnH(G73RB9>b2n%`X&<4Fo6qh(BZyFWE;hbl z+Ifu4T17-YnuWpuH_Dw0LJ>03jh3kZGB4ywLtKTXS&388SPlvdH2O2o*u3V(6X34@ z({<@HmwdL2#>qZQ(liutsAhyaZoi}QZT9Thv52q?H}GwTC-8@YPE?kvp2S9i8~UTc&31)i3hO*A&-#^N*|OzvyI{fI>1}U)E1MdJ<6Y^l z^zo1XGmGlq#5YeHded9p9QQ7;-~QIO#py+BIGOO%7hjxy!-+fw7vlf*jsH$(Am9z5 zEp@W2g|y)~PE$F66OW#K$|-RIp$ZB1>$rY zhUFK1?4npmS&r?0EyjAfTc3o0q6_@|#y2lZ|MD-NiA^8l7+iFF@?R*}@vOq(cfRx8 zR2l=?FaP+CbJDX;c~10;bIu<*eBjM*IV;+tcc#yO{?hcGcfTiu2<;fEivudkh0-AS zXTR(~&?J6)e`hi0S^i??NO8pa`cwF@^tN056k-1Sy+cS5_#NpTCn^pCH|nAyh&Zc~ zoOM-saWX>1XhBdWa01Csz%OUhsnFLl-nEB^HjgdP#;@Tk!x682fj^%N?Xu z*?+=Bd9l~6F77I&3{ba`ay0>ZlxSw4&}8>8=02h_-IW3iHoPb>ckBAyO`1wzQI+YxFbEIyXN@VL3n3SL3kv`|f{0CEX@Zp{%rvgc-?- z?`9O4(f*tdQ6rdpnYT&GXFmdBvMJJ$x%U|!`D4(YNKIV6jrHJc9<}iBhk$&do&psP zIVU{agKMMhC?mQS*praQVL5_w4l$?Zp;C-A-#cb9Kj@q#of|=+GV`o_CcY!;u)~f@ zt5+^#UR(!HnAazRtjmTlC<h||;g6ywyjXLC0S z&y+8%mIgJVnB>|-rK)igxnk_+v+u2I>ScaKIakFc2ft~oYqU+C8E}<`z}CTUVFby# zRxci&l&=T2dfi5tjyhYq|BC;)94kwxhG3>8zNvo8V*yj+=iv9TFL@W8GA3=Ar21M! z31xTFlu3=_xBMz@Wer?UMq46oUMJW`Dt%@pJrfefRw=)YzaiU`F^l`YX~o4O2f*}UJeK!DTvJmPaaDv1PkG}tYW0AdwpjD|U4AhP<>aGvKLSwXtA<2d`%bkmh1kJxN4qTw{8oZmxK)rvNyw3qdgV*8c{ITtA#W{ z9&bDfk-a+@Gpbu4>Z4cLxSn z;hmBF1W`*brP6|bHly4n-G%5Nfyqbs?_9r1=%SU1F-a?EoJ2G;OC^1&e zz&tENzQ-{eZDjpk(r;540uPETVx00$SjDvfC3r8~Fc8J?uLosEffD`6JM(SC zpxON7VGJq)yQh#9s8RNZCfO9@`o0NV(i2TqX4k6*3cXa^v86`|6?N-Tf^NXjOivr3 z+?%Z+$vx8-pb+?m#Q_S}?0E=3aM`#Tx|Vw!!cf>|J|DcV1?Y>fL3s#Sh zf9#_p&)T0F1pfLUkVosT>m?C*fWoedaczb7pOtG@rrTL7uH%{**RJ6i`p|f2SuhVK z<^?3%8bww?a<~h+!vkM3Z6gclTJWXB4F1bRrVQEzy^H&J3_}v>m&P2@IfHY6hZ5<* zx}LSRa)+KBcwp+=&f$W$rj=`!r%fFgxwKLtDr$L5u}%y@cQP-@3+wAI%H`R*^51zb z!H+sWSeGmdmyhNf?RVeEy2gaeOX(=4vghC(*9d-ye189Uk4h&do>NFHu*=>0|)!Tym!Fo zxmPWZls$`EK@Tl~7gH>UA$lF22$^LHK8E)gmJKndTeQ=i`53G-Gaz@u)i8pgyWWwR z|C!6|f2Nw?Rh@Gt=vfLwCF}3psX@!O4m@_TH?E;b&WAjy3;(GDiDBqGgkUR%a!nZE zhzG+|WJmXKT7lB*@)dV*sM$I^oUKn=IoRy`<0m2WKRE4&Z29QN9+!I9BO3yTJ^Y~$ zJPt!8c+>UlJ$d-SIMz*$H>@M6uP}iRcg|~V#4rzIFl2Nd9uZBXnOzzKIZwh*g(0lX zCKMwpP}1kfGH^b_CZ2hlIfVS(c%rb8g{eHkApGqhbFuIdkxb#(j=&}7V|6f)0Z5xS zZcN?ONq||Lam^=i#0$T24Azrp<{~1u;2CU3>EWCqoa@2ovOV&G4IOLJ;9jHqQaSam z|7x@)T$OFQ9?LQvWS#JC%ADlggMWj!kaoxuMRlpX-}NRJd+qQq{nSS}qjFmhDsX+_ zv;8F>rN?pkTF06EO+M_z@j=~uZ-~sfaBcK}5#*QVKLCvT8B;^@T;QhoS;qBXidH>P zjzb=Z+{*Ql`Y;}NF^+dpXK>iPNDUE{gUW~1`3_?z77CP)G1HXk;P-mINW+ksHc#LH z3X7o^=p;RY_SoMcGr~x(Z8#k;bAIr=ogs6;!`$5I7%@&s6EOyyIB6)NA@GJEw<$e8hEQ!|II)MukF`NAINm$hrwBKPYEo_~B)?*L?WK5Qk4p$0&DJtQF+1dyu8} zu*bA%)5b7zm5&vM9>P5teG>ayepaJ2X@K#U-En*Hr0z=@r^HzlP zzOxaWdoW$liXGkVHRFjC!{mHmAhLN4LpeNk3V1nX>f|Wf^{nel502HtrNO$1GxFXO zX_IkW7v%jJ*Nc5oU+ZpL0WS11?*~z2^o#k}rtsd*OW`gr?s({cekvzk%l`Ym`|iuW zKkHI(P;wehI*)T zTj&7|Ge@}Ib=;``;22k~?zjlLMZVI0shfKkQj=IOI&f*AbyJVP1A2DgRo=Zj`_Umt zHKV@bk8sO$gnVhYbVGb;?rsWP*}?&`Ef^Jt}U_l*@E7q{iTt$bWD15 z=bhK5D}Qlq#I=U^7XFlOy|>Tz>08+kyPN04ELk zm%KcTuVS;aj8JvekZ9eiRq8cpN-XTA6(Vf5y`;fWX;y1`S%>tbU@ zk77%n_@o@6_C?_r8iuk{%}oJy8Q8XzkN4@KsOtzgB}ad{qV;s zuk?=i?vH;eo%@@KUNvEbV;_)vQL883_P zE7>r-{pOoewJ}*I8-ri^WH!n)(t(FPDt++MFUCeunW+YX@4=w;)u%o)PA)6oyWv?K z9tgaz&Ts5}wK3wZjO?nvn|A&_i^gWL+t2IPtWFwA-rw+4j9hkA*ZZ4qb)MU*j5P0W zzP0p!y%5N!Q@c6qo-|?{ZrnW13OCl9XFn1Y0)!$NbA*zPoW?H-BS=HKoQFd2oG#Lu zoCvWIPTYKNI^(+$&PKNHi=c=jM0JG_DM}}vhIO&QUBtT+kEPdMdtKB+1saXKZsw$r z8*jX+%!-Bd-1KI=`&7551EEM67VWbzyxvK76ewn895=!hB-C@_&Z?-l3&jbX0;vGZ zIy)DrY^P@?H{LysP{BfVxEMF$_Y_V&_0;q_4BwpZO{J1nD2VYOEK3-<(NA$1PTVMz zs16DVgsV!53Wiinst(R|AO7HlY2JLi5+MMZKX+dG$cH|d{^2DrORH9|u0(Ya^q~)a zD2&0(Z!SE^1s7b9&UnQu;?yA{{_+>UKmq@>5boJu3M|~%fB*YGklRkZog0OZ2BG`x zvrl^0JO3%Y@vN+rzhcGmbldGqIlX0n;tAh|^dImjYu2o()Z+u>^^_++86gP5A%xy4 z*8anbUl;<4OD?&z5-%HDh;#A?cuPQ#^Vv%;seC`@oOfb;_{^x6{UeYMJ>*c@_>uJb zGhZ9=e)7|wq}RRnb!qyHX{n`7&j$)QvVcb(#c|-X@VBiBG|Hg&J_R#jJY(MxzoYPa zYn(-k76%+mHv~MhQg7}jamb&GNQFAK!LcP<+gwv7`-PAbB$`6a?=g z=(W0LSg{MhJWO8cmBKMkk4KFI2LeaMp8_M|IX6hUD&CdAbl_urLoZ$AfPz>}XsbE43A zfAFCPqz`=X+;rBN?~Lc4{^Y9khBv+nfvtx?P&gS~^sx)6kAi9*`7_LkzK)Xx3-?Lq zo^vjS&v{+99Gbgy>8J#c*D@~uyJcfdMo`bB5?RAciR!2SZAED@+ z?UUoIh!-{4IqvAUoKhirb=YU&y!55deke`hl;|kN#t{DJ+gGGjcuF)Zm_Ijt=`$Zj z5X}j-K_s$wk@L@e6CP;Sr{7(BeZ>3EZ+;Iiey`4OEb0=qAU!{Q4E)3r1_*1 zo)GsXG($Ni-sC@rA9zT*?YnSs%zwF^W|mW% zW#pS5$;UT-=3nt)&7G^#_kR4XBF3Iyp8TYfG0uEcE<4&$)PwsY9{ref{P9mtzxvfr zb}HccFE|6faA5|8Z6t0Es{Yvs@B?_5=_C|?%Ai;Kh*|j~9Q{gMuf=^_ibSPxU_6Sy zW-VB~w~WXjk15mfrubVt1-$GZUu(3Xf@Li{5+UH4!b2J!?nZ&~o1M^#k{{cXz6w%b zBrJz#3>hAzH~Bl`hBcyNMjGSVQ_^1Ym}R-f_uo^Wc1pVT_g94ySe#xC->Q9@dR*oEnce?KTu= zJ-yzO+*M@MAiWtwuQn9@ns}#jRT%Bi5WQgmzTnrR92AC|C~pu&LwVZpMuO*#dJK31 z9%UoB1}w-+MZtiP?J9zIvBr!VmT#@6H70FAc}BnFJHKbXp9}voeX9C4HbLkh-W>F4KH@$D9}(1Q~npI(B&2bv|nr;0hB@x;$SBr=2QLmK|B;{K^Q{Q^hvD zxWwAuXY$fZLGTgMRsM%TU)-{uMVYjPb(sBcS>;}&O0)JwQ!^34mPQpdS@78BBXubL z^3Sb`9y}>%WZDX!-~ltvCXQ)w$9)AoxEWNaRWVV8*b(|Q6c^!XRr*)qI@a>=N_uT; z#;b-(vIFpUy}evjSR}39`ZShQL9YqJy!KWMSljwy-5pA~mP1>N;~L%d&c=PAt!k9umfWxa*Jc<#OZA#D3moVR`&HSv;tb`(CrX$@be zarn_X)|`4^9*1%!+v9jl#M@y^dZfW1aTsGiJ!mxXegGq}9ux+LNIx>f`Wxj;_b3|e zvqA8}x_1qvW;`is%+$zUz;^1h2@g(pEMJqh_rhK2c>@?Y?%n&)&`pm=gBUexoaliX z<0kadC*#sY6doHJQ4j|2H1HZkv9>e@c1{*AU5mS}jCH-#KxW^}#npoG4<+?@jZ!;( zTGBZWeQ=z+wvQmXi1S=x9C4Ke6sH5P&6l>8#$yg>_eET%@4zdFMx601t)c(I+Xjl! zt-w#?#}@D)yp*yJC5{iEINJvvxsLa@5yjsg@Obkk=@W2at7I~VB)ZoVyg2m=Jz)6Lyv%c7xg?-;=TPRniV0|BKASFM>^r&OcX}^Jg)5v zVe8(V9-@cvNJA`DzT;hnHF2aZv`tSlATHfPJIT9&aU_kgymu_&mG(=QwI~aE8g=ClP0{E&<|2*6 zh$3xuA4%h+fO|BIH_#(U6KSZYb;po^SlQ?%rngM5>&gSyNEc;7RR;!o@P@hude%w1 z`+1*v2Xcub$d!;=IQpUj(ERxU`dj9jdqpa0aK4BOe}s4TTq|Fg=V_@od^mJFD7i4v zix+VtEquv{d=b3R2!|dFVdOIm-`CrTr@D=6)4CP6a^UTa=yv=j&6x?EZ<5B-f5D%S zg}K;2{Mo@=p%D??PQQ5=iC>u`sUPesKaD+@sn1dVj#MTe* z+1!X>PWuE5mNtinrzZBzMwpXAu7D$F4Fb1zZ-=MrgAbwK;a`6E-S4JlykEa&4c;y0 zr#snC>*0OOjqt_F^tRwdejP?MBk-H`cvW{SYS;q0Me{VQ(%ZUwr_JnnHL%|$`Ur#0!Q)6DOER#p^+SbpF_Zi{s>#KAOMRO z?imD{repK^G-I!MtQDHzA#8{671t@FEQGfnexfI6*O_@u3f>9`B3i9Dpe10zo+CV@ zGEbo%>t5oy7O{_V{iSihKzb7|KtE_q9Ml0UrBTM0*N!sCUqdJj%$ht<1->dek$M@| zdTKDH2RYXw*0l{@Nj^5@cHpo1$Vbsz)HnAnwWsdQ4Tol zx|%eDq#2~4@^REKwXwFCIAuoct!t1cJ(z}vx{2`68k3E~*tMh&9tI*GCtY{#5XOo0 zpZzWfrLug42X}3$+!T5Mj>s35>vjeqYqSl?gXQ|cB@aqzY8ju}SU0uf<*)@BpVyS` zKjb>=9?&+5pROsLW9kO%FL6u$oH|i2>6&l?GDeQRw9Udc4ER`!`K)oYJSP#N4;l-Y z#+sA)Nj!+X4)-C=NBHuyAHuUeZ7lms`KIOCr>>zbU)Z3y7Im^5Jp?ww|9b#VH@tDI zlc6b=KOO@#y$6=-6%Fp}RoC^7OV_mac`GpTP~7HLja=Dh5ihBmYa(lB9sCI+_gCSkHlZ%U7%pBS6=#u803xgYCU9;iI4YIvx&Zr3Le5rM>6xg4XzbxEn0=4ETmOWPM0K z&SX7t_~D1&Ene-#Lk9uZ5$d{@;d#${UdZ6f=i0Rfff@vM9|DE+bN3VcEyi?{(9EIF<|-afxcG5;xFBIhaPcM7+UHH(O}zjkGeyPXris>2*S zKkaGQYxbP*3c9E1%XICWI`UwIHk4-E^mDVdy8j-GvTAw$bwI$4W;e5)J0!PUV*5CR z2)yvUKlhKbLX_f`9DE%Kyzp}a-tn6^;&U8D25zQHmrEg2DMc{9$e)enELzBEC^0e| zR&rOhaVuVi(ov3cs8PUCM;*;V`tb-wP_9L|!e`);1x&Ag)vMBvfBds_+ils{ zL3m{WK2@XaD}H!I+Mov?!lFfsF=~6pDBR*Lf54}sjyekOev84KJ3`3vvnzj=p7ZSI z&@KgmSrBS;PtOz!^2v(|?i#{lpWhTv*-pof^~i$2`cUBVyFpkAj}X#v6>bU(6szv9Nf?`ovBJS?NM-yR1JL>k_dFU)yfLQ1=S7PafxCE8 zpdYNOf*w!uRN-t_!8+Pc3bhv?ytmAvsAx;BLsTZlOqoX)UZ52Y5ZdtvXr|A-awY=h6LMR?+-$#SavcbFF{M}*+o zPqpx{gMhfKRZZEo`C3gU!GL&~o94YZ=5%6+Z#?8EId05tp%t8QttvSwOvsOfrrr4) z=Xoo@zL(&8mQv5dRfsf-X8X-!{dZpy}BAywmI;?L-|f52PSl5Y%Ba0 z${Xfm8T>EX>|GfmrJtqCh?N5-0UN)J4JB+d1XW_L4j(x0Yy_&4!M7C6B8Z1g^s~H)s-d&iJZgaaK&oX;XUl8_(v1Z(wO(^2-Jj zBWW`0f_GrV__BAsJ))|B^R1u$Fumag{{VU!*VmaoM&1-;Sq=<8ZQ7dGY~wIyQ0dtD zrK~2%fr9$Z%Eyc5Eyzj{wucNd6}F6`{v@`vpx?a9)s=rhpJ~SIbl5?Uj=1HYs9yPC z{K`Fd@qec`@wFX;3G=g_VK~lBjuj0{Pkrih?q(3UWXTgU{EZUh%?ygd0ym0wlUG}z z#1U&E*1Ngqi5m?zk)?6X04Opk^Ru6Qm22dk=^5(aSAJd2aiIj~S3erh{EB?@8{1bi z2n^sng8#@*%Y%6`xctq-Ey#b}Ut_@B<~(K`+oQoXBx6(R8nnwRbD`^^-~|~Y#E&HW zsf?Rq{I#P@HG9rNjG}H2Ly&RfCcvLJW5|VKD#jJlr|*SQY*yNGuGVl$Ua^-`+j~*; zQYo$rPh@!>VeN$ixrRC_f~pkeSoVZ|PuK57X}fO_<;9`?v~?Q>CL6Oid+XQ4TB4bC zfClCog}Fv>KKH!}a;{xNQJXrrE^Wpb%5{Nt$_8w-Ip`M3UEqsKi~}5=67vK~gerBF z->p-oBhnNgLLLQC8U^b;+?8`wz>&1&v-xGZwsXSK@AxOQ+xg}hcgK%|?s1({vgX+P3_2tvQZ#;4Ow&6Hs2AGkYE<*d7?348+q;Jefq>@HW(o zS0CeQ{2Fa#t*El3N|N}D}BooORV-8;H>q|KY}Liw>R zD`+-uW6r8)T+L3?rp*e&hPJkeaf0#Q9BSCtM|N< zUX!ufjuL0n_*RVk)`K7@Evk4vusy~|6AG<$;Eal%<4_c~pKkio4e8GHo5PDo9ph{A z^l2!qHpjPiJlap0F`atNL}`9pD5W~?7)Al_Fw8(P-+mNd<&7PS8TWmrrl89Jimc&5 z5}><(R9~;cY2L?)H3hT@Osb%*dC3#fyxjHz|H}w@+|w2ni=`7Nxi$=XU{IzLeRxOg zr*9f};Hii5R9@8>Qw3!2HQ>}3Rc}8Y{^2$DQ=lKN6QpAvoV97w=Cqdm91W8Fsch^% zl!tRn#FMxOVA(bD%8r9DTD9B;y`f+*h@r<|q3|wTnrL@RiwdQ*jm3z{tE<+mN>^X~ zTiQDkhHeMr&3dnyGa?VYA=$@07%(=55v4Q%J{QIA;F(d%rf}YY(A?^Y$i5�V?`H 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

    P38P!mhq^dL% zS8NnOi?^uM9YlTEJ)jvt9KdDb^X?4JZD3S^BC@t|d9Fp2kHz3?=>>BG$%oY5)rHb= zOL`>2cpx6yKYQ`{QQQWl>;{}oDLDgy$ClveyV1th-Pe0Z_~1F9{zvUsKU4V1g<)sw z>ijhIH|IAd+jGg*>is(de9R4O>|T-CspS`#0aPZ7CSgwLs(FY}&`ZjACx!du&qEh0{a5iEG2~*<5Dv}91D(O zgMFq62T1tHHI>WU0{5$xbg7Qd4JM>YVtOcdn}C(;7Nn@xZsR*m?2{kY@_6!T> z6DbV8#C6~5=JMdExbOb9frX9edoio!@iYo874YK(%_SG2mK2%Q>xX@~FpP3aQT9ER z>#ngY%T__h(OsNw;$rM+H1CrfY`|(+8Yqdb!a@%h4a5DxNBK_vSL?Y2_HSo-*e6gt zBZQF{Rx5-L8-Muw-x6SL%E4pQHl zU|lmF?<~h&acYb|j%qK4U*pnDeh6)p>9GlMK{&pi^}7+7PY5XP%P7}{(qJ+ECK+C_ zWsf-@OVN&khHfA04p`W|f5*RM!1bbzqsF0FH>6cixv&%YLEPTXzG#g8a+@7lt4Zn5dn&h4%cD(QQk5N7&RO=@nJ6S!S@m6S`wBMB;ky13ZjNh2c%w-?>R!!cJ7e13g zfXkxiVf^fQ#>#K2r8r{CRCWbf=%ACR-oM|LUm!U>dROiHdQWvy*RHidd=46Wap|Z_ z1XjVpQuXU(-`^(4FE6bm7R4XtoJxtV72c4?0KZMn(tGEUH`hkH3#XU4Ck6RYIrn#= zIFWr`;Y>Vd>DH;wHu>N!|A^_#Xe%KPSg6b1PEOtBy4cd1u}q84CDl~HsUf{jiCdU- zA5^n}aP7Wt=og!@FW5X^^X3Ir#KuROn5zx=aCp&aWm9><3CQ`h|Ewd4*LcW zKvP1*oP-2`QtCdUVE1VD(91=yl5Ce=dL*sY09wI#wM&MGc~gqs7}ny?Mykuf=4Tmx z61J@@r7A6q%gY%?H7>be4;PmIrvF~dfIJPoSDaO8|B`uliz&VP{%fJ zP2S)2%JaKD%;h9&UbDxSwb`0$r|Et8D{|o)yZl+S55wv<-PFI6U z|8aQvIk3U7MkQMARBVlTE0$Bj5TVd6k8`K%}(Q+`pHSjuUgjXB)@i5rQftg zq6-GAMiFp@RG*j$BL~KZ!KlWDS$hIfYD*`2Tc(m%VeK~E(CSd{PNxy*b)RqO1tKc+ zrW}v>#fp{|lZnsCN5p|2qVn5%znXDJI*4-^@4)+M7o>WM{L!$cD)4^gc{Yrt=B?fH zcxqUSZ%1&hrMBN-`SD9S!53PldYbU`ri6WtZvLCsTz6!!Womo4qvj~P@|i72?x+e5 z`oC1W)yK7ai=BNRFW8%#B6Va}@GVns+i9+K^?&rA|F4tfe>bG(VKSq&pJZAE#$Gxn zobGTQ%rO(FgapEu0kt4U`l<1YVDr&^?xkwl4T7a_v5Lp>QP za4t~N(E!o@Z1A}t^tGyD$B_N0iUQH1!st?!UeX5i@3XGEyCwvbz;W`8C*3X-G04)BgzwhjcxnPxA6ls#0d?mVvt`r<#poqi zRjQ6Om6$*onyPa8-nxCcHpc92Q8gw`GrP`E)HT9^8bO&=zEq{0_%54Qr8w(bPKhc` z;G_6&Y>FnWIdV8nyz)tLeE_=QlGixx<$%6Y6bbZvF7T}>{ZMPWI~gxis_#Jlw7)zH zqY7zeZ(Rvbr?2b}lCF|OTG$(fShbhNM!B2;W4W;sRYo7bWZMxfg}Hz8fTe1i2bV>h zk-)fb^?-XRk@8DRO8_1ZRL7<|bSKnNrTY0basSxxc9w1c*PoRFI%oq~e!&CRD|k70g(C|K1Pc@#29J z;T`ks+pJL6m`D;bKq|zV^i~YORpKLpzwXgFIgl!Q7mI~bfAY?Ek;O&dJ9)$oFI6HQ zNu+7of|W}$MGBoc8m+^@c_*I2Vnaw8PSspS!N2K!3I4hyH6MKuFWbC=Mx05k1<0%) zXbi1C7guyA*7V=OY*Lr}*bI~HbCEES>6;szs;;k3nw_mI_#0fn{H+Xy@uS)KfePq3&oPp1+N>7xi=(m)7yT_xy==Fe?-x#2+;1T1^3SzWLG>hiw#0?e zTX;r9S%jMVeS-Xi(bpdR9K1MSW|DLslGpL0_Nzxn1^NH<>Dlpn`gJ%6Q znHCqu+u2bXQ|**`qo@=;b$n!F-)0I()i$Gy(Nm6(05R`^CnPZRl~L3BE}th_TVNGe=v=zG=ZHjSil%CysK{VOo&-u?3 z1;30RTw$_T+B_r*tkqPiDlyzpW#+h6YsjxGv!fGkcMO@R)1;9H1&jJ*kndPNr<d(-#LX-@>Elj!ik_;1r{|oBW;tmQweTMTzn$GKmX3B6WerN*WX(#`>4rXnQWn^!oT`SVwbLa@6lSLjkLDtJ}mwP z5o+pO;!=-Dwn7qg?3D4nu~pQOV*F1L^jkV_#b)PGW_wQg9rwkRW!6IOpbUt_BG8vw zIBE{EDhhNbbQkdSaN7BFWkr*#(Cg9`4=ajjU3P(0WrN%h47d&JH!UrOXJGaR0=x*6>2ijgtj6 z%>$^~5}X)b!IwAf01rh}=f=vB;wfB+!~}zQ_P_VBPP8(*s{uZy@A~ne*nY|`y`6?% zTGYN8hx*iXEymZ1DH;BITmnZOQBlM-L`6c-T%p1JWZ}b!KmQa&W-C4S z)%(o+17VN%GCU-~`Ky;Nr>^Xx+pX*Ie?N!D*PtPPccafN)%|wig3)paL@O;`aM+_P z6?2F`6-pVKtFs>To{m}G;2`q&X;>15k(>;#3Ng-!?y0gD5^9nNr_`*5hd*CNMG3;+ z5I@=|i+`M7)(7>l!F#fk_4EeFKkTyDagbCl2E`6NesDHS7NiwmqOF~GOVe-1JMi^( zNsjcNf0=ILd19Vsw2Ok;t1kdyFtRJC&3f~$G)9}6D)59w1` z+Fav2)w3%`HfuDGN z|8frH<|aOJxOKZz#A77k0PW3lm*gfp{oFFm5zW{%b#|$QysVf3IHs_?*zfy}f|0T1 z+q((h*1Brnk_g3`GSbpq<-gRYJrc|P2Gd^f-84|ii|xtpF0+)P`5BM&(l0=qs@M${ z4>>_A%RE=roP^P^z7ZAHnRSGrgh(I~90UEFTt6di=eK|e2hU1vX6Y{-Cx22 z_L3ausJn`6rdbv7)a8m@@V)65mNtYqe*wRNLZQk}y(Fu4gYeC2{pHl> zK$}^=BWN#rST$#`-9txfR5mRzg8XsAQHBvpNY@<-L?vaCgomfEL=#;M7+59)&C9by zpQF6C+EQ`rT3Vzh)Dc=L+lb9BOsS0wVS53g`BV6 z>WzJK;#QFdg#U_k=tVOvL4#+&aOP$!f-)12de66(^+q%>1CdfUn#;B(ZSOuvVTVMI zUXpGtGk9maAg&Hv5$)6GP>Sx$JG{LEtDjCA>U~(|={HU%D=ciy$%gADwja}kY1+UB z0>Tb8?#QLJ+v|w~r)?463$R%CJj;B4mOJ4Eqqo=%CxrJc=Q3RKkw^<=M~0z8BBPt5c6`4SUsLwC^EgF{5vLSqwy=2ehvL=Xi1Dq&oJtc zoc2KLfSkdDx4-wXlwYXz82{c%5wPK&tyZnYVx91EQq zf7*O{VXG?wGkHKXSNeJ&#QnC?Cy~o0br+kZCF7v`KOpaO0-q0~&$&pMV5_TB>c1M+ z>*IQ8mEPAq2g$zh&}nsKt>4eb2EPkG-u_F(wRyhv3x|#)Z(j-M_Ic6N8scb89^XBY zGkRQ@Kr!-ZWesVf7d;I+HL$>u9J5~eBz6qX6O~OZ`&>(Hq0*i z826WkA)@KCs3#`z8klYHK9W-NnLqR;T@&f%65+P|&^;-t&0X_c zs(`O~M6xA-`T*}}z>DMo$aH?kM~s>fQBLCbysu6Az9kA{jth?mX)vRreu5`5qs#u7 zq$pgFFpU(=s*FYu_fiF+0ib~hXE?qq>p9Ludd>SaJ|Ucsi-AY}xEPyhcf9;O0Dv}@ z=mI*!Rm5Db96rhUK91;k#FiZj2>LpC+Q=4)6$iu+Shu+KJuVqz zfls*g<>|7aH+M~&>I{6vyILh@0y48kk1a9h>F^ znjB~}L*&s=p4yoOP!xzJ>O|D;57>FcF4}$=2Wql-AIGKk+kKj|(a{VD%Ddb%`i;}+ zftgeESPGMEmkA}sHbwpjW#k8l1-}$wO3{zy*uUne#Pz=!XbkaXnQ}wHY`F0d9oI*v z_|A|XfNeJOf=2q)kyg3E$J#6VS7HIb1IKTUz#?UFvTEKR9y&qRzgTk#+7ziJa#oJ! zD&rZ?K7tqL=a(bzB+%C#HU_LMd~^n{_V}*<*}%>-ysmvR@*MU$0D49F3Ke4%u4Pyr z1I^lU{|rk{sJzJ{+c@T%x35V%uB(;2o;(A;fET3OvPfC*SwJN2xNr8_6v%G+V_) zA6qaa_753oS12rghSyO|eUsE^Z0;sV!i2%jf$P<^OtM3s3x#@vF7U4~UKe~YUO_@I zBs>1|gB{NH(qG}IS}0&C^<^rQo&ufOK12{XrV{BTKNeym5)=7;phQ}cE8={@m)OD1 znB=RdIo)3f!nQs$n`Md}tGR~Z@oB1w@tnJc~E|FC(Z>BIN55f%B z%vfLpTfjK{o6^wnFS**U&AYrZeZ~D4RlhEeUfqkV!!MatnI>$oU=k-7e0HAmESR^xA3Tq`iMIv1fLd$kS|A*NuoD)_Fz(wg5=r@tpFc>ZRcpKos9q2(!qM*_#FrmwOs3X5s>>!6oWbp_S;Fr(g0w1Mr4pYbYD8p@$b;V9sp zf1t3-C1QDe*5`iLPiUZtRX)&JIf>J69s_?kq8H7wWGj8q&dEvY&G`5x2&{J~auH{WZ|k9fO^ZUp0@58o3V)!ZLmwA%}kT+99Pse)32 z^~$C{MJ{sqHiym9;g$Kc1EttU5i6j+Dkx$6(H^$bIezV?bepw5?U8+*{%(Uo_HDoE z*mJ_#2b*X~ORYc}7p8vPTI(j^F80`sjI|R^1Pq58zLB3nCGwMua(!H zPrUh_d+^!oQ6Sl9oQ_=p%q%I~P7~Y8CysZUzWT4P(COqSDZbU;u?m<}3`T_Oo z>8aoD_BUL&Z~21+T|?UxT5NyULRoaqqY8r>k>##6!%`U8tHA?rzwN%VC6HHlWZ_iU zoyP6G>hqxLI5c7Cr+u@T^kXl25-+vU^glFxY%(Sb88f$4GMf_*rLIZqf*1%GO7B_U)|3v4Rr57w;L86T!{a77pdm zGaUH#1~Er_=(U#*4>@ia@N6Qmsw6zl%}4Td!a^%l5AQB^hGC^Qc?1Gaud&8n{7h6i;Q2XQ*OLzgxcDp}zm2ClT*H(CEE$K{h*AItZ5)HSLof%GZb`^mV+JH8R}NqNa+w zyex>J1SIg3)-~xReRJ87@z}BUxK8)&4v#|A^WhVs>-27XN_-WuNWpze3i`*kdcS(J zT5BqGl}l70+yNdpyp5L-NBH6ofgljig(HUmtLG!0Zpa zeb3mYLZuPC5!O49L_au>pCEK|dOV-uexoCcu$E?oyT8-z)hW)6nR3 z9_UP;Tim#CfQS$6@B&%cI=CKNLy>s(msL+TOXEhj80u<4Kipv{Jz756)cxilCr2qc z$t}67BSDm94Ra2~88_^o=kn#ty>&Vr3#xSfs@WVS1xV590# zQoO>=S-_Q1JiIX~LI(BYY3%R<(Aaqv*sQjhjtFF=F`{62GueosZc6|p1Q0rI zZgfB3BIg{Lqqy`Ql<}4+*g%ANI{{$vqX^#IIm~bNFvYQ^9;o1vZp{{$)|iaf*ap|D zQdZaQ{RbS``czkp`3yL7nj*QTUbMgw<)_yOV@WP0Wl~BptH?Mqw#5c%?>Wj01qD(n zW-RAdeWn;(M0J_&u>tPGhq!&AHEB_?@<9U}uSYKGrPaIz`Q0yGpk+laoX?LF$Ai;h z+F0P$dEqS*ne~A_GOB3pPDDX_zQHJ?qEX9&d!}y& zjVxjB2d9a4bS?W|phy(w(6u0Fq;&mnqMdK%(y|{4>`jzu?im4Rt>O+ZjbQ8mq zgUr@an88U^5GYX#{*?bawE1Ylt)b%%{soaQ`Vk0Mg{Q_;)V`YuEYR1;U{*3b&QC%| zgM0|w^bgAQcWiV6l5s0A&2PAFEM$r$%$EcJ>%qF|TdS7OOdtDFqW<>oM5*G$dbn#d za-{xKZ95#UH?UWp^;aA-V|h$1P;F}61soAStm8ZL>J#}W$E)IW$R@9Ca$W7I~&JmnJmqiknuL;{|HlWy_qcFr_6(CObrlArq~SDGXs^J z1%&P{C`owU>ddRrFt$9}L$_p%aXNNr-%Y7RCI>!ltp^25QmzrSIBIsYs?bWSRtT(x zKS6Y^i|3fNbQwR1IfQM*I(q4J-dA+It#G*8YQ?|X=P?&4i+1jfU3P}cN-uDzP^~$aNd~1~?6<)XauSfFxrOK~miS3dqp6i=|tld_EHeke2lGk$z zu43^YNrCi3Z!B;nonoV=DQnuHbNSGbJS*{H2s+W8VfMG8HEM+-c_37=``1xO&_F8# z3F;^0=L|gIYgdATuOn+(#3GOHUc1v zB9}1yUAEMfLEM*Z!^Zr}4w>A_5BSN$swO`?J*^Zbw%7Vg}8Z|rSJL? zg){rLsNV(Y?W)MD#;(NKqCM>%-sIbJq8UpKvth!OO;McMvKSW}lWUc2v$Lb^&w zC8Dr5OGV=nd7(qlxWdTE?JYSlPPa=WaUL$nOfSH5B^}k3VvgjCKHH*SZdBwXb|0_{ zaY!R`?e!9Jj|%vz7gwx|WOVA2JkE*8mcuXCC=`>MRT|-w@ty1EL#M!jo&!Q0Hl>*nNujJCT52@wC+d0ux zkd>uic~NVoRBsZ~KCfM!w^j@Y#^zF)nm2JPLIY_&JfG|M>!%!`IbE?eo+lF%m$dkA z5RKRIdl?jRQHOiCQsEI9ns1T(rnz==0CSO@sH3q!i5F#1Eie*}LDW)fzgk1!z#}Qi zAXJzzYOvFntNNzbY00x)uj#3Ex`)ffGAwUScy3FUsig&i0IzjZZ+sVyuAtwLr33Fl zq`X8ZGD?~DUS8UGR8sWT4RBE(`GiM$7MZI|y@0a=PTP?4Q`)241>>YZO}k|w*A0|oTtApeBSpJKI1?s-$K+kt?*)Zqh-n4 zZ;d(2L2W~FEcKrIgQ&f2TerfgID?A~&;wB)jC)ceV+H$utYYI}Uen5-;mM)#8P68p znH5pRrLx3nZ#Rp7I5qfE-*)jWI2FjdSB_U=M^7Q%24dN zA0zwFuzrY)&u;3a#7jtw`x&RH2^{rAa73)}o!#Zen+ULZtK*{t5v3P@rr)j|SV`it zGu8Da|AqsyXSKZDad?_$Nb0`T{j-P>+#AlOiwJG~GV!R{l(mb@v*+4DYPZ@>cSF-A{250F7y=R`Ka|-R4kj_3oaem$Mg{InH zl6I3@thBz=O&IElNEzc{57>~@9Pn816Ib{1LD#phZeQ0`a|eE|$Gcx1+O1qxTs`|g z>Q@t_uKe7zEQC9)^j|~q13u41KNIV+Qn8>0u(KR4HFMyIexrFlQuXtHh{(Pdn|i&_ z?0kRuG-|hMbP?o#H*|Hq`n0@H^@`(9>pO8s+5T*He(Yj|@a7&+QWZXziUaynOtuDF zfyN1C|8ERa*I!kH7uXrS$WF4}KGvxpqsU8uOKH1%@mQOeyfiZ@`+rtC{~vzMHA>sH zyVQSIdxxqkfX?OKqE3^v7IYI{t|^ECD;#U$67_{9YB7Kvr#q4c1L++`LsaEU8o8x- z9pUnV9!AbtZ0}rfZ;^u#tA$8wME?g0spH*`KKj>-ojRhVQrx1dzgX-T#w^4$vqkuj z=8$aUVs7f%)?kp&%l5nU(Bw=Rb$*K57vJR>o_6j&6 z7Y|o&4qQ}#2MSOq^^TuUM^C&MLRvy2-b&jPqw~v>UD2#Vo!}-hzS$9e=qK~am4ZT?5WD8tJEmhLcVNst zEya>pTP`uUAGrnUj={2Zg6)H?UDl|~cyM21O_A=rxgkI_{6ZYmRj9fy!!g5MGH;c- zMIXZSUJ6;viPa#Znj>KDq_Za|I)SGa#y8WBVHK>K4rhAsZ#ap|3WIjdd z1|kdMCA46lGkTsO4%3~XQ`{GX*FedsLNdeX<5tw!gKI|8`ehYRlmtRBr8q0_+W(|B zPpv2giG$O@XrYi`+ml!-1&9+BD9%o}g<{|=`2D&fkZx2&td_WMy83T zjwYJFr`VJKw(yx-O}{d;pu8(^zJ_j-jfwM`V=mH zZAujJ?m;4xHK3)m0A3z~0D?%?RJg;>laBnCqL{}8? zIOt-S^2J7+SgBmRrF&3=OMJr#zI+!Z&t2v1BY!3|l#2=HFR!?ZNZBhch5te$+vmS9 zEt?FdX-sRU(C2~vOWS;M(B2TrIgnvbHI&3=##{V)pecd+{iv?^_keIg=HA=l+zZy3 zz^<2*`4xfUcBrk715CHYXZP#)Dut{qgQP$A2RN{a3@fq~tGiDHPt(j+ZMB9*ZvJTS4YCE5#NICB0koOvnv5u0^7nw1gySSsn4cX;G_=8y|bV6{rA1ShH(d*LhUy)N5}`?3mFfBTS|?YVKm8XSPlImojQ!SuNfCBXzajf(_({m}WLD!;>P^_KJH z6BqUl_crmLhxOwD+eXV_iXC9{;!Du9h2R%oEtFq?5qG1J&m{vH33q%_L=}b=rUw$A z`s{xmiOe}6(`4Onx0>cBM&LcbI;s=>=ra*XBImgH6lEB(&B3al_^(OpD5UszYEx0% z-Fbt8+vT>d7W75u>N=gt$S>HR6TkAP{63QTT}RX~n3EKVpa`cf!P$+-6+Z%{1MPTR zKCMtZ-Y)L?#YWQw0D;s2r$3uc{d(_5=dH8bZv|GpUtb#|OwAAQ@QlMakHoo%0|)s6 zMO!UwF$`T^IizOPE%+AG`ql;u6qhJJ-B3Qv(HzFVOh{C?e z6*;vBd{pc!<(C&w9_zB;sXJ}&w>_4v37&=4-mKmWqXrDiq)QkTs+iYpPK3_Y^7Q$z zFopb}82GqjH^AeQC>W_I&|BmNO1eq;-CJ4Zz1is^vtEhUC6j`y72e5gW@{DdWGfY_ zad?$6uQs98H^4i8ox)mW>TD^H1l24?h?Szq@i$LSrKGjvZNxVk#GJKgBl1*76kS+R zu*0yPdSX13KC1sD(?w`Wiff95r-)oWHJf+|Eq1}ZT)@56=F_vFr^~N74{rE1g0)bs zmpp#-p&#X(9A9UI^R?9c-;(qgMffUM)cfRvTog7u-Dk8)D-mvtkIXxkD0>T@p>_nQ zi7H_fH5dvdzsDWTnV)!{q^T?rzm7UaXErAOtuK4+X}Uvi+!E@ip!iZHwA+d<7@xy; zG|*D_Zm4v68#WU}poaf4k~+8oR^1o-VnBz`LVC4nm~ z_wYnUjiYFDplrYySq-haB{;~%l3F<;|RHBRJK0qi~k0&WYXGhuKoWHS}r z+mzK{mLwjkI!w@;a$3Z*?P>qh*Wse$=k^hX=w>yQ>-*KEefN>l8_uI-@5r#hw7&;- z2OkWq%OeWph|Drzb4v`TElk zC(NBa6L-!m(m}@3JeZx-hEp3_n-l{$@mkm=oc$xEdBru39%)e{P#sj?a{EO`v-RZr zN3fffyw&++W)+6zbaEt7zxdUUu~LEUn>Q+uB3H+-FWp(x$Bi^N$j6!fBmGX7lpju% zpButi5}cOxg2u%}L^4N@Gk&_Z94o2r9u*6Xlv=f>GyFc{*R_0XXShzyjlceI87io= zdK9wMSkBIA(4yJ?$>jiE6dm$ZXqNjq-MzaAhcGi%O3Y7`COyI zvxditVuy3~2f5vD*b}SijY-xe@dv{kSz$}!yp?dxyJ|bk>_>yv@49y5be1(Rov{D} z7wGI)X#M8<+3-iJaY`DOro$m&zj_Y==;qFY#Pi)G>VR*wz+*rdrSj`o`U@TS6aTA0 zgHsLb>#5lN^L~2A`hB({&vv_N9P-ohkTTzLf=cGYl6-(piVG4@M;?|D0P^c~x)#A$! z+MRLNhBxig;-vxq`Gx;d=t_=6rkh{-wmb2CZ#b1bUDTITkcRm1XdVQIN!Y`9rXk+c z*9BNYVm{{_LiFEpCVBc0(u*}`3%Pv&h-ee4N}iR%)d`VbBdOs+bRgtN@n~7^IeANj z+ypMtlgil~PkscGXIw^o4c2Ua@9G%^^WH=)NL>@RY*fp*fe7{l zQVO2Y^zS?z0p@U}sNr8eXff=u)?|D1c}AeX$Cn8${B%@=*C4Nhl{TF;_CO<*;R8hh z#P9IFKoDG7^;`90BTQe`d@L0BQ8+3QsvPh&l5`=zdI7s|##+pPDe5t_@V~l{m?4!5 z@3VJZclGON3qgPw#EEDLW`rhHv4&Q=J!6f8I*GL*xRrdIB|W5YVS`k}RaL?uKYWvA zWXLB-Ai!4WW7quqv;Zi`AVdjKoJt4C8?$`^H;0{`8wn_PrW-Vz?BXa0U^W?sWnv`& z?wT8wmn~QqTEuTCx!~)mCu1oJkr`Vx5`lnw6y2jJI$r7l>^mbnp#@5YS~<&tMBY{l z1RascNQWXc@kIT<@HguG010MP4nLylMu1*G2wp9XBw=tEHt>j2Dx4H3J>)I{vANa2 z@A4<>yQGA?N^@DUu~)+7Ed?GmVC``RVaNjP(&2Xdg5r$eK<48q&U5;ZZ5u@{`S>zq zD`$>Ysmy0mfOqYTeE9gx$Q^KALVR7;OTUD6{&t zU|?+zC^L5YV|qe?ptA_^k(tR~mtTOyNX+EjFK~mq9uVr9Wf?L^#l1lE@-quPC;b4S zlLlS^2h&DC=Y(NvEf(tgPipyS{0W`ErDkZ4S{n&p*v9J`Ws5|Q{3@rE%wtBc@^^^4 z?D`#C!5@#sNp0i5$WHcR*CVU z+`JiO4G1^HY@Mk@oRuM@zanesccRFS`ATeJ+LcG}y?hysaMh}HpY=hZkY42mJ;<87D>Y5#IXU79Q>&!G6+fNkTL?8Ji~NAmpZjXZ$_ z$waNzmUTUf)n}}HniFwjXx4;ZV&l?{P8}xK2ifxsv2sIC>!>~KW7-Q;`|-QS;VbEz z7Neu zx}zOM4Bx{q^AGT;WUhZDXFknfKYypAC;R#rGuNKdEb^Sl-`){KIkzPTI+(U@*mEJ8 zl!*2$h7n(#5B(yEWaI;JCNd1k%nw-e0e{?7_j-Xdh zfR9Lqs@4DgaeO~6(#nzo{@6&*p!s{wMymtm zVDDRy?iO{R4SCOBy#dUpxF|4=_vVqfE2nKH$cE-;=<};1Nt$(FUJ+lJKr04uxWViU zbb)_CPUEbun7l;{Xdx?kLSu^G#ybV~81Zvp5Sa$y2bNUWi`<|ccZBGk!kZ+lX@S7a z@;g=98izc`YnJuy&y1Izz6?qXvh8q`GU`qCmd>&O_V3?u`t*`feM=g@C9EV_GD&!G}vP*#qqbR$-fQ= zv@=^z&^LDV^ysa=>zb$dMw%q`x8RzehcLXDWr%oqV6R$1BjT~P_yH5n(E?Tk&t;p6 z(ZXjYwrV%Oa>*u9Ev`7_e#WKfJw)*;A5H$EK#jT^{)Sr1-l%(dmELFmuqE8YB9BGW zY4K5e5)VlKtM#QCO7f5Hl#|%0t>3Gd$uqEd<+}7ZkG10*#mBAm&qJ_M4((^_8zy<; zb2GFpXTz$tE-!hSB$-dEBXUd=3q)LHl|p(KALVI?2DKlH1rBhbQY7e$->kzO0T znhUs1Vkh6^qnHJp&)L)8K31(Lg5ujgn`G6$FG#r=0G>ksO=0?8ZX+4KCCvuzvlV1% z#q;pooCr_%WCbNSjD5PDb61+{W87Khy_`jLxfpqRH>h@K6I5>~tjV!!Q@eTP=w6=5 zOY)ewO)(=@I|9P5n-wR5)p?qc_}{Z)4*SFuH z?gTRIkVM2`J9zPcGll>Z9;tm$8r|A3HLFnU_)B?~welw#=Pd1S@5p{^)84 zejnHui@PmL>QV2(4$XPA8p0DiJJcb|(QMI5ISwI?F`xeD8)>{{WJF$hhYEL@7>U-O z^=MrLPcHH$fZd!Lq*xF1?q@O{JyJOh!Jh>{>6z=`V zQ7PDXR1k!MjdwVK61BP)ubkkFQsVCEgl2ZZwN-u1E&mi-@-;h(e2CqLbLIFVHrxu+ zFz?Be3uDFq^%-|?VDf6~dz$2^xol;RsDU>S-;O)-Pgx<#08UZreCie7sV{r#J!Qmh zeXnq%$gaSca_@*;+<9j5aVw(NY%gN6PX5xRs=F*Q9eB^*XNa$GbJpM|l>>)kpi{md zXxGU1nkOdD0lR1Y^|6Sru=D=#Hh8qMY2(LLAW=JRT%Y=2B*=nKIQyjKP7ke`lcmz!JLe$oN+C%e=g8f1&rp$vHW`6az@8FNHEG_wEZ zcROMZkHuFH)7^lfjvfhf|?RDRf-8GM~SD^Tws|ddeRGyuRoIVd+?fRd)n_6ej z{}OYJXgz7;Y(J?N%ZQ>BI4i{vk*;Xl;i*JhY$tc>NRa1VP?tw;%TV{XU3D2KpDk{D zIT$c6hv8x?8%h z`ntbad73t(Qe-=Yy>xH#{&TN?R#+LpK8LBM}}q)kZiE&hrzm&!RFQ+G9McDA5GAtUcS}RDI~w zk5WR0%x)lW=b0plU;xLtA*EU-g*RazJ8mcjA`LnY4$`L{7T`@hP(KY4I_?@9g!9tR zkHFDn1lPSoL|~5KThI3o$c1mDmyu(Q_+>MoL=8{kjhjhlm)5NwZcv9)f;~+xB?d`2 znxg26EpO6xR?Nm^hzeVqB{uJJtu6%}yt8Nj*JI1|A=nEJ=dW+|DnkPFovFcyI3bs3QNrB z8=}<|0H%OalSX^9j_&Wo#T$9NGxavx#KsZ5f}c=Q3dE#%`Q&6U0CJ7IjkL907sH-i zMesbZf-nc5hP;{0r!5YBErh(EeVAerq`8?@Bnz>Fb!Y+BI2%%lekgL3z{UquxcSo9 zKNFl3NK#D1&hQ++NL~=*9yz^NPyueY6bK-e_oB3GUhc_Cgn@DDRc=Qn3VWpxKtpB^ zFGaNIi@s?LqUsD_P2nsYQ~63-+yN_yLn!S6^;;614PoCN)$PN_s!mS$@zjQYh2knh z%5f4%JI5Tz`Flw5sEbg0zq@D?isxBYt%u~}hR_fxZCZ?6X9We0-=VjT;%qTXpan!Z zF%f)oBER7*(O;^z#w)w4KCD0+(`b9K-ruQrR#aXzx#x!O-wReE-&0fRchH|D`$@ae zUs3A_;D4)m6U9C-^MMApq&s(s^8&YNGzp$75V)pXrc=eY2g_u|(s4;>gwQq_bMukl z5Rrl_1Ok-w0$+a|SGR9K-B{rIk3<4PgFZ_y#-XlvaYo^dLrr56I6g-x!8=lD);gg& z%=FVUL~bZr&7p3F6GPet$>E7FsW(UjSoLk*2>@SyeE<(R57T_(^GWvw%h8lSf00$T z*MZM4XF79uA1GtdF=-SdaZg^W=ozw9Op!vO`;=?pru5t=8BV-2aR)SGevP{ z$}Q5I$9`CuDe(4FS-pXTDk|QyYg-0Nop~A>*|2EBEk#6+ z|D1H_lam;Feq_^V>=mYeXx5(WA6CyjH4&t00|Ij*s}Pb5GkpZ^16ZUouq2bTwDf5V z*$f}@^IPE&WEyjnjaNUeP_^XE$I4)xJqL_8^D+(T`X`HTh*)*(PgozTrBAr^IFv+o(CHW}%Iy@{VNwrj=?Mlik_7QKzkZsw6DJ$q|zeAK(!nZQSF%L8_@HpKpT0w3O(mXrl1)7QL&4}*x z@^96ve3>-y>kiP(x1DRd?N1Bn=+pUaB1JAE`w%g@D;O3q5KRs@N=>^Cy&U~$l@2bX zmm{^RnzpvZ#XgKn|LX5unmwapc6q2Dvqf#C(4Y6iaO0BM$}CuIN04_dMKCHZKP(33 zs+`_10~}`uOYQ~YhW1A!9%zsOPbwUW!cN3u8E~l3H-ZavcfAJ!^qGqNpqZnsed;%c zz1W~`s0SPB8Wcl1C5Xx;8<1_b4*%?i1}EbGR?t=-hO*D_Bxy zm0@w?W)Rr|RC7~J=~R)l#)k~&5JW^tY@Oiv*%{f7?0o4S=^p%{27$IxR76_KeAnbl z&a%7i?j8m$UiDW#YyQM<`pQ@uDQdI;LFp zphlD43z9`YjyYB3%x)}EFo_EjMx6Hw_;=S$YAF@(nHm^jI6sZscDi#CoVX6yRCMLB zQPlek#f;ooIxf{aie3zn=e3~vKkt@OSbz8|oW|p1D~x%sYonYGmZgQA3>P@;+34dZ?N@Om5_gzLWjMZ1tCijqF5!RFOqZ^FaQ&0yDc zmbW9^GP(Jr)#&Bo>h*bus?h!UpK&2k$DQ5eR7F@x6j<;9#cF4AUNaim=FxM^n~mMY zrl9lj@U}o2^{R2j$vZ8C`z}iCe)Iccd1ImD-RNof+YG@oTO>>Q%Lz!rV^6YmE?#cP#SE)6IcHCiapivWwy@J{ zOw315=tYUhm-0T=|9}vx_ybkII#X3PGf|3s@?zf>w>{0QNgy> zn@s+HJo!I#^Z!!lN`@leZJtip?M~J=#<{{(nK%2Mkn+2qe1B3myhvSBQdr|CgDBrM0w-}Dk9`?OVI$-ZbP`C)$lop^LY@4{CcNry zz5U#;wOS7sZ4v@8KgIsyC!cR$d?9r1aMO+sF@+K7Fb6zcrzT1G@a(ehg@3vD2~WJ< zQyqMtrh`vwA5i+D;WJVb9|9=&LB4VQ{)3bTF{J*n@p&^=o;*;$Gf*vzL)-^Ysj+?akp=l z9q-Vk43$5n0T^FEHpxwFCrZ@CfIc;Uk7j_j&h|H9z*EG1_)oaN)4?4;*FskCshX^D z4I|iQ3{OqUS#fP-OJp&s$H~xHjeul?Ifx(b$F?m*HApFpwI4^`22W=?sL?Kr8gzVB z)w<_+_4DE12Y|+y?uXKCKwUf-QN$Ing2IW5@m`Kn{HnWSo_VQf?2B^=`s24%KlRQn zT&zampA@ia>Xq`N;x=`mc2pzZ@T6>R;Z)s;5e{R-ac^ycvLsX`2q$Ik5IKJ+Mx{~^ zvXb}WKTiacE7~XeVNNv6F7;F}vB;6ZnJ>{x=!ZSm`sD?fx2FE4?{E4j`E56(;1EeW4UD=)2TSm9UR@e z8W)90jTZ)pXZH%vlQd1qTflSfTUO(SeY)X3USogCro%3YE;-#3;_3=HgV0C6d@P+x z^Eg+&J+wyR-_!3X0xdqt2%R)K9!MJFY~WL<5v(Wz@+rWzGQuGR%B*LW@C_uQO8Q#6 zSp8Y9T+57_()v3+99!tu1$FbhwMz$bJ-NY}Lxsa?AWgQM@7wqW?9?TyZYtYv(9lE{ za|UDim9CqT!FSkV;@A=3YEyHHnw1;DAY$a@!u*QFMCExQAzU+L!AagamVn3Vb;8m4 zgWitCFv{Q}7|(Y|*-bT^M8iySmtuCwY}OwP#F$wtx520Q!+$H)_&ZJDU0}tcU%5?a z9yy54A}v)7KKL^4Il+V4W(sCEoU5v^H`GGH<0eAMh-FcUl-qJnbkz8HfS zC>7L!JK9ukg!Ezu>X%+z1EZ}6NuWa*P05|hV5D1ZWrov0>eN)WBU&%z+jdBFW1U!F zbjwj{xm}K98v1K}lh==A!na!>O!m#i^Q5xE;}+i7H4c@Te zBZfSK2v{|tk@2o}cs&;82jUBs87+0?BIh8msd?+%v0zJORg%pnU+YyV{KSv>;E`0B z0rbm`)W~z)1?*Pyj1ha=vbZ%_>skZ!F+xt%Oliz66gAPnp&;_%!k?ry{S=JMbcZFw*YguFhBaWux7Q6AhYSh$vzB> zn0)l+%3*$$E(j?Fg}f|7PUSmCy*b0Oh~``jZJF1ys?btU4J}^wyUF0}F9&Zfnqs}g zBeH?@$1Iqi(4JtTO<3-B_{99!GzKj+Gj$TyFyj1GiHer?=7!C8E6a4_6H$7J#ON<5 zbl`>ZvKy6m*-B~8^X|Ngq-tNkGqV;U%IuW3k8ajrxafpf<2!O``e)zK=W>kz}6p zvA`;bx5{xeW#^eW#_OX)kv)<|G%vakooIOVnVZdtaqh=sS}00*y%sp&1+BBC9_RU) zr?H=|iPpt5N=QE*{`4K_#+$E32@z;(N@mw(NX}PbBODkuC(G69s28_xdggg=NrA`y zhjTUQ*Adu=i@HiitavcaPWYmb0`DW4FwuS7d(dyDhD_|0td{QY1I zrS2)PtJGyPh@Ce!VK+_ZBGddtultTuMT_59N~1Db26~a~H`Z5mxpZlJ8W?ep zxA>D@TsD?WhI>q@j6yyCXivfp0Afd(G`?VW*~5xeGgV{<={%m&>?TbIjf%%IB8~#B zEFI4bs5vL=+g&aZeI1=o${p{627z}Y)}plK;%Q6yhQ?58CztTMLxakrj=i-9GKX*? z3H$MtH?Oa+jg2YOveV+!R3zVWO3@%`I}F2mq(%T`Vv@*5PHt%l_>&E+9NX>^T^~Od z-hpWmxNBytv7snX^Qdk121IeSUOGJA$Y+V7!00^9Je9t24UMx8JG2NireU+BDZXu_ zZRNiiYR7IEi@#6p_58yhN}+a3$lixW*7NIis`6>}s@uPXz5mhK-@x@q?E&ZYMmCOQ zc)0w(w_NNU$S+~9Cj$GUiw<&?Ua-odTi><(z{PMtiy18_ayhXhT`{c79Bf}MoJ%lvAQe%Z|lSVY~e&vui!GYbt#8S zDZUCHW4*)72lo^$d@%tCfsHDl*Kz&bT^&L7jF0BuN#p9@Q6_0(&iQNx>H6Aji=;N`gH49j4keA0Szd#?58D*=386j zr3!EmH$w0sm4ivx`AHiib6LD=|L}MJ3mS{&6bjsd`_z!Eid5%F7CmYOZ1*Zv)5g*h z3Ap|lSqpyf{S_mLyqYl<&(JL^=y27IWxsvxHA2=-gO1X?3Z=jh{K^HPQ#-E+#m_fjd+4G?r`YAjD!~A zsNN8KZS7<@nF=HiZt?wG6YA=vJ-_OCOd88Iv16c%{q%9OsGt)ojF6F2b^L&1t8M5! zf?LQNGS&^?7=^)P7`V|$tU7gRF(UhD(Ce zA~p@ykQ>ITf0zn^KpYBD)IGdB06-a7W0Qy}X2(M2#(0pG znGMIvY^tnJg7qoZo;^aq8`o&0=Ic&K3Borpu5Htbtt&~o@OjE;Ho!0|fD)S~GS!3tEZVy(q73mR-{<(z}TC29_S zYXE0@oQWx#SYSO|fU~l*3>1e?PKzX9aDwM!VFSs0O_l3$ruX!}!K&1%7KpCf6yFI)`0N~ixTn4DO~O=an6RW{54$Wio05u>luYdQ zwaE9FW2MgOEKL5f=YPnEhv+iy!g?0|pcN_q(y8iiQwr6@58{s=N`PyW8xjlrQAL^k zwccawtZ)Mf?kQfg>=)YHXFkc8ghbP;m9J5Vr4<;Qd10sjsDH2;B(GmaodI3~@5mw2W7W zAAkPpgFcz(t5Lb)P_>@s6{9qa{Xrnap$2zY>Zv$`tJxE#8k0xjc39u?lgu)4;K)p( zZ6l4=oUjsTrKVH!!$~!hXK0W<#|z_IldmD|-@lU=T*sFBL>wn63TBhZNTTTyE|nt0 zbw9EEA2J0Y&l`Wx4!*R4gv|XB9;J3;1>yr{vU^WsHA$W-Zx{UQ&7Yi&n7D!$eu#lekunBT~v!J1d@HU`AI?~1n(Lt7oH zMkf}&-W9x5$!2JTVxNDGTPD7~4#yuYOiEk=9eHRlTl_&5AmCi0IIfce zNobSR_|!>2iRv75(ZZ-n#Ezn!y6!Y62;Z-&Zsu=V)XhPNt4Lnf(j*MYW`8sfv;-CW zUMZ0>yaHZ&tzb$$j1%VgZ{LDu(xq;3nV`+kQs=tG^mYASi#}2^*^_mv1XmFr^jvPP zLF#O`6Q9E6Qn<|yH};`r9S1j6%Mx?r8Aphg7~bZ!^>No7xS=roSf`KJCBM1`+`zRH zO<3R#TA`+MnY8T#g9sL6L3dZ-lEbG4gy0-}^RyXUH|q=&pIT9Bm4|4*CM^<;7x0GC z9@*o@0voR|6vj`eyfHb=Up+sfxM%s#6QR@WSAejz{nt3^u@?rp+u(W59f)K+u3*YQ z>PyV>U0vo3aL#eUC|VTfEw>OZ6(yk*#WT*?Fd|?Hm^*s595^xE%MdEtjHXM^!p}w? z0{xO|c@x76TbT>WIk}suil^KZk}?3f*qpE&a}{4xho+Rm?)`{gwNWa*sxk7E0_?6( zW|aO^=r4?Xr2R7c9-#^8q314kJ|$|DIt%PN8yjJctR?2=o2M$5W9u^d_QPIy9bHmz z1{Be?wrHVov3(><&Z8XuolFh-_lwW+^XEcyKGce&M#BzvhiPzIvd+GscbN>-TJ$Rx z=fFFbn~@?#vSEhYFB{s{b~tfm>Qn;zt-;E(wQ;lWGR&{~pQ6sLqMc;;@CQXkGeAKx zVWbvb2Hl}Hi^SC!5}hdBQIfW_Dnai^)Y%^GFgM#`dF>1{saa+zev2MA4U8Ks)s%bD zCWrSAnA*StWkcAr{)R@%pXoUU(cNEkYsGp!GRDUb6@4Y9TCpNhjfm{{xuz95pM zzT6q~k{Eda&<}%Fmj|6If(H*PI;SI~?my^edu{uk;j}3Wc<_9+AE>(ZY^w>lW z-fxy+tp=U?UxVBUa!lYc0%`Aq7XgH2Ju*#{K8!CDf{HJSu*??bQEVv z+#_B*9h|Yvq`e-)}afS5wY3lBVo4Egr1u*U83I+{5Fyk*oU<}&$7|>$0a}n3>0xy-*{!ldg z+(aqO&Rwb@bxKzq8yYjz66!uBB@xEP^Ps2N78e%>Vt!3J<&27i^X}K!@s0?V_%;=F z$8UQ$?L=r+=(5!ue&;$XWu;@x zJwcp11619-g=X7HoT}f-R`RE*WQnE{#=1wW!iii~v<7ySh~0l8ob7BVAF&&u(knh! zprRlho?X_?P6G7@i^g)ST6-SFT`olWa$i0Z+u~OQMCy zbTH(1$<6KH z6+R!%5u{&kaCItr&bF>3Mp21nIkcVkr{w=Q+;;!JEx27oDhS4H#X>V-+AH6H6#TrI zqA#(v`%gnWUdNRN|D$#O|L^CE38#apC#{jk|HQSnLwX z#%9}KZH;ae5e^+U8j-fLQu6&gLu+IzA{~kXb}aEmH620-A&{x01367#EeCKa!J%pW z6UsX2fNXLOP-CGbHta-v0YybI*a%;U_I2)o1kt$wT&PNw@Br@kA7CsL>MBUq!fRQO zAoCuLB$i={Nd7F!95m_%ahrBvp(mv7+s)?~cpi8j!j>(+fbzOQk}VlZ(=o}x51uZl ztMnO9vfap#9m~;&-1@7DwlG;a3Gvca-)TK0- zUs`siB7QzToG1?n#_gDsm6pa3-)A4gg+nDs4w323X@%&`&hQ4-S%rR@exD;9P(fjl z#Mm^{v|XlvkR$Ry)I_3N{mWvLmNt79^pyp_eA<`SQAUP?H(jeq<%R>U(M={j9zcJu zT-8y4UHiS@5lKw43(~|Z#+Ui#0s;iXn-HKXWP6K%_~rCsG6p^1D-yzKC$M9u2m$|$ z+-WTm?5ohe{!^lK?Rv3XnG;Fd&z=svcz)nSg402hP28LvCx{@Y zkjv{ShI!{-kOOUP?aBKPY4IY({jPNuKzH1HKIb3ebP>et!fbF?(P9i35i2t4(*gpw zkSK#Xo*K)AU4%E_oE|X2SwLuu1sB6AGi5OXQ3O=^GiHkTcdw&DzO`c$XZT@k5v0G@ z#isU62^k^MP~e(3EyJMsZtn9PSGD%Egf_y@wm!TzFy|Ug9_OKvWV!{qhzl=AY%9sZ z>1P|g89$v&e0y&r-achfOAfm!#jFFjrDXJE6T1ws$@yUBn>c`b92Q%iqoE>DdF``f zaW>`v4k=1{xd?(M-PYsSV|A{5N{jsC1vhB9EBl7f4=ZMrxvMP+ zpAn+}IpP+T{)63}cpjpf!D9)+uZLzdCV&x{3`}ppdg0~{(CN`jdu9*A(+~iL`1e#L zMl#$~KDZ)B2YWcwff;JVQ@D}Y9dP432gd$qyb>OU-rI^+G(wpgIsMXp#>Jw08!GxQ zC789B2R#4CQ$_q?tK8H$KL(DDMK8kl8+nlMpy5K3)aS~@Pzx57>VD2p@vI=++1RR3 z9|t2%q6J8Lu+`W$%&YcT%6qWjHCRBc@!TDKqp7+trSRm(!$=jrl*ht(nlq{SNFBEd za;|GvWE^eFGc09uH=4Xi)Qqb7`6&c6;rLiL+6EHklvxUv6Zhfjuv69VGk*NA_R`fY zX&Q}(#>+^RYHc$Bt4>YLl&}hT{#8b`g*HnvOgE%NbI$APRj%SD+5YLC!aM>gKSq=s zN8aykuuJ=Ny$RZcs`7oz68Py8Z-GskZ@B5tzEOk7vFi;wvNbPo%l8`qIOn_2R`;EU z+dEs0OS@BqGyZ*}MZprc>;5+BuL$(Js%NH%i3nvnwB6g3;!G3-jKr&C;c^{9&!Ju^ zZ`aCVeqhoQ4x}u9m0&tV0FJuXEI$;^Fbq6F3??8 z`;zrUP-!Hl?~LTXR4=_%(d?GJgcTrP0o6#gEumTpqpivdMB6+4&R$y-ZxX?l zWpl%I`tpWvL;K_>ALXUWt4*SDWyK7Q_b?u~|6DGl`-XPq0}&T6(Bd`7OBk}Kg^9K| z(_dk8ADeJj9o)f0Gyxf%MthBr^GQJiYw3ZbH*w9+=NHVa zx9bZ-c1(1`FWNSbAh*_bWgnzG!t=R9X+tZW0`6I{YO7;WqG8UeGa+dfUio@V%Y;J` zmU-8I)C6OWVBVgV>kqD0E##vNOJgfrxnJp{RTO?-lzD5>oDpT-@i#^Xy7}CtK-QV9( zN1kP$OIRPD8I5bY!2E7F@(VdTtQ0CfnvUw6yVZ=8#j+?IyXblewXRZ>qU=ck-dMe!9zzZg<93HV8n>e$XXKQLmikX^`Cfl9HCu z9j&|iTdMz$brT_-c;!&g>Dkf6UaD;1$S&zA>ikZH{{p!BL~B5QM63cy=39?E*OATc z0T`tQ>f9ZK$n(B?Fk1tV@1X`q-n+x1M_`&r3Q?Cr;P`Za z$~VC!K8DIce#~PBG$r=3DTb%*nJd$Kjm16e$7_r9+yl$G??VXx(nDH05~@=+Z=kvqomuCIE?32q%jbJK1SY9$H+7p@5S zf0tqK{r?2Vy zYAqCP^842ZO={R@iLW9t^Z5$jtnyc{xA{Nn8az1$K3vi3e`4!;v>Q*o+`n0YfB%tq zJ-ThvfA(@5te^DUchkP*P;y({ewq(_vhcV}U(EpDcHv3vlm!F5d1hG~mK7prbLg}1QhMF$?Z+s7R_8})1R#WysaPQ?2~c(M$r4U z&ce2JReipTW9ufmr2WQclYBL0@-FsMtH&TaX^Hq~&N2~1c;Xc~)%;DsX*8|ohivs_vHjWlmA}c{9?0LHON{;8Sz&M&{X~ZR*54uB z7uHDTE^;7JZjr&{(#f|GRJ=tal*7X?!Rw1O@M&OPLCrw$2J_u9sv;*5DstvdsSa6j zF4e0=aRG1sm8V7s2(p`XdDIvw12FY!eiGyU$i~6(pS1Yhes91Ha)?$;UCy_zN{$+p zST$jMVthM5KuJtJ7h(jv9$Y0HY6JlY0L*)NDwA*mS|)HLAjou~QMJTscw)1yt*8G;(C_U^wO)h%B7qoihg_ z4_D`+?_LWajlYcYzCk7_mlNQ<_@}E4QMkklOMR@<_R0PeRh*)Kxj<@%=*WGFT>s&ox3R@)T3iY#-)0;dL z59A6mF`OD%C+Zg8G3YEp5E54rBYgBTh9Wj-+fFUy3&2&e8u59Qhi+dCF&!CU5yzm# zIdBx<#BdlB_zB}v9HYNRz^F4QS`+#{XXdSt?XjdL`8Vm9y=)K1dSNMR{4ly$vqh6Y zfW3`P9W|w}OMut3MMmf|1`iGms!0xD7O^(N-`8k1y6=~1$a}Lb3sl|;BRChkSjzIB z`3!(nd4`#nXn%VFSk(`4gml`_>I#6tW;R+GU2lp?C;hP>XVB=-QhO=h`TY+Wh{fV8 zb*jR$G{~+PF=6Z@hi2gOMD#qP%ivlqZ7#~gXfKm<+;ut57iu17>PVD*Y|!bTO3~Cj z*6?0fsgkcO3hnrYrP@6=_MSId(`zRfnTr~4`aBqOi_=S5Q)D;5p51ft?K6X+QcM%y zs?zCRr}6POO>MxW_MS?1oL2%y%awE`sWY$H5E;Cb-3V(l;wwgpP1EsQq&(f7XDmBP8%;kU;g2P9XZSfL(1-%l z;TIh*!ckORAj_svGIjvsfxXwz$Bw|5jF0TeM`-_`=TrLA0hbMMv(mro=KRFyMeOw0 zgjdEULT2y$7(ym6|Zoc>X>5BfD^Rrux)GwzLjPcX_|zapc&O!PHS_&9{sdBVAOpZ=wZh1dhgg_<^Tm(V*`0q;^%_@9K- zu$f(2YDIljG7GwdnH~pIF>r}n%>+yTq?B10JMKfebYp&c+oJ!OfOtZ6#F7viYW)#>$Tn@S;uNoq- zdk;81653cal|OP=x$ea!LvpPjq_1nwSdiUS&K%?1U!(&I@Z%^|a3>XN0!Kv}(*r;j zrSlpzK{qagD^gr(EFn~b*x#O}1K(8t%9W2rfVrC(Ib@8qnEhvF!wd>vy$& zD+Np|{VB4qo^!sXGK(l0jQMUj65;9DTljmMz8`EJtemXYZ;*cHw!cMtg|I>WwB)Y? zp9p@&$du&?uJs#N7#l@Xn&A9pT)=uj30X`W$vw{B#H|+J>f!3np3XV~S+QbAENejR zeR}_*FW#~h)Tih-E#9*=Otf%OrmEWiN+J3%LsOD-4!zyJH^c63)vO-9+R;%q)=Lz# zzz*5r1)4yRIXo*i$ySE9sm_Bw6=3w!qIdSY97$_e`SgEy;$GB^%7p9ahdkSt$<{M% zZlm8wwQ`r3b|CE!j6mmJ{m|Qwb5QPPrtlv|#{!q~43U>VWN20veG9m{!_i2Iw)S&t zMj|h+iS~&7v3j~RYLZl4k1T;bBbvlJY30VpEV|2rGy}}zRY-_gQ^vpw-as& zK>s5P;q+?+(TfRu$1e0#yOviiLQtyF!=6T7-?uc;Sb_dm!tPmEx37* zjn5GH>8)w)hK_t{c=gewGc0)S%l6erS#PeuPAn{0{L{A@yD-qTbpa7xMhMT3N1F{8 zw7iwQdW<)V|8||0fhwri8$tWp^iBB-NFFEt4u6y$&J35{{*ZYj< zfVgN~v?gywrE*F7ZBF+UUdX+Z$C)46mb}t`ADbIf0%VW6+b9>}1Mi1)t`9aaIo{kA99U0&8Z%({T~?FB~w^@dUyXubl~2 z$(Zc@Mg`&E$;jqiq1(26#$9XD9n zIUyo?u$d}F7>_V^cQkD9(Go5xt;M-Rt6!W)VfGsaBbBhy8CLlq5e=17$O|DbQ&7T9cn(U%m;O9_`b4%F zXYBLkUh_F6HA|}ErO78T>#|f^aG1a2F`S&1ZuDtO;n}2=>E>pRb9LEul@cgz-vPJm zNb7)F8zwKlH zhJ#nfP21_W`iI+ZEek%+o*g%ytb~X@FE>7dZI_v+t!~2#PtywjsRZf^c;`_r)@S#@ zFJFsh!b>bss~1TP1^-#RqIwo9*NX(7_V@YQH~G66!q^$)Go&g!mk%dtqXh`X1~wk! zbM>#`ugZ(%b!~C}zMEI=a$I)DZFonBN`?1ziRgFzmur3fH+ONj-v2JMW1rVLo~`a< zvv2#Zs?dOK%&DUp_u3sdCs(7ZXCqgS747Fl2X;D3VXH6?ouh~2^JfM7vJbmAM9VK? zuyDsDR(OZ%X#?J!Cbv&XvKtrGUd3Ma_EM{!mjJx^=9G0;w(GHN?b(Cn(B8h{vT3}H z>a+vqkmY#Uhe#MhKX9Liz=4(Y-)8$x5(%W|m4lB}chLC7EXQvP8q3l}R2p(5^6@|U zDweYeFA_!m4@BgD-UI$OX5?1ppKs@jG3?Up#&QRcLtNQhk+9-p_|Vko7A07)_+D^n zy~9U>#DZteT@LgTa?072cqA2N#F`v_+1)fJ1eQ?G1p73Sc5ADBJmXap=Kx2M7{yClvpj`&cX5e-ooC7`R&^F^0(3(kEEctWWHl zidc%jHLYpLaYEJ%t!M_MmQ*Yl?xS)LtN00>0AJJp<)F>AZycrS!_r25V{^wFIVuH&qaB zS@w%3`%kD1)7XT8Z28*fXfYF!H&V?)d#`7BR|I~&srVs^2SgM3om|E_o%bOAe>(XH zY&ar;$cPB(X5(>A_;6o+>Dq};bQMPkz8KwuAjjyZ9BAy1N$huKuQ#ikZREb3u5&zKV$7Io7@S(8gQaTZFE95b;?<}yF}~|>#zBH7g!ja~AG_FO z9I`zsGvyF3)g{}3WaYJnult3xz^Q%3u=D-z*2P79;UA)eu`qupao%x^>E*t$S~Ou1 z|ENX4e1L|(e7C?}dXiZ`xW=$7Cej3J!lNvx%*g!UTT|)x&pwe60cO`kJWK%I>H_q#XEg5m}XyJ1y0 zr@O3HyK65Fk$IEH*)wKWMBzTwWEf%4|2{#QKPp1LpUlaaqX%$B>4@iFx-0!0tWae< zOMQxiNP1&Vc40>BcXdFTIlIte_OVK;V3px8x$jR7^ z{n(-XpGF(u7Q$?7sbPlFzGl>VU;TbEOo^m2o*}_2CTrP6{JBqtavR0-$8?Qy-!STf z@X`GSsbl5Rp`|2rtJWcbC4ud-%Om}S&%t=jzbNyTJdifTwJ$=D1+7w3)>5{;L4pvR zj_Gz@OD>8hDTh>mkDys9A@b?hmF(j{uF8LukJGmx_s;XECh4aSqP+t5byK2f&gEE$ zTiu)7<2X(y$rsYKb*;$w4OYo}WZL$v-GXO=Kbntq2d4KHyyq&}`&$Pg!U7^)X2;ms zbV*XECj+fHR&&MnI;l;|T#o%hW4VH%hQv~+#34sE7Q<1JWYTrZRZ1p-m14St-!qUN zOx8HfJUiNtW(zVL+p7lLy&XK#9PS(00-3#h_Z)S`&*f=q&hF=~>PtY+*oiL|g=oeej+Bh;FoO4e{062r3Ex+}s^AZuy{kMig z+<#nAst4a6MspriNYx)$^lPzTpGs>fTgPm6u3p8Gfb*;;L1KhkqX(&WAIQI2$X zeR&))QOkr`3UKV}El7-m{X91rrF#0F#*Yl0<-X}@Nej^yFjyYODh>U!uM$Jk{Glfq z^{Nud8D=!5{#uoT>uUdVC}mkF-KG=eQSblCJ?zLiB$aXTVK!qAcFW?ftetelkMK|Y z>rd8$32bdb4qBIL`R|1qM4JAee&oe*e;DG_bHFFlnmISn!)4FGqI|@liEiIt=sOyS z^1KB@roiwIhiR|xY2aH$b+&jNna)0Yjxs2|@IuA+*)ikd;BetYkL0585+#*#wAVs? zoXRBCCjBT5e=A}+1AXZa#P#XRdXFyn` zHWc!0WF(iw8hyU1X=lsn@5J|A5f6FWO54CVRSv{1TrG$I)=larJzI1vwJeY;>nB5; zNv*L-a^;q=EY?S{n_b76FhVNd>&F`Y(sBr43{-P`gs}h3c6x?3rTwzA2br z1YB2=`IDhMa^_b(cZ78xm@mh8&XRv4(w<@5Gi>ADI0w1J1gq)tgy{LIc~nw|>ZpXl zT1imNMr>QVD7I7TNh*_*(BJWKZilQnyJ3RuCJ06y=EHI5YDdrEC0lhcs<@hV#PEatb7v1`go zY5T94VW-inw6e~Sa$o@+?!3(OZQ8fZLf}~Y%w%?guUZG;0)6wbOgZi)J4o{}e6bP% zM$pT9WE3`1JKSnl@XMMj)z*@;riLhcFa1y}G&mjqd?uO|QA1xJtJ~kC)6%9rw23r3 z)V{BStoK}6?`;><@A@~P3TO3z2>aDGAtA$9CVzaE=kaAeWc*t^WZGPIP`mzLNE2_x zk6JYA*(S3PH)_LwR=o%!E~}oi{3cQ8$edi`QcA-P`JKl z-qU|L7wjm{ldMn5_g%opE(S(IF(Hl<2v>UGlNXVb_WJRXyrNs|T<4m><4th%qt zG`y@4p6J#w4zoGWXj3r%^{Evu_VDW&bNQHcH*GESWM03pan;dA{BFaGE$BWd)e*R* zdE8HKD;JFSVATEJ8+>l;oNK3e*~*K(P8`dRYTpYt8z|*>ftu3hKuvki#a70OrT>e) z`~R9)-3U29ClumF6uzqKe&6-P`}$*kSd5?B`tCMEPJV~eiYVHGZ|jebfN2eEr+#i^ z4fzH#MVbB%SU`|5v7R`+-zy*;A}1>T5Ywr)o4 z7X2BV7eM6FFkr+q2pZsi#<6v^S2F$6!`}h>Ips5 zHIAV{z$%YrHUbkCQK5WSdz+9ZEfBQB1sJ}rBko+m9|vf_28L*>Ku3dBd9S97X~5mA zBtV_!r>{SXJ60N9PYxOKh9os>U0wF>W0uVJ9{j;$ZW8f(G{(RuPT0fRd{0=~9 zNqf*e%G#ABaIm$joL3VXFx%Z zpb7m9q0AjOdydPPRLED#^;HRtG7}m|9ZTT+J@3x0iV#HcuD7eM?%L_%Upzw2s5NY= z3uzKaN^oxrXW32`qw5ljDHdy&i!E5OOQ=Ir?u;eb3w;+xMXx~D+ZmN^t;rF6J4Fj6-WTbsg4{k3V8%#lWlUm!W zgHbBf1n*2SuC20k7BiI`0!)g?SlKbfvtgCaof8rEMM!r!Et&Fid*){59Qn`>n(qD7 zKV!R)e10Iw>E+{w;+jQh$lIrGB$hh$F80g6?&CUwD~FUlT}#2#9jO6K-?2IN+wgFPo&&bZ7ssE|&e=hbE$L$KzkH z7r8D>cFD_CkmxXvE77Di9zJ{iUNam4IT6F7bY-glp2URQO7*VIlSnwK-wof#Y?pNyX;0^r7rh^OL_5dAZz3va zr`D9^kNd)n`mx`h<1(_-YB4dw)P>7hn=(^NSL(<5r0*jq2kT^T3hPmPoA97BHq=T< z`?eiYE-Zf{f?ua^vw$ZmdDyht|H1DPuJ96jtC9;e`xki|^og;z*6_ZxA`LQT&#i8O z)sHx%hTj{3m-;0Tp~T!|?XZeP%vmQPg{D9-?lupHH(G`(Ok=G531bq?nMY69jlRc_ z9FZ?ppd61Z{A^Jt^-?zAcKidc-WMZ5dIED1oY+Xm>q@)_g@?J!En!Jz;{6V@j?$Pq zrg1zz4ZY1df<*_auC)&Wz?5jh*u_9gR z2uuiJ{7ihHGX^XAyJL^BJJk(8c#H7Ss-M*?UD6ClNlpaZ$OFZXKPus(a^OvxE@Cz- zaS}X?<9`rA@D15w#A3USFWWn6(Vx-S z4KX~qD8g&`?y5DS?>AUBmf2JPjv!j>4C@}~Q@dE%l!+Pz1B9K(C=GQqzDI~)vtgxK z((E?Ao>%_pKs}E(>ZRO7HTL}$Jqrbe6A_WEa)w}G;blq5;={R9^50UE{IrTUSxY$M z$7t%q*5&N)ubT16!20tcDCQ@KC+@3Lq*ZWf{K4&U@3dP=iE$v}ev##8EF<%Kgd3UZ zu*0{xdS6K4)CBXqEl3~Lt5aC@iaGR;@h>A$R!p!LsHdu-3pI3d(vP3^Hc;>*N_t@y zLW%j@`k&WL^6-wT-(zLx*gOSU*x5r2zmC-{#5$(1mHq?qgSIpHwMGPqw=l^IrJppb zqrH#382`<2`n6kSB)ysIa+R1cOdJU$q>wzrskwG;qB7AZwS>Szm!hR({P=#eod8Xb z=M5;Ag-9~h1{wxx)U1E+2oKaBC_NcfnDt+#{+9F^83=Lbvknr}#8rUq{0MMgy0SG4 zjtDk3B2N3wKgP`qw&Qj&^0MEyvZgI%=>I2doF~gQfHX3Xe?y!^f;SB{|JVn5h4rYPUTP3^Xhew#3ta6EhyiIh= zSuP!M>wDUje=4N;x%|{`<=&AtLTE4(0ihh1b6N0ugItT*7Jq|9AYU_MAjpN$35JhB zsH`+0yPgSe52YWqGao`ZIkt7j@4Rw81#JDbBlun_*`dV#^aTnxlnNF`r<1tmHRsZ? z9=q0xscz!FA{U$|zlxN}TlFUKY=Yg%opVUczh7>IjU1U}sl2_56P+t>u3W+AOn$5t zWFfQXIk>u$tF}u~ilB~Gyb|;g(4Q{R<>S)OO1Not{pEHC8rvdrZ)k)mYiMMYI(>>1 zFf!C0ogM7T*i7cIJ;5hHOa(q|XtaI@>*SKy|8D&-~Hy2l^Lg~1> z``G-Hx%*oUd0E-vksrLG<>M%0Mc>dZ`A7H(@x6Eh4$}s}fpUZkl4xY(qhpqDYx??7 ztPDu=)-?E>_7s~pUMUknp-p%QiIU_E3T7H(4+{?7W?Va*Ax&nuOUq>i(cW9MRfS~q z^69bM2f5jhjRN&Nc^&c{jpOiuX$Z^guedjnsb-hXU>9$@=dfgo%2STZIf@QT;cQK? z%YJtCkD4(hl~MwAb#)`1$bW>5J^c|C5%HFu(5~yu_U)Rq`f(v;?J$-&!0Y19_8!?5vjIZ81 z@6QOHccA_|uV%bu@7QPX-e3TSV!KU!;j_D3;C*g56dDceXnZj_mAZIPO|LqlXLTR!8_u?U z(yB_uxQRzNeqho&4|5u3Y3S7&Kk_xR@OsU`M3ijbo~AqvRXh$cn5eaW*i!K-k}iF? z5xk_`k6J8O=s3Gy4dvZ&5c9rST~4k~Wq6*K&7y1|cb!%^Z|fL?X0s069@oEk*q61w zu;CoRqRp`=A?;V@ne|Fm;!l0{=Pc*Tx7!>sy`BHV@O<&*^DWj>JgjqjcFAIPa)z5y z?)$PEsEpON2#ewS7DOMVcUcDy|L&X~TKKlk@s+ZjC}4 z<0l=S9^eGZvDrMbJmwP9vmGlbcfeI3K4Jpk2Jrl^V+)GY-O?G4(0Ltw=GA$r#9WRS z+a`*yr`E|;)Jur=F^Ufb-FqwFwMg66{k>S`e4~79S6RI=eSqN6RIxRhg@N6WY}GLE zh1DAid959risj(LPe>_6Cf4UaYt?{W3?A|Ke)e!}16|)^9@Y=|8K0dogGK=J&;V?K zPh--UwYb7IDES_bs3Ne3x*C9rJO zMVN4N05SLQ3|}F)>{zK~*2suKbaWiQbCeHI8V9c1GI6AsOMFFP0G+f{)Et^McaFD5 zLhb16?;Wruv>k=smY9!JS$c!G`3zc7Ft6S`$#|1>9o zLTiHO3-SnrD761@&pE<9(1TB9zk8BVQ*gGD+OOf~ zEVjSNd(m=B+h*#~ae3;+ck{JLlS2!?uJ&l7l`G&P9e1_VUv8*5Hb49;6#I*+>0K&_ z6OBshO4@mezot3JNXm5~y|&Q*OzA1jYy$J`HK-?g60qWUrR#MSvZnr_)fxTSZO8c? zp+$ql1&rCLK_fPN&Onm#`P)gP-zz#gvHPyaPKVf$aFg>xKtS7DVs`#s>87-9xbY9{*!eSWTWA9kfl5%D{ zXX&gE)y+HJ7iaRdv~53)dM`ZLbKp)EUWS~T;&rw_n9+k!QbiCwqEoCR;2yVFnhpN9 z;YV>(jEgbTq}iZ-5LClhz+z)zVqxeV9M>>8h1%}nES47E-Zci+i0tnBP-h5H%SJ<> z0)O};|Gg>97=m2>FMz9a3UL2mIsu;PaQ-LiK53$t+TLX%Em*n z4|kT9iwpUXvs^9QT(E9EfNqAGSXzeN|D{ItN45>|&J-Iuf~LfvObmewo#0w<)|O8) z@4vfVUJE&2{&eTG$bU`W7j&to4~5_OE5skWaw%574ysSH+^$yBZjQz7>|gSs zj=D*|v8UpEE9DjHjOYB5h~OrpB_Wijs;#+ebqhv~xZ|9F+$A&RPQ`x=5?yS{Dz#3D z%g8`Q{_A0zeyW5HAw*0yrWD-hmhZ?+;wHh^@3rjziFBtx#KdpTJxRC0wYQ?7B|CL? z+20uCSHRfYM7EQ^zaP+x^&x0|W=|9(SEApxRw!j2jzGIHpkTRlcF)O;w^fsS@gnE={1h3`W z(Dzh_9Y4oyp;G=CRWK4ai*dqE8a{ShW-g<#Il30LWZuDZ%D6ATA_x^IJ21nDfn9Xa zTyJIBLvoXYZYW&~lT7%XcKS4~HHm9?#mKGtra17@kSMMSpKliX-exw7ag2+fPewv> zE19&qwQ{6w-hAd)sxpka`bcPx8yulv#IzoDOY{Oi6V!jRp7w^Ir{D9+F@pp#h1W9h zoX3}W6JL;tyu^g4r87l^1FoD(69DV=`e~IFbQb!k3L>ZsX!qikAmLq$C?x1dO@jQb z!L?hh6MLDU(xkKe5qv@lG=dO1f0im$`|CyFS^Ex5Xvyf6KkA`qR8#O5lg$CiXK9f- zNSKqNAJ2tvk8#Iowv919SurBMt`y|w+!;XQfr9<%w+RN`Q@G;PnX6ScEJ7p^vP`gz(2t_E}^St z=-BD~UX=9T2AeYuFD|nSMWO$)t$z^l2nisieXFx1pGz`PtD_|=jb`b)54cWofxg6O zcjpKCK>HXIhg&{$HQf&K%6}ds{8utpa(IJTAQb8zmsvZC)H{dCx4h`^srvbGeN1+t zx}d(rc50P}A~RFmr`_t8`J08}s-Q^bU-0zfD$hM%?Kv^8zFbJ;=&)Bp*_^=k`r2e) zv&gOv){~=Bw?P7CYUN^MPx|GL3cXTdvPgvcbQ_c9&&uGxIZVT-JGn zxkK65<%u$%`vu)NkUZAeE^fqSvo)fJ)NHo>TNc7wP-|+YVt2L)Z_S12g%*Qe-e;6Q zvG+m`jfaU?fT*o7NPK5Zg7LvFma)UDmP+>w<=kCF6?^Zb1-VRlo9HL z1YdWvOkT%)oi0OkWz^@A^-v;)iD9qa{ddjc{%&IeUR(H@&+4Qll9RCkXd?Bk?cLvE z^EJXFYTj}qi)=mDL<=bLHbn#b9Pof?aTu-Z&F0(8?FoLyd-)Bv%)X5Xg1 z(d&Y760kBQ50AnuRC6b6uvq)Sj-&8C;xMfcDqyh)mb|YHYIij6zU)bX zr+tU$d+c-j9B(f@C$#N;v-Kd_-f7E67VHm^PhHq%u;jf_8HKMQ40 zS+V-u4NpbCy8nLLKGfTWTcu{X;M@*35#5{v(hAXeMP|XYN|x>7B@$ z9_zNL+Qv2iwkZQ)5a31&P5O!&bq0Lln4|gV z9Hc?li;j`ohwp18-04&}T%<#>M?%3U! zYx`xUBgf0j!%Hl%$!pms3NKE(PP#+N>hV9x5)c(}yC?XODRz=V%Zl+Ca-fnO#-?&~ zsXGJJe`Nwj-q7HAodp2p{mA%*V7L31qhW)O;tleCRSFKVT1=RAH)v5-htxc=kD*ZuMqz0vqnCAl!8JA!KxGn1AtaSG?Qst?2a>15CF~Zj3%^ zEdVDRlrw}OSFAWikgcN?DH^=eS5)v&hgIcQ5atJcT47w3ey%l>iDn8C{3r$FgGmEF zZ^TE;Ggl`?9R`he4v0CfjlMC(01FjWqDd*doZWisPCN);$p0+^z!I}MZt1s(rW->G z!z16l1;<5D?#ZPo))$>^#D~`~jjvRMgl7nOR~#oGkcg2%_$odkv;}c#PMFOI^fAte zopiNcR0LmWP*z07QU?(?#~G_2if_${sX+&WYj-TuFQ%TgWD~GK(JhCM%xKu>&w*hj zfR6BtBVy1VW)UZJ2-@5SOS!1zhA=cbp=G0IeQ^<)2~9b}xL0}$si-(|750o{SA$I6 z#EJXr=4Vt9Izv-X0iGBaVNd$SA|~t%GBQ^6+JXzR82ksST>wQMmO5L1F_{+I#&gn~E%N<0Qgy}j z(qC{ozvxz0RmFc|DJ$5%{#}cjE2LOL7Xp$O(eP`2XRs)J{9BHx`E+Hx2nrP4#;IP2 z>eagX`-!Kzw z0AYyl{*Nfx50ks_-_Yw8kiHAMdfE7M5D2}y;hPRxO!g_l!FJ0z2_12NhrtpXQxTq3 zS?~O}g-Kc)O1!vq)l#)k`M4Zon^l@H{kc3En6%I+QV1zWO^nHT8*hWW`_3(ui{-oIFQlIcA#^+?E$Q-{xd|1Zx6;g|G+Zlc4}=|_;Abn={Qe@=I}$OgVbcyU2dm61DfyicilC!s@jpZJg=Cv7Fl}9MRUQ1wA(NT|FuXUiY33KWrvso%rTBx z=Wu^YdH_4#Svro8`5fz1Qye3&jq@|AKlZ?`JqDG*Aie!O_r115O?%~IJ2H~AeZo{9 zUV4nEnT7F8b7kLM9@y}*Yg{&u>1P#7KZ^)5}--qe%ZhPlPf&Hc^W3Sp%a zLi!rmIedu#@)7Qg$NHT&8!_z!Lagx34|!9W{=gV4E++q&_9oY#QxL2K*S z<4O)o>|tmhR6!tVSJ_zNz2qGbaZzFX#fr zl2BUn5{r>ngwZh7?$t~;Dtv3F6V1jo`<;Hn#97xd_-8)(oJl!bw$xtaHFwp1b5E1x z_NyN*6-FI=WqN5Ci5EtiGs_*4!Ac!7Cq!Qj^$Oh^AY~ zJjQwDw=d0!tCfjs2L&vbUPwLvph}AzkHUd*Y~u4YkiOK5XG@P=0AUh3z4ZT{GA+-1GgX`}wD2?jcUDZuv!tsvUO>gN6P3PRq!25RHSs zWsch(f^n|sksaHvDSyp3HX@Z@ZBK~}7Boda(|HFn1Pv&}qQ0|bK%#(`GsQ_IBnQI! z>g2z6>fNeayqY3$w^<*j$=kC&q-W8%E+DywXQ8jU0TWN#zB)AZR#ILX2}tVdjBkV{ z#Qzz}_s_a08*Me}U={(V2cX~1C z(9-o}i_)z2hBGx}1J66#E#Ou*D|;8bN8GTQv_qYH=Nm3}0u({j$#0j@S`thy=Xarl z9Nh?}soqp&>tCi-C{%dOlu&oGeD09zZ|j5yS$a*^q>lIZH@z5)`oKqiSP3M8pCq$o zB&$xxU>)FPuVEH@+p6knvAc4J-9CP`xf9o$n8kchwUO1uyu48`R`@ z!Gvo*4>vE~9y71aMezM=lk#MY=7xZ~_Z}1i=b3f4j39UAMqrcS(hOsYaFw0kuLJiP1PNkQ^_NFGxzVSC7X7}zDWgg#M~C9GU3{vUTu(c z1Ue(!O`aQ6I7S{jFX#E^*c*WN;>dM7n5XavyBRdiqid4p)}PJ&&wpic_43(Z%3$#Gc{Ez;X_+m= z((A_ijwt)KcV&2z^_3(Iy}yv=m(=$fh-UNy-cJM@S?}2lc0_qX$MtW%(f9sma5pSO zUTJyl5LOS42m7!*a%A6)Z1X*yy_Qp-h6jB6Fc>kOH&~yI@QIg;Xbyr0jrA@?mi63k z!Y9#QPJs%i_t`Jv9%t(+ZS|G4hh-m55aY>tYRlj{U^s)VB`RRMsX1h_# zg@*f+<6%e1UBemVT<>=2RQ%RAi}nA`;s1M{b~_PRJH^*mT-?G|aM?(-Sq8eC zS~=e$q4*@suZ6mKt*mU|rSLy02kQ@A@jWV^gpmi6s2a-}%l_A){(l_K1w`@C8L3oe z0G+uxrL)Kd@7{>MH+Mhx5&mGK)*^taU**_3oR!NDa6*#87^=W7J3U}OT$SJ_WL$Cq zRpS~bCno9SopFFC#U2lm9AtZWdq>k;;>qWDjl8prDx!rgXUPkA=)Z2?^}*5pIna;( zu4M`vnI;*O7@EG%UE?T~Rgk$`H{lV4^N$~#aAq`JpB*T-=^lBwAt(|J$h6X7+P=x+9kN{H*s7QB z{BAg-ctGzEulOT}RFFEHJO$nm+F5R~cY8Xv#J`79_mwFWB#wT3-a#q`o@E5qamh#> zrl$)0W{r?sMOkpbyhfN4$0?E3)6`v!I;0!L0Z^HnvMh`Xj`&t?xb>RX!s_Q;qe3lm z)DN(XmN!K=hZZaX6u7^~{y~a;{j>dg(u7#A#vT8K?vDr}`Z7g9OqO*KUf%nS89wA` zC=a6BVM`#Ba3lGlc5kmo45eC0js8e(f28jrs)5_!AHsJz$HIsxr4f-RT|z!74ah}! z6h-)n$DWHxmnq2h=u*Cr62>QcIW?gGsQt%I!J!;EN8MhsjX{@>RIl9?C-j^Py+x7@?6$UyitgsDuV&f1 zgq(ZI`$doIlXso2i2~#*Sop%KMhJmXr$q;GQ6L9Iql&*05_yOD8`H5GqR;P2g!M$v zcGX$Or9k^PiwI6O^8b>Xbwsiu zA7X!4g(jsIJToIW}mH_ zJ&crwN@UJCWam6$S}Q|lcx*rWa8jtW%n2{j2YZx5s|D#A0PtXe?6bEAT;5X3*J@b^7uYO+9sESQ4| z&AW(lVN2)LxRE+|OLZ4&>m^r5HDnuOa>XEtPeR*{+KaGXGPI=6;C%!%<}VNUS`b#a z<>wtEH8^VQMChacomWju2dD4L=Cn0-+w*ZX= zhbCwUPH<@4J!o*!xVt+9x8UyX1b24}5F~hj(70Qpm;apFRr~IJAMWdV?W(T1=9=Fa zf&*`~b=$3A{cShz#HaAKOd(Y4dospPd`XXZ!6u{HtA9HrB*KT+|6E*adt=-fjMe~= zv{ICcA@dlbkrn-B(XP0@rA}2Le9z_EiPVwN*%=ID%(#^%0f@=ixw5F7a^z>x>^|$X zq1)ck*8HC+DByZBZqj`h&7T)3Rgj&VBCSMK2GqqE!nJG2qp_iLa)WUHB%^nmNJUKt zcsK8!0H`PL=7hOrI#o=Ux^seh)9&7wy>Wv{)$G#cD@>lXq1glv0;n6Y1U{tXlb#iD z^8C)vctuQBpHo|h53s4um3iGXB=+Et4G8&Gai+b3_`ZJe!ZVfApoG|mSrfb07-z&+ zXRHZhO}f_jABaDHBi4|y*-Nns&dLkE=(@qKZ;3s@#D_bosw^po1o2hXHz!+Jca%$J z$wX%I++BY8S1)Bpme8P2pEh7U7>#qZ%)!cMzVyxRv?yXd`E#2<%*v9}N~a6BTAaH= z6#NhVDR|RE^5sBWj-(*g_BRI@<=!xNv2>W)>~JtcH3)As5Ey*FNNd;5fJm~@ER#IS zh~DK(QMDCJQ?Z+DcaqZBwbxLJkR^f@~ zdQRb*nLptBPSlrtLVtC{T%m}?>fd_(;Wb~9MU?R4rz-mkUFUsq1R5wV{dH}B{?5JL zhr)~fU^KmSg}jVTcJ6ey5tW^y?3xh=j@JmJJ%0!X<5u;^4Z(KjqJ(FXb^E=&nNxTX5%K@`SM|7iC&u7(ouXDoS@U zTl9Bv4>e@gZY1BA@`Btk!2hGTU5Q^+y88anKEbyc$nn^jOWL3owl}i=h~M;9&n*$3 zBkd+c=r18Z_sXcb*(Z0Eev87wp--@NHS66o{^!MiR2;$9G>8=@sXP>*{$Lgw5`hhU zY$b6&wd}Y(C(4H48Pz-!rV+BJTuRT~zbdm=2K`UY^B0*AMZ!A+UVn^B?=^%vv+AXi z`3N<7;ya9#q+ow!q6~XjL~8s^H%ZaZsjw8 zJrGDeRE7?Vldrked(@{JvMb(iI6Uz-FMgX&>fKv=k1h5=xnuF1io=8@$Vmje|s=}cgc|I#&63_Vg9R_khvmHljrPcnEADQ8F z;mZlEMm9@cry@l$2T@FzH85;A$}hvD(^HuM8`D@YwvgoTiINeT)dNtShYhfw zlDOrd5LAf~>FxY`&I{o{)2rdL5%1olZRa)A)yp&)l5%3P=B}O*4mWptCBtU;Wtd}g z`s3X`{{%|>vQorpjoM4C;e*P<`Rg5Vt)J%V%@VnS@ZJ3D=XH@D-=9Gwg8ze9sn0`SO=iY4fpb(;HS7(hvmP=k=V>-N0o`!4`gU zcysx5%##B}bL|9N_JOFc%R^2`pA)X6j6R4OdS{jBs3XOf3G~gv zA6`qdC=Ug}1OMV}J~EEh%QC{|1`K6bJulWp@jVK7<)=YWda}r8l7F5?Z**`Zs z7~Xp8u)>+3KQvR-wWgA>ycC4yMtVtuT%vLazs*!n6I*}Cn#Wg5{F|-n_nX3f&7V>4 zZBP*Pf@9hWFzTIvTA{p(kw^aAA-nbT1?p6>9y^+g(VmpJyi69BMds@az&(mTGKDQ4iTzZh<+keszz{shtoqF4s}_*n3A7L5q>yV zlxsKis8+guXAdyWA4-!g3sR3!_>ciJCgj+qI!^QfzR(!xmYt(%|E7q*lAn;zhi~p9 zQb{&KGi{U=8F%ubxx}QRPs>1#{=Po#wrs3Vj*5#VB8#pDTtdS$Nd7F)65upO*1Ulj zfq41Zv{^Oor@l21^Asw3Z9bigof+*Z+b&%zkYNV*62&L%x#!aEaHyx#-k74v1IkdR zv?v2pscgo1@;aCr_{fOKYUc)I%C{K5_I3`OS$HhizS~2w2Bv+p}6$9d@ZuV3o;ue|5hF*S~r`UJF z-;m4WN=qwY3wu-tK&UkZrmk*b_~Q(u@&9;K%vL@uHBr$lQX#p5QlwlU>VQ1YnU|y| zy1WdqX%#P)J5fV(xuu^;mG%n@6Yoej)Gi(m3i@YJdBQ%E?e*kx-C?qZbgc3N1zkmt zw0m&6+BS`Hsg+CT>vQPmIK|Z;iL^$x;%Tbi9V@t^gn-FuQU4H4l7+X?zChyG|8-K$ zx}y}ROS+GiGh@8BHlpm5c7nFoc!?->DQfG6OwNBwo5SN%e=vo$QN?e8uRZ+sy(y~<|od$=_ASN z^QktcKjDsNl%R?J3O};roR_*%g{&Ne>|Lu=P>4y^B4QiK4Gn>8Kcp`s1M%0W??#oxBbJ|{w9oSq zmq{TBFm(=NL(Q^GL;-$U8OCS?f^;_!r$#t)0xj6dhJ&!qt~dN#Lzx3Jj8itEGs50# zHvw+2kJ+a=NO_4TVvNFB*zZiV2L0!|Tv|EIuNba8MEWjj1cukdSM*D%d?>}!2VVRg zKFFJmb02m~kR2%-8Lx0y$K)USZ;&+Wz{EwePWxnv)!VO@v5kE8D2Bv%)4B*wxrj8~ zqB(TK4V3QTVA; zCR`93hr#k$)?pfXLgosPFU#9yW$g((UaB$Z6Lv8e5iPu@eAu z5mioYDKAyux6Av?=2qNm%t=*Tv1L&W3eqWTN9iHMhV^uVufGOc7}(3DHuPK*UaSX5 zC}f_i+^?W;xmXxV!s|HmpKyby?Fyy%(8f?Y9&chAyVsQ)@UG#kTe)E_@S9vlM_k(T z>K4js3(7lk!U^_=_hs^rsBuIM?>L8}nv+<4T#Ap~Y{LSN{^hCD7jloH*B z4=4VRo^s6X62VUxlu4ce6_h1=)2ZXwj#VM7*x!FE*)uc?R z;PTa7lDN(88Im);3wA<1*$jyGe6A;LEj4B-)w6Yp(%vpC9MdO==p}1;Ms7Gl*;#6c zAzalEY|TG&JiPgf*3q%r$$y{)zMs7=7k*Gyy={P9T&Av*j0apfS2azXSPGs062}%g zxaaX1;Blb*d0ynJ^?1p=dC9E2($zvHYull*Gh0* zA2fIQU35bGds3*|?9WQ93dcjv-sF-AzSM0_XSeN3T`aH%omF+2cFAp3P{b311Qb{sLKM|Sl0(}vK_IOOzdt!p(IioYpTdau{nQQP^F z4mwF`Irg;+OgP}ZL5Q*pefg%QI?~=y4R`_Ud+GrTa*;GK zY%sQH9yP@JD%cd#zI0EY`4~rC0w&PBn)UkPQg+-$1KxPWorus8uoc1NkJZdg&Q^#z z8$H_br<$vE4qEQ}_KUsL(wWyG`gtXLfq?9wQ*O{}*^1hA7$eG~)g#;jS}f8is`0N ziZ?=@2a3lLQQp_1d6}<81gZ;-aJp9TNwBrBEh^)Bw6ve%e2n}nWh$!u_RU;+uOZ%r zlr^^lYR4F>^!L9!&L0>-gDPuLX}vu6r4$u(0g~)GO#&K!Y*jN zm_#;%#3KBBOT;Q@q*?&iHmv>VGHkaV%=98YYpjKl^h$<{xE*Th8&GR z+Pgosi!=K64Y99lxSy9sLbUQmzi(i9OZz8N>}pBJncr9bMoJ`{Z`aFz<_|zceR!qQ zMf2v(@yl= zGYWQz@8bs|OJ$^Q8ydE-_co$Bhk`Z%Byk9x#mlzNu36~|?G85<#7VjAr72L?X9x@OOM*>0d7 zV}u$(e7O0;qV>uAV#r}!Itct5x%aXJ0c}+L;cxHD^KO+U5RIj}3L_CfT(ea>b$w1vKUYYv z6l!}h;N?Y&Bip>RaP&S@Da(+z1$iwEA6B}in~R0LW0W!x$kux7{W>CsxeH< zEySkMV2k06ovKtN=UX{5qgeH*UgZvn-AEW`OBY$sl9VMdR8}!Sk^ShL)MkSB!6~f1 zj!UTTqRNRumLsDm>8aXY4_;yV;^G}cYRI^Wa#eih*u405X$!UE`vgNE z5*?91gXNF31!Y{GrLqP&{psLXh;yLhw;CdPo>CCbc1@~ z+5cK_NPn(##0c8phC$F4vWa)1fBMLR*;s`5P!)a)+lc=vI-@pNW|bA$F0n@P-Fjc7 zi44u-!Q{jFiRRqP!ipBrFgPlB!IZD#ninNc2>S7jzHOMSA$Y}l@{^CGDFEO=FT zG3>Lvft!uMi)ISQjWbl^{bwv%ZhU~nM21sml>vHz`0^0nG-eF}jYktX#=X?)lsK5p z$k&?o__JSDAr_fX7S_ew=IXA@Lb#@u)_J+aXBo{!alh0_kEh$rc|`2@D#=4!Vc<)T zUnsz5;1wd=)SLj?$yALvMdS({uV5FmrIoExriNp4PNb0g0N94)9Glo6;GcU`Vi`P03D5!4cv`uh@TV3AA5%ZN)7XqsWoxoGQUWy6ffQ z=ViEDW1CROqgpg)u+!IOf^^yH_&3d&xk#rN9KXCT_^)Fy*<&l@2nc0=5L%?P65_BU z>8cvvt7m!U?F~h)7ixz4VMD+{dZoFrOgGiO5fhd$8s2XP(Mib55{hud-Ph~N?C9#% z#pcWc-L`p_vHwBs@3PLly_M2w2mGZZ5RgsWDKk@g$20e&&UsRJ-}XM_s(8NM zt}_0vEb?XX%Ocyo%4LViG<%KpuSG0dyN*R8cKlr(62cJaomnZ;hFINGxMAI@#}mj? zL1cjh7nBuQWAbYSo7}gW0ttrnDGh>Bm3Pn5eE7Jwi*duT7e$0S>pL|q4vxHwM`aUP zOaInAKKnbk4HAU0+7G8c`@qB^D|XbNQQ?vsLS|18gN)S{;8oC3I@ohkJ8_Vncnk&8 z!@$w-t9n7PH;>NNeiWgk)678Yux9SP3RGW=!k~ESc)KG6vLn#qsXkZsjHq{97h6EF zioX=6wEmc~+TlL4AWT}*?Q*bDt<5tG#BEtyHoCRi3}yj8q~A49LNLOR(4%!Y z7+Y{qoKaJor>aPP4Npb3H5LJ!(itQl)dCy-Oa5lu>(0(8&Z$KUKSM~qR! zdSz;kjkd1jb^R-U$QmcCgKvGe5QI~^FGzdX*L{wvMVJ4W+U^H)(V*F7=_~Unlf{ww z!|o8Pil_WH&X#=B09O6<%3vvhii2PI2+OuLZl{i9%YUO44sQY}VwJ9BpMUic;q7HP z9%q?tRv!HTA0eb>A=%;SF>?F|Tv! z1JmNDN9=t=wLqPo-@K2brVGOYr>)do2a5J`_I_8H^Q0T+p{;KN@a?5#l(QYbr?AcB zSaP8>zr)R^!v?GMh>_H}SJ>-|=mX_zN6%CS)2l&0%;U@~Hi~a0gm>lk^#ANbu8w-T zURc0{VAh8rJ4Wzh_no)TNB{rVRQo?sTM$Zd&a?7Q^S|cX|090?uRK17U?_>L*XhAx zb#=D=;;6?)Y@y(20w51Cc@XN2>4v2*SzIYU!kJ8#26!U?k$-)0NHs-k+?59yAq{CD zru;MvV5KbZ5goJZ#*o3&ZtryBXJ*kGDSlef20*gnkm}`92wwmXiQ(&Lzr*Dez4I*`50G<)Z$%izKy^fA z>k6})0QTB4l>fcFY0`Lr(*VWi!Gm-YffVp2aTO#*g2|c=SlmZ^`11R?j36=g{%+n( z55W19Ja7*yV7(*;#6rSwfy$;uAl2BpRYTtUPouk%jTQ)gOmh?4uW<1Deh0EpoyOY5 z$-rYBKv)Ck-Zbq3`=D=P^avw+jJoRG%CGpu$P5YBd>c}td76^ta8AQ?Ml<9h#f+xM z>mS~)vmb^P*sqzc$v$7^cBl4|h)jbJNfI4#15_7^)i=*cZaJ``5uR%@G9-`}`01z+ zD)y-X&Ek(t@|W5FDmT~!1PJTrH9tnS!w-(Z;CFa5|6}w8bx1stOOub%=;{gp8a^tEp+I`V z%fk(KLLV}hX&q*M86i6K*p} zFtEhjH?0vl*F%UHndbw>e9^E{x2V4=es4e%Sq>@><|Sw@r{g6!`2nK7kTjKxU|nS- z7JI1@?VOzv-6|*`;`vRylf!ST(;V16z;_w}!TJDJ(~Gv3O^~!x(U+3!98nVNPYcmT z$EjW}=-i(8cSnEAZ^oSdj_jF2dYQ+>2JuJSJsP}Fa*X&~@~CC>=Y6%+((y`&et$)m z5ctpF>mcjPiOAFX^6-{<-HEVIxFfQ0P@A}^ECI>Q09Jhu<{uwi0UBZrV)v#MCW*#~ z*|Z?uNJ^xMu+7HACB&r>!2-s_HpXGPL48!oJ+fy_S~_#$u!gG!EcA6s$5sr{U);R6 zBwXtGpdf*6*_CTyM?LA7#Hp85pN;PpYLMd<)&&wd;V|gv<1m>siepAZuR-ofRrIKJ zivLryt|bq;#9+xS-nns@W9{<}FiQ{nH|_eDJ}fs^GSj9-2 zK>xsxc>9d<6|#HpkYskFwKA=(3vS6$YEnkBR1_N^8>IEc-=WA99P!-b8yl0Ml^Mel zoebnf{0>q6@j`2c8^LFGJC5IsEa7{pqL7D$11hP;wNA&so~u6$uM z(e@0hGh~^e3T%D6DHdALClV7)=(&D)(5LwRX5^E`>E)w*FG3n>LZXTy*@W#Uq|pxz zVfNoT6QHdn;=)|hJP?+ZW$h1#p_Z9#UWsdrvxUR13!u0}p1O5wbx_okY;JP|dq!6K zvfyXd`Pv1>BFSyVp>hzqXSZl&MGm(HF1WE`@-}}`Cm{}9oYh79ZkKF2QMKZqQi+~n%ER7t zTB^d1wCrne-|SY_Rj0;0`VG+0I0QDUziglWp41x*d#~MH1d5KUci8%s4?45U2OZzf zSxRG(g~Yd$>`-r~W}UV=2+HU=DgK*`Y`Gw~!mtioY#bEn+!Bl(VyqhyC)*cr*YZW} zy|k*x(U*Ip*GG!Jv)Nt>a8aWZ$M-*igG2}hv>Q$kN-aewQi_PW|I(6RQ~boOaZy4V zPwcKOZ*L&iVGW&|c1Y~xBHvkeO=8S)#wgQ}2YweZ_m^jI$D)XzQ1@tbK;uq!gc>c; z?TSyP2L*7#;gkj`29vbq+zkI_a;6*)uAr9Z$jMn&e7t2XIv}|^I@QtPe!qh1bFOuK+A!)>hmIYGznKPi zN@07{e-ptMhigygkk&_WgFwRcaVOMD_xOVuRXPRFPn{*4v9{QXW z%t^AVK6bPSAs4cDS+3Jo8|bO0z9q=L?IgXsV69DmB2LkHH*#xt>K?6Kqw6z6xl<}H zRy!6ZO>dl;xhZJSsg*uZ>w49Ph61|T^ccX*$2wixdzv?87U02z%Y8b2o`J-H$DffQ zhy_RQXs-SfSe1DU{Hb?>UfkB-j{Kwi)^Es;NW!1uz_&6FbK=->sWnfnV}p(GP)2~qG0uSXuE>o4LZxB$sn^h_pg{|pjz1*}3r&shV6UU6v!n7c z9?MAeV;7M}EaTDlyCe|_2{hT8lk3(%{GC9utQOJJA3#g}gvS(+A_drk!Df+#aynnk zsk>JFCi!BB==`scQu5xaydYce5Gjs1t(=50Ri&c;WOOufv1i{vcmQmsy*?* zNk`-i?1Aw5pq>+Y=NL$*rt5n8S)z|a_}zlnrsFkf&sF;M5Q>tN(9GV*>-pV_(gXeL zJ^3uke}eHG*XFJ5=6m!+e~nDqy_5CRjuK-*xH|tI)ORbi_429q``PB>y1o1o`FgJ3zW;N}Akoo)d22SfCE;c2_3Glf z=Imkhsk^_aNsZC@km2>=*(!J4y$N#qsn*}`N$dW}%5MqkeP{RwWvHIF{7LnHrrz@` z?>rhrFqDNEgXw=xssG!J<9`pyz4P88VtGb)@DxP;>L{k#Pmb&EaQ1LSQ}@lPfiUc2 zmmVi5MPVl`j5N0#e}Kch<+n_+3lwqYHlMThwL%X(SUAk4!lp9@X#yx4&$Rj0*4o!X(x@f9dZG6GOKuXoz`) z6%<*Oe7B{U-EbWk@tlvtDQI7?1DJC;1LpXp5qr+*myG2BuZ=RosNB)cfTh@Ql|R^R zCvDudqV;fj4#1D$C@hGLNocwis>^XJpkFx4j=&%4g{Z%w9CmI$yXDHA|rdA1+zmSPgDvKYeK0y!F4;x-~hOluQx9L zjS!Kyw+8+ws@^OUX&nUz1^8y|AYHAYM39)MCo64x2hsZVf;IU47;*>6W$#0YD+kb6 zPW(hXk|LU;Ot}1&9Q}Z3v<+)rbU)HcmJutw#xh#`dj>F_rwE)+$;_5yRVkAoPp;!A z%lKkZC}JC-46m=zy_ybKi^bFz8BLDd(na(2fi8r0=8fwi|Av=CF=DP$>8-zo**)XV z9D74#w}W4rglR~LAweo9d}yN0P4bkkASB+)wac_bH9$IMu8cNu!Ktz5B1B;YIq-&2 zP1dgY2=OQSLo#mzR^Ui?3|WFa=3K~*T(2|b5QZ;nyrHf}N`m00Had~oTO4rmu4r;O z3R^~rRF~X3YXWV!L^mEDu9wFWGF>3TS-H9SCSb4gVEV91ZKwknx z(cYz?4kQD4M0R9mb6;DbfbCdQw7iNOUMZi{W2Qc~KuBX`+57gw_8X_jUdXG^GU5>zD zc0YS>DE(NK>z|V_0!KIklQMa+*=(2ZNrNKJT35QQ`Z-5*JNuxWYPx=m%$tr;BxtR% zt^BJcx~Pt~tA?hBiAu^fy!`HkJlNu0Q_Pd{`Ypm^G!hi&%9%1=7^{Rsr>HA|{@itt zW+12-y|=DPHlWL}7gW!*W81&+0fVxDW)e$U04Ec~@+f+$p*~Ywp4L ziT5Abf#AG@&32sFiNXS#B1S_3dM6^OPy2A3vvo zsb6?mw~25Sus_sdqo|m^D{riuS_66Nz$+63W%*K|+XJ~VxRggscR8Tg1}Vlb8aOj# zmauC^XFL~m=B_$%Jd(~=aSVW zEBdjt$(GEylussa<~89!;C-ItPPpDx#=n7{j7ROGjWWJ06JiCEKWTpc++Ct zW?W;2u#IQ|d-(Ru3>!7F2Eur`F5?YauxY;V&kl;Su=O>yVROf;7kns#%@M79K+$Ot zCQC#Z&j~29?`(fz*rSJr5^bt-8k86c8p12mc^Jck)%(6&b`{-eixagh)65ou{>l7y z)K_Pi@C?1-mDbn^B)b3NB@v5jCI-%h;1Si_h_2lBlla6*Z1zip)&Z6y?|a63AlmomgA;xV(Q1#3+<`n$EJ?u2FO=z$Q%^ijqJAh7o}>XOFZr+ zi`m6vO$5)*0YTYeW5l@n8pgUqsig6UM`d5|I0u7wR*34cX=_7u8rmWiald72+d9nT zjhCjE1d@On%GS4ti69%n_!DVqG#mOo_aeX7Hcifnx{iZio$zJM(1=yvB{9k9Um)sZY zAwj9^jS>9A%#Ba)K7Fm`8jr}J&Xn-qm8nyRnyhEv6{;vyoPNahhe(xzDb2nVPgb~Y zpMe0|nXRR!?-tTXY0NP7jm`_gJ5@tncct!sq}^7YY|->QavnMg=R%?&1{(ND?q|;j z=_y?8AFv2=qmEoO8f6WCdcNS%ew*M_K}~A)j&S{PbRg z#N+lU&q$*oSIM4orE+;(BlixNtFxhqolR{yv1CGW1|Ut#TIVur%oflfX(?h={kHE6 z$=wj+wNgE@lm6O2k7?JzqQH}_qHD-<(Zd$30V>v|M(fcZ>kOji#6Af7xNTr6BzwZS z2I*j3^c$@3{LS~}=5p1(jn;Q}fD&u&1up#l%}Zhp@sGxt=6X*Oj~quX)E}&BrXpY< z&zUIg+%Z5hjOR#z{Uh(~K2F#NXev^(T5OonXq)9@^+?{av+ED_eC8c%<57F%$2ORy zAke$1w&sxa-Sg5tX%htwqJXbOlC_uqaqbqlF5(>lF|yC@m`|16yN*o{0>e(<@bye5 z;E;quYxl928l1g7UynFM5%US-wIlxFt~icZr5yf53IR{Xli;#8dq=~nWD1Y1sNYw>>=)c6Up$Cj1JPjd%YqLNVG@`gO>Q`g&e`1;hnN5J8$9UR85l+Jr zyL{1E>%LK}RSv^CmVez}7Y;l;UgWgfhDBK)K>ZJ}=kH#+cz&{&cT+93^S$c9{=5+} zgcm%On|eB5YWIYn58a9>qrewk_s5u6`^Q`W-v#^3hxR;)V^xn~m+pPZ z#-sZxy-J_1|BD3>z+I){4Y)u;4S=K&{f_6noeSddz@_C*BzUuks{p_b;^5V6Q6jl7aaBx@zO*bT`AYy`lVnUReVQ-RQfo`X;k zKm;a)KP%>HkC@ZM67c~(11TBf^12B@R*iuwUxnR9RJQA)BFu# z0m5p+4d^)GmiwmvyM)dt0PrpDidR&n+en{J6h0Jb&_G8AZrO+B&BV^GALL*}jQgHR zWjokt2Q=q$l+?xb#eXfJ2flTKcaJPW)_3eHvrWEzDDZmMN@j9}!VnwOa6wlu{xf9R z>p7fMN_QF$ry-UrfA@pe4PHI8)qM>;lDh;c17$zGdtM1L?@UWfT&p4T4L8_HFIuTC z*W(5btMd1sBeU<~XsX2BHJ5l>5Svbs=v)DB?rdI9j&+Znm}SO4_;U-$v^n;=lQuyAa#S*I{as&LNc+6T`sD@Xao_>DZ9{mcE0cY?|RM9jD%!TG%i<&_$KN< zrqf)i+{am<4pFYA2$>2CERwMjJaev0a~ikF^_0n!=$Izf^Pc)Ni`vBVcmoc^lcSq) zopu51qwF*JehUWI#gJ)V+(5?Ni(_jjD=Kbd{>HDnY4WnkUlg+6kTXXRa|KY+JF*~$ znCkSad&J4PX{7r*%h%@DIIhO2>^fo5vr;#<-*7c#$7jv$a5ZTSkm_SAZgBR7-Dl?S zrVFPje=U3?lQ$#Hi(L*iDU2+;s@QQ#(6h9Qy5A~2G)U0a@Z=;swh@1T*nYT>pwv+X zvK-hy&yK_~ewE8w4Q!>}_a_^YT&3fiuRp$@4HJhS@7yTC65_^U?}IVh>R&jP-9)omNjrO7o2RZ!*$L2NYzhNuI2IuaJ${mjkiRQx_E(>KF1JQGR0sZhA9+ zliEY?9Zz(p=!z8Fyx?8Mn&u56adquN|KUB_4nB8wvjIBcM8ga61w_~^BxTL|S}cNY z(PjB9YdA_27z@5^acbNj3>M|ML@RsZcoPE{7Uyb*k5uEgi#C7xL!dzrYfUH>l;F{pA zhV8X8It6I`qRj3!8}E zLl?dF-*86QJ=4R04?g-xW8XdJojL?O1zX^Y%pdM7B23dF7Ekb@rINMaK8@f|80B`L zgAR@POg`I_=Sa7X+$T$9%xsY?QYFyRrfX%-co+>~J>z^G60`sha+3>OOOi4z75K(j zMe0Ymz(un%tS6O4orH%%l4+SRZ8W zcHyA$eE5%8OGu3%9JEq9XEr%7|kKo%ikWS0@)456yB^XFbaLWQvf}RSoSmHy7Ip2{ zJB~7h1^fwC>4jlqMUnY;+{#USeugiXsijNZw@n8z_CAn!l-H-3*Qau&*H34xd&#Ar zM%Qi?n!k0us4oc`zAzuI_W1ihT$c)GzZ}oJFqISCul78z9>^O$d~v*=*r3JgKGdj1 zUl>k(+Z`CXJy{!%R2sY#T%Y-!O3%B$7W${K6i_@Xv@}4q=23*7+OD02pL@;)Xel`) zOGvspu|I(gPo8yRt!LD-wT}HOoCQzK)`!}>PZ)0XJ$)VZFAVfv)u9Bgt!`I(E!)mj z(424nj;B|izQ$2!-aIEO9R$tzkJt^1t^ZPVwcRI+|Km7BeLWHCdD8p8WoqeFFA~N3 z%Rp=&(Bgqs4pe8W>&*8oxntt&|F)+0q(^Z6?*AX)xc^?N{vVRue?2(Yxa|FY1!Y-E zdKF=@h!M`a!o3%I$n?*`GYXvj15b!RFnl-RZy(pw0Tu4XPoH3^4w=$F1K-Ts*RxUy3ZA58^_I}6%E4+vcfnrx_s%lPMf z|Kp7q@-OiUsgN+`Cl49H8*A0iGG?aa5&UZ8^>l#;OwqA)-1JM*0a=KK;yiKlv5)Zu z#K1Yp{wyo8j6^8gSccPXMdMPGZ(}Lvh%AKL{`CQGtO4Gx!nn8)dMnpX7Go zVt@!SG<#nH@GG93=F=}6xRf)7SpYz{Cq#$b4psRV9f6;XvgQ?h(TCRb(@J=F^$6)E zxH0^#C^(VINzHpa0P~2(zDl|r@LL%lTn?F-O__=k%4MdJVqYBm1mdSygyB;$mg^OE zpMH9qLI(hBSj6V<#H{(ontiSdoN>nj+}R!xLSxzU2gX98hs1|Z%Nu2}-{U&gb*$W1 z;R1#%`OM&WG%r%~JL+Q;aWeqe@_9d&sc}ls0=}@Gh;WyQc4t_MrE?5E?EruFf~0>q`2aD(a+J1 z6oAhDiFsO;LV~|0`I??sMx_Rz=G!6uj+8nvo|ul#yznWCPzyk3FDjF0@)`MK?Uegi zs5MR^rVO3yb~pU&&tR`#i<;PZ9CBhis|<_zqj)*ASfkRo)|DDha0lYW{hVbXRU&?g z?>zo)(>}yC)DLkJa}JltNhNd)6Ia5MVUzKPkH3qpsGU_FXjELKF*+>OC!&D>*VHS= zZ}^?wDPj10OKi0=MB8%X6mC_XBNrN!Bm)^BzTgUyQJa;iY4lgQ1$lxVH5N%7rUITo z7KT5|y16&4I&=f}knZ@Ab>cfM{NrZyZEEnS^R>;%_aZ>#fHZ@!&to_6-AF1J$J~^% z=YK3K86;t`JmbmuWh7}gHMJ|s=~*;C$}m0IKJDa#;2qAc%NycdECf!f<2y@ApmTi# zOT{plBTh+QX;9wWN{mj!Uwgjz{>>F_dSf@`kQL zu@r#yXhCBO$`}pzbVR*5q32%$-AUTr4;)_sc^ExjI*#qn=0d;m|7{bu$6Uy~x|EKH zFT4fc@FYC;Xxw*vN}vu~j+$CmYY~zRxZ@PG${?sWV6Z%qNM+XC)|8LjKrrPnUdL)&n8SxsBhqbKQrxnTpQQHu zWV=7%t|XA_@2DPGQ2ze86#$dX?5J_7cEbv6nSQn*6OGV0pJBn&`=j$IO)#>wOEEDo zD=f^{p9)+lv@!>Hhp}!Xe1+H37${(Es5u%gtu~j5ldg- zm7iEcC=M9Ix?bZ%_H7NHww+9E9mWe+x{crW-!2K^=}EX5?E79kZtAHJ4Z>Xo|5T;ub>{xHH4ike{NfA z<|t4JN=H{zWEuC`p>q^tu4xLnt3}ylop|73<4rO>LOtWkaCNN3h%j>RT93TOMJZOXca(pTLCHi1u?Y`gXWv{Q)=AfZtPS1w4HxH@9^>W*G|OD+X|q@MK25ihE*Mdf_Ep&bA;M-WYA3HqB%w&?g4uhAG{J+WJ(*nsCv zy-(Ie6dj?h89(fNP0Yb2x1)Mx%W8gXiT(!R@5Zmak(#~{jwqhZ6Asa!h&u_pf|rt# zmI2t^>8oeagx>0OJmbE?Zg$WocN5D;Xa^CAf%f0`6lF0qIOrExsTPuaWxwt3+SxiJ zR7q}0%)AmgP8x6LzV2pT~|zh+D#aqi?QXB|KWZ;k52bq-`VF{5u#$30JGkx}oWR0$FA>7rwo4R9uJub$=z`0v|mF z_G_MeG+vVy#!<_|mwMMTX`?4*jiVz zLub{oH}v@ARpvbAP20|MS2%20x@QfsZqv(eQCwq_xc--(LMfj(!wT9DKxf`=aUU?j zST75!(a8*;A_5V!EnH{#Bh1Pc35j>|N?c94{|b82q5C;mtU^62bKb@_bYFpGWTTu2 zD-1G?m+7v6Q~m4W-PzG05(l-<>m3bRZqC* zv&brN(dC?O@{Wq=IzjmKxYT$15YVuM=Yv#~>I%jMwg>c(9|Q{$>-? z=3(*J5JgZ2{}5)3*Y2Iv=yOW1vnr?|V1>qJ#qd+PNn)B(|Cs}}#cO6c6CrCU1~8zRo_<9fZG zRFWUrD>ZcUUj(rE$?yM^NVdPfLOPH4D;#7*w$yZ0&i_M0Y}pqf1Zc)<|HtzDU$goD zt9}0eJ@884`?bA;70{J4@)8VscRQzhzwCT~Y4@{o{X-hI>#%T$esTU;QT?S9@!=-w zLYN(j`PlV6i|GMBI?WVbQ`3SG{Ij4B8_EG2kYxn=AP7`9r3xnn(jtj?NV@8)LPaS~ z$~ZVXwL7&hCEg#>?)xUG-?xw_G}kvopS=Ppbh#C z59y9otK|XN&;IlY1<-!(H;3D9(4EK{{D?wOi06o>gNp!YxKU0*zB7V9{evhy@${5H zUR4xW8Z7~XQ43xHMKxi}jVuHj%&9Frv9hd=5XpLlqg6Xn))-itJ5(t0mP!#KlX+gX z)dI3nsG|Heh84`eqA!7dvyAqisR3tdN>#Z2L`Av)I=IIBs&WKLcLZnvdu$P#P?q1Hu(s zDO}FbTdhARWrG&JhVbyNmXPi4FG=SO4 zI&sbqI7QWcawIx7wt9dQip|-!0(K$ns4TQ3_RF_uUqc_xic9qA09e>ymw&05e=M>< z)|OEI|F+z9$t3HdtYSfb; z2W-dn#f{htZ|!*eu2NrsI_-ct^p5lJPs`IEhSM%0$PfU*W1P$O9kT-#&x&38!oA7d z*6$Du;VmUT+zW3Pj%aXAT!7;`XIHNK@tTkKmSifmw2ql#M*ABKgVAhNY^^0fjS0UY0lCsm^bsvGj6O;J!wI+J zL;CCdspO7&$lEse)r2DBAl19W$>-Z?iFU(Z=7-^AwQOsmSgFQ!q#c4>3c0LAjTm;Z zR7v;fm!ZZnl!H&tH$BZL4i!G-!djpC^eK{pt+0+GViXL-q#oMb-kf+`pD3^4{ubU0 zzmWHpcw_LOpP`4T^;pl6fEl`P7K*KM`YIK#4bhNtfz)Wre9M+vLP^x>H(uGkZK zjy3n`*#8VhC(V8pLwEkzEz1|>}?2(;c4c3oIh7}oQzd!@&f_N6>axn6WN=m2p6(S>nc%)R88 zgY43f?$vf4%VK6}%E( z?-w*%8Jo)kV+>8PgH0SSG)=$3CtY@?dYpf>{RBhHN zGw>_(Bcas8$jN>Y& z8r$s3FcBAI_)`|c!+SC|By);%Y3mBQkjDNfFyN-fUF9F;@a;0lci`e% zGr8T@q9mj+nH16CIGBZEZwU7x9gG@{b})WZ4dP4WhppMlZ85B#h|McZ7A+b54Nh&QNQ+^ zEd4Sk#MCH~Ez-UD9BdZ`%E`Y}AvA9H=QtnF7iYO#_DePW0N zq2a*)o>IWR>Z`X)UF-BZ7ktI%ZkO9w6-T;Ywr=-6nn-F7Z_^|DKzp8AQ1RK75nc_` zD=6%mE}wu!<@Ud#`V88x^IZo-*>udg3*GbsxQ+-RrgUp36@wn4`Vld>V-zvZHq^WE z>(zR7gyUynW!!{w<;b_{+PC`i6T=K?<^5j zw&*&DidfJGWjCXKwCB@3p~_KTZd5D<@StzizJtRy);cN09`d>d_D=>H%J1YgxRIV{Eqg-#jNMPX9yl$o1~=)Ku}~kw zK&%&l3?+7RS1T;o;f=FDk7HiIFcvsq93zGuQDEEqmEKLkF4w@5a?b&!bsDN;9kEHq z?M6;d{Q+3Oxk5<5>t>oMe^7y+1ibFEdUiCydme(Y;U<_<(rS$}{5Gp1Vf16@LIxrnVmBC203_ZE3I;&7i(vFxccvvIjQcz^COV~*WI;`6XwL~(!*Hog*5GLK<< z@mY6XOc3j$cCUO<{_jNc!?By+CLriy5%tG&;^o+B9ZxM^7-I$UW+%;jiO-*^)YvYFie~11sb7X z8?+9Qva-|=(!Mi(V*r3t*gu<)9%FhD?2R5$lp!?Z6UfYA8`uho!uXBg&@cCP%t?2L z#$FE)#BbZ*a+B;yrjGo;LV~WS)%lrDgbuCM7a&ju`%Awkh%$ol*apgL0c@uvbe;r^ z9JsAR-LjE5A|Ab6n|@qb2^^x#63{1t)11LtRdeBYVD_!iJed$b@yzbBnakWf#RVMI z`O40-1Cm$H5)&xCM_E%INcF|8Q8d-VNjfWYNC=JkH0sQwi_>X9VR~+07}N#8bX)o# zuj4*f5BNsXLRAmMK0A=NE=}TvfuIV4kg1;4)-6Nq?rDuELQLZ6vL~C6ory3i22u`W zM&j2@Fa2$aD@#VC(6Dj%1BO%!z0T13@t^3)mrfjFfO=3biC{d$i;ltXoBTv>J;A3A zFA{uJtDrVLgCf8J^h4#@Kxl(it(7g#eBnFQ5MpxWu|ih|t(BDjnTX?3{i~mWn#3m& z@=djfy3LzFQ#ckm-iuDaL)E{BbEP}RW3vE!wRxzBV0TUOk8L;0$Unb*)kZ8$lUo0# z9`j+8fqc1|4S!jDN}?Sv%$z!_Me{=kH zE1Y;o7V&}}1{b+YXasV|P6$^5-#2=|oL@w3bDg6Y-dLXPb?7dAoSY+n9i4eW(*gk; zmb6%GUY;OwRY!F;W@xHInpFP)`q>sX*dg5*h($y71`xA{`fL6PoJ1)!gmj06>mK1; zceIL%6bzW6D`GCb;>c6r(UlaLW_&e_{JS>>{!}rk*AFz7r?>$<$axn1nZzunYI$65 z3U4F06yzZ#R1+aWerj~cJ$ZGj|Df3aZnjg4y~cAN*9vUX-J}XV=wAEZg668#!@qT( zp2S)c2NR9H2K7+pMOd#BQHZ~wY;kI&VBLtSki-4frI4o`GLjN16}4f(pcGood{U++ z)Q-G<0_02~##h$ZMl}n~j5A-(9%Mx!T0Nq4!&A+&5ga#^|uRwRl-^wM9MU+)wlGk{4hSDua3 z-9*EQ?DnPRcDag`JX<2tT(4nw=W90b&gqch0h_I}4L$_3VhsIhqs>+zgik-%Z$8b0 zzwVE{qWhjHpH$)k6wAO8MYVKn3aISZA-iwPhmh(>Mx+It+DUmJ2Wa{Ndn&_P&r&4l zqA0=s^{Yi#1ACQ9ppq2KK+H*YRb0mGdt^E>qG7BfvAs6!@ay|&yL*+b<iq6xak`)qk9O=t!dMJfDIckAHk3DAh)htyby|s;aLOn#w{x0$`W+ zG76to)U5bfbU_7wr3MbBx?fL#*VxW$!R^oYo{JmQ_GpyuakBLW<(~J;o|U%|kb57< zeK{z@oPTc|aqFCd$aNs{R=%I%!{$On6#e6>{%jZ7yMXVh>}ro_#OhB3vFae6b%kf& zlW-vFNa_mOEz7o6Qi1TWR?G`~sU&(Nevfd5`d&#FahHEZ zr(f{orn>u0%Ct$Kk8f2yw?Z*ErxP=h_Vo9UC0HKu-fwEM*b)>@8JP`30(m^s*Q6}lXfck;+D z{VYeKCW-VXetj@pMNvCaU@y^c(yTz^lZRvpHI7Ajbc!?q(#OXQyIneM8W#9%g3Nq| zS`6iaV04Kk66vqo(EH0ci$-c%{P1-u;molp5${8_ZD6Fy8YrRJvuO4^MjM@>T_oo!^t>!Q*)r&-;X z73SZNPwfY3#Mt=BV6}M80pN*smBdKMzZA%29P8f)Rl};(pw)+`rgUi##-Vhy6R`L8 zrvmQ3a8anM3~R@zdbHNbEm65Ab?fZDaR!adrls~ZN!uY-UX-!+-9cp-Wd-cOIx?TU z<8t;^@=K1nn{b3}7-Pw1m=N_bcf{WubFih?r=q2&@1v`ASiZ!fMgyc0MQE(EMiFra z3>497@Z|JVWRKKRGs)+3F-aO9N@Y0AE-K`b3{4X+7L@&qKOY`4EutE}>R1T&N=xIS zgKjV$Byd1mDg+oYi>j4gBi06-ygSwPk-43R9?=X z6o9-@>K!_o8H-4)+NR%P`5hde%$rZc+?%;L}ZPN9s@t1-=zzP9{lbDWEUS9Ig)MV;-I_Nh$TsS7Qp ztg^#2yCwtL?0J2}WSr{q^Ind9BACR(YSglY#w3<$V%e~>Hc?=<_j_~b)hb=bqjpu2 zcT$tK%ryp-+7G8!$H*rIOuIFB3(+*O&-^Y#0dpqAf%CjVj3e z^$a6U^|FCOMJjK=OQF6(>iw@}kxZ9~k!A4&rI<@>7AOOv<45sMGPqj|^4|E) z)BccnQpsbVv3-f-Ms6s_n)#Ne&$sT7i16HYl~5V(z4swLp5<87iQBl0bcHp%{ZALk zZq3^i`s-8@70d=`l3#&*m)pEEb~n^JTK2|ia8q>YmW)e-WZ+Nbo}0j_wWrTEt`FJk zM{%HT>>ij;eR`IE8w-81{jR=J?mxAO#^EpPalx-V-cL>~+d+gG$@`_p&oQEON1~n2 zVMqEM+h<1|2qf*t9p1-Gf=NCH44nyYrxgz5)JtV4OXR$Tce2fL$+xu>wd3c zB`<~xQvCRqXc%9;*Xf{vM)5K$Mct0DyZ;hMr{(`$iCip&>-`0Yjx;YMImq2JO(4vXGn!gnvE+y@vc@sj*k?hYdgrhGu4KUA+M~U{k#z zZNctEX$2p%u+>J?{Y6(N15Wvk4L~#XGWzdP`2fxf!vz5PC57)1fJbD<_$ia;6@Um; zRJd>^JPYGf499rp%D<7!UxyTtsJIXI8b&nbaVY|7M~2+h>*iF~~HHCCps_RjTA^2WkdD_Ze5o005d zv-s<>gUMr^ZCC3EMl5;Txm$m7HgJ}#^R7hn=5yDgxRQwC>(jyhVcPYNnqW&6-vBJCEqj-khD{;pKas715YbYHBOiA+0q?BQm3H0lgO zT~-98;03<5!CTDtx>$xEtT}4wwtq3{CE>*8YY9XyaHlMCDh8Po2G%(iSW(hw?2FGA z!464_D5Xp|EG7l}y`YowqeVAB(Nv@{>gplj(HW}0=W66}mG{zZi#f_*_r!`#$i=%o z`JI&(SxBm@|5o1TrZhU-L?p*K=Joqsp8!kjorQ|GAfT-WFA!U2nbJ^60yKG^3ay?9 ziI`{w@+$@@z60`Ag!*`FXz&MJta7*ZSUZWaz~Zn58?T3>kNXz=zE8VNJcD9JNyUR5 zjavR*PzJlQD_x@{sfbyO6xX@2IV1WD%fTjvv0;}&t4?IAXbqG{-MGN<0~`bMCu%4~ z;IHNEnt%l;kbnq#CR? zb+QcG`{q59JfhQWueOyY?rz<%(pPwi|MW3IrhaeqeAr>*hxOov)b}Q{9Exx*!@=5R z*Os*IV9n$2boyrJXOQ&{wSId3g`lc6Eb;VSO*?mq7DvSPEFoi z5+FOu$XrLKhH&RCGCh}lD*^F*h29$!9-5IK@II4W3#PR248|)#Uv5W@`H>kNupy*o z4G>yln)$I_6eh=S zv)VJ`7;in6AtANUZ2XDDC<-Vz!|{)i~`_bFWBDM~B| zf8mR<4@P#xhcDnRkY#46O0;d7ixtZ}0Oc8X_pkR^ulznaCs{gZVnnmEtWKIxBs;VP zh23vQ6Xud>K)aC{M;eb1x8}i8&p6Y^#*0yyHZh)wtV)59=Rqy%k!<=`kO1eQ{b&6% zv{2gzvtFN1^_`rCwpn`Mx{`7jq+zd(?D2d|Pt5@2JB6W zpPba+24Aa8u!qBi_r$!*pdTe!LqDWmHLs}TL}xA&D_lr<*@>UJ!;}ySW#n(MuY)fy zYM;?&rJF{F*nYMWOPFq`mS0Vot6J20FMJc;;17kR;a^F%^U7Rch|w1*yjc2{C&nh~(?S6iPbe10mY zU_;}0=IKH0l<%rLorzC70+bxuV5F2Y4d01U5qDvY`9k?8aQ{-1$UK44`;_~3>=4M= zE?Wjdkssj)H19>4viiT*PgdM}Wp`i-;P7-=aO-v)%0hMxl=m9??z7i_b< zk;x4@+v@feuB&`s80aq=@*=tc`aFGmCb4Jv>V!s!5k|Ax-gr{yKyi0679$dq*srPl z^{fVMxSV$`uAh|8n5XFrM8bC|^T8&e=mq=Y(J=z|x+b7KINmsQ)Qi(+b?|6~Q;vCKukDeK-)`=w;O^)=|!)Q=sRGeA}|oO^y?wd76HlMrFfjn0jGF-SvEU7UR|(`@49bOVeA;& z=&RZ3^fJiJ_qeI)-I-s7SRvmb)lyp*x8Zq}J>?YzG;+%v)_LRCkUHo|xA?L&nKJ!{ z%X<-_tE@uW5$x03BqVs6yJvMjyny}u?V!WD+4>g^ehpWMXD$sRq3qd_^F7?1LPA$~ zTkl#udc5IPapfc9^ae}FGu?`{2ey6fGsBAHKb{VvXWa$ZXA@5%Qs2oOep#$e?W{~a zjeT`BL0iz>X$pN}9OJn|@^uA8w#nFc6O*AYV)6+`?S)QETl}eK8vJ)Xk0>|6o~Y+x zL?WY)3h(=sGaqoU5`+8vAgkvXdK;MGD3D7BH1B@>Nui-jM(-*%S#)F5J&nhiw*5LC zB5Ut`qMe!c@RzN?{ljmz8*b7ON3Brc+WEZhxmhXs&#v{Xfv!_vAN(JegXhenWokv+ z*4x3zZt;w4r6pvY@r|VoJ^RvD0g(_GsMR z)7}HTsz-X#rG^`A?j}#a#pC?;@~Bxz&wPg#7pvQvn3y>8!O`R_8S_zN9|Zo7(bN%z zj}GNxwd3W#4XpoT7Hx+6ZwJ1gP!KV+_4VcGp1nt&Rfv1uD0LBMV7f*$s^+2m@6pf5 zr=df>CWiOUWst(Ou-Sf#PBg)>fbVlu$PR<1T9xGa9KQgSM$+Yp{KaO`2D$+z&DI_I z8IJN%Oa`0%Kf4xIT)d6oKPIXromx!<~wd z6rH+>Dl%iXaR@h*hgsasMeM3xH`Wv66LY?w)S1z1Y^RnV8k4RT+(?uEI{Z&p8QPSO@UM?K==VXiaaHq(!%&-;jBQ(& z2~^Z|UZ&c%a96o8;#8V?PKO^kiC>O8;tzlS->8LXe>wcwsYDJ13#vPoADaOv6)`FX zxw}W2Uxd|z7nhh;fRcJUi6w#tK2U7X{sS5Kp@>`5Rx+YPIWojqAxoD@)a|TrIWru@kqshOel!veF&*?v=`J#5pDjv`mE2XL+t1+Kz8U;`qL*PV-K}nc z?`Aj+-V}NGTqmezsg83w%h*Q&}S3nNKm4gq$s=1Qxw zDYc|%7I@(@;fn)X)XtWm^W5>F*L);H`2AMAk9E1Lm~6{n9%|md->t0d1I~jSzr5;d z(&sr}73Jjq*p>*uC503lY@BXJk6Tjt`-Ne@Pm_To}qGuvweR4jA%NQ7(BIrI9+ zO^BfmZm0pxfNT86xj(Yg5E!w1d2b!wqdj@!^i{mA$JwYfdDjhR*MCrmrQ|~+9SOk1 zx|QC#>RKf3U%_pAFza@0(VEP`f@)B&%bk zTjV92q)~Rp0Cy?&_pyshBOHQG=&ey#JUU%T-O?nDKRQ1X=n;^5T^7fOoQ=zT4m5Uk z!qG>}{}blleVjPQu@z~Dy=@c_K=cwsgp&PRG+Axms2y!eoT{XyrHPg~{R8tf4L3H? z>chZH)u$6Qr%o^YgG5SXSkk+J*!4GJS`2Dfznx#3S}{GV8TMQXf#{s68Lp)^s-pqd z+2(tSlcgSa@?oSG757}YJJ zUaQU^CKh=f%dv2p154j2tvAySGaYvMQlq`(!8IaDRfD3Qu^)N1 z$Fm=K)=J*V8;Mc1_^s8o4_lwDm9CVX7OjS{r!pZ{U9HGU1fMwvTB- zIgtC~Q>G;#gNmdfgs!5S_W`m-{+B(jxqL+zM)`iMOfHv%yUK#uP2g0DeYL4U)2@>^6~{i3FE z21SfCFitcn(qJm+1}p{_dXsbP3D{bqXI+5IDO{>!l7a}|JCVQpY+gCW7eZu2j^z>I z6P5nlY`5_0O571Ikyg(%e-pN{y>*OdaIXmT4wCa4cn~HGPYI49hKX+qN5|Z}<%&;G zWpGxSW@-dVaX0GD9?KamcW~Prct|~IKHs1$ig&%Gt*)%}B(jHhaF|&VzK^V6zjOFV z?m#3b@-u~X42URCczhz8U)Ozs6dIb7cLy#!-pAR=xolXsuqSa|Zl`-3pQ+U-V>PQ` zVs0KnuOY00{ShU353*=hJKs6IjbL)vk$ig|a4v|aKU+q3`P?_6{wh&?_ z4a}_@+wWw+umzI_Z38{jtnr)c*?a7;IC{u@7B>thMd|f>ey~00V~I!~<*S1m(*Ke>X!FLKMa4MY|w}^cHKX z3Q)}-;Twp-u@*Y5rI|djPGU4Y!8<}H;{IaW+15fJ&@wI%j|~m|J{{72ZmI*L+Ptu- zHMVLL%8#5UZCrcor`?)lQFDTMg8inKBniV*1sfAlF7YoriUZy|=5e5?s-uN#ydd0X zi%hEWup<$RUicvmox$L%Fota{DOxO_wM5G8l(*lgrQ(pLr>Az(B{w3|)&Z_L*(v>4 zY!rg{sZBmZ+OIBx<$zGlZPS-t-C}giFSm2WwbRRzY(Jo%dLM9UuMG_wbCKhLg%=-2PO_2!ucuvL) zsqsMW0W{y`CPXsJI8KbDrOHX6qEEi_n>>87P&G49J0*KsrdU)q6T5#*?*MRkQL)hZ zffg`ep$HA7E2=%49&*pwQyOL882(b^U}MfciWl=fH`I0QERup6rl82BLSN>pB7&>p zv4^H4iXgS(#qm0mF-g(s&x?opYsQx(#={TX@e^k`C8g(4WiZC#+DO9!l8+!GklVfN8eU<+UTC=h_X@wOn?0PJOBScOI4DUBdL%xFk zilm<;yZTYHH%}AIYEu~edcnb;akEYWT5l;lGqgz0aNxyy-EWH+H25zU!1Yaflp)Gy zC107L7I=3;yV2!W2k5sXA>@3VAGt5Nl>2QJ;)Pmm!G&m@q@?3isenL(y7^0|ETGqe zuS}ev@p`3Rye55gi#W5DLbsO(E01+2cvx4PBm3mMdUtSE|8-yAfwXI-zp4JGsLu7D z8>zBi>B~DA#qwU!USHkqB5#XE9thBxa$-5STwnWw#8gJuO{@pH^<)K-)SmbQ)8nkQh` z?_6UoS9ML}dJ@lP)mA_AydARfz&FWXjUN1qKm3);_GX(o_R#CYfPT;XP7r)i}yl&}t0px$XWL7Cy^=T_>rrsgVumL*q+9gGdr_ z_w=j4-s5OAmpkqC*S891v!c&>dvnIs?Ze0QE5=PLZD*2t9iy&)C+U0?C`-OT`>b!+ltVM)^b zH0B;zSl6Yru*>z~4Hkw@`}#1i|2lv3SEG%*{UaavFT-Q)ne_dVwD7(S%pb*jAH>y0 zwg6Jl^L_o;T(=)x;`(0V9#Q*VQ5WiG-n{X4Uh^KokUn(9O_ct6?d#=c_%_8~F_`<| z*W+0T(nY&kH_se$Rihhf%zcq|CRYO!*IXxt5|>pty=oo{#jd{sHp3 z0YMcXuv8PgRS``1fTG{Nk{Gb_yY9Eb_RtOc#ZuX>E{;^!eNXa%v^N%Jy6y7L3a&Xo z)Lfs9-|q`41UkRE#b!VvH4=quLy|=O#lJ}P z9hL~IYX#5XM3RG4(O2a&C7E3pGt3w#v<{7cqLVSkJ0KGokI4TDi)Im3oGc+99&oR? z2|dRJJC@5635)j^nK_*jliR#&8-{%oL8qa;J@K5ti?jWqe-qYajzCHtf%Ur(JmQpB z!@|3RqWw(_6DIbZD*S_;U~L;TYweytN`)6(SDfna!Y>wM2vR;?Ljnj-(*)l}MPBUE zl~^rzJ=ERcaUvF!QotXvV-^9qW9%PDLz+ej{XYvVi+G5?JHh(*(r&en`oXi^LJunS zNWlDZiqo*Jim*cT(+H7;i7rncr3q2Y=p%|6=lHS&JFeUy_DKy2)(xd4u}CA(-PH{# zb_*p^C`*VX56y;{D$6JvnHj`6hdBCC&<*$mcOQk1EBr5;8Ah@}5H?MA6&5MiScDLu z3cW!R2}Bo4_ScH9(ETahN*$S>er*n|Q^dN2H%JHAJ55#Bg;7;pAx=nBBrB5EKZJSH z>3`>Wkc0Zgw&i|oAuNIYlahf+aG^8#fPGu@MoEh;TA@XNIs2c!pT9nV+V_<9H*9u|!EwNA~3u@K?iG!apMT zuca_vF6t^^aCl&enWPOKu)N4MZSBC`cH()xj)3q7PGQf@F>FLUD8 z0p-A|9|T=Xm8_GPK8^|qGS5M%l z8G^_ApiB&%oyPM8P2!vh z-1gwPJ|qCF*BX|Ny@yKmeUbY5^e;=q}hw~ZEHpmc;kPllVNSLZI-N)CxmtsGI1{a(q4^>;@@Cm;rVTA2R@!RLu}N7rh!@M3i((zyZAl4@$ou2snU#y$t2N z*4|`fPD+7VLcT3Sie7=lri2%&291*;ZRf`N>ITEd&+oSEYEb&bhgMS@WU>;i{sXEoS{?#NyAj&Q)UoFF2)- z$N1VpXe}vERD+Uh2`9Ajy6C-+q?glZspN$AHM1h78V2-+rO@&4=m|umhl4T>Y!4~1 z`>;Obxs0hkPbW^u56UV_{3tT;m7uR+PK0hU)>-16tB>oGAjntFtd?}lN5yAT;2kSY z*u@y2G)i-)OmByT)hqzHx0aWTQaNT>;%Yp93qGj zx%RmmJF2Uxi)9pWqje^t2=xum{@Y!RW`JP6?=G2RJD}`1JF0(KZfR#px*K?g*GNlQ zD)7v7mK$YLE0FdFXnC3jviC#%S9@(Z3oI~T^X9$7?Hea~cE5i*sE5#D6hyd^_#aXw zGqQF@%ojN5S$mEu&L4L_lZ150+~{mHW;QQ{1Pk=7grN>&=8Y{WXnj2*(l<`+(_#(o zv^2kWIOkTsBTb8s%DE*#SMZ}}vl0F(hBWpZg?z1%*?tgoq7po=d}<$xCAV`C4r``r zJ;?vktU<0`rMJTt*0+Lh@AH0;j6A%(zzOw+s=cxps6~ ztvf?B;-1X(wHzYaS! z(A|BFkNUGcnOoP~j_>*7Bw^@G^!J4R_et-;K+WCC)^j)-%JM#MtvI}DIWGsF$JS)p zuMI*G6!m|#8xe3Kd%7x~e9?VE_q`e}yC{8eKiqPBnu5F-eIN#1 zY6oL+zT7BlKF?=IqNGoXvA=e=30{shI(Z}=F<&Vkn$2|riJk~MFA1eM1n)o1ikeoC zzD|>-`^arxpl(LL9Y(!bKw2{yb{Xv5W%v}0Jhmfw&m|!qi>))kf-l=g#e?noW&(oq z+iU;yuJ3Ja;fjtvOA&dtHX<%Wl4mZ>DX$-8B|Mo+==Jy;H#6 zh>;@^5Vt|zmloHTrKs1X4RB=wI;eL12D0&ba1-~w+d5#y!La}}IIkSXLk&G`J(2&1Q~6)FgRa_op*zn~^Hko+ zr2qZv#N-k*Vd@DK(Pv)P?x+h!Ad%u0$;+rUeiJ3YaMl{QqMC|g25TVwhS{l6=^KB) z%AWc2g|D3YFLUR-A89NRxrMTUJWa3I&v@cMll=jO8N|O0Wur+<1(Ug7+(sGR$&V+L z&p5WL(LHg?HklUaLY7C$$$38>Ka?j|;q`=f{@$4^QjyFkjzAwG3DpZx|L|%6X$`Z& z(mr{6XeL@7nx>5~nr1RgoTzAv`>42gHx8q(TB5pig9a;_S-iK;J1H|?G2&4)l~l@R$xTH z-($QTBo|N1k&=h#)pgGt#gM>G(F|iz1IsYcNEYkfUk$~Iw3Wc_*F=F;kW^&pDJSEM z!@~WrbN?N-{fSjuJqmSvAOsTm&6L^kCu{8vo4*+`!EB(_SI#MF1PoJ;==LmKD7V|R zS7!dlaf9|R_{Qb$(;LZHIyhxzSDAfe!j=9hjn6c@fT=PO8B8V$J~xAhH#CVY&dyoe?2Z9R#Q~be$Mh0%F9;K&++4?i3g4OVI#H7u?%u-3SS1xd)|DMWO3z}bOW{*b6h{uqpt~C=S zn=58?S{IG^j#BwA<11O$mH6PFDBN++Zs$p^=Zp2ls=&+_8Zs;IJv*GCZ*h6yc%o<~ zdX)DoKN0zw6ym%l=vT4d#{^;>sUJ?o6N*gM@2N$uvTw28@_+789frG|1RX}ZU6ZQ+ zY7{sPM4Ql7HYKA~l;ICIAJTodD%LJ0^gQ(6;X14|GhC(KX-D%l%c)Ef=Z~A>!hNA6 zA4IG=Wd|EhEJi2>{*dCbGZUt0|BkHKqa1GKThwDKz?i1KfEPq)80G!I9@(r%0bgzP z#_@ga9~3Oa0X9oukMXy2UE|*xK6K(^CCi!d!Rpx4<@T-`tvHM94H_+MoUM?8R0 z|CV!)GMP4HTrIK&iU>IrN@=hjjLT0;X%GS)8m%5T5xuDl{G1|AGR<-<+dw=LObPxa zA>Wz?A{qgQWr6RKiT1W6(_SNs1@zhqugFPv&ncR$n>+ z*?o446w+83+&QhrTQsp42}F=LA9dw|+dq;WY0Rw{c>Haxgt0sFy^=k8o-NTuZy9`; z_&Vp`(+RNf{uRgrpN$Uf=5z9))4d^GP5-EzgcAl!1p(Dbw%5=*&`2fNIP3a;23GTg z-J&f;PFn?0^9E`tk^|g%!TkJ9lL?VrP$SK>i;q#}bC1E0f@+X1a!=kmUEH+-AxNiN z%d>%UJI9kBy0$uyQB&%RSbFGgH&?>fZ@W8?RbhYEr^BOoa1UCJf=tP0L+^{U{=xsv zgD@U&H5u@l4b-bh(Do!ATX(*nmZq20a z5Jn08Wj0M`r6LGo_1xwZ%{YY@RWtm_B3yRY$VN)UThvKrgX!s2aLKz-YuQ`t$~3F` z9Vr4+>|_a;)oZu}{N@U*ViajeV)^NVlEBKv$YPPeLRkSwBNT`GV;^O_j!M)?#dyAz zlYz!BH=qYcOCF|H?Q1Sf0m%i)Dm`H$k%`8wLFKG)$GDu&W|ajkkqo?-<6=G`)N|g_ z+R1~P=g~8rriSF`seh6wOgQgfk3DT=cfO!z!^pBxo@}c1tMPf{dniQ6n|Og7Z_@kx z9Usek08QnhaMWyP@%5_P7VdNz!$g+YH$TA=vb%y4$cK@7-GEzt6DNphMd5)pHZW=| z#Y4#6^xaR!=j6^!9nrj6(#IH;UrT>4@T(>5-9TA%a|iDSIn&_i58`tw$b(i3jc|R~ z2j`KuLVVElKP9uMjug@Fm->Ne|G?CYVQF#(FXwza;*@fd;oWCDzs8-POiAht0lQ=& zGqL#l4}9+}0rp8vK)GuB!YMugp})#LG|sPr>Kc+#Amd2GFHp|rH~jd}FnaAU3fHIV z-v>yho4dwHaA$0C0aNqnh;GsXAgDS0)?TkZ0s22~e-C$HU`?vaEKuGc%?C+AG;!Tx zQKdD8w6&Lx++yxuetW+cz4;6p6R@Zg-fcAME(*%^U`I9MWZBa}w;!etJ&8kl`7;(H z+@vqRmF-y*7MQ*+>zh=WoINR|T-i*W0&3lxg^(6L=-0JmY|o9<$6X6(f!?ZJ=E>on zSi9z1<5*pMoyB@azTajZ0WG_X{lj7GJv$bbb6NH7f;rfa4`@@ENV z-}k(8Y=lt#52XpB?q`jInr`PTJXc5!bo|aLQaKeov?wAfz{sqVt+-tM%8cICK0=l+ zgzA>&7EP1Zb4?km_Fef3o5f+2mb9%FdVv#93aBJ?wG75nLaIL+BBsqx>nFcSd~|3< z2wm$)o}n^p#&lj}kgE>E%WBv>@p`+}5Aw{=2@`Omo(ZFEF&T8gqJ= z(d^h-41xUZQZ+VBC&OMl{76`#L!2I|6YG3N#0OZ1#yngnuQ46{^njq`&gJLZBVbcw z%VoyS4)kYD-A7wBq=9pRQ_!bnEWB-5YZ-`8W!8V{k&$wvX@1{JQ;wr~xETSD`^186 zNc8}T6w}Ts;kt-PU4^*V%NWjA`)EPPx2cXn%~WZCL~voLPeVc#llYO{elg%mk9KQ0 zAI;psyHpnN!v3IkM8cQTM3FOZxyI|h5Z1T=gwIw62ssEtbB2Rc9vO#&NGoo4!bpZ5 z8h;$kl1tBhhM-M-I_%Y1uQr)|ST&%ue)OX(Z=nIutVPxI3hlatUuXJRKQyfL{9FEs z>rkA7`Fwu(wK*6wCe<{n@@ar(ynP<6V}-m(J73&C#4V6fys?J64npp{yFuPca2-gQ z`ig2K_&1r|&zYiZnHX<(I#~BUp8DqhkZBx*t{sFv?d^9fH0$DJ-={D?p70>8qSUye zvhB~x;MbRLp!2*i;tUJVvByt7UpGiDxlh-=lN0nAU|Ao(Ema25J>SIbgTc$)LPCb# z=Z(kzG1>oz@$qyKt6r>B$ld)sdA-X2Ea3Ma?dxp#x{FiX+;v}hY-jJiW^j7h^>P7} z!at2+Y2F9}zjRR(bKi&r=DhvQ0qq`FM_iWGbUiMA9Nm#u`+2wBX2VytO?N+U3d;?X zQg$CMZaMvrgT4uc;YWE%klJy{LcHO&W+!Uq_fUAq`+ox3R}+ji_FG+dV_ID|wCpWZ zN7DaQ!2%YLANlbl|7(|T^Va(N!Q7@MLsIQK`~KH>@6l?8eLbj#fcO}>#ziUz zx`zTF>?fO@=y-_WEhzIq8S|6FG2?YudmEU484?m{Uu&RnBZwa)xR*V-H{^wZ&Mtx*s($L#3>cgums4y z$sBd|AJ;BBXFQmy4eDV1=0>s=tU^Rv1HI%x0PzR z{TVY$5C|bMd1Tx-8)5t%*~ioa%9fj=CVn=lE+)bO4MmGV;jnK8&}d8)NT++0h@!B} zZ&LN??l=cn!}AXs)NbiU-RvLvO}LmUI|+|)`Q?kNx#vsd$BKP{X7HLl4N8an9mtzF zK1dKA#0MOZRTxNZ1gG&sZn#>M76^5*tvfs>?l0tcclaxeo^xiC~RtF2VE5`lU) z?))O97;Fs@`w)xl5~5*Fh;K`s6XaL(b)8ih#&N_Nm2oX_xLW=$1dA<9)#$miyby16 zE(k?`A)me{_!NMSTXHQB$@0KyoOnQnXH_>fMbijjAO6Tm=71V#D+_Z^N(8`zV*9y~ zcU!2k87#-)HF?jqHlc1b#8m^^F73UBDqlx~7t@%VKtUe@onVZUS=>C$4@+byn&pOM z3bf?crkY6K^E8j@Svy3`*w;}y%RR?UG#Du_|njgl)9*De!q z{^8R7`q|mtSaR4HP7UT0=-@?Y!g8nN;L)hxdG?S-Lt$l4ITDFvJq~;61-P<6aflNP zHwtEJ;h;1TiwO9#xhP040Ax~mU=diyahF^}Vf8Hh`AFJlc7E0Ka>fqisX(+I%gS96 z*+xkq`;MM!hi@7Vd=MH7m?Als#Mexj#)ORz#pmaN2d>Pk6mT9POFHK_ve|ehcj&0P)NUgR3cd z3NEt~Pv&IcUPaWbeP^QMl+?f@)xc#JvqPa|hyayQgS*5D?h$3zog=4EYy$w+u}~B_ zyB?u+8a+WiktBFqd^B3eIOb!&L$*mHs=rGMRx5nB{YSVQigCBPHdGrGXZeL?h*Mkn zw;z_NpjFtE`Kw5u9-`|+9tD|?m^ZsiVr_^>pqg&hb!xa;KoYLR=@qF7ly9k6j+^tD z$)>7QVR>~6yaOoUPKOpX2kUgrUQp-M%62u9z!kR*z zmhDLkX=y?d@lYVqV>eNjsz_Y7;=SP3;Ba9q|KqQ<69CQsS-yf^)z&o^v?(%|!Dp{P z97-Rz5%>Y+UX(eYF_g|XenvnhWQ@F4*{K&v)|KCuM2pWitl<{eGdjLf+g=~vv~-UG z4q^MZyABD~m8P6tLF^5liUJC`)*4GY;e&4L(I>s^ylaX^goiF!#iHPI`aVC$vWei_ zfo}AIE;6AVallx@TTOu6ub_lrv!T?6ETpc0>S$nP83%vQ(Xqwqpy8CrnHO%I7rd~R ztTSw59a&RSI9=->vm7G#IV1gr{ct~wVc-rE15@!Ssrv*YhP|rtT&$+ismlhmNbsL( zaNp|^snKDg5JS(uUEcFcpJkHuW|`lPTccL1y#j@Q zz|lfE8EySeO~XAFU=UHr)QbB*l8%O)u&zH|rQYL?D@lUrw?@P_({Vmin2UvdA9ms5 z;`}%&;(lF*G#Nf4zP2wf0%CmrKfOTz(4#IT_@7HAg#LA4DF1_pwd! z(Hxqn)uN2eqY!Ql_Z-T@Fvru?x2Fw=-wx+;64VQQ-u1=FH^rl-R}IsZU>c+^GoN5| z(>sE?CFmc8y-yi1DjviQeml!ho~ku*D|$=H`J5{gR@n z(Md-ggE4-^P5e*QjF2u4zZ?V0$`F!F(YPVmi}B%05)-679Ovhf_eu!GCgO*fK6arX z*2xdJ7uH?C0ViqQqG!0M<0G5IUzD-_rj-aHBp*@ma#0M|ZInVd8GCAFfHP{f)b2qh zD0`K3lQ&N@OSd781NU>p4~~$vOGtnePNW-{C85n|Y6YgVKn~P;su()*yXCTpM(oqkyvLr=hH|%4b`fuGrYx4R{39Xt0%$}Q-*2h%^nS6 zDo6X$Wx8ON=n^==iUOi z!Hq-Y_00Dy)n_4ZIjbU>UR>Z&*GIvsh?{M~}Nzh*bn>o1aSuVUsfqcONM|;bThIhL$qB=O;OD5}( zCUL0T7ye~k5-0V;P4$F27F;=9Y*&VLI>>&~Q3A z_dTrlIeRCayN!{Rp!IN$yz zryPy_PbaZwQCH-CPx!T8xC0#J8S{TqAwDSI{SAW-|E~hx$8O<6ei|M)W(K~&zT6!= z|8G9LS|1rkJ3<)Y1zxK+@*VQ;^+pcnN2HnGTW@EaEI+rGc6~yNF?Df7IvLOz(HlJn zNw22W@k-dCw+H86M{)gqs!D~>>8t}8A?L1BlEp(d=a3tGjP#fA1q3?Na2S#Av1XA|Mnt3gmr!nvR(( zuve8c1`r;9SgnyEmb@VrVDDw4Y5;Tsh<8&E>HY+e{74L2-B7vlelhU&>E|OrM~OLq zIVpV^0}M^Nz-`r^Yk>=tjzc$YFedXr(eMX#v>S0iHrbX7L!{MK*BfSTXmpqh)OJm5 zUvNR44#c}O>Yx3dE+r8wXi7}14tz8*q!1<%1&FiBD33gvwYmHr85z%Q&t5VyiB*dh zFDs&%{BH6SC>91$j`BG-(LAh$-QXDL(_uK8Daf0P+;9p9U8o??&CFd|{JV{~t*Eeu zbK(y+q(0AM31PYs zT_TmhioeTWZ*Fe)y}`>fYc6fL!LzBClh16u1~b_NdWI81Wat~4 z5)J{E##Io^&dNnoGoFn`$XOrkc07mgY(_n&bX4H_q!U7eMUz#XfCIPUn%b~ws@=?`)meIe zNeEdhw^=G$R8yH^IP6Y9lU`}C+0$Js4E#`OLOL>5;t9JF9i^PQMK|U0FC}wSbg1(E zb|cXB%`BVu{qOptI5v9}_e5FE7KOlyk4<>$0XY53JbS_5CfPac5j*zz6q6|wZkjtH z5JQn1btdeM9zM;GW_Gr^2uTsDaFp&?zV2Lrjskqi1l+ds5$D7?(iy;5r7~J`oUs^k zKMMY&q#5JIs}o=IPQQd$U?7P0qWrW-wcD6< z!h$(8{~ZD)D&c{6eu#lu(XC;A^ME(yOkPyn_;fN>%KF;FT|YF@HM=1~kw)i-k=Z}T zr}pifV@^}+uFG4+kvL340yKN|;B*S>hzQA~RJ|OSqBW||9(1k#%ut*R6*MNRRA3~; zxiJZe&7+4S^Y|+>6U(xP*0bWlA}a9Gt(jb0%aQV{gFa< zViW|jEWi}EoU-qjdg!aHS0g?vdNS8y=}a#D8 zDqFyr+Z{7TXmP$H+3p%h(m%o|3oSTTlg_*xqTG8qdo{5ZDWh3DoEPwAl+-T8+p5mto?9(j?T`yTT3 zZB)w%k1O7vE663u?n{vYD@cXZyFs*}C)w<;gk_Z!Z1}XA{qGcGcy~eZ;r4J`(u%H zSfZV&4IKntm7y{v;P(2NZfBp*ybMj5hJF4BI+s+py0d+QHAW_J`T0|96&Zt^kqwSh zJC@)neSdKU9)?u(k<+5q%_K+2+1SP#Q#e3oU|o(&t^xkN%1j-!#nd9TFHLGeUP zr39V)yxJUv6v@`~67s#Ak)of=L%V0N9tYQZD0y6$bc|iBuXTBTBO|xRhBkI7OAzb5$cYIZgdEAx>fq5!UV?Sgf zlFin2WZX_UhS$AE3bC&>s1>qo>!WWIURw~ED@|+_2CfWNjYWN1C%S~wF>q?6P+4v{ zw;LfQqp685^)g+@`Zku8lr*6_9`+a99jn;`rKvdeO=d@?ZId~Vl8tP}l}M^BEpGBDg?XynJ%Get*S zh8jM+cUlr4`c8kRiePJ30P9l}fMk#k58pGPuAs6fx$a)|luXG!)GOqDNBEW7C`qQi zB(}m<@|XSta|r}KRk5cDEvZ%9dsKfvR{`&t0X5P70@A+7W7nk6z<{V=G(TD<;4|&9 z&>F-16&rX|!CH+U7jIc+Rg^r(cK=haBaUg)P-%I~0fFSANG?zO?3}{wX9Ik)uuogK z-_m%hdiO6um0N<^uru2z^+>QcEJD%&oEtBMv0Dlp#vWd?*Pcp7)>^6?JpTmx$opBU z{J=5qL%8dqkUCJ)eTDr3&6%b;v~neT*3VX6_!n+X5AiaqON>o73+-h_G$|rhkM=Es z3;79Qo-O~t56~E$creoLZ<~BxmfYa>aLyt9Wzr#as0uT#jpfdA7;9XE4ni~`=VsP;K?C1n?jaM1S^tLd%e-@-%C@i-KhR**YrK_<1v1rk)8;;X+Yi8km2GX{ zG~wyO84z35HnOA3|EJPz_vO_7S!^LW zDr3B%*D9s933;USc8&k}`8ibfZrQrcqX8v#HfEVpsBW!jFdJD?V}R;~mVF-;E^=6j zxLn_^jFI9xQd7t_(^S|%A#d%zmb^kf`60?o42)7yZ7zwtn-B{M?u&IeZaYw{`f+uLgHHw>-mdUnLoQ$Gwfrj&jQ^b!Ym8;j}*!o;7<=T>iuh-hhmvYjx_T^Mbe51se&Go=4aMkpX)Cf#G;~Cytf|V6VIaiMOqn(DsWqdeHmD^swMx6z)x2o3NMdHNS(b^|fbUZaKe2V9V{H z%ijHPHPfD!j`d!K-(C_7*oXK(T#)(y2;<~f1{g0cmq8S$UjLMjrgLI>9nB%j z-a-Gt>g{gQe*LHt_}qI8pzkg+eLAHUx{jdmym-6x6Fy1DA#vYeUN-QyLj(A|4*Lnb zeU3JQ6RU(b5KU*<1+(Q}z89a4{wHyA2Q7RB&1ykM=Uck>2}wCdvG))Mr{_GUk31I6 zfhvC+Zo3nGyl>dc3SVJ%ClPx+ooTwRZ3(_DeB9X_13uoEi*2e$BgVAMJ1pZ@yw}++ zrzE~;U^#?rnf|Z+{eS&!VMF96{(=9M{_9YNOHl8<#*@VsH<2QcH1AMA;s1Kvz~-K0 zY=_D#N}!dO48~WzU6QodpahZR*QX;pNJxGH0s+}f;RgPcz=s?1|1wZMxhM!cY9T|* zcMg*-DEcsFpBQHZO5rX(hMEwQkg#ozfSNv-&cO#t8OAB^@yQ6_3gpW8Ht6?l+Ip<= zrU3c}2s6pVS{XrOA0}6_w@`)Pinh93B?0n|LfCwZl2)Qqv?9;IXHL+cxoePEDd&q= zXrcN;2r^U>(lIRaQ(FaLS>qTF70K&{=n_>=_|iDN4K`5a#OJJL%QrK{h~#zXvGewh z6eFF>TQXzxe)uT%Y=O}#vd#l>1+|fw$&-nE&U3Qibp$EA!SPr9{Dbm~5t|$&%yr;h zy7C9Dk)*5>jkT!2=U>%rtwwUvd2DK(LIl>{Q*n_HU!32#5Rx(oF{&1@5LFPmXZBG5 z5iv~-Db7*CBv^knV2i)Hc&`W+)>K#mSwTo&0kAjV`$}y?2iGt6Ch-F}MDH>-L|l!K zA8=5Tdn>b_BO$nq#);U#DgB<0ViF1_&xFk9ke>Tv)0RkPElMKG)57% znMx#{dwe@f-@6)T8X_y48$_xq4a$pL{QLyWy>AI=5`J~Pi+u&A*|2{T?v~Qgd4B-z zt(dXUEi>r%Cm|}bakQ=U(@E0e>S(ogi;++;pedQ;ERr-#bv36}0=64rb!t&-8iF=D zr86@7={S@If9Zr1o_<2S7*%re6*SxN(KJH~8jk~&8OK>>L%v|t1_;R@lrF=T<_|%( zbcEZNHn`pWbM!w#>jQr0Sqg}xvXAFw>}d*AQ-p=E)1kyV(GPCOzX|a#(^!e-lCiyd z#juu@uMj+iuz^JjJAtKuQXqz*lhq)GGIs~^BfQ(qEqlrcCXB2y$}p4wWM4m#V)a6A z++P`g$VadVHblaNL!hcZeXTg<98dBfcbuzba|?#T^?$?%I$&u^H4u5poM@8v`v;{c zSouLAL@T?Ke&Y!xI-^E206L-B@$L))Txh^a1t=dHHJT0UkqXGj7RfAu(%1#QPoC z1x1PxT5%*M+0L3KWk9b}OxubNMUcivYQwHxso2bXEUcGw#qbd&7*Bqpf>}~e^?&0EM&VL@R`2rxJ0N9x^L|~NMvOL7)H#&N-S0tiJjAe<^XZ`IES^vC3e^}SWBw-Ur z=3$(WNo61#wmQ7);iD1gX}Mr8qhj4t;NqWJcyNOv({Q}Myly;E)6NIDb}a_sBFiE> zbclRVop6{QI>fb=n4aEX@3E@N8MmCq`A^tB*Pmrka)-pSKVS$CgdPtr*U%hyXRjGtTBKPsPM;+3#{5A}}gf~F|9?s)VpQP0Zcq22;>dQG%iI#N8A zOy8R*e3Ugs{N%s7b&eS~)jw33%O7vIj0YAc|66pPYHUA7vs zIrBAj#yaHac|GX2dcPvPHKj#KjV%H#Z^Y4^$$uZ{B6^^$B8U+W;Vmf39{8c<_sGl) z23N~-Z#^i+ag&~i7tqylo#2+W96QfSg zOewZtJri>as!_rx6E-P-YDk^!efjputgsma<{Xm=cddTnY@7$vsHeC=W|{C2JY7Sc z$*n0WBMA^D{7s}&G6E@I_wYB3^!PD;luG+KPP#LP(~@<=^r84JTN2!Lw!&)EX_Hf$ zJZ@}>Vl%X-4j4TA)m|g_j&_}_b&Fx&wW>Yr3Jb&8j#S*$4SG+yxSzSsA|54%;Iok@UgdWq!$rG;L6d(hm7CZ|)-< z_Zdphw;)B14lf7E93Q}HhZ7E}?8=8BB+y~a16!4XN9HK4k z%)f{)CUET3r;Hy}aC7x7t-zDGVHlbk23q~`7CmfyO$&OWd5h{=-C{A4qG-BIn`=fZ zQa^TNW;|*z9zZ)QA)~G8a91dco|yVF{+OT`Oaj5Y1YL*2+c;Fa z;IX;iUhUZC3}=wHV&E+-eBV-f+<5UsaG_qAXMsBmXjuDQTA*Hh5d<;ZHWnmuctjwY z{g5ZJN#E*LebruUx0J=WJ3%?7RjA~Ri-}4?xvAvKEeWU@rWvbyYac)#{a37%70BU1 zMzrqde{U202J4F+>M%thE`^q*R5%|ifLrFl?6rg92;c~PJvVT-P^#+y^!+OY(aT?N zhyH!0I#tJEdr5bhY+P1}WhLtF*=%w(|BOof((=JPABJm~cYoOz^7#i!0!TV_nwWAJ zrXLxYQ&);135k0W2&^A|mL-kbo{KVDaQ1h2EB3^PbLw6MR0h4@Bp;X*ZRvHuUnK+q z$!oD9C+tk%o)nCM37uCxSINgXSD!XG)w+>K-iva&CouHmR?asdkpYZN?VwCTpOf`*@YaEDiiiadfiT;&|$#Lc&^4{||=6IFKoMN-;Z_m9cxB3;9~!1A%j#WZaa z2fYtgR1%EGD)&x$gI!08gALH*hNGbiqmaWVt(x+aDmakJe|IYUoG6T_mLunuaL+J* z+q~&T-!04oZXsK*f8p-6bn3Wpt(Nb)=zQFCc{uy~Blh;4<@#Sl*g@CZxqWQvm}k!0 zndN*xnjvNDrb9o9XfS7&hfLb-ePK-O=PHij$s9Z1hu*6D_dFO`!&N4k)|?L?0g=Hl zp^~K^B#rLA0-I1T9#@N(Zx7SO9~Z+PI40MH!-lVHTU^cGkEu7Gx{G3cwo~WXUOrwu z-WePM!upuM`-z?O*;^oqwWX3SnROg3bIF7Z;xn7S*Z7 zln?(GY*<|Dzuh%nBL9RDSJ%-&=yx`n44pId<3l3#wZBOD*yS8&Ba*&7{BqgX}>fBy%loLYmy75B&nh3akyck0#XN02Xi;SG(S^E%WnTJSI~Dq@IYyN zt^EYCiuQqAg3~AsS6oaABDP3UkzFnHW8~|7NGHU-PK{kNNPZkXJ(hYdU77@;E=WWT zGSoaNn_}%=)f`=g)Fi8T}l2b<%hgq3&v#Gm2DxH{1pJdjN~vSHV=h9Ph+ttBbqZ+_U@@IBH7 z!vC2mcbyeOLfDvm&~+Z>b6AiO$+Jmv<{j6;9qtQp$c6XUrd$XVv9N|;gI!G&wHNypR_XWqyV(WEQPo}cM%UYs9c?$#TEeXA)_f399fc~Q?%SKwHiz6X#4tOT&y;!Np@lO z5r+448fuORS-mu-a4dA&Bf>tzP^G#64@(UuR9feH-XkBxCfuxG_!&J>Ml6&aQx)Iv z9{w*2fHY1l-)AjX`7E0GfPW}PdPy!($~0d%`{7rZWqn(};GW)ZfaQdSP!<6Cs|`hh z%rD0aP6!G2Qu6S)yN%l>{#(p3GXvgDvTJq>;%$(174U1{ve|9G)xosAuFhP5`VLG`}btVkZVv%W!lQXt)m0k z1dedsX?Bj!q=GW-S3L6}&R4!d`G@Z@(`U?7;7G+oY_G5 z0i-ayCH5kB)`6`K*J+R>3t^?*<+#>X(|w{jx(6-enff2#N>kwR-=H&pZrE@Zo28@~ zCSf^;y4{cD6qHAr608|Fn})rK`g$rlef`36f{Cj`k?X&#{Z|5q5}?{?Kc}lb(}XazSD3#!m7m zQJnaLu}>8YyO-g1>u`287Op!b`v}AsK(aF}uy&ZzHzC%K1JdGcv{WT5q3+9^vKHZU z?=XrsI8lgZ3Bdh`6xV-66b{LE6(fbPCX^4_+~DT%-`t`9bcZyXM57`O_QsQ@Z}IzLzsxdU@9HCnv_y3f?qklh9~nmBsd2 z#@$b}8dJ;LW+?nprZ0scdOdj)944+B&?(MTj+o>EhRX8@K)a_*tiCuTHd74frg@K9 z;^vqMob&WpZD?0OQs((1ROeiX&+=WT8z|ki@E1rGfe?jMH%4XMM0o;^jFIh~{Ln4F zQyWh#>%@c7w7Jl!Q=TD9ys@RsUL0Y4BXqkXqz;%6rf87N`bJJ18!8kW(20CWzQ<%2 z+@DnnZGyb)i|c!bNp6J<9-8o98}C@4$}WmzZArvE$7eB%l3IEHv0PoKU!1^H5j^Y*OXggGQ(_M8LD^&4 zAg!qDVl6h=G&%JozNv)@SiwCvR#2N=+oEo*Iu|4UM)cRo^jw;9^P2r(BA>Y3{x5uD z6cC1~Kr=ibb(!f_1Z5e=f^*M2OrPDvj*~phTlEr>;=I~fSjW^hs?hCwCU@YK;m)Om z%{5Df{nL;=1(VpPo?TDeDIO{&wbJj`P`($1c_DpWyk29}5Y~UBXV3%3dc*GJNqq3i zOnqJs@hfKyszJle-E`se7w7nAK~wrXITugsM^~c6-~35B58JyUpQpTr@V&r0(qz*p zac3E5*JqKBKZSs~gYUDCgM|loMAcyX-OWKxt)LC}%TCrX3b~GdDY`Y%tO#m2B{q;Z z`)qbvg0t}5zdH_B!*_Jio|wdBI3~N2L5?Iv7wwEkd(CSVRdfHrTO}z_% zdA|11?%854tx7)!Joj+49IwHiQ3fw>h@nzndYY#qnaj)no2%kLl3x|K&E< zH~2#Y$)_?6jtj>~uYnEO05XhsN27i5!qdUS|%vVISs*%_%MjVkoo&RS*@8D~M+HSsbz`FXcekfkT?W zp0P8%mH}~4h>X)s8555+vOe1wBEvwqxT#ZOWA8EV*-B<*_f1D?k=}0*=$f)nmW2Lq zK#sU3Is~>=1nqB7I1qAJh8ouxUum8dMDmRmN=@>CJrJ(Y4avXBRmIh|(cIZeWB;ajaxm{~6 zQW+@1Z;AlNJc#dQH>r?6U|;4eZ;+hqjHkIoq#nzlSf-($5c{N`Om=0r3eY9@<*UL{tgBc&(bAoyUbq0vZgm{vaFnDwP7Jnkd_ z**uC>1^(JhyG1IfTX_sRa2feAHI(x;5rS$N_)Mg4#_!~5>JUt2ZE@?y*;CG560``k zk>N;)%b3(T;^wM>zmvYfSse6uGKN2(G1?Wq(*FM4Y~rr8LJ5&OAs^`XpnboRUZNfyO){o`qG~yLrN8s|f<>7hVwonal)oMNP4ZSd4StMDL4qF5Xf0HU zzW9s2tK_gfoH-K`VnUF_XebPQl7ENA>F;5obHllRO(#EARP%#_@$5)PMM=gH6j%G0 zX1`VLwG8cy4x^q=Mg78jnDujXAchW=Eh;W*)u8!ePOK-T8LfXPHb8k|FY*mtV5_ub zDC8Tu$T9vyCDOh{_G0Y|Q`zqX+%S$BxRp&@)<7R%4?o2HEUMz~!9QeTSci>7fknl& zlp|RyQYMiwxeP_KW3qsr zG+&TaxI@qX%KlMlK4Fk3zS=7>w4_L;D8O(woN1=xgksbD_GJ!Phr(5IQN>r>F?PW0x2Uw>6lgr6oe4|^0jVBsjd&=Ie3CZ69 zD5O~L1mqPMN~I$g&hvG(3yAyVPiGPY&ZrWq_o9Sk@%d^<9oKI%6#u0QMr4zBvu-3! zsYi`&*X^h-x>yyQP+#C3i)#ZGYy3is&P!ZS=}+QNrG#73@a#t&DkPSWji{$QtO$lk zh8W+ecD0rHlC;l{JetBWD$dec9g@GuI-MsXx0-m8_2C_^PyE0HnZ0(oKGss0Nq<(%Z`uRMx354gPVa2 zk0XfXa6yMYN_C08bPAAg_B&_jG7H6a*m4;d;Y}y7gjDtg!w8Xh56@JAd@M;D+YF?u z#5+Z_S73&+EHtV$M6;JI5lS4)cocae($o&sE6F*AE`;qk^xkWWWI~+NudKJ+^3%Iv zT)-yu%|So8W=)z`c1|1(BHiz6P9t>j<@PB*KN{C>KoeFbH&9)MEKy*6BSc1~`8RSN zcw)Vgq^dKi?;SdM5btXwuJ|AE9PP#pF;0{@Q$)&o;`>Y798&3>q8~A{ek1>Q{Ffh#UmJ@bvMyet3_Wb0Dqy0!Y>;5k-clK{ zuhsIYj-J+S9b$Y3pX!U_WVCASR~kx)fXJb(QJ~kzy2{9Fb#n*Q8-=sPzO9Hs3RE?g z!xHgVtx+ZfmIbR1IM~sx3B6|uhj$8;L=C%T2h@KOd=r(9+@+KxWUs>^M7uZN;_UbD)e82N_ zFrVwL=PZ46zc`2|(FL{ldwqeP(@%TkqkJfU2D7b^6N{hGC;nW}AD(Xhfh-~KRXfrd z7p%XW$aZ{0A;Jsq9fe+I6wQW|NE7^6;|d>Aqj<5rAaTW)lZkluEidw7vtEzwMI;z#k3M{rY@H!-J{g+CP2AX*aTM%zsEMMf9xGK0;yk zZXPT$95Y?jdj`6vRFc5Ej)QzKDvKHZ?eI?E{c5qk?fp&m0o$88(zrAJ49^CZYlN61 zPmN;lu%ENzfR#9IiG0a!JhS6&`qw?iCGwLQS_CcgL&%c{2?>i*Qbf)m-zoO3p2=C7 z2>H%DFXiz{WA%i9Nx#1r0gTcx`qm6F^lFzhLR9D(=g@_uLXG|E3@7E+FIMvFHmpOA zegryEckg=`5g<=(vj-D_*WX#FACn9}$U@_rkKOCRe;-%WrHd+h%1L2Pf>syaI)d$^ zB&oyyt`4%+>urLZyS&RFpV^2VdSs`)d4}jV+u&ovh|w_X;AMHbo+5-KeJ`I6!v|xk zDO5bi{?A}$CMY~csez{ z0y+HprPn0+lFXM215bfK1w}orET$h>0Swh#e{BVj*@@v-w%jqgNN$?Ea zzgN0|@5n!dy)TIwt=v)`&)c-JUK*9R+KVlv{=^5{T9{E7n-bdo?Y-{1ma7mBOeOj- z4onpv`Od`vZ(0Y1%2ON7nz}MXA8bwtMHQilaV9Y$f`A}_kYK?+NO46Z*65Oo6ug>9Rsf%!_SW0!?n=qmmMqswki9NX z!J3&JS`T>;o6Su12HK)JI)-lx!XGl=5$POML!lAC_;bMJ%hDbE*2@KaYXwj9mB>y& zA9VF7bg?oKa$%3~qvBRpQJ>|q`M&L2}>V4s&?zZ+P4UgRa9@R^vO8?*5$nuioc%6mnNz$okH7yAkq3<&y^0&e5flc0O#4gT?l(L-t0!9Mm7wj# zkE5; zpgcAc0xz|5u_(cTA3T!`w|Vq+4BRaiaOL6?>)FAqt%N-46uh{k#@;7gu1*b5Q;zTG~AL_*7zSuD&TjbiCXOUdVtOk62K%tSni5sz~X#E z2RaA0W&mI=qyi}r8zss63M?%R=^`Y!$QLW7rB2^cPeh$Zm%LsX9W|Jwe+(Q@um^0y ze+$`O94UPp2Jsgb^Q_T*PC=}l=A$_bqJ;#fg^sBc14mSJ@DNl2a|}xA&X_cYoxDT2 z;tsTt=MW{tcNBs~;rxFbF*dz01|BlPyG42*xR5Iqu7qhW6rE}+6ZkIuwwV@nMhN{) zWO{@-0E3T-sRotW&^IW)l%g3HsA(F}98 zIPYv4LoNHuOCWtDgSz+1Rw9ClE4>Tbg8jww>n*Dp0T&;@r%hPrrM}Svah$eZc)4|- zC!D}xlsW&VNW?v9#;#5&G*kY@lm5mt^i&{U6%$WD3G|>xjsxwm0HW#H0j0mT{Zh|V z+`c$$)3o!KH;=VKJOwE1 ze^tprT%|GyZ!Xqi+R|^@@3!J;SCF1<+c~ZGqZr5IZta?}mIEszsR$Y3ii^4Mgtim34Llfc_pvb z0r%?@?`a;;9br^HXiYlFCABwm8Il<*tWAtnxYqu6CH$skQwYM?WH_ zb`jDvMAZ?z63y_8ntM{*qVU{Inn_B5q5At6EPoEqdG zFwoBlDd#C=05Nf~tlrC+Us{q44G+~mp`5%++J`QZ-)i)D7Ypth>SaE9J|e^p3*@Rc zA2~rdS*Jz{{@#Bt!I4jyLNN*_BCn2BZKE2P^w01YYDBDof>U2MEujfFPTz{K37zO5 z93DK3NMnyiM=2lu{RfaAtaQ1Nce+c3pld)Tc2RG}QyU;kN<6lD!k#zsm0ZDL1$wJ% zAECZ0*q;Go#pk|^*N-7SuAD#PG0*4udfqnX>lyE`)!>5GCwrQ++ ze(N!*E8|Wi81Aw)#W63o<5um<(G{o#_jXJ}>Hy8nOujlU(?>W~$ojA99yec;1Bt|i zpvC$hvW)Z9`hlk@XZ=j0UXvc|_IIH5Mmbf|iK4L(N~-C0gygge;aADu>q6o&gVz&j zUNHhsD7nZKK`0ia;-!%_}^n=&vJ* z$uQ7`lhr{jFQrQy0v}erK!jhZ0oM&(*NW9iMuu&no^Qineq>Y(8QO>t&57?8^o|xcGS2hEipv-#Yk_+|v%VL3m1}zcx10zOzFA4%<=h5Ak$TH^)vy-Lnty zUe&)Wz^JKPMi5J_7GF!1y#4Ne^1!k6HP$9uE0+;0VE&7&KJsk`ruY4&ExQV%aK;Li zMai13Z+BTFzyH(Lf)5?@*VQ*Ftgsmy%g2jk?E5=3fq8)LjCp>9<_@l(U*U33u%)fU zOe<6DnO+$a{pM5dmyUnH1xMYud86xtNp8C!lSJLh{p$#5HeB*W`Bht2N9m;ob5zfH z2Z!+ME=f~lodlIjF3daVS@~RLYu(M-JkEWo=qTy?(kcV*C~*iDt=h$&2J$E4jCCHd z-`Z+fDvjErL1v&HiCBsaG0Ku8t7^N172%`ksT*dU=^q~1W)5cM;)=%!;a^e`sX!D7 zJk}BEGK9<}l|YTBy*c*-jK--dQRGcWTteQtop^VgMvGR80%)d>I*osodEL5#PcbHM z-?r;R3leA5nj<6>wb>TzhK5xtiBwecH4dok0`mlWky9=DdNb{Q`2;}PBZ2W=;D#=8 zn)^u`#_o;3(dqq)AyQ`euCjNwOaltMF}|`Qr8>Ooip-PjG!LO4(!WST83nhPm~wyb z^A5h{#+=)&?qUt|%H0kkj~(mpFTEeX%^r#3=Wr+-3M}bJD-~9@kXOBK?`r<%wz|M6 z<*Rg1!C{>|I8JVwskrpML|t=c`0gWi((LEd$52Y?SJ8E&VO*6j)t8+S)oF6BYh=~` zCeJ8gzm@37=Jv{%ZsBi6bGE(z@qB!i&sbqesftZJj=Br%HgwU`ev#n*z<$yk>9vA$ zzMtk6vtxCqHWJlJIq%)cK(qoQYKJ&LyM5jfYFv9FnCKbf(5#N@p0#&2JHSbTFD0H- zJJ0(fD=xKDwLwO9$O$7+*Xe7Q!f&y$yS}I0q=w)YRX&~L_^9zrLHy$ea9$k4jZfQ+ z{LN>LiR(CQgbzuM~~YW++WR}J{}B|w5;4di1)0& zrkD(Re-}8h@kpPZpVN`T^mDW1S=}-|`8+O4b{j1U`qzJHF+=vvn=YWE#{yl&qb?gtZEAAFv*@;)djI)l4p>c2!_ zp$E$CULp=n?7p5hil+E)75O_%31Q#dG`3%6Oi?{A-3l+r^e+C7BK4%8Z2JD9`M@A{ zH$M%2RC*=6ZCQB~>AVSe{wFt${Q?CmtUruW`39E#{EYs;+W7zJUNr1h0g(-ps;K`X zpMl>cKZ!%IG=Wn8rN#g2CBB>@pbrybcBQU$)z!FwQg*9n$KJnB2ps`{4kxHA(oQR3 zmU>P_cEMNV@x1>CT_$T_Wa~bWZ!QlwWa!Or;kp)mKBvJTki;PoE&(zT)!{1QiE;y8r{ZkSi% zetc*7DQx3L-7mLOIc@L<(COQ!*Ze@&lQF=W`3BhGIT6V zxb13wIP(|J%wSKGhtc)B7}xvWD7XlU7?6`5Q@@>2e5#36YkspCkgAN511&^XM9tc$R z#)SLvGpJ!l6pRq~AyQ*18A#aG3g4r(jax1ToGHhPt&>GVe{BE&l#cN0DiTd`;#hvy z*pI&-QViZkWGwAu5C9Q80U5(7Jn0UKRBse;T$Ae5`%Vx8UvA8?&+d)Mf{{))MyO*; zNQ$?pd7ZL0yr~$Sfg4)znb+^i<}24xI|~lXz5^EMfvn{0Hr)?bsrHn4U-RCoh>3oD zdmRCo*-Lz@vePOCdZB%-Ung%#Bqs$lB67s3I|~G7=Dml&P_+N3#Ok>OTEopDO8|5J zfX18Oq2e2t>F4**2ll&TEbC6mVsFs|`aa5EBn?@Y5@9+?7ATthV8S)MrV;PdB6#;< zUAIo;k#P%XlkC2LO#h2o8Y!rYCW0`LBQW7%36|tubzi+Rt&>u8MZx z`no>C+`KYGWEW2Yirf99j#qN2&X6t6~GzM!VnIoE`L5p5y&KCGQm z0}PmZheAmQSb#cV??hqcgObBQnX(vW1=8SHQ}1j7_AmC@@EGD-4nwd5C@0D@<>e+^ zr0qmF$ro#35O&)bmO8f$UPXDsqPeZLE(=k-G= znn-3&ZWff!u)&S&AO5qWLlP~`u!OoRV+#QC%Z_$pk^g(%vKhnY+I}7S#I=tWW1)~zz>(vIbK~uf0vw~O*7c=%|7w0 znf*<{=O{LkZfsAp(pvVhPo`kBjmmj-y)VKia9^o%N7A*nMr7ch;S#3}3H7g1+)z3z z#JOB!x%muYMSuSN+99C4mE3;jf*#n`Gkc`+@V*by77&n88jL5B0cf^{iyl{~3;POU zT%#`hP1~Jy+wFS2GQ-y{rp_lfxho}$#G2`DZiIY zUjB2gcqLd}Q?+p!hbPW`YEXP_qO|7;tA4`2{faq4vgcc5eN3kAj zxm;9q9Z=s&Lffo}qki#QlFK^Yg93`vrAe7cTRu+4U1sy{dpj+W%NXuBPtn-{%^Kp-_r&6IkR#$5BwlwKtH>#Y(oyAydXzRRY$ z$$7<_VJ+|=za_qiR$d^CuD19mi7o9Vu^TT;v)r7#*&(r~$1qiElRuSwQR|s`tMV7G zYBq@Bq)>;==%5q^~CyLUPk6#NH<=~RsFb;|v8h~9o zDW6aY>5kekC!H`L9yU-C^DiF?%&n&*GOLgy>m~gN%`9MZe|-HhbWpf)e0}cT>I255 zLeqcfQd27w=>5g+RYkGdjv=QhcQov1BC&Gd=}xpc@gDrCqA!^S7p^b?8F-ZGzAqX7`6H+ks-KPYo$yr;zJSROV?5Rq!kRtc zFNwEB?tdcr(aZ>jKxjp+PbEo`Qp_91xYqQY+8&qh&#}XAA@TFLW_}4Ei;F{y+b8ey z-nwU0&5t^IsUtWU<;=gdUTYo9PKN47UG1_BW7$dLr<7U@<=X0zq{oP)OJ3NZ?`i^& ze|#n|9T$BdEP=xDgG03jxP~zFaa$!0!_t~zPBRT{Pp&5%>V%}zk>~w5;=q4Zx zkxHR_ydcq%SnB>z@y#jHJpJx1>M*nNUf4pFY#PS@ac=OYzGq6;fI}PVdz0SLDp#DS z)>naFvOLNY#rdhr>QwC1!MDzY{Pmt1GjXYQ3sh9wU=cF}a#pb(b9Hc2R=6oY%SAIo z6Vin8ghfUQiXL-^3$YnG0)w;@Dek*uI<|+HY|ojn0VU_(;%iqpSo?lq>)1f}{b#6A zYmn^9{&o;D;@-J^m9u z5Q+MEfOmS7Dzl4tIrt}|am!z_ph>q|{|DBUnB^THqfqgpyjgSkPwfp9$I^=Gkpn;F zPdK;Kz!6_le}^i|Etf(pGXM6k&%f+*R=$5Y_5T&$h^4XEytELBtgr4*{{cTB`43n% zO8_z5pKdoSLhT9W=~!cRo+nDqA$uU)v_T}`hb@_V7)3`gx*RW&MeMiH7YSvUa@y64 zVRTZ7(KRSAJT02LnQM~UD*)evU%f`=A7E;)`vGE_sP&NUZb5B5$D@-5D7DDtNPmT# z;~8HP4D7@9yw!1!cyZ3ycKUp(#Gsa`Om^5WH7h{*O~KFHY&+t90vU0o$qE0{M%Go2 zPxb~J56s+QHR$VWg2^LFPp6#uS_P*lTZiYn_Z#|m5<3UryYm3j?Vf3C)uN=gygGyJ zTRE!cc&v0etbHZueE4_%_ROf*6uznXmrb$6w{<`hwT?4%D%CgVwW`T0LwokUDcjR& z)6&X{V!$c#Yf0Nn=d#JY(yPP+cff%y)!pB%;Q!I6t;X1`m&e!zr>|?TEYB$&Hy-9# zp79qin*p!vQ!VTF@(&*EyOI9~GXIC?s=ra-&WtexMCvn@`2v}c|KY`F8+lS@q9qf5O?0^xeCB z0Y(uS_>Y^a4in^&0HZOEp+!Pl0c+jX^QPH*UL4p6hI^uL2h)cL{0f+#IUtWA%Ds;8$yw>_<1YgaqjcftaNt6-y8ATjPQuc#aJ zJ*z0*w?)>DmhqdFmR?a0&rY4R#N$c6xzx(;`J~hJGwT<-he@jYpcS1O^;~t4F#)^) z`W;JyMReUs)p+GEuV|#>L*#YHIN*&z-2PnP7=Au_-SwUWna=3KW|cNJ(N#A26oxEMm%5zvJs=4 z5HglBsb$^BqfH|XvrEyQ32My(J-)THe;zeMS(M66R3u6S(DBLxZ2-xb-?{DMj|xk} zR&%G~t@*-$)Og$!B}N6xWLOb ztfPvr@Ef=@G+sa4V84h5cDwDA_Sx0x91iPl~D$q#8|4 zim5(U8%HZH?~7tk-OE`>aZ~wt7J6{gTJW+1&Iuzb#E*Al_iKJ|z!_bJXLYWPE}DmRBD-~eI#T6m%GZQxezDzG zx#b;AW}#%_V+e`YrmVSPn`zyf4!}p0Wa>!rIT)FtdXc(z^ z-~FfhDH@DqpzA{SZM^nPEC7~=!yoqXBe{gMo*|8+{NJDrwDbHqvkFQH-Ovb~5MOQ+ z88`yBGQ5p@ARM|=?Z@DV_i=CuaznxV;=;cV4qf8m1ewH3eHqTfn)bKIG}rWFwDldu zd6^*`+}Sclb?~Us{#F?MX>!i$Ke!^T-1;g7EQq#-QKkY<=EGTM9g831FQX+C)bRkL zxMS2VI0;&Iy~o?-z(q%aC+4^9SCQ9S1G#rnn7&)KB9_V zwRp=WV@nBCwHR&s0;Rc6M$5J#fsza})FSmDX;ao7Jm*Fr zWEhhpDT3&CaoPCGrprQ|JB|>ha(AeF%FKT2U~uH+IqSR|Xq$|0%&!)ru5iS^z$!7N z7sFp0w?~Bvnx%sYAEeUC1xQ!yJ`C{rdWe43n`uY|ZO8VPBSfH@E7Y_d@g5xXxt+iylUscz{K2D=Dv zAaso6yzofRIe%;aIcV4W=y8J1Lr7R; zEoRgIxL}(5Aw=PSdnm~F)l)UKCYb9N?tTYZc*{TaJVlvU$Nnk08D`I?^bdihDw11o ze98_L9++8UJ~~Q3fbFTtr{csARi_h(M~*<_wZfyzX!_Zlogf%7Ul5$R_CeQ?_s(tt zqw#iGItS4r3-cu-A|@)iM1Dp=7`l>#-(AJYyrXZ~8kTsEAU+!TP?2zq9>@Ndy5nhM z)3qFXhs2ofB6=jK)+-lpYxtSvzcV z{fD@8UB2mYL%ez9FR^)jky+b!A5D!ikq7#{FJuZv%>Yv^3 zklh__!bPi1F8J10T)+l*VAAFu@|`xF7_TO%6sJ1s?b`lAwRy4ON%-HEW`|#`8_jd( zX}a~dp?Wss8zG%z_dEn8F-Cmz*%h$1S5DYMVHCUY_=-rXs(7ml1v9SLQv~~w$0MEL zTit?=b@Y88^6dO*Eo;TQ!*vwzhqU$#u*r58ODPW@=*A1&^`x|VQ!>fMY2bF}6jwdc z`nCPD$nDWSw+)%roqaO82T0y=ZSmuT8S9qckJ5j{bT}7h3WWD{$A|4FalIn4U?;Dg zp%jqv0S?vA?+-KSAe}Nz-~HaGNvp^pHR1d0s~&u{zK7mN;#aEzE{M@Cf~DrKIT$f} zd*IT0riSt#Z-HwR--1N<%qRm!rIy-56gPK>FHhyJHfiF7e`g20G`k)j)Vn6#-)!%H z-p39Yod+tYo3#4gJ3sXFi{X~e9Uk^?Nx-WdOo~-V8H!aRT?I=MU z+FEPy{BE<>pSydc+vVEE_kK>dZ>qgOu2|Qvs6+?odYk{3jY^4tAg7K`vmNp6u+yhI zgw#j-fXndd*9-jhjIk_%m(F=2;{UM={2wGrK{3jdF7yhG5$u|9p!{#yHd_3cc(p6zLPAz9WaiXgPw@8vyP6P zwPf0xl)JTB3q)*pzWxD_q*~{{JSZW@|Ei1j3GGi_0vvBc^>oZXdX@B(`|{gyvU$S_ z`(Ip0$(|lj6i3sYgY-F9F3Sl)kSE3Xgzo zYXr|?!C#;WDL`Csu-1L<_pz=b_#C*HN3Dxc3-MVU*IFjDm@rez_A_{BBphQcpfnSq z>Z_gv7EqTNMUy93kHq0J>XK2FC0|vD*%*-#j8QuwD9u~_E1V%FFHZ{PJh$`Q1iyy2O>YWLz%w}w>Ro^TopibvriM0 z?Y2a(P!+UZgj;IXi?!ioE}0u;ZcS+!hR;B42{rDjMXE&$N!%ybc|3jwag?Mvp~(B9 z;)UdBnU5s>>6j{vsr$T@3eq3MV*=kVik2?3_Y8d@Hko=65kFLlDh^~7?-2r8#8e`( zktrn#(Q@F--es8M88lg;;C7k^f1Q6z8Ll>p>a>Bnm7ol#RZ*R#n(hGH}1u zJyyAh3xT-cMu?7t5H_g?gcgd&iK=bw-7pOllV=rDP5$E9&vd|dYt8E#8iyLfA(3xi zcb#NaEpvME$$k*pinJw7W=7GTVl0vtLv5;8OKDHe4GJf?U@V*)1ef>)Gj@HA=n zuc%{5bz-xA!sfXr>H6U36@^PD#sK=CV>fIbmv|Kz&wB%R`2~V6uY8J6Hg#R{+&K;e zmLr_=z`&HxVMFPOvAOug!_|CYAGhQlds!>ak+0DT8(+0{2m4t~KH-Ow|4fjkO`mo5 zGK4PxTvz9Ryx6JwaKGS*5ULhCLDU7){yG-DVuyXMms_<768QO!?P!*G*Rm3`!_-F# z{$CFjDcODYEgLVts@ASoyh=*t%cQ6UuBI}!2f)#B(jhtSY|#+?6A(@EPp@UWknx_{ z){Z(nb+bh(2@?gE>eo+^R0T^IKW(aFG=9=Sd;aEN-RJ5Du}EMQ6axF>pd6n;r!my{ zl#|Gi*!~3y)T;2Di76OPgJLaX#U{I-y>IaY?_M6SkcDspOw!N69Rco-Ub57=SaU%1 zlA%wB$RKkx_YupN76JW4Dk*BSK`fV*5=uRp(f&+ki1@W!f6lWg!dGK0VZzerxA26k zTS|dJ5{Eo2=C^{Es2;IA*ULF8>FjkF@jHWUlE-Bd3dt}&$8CQ}nIaQQLkNn3a#vAk zGF%D3hc1*XwnD~gS2np;{wQ}vzEvq!K=K32_F9gNN5AH`M`s{OBo_=VnAPoqVq1b{m<(dss&l8WDDjIjh+yf zsDsc%GukiP_r;ME;UnlcuM4zc3U^UF7Z7Q1hG8 zY;CXRBmBQPIuwTdId;tmm%ZU_{7gvL_qISO(UD@BSPCpGt-4gQcx$Z{VWCMgud@H` zXr5i@KgAlVInR%GcAUq-=fB}FM?7-bBaTibeh-O7Dh(+o9>K+tE5$J~XO*#&H)dYe z*^Ul!msJSq)$2#_lWSMVxU=uw)5$scM{K6X2@N{T#T%s^hEY$=jm&b3zB`L8u$K1FuAGH#h|DZ!JDBy*^gWkV+^&D?}{o{V#btQ5>$On|E6jH>dwq#H-m_WS~ zm4DnDz?+147Vq<^7BAFi!bS+#ZyHCG#%`H%Ab^Id_Qa*j?FFMb74p*u97HpPS&6|P zeOg(bj#aVW&N#weC}w_AyEl-KDMvBtCZSV*W0*6hakh&h`BT#%K-&<$JqBl+MhYC+ zLGt>&Vr+lPbrLBtmyg+}9p#<^`b<-wIfN`+7u-<%ZBHy*qgicCGbq)c6{$yoIxTp+R=)xPKDi5@pGby?Yc%<;{&=XteF73fa2lsi(_AT;ok$DrV71H}p< zTm2KU-;6lS^NR3tV)Z)`-fNmse(do{6w!3B*6>W;E<7fXFeq07FZ4eQptpuq_b!}! zKX&4K4X$AGd6T6#rZmjCRHSg!$qMU8+ z3*V~Ze%=s!D7l&%o_7I@b&gkhZ=GMgjoHP#0-66aFF$L6201=$fHypb8mHo3w>!LZ z&~EgG{e~O;0v`6MUMVSscMJ{f{x4AcZyW0mIm#cBNYuosCq@d@(1yFSZ`sgiZVy;Qrw( zkd9!a4pGxBF!RIv5O%mL8=bZCR6)3b_4*WZrs8Wr-M8riB`})lI#RxP>8@~BNG1Xv zPepI+h4j7RvhQMc@xO-ZW_G)D-`K3%r!!B+Ugev%Z&WhXYJsJXxpwX7FBuQRN>||k z!CM93IS>4VE^hR&Q&6PCw6n;3;-v$i96*m~t^Y#x+&Pb+dQv2GH{mUOi__^()>&6- zop=SrRb+Y>ayM%Eg=QXGf>w#CiYj;mp2VOtPunxg?+c6(L5peY3)gsdpfDq@!wG(4N=PA?A37tvRxA?CQ zh{;I%ayi`Mx?Pb-kWOgHtL9mHI%4*p^8I+0Wx>#<)3STlJ(EFJ^ebBRf zyi8ci>n8Km@KoSkUG^Y3{0GD?J~|n|-PNr=GS0_?WCm(GOScbpzf7rdKBrK3-4GBP zX#bo1co^U6gkvs~D~la~mMVppwc76gOa$Zb-?Kfg zqo4}#=3C-J*V`nqXwg%UxN7OaoCQ`QfV3ne3&M#T*$}SgQ=73d1&1$uBZVJybHP79 zK9sci0D=(DnCa6i05Yr`SMJ#9qu+)dn4QlnBV`snUERc z*Zbp9A;{lJI_(DP;Ex83i-0g=>8``OZZd$K#t7W@Qkqm7f*1vS`K`WKhKuG~x(%> z5Wpp}Ha??nmpv2zsHOQ(`0*lvuqn3%IDrK6+@XZ$(n``EPwZtga?Y>^pHfUo_}+Fl z%Nc5O`7?6(2|l)?bvyy(aP@yik0S^YhP`tM(lq@7b_n*^ZtR_{v6d-(eG7|8-+!98 zlRP2>Lh%NoA#njmjh+*u-G-@z8g^=Ra2)lfCK6qECA5<$wAz~<_I_@XD?t%I$91SR zWy`lJjXD>YeaAP;yus#jDU4fL^C&ed@t}M2g>u#4JtQ=9f zYehr1{pBkojU3b|n$Q`A+kFJAeVt1H{A8ZaxUHA$XkJVZQYVxNk zJ=%!c*O%>AVSd>kgOheb*(o-jJl?J_7WCTn{4J3%s*+plGWUm!FBsV3b6!wa)r!;n z?-_Y}>IdCC-VCa)KO){yeD(d1QtC9N_~=>++5XBhWg+cFJJ86JtIw2TN@cO>$DXIp zrPW^-B|1uZ%$_mw{7OXQ*mr}Ze$LJ+&eXJ-_dj;(kRe{yhwkwJ?<|MkdeZyo|2mU5 zs+yWqM=TL@*~~p09DbzbvOFwuPIaF+3nXpAVB8v4SU`cxZZv2Ol2fCKs4IDSZf8DM zJT3A(s4rijvw2)uhqHaZQ5leA=M?X-PJ0VQzEuD{1Xz1GIz?JM4iH62zk3o%GMD848$W$dyBQs3R>5vz}^C=mx7>g?_63;J)7pJRGS z`J{2T^iYR^ldp`F) znBN_Y-0nT03?-gZr#GKVO_V%YS)n1)>*s1WxNF10m6B0<+{bzQFFn!%_(;^;F2cPI zzeH5`>t1SWd@scx7R@p3Y^_m?elP_n%+knf9@{n!zGL3!y|=59&Y%)XnxpdJzqZ;Z z_Wdj~`6*b-ao{&;O8HnlS+RL8M`R5fH&%O&;Vzn$jVNDw0I^2+lENQ4)Wtt_4GoD% zj|L@eZU}UxOqc7;b=cs_PkOm=2j$Hi_P*hs-Li_!W%MNY#{L5#_sh+k7f4ywk54D0 zT{_qSLJn5y&qvt1)5EF8rYd~+kJ=!fUjhLE>%QK}Cw7t_^>op86bWZE7gBoG4x9a5 zjXH%TR(!-DOjny-#_{82s3<7VF+{wqcWMsXu(m3 z#iTCQE?8R(oWW%qwJD4`W+E3c6 zgp5}HW;bY%`>E+G4bz}}^xMMEU006se0P#Rm8IzIs>VpL{(xuf&=naldr@FF_kve8lt;Hu5bV}}2Ke+S$_YoUZbt2THWPYw zEUYDBI?5Hy(PQY;>8I)80p{J$Itn+AX{RmXro&Z>_L|`licVs)y%g=~y%9c#BR-FC z`g}9Qb$Nw%^LNcGHhIL&4ocv{NR#BGZ9n2929n5H+Q)Z5rT%l86h%VSW8=~JBu&nd zzev(J5;Sk@71@-jX4_A#&FM(S0{NtHMCt00j^1#NYVj7|!|`POH5txo`#YwaLH7frd@ty*?f*f zbi`bF?V^hg-N^2Hg5*&wO<1~Ada7YZ^Z0xq)GxTwae1G(zm66Zea^Q4GYB#ws_h;s?Ja^E|Sk$82OwWNma8I zNP#wv`NX5bWM1 z9l9=t^-F2*)5mo=N_VzfYQ}AgU3NkP>oVbi(B>JR^|xSx3qU1ontNQd`_^0Vb>jYN z?e-<;>a3d>gmMD>qCRz;&TajUo6l2y*!`QKW4oTIW% zrDGxZwfFTlh{^M0i}|g54<bj@Lli`@`UOvE-GGW3yM{3`-gvA zooUJYf2mRQD046>=ds3#rB7Ni0BS+OUy!cRPtfTIj|hQT68V;a?&H%9^lHQF5r^dy zw)FxCq(8o?9*o>|a}2tFQwscwSm`sm>XJWO=*hj&gnvJZRN&^|`M1g1(<+n6*sK zf-9AwH|5q4`?r&`F&p<2e(HnyHy!`RIREveQ#G}KqxoF>#BW#Hj2{=l51Af8&3GY( zum(65IR*S>Nx0$5Bfd2{zI&gH@;+`XM1-!aV9{%RFv-vHw4%jQA{CaH222nH6RtMQ zjPjY)y#u4F0fVF|)I=*T2`6n?)#S4yy#pE%T?6B&bBxlUT5wpAUxr^XVKVWvjbU+( z40wrBG3!SljV@1n6-{#5LcklliY^6+iou(be%Bqs!O;H$m)U>Vpt5NeJUc*TPSc%lNgrS&~zz zkVIC>XT~&?3%Yj1T_wEal^uaZIZbc0V9>QZX);R;F1S2AmtV?q%`32 zRKhX2CPG`@;Ds8TGE-C|ha?kjMseMj2K|lKul0T=RqAL30c8BwJH+uFuoc5g2R_fQ zKn%HbbV2nfek1pJQTC|Fe~?c}sZ65D1?5QUeO1Mt%aAMBKFM>psaiGCaZ{@E_F)I5 zCiGiM>6aL|7A5}dkYuj7PtfxiC@$3|@{kqK3zmtZV25L!Wiv6^Bb-NsF_FZ{Lh6Ue z!;jWx8p%*MFBiv`%)x(|ajZ;yCGc}WGx=tVSUEem_vBKM=6!ga??o=V_RigT?=L{HzRTcD3;Dr#Lk=dH^5i1Q}Z%QL3o2z z9R95#D%@5Vp=x{y^N&1N`Rr_f=#K6H%V;Kj?;Tr#v7{s6jG?CzoODAeu1oA{_iHYW z_X|eOTJ!K3eO&4!(qzmxV%b_afN-Jp99xeb+R zo_Uwoyo*b*8KKu7$(3U%QU7=qoaf`!Wt?kwi1kqsUFRlx6wdn*oxAoB?@{erSsW#K zvHjQky=j}{k^7Gw{=w@(!imPsBJwUcXS;{oC7R*taw|s;_KC=#m^z>R6{LLR-7JZY zq>9znAzx=99ul3Gu10;S^Atg*;=-61pNRNlN(;nGYKylOp(mVAh>|+-$^#xa$fP!? zmLd;?Cdqr0^XS}gVb)kCMlvesTEa&YCcAo2Z|FAa79@kWay<~IA)QG3S8$r^4J7=1 zV;VY5$0RWmmKb&}W&b z8-+e`nZ7KyIwkokkHJTicz)zdqoI9%XM#sFTK(|liw&o*xvDD* zS@?;^AA0IC3@7j3l=V`xrXFe2A)P_5nj3E9ieaA!6{dbQ%!B3x#Pm#%-Na|(w6#+s zYv1`!hURbW{nNFpS;M=u#=LH$ZqAKMe9J=msl;xq_)PxBI z@*4!<5L@hvFd9Zn+>LM6s@In#=Diz%>?&j*i;I_Vx|ef)q5+ShmTt_}r;}T;{07j* zCf6lAL0tj${1G3+X=X@DU^!#n5$d{v0fIcSl?8n?)>A0C<|-G(+u9W=a@utCM%<@s zi@~kIjwHISWCy)ZXC&83?tjm2`lo_xl&dP$ZGE48Q7(c_ACl3*Ys zwhfaApB~e=h14c9DkbT;f~R@Z$#oT!y9bZMn?JhC;iWX9nuBvqYvH=bnM)yG=cFaR z6@IWuNx_8igG*2hX(;JZlo%;;TqA8sgo>9|r4@d9U#0YrQcX+*lL&9Y;fKJ@C&`5; z8|9vs;$YIn7e5qB{;?DwBAqGe@VRORwjdHH))%d=DXvmPcrgpa_Q$I)$KyXfa~`Lu zXzkWfZx3w--WMuST4a|<;!#eI@0zvZ9nTT&j@4|dKIKp{Y?6YZto~KutxzxTVUqCo z1o>i@@XXj|A*-3@jlCc4k5AP4r6a317F=tBkQGKI{Eg>e!~EYQjkCh{+{|o5{LaW; z?3R{Rl~dPlT^~l|M1PCEB#9-(f~@$|k;`iQ%f#uACdDQoB^lSWJ+`tWi0`J$wML_W z>CYrX>)|u-gDyRyud^WM3|~2)ra?q_W?`?%-#AhXo~mHb_2C#+WYVkn$pf2{@VyQQHo*D_o)djnW=4H z(0Mr8A%>G)0p?hGsCv)%`DX^3D6c*eGylR7PgB70=%t8PFfw&0DM;YWvTNOXmlIn~ zJNhu(e(QY{!NX-v+m{sfIRPqi0k)+_Eg5D`4j1$4{fjcI^7;;kg#pA0^IGLmB=3if zP5#<>mLV9<_C4(rg?@eDqUU!!5@CZ*-_Mf^8cnB%j~G=%zCS%PauYm$GvjXkQrF!S ztSxY{z(L!`rdJ@xS|m0r7x;J*@&<-WYn%p!Wvfa__YCnl_nR23!VH}nbj)t0tboE{~u8Ywv0%RdN%f>(ByR-Y12m#_F$ z%@1oS?W>VYcBnDNB_o#QW@}Wbn%%FS)DwD&Fe}8c_oK%`HUGj*;uMV5(3&0;R^Gk) z6Pdjo?sJrf=C{>))O!6^#jNqfty)$LV@>ebRnOL$RC8`Qi~%9wwJa|$?~i2(;cU7q zk{kf zOLk#3N@2x-r?>!s*`{DSScy*;;dvPROnly%ieGMiWyho;?65$u_TCpP6?yG&q|KLv9CHx=QGZVT@6 zbp8J1_2cus<4g9{3^%)Qyq4H4Bre~h<8t$g_$5#5UVNUA;Xjo6f5G;DiCa%@&%kv} z!vAN6XiX8`p!y+pnLge_)fv#ZbWBC^WU2BZ)qSeXD)YaF3`XHIpJTY!&eKB=+vV-Z zBX|@_?>&f_su!jz(bL&KboL&qW|QunTfa#02(z&cM-M^}pQE^0Vw{AD?9vm8n;1=8=xCRZu-3hJ@jU>2xkVb;L1-IbtuEE`15C8tgxBqj- zxvep(>Z(@F^{zReY5LvN&vFxeBbB0$IGl*lO|uP=VBnxNV?0t_a#dcHPVCP|D=u6N z_@6M^xOTkAl9g8mA_IJCnCzlrU>G$01o$dWZIFwoMb*v{%@24v#0|#2UMIiYFVCb# zQi%n-z(AOdbd6p&{2qU`6)FMxonYbV+66K<-O)XVr8}=bKI1W8MEB}^VpP~Xpteg@ z4$gjM_UuZkhn9{Rz5LL&+d+cza;Vh5Be>4iWgsW|dv7yX{Qh4q1s;$GO@czqVo(Ff z{TpVPg?+iP3Mw%Rt6G|U%W7j)Vu(Cumor4m(4e>;a=4){#y0V#vksS6mx3`Cl1f>1 z1FNHK_Ynw##eWFbN*t^4H1zm@fG_$;1?Yr{_$b)|a~)yd9c%4Xe?p}3>q$UFeGa>5 z6KyW(cfRl};VbqijVB<=0G*_=@l|u+vQr6le$EC*zgKkN@cupG+2v1$dUFyr^I)DU~Bs z&6K6eHdWkAxS$N^0+(>@UiS7+Sw@ah_P~PQosE}El;OIFayueGXrMotf1n#J#-YkG z)g*IJMpOLdRy#^MnQdRF6Bi)15+>1tTp|^FLg{ErH;fHt`ea;kGY_#v#<@D3BhdwY z!)L&LIcD4nW2wl#z=1_RlMPg-+!n0ynTz-D(KA4aA#EcLK%3Fd&a zN}cB{P7F#cUFV`S#rS|5<{B6ggeNeV&JkU`7>hk(|8N_TY<+cBM?{^rEi0VyYq0G) z%8z0!5*#*BtAvz~l}!@+UE}9_&G=86ChU{%#|n_yJ$)p%+izHP)X5s8GzcFDMYPmv z^#*O|;^k=%(+o#38P!WRsDU#nQZf3Wy*PB5gDqem+|6G++(5cK`M{V=(6J1drF!&s zAr|G(aVh@=X5*&KZwO8ViEl*aahdZlkrxij(NNmXc@=BjyPfTc@$syIf2!>9P!D(A zL`1FYCugXeawq8}_RmEOxi8>Q`jFVY<=AtY`lX+th);pdQD>faCa)o6*Tp+4X9aBz z?Ifs`OOCG14_y68AZlpu>(i4H+=3r|N1XB$RTKIthFO67_O;|?joCikkbAk;z$%v2 zuT>`jF>9O1OAXwbHRkLG11}6tby%1bFe7D}(^|lB*9A)`^Z5^oJ~0Z3wy2pg-N3W$ zCan)s-*BPgJVZDI;DIEvOWtd8vBwNqFMVZlZ35MLn|utjF0gEn4E2%C?6>bfY!+Z(UKJBP9ShLO0zdJTZCR@*I zDpLBz60=uJ(^kJ$fcKFd$U85&t8takGqq1vxU(;^324dKdS*SSvgnA%9qJQ$81<6U zG*F4%P%~HlLaRiT@ep%P`>4;$kK?SkaMz~+A7A|&CyAX23nzJ=GH)`6(OACKE$jP= z;vQlcTwKQm|7R(TtmqUXB%s$=p3*g#2y{bn-DPC#YYK7?Ie2Ejq(N(OM{#bqH;#6R zM2iGRa|Ko_nWVJ;IF}q-mLakhd({bcoius2jo2QoeqUthgZOtc>{euXEF(cVzv`mA zbKt5toW9b^%~6hVSE)!qr*{cKuKxh!oE@OtwV8xOaa<-eLpgau=>V+0kHgVe+Cq4-Q6zWKSxrZL11e9N=eg;L`@O&hVEOBM#gcM})f zKDTBiaoVM|5eG=lW1h0$3PfgLdgjq6s=mh2uU+97z8I6Nx_XZJqDukT$y)J|+pxk= zkPBzK;P%=9q&>NjdeBn#i9l=az~j<0;gUlWC#l2`Oa>|6wb;_9H5YLv<)qnhwU)H~ zY5QJ7K)KLF&SBW{s-^E^oMS!TpL!TKAJXF>L<4Dee%b04e7p|1Lt?z9TC^*fCOL@PKez9GTf?^cjU@TAex zK$7&Dh{QRG&+PNDuSSl6HV$LJ1kXB5TJ;tpn@J{L`urWWUdxv)hP*Al2)iDc zzsR)w?KmXvi5wJ@8iI->PSqUB%X*@He#3Wyf4*gvW)(O|k;`}reWYOk+a-Tedx1Qd zcEmJa5|^}Kol@R6j``eb`?H*osuDCgM&C$<@grIo)ZuCw6t$!g_!16H5`H#~?h1?M z$dl0T^(=5$HtcF=ye*=$eAQG=P9lBZFe%|c?|j_W20Dv>%%aaji+a=|}@#Gnf3b%yP;kQPKuSi_oQp+9LP1`qE>1`cs5?mvwtJ#Z*Chwgm#}NzCt6 zfu|TI$GTZgr7qMwtz&K_ejfDnvKDUT3<34lYt%nC*XTS{7wD=#&1qG~C^WI+`KC4a zR!Jr~Uv;xzwyBs2gg3D1L&fwlbHA0%Mj;=EKNq0?GAXMbzcKgS2)^&1=i{}DVh<(F zoDIptU&=2Hwd`}Hd69kI_P>q$?Mz-n`qTv)PU1D=V0e941Gip=spVsCD1aB?Iot_iS*9 zczuJT*>nnp)a*3pCV}zX>-ytsP^hjs%T>th#{6%VP`_n{wG+;udXITi8o11{m}Y~I}Q=gUXc`T0{5-61bP)GQ5O>0u5!=s5j1@=ATVBTd5^ap zwI6{R=gN*qnbHIFVWjXv-A^_Yvte@U(c*#`lf#HrC$Oq=sdX!FI0*Up${z2;gAzlx z!Pa;_SKlt}^UljkQ@!hE&qZU5Yb48Nzb3ivMq2_Vqvv6QiulmV-da+~hwq}Q7Gu6= zJ{{rfKhCpZE@O}6mhIo#&<<4cyL~}o#JL##g&cHUPSID65)OJY;`(l`gYoU;{?BAN zt|!F(ugzdf`WN2yw=K2Z)%Nxn%=p!}$@RBCu8%Y{4<=0iXExfIl8WfN&?ox*`acNU zce8M_xBXQ>*^{IHxxeC>@3VyWxOV%?|7VuUri8iD?8fx65c5KKYUy(FOtyYO z2CZ$l*ZofdtKl8ar661V;lIX-Z#}TAu~47Wrtub4KNi;SPA6X~l#|K*8o)cc50#CGN=w(~{uYj8rJ4A1DCItz0ZP@b77 z7LHgN8(-bL#AbhrbSj8nm5d_!UCF&kc4muwHiUs@vm^7ulp{iJqXkL?a-_SH<**jv zay$ZkYrW%*^bE?}9>Bm{ zZfeRrddksT<4BQR)LYqBz=rII+-}%CR+&miQ5L1P{8W(k0xNLeGmhX^hhqmBa-0)9 zK_VZXXST`Zc+dN|#wfh}g+Z{QL9era;lm;K(%%k7h=)r$jo{WAQ*@E~dSd}zD5Kop zGnh0@h>du=RgT|`4NTykkB2cwCjLx~Bb3@bQ+kYXd zG+j^}KDrM80mN9)#ph+5gaRF&`Q^6=AW=5|d)T-zAAXU9g=`!fTpm{KptD8Q+NWN;oO& zi-L_os8$umTdILbuhVan{@oD>#Ed+#q&4xXbXe@OM&0=oxHEy{r>|Esx+t$tMsU?bYbyom7j+6;g4>37*H&I$&o$dLqTn@74Cr7wTffv-k(>&B|L zWWGRG-?gYzjw)&?X@9Z+WZgp708XcsU50cV-pJG3p4Pq$6wyq&6<;JkCQBdtO5?uh zkfekm=u3a=ec$TiDYiCx!*8KUb$qoJQbxPD|05zL7rn2znm@|6zxw5NN`cKquVYp< zJ&>DlE5r#1l=xoPX%d6HlCqi&lZf6IaqI|(#D58Ua$+#DBvtN{vT<)5q zpAVn38)l!jM8OwdOtgC)UIV>3+9t~7CyfbMD-dl*Iwb^p)RTIgNhx0?_{}_V#sLx8 zD6N`G&fQP^v!I;HHu7a9|7_!#M1||Ivi}_xe~cJs0XtJ) zG}RHBm>CKM@{J>J$xD_OrY^>^I-zp&JkmYa4suSBZ?w-Utej^cv`Yc~bl=6l6o1s9 zF25gIqu&aTSWGqYMNB`E4|G0`)ifhw{VZabgXmd~&YcO_yq0kE(dwssWz$eCCjLjA zf-R6dT(?WcewNr>PHaILA5pm#rN6IL}5^_ zCx2z)dlHmMH!OLKdDN3U7Ka?k&ip`H%tW)7`!RPyn*D}gzAF$SpWt3|d!!)I8?x(w zF_?goUrU7a(yx2f!$M#R)ed26(lYs=QB2`=s;-@`<2c`E{qNs&u^aIR-95fdjf+3n zC3f*b!+N+Mu?l79jwUM*oQUDbqAx^4dATFq=heXopGS!1q~ni;{X1U>%uogw{6r7y zrj=xg(e3KMr3`MHJuOZB$i2^`Bp1}km17x3r~7#`%Q^l(@BO4QV#pAy7T!alpSN)% z)fT5YT&ht2rDX^};8u(>K3S?s(*2A|_!rs);DmxlDZ<=7qvuxGg8Gw96>AdT?4V{T z9Hx#Vge0RIc8B4J(GwnH0c*JOf!qluN((r_ps`YMx+6(tTS>pTPTC7gw-dgr3>q_X z`2b?0;=%hktVS<-+PS>`Tgo2JhEiFpR^k{8czfrlGmr2QzZe0Rk!BF=WKfl)DjDZq^{xMS;^?;-tL=g#-XeJ87%*#Vm4F{ zeO`^pPVAn=Me(zk3-KFe?3C=~!otcz!wuft}n z>z6jMk#kEKFNqc?tr(bu+KOF9>}<;D;anX(|FtW7$QXYS9^kPRlC$3}5T5H=t8J<% za%SUH@XHFRBfD#wIr`PfBl~*gs3eZ{TN!zL_tQ~Y&~M)16(iDKFymIAm))ZeAS~3w z6Di=r%1{5>S5z2i>QADj518Ctud2PYtQak&ai+^HKGvwS3ryMu2(ZGG`=<#1?xnW+g#W=4eCo-st9C;BH22{89x+B;yPGJWxHFBQx#qdk z|7x6>N?o9z(8rgf(l$OZ-{7z!?=jFOvXLKysaXfDX7j;l| zkLoxGdCh&fv3vbz>UBBn_@)#4cK+fm&s@RsUw;Cd$2;8C{0(wwYi>^ai~4?0G3zGFrI=5y`aP!iL>r}=L={uFm|4P!62;{U6$NsfTxa%mb<+XveU zLiW#6fB-l-{*cqt)AkCK%pf*{)>Lw@?YPag6F0BRs1}`UT|f|!{t=OB))@&l)E|Nt z6O02xh@iM9$`PSC@knf7I3=o)04q9O)m)X>1OSnO8H!QMfELd+X#VITBGy1^y`o!BmEj@dpi| zo|Tsk``mM0w3_$r+`AHW3IP4P4mmBfNBM55Ckhm}Ov}S{DZEj#y=}QQ_a6uH`5m7a zrWrInTi;I6mx#l)rf^c2D|V&p0XX35VKgk?xdTCF@JDkV@c_70gaDL{;_P!)qqm)2 z=U<5TR_#TSf5P3BWr2NP5I=JObHIR~Fut0@!;D0bc3>Ie$8s>b+)hs@f1@vDxYFkSR9vB%>+t zh-Aps(dh@suH(#srZI>S8md#sm|H=VVtW)+$K=NAYLID5OJEOfX&`Owd@pp<=LH^1 zgZ3vyzM2D8w^-3HQ~1UZUE<-d{S%>n#j4feSZ>iy_@;mP2>8x|l%y{eh(NLL^T^_{9XoS3mtQVc5zLe?#)==;K?86!w{rE@Ha68D{{ zvA)nmMb-Z6H*mhOvu1HO-@!imqVl>ilTEW~^B1p&!v~l@BIazr0K@?BH z$Lu~GuD-~RV5+pX8Y*kWFX1K85KT&#I5#SuNY*D`ficc52Bf+rZHSYy!s1z(Ez(BJRXOwoG3qGmGUj8i{!0?P-Gr z3Vew?lqxDswGlf!=s6O*#&#L56tn!cZxqf-oTqm;@?Tj%THKp&EmHLKt8bXkM&7gCQQtI zOb79M^{-{0X|T@j-QTQYR2a;v9sdBURShw1#QCIJK7IlmH|)+Ih&ofc%tkTsQWZq~ zsNd@E262rDyYG%=mb)J9Dm|*zv-Hsie*~FS0gP9DtGXZE0@hKHE9PS^8j#jZw^-&t zBii+$T*!zFb|(Ho91b9}zp#7!tf6`MZpX)V`MojpEH0$R-s54l`YuTDaFS}MEv%I622$dI)^ioN2vkg@fp9dUnPM})U~z`PJ} zu?-YD@FjYn{Tp>fRfQ7%1;e=g|7}&;8%;KTD6KR zw;#Ja&=_T4Vj=y{7XAul2_Ju~Rw&49XAA6(Vp}RXPf|J6w6~&Mplq@|EY# z!tivzA{myEg0ywSY+eYAPsYcg_ca&as!d`g}u zx?nNk-YPlsLR58;c^v!%a~eZtLx1&LqD2{8E1yCBFcCKOuR*=4nZ4?;APfp^Q2XDr ze9_y%y4TlrOa-jK=S%O$4a3*rgD3xk@xmhp@~mAT%u!-Bhe~_W%#dEY2YkNl;jEb< zc*r$FPHQ_2P8^}^YSE3LI3NSkG;{DQ1QD`*r7wq1Q&Q9V3A*$A)BD8cj9F5S;E?2N zYv|U$S|?+;_Z2yi`sCM^&g_Gx=(6)JLrL)YfC#exc5^_FX@`2iwz}qtbYvmX+OPfU%m~gWvsF{gUD?>Z$Cr27i()lhbSHD`%lp z4Ax#r!5^K{rnA{mnCelH?RTifDc_Fa+CdAbO*@cX#=wRAwu@r-l`q-fC}KzP)ck}% zKKcp6gg22WO5Gq;s5s#)t2<(P>ycCkj^JScsYI;K-G09_fpmY-{P|?qDZkm8&T8@O z;U6GPV_;#Ac;3}7<=G;di(nynpjs$6K#s~e*FMwu#TO#qa24JFCxZ7I-f0@~Z6Wz- zwUypRhxG(Qf{LfVP1q$jxD(vo@s31Dv%gOXaIY)Sl@tv9+LyBZ{-@sRwLRxe@w zc3=LNLm59>;m3jHDI#)GuXoR_>cWx4dGr%zUyj$zIwEs5PaHFY@gp%N^Y`-XZjitm z7Mw7iW!NX=k~R8Mac?(+2K%{|apKLPcV=?G$ZhqzJ@*CrPG&fnFQA8da=wa~G(D;< z-zbr2F4fQ0&)7C9m*#(%V+6I|8=vCNHHD=x2 z-#^^k{x5Ce|Ap%^%pyN;(EER>W*}zk{bt0)OzZrT##@mS8l}5K>Bl&nTUdE>E;<^xCOMvcKn5PEV^bi1R7{o=PH-rxU_1sK&a(Tsn&!Fe-*_oxQ}`Ab z8sZZm*3jz~z4DLrsAB%PxXd&R4oX6engmA6Sc)j~Te-T4Fl@&}vLRf^=1t<0wF5*V zAJ0e)5_`8y=9?5&m&_LSiB#sPe%P0OP-(Llzw_ojErOOy9ugFsT@rNn(HJ-Oh|b8r zKkxQm1%>bNnI)j~XoD!!Iq;m8&NC|bN5GJ8k7h(WmqlcNHR-+n#GiFcN+-F^IuT?W zm#bPm=%8QQ8p9|cwbxC&l@N^to1P0&PW#jP3>(E7=I*9tn?0a0zLN%)7}clbf&C97 zWD)+WZ6VF~Fzd%ZQN(E!j#m-4o+`VZv7KC)RU{ZVQsiOzSghxFXp9~>O{8ZqO64+N zQsI)R@eTz-VsEQ@T~4~2!#&YuWAce?upp@7k(cmTbAIBmvxxVD-L_T?Hse^>ja455r;PaSfLG9a=Cpp8?ygb&9fJX{p5gWzb8ae!Y6U`+GFOw9Aq7I6%JO5oThE9#q%9C2w{ zAzU~77BwAdH90Qzv-H~Ja9VDb&}>+i>oDtC`_S<(lv#5OonP8z)P+KQfbF>7{%C%0dX2NP5bC?9SGH^L zVlPEg`?#kd^gWW#aEU-K`iIf*fx_ z1c_+)sdD%BhN*a2`YYnsI%1~=_Lg_Fl=kKGIN@^F{v%bVS1Prnuk(e#_VeO&F~5l7 zyg_sP>&@HkKi9)J4|e4gH4-WhmuMP>y+%5tYxQ_f-~b8zg#7e9KvnR)g+~mNwgFiA zGZ=P&A^(TwqX)rf#(j0#*-Q$pi`alncP-4aab|2o)CC?~a9+(4=~lT+>*1A%QyYq> z0oEJv_cU3eH%;)Eq%)Rmw1b!t|X{&SV}(2hIi#LmXcIXqt{~PZwXoQ++;7weHgRX_E>QDF3it zPgy`FKStDrmowB2^A=>6^?RdKmDAZae+Zk=u}IHp z5{+&83#xzQ#oc?z6OCyP52l%$U1j2qfuN+WHjfTmq-e1{F5TEENE@E63=9dT}u`!9?wjvaO|B&2JZ(85x z^Azpdo+sch%r+ibDa>rFTWyKoa(cQrpR3)H=n&i7eqPh(Q09zfnK<@J*bFA3piHNw zeDE0Vu2Rw^K4A;G9n!3#1X>6-)JuszZSs>zh|`&*)NeEB4!(1%o8V~eDIWs=!#$a7 zxR6+m{KLrO0>n|TUpHCaXTiNEh7wM=neDPw@#ERIk%x>d-S-|VM;LQk_u0El!S!Du z+Bdt!YZERF`}i=ySP~Le=8K+-U2^yXRD@{mT4<<|$Ak&N8>s-wFeSh@BN8@xvERLB zL1J)$YBXX<$Z~bwr+#NQJ}-|^pT^xnnv>QYq0N=)gT;sN@y$2jv(@H1zjdP9MIR`5 zOuPPV9pv4KVY>9MO)!$}pVr*8n;1ToN>N5aB=*}>jv3ReqwmUJBumfV0Lu%OTT66Z zvObSxcGxMVFV%*D9B#Pl?J(cw_uK9Oe~B&6c;d!Z-#e?uKyP8!Z?7xk1?z9KcZIAj za?<}e%t&{|>GW?M`m7|sz&`X>i~i#Vgw{MSIx^2k^7ch?nCxd*9u1N13SA1Gkovcc z>B25dg{U>&9x-{ws&n45>yu`kZtloZ~c^Q(>nt>J@{iF z&e13t&f^TV#kOT7r70oQ(zcF3E%H9a`JIK*N!4fd`2hsCe&0FO#`j_W(U5aGa88HC5`utG1$TKtn>XS_svSSsYiJ$$ez+ zHW*c~T)cASeQ(I|AXMOkNhimV!iQe3Q&BGp^rtUfZ?HZ8%(r#^t(hhGDBK|&X8|*6 zMSEoE7oPS#PQS8sFL>`{`uNK_b2nbUyO?AtKMVr-K)Is+IS3`_x9TLspCuYi^j(x zd}0P}RjZBKl7P4E6T|rSgD}*C_2=u#Q-$alzvr-`tA_U1(mTyc20g3n39+023D_S9 zDCl_qxofs0;5j`+yY%|U%73p`(W4`woD;lM@{ME`{g(xB&5nK36NdYcGFMp_muv9f zr}(bfh$T0*+~?JWX=zvJg^6CbQ0Ih_14hW_kbOF9rb}7$f>i0HQ_6_6X^v1rN=qYCpJXt3KP7a zGPT@(X*<<*VCoSMr?gh9+^WdjI_*j>bGj4rT2~g*R66Ywxe29sBY3F;N&R>eY(cx63b?>Oe@J5>ZTO0Dkl->zRSBP8ic1LDM)7rn zjkfGscAc){xnZf~D!A4-d_&1Bd=Ou3Vf)%uy(RzwJ8H24Ads=kuIBVpLt zWBe^b=nOK`Nk|h`lqFCls7ZZL{wgk;ML<#C_Su9j(?MD}#@lM&Sd*{aMbv)+Q;W{}_Wp4Ca~yB6eNof9;0P zSu$+3is20U=X0Nw-E&TVoRTn{C+nU%@yj9~4Gd2m(~Q1qxwFbaV1DNvtaL*V9oqG% zUZx&s5*aik+xpunq36jo4AtkJgJ0ymlB?mO-+u1vu1_IMBO--%RfA7q;o_!qv2G=m7>WPnD!52QA>5W|!L3E}uK)fiQ>BM$(>dtn;jmkvSZ z0hm_8=;4q~QM@0NzWnwxc_WsmfLV#oVY>NP`(*^vwMdkyjaj%amer33X+R~m)Wt0` z*po44Mvet>+3xKUIt;d@Vc;B4s$KRltp!cvvQTb z&^4fg8-th&!Mgv(>_NwKfnb@xVKU^_MVMElh$Ics2WAX#1^12CUOTipISQ$pkMD!IekS~GQ>D5j z`Qh{@U9C9)s|?%+BsGVowrGx8Cem8;f=`;`i*2C&07;_t3e&MD1(sSAyQ_oL)8T|{V{ zmzq0?`moz6pMjg7U%4Hm;8Ud}B6tJMIi9q8CN%tWmtKM7wEY$1om7`hk>)#B2q~Q><84&wv z`XqI(PZYdKlLCE6VPv+@vRDMQx$RKTm*z&~ZeEZo|RXYx^ z6Dy!-e{AIYcaQI@vEykLN*?E*))d;F$>23I`HlFCEJrF7wE~J7*7cSV@Yx$2(4vl# zLKreZmPmiD$!}&i%S%@3gS6-Y28grk*!q|x`V1{JENSf%_%s?&`c%39>}X;$suXW6 zLs_CTSghE&Y)AiEe$*)0;47o--zSN5E^ew`l_ub8_$#hE#L&uSE6+C3FtPs$j-)C| z5HTf*`IaCt<-->&e~WW!y6U~;{3<-#dh%j4ws#KCk`>|uJSQi|+W-?G%n5Ewk^k%h zZl|md@!|qm8DxeDn`C%|&F?(T-A-FD$Ny~E+=e;Nue`h`n|133e6ezBk)D zapMOFaN7)x4*BGMx77%-CE76VdQjTjx}cV!wrCN({ti789-#xQ+ou83?)qE}PxJI8 zqpbTe$dn0K^<)X4UOY2fuo}MmyE+s@G1AzhCCZa}i}VY~B#vw(6%CxegVnQ+|& z74ra_L0kMgL6%*5N*(4Ki_e#VFsjov#$F$>kxSg3i*z;;`^m@f*y!X{FFhmQj zO0>!IhVx~#uWfH+F>Swe@N6bSo%4PBO3*>6-^`x$yt-r><43&PS?_w;Gw2$Gs8$lR z$0iIV_uTI?x@~!SUR;1?rt#xqw&GFTzut9-z8oU@eF9&qLlwCSRSJDh+t@M%oEW!> z>D`B@v6~3b(#@n()*-p2s?WooHqHXn_&ziWh?j zP&}sytm|ZraNB*nDLo*3T&2N(o4|YnVS~CCe4d@YdsDsCg6`et@{g%~%Czv9-sNWY zM5m=b?Ahy_M?pWdHBsbtu<(|481pUSE}!is7jdf11G=W&mizs`Lh(Ox^Z)2i?K}h& zv5nG6n;#?p5rPXL2)+W1D&0P`A^v3?dTp8Ro z23PS8n#g}Q5QpdiU&D1t{iR^(Wb|4+IpS$v2Yv|qT?{tL#E`SNw#a}#^!`Wbo~O+~ zNVl&-mQ#^6jjU#TX)9HE9{Gw38+N16E_Y04pR zTdUrFS|swOnP<#Ejy5+7Ya`eZDk67IOFdTOiQ|H!GM@S^DPFm{V|(0q-@p=zr-u@=9%LpEWQLO*uX?Zt(9X-?0;v?pY`>#^+1J-*uG!K+FAc zqAv;hYam4bK;=9+tcxE#g~mDn2~F=O9PS@mnoC{!RG=I+x-<(8vQj6TF)vV#u5vh( zp%D>w@3$ll-*UDT+^ySr5Q`W+41(Dnj$-W};BuOBQ4QC33R|rt}g%y6P zB*r?ZD9c&iOd2Tn-6{oL5$b%37E8l4oPk_vzbBlH_SNKCHhjY}jbGJh9$-7P5{PLN zAQv0F{0Yasn=OtO77l>SQIO)h-UP%Y8WE?v;vo*i021&U-jloFkl|?L`X4P8c2*lv ziX+5`RLP?vF;B7nmc5EDzllga;x+~CJHq*&{6k%)u^7%;SR#bW29h9&w5ca!|Ii6* zgJ&P~#!*Zk$PtZEQvO|QIhOxns1mT<H^e3YQ z@*SY40f_yDRjD*wMZv#L^#E<}Hy`I({Iv~U#18@L4=tHJ*MbtjPbW6G34Z3XXngRW z&78kDngiHrw}7Ttv4?^RFk#baZlCp!D#s$!#K?zo*Buf(LC71?VJTwzM1gQXxF-vU zo&ddeB_m41 z7OTupJ;DAlbe)q`1Z7T) zDzU#HqC^KPF+JY@bc6ls6PyMR36W+#Y_yIpsR197IM9}OgXry+!9TKX+^if=!{Aqm z#^J?|f?xquGYVxFb(O2vSFQdO7g>Bc{<~*lwpO*s3*uPwIFLZ2y*z^vHj}0!{P>WV zgY=hAlOl=hrG&g9N6teQ>zuJD4vA6fokoC#*|^u4yRXjQ&cMX@?msKhcT0TH$)VQwB1Sg%&nV#w zd7q}mc#deJ_M)_*lItoZ`F=uR0$l-JD%+U9sXc;Kab9cIEDU!gi(4G=tEhAC}7N+Rupl$%CG&+FZ*l+?HV z*+;!E^paKnZKvgqO7!EIN}}USyrP&1#PixsyMCo3&uZVr+hAaXTU~I`LVry(SY9@| zBAnzYFYfet%|9_5X&Ydp60zZO>2UE@1-*Z1o7E?i_U*h|B!#Jn`+S>#=z_CcLZUTf z`3%c~Du0G*l}m$)em+4w$zvh<$&NK<_N6u!q5hmLVq3+i`-3(EA5>^Ae>z^`p05)c zwmm8Diw`CRZh?=RcyM1?X!T6EPAKP104c$Z(zV4(Zd+r6F?7G3_4cvuqyykS)t9JZS#T+5g#~KJW>2X}DT_FQ7J3n@&HCBo_eP~}UP@0x%{mvbkvU4RB z#&-ZN1c+y{UXOUC$nP0chUDKkkz}s}fKxwBUB;3DUs3u-vZZ}T;wClNmQ0!VhY)`k zVX`4TGh$2L5N&;nXj+2Z8j%sa?$5%Q|4Eqc{IB#-U-;02N11IfL=tWvyJg#l#TUnL zO#-7oFM|WYtw%?APk0Y2+Y_|Qz}0M**5J4rodE#RD@Lu6$g=@)S#lkPMc$d7(<^T*tIWNRFM(i7i=xn$mYDS3))q%ZJ2w&i2X z*5EhuOk$b!Azvo61Z}p#bt7rbEzfB4_#0Y?uJtP^HyH-h&w>dBrVNw7;e>lZCT1$F zZckc5+~(+7+Wr65KU<8AbZ&akoL&iJekLDd$Ku4i+V~kl?#uA<59AjPzC!6pX^}t! zDHN(?LY%&%H2n;tb@|6MMg(3L@ooIe!>Rd|WHqL#Vf-}D?*5Bo?@ivE!}!g zc|Y~ETK_54-jsRy0Q$P1Qn*|TIl6N~qIj7EJ^CDUnq9isDT? ze=>Yq?Ky4h7d=Z_e_4OAdhCTh0#B(UIzoJ-Q){vE{(s|5Hd)x$*BZY6JMR2c0(@hj zP*8n^9eqVO00G7__;EXg)(uBjawi7jin-3}GK09l-6k1_s0bPFSH|(NkN^U=mf>c&n{NLy)tz zD-EJjJD}d57ex)xx21+MCRl=kkXvC+6+^f`j+==j&?;mkv;{9euA1o%Z+Cl~T|Kd( zel}o~`%YJmithv_2sNrHKBn&yka!{+Tf}sXOP#0Y7;&wQS47Gf@8rhKP?D!}ihd*q zwo*`zdIL2mizUQ(WL}xLce} zMsReeVsWwAf`Hn1&4%8C>dy4hwN&M=tGTHH-_57|0}<}at+RCfEfjTO$Ngho0e@Qo z+KG>WDT=)eq^S%`eTWG}(V#?`ZZ?8P#E14esRD-H8P6#XPv#)lccMsMSj)HrAudwi z31fH0rcQ__)9ie#P>MhtQDegBKFEs_k{F)E_#PWOhK5|HC(bm3zzdlssTabp0PdDL zA__k@vJl3#p*aZ79g80n^AWJB%fS^jpp>R^U5G&Hl}XD1utY^gCL{_;&=u@0Z2xfs zrUBU3BKi)2nVe~#G(j-*Ko&*D5Bpe}2S{=xb?%Z`VVk$TC zCsDF2U>X)UWw?njBzqNR*B{Nvel# zth%%%YJrub>QzGD^yr~3wd0HZwk|;}lspQxaplo=@Fc09K~_N(BJNZEP|k`380m&2 zR_<8;@9>6$U5^A$G)TOOb;OJM)l6}lP?6MiObvjd;E^QMEA6mTN<&QzryGD|V8TNxZQ>$LBmTjw|@N1N3Im+aQ*0@tBLGvt>M*#g|@pc^S1?06m+p z>UA=*2YHtc)nzWU6Gy63iq9sG)w0qQcKp~nrAI1?mDXeO6i#&*)mM>KzDs)KgvnRG zR!o_^ZsI77#}R2 z>zZ;;M8kcunZox;B7nHX_^bX$Q?n3c6Uv_v&6J54({%7Ceu%DfcIEV_R;M<6EZ9|1 zJR9w>jrS!8$C&uUc0Pn-S}xhNiM!f@hE_hyN_Pu?728LIDnqQ03)S94Q-XcJ-P#;7 z7brlfP@`WW&rVu(b$M#`Lx;*Q=j-LDY#tJm1i@N`_~r}dO+@H#tm(7@HmK_oKhz0O zC`MBEjz)e_%%wIIm;MQsZej_vTXA*gKSWXd89>Pw<#-xD+M*0m!@7Sm2Tw9cpciM1KIJ4X_H5z#O)3BFQO3 zjqMjKDn)_RRu5@k0J!HuIZSGyNw>PSyC%Hry3Q~@GFVTk)Si815;nng=0%3}!>}32 z68DI$GZqTHgzg*%P(3>GXZG3KX|Cz4qb-1yCAgU{6?<=Dj31B`8HH7V3?r8Q6>DW` z%)9N-m%95sYs}dk(>Tg~MQV-@YTLh|m(-`gnPMGOnCpZ_gK*X*WTVGzj*M6$fkl}m z>LIvf-u&6NJytgBV^lg|tRMP1-9~_H5UdAS01l%(I9>O~RrjBy&sR?vwN}&#VV2_n z-ujv9;j7kmG~sm$d^ND{WZ6l4Is`fUqUOMetO4sOwaF9a1R-OtBv?8HjfyY!NUN+% z@zXC!TzqFkDBeH057YHw6)E5+LBKF#ksneHxxn=5O!=alK+42r@yJgMmBF8`)0^xy zj+8N>2An7xOw2pl_MGxxzE>UGoNoru7hwxFHCLo_{bTrlkJ;$pv9^x1VKU(Xir)m4B>s zrAglTJ7dI0*j68PayRHT;A9|M2YFWAh*Ct9E9vRj+mCMPVfF>ly}@Zs1D)wozaQx3 z!G2%UmnwUDy;chK1C;bCP0%Kf^^EmIccIpt{X=4?K=y3tzXOe;znALi)J=aE9Iu zp3#F7M*7XmiqJ`?)l^Smb9sc4hrPR)f0Nn*Yj8)On5D8KpTuV=6Qgr~3+Py3>{M=Y7QK^huo%nq3CSpEnUP;VFqi(d( zZiph8p^q+{31q^s>Qfe*TSt!rv2mzD6i=HS;ne)iz^(oFVds1Jvf#*x6Y<_3^5#N*d_JW}2(Z42mc&y5WCg0Oqu+ev4%9Y3KR@&y{fQ$Rz z>aW@V)8OvJqag7<_dY*R?&+_b$83BT^iDb&-#XYs^}i_?e_?l5=B<?u+S%N>MU|ixuv?t1C3-Naj#Os^5zGDW+$LdO$ety?-+j}JDKqk{ zyq*hMy~qn;tFN8r@}eI-T5xvXrdcW(XI7@#FntJA_;x9*U}p|k5ZEz8*VY|S!~41YtXw#8nmf)aJ$s`C4tJ!N%9hqX`0>#5YTyT zs!;3-{2hC0NQXE3W7Kawmvk!7^1&#t9%Rm)SEEa>v;6h588t(j)~X7?SzZ&H|Bch9 zMnIe?ZMlq2cKfi;wE2(n&?p<&6;jFft5d0O(jR|^7jSPJ0dlR;I1wy2VTySa0dM3f zcRw%|?DO2kuM6WKS)`Vi`U^inngO!_uaJW&dHG8qNu`P)N}CKf%bvw>5#EC#5%bY+ zo50FJ`5FJ9sTcWMZtCmCsw(N$avHU=0navaE^rZ(hZCYKDsS46$wyWi2{TOp2~~<| z3~{taArzf8hqYK1)77TFx@m$Y%ayyNjhwG-%GA;g%=X^gF1+$rS~HK1nAkChoN1Bu znI{5(py=QK=@fSO% z%(*K$Zra2`J-dUz`r9*&C6Sd&b=MsVfeIa{^{22F9fH>?x0lx2FMDeNFxu7cU+4sm zuHSdsKYZqw^zD;!V-HZ_QW>)@FEk?F!ZiHmcILcn6~M0->SWlRBLTycg8t$Sc|`5i zc>cL0Km04lNoQJ~WE~=vmY&{Cj6?)rrYAKNf`jh`@W9i#qtSk{c`ZQ|uFJND=I;qg zk;ywfA49cn;-uDD_{QX@@&UmmXnw-U4_(IJnSgK4%&vWS?<^j2-8k#s=0DQf4q~*u zogZY3L>165z$F}`h;$a|p4U2FTU){UI7KW+|K zt;AA|X!)iTB8NT3A&xV9FsuDlf5+TVQCGzf)`|*1j0!&47VIK3FUftZ5Qfl+`*bIm zLH(per5%tsb--6bp~ya|qou9AjGlXY7VWZ1S0#v@!$eSfu&%O$1Vbw#gEO`Oppc{| z%H%fb#q$rx+8xy9N=?H>UL`d&TX$^c`qd@;YpYx%#`T8;^_pQLM2qy3iQXLv%AdF& zt(*cMn)ypWsN?7BO)o!IR|+OCR^>f`@yDsl((hDMY|0;L1CWl~?b2qYTl32aNjd&Z z{5V91Z4n(zF+zA|aQ2!b9l4#c0hP>+s2eLZl_0N6buJauu|LiqsIguID};$mt2P-e znWzXH#@K&Kkw|9iRKX5_a?Xq31BC8OwrF*S3`g&{Ry-v6B^p}kufmOz_;wMlE~IJ3M)Xa zoiH9S#d^6=zOCC0acVz%Lp1kwsO_9rK=h!4ti6aqB$l1q*hF=^VewTCrAqmZHXrx@AUVTS1G z-h|#8&3z3TizX?e->nt75%0MP{5XB~mpFNQqMOE7c_TEksGn-3Srun>X1?F+=A{#% zAb^!{cp{1L-1iE@#vs+5p+2bre*1{RllC{toDBIa`}N1}bNQX1l!oOh^wfcw%*%C$ zGy7}N2lCbH=jD7O+sO3$qp?uhY3*bQ1MO(Ryg&Is$~R42?vDW=!5(Z-3cnpwG#069WB=IggQfZT)MI3j98+}h?)8eeXe zcCFJCz`COf-F@DHWzL$x!n|fM3E&&q!Z`oaL3X=Xjrz|}J8L)>Yx%*ps_2hU@jbw` zi|FOx#h&3)Mvl_+l)xjg6$R191q~TpjoD;Mfd+_94-ua$18ygkE1K@gnlwq@rAu!zSdO|+wXgYN~ut4=M%-c@PF zp;R4s%C5vor0w8{>>E>r-%@P56e?(j^bMmY3C|bnYUcW3vlWB%`eNe+i{MZ(yq;Hei(u`gHIFg<4=5BPc!z|?7ak=FNb0diw)H3{ufk1_hf>w zlcwc|ZGq>aKo9B{<;*5OOO~j%sI0Zf&#-75tx$V z89wB!Q->#*hdP>GiN{mV5y#PP`}@VdGxuz{4#H$WlPOtq|FlI%_cv8 zHo(daR&XP?{sYgxeo(zjw)Ygsg>|eYToFI}>}c?F5#1`0M7sxj%#Ep7Y6!F;nb>}t z?WP8^PJrp!qWPaaxU9Qo?_d7KglylUfCmwR`}NGqZOOA`4hw3zm@Ht^y~k(0RHZ3w zNOtt0{XD7eck4@Bj(CI)zX8m%W{#}!(xp@c9*Y;l{nSN&~DCZyuDtsSKx7? z{@39>KKyDE(kt&GxoV7!y$uWcClV-orS1CPwnEGVx!tCub4P7B%1)@sW2*5=?bQy5(dUL3}f_M9hq%(D9R)` z70^^Z-t5CR3Y=-Jka~O-0=^_O&%pMJDGUaWM$vqlT@4-5}!IS zPrjL&%S}qCyK7jlbeODfM!tp7K;YocL`$tJq(WKMcf8+sqO_Zr&hYJI68Wzg&97W( zDdhHhdJqQhyWrtSt{aLO)`Ukw6K7@DRnN0IZ(JRV27qAy4K%lqDjZJgA|Z5GiAAGP z?wD2crHL$3pPCyjYhbK)6|w2tjNLt)R<#N_)tG4d&+VKHfUrCfb~irZZY4e%hjzqx zx=^-pru&Klalo18-ZeEjB67kyJ<)!+5tDOM6hyP3*J~3Ga>5|{ql5FqNfrpP`on?)*167W5~6R31}mOuqHGe$U;=ke#cnowGp}XRM1ktN zhhfRLTxF=LGFol&`fMZp2kC7oCYQms1xj9#_m(j>WP;LkcOld0=wP>m?Z@`3NNI); zE%NGt%ws?iLb&8kZv++sCrl7NQ%-*-z80CGEtopoKnatWY=*OT_Vw%5V=zI_6gcq~il;vfp2214UCS$JNfeVlT?WV!tPsPBxl zP$OTnA{mWtot}%kHGw_f@fh<|goW(ST;)x2AXBoLX^Al>#F86ZV!LXmiC?;kmroL8Zl%{K6eHlOy*HQoQ!~Npzw;UOHL!qu>a!IIt~L3R zeTSrmkqsh9G05?lgj$O5Du&XtFvRgaAh%^^89>vQJ_}JQG#No(RZV;ENb1rPrX3oo z;|gWqgQZtc%NZ0{Q1n)JB5Lx_g%(~QPJ{+N7NH^L@RyYv*u8vRo|Um0K82{ifjWVbIz1%x+o?Q>S%>c+IX`z-i~f9HrNI=HpYq3 z3+ezsj80v1-jMIC<@W%Qxv1cDb)+m1t?n)G`d>yYRoVu(Y^+mGM6+aDC(>A@w8shD zi}Jsi8T2-vLXBLg%(L5k!#LLR2dRP2`|8aaW8UT5+?F%+C!}A4G~*=73vN;{m3d1G zcS_zL2$zXu43c743j&-(Ix+Fme=gld%c=JX&lQ;R@sC@Zm#rx|c1c!u`e8f+#kD&u z+RT3;`sDaNj7>t*JoiUk$~83sZ5ZbRdF3-yYqVJTP|qHwiF$$Nx4v)ghcRM6$>!9) zqC;)mdIdI=Ob#mS&~eWF#Y!MmR)A=K>`rFMv=Ly3(&XI+q9D;$80p|GmDkl%04LdH zq=h1xv3j(9WkIFnj<+yOHbiiSVJB?W)H=yh>Qslav440G2%n)4iwv$6k6T|w2*rH_4nZ)f;g^-??{I?#AE@v+5)D0QQwSo8+LFRELpJ`d0k8f zFT+xaaV{a)yTrYU?i8~0cUxO69egu)e#7^VKK5S}ugc$l+VC<6EehH||FXpRD_Lko zN~IgZe~VY!&{@NNo&MboZti*QkzEd^4B1n1Gy#9!^y|C;JcV_7u2UleI!WCqe8{XO9_}T9zN#S%*N9`gEwB%W}!)U zeq--Z2w3d(zdcRT0wQ=2p_2R7ED0 zp&yMW^#W|b(hS6E4%OrKE{wg&D@8KYK~Yg85uuh=r2Ff`Lp=bcTv%vVE+KF)#wod3mSLT)wNR{aIx((uHWv4sxdzy9$l@ zSyYy(EEl7wt{I{>Ei|Lleejv+T3b<%y7Q1r!q_RnjoN=b+~sEUyUYG&5d26;$$VH#$GOT~|^%9g@RM-Bzx*zjc zY&hr*t!t>IcFzIplp7x@X~-1)Yw*h84cX0nnWy*NWd6u6!#kM$$%plmCu)Du=4W4U z;xFt|hp_d3TGl9(e`&hlE!WK_8ua$Gmj7u)K^bJTEB5K2jCdkn;(uq+7eu0k*WqCL z&yC5m-@B;D$RBBGX(FvQ%PLEGHvg+pUz2&fA>({|_;7o%mu8V24pu(-8x;h+2 zIr#Oob5DzFng(t-+2O=fGKV2x)=~c^hfku2wJ0WZX((#V|jdxtmNMkfxyn)oD{SseNsb!gmgS(Um@ee zo#`{S!tC}Zx>&Fzh=A6N6hoE5suZEIMuhj!^=?-7Wg2($3ty_kJ1Ay9r*mxoP{$)s zEN&Guqiz3O^RCbTF&jSQf4?w+q)_+ke7nQXvhz>?yD_R$8B|E{EOZQcSi8t^OD!RT zRxX{tiO=Q14eM0HKS;cf23gU;c-=brj2Nk|WCY@9_E8hgk>*mh(g`kKD_W71*~)(5 zHk7nuIR?OdrS2{b@6+VB`O*wmLt(Gmh_CF=n^@(f7=-4d!|N&Ws}XOIZ%iz6v%5nS zI8hl?yUmsG1w$1WmP~Q#TIfbG?$0ZaI|KT7p~C|=5sx;1`RP3;q}QE%X|UpN-il*} zz6!zpt(uJFf?wXI>5#o?03)b$OWQ1Ng`Z;J5M)uNa^H_UDOL+q>HS5sDU`USV~K#o zPZO00#KH8sw(mkPRS|^B$y-eGe$rsHp}bN46!$&Hf#o7iycvZC!Pk)V7LO(&Ygv`y z={J4PpHFQR;kcx;DLSr;JLr+x0e`K|3etr zF_xy94(9o6v(U}nJpx$ELqxTWuN?fQ(Y^PusJ$H4Y2GHVFHZwSyB9M(3CWfpMak?W zB?%$gl_|HN_kmz}r_ZwLCineBpla;3>GnwbdJKH%a#Na5e$&x{cq#*Cq^MPR$VyKR z9~45(M{YgU2(#iuA*q4Str5??loY+;kfrh(yOeu&oL3;|7j{Vw|pyN!|23nx}o zrQc^7c*jCeYnrG|*grM5si701@iQxA*BcA0RJo7D3V7yKm}$XlXSkH`@$&gX0S>|Y zjjTI1%~>J)9IJ;+o%e{X_+ei@6ZYz|81SCr;*Ly_63d5hRD5Lf%=Qjp)fnF!1JKF8 zk(hLF?##h(ew9X$Z?!(#=R%MyvEwj{h#PrTgdk|Esjw>Bz%A@*w_B@QUW=7WeKgCc z>@NT6_!aN^J)|m`A2=DVi=Rs?XeM{+R1}U4R09a=q#C{%^TePeGeoun3b*m6erpj$ za*0nIMr#9b!}kW-dZjY5YfZ!31`zfi##gd1NEfXihR)D}WFAOEgXNxyCh^3vKF20G zAkq{7z5(G{?S_}v=zt8OK?Puco`pGw3D=qq42b)B&bHA0@Z<_2jF%eG@&%w1Qn5EH z&9l_<_baRZ0}RR>G-Y~|rm$BzJ_V??IdB2kr@}gc58)M>ds5F%qOwF6YXhz{gq@L; zo5Y6Nk};(Tc==I6H&TNi0Inj{_6cIlK3<#yy>#?Yy0!*lGo-lDGOpO?-Atj6h$LTg z62m2cc`~i~KCPvovp?)D1w7;|$j)|wuy9Z2)JRWe4@Q`4XP_7*XM7YI6j3!J-2+Qe zwInY9&x*eI(BMrFdkq#et0GbRd#lX305?V=5vCyK>`r?^43FV2qiphUXAPL#>opiE z66aeGri&n5LrF*z0xeujs_v|>`76jovLRxAl=+mZ1>;qsjt7Y*RT~nic6NYdH>vO2 z*+jU&lNl~w&S>z}UhQ5}^ku+>3Bd*@CUCkvTleNz&^qBzTDTQNCXT*8PQks-;gcLt z{@V_q+&fMLppzvz5Dl98Kv@l9nB^kbgCmbLK5-uJ0u1|(xSwo&aQy|`ia%H+SsxOe zeOp6<$#zS&aaTRC$*3BC;M6Q9Zip7{sa6v){_c%_jeZb0HgGjIpGE>2cTYkMz@7HgwF} z87^bIs&jm<32LUSbqaTL^yyYHmxSx1_=KAL7~l62);4$79Ef6*sEo>`1M9sgr4P3MKc6 z+tD-v6;qI1XE(ifnubdFdSP&^X~wCGrUq!tv9@p_Q2KM~D9XhlFFP6d_M{wVA0hWt zL&_kn7Rkd_=$iDa$(R7Lorui9caId@(VjCCNq&`+mGqk8k}k z%U3ev(w-1ysN?1FzhT^@b!x2*NO&0dv5J**3e6_&kJ|H;ifQ#?DHliT!3QWSmhN!b zP;h;<VSO!KRmU{Pxu=Ymkr$L?oA@~3UN2(NAvfxzzB3TA#O>`l>5vEG;O z{AU1tsQSh17_VY5y7xNeWdWf2qb+RRvIJ4v=cWa9yshzAX@mOC;f?_@(-)3ovP6!c zA*`AZ%Xai2gb|_$O8FFy$2cuCmDs&otZ2mCb26qHH(cFQglSdh|%Zb6~-G zOYq-@A-@7HgnWUGnx=#me>`x9_CBUaDA_3&5|7(5FqEt(GUu+gO@)*s)KO9dWp?B* z!?exJq>ZcVXY--5ew1Rrx6Y`zVPa&R==UXjpNqH~W68?>Qylj3??)b~h&l8>tX!xp zCoDhO`qO6##yzv+yO}j13?h#U)h?~vj@)BXztBy9G2K;78&wc>JdT>;;Y zc)70VCunoBw~;>%4a+V1qu0qsll#b)pB&MblODLl#t{mQ%8BPC+JYlaWhK(R&|@Fy zqCy4R`)BEo^X7+u2?5dq=amD!Z(0xHu@B9Oes|5S$=N=4wqg6Hv3y3r55M4jaybfGWo^?fJtlFN8;wtAF$MmQ^ecaR$Yd)1ucF}Jyn!TQ89Ua^ zLCHVacqSF)A-GkgWnpBEdTS(GY=GMM_~F(ZJQeZZ+V|g51VU@r=FUqNb~#(`^8M?$ z(H&J-TlT)Jt$p99wdZ9Qu{}#C%@N+f&5Q>_KW zj-vVV$}%g7F3sFjK?8G!ieYG1!zQT8yk zT!F3>#{*YelgWx>{7aFIE@^BU0Ua_!FEbxMC_b86hy*Q;QK7W-4?^r``dd+^K>M?M zN{NuCY&mM4pTeoTxOKAJ&Ow`-qj)n2im8OjN63P0rk)9GO3>Gvv0G4`0Dk1NSHodn zjk=BS3&M{B^GxgCB>>1*vAhX0Wu{$QTj>mEx;95R#$Zq3CB2-8R~ssD1% z_)$w?7!wx*lsaco_YT^PWP-1o!~=sGiRfI{Kqkl)HhTAs5O%)P%UR}A*nk*wJ{#ne zB@9|u{<7^PsR&w?1ERATSTnfGek?pX<-iwt0l84cfr?}ZOeUb?yC#4Rfw8R=jb<+l zhv1Vp5Zbvsh)gJ6M(Wcp$S)6C;?_yNp6@0S$4`hhVr~yXAkqblg~;ESZ_c_Ud|lA! zHu+do0cb?v#HC?no~lS+9qIy5r2^Qk<8q08vnRgaU;c4D{D8m_zSqyvYvbb+csGys zJi##oaDDe|*Qf+_pyMYo-p!u^j;>OuV~hK=p?6*b5BVeg<&4>!2C&~HVAMZtYGGi* zu1~Z06&Y;d%q&{9e?vgAX;;X22UQ5~5cC57KtKN=VttP&#ef-u6a2?in7gCltKp1M z#Jt3_E>r_4XF0u(V^y_^HO3s?E^uTe|u83SoM3)$={Hk;9{E!E$H z6?funJfdpt+&Vph1p{%ae~yV2!lt_eBazNhPm9Zn4Xx8~S7f5IvRQ2d8!qV{DExU8 z8YP_SOV}A(G4@s6yAgnx1~XE^gW>5HfQ;O*Q?{L`iyG=i$KBWp>{ukAv0idglA;tk zN}E-hfX`YM9sDhTJt({bCghvG{xlHkh%bj$Z=5|V>$4*&7oE==zBo*MIrqlMFoS%+ ztvoz8!FIWERtaDq4Enjlg=P>-S&YLKe}bTR+My9Y78N|aaU`EOGCu3}9H!z^`wSSq zG*eq%l8O@4WZ1^!BWcVK*Nyr4|k`laQN>~EGp=4kCO;sZq0zu$w!KFL5hK4lKk5E!a)CQ!3&MW&J9t+|$1IrqYXhnx&C^VO2>8 z>){oD@ahuY;ZPGQq@h-}_yYSl^+c3{hz)-}>YWG%Ykeb(4iCXSaF^MO}bU3f&!x6SKVz3HElw zF96~mP=s$fL9SoE+yS2SXooqq!U@<+Ck&Yi3dYc`%(HJB=ho5^tRAZgi+!hXlqCnnz3~LJ6UM|k+uH&yB))ZdU>5mB_ZsW(@7;zO zt9Im^39Q5UH~70z1z(H*eR|_va>t2H%RTgkXPxTo(?Fl{!s;7EZeU3XU8b;IGT_@% zLvps?bL)o~|Mlw$!>5|okxUd1RvPqCrtJd5yK5kt$f1agG(Kv}Zt-&VvHxiR{G#;| z&s1_pcc4V2xKlgbB5#(T_H}(+gkuWO_M0ogwA>FVO#@1w0wMI46j!RQvqem*c5yL- zWRvP}LJqhYYl`$IeV%!R7F$4QMMvczp2JUyS(_}dOj59j^Y!`gN>cy1UU{pT2XR7GFv9x_ z5xWnae+p^MGfm8Hf5X)d&cY9{@5CC}()&U0z@Sef6-?-@GRu@yvbZ>sT*{{|Xlbto z4!eRVaUYXB-WV63;8~M2-rJwBsB+ro^B4f>@_nft)~TAzpmd-+aj25`QoeHi9MB@9m>_!+;D+WYxUWwgK z671caZ4}11M*clt4~~HIWh)O2{xIoL`SJ6%OWS+VSx}9-?l}NX=bK*Uu(9n*Wq$ek zKDuZ$?x3@1qM+V_8~0Q%P4K}NE)&3yrKLc z7fsPsD>n-+HPXJuo+CmaQ|U1E*zbHxL7hO8 z!(JEMzvUY7-Yv!d=IG@8&M?J_dvl)Te+%CkK29X&2mi+wd!>_y?USg-VS}y5tQBwG z#|I8y&PNOX%Rk5(?(f5J=L zqca;UQRx4kgOAsgNG=Tg3e4kwY^6*v24>h*Z4u z@g(Q3LD*^wp64G6143=LQ~OKzij4{Z5>{5 z1}dCjcXuAjE6P4oB@;qM5x&ySst8fmqBS7A|MY41tCz_Q;`)Rt3BS}K&QUypG*cK_lpW^yiIf8MYPUVIL z{bMNiUazo8UIPR-%`Xq1TRL8FM~qk@W0Bx%vwVw7BKcv0(tG~5)j;im8YLq4Y$Rxe z=_$m-Ovg_2MJOCY)u8PVhzf$6K=ej(;pTmVjnWPw;PEHY6* z&GlvF%lyQN&E%q~1V7^&mXtg7f-zdK(!1*nKoZub!?Cg=AdGfQlSp!ol+pwcMcUfJ zB|e^1;;Ga|tvQ`{_u4f|q-f$5Y(+dj{g=^!wtj~ekR1+zzDp?42a;$a?2dglG#c_E zGeq6&y}gDYSKvN0>eN~ep-bycl21*&F(}jD#=3JeGdo=htlRhUkf4Tx` z+XJNX+b2mjQBBCrSWO5342&ofos+7 z>O>^!3O1D9%Xx5r?Dofs@R2WC38tIIA^oUyR4pWt=PlbTR5kiS2AT&I0#-5p7J$f9 zD5cr`29!+JTc*j!qT-O)4eHs zHnv+=F(U77kHk^U);MotnxSaEhpW=Q!?ah z?(eLx%a!HVAB;2cuCrRWf}J1sdgSj93+cBN0kyj;YRTnMgKztZo$^8t-RlVs(ikWa zy5GJz%jGpQ^TzAkOT>kY)1#pO`gRjSQ4DR@Lp@aI{L{dloJs?dc4}}O@tlT$OdWje zd^y1GvHGf^qp#;C--(0X0c0s*{LIp%*jf;mcl0x><(xVupAAIJ;4aHHC4UeTmk

    PeM`d~zhkSbTh@X7 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 o8%kz{7`>=ru*BZCGh$?gTW!=#~Baf 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%0D<25tBLKKZe_qGIQ!1ghkx^a^Z=K7 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

    t$fs0bTjzu9aH$ebbv5@9)7+^^@X z``aal@6a?)Igd-@Tfw{#@i-;&HY3(h7Tnn`PlUGzT<`)?>}K4Q832EiuujUD2|OL_ zhPYTpDShE?Zi_lEMUU7{Py{Q^AnOwA^*ZNe*!f+IX%MLZJAE1>?i=wb4z6Sm+B8sf zt9n)RLPkJe{VpNZ2g!opyvwPlQ!~Ho7D$qp%W60#gtnsSbnrLAQE0e43jVaH zgT0JcA2^{@R-|!f^ID{Kf%Y=nDdWcy$*Tu7X63cEfn&|%RQM0}A)A&`5>1cNqIibm z;RC{ic-<2M2i80YZ70m>G; z?KWFa)~;$9cgn?lq-4uQ0LikE2cn*c_nnWRlL>jII7k~s!!e1nRM+D|7vg;VD)$uz zI{DfI<$-*Wx`vg~3S+wwQ;7GVF7UEyja>quY=Lcul{z{m!Y-3=X(CuG8>or`$bF2TF%*6K+8tF~45aJSc&R&QUh zG`yR%P)!bhaOZXDgOV@x+g*9zIbnFF>Y9i~P1wOAa~4Fsq_}<4`-0EvF9FY_VJRzF zsv5FxL$Zo2?|vM_8M5V{k$W(0$Wc6hQazUthiAhj zaMjpzC=`V5P8DR&Tk!tPeAvHx4>ysb=-3LW9SE2y#w2I7M7fe}I|?1=b?-uw zW*g~&*6GO`*2G3Z_sMOC0H^NJa@BvAHp5?oF)Lx`Dyzi@NQ1kqD}`VK@*{b50aGF{ z9H?3k!lsaMM7RXWJ*pV}zDgxYl@rRVVs$HvQifR#;C+kB!_f829hs2Txzu0lL#40R z#g_M5Byc%=fk`+n^Mm0-au$ib>{eq<|MFmQgFft+;Aqci$=M)ORt+{T@y_G*VoLk{ z?I;+RBW=JvEgWQ^pTQhDL^19qwi<)Wu@8G!^vS;y;_cij^ATS*wSEEB1l*Q>m8vVT zn|^T{5|nXfo3+O{6N$Uqa1aS54rkb*x{1GxHWXw*Q6enOvLC(U{1mxH@#-Fmi#CYs+`u zRIfN4QGSg;*YO|c&0jmJMUHbHpPk)vuV6Gl?U!K&0UHldi3UqlQ9S}*; zdW6iTAPm_#`$22Sq4cxzpi1NZcW5vdw3O9NX=6d*v(b~lvv@#Gg%o+FY${#i3Ij2M zghUhcc#lnMW!iv1CgX8G;p?2UZPV!(Vg=|k#y;_v><>J)7-rov0*Dv-G_x89nKY~< z__i(4z~8?q$PUeDJEG()NqRctJ%Y#_^z#E8NehdXf)`)&VsCBbLu1s1wF!^s>8P9B z?Z@Av1GgPf!GAE=CFtE~qT�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%0A+?~x8qR<=kgiK7Zxd`8XL;2_iVbmY8X6*&Wk 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�Fc!^2O6jOT>* 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%0ALEMXO4QQza5J+Io3D7&j z_#p!-ej_Y#cWU}e#ccyLt7>f1r6qRc;y|%s zIAA#Q(}rTyS%dS|TFOdsK;#Rd(BRMp3D$ByD1fu8q{2ahqX#jdWTn{uL*hjI$-xaU z2POTNPN8Y?xE|W|Mc5xAl$H&)&d|Pq1}R7xVVhIeXbJhj-JS{C=4&l72xig;X20e$ zhZFRnq{WmqV%^{wgY4+Z|`Qws<` zl59@Ylv7~*`gDS^MktAEKvgCye(Saw)a7P*;FXks z$4ym3^ZqJ;Tz*y{Shv=68P!#Ewnj-^MFF$FAyY^$9+nN*qGdo*SG`;~#OraDL0D~bVNxNoq>zPn zhB;c8pBUf&P>jW8JTs*05=5P%FxJCAkBj zG4<8(!+UDPZ5=u1-qb+G1&I&hrm!@kEoH>qe+T2zW;p`)>UescEqXFI=yRTPYJibh ze4Y=&4^$s@<|Fhc7if`B%f+M)bIN@hn58XazKr1-fkjeX7n_sjASkuKdHLVansEWY z9mN0T46^>#pVp^$G}nW|KTn%cQpBH$?MjR7&24LZy83HnF45}`^JaY7O#6>6!WnSuAAYAwelTw(*v zd4nrZd_Ub(NoiN0^vG-dr%+lT6gEr-Qn|m#v$(iyMq}eS>cZxDObHiYx_{(_Ei*1v zH^||Lj2)BP$mCtp`D^enb_(%|i+q6e2j6p}0DjZ2H{&(qJ*j*Evv^^Fotf);otL35 zP_UxgkGeV<^z13L8p=Kxav4~Oo4hO67r~d3j0q+TsP|X3UNhUAhtC+OAp;4^~ zbTsMh>e}J-f;7ZRa0>cp!sz|x(@#z>jsz&mROU(LJSOaS^LkUHFsJzd4wbJibQu2@ zkLYB6M4QuK!^llpe;O4k)as?gE-HiaTd_AIu`RXhgU3`%;*g)L5uQ(&E14?hESZEQ z`~%nC8!kZ(U{Gl1ZuP)uX$Ylc&_vO~^*F$bayR6{plbcSH7E7=j_4>vN57^%97(;br{U-5++R+e^5Nt-Cu6@5=?3j;XyWl*@?8sXv z|IP5>I7mhirA`o|jQ$XmJeBv%mBG`JGZ)QC5&Do>tsK|nH%nv&RpC?k6}Ff+))tky z*nFUT@Z_{k3K9aVNvBLq#&bRavL3fQ@l$D!1VrXyAZWv)RCU`0=ESg=3L+??LA9ei zjg#WRbjPSY%>Lwo1d#KzjwW9@B51hZte^wc=p(Sj2&A*3QGn zjDQia6=Fa}-ghyTgcv?fYUe%}9v&Um9x<7UXr8&L;y1^F!w3pum1Mwyg8iKA2S0D% zG?0DafMB>&hRy+X;@X-Fq#&G(o2Rt&XKA?4fsLw@orllV>qrJ^S_Mx$wiXjRfFjQv z-`_B5-eRE(<@Z*pPlDmZSnYxUv9vvO-!oMY9d#Gst73lkIrTrWItR3UWZ^#B$FHS% zHnBn+*`s@ArAUrb)nus{dR+&u zlhA$0UXm;Qm%V;7ivm^0mpV$+(sExh!;5T}s-cZbx{52$NLM^y@e%ns7J(;B*b|yJ z`Zxk~U#6O_)IBbnnPUQ^_sj}~Z{v)2KsEtS47%q(*#zdk(xgMX+G0Lj*K~4ZO#;P<1YK`ml^B_O> z`(QiKTq}yJbNf99Jy}@Y&m^}u8Tc%`Cj|fOu6vhhpV4f9QA05*L@EnCOlsc^F)3ub!ZQlGwbmz`qdV$#gy(TbN8^;ev0I z4{8B^k^}uX%;UGZq+^96Di0b4`{*KWMHWx5=A-hR)w3P-snX~GH(@{%c!L1HHk&L^ zU3q1v27fR~;KXFlt%9e!b@DHP6k*-gH4E=-{26WhO6xaFq>*xLO8&^R&M#u|*bzTd z8Ee&;FF<)D3Xck-H9yN6WgWtCcm{_3xcN}NpsNlE(RdAQxr{2I?S3*+*cS#_NY(;j zXMdAmR??`OVC}S$3Z5S|AGi;C9hO5UVj&x8;-M{EOL=L@iZDeXs7DDA7Nps^xtqfd zlyQLd>1DJtV!E`^GylBB$$6X6m~T=Dc8?9}n#j&}kPzGW9a1Jp);=8p6wt>VD7{pC z-J|243EWCEZ}cP)@XR0ZPE6Y3KOLXcU%NL1SaHfQ-MPJC2w(F@xT88>oieZua2`s> zSk=<0*eiwU#Wz$pSa7A!_r;o!rT3&~u4XXuzL2ZO-&mn+&#SOa6FQnj>!wEUs!O zL@Pn|@D0{~VKL}l)1*RZL{jm3^o3mHFTVGs-3cq(Ew5U^`D&^jFV~KHj>BRj{fKW> z!CxYBqk0arjO-Xv!E~_o2GYtDa4_z%UGQgCG;-X5fRu_p>vOBicTZhD_1@Co{RL9J zWc=C10H?VI5}95oq4~Kk!r4IM!*vO-y#Uow+PT__^Z!HFTL#4$t?imk1Hs+hEm)A? z4r$y8uE7Hh!L@M$1oz;s!QCymyIXK~ZS1hmnf=X7P0hcquIjgctW|H-TF-r77v~22 z+Ei5b(ydfMU6u`7Lb=m?mClX93z`$}ut{06W4JkLiVEL~oUr=B_OBW*`ND15f%8EC z$L^`Rcg_Z`Rh$!5!VTwXII(y~!0aWE21CH#9#zQl%sknT)|*CXZL*m z?>-G$Ty;v#Y|Xc$+NCH5QBhCrFji~+?O$yk1C}dYZGR1^<2}%)TNXzsY3Kg@ce=G% zo#?moUNk<3V5AL2zbr-$)r(Y{nn7czP~x%P z22^twyj*Q6{oY1~mf!UAc5wVhMRe%qd+#=*w|5>y}9X5bKf6>j}eNZ?nJH~Y+r8QBX89E84&}>#9_$Gdq{Jz&1un!7hzAC{g6oOj7%3kU1op@K~xX+9UhxuaV(PTHoQF+Ad->oJ3Tk5TjMSU-eWA;TO%$ zKW|gY>@6*wju;SEP@mY<)k&Tfb#j%DeAnKdTiLz247H3pV83n7Oyecng^N79V@2rR z1a#P@8R(6_5uU$?2jxXyD%TzCYEQ*^y;leZlu(Pb+RsGud7ni^W7nUr zMX$k~A}!JCnArBueH#izO3|U zIE~8x*O>Hw&r2DC;o#OaD$gU~gr<(4;akF4gH>hj&LB4kY5KMzb5G>WaA(c?nSc== z-W8d+@oLk7+)v3yKKuX_zx)5QH9Ly1-KnE8G8=e>m4dne%T*8KA6wJ#mJ(kgZ>i@a zI2}LONI$bNieq}(!3V&R5ZI~p)~L1Z)1(2InV0VW0F)Mn<48ikcY^{ce}b+FYmN{^0oNku9g{uN^)tNdGSu$NBXe)ITwTMQ0}NXoV4~IEj0lt9 z6sGBCr@Y^W4d9zOi6S6m$(X5{iq>6*5`qI@=hrre zl;UmSgyzv>bUd0(tTViq?tB^|eDF1j+Lnh*6GQE6gqZynoDFgkZtB;&oB%~|goSg> z+>`NNpsG9~?4b)@d05XQcvFdsi$~!4h=9O^g2Se6`ri{gDoL1zsjI8Nx-ln^w6?az zUld9T#tbQ;3P2)j?0iHoapv(q+&kdz5W(VwuHG-jPqI}3tu)`LgW3hp9>2FdGl>G2 zipc!7RRo5J-*Ahz*?;5~rP(o$aQTs0P8K+}?3D=eH*;W2KH@Ue@fIQtefFb)M<+g1 ziZP6$*;qT!%V}SLX=1I-VVD|^tiRG{iX6wCp{>*%rc`y95z|_3t4|gVp0Td}Q03*1 z$R3$q$nKZoxkvj3zZfeb??Lj=4nNuSqVgy+8=r3T6wH(@%*ekfu#!Rm)&N<228cB3 z*D&k?l#++;yIw*VX;k}VTKz;6BQljNLxmRCzRc3!(a2RLAqGG6T+sVk;n`>{eLN+`RRwUwu6dmx%7&sr?uL26J9_|-JtvkxivX6nOW zjLpp>e`ewVA3_*Ytwh{iQkb9fM`%_{sUe|Bzl=(`RNzYMZk+Sg#S-^yt+314k^G-) z(-OXFLgQy~vt{^_!@HF?jtpTB>iX%03ZJ978>*YeJi1%h6LNC?anM7ei772C8@}|k z%Yp$BWZ1{TcLLx#o2 zu9sS>^M)4Gg|SvdCSF*sEYi#&$jOQBco^CVOw6#;GLZ{u{+9)Cg~-EdjIqtFdv)!s zk2HdEpdsu@6#FHn@z5rE&GydgdZ?cSN-u>Z*vX%kwaYEt9lq}ufm^6r#n3rc^SCb2 zD?J2Ue$|0$ctq0J}-?dr5u;o3`xsdN>sjG8=KmShL_tggbnn2}1X(7u?luGPP> ziN!@w{7&;gL<3_ASnek`Te5V;uL(n9$BDP2z$`FU!JMCKYuDDBS^GnlniK1M->PSS z8CqA;eIzWgxA07WrEHwuuM=hhuT_&^-s+fb(F?&z?0Fd6L{hTAOeXwpLNzhPYyU)S zDGV_-&K9(d0vzoo>SV&WtN5kMx3aOr^7x@Hil?-;Le(IwL1z*SUN<+NWd<20Mge6O zc@UGIKGib$+a0r0J&RLx9^A^f2uk|W^i$*9*W6R$a0jk+IAMMrorpONMQPQ!@HGtP z)@39zf48NSiIXQkSpVn{yp6FaaSpnXi*Z_>oGO`ZEukBXW&Exy{H3?gB3B9PA5feKsNmNyvevLgEx*Tbi7FlPnq zNQ?^@X|Q}7OR$)dmfdZHf4;}S;{E!FA~Q#EaCjb~F%J{=uDC~qV7bh;4D?YvK{Q>l zu`~YdQixMvYM*+=b<>7?nU(Q-JjLvQZ$xICn)i@RN8&CWnmiXeOi`uTp|sY$__@3G$SwF?civY^c@hTY{nsyQX#A#H~9kEzRxJjjYGsw0$)+29D#@!S#R;P|D~xeLx;mqpnc0irIqCJNOl6 z#|2s4AAk{@_~cqI2C@%H*ppp622AbKhw=Q(NX;;mgH4!n&{qYe5VofBJubJDwj#12 zc8Eu1Z^)mW`E{{kSszE8I%JKR%;LKs*$VH9SKRcyjs?O@He6Za> zG;0c_2Ii14|Gam`!8?f`Il4bzR8U{C3K=q+$(uW zy~ezdRX0eawV>@ZztPL`{$VBWS5LdG7!mnx=JJU!JZ+MFW`-d;^mhUd7{ka6IqtT^ zbl{L;`>@nf1m()yD~gF#r>a9WBBQVOe=&%)5(Z}m2l zKt}!Ud$H0AX|R`1YqZCBqQ_Kdx9Jj%1F&CgTq#cBgRrM9N|kAflt6FCR4rM_`Eo0I z6v`*>nW^7oGxo7J0bG6v2 zw69UvYa>Ntrz%p~(OTN~ShRy9H%>Tizw};{?neh)U4b62eUC4R$lLMxgAehRfl<7w zPHpwXWonAu@@y>=w53bFT7vu+RoH6tUrg7s%;uVFd{%vJNi*yxU+{SG-HC?~40RM$4u zYh}S-`B5U8Tq%?w5KV`U^f7oxaz7Ytr@nu6(Gm;iN?Ue29H*p`fJn6g`<|7Rf8Dv4 zutZp2&rGE6**gPPNE=KoY)NG{h`9HLVhmK2*4rU0h~y%+he=aotge9bALB5nVlkvN zH}43Ft_t-nh+Y7suy*y$YSkom1eui*2Z>){0vGtoLSZRn8V8?84=$KB({H(Zd%g3i z44mfFw|$6d@kmMNdbeS@F~53846Z*C%e=lbcm(wLr0DC5sG(oqDT+*a|NfC*ZgFiN z5qId4?sSpTC^zF*U*cvxa!>uMD)-nc{G32F5LBA^{DB87tFZ8Q9EFh0xuIs9`oWD~ zQA|m1vwaF^Su#S@f76iDeZhQPrhK$N#v!7^0LiAK9&y>;{#Sr?8f0~_cuzc0CGl!= z5Q?C-dlMb|kMwnx^K@njsXC!rVp@;vn4Aus5=H7DAwOqS$EOSaEHWf@eLwP`E%aZ9l2xsls5 zgZ;T1`8zI-N)Z&4RAyOjIu=)V^LZk+`@uHrihrNY1yG%K+QS0LN%8_G zV0VOxL?*vR^!}ZyW%x@_`|<>Jb?m@7E*~6=s`>SLoIL&x?TJw{^>TYJp=t>Hc%U@B z_|{^!aaQNDPx*rHcmapCU5!@;mu*Mt*{2&G@#V!ekJoN*@=un}5(*7P;$aOBSDh0grcgx4j%B+EiiAetkx z}ly1AVO7n3eahv9SmF_u(D`-8?GH_iW+W7FCFm3^+_hZg=CtTfvDVp2^${cj}I ze{41w_Xlpzr)c)>lF*UP=aHM{2?$&JHrcsM9Qysq(ly!nTcXip;=}3tnxx{(E}SrbHDlH@1ye z#h2NtBK|%TBNu2!#Ki4GbVZgkPAo|y>$J8xg<~Rzw{4AxBEiZ-lnd!|(z{l5&xM6{ z0q=-EhDmfZb?lSPXW<9F2c!qU%*;%+TfWi0Zqlp&b?{cbqjN&tp(yjaYSA)-BS@=E9?&=X1f?6nrk~QM~YvxhCJ)K`P>h2l8S~ z$&9_wj??v6n^?F(kMwu**GlISZl8*l* zwhEpaiYQvnN~||B%L${Jod?!J!baUl;;U>q_jh(7zE@g@Mr`|)ZQEc2r4Ev81z$vijt&Lad_=CIp-@V{t^~-N#6Y*p4 zpMTR8pnMA1v=K!q#tO;-<756S49rLBCJ3;FT@+8nMrAdG=cf9U9~WZ&!?c@Q-}Hv} z4R#q9KrT+SsmIrpp@?c`Lfa0o6wAc)`-u6D)gBZ|0@$*`Okz%!DgZ<6$XHvAai;O% zNP>7XY0SmsS%TG59?-=i0GUmUm2PIek~15#zxqqACMm zKQaRKn){ZZZbFdrdcN2RKXGyw(z#+KeMA6`WU&q8bI5XBp?6poq)cZKyzNqFZD()g z6?4UQRVjH6k)Qk35J`6(`0;^X9#+ z*9gmhonB*Dre0yF6o@&ZTriCK^ zePUal8vIy5H&P4I!4HsGB1O28CFRm(IF+Hm4MiG8H5S-4{AmkwU__Z9fEy%cMr+dF zP(wNo&IujA@)D-~If=uwHH*Q`y&TBvz{EA8_|0~@B-&4aPAa=m5wHa10p~^(NlYx@ z!<4GpDYJbp%{=|+p~P7LS>oZup8V+A?aYMF^Y;MBFS)QNl$J+f$s*u~g+@QCUSk1U zD8Abok_k#z`@I*^Rb%JU2FX&;?as_-rc6|+vb^1oQh^tMGbD>ADhte-oB!eKvItN0+!%3*S35Kp%+QfjR6c8;rEEAp-zf z3)p4oANc09R_uLe(4AGNs%0rf^$W)pL1&tQB@No*S5_x^v`PqgloLdft9!|M2W0@Q zRzvw@sFy{xBb!)=i(t5i=59mrZFu=7VCv)yQ5n7h7j_ys*)SK_3Fzm8CNBn4a1 z2j@rRl`GHLaCMM`V}4gz}f z(Lkc*zo6Nu*MmN>5H@g|Ywx9e-Vr^7Z3F&ac1#qxFurOu{-Uks&>jpkFOE)au*k-m z^sMa8aY>tbr~#U-CdTbKa(lJVE+-t2XKQWHNE*M02&08oV-g>`M=Na^#^CM?MI4`6 zk1O{qNp&Ej@8Umt#8KeGEI8~pO1KVO10hPx`LH7-_3thnG28p|RNMB$e>J*-o#WK)ON2!$^iZL>W z3x(!4U8gI&s&{>}b2CJ)%o7~_0~m_aA&eM2gTIojcxgz8k^UY8gVKMevrR`=DN3!` zO25Co^P~A?k^+c5y(ozl0a0k$TsMAt=^gJ}1@VW`bnBo&&0x$Dh9DPM+asUG;X2!>z z=-;>+vSZ{_90rz2(5oFqoGqg}4`9#Ra0Gb_M-ykzvVj)d}qHnTny6t=@2yjfk+jYH?<1=@N>&;NP^*9 z^j!$SB)c5DIUnpjyqHW_dsyr8z>5+=6^@xpi>caNhm=7e#rjEWX<-&UNJKd*vMBKW z48ykyzDMJ2a=wcFI^quqDGrnNVTEJu56ap`vpohF9YCsfaI@p=m#R3xlQ26w$3zt| zm^zHkPfT?=dYLB<?+>bWJ{WI>Wi<0>uw6+6d45|VdMiL}cHm(Mk8$l$f5MyAM2|91`mu_QYbAw0ZzE zQ~`WSCT=#%E8uX#*g_qf&4Gqx(rwjnZf`?k<(}DLx znIce{DHtjqlaB$}b4ycX*Sh=sDA)4VH5SyvTPg*SN@>O{LgtR!tYLcmkzYvvcF1)ux?>HyZM_NTGsgy5jOc6S+US7Qyw*$w{0;( zzK=RyjP%|}@z@(H%n)dR#s_X~7BFk_1qPIUMN3_75Z-GI_XW+F>x4Ap-c4(JeU1<( zA2uetH6`GuG!Gs$4)@N?wyh_{jw@1d8LSW^KV^NuZ9w|`HNQdG-;>L+5FcYrhhlp( zWXRbSU4pCzHTFlI$W&@pY3<1s=<;@M}4@(e5CNgqa4cCz?;=s1(Hv^mzx<#d$i%#G^-d6vHW(X zG{#oLt8yt{e_#Ne*3|=?32g%F7QQ>AZrnywLJqe}*%DkLZ!yAZ0$NFiW?-d+WXw`r zUD4E~(N+6|z6$Gq^?y7uG5I_gsaz*~$c3IrID#Eg)}1F6HN3z}i`6j-(ycJP%xWpm zGz;-`C&Uzq^T9aGVZj~M%-27NITlQkq%d*zCKYw~RUZ+L`SD3DUj^;{|gCrP; z(@KaK)8LB7s&_%_tqNzmJiC1yj zp&Q(DD6*5#^4kjgYooHYkA$xnYM&e(PCxB^I!L)+aZA?z^CL13hkv>8ra7ba&{sxH zpYD|O+HxU`MgD*(?0e-LFH$Rq^my@6 zXL_{SJ*zA@Wjz5pw{m=Zo6bqI*8c+wXRc@p5RQCw-j3ug)U#`*^ZsS;YlrK&P@-ND zn}3tOFT_B$!dKPexX}T5`X*9V$wt06B#o%Sw%|y)GxLr)Gw5lVaOgMQBYzk=>pW6# zLZI}o8142fpnhfV?V>|xFE)A2-*`vODf)XPg^=(uq^6D+!Ag5hYuQr-JvYQxQ;3#P z|JWlOE3ddzF6tPMtTMeTRD214ki)UYuE~3q#uBwT-n2N1m(L^Z*b=t^pXhjEN|AV(ZTqQkmp2WzB)lpi_^i*L zj^cdK8?q5tbK0MB-fu+DpPDN9jba{WYQLNQoY`g%8nB#}eud6EPx#{;-d6hf9QkiP zwzpjvW-TsQc0NSjJo#Q#qkL?J*oda}5g@;|`~Gl>c^U7#tgn2%ys=+@_=Upr)9`U- zLa`E>vR~NP_Tn~8B%rwqt-pW1zZoj(M3D5pG;18L#kgGv>+<#7Kc0!!&k9Z}Up3w7 zO5S*26A&mOw9|jP&hvGP!gR;$l`>*$%2Gz;ZufnGW|azE6~C=NYh@{Jv|UfaPsoG3 zSJ+=j)7CJGXHa}@mT$HQgcxM}VDvY`;uBupBQ`bJ50s9nZf49pG$Q#PepAZ?m zYE?QNK4+u6^9kFi+Ao?hX7BqZe3e=*_YD(#F2QefYwd3`yYojI|KAY6|9o>z`(p$0 zo;!G1$}+#cin{532cnAybq$x}QCjR?yB(jKCZ4(d@t$-3&u-s*(gFq$!*jM8vrW=# zj>2HWSpX@O7qbBP7a5^cY%pExjF{rsk>L*k>YAZf3@U?Tp%KqiR-xuTFw(XbGNedV z5<+O&{u>|RaJ#i_{3vM&WY59|8S-o8pw(ZyYKev=Cb2hS_gcg>#q|^V7zqRXkpY!{ zk^rf1(gFJ~+stRxhO6uf)UAxXojN?7NEgU>1S-@>cIC#)OV{Ecl;61bwcW9nGll4Y zApjOwVI>I84UsL(vEPZvL}gNG(}A&83|(BruK#OkKB+>FdjFbV*hn$$>wfJz#TA$8 zIToQ}FZyx?QcNNoqBs~h1lL-2*^2d~5Dp>dapm;;O{urC@;p|ENcpa+$Pu$Jr@oX` z{jvnt3;2znUxY3r5Th}RVb!YXhisO00`!wug7cRp$Mic*Oq`-0L`=iR$n`!5>ueTD zJB**0X_%4$w!zmShHi^=)RK8?0@J$EDBVAz>_$44SZabwQi5DY5d-4d2BmSMJFoIO zQSJ!b%`+ac*BIhp(hP?C5Iy4ZImHY=RK;>LAnIQ<8JoyjXR0tQigf7?mJ|ddI)T_> zs*IFr$$4S40D)xuuAfd&^qb=Rh-%GXc*&t@g=kGc)+;7y~n-sGUOC zLtuVVxVodg9cB}E(*jyZo6OU-IdY>sBm@SN`K>Izizn*v(*u-S_bDp~yGOMc#Q6L# z<&SvHHRja;Q)}rF9Su1)zy&zfCH6HT+{HTdoKIr62dypHs}B^-rTT3r_Z6)(N!XuR z^Gq}wV4E^CV|oWYw~lT>u})`iKa+uJuzr&J$^v2Kl%>T>N_&zdte}rz~k{Fdvzx zH2#?bG-EiVky$L}H3)bDlv-Og0db{UKHHSve1%UBFV;~>wvs=^0*F%6mU&Y9rpPD{ z=HvOj>%458yb=UVjc%*N!|HYL;8!mNv95^u=o(7GZickJaVlqbg0xlk>%P>nrga5i zpJtiFOD&fwtTG>>Dk5gMatYl~pGXwu-5G%ZXQ~K?*HYbiI~+V#HYm0-ys+aMbo`bAE2djUY^J zkFW@JncrXz?Jo2H9?1gbv|UM%%^@026s7QG79{J#sE(f}|DY3-x1&DLTFd}0S9Es9 zW^4&spMWJUW|*MtGS-Uh`aCAvQOtG4R<#7d_rTGKDTd3)h^cM~t8wv!djc-vZK*Ff zYxyCpgc@7F@yMmBzNbj>eCc5KLnprxatxr-sMWz}PyTEzI%wJ=%<%vjP%^s&dnaT$ zewI7C*s)5@(4_`DCrs4GLt&%}`^J0Dl_LF|={Od4LMveSAuybkK~zKEG8I;bnT@pM zz|7K=(x<8%Y*1oho^*8IYq4eTC7!ONu|XC=R_)H-%jwtnTfBIUL)*p&9EvoUH#Xqx zCr<-r&mC4G>-3or7}$FlDc4nkE?KSO{4UG)%TA=T*-Dr$d8q^sLjt7BK%7 zigQ2nP1L!gRNi-(-cLw;T7vl^jW<}}pEX9K=0v0@$YeUsqt>A^aXi8)%a=192Ygl> ztQ9SGH)7({%ic(WaUtaj2@zLcbRNx?b!N%>F}m7^RWHgnjgLuO<9RfcJ*nWWx!{#a zAYh~?7OGMl<0?4%>v~aAQD?qfgDVc(t%g&fjH!Z_`3S z*=Lz{{d6*^i`_Gp(bsNtX0x>=qM@401mB4%uhU&aee?kNxuUe<*>FrU2EslEDvRRa z_D3Ctfs?2^7P&On84-48gBS;#hN|&E#9}89VF2wg(_F0-yvu4e>9B;!94z|T(K5E# zAkbAJZVmWi0lyiIph39nQj7uMU*J>SDwH0Wxd@B*R)#ZmE>fzY>ZPa2MMC8@fLTU+ zK4V&p3t^xNb=hqR^~=L3S4t)JlzMsjqq7|niddvHAptPl^f0%CB@rHgB^P29>X*)( z8fduP7CoEVm|htDH}IL4a3BN?7MIgmAys<6pAsrR z9KX37HOBL+5JI;{y~_TmklooJw$dK)Li$ap0Tmm*C@T8jlY&LpS*D@0Vis%LBK-j-&1{>_PJ~b?_5JQI=zLdy4_%7+|~47qCO!!+DQ;Nk%5P zw(nN9J}QoM$4`T^<~t!gg`r1fuwWN(GU^95Lgw;2nT3~iO2NXFQ4*wKcv+`&9@QG1 zV{E-HmF+S>i}^~658KcNRwsQ--)Ze7AX_ftLqa30_ECIBo(NT(bWG~`jL3dwP zy3d8?)_qJ3v5ig_j<%?~s;6cww=OU`-Nsw{+p$?987;h69haYzP6es4O-$pjVfy8U zjk%@6{*Y5rGEJ%diw>fCqL4UAck`))0;0`k_tW5|rTmJ$R*DHYy+$@5BY?I@)Un=O?gLnPQf zW=1o`A@u`Yk63{pU8;70K~16P;|^W1HmDg=B{Ry}`(ki;siRz3zyFdis3hy|SR7t2 z?z|SFo7r*8?*!W)r$+c>fa?QB!FgZJmD6@8?LAc#-y7iZUop#Fw8*)29N>cWdAz#m&B7169Did6yI&#y6 zn!1{G7P)UEL}h%H-ugzW*XqBY8ZDCDOikQHf5`A5v-#+d zooH?DB-X<3Xr_c0X@-6TP%W{fte(!SK;x|j5yJnYe~Rwt6iJ@Y$jxePV2Yisfwupl zWNx5v9dil2kc8;wTzHk`UClq2(QI7g(p`dYx6_LhGuz!IHqSEB6!ZV@xuQ@%w)^cL zBQn)naz!4mJE5A-Gxigv?_9D&;d2jVXt2>ku=5JIvEcqa^nRG^`9=TRVLF zORFvS>W=Cy)Aw9*{Q?fE<}16A7b5d-rO}H}+u!9xcAiD9+F~18ZF6gWSJkg0SZ4BS z8gy0IKfh>m6NA0byIRTkZ-4$@S_%l(=MDF@G6aRK()Ixt{Vq|yGuV_6`5}Ld^`SX3 zLtJ2#9`g)iGkOcPNzmW$exa-#Ad*IX^S24yty-D-q8xsB;V-uPFcVs#@{Wu0F! z7fJk^H*tSLRhqp32q93%73^cC`U@|8b^|ktfyV>{(|L9?gdNW&TP~OD%HtwvBe`K! zzrJxw^AOOc6;j5!pHkYpny1G8{i~$M6;0nPkFFfUz>*%NYH+C9|V9$G?bAs)zsE9zk%PGg~9WN?OBwe<-R| zP?rySledt5@yz|gE?iI8zNCRtSwtI;kibw0lj&g|#hX5K-T;GeVwmf^?eKGAjCm0kTW9jB2w`l5HdMopV~yN)76 zRad5Og=aUGZ>I)_&Fo(C2R6G;|9=NucU!tm;B@Q8%USq%FHT$O!aWH1A3|6l>O+R( z1{`G#31#wT?SG-=-lDQ%o5@}7lkhN2m{wbyx@)g)E1e!mlJ&OL!OpCa<^fkkP1-n#brzs9{V9iE!Kk@lp^HCuJAGaWWPR z_%G_>7S&7KuYh8imbh2AA;!rs)QgBscsn+&9!PvxgL@z1iX?bop|{wZG{#GeLLP&H zAjRBbeWGj-k!}>~r{d>Hinux<9|mn{wXE1dg%P3JefTLeGx0Fm;a*+j;c76Py;s&b zv+)^UY?|fA9Z~rlO!(=bok4BP?43%h z2&qiF($SIJ)QI{$wkVt!*v!`Q_*U;y5;JV1z|7vWy)1_PYcAhwDKOvrr3LFDC-oGm zz>f$k-FtWwY0QZv)|Jo*fIDe3?vP|n1Vrr7)zzi&RL~89uN+UTUKLRu6PtKYUCarD z{Y}!=VSHHHr$H7WpVHqDWL357WV=_Q4qSyJM9S1u9LZ#hY9oecQuE!-u;f(~)3Bv> zjCV|C#M3Q`o1QOB#AzBDiR=>)vqb~Y!kgG{bO@7)x&{a&s96Wf!CJuCMisdu#O=xAFpVBlG06bw#dV0z#r@Y{h zbm?I{lio!DqhYUp?ObZqecMFCN}|>~Zru%WKf&@(A)O>-V`$n>ItCSVP{GEc>ML4E z5F_C89g{5sVE(oS>%){srj3RAQmE)M5sss}o(DVogev(HU{`Elmdukx#2$sA1IU;^ zX3I=byHUcF5QC<7RkS)h`y2^0&lnr+uz~Jv*T$ul)v8Luvsb8gSP}FS9q-UlO?tm; zW>ff)=6ArUC3=X)CaivQLIBA;$KpTB!@8%X&|o1=#=t9-)`{z3z7tW-bn5T%`J7n&c?waZHtC`_-y?4-+`!ecevCxW8zgoz14^*eX0d09!UVJia)Ty zyOg6pU-ByAe&$wwfv-JC4ERJ>U+hK4(;wNzRQ#1h07J~!)l~?w8~zBg)yw2u@Im-k zUeMJpZ#=zMKB0&c;^SbFRO}a{M_I!oM%+l2V1pH76Ba5xBIT9-?h(z4&!kqsvn<>% z@q&dzyn@>VSO2=^f+1J2Us(=iL?TpQW1bq&0?0*)OEHgGpIGS(YjaHyq7B6~G9hg8 zY$Z|p4ynrT@GF~rD#JQOCTlqvev&NoNI()P~ksf;uERh_{sd zc3p-_us4Tu9{Hh&Wl=oqQq(*T@g!Mu{y^ZppgLm0Oo~(El{dXg7#nn;j&0A<`l8p` z`E&e3EUFjbE)55gKelxn?FLE>k6KuV3{QuR6U-CN?cdjyATqsd{i6lcDc0M=gg=Ke z#f~gfKj*p7iK|CyWKd`OEqQR3;tZpNW`|s^GBdO4bQg8RrU&I5n`oJb7T(P-{ag>SKHa#j-y5U6UEa+*A{7_SRm-B;9GJ9G!oL ziJD4I;NENcEZHfG`qkwiTh&H)g_6NRps7K^OSU^tss3hcwPusRkNcrE_%k9Z@$w|Y z>t*}By2vhTSY%_#Z{8j%sY>9cHL{76((y^tj(hQGol??7ol5XYq(EOQ<<%o;mZbD# zIFC1qY-WQV(i0xE;WB;bcXdZltOCJ2WeDdTFOBG_+MU-t=qMrIa%GAK1@HnQf}_?E zy{$qO`-s>uTS?x@&CK2+<0YT%);6iMVwsQvEfs=`H!Z7fTy$_Qa%9RHUAJtIt3Je7 ze4FKP>AuH4iGcgF%A$Yc(@pzh{|AC8L$AsX1x7!~V1~O_vdeE# zDTl3a7)~>s9>)Rer8zdFl*rTn)i$(42JgNWeYc6ltErkO9RO`{RMHRL-r@M7TzvwU ziySHADg<(@ir`#-o#y{B(vAs#VM^XjSAEs!yREp`W;^N*7p-akzbCan4%bgH9$zFO z{B+hz6sfN^6b%~-|MW;A3BGJxI8?zL2yt=sOF@gJSWmvAWh+&F{vd$yT$Q!dSSJf= zwCZ8M{eehRC9r^z8+*6vp!E%FyX-|fjj4KU-}?~dFfRz4L$N&Y`%~{dcGWy%ns4L} zyHtENC!+us!tI#Y7RE{u#RsuF)nTm>VrAA?=RhIzM<(Vab%K*PLlQI5vk1<^KI_W1 zkJ~gv{J4UlrU>sytf#O0-oWNrN5*MSv}^9G;meFzVQy#htGUtLs+1I?eo_n%={m8! z&I*nTNg=IdSgEv-u5`;)HpMg&>q&G0jY9d3`iJ5AKZ{DTDdx+86trv18_mmVsb*xB zq!R9;JN>#>4(Z4#7rgP6+iW)MaWp8ic(`Yttf$@Q93rat?5DJaLc{igG7*1v$?5V3 zsx$-F4*)dBR!+l5>2uJXDszWHR44J7OSb_Vnw7aL1%Lhy)q$8G>PU~)s|hOg)SeHr z=7ULb!0k_LSFRnJ-)uj>FcAZ<4e>);7XT;aFrC?XH(fdS++$v^ z=558rVmW9>AwSUe>17_?CH@D zAdDOcAf1_%>Z{(n|8;A)|20n1`(;0SiZ>?Mh0DpPXa6Vn#fmB4 zCYw=zh~`1tOYC`5a<9vP%(03;h0R*K9g$8{RFqhgJ+kQ7W9zo3>&C-h(IeM+1eVZ+ z{#3$OKY!%s2zu$X8}yq3S44l82TInla=)#Wp;h7W$%u_GQOu5}7kXv^Emek{*@%tR zu{P(4vymBLX$;N~V_WmFf|g|;aD%5ANL1gnqJlMyQY1m)^V|ZPIFG7ZVq)vh>tRWj zv@Z+Mp|{E>z5RLZsao_Q?tcdqB+DHNCx$1yq>NdX$6ZLxiH<9TykkB2rBPNSiEJ+~ zl-=#g0%;FSS)@tVQ+%X7X16&{tSXXTC+u~sAHtQ~7e!*{GBp=0%v=Ls|DL}R-0zUS zl=lck3t-#CVp7)DBD;O1$Cp@B0oh;z(O9aRw@aB_ZO?kQbiN?r(y1hfsRG|RWxM>G zqVL`R6FvP;^f~`OdDKIfN-qP?A$h~A7`>Jdbw0cHTTO4q{v&C=<&_nRf60{-m5IUP zf_jvL>oeK5)lo8m@}fsGYO6n=_+foSna4IQQf#JOth*5f(a~jpDHcz0CejDBuxiRkT#ZnbU(wov4C z7I*GjL*1Y>Lh4K|7mH~@VGeGaIZceA1zjw)3jfB@D>$`y0AkX zt;+=sbPJZGYLykn^NZF!2k6JWAJj+n?@ugO-N&QvSA7}NPQczPV)@^Y{G(l+UF-5G zd>$L~?_Y-o#?$Y@lp(K3RB$4JFnMWkl?cPTJ zVmZV;$D+OWQzkI(_k4Z!d5c87-=sNo3FYZs<396x>3=`Hvf6!JC7=i$viL{3vR|+P zP45{9dH(!s;gsFi0ov~NIw$GF?4$ahRsWym|DO-aQE>XWo~Q3vww={B_XP$GV8dJ< z+1vhGI!W2y)Hv&_=KuMfz8p4YK1(ybA2UFv3;p8lLl*#dWC`HXjdUj4ByG}r>L|l! z$bKNh%w#M%scq;7+^+x{4ofO&o0v*o{Y9OcSz|=x#9=@QO<2_eM3zg;WAo8(E}$XX zb-e+H+$jJdetf+?{uJwACu)IoeNfvM-;w&i%D0eGQvOlqmGTd}PCUmC^Zl^+;sW+u0_;Rvjpj5?c=7r7mH|6c+9p_S1rck+rHV zPdLU+VR;^xqzofb$HMZ4NRA$&&P*EGh!i$1$&IQ$AoCs?8djOo9P1O8c#eC4hr@70=7^3}9P z*{HE?b6#hl6k;_GG!cADIaf1zfai%E3)Z-23!&uVz8;7&0-PKUlxn+pXp?LPWc!$FMIp@QTWt(XLO!RR?*@wxod9I|aqyuMK8RiSum6`f{E-F5wh+mm(h8_FUB zgG?Cm)y#x53K!5IZAhn_BRg%Um>K^mJd22k7{a@NF`DxHdAVV zK4%hQVQ#*opX3*RsfXMhGHFy2K-wZC#D(XA{oRV@ex$OA%FV+Axw`c1yGUjSb6{Ue zK04XTooLH$OR0EKZJh=I1rJC#LAo*FVrVaRq8Rw21e~0}#hX;>?a&$T`NnX@`F!)$ z5Rv%z>2AcfO$sI0w(h|>e{`vGb*8qXK`+m~-4Tm6t~H(AZ(xaIo5n7AJ9H_-0+L@Y zW|*0qMcs?5h99Cc^UbH|*QKu1cTFC&>Qq$8C!_0nfS2RHuS#Km`>jWsMn8Ho_K|Qf z^jo+iVO80wiF`NncaX;$6-}g9Zzdj3;(2Gc9=u|@T3&2ySmKRmmov!loMSH)FpIG? zaA;1*!HJvNH|ApYOyRy?E~`qQ_j>aY zXK;U-UBu4q9Epf*`Y_C2X!u7EVb$P(ooSC^y^a&&iJ|DiCU{6a6&0!FzaXiGO38rg z(EFbK!KK)t_{plh1Y5QNYkbwvTg^v4&|hA=ZKJkS86(Tra=D`9=~RpeUiHH^nK4d!d8C@7?ka zXK%npBrP$aNw1+Q2HcP?2B%G*XY{Ehz%GPdRoP!FcDM@hk;}quwB~wY_F4-Ir3;(U zwEZZP2;!+t@G=zbUJxRI?bPL89!slMUS7^QUfYR!nf&Eb^>EDwN?%hM^VAwBhVb}E zK?d_UTv9%T2-bR>VLLTvzuc3ecKD~*6u&V-(KUJhe&z?E_vHf7G1)&$EdLecB9iHA zqa&)wYB;Y(j|Po^YPu!)nz30e^FEs4B4#JFi3Y+fcsG!cHm@9aGYmEpuq}JIBF9~Q z<=~D|toP_vReUF|!dyd(a5MChfG4ga0ymg(P}+u-G8NL#Dh;4Of=azo=VYT>rUKPC5l z!0_dv%2EgFlH$@B0BN{)9LJdACi=;GWLY3NKG183Fuk6Kc$6P|rdK8eU~)_TWI`%M z7nS`#ECBz&y?eGDhKJ88naL^fT=6xw*EivHgJPonbHCze|Ck=l(Z>om?#V^h2_~E# z(`jIxlc+Q#WIG=eBXRL)KmEIbBH66Gj+o0gh%KOF_^)5`y!q(KIWh ze)(~7QYryEpb9`X%wb$n85gmgJK0v?0s0`Vpe1wv{%0W=O_)zq$D*f9f`B&3W>83r z?@;Doo29Evs1Kf=o8R?A4{k8GoG*2%< z`?D^`x5PYEuqlR~jfFfXy}aZEvbC|k8dAc`^=lnp@xflm{$Ij|)_WFT#csQ#X=CEY z`bX8dMR%|S-7bZZe4B{-y_1xt^Aa@m#1JzfN1wvaLFERN8)`}h zUu_ue<$D$Ok%6-2miS_Y(OJn{cQONyKg`XRQNbS`4q~-b=WVV_N{XoLY3YTM6l#G3X@T!C#ncU)+Vp6Tp02k&|89~cGbPS)d*t#g*qIr-%bDk` z+z`?T&TZZSv13{Y(|Rs?Z)E2Om^ARbHKa5j-tyhsr8V>7fKY>2R08-(AC@cI93unj z1F+Wz(`1;c1oM$#To2mM`kuDPeU3UhQ$F)J&tlHPPU4eZUygA7@5-bSGxmGgG3+U` zE?4$gE61@d&Rq9FhaEx1cCi#;UMY{};C}*t6XNvUHO5Djnvku zy*M(Jx_0?Wh51Omr4d8BKpY~N_In^#l)Bfn%u7){JYi-{3O_4d%9l<^EW`{etL&3) zz*8>NDaUr#M>o6q<7MHSFa3IA-i*Ex|GCuN>~(R@zcYG8kO<{nZl{%KxOD={XU=sV zh|+5$=n)L_pGzN<4`h)7@!qz*zMQEbk$EWnyIppK&H=|i9p?!7 zjQe`uwXSDZv|SE!f?owX)!Zu_9oMUqZ_wbK8@BYS@eRK&#y{#f8q>$31y)onuH^>lei_1#Wk{vD9M6KR3H(W@<-Dkr8REYGQYwYNXV>=rr8hpZ5{Wd2|;j+ZWSqdvM!%Tp-|PG6iCq8EjEo*R&<{p^kQ zi{W;Xo@G0DgQXrXswCb`ScqMy<_gnq%`2sMxuKz$1D>pcBlUi&%dd>lg|x5l)czPu zL?7w~qkXO{0Roz zvEXa>v*W#5>pvfKU2(bkO3>C8KJLX$IRTkgxxEPJbb95BZMxCnDb8MQ%(_~AAXi*} zBslXy$jrDYK{mz7)Y=1Izd>T_-MxN%8<>B62z?rV(4jJ;MSYER_g(i`Pl27siV$I6 zke#$`IsWhb`u{wf-!Q-hO(p>KS6UV%0JWK;u{Y<7!A@i&7oHV2Ua@zNgX+73jFp3z zirsIsFu96=!LciOtQ}(0-&g{EGTZidxjJ$bu{WNAH$G)hCPS^HE?j1~ZZw4icmM`K zW8*dk4u;qS@I+=31H23527aI=rUZ(DIEG;Sc4n%m<3g^Ulxj_c#BGhDq;N&e`a!;k zX+Mv@_OwvpP;n2V#{(2VR^5i63aq}2c=*sjH6;AIRJc{3F#?4{mbqaigWB(bV%#Bgnr~Rt{m-*LqTXj?8-JTNEfCVb8|_jJ?#$;8Y=FB(P`;?b zfX_o9(+Z$<8*#t=wFvilFc>3Q#qP^w%J86%_xm~LS{40)JDk_84I;+P7a(~C zoM@nuTRkDs+gTJs;)nT--kY|11SKbBKD99oS@yIj{SFUUuAiimzE|Cl5roHp+G6aE zKlJ&L)u9j_VZSkZRM+B`QjUX8<+^65F-chXcIZ06(NC@Aw#61MQ>9SI#~qoCy;CwN zAVM4G{$r7hYLi>dGZ%dHscfPd0*5CdRur^kF7tM6F)pL_=C7b;BI8i zS{ruW7mCg8?KB(}ukjLbD6MLR`dx&$4UO+(#Wv&e7xAC`Hcyg9l3_T*`S$zZxvw~4 z=4PTyrU=SxM8-<0`VI{soG60JgJUa9_!;=zBX*S9;8r^-IlXX9a&&d^`4o)9DfkIn zeo`UtpJN)_s_~oEiS6;5qgIF6WW;sU%Qx6~AI>ti)AR_H&D2RKL((|G}KK zxD(~UUsP;ZUq&V((u0(xnFG=Q=V!G{3evfVxs^;>aIKTr@`#6djJK_C+N&k(ptp=H z%@@z|&d~OMf=`_{4bY~8@@!O}KEF1j1=Q$hw;K{3X!+}-xAgOPeApO23mm-RN1wbq zT>1|>GyrUkQHbaPAKp#^8$&A1C*|ukVQQ3u3#Pz<=Bb&bDf#qKc}h4N_Cre}qTp*b z;S_WB;Ci@)54jXNf@2$6nAVnX36KtCOiA!Gnf1kzUZZ3Ri`=(iEsk#VYnduKrniXM)1Qs3JV3{u_7Ni zzD4y1EBqz%8VMWDF~d2GcrTlGRqzyp@fXc?ep;4?hc;2op}=!|j^8>+dwjToDum2@ zmdJ(gIZ7sDY2u?}(549TzCjB{N~O=TF(~dXeWecfk5xiKQq@>SYMM<6;jdxPQw1fT z40`I8AZ66c_jS5WQ4~f3;ru7<1yF!O1t8ES$&B;6X1*Ry6L5(;@j=6gk~nkHcKggH zG9(6fZRG4-N9cyjNr4%aY6C!saF9NP`$K&+bp=7$5Rbo}6nVI=T`Zl8#izoJ4}PK5>nc9a7+1v3?jb{1@H0YzSc@+=c)Sm#DGfTr2P=NAKDs z=6pS={@zQzevFtex1Mf*qvJy7_^Ew~C4nt&lH0rU$02H&p^dMJ{4Ep&@H1QzH5&^h zpqe8JT@W;-UokBKRG&9DS7x;Cw909n;fqxtL&}$hg#0+|KCtQCHDtk*)vcA(mK#uD zRE1>i?(z*SAJ~9qK##2IJ2s{wcf_+MS=1T-{Vdy~=&9p8;NSDy>B&I})Kl5U{CWCa zI%vYXzOI3NjSc@;B<-~0>PqarT}a){FQ}LDJrOcxS8VLBA`(-1xvwz%6Q{6j}TB2{K>~_(@7j7!8v^x|m3ZsqsVz9wZ zEs=ks$fGN%aLZ$9+zQMyK7gq>yrara7E%Ehn#ZtzM(Ex};PSIbxS>bJGtwhcayu~0 zl#Z&mApI_>5*P-OLw*D=wEeX~!4(vK);i4_)93n%5e_paHEo7fiQy=d2$Ptp`q|g& zGPCc>-p?2fJ$@uG>7{wpoWNw%s^T)mEg|r;E?~09qL~!{-5-{3Te%Gs#6J@5i}M+| z_wR_cCE0l#ZeP@$tvw+C*2NpNPtr`2UQ9`9^3IAWTI8$_7V8=7J-&0`vs>(|sLi{` zVrl#XexT1TLMO4UF{Zy29Q<}h{YTHG45s30i`-$PkaV@5hp;~Z^xx1NNS~vZh;c5; ztL7WFW&gY=_I~FW7nE;hWr2wW~+V>uD>T^;oE**X#{X z80^V65{d7$7`_hWP*k(hd}MR21txz5EpCrc_)Zb{X@WQ! z{AQ?MI>UCuX0(@+$eNzWPJaoP;@)Sq(<%QjJUr9f^l_iOWn5sAI~NjK-r}pRjeDwg zMe^Mj@)tzM%(5s0E6)e~4f;A+ z{Vr;!8?Qc*Nr438aTeC5KGL-(X1#9>B_ug|j#b;GxxANP9**GIX~Z?D(AZ=SCAJIt0W z>TnFtpSe4gE@|vll{EY0?JN*Y$(Tu4cUp0D>PonK?ab`@RAyg#5EM1ASlEY07p-wo zB0?S(>vRngT3VN;$5RXrK8+s;@S(u@0&D255a!P8?6oF!8jMLKcsz?(#G>nG3_j`b z**7ySGV(sgYwxEi@=3WOiI&zR-;e>eAi9v7lFCne!beSM(?34=D>roB z+R>KPVZ(xoJJsbgl=A^w{J!C|1HU&Xr>!@xMGx1SafR&BIxEp$>Vga;#=ce-odAWb zdSxcUIVHRg@`J3j_d?iOhjo)E&T&Yr<$l5s(3Ur!n$M*>;r$6ucYx205x!xUSzTJp zCOS}=H*%GDghG9}m7*03FXpQE?{KcNRQQT>@?Kw72VoxkvmWmrs!l1`W1gU#mKo`q z%29Ef5R!EZe47ZTGK4bmwpniN9Vw1U5zlqu;Xy-9bT~xsC3Wf`SE>+-%c`8muSiy| zCtAye4y~sO=)IxJW z3Q@>WuB)&qqDa~w5CoK6&`yi4+D2b1skuJAJi)rFnWWTeAXhM^oO?9#+%)v>Z@U1G zm&HY0KJdS1=t?)x@j^9q`%Sr{QlGa;4@HqU7C7p1n?fX;v=NqF}x5s*;r+U|M zKKEm7@7r21sSlo`_jKmee+b!wXVndZ0`qkpYZxzx^OvnY4MmPVLs5&<%VDoZq)$4G z_v#3AD&dtIuoPH_*zGq~T%*1XC8Rfzr~9i^r;C+UTr<2_|4KkNf&6d1Z>thuo~w=K z^U=)=WSxh(RZebgb!*`A_jP-uU_&5Uclei6i*NJcrVJ5#So_R_sGU7RA-ciZ>0)Oy z7X|F(uB%qq>u%q&{AA~(YTfms{4icn=cP**J)8qL^;!o8dyd#P%7ZYoUuUb7&ChF{ zZ&h9HH>w+d=vx${@aibVapx@dugU534*iP0di?kX{6IEj?s)bqjwxIV7$k4Av-BQd zZj`h*czAw)qRov!(kzOy z(nj!weq?^lXkO9LZ}->1&icz(No{-3OGb%83r_5~c1vMY$3xFeRUYfm88U1S)ztOy znX%LNEXcKE$*2F;Raj&Sne)<3VpPD{hD~{L;`$b|*g$|Ro96CK^zOUfzSCoEXsbgZ z^mM+ca_j6JAvZMxZnUEU(0`!z@HNTM)+wFTJ&_*DT42Dd%Buwc=K25x4>x= zweVX!hS=!&WF2Pz_)i38%CUZ|;OFNT*p@kcGjD`x{HSw~>VJ?55VeeVMx75hbpwrl97lj?443mTxYvVA}v4gLD3$K#5Hcq?g_PCS9?s?Y{W}$DH{>#Gs zVJ9`wYj5B>W4`SpJ`GfO{Vw)qaZZ7cM8yAjlzIJmm!}xhZ(qWCzQW+(4IA(1YZO<) z;gom%{Erj-p!m3fERt5X*ByeKn0v@gm7;f=>CnQ^4!fyT$qt;&f%HP29etLUr&2qv ze|uKAVO5#5F5Fi7?l4Z@`Jdh8cx|)3Ua}Uqp0+RwcfOoBs%RP9oOcJ20X8mbMV@M% z*LeJet6G`KUNK6t^koov>~`Xau(6nwC7-gwvA}m z^WIy2JZaNhGVUc3d>_eq*}UML{lX-6d*(SPFl7YWF_O+~QMF&pd41lKA%31wdHIs` zFO1kBBJ`rR^5(^Kvi<5z?O8vmiFAjv zhy$ZFrCj?spVv6y#8o-OSZvKwt`<|&w$wY!s8Nyj^vEMY!g^hy^Y=_V^ks@j-*6Yi zyvjdRE{H~2qN=9gfUuIC4yBo*zn%L=$_8`8-=i+{+ad_k1dcvAp~zM%CcFc-6ESBj z7vWH+IHGX)_}?1C>6!x!qI1uJJ2<{-E=H|4fy19{)+|ARNiILd9glI%=d}-ytFo{! zu=!Am@Mw-q{3IGyjDpj)L6|!`A5#Ny&ukYFB@s6=I6&fh+v&pdmJGdsqf1GtccYP| zfZtanXAIq(U4G6U(7k}8{(uHN@@5Rx@vsT`g@sFj*Xp%N3r#hz3v)3K;Qak1N5DnI z(fH$$$K0e(AD=@sCFZhLS9Tvwq>1hD%Kj@OBrG${ZBnVViQFZockev(E>8|&R8tLu z9{q(YqjekEmh~LcaN!MdXAF!>1<(?)>#I(zKaagCzq#k_4>Z7!S}2a$aQwrMSzX>; z&UU$6+;dV%lOF-ls5lE<2yblz(jU}zytHkLJPvN#pMefMRwu~P*>|mfNdmbbLGY)+ z@2LS~I=YTx|AN6uAvd`9#fq~UZuwY|EA4#L4KjN6`vp5_xpjT16#imy+wBSJ9}jCN zVEA1}wOA9o3nW=^`{sI2g49o$g*G+&$}dCbK9di20H1BF1C zV2!&gFQ(^o!zg!fGoj0*LsQA8DlM-ELHmagOp+gQ@^dJstZEV>bDfiee=@yyTuBk$ zHT1aeTvjpS3(NMomrc-opR|Juv~Ne&?)snt^jR{JVBI&x2|;ZL+L97V4l(QDC>Y4c zg|TcTW5el%R7`0x!cnAL<)Fgz(yOXHX?B0~LQE%&0d35Puvx ztp3y$uXJ@{7OTr)3Jhh7N`s=iFuT>QvMjgrEGchP@^gF^R%9C?wfk9{u7pfXi1>Nb z3uoq7f@{A(QsG8ZAfH8fGIiLh5b_?B*3FI34pQ^x+uld+gR1!#w zja6#X)4>k7#Mkyie5SZTJVLueC|?oJ`5g;H1@#eUj9b6L!&e|I*dxWNMSQV{(M6(Q zwjSD35H~=e)Puune2*imafK52Bc^H3;+2s61EN0Q;Rh_ks3+FsR4nS-Iw#*B*FR~$ ze*UF*%~9|>2{`P+x&8a@JXjQIaL*gXX{q}--){6O(R<+cq+<>HjF0u}@yMuSm6zBl zFwF!>9E?lnRKh)X2eTyqThv*f_;m(mfzNo-vhj0_?66qUn{&-AuKQ#HhCF=?5F?nV z{7DM%Jf_=khl)?q*ZxYs5wdUA$vhc^6Gf*Y;sJ2DMO2^v3U$f&k&^1H+Tl zZc0A83l;X&!Z-)CY@x9->qkApDJgdprV%^)S&LHx)nKFutg7XoezW5?XEaL-(BszL z;>VEl?X*b<=kn50f$-At(vUZb=7Q?+&IL6<8_Cs7r*~J?aH#pVUu_^(%FI!dBeT`? z2>(&}R#Ccx-j>U|$#1>_V#O`UmNpP31Nk_GMWaeYJ#4EQ*o=6cb~R3TK7d|V~Kg0P{ydb{eXMO3VaFc?#;%yDes zzVmfbWo)AOezXl(O4ZdKlk0&{Y-nawQT`=a7T5= zFMcg)KH8pn_&@Xb89Mlt3=zIDmP^iXLrsk&Yi}jYvU@y&2GGS1Yx&yC_! zSc1v}5?xAgA55 zN)!7>K*0TEfHe&SfB#{-84x4(mmLATM^4?$!65C8bX*!xYx#RxAo?Kr z3bJ%NcfF*@52jw%S)RctKd=ywYW<@}UT;}oC7por z1-<-6WJ;jvK(f}ctjDU4lSU(1UyM-C#(xx-(?D*13!Fj~G#To45xAC&88 zeTm}-I}%!?iV5a@2k^D`0z0u=<-6u?)XwOy%*-XK^Iu}|Xc_UnDO$$V)DxK8bOXfv zx**pxHv~1d4&!FG!YY%;9~KuyXJV0`Oi2GG1xbmkB=AC>MK5zOG8PdSY1l68<|S=V zTyPfc4IDSgHrKxed}?y1Rr%;VY{PAdz{@9s)oal?@9;#(N%*hOR0pw-c^)ApxSRg^Udb$sI1+EIDt|tdh&;j`0lH6|m(#Yig2u+}EWaTyQ_JplRj~LN&sfr*tEB zbQ})UsD`$Di#DLJFa7NbRX*b?bMs?=qQFwbh}H=YKEN#TEU%?%T|SOeX4!Yex>t~@ zh7x`*51yj1n7PmJls4XG9AgEHNX9w?(A}voTWP(XoBY{*T_5JXEI`KQVfwN@aZl+! zgewX!J+^&=yZja7hr`YLqe@x^nGNoC|JFt;u{;^>KJZGV=-D}jeU#_Pkblhn(TyzZF|8Ka{!h!G}@lFLUvE{Ac%$ z#=#UxYSJ&c9|XjCbQ;Y%=ohPybfAf#iR!69?As8RYyI_Mb{!)~{pS~ffZFV_CVOcq zKbQF&3w_t~4#>LmyzPt_vhdNC9+bJPw?7NvCACgVn~o&&13Fe?I_mN=Iz4sXc!#vW zl<1dm07<&PG#2B4m7gq`xB-PFj$rpw#@O#9uPSIA*5+%!&^5WXTPPNZE%CkVk(miQ z+ZT~^KfO!}>VFb-8@T!QSl{TT>5t$ovP=49GAZH$Z7IWJN#xtxfe@;|WJ7sS4L(VS zs70n*@Sk(hYrkyv6$;*QCD1m)Lk-!MWnAp!h%(2)C=S|47v^ECi`x42S6^irI>Lwx z&YR?{!4~|&oNb-(%)a%6dwnTmoLc!52IRx$pQ{u8Eo60pq+m@ACw-kb{k@wg0jbs-?s?xs9!gs2mfTq z_xKXj3*fAPBWCUgUUPsRy55g^^MWrzv9CM)Qlm0WMs?}G#<&)5lBnmRN2avFwi}rO z`n9X=wLY$N1kg|aGZlL3<6vbvz3mB5*WThvJe3xb3 z$QS17s4Q~b&MLdAx3oot@MLg^tou^$hGOM)%IWCcC$7cT9QS8W!SZpb)T4OB<1V*O zIh7p7J1g*g95a)08;^zU$RG%7-(yhuTEszoLo?skaNjBT#>g)k+vM!n)K=?gksN$} zm#W(;sEauGu?YI$RXb2tT3auRA}Hh1kNN)`-~X#tAO+I*#&LRMO797=zHF<&%-$<= ztd}>g5pCCqTX$Y2R~C}LUXaHkzVCcm7!=mLXYhiBU<#u+dDFb~iabkT!J&%0lkd1& z^9lKUAIj=W`Eme;S#K6|2FSpv$%#KV20S%#u0Kd8EO)*>bq*d?!VW99bPGc9FuF&< zk2A$v1)U0I0zP>?p{4%;#a|>i?dJb`7z}tG3@9Xj%p;el8wz&1r5qYhrRg_%?l)3& z^!-P?nEP~y(`)M2uyG=ujtUjR!rFgpjy(6q0bskw zmH*mZuFYwb9nYteMwz1Yt4bd6%TCx)=fF_``OAKKjhqG3 z%nkJQ89MFwGUu2bVC|c7ti^lw)N%GSp7k%d3ON1tY7xP!Y)6_&yz8FZ_-H!Nn}wK4}y-Lokq`F1c|I8PS^XBR=9BA z_sC#vT)3*ir)B^@>3reQts};TR{^@nXSlNKc6EOe#a}!3LwfJt4X*bb=c%bd zJqB?0QJnjE5q4#{09XP`w5qzh1gNGOMFYfID#G7M#sfBlQu$<5t2f59zwEUyionP9 z4*Udo!C|G0RI~QJTr#hN@EJ(fT$7#F=O{ZGqXkDSm%z+mVib59pmW~A&sP%2^pLPD+0+t*e@X286ky(7+IEWp$ku>Zv`s| zXYF$!J>ViK{#C|1(-W6Ge>7#;M~9&DE0VvvtK@lRE(Lh=EZA_&f?o9F!n+wowk+(% zko_H_ImhH|nhG3lcAz$1gsJevm8WW*6rcduUwz9QA*Ze?HEZ)1zHs}V$c$4=S&)^= z^vZ|!0Jq#x8Yu}SDe6{8Lq=ibVNIbYhy%S{gKEYNons0IT7yRU4mKnkos{bOqK;)a zr&%5H9?G&Ge#wCKX+8-tumci7H-Vz#Oi&7v3@30*N{>|!8j&X(m8~^NqTl4T~vZ1Q}oyp_I3at7(8m{X4D7p zzE73u9G2QUuA`BfOQ?%e;9=xuJ>t0(Dx2SWiTcFHvv=%$&T%BA`8e?iL620kJP8HJ zz$J0V13UU}X(Mc->||qr)exAJau!9q+>*we#jSuRK%9^`3Vv}JP|U(ShMZO=iuAo! zeWQIFez{9xQ4gP(1$hJdOMM2k%53^fM%i;n)c{!C@Q`y%{%V%>%~hS8Le%iRdR5k< z6HVn}syKs{C6}aeZn_8m&>W3(UuyWJfb+g5zY;egc=jFNH$AAP@Lj%25+YyaY=U24 zCu$(>-bMYjxt&T~b_1f~ptQXdpPC6nrm;vQGraO3+|v=l9m0OyNxp~%!-!=GQ)}kf z-HNLUMAd-aY-B}sVq$he!|m(uRbHA_O@y2okyY1zJhfP)wMK-%%IY=<^eOXeUSZO) zr^&R}r;`JdqCas$<}3w9yoMh_jf^f&eLAylarb*#GC@b)&s+GiC`$rwcwRFtOJw^W z5%H}qko+sl7nSDHR(Q$&wibLi*VCS!uRJgfzft|Llu3vfoww*oTWx9=cSFU8?Aqk8`XJ8i^noPSsRhtkWt0EH&!UW6eCEtqjiZcUZ34F zPoI=I%Dwr%sd+Q5h%+w;=)nzQSmlz0g9Mxi7Q#sUKS{CZOC2&_%p*GrptPGsVeE>F z1AOH*v;I&iEg#mficAoTyrYS07>=J(MI=gQ#vR^eQAq&oV z(QcO8PKwyn?Vjm-ADDr^G}Z8vN;2~x_>V_JA!nmhukz34=?kdXoX1iyRa3?JFF%2?P*31PzeR&N$6JTU#R?HOXQJ81s>@UtyPonT?d zRD@)u2+qx~!N*vh;T-0mb|9%bK~gesoBrcYT{|@++D+X$gI4T>#G}30ucGqOq4UNz zMd0OxPFTjXSw@i(ZEq44R%dENk-v`elV%(o6+~))E*-vNi z;6q1`abRREMQ!+SX{;P!awuq`{0(!_vWJv$)m8*<5O=LJlGa(yryyABB`5Aa3hbwF z$`8?_O7wakS?OQV{*RX=x16zYlNo0Bii3382(@X#dQ+;>%Hz99w+NMqS>8ts7EKrV4JtF7O` z`vL=Kkw5RFX;DH`)JSI>>&lECw+X)4#mL)VlAm0?US*09>a1{k$^GZt$083uuitDt z{i6#sKyF{bJ;awK+_-Jj`WMb&PDjPrH)RyxPt6qvDCz@mIXz#8sjXDem`3DO7V{4f zK+4F;L6Hteh+L-=v$-Sy{+gU<4DpUyoNCg2O(ecVdR^1|KoR^9*ipm8;8*ev62Q(P zQ9p^#=WZsHSWCZ$^P|>n&Y~^W{8Fy8jLTYv#0J>l-3e&g+Iy>~v&$Crv%*T5d>asQ zeo(Fi9uqEoH~jrODe|fs^1Q1+_^9Z(={AmVPT;vg)e-Gq4n-wLa#3Lj60Iw)Smlk? zi%01<@+%)8ide%!t`|T}QWD{K?&lS$9mI=!;9VTZ&8zZ&IEK3JeK1m1@GUl&KSb*Z zg=$0|U#Q48uk$bVU1G5|qo$gkSu4Ejzbg}S5*V_kjlsma)3h%Ade~W1UIvAaLlMp) zO^Fw7ndh{ZDDOUz5cfdSh6wR0ppF({B#Z6$kuAjrVwq$xS!l z1_Ly|Sy^zR1GT3Ds2(H)PQMmFbk&WUOF z%NRe>W-_BMIgREn$Qc9bK4$ywGV8X-dv;>HLV-D&_#Dws!XZI)kP-!Bi-6qnY@9Ec z|6BbW2x-$>++U8Ph(C~A>iokz@cQ>v?#zuCI}>(6K_l z_sP(DzvrWN@!i|W`(QBdprxAKW8uv<>Zji-#chc7;X<1};FG(xsTwPpto8lW18Cn% zbL9?~#-F>(wL`tS$i`b$i?$}v-6y32ztI~WujAEP>g(@`#RMvh|2qVe;IMhtR-%$3 zrTVX3<#^;xlU<#~u$~3HK26up8xnUnKs)1g;9g;8ufkP0Z!YQejGWuLVyQri3+xy* zGNj{_CT-pZ$91v~=^pJz1_!aQ{n)9qx1S?dSDio2KN=0%-eD_eADfP4ZxG%aJsMZU zr>)L&eSg7}wtc3Yne3D^+4d#>_dJHc!}ClzZ+o36H0bvJj^qZ>G#jaNB;oNV=QqQh z#|kmp-RYTg&-;kST}(btZ4k^LCilzn^)4VGe^4ZI?QLx9ELj$QI+*|c zdUHvD?Nno{v1cStXRhnUkh~9XZXI~=INk_5MjUTx0-vN=lAn}I7OrehuDPE!Q=2Ac zwq3@nB#wGAkl`xwLWP%>wVV8KVin#{(B*%FKaC3$MT*v@7u3FNaqIH9Lbv$-f3xg+ z+VehzE_#F4``Fhs*aP^L4}a6};-?nyV7On9VCO&f@7nzYdw?9t^R46SZTNffEpWKn zz}UW}yRe)+PB)PKbrJlc<9(DLq5X?95k+?fdZ z>|S9nCB?;ilu&Mstnm5vZCcj16K47j4TpD=@xEVW$K&Ds@taT4=)Q*_N9TK8+kZKv zzEq@K@302&)!^w`jyOu=M+RYf=#SQpxnCZ=&7WdajB%ej{|R(Z*9@O5*6wXO1dMxF zs4~UDF;A0vtYDk*?$9ru{O9N`xsagvP}=!eI@G^5=!3$2#U~+IaTjN1^|8yH>d#X) zjVQ>Q4Ch)O!sWA$3ERLddQ+(xMTQD4Pf8iw931yb2?tzZ0Y9?WIXyo^U;nFhK}wFO zn{Ix|pyDMjIK8(ZZ6W)N&+&W3AL1v*;4f~*14o)uVQ&{Pmk1BW5(h2^brr0JWWn{uB38LYtJ|Sr9kV|$# zl8~xc%@oZ?e{Nf(nRDW_{-ENaMeqduu_b(HEukxs<em6Bzf#jmgy0cez6}^F>L4sVp2v%{n}ALz@%b5^(;Q zn*~NMW?wS0a-teqpVpq#g?4f>GL(AF^8Zp^rF&!F!YxypOv2cOB*L<-LGFoIHw`~> z{ze720z(@`JrBE#rq|yqeq87PM1w=SRDT}Z9u27nb{+}9crE$fa;6=ZF}%=apclT42vSsc@cJF7tLhXeq@_utYrdg5h~!3z zFm9gPvQSu*!-y3;k9banx(7qaXMIw#uXT4FDv^J`{!6`&>tI< zvOx9d8qR+STJo&Pip7j81IDR;Au> z)FR2=;JEWi>;eD!&AK=f?tC{ak*XMPzx9BU&e+Rh6zr7t7~dQPm&b9Aeg>MoaX8m0Ddtgn$~e@lt<4d54{nAsn@)-=^T}h>{i(2xWu2I^$Ru zVFr$9nlwOTAz9D^c#GJR?%{W}F@$VQ5oLDUlxlIoc_qypLc1kA1wVFsvx zyu8Wxw$P^oMWBKC_U~7g+K9EzAHP7-x-~VCB;s`S>vZ4Vi)*2X_q;n}u0cqEO6`|=zMD#qDHGEEg&bVj%(fzA|mMT;0`^tF+$Ti z!$)Fs!R)$bc+zF%%iy>29ib8UQNx3JHKi2&@sBF%lr{Rc!F*aCH^}@Vhg4f&C}&v9 ziiFRz94+jZdIn@2C$H@=`4A)W`;}uO=&3E^Z>N%3@7DcF?dLr$dHbUsGwZahiNP!WbN^W8z|G<*d(l@+D3LcwLmXh*#;rC) z;b~L2OeW(ftQ@6#LAz797F-$8Hbk~m|M?DM&LW5DQwFCmzTEg?;M`M?0jaFOvM5~C5hGY*)x1e zJ+6pI%tAsdDJWBkGFL`wYVre%(H#AP(H3?&_E)Esp?>HDDLb+jj%2BzPsC#FVWJ@Ia2sw%^ER4= zMtpf$Sz^bK(?uJ=O~V9+da?Yw0LRrlyGad1Juf*GCI!%2am_R+u&EZ0^F0cHm#mAG zCnGoFMkcn2UV!ytRN74*V*wJO89E=qrO2C3`a0Z&U)N>|s;@Kv#DzK~W>Qf>koHyK z*m8LVu`w8(x{1X+G8lgy4qqkKa>rh<5mU8wV>R@gIGVEsdZxJAE+&K&UhG>`=|-qM z%w9)MVkNrA39aT(zR85U!#QOqS(|nw_G#PbXyeNjksB(-shSde=$6{4)n_(kHoYq1 zlfbU7u@<8yjm=qC{O6O&6<U7{0DwRBb`glSmbRloSH)liO1+O*Ow;MK4|tTu>ifTx0Nsy z{3Z1oT8hflX~>97R~@+tVg!g8xN5bIy=X+w?noz}FmfHD4bMBuYj=@cidZ!@fUg^B zc+_Mz5jtx&4;p;=5+W&APDge>viFz6aM-0Zvx`bF-1W2(IL_6f`V5m0V6&hPM!_xYt< z#*DlPFehDhwD#xLaxeIfcJ!Q~Nqeq|Qi%?U_NuMM)WP3hoo5H()a~GObYnOZ1W5&U zGj6{l_lhC`fX+U9q1bbQRq9vn$x;+D$8zq z8)(YvPnjZhLa``N0+&f7Dt+Gf|5fx}-SjQH!(9^g$4d}+r&Q!E@)AkU(7y5)1gpOTr%ScB@@CPn!_8(?CS6%-8GjO}D zxJlD&>j*|Vq6(NPUTd+^gJ zY**pMVfg#A;Udf8UVr}l-`-Fe{y&Sh{LdI8wW%f?AFBJ{7Djd@@EnGHMoA7a{M0f>B{ztkq+~_orAFe~gEkly;^pmqMeM zi@wKMfwjx%2lXGjMZ&iw&cn=&8BPt_#7Wtymm^C>BjAL7C)o}G$dmJm_|?|>>*{)M zq3LE8mgH=LIE{#J3Puy`#eRgrP2NPU8k6mpPu?HtecdLeH=R&1z&Db3DC7;#@B(R{ zYZc8=agPQAI{W1l7}5t(3?TTpvE#Pf;qCFgX~VWb*v#c4ZlbkvlhLokS_xTyUQ2n~ zVtxD9m^+MRMeXG&`zi7BBY6D|Y>|Z{l5snZUE*c2+VIdo=Pxe~Z7%paQuIy@pny*Q z0?02qV)L!y^f}hFOS)uwbCpqH<@E$A;9nvwZ$l+}eei zpO^ypYM6f(aF7mFgJjLkkmrcOORG9=1FOS_renxsisau{=9U<74m^;aaadEE0W_E{ z2D5jCrSoDsWP8aV19{U&v5tr)^R?xQLSBxf(Qjc;XfLSI?C6>#$>aydbRICqZYxjI z|DG*~ejOtYNX5ggiR25g1;RXDWl3k@MH-CmB?IcD{50bnLcQo^{Cmxh1`slnDJh-i zV9*+(v0zpuuNEt;ba>tw(g!2~fWG2KdD|NVGF)dCx&_4wGNG?{5CDY4KSH>lo6Rd1 zO#UcKkzIq%USd{wR__8m^N{I8y&DUlzEMprsa#Xbtd5Rz!SqOWLf8BXLl#crp^RRc zQoPGWUDuj3$hT9~hB6tzJ`Oxo64FKz-NH9%xy5y-U69uY2Nr)8;^>{${K~UYjww2% z2KYCMP+B71u#WKem^o9<=>B%-qDb=@$Pl{Gkx-j%mW~Pr|sfz9n^u$ zglBu$um){*O~~W63j9`hR~d_)O|LWH7#}Gw&BSBf3RH%qxQwac*^YCGdKVki)r&sS zbKe4Olc!zpItMWFAvqs)4FJb-4)EEVL{!6^@#~BtAhTsIYJCz-`(Fz(&`^&lO2I$k zK$cIE84^n(iv^g#2;DX~UtC+5Jhj+E!kGO0-z^4X@$@ zMR9Lff4<5f^MKx}Wp3+C^%G3WxhB-Jfbp`PtC!qy)>K=0i#e{eE++i2g|x)mVqSmXeB$Zh?0Vyb zKc(E1&{dYsBb0?-NNDDh4@PTd8x!IXNRLYx{enx-Muk$HEpN;{l;2?t?_p)KjrLN{ zDBVXsRtlY?H|D}|LmTdn^})0ehOd_e^L05dMhkGu2qlMA86P7##n_JIy_(NYb#0Vz z`n|V(79k?qxJ3nH5c9KFv0hagCHTT__0#~{ciFR$OOOQ4J0koxLJBq5rSpy>;p20k zJe7O*JXkbk1omTPApFjzq_?aRZlzOWnF11TsHjn5BZ{{5-Vz#{SYQ98cXreqRtBg2-+4i%TjtU5CrJm!5~ zK)8+7r>O}b;71Kr^`wEe0rFoPcF5Va8wX305f4-Za!a2uf?i)s;o(mYgmQf=YbA^l zlO<37iw($(amGFjjfI||>jPa*sI9F{=x0M!!~tAD1p)5N?_lkLw1ZgiHz}ehv=|t> zpklGsv5}m>C>JYv7%Fw2(lY#@9}R(bZYxVGo9-T4XZaX)u7!FM+-nP@&~=fJFgBIg ziVl?QD6%$%=Tr|HSYPwwEKo^^t=f`6tx2)lxAph!_U%F$00h=IKXfG|kQ?^mSc^u{ z0JLefc>6Z&!BFX^$a+z`t+|qYJ=@RQuM6I~NHyDyU*aGo?<(}BAEbk)YfBobxtrV$ zMRyou(4K7o<~j>PkYT>_|F!uCt zJL~=Ud@tTS!fVn=FGF)A8@pJ&99>-<^Tk)dVdn>b^|`@`9*fXx1D+9jwbcXXq?X0fXDCDi@f@2c)UKRe~I(7Xt?>qU=$ zIxi;in7>9}ffqZN5llHA@SluN^>xX!4YV*_+0(xD}v{7mS83q3@5Ol(qXjDgG); zC{56E3KT)?ai2jzXyzoUxtMnE?y$$SF)$y zeOyEh=E3iB4vsZquokSC*?iXUwl}yoNO%|16(BT#N!1eUQ$B_yX`jQE^az z8){e-_bh&uianX1Y3ailOOd9(h4YLzY2lf;ndjf$X399yzPX*apV!z_}~Ab*KK=25UE7MwZ?d;xaCIDv$KCXRFyzE zqBQ8NFF*5{_qWYeM>wo%e~D)ML3mYbgBRaM)YMn4unZ={e;s0v%$t99MCqS!KyxvA zp*$yCj~o4UIn_LV<-B*CBte2qA-GQzW}KNrz$VQ>^5tmn&Nu<3BWHEEa^vqtL|JTg zV#(J?semBr+g}i-ohbCqA&AcL@&Lt3Mnl2r;YRo?M%uFn+%=hOR5dOYJ%+Z;y8IV% z-7QU47Ii?Hz5?Z#|3ziL#k1Nw#&v#(T~}3X*Cp4`ufRl#jrye23yTpWna!`*L3cQF z*H>*vrDUQUh8z=OS$tkjGA2hoK1w5zzr)4mNX$!MsH$KQAf>=-ODeCN8U|!T?L~4; zAJ+WxL{W8mF(|Sy7#SMTKF-rkj!P%<%<}!rca|bJZ1NtV6f&Z_W2qv~Jvp36A?nCy zt`Snb(jUzId@d#?@;Z{C$<@=_4*)ppA7>R4nag|~sqIZcx1Z;yzMrD!6?e*SL{w+p z2mI8ptcm(EKEgTyzo!{bo^ojcWNw_m<%%ppO)Rlh|G^0^ybfIfCFl=_-3kGg9S=uF z+QZPRls*Ic$u+lcO7wgOa)(Lc@AI;o8hSDsu)gP+)=CM7t_K+ijQ=u$pApUJ)Ct-+=D+rkA;A@GfWE=l0dVh4dh+Knn39-O}6_iDIcJlYNp0SH(qUw^UcHG z3kx_ICHV0BgH6hkl;$eO4^xb7pm2yCKH1>yr}Xjq6=EmTc_BSt2S`ya6d4a88)pwc zYS%esDBADzEJwA66S&W8$LE|*%KNX58&ohM>tXGVkQtA?!!@yrVBqj`c`HJsX`hH` zeD?61oUTq!N{g^XA?XdQP-!574V=wj+nxPsqKz+H6Ww<6IA7@sk~#;RFqnDsFgnL*Ox+`SV<8 zns~oSIqeJK(!%~xzSHqn+2+L-7TA20F)P~8j5xcqCVw*F|GIwv2fN=GOzMiGlp&dh zsW3)yYx69Su$}0BWx4B~502LCxJnwF?*@J6{Ky#G14DKWCiDFdVIkkJ zKQ`E5MO4kj<-~vcJh7~iqcc@$TLQbx<6G$Y5#gLpIMfl+X}Nv!sOHrOfu2oj2~F%S z^cxctG>73B*{_rRuekTY)KEudO)`f*b;7cWncDD+65ZJj=j~}^h)zyG`W_iKmffY4 z1*&-^{YH+k5UA!G;~N`>3;C3b%w8x0+ZvRu-0adtCx=cqkMP$q*caFNH;+-J@gfsi zrOnDY45|VO@ak07pXXo04(}r{v-3AnLYJ8H7aaSU+~rs!P`=-M+e?z#HSdK{Pr4vC z%^Ap#47nos1Nq?_Diw!wb68FB8^rQ;iu9*75DWAc{+dgaH@&U?l8#O13)yqZh`0%l!AR>j_z}zt#Csa5niund*73V2I@@SB&d^5((hfeOCRKen&TlY#lfPCy!`ee zX=laS`2io^f`_N&iCp=*uUTu8v0JW5+TaT%=(IfQ@L|xOLj=9b(rI=r)8YfvPoEA{ zu0SC@Z0R7i_ z8oKX8ceOE|q2P#!^dm#;E0Tzz$8M4s(0ldR053f?z6)tTL-EY(gRyW#I~+cSbZB2v z5wyfHERMjAU)LTI$c>;lTg(rSeyzQiqq+XfsJpq)XunSIeG^AhFK+Fwq0x*eA{hJO zxvofvx#mPp{FCTSg|GVa@rRD7Q*osdQTmV~S7wwDmfmBR5^_BoVZbV&~yR#kyij@0L9M zS>lJOq~z)x)x<>`MOFN{;tpe?LZId3#bdfg21t5of`hVbKGGc~l+;~#1gUbOKLE6mNbL@+P}1@6LMx(9+xfPz8yI;A6JhD-i2{`6W=3v^ z3}U|)$wn_6B!uS@P?08?i35I>rx@|?Qf?>`Fh(?yx?t@Xr+&YV9!2F~H4ozN0_FI& zWnaJYOv$EFWuW3fOc<&Iiw|6XU=mQ5YRa!P>=!_jMB;W(5^U`Vh{*&|Lwk%#6`ewxNzdAjhN zsm8+%)(HxKr{V3Yi3NQ59+=W0mX8Mg?E|NI#V!sPj00OOIx^_OUG%n(_}~ZG?0h}o zkj_o%a++1wl%g^74@%ZtAFOHly99UGH|oxzXVsV|mOpcsd7`pLvK0C6+$ppCMy%GV z(Antyt%@%*^K>QVoIZQ}vI;`Qxa4*s(eW}$+v~+2N7i_<7Ed*_uyT$BNjag*VPn?< zC+Z7n_ZrClU|bQY3AZ#klvxrUtcgbl{@9x=Q3s?zQIZ`E-xWJ|KoxtVO&gA|J#SCR?67=`Athz-pI zWK2a)*x+!2+&!qjSN{6|$K4D>cA?#B(6FtneA|zelJatNoX<`L+F$B^2k_d2&mF5a zP)$ZfCVf6z8Z6Xc`~I=PTKi^V+3U|h?c^gR*@=5_~8$u!{<)1G>$y-)lxy{RaCNu z{-OxOK@NIZ>0vF3Rx`cli25nfkt$6iJ!r?j5*nRnh;cGP^*uXI7EfCpz{E3$y<=Jq z4N5$S5-P(CqyP0yTqykx0}l@%W*MQo1jvSI;0~yX3$r;U5Mi{K+9-(x5<#!@h?ti> zOwo#DXFZB^@X5+U6=?YL{=>bRKS4Y?K;oy4ZO&@1oAlqDQA3Nvm?&=NIF=ylP;|x~ zD}wLItP-GArbl*e`zi+?;wXtenhDB@C2oV z>GP4NU_U)Ie-<0Dxr1doT|oC}Ms;EIrD4<#=bNs%?Z*%+Lo38vK08;sB+4bM(0ot@ zU|9|CVXJStkfQ*t&CsmjA(OmX|JyxzyX7w-uB98)(`{r7$%h_IJ6V#f*+Kt#%q_DVcz^A1XWJiyFW|cR9V=fFcv0163yn z4JnH|zJ5CdIEZKsvH-*Eq8lc6PT8j2N`t)PeD~+VTmAbS8uMFK|+`?6xtGL-}>7ShwmA*ph9QFlZ6cm&!h>{G%= zp$z(8gi2%o8m$8eP63M?Z}#iW95;IH&Vs_t?~)6@t!+ySLw>y%!s=8iA^aw#jP_o>C zYwg}Q+S<1oV;fJF-k!=~q&H*EslFgpDe6cbcOY0!fmgHzsK|ctU)2Fwv z9wo>p4rLb0(kh~;QRWg%kScersUIo-EFQQ(Xt~-()AVy@7fI@?1v1$`tT52nDDgUQ zIfd=*o00CkJKuquC`z~y)xl4vP#ARKUssX#v!;L5`_V}G@b8%5bIP+Wsl1b@Wszff zMrjHRYeKM%R;m3WbMT`EG^gA+d}m*!5F~5kX~@cD-&E|8;?7D38EA~&Z#Ltcul%=N zgCqD^I?HI=H&YB9ROde_vwYd8mNn8x%?2kxtIZj~(eOL@?NCt6i|H?IdSk3dlnvIKH@Jd; z0t*5QGXPvnuC~@faKJN1f{#~9o~|9L zz9w(Wh&j`ev&v4H_gCkSR)W2`V6bFe063t@3(9_!qpf{2sKJ18;Uu;7XeCH)cgy+ z>&fL7RHcx+?MZJ?wp_Ap00t6WW6STc*(4{lM(gbT*CP$hMx8ue@j$<4x!LFXT~-@_2+(mm_ikdx`~%IjBA8!XLy8}=`({$+=xsBZ};7QXVzA2y@Yx|9V_of zqQakbW+McS@eED<7PuGV@0l|z3$GXNil>QIJ_h|^Rf#knwK2I zb^VLt-DDFV#+po_{s6C&hPXITI8eB`Z>6-XdzP9{Z;8t8+khaZsM4-0C!FQt$ z#VyAr@90$thFUoz@2Q=~^t?wA?3zo%A?I+BMX5 zDv#Z-=0i%X62#G-9>(BVd#<)Jh4>YMV9X{mCKsXQ&d>KjTz-*1V$G-IG3%lq4 zXH+rltr+W0?P4sAp}EtZCRj1a>f-#{q(U_V5qx|a-m%}5W)fKs**y-UQqs;iSIDzb z`fOiQ>FmZ?G`42Gq?FZsWcl>gXx}Z&+Ru_|(NU65y*G5tOQ7?k;(GyM9s{)f$>@Q5;FcvOH2NH6kvx$-@IDG)QfJ5o_M?F=r`~M==v2p%!KCS>3Q^y{>y98UVt# zn-+S*!&U89E}ezIq#Bj64^@I3QduAvFKj^*MPm7$2Qto|o;ZdWPs) zjuMrn0#m!Wkg{CUOj2o{YmoU-)aM|F!PYht-I6k1C$CxZ({Pjjb0RrTf`-G4T9@#k zy69X~!ystS-@_6YO0S=t?}n&A#qVZ`YEQAq6N}zuFK0T4CIejFaz^i;P@wNSp^CcM zTgxreM-y6GFK^(j)c+VeG*16_N|72dkxC_AR1R814Qpa-z0uzAB~$({73v!kXbehE zV*K8z#h0Ba;p$s+Scd!uBf@QB?pR{yegWD zaQ@ciVbdVk)t9;<->HT>L-I&a>1)niKa!1juaI%(-CT`Qq?nk2rq*-+Bkkij-#kTj zmeaemzz-72v39&uO;BFs_6aH_q8EHRI+1D-FygxG*kSe7HB)4!)=sa<+ak?6Q^95% zx#X~mQ)*gxOI5gTVBsga?ojZ$Uci7w6~eD+d=vJAox=;g#)0ioVi8 z80B)P{NsUNu;~7uL%%rmN05ZK$W-55VA&Yh#MAjWdiY;}Akgo=kEg@onj6tDexKy% zhyO14Ls6&A`uHPgU)(NMq2Ww9 z;v4_+Lp#Nd$;9Ji-J0NfdDiwD@@XE&twjX?-kMard<)#&YA$;pk(36vJ&xb&)QEy4 zRAg*9qrX->v|HoU9MUP?lZ^30cDXB@jj6TB}_=f z^HXW51E42iICE%8*xBR9|AYc{5D{>ytWBF>!vYI8&4U48{|4#LpPI-C#5aPi5QAQbym---pGmftI5OONLhC+=VfK)fe0#UFL2YF zd#GL#M4jbCUEfUO(W4d6hQ`@-V2u187>^*xFc*<+o;@G*A`OulSop`7+ikM@Q2tpPgcbz4Rq!}S%RSl6_!#*PS z3Q%Pk4QR?NH-f#;d$xGnt-ByVraUfyC^4jKE9WJ2tMwm61Elg{t zG2RjmcBliZfYQ&kK_+O+S0@kpH#NbcNTRwVqa^QLx+lQ-j$qI)L9(&h=d`;4^>}0; z<_Hez6pP{HeXrlr$|YXC>r@fY)@aYU!N-N**Vd0JBL@|)#w36U-Ixc7*X7-SXbHI+gQDI=W+~jO&I*CvRJ$EcsF(O z9V-*uodKJ33&aMn-&)1f1LrXTB62Qk7G50Zn5s!N@(TFb#M@5%r)$$NT^L(v*9j%` zON>@T+AseVTwtmuIrHzV9mC0UpLZPdVb}+C|R5y4-6*zK>C18jhtjmK?M=^ zhGeYICg;kUmPIa8um4f{hFJI#gwwu1f7C+jM-4LOkbozIqO}?E%KCeA}Dp(j8>jPRAs*d z7%j$PKJjv}XP&*xF(3ZK(@Rk2w&2uok@OP|OS9sKW{7Ms?$N(3HHplI))=l1|87e&>VlGjZv&h0tbyPyZ4x&_ zg6TS#hdDEozg9F#OI{`FRVmJcAROHd9cSUdb{A-tZ#-q!Elg=IZBU!d)hPZ$T4sDY z<-|8W2gDP3lmEi;8UmIvpbpZONtiZ~#3v5=%m?RT!{TChPM)`LSDb2`H-+>tM!|2c zJ!znFBg-wyC_OHPKcMD?eFk+eZ)qrY=7Pae3dJq|S(nmqv`smlC>{;7l(BnmCo;Pp zi!rvDibibR1%up@CfR#iWbN3?y)%@3dM|uvzrb^`rN+SuM#GV{a--;K`=eZ!m5F4# zbII@FYMgwR5EFOq)u`Qc_kHO#S*&enWWu8{T`nXyz|(s{FSjN02?@1VWl{2>*T=5{gp6N-mR zMrqz#G9cU|2COyZ&V9CIV98Zbs&tX&sv0=<$Y;vH#8f`QCsYv5Q;>rh%!b+O(%NXN zC!?P}hQ?l8iZU;HxCf5M*R>(uFoK=cc$@t+yi+8(CFtFys$lbCO_rcY+e)mYZbZO% zN;%S%MFwf6QlrmnVeHJ~iyFM>d5rLrJz0p+LUMFG@C{yeBU}=(jf7&XnK<81n6d@L z@0IDGAw*SexT=oW3h{q5gR(%wIhb&K3VhXWKL8X)tFAB46Hm`5j?0eniiq_f4mF81dkZm-@n}&)-fie}Z$Vk?=OS*Sa{w*JJcd1~ zPL?dc_(t8rPz^Kz_)v7M6yu3KOu5CLMjQrwF)DXz9zUtBTBKM{e?!IG_(abADk%A7 z`o@jG1R(!yMQ$xN@RlP8-0`)(tBoKp>l$N^S^YrBa=Ij|W%xP=EqKJO%p!J<--G+f z$gJK5<-oqL;L*eOj-XH5ESP!RNRov5%%l+pg1b}NUiQLBuDnOiLBQ1^N`f~zKfBA% z8y`E`<{!3aW-~_r*lnP<+03<+#+?`k6~%d;o8{Wx-yEUDIkUckGB_?f4%Ed$a(b>4k-Vq&anb1EL_x~AN?Ah zOx%Jjkp){~*XbY0*E&Zztk=UZFkYQ>R>T}gj+|?Y4EU)1tg3a1-p~TKUt+ykwADcq ze2x?M?vom=F4lT3G2b6A*NL>AShfW|??b=!gz za#x49ygy?m`!kmhO)adgDY!Q2sEK{z=DE)9J)R3EiD2smSlRfMu<>Wcl;%E@jhEu- zMKr%}z_g_lvrJn2F#WXK)1Xy_CyQ2~IQfROvq%;laWk0V@eea9YF@SE@mi-i<*YV^;hwuH14pAmNhB8m&GZ=PWN5 z8~C;FDNB>`&4B;^sZ%y`sW;mG)kE&jT+bJKNffcU1-*JsaGDDLBf$rY(r zXIaMM!&UG!_vM2RJj+7bZ1B~Yf_O<0^F;cxxq~Qu@Alo4Kew2`lo?YV@-oly48~le zf+BiS;N7oIr z4PLMI-({O$x_LTD(}#MA^leujIc$5*mmHpeyHDpUxJ0aWGa@UO>m3(SWJ+tU{r*j- zz2m+^-K!lQr`2V6c#n-F+qM_ND-Ppt-6%A6-?RDI%`#r!f=gMI4BwXAcv#R=c<2|&`cDjx>npsoKWEXf=G<|<_H;t|YWJ<}KO@^9o!j1Vmp{zm zM6QJGjnGZoSzJfyL&gS6zQC7|S~TyXY)_q4Puom+q=5et_C!5Ra(-qX^K${;oH$UuI-hrljH}p$HHoWNbW!-oF+=TPC}#N?1+ML6J{PP>*E?u=m9YuEY-ru zp`Id4cv!Auq1C7?BmjPI9jwMLX$<7J`JELiBR-0+P?mq<0djmm(nIRCT>02i4=(G( z9MpS9?@ls&F*?uD1_dl2lSHxzz^Yjxx{Wt$JU3zWU=#1d)YM}kxNRPGewAs5bh#p( z>7fj#GJe&m^j2Iw`t&Jm?|BH;%E7)mYc$))vNBa|+`ioHSQSKSD&?kI?Dm(w5cHS_ zd9Z2*t`MS^mZ8M*-tIX`P3X@gi7)ZeF7zr^<75$$l5V!|krE&+i22}1W-@phRl*hQ zg(zc)kCHlS_Ys-HdQ`v_Qv#L{^aHwpOR~6W6#U~`Eq;#I<|K<4wamIhv8grJG7Xca zZ}Ze_2$FE3)H%z~ZD;0&uzu|R!2z*JG27;FBZcMH!eX|tbG9%O(nNg_As5&IQWdpH z?4q6Qu%G`5mmN+-K`@bGG(^Oy{x{vca+ymZbIE`iF=?l5=7<28g^89u{wdfMmfXSx zpSkJHK$(Cpi&vQ->@)4s+^mC`fQTi29W~`~S3mXB5*+rB$LxS6i}i*wm-?s~eK^S) zmV8LFKK+8SHW-lmDRllMVlvs1=Z;`H6{<>@TR07lOoy1yQ?P;vRj~*F-EZ3%0T=@| zESk5rG{m9%E5;^ED@%Iu97)3Xc~MqrzfHzr&b?6gnE_aio7WVT!fISB&uzTeQeKQ?AvgM*^_#^uCEhd9OtPJg zU+q8+hsFi!V9nKps7@aT5oxak!JJ3vxg%C?>Hgqo=U*agMt>f={9E1Y_y=YsAzU_i*QKP@i%2plHBpzH-+;?cJZ~D6 z1ohQgJE|dPugVAdW6|d&1{2+&xsPky8*2&7SB%p(l7L=U!5L{&nLPd(uGzxqiaAR> zu%w?g#SzxU@Q(xbes7x)Iy8C7daWJ%RQ?)LWuV-IL%tw*S!_997ApdXz3#O>NhRz_ zM3pqm((ySLw7?~ zOWk=M#7fhU^+`40O@ZI>0pm6B1*6{Czq2|{?x-MAR=?eLs`57!h4QB`tSQj~=;dF2 zc9eMy4Pt5j6U&k$=H`IR{92$rt0+<&FNg4VNyHmWNLynOk7!rJ9L-H?%kTFcBaFc3 z7*JuxLCCGi&Y|3nK&`U)!TyEvdwc&^=1C5groFu4WA~oTsP6ko1qt{?Vcq4{fLJq5 zOqVp12#@gUe?*FZ9ZKEZN6(4wWrOlfObhgv?lAL=6hE(92l1M5a;jh+I3SE3VJ)>y zvcMkT0yw?KilgddPp|3$6ILRD{m+N?&>{pjO)Sl$VI`ToJ8?TE>3FdU|6Cb%kh+pN zK|Djm`^D(_5sEqU#6^`4y*3^)(uqzxoIkDAXPqUL5nEZ1#JBTQu%@law#LLs2tg!! ztF;AOP;pHO13&OWG_4T%-BvtxC8?b<&W_HYVmDjFaev!jK3m3rth$5x1Y?AI1G!n4 zBm@2-N=w)MDl^VKz|O@Mf{OWQd$1$QKw640KC|pUIt+;EE;O@np;_e>2xH}Zzy!)KJ z=YKw&Z~3xjGLyA_vz|QneO<%T;q=)~qr@*iv*HXwLdUgAK3Mz$P4R#H?94WFDVD1!ogk8RDU#`{XYUCG z$<9<#+Wx+(wCgu*nhHN`O%QiC6^>)MDX9r5fWp_$*6bh)yJ>U6cXF8!aoaqEtnoXY%ZKerNN8yZf9X1+R+6THXok4@vj=P4{Ic!Gzhd(xh~`4oiMshjpq(wPS2L$ zLT5VVSScWTC5u=K989s6u2YI2jpFO3zj2wC!qiKL5FcFDqlLxp9O?$6p(q=Uc0UOBC(4=RKHXXLU6#mGj;Kuv zax!uDj0_9>(Z=$|I6j%)Utx)fh!yYGeRyAj=)HG}kr5H0KcOij9quKmW1+60r|yJ^ zSRhL_R*aJ_)+|edRhxmvGO?!E{OqD>CkaUek|VM|oyVwYnuw&>KN@_1`6R|RnSJOL zp_z<;)qC~7QQ~>3OBO?a`{1N4cCe*uJ$6^;Y+8?xo8l)`J)(jqx3V$(F8mbQ+`s~% z0&-1B)EC?Ff0C7&FEWt>j3rZ3{P#0i!^UqczYCLPNC$LM)YlQ_U2xpVU|t?ngAAt; z?1d@gmoFuxagTTo+~PxCv_hF(+?_4#&O>Ud6N_!C2&_4m1QYtoelrZ>72D?p)P3Ch zVbn&9G5V`H<#Oc`9Vhe>t}TIK;b(lhwJCl46`)|0UO!RL|Vzc$L&z3rYl) z1I3jEIpYHPQZ^uX6W5BI)(;K3#BM}K&L-1QFM4vzHO5l}36-Paar6Y5B$>Ps+}E*M zBPmpY5T1U?H$ zOx<99Yfb)ZWhuLTK`BN30m}hwr@c=|YErqCKQZ|m!qA#NvBr zqkqS&aO@N&V&W?usLmB!e?IEJoZ&{Mjw_3o*iZKRclUo-0Cyy%p&l=~O>g9D-lJ;J z&Ptk7g!AV8o=DZVX~2N%QKF2y9113Hcn*E{YM2ii_bmnQe(8i-a(Qqc_bavcIJ7g) zk2}UA>MMygx(WG0SG`MpEL*sX_s+8!LR`(UP@}}6Y1F!Iq>rvb#@uxLbve%f#Y&-T zpo(fH(c(01#*mV_Hm_;cfNhap8s0!U@?kQk6bBl--Z*|YF=-JoM{eZ+Ur7+sf^Kso zxkDs6&EeETz;q&HyWgkYbkTV)O_fMX3mY$1`@>Gmc%+R}94B0q!ZHM4y}0tD0bK9q zf}0Of|LJooxayMhHLp!BeU{BXC0t=dFxz*_38Xo5=a6L}tv(?*K_l>OVfR$}`dzUp z;EI$XO9`#&Tr<2r4yG88D$^aE;;%Z^po<~P_o*%x^3i2?b8EkaY;;`~)py+Y%*{kV zCcW1|->vHEsHW9j((_#j=+fP2POF%tckG9PlKGm>; zyCOurIwM>Y8bq97d!}W3=DPD$7S=n2RNU00?u3bbD_FNLz&^MwO9M8l2ZY#8>wB$g zXwyg;TIn*<`<4aO-FWY?SZ5=WP|q6S#Tx$S$)|d2m$^^(Z0dWCJ6*(-1&IM1Bx6(3 z9i%QpF6ZHXLWZ7dGgBUzu+`o@66YIVW(xiOKl3$A20fmude$UQ9+i?pZ1IDk4TjAQ zC{s5^AqLUbilFWLisHUK)MAuR+CjG>wy)b1hkBr|3$gYc+py319o!2KSshQ*6Yj#l%X?x55zIGULZJVu#8@#~l(h2! z#mKjO*G^|UdJ)$B@Wj8&p1g}Dq2zbrjTc8p-d5%q(?ZybzjWYg1$TGR+N*_a4qo5i zP0gyduAy8S=3~`X+z@+LX`Q^3m`y!=hg2?QO0WRc(>O}l@~^#-MYP#=NYHpmQB-Oi_**RhRyn09B(qq|GT~a zzia&e=fj_EMc6>S|Ls%zFD{qx%zXkMmMSChH?y00VIe>$rxbg0?~mUR8+0(>u( z?`w*B-CS=v`Bd+8yo;zd1f!{2Z#D6NO|UhMdS0^`>-7W-=l_w-d65IYU>8k(MPedd zIA3UVU~$>5GcPAwNsf%ca1l&!TyxuC5Vyi2cWu0ZcVFQ_Scci~eCAtOUvQS&ki&Lw zml4e|7096(_JSoBTy>)_+gA1DhpRB*t+Bv>k|Pl@%_17e{rQmbG4T6|QXn{30VxWT zD|Bot-wt*K+hAx zQ=9WJe#JNq6i3)>fTskFkBf5v>&-~Zi-E~-?naPrwb7C+!&ILdY-3>PjdA*V$I)gd z))NnHXVG(zOmQ+3q-_Djw5Q~lHR0P*F%Lg{Z5u0U`19Q?S!_Pcag9}wjnKt?8JhAM z@pvmMp+&bAXT7m4bRVFm=4hobQp3q#Y>CGq;(^tY46#Q_aNHiar)Skj$s9jwaMva1 zbD6nMCzADLG(V;}n#J?vIb!b|Xk*GZMPUR{`HwRnW^}+kW{q3e`vj0urBi{hMvyFmLXZJ9*ZZf3?(kqsyY4*{)?<2r|wDy zR{as+RSFU(B?aYrD;U?8TBv1S38}l6k_7Pn1+LY26yHQ^^mnaFw-$igN=;`+kix#( z)Ou9&>+TBY-yIUn3AR}_!X9uS6}Ky`$S56k%ICDfFjGxDm?ur7@$X8Vl`1)ifHB7g z5IHWE31M6S(b#E>B~Kp&Ehey;?ZchcS@VXhbox2X(@q1fdZVC0d_?%5pEdT^Mkr;-vgJc!ofIbZ*FMc+|{Po1_HL8@RUGV#em zm-tE7cWKmI;E>LPi4C0vI?k1%a8x2law0fj9O|2BWj+Mf|Eaw6<#~(K?JPpS&=v43 z6;h~Krh`$v8v6+RL^Z{54mtyaEm2^O+D&S<>At;%`|`YkzM)9MQ`Ia>QPV=JXvB|X z=l1EO24Hv2U)DeWszA3dSAh+z2|%?83Iw9~w+7ZnqVa-&_LvDdqaF{Y}%qD#s$C{>w7sIyVo9 zqw={G|G7mg6HqZYaLwUZbN&N?4ew>Q?q=UEN19k7``TS)>BYm0uG|d&?HMQ>oSQ)R8d&YAB$FZPw2M zJ|A+C4Wqqsi#jbl?&adbTuYlk=u;YfCxAZe0H5bRtA(>~)ia@!CSLL&*a38ARwY7%pV+uZzg{5!yxmsieN5Gm|lejNqNgza?A z4OvtMDJ4mo=>1d;y)0&mMtygTLjuMqk;6KnA|LWE*_Gw%zu)3G@lp|YQRl@R(_fA_Wh^AkOUn-TAh6S?x|(ToXwPA_0!0@x z_2sIX%6J!ue2aHK(D`^bM749PlEmINht))+AvZUeSjH4Xyq?l}6f+}zee}VQkg%`Q zNW;53zj1O?y<>NBLbU$uw97y=AgV<;fQwIaD-q)hbFjmy>?6OWl;)hGgq-T7_e~b; zNPDdIW5$-lTZ`S4i0+VDBOZzUGkKAhi#}1t`-e**@yx@-z@y-mOfuZ8{u|;mrjJPD zXo8J7D}pTDlduBM^?m0P1EZ)eF9Bgwy;KsV#ct+NE!g5upH?u+^_tFp4 zNz;A@tRS=+TRL)Ge#O(J4kGc7lEx>$$=UgSP}N!G`Ld{l&}8B)?X}@Q!MDf>x~#8- zS4bmBQ&qRqhMDwt8ik)W-61;}`#vW&gR|!Ix7#-aLv%w?0~q2l@{q98T;qAvOEeW% zJl!N8W6D)A&EBsKo8TjGoKajsfT54<`zjz+oXzKm#KwONds8gvPsf<9#=z>MPE?ZY z%WNo5nO~r{vKuZD8t0>mIYCWGEaJ)Zc+)Azf&v@q=&;&olfa{G=@z&+o=Dw#zF{w6 z)g4mP#iQH_Sm3MJ_JrB>@w)4CHx3q{!j(?az5=&EKH~#e>*Po#e~S>{PzF*uVXaum z33x(XCtqSD$|cRlVcu}ZJ!HQ_1Dx^*9`oYsV#O8fUJmCZ+y1x-ZXK29JtzQpu6?P5 z_I^-fOVsAG%HdXJgLAUwqBIM$B_gCSmiDPd-k(HgQAUT3e)^M`R4L)PAF~5JY$(cU zjR}*exm{A^YAj+&%}4K6Sz)NSA1WFeXBMjXSg&wy<)Zrhpa!e*=&RA3i5PemXV!4P zQE%?OdiIb~-^aaDW6JOS7GTjPwOb1Rk48mVn|TjqEQmuJqfP6{Uu2YVYyPpJ9k!eL zjAvE~I2kL3p7f95x5hr!y0xTB#i4RZhE;r$1-!@Ktl0tD#0RTeqP4=4gyCONc6^4mz_=Vx2k4Qd3% zB<~j}&}o*IY3*~>E#-MUHrzRXosHyM=}vK0{1)CDX*-}y1(N9*Sz!0KpTRiBk8@)S z%?R;U1zdd3pix(F4*Q8b@DZZTcP?6KDE?hyv$Q9q3N?WQ7Z6V|he&SLk_%!M&C8%F z3w~tQufqn7Jh*dv(&T-`0V@Zp2_17DMX|4M8B+J)HwBsu{R@6MBJ{VG$GZIJQwT=@ zW?qfZJ9r*KbB8urQy#D8s_Abw}Ej%ZX{Ll zwRYq?HDqFgZM}9ItvT`vFQ9O5YApkx;H*uiOT{==SLYBhR4;@)%%6xF9k>wRu`MLw zP^Q#_9K%*)t(k2x z#4ANWOhmIUK-9#((&t!DFQb)vT0{1kylU?ECgXaRRj&Zp`W*L{bz;>RZ z5V4=5j?>v5liyEIcB^oe8%HVM;8k-q?fmB!;g+!8c)`(bM`K?;?i;=GUgyK&)T9QP0PLW^v z=Q1@nud9p$9EZ?B!Tt0z#(nq<^J53i9a9Lx*o1h*7b$9mI*Eay6^E;Tm%dp}(VKX~ z>ZYE1oY}ptiqeneUC%^EVEzV2B|cnApZy0Y%XJbN!`4S5vf5sXjGTWu0sLcpcSugK z3zRzAX+6FN%j>3*to#5sX^N9(l=s>*c^oxU%{jm9~;m{9S%xkgz0loWLF zp^VIn>D=n5I##QF_xj47L>yetO)|ddNvl49PVD?|Ts8IZT;%2UOKreCpam8VtrF{F z!*jOtN>g78FDKix%v^upq1Np4?RKl_SED>!_@825pQmiK{U6cWO>;F^!&FN2pgSm?`g_trk-aIAVim~;-`~Mt)1uf&g9zN#Y02Ke6TLMhKA2c(SUy%4 z&NB(>;PGXC0zjQdPtsTnVhum3pHGxera{Dbae}T`G48+Lv6#B$ zGZgzw)*&E2cA@(N9qs9uG;`8DX!v4%bwjugN-WZt_arYHXZJ&BB48i!^V0SArE#c& z#@OLMpU@f8m!)q@-OIUHiObTXW2OVk(i(rzojTePw7ugyoFP7Q9MU%a6&hQ53&h9O zE=zeUD2FC*_K)4sd=R6_wn&#@I-!S=dLlaX@1S&p=yES@MC&8-!EDoWKkw(KXy$1^ zb@NH!O{ZH2t;=t`=Q>Y5?bj9&mad(^n}oN+(nGnoi!}vJ?;Q-`RM)?<`*|JoL7eDx z-^ku|U`kT%E1u7hc!Dm+li3INFiJLizki35cC?qJ zZ&$pB>7Q9apNExbUOL|{4#&M-t^~uJ_B{ntZXJu7nkRi;%cl{t?3c3;P0!s#Uej(W z{aSa$_M5US?5q_h-H(zF5%OqpV>h1q_QhG+ETqjz^`90L4nOO^t)~^sy`x$F$8GR` zGufNPqOjOm|Jl1UQ)d68tsS;Z`mmr->J~#b9($2+G2EhHe_b!Nx!HL)!f-K?_R9qH zZ`%0x>-h2F3>Ue#zx&H&l>8oNBSpxrR5x#wt}vA^-nHUfx_&RW8OsMS z?ykGZ>P2$Pn0_;fSxH&i1kX@3}|4{yQ|Fy5K)_fQ?kG%)r*)>~l`S zY`;m*g*qdL8Sl)~=D!i2XXe%QA+{a23t^ZRY9z;P8ZrBV`}~&s6ROrYuyqlkky-D) zGU@lPaChB$T;(<85)k}8z0Wv;qd}IMq(_*_Ee&h9=TDY4Uj6N0;2=ISD;3aer|Z4h0Hj39!@`8bw^MhTm|$e%JRgMw zWM#uw%)z;0dV^cBP5y`j<5t|f_!K=90<%P?DK*qy%IGAjD**!wpIawCx`e%We9DPA zk7-vXokYe@k!hwZf%Q?9xZ&!yhHVl8hNdfZla&i@dySb7QOejPAk}$!xL|fHTz+8H zfQHd{@X$xu{^jhy2Zyol{0jKPc@ce&4Y?=fc5E#MRWu(_7d3cO-s zHQ!~+B{%rOvFy{B`gNwVqy`lpikZb(DsiofAp7-Orln^#j06>vEZ1%Wpr%%f26_;_ zhU6v{gS8}x;gAgOAt&9X4}JLywGNB;;>izVl^_b9mAk{ip3d--l>7r{Hnj9;v^|a{ z6sHSFz`hXFRh;AaW7W8eBbh}&NQ@+kMH8fk=n+njxKIi1zhX4sRmgiz!7LKqJRWFh z?sE&C;5Lo-Ne_vaqO%Xq*>?l%EQFrF6Z#S7Sdn~Uo?Ex*RpdpV{tB9q9W8|!T23s) z-?|C4t&mc4|Edz@zn+$)hImr8$;>3|ur`AuyrN!tVHw17+-)=xRBlxe?)ub)Gg53N z3B{z9b>cE*X6XeI{DDCV@TH%v)f;_=^>F9!(^L9jhJ9c$;q6_w_&2)?7%_26LEi7Z7J~G4sd zPJg+pc%pI{(VK`&1^xB1?X6;WUhEDL%DVgA77Gw;J-yhnC)LLh1V6A`KiW>|D^K~{u{>#&tSzEgoNNjxfz zE+rhakMKne^M=|aO%^FA5VMYvLGq*0wV+%8T`)PmrVTFD3VG>E6t)w?`NUJ-Kr7t`BFwlqr>g!{1luAFeqb8Y3f_p2A%|Y z50oUb=h3nNYKBzt0$Hd_WcgIl8?S%JeC>^M8jzL>VxpEcO{3?W_gH_@%opq4@Fc3=C;pD$wKR!Z7cMBwt}C$l3XyKUQ~?a0hxxYDtBc+qLaS z+Gu*ou*|u5(u8Lk6dv&_oC*;*Obw3do|D&uYiwmF{~zg=8?Zjfktz{$0=Ztq)wPNr zuXH77S3JEe^PzH*fkobk_Zx|3=k4l6LjB(s9;a<^nJDk)GI!v{U_& z^~T@`MyTD7hcw|NE`8Z2rZMZ{9Hps99{6yDMs)}dU(DBfHIe98f?-rq?(+$BFlB8! z`vhT&CWHa`bDiC^h@{3Hn7VHI1c>Pr@F`qc9sE{G%;w znh|ZexDXcX5!{+zPwu1S6V@9B8wo6T;nNJz_mtz3|^<&FAo8B=Cm zsS`C+OMRmMLk!>`NmCSj*TC}_60CJz+Mnoc?PWc;@+TYz;9aNh2HR8n3M^#hl=@y_ zhHfNpoK+$yyx0Lp_i--BN8`o9S)}_B=SGf-pYY3f{*sJ&KdI+g1g@FVJ|)?pg<_mM zsRab)YH3pfES?}Hr0G~!^0;xNSsa+_o&coUsSt~NmgA{NY_e1fCu}gs3T2&Bki7T{ zTWj$X#cvrxz6}Za0fCLHh-;q;XFplkSS?s}f0~)B`4E9r<2VmdpvL>W8o7)8z#xH#575cW=>5a7eadKD_YTIk zDd=PznF6v;3g*a8%YlyK`a%?UNEgFDRFDMs(hc0;W?CM2OF=%1Sy=efSNL1G4CRc^ z&xqHnoW6a?{St}5BJ#7=4!2sSmQZg*eHM30UWICWRf&HCn zC=>vl5Ifp$tfDKPdFK1+SKf@7x>I*HPyFIWBrixdgXNrn;V*)I+y_Mr!`L(%m&3YhR});jbfOREK|k0y^53fq1}k0!joCeHtqs!w zsTOk3)NB7Lt?ke}Q4>x*C6Dt(iQ z1V$?}7>R=fD6{C9f_uojqqH(=kr92vFey-U^!(>i@2RhIs3P7qaeM>bc_nmVl(uJJ zxuK5rJC@4yaaB0(FT@{Pg3;<?@fW6GTV|X+pU+aaY$V$kvolZTF*UIY3 zjGVVL-Wq*}Yr#wl^v_27xq?;U_`m0S&7G->-nGM_eEXp6O4+tm{tgxD`HtKsh_cE% z-@M%CncCBYs^es&_s#2+J5}%*t+4!mY#*O9l$n!C8WIn7`-S3ul9 z9-}k5#{1kKud7{#N*9fW=5&~VvS=?p{2cs}m}cL@i~l4;c&LR1Wr7ky^`e)w&Iml4 zS$5Jhu%4Y!4?X8muVE*N(mDVuegpyz5gvheUp{%v(JpGHI+ZrSUgPfRRS`U(@_+DJ z<`!PGjHWywTn5FEj_8K=;m+H#j9CoWo#Z-HC7(z0jSnf=;d}OUH_MkSET+jQpaoZ>^^>(KZ!THIFk!}Jr&R+ zDyTNPX-jlJ@aiWLj(a^_(a(r_U6@}cL=kX17s(X9^Lyz!Y!pDxq-{3Wb({ByUsLq@ z$Ns1iN|(ey>qzQ4#@l%-k}$|*w1$#>zcV-ca)CuVky6RqdDnl~^|r>V`X-8?Mnak< z)Ajg>QE=b&v^e9G^?oE-3R31pb^2Ye9llS)=I+#lOY%j?@R#ZOKHYoo%BL%h`BAyI ze$JWV*HJv>8KOjCTK9AB4KnQ03y(w1Mcwg0Ifciw`|~KC%h)&X;}#R{m$v(M;WhVb zT~zsH*i8qG8P>N3zf|EHZM*mJ8k)Q{ZDnB3^wO{I$NVzv_wtv&P_wo4|0jH|j~$13 z30>^u!L=Mq^RF=!GO3$>+T-ow_c@f)_Z&hc6Y+hfs3utZV$eRwy{Lne?c-yETC1`r z5DSCv(`@|SNV1Q;Yrg0~;Z1D*fSFC*I`~8paQb*$9cy#cF>2u@W$Ww!KK{)es0-8A zsOJsb*m!%rAMAm|c0SHmEB@yaCzTxGn$f%DTM^i}DdL5vm_mDC^}URo&e8$ixWALi zG`zWl;mhR&nWYe(qc{FV51L#a#iv-`pRF-fAU`q-n)FGcIHIyXvbbk?JaaX6aE>ZJ z>L&c@mCb?wbH$SP(-eq1teGIlVf6jeA97yd)$jIjx%esyGw}wPgTYpRuwY5Vn;gm+ zC%9lg%55YX7{1}OZ}H!A%g;Vp!>FNDs4OzUVwVD8k~#kpX3*PO0v&Y82@ml*dK3^a zhB*^>R>w3Drwp~$RjC74QsD#vC0{X1iKzF);xgk?b$s7LMV<;haYU$lU}VZ554?{i zgemHAAtqf`Ba8%+Jux(x&bS#=aXRu-`&RFp`uCj|Jx6v?N6R|iKIbwrNL9nLj`uvp zFj|3n1CQW_8OBe%%KQGpYt>x0W_=LiV4W#lGotXLaJmyIpVB#a@`UvIn6UKLV0m2i zN65)67m(0v;>zO}E2RCw@*yHr-zWK8g3CMIZaCrnuQu#kZv;Y|i|Td{lvr(yXE{}UJ}c) z(w~^q1|I!MsTDZ?Rv78oVj%iAc+D0MS7g>hiC)aPuuO9D-yjSJ>A$Fo7p+hM2j7eO zIe>wpkzv-jB-JbvEK{PpaW(_?9k|+7P;38(d%aIwLLhtbC@#gJg4E5*;bAxzA6up( zw%8ZP6ktcEt^j=`nAUo--<1MhiXVxzZZl=A@gq4?w>s>3g>e|M6t|ipG#V#S@^``x z;-&(}EOs#Ev1DEVR(41@K8>b~Qc;3oak%GqxXmgA(aulF^Ky5cvNMEnK#3jFS$0Y# z0TlpzEAj;|cJw(hqC89KH~*A^WX(+c;9{R(Fg3%iILz&E5Rm67OC>PnQobx^SVFM| z5-YmO{wK7o3$P3N`{8QDoY$ z%NF%FUuI)Ow94#z59D_yU&}jH_MYWG*R$WY`i#GhELW_*D6A({x-i_0?QK%TtIy=T z5g7hC@D(=EV{R)5vfvElIE>VxWW5onddmCjMIAAR)Blxx?Sl*DL5l7njBc49@H13V zeHyXRusAS}Kt#^=Me@Be;C8a)YZG?6{YQL}UTmWDu>avP5S|X=Tn28RaBAht> zbCf%5TI|(wERCjY8Dj+@L4u5m`3da>QH#9WBeAS~>7~~ybg&7@}jI}86p!MRL}?F2B26{@n7kkU}dULn`PRzs7Fl=Z*@vS!Aj$aV$VcFt4m11*AWQ_Q;W)&;< zr>gvQP5y>c z7mOCN{t*)(KM~Vs#6o(#%^y;@o{E{V{Qw%`{RER!xnjgXbFGE$^7~~*m=B|*1BTu+ zMTRmzE~gB}hiF$^$l%7}`ftY(bSxzwe4T0B86OCD0>J-40)^4^aIwM{X98d{~-^(idLfTF1f@8-2d)j)n{)#7Hr7#llX@EaCWlkssaecr6Xo=pyasoT*mrPH!FVaA!E& z0d?4;paSA)uwLR!;c>!pPQj<_`N`xhIzE#Y)ep?ddeg03%jv5->XKqR- z=9+#5;>jQzKHF1Ss}fcwZ8Uz0vXtzYRRoeLR4Mhfrsp^ycVRI{I3l|`qTVZ~ywfc1 zvN%r3HyBx0FwX7Kw{(WtRae?F&o2cRD^+Q?I2$vlE~Poq zIunwQ$4pd<{A8m@XW0MbNAFnUmmI!3<~+;XndP~|g7Xqbb z?7v`tgzs0Sh8}*q$z}-if%=0hxMh*1d~4vKuQqs^0?7sPEyhff&P8C$c#w7hF-Up( zheJDW?481{nLaf|!ZoDe%Pm9G%SPwtXmLf64GHP7uD7i>A?WObuy$(~b%69|z#>tW z`@{N8koLJyalt_NiNQwQ+f2UufbUOX)s0}qap%a#Lc+MBYY(t`wq{5(t;e`;bA2FM zTn#^dFLx>NwzbBngAUqL_UnFnv{U^j7i>!>oXhsx6TX7q3f8R(yEJY*xMBh7lTR&Urd(gP>zg;C-w&2tQI}9B!^hH zBVR;r*gcGFkDh(85CQCTMm9+%^^)%(z6BO+NxIt%Yl-i1n4`b^@NXv`TJB^`RTg1C zr2L^pu4+x-N4pkr46!v9fhQ?2CI-{*a~?sa?nmT1qzKZW7ooOB9fn4p^k~r-1=9|c z!JMi34BDatWfc`;91SDC+yw3`oKJFIqr%!eHj{=Q?QLm>?X)o2JqgrdN;6BQb^<;B zI3UHaGXk!D7%XZ|%I!>x3{IWY2ot~k+h!d4~EejGYy3K+z#>R>Wrg$ao4O}A(Max2e4EM?21m2T~yM)fO9d5Fl{+(f)s^||^) zVms*9$nx*5h{e4E6T~;dWKWuggsIYBQxTx zf0LIJ9?8>4pBKUxdKyZ!S(a^+W;m|9Om|o$6ul$`YSUf!GJ8CuoMnq6T2eaJWH?Au zglx!n4weXCf}Clppi15yrmo{dS;yERq3{ocKeF9U zTzq5%;8a4}zm%@Lj?!0`ck&af8stooI%9SdXL495S+KS)9Mke>cR_B91>9GvitL6d?-iTP2QTwRp$)a|C}t_<^DLl3kqf{wqjy`PsGg1 zof1O|gV73@dks!NIu*msJOM9xPCZ|U!w>mnwWl1k_vK8-KK)2>5d5t%>WLVC;#}Xv zK44DeMeD#E_I2U(=(tA7AtwjT7U;NmCzL5|`DSWOk_Iu-ThpE)ofckb$>)iDGBnh_ zT)R&9nrPyppoSS}#iwg2knQD6%LmS0yH&_trd3uxuq@d9`rN!hz!S;CB=v*;q2ew>b=V(+ayQ{y*MygGU#sTgz_pEZKN+G=VS;L5%=V>#V#+i)}_z}L+MF3!8E4i zSgI|{0V7Dpb8E;j>el9{&qeaOpm)kx8u6R7wO#x1<>O>D?}h~AN8#JQ6+6XL{i|!k z*iYukv5TMwvXp8To`?0z6!oIm=WcV}4Tj&xZ~k+8*(QzrLi@RV6M~H{4TZ7KPj9DV zvm%!pc-U+9$3}CNO&h7t*O=t?ojZcrPMpt8>$lZ2D;rOt88}Q-fY-awH|kd{ZNkHg z>*>pmE_XhM#}|yQmv-5(*zX-Tw&&i;k|MG(eix;0xPJZK*^~Pd>s2@FZtW~D6NAEa z55H>N?-7N=YgtglH@QyEXH@>py9E{>91u zrI^WwHN7VMa;Q|?)V|AX&YV-wMP%DdA#|NK={*VSid<8L0gu}dZ_ukOI?1i1gO)$ZTO*UUwpmNf(gI7|Nu zWr?f^&|r5yt(}`ufEgIhDVLS5Hb(XCYB>|-7Gm$4-RZHeXjnalgU&Adto5$bZy@L1 zbho#+g|Xf{RKp-p>h^S!oM>x2mfbu3I_~yALRVOp$DS9BV%DjN|RlH3+QKY~I_@TZskv2eJB77r4%`cZi@{Sq@%pLSbYMn7W_fLN?s_IZM zGvEU`fK`$^3};vtwC?I`68t%iR2;zY2rez{bPrNd_zWCdogGIPqWgH_$uG6u?^X(U z8@OSyz>gU)fThiLl{sLQ8B8szhT$9+X^i>&hOLcB_D<@?dIo?A=8tF}$6LxQw>p5} z2y>B4p$*A|`!QIrc##^Z^-_EwNxkxq$H3RYZqq*kw&gN=moJ@5T=0_vE<6n4DYip# zArB>$cKeFil!?!ub`7!=sNfoa3qfshY?G~G34oCjPM&WOrr~amvA`jjnDa~T6phvW zj{d8s!|Yww*Zw_~p)s_AllB}?hpMU? zsW1J1r9qdmLnYC{%*J;eQ5M?cY0o@o1qVdnpE#>OY?>_JU&3z>2FSo_Fm+&!o0Ofv zue(8lHxoh%Nr8@6bHTH%2r_(um9X_=1Dlumk|zTEA8%(w`?82lYQO&R`|h8A_3&ZH zv%?+GfrQyGZF(_-96!NB#WH*V2RqJqSa+ui*la`wB!29%d%m>O)oeY^dO0jQekT3y->ye zLV^X*)>@h2k->Oh{<1a>BA$u-iZML@x&WrhTj;>I>kj7ih|#Z%*Y4XA<> z+@tbBNXk;N)ijhpstyj_;=7X7#-opZS+&2)ttZ`>ub*x-#1#@gk~c78HekbA%@GjI zTQtlKnZ1|&=Y`;BuwfX7M?0v+vJ&2+CV1ia)nhwGhCD4Ttz(CPM?N0V3a(Yyqp_mB{A`ufUjMYOLU-*113SCGOo&%tJpToU>>ITkW`Y~M%uPc zl2+j3ts0z6b4NquxG(Z=>o^~Q*$L8NqBL*d?pNTn#P7bun8qJGH~hSY&S{l>!bGFJ zWOA5sc0WJQMxxixA~7o&^K1}PR0 zJh^9`a6plqECrYdn`!hyb^#BmK6T4fKiRc}Uv9sX!lF!;rGhJBsX7*XY$Nv7CNqD+>98Q;-~NqzT^ z4$u@KY{p$ZTdYmKyvVu0Ek3iRSnvc7!*xVUb-}g$1$xlAvr4SE&0CnX|~Rk*>RLUkm7AS@?=;zbDz zNWx*`aEVo;(m6qb>0hu-bs%P^n^|P*q^)L)G+uD^RWDK;2aLhy`cvx?oiVzkfpzNS zUqVk6^{v3?ii5F&{(8DJj|NUhN6R7C0TeQnH$*qpFDqd~N4hHoJcxyt@I&Yc2v?*u zA69!#e#>;l9I$kx>P_@6x1AWrFx;W7)R|y*Yj_MWT_0v&(My?<2FQazY`^Z_Ys_<@ zrxGh;m-Cdr^rHOeX~DIyFTP+jSWXqZWBjN048dLs*H_56So*I*@X00(GavVbDYkLc z-}09nk~*n1nH^sN<^%t?{5!+|K|2$=MRG#HT)7Kwxh(BvY%~jk7ZWePKE}Q zp+8;YRLllL5WbOs>$5-^MuNlpVFh2IDW^Nr+of$yp&VS&B4iS{QgU3AP^OX9lDs|r znUi6h7sE+ePjJt4lxh5l4RwEi|HIsRGT<=u5%qllsw@Hc@LL9_+ zm;S{pMhQ7u;O?Z`%*Z=e5PJ%*S!rd+nJHgVdL{Hx?Qd?@R&wvw3*yY5`0di4Na<3E zDJ50Wx$V>~ecn-S0tj<#dnB)0ug)h`yXorinu@QbLm{-zEftNY&p zXQf^PA)PCnsFuhB4yvJ}%`a;Q*)Ot?mOhtohY2+6w0uQ{m@j@Q2PV!ae@ozVy?tSI ze+n%wtOks*PE22#2$lFSu*4E3aSC37KS*<=)Uz;W#yR~w zJH0eA_OpzUgJ}Js_FCH|CSEh6Ed93x{ynu1r^s9kSvJ0ev_UVs9^biDPs*9aS&xbl z0&mh-We_T|(PyVIS%`J6lN)%0#JI$oo_UEB5ZkXoeL3t5LIeQw z%coMSmId_707%-Es&oU{SD6zu)M4X=r4QXVZ$7(DheLnhhCY0wOsFn#6!O0e@icO$ zA&Wcxwa1T0v81(Xh~iR0d!Mk&(>C%}D*eeZDZ4;>`lz9+z4)P9Y;B?+ z+dLM6$q9e(R~NRA^~CdTbAWBE5Wdkps!NMm?@T&417M4;L8{9ObwP{9aLRaCrjW^h zlj4b;*SFkZmQY@6m|%F)*w{MS;HYa!Lg&uY)?jjr{oJ~WabN((^ub(+oY-A$aD{8g zX}&`BIMZ+~!b=P=A5B66jc9_K^*DNT4#yP_T(1L51TKhZn1@9;6x_`y6d9ZPL8QvL zZIm?>+fXXdL}H(>$WFamYt~#NE_9spa~3|2riwG$cw$TAdw>x8m{$A?-NrBeYx>2T z&3-5s)G|Tke^GUoL2-5AmTugF2MF$v;O-8=H9>>ByG!E<5SqqRXyAG>P5vevT}h%=7$%w1vn3L(E;6tz?+-A~Pbc&6ITaDTZ*cQi)P zNWC$$wo8)hwfhCgWLPZnf|$p*MsQ5|HM~Ql-pRhUg~5P7Qw?ib zmz6`J3p6;UsGxp~6GujgYv?4>JNOAv{cN#QRXEa1vc2}yM_|(4)|mm5yr!ZsB+CsbWtRqIeV`P}{5@U`w%ZDEWn^!H2IK_r#EOoh98&T`+8NtS8pQ%6%M zNItlu6&4oAfNeD9J&Qimm5ShQ(E49m3*Sz9 zu4@1LSW9_wwqXSicc6%l4 z%nzZ9{1oxy>@Az2E*Hl_n*vR`^iUn}gW`_u1hDO=$FQY;Dx=4bN?y)48}s$IeOFrA z?L#YgYs0`x{DO+ug&^=gM`ZMQKR$BV(*oyR+3vwbfapPzyr8iUfD+Fv9bjCnE28H<3}bd?v})qF?3{!E!UHo9xO`GXzE5tz}0DDx*+ zKUOVZ3;#a~n5&&IV6bx1x$`^#k|AqsY%JuqBmemJYMj`^uv&3**UM=MJ$0@eUPd3! zYv5r@;9|R80!4|c^i2)XzT>ti4h}wTNGAAm?o75T=pm}M5i)!=?gye*lWuE(f zNK@nhs;N!d4$EskFAj<|`JOqPzu$q4c0G?CR>O{}X{1ap_jEdswBYcVVQhhlH&6RP zu>Jc7uy+Toq4%1n3=gh=%TZ0`^RBU#`yyxXV~UaAVOg~J)=B~E!qfU4#A01^{kF=x zs5ZNCpM262o zqz~8rM@e+OfCRqi1jU395Z*2z#yZ4xbmVjf`^bhW6XYfX+ySbauaS>+$f<>RHQ4v> zU{pmloCyfJ3?`wD@c=WlJscZc4N-U*Y7??xUXA!wku-!UCKKsWaN5`N)=#l#2 zwtpaCN3rc6vhk}2#c)Xfh|w4Tg7Q5o37#Vm3mA}}2+1TR@yBLfOUgJNS|q%-0^7Q= z+WTw}ck2-5NprMuG2xB*Ab6`&@Hza7;(CAo{!lO0m91Tyj2Y3o{m<4vWZU?I zuN@H2&gl-TpdmE9!zfpJzJMXphkE4^CJ}1{o8coRj+BK@&wHi{rHPRiTTe(@aLY6a zNg28nBWi%S_`UpumJNq=@Huqy91ooiQL($h@BnkBqrHqpQPp{8L}M!E_K0_->3n!6 zWl21F*0ohW82`q4PDq^FMIAYqi(M)nFT=p3VbKPm8&OaySB*D38V%s#^oy8SK|L@2 z!VZpN;Vupk?!pmuSSff7#f9$j|x1yB%-oc=HQ%XZ6R@B!Uhl&x@J4^)mEs%aOwQHk( zNT5NoV5`%x>xxE&Zy+x4CRUh&><3D5cdO*ERs#^DCh7vM_W*`VI08)5j-g!iVd$_g zxp<*rE{u!s(kkEuzNRQh-RPPi`2M_GbUM+O{4&G@zc$my;4mK)L(|eCpH*O<|2lhK zANEfC;KINQ0xtE`Xl61{{X{fMyQm{doPAKHUrlf;0e!T2S5ic_n``jbqmN2cj{)mR z)itx`UFJXU;u5p4G>CN=!DR zS}%`7WRyjTys4EJ*HgK5NVq#)kN;+~;u%Mz9jWSfbHSPaY5cSA-N~BL%J+^zD-q=h z01*otoEg%|kyev?r`WksFvUoX_6-J&D(Be7%F zW%mKeP4e7oy3)$GwpoeSOOK5#ZzRDXxAXQZbP4Q~X)w|~JVj9z?KhT}-$K@X+n9hK zetGFIxG4)_pgAS9ly+;2W;^;+2~ZubNei6TwIKz4-)Swz2E$pr2|Km||s$gq)pQWd1ObSziA0ZaB?JL&r43gX#^U`(f1nMrBqjNU=Ci z-FuV{m4J)F7w&fLhn8+5-{L1*;?TpFs+jYV;CwH3Zul(Bg{eTASRwgctRRrFc&fj! zY`v1Z=M#Y@IQv?hyOJBsJD@)ZH+W5aQZ^lxS2H_$m=hx-LCzo^`sWluRyC=#m_?LM zqgvt%j>nq<2F(KHtc~#|@zI?Wu`R3pj;dGB113X4PNs-oVJy$&C}GXdH%(c}eLQu! zK8e&V*F>a1?}@YZO_*vZF34W#i$PqEEhG2=S0&|ouj_|Dk~`W+!ux_#E{|uKBS|@u zw2>Re(wxU1S#WgMkAQ`8_ue$f)>`Fh$0$r8hevAbgS`Zv4}F=J$&=@u1BwCf&oOSP znD8Y-e`t6X{b5lwY5>Yv3n|Un#|QqOQ;E}qAAsO^8R}E znc)UPm^k*EsC*kQH_neu+to7Jgv%Kg^82c)X>HOR|48I}XB1fyIfW1=ehEQ#sirij{_0WsUW;L)enP zb|H~NKgsQQ-mpSgOLx#S

    K*9bT$u*4(&O#a#O66|+4+?|tuLzUG0q+H*C~?)>Q3@^d zDSmv!V?r&Phz!j5sLy|awk{>rHr(7ck6*k;030XiHGS+O!WYk`9rwWRavr-vm{qDX zMAfx*hwbR~=7ThYU81bj8WZmrh=txZBY2-2A4vyEon%|U36e$?h(XgijO`J<({^;! zDzWOxd73;xr#S>VM*F-2;`OxJYNgI71!=0!Hh8x5mSRGhS9(kCPehi3iiL{YH{|w0 zqs+&)cyd;SCujf0cb)_X0x5$rYFQquUoT1hZ^8$Bk6+9LZxU z?87q~ZRCN3h~CB_3{9>=$4~pUjMMjJUV&US@e40+5P+vtm|4K@30bO;y}}@*reG7=EZp0E}i9Nm2b&|&n1VK4gNBZA5|vj zx3xfohEGv4I1!qtMSbYNRHOixJRxvzyJQd{IMVZy$KEJ4m4}?xLZtV+(MHYcIOat_ zI9hmQ+Iu16Z;90Ew*~}_sNmHOD+gHyiqL(rIzQ(tJuu^A?Xw=x3-8qjq*pHU*J8LS z{`}qfa)Uy=A;7lK#_@QGU_A&UmVkIm$We-Z^Mg4}qRTuRtreIUOaqT28~nJZ2KkC^ zjV*iGb|5r?W8~0w8u@-QdUdVd3)fQO0eDcwgY);#94j4zrZI-q;v!+{fUpqfjkLe$ zSt?t-oDOhTUG`%!ljMD97DXbb`aouCzHu?9$X>N646{#X7xZz)pcOiO^8Cn~{pMLf z*qxv1e%b8bxfc=j0!QLQTv!U6_@@hc!B({ROZ%$C{bzdUg9L3*!sH%Qwc69QuO$K#>EY67W6*yte9Cow-w50p{?t~D69XN%(+8fym<*PWh1-6-1p zFevBXXf3q5ObxUq-O!9nKBdsn=Mma7w#8uXYfiAzk?eWA@^+m~7#mzC^5EITeL3{w z@g&T43Bk39ZXg8T>3ygc;i0Zl`otJc_5o~GkdTwuBg+){u+D}58&ROs+ zXNiGI5cMw&)w68zO1&7I0n9j5{IWXgofYx^cwXS55Q!6x_t1hP$8^rY8Qh)H-c&RZ zc|!a3C_@re)ZJ9)A#Cl=8BeI*?UF5{7gmnUfZV<1wMyl-Qxd&CzL0k1IOsjH|LB6b z?cdK+^=tJT>AUNn!g-8;Z2d&~_kfY=o2ha}RGvvYqXp7 zFR}^!g)v=;b=i7BpEJD-6P!Ql`W4W0E!=B&ta-GJzjvS8YN!j^^K2E7eQRY@OwUM9 z+W$f{fzIN=iByVxYkk=^u3+v|I$H1KGK1zf+MF^TvCBHM7&@Nvu4+d=Qzv^WO87(l zON7gvW$|W%C!xbWdF&|p9F9utXo;*wf0jmy8-j;p==(TKoR!K(78nxtA_-MLL_T9TA_Y_X2tQq4}5%YLI~hEo>`Zc8RM~oYt6-Ox#Kd2x)i$nkNJ(s zM+c0BU7YXNGh-AIMr!m}EC~HrY8Kd|H2018J>4A@kNmmf`k4xkHd{;Z3#|zI*y%-h zcGeZ52is5nOpbGxY1URrSVPqz;nI)Huk14t-%=~n`E8MjRu-00n5>zjN5vtf8P>Y$ z(=ffF2<-TB_?GDRL-#sMvN`g7H)W}lD#@F#ZBzzc5$Btk+*%$;0rDLqLd(s`eq_mt z&1N3dh1fl^g~~q5>DW(}VJflt0e_0cY zfB7nuRc?1|8sk6rL8oh~!V(4J8?$ec2##*6e~>NcrNcLC#`u(<;>5HV+3d?YK#)v} z>Y@1$xVLnaI?EuMDQfwQdF#YCD;<;P86zcphmLvnriNqe<0Ysu>9YkPo^$oX?-_bN z(P=v%rOlVUXGKYn)i==Npne+SYd5u5hYV72&yo276v>wR!vLsf01-;k)ToObetgD-$LnI%;^3n4Wa4LEmt@M0Fo;g$K*lD|nGK zc7oDtJaGdA?uIKs_AFwZ!JMYNuE>hewIK2Q14(_jeJ5@BzbzoWuux=@1@u9T5ECqR z2#otb)%SnhX75f$yls|X91#1oTYb2I)Y^s+UT}&j0|wBSC?lAzwHTEk$rKxxg9m^Q zKtrHItl;NFph9d!cK*gQm?E$+^q@sMF7I1zZb+J ze!j9VXTE>08AHVI&O7FDY^E_4VCYCaj{atbqQm2#Q~NELUNH@YU20qx!M&boomf&E z$&_e@7|1@TxSl$sppqm?2ZSd5#urPa_{l=&p%HjwZ6w-+=WRt6X4t5QIzz&cAxAf& z0J0=%KtJ6ZM9$F+mQVe(tnMdkNt&zunVQKbKw@#q`S=VzR3rqY1MYXe?q9g$km(=Z` zBHlcKUk4(*6ZRCw_4SQt{uG4|wrnMzB`yB%z@|K}X-&1tUAEvUOI8KN zgk|?@)idIJ`dotuB51vtpHhRRVPcPLzjREFf&KJ;njg=1VenW!D!3S5cwd4NLfOcPEKii^kg7d z%M$xDQ=yvoojeZla1ZAEk6*2cpUGSbEtwx_AcS>xtR8eUkLgii)xmhz$P+WEYv=FoK71o#DzC)Wu%K!n zr&C%yJ9Fu@e!C>3ASZs+h8>;amWa0}#8nOP2%;kRo`iVda7d+?PJjqQsIQ*xVT@9& zz!yE$ZR)A4-T#9pIx7~>94&vye7OD7;;r#6JtA#>gYQF;DTkC7uE(d4>jh^-_(>1j z2jB$OhnbnqEk&bu3KR8?OH~>igt&;5xJ$2F&L^7Gb3&3$+s^nZy#1o!jkZvrT1dL@ zH)2zpXZA`9)o6=m!|q4N&dVI2pa)UwD4yO^aeVAoo^hX>Cp(=#KGIad<0!?BL>WNLurF#2(+JaO z7yRJ)hAgf3#y*r`4h`Uqf!hRP)en7RV2Z;g98t{fNz2y)dUVt?XeCBps_k@0~#cV;Erp5Wr=K7C&_D)Z*}X-;&{iN^B8{mKGM` zRqvJ;h3H*4^uuzqMOSNe$(XGU8$lQHIv;%6kME>W*~g1=KF-}Ee=D$ zuq1OSPU4RnZ$LkrWyy4l)fw_mmVqeS#IWcJ3<#q1%_AXL?ya(?Cbb3sa4s2j3(jXu z8been?nwH~j=Ut)&m2H4ZOuD6obI&!(|;Bui`&LHtobPH7s0chqLuYkiVt5kkm6tQS0UnB|?xiX?ZwtU47740*Vsyj@I_ZXZG z#wSmdLdbVBuyMYcW>m;k*-UcQp=m%(VaKTIlnVco~i*g{y-~VGCV|`Tqc<+ z{}@%xI5;pSYXPB@|2~hY8pa(|JlxE!2ER?%{o?O`C-$1j(R1+SiXMpijw8wDs5gFA zE?h%V7BqE1P)O-Uh>{e{xM0|Dh|KWI32?l~!~H-i!<{13-yrWZzD63hFHL_=N~}fE zr;xn5)oEBzn?7|L5BqkldgFNG&p*dV`n^=I9KY!=2{7?{`UK{MrxUlfy@e_ z9amH#>lXDZ4urI4a<|Efx7Uz@?F#iaGNAYL@Xh6AUX}R5THuY)PN^!lTsU=6O1PMO z+c+%2mEs0LDR_ekoK^goO<>UyrXWjz9yeVTtAkKY(M7^bzc?i{d?D;r;m$bf(4r7s7srsRobPzl zx9U=})eX8TZw&)*UOv803Rt{TkHTF9-6$i=xh5gy#f5(mQ|u!G$TwfL{5gpD@a=`` zK`l^B7ZLx@KH@?w%>?BfpQN~LXy!5^LV%Az-&i%^PgYK>=e8*M>r{`Ux|A*`jmJLi z*s4!_PjE@)-`MDEl=Y`CzjFvyGv8TZ1q#Ec`FcI{E5 zO13MSJ<(lGNYVb8tbtYfjgFVS4*B09kC01U!z;3w)rHJIs5ZF`68wcohHPUgkqiXj zVvlJ^7~V$ZgkWTfBNg z)W3URCT?8MCrd%^(Nz*Q&YzMD5!J~t6ruw*E}fNvUK8>@>Lk}|HrU)b3Bk!dC|L{hmV;c6 zL&xWrl{FLENlROla?BUlU;Va@YZ^-$V`w1%Tb6*Q%HU$0q? z?ypJc!1Z~Bf!eHv)J2AkiE~YUh9VespIY=iAx^V(H*-nxo*IJp`6r7g6!VRXNt@?} zd4ElTwv9wFO64+$R*Yoq7tqmV3vhtqaz#n*38zBxv|h~ALDMx?P$G>Vc9jIC;LeYA z1sS)I&O=p`JwU3-3RrI?Ck7-YY8!HGhD9Ae#xg6yt6pPBQ)@V*Q6QGql)BL z9)map{FkteKbM;~PbSi0YuPLFF;`@ERVjs3&+!GMJ zs{(78RyX%kOOx41W7UMzL#lMvrF>e{Ve`P$Ki!nuGQz3%H4SgAx-4Faq!uGJ&6h&| zA=^DnEJp3texx+@ltvBPZQqqFZ7%X$(Bw?*ZI%sPZz}9)Ooig7`P)ypFLro2FVlmOoA2F`t&f46u=_&ddQwc-+YK-{bw2Ks+dnlA*wa~D&>04X9H!} zhAJziSx@IzZYi=u*9{6v*7D(1Wo*MfE6sT z^FJ&Ax~@m(7e*=xSAME3z7Q`J0Zfi1kwhG0D6f&Lt-9|Y0f__|3ePB-UEhhdK!%lv zwvMg%z)tU%$=e`Mu%6vNvXhGe-3$ab z6}M}CYh)y;m6|UrBGBT>+y>6)_1hkv>stcyD}0U_pH~Tgx~%^5ls#{Vs?9&3W=@q$ z>*(tt+bxoAE8Ri8l5;z5r}$HCo@%$@ow4_d*OQ~~(!}%leQo!iNRQC*O4sqzTE@l3 zGtGnd!+aS|Ue9$@&^jOP1*KPkXvf*%J-xFJ7@+fV64p}O^ZaNq4e^3RhiUKFy+Dtz zVU!AMH`Sby2W_N*`$xarTdusyXr9z-`$VSvAF^@%Q*Sz$R|4;-Q(4|PKa9m62ON|h zajH8%-MnUcimIdzdv)LDO>b~getQGS58RYDrs*4r;*h#Irg>g?EDCrU!KQw6Z(dF) zgVWTg+&lj#`}co^0XaS)QVRyne9QCr(Xw~@KRdST4*H0YW5kimBZp6jpYS5D-%8SY zYfFX$uTciwjZu0rLGl;9Qh?N84qU3v<;O2QLtZA-AH2^r0zACD&~#_l5CMH189pd3 zseX;veo|c0!(#5H6nX3t0+(G0uWiWQcPqj`&JcaFazmgRKpRPvZe9iuw_XSbN~({E z67`abN%|d}YlMd4i}cFNzx64Ul=oU~ql#Yyp+v*-=ot5)3^Z0KB%nd_}|7*Zl!{fNcR30YY-FwGROrV~N;K65G3_@k^ zr;NUQxSXwkWO(IHqGQ;^@2$&ODoK)jIjwx`>_U!f?`IhA|6%JanCghOHhr+*?(V_e z-7PpIA-KD{!@(iAyL)gC4#C~sorCMaVYpS_otl}NztFpDcdzxzQ({m__E%gd`|EQS zZ!Q@{f?-74=3P?7?Dd*(vUF?%i=YRyZnLYm73Lk1hXp*#ZC~8oq$*FK@r(>U>Tq4i z`;Yt>i1)xeetynxVbC4Oo>dJEGzC!15bW9k`%uB*zD{sy^Q{5w$afeJ5DBKpdBp_b zh>CaZ`3FSYR6#j3YGUsks*CwU9(Q~K7*2ilI= z--abV+ffx}lXyGpIT6$J60n^5DLc?1+%JN!g1QpWo#HCfqq34n_Qo zbBYgJiM|+kX1Y-8a@zA4*Wd9O5bu9|O^mX!rTRh{@pFz7#{a=!i9s|(Y!++1#gkLU z-?bxb6GKe%jVPC@EUyJ{hMPHK{#+HG;@dt-3Lt}0;qS{gb1hC_6g z{1eP8mbd}qpBJ^!4t_0H!X{!+9S-+twuVLL%^>sm zrgL>E1?P?r`Xee5SoS9;s6$Fhf@hKgH@HihN?NG_g;;X#PV-*Rw3Fwqq~8dlIWg&n zawl790jBv=O*9;dH0^hP1UDv#`Kod@EgPm8T?COc^&onR;$3F zD0~{som0o_N{FyGW zIHb8!5FRsx^ejCw=OBV222j0ALEHU;!fHu{-*0Kg zR&90T45yHDSZ5Z!BBGYl zn{Brul+qQ|3mYsG91Cn{CdI9=xU%*26QF<2ICq(ahSPfPD-2}`7yD3QILin@e~WtUWFw+=eggp zq^k-Fc=?Ey^%c}hdrTPRP3)B=kz}^MsAyn#eaty6SC@!Nm^Elw0|?ijmPb;*T9c#u%P3aI!wFhn&_I()P;~_ zJp%?zlI-nzOO&nFV97KX*_;zC@=KT*-qA%m)*Sd;KuyHCGc@QnZ$={1#jaK|SnFZ7RMtaXw_N1@$URNkhvhIxi@MU8#b~4*$n0?W~04FflRVf*>lH74EGbZ1d+( zY3lNa`^2m2g|0G)46W7OaVz4bw*8bGr6sV10(Dd+j7hgtadn-RDE~%YkPTbJb87+yi?!N+YX0e7gMCEJ@I=*g?P*@+!83%Cloaz$2 z{1r|&%DzGUcqB*CK#1+K>-Sp|H`$|bvJ9SH1_amzIWdHpo_jAYVu)M%bj|o36z9cf zOVTgp%A?_B)-~uH9dG}RM&|XaoTxUK`bi zO^HlcywPM6Pn$l`=&kTap>p!JYMWO(ZS7oLeZ0_`7qRxd38uthxwdOmXn8ZbQahvF z0k21ETDE&sASjHJz-4eP>wK>LsdC&z+p229%)Ah#> zq!$9NtJf{|F`aePRWlLH9bjgjb*q}{wB&#{Iioqp+Y~<>9uYaitlqMHP&zyAt+PBd zy@#I6sSP@(5K}6OKC#4f10OptKVq%Cp?tHUcVk#h^o{e%&J~3#F8o{bx3^7tEljOI z8;9~F*HnXsOHIa>jF^vBd2Tw#QJEquL`CvJgZcy1BkJv&9bn=jeR}d9J7rhP4e!L^ zRgp>?{P!8b93ki-TblW_oODg@=H$y;eu~T4$EdHO=5&omA#=4R#$MDL>f$22xqdX0 zWO%=ylkXu(?aP+~sfU6M!r8z%l1h1Ze~LcZ#Bplf8o!k#sf<(?XFv7-hN^r5!JfgBl9S zdc=lMjuNV&j1jI$>KBAB=wLfjU*_{wz04ffTT{@e#8Oe_GU4LSjZSOjESX$Ffn+7* z95?|7TN?_noP6}gat#019fidE43vJs+*NM_ST_!wPbSLCK7SS~K@-Z4M#X=PgJA6( zV|)0_KS0VJ5J-whWZWpzF*FRH+sBP!LV?MM!89JR#{Z857o8v z;qv|db*aiD$CHd)g<@yT|Al3?{o`5xS5p7Clh-#pw@rA}=~U1wNZ*I`ZFZ`QPS<ccm-9<+xrKRAv9-`eo_OQhQP4F|nHx>-E=jZug@E2q!#{ z^tDuZki*-}R&nb=cPnG_uCF^o_bc}Lwx8Fy1@q_P`F$mZHlh?olRV3tU z#``uM+by)=J5?Te(enBrdUjhJ<+nrA&C+>%n&UPjg!^u|;tx9a|9!MnhuGb9e2WJw z@MCtx{_Wj+w&rymwdhFjb~W-Me%&K~y+Q=x+uy4f`=`O9A{lwO*I}lX;_kwWh12A% z=T}&CNS34{K!1lu=N$|v%>Tx}xX+!WLKx?A^j3H{x9c6HAkU=l;{kW`Mk*o^x8xLJ zvjYC;eUS7~YS=Rfx42@x0@QU{Bb?QB+QcF!@*Gs-En95X?tjDa&~p3Gy`!CI>i1V( zZBJK5Ij8#|Z0jcD_EWr2Udf$e{rEqI(Elwg%f|slxAdP{dHmt&_G1tKC-M2o1*}1a z{~n=!D*1du-li!eirGt!kv$sd5=>reTrnid(!w1HEV?^O4UoL6X3UcY!u0rn4}Dr8 zF6Dt~VG#H|VyH(z0okJG8x;z9yfd!t1cV+&p)}ZdnCak$c!%}+C!7blqQqkgyhSKT zR4#Uv@@-0aWME)WN;5YE)$0I+c%0GSsc>L&Gz?G=O@$W@J+I)LjCb*vUMj#ICV~sV zjsOgjm5IxEKs3q?Wo4BMP92x;*cX>g0v7y}7d~KtB7hh$BM11IsA3@QtNz0*G9fuQ zz$QaiAs5rT140F=Ly@J%73L9F=LrA`BFx2+dJIqGFt;gR}fNua#a)bJ4`G0z?NFFjz zfS+P#jA06Tb zL$(N)w?gYgC>fE+_zM;Ajb%Tu1o|iq*B(${p?5=YIDOJ%D&#R}Bd6U4kd*kx>wJ1{ z`Lqw3A5er!DuxDF8p>P0<{$s?uW&l7Q_RHCy3$6HCHH`52OC@^qJPI{Oo>GyT%oY6y1qpg+{ z1jt3{lr&}5(k7Vm8WJl65cD_^qfKqx%36>GS46+FtUwj6yeErjFw@lAQgVzKqE-+;3D`n6iF{eZ2PD(c zB!7eoe*YSnQ6vvryXWa+gXE;IZw2eXEOs0tfFh&cC^7Sz6-HnwUT-2z)pW}zO~v5*3BZB(4+B21whLA{jy1>^Jp6 z?9%;mY7f(}9Rfeal?O33MZkqyh$@(}HAu-}-Db~B!cx9O-S>C45WxII{6_qEfyC~x zR_T)P3njkaq3RsjCu1%ZrYd36Zb|gBpJA?Q%#sw)jY8~PI~0&GBF>EXrurmHN)WW< z9A2fwnUL*O76zxOy{0uwL}C^R{2Gm5G+*FZ5Qm&g_-VpphI}X?+hK-SJr|9=yK^f& z*KR2x2CChM3LrRwmg_JrF*X>}zR&i7v)AU~Mc0RF78uU(O zQR~(a_BNK*--a#)NN)R(JmtQj$y$h5eI>{+G_vL;dWiFx;Il(U*c!*W&-3Td`-#6d znZC&2qT+Fwdr_pbxuALh9%uvEC5P2({R=S&{8q4Q9;@EP^sebsXx7`rS+fpdw5V#D8HvQ)Lc8 za}qc@@>x*Iu{M1i1uI z(`^7C4jC_5NZ00hId)tFzZC)CY-bHcg8$6;)!Kf(RCQQBrr~P=HQ3FT{ExIPzvEdV z=xoJsI7o8EipWHe0~~)u4p=FjTt{>;*50XBz6>&nd38sGu?h6TlhY|eq3eA?UzDj z&VaLJG7QsY>ATKof@d~WqH`#W-*_WbX82fe_I~1)@tmg2MKR~umITC%JFG5nJ>N%4 zARl4DXH?mW={CZd#kEg0BU&t*l{Mgfx8aze@#w_J#Q2t(52GBz4oM7pSCOmVnt_+p z(AF9*5BGg+u=_~0ei_Hr)->cJ>?r&Y`zP0{Tk{gquJJ`KJSIhaXA$S^?xjp?&HaBd z6x2%I2+7Hb+n(txLp%+=yy%DPX=2ui(Y2cGH+ug9zW@7cV}C9ybJ@l~0acxF*fiCF zU(4o8`~*MS5=*arFdgZXIb~Ts~(y`(*L?o!yC^7JN;B;M0xP=0m+&sDj_194 zEHLA`rn1^l#f{}9MUiiqr!JQ}1s1ibaKYa=+9vOpK#4T7bcZ`yi`b?1B69fLxP&-& zs(LJbJ9D!ieL1z(zh6hGuS`;a#%ekXt@)1O4(dBmeneq+n3x>bZw)zau3i%idUzDm z= z>(p_-#j>s8f@m2>#u_u+@rVO_P?>x|Pb3sf-ULN*2&6U-9 ztQ_QMV+5XeKp=Ni4O}@M=jCsgb&2D?+j-}dc##S=Seytn(tUW?-X1(Ad>|3PaLab9 z^=5}<5lH)bs64ZIRI5re+gV%)+Rm>a<1^Z;JG8eyjo>pN5itKEV4e|Pb2f(eZ!xMcU}4-rl4U2@uea;zU~3{n ze9+XPS^6xUWNfQ;{3yWjF3Qvp zdRL3Z`;J+|*E9?3SO7C)Wo@T%{ohPaK*D&ZgUBcCqglszznUf*6OB6uGo$5&P9HPN zqq*3+RS(&H?W)eSqJ7C{ElY^UttYr@n%TCR@SbAu>%OG7<2H@!9QqstpJWt~cq_`U zH~FAz+V;k1=L?UGk4RgR!a!Mi(w{kV)`!~A&pbHv82Md9MAdQ6=(V8YjXYB+5w6e8 zqg)Q)%j3ouc22#1J1b>W8R7%$|Ct2(vWH8XA~-)>n+HzFSwwUno|3xhLo1L_=scOcsZ z#fOb@!=NJDqSelPICrzi!Y~H4(1DsHi|n?Ju~;|YsR>`DeG>lU)RJLwrJ4^W1{W{4 zntHvZ$+jt0%YsDz^-6Y~TSH7sihy4g4Ja7W8kfB{z$EZq> z-6Lh{m>%qdLc%XQdG5`=Y{J*#!qy z$aeWGDdJi2<^gHhXl$;bNu+9AV>V)qW613{D4uyJ1A^z~f7oic-wX_|jn?e5pQf!% zY&p5A8n&Kz^>Qo)HEWo|pKE*uxH_ss?{dz|MKn*JJ?1OIeXr_Mb+h%JXDeohMEuy_ z==yt<{h#ml;ukQ#PK;X`FXR`%dSNj|{W>GoIpE^);eTss5zYpv5*zaP>|&BeK2TT_ z7M`4M`O+@p_Hjv6qNmK!zMNDsok4iz{PrbEHDl$LfqIFVnCNgw(X!hW%(_o&wv9iY zU(uvFDkb9He4IaBdFl6r^UgI_LMl16>tK(rZT{SsA)V%GWqmL;=x-6f@M@fObL)CP zDM|{=*U9yHwq|VNwl@w5qE-&=g?=g+%WpPQDQzn}3x_jim0kb7_9;z{mIZulGYD)g z>@+}d}EV?6E(?K6DOW8qp8!||cyHg!f7~k1l72kFl04q`y$c1o zkMVpA*Od4_XS#1wpTrlU3fmaP&c&)Tj&1@hFC)>VS;oN)EnC@o;B$L2y_U(+BzC`b!XlxOL$9}8rbBemV&+Bg`T%G#o+AA6N5vc>V-KyfAy$6D>S4=9 znxK1nm>53`V+HdGKdm^K%oIm4!j^@1S9N=Pt|Uv1<_{;ydwRfSj%ejIKP&)L{=fkC z#NgBWZ%3o)Rm?^wgvt0+V=6a&2>UU_q#&bk7!qFV>pkL(8f7v^%me44YKL}ZvFdGH z0Yz4T*#+PoJwTRiBaXq-)U_}MYndY#8;%t*4sPkMOi#P*CiL-0Gd30VNKKTs%~-XJ zO<_JQhu>G_a2O&pI`=VhgUKK|mbHl>;#{7aWMIa4q%hDt2Oh1lKZf@#p=h{s|1X3` zH4gaC%qwH8ZF4gUzDJOqluRgUH@{!=w$HgOTWp=Pfs^=(F0j; z26h734Q;R4_s$nJcSO-5hVAU<+m=Ox&dn?wH1GY7grc^o5v2@VCLjEqmRkBso8zKGtt$(HJR zT9{Jh&MQ2hW6n9Qz-;zd_6r^t!UCkN`99Qb#gXPvsqZ-3N%5eA!m@jXi4m#=F%)${ zSCa%rqNGU@bVLV?r~@KKJzk3@2G?Eb;Vnp0x;?=(YO6}!hr63mxlQPyOnHPY#%Pf- z6nKV>b1aZM&!su`r-|w%6QLJo1XG0M5A^gvVcPfyPYz*3$UD=_1Bh<%oSv*n*` z1xvkrNA_JTYhaTBq-esDSy0VWyg4WPQCa*%mkCB1HNh(8Uu~X8FpP4f19=e9ZjiJy@3Qv^Cdi#|aMR(hLJlcQ`LdNYZx zf4!sHkt(PT!6{_N2ng!Rw^wUrHPHA-l4K;R$fE?kJX7gbR^o%P+$<@pzvMMqk$%?r!5bo8Wl!T69N!SxY?EO%R z`LLdeqUZR7zKN%hrjD5CXmh;yVmiI|jEYM0(BNPTYFKx>KKREyZxC_;U45}HZun~2 z3f8zciqQ~d+j70fK-Pr2=1KbGuY6QDF(+-q4n;OQ=~0Ptn4X5B>@-~8$uLq{oUW*v zR~mUV(MF&%;MfJBcZ)+(1O$DD&O_#WU-Qh^(8rkL%+BrvjL)Dd3D9i^ptQ`8lJ$#U zWQyhzS}F)MVTuFM{U&qBzrmhYlpdc80ERdw6*chbPNs$SX##3f_{7EYAEwxpXlMrK z>L}e|L_0!0A2OqiNKrdCMGGg{9)hvb3O$S27}-|(6-7@X!D?eBt=KuBfx4C1p<0Md z5W~rR(neTf%XML7xN3Gs zAV9&Bs4!;8^*L<@qE8jJO#|@Gy6rI(&;9%<>63r%eGDsk?W_B>dY|mL4<*A7hLl-T z<-b})SO`L1QTHiazuu*fG_wBQ{lKWc^jL_T{al%Ep&z_qB#e+wP+tWn_tboV+Y=_+ zr%*7n-ApJB-&uYxqa0o!)+}}2oX$;sjFRdiA=fV%_!dgguytC`=(rZgj=v zF{tW0H1t}qZK2ovq|*jZi0(1Lh;J?R;`&9H#VMht(r1beS8ORH5pAh=e(eqMa?WsE zaIm7gRp~?mmtey+{J4DbLArRe)!KcS0W9-t4oiol?W5QFlRev7M^5yP8e%7NDvor9 z^3R=zGVfKQTBS0W6D<>zxY+^x0tV_0=VS`N9O6T@EIX62}*>?8}g^I=< z0;d}CZ$eTi>2yLz2)El}8NK%;&Kkt0(yOr{QfK6?8Z@eF_i?I6zn+GC_JyPO`(mmW zzk~757(c3v^}o%|Ye@=_(}NLaXeq^sx>X0T!NDmjxAgNG|IGfF#|Gg{+35JWf5aK_ zW=p@EoRy**H2ThErf5X$D{biva#vPphCCj(<=iuJyAsC~@YkN2{qo1Fn|yQV#Ex3yTCnyfIhA5g1&H_|vU)*us%qoTG z3SXiy_%TgZ4m>B7jqcr*vGx!>F{HVB; z$Y3M&TuQoa{b%PqR6L*l-^1ka(rO1{<8IEWUt!Dfe^nuMkz&XWsMZfJNUc6L`r&Nle;#n$tk3duM?OSBmyZ+e-cr7GZ z5iUS6(V;mFA8aafZBQQHvoVKI%R8M?D~E!#G{4iZC7D}-*kt0};Vzcs=H+!PEVbv|cLU^F(@EZWECrjc!Qlkq6qDPZ zyz@O-1FbGgNR|lKLgEy<3YRAAqG?Ev^^`Ijg?U@$`;*5c>(CSaPik|B5+rUwGg~*~$4hBmCo^xZo8{S9QC%bz9eyr#R5Tfn#l<5}wk`q2*u^m1?ldVfTyODyEB1Z#fl ze)7KbR7vVzL*2S1V>d9DvGy8h5k#FDXun?9{Dz5ks+7h5>6p#&-!-^?pFU!y{rGVI zbky`znBCn^`CBmt>UO+eio9o@EO{hZD%W^EAx?b=0o@0OUbGAxK^0ybE^h~*XKNH_ z(NSc+1J9jHOxn$E3dq9D*;tn!lyv+MT{x(EQ@)3;wEfL4L)j0-BF_yErE?xh<$C@v z0onyq9VrtXL$_WOBk$Lh<~eTvRi*z6N&nRB{@V=mpYG4?5oU;o2k5Q#YZic1K~PSF zHQ%(=m#m^aI*5f$DEUu9c%CWcttoUp*$9NoRouS`uZLQ}el#13X{nxw)Gb)F+^HWu zkz3xe-A~!DI15K_6OAyAaDb87af+taIu_9pS+fE@Xr0Gw)f@_OJf6%LbNcTgLJI1) zkSbKyu(Lme9%>fxo}>#X$k6?;k<`p;X2y37LZdjusr2KO({C!BW94L$@Py%bwIBS{ zk4WXz51FR7+PEMnVxQ?WFR;I>!I*~meE$8o=>@J(X_;(NwCbyLKP8lIdqf}zU%Hoo z$YX{U@=YKKgqEbA+suA z%eKS~1)^91Jzgu^uog7S6|ygGSDrz%iiC}s=dItMnP2z@6p$O;5#L}wo&a6EIud3W zrB)DjYostd@Rc}3N=%^4;n|pxORr~*E_IJD#LJ=Pp5Tj`cJQC?yzXDKzxeREoVZx^ ztR2x)RY(`i&5Ql}!^&$Ft|vMWehk|RuaYZD@8$ZZWr~lRkP(W#IgvauoE{$C1!{Yb zU~`Ocwao)3aGO0?w18zEuvpR1vEDuCizUpT=-cCGt*05*v;h$;wwn}AyFEJ04JIA& z*<=KXsp(12Rz(E;^X$2lwuZ99^HrX$&RO%71OM7_P_309Htv}IE~{~Ov2A09qe6); zR6g|B|Eq}M$||C7E(FE}(pMVzv!tR@2*|S*T(GEOHxvt~rvONx@_RevEN?BzNj5SU zEI>3Dkgh7@@Bv)~(_)~rG4_+W)*Kp6!b2is#>f0^rJQd)yVXUOODj@yIh0>E3toLE zFVFVyVWJLKsb z5wOEG@6d!Hwv#}6E$?X0qo}i~N#s2S`$YYcqdKt{R+2J=1<^qG@_1qGf+_*t%Jbc; zB|kd44Q`D?H|(|ER+*csBhg6>`M4#sQ^725C+O!`Cl3^w5gC;V=rACftadD3*#B<_lqACr72fvK!ZW-uT4nR;-?HPtQBF42&8_ofPQ_1iLmPHR65|3SO z=u&07(Jy<(@tcmP`Qc)aC5@b)9cOK3ytB(nqh_V}~fNsv?JT2VY3xAZ+D=F9h5YWMdm7=hKY@6Gfgs7h$LfY0GU*l1VAz&v!#)nnKbs zqe#JRv7IlZbFM6Y{P7QMg~au2dmgRZM!a0pVbos8V%71li+NGg_6b4I8L(aR=!Zng zr0d(A@b&5Z(_Vu*cu;t{Vo-2b3wo;lwDS6alf(y;3@$@wt3HFhq|d0GHd_r@bAY|` zwKX?1DfBBlun$$;(-n+;iE&2eW&FFDuvAa?$td>VBBXJjh0w{O*6}lKBLd&7YeX_ip;`D7&z%7{*GT{&&LaUxVJ+K42sHV@rN%rq#Tco; z;ceK2fAwlZUXU#p{6i0Ne2v_fP^=}$eaIUIBlj5-oxW3csNUlCvABMP)+&q@Om@Wt zI7@~;$Xc9wWdE1fZ*Xe-qfkgrbV5sB;E%N;k2RKDE^wCopaR#NOmxzzq^9$v!@OVp zrQ^XIjAv>_q?|>fSV$8#`P0kbS-1&QBTh#g%uxWT3U!UuI>7JR}#Qxd2 z`}<2)>kg89*SFT^)zg(v>zaY=GaLFDWicg4QyaMg30Nia;-sWXaZs31>i-NXUrc^r z7w}nfAcAK@-4KuoGmaZ4!>FM0Y`LRRkxR?x<}6JYJum9?|KpsIw||ZKcwELD&K;+| z`au@ZekqhJ?0On6PY(+5U?uec@d)vB5{vH;o#wIJTZy*()tk3tpRJR(!jc{DT=ie2 zm9hcygOj;Sk6}$mT*9Fc^?cF}-y6nrS<7ejDE1c&hpH^wuX4*zqh#5g(e7OH*hKmg zmm@OW65_Q68C{hj1ZH z{_;1{_$$#E9K#&f^~lQ@^^3!brfkcq?#Ok~&_pmol0O~3xT^lJ-tMH;^~me}3fl`+ z@i@aQ-L)X*8u7$Ic4ll@>sC@&v<&Yoq=yr87KnAcD>=@{D{sC zR1D4y1|}};-r5Yy6FYYyoJ}H{_`G}rTD`*uX@&bCRUy6?ZR1_rK0yN*rqv5iNr?~< zLt4u0Wc!k~t&peZzqU>!sbEt+ zW^vx-e}cx*hAV%i+B3xE+q5*BZ0hJ^o3#o%)4qGg!=iiHiVz4Kifz&1QCc$N2%JeLT|-iPK&G=zapX|+psWkwkR=LUdAUgJ#gWN${-)Xw z{*=b(rl$l8qEk03Wq%#+kIa>^W_`*R25APDH}zh|%r&UR1 z&*b0!iM$ebYu`=0RLP|KWDiZ)|F#GdPCYl&N$Uy8ZGf(FZLWb*j;}8lp>X$i289g#*W*{)SwMXp#BZj}cvR)|8+|{AOBhXbZgfd8HYgTCP?<@f)Y;B*(J(}}_ zA~Bplpzh2s3miMM+HhlHJraG7zZxKf1;)@?Hh0j~k|9OzR3WyX5uV5OWe=Jo@t>PX zS4~?wKDx+%)YmM4`r&Lz*6Uzth@Tln8yaJ;XU$vG`hb~ALOlKKe^jA=ru{!rz3mR@ zdCl(Ev2LGtdl5!M_hXB4SQ@2v^r>ZJ^s8r=+llrZqyLp*+=KaM~15fVxy%0I#YZ}76fqlb+3AVQI0Z?Z-%? zEZxJ!RR^9Kr!?cazxIAhy{a7yeLk>8aWL%R}_H{l|GXT>Vyve)qLN7hUJQVvP~2 zDWZVCH?m~SQrArgNaW+OrZ13K#Q$aLZIrb5Ve64$C;Rp_RexUs5pn$E=1`*)S3D^* zD@&2I^}r1!JChgacDs|$g4+IZ#j}Nj{`SZHwUoz4{(0r&8WzOze$uy4GueH)B@pL# zj_b!tyxhI_>K-V)`FNV6;}@BsVSH{SCkk2dz^T>u$< zCwb8xpT;eEY+`_qDiqF&le4r0a2M?lU^L=HKt+F3MEh&nWRURBKxd$&TT>2iE~rKH z4?7_DM68r5?3X}Btcmy{<_J%fgn&St5?|juHf=)s7eC40 zp^XUI-p1>4aO(h{(BtCRX?|ekF(LM_Mh=~wDB8`u63f9vTpBN*LZZ2H@kifgCO|Gl z_sFy5PksHLdT^)pxo;+NP&x!0S{^x!A>_6h6V=23MHv~>@2}-?a0%SDbP7_kh9eZj zNkMME5Hi32qB4c0w9%rXMxc<2BLhG{jd$JO-Tl;E(0%DL`(gU@GFf5cg6dVC-fOe% z&9S1H{SvaHD z=ehTQ_G)3GV=b1d^=SLs2GPtw zo#m_r^4UlKA>`dQFHGnytZ-|!G=@YdD~5=Vh+D>J=iYj0Zk%z&#sgd{(HPtDqA zeDE2}IwJ7<7C&VJBtDVH&wQYnn-+{qx$jNe7eEw#xr#59H%$7@{2RUKXUiY$6MjZ? zHwRg+(}bSgwigQN(_}a3i@q~-I18L-4mM3t{@mttO$6pVlf(n*hIHINhe3!=^{H;JO155tHaVFQ$9Qoa{sAql65Dmi;KumA&(A2}wwl zC@I6p3m__u&$P%+(~Q%pXd_&*b+bW_BZ=`53VF3FJ(a|@?SEtQ1Z{r=*btay&_ey= zV6UQL6-(#fFymi^(>7=phL^SbF8}Y^G=)a4^87rz9Cx~&+c}$iYnP}u24im&Y)o-! zccUkxue;~o;AyGe-uBX3LS3KZDt5+Uys^Nb;i(s)Wa_e92l*1z0X_E(&t07qIsYAv zZp|A6YnvpK3#+gk+rhnv15(ma{u&&uSg$1Z_xRuY-Mt%x--V(xTDx1Ft9KWbGo%Za zj!rBx=m?)XHcJ5!x-%PKNuc7Ihzt3<@TiF~O<=_J|XD?AZ{C3scP3bwVz zmI9c~VZx>Q6THIpd_VZd_b*9;6YkVHB7~!GPb|hW;s7IJ-QG!0KDm~3dpAkV23h9p zKG(8MWx}@2n9aXUo63t4me(N`DgF4resD&4&HJlZz9?6arP6MRIT9Ntwx=<|HrlrA zegxw^QPzcpeV~3&qH1bHgf)PAyz$4^F$0{}#*b+SpapJOjq!9LDQz)L7wzBI3SlH{ z;Vad{P5tL=5jpejgB{M-ZPh_*=#EQL7!_=7^0JQb8t2_E4ojaidVJFo@)C$IG?Z+&j1tL*Ewt`^hRa zgwx$*vgd^1v%SJfKMuqHB4qAn6{=us;-0Cg zsGeFagVVFt)En(K`r)A=Yv60ir0aQT)Dcy%$?@Bc6m-OerkQ|5q!vmxO%UwPelTlJ zbPDq#@UWsOZqH|K=k~S!($&bjedII)TDqC1jEQmNb z%EKg0SSD1@kH`67QrJ_BbW6Bgq%mT`2GE|T&&J1w{#N8~!FrbLcgt>^^WMBy?u^l3 zbuYVnC=kK#%)v1(kY;SCpX>KJ2710-x~A02^=&ewK7B>)e#8U`h=B9mr38+W$Ej=o zHfH4bgD4<+SW1rcI^epFhmN&j$4)re=iLn;x-!r#2J0^0%@RiGW55pRZ+GZ68@M}r&E4S*^O61xdAKfpSrio3EgL?!QD?NCdtBYc2NcB3bn>Dih{X=C- zEZeQPhezth488uf=4NW`+GnNdfM@8a+0-(%0X;aESh5@Jlw zl`$99S0Y(s+|6-{*+A;zP`B5#FMkuph0>jq(moo=!k7*VSoAy)KGM#Np~pT8Fo=ef zwjBg+3&3z>wV|ly(=bOJW^NU#KNZ&R2!pOBwkESrM*5d(vtgPwYiQK*zpgxg)~zaO z%1BEOV-02HrnHuOLtKH|vhn*K$DZl8noIJ4B~qMXb3&>1DraMKan=qt=|WvE31JQXX+F zAGFzjG_Q=rCX4v8f`ni3gKKm)uaE>_>KRBFk?}ljbE^!SqIwYK?O+XVnMfYC& zk9m?h53a1VzTKm;KiavmcAHEjKGommMYH>{+S=DrkG#~S07u(X=zFIf*Xy!(ckO+3 ze@Yg#x8dw*<=P(d?ZDWWVxmMi+#<@450EdaDY;D>jU(3QiM@ihuo(H~dI-K;)?PF> zoaQ>_(11Lg!+w)p{qnA@N@`x3eSQ(+v-+j65IbVGyB>PV+x-phP7^6~FN3bdKySN^ zMUGjgTkHd=dT%w|cLCfG_@&gb+8`Y}@HlOtE8Wk0tF{_LoW~M#iT7J&suRy*l7MF@ zr0qtwS;<#*?Un!$0*h`&Nc;gT>A;H~Uf@?Pp!QCxb_-Nc60zn&hZQR{y zY?<2Ks@d9_n)!SFo;s)A=Xvkzy4Cr1A^VXb(?@DR^b}72?ybpiHP%l>Z{61Gl!}N^ z5DQ;u*ZF-JHJ5KNndi;cJc6BZwkv?7GCyeY94&)tPt{qgmQt51QqH2#f3iO;muRcA#*a)uaE>=x? z&TiC00;Q24iRsRvP!5($y=&_l9^R9OorG zpE^C?-)X9~Z9Q^7LGk1p#nkrS{4G|h)SX)`v$QYEYR~7K=D@Bd>F4V>kQy8maL3Cr zXHGqTwmNga1G=AXibr@}L+9$cjC=8bPYk?RD(^oz`Z2hEcv|iqIwz$CaXnVQR#~jZ zV(*V9Qog=$ztMJEdnDr}w2d0?2>$Faszho;va#6RPNubaPBdb^~tmo|NG| zw2!h9{U)0Kg2l(VUj!w5u*j=*!-~3IchUj`{Es|euVXlpx#(WT&OieGmuTW&#W+FZ z{|DhiXFUw$46KhyfQSyUTCy6KbrVhW9s|U1WCQdCeEbd>ne!!G25dw^jCj8Ma1OH{ za!eRtyuG&6_kkuP6Dj$&Lo772$}Hqx`$vQ9#in4$hDyKUkr^-s9vvNlotqXOB!WSt zbOwqG1oZ@8krAl8xdj=Jvoh&FpgYXW;-E&lx^#9Y!Bv1|evJVDJLC=YFF&vT#^7Rr z#p}Sjf?7<@ipWp}Z?LdwQX$LX+>CucR^2rQ=0?}E7=fVO@Xie&52KO)XQ6u??wZ;; z1mGm-fqa8m>CW3HmM|z6n!O;6k>OLB@YZHExxmazVY2!&MP3dw1W1xV$Eop=1V|_l z>6g*+9|17yCR$)qF!1yp;-CZ)03*z`u&?la%Y^G))tztP2SWC(e=yDOExJu~T8MnL zoXKU#(t&n~HTINQD^~WQev@C?1Q3A9*7(TsOK((GIG9J#ASeUnvaMi;q5-b?j!ZU- zO=PDL5nWX(W~Vu0+qa%*+~V=%*qriPWB9gg9<#X=brw@5J>JHRJq|*>Ed!6lRMB+cd=>(}xtW^pDvn6?LiMD`;Sq4^J zJ_ouHQ&J`-u%!jiNp`6U#~+YMvg3Jo-AlaQLPt4^k0M@?*n=IPXbzNoDa&dEq_Zx3 zQ-AA<0O(Dk^5gr=*^uHZgF^=`8#^-I^ioAz19H<76F^~M;Y35f!;ynUZohI z!9b)A|1z3OSxzt~BlK)+v;-4;0V!;=-1 z#$~ALYu;&lK&^m-xCl^jkQz>Crw3HO)jG7?%PD^8mrB2=@|P1s{z1k)6!;ttopYz> zbOhYzSNT>crE$sRHJ(5{*y#7++x%{WP}il5==Fj%KB?q=FtX;7ErwWjI9+3{XkG(j z44X3_&pT(M$1g@ko)pvtr~9dmUl2_fP~8@RzYe`iL~dy@Jjw5I8jwS*1rY1fGdgIv~CM0V2lFQ`G*3=U}U+*9jB{TIO!G1aTL_)`>z`^OfQ6c;Jb*Mtx8tu}q&@Mc-3h~30x^8>uZokhsMaOaD0{C*{o=WAhjh}r zLqx0^X3KQ`$ZbFaR5~o`Q1DFPsUt%#Cy$Bps6pwfm#IZi$4B-(VLH=+oXB#m7Ky9_ zd}*b4&*buPt<~<^42N>B3%z}820bi9AO@o-Hn7k_pX<#Vfcn&25*vR8gATTzQ!znfJDGbpCiOFOJ+Pb(LMkjReggvhMm>?Zn=y>w^df(=T* zjx_pZa~ZkXaaXqOiRR}3olKka7r(vG$EJlYJTqK?R}X!7SojndPa>ph)NEqB^2U&6 z_UDi)*Yao~3qa514$@q= z<1mGta9ciz`d!LIlM-ohg~Ob$w-4ODeA`L60Gwlf7Uazn(0!;tY=y~@B+R0&>Xy>x z$mimTUB1lBt@XHW-F-U^O*6#4+~gnjKS!dC@U>wdmD3%+uZzyrRSc$7KyCLqzywnQ zHWtWu;Z*+DlY{roivEH^p2t%baDpCW>%3_^@pr-<(%&5!J@0sEbW)#_?JoW+^Zw9)=T;IMcv?T| zchV_O6DyQ;_4(QK`R7Ua6%wzeAYr!&#?=1y4m)7(k^bNswLl;%if=Nlr{MGH>3DD> zJ?8@2Q4C}Z#H@fe_Lb>_Qc2Bg72wGz?3hPPAOZEQWqh6&Yga&^qr3?XKSP{_iEO+S z&jh$h120Roye`b<{hr>;w?(wf%F1n|M5GpHc4#DFT#iD!sRcUFI6#V9eZ?uqdI;`l zV>Uj|a5cYq9G>2rB5Kd|-(b-G??8{{5Uq2s@IV@NJ;4cEJqT_t45rx(GxUF&xbx?D zj)K7jn**z8s*U`2S0$=|9}mxt6vF8wg*+ER)!*8aD|1{b6ER(p3)9t;@I%QDYg|zYKg+OK1nVl^>M`{0cX{82^2r)!ZLWpR1m)Ot zFIsn_ahnpUZ4jYkbwMttqG|R5%CXO1ThWZUjJ+Oy8KV<62x@A#uuK@LNe9F!25F zTxy3Ln;L(v3dcIGzbh6d79R{+;6FdC=gkwN145})8!Vqx%gWExA#VxuJkAJ@Wn#p; z34t+LCK?9^>CYc1(L+7~S|~pjgFAA=iq1EqxQk8IG$_Q^a^%vj+<^BGW`!R_wQO78 zmAsOlDyp>2V~Q0fV(nGJeKkUbcbOyjc29B(@s^j=2sh7S`eUQ@1|< zfr+T?2=5nTGt9KOuTK4HQ^3r~+y8OCb*^+u+Eib*3;L@r`B!m z_m1=*IClCRQZ_RObqby7_i7%dav;g!#`w>XF-o+DPk@fhk6&UrjcQbPa#KL1`;5_T#BukNWjvE&r`^8y^Gjy# z9j{C8s3z0g#pdww^84{18xeP9&_93yD%QE(-fV90I@`dafP3}i@2>p*!63Zs-uA2( z$y7;E#`pbq^%YkqKIRAi*_#pde2XtMmz|&g^0X?4AIxvQNpZ;6Qv?qm6vxaM&nhE5 zOuhPtP8bHQh_MU%kYLzi_x{FmwP#(f!cP(!m2+mnnZ#VMnZ^T^Gt|K^$YDi5RH=pGmXWR0_ z*XTLBi&hy?Ol4;jexmgK)@Y~G~u>bP$xKMrgaoK-f)d=C17D6K*e zG9G<^s$^%gteV3pX5+ItvcXC&V`lCK=;ALfV3a->93nuBs4odTm9}ZV)3)VmEKRvc zj-{e8>r~HcZEHQ((J8f3`~Di>c5V&Nl7MTNQ=egzd%Am+_7;X$OgP}(O_;{L_iI_s z{kb)wjfI)_@p0JQ-hcLI27u+h*dnN|#cum$=p?oZp4{|EtTy$47rwW8w6dHQ4|=pz z0^Z$IZhBp2q?z$(`=<-AoD(9Rd0gMQ7puLjvrb7o-n^dm+q~YwKpVLs-Dqbb0m0Z_ zTYr6@E>zqbQEaC=O+2?oE}bzOo((B@pR%8RLkUy@#~|n!BX%!lET2*L$@5* zn64W}_yNFyFod{b=D`=Zzea1U*4|!aj*Bh~c4qJ;qGJq{AukAzN&16T6w3l&&t}J0 z$Pb_Q%FQq8+C5t6J}^d_%?gu%V;-!^!w1LsZ!>@OAAPseg{axzIPsOk}C zD_a;72HEfa0TzbL533BT^cxZ4y&^9Y0UNwN<`!3I?(eG2SvW!Ej_opwE;J63I*#@C z`agIQcYI?r#F=CjNxqSge8C}DP6=5=ywIx^G8_1(qTR5IRB)f^TEd%^c zneCLN7|&;y)pKZjw`134x#(A0`mr#%+oxz?MA*_C%fhl_w6Up)wHv$UGHaZTX;5=a zLHvmTZJxbqp{OutLWBQLgfc2ZgZs1<1wH-=2LKw3ZyoZa>t>BKq0K21NDb5=X6S92 zr)6jr2g?Cv6$k-u)vm)FjDmHevoq83Gwikdvk1{7?=|NE_>tnQ>%$S3B7=$_8!j>M z8TK+BzD>;-wvzPa^%lmz4vx`976dl#BTvk%PGZo9UrwBf!A(%QzlGM`l0-K~$9~<* ztl0f-_fcFBMt3@Mjy(xLe}A2h^B41Gxlnm|!Cp^8tN$BiNSFXH-FH85Dz*8y;|DDZ zu7Uwy^tx^7_W6P$dYjyeps}n~J1mAG;U689G&%ZV`SsO+gQUHb?H_u}ZiP-Wq(Vs^ zi<@hD=2=M*dWdeNT+65@@#;+p#mxW7f5ker!teVaG(kH<3&QzGHjcmOd~aLI(KF70 zs>2ctalFRn!8t~Fsq02O`C$I_lHrilA!}7JtIudgn&5tA82E?}@=>|5TT4j-c!RE~ zPF#K%=8~kuN!)7~$dtIqeU~1+zTzyku(Kr6|M#jAj`8uJIl7 z6E3{esny)0_>WA#_%lop60HVEbZW>7-_?5zdI(6DXEe1AI(lASvt1h#0qM5Ydmsx* z)bLa$iI0JrY`}lM^|QjpU9+RagW=%E{fko(4D}UM?RE@|38=ydAbJ#kz1i5Z(coG+ zKmS%k2)%oS&NWi_KTgj=Lt}_Jm!fZ*IYG*GQwPoh$?puapj$=%59+zk%^Z zJI(Z~amvIC=z+P3e|+gkFf@suboG#IV)ig*EgxGt{#K$A=(PvvCd6&O>@Wi& z!Tu=L+@sPTw_6109nLV}p)2zU>x+=Q*hgO8r1tp%F{M$<@4c1y#Z85{iQ*xHx2gd2 znb%3@9b5P3@F!!kae+C}M+=_#}0pF|L+u{)k%=E3~ zntYB|2mwcnEjDh5-^6uPQO>?x$}-Im2Z?l#U}i*(fHP3YlmI$AD~k{0V`<0SJ+$S7 z=Fp{yy!sQe2pZF6hY>`9xm#UB0$?ZR#>Xo`s;vIXXhx-Hq+oJD-|AOVCHy{QKLLCQ z;O`r#0})Y^%QV?`MJI3X+&a8Un;M3G^VwdONY4Zq9bZCjr5}}X1PXDz@!|`V@>|JS zDie0xjg85C69a>_h9Wc&MJH!*6bW>c0HfeJ-Sy|-OJscc*CM<_qjd7AtmH|HRj#@* z+qUD8wPnz6l5ER(WQWWXD`$j(6Ja;iWtoD-2f@>ZSNV5|&;4vJ>TUqrLau8B-duj( zF)9&%7EUQ$LO=x`#iH2Ia9|?ut+N@$SmRavQ|m~&MXKpzSy3BBZUt@PZ}F@?hPugx z(wVdJG%n=xd1Wfg87K|MhII6fN)_wS!pn>-<$#Y)_u7m_V~gvT0LA?bv# z9>LbjGN+)Y3qE9HBZi>X=H7d -Vi=ixB`cm8rBfE7vQ%v$b1*(+S#1QrW^6Lsq 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%0DmZ?OyM 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


    U3(L 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

    ACMqaGN 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

    s`?ta-KaX9h0_r~A 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

    06p<0CWU?A%{B*v+wH|$Mzt46VG>ejLiz+l9^U$ zRUh=X)!-52e;u|5aoE%uOJ`mk)Rqad*^X)f^ql_bT-P3sRAzkVML*rkc)xo<$JEO{ zMOqe6pfd(H=-{WrrwK@;m9f8rwr2+^x1G{JozHTBUWR>kxH70v=VSMK2EP^HLna!~ znaZisX*l2**}(np#kd=1jGCrn5DCxm}j+w zCT`q;H`;&a$_lp?9Mi-Flge3TO<3yC=A5Y~Eudc{7eFc(v!kx#)A=we#vq$CF~>Sj z#!FsEKfKSm(%Ds513vm#l}(&8f;k=Hol8g&n;GoPO$=!dpU&=U@u%#Ap0 zm8s}F^5EV+N!zR%ND!eqj~uXMax*lSjIo9TuC0)-><6D?`sjDYGy9`nnvwegud<_F zHQ4}*#pfDq;oRqBJe=b?arPm{7O1Q*#_9O^ANW-Sem+llJ5M@3hCCk6^x3%uXNfO7 zgMM+H@CjLt&(4MOD2%P(Wn0ll`e57AhDcQ4pgjR>=t{JsgST1y8qt?WP?f*aLY^;W zC;OUl)O%dJHCTwl;%2N<$IJMo6CKDjCS9^myEp&~2a`9bi!qSRzQsBN2Xr2Fyy|m= zcRNm&-X}~;CDt@}Ckz~u&YsGaMR3hN0SpHb>(XRLu25R6)gK5fe!rW=Ll|&e&k>>$05Cn`Qp5A2&ZM| zh_S?rd2+6tTd%ckD-P=L*{@?Sa_z>Z71q|%&6~HNHR#=eOE~tTck&(s01XHf@1-R= zXFKNxLfVG9pMIRRt*BbV5Ao1v*~geO=EmP*UZFJw=`ygj%6U6u-Py^(e+%qQc5rMT z9MmD2N@3g=^n?Bj1Ctb14jdEv4B9)6^{nns8jrk-6+yd%&(#Uo^&XD&&{>1o=H}+0 zx9Woi13m_YNQb;u*srf`#oQTux7fKDRStt!u~$5Ve(bZ3U4!mlqz4`*nUT+h(=v3x z3XtO2LExUwfSw zqr3q{%^26@TfP7V%ylDEC+a&LDAAC12x}%=Pew! z7kF-C@L1>DK$u2?Epqi%*Fwf8`!A2REf2qo|I!DKOv&P7?k{W5XYaHASv7Q#HN;hp z#Wq^`T|PuJ;Iw}XE@VC#pYU*9ip#E-T0o$<>HRwM_k({rYRmIak9ItEK;Rn5d>WAt zdPpu~CEt(_fSZ9zt~sArBKY)xz1-1}`yhU#56+GKcKC%za!P+?p`2$RF(-5-aNa}# zOhoV-R(srMlA$B)XC(rwU4R}kkIrR#2Z1iMWl&r*)tq=}$P@0#wYeRZk>z-Z^RFHt=$w7y zRbl)lU2S&!^t%yTTobg=d9>1B01CROzF?@kKmFc|zmqz^`Bpc$RAw@M!oYJ?%O^O^ zQ!Wnt$F|2FzMo1ylVii_Hfwi#Z-)R6s@bt`Hozhh-Dqc|9i89}x^d18tkpo?%sGQz z4J3A~!H3Z6wou`xo#5&g`q_+4w}cK_^wH8$VSIb&2Bg2j(&PsF%3@x?ca!C`YC|ou z#_hj)59oh8wqt`5>_cn2v?JRCS_xDv&{rS=Z4i$^5oXHDc*>K5L(oaqv4QB$1D%MZ zv?m0@iDP@rVYy7Q9_WX2ZctrW-lrVJf7l~|yVye2uLRB!2m^9ig)o9H9k&lP83oFD z)gR>(lP&U@>zlDjuN&;dSj3+;+t7|nFAZD(yn)YQ1!q1h;G*)K0BfW#&5XT?>)Oye z8JK^nnq$I&UGzb%z*|}z2?LJ#jldsmAKr7sJtc7T$OKIL1Te2tF`R@& z%C;3NH`1qreVz&a$>R-DElT6TarI4u(C8jy|DIl}M54RsZijb4uaRq+L|#~t;k%s# zXS7vqK7n-nBoLL6r6=N$dkA@;vUiq!0dgQP&4{P|p&#-d^*1GCN`tb8r~sU0EZgKd z`YbJXJ7lFOX`lEcjqv;@J%YAGfAgIWzB|5Z|7dZXuoXMSG@UwdmcIb7VUd4A3%Z71A4A@b?^h)v{}(!KJaktUiI+serdb9L|^tv zI6t&8Dh~ z&Zh$#K^D<2X|Rm}fibVHRSxCF>6w{;pVi6rLlAEaE)rLSllwCHTa&?x1j|Km5Hf=M zqa0Xfkd}N;ovMB-RO$kCOC*XG&y=f_v!tim7L~EwpSXt-ueNu$QtOdHPJ59|wXbhD zO-@ci`>D)FpEjs0=l)szzIN?8Frja(@grzZ@UGaSWErum8$1TCR=6`6+7J~p4d!#- zVE?R;Sb?@E6Sx#y-}0Iq09ciO8M886k@Xw;Tb`|7hZW)OPTgf~$h%0;);*ZUMkjb) z1N(Jsm{g8Eq`F%(dh63?`a)iJJ$AJBM}meHXkKTfD`Yh*Nc-EsV1Mc*V9+&dwRd%s zv$M0YFO5AM_^z#1InH?lYeH@S%ODHxcS+Vo3E45IDRq_oYHyK>&8V&gzTvA51;<s=ZJkkPy8PHSgsRaY%dbvKz{%m)xek2_^F938^gyU;gY<9>q8F$e%gNz zA1`h7nIfd?L%M3>TH&h9EiHG=DWmvY69TyA43MwsIjsJz4#mBR6$PF5EvnL*M8gWx zyZAaO-}<~}6bbI-OWd!W$D~LG1j+`*sP=a7hIurI_7J(swdNimDsv-CTb0qE*#_2= zHv1F!*A9DsD}A=ceiZw}!E%h%N~hYOx~-PTo=ZNzwQHqyWFHc#NCRTsizv=_z<@TH z^9}ZsCN{E~dfp>tev{$l+VpzoFlI9DwH3d6zjVdJvDQA@e(fdR`^xvnr62j@ebNG9 z?>)EfkW2>I z@#aE?`;8uOeQ~pvenw9p z2l|`13N?OK@Wxqp{h=<1`)wtwi%_1RY*6uU6*}}L1adW|p-~j>DDYeRDyer21?X5Y z?Y5js%{?f(xMu6Hl0KZ-N!{ZFnH}^{Rj!z(XG`hAWwH#CeQIO>D0OhnsdF7<0#9jr zu9SZI*3H!2cQ%ZR4Q;4untIdPR!jQHPj|^^x}Hvrm(th1c8+XjxD?PiR6i(wSE zCLFxY)9CDydCs~}ZVh8ZC;@}YiP@}F^ORF}BSC3cTy#h=tLA}572sx;Z&Xj=Xmfxu z>43_9``mXzMmUXk&P9t#Ti%N(fl-a}50enjLoLHU4K5hYxHdJZ=yu*wu$nzw%~~A3 z`SGK)|AQ=f(yVVPv&DDyBQ{ETp%8d=GuN_mA%#N*~q}VzlTv>6A;0WW((8sbVwD$63W*PZf~a#r!WTnV0JCybdfp|<2%7`?-MrE7|> zyk=<9mg`3y0>AMP5Z7ZF#fM)$+^i6GeP$!;$FEe0>!H#c67UNSfA_^2`!&z<=8s(B zZ4v^`sxbe*|Kv~7zy7m73uD*c{|EnJ(2Un!eIqjA$)nbA!ZG7*c3P^WS%UEHP2VB7 z>|*-T?|d;0jP#|Ym4z_m9N@fEC}5a^#z4w3EMf5Gd1dIFhYkmRhlJ+CzW9^x9x{bT z4k@m})ua8_IITf&Zf+*M`_4P`?5zbJY zJHo-CjM4ne#JO~87zZ5y5Si|A=Fu>zlceo==nzsnY)4~JW}?t*o^goLRKvkvcCr)oGN|(AY*6#1h7k0!&r@rU7IF$6O6gK4)-nAdGfq zTHW5=P76!-sn$eg;o-q>j(hk0_Xx6RXP)OHEBoB+e9TXeS@ChQ7$bA(xry^>bo5kI zrs}}yNe5cpYCWn@sSWSp`y-R+T(|}_T!>#9iOg=ULq~IaF-OjG&bU7qhUkC zi2c{d^vet(4%GSc6j!D$pbMn}@Z{gt$~d61Uw&7~iF{oCp3gF?Fa;^#=XLFF5g zsJP>Jz*FgjnRIo`2=W#Efp7Cn_dLgzkLNiR==3p$;%$QKE9_JHM|*K{U^MXA_or@> zjd+qO5>$1-S)x|8R+u=psKkN;*4FY0eVQg1a6Y~Jt?%F*yOFk_+XbAb)@P=1Y=BQd zT#MmQ0cFSe#*PMjdDMx9amK#SJsV4NY5LCXaM-XK-{$Zs4D~uhQ*j5wJMO|bNMX#! z>8r815oeA;f(|Qbzlq>H`5Nu%aOhsm+#xy}n%({gC&4zHEKaC`+2zik|Br#&1CJKD&uj8owbPG-$ih={@HOaM){I>7qEB0>K5kq?-C z9Sa)iC49KNf1Kv;Od~^3;Sc`P!9L@|_dZDdIPh5kr-Eb823h2H;3NBFfo^7F^wtl5 zl6I+h*nm<0nJ2HLci(+8UH$Z@()i^|>7~!SNTQZys<&_9P(u|V=4_qnC#T62Ja*0kaoe~iPf zTuSBL*IB$F@T67RBPfS+25_vPW6aKCju&1H5AAt|dme6r8;k_Q7*OArd>ip;) z!peRo8Y`0_%wQ%fu5bZ&`fdyPU7eVFGo870><$?7tYU>Wc$NW_?&&JC8r2vXkAV%jLKqKVmVMclj_YvIcvi?8^u_+$cm(N$17X&C#&}{r z=q*ES3;T8K+ zu5ARa!f6u+z6ea@Is+ji_y)k4?4X6cZg$pGc0fKtAK(xOU*MTK4_e8Lz&-ex4r}iH zguHypG5PQecVs!>+DcLf16Xw)JODRz#?5IAV#rP4OOcn~ zz2AGH(xvMWoV5y(x>Cm&RKa(yYbtX;vZWJal_C4*z2dA+$Xp!wrBh}+hwmP-E_rv( zJUkuec!18_C2+yM8ffG^Id298>U3&_=Qwy~=yn`4|HOdM(L`%f0M2lqjD^Di_Mwj+eH# zz_nE>N{BByn0n7Ja*sF>|9BU!j?GR4{Q_pf?F3znPNCw&3INMMG{4pMR#!JTuMABP zBF|jMX>$_?ZmUfg+);EMXseSdAbrT{xsqG1zT$Yj*VnC^w_QRYpaYe2jDqQ zU*fibxyr!mFg%=>aA0Q4es+GPU)fA!R0`Vfbl19gVt46BCuw%Q1esjQ&_<8?hU zv4LkU0%^N6&h`ze+L@iDdOHnpD@*9d)O zu+D80^L(Q1khv?D4bp_xSfv*^AmkqSWQ?Et^Zq{LiMVn^^)#{CDrx{Ax~`+URp`_& z3q@rBX@U;^NA%4kc~*PR6_0qYe%6WIN=Szo0S&@(x=id+fS*bS3x`%!Vop6`Uf`_+ z0~#ni$KL+XJ}5_M(*!r%XR|0s>P8>viTAh%Wj4Td&52Y4UE5AwG`UItcA=#!CGeEX zlnJzt_A{hI_Pos`!4V&9Dbrba0Ap!qo%OLc?%$tFQ|Mt9*6zdK4}ce|1RJ?yQYX+# zQdk2Z#E(7#>`b6%ptS*gnGXj5btT$GM6i4G={s!4w zm(fcoAG(g)*?V_j*Q{0Nah;hcV2=Py*MG=xz}LjRu9LFs02?V&9z>y<@V2{D66M_T}O30Qxmxv(x4&Siv{FAQlV+S~3 ztR|e2Mkqg*l_Al+usE1i`Yg%PP_HS3XEAB~RDmbRn>oi%Z@v9ax^VG4L7u>f0Ok3G z6%q=*kA8-r59VQP;xu!*1C1r1-YgMf46yW_A;n9&H!v{B{F|tl1S7zNZU#LJUc#7N zzjgs|a-DJrn9jKO_R%$w079B*i%lf@wNYt-*SjJzb>&8%$8V3yadGn3{ITW7J%U&G z5WB(i{Vr{ccRyEO58AY^G|t<{4$eAQ58rK5B#3c((mOH@&w+cMt6uL%e)d^(BW}$P zurD^j(?j6$!s_AUoMPZ?yY@K_o+*v1{U+|)o#;O&oil@;=}UvQT>@_B1(-e89v2R?Jr3jG%0Ia@&z|Z62F+Pg%X0?@FXLYe9ItvhLi z3c>EP447W0npq3-aPt9vICInK<(H?@GbAS+A0JIGz4Rh<4t*#(&&@Nt>D=Tb!DS>{ zUS7oB*dNcAQ!gzp0q7ItoE~JiAu2qZR1}>mNh^+V;!z%Q4={kfb7gG>nUH{Sc%byQ z1pnwVfdRD3d01z>dz>q{Uxp4Vm$?U2&XDg*QxB+6_p_h9mj2>+14i0$^$}WR9g8^Q=(Vi~Xz)}Yvd)X2dNE`JA1>dslJtFo4Q)qx z#kJhlPT(BD*n?LFu@`?SXuH8u;>gI*2y-@tosr7ctlLqNkY2lXEuA@iI$-R6O?qM5 z1_r+I=9?i)wG#|wWx-+ks{TPdj%%Q024mg5GX*W!Pha`USJO{_@@mK&R*HZ6>1WcD z@D1T%#X@zi(nb4_ zSSy<;v$!Tq#uLeGcovAn?^M@ChUn_(!$v!j?%ci2e7~CBBrxzl_`6@t3tLJMYZ88g zycqI5__RR4W-m!z-5a~-x_b2*NniVe2Ak|4|I0E?jds~*@yIHQ>M(q^aHu7A5gyJB zT_s3yG^#{Kf+E0R0*PCCD*)@SbGo$OAC?;HwuVFCfOSUZwHc!$W2Q9yI2h z7~K2e)UAMP8+Pc?v9XXn3?!9DuWhj&*t57+l)?0Sat~&*fHs2s0DD>jU#%Y5iG6#R zxjI8ta{IndW!!BNQK--A>B$v3l@EFeM0RGBWlT0?0IV<%`U(N`-9T7<6s}yk;?#ZQ zP-d>d&iVTI;e6Y+*Qv*FkK|!{RwkU9nxf+4={P5x#Y=IbcGz~!7r=LEPYGT>ZTcfjR{05U4|-4uLuZ>Ja#?gTVU6 ze){frZl-U1>qdI@)!C4}f9rryA8;K4bqG8*1gcu*$G*OP;a_(M80CbTAv^YA@W81f zv`*+zRPLj@kDxdetXaXVvKeJR-&OMELp7Bz4-}33RUwpB-x#3cj!@yC7^z@9M0rSY zgc3%I*8Zk6bfzhtyNIc#e=Ie%H>LHRBOE9W)9smUs{9NQD28#jTukrYzz~6w=>Vn4 z;oecAkQ^Q&9Vqfn(v3NkXdlj`tJlXd0-;3Yw{lZwT3Vyz?T31?W|Ba}e{TY(qK zUu#{M4cWQ(u+p6{aSpYHR2aL4TSkpiN~3Ta$}lpL;lP?IWSH7*#Cdr=-TPn_MO0Hd zGdUa%O{XWxZi=#HvGWKe@JiYvNCp!*L6f}%J+xrR#`ttVX5L~KPN^Dh4a39Xh3DyP z`}+Gk>4Tf}xs5Epz}w#S_O_+ZJU5(9k5tk|5hW~lw2-Z=jB@S-3(g5fm`bG$+) zVqR!zutF0CNI_cRM8DBXRWOu><;yh~ae*OiBuafpx9W@2729+@I z$HldVytnq*A2cxf?pm&%|H$(>r@`-$Lj|^uZkyX1>CLy_j^@n7`hy>QKb<{yj_(+l zQ8eqIq;dVY$soTYGO+Go94n=pDDihNB5PFBp``=GvlOyGpn#bdrEfaK=#chDfAqhm z7hiY@o;6Ca+~^~{;G^B5uXHC4yInmM-~EjF<3ax&UpQt$e>Lv+^mL_bPd-6*U!0vV zyxAWe#A?GexIoxsut>jsRU-4dh6@$$_X$FH_uY5HXwi;wZ}RLp#+f-x?fY$32ZmzYU%>h2U-1_`3Zn5UChBpIMnj;EG| z+l-g?RpZ4r{nCJ8c1qie4BR@B(U%gmy$QpM!JIm(7&Q3K>u;se@v(6F>cv1cw>Xz( z2q4g4a`pN(vZ}9#kwIffFB$O7inxRE#n;BxMtb?jKZu}0O}|zpI-K7NqpD5>8otcn z+&a*l25~^Tdi6R^d4psv?+939GL1R0np73g0jpp1M`MM~ZQ}JI2K;UMF^%!$KGhx_ zlVk1gAHX9{C#~!_24@N5NX>{+d#~Yo?fn-$uYRr$fjR^p9|Eo|*VC_BQ?+Xzzg4c3 zu-A^-XNfyU?W^w^oOK-18m!|<8KZPX11UfDKwF3VspbbQ+UZ;;`AAcmJT;LEC=1}#sQ-PM}ZdPj1HXh zmS-0Tt}|Gisw1Z~CbJ)azx&eBtH{2m2)`;bo-Q_`1@1KiwY;VgzS9LyX>1^1es3Me zm-+MrJf(?iDmt5Bl-BVlJQ-pym<{;bI|peM-m;E^zQN?24W|^VQaRUFOgO-ic?d^e zWeW}b@}jSQ{ZG?NFTRBH=h@WDec%4`Z>4wMcsrfv`{j$5((Mm!g(LF#*f1uPj}vXKiz!e9rh{6I#V<0eH>Lbch||Bd>Y3^c7?#| z#%pg;{h*7AxT7RD7-tVfa0^+1b>e8kNo0$}EeAMM8dO^3W$-|IhmQRjV?_*&_gNlr z=i}UpHDq7rd3On9ef$0Q2sX^ltZg`D>*Q#VpIQ8yaLAZ^^2xM9)sLmQS)Aa8()j6f zWG8no%G|&C1`eG#C}6Pxh$vu{eSzT*oPS$;J@skpB?zs<>^4>eo5LIL1=oL(Xr?* zkBrI)?3oN&3nwc0ll#3K&;%Q1tbRA^y7W({&h4Gekl*d@F8oTTq*mH0u-CD|)AY<- zIOOVBEv2_2nDDc@pU#{*IJx&S>5Ahrh{0!gy-v;%6a+cd0n@g1-g3X-Oa9qP0xe-E z={ur7I*K(ges{_-IQQ0k3|K=W8{h?A>z>=HgzhT*pQ~07%;X%&*Kw9S!h!n)9bz-= zo$hcDw1N|0Cw(+Pt|k{bR$=FU*Z{e>5}NCN&ni)lQJ7hE4A*{mhE9L(eblVlSM_oR zP0$g(TcttAKzV2Z*~2P!2Dtcq1JvxJj&<(m4AOD0?tJM~*wxh&!6=O=S+{U(bAM$; zFO#>-FU*HCra^#?-+iji((aFG5`OHC59e6=+RZ(VPaHDPC@S=sfuDV*cwlhf5y4YB zWxMy*$-lSP>SNvEC~0*q_iqvWu)h=6>16Ns*l!{y>11!EO{;f^4=v!74v9xN_{uA- zawwj4N|ZEY#4%NSH(VjJ68F03` z{=tbHe5(A+UY`4{deLZb32Vk+C2`##7UdfQe#GHcboEia!TWj9#n3f4&jxx1t}#D4 zN*a8b=@aY;-;Z`)J<3m3;_;2jOdeL6Sx68vE$ zF$3D>z~8lvHRSju=*o2Z;6og~sjOlZQJuaGGRYN1!5L(^Wva8S5I`ut>>(%Ly*Cr* ztdead$bOt#t*BxUTLhco5NtoM;kbGAi6^2@(iUk_Z5*|rJ?Guy+2@`Q9MIW!5eM2$ z9JsT?E0zMrGm1>=IILtQ&bp>)k^}g&ejqc|_Qg(QMCMO9-k@Hq->8#vT7`*lR<|~e zPOSsS??s%)#o4Vgm89s8yh3{E^M<)jIyy*&?H&U4q_4`=Is-2Olhag3`P^qe%UVIM zXC9s8@$sQ}UM&d3cFJtFq`j`m!;Mnv?gC%Hl~(jUCMkUO`Da6)WR;95s?4bGGqBU3 zo>hV)rPofd-#e-3ren5iTNp{>?YFQq5Yx}<7@Z6CgI4>Lez^`eaeg%*R6LQVIxo)g zQ`fIX@MBKkh5id2R+(TN@i5je&vNd>-O*FS;4hVDfN{(p{ck6z$+e|}tq$zAvrSSH zt61f}8ibxJ|5)v?4H_uD6&^b~RNKWt+`vO=Vl5EUsxmr@TLn$pV&JA#DAx%>)gfPg zU;umvb7kPBIA()o1U$LI;A2ht0l&Hs4!dXEM-fwXXhtw}g?VZdV+TC2`b zyplgHEv+&Z6QpPdvs!F+Y;PfWLpm-`Fn~vX0x_VP9l?sMLmkDX?GvZQ!kK<%W177* zL88IS?D?-h?#?WxFMO7SZ_G)iv8*5ZV1;7oaDgN}hyswq+L)yG&>{j#9Iva*N~h9G zPiv1X0i(u7XrnL&?#C_QDff$O?&XD}yx9PhvhTo_r*JRx4~&GFebAvlXtDP=2f*hT z8(P-Us;8x0=0Msm{utP8bxNz69aE)^2QvE@O6iaMpn~4ugnK-smvj$&ZeVXtB_P(q zAw7cpe*i9S#HtHA&-#%O?UGh>iDUeV!8m`}85pV?2*JZ>Oq{RiJgqAAlAa zlr7C|2lp8Y?Xi{-K#CZK)hjD!I6)=ogz{6Yb@>QwvBV&s%3kOo2$(U^!6LlifVnz< z{t|Sj1s>2B^F$NCy%GT$L4OHGZWUh2YP2Vfl9xFSL1w}{I5Kn!d=S3iPczRf10Uzx zDqlOS)u`GGtPjzJl$hHXf&?9KC_UwQ7YDTI^IbfP7dXK@HAwLNkDXKyW8?+~yn`$G z1z%yEC?ooFh=lwe(@HzaEZSxbjBsgU%H=kAKADShz%Fo)?!dQQzu;++R}1a8Gv*S{ zZ()uL1TgteTW$k(W(>N)2b8n+37R)35JE}gJU}UxITCl``M~N#-A+{AWlZ!J3P$gg zfuyb2s-bgh=(6rFErY{Uttz#q8R&-rI?4@JZ&L4J5cVO-j6uJ^Gl3yZayj`-5AjXf zc;Wnc^my=d`47KK%e*#U43phv45d&t>BkG8}Me;F9#IzFBj*30<+qN z0Dp`lE_42KH)u1W``~-^-sq#B9c18mwGZN;uecYa;4pzq9=T5l%+2SS zNE3%yRV_~szd?r%56c9y<9PCz#|zJ22)ZIa^T|HN1Z?t8`MjezckXQ1?+or*LH4+G z@lwzo^GQx z^5dUEZ%b)trJwsY(#6Xc)BJtb9)YZz=svCH97#ju2LQXRwLn#}T;crAojV~XDMQFl z_ep%Pxu(yEQ-y5A+BdN2J~Cn#@^cS*Z~3sn`YrJA(7{3PTM4FGvKSI z-(V=NSKeX#%?76H&sZ;cSp zcjxvLFo(whJLQ#WWbi=(ds~t3T;Ix2vS?}j-MiCiVSa(BB#}6FNvrp*A@{8lgr(ee ze)4?KC~1gt@hO5a4fw9jkK=O>tz76lDGNK#@*`={cfa#*kWue(pMi!?p+9~yg7mkx zR*=t-W!SHJU+5s(nt>gOy8Ef%h%Vf{jWU`E{My>Y2l)oH7QFD?XRZO0Q=?;y9T^<0a^&hx;!N&v~!7=-xwK7xE)IYLhY1D`+@= zPV9y4#|ZlKP2jVN{@dW#qSbGq$tC3q7U19id;cJP^P7K`UjE?^B9Vl;`c~vyamY$~ z%C%lE&FyIKg3kd1c^zxG>jJ(={96T9OC(Yp8=U}V$SI8Ff$Yc^lN)TZPgAZj0grNz zGWG^@X=QSCC(?WO)b9J06_pQSFT#2de+_Juw!23w8MF>Q`|Q}$bF*{Njhq{MZvbf0 z3SoZv(j~4}J~u#~JX?ypbmjL1nLl|L!b_U-y#TXk}&+c z-@BE*@r@7D&t9ED7IWwO$qr@zPkriidj7fbPj+Md>N*7K5cnGnfxP4T8$E=2=O2ZD zRnoGO7L^Jb_|V-Gg=TRcY>%mds&^EEOGnJS_0u$jQ#dU(^I{*4LY{XNB`RzhQKF+Z z4~3>GRC!B5BSiH~JQsby{k2MZ|3fo^k!|Uyo9uQtT%2l1-D4dn4O9B=H*TlD`2HP~ zGS8;ba}DXkyZ6$YH>T6om%g07|C4)ZWVAIs{Y-cITYu1*UVgQbZci!mu`~UFY zNk970F_nOD(A>r#MQ=8CG0N_1z-Xkh(j>~G0*Xa?N#9yJP$poQRN1Q%)`QdW+aWMm zSlLfgWU1^K>cfF@Anl=?qPaA;yqD%zFmhGe)4lssp&T7(IE7Pe4s;M6s*+WGs2;I^ zh6lR9IEPzE{3|9hnjfw6K&l*}r0OJNWm6&(oBvP>nJul@h|)Ih(rBjf3FQw4wFZ=f zm8Oog--zOjiNX|=Ixu#28hFR=n1vXVA%GZNd6g?>OWaNsg7H!lo}VaBG_n;M$TG{d zoIs^!fE!9i`io8+gkU5h1SleoG!#(K!u_Xx zLps23XnVtIP8j=|$WBJq`D3z;ukCN8m%eZ^U60tZWLcsw$`-_U0FT z%HxQB1{JAYqw$!)bCmrm=rx)SQrStvj>ZNvJ{vR_xBUFDISmiTsG<{+Mr@rcbv9eT z@l3;(ui)7je>^lISou_APE0{`D>tl@he2&-u-EDJL3UxT(a4gO^%%_=v)3E|V~tE! z$Iv3?b3E)vHUeg&j4(2TxsH7e^uz3p(oV0}5hf09jd9Yc9RfvePu<3`3}c8+Ccx(Q z&D%)>qDH139PBhK^)N3=A{u%Pw$brY1B2N`9pDVc5c@rV;c_2-sAGnP5;I6k%R4c~ z^kS^(!vRBQJsqw>LI{}TZsor}cOp)UYZ_zsF=XkKB|vqU*vFwuBcQyy=H#cdjSgGK z^r1o^yJHt`YKD_XpH}}|hrn+$1YB*8uDDF96i)LG%3sn7X`k!QBdTgh(74fRZ#wEo z7qYKXZo%u!&g>zb^pN%jd4)&l$RZuFkzDnzdJWD((i5B4$Q&}Kg0tsvEK;QOGv7j% zZX|8F-~71(O)4GWuz?d;5FL!dCpZwb^Uw}5tCO#nU@&-1+u79KKbTHme+IFAKP{Ku zN-H=g9OBevCi@%=MK{O4bwf6!zcC|02JgXb@&rY-hZ+c>J?JkfN#MSpa{ zC0GEXaAPY02N;ZX&)UO*!c5hTz`>vcv!*8;{fg}AYVxd3aSo{o=j2nLeldN8?9fLG z1oz=Edw@ghc>fukPX>^|akgc<5`BTrdKh5ViZjO13R!w5C(?K)72(NB+toKja357} zaNut4ZcQ(I@rxu^X(M3nAia0<_4M=?ejjHi9PHSqtr5^J4K3k#c?hg_$>{8Jci{^i z(CUj<$o7f>{sf2jMreKWU~6n$!pZ*xCw();QdxZ$L;A{n_#hQpJBJO3WB*Vf+b@p% zWy_yJtq|k(c{yTs1N*X?QIUUR_rJIbcd-h&BH#e19x2LEs z_*R-YKc1Qc~v$!g*z# zpvwiEQ;J;!>2tsTWnkQc11#gXGt1nyrXJQnCrNiKdAjH4hZ20%DDECbM|nAfMG`UfOY~jK%dwzm)IZba4>dyA`Rml(2Xo*GJvDQleE6F zoz`)7!(%V4-J0U_eX2MhOMq`B9Ab)PbO6X-Eg;M>d)OZKiyb)j6mU9jz=2k^}z5Vym{Jtm-~N-l&``uT-xV{EQR6=LP8p z_+KzU&w0J~=4)#E0nhoW-Jjd`dbvzK40icn{^$QOZ4hj&GgY+D8(oNfgIDP&XApuF zg5<9{t$Uvi*xut_!m36FaqaI)&$EMBcFKlf@;H-hW!c-nE%+nJqC(dRt<*`$eku=S zhj2#SRD|~8EX8lF2LIu7sobA`uZ=%fiZXyg`M`iSv%)Li+duc5I`zB1su42xM7|U^ zq>t`fbTZR9GiTg)UzlO0!36)-&7fN{a!LuLVH>{|{G31s11FUidc$`#Rn_=cX4Jj1s0 z*zCgzc$N2ioxrRK9vOjETxVcYIJ45033_z&axWJZ1mQ!rVNjsSca-mp?r%W1=icc6 zp45diTpLc3;SkMUOB`s2PrCODM|Q?4oDDJ%UcPi}%P%lAU}QzBT>T)bUeUh}JmtFK z)q{hC9dM6HZwv3P;qBw`#$upEa4H|4?A8CM*Fjxnc3pn!{grS^zi0rUI z#a@Hd)FG&waF3{*>H4w~LvLRfD~F(_`#2Iib_Mp7GuNNmhJXhPF=Jn`V@Ccbp zVaqneqX;bFyKB?Ho2ZP$V{`&FAW7Y}xTwQq=mEe#@yR)t-&@Vm%EcMKeMW|_IvZcd zD1}dG%YH`C60*HVf$ttxI&!{a{WD(iUmbyoFs!7Yp4i{S$#_0%MQ2%^M_qFUf4VlL z5%y7h6c38@+aOlgy1EtnE8Gpv6D@_k|7y;X5x~s+sCSBhW91zBVZs9g!jvm@g!MUA zAu;Gy{Cb}R53f@t#DHR}(^(NBoR-};aQ!`OB3AyhdRzpE@@)HTr6J+%efHG=G-=~0 z9FU!7gG8hs_Hzg4XZv5H4bG#uCwx8BQ3yjF)5R65!5G|TCBm6$^kKB4Bc_hq2L!_m zQ?XC|l(@Blld@H>go$+1cC6T^vvX9pWX~WTi2nwo(4#atImtTi3P)Mze{5oc^<;n# z0i?7sij%Yz4XrR^P-_IRu)lEp&aG>Hc6Np;FAFjLOE}O%ba^&w4LQ?wD1JuZF*czS z_FOuVOYhZ7i8?y5lbt1kIYy!?OV*XywlqQfb?zOz!9eP*SWU>$?1SiwxTKy-2WqRU z#5w|Y;*T(Q&V-@u2&aGx_$b}*yYnX8b%Hf;rXQV_&f)5yq${>x(_4zCu1Dv_O56q( zMKGM}1N>Ld>6#ZGe2)8>V`(Gn(;&xtcg0i3j&m>cDhF3)2U(M(SYbBogBY+PP?Dge zW8feR-LF~I=IWIzQQ7g{^jw@OZ+!L%0vDjT{!^e&Xarcpv&~b{@H&yroq$( zm<7%mJV~F_AsTGDOuN%mmGA%m*?Y6#NUtkF@8*Ji-%$W+L2YDlE0LmF)G}H~Ni*%} z9`)D}ju?mSiFVjCZTrD~@Pi-xFcA)i+Y$DIW1c6*5!1G293E?==?M2oBZ;CYk(4Oz zEY=F302ENzcO(*-Ncj8Ck0gt1xg~XYT52hOG7Fjia{qhJJ@=e*&&r;_aZ5+#Q3gI8 zFs_B|McR?3L*L`A2JbLd`fB^Gxpss7+|x*(m`l$&F993Q`B&$6dCDR+5TLw1` za?1FZFOui&)88iM-*xPI5f?my#({_4XJ1rH&?E220-eC~A_+T9ekqRUbLf;qHpre2 zdK$PT{#sR0JY#Pw-{51_R5yiIuc?{b6I#m2(0A0RPFgtx|G*bv8vKvz2E^-xFP6mNW0T__b0enp=Y8boD?={9Iofp4df2-i{B0ROn z{i2TTRJLN6^o@YKs9cOS6PDBpPC&K82D^jaIL1mlWdnD>g#s^)eLn3Pyk`fTS820) ze}iBQO6bCIJZ6DsC2H~nEA_M?&p96kCr3qEUMe2QzYopk3LR@F0HcW{s;va>`TkN3 zUe9=yMNBei6=uin+*o-}J-mOlL-;zAH*``7wY}|xPul~g#67YB?^c{HfGZ(u0J{j% zpl#(wVX5w=pq-!bGTIo2dX1PH=EZ;=6I>kZ6DZ31i=Y#I0GJ!P^ufo@@KJs_4!eHV zo{3|L;fp?dvv!9Z<5G_#ELlcSNS@)tP0oYwRjrn55O@LuX^qEH&YXB_)ddOLWcH%IDCdHv;(@uoJgm# z;2nZPNg5{o6Vf!m|M5>e2?^vx24f%2s6<@)3;*$bzQ_Q%IBfp?FSe4M@ZZ4Q54sxD zoIQN`(Sf6 z;|G|BH~GWo0D4braSw<0Yt zQC#??kbqm+RNbk2Rq56~YwgC3Tj|1u$&d-)y!53+;MID_rY0gWU}_f~b?6)j&=U9a z`2pm|?Vx2s+GK69uApDS!1>){4=n|P%_HMd!47(;ET>G+iT?4$7hXv#R8N#I35Q3n zJe(#8th9g1P0HHA@1XU^;6YQ7WCzGC&B%S9eCAUmOq~q;kRDdhU2bieq{86#GJCVW z2(~idND{_@JKeZ`lY2<~f&4y55aQ*_=;NX7CJ^tSzsitSY^7@? z0J#|f!QMN-Ueo8ahX%i5j^%kKQdOprw=l$zT}@QuUgpMow-|G0ROuTVod`MBeo7P6 zQEVZzcUln|c~^d=tSNe*AYAmt{kMBN?cw5~dn0k&Ioijk#-K>|G{h=D=gbCq$=R%vsRP#9sBqP`Mg2b29|~%-#~sRi}$)7l&Kv@$i48U z*spL-zA3JHc)Rqpg}_3Slw7!Y0o+|6fd~3?^x7GO(ND9VbU&etX+U7?8=V7yDGZhW z#AWviRy*{a_QgGs?K@xYm8A16$jv?z@2ASKxa3|a5)v^c`|qAtzG1uC&&5&Y;z&5a zb@xp@rQT>iSR+pfe?T0(!=7jQpDf9QysCyd*<=9HeuMtpcbfd>=}$Zz>()2ZbkGRL zWgnEuuHU#GI(d^&I`>X+R3+wR;*~T-y!0cTaev_0-H#|o_=#zudEw!{)4;;;Q3DRj z!^+tn!s(-*2hV3P&Bow&aa>tMT~mEO zp1OKD{a63_zfW?p%~Y=*_~a9pAkct70|E^QG$8PA z3j#Yk2kH6m-$~#4_DvGE%!VBQ%f3r7>!~Lv(wDz{IeqE5OX#chb8H+92s9w@+XMl% zVvXZB2mK4dm1bv;)4Olu zWZ8>itxvsDf4cH;K3%;!lBVzE()e7bZ7r&l5z z&C7-<1$89`D8{6!@z&yUx=sa-VKTn$H+A9+dYG1RRK2&lnN}#TJ9=&~jXiRXckHC; zg}dpok@Kma@tct`l=J8$)JteoRXvgAMkf1G+De<%%`}7KXPGh|M^wDi_}bBelML5d zj&W`=tdEL!gs^1>33^wxx&{AHn~(o6a*^>9l{7|*eJYFKAWR$WEhu-m=2%eWq4d&# zh+#NK=1G*7%@|6$RGMO-!h}Gt2omI8gAEOGi!9?*W26)#3MQAkigA@M7|`|z!fWXx z81imfnqE)Wf4r8qXUEdgq6)xbnwsrPe|O{@j=W?PUM#1@SsZZlqiGiB+k@IxY8&26 zpa1>OrSU5$M7vcO_N6%j0B7!}G)oZYi*Mec(&K*W86&7>jG&BOl#KW=SMe(#X?^M( zqJm;K$|t&q>Ky|f3OioWjL|1gHOHeG!Ig{(YhM6f-O3D5B&-d9`2I zOS@!`oL{G6Q+Y8BQe_0yW@^Eyq`JRKg%J&CjG0lD)^-SL#Q2Bee6;gC$~+W!se_LW z1Sq4$N$&HA_rx}w%|p%{MfBJ}6a9Up14&P!aKf9?p2 z@dsz6y{=)6RvHB~)Etw3Ri~22o_I7eRc3~S)~Hr<^@%6b*T4StFko#!<8`di`9lMO z*&WUPK0p>b4P@x~G2Gy&k0C%uiLK3DoTO%O-2W^NEc;Z1BM_QuLmwD^?bio=u7gF+ zlYRH!%;+nV45JqVP%*!`xrQNXJ55fSp;2QFFUM#ZhIwd^jtq6)>RW76XQ%yxz4ZDU zZ-kLf1IoMCu3@N}B53h!Iz2IgLsk|b8P6~vvvg`8tsfc)HOMTl7)W?OswL`VHI8#x z55_7Tn{;N>$Y2$T8o?y@xwjLej~U0u^BAUZ6wwJ!|N!L5CuZOA8D0>6KT167Mi`;VCK|z5Mda;k?z3^QK0<3C1-@pq~L5 zIvo`mQyYe`o?36}9H45{P=8ulTS4ZSP4jc};do&G#j7zgVCu+r{@nR=;rs=%I%6ck zaD`NJ0uqh)brIOP`~X(oP)AjrGj(oSUR_BSFI{HN;I}yEX&gGJV36I0e`BN>JvB-d zgu}EB4jF{s*M>n8qe$J+%e4~DQXe4wNk1BY8W3ne;G+=G_$>X%mgUK6vOs?hF^u8FkUgj0D3RsZ@&39g!_iXP7Me2#J0s9~ga zucBi=gei4l4Bx@IOGnvFoVz;7)_l0TimYEqBRJA_wl}Ap6=d=926UBuM(V zi-5c6V>S-QrW2r!F=myQ*9bP98T>0PZqWf_U?|-u^YHK2>PF|UrNqGVUI>;EDql(Ag@($G@D{0Uq zCYGKDukmFduwWYp1F{`65l1)~;3~qL==5)841N>0SUF;z*eiCm5L8E%sX_}03UW9) zGiQg$4?8+YR}qmf?|BE)-Vb&ul*C8o^;NKjw8>@H`S));jz*lW#uO5hK{j1TuCq7 zYuK#&y}E-@1j6BrwO-ujI{PE|TU4i0zL(yU49#{7cB?yy_E3GmV7_*oqI8(jaa<=W z-)aAIIR6>QV?`kEQQsC$QS?ElUjtDL0Bq)?Qwd=|KlPMWO!D33sNjPZ zOnPg3=)&B0@g^sdbMyf^Z$BcS1G+74=l}f;#|E$`zL{;34^{wcm&bwAPTwPtJBE?=f@)~$z z#Rb9dp#!MFfZ~wOaso=Y=p>m{0Z^~uo&G}~sge-ujg!i4aTXnb*TfGG_w!W*#v0ev zS;QI^(DX6d;o0c1ILbL4|2*Sm=Q3d9ImTmKq2oSzwoEcL_sUrSAc1r`8Z(BhMV%6H z1g0qiKO@-0y}5D(_ldW@OB^=%Q2Z0uz@V&;@s8~M-WPfa;FSd(`a2t&WAu8ACB8c+ zSpcc<42Ml&LEj_DH}L8tI13QFPd8vmTA|Z(J9^=)f8v{gTF?QU6LrA$HCC7wr*u;7 zfVNoWKp5>1M6$GmQd>M{Z0`L#dENjr^&h@R=Vj$|gGn8?IAleHZUR3{xU?{TF9Jq{ zqc)CpvKxkl@u$5L6*sB=)Cd>?^l0Mj1 zX{9*kBugt@)AbK2B4X~dKuKvVbfX2i7&2>+S_^?MyWp=$j>5T?AP9q@q@h;5v(FV| z%LpiS4dGC%L$way9mHkhe&04{@5 z!a&(r2kR%PXsDjbN=xdwbPn$!SfdTto5;mIo$Un|VGeU7XbE~H{&7uQ37n+=R@AUk zmiXId6$zdb?+pIbVK$tqV@+_LM%6Gn-#QUXFU0-OKLL9KpPUzQ-<9TC5>DAVsxcM< zr}z}1U*cN}Fp&-#6cjcEXq9#xgGc3w9^#R6AHht_pKTt)M?7585j4hp7+fp8mNy1{ zM!r_}Bpx^pyDfdo6btOL|`*0gXZFT#9}P3xfsJ7h9$C(%BjTfh&UN=N_)5 zJ0x%U3<-XeaSS$b1kHO?hUC35Kj=-R8`3-Ztw9jSFfvsV@>MhP9AhVymL3shC10^` zN7y>S$ly^{#$m}b{{-+s6PzPI@-HjJ480FJWc9&Iq&}2-~f~230F`x;GYEn z>c9^VX8k`v+C&$%(b{~l06;sBN(4x zO#_todeE1&0neQHn5am#h5nwzrRa`#H=%O`ENpI|1E3Sax)(!r8%co*;Nbzd=bl$h zfHNh&J7MbOi;TCuy&L+ZtjKs7LkG`^g9hhE(5|$AKC5Rpc=Yb<-OzQMK~I0~+$2>~ zPX{fOCwiaF=cMQ0R|Kqs_j&gD@}-bl1fXaddZ_3T^n?EJZr7!OnY-KT1o9$(0Nd5o zb>6qbc?Xd7Sz4dBUv&5wT;suL(|)^nrFl8+&&U!5l^noK)qysXV`xqd{FDB9I(v|H zMStvn4t!Mh2pzxtnCGFKtTp%#&!{)49yX^Ea*|amtyZ`LpOj9LGnart+r?@PE;~;3 z69)H{7(ffxnrOQQj_#~LhqxgEOPF(mn2zBYMi3!&fMoPWTRk*42QLcjvp?ADm5~a0 zYzX}4Dc=)a1&3Ud@|Ih7?(ob}8YvAkXS2*}4{H+s0A1LiO6@*4tBxedBIC;RlgjOm zpSiS6`f3pUlF!*^_@5Ovs1c zLeH{C;v2Bbu6bP^oagUHpBD~(TzhdXen(>&`q*!STC=Xiz46S+35P6>XE*ykzn%Q& z{Qa!M7saG1RnK}6k(l!;gH=}hX%KsoJ1K$8q!R_ zl7VW;CG+7)xbLMQwQPNZSq%zzw z(Mj^~W%yc!WY0(?0f!!BSSt@#*#r8%_ujjPqp06fS7yHUFeTI z!|}KuJ%C1SpeJ;^CLt}-!TNeo?#sJ|fQ|dT9b}IjLUJ=a+rEo@h0bEScI|pvxObm% z8F*L3=KFX$fBqb>!+(Q)pn+e)#lR+mvd1URL`6ia?_GWDVPqWw#L&;~NE?B{DwXM0 zS61Sj$tor%&xMY`y{B?!r~3uyhzU#Y+@4B5{_(3M?CVNr&z(u^en z&yW2PywmH>gZxIFfB}KFC9U;PXQ9lk4kN3M2OS4Dd+3iaQO*uo79S%Y*}~54-oWas zEnN%e0&_bgk8y17_q@+NVk@u&Tcbal^#2q%qE0~g z`Aj6e04T~E+P)3;G{G#8iS_1O7!;_S7J3wTj`|tLXLU&fD_iV8a#E(Zk$0$9$;bSz zu2E5*M32I#kHAoa-W`Xyt}GBxq~Gc*-hKDoboKEkql%!(Pn7pv!>)~En06n&3RVtw zj!f>Nysf;fd|CgvxA)!Ba03FZ8t*>Fy^`;fmeh}WvWhxS@VvNd|2#Zj-v@f$`yE^T zy1zZ2@dV~t^ z?CMzh%2ysr&pmsIB$;Zw8b<>H4G8?ULcm>STJ-_!yJ-Tc>3CE+F000 zn@ihiZfQMT{=%iyeT1P4ADux zw)wb~cRybxXzSLU9kSnUkUfixge3whb_(e&jErkbYiaWFLOOT8h0I?VtT7s%I#nRU zR}BR?#t8xt4^Xr>wPF12!dOH#33NMD;L&(UC5T!l3e2^1`uq@zLV^u=Usq>yn*2Bl z+H2kE`a4vi+iyzmythZyz;aqyucW_wev+<+DK}V^l2dCc`G)C z;zos;)aZp$9*U7auo3dO1>%?zB^H-9gnrA z>Xp89fT1go!E$Z$FfHEOAmc!9dgs;x3a*sSo|;G-%NTaeB-K?(Pk-uk>KVkbMSBW**0?o1q!n=j?PUu`L^)UkcyiUZ>DYEnxQv;1L3(Qq#8#90u2b%A)xZMuE2dz zVeIvwjVzctja1oOKU_ya_grHS9`7%(5AJ>N@`K;i1Fzt0ze6Cw>e?zsfF3H!-GVli z)78Qg>E?Sk((nELSCfW!9Y0HKn!<>S!AgT#D@I=x@@8vngU@Na`u*SicL)d^NE_SG zt?9d|pEgy@zkBVy)Y?(Z&d*MVLCvoAkSSV4_lFO!NI`;%oLrJSd@v?ycpFY8=P)L9 zb+!_CxJjEjsX!xN6GnCC$lj@7*T}3PV+9AR`FVn;sbX~X>QxLT`xwCY(ink(Eg0(z zzUzRG)d+4Mz%UWcx2-t5Vc^l|VdW0964t1?r~{csMjdUIF|K8bf8YRb)nFp?6c03t z)Ob$Ey1RGp5^Oma2BC9j&P4#=olP=u-nbE2B{e2xFeW^nK7Zz!&!kf$V>l2Hcmho8 z#sv*tnIo*c!M^N-v1AM5{lxf0`h%~2HNEh?@2At_V`&(poY}0M6XD_UQTz>{bH09^ zJ0gSnHW^tL$gcY8tFK`UoD3FhaM0kX!SvRg~n;DdFR4LDfC$w_IS25ODJ%F;R&c^u&+8w(J+;yq@omCY2I zaWFuh%_C#mL=}3VL$*gahqBkuQK?yna@v!A1s`)gDr;&Chd*fag)qc((#$+YRcV+! zt%@wEGmVCS6L4hfIc|+TMl*qbM;K*w9;Ig(?a4Arg|_N`cbdO*KMmrvQKBk$vCnEc zWa+I?^$4e_cKAUKXQ)H6Jultgi2$`KMqV8_-}vckX&G8wBct!*XD*~`n>Rx~|Kz8h zA<@Qo`pI{{ivtIaXUM+8XD+5^|AW7mhRzb)hXV*Bj-l9hgYN7XBaOakM2`RhT_cgWAq0H2P!_b_4cH@ zH|7Wm%cbG*(e%V~&!v{JVJ-iu7kH1IolGrk@N`zx32}$QA@<#f~vn3on$ZpJ> zw^fSi`nzP2XRO`qdCv~^r?vOqO$#`qE#AAAx`6Y-`bruYJ0X)Of0=tHuJ*n2J+I>)E%BVK(@-IvuDOr zA3^aTM>qqwQ;n&AXpn?II2AK*ExfnR3;EeN8W3ne;I9Y*I(hZu%)Ww*?or>zeXy64 ztjqUw@{Bw9$KTS158p38@rsB05czApz3l9V|8>oK|JVQTf1d8#xykoze<00{wrHb9 zNfHA9bQUx~!1j8m%r5WILCT<`KAe9dBRaI-{YF-mivSGti&ihv(aq<*R@D&^J`_$# zjNRfcy;NuFCMeuslW_8iLHJLW-MlqtR&?Y8=((RZbbO z$NLS+QEuUK&`|#xh!p!I;L$?hev#nt;E-H2004#`@=VMha~c&E86U5Ub|C!l1m{;c zS$)bRCpr@n>;V#F)%TEgY{38d8{d(EWW+ftMhFWX!ws-319Rmu121?*I5g`B>704K zi9QNn+j6}7$Vze0uGI>4j&{E%T%+Owt+?0Ic~b{U4;|YXuAPZQ1IjTGkccC=!3hPU z_4!|2gCAwJ2=+maa~M_>C?QJ;DIL;FRs_V6OANI_kN5bApcfqf;yQd$r$HS7#RI=D zvLDhOlFsQ2S!ImMpKV9T9=uD(L}jZCZ{Y7Z zln;MAz`wu;p0h$+ z#g01Q_YdiYxX74e{KCNBz8B3n=Q8I-WmcbMyeId0PbYyGk>rOi8(g7dbgXxri>;zz zl}{ZuBM2B7(;z$hWgiS))1g#HX&sN9k7_lmIH5CVA5PlJ%Le%An0bF8!)t?H)WIk} z1ztHG`tRBl)+R(UNrl%2&?~i}*D+u~+S`wFtNnIgp|iJoCLJ-YVzEwjYy%vv<|-Zz zvsbt`zYvhpA=Knm{k;Q$E3OffX+-c1eKlCt^%QH1{zP>fVCCA(;LW_UX06QT8kcU^ z57)C5sa&H5YUx~S0G>KF18tOvy3G} z$S4)7l|OaxmiM@p4d^(c%B1v3{1*l~m**I3Gi%=<4SAoikG%po?O43WfQ<<1KAD>c z>;~ori3t-O?A3ee&~LxPDH{i3-yQow=Gp)|osO-3QlmZBmTN@%bp+g{VeUPJxfQn# zk>PdhwZFo{U=<~C`IgTFE#|#UBD^T0VLCKheZ@A!Ywu~|y#{7(6HHKsM;>9{(8N3^woEIkc*Wdv64-AV6u~@~R8Ln*|$*UwbDe^uY{B6s? z0E3tgfr*Ff+-gP5EzE&^=A4x>oqzY?ZQ#S&Mui|z0tUdhwaPllx=18KJL=Bb!TAWn zj{q>SR@wmX;5lL5bOO7aiBLHFZPKzFYt$v^m|W+s=a?79EM7`W{cAN)`z-G3@H}~L zG6GWF=gI3Fr}H6)@U_JE$pCi`)(~RSXZ>;jHbm`|GZ(X~cp8L{g z=`%rq^rJ?yR`J(hSm#_klxMqkq~ZtA?iOua=#8a;HLA)QP%aI0@5}IjKl8)3xCvXT zG{D3%+ROMF^jJRZr^^1^`N@Gl3^c}4G?*=nk+jX&_t-02RZ?B8YsWPa)u-Umd+0S? z|0YHgzbnWG!bkZlXHYUdjv!f{H+ZX5+6|m3F)lifKEMDclF>qsd0Qj`Fg7{h4QP+C zMelHadVLw)M=qV)I-f3L+iQ}3V}tI4_9YVjMBqF9H<7^MDph@X7b_5}DS>9nOjJlc zg14&|Uoim@d|5o)1*ggcYd`jhkEb)NoBIn(Y3An5w7IelUMnYMa!n)~Aef9E0dVDH7a4DXd(d;Jm0Y*ABq>%<4orhRV#VtFniukY|InTFY(I&0DC$*HV%#K zA@Sf)1PL4P3+SPX&;(>D0}KshX;zl&kS}2k4tWWR#`u(R4f1iGt5iL$5Oi4+e^{H_ zTWbUat|8m(qvOC9kB-H0Ne$%#MRX8(#>Av^-j8$y;P_#V7zI6aSq zf!N3$R@{=u+aLR<4MX`~dZUc0JaRy_L*Z_qufe14a}1a_QGvn!>Y{?y0SkF`i*(7o z2xH+%o?~{R)4<7VyvrbyU-XFi_Wd^Ya}H%^D?<9>W9B7$NSf>?>x<2ZVHr|VYG}!3XZ~#XKet^KAC6?0x>o-tVgS_~1Fm6ypNlls_YD7fr=sf596AYBM?4 z3(k{s!M&~t4qh2@kNcR7jZJWt`G@ySP0z*kU*w-BpPVF6j{Ty%+Hpi5t=wxcd2a;l z-n%!SuD^IaU3ui;2;>_a7)lHG7myRPV0vlw@bFOZYAcn^FW!qv#O`gC7nCJD|Jb9C z27kXtAe4LLThKK5yTQ@oqWdf1)drrqKX~MkD=bCiT*i0n){UrwXXWB^=O$x4Z=owR z*sB?wTUfu3E_wsHU4svHglrdb6XS{ZfPV&O()XW#F|85A zr`@lsy*pjJaF!&TL+}-3Kaz)Q4_4mj#;3_Wi-{wYy`A$t=>M%7w?nrXi7BA-R;M0= zCbyEfVh>tm0Gc|4mbT+Gb?0sba?1yWX(zhUKm5c01o&n0+Su3` zpu0}Dvdq&Tf0{(C=VFa}-h@m$@=$1t^Ac+xncKj-kiVc2HDtTsuLRLO{`ggBeU^CP z&di+%SnqRAt&EEN;6BrRfbe$T+(%MeS4D=;;2-o~`$>^NNpT>P0hwFu3dLeq1Qc3X zQeAJ*AYf$`>U{za-G6r>f5%!2`6lC!wjphE4kI8HnAZBB!O(eSUshKv5%&hl)~)EA z-B+j^sFJKe+>-t)tBsu+kL0i7OtH~xkpFVWIo-mw^y{4llXz) zZ{cr}x_KcP%V8T&MH5) zn=}A<$Td|1wg%#wWUq?^Ch}AJBpfEd9miKc*4Y0mAHyz4P&<#mlgR@ZKQLb-NZ)lk zza?(^x&l`H9s&psQnQ8s75jd`{rv~sr~_Whd#6mMa35zh^% zAHc6oye_j=O5m}$RxYonx8K4(&H8`tOV6<%aDT0C!6Ybt)UzOuBik5I{JrmeFP$b? zftBHv&FrUr5dWPE@ib(6`unpE1DCzudwi$sy#BoH#a{B{SBa) zNP|?}EA+RdxwokD*5mycskV;N+SL6tj4|TThfbrAYD-O%?C#n{6inCI0~N0R{wzH^|G$Bcr4<(NQ(+9pP%Z7Kn( zB-K!X;tgeUGm0t=R^(ddUljXv2wf6wWlj@*MWqu)z&yqZr?E-H0DWsBbGG-J*)D4S~hTnmozn@pd`p<8%5$l6(@@g0$fl?bzAuZc!%MGz?~Wf z8jZSDlvYP5*qROK( zP=-opgAJ@KEBV3D0l!d@tDVmE>rq$is-Uj_cFl+V!Ry}4;q%#%y-kI?j*^$pUraBO zRkI(XPCtgWGdQD<41JX>Cxg%rs^Bdxr#D}JJ2G!xdH4#>Kx^sd_3O|fod$LKgwkT1 zP-(5x#La8(rEh=dyXoxN^PI+@i$lLv6>i?7%IVGN^o?)+S^A@Y@L#5fF6(3l<&Ew^ zxliDt^G^1q*aKa@aOphbpyH97 zjQgxwXuHn5&KkP}&V{2RhD)7$nlM(atS)n}8O=M=2##Fe{8z7#i9F=pV2M$BANk{)O*FVBXtE)KNbrPURCEFI}JPaF*LX zn^IAC16CR})2j}i+1ZS~DqKsk5w%HLfl~n&b#tK={Tm-oHH@D3rf#Me{>`7JJciq5 zs&tqLWM`cW{5XAew)J3G97=Eh>Hm{z(6wPQZuAcKr>S?|!-2NUo%wYA#(SxJ=VkK}?~eE09qr@}s&jB(WH#z^0WF+7Kp8$OJworEtPWOi<*FK%M1@W(@p`)xW< zG2c4j?(r!wr+MCQV4{Zs?ZH3cKL#Xj67bgoy&fcy%g*L@x=$sM4x9jVlr5Smn7xHn zONwkRbMW092L1t@Z3fa%RHx`he$bQ1>IyqsD`|Luy(au-7YF~j-FX5DdDf~F@SZMs zSQW>SBjyOdkm(akMOytfA4qGwU>XARtXl=C_Xqb${dlge`gih;&LjE z&_+8>6*%aPpp0Feh0oz6Qbpd_rdr0emtIQu?@p%!=A@&yoyzLNX%xqoiH9zwj9AtH_quO9AJiHSg=$vir z=+vMSXd67z{dQZb;7IVw%dfES!WoURjiD>(<+HTBoaPr6crKsDapdU2xuOmJTe$K_ zT3=+|aZX_S7LM$1;uw^}*`|#(dEudl2;QWUJ^Skdu&}a38@#c>0|S*C|1==*R|FR^Rj=Ni4T5f`yZck&k;8VkBq=E z`9!pzFl0TS-g@h`aNgCCHTGceW1owlF1VTrTDq09**~~P(UDAtr$hL+G{b-qnnY$N zAR9X8(FAWCIYpp1e8GT}K7;?OVlQbYuh?2v0zcSX*C<_ROxH1;ZJL zhyy5kEQ7X6@S-j%gc!h}lbD(8b)XVf@_!xK?5}j+O0w#%{1|ktLp1)su}8@qo-(;Z zr$U{(47BmD`lkr?V|+SanKZ^KL0&VNKz7b7^0du6d@h@-j28yaalgl$x#uhG=`5aA zNE1H7*Z?N^lfi7xPw3CsTY0~8?eEy1>aZLET&6RK4bbo|nB&EGoU`EGGQ2iB%$9WLEtwc&_45ql)(#mwsAfF>{M zCg>B`nxWqy37xbfaFD*XsFA+ zDiE?a=em^_Y|Ef110Lj=!uWu_-R|ZJ&YQbY{lYzBJAKxXPRBSaC+#Aa35N};46TDp z!pUF=tK{l{s$>2(_dD|eL#{QWV->#Y7jzD+xqm*HJ8{|jvUyPwRcB&QXf_8?34wNn zrImMtYXtQ%mj)Av?>g~Y?Ky(_d>nz39NM^Paj@omictZK@N+^Yp{RHl+hrSy2y*IwPAC&U>wXWI7SF ztBPoPLZr*kiJA^7-UP=W;iG_4)JH2 zD%o4;NcO2LHUjNMgCFp74(+4CvIS^I2MGhE3DRA!9iua|Ey!q^VE-{TK9Af)05!S#klU)c5oqnCi zU6NsL@NN&+^(fV4#B*uAIBgXlX-42J?MwT`4}-gO7S5{w7&NN`Z>G=MK-Z?@_7=R! z;LnGV;adpy@V!=>^CLc~;}qw_sbtnPaZ~S8pYK)-gTf(F~Y(N#(7Yt|PY<)*Qp&NMF#v;8k?H z2i|I5U3d0PUcJkj-vM`=H=nVu2GdKy47M_OjfdD16mg0l4EpRE=)*z2ll@=UiJnZ{ zH1Uc$$}Mz`x2NtzWzM}l0tFeT0R!@O;U&$N&lxD-9GNUgIwvia=i9%Gj$+^jzwFNt zd%jinMZzY6hM{A&C4Uhf23;y|$PaiJc$n103XU256?gX0Z?+LUU@)dm=NHf3At}ll zqxt#A&D*mPaM07sevI}F9IipzOhjY=NG5A#bkP`T@+Su7jLTu zz(Ut;PZ=r;PNZ${+4)d+>2v%;3*5(V?-d>qP|28-Cw#Yj*pIkiV2boEcp>Kw(Fe%$ z+!xwcseABG9OT*Hr5&8r4Hn52c^|=J(i{U6U1!4Yh~L`j)alEg+n}EYtR5M}MZch$ zk;Zg~_Lm6)xi&YGMzIg~#9Yxf&)fezcGY9_5Vqs63t_Pt}lZUC&oswuOgH5tp+Vq{t%BU!iRoGGAU#s6C0@;u##6QvOh)!tbsTF zr#xm=MD+_@;HTp>C?u*{GDhtZw&`4`PgmybLf0M%E1;F)Qv}k{d-XG}ccv!VaXjkr zoeL?F71#_gGT=S%o&dl@f-Vm$u4Mv$(N`!h?nCEXm&zC7xqY`S=l9S61lET0t(;nr zCwny;BKLqV+$WrUN*q*f(nf5;2U_9dwRnV1WoPVj1`jES{pS9Yd+dU1j1KV^n>a=j z?Jmd2G#Ctmhwt+aQ&%-(<2OLnXKZ7aYNG4#jveNv!aA&h8{#iBPV2y$F^bhrk@77ehBhE;u* z{^ihZMq?s0A7Ae}&b~!Ae&K&;>HWj+w)L|QuVi<}djtr_$)D_d){{6H_K!}z>wAM&Mh6~j@WJm{Yk|8b4cBq`{q{ItZ#w29`YMlC37p}S zYu4&}ZTKo&d+#=DPP+Sx9iM*YQt%UHIOotlOM^B@6y_dC`NK74b?FuKYOZHxF00N; zZ$k#<`h8?C?QinJCFIUS_=QO#29Y@)y7W-$YI`hg?QO=sZg{94n%9@!d6#5j3(M)X zpWY3edl>zja+fk%5458MZIA{I4)&o3Xvb&g9?3bU(-HxPCZRCM$n~I(;QYDs&@FU! zRBq)|=w!A?V~555emnN~CWkvLGatw$?jellb*;fr(kg8f*?)HI zw~}n5n}luXJKY;UIj{hxj<&CJfH3+K;KS@6;H1l84qjdH)Vd3PV5 zAN11;_ZF}lzm@*k*ZwcyJ&>M#_Sy8szxf5^JrXYA-o22oqz49Q zb|UkZNunoTch8}nyNu4-`H`l(Z?@W@vXMBK$!y5Nz%2Id5I|T+%zqPf*n}GH5AAOg z@9)M3XdRlhZqg6hv@)TAYSJB-oV-BWu6uCzo?Gzg{_q>hf-aRcOl~X9D8rw2Nv_^c zGFkT^$^rJbP9hc#O1E5Ci!|OqC+f>DzpPi*2&{Wz~ zev-c$^w-i{jfA)+cyS#Vd?_#6U_Tf@OvD$7zE=ap(Fw-~C>? zjIH2^b`%aF>7{(kk4K%S$&17{@A0EvKwX@BvY_=`mlnETs6QJG z@J~jAnR4#&qg+{kk2oW}@~B^rAHQb*{EKfspZ@26^nXNRmcRe^zWQs{yGC~!5NJT4 z0f7bt8W3ne;IA75w8Opl;&l4fw{N5${%{((PR;5se?0og2vyx5N?-ocWo!stzkCCY zCmIlFK;SnX0@=>)H-4DEo&!`dsnUT|%Y1M)2^GEWk}B6xz;Hti#fSz2bc8s@vaz-R z+R1MfJS#I~)#*jSLm=Hzi2%T_71GSqaay8c-r$8CRoYIcrMb?uJcj~l>EZO^ALDR? zGOLB4sOr{N(jG;Ls@QePEfo}Jqv_uMMk;=>Cyk)AICr&>%DJ`FMApfsW2+bOKT7*b z1*IK9h1=^Xz402x@D-Hd{aYyH)^Wz{!!ZQIT1#j8kN=1aO0-=$8bB$M(o1jF(lz?F zT*bJ03Wdk!V*1qQ&!xw&Hm8f1Xq@p5Vx!*WUF%ksTN@;}tbigRmo7e@Pmg^ppMLym zEiI5Wux%395ZvBI)wuyOHcnh?7mSHM>kTuP$t4%1ZO1lfRe}x{Qq@*ocyhDDF_a zfm5i-FqTrO0%MR$?Y(uJSaFOk6wPdj;SPmMj(Ix5s9P(yqOcoH3p-R`T-iypD^!!( zI*XHP7YfPo)J^A0yJXxQ{BHWAKl*q&eU2c)E`mUtFq~qH+M{aKy_NR#gIir`o?yV^ zW&$f8ogmBfemd1Lm%33NkMvRD@zICVcfNBk%~J{GpM1X~{q4VfDP07HL#>rGIe>DJ z(bQ0!hLHy4k_z8^4X0q7b_y7fH`ni=c-dqvU~C391sq+w$Rydt%#)KUZFc}C6vmjC z(ngL<&Zj0*34^hTWmT3M4ANS_VLC@8L<1`M_e4kNqy&yS zInesUUvLt{2r!7ViOy6SGju93ySkY;hlfUakCo|G;{GuF>huL|(Xm4(z-=<^EzHkz zouD}!Da%~54XZcYUs=U)0*x!-yoIBT&XR)X&x0s~g6CCaoB4fxZ3pEz43Giao`(6g z4T2_krx__X`5RU5;D=%9(31Hxps8^ntJYA27j}gaLWekwi^4%?#SR?L!jQr9I{H{q zLcXHop$1M5jR3+zLyATfjgVGn%CZDfo%Y0eG!*<8(yYX&5z8*=^ryil4AtR;rK5m` z1^69~5JE(wQ8PSCrw9!}S%zI`F@4ylGdij6z;ks@^;xr8j$y3u&{@+A?kxl`=+tDN z<+pug)sJz|AB{Zr=O9N=49^Sa*}Hecu|OE<1k%&lof$zfn2BE+hjjGu&~Zzc*1D(8mPlwWPG(He&?Yj%T!^#H#e6yR+rQCjXSC1Q=bec=7YU; zo;$*T4Ijj*U>6?LsiB)^b$pt-b&Ei_CIZvQtWO_@#wXGy4kSvp21Db95sqp_`eBuX z);)G4Rpj;`zMOUlwn=^dH)VL&7f4e(O*FGY-8f4OV@xkW$2-m93!f|NYz@!d#c{+8&|MV*3Ak?)N3#x` z1KM$_I6B@=%gbv)tL208Bb{C34YqlzeHbSPoWJ=m_D>`+xi@tu?c(UW&!-t<{5V;# z#T+G_{=t#7&phk6QN+1rl&ZGx-nq>ls3{GeyO=)y*-xiV98+~Ftm4c^Xk2Q>Sz?2P zE9-L$X=az*~lun%)NoB^;)=zZ{_I>T_>sq^UaMz&_9y@gU9Q;3*`pI~6 zNM(>toB*Q+v0R5@WREX&5xfItHRzaj{j6<;SKKgz)@-;k?eC;XPi>KLnTN?I>f%Z~cG ztvm2|R+(3!IUI+1R_CbL5At1^-|x!#H*eiYue|ay4wmR~IA>tL4(UFwBau#NR>V*~ zHSQ~F^Iq0r{;-E320ZpX1O3D7{{~_Y;Je%d$&cmfdGvhqQ|I9N{>c50d`%d+N6^v9J)7{d3c()11qN5?0BN!S6R&i^bL^n}T?ap% zsvMK^pwpJm+Ln8+oQ|33^xT)wMQE>k7^DYe0pDrQn&_7SVnxO|!amEri}UW@)WE)W ztH#E?JOi8<4*V0{ERJ0E*TB&T(g8mHF3>M!0UZVHdoz8vTD(qmCiEJD|7GuXubEYw z${aM|F}$--AovQnxJUH5d`JY-X9fItTva&_ty2Mt^jA9Zjo zP=Uu_E5{pwBFKJLd2wG_pfC@pwSl{E4{}#&|$NJOyg`Ca3TI$tpMIDplaj(p6$YjcAtm$})Zwj^? z;)#3aY)x`6*IgINv_PDoo}E+U?spA(6JFx^3KbEAtuPWF ztU#a>VHDv3nVe&BPk5}Ztffv8H-&R5@6}n;^%p_E;sS8Dat>e&d^b2{1LsuRh=4tC zzPpPmZ6qzSa+i2vk{*LGI_S57W7E@9%pWo&0J2?!^t`u+b*qDG1Yo*Y_}>HwJ})HH zkE@rm`lL>bJtPEl?gp&7!Mz^h&BDU{aMacT`1-Z?B58zkuG8uO@@FUe{tk2mI#ds# ze-OUT=MMUD17X*3xRxF%|5~ll8w`vZqH^`cOP7Evfe0=_4*T`qwd(E)`=*(+7%gFaxwZE+LNk)IOwj6`FTCGyS4Vbqg(^{!YU5vqB>cBSEH)38L zzrk+f6XOveq`pnP##t(c>%44>w%5db7~ElSk9s2=XM;8o{Gb!Ecs4ph5)f#&!J4nV z`qOk~@_ZIx&HV-fW{ue%xbNCAVifpT@xp6X?{MEH{#jAv>eY{hBf7yaCdHaOGs&2< zc64TT?xo2-EX_3FQktp5u4~^wN~_&?hv%F(1IeY^2CsGWWC6$0l`^y~0#N9i8cqYD zYC-E*FVZX4K?IY4JFdM5$RcS~@Jyc3`LzdKkn}~GV&6*W{Pv*-@=JA(!dg6wfLX>7 z0l3gf=Sq4jt#m8~SJhZsoj5;BXNAA>yU%{1t0${iIdS?7G@}h&COn9~+DGZAv_t$b z;g?lbgP%YYY}37|@3B9w>3N)u?UVD^;T{g&+shu#Ltf^3mA1MjMNlh|baPz?|NHC} z4i40ZS(%5u6mo`vrBShl4$GT#%63j%6V96fg5slNv6{QOP}he#-Nzq$EWQ5Po9XSB zUygT=fJ>iz<{2E}hoB(_dl__3Z~^-m*L4%)jerYjGXKdV4F<^JU@z}>E~Gijt0c{# zQqlaq`3S7Aj|OQS8t_kYOnGnU19V=;?k6n7W%-i9n$q`7_gYDhTp0d^0|Ld1pT6;K z`r_w58MqSFf0!rrkMb0QVEGbw4^jY=EO<-!fnDGtJkK@4`#BZ(S0Nbi{eVEO`;6Cx z=MiI9u8C((o^x%;Z<-94uyQFfL^%C(-nC%0MlJ(S0wsZC1O%cxP(ND6rsfzt3IvK6 zlwbvTtMVT5P7~bG82vObpE+d?D(vmG#wgdUw0La1j3(gsVF~Kij zs8%gADTRE}3PC2OJ7m37*ux(j5DciU9{%AxI*004Y|~FA@Cux8{PG{=XU7(f1>C@! zTtiSqzH%Qtyb!pN$tlVb_RGGw?)f*yDNYKBfR)dnB=Fr{k1zg+U;O2}G^t=DCgb+i z>U$0<=xPX1sbTY%4jKDa1-={G=p#ttx5u26SRW=0WLDz+_CX$Mo3735Wc-ZRN%y3y z9?oan&re}~@-zN=(IgnzIx%PwIOt3)Ms&&te6IfB$+zq+*&PpFtDnhkuRr%-yV*JEu(T>( z<$MIbojeV`eCUYz@?7>nb~S4!?h87YJyGxKhx^Bqv?;B$jSpY*{0C?1--0`W6Gz~H z@~ek!8w6|cZ)?j@di{-e;`}f2k9hZ~XD)zG@cJ_QwQLaJLuOZ$=e4zU2M$?1IkST$ z`0%2L5%k4gc;BY-8n~~VIyreRcDwW{RJ_*Id zEB7#S^K)@tx(tRBxQESCI~;iJzD(O&k%S3W64Y*`ESr~>27b1s^XDhi#F_E5_NIwM zp*`^Gg@r{DNwcO2?ltKC;fJq8f0gCbfo~K1=$=)cVU_JB@LKq|e$=fRbZ(%v^h%rF zCi-vNJtCkS@P*uD1#qj@YJXi?MCWS48F-O;>8GB0DvcsHTaBv)UZ$KXZ1zdkc4Q?{ zXx{#TvXIF`N+JLE_6(q-?PI^t5wd#)#^m}J=Hia~mu2=T$~B+<^rv}`3CjC{nfPHK z6f#*8@CL;UepJ^iZFdf$U(SygPiT*OwrXV$+JK)BdX11v0teXtL%+q7OrNf-q8wm= zF_q@&gL7q-Y-Q6mWb-02vw>#KJ`YY9WEamk|KO{^aOzOhov2??<`kKwH$hLpLFY!< z%j?Q{+N6D^2!Ax;ta^2SD>oUW>T}XppNo0ryRyDPjncD_9l0m;9Kf*EIbi%D%hQiY z5Q1!_%|e+ZV+{5I-zo6hbMk6!z@Yrx)Owr)~dl7Gb#FoO|-?=pTuH#fTpPrgx zkC-I~R(In3&7e1b>dBAATJwJQ3$b2ZPtF0zaUXfzJ+X4`DcUo^AJZCqEt3hrdtjk0 zqeZ(5^4FCs4@D9guZyd`%dxk#Am6iB^_;xx`px&EqGd0-76T-eV>~jP$zbO1kcH__ z{d;`jA7SdpLp`8-DDQpny!!&%bKWyKDZ?$F@w`W-m&B$44SMjXzt_LNF2}~^PWp%c z(?3q%fARGgYbUt*h0i|u>(aeOKN=8dK%fDE1_T-qXh7hv5d;p{+x_TA1_9noKls5^ z=s5o}-GBI@;q;ZST#g{Xv9U~#`pK%nm7_}eksU$arV1y(Wap&CNP z2_APSadi05Q16Br+awFsI#uaV=p2>^iV8&)Mj9%q?cN$D zP!Hn(neEOsjZwJ{Lw8#(ojTu{CO3{rR zs7Q!oN4|MC-MKrKt`Nw_tJ3mzHNEueQkq{XVi+fjC(aQaymx(b9|a59M~T|IJH3vw z5Q8I%$unokm(iV~_{ zLybxUoJttr4$3YwziyyxN>r&MpDS=R&=E(EE)*�##60RjRcGgMJaEe;%b5!D69$ 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%0AXTlIlYNk24m^ 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%0A8IeGy5p^< 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 {pqRAhnzRTRM`LT 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:-9@e_MX(lDpX~DJ@=1@M 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

    s9W`2HjSU2#7dF~H0|^1 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 zº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 + Takahiro Miki, Lorenz Wellhausen, Ruben Grandia, Fabian Jenelten, Timon Homberger, Marco Hutter - Elevation Mapping for Locomotion and Navigation using GPU `Link `_ +.. code-block:: + @misc{mikielevation2022, + doi = {10.48550/ARXIV.2204.12876}, + author = {Miki, Takahiro and Wellhausen, Lorenz and Grandia, Ruben and Jenelten, Fabian and Homberger, Timon and Hutter, Marco}, + keywords = {Robotics (cs.RO), FOS: Computer and information sciences, FOS: Computer and information sciences}, + title = {Elevation Mapping for Locomotion and Navigation using GPU}, + publisher = {International Conference on Intelligent Robots and Systems (IROS)}, + year = {2022}, + } +Multi-modal elevation mapping if you use color or semantic layers -.. code-block:: none +.. hint:: - @misc{https://doi.org/10.48550/arxiv.2204.12876, - doi = {10.48550/ARXIV.2204.12876}, - url = {https://arxiv.org/abs/2204.12876}, - author = {Miki, Takahiro and Wellhausen, Lorenz and Grandia, Ruben and Jenelten, Fabian and Homberger, Timon and Hutter, Marco}, - keywords = {Robotics (cs.RO), FOS: Computer and information sciences, FOS: Computer and information sciences}, - title = {Elevation Mapping for Locomotion and Navigation using GPU}, - publisher = {arXiv}, - year = {2022}, - copyright = {arXiv.org perpetual, non-exclusive license} - } + MEM: Multi-Modal Elevation Mapping for Robotics and Learning `Link `_ + + Gian Erni, Jonas Frey, Takahiro Miki, Matias Mattamala, Marco Hutter +.. code-block:: + + @misc{Erni2023-bs, + title = "{MEM}: {Multi-Modal} Elevation Mapping for Robotics and Learning", + author = "Erni, Gian and Frey, Jonas and Miki, Takahiro and Mattamala, Matias and Hutter, Marco", + publisher = {International Conference on Intelligent Robots and Systems (IROS)}, + year = {2023}, + } diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst deleted file mode 100644 index 94693b43..00000000 --- a/docs/source/getting_started/index.rst +++ /dev/null @@ -1,71 +0,0 @@ -.. _introduction: - - - -Introduction -****************************************************************** - - - -Subscribed Topics -------------------------------------------------------------------- -* topics specified in **`pointcloud_topics`** in **`elevation_mapping_cupy/config/parameters.yaml`** ([sensor_msgs/PointCloud2]) - - The distance measurements. - -* **`/tf`** ([tf/tfMessage]) - - The transformation tree. - -* The plane segmentation node subscribes to an elevation map topic ([grid_map_msg/GridMap]). This can be configured in - **`convex_plane_decomposition_ros/config/parameters.yaml`** - -Published Topics -------------------------------------------------------------------- -For elevation_mapping_cupy, topics are published as set in the rosparam. -You can specify which layers to publish in which fps. - -Under `publishers`, you can specify the `topic_name`, `layers` `basic_layers` and `fps`. - -.. code-block:: yaml - - publishers: - your_topic_name: - layers: [ 'list_of_layer_names', 'layer1', 'layer2' ] # Choose from 'elevation', 'variance', 'traversability', 'time' + plugin layers - basic_layers: [ 'list of basic layers', 'layer1' ] # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. - fps: 5.0 # Publish rate. Use smaller value than `map_acquire_fps`. - - -Example setting in `config/parameters.yaml`. - -* **`elevation_map_raw`** ([grid_map_msg/GridMap]) - - The entire elevation map. - -* **`elevation_map_recordable`** ([grid_map_msg/GridMap]) - - The entire elevation map with slower update rate for visualization and logging. - -* **`elevation_map_filter`** ([grid_map_msg/GridMap]) - - The filtered maps using plugins. - -The plane segmentation node publishes the following: - -* **`planar_terrain`** ([convex_plane_decomposition_msgs/PlanarTerrain]) - - A custom message that contains the full segmentation as a map together with the boundary information. - -* **`filtered_map`** ([grid_map_msg/GridMap]) - - A grid map message to visualize the segmentation and some intermediate results. This information is also part of **`planar_terrain`**. - -* **`boundaries`** ([visualization_msgs/MarkerArray]) - - A set of polygons that trace the boundaries of the segmented region. Holes and boundaries of a single region are published as separate - markers with the same color. - -* **`insets`** ([visualization_msgs/PolygonArray]) - - A set of polygons that are at a slight inward offset from **`boundaries`**. There might be more insets than boundaries since the inward - shift can cause a single region to break down into multiple when narrow passages exist. diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 9d65d6b7..95a99a2d 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -1,32 +1,55 @@ .. _installation: -.. toctree:: - :hidden: - :maxdepth: 2 +Installation +****************************************************************** - Cuda installation +This section provides instructions for installing the necessary dependencies for the project. The installation process includes setting up CUDA & cuDNN, installing Python dependencies, and configuring Cupy. +Follow the instructions carefully to avoid any installation issues. +Dockers +================================================================== +We provide a docker setup for the project. +To build the docker image, run the following command: -Installation -****************************************************************** -CUDA & cuDNN +.. code-block:: bash + + cd /docker + ./build.sh + + +To run the docker image, run the following command: + + +.. code-block:: bash + + cd /docker + ./run.sh + +This will start the docker container and mount the home directory of the host machine to the docker container. +After you clone the project repository into your catkin_ws, you can build the packages inside the docker container. +To build the packages inside the docker container, follow the instructions in the `Build section <#build>`_ of this document. + + +On Desktop or Laptop with NVIDIA GPU ================================================================== +CUDA & cuDNN +------------------------------------------------------------------ + +If you do not have CUDA and cuDNN installed, please install them first. The tested versions are CUDA10.2, 11.6 `CUDA `_ `cuDNN `_ -Check how to install :ref:`here`. - - +You can check how to install :ref:`here`. Python dependencies -------------------------------------------------------------------- +------------------------------------------------------------------ You will need @@ -235,4 +258,18 @@ Detectron .. code-block:: bash - python3 -m pip install 'git+https://github.com/facebookresearch/detectron2.git' \ No newline at end of file + python3 -m pip install 'git+https://github.com/facebookresearch/detectron2.git' + + +Build +================================================================== +After installing all the dependencies, you can build the packages. +Clone the project repository into your catkin_ws/src directory. +Then, build the packages with catkin. + +.. code-block:: bash + + cd + catkin build elevation_mapping_cupy # The core package + catkin build convex_plane_decomposition_ros # If you want to use plane segmentation + catkin build semantic_sensor # If you want to use semantic sensors \ No newline at end of file diff --git a/docs/source/getting_started/introduction.rst b/docs/source/getting_started/introduction.rst new file mode 100644 index 00000000..90689dfe --- /dev/null +++ b/docs/source/getting_started/introduction.rst @@ -0,0 +1,132 @@ +.. _introduction: + + + +Introduction +****************************************************************** +The Elevaton Mapping CuPy software package represents an advancement in robotic navigation and locomotion. +Integrating with the Robot Operating System (ROS) and utilizing GPU acceleration, this framework enhances point cloud registration and ray casting, +crucial for efficient and accurate robotic movement, particularly in legged robots. + +Used for Various Real-World Applications +------------------------------------------------------------------- +This software package has been rigorously tested in challenging environments, including the DARPA Subterranean Challenge, +demonstrating its effectiveness in complex, real-world scenarios. +It supports a wide range of applications, from underground exploration to advanced research in legged locomotion and autonomous navigation. + +* **DARPA Subterranean Challenge**: This package was used by Team CERBERUS in the DARPA Subterranean Challenge. + + `Team Cerberus `_ + + `CERBERUS in the DARPA Subterranean Challenge (Science Robotics) `_ + +* **ESA / ESRIC Space Resources Challenge**: This package was used for the Space Resources Challenge. + + `Scientific exploration of challenging planetary analog environments with a team of legged robots (Science Robotics) `_ + + + + +Key Features +------------------------------------------------------------------- +* **Height Drift Compensation**: Tackles state estimation drifts that can create mapping artifacts, ensuring more accurate terrain representation. + +* **Visibility Cleanup and Artifact Removal**: Raycasting methods and an exclusion zone feature are designed to remove virtual artifacts and correctly interpret overhanging obstacles, preventing misidentification as walls. + +* **Learning-based Traversability Filter**: Assesses terrain traversability using local geometry, improving path planning and navigation. + +* **Versatile Locomotion Tools**: Incorporates smoothing filters and plane segmentation, optimizing movement across various terrains. + +* **Multi-Modal Elevation Map (MEM) Framework**: Allows seamless integration of diverse data like geometry, semantics, and RGB information, enhancing multi-modal robotic perception. + +* **GPU-Enhanced Efficiency**: Facilitates rapid processing of large data structures, crucial for real-time applications. + +Overview +------------------------------------------------------------------- + +.. image:: ../../media/overview.png + :alt: Overview of multi-modal elevation map structure + +Overview of our multi-modal elevation map structure. The framework takes multi-modal images (purple) and multi-modal (blue) point clouds as +input. This data is input into the elevation map by first associating the data to the cells and then fused with different fusion algorithms into the various +layers of the map. Finally the map can be post-processed with various custom plugins to generate new layers (e.g. traversability) or process layer for +external components (e.g. line detection). + +Subscribed Topics +------------------------------------------------------------------- +The subscribed topics are specified under **subscribers** parameter. + +Example setup is in **elevation_mapping_cupy/config/core/example_setup.yaml**. + +* **/** ([sensor_msgs/PointCloud2]) + + The point cloud topic. It can have additional channels for RGB, intensity, etc. + +* **/** ([sensor_msgs/Image]) + + The image topic. It can have additional channels for RGB, semantic probabilities, image features etc. + +* **/** ([sensor_msgs/CameraInfo]) + + The camera info topic. It is used to project the point cloud into the image plane. + +* **/** ([elevation_map_msgs/ChannelInfo]) + + If this topic is configured, the node will subscribe to it and use the information to associate the image channels to the elevation map layers. + +* **/tf** ([tf/tfMessage]) + + The transformation tree. + +* The plane segmentation node subscribes to an elevation map topic ([grid_map_msg/GridMap]). This can be configured in + **convex_plane_decomposition_ros/config/core/parameters.yaml** + +Published Topics +------------------------------------------------------------------- +For elevation_mapping_cupy, topics are published as set in the rosparam. +You can specify which layers to publish in which fps. + +Under publishers, you can specify the topic_name, layers basic_layers and fps. + +.. code-block:: yaml + + publishers: + your_topic_name: + layers: [ 'list_of_layer_names', 'layer1', 'layer2' ] # Choose from 'elevation', 'variance', 'traversability', 'time' + plugin layers + basic_layers: [ 'list of basic layers', 'layer1' ] # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. + fps: 5.0 # Publish rate. Use smaller value than `map_acquire_fps`. + + +Example setting in `config/parameters.yaml`. + +* **elevation_map_raw** ([grid_map_msg/GridMap]) + + The entire elevation map. + +* **elevation_map_recordable** ([grid_map_msg/GridMap]) + + The entire elevation map with slower update rate for visualization and logging. + +* **elevation_map_filter** ([grid_map_msg/GridMap]) + + The filtered maps using plugins. + +The plane segmentation node publishes the following: + +* **planar_terrain** ([convex_plane_decomposition_msgs/PlanarTerrain]) + + A custom message that contains the full segmentation as a map together with the boundary information. + +* **filtered_map** ([grid_map_msg/GridMap]) + + A grid map message to visualize the segmentation and some intermediate results. This information is also part of **planar_terrain**. + +* **boundaries** ([visualization_msgs/MarkerArray]) + + A set of polygons that trace the boundaries of the segmented region. Holes and boundaries of a single region are published as separate + markers with the same color. + +* **insets** ([visualization_msgs/PolygonArray]) + + A set of polygons that are at a slight inward offset from **boundaries**. There might be more insets than boundaries since the inward + shift can cause a single region to break down into multiple when narrow passages exist. diff --git a/docs/source/getting_started/tutorial.rst b/docs/source/getting_started/tutorial.rst index abefdf8d..12f9eda3 100644 --- a/docs/source/getting_started/tutorial.rst +++ b/docs/source/getting_started/tutorial.rst @@ -2,35 +2,10 @@ Tutorial ****************************************************************** +This tutorial will guide you through the basic usage of the elevation mapping cupy. +You will learn how to run the plane segmentation node, the sensor node, and the TurtleBot example. - - -Build -================================================================== - -.. code-block:: bash - - catkin build elevation_mapping_cupy - catkin build convex_plane_decomposition_ros - - -Errors -""""""""""""" - -If you get error such as - -.. code-block:: none - - Make Error at /usr/share/cmake-3.16/Modules/FindPackageHandleStandardArgs.cmake:146 (message): - Could NOT find PythonInterp: Found unsuitable version "2.7.18", but - required is at least "3" (found /usr/bin/python) - - -Build with option. - -.. code-block:: bash - - catkin build elevation_mapping_cupy -DPYTHON_EXECUTABLE=$(which python3) +If you want to use your own custom plugins, please refer to the :ref:`plugins`. Run @@ -53,27 +28,8 @@ For the sensor node .. code-block:: bash - roslaunch elevation_mapping_cupy pointlcoud.launch - roslaunch elevation_mapping_cupy image.launch - - -Errors -""""""""""""" - -If you build with the install flag under ros melodic, you might get issues with the modules not found: - -.. code-block:: bash - - terminate called after throwing an instance of 'pybind11::error_already_set' - what(): ModuleNotFoundError: No module named 'elevation_mapping_cupy' - -This is because python3 modules are installed into a different location. - -This can be fixed by including also the python3 modules location in the `PYTHONPATH` by adding following line into the launch file: - -.. code-block:: xml - - + roslaunch semantic_sensor semantic_pointcloud.launch + roslaunch semantic_sensor semantic_image.launch Run TurtleBot example @@ -91,7 +47,7 @@ Then, you can run the examples. For the basic version: .. code-block:: bash export TURTLEBOT3_MODEL=waffle - roslaunch elevation_mapping_cupy turtlesim_example.launch + roslaunch elevation_mapping_cupy turtlesim_simple_example.launch For fusing semantics into the map such as rgb from a multi modal pointcloud: @@ -102,33 +58,22 @@ For fusing semantics into the map such as rgb from a multi modal pointcloud: .. code-block:: bash export TURTLEBOT3_MODEL=waffle - roslaunch elevation_mapping_cupy turtlesim_semantic_example.launch + roslaunch elevation_mapping_cupy turtlesim_semantic_pointcloud_example.launch -For fusing semantics into the map such as rgb from an image: +For fusing semantics into the map such as rgb semantics or features from an image: .. code-block:: bash export TURTLEBOT3_MODEL=waffle roslaunch elevation_mapping_cupy turtlesim_semantic_image_example.launch -For fusing features extracted with a feature extractor from an image: - -.. code-block:: bash - - export TURTLEBOT3_MODEL=waffle - roslaunch elevation_mapping_cupy turtlesim_features_image_example.launch - - Or, for the version including plane segmentation: - - .. code-block:: bash catkin build convex_plane_decomposition_ros export TURTLEBOT3_MODEL=waffle - roslaunch elevation_mapping_cupy turtlesim_segmentation_example.launch - + roslaunch elevation_mapping_cupy turtlesim_plane_decomposition_example.launch To control the robot with a keyboard, a new terminal window needs to be opened. @@ -143,3 +88,40 @@ Then run Velocity inputs can be sent to the robot by pressing the keys `a`, `w`, `d`, `x`. To stop the robot completely, press `s`. + + +Errors +================================================================== + +If you build with the install flag under ros melodic, you might get issues with the modules not found: + +.. code-block:: bash + + terminate called after throwing an instance of 'pybind11::error_already_set' + what(): ModuleNotFoundError: No module named 'elevation_mapping_cupy' + +This is because python3 modules are installed into a different location. + +This can be fixed by including also the python3 modules location in the `PYTHONPATH` by adding following line into the launch file: + +.. code-block:: xml + + + +If you get error such as + +.. code-block:: none + + Make Error at /usr/share/cmake-3.16/Modules/FindPackageHandleStandardArgs.cmake:146 (message): + Could NOT find PythonInterp: Found unsuitable version "2.7.18", but + required is at least "3" (found /usr/bin/python) + + +Build with option. + +.. code-block:: bash + + catkin build elevation_mapping_cupy -DPYTHON_EXECUTABLE=$(which python3) + + + diff --git a/docs/source/index.rst b/docs/source/index.rst index 808139c6..d6566c77 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -10,7 +10,7 @@ :maxdepth: 3 :caption: Getting Started - Introduction + Introduction Installation Tutorial diff --git a/docs/source/usage/parameters.rst b/docs/source/usage/parameters.rst index 57836bb7..0594a0f4 100644 --- a/docs/source/usage/parameters.rst +++ b/docs/source/usage/parameters.rst @@ -5,18 +5,20 @@ Parameters There are three parameter files: -1. `Parameters`_ +#. `Robot Setup Configurations`_ -2. `Plugin configurations`_ +#. `Plugin configurations`_ -3. `Sensor parameter`_ +#. `Core Parameters`_ +#. `Sensor parameter`_ -Parameters +Robot Setup Configurations ================================================ +Such as Publishers and subscribers -.. include:: ../../../elevation_mapping_cupy/config/parameters.yaml +.. include:: ../../../elevation_mapping_cupy/config/core/example_setup.yaml :code: yaml Plugin configurations @@ -24,17 +26,21 @@ Plugin configurations More informations on the plugins can be found in :ref:`plugins`. -.. include:: ../../../elevation_mapping_cupy/config/plugin_config.yaml +.. include:: ../../../elevation_mapping_cupy/config/core/plugin_config.yaml :code: yaml +Core Parameters +============================================================== +.. include:: ../../../elevation_mapping_cupy/config/core/core_param.yaml + :code: yaml Sensor parameter ================================================ More informations on the sensor configurations can be found in :ref:`semantics`. -.. include:: ../../../elevation_mapping_cupy/config/sensor_parameter.yaml +.. include:: ../../../sensor_processing/semantic_sensor/config/sensor_parameter.yaml :code: yaml diff --git a/docs/source/usage/plugins.rst b/docs/source/usage/plugins.rst index 410ad623..4a3f6d9b 100644 --- a/docs/source/usage/plugins.rst +++ b/docs/source/usage/plugins.rst @@ -3,47 +3,13 @@ Plugins ****************************************************************** -This page is structured in two parts: +You can add your own plugin to process the elevation map and publish as a layer in GridMap message. -* `Existing plugins`_ +This page is structured in two parts: * `Create a plugin`_ -Existing plugins -================================================================== - -1. Min filter -------------------------------------------------------------------- -.. automodule:: elevation_mapping_cupy.plugins.min_filter - :members: - -2. Inpainting -------------------------------------------------------------------- - -.. automodule:: elevation_mapping_cupy.plugins.inpainting - :members: - -3. Smooth Filter -------------------------------------------------------------------- -.. automodule:: elevation_mapping_cupy.plugins.smooth_filter - :members: - -4. Robot centric elevation -------------------------------------------------------------------- -.. automodule:: elevation_mapping_cupy.plugins.robot_centric_elevation - :members: - -5. Semantic Filter -------------------------------------------------------------------- -.. automodule:: elevation_mapping_cupy.plugins.semantic_filter - :members: - -6. Semantic traversability -------------------------------------------------------------------- -.. automodule:: elevation_mapping_cupy.plugins.semantic_traversability - :members: - - +* `Existing plugins`_ Create a plugin @@ -66,8 +32,15 @@ First, create your plugin file in `elevation_mapping_cupy/script/plugins/` and s super().__init__() self.add_value = float(add_value) - def __call__(self, elevation_map: cp.ndarray, layer_names: List[str], - plugin_layers: cp.ndarray, plugin_layer_names: List[str])->cp.ndarray: + def __call__(self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_layers: cp.ndarray, + semantic_layer_names: List[str], + *args + )->cp.ndarray: # Process maps here # You can also use the other plugin's data through plugin_layers. new_elevation = elevation_map[0] + self.add_value @@ -96,7 +69,7 @@ Then, add your plugin setting to `config/plugin_config.yaml` add_value: 100.0 # Example param with larger value. -Finally, add your layer name to publishers in `config/parameters.yaml`. You can create a new topic or add to existing topics. +Finally, add your layer name to publishers in your config. You can create a new topic or add to existing topics. .. code-block:: yaml @@ -108,3 +81,47 @@ Finally, add your layer name to publishers in `config/parameters.yaml`. You can + +Existing plugins +================================================================== + +This section lists the plugins that are already installed and available for use. + + + + +1. Min filter +------------------------------------------------------------------- +.. automodule:: elevation_mapping_cupy.plugins.min_filter + :members: + +2. Inpainting +------------------------------------------------------------------- + +.. automodule:: elevation_mapping_cupy.plugins.inpainting + :members: + +3. Smooth Filter +------------------------------------------------------------------- +.. automodule:: elevation_mapping_cupy.plugins.smooth_filter + :members: + +4. Robot centric elevation +------------------------------------------------------------------- +.. automodule:: elevation_mapping_cupy.plugins.robot_centric_elevation + :members: + +5. Semantic Filter +------------------------------------------------------------------- +.. automodule:: elevation_mapping_cupy.plugins.semantic_filter + :members: + +6. Semantic traversability +------------------------------------------------------------------- +.. automodule:: elevation_mapping_cupy.plugins.semantic_traversability + :members: + +7. Features PCA +------------------------------------------------------------------- +.. automodule:: elevation_mapping_cupy.plugins.features_pca + :members: \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/config/sensor_parameter.yaml b/sensor_processing/semantic_sensor/config/sensor_parameter.yaml index c497564c..81fde9b1 100644 --- a/sensor_processing/semantic_sensor/config/sensor_parameter.yaml +++ b/sensor_processing/semantic_sensor/config/sensor_parameter.yaml @@ -1,33 +1,3 @@ -# subscribers: -# # sensor_name: -# # channels: ['feat_0','feat_1'] -# # fusion: ['average','average'] -# # topic_name: '/elevation_mapping/pointcloud_semantic' -# front_cam: -# channels: [ 'rgb' ] #'feat_0','feat_1','person','grass'] -# fusion: [ 'color' ] #'average','average','class_average','class_average'] -# topic_name: '/elvation_mapping/pointcloud_semantic' -# semantic_segmentation: False -# segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' -# publish_segmentation_image: True -# feature_extractor: False -# feature_config: -# name: 'DINO' -# interpolation: 'bilinear' -# model: "vit_small" -# patch_size: 16 -# dim: 5 -# dropout: False -# dino_feat_type: "feat" -# input_size: [ 80, 160 ] -# projection_type: "nonlinear" - -# cam_info_topic: "/zed2i/zed_node/depth/camera_info" -# image_topic: "/zed2i/zed_node/left/image_rect_color" -# depth_topic: "/zed2i/zed_node/depth/depth_registered" -# cam_frame: "zed2i_right_camera_optical_frame" -# confidence_topic: "/zed2i/zed_node/confidence/confidence_map" -# confidence_threshold: 10 front_cam_pointcloud: channels: ['rgb', 'chair','sofa',"person" ] fusion: ['color','class_average','class_average','class_average'] From c11991839121a92c67f13d91d512d53bb41298da Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 11:17:01 +0100 Subject: [PATCH 383/504] Modified the readme. --- README.md | 144 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 113 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 3b86f5dd..07a4c7b5 100644 --- a/README.md +++ b/README.md @@ -2,58 +2,140 @@ ![python tests](https://github.com/leggedrobotics/elevation_mapping_semantic_cupy/actions/workflows/python-tests.yml/badge.svg) +[Documentation](https://leggedrobotics.github.io/elevation_mapping_cupy/) + + +## Overview + +The Elevaton Mapping CuPy software package represents an advancement in robotic navigation and locomotion. +Integrating with the Robot Operating System (ROS) and utilizing GPU acceleration, this framework enhances point cloud registration and ray casting, +crucial for efficient and accurate robotic movement, particularly in legged robots. +![screenshot](doc/media/main_repo.png) +![screenshot](doc/media/main_mem.png) +![gif](doc/media/convex_approximation.gif) + +## Key Features + +- **Height Drift Compensation**: Tackles state estimation drifts that can create mapping artifacts, ensuring more accurate terrain representation. + +- **Visibility Cleanup and Artifact Removal**: Raycasting methods and an exclusion zone feature are designed to remove virtual artifacts and correctly interpret overhanging obstacles, preventing misidentification as walls. + +- **Learning-based Traversability Filter**: Assesses terrain traversability using local geometry, improving path planning and navigation. + +- **Versatile Locomotion Tools**: Incorporates smoothing filters and plane segmentation, optimizing movement across various terrains. + +- **Multi-Modal Elevation Map (MEM) Framework**: Allows seamless integration of diverse data like geometry, semantics, and RGB information, enhancing multi-modal robotic perception. + +- **GPU-Enhanced Efficiency**: Facilitates rapid processing of large data structures, crucial for real-time applications. + ## Overview -This is a ROS package for elevation mapping on GPU. The elevation mapping code is written in python and uses cupy for -GPU computation. The -plane segmentation is done independently and runs on CPU. When the plane segmentation is generated, local convex -approximations of the -terrain can be efficiently generated. -![screenshot](doc/main_repo.png) -![gif](doc/convex_approximation.gif) +![Overview of multi-modal elevation map structure](doc/media/overview.png) + +Overview of our multi-modal elevation map structure. The framework takes multi-modal images (purple) and multi-modal (blue) point clouds as +input. This data is input into the elevation map by first associating the data to the cells and then fused with different fusion algorithms into the various +layers of the map. Finally the map can be post-processed with various custom plugins to generate new layers (e.g. traversability) or process layer for +external components (e.g. line detection). ## Citing +If you use the Elevation Mapping CuPy, please cite the following paper: +Elevation Mapping for Locomotion and Navigation using GPU + +[Elevation Mapping for Locomotion and Navigation using GPU](https://arxiv.org/abs/2204.12876) -> Takahiro Miki, Lorenz Wellhausen, Ruben Grandia, Fabian Jenelten, Timon Homberger, Marco Hutter -> Elevation Mapping for Locomotion and Navigation using GPU [arXiv](https://arxiv.org/abs/2204.12876) +Takahiro Miki, Lorenz Wellhausen, Ruben Grandia, Fabian Jenelten, Timon Homberger, Marco Hutter +```bibtex +@misc{mikielevation2022, + doi = {10.48550/ARXIV.2204.12876}, + author = {Miki, Takahiro and Wellhausen, Lorenz and Grandia, Ruben and Jenelten, Fabian and Homberger, Timon and Hutter, Marco}, + keywords = {Robotics (cs.RO), FOS: Computer and information sciences, FOS: Computer and information sciences}, + title = {Elevation Mapping for Locomotion and Navigation using GPU}, + publisher = {International Conference on Intelligent Robots and Systems (IROS)}, + year = {2022}, +} ``` -@misc{https://doi.org/10.48550/arxiv.2204.12876, - doi = {10.48550/ARXIV.2204.12876}, - url = {https://arxiv.org/abs/2204.12876}, - author = {Miki, Takahiro and Wellhausen, Lorenz and Grandia, Ruben and Jenelten, Fabian and Homberger, Timon and Hutter, Marco}, - keywords = {Robotics (cs.RO), FOS: Computer and information sciences, FOS: Computer and information sciences}, - title = {Elevation Mapping for Locomotion and Navigation using GPU}, - publisher = {arXiv}, - year = {2022}, - copyright = {arXiv.org perpetual, non-exclusive license} + +If you use the Multi-modal Elevation Mapping for color or semantic layers, please cite the following paper: + +[MEM: Multi-Modal Elevation Mapping for Robotics and Learning](https://arxiv.org/abs/2309.16818v1) + +Gian Erni, Jonas Frey, Takahiro Miki, Matias Mattamala, Marco Hutter + +```bibtex +@misc{Erni2023-bs, + title = "{MEM}: {Multi-Modal} Elevation Mapping for Robotics and Learning", + author = "Erni, Gian and Frey, Jonas and Miki, Takahiro and Mattamala, Matias and Hutter, Marco", + publisher = {International Conference on Intelligent Robots and Systems (IROS)}, + year = {2023}, } ``` ## Quick instructions to run: -For the lonomy bag: +### Installation -CPP wrapper: +First, clone to your catkin_ws ```zsh - roslaunch elevation_mapping_cupy lonomy_semantic_elevation_single.launch use_sim_true:=true - rosbag play --clock ~/bags/good_working_wine_field_zed_topcom_rtk_person_9_2022-07-15-14-37-05.bag +mkdir -p catkin_ws/src +cd catkin_ws/src +git clone https://github.com/leggedrobotics/elevation_mapping_cupy.git ``` -Python wrapper: +Then install dependencies. +You can also use docker which already install all dependencies. -````zsh - python -m elevation_mapping_cupy.elevation_mapping_ros - roslaunch elevation_mapping_cupy pointcloud.launch use_sim_time:=true - rosbag play --clock ~/bags/good_working_wine_field_zed_topcom_rtk_person_9_2022-07-15-14-37-05.bag -```` +```zsh +cd docker +./build.sh +./run.sh +``` -For the anymal bag: +### Build package +Inside docker container. ```zsh - roslaunch elevation_mapping_cupy anymal_semantic_elevation_single.launch use_sim_time:=true - rosbag play --clock ~/bags/anymal_coyote_2022-12-11-20-01-46.bag +cd $HOME/catkin_ws +catkin build elevation_mapping_cupy +``` + +### Run turtlebot example. +![Elevation map examples](doc/media/turtlebot.png) + +```bash +export TURTLEBOT3_MODEL=waffle +roslaunch elevation_mapping_cupy turtlesim_simple_example.launch +``` + +For fusing semantics into the map such as rgb from a multi modal pointcloud: + +```bash +export TURTLEBOT3_MODEL=waffle +roslaunch elevation_mapping_cupy turtlesim_semantic_pointcloud_example.launch ``` +For fusing semantics into the map such as rgb semantics or features from an image: + +```bash +export TURTLEBOT3_MODEL=waffle +roslaunch elevation_mapping_cupy turtlesim_semantic_image_example.launch +``` + +For plane segmentation: + +```bash +catkin build convex_plane_decomposition_ros +export TURTLEBOT3_MODEL=waffle +roslaunch elevation_mapping_cupy turtlesim_plane_decomposition_example.launch +``` + +To control the robot with a keyboard, a new terminal window needs to be opened. +Then run + +```bash +export TURTLEBOT3_MODEL=waffle +roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch +``` +Velocity inputs can be sent to the robot by pressing the keys `a`, `w`, `d`, `x`. To stop the robot completely, press `s`. From 9742a25b94c30a954c3cd0bcd0dbc17f32a340af Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 12:19:08 +0100 Subject: [PATCH 384/504] Applied black formatting. --- .../elevation_mapping.py | 50 ++++----------- .../fusion/image_color.py | 4 +- .../fusion/image_exponential.py | 5 +- .../fusion/pointcloud_average.py | 18 ++---- .../fusion/pointcloud_bayesian_inference.py | 25 ++------ .../fusion/pointcloud_class_average.py | 24 ++----- .../fusion/pointcloud_class_bayesian.py | 10 +-- .../fusion/pointcloud_class_max.py | 20 ++---- .../fusion/pointcloud_color.py | 16 ++--- .../kernels/custom_kernels.py | 2 +- .../kernels/custom_semantic_kernels.py | 36 +++-------- .../elevation_mapping_cupy/parameter.py | 21 ++++--- .../plugins/features_pca.py | 12 ++-- .../plugins/inpainting.py | 5 +- .../plugins/min_filter.py | 1 + .../plugins/plugin_manager.py | 15 +---- .../plugins/robot_centric_elevation.py | 7 +-- .../plugins/semantic_filter.py | 16 ++--- .../plugins/semantic_traversability.py | 5 +- .../plugins/smooth_filter.py | 10 +-- .../elevation_mapping_cupy/semantic_map.py | 52 +++++++-------- .../tests/test_plugins.py | 4 +- .../tests/test_semantic_kernels.py | 63 ++++--------------- .../tests/test_semantic_map.py | 41 +++--------- elevation_mapping_cupy/setup.py | 6 +- .../DINO/vision_transformer.py | 45 +++---------- .../script/semantic_sensor/image_node.py | 12 +++- .../semantic_sensor/image_parameters.py | 2 +- .../script/semantic_sensor/networks.py | 30 ++++----- .../script/semantic_sensor/pointcloud_node.py | 18 +----- .../semantic_sensor/pointcloud_parameters.py | 8 +-- .../semantic_sensor/tests/test_pointcloud.py | 42 ++----------- .../semantic_sensor/tests/test_utils.py | 5 +- sensor_processing/semantic_sensor/setup.py | 9 +-- 34 files changed, 166 insertions(+), 473 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 42c81c04..0ff32d9a 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -228,10 +228,7 @@ def shift_map_z(self, delta_z): def compile_kernels(self): """Compile all kernels belonging to the elevation map.""" - self.new_map = cp.zeros( - (self.elevation_map.shape[0], self.cell_n, self.cell_n), - dtype=self.data_type, - ) + self.new_map = cp.zeros((self.elevation_map.shape[0], self.cell_n, self.cell_n), dtype=self.data_type,) self.traversability_input = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) self.traversability_mask_dummy = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) self.min_filtered = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) @@ -290,18 +287,14 @@ def compile_image_kernels(self): np.zeros((self.cell_n, self.cell_n), dtype=np.bool_), dtype=np.bool_ ) self.uv_correspondence = cp.asarray( - np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), - dtype=np.float32, + np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32, ) # self.distance_correspondence = cp.asarray( # np.zeros((self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32 # ) # TODO tolerance_z_collision add parameter self.image_to_map_correspondence_kernel = image_to_map_correspondence_kernel( - resolution=self.resolution, - width=self.cell_n, - height=self.cell_n, - tolerance_z_collision=0.10, + resolution=self.resolution, width=self.cell_n, height=self.cell_n, tolerance_z_collision=0.10, ) break @@ -529,12 +522,7 @@ def input_image( size=int(self.cell_n * self.cell_n), ) self.semantic_map.update_layers_image( - image, - channels, - self.uv_correspondence, - self.valid_correspondence, - image_height, - image_width, + image, channels, self.uv_correspondence, self.valid_correspondence, image_height, image_width, ) def update_normal(self, dilated_map): @@ -546,10 +534,7 @@ def update_normal(self, dilated_map): with self.map_lock: self.normal_map *= 0.0 self.normal_filter_kernel( - dilated_map, - self.elevation_map[2], - self.normal_map, - size=(self.cell_n * self.cell_n), + dilated_map, self.elevation_map[2], self.normal_map, size=(self.cell_n * self.cell_n), ) def process_map_for_publish(self, input_map, fill_nan=False, add_z=False, xp=cp): @@ -595,9 +580,7 @@ def get_traversability(self): traversability layer """ traversability = cp.where( - (self.elevation_map[2] + self.elevation_map[6]) > 0.5, - self.elevation_map[3].copy(), - cp.nan, + (self.elevation_map[2] + self.elevation_map[6]) > 0.5, self.elevation_map[3].copy(), cp.nan, ) self.traversability_buffer[3:-3, 3:-3] = traversability[3:-3, 3:-3] traversability = self.traversability_buffer[1:-1, 1:-1] @@ -619,8 +602,7 @@ def get_upper_bound(self): """ if self.param.use_only_above_for_upper_bound: valid = cp.logical_or( - cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), - self.elevation_map[2] > 0.5, + cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), self.elevation_map[2] > 0.5, ) else: valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) @@ -636,8 +618,7 @@ def get_is_upper_bound(self): """ if self.param.use_only_above_for_upper_bound: valid = cp.logical_or( - cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), - self.elevation_map[2] > 0.5, + cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), self.elevation_map[2] > 0.5, ) else: valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) @@ -798,11 +779,7 @@ def get_layer(self, name): return_map = self.semantic_map.semantic_map[idx] elif name in self.plugin_manager.layer_names: self.plugin_manager.update_with_name( - name, - self.elevation_map, - self.layer_names, - self.semantic_map, - self.base_rotation, + name, self.elevation_map, self.layer_names, self.semantic_map, self.base_rotation, ) return_map = self.plugin_manager.get_map_with_name(name) else: @@ -848,10 +825,7 @@ def get_polygon_traversability(self, polygon, result): else: t = cp.asarray(0.0, dtype=self.data_type) is_safe, un_polygon = is_traversable( - masked, - self.param.safe_thresh, - self.param.safe_min_thresh, - self.param.max_unsafe_n, + masked, self.param.safe_thresh, self.param.safe_min_thresh, self.param.max_unsafe_n, ) untraversable_polygon_num = 0 if un_polygon is not None: @@ -907,9 +881,7 @@ def initialize_map(self, points, method="cubic"): t = xp.random.rand(3) print(R, t) param = Parameter( - use_chainer=False, - weight_file="../config/weights.dat", - plugin_config_file="../config/plugin_config.yaml", + use_chainer=False, weight_file="../config/weights.dat", plugin_config_file="../config/plugin_config.yaml", ) param.additional_layers = ["rgb", "grass", "tree", "people"] param.fusion_algorithms = ["color", "class_bayesian", "class_bayesian", "class_bayesian"] diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py index 8eea8eb2..e4026a13 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py @@ -53,9 +53,7 @@ def __init__(self, params, *args, **kwargs): self.resolution = params.resolution self.color_correspondences_to_map_kernel = color_correspondences_to_map_kernel( - resolution=self.resolution, - width=self.cell_n, - height=self.cell_n, + resolution=self.resolution, width=self.cell_n, height=self.cell_n, ) def __call__( diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py index 480b943d..48fa11f8 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py @@ -44,10 +44,7 @@ def __init__(self, params, *args, **kwargs): self.resolution = params.resolution self.exponential_correspondences_to_map_kernel = exponential_correspondences_to_map_kernel( - resolution=self.resolution, - width=self.cell_n, - height=self.cell_n, - alpha=0.7, + resolution=self.resolution, width=self.cell_n, height=self.cell_n, alpha=0.7, ) def __call__( diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py index a823b258..c4165a54 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py @@ -6,9 +6,7 @@ def sum_kernel( - resolution, - width, - height, + resolution, width, height, ): """Sums the semantic values of the classes for the exponentiala verage or for the average. @@ -53,8 +51,7 @@ def sum_kernel( def average_kernel( - width, - height, + width, height, ): average_kernel = cp.ElementwiseKernel( in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", @@ -90,15 +87,8 @@ def __init__(self, params, *args, **kwargs): self.name = "pointcloud_average" self.cell_n = params.cell_n self.resolution = params.resolution - self.sum_kernel = sum_kernel( - self.resolution, - self.cell_n, - self.cell_n, - ) - self.average_kernel = average_kernel( - self.cell_n, - self.cell_n, - ) + self.sum_kernel = sum_kernel(self.resolution, self.cell_n, self.cell_n,) + self.average_kernel = average_kernel(self.cell_n, self.cell_n,) def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): self.sum_kernel( diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py index c8da65d9..96f1d1e2 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py @@ -6,9 +6,7 @@ def sum_compact_kernel( - resolution, - width, - height, + resolution, width, height, ): # input the list of layers, amount of channels can slo be input through kernel sum_compact_kernel = cp.ElementwiseKernel( @@ -43,8 +41,7 @@ def sum_compact_kernel( def bayesian_inference_kernel( - width, - height, + width, height, ): bayesian_inference_kernel = cp.ElementwiseKernel( in_params=" raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", @@ -91,23 +88,11 @@ def __init__(self, params, *args, **kwargs): self.data_type = params.data_type self.sum_mean = cp.ones( - ( - self.fusion_algorithms.count("bayesian_inference"), - self.cell_n, - self.cell_n, - ), - self.data_type, + (self.fusion_algorithms.count("bayesian_inference"), self.cell_n, self.cell_n,), self.data_type, ) # TODO initialize the variance with a value different than 0 - self.sum_compact_kernel = sum_compact_kernel( - self.resolution, - self.cell_n, - self.cell_n, - ) - self.bayesian_inference_kernel = bayesian_inference_kernel( - self.cell_n, - self.cell_n, - ) + self.sum_compact_kernel = sum_compact_kernel(self.resolution, self.cell_n, self.cell_n,) + self.bayesian_inference_kernel = bayesian_inference_kernel(self.cell_n, self.cell_n,) def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): self.sum_mean *= 0 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py index b8ad5cb8..8fa94c13 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py @@ -6,9 +6,7 @@ def sum_kernel( - resolution, - width, - height, + resolution, width, height, ): """Sums the semantic values of the classes for the exponentiala verage or for the average. @@ -53,9 +51,7 @@ def sum_kernel( def class_average_kernel( - width, - height, - alpha, + width, height, alpha, ): class_average_kernel = cp.ElementwiseKernel( in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", @@ -85,9 +81,7 @@ def class_average_kernel( } } """ - ).substitute( - alpha=alpha, - ), + ).substitute(alpha=alpha,), name="class_average_kernel", ) return class_average_kernel @@ -102,16 +96,8 @@ def __init__(self, params, *args, **kwargs): self.resolution = params.resolution self.average_weight = params.average_weight - self.sum_kernel = sum_kernel( - self.resolution, - self.cell_n, - self.cell_n, - ) - self.class_average_kernel = class_average_kernel( - self.cell_n, - self.cell_n, - self.average_weight, - ) + self.sum_kernel = sum_kernel(self.resolution, self.cell_n, self.cell_n,) + self.class_average_kernel = class_average_kernel(self.cell_n, self.cell_n, self.average_weight,) def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): self.sum_kernel( diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py index 6e507194..22869d22 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py @@ -6,9 +6,7 @@ def alpha_kernel( - resolution, - width, - height, + resolution, width, height, ): # input the list of layers, amount of channels can slo be input through kernel alpha_kernel = cp.ElementwiseKernel( @@ -55,11 +53,7 @@ def __init__(self, params, *args, **kwargs): self.name = "pointcloud_class_bayesian" self.cell_n = params.cell_n self.resolution = params.resolution - self.alpha_kernel = alpha_kernel( - self.resolution, - self.cell_n, - self.cell_n, - ) + self.alpha_kernel = alpha_kernel(self.resolution, self.cell_n, self.cell_n,) def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): self.alpha_kernel( diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py index 630c2ae6..728e42fb 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py @@ -6,9 +6,7 @@ def sum_max_kernel( - resolution, - width, - height, + resolution, width, height, ): # input the list of layers, amount of channels can slo be input through kernel sum_max_kernel = cp.ElementwiseKernel( @@ -53,11 +51,7 @@ def __init__(self, params, *args, **kwargs): self.resolution = params.resolution self.fusion_algorithms = params.fusion_algorithms - self.sum_max_kernel = sum_max_kernel( - self.resolution, - self.cell_n, - self.cell_n, - ) + self.sum_max_kernel = sum_max_kernel(self.resolution, self.cell_n, self.cell_n,) layer_cnt = self.fusion_algorithms.count("class_max") self.unique_id = cp.array([0]) @@ -88,10 +82,7 @@ def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic # get all unique ids, where index is the position in the prob_sum and the value in the NN class self.unique_id = cp.unique(cp.concatenate((unique_idm, unique_ida))) # contains the sum of the new measurement probabilities - self.prob_sum = cp.zeros( - (len(self.unique_id), self.cell_n, self.cell_n), - dtype=np.float32, - ) + self.prob_sum = cp.zeros((len(self.unique_id), self.cell_n, self.cell_n), dtype=np.float32,) # transform the index matrix of the classes to the index matrix of the prob_sum pt_id_zero = pt_id.copy() for it, val in enumerate(self.unique_id): @@ -104,10 +95,7 @@ def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic pt_id_zero, pcl_ids, layer_ids, - cp.array( - [points_all.shape[1], pcl_ids.shape[0], pt_id.shape[1]], - dtype=cp.int32, - ), + cp.array([points_all.shape[1], pcl_ids.shape[0], pt_id.shape[1]], dtype=cp.int32,), self.prob_sum, size=(points_all.shape[0]), ) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py index 9b7c1b34..801abd95 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py @@ -6,8 +6,7 @@ def add_color_kernel( - width, - height, + width, height, ): add_color_kernel = cp.ElementwiseKernel( in_params="raw T p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", @@ -57,8 +56,7 @@ def add_color_kernel( def color_average_kernel( - width, - height, + width, height, ): color_average_kernel = cp.ElementwiseKernel( in_params="raw V color_map, raw W pcl_chan, raw W map_lay, raw W pcl_channels", @@ -123,17 +121,11 @@ def __init__(self, params, *args, **kwargs): self.cell_n = params.cell_n self.resolution = params.resolution - self.add_color_kernel = add_color_kernel( - params.cell_n, - params.cell_n, - ) + self.add_color_kernel = add_color_kernel(params.cell_n, params.cell_n,) self.color_average_kernel = color_average_kernel(self.cell_n, self.cell_n) def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): - self.color_map = cp.zeros( - (1 + 3 * layer_ids.shape[0], self.cell_n, self.cell_n), - dtype=cp.uint32, - ) + self.color_map = cp.zeros((1 + 3 * layer_ids.shape[0], self.cell_n, self.cell_n), dtype=cp.uint32,) points_all = points_all.astype(cp.float32) self.add_color_kernel( diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py index af874e6a..d7025270 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py @@ -265,7 +265,7 @@ def add_points_kernel( mahalanobis_thresh=mahalanobis_thresh, outlier_variance=outlier_variance, wall_num_thresh=wall_num_thresh, - ray_step=resolution / 2**0.5, + ray_step=resolution / 2 ** 0.5, max_ray_length=max_ray_length, cleanup_step=cleanup_step, cleanup_cos_thresh=cleanup_cos_thresh, diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py index 38910c53..43980321 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py @@ -3,9 +3,7 @@ def sum_kernel( - resolution, - width, - height, + resolution, width, height, ): """Sums the semantic values of the classes for the exponentiala verage or for the average. @@ -50,9 +48,7 @@ def sum_kernel( def sum_compact_kernel( - resolution, - width, - height, + resolution, width, height, ): # input the list of layers, amount of channels can slo be input through kernel sum_compact_kernel = cp.ElementwiseKernel( @@ -87,9 +83,7 @@ def sum_compact_kernel( def sum_max_kernel( - resolution, - width, - height, + resolution, width, height, ): # input the list of layers, amount of channels can slo be input through kernel sum_max_kernel = cp.ElementwiseKernel( @@ -126,9 +120,7 @@ def sum_max_kernel( def alpha_kernel( - resolution, - width, - height, + resolution, width, height, ): # input the list of layers, amount of channels can slo be input through kernel alpha_kernel = cp.ElementwiseKernel( @@ -169,8 +161,7 @@ def alpha_kernel( def average_kernel( - width, - height, + width, height, ): average_kernel = cp.ElementwiseKernel( in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", @@ -200,8 +191,7 @@ def average_kernel( def bayesian_inference_kernel( - width, - height, + width, height, ): bayesian_inference_kernel = cp.ElementwiseKernel( in_params=" raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", @@ -237,9 +227,7 @@ def bayesian_inference_kernel( def class_average_kernel( - width, - height, - alpha, + width, height, alpha, ): class_average_kernel = cp.ElementwiseKernel( in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", @@ -269,17 +257,14 @@ def class_average_kernel( } } """ - ).substitute( - alpha=alpha, - ), + ).substitute(alpha=alpha,), name="class_average_kernel", ) return class_average_kernel def add_color_kernel( - width, - height, + width, height, ): add_color_kernel = cp.ElementwiseKernel( in_params="raw T p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", @@ -329,8 +314,7 @@ def add_color_kernel( def color_average_kernel( - width, - height, + width, height, ): color_average_kernel = cp.ElementwiseKernel( in_params="raw V color_map, raw W pcl_chan, raw W map_lay, raw W pcl_channels", diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 88b111ed..e92d0d99 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -23,15 +23,18 @@ class Parameter(Serializable): } ) additional_layers: list = field(default_factory=lambda: ["color"]) - fusion_algorithms: list = field(default_factory=lambda: [ - "image_color", - "image_exponential", - "pointcloud_average", - "pointcloud_bayesian_inference", - "pointcloud_class_average", - "pointcloud_class_bayesian", - "pointcloud_class_max", - "pointcloud_color"]) + fusion_algorithms: list = field( + default_factory=lambda: [ + "image_color", + "image_exponential", + "pointcloud_average", + "pointcloud_bayesian_inference", + "pointcloud_class_average", + "pointcloud_class_bayesian", + "pointcloud_class_max", + "pointcloud_color", + ] + ) pointcloud_channel_fusions: dict = field(default_factory=lambda: {"rgb": "color", "default": "class_average"}) image_channel_fusions: dict = field(default_factory=lambda: {"rgb": "color", "default": "exponential"}) data_type: str = np.float32 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py index 8ea2d54a..94f88823 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py @@ -19,11 +19,9 @@ class FeaturesPca(PluginBase): classes (ruamel.yaml.comments.CommentedSeq): **kwargs (): """ + def __init__( - self, - cell_n: int = 100, - process_layer_names: List[str]=[], - **kwargs, + self, cell_n: int = 100, process_layer_names: List[str] = [], **kwargs, ): super().__init__() self.process_layer_names = process_layer_names @@ -40,7 +38,6 @@ def get_layer_indices(self, layer_names: List[str]) -> List[int]: if any(re.match(pattern, layer_name) for pattern in self.process_layer_names): indices.append(i) return indices - def __call__( self, @@ -67,8 +64,9 @@ def __call__( """ # get indices of all layers that contain semantic features information data = [] - for m, layer_names in zip([elevation_map, plugin_layers, semantic_map], - [layer_names, plugin_layer_names, semantic_layer_names]): + for m, layer_names in zip( + [elevation_map, plugin_layers, semantic_map], [layer_names, plugin_layer_names, semantic_layer_names] + ): layer_indices = self.get_layer_indices(layer_names) if len(layer_indices) > 0: n_c = m[layer_indices].shape[1] diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py index 622c0150..3e926b00 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py @@ -20,6 +20,7 @@ class Inpainting(PluginBase): method (str): The inpainting method. Options are 'telea' or 'ns' (Navier-Stokes). Default is 'telea'. **kwargs (): Additional keyword arguments. """ + def __init__(self, cell_n: int = 100, method: str = "telea", **kwargs): super().__init__() if method == "telea": @@ -54,9 +55,7 @@ def __call__( h = elevation_map[0] h_max = float(h[mask < 1].max()) h_min = float(h[mask < 1].min()) - h = cp.asnumpy((elevation_map[0] - h_min) * 255 / (h_max - h_min)).astype( - "uint8" - ) + h = cp.asnumpy((elevation_map[0] - h_min) * 255 / (h_max - h_min)).astype("uint8") dst = np.array(cv.inpaint(h, mask, 1, self.method)) h_inpainted = dst.astype(np.float32) * (h_max - h_min) / 255 + h_min return cp.asarray(h_inpainted).astype(np.float64) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py index c685eed6..ebf4300a 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py @@ -18,6 +18,7 @@ class MinFilter(PluginBase): iteration_n (int): The number of iteration to repeat the same filter. **kwargs (): """ + def __init__(self, cell_n: int = 100, dilation_size: int = 5, iteration_n: int = 5, **kwargs): super().__init__() self.iteration_n = iteration_n diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index 01e3aea8..8ff9fda1 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -152,22 +152,11 @@ def update_with_name( self.layers[idx] = self.plugins[idx](elevation_map, layer_names, self.layers, self.layer_names) elif n_param == 7: self.layers[idx] = self.plugins[idx]( - elevation_map, - layer_names, - self.layers, - self.layer_names, - semantic_map, - semantic_params, + elevation_map, layer_names, self.layers, self.layer_names, semantic_map, semantic_params, ) elif n_param == 8: self.layers[idx] = self.plugins[idx]( - elevation_map, - layer_names, - self.layers, - self.layer_names, - semantic_map, - semantic_params, - rotation, + elevation_map, layer_names, self.layers, self.layer_names, semantic_map, semantic_params, rotation, ) else: self.layers[idx] = self.plugins[idx]( diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py index 334085f0..ebb3c6e7 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py @@ -14,6 +14,7 @@ class RobotCentricElevation(PluginBase): use_threshold (bool): **kwargs (): """ + def __init__( self, cell_n: int = 100, resolution: float = 0.05, threshold: float = 0.4, use_threshold: bool = 0, **kwargs ): @@ -111,10 +112,6 @@ def __call__( # check that transform is a ndarray self.min_filtered = elevation_map[0].copy() self.base_elevation_kernel( - elevation_map[0], - elevation_map[2], - rotation, - self.min_filtered, - size=(self.width * self.height), + elevation_map[0], elevation_map[2], rotation, self.min_filtered, size=(self.width * self.height), ) return self.min_filtered diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py index 7085f558..0ec56010 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py @@ -18,18 +18,16 @@ class SemanticFilter(PluginBase): classes (list): List of classes for semantic filtering. Default is ["person", "grass"]. **kwargs: Additional keyword arguments. """ + def __init__( - self, - cell_n: int = 100, - classes: list = ["person", "grass"], - **kwargs, + self, cell_n: int = 100, classes: list = ["person", "grass"], **kwargs, ): super().__init__() self.indices = [] self.classes = classes self.color_encoding = self.transform_color() - def color_map(self, N:int =256, normalized: bool=False): + def color_map(self, N: int = 256, normalized: bool = False): """ Creates a color map with N different colors. @@ -40,6 +38,7 @@ def color_map(self, N:int =256, normalized: bool=False): Returns: np.ndarray: The color map. """ + def bitget(byteval, idx): return (byteval & (1 << idx)) != 0 @@ -117,8 +116,9 @@ def __call__( """ # get indices of all layers that contain semantic class information data = [] - for m, layer_names in zip([elevation_map, plugin_layers, semantic_map], - [layer_names, plugin_layer_names, semantic_layer_names]): + for m, layer_names in zip( + [elevation_map, plugin_layers, semantic_map], [layer_names, plugin_layer_names, semantic_layer_names] + ): layer_indices = self.get_layer_indices(layer_names) if len(layer_indices) > 0: data.append(m[layer_indices]) @@ -130,4 +130,4 @@ def __call__( class_map = cp.zeros_like(elevation_map[0]) class_map_id = cp.zeros_like(elevation_map[0], dtype=cp.int32) enc = self.color_encoding[class_map_id] - return enc \ No newline at end of file + return enc diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py index 842d3b16..5f6ef1d5 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py @@ -19,6 +19,7 @@ class SemanticTraversability(PluginBase): type (list): List of types for each layer. Default is ["traversability"]. **kwargs: Additional keyword arguments. """ + def __init__( self, cell_n: int = 100, @@ -69,9 +70,7 @@ def __call__( idx = plugin_layer_names.index(name) tempo = plugin_layers[idx] else: - print( - "Layer {} is not in the map, returning traversabiltiy!".format(name) - ) + print("Layer {} is not in the map, returning traversabiltiy!".format(name)) return if self.type[it] == "traversability": tempo = cp.where(tempo <= self.thresholds[it], 1, 0) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py index f728d557..ae48b688 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py @@ -21,9 +21,7 @@ class SmoothFilter(PluginBase): **kwargs: Additional keyword arguments. """ - def __init__( - self, cell_n: int = 100, input_layer_name: str = "elevation", **kwargs - ): + def __init__(self, cell_n: int = 100, input_layer_name: str = "elevation", **kwargs): super().__init__() self.input_layer_name = input_layer_name @@ -54,11 +52,7 @@ def __call__( idx = plugin_layer_names.index(self.input_layer_name) h = plugin_layers[idx] else: - print( - "layer name {} was not found. Using elevation layer.".format( - self.input_layer_name - ) - ) + print("layer name {} was not found. Using elevation layer.".format(self.input_layer_name)) h = elevation_map[0] hs1 = ndimage.uniform_filter(h, size=3) hs1 = ndimage.uniform_filter(hs1, size=3) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 1d2eb838..09d1595d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -32,13 +32,9 @@ def __init__(self, param: Parameter): self.amount_layer_names = len(self.layer_names) self.semantic_map = xp.zeros( - (self.amount_layer_names, self.param.cell_n, self.param.cell_n), - dtype=param.data_type, - ) - self.new_map = xp.zeros( - (self.amount_layer_names, self.param.cell_n, self.param.cell_n), - param.data_type, + (self.amount_layer_names, self.param.cell_n, self.param.cell_n), dtype=param.data_type, ) + self.new_map = xp.zeros((self.amount_layer_names, self.param.cell_n, self.param.cell_n), param.data_type,) # which layers should be reset to zero at each update, per default everyone, # if a layer should not be reset, it is defined in compile_kernels function self.delete_new_layers = cp.ones(self.new_map.shape[0], cp.bool8) @@ -58,10 +54,7 @@ def initialize_fusion(self): pcl_ids = self.get_layer_indices("class_max", self.layer_specs_points) self.delete_new_layers[pcl_ids] = 0 layer_cnt = self.param.fusion_algorithms.count("class_max") - id_max = cp.zeros( - (layer_cnt, self.param.cell_n, self.param.cell_n), - dtype=cp.uint32, - ) + id_max = cp.zeros((layer_cnt, self.param.cell_n, self.param.cell_n), dtype=cp.uint32,) self.elements_to_shift["id_max"] = id_max self.fusion_manager.register_plugin(fusion) @@ -77,10 +70,7 @@ def update_fusion_setting(self): pcl_ids = self.get_layer_indices("class_max", self.layer_specs_points) self.delete_new_layers[pcl_ids] = 0 layer_cnt = self.param.fusion_algorithms.count("class_max") - id_max = cp.zeros( - (layer_cnt, self.param.cell_n, self.param.cell_n), - dtype=cp.uint32, - ) + id_max = cp.zeros((layer_cnt, self.param.cell_n, self.param.cell_n), dtype=cp.uint32,) self.elements_to_shift["id_max"] = id_max def add_layer(self, name): @@ -98,13 +88,10 @@ def add_layer(self, name): axis=0, ) self.new_map = cp.append( - self.new_map, - cp.zeros((1, self.param.cell_n, self.param.cell_n), dtype=self.param.data_type), - axis=0, + self.new_map, cp.zeros((1, self.param.cell_n, self.param.cell_n), dtype=self.param.data_type), axis=0, ) self.delete_new_layers = cp.append(self.delete_new_layers, cp.array([1], dtype=cp.bool8)) - def pad_value(self, x, shift_value, idx=None, value=0.0): """Create a padding of the map along x,y-axis according to amount that has shifted. @@ -147,7 +134,9 @@ def shift_map_xy(self, shift_value): el = cp.roll(el, shift_value, axis=(1, 2)) self.pad_value(el, shift_value, value=0.0) - def get_fusion(self, channels: List[str], channel_fusions: Dict[str, str], layer_specs: Dict[str, str]) -> List[str]: + def get_fusion( + self, channels: List[str], channel_fusions: Dict[str, str], layer_specs: Dict[str, str] + ) -> List[str]: """Get all fusion algorithms that need to be applied to a specific pointcloud. Args: @@ -156,18 +145,22 @@ def get_fusion(self, channels: List[str], channel_fusions: Dict[str, str], layer fusion_list = [] process_channels = [] for channel in channels: - if channel not in layer_specs: + if channel not in layer_specs: # If the channel is not in the layer_specs, we use the default fusion algorithm matched_fusion = self.get_matching_fusion(channel, channel_fusions) if matched_fusion is None: if "default" in channel_fusions: default_fusion = channel_fusions["default"] - print(f"[WARNING] Layer {channel} not found in layer_specs. Using {default_fusion} algorithm as default.") + print( + f"[WARNING] Layer {channel} not found in layer_specs. Using {default_fusion} algorithm as default." + ) layer_specs[channel] = default_fusion self.update_fusion_setting() # If there's no default fusion algorithm, we skip this channel else: - print(f"[WARNING] Layer {channel} not found in layer_specs ({layer_specs}) and no default fusion is configured. Skipping.") + print( + f"[WARNING] Layer {channel} not found in layer_specs ({layer_specs}) and no default fusion is configured. Skipping." + ) continue else: layer_specs[channel] = matched_fusion @@ -177,7 +170,6 @@ def get_fusion(self, channels: List[str], channel_fusions: Dict[str, str], layer process_channels.append(channel) return process_channels, fusion_list - def get_matching_fusion(self, channel: str, fusion_algs: Dict[str, str]): """ Use regular expression to check if the fusion algorithm matches the channel name.""" for fusion_alg, alg_value in fusion_algs.items(): @@ -185,7 +177,6 @@ def get_matching_fusion(self, channel: str, fusion_algs: Dict[str, str]): return alg_value return None - def get_layer_indices(self, fusion_alg, layer_specs): """Get the indices of the layers that are used for a specific fusion algorithm. @@ -216,10 +207,7 @@ def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str, layer_spe # this contains exactly the fusion alg type for each channel of the pcl pcl_val_list = [layer_specs[x] for x in pcl_channels] # this contains the indices of the point cloud where we have to perform a certain fusion - pcl_indices = cp.array( - [idp + 3 for idp, x in enumerate(pcl_val_list) if x == fusion_alg], - dtype=cp.int32, - ) + pcl_indices = cp.array([idp + 3 for idp, x in enumerate(pcl_val_list) if x == fusion_alg], dtype=cp.int32,) # create a list of indices of the layers that will be updated by the point cloud with specific fusion alg layer_indices = cp.array([], dtype=cp.int32) for it, (key, val) in enumerate(layer_specs.items()): @@ -238,7 +226,9 @@ def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): t: translation vector elevation_map: elevation map object """ - process_channels, additional_fusion = self.get_fusion(channels, self.param.pointcloud_channel_fusions, self.layer_specs_points) + process_channels, additional_fusion = self.get_fusion( + channels, self.param.pointcloud_channel_fusions, self.layer_specs_points + ) # If channels has a new layer that is not in the semantic map, add it for channel in process_channels: if channel not in self.layer_names: @@ -286,7 +276,9 @@ def update_layers_image( image_width: """ - process_channels, fusion_methods = self.get_fusion(channels, self.param.image_channel_fusions, self.layer_specs_image) + process_channels, fusion_methods = self.get_fusion( + channels, self.param.image_channel_fusions, self.layer_specs_image + ) self.new_map[self.delete_new_layers] = 0.0 for j, (fusion, channel) in enumerate(zip(fusion_methods, process_channels)): if channel not in self.layer_names: diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py index 7c1dc945..f3e8cc1c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py @@ -10,9 +10,7 @@ @pytest.fixture() def semmap_ex(add_lay, fusion_alg): p = parameter.Parameter( - use_chainer=False, - weight_file="../../../config/weights.dat", - plugin_config_file=plugin_path, + use_chainer=False, weight_file="../../../config/weights.dat", plugin_config_file=plugin_path, ) p.subscriber_cfg["front_cam"]["channels"] = add_lay p.subscriber_cfg["front_cam"]["fusion"] = fusion_alg diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py index ed7eb85c..590946eb 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py @@ -4,9 +4,7 @@ from elevation_mapping_cupy.parameter import Parameter -from elevation_mapping_cupy.kernels import ( - add_points_kernel, -) +from elevation_mapping_cupy.kernels import add_points_kernel from elevation_mapping_cupy.kernels import ( average_kernel, class_average_kernel, @@ -34,17 +32,11 @@ def test_color_kernel(): semantic_map = cp.zeros((1, 4, 4), dtype=cp.float32) # compile kernel - add_color_kernel_ = add_color_kernel( - cell_n, - cell_n, - ) + add_color_kernel_ = add_color_kernel(cell_n, cell_n,) color_average_kernel_ = color_average_kernel(cell_n, cell_n) # updatelayer - color_map = cp.zeros( - (1 + 3 * layer_ids.shape[0], cell_n, cell_n), - dtype=cp.uint32, - ) + color_map = cp.zeros((1 + 3 * layer_ids.shape[0], cell_n, cell_n), dtype=cp.uint32,) points_all = points_all.astype(cp.float32) add_color_kernel_( @@ -91,11 +83,7 @@ def test_sum_kernel(map_shape, points_all, pcl_ids, layer_ids): R = cp.eye(3, dtype=cp.float32) t = cp.array([0, 0, 0], dtype=cp.float32) # compile kernel - sum_kernel_ = sum_kernel( - 0.9, - 4, - 4, - ) + sum_kernel_ = sum_kernel(0.9, 4, 4,) # simulating adding the points print("idx, valid, inside, values") points_all[:, 0] = 1 @@ -138,10 +126,7 @@ def test_average_kernel(map_shape, points_all, pcl_ids, layer_ids): R = cp.eye(3, dtype=cp.float32) t = cp.array([0, 0, 0], dtype=cp.float32) # compile kernel - average_kernel_ = average_kernel( - 4, - 4, - ) + average_kernel_ = average_kernel(4, 4,) cell_n = 4 print("new_map", new_map) print("semantic_map", semantic_map) @@ -184,23 +169,9 @@ def test_bayesian_inference_kernel(map_shape, points_all, pcl_ids, layer_ids): t = cp.array([0, 0, 0], dtype=cp.float32) # compile kernel - sum_mean = cp.ones( - ( - pcl_ids.shape[0], - cell_n, - cell_n, - ), - cp.float32, - ) - sum_compact_kernel_ = sum_compact_kernel( - resolution, - cell_n, - cell_n, - ) - bayesian_inference_kernel_ = bayesian_inference_kernel( - cell_n, - cell_n, - ) + sum_mean = cp.ones((pcl_ids.shape[0], cell_n, cell_n,), cp.float32,) + sum_compact_kernel_ = sum_compact_kernel(resolution, cell_n, cell_n,) + bayesian_inference_kernel_ = bayesian_inference_kernel(cell_n, cell_n,) # updatelayer sum_mean *= 0 sum_compact_kernel_( @@ -251,16 +222,8 @@ def test_class_average_kernel(map_shape, points_all, pcl_ids, layer_ids): R = cp.eye(3, dtype=cp.float32) t = cp.array([0, 0, 0], dtype=cp.float32) # compile kernel - sum_kernel_ = sum_kernel( - 0.9, - 4, - 4, - ) - class_average_kernel_ = class_average_kernel( - cell_n, - cell_n, - average_weight, - ) + sum_kernel_ = sum_kernel(0.9, 4, 4,) + class_average_kernel_ = class_average_kernel(cell_n, cell_n, average_weight,) print("x,y,z,class") print("points all after ", points_all) @@ -320,11 +283,7 @@ def test_class_bayesian_inference_fct(map_shape, points_all, pcl_ids, layer_ids) R = cp.eye(3, dtype=cp.float32) t = cp.array([0, 0, 0], dtype=cp.float32) # compile kernel - alpha_kernel_ = alpha_kernel( - resolution, - cell_n, - cell_n, - ) + alpha_kernel_ = alpha_kernel(resolution, cell_n, cell_n,) # simulating adding the points print("idx, valid, inside, values") points_all[:, 0] = 1 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py index f38bc73e..95966bc4 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py @@ -24,36 +24,12 @@ def semmap_ex(sem_lay, fusion_alg): [ (["feat_0", "feat_1"], ["average", "average"], ["feat_0"]), (["feat_0", "feat_1"], ["average", "average"], []), - ( - ["feat_0", "feat_1", "rgb"], - ["average", "average", "color"], - ["rgb", "feat_0"], - ), - ( - ["feat_0", "feat_1", "rgb"], - ["class_average", "average", "color"], - ["rgb", "feat_0"], - ), - ( - ["feat_0", "feat_1", "rgb"], - ["class_bayesian", "average", "color"], - ["rgb", "feat_0"], - ), - ( - ["feat_0", "feat_1", "rgb"], - ["class_bayesian", "average", "color"], - ["rgb", "feat_0", "feat_1"], - ), - ( - ["feat_0", "feat_1", "rgb"], - ["class_bayesian", "class_max", "color"], - ["rgb", "feat_0", "feat_1"], - ), - ( - ["max1", "max2", "rgb"], - ["class_max", "class_max", "color"], - ["rgb", "max1", "max2"], - ), + (["feat_0", "feat_1", "rgb"], ["average", "average", "color"], ["rgb", "feat_0"],), + (["feat_0", "feat_1", "rgb"], ["class_average", "average", "color"], ["rgb", "feat_0"],), + (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0"],), + (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0", "feat_1"],), + (["feat_0", "feat_1", "rgb"], ["class_bayesian", "class_max", "color"], ["rgb", "feat_0", "feat_1"],), + (["max1", "max2", "rgb"], ["class_max", "class_max", "color"], ["rgb", "max1", "max2"],), ], ) def test_fusion_of_pcl(semmap_ex, channels): @@ -64,10 +40,7 @@ def test_fusion_of_pcl(semmap_ex, channels): @pytest.mark.parametrize( - "sem_lay, fusion_alg", - [ - (["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), - ], + "sem_lay, fusion_alg", [(["feat_0", "feat_1", "rgb"], ["average", "average", "color"]),], ) @pytest.mark.parametrize("channels", [["rgb"], ["rgb", "feat_0"], []]) def test_indices_fusion(semmap_ex, channels, fusion_alg): diff --git a/elevation_mapping_cupy/setup.py b/elevation_mapping_cupy/setup.py index f225f03a..8d5a2492 100644 --- a/elevation_mapping_cupy/setup.py +++ b/elevation_mapping_cupy/setup.py @@ -2,11 +2,7 @@ from catkin_pkg.python_setup import generate_distutils_setup setup_args = generate_distutils_setup( - packages=[ - "elevation_mapping_cupy", - "elevation_mapping_cupy.plugins", - ], - package_dir={"": "script"}, + packages=["elevation_mapping_cupy", "elevation_mapping_cupy.plugins",], package_dir={"": "script"}, ) setup(**setup_args) diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py index 711c5b4e..53abd17a 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py @@ -34,12 +34,7 @@ def forward(self, x): class Mlp(nn.Module): def __init__( - self, - in_features, - hidden_features=None, - out_features=None, - act_layer=nn.GELU, - drop=0.0, + self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.0, ): super().__init__() out_features = out_features or in_features @@ -60,13 +55,7 @@ def forward(self, x): class Attention(nn.Module): def __init__( - self, - dim, - num_heads=8, - qkv_bias=False, - qk_scale=None, - attn_drop=0.0, - proj_drop=0.0, + self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0.0, proj_drop=0.0, ): super().__init__() # number of attention heads @@ -74,7 +63,7 @@ def __init__( # dimension of each head head_dim = dim // num_heads # scale factor for the attention scores - self.scale = qk_scale or head_dim**-0.5 + self.scale = qk_scale or head_dim ** -0.5 # linear layer to project the input to 3 times the dimension self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) @@ -127,22 +116,12 @@ def __init__( super().__init__() self.norm1 = norm_layer(dim) self.attn = Attention( - dim, - num_heads=num_heads, - qkv_bias=qkv_bias, - qk_scale=qk_scale, - attn_drop=attn_drop, - proj_drop=drop, + dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop, ) self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity() self.norm2 = norm_layer(dim) mlp_hidden_dim = int(dim * mlp_ratio) - self.mlp = Mlp( - in_features=dim, - hidden_features=mlp_hidden_dim, - act_layer=act_layer, - drop=drop, - ) + self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop,) def forward(self, x, return_attention=False, return_qkv=False): y, attn, qkv = self.attn(self.norm1(x)) @@ -199,10 +178,7 @@ def __init__( self.num_features = self.embed_dim = embed_dim self.patch_embed = PatchEmbed( - img_size=img_size[0], - patch_size=patch_size, - in_chans=in_chans, - embed_dim=embed_dim, + img_size=img_size[0], patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim, ) num_patches = self.patch_embed.num_patches @@ -372,14 +348,7 @@ def vit_base(patch_size=16, **kwargs): class DINOHead(nn.Module): def __init__( - self, - in_dim, - out_dim, - use_bn=False, - norm_last_layer=True, - nlayers=3, - hidden_dim=2048, - bottleneck_dim=256, + self, in_dim, out_dim, use_bn=False, norm_last_layer=True, nlayers=3, hidden_dim=2048, bottleneck_dim=256, ): super().__init__() nlayers = max(nlayers, 1) diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py index d59840ba..e64991f1 100755 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py @@ -73,7 +73,9 @@ def register_sub_pub(self): # subscribers if self.param.camera_info_topic is not None and self.param.resize is not None: rospy.Subscriber(self.param.camera_info_topic, CameraInfo, self.image_info_callback) - self.feat_im_info_pub = rospy.Publisher(node_name + "/" + self.param.camera_info_topic + "_resized", CameraInfo, queue_size=2) + self.feat_im_info_pub = rospy.Publisher( + node_name + "/" + self.param.camera_info_topic + "_resized", CameraInfo, queue_size=2 + ) if "compressed" in self.param.image_topic: self.compressed = True @@ -94,9 +96,13 @@ def register_sub_pub(self): if self.param.feature_extractor: self.feature_pub = rospy.Publisher(node_name + "/" + self.param.feature_topic, Image, queue_size=2) self.feat_im_pub = rospy.Publisher(node_name + "/" + self.param.feat_image_topic, Image, queue_size=2) - self.feat_channel_info_pub = rospy.Publisher(node_name + "/" + self.param.feat_channel_info_topic, ChannelInfo, queue_size=2) + self.feat_channel_info_pub = rospy.Publisher( + node_name + "/" + self.param.feat_channel_info_topic, ChannelInfo, queue_size=2 + ) - self.channel_info_pub = rospy.Publisher(node_name + "/" + self.param.channel_info_topic, ChannelInfo, queue_size=2) + self.channel_info_pub = rospy.Publisher( + node_name + "/" + self.param.channel_info_topic, ChannelInfo, queue_size=2 + ) def color_map(self, N=256, normalized=False): """Create a color map for the class labels. diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py index aacb152c..6ad67027 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py @@ -39,4 +39,4 @@ class ImageParameter(Serializable): feat_image_topic: str = "semantic_seg_feat_im" feat_channel_info_topic: str = "feat_channel_info" resize: float = None - camera_info_topic: str = "camera_info" \ No newline at end of file + camera_info_topic: str = "camera_info" diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py index 0c666a3e..e64b4497 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py @@ -106,8 +106,7 @@ def resolve_categories(self): # get all classes class_to_idx = {cls: idx for (idx, cls) in enumerate(self.get_classes())} print( - "Semantic Segmentation possible channels: ", - self.get_classes(), + "Semantic Segmentation possible channels: ", self.get_classes(), ) indices = [] channels = [] @@ -124,14 +123,14 @@ def resolve_categories(self): # print(chan, " is not in the semantic segmentation model.") # for it, chan in enumerate(self.param.channels): # self.actual_channels.append(chan) - # if self.param.fusion_methods[it] in ["class_max"]: - # self.actual_channels.append(chan) - # print( - # chan, - # " is not in the semantic segmentation model but is a max channel.", - # ) - # else: - # pass + # if self.param.fusion_methods[it] in ["class_max"]: + # self.actual_channels.append(chan) + # print( + # chan, + # " is not in the semantic segmentation model but is a max channel.", + # ) + # else: + # pass self.stuff_categories = dict(zip(channels, indices)) self.segmentation_channels = dict(zip(channels, indices)) @@ -204,8 +203,7 @@ def resolve_categories(self, name): classes = self.get_category(name) class_to_idx = {cls: idx for (idx, cls) in enumerate(classes)} print( - "Semantic Segmentation possible channels: ", - classes, + "Semantic Segmentation possible channels: ", classes, ) indices = [] channels = [] @@ -227,13 +225,7 @@ def __call__(self, image, *args, **kwargs): image = cp.flip(image, axis=2) prediction = self.predictor(image.get()) probabilities = cp.asarray(torch.softmax(prediction["sem_seg"], dim=0)) - output = cp.zeros( - ( - len(self.segmentation_channels), - probabilities.shape[1], - probabilities.shape[2], - ) - ) + output = cp.zeros((len(self.segmentation_channels), probabilities.shape[1], probabilities.shape[2],)) # add semseg output[cp.array(list(self.is_stuff.values()))] = probabilities[list(self.stuff_categories.values())] # add instances diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py index 597cc080..a713f312 100755 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py @@ -3,6 +3,7 @@ import numpy as np import cupy as cp + np.float = np.float64 # temp fix for following import suggested at https://github.com/eric-wieser/ros_numpy/issues/37 import ros_numpy import matplotlib.pyplot as plt @@ -88,23 +89,10 @@ def register_sub_pub(self): if self.param.confidence: confidence_sub = message_filters.Subscriber(self.param.confidence_topic, Image) ts = message_filters.ApproximateTimeSynchronizer( - [ - depth_sub, - rgb_sub, - confidence_sub, - ], - queue_size=10, - slop=0.5, + [depth_sub, rgb_sub, confidence_sub,], queue_size=10, slop=0.5, ) else: - ts = message_filters.ApproximateTimeSynchronizer( - [ - depth_sub, - rgb_sub, - ], - queue_size=10, - slop=0.5, - ) + ts = message_filters.ApproximateTimeSynchronizer([depth_sub, rgb_sub,], queue_size=10, slop=0.5,) ts.registerCallback(self.image_callback) self.pcl_pub = rospy.Publisher(self.param.topic_name, PointCloud2, queue_size=2) diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py index dfb81228..a4837c67 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py @@ -23,13 +23,7 @@ class PointcloudParameter(Serializable): topic_name: str = "/elvation_mapping/pointcloud_semantic" channels: list = field(default_factory=lambda: ["rgb", "person", "grass", "tree", "max"]) fusion: list = field( - default_factory=lambda: [ - "color", - "class_average", - "class_average", - "class_average", - "class_max", - ] + default_factory=lambda: ["color", "class_average", "class_average", "class_average", "class_max",] ) semantic_segmentation: bool = False diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py index 544c2eeb..724b6b51 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py @@ -28,12 +28,10 @@ def pointcloud_ex(cam_name, channels, fusion, semseg, segpub, showlbl): ], ) @pytest.mark.parametrize( - "segpub", - [True, False], + "segpub", [True, False], ) @pytest.mark.parametrize( - "showlbl", - [True, False], + "showlbl", [True, False], ) def test_initialize(pointcloud_ex): # todo here we can add more test @@ -46,39 +44,11 @@ def test_initialize(pointcloud_ex): @pytest.mark.parametrize( "cam_name,channels, fusion,semseg,segpub,showlbl", [ - ( - "front_cam", - ["feat_0", "feat_1"], - ["average", "average"], - False, - False, - False, - ), + ("front_cam", ["feat_0", "feat_1"], ["average", "average"], False, False, False,), ("front_cam", ["feat_0", "feat_1"], ["class_max", "average"], True, True, True), - ( - "front_cam", - ["feat_0", "feat_1"], - ["class_max", "average"], - True, - False, - False, - ), - ( - "front_cam", - ["feat_0", "feat_1"], - ["class_bayesian", "average"], - True, - True, - True, - ), - ( - "front_cam", - ["feat_0", "feat_1"], - ["class_bayesian", "average"], - True, - False, - False, - ), + ("front_cam", ["feat_0", "feat_1"], ["class_max", "average"], True, False, False,), + ("front_cam", ["feat_0", "feat_1"], ["class_bayesian", "average"], True, True, True,), + ("front_cam", ["feat_0", "feat_1"], ["class_bayesian", "average"], True, False, False,), ], ) def test_pcl_creation(pointcloud_ex, channels, fusion, semseg, segpub, showlbl): diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py index fdcc4c91..e50ca9e5 100644 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py +++ b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py @@ -31,10 +31,7 @@ def test_semantic_segmentation(model_name, channels, fusion): @pytest.mark.parametrize( - "model_name", - [ - "DINO", - ], + "model_name", ["DINO",], ) def test_feature_extractor(model_name): param = FeatureExtractorParameter() diff --git a/sensor_processing/semantic_sensor/setup.py b/sensor_processing/semantic_sensor/setup.py index e042fa90..fef26672 100644 --- a/sensor_processing/semantic_sensor/setup.py +++ b/sensor_processing/semantic_sensor/setup.py @@ -2,14 +2,7 @@ from catkin_pkg.python_setup import generate_distutils_setup setup_args = generate_distutils_setup( - packages=[ - "semantic_sensor", - ], - install_requires=[ - "torch", - "torchvision", - ], - package_dir={"": "script"}, + packages=["semantic_sensor",], install_requires=["torch", "torchvision",], package_dir={"": "script"}, ) setup(**setup_args) From 10ec9da44e84f4107711d58c626e86c7acb1063d Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 12:39:31 +0100 Subject: [PATCH 385/504] Some minor cleanup --- .../config/core/core_param.yaml | 2 +- .../setups/features/features_parameters.yaml | 94 ------------------- .../features/features_plugin_config.yaml | 70 -------------- .../setups/features/features_semantics.yaml | 32 ------- .../features/features_sensor_parameter.yaml | 13 --- .../setups/features/image_semantics.yaml | 14 --- .../launch/turtlesim_init.launch | 8 +- .../elevation_mapping_ros.py | 4 +- 8 files changed, 7 insertions(+), 230 deletions(-) delete mode 100644 elevation_mapping_cupy/config/setups/features/features_parameters.yaml delete mode 100644 elevation_mapping_cupy/config/setups/features/features_plugin_config.yaml delete mode 100644 elevation_mapping_cupy/config/setups/features/features_semantics.yaml delete mode 100644 elevation_mapping_cupy/config/setups/features/features_sensor_parameter.yaml delete mode 100644 elevation_mapping_cupy/config/setups/features/image_semantics.yaml diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 6bbede56..17baea09 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -65,7 +65,7 @@ initialize_method: 'linear' # Choose one initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 2 # dilation size after the init. -initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. +initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. #### Default Plugins ######## diff --git a/elevation_mapping_cupy/config/setups/features/features_parameters.yaml b/elevation_mapping_cupy/config/setups/features/features_parameters.yaml deleted file mode 100644 index e1c4c881..00000000 --- a/elevation_mapping_cupy/config/setups/features/features_parameters.yaml +++ /dev/null @@ -1,94 +0,0 @@ -#### Basic parameters ######## -resolution: 0.04 # resolution in m. -map_length: 8.0 # map's size in m. -sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). -mahalanobis_thresh: 2.0 # points outside this distance is outlier. -outlier_variance: 0.01 # if point is outlier, add this value to the cell. -drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. -max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) -drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation -time_variance: 0.0001 # add this value when update_variance is called. -max_variance: 100.0 # maximum variance for each cell. -initial_variance: 1000.0 # initial variance for each cell. -traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. -dilation_size: 3 # dilation filter size before traversability filter. -wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. -min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. -position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. -orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. -position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -min_valid_distance: 0.5 # points with shorter distance will be filtered out. -max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. -ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -update_variance_fps: 5.0 # fps for updating variance. -update_pose_fps: 10.0 # fps for updating pose and shift the center of map. -time_interval: 0.1 # Time layer is updated with this interval. -map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. -publish_statistics_fps: 1.0 # Publish statistics topic in this fps. - -max_ray_length: 10.0 # maximum length for ray tracing. -cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. -cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. - -safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. -safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. -max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. - -overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) -overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - -map_frame: 'odom' # The map frame where the odometry source uses. -base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'odom' - -#### Feature toggles ######## -enable_edge_sharpen: true -enable_visibility_cleanup: true -enable_drift_compensation: true -enable_overlap_clearance: true -enable_pointcloud_publishing: false -enable_drift_corrected_TF_publishing: false -enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. - -#### Traversability filter ######## -use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. -weight_file: '$(rospack find elevation_mapping_cupy)/config/weights.dat' # Weight file for traversability filter - -#### Upper bound ######## -use_only_above_for_upper_bound: false - -#### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/features_plugin_config.yaml' - -#### Subscribers ######## - - -#### Publishers ######## -# topic_name: -# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names -# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. -# fps: # Publish rate. Use smaller value than `map_acquire_fps`. -publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','pca'] - basic_layers: ['elevation'] - fps: 5.0 -# elevation_map_recordable: -# layers: ['elevation', 'traversability'] -# basic_layers: ['elevation', 'traversability'] -# fps: 2.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation','pca'] - basic_layers: ['min_filter'] - fps: 3.0 - -#### Initializer ######## -initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. -dilation_size_initialize: 5 # dilation size after the init. -initialize_tf_grid_size: 2 # This is not used if number of tf is more than 3. -use_initializer_at_start: true # Use initializer when the node starts. diff --git a/elevation_mapping_cupy/config/setups/features/features_plugin_config.yaml b/elevation_mapping_cupy/config/setups/features/features_plugin_config.yaml deleted file mode 100644 index 6bf79c0a..00000000 --- a/elevation_mapping_cupy/config/setups/features/features_plugin_config.yaml +++ /dev/null @@ -1,70 +0,0 @@ -# Settings of the plugins. (The plugins should be stored in script/plugins) - -# min_filter fills in minimum value around the invalid cell. -min_filter: - enable: True # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - dilation_size: 1 # The patch size to apply - iteration_n: 30 # The number of iterations -# Apply smoothing. -smooth_filter: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth" - extra_params: - input_layer_name: "min_filter" -# Apply inpainting using opencv -inpainting: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "inpaint" - extra_params: - method: "telea" # telea or ns -# Apply smoothing for inpainted layer - -robot_centric_elevation: # Use the same name as your file name. -# type: "robot_centric_elevation" - enable: False # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. -# add_value: 2.0 # Example param - resolution: 0.04 - threshold: 1.1 - use_threshold: True - -semantic_filter: - type: "semantic_filter" - enable: False - fill_nan: False - is_height_layer: False - layer_name: "sem_fil" - extra_params: - classes: ['grass','tree','fence','dirt'] - -semantic_traversability: - type: "semantic_traversability" - enable: False - fill_nan: False - is_height_layer: False - layer_name: "sem_traversability" - extra_params: - layers: ['traversability','robot_centric_elevation'] - thresholds: [0.3,0.5] - type: ['traversability', 'elevation'] - -features_pca: - type: "features_pca" - enable: True - fill_nan: False - is_height_layer: False - layer_name: "pca" - extra_params: - classes: [] - diff --git a/elevation_mapping_cupy/config/setups/features/features_semantics.yaml b/elevation_mapping_cupy/config/setups/features/features_semantics.yaml deleted file mode 100644 index 4cd5365f..00000000 --- a/elevation_mapping_cupy/config/setups/features/features_semantics.yaml +++ /dev/null @@ -1,32 +0,0 @@ -#### Subscribers ######## -subscribers: - - feat_front: - fusion: ['average','average','average','average','average','average','average','average','average','average'] - image_topic: "/camera/rgb/image_raw" - image_info_topic: "/camera/depth/camera_info" - semantic_segmentation: False - feature_extractor: True - feature_topic: "/elevation_mapping/feat_f" - feat_image_topic: "/elevation_mapping/feat_im_f" - show_label_legend: True - channels: [ 'feat_0','feat_1','feat_2','feat_3','feat_4','feat_5','feat_6','feat_7','feat_8','feat_9' ] - resize: 0.5 - input_size: [160,320] - -# sem_wide_back: -# fusion: ['average','average','average','average','average','average','average','average','average','average'] -# image_topic: "/wide_angle_camera_rear/image_color_rect/compressed" -# semantic_segmentation: False -# feature_extractor: True -# feature_topic: "/elevation_mapping/feat_b" -# feat_image_topic: "/elevation_mapping/feat_im_b" -# show_label_legend: False -# channels: [ 'feat_0','feat_1','feat_2','feat_3','feat_4','feat_5','feat_6','feat_7','feat_8','feat_9' ] -# image_info_topic: "/wide_angle_camera_rear/camera_info" -# resize: 0.5 -# input_size: [160,320] - - - - diff --git a/elevation_mapping_cupy/config/setups/features/features_sensor_parameter.yaml b/elevation_mapping_cupy/config/setups/features/features_sensor_parameter.yaml deleted file mode 100644 index d09cc6b6..00000000 --- a/elevation_mapping_cupy/config/setups/features/features_sensor_parameter.yaml +++ /dev/null @@ -1,13 +0,0 @@ -subscribers: - feat_front: - fusion: [ 'exponential','exponential','exponential','exponential','exponential','exponential','exponential','exponential','exponential','exponential' ] - topic_name_camera: /elevation_mapping/feat_f - topic_name_camera_info: "/camera/depth/camera_info" - channels: [ 'feat_0','feat_1','feat_2','feat_3','feat_4','feat_5','feat_6','feat_7','feat_8','feat_9' ] - data_type: image - pointcloud: - channels: [ ] - fusion: [ ] - topic_name: '/camera/depth/points' - data_type: pointcloud - diff --git a/elevation_mapping_cupy/config/setups/features/image_semantics.yaml b/elevation_mapping_cupy/config/setups/features/image_semantics.yaml deleted file mode 100644 index 76b4295a..00000000 --- a/elevation_mapping_cupy/config/setups/features/image_semantics.yaml +++ /dev/null @@ -1,14 +0,0 @@ -#### Subscribers ######## -subscribers: - front_cam: - channels: ['grass','tree',"person" ] - fusion: ['class_average','class_average','class_average' ] - semantic_segmentation: True - segmentation_model: 'detectron_coco_panoptic_fpn_R_101_3x' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large - show_label_legend: False - image_topic: "/camera/rgb/image_raw" - image_info_topic: "/camera/depth/camera_info" - resize: 0.5 - - sem_seg_topic: "/elevation_mapping/semantic_front" - sem_seg_image_topic: "/elevation_mapping/semantic_image_front" \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_init.launch b/elevation_mapping_cupy/launch/turtlesim_init.launch index 0679d174..7bd323a9 100644 --- a/elevation_mapping_cupy/launch/turtlesim_init.launch +++ b/elevation_mapping_cupy/launch/turtlesim_init.launch @@ -2,15 +2,15 @@ - - + + - - + + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index 8cd63b52..3756ebd7 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -39,8 +39,8 @@ class ElevationMapWrapper: def __init__(self): rospack = rospkg.RosPack() self.root = rospack.get_path("elevation_mapping_cupy") - weight_file = os.path.join(self.root, "config/weights.dat") - plugin_config_file = os.path.join(self.root, "config/plugin_config.yaml") + weight_file = os.path.join(self.root, "config/core/weights.dat") + plugin_config_file = os.path.join(self.root, "config/core/plugin_config.yaml") self.param = Parameter(use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file) self.node_name = "elevation_mapping" From d6fcd9d871a1684b36c5c74754f436093c2521a9 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 12:45:42 +0100 Subject: [PATCH 386/504] Cleaning up. --- elevation_mapping_cupy/package.xml | 4 ++-- .../script/elevation_mapping_cupy/fusion/fusion_manager.py | 4 ++++ .../script/elevation_mapping_cupy/fusion/image_color.py | 4 ++++ .../script/elevation_mapping_cupy/fusion/image_exponential.py | 4 ++++ .../fusion/pointcloud_bayesian_inference.py | 4 ++++ .../elevation_mapping_cupy/fusion/pointcloud_class_average.py | 4 ++++ .../fusion/pointcloud_class_bayesian.py | 4 ++++ .../elevation_mapping_cupy/fusion/pointcloud_class_max.py | 4 ++++ .../script/elevation_mapping_cupy/fusion/pointcloud_color.py | 4 ++++ .../elevation_mapping_cupy/kernels/custom_image_kernels.py | 4 ++++ .../elevation_mapping_cupy/kernels/custom_semantic_kernels.py | 4 ++++ .../elevation_mapping_cupy/plugins/robot_centric_elevation.py | 4 ++++ .../script/elevation_mapping_cupy/semantic_map.py | 4 ++++ 13 files changed, 50 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index 6a5985f8..9befc801 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -1,8 +1,8 @@ elevation_mapping_cupy - 1.0.0 - The elevation mapping by cupy + 2.0.0 + The elevation mapping on GPU Takahiro Miki diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py index 152e37bd..aca34a6d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py @@ -1,3 +1,7 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# from abc import ABC, abstractmethod import cupy as cp from typing import List, Dict, Any diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py index e4026a13..c882c1b0 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py @@ -1,3 +1,7 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# import cupy as cp import numpy as np import string diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py index 48fa11f8..26aa2f89 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py @@ -1,3 +1,7 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# import cupy as cp import numpy as np import string diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py index 96f1d1e2..95dc8aea 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py @@ -1,3 +1,7 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# import cupy as cp import numpy as np import string diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py index 8fa94c13..80c96dc4 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py @@ -1,3 +1,7 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# import cupy as cp import numpy as np import string diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py index 22869d22..5fec3a7d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py @@ -1,3 +1,7 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# import cupy as cp import numpy as np import string diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py index 728e42fb..e506571d 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py @@ -1,3 +1,7 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# import cupy as cp import numpy as np import string diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py index 801abd95..a749b842 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py @@ -1,3 +1,7 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# import cupy as cp import numpy as np import string diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py index 18873aa7..ce03ee8f 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py @@ -1,3 +1,7 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# import cupy as cp import string diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py index 43980321..26db74c0 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py @@ -1,3 +1,7 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# import cupy as cp import string diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py index ebb3c6e7..80ac73a3 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py @@ -1,3 +1,7 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# import cupy as cp import string from typing import List diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py index 09d1595d..a06b7361 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py @@ -1,3 +1,7 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# from elevation_mapping_cupy.parameter import Parameter import cupy as cp import numpy as np From fe909d10ea2134a3288d4a1090dceaba14f496c3 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 12:52:15 +0100 Subject: [PATCH 387/504] Updated README. --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a5072f25..8eae8a86 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ The Elevaton Mapping CuPy software package represents an advancement in robotic navigation and locomotion. Integrating with the Robot Operating System (ROS) and utilizing GPU acceleration, this framework enhances point cloud registration and ray casting, crucial for efficient and accurate robotic movement, particularly in legged robots. -![screenshot](doc/media/main_repo.png) -![screenshot](doc/media/main_mem.png) -![gif](doc/media/convex_approximation.gif) +![screenshot](docs/media/main_repo.png) +![screenshot](docs/media/main_mem.png) +![gif](docs/media/convex_approximation.gif) ## Key Features @@ -30,7 +30,7 @@ crucial for efficient and accurate robotic movement, particularly in legged robo ## Overview -![Overview of multi-modal elevation map structure](doc/media/overview.png) +![Overview of multi-modal elevation map structure](docs/media/overview.png) Overview of our multi-modal elevation map structure. The framework takes multi-modal images (purple) and multi-modal (blue) point clouds as input. This data is input into the elevation map by first associating the data to the cells and then fused with different fusion algorithms into the various @@ -101,7 +101,7 @@ catkin build elevation_mapping_cupy ``` ### Run turtlebot example. -![Elevation map examples](doc/media/turtlebot.png) +![Elevation map examples](docs/media/turtlebot.png) ```bash export TURTLEBOT3_MODEL=waffle From 0d8f618af4fe29e2bb9b734fdeee4ec192efb4c2 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 15:54:28 +0100 Subject: [PATCH 388/504] Update readme. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 8eae8a86..9a729ce9 100644 --- a/README.md +++ b/README.md @@ -92,12 +92,16 @@ cd docker ./run.sh ``` +For more information, check [Document](https://leggedrobotics.github.io/elevation_mapping_cupy/getting_started/installation.html) + ### Build package Inside docker container. ```zsh cd $HOME/catkin_ws catkin build elevation_mapping_cupy +catkin build convex_plane_decomposition_ros # If you want to use plane segmentation +catkin build semantic_sensor # If you want to use semantic sensors ``` ### Run turtlebot example. From 96655ed545fe6551ae6e0cab2c86ea1cb0fc18bf Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 16:39:31 +0100 Subject: [PATCH 389/504] Added installing the module. --- .github/workflows/documentation.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 9da81809..d6344387 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -9,6 +9,7 @@ jobs: - name: Install dependencies run: | pip install sphinx sphinx_rtd_theme sphinx-copybutton + pip install elevation_mapping_cupy/. - name: Sphinx build run: | sphinx-build docs/source docs/_build From 592d0915298b03d4045d05579fc856469e50cb43 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 21:01:52 +0100 Subject: [PATCH 390/504] Added catkin-tools in requirements. --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 45fb53ea..47cf9c5f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ opencv-python simple-parsing scikit-image matplotlib +catkin-tools # cupy ###### Requirements with Version Specifiers ######` From 37e92b6edd4593db8c0a4ad65e466ea7d10851d3 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 21:03:34 +0100 Subject: [PATCH 391/504] Modified workflow for doc --- .github/workflows/documentation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index d6344387..fa070155 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -9,7 +9,7 @@ jobs: - name: Install dependencies run: | pip install sphinx sphinx_rtd_theme sphinx-copybutton - pip install elevation_mapping_cupy/. + pip install -r elevation_mapping_cupy/requirements.txt - name: Sphinx build run: | sphinx-build docs/source docs/_build From 20d106a14e1d39bb693118f748cc474394a88407 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 21:12:35 +0100 Subject: [PATCH 392/504] Modified workflow for doc --- .github/workflows/documentation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index fa070155..12d4de2f 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -9,7 +9,7 @@ jobs: - name: Install dependencies run: | pip install sphinx sphinx_rtd_theme sphinx-copybutton - pip install -r elevation_mapping_cupy/requirements.txt + pip install -r requirements.txt - name: Sphinx build run: | sphinx-build docs/source docs/_build From 479d825abdeed5c9b2569669d0815bcbc5aa7e52 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 21:16:16 +0100 Subject: [PATCH 393/504] Modified workflow for doc --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 47cf9c5f..134ec9be 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ ###### Requirements without Version Specifiers ######` numpy -scipy==1.7 +scipy==1.9 dataclasses ruamel.yaml opencv-python From 4108f64e480efc5b94d0ce4fbbfd3a32dea5646d Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 21:21:07 +0100 Subject: [PATCH 394/504] Modified requirements for doc --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 134ec9be..b04f3ec1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ ###### Requirements without Version Specifiers ######` numpy -scipy==1.9 +scipy==1.9.2 dataclasses ruamel.yaml opencv-python From ed94ac7762f23b00a43c508b5071090729f9615a Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 21:25:24 +0100 Subject: [PATCH 395/504] Added requirements for docs --- .github/workflows/documentation.yml | 2 +- docs/requirements.txt | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 docs/requirements.txt diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 12d4de2f..2e91434d 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -9,7 +9,7 @@ jobs: - name: Install dependencies run: | pip install sphinx sphinx_rtd_theme sphinx-copybutton - pip install -r requirements.txt + pip install -r docs/requirements.txt - name: Sphinx build run: | sphinx-build docs/source docs/_build diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..4e69f120 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,14 @@ +###### Requirements without Version Specifiers ######` +numpy +scipy +dataclasses +ruamel.yaml +opencv-python +simple-parsing +scikit-image +matplotlib +catkin-tools +# cupy + +###### Requirements with Version Specifiers ######` +shapely==1.7.1 From aec50afc63ee8eade10d5c83ad7f6e6dde9138b7 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 21:31:03 +0100 Subject: [PATCH 396/504] Modified requirements for docs --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 4e69f120..ea77e852 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -11,4 +11,4 @@ catkin-tools # cupy ###### Requirements with Version Specifiers ######` -shapely==1.7.1 +# shapely==1.7.1 From 0eed131f676f223a15dcbb5ea3473e558d25c17a Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 21:34:20 +0100 Subject: [PATCH 397/504] Modified requirements for docs --- .github/workflows/documentation.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 2e91434d..2ee743fd 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -10,6 +10,7 @@ jobs: run: | pip install sphinx sphinx_rtd_theme sphinx-copybutton pip install -r docs/requirements.txt + pip install elevation_mapping_cupy/. - name: Sphinx build run: | sphinx-build docs/source docs/_build From 02b760aa8ab94cc5abd1692a017eb131f500d482 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 21:36:50 +0100 Subject: [PATCH 398/504] Modified requirements for docs --- docs/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/requirements.txt b/docs/requirements.txt index ea77e852..5498636f 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -8,6 +8,7 @@ simple-parsing scikit-image matplotlib catkin-tools +catkin_pkg # cupy ###### Requirements with Version Specifiers ######` From 0277c9510b22e39c29bfa86403546ec39d911753 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 22:06:51 +0100 Subject: [PATCH 399/504] Added some mock import --- .github/workflows/documentation.yml | 1 - docs/source/conf.py | 22 ++++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 2ee743fd..2e91434d 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -10,7 +10,6 @@ jobs: run: | pip install sphinx sphinx_rtd_theme sphinx-copybutton pip install -r docs/requirements.txt - pip install elevation_mapping_cupy/. - name: Sphinx build run: | sphinx-build docs/source docs/_build diff --git a/docs/source/conf.py b/docs/source/conf.py index c2b0da13..96a46b57 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -8,8 +8,26 @@ import os, sys -sys.path.insert(0, os.path.abspath("../../elevation_mapping_cupy")) -sys.path.insert(0, os.path.abspath("../../sensor_processing/semantic_sensor")) +sys.path.append(os.path.join(os.path.dirname(__file__), '../../elevation_mapping_cupy/script')) +sys.path.append(os.path.join(os.path.dirname(__file__), '../../sensor_processing/semantic_sensor/script')) + +autodoc_mock_imports = [ + "cupy" + "numpy", + "scipy", + "dataclasses", + "ruamel.yaml", + "opencv-python", + "simple-parsing", + "scikit-image", + "matplotlib", + "catkin-tools", + "catkin_pkg", + "detectron", + "torch", + "shapely", + "simple_parsing", + ] on_rtd = os.environ.get("READTHEDOCS", None) == "True" From 4ca9ba8d95b71b7945085636b38a87d1ff5a7489 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 22:13:07 +0100 Subject: [PATCH 400/504] Added some mock import --- docs/source/conf.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 96a46b57..d9e6ffad 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -12,7 +12,9 @@ sys.path.append(os.path.join(os.path.dirname(__file__), '../../sensor_processing/semantic_sensor/script')) autodoc_mock_imports = [ - "cupy" + "cupy", + "rospy", + "torchvision", "numpy", "scipy", "dataclasses", @@ -61,7 +63,7 @@ "prev_next_buttons_location": "bottom", "style_external_links": False, "vcs_pageview_mode": "", - "style_nav_header_background": "#A00000", + # "style_nav_header_background": "#A00000", # Toc options "collapse_navigation": True, "sticky_navigation": True, From 5f850198cfb9fe0fc48ed076543f13f43e5e03a2 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 22:15:18 +0100 Subject: [PATCH 401/504] Added some mock import --- docs/source/conf.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index d9e6ffad..2d0c9090 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -13,10 +13,13 @@ autodoc_mock_imports = [ "cupy", + "cupyx", "rospy", + "ros_numpy" "torchvision", "numpy", "scipy", + "sklearn", "dataclasses", "ruamel.yaml", "opencv-python", @@ -25,7 +28,7 @@ "matplotlib", "catkin-tools", "catkin_pkg", - "detectron", + "detectron2", "torch", "shapely", "simple_parsing", From f60fdddbeeebadbadc0118b313e66107d3862777 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 22:22:26 +0100 Subject: [PATCH 402/504] Added some comments to parameters.py --- .../elevation_mapping_cupy/parameter.py | 178 +++++++++++------- 1 file changed, 109 insertions(+), 69 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 569bca66..b451149e 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -12,7 +12,10 @@ @dataclass class Parameter(Serializable): - resolution: float = 0.04 + """ + This class holds the parameters for the elevation mapping algorithm. + """ + resolution: float = 0.04 # resolution in m. subscriber_cfg: dict = field( default_factory=lambda: { "front_cam": { @@ -21,8 +24,8 @@ class Parameter(Serializable): "data_type": "pointcloud", } } - ) - additional_layers: list = field(default_factory=lambda: ["color"]) + ) # configuration for the subscriber + additional_layers: list = field(default_factory=lambda: ["color"]) # additional layers for the map fusion_algorithms: list = field( default_factory=lambda: [ "image_color", @@ -34,76 +37,82 @@ class Parameter(Serializable): "pointcloud_class_max", "pointcloud_color", ] - ) - pointcloud_channel_fusions: dict = field(default_factory=lambda: {"rgb": "color", "default": "class_average"}) - image_channel_fusions: dict = field(default_factory=lambda: {"rgb": "color", "default": "exponential"}) - data_type: str = np.float32 - average_weight: float = 0.5 - - map_length: float = 8.0 - sensor_noise_factor: float = 0.05 - mahalanobis_thresh: float = 2.0 - outlier_variance: float = 0.01 - drift_compensation_variance_inlier: float = 0.1 - time_variance: float = 0.01 - time_interval: float = 0.1 - - max_variance: float = 1.0 - dilation_size: float = 2 - dilation_size_initialize: float = 10 - drift_compensation_alpha: float = 1.0 - - traversability_inlier: float = 0.1 - wall_num_thresh: float = 100 - min_height_drift_cnt: float = 100 - - max_ray_length: float = 2.0 - cleanup_step: float = 0.01 - cleanup_cos_thresh: float = 0.5 - min_valid_distance: float = 0.3 - max_height_range: float = 1.0 - ramped_height_range_a: float = 0.3 - ramped_height_range_b: float = 1.0 - ramped_height_range_c: float = 0.2 - - safe_thresh: float = 0.5 - safe_min_thresh: float = 0.5 - max_unsafe_n: int = 20 - checker_layer: str = "traversability" - - min_filter_size: int = 5 - min_filter_iteration: int = 3 - - max_drift: float = 0.10 - - overlap_clear_range_xy: float = 4.0 - overlap_clear_range_z: float = 2.0 - - enable_edge_sharpen: bool = True - enable_drift_compensation: bool = True - enable_visibility_cleanup: bool = True - enable_overlap_clearance: bool = True - use_only_above_for_upper_bound: bool = True - use_chainer: bool = True - position_noise_thresh: float = 0.1 - orientation_noise_thresh: float = 0.1 - - plugin_config_file: str = "config/plugin_config.yaml" - weight_file: str = "config/weights.dat" - - initial_variance: float = 10.0 - initialized_variance: float = 10.0 - w1: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) - w2: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) - w3: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) - w_out: np.ndarray = field(default_factory=lambda: np.zeros((1, 12, 1, 1))) + ) # list of fusion algorithms + pointcloud_channel_fusions: dict = field(default_factory=lambda: {"rgb": "color", "default": "class_average"}) # fusion for pointcloud channels + image_channel_fusions: dict = field(default_factory=lambda: {"rgb": "color", "default": "exponential"}) # fusion for image channels + data_type: str = np.float32 # data type for the map + average_weight: float = 0.5 # weight for the average fusion + + map_length: float = 8.0 # map's size in m. + sensor_noise_factor: float = 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). + mahalanobis_thresh: float = 2.0 # points outside this distance is outlier. + outlier_variance: float = 0.01 # if point is outlier, add this value to the cell. + drift_compensation_variance_inlier: float = 0.1 # cells under this value is used for drift compensation. + time_variance: float = 0.01 # add this value when update_variance is called. + time_interval: float = 0.1 # Time layer is updated with this interval. + + max_variance: float = 1.0 # maximum variance for each cell. + dilation_size: float = 2 # dilation filter size before traversability filter. + dilation_size_initialize: float = 10 # dilation size after the init. + drift_compensation_alpha: float = 1.0 # drift compensation alpha for smoother update of drift compensation. + + traversability_inlier: float = 0.1 # cells with higher traversability are used for drift compensation. + wall_num_thresh: float = 100 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. + min_height_drift_cnt: float = 100 # drift compensation only happens if the valid cells are more than this number. + + max_ray_length: float = 2.0 # maximum length for ray tracing. + cleanup_step: float = 0.01 # substitute this value from validity layer at visibility cleanup. + cleanup_cos_thresh: float = 0.5 # substitute this value from validity layer at visibility cleanup. + min_valid_distance: float = 0.3 # points with shorter distance will be filtered out. + max_height_range: float = 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. + ramped_height_range_a: float = 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_b: float = 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_c: float = 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + + safe_thresh: float = 0.5 # if traversability is smaller, it is counted as unsafe cell. + safe_min_thresh: float = 0.5 # polygon is unsafe if there exists lower traversability than this. + max_unsafe_n: int = 20 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + checker_layer: str = "traversability" # layer used for checking safety + + min_filter_size: int = 5 # minimum size for the filter + min_filter_iteration: int = 3 # minimum number of iterations for the filter + + max_drift: float = 0.10 # maximum drift for the compensation + + overlap_clear_range_xy: float = 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) + overlap_clear_range_z: float = 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + + enable_edge_sharpen: bool = True # enable edge sharpening + enable_drift_compensation: bool = True # enable drift compensation + enable_visibility_cleanup: bool = True # enable visibility cleanup + enable_overlap_clearance: bool = True # enable overlap clearance + use_only_above_for_upper_bound: bool = True # use only above for upper bound + use_chainer: bool = True # use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. + position_noise_thresh: float = 0.1 # if the position change is bigger than this value, the drift compensation happens. + orientation_noise_thresh: float = 0.1 # if the orientation change is bigger than this value, the drift compensation happens. + + plugin_config_file: str = "config/plugin_config.yaml" # configuration file for the plugin + weight_file: str = "config/weights.dat" # weight file for traversability filter + + initial_variance: float = 10.0 # initial variance for each cell. + initialized_variance: float = 10.0 # initialized variance for each cell. + w1: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the first layer + w2: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the second layer + w3: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the third layer + w_out: np.ndarray = field(default_factory=lambda: np.zeros((1, 12, 1, 1))) # weights for the output layer # # not configurable params - true_map_length: float = None - cell_n: int = None - true_cell_n: int = None + true_map_length: float = None # true length of the map + cell_n: int = None # number of cells in the map + true_cell_n: int = None # true number of cells in the map def load_weights(self, filename): + """ + Load weights from a file into the model's parameters. + + Args: + filename (str): The path to the file containing the weights. + """ with open(filename, "rb") as file: weights = pickle.load(file) self.w1 = weights["conv1.weight"] @@ -112,18 +121,49 @@ def load_weights(self, filename): self.w_out = weights["conv_final.weight"] def get_names(self): + """ + Get the names of the parameters. + + Returns: + list: A list of parameter names. + """ return list(self.__annotations__.keys()) def get_types(self): + """ + Get the types of the parameters. + + Returns: + list: A list of parameter types. + """ return [v.__name__ for v in self.__annotations__.values()] def set_value(self, name, value): + """ + Set the value of a parameter. + + Args: + name (str): The name of the parameter. + value (any): The new value for the parameter. + """ setattr(self, name, value) def get_value(self, name): + """ + Get the value of a parameter. + + Args: + name (str): The name of the parameter. + + Returns: + any: The value of the parameter. + """ return getattr(self, name) def update(self): + """ + Update the parameters related to the map size and resolution. + """ # +2 is a border for outside map self.cell_n = int(round(self.map_length / self.resolution)) + 2 self.true_cell_n = round(self.map_length / self.resolution) From bf20e73c8bbe5b57957fe52da204a84fe776c410 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 22:31:27 +0100 Subject: [PATCH 403/504] Added some comments to parameters.py --- .../script/elevation_mapping_cupy/parameter.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index b451149e..c4cb97b4 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -12,9 +12,6 @@ @dataclass class Parameter(Serializable): - """ - This class holds the parameters for the elevation mapping algorithm. - """ resolution: float = 0.04 # resolution in m. subscriber_cfg: dict = field( default_factory=lambda: { From f20080e1785e40f72753a89c19203aea1990ab0c Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 22:37:52 +0100 Subject: [PATCH 404/504] Added some comments to parameters.py --- .../elevation_mapping_cupy/parameter.py | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index c4cb97b4..e106cabc 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -12,6 +12,69 @@ @dataclass class Parameter(Serializable): + """ + This class holds the parameters for the elevation mapping algorithm. + + Attributes: + resolution (float): resolution in m. + subscriber_cfg (dict): configuration for the subscriber. + additional_layers (list): additional layers for the map. + fusion_algorithms (list): list of fusion algorithms. + pointcloud_channel_fusions (dict): fusion for pointcloud channels. + image_channel_fusions (dict): fusion for image channels. + data_type (str): data type for the map. + average_weight (float): weight for the average fusion. + map_length (float): map's size in m. + sensor_noise_factor (float): point's noise is sensor_noise_factor*z^2 (z is distance from sensor). + mahalanobis_thresh (float): points outside this distance is outlier. + outlier_variance (float): if point is outlier, add this value to the cell. + drift_compensation_variance_inlier (float): cells under this value is used for drift compensation. + time_variance (float): add this value when update_variance is called. + time_interval (float): Time layer is updated with this interval. + max_variance (float): maximum variance for each cell. + dilation_size (float): dilation filter size before traversability filter. + dilation_size_initialize (float): dilation size after the init. + drift_compensation_alpha (float): drift compensation alpha for smoother update of drift compensation. + traversability_inlier (float): cells with higher traversability are used for drift compensation. + wall_num_thresh (float): if there are more points than this value, only higher points than the current height are used to make the wall more sharp. + min_height_drift_cnt (float): drift compensation only happens if the valid cells are more than this number. + max_ray_length (float): maximum length for ray tracing. + cleanup_step (float): substitute this value from validity layer at visibility cleanup. + cleanup_cos_thresh (float): substitute this value from validity layer at visibility cleanup. + min_valid_distance (float): points with shorter distance will be filtered out. + max_height_range: float = 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. + ramped_height_range_a: float = 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_b: float = 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_c: float = 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + safe_thresh: float = 0.5 # if traversability is smaller, it is counted as unsafe cell. + safe_min_thresh: float = 0.5 # polygon is unsafe if there exists lower traversability than this. + max_unsafe_n: int = 20 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + checker_layer: str = "traversability" # layer used for checking safety + min_filter_size: int = 5 # minimum size for the filter + min_filter_iteration: int = 3 # minimum number of iterations for the filter + max_drift: float = 0.10 # maximum drift for the compensation + overlap_clear_range_xy: float = 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) + overlap_clear_range_z: float = 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + enable_edge_sharpen: bool = True # enable edge sharpening + enable_drift_compensation: bool = True # enable drift compensation + enable_visibility_cleanup: bool = True # enable visibility cleanup + enable_overlap_clearance: bool = True # enable overlap clearance + use_only_above_for_upper_bound: bool = True # use only above for upper bound + use_chainer: bool = True # use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. + position_noise_thresh: float = 0.1 # if the position change is bigger than this value, the drift compensation happens. + orientation_noise_thresh: float = 0.1 # if the orientation change is bigger than this value, the drift compensation happens. + plugin_config_file: str = "config/plugin_config.yaml" # configuration file for the plugin + weight_file: str = "config/weights.dat" # weight file for traversability filter + initial_variance: float = 10.0 # initial variance for each cell. + initialized_variance: float = 10.0 # initialized variance for each cell. + w1: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the first layer + w2: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the second layer + w3: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the third layer + w_out: np.ndarray = field(default_factory=lambda: np.zeros((1, 12, 1, 1))) # weights for the output layer + true_map_length: float = None # true length of the map + cell_n: int = None # number of cells in the map + true_cell_n: int = None # true number of cells in the map + """ resolution: float = 0.04 # resolution in m. subscriber_cfg: dict = field( default_factory=lambda: { From 55a1396ed6919575115934dac039693b219ab15c Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 6 Dec 2023 23:07:31 +0100 Subject: [PATCH 405/504] Updated some docstring for parameters. --- .../elevation_mapping_cupy/parameter.py | 175 ++++++++++++------ 1 file changed, 117 insertions(+), 58 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index e106cabc..5fc3c110 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -16,64 +16,123 @@ class Parameter(Serializable): This class holds the parameters for the elevation mapping algorithm. Attributes: - resolution (float): resolution in m. - subscriber_cfg (dict): configuration for the subscriber. - additional_layers (list): additional layers for the map. - fusion_algorithms (list): list of fusion algorithms. - pointcloud_channel_fusions (dict): fusion for pointcloud channels. - image_channel_fusions (dict): fusion for image channels. - data_type (str): data type for the map. - average_weight (float): weight for the average fusion. - map_length (float): map's size in m. - sensor_noise_factor (float): point's noise is sensor_noise_factor*z^2 (z is distance from sensor). - mahalanobis_thresh (float): points outside this distance is outlier. - outlier_variance (float): if point is outlier, add this value to the cell. - drift_compensation_variance_inlier (float): cells under this value is used for drift compensation. - time_variance (float): add this value when update_variance is called. - time_interval (float): Time layer is updated with this interval. - max_variance (float): maximum variance for each cell. - dilation_size (float): dilation filter size before traversability filter. - dilation_size_initialize (float): dilation size after the init. - drift_compensation_alpha (float): drift compensation alpha for smoother update of drift compensation. - traversability_inlier (float): cells with higher traversability are used for drift compensation. - wall_num_thresh (float): if there are more points than this value, only higher points than the current height are used to make the wall more sharp. - min_height_drift_cnt (float): drift compensation only happens if the valid cells are more than this number. - max_ray_length (float): maximum length for ray tracing. - cleanup_step (float): substitute this value from validity layer at visibility cleanup. - cleanup_cos_thresh (float): substitute this value from validity layer at visibility cleanup. - min_valid_distance (float): points with shorter distance will be filtered out. - max_height_range: float = 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. - ramped_height_range_a: float = 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - ramped_height_range_b: float = 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - ramped_height_range_c: float = 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - safe_thresh: float = 0.5 # if traversability is smaller, it is counted as unsafe cell. - safe_min_thresh: float = 0.5 # polygon is unsafe if there exists lower traversability than this. - max_unsafe_n: int = 20 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. - checker_layer: str = "traversability" # layer used for checking safety - min_filter_size: int = 5 # minimum size for the filter - min_filter_iteration: int = 3 # minimum number of iterations for the filter - max_drift: float = 0.10 # maximum drift for the compensation - overlap_clear_range_xy: float = 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) - overlap_clear_range_z: float = 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - enable_edge_sharpen: bool = True # enable edge sharpening - enable_drift_compensation: bool = True # enable drift compensation - enable_visibility_cleanup: bool = True # enable visibility cleanup - enable_overlap_clearance: bool = True # enable overlap clearance - use_only_above_for_upper_bound: bool = True # use only above for upper bound - use_chainer: bool = True # use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. - position_noise_thresh: float = 0.1 # if the position change is bigger than this value, the drift compensation happens. - orientation_noise_thresh: float = 0.1 # if the orientation change is bigger than this value, the drift compensation happens. - plugin_config_file: str = "config/plugin_config.yaml" # configuration file for the plugin - weight_file: str = "config/weights.dat" # weight file for traversability filter - initial_variance: float = 10.0 # initial variance for each cell. - initialized_variance: float = 10.0 # initialized variance for each cell. - w1: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the first layer - w2: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the second layer - w3: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the third layer - w_out: np.ndarray = field(default_factory=lambda: np.zeros((1, 12, 1, 1))) # weights for the output layer - true_map_length: float = None # true length of the map - cell_n: int = None # number of cells in the map - true_cell_n: int = None # true number of cells in the map + resolution: The resolution in meters. + (Default: ``0.04``) + subscriber_cfg: The configuration for the subscriber. + (Default: ``{ "front_cam": { "channels": ["rgb", "person"], "topic_name": "/elevation_mapping/pointcloud_semantic", "data_type": "pointcloud", } }``) + additional_layers: The additional layers for the map. + (Default: ``["color"]``) + fusion_algorithms: The list of fusion algorithms. + (Default: ``[ "image_color", "image_exponential", "pointcloud_average", "pointcloud_bayesian_inference", "pointcloud_class_average", "pointcloud_class_bayesian", "pointcloud_class_max", "pointcloud_color", ]``) + pointcloud_channel_fusions: The fusion for pointcloud channels. + (Default: ``{"rgb": "color", "default": "class_average"}``) + image_channel_fusions: The fusion for image channels. + (Default: ``{"rgb": "color", "default": "exponential"}``) + data_type: The data type for the map. + (Default: ``np.float32``) + average_weight: The weight for the average fusion. + (Default: ``0.5``) + map_length: The map's size in meters. + (Default: ``8.0``) + sensor_noise_factor: The point's noise is sensor_noise_factor*z^2 (z is distance from sensor). + (Default: ``0.05``) + mahalanobis_thresh: Points outside this distance is outlier. + (Default: ``2.0``) + outlier_variance: If point is outlier, add this value to the cell. + (Default: ``0.01``) + drift_compensation_variance_inlier: Cells under this value is used for drift compensation. + (Default: ``0.1``) + time_variance: Add this value when update_variance is called. + (Default: ``0.01``) + time_interval: Time layer is updated with this interval. + (Default: ``0.1``) + max_variance: The maximum variance for each cell. + (Default: ``1.0``) + dilation_size: The dilation filter size before traversability filter. + (Default: ``2``) + dilation_size_initialize: The dilation size after the init. + (Default: ``10``) + drift_compensation_alpha: The drift compensation alpha for smoother update of drift compensation. + (Default: ``1.0``) + traversability_inlier: Cells with higher traversability are used for drift compensation. + (Default: ``0.1``) + wall_num_thresh: If there are more points than this value, only higher points than the current height are used to make the wall more sharp. + (Default: ``100``) + min_height_drift_cnt: Drift compensation only happens if the valid cells are more than this number. + (Default: ``100``) + max_ray_length: The maximum length for ray tracing. + (Default: ``2.0``) + cleanup_step: Substitute this value from validity layer at visibility cleanup. + (Default: ``0.01``) + cleanup_cos_thresh: Substitute this value from validity layer at visibility cleanup. + (Default: ``0.5``) + min_valid_distance: Points with shorter distance will be filtered out. + (Default: ``0.3``) + max_height_range: Points higher than this value from sensor will be filtered out to disable ceiling. + (Default: ``1.0``) + ramped_height_range_a: If z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + (Default: ``0.3``) + ramped_height_range_b: If z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + (Default: ``1.0``) + ramped_height_range_c: If z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + (Default: ``0.2``) + safe_thresh: If traversability is smaller, it is counted as unsafe cell. + (Default: ``0.5``) + safe_min_thresh: Polygon is unsafe if there exists lower traversability than this. + (Default: ``0.5``) + max_unsafe_n: If the number of cells under safe_thresh exceeds this value, polygon is unsafe. + (Default: ``20``) + checker_layer: Layer used for checking safety. + (Default: ``"traversability"``) + min_filter_size: The minimum size for the filter. + (Default: ``5``) + min_filter_iteration: The minimum number of iterations for the filter. + (Default: ``3``) + max_drift: The maximum drift for the compensation. + (Default: ``0.10``) + overlap_clear_range_xy: XY range [m] for clearing overlapped area. This defines the valid area for overlap clearance. (used for multi floor setting) + (Default: ``4.0``) + overlap_clear_range_z: Z range [m] for clearing overlapped area. Cells outside this range will be cleared. (used for multi floor setting) + (Default: ``2.0``) + enable_edge_sharpen: Enable edge sharpening. + (Default: ``True``) + enable_drift_compensation: Enable drift compensation. + (Default: ``True``) + enable_visibility_cleanup: Enable visibility cleanup. + (Default: ``True``) + enable_overlap_clearance: Enable overlap clearance. + (Default: ``True``) + use_only_above_for_upper_bound: Use only above for upper bound. + (Default: ``True``) + use_chainer: Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. Pytorch requires ~2GB more GPU memory compared to chainer but runs faster. + (Default: ``True``) + position_noise_thresh: If the position change is bigger than this value, the drift compensation happens. + (Default: ``0.1``) + orientation_noise_thresh: If the orientation change is bigger than this value, the drift compensation happens. + (Default: ``0.1``) + plugin_config_file: Configuration file for the plugin. + (Default: ``"config/plugin_config.yaml"``) + weight_file: Weight file for traversability filter. + (Default: ``"config/weights.dat"``) + initial_variance: Initial variance for each cell. + (Default: ``10.0``) + initialized_variance: Initialized variance for each cell. + (Default: ``10.0``) + w1: Weights for the first layer. + (Default: ``np.zeros((4, 1, 3, 3))``) + w2: Weights for the second layer. + (Default: ``np.zeros((4, 1, 3, 3))``) + w3: Weights for the third layer. + (Default: ``np.zeros((4, 1, 3, 3))``) + w_out: Weights for the output layer. + (Default: ``np.zeros((1, 12, 1, 1))``) + true_map_length: True length of the map. + (Default: ``None``) + cell_n: Number of cells in the map. + (Default: ``None``) + true_cell_n: True number of cells in the map. + (Default: ``None``) + """ resolution: float = 0.04 # resolution in m. subscriber_cfg: dict = field( From 5319782fb12b7e39724b8c9889fa402a55668abf Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 7 Dec 2023 17:31:34 +0100 Subject: [PATCH 406/504] Renamed dockerfile. --- docker/{Dockerfile.x86 => Dockerfile.x64} | 0 docker/build.sh | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename docker/{Dockerfile.x86 => Dockerfile.x64} (100%) diff --git a/docker/Dockerfile.x86 b/docker/Dockerfile.x64 similarity index 100% rename from docker/Dockerfile.x86 rename to docker/Dockerfile.x64 diff --git a/docker/build.sh b/docker/build.sh index 0cd07383..1d92a220 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -1,3 +1,3 @@ #! /bin/bash home=`realpath "$(dirname "$0")"/../` -cd $home && sudo docker build -t elevation_mapping_cupy -f docker/Dockerfile.x86 --no-cache . \ No newline at end of file +cd $home && sudo docker build -t elevation_mapping_cupy -f docker/Dockerfile.x64 --no-cache . \ No newline at end of file From 66d029ae784614717abfa2dd702648a8dbc8a696 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 7 Dec 2023 17:58:13 +0100 Subject: [PATCH 407/504] Updated run script to use docker image from the registry. --- README.md | 2 +- docker/run.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9a729ce9..8f67ba5f 100644 --- a/README.md +++ b/README.md @@ -85,10 +85,10 @@ git clone https://github.com/leggedrobotics/elevation_mapping_cupy.git Then install dependencies. You can also use docker which already install all dependencies. +When you run the script it should pull the image. ```zsh cd docker -./build.sh ./run.sh ``` diff --git a/docker/run.sh b/docker/run.sh index 32587aa0..125928fd 100755 --- a/docker/run.sh +++ b/docker/run.sh @@ -1,5 +1,5 @@ #!/bin/bash -IMAGE_NAME="elevation_mapping_cupy:latest" +IMAGE_NAME="mktk1117/elevation_mapping_cupy:latest" # Define environment variables for enabling graphical output for the container. XSOCK=/tmp/.X11-unix From 689b86f7f55f77c275d26b846b086e7c5893e28e Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 7 Dec 2023 17:59:57 +0100 Subject: [PATCH 408/504] Updated readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 8f67ba5f..e7321e72 100644 --- a/README.md +++ b/README.md @@ -87,11 +87,14 @@ Then install dependencies. You can also use docker which already install all dependencies. When you run the script it should pull the image. + ```zsh cd docker ./run.sh ``` +You can also build locally by running `build.sh`. + For more information, check [Document](https://leggedrobotics.github.io/elevation_mapping_cupy/getting_started/installation.html) ### Build package From 46c9b4423752bf7f32602ee8d5bad976e9dc3806 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 7 Dec 2023 21:08:49 +0100 Subject: [PATCH 409/504] Added OpenCV in CMakeLists.txt --- elevation_mapping_cupy/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index 2b4cc858..bc4cf6a0 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -4,6 +4,7 @@ project(elevation_mapping_cupy) find_package(PythonInterp 3 REQUIRED) find_package(PythonLibs 3 REQUIRED) +find_package(OpenCV REQUIRED) if(PYTHONLIBS_FOUND) message(STATUS "Using Python Libraries at: " ${PYTHON_LIBRARIES}) @@ -54,13 +55,14 @@ include_directories( ${PYTHON_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS} ${EIGEN3_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} ) add_library(elevation_mapping_ros src/elevation_mapping_wrapper.cpp src/elevation_mapping_ros.cpp) -target_link_libraries(elevation_mapping_ros ${PYTHON_LIBRARIES} ${catkin_LIBRARIES}) +target_link_libraries(elevation_mapping_ros ${PYTHON_LIBRARIES} ${catkin_LIBRARIES} ${OpenCV_LIBRARIES}) add_executable(elevation_mapping_node src/elevation_mapping_node.cpp) target_link_libraries(elevation_mapping_node elevation_mapping_ros) From 8093dfb6090f449bafc878198fafb025870532b6 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Thu, 7 Dec 2023 22:15:20 +0100 Subject: [PATCH 410/504] Updated requirements for jetson --- requirements.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index b04f3ec1..76a0b9d2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,10 @@ ###### Requirements without Version Specifiers ######` numpy -scipy==1.9.2 -dataclasses +scipy==1.7 ruamel.yaml opencv-python simple-parsing -scikit-image +scikit-image==0.19 matplotlib catkin-tools # cupy From 8fce9e4c3ff91423b685dcfa4654e6b1154561c4 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 20 Dec 2023 17:15:32 +0100 Subject: [PATCH 411/504] Added max layer filter. --- .../plugins/max_layer_filter.py | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py new file mode 100644 index 00000000..63c6a496 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py @@ -0,0 +1,122 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +from typing import List + +from elevation_mapping_cupy.plugins.plugin_manager import PluginBase + + +class MaxLayerFilter(PluginBase): + """Applies a maximum filter to the input layers and updates the traversability map. + This can be used to enhance navigation by identifying traversable areas. + + Args: + cell_n (int): The width and height of the elevation map. + layers (list): List of layers for semantic traversability. Default is ["traversability"]. + thresholds (list): List of thresholds for each layer. Default is [0.5]. + type (list): List of types for each layer. Default is ["traversability"]. + **kwargs: Additional keyword arguments. + """ + + def __init__( + self, + cell_n: int = 100, + layers: list = ["traversability"], + reverse: list = [True], + min_or_max: str = "max", + thresholds: list = [False], + default_value: float = 0.0, + **kwargs, + ): + super().__init__() + self.layers = layers + self.reverse = reverse + self.min_or_max = min_or_max + self.thresholds = thresholds + self.default_value = default_value + + def get_layer_data( + self, + elevation_map, + layer_names, + plugin_layers, + plugin_layer_names, + semantic_map, + semantic_layer_names, + name, + ): + if name in layer_names: + idx = layer_names.index(name) + layer = elevation_map[idx].copy() + elif name in plugin_layer_names: + idx = plugin_layer_names.index(name) + layer = plugin_layers[idx].copy() + elif name in semantic_layer_names: + idx = semantic_layer_names.index(name) + layer = semantic_map[idx].copy() + else: + print(f"Could not find layer {name}!") + layer = None + return layer + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], + *args, + ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): + *args (): + + Returns: + cupy._core.core.ndarray: + """ + layers = [] + for it, name in enumerate(self.layers): + layer = self.get_layer_data( + elevation_map, layer_names, plugin_layers, plugin_layer_names, semantic_map, semantic_layer_names, name + ) + if layer is None: + continue + if isinstance(self.default_value, float): + layer = cp.where(layer == 0.0, float(self.default_value), layer) + elif isinstance(self.default_value, str): + default_layer = self.get_layer_data( + elevation_map, + layer_names, + plugin_layers, + plugin_layer_names, + semantic_map, + semantic_layer_names, + self.default_value, + ) + layer = cp.where(layer == 0, default_layer, layer) + if self.reverse[it]: + layer = 1.0 - layer + if isinstance(self.thresholds[it], float): + layer = cp.where(layer > float(self.thresholds[it]), 1, 0) + layers.append(layer) + if len(layers) == 0: + print("No layers are found, returning traversability!") + idx = layer_names.index("traversability") + return elevation_map[idx] + result = cp.stack(layers, axis=0) + if self.min_or_max == "min": + result = cp.min(result, axis=0) + else: + result = cp.max(result, axis=0) + return result From a3f892f69b1675dce1596710e7a3d7fd087160dd Mon Sep 17 00:00:00 2001 From: Takahiro Date: Wed, 3 Jan 2024 17:35:11 +0100 Subject: [PATCH 412/504] Fixed a indentation bug in example_setup.yaml --- elevation_mapping_cupy/config/core/example_setup.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/config/core/example_setup.yaml b/elevation_mapping_cupy/config/core/example_setup.yaml index eb4aa3dd..a3f7a2f2 100644 --- a/elevation_mapping_cupy/config/core/example_setup.yaml +++ b/elevation_mapping_cupy/config/core/example_setup.yaml @@ -48,7 +48,7 @@ publishers: layers: ['elevation', 'traversability', 'variance','rgb'] basic_layers: ['elevation'] fps: 5.0 - elevation_map_recordable: + elevation_map_recordable: layers: ['elevation', 'traversability'] basic_layers: ['elevation', 'traversability'] fps: 2.0 From e6989e0986369443bc831967e81947788f293494 Mon Sep 17 00:00:00 2001 From: RobinSchmid7 Date: Mon, 8 Jan 2024 15:46:02 +0100 Subject: [PATCH 413/504] Added anomaly configs --- elevation_mapping_cupy/config/core/core_param.yaml | 4 ++-- .../config/setups/anymal/anymal_sensor_parameter.yaml | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 17baea09..f3cfa386 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -41,7 +41,7 @@ overlap_clear_range_xy: 4.0 # xy range [m] for clearing over overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) map_frame: 'odom' # The map frame where the odometry source uses. -base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. +base_frame: 'footprint' # The robot's base frame. This frame will be a center of the map. corrected_map_frame: 'odom' #### Feature toggles ######## @@ -62,7 +62,7 @@ use_only_above_for_upper_bound: false #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_frame_id: ['footprint'] # One tf (like ['footprint'] ) initializes a square around it. initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 2 # dilation size after the init. initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml index a130607f..26e3f7c3 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml @@ -18,7 +18,7 @@ image_channel_fusions: publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance', 'rgb'] + layers: ['elevation', 'traversability', 'variance', 'rgb', 'anomaly'] basic_layers: ['elevation', 'traversability'] fps: 5.0 @@ -73,4 +73,10 @@ subscribers: rear_bpearl: topic_name: /robot_self_filter/bpearl_rear/point_cloud - data_type: pointcloud \ No newline at end of file + data_type: pointcloud + + anomaly: + topic_name: "/wild_visual_navigation_node/front/traversability" + camera_info_topic_name: "/wild_visual_navigation_node/front/camera_info" + channel_info_topic_name: "/wild_visual_navigation_node/front/channel_info" + data_type: image \ No newline at end of file From 23a1f8eef05aa7c0798437a2ff3e5112ed504a94 Mon Sep 17 00:00:00 2001 From: RobinSchmid7 Date: Mon, 8 Jan 2024 18:24:11 +0100 Subject: [PATCH 414/504] reverted base footprint layer --- elevation_mapping_cupy/config/core/core_param.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index f3cfa386..17baea09 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -41,7 +41,7 @@ overlap_clear_range_xy: 4.0 # xy range [m] for clearing over overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) map_frame: 'odom' # The map frame where the odometry source uses. -base_frame: 'footprint' # The robot's base frame. This frame will be a center of the map. +base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. corrected_map_frame: 'odom' #### Feature toggles ######## @@ -62,7 +62,7 @@ use_only_above_for_upper_bound: false #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['footprint'] # One tf (like ['footprint'] ) initializes a square around it. +initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 2 # dilation size after the init. initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. From 084405f31b5448c78e61e53c928856c6aef823a5 Mon Sep 17 00:00:00 2001 From: RobinSchmid7 Date: Wed, 17 Jan 2024 15:49:12 +0100 Subject: [PATCH 415/504] Adding max filter and square filter --- .../plugins/max_layer_filter.py | 4 + .../plugins/sqrt_filter.py | 122 ++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/sqrt_filter.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py index 63c6a496..f6b2fc46 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py @@ -29,6 +29,7 @@ def __init__( min_or_max: str = "max", thresholds: list = [False], default_value: float = 0.0, + apply_sqrt: bool = True, **kwargs, ): super().__init__() @@ -37,6 +38,7 @@ def __init__( self.min_or_max = min_or_max self.thresholds = thresholds self.default_value = default_value + self.apply_sqrt = apply_sqrt def get_layer_data( self, @@ -119,4 +121,6 @@ def __call__( result = cp.min(result, axis=0) else: result = cp.max(result, axis=0) + if self.apply_sqrt: + result = cp.square(result) return result diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/sqrt_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/sqrt_filter.py new file mode 100644 index 00000000..63c6a496 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/sqrt_filter.py @@ -0,0 +1,122 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +from typing import List + +from elevation_mapping_cupy.plugins.plugin_manager import PluginBase + + +class MaxLayerFilter(PluginBase): + """Applies a maximum filter to the input layers and updates the traversability map. + This can be used to enhance navigation by identifying traversable areas. + + Args: + cell_n (int): The width and height of the elevation map. + layers (list): List of layers for semantic traversability. Default is ["traversability"]. + thresholds (list): List of thresholds for each layer. Default is [0.5]. + type (list): List of types for each layer. Default is ["traversability"]. + **kwargs: Additional keyword arguments. + """ + + def __init__( + self, + cell_n: int = 100, + layers: list = ["traversability"], + reverse: list = [True], + min_or_max: str = "max", + thresholds: list = [False], + default_value: float = 0.0, + **kwargs, + ): + super().__init__() + self.layers = layers + self.reverse = reverse + self.min_or_max = min_or_max + self.thresholds = thresholds + self.default_value = default_value + + def get_layer_data( + self, + elevation_map, + layer_names, + plugin_layers, + plugin_layer_names, + semantic_map, + semantic_layer_names, + name, + ): + if name in layer_names: + idx = layer_names.index(name) + layer = elevation_map[idx].copy() + elif name in plugin_layer_names: + idx = plugin_layer_names.index(name) + layer = plugin_layers[idx].copy() + elif name in semantic_layer_names: + idx = semantic_layer_names.index(name) + layer = semantic_map[idx].copy() + else: + print(f"Could not find layer {name}!") + layer = None + return layer + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], + *args, + ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): + *args (): + + Returns: + cupy._core.core.ndarray: + """ + layers = [] + for it, name in enumerate(self.layers): + layer = self.get_layer_data( + elevation_map, layer_names, plugin_layers, plugin_layer_names, semantic_map, semantic_layer_names, name + ) + if layer is None: + continue + if isinstance(self.default_value, float): + layer = cp.where(layer == 0.0, float(self.default_value), layer) + elif isinstance(self.default_value, str): + default_layer = self.get_layer_data( + elevation_map, + layer_names, + plugin_layers, + plugin_layer_names, + semantic_map, + semantic_layer_names, + self.default_value, + ) + layer = cp.where(layer == 0, default_layer, layer) + if self.reverse[it]: + layer = 1.0 - layer + if isinstance(self.thresholds[it], float): + layer = cp.where(layer > float(self.thresholds[it]), 1, 0) + layers.append(layer) + if len(layers) == 0: + print("No layers are found, returning traversability!") + idx = layer_names.index("traversability") + return elevation_map[idx] + result = cp.stack(layers, axis=0) + if self.min_or_max == "min": + result = cp.min(result, axis=0) + else: + result = cp.max(result, axis=0) + return result From 99bf682f666413be708e66e6c2ee9c0d33cb8388 Mon Sep 17 00:00:00 2001 From: Sergei Sergienko Date: Thu, 1 Feb 2024 11:09:32 +0300 Subject: [PATCH 416/504] fix: Updated included launch name in plane decomposition launch --- README.md | 13 +++++++------ .../turtlesim_plane_decomposition_example.launch | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e7321e72..975fba85 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,9 @@ [Documentation](https://leggedrobotics.github.io/elevation_mapping_cupy/) - ## Overview -The Elevaton Mapping CuPy software package represents an advancement in robotic navigation and locomotion. +The Elevaton Mapping CuPy software package represents an advancement in robotic navigation and locomotion. Integrating with the Robot Operating System (ROS) and utilizing GPU acceleration, this framework enhances point cloud registration and ray casting, crucial for efficient and accurate robotic movement, particularly in legged robots. ![screenshot](docs/media/main_repo.png) @@ -38,6 +37,7 @@ layers of the map. Finally the map can be post-processed with various custom plu external components (e.g. line detection). ## Citing + If you use the Elevation Mapping CuPy, please cite the following paper: Elevation Mapping for Locomotion and Navigation using GPU @@ -71,7 +71,7 @@ Gian Erni, Jonas Frey, Takahiro Miki, Matias Mattamala, Marco Hutter } ``` -## Quick instructions to run: +## Quick instructions to run ### Installation @@ -87,19 +87,19 @@ Then install dependencies. You can also use docker which already install all dependencies. When you run the script it should pull the image. - ```zsh cd docker ./run.sh ``` -You can also build locally by running `build.sh`. +You can also build locally by running `build.sh`, but in this case change `IMAGE_NAME` in `run.sh` to `elevation_mapping_cupy:latest`. For more information, check [Document](https://leggedrobotics.github.io/elevation_mapping_cupy/getting_started/installation.html) ### Build package Inside docker container. + ```zsh cd $HOME/catkin_ws catkin build elevation_mapping_cupy @@ -107,7 +107,8 @@ catkin build convex_plane_decomposition_ros # If you want to use plane segmenta catkin build semantic_sensor # If you want to use semantic sensors ``` -### Run turtlebot example. +### Run turtlebot example + ![Elevation map examples](docs/media/turtlebot.png) ```bash diff --git a/elevation_mapping_cupy/launch/turtlesim_plane_decomposition_example.launch b/elevation_mapping_cupy/launch/turtlesim_plane_decomposition_example.launch index 0cbd561b..09bfb7c9 100644 --- a/elevation_mapping_cupy/launch/turtlesim_plane_decomposition_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_plane_decomposition_example.launch @@ -3,7 +3,7 @@ - + From 6cf88aca82c6551e2083c81d7b41a997d501790f Mon Sep 17 00:00:00 2001 From: RobinSchmid7 Date: Mon, 12 Feb 2024 13:40:58 +0100 Subject: [PATCH 417/504] changes on jetson --- .../setups/anymal/anymal_sensor_parameter.yaml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml index 26e3f7c3..a14b08d0 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml @@ -18,10 +18,15 @@ image_channel_fusions: publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance', 'rgb', 'anomaly'] + layers: ['elevation', 'traversability', 'variance', 'rgb', 'anomaly', 'friction', 'stiffness', 'risk'] basic_layers: ['elevation', 'traversability'] fps: 5.0 + elevation_map_recordable: + layers: ['elevation', 'traversability', 'variance', 'rgb', 'anomaly', 'friction', 'stiffness', 'risk'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + filtered_elevation_map: layers: ['inpaint', 'smooth', 'min_filter'] basic_layers: ['inpaint'] @@ -75,8 +80,14 @@ subscribers: topic_name: /robot_self_filter/bpearl_rear/point_cloud data_type: pointcloud + traversability: + topic_name: "/hdr_camera/semantic_image" + camera_info_topic_name: "/hdr_camera/semantic_camera_info" + channel_info_topic_name: "/hdr_camera/image_channel_info" + data_type: image + anomaly: topic_name: "/wild_visual_navigation_node/front/traversability" camera_info_topic_name: "/wild_visual_navigation_node/front/camera_info" channel_info_topic_name: "/wild_visual_navigation_node/front/channel_info" - data_type: image \ No newline at end of file + data_type: image From cfb3fc76bd52546acb9ac5e74b001b379a8571df Mon Sep 17 00:00:00 2001 From: Takahiro Date: Sat, 24 Feb 2024 19:36:21 +0100 Subject: [PATCH 418/504] Moved get_layer_data to plugin manager base. Created erosion filter. --- .../config/core/plugin_config.yaml | 12 +- .../anymal/anymal_sensor_parameter.yaml | 2 +- .../elevation_mapping_cupy/plugins/erosion.py | 89 +++++++++++++ .../plugins/max_layer_filter.py | 55 ++++---- .../plugins/plugin_manager.py | 60 ++++++++- .../plugins/sqrt_filter.py | 122 ------------------ 6 files changed, 184 insertions(+), 156 deletions(-) create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/erosion.py delete mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/sqrt_filter.py diff --git a/elevation_mapping_cupy/config/core/plugin_config.yaml b/elevation_mapping_cupy/config/core/plugin_config.yaml index 7eb62c4c..efb29b27 100644 --- a/elevation_mapping_cupy/config/core/plugin_config.yaml +++ b/elevation_mapping_cupy/config/core/plugin_config.yaml @@ -25,4 +25,14 @@ inpainting: layer_name: "inpaint" extra_params: method: "telea" # telea or ns -# Apply smoothing for inpainted layer \ No newline at end of file +# Apply smoothing for inpainted layer +erosion: + enable: True + fill_nan: False + is_height_layer: False + layer_name: "erosion" + extra_params: + input_layer_name: "traversability" + dilation_size: 3 + iteration_n: 20 + reverse: True \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml index a130607f..7f5bec6b 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml @@ -23,7 +23,7 @@ publishers: fps: 5.0 filtered_elevation_map: - layers: ['inpaint', 'smooth', 'min_filter'] + layers: ['inpaint', 'smooth', 'min_filter', 'erosion'] basic_layers: ['inpaint'] fps: 5.0 diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/erosion.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/erosion.py new file mode 100644 index 00000000..b78497b4 --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/erosion.py @@ -0,0 +1,89 @@ +# +# Copyright (c) 2024, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cv2 as cv +import cupy as cp +import numpy as np + +from typing import List + +from .plugin_manager import PluginBase + + +class Erosion(PluginBase): + """ + This class is used for applying erosion to an elevation map or specific layers within it. + Erosion is a morphological operation that is used to remove small-scale details from a binary image. + + Args: + kernel_size (int): Size of the erosion kernel. Default is 3, which means a 3x3 square kernel. + iterations (int): Number of times erosion is applied. Default is 1. + **kwargs (): Additional keyword arguments. + """ + + def __init__( + self, + input_layer_name="traversability", + kernel_size: int = 3, + iterations: int = 1, + reverse: bool = False, + **kwargs, + ): + super().__init__() + self.input_layer_name = input_layer_name + self.kernel_size = kernel_size + self.iterations = iterations + self.reverse = reverse + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], + *args, + ) -> cp.ndarray: + """ + Applies erosion to the given elevation map. + + Args: + elevation_map (cupy._core.core.ndarray): The elevation map to be eroded. + layer_names (List[str]): Names of the layers in the elevation map. + plugin_layers (cupy._core.core.ndarray): Layers provided by other plugins. + plugin_layer_names (List[str]): Names of the layers provided by other plugins. + *args (): Additional arguments. + + Returns: + cupy._core.core.ndarray: The eroded elevation map. + """ + # Convert the elevation map to a format suitable for erosion (if necessary) + layer_data = self.get_layer_data( + elevation_map, + layer_names, + plugin_layers, + plugin_layer_names, + semantic_map, + semantic_layer_names, + self.input_layer_name, + ) + layer_np = cp.asnumpy(layer_data) + + # Define the erosion kernel + kernel = np.ones((self.kernel_size, self.kernel_size), np.uint8) + + if self.reverse: + layer_np = 1 - layer_np + # Apply erosion + layer_min = float(layer_np.min()) + layer_max = float(layer_np.max()) + layer_np_normalized = ((layer_np - layer_min) * 255 / (layer_max - layer_min)).astype("uint8") + eroded_map_np = cv.erode(layer_np_normalized, kernel, iterations=self.iterations) + eroded_map_np = eroded_map_np.astype(np.float32) * (layer_max - layer_min) / 255 + layer_min + if self.reverse: + eroded_map_np = 1 - eroded_map_np + + # Convert back to cupy array and return + return cp.asarray(eroded_map_np) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py index f6b2fc46..3b3dc3c6 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py @@ -15,9 +15,10 @@ class MaxLayerFilter(PluginBase): Args: cell_n (int): The width and height of the elevation map. + reverse (list): A list of boolean values indicating whether to reverse the filter operation for each layer. Default is [True]. + min_or_max (str): A string indicating whether to apply a minimum or maximum filter. Accepts "min" or "max". Default is "max". layers (list): List of layers for semantic traversability. Default is ["traversability"]. - thresholds (list): List of thresholds for each layer. Default is [0.5]. - type (list): List of types for each layer. Default is ["traversability"]. + thresholds (list): List of thresholds for each layer. If the value is bigger than a threshold, assign 1.0 otherwise 0.0. If it is False, it does not apply. Default is [False]. **kwargs: Additional keyword arguments. """ @@ -29,7 +30,6 @@ def __init__( min_or_max: str = "max", thresholds: list = [False], default_value: float = 0.0, - apply_sqrt: bool = True, **kwargs, ): super().__init__() @@ -38,31 +38,30 @@ def __init__( self.min_or_max = min_or_max self.thresholds = thresholds self.default_value = default_value - self.apply_sqrt = apply_sqrt - def get_layer_data( - self, - elevation_map, - layer_names, - plugin_layers, - plugin_layer_names, - semantic_map, - semantic_layer_names, - name, - ): - if name in layer_names: - idx = layer_names.index(name) - layer = elevation_map[idx].copy() - elif name in plugin_layer_names: - idx = plugin_layer_names.index(name) - layer = plugin_layers[idx].copy() - elif name in semantic_layer_names: - idx = semantic_layer_names.index(name) - layer = semantic_map[idx].copy() - else: - print(f"Could not find layer {name}!") - layer = None - return layer + # def get_layer_data( + # self, + # elevation_map, + # layer_names, + # plugin_layers, + # plugin_layer_names, + # semantic_map, + # semantic_layer_names, + # name, + # ): + # if name in layer_names: + # idx = layer_names.index(name) + # layer = elevation_map[idx].copy() + # elif name in plugin_layer_names: + # idx = plugin_layer_names.index(name) + # layer = plugin_layers[idx].copy() + # elif name in semantic_layer_names: + # idx = semantic_layer_names.index(name) + # layer = semantic_map[idx].copy() + # else: + # print(f"Could not find layer {name}!") + # layer = None + # return layer def __call__( self, @@ -121,6 +120,4 @@ def __call__( result = cp.min(result, axis=0) else: result = cp.max(result, axis=0) - if self.apply_sqrt: - result = cp.square(result) return result diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py index 8ff9fda1..26f81d21 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py @@ -4,7 +4,7 @@ # from abc import ABC import cupy as cp -from typing import List, Dict +from typing import List, Dict, Optional import importlib import inspect from dataclasses import dataclass @@ -39,6 +39,8 @@ def __call__( layer_names: List[str], plugin_layers: cp.ndarray, plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], *args, **kwargs, ) -> cp.ndarray: @@ -50,6 +52,8 @@ def __call__( layer_names (): plugin_layers (): plugin_layer_names (): + semantic_map (): + semantic_layer_names (): Run your processing here and return the result. layer of elevation_map 0: elevation @@ -64,6 +68,45 @@ def __call__( """ pass + def get_layer_data( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], + name: str, + ) -> Optional[cp.ndarray]: + """ + Retrieve a copy of the layer data from the elevation, plugin, or semantic maps based on the layer name. + + Args: + elevation_map (cp.ndarray): The elevation map containing various layers. + layer_names (List[str]): A list of names for each layer in the elevation map. + plugin_layers (cp.ndarray): The plugin layers containing additional data. + plugin_layer_names (List[str]): A list of names for each layer in the plugin layers. + semantic_map (cp.ndarray): The semantic map containing various layers. + semantic_layer_names (List[str]): A list of names for each layer in the semantic map. + name (str): The name of the layer to retrieve. + + Returns: + Optional[cp.ndarray]: A copy of the requested layer as a cupy ndarray if found, otherwise None. + """ + if name in layer_names: + idx = layer_names.index(name) + layer = elevation_map[idx].copy() + elif name in plugin_layer_names: + idx = plugin_layer_names.index(name) + layer = plugin_layers[idx].copy() + elif name in semantic_layer_names: + idx = semantic_layer_names.index(name) + layer = semantic_map[idx].copy() + else: + print(f"Could not find layer {name}!") + layer = None + return layer + class PluginManager(object): """ @@ -152,11 +195,22 @@ def update_with_name( self.layers[idx] = self.plugins[idx](elevation_map, layer_names, self.layers, self.layer_names) elif n_param == 7: self.layers[idx] = self.plugins[idx]( - elevation_map, layer_names, self.layers, self.layer_names, semantic_map, semantic_params, + elevation_map, + layer_names, + self.layers, + self.layer_names, + semantic_map, + semantic_params, ) elif n_param == 8: self.layers[idx] = self.plugins[idx]( - elevation_map, layer_names, self.layers, self.layer_names, semantic_map, semantic_params, rotation, + elevation_map, + layer_names, + self.layers, + self.layer_names, + semantic_map, + semantic_params, + rotation, ) else: self.layers[idx] = self.plugins[idx]( diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/sqrt_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/sqrt_filter.py deleted file mode 100644 index 63c6a496..00000000 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/sqrt_filter.py +++ /dev/null @@ -1,122 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import numpy as np -from typing import List - -from elevation_mapping_cupy.plugins.plugin_manager import PluginBase - - -class MaxLayerFilter(PluginBase): - """Applies a maximum filter to the input layers and updates the traversability map. - This can be used to enhance navigation by identifying traversable areas. - - Args: - cell_n (int): The width and height of the elevation map. - layers (list): List of layers for semantic traversability. Default is ["traversability"]. - thresholds (list): List of thresholds for each layer. Default is [0.5]. - type (list): List of types for each layer. Default is ["traversability"]. - **kwargs: Additional keyword arguments. - """ - - def __init__( - self, - cell_n: int = 100, - layers: list = ["traversability"], - reverse: list = [True], - min_or_max: str = "max", - thresholds: list = [False], - default_value: float = 0.0, - **kwargs, - ): - super().__init__() - self.layers = layers - self.reverse = reverse - self.min_or_max = min_or_max - self.thresholds = thresholds - self.default_value = default_value - - def get_layer_data( - self, - elevation_map, - layer_names, - plugin_layers, - plugin_layer_names, - semantic_map, - semantic_layer_names, - name, - ): - if name in layer_names: - idx = layer_names.index(name) - layer = elevation_map[idx].copy() - elif name in plugin_layer_names: - idx = plugin_layer_names.index(name) - layer = plugin_layers[idx].copy() - elif name in semantic_layer_names: - idx = semantic_layer_names.index(name) - layer = semantic_map[idx].copy() - else: - print(f"Could not find layer {name}!") - layer = None - return layer - - def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - semantic_map: cp.ndarray, - semantic_layer_names: List[str], - *args, - ) -> cp.ndarray: - """ - - Args: - elevation_map (cupy._core.core.ndarray): - layer_names (List[str]): - plugin_layers (cupy._core.core.ndarray): - plugin_layer_names (List[str]): - semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): - *args (): - - Returns: - cupy._core.core.ndarray: - """ - layers = [] - for it, name in enumerate(self.layers): - layer = self.get_layer_data( - elevation_map, layer_names, plugin_layers, plugin_layer_names, semantic_map, semantic_layer_names, name - ) - if layer is None: - continue - if isinstance(self.default_value, float): - layer = cp.where(layer == 0.0, float(self.default_value), layer) - elif isinstance(self.default_value, str): - default_layer = self.get_layer_data( - elevation_map, - layer_names, - plugin_layers, - plugin_layer_names, - semantic_map, - semantic_layer_names, - self.default_value, - ) - layer = cp.where(layer == 0, default_layer, layer) - if self.reverse[it]: - layer = 1.0 - layer - if isinstance(self.thresholds[it], float): - layer = cp.where(layer > float(self.thresholds[it]), 1, 0) - layers.append(layer) - if len(layers) == 0: - print("No layers are found, returning traversability!") - idx = layer_names.index("traversability") - return elevation_map[idx] - result = cp.stack(layers, axis=0) - if self.min_or_max == "min": - result = cp.min(result, axis=0) - else: - result = cp.max(result, axis=0) - return result From 1b304358d163977dee33fd13dfe1295d60ec8c5b Mon Sep 17 00:00:00 2001 From: Takahiro Date: Sat, 24 Feb 2024 19:42:38 +0100 Subject: [PATCH 419/504] Removed commented out code. --- .../plugins/max_layer_filter.py | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py index 3b3dc3c6..1c4e7853 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py @@ -39,30 +39,6 @@ def __init__( self.thresholds = thresholds self.default_value = default_value - # def get_layer_data( - # self, - # elevation_map, - # layer_names, - # plugin_layers, - # plugin_layer_names, - # semantic_map, - # semantic_layer_names, - # name, - # ): - # if name in layer_names: - # idx = layer_names.index(name) - # layer = elevation_map[idx].copy() - # elif name in plugin_layer_names: - # idx = plugin_layer_names.index(name) - # layer = plugin_layers[idx].copy() - # elif name in semantic_layer_names: - # idx = semantic_layer_names.index(name) - # layer = semantic_map[idx].copy() - # else: - # print(f"Could not find layer {name}!") - # layer = None - # return layer - def __call__( self, elevation_map: cp.ndarray, From 6b25b7ede8106c5d4981d7b69a5284fc758a44df Mon Sep 17 00:00:00 2001 From: Takahiro Miki Date: Wed, 28 Feb 2024 17:47:36 +0100 Subject: [PATCH 420/504] Updated bibtex. --- README.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 975fba85..057424df 100644 --- a/README.md +++ b/README.md @@ -46,13 +46,13 @@ Elevation Mapping for Locomotion and Navigation using GPU Takahiro Miki, Lorenz Wellhausen, Ruben Grandia, Fabian Jenelten, Timon Homberger, Marco Hutter ```bibtex -@misc{mikielevation2022, - doi = {10.48550/ARXIV.2204.12876}, - author = {Miki, Takahiro and Wellhausen, Lorenz and Grandia, Ruben and Jenelten, Fabian and Homberger, Timon and Hutter, Marco}, - keywords = {Robotics (cs.RO), FOS: Computer and information sciences, FOS: Computer and information sciences}, - title = {Elevation Mapping for Locomotion and Navigation using GPU}, - publisher = {International Conference on Intelligent Robots and Systems (IROS)}, - year = {2022}, +@inproceedings{miki2022elevation, + title={Elevation mapping for locomotion and navigation using gpu}, + author={Miki, Takahiro and Wellhausen, Lorenz and Grandia, Ruben and Jenelten, Fabian and Homberger, Timon and Hutter, Marco}, + booktitle={2022 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)}, + pages={2273--2280}, + year={2022}, + organization={IEEE} } ``` @@ -63,11 +63,13 @@ If you use the Multi-modal Elevation Mapping for color or semantic layers, pleas Gian Erni, Jonas Frey, Takahiro Miki, Matias Mattamala, Marco Hutter ```bibtex -@misc{Erni2023-bs, - title = "{MEM}: {Multi-Modal} Elevation Mapping for Robotics and Learning", - author = "Erni, Gian and Frey, Jonas and Miki, Takahiro and Mattamala, Matias and Hutter, Marco", - publisher = {International Conference on Intelligent Robots and Systems (IROS)}, - year = {2023}, +@inproceedings{erni2023mem, + title={MEM: Multi-Modal Elevation Mapping for Robotics and Learning}, + author={Erni, Gian and Frey, Jonas and Miki, Takahiro and Mattamala, Matias and Hutter, Marco}, + booktitle={2023 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)}, + pages={11011--11018}, + year={2023}, + organization={IEEE} } ``` From f8f8fe30ea39b4f4f78d49a5e1d11f87ac47f553 Mon Sep 17 00:00:00 2001 From: RobinSchmid7 Date: Thu, 14 Mar 2024 16:20:02 +0100 Subject: [PATCH 421/504] Font cleanup --- .../config/setups/anymal/anymal_parameters.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml index 5d1ad988..4a2ed7f4 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml @@ -1,6 +1,6 @@ #### Basic parameters ######## -resolution: 0.04 # resolution in m. -map_length: 8 # map's size in m. +resolution: 0.04 # resolution in m. +map_length: 8 # map's size in m. sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). mahalanobis_thresh: 2.0 # points outside this distance is outlier. outlier_variance: 0.01 # if point is outlier, add this value to the cell. @@ -9,7 +9,7 @@ max_drift: 0.1 # drift compensation happens onl drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation time_variance: 0.0001 # add this value when update_variance is called. max_variance: 100.0 # maximum variance for each cell. -initial_variance: 1000.0 # initial variance for each cell. +initial_variance: 1000.0 # initial variance for each cell. traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. dilation_size: 3 # dilation filter size before traversability filter. wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. From 0ecb24a1862996dab64e23738ddea64b9515fec9 Mon Sep 17 00:00:00 2001 From: RobinSchmid7 Date: Mon, 18 Mar 2024 10:51:32 +0100 Subject: [PATCH 422/504] Adding the upper bound layer to the default elevation map layers --- .../config/setups/anymal/anymal_sensor_parameter.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml index a14b08d0..a5a96577 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml @@ -18,7 +18,7 @@ image_channel_fusions: publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance', 'rgb', 'anomaly', 'friction', 'stiffness', 'risk'] + layers: ['elevation', 'traversability', 'variance', 'rgb', 'anomaly', 'friction', 'stiffness', 'risk', 'upper_bound'] basic_layers: ['elevation', 'traversability'] fps: 5.0 @@ -28,7 +28,7 @@ publishers: fps: 2.0 filtered_elevation_map: - layers: ['inpaint', 'smooth', 'min_filter'] + layers: ['inpaint', 'smooth', 'min_filter', 'upper_bound'] basic_layers: ['inpaint'] fps: 5.0 From d33feca2ad24429d1baa9a0790b5b55c071705e1 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Mon, 25 Mar 2024 21:48:44 +0100 Subject: [PATCH 423/504] Added a param called alwaysClearWithInitializer. --- .../include/elevation_mapping_cupy/elevation_mapping_ros.hpp | 1 + elevation_mapping_cupy/src/elevation_mapping_ros.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 0149ffad..0fb75b6a 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -184,6 +184,7 @@ class ElevationMappingNode { bool enableDriftCorrectedTFPublishing_; bool useInitializerAtStart_; double initializeTfGridSize_; + bool alwaysClearWithInitializer_; std::atomic_int pointCloudProcessCounter_; }; diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 4a72e8c6..715afeb9 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -68,6 +68,7 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) nh.param("enable_normal_arrow_publishing", enableNormalArrowPublishing_, false); nh.param("enable_drift_corrected_TF_publishing", enableDriftCorrectedTFPublishing_, false); nh.param("use_initializer_at_start", useInitializerAtStart_, false); + nh.param("always_clear_with_initializer", alwaysClearWithInitializer_, false); enablePointCloudPublishing_ = enablePointCloudPublishing; @@ -541,6 +542,9 @@ bool ElevationMappingNode::getSubmap(grid_map_msgs::GetGridMap::Request& request bool ElevationMappingNode::clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) { ROS_INFO("Clearing map."); map_.clear(); + if (alwaysClearWithInitializer_) { + initializeWithTF(); + } return true; } From ee9a15521bb8d270cb1c2e43c7e89ba71e0e5f3c Mon Sep 17 00:00:00 2001 From: Takahiro Date: Mon, 1 Apr 2024 22:41:03 +0200 Subject: [PATCH 424/504] Fixed issue with erosion filter. --- .gitignore | 3 ++- elevation_mapping_cupy/compile_commands.json | 1 - .../elevation_mapping_cupy/plugins/erosion.py | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) delete mode 120000 elevation_mapping_cupy/compile_commands.json diff --git a/.gitignore b/.gitignore index 69ac53f4..41fde99f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ docs/build _build .idea* .vscode* -*.egg-info \ No newline at end of file +*.egg-info +elevation_mapping_cupy/compile_commands.json diff --git a/elevation_mapping_cupy/compile_commands.json b/elevation_mapping_cupy/compile_commands.json deleted file mode 120000 index 2fdee343..00000000 --- a/elevation_mapping_cupy/compile_commands.json +++ /dev/null @@ -1 +0,0 @@ -/home/takahiro/catkin_ws/build/elevation_mapping_cupy/compile_commands.json \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/erosion.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/erosion.py index b78497b4..7b0211df 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/erosion.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/erosion.py @@ -28,6 +28,7 @@ def __init__( kernel_size: int = 3, iterations: int = 1, reverse: bool = False, + default_layer_name: str = "traversability", **kwargs, ): super().__init__() @@ -35,6 +36,7 @@ def __init__( self.kernel_size = kernel_size self.iterations = iterations self.reverse = reverse + self.default_layer_name = default_layer_name def __call__( self, @@ -69,6 +71,28 @@ def __call__( semantic_layer_names, self.input_layer_name, ) + if layer_data is None: + print(f"No layers are found, using {self.default_layer_name}!") + layer_data = self.get_layer_data( + elevation_map, + layer_names, + plugin_layers, + plugin_layer_names, + semantic_map, + semantic_layer_names, + self.default_layer_name, + ) + if layer_data is None: + print(f"No layers are found, using traversability!") + layer_data = self.get_layer_data( + elevation_map, + layer_names, + plugin_layers, + plugin_layer_names, + semantic_map, + semantic_layer_names, + "traversability", + ) layer_np = cp.asnumpy(layer_data) # Define the erosion kernel From 91d2a3de18b7c13b53c9581f4f9982948dd95bef Mon Sep 17 00:00:00 2001 From: yyagin Date: Fri, 5 Apr 2024 14:50:17 +0000 Subject: [PATCH 425/504] Networkx installation error fix https://github.com/leggedrobotics/elevation_mapping_cupy/issues/87 Newest version of Networkx only available for Python >3.9. --- docker/Dockerfile.x64 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile.x64 b/docker/Dockerfile.x64 index 05cad5c7..7864e918 100644 --- a/docker/Dockerfile.x64 +++ b/docker/Dockerfile.x64 @@ -16,7 +16,7 @@ RUN apt-get update && apt-get install -y \ git # Install PyTorch -RUN pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 +RUN pip3 install networkx==3.0 torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 COPY requirements.txt /tmp/requirements.txt RUN pip3 install -r /tmp/requirements.txt From a23191f36e08df2852de41b5e5f2a8d21bd2dfcf Mon Sep 17 00:00:00 2001 From: Jonas Frey Date: Thu, 18 Apr 2024 12:37:39 +0200 Subject: [PATCH 426/504] fix bug --- .../elevation_mapping_cupy/kernels/custom_image_kernels.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py index ce03ee8f..a29668a2 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py @@ -22,7 +22,7 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_co return layer * layer_n + idx; } __device__ bool is_inside_map(int x, int y) { - return (x >= 0 && y >= 0 && x<${width} && x<${height}); + return (x >= 0 && y >= 0 && x<${width} && y<${height}); } __device__ float get_l2_distance(int x0, int y0, int x1, int y1) { float dx = x0-x1; From 8de87cebafc10bff7b96fe879c6902b3ccec91a2 Mon Sep 17 00:00:00 2001 From: yyagin Date: Wed, 24 Apr 2024 12:21:32 +0300 Subject: [PATCH 427/504] Add networkx dependency --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 76a0b9d2..fa3f3767 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ simple-parsing scikit-image==0.19 matplotlib catkin-tools +networkx==3.0 # cupy ###### Requirements with Version Specifiers ######` From dd3d9a2f1086f67d79a6a4fe16829a48049d1a61 Mon Sep 17 00:00:00 2001 From: yyagin Date: Wed, 24 Apr 2024 12:22:05 +0300 Subject: [PATCH 428/504] Install requirements before PyTorch --- docker/Dockerfile.x64 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile.x64 b/docker/Dockerfile.x64 index 7864e918..26bb85f4 100644 --- a/docker/Dockerfile.x64 +++ b/docker/Dockerfile.x64 @@ -16,9 +16,9 @@ RUN apt-get update && apt-get install -y \ git # Install PyTorch -RUN pip3 install networkx==3.0 torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 COPY requirements.txt /tmp/requirements.txt RUN pip3 install -r /tmp/requirements.txt +RUN pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # Install other Python packages RUN pip3 install cupy-cuda11x scikit-learn From 0126df19f0d3a57f940eb08e4481d9feed52ef51 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Sat, 27 Apr 2024 23:45:13 +0200 Subject: [PATCH 429/504] Added scales param to max_layer_filter. --- .../script/elevation_mapping_cupy/plugins/max_layer_filter.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py index 1c4e7853..34783ebd 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py @@ -29,6 +29,7 @@ def __init__( reverse: list = [True], min_or_max: str = "max", thresholds: list = [False], + scales: list = [1.0], default_value: float = 0.0, **kwargs, ): @@ -37,6 +38,7 @@ def __init__( self.reverse = reverse self.min_or_max = min_or_max self.thresholds = thresholds + self.scales = scales self.default_value = default_value def __call__( @@ -84,6 +86,8 @@ def __call__( layer = cp.where(layer == 0, default_layer, layer) if self.reverse[it]: layer = 1.0 - layer + if len(self.scales) > it and isinstance(self.scales[it], float): + layer = layer * float(self.scales[it]) if isinstance(self.thresholds[it], float): layer = cp.where(layer > float(self.thresholds[it]), 1, 0) layers.append(layer) From c4af484ff6368e496c144224aa18fac43fc45e5f Mon Sep 17 00:00:00 2001 From: RobinSchmid7 Date: Sun, 9 Jun 2024 22:18:06 +0200 Subject: [PATCH 430/504] Start adding distortion, not tested yet --- .../elevation_mapping_wrapper.hpp | 2 +- .../elevation_mapping_cupy/elevation_mapping.py | 3 +++ .../elevation_mapping_ros.py | 2 +- .../kernels/custom_image_kernels.py | 17 ++++++++++++++++- .../src/elevation_mapping_ros.cpp | 7 +++++-- .../src/elevation_mapping_wrapper.cpp | 4 ++-- 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index 116403e6..fb74574f 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -49,7 +49,7 @@ class ElevationMappingWrapper { void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); void input_image(const std::vector& multichannel_image, const std::vector& channels, const RowMatrixXd& R, - const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, int height, int width); + const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, const RowMatrixXd& D, int height, int width); void move_to(const Eigen::VectorXd& p, const RowMatrixXd& R); void clear(); void update_variance(); diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 0ff32d9a..11136fe9 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -466,6 +466,7 @@ def input_image( R: cp._core.core.ndarray, t: cp._core.core.ndarray, K: cp._core.core.ndarray, + D: cp._core.core.ndarray, image_height: int, image_width: int, ): @@ -492,6 +493,7 @@ def input_image( K = cp.asarray(K, dtype=self.data_type) R = cp.asarray(R, dtype=self.data_type) t = cp.asarray(t, dtype=self.data_type) + D = cp.asarray(D, dtype=self.data_type) image_height = cp.float32(image_height) image_width = cp.float32(image_width) @@ -514,6 +516,7 @@ def input_image( y1, z1, P.reshape(-1), + D.reshape(-1), image_height, image_width, self.center, diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index 3756ebd7..6e69861c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -177,7 +177,7 @@ def image_callback(self, camera_msg, camera_info_msg, sub_key): assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) # process pointcloud - self._map.input_image(sub_key, semantic_img, R, t, K, camera_info_msg.height, camera_info_msg.width) + self._map.input_image(sub_key, semantic_img, R, t, K, D, camera_info_msg.height, camera_info_msg.width) self._image_process_counter += 1 def pointcloud_callback(self, msg, sub_key): diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py index a29668a2..4af01577 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py @@ -13,7 +13,7 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_co The function returns a kernel that can be used to perform the correspondence calculation. """ _image_to_map_correspondence_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U image_height, raw U image_width, raw U center", + in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U D, raw U image_height, raw U image_width, raw U center", out_params="raw U uv_correspondence, raw B valid_correspondence", preamble=string.Template( """ @@ -65,6 +65,21 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_co if ((u < 0) || (v < 0) || (u >= image_width) || (v >= image_height)){ return; } + + // Apply undistortion using distortion matrix D + float k1 = D[0]; + float k2 = D[1]; + float p1 = D[2]; + float p2 = D[3]; + float k3 = D[4]; + float x = (u - image_width / 2.0) / (image_width / 2.0); + float y = (v - image_height / 2.0) / (image_height / 2.0); + float r2 = x * x + y * y; + float radial_distortion = 1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2; + float x_corrected = x * radial_distortion + 2 * p1 * x * y + p2 * (r2 + 2 * x * x); + float y_corrected = y * radial_distortion + 2 * p2 * x * y + p1 * (r2 + 2 * y * y); + u = (x_corrected * (image_width / 2.0)) + (image_width / 2.0); + v = (y_corrected * (image_height / 2.0)) + (image_height / 2.0); int y0_c = y0; int x0_c = x0; diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 4a72e8c6..50c2dd96 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -387,6 +387,9 @@ void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_ms // Extract camera matrix Eigen::Map> cameraMatrix(&camera_info_msg->K[0]); + // Extract distortion coefficients + Eigen::Map distortionCoeffs(camera_info_msg->D.data(), camera_info_msg->D.size()); + // Get pose of sensor in map frame tf::StampedTransform transformTf; std::string sensorFrameId = image_msg->header.frame_id; @@ -427,8 +430,8 @@ void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_ms } // Pass image to pipeline - map_.input_image(multichannel_image, channels, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, - image.rows, image.cols); + map_.input_image(multichannel_image, channels, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, + distortionCoeffs, image.rows, image.cols); } void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image_msg, diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index f66f9a79..b23207d6 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -178,10 +178,10 @@ void ElevationMappingWrapper::input(const RowMatrixXd& points, const std::vector } void ElevationMappingWrapper::input_image(const std::vector& multichannel_image, const std::vector& channels, const RowMatrixXd& R, - const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, int height, int width) { + const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, const RowMatrixXd& D, int height, int width) { py::gil_scoped_acquire acquire; map_.attr("input_image")(multichannel_image, channels, Eigen::Ref(R), Eigen::Ref(t), - Eigen::Ref(cameraMatrix), height, width); + Eigen::Ref(cameraMatrix), Eigen::Ref(D), height, width); } void ElevationMappingWrapper::move_to(const Eigen::VectorXd& p, const RowMatrixXd& R) { From bf8fc22d98df52f4d19a34785d4810895db049cb Mon Sep 17 00:00:00 2001 From: RobinSchmid7 Date: Mon, 10 Jun 2024 21:32:15 +0200 Subject: [PATCH 431/504] Only apply kernel if not all zeros --- .../kernels/custom_image_kernels.py | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py index 4af01577..abce0226 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py @@ -64,22 +64,27 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_co // filter point next to image plane if ((u < 0) || (v < 0) || (u >= image_width) || (v >= image_height)){ return; - } + } + + // Check if D is all zeros + bool is_D_zero = (D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == 0 && D[4] == 0); - // Apply undistortion using distortion matrix D - float k1 = D[0]; - float k2 = D[1]; - float p1 = D[2]; - float p2 = D[3]; - float k3 = D[4]; - float x = (u - image_width / 2.0) / (image_width / 2.0); - float y = (v - image_height / 2.0) / (image_height / 2.0); - float r2 = x * x + y * y; - float radial_distortion = 1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2; - float x_corrected = x * radial_distortion + 2 * p1 * x * y + p2 * (r2 + 2 * x * x); - float y_corrected = y * radial_distortion + 2 * p2 * x * y + p1 * (r2 + 2 * y * y); - u = (x_corrected * (image_width / 2.0)) + (image_width / 2.0); - v = (y_corrected * (image_height / 2.0)) + (image_height / 2.0); + // Apply undistortion using distortion matrix D if not all zeros + if (!is_D_zero) { + float k1 = D[0]; + float k2 = D[1]; + float p1 = D[2]; + float p2 = D[3]; + float k3 = D[4]; + float x = (u - image_width / 2.0) / (image_width / 2.0); + float y = (v - image_height / 2.0) / (image_height / 2.0); + float r2 = x * x + y * y; + float radial_distortion = 1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2; + float x_corrected = x * radial_distortion + 2 * p1 * x * y + p2 * (r2 + 2 * x * x); + float y_corrected = y * radial_distortion + 2 * p2 * x * y + p1 * (r2 + 2 * y * y); + u = (x_corrected * (image_width / 2.0)) + (image_width / 2.0); + v = (y_corrected * (image_height / 2.0)) + (image_height / 2.0); + } int y0_c = y0; int x0_c = x0; From 99dd4065e7aa826c52536cc9330c28acab863870 Mon Sep 17 00:00:00 2001 From: RobinSchmid7 Date: Mon, 10 Jun 2024 21:58:21 +0200 Subject: [PATCH 432/504] Load D and check if D is not empty --- .../elevation_mapping_cupy/elevation_mapping_ros.py | 5 ++++- elevation_mapping_cupy/src/elevation_mapping_ros.cpp | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index 6e69861c..c28823e9 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -174,8 +174,11 @@ def image_callback(self, camera_msg, camera_info_msg, sub_key): else: semantic_img = [semantic_img] - assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) + + assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" + D = np.array(camera_info_msg.D, dtype=np.float32).reshape(5, 1) + # process pointcloud self._map.input_image(sub_key, semantic_img, R, t, K, D, camera_info_msg.height, camera_info_msg.width) self._image_process_counter += 1 diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 50c2dd96..c10e5185 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -388,8 +388,14 @@ void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_ms Eigen::Map> cameraMatrix(&camera_info_msg->K[0]); // Extract distortion coefficients - Eigen::Map distortionCoeffs(camera_info_msg->D.data(), camera_info_msg->D.size()); - + Eigen::VectorXd distortionCoeffs; + if (!camera_info_msg->D.empty()) { + distortionCoeffs = Eigen::Map(camera_info_msg->D.data(), camera_info_msg->D.size()); + } else { + ROS_ERROR("Distortion coefficients are empty."); + return; + } + // Get pose of sensor in map frame tf::StampedTransform transformTf; std::string sensorFrameId = image_msg->header.frame_id; From e0f7c735107f79dd661eae5698aa9e164ebd9a8c Mon Sep 17 00:00:00 2001 From: Takahiro Date: Tue, 11 Jun 2024 23:01:42 +0200 Subject: [PATCH 433/504] Fixed bugs for distortion model. --- .../elevation_mapping_wrapper.hpp | 2 +- .../elevation_mapping.py | 60 +++++++++++++++---- .../kernels/custom_image_kernels.py | 28 +++++---- .../src/elevation_mapping_ros.cpp | 5 +- .../src/elevation_mapping_wrapper.cpp | 4 +- 5 files changed, 70 insertions(+), 29 deletions(-) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index fb74574f..2b026c17 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -49,7 +49,7 @@ class ElevationMappingWrapper { void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); void input_image(const std::vector& multichannel_image, const std::vector& channels, const RowMatrixXd& R, - const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, const RowMatrixXd& D, int height, int width); + const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, const Eigen::VectorXd& D, int height, int width); void move_to(const Eigen::VectorXd& p, const RowMatrixXd& R); void clear(); void update_variance(); diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 11136fe9..bba41ec6 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -228,7 +228,10 @@ def shift_map_z(self, delta_z): def compile_kernels(self): """Compile all kernels belonging to the elevation map.""" - self.new_map = cp.zeros((self.elevation_map.shape[0], self.cell_n, self.cell_n), dtype=self.data_type,) + self.new_map = cp.zeros( + (self.elevation_map.shape[0], self.cell_n, self.cell_n), + dtype=self.data_type, + ) self.traversability_input = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) self.traversability_mask_dummy = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) self.min_filtered = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) @@ -287,14 +290,18 @@ def compile_image_kernels(self): np.zeros((self.cell_n, self.cell_n), dtype=np.bool_), dtype=np.bool_ ) self.uv_correspondence = cp.asarray( - np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32, + np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), + dtype=np.float32, ) # self.distance_correspondence = cp.asarray( # np.zeros((self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32 # ) # TODO tolerance_z_collision add parameter self.image_to_map_correspondence_kernel = image_to_map_correspondence_kernel( - resolution=self.resolution, width=self.cell_n, height=self.cell_n, tolerance_z_collision=0.10, + resolution=self.resolution, + width=self.cell_n, + height=self.cell_n, + tolerance_z_collision=0.10, ) break @@ -484,6 +491,7 @@ def input_image( Returns: None: """ + image = np.stack(image, axis=0) if len(image.shape) == 2: image = image[None] @@ -497,6 +505,13 @@ def input_image( image_height = cp.float32(image_height) image_width = cp.float32(image_width) + if len(D) < 4: + D = cp.zeros(5, dtype=self.data_type) + elif len(D) == 4: + D = cp.concatenate([D, cp.zeros(1, dtype=self.data_type)]) + else: + D = D[:5] + # Calculate transformation matrix P = cp.asarray(K @ cp.concatenate([R, t[:, None]], 1), dtype=np.float32) t_cam_map = -R.T @ t - self.center @@ -507,7 +522,6 @@ def input_image( self.uv_correspondence *= 0 self.valid_correspondence[:, :] = False - # self.distance_correspondence *= 0.0 with self.map_lock: self.image_to_map_correspondence_kernel( @@ -516,6 +530,7 @@ def input_image( y1, z1, P.reshape(-1), + K.reshape(-1), D.reshape(-1), image_height, image_width, @@ -525,7 +540,12 @@ def input_image( size=int(self.cell_n * self.cell_n), ) self.semantic_map.update_layers_image( - image, channels, self.uv_correspondence, self.valid_correspondence, image_height, image_width, + image, + channels, + self.uv_correspondence, + self.valid_correspondence, + image_height, + image_width, ) def update_normal(self, dilated_map): @@ -537,7 +557,10 @@ def update_normal(self, dilated_map): with self.map_lock: self.normal_map *= 0.0 self.normal_filter_kernel( - dilated_map, self.elevation_map[2], self.normal_map, size=(self.cell_n * self.cell_n), + dilated_map, + self.elevation_map[2], + self.normal_map, + size=(self.cell_n * self.cell_n), ) def process_map_for_publish(self, input_map, fill_nan=False, add_z=False, xp=cp): @@ -583,7 +606,9 @@ def get_traversability(self): traversability layer """ traversability = cp.where( - (self.elevation_map[2] + self.elevation_map[6]) > 0.5, self.elevation_map[3].copy(), cp.nan, + (self.elevation_map[2] + self.elevation_map[6]) > 0.5, + self.elevation_map[3].copy(), + cp.nan, ) self.traversability_buffer[3:-3, 3:-3] = traversability[3:-3, 3:-3] traversability = self.traversability_buffer[1:-1, 1:-1] @@ -605,7 +630,8 @@ def get_upper_bound(self): """ if self.param.use_only_above_for_upper_bound: valid = cp.logical_or( - cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), self.elevation_map[2] > 0.5, + cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), + self.elevation_map[2] > 0.5, ) else: valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) @@ -621,7 +647,8 @@ def get_is_upper_bound(self): """ if self.param.use_only_above_for_upper_bound: valid = cp.logical_or( - cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), self.elevation_map[2] > 0.5, + cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), + self.elevation_map[2] > 0.5, ) else: valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) @@ -782,7 +809,11 @@ def get_layer(self, name): return_map = self.semantic_map.semantic_map[idx] elif name in self.plugin_manager.layer_names: self.plugin_manager.update_with_name( - name, self.elevation_map, self.layer_names, self.semantic_map, self.base_rotation, + name, + self.elevation_map, + self.layer_names, + self.semantic_map, + self.base_rotation, ) return_map = self.plugin_manager.get_map_with_name(name) else: @@ -828,7 +859,10 @@ def get_polygon_traversability(self, polygon, result): else: t = cp.asarray(0.0, dtype=self.data_type) is_safe, un_polygon = is_traversable( - masked, self.param.safe_thresh, self.param.safe_min_thresh, self.param.max_unsafe_n, + masked, + self.param.safe_thresh, + self.param.safe_min_thresh, + self.param.max_unsafe_n, ) untraversable_polygon_num = 0 if un_polygon is not None: @@ -884,7 +918,9 @@ def initialize_map(self, points, method="cubic"): t = xp.random.rand(3) print(R, t) param = Parameter( - use_chainer=False, weight_file="../config/weights.dat", plugin_config_file="../config/plugin_config.yaml", + use_chainer=False, + weight_file="../config/weights.dat", + plugin_config_file="../config/plugin_config.yaml", ) param.additional_layers = ["rgb", "grass", "tree", "people"] param.fusion_algorithms = ["color", "class_bayesian", "class_bayesian", "class_bayesian"] diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py index abce0226..a020ba2e 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py @@ -13,7 +13,7 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_co The function returns a kernel that can be used to perform the correspondence calculation. """ _image_to_map_correspondence_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U D, raw U image_height, raw U image_width, raw U center", + in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U K, raw U D, raw U image_height, raw U image_width, raw U center", out_params="raw U uv_correspondence, raw B valid_correspondence", preamble=string.Template( """ @@ -60,11 +60,6 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_co } u = u/d; v = v/d; - - // filter point next to image plane - if ((u < 0) || (v < 0) || (u >= image_width) || (v >= image_height)){ - return; - } // Check if D is all zeros bool is_D_zero = (D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == 0 && D[4] == 0); @@ -76,14 +71,23 @@ def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_co float p1 = D[2]; float p2 = D[3]; float k3 = D[4]; - float x = (u - image_width / 2.0) / (image_width / 2.0); - float y = (v - image_height / 2.0) / (image_height / 2.0); + float fx = K[0]; + float fy = K[4]; + float cx = K[2]; + float cy = K[5]; + float x = (u - cx) / fx; + float y = (v - cy) / fy; float r2 = x * x + y * y; float radial_distortion = 1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2; - float x_corrected = x * radial_distortion + 2 * p1 * x * y + p2 * (r2 + 2 * x * x); - float y_corrected = y * radial_distortion + 2 * p2 * x * y + p1 * (r2 + 2 * y * y); - u = (x_corrected * (image_width / 2.0)) + (image_width / 2.0); - v = (y_corrected * (image_height / 2.0)) + (image_height / 2.0); + float u_corrected = x * radial_distortion + 2 * p1 * x * y + p2 * (r2 + 2 * x * x); + float v_corrected = y * radial_distortion + 2 * p2 * x * y + p1 * (r2 + 2 * y * y); + u = fx * u_corrected + cx; + v = fy * v_corrected + cy; + } + + // filter point next to image plane + if ((u < 0) || (v < 0) || (u >= image_width) || (v >= image_height)){ + return; } int y0_c = y0; diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index c10e5185..290246cc 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -392,8 +392,9 @@ void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_ms if (!camera_info_msg->D.empty()) { distortionCoeffs = Eigen::Map(camera_info_msg->D.data(), camera_info_msg->D.size()); } else { - ROS_ERROR("Distortion coefficients are empty."); - return; + ROS_WARN("Distortion coefficients are empty."); + distortionCoeffs = Eigen::VectorXd::Zero(5); + // return; } // Get pose of sensor in map frame diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index b23207d6..07f904c8 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -178,10 +178,10 @@ void ElevationMappingWrapper::input(const RowMatrixXd& points, const std::vector } void ElevationMappingWrapper::input_image(const std::vector& multichannel_image, const std::vector& channels, const RowMatrixXd& R, - const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, const RowMatrixXd& D, int height, int width) { + const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, const Eigen::VectorXd& D, int height, int width) { py::gil_scoped_acquire acquire; map_.attr("input_image")(multichannel_image, channels, Eigen::Ref(R), Eigen::Ref(t), - Eigen::Ref(cameraMatrix), Eigen::Ref(D), height, width); + Eigen::Ref(cameraMatrix), Eigen::Ref(D), height, width); } void ElevationMappingWrapper::move_to(const Eigen::VectorXd& p, const RowMatrixXd& R) { From eb1c76c03dfa2733441fc5445f141e03a8baac6b Mon Sep 17 00:00:00 2001 From: Takahiro Date: Mon, 24 Jun 2024 11:19:15 +0200 Subject: [PATCH 434/504] Passing distortion model information --- .../elevation_mapping_wrapper.hpp | 2 +- .../elevation_mapping_cupy/elevation_mapping.py | 13 +++++++++++++ .../src/elevation_mapping_ros.cpp | 5 ++++- .../src/elevation_mapping_wrapper.cpp | 4 ++-- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index 2b026c17..712ed10a 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -49,7 +49,7 @@ class ElevationMappingWrapper { void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); void input_image(const std::vector& multichannel_image, const std::vector& channels, const RowMatrixXd& R, - const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, const Eigen::VectorXd& D, int height, int width); + const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, const Eigen::VectorXd& D, const std::string distortion_model, int height, int width); void move_to(const Eigen::VectorXd& p, const RowMatrixXd& R); void clear(); void update_variance(); diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index bba41ec6..43cbe884 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -474,6 +474,7 @@ def input_image( t: cp._core.core.ndarray, K: cp._core.core.ndarray, D: cp._core.core.ndarray, + distortion_model: str, image_height: int, image_width: int, ): @@ -512,6 +513,18 @@ def input_image( else: D = D[:5] + if distortion_model == "radtan": + pass + elif distortion_model == "equidistant": + # Not implemented yet. + D *= 0 + elif distortion_model == "plumb_bob": + # Not implemented yet. + D *= 0 + else: + # Not implemented yet. + D *= 0 + # Calculate transformation matrix P = cp.asarray(K @ cp.concatenate([R, t[:, None]], 1), dtype=np.float32) t_cam_map = -R.T @ t - self.center diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 072a117c..2fbc3128 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -397,6 +397,9 @@ void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_ms distortionCoeffs = Eigen::VectorXd::Zero(5); // return; } + + // distortion model + std::string distortion_model = camera_info_msg->distortion_model; // Get pose of sensor in map frame tf::StampedTransform transformTf; @@ -439,7 +442,7 @@ void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_ms // Pass image to pipeline map_.input_image(multichannel_image, channels, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, - distortionCoeffs, image.rows, image.cols); + distortionCoeffs, distortion_model, image.rows, image.cols); } void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image_msg, diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 07f904c8..3980a8be 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -178,10 +178,10 @@ void ElevationMappingWrapper::input(const RowMatrixXd& points, const std::vector } void ElevationMappingWrapper::input_image(const std::vector& multichannel_image, const std::vector& channels, const RowMatrixXd& R, - const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, const Eigen::VectorXd& D, int height, int width) { + const Eigen::VectorXd& t, const RowMatrixXd& cameraMatrix, const Eigen::VectorXd& D, const std::string distortion_model, int height, int width) { py::gil_scoped_acquire acquire; map_.attr("input_image")(multichannel_image, channels, Eigen::Ref(R), Eigen::Ref(t), - Eigen::Ref(cameraMatrix), Eigen::Ref(D), height, width); + Eigen::Ref(cameraMatrix), Eigen::Ref(D), distortion_model, height, width); } void ElevationMappingWrapper::move_to(const Eigen::VectorXd& p, const RowMatrixXd& R) { From 154e3ec0bf0b4bca2eb3319729535435a11bef02 Mon Sep 17 00:00:00 2001 From: Takahiro Miki Date: Tue, 23 Jul 2024 14:16:07 +0200 Subject: [PATCH 435/504] Update installation.rst --- docs/source/getting_started/installation.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 95a99a2d..0db64ce6 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -154,7 +154,7 @@ ROS package dependencies .. code-block:: bash sudo apt install ros-noetic-pybind11-catkin - sudo apt install ros-noetic-grid-map-core ros-noetic-grid-map-msgs + sudo apt install ros-noetic-grid-map-core ros-noetic-grid-map-msgs ros-noetic-grid-map-ros On Jetson @@ -195,7 +195,7 @@ ROS dependencies .. code-block:: bash sudo apt install ros-melodic-pybind11-catkin - sudo apt install ros-melodic-grid-map-core ros-melodic-grid-map-msgs + sudo apt install ros-melodic-grid-map-core ros-melodic-grid-map-msgs ros-melodic-grid-map-ros Also, on jetson you need fortran (should already be installed). @@ -272,4 +272,4 @@ Then, build the packages with catkin. cd catkin build elevation_mapping_cupy # The core package catkin build convex_plane_decomposition_ros # If you want to use plane segmentation - catkin build semantic_sensor # If you want to use semantic sensors \ No newline at end of file + catkin build semantic_sensor # If you want to use semantic sensors From d4b1273bf98eee21e2fbd462a9686bbc9ca23d8c Mon Sep 17 00:00:00 2001 From: Takahiro Miki Date: Tue, 23 Jul 2024 14:18:51 +0200 Subject: [PATCH 436/504] Update installation.rst --- docs/source/getting_started/installation.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 0db64ce6..f8bcb13b 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -170,6 +170,8 @@ Python dependencies On jetson, you need the version for its CPU arch: +Please check `official document `_ for latest information for pytorch. + .. code-block:: bash wget https://nvidia.box.com/shared/static/p57jwntv436lfrd78inwl7iml6p13fzh.whl -O torch-1.8.0-cp36-cp36m-linux_aarch64.whl From c33437c2edf16c5df5b295a518f015d8a99719c5 Mon Sep 17 00:00:00 2001 From: jurichterrsl <153094227+jurichterrsl@users.noreply.github.com> Date: Mon, 5 Aug 2024 10:18:40 +0200 Subject: [PATCH 437/504] Fixed installation docs Dodo --- docs/source/getting_started/installation.rst | 22 +++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index f8bcb13b..a32cdce2 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -172,6 +172,17 @@ On jetson, you need the version for its CPU arch: Please check `official document `_ for latest information for pytorch. +Current for Jetson Orin on Ubuntu 20.04: + +.. code-block:: bash + + export TORCH_INSTALL=https://developer.download.nvidia.cn/compute/redist/jp/v511/pytorch/torch-2.0.0+nv23.05-cp38-cp38-linux_aarch64.whl + pip install Cython + python -m pip install numpy==’1.24.1’ + python -m pip install --no-cache $TORCH_INSTALL + +Current for Jetson Xavier on Ubuntu 18.04: + .. code-block:: bash wget https://nvidia.box.com/shared/static/p57jwntv436lfrd78inwl7iml6p13fzh.whl -O torch-1.8.0-cp36-cp36m-linux_aarch64.whl @@ -254,7 +265,16 @@ Python dependencies .. code-block:: bash - pip3 install torchvision scikit-learn + pip3 install scikit-learn + +Torchvision (for Jetson Orin on Ubuntu 20.04) + +.. code-block:: bash + + git clone --branch release/0.15 https://github.com/pytorch/vision torchvision + cd torchvision/ + export BUILD_VERSION=0.15.1 + python3 setup.py install --user Detectron From 968458abd7fb214634279c3874b654c952201915 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Sun, 11 Aug 2024 11:40:16 +0200 Subject: [PATCH 438/504] Use default value in max_layer_filter if the layer does not exist. --- .../elevation_mapping_cupy/plugins/max_layer_filter.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py index 34783ebd..33bc069a 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py @@ -93,8 +93,13 @@ def __call__( layers.append(layer) if len(layers) == 0: print("No layers are found, returning traversability!") - idx = layer_names.index("traversability") - return elevation_map[idx] + if isinstance(self.default_value, float): + layer = cp.ones_like(elevation_map[0]) + layer *= float(self.default_value) + return layer + else: + idx = layer_names.index("traversability") + return elevation_map[idx] result = cp.stack(layers, axis=0) if self.min_or_max == "min": result = cp.min(result, axis=0) From 494ab5fac1dd03a9fa698d984549960ac689e6be Mon Sep 17 00:00:00 2001 From: Takahiro Date: Mon, 2 Sep 2024 18:16:01 +0200 Subject: [PATCH 439/504] Only checking isnan for xyz layers. --- .../script/elevation_mapping_cupy/elevation_mapping.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 43cbe884..b78aeb45 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -455,7 +455,7 @@ def input_pointcloud( """ raw_points = cp.asarray(raw_points, dtype=self.data_type) additional_channels = channels[3:] - raw_points = raw_points[~cp.isnan(raw_points).any(axis=1)] + raw_points = raw_points[~cp.isnan(raw_points[:, :3]).any(axis=1)] self.update_map_with_kernel( raw_points, additional_channels, From 1f61e1102ec7e31b8d9068e8d2c4ad1bf0d9b987 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 26 Sep 2024 13:50:57 +0200 Subject: [PATCH 440/504] ros2 --- .../cgal5_catkin/CMakeLists.txt | 17 +++++++------ plane_segmentation/cgal5_catkin/package.xml | 24 ++++++++++++------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/plane_segmentation/cgal5_catkin/CMakeLists.txt b/plane_segmentation/cgal5_catkin/CMakeLists.txt index 75aa205a..306a7905 100644 --- a/plane_segmentation/cgal5_catkin/CMakeLists.txt +++ b/plane_segmentation/cgal5_catkin/CMakeLists.txt @@ -1,31 +1,30 @@ cmake_minimum_required(VERSION 3.14) project(cgal5_catkin) -find_package(catkin REQUIRED) +# Use ament for ROS2 +find_package(ament_cmake REQUIRED) include(ExternalProject) set(VERSION 5.3) -file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/include) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include) set(CGAL_VERSION 5.3) ExternalProject_Add(cgal URL https://github.com/CGAL/cgal/archive/refs/tags/v${CGAL_VERSION}.tar.gz UPDATE_COMMAND "" CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX=${CATKIN_DEVEL_PREFIX} + -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR} -DCMAKE_BUILD_TYPE:STRING=Release BUILD_COMMAND $(MAKE) INSTALL_COMMAND $(MAKE) install ) -catkin_package( - INCLUDE_DIRS ${CATKIN_DEVEL_PREFIX}/include - CFG_EXTRAS cgal-extras.cmake -) +ament_export_include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) -install(DIRECTORY ${CATKIN_DEVEL_PREFIX}/include/CGAL/ - DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/CGAL/ +install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/CGAL/ + DESTINATION include/CGAL/ ) +ament_package() diff --git a/plane_segmentation/cgal5_catkin/package.xml b/plane_segmentation/cgal5_catkin/package.xml index 9c3cf37a..1fb19b57 100644 --- a/plane_segmentation/cgal5_catkin/package.xml +++ b/plane_segmentation/cgal5_catkin/package.xml @@ -1,13 +1,19 @@ - cgal5_catkin - 5.0.2 - Catkin wrapper for CGAL 5. - Ruben Grandia + cgal5_catkin + 0.0.1 + ROS2 package integrating CGAL + Lorenzo Terenzi + BSD-3-Clause - See package + + ament_cmake - catkin - libgmp-dev - libmpfr-dev - + + Boost + + + + ament_cmake + + \ No newline at end of file From 889a6013f75d39267bd3fdba838c556929f9b601 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 26 Sep 2024 14:30:36 +0200 Subject: [PATCH 441/504] ros2 --- .../CMakeLists.txt | 48 ++++++++----------- .../msg/PlanarTerrain.msg | 2 +- .../package.xml | 44 +++++++++-------- 3 files changed, 43 insertions(+), 51 deletions(-) diff --git a/plane_segmentation/convex_plane_decomposition_msgs/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition_msgs/CMakeLists.txt index 12f1b2b4..5c25b7a6 100644 --- a/plane_segmentation/convex_plane_decomposition_msgs/CMakeLists.txt +++ b/plane_segmentation/convex_plane_decomposition_msgs/CMakeLists.txt @@ -1,35 +1,25 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.5) project(convex_plane_decomposition_msgs) -set(CATKIN_PACKAGE_DEPENDENCIES - std_msgs - geometry_msgs - grid_map_msgs -) - -find_package(catkin REQUIRED - COMPONENTS - ${CATKIN_PACKAGE_DEPENDENCIES} - message_generation -) - -add_message_files( - FILES - BoundingBox2d.msg - PlanarRegion.msg - PlanarTerrain.msg - Point2d.msg - Polygon2d.msg - PolygonWithHoles2d.msg -) +# Find ament and necessary packages +find_package(ament_cmake REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(std_msgs REQUIRED) +find_package(geometry_msgs REQUIRED) +find_package(grid_map_msgs REQUIRED) -generate_messages( - DEPENDENCIES - ${CATKIN_PACKAGE_DEPENDENCIES} +# Add message files for ROS2 +rosidl_generate_interfaces(${PROJECT_NAME} + "msg/BoundingBox2d.msg" + "msg/PlanarRegion.msg" + "msg/PlanarTerrain.msg" + "msg/Point2d.msg" + "msg/Polygon2d.msg" + "msg/PolygonWithHoles2d.msg" + DEPENDENCIES std_msgs geometry_msgs grid_map_msgs ) -catkin_package( - CATKIN_DEPENDS - ${CATKIN_PACKAGE_DEPENDENCIES} - message_runtime +# Replace catkin_package with ament_package +ament_package( + # ... existing export settings if any ... ) diff --git a/plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg index c50376ee..3b8f895e 100644 --- a/plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg +++ b/plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg @@ -1,2 +1,2 @@ -PlanarRegion[] planarRegions +PlanarRegion[] planar_regions grid_map_msgs/GridMap gridmap \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_msgs/package.xml b/plane_segmentation/convex_plane_decomposition_msgs/package.xml index 2af22815..c6672ab9 100644 --- a/plane_segmentation/convex_plane_decomposition_msgs/package.xml +++ b/plane_segmentation/convex_plane_decomposition_msgs/package.xml @@ -1,23 +1,25 @@ - - - convex_plane_decomposition_msgs - 0.0.0 - Convex plane decomposition message definitions. - - Ruben Grandia - - MIT - - catkin - - message_generation - - std_msgs - geometry_msgs - grid_map_msgs - - message_runtime - - + + convex_plane_decomposition_msgs + 0.0.1 + + Messages for Convex Plane Decomposition. + + Lorenzo Terenzi + Apache-2.0 + + ament_cmake + rosidl_default_generators + rosidl_runtime_cpp + std_msgs + geometry_msgs + grid_map_msgs + + + rosidl_interface_packages + + + ament_cmake + + \ No newline at end of file From 396abc9123e2e8410f0bca923bc777765ae96599 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 26 Sep 2024 14:52:13 +0200 Subject: [PATCH 442/504] ros2 elevation_mapping_mgsgs --- elevation_map_msgs/CMakeLists.txt | 41 +++++++++++--------------- elevation_map_msgs/msg/ChannelInfo.msg | 2 +- elevation_map_msgs/msg/Statistics.msg | 4 +-- elevation_map_msgs/package.xml | 15 ++++++---- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/elevation_map_msgs/CMakeLists.txt b/elevation_map_msgs/CMakeLists.txt index 2d73f5e5..7a4c23da 100644 --- a/elevation_map_msgs/CMakeLists.txt +++ b/elevation_map_msgs/CMakeLists.txt @@ -1,32 +1,27 @@ -cmake_minimum_required(VERSION 3.0.2) +cmake_minimum_required(VERSION 3.5) project(elevation_map_msgs) -find_package(catkin REQUIRED) +find_package(ament_cmake REQUIRED) +find_package(geometry_msgs REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(std_msgs REQUIRED) # Added dependency -find_package(catkin REQUIRED COMPONENTS - geometry_msgs - message_generation +set(msg_files + "msg/Statistics.msg" + "msg/ChannelInfo.msg" ) -add_message_files( - FILES - Statistics.msg - ChannelInfo.msg +set(srv_files + "srv/CheckSafety.srv" + "srv/Initialize.srv" ) -## Generate services in the 'srv' folder -add_service_files( - FILES - CheckSafety.srv - Initialize.srv +rosidl_generate_interfaces(${PROJECT_NAME} + ${msg_files} + ${srv_files} + DEPENDENCIES geometry_msgs + DEPENDENCIES std_msgs # Added dependency ) - -## Generate added messages and services with any dependencies listed here -generate_messages( - DEPENDENCIES - geometry_msgs -) - -catkin_package( -) +ament_export_dependencies(rosidl_default_runtime) +ament_package() diff --git a/elevation_map_msgs/msg/ChannelInfo.msg b/elevation_map_msgs/msg/ChannelInfo.msg index bccf1447..2e6327ec 100644 --- a/elevation_map_msgs/msg/ChannelInfo.msg +++ b/elevation_map_msgs/msg/ChannelInfo.msg @@ -1,2 +1,2 @@ -Header header +std_msgs/Header header string[] channels # channel names for each layer \ No newline at end of file diff --git a/elevation_map_msgs/msg/Statistics.msg b/elevation_map_msgs/msg/Statistics.msg index 294ccb9d..85daaa50 100644 --- a/elevation_map_msgs/msg/Statistics.msg +++ b/elevation_map_msgs/msg/Statistics.msg @@ -1,2 +1,2 @@ - Header header - float64 pointcloud_process_fps +std_msgs/Header header +float64 pointcloud_process_fps diff --git a/elevation_map_msgs/package.xml b/elevation_map_msgs/package.xml index 5fa7a60a..d30443e7 100644 --- a/elevation_map_msgs/package.xml +++ b/elevation_map_msgs/package.xml @@ -1,18 +1,23 @@ - + elevation_map_msgs 0.0.0 - ROS Message definitions for elevation mapping. + ROS 2 Message definitions for elevation mapping. Takahiro Miki Takahiro Miki MIT - catkin + ament_cmake geometry_msgs - message_generation + rosidl_default_generators + std_msgs - geometry_msgs + geometry_msgs + rosidl_default_runtime + std_msgs + + rosidl_interface_packages From 420a601f0e84233e8b7b30fba15af1b476064d03 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 26 Sep 2024 18:26:57 +0200 Subject: [PATCH 443/504] ros2 gridmap filters --- .../grid_map_filters_rsl/CMakeLists.txt | 151 ++++++------------ .../grid_map_filters_rsl/package.xml | 47 ++++-- 2 files changed, 86 insertions(+), 112 deletions(-) diff --git a/plane_segmentation/grid_map_filters_rsl/CMakeLists.txt b/plane_segmentation/grid_map_filters_rsl/CMakeLists.txt index 444929cb..515f0536 100644 --- a/plane_segmentation/grid_map_filters_rsl/CMakeLists.txt +++ b/plane_segmentation/grid_map_filters_rsl/CMakeLists.txt @@ -1,40 +1,43 @@ -# Project configuration -cmake_minimum_required (VERSION 3.5.1) +cmake_minimum_required(VERSION 3.5) project(grid_map_filters_rsl) -set(CMAKE_CXX_STANDARD 14) -add_compile_options(-Wall -Wextra -Wpedantic) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() -set(CATKIN_PACKAGE_DEPENDENCIES - grid_map_cv - grid_map_core -) +# Enable warnings +add_compile_options(-Wall -Wextra -Wpedantic) -find_package(catkin REQUIRED - COMPONENTS - ${CATKIN_PACKAGE_DEPENDENCIES} -) +# Export compile commands +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +# Find dependencies +find_package(ament_cmake REQUIRED) +find_package(grid_map_cv REQUIRED) +find_package(grid_map_core REQUIRED) find_package(Eigen3 REQUIRED) +find_package(ament_cmake_gtest REQUIRED) +find_package(sensor_msgs REQUIRED) # Added dependency +find_package(rosidl_runtime_cpp REQUIRED) # Added dependency -################################### -## catkin specific configuration ## -################################### -catkin_package( - INCLUDE_DIRS - include - ${EIGEN3_INCLUDE_DIR} - LIBRARIES - ${PROJECT_NAME} - CATKIN_DEPENDS - ${CATKIN_PACKAGE_DEPENDENCIES} +# Debugging output +message(STATUS "grid_map_cv_FOUND: ${grid_map_cv_FOUND}") +message(STATUS "grid_map_cv_INCLUDE_DIRS: ${grid_map_cv_INCLUDE_DIRS}") +message(STATUS "grid_map_cv_LIBRARIES: ${grid_map_cv_LIBRARIES}") + +# Include directories +include_directories( + include + ${grid_map_cv_INCLUDE_DIRS} + ${grid_map_core_INCLUDE_DIRS} + ${EIGEN3_INCLUDE_DIRS} + ${sensor_msgs_INCLUDE_DIRS} # Ensure sensor_msgs include dirs are added + ${rosidl_runtime_cpp_INCLUDE_DIRS} # Ensure rosidl_runtime_cpp include dirs are added ) -########### -## Build ## -########### -add_library(${PROJECT_NAME} +# Add library +add_library(${PROJECT_NAME} SHARED src/GridMapDerivative.cpp src/inpainting.cpp src/lookup.cpp @@ -42,85 +45,37 @@ add_library(${PROJECT_NAME} src/processing.cpp ) -target_include_directories(${PROJECT_NAME} PRIVATE - include +target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ ) -target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC - ${catkin_INCLUDE_DIRS} - ${EIGEN3_INCLUDE_DIR} +# Replace target_link_libraries with ament_target_dependencies +ament_target_dependencies(${PROJECT_NAME} + grid_map_cv + grid_map_core + sensor_msgs + rosidl_runtime_cpp ) - -target_link_libraries(${PROJECT_NAME} - ${catkin_LIBRARIES} +# Install library +install(TARGETS ${PROJECT_NAME} + EXPORT export_${PROJECT_NAME} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin ) -########## -## Test ## -########## - -## GTest. -if(CATKIN_ENABLE_TESTING) - ## Find catkin dependencies, including test dependencies. - find_package(catkin REQUIRED - COMPONENTS - ${CATKIN_PACKAGE_DEPENDENCIES} - ) - - catkin_add_gtest(test_${PROJECT_NAME} - test/TestDerivativeFilter.cpp - test/TestFilters.cpp - test/TestLookup.cpp - ) -endif() - -## Link GTest. -if(TARGET test_${PROJECT_NAME}) - target_link_libraries(test_${PROJECT_NAME} - ${PROJECT_NAME} - ${catkin_LIBRARIES} - gtest_main - ) - - target_include_directories(test_${PROJECT_NAME} PRIVATE - include - ) - - target_include_directories(test_${PROJECT_NAME} SYSTEM PUBLIC - ${catkin_INCLUDE_DIRS} - ) - - # Generate test coverage report - find_package(cmake_code_coverage QUIET) - if(cmake_code_coverage_FOUND) - add_gtest_coverage( - TEST_BUILD_TARGETS test_${PROJECT_NAME} - ) - endif(cmake_code_coverage_FOUND) -endif() - -############# -## Install ## -############# -install( - TARGETS - ${PROJECT_NAME} - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# Install headers +install(DIRECTORY include/${PROJECT_NAME}/ + DESTINATION include/${PROJECT_NAME}/ ) -install( - DIRECTORY - include/${PROJECT_NAME}/ - DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} -) -########### -## Clang ## -########### +# Clang tools (optional) find_package(cmake_clang_tools QUIET) if(cmake_clang_tools_FOUND) add_default_clang_tooling() -endif(cmake_clang_tools_FOUND) \ No newline at end of file +endif() + +ament_package() \ No newline at end of file diff --git a/plane_segmentation/grid_map_filters_rsl/package.xml b/plane_segmentation/grid_map_filters_rsl/package.xml index 3df62480..fbea7dc0 100644 --- a/plane_segmentation/grid_map_filters_rsl/package.xml +++ b/plane_segmentation/grid_map_filters_rsl/package.xml @@ -1,19 +1,38 @@ - - grid_map_filters_rsl - 0.1.0 - Extension of grid map filters package with op-cv filters and others - Fabian Jenelten + + grid_map_filters_rsl + 0.1.0 + Extension of grid map filters package with OpenCV filters and others - Fabian Jenelten + Fabian Jenelten + Fabian Jenelten - MIT + MIT - catkin - cmake_clang_tools - grid_map_cv - grid_map_core + + ament_cmake - gtest - cmake_code_coverage - + + ament_cmake + cmake_clang_tools + grid_map_cv + grid_map_core + Eigen3 + + + rosidl_runtime_cpp + + + grid_map_cv + grid_map_core + sensor_msgs + + + ament_cmake_gtest + ament_cmake_pytest + + + + ament_cmake + + \ No newline at end of file From 6d2c1b40253ba50f7d42da1e06b25b18f1ce3bf5 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Mon, 30 Sep 2024 10:32:47 +0200 Subject: [PATCH 444/504] semantic sensor ros2 --- .../semantic_sensor/CMakeLists.txt | 51 +++++++++---------- .../launch/semantic_image.launch.py | 14 +++++ .../launch/semantic_pointcloud.launch.py | 14 +++++ sensor_processing/semantic_sensor/package.xml | 18 +++---- 4 files changed, 57 insertions(+), 40 deletions(-) create mode 100644 sensor_processing/semantic_sensor/launch/semantic_image.launch.py create mode 100644 sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch.py diff --git a/sensor_processing/semantic_sensor/CMakeLists.txt b/sensor_processing/semantic_sensor/CMakeLists.txt index bdc8a1b7..04fe1c0f 100644 --- a/sensor_processing/semantic_sensor/CMakeLists.txt +++ b/sensor_processing/semantic_sensor/CMakeLists.txt @@ -1,33 +1,28 @@ -cmake_minimum_required(VERSION 3.0.2) +cmake_minimum_required(VERSION 3.8) project(semantic_sensor) -find_package(PythonInterp 3 REQUIRED) -find_package(PythonLibs 3 REQUIRED) - -if(PYTHONLIBS_FOUND) - message(STATUS "Using Python Libraries at: " ${PYTHON_LIBRARIES}) - message(STATUS "Using Python include directories at: " ${PYTHON_INCLUDE_DIRS}) -else() - message(WARNING "Could not find Python Libraries") -endif() - - -find_package(catkin REQUIRED COMPONENTS - message_generation - rospy - tf - tf_conversions - sensor_msgs - std_msgs - geometry_msgs +# Find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclpy REQUIRED) +find_package(tf2_ros REQUIRED) +find_package(sensor_msgs REQUIRED) +find_package(std_msgs REQUIRED) +find_package(geometry_msgs REQUIRED) + +# Install Python modules +ament_python_install_package(${PROJECT_NAME} PACKAGE_DIR script/semantic_sensor) + +# Install Python executables +install(PROGRAMS + script/semantic_sensor/pointcloud_node.py + script/semantic_sensor/image_node.py + DESTINATION lib/${PROJECT_NAME} ) -catkin_package() - -catkin_python_setup() - - - -catkin_install_python(PROGRAMS script/semantic_sensor/pointcloud_node.py script/semantic_sensor/image_node.py - DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) +# Install launch files +install(DIRECTORY + launch + DESTINATION share/${PROJECT_NAME} +) +ament_package() \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/launch/semantic_image.launch.py b/sensor_processing/semantic_sensor/launch/semantic_image.launch.py new file mode 100644 index 00000000..50d551f2 --- /dev/null +++ b/sensor_processing/semantic_sensor/launch/semantic_image.launch.py @@ -0,0 +1,14 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='semantic_sensor', + executable='image_node.py', + name='semantic_image', + arguments=['front_cam_image'], + output='screen', + parameters=[{'ros__parameters': 'config/sensor_parameter.yaml'}] + ) + ]) \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch.py b/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch.py new file mode 100644 index 00000000..91fbb8c9 --- /dev/null +++ b/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch.py @@ -0,0 +1,14 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='semantic_sensor', + executable='pointcloud_node.py', + name='semantic_pointcloud', + arguments=['front_cam'], + output='screen', + parameters=[{'ros__parameters': 'config/sensor_parameter.yaml'}] + ) + ]) \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/package.xml b/sensor_processing/semantic_sensor/package.xml index 635775eb..5637b4d4 100644 --- a/sensor_processing/semantic_sensor/package.xml +++ b/sensor_processing/semantic_sensor/package.xml @@ -1,27 +1,21 @@ - + semantic_sensor 0.0.0 The semantic_sensor package Gian Erni - MIT + https://github.com/leggedrobotics/elevation_mapping_semantic_cupy - https://github.com/leggedrobotics/elevation_mapping_semantic_cupy - - - Gian Erni - - catkin - rospy - roslib - tf - tf_conversions + ament_cmake + rclpy + tf2_ros sensor_msgs std_msgs geometry_msgs + python3 From f4ac1bd7c27b5648beecf4836712cb660eef7858 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Tue, 1 Oct 2024 15:15:42 +0200 Subject: [PATCH 445/504] restructuring --- elevation_map_msgs/CMakeLists.txt | 3 +- elevation_map_msgs/package.xml | 1 + elevation_mapping_cupy/CMakeLists.txt | 96 +++----------- .../elevation_mapping_cupy/__init__.py | 0 .../elevation_mapping.py | 1 + .../elevation_mapping_ros.py | 121 +++++++++--------- .../elevation_mapping_cupy/fusion/__init__.py | 0 .../fusion/fusion_manager.py | 0 .../fusion/image_color.py | 0 .../fusion/image_exponential.py | 0 .../fusion/pointcloud_average.py | 0 .../fusion/pointcloud_bayesian_inference.py | 0 .../fusion/pointcloud_class_average.py | 0 .../fusion/pointcloud_class_bayesian.py | 0 .../fusion/pointcloud_class_max.py | 0 .../fusion/pointcloud_color.py | 0 .../kernels/__init__.py | 0 .../kernels/custom_image_kernels.py | 0 .../kernels/custom_kernels.py | 0 .../kernels/custom_semantic_kernels.py | 0 .../elevation_mapping_cupy/map_initializer.py | 0 .../elevation_mapping_cupy/parameter.py | 0 .../plugins/__init__.py | 0 .../elevation_mapping_cupy/plugins/erosion.py | 0 .../plugins/features_pca.py | 0 .../plugins/inpainting.py | 0 .../plugins/max_layer_filter.py | 0 .../plugins/min_filter.py | 0 .../plugins/plugin_manager.py | 0 .../plugins/robot_centric_elevation.py | 0 .../plugins/semantic_filter.py | 0 .../plugins/semantic_traversability.py | 0 .../plugins/smooth_filter.py | 0 .../elevation_mapping_cupy/semantic_map.py | 0 .../elevation_mapping_cupy/tests/__init__.py | 0 .../tests/plugin_config.yaml | 0 .../tests/test_elevation_mapping.py | 0 .../tests/test_parameter.py | 0 .../tests/test_plugins.py | 0 .../tests/test_semantic_kernels.py | 0 .../tests/test_semantic_map.py | 0 .../traversability_filter.py | 0 .../traversability_polygon.py | 0 .../launch/elevation_mapping_launch.py | 16 +++ elevation_mapping_cupy/package.xml | 22 ++-- elevation_mapping_cupy/setup.py | 33 ++++- 46 files changed, 139 insertions(+), 154 deletions(-) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/__init__.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/elevation_mapping.py (99%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/elevation_mapping_ros.py (69%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/fusion/__init__.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/fusion/fusion_manager.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/fusion/image_color.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/fusion/image_exponential.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/fusion/pointcloud_average.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/fusion/pointcloud_class_average.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/fusion/pointcloud_class_max.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/fusion/pointcloud_color.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/kernels/__init__.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/kernels/custom_image_kernels.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/kernels/custom_kernels.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/kernels/custom_semantic_kernels.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/map_initializer.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/parameter.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/plugins/__init__.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/plugins/erosion.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/plugins/features_pca.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/plugins/inpainting.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/plugins/max_layer_filter.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/plugins/min_filter.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/plugins/plugin_manager.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/plugins/robot_centric_elevation.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/plugins/semantic_filter.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/plugins/semantic_traversability.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/plugins/smooth_filter.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/semantic_map.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/tests/__init__.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/tests/plugin_config.yaml (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/tests/test_elevation_mapping.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/tests/test_parameter.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/tests/test_plugins.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/tests/test_semantic_kernels.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/tests/test_semantic_map.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/traversability_filter.py (100%) rename elevation_mapping_cupy/{script => }/elevation_mapping_cupy/traversability_polygon.py (100%) create mode 100755 elevation_mapping_cupy/launch/elevation_mapping_launch.py diff --git a/elevation_map_msgs/CMakeLists.txt b/elevation_map_msgs/CMakeLists.txt index 7a4c23da..2ee13395 100644 --- a/elevation_map_msgs/CMakeLists.txt +++ b/elevation_map_msgs/CMakeLists.txt @@ -19,8 +19,7 @@ set(srv_files rosidl_generate_interfaces(${PROJECT_NAME} ${msg_files} ${srv_files} - DEPENDENCIES geometry_msgs - DEPENDENCIES std_msgs # Added dependency + DEPENDENCIES geometry_msgs std_msgs # Combined dependencies ) ament_export_dependencies(rosidl_default_runtime) diff --git a/elevation_map_msgs/package.xml b/elevation_map_msgs/package.xml index d30443e7..eec97b14 100644 --- a/elevation_map_msgs/package.xml +++ b/elevation_map_msgs/package.xml @@ -20,5 +20,6 @@ rosidl_interface_packages + ament_cmake diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index bc4cf6a0..68a1c1af 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -1,80 +1,24 @@ -# %Tag(FULLTEXT)% -cmake_minimum_required(VERSION 3.0.2) +cmake_minimum_required(VERSION 3.5) project(elevation_mapping_cupy) -find_package(PythonInterp 3 REQUIRED) -find_package(PythonLibs 3 REQUIRED) -find_package(OpenCV REQUIRED) - -if(PYTHONLIBS_FOUND) - message(STATUS "Using Python Libraries at: " ${PYTHON_LIBRARIES}) - message(STATUS "Using Python include directories at: " ${PYTHON_INCLUDE_DIRS}) -else() - message(WARNING "Could not find Python Libraries") -endif() - -find_package(Eigen3 REQUIRED) - -find_package(catkin REQUIRED - roscpp - rospy - tf - tf_conversions - sensor_msgs - std_msgs - geometry_msgs - elevation_map_msgs - grid_map_msgs - grid_map_ros - image_transport - pcl_ros - pybind11_catkin -) - -catkin_package( - INCLUDE_DIRS - include - ${EIGEN3_INCLUDE_DIRS} - CATKIN_DEPENDS - roscpp - rospy - tf - tf_conversions - sensor_msgs - std_msgs - geometry_msgs - elevation_map_msgs - grid_map_ros - image_transport - pcl_ros - pybind11_catkin -) - -include_directories( - include - ${PYTHON_INCLUDE_DIRS} - ${catkin_INCLUDE_DIRS} - ${EIGEN3_INCLUDE_DIRS} - ${OpenCV_INCLUDE_DIRS} +find_package(ament_cmake_python REQUIRED) +find_package(rclpy REQUIRED) +find_package(std_msgs REQUIRED) +find_package(sensor_msgs REQUIRED) +find_package(geometry_msgs REQUIRED) +find_package(elevation_map_msgs REQUIRED) +find_package(grid_map_msgs REQUIRED) +find_package(grid_map_ros REQUIRED) +find_package(image_transport REQUIRED) +find_package(pcl_ros REQUIRED) +find_package(pybind11 REQUIRED) + +# Install Python modules +ament_python_install_package(${PROJECT_NAME}) + +# Install launch and config directories +install(DIRECTORY launch config + DESTINATION share/${PROJECT_NAME}/ ) -add_library(elevation_mapping_ros - src/elevation_mapping_wrapper.cpp - src/elevation_mapping_ros.cpp) - -target_link_libraries(elevation_mapping_ros ${PYTHON_LIBRARIES} ${catkin_LIBRARIES} ${OpenCV_LIBRARIES}) - -add_executable(elevation_mapping_node src/elevation_mapping_node.cpp) -target_link_libraries(elevation_mapping_node elevation_mapping_ros) - -catkin_python_setup() - -install( - TARGETS elevation_mapping_ros elevation_mapping_node - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) - -install( - DIRECTORY launch config - DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) +ament_package() diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py b/elevation_mapping_cupy/elevation_mapping_cupy/__init__.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py rename to elevation_mapping_cupy/elevation_mapping_cupy/__init__.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py similarity index 99% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py rename to elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py index b78aeb45..c189fd68 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py @@ -20,6 +20,7 @@ add_color_kernel, color_average_kernel, ) + from elevation_mapping_cupy.kernels import sum_kernel from elevation_mapping_cupy.kernels import error_counting_kernel from elevation_mapping_cupy.kernels import average_map_kernel diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py similarity index 69% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py rename to elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py index c28823e9..34d2b8a3 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py @@ -6,7 +6,8 @@ import numpy as np # ROS -import rospy +import rclpy +from rclpy.node import Node import ros_numpy from tf.transformations import quaternion_matrix import tf2_ros @@ -35,8 +36,9 @@ } -class ElevationMapWrapper: +class ElevationMappingNode(Node): def __init__(self): + super().__init__('elevation_mapping_node') rospack = rospkg.RosPack() self.root = rospack.get_path("elevation_mapping_cupy") weight_file = os.path.join(self.root, "config/core/weights.dat") @@ -67,7 +69,6 @@ def initalize_elevation_mapping(self): self._map_t = None def initalize_ros(self): - rospy.init_node(self.node_name, anonymous=False) self._tf_buffer = tf2_ros.Buffer() self._listener = tf2_ros.TransformListener(self._tf_buffer) self.get_ros_params() @@ -91,25 +92,25 @@ def register_subscribers(self): image_subs[key].registerCallback(self.image_callback, key) elif config["data_type"] == "pointcloud": - pointcloud_subs[key] = rospy.Subscriber( - config["topic_name"], PointCloud2, self.pointcloud_callback, key + pointcloud_subs[key] = self.create_subscription( + PointCloud2, config["topic_name"], self.pointcloud_callback, key ) def register_publishers(self): self._publishers = {} self._publishers_timers = [] for k, v in self.publishers.items(): - self._publishers[k] = rospy.Publisher(f"/{self.node_name}/{k}", GridMap, queue_size=10) + self._publishers[k] = self.create_publisher(GridMap, f"/{self.node_name}/{k}", 10) # partial(.) allows to pass a default argument to a callback - self._publishers_timers.append(rospy.Timer(rospy.Duration(1 / v["fps"]), partial(self.publish_map, k))) + self._publishers_timers.append(self.create_timer(1 / v["fps"], partial(self.publish_map, k))) - def publish_map(self, k, t): + def publish_map(self, k): print("publish_map") if self._map_q is None: return gm = GridMap() gm.info.header.frame_id = self.map_frame - gm.info.header.stamp = rospy.Time.now() + gm.info.header.stamp = self.get_clock().now().to_msg() gm.info.header.seq = 0 gm.info.resolution = self._map.resolution gm.info.length_x = self._map.map_length @@ -145,13 +146,13 @@ def publish_map(self, k, t): self._publishers[k].publish(gm) def register_timers(self): - self.timer_variance = rospy.Timer(rospy.Duration(1 / self.update_variance_fps), self.update_variance) - self.timer_pose = rospy.Timer(rospy.Duration(1 / self.update_pose_fps), self.update_pose) - self.timer_time = rospy.Timer(rospy.Duration(self.time_interval), self.update_time) + self.timer_variance = self.create_timer(1 / self.update_variance_fps, self.update_variance) + self.timer_pose = self.create_timer(1 / self.update_pose_fps, self.update_pose) + self.timer_time = self.create_timer(self.time_interval, self.update_time) def image_callback(self, camera_msg, camera_info_msg, sub_key): # get pose of image - ti = rospy.Time(secs=camera_msg.header.stamp.secs, nsecs=camera_msg.header.stamp.nsecs) + ti = camera_msg.header.stamp self._last_t = ti try: transform = self._tf_buffer.lookup_transform( @@ -195,7 +196,7 @@ def pointcloud_callback(self, msg, sub_key): pts = np.append(pts, p, axis=1) # get pose of pointcloud - ti = rospy.Time(secs=msg.header.stamp.secs, nsecs=msg.header.stamp.nsecs) + ti = msg.header.stamp self._last_t = ti try: transform = self._tf_buffer.lookup_transform(self.map_frame, msg.header.frame_id, ti, rospy.Duration(1.0)) @@ -213,7 +214,7 @@ def pointcloud_callback(self, msg, sub_key): self._pointcloud_process_counter += 1 print("Pointclouds processed: ", self._pointcloud_process_counter) - def update_pose(self, t): + def update_pose(self): # get pose of base # t = rospy.Time.now() if self._last_t is None: @@ -234,54 +235,52 @@ def update_pose(self, t): self._map_t = t self._map_q = q - def update_variance(self, t): + def update_variance(self): self._map.update_variance() - def update_time(self, t): + def update_time(self): self._map.update_time() + def get_ros_params(self): - # TODO fix this here when later launching with launch-file - # This is currently {p} elevation_mapping") - typ = "sim" - para = os.path.join(self.root, f"config/{typ}_parameters.yaml") - sens = os.path.join(self.root, f"config/{typ}_sensor_parameter.yaml") - plugin = os.path.join(self.root, f"config/{typ}_plugin_config.yaml") - - os.system(f"rosparam delete /{self.node_name}") - os.system(f"rosparam load {para} elevation_mapping") - os.system(f"rosparam load {sens} elevation_mapping") - os.system(f"rosparam load {plugin} elevation_mapping") - - self.subscribers = rospy.get_param("~subscribers") - self.publishers = rospy.get_param("~publishers") - self.initialize_frame_id = rospy.get_param("~initialize_frame_id", "base") - self.initialize_tf_offset = rospy.get_param("~initialize_tf_offset", 0.0) - self.pose_topic = rospy.get_param("~pose_topic", "pose") - self.map_frame = rospy.get_param("~map_frame", "map") - self.base_frame = rospy.get_param("~base_frame", "base") - self.corrected_map_frame = rospy.get_param("~corrected_map_frame", "corrected_map") - self.initialize_method = rospy.get_param("~initialize_method", "cubic") - self.position_lowpass_alpha = rospy.get_param("~position_lowpass_alpha", 0.2) - self.orientation_lowpass_alpha = rospy.get_param("~orientation_lowpass_alpha", 0.2) - self.recordable_fps = rospy.get_param("~recordable_fps", 3.0) - self.update_variance_fps = rospy.get_param("~update_variance_fps", 1.0) - self.time_interval = rospy.get_param("~time_interval", 0.1) - self.update_pose_fps = rospy.get_param("~update_pose_fps", 10.0) - self.initialize_tf_grid_size = rospy.get_param("~initialize_tf_grid_size", 0.5) - self.map_acquire_fps = rospy.get_param("~map_acquire_fps", 5.0) - self.publish_statistics_fps = rospy.get_param("~publish_statistics_fps", 1.0) - self.enable_pointcloud_publishing = rospy.get_param("~enable_pointcloud_publishing", False) - self.enable_normal_arrow_publishing = rospy.get_param("~enable_normal_arrow_publishing", False) - self.enable_drift_corrected_TF_publishing = rospy.get_param("~enable_drift_corrected_TF_publishing", False) - self.use_initializer_at_start = rospy.get_param("~use_initializer_at_start", False) - - -if __name__ == "__main__": - emw = ElevationMapWrapper() - - while not rospy.is_shutdown(): - try: - rospy.spin() - except rospy.ROSInterruptException: - print("Error") + self.declare_parameter('use_chainer', False) + self.declare_parameter('weight_file', '$(rospack find elevation_mapping_cupy)/config/core/weights.dat') + self.declare_parameter('plugin_config_file', '$(rospack find elevation_mapping_cupy)/config/core/plugin_config.yaml') + + self.subscribers = self.get_parameter("subscribers").value + self.publishers = self.get_parameter("publishers").value + self.initialize_frame_id = self.get_parameter("initialize_frame_id").value + self.initialize_tf_offset = self.get_parameter("initialize_tf_offset").value + self.pose_topic = self.get_parameter("pose_topic").value + self.map_frame = self.get_parameter("map_frame").value + self.base_frame = self.get_parameter("base_frame").value + self.corrected_map_frame = self.get_parameter("corrected_map_frame").value + self.initialize_method = self.get_parameter("initialize_method").value + self.position_lowpass_alpha = self.get_parameter("position_lowpass_alpha").value + self.orientation_lowpass_alpha = self.get_parameter("orientation_lowpass_alpha").value + self.recordable_fps = self.get_parameter("recordable_fps").value + self.update_variance_fps = self.get_parameter("update_variance_fps").value + self.time_interval = self.get_parameter("time_interval").value + self.update_pose_fps = self.get_parameter("update_pose_fps").value + self.initialize_tf_grid_size = self.get_parameter("initialize_tf_grid_size").value + self.map_acquire_fps = self.get_parameter("map_acquire_fps").value + self.publish_statistics_fps = self.get_parameter("publish_statistics_fps").value + self.enable_pointcloud_publishing = self.get_parameter("enable_pointcloud_publishing").value + self.enable_normal_arrow_publishing = self.get_parameter("enable_normal_arrow_publishing").value + self.enable_drift_corrected_TF_publishing = self.get_parameter("enable_drift_corrected_TF_publishing").value + self.use_initializer_at_start = self.get_parameter("use_initializer_at_start").value + + +def main(args=None): + rclpy.init(args=args) + node = ElevationMappingNode() + try: + rclpy.spin(node) + except KeyboardInterrupt: + pass + finally: + node.destroy_node() + rclpy.shutdown() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/__init__.py b/elevation_mapping_cupy/elevation_mapping_cupy/fusion/__init__.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/__init__.py rename to elevation_mapping_cupy/elevation_mapping_cupy/fusion/__init__.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py b/elevation_mapping_cupy/elevation_mapping_cupy/fusion/fusion_manager.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/fusion_manager.py rename to elevation_mapping_cupy/elevation_mapping_cupy/fusion/fusion_manager.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py b/elevation_mapping_cupy/elevation_mapping_cupy/fusion/image_color.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_color.py rename to elevation_mapping_cupy/elevation_mapping_cupy/fusion/image_color.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py b/elevation_mapping_cupy/elevation_mapping_cupy/fusion/image_exponential.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_exponential.py rename to elevation_mapping_cupy/elevation_mapping_cupy/fusion/image_exponential.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py b/elevation_mapping_cupy/elevation_mapping_cupy/fusion/pointcloud_average.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_average.py rename to elevation_mapping_cupy/elevation_mapping_cupy/fusion/pointcloud_average.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py b/elevation_mapping_cupy/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py rename to elevation_mapping_cupy/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py b/elevation_mapping_cupy/elevation_mapping_cupy/fusion/pointcloud_class_average.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_average.py rename to elevation_mapping_cupy/elevation_mapping_cupy/fusion/pointcloud_class_average.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py b/elevation_mapping_cupy/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py rename to elevation_mapping_cupy/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py b/elevation_mapping_cupy/elevation_mapping_cupy/fusion/pointcloud_class_max.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_class_max.py rename to elevation_mapping_cupy/elevation_mapping_cupy/fusion/pointcloud_class_max.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py b/elevation_mapping_cupy/elevation_mapping_cupy/fusion/pointcloud_color.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/pointcloud_color.py rename to elevation_mapping_cupy/elevation_mapping_cupy/fusion/pointcloud_color.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/__init__.py b/elevation_mapping_cupy/elevation_mapping_cupy/kernels/__init__.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/__init__.py rename to elevation_mapping_cupy/elevation_mapping_cupy/kernels/__init__.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/elevation_mapping_cupy/kernels/custom_image_kernels.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_image_kernels.py rename to elevation_mapping_cupy/elevation_mapping_cupy/kernels/custom_image_kernels.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py b/elevation_mapping_cupy/elevation_mapping_cupy/kernels/custom_kernels.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py rename to elevation_mapping_cupy/elevation_mapping_cupy/kernels/custom_kernels.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py b/elevation_mapping_cupy/elevation_mapping_cupy/kernels/custom_semantic_kernels.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_semantic_kernels.py rename to elevation_mapping_cupy/elevation_mapping_cupy/kernels/custom_semantic_kernels.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/map_initializer.py b/elevation_mapping_cupy/elevation_mapping_cupy/map_initializer.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/map_initializer.py rename to elevation_mapping_cupy/elevation_mapping_cupy/map_initializer.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/elevation_mapping_cupy/parameter.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py rename to elevation_mapping_cupy/elevation_mapping_cupy/parameter.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/__init__.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/__init__.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/__init__.py rename to elevation_mapping_cupy/elevation_mapping_cupy/plugins/__init__.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/erosion.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/erosion.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/erosion.py rename to elevation_mapping_cupy/elevation_mapping_cupy/plugins/erosion.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/features_pca.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/features_pca.py rename to elevation_mapping_cupy/elevation_mapping_cupy/plugins/features_pca.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/inpainting.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/inpainting.py rename to elevation_mapping_cupy/elevation_mapping_cupy/plugins/inpainting.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/max_layer_filter.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/max_layer_filter.py rename to elevation_mapping_cupy/elevation_mapping_cupy/plugins/max_layer_filter.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/min_filter.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/min_filter.py rename to elevation_mapping_cupy/elevation_mapping_cupy/plugins/min_filter.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/plugin_manager.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/plugin_manager.py rename to elevation_mapping_cupy/elevation_mapping_cupy/plugins/plugin_manager.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/robot_centric_elevation.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/robot_centric_elevation.py rename to elevation_mapping_cupy/elevation_mapping_cupy/plugins/robot_centric_elevation.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/semantic_filter.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_filter.py rename to elevation_mapping_cupy/elevation_mapping_cupy/plugins/semantic_filter.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/semantic_traversability.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/semantic_traversability.py rename to elevation_mapping_cupy/elevation_mapping_cupy/plugins/semantic_traversability.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/smooth_filter.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/plugins/smooth_filter.py rename to elevation_mapping_cupy/elevation_mapping_cupy/plugins/smooth_filter.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/elevation_mapping_cupy/semantic_map.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/semantic_map.py rename to elevation_mapping_cupy/elevation_mapping_cupy/semantic_map.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/__init__.py b/elevation_mapping_cupy/elevation_mapping_cupy/tests/__init__.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/tests/__init__.py rename to elevation_mapping_cupy/elevation_mapping_cupy/tests/__init__.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/plugin_config.yaml b/elevation_mapping_cupy/elevation_mapping_cupy/tests/plugin_config.yaml similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/tests/plugin_config.yaml rename to elevation_mapping_cupy/elevation_mapping_cupy/tests/plugin_config.yaml diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/elevation_mapping_cupy/tests/test_elevation_mapping.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_elevation_mapping.py rename to elevation_mapping_cupy/elevation_mapping_cupy/tests/test_elevation_mapping.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_parameter.py b/elevation_mapping_cupy/elevation_mapping_cupy/tests/test_parameter.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_parameter.py rename to elevation_mapping_cupy/elevation_mapping_cupy/tests/test_parameter.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/elevation_mapping_cupy/tests/test_plugins.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_plugins.py rename to elevation_mapping_cupy/elevation_mapping_cupy/tests/test_plugins.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py b/elevation_mapping_cupy/elevation_mapping_cupy/tests/test_semantic_kernels.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_kernels.py rename to elevation_mapping_cupy/elevation_mapping_cupy/tests/test_semantic_kernels.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py b/elevation_mapping_cupy/elevation_mapping_cupy/tests/test_semantic_map.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/tests/test_semantic_map.py rename to elevation_mapping_cupy/elevation_mapping_cupy/tests/test_semantic_map.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_filter.py b/elevation_mapping_cupy/elevation_mapping_cupy/traversability_filter.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_filter.py rename to elevation_mapping_cupy/elevation_mapping_cupy/traversability_filter.py diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py b/elevation_mapping_cupy/elevation_mapping_cupy/traversability_polygon.py similarity index 100% rename from elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py rename to elevation_mapping_cupy/elevation_mapping_cupy/traversability_polygon.py diff --git a/elevation_mapping_cupy/launch/elevation_mapping_launch.py b/elevation_mapping_cupy/launch/elevation_mapping_launch.py new file mode 100755 index 00000000..36e3df9d --- /dev/null +++ b/elevation_mapping_cupy/launch/elevation_mapping_launch.py @@ -0,0 +1,16 @@ +from launch import LaunchDescription +from launch_ros.actions import Node +from launch_ros.parameter_descriptions import ParameterFile + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='elevation_mapping_cupy', + executable='elevation_mapping_node', + name='elevation_mapping_node', + output='screen', + parameters=[ + ParameterFile('config/core/core_param.yaml', allow_substs=True) + ] + ) + ]) \ No newline at end of file diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index 9befc801..74c11f5f 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -1,5 +1,5 @@ - + elevation_mapping_cupy 2.0.0 The elevation mapping on GPU @@ -8,19 +8,23 @@ MIT - catkin - roscpp - rospy - tf - tf_conversions - sensor_msgs + + ament_cmake + ament_cmake_python + + + rclpy std_msgs + sensor_msgs geometry_msgs - grid_map_msgs elevation_map_msgs + grid_map_msgs grid_map_ros image_transport pcl_ros - pybind11_catkin + pybind11 + + ament_python + diff --git a/elevation_mapping_cupy/setup.py b/elevation_mapping_cupy/setup.py index 8d5a2492..9225d74c 100644 --- a/elevation_mapping_cupy/setup.py +++ b/elevation_mapping_cupy/setup.py @@ -1,8 +1,29 @@ -from distutils.core import setup -from catkin_pkg.python_setup import generate_distutils_setup +from setuptools import setup, find_packages +import os -setup_args = generate_distutils_setup( - packages=["elevation_mapping_cupy", "elevation_mapping_cupy.plugins",], package_dir={"": "script"}, -) +package_name = 'elevation_mapping_cupy' -setup(**setup_args) +setup( + name=package_name, + version='2.0.0', + packages=find_packages(include=[package_name, f'{package_name}.*']), + install_requires=['setuptools'], + zip_safe=True, + author='Your Name', + author_email='your.email@example.com', + maintainer='Your Name', + maintainer_email='your.email@example.com', + description='Elevation mapping on GPU', + license='MIT', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + 'elevation_mapping_node = elevation_mapping_cupy.elevation_mapping_ros:main', + ], + }, + # Remove data_files for package.xml + data_files=[ + # Add the launch file + (os.path.join('share', package_name, 'launch'), ['launch/elevation_mapping_launch.py']), + ], +) From 66ad5c3e36f2f04767c93abad4741c9f81d1d9ce Mon Sep 17 00:00:00 2001 From: amilearning Date: Fri, 1 Nov 2024 13:08:22 +0000 Subject: [PATCH 446/504] wrapper ros2 done --- elevation_map_msgs/CMakeLists.txt | 65 +- elevation_map_msgs/msg/ChannelInfo.msg | 2 +- elevation_map_msgs/msg/Statistics.msg | 4 +- elevation_map_msgs/package.xml | 21 +- elevation_mapping_cupy/CMakeLists.txt | 112 +- .../elevation_mapping_ros.hpp | 313 ++-- .../elevation_mapping_wrapper.hpp | 21 +- elevation_mapping_cupy/package.xml | 22 +- .../src/elevation_mapping_node.cpp | 20 +- .../src/elevation_mapping_ros.cpp | 1638 ++++++++--------- .../src/elevation_mapping_wrapper.cpp | 209 ++- 11 files changed, 1249 insertions(+), 1178 deletions(-) diff --git a/elevation_map_msgs/CMakeLists.txt b/elevation_map_msgs/CMakeLists.txt index 2d73f5e5..0ea3f7cb 100644 --- a/elevation_map_msgs/CMakeLists.txt +++ b/elevation_map_msgs/CMakeLists.txt @@ -1,32 +1,55 @@ -cmake_minimum_required(VERSION 3.0.2) +cmake_minimum_required(VERSION 3.5) project(elevation_map_msgs) -find_package(catkin REQUIRED) +find_package(ament_cmake REQUIRED) +find_package(geometry_msgs REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(std_msgs REQUIRED) # Added std_msgs -find_package(catkin REQUIRED COMPONENTS - geometry_msgs - message_generation +set(msg_files + "msg/Statistics.msg" + "msg/ChannelInfo.msg" ) -add_message_files( - FILES - Statistics.msg - ChannelInfo.msg +set(srv_files + "srv/CheckSafety.srv" + "srv/Initialize.srv" ) -## Generate services in the 'srv' folder -add_service_files( - FILES - CheckSafety.srv - Initialize.srv +rosidl_generate_interfaces(${PROJECT_NAME} + ${msg_files} + ${srv_files} + DEPENDENCIES geometry_msgs std_msgs # Added std_msgs ) +ament_export_dependencies(rosidl_default_runtime) -## Generate added messages and services with any dependencies listed here -generate_messages( - DEPENDENCIES - geometry_msgs -) +ament_package() + +# cmake_minimum_required(VERSION 3.8) +# project(elevation_map_msgs) + +# if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") +# add_compile_options(-Wall -Wextra -Wpedantic) +# endif() + +# # find dependencies +# find_package(ament_cmake REQUIRED) +# find_package(rosidl_default_generators REQUIRED) +# find_package(builtin_interfaces REQUIRED) +# find_package(std_msgs REQUIRED) +# find_package(geometry_msgs REQUIRED) +# find_package(action_msgs REQUIRED) + +# rosidl_generate_interfaces(${PROJECT_NAME} +# "msg/Statistics.msg" +# "msg/ChannelInfo.msg" +# "srv/CheckSafety.srv" +# "srv/Initialize.srv" +# DEPENDENCIES builtin_interfaces geometry_msgs std_msgs action_msgs +# ) + +# ament_export_dependencies(rosidl_default_runtime) + +# ament_package() -catkin_package( -) diff --git a/elevation_map_msgs/msg/ChannelInfo.msg b/elevation_map_msgs/msg/ChannelInfo.msg index bccf1447..2e6327ec 100644 --- a/elevation_map_msgs/msg/ChannelInfo.msg +++ b/elevation_map_msgs/msg/ChannelInfo.msg @@ -1,2 +1,2 @@ -Header header +std_msgs/Header header string[] channels # channel names for each layer \ No newline at end of file diff --git a/elevation_map_msgs/msg/Statistics.msg b/elevation_map_msgs/msg/Statistics.msg index 294ccb9d..85daaa50 100644 --- a/elevation_map_msgs/msg/Statistics.msg +++ b/elevation_map_msgs/msg/Statistics.msg @@ -1,2 +1,2 @@ - Header header - float64 pointcloud_process_fps +std_msgs/Header header +float64 pointcloud_process_fps diff --git a/elevation_map_msgs/package.xml b/elevation_map_msgs/package.xml index 5fa7a60a..22f222c1 100644 --- a/elevation_map_msgs/package.xml +++ b/elevation_map_msgs/package.xml @@ -1,5 +1,5 @@ - + elevation_map_msgs 0.0.0 ROS Message definitions for elevation mapping. @@ -7,13 +7,24 @@ Takahiro Miki MIT - catkin - + + ament_cmake + geometry_msgs - message_generation + rosidl_default_generators + std_msgs + rosidl_interface_packages + + geometry_msgs + rosidl_default_runtime + std_msgs - geometry_msgs + + ament_lint_auto + ament_lint_common + ament_cmake + rosidl_interface_packages diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index bc4cf6a0..81baa06d 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -1,80 +1,100 @@ -# %Tag(FULLTEXT)% -cmake_minimum_required(VERSION 3.0.2) +cmake_minimum_required(VERSION 3.8) project(elevation_mapping_cupy) +# Enable C++11 (or higher if needed for ROS 2 and pybind11) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Compiler options +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() +# Additional dependencies +find_package(Python COMPONENTS Interpreter Development) find_package(PythonInterp 3 REQUIRED) -find_package(PythonLibs 3 REQUIRED) +find_package(pybind11 CONFIG REQUIRED) +find_package(Eigen3 REQUIRED) find_package(OpenCV REQUIRED) -if(PYTHONLIBS_FOUND) - message(STATUS "Using Python Libraries at: " ${PYTHON_LIBRARIES}) - message(STATUS "Using Python include directories at: " ${PYTHON_INCLUDE_DIRS}) -else() - message(WARNING "Could not find Python Libraries") -endif() +# Find pybind11 -find_package(Eigen3 REQUIRED) +message([MAIN] "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}") +message([MAIN] "pybind11_INCLUDE_DIRS = ${pybind11_INCLUDE_DIRS}") +message([MAIN] "pybind11_LIBRARIES = ${pybind11_LIBRARIES}") -find_package(catkin REQUIRED - roscpp - rospy - tf - tf_conversions - sensor_msgs +# Find ROS 2 dependencies +find_package(message_filters REQUIRED) +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +find_package(rclpy REQUIRED) +find_package(builtin_interfaces REQUIRED) +find_package(std_msgs REQUIRED) +find_package(std_srvs REQUIRED) +find_package(sensor_msgs REQUIRED) +find_package(grid_map_msgs REQUIRED) +find_package(geometry_msgs REQUIRED) +find_package(elevation_map_msgs REQUIRED) +find_package(grid_map_ros REQUIRED) +find_package(image_transport REQUIRED) +find_package(pcl_ros REQUIRED) + + +# List dependencies for ament_target_dependencies +set(dependencies + rclcpp + rclpy std_msgs + std_srvs + builtin_interfaces geometry_msgs + sensor_msgs elevation_map_msgs grid_map_msgs grid_map_ros image_transport pcl_ros - pybind11_catkin -) - -catkin_package( - INCLUDE_DIRS - include - ${EIGEN3_INCLUDE_DIRS} - CATKIN_DEPENDS - roscpp - rospy - tf - tf_conversions - sensor_msgs - std_msgs - geometry_msgs - elevation_map_msgs - grid_map_ros - image_transport - pcl_ros - pybind11_catkin + message_filters ) +# Include directories include_directories( include ${PYTHON_INCLUDE_DIRS} - ${catkin_INCLUDE_DIRS} - ${EIGEN3_INCLUDE_DIRS} + ${Eigen3_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} + ${pybind11_INCLUDE_DIRS} ) +# Declare C++ library add_library(elevation_mapping_ros src/elevation_mapping_wrapper.cpp - src/elevation_mapping_ros.cpp) + src/elevation_mapping_ros.cpp +) -target_link_libraries(elevation_mapping_ros ${PYTHON_LIBRARIES} ${catkin_LIBRARIES} ${OpenCV_LIBRARIES}) +# Link the library with necessary dependencies +target_link_libraries(elevation_mapping_ros ${PYTHON_LIBRARIES} ${OpenCV_LIBRARIES}) +ament_target_dependencies(elevation_mapping_ros ${dependencies}) +# Declare C++ executable add_executable(elevation_mapping_node src/elevation_mapping_node.cpp) -target_link_libraries(elevation_mapping_node elevation_mapping_ros) -catkin_python_setup() +# Link the executable with the library and dependencies +target_link_libraries(elevation_mapping_node elevation_mapping_ros ${OpenCV_LIBRARIES}) +ament_target_dependencies(elevation_mapping_node ${dependencies}) +# Install targets install( TARGETS elevation_mapping_ros elevation_mapping_node - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin +) +# Install launch and config directories install( DIRECTORY launch config - DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) + DESTINATION share/${PROJECT_NAME} +) + +# Ament package declaration +ament_package() diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 0fb75b6a..f631fbba 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -16,26 +16,29 @@ #include // everything needed for embedding // ROS -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include "message_filters/subscriber.h" +#include "message_filters/sync_policies/approximate_time.h" +#include "message_filters/synchronizer.h" +#include +#include +#include +#include +#include "std_srvs/srv/empty.h" +#include + +#include +#include +#include + +#include +#include // Grid Map -#include -#include +#include +#include #include // PCL @@ -47,145 +50,145 @@ #include #include -#include -#include -#include +#include +#include +#include #include "elevation_mapping_cupy/elevation_mapping_wrapper.hpp" namespace py = pybind11; -namespace elevation_mapping_cupy { - -class ElevationMappingNode { - public: - ElevationMappingNode(ros::NodeHandle& nh); - using RowMatrixXd = Eigen::Matrix; - using ColMatrixXf = Eigen::Matrix; - - using ImageSubscriber = image_transport::SubscriberFilter; - using ImageSubscriberPtr = std::shared_ptr; - - // Subscriber and Synchronizer for CameraInfo messages - using CameraInfoSubscriber = message_filters::Subscriber; - using CameraInfoSubscriberPtr = std::shared_ptr; - using CameraPolicy = message_filters::sync_policies::ApproximateTime; - using CameraSync = message_filters::Synchronizer; - using CameraSyncPtr = std::shared_ptr; - - // Subscriber and Synchronizer for ChannelInfo messages - using ChannelInfoSubscriber = message_filters::Subscriber; - using ChannelInfoSubscriberPtr = std::shared_ptr; - using CameraChannelPolicy = message_filters::sync_policies::ApproximateTime; - using CameraChannelSync = message_filters::Synchronizer; - using CameraChannelSyncPtr = std::shared_ptr; - - // Subscriber and Synchronizer for Pointcloud messages - using PointCloudSubscriber = message_filters::Subscriber; - using PointCloudSubscriberPtr = std::shared_ptr; - using PointCloudPolicy = message_filters::sync_policies::ApproximateTime; - using PointCloudSync = message_filters::Synchronizer; - using PointCloudSyncPtr = std::shared_ptr; - - private: - void readParameters(); - void setupMapPublishers(); - void pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key); - void inputPointCloud(const sensor_msgs::PointCloud2& cloud, const std::vector& channels); - void inputImage(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::vector& channels); - void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::string& key); - void imageChannelCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg); - void pointCloudChannelCallback(const sensor_msgs::PointCloud2& cloud, const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg); - // void multiLayerImageCallback(const elevation_map_msgs::MultiLayerImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg); - void publishAsPointCloud(const grid_map::GridMap& map) const; - bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); - bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response); - bool initializeMap(elevation_map_msgs::Initialize::Request& request, elevation_map_msgs::Initialize::Response& response); - bool clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); - bool clearMapWithInitializer(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); - bool setPublishPoint(std_srvs::SetBool::Request& request, std_srvs::SetBool::Response& response); - void updatePose(const ros::TimerEvent&); - void updateVariance(const ros::TimerEvent&); - void updateTime(const ros::TimerEvent&); - void updateGridMap(const ros::TimerEvent&); - void publishNormalAsArrow(const grid_map::GridMap& map) const; - void initializeWithTF(); - void publishMapToOdom(double error); - void publishStatistics(const ros::TimerEvent&); - void publishMapOfIndex(int index); - - visualization_msgs::Marker vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id) const; - - ros::NodeHandle nh_; - image_transport::ImageTransport it_; - std::vector pointcloudSubs_; - std::vector imageSubs_; - std::vector cameraInfoSubs_; - std::vector channelInfoSubs_; - std::vector cameraSyncs_; - std::vector cameraChannelSyncs_; - std::vector pointCloudSyncs_; - std::vector mapPubs_; - tf::TransformBroadcaster tfBroadcaster_; - ros::Publisher alivePub_; - ros::Publisher pointPub_; - ros::Publisher normalPub_; - ros::Publisher statisticsPub_; - ros::ServiceServer rawSubmapService_; - ros::ServiceServer clearMapService_; - ros::ServiceServer clearMapWithInitializerService_; - ros::ServiceServer initializeMapService_; - ros::ServiceServer setPublishPointService_; - ros::ServiceServer checkSafetyService_; - ros::Timer updateVarianceTimer_; - ros::Timer updateTimeTimer_; - ros::Timer updatePoseTimer_; - ros::Timer updateGridMapTimer_; - ros::Timer publishStatisticsTimer_; - ros::Time lastStatisticsPublishedTime_; - tf::TransformListener transformListener_; - ElevationMappingWrapper map_; - std::string mapFrameId_; - std::string correctedMapFrameId_; - std::string baseFrameId_; - - // map topics info - std::vector> map_topics_; - std::vector> map_layers_; - std::vector> map_basic_layers_; - std::set map_layers_all_; - std::set map_layers_sync_; - std::vector map_fps_; - std::set map_fps_unique_; - std::vector mapTimers_; - std::map> channels_; - - std::vector initialize_frame_id_; - std::vector initialize_tf_offset_; - std::string initializeMethod_; - - Eigen::Vector3d lowpassPosition_; - Eigen::Vector4d lowpassOrientation_; - - std::mutex mapMutex_; // protects gridMap_ - grid_map::GridMap gridMap_; - std::atomic_bool isGridmapUpdated_; // needs to be atomic (read is not protected by mapMutex_) - - std::mutex errorMutex_; // protects positionError_, and orientationError_ - double positionError_; - double orientationError_; - - double positionAlpha_; - double orientationAlpha_; - - double recordableFps_; - std::atomic_bool enablePointCloudPublishing_; - bool enableNormalArrowPublishing_; - bool enableDriftCorrectedTFPublishing_; - bool useInitializerAtStart_; - double initializeTfGridSize_; - bool alwaysClearWithInitializer_; - std::atomic_int pointCloudProcessCounter_; -}; - -} // namespace elevation_mapping_cupy +// namespace elevation_mapping_cupy { + +// class ElevationMappingNode { +// public: +// ElevationMappingNode(ros::NodeHandle& nh); +// using RowMatrixXd = Eigen::Matrix; +// using ColMatrixXf = Eigen::Matrix; + +// using ImageSubscriber = image_transport::SubscriberFilter; +// using ImageSubscriberPtr = std::shared_ptr; + +// // Subscriber and Synchronizer for CameraInfo messages +// using CameraInfoSubscriber = message_filters::Subscriber; +// using CameraInfoSubscriberPtr = std::shared_ptr; +// using CameraPolicy = message_filters::sync_policies::ApproximateTime; +// using CameraSync = message_filters::Synchronizer; +// using CameraSyncPtr = std::shared_ptr; + +// // Subscriber and Synchronizer for ChannelInfo messages +// using ChannelInfoSubscriber = message_filters::Subscriber; +// using ChannelInfoSubscriberPtr = std::shared_ptr; +// using CameraChannelPolicy = message_filters::sync_policies::ApproximateTime; +// using CameraChannelSync = message_filters::Synchronizer; +// using CameraChannelSyncPtr = std::shared_ptr; + +// // Subscriber and Synchronizer for Pointcloud messages +// using PointCloudSubscriber = message_filters::Subscriber; +// using PointCloudSubscriberPtr = std::shared_ptr; +// using PointCloudPolicy = message_filters::sync_policies::ApproximateTime; +// using PointCloudSync = message_filters::Synchronizer; +// using PointCloudSyncPtr = std::shared_ptr; + +// private: +// void readParameters(); +// void setupMapPublishers(); +// void pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key); +// void inputPointCloud(const sensor_msgs::PointCloud2& cloud, const std::vector& channels); +// void inputImage(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::vector& channels); +// void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::string& key); +// void imageChannelCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg); +// void pointCloudChannelCallback(const sensor_msgs::PointCloud2& cloud, const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg); +// // void multiLayerImageCallback(const elevation_map_msgs::MultiLayerImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg); +// void publishAsPointCloud(const grid_map::GridMap& map) const; +// bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); +// bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response); +// bool initializeMap(elevation_map_msgs::Initialize::Request& request, elevation_map_msgs::Initialize::Response& response); +// bool clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); +// bool clearMapWithInitializer(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); +// bool setPublishPoint(std_srvs::SetBool::Request& request, std_srvs::SetBool::Response& response); +// void updatePose(const ros::TimerEvent&); +// void updateVariance(const ros::TimerEvent&); +// void updateTime(const ros::TimerEvent&); +// void updateGridMap(const ros::TimerEvent&); +// void publishNormalAsArrow(const grid_map::GridMap& map) const; +// void initializeWithTF(); +// void publishMapToOdom(double error); +// void publishStatistics(const ros::TimerEvent&); +// void publishMapOfIndex(int index); + +// visualization_msgs::Marker vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id) const; + +// ros::NodeHandle nh_; +// image_transport::ImageTransport it_; +// std::vector pointcloudSubs_; +// std::vector imageSubs_; +// std::vector cameraInfoSubs_; +// std::vector channelInfoSubs_; +// std::vector cameraSyncs_; +// std::vector cameraChannelSyncs_; +// std::vector pointCloudSyncs_; +// std::vector mapPubs_; +// tf::TransformBroadcaster tfBroadcaster_; +// ros::Publisher alivePub_; +// ros::Publisher pointPub_; +// ros::Publisher normalPub_; +// ros::Publisher statisticsPub_; +// ros::ServiceServer rawSubmapService_; +// ros::ServiceServer clearMapService_; +// ros::ServiceServer clearMapWithInitializerService_; +// ros::ServiceServer initializeMapService_; +// ros::ServiceServer setPublishPointService_; +// ros::ServiceServer checkSafetyService_; +// ros::Timer updateVarianceTimer_; +// ros::Timer updateTimeTimer_; +// ros::Timer updatePoseTimer_; +// ros::Timer updateGridMapTimer_; +// ros::Timer publishStatisticsTimer_; +// ros::Time lastStatisticsPublishedTime_; +// tf::TransformListener transformListener_; +// ElevationMappingWrapper map_; +// std::string mapFrameId_; +// std::string correctedMapFrameId_; +// std::string baseFrameId_; + +// // map topics info +// std::vector> map_topics_; +// std::vector> map_layers_; +// std::vector> map_basic_layers_; +// std::set map_layers_all_; +// std::set map_layers_sync_; +// std::vector map_fps_; +// std::set map_fps_unique_; +// std::vector mapTimers_; +// std::map> channels_; + +// std::vector initialize_frame_id_; +// std::vector initialize_tf_offset_; +// std::string initializeMethod_; + +// Eigen::Vector3d lowpassPosition_; +// Eigen::Vector4d lowpassOrientation_; + +// std::mutex mapMutex_; // protects gridMap_ +// grid_map::GridMap gridMap_; +// std::atomic_bool isGridmapUpdated_; // needs to be atomic (read is not protected by mapMutex_) + +// std::mutex errorMutex_; // protects positionError_, and orientationError_ +// double positionError_; +// double orientationError_; + +// double positionAlpha_; +// double orientationAlpha_; + +// double recordableFps_; +// std::atomic_bool enablePointCloudPublishing_; +// bool enableNormalArrowPublishing_; +// bool enableDriftCorrectedTFPublishing_; +// bool useInitializerAtStart_; +// double initializeTfGridSize_; +// bool alwaysClearWithInitializer_; +// std::atomic_int pointCloudProcessCounter_; +// }; + +// } // namespace elevation_mapping_cupy diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index 712ed10a..92370e3c 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -15,16 +15,17 @@ #include // everything needed for embedding #include -// ROS -#include -#include -#include -#include -#include +// ROS2 +#include +#include +#include +#include +#include +#include // Grid Map -#include -#include +#include +#include #include // PCL @@ -44,7 +45,7 @@ class ElevationMappingWrapper { ElevationMappingWrapper(); - void initialize(ros::NodeHandle& nh); + void initialize(rclcpp::Node::SharedPtr node); void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); @@ -64,7 +65,7 @@ class ElevationMappingWrapper { void addNormalColorLayer(grid_map::GridMap& map); private: - void setParameters(ros::NodeHandle& nh); + void setParameters(rclcpp::Node::SharedPtr node); py::object map_; py::object param_; double resolution_; diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index 9befc801..9cb9c1bb 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -1,5 +1,5 @@ - + elevation_mapping_cupy 2.0.0 The elevation mapping on GPU @@ -8,19 +8,23 @@ MIT - catkin - roscpp - rospy - tf - tf_conversions - sensor_msgs + ament_cmake + rclcpp std_msgs + std_srvs + sensor_msgs geometry_msgs + message_filters grid_map_msgs elevation_map_msgs grid_map_ros image_transport pcl_ros - pybind11_catkin + pybind11 + ament_lint_auto + ament_lint_common - + + ament_cmake + + \ No newline at end of file diff --git a/elevation_mapping_cupy/src/elevation_mapping_node.cpp b/elevation_mapping_cupy/src/elevation_mapping_node.cpp index 3d7a778f..05fac5d6 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_node.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_node.cpp @@ -6,22 +6,22 @@ // Pybind #include // everything needed for embedding -// ROS -#include - +// ROS2 +#include #include "elevation_mapping_cupy/elevation_mapping_ros.hpp" int main(int argc, char** argv) { - ros::init(argc, argv, "elevation_mapping"); - ros::NodeHandle nh("~"); + rclcpp::init(argc, argv); + auto node = std::make_shared("elevation_mapping"); py::scoped_interpreter guard{}; // start the interpreter and keep it alive - elevation_mapping_cupy::ElevationMappingNode mapNode(nh); + // elevation_mapping_cupy::ElevationMappingNode mapNode(node); py::gil_scoped_release release; // Spin - ros::AsyncSpinner spinner(1); // Use n threads - spinner.start(); - ros::waitForShutdown(); + rclcpp::executors::SingleThreadedExecutor executor; + executor.add_node(node); + executor.spin(); + rclcpp::shutdown(); return 0; -} +} \ No newline at end of file diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 2fbc3128..374bf709 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -1,820 +1,820 @@ -// -// Copyright (c) 2022, Takahiro Miki. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for details. -// - -#include "elevation_mapping_cupy/elevation_mapping_ros.hpp" - -// Pybind -#include - -// ROS -#include -#include -#include - -// PCL -#include - -#include - -namespace elevation_mapping_cupy { - -ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) - : it_(nh), - lowpassPosition_(0, 0, 0), - lowpassOrientation_(0, 0, 0, 1), - positionError_(0), - orientationError_(0), - positionAlpha_(0.1), - orientationAlpha_(0.1), - enablePointCloudPublishing_(false), - isGridmapUpdated_(false) { - nh_ = nh; - - std::string pose_topic, map_frame; - XmlRpc::XmlRpcValue publishers; - XmlRpc::XmlRpcValue subscribers; - std::vector map_topics; - double recordableFps, updateVarianceFps, timeInterval, updatePoseFps, updateGridMapFps, publishStatisticsFps; - bool enablePointCloudPublishing(false); - - // Read parameters - nh.getParam("subscribers", subscribers); - nh.getParam("publishers", publishers); - if (!subscribers.valid()) { - ROS_FATAL("There aren't any subscribers to be configured, the elevation mapping cannot be configured. Exit"); - } - if (!publishers.valid()) { - ROS_FATAL("There aren't any publishers to be configured, the elevation mapping cannot be configured. Exit"); - } - nh.param>("initialize_frame_id", initialize_frame_id_, {"base"}); - nh.param>("initialize_tf_offset", initialize_tf_offset_, {0.0}); - nh.param("pose_topic", pose_topic, "pose"); - nh.param("map_frame", mapFrameId_, "map"); - nh.param("base_frame", baseFrameId_, "base"); - nh.param("corrected_map_frame", correctedMapFrameId_, "corrected_map"); - nh.param("initialize_method", initializeMethod_, "cubic"); - nh.param("position_lowpass_alpha", positionAlpha_, 0.2); - nh.param("orientation_lowpass_alpha", orientationAlpha_, 0.2); - nh.param("recordable_fps", recordableFps, 3.0); - nh.param("update_variance_fps", updateVarianceFps, 1.0); - nh.param("time_interval", timeInterval, 0.1); - nh.param("update_pose_fps", updatePoseFps, 10.0); - nh.param("initialize_tf_grid_size", initializeTfGridSize_, 0.5); - nh.param("map_acquire_fps", updateGridMapFps, 5.0); - nh.param("publish_statistics_fps", publishStatisticsFps, 1.0); - nh.param("enable_pointcloud_publishing", enablePointCloudPublishing, false); - nh.param("enable_normal_arrow_publishing", enableNormalArrowPublishing_, false); - nh.param("enable_drift_corrected_TF_publishing", enableDriftCorrectedTFPublishing_, false); - nh.param("use_initializer_at_start", useInitializerAtStart_, false); - nh.param("always_clear_with_initializer", alwaysClearWithInitializer_, false); - - enablePointCloudPublishing_ = enablePointCloudPublishing; - - // Iterate all the subscribers - // here we have to remove all the stuff - for (auto& subscriber : subscribers) { - std::string key = subscriber.first; - auto type = static_cast(subscriber.second["data_type"]); - - // Initialize subscribers depending on the type - if (type == "pointcloud") { - std::string pointcloud_topic = subscriber.second["topic_name"]; - channels_[key].push_back("x"); - channels_[key].push_back("y"); - channels_[key].push_back("z"); - boost::function f = boost::bind(&ElevationMappingNode::pointcloudCallback, this, _1, key); - ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, f); - pointcloudSubs_.push_back(sub); - ROS_INFO_STREAM("Subscribed to PointCloud2 topic: " << pointcloud_topic); - } - else if (type == "image") { - std::string camera_topic = subscriber.second["topic_name"]; - std::string info_topic = subscriber.second["camera_info_topic_name"]; - - // Handle compressed images with transport hints - // We obtain the hint from the last part of the topic name - std::string transport_hint = "compressed"; - std::size_t ind = camera_topic.find(transport_hint); // Find if compressed is in the topic name - if (ind != std::string::npos) { - transport_hint = camera_topic.substr(ind, camera_topic.length()); // Get the hint as the last part - camera_topic.erase(ind - 1, camera_topic.length()); // We remove the hint from the topic - } else { - transport_hint = "raw"; // In the default case we assume raw topic - } - - // Setup subscriber - const auto hint = image_transport::TransportHints(transport_hint, ros::TransportHints(), ros::NodeHandle(camera_topic)); - ImageSubscriberPtr image_sub = std::make_shared(); - image_sub->subscribe(it_, camera_topic, 1, hint); - imageSubs_.push_back(image_sub); - - CameraInfoSubscriberPtr cam_info_sub = std::make_shared(); - cam_info_sub->subscribe(nh_, info_topic, 1); - cameraInfoSubs_.push_back(cam_info_sub); - - std::string channel_info_topic; - // If there is channel info topic setting, we use it. - if (subscriber.second.hasMember("channel_info_topic_name")) { - std::string channel_info_topic = subscriber.second["channel_info_topic_name"]; - ChannelInfoSubscriberPtr channel_info_sub = std::make_shared(); - channel_info_sub->subscribe(nh_, channel_info_topic, 1); - channelInfoSubs_.push_back(channel_info_sub); - CameraChannelSyncPtr sync = std::make_shared(CameraChannelPolicy(10), *image_sub, *cam_info_sub, *channel_info_sub); - sync->registerCallback(boost::bind(&ElevationMappingNode::imageChannelCallback, this, _1, _2, _3)); - cameraChannelSyncs_.push_back(sync); - ROS_INFO_STREAM("Subscribed to Image topic: " << camera_topic << ", Camera info topic: " << info_topic << ", Channel info topic: " << channel_info_topic); - } - else { - // If there is channels setting, we use it. Otherwise, we use rgb as default. - if (subscriber.second.hasMember("channels")) { - const auto& channels = subscriber.second["channels"]; - for (int32_t i = 0; i < channels.size(); ++i) { - auto elem = static_cast(channels[i]); - channels_[key].push_back(elem); - } - } - else { - channels_[key].push_back("rgb"); - } - ROS_INFO_STREAM("Subscribed to Image topic: " << camera_topic << ", Camera info topic: " << info_topic << ". Channel info topic: " << (channel_info_topic.empty() ? ("Not found. Using channels: " + boost::algorithm::join(channels_[key], ", ")) : channel_info_topic)); - CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); - sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2, key)); - cameraSyncs_.push_back(sync); - } - - - } else { - ROS_WARN_STREAM("Subscriber data_type [" << type << "] Not valid. Supported types: pointcloud, image"); - continue; - } - } - - map_.initialize(nh_); - - // Register map publishers - for (auto itr = publishers.begin(); itr != publishers.end(); ++itr) { - // Parse params - std::string topic_name = itr->first; - std::vector layers_list; - std::vector basic_layers_list; - auto layers = itr->second["layers"]; - auto basic_layers = itr->second["basic_layers"]; - double fps = itr->second["fps"]; - - if (fps > updateGridMapFps) { - ROS_WARN( - "[ElevationMappingCupy] fps for topic %s is larger than map_acquire_fps (%f > %f). The topic data will be only updated at %f " - "fps.", - topic_name.c_str(), fps, updateGridMapFps, updateGridMapFps); - } - - for (int32_t i = 0; i < layers.size(); ++i) { - layers_list.push_back(static_cast(layers[i])); - } - - for (int32_t i = 0; i < basic_layers.size(); ++i) { - basic_layers_list.push_back(static_cast(basic_layers[i])); - } - - // Make publishers - ros::Publisher pub = nh_.advertise(topic_name, 1); - mapPubs_.push_back(pub); - - // Register map layers - map_layers_.push_back(layers_list); - map_basic_layers_.push_back(basic_layers_list); - - // Register map fps - map_fps_.push_back(fps); - map_fps_unique_.insert(fps); - } - setupMapPublishers(); - - pointPub_ = nh_.advertise("elevation_map_points", 1); - alivePub_ = nh_.advertise("alive", 1); - normalPub_ = nh_.advertise("normal", 1); - statisticsPub_ = nh_.advertise("statistics", 1); - - gridMap_.setFrameId(mapFrameId_); - rawSubmapService_ = nh_.advertiseService("get_raw_submap", &ElevationMappingNode::getSubmap, this); - clearMapService_ = nh_.advertiseService("clear_map", &ElevationMappingNode::clearMap, this); - initializeMapService_ = nh_.advertiseService("initialize", &ElevationMappingNode::initializeMap, this); - clearMapWithInitializerService_ = - nh_.advertiseService("clear_map_with_initializer", &ElevationMappingNode::clearMapWithInitializer, this); - setPublishPointService_ = nh_.advertiseService("set_publish_points", &ElevationMappingNode::setPublishPoint, this); - checkSafetyService_ = nh_.advertiseService("check_safety", &ElevationMappingNode::checkSafety, this); - - if (updateVarianceFps > 0) { - double duration = 1.0 / (updateVarianceFps + 0.00001); - updateVarianceTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updateVariance, this, false, true); - } - if (timeInterval > 0) { - double duration = timeInterval; - updateTimeTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updateTime, this, false, true); - } - if (updatePoseFps > 0) { - double duration = 1.0 / (updatePoseFps + 0.00001); - updatePoseTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updatePose, this, false, true); - } - if (updateGridMapFps > 0) { - double duration = 1.0 / (updateGridMapFps + 0.00001); - updateGridMapTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updateGridMap, this, false, true); - } - if (publishStatisticsFps > 0) { - double duration = 1.0 / (publishStatisticsFps + 0.00001); - publishStatisticsTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::publishStatistics, this, false, true); - } - lastStatisticsPublishedTime_ = ros::Time::now(); - ROS_INFO("[ElevationMappingCupy] finish initialization"); -} - -// Setup map publishers -void ElevationMappingNode::setupMapPublishers() { - // Find the layers with highest fps. - float max_fps = -1; - // Create timers for each unique map frequencies - for (auto fps : map_fps_unique_) { - // Which publisher to call in the timer callback - std::vector indices; - // If this fps is max, update the map layers. - if (fps >= max_fps) { - max_fps = fps; - map_layers_all_.clear(); - } - for (int i = 0; i < map_fps_.size(); i++) { - if (map_fps_[i] == fps) { - indices.push_back(i); - // If this fps is max, add layers - if (fps >= max_fps) { - for (const auto layer : map_layers_[i]) { - map_layers_all_.insert(layer); - } - } - } - } - // Callback funtion. - // It publishes to specific topics. - auto cb = [this, indices](const ros::TimerEvent&) { - for (int i : indices) { - publishMapOfIndex(i); - } - }; - double duration = 1.0 / (fps + 0.00001); - mapTimers_.push_back(nh_.createTimer(ros::Duration(duration), cb)); - } -} - -void ElevationMappingNode::publishMapOfIndex(int index) { - // publish the map layers of index - if (!isGridmapUpdated_) { - return; - } - grid_map_msgs::GridMap msg; - std::vector layers; - - { // need continuous lock between adding layers and converting to message. Otherwise updateGridmap can reset the data not in - // map_layers_all_ - std::lock_guard lock(mapMutex_); - for (const auto& layer : map_layers_[index]) { - const bool is_layer_in_all = map_layers_all_.find(layer) != map_layers_all_.end(); - if (is_layer_in_all && gridMap_.exists(layer)) { - layers.push_back(layer); - } else if (map_.exists_layer(layer)) { - // if there are layers which is not in the syncing layer. - ElevationMappingWrapper::RowMatrixXf map_data; - map_.get_layer_data(layer, map_data); - gridMap_.add(layer, map_data); - layers.push_back(layer); - } - } - if (layers.empty()) { - return; - } - - grid_map::GridMapRosConverter::toMessage(gridMap_, layers, msg); - } - - msg.basic_layers = map_basic_layers_[index]; - mapPubs_[index].publish(msg); -} - -void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key) { - - // get channels - auto fields = cloud.fields; - std::vector channels; - - for (int it = 0; it < fields.size(); it++) { - auto& field = fields[it]; - channels.push_back(field.name); - } - inputPointCloud(cloud, channels); - - // This is used for publishing as statistics. - pointCloudProcessCounter_++; -} - -void ElevationMappingNode::inputPointCloud(const sensor_msgs::PointCloud2& cloud, - const std::vector& channels) { - auto start = ros::Time::now(); - auto* pcl_pc = new pcl::PCLPointCloud2; - pcl::PCLPointCloud2ConstPtr cloudPtr(pcl_pc); - pcl_conversions::toPCL(cloud, *pcl_pc); - - // get channels - auto fields = cloud.fields; - uint array_dim = channels.size(); - - RowMatrixXd points = RowMatrixXd(pcl_pc->width * pcl_pc->height, array_dim); - - for (unsigned int i = 0; i < pcl_pc->width * pcl_pc->height; ++i) { - for (unsigned int j = 0; j < channels.size(); ++j) { - float temp; - uint point_idx = i * pcl_pc->point_step + pcl_pc->fields[j].offset; - memcpy(&temp, &pcl_pc->data[point_idx], sizeof(float)); - points(i, j) = static_cast(temp); - } - } - // get pose of sensor in map frame - tf::StampedTransform transformTf; - std::string sensorFrameId = cloud.header.frame_id; - auto timeStamp = cloud.header.stamp; - Eigen::Affine3d transformationSensorToMap; - try { - transformListener_.waitForTransform(mapFrameId_, sensorFrameId, timeStamp, ros::Duration(1.0)); - transformListener_.lookupTransform(mapFrameId_, sensorFrameId, timeStamp, transformTf); - poseTFToEigen(transformTf, transformationSensorToMap); - } catch (tf::TransformException& ex) { - ROS_ERROR("%s", ex.what()); - return; - } - - double positionError{0.0}; - double orientationError{0.0}; - { - std::lock_guard lock(errorMutex_); - positionError = positionError_; - orientationError = orientationError_; - } - map_.input(points, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError, - orientationError); - - if (enableDriftCorrectedTFPublishing_) { - publishMapToOdom(map_.get_additive_mean_error()); - } - - ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed a point cloud (%i points) in %f sec.", static_cast(points.size()), - (ros::Time::now() - start).toSec()); - ROS_DEBUG_THROTTLE(1.0, "positionError: %f ", positionError); - ROS_DEBUG_THROTTLE(1.0, "orientationError: %f ", orientationError); - -} - -void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_msg, - const sensor_msgs::CameraInfoConstPtr& camera_info_msg, - const std::vector& channels) { - // Get image - cv::Mat image = cv_bridge::toCvShare(image_msg, image_msg->encoding)->image; - - // Change encoding to RGB/RGBA - if (image_msg->encoding == "bgr8") { - cv::cvtColor(image, image, CV_BGR2RGB); - } else if (image_msg->encoding == "bgra8") { - cv::cvtColor(image, image, CV_BGRA2RGBA); - } - - // Extract camera matrix - Eigen::Map> cameraMatrix(&camera_info_msg->K[0]); - - // Extract distortion coefficients - Eigen::VectorXd distortionCoeffs; - if (!camera_info_msg->D.empty()) { - distortionCoeffs = Eigen::Map(camera_info_msg->D.data(), camera_info_msg->D.size()); - } else { - ROS_WARN("Distortion coefficients are empty."); - distortionCoeffs = Eigen::VectorXd::Zero(5); - // return; - } - - // distortion model - std::string distortion_model = camera_info_msg->distortion_model; +// // +// // Copyright (c) 2022, Takahiro Miki. All rights reserved. +// // Licensed under the MIT license. See LICENSE file in the project root for details. +// // + +// #include "elevation_mapping_cupy/elevation_mapping_ros.hpp" + +// // Pybind +// #include + +// // ROS +// #include +// #include +// #include + +// // PCL +// #include + +// #include + +// namespace elevation_mapping_cupy { + +// ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) +// : it_(nh), +// lowpassPosition_(0, 0, 0), +// lowpassOrientation_(0, 0, 0, 1), +// positionError_(0), +// orientationError_(0), +// positionAlpha_(0.1), +// orientationAlpha_(0.1), +// enablePointCloudPublishing_(false), +// isGridmapUpdated_(false) { +// nh_ = nh; + +// std::string pose_topic, map_frame; +// XmlRpc::XmlRpcValue publishers; +// XmlRpc::XmlRpcValue subscribers; +// std::vector map_topics; +// double recordableFps, updateVarianceFps, timeInterval, updatePoseFps, updateGridMapFps, publishStatisticsFps; +// bool enablePointCloudPublishing(false); + +// // Read parameters +// nh.getParam("subscribers", subscribers); +// nh.getParam("publishers", publishers); +// if (!subscribers.valid()) { +// ROS_FATAL("There aren't any subscribers to be configured, the elevation mapping cannot be configured. Exit"); +// } +// if (!publishers.valid()) { +// ROS_FATAL("There aren't any publishers to be configured, the elevation mapping cannot be configured. Exit"); +// } +// nh.param>("initialize_frame_id", initialize_frame_id_, {"base"}); +// nh.param>("initialize_tf_offset", initialize_tf_offset_, {0.0}); +// nh.param("pose_topic", pose_topic, "pose"); +// nh.param("map_frame", mapFrameId_, "map"); +// nh.param("base_frame", baseFrameId_, "base"); +// nh.param("corrected_map_frame", correctedMapFrameId_, "corrected_map"); +// nh.param("initialize_method", initializeMethod_, "cubic"); +// nh.param("position_lowpass_alpha", positionAlpha_, 0.2); +// nh.param("orientation_lowpass_alpha", orientationAlpha_, 0.2); +// nh.param("recordable_fps", recordableFps, 3.0); +// nh.param("update_variance_fps", updateVarianceFps, 1.0); +// nh.param("time_interval", timeInterval, 0.1); +// nh.param("update_pose_fps", updatePoseFps, 10.0); +// nh.param("initialize_tf_grid_size", initializeTfGridSize_, 0.5); +// nh.param("map_acquire_fps", updateGridMapFps, 5.0); +// nh.param("publish_statistics_fps", publishStatisticsFps, 1.0); +// nh.param("enable_pointcloud_publishing", enablePointCloudPublishing, false); +// nh.param("enable_normal_arrow_publishing", enableNormalArrowPublishing_, false); +// nh.param("enable_drift_corrected_TF_publishing", enableDriftCorrectedTFPublishing_, false); +// nh.param("use_initializer_at_start", useInitializerAtStart_, false); +// nh.param("always_clear_with_initializer", alwaysClearWithInitializer_, false); + +// enablePointCloudPublishing_ = enablePointCloudPublishing; + +// // Iterate all the subscribers +// // here we have to remove all the stuff +// for (auto& subscriber : subscribers) { +// std::string key = subscriber.first; +// auto type = static_cast(subscriber.second["data_type"]); + +// // Initialize subscribers depending on the type +// if (type == "pointcloud") { +// std::string pointcloud_topic = subscriber.second["topic_name"]; +// channels_[key].push_back("x"); +// channels_[key].push_back("y"); +// channels_[key].push_back("z"); +// boost::function f = boost::bind(&ElevationMappingNode::pointcloudCallback, this, _1, key); +// ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, f); +// pointcloudSubs_.push_back(sub); +// ROS_INFO_STREAM("Subscribed to PointCloud2 topic: " << pointcloud_topic); +// } +// else if (type == "image") { +// std::string camera_topic = subscriber.second["topic_name"]; +// std::string info_topic = subscriber.second["camera_info_topic_name"]; + +// // Handle compressed images with transport hints +// // We obtain the hint from the last part of the topic name +// std::string transport_hint = "compressed"; +// std::size_t ind = camera_topic.find(transport_hint); // Find if compressed is in the topic name +// if (ind != std::string::npos) { +// transport_hint = camera_topic.substr(ind, camera_topic.length()); // Get the hint as the last part +// camera_topic.erase(ind - 1, camera_topic.length()); // We remove the hint from the topic +// } else { +// transport_hint = "raw"; // In the default case we assume raw topic +// } + +// // Setup subscriber +// const auto hint = image_transport::TransportHints(transport_hint, ros::TransportHints(), ros::NodeHandle(camera_topic)); +// ImageSubscriberPtr image_sub = std::make_shared(); +// image_sub->subscribe(it_, camera_topic, 1, hint); +// imageSubs_.push_back(image_sub); + +// CameraInfoSubscriberPtr cam_info_sub = std::make_shared(); +// cam_info_sub->subscribe(nh_, info_topic, 1); +// cameraInfoSubs_.push_back(cam_info_sub); + +// std::string channel_info_topic; +// // If there is channel info topic setting, we use it. +// if (subscriber.second.hasMember("channel_info_topic_name")) { +// std::string channel_info_topic = subscriber.second["channel_info_topic_name"]; +// ChannelInfoSubscriberPtr channel_info_sub = std::make_shared(); +// channel_info_sub->subscribe(nh_, channel_info_topic, 1); +// channelInfoSubs_.push_back(channel_info_sub); +// CameraChannelSyncPtr sync = std::make_shared(CameraChannelPolicy(10), *image_sub, *cam_info_sub, *channel_info_sub); +// sync->registerCallback(boost::bind(&ElevationMappingNode::imageChannelCallback, this, _1, _2, _3)); +// cameraChannelSyncs_.push_back(sync); +// ROS_INFO_STREAM("Subscribed to Image topic: " << camera_topic << ", Camera info topic: " << info_topic << ", Channel info topic: " << channel_info_topic); +// } +// else { +// // If there is channels setting, we use it. Otherwise, we use rgb as default. +// if (subscriber.second.hasMember("channels")) { +// const auto& channels = subscriber.second["channels"]; +// for (int32_t i = 0; i < channels.size(); ++i) { +// auto elem = static_cast(channels[i]); +// channels_[key].push_back(elem); +// } +// } +// else { +// channels_[key].push_back("rgb"); +// } +// ROS_INFO_STREAM("Subscribed to Image topic: " << camera_topic << ", Camera info topic: " << info_topic << ". Channel info topic: " << (channel_info_topic.empty() ? ("Not found. Using channels: " + boost::algorithm::join(channels_[key], ", ")) : channel_info_topic)); +// CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); +// sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2, key)); +// cameraSyncs_.push_back(sync); +// } + + +// } else { +// ROS_WARN_STREAM("Subscriber data_type [" << type << "] Not valid. Supported types: pointcloud, image"); +// continue; +// } +// } + +// map_.initialize(nh_); + +// // Register map publishers +// for (auto itr = publishers.begin(); itr != publishers.end(); ++itr) { +// // Parse params +// std::string topic_name = itr->first; +// std::vector layers_list; +// std::vector basic_layers_list; +// auto layers = itr->second["layers"]; +// auto basic_layers = itr->second["basic_layers"]; +// double fps = itr->second["fps"]; + +// if (fps > updateGridMapFps) { +// ROS_WARN( +// "[ElevationMappingCupy] fps for topic %s is larger than map_acquire_fps (%f > %f). The topic data will be only updated at %f " +// "fps.", +// topic_name.c_str(), fps, updateGridMapFps, updateGridMapFps); +// } + +// for (int32_t i = 0; i < layers.size(); ++i) { +// layers_list.push_back(static_cast(layers[i])); +// } + +// for (int32_t i = 0; i < basic_layers.size(); ++i) { +// basic_layers_list.push_back(static_cast(basic_layers[i])); +// } + +// // Make publishers +// ros::Publisher pub = nh_.advertise(topic_name, 1); +// mapPubs_.push_back(pub); + +// // Register map layers +// map_layers_.push_back(layers_list); +// map_basic_layers_.push_back(basic_layers_list); + +// // Register map fps +// map_fps_.push_back(fps); +// map_fps_unique_.insert(fps); +// } +// setupMapPublishers(); + +// pointPub_ = nh_.advertise("elevation_map_points", 1); +// alivePub_ = nh_.advertise("alive", 1); +// normalPub_ = nh_.advertise("normal", 1); +// statisticsPub_ = nh_.advertise("statistics", 1); + +// gridMap_.setFrameId(mapFrameId_); +// rawSubmapService_ = nh_.advertiseService("get_raw_submap", &ElevationMappingNode::getSubmap, this); +// clearMapService_ = nh_.advertiseService("clear_map", &ElevationMappingNode::clearMap, this); +// initializeMapService_ = nh_.advertiseService("initialize", &ElevationMappingNode::initializeMap, this); +// clearMapWithInitializerService_ = +// nh_.advertiseService("clear_map_with_initializer", &ElevationMappingNode::clearMapWithInitializer, this); +// setPublishPointService_ = nh_.advertiseService("set_publish_points", &ElevationMappingNode::setPublishPoint, this); +// checkSafetyService_ = nh_.advertiseService("check_safety", &ElevationMappingNode::checkSafety, this); + +// if (updateVarianceFps > 0) { +// double duration = 1.0 / (updateVarianceFps + 0.00001); +// updateVarianceTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updateVariance, this, false, true); +// } +// if (timeInterval > 0) { +// double duration = timeInterval; +// updateTimeTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updateTime, this, false, true); +// } +// if (updatePoseFps > 0) { +// double duration = 1.0 / (updatePoseFps + 0.00001); +// updatePoseTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updatePose, this, false, true); +// } +// if (updateGridMapFps > 0) { +// double duration = 1.0 / (updateGridMapFps + 0.00001); +// updateGridMapTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updateGridMap, this, false, true); +// } +// if (publishStatisticsFps > 0) { +// double duration = 1.0 / (publishStatisticsFps + 0.00001); +// publishStatisticsTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::publishStatistics, this, false, true); +// } +// lastStatisticsPublishedTime_ = ros::Time::now(); +// ROS_INFO("[ElevationMappingCupy] finish initialization"); +// } + +// // Setup map publishers +// void ElevationMappingNode::setupMapPublishers() { +// // Find the layers with highest fps. +// float max_fps = -1; +// // Create timers for each unique map frequencies +// for (auto fps : map_fps_unique_) { +// // Which publisher to call in the timer callback +// std::vector indices; +// // If this fps is max, update the map layers. +// if (fps >= max_fps) { +// max_fps = fps; +// map_layers_all_.clear(); +// } +// for (int i = 0; i < map_fps_.size(); i++) { +// if (map_fps_[i] == fps) { +// indices.push_back(i); +// // If this fps is max, add layers +// if (fps >= max_fps) { +// for (const auto layer : map_layers_[i]) { +// map_layers_all_.insert(layer); +// } +// } +// } +// } +// // Callback funtion. +// // It publishes to specific topics. +// auto cb = [this, indices](const ros::TimerEvent&) { +// for (int i : indices) { +// publishMapOfIndex(i); +// } +// }; +// double duration = 1.0 / (fps + 0.00001); +// mapTimers_.push_back(nh_.createTimer(ros::Duration(duration), cb)); +// } +// } + +// void ElevationMappingNode::publishMapOfIndex(int index) { +// // publish the map layers of index +// if (!isGridmapUpdated_) { +// return; +// } +// grid_map_msgs::GridMap msg; +// std::vector layers; + +// { // need continuous lock between adding layers and converting to message. Otherwise updateGridmap can reset the data not in +// // map_layers_all_ +// std::lock_guard lock(mapMutex_); +// for (const auto& layer : map_layers_[index]) { +// const bool is_layer_in_all = map_layers_all_.find(layer) != map_layers_all_.end(); +// if (is_layer_in_all && gridMap_.exists(layer)) { +// layers.push_back(layer); +// } else if (map_.exists_layer(layer)) { +// // if there are layers which is not in the syncing layer. +// ElevationMappingWrapper::RowMatrixXf map_data; +// map_.get_layer_data(layer, map_data); +// gridMap_.add(layer, map_data); +// layers.push_back(layer); +// } +// } +// if (layers.empty()) { +// return; +// } + +// grid_map::GridMapRosConverter::toMessage(gridMap_, layers, msg); +// } + +// msg.basic_layers = map_basic_layers_[index]; +// mapPubs_[index].publish(msg); +// } + +// void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key) { + +// // get channels +// auto fields = cloud.fields; +// std::vector channels; + +// for (int it = 0; it < fields.size(); it++) { +// auto& field = fields[it]; +// channels.push_back(field.name); +// } +// inputPointCloud(cloud, channels); + +// // This is used for publishing as statistics. +// pointCloudProcessCounter_++; +// } + +// void ElevationMappingNode::inputPointCloud(const sensor_msgs::PointCloud2& cloud, +// const std::vector& channels) { +// auto start = ros::Time::now(); +// auto* pcl_pc = new pcl::PCLPointCloud2; +// pcl::PCLPointCloud2ConstPtr cloudPtr(pcl_pc); +// pcl_conversions::toPCL(cloud, *pcl_pc); + +// // get channels +// auto fields = cloud.fields; +// uint array_dim = channels.size(); + +// RowMatrixXd points = RowMatrixXd(pcl_pc->width * pcl_pc->height, array_dim); + +// for (unsigned int i = 0; i < pcl_pc->width * pcl_pc->height; ++i) { +// for (unsigned int j = 0; j < channels.size(); ++j) { +// float temp; +// uint point_idx = i * pcl_pc->point_step + pcl_pc->fields[j].offset; +// memcpy(&temp, &pcl_pc->data[point_idx], sizeof(float)); +// points(i, j) = static_cast(temp); +// } +// } +// // get pose of sensor in map frame +// tf::StampedTransform transformTf; +// std::string sensorFrameId = cloud.header.frame_id; +// auto timeStamp = cloud.header.stamp; +// Eigen::Affine3d transformationSensorToMap; +// try { +// transformListener_.waitForTransform(mapFrameId_, sensorFrameId, timeStamp, ros::Duration(1.0)); +// transformListener_.lookupTransform(mapFrameId_, sensorFrameId, timeStamp, transformTf); +// poseTFToEigen(transformTf, transformationSensorToMap); +// } catch (tf::TransformException& ex) { +// ROS_ERROR("%s", ex.what()); +// return; +// } + +// double positionError{0.0}; +// double orientationError{0.0}; +// { +// std::lock_guard lock(errorMutex_); +// positionError = positionError_; +// orientationError = orientationError_; +// } +// map_.input(points, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError, +// orientationError); + +// if (enableDriftCorrectedTFPublishing_) { +// publishMapToOdom(map_.get_additive_mean_error()); +// } + +// ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed a point cloud (%i points) in %f sec.", static_cast(points.size()), +// (ros::Time::now() - start).toSec()); +// ROS_DEBUG_THROTTLE(1.0, "positionError: %f ", positionError); +// ROS_DEBUG_THROTTLE(1.0, "orientationError: %f ", orientationError); + +// } + +// void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_msg, +// const sensor_msgs::CameraInfoConstPtr& camera_info_msg, +// const std::vector& channels) { +// // Get image +// cv::Mat image = cv_bridge::toCvShare(image_msg, image_msg->encoding)->image; + +// // Change encoding to RGB/RGBA +// if (image_msg->encoding == "bgr8") { +// cv::cvtColor(image, image, CV_BGR2RGB); +// } else if (image_msg->encoding == "bgra8") { +// cv::cvtColor(image, image, CV_BGRA2RGBA); +// } + +// // Extract camera matrix +// Eigen::Map> cameraMatrix(&camera_info_msg->K[0]); + +// // Extract distortion coefficients +// Eigen::VectorXd distortionCoeffs; +// if (!camera_info_msg->D.empty()) { +// distortionCoeffs = Eigen::Map(camera_info_msg->D.data(), camera_info_msg->D.size()); +// } else { +// ROS_WARN("Distortion coefficients are empty."); +// distortionCoeffs = Eigen::VectorXd::Zero(5); +// // return; +// } + +// // distortion model +// std::string distortion_model = camera_info_msg->distortion_model; - // Get pose of sensor in map frame - tf::StampedTransform transformTf; - std::string sensorFrameId = image_msg->header.frame_id; - auto timeStamp = image_msg->header.stamp; - Eigen::Affine3d transformationMapToSensor; - try { - transformListener_.waitForTransform(sensorFrameId, mapFrameId_, timeStamp, ros::Duration(1.0)); - transformListener_.lookupTransform(sensorFrameId, mapFrameId_, timeStamp, transformTf); - poseTFToEigen(transformTf, transformationMapToSensor); - } catch (tf::TransformException& ex) { - ROS_ERROR("%s", ex.what()); - return; - } - - // Transform image to vector of Eigen matrices for easy pybind conversion - std::vector image_split; - std::vector multichannel_image; - cv::split(image, image_split); - for (auto img : image_split) { - ColMatrixXf eigen_img; - cv::cv2eigen(img, eigen_img); - multichannel_image.push_back(eigen_img); - } - - // Check if the size of multichannel_image and channels and channel_methods matches. "rgb" counts for 3 layers. - int total_channels = 0; - for (const auto& channel : channels) { - if (channel == "rgb") { - total_channels += 3; - } else { - total_channels += 1; - } - } - if (total_channels != multichannel_image.size()) { - ROS_ERROR("Mismatch in the size of multichannel_image (%d), channels (%d). Please check the input.", multichannel_image.size(), channels.size()); - ROS_ERROR_STREAM("Current Channels: " << boost::algorithm::join(channels, ", ")); - return; - } - - // Pass image to pipeline - map_.input_image(multichannel_image, channels, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, - distortionCoeffs, distortion_model, image.rows, image.cols); -} - -void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image_msg, - const sensor_msgs::CameraInfoConstPtr& camera_info_msg, - const std::string& key) { - auto start = ros::Time::now(); - inputImage(image_msg, camera_info_msg, channels_[key]); - ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); -} - -void ElevationMappingNode::imageChannelCallback(const sensor_msgs::ImageConstPtr& image_msg, - const sensor_msgs::CameraInfoConstPtr& camera_info_msg, - const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg) { - auto start = ros::Time::now(); - // Default channels and fusion methods for image is rgb and image_color - std::vector channels; - channels = channel_info_msg->channels; - inputImage(image_msg, camera_info_msg, channels); - ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); -} - -void ElevationMappingNode::updatePose(const ros::TimerEvent&) { - tf::StampedTransform transformTf; - const auto& timeStamp = ros::Time::now(); - Eigen::Affine3d transformationBaseToMap; - try { - transformListener_.waitForTransform(mapFrameId_, baseFrameId_, timeStamp, ros::Duration(1.0)); - transformListener_.lookupTransform(mapFrameId_, baseFrameId_, timeStamp, transformTf); - poseTFToEigen(transformTf, transformationBaseToMap); - } catch (tf::TransformException& ex) { - ROS_ERROR("%s", ex.what()); - return; - } - - // This is to check if the robot is moving. If the robot is not moving, drift compensation is disabled to avoid creating artifacts. - Eigen::Vector3d position(transformTf.getOrigin().x(), transformTf.getOrigin().y(), transformTf.getOrigin().z()); - map_.move_to(position, transformationBaseToMap.rotation().transpose()); - Eigen::Vector3d position3(transformTf.getOrigin().x(), transformTf.getOrigin().y(), transformTf.getOrigin().z()); - Eigen::Vector4d orientation(transformTf.getRotation().x(), transformTf.getRotation().y(), transformTf.getRotation().z(), - transformTf.getRotation().w()); - lowpassPosition_ = positionAlpha_ * position3 + (1 - positionAlpha_) * lowpassPosition_; - lowpassOrientation_ = orientationAlpha_ * orientation + (1 - orientationAlpha_) * lowpassOrientation_; - { - std::lock_guard lock(errorMutex_); - positionError_ = (position3 - lowpassPosition_).norm(); - orientationError_ = (orientation - lowpassOrientation_).norm(); - } - - if (useInitializerAtStart_) { - ROS_INFO("Clearing map with initializer."); - initializeWithTF(); - useInitializerAtStart_ = false; - } -} - -void ElevationMappingNode::publishAsPointCloud(const grid_map::GridMap& map) const { - sensor_msgs::PointCloud2 msg; - grid_map::GridMapRosConverter::toPointCloud(map, "elevation", msg); - pointPub_.publish(msg); -} - -bool ElevationMappingNode::getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response) { - std::string requestedFrameId = request.frame_id; - Eigen::Isometry3d transformationOdomToMap; - grid_map::Position requestedSubmapPosition(request.position_x, request.position_y); - if (requestedFrameId != mapFrameId_) { - tf::StampedTransform transformTf; - const auto& timeStamp = ros::Time::now(); - try { - transformListener_.waitForTransform(requestedFrameId, mapFrameId_, timeStamp, ros::Duration(1.0)); - transformListener_.lookupTransform(requestedFrameId, mapFrameId_, timeStamp, transformTf); - tf::poseTFToEigen(transformTf, transformationOdomToMap); - } catch (tf::TransformException& ex) { - ROS_ERROR("%s", ex.what()); - return false; - } - Eigen::Vector3d p(request.position_x, request.position_y, 0); - Eigen::Vector3d mapP = transformationOdomToMap.inverse() * p; - requestedSubmapPosition.x() = mapP.x(); - requestedSubmapPosition.y() = mapP.y(); - } - grid_map::Length requestedSubmapLength(request.length_x, request.length_y); - ROS_DEBUG("Elevation submap request: Position x=%f, y=%f, Length x=%f, y=%f.", requestedSubmapPosition.x(), requestedSubmapPosition.y(), - requestedSubmapLength(0), requestedSubmapLength(1)); - - bool isSuccess; - grid_map::Index index; - grid_map::GridMap subMap; - { - std::lock_guard lock(mapMutex_); - subMap = gridMap_.getSubmap(requestedSubmapPosition, requestedSubmapLength, index, isSuccess); - } - const auto& length = subMap.getLength(); - if (requestedFrameId != mapFrameId_) { - subMap = subMap.getTransformedMap(transformationOdomToMap, "elevation", requestedFrameId); - } - - if (request.layers.empty()) { - grid_map::GridMapRosConverter::toMessage(subMap, response.map); - } else { - std::vector layers; - for (const auto& layer : request.layers) { - layers.push_back(layer); - } - grid_map::GridMapRosConverter::toMessage(subMap, layers, response.map); - } - return isSuccess; -} - -bool ElevationMappingNode::clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) { - ROS_INFO("Clearing map."); - map_.clear(); - if (alwaysClearWithInitializer_) { - initializeWithTF(); - } - return true; -} - -bool ElevationMappingNode::clearMapWithInitializer(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) { - ROS_INFO("Clearing map with initializer."); - map_.clear(); - initializeWithTF(); - return true; -} - -void ElevationMappingNode::initializeWithTF() { - std::vector points; - const auto& timeStamp = ros::Time::now(); - int i = 0; - Eigen::Vector3d p; - for (const auto& frame_id : initialize_frame_id_) { - // Get tf from map frame to tf frame - Eigen::Affine3d transformationBaseToMap; - tf::StampedTransform transformTf; - try { - transformListener_.waitForTransform(mapFrameId_, frame_id, timeStamp, ros::Duration(1.0)); - transformListener_.lookupTransform(mapFrameId_, frame_id, timeStamp, transformTf); - poseTFToEigen(transformTf, transformationBaseToMap); - } catch (tf::TransformException& ex) { - ROS_ERROR("%s", ex.what()); - return; - } - p = transformationBaseToMap.translation(); - p.z() += initialize_tf_offset_[i]; - points.push_back(p); - i++; - } - if (!points.empty() && points.size() < 3) { - points.emplace_back(p + Eigen::Vector3d(initializeTfGridSize_, initializeTfGridSize_, 0)); - points.emplace_back(p + Eigen::Vector3d(-initializeTfGridSize_, initializeTfGridSize_, 0)); - points.emplace_back(p + Eigen::Vector3d(initializeTfGridSize_, -initializeTfGridSize_, 0)); - points.emplace_back(p + Eigen::Vector3d(-initializeTfGridSize_, -initializeTfGridSize_, 0)); - } - ROS_INFO_STREAM("Initializing map with points using " << initializeMethod_); - map_.initializeWithPoints(points, initializeMethod_); -} - -bool ElevationMappingNode::checkSafety(elevation_map_msgs::CheckSafety::Request& request, - elevation_map_msgs::CheckSafety::Response& response) { - for (const auto& polygonstamped : request.polygons) { - if (polygonstamped.polygon.points.empty()) { - continue; - } - std::vector polygon; - std::vector untraversable_polygon; - Eigen::Vector3d result; - result.setZero(); - const auto& polygonFrameId = polygonstamped.header.frame_id; - const auto& timeStamp = polygonstamped.header.stamp; - double polygon_z = polygonstamped.polygon.points[0].z; - - // Get tf from map frame to polygon frame - if (mapFrameId_ != polygonFrameId) { - Eigen::Affine3d transformationBaseToMap; - tf::StampedTransform transformTf; - try { - transformListener_.waitForTransform(mapFrameId_, polygonFrameId, timeStamp, ros::Duration(1.0)); - transformListener_.lookupTransform(mapFrameId_, polygonFrameId, timeStamp, transformTf); - poseTFToEigen(transformTf, transformationBaseToMap); - } catch (tf::TransformException& ex) { - ROS_ERROR("%s", ex.what()); - return false; - } - for (const auto& p : polygonstamped.polygon.points) { - const auto& pvector = Eigen::Vector3d(p.x, p.y, p.z); - const auto transformed_p = transformationBaseToMap * pvector; - polygon.emplace_back(Eigen::Vector2d(transformed_p.x(), transformed_p.y())); - } - } else { - for (const auto& p : polygonstamped.polygon.points) { - polygon.emplace_back(Eigen::Vector2d(p.x, p.y)); - } - } - - map_.get_polygon_traversability(polygon, result, untraversable_polygon); - - geometry_msgs::PolygonStamped untraversable_polygonstamped; - untraversable_polygonstamped.header.stamp = ros::Time::now(); - untraversable_polygonstamped.header.frame_id = mapFrameId_; - for (const auto& p : untraversable_polygon) { - geometry_msgs::Point32 point; - point.x = static_cast(p.x()); - point.y = static_cast(p.y()); - point.z = static_cast(polygon_z); - untraversable_polygonstamped.polygon.points.push_back(point); - } - // traversability_result; - response.is_safe.push_back(bool(result[0] > 0.5)); - response.traversability.push_back(result[1]); - response.untraversable_polygons.push_back(untraversable_polygonstamped); - } - return true; -} - -bool ElevationMappingNode::setPublishPoint(std_srvs::SetBool::Request& request, std_srvs::SetBool::Response& response) { - enablePointCloudPublishing_ = request.data; - response.success = true; - return true; -} - -void ElevationMappingNode::updateVariance(const ros::TimerEvent&) { - map_.update_variance(); -} - -void ElevationMappingNode::updateTime(const ros::TimerEvent&) { - map_.update_time(); -} - -void ElevationMappingNode::publishStatistics(const ros::TimerEvent&) { - ros::Time now = ros::Time::now(); - double dt = (now - lastStatisticsPublishedTime_).toSec(); - lastStatisticsPublishedTime_ = now; - elevation_map_msgs::Statistics msg; - msg.header.stamp = now; - if (dt > 0.0) { - msg.pointcloud_process_fps = pointCloudProcessCounter_ / dt; - } - pointCloudProcessCounter_ = 0; - statisticsPub_.publish(msg); -} - -void ElevationMappingNode::updateGridMap(const ros::TimerEvent&) { - std::vector layers(map_layers_all_.begin(), map_layers_all_.end()); - std::lock_guard lock(mapMutex_); - map_.get_grid_map(gridMap_, layers); - gridMap_.setTimestamp(ros::Time::now().toNSec()); - alivePub_.publish(std_msgs::Empty()); - - // Mostly debug purpose - if (enablePointCloudPublishing_) { - publishAsPointCloud(gridMap_); - } - if (enableNormalArrowPublishing_) { - publishNormalAsArrow(gridMap_); - } - isGridmapUpdated_ = true; -} - -bool ElevationMappingNode::initializeMap(elevation_map_msgs::Initialize::Request& request, - elevation_map_msgs::Initialize::Response& response) { - // If initialize method is points - if (request.type == request.POINTS) { - std::vector points; - for (const auto& point : request.points) { - const auto& pointFrameId = point.header.frame_id; - const auto& timeStamp = point.header.stamp; - const auto& pvector = Eigen::Vector3d(point.point.x, point.point.y, point.point.z); - - // Get tf from map frame to points' frame - if (mapFrameId_ != pointFrameId) { - Eigen::Affine3d transformationBaseToMap; - tf::StampedTransform transformTf; - try { - transformListener_.waitForTransform(mapFrameId_, pointFrameId, timeStamp, ros::Duration(1.0)); - transformListener_.lookupTransform(mapFrameId_, pointFrameId, timeStamp, transformTf); - poseTFToEigen(transformTf, transformationBaseToMap); - } catch (tf::TransformException& ex) { - ROS_ERROR("%s", ex.what()); - return false; - } - const auto transformed_p = transformationBaseToMap * pvector; - points.push_back(transformed_p); - } else { - points.push_back(pvector); - } - } - std::string method; - switch (request.method) { - case request.NEAREST: - method = "nearest"; - break; - case request.LINEAR: - method = "linear"; - break; - case request.CUBIC: - method = "cubic"; - break; - } - ROS_INFO_STREAM("Initializing map with points using " << method); - map_.initializeWithPoints(points, method); - } - response.success = true; - return true; -} - -void ElevationMappingNode::publishNormalAsArrow(const grid_map::GridMap& map) const { - auto startTime = ros::Time::now(); - - const auto& normalX = map["normal_x"]; - const auto& normalY = map["normal_y"]; - const auto& normalZ = map["normal_z"]; - double scale = 0.1; - - visualization_msgs::MarkerArray markerArray; - // For each cell in map. - for (grid_map::GridMapIterator iterator(map); !iterator.isPastEnd(); ++iterator) { - if (!map.isValid(*iterator, "elevation")) { - continue; - } - grid_map::Position3 p; - map.getPosition3("elevation", *iterator, p); - Eigen::Vector3d start = p; - const auto i = iterator.getLinearIndex(); - Eigen::Vector3d normal(normalX(i), normalY(i), normalZ(i)); - Eigen::Vector3d end = start + normal * scale; - if (normal.norm() < 0.1) { - continue; - } - markerArray.markers.push_back(vectorToArrowMarker(start, end, i)); - } - normalPub_.publish(markerArray); - ROS_INFO_THROTTLE(1.0, "publish as normal in %f sec.", (ros::Time::now() - startTime).toSec()); -} - -visualization_msgs::Marker ElevationMappingNode::vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, - const int id) const { - visualization_msgs::Marker marker; - marker.header.frame_id = mapFrameId_; - marker.header.stamp = ros::Time::now(); - marker.ns = "normal"; - marker.id = id; - marker.type = visualization_msgs::Marker::ARROW; - marker.action = visualization_msgs::Marker::ADD; - marker.points.resize(2); - marker.points[0].x = start.x(); - marker.points[0].y = start.y(); - marker.points[0].z = start.z(); - marker.points[1].x = end.x(); - marker.points[1].y = end.y(); - marker.points[1].z = end.z(); - marker.pose.orientation.x = 0.0; - marker.pose.orientation.y = 0.0; - marker.pose.orientation.z = 0.0; - marker.pose.orientation.w = 1.0; - marker.scale.x = 0.01; - marker.scale.y = 0.01; - marker.scale.z = 0.01; - marker.color.a = 1.0; // Don't forget to set the alpha! - marker.color.r = 0.0; - marker.color.g = 1.0; - marker.color.b = 0.0; - - return marker; -} - -void ElevationMappingNode::publishMapToOdom(double error) { - tf::Transform transform; - transform.setOrigin(tf::Vector3(0.0, 0.0, error)); - tf::Quaternion q; - q.setRPY(0, 0, 0); - transform.setRotation(q); - tfBroadcaster_.sendTransform(tf::StampedTransform(transform, ros::Time::now(), mapFrameId_, correctedMapFrameId_)); -} - -} // namespace elevation_mapping_cupy +// // Get pose of sensor in map frame +// tf::StampedTransform transformTf; +// std::string sensorFrameId = image_msg->header.frame_id; +// auto timeStamp = image_msg->header.stamp; +// Eigen::Affine3d transformationMapToSensor; +// try { +// transformListener_.waitForTransform(sensorFrameId, mapFrameId_, timeStamp, ros::Duration(1.0)); +// transformListener_.lookupTransform(sensorFrameId, mapFrameId_, timeStamp, transformTf); +// poseTFToEigen(transformTf, transformationMapToSensor); +// } catch (tf::TransformException& ex) { +// ROS_ERROR("%s", ex.what()); +// return; +// } + +// // Transform image to vector of Eigen matrices for easy pybind conversion +// std::vector image_split; +// std::vector multichannel_image; +// cv::split(image, image_split); +// for (auto img : image_split) { +// ColMatrixXf eigen_img; +// cv::cv2eigen(img, eigen_img); +// multichannel_image.push_back(eigen_img); +// } + +// // Check if the size of multichannel_image and channels and channel_methods matches. "rgb" counts for 3 layers. +// int total_channels = 0; +// for (const auto& channel : channels) { +// if (channel == "rgb") { +// total_channels += 3; +// } else { +// total_channels += 1; +// } +// } +// if (total_channels != multichannel_image.size()) { +// ROS_ERROR("Mismatch in the size of multichannel_image (%d), channels (%d). Please check the input.", multichannel_image.size(), channels.size()); +// ROS_ERROR_STREAM("Current Channels: " << boost::algorithm::join(channels, ", ")); +// return; +// } + +// // Pass image to pipeline +// map_.input_image(multichannel_image, channels, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, +// distortionCoeffs, distortion_model, image.rows, image.cols); +// } + +// void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image_msg, +// const sensor_msgs::CameraInfoConstPtr& camera_info_msg, +// const std::string& key) { +// auto start = ros::Time::now(); +// inputImage(image_msg, camera_info_msg, channels_[key]); +// ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); +// } + +// void ElevationMappingNode::imageChannelCallback(const sensor_msgs::ImageConstPtr& image_msg, +// const sensor_msgs::CameraInfoConstPtr& camera_info_msg, +// const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg) { +// auto start = ros::Time::now(); +// // Default channels and fusion methods for image is rgb and image_color +// std::vector channels; +// channels = channel_info_msg->channels; +// inputImage(image_msg, camera_info_msg, channels); +// ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); +// } + +// void ElevationMappingNode::updatePose(const ros::TimerEvent&) { +// tf::StampedTransform transformTf; +// const auto& timeStamp = ros::Time::now(); +// Eigen::Affine3d transformationBaseToMap; +// try { +// transformListener_.waitForTransform(mapFrameId_, baseFrameId_, timeStamp, ros::Duration(1.0)); +// transformListener_.lookupTransform(mapFrameId_, baseFrameId_, timeStamp, transformTf); +// poseTFToEigen(transformTf, transformationBaseToMap); +// } catch (tf::TransformException& ex) { +// ROS_ERROR("%s", ex.what()); +// return; +// } + +// // This is to check if the robot is moving. If the robot is not moving, drift compensation is disabled to avoid creating artifacts. +// Eigen::Vector3d position(transformTf.getOrigin().x(), transformTf.getOrigin().y(), transformTf.getOrigin().z()); +// map_.move_to(position, transformationBaseToMap.rotation().transpose()); +// Eigen::Vector3d position3(transformTf.getOrigin().x(), transformTf.getOrigin().y(), transformTf.getOrigin().z()); +// Eigen::Vector4d orientation(transformTf.getRotation().x(), transformTf.getRotation().y(), transformTf.getRotation().z(), +// transformTf.getRotation().w()); +// lowpassPosition_ = positionAlpha_ * position3 + (1 - positionAlpha_) * lowpassPosition_; +// lowpassOrientation_ = orientationAlpha_ * orientation + (1 - orientationAlpha_) * lowpassOrientation_; +// { +// std::lock_guard lock(errorMutex_); +// positionError_ = (position3 - lowpassPosition_).norm(); +// orientationError_ = (orientation - lowpassOrientation_).norm(); +// } + +// if (useInitializerAtStart_) { +// ROS_INFO("Clearing map with initializer."); +// initializeWithTF(); +// useInitializerAtStart_ = false; +// } +// } + +// void ElevationMappingNode::publishAsPointCloud(const grid_map::GridMap& map) const { +// sensor_msgs::PointCloud2 msg; +// grid_map::GridMapRosConverter::toPointCloud(map, "elevation", msg); +// pointPub_.publish(msg); +// } + +// bool ElevationMappingNode::getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response) { +// std::string requestedFrameId = request.frame_id; +// Eigen::Isometry3d transformationOdomToMap; +// grid_map::Position requestedSubmapPosition(request.position_x, request.position_y); +// if (requestedFrameId != mapFrameId_) { +// tf::StampedTransform transformTf; +// const auto& timeStamp = ros::Time::now(); +// try { +// transformListener_.waitForTransform(requestedFrameId, mapFrameId_, timeStamp, ros::Duration(1.0)); +// transformListener_.lookupTransform(requestedFrameId, mapFrameId_, timeStamp, transformTf); +// tf::poseTFToEigen(transformTf, transformationOdomToMap); +// } catch (tf::TransformException& ex) { +// ROS_ERROR("%s", ex.what()); +// return false; +// } +// Eigen::Vector3d p(request.position_x, request.position_y, 0); +// Eigen::Vector3d mapP = transformationOdomToMap.inverse() * p; +// requestedSubmapPosition.x() = mapP.x(); +// requestedSubmapPosition.y() = mapP.y(); +// } +// grid_map::Length requestedSubmapLength(request.length_x, request.length_y); +// ROS_DEBUG("Elevation submap request: Position x=%f, y=%f, Length x=%f, y=%f.", requestedSubmapPosition.x(), requestedSubmapPosition.y(), +// requestedSubmapLength(0), requestedSubmapLength(1)); + +// bool isSuccess; +// grid_map::Index index; +// grid_map::GridMap subMap; +// { +// std::lock_guard lock(mapMutex_); +// subMap = gridMap_.getSubmap(requestedSubmapPosition, requestedSubmapLength, index, isSuccess); +// } +// const auto& length = subMap.getLength(); +// if (requestedFrameId != mapFrameId_) { +// subMap = subMap.getTransformedMap(transformationOdomToMap, "elevation", requestedFrameId); +// } + +// if (request.layers.empty()) { +// grid_map::GridMapRosConverter::toMessage(subMap, response.map); +// } else { +// std::vector layers; +// for (const auto& layer : request.layers) { +// layers.push_back(layer); +// } +// grid_map::GridMapRosConverter::toMessage(subMap, layers, response.map); +// } +// return isSuccess; +// } + +// bool ElevationMappingNode::clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) { +// ROS_INFO("Clearing map."); +// map_.clear(); +// if (alwaysClearWithInitializer_) { +// initializeWithTF(); +// } +// return true; +// } + +// bool ElevationMappingNode::clearMapWithInitializer(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) { +// ROS_INFO("Clearing map with initializer."); +// map_.clear(); +// initializeWithTF(); +// return true; +// } + +// void ElevationMappingNode::initializeWithTF() { +// std::vector points; +// const auto& timeStamp = ros::Time::now(); +// int i = 0; +// Eigen::Vector3d p; +// for (const auto& frame_id : initialize_frame_id_) { +// // Get tf from map frame to tf frame +// Eigen::Affine3d transformationBaseToMap; +// tf::StampedTransform transformTf; +// try { +// transformListener_.waitForTransform(mapFrameId_, frame_id, timeStamp, ros::Duration(1.0)); +// transformListener_.lookupTransform(mapFrameId_, frame_id, timeStamp, transformTf); +// poseTFToEigen(transformTf, transformationBaseToMap); +// } catch (tf::TransformException& ex) { +// ROS_ERROR("%s", ex.what()); +// return; +// } +// p = transformationBaseToMap.translation(); +// p.z() += initialize_tf_offset_[i]; +// points.push_back(p); +// i++; +// } +// if (!points.empty() && points.size() < 3) { +// points.emplace_back(p + Eigen::Vector3d(initializeTfGridSize_, initializeTfGridSize_, 0)); +// points.emplace_back(p + Eigen::Vector3d(-initializeTfGridSize_, initializeTfGridSize_, 0)); +// points.emplace_back(p + Eigen::Vector3d(initializeTfGridSize_, -initializeTfGridSize_, 0)); +// points.emplace_back(p + Eigen::Vector3d(-initializeTfGridSize_, -initializeTfGridSize_, 0)); +// } +// ROS_INFO_STREAM("Initializing map with points using " << initializeMethod_); +// map_.initializeWithPoints(points, initializeMethod_); +// } + +// bool ElevationMappingNode::checkSafety(elevation_map_msgs::CheckSafety::Request& request, +// elevation_map_msgs::CheckSafety::Response& response) { +// for (const auto& polygonstamped : request.polygons) { +// if (polygonstamped.polygon.points.empty()) { +// continue; +// } +// std::vector polygon; +// std::vector untraversable_polygon; +// Eigen::Vector3d result; +// result.setZero(); +// const auto& polygonFrameId = polygonstamped.header.frame_id; +// const auto& timeStamp = polygonstamped.header.stamp; +// double polygon_z = polygonstamped.polygon.points[0].z; + +// // Get tf from map frame to polygon frame +// if (mapFrameId_ != polygonFrameId) { +// Eigen::Affine3d transformationBaseToMap; +// tf::StampedTransform transformTf; +// try { +// transformListener_.waitForTransform(mapFrameId_, polygonFrameId, timeStamp, ros::Duration(1.0)); +// transformListener_.lookupTransform(mapFrameId_, polygonFrameId, timeStamp, transformTf); +// poseTFToEigen(transformTf, transformationBaseToMap); +// } catch (tf::TransformException& ex) { +// ROS_ERROR("%s", ex.what()); +// return false; +// } +// for (const auto& p : polygonstamped.polygon.points) { +// const auto& pvector = Eigen::Vector3d(p.x, p.y, p.z); +// const auto transformed_p = transformationBaseToMap * pvector; +// polygon.emplace_back(Eigen::Vector2d(transformed_p.x(), transformed_p.y())); +// } +// } else { +// for (const auto& p : polygonstamped.polygon.points) { +// polygon.emplace_back(Eigen::Vector2d(p.x, p.y)); +// } +// } + +// map_.get_polygon_traversability(polygon, result, untraversable_polygon); + +// geometry_msgs::PolygonStamped untraversable_polygonstamped; +// untraversable_polygonstamped.header.stamp = ros::Time::now(); +// untraversable_polygonstamped.header.frame_id = mapFrameId_; +// for (const auto& p : untraversable_polygon) { +// geometry_msgs::Point32 point; +// point.x = static_cast(p.x()); +// point.y = static_cast(p.y()); +// point.z = static_cast(polygon_z); +// untraversable_polygonstamped.polygon.points.push_back(point); +// } +// // traversability_result; +// response.is_safe.push_back(bool(result[0] > 0.5)); +// response.traversability.push_back(result[1]); +// response.untraversable_polygons.push_back(untraversable_polygonstamped); +// } +// return true; +// } + +// bool ElevationMappingNode::setPublishPoint(std_srvs::SetBool::Request& request, std_srvs::SetBool::Response& response) { +// enablePointCloudPublishing_ = request.data; +// response.success = true; +// return true; +// } + +// void ElevationMappingNode::updateVariance(const ros::TimerEvent&) { +// map_.update_variance(); +// } + +// void ElevationMappingNode::updateTime(const ros::TimerEvent&) { +// map_.update_time(); +// } + +// void ElevationMappingNode::publishStatistics(const ros::TimerEvent&) { +// ros::Time now = ros::Time::now(); +// double dt = (now - lastStatisticsPublishedTime_).toSec(); +// lastStatisticsPublishedTime_ = now; +// elevation_map_msgs::Statistics msg; +// msg.header.stamp = now; +// if (dt > 0.0) { +// msg.pointcloud_process_fps = pointCloudProcessCounter_ / dt; +// } +// pointCloudProcessCounter_ = 0; +// statisticsPub_.publish(msg); +// } + +// void ElevationMappingNode::updateGridMap(const ros::TimerEvent&) { +// std::vector layers(map_layers_all_.begin(), map_layers_all_.end()); +// std::lock_guard lock(mapMutex_); +// map_.get_grid_map(gridMap_, layers); +// gridMap_.setTimestamp(ros::Time::now().toNSec()); +// alivePub_.publish(std_msgs::Empty()); + +// // Mostly debug purpose +// if (enablePointCloudPublishing_) { +// publishAsPointCloud(gridMap_); +// } +// if (enableNormalArrowPublishing_) { +// publishNormalAsArrow(gridMap_); +// } +// isGridmapUpdated_ = true; +// } + +// bool ElevationMappingNode::initializeMap(elevation_map_msgs::Initialize::Request& request, +// elevation_map_msgs::Initialize::Response& response) { +// // If initialize method is points +// if (request.type == request.POINTS) { +// std::vector points; +// for (const auto& point : request.points) { +// const auto& pointFrameId = point.header.frame_id; +// const auto& timeStamp = point.header.stamp; +// const auto& pvector = Eigen::Vector3d(point.point.x, point.point.y, point.point.z); + +// // Get tf from map frame to points' frame +// if (mapFrameId_ != pointFrameId) { +// Eigen::Affine3d transformationBaseToMap; +// tf::StampedTransform transformTf; +// try { +// transformListener_.waitForTransform(mapFrameId_, pointFrameId, timeStamp, ros::Duration(1.0)); +// transformListener_.lookupTransform(mapFrameId_, pointFrameId, timeStamp, transformTf); +// poseTFToEigen(transformTf, transformationBaseToMap); +// } catch (tf::TransformException& ex) { +// ROS_ERROR("%s", ex.what()); +// return false; +// } +// const auto transformed_p = transformationBaseToMap * pvector; +// points.push_back(transformed_p); +// } else { +// points.push_back(pvector); +// } +// } +// std::string method; +// switch (request.method) { +// case request.NEAREST: +// method = "nearest"; +// break; +// case request.LINEAR: +// method = "linear"; +// break; +// case request.CUBIC: +// method = "cubic"; +// break; +// } +// ROS_INFO_STREAM("Initializing map with points using " << method); +// map_.initializeWithPoints(points, method); +// } +// response.success = true; +// return true; +// } + +// void ElevationMappingNode::publishNormalAsArrow(const grid_map::GridMap& map) const { +// auto startTime = ros::Time::now(); + +// const auto& normalX = map["normal_x"]; +// const auto& normalY = map["normal_y"]; +// const auto& normalZ = map["normal_z"]; +// double scale = 0.1; + +// visualization_msgs::MarkerArray markerArray; +// // For each cell in map. +// for (grid_map::GridMapIterator iterator(map); !iterator.isPastEnd(); ++iterator) { +// if (!map.isValid(*iterator, "elevation")) { +// continue; +// } +// grid_map::Position3 p; +// map.getPosition3("elevation", *iterator, p); +// Eigen::Vector3d start = p; +// const auto i = iterator.getLinearIndex(); +// Eigen::Vector3d normal(normalX(i), normalY(i), normalZ(i)); +// Eigen::Vector3d end = start + normal * scale; +// if (normal.norm() < 0.1) { +// continue; +// } +// markerArray.markers.push_back(vectorToArrowMarker(start, end, i)); +// } +// normalPub_.publish(markerArray); +// ROS_INFO_THROTTLE(1.0, "publish as normal in %f sec.", (ros::Time::now() - startTime).toSec()); +// } + +// visualization_msgs::Marker ElevationMappingNode::vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, +// const int id) const { +// visualization_msgs::Marker marker; +// marker.header.frame_id = mapFrameId_; +// marker.header.stamp = ros::Time::now(); +// marker.ns = "normal"; +// marker.id = id; +// marker.type = visualization_msgs::Marker::ARROW; +// marker.action = visualization_msgs::Marker::ADD; +// marker.points.resize(2); +// marker.points[0].x = start.x(); +// marker.points[0].y = start.y(); +// marker.points[0].z = start.z(); +// marker.points[1].x = end.x(); +// marker.points[1].y = end.y(); +// marker.points[1].z = end.z(); +// marker.pose.orientation.x = 0.0; +// marker.pose.orientation.y = 0.0; +// marker.pose.orientation.z = 0.0; +// marker.pose.orientation.w = 1.0; +// marker.scale.x = 0.01; +// marker.scale.y = 0.01; +// marker.scale.z = 0.01; +// marker.color.a = 1.0; // Don't forget to set the alpha! +// marker.color.r = 0.0; +// marker.color.g = 1.0; +// marker.color.b = 0.0; + +// return marker; +// } + +// void ElevationMappingNode::publishMapToOdom(double error) { +// tf::Transform transform; +// transform.setOrigin(tf::Vector3(0.0, 0.0, error)); +// tf::Quaternion q; +// q.setRPY(0, 0, 0); +// transform.setRotation(q); +// tfBroadcaster_.sendTransform(tf::StampedTransform(transform, ros::Time::now(), mapFrameId_, correctedMapFrameId_)); +// } + +// } // namespace elevation_mapping_cupy diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 3980a8be..16c57332 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -12,162 +12,171 @@ #include // ROS -#include +#include +#include #include + namespace elevation_mapping_cupy { ElevationMappingWrapper::ElevationMappingWrapper() {} -void ElevationMappingWrapper::initialize(ros::NodeHandle& nh) { +void ElevationMappingWrapper::initialize(rclcpp::Node::SharedPtr node) { // Add the elevation_mapping_cupy path to sys.path auto threading = py::module::import("threading"); py::gil_scoped_acquire acquire; auto sys = py::module::import("sys"); auto path = sys.attr("path"); - std::string module_path = ros::package::getPath("elevation_mapping_cupy"); + std::string module_path = ament_index_cpp::get_package_share_directory("elevation_mapping_cupy"); module_path = module_path + "/script"; path.attr("insert")(0, module_path); auto elevation_mapping = py::module::import("elevation_mapping_cupy.elevation_mapping"); auto parameter = py::module::import("elevation_mapping_cupy.parameter"); param_ = parameter.attr("Parameter")(); - setParameters(nh); + setParameters(node); map_ = elevation_mapping.attr("ElevationMap")(param_); } -/** - * Load ros parameters into Parameter class. - * Search for the same name within the name space. - */ -void ElevationMappingWrapper::setParameters(ros::NodeHandle& nh) { +// /** +// * Load ros parameters into Parameter class. +// * Search for the same name within the name space. +// */ +void ElevationMappingWrapper::setParameters(rclcpp::Node::SharedPtr node) { // Get all parameters names and types. py::list paramNames = param_.attr("get_names")(); py::list paramTypes = param_.attr("get_types")(); py::gil_scoped_acquire acquire; - // Try to find the parameter in the ros parameter server. + // Try to find the parameter in the ROS parameter server. // If there was a parameter, set it to the Parameter variable. - for (int i = 0; i < paramNames.size(); i++) { + for (size_t i = 0; i < paramNames.size(); i++) { std::string type = py::cast(paramTypes[i]); std::string name = py::cast(paramNames[i]); if (type == "float") { float param; - if (nh.getParam(name, param)) { + if (node->get_parameter(name, param)) { param_.attr("set_value")(name, param); } } else if (type == "str") { std::string param; - if (nh.getParam(name, param)) { + if (node->get_parameter(name, param)) { param_.attr("set_value")(name, param); } } else if (type == "bool") { bool param; - if (nh.getParam(name, param)) { + if (node->get_parameter(name, param)) { param_.attr("set_value")(name, param); } } else if (type == "int") { int param; - if (nh.getParam(name, param)) { + if (node->get_parameter(name, param)) { param_.attr("set_value")(name, param); } } } - XmlRpc::XmlRpcValue subscribers; - nh.getParam("subscribers", subscribers); - - py::dict sub_dict; - for (auto& subscriber : subscribers) { - const char* const name = subscriber.first.c_str(); - const auto& subscriber_params = subscriber.second; - if (!sub_dict.contains(name)) { - sub_dict[name] = py::dict(); - } - for (auto iterat : subscriber_params) { - const char* const key = iterat.first.c_str(); - const auto val = iterat.second; - std::vector arr; - switch (val.getType()) { - case XmlRpc::XmlRpcValue::TypeString: - sub_dict[name][key] = static_cast(val); - break; - case XmlRpc::XmlRpcValue::TypeInt: - sub_dict[name][key] = static_cast(val); - break; - case XmlRpc::XmlRpcValue::TypeDouble: - sub_dict[name][key] = static_cast(val); - break; - case XmlRpc::XmlRpcValue::TypeBoolean: - sub_dict[name][key] = static_cast(val); - break; - case XmlRpc::XmlRpcValue::TypeArray: - for (int32_t i = 0; i < val.size(); ++i) { - auto elem = static_cast(val[i]); - arr.push_back(elem); + + rclcpp::Parameter subscribers; + node->get_parameter("subscribers", subscribers); + + py::dict sub_dict; + auto subscribers_array = subscribers.as_string_array(); + for (const auto& subscriber : subscribers_array) { + const char* const name = subscriber.c_str(); + if (!sub_dict.contains(name)) { + sub_dict[name] = py::dict(); + } + std::map subscriber_params; + node->get_parameters(name, subscriber_params); + for (const auto& param_pair : subscriber_params) { + const char* const param_name = param_pair.first.c_str(); + const auto& param_value = param_pair.second; + std::vector arr; + switch (param_value.get_type()) { + case rclcpp::ParameterType::PARAMETER_STRING: + sub_dict[name][param_name] = param_value.as_string(); + break; + case rclcpp::ParameterType::PARAMETER_INTEGER: + sub_dict[name][param_name] = param_value.as_int(); + break; + case rclcpp::ParameterType::PARAMETER_DOUBLE: + sub_dict[name][param_name] = param_value.as_double(); + break; + case rclcpp::ParameterType::PARAMETER_BOOL: + sub_dict[name][param_name] = param_value.as_bool(); + break; + case rclcpp::ParameterType::PARAMETER_STRING_ARRAY: + for (const auto& elem : param_value.as_string_array()) { + arr.push_back(elem); + } + sub_dict[name][param_name] = arr; + arr.clear(); + break; + default: + sub_dict[name][param_name] = py::cast(param_value); + break; } - sub_dict[name][key] = arr; - arr.clear(); - break; - case XmlRpc::XmlRpcValue::TypeStruct: - break; - default: - sub_dict[name][key] = py::cast(val); - break; + } } - } - } - param_.attr("subscriber_cfg") = sub_dict; - - // point cloud channel fusion - if (!nh.hasParam("pointcloud_channel_fusions")) { - ROS_WARN("No pointcloud_channel_fusions parameter found. Using default values."); - } - else { - XmlRpc::XmlRpcValue pointcloud_channel_fusion; - nh.getParam("pointcloud_channel_fusions", pointcloud_channel_fusion); - - py::dict pointcloud_channel_fusion_dict; - for (auto& channel_fusion : pointcloud_channel_fusion) { - const char* const name = channel_fusion.first.c_str(); - std::string fusion = static_cast(channel_fusion.second); - if (!pointcloud_channel_fusion_dict.contains(name)) { - pointcloud_channel_fusion_dict[name] = fusion; + param_.attr("subscriber_cfg") = sub_dict; + + + // point cloud channel fusion + if (!node->has_parameter("pointcloud_channel_fusions")) { + RCLCPP_WARN(node->get_logger(), "No pointcloud_channel_fusions parameter found. Using default values."); + } else { + rclcpp::Parameter pointcloud_channel_fusion; + node->get_parameter("pointcloud_channel_fusions", pointcloud_channel_fusion); + + py::dict pointcloud_channel_fusion_dict; + auto pointcloud_channel_fusion_map = pointcloud_channel_fusion.as_string_array(); + for (const auto& channel_fusion : pointcloud_channel_fusion_map) { + const char* const fusion_name = channel_fusion.c_str(); + std::string fusion; + node->get_parameter(fusion_name, fusion); + if (!pointcloud_channel_fusion_dict.contains(fusion_name)) { + pointcloud_channel_fusion_dict[fusion_name] = fusion; + } + } + RCLCPP_INFO_STREAM(node->get_logger(), "pointcloud_channel_fusion_dict: " << pointcloud_channel_fusion_dict); + param_.attr("pointcloud_channel_fusions") = pointcloud_channel_fusion_dict; } - } - ROS_INFO_STREAM("pointcloud_channel_fusion_dict: " << pointcloud_channel_fusion_dict); - param_.attr("pointcloud_channel_fusions") = pointcloud_channel_fusion_dict; - } - // image channel fusion - if (!nh.hasParam("image_channel_fusions")) { - ROS_WARN("No image_channel_fusions parameter found. Using default values."); - } - else { - XmlRpc::XmlRpcValue image_channel_fusion; - nh.getParam("image_channel_fusions", image_channel_fusion); - - py::dict image_channel_fusion_dict; - for (auto& channel_fusion : image_channel_fusion) { - const char* const name = channel_fusion.first.c_str(); - std::string fusion = static_cast(channel_fusion.second); - if (!image_channel_fusion_dict.contains(name)) { - image_channel_fusion_dict[name] = fusion; + + // image channel fusion + if (!node->has_parameter("image_channel_fusions")) { + RCLCPP_WARN(node->get_logger(), "No image_channel_fusions parameter found. Using default values."); + } else { + rclcpp::Parameter image_channel_fusion; + node->get_parameter("image_channel_fusions", image_channel_fusion); + + py::dict image_channel_fusion_dict; + auto image_channel_fusion_map = image_channel_fusion.as_string_array(); + for (const auto& channel_fusion : image_channel_fusion_map) { + const char* const channel_fusion_name = channel_fusion.c_str(); + std::string fusion; + node->get_parameter(channel_fusion_name, fusion); + if (!image_channel_fusion_dict.contains(channel_fusion_name)) { + image_channel_fusion_dict[channel_fusion_name] = fusion; + } + } + RCLCPP_INFO_STREAM(node->get_logger(), "image_channel_fusion_dict: " << image_channel_fusion_dict); + param_.attr("image_channel_fusions") = image_channel_fusion_dict; } - } - ROS_INFO_STREAM("image_channel_fusion_dict: " << image_channel_fusion_dict); - param_.attr("image_channel_fusions") = image_channel_fusion_dict; - } - param_.attr("update")(); - resolution_ = py::cast(param_.attr("get_value")("resolution")); - map_length_ = py::cast(param_.attr("get_value")("true_map_length")); - map_n_ = py::cast(param_.attr("get_value")("true_cell_n")); + param_.attr("update")(); + resolution_ = py::cast(param_.attr("get_value")("resolution")); + map_length_ = py::cast(param_.attr("get_value")("true_map_length")); + map_n_ = py::cast(param_.attr("get_value")("true_cell_n")); + + node->declare_parameter("enable_normal", false); + node->declare_parameter("enable_normal_color", false); + enable_normal_ = node->get_parameter("enable_normal").as_bool(); + enable_normal_color_ = node->get_parameter("enable_normal_color").as_bool(); - nh.param("enable_normal", enable_normal_, false); - nh.param("enable_normal_color", enable_normal_color_, false); } void ElevationMappingWrapper::input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, From 1dd0e86f248cb2ca03fac4be072fe10158585ab6 Mon Sep 17 00:00:00 2001 From: amilearning Date: Tue, 5 Nov 2024 00:30:09 +0100 Subject: [PATCH 447/504] ros2 --- elevation_mapping_cupy/CMakeLists.txt | 53 +- .../lib/elevation_mapping_cupy/__init__.py | 4 + .../elevation_mapping.py | 969 +++++++++++++ .../elevation_mapping_ros.py | 322 ++++ .../elevation_mapping_cupy/fusion/__init__.py | 0 .../fusion/fusion_manager.py | 112 ++ .../fusion/image_color.py | 86 ++ .../fusion/image_exponential.py | 77 + .../fusion/pointcloud_average.py | 113 ++ .../fusion/pointcloud_bayesian_inference.py | 122 ++ .../fusion/pointcloud_class_average.py | 126 ++ .../fusion/pointcloud_class_bayesian.py | 75 + .../fusion/pointcloud_class_max.py | 123 ++ .../fusion/pointcloud_color.py | 152 ++ .../kernels/__init__.py | 3 + .../kernels/custom_image_kernels.py | 271 ++++ .../kernels/custom_kernels.py | 685 +++++++++ .../kernels/custom_semantic_kernels.py | 375 +++++ .../lib/elevation_mapping_cupy/kernels/kk.py | 1290 +++++++++++++++++ .../elevation_mapping_cupy/map_initializer.py | 80 + .../lib/elevation_mapping_cupy/parameter.py | 300 ++++ .../plugins/__init__.py | 0 .../elevation_mapping_cupy/plugins/erosion.py | 113 ++ .../plugins/features_pca.py | 96 ++ .../plugins/inpainting.py | 63 + .../plugins/max_layer_filter.py | 108 ++ .../plugins/min_filter.py | 118 ++ .../plugins/plugin_manager.py | 268 ++++ .../plugins/robot_centric_elevation.py | 121 ++ .../plugins/semantic_filter.py | 133 ++ .../plugins/semantic_traversability.py | 83 ++ .../plugins/smooth_filter.py | 59 + .../elevation_mapping_cupy/semantic_map.py | 400 +++++ .../elevation_mapping_cupy/tests/__init__.py | 0 .../tests/test_elevation_mapping.py | 118 ++ .../tests/test_parameter.py | 17 + .../tests/test_plugins.py | 69 + .../tests/test_semantic_kernels.py | 307 ++++ .../tests/test_semantic_map.py | 47 + .../traversability_filter.py | 100 ++ .../traversability_polygon.py | 77 + .../config/core/core_param.yaml | 248 +++- .../config/core/example_setup.yaml | 159 +- .../elevation_mapping_ros.hpp | 242 ++-- .../elevation_mapping_wrapper.hpp | 12 +- .../launch/elevation_mapping_cupy.launch | 7 - .../launch/elevation_mapping_cupy.launch.py | 28 + elevation_mapping_cupy/package.xml | 2 + .../script/elevation_mapping_cupy/__init__.py | 6 +- .../elevation_mapping.py | 8 +- .../elevation_mapping_ros.py | 607 ++++---- .../elevation_mapping_cupy/kernels/kk.py | 1290 +++++++++++++++++ .../elevation_mapping_cupy/parameter.py | 16 +- .../traversability_polygon.py | 2 +- elevation_mapping_cupy/setup.py | 35 +- .../src/elevation_mapping_node.cpp | 15 +- .../src/elevation_mapping_ros.cpp | 519 ++++--- .../src/elevation_mapping_wrapper.cpp | 273 ++-- 58 files changed, 10154 insertions(+), 950 deletions(-) create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/__init__.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping_ros.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/__init__.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/fusion_manager.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_color.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_exponential.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_average.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_average.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_max.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_color.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/__init__.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_image_kernels.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_kernels.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_semantic_kernels.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/kk.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/map_initializer.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/parameter.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/__init__.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/erosion.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/features_pca.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/inpainting.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/max_layer_filter.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/min_filter.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/plugin_manager.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/robot_centric_elevation.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_filter.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_traversability.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/smooth_filter.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/semantic_map.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/__init__.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_elevation_mapping.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_parameter.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_plugins.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_kernels.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_map.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_filter.py create mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_polygon.py delete mode 100644 elevation_mapping_cupy/launch/elevation_mapping_cupy.launch create mode 100644 elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py create mode 100644 elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/kk.py diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index 81baa06d..fa8e2d25 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -1,16 +1,16 @@ cmake_minimum_required(VERSION 3.8) project(elevation_mapping_cupy) -# Enable C++11 (or higher if needed for ROS 2 and pybind11) -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) +# # Enable C++11 (or higher if needed for ROS 2 and pybind11) +# set(CMAKE_CXX_STANDARD 11) +# set(CMAKE_CXX_STANDARD_REQUIRED ON) # Compiler options if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() # Additional dependencies -find_package(Python COMPONENTS Interpreter Development) +# find_package(Python COMPONENTS Interpreter Development) find_package(PythonInterp 3 REQUIRED) find_package(pybind11 CONFIG REQUIRED) find_package(Eigen3 REQUIRED) @@ -37,7 +37,9 @@ find_package(elevation_map_msgs REQUIRED) find_package(grid_map_ros REQUIRED) find_package(image_transport REQUIRED) find_package(pcl_ros REQUIRED) - +find_package(tf2_eigen REQUIRED) +find_package(ament_cmake_python REQUIRED) +find_package(python_cmake_module REQUIRED) # List dependencies for ament_target_dependencies set(dependencies @@ -54,6 +56,7 @@ set(dependencies image_transport pcl_ros message_filters + tf2_eigen ) # Include directories @@ -72,29 +75,63 @@ add_library(elevation_mapping_ros ) # Link the library with necessary dependencies -target_link_libraries(elevation_mapping_ros ${PYTHON_LIBRARIES} ${OpenCV_LIBRARIES}) +target_link_libraries(elevation_mapping_ros ${PYTHON_LIBRARIES} ${OpenCV_LIBRARIES} pybind11::embed) ament_target_dependencies(elevation_mapping_ros ${dependencies}) # Declare C++ executable add_executable(elevation_mapping_node src/elevation_mapping_node.cpp) # Link the executable with the library and dependencies -target_link_libraries(elevation_mapping_node elevation_mapping_ros ${OpenCV_LIBRARIES}) +target_link_libraries(elevation_mapping_node elevation_mapping_ros ${OpenCV_LIBRARIES} pybind11::embed) ament_target_dependencies(elevation_mapping_node ${dependencies}) + + # Install targets install( - TARGETS elevation_mapping_ros elevation_mapping_node + TARGETS elevation_mapping_node + DESTINATION lib/${PROJECT_NAME} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib RUNTIME DESTINATION bin ) + +install(TARGETS + elevation_mapping_node + DESTINATION lib/${PROJECT_NAME} +) + + +install( + TARGETS elevation_mapping_ros + DESTINATION lib/${PROJECT_NAME} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin +) + + +ament_python_install_package(${PROJECT_NAME} PACKAGE_DIR script/${PROJECT_NAME}) + +install(PROGRAMS + DESTINATION lib/${PROJECT_NAME} +) + # Install launch and config directories install( DIRECTORY launch config DESTINATION share/${PROJECT_NAME} ) + + +_ament_cmake_python_register_environment_hook() + + +# ament_python_install_package(script/${PROJECT_NAME}) +# ament_python_install_package(script/${PROJECT_NAME}) + + # Ament package declaration ament_package() diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/__init__.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/__init__.py new file mode 100644 index 00000000..88d6a666 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/__init__.py @@ -0,0 +1,4 @@ +# from .parameter import Parameter +# from .elevation_mapping import ElevationMap +# from .kernels import custom_image_kernels, custom_kernels, custom_semantic_kernels + diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping.py new file mode 100644 index 00000000..4d704739 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping.py @@ -0,0 +1,969 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import os +from typing import List, Any, Tuple, Union + +import numpy as np +import threading +import subprocess + +from elevation_mapping_cupy.traversability_filter import ( + get_filter_chainer, + get_filter_torch, +) +from elevation_mapping_cupy.parameter import Parameter + + +from elevation_mapping_cupy.kernels import ( + add_points_kernel, + add_color_kernel, + color_average_kernel, +) +from elevation_mapping_cupy.kernels import sum_kernel +from elevation_mapping_cupy.kernels import error_counting_kernel +from elevation_mapping_cupy.kernels import average_map_kernel +from elevation_mapping_cupy.kernels import dilation_filter_kernel +from elevation_mapping_cupy.kernels import normal_filter_kernel +from elevation_mapping_cupy.kernels import polygon_mask_kernel +from elevation_mapping_cupy.kernels import image_to_map_correspondence_kernel + +from elevation_mapping_cupy.map_initializer import MapInitializer +from elevation_mapping_cupy.plugins.plugin_manager import PluginManager +from elevation_mapping_cupy.semantic_map import SemanticMap +from elevation_mapping_cupy.traversability_polygon import ( + get_masked_traversability, + is_traversable, + calculate_area, + transform_to_map_position, + transform_to_map_index, +) + +import cupy as cp + +xp = cp +pool = cp.cuda.MemoryPool(cp.cuda.malloc_managed) +cp.cuda.set_allocator(pool.malloc) + + +class ElevationMap: + """Core elevation mapping class.""" + + def __init__(self, param: Parameter): + """ + + Args: + param (elevation_mapping_cupy.parameter.Parameter): + """ + self.param = param + self.data_type = self.param.data_type + self.resolution = param.resolution + self.center = xp.array([0, 0, 0], dtype=self.data_type) + self.base_rotation = xp.eye(3, dtype=self.data_type) + self.map_length = param.map_length + self.cell_n = param.cell_n + + self.map_lock = threading.Lock() + self.semantic_map = SemanticMap(self.param) + self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n), dtype=self.data_type) + self.layer_names = [ + "elevation", + "variance", + "is_valid", + "traversability", + "time", + "upper_bound", + "is_upper_bound", + ] + + # buffers + self.traversability_buffer = xp.full((self.cell_n, self.cell_n), xp.nan) + self.normal_map = xp.zeros((3, self.cell_n, self.cell_n), dtype=self.data_type) + # Initial variance + self.initial_variance = param.initial_variance + self.elevation_map[1] += self.initial_variance + self.elevation_map[3] += 1.0 + + # overlap clearance + cell_range = int(self.param.overlap_clear_range_xy / self.resolution) + cell_range = np.clip(cell_range, 0, self.cell_n) + self.cell_min = self.cell_n // 2 - cell_range // 2 + self.cell_max = self.cell_n // 2 + cell_range // 2 + + # Initial mean_error + self.mean_error = 0.0 + self.additive_mean_error = 0.0 + + self.compile_kernels() + + self.compile_image_kernels() + + self.semantic_map.initialize_fusion() + + weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') + param.load_weights(weight_file) + + if param.use_chainer: + self.traversability_filter = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) + else: + self.traversability_filter = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) + self.untraversable_polygon = xp.zeros((1, 2)) + + # Plugins + self.plugin_manager = PluginManager(cell_n=self.cell_n) + plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') + self.plugin_manager.load_plugin_settings(plugin_config_file) + + self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") + + def clear(self): + """Reset all the layers of the elevation & the semantic map.""" + with self.map_lock: + self.elevation_map *= 0.0 + # Initial variance + self.elevation_map[1] += self.initial_variance + self.semantic_map.clear() + + self.mean_error = 0.0 + self.additive_mean_error = 0.0 + + def get_position(self, position): + """Return the position of the map center. + + Args: + position (numpy.ndarray): + + """ + position[0][:] = xp.asnumpy(self.center) + + def move(self, delta_position): + """Shift the map along all three axes according to the input. + + Args: + delta_position (numpy.ndarray): + """ + # Shift map using delta position. + delta_position = xp.asarray(delta_position) + delta_pixel = xp.round(delta_position[:2] / self.resolution) + delta_position_xy = delta_pixel * self.resolution + self.center[:2] += xp.asarray(delta_position_xy) + self.center[2] += xp.asarray(delta_position[2]) + self.shift_map_xy(delta_pixel) + self.shift_map_z(-delta_position[2]) + + def move_to(self, position, R): + """Shift the map to an absolute position and update the rotation of the robot. + + Args: + position (numpy.ndarray): + R (cupy._core.core.ndarray): + """ + # Shift map to the center of robot. + self.base_rotation = xp.asarray(R, dtype=self.data_type) + position = xp.asarray(position) + delta = position - self.center + delta_pixel = xp.around(delta[:2] / self.resolution) + delta_xy = delta_pixel * self.resolution + self.center[:2] += delta_xy + self.center[2] += delta[2] + self.shift_map_xy(-delta_pixel) + self.shift_map_z(-delta[2]) + + def pad_value(self, x, shift_value, idx=None, value=0.0): + """Create a padding of the map along x,y-axis according to amount that has shifted. + + Args: + x (cupy._core.core.ndarray): + shift_value (cupy._core.core.ndarray): + idx (Union[None, int, None, None]): + value (float): + """ + if idx is None: + if shift_value[0] > 0: + x[:, : shift_value[0], :] = value + elif shift_value[0] < 0: + x[:, shift_value[0] :, :] = value + if shift_value[1] > 0: + x[:, :, : shift_value[1]] = value + elif shift_value[1] < 0: + x[:, :, shift_value[1] :] = value + else: + if shift_value[0] > 0: + x[idx, : shift_value[0], :] = value + elif shift_value[0] < 0: + x[idx, shift_value[0] :, :] = value + if shift_value[1] > 0: + x[idx, :, : shift_value[1]] = value + elif shift_value[1] < 0: + x[idx, :, shift_value[1] :] = value + + def shift_map_xy(self, delta_pixel): + """Shift the map along the horizontal axes according to the input. + + Args: + delta_pixel (cupy._core.core.ndarray): + + """ + shift_value = delta_pixel.astype(cp.int32) + if cp.abs(shift_value).sum() == 0: + return + with self.map_lock: + self.elevation_map = cp.roll(self.elevation_map, shift_value, axis=(1, 2)) + self.pad_value(self.elevation_map, shift_value, value=0.0) + self.pad_value(self.elevation_map, shift_value, idx=1, value=self.initial_variance) + self.semantic_map.shift_map_xy(shift_value) + + def shift_map_z(self, delta_z): + """Shift the relevant layers along the vertical axis. + + Args: + delta_z (cupy._core.core.ndarray): + """ + with self.map_lock: + # elevation + self.elevation_map[0] += delta_z + # upper bound + self.elevation_map[5] += delta_z + + def compile_kernels(self): + """Compile all kernels belonging to the elevation map.""" + + self.new_map = cp.zeros( + (self.elevation_map.shape[0], self.cell_n, self.cell_n), + dtype=self.data_type, + ) + self.traversability_input = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + self.traversability_mask_dummy = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + self.min_filtered = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + self.min_filtered_mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + self.mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + self.add_points_kernel = add_points_kernel( + self.resolution, + self.cell_n, + self.cell_n, + self.param.sensor_noise_factor, + self.param.mahalanobis_thresh, + self.param.outlier_variance, + self.param.wall_num_thresh, + self.param.max_ray_length, + self.param.cleanup_step, + self.param.min_valid_distance, + self.param.max_height_range, + self.param.cleanup_cos_thresh, + self.param.ramped_height_range_a, + self.param.ramped_height_range_b, + self.param.ramped_height_range_c, + self.param.enable_edge_sharpen, + self.param.enable_visibility_cleanup, + ) + self.error_counting_kernel = error_counting_kernel( + self.resolution, + self.cell_n, + self.cell_n, + self.param.sensor_noise_factor, + self.param.mahalanobis_thresh, + self.param.drift_compensation_variance_inlier, + self.param.traversability_inlier, + self.param.min_valid_distance, + self.param.max_height_range, + self.param.ramped_height_range_a, + self.param.ramped_height_range_b, + self.param.ramped_height_range_c, + ) + self.average_map_kernel = average_map_kernel( + self.cell_n, self.cell_n, self.param.max_variance, self.initial_variance + ) + + self.dilation_filter_kernel = dilation_filter_kernel(self.cell_n, self.cell_n, self.param.dilation_size) + self.dilation_filter_kernel_initializer = dilation_filter_kernel( + self.cell_n, self.cell_n, self.param.dilation_size_initialize + ) + self.polygon_mask_kernel = polygon_mask_kernel(self.cell_n, self.cell_n, self.resolution) + self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) + + def compile_image_kernels(self): + """Compile kernels related to processing image messages.""" + + for config in self.param.subscriber_cfg.values(): + if config["data_type"] == "image": + self.valid_correspondence = cp.asarray( + np.zeros((self.cell_n, self.cell_n), dtype=np.bool_), dtype=np.bool_ + ) + self.uv_correspondence = cp.asarray( + np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), + dtype=np.float32, + ) + # self.distance_correspondence = cp.asarray( + # np.zeros((self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32 + # ) + # TODO tolerance_z_collision add parameter + self.image_to_map_correspondence_kernel = image_to_map_correspondence_kernel( + resolution=self.resolution, + width=self.cell_n, + height=self.cell_n, + tolerance_z_collision=0.10, + ) + break + + def shift_translation_to_map_center(self, t): + """Deduct the map center to get the translation of a point w.r.t. the map center. + + Args: + t (cupy._core.core.ndarray): Absolute point position + """ + t -= self.center + + def update_map_with_kernel(self, points_all, channels, R, t, position_noise, orientation_noise): + """Update map with new measurement. + + Args: + points_all (cupy._core.core.ndarray): + channels (List[str]): + R (cupy._core.core.ndarray): + t (cupy._core.core.ndarray): + position_noise (float): + orientation_noise (float): + """ + self.new_map *= 0.0 + error = cp.array([0.0], dtype=cp.float32) + error_cnt = cp.array([0], dtype=cp.float32) + points = points_all[:, :3] + # additional_fusion = self.get_fusion_of_pcl(channels) + with self.map_lock: + self.shift_translation_to_map_center(t) + self.error_counting_kernel( + self.elevation_map, + points, + cp.array([0.0], dtype=self.data_type), + cp.array([0.0], dtype=self.data_type), + R, + t, + self.new_map, + error, + error_cnt, + size=(points.shape[0]), + ) + if ( + self.param.enable_drift_compensation + and error_cnt > self.param.min_height_drift_cnt + and ( + position_noise > self.param.position_noise_thresh + or orientation_noise > self.param.orientation_noise_thresh + ) + ): + self.mean_error = error / error_cnt + self.additive_mean_error += self.mean_error + if np.abs(self.mean_error) < self.param.max_drift: + self.elevation_map[0] += self.mean_error * self.param.drift_compensation_alpha + self.add_points_kernel( + cp.array([0.0], dtype=self.data_type), + cp.array([0.0], dtype=self.data_type), + R, + t, + self.normal_map, + points, + self.elevation_map, + self.new_map, + size=(points.shape[0]), + ) + self.average_map_kernel(self.new_map, self.elevation_map, size=(self.cell_n * self.cell_n)) + + self.semantic_map.update_layers_pointcloud(points_all, channels, R, t, self.new_map) + + if self.param.enable_overlap_clearance: + self.clear_overlap_map(t) + # dilation before traversability_filter + self.traversability_input *= 0.0 + self.dilation_filter_kernel( + self.elevation_map[5], + self.elevation_map[2] + self.elevation_map[6], + self.traversability_input, + self.traversability_mask_dummy, + size=(self.cell_n * self.cell_n), + ) + # calculate traversability + traversability = self.traversability_filter(self.traversability_input) + self.elevation_map[3][3:-3, 3:-3] = traversability.reshape( + (traversability.shape[2], traversability.shape[3]) + ) + + # calculate normal vectors + self.update_normal(self.traversability_input) + + def clear_overlap_map(self, t): + """Clear overlapping areas around the map center. + + Args: + t (cupy._core.core.ndarray): Absolute point position + """ + + height_min = t[2] - self.param.overlap_clear_range_z + height_max = t[2] + self.param.overlap_clear_range_z + near_map = self.elevation_map[:, self.cell_min : self.cell_max, self.cell_min : self.cell_max] + valid_idx = ~cp.logical_or(near_map[0] < height_min, near_map[0] > height_max) + near_map[0] = cp.where(valid_idx, near_map[0], 0.0) + near_map[1] = cp.where(valid_idx, near_map[1], self.initial_variance) + near_map[2] = cp.where(valid_idx, near_map[2], 0.0) + valid_idx = ~cp.logical_or(near_map[5] < height_min, near_map[5] > height_max) + near_map[5] = cp.where(valid_idx, near_map[5], 0.0) + near_map[6] = cp.where(valid_idx, near_map[6], 0.0) + self.elevation_map[:, self.cell_min : self.cell_max, self.cell_min : self.cell_max] = near_map + + def get_additive_mean_error(self): + """Returns the additive mean error. + + Returns: + + """ + return self.additive_mean_error + + def update_variance(self): + """Adds the time variacne to the valid cells.""" + self.elevation_map[1] += self.param.time_variance * self.elevation_map[2] + + def update_time(self): + """adds the time interval to the time layer.""" + self.elevation_map[4] += self.param.time_interval + + def update_upper_bound_with_valid_elevation(self): + """Filters all invalid cell's upper_bound and is_upper_bound layers.""" + mask = self.elevation_map[2] > 0.5 + self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) + self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) + + def input_pointcloud( + self, + raw_points: cp._core.core.ndarray, + channels: List[str], + R: cp._core.core.ndarray, + t: cp._core.core.ndarray, + position_noise: float, + orientation_noise: float, + ): + """Input the point cloud and fuse the new measurements to update the elevation map. + + Args: + raw_points (cupy._core.core.ndarray): + channels (List[str]): + R (cupy._core.core.ndarray): + t (cupy._core.core.ndarray): + position_noise (float): + orientation_noise (float): + + Returns: + None: + """ + raw_points = cp.asarray(raw_points, dtype=self.data_type) + additional_channels = channels[3:] + raw_points = raw_points[~cp.isnan(raw_points[:, :3]).any(axis=1)] + self.update_map_with_kernel( + raw_points, + additional_channels, + cp.asarray(R, dtype=self.data_type), + cp.asarray(t, dtype=self.data_type), + position_noise, + orientation_noise, + ) + + def input_image( + self, + image: List[cp._core.core.ndarray], + channels: List[str], + # fusion_methods: List[str], + R: cp._core.core.ndarray, + t: cp._core.core.ndarray, + K: cp._core.core.ndarray, + D: cp._core.core.ndarray, + distortion_model: str, + image_height: int, + image_width: int, + ): + """Input image and fuse the new measurements to update the elevation map. + + Args: + sub_key (str): Key used to identify the subscriber configuration + image (List[cupy._core.core.ndarray]): List of array containing the individual image input channels + R (cupy._core.core.ndarray): Camera optical center rotation + t (cupy._core.core.ndarray): Camera optical center translation + K (cupy._core.core.ndarray): Camera intrinsics + image_height (int): Image height + image_width (int): Image width + + Returns: + None: + """ + + image = np.stack(image, axis=0) + if len(image.shape) == 2: + image = image[None] + + # Convert to cupy + image = cp.asarray(image, dtype=self.data_type) + K = cp.asarray(K, dtype=self.data_type) + R = cp.asarray(R, dtype=self.data_type) + t = cp.asarray(t, dtype=self.data_type) + D = cp.asarray(D, dtype=self.data_type) + image_height = cp.float32(image_height) + image_width = cp.float32(image_width) + + if len(D) < 4: + D = cp.zeros(5, dtype=self.data_type) + elif len(D) == 4: + D = cp.concatenate([D, cp.zeros(1, dtype=self.data_type)]) + else: + D = D[:5] + + if distortion_model == "radtan": + pass + elif distortion_model == "equidistant": + # Not implemented yet. + D *= 0 + elif distortion_model == "plumb_bob": + # Not implemented yet. + D *= 0 + else: + # Not implemented yet. + D *= 0 + + # Calculate transformation matrix + P = cp.asarray(K @ cp.concatenate([R, t[:, None]], 1), dtype=np.float32) + t_cam_map = -R.T @ t - self.center + t_cam_map = t_cam_map.get() + x1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[0]) / self.resolution)) + y1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[1]) / self.resolution)) + z1 = cp.float32(t_cam_map[2]) + + self.uv_correspondence *= 0 + self.valid_correspondence[:, :] = False + + with self.map_lock: + self.image_to_map_correspondence_kernel( + self.elevation_map, + x1, + y1, + z1, + P.reshape(-1), + K.reshape(-1), + D.reshape(-1), + image_height, + image_width, + self.center, + self.uv_correspondence, + self.valid_correspondence, + size=int(self.cell_n * self.cell_n), + ) + self.semantic_map.update_layers_image( + image, + channels, + self.uv_correspondence, + self.valid_correspondence, + image_height, + image_width, + ) + + def update_normal(self, dilated_map): + """Clear the normal map and then apply the normal kernel with dilated map as input. + + Args: + dilated_map (cupy._core.core.ndarray): + """ + with self.map_lock: + self.normal_map *= 0.0 + self.normal_filter_kernel( + dilated_map, + self.elevation_map[2], + self.normal_map, + size=(self.cell_n * self.cell_n), + ) + + def process_map_for_publish(self, input_map, fill_nan=False, add_z=False, xp=cp): + """Process the input_map according to the fill_nan and add_z flags. + + Args: + input_map (cupy._core.core.ndarray): + fill_nan (bool): + add_z (bool): + xp (module): + + Returns: + cupy._core.core.ndarray: + """ + m = input_map.copy() + if fill_nan: + m = xp.where(self.elevation_map[2] > 0.5, m, xp.nan) + if add_z: + m = m + self.center[2] + return m[1:-1, 1:-1] + + def get_elevation(self): + """Get the elevation layer. + + Returns: + elevation layer + + """ + return self.process_map_for_publish(self.elevation_map[0], fill_nan=True, add_z=True) + + def get_variance(self): + """Get the variance layer. + + Returns: + variance layer + """ + return self.process_map_for_publish(self.elevation_map[1], fill_nan=False, add_z=False) + + def get_traversability(self): + """Get the traversability layer. + + Returns: + traversability layer + """ + traversability = cp.where( + (self.elevation_map[2] + self.elevation_map[6]) > 0.5, + self.elevation_map[3].copy(), + cp.nan, + ) + self.traversability_buffer[3:-3, 3:-3] = traversability[3:-3, 3:-3] + traversability = self.traversability_buffer[1:-1, 1:-1] + return traversability + + def get_time(self): + """Get the time layer. + + Returns: + time layer + """ + return self.process_map_for_publish(self.elevation_map[4], fill_nan=False, add_z=False) + + def get_upper_bound(self): + """Get the upper bound layer. + + Returns: + upper_bound: upper bound layer + """ + if self.param.use_only_above_for_upper_bound: + valid = cp.logical_or( + cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), + self.elevation_map[2] > 0.5, + ) + else: + valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) + upper_bound = cp.where(valid, self.elevation_map[5].copy(), cp.nan) + upper_bound = upper_bound[1:-1, 1:-1] + self.center[2] + return upper_bound + + def get_is_upper_bound(self): + """Get the is upper bound layer. + + Returns: + is_upper_bound: layer + """ + if self.param.use_only_above_for_upper_bound: + valid = cp.logical_or( + cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), + self.elevation_map[2] > 0.5, + ) + else: + valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) + is_upper_bound = cp.where(valid, self.elevation_map[6].copy(), cp.nan) + is_upper_bound = is_upper_bound[1:-1, 1:-1] + return is_upper_bound + + def xp_of_array(self, array): + """Indicate which library is used for xp. + + Args: + array (cupy._core.core.ndarray): + + Returns: + module: either np or cp + """ + if type(array) == cp.ndarray: + return cp + elif type(array) == np.ndarray: + return np + + def copy_to_cpu(self, array, data, stream=None): + """Transforms the data to float32 and if on gpu loads it to cpu. + + Args: + array (cupy._core.core.ndarray): + data (numpy.ndarray): + stream (Union[None, cupy.cuda.stream.Stream, None, None, None, None, None, None, None]): + """ + if type(array) == np.ndarray: + data[...] = array.astype(np.float32) + elif type(array) == cp.ndarray: + if stream is not None: + data[...] = cp.asnumpy(array.astype(np.float32), stream=stream) + else: + data[...] = cp.asnumpy(array.astype(np.float32)) + + def exists_layer(self, name): + """Check if the layer exists in elevation map or in the semantic map. + + Args: + name (str): Layer name + + Returns: + bool: Indicates if layer exists. + """ + if name in self.layer_names: + return True + elif name in self.semantic_map.layer_names: + return True + elif name in self.plugin_manager.layer_names: + return True + else: + return False + + def get_map_with_name_ref(self, name, data): + """Load a layer according to the name input to the data input. + + Args: + name (str): Name of the layer. + data (numpy.ndarray): Data structure that contains layer. + + """ + use_stream = True + xp = cp + with self.map_lock: + if name == "elevation": + m = self.get_elevation() + use_stream = False + elif name == "variance": + m = self.get_variance() + elif name == "traversability": + m = self.get_traversability() + elif name == "time": + m = self.get_time() + elif name == "upper_bound": + m = self.get_upper_bound() + elif name == "is_upper_bound": + m = self.get_is_upper_bound() + elif name == "normal_x": + m = self.normal_map.copy()[0, 1:-1, 1:-1] + elif name == "normal_y": + m = self.normal_map.copy()[1, 1:-1, 1:-1] + elif name == "normal_z": + m = self.normal_map.copy()[2, 1:-1, 1:-1] + elif name in self.semantic_map.layer_names: + m = self.semantic_map.get_map_with_name(name) + elif name in self.plugin_manager.layer_names: + self.plugin_manager.update_with_name( + name, + self.elevation_map, + self.layer_names, + self.semantic_map.semantic_map, + self.semantic_map.layer_names, + self.base_rotation, + self.semantic_map.elements_to_shift, + ) + m = self.plugin_manager.get_map_with_name(name) + p = self.plugin_manager.get_param_with_name(name) + xp = self.xp_of_array(m) + m = self.process_map_for_publish(m, fill_nan=p.fill_nan, add_z=p.is_height_layer, xp=xp) + else: + print("Layer {} is not in the map".format(name)) + return + m = xp.flip(m, 0) + m = xp.flip(m, 1) + if use_stream: + stream = cp.cuda.Stream(non_blocking=False) + else: + stream = None + self.copy_to_cpu(m, data, stream=stream) + + def get_normal_maps(self): + """Get the normal maps. + + Returns: + maps: the three normal values for each cell + """ + normal = self.normal_map.copy() + normal_x = normal[0, 1:-1, 1:-1] + normal_y = normal[1, 1:-1, 1:-1] + normal_z = normal[2, 1:-1, 1:-1] + maps = xp.stack([normal_x, normal_y, normal_z], axis=0) + maps = xp.flip(maps, 1) + maps = xp.flip(maps, 2) + maps = xp.asnumpy(maps) + return maps + + def get_normal_ref(self, normal_x_data, normal_y_data, normal_z_data): + """Get the normal maps as reference. + + Args: + normal_x_data: + normal_y_data: + normal_z_data: + """ + maps = self.get_normal_maps() + self.stream = cp.cuda.Stream(non_blocking=True) + normal_x_data[...] = xp.asnumpy(maps[0], stream=self.stream) + normal_y_data[...] = xp.asnumpy(maps[1], stream=self.stream) + normal_z_data[...] = xp.asnumpy(maps[2], stream=self.stream) + + def get_layer(self, name): + """Return the layer with the name input. + + Args: + name: The layers name. + + Returns: + return_map: The rqeuested layer. + + """ + if name in self.layer_names: + idx = self.layer_names.index(name) + return_map = self.elevation_map[idx] + elif name in self.semantic_map.layer_names: + idx = self.semantic_map.layer_names.index(name) + return_map = self.semantic_map.semantic_map[idx] + elif name in self.plugin_manager.layer_names: + self.plugin_manager.update_with_name( + name, + self.elevation_map, + self.layer_names, + self.semantic_map, + self.base_rotation, + ) + return_map = self.plugin_manager.get_map_with_name(name) + else: + print("Layer {} is not in the map, returning traversabiltiy!".format(name)) + return + return return_map + + def get_polygon_traversability(self, polygon, result): + """Check if input polygons are traversable. + + Args: + polygon (cupy._core.core.ndarray): + result (numpy.ndarray): + + Returns: + Union[None, int]: + """ + polygon = xp.asarray(polygon) + area = calculate_area(polygon) + polygon = polygon.astype(self.data_type) + pmin = self.center[:2] - self.map_length / 2 + self.resolution + pmax = self.center[:2] + self.map_length / 2 - self.resolution + polygon[:, 0] = polygon[:, 0].clip(pmin[0], pmax[0]) + polygon[:, 1] = polygon[:, 1].clip(pmin[1], pmax[1]) + polygon_min = polygon.min(axis=0) + polygon_max = polygon.max(axis=0) + polygon_bbox = cp.concatenate([polygon_min, polygon_max]).flatten() + polygon_n = xp.array(polygon.shape[0], dtype=np.int16) + clipped_area = calculate_area(polygon) + self.polygon_mask_kernel( + polygon, + self.center[0], + self.center[1], + polygon_n, + polygon_bbox, + self.mask, + size=(self.cell_n * self.cell_n), + ) + tmp_map = self.get_layer(self.param.checker_layer) + masked, masked_isvalid = get_masked_traversability(self.elevation_map, self.mask, tmp_map) + if masked_isvalid.sum() > 0: + t = masked.sum() / masked_isvalid.sum() + else: + t = cp.asarray(0.0, dtype=self.data_type) + is_safe, un_polygon = is_traversable( + masked, + self.param.safe_thresh, + self.param.safe_min_thresh, + self.param.max_unsafe_n, + ) + untraversable_polygon_num = 0 + if un_polygon is not None: + un_polygon = transform_to_map_position(un_polygon, self.center[:2], self.cell_n, self.resolution) + untraversable_polygon_num = un_polygon.shape[0] + if clipped_area < 0.001: + is_safe = False + print("requested polygon is outside of the map") + result[...] = np.array([is_safe, t.get(), area.get()]) + self.untraversable_polygon = un_polygon + return untraversable_polygon_num + + def get_untraversable_polygon(self, untraversable_polygon): + """Copy the untraversable polygons to input untraversable_polygons. + + Args: + untraversable_polygon (numpy.ndarray): + """ + untraversable_polygon[...] = xp.asnumpy(self.untraversable_polygon) + + def initialize_map(self, points, method="cubic"): + """Initializes the map according to some points and using an approximation according to method. + + Args: + points (numpy.ndarray): + method (str): Interpolation method ['linear', 'cubic', 'nearest'] + """ + self.clear() + with self.map_lock: + points = cp.asarray(points, dtype=self.data_type) + indices = transform_to_map_index(points[:, :2], self.center[:2], self.cell_n, self.resolution) + points[:, :2] = indices.astype(points.dtype) + points[:, 2] -= self.center[2] + self.map_initializer(self.elevation_map, points, method) + if self.param.dilation_size_initialize > 0: + for i in range(2): + self.dilation_filter_kernel_initializer( + self.elevation_map[0], + self.elevation_map[2], + self.elevation_map[0], + self.elevation_map[2], + size=(self.cell_n * self.cell_n), + ) + self.update_upper_bound_with_valid_elevation() + + +if __name__ == "__main__": + # Test script for profiling. + # $ python -m cProfile -o profile.stats elevation_mapping.py + # $ snakeviz profile.stats + xp.random.seed(123) + R = xp.random.rand(3, 3) + t = xp.random.rand(3) + print(R, t) + param = Parameter( + use_chainer=False, + weight_file="/home/hojin/new_elev/src/elevation_mapping_cupy/elevation_mapping_cupy/config/core/weights.dat", + plugin_config_file="/home/hojin/new_elev/src/elevation_mapping_cupy/elevation_mapping_cupy/config/core/plugin_config.yaml", + ) + param.additional_layers = ["rgb", "grass", "tree", "people"] + # param.fusion_algorithms = ["color", "class_bayesian", "class_bayesian", "class_bayesian"] + param.fusion_algorithms = ["image_color", "pointcloud_color", "pointcloud_class_average"] + param.update() + elevation = ElevationMap(param) + layers = [ + "elevation", + "variance", + "traversability", + "min_filter", + "smooth", + "inpaint", + "rgb", + ] + points = xp.random.rand(100000, len(layers)) + + channels = ["x", "y", "z"] + param.additional_layers + print(channels) + data = np.zeros((elevation.cell_n - 2, elevation.cell_n - 2), dtype=np.float32) + for i in range(50): + elevation.input_pointcloud(points, channels, R, t, 0, 0) + elevation.update_normal(elevation.elevation_map[0]) + pos = np.array([i * 0.01, i * 0.02, i * 0.01]) + elevation.move_to(pos, R) + for layer in layers: + elevation.get_map_with_name_ref(layer, data) + print(i) + polygon = cp.array([[0, 0], [2, 0], [0, 2]], dtype=param.data_type) + result = np.array([0, 0, 0]) + elevation.get_polygon_traversability(polygon, result) + print(result) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping_ros.py new file mode 100644 index 00000000..94cc1e5c --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping_ros.py @@ -0,0 +1,322 @@ +# # General +# import os +# import numpy as np +# import yaml + +# from elevation_mapping_cupy import ElevationMap, Parameter + + + +# # ROS2 +# import rclpy +# from rclpy.node import Node +# from tf_transformations import quaternion_matrix +# import tf2_ros +# from ament_index_python.packages import get_package_share_directory +# from cv_bridge import CvBridge + +# from sensor_msgs.msg import PointCloud2, Image, CameraInfo +# from grid_map_msgs.msg import GridMap +# from std_msgs.msg import Float32MultiArray, MultiArrayLayout as MAL, MultiArrayDimension as MAD + +# from functools import partial +# import message_filters + + +# PDC_DATATYPE = { +# "1": np.int8, +# "2": np.uint8, +# "3": np.int16, +# "4": np.uint16, +# "5": np.int32, +# "6": np.uint32, +# "7": np.float32, +# "8": np.float64, +# } + + +# class ElevationMapWrapper(Node): +# def __init__(self): +# super().__init__('elevation_mapping') +# self.node_name = "elevation_mapping" +# self.root = get_package_share_directory("elevation_mapping_cupy") +# weight_file = os.path.join(self.root, "config/core/weights.dat") +# plugin_config_file = os.path.join(self.root, "config/core/plugin_config.yaml") +# self.param = Parameter(use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file) + +# # ROS2 +# self.initialize_ros() +# self.param.subscriber_cfg = self.subscribers + +# self.initialize_elevation_mapping() +# # self.register_subscribers() +# # self.register_publishers() +# # self.register_timers() + +# self._last_t = None + + + + +# # # ROS +# # self.initalize_ros() +# # self.param.subscriber_cfg = self.subscribers + + +# def initialize_ros(self): +# self._tf_buffer = tf2_ros.Buffer() +# self._listener = tf2_ros.TransformListener(self._tf_buffer, self) +# self.get_ros_params() + + +# def initialize_elevation_mapping(self): +# self.param.update() +# # TODO add statistics across processed topics +# self._pointcloud_process_counter = 0 +# self._image_process_counter = 0 +# self._map = ElevationMap(self.param) +# self._map_data = np.zeros((self._map.cell_n - 2, self._map.cell_n - 2), dtype=np.float32) +# self._map_q = None +# self._map_t = None + + + + +# # def register_subscribers(self): +# # # check if CV bridge is needed +# # for config in self.param.subscriber_cfg.values(): +# # if config["data_type"] == "image": +# # self.cv_bridge = CvBridge() +# # break + +# # pointcloud_subs = {} +# # image_subs = {} +# # for key, config in self.subscribers.items(): +# # if config["data_type"] == "image": +# # camera_sub = message_filters.Subscriber(config["topic_name_camera"], Image) +# # camera_info_sub = message_filters.Subscriber(config["topic_name_camera_info"], CameraInfo) +# # image_subs[key] = message_filters.ApproximateTimeSynchronizer( +# # [camera_sub, camera_info_sub], queue_size=10, slop=0.5 +# # ) +# # image_subs[key].registerCallback(self.image_callback, key) + +# # elif config["data_type"] == "pointcloud": +# # pointcloud_subs[key] = rospy.Subscriber( +# # config["topic_name"], PointCloud2, self.pointcloud_callback, key +# # ) + +# # def register_publishers(self): +# # self._publishers = {} +# # self._publishers_timers = [] +# # for k, v in self.publishers.items(): +# # self._publishers[k] = rospy.Publisher(f"/{self.node_name}/{k}", GridMap, queue_size=10) +# # # partial(.) allows to pass a default argument to a callback +# # self._publishers_timers.append(rospy.Timer(rospy.Duration(1 / v["fps"]), partial(self.publish_map, k))) + +# # def publish_map(self, k, t): +# # print("publish_map") +# # if self._map_q is None: +# # return +# # gm = GridMap() +# # gm.info.header.frame_id = self.map_frame +# # gm.info.header.stamp = rospy.Time.now() +# # gm.info.header.seq = 0 +# # gm.info.resolution = self._map.resolution +# # gm.info.length_x = self._map.map_length +# # gm.info.length_y = self._map.map_length +# # gm.info.pose.position.x = self._map_t.x +# # gm.info.pose.position.y = self._map_t.y +# # gm.info.pose.position.z = 0.0 +# # gm.info.pose.orientation.w = 1.0 # self._map_q.w +# # gm.info.pose.orientation.x = 0.0 # self._map_q.x +# # gm.info.pose.orientation.y = 0.0 # self._map_q.y +# # gm.info.pose.orientation.z = 0.0 # self._map_q.z +# # gm.layers = [] +# # gm.basic_layers = self.publishers[k]["basic_layers"] +# # for i, layer in enumerate(self.publishers[k]["layers"]): +# # gm.layers.append(layer) +# # try: +# # self._map.get_map_with_name_ref(layer, self._map_data) +# # data = self._map_data.copy() +# # arr = Float32MultiArray() +# # arr.layout = MAL() +# # N = self._map_data.shape[0] +# # arr.layout.dim.append(MAD(label="column_index", size=N, stride=int(N * N))) +# # arr.layout.dim.append(MAD(label="row_index", size=N, stride=N)) +# # arr.data = tuple(np.ascontiguousarray(data.T).reshape(-1)) +# # gm.data.append(arr) +# # except: +# # if layer in gm.basic_layers: +# # print("Error: Missed Layer in basic layers") + +# # gm.outer_start_index = 0 +# # gm.inner_start_index = 0 + +# # self._publishers[k].publish(gm) + +# # def register_timers(self): +# # self.timer_variance = rospy.Timer(rospy.Duration(1 / self.update_variance_fps), self.update_variance) +# # self.timer_pose = rospy.Timer(rospy.Duration(1 / self.update_pose_fps), self.update_pose) +# # self.timer_time = rospy.Timer(rospy.Duration(self.time_interval), self.update_time) + +# # def image_callback(self, camera_msg, camera_info_msg, sub_key): +# # # get pose of image +# # ti = rospy.Time(secs=camera_msg.header.stamp.secs, nsecs=camera_msg.header.stamp.nsecs) +# # self._last_t = ti +# # try: +# # transform = self._tf_buffer.lookup_transform( +# # camera_msg.header.frame_id, self.map_frame, ti, rospy.Duration(1.0) +# # ) +# # except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: +# # print("Error: image_callback:", e) +# # return + +# # t = transform.transform.translation +# # t = np.array([t.x, t.y, t.z]) +# # q = transform.transform.rotation +# # R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] + +# # semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") + +# # if len(semantic_img.shape) != 2: +# # semantic_img = [semantic_img[:, :, k] for k in range(3)] + +# # else: +# # semantic_img = [semantic_img] + +# # K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) + +# # assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" +# # D = np.array(camera_info_msg.D, dtype=np.float32).reshape(5, 1) + +# # # process pointcloud +# # self._map.input_image(sub_key, semantic_img, R, t, K, D, camera_info_msg.height, camera_info_msg.width) +# # self._image_process_counter += 1 + +# # def pointcloud_callback(self, msg, sub_key): +# # channels = ["x", "y", "z"] + self.param.subscriber_cfg[sub_key]["channels"] + +# # points = ros_numpy.numpify(msg) +# # pts = np.empty((points.shape[0], 0)) +# # for ch in channels: +# # p = points[ch] +# # if len(p.shape) == 1: +# # p = p[:, None] +# # pts = np.append(pts, p, axis=1) + +# # # get pose of pointcloud +# # ti = rospy.Time(secs=msg.header.stamp.secs, nsecs=msg.header.stamp.nsecs) +# # self._last_t = ti +# # try: +# # transform = self._tf_buffer.lookup_transform(self.map_frame, msg.header.frame_id, ti, rospy.Duration(1.0)) +# # except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: +# # print("Error: pointcloud_callback: ", e) +# # return + +# # t = transform.transform.translation +# # t = np.array([t.x, t.y, t.z]) +# # q = transform.transform.rotation +# # R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] + +# # # process pointcloud +# # self._map.input(pts, channels, R, t, 0, 0) +# # self._pointcloud_process_counter += 1 +# # print("Pointclouds processed: ", self._pointcloud_process_counter) + +# # def update_pose(self, t): +# # # get pose of base +# # # t = rospy.Time.now() +# # if self._last_t is None: +# # return +# # try: +# # transform = self._tf_buffer.lookup_transform( +# # self.map_frame, self.base_frame, self._last_t, rospy.Duration(1.0) +# # ) +# # except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: +# # print("Error: update_pose error: ", e) +# # return +# # t = transform.transform.translation +# # trans = np.array([t.x, t.y, t.z]) +# # q = transform.transform.rotation +# # rot = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] +# # self._map.move_to(trans, rot) + +# # self._map_t = t +# # self._map_q = q + +# # def update_variance(self, t): +# # self._map.update_variance() + +# # def update_time(self, t): +# # self._map.update_time() + + + +# def declare_parameters_from_yaml(self, yaml_file): +# def declare_nested_parameters(parent_name, param_dict): +# for sub_name, sub_value in param_dict.items(): +# full_param_name = f"{parent_name}.{sub_name}" + +# if isinstance(sub_value, dict): +# declare_nested_parameters(full_param_name, sub_value) +# else: +# if "elevation_mapping.ros__parameters" in full_param_name: +# full_param_name = full_param_name.replace("elevation_mapping.ros__parameters.", "") +# self.declare_parameter(full_param_name, sub_value) + +# with open(yaml_file, 'r') as file: +# params = yaml.safe_load(file) + +# # Set parameters in the node +# for param_name, param_value in params.items(): +# if isinstance(param_value, dict): +# # For nested dictionaries, set each nested parameter individually +# declare_nested_parameters(param_name, param_value) +# else: +# # For top-level parameters +# if "elevation_mapping.ros__parameters" in param_name: +# param_name = param_name.replace("elevation_mapping.ros__parameters.", "") +# self.declare_parameter(param_name, param_value) + + + + +# def get_ros_params(self): +# # TODO fix this here when later launching with launch-file +# # This is currently {p} elevation_mapping") +# param_file = os.path.join(self.root, f"config/core/core_param.yaml") +# self.declare_parameters_from_yaml(param_file) + +# # os.system(f"rosparam delete /{self.node_name}") +# # os.system(f"rosparam load {para} elevation_mapping") +# # self.subscribers = self.get_parameter("subscribers").get_parameter_value().string_value +# # self.publishers = self.get_parameter("publishers").get_parameter_value().string_value +# self.initialize_frame_id = self.get_parameter("initialize_frame_id").get_parameter_value().string_array_value +# self.initialize_tf_offset = self.get_parameter("initialize_tf_offset").get_parameter_value().double_value +# self.pose_topic = self.get_parameter("pose_topic").get_parameter_value().string_value +# self.map_frame = self.get_parameter("map_frame").get_parameter_value().string_value +# self.base_frame = self.get_parameter("base_frame").get_parameter_value().string_value +# self.corrected_map_frame = self.get_parameter("corrected_map_frame").get_parameter_value().string_value +# self.initialize_method = self.get_parameter("initialize_method").get_parameter_value().string_value +# self.position_lowpass_alpha = self.get_parameter("position_lowpass_alpha").get_parameter_value().double_value +# self.orientation_lowpass_alpha = self.get_parameter("orientation_lowpass_alpha").get_parameter_value().double_value +# self.update_variance_fps = self.get_parameter("update_variance_fps").get_parameter_value().double_value +# self.time_interval = self.get_parameter("time_interval").get_parameter_value().double_value +# self.update_pose_fps = self.get_parameter("update_pose_fps").get_parameter_value().double_value +# self.initialize_tf_grid_size = self.get_parameter("initialize_tf_grid_size").get_parameter_value().double_value +# self.map_acquire_fps = self.get_parameter("map_acquire_fps").get_parameter_value().double_value +# self.publish_statistics_fps = self.get_parameter("publish_statistics_fps").get_parameter_value().double_value +# self.enable_pointcloud_publishing = self.get_parameter("enable_pointcloud_publishing").get_parameter_value().bool_value +# self.enable_normal_arrow_publishing = self.get_parameter("enable_normal_arrow_publishing").get_parameter_value().bool_value +# self.enable_drift_corrected_TF_publishing = self.get_parameter("enable_drift_corrected_TF_publishing").get_parameter_value().bool_value +# self.use_initializer_at_start = self.get_parameter("use_initializer_at_start").get_parameter_value().bool_value + + +# def main(args=None): +# rclpy.init(args=args) +# node = ElevationMapWrapper() +# rclpy.spin(node) +# rclpy.shutdown() + +# if __name__ == '__main__': +# main() \ No newline at end of file diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/__init__.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/fusion_manager.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/fusion_manager.py new file mode 100644 index 00000000..aca34a6d --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/fusion_manager.py @@ -0,0 +1,112 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +from abc import ABC, abstractmethod +import cupy as cp +from typing import List, Dict, Any +from dataclasses import dataclass +import importlib +import inspect + + +# @dataclass +# class FusionParams: +# name: str + + +class FusionBase(ABC): + """ + This is a base class of Fusion + """ + + @abstractmethod + def __init__(self, *args, **kwargs): + """ + + Args: + fusion_params : FusionParams + The parameter of callback + """ + self.name = None + + @abstractmethod + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map): + pass + + +class FusionManager(object): + def __init__(self, params): + self.fusion_plugins: Dict[str, FusionBase] = {} + self.params = params + self.plugins = [] + + def register_plugin(self, plugin): + """ + Register a new fusion plugin + """ + try: + m = importlib.import_module("." + plugin, package="elevation_mapping_cupy.fusion") # -> 'module' + except: + raise ValueError("Plugin {} does not exist.".format(plugin)) + for name, obj in inspect.getmembers(m): + + if inspect.isclass(obj) and issubclass(obj, FusionBase) and name != "FusionBase": + self.plugins.append(obj(self.params)) + + def get_plugin_idx(self, name: str, data_type: str): + """ + Get a registered fusion plugin + """ + name = data_type + "_" + name + for idx, plugin in enumerate(self.plugins): + if plugin.name == name: + return idx + print("[WARNING] Plugin {} is not in the list: {}".format(name, self.plugins)) + return None + + def execute_plugin( + self, name: str, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, elements_to_shift + ): + """ + Execute a registered fusion plugin + """ + idx = self.get_plugin_idx(name, "pointcloud") + if idx is not None: + self.plugins[idx]( + points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, elements_to_shift + ) + # else: + # raise ValueError("Plugin {} is not registered".format(name)) + + def execute_image_plugin( + self, + name: str, + sem_map_idx, + image, + j, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + semantic_map, + new_map, + ): + """ + Execute a registered fusion plugin + """ + idx = self.get_plugin_idx(name, "image") + if idx is not None: + self.plugins[idx]( + sem_map_idx, + image, + j, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + semantic_map, + new_map, + ) + # else: + # raise ValueError("Plugin {} is not registered".format(name)) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_color.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_color.py new file mode 100644 index 00000000..c882c1b0 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_color.py @@ -0,0 +1,86 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + +def color_correspondences_to_map_kernel(resolution, width, height): + color_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + + int idx_red = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + int idx_green = image_width * image_height + idx_red; + int idx_blue = image_width * image_height * 2 + idx_red; + + unsigned int r = image_rgb[idx_red]; + unsigned int g = image_rgb[idx_green]; + unsigned int b = image_rgb[idx_blue]; + + unsigned int rgb = (r<<16) + (g << 8) + b; + float rgb_ = __uint_as_float(rgb); + new_sem_map[get_map_idx(i, map_idx)] = rgb_; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + """ + ).substitute(), + name="color_correspondences_to_map_kernel", + ) + return color_correspondences_to_map_kernel + + +class ImageColor(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + # print("Initialize fusion kernel") + self.name = "image_color" + self.cell_n = params.cell_n + self.resolution = params.resolution + + self.color_correspondences_to_map_kernel = color_correspondences_to_map_kernel( + resolution=self.resolution, width=self.cell_n, height=self.cell_n, + ) + + def __call__( + self, + sem_map_idx, + image, + j, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + semantic_map, + new_map, + ): + self.color_correspondences_to_map_kernel( + semantic_map, + cp.uint64(sem_map_idx), + image, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + new_map, + size=int(self.cell_n * self.cell_n), + ) + semantic_map[sem_map_idx] = new_map[sem_map_idx] diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_exponential.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_exponential.py new file mode 100644 index 00000000..26aa2f89 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_exponential.py @@ -0,0 +1,77 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + +def exponential_correspondences_to_map_kernel(resolution, width, height, alpha): + exponential_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)] * (1-${alpha}) + ${alpha} * image_mono[idx]; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + + """ + ).substitute(alpha=alpha), + name="exponential_correspondences_to_map_kernel", + ) + return exponential_correspondences_to_map_kernel + + +class ImageExponential(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + # print("Initialize fusion kernel") + self.name = "image_exponential" + self.cell_n = params.cell_n + self.resolution = params.resolution + + self.exponential_correspondences_to_map_kernel = exponential_correspondences_to_map_kernel( + resolution=self.resolution, width=self.cell_n, height=self.cell_n, alpha=0.7, + ) + + def __call__( + self, + sem_map_idx, + image, + j, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + semantic_map, + new_map, + ): + self.exponential_correspondences_to_map_kernel( + semantic_map, + sem_map_idx, + image[j], + uv_correspondence, + valid_correspondence, + image_height, + image_width, + new_map, + size=int(self.cell_n * self.cell_n), + ) + semantic_map[sem_map_idx] = new_map[sem_map_idx] diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_average.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_average.py new file mode 100644 index 00000000..c4165a54 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_average.py @@ -0,0 +1,113 @@ +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + +def sum_kernel( + resolution, width, height, +): + """Sums the semantic values of the classes for the exponentiala verage or for the average. + + Args: + resolution: + width: + height: + + Returns: + + """ + # input the list of layers, amount of channels can slo be input through kernel + sum_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map, raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; + atomicAdd(&newmap[get_map_idx(idx, map_lay[layer])], feat); + } + } + """ + ).substitute(), + name="sum_kernel", + ) + return sum_kernel + + +def average_kernel( + width, height, +): + average_kernel = cp.ElementwiseKernel( + in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U feat = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); + map[get_map_idx(id, map_lay[layer])] = feat; + } + """ + ).substitute(), + name="average_map_kernel", + ) + return average_kernel + + +class Average(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + # print("Initialize fusion kernel") + self.name = "pointcloud_average" + self.cell_n = params.cell_n + self.resolution = params.resolution + self.sum_kernel = sum_kernel(self.resolution, self.cell_n, self.cell_n,) + self.average_kernel = average_kernel(self.cell_n, self.cell_n,) + + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): + self.sum_kernel( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + new_map, + size=(points_all.shape[0] * pcl_ids.shape[0]), + ) + self.average_kernel( + new_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + elevation_map, + semantic_map, + size=(self.cell_n * self.cell_n * pcl_ids.shape[0]), + ) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py new file mode 100644 index 00000000..95dc8aea --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py @@ -0,0 +1,122 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + +def sum_compact_kernel( + resolution, width, height, +): + # input the list of layers, amount of channels can slo be input through kernel + sum_compact_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params=" raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; + atomicAdd(&newmap[get_map_idx(idx, layer)], feat); + } + } + """ + ).substitute(), + name="sum_compact_kernel", + ) + return sum_compact_kernel + + +def bayesian_inference_kernel( + width, height, +): + bayesian_inference_kernel = cp.ElementwiseKernel( + in_params=" raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U newmap, raw U sum_mean, raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U feat_ml = sum_mean[get_map_idx(id, layer)]/cnt; + U feat_old = map[get_map_idx(id, map_lay[layer])]; + U sigma_old = newmap[get_map_idx(id, map_lay[layer])]; + U sigma = 1.0; + U feat_new = sigma*feat_old /(cnt*sigma_old + sigma) +cnt*sigma_old *feat_ml /(cnt*sigma_old+sigma); + U sigma_new = sigma*sigma_old /(cnt*sigma_old +sigma); + map[get_map_idx(id, map_lay[layer])] = feat_new; + newmap[get_map_idx(id, map_lay[layer])] = sigma_new; + } + """ + ).substitute(), + name="bayesian_inference_kernel", + ) + return bayesian_inference_kernel + + +class BayesianInference(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + # print("Initialize bayesian inference kernel") + self.name = "pointcloud_bayesian_inference" + + self.cell_n = params.cell_n + self.resolution = params.resolution + self.fusion_algorithms = params.fusion_algorithms + self.data_type = params.data_type + + self.sum_mean = cp.ones( + (self.fusion_algorithms.count("bayesian_inference"), self.cell_n, self.cell_n,), self.data_type, + ) + # TODO initialize the variance with a value different than 0 + self.sum_compact_kernel = sum_compact_kernel(self.resolution, self.cell_n, self.cell_n,) + self.bayesian_inference_kernel = bayesian_inference_kernel(self.cell_n, self.cell_n,) + + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): + self.sum_mean *= 0 + self.sum_compact_kernel( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + self.sum_mean, + size=(points_all.shape[0]), + ) + self.bayesian_inference_kernel( + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + elevation_map, + new_map, + self.sum_mean, + semantic_map, + size=(self.cell_n * self.cell_n), + ) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_average.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_average.py new file mode 100644 index 00000000..80c96dc4 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_average.py @@ -0,0 +1,126 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + +def sum_kernel( + resolution, width, height, +): + """Sums the semantic values of the classes for the exponentiala verage or for the average. + + Args: + resolution: + width: + height: + + Returns: + + """ + # input the list of layers, amount of channels can slo be input through kernel + sum_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map, raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; + atomicAdd(&newmap[get_map_idx(idx, map_lay[layer])], feat); + } + } + """ + ).substitute(), + name="sum_kernel", + ) + return sum_kernel + + +def class_average_kernel( + width, height, alpha, +): + class_average_kernel = cp.ElementwiseKernel( + in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U prev_val = map[get_map_idx(id, map_lay[layer])]; + if (prev_val==0){ + U val = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); + map[get_map_idx(id, map_lay[layer])] = val; + } + else{ + U val = ${alpha} *prev_val + (1-${alpha}) * newmap[get_map_idx(id, map_lay[layer])]/(cnt); + map[get_map_idx(id, map_lay[layer])] = val; + } + } + """ + ).substitute(alpha=alpha,), + name="class_average_kernel", + ) + return class_average_kernel + + +class ClassAverage(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + # print("Initialize fusion kernel") + self.name = "pointcloud_class_average" + self.cell_n = params.cell_n + self.resolution = params.resolution + self.average_weight = params.average_weight + + self.sum_kernel = sum_kernel(self.resolution, self.cell_n, self.cell_n,) + self.class_average_kernel = class_average_kernel(self.cell_n, self.cell_n, self.average_weight,) + + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): + self.sum_kernel( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + new_map, + size=(points_all.shape[0] * pcl_ids.shape[0]), + ) + self.class_average_kernel( + new_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + elevation_map, + semantic_map, + size=(self.cell_n * self.cell_n * pcl_ids.shape[0]), + ) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py new file mode 100644 index 00000000..5fec3a7d --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py @@ -0,0 +1,75 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + +def alpha_kernel( + resolution, width, height, +): + # input the list of layers, amount of channels can slo be input through kernel + alpha_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U theta_max = 0; + W arg_max = 0; + U theta = p[id * pcl_channels[0] + pcl_chan[layer]]; + if (theta >=theta_max){ + arg_max = map_lay[layer]; + theta_max = theta; + } + atomicAdd(&newmap[get_map_idx(idx, arg_max)], theta_max); + } + } + """ + ).substitute(), + name="alpha_kernel", + ) + return alpha_kernel + + +class ClassBayesian(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + # print("Initialize fusion kernel") + self.name = "pointcloud_class_bayesian" + self.cell_n = params.cell_n + self.resolution = params.resolution + self.alpha_kernel = alpha_kernel(self.resolution, self.cell_n, self.cell_n,) + + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): + self.alpha_kernel( + points_all, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + new_map, + size=(points_all.shape[0]), + ) + # calculate new thetas + sum_alpha = cp.sum(new_map[layer_ids], axis=0) + # do not divide by zero + sum_alpha[sum_alpha == 0] = 1 + semantic_map[layer_ids] = new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_max.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_max.py new file mode 100644 index 00000000..e506571d --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_max.py @@ -0,0 +1,123 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +import string + +from .fusion_manager import FusionBase + + +def sum_max_kernel( + resolution, width, height, +): + # input the list of layers, amount of channels can slo be input through kernel + sum_max_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U max_pt, raw T max_id, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params=" raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U idx = p[i * pcl_channels[0]]; + U valid = p[i * pcl_channels[0] + 1]; + U inside = p[i * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + // for every max value + for ( W it=0;it> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = ( color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid && inside){ + unsigned int color = __float_as_uint(p[id * pcl_channels[0] + pcl_chan[layer]]); + atomicAdd(&color_map[get_map_idx(idx, layer*3)], get_r(color)); + atomicAdd(&color_map[get_map_idx(idx, layer*3+1)], get_g(color)); + atomicAdd(&color_map[get_map_idx(idx, layer*3 + 2)], get_b(color)); + atomicAdd(&color_map[get_map_idx(idx, pcl_channels[1]*3)], 1); + } + """ + ).substitute(width=width), + name="add_color_kernel", + ) + return add_color_kernel + + +def color_average_kernel( + width, height, +): + color_average_kernel = cp.ElementwiseKernel( + in_params="raw V color_map, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ unsigned int get_r(unsigned int color){ + unsigned int red = 0xFF0000; + unsigned int reds = (color & red) >> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = (color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + unsigned int cnt = color_map[get_map_idx(id, pcl_channels[1]*3)]; + if (cnt>0){ + // U prev_color = map[get_map_idx(id, map_lay[layer])]; + unsigned int r = color_map[get_map_idx(id, layer*3)]/(1*cnt); + unsigned int g = color_map[get_map_idx(id, layer*3+1)]/(1*cnt); + unsigned int b = color_map[get_map_idx(id, layer*3+2)]/(1*cnt); + //if (prev_color>=0){ + // unsigned int prev_r = get_r(prev_color); + // unsigned int prev_g = get_g(prev_color); + // unsigned int prev_b = get_b(prev_color); + // unsigned int r = prev_r/2 + color_map[get_map_idx(i, layer*3)]/(2*cnt); + // unsigned int g = prev_g/2 + color_map[get_map_idx(i, layer*3+1)]/(2*cnt); + // unsigned int b = prev_b/2 + color_map[get_map_idx(i, layer*3+2)]/(2*cnt); + //} + unsigned int rgb = (r<<16) + (g << 8) + b; + float rgb_ = __uint_as_float(rgb); + map[get_map_idx(id, map_lay[layer])] = rgb_; + } + """ + ).substitute(), + name="color_average_kernel", + ) + return color_average_kernel + + +class Color(FusionBase): + def __init__(self, params, *args, **kwargs): + # super().__init__(fusion_params, *args, **kwargs) + # print("Initialize fusion kernel") + self.name = "pointcloud_color" + self.cell_n = params.cell_n + self.resolution = params.resolution + + self.add_color_kernel = add_color_kernel(params.cell_n, params.cell_n,) + self.color_average_kernel = color_average_kernel(self.cell_n, self.cell_n) + + def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): + self.color_map = cp.zeros((1 + 3 * layer_ids.shape[0], self.cell_n, self.cell_n), dtype=cp.uint32,) + + points_all = points_all.astype(cp.float32) + self.add_color_kernel( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + self.color_map, + size=(points_all.shape[0]), + ) + self.color_average_kernel( + self.color_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + size=(self.cell_n * self.cell_n), + ) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/__init__.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/__init__.py new file mode 100644 index 00000000..06eecc38 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/__init__.py @@ -0,0 +1,3 @@ +from .custom_image_kernels import * +from .custom_kernels import * +from .custom_semantic_kernels import * diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_image_kernels.py new file mode 100644 index 00000000..a020ba2e --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_image_kernels.py @@ -0,0 +1,271 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import string + + +def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_collision): + """ + This function calculates the correspondence between the image and the map. + It takes in the resolution, width, height, and tolerance_z_collision as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _image_to_map_correspondence_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U K, raw U D, raw U image_height, raw U image_width, raw U center", + out_params="raw U uv_correspondence, raw B valid_correspondence", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ bool is_inside_map(int x, int y) { + return (x >= 0 && y >= 0 && x<${width} && y<${height}); + } + __device__ float get_l2_distance(int x0, int y0, int x1, int y1) { + float dx = x0-x1; + float dy = y0-y1; + return sqrt( dx*dx + dy*dy); + } + """ + ).substitute(width=width, height=height, resolution=resolution), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + + // return if gridcell has no valid height + if (map[get_map_idx(i, 2)] != 1){ + return; + } + + // get current cell position + int y0 = i % ${width}; + int x0 = i / ${width}; + + // gridcell 3D point in worldframe TODO reverse x and y + float p1 = (x0-(${width}/2)) * ${resolution} + center[0]; + float p2 = (y0-(${height}/2)) * ${resolution} + center[1]; + float p3 = map[cell_idx] + center[2]; + + // reproject 3D point into image plane + float u = p1 * P[0] + p2 * P[1] + p3 * P[2] + P[3]; + float v = p1 * P[4] + p2 * P[5] + p3 * P[6] + P[7]; + float d = p1 * P[8] + p2 * P[9] + p3 * P[10] + P[11]; + + // filter point behind image plane + if (d <= 0) { + return; + } + u = u/d; + v = v/d; + + // Check if D is all zeros + bool is_D_zero = (D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == 0 && D[4] == 0); + + // Apply undistortion using distortion matrix D if not all zeros + if (!is_D_zero) { + float k1 = D[0]; + float k2 = D[1]; + float p1 = D[2]; + float p2 = D[3]; + float k3 = D[4]; + float fx = K[0]; + float fy = K[4]; + float cx = K[2]; + float cy = K[5]; + float x = (u - cx) / fx; + float y = (v - cy) / fy; + float r2 = x * x + y * y; + float radial_distortion = 1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2; + float u_corrected = x * radial_distortion + 2 * p1 * x * y + p2 * (r2 + 2 * x * x); + float v_corrected = y * radial_distortion + 2 * p2 * x * y + p1 * (r2 + 2 * y * y); + u = fx * u_corrected + cx; + v = fy * v_corrected + cy; + } + + // filter point next to image plane + if ((u < 0) || (v < 0) || (u >= image_width) || (v >= image_height)){ + return; + } + + int y0_c = y0; + int x0_c = x0; + float total_dis = get_l2_distance(x0_c, y0_c, x1,y1); + float z0 = map[cell_idx]; + float delta_z = z1-z0; + + + // bresenham algorithm to iterate over cells in line between camera center and current gridmap cell + // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm + int dx = abs(x1-x0); + int sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0); + int sy = y0 < y1 ? 1 : -1; + int error = dx + dy; + + bool is_valid = true; + + // iterate over all cells along line + while (1){ + // assumption we do not need to check the height for camera center cell + if (x0 == x1 && y0 == y1){ + break; + } + + // check if height is invalid + if (is_inside_map(x0,y0)){ + int idx = y0 + (x0 * ${width}); + if (map[get_map_idx(idx, 2)]){ + float dis = get_l2_distance(x0_c, y0_c, x0, y0); + float rayheight = z0 + ( dis / total_dis * delta_z); + if ( map[idx] - ${tolerance_z_collision} > rayheight){ + is_valid = false; + break; + } + } + } + + + // computation of next gridcell index in line + int e2 = 2 * error; + if (e2 >= dy){ + if(x0 == x1){ + break; + } + error = error + dy; + x0 = x0 + sx; + } + if (e2 <= dx){ + if (y0 == y1){ + break; + } + error = error + dx; + y0 = y0 + sy; + } + } + + // mark the correspondence + uv_correspondence[get_map_idx(i, 0)] = u; + uv_correspondence[get_map_idx(i, 1)] = v; + valid_correspondence[get_map_idx(i, 0)] = is_valid; + """ + ).substitute(height=height, width=width, resolution=resolution, tolerance_z_collision=tolerance_z_collision), + name="image_to_map_correspondence_kernel", + ) + return _image_to_map_correspondence_kernel + + +def average_correspondences_to_map_kernel(width, height): + """ + This function calculates the average correspondences to the map. + It takes in the width and height as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _average_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + new_sem_map[get_map_idx(i, map_idx)] = image_mono[idx]; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + + """ + ).substitute(), + name="average_correspondences_to_map_kernel", + ) + return _average_correspondences_to_map_kernel + + +def exponential_correspondences_to_map_kernel(width, height, alpha): + """ + This function calculates the exponential correspondences to the map. + It takes in the width, height, and alpha as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _exponential_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)] * (1-${alpha}) + ${alpha} * image_mono[idx]; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + + """ + ).substitute(alpha=alpha), + name="exponential_correspondences_to_map_kernel", + ) + return _exponential_correspondences_to_map_kernel + + +def color_correspondences_to_map_kernel(width, height): + """ + This function calculates the color correspondences to the map. + It takes in the width and height as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _color_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + + int idx_red = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + int idx_green = image_width * image_height + idx_red; + int idx_blue = image_width * image_height * 2 + idx_red; + + unsigned int r = image_rgb[idx_red]; + unsigned int g = image_rgb[idx_green]; + unsigned int b = image_rgb[idx_blue]; + + unsigned int rgb = (r<<16) + (g << 8) + b; + float rgb_ = __uint_as_float(rgb); + new_sem_map[get_map_idx(i, map_idx)] = rgb_; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + """ + ).substitute(), + name="color_correspondences_to_map_kernel", + ) + return _color_correspondences_to_map_kernel diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_kernels.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_kernels.py new file mode 100644 index 00000000..d7025270 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_kernels.py @@ -0,0 +1,685 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import string + + +def map_utils( + resolution, + width, + height, + sensor_noise_factor, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, +): + util_preamble = string.Template( + """ + __device__ float16 clamp(float16 x, float16 min_x, float16 max_x) { + + return max(min(x, max_x), min_x); + } + __device__ int get_x_idx(float16 x, float16 center) { + int i = (x - center) / ${resolution} + 0.5 * ${width}; + return i; + } + __device__ int get_y_idx(float16 y, float16 center) { + int i = (y - center) / ${resolution} + 0.5 * ${height}; + return i; + } + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x == 0 || idx_x == ${width} - 1) { + return false; + } + if (idx_y == 0 || idx_y == ${height} - 1) { + return false; + } + return true; + } + __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { + int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); + int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); + return ${width} * idx_x + idx_y; + } + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ float transform_p(float16 x, float16 y, float16 z, + float16 r0, float16 r1, float16 r2, float16 t) { + return r0 * x + r1 * y + r2 * z + t; + } + __device__ float z_noise(float16 z){ + return ${sensor_noise_factor} * z * z; + } + + __device__ float point_sensor_distance(float16 x, float16 y, float16 z, + float16 sx, float16 sy, float16 sz) { + float d = (x - sx) * (x - sx) + (y - sy) * (y - sy) + (z - sz) * (z - sz); + return d; + } + + __device__ bool is_valid(float16 x, float16 y, float16 z, + float16 sx, float16 sy, float16 sz) { + float d = point_sensor_distance(x, y, z, sx, sy, sz); + float dxy = max(sqrt(x * x + y * y) - ${ramped_height_range_b}, 0.0); + if (d < ${min_valid_distance} * ${min_valid_distance}) { + return false; + } + else if (z - sz > dxy * ${ramped_height_range_a} + ${ramped_height_range_c} || z - sz > ${max_height_range}) { + return false; + } + else { + return true; + } + } + + __device__ float ray_vector(float16 tx, float16 ty, float16 tz, + float16 px, float16 py, float16 pz, + float16& rx, float16& ry, float16& rz){ + float16 vx = px - tx; + float16 vy = py - ty; + float16 vz = pz - tz; + float16 norm = sqrt(vx * vx + vy * vy + vz * vz); + if (norm > 0) { + rx = vx / norm; + ry = vy / norm; + rz = vz / norm; + } + else { + rx = 0; + ry = 0; + rz = 0; + } + return norm; + } + + __device__ float inner_product(float16 x1, float16 y1, float16 z1, + float16 x2, float16 y2, float16 z2) { + + float product = (x1 * x2 + y1 * y2 + z1 * z2); + return product; + } + + """ + ).substitute( + resolution=resolution, + width=width, + height=height, + sensor_noise_factor=sensor_noise_factor, + min_valid_distance=min_valid_distance, + max_height_range=max_height_range, + ramped_height_range_a=ramped_height_range_a, + ramped_height_range_b=ramped_height_range_b, + ramped_height_range_c=ramped_height_range_c, + ) + return util_preamble + + +def add_points_kernel( + resolution, + width, + height, + sensor_noise_factor, + mahalanobis_thresh, + outlier_variance, + wall_num_thresh, + max_ray_length, + cleanup_step, + min_valid_distance, + max_height_range, + cleanup_cos_thresh, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, + enable_edge_shaped=True, + enable_visibility_cleanup=True, +): + add_points_kernel = cp.ElementwiseKernel( + in_params="raw U center_x, raw U center_y, raw U R, raw U t, raw U norm_map", + out_params="raw U p, raw U map, raw T newmap", + preamble=map_utils( + resolution, + width, + height, + sensor_noise_factor, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, + ), + operation=string.Template( + """ + U rx = p[i * 3]; + U ry = p[i * 3 + 1]; + U rz = p[i * 3 + 2]; + U x = transform_p(rx, ry, rz, R[0], R[1], R[2], t[0]); + U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); + U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); + U v = z_noise(rz); + int idx = get_idx(x, y, center_x[0], center_y[0]); + if (is_valid(x, y, z, t[0], t[1], t[2])) { + if (is_inside(idx)) { + U map_h = map[get_map_idx(idx, 0)]; + U map_v = map[get_map_idx(idx, 1)]; + U num_points = newmap[get_map_idx(idx, 4)]; + if (abs(map_h - z) > (map_v * ${mahalanobis_thresh})) { + atomicAdd(&map[get_map_idx(idx, 1)], ${outlier_variance}); + } + else { + if (${enable_edge_shaped} && (num_points > ${wall_num_thresh}) && (z < map_h - map_v * ${mahalanobis_thresh} / num_points)) { + // continue; + } + else { + T new_h = (map_h * v + z * map_v) / (map_v + v); + T new_v = (map_v * v) / (map_v + v); + atomicAdd(&newmap[get_map_idx(idx, 0)], new_h); + atomicAdd(&newmap[get_map_idx(idx, 1)], new_v); + atomicAdd(&newmap[get_map_idx(idx, 2)], 1.0); + // is Valid + map[get_map_idx(idx, 2)] = 1; + // Time layer + map[get_map_idx(idx, 4)] = 0.0; + // Upper bound + map[get_map_idx(idx, 5)] = new_h; + map[get_map_idx(idx, 6)] = 0.0; + } + // visibility cleanup + } + } + } + if (${enable_visibility_cleanup}) { + float16 ray_x, ray_y, ray_z; + float16 ray_length = ray_vector(t[0], t[1], t[2], x, y, z, ray_x, ray_y, ray_z); + ray_length = min(ray_length, (float16)${max_ray_length}); + int last_nidx = -1; + for (float16 s=${ray_step}; s < ray_length; s+=${ray_step}) { + // iterate through ray + U nx = t[0] + ray_x * s; + U ny = t[1] + ray_y * s; + U nz = t[2] + ray_z * s; + int nidx = get_idx(nx, ny, center_x[0], center_y[0]); + if (last_nidx == nidx) {continue;} // Skip if we're still in the same cell + else {last_nidx = nidx;} + if (!is_inside(nidx)) {continue;} + + U nmap_h = map[get_map_idx(nidx, 0)]; + U nmap_v = map[get_map_idx(nidx, 1)]; + U nmap_valid = map[get_map_idx(nidx, 2)]; + // traversability + U nmap_trav = map[get_map_idx(nidx, 3)]; + // Time layer + U non_updated_t = map[get_map_idx(nidx, 4)]; + // upper bound + U nmap_upper = map[get_map_idx(nidx, 5)]; + U nmap_is_upper = map[get_map_idx(nidx, 6)]; + + // If point is close or is farther away than ray length, skip. + float16 d = (x - nx) * (x - nx) + (y - ny) * (y - ny) + (z - nz) * (z - nz); + if (d < 0.1 || !is_valid(x, y, z, t[0], t[1], t[2])) {continue;} + + // If invalid, do upper bound check, then skip + if (nmap_valid < 0.5) { + if (nz < nmap_upper || nmap_is_upper < 0.5) { + map[get_map_idx(nidx, 5)] = nz; + map[get_map_idx(nidx, 6)] = 1.0f; + } + continue; + } + // If updated recently, skip + if (non_updated_t < 0.5) {continue;} + + if (nmap_h > nz + 0.01 - min(nmap_v, 1.0) * 0.05) { + // If ray and norm is vertical, skip + U norm_x = norm_map[get_map_idx(nidx, 0)]; + U norm_y = norm_map[get_map_idx(nidx, 1)]; + U norm_z = norm_map[get_map_idx(nidx, 2)]; + float product = inner_product(ray_x, ray_y, ray_z, norm_x, norm_y, norm_z); + if (fabs(product) < ${cleanup_cos_thresh}) {continue;} + U num_points = newmap[get_map_idx(nidx, 3)]; + if (num_points > ${wall_num_thresh} && non_updated_t < 1.0) {continue;} + + // Finally, this cell is penetrated by the ray. + atomicAdd(&map[get_map_idx(nidx, 2)], -${cleanup_step}/(ray_length / ${max_ray_length})); + atomicAdd(&map[get_map_idx(nidx, 1)], ${outlier_variance}); + // Do upper bound check. + if (nz < nmap_upper || nmap_is_upper < 0.5) { + map[get_map_idx(nidx, 5)] = nz; + map[get_map_idx(nidx, 6)] = 1.0f; + } + } + } + } + p[i * 3]= idx; + p[i * 3 + 1] = is_valid(x, y, z, t[0], t[1], t[2]); + p[i * 3 + 2] = is_inside(idx); + """ + ).substitute( + mahalanobis_thresh=mahalanobis_thresh, + outlier_variance=outlier_variance, + wall_num_thresh=wall_num_thresh, + ray_step=resolution / 2 ** 0.5, + max_ray_length=max_ray_length, + cleanup_step=cleanup_step, + cleanup_cos_thresh=cleanup_cos_thresh, + enable_edge_shaped=int(enable_edge_shaped), + enable_visibility_cleanup=int(enable_visibility_cleanup), + ), + name="add_points_kernel", + ) + return add_points_kernel + + +def error_counting_kernel( + resolution, + width, + height, + sensor_noise_factor, + mahalanobis_thresh, + outlier_variance, + traversability_inlier, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, +): + error_counting_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U p, raw U center_x, raw U center_y, raw U R, raw U t", + out_params="raw U newmap, raw T error, raw T error_cnt", + preamble=map_utils( + resolution, + width, + height, + sensor_noise_factor, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, + ), + operation=string.Template( + """ + U rx = p[i * 3]; + U ry = p[i * 3 + 1]; + U rz = p[i * 3 + 2]; + U x = transform_p(rx, ry, rz, R[0], R[1], R[2], t[0]); + U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); + U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); + U v = z_noise(rz); + // if (!is_valid(z, t[2])) {return;} + if (!is_valid(x, y, z, t[0], t[1], t[2])) {return;} + // if ((x - t[0]) * (x - t[0]) + (y - t[1]) * (y - t[1]) + (z - t[2]) * (z - t[2]) < 0.5) {return;} + int idx = get_idx(x, y, center_x[0], center_y[0]); + if (!is_inside(idx)) { + return; + } + U map_h = map[get_map_idx(idx, 0)]; + U map_v = map[get_map_idx(idx, 1)]; + U map_valid = map[get_map_idx(idx, 2)]; + U map_t = map[get_map_idx(idx, 3)]; + if (map_valid > 0.5 && (abs(map_h - z) < (map_v * ${mahalanobis_thresh})) + && map_v < ${outlier_variance} / 2.0 + && map_t > ${traversability_inlier}) { + T e = z - map_h; + atomicAdd(&error[0], e); + atomicAdd(&error_cnt[0], 1); + atomicAdd(&newmap[get_map_idx(idx, 3)], 1.0); + } + atomicAdd(&newmap[get_map_idx(idx, 4)], 1.0); + """ + ).substitute( + mahalanobis_thresh=mahalanobis_thresh, + outlier_variance=outlier_variance, + traversability_inlier=traversability_inlier, + ), + name="error_counting_kernel", + ) + return error_counting_kernel + + +def average_map_kernel(width, height, max_variance, initial_variance): + average_map_kernel = cp.ElementwiseKernel( + in_params="raw U newmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U h = map[get_map_idx(i, 0)]; + U v = map[get_map_idx(i, 1)]; + U valid = map[get_map_idx(i, 2)]; + U new_h = newmap[get_map_idx(i, 0)]; + U new_v = newmap[get_map_idx(i, 1)]; + U new_cnt = newmap[get_map_idx(i, 2)]; + if (new_cnt > 0) { + if (new_v / new_cnt > ${max_variance}) { + map[get_map_idx(i, 0)] = 0; + map[get_map_idx(i, 1)] = ${initial_variance}; + map[get_map_idx(i, 2)] = 0; + } + else { + map[get_map_idx(i, 0)] = new_h / new_cnt; + map[get_map_idx(i, 1)] = new_v / new_cnt; + map[get_map_idx(i, 2)] = 1; + } + } + if (valid < 0.5) { + map[get_map_idx(i, 0)] = 0; + map[get_map_idx(i, 1)] = ${initial_variance}; + map[get_map_idx(i, 2)] = 0; + } + """ + ).substitute(max_variance=max_variance, initial_variance=initial_variance), + name="average_map_kernel", + ) + return average_map_kernel + + +def dilation_filter_kernel(width, height, dilation_size): + dilation_filter_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U mask", + out_params="raw U newmap, raw U newmask", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { + const int layer = ${width} * ${height}; + const int relative_idx = idx + ${width} * dy + dx; + return layer * layer_n + relative_idx; + } + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x <= 0 || idx_x >= ${width} - 1) { + return false; + } + if (idx_y <= 0 || idx_y >= ${height} - 1) { + return false; + } + return true; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U h = map[get_map_idx(i, 0)]; + U valid = mask[get_map_idx(i, 0)]; + newmap[get_map_idx(i, 0)] = h; + if (valid < 0.5) { + U distance = 100; + U near_value = 0; + for (int dy = -${dilation_size}; dy <= ${dilation_size}; dy++) { + for (int dx = -${dilation_size}; dx <= ${dilation_size}; dx++) { + int idx = get_relative_map_idx(i, dx, dy, 0); + if (!is_inside(idx)) {continue;} + U valid = mask[idx]; + if(valid > 0.5 && dx + dy < distance) { + distance = dx + dy; + near_value = map[idx]; + } + } + } + if(distance < 100) { + newmap[get_map_idx(i, 0)] = near_value; + newmask[get_map_idx(i, 0)] = 1.0; + } + } + """ + ).substitute(dilation_size=dilation_size), + name="dilation_filter_kernel", + ) + return dilation_filter_kernel + + +def normal_filter_kernel(width, height, resolution): + normal_filter_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U mask", + out_params="raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { + const int layer = ${width} * ${height}; + const int relative_idx = idx + ${width} * dy + dx; + return layer * layer_n + relative_idx; + } + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x <= 0 || idx_x >= ${width} - 1) { + return false; + } + if (idx_y <= 0 || idx_y >= ${height} - 1) { + return false; + } + return true; + } + __device__ float resolution() { + return ${resolution}; + } + """ + ).substitute(width=width, height=height, resolution=resolution), + operation=string.Template( + """ + U h = map[get_map_idx(i, 0)]; + U valid = mask[get_map_idx(i, 0)]; + if (valid > 0.5) { + int idx_x = get_relative_map_idx(i, 1, 0, 0); + int idx_y = get_relative_map_idx(i, 0, 1, 0); + if (!is_inside(idx_x) || !is_inside(idx_y)) { return; } + float dzdx = (map[idx_x] - h); + float dzdy = (map[idx_y] - h); + float nx = -dzdy / resolution(); + float ny = -dzdx / resolution(); + float nz = 1; + float norm = sqrt((nx * nx) + (ny * ny) + 1); + newmap[get_map_idx(i, 0)] = nx / norm; + newmap[get_map_idx(i, 1)] = ny / norm; + newmap[get_map_idx(i, 2)] = nz / norm; + } + """ + ).substitute(), + name="normal_filter_kernel", + ) + return normal_filter_kernel + + +def polygon_mask_kernel(width, height, resolution): + polygon_mask_kernel = cp.ElementwiseKernel( + in_params="raw U polygon, raw U center_x, raw U center_y, raw int16 polygon_n, raw U polygon_bbox", + out_params="raw U mask", + preamble=string.Template( + """ + __device__ struct Point + { + int x; + int y; + }; + // Given three colinear points p, q, r, the function checks if + // point q lies on line segment 'pr' + __device__ bool onSegment(Point p, Point q, Point r) + { + if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) && + q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y)) + return true; + return false; + } + // To find orientation of ordered triplet (p, q, r). + // The function returns following values + // 0 --> p, q and r are colinear + // 1 --> Clockwise + // 2 --> Counterclockwise + __device__ int orientation(Point p, Point q, Point r) + { + int val = (q.y - p.y) * (r.x - q.x) - + (q.x - p.x) * (r.y - q.y); + if (val == 0) return 0; // colinear + return (val > 0)? 1: 2; // clock or counterclock wise + } + // The function that returns true if line segment 'p1q1' + // and 'p2q2' intersect. + __device__ bool doIntersect(Point p1, Point q1, Point p2, Point q2) + { + // Find the four orientations needed for general and + // special cases + int o1 = orientation(p1, q1, p2); + int o2 = orientation(p1, q1, q2); + int o3 = orientation(p2, q2, p1); + int o4 = orientation(p2, q2, q1); + // General case + if (o1 != o2 && o3 != o4) + return true; + // Special Cases + // p1, q1 and p2 are colinear and p2 lies on segment p1q1 + if (o1 == 0 && onSegment(p1, p2, q1)) return true; + // p1, q1 and p2 are colinear and q2 lies on segment p1q1 + if (o2 == 0 && onSegment(p1, q2, q1)) return true; + // p2, q2 and p1 are colinear and p1 lies on segment p2q2 + if (o3 == 0 && onSegment(p2, p1, q2)) return true; + // p2, q2 and q1 are colinear and q1 lies on segment p2q2 + if (o4 == 0 && onSegment(p2, q1, q2)) return true; + return false; // Doesn't fall in any of the above cases + } + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ int get_idx_x(int idx){ + int idx_x = idx / ${width}; + return idx_x; + } + + __device__ int get_idx_y(int idx){ + int idx_y = idx % ${width}; + return idx_y; + } + + __device__ float16 clamp(float16 x, float16 min_x, float16 max_x) { + + return max(min(x, max_x), min_x); + } + __device__ float16 round(float16 x) { + return (int)x + (int)(2 * (x - (int)x)); + } + __device__ int get_x_idx(float16 x, float16 center) { + const float resolution = ${resolution}; + const float width = ${width}; + int i = (x - center) / resolution + 0.5 * width; + return i; + } + __device__ int get_y_idx(float16 y, float16 center) { + const float resolution = ${resolution}; + const float height = ${height}; + int i = (y - center) / resolution + 0.5 * height; + return i; + } + __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { + int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); + int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); + return ${width} * idx_x + idx_y; + } + + """ + ).substitute(width=width, height=height, resolution=resolution), + operation=string.Template( + """ + // Point p = {get_idx_x(i, center_x[0]), get_idx_y(i, center_y[0])}; + Point p = {get_idx_x(i), get_idx_y(i)}; + Point extreme = {100000, p.y}; + int bbox_min_idx = get_idx(polygon_bbox[0], polygon_bbox[1], center_x[0], center_y[0]); + int bbox_max_idx = get_idx(polygon_bbox[2], polygon_bbox[3], center_x[0], center_y[0]); + Point bmin = {get_idx_x(bbox_min_idx), get_idx_y(bbox_min_idx)}; + Point bmax = {get_idx_x(bbox_max_idx), get_idx_y(bbox_max_idx)}; + if (p.x < bmin.x || p.x > bmax.x || p.y < bmin.y || p.y > bmax.y){ + mask[i] = 0; + return; + } + else { + int intersect_cnt = 0; + for (int j = 0; j < polygon_n[0]; j++) { + Point p1, p2; + int i1 = get_idx(polygon[j * 2 + 0], polygon[j * 2 + 1], center_x[0], center_y[0]); + p1.x = get_idx_x(i1); + p1.y = get_idx_y(i1); + int j2 = (j + 1) % polygon_n[0]; + int i2 = get_idx(polygon[j2 * 2 + 0], polygon[j2 * 2 + 1], center_x[0], center_y[0]); + p2.x = get_idx_x(i2); + p2.y = get_idx_y(i2); + if (doIntersect(p1, p2, p, extreme)) + { + // If the point 'p' is colinear with line segment 'i-next', + // then check if it lies on segment. If it lies, return true, + // otherwise false + if (orientation(p1, p, p2) == 0) { + if (onSegment(p1, p, p2)){ + mask[i] = 1; + return; + } + } + else if(((p1.y <= p.y) && (p2.y > p.y)) || ((p1.y > p.y) && (p2.y <= p.y))){ + intersect_cnt++; + } + } + } + if (intersect_cnt % 2 == 0) { mask[i] = 0; } + else { mask[i] = 1; } + } + """ + ).substitute(a=1), + name="polygon_mask_kernel", + ) + return polygon_mask_kernel + + +if __name__ == "__main__": + for i in range(10): + import random + + a = cp.zeros((100, 100)) + n = random.randint(3, 5) + + # polygon = cp.array([[-1, -1], [3, 4], [2, 4], [1, 3]], dtype=float) + polygon = cp.array( + [[(random.random() - 0.5) * 10, (random.random() - 0.5) * 10] for i in range(n)], dtype=float + ) + print(polygon) + polygon_min = polygon.min(axis=0) + polygon_max = polygon.max(axis=0) + polygon_bbox = cp.concatenate([polygon_min, polygon_max]).flatten() + polygon_n = polygon.shape[0] + print(polygon_bbox) + # polygon_bbox = cp.array([-5, -5, 5, 5], dtype=float) + polygon_mask = polygon_mask_kernel(100, 100, 0.1) + import time + + start = time.time() + polygon_mask(polygon, 0.0, 0.0, polygon_n, polygon_bbox, a, size=(100 * 100)) + print(time.time() - start) + import pylab as plt + + print(a) + plt.imshow(cp.asnumpy(a)) + plt.show() diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_semantic_kernels.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_semantic_kernels.py new file mode 100644 index 00000000..26db74c0 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_semantic_kernels.py @@ -0,0 +1,375 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import string + + +def sum_kernel( + resolution, width, height, +): + """Sums the semantic values of the classes for the exponentiala verage or for the average. + + Args: + resolution: + width: + height: + + Returns: + + """ + # input the list of layers, amount of channels can slo be input through kernel + sum_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map, raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; + atomicAdd(&newmap[get_map_idx(idx, map_lay[layer])], feat); + } + } + """ + ).substitute(), + name="sum_kernel", + ) + return sum_kernel + + +def sum_compact_kernel( + resolution, width, height, +): + # input the list of layers, amount of channels can slo be input through kernel + sum_compact_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params=" raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; + atomicAdd(&newmap[get_map_idx(idx, layer)], feat); + } + } + """ + ).substitute(), + name="sum_compact_kernel", + ) + return sum_compact_kernel + + +def sum_max_kernel( + resolution, width, height, +): + # input the list of layers, amount of channels can slo be input through kernel + sum_max_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U max_pt, raw T max_id, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params=" raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U idx = p[i * pcl_channels[0]]; + U valid = p[i * pcl_channels[0] + 1]; + U inside = p[i * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + // for every max value + for ( W it=0;it=theta_max){ + arg_max = map_lay[layer]; + theta_max = theta; + } + atomicAdd(&newmap[get_map_idx(idx, arg_max)], theta_max); + } + } + """ + ).substitute(), + name="alpha_kernel", + ) + return alpha_kernel + + +def average_kernel( + width, height, +): + average_kernel = cp.ElementwiseKernel( + in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U feat = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); + map[get_map_idx(id, map_lay[layer])] = feat; + } + """ + ).substitute(), + name="average_map_kernel", + ) + return average_kernel + + +def bayesian_inference_kernel( + width, height, +): + bayesian_inference_kernel = cp.ElementwiseKernel( + in_params=" raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U newmap, raw U sum_mean, raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U feat_ml = sum_mean[get_map_idx(id, layer)]/cnt; + U feat_old = map[get_map_idx(id, map_lay[layer])]; + U sigma_old = newmap[get_map_idx(id, map_lay[layer])]; + U sigma = 1.0; + U feat_new = sigma*feat_old /(cnt*sigma_old + sigma) +cnt*sigma_old *feat_ml /(cnt*sigma_old+sigma); + U sigma_new = sigma*sigma_old /(cnt*sigma_old +sigma); + map[get_map_idx(id, map_lay[layer])] = feat_new; + newmap[get_map_idx(id, map_lay[layer])] = sigma_new; + } + """ + ).substitute(), + name="bayesian_inference_kernel", + ) + return bayesian_inference_kernel + + +def class_average_kernel( + width, height, alpha, +): + class_average_kernel = cp.ElementwiseKernel( + in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U prev_val = map[get_map_idx(id, map_lay[layer])]; + if (prev_val==0){ + U val = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); + map[get_map_idx(id, map_lay[layer])] = val; + } + else{ + U val = ${alpha} *prev_val + (1-${alpha}) * newmap[get_map_idx(id, map_lay[layer])]/(cnt); + map[get_map_idx(id, map_lay[layer])] = val; + } + } + """ + ).substitute(alpha=alpha,), + name="class_average_kernel", + ) + return class_average_kernel + + +def add_color_kernel( + width, height, +): + add_color_kernel = cp.ElementwiseKernel( + in_params="raw T p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw V color_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ unsigned int get_r(unsigned int color){ + unsigned int red = 0xFF0000; + unsigned int reds = (color & red) >> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = ( color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid && inside){ + unsigned int color = __float_as_uint(p[id * pcl_channels[0] + pcl_chan[layer]]); + atomicAdd(&color_map[get_map_idx(idx, layer*3)], get_r(color)); + atomicAdd(&color_map[get_map_idx(idx, layer*3+1)], get_g(color)); + atomicAdd(&color_map[get_map_idx(idx, layer*3 + 2)], get_b(color)); + atomicAdd(&color_map[get_map_idx(idx, pcl_channels[1]*3)], 1); + } + """ + ).substitute(width=width), + name="add_color_kernel", + ) + return add_color_kernel + + +def color_average_kernel( + width, height, +): + color_average_kernel = cp.ElementwiseKernel( + in_params="raw V color_map, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ unsigned int get_r(unsigned int color){ + unsigned int red = 0xFF0000; + unsigned int reds = (color & red) >> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = (color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + unsigned int cnt = color_map[get_map_idx(id, pcl_channels[1]*3)]; + if (cnt>0){ + // U prev_color = map[get_map_idx(id, map_lay[layer])]; + unsigned int r = color_map[get_map_idx(id, layer*3)]/(1*cnt); + unsigned int g = color_map[get_map_idx(id, layer*3+1)]/(1*cnt); + unsigned int b = color_map[get_map_idx(id, layer*3+2)]/(1*cnt); + //if (prev_color>=0){ + // unsigned int prev_r = get_r(prev_color); + // unsigned int prev_g = get_g(prev_color); + // unsigned int prev_b = get_b(prev_color); + // unsigned int r = prev_r/2 + color_map[get_map_idx(i, layer*3)]/(2*cnt); + // unsigned int g = prev_g/2 + color_map[get_map_idx(i, layer*3+1)]/(2*cnt); + // unsigned int b = prev_b/2 + color_map[get_map_idx(i, layer*3+2)]/(2*cnt); + //} + unsigned int rgb = (r<<16) + (g << 8) + b; + float rgb_ = __uint_as_float(rgb); + map[get_map_idx(id, map_lay[layer])] = rgb_; + } + """ + ).substitute(), + name="color_average_kernel", + ) + return color_average_kernel diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/kk.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/kk.py new file mode 100644 index 00000000..27562dda --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/kk.py @@ -0,0 +1,1290 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import string + + +def sum_kernel( + resolution, width, height, +): + """Sums the semantic values of the classes for the exponentiala verage or for the average. + + Args: + resolution: + width: + height: + + Returns: + + """ + # input the list of layers, amount of channels can slo be input through kernel + sum_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map, raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; + atomicAdd(&newmap[get_map_idx(idx, map_lay[layer])], feat); + } + } + """ + ).substitute(), + name="sum_kernel", + ) + return sum_kernel + + +def sum_compact_kernel( + resolution, width, height, +): + # input the list of layers, amount of channels can slo be input through kernel + sum_compact_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params=" raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; + atomicAdd(&newmap[get_map_idx(idx, layer)], feat); + } + } + """ + ).substitute(), + name="sum_compact_kernel", + ) + return sum_compact_kernel + + +def sum_max_kernel( + resolution, width, height, +): + # input the list of layers, amount of channels can slo be input through kernel + sum_max_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U max_pt, raw T max_id, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params=" raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U idx = p[i * pcl_channels[0]]; + U valid = p[i * pcl_channels[0] + 1]; + U inside = p[i * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + // for every max value + for ( W it=0;it=theta_max){ + arg_max = map_lay[layer]; + theta_max = theta; + } + atomicAdd(&newmap[get_map_idx(idx, arg_max)], theta_max); + } + } + """ + ).substitute(), + name="alpha_kernel", + ) + return alpha_kernel + + +def average_kernel( + width, height, +): + average_kernel = cp.ElementwiseKernel( + in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U feat = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); + map[get_map_idx(id, map_lay[layer])] = feat; + } + """ + ).substitute(), + name="average_map_kernel", + ) + return average_kernel + + +def bayesian_inference_kernel( + width, height, +): + bayesian_inference_kernel = cp.ElementwiseKernel( + in_params=" raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U newmap, raw U sum_mean, raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U feat_ml = sum_mean[get_map_idx(id, layer)]/cnt; + U feat_old = map[get_map_idx(id, map_lay[layer])]; + U sigma_old = newmap[get_map_idx(id, map_lay[layer])]; + U sigma = 1.0; + U feat_new = sigma*feat_old /(cnt*sigma_old + sigma) +cnt*sigma_old *feat_ml /(cnt*sigma_old+sigma); + U sigma_new = sigma*sigma_old /(cnt*sigma_old +sigma); + map[get_map_idx(id, map_lay[layer])] = feat_new; + newmap[get_map_idx(id, map_lay[layer])] = sigma_new; + } + """ + ).substitute(), + name="bayesian_inference_kernel", + ) + return bayesian_inference_kernel + + +def class_average_kernel( + width, height, alpha, +): + class_average_kernel = cp.ElementwiseKernel( + in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U prev_val = map[get_map_idx(id, map_lay[layer])]; + if (prev_val==0){ + U val = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); + map[get_map_idx(id, map_lay[layer])] = val; + } + else{ + U val = ${alpha} *prev_val + (1-${alpha}) * newmap[get_map_idx(id, map_lay[layer])]/(cnt); + map[get_map_idx(id, map_lay[layer])] = val; + } + } + """ + ).substitute(alpha=alpha,), + name="class_average_kernel", + ) + return class_average_kernel + + +def add_color_kernel( + width, height, +): + add_color_kernel = cp.ElementwiseKernel( + in_params="raw T p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw V color_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ unsigned int get_r(unsigned int color){ + unsigned int red = 0xFF0000; + unsigned int reds = (color & red) >> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = ( color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid && inside){ + unsigned int color = __float_as_uint(p[id * pcl_channels[0] + pcl_chan[layer]]); + atomicAdd(&color_map[get_map_idx(idx, layer*3)], get_r(color)); + atomicAdd(&color_map[get_map_idx(idx, layer*3+1)], get_g(color)); + atomicAdd(&color_map[get_map_idx(idx, layer*3 + 2)], get_b(color)); + atomicAdd(&color_map[get_map_idx(idx, pcl_channels[1]*3)], 1); + } + """ + ).substitute(width=width), + name="add_color_kernel", + ) + return add_color_kernel + + +def color_average_kernel( + width, height, +): + color_average_kernel = cp.ElementwiseKernel( + in_params="raw V color_map, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ unsigned int get_r(unsigned int color){ + unsigned int red = 0xFF0000; + unsigned int reds = (color & red) >> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = (color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + unsigned int cnt = color_map[get_map_idx(id, pcl_channels[1]*3)]; + if (cnt>0){ + // U prev_color = map[get_map_idx(id, map_lay[layer])]; + unsigned int r = color_map[get_map_idx(id, layer*3)]/(1*cnt); + unsigned int g = color_map[get_map_idx(id, layer*3+1)]/(1*cnt); + unsigned int b = color_map[get_map_idx(id, layer*3+2)]/(1*cnt); + //if (prev_color>=0){ + // unsigned int prev_r = get_r(prev_color); + // unsigned int prev_g = get_g(prev_color); + // unsigned int prev_b = get_b(prev_color); + // unsigned int r = prev_r/2 + color_map[get_map_idx(i, layer*3)]/(2*cnt); + // unsigned int g = prev_g/2 + color_map[get_map_idx(i, layer*3+1)]/(2*cnt); + // unsigned int b = prev_b/2 + color_map[get_map_idx(i, layer*3+2)]/(2*cnt); + //} + unsigned int rgb = (r<<16) + (g << 8) + b; + float rgb_ = __uint_as_float(rgb); + map[get_map_idx(id, map_lay[layer])] = rgb_; + } + """ + ).substitute(), + name="color_average_kernel", + ) + return color_average_kernel + + + +def map_utils( + resolution, + width, + height, + sensor_noise_factor, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, +): + util_preamble = string.Template( + """ + __device__ float16 clamp(float16 x, float16 min_x, float16 max_x) { + + return max(min(x, max_x), min_x); + } + __device__ int get_x_idx(float16 x, float16 center) { + int i = (x - center) / ${resolution} + 0.5 * ${width}; + return i; + } + __device__ int get_y_idx(float16 y, float16 center) { + int i = (y - center) / ${resolution} + 0.5 * ${height}; + return i; + } + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x == 0 || idx_x == ${width} - 1) { + return false; + } + if (idx_y == 0 || idx_y == ${height} - 1) { + return false; + } + return true; + } + __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { + int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); + int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); + return ${width} * idx_x + idx_y; + } + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ float transform_p(float16 x, float16 y, float16 z, + float16 r0, float16 r1, float16 r2, float16 t) { + return r0 * x + r1 * y + r2 * z + t; + } + __device__ float z_noise(float16 z){ + return ${sensor_noise_factor} * z * z; + } + + __device__ float point_sensor_distance(float16 x, float16 y, float16 z, + float16 sx, float16 sy, float16 sz) { + float d = (x - sx) * (x - sx) + (y - sy) * (y - sy) + (z - sz) * (z - sz); + return d; + } + + __device__ bool is_valid(float16 x, float16 y, float16 z, + float16 sx, float16 sy, float16 sz) { + float d = point_sensor_distance(x, y, z, sx, sy, sz); + float dxy = max(sqrt(x * x + y * y) - ${ramped_height_range_b}, 0.0); + if (d < ${min_valid_distance} * ${min_valid_distance}) { + return false; + } + else if (z - sz > dxy * ${ramped_height_range_a} + ${ramped_height_range_c} || z - sz > ${max_height_range}) { + return false; + } + else { + return true; + } + } + + __device__ float ray_vector(float16 tx, float16 ty, float16 tz, + float16 px, float16 py, float16 pz, + float16& rx, float16& ry, float16& rz){ + float16 vx = px - tx; + float16 vy = py - ty; + float16 vz = pz - tz; + float16 norm = sqrt(vx * vx + vy * vy + vz * vz); + if (norm > 0) { + rx = vx / norm; + ry = vy / norm; + rz = vz / norm; + } + else { + rx = 0; + ry = 0; + rz = 0; + } + return norm; + } + + __device__ float inner_product(float16 x1, float16 y1, float16 z1, + float16 x2, float16 y2, float16 z2) { + + float product = (x1 * x2 + y1 * y2 + z1 * z2); + return product; + } + + """ + ).substitute( + resolution=resolution, + width=width, + height=height, + sensor_noise_factor=sensor_noise_factor, + min_valid_distance=min_valid_distance, + max_height_range=max_height_range, + ramped_height_range_a=ramped_height_range_a, + ramped_height_range_b=ramped_height_range_b, + ramped_height_range_c=ramped_height_range_c, + ) + return util_preamble + + +def add_points_kernel( + resolution, + width, + height, + sensor_noise_factor, + mahalanobis_thresh, + outlier_variance, + wall_num_thresh, + max_ray_length, + cleanup_step, + min_valid_distance, + max_height_range, + cleanup_cos_thresh, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, + enable_edge_shaped=True, + enable_visibility_cleanup=True, +): + add_points_kernel = cp.ElementwiseKernel( + in_params="raw U center_x, raw U center_y, raw U R, raw U t, raw U norm_map", + out_params="raw U p, raw U map, raw T newmap", + preamble=map_utils( + resolution, + width, + height, + sensor_noise_factor, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, + ), + operation=string.Template( + """ + U rx = p[i * 3]; + U ry = p[i * 3 + 1]; + U rz = p[i * 3 + 2]; + U x = transform_p(rx, ry, rz, R[0], R[1], R[2], t[0]); + U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); + U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); + U v = z_noise(rz); + int idx = get_idx(x, y, center_x[0], center_y[0]); + if (is_valid(x, y, z, t[0], t[1], t[2])) { + if (is_inside(idx)) { + U map_h = map[get_map_idx(idx, 0)]; + U map_v = map[get_map_idx(idx, 1)]; + U num_points = newmap[get_map_idx(idx, 4)]; + if (abs(map_h - z) > (map_v * ${mahalanobis_thresh})) { + atomicAdd(&map[get_map_idx(idx, 1)], ${outlier_variance}); + } + else { + if (${enable_edge_shaped} && (num_points > ${wall_num_thresh}) && (z < map_h - map_v * ${mahalanobis_thresh} / num_points)) { + // continue; + } + else { + T new_h = (map_h * v + z * map_v) / (map_v + v); + T new_v = (map_v * v) / (map_v + v); + atomicAdd(&newmap[get_map_idx(idx, 0)], new_h); + atomicAdd(&newmap[get_map_idx(idx, 1)], new_v); + atomicAdd(&newmap[get_map_idx(idx, 2)], 1.0); + // is Valid + map[get_map_idx(idx, 2)] = 1; + // Time layer + map[get_map_idx(idx, 4)] = 0.0; + // Upper bound + map[get_map_idx(idx, 5)] = new_h; + map[get_map_idx(idx, 6)] = 0.0; + } + // visibility cleanup + } + } + } + if (${enable_visibility_cleanup}) { + float16 ray_x, ray_y, ray_z; + float16 ray_length = ray_vector(t[0], t[1], t[2], x, y, z, ray_x, ray_y, ray_z); + ray_length = min(ray_length, (float16)${max_ray_length}); + int last_nidx = -1; + for (float16 s=${ray_step}; s < ray_length; s+=${ray_step}) { + // iterate through ray + U nx = t[0] + ray_x * s; + U ny = t[1] + ray_y * s; + U nz = t[2] + ray_z * s; + int nidx = get_idx(nx, ny, center_x[0], center_y[0]); + if (last_nidx == nidx) {continue;} // Skip if we're still in the same cell + else {last_nidx = nidx;} + if (!is_inside(nidx)) {continue;} + + U nmap_h = map[get_map_idx(nidx, 0)]; + U nmap_v = map[get_map_idx(nidx, 1)]; + U nmap_valid = map[get_map_idx(nidx, 2)]; + // traversability + U nmap_trav = map[get_map_idx(nidx, 3)]; + // Time layer + U non_updated_t = map[get_map_idx(nidx, 4)]; + // upper bound + U nmap_upper = map[get_map_idx(nidx, 5)]; + U nmap_is_upper = map[get_map_idx(nidx, 6)]; + + // If point is close or is farther away than ray length, skip. + float16 d = (x - nx) * (x - nx) + (y - ny) * (y - ny) + (z - nz) * (z - nz); + if (d < 0.1 || !is_valid(x, y, z, t[0], t[1], t[2])) {continue;} + + // If invalid, do upper bound check, then skip + if (nmap_valid < 0.5) { + if (nz < nmap_upper || nmap_is_upper < 0.5) { + map[get_map_idx(nidx, 5)] = nz; + map[get_map_idx(nidx, 6)] = 1.0f; + } + continue; + } + // If updated recently, skip + if (non_updated_t < 0.5) {continue;} + + if (nmap_h > nz + 0.01 - min(nmap_v, 1.0) * 0.05) { + // If ray and norm is vertical, skip + U norm_x = norm_map[get_map_idx(nidx, 0)]; + U norm_y = norm_map[get_map_idx(nidx, 1)]; + U norm_z = norm_map[get_map_idx(nidx, 2)]; + float product = inner_product(ray_x, ray_y, ray_z, norm_x, norm_y, norm_z); + if (fabs(product) < ${cleanup_cos_thresh}) {continue;} + U num_points = newmap[get_map_idx(nidx, 3)]; + if (num_points > ${wall_num_thresh} && non_updated_t < 1.0) {continue;} + + // Finally, this cell is penetrated by the ray. + atomicAdd(&map[get_map_idx(nidx, 2)], -${cleanup_step}/(ray_length / ${max_ray_length})); + atomicAdd(&map[get_map_idx(nidx, 1)], ${outlier_variance}); + // Do upper bound check. + if (nz < nmap_upper || nmap_is_upper < 0.5) { + map[get_map_idx(nidx, 5)] = nz; + map[get_map_idx(nidx, 6)] = 1.0f; + } + } + } + } + p[i * 3]= idx; + p[i * 3 + 1] = is_valid(x, y, z, t[0], t[1], t[2]); + p[i * 3 + 2] = is_inside(idx); + """ + ).substitute( + mahalanobis_thresh=mahalanobis_thresh, + outlier_variance=outlier_variance, + wall_num_thresh=wall_num_thresh, + ray_step=resolution / 2 ** 0.5, + max_ray_length=max_ray_length, + cleanup_step=cleanup_step, + cleanup_cos_thresh=cleanup_cos_thresh, + enable_edge_shaped=int(enable_edge_shaped), + enable_visibility_cleanup=int(enable_visibility_cleanup), + ), + name="add_points_kernel", + ) + return add_points_kernel + + +def error_counting_kernel( + resolution, + width, + height, + sensor_noise_factor, + mahalanobis_thresh, + outlier_variance, + traversability_inlier, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, +): + error_counting_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U p, raw U center_x, raw U center_y, raw U R, raw U t", + out_params="raw U newmap, raw T error, raw T error_cnt", + preamble=map_utils( + resolution, + width, + height, + sensor_noise_factor, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, + ), + operation=string.Template( + """ + U rx = p[i * 3]; + U ry = p[i * 3 + 1]; + U rz = p[i * 3 + 2]; + U x = transform_p(rx, ry, rz, R[0], R[1], R[2], t[0]); + U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); + U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); + U v = z_noise(rz); + // if (!is_valid(z, t[2])) {return;} + if (!is_valid(x, y, z, t[0], t[1], t[2])) {return;} + // if ((x - t[0]) * (x - t[0]) + (y - t[1]) * (y - t[1]) + (z - t[2]) * (z - t[2]) < 0.5) {return;} + int idx = get_idx(x, y, center_x[0], center_y[0]); + if (!is_inside(idx)) { + return; + } + U map_h = map[get_map_idx(idx, 0)]; + U map_v = map[get_map_idx(idx, 1)]; + U map_valid = map[get_map_idx(idx, 2)]; + U map_t = map[get_map_idx(idx, 3)]; + if (map_valid > 0.5 && (abs(map_h - z) < (map_v * ${mahalanobis_thresh})) + && map_v < ${outlier_variance} / 2.0 + && map_t > ${traversability_inlier}) { + T e = z - map_h; + atomicAdd(&error[0], e); + atomicAdd(&error_cnt[0], 1); + atomicAdd(&newmap[get_map_idx(idx, 3)], 1.0); + } + atomicAdd(&newmap[get_map_idx(idx, 4)], 1.0); + """ + ).substitute( + mahalanobis_thresh=mahalanobis_thresh, + outlier_variance=outlier_variance, + traversability_inlier=traversability_inlier, + ), + name="error_counting_kernel", + ) + return error_counting_kernel + + +def average_map_kernel(width, height, max_variance, initial_variance): + average_map_kernel = cp.ElementwiseKernel( + in_params="raw U newmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U h = map[get_map_idx(i, 0)]; + U v = map[get_map_idx(i, 1)]; + U valid = map[get_map_idx(i, 2)]; + U new_h = newmap[get_map_idx(i, 0)]; + U new_v = newmap[get_map_idx(i, 1)]; + U new_cnt = newmap[get_map_idx(i, 2)]; + if (new_cnt > 0) { + if (new_v / new_cnt > ${max_variance}) { + map[get_map_idx(i, 0)] = 0; + map[get_map_idx(i, 1)] = ${initial_variance}; + map[get_map_idx(i, 2)] = 0; + } + else { + map[get_map_idx(i, 0)] = new_h / new_cnt; + map[get_map_idx(i, 1)] = new_v / new_cnt; + map[get_map_idx(i, 2)] = 1; + } + } + if (valid < 0.5) { + map[get_map_idx(i, 0)] = 0; + map[get_map_idx(i, 1)] = ${initial_variance}; + map[get_map_idx(i, 2)] = 0; + } + """ + ).substitute(max_variance=max_variance, initial_variance=initial_variance), + name="average_map_kernel", + ) + return average_map_kernel + + +def dilation_filter_kernel(width, height, dilation_size): + dilation_filter_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U mask", + out_params="raw U newmap, raw U newmask", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { + const int layer = ${width} * ${height}; + const int relative_idx = idx + ${width} * dy + dx; + return layer * layer_n + relative_idx; + } + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x <= 0 || idx_x >= ${width} - 1) { + return false; + } + if (idx_y <= 0 || idx_y >= ${height} - 1) { + return false; + } + return true; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U h = map[get_map_idx(i, 0)]; + U valid = mask[get_map_idx(i, 0)]; + newmap[get_map_idx(i, 0)] = h; + if (valid < 0.5) { + U distance = 100; + U near_value = 0; + for (int dy = -${dilation_size}; dy <= ${dilation_size}; dy++) { + for (int dx = -${dilation_size}; dx <= ${dilation_size}; dx++) { + int idx = get_relative_map_idx(i, dx, dy, 0); + if (!is_inside(idx)) {continue;} + U valid = mask[idx]; + if(valid > 0.5 && dx + dy < distance) { + distance = dx + dy; + near_value = map[idx]; + } + } + } + if(distance < 100) { + newmap[get_map_idx(i, 0)] = near_value; + newmask[get_map_idx(i, 0)] = 1.0; + } + } + """ + ).substitute(dilation_size=dilation_size), + name="dilation_filter_kernel", + ) + return dilation_filter_kernel + + +def normal_filter_kernel(width, height, resolution): + normal_filter_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U mask", + out_params="raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { + const int layer = ${width} * ${height}; + const int relative_idx = idx + ${width} * dy + dx; + return layer * layer_n + relative_idx; + } + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x <= 0 || idx_x >= ${width} - 1) { + return false; + } + if (idx_y <= 0 || idx_y >= ${height} - 1) { + return false; + } + return true; + } + __device__ float resolution() { + return ${resolution}; + } + """ + ).substitute(width=width, height=height, resolution=resolution), + operation=string.Template( + """ + U h = map[get_map_idx(i, 0)]; + U valid = mask[get_map_idx(i, 0)]; + if (valid > 0.5) { + int idx_x = get_relative_map_idx(i, 1, 0, 0); + int idx_y = get_relative_map_idx(i, 0, 1, 0); + if (!is_inside(idx_x) || !is_inside(idx_y)) { return; } + float dzdx = (map[idx_x] - h); + float dzdy = (map[idx_y] - h); + float nx = -dzdy / resolution(); + float ny = -dzdx / resolution(); + float nz = 1; + float norm = sqrt((nx * nx) + (ny * ny) + 1); + newmap[get_map_idx(i, 0)] = nx / norm; + newmap[get_map_idx(i, 1)] = ny / norm; + newmap[get_map_idx(i, 2)] = nz / norm; + } + """ + ).substitute(), + name="normal_filter_kernel", + ) + return normal_filter_kernel + + +def polygon_mask_kernel(width, height, resolution): + polygon_mask_kernel = cp.ElementwiseKernel( + in_params="raw U polygon, raw U center_x, raw U center_y, raw int16 polygon_n, raw U polygon_bbox", + out_params="raw U mask", + preamble=string.Template( + """ + __device__ struct Point + { + int x; + int y; + }; + // Given three colinear points p, q, r, the function checks if + // point q lies on line segment 'pr' + __device__ bool onSegment(Point p, Point q, Point r) + { + if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) && + q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y)) + return true; + return false; + } + // To find orientation of ordered triplet (p, q, r). + // The function returns following values + // 0 --> p, q and r are colinear + // 1 --> Clockwise + // 2 --> Counterclockwise + __device__ int orientation(Point p, Point q, Point r) + { + int val = (q.y - p.y) * (r.x - q.x) - + (q.x - p.x) * (r.y - q.y); + if (val == 0) return 0; // colinear + return (val > 0)? 1: 2; // clock or counterclock wise + } + // The function that returns true if line segment 'p1q1' + // and 'p2q2' intersect. + __device__ bool doIntersect(Point p1, Point q1, Point p2, Point q2) + { + // Find the four orientations needed for general and + // special cases + int o1 = orientation(p1, q1, p2); + int o2 = orientation(p1, q1, q2); + int o3 = orientation(p2, q2, p1); + int o4 = orientation(p2, q2, q1); + // General case + if (o1 != o2 && o3 != o4) + return true; + // Special Cases + // p1, q1 and p2 are colinear and p2 lies on segment p1q1 + if (o1 == 0 && onSegment(p1, p2, q1)) return true; + // p1, q1 and p2 are colinear and q2 lies on segment p1q1 + if (o2 == 0 && onSegment(p1, q2, q1)) return true; + // p2, q2 and p1 are colinear and p1 lies on segment p2q2 + if (o3 == 0 && onSegment(p2, p1, q2)) return true; + // p2, q2 and q1 are colinear and q1 lies on segment p2q2 + if (o4 == 0 && onSegment(p2, q1, q2)) return true; + return false; // Doesn't fall in any of the above cases + } + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ int get_idx_x(int idx){ + int idx_x = idx / ${width}; + return idx_x; + } + + __device__ int get_idx_y(int idx){ + int idx_y = idx % ${width}; + return idx_y; + } + + __device__ float16 clamp(float16 x, float16 min_x, float16 max_x) { + + return max(min(x, max_x), min_x); + } + __device__ float16 round(float16 x) { + return (int)x + (int)(2 * (x - (int)x)); + } + __device__ int get_x_idx(float16 x, float16 center) { + const float resolution = ${resolution}; + const float width = ${width}; + int i = (x - center) / resolution + 0.5 * width; + return i; + } + __device__ int get_y_idx(float16 y, float16 center) { + const float resolution = ${resolution}; + const float height = ${height}; + int i = (y - center) / resolution + 0.5 * height; + return i; + } + __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { + int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); + int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); + return ${width} * idx_x + idx_y; + } + + """ + ).substitute(width=width, height=height, resolution=resolution), + operation=string.Template( + """ + // Point p = {get_idx_x(i, center_x[0]), get_idx_y(i, center_y[0])}; + Point p = {get_idx_x(i), get_idx_y(i)}; + Point extreme = {100000, p.y}; + int bbox_min_idx = get_idx(polygon_bbox[0], polygon_bbox[1], center_x[0], center_y[0]); + int bbox_max_idx = get_idx(polygon_bbox[2], polygon_bbox[3], center_x[0], center_y[0]); + Point bmin = {get_idx_x(bbox_min_idx), get_idx_y(bbox_min_idx)}; + Point bmax = {get_idx_x(bbox_max_idx), get_idx_y(bbox_max_idx)}; + if (p.x < bmin.x || p.x > bmax.x || p.y < bmin.y || p.y > bmax.y){ + mask[i] = 0; + return; + } + else { + int intersect_cnt = 0; + for (int j = 0; j < polygon_n[0]; j++) { + Point p1, p2; + int i1 = get_idx(polygon[j * 2 + 0], polygon[j * 2 + 1], center_x[0], center_y[0]); + p1.x = get_idx_x(i1); + p1.y = get_idx_y(i1); + int j2 = (j + 1) % polygon_n[0]; + int i2 = get_idx(polygon[j2 * 2 + 0], polygon[j2 * 2 + 1], center_x[0], center_y[0]); + p2.x = get_idx_x(i2); + p2.y = get_idx_y(i2); + if (doIntersect(p1, p2, p, extreme)) + { + // If the point 'p' is colinear with line segment 'i-next', + // then check if it lies on segment. If it lies, return true, + // otherwise false + if (orientation(p1, p, p2) == 0) { + if (onSegment(p1, p, p2)){ + mask[i] = 1; + return; + } + } + else if(((p1.y <= p.y) && (p2.y > p.y)) || ((p1.y > p.y) && (p2.y <= p.y))){ + intersect_cnt++; + } + } + } + if (intersect_cnt % 2 == 0) { mask[i] = 0; } + else { mask[i] = 1; } + } + """ + ).substitute(a=1), + name="polygon_mask_kernel", + ) + return polygon_mask_kernel + + + +def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_collision): + """ + This function calculates the correspondence between the image and the map. + It takes in the resolution, width, height, and tolerance_z_collision as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _image_to_map_correspondence_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U K, raw U D, raw U image_height, raw U image_width, raw U center", + out_params="raw U uv_correspondence, raw B valid_correspondence", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ bool is_inside_map(int x, int y) { + return (x >= 0 && y >= 0 && x<${width} && y<${height}); + } + __device__ float get_l2_distance(int x0, int y0, int x1, int y1) { + float dx = x0-x1; + float dy = y0-y1; + return sqrt( dx*dx + dy*dy); + } + """ + ).substitute(width=width, height=height, resolution=resolution), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + + // return if gridcell has no valid height + if (map[get_map_idx(i, 2)] != 1){ + return; + } + + // get current cell position + int y0 = i % ${width}; + int x0 = i / ${width}; + + // gridcell 3D point in worldframe TODO reverse x and y + float p1 = (x0-(${width}/2)) * ${resolution} + center[0]; + float p2 = (y0-(${height}/2)) * ${resolution} + center[1]; + float p3 = map[cell_idx] + center[2]; + + // reproject 3D point into image plane + float u = p1 * P[0] + p2 * P[1] + p3 * P[2] + P[3]; + float v = p1 * P[4] + p2 * P[5] + p3 * P[6] + P[7]; + float d = p1 * P[8] + p2 * P[9] + p3 * P[10] + P[11]; + + // filter point behind image plane + if (d <= 0) { + return; + } + u = u/d; + v = v/d; + + // Check if D is all zeros + bool is_D_zero = (D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == 0 && D[4] == 0); + + // Apply undistortion using distortion matrix D if not all zeros + if (!is_D_zero) { + float k1 = D[0]; + float k2 = D[1]; + float p1 = D[2]; + float p2 = D[3]; + float k3 = D[4]; + float fx = K[0]; + float fy = K[4]; + float cx = K[2]; + float cy = K[5]; + float x = (u - cx) / fx; + float y = (v - cy) / fy; + float r2 = x * x + y * y; + float radial_distortion = 1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2; + float u_corrected = x * radial_distortion + 2 * p1 * x * y + p2 * (r2 + 2 * x * x); + float v_corrected = y * radial_distortion + 2 * p2 * x * y + p1 * (r2 + 2 * y * y); + u = fx * u_corrected + cx; + v = fy * v_corrected + cy; + } + + // filter point next to image plane + if ((u < 0) || (v < 0) || (u >= image_width) || (v >= image_height)){ + return; + } + + int y0_c = y0; + int x0_c = x0; + float total_dis = get_l2_distance(x0_c, y0_c, x1,y1); + float z0 = map[cell_idx]; + float delta_z = z1-z0; + + + // bresenham algorithm to iterate over cells in line between camera center and current gridmap cell + // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm + int dx = abs(x1-x0); + int sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0); + int sy = y0 < y1 ? 1 : -1; + int error = dx + dy; + + bool is_valid = true; + + // iterate over all cells along line + while (1){ + // assumption we do not need to check the height for camera center cell + if (x0 == x1 && y0 == y1){ + break; + } + + // check if height is invalid + if (is_inside_map(x0,y0)){ + int idx = y0 + (x0 * ${width}); + if (map[get_map_idx(idx, 2)]){ + float dis = get_l2_distance(x0_c, y0_c, x0, y0); + float rayheight = z0 + ( dis / total_dis * delta_z); + if ( map[idx] - ${tolerance_z_collision} > rayheight){ + is_valid = false; + break; + } + } + } + + + // computation of next gridcell index in line + int e2 = 2 * error; + if (e2 >= dy){ + if(x0 == x1){ + break; + } + error = error + dy; + x0 = x0 + sx; + } + if (e2 <= dx){ + if (y0 == y1){ + break; + } + error = error + dx; + y0 = y0 + sy; + } + } + + // mark the correspondence + uv_correspondence[get_map_idx(i, 0)] = u; + uv_correspondence[get_map_idx(i, 1)] = v; + valid_correspondence[get_map_idx(i, 0)] = is_valid; + """ + ).substitute(height=height, width=width, resolution=resolution, tolerance_z_collision=tolerance_z_collision), + name="image_to_map_correspondence_kernel", + ) + return _image_to_map_correspondence_kernel + + +def average_correspondences_to_map_kernel(width, height): + """ + This function calculates the average correspondences to the map. + It takes in the width and height as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _average_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + new_sem_map[get_map_idx(i, map_idx)] = image_mono[idx]; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + + """ + ).substitute(), + name="average_correspondences_to_map_kernel", + ) + return _average_correspondences_to_map_kernel + + +def exponential_correspondences_to_map_kernel(width, height, alpha): + """ + This function calculates the exponential correspondences to the map. + It takes in the width, height, and alpha as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _exponential_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)] * (1-${alpha}) + ${alpha} * image_mono[idx]; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + + """ + ).substitute(alpha=alpha), + name="exponential_correspondences_to_map_kernel", + ) + return _exponential_correspondences_to_map_kernel + + +def color_correspondences_to_map_kernel(width, height): + """ + This function calculates the color correspondences to the map. + It takes in the width and height as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _color_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + + int idx_red = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + int idx_green = image_width * image_height + idx_red; + int idx_blue = image_width * image_height * 2 + idx_red; + + unsigned int r = image_rgb[idx_red]; + unsigned int g = image_rgb[idx_green]; + unsigned int b = image_rgb[idx_blue]; + + unsigned int rgb = (r<<16) + (g << 8) + b; + float rgb_ = __uint_as_float(rgb); + new_sem_map[get_map_idx(i, map_idx)] = rgb_; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + """ + ).substitute(), + name="color_correspondences_to_map_kernel", + ) + return _color_correspondences_to_map_kernel diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/map_initializer.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/map_initializer.py new file mode 100644 index 00000000..0139ea76 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/map_initializer.py @@ -0,0 +1,80 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +from scipy.interpolate import griddata +import numpy as np +import cupy as cp + + +class MapInitializer(object): + def __init__(self, initial_variance, new_variance, xp=np, method="points"): + self.methods = ["points"] + assert method in self.methods, "method should be chosen from {}".format(self.methods) + self.method = method + self.xp = xp + self.initial_variance = initial_variance + self.new_variance = new_variance + + def __call__(self, *args, **kwargs): + if self.method == "points": + self.points_initializer(*args, **kwargs) + else: + return + + def points_initializer(self, elevation_map, points, method="linear"): + """Initialize the map using interpolation between given points + + Args: + elevation_map (cupy._core.core.ndarray): elevation_map data. + points (cupy._core.core.ndarray): points used to interpolate. + method (str): method for interpolation. (nearest, linear, cubic) + + """ + # points from existing map. + points_idx = self.xp.where(elevation_map[2] > 0.5) + values = elevation_map[0, points_idx[0], points_idx[1]] + + # Add external points for interpolation. + points_idx = self.xp.stack(points_idx).T + points_idx = self.xp.vstack([points_idx, points[:, :2]]) + values = self.xp.hstack([values, points[:, 2]]) + + assert points_idx.shape[0] > 3, "Initialization points must be more than 3." + + # Interpolation using griddata function. + w = elevation_map.shape[1] + h = elevation_map.shape[2] + grid_x, grid_y = np.mgrid[0:w, 0:h] + if self.xp == cp: + points_idx = cp.asnumpy(points_idx) + values = cp.asnumpy(values) + interpolated = griddata(points_idx, values, (grid_x, grid_y), method=method) + if self.xp == cp: + interpolated = cp.asarray(interpolated) + + # Update elevation map. + elevation_map[0] = self.xp.nan_to_num(interpolated) + elevation_map[1] = self.xp.where( + self.xp.invert(self.xp.isnan(interpolated)), self.new_variance, self.initial_variance + ) + elevation_map[2] = self.xp.where(self.xp.invert(self.xp.isnan(interpolated)), 1.0, 0.0) + return + + +if __name__ == "__main__": + initializer = MapInitializer(100, 10, method="points", xp=cp) + m = np.zeros((4, 10, 10)) + m[0, 0:5, 2:5] = 0.3 + m[2, 0:5, 2:5] = 1.0 + np.set_printoptions(threshold=100) + print(m[0]) + print(m[1]) + print(m[2]) + points = cp.array([[0, 0, 0.2], [8, 0, 0.2], [6, 9, 0.2]]) + # [3, 3, 0.2]]) + m = cp.asarray(m) + initializer(m, points, method="cubic") + print(m[0]) + print(m[1]) + print(m[2]) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/parameter.py new file mode 100644 index 00000000..5fc3c110 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/parameter.py @@ -0,0 +1,300 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +from dataclasses import dataclass, field +import pickle +import numpy as np +from simple_parsing.helpers import Serializable +from dataclasses import field +from typing import Tuple + + +@dataclass +class Parameter(Serializable): + """ + This class holds the parameters for the elevation mapping algorithm. + + Attributes: + resolution: The resolution in meters. + (Default: ``0.04``) + subscriber_cfg: The configuration for the subscriber. + (Default: ``{ "front_cam": { "channels": ["rgb", "person"], "topic_name": "/elevation_mapping/pointcloud_semantic", "data_type": "pointcloud", } }``) + additional_layers: The additional layers for the map. + (Default: ``["color"]``) + fusion_algorithms: The list of fusion algorithms. + (Default: ``[ "image_color", "image_exponential", "pointcloud_average", "pointcloud_bayesian_inference", "pointcloud_class_average", "pointcloud_class_bayesian", "pointcloud_class_max", "pointcloud_color", ]``) + pointcloud_channel_fusions: The fusion for pointcloud channels. + (Default: ``{"rgb": "color", "default": "class_average"}``) + image_channel_fusions: The fusion for image channels. + (Default: ``{"rgb": "color", "default": "exponential"}``) + data_type: The data type for the map. + (Default: ``np.float32``) + average_weight: The weight for the average fusion. + (Default: ``0.5``) + map_length: The map's size in meters. + (Default: ``8.0``) + sensor_noise_factor: The point's noise is sensor_noise_factor*z^2 (z is distance from sensor). + (Default: ``0.05``) + mahalanobis_thresh: Points outside this distance is outlier. + (Default: ``2.0``) + outlier_variance: If point is outlier, add this value to the cell. + (Default: ``0.01``) + drift_compensation_variance_inlier: Cells under this value is used for drift compensation. + (Default: ``0.1``) + time_variance: Add this value when update_variance is called. + (Default: ``0.01``) + time_interval: Time layer is updated with this interval. + (Default: ``0.1``) + max_variance: The maximum variance for each cell. + (Default: ``1.0``) + dilation_size: The dilation filter size before traversability filter. + (Default: ``2``) + dilation_size_initialize: The dilation size after the init. + (Default: ``10``) + drift_compensation_alpha: The drift compensation alpha for smoother update of drift compensation. + (Default: ``1.0``) + traversability_inlier: Cells with higher traversability are used for drift compensation. + (Default: ``0.1``) + wall_num_thresh: If there are more points than this value, only higher points than the current height are used to make the wall more sharp. + (Default: ``100``) + min_height_drift_cnt: Drift compensation only happens if the valid cells are more than this number. + (Default: ``100``) + max_ray_length: The maximum length for ray tracing. + (Default: ``2.0``) + cleanup_step: Substitute this value from validity layer at visibility cleanup. + (Default: ``0.01``) + cleanup_cos_thresh: Substitute this value from validity layer at visibility cleanup. + (Default: ``0.5``) + min_valid_distance: Points with shorter distance will be filtered out. + (Default: ``0.3``) + max_height_range: Points higher than this value from sensor will be filtered out to disable ceiling. + (Default: ``1.0``) + ramped_height_range_a: If z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + (Default: ``0.3``) + ramped_height_range_b: If z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + (Default: ``1.0``) + ramped_height_range_c: If z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + (Default: ``0.2``) + safe_thresh: If traversability is smaller, it is counted as unsafe cell. + (Default: ``0.5``) + safe_min_thresh: Polygon is unsafe if there exists lower traversability than this. + (Default: ``0.5``) + max_unsafe_n: If the number of cells under safe_thresh exceeds this value, polygon is unsafe. + (Default: ``20``) + checker_layer: Layer used for checking safety. + (Default: ``"traversability"``) + min_filter_size: The minimum size for the filter. + (Default: ``5``) + min_filter_iteration: The minimum number of iterations for the filter. + (Default: ``3``) + max_drift: The maximum drift for the compensation. + (Default: ``0.10``) + overlap_clear_range_xy: XY range [m] for clearing overlapped area. This defines the valid area for overlap clearance. (used for multi floor setting) + (Default: ``4.0``) + overlap_clear_range_z: Z range [m] for clearing overlapped area. Cells outside this range will be cleared. (used for multi floor setting) + (Default: ``2.0``) + enable_edge_sharpen: Enable edge sharpening. + (Default: ``True``) + enable_drift_compensation: Enable drift compensation. + (Default: ``True``) + enable_visibility_cleanup: Enable visibility cleanup. + (Default: ``True``) + enable_overlap_clearance: Enable overlap clearance. + (Default: ``True``) + use_only_above_for_upper_bound: Use only above for upper bound. + (Default: ``True``) + use_chainer: Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. Pytorch requires ~2GB more GPU memory compared to chainer but runs faster. + (Default: ``True``) + position_noise_thresh: If the position change is bigger than this value, the drift compensation happens. + (Default: ``0.1``) + orientation_noise_thresh: If the orientation change is bigger than this value, the drift compensation happens. + (Default: ``0.1``) + plugin_config_file: Configuration file for the plugin. + (Default: ``"config/plugin_config.yaml"``) + weight_file: Weight file for traversability filter. + (Default: ``"config/weights.dat"``) + initial_variance: Initial variance for each cell. + (Default: ``10.0``) + initialized_variance: Initialized variance for each cell. + (Default: ``10.0``) + w1: Weights for the first layer. + (Default: ``np.zeros((4, 1, 3, 3))``) + w2: Weights for the second layer. + (Default: ``np.zeros((4, 1, 3, 3))``) + w3: Weights for the third layer. + (Default: ``np.zeros((4, 1, 3, 3))``) + w_out: Weights for the output layer. + (Default: ``np.zeros((1, 12, 1, 1))``) + true_map_length: True length of the map. + (Default: ``None``) + cell_n: Number of cells in the map. + (Default: ``None``) + true_cell_n: True number of cells in the map. + (Default: ``None``) + + """ + resolution: float = 0.04 # resolution in m. + subscriber_cfg: dict = field( + default_factory=lambda: { + "front_cam": { + "channels": ["rgb", "person"], + "topic_name": "/elevation_mapping/pointcloud_semantic", + "data_type": "pointcloud", + } + } + ) # configuration for the subscriber + additional_layers: list = field(default_factory=lambda: ["color"]) # additional layers for the map + fusion_algorithms: list = field( + default_factory=lambda: [ + "image_color", + "image_exponential", + "pointcloud_average", + "pointcloud_bayesian_inference", + "pointcloud_class_average", + "pointcloud_class_bayesian", + "pointcloud_class_max", + "pointcloud_color", + ] + ) # list of fusion algorithms + pointcloud_channel_fusions: dict = field(default_factory=lambda: {"rgb": "color", "default": "class_average"}) # fusion for pointcloud channels + image_channel_fusions: dict = field(default_factory=lambda: {"rgb": "color", "default": "exponential"}) # fusion for image channels + data_type: str = np.float32 # data type for the map + average_weight: float = 0.5 # weight for the average fusion + + map_length: float = 8.0 # map's size in m. + sensor_noise_factor: float = 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). + mahalanobis_thresh: float = 2.0 # points outside this distance is outlier. + outlier_variance: float = 0.01 # if point is outlier, add this value to the cell. + drift_compensation_variance_inlier: float = 0.1 # cells under this value is used for drift compensation. + time_variance: float = 0.01 # add this value when update_variance is called. + time_interval: float = 0.1 # Time layer is updated with this interval. + + max_variance: float = 1.0 # maximum variance for each cell. + dilation_size: float = 2 # dilation filter size before traversability filter. + dilation_size_initialize: float = 10 # dilation size after the init. + drift_compensation_alpha: float = 1.0 # drift compensation alpha for smoother update of drift compensation. + + traversability_inlier: float = 0.1 # cells with higher traversability are used for drift compensation. + wall_num_thresh: float = 100 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. + min_height_drift_cnt: float = 100 # drift compensation only happens if the valid cells are more than this number. + + max_ray_length: float = 2.0 # maximum length for ray tracing. + cleanup_step: float = 0.01 # substitute this value from validity layer at visibility cleanup. + cleanup_cos_thresh: float = 0.5 # substitute this value from validity layer at visibility cleanup. + min_valid_distance: float = 0.3 # points with shorter distance will be filtered out. + max_height_range: float = 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. + ramped_height_range_a: float = 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_b: float = 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_c: float = 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + + safe_thresh: float = 0.5 # if traversability is smaller, it is counted as unsafe cell. + safe_min_thresh: float = 0.5 # polygon is unsafe if there exists lower traversability than this. + max_unsafe_n: int = 20 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + checker_layer: str = "traversability" # layer used for checking safety + + min_filter_size: int = 5 # minimum size for the filter + min_filter_iteration: int = 3 # minimum number of iterations for the filter + + max_drift: float = 0.10 # maximum drift for the compensation + + overlap_clear_range_xy: float = 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) + overlap_clear_range_z: float = 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + + enable_edge_sharpen: bool = True # enable edge sharpening + enable_drift_compensation: bool = True # enable drift compensation + enable_visibility_cleanup: bool = True # enable visibility cleanup + enable_overlap_clearance: bool = True # enable overlap clearance + use_only_above_for_upper_bound: bool = True # use only above for upper bound + use_chainer: bool = True # use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. + position_noise_thresh: float = 0.1 # if the position change is bigger than this value, the drift compensation happens. + orientation_noise_thresh: float = 0.1 # if the orientation change is bigger than this value, the drift compensation happens. + + plugin_config_file: str = "config/plugin_config.yaml" # configuration file for the plugin + weight_file: str = "config/weights.dat" # weight file for traversability filter + + initial_variance: float = 10.0 # initial variance for each cell. + initialized_variance: float = 10.0 # initialized variance for each cell. + w1: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the first layer + w2: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the second layer + w3: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the third layer + w_out: np.ndarray = field(default_factory=lambda: np.zeros((1, 12, 1, 1))) # weights for the output layer + + # # not configurable params + true_map_length: float = None # true length of the map + cell_n: int = None # number of cells in the map + true_cell_n: int = None # true number of cells in the map + + def load_weights(self, filename): + """ + Load weights from a file into the model's parameters. + + Args: + filename (str): The path to the file containing the weights. + """ + with open(filename, "rb") as file: + weights = pickle.load(file) + self.w1 = weights["conv1.weight"] + self.w2 = weights["conv2.weight"] + self.w3 = weights["conv3.weight"] + self.w_out = weights["conv_final.weight"] + + def get_names(self): + """ + Get the names of the parameters. + + Returns: + list: A list of parameter names. + """ + return list(self.__annotations__.keys()) + + def get_types(self): + """ + Get the types of the parameters. + + Returns: + list: A list of parameter types. + """ + return [v.__name__ for v in self.__annotations__.values()] + + def set_value(self, name, value): + """ + Set the value of a parameter. + + Args: + name (str): The name of the parameter. + value (any): The new value for the parameter. + """ + setattr(self, name, value) + + def get_value(self, name): + """ + Get the value of a parameter. + + Args: + name (str): The name of the parameter. + + Returns: + any: The value of the parameter. + """ + return getattr(self, name) + + def update(self): + """ + Update the parameters related to the map size and resolution. + """ + # +2 is a border for outside map + self.cell_n = int(round(self.map_length / self.resolution)) + 2 + self.true_cell_n = round(self.map_length / self.resolution) + self.true_map_length = self.true_cell_n * self.resolution + + +if __name__ == "__main__": + param = Parameter() + print(param) + print(param.resolution) + param.set_value("resolution", 0.1) + print(param.resolution) + + print("names ", param.get_names()) + print("types ", param.get_types()) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/__init__.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/erosion.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/erosion.py new file mode 100644 index 00000000..7b0211df --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/erosion.py @@ -0,0 +1,113 @@ +# +# Copyright (c) 2024, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cv2 as cv +import cupy as cp +import numpy as np + +from typing import List + +from .plugin_manager import PluginBase + + +class Erosion(PluginBase): + """ + This class is used for applying erosion to an elevation map or specific layers within it. + Erosion is a morphological operation that is used to remove small-scale details from a binary image. + + Args: + kernel_size (int): Size of the erosion kernel. Default is 3, which means a 3x3 square kernel. + iterations (int): Number of times erosion is applied. Default is 1. + **kwargs (): Additional keyword arguments. + """ + + def __init__( + self, + input_layer_name="traversability", + kernel_size: int = 3, + iterations: int = 1, + reverse: bool = False, + default_layer_name: str = "traversability", + **kwargs, + ): + super().__init__() + self.input_layer_name = input_layer_name + self.kernel_size = kernel_size + self.iterations = iterations + self.reverse = reverse + self.default_layer_name = default_layer_name + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], + *args, + ) -> cp.ndarray: + """ + Applies erosion to the given elevation map. + + Args: + elevation_map (cupy._core.core.ndarray): The elevation map to be eroded. + layer_names (List[str]): Names of the layers in the elevation map. + plugin_layers (cupy._core.core.ndarray): Layers provided by other plugins. + plugin_layer_names (List[str]): Names of the layers provided by other plugins. + *args (): Additional arguments. + + Returns: + cupy._core.core.ndarray: The eroded elevation map. + """ + # Convert the elevation map to a format suitable for erosion (if necessary) + layer_data = self.get_layer_data( + elevation_map, + layer_names, + plugin_layers, + plugin_layer_names, + semantic_map, + semantic_layer_names, + self.input_layer_name, + ) + if layer_data is None: + print(f"No layers are found, using {self.default_layer_name}!") + layer_data = self.get_layer_data( + elevation_map, + layer_names, + plugin_layers, + plugin_layer_names, + semantic_map, + semantic_layer_names, + self.default_layer_name, + ) + if layer_data is None: + print(f"No layers are found, using traversability!") + layer_data = self.get_layer_data( + elevation_map, + layer_names, + plugin_layers, + plugin_layer_names, + semantic_map, + semantic_layer_names, + "traversability", + ) + layer_np = cp.asnumpy(layer_data) + + # Define the erosion kernel + kernel = np.ones((self.kernel_size, self.kernel_size), np.uint8) + + if self.reverse: + layer_np = 1 - layer_np + # Apply erosion + layer_min = float(layer_np.min()) + layer_max = float(layer_np.max()) + layer_np_normalized = ((layer_np - layer_min) * 255 / (layer_max - layer_min)).astype("uint8") + eroded_map_np = cv.erode(layer_np_normalized, kernel, iterations=self.iterations) + eroded_map_np = eroded_map_np.astype(np.float32) * (layer_max - layer_min) / 255 + layer_min + if self.reverse: + eroded_map_np = 1 - eroded_map_np + + # Convert back to cupy array and return + return cp.asarray(eroded_map_np) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/features_pca.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/features_pca.py new file mode 100644 index 00000000..94f88823 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/features_pca.py @@ -0,0 +1,96 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +from typing import List +import re + +from elevation_mapping_cupy.plugins.plugin_manager import PluginBase +from sklearn.decomposition import PCA + + +class FeaturesPca(PluginBase): + """This is a filter to create a pca layer of the semantic features in the map. + + Args: + cell_n (int): width and height of the elevation map. + classes (ruamel.yaml.comments.CommentedSeq): + **kwargs (): + """ + + def __init__( + self, cell_n: int = 100, process_layer_names: List[str] = [], **kwargs, + ): + super().__init__() + self.process_layer_names = process_layer_names + + def get_layer_indices(self, layer_names: List[str]) -> List[int]: + """ Get the indices of the layers that are to be processed using regular expressions. + Args: + layer_names (List[str]): List of layer names. + Returns: + List[int]: List of layer indices. + """ + indices = [] + for i, layer_name in enumerate(layer_names): + if any(re.match(pattern, layer_name) for pattern in self.process_layer_names): + indices.append(i) + return indices + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], + *args, + ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): + *args (): + + Returns: + cupy._core.core.ndarray: + """ + # get indices of all layers that contain semantic features information + data = [] + for m, layer_names in zip( + [elevation_map, plugin_layers, semantic_map], [layer_names, plugin_layer_names, semantic_layer_names] + ): + layer_indices = self.get_layer_indices(layer_names) + if len(layer_indices) > 0: + n_c = m[layer_indices].shape[1] + data_i = cp.reshape(m[layer_indices], (len(layer_indices), -1)).T.get() + data_i = np.clip(data_i, -1, 1) + data.append(data_i) + if len(data) > 0: + data = np.concatenate(data, axis=1) + # check which has the highest value + n_components = 3 + pca = PCA(n_components=n_components).fit(data) + pca_descriptors = pca.transform(data) + img_pca = pca_descriptors.reshape(n_c, n_c, n_components) + comp = img_pca # [:, :, -3:] + comp_min = comp.min(axis=(0, 1)) + comp_max = comp.max(axis=(0, 1)) + if (comp_max - comp_min).any() != 0: + comp_img = np.divide((comp - comp_min), (comp_max - comp_min)) + pca_map = (comp_img * 255).astype(np.uint8) + r = np.asarray(pca_map[:, :, 0], dtype=np.uint32) + g = np.asarray(pca_map[:, :, 1], dtype=np.uint32) + b = np.asarray(pca_map[:, :, 2], dtype=np.uint32) + rgb_arr = np.array((r << 16) | (g << 8) | (b << 0), dtype=np.uint32) + rgb_arr.dtype = np.float32 + return cp.asarray(rgb_arr) + else: + return cp.zeros_like(elevation_map[0]) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/inpainting.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/inpainting.py new file mode 100644 index 00000000..3e926b00 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/inpainting.py @@ -0,0 +1,63 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +from typing import List +import cupyx.scipy.ndimage as ndimage +import numpy as np +import cv2 as cv + +from .plugin_manager import PluginBase + + +class Inpainting(PluginBase): + """ + This class is used for inpainting, a process of reconstructing lost or deteriorated parts of images and videos. + + Args: + cell_n (int): The number of cells. Default is 100. + method (str): The inpainting method. Options are 'telea' or 'ns' (Navier-Stokes). Default is 'telea'. + **kwargs (): Additional keyword arguments. + """ + + def __init__(self, cell_n: int = 100, method: str = "telea", **kwargs): + super().__init__() + if method == "telea": + self.method = cv.INPAINT_TELEA + elif method == "ns": # Navier-Stokes + self.method = cv.INPAINT_NS + else: # default method + self.method = cv.INPAINT_TELEA + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + *args, + ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + *args (): + + Returns: + cupy._core.core.ndarray: + """ + mask = cp.asnumpy((elevation_map[2] < 0.5).astype("uint8")) + if (mask < 1).any(): + h = elevation_map[0] + h_max = float(h[mask < 1].max()) + h_min = float(h[mask < 1].min()) + h = cp.asnumpy((elevation_map[0] - h_min) * 255 / (h_max - h_min)).astype("uint8") + dst = np.array(cv.inpaint(h, mask, 1, self.method)) + h_inpainted = dst.astype(np.float32) * (h_max - h_min) / 255 + h_min + return cp.asarray(h_inpainted).astype(np.float64) + else: + return elevation_map[0] diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/max_layer_filter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/max_layer_filter.py new file mode 100644 index 00000000..33bc069a --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/max_layer_filter.py @@ -0,0 +1,108 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +from typing import List + +from elevation_mapping_cupy.plugins.plugin_manager import PluginBase + + +class MaxLayerFilter(PluginBase): + """Applies a maximum filter to the input layers and updates the traversability map. + This can be used to enhance navigation by identifying traversable areas. + + Args: + cell_n (int): The width and height of the elevation map. + reverse (list): A list of boolean values indicating whether to reverse the filter operation for each layer. Default is [True]. + min_or_max (str): A string indicating whether to apply a minimum or maximum filter. Accepts "min" or "max". Default is "max". + layers (list): List of layers for semantic traversability. Default is ["traversability"]. + thresholds (list): List of thresholds for each layer. If the value is bigger than a threshold, assign 1.0 otherwise 0.0. If it is False, it does not apply. Default is [False]. + **kwargs: Additional keyword arguments. + """ + + def __init__( + self, + cell_n: int = 100, + layers: list = ["traversability"], + reverse: list = [True], + min_or_max: str = "max", + thresholds: list = [False], + scales: list = [1.0], + default_value: float = 0.0, + **kwargs, + ): + super().__init__() + self.layers = layers + self.reverse = reverse + self.min_or_max = min_or_max + self.thresholds = thresholds + self.scales = scales + self.default_value = default_value + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], + *args, + ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): + *args (): + + Returns: + cupy._core.core.ndarray: + """ + layers = [] + for it, name in enumerate(self.layers): + layer = self.get_layer_data( + elevation_map, layer_names, plugin_layers, plugin_layer_names, semantic_map, semantic_layer_names, name + ) + if layer is None: + continue + if isinstance(self.default_value, float): + layer = cp.where(layer == 0.0, float(self.default_value), layer) + elif isinstance(self.default_value, str): + default_layer = self.get_layer_data( + elevation_map, + layer_names, + plugin_layers, + plugin_layer_names, + semantic_map, + semantic_layer_names, + self.default_value, + ) + layer = cp.where(layer == 0, default_layer, layer) + if self.reverse[it]: + layer = 1.0 - layer + if len(self.scales) > it and isinstance(self.scales[it], float): + layer = layer * float(self.scales[it]) + if isinstance(self.thresholds[it], float): + layer = cp.where(layer > float(self.thresholds[it]), 1, 0) + layers.append(layer) + if len(layers) == 0: + print("No layers are found, returning traversability!") + if isinstance(self.default_value, float): + layer = cp.ones_like(elevation_map[0]) + layer *= float(self.default_value) + return layer + else: + idx = layer_names.index("traversability") + return elevation_map[idx] + result = cp.stack(layers, axis=0) + if self.min_or_max == "min": + result = cp.min(result, axis=0) + else: + result = cp.max(result, axis=0) + return result diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/min_filter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/min_filter.py new file mode 100644 index 00000000..ebf4300a --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/min_filter.py @@ -0,0 +1,118 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import string +from typing import List + +from .plugin_manager import PluginBase + + +class MinFilter(PluginBase): + """This is a filter to fill in invalid cells with minimum values around. + + Args: + cell_n (int): width of the elevation map. + dilation_size (int): The size of the patch to search for minimum value for each iteration. + iteration_n (int): The number of iteration to repeat the same filter. + **kwargs (): + """ + + def __init__(self, cell_n: int = 100, dilation_size: int = 5, iteration_n: int = 5, **kwargs): + super().__init__() + self.iteration_n = iteration_n + self.width = cell_n + self.height = cell_n + self.min_filtered = cp.zeros((self.width, self.height)) + self.min_filtered_mask = cp.zeros((self.width, self.height)) + self.min_filter_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U mask", + out_params="raw U newmap, raw U newmask", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { + const int layer = ${width} * ${height}; + const int relative_idx = idx + ${width} * dy + dx; + return layer * layer_n + relative_idx; + } + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x <= 0 || idx_x >= ${width} - 1) { + return false; + } + if (idx_y <= 0 || idx_y >= ${height} - 1) { + return false; + } + return true; + } + """ + ).substitute(width=self.width, height=self.height), + operation=string.Template( + """ + U h = map[get_map_idx(i, 0)]; + U valid = mask[get_map_idx(i, 0)]; + if (valid < 0.5) { + U min_value = 1000000.0; + for (int dy = -${dilation_size}; dy <= ${dilation_size}; dy++) { + for (int dx = -${dilation_size}; dx <= ${dilation_size}; dx++) { + int idx = get_relative_map_idx(i, dx, dy, 0); + if (!is_inside(idx)) {continue;} + U valid = newmask[idx]; + U value = newmap[idx]; + if(valid > 0.5 && value < min_value) { + min_value = value; + } + } + } + if (min_value < 1000000 - 1) { + newmap[get_map_idx(i, 0)] = min_value; + newmask[get_map_idx(i, 0)] = 0.6; + } + } + """ + ).substitute(dilation_size=dilation_size), + name="min_filter_kernel", + ) + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + *args, + ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + *args (): + + Returns: + cupy._core.core.ndarray: + """ + self.min_filtered = elevation_map[0].copy() + self.min_filtered_mask = elevation_map[2].copy() + for i in range(self.iteration_n): + self.min_filter_kernel( + elevation_map[0], + elevation_map[2], + self.min_filtered, + self.min_filtered_mask, + size=(self.width * self.height), + ) + # If there's no more mask, break + if (self.min_filtered_mask > 0.5).all(): + break + min_filtered = cp.where(self.min_filtered_mask > 0.5, self.min_filtered.copy(), cp.nan) + return min_filtered diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/plugin_manager.py new file mode 100644 index 00000000..26f81d21 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/plugin_manager.py @@ -0,0 +1,268 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +from abc import ABC +import cupy as cp +from typing import List, Dict, Optional +import importlib +import inspect +from dataclasses import dataclass +from ruamel.yaml import YAML +from inspect import signature + + +@dataclass +class PluginParams: + name: str + layer_name: str + fill_nan: bool = False # fill nan to invalid region + is_height_layer: bool = False # if this is a height layer + + +class PluginBase(ABC): + """ + This is a base class of Plugins + """ + + def __init__(self, *args, **kwargs): + """ + + Args: + plugin_params : PluginParams + The parameter of callback + """ + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], + *args, + **kwargs, + ) -> cp.ndarray: + """This gets the elevation map data and plugin layers as a cupy array. + + + Args: + elevation_map (): + layer_names (): + plugin_layers (): + plugin_layer_names (): + semantic_map (): + semantic_layer_names (): + + Run your processing here and return the result. + layer of elevation_map 0: elevation + 1: variance + 2: is_valid + 3: traversability + 4: time + 5: upper_bound + 6: is_upper_bound + You can also access to the other plugins' layer with plugin_layers and plugin_layer_names + + """ + pass + + def get_layer_data( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], + name: str, + ) -> Optional[cp.ndarray]: + """ + Retrieve a copy of the layer data from the elevation, plugin, or semantic maps based on the layer name. + + Args: + elevation_map (cp.ndarray): The elevation map containing various layers. + layer_names (List[str]): A list of names for each layer in the elevation map. + plugin_layers (cp.ndarray): The plugin layers containing additional data. + plugin_layer_names (List[str]): A list of names for each layer in the plugin layers. + semantic_map (cp.ndarray): The semantic map containing various layers. + semantic_layer_names (List[str]): A list of names for each layer in the semantic map. + name (str): The name of the layer to retrieve. + + Returns: + Optional[cp.ndarray]: A copy of the requested layer as a cupy ndarray if found, otherwise None. + """ + if name in layer_names: + idx = layer_names.index(name) + layer = elevation_map[idx].copy() + elif name in plugin_layer_names: + idx = plugin_layer_names.index(name) + layer = plugin_layers[idx].copy() + elif name in semantic_layer_names: + idx = semantic_layer_names.index(name) + layer = semantic_map[idx].copy() + else: + print(f"Could not find layer {name}!") + layer = None + return layer + + +class PluginManager(object): + """ + This manages the plugins. + """ + + def __init__(self, cell_n: int): + self.cell_n = cell_n + + def init(self, plugin_params: List[PluginParams], extra_params: List[Dict]): + self.plugin_params = plugin_params + + self.plugins = [] + for param, extra_param in zip(plugin_params, extra_params): + m = importlib.import_module("." + param.name, package="elevation_mapping_cupy.plugins") # -> 'module' + for name, obj in inspect.getmembers(m): + if inspect.isclass(obj) and issubclass(obj, PluginBase) and name != "PluginBase": + # Add cell_n to params + extra_param["cell_n"] = self.cell_n + self.plugins.append(obj(**extra_param)) + self.layers = cp.zeros((len(self.plugins), self.cell_n, self.cell_n), dtype=cp.float32) + self.layer_names = self.get_layer_names() + self.plugin_names = self.get_plugin_names() + + def load_plugin_settings(self, file_path: str): + print("Start loading plugins...") + cfg = YAML().load(open(file_path, "r")) + plugin_params = [] + extra_params = [] + for k, v in cfg.items(): + if v["enable"]: + plugin_params.append( + PluginParams( + name=k if not "type" in v else v["type"], + layer_name=v["layer_name"], + fill_nan=v["fill_nan"], + is_height_layer=v["is_height_layer"], + ) + ) + extra_params.append(v["extra_params"]) + self.init(plugin_params, extra_params) + print("Loaded plugins are ", *self.plugin_names) + + def get_layer_names(self): + names = [] + for obj in self.plugin_params: + names.append(obj.layer_name) + return names + + def get_plugin_names(self): + names = [] + for obj in self.plugin_params: + names.append(obj.name) + return names + + def get_plugin_index_with_name(self, name: str) -> int: + try: + idx = self.plugin_names.index(name) + return idx + except Exception as e: + print("Error with plugin {}: {}".format(name, e)) + return None + + def get_layer_index_with_name(self, name: str) -> int: + try: + idx = self.layer_names.index(name) + return idx + except Exception as e: + print("Error with layer {}: {}".format(name, e)) + return None + + def update_with_name( + self, + name: str, + elevation_map: cp.ndarray, + layer_names: List[str], + semantic_map=None, + semantic_params=None, + rotation=None, + elements_to_shift={}, + ): + idx = self.get_layer_index_with_name(name) + if idx is not None and idx < len(self.plugins): + n_param = len(signature(self.plugins[idx]).parameters) + if n_param == 5: + self.layers[idx] = self.plugins[idx](elevation_map, layer_names, self.layers, self.layer_names) + elif n_param == 7: + self.layers[idx] = self.plugins[idx]( + elevation_map, + layer_names, + self.layers, + self.layer_names, + semantic_map, + semantic_params, + ) + elif n_param == 8: + self.layers[idx] = self.plugins[idx]( + elevation_map, + layer_names, + self.layers, + self.layer_names, + semantic_map, + semantic_params, + rotation, + ) + else: + self.layers[idx] = self.plugins[idx]( + elevation_map, + layer_names, + self.layers, + self.layer_names, + semantic_map, + semantic_params, + rotation, + elements_to_shift, + ) + + def get_map_with_name(self, name: str) -> cp.ndarray: + idx = self.get_layer_index_with_name(name) + if idx is not None: + return self.layers[idx] + + def get_param_with_name(self, name: str) -> PluginParams: + idx = self.get_layer_index_with_name(name) + if idx is not None: + return self.plugin_params[idx] + + +if __name__ == "__main__": + plugins = [ + PluginParams(name="min_filter", layer_name="min_filter"), + PluginParams(name="smooth_filter", layer_name="smooth"), + ] + extra_params = [ + {"dilation_size": 5, "iteration_n": 5}, + {"input_layer_name": "elevation2"}, + ] + manager = PluginManager(200) + manager.load_plugin_settings("../config/plugin_config.yaml") + print(manager.layer_names) + print(manager.plugin_names) + elevation_map = cp.zeros((7, 200, 200)).astype(cp.float32) + layer_names = [ + "elevation", + "variance", + "is_valid", + "traversability", + "time", + "upper_bound", + "is_upper_bound", + ] + elevation_map[0] = cp.random.randn(200, 200) + elevation_map[2] = cp.abs(cp.random.randn(200, 200)) + print("map", elevation_map[0]) + print("layer map ", manager.layers) + manager.update_with_name("min_filter", elevation_map, layer_names) + manager.update_with_name("smooth_filter", elevation_map, layer_names) + # manager.update_with_name("sem_fil", elevation_map, layer_names, semantic_map=semantic_map) + print(manager.get_map_with_name("smooth")) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/robot_centric_elevation.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/robot_centric_elevation.py new file mode 100644 index 00000000..80ac73a3 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/robot_centric_elevation.py @@ -0,0 +1,121 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import string +from typing import List +from .plugin_manager import PluginBase + + +class RobotCentricElevation(PluginBase): + """Generates an elevation map with respect to the robot frame. + + Args: + cell_n (int): + resolution (ruamel.yaml.scalarfloat.ScalarFloat): + threshold (ruamel.yaml.scalarfloat.ScalarFloat): + use_threshold (bool): + **kwargs (): + """ + + def __init__( + self, cell_n: int = 100, resolution: float = 0.05, threshold: float = 0.4, use_threshold: bool = 0, **kwargs + ): + super().__init__() + self.width = cell_n + self.height = cell_n + self.min_filtered = cp.zeros((self.width, self.height), dtype=cp.float32) + + self.base_elevation_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U mask, raw U R", + out_params="raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x <= 0 || idx_x >= ${width} - 1) { + return false; + } + if (idx_y <= 0 || idx_y >= ${height} - 1) { + return false; + } + return true; + } + __device__ float get_map_x(int idx){ + float idx_x = idx / ${width}* ${resolution}; + return idx_x; + } + __device__ float get_map_y(int idx){ + float idx_y = idx % ${width}* ${resolution}; + return idx_y; + } + __device__ float transform_p(float x, float y, float z, + float r0, float r1, float r2) { + return r0 * x + r1 * y + r2 * z ; + } + """ + ).substitute(width=self.width, height=self.height, resolution=resolution), + operation=string.Template( + """ + U rz = map[get_map_idx(i, 0)]; + U valid = mask[get_map_idx(i, 0)]; + if (valid > 0.5) { + U rx = get_map_x(get_map_idx(i, 0)); + U ry = get_map_y(get_map_idx(i, 0)); + U x_b = transform_p(rx, ry, rz, R[0], R[1], R[2]); + U y_b = transform_p(rx, ry, rz, R[3], R[4], R[5]); + U z_b = transform_p(rx, ry, rz, R[6], R[7], R[8]); + if (${use_threshold} && z_b>= ${threshold} ) { + newmap[get_map_idx(i, 0)] = 1.0; + } + else if (${use_threshold} && z_b< ${threshold} ){ + newmap[get_map_idx(i, 0)] = 0.0; + } + else{ + newmap[get_map_idx(i, 0)] = z_b; + } + } + """ + ).substitute(threshold=threshold, use_threshold=int(use_threshold)), + name="base_elevation_kernel", + ) + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], + rotation, + *args, + ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): + rotation (cupy._core.core.ndarray): + *args (): + + Returns: + cupy._core.core.ndarray: + """ + # Process maps here + # check that transform is a ndarray + self.min_filtered = elevation_map[0].copy() + self.base_elevation_kernel( + elevation_map[0], elevation_map[2], rotation, self.min_filtered, size=(self.width * self.height), + ) + return self.min_filtered diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_filter.py new file mode 100644 index 00000000..0ec56010 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_filter.py @@ -0,0 +1,133 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +from typing import List +import re + +from elevation_mapping_cupy.plugins.plugin_manager import PluginBase + + +class SemanticFilter(PluginBase): + """This is a filter to create a one hot encoded map of the class probabilities. + + Args: + cell_n (int): width and height of the elevation map. + classes (list): List of classes for semantic filtering. Default is ["person", "grass"]. + **kwargs: Additional keyword arguments. + """ + + def __init__( + self, cell_n: int = 100, classes: list = ["person", "grass"], **kwargs, + ): + super().__init__() + self.indices = [] + self.classes = classes + self.color_encoding = self.transform_color() + + def color_map(self, N: int = 256, normalized: bool = False): + """ + Creates a color map with N different colors. + + Args: + N (int, optional): The number of colors in the map. Defaults to 256. + normalized (bool, optional): If True, the colors are normalized to the range [0,1]. Defaults to False. + + Returns: + np.ndarray: The color map. + """ + + def bitget(byteval, idx): + return (byteval & (1 << idx)) != 0 + + dtype = "float32" if normalized else "uint8" + cmap = np.zeros((N + 1, 3), dtype=dtype) + for i in range(N + 1): + r = g = b = 0 + c = i + for j in range(8): + r = r | (bitget(c, 0) << 7 - j) + g = g | (bitget(c, 1) << 7 - j) + b = b | (bitget(c, 2) << 7 - j) + c = c >> 3 + + cmap[i] = np.array([r, g, b]) + + cmap = cmap / 255 if normalized else cmap + cmap[1] = np.array([81, 113, 162]) + cmap[2] = np.array([81, 113, 162]) + cmap[3] = np.array([188, 63, 59]) + return cmap[1:] + + def transform_color(self): + """ + Transforms the color map into a format that can be used for semantic filtering. + + Returns: + cp.ndarray: The transformed color map. + """ + color_classes = self.color_map(255) + r = np.asarray(color_classes[:, 0], dtype=np.uint32) + g = np.asarray(color_classes[:, 1], dtype=np.uint32) + b = np.asarray(color_classes[:, 2], dtype=np.uint32) + rgb_arr = np.array((r << 16) | (g << 8) | (b << 0), dtype=np.uint32) + rgb_arr.dtype = np.float32 + return cp.asarray(rgb_arr) + + def get_layer_indices(self, layer_names: List[str]) -> List[int]: + """ Get the indices of the layers that are to be processed using regular expressions. + Args: + layer_names (List[str]): List of layer names. + Returns: + List[int]: List of layer indices. + """ + indices = [] + for i, layer_name in enumerate(layer_names): + if any(re.match(pattern, layer_name) for pattern in self.classes): + indices.append(i) + return indices + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], + rotation, + elements_to_shift, + *args, + ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): + *args (): + + Returns: + cupy._core.core.ndarray: + """ + # get indices of all layers that contain semantic class information + data = [] + for m, layer_names in zip( + [elevation_map, plugin_layers, semantic_map], [layer_names, plugin_layer_names, semantic_layer_names] + ): + layer_indices = self.get_layer_indices(layer_names) + if len(layer_indices) > 0: + data.append(m[layer_indices]) + if len(data) > 0: + data = cp.concatenate(data, axis=0) + class_map = cp.amax(data, axis=0) + class_map_id = cp.argmax(data, axis=0) + else: + class_map = cp.zeros_like(elevation_map[0]) + class_map_id = cp.zeros_like(elevation_map[0], dtype=cp.int32) + enc = self.color_encoding[class_map_id] + return enc diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_traversability.py new file mode 100644 index 00000000..5f6ef1d5 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_traversability.py @@ -0,0 +1,83 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import numpy as np +from typing import List + +from elevation_mapping_cupy.plugins.plugin_manager import PluginBase + + +class SemanticTraversability(PluginBase): + """Extracts traversability and elevations from layers and generates an updated traversability that can be used by checker. + + Args: + cell_n (int): The width and height of the elevation map. + layers (list): List of layers for semantic traversability. Default is ["traversability"]. + thresholds (list): List of thresholds for each layer. Default is [0.5]. + type (list): List of types for each layer. Default is ["traversability"]. + **kwargs: Additional keyword arguments. + """ + + def __init__( + self, + cell_n: int = 100, + layers: list = ["traversability"], + thresholds: list = [0.5], + type: list = ["traversability"], + **kwargs, + ): + super().__init__() + self.layers = layers + self.thresholds = cp.asarray(thresholds) + self.type = type + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + semantic_map: cp.ndarray, + semantic_layer_names: List[str], + *args, + ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): + *args (): + + Returns: + cupy._core.core.ndarray: + """ + # get indices of all layers that + map = cp.zeros(elevation_map[2].shape, np.float32) + tempo = cp.zeros(elevation_map[2].shape, np.float32) + for it, name in enumerate(self.layers): + if name in layer_names: + idx = layer_names.index(name) + tempo = elevation_map[idx] + # elif name in semantic_params.additional_layers: + # idx = semantic_params.additional_layers.index(name) + # tempo = semantic_map[idx] + elif name in plugin_layer_names: + idx = plugin_layer_names.index(name) + tempo = plugin_layers[idx] + else: + print("Layer {} is not in the map, returning traversabiltiy!".format(name)) + return + if self.type[it] == "traversability": + tempo = cp.where(tempo <= self.thresholds[it], 1, 0) + map += tempo + else: + tempo = cp.where(tempo >= self.thresholds[it], 1, 0) + map += tempo + map = cp.where(map <= 0.9, 0.1, 1) + + return map diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/smooth_filter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/smooth_filter.py new file mode 100644 index 00000000..ae48b688 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/smooth_filter.py @@ -0,0 +1,59 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +from typing import List +import cupyx.scipy.ndimage as ndimage + +from .plugin_manager import PluginBase + + +class SmoothFilter(PluginBase): + """ + SmoothFilter is a class that applies a smoothing filter + to the elevation map. The filter is applied to the layer specified by the input_layer_name parameter. + If the specified layer is not found, the filter is applied to the elevation layer. + + Args: + cell_n (int): The width and height of the elevation map. Default is 100. + input_layer_name (str): The name of the layer to which the filter should be applied. Default is "elevation". + **kwargs: Additional keyword arguments. + """ + + def __init__(self, cell_n: int = 100, input_layer_name: str = "elevation", **kwargs): + super().__init__() + self.input_layer_name = input_layer_name + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + *args, + ) -> cp.ndarray: + """ + + Args: + elevation_map (cupy._core.core.ndarray): + layer_names (List[str]): + plugin_layers (cupy._core.core.ndarray): + plugin_layer_names (List[str]): + *args (): + + Returns: + cupy._core.core.ndarray: + """ + if self.input_layer_name in layer_names: + idx = layer_names.index(self.input_layer_name) + h = elevation_map[idx] + elif self.input_layer_name in plugin_layer_names: + idx = plugin_layer_names.index(self.input_layer_name) + h = plugin_layers[idx] + else: + print("layer name {} was not found. Using elevation layer.".format(self.input_layer_name)) + h = elevation_map[0] + hs1 = ndimage.uniform_filter(h, size=3) + hs1 = ndimage.uniform_filter(hs1, size=3) + return hs1 diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/semantic_map.py new file mode 100644 index 00000000..a06b7361 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/semantic_map.py @@ -0,0 +1,400 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +from elevation_mapping_cupy.parameter import Parameter +import cupy as cp +import numpy as np +from typing import List, Dict +import re + + +from elevation_mapping_cupy.fusion.fusion_manager import FusionManager + +xp = cp + + +class SemanticMap: + def __init__(self, param: Parameter): + """ + + Args: + param (elevation_mapping_cupy.parameter.Parameter): + """ + + self.param = param + + self.layer_specs_points = {} + self.layer_specs_image = {} + self.layer_names = [] + self.unique_fusion = [] + self.unique_data = [] + self.elements_to_shift = {} + + self.unique_fusion = self.param.fusion_algorithms + + self.amount_layer_names = len(self.layer_names) + + self.semantic_map = xp.zeros( + (self.amount_layer_names, self.param.cell_n, self.param.cell_n), dtype=param.data_type, + ) + self.new_map = xp.zeros((self.amount_layer_names, self.param.cell_n, self.param.cell_n), param.data_type,) + # which layers should be reset to zero at each update, per default everyone, + # if a layer should not be reset, it is defined in compile_kernels function + self.delete_new_layers = cp.ones(self.new_map.shape[0], cp.bool8) + self.fusion_manager = FusionManager(self.param) + + def clear(self): + """Clear the semantic map.""" + self.semantic_map *= 0.0 + + def initialize_fusion(self): + """Initialize the fusion algorithms.""" + for fusion in self.unique_fusion: + if "pointcloud_class_bayesian" == fusion: + pcl_ids = self.get_layer_indices("class_bayesian", self.layer_specs_points) + self.delete_new_layers[pcl_ids] = 0 + if "pointcloud_class_max" == fusion: + pcl_ids = self.get_layer_indices("class_max", self.layer_specs_points) + self.delete_new_layers[pcl_ids] = 0 + layer_cnt = self.param.fusion_algorithms.count("class_max") + id_max = cp.zeros((layer_cnt, self.param.cell_n, self.param.cell_n), dtype=cp.uint32,) + self.elements_to_shift["id_max"] = id_max + self.fusion_manager.register_plugin(fusion) + + def update_fusion_setting(self): + """ + Update the fusion settings. + """ + for fusion in self.unique_fusion: + if "pointcloud_class_bayesian" == fusion: + pcl_ids = self.get_layer_indices("class_bayesian", self.layer_specs_points) + self.delete_new_layers[pcl_ids] = 0 + if "pointcloud_class_max" == fusion: + pcl_ids = self.get_layer_indices("class_max", self.layer_specs_points) + self.delete_new_layers[pcl_ids] = 0 + layer_cnt = self.param.fusion_algorithms.count("class_max") + id_max = cp.zeros((layer_cnt, self.param.cell_n, self.param.cell_n), dtype=cp.uint32,) + self.elements_to_shift["id_max"] = id_max + + def add_layer(self, name): + """ + Add a new layer to the semantic map. + + Args: + name (str): The name of the new layer. + """ + if name not in self.layer_names: + self.layer_names.append(name) + self.semantic_map = cp.append( + self.semantic_map, + cp.zeros((1, self.param.cell_n, self.param.cell_n), dtype=self.param.data_type), + axis=0, + ) + self.new_map = cp.append( + self.new_map, cp.zeros((1, self.param.cell_n, self.param.cell_n), dtype=self.param.data_type), axis=0, + ) + self.delete_new_layers = cp.append(self.delete_new_layers, cp.array([1], dtype=cp.bool8)) + + def pad_value(self, x, shift_value, idx=None, value=0.0): + """Create a padding of the map along x,y-axis according to amount that has shifted. + + Args: + x (cupy._core.core.ndarray): + shift_value (cupy._core.core.ndarray): + idx (Union[None, int, None, None]): + value (float): + """ + if idx is None: + if shift_value[0] > 0: + x[:, : shift_value[0], :] = value + elif shift_value[0] < 0: + x[:, shift_value[0] :, :] = value + if shift_value[1] > 0: + x[:, :, : shift_value[1]] = value + elif shift_value[1] < 0: + x[:, :, shift_value[1] :] = value + else: + if shift_value[0] > 0: + x[idx, : shift_value[0], :] = value + elif shift_value[0] < 0: + x[idx, shift_value[0] :, :] = value + if shift_value[1] > 0: + x[idx, :, : shift_value[1]] = value + elif shift_value[1] < 0: + x[idx, :, shift_value[1] :] = value + + def shift_map_xy(self, shift_value): + """Shift the map along x,y-axis according to shift values. + + Args: + shift_value: + """ + self.semantic_map = cp.roll(self.semantic_map, shift_value, axis=(1, 2)) + self.pad_value(self.semantic_map, shift_value, value=0.0) + self.new_map = cp.roll(self.new_map, shift_value, axis=(1, 2)) + self.pad_value(self.new_map, shift_value, value=0.0) + for el in self.elements_to_shift.values(): + el = cp.roll(el, shift_value, axis=(1, 2)) + self.pad_value(el, shift_value, value=0.0) + + def get_fusion( + self, channels: List[str], channel_fusions: Dict[str, str], layer_specs: Dict[str, str] + ) -> List[str]: + """Get all fusion algorithms that need to be applied to a specific pointcloud. + + Args: + channels (List[str]): + """ + fusion_list = [] + process_channels = [] + for channel in channels: + if channel not in layer_specs: + # If the channel is not in the layer_specs, we use the default fusion algorithm + matched_fusion = self.get_matching_fusion(channel, channel_fusions) + if matched_fusion is None: + if "default" in channel_fusions: + default_fusion = channel_fusions["default"] + print( + f"[WARNING] Layer {channel} not found in layer_specs. Using {default_fusion} algorithm as default." + ) + layer_specs[channel] = default_fusion + self.update_fusion_setting() + # If there's no default fusion algorithm, we skip this channel + else: + print( + f"[WARNING] Layer {channel} not found in layer_specs ({layer_specs}) and no default fusion is configured. Skipping." + ) + continue + else: + layer_specs[channel] = matched_fusion + self.update_fusion_setting() + x = layer_specs[channel] + fusion_list.append(x) + process_channels.append(channel) + return process_channels, fusion_list + + def get_matching_fusion(self, channel: str, fusion_algs: Dict[str, str]): + """ Use regular expression to check if the fusion algorithm matches the channel name.""" + for fusion_alg, alg_value in fusion_algs.items(): + if re.match(f"^{fusion_alg}$", channel): + return alg_value + return None + + def get_layer_indices(self, fusion_alg, layer_specs): + """Get the indices of the layers that are used for a specific fusion algorithm. + + Args: + fusion_alg(str): fusion algorithm name + + Returns: + cp.array: indices of the layers + """ + layer_indices = cp.array([], dtype=cp.int32) + for it, (key, val) in enumerate(layer_specs.items()): + if key in val == fusion_alg: + layer_indices = cp.append(layer_indices, it).astype(cp.int32) + return layer_indices + + def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str, layer_specs: Dict[str, str]): + """Computes the indices of the channels of the pointcloud and the layers of the semantic map of type fusion_alg. + + Args: + pcl_channels (List[str]): list of all channel names + fusion_alg (str): fusion algorithm type we want to use for channel selection + + Returns: + Union[Tuple[List[int], List[int]], Tuple[cupy._core.core.ndarray, cupy._core.core.ndarray]]: + + + """ + # this contains exactly the fusion alg type for each channel of the pcl + pcl_val_list = [layer_specs[x] for x in pcl_channels] + # this contains the indices of the point cloud where we have to perform a certain fusion + pcl_indices = cp.array([idp + 3 for idp, x in enumerate(pcl_val_list) if x == fusion_alg], dtype=cp.int32,) + # create a list of indices of the layers that will be updated by the point cloud with specific fusion alg + layer_indices = cp.array([], dtype=cp.int32) + for it, (key, val) in enumerate(layer_specs.items()): + if key in pcl_channels and val == fusion_alg: + layer_idx = self.layer_names.index(key) + layer_indices = cp.append(layer_indices, layer_idx).astype(cp.int32) + return pcl_indices, layer_indices + + def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): + """Update the semantic map with the pointcloud. + + Args: + points_all: semantic point cloud + channels: list of channel names + R: rotation matrix + t: translation vector + elevation_map: elevation map object + """ + process_channels, additional_fusion = self.get_fusion( + channels, self.param.pointcloud_channel_fusions, self.layer_specs_points + ) + # If channels has a new layer that is not in the semantic map, add it + for channel in process_channels: + if channel not in self.layer_names: + print(f"Layer {channel} not found, adding it to the semantic map") + self.add_layer(channel) + + # Resetting new_map for the layers that are to be deleted + self.new_map[self.delete_new_layers] = 0.0 + for fusion in list(set(additional_fusion)): + # which layers need to be updated with this fusion algorithm + pcl_ids, layer_ids = self.get_indices_fusion(process_channels, fusion, self.layer_specs_points) + # update the layers with the fusion algorithm + self.fusion_manager.execute_plugin( + fusion, + points_all, + R, + t, + pcl_ids, + layer_ids, + elevation_map, + self.semantic_map, + self.new_map, + self.elements_to_shift, + ) + + def update_layers_image( + self, + # sub_key: str, + image: cp._core.core.ndarray, + channels: List[str], + # fusion_methods: List[str], + uv_correspondence: cp._core.core.ndarray, + valid_correspondence: cp._core.core.ndarray, + image_height: cp._core.core.ndarray, + image_width: cp._core.core.ndarray, + ): + """Update the semantic map with the new image. + + Args: + sub_key: + image: + uv_correspondence: + valid_correspondence: + image_height: + image_width: + """ + + process_channels, fusion_methods = self.get_fusion( + channels, self.param.image_channel_fusions, self.layer_specs_image + ) + self.new_map[self.delete_new_layers] = 0.0 + for j, (fusion, channel) in enumerate(zip(fusion_methods, process_channels)): + if channel not in self.layer_names: + print(f"Layer {channel} not found, adding it to the semantic map") + self.add_layer(channel) + sem_map_idx = self.get_index(channel) + + if sem_map_idx == -1: + print(f"Layer {channel} not found!") + return + + # update the layers with the fusion algorithm + self.fusion_manager.execute_image_plugin( + fusion, + cp.uint64(sem_map_idx), + image, + j, + uv_correspondence, + valid_correspondence, + image_height, + image_width, + self.semantic_map, + self.new_map, + ) + + def decode_max(self, mer): + """Decode the float32 value into two 16 bit value containing the class probability and the class id. + + Args: + mer: + + Returns: + cp.array: probability + cp.array: class id + """ + mer = mer.astype(cp.float32) + mer = mer.view(dtype=cp.uint32) + ma = cp.bitwise_and(mer, 0xFFFF, dtype=np.uint16) + ma = ma.view(np.float16) + ma = ma.astype(np.float32) + ind = cp.right_shift(mer, 16) + return ma, ind + + def get_map_with_name(self, name): + """Return the map with the given name. + + Args: + name: layer name + + Returns: + cp.array: map + """ + # If the layer is a color layer, return the rgb map + if name in self.layer_specs_points and self.layer_specs_points[name] == "color": + m = self.get_rgb(name) + return m + elif name in self.layer_specs_image and self.layer_specs_image[name] == "color": + m = self.get_rgb(name) + return m + else: + m = self.get_semantic(name) + return m + + def get_rgb(self, name): + """Return the rgb map with the given name. + + Args: + name: + + Returns: + cp.array: rgb map + """ + idx = self.layer_names.index(name) + c = self.process_map_for_publish(self.semantic_map[idx]) + c = c.astype(np.float32) + return c + + def get_semantic(self, name): + """Return the semantic map layer with the given name. + + Args: + name(str): layer name + + Returns: + cp.array: semantic map layer + """ + idx = self.layer_names.index(name) + c = self.process_map_for_publish(self.semantic_map[idx]) + return c + + def process_map_for_publish(self, input_map): + """Remove padding. + + Args: + input_map(cp.array): map layer + + Returns: + cp.array: map layer without padding + """ + m = input_map.copy() + return m[1:-1, 1:-1] + + def get_index(self, name): + """Return the index of the layer with the given name. + + Args: + name(str): + + Returns: + int: index + """ + if name not in self.layer_names: + return -1 + else: + return self.layer_names.index(name) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/__init__.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_elevation_mapping.py new file mode 100644 index 00000000..7bdbb20b --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_elevation_mapping.py @@ -0,0 +1,118 @@ +import pytest +from elevation_mapping_cupy import parameter, elevation_mapping +import cupy as cp +import numpy as np + + +def encode_max(maxim, index): + maxim, index = cp.asarray(maxim, dtype=cp.float32), cp.asarray(index, dtype=cp.uint32) + # fuse them + maxim = maxim.astype(cp.float16) + maxim = maxim.view(cp.uint16) + maxim = maxim.astype(cp.uint32) + index = index.astype(cp.uint32) + mer = cp.array(cp.left_shift(index, 16) | maxim, dtype=cp.uint32) + mer = mer.view(cp.float32) + return mer + + +@pytest.fixture() +def elmap_ex(add_lay, fusion_alg): + additional_layer = add_lay + fusion_algorithms = fusion_alg + p = parameter.Parameter( + use_chainer=False, + weight_file="../../../config/weights.dat", + plugin_config_file="../../../config/plugin_config.yaml", + ) + p.subscriber_cfg["front_cam"]["channels"] = additional_layer + p.subscriber_cfg["front_cam"]["fusion"] = fusion_algorithms + p.update() + e = elevation_mapping.ElevationMap(p) + return e + + +@pytest.mark.parametrize( + "add_lay,fusion_alg", + [ + (["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), + (["feat_0", "feat_1"], ["average", "average"]), + (["feat_0", "feat_1"], ["class_average", "class_average"]), + (["feat_0", "feat_1"], ["class_bayesian", "class_bayesian"]), + (["feat_0", "feat_1"], ["class_bayesian", "class_max"]), + (["feat_0", "feat_1"], ["bayesian_inference", "bayesian_inference"]), + ], +) +class TestElevationMap: + def test_init(self, elmap_ex): + assert len(elmap_ex.layer_names) == elmap_ex.elevation_map.shape[0] + # assert elmap_ex.color_map is None + + def test_input(self, elmap_ex): + channels = ["x", "y", "z"] + elmap_ex.param.additional_layers + if "class_max" in elmap_ex.param.fusion_algorithms: + val = cp.random.rand(100000, len(channels), dtype=cp.float32).astype(cp.float16) + ind = cp.random.randint(0, 2, (100000, len(channels)), dtype=cp.uint32).astype(cp.float32) + points = encode_max(val, ind) + else: + points = cp.random.rand(100000, len(channels), dtype=elmap_ex.param.data_type) + R = cp.random.rand(3, 3, dtype=elmap_ex.param.data_type) + t = cp.random.rand(3, dtype=elmap_ex.param.data_type) + elmap_ex.input_pointcloud(points, channels, R, t, 0, 0) + + def test_update_normal(self, elmap_ex): + elmap_ex.update_normal(elmap_ex.elevation_map[0]) + + def test_move_to(self, elmap_ex): + for i in range(20): + pos = np.array([i * 0.01, i * 0.02, i * 0.01]) + R = cp.random.rand(3, 3) + elmap_ex.move_to(pos, R) + + def test_get_map(self, elmap_ex): + layers = [ + "elevation", + "variance", + "traversability", + "min_filter", + "smooth", + "inpaint", + "rgb", + ] + data = np.zeros((elmap_ex.cell_n - 2, elmap_ex.cell_n - 2), dtype=cp.float32) + for layer in layers: + elmap_ex.get_map_with_name_ref(layer, data) + + def test_get_position(self, elmap_ex): + pos = np.random.rand(1, 3) + elmap_ex.get_position(pos) + + def test_clear(self, elmap_ex): + elmap_ex.clear() + + def test_move(self, elmap_ex): + delta_position = np.random.rand(3) + elmap_ex.move(delta_position) + + def test_exists_layer(self, elmap_ex, add_lay): + for layer in add_lay: + assert elmap_ex.exists_layer(layer) + + def test_polygon_traversability(self, elmap_ex): + polygon = cp.array([[0, 0], [2, 0], [0, 2]], dtype=np.float64) + result = np.array([0, 0, 0]) + number_polygons = elmap_ex.get_polygon_traversability(polygon, result) + untraversable_polygon = np.zeros((number_polygons, 2)) + elmap_ex.get_untraversable_polygon(untraversable_polygon) + + def test_initialize_map(self, elmap_ex): + methods = ["linear", "cubic", "nearest"] + for method in methods: + points = np.array([[-4.0, 0.0, 0.0], [-4.0, 8.0, 1.0], [4.0, 8.0, 0.0], [4.0, 0.0, 0.0]]) + elmap_ex.initialize_map(points, method) + + def test_plugins(self, elmap_ex): + layers = elmap_ex.plugin_manager.layer_names + data = np.zeros((200, 200), dtype=np.float32) + for layer in layers: + elmap_ex.get_map_with_name_ref(layer, data) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_parameter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_parameter.py new file mode 100644 index 00000000..4c497349 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_parameter.py @@ -0,0 +1,17 @@ +import pytest +from elevation_mapping_cupy.parameter import Parameter + + +def test_parameter(): + param = Parameter( + use_chainer=False, + weight_file="../../../config/weights.dat", + plugin_config_file="../../../config/plugin_config.yaml", + ) + res = param.resolution + param.set_value("resolution", 0.1) + param.get_types() + param.get_names() + param.update() + assert param.resolution == param.get_value("resolution") + param.load_weights(param.weight_file) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_plugins.py new file mode 100644 index 00000000..f3e8cc1c --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_plugins.py @@ -0,0 +1,69 @@ +import pytest +from elevation_mapping_cupy import semantic_map, parameter +import cupy as cp +import numpy as np +from elevation_mapping_cupy.plugins.plugin_manager import PluginManager, PluginParams + +plugin_path = "plugin_config.yaml" + + +@pytest.fixture() +def semmap_ex(add_lay, fusion_alg): + p = parameter.Parameter( + use_chainer=False, weight_file="../../../config/weights.dat", plugin_config_file=plugin_path, + ) + p.subscriber_cfg["front_cam"]["channels"] = add_lay + p.subscriber_cfg["front_cam"]["fusion"] = fusion_alg + p.update() + e = semantic_map.SemanticMap(p) + e.initialize_fusion() + return e + + +@pytest.mark.parametrize( + "add_lay, fusion_alg,channels", + [ + ( + ["grass", "tree", "fence", "person"], + ["class_average", "class_average", "class_average", "class_average"], + ["grass"], + ), + (["grass", "tree"], ["class_average", "class_average"], ["grass"]), + (["grass", "tree"], ["class_average", "class_max"], ["tree"]), + (["max1", "max2"], ["class_max", "class_max"], ["max1", "max2"]), + ], +) +def test_plugin_manager(semmap_ex, channels): + manager = PluginManager(202) + manager.load_plugin_settings(plugin_path) + elevation_map = cp.zeros((7, 202, 202)).astype(cp.float32) + rotation = cp.eye(3, dtype=cp.float32) + layer_names = [ + "elevation", + "variance", + "is_valid", + "traversability", + "time", + "upper_bound", + "is_upper_bound", + ] + elevation_map[0] = cp.random.randn(202, 202) + elevation_map[2] = cp.abs(cp.random.randn(202, 202)) + elevation_map[0] + manager.layers[0] + manager.update_with_name("min_filter", elevation_map, layer_names) + manager.update_with_name("smooth_filter", elevation_map, layer_names) + manager.update_with_name("semantic_filter", elevation_map, layer_names, semmap_ex, rotation) + manager.update_with_name("semantic_traversability", elevation_map, layer_names, semmap_ex) + manager.get_map_with_name("smooth") + for lay in manager.get_layer_names(): + manager.update_with_name( + lay, + elevation_map, + layer_names, + semmap_ex.semantic_map, + semmap_ex.param, + rotation, + semmap_ex.elements_to_shift, + ) + manager.get_map_with_name(lay) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_kernels.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_kernels.py new file mode 100644 index 00000000..590946eb --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_kernels.py @@ -0,0 +1,307 @@ +import pytest +from elevation_mapping_cupy import parameter, elevation_mapping +import cupy as cp + +from elevation_mapping_cupy.parameter import Parameter + +from elevation_mapping_cupy.kernels import add_points_kernel +from elevation_mapping_cupy.kernels import ( + average_kernel, + class_average_kernel, + alpha_kernel, + bayesian_inference_kernel, + add_color_kernel, + color_average_kernel, + sum_compact_kernel, + sum_max_kernel, + sum_kernel, +) + + +# to check output run: pytest -rP test_semantic_kernels.py + + +# only kernel where we test only one layer +def test_color_kernel(): + # params + cell_n = 4 + pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) + semantic_map = cp.zeros((1, 4, 4), dtype=cp.float32) + + # compile kernel + add_color_kernel_ = add_color_kernel(cell_n, cell_n,) + color_average_kernel_ = color_average_kernel(cell_n, cell_n) + + # updatelayer + color_map = cp.zeros((1 + 3 * layer_ids.shape[0], cell_n, cell_n), dtype=cp.uint32,) + + points_all = points_all.astype(cp.float32) + add_color_kernel_( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + color_map, + size=(points_all.shape[0] * pcl_ids.shape[0]), + ) + color_average_kernel_( + color_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + size=(cell_n * cell_n * pcl_ids.shape[0]), + ) + print(color_map) + + +@pytest.mark.parametrize( + "map_shape, points_all,pcl_ids, layer_ids", + [ + ( + (4, 4, 4), + cp.array( + [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 + ), + cp.array([3, 4], dtype=cp.int32), + cp.array([1, 2], dtype=cp.int32), + ), + ], +) +def test_sum_kernel(map_shape, points_all, pcl_ids, layer_ids): + # create points + resolution = 0.9 + points = points_all[:, :3] + # arguments for kernel + semantic_map = cp.zeros(map_shape, dtype=cp.float32) + new_map = cp.zeros(map_shape, dtype=cp.float32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + # compile kernel + sum_kernel_ = sum_kernel(0.9, 4, 4,) + # simulating adding the points + print("idx, valid, inside, values") + points_all[:, 0] = 1 + points_all[:, 1:3] = 1.0 + print("points all after ", points_all) + # run the kernel + sum_kernel_( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + new_map, + size=(points_all.shape[0] * pcl_ids.shape[0]), + ) + print("semantic_map", semantic_map) + print("new_map", new_map) + + +@pytest.mark.parametrize( + "map_shape, points_all,pcl_ids, layer_ids", + [ + ( + (4, 4, 4), + cp.array( + [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 + ), + cp.array([3, 4], dtype=cp.int32), + cp.array([1, 2], dtype=cp.int32), + ), + ], +) +def test_average_kernel(map_shape, points_all, pcl_ids, layer_ids): + elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) + elevation_map[2] = points_all.shape[0] + semantic_map = cp.zeros(map_shape, dtype=cp.float32) + new_map = cp.ones(map_shape, dtype=cp.float32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + # compile kernel + average_kernel_ = average_kernel(4, 4,) + cell_n = 4 + print("new_map", new_map) + print("semantic_map", semantic_map) + print("elevation_map", elevation_map) + + average_kernel_( + new_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + elevation_map, + semantic_map, + size=(cell_n * cell_n * pcl_ids.shape[0]), + ) + print("semantic_map", semantic_map) + + +@pytest.mark.parametrize( + "map_shape, points_all,pcl_ids, layer_ids", + [ + ( + (3, 4, 4), + cp.array( + [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 + ), + cp.array([3], dtype=cp.int32), + cp.array([0], dtype=cp.int32), + ), + ], +) +def test_bayesian_inference_kernel(map_shape, points_all, pcl_ids, layer_ids): + # params + cell_n = 4 + resolution = 0.9 + elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) + elevation_map[2] = points_all.shape[0] + semantic_map = cp.zeros(map_shape, dtype=cp.float32) + new_map = cp.ones(map_shape, dtype=cp.float32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + + # compile kernel + sum_mean = cp.ones((pcl_ids.shape[0], cell_n, cell_n,), cp.float32,) + sum_compact_kernel_ = sum_compact_kernel(resolution, cell_n, cell_n,) + bayesian_inference_kernel_ = bayesian_inference_kernel(cell_n, cell_n,) + # updatelayer + sum_mean *= 0 + sum_compact_kernel_( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + sum_mean, + size=(points_all.shape[0] * pcl_ids.shape[0]), + ) + bayesian_inference_kernel_( + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + elevation_map, + new_map, + sum_mean, + semantic_map, + size=(cell_n * cell_n * pcl_ids.shape[0]), + ) + print("semantic_map", semantic_map) + + +@pytest.mark.parametrize( + "map_shape, points_all,pcl_ids, layer_ids", + [ + ( + (4, 4, 4), + cp.array( + [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 + ), + cp.array([3, 4], dtype=cp.int32), + cp.array([1, 2], dtype=cp.int32), + ), + ], +) +def test_class_average_kernel(map_shape, points_all, pcl_ids, layer_ids): + # params + cell_n = 4 + resolution = 0.9 + average_weight = 0.5 + elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) + elevation_map[2] = 3 + semantic_map = cp.zeros(map_shape, dtype=cp.float32) + new_map = cp.zeros(map_shape, dtype=cp.float32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + # compile kernel + sum_kernel_ = sum_kernel(0.9, 4, 4,) + class_average_kernel_ = class_average_kernel(cell_n, cell_n, average_weight,) + print("x,y,z,class") + print("points all after ", points_all) + + # simulating adding the points + print("idx, valid, inside, values") + points_all[:, 0] = 1 + points_all[:, 1:3] = 1.0 + print("points all after ", points_all) + # run the kernel + sum_kernel_( + points_all, + R, + t, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + semantic_map, + new_map, + size=(points_all.shape[0] * pcl_ids.shape[0]), + ) + print("new_map bef", new_map) + print("pcl_ids.shape[0]", pcl_ids.shape[0]) + class_average_kernel_( + new_map, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + elevation_map, + semantic_map, + size=(cell_n * cell_n * pcl_ids.shape[0]), + ) + print("semantic_map", semantic_map) + print("new_map", new_map) + + +@pytest.mark.parametrize( + "map_shape, points_all,pcl_ids, layer_ids", + [ + ( + (4, 4, 4), + cp.array( + [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 + ), + cp.array([3, 4], dtype=cp.int32), + cp.array([1, 2], dtype=cp.int32), + ), + ], +) +def test_class_bayesian_inference_fct(map_shape, points_all, pcl_ids, layer_ids): + # params + cell_n = 4 + resolution = 0.9 + elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) + elevation_map[2] = points_all.shape[0] + semantic_map = cp.zeros(map_shape, dtype=cp.float32) + new_map = cp.zeros(map_shape, dtype=cp.float32) + R = cp.eye(3, dtype=cp.float32) + t = cp.array([0, 0, 0], dtype=cp.float32) + # compile kernel + alpha_kernel_ = alpha_kernel(resolution, cell_n, cell_n,) + # simulating adding the points + print("idx, valid, inside, values") + points_all[:, 0] = 1 + points_all[:, 1:3] = 1.0 + print("points all after ", points_all) + # run the kernel + alpha_kernel_( + points_all, + pcl_ids, + layer_ids, + cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), + new_map, + size=(points_all.shape[0] * pcl_ids.shape[0]), + ) + # calculate new thetas + sum_alpha = cp.sum(new_map[layer_ids], axis=0) + # do not divide by zero + sum_alpha[sum_alpha == 0] = 1 + semantic_map[layer_ids] = new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) + print("semantic_map", semantic_map) + print("new_map", new_map) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_map.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_map.py new file mode 100644 index 00000000..95966bc4 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_map.py @@ -0,0 +1,47 @@ +import pytest +from elevation_mapping_cupy import semantic_map, parameter +import cupy as cp +import numpy as np + + +@pytest.fixture() +def semmap_ex(sem_lay, fusion_alg): + p = parameter.Parameter( + use_chainer=False, + weight_file="../../../config/weights.dat", + plugin_config_file="../../../config/plugin_config.yaml", + ) + for subs, value in p.subscriber_cfg.items(): + value["channels"] = sem_lay + value["fusion"] = fusion_alg + p.update() + e = semantic_map.SemanticMap(p) + return e + + +@pytest.mark.parametrize( + "sem_lay, fusion_alg,channels", + [ + (["feat_0", "feat_1"], ["average", "average"], ["feat_0"]), + (["feat_0", "feat_1"], ["average", "average"], []), + (["feat_0", "feat_1", "rgb"], ["average", "average", "color"], ["rgb", "feat_0"],), + (["feat_0", "feat_1", "rgb"], ["class_average", "average", "color"], ["rgb", "feat_0"],), + (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0"],), + (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0", "feat_1"],), + (["feat_0", "feat_1", "rgb"], ["class_bayesian", "class_max", "color"], ["rgb", "feat_0", "feat_1"],), + (["max1", "max2", "rgb"], ["class_max", "class_max", "color"], ["rgb", "max1", "max2"],), + ], +) +def test_fusion_of_pcl(semmap_ex, channels): + fusion = semmap_ex.get_fusion_of_pcl(channels=channels) + assert len(fusion) <= len(channels) + assert len(fusion) > 0 or len(channels) == 0 + assert all(isinstance(item, str) for item in fusion) + + +@pytest.mark.parametrize( + "sem_lay, fusion_alg", [(["feat_0", "feat_1", "rgb"], ["average", "average", "color"]),], +) +@pytest.mark.parametrize("channels", [["rgb"], ["rgb", "feat_0"], []]) +def test_indices_fusion(semmap_ex, channels, fusion_alg): + pcl_indices, layer_indices = semmap_ex.get_indices_fusion(pcl_channels=channels, fusion_alg=fusion_alg[0]) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_filter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_filter.py new file mode 100644 index 00000000..7dfb47c2 --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_filter.py @@ -0,0 +1,100 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp + + +def get_filter_torch(*args, **kwargs): + import torch + import torch.nn as nn + + class TraversabilityFilter(nn.Module): + def __init__(self, w1, w2, w3, w_out, device="cuda", use_bias=False): + super(TraversabilityFilter, self).__init__() + self.conv1 = nn.Conv2d(1, 4, 3, dilation=1, padding=0, bias=use_bias) + self.conv2 = nn.Conv2d(1, 4, 3, dilation=2, padding=0, bias=use_bias) + self.conv3 = nn.Conv2d(1, 4, 3, dilation=3, padding=0, bias=use_bias) + self.conv_out = nn.Conv2d(12, 1, 1, bias=use_bias) + + # Set weights. + self.conv1.weight = nn.Parameter(torch.from_numpy(w1).float()) + self.conv2.weight = nn.Parameter(torch.from_numpy(w2).float()) + self.conv3.weight = nn.Parameter(torch.from_numpy(w3).float()) + self.conv_out.weight = nn.Parameter(torch.from_numpy(w_out).float()) + + def __call__(self, elevation_cupy): + # Convert cupy tensor to pytorch. + elevation_cupy = elevation_cupy.astype(cp.float32) + elevation = torch.as_tensor(elevation_cupy, device=self.conv1.weight.device) + + with torch.no_grad(): + out1 = self.conv1(elevation.view(-1, 1, elevation.shape[0], elevation.shape[1])) + out2 = self.conv2(elevation.view(-1, 1, elevation.shape[0], elevation.shape[1])) + out3 = self.conv3(elevation.view(-1, 1, elevation.shape[0], elevation.shape[1])) + + out1 = out1[:, :, 2:-2, 2:-2] + out2 = out2[:, :, 1:-1, 1:-1] + out = torch.cat((out1, out2, out3), dim=1) + # out = F.concat((out1, out2, out3), axis=1) + out = self.conv_out(out.abs()) + out = torch.exp(-out) + out_cupy = cp.asarray(out) + + return out_cupy + + traversability_filter = TraversabilityFilter(*args, **kwargs).cuda().eval() + return traversability_filter + + +def get_filter_chainer(*args, **kwargs): + import os + + os.environ["CHAINER_WARN_VERSION_MISMATCH"] = "0" + import chainer + import chainer.links as L + import chainer.functions as F + + class TraversabilityFilter(chainer.Chain): + def __init__(self, w1, w2, w3, w_out, use_cupy=True): + super(TraversabilityFilter, self).__init__() + self.conv1 = L.Convolution2D(1, 4, ksize=3, pad=0, dilate=1, nobias=True, initialW=w1) + self.conv2 = L.Convolution2D(1, 4, ksize=3, pad=0, dilate=2, nobias=True, initialW=w2) + self.conv3 = L.Convolution2D(1, 4, ksize=3, pad=0, dilate=3, nobias=True, initialW=w3) + self.conv_out = L.Convolution2D(12, 1, ksize=1, nobias=True, initialW=w_out) + + if use_cupy: + self.conv1.to_gpu() + self.conv2.to_gpu() + self.conv3.to_gpu() + self.conv_out.to_gpu() + chainer.config.train = False + chainer.config.enable_backprop = False + + def __call__(self, elevation): + out1 = self.conv1(elevation.reshape(-1, 1, elevation.shape[0], elevation.shape[1])) + out2 = self.conv2(elevation.reshape(-1, 1, elevation.shape[0], elevation.shape[1])) + out3 = self.conv3(elevation.reshape(-1, 1, elevation.shape[0], elevation.shape[1])) + + out1 = out1[:, :, 2:-2, 2:-2] + out2 = out2[:, :, 1:-1, 1:-1] + out = F.concat((out1, out2, out3), axis=1) + out = self.conv_out(F.absolute(out)) + return F.exp(-out).array + + traversability_filter = TraversabilityFilter(*args, **kwargs) + return traversability_filter + + +if __name__ == "__main__": + import cupy as cp + from parameter import Parameter + + elevation = cp.random.randn(202, 202, dtype=cp.float32) + print("elevation ", elevation.shape) + param = Parameter() + fc = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) + print("chainer ", fc(elevation)) + + ft = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) + print("torch ", ft(elevation)) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_polygon.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_polygon.py new file mode 100644 index 00000000..be874f1b --- /dev/null +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_polygon.py @@ -0,0 +1,77 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import numpy as np +import cupy as cp +from shapely.geometry import Polygon, MultiPoint + + +def get_masked_traversability(map_array, mask, traversability): + traversability = traversability[1:-1, 1:-1] + is_valid = map_array[2][1:-1, 1:-1] + mask = mask[1:-1, 1:-1] + + # invalid place is 0 traversability value + untraversability = cp.where(is_valid > 0.5, 1 - traversability, 0) + masked = untraversability * mask + masked_isvalid = is_valid * mask + return masked, masked_isvalid + + +def is_traversable(masked_untraversability, thresh, min_thresh, max_over_n): + untraversable_thresh = 1 - thresh + max_thresh = 1 - min_thresh + over_thresh = cp.where(masked_untraversability > untraversable_thresh, 1, 0) + polygon = calculate_untraversable_polygon(over_thresh) + max_untraversability = masked_untraversability.max() + if over_thresh.sum() > max_over_n: + is_safe = False + elif max_untraversability > max_thresh: + is_safe = False + else: + is_safe = True + return is_safe, polygon + + +def calculate_area(polygon): + area = 0 + for i in range(len(polygon)): + p1 = polygon[i - 1] + p2 = polygon[i] + area += (p1[0] * p2[1] - p1[1] * p2[0]) / 2.0 + return abs(area) + + +def calculate_untraversable_polygon(over_thresh): + x, y = cp.where(over_thresh > 0.5) + points = cp.stack([x, y]).T + convex_hull = MultiPoint(points.get()).convex_hull + if convex_hull.is_empty or convex_hull.geom_type == "Point" or convex_hull.geom_type == "LineString": + return None + else: + return cp.array(convex_hull.exterior.coords) + + +def transform_to_map_position(polygon, center, cell_n, resolution): + polygon = center.reshape(1, 2) + (polygon - cell_n / 2.0) * resolution + return polygon + + +def transform_to_map_index(points, center, cell_n, resolution): + indices = ((points - center.reshape(1, 2)) / resolution + cell_n / 2).astype(cp.int32) + return indices + + +if __name__ == "__main__": + polygon = [[0, 0], [2, 0], [0, 2]] + print(calculate_area(polygon)) + + under_thresh = cp.zeros((20, 20)) + # under_thresh[10:12, 8:10] = 1.0 + under_thresh[14:18, 8:10] = 1.0 + under_thresh[1:8, 2:9] = 1.0 + print(under_thresh) + polygon = calculate_untraversable_polygon(under_thresh) + print(polygon) + transform_to_map_position(polygon, cp.array([0.5, 1.0]), 6.0, 0.05) diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 17baea09..c9228427 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -1,72 +1,176 @@ -#### Basic parameters ######## -resolution: 0.04 # resolution in m. -map_length: 8.0 # map's size in m. -sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). -mahalanobis_thresh: 2.0 # points outside this distance is outlier. -outlier_variance: 0.01 # if point is outlier, add this value to the cell. -drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. -max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) -drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation -time_variance: 0.0001 # add this value when update_variance is called. -max_variance: 100.0 # maximum variance for each cell. -initial_variance: 1000.0 # initial variance for each cell. -traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. -dilation_size: 3 # dilation filter size before traversability filter. -wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. -min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. -position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. -orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. -position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -min_valid_distance: 0.5 # points with shorter distance will be filtered out. -max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. -ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -update_variance_fps: 5.0 # fps for updating variance. -update_pose_fps: 10.0 # fps for updating pose and shift the center of map. -time_interval: 0.1 # Time layer is updated with this interval. -map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. -publish_statistics_fps: 1.0 # Publish statistics topic in this fps. - -max_ray_length: 10.0 # maximum length for ray tracing. -cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. -cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. - -safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. -safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. -max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. - -overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) -overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - -map_frame: 'odom' # The map frame where the odometry source uses. -base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'odom' - -#### Feature toggles ######## -enable_edge_sharpen: true -enable_visibility_cleanup: true -enable_drift_compensation: true -enable_overlap_clearance: true -enable_pointcloud_publishing: false -enable_drift_corrected_TF_publishing: false -enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. - -#### Traversability filter ######## -use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. -weight_file: '$(rospack find elevation_mapping_cupy)/config/core/weights.dat' # Weight file for traversability filter - -#### Upper bound ######## -use_only_above_for_upper_bound: false - -#### Initializer ######## -initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. -dilation_size_initialize: 2 # dilation size after the init. -initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. -use_initializer_at_start: true # Use initializer when the node starts. - -#### Default Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/core/plugin_config.yaml' \ No newline at end of file +elevation_mapping: + ros__parameters: + #### Basic parameters ######## + resolution: 0.04 # resolution in m. + map_length: 8.0 # map's size in m. + sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). + mahalanobis_thresh: 2.0 # points outside this distance is outlier. + outlier_variance: 0.01 # if point is outlier, add this value to the cell. + drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. + max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) + drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation + time_variance: 0.0001 # add this value when update_variance is called. + max_variance: 100.0 # maximum variance for each cell. + initial_variance: 1000.0 # initial variance for each cell. + traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. + dilation_size: 3 # dilation filter size before traversability filter. + wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. + min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. + position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. + orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. + position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. + orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. + min_valid_distance: 0.5 # points with shorter distance will be filtered out. + max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. + ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + update_variance_fps: 5.0 # fps for updating variance. + update_pose_fps: 10.0 # fps for updating pose and shift the center of map. + time_interval: 0.1 # Time layer is updated with this interval. + map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. + publish_statistics_fps: 1.0 # Publish statistics topic in this fps. + + max_ray_length: 10.0 # maximum length for ray tracing. + cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + + safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. + safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. + max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + + overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) + overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + pose_topic: '/odom' + map_frame: 'base_footprint' # The map frame where the odometry source uses. + base_frame: 'base_link' # The robot's base frame. This frame will be a center of the map. + corrected_map_frame: 'odom' + + + + #### Feature toggles ######## + enable_edge_sharpen: true + enable_visibility_cleanup: true + enable_drift_compensation: true + enable_overlap_clearance: true + enable_pointcloud_publishing: false + enable_drift_corrected_TF_publishing: false + enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + + #### Traversability filter ######## + use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. + weight_file: '/config/core/weights.dat' # Weight file for traversability filter + + #### Upper bound ######## + use_only_above_for_upper_bound: false + + #### Initializer ######## + initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' + initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. + initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. + dilation_size_initialize: 2 # dilation size after the init. + initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. + use_initializer_at_start: true # Use initializer when the node starts. + + #### Default Plugins ######## + + pointcloud_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'average' # 'average' fusion is used for channels not listed here + + image_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'exponential' # 'exponential' fusion is used for channels not listed here + feat_.*: 'exponential' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names + + #### Subscribers ######## + # pointcloud_sensor_name: + # topic_name: '/sensor/pointcloud_semantic' + # data_type: pointcloud # pointcloud or image + # + # image_sensor_name: + # topic_name: '/camera/image_semantic' + # data_type: image # pointcloud or image + # camera_info_topic_name: '/camera/depth/camera_info' + # channel_info_topic_name: '/camera/channel_info' + + subscribers: + pointcloud_topic1: '/a200/sensors/camera_1/points' + + image_topic1: '/a200/sensors/camera_0/color/image' + image_info1: '/a200/sensors/camera_0/color/camera_info' + # image_channel_info1: '/front_cam/channel_info' + + # image_topic2: '/camera/rgb/image_raw2' + # image_info2: '/camera/depth/camera_info2' + # image_channel_info1: '/front_cam/channel_info' + + + + # image: # for semantic images + # topic_name: '/front_cam/semantic_image' + # camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' + # channel_info_topic_name: '/front_cam/channel_info' + # data_type: image + + #### Publishers ######## + # topic_name: + # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names + # basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. + # fps: # Publish rate. Use smaller value than `map_acquire_fps`. + + publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_recordable: + layers: ['elevation', 'traversability'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + basic_layers: ['min_filter'] + fps: 3.0 + + + # plugun info + + min_filter: + enable: True # whether to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # These params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations + + # Apply smoothing. + smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" + + # Apply inpainting using opencv + inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns + + # Apply smoothing for inpainted layer + erosion: + enable: True + fill_nan: False + is_height_layer: False + layer_name: "erosion" + extra_params: + input_layer_name: "traversability" + dilation_size: 3 + iteration_n: 20 + reverse: True \ No newline at end of file diff --git a/elevation_mapping_cupy/config/core/example_setup.yaml b/elevation_mapping_cupy/config/core/example_setup.yaml index a3f7a2f2..2fc0ee84 100644 --- a/elevation_mapping_cupy/config/core/example_setup.yaml +++ b/elevation_mapping_cupy/config/core/example_setup.yaml @@ -1,58 +1,101 @@ -#### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/core/plugin_config.yaml' - -#### Channel Fusions ######## -pointcloud_channel_fusions: - rgb: 'color' # 'color' fusion is used for the 'rgb' channel - default: 'average' # 'average' fusion is used for channels not listed here - -image_channel_fusions: - rgb: 'color' # 'color' fusion is used for the 'rgb' channel - default: 'exponential' # 'exponential' fusion is used for channels not listed here - feat_.*: 'exponential' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names - -#### Subscribers ######## -# pointcloud_sensor_name: -# topic_name: '/sensor/pointcloud_semantic' -# data_type: pointcloud # pointcloud or image -# -# image_sensor_name: -# topic_name: '/camera/image_semantic' -# data_type: image # pointcloud or image -# camera_info_topic_name: '/camera/depth/camera_info' -# channel_info_topic_name: '/camera/channel_info' - - -subscribers: - front_cam: - topic_name: '/camera/depth/points' - data_type: pointcloud - color_cam: # for color camera - topic_name: '/camera/rgb/image_raw' - camera_info_topic_name: '/camera/depth/camera_info' - data_type: image - semantic_cam: # for semantic images - topic_name: '/front_cam/semantic_image' - camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' - channel_info_topic_name: '/front_cam/channel_info' - data_type: image - -#### Publishers ######## -# topic_name: -# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names -# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. -# fps: # Publish rate. Use smaller value than `map_acquire_fps`. - -publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb'] - basic_layers: ['elevation'] - fps: 5.0 - elevation_map_recordable: - layers: ['elevation', 'traversability'] - basic_layers: ['elevation', 'traversability'] - fps: 2.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] - basic_layers: ['min_filter'] - fps: 3.0 \ No newline at end of file +elevation_mapping: + ros__parameters: + #### Plugins ######## + plugin_config_file: '$(find_package_share elevation_mapping_cupy)/config/core/plugin_config.yaml' + + #### Channel Fusions ######## + pointcloud_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'average' # 'average' fusion is used for channels not listed here + + image_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'exponential' # 'exponential' fusion is used for channels not listed here + feat_.*: 'exponential' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names + + #### Subscribers ######## + # pointcloud_sensor_name: + # topic_name: '/sensor/pointcloud_semantic' + # data_type: pointcloud # pointcloud or image + # + # image_sensor_name: + # topic_name: '/camera/image_semantic' + # data_type: image # pointcloud or image + # camera_info_topic_name: '/camera/depth/camera_info' + # channel_info_topic_name: '/camera/channel_info' + + subscribers: + front_cam: + topic_name: '/camera/depth/points' + data_type: pointcloud + color_cam: # for color camera + topic_name: '/camera/rgb/image_raw' + camera_info_topic_name: '/camera/depth/camera_info' + data_type: image + semantic_cam: # for semantic images + topic_name: '/front_cam/semantic_image' + camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' + channel_info_topic_name: '/front_cam/channel_info' + data_type: image + + #### Publishers ######## + # topic_name: + # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names + # basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. + # fps: # Publish rate. Use smaller value than `map_acquire_fps`. + + publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_recordable: + layers: ['elevation', 'traversability'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + basic_layers: ['min_filter'] + fps: 3.0 + + +# plugun info + + min_filter: + enable: True # whether to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # These params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations + + # Apply smoothing. + smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" + + # Apply inpainting using opencv + inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns + + # Apply smoothing for inpainted layer + erosion: + enable: True + fill_nan: False + is_height_layer: False + layer_name: "erosion" + extra_params: + input_layer_name: "traversability" + dilation_size: 3 + iteration_n: 20 + reverse: True \ No newline at end of file diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index f631fbba..18fd4eaf 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -26,8 +26,11 @@ #include #include #include -#include "std_srvs/srv/empty.h" +#include #include +#include +#include +#include #include #include @@ -58,46 +61,50 @@ namespace py = pybind11; -// namespace elevation_mapping_cupy { - -// class ElevationMappingNode { -// public: -// ElevationMappingNode(ros::NodeHandle& nh); -// using RowMatrixXd = Eigen::Matrix; -// using ColMatrixXf = Eigen::Matrix; - -// using ImageSubscriber = image_transport::SubscriberFilter; -// using ImageSubscriberPtr = std::shared_ptr; - -// // Subscriber and Synchronizer for CameraInfo messages -// using CameraInfoSubscriber = message_filters::Subscriber; -// using CameraInfoSubscriberPtr = std::shared_ptr; -// using CameraPolicy = message_filters::sync_policies::ApproximateTime; -// using CameraSync = message_filters::Synchronizer; -// using CameraSyncPtr = std::shared_ptr; - -// // Subscriber and Synchronizer for ChannelInfo messages -// using ChannelInfoSubscriber = message_filters::Subscriber; -// using ChannelInfoSubscriberPtr = std::shared_ptr; -// using CameraChannelPolicy = message_filters::sync_policies::ApproximateTime; -// using CameraChannelSync = message_filters::Synchronizer; -// using CameraChannelSyncPtr = std::shared_ptr; - -// // Subscriber and Synchronizer for Pointcloud messages -// using PointCloudSubscriber = message_filters::Subscriber; -// using PointCloudSubscriberPtr = std::shared_ptr; -// using PointCloudPolicy = message_filters::sync_policies::ApproximateTime; -// using PointCloudSync = message_filters::Synchronizer; -// using PointCloudSyncPtr = std::shared_ptr; - -// private: -// void readParameters(); +namespace elevation_mapping_cupy { + +class ElevationMappingNode : public rclcpp::Node { + public: + ElevationMappingNode(); + using RowMatrixXd = Eigen::Matrix; + using ColMatrixXf = Eigen::Matrix; + + // using ImageSubscriber = image_transport::SubscriberFilter; + using ImageSubscriber = message_filters::Subscriber; + using ImageSubscriberPtr = std::shared_ptr; + + // Subscriber and Synchronizer for CameraInfo messages + using CameraInfoSubscriber = message_filters::Subscriber; + using CameraInfoSubscriberPtr = std::shared_ptr; + using CameraPolicy = message_filters::sync_policies::ApproximateTime; + using CameraSync = message_filters::Synchronizer; + using CameraSyncPtr = std::shared_ptr; + + // Subscriber and Synchronizer for ChannelInfo messages + using ChannelInfoSubscriber = message_filters::Subscriber; + using ChannelInfoSubscriberPtr = std::shared_ptr; + using CameraChannelPolicy = message_filters::sync_policies::ApproximateTime; + using CameraChannelSync = message_filters::Synchronizer; + using CameraChannelSyncPtr = std::shared_ptr; + + // Subscriber and Synchronizer for Pointcloud messages + using PointCloudSubscriber = message_filters::Subscriber; + using PointCloudSubscriberPtr = std::shared_ptr; + using PointCloudPolicy = message_filters::sync_policies::ApproximateTime; + using PointCloudSync = message_filters::Synchronizer; + using PointCloudSyncPtr = std::shared_ptr; + + private: + void readParameters(); // void setupMapPublishers(); -// void pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key); -// void inputPointCloud(const sensor_msgs::PointCloud2& cloud, const std::vector& channels); + void pointcloudCallback(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::string& key); + void inputPointCloud(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::vector& channels); // void inputImage(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::vector& channels); -// void imageCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::string& key); -// void imageChannelCallback(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg); +// void imageCallback(const sensor_msgs::msg::Image::SharedPtr image_msg, const sensor_msgs::msg::CameraInfo::SharedPtr camera_info_msg, const std::string& key); +// void imageChannelCallback(const sensor_msgs::msg::Image::SharedPtr image_msg, const sensor_msgs::msg::CameraInfo::SharedPtr camera_info_msg, const elevation_map_msgs::msg::ChannelInfo::SharedPtr channel_info_msg); +void imageCallback(const std::shared_ptr& image_msg, const std::shared_ptr& camera_info_msg, const std::string& key); +void imageChannelCallback(const std::shared_ptr& image_msg, const std::shared_ptr& camera_info_msg, const std::shared_ptr& channel_info_msg); + // void pointCloudChannelCallback(const sensor_msgs::PointCloud2& cloud, const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg); // // void multiLayerImageCallback(const elevation_map_msgs::MultiLayerImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg); // void publishAsPointCloud(const grid_map::GridMap& map) const; @@ -118,77 +125,86 @@ namespace py = pybind11; // void publishMapOfIndex(int index); // visualization_msgs::Marker vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id) const; - -// ros::NodeHandle nh_; -// image_transport::ImageTransport it_; -// std::vector pointcloudSubs_; -// std::vector imageSubs_; -// std::vector cameraInfoSubs_; -// std::vector channelInfoSubs_; -// std::vector cameraSyncs_; -// std::vector cameraChannelSyncs_; -// std::vector pointCloudSyncs_; -// std::vector mapPubs_; -// tf::TransformBroadcaster tfBroadcaster_; -// ros::Publisher alivePub_; -// ros::Publisher pointPub_; -// ros::Publisher normalPub_; -// ros::Publisher statisticsPub_; -// ros::ServiceServer rawSubmapService_; -// ros::ServiceServer clearMapService_; -// ros::ServiceServer clearMapWithInitializerService_; -// ros::ServiceServer initializeMapService_; -// ros::ServiceServer setPublishPointService_; -// ros::ServiceServer checkSafetyService_; -// ros::Timer updateVarianceTimer_; -// ros::Timer updateTimeTimer_; -// ros::Timer updatePoseTimer_; -// ros::Timer updateGridMapTimer_; -// ros::Timer publishStatisticsTimer_; -// ros::Time lastStatisticsPublishedTime_; -// tf::TransformListener transformListener_; -// ElevationMappingWrapper map_; -// std::string mapFrameId_; -// std::string correctedMapFrameId_; -// std::string baseFrameId_; - -// // map topics info -// std::vector> map_topics_; -// std::vector> map_layers_; -// std::vector> map_basic_layers_; -// std::set map_layers_all_; -// std::set map_layers_sync_; -// std::vector map_fps_; -// std::set map_fps_unique_; -// std::vector mapTimers_; -// std::map> channels_; - -// std::vector initialize_frame_id_; -// std::vector initialize_tf_offset_; -// std::string initializeMethod_; - -// Eigen::Vector3d lowpassPosition_; -// Eigen::Vector4d lowpassOrientation_; - -// std::mutex mapMutex_; // protects gridMap_ -// grid_map::GridMap gridMap_; -// std::atomic_bool isGridmapUpdated_; // needs to be atomic (read is not protected by mapMutex_) - -// std::mutex errorMutex_; // protects positionError_, and orientationError_ -// double positionError_; -// double orientationError_; - -// double positionAlpha_; -// double orientationAlpha_; - -// double recordableFps_; -// std::atomic_bool enablePointCloudPublishing_; -// bool enableNormalArrowPublishing_; -// bool enableDriftCorrectedTFPublishing_; -// bool useInitializerAtStart_; -// double initializeTfGridSize_; -// bool alwaysClearWithInitializer_; -// std::atomic_int pointCloudProcessCounter_; -// }; - -// } // namespace elevation_mapping_cupy + + rclcpp::Node::SharedPtr node_; + // image_transport::ImageTransport it_; + std::vector::SharedPtr> pointcloudSubs_; + std::vector imageSubs_; + std::vector cameraInfoSubs_; + std::vector channelInfoSubs_; + std::vector cameraSyncs_; + std::vector cameraChannelSyncs_; + std::vector pointCloudSyncs_; + std::vector::SharedPtr> mapPubs_; + + + std::shared_ptr tfBroadcaster_; + std::shared_ptr tfListener_; + std::shared_ptr tfBuffer_; + + + rclcpp::Publisher::SharedPtr alivePub_; + rclcpp::Publisher::SharedPtr pointPub_; + rclcpp::Publisher::SharedPtr normalPub_; + rclcpp::Publisher::SharedPtr statisticsPub_; + rclcpp::Service::SharedPtr rawSubmapService_; + rclcpp::Service::SharedPtr clearMapService_; + rclcpp::Service::SharedPtr clearMapWithInitializerService_; + rclcpp::Service::SharedPtr initializeMapService_; + rclcpp::Service::SharedPtr setPublishPointService_; + rclcpp::Service::SharedPtr checkSafetyService_; + rclcpp::TimerBase::SharedPtr updateVarianceTimer_; + rclcpp::TimerBase::SharedPtr updateTimeTimer_; + rclcpp::TimerBase::SharedPtr updatePoseTimer_; + rclcpp::TimerBase::SharedPtr updateGridMapTimer_; + rclcpp::TimerBase::SharedPtr publishStatisticsTimer_; + rclcpp::Time lastStatisticsPublishedTime_; + + + std::shared_ptr map_; + // ElevationMappingWrapper map_; + std::string mapFrameId_; + std::string correctedMapFrameId_; + std::string baseFrameId_; + + + // map topics info + std::vector> map_topics_; + std::vector> map_layers_; + std::vector> map_basic_layers_; + std::set map_layers_all_; + std::set map_layers_sync_; + std::vector map_fps_; + std::set map_fps_unique_; + std::vector mapTimers_; + std::map> channels_; + + std::vector initialize_frame_id_; + std::vector initialize_tf_offset_; + std::string initializeMethod_; + + Eigen::Vector3d lowpassPosition_; + Eigen::Vector4d lowpassOrientation_; + + std::mutex mapMutex_; // protects gridMap_ + grid_map::GridMap gridMap_; + std::atomic_bool isGridmapUpdated_; // needs to be atomic (read is not protected by mapMutex_) + + std::mutex errorMutex_; // protects positionError_, and orientationError_ + double positionError_; + double orientationError_; + + double positionAlpha_; + double orientationAlpha_; + + double recordableFps_; + std::atomic_bool enablePointCloudPublishing_; + bool enableNormalArrowPublishing_; + bool enableDriftCorrectedTFPublishing_; + bool useInitializerAtStart_; + double initializeTfGridSize_; + bool alwaysClearWithInitializer_; + std::atomic_int pointCloudProcessCounter_; +}; + +} // namespace elevation_mapping_cupy diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index 92370e3c..0623d0f6 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -43,9 +43,9 @@ class ElevationMappingWrapper { using RowMatrixXf = Eigen::Matrix; using ColMatrixXf = Eigen::Matrix; - ElevationMappingWrapper(); + ElevationMappingWrapper(rclcpp::Node::SharedPtr node); - void initialize(rclcpp::Node::SharedPtr node); + void initialize(); void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); @@ -63,9 +63,11 @@ class ElevationMappingWrapper { double get_additive_mean_error(); void initializeWithPoints(std::vector& points, std::string method); void addNormalColorLayer(grid_map::GridMap& map); - - private: - void setParameters(rclcpp::Node::SharedPtr node); + + private: + rclcpp::Node::SharedPtr node_; + py::object setParameters(); + py::object map_; py::object param_; double resolution_; diff --git a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch deleted file mode 100644 index b0fb53c9..00000000 --- a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py new file mode 100644 index 00000000..db110a12 --- /dev/null +++ b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py @@ -0,0 +1,28 @@ +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch_ros.actions import Node +import launch_ros.actions + +def generate_launch_description(): + core_param_file = os.path.join( + get_package_share_directory('elevation_mapping_cupy'), + 'config', + 'core', + 'core_param.yaml' + ) + + + return LaunchDescription([ + launch_ros.actions.SetParameter(name='use_sim_time', value=True), + Node( + package='elevation_mapping_cupy', + executable='elevation_mapping_node', + name='elevation_mapping', + output='screen', + parameters=[core_param_file], + # arguments=['--ros-args', '--log-level', 'DEBUG'] + ) + ]) \ No newline at end of file diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index 9cb9c1bb..c1395b61 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -9,11 +9,13 @@ MIT ament_cmake + ament_cmake_python rclcpp std_msgs std_srvs sensor_msgs geometry_msgs + message_filters grid_map_msgs elevation_map_msgs diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py index a16e894d..88d6a666 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/__init__.py @@ -1,2 +1,4 @@ -from .parameter import Parameter -from .elevation_mapping import ElevationMap +# from .parameter import Parameter +# from .elevation_mapping import ElevationMap +# from .kernels import custom_image_kernels, custom_kernels, custom_semantic_kernels + diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index b78aeb45..4d704739 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -15,6 +15,7 @@ ) from elevation_mapping_cupy.parameter import Parameter + from elevation_mapping_cupy.kernels import ( add_points_kernel, add_color_kernel, @@ -932,11 +933,12 @@ def initialize_map(self, points, method="cubic"): print(R, t) param = Parameter( use_chainer=False, - weight_file="../config/weights.dat", - plugin_config_file="../config/plugin_config.yaml", + weight_file="/home/hojin/new_elev/src/elevation_mapping_cupy/elevation_mapping_cupy/config/core/weights.dat", + plugin_config_file="/home/hojin/new_elev/src/elevation_mapping_cupy/elevation_mapping_cupy/config/core/plugin_config.yaml", ) param.additional_layers = ["rgb", "grass", "tree", "people"] - param.fusion_algorithms = ["color", "class_bayesian", "class_bayesian", "class_bayesian"] + # param.fusion_algorithms = ["color", "class_bayesian", "class_bayesian", "class_bayesian"] + param.fusion_algorithms = ["image_color", "pointcloud_color", "pointcloud_class_average"] param.update() elevation = ElevationMap(param) layers = [ diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py index c28823e9..94cc1e5c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping_ros.py @@ -1,287 +1,322 @@ -from elevation_mapping_cupy import ElevationMap -from elevation_mapping_cupy import Parameter - -# General -import os -import numpy as np - -# ROS -import rospy -import ros_numpy -from tf.transformations import quaternion_matrix -import tf2_ros -import rospkg -import message_filters -from cv_bridge import CvBridge - -from sensor_msgs.msg import PointCloud2, Image, CameraInfo -from grid_map_msgs.msg import GridMap -from std_msgs.msg import Float32MultiArray -from std_msgs.msg import MultiArrayLayout as MAL -from std_msgs.msg import MultiArrayDimension as MAD - -import numpy as np -from functools import partial - -PDC_DATATYPE = { - "1": np.int8, - "2": np.uint8, - "3": np.int16, - "4": np.uint16, - "5": np.int32, - "6": np.uint32, - "7": np.float32, - "8": np.float64, -} - - -class ElevationMapWrapper: - def __init__(self): - rospack = rospkg.RosPack() - self.root = rospack.get_path("elevation_mapping_cupy") - weight_file = os.path.join(self.root, "config/core/weights.dat") - plugin_config_file = os.path.join(self.root, "config/core/plugin_config.yaml") - self.param = Parameter(use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file) - - self.node_name = "elevation_mapping" - - # ROS - self.initalize_ros() - self.param.subscriber_cfg = self.subscribers - - self.initalize_elevation_mapping() - self.register_subscribers() - self.register_publishers() - self.register_timers() - - self._last_t = None - - def initalize_elevation_mapping(self): - self.param.update() - # TODO add statistics across processed topics - self._pointcloud_process_counter = 0 - self._image_process_counter = 0 - self._map = ElevationMap(self.param) - self._map_data = np.zeros((self._map.cell_n - 2, self._map.cell_n - 2), dtype=np.float32) - self._map_q = None - self._map_t = None - - def initalize_ros(self): - rospy.init_node(self.node_name, anonymous=False) - self._tf_buffer = tf2_ros.Buffer() - self._listener = tf2_ros.TransformListener(self._tf_buffer) - self.get_ros_params() - - def register_subscribers(self): - # check if CV bridge is needed - for config in self.param.subscriber_cfg.values(): - if config["data_type"] == "image": - self.cv_bridge = CvBridge() - break - - pointcloud_subs = {} - image_subs = {} - for key, config in self.subscribers.items(): - if config["data_type"] == "image": - camera_sub = message_filters.Subscriber(config["topic_name_camera"], Image) - camera_info_sub = message_filters.Subscriber(config["topic_name_camera_info"], CameraInfo) - image_subs[key] = message_filters.ApproximateTimeSynchronizer( - [camera_sub, camera_info_sub], queue_size=10, slop=0.5 - ) - image_subs[key].registerCallback(self.image_callback, key) - - elif config["data_type"] == "pointcloud": - pointcloud_subs[key] = rospy.Subscriber( - config["topic_name"], PointCloud2, self.pointcloud_callback, key - ) - - def register_publishers(self): - self._publishers = {} - self._publishers_timers = [] - for k, v in self.publishers.items(): - self._publishers[k] = rospy.Publisher(f"/{self.node_name}/{k}", GridMap, queue_size=10) - # partial(.) allows to pass a default argument to a callback - self._publishers_timers.append(rospy.Timer(rospy.Duration(1 / v["fps"]), partial(self.publish_map, k))) - - def publish_map(self, k, t): - print("publish_map") - if self._map_q is None: - return - gm = GridMap() - gm.info.header.frame_id = self.map_frame - gm.info.header.stamp = rospy.Time.now() - gm.info.header.seq = 0 - gm.info.resolution = self._map.resolution - gm.info.length_x = self._map.map_length - gm.info.length_y = self._map.map_length - gm.info.pose.position.x = self._map_t.x - gm.info.pose.position.y = self._map_t.y - gm.info.pose.position.z = 0.0 - gm.info.pose.orientation.w = 1.0 # self._map_q.w - gm.info.pose.orientation.x = 0.0 # self._map_q.x - gm.info.pose.orientation.y = 0.0 # self._map_q.y - gm.info.pose.orientation.z = 0.0 # self._map_q.z - gm.layers = [] - gm.basic_layers = self.publishers[k]["basic_layers"] - for i, layer in enumerate(self.publishers[k]["layers"]): - gm.layers.append(layer) - try: - self._map.get_map_with_name_ref(layer, self._map_data) - data = self._map_data.copy() - arr = Float32MultiArray() - arr.layout = MAL() - N = self._map_data.shape[0] - arr.layout.dim.append(MAD(label="column_index", size=N, stride=int(N * N))) - arr.layout.dim.append(MAD(label="row_index", size=N, stride=N)) - arr.data = tuple(np.ascontiguousarray(data.T).reshape(-1)) - gm.data.append(arr) - except: - if layer in gm.basic_layers: - print("Error: Missed Layer in basic layers") - - gm.outer_start_index = 0 - gm.inner_start_index = 0 - - self._publishers[k].publish(gm) - - def register_timers(self): - self.timer_variance = rospy.Timer(rospy.Duration(1 / self.update_variance_fps), self.update_variance) - self.timer_pose = rospy.Timer(rospy.Duration(1 / self.update_pose_fps), self.update_pose) - self.timer_time = rospy.Timer(rospy.Duration(self.time_interval), self.update_time) - - def image_callback(self, camera_msg, camera_info_msg, sub_key): - # get pose of image - ti = rospy.Time(secs=camera_msg.header.stamp.secs, nsecs=camera_msg.header.stamp.nsecs) - self._last_t = ti - try: - transform = self._tf_buffer.lookup_transform( - camera_msg.header.frame_id, self.map_frame, ti, rospy.Duration(1.0) - ) - except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - print("Error: image_callback:", e) - return - - t = transform.transform.translation - t = np.array([t.x, t.y, t.z]) - q = transform.transform.rotation - R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] - - semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") - - if len(semantic_img.shape) != 2: - semantic_img = [semantic_img[:, :, k] for k in range(3)] - - else: - semantic_img = [semantic_img] - - K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) - - assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" - D = np.array(camera_info_msg.D, dtype=np.float32).reshape(5, 1) +# # General +# import os +# import numpy as np +# import yaml + +# from elevation_mapping_cupy import ElevationMap, Parameter + + + +# # ROS2 +# import rclpy +# from rclpy.node import Node +# from tf_transformations import quaternion_matrix +# import tf2_ros +# from ament_index_python.packages import get_package_share_directory +# from cv_bridge import CvBridge + +# from sensor_msgs.msg import PointCloud2, Image, CameraInfo +# from grid_map_msgs.msg import GridMap +# from std_msgs.msg import Float32MultiArray, MultiArrayLayout as MAL, MultiArrayDimension as MAD + +# from functools import partial +# import message_filters + + +# PDC_DATATYPE = { +# "1": np.int8, +# "2": np.uint8, +# "3": np.int16, +# "4": np.uint16, +# "5": np.int32, +# "6": np.uint32, +# "7": np.float32, +# "8": np.float64, +# } + + +# class ElevationMapWrapper(Node): +# def __init__(self): +# super().__init__('elevation_mapping') +# self.node_name = "elevation_mapping" +# self.root = get_package_share_directory("elevation_mapping_cupy") +# weight_file = os.path.join(self.root, "config/core/weights.dat") +# plugin_config_file = os.path.join(self.root, "config/core/plugin_config.yaml") +# self.param = Parameter(use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file) - # process pointcloud - self._map.input_image(sub_key, semantic_img, R, t, K, D, camera_info_msg.height, camera_info_msg.width) - self._image_process_counter += 1 - - def pointcloud_callback(self, msg, sub_key): - channels = ["x", "y", "z"] + self.param.subscriber_cfg[sub_key]["channels"] - - points = ros_numpy.numpify(msg) - pts = np.empty((points.shape[0], 0)) - for ch in channels: - p = points[ch] - if len(p.shape) == 1: - p = p[:, None] - pts = np.append(pts, p, axis=1) - - # get pose of pointcloud - ti = rospy.Time(secs=msg.header.stamp.secs, nsecs=msg.header.stamp.nsecs) - self._last_t = ti - try: - transform = self._tf_buffer.lookup_transform(self.map_frame, msg.header.frame_id, ti, rospy.Duration(1.0)) - except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - print("Error: pointcloud_callback: ", e) - return - - t = transform.transform.translation - t = np.array([t.x, t.y, t.z]) - q = transform.transform.rotation - R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] - - # process pointcloud - self._map.input(pts, channels, R, t, 0, 0) - self._pointcloud_process_counter += 1 - print("Pointclouds processed: ", self._pointcloud_process_counter) - - def update_pose(self, t): - # get pose of base - # t = rospy.Time.now() - if self._last_t is None: - return - try: - transform = self._tf_buffer.lookup_transform( - self.map_frame, self.base_frame, self._last_t, rospy.Duration(1.0) - ) - except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - print("Error: update_pose error: ", e) - return - t = transform.transform.translation - trans = np.array([t.x, t.y, t.z]) - q = transform.transform.rotation - rot = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] - self._map.move_to(trans, rot) - - self._map_t = t - self._map_q = q - - def update_variance(self, t): - self._map.update_variance() - - def update_time(self, t): - self._map.update_time() - - def get_ros_params(self): - # TODO fix this here when later launching with launch-file - # This is currently {p} elevation_mapping") - typ = "sim" - para = os.path.join(self.root, f"config/{typ}_parameters.yaml") - sens = os.path.join(self.root, f"config/{typ}_sensor_parameter.yaml") - plugin = os.path.join(self.root, f"config/{typ}_plugin_config.yaml") - - os.system(f"rosparam delete /{self.node_name}") - os.system(f"rosparam load {para} elevation_mapping") - os.system(f"rosparam load {sens} elevation_mapping") - os.system(f"rosparam load {plugin} elevation_mapping") - - self.subscribers = rospy.get_param("~subscribers") - self.publishers = rospy.get_param("~publishers") - self.initialize_frame_id = rospy.get_param("~initialize_frame_id", "base") - self.initialize_tf_offset = rospy.get_param("~initialize_tf_offset", 0.0) - self.pose_topic = rospy.get_param("~pose_topic", "pose") - self.map_frame = rospy.get_param("~map_frame", "map") - self.base_frame = rospy.get_param("~base_frame", "base") - self.corrected_map_frame = rospy.get_param("~corrected_map_frame", "corrected_map") - self.initialize_method = rospy.get_param("~initialize_method", "cubic") - self.position_lowpass_alpha = rospy.get_param("~position_lowpass_alpha", 0.2) - self.orientation_lowpass_alpha = rospy.get_param("~orientation_lowpass_alpha", 0.2) - self.recordable_fps = rospy.get_param("~recordable_fps", 3.0) - self.update_variance_fps = rospy.get_param("~update_variance_fps", 1.0) - self.time_interval = rospy.get_param("~time_interval", 0.1) - self.update_pose_fps = rospy.get_param("~update_pose_fps", 10.0) - self.initialize_tf_grid_size = rospy.get_param("~initialize_tf_grid_size", 0.5) - self.map_acquire_fps = rospy.get_param("~map_acquire_fps", 5.0) - self.publish_statistics_fps = rospy.get_param("~publish_statistics_fps", 1.0) - self.enable_pointcloud_publishing = rospy.get_param("~enable_pointcloud_publishing", False) - self.enable_normal_arrow_publishing = rospy.get_param("~enable_normal_arrow_publishing", False) - self.enable_drift_corrected_TF_publishing = rospy.get_param("~enable_drift_corrected_TF_publishing", False) - self.use_initializer_at_start = rospy.get_param("~use_initializer_at_start", False) - - -if __name__ == "__main__": - emw = ElevationMapWrapper() - - while not rospy.is_shutdown(): - try: - rospy.spin() - except rospy.ROSInterruptException: - print("Error") +# # ROS2 +# self.initialize_ros() +# self.param.subscriber_cfg = self.subscribers + +# self.initialize_elevation_mapping() +# # self.register_subscribers() +# # self.register_publishers() +# # self.register_timers() + +# self._last_t = None + + + + +# # # ROS +# # self.initalize_ros() +# # self.param.subscriber_cfg = self.subscribers + + +# def initialize_ros(self): +# self._tf_buffer = tf2_ros.Buffer() +# self._listener = tf2_ros.TransformListener(self._tf_buffer, self) +# self.get_ros_params() + + +# def initialize_elevation_mapping(self): +# self.param.update() +# # TODO add statistics across processed topics +# self._pointcloud_process_counter = 0 +# self._image_process_counter = 0 +# self._map = ElevationMap(self.param) +# self._map_data = np.zeros((self._map.cell_n - 2, self._map.cell_n - 2), dtype=np.float32) +# self._map_q = None +# self._map_t = None + + + + +# # def register_subscribers(self): +# # # check if CV bridge is needed +# # for config in self.param.subscriber_cfg.values(): +# # if config["data_type"] == "image": +# # self.cv_bridge = CvBridge() +# # break + +# # pointcloud_subs = {} +# # image_subs = {} +# # for key, config in self.subscribers.items(): +# # if config["data_type"] == "image": +# # camera_sub = message_filters.Subscriber(config["topic_name_camera"], Image) +# # camera_info_sub = message_filters.Subscriber(config["topic_name_camera_info"], CameraInfo) +# # image_subs[key] = message_filters.ApproximateTimeSynchronizer( +# # [camera_sub, camera_info_sub], queue_size=10, slop=0.5 +# # ) +# # image_subs[key].registerCallback(self.image_callback, key) + +# # elif config["data_type"] == "pointcloud": +# # pointcloud_subs[key] = rospy.Subscriber( +# # config["topic_name"], PointCloud2, self.pointcloud_callback, key +# # ) + +# # def register_publishers(self): +# # self._publishers = {} +# # self._publishers_timers = [] +# # for k, v in self.publishers.items(): +# # self._publishers[k] = rospy.Publisher(f"/{self.node_name}/{k}", GridMap, queue_size=10) +# # # partial(.) allows to pass a default argument to a callback +# # self._publishers_timers.append(rospy.Timer(rospy.Duration(1 / v["fps"]), partial(self.publish_map, k))) + +# # def publish_map(self, k, t): +# # print("publish_map") +# # if self._map_q is None: +# # return +# # gm = GridMap() +# # gm.info.header.frame_id = self.map_frame +# # gm.info.header.stamp = rospy.Time.now() +# # gm.info.header.seq = 0 +# # gm.info.resolution = self._map.resolution +# # gm.info.length_x = self._map.map_length +# # gm.info.length_y = self._map.map_length +# # gm.info.pose.position.x = self._map_t.x +# # gm.info.pose.position.y = self._map_t.y +# # gm.info.pose.position.z = 0.0 +# # gm.info.pose.orientation.w = 1.0 # self._map_q.w +# # gm.info.pose.orientation.x = 0.0 # self._map_q.x +# # gm.info.pose.orientation.y = 0.0 # self._map_q.y +# # gm.info.pose.orientation.z = 0.0 # self._map_q.z +# # gm.layers = [] +# # gm.basic_layers = self.publishers[k]["basic_layers"] +# # for i, layer in enumerate(self.publishers[k]["layers"]): +# # gm.layers.append(layer) +# # try: +# # self._map.get_map_with_name_ref(layer, self._map_data) +# # data = self._map_data.copy() +# # arr = Float32MultiArray() +# # arr.layout = MAL() +# # N = self._map_data.shape[0] +# # arr.layout.dim.append(MAD(label="column_index", size=N, stride=int(N * N))) +# # arr.layout.dim.append(MAD(label="row_index", size=N, stride=N)) +# # arr.data = tuple(np.ascontiguousarray(data.T).reshape(-1)) +# # gm.data.append(arr) +# # except: +# # if layer in gm.basic_layers: +# # print("Error: Missed Layer in basic layers") + +# # gm.outer_start_index = 0 +# # gm.inner_start_index = 0 + +# # self._publishers[k].publish(gm) + +# # def register_timers(self): +# # self.timer_variance = rospy.Timer(rospy.Duration(1 / self.update_variance_fps), self.update_variance) +# # self.timer_pose = rospy.Timer(rospy.Duration(1 / self.update_pose_fps), self.update_pose) +# # self.timer_time = rospy.Timer(rospy.Duration(self.time_interval), self.update_time) + +# # def image_callback(self, camera_msg, camera_info_msg, sub_key): +# # # get pose of image +# # ti = rospy.Time(secs=camera_msg.header.stamp.secs, nsecs=camera_msg.header.stamp.nsecs) +# # self._last_t = ti +# # try: +# # transform = self._tf_buffer.lookup_transform( +# # camera_msg.header.frame_id, self.map_frame, ti, rospy.Duration(1.0) +# # ) +# # except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: +# # print("Error: image_callback:", e) +# # return + +# # t = transform.transform.translation +# # t = np.array([t.x, t.y, t.z]) +# # q = transform.transform.rotation +# # R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] + +# # semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") + +# # if len(semantic_img.shape) != 2: +# # semantic_img = [semantic_img[:, :, k] for k in range(3)] + +# # else: +# # semantic_img = [semantic_img] + +# # K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) + +# # assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" +# # D = np.array(camera_info_msg.D, dtype=np.float32).reshape(5, 1) + +# # # process pointcloud +# # self._map.input_image(sub_key, semantic_img, R, t, K, D, camera_info_msg.height, camera_info_msg.width) +# # self._image_process_counter += 1 + +# # def pointcloud_callback(self, msg, sub_key): +# # channels = ["x", "y", "z"] + self.param.subscriber_cfg[sub_key]["channels"] + +# # points = ros_numpy.numpify(msg) +# # pts = np.empty((points.shape[0], 0)) +# # for ch in channels: +# # p = points[ch] +# # if len(p.shape) == 1: +# # p = p[:, None] +# # pts = np.append(pts, p, axis=1) + +# # # get pose of pointcloud +# # ti = rospy.Time(secs=msg.header.stamp.secs, nsecs=msg.header.stamp.nsecs) +# # self._last_t = ti +# # try: +# # transform = self._tf_buffer.lookup_transform(self.map_frame, msg.header.frame_id, ti, rospy.Duration(1.0)) +# # except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: +# # print("Error: pointcloud_callback: ", e) +# # return + +# # t = transform.transform.translation +# # t = np.array([t.x, t.y, t.z]) +# # q = transform.transform.rotation +# # R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] + +# # # process pointcloud +# # self._map.input(pts, channels, R, t, 0, 0) +# # self._pointcloud_process_counter += 1 +# # print("Pointclouds processed: ", self._pointcloud_process_counter) + +# # def update_pose(self, t): +# # # get pose of base +# # # t = rospy.Time.now() +# # if self._last_t is None: +# # return +# # try: +# # transform = self._tf_buffer.lookup_transform( +# # self.map_frame, self.base_frame, self._last_t, rospy.Duration(1.0) +# # ) +# # except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: +# # print("Error: update_pose error: ", e) +# # return +# # t = transform.transform.translation +# # trans = np.array([t.x, t.y, t.z]) +# # q = transform.transform.rotation +# # rot = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] +# # self._map.move_to(trans, rot) + +# # self._map_t = t +# # self._map_q = q + +# # def update_variance(self, t): +# # self._map.update_variance() + +# # def update_time(self, t): +# # self._map.update_time() + + + +# def declare_parameters_from_yaml(self, yaml_file): +# def declare_nested_parameters(parent_name, param_dict): +# for sub_name, sub_value in param_dict.items(): +# full_param_name = f"{parent_name}.{sub_name}" + +# if isinstance(sub_value, dict): +# declare_nested_parameters(full_param_name, sub_value) +# else: +# if "elevation_mapping.ros__parameters" in full_param_name: +# full_param_name = full_param_name.replace("elevation_mapping.ros__parameters.", "") +# self.declare_parameter(full_param_name, sub_value) + +# with open(yaml_file, 'r') as file: +# params = yaml.safe_load(file) + +# # Set parameters in the node +# for param_name, param_value in params.items(): +# if isinstance(param_value, dict): +# # For nested dictionaries, set each nested parameter individually +# declare_nested_parameters(param_name, param_value) +# else: +# # For top-level parameters +# if "elevation_mapping.ros__parameters" in param_name: +# param_name = param_name.replace("elevation_mapping.ros__parameters.", "") +# self.declare_parameter(param_name, param_value) + + + + +# def get_ros_params(self): +# # TODO fix this here when later launching with launch-file +# # This is currently {p} elevation_mapping") +# param_file = os.path.join(self.root, f"config/core/core_param.yaml") +# self.declare_parameters_from_yaml(param_file) + +# # os.system(f"rosparam delete /{self.node_name}") +# # os.system(f"rosparam load {para} elevation_mapping") +# # self.subscribers = self.get_parameter("subscribers").get_parameter_value().string_value +# # self.publishers = self.get_parameter("publishers").get_parameter_value().string_value +# self.initialize_frame_id = self.get_parameter("initialize_frame_id").get_parameter_value().string_array_value +# self.initialize_tf_offset = self.get_parameter("initialize_tf_offset").get_parameter_value().double_value +# self.pose_topic = self.get_parameter("pose_topic").get_parameter_value().string_value +# self.map_frame = self.get_parameter("map_frame").get_parameter_value().string_value +# self.base_frame = self.get_parameter("base_frame").get_parameter_value().string_value +# self.corrected_map_frame = self.get_parameter("corrected_map_frame").get_parameter_value().string_value +# self.initialize_method = self.get_parameter("initialize_method").get_parameter_value().string_value +# self.position_lowpass_alpha = self.get_parameter("position_lowpass_alpha").get_parameter_value().double_value +# self.orientation_lowpass_alpha = self.get_parameter("orientation_lowpass_alpha").get_parameter_value().double_value +# self.update_variance_fps = self.get_parameter("update_variance_fps").get_parameter_value().double_value +# self.time_interval = self.get_parameter("time_interval").get_parameter_value().double_value +# self.update_pose_fps = self.get_parameter("update_pose_fps").get_parameter_value().double_value +# self.initialize_tf_grid_size = self.get_parameter("initialize_tf_grid_size").get_parameter_value().double_value +# self.map_acquire_fps = self.get_parameter("map_acquire_fps").get_parameter_value().double_value +# self.publish_statistics_fps = self.get_parameter("publish_statistics_fps").get_parameter_value().double_value +# self.enable_pointcloud_publishing = self.get_parameter("enable_pointcloud_publishing").get_parameter_value().bool_value +# self.enable_normal_arrow_publishing = self.get_parameter("enable_normal_arrow_publishing").get_parameter_value().bool_value +# self.enable_drift_corrected_TF_publishing = self.get_parameter("enable_drift_corrected_TF_publishing").get_parameter_value().bool_value +# self.use_initializer_at_start = self.get_parameter("use_initializer_at_start").get_parameter_value().bool_value + + +# def main(args=None): +# rclpy.init(args=args) +# node = ElevationMapWrapper() +# rclpy.spin(node) +# rclpy.shutdown() + +# if __name__ == '__main__': +# main() \ No newline at end of file diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/kk.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/kk.py new file mode 100644 index 00000000..27562dda --- /dev/null +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/kk.py @@ -0,0 +1,1290 @@ +# +# Copyright (c) 2023, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import string + + +def sum_kernel( + resolution, width, height, +): + """Sums the semantic values of the classes for the exponentiala verage or for the average. + + Args: + resolution: + width: + height: + + Returns: + + """ + # input the list of layers, amount of channels can slo be input through kernel + sum_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map, raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; + atomicAdd(&newmap[get_map_idx(idx, map_lay[layer])], feat); + } + } + """ + ).substitute(), + name="sum_kernel", + ) + return sum_kernel + + +def sum_compact_kernel( + resolution, width, height, +): + # input the list of layers, amount of channels can slo be input through kernel + sum_compact_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params=" raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; + atomicAdd(&newmap[get_map_idx(idx, layer)], feat); + } + } + """ + ).substitute(), + name="sum_compact_kernel", + ) + return sum_compact_kernel + + +def sum_max_kernel( + resolution, width, height, +): + # input the list of layers, amount of channels can slo be input through kernel + sum_max_kernel = cp.ElementwiseKernel( + in_params="raw U p, raw U max_pt, raw T max_id, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params=" raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(resolution=resolution, width=width, height=height), + operation=string.Template( + """ + U idx = p[i * pcl_channels[0]]; + U valid = p[i * pcl_channels[0] + 1]; + U inside = p[i * pcl_channels[0] + 2]; + if (valid) { + if (inside) { + // for every max value + for ( W it=0;it=theta_max){ + arg_max = map_lay[layer]; + theta_max = theta; + } + atomicAdd(&newmap[get_map_idx(idx, arg_max)], theta_max); + } + } + """ + ).substitute(), + name="alpha_kernel", + ) + return alpha_kernel + + +def average_kernel( + width, height, +): + average_kernel = cp.ElementwiseKernel( + in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U feat = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); + map[get_map_idx(id, map_lay[layer])] = feat; + } + """ + ).substitute(), + name="average_map_kernel", + ) + return average_kernel + + +def bayesian_inference_kernel( + width, height, +): + bayesian_inference_kernel = cp.ElementwiseKernel( + in_params=" raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U newmap, raw U sum_mean, raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U feat_ml = sum_mean[get_map_idx(id, layer)]/cnt; + U feat_old = map[get_map_idx(id, map_lay[layer])]; + U sigma_old = newmap[get_map_idx(id, map_lay[layer])]; + U sigma = 1.0; + U feat_new = sigma*feat_old /(cnt*sigma_old + sigma) +cnt*sigma_old *feat_ml /(cnt*sigma_old+sigma); + U sigma_new = sigma*sigma_old /(cnt*sigma_old +sigma); + map[get_map_idx(id, map_lay[layer])] = feat_new; + newmap[get_map_idx(id, map_lay[layer])] = sigma_new; + } + """ + ).substitute(), + name="bayesian_inference_kernel", + ) + return bayesian_inference_kernel + + +def class_average_kernel( + width, height, alpha, +): + class_average_kernel = cp.ElementwiseKernel( + in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U cnt = new_elmap[get_map_idx(id, 2)]; + if (cnt>0){ + U prev_val = map[get_map_idx(id, map_lay[layer])]; + if (prev_val==0){ + U val = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); + map[get_map_idx(id, map_lay[layer])] = val; + } + else{ + U val = ${alpha} *prev_val + (1-${alpha}) * newmap[get_map_idx(id, map_lay[layer])]/(cnt); + map[get_map_idx(id, map_lay[layer])] = val; + } + } + """ + ).substitute(alpha=alpha,), + name="class_average_kernel", + ) + return class_average_kernel + + +def add_color_kernel( + width, height, +): + add_color_kernel = cp.ElementwiseKernel( + in_params="raw T p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw V color_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ unsigned int get_r(unsigned int color){ + unsigned int red = 0xFF0000; + unsigned int reds = (color & red) >> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = ( color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + U idx = p[id * pcl_channels[0]]; + U valid = p[id * pcl_channels[0] + 1]; + U inside = p[id * pcl_channels[0] + 2]; + if (valid && inside){ + unsigned int color = __float_as_uint(p[id * pcl_channels[0] + pcl_chan[layer]]); + atomicAdd(&color_map[get_map_idx(idx, layer*3)], get_r(color)); + atomicAdd(&color_map[get_map_idx(idx, layer*3+1)], get_g(color)); + atomicAdd(&color_map[get_map_idx(idx, layer*3 + 2)], get_b(color)); + atomicAdd(&color_map[get_map_idx(idx, pcl_channels[1]*3)], 1); + } + """ + ).substitute(width=width), + name="add_color_kernel", + ) + return add_color_kernel + + +def color_average_kernel( + width, height, +): + color_average_kernel = cp.ElementwiseKernel( + in_params="raw V color_map, raw W pcl_chan, raw W map_lay, raw W pcl_channels", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ unsigned int get_r(unsigned int color){ + unsigned int red = 0xFF0000; + unsigned int reds = (color & red) >> 16; + return reds; + } + __device__ unsigned int get_g(unsigned int color){ + unsigned int green = 0xFF00; + unsigned int greens = (color & green) >> 8; + return greens; + } + __device__ unsigned int get_b(unsigned int color){ + unsigned int blue = 0xFF; + unsigned int blues = (color & blue); + return blues; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U id = floorf(i/pcl_channels[1]); + int layer = i % pcl_channels[1]; + unsigned int cnt = color_map[get_map_idx(id, pcl_channels[1]*3)]; + if (cnt>0){ + // U prev_color = map[get_map_idx(id, map_lay[layer])]; + unsigned int r = color_map[get_map_idx(id, layer*3)]/(1*cnt); + unsigned int g = color_map[get_map_idx(id, layer*3+1)]/(1*cnt); + unsigned int b = color_map[get_map_idx(id, layer*3+2)]/(1*cnt); + //if (prev_color>=0){ + // unsigned int prev_r = get_r(prev_color); + // unsigned int prev_g = get_g(prev_color); + // unsigned int prev_b = get_b(prev_color); + // unsigned int r = prev_r/2 + color_map[get_map_idx(i, layer*3)]/(2*cnt); + // unsigned int g = prev_g/2 + color_map[get_map_idx(i, layer*3+1)]/(2*cnt); + // unsigned int b = prev_b/2 + color_map[get_map_idx(i, layer*3+2)]/(2*cnt); + //} + unsigned int rgb = (r<<16) + (g << 8) + b; + float rgb_ = __uint_as_float(rgb); + map[get_map_idx(id, map_lay[layer])] = rgb_; + } + """ + ).substitute(), + name="color_average_kernel", + ) + return color_average_kernel + + + +def map_utils( + resolution, + width, + height, + sensor_noise_factor, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, +): + util_preamble = string.Template( + """ + __device__ float16 clamp(float16 x, float16 min_x, float16 max_x) { + + return max(min(x, max_x), min_x); + } + __device__ int get_x_idx(float16 x, float16 center) { + int i = (x - center) / ${resolution} + 0.5 * ${width}; + return i; + } + __device__ int get_y_idx(float16 y, float16 center) { + int i = (y - center) / ${resolution} + 0.5 * ${height}; + return i; + } + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x == 0 || idx_x == ${width} - 1) { + return false; + } + if (idx_y == 0 || idx_y == ${height} - 1) { + return false; + } + return true; + } + __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { + int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); + int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); + return ${width} * idx_x + idx_y; + } + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ float transform_p(float16 x, float16 y, float16 z, + float16 r0, float16 r1, float16 r2, float16 t) { + return r0 * x + r1 * y + r2 * z + t; + } + __device__ float z_noise(float16 z){ + return ${sensor_noise_factor} * z * z; + } + + __device__ float point_sensor_distance(float16 x, float16 y, float16 z, + float16 sx, float16 sy, float16 sz) { + float d = (x - sx) * (x - sx) + (y - sy) * (y - sy) + (z - sz) * (z - sz); + return d; + } + + __device__ bool is_valid(float16 x, float16 y, float16 z, + float16 sx, float16 sy, float16 sz) { + float d = point_sensor_distance(x, y, z, sx, sy, sz); + float dxy = max(sqrt(x * x + y * y) - ${ramped_height_range_b}, 0.0); + if (d < ${min_valid_distance} * ${min_valid_distance}) { + return false; + } + else if (z - sz > dxy * ${ramped_height_range_a} + ${ramped_height_range_c} || z - sz > ${max_height_range}) { + return false; + } + else { + return true; + } + } + + __device__ float ray_vector(float16 tx, float16 ty, float16 tz, + float16 px, float16 py, float16 pz, + float16& rx, float16& ry, float16& rz){ + float16 vx = px - tx; + float16 vy = py - ty; + float16 vz = pz - tz; + float16 norm = sqrt(vx * vx + vy * vy + vz * vz); + if (norm > 0) { + rx = vx / norm; + ry = vy / norm; + rz = vz / norm; + } + else { + rx = 0; + ry = 0; + rz = 0; + } + return norm; + } + + __device__ float inner_product(float16 x1, float16 y1, float16 z1, + float16 x2, float16 y2, float16 z2) { + + float product = (x1 * x2 + y1 * y2 + z1 * z2); + return product; + } + + """ + ).substitute( + resolution=resolution, + width=width, + height=height, + sensor_noise_factor=sensor_noise_factor, + min_valid_distance=min_valid_distance, + max_height_range=max_height_range, + ramped_height_range_a=ramped_height_range_a, + ramped_height_range_b=ramped_height_range_b, + ramped_height_range_c=ramped_height_range_c, + ) + return util_preamble + + +def add_points_kernel( + resolution, + width, + height, + sensor_noise_factor, + mahalanobis_thresh, + outlier_variance, + wall_num_thresh, + max_ray_length, + cleanup_step, + min_valid_distance, + max_height_range, + cleanup_cos_thresh, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, + enable_edge_shaped=True, + enable_visibility_cleanup=True, +): + add_points_kernel = cp.ElementwiseKernel( + in_params="raw U center_x, raw U center_y, raw U R, raw U t, raw U norm_map", + out_params="raw U p, raw U map, raw T newmap", + preamble=map_utils( + resolution, + width, + height, + sensor_noise_factor, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, + ), + operation=string.Template( + """ + U rx = p[i * 3]; + U ry = p[i * 3 + 1]; + U rz = p[i * 3 + 2]; + U x = transform_p(rx, ry, rz, R[0], R[1], R[2], t[0]); + U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); + U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); + U v = z_noise(rz); + int idx = get_idx(x, y, center_x[0], center_y[0]); + if (is_valid(x, y, z, t[0], t[1], t[2])) { + if (is_inside(idx)) { + U map_h = map[get_map_idx(idx, 0)]; + U map_v = map[get_map_idx(idx, 1)]; + U num_points = newmap[get_map_idx(idx, 4)]; + if (abs(map_h - z) > (map_v * ${mahalanobis_thresh})) { + atomicAdd(&map[get_map_idx(idx, 1)], ${outlier_variance}); + } + else { + if (${enable_edge_shaped} && (num_points > ${wall_num_thresh}) && (z < map_h - map_v * ${mahalanobis_thresh} / num_points)) { + // continue; + } + else { + T new_h = (map_h * v + z * map_v) / (map_v + v); + T new_v = (map_v * v) / (map_v + v); + atomicAdd(&newmap[get_map_idx(idx, 0)], new_h); + atomicAdd(&newmap[get_map_idx(idx, 1)], new_v); + atomicAdd(&newmap[get_map_idx(idx, 2)], 1.0); + // is Valid + map[get_map_idx(idx, 2)] = 1; + // Time layer + map[get_map_idx(idx, 4)] = 0.0; + // Upper bound + map[get_map_idx(idx, 5)] = new_h; + map[get_map_idx(idx, 6)] = 0.0; + } + // visibility cleanup + } + } + } + if (${enable_visibility_cleanup}) { + float16 ray_x, ray_y, ray_z; + float16 ray_length = ray_vector(t[0], t[1], t[2], x, y, z, ray_x, ray_y, ray_z); + ray_length = min(ray_length, (float16)${max_ray_length}); + int last_nidx = -1; + for (float16 s=${ray_step}; s < ray_length; s+=${ray_step}) { + // iterate through ray + U nx = t[0] + ray_x * s; + U ny = t[1] + ray_y * s; + U nz = t[2] + ray_z * s; + int nidx = get_idx(nx, ny, center_x[0], center_y[0]); + if (last_nidx == nidx) {continue;} // Skip if we're still in the same cell + else {last_nidx = nidx;} + if (!is_inside(nidx)) {continue;} + + U nmap_h = map[get_map_idx(nidx, 0)]; + U nmap_v = map[get_map_idx(nidx, 1)]; + U nmap_valid = map[get_map_idx(nidx, 2)]; + // traversability + U nmap_trav = map[get_map_idx(nidx, 3)]; + // Time layer + U non_updated_t = map[get_map_idx(nidx, 4)]; + // upper bound + U nmap_upper = map[get_map_idx(nidx, 5)]; + U nmap_is_upper = map[get_map_idx(nidx, 6)]; + + // If point is close or is farther away than ray length, skip. + float16 d = (x - nx) * (x - nx) + (y - ny) * (y - ny) + (z - nz) * (z - nz); + if (d < 0.1 || !is_valid(x, y, z, t[0], t[1], t[2])) {continue;} + + // If invalid, do upper bound check, then skip + if (nmap_valid < 0.5) { + if (nz < nmap_upper || nmap_is_upper < 0.5) { + map[get_map_idx(nidx, 5)] = nz; + map[get_map_idx(nidx, 6)] = 1.0f; + } + continue; + } + // If updated recently, skip + if (non_updated_t < 0.5) {continue;} + + if (nmap_h > nz + 0.01 - min(nmap_v, 1.0) * 0.05) { + // If ray and norm is vertical, skip + U norm_x = norm_map[get_map_idx(nidx, 0)]; + U norm_y = norm_map[get_map_idx(nidx, 1)]; + U norm_z = norm_map[get_map_idx(nidx, 2)]; + float product = inner_product(ray_x, ray_y, ray_z, norm_x, norm_y, norm_z); + if (fabs(product) < ${cleanup_cos_thresh}) {continue;} + U num_points = newmap[get_map_idx(nidx, 3)]; + if (num_points > ${wall_num_thresh} && non_updated_t < 1.0) {continue;} + + // Finally, this cell is penetrated by the ray. + atomicAdd(&map[get_map_idx(nidx, 2)], -${cleanup_step}/(ray_length / ${max_ray_length})); + atomicAdd(&map[get_map_idx(nidx, 1)], ${outlier_variance}); + // Do upper bound check. + if (nz < nmap_upper || nmap_is_upper < 0.5) { + map[get_map_idx(nidx, 5)] = nz; + map[get_map_idx(nidx, 6)] = 1.0f; + } + } + } + } + p[i * 3]= idx; + p[i * 3 + 1] = is_valid(x, y, z, t[0], t[1], t[2]); + p[i * 3 + 2] = is_inside(idx); + """ + ).substitute( + mahalanobis_thresh=mahalanobis_thresh, + outlier_variance=outlier_variance, + wall_num_thresh=wall_num_thresh, + ray_step=resolution / 2 ** 0.5, + max_ray_length=max_ray_length, + cleanup_step=cleanup_step, + cleanup_cos_thresh=cleanup_cos_thresh, + enable_edge_shaped=int(enable_edge_shaped), + enable_visibility_cleanup=int(enable_visibility_cleanup), + ), + name="add_points_kernel", + ) + return add_points_kernel + + +def error_counting_kernel( + resolution, + width, + height, + sensor_noise_factor, + mahalanobis_thresh, + outlier_variance, + traversability_inlier, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, +): + error_counting_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U p, raw U center_x, raw U center_y, raw U R, raw U t", + out_params="raw U newmap, raw T error, raw T error_cnt", + preamble=map_utils( + resolution, + width, + height, + sensor_noise_factor, + min_valid_distance, + max_height_range, + ramped_height_range_a, + ramped_height_range_b, + ramped_height_range_c, + ), + operation=string.Template( + """ + U rx = p[i * 3]; + U ry = p[i * 3 + 1]; + U rz = p[i * 3 + 2]; + U x = transform_p(rx, ry, rz, R[0], R[1], R[2], t[0]); + U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); + U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); + U v = z_noise(rz); + // if (!is_valid(z, t[2])) {return;} + if (!is_valid(x, y, z, t[0], t[1], t[2])) {return;} + // if ((x - t[0]) * (x - t[0]) + (y - t[1]) * (y - t[1]) + (z - t[2]) * (z - t[2]) < 0.5) {return;} + int idx = get_idx(x, y, center_x[0], center_y[0]); + if (!is_inside(idx)) { + return; + } + U map_h = map[get_map_idx(idx, 0)]; + U map_v = map[get_map_idx(idx, 1)]; + U map_valid = map[get_map_idx(idx, 2)]; + U map_t = map[get_map_idx(idx, 3)]; + if (map_valid > 0.5 && (abs(map_h - z) < (map_v * ${mahalanobis_thresh})) + && map_v < ${outlier_variance} / 2.0 + && map_t > ${traversability_inlier}) { + T e = z - map_h; + atomicAdd(&error[0], e); + atomicAdd(&error_cnt[0], 1); + atomicAdd(&newmap[get_map_idx(idx, 3)], 1.0); + } + atomicAdd(&newmap[get_map_idx(idx, 4)], 1.0); + """ + ).substitute( + mahalanobis_thresh=mahalanobis_thresh, + outlier_variance=outlier_variance, + traversability_inlier=traversability_inlier, + ), + name="error_counting_kernel", + ) + return error_counting_kernel + + +def average_map_kernel(width, height, max_variance, initial_variance): + average_map_kernel = cp.ElementwiseKernel( + in_params="raw U newmap", + out_params="raw U map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U h = map[get_map_idx(i, 0)]; + U v = map[get_map_idx(i, 1)]; + U valid = map[get_map_idx(i, 2)]; + U new_h = newmap[get_map_idx(i, 0)]; + U new_v = newmap[get_map_idx(i, 1)]; + U new_cnt = newmap[get_map_idx(i, 2)]; + if (new_cnt > 0) { + if (new_v / new_cnt > ${max_variance}) { + map[get_map_idx(i, 0)] = 0; + map[get_map_idx(i, 1)] = ${initial_variance}; + map[get_map_idx(i, 2)] = 0; + } + else { + map[get_map_idx(i, 0)] = new_h / new_cnt; + map[get_map_idx(i, 1)] = new_v / new_cnt; + map[get_map_idx(i, 2)] = 1; + } + } + if (valid < 0.5) { + map[get_map_idx(i, 0)] = 0; + map[get_map_idx(i, 1)] = ${initial_variance}; + map[get_map_idx(i, 2)] = 0; + } + """ + ).substitute(max_variance=max_variance, initial_variance=initial_variance), + name="average_map_kernel", + ) + return average_map_kernel + + +def dilation_filter_kernel(width, height, dilation_size): + dilation_filter_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U mask", + out_params="raw U newmap, raw U newmask", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { + const int layer = ${width} * ${height}; + const int relative_idx = idx + ${width} * dy + dx; + return layer * layer_n + relative_idx; + } + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x <= 0 || idx_x >= ${width} - 1) { + return false; + } + if (idx_y <= 0 || idx_y >= ${height} - 1) { + return false; + } + return true; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + U h = map[get_map_idx(i, 0)]; + U valid = mask[get_map_idx(i, 0)]; + newmap[get_map_idx(i, 0)] = h; + if (valid < 0.5) { + U distance = 100; + U near_value = 0; + for (int dy = -${dilation_size}; dy <= ${dilation_size}; dy++) { + for (int dx = -${dilation_size}; dx <= ${dilation_size}; dx++) { + int idx = get_relative_map_idx(i, dx, dy, 0); + if (!is_inside(idx)) {continue;} + U valid = mask[idx]; + if(valid > 0.5 && dx + dy < distance) { + distance = dx + dy; + near_value = map[idx]; + } + } + } + if(distance < 100) { + newmap[get_map_idx(i, 0)] = near_value; + newmask[get_map_idx(i, 0)] = 1.0; + } + } + """ + ).substitute(dilation_size=dilation_size), + name="dilation_filter_kernel", + ) + return dilation_filter_kernel + + +def normal_filter_kernel(width, height, resolution): + normal_filter_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U mask", + out_params="raw U newmap", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { + const int layer = ${width} * ${height}; + const int relative_idx = idx + ${width} * dy + dx; + return layer * layer_n + relative_idx; + } + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x <= 0 || idx_x >= ${width} - 1) { + return false; + } + if (idx_y <= 0 || idx_y >= ${height} - 1) { + return false; + } + return true; + } + __device__ float resolution() { + return ${resolution}; + } + """ + ).substitute(width=width, height=height, resolution=resolution), + operation=string.Template( + """ + U h = map[get_map_idx(i, 0)]; + U valid = mask[get_map_idx(i, 0)]; + if (valid > 0.5) { + int idx_x = get_relative_map_idx(i, 1, 0, 0); + int idx_y = get_relative_map_idx(i, 0, 1, 0); + if (!is_inside(idx_x) || !is_inside(idx_y)) { return; } + float dzdx = (map[idx_x] - h); + float dzdy = (map[idx_y] - h); + float nx = -dzdy / resolution(); + float ny = -dzdx / resolution(); + float nz = 1; + float norm = sqrt((nx * nx) + (ny * ny) + 1); + newmap[get_map_idx(i, 0)] = nx / norm; + newmap[get_map_idx(i, 1)] = ny / norm; + newmap[get_map_idx(i, 2)] = nz / norm; + } + """ + ).substitute(), + name="normal_filter_kernel", + ) + return normal_filter_kernel + + +def polygon_mask_kernel(width, height, resolution): + polygon_mask_kernel = cp.ElementwiseKernel( + in_params="raw U polygon, raw U center_x, raw U center_y, raw int16 polygon_n, raw U polygon_bbox", + out_params="raw U mask", + preamble=string.Template( + """ + __device__ struct Point + { + int x; + int y; + }; + // Given three colinear points p, q, r, the function checks if + // point q lies on line segment 'pr' + __device__ bool onSegment(Point p, Point q, Point r) + { + if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) && + q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y)) + return true; + return false; + } + // To find orientation of ordered triplet (p, q, r). + // The function returns following values + // 0 --> p, q and r are colinear + // 1 --> Clockwise + // 2 --> Counterclockwise + __device__ int orientation(Point p, Point q, Point r) + { + int val = (q.y - p.y) * (r.x - q.x) - + (q.x - p.x) * (r.y - q.y); + if (val == 0) return 0; // colinear + return (val > 0)? 1: 2; // clock or counterclock wise + } + // The function that returns true if line segment 'p1q1' + // and 'p2q2' intersect. + __device__ bool doIntersect(Point p1, Point q1, Point p2, Point q2) + { + // Find the four orientations needed for general and + // special cases + int o1 = orientation(p1, q1, p2); + int o2 = orientation(p1, q1, q2); + int o3 = orientation(p2, q2, p1); + int o4 = orientation(p2, q2, q1); + // General case + if (o1 != o2 && o3 != o4) + return true; + // Special Cases + // p1, q1 and p2 are colinear and p2 lies on segment p1q1 + if (o1 == 0 && onSegment(p1, p2, q1)) return true; + // p1, q1 and p2 are colinear and q2 lies on segment p1q1 + if (o2 == 0 && onSegment(p1, q2, q1)) return true; + // p2, q2 and p1 are colinear and p1 lies on segment p2q2 + if (o3 == 0 && onSegment(p2, p1, q2)) return true; + // p2, q2 and q1 are colinear and q1 lies on segment p2q2 + if (o4 == 0 && onSegment(p2, q1, q2)) return true; + return false; // Doesn't fall in any of the above cases + } + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ int get_idx_x(int idx){ + int idx_x = idx / ${width}; + return idx_x; + } + + __device__ int get_idx_y(int idx){ + int idx_y = idx % ${width}; + return idx_y; + } + + __device__ float16 clamp(float16 x, float16 min_x, float16 max_x) { + + return max(min(x, max_x), min_x); + } + __device__ float16 round(float16 x) { + return (int)x + (int)(2 * (x - (int)x)); + } + __device__ int get_x_idx(float16 x, float16 center) { + const float resolution = ${resolution}; + const float width = ${width}; + int i = (x - center) / resolution + 0.5 * width; + return i; + } + __device__ int get_y_idx(float16 y, float16 center) { + const float resolution = ${resolution}; + const float height = ${height}; + int i = (y - center) / resolution + 0.5 * height; + return i; + } + __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { + int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); + int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); + return ${width} * idx_x + idx_y; + } + + """ + ).substitute(width=width, height=height, resolution=resolution), + operation=string.Template( + """ + // Point p = {get_idx_x(i, center_x[0]), get_idx_y(i, center_y[0])}; + Point p = {get_idx_x(i), get_idx_y(i)}; + Point extreme = {100000, p.y}; + int bbox_min_idx = get_idx(polygon_bbox[0], polygon_bbox[1], center_x[0], center_y[0]); + int bbox_max_idx = get_idx(polygon_bbox[2], polygon_bbox[3], center_x[0], center_y[0]); + Point bmin = {get_idx_x(bbox_min_idx), get_idx_y(bbox_min_idx)}; + Point bmax = {get_idx_x(bbox_max_idx), get_idx_y(bbox_max_idx)}; + if (p.x < bmin.x || p.x > bmax.x || p.y < bmin.y || p.y > bmax.y){ + mask[i] = 0; + return; + } + else { + int intersect_cnt = 0; + for (int j = 0; j < polygon_n[0]; j++) { + Point p1, p2; + int i1 = get_idx(polygon[j * 2 + 0], polygon[j * 2 + 1], center_x[0], center_y[0]); + p1.x = get_idx_x(i1); + p1.y = get_idx_y(i1); + int j2 = (j + 1) % polygon_n[0]; + int i2 = get_idx(polygon[j2 * 2 + 0], polygon[j2 * 2 + 1], center_x[0], center_y[0]); + p2.x = get_idx_x(i2); + p2.y = get_idx_y(i2); + if (doIntersect(p1, p2, p, extreme)) + { + // If the point 'p' is colinear with line segment 'i-next', + // then check if it lies on segment. If it lies, return true, + // otherwise false + if (orientation(p1, p, p2) == 0) { + if (onSegment(p1, p, p2)){ + mask[i] = 1; + return; + } + } + else if(((p1.y <= p.y) && (p2.y > p.y)) || ((p1.y > p.y) && (p2.y <= p.y))){ + intersect_cnt++; + } + } + } + if (intersect_cnt % 2 == 0) { mask[i] = 0; } + else { mask[i] = 1; } + } + """ + ).substitute(a=1), + name="polygon_mask_kernel", + ) + return polygon_mask_kernel + + + +def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_collision): + """ + This function calculates the correspondence between the image and the map. + It takes in the resolution, width, height, and tolerance_z_collision as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _image_to_map_correspondence_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U K, raw U D, raw U image_height, raw U image_width, raw U center", + out_params="raw U uv_correspondence, raw B valid_correspondence", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + __device__ bool is_inside_map(int x, int y) { + return (x >= 0 && y >= 0 && x<${width} && y<${height}); + } + __device__ float get_l2_distance(int x0, int y0, int x1, int y1) { + float dx = x0-x1; + float dy = y0-y1; + return sqrt( dx*dx + dy*dy); + } + """ + ).substitute(width=width, height=height, resolution=resolution), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + + // return if gridcell has no valid height + if (map[get_map_idx(i, 2)] != 1){ + return; + } + + // get current cell position + int y0 = i % ${width}; + int x0 = i / ${width}; + + // gridcell 3D point in worldframe TODO reverse x and y + float p1 = (x0-(${width}/2)) * ${resolution} + center[0]; + float p2 = (y0-(${height}/2)) * ${resolution} + center[1]; + float p3 = map[cell_idx] + center[2]; + + // reproject 3D point into image plane + float u = p1 * P[0] + p2 * P[1] + p3 * P[2] + P[3]; + float v = p1 * P[4] + p2 * P[5] + p3 * P[6] + P[7]; + float d = p1 * P[8] + p2 * P[9] + p3 * P[10] + P[11]; + + // filter point behind image plane + if (d <= 0) { + return; + } + u = u/d; + v = v/d; + + // Check if D is all zeros + bool is_D_zero = (D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == 0 && D[4] == 0); + + // Apply undistortion using distortion matrix D if not all zeros + if (!is_D_zero) { + float k1 = D[0]; + float k2 = D[1]; + float p1 = D[2]; + float p2 = D[3]; + float k3 = D[4]; + float fx = K[0]; + float fy = K[4]; + float cx = K[2]; + float cy = K[5]; + float x = (u - cx) / fx; + float y = (v - cy) / fy; + float r2 = x * x + y * y; + float radial_distortion = 1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2; + float u_corrected = x * radial_distortion + 2 * p1 * x * y + p2 * (r2 + 2 * x * x); + float v_corrected = y * radial_distortion + 2 * p2 * x * y + p1 * (r2 + 2 * y * y); + u = fx * u_corrected + cx; + v = fy * v_corrected + cy; + } + + // filter point next to image plane + if ((u < 0) || (v < 0) || (u >= image_width) || (v >= image_height)){ + return; + } + + int y0_c = y0; + int x0_c = x0; + float total_dis = get_l2_distance(x0_c, y0_c, x1,y1); + float z0 = map[cell_idx]; + float delta_z = z1-z0; + + + // bresenham algorithm to iterate over cells in line between camera center and current gridmap cell + // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm + int dx = abs(x1-x0); + int sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0); + int sy = y0 < y1 ? 1 : -1; + int error = dx + dy; + + bool is_valid = true; + + // iterate over all cells along line + while (1){ + // assumption we do not need to check the height for camera center cell + if (x0 == x1 && y0 == y1){ + break; + } + + // check if height is invalid + if (is_inside_map(x0,y0)){ + int idx = y0 + (x0 * ${width}); + if (map[get_map_idx(idx, 2)]){ + float dis = get_l2_distance(x0_c, y0_c, x0, y0); + float rayheight = z0 + ( dis / total_dis * delta_z); + if ( map[idx] - ${tolerance_z_collision} > rayheight){ + is_valid = false; + break; + } + } + } + + + // computation of next gridcell index in line + int e2 = 2 * error; + if (e2 >= dy){ + if(x0 == x1){ + break; + } + error = error + dy; + x0 = x0 + sx; + } + if (e2 <= dx){ + if (y0 == y1){ + break; + } + error = error + dx; + y0 = y0 + sy; + } + } + + // mark the correspondence + uv_correspondence[get_map_idx(i, 0)] = u; + uv_correspondence[get_map_idx(i, 1)] = v; + valid_correspondence[get_map_idx(i, 0)] = is_valid; + """ + ).substitute(height=height, width=width, resolution=resolution, tolerance_z_collision=tolerance_z_collision), + name="image_to_map_correspondence_kernel", + ) + return _image_to_map_correspondence_kernel + + +def average_correspondences_to_map_kernel(width, height): + """ + This function calculates the average correspondences to the map. + It takes in the width and height as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _average_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + new_sem_map[get_map_idx(i, map_idx)] = image_mono[idx]; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + + """ + ).substitute(), + name="average_correspondences_to_map_kernel", + ) + return _average_correspondences_to_map_kernel + + +def exponential_correspondences_to_map_kernel(width, height, alpha): + """ + This function calculates the exponential correspondences to the map. + It takes in the width, height, and alpha as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _exponential_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)] * (1-${alpha}) + ${alpha} * image_mono[idx]; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + + """ + ).substitute(alpha=alpha), + name="exponential_correspondences_to_map_kernel", + ) + return _exponential_correspondences_to_map_kernel + + +def color_correspondences_to_map_kernel(width, height): + """ + This function calculates the color correspondences to the map. + It takes in the width and height as parameters. + The function returns a kernel that can be used to perform the correspondence calculation. + """ + _color_correspondences_to_map_kernel = cp.ElementwiseKernel( + in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", + out_params="raw U new_sem_map", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + """ + ).substitute(width=width, height=height), + operation=string.Template( + """ + int cell_idx = get_map_idx(i, 0); + if (valid_correspondence[cell_idx]){ + int cell_idx_2 = get_map_idx(i, 1); + + int idx_red = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; + int idx_green = image_width * image_height + idx_red; + int idx_blue = image_width * image_height * 2 + idx_red; + + unsigned int r = image_rgb[idx_red]; + unsigned int g = image_rgb[idx_green]; + unsigned int b = image_rgb[idx_blue]; + + unsigned int rgb = (r<<16) + (g << 8) + b; + float rgb_ = __uint_as_float(rgb); + new_sem_map[get_map_idx(i, map_idx)] = rgb_; + }else{ + new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; + } + """ + ).substitute(), + name="color_correspondences_to_map_kernel", + ) + return _color_correspondences_to_map_kernel diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 5fc3c110..52fc2664 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -289,12 +289,12 @@ def update(self): self.true_map_length = self.true_cell_n * self.resolution -if __name__ == "__main__": - param = Parameter() - print(param) - print(param.resolution) - param.set_value("resolution", 0.1) - print(param.resolution) +# if __name__ == "__main__": +# param = Parameter() +# print(param) +# print(param.resolution) +# param.set_value("resolution", 0.1) +# print(param.resolution) - print("names ", param.get_names()) - print("types ", param.get_types()) +# print("names ", param.get_names()) +# print("types ", param.get_types()) diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py index f39c99cc..be874f1b 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/traversability_polygon.py @@ -46,7 +46,7 @@ def calculate_area(polygon): def calculate_untraversable_polygon(over_thresh): x, y = cp.where(over_thresh > 0.5) points = cp.stack([x, y]).T - convex_hull = MultiPoint(points).convex_hull + convex_hull = MultiPoint(points.get()).convex_hull if convex_hull.is_empty or convex_hull.geom_type == "Point" or convex_hull.geom_type == "LineString": return None else: diff --git a/elevation_mapping_cupy/setup.py b/elevation_mapping_cupy/setup.py index 8d5a2492..2831eabb 100644 --- a/elevation_mapping_cupy/setup.py +++ b/elevation_mapping_cupy/setup.py @@ -1,8 +1,33 @@ -from distutils.core import setup -from catkin_pkg.python_setup import generate_distutils_setup +from setuptools import setup, find_packages -setup_args = generate_distutils_setup( - packages=["elevation_mapping_cupy", "elevation_mapping_cupy.plugins",], package_dir={"": "script"}, +setup( + name="elevation_mapping_cupy", + version="0.0.1", + packages=find_packages(where="script"), + package_dir={"": "script"}, + install_requires=["setuptools"], + zip_safe=True, + maintainer="Your Name", + maintainer_email="your_email@example.com", + description="Description of the elevation_mapping_cupy package.", + license="Apache License 2.0", + tests_require=["pytest"], + entry_points={ + "console_scripts": [ + # 'node_name = elevation_mapping_cupy.some_module:main_function', + ], + }, ) -setup(**setup_args) + +# from distutils.core import setup +# from catkin_pkg.python_setup import generate_distutils_setup +# from setuptools import find_packages +# setup_args = generate_distutils_setup( +# packages=["elevation_mapping_cupy", "elevation_mapping_cupy.plugins","elevation_mapping_cupy.kernels","elevation_mapping_cupy.fusion"], package_dir={"": "script"}, + +# ) + +# setup(**setup_args) + + diff --git a/elevation_mapping_cupy/src/elevation_mapping_node.cpp b/elevation_mapping_cupy/src/elevation_mapping_node.cpp index 05fac5d6..ca70b5db 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_node.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_node.cpp @@ -12,16 +12,15 @@ int main(int argc, char** argv) { rclcpp::init(argc, argv); - auto node = std::make_shared("elevation_mapping"); - + py::scoped_interpreter guard{}; // start the interpreter and keep it alive - // elevation_mapping_cupy::ElevationMappingNode mapNode(node); + auto mapNode = std::make_shared(); // Correct instantiation py::gil_scoped_release release; + - // Spin - rclcpp::executors::SingleThreadedExecutor executor; - executor.add_node(node); - executor.spin(); + // TODO: Create a multi-threaded executor + rclcpp::spin(mapNode); rclcpp::shutdown(); return 0; -} \ No newline at end of file +} + diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 374bf709..e6535d38 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -1,157 +1,187 @@ -// // -// // Copyright (c) 2022, Takahiro Miki. All rights reserved. -// // Licensed under the MIT license. See LICENSE file in the project root for details. -// // - -// #include "elevation_mapping_cupy/elevation_mapping_ros.hpp" - -// // Pybind -// #include - -// // ROS -// #include -// #include -// #include - -// // PCL -// #include - -// #include - -// namespace elevation_mapping_cupy { - -// ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh) -// : it_(nh), -// lowpassPosition_(0, 0, 0), -// lowpassOrientation_(0, 0, 0, 1), -// positionError_(0), -// orientationError_(0), -// positionAlpha_(0.1), -// orientationAlpha_(0.1), -// enablePointCloudPublishing_(false), -// isGridmapUpdated_(false) { -// nh_ = nh; - -// std::string pose_topic, map_frame; -// XmlRpc::XmlRpcValue publishers; -// XmlRpc::XmlRpcValue subscribers; -// std::vector map_topics; -// double recordableFps, updateVarianceFps, timeInterval, updatePoseFps, updateGridMapFps, publishStatisticsFps; -// bool enablePointCloudPublishing(false); - -// // Read parameters -// nh.getParam("subscribers", subscribers); -// nh.getParam("publishers", publishers); -// if (!subscribers.valid()) { -// ROS_FATAL("There aren't any subscribers to be configured, the elevation mapping cannot be configured. Exit"); -// } -// if (!publishers.valid()) { -// ROS_FATAL("There aren't any publishers to be configured, the elevation mapping cannot be configured. Exit"); -// } -// nh.param>("initialize_frame_id", initialize_frame_id_, {"base"}); -// nh.param>("initialize_tf_offset", initialize_tf_offset_, {0.0}); -// nh.param("pose_topic", pose_topic, "pose"); -// nh.param("map_frame", mapFrameId_, "map"); -// nh.param("base_frame", baseFrameId_, "base"); -// nh.param("corrected_map_frame", correctedMapFrameId_, "corrected_map"); -// nh.param("initialize_method", initializeMethod_, "cubic"); -// nh.param("position_lowpass_alpha", positionAlpha_, 0.2); -// nh.param("orientation_lowpass_alpha", orientationAlpha_, 0.2); -// nh.param("recordable_fps", recordableFps, 3.0); -// nh.param("update_variance_fps", updateVarianceFps, 1.0); -// nh.param("time_interval", timeInterval, 0.1); -// nh.param("update_pose_fps", updatePoseFps, 10.0); -// nh.param("initialize_tf_grid_size", initializeTfGridSize_, 0.5); -// nh.param("map_acquire_fps", updateGridMapFps, 5.0); -// nh.param("publish_statistics_fps", publishStatisticsFps, 1.0); -// nh.param("enable_pointcloud_publishing", enablePointCloudPublishing, false); -// nh.param("enable_normal_arrow_publishing", enableNormalArrowPublishing_, false); -// nh.param("enable_drift_corrected_TF_publishing", enableDriftCorrectedTFPublishing_, false); -// nh.param("use_initializer_at_start", useInitializerAtStart_, false); -// nh.param("always_clear_with_initializer", alwaysClearWithInitializer_, false); - -// enablePointCloudPublishing_ = enablePointCloudPublishing; - -// // Iterate all the subscribers -// // here we have to remove all the stuff -// for (auto& subscriber : subscribers) { -// std::string key = subscriber.first; -// auto type = static_cast(subscriber.second["data_type"]); - -// // Initialize subscribers depending on the type -// if (type == "pointcloud") { -// std::string pointcloud_topic = subscriber.second["topic_name"]; -// channels_[key].push_back("x"); -// channels_[key].push_back("y"); -// channels_[key].push_back("z"); -// boost::function f = boost::bind(&ElevationMappingNode::pointcloudCallback, this, _1, key); -// ros::Subscriber sub = nh_.subscribe(pointcloud_topic, 1, f); -// pointcloudSubs_.push_back(sub); -// ROS_INFO_STREAM("Subscribed to PointCloud2 topic: " << pointcloud_topic); -// } -// else if (type == "image") { -// std::string camera_topic = subscriber.second["topic_name"]; -// std::string info_topic = subscriber.second["camera_info_topic_name"]; - -// // Handle compressed images with transport hints -// // We obtain the hint from the last part of the topic name -// std::string transport_hint = "compressed"; -// std::size_t ind = camera_topic.find(transport_hint); // Find if compressed is in the topic name -// if (ind != std::string::npos) { -// transport_hint = camera_topic.substr(ind, camera_topic.length()); // Get the hint as the last part -// camera_topic.erase(ind - 1, camera_topic.length()); // We remove the hint from the topic -// } else { -// transport_hint = "raw"; // In the default case we assume raw topic -// } - -// // Setup subscriber -// const auto hint = image_transport::TransportHints(transport_hint, ros::TransportHints(), ros::NodeHandle(camera_topic)); -// ImageSubscriberPtr image_sub = std::make_shared(); -// image_sub->subscribe(it_, camera_topic, 1, hint); -// imageSubs_.push_back(image_sub); - -// CameraInfoSubscriberPtr cam_info_sub = std::make_shared(); -// cam_info_sub->subscribe(nh_, info_topic, 1); -// cameraInfoSubs_.push_back(cam_info_sub); - -// std::string channel_info_topic; -// // If there is channel info topic setting, we use it. -// if (subscriber.second.hasMember("channel_info_topic_name")) { -// std::string channel_info_topic = subscriber.second["channel_info_topic_name"]; -// ChannelInfoSubscriberPtr channel_info_sub = std::make_shared(); -// channel_info_sub->subscribe(nh_, channel_info_topic, 1); -// channelInfoSubs_.push_back(channel_info_sub); -// CameraChannelSyncPtr sync = std::make_shared(CameraChannelPolicy(10), *image_sub, *cam_info_sub, *channel_info_sub); -// sync->registerCallback(boost::bind(&ElevationMappingNode::imageChannelCallback, this, _1, _2, _3)); -// cameraChannelSyncs_.push_back(sync); -// ROS_INFO_STREAM("Subscribed to Image topic: " << camera_topic << ", Camera info topic: " << info_topic << ", Channel info topic: " << channel_info_topic); -// } -// else { -// // If there is channels setting, we use it. Otherwise, we use rgb as default. -// if (subscriber.second.hasMember("channels")) { -// const auto& channels = subscriber.second["channels"]; -// for (int32_t i = 0; i < channels.size(); ++i) { -// auto elem = static_cast(channels[i]); -// channels_[key].push_back(elem); -// } -// } -// else { -// channels_[key].push_back("rgb"); -// } -// ROS_INFO_STREAM("Subscribed to Image topic: " << camera_topic << ", Camera info topic: " << info_topic << ". Channel info topic: " << (channel_info_topic.empty() ? ("Not found. Using channels: " + boost::algorithm::join(channels_[key], ", ")) : channel_info_topic)); -// CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); -// sync->registerCallback(boost::bind(&ElevationMappingNode::imageCallback, this, _1, _2, key)); -// cameraSyncs_.push_back(sync); -// } - - -// } else { -// ROS_WARN_STREAM("Subscriber data_type [" << type << "] Not valid. Supported types: pointcloud, image"); -// continue; -// } -// } - -// map_.initialize(nh_); +// +// Copyright (c) 2022, Takahiro Miki. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for details. +// + + +#include "elevation_mapping_cupy/elevation_mapping_ros.hpp" + +// Pybind +#include + +// ROS2 +#include +#include +#include + +// PCL +#include + +#include + +namespace elevation_mapping_cupy { + +ElevationMappingNode::ElevationMappingNode() + : rclcpp::Node("elevation_mapping_node", rclcpp::NodeOptions().automatically_declare_parameters_from_overrides(true)), + node_(std::shared_ptr(this, [](auto *) {})), + // it_(node_), + lowpassPosition_(0, 0, 0), + lowpassOrientation_(0, 0, 0, 1), + positionError_(0), + orientationError_(0), + positionAlpha_(0.1), + orientationAlpha_(0.1), + enablePointCloudPublishing_(false), + isGridmapUpdated_(false){ + RCLCPP_INFO(this->get_logger(), "Initializing ElevationMappingNode..."); + + tfBroadcaster_ = std::make_shared(*this);// ROS2构造TransformBroadcaster + tfBuffer_ = std::make_shared(this->get_clock()); + tfListener_ = std::make_shared(*tfBuffer_); + + + std::string pose_topic, map_frame; + std::vector map_topics; + double recordableFps, updateVarianceFps, timeInterval, updatePoseFps, updateGridMapFps, publishStatisticsFps; + bool enablePointCloudPublishing(false); + + py::gil_scoped_acquire acquire; + auto math = py::module::import("math"); + double root_two = math.attr("sqrt")(2.0).cast(); + RCLCPP_INFO(this->get_logger(), "The square root of 2 is: %f", root_two); + + this->get_parameter("initialize_frame_id", initialize_frame_id_); + this->get_parameter("initialize_tf_offset", initialize_tf_offset_); + this->get_parameter("pose_topic", pose_topic); + this->get_parameter("map_frame", mapFrameId_); + this->get_parameter("base_frame", baseFrameId_); + this->get_parameter("corrected_map_frame", correctedMapFrameId_); + this->get_parameter("initialize_method", initializeMethod_); + this->get_parameter("position_lowpass_alpha", positionAlpha_); + this->get_parameter("orientation_lowpass_alpha", orientationAlpha_); + this->get_parameter("recordable_fps", recordableFps); + this->get_parameter("update_variance_fps", updateVarianceFps); + this->get_parameter("time_interval", timeInterval); + this->get_parameter("update_pose_fps", updatePoseFps); + this->get_parameter("initialize_tf_grid_size", initializeTfGridSize_); + this->get_parameter("map_acquire_fps", updateGridMapFps); + this->get_parameter("publish_statistics_fps", publishStatisticsFps); + this->get_parameter("enable_pointcloud_publishing", enablePointCloudPublishing); + this->get_parameter("enable_normal_arrow_publishing", enableNormalArrowPublishing_); + this->get_parameter("enable_drift_corrected_TF_publishing", enableDriftCorrectedTFPublishing_); + this->get_parameter("use_initializer_at_start", useInitializerAtStart_); + this->get_parameter("always_clear_with_initializer", alwaysClearWithInitializer_); + + RCLCPP_INFO(this->get_logger(), "initialize_frame_id: %s", initialize_frame_id_.empty() ? "[]" : initialize_frame_id_[0].c_str()); + RCLCPP_INFO(this->get_logger(), "initialize_tf_offset: [%f, %f, %f, %f]", initialize_tf_offset_[0], initialize_tf_offset_[1], initialize_tf_offset_[2], initialize_tf_offset_[3]); + RCLCPP_INFO(this->get_logger(), "pose_topic: %s", pose_topic.c_str()); + RCLCPP_INFO(this->get_logger(), "map_frame: %s", mapFrameId_.c_str()); + RCLCPP_INFO(this->get_logger(), "base_frame: %s", baseFrameId_.c_str()); + RCLCPP_INFO(this->get_logger(), "corrected_map_frame: %s", correctedMapFrameId_.c_str()); + RCLCPP_INFO(this->get_logger(), "initialize_method: %s", initializeMethod_.c_str()); + RCLCPP_INFO(this->get_logger(), "position_lowpass_alpha: %f", positionAlpha_); + RCLCPP_INFO(this->get_logger(), "orientation_lowpass_alpha: %f", orientationAlpha_); + RCLCPP_INFO(this->get_logger(), "recordable_fps: %f", recordableFps); + RCLCPP_INFO(this->get_logger(), "update_variance_fps: %f", updateVarianceFps); + RCLCPP_INFO(this->get_logger(), "time_interval: %f", timeInterval); + RCLCPP_INFO(this->get_logger(), "update_pose_fps: %f", updatePoseFps); + RCLCPP_INFO(this->get_logger(), "initialize_tf_grid_size: %f", initializeTfGridSize_); + RCLCPP_INFO(this->get_logger(), "map_acquire_fps: %f", updateGridMapFps); + RCLCPP_INFO(this->get_logger(), "publish_statistics_fps: %f", publishStatisticsFps); + RCLCPP_INFO(this->get_logger(), "enable_pointcloud_publishing: %s", enablePointCloudPublishing ? "true" : "false"); + RCLCPP_INFO(this->get_logger(), "enable_normal_arrow_publishing: %s", enableNormalArrowPublishing_ ? "true" : "false"); + RCLCPP_INFO(this->get_logger(), "enable_drift_corrected_TF_publishing: %s", enableDriftCorrectedTFPublishing_ ? "true" : "false"); + RCLCPP_INFO(this->get_logger(), "use_initializer_at_start: %s", useInitializerAtStart_ ? "true" : "false"); + RCLCPP_INFO(this->get_logger(), "always_clear_with_initializer: %s", alwaysClearWithInitializer_ ? "true" : "false"); + + enablePointCloudPublishing_ = enablePointCloudPublishing; + + std::map subscriber_params, publisher_params; + if (!this->get_parameters("subscribers", subscriber_params)) { + RCLCPP_FATAL(this->get_logger(), "There aren't any subscribers to be configured, the elevation mapping cannot be configured. Exit"); + rclcpp::shutdown(); + } + if (!this->get_parameters("publishers", publisher_params)) { + RCLCPP_FATAL(this->get_logger(), "There aren't any publishers to be configured, the elevation mapping cannot be configured. Exit"); + rclcpp::shutdown(); + } + + for (const auto& name : subscriber_params) { + if (name.first.find("image_topic") != std::string::npos) { + std::string camera_topic = name.second.as_string(); + // setup image subscriber + std::string transport_hint = "compressed"; + std::size_t ind = camera_topic.find(transport_hint); // Find if compressed is in the topic name + if (ind != std::string::npos) { + transport_hint = camera_topic.substr(ind, camera_topic.length()); // Get the hint as the last part + camera_topic.erase(ind - 1, camera_topic.length()); // We remove the hint from the topic + } else { + transport_hint = "raw"; // In the default case we assume raw topic + } + // Create a standard ROS2 subscription for the image topic + ImageSubscriberPtr image_sub = std::make_shared(this, camera_topic, rmw_qos_profile_sensor_data); + // image_sub->subscribe(this->shared_from_this(), camera_topic, 1); + imageSubs_.push_back(image_sub); + + + + + + std::string info_topic; + std::string channel_info_topic; + // Check if the last character is a digit + if (std::isdigit(name.first.back())) { + char last_char = name.first.back(); + std::string cam_info_name_param = "image_info" + std::string(1, last_char); + std::string channel_info_name_param = "image_channel_info" + std::string(1, last_char); + if (this->get_parameter("subscribers." + cam_info_name_param, info_topic)) { + RCLCPP_INFO(this->get_logger(), "Generated parameter %s: %s", cam_info_name_param.c_str(), info_topic.c_str()); + CameraInfoSubscriberPtr cam_info_sub = std::make_shared(this, info_topic, rmw_qos_profile_sensor_data); + // cam_info_sub->subscribe(this->shared_from_this(), info_topic, 1); + cameraInfoSubs_.push_back(cam_info_sub); + if (this->get_parameter("subscribers." + channel_info_name_param, channel_info_topic)) { + ChannelInfoSubscriberPtr channel_info_sub = std::make_shared(this, channel_info_topic, rmw_qos_profile_sensor_data); + // channel_info_sub->subscribe(this->shared_from_this(), channel_info_topic, 1); + channelInfoSubs_.push_back(channel_info_sub); + CameraChannelSyncPtr sync = std::make_shared(CameraChannelPolicy(10), *image_sub, *cam_info_sub, *channel_info_sub); + sync->registerCallback(std::bind(&ElevationMappingNode::imageChannelCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + cameraChannelSyncs_.push_back(sync); + RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s, Camera info topic: %s, Channel info topic: %s", camera_topic.c_str(), info_topic.c_str(), channel_info_topic.c_str()); + }else{ + std::string key = name.first; + channels_[key].push_back("rgb"); + // RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s, Camera info topic: %s. Channel info topic: %s", camera_topic.c_str(), info_topic.c_str(), (channel_info_topic.empty() ? ("Not found. Using channels: " + boost::algorithm::join(channels_[key], ", ")).c_str() : channel_info_topic.c_str())); + CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); + sync->registerCallback(std::bind(&ElevationMappingNode::imageCallback, this, std::placeholders::_1, std::placeholders::_2, key)); + cameraSyncs_.push_back(sync); + } + }else{ + throw std::runtime_error("Info topic is missing for camera: " + camera_topic); + } + }else{ + throw std::runtime_error("Error: image param numbering at the end "); + } + // generate point cloud subscriber + }else if(name.first.find("pointcloud_topic") != std::string::npos) { + std::string pointcloud_topic = name.second.as_string(); + RCLCPP_INFO(this->get_logger(), "Generated parameter %s:", name.first.c_str()); + std::string key = name.first; + channels_[key].push_back("x"); + channels_[key].push_back("y"); + channels_[key].push_back("z"); + auto callback = [this, key](const sensor_msgs::msg::PointCloud2::SharedPtr msg) { + this->pointcloudCallback(msg, key); + }; + auto sub = this->create_subscription(pointcloud_topic, 1, callback); + pointcloudSubs_.push_back(sub); + RCLCPP_INFO(this->get_logger(), "Subscribed to PointCloud2 topic: %s", pointcloud_topic.c_str()); + } + + } + + // get node pointer, pass into Class B + // map_ = std::make_shared(shared_from_this()); + map_->initialize(); // // Register map publishers // for (auto itr = publishers.begin(); itr != publishers.end(); ++itr) { @@ -228,7 +258,10 @@ // } // lastStatisticsPublishedTime_ = ros::Time::now(); // ROS_INFO("[ElevationMappingCupy] finish initialization"); -// } +} + + // namespace elevation_mapping_cupy + // // Setup map publishers // void ElevationMappingNode::setupMapPublishers() { @@ -300,77 +333,80 @@ // mapPubs_[index].publish(msg); // } -// void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cloud, const std::string& key) { -// // get channels -// auto fields = cloud.fields; -// std::vector channels; +void ElevationMappingNode::pointcloudCallback(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::string& key) { + // get channels + auto fields = cloud->fields; + std::vector channels; + + for (size_t it = 0; it < fields.size(); it++) { + auto& field = fields[it]; + channels.push_back(field.name); + } + inputPointCloud(cloud, channels); + + // This is used for publishing as statistics. + pointCloudProcessCounter_++; +} + +void ElevationMappingNode::inputPointCloud(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, + const std::vector& channels) { + auto start = this->now(); + auto* pcl_pc = new pcl::PCLPointCloud2; + pcl::PCLPointCloud2ConstPtr cloudPtr(pcl_pc); + pcl_conversions::toPCL(*cloud, *pcl_pc); + + // Get channels + auto fields = cloud->fields; + uint array_dim = channels.size(); + + RowMatrixXd points = RowMatrixXd(pcl_pc->width * pcl_pc->height, array_dim); + + for (unsigned int i = 0; i < pcl_pc->width * pcl_pc->height; ++i) { + for (unsigned int j = 0; j < channels.size(); ++j) { + float temp; + uint point_idx = i * pcl_pc->point_step + pcl_pc->fields[j].offset; + memcpy(&temp, &pcl_pc->data[point_idx], sizeof(float)); + points(i, j) = static_cast(temp); + } + } + + // Get pose of sensor in map frame + geometry_msgs::msg::TransformStamped transformStamped; + std::string sensorFrameId = cloud->header.frame_id; + auto timeStamp = cloud->header.stamp; + Eigen::Affine3d transformationSensorToMap; + try { + transformStamped = tfBuffer_->lookupTransform(mapFrameId_, sensorFrameId, tf2::TimePointZero); + transformationSensorToMap = tf2::transformToEigen(transformStamped); + } catch (tf2::TransformException& ex) { + RCLCPP_ERROR(this->get_logger(), "%s", ex.what()); + return; + } + + double positionError{0.0}; + double orientationError{0.0}; + { + std::lock_guard lock(errorMutex_); + positionError = positionError_; + orientationError = orientationError_; + } + + // map_.input(points, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError, + // orientationError); + + // if (enableDriftCorrectedTFPublishing_) { + // publishMapToOdom(map_.get_additive_mean_error()); + // } + + RCLCPP_DEBUG(this->get_logger(), "ElevationMap processed a point cloud (%i points) in %f sec.", static_cast(points.size()), + (this->now() - start).seconds()); + RCLCPP_DEBUG(this->get_logger(), "positionError: %f ", positionError); + RCLCPP_DEBUG(this->get_logger(), "orientationError: %f ", orientationError); +} -// for (int it = 0; it < fields.size(); it++) { -// auto& field = fields[it]; -// channels.push_back(field.name); -// } -// inputPointCloud(cloud, channels); -// // This is used for publishing as statistics. -// pointCloudProcessCounter_++; -// } -// void ElevationMappingNode::inputPointCloud(const sensor_msgs::PointCloud2& cloud, -// const std::vector& channels) { -// auto start = ros::Time::now(); -// auto* pcl_pc = new pcl::PCLPointCloud2; -// pcl::PCLPointCloud2ConstPtr cloudPtr(pcl_pc); -// pcl_conversions::toPCL(cloud, *pcl_pc); - -// // get channels -// auto fields = cloud.fields; -// uint array_dim = channels.size(); - -// RowMatrixXd points = RowMatrixXd(pcl_pc->width * pcl_pc->height, array_dim); - -// for (unsigned int i = 0; i < pcl_pc->width * pcl_pc->height; ++i) { -// for (unsigned int j = 0; j < channels.size(); ++j) { -// float temp; -// uint point_idx = i * pcl_pc->point_step + pcl_pc->fields[j].offset; -// memcpy(&temp, &pcl_pc->data[point_idx], sizeof(float)); -// points(i, j) = static_cast(temp); -// } -// } -// // get pose of sensor in map frame -// tf::StampedTransform transformTf; -// std::string sensorFrameId = cloud.header.frame_id; -// auto timeStamp = cloud.header.stamp; -// Eigen::Affine3d transformationSensorToMap; -// try { -// transformListener_.waitForTransform(mapFrameId_, sensorFrameId, timeStamp, ros::Duration(1.0)); -// transformListener_.lookupTransform(mapFrameId_, sensorFrameId, timeStamp, transformTf); -// poseTFToEigen(transformTf, transformationSensorToMap); -// } catch (tf::TransformException& ex) { -// ROS_ERROR("%s", ex.what()); -// return; -// } - -// double positionError{0.0}; -// double orientationError{0.0}; -// { -// std::lock_guard lock(errorMutex_); -// positionError = positionError_; -// orientationError = orientationError_; -// } -// map_.input(points, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError, -// orientationError); - -// if (enableDriftCorrectedTFPublishing_) { -// publishMapToOdom(map_.get_additive_mean_error()); -// } - -// ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed a point cloud (%i points) in %f sec.", static_cast(points.size()), -// (ros::Time::now() - start).toSec()); -// ROS_DEBUG_THROTTLE(1.0, "positionError: %f ", positionError); -// ROS_DEBUG_THROTTLE(1.0, "orientationError: %f ", orientationError); - -// } // void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_msg, // const sensor_msgs::CameraInfoConstPtr& camera_info_msg, @@ -445,24 +481,25 @@ // distortionCoeffs, distortion_model, image.rows, image.cols); // } -// void ElevationMappingNode::imageCallback(const sensor_msgs::ImageConstPtr& image_msg, -// const sensor_msgs::CameraInfoConstPtr& camera_info_msg, -// const std::string& key) { -// auto start = ros::Time::now(); -// inputImage(image_msg, camera_info_msg, channels_[key]); -// ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); -// } - -// void ElevationMappingNode::imageChannelCallback(const sensor_msgs::ImageConstPtr& image_msg, -// const sensor_msgs::CameraInfoConstPtr& camera_info_msg, -// const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg) { -// auto start = ros::Time::now(); -// // Default channels and fusion methods for image is rgb and image_color -// std::vector channels; -// channels = channel_info_msg->channels; -// inputImage(image_msg, camera_info_msg, channels); -// ROS_DEBUG_THROTTLE(1.0, "ElevationMap processed an image in %f sec.", (ros::Time::now() - start).toSec()); -// } +void ElevationMappingNode::imageCallback(const std::shared_ptr& image_msg, + const std::shared_ptr& camera_info_msg, + const std::string& key) { + auto start = this->now(); + // inputImage(image_msg, camera_info_msg, channels_[key]); + RCLCPP_DEBUG(this->get_logger(), "ElevationMap imageCallback processed an image in %f sec.", (this->now() - start).seconds()); +} + + +void ElevationMappingNode::imageChannelCallback(const std::shared_ptr& image_msg, + const std::shared_ptr& camera_info_msg, + const std::shared_ptr& channel_info_msg) { +auto start = this->now(); +// Default channels and fusion methods for image is rgb and image_color +// std::vector channels; +// channels = channel_info_msg->channels; +// inputImage(image_msg, camera_info_msg, channels); +RCLCPP_DEBUG(this->get_logger(), "ElevationMap imageChannelCallback processed an image in %f sec.", (this->now() - start).seconds()); +} // void ElevationMappingNode::updatePose(const ros::TimerEvent&) { // tf::StampedTransform transformTf; @@ -817,4 +854,4 @@ // tfBroadcaster_.sendTransform(tf::StampedTransform(transform, ros::Time::now(), mapFrameId_, correctedMapFrameId_)); // } -// } // namespace elevation_mapping_cupy +} // namespace elevation_mapping_cupy diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 16c57332..f0796abb 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -20,9 +20,10 @@ namespace elevation_mapping_cupy { -ElevationMappingWrapper::ElevationMappingWrapper() {} +ElevationMappingWrapper::ElevationMappingWrapper(rclcpp::Node::SharedPtr node) +:node_(node) {} -void ElevationMappingWrapper::initialize(rclcpp::Node::SharedPtr node) { +void ElevationMappingWrapper::initialize() { // Add the elevation_mapping_cupy path to sys.path auto threading = py::module::import("threading"); py::gil_scoped_acquire acquire; @@ -34,148 +35,154 @@ void ElevationMappingWrapper::initialize(rclcpp::Node::SharedPtr node) { path.attr("insert")(0, module_path); auto elevation_mapping = py::module::import("elevation_mapping_cupy.elevation_mapping"); - auto parameter = py::module::import("elevation_mapping_cupy.parameter"); - param_ = parameter.attr("Parameter")(); - setParameters(node); - map_ = elevation_mapping.attr("ElevationMap")(param_); + // auto parameter = py::module::import("math"); + + // auto param_2 = parameter.attr("Parameter")(); + // setParameters(param_v2); + auto params = setParameters(); + + // map_ = elevation_mapping.attr("ElevationMap")(param_v2); } // /** // * Load ros parameters into Parameter class. // * Search for the same name within the name space. // */ -void ElevationMappingWrapper::setParameters(rclcpp::Node::SharedPtr node) { +py::object ElevationMappingWrapper::setParameters() { + auto parameter = py::module::import("elevation_mapping_cupy.parameter"); + auto param_2 = parameter.attr("Parameter")(); + return param_2; // Get all parameters names and types. - py::list paramNames = param_.attr("get_names")(); - py::list paramTypes = param_.attr("get_types")(); - py::gil_scoped_acquire acquire; - - // Try to find the parameter in the ROS parameter server. - // If there was a parameter, set it to the Parameter variable. - for (size_t i = 0; i < paramNames.size(); i++) { - std::string type = py::cast(paramTypes[i]); - std::string name = py::cast(paramNames[i]); - if (type == "float") { - float param; - if (node->get_parameter(name, param)) { - param_.attr("set_value")(name, param); - } - } else if (type == "str") { - std::string param; - if (node->get_parameter(name, param)) { - param_.attr("set_value")(name, param); - } - } else if (type == "bool") { - bool param; - if (node->get_parameter(name, param)) { - param_.attr("set_value")(name, param); - } - } else if (type == "int") { - int param; - if (node->get_parameter(name, param)) { - param_.attr("set_value")(name, param); - } - } - } + // py::list paramNames = param_.attr("get_names")(); + // py::list paramTypes = param_.attr("get_types")(); + // py::gil_scoped_acquire acquire; + + // // Try to find the parameter in the ROS parameter server. + // // If there was a parameter, set it to the Parameter variable. + // for (size_t i = 0; i < paramNames.size(); i++) { + // std::string type = py::cast(paramTypes[i]); + // std::string name = py::cast(paramNames[i]); + // if (type == "float") { + // float param; + // if (node_->get_parameter(name, param)) { + // param_.attr("set_value")(name, param); + // } + // } else if (type == "str") { + // std::string param; + // if (node_->get_parameter(name, param)) { + // param_.attr("set_value")(name, param); + // } + // } else if (type == "bool") { + // bool param; + // if (node_->get_parameter(name, param)) { + // param_.attr("set_value")(name, param); + // } + // } else if (type == "int") { + // int param; + // if (node_->get_parameter(name, param)) { + // param_.attr("set_value")(name, param); + // } + // } + // } - rclcpp::Parameter subscribers; - node->get_parameter("subscribers", subscribers); - - py::dict sub_dict; - auto subscribers_array = subscribers.as_string_array(); - for (const auto& subscriber : subscribers_array) { - const char* const name = subscriber.c_str(); - if (!sub_dict.contains(name)) { - sub_dict[name] = py::dict(); - } - std::map subscriber_params; - node->get_parameters(name, subscriber_params); - for (const auto& param_pair : subscriber_params) { - const char* const param_name = param_pair.first.c_str(); - const auto& param_value = param_pair.second; - std::vector arr; - switch (param_value.get_type()) { - case rclcpp::ParameterType::PARAMETER_STRING: - sub_dict[name][param_name] = param_value.as_string(); - break; - case rclcpp::ParameterType::PARAMETER_INTEGER: - sub_dict[name][param_name] = param_value.as_int(); - break; - case rclcpp::ParameterType::PARAMETER_DOUBLE: - sub_dict[name][param_name] = param_value.as_double(); - break; - case rclcpp::ParameterType::PARAMETER_BOOL: - sub_dict[name][param_name] = param_value.as_bool(); - break; - case rclcpp::ParameterType::PARAMETER_STRING_ARRAY: - for (const auto& elem : param_value.as_string_array()) { - arr.push_back(elem); - } - sub_dict[name][param_name] = arr; - arr.clear(); - break; - default: - sub_dict[name][param_name] = py::cast(param_value); - break; - } - } - } - param_.attr("subscriber_cfg") = sub_dict; - - - // point cloud channel fusion - if (!node->has_parameter("pointcloud_channel_fusions")) { - RCLCPP_WARN(node->get_logger(), "No pointcloud_channel_fusions parameter found. Using default values."); - } else { - rclcpp::Parameter pointcloud_channel_fusion; - node->get_parameter("pointcloud_channel_fusions", pointcloud_channel_fusion); - - py::dict pointcloud_channel_fusion_dict; - auto pointcloud_channel_fusion_map = pointcloud_channel_fusion.as_string_array(); - for (const auto& channel_fusion : pointcloud_channel_fusion_map) { - const char* const fusion_name = channel_fusion.c_str(); - std::string fusion; - node->get_parameter(fusion_name, fusion); - if (!pointcloud_channel_fusion_dict.contains(fusion_name)) { - pointcloud_channel_fusion_dict[fusion_name] = fusion; - } - } - RCLCPP_INFO_STREAM(node->get_logger(), "pointcloud_channel_fusion_dict: " << pointcloud_channel_fusion_dict); - param_.attr("pointcloud_channel_fusions") = pointcloud_channel_fusion_dict; - } + // rclcpp::Parameter subscribers; + // node_->get_parameter("subscribers", subscribers); + + // py::dict sub_dict; + // auto subscribers_array = subscribers.as_string_array(); + // for (const auto& subscriber : subscribers_array) { + // const char* const name = subscriber.c_str(); + // if (!sub_dict.contains(name)) { + // sub_dict[name] = py::dict(); + // } + // std::map subscriber_params; + // node_->get_parameters(name, subscriber_params); + // for (const auto& param_pair : subscriber_params) { + // const char* const param_name = param_pair.first.c_str(); + // const auto& param_value = param_pair.second; + // std::vector arr; + // switch (param_value.get_type()) { + // case rclcpp::ParameterType::PARAMETER_STRING: + // sub_dict[name][param_name] = param_value.as_string(); + // break; + // case rclcpp::ParameterType::PARAMETER_INTEGER: + // sub_dict[name][param_name] = param_value.as_int(); + // break; + // case rclcpp::ParameterType::PARAMETER_DOUBLE: + // sub_dict[name][param_name] = param_value.as_double(); + // break; + // case rclcpp::ParameterType::PARAMETER_BOOL: + // sub_dict[name][param_name] = param_value.as_bool(); + // break; + // case rclcpp::ParameterType::PARAMETER_STRING_ARRAY: + // for (const auto& elem : param_value.as_string_array()) { + // arr.push_back(elem); + // } + // sub_dict[name][param_name] = arr; + // arr.clear(); + // break; + // default: + // sub_dict[name][param_name] = py::cast(param_value); + // break; + // } + // } + // } + // param_.attr("subscriber_cfg") = sub_dict; + + + // // point cloud channel fusion + // if (!node_->has_parameter("pointcloud_channel_fusions")) { + // RCLCPP_WARN(node_->get_logger(), "No pointcloud_channel_fusions parameter found. Using default values."); + // } else { + // rclcpp::Parameter pointcloud_channel_fusion; + // node_->get_parameter("pointcloud_channel_fusions", pointcloud_channel_fusion); + + // py::dict pointcloud_channel_fusion_dict; + // auto pointcloud_channel_fusion_map = pointcloud_channel_fusion.as_string_array(); + // for (const auto& channel_fusion : pointcloud_channel_fusion_map) { + // const char* const fusion_name = channel_fusion.c_str(); + // std::string fusion; + // node_->get_parameter(fusion_name, fusion); + // if (!pointcloud_channel_fusion_dict.contains(fusion_name)) { + // pointcloud_channel_fusion_dict[fusion_name] = fusion; + // } + // } + // RCLCPP_INFO_STREAM(node_->get_logger(), "pointcloud_channel_fusion_dict: " << pointcloud_channel_fusion_dict); + // param_.attr("pointcloud_channel_fusions") = pointcloud_channel_fusion_dict; + // } - // image channel fusion - if (!node->has_parameter("image_channel_fusions")) { - RCLCPP_WARN(node->get_logger(), "No image_channel_fusions parameter found. Using default values."); - } else { - rclcpp::Parameter image_channel_fusion; - node->get_parameter("image_channel_fusions", image_channel_fusion); - - py::dict image_channel_fusion_dict; - auto image_channel_fusion_map = image_channel_fusion.as_string_array(); - for (const auto& channel_fusion : image_channel_fusion_map) { - const char* const channel_fusion_name = channel_fusion.c_str(); - std::string fusion; - node->get_parameter(channel_fusion_name, fusion); - if (!image_channel_fusion_dict.contains(channel_fusion_name)) { - image_channel_fusion_dict[channel_fusion_name] = fusion; - } - } - RCLCPP_INFO_STREAM(node->get_logger(), "image_channel_fusion_dict: " << image_channel_fusion_dict); - param_.attr("image_channel_fusions") = image_channel_fusion_dict; - } - - param_.attr("update")(); - resolution_ = py::cast(param_.attr("get_value")("resolution")); - map_length_ = py::cast(param_.attr("get_value")("true_map_length")); - map_n_ = py::cast(param_.attr("get_value")("true_cell_n")); - - node->declare_parameter("enable_normal", false); - node->declare_parameter("enable_normal_color", false); - enable_normal_ = node->get_parameter("enable_normal").as_bool(); - enable_normal_color_ = node->get_parameter("enable_normal_color").as_bool(); + // // image channel fusion + // if (!node_->has_parameter("image_channel_fusions")) { + // RCLCPP_WARN(node_->get_logger(), "No image_channel_fusions parameter found. Using default values."); + // } else { + // rclcpp::Parameter image_channel_fusion; + // node_->get_parameter("image_channel_fusions", image_channel_fusion); + + // py::dict image_channel_fusion_dict; + // auto image_channel_fusion_map = image_channel_fusion.as_string_array(); + // for (const auto& channel_fusion : image_channel_fusion_map) { + // const char* const channel_fusion_name = channel_fusion.c_str(); + // std::string fusion; + // node_->get_parameter(channel_fusion_name, fusion); + // if (!image_channel_fusion_dict.contains(channel_fusion_name)) { + // image_channel_fusion_dict[channel_fusion_name] = fusion; + // } + // } + // RCLCPP_INFO_STREAM(node_->get_logger(), "image_channel_fusion_dict: " << image_channel_fusion_dict); + // param_.attr("image_channel_fusions") = image_channel_fusion_dict; + // } + + // param_.attr("update")(); + // resolution_ = py::cast(param_.attr("get_value")("resolution")); + // map_length_ = py::cast(param_.attr("get_value")("true_map_length")); + // map_n_ = py::cast(param_.attr("get_value")("true_cell_n")); + + // node_->declare_parameter("enable_normal", false); + // node_->declare_parameter("enable_normal_color", false); + // enable_normal_ = node_->get_parameter("enable_normal").as_bool(); + // enable_normal_color_ = node_->get_parameter("enable_normal_color").as_bool(); } From 59d9a21fe681fd9abaff3180738339ce39186088 Mon Sep 17 00:00:00 2001 From: amilearning Date: Tue, 5 Nov 2024 23:49:41 +0100 Subject: [PATCH 448/504] sub and pub --- .../elevation_mapping.py | 31 +- .../lib/elevation_mapping_cupy/parameter.py | 26 +- .../config/core/core_param.yaml | 23 +- .../elevation_mapping_ros.hpp | 4 +- .../elevation_mapping_wrapper.hpp | 9 +- .../elevation_mapping.py | 29 +- .../elevation_mapping_cupy/parameter.py | 10 +- .../src/elevation_mapping_ros.cpp | 342 +++++++++--------- .../src/elevation_mapping_wrapper.cpp | 199 +++++----- 9 files changed, 366 insertions(+), 307 deletions(-) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping.py index 4d704739..06f81dfb 100644 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping.py @@ -85,7 +85,7 @@ def __init__(self, param: Parameter): self.elevation_map[1] += self.initial_variance self.elevation_map[3] += 1.0 - # overlap clearance + # # overlap clearance cell_range = int(self.param.overlap_clear_range_xy / self.resolution) cell_range = np.clip(cell_range, 0, self.cell_n) self.cell_min = self.cell_n // 2 - cell_range // 2 @@ -95,27 +95,28 @@ def __init__(self, param: Parameter): self.mean_error = 0.0 self.additive_mean_error = 0.0 + self.compile_kernels() - self.compile_image_kernels() + # self.compile_image_kernels() - self.semantic_map.initialize_fusion() + # self.semantic_map.initialize_fusion() - weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') - param.load_weights(weight_file) + # weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') + # param.load_weights(weight_file) - if param.use_chainer: - self.traversability_filter = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) - else: - self.traversability_filter = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) - self.untraversable_polygon = xp.zeros((1, 2)) + # if param.use_chainer: + # self.traversability_filter = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) + # else: + # self.traversability_filter = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) + # self.untraversable_polygon = xp.zeros((1, 2)) - # Plugins - self.plugin_manager = PluginManager(cell_n=self.cell_n) - plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') - self.plugin_manager.load_plugin_settings(plugin_config_file) + # # Plugins + # self.plugin_manager = PluginManager(cell_n=self.cell_n) + # plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') + # self.plugin_manager.load_plugin_settings(plugin_config_file) - self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") + # self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") def clear(self): """Reset all the layers of the elevation & the semantic map.""" diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/parameter.py index 5fc3c110..2193ad02 100644 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/parameter.py @@ -171,13 +171,13 @@ class Parameter(Serializable): time_interval: float = 0.1 # Time layer is updated with this interval. max_variance: float = 1.0 # maximum variance for each cell. - dilation_size: float = 2 # dilation filter size before traversability filter. - dilation_size_initialize: float = 10 # dilation size after the init. + dilation_size: int = 2 # dilation filter size before traversability filter. + dilation_size_initialize: int = 10 # dilation size after the init. drift_compensation_alpha: float = 1.0 # drift compensation alpha for smoother update of drift compensation. traversability_inlier: float = 0.1 # cells with higher traversability are used for drift compensation. - wall_num_thresh: float = 100 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. - min_height_drift_cnt: float = 100 # drift compensation only happens if the valid cells are more than this number. + wall_num_thresh: int = 100 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. + min_height_drift_cnt: int = 100 # drift compensation only happens if the valid cells are more than this number. max_ray_length: float = 2.0 # maximum length for ray tracing. cleanup_step: float = 0.01 # substitute this value from validity layer at visibility cleanup. @@ -210,7 +210,7 @@ class Parameter(Serializable): position_noise_thresh: float = 0.1 # if the position change is bigger than this value, the drift compensation happens. orientation_noise_thresh: float = 0.1 # if the orientation change is bigger than this value, the drift compensation happens. - plugin_config_file: str = "config/plugin_config.yaml" # configuration file for the plugin + # plugin_config_file: str = "config/plugin_config.yaml" # configuration file for the plugin weight_file: str = "config/weights.dat" # weight file for traversability filter initial_variance: float = 10.0 # initial variance for each cell. @@ -289,12 +289,12 @@ def update(self): self.true_map_length = self.true_cell_n * self.resolution -if __name__ == "__main__": - param = Parameter() - print(param) - print(param.resolution) - param.set_value("resolution", 0.1) - print(param.resolution) +# if __name__ == "__main__": +# param = Parameter() +# print(param) +# print(param.resolution) +# param.set_value("resolution", 0.1) +# print(param.resolution) - print("names ", param.get_names()) - print("types ", param.get_types()) +# print("names ", param.get_names()) +# print("types ", param.get_types()) diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index c9228427..4c0d8302 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -1,6 +1,14 @@ elevation_mapping: ros__parameters: #### Basic parameters ######## + cell_n: 10000 # number of cells in the map. + data_type: 'float32' # data type for the map. + average_weight: 0.5 + drift_compensation_variance_inlier: 0.1 + checker_layer: 'traversability' # layer name for checking the validity of the cell. + min_filter_size: 5 # size of the filter for min filter. + min_filter_iteration: 3 # number of iterations for min filter. + initialized_variance: 10.0 # initial variance for each cell. resolution: 0.04 # resolution in m. map_length: 8.0 # map's size in m. sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). @@ -95,11 +103,14 @@ elevation_mapping: # channel_info_topic_name: '/camera/channel_info' subscribers: - pointcloud_topic1: '/a200/sensors/camera_1/points' - - image_topic1: '/a200/sensors/camera_0/color/image' - image_info1: '/a200/sensors/camera_0/color/camera_info' - # image_channel_info1: '/front_cam/channel_info' + pointcloud1: + topic_name: '/a200/sensors/camera_1/points' + data_type: 'pointcloud' + image1: + topic_name: '/a200/sensors/camera_0/color/image' + info_name: '/a200/sensors/camera_0/color/camera_info' + data_type: 'image' + # channel_name: '/front_cam/channel_info' # image_topic2: '/camera/rgb/image_raw2' # image_info2: '/camera/depth/camera_info2' @@ -120,7 +131,7 @@ elevation_mapping: # fps: # Publish rate. Use smaller value than `map_acquire_fps`. publishers: - elevation_map_raw: + elevation_map_raw: layers: ['elevation', 'traversability', 'variance','rgb'] basic_layers: ['elevation'] fps: 5.0 diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 18fd4eaf..b4abac57 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -96,7 +96,7 @@ class ElevationMappingNode : public rclcpp::Node { private: void readParameters(); -// void setupMapPublishers(); + void setupMapPublishers(); void pointcloudCallback(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::string& key); void inputPointCloud(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::vector& channels); // void inputImage(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::vector& channels); @@ -122,7 +122,7 @@ void imageChannelCallback(const std::shared_ptr& // void initializeWithTF(); // void publishMapToOdom(double error); // void publishStatistics(const ros::TimerEvent&); -// void publishMapOfIndex(int index); + void publishMapOfIndex(int index); // visualization_msgs::Marker vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id) const; diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index 0623d0f6..a6514843 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -43,9 +43,9 @@ class ElevationMappingWrapper { using RowMatrixXf = Eigen::Matrix; using ColMatrixXf = Eigen::Matrix; - ElevationMappingWrapper(rclcpp::Node::SharedPtr node); + ElevationMappingWrapper(); - void initialize(); + void initialize(const std::shared_ptr& node); void input(const RowMatrixXd& points, const std::vector& channels, const RowMatrixXd& R, const Eigen::VectorXd& t, const double positionNoise, const double orientationNoise); @@ -65,8 +65,9 @@ class ElevationMappingWrapper { void addNormalColorLayer(grid_map::GridMap& map); private: - rclcpp::Node::SharedPtr node_; - py::object setParameters(); + + std::shared_ptr node_; + void setParameters(); py::object map_; py::object param_; diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index 4d704739..b0b0b40f 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -85,7 +85,7 @@ def __init__(self, param: Parameter): self.elevation_map[1] += self.initial_variance self.elevation_map[3] += 1.0 - # overlap clearance + # # overlap clearance cell_range = int(self.param.overlap_clear_range_xy / self.resolution) cell_range = np.clip(cell_range, 0, self.cell_n) self.cell_min = self.cell_n // 2 - cell_range // 2 @@ -95,27 +95,28 @@ def __init__(self, param: Parameter): self.mean_error = 0.0 self.additive_mean_error = 0.0 + self.compile_kernels() self.compile_image_kernels() - self.semantic_map.initialize_fusion() + # self.semantic_map.initialize_fusion() - weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') - param.load_weights(weight_file) + # weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') + # param.load_weights(weight_file) - if param.use_chainer: - self.traversability_filter = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) - else: - self.traversability_filter = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) - self.untraversable_polygon = xp.zeros((1, 2)) + # if param.use_chainer: + # self.traversability_filter = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) + # else: + # self.traversability_filter = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) + # self.untraversable_polygon = xp.zeros((1, 2)) - # Plugins - self.plugin_manager = PluginManager(cell_n=self.cell_n) - plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') - self.plugin_manager.load_plugin_settings(plugin_config_file) + # # Plugins + # self.plugin_manager = PluginManager(cell_n=self.cell_n) + # plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') + # self.plugin_manager.load_plugin_settings(plugin_config_file) - self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") + # self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") def clear(self): """Reset all the layers of the elevation & the semantic map.""" diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 52fc2664..2193ad02 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -171,13 +171,13 @@ class Parameter(Serializable): time_interval: float = 0.1 # Time layer is updated with this interval. max_variance: float = 1.0 # maximum variance for each cell. - dilation_size: float = 2 # dilation filter size before traversability filter. - dilation_size_initialize: float = 10 # dilation size after the init. + dilation_size: int = 2 # dilation filter size before traversability filter. + dilation_size_initialize: int = 10 # dilation size after the init. drift_compensation_alpha: float = 1.0 # drift compensation alpha for smoother update of drift compensation. traversability_inlier: float = 0.1 # cells with higher traversability are used for drift compensation. - wall_num_thresh: float = 100 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. - min_height_drift_cnt: float = 100 # drift compensation only happens if the valid cells are more than this number. + wall_num_thresh: int = 100 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. + min_height_drift_cnt: int = 100 # drift compensation only happens if the valid cells are more than this number. max_ray_length: float = 2.0 # maximum length for ray tracing. cleanup_step: float = 0.01 # substitute this value from validity layer at visibility cleanup. @@ -210,7 +210,7 @@ class Parameter(Serializable): position_noise_thresh: float = 0.1 # if the position change is bigger than this value, the drift compensation happens. orientation_noise_thresh: float = 0.1 # if the orientation change is bigger than this value, the drift compensation happens. - plugin_config_file: str = "config/plugin_config.yaml" # configuration file for the plugin + # plugin_config_file: str = "config/plugin_config.yaml" # configuration file for the plugin weight_file: str = "config/weights.dat" # weight file for traversability filter initial_variance: float = 10.0 # initial variance for each cell. diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index e6535d38..760a6dc5 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -21,6 +21,19 @@ namespace elevation_mapping_cupy { +std::vector extract_unique_names(const std::map& subscriber_params) { + std::set unique_names_set; + for (const auto& param : subscriber_params) { + std::size_t pos = param.first.find('.'); + if (pos != std::string::npos) { + std::string name = param.first.substr(0, pos); + unique_names_set.insert(name); + } + } + return std::vector(unique_names_set.begin(), unique_names_set.end()); +} + + ElevationMappingNode::ElevationMappingNode() : rclcpp::Node("elevation_mapping_node", rclcpp::NodeOptions().automatically_declare_parameters_from_overrides(true)), node_(std::shared_ptr(this, [](auto *) {})), @@ -95,7 +108,12 @@ ElevationMappingNode::ElevationMappingNode() RCLCPP_INFO(this->get_logger(), "always_clear_with_initializer: %s", alwaysClearWithInitializer_ ? "true" : "false"); enablePointCloudPublishing_ = enablePointCloudPublishing; - + + // map_ = std::make_shared(); + // map_->initialize(node_); + + + std::map subscriber_params, publisher_params; if (!this->get_parameters("subscribers", subscriber_params)) { RCLCPP_FATAL(this->get_logger(), "There aren't any subscribers to be configured, the elevation mapping cannot be configured. Exit"); @@ -106,121 +124,117 @@ ElevationMappingNode::ElevationMappingNode() rclcpp::shutdown(); } - for (const auto& name : subscriber_params) { - if (name.first.find("image_topic") != std::string::npos) { - std::string camera_topic = name.second.as_string(); - // setup image subscriber - std::string transport_hint = "compressed"; - std::size_t ind = camera_topic.find(transport_hint); // Find if compressed is in the topic name - if (ind != std::string::npos) { - transport_hint = camera_topic.substr(ind, camera_topic.length()); // Get the hint as the last part - camera_topic.erase(ind - 1, camera_topic.length()); // We remove the hint from the topic - } else { - transport_hint = "raw"; // In the default case we assume raw topic - } - // Create a standard ROS2 subscription for the image topic - ImageSubscriberPtr image_sub = std::make_shared(this, camera_topic, rmw_qos_profile_sensor_data); - // image_sub->subscribe(this->shared_from_this(), camera_topic, 1); + + auto unique_sub_names = extract_unique_names(subscriber_params); + for (const auto& sub_name : unique_sub_names) { + std::string data_type; + if(this->get_parameter("subscribers." + sub_name + ".data_type", data_type)){ + // image + if(data_type == "image"){ + std::string camera_topic; + std::string info_topic; + this->get_parameter("subscribers." + sub_name + ".topic_name", camera_topic); + this->get_parameter("subscribers." + sub_name + ".info_name", info_topic); + RCLCPP_INFO(this->get_logger(), "camera_topic %s: %s", sub_name.c_str(), camera_topic.c_str()); + RCLCPP_INFO(this->get_logger(), "info_name %s: %s", sub_name.c_str(), info_topic.c_str()); + + // std::string transport_hint = "compressed"; + // std::size_t ind = camera_topic.find(transport_hint); // Find if compressed is in the topic name + // if (ind != std::string::npos) { + // transport_hint = camera_topic.substr(ind, camera_topic.length()); // Get the hint as the last part + // camera_topic.erase(ind - 1, camera_topic.length()); // We remove the hint from the topic + // } else { + // transport_hint = "raw"; // In the default case we assume raw topic + // } + + ImageSubscriberPtr image_sub = std::make_shared(this, camera_topic, rmw_qos_profile_sensor_data); imageSubs_.push_back(image_sub); - - - + CameraInfoSubscriberPtr cam_info_sub = std::make_shared(this, info_topic, rmw_qos_profile_sensor_data); + cameraInfoSubs_.push_back(cam_info_sub); - std::string info_topic; std::string channel_info_topic; - // Check if the last character is a digit - if (std::isdigit(name.first.back())) { - char last_char = name.first.back(); - std::string cam_info_name_param = "image_info" + std::string(1, last_char); - std::string channel_info_name_param = "image_channel_info" + std::string(1, last_char); - if (this->get_parameter("subscribers." + cam_info_name_param, info_topic)) { - RCLCPP_INFO(this->get_logger(), "Generated parameter %s: %s", cam_info_name_param.c_str(), info_topic.c_str()); - CameraInfoSubscriberPtr cam_info_sub = std::make_shared(this, info_topic, rmw_qos_profile_sensor_data); - // cam_info_sub->subscribe(this->shared_from_this(), info_topic, 1); - cameraInfoSubs_.push_back(cam_info_sub); - if (this->get_parameter("subscribers." + channel_info_name_param, channel_info_topic)) { - ChannelInfoSubscriberPtr channel_info_sub = std::make_shared(this, channel_info_topic, rmw_qos_profile_sensor_data); - // channel_info_sub->subscribe(this->shared_from_this(), channel_info_topic, 1); - channelInfoSubs_.push_back(channel_info_sub); - CameraChannelSyncPtr sync = std::make_shared(CameraChannelPolicy(10), *image_sub, *cam_info_sub, *channel_info_sub); - sync->registerCallback(std::bind(&ElevationMappingNode::imageChannelCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - cameraChannelSyncs_.push_back(sync); - RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s, Camera info topic: %s, Channel info topic: %s", camera_topic.c_str(), info_topic.c_str(), channel_info_topic.c_str()); - }else{ - std::string key = name.first; - channels_[key].push_back("rgb"); - // RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s, Camera info topic: %s. Channel info topic: %s", camera_topic.c_str(), info_topic.c_str(), (channel_info_topic.empty() ? ("Not found. Using channels: " + boost::algorithm::join(channels_[key], ", ")).c_str() : channel_info_topic.c_str())); - CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); - sync->registerCallback(std::bind(&ElevationMappingNode::imageCallback, this, std::placeholders::_1, std::placeholders::_2, key)); - cameraSyncs_.push_back(sync); - } - }else{ - throw std::runtime_error("Info topic is missing for camera: " + camera_topic); - } + if (this->get_parameter("subscribers." + sub_name + ".channel_name", channel_info_topic)) { + ChannelInfoSubscriberPtr channel_info_sub = std::make_shared(this, channel_info_topic, rmw_qos_profile_sensor_data); + channelInfoSubs_.push_back(channel_info_sub); + CameraChannelSyncPtr sync = std::make_shared(CameraChannelPolicy(10), *image_sub, *cam_info_sub, *channel_info_sub); + sync->registerCallback(std::bind(&ElevationMappingNode::imageChannelCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + cameraChannelSyncs_.push_back(sync); + RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s, Camera info topic: %s, Channel info topic: %s", camera_topic.c_str(), info_topic.c_str(), channel_info_topic.c_str()); }else{ - throw std::runtime_error("Error: image param numbering at the end "); + std::string key = sub_name; + channels_[key].push_back("rgb"); + // RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s, Camera info topic: %s. Channel info topic: %s", camera_topic.c_str(), info_topic.c_str(), (channel_info_topic.empty() ? ("Not found. Using channels: " + boost::algorithm::join(channels_[key], ", ")).c_str() : channel_info_topic.c_str())); + CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); + sync->registerCallback(std::bind(&ElevationMappingNode::imageCallback, this, std::placeholders::_1, std::placeholders::_2, key)); + cameraSyncs_.push_back(sync); } - // generate point cloud subscriber - }else if(name.first.find("pointcloud_topic") != std::string::npos) { - std::string pointcloud_topic = name.second.as_string(); - RCLCPP_INFO(this->get_logger(), "Generated parameter %s:", name.first.c_str()); - std::string key = name.first; - channels_[key].push_back("x"); - channels_[key].push_back("y"); - channels_[key].push_back("z"); - auto callback = [this, key](const sensor_msgs::msg::PointCloud2::SharedPtr msg) { + }else if(data_type == "pointcloud"){ + std::string pointcloud_topic; + this->get_parameter("subscribers." + sub_name + ".topic_name", pointcloud_topic); + std::string key = sub_name; + channels_[key].push_back("x"); + channels_[key].push_back("y"); + channels_[key].push_back("z"); + auto callback = [this, key](const sensor_msgs::msg::PointCloud2::SharedPtr msg) { this->pointcloudCallback(msg, key); }; auto sub = this->create_subscription(pointcloud_topic, 1, callback); pointcloudSubs_.push_back(sub); RCLCPP_INFO(this->get_logger(), "Subscribed to PointCloud2 topic: %s", pointcloud_topic.c_str()); - } + } + } + } + + + + auto unique_pub_names = extract_unique_names(publisher_params); + + // for (const auto& pub_name : unique_pub_names) { + // std::string topic_name = pub_name; + // std::vector layers_list; + // std::vector basic_layers_list; + // double fps; + // this->get_parameter("publishers." + pub_name + ".layers", layers_list) + // this->get_parameter("publishers." + pub_name + ".basic_layers", basic_layers_list) + // this->get_parameter("publishers." + pub_name + ".fps", fps) + // } + for (const auto& pub_name : unique_pub_names) { + std::string topic_name = pub_name; + double fps; + std::vector layers_list; + std::vector basic_layers_list; + + this->get_parameter("publishers." + pub_name + ".layers", layers_list); + this->get_parameter("publishers." + pub_name + ".basic_layers", basic_layers_list); + this->get_parameter("publishers." + pub_name + ".fps", fps); + + if (fps > updateGridMapFps) { + RCLCPP_WARN( + this->get_logger(), + "[ElevationMappingCupy] fps for topic %s is larger than map_acquire_fps (%f > %f). The topic data will be only updated at %f " + "fps.", + topic_name.c_str(), fps, updateGridMapFps, updateGridMapFps); } - // get node pointer, pass into Class B - // map_ = std::make_shared(shared_from_this()); - map_->initialize(); - -// // Register map publishers -// for (auto itr = publishers.begin(); itr != publishers.end(); ++itr) { -// // Parse params -// std::string topic_name = itr->first; -// std::vector layers_list; -// std::vector basic_layers_list; -// auto layers = itr->second["layers"]; -// auto basic_layers = itr->second["basic_layers"]; -// double fps = itr->second["fps"]; - -// if (fps > updateGridMapFps) { -// ROS_WARN( -// "[ElevationMappingCupy] fps for topic %s is larger than map_acquire_fps (%f > %f). The topic data will be only updated at %f " -// "fps.", -// topic_name.c_str(), fps, updateGridMapFps, updateGridMapFps); -// } + // Make publishers + auto pub = this->create_publisher(topic_name, 1); + RCLCPP_INFO(this->get_logger(), "Publishing map to topic %s", topic_name.c_str()); + mapPubs_.push_back(pub); -// for (int32_t i = 0; i < layers.size(); ++i) { -// layers_list.push_back(static_cast(layers[i])); -// } + // Register map layers + map_layers_.push_back(layers_list); + map_basic_layers_.push_back(basic_layers_list); -// for (int32_t i = 0; i < basic_layers.size(); ++i) { -// basic_layers_list.push_back(static_cast(basic_layers[i])); -// } + // Register map fps + map_fps_.push_back(fps); + map_fps_unique_.insert(fps); -// // Make publishers -// ros::Publisher pub = nh_.advertise(topic_name, 1); -// mapPubs_.push_back(pub); + } -// // Register map layers -// map_layers_.push_back(layers_list); -// map_basic_layers_.push_back(basic_layers_list); -// // Register map fps -// map_fps_.push_back(fps); -// map_fps_unique_.insert(fps); -// } -// setupMapPublishers(); + setupMapPublishers(); // pointPub_ = nh_.advertise("elevation_map_points", 1); // alivePub_ = nh_.advertise("alive", 1); @@ -264,74 +278,75 @@ ElevationMappingNode::ElevationMappingNode() // // Setup map publishers -// void ElevationMappingNode::setupMapPublishers() { -// // Find the layers with highest fps. -// float max_fps = -1; -// // Create timers for each unique map frequencies -// for (auto fps : map_fps_unique_) { -// // Which publisher to call in the timer callback -// std::vector indices; -// // If this fps is max, update the map layers. -// if (fps >= max_fps) { -// max_fps = fps; -// map_layers_all_.clear(); -// } -// for (int i = 0; i < map_fps_.size(); i++) { -// if (map_fps_[i] == fps) { -// indices.push_back(i); -// // If this fps is max, add layers -// if (fps >= max_fps) { -// for (const auto layer : map_layers_[i]) { -// map_layers_all_.insert(layer); -// } -// } -// } -// } -// // Callback funtion. -// // It publishes to specific topics. -// auto cb = [this, indices](const ros::TimerEvent&) { -// for (int i : indices) { -// publishMapOfIndex(i); -// } -// }; -// double duration = 1.0 / (fps + 0.00001); -// mapTimers_.push_back(nh_.createTimer(ros::Duration(duration), cb)); -// } -// } - -// void ElevationMappingNode::publishMapOfIndex(int index) { -// // publish the map layers of index -// if (!isGridmapUpdated_) { -// return; -// } -// grid_map_msgs::GridMap msg; -// std::vector layers; - -// { // need continuous lock between adding layers and converting to message. Otherwise updateGridmap can reset the data not in -// // map_layers_all_ -// std::lock_guard lock(mapMutex_); -// for (const auto& layer : map_layers_[index]) { -// const bool is_layer_in_all = map_layers_all_.find(layer) != map_layers_all_.end(); -// if (is_layer_in_all && gridMap_.exists(layer)) { -// layers.push_back(layer); -// } else if (map_.exists_layer(layer)) { -// // if there are layers which is not in the syncing layer. -// ElevationMappingWrapper::RowMatrixXf map_data; -// map_.get_layer_data(layer, map_data); -// gridMap_.add(layer, map_data); -// layers.push_back(layer); -// } -// } -// if (layers.empty()) { -// return; -// } +void ElevationMappingNode::setupMapPublishers() { + // Find the layers with highest fps. + float max_fps = -1; + // Create timers for each unique map frequencies + for (auto fps : map_fps_unique_) { + // Which publisher to call in the timer callback + std::vector indices; + // If this fps is max, update the map layers. + if (fps >= max_fps) { + max_fps = fps; + map_layers_all_.clear(); + } + for (int i = 0; i < map_fps_.size(); i++) { + if (map_fps_[i] == fps) { + indices.push_back(i); + // If this fps is max, add layers + if (fps >= max_fps) { + for (const auto layer : map_layers_[i]) { + map_layers_all_.insert(layer); + } + } + } + } + // Callback funtion. + // It publishes to specific topics. + auto cb = [this, indices]() -> void { + for (int i : indices) { + publishMapOfIndex(i); + } + }; + double duration = 1.0 / (fps + 0.00001); + mapTimers_.push_back(this->create_wall_timer(std::chrono::duration(duration), cb)); + } +} -// grid_map::GridMapRosConverter::toMessage(gridMap_, layers, msg); -// } -// msg.basic_layers = map_basic_layers_[index]; -// mapPubs_[index].publish(msg); -// } +void ElevationMappingNode::publishMapOfIndex(int index) { + // publish the map layers of index + if (!isGridmapUpdated_) { + return; + } + grid_map_msgs::msg::GridMap msg; + std::vector layers; + + // { // need continuous lock between adding layers and converting to message. Otherwise updateGridmap can reset the data not in + // // map_layers_all_ + // std::lock_guard lock(mapMutex_); + // for (const auto& layer : map_layers_[index]) { + // const bool is_layer_in_all = map_layers_all_.find(layer) != map_layers_all_.end(); + // if (is_layer_in_all && gridMap_.exists(layer)) { + // layers.push_back(layer); + // } else if (map_.exists_layer(layer)) { + // // if there are layers which is not in the syncing layer. + // ElevationMappingWrapper::RowMatrixXf map_data; + // map_.get_layer_data(layer, map_data); + // gridMap_.add(layer, map_data); + // layers.push_back(layer); + // } + // } + // if (layers.empty()) { + // return; + // } + + // grid_map::GridMapRosConverter::toMessage(gridMap_, layers, msg); + // } + + msg.basic_layers = map_basic_layers_[index]; + mapPubs_[index]->publish(msg); +} void ElevationMappingNode::pointcloudCallback(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::string& key) { @@ -487,6 +502,7 @@ void ElevationMappingNode::imageCallback(const std::shared_ptrnow(); // inputImage(image_msg, camera_info_msg, channels_[key]); RCLCPP_DEBUG(this->get_logger(), "ElevationMap imageCallback processed an image in %f sec.", (this->now() - start).seconds()); + } diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index f0796abb..013fb1b9 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -18,12 +18,17 @@ #include + namespace elevation_mapping_cupy { -ElevationMappingWrapper::ElevationMappingWrapper(rclcpp::Node::SharedPtr node) -:node_(node) {} +ElevationMappingWrapper::ElevationMappingWrapper(){} -void ElevationMappingWrapper::initialize() { +void ElevationMappingWrapper::initialize(const std::shared_ptr& node){ + if (!node) { + RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Invalid node shared pointer"); + return; + } + node_ = node; // Add the elevation_mapping_cupy path to sys.path auto threading = py::module::import("threading"); py::gil_scoped_acquire acquire; @@ -35,100 +40,124 @@ void ElevationMappingWrapper::initialize() { path.attr("insert")(0, module_path); auto elevation_mapping = py::module::import("elevation_mapping_cupy.elevation_mapping"); - // auto parameter = py::module::import("math"); - - // auto param_2 = parameter.attr("Parameter")(); - // setParameters(param_v2); - auto params = setParameters(); - - // map_ = elevation_mapping.attr("ElevationMap")(param_v2); + auto parameter = py::module::import("elevation_mapping_cupy.parameter"); + param_ = parameter.attr("Parameter")(); + setParameters(); + map_ = elevation_mapping.attr("ElevationMap")(param_); } // /** // * Load ros parameters into Parameter class. // * Search for the same name within the name space. // */ -py::object ElevationMappingWrapper::setParameters() { - auto parameter = py::module::import("elevation_mapping_cupy.parameter"); - auto param_2 = parameter.attr("Parameter")(); - return param_2; +void ElevationMappingWrapper::setParameters() { + + // auto parameter = py::module::import("elevation_mapping_cupy.parameter"); + // auto param_ = parameter.attr("Parameter")(); + // Get all parameters names and types. - // py::list paramNames = param_.attr("get_names")(); - // py::list paramTypes = param_.attr("get_types")(); - // py::gil_scoped_acquire acquire; + py::list paramNames = param_.attr("get_names")(); + py::list paramTypes = param_.attr("get_types")(); + py::gil_scoped_acquire acquire; // // Try to find the parameter in the ROS parameter server. // // If there was a parameter, set it to the Parameter variable. - // for (size_t i = 0; i < paramNames.size(); i++) { - // std::string type = py::cast(paramTypes[i]); - // std::string name = py::cast(paramNames[i]); - // if (type == "float") { - // float param; - // if (node_->get_parameter(name, param)) { - // param_.attr("set_value")(name, param); - // } - // } else if (type == "str") { - // std::string param; - // if (node_->get_parameter(name, param)) { - // param_.attr("set_value")(name, param); - // } - // } else if (type == "bool") { - // bool param; - // if (node_->get_parameter(name, param)) { - // param_.attr("set_value")(name, param); - // } - // } else if (type == "int") { - // int param; - // if (node_->get_parameter(name, param)) { - // param_.attr("set_value")(name, param); - // } - // } - // } + for (size_t i = 0; i < paramNames.size(); i++) { + std::string type = py::cast(paramTypes[i]); + std::string name = py::cast(paramNames[i]); + RCLCPP_INFO(node_->get_logger(), "type: %s, name %s", type.c_str(), name.c_str()); + if (type == "float") { + float param; + if (node_->get_parameter(name, param)) { + RCLCPP_INFO(node_->get_logger(), "Retrieved parameter: %s value: %f", name.c_str(), param); + param_.attr("set_value")(name, param); + RCLCPP_INFO(node_->get_logger(), "Set parameter: %s value: %f", name.c_str(), param); + } else { + RCLCPP_WARN(node_->get_logger(), "Parameter not found or invalid: %s", name.c_str()); + } + } else if (type == "str") { + std::string param; + if (node_->get_parameter(name, param)) { + RCLCPP_INFO(node_->get_logger(), "Retrieved parameter: %s value: %s", name.c_str(), param.c_str()); + param_.attr("set_value")(name, param); + RCLCPP_INFO(node_->get_logger(), "Set parameter: %s value: %s", name.c_str(), param.c_str()); + } else { + RCLCPP_WARN(node_->get_logger(), "Parameter not found or invalid: %s", name.c_str()); + } + } else if (type == "bool") { + bool param; + if (node_->get_parameter(name, param)) { + RCLCPP_INFO(node_->get_logger(), "Retrieved parameter: %s value: %s", name.c_str(), param ? "true" : "false"); + param_.attr("set_value")(name, param); + RCLCPP_INFO(node_->get_logger(), "Set parameter: %s value: %s", name.c_str(), param ? "true" : "false"); + } else { + RCLCPP_WARN(node_->get_logger(), "Parameter not found or invalid: %s", name.c_str()); + } + } else if (type == "int") { + int param; + if (node_->get_parameter(name, param)) { + RCLCPP_INFO(node_->get_logger(), "Retrieved parameter: %s value: %d", name.c_str(), param); + param_.attr("set_value")(name, param); + RCLCPP_INFO(node_->get_logger(), "Set parameter: %s value: %d", name.c_str(), param); + } else { + RCLCPP_WARN(node_->get_logger(), "Parameter not found or invalid: %s", name.c_str()); + } + } + + } + py::dict sub_dict; + // rclcpp::Parameter subscribers; + std::vector parameter_prefixes; + auto parameters = node_->list_parameters(parameter_prefixes, 2); // List all parameters with a maximum depth of 10 + for (const auto& param_name : parameters.names) { + if (param_name.find("subscribers") != std::string::npos) { + RCLCPP_WARN(node_->get_logger(), "Subscriber : %s", param_name.c_str()); - // rclcpp::Parameter subscribers; - // node_->get_parameter("subscribers", subscribers); - - // py::dict sub_dict; - // auto subscribers_array = subscribers.as_string_array(); - // for (const auto& subscriber : subscribers_array) { - // const char* const name = subscriber.c_str(); - // if (!sub_dict.contains(name)) { - // sub_dict[name] = py::dict(); - // } - // std::map subscriber_params; - // node_->get_parameters(name, subscriber_params); - // for (const auto& param_pair : subscriber_params) { - // const char* const param_name = param_pair.first.c_str(); - // const auto& param_value = param_pair.second; - // std::vector arr; - // switch (param_value.get_type()) { - // case rclcpp::ParameterType::PARAMETER_STRING: - // sub_dict[name][param_name] = param_value.as_string(); - // break; - // case rclcpp::ParameterType::PARAMETER_INTEGER: - // sub_dict[name][param_name] = param_value.as_int(); - // break; - // case rclcpp::ParameterType::PARAMETER_DOUBLE: - // sub_dict[name][param_name] = param_value.as_double(); - // break; - // case rclcpp::ParameterType::PARAMETER_BOOL: - // sub_dict[name][param_name] = param_value.as_bool(); - // break; - // case rclcpp::ParameterType::PARAMETER_STRING_ARRAY: - // for (const auto& elem : param_value.as_string_array()) { - // arr.push_back(elem); - // } - // sub_dict[name][param_name] = arr; - // arr.clear(); - // break; - // default: - // sub_dict[name][param_name] = py::cast(param_value); - // break; - // } - // } - // } - // param_.attr("subscriber_cfg") = sub_dict; + + // const char* const name = param_name.c_str(); + // std::string subscriber_params; + // node_->get_parameter(param_name, subscriber); + // const auto& subscriber_params = subscriber.second; + // if (!sub_dict.contains(name)) { + // sub_dict[name] = py::dict(); + // } + // for (auto iterat : subscriber_params) { + // const char* const key = iterat.first.c_str(); + // const auto val = iterat.second; + // std::vector arr; + // switch (val.getType()) { + // case XmlRpc::XmlRpcValue::TypeString: + // sub_dict[name][key] = static_cast(val); + // break; + // case XmlRpc::XmlRpcValue::TypeInt: + // sub_dict[name][key] = static_cast(val); + // break; + // case XmlRpc::XmlRpcValue::TypeDouble: + // sub_dict[name][key] = static_cast(val); + // break; + // case XmlRpc::XmlRpcValue::TypeBoolean: + // sub_dict[name][key] = static_cast(val); + // break; + // case XmlRpc::XmlRpcValue::TypeArray: + // for (int32_t i = 0; i < val.size(); ++i) { + // auto elem = static_cast(val[i]); + // arr.push_back(elem); + // } + // sub_dict[name][key] = arr; + // arr.clear(); + // break; + // case XmlRpc::XmlRpcValue::TypeStruct: + // break; + // default: + // sub_dict[name][key] = py::cast(val); + // break; + // } + // } + } + } + param_.attr("subscriber_cfg") = sub_dict; + // // point cloud channel fusion From 61e10c55515e5300f6d2a27ac80ce0914c1e7780 Mon Sep 17 00:00:00 2001 From: amilearning Date: Thu, 7 Nov 2024 11:56:34 +0100 Subject: [PATCH 449/504] upto init --- elevation_mapping_cupy/CMakeLists.txt | 6 +- .../config/core/core_param.yaml | 5 +- .../elevation_mapping_wrapper.hpp | 2 + .../elevation_mapping.py | 38 ++-- .../elevation_mapping_cupy/parameter.py | 4 +- .../src/elevation_mapping_ros.cpp | 127 +++++------- .../src/elevation_mapping_wrapper.cpp | 191 +++++++++--------- 7 files changed, 183 insertions(+), 190 deletions(-) diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index fa8e2d25..91e4db8d 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -41,6 +41,10 @@ find_package(tf2_eigen REQUIRED) find_package(ament_cmake_python REQUIRED) find_package(python_cmake_module REQUIRED) + +_ament_cmake_python_register_environment_hook() +ament_python_install_package(${PROJECT_NAME} PACKAGE_DIR script/${PROJECT_NAME}) + # List dependencies for ament_target_dependencies set(dependencies rclcpp @@ -112,7 +116,7 @@ install( ) -ament_python_install_package(${PROJECT_NAME} PACKAGE_DIR script/${PROJECT_NAME}) + install(PROGRAMS DESTINATION lib/${PROJECT_NAME} diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 4c0d8302..19f8aa28 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -64,11 +64,12 @@ elevation_mapping: enable_pointcloud_publishing: false enable_drift_corrected_TF_publishing: false enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + enable_normal: false #### Traversability filter ######## use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. - weight_file: '/config/core/weights.dat' # Weight file for traversability filter - + weight_file: '/share/elevation_mapping_cupy/config/core/weights.dat' # Weight file for traversability filter + plugin_config_file: '/share/elevation_mapping_cupy/config/core/plugin_config.yaml' # Configuration file for the plugin. #### Upper bound ######## use_only_above_for_upper_bound: false diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp index a6514843..f0090254 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_wrapper.hpp @@ -37,6 +37,8 @@ namespace py = pybind11; namespace elevation_mapping_cupy { +std::vector extract_unique_names(const std::map& subscriber_params); + class ElevationMappingWrapper { public: using RowMatrixXd = Eigen::Matrix; diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index b0b0b40f..ea19064c 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -5,6 +5,8 @@ import os from typing import List, Any, Tuple, Union +from rclpy.logging import get_logger +from ament_index_python.packages import get_package_prefix import numpy as np import threading import subprocess @@ -42,6 +44,7 @@ import cupy as cp + xp = cp pool = cp.cuda.MemoryPool(cp.cuda.malloc_managed) cp.cuda.set_allocator(pool.malloc) @@ -97,26 +100,31 @@ def __init__(self, param: Parameter): self.compile_kernels() - + get_logger('elevation_mapping').info("Finished compiling kernels.") self.compile_image_kernels() + get_logger('elevation_mapping').info("Finished compiling image kernels.") + self.semantic_map.initialize_fusion() + get_logger('elevation_mapping').info("Finished compiling semantic_map kernels.") - # self.semantic_map.initialize_fusion() - - # weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') - # param.load_weights(weight_file) + weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') + package_prefix = get_package_prefix('elevation_mapping_cupy') + get_logger('elevation_mapping').info("weight file : ." + str(package_prefix) + str(weight_file)) + param.load_weights(package_prefix+weight_file) - # if param.use_chainer: - # self.traversability_filter = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) - # else: - # self.traversability_filter = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) - # self.untraversable_polygon = xp.zeros((1, 2)) + if param.use_chainer: + self.traversability_filter = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) + else: + self.traversability_filter = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) + + self.untraversable_polygon = xp.zeros((1, 2)) - # # Plugins - # self.plugin_manager = PluginManager(cell_n=self.cell_n) - # plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') - # self.plugin_manager.load_plugin_settings(plugin_config_file) + # Plugins + self.plugin_manager = PluginManager(cell_n=self.cell_n) + plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') + get_logger('elevation_mapping').info("plugin file : ." + str(package_prefix) + str(plugin_config_file)) + self.plugin_manager.load_plugin_settings(package_prefix+plugin_config_file) - # self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") + self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") def clear(self): """Reset all the layers of the elevation & the semantic map.""" diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py index 2193ad02..d23711eb 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/parameter.py @@ -210,7 +210,7 @@ class Parameter(Serializable): position_noise_thresh: float = 0.1 # if the position change is bigger than this value, the drift compensation happens. orientation_noise_thresh: float = 0.1 # if the orientation change is bigger than this value, the drift compensation happens. - # plugin_config_file: str = "config/plugin_config.yaml" # configuration file for the plugin + plugin_config_file: str = "config/plugin_config.yaml" # configuration file for the plugin weight_file: str = "config/weights.dat" # weight file for traversability filter initial_variance: float = 10.0 # initial variance for each cell. @@ -225,7 +225,7 @@ class Parameter(Serializable): cell_n: int = None # number of cells in the map true_cell_n: int = None # true number of cells in the map - def load_weights(self, filename): + def load_weights(self, filename: str): """ Load weights from a file into the model's parameters. diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 760a6dc5..7ebb5dd2 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -21,17 +21,6 @@ namespace elevation_mapping_cupy { -std::vector extract_unique_names(const std::map& subscriber_params) { - std::set unique_names_set; - for (const auto& param : subscriber_params) { - std::size_t pos = param.first.find('.'); - if (pos != std::string::npos) { - std::string name = param.first.substr(0, pos); - unique_names_set.insert(name); - } - } - return std::vector(unique_names_set.begin(), unique_names_set.end()); -} ElevationMappingNode::ElevationMappingNode() @@ -59,9 +48,6 @@ ElevationMappingNode::ElevationMappingNode() bool enablePointCloudPublishing(false); py::gil_scoped_acquire acquire; - auto math = py::module::import("math"); - double root_two = math.attr("sqrt")(2.0).cast(); - RCLCPP_INFO(this->get_logger(), "The square root of 2 is: %f", root_two); this->get_parameter("initialize_frame_id", initialize_frame_id_); this->get_parameter("initialize_tf_offset", initialize_tf_offset_); @@ -109,8 +95,8 @@ ElevationMappingNode::ElevationMappingNode() enablePointCloudPublishing_ = enablePointCloudPublishing; - // map_ = std::make_shared(); - // map_->initialize(node_); + map_ = std::make_shared(); + map_->initialize(node_); @@ -190,46 +176,38 @@ ElevationMappingNode::ElevationMappingNode() auto unique_pub_names = extract_unique_names(publisher_params); - // for (const auto& pub_name : unique_pub_names) { - // std::string topic_name = pub_name; - // std::vector layers_list; - // std::vector basic_layers_list; - // double fps; - // this->get_parameter("publishers." + pub_name + ".layers", layers_list) - // this->get_parameter("publishers." + pub_name + ".basic_layers", basic_layers_list) - // this->get_parameter("publishers." + pub_name + ".fps", fps) - // } + for (const auto& pub_name : unique_pub_names) { - std::string topic_name = pub_name; - double fps; - std::vector layers_list; - std::vector basic_layers_list; - - this->get_parameter("publishers." + pub_name + ".layers", layers_list); - this->get_parameter("publishers." + pub_name + ".basic_layers", basic_layers_list); - this->get_parameter("publishers." + pub_name + ".fps", fps); - - if (fps > updateGridMapFps) { - RCLCPP_WARN( - this->get_logger(), - "[ElevationMappingCupy] fps for topic %s is larger than map_acquire_fps (%f > %f). The topic data will be only updated at %f " - "fps.", - topic_name.c_str(), fps, updateGridMapFps, updateGridMapFps); - } + std::string topic_name = pub_name; + double fps; + std::vector layers_list; + std::vector basic_layers_list; + + this->get_parameter("publishers." + pub_name + ".layers", layers_list); + this->get_parameter("publishers." + pub_name + ".basic_layers", basic_layers_list); + this->get_parameter("publishers." + pub_name + ".fps", fps); + + if (fps > updateGridMapFps) { + RCLCPP_WARN( + this->get_logger(), + "[ElevationMappingCupy] fps for topic %s is larger than map_acquire_fps (%f > %f). The topic data will be only updated at %f " + "fps.", + topic_name.c_str(), fps, updateGridMapFps, updateGridMapFps); + } - // Make publishers - auto pub = this->create_publisher(topic_name, 1); - RCLCPP_INFO(this->get_logger(), "Publishing map to topic %s", topic_name.c_str()); - mapPubs_.push_back(pub); + // Make publishers + auto pub = this->create_publisher(topic_name, 1); + RCLCPP_INFO(this->get_logger(), "Publishing map to topic %s", topic_name.c_str()); + mapPubs_.push_back(pub); - // Register map layers - map_layers_.push_back(layers_list); - map_basic_layers_.push_back(basic_layers_list); + // Register map layers + map_layers_.push_back(layers_list); + map_basic_layers_.push_back(basic_layers_list); - // Register map fps - map_fps_.push_back(fps); - map_fps_unique_.insert(fps); + // Register map fps + map_fps_.push_back(fps); + map_fps_unique_.insert(fps); } @@ -319,31 +297,36 @@ void ElevationMappingNode::publishMapOfIndex(int index) { if (!isGridmapUpdated_) { return; } + + + std::unique_ptr msg_ptr; grid_map_msgs::msg::GridMap msg; + std::vector layers; - // { // need continuous lock between adding layers and converting to message. Otherwise updateGridmap can reset the data not in - // // map_layers_all_ - // std::lock_guard lock(mapMutex_); - // for (const auto& layer : map_layers_[index]) { - // const bool is_layer_in_all = map_layers_all_.find(layer) != map_layers_all_.end(); - // if (is_layer_in_all && gridMap_.exists(layer)) { - // layers.push_back(layer); - // } else if (map_.exists_layer(layer)) { - // // if there are layers which is not in the syncing layer. - // ElevationMappingWrapper::RowMatrixXf map_data; - // map_.get_layer_data(layer, map_data); - // gridMap_.add(layer, map_data); - // layers.push_back(layer); - // } - // } - // if (layers.empty()) { - // return; - // } - - // grid_map::GridMapRosConverter::toMessage(gridMap_, layers, msg); - // } + { // need continuous lock between adding layers and converting to message. Otherwise updateGridmap can reset the data not in + // map_layers_all_ + std::lock_guard lock(mapMutex_); + for (const auto& layer : map_layers_[index]) { + const bool is_layer_in_all = map_layers_all_.find(layer) != map_layers_all_.end(); + if (is_layer_in_all && gridMap_.exists(layer)) { + layers.push_back(layer); + } else if (map_->exists_layer(layer)) { + // if there are layers which is not in the syncing layer. + ElevationMappingWrapper::RowMatrixXf map_data; + map_->get_layer_data(layer, map_data); + gridMap_.add(layer, map_data); + layers.push_back(layer); + } + } + if (layers.empty()) { + return; + } + msg_ptr = grid_map::GridMapRosConverter::toMessage(gridMap_, layers); + msg= *msg_ptr; + } + msg.basic_layers = map_basic_layers_[index]; mapPubs_[index]->publish(msg); } diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 013fb1b9..0e9f29c5 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -21,6 +21,19 @@ namespace elevation_mapping_cupy { +std::vector extract_unique_names(const std::map& subscriber_params) { + std::set unique_names_set; + for (const auto& param : subscriber_params) { + std::size_t pos = param.first.find('.'); + if (pos != std::string::npos) { + std::string name = param.first.substr(0, pos); + unique_names_set.insert(name); + } + } + return std::vector(unique_names_set.begin(), unique_names_set.end()); +} + + ElevationMappingWrapper::ElevationMappingWrapper(){} void ElevationMappingWrapper::initialize(const std::shared_ptr& node){ @@ -41,9 +54,11 @@ void ElevationMappingWrapper::initialize(const std::shared_ptr& no auto elevation_mapping = py::module::import("elevation_mapping_cupy.elevation_mapping"); auto parameter = py::module::import("elevation_mapping_cupy.parameter"); - param_ = parameter.attr("Parameter")(); + param_ = parameter.attr("Parameter")(); setParameters(); map_ = elevation_mapping.attr("ElevationMap")(param_); + RCLCPP_INFO(node_->get_logger(), "ElevationMappingWrapper has been initialized"); + } // /** @@ -52,9 +67,6 @@ void ElevationMappingWrapper::initialize(const std::shared_ptr& no // */ void ElevationMappingWrapper::setParameters() { - // auto parameter = py::module::import("elevation_mapping_cupy.parameter"); - // auto param_ = parameter.attr("Parameter")(); - // Get all parameters names and types. py::list paramNames = param_.attr("get_names")(); py::list paramTypes = param_.attr("get_types")(); @@ -110,108 +122,91 @@ void ElevationMappingWrapper::setParameters() { // rclcpp::Parameter subscribers; std::vector parameter_prefixes; auto parameters = node_->list_parameters(parameter_prefixes, 2); // List all parameters with a maximum depth of 10 - for (const auto& param_name : parameters.names) { - if (param_name.find("subscribers") != std::string::npos) { - RCLCPP_WARN(node_->get_logger(), "Subscriber : %s", param_name.c_str()); - - // const char* const name = param_name.c_str(); - // std::string subscriber_params; - // node_->get_parameter(param_name, subscriber); - // const auto& subscriber_params = subscriber.second; - // if (!sub_dict.contains(name)) { - // sub_dict[name] = py::dict(); - // } - // for (auto iterat : subscriber_params) { - // const char* const key = iterat.first.c_str(); - // const auto val = iterat.second; - // std::vector arr; - // switch (val.getType()) { - // case XmlRpc::XmlRpcValue::TypeString: - // sub_dict[name][key] = static_cast(val); - // break; - // case XmlRpc::XmlRpcValue::TypeInt: - // sub_dict[name][key] = static_cast(val); - // break; - // case XmlRpc::XmlRpcValue::TypeDouble: - // sub_dict[name][key] = static_cast(val); - // break; - // case XmlRpc::XmlRpcValue::TypeBoolean: - // sub_dict[name][key] = static_cast(val); - // break; - // case XmlRpc::XmlRpcValue::TypeArray: - // for (int32_t i = 0; i < val.size(); ++i) { - // auto elem = static_cast(val[i]); - // arr.push_back(elem); - // } - // sub_dict[name][key] = arr; - // arr.clear(); - // break; - // case XmlRpc::XmlRpcValue::TypeStruct: - // break; - // default: - // sub_dict[name][key] = py::cast(val); - // break; - // } - // } + + std::map subscriber_params; + if (!node_->get_parameters("subscribers", subscriber_params)) { + RCLCPP_FATAL(node_->get_logger(), "There aren't any subscribers to be configured, the elevation mapping cannot be configured. Exit"); + rclcpp::shutdown(); + } + auto unique_sub_names = extract_unique_names(subscriber_params); + for (const auto& name : unique_sub_names) { + const char* const name_c = name.c_str(); + if (!sub_dict.contains(name_c)) { + sub_dict[name_c] = py::dict(); + } + std::string topic_name; + if(node_->get_parameter("subscribers." + name + ".topic_name", topic_name)){ + const char* topic_name_cstr = "topic_name"; + sub_dict[name_c][topic_name_cstr] = static_cast(topic_name); + std::string data_type; + if(node_->get_parameter("subscribers." + name + ".data_type", data_type)){ + const char* data_type_cstr = "data_type"; + sub_dict[name_c][data_type_cstr] = static_cast(data_type); + } + std::string info_name; + if(node_->get_parameter("subscribers." + name + ".data_type", info_name)){ + const char* info_name_cstr = "info_name"; + sub_dict[name_c][info_name_cstr] = static_cast(info_name); + } + std::string channel_name; + if(node_->get_parameter("subscribers." + name + ".data_type", channel_name)){ + const char* channel_name_cstr = "channel_name"; + sub_dict[name_c][channel_name_cstr] = static_cast(channel_name); } } + } + + + param_.attr("subscriber_cfg") = sub_dict; + // point cloud channel fusion + std::map pointcloud_channel_fusions_params; + if (node_->get_parameters("pointcloud_channel_fusions", pointcloud_channel_fusions_params)) { + py::dict pointcloud_channel_fusion_dict; + for (const auto& param : pointcloud_channel_fusions_params) { + std::string param_name = param.first; + std::string param_value = param.second.as_string(); + // Extract the string after "pointcloud_channel_fusions." + pointcloud_channel_fusion_dict[param_name.c_str()] = param_value; + } + // Print the dictionary for debugging + for (auto item : pointcloud_channel_fusion_dict) { + RCLCPP_INFO(node_->get_logger(), "pointcloud_channel_fusions Key: %s, Value: %s", std::string(py::str(item.first)).c_str(), std::string(py::str(item.second)).c_str()); + } + } else { + RCLCPP_WARN(node_->get_logger(), "No parameters found for 'pointcloud_channel_fusions'"); + } - // // point cloud channel fusion - // if (!node_->has_parameter("pointcloud_channel_fusions")) { - // RCLCPP_WARN(node_->get_logger(), "No pointcloud_channel_fusions parameter found. Using default values."); - // } else { - // rclcpp::Parameter pointcloud_channel_fusion; - // node_->get_parameter("pointcloud_channel_fusions", pointcloud_channel_fusion); - - // py::dict pointcloud_channel_fusion_dict; - // auto pointcloud_channel_fusion_map = pointcloud_channel_fusion.as_string_array(); - // for (const auto& channel_fusion : pointcloud_channel_fusion_map) { - // const char* const fusion_name = channel_fusion.c_str(); - // std::string fusion; - // node_->get_parameter(fusion_name, fusion); - // if (!pointcloud_channel_fusion_dict.contains(fusion_name)) { - // pointcloud_channel_fusion_dict[fusion_name] = fusion; - // } - // } - // RCLCPP_INFO_STREAM(node_->get_logger(), "pointcloud_channel_fusion_dict: " << pointcloud_channel_fusion_dict); - // param_.attr("pointcloud_channel_fusions") = pointcloud_channel_fusion_dict; - // } + // image channel fusion + std::map image_channel_fusions_params; + if (node_->get_parameters("image_channel_fusions", image_channel_fusions_params)) { + py::dict image_channel_fusion_dict; + for (const auto& param : image_channel_fusions_params) { + std::string param_name = param.first; + std::string param_value = param.second.as_string(); + // Extract the string after "pointcloud_channel_fusions." + image_channel_fusion_dict[param_name.c_str()] = param_value; + } + // Print the dictionary for debugging + for (auto item : image_channel_fusion_dict) { + RCLCPP_INFO(node_->get_logger(), "image_channel_fusions Key: %s, Value: %s", std::string(py::str(item.first)).c_str(), std::string(py::str(item.second)).c_str()); + } + } else { + RCLCPP_WARN(node_->get_logger(), "No parameters found for 'image_channel_fusions'"); + } - - // // image channel fusion - // if (!node_->has_parameter("image_channel_fusions")) { - // RCLCPP_WARN(node_->get_logger(), "No image_channel_fusions parameter found. Using default values."); - // } else { - // rclcpp::Parameter image_channel_fusion; - // node_->get_parameter("image_channel_fusions", image_channel_fusion); - - // py::dict image_channel_fusion_dict; - // auto image_channel_fusion_map = image_channel_fusion.as_string_array(); - // for (const auto& channel_fusion : image_channel_fusion_map) { - // const char* const channel_fusion_name = channel_fusion.c_str(); - // std::string fusion; - // node_->get_parameter(channel_fusion_name, fusion); - // if (!image_channel_fusion_dict.contains(channel_fusion_name)) { - // image_channel_fusion_dict[channel_fusion_name] = fusion; - // } - // } - // RCLCPP_INFO_STREAM(node_->get_logger(), "image_channel_fusion_dict: " << image_channel_fusion_dict); - // param_.attr("image_channel_fusions") = image_channel_fusion_dict; - // } - - // param_.attr("update")(); - // resolution_ = py::cast(param_.attr("get_value")("resolution")); - // map_length_ = py::cast(param_.attr("get_value")("true_map_length")); - // map_n_ = py::cast(param_.attr("get_value")("true_cell_n")); - - // node_->declare_parameter("enable_normal", false); - // node_->declare_parameter("enable_normal_color", false); - // enable_normal_ = node_->get_parameter("enable_normal").as_bool(); - // enable_normal_color_ = node_->get_parameter("enable_normal_color").as_bool(); + + param_.attr("update")(); + resolution_ = py::cast(param_.attr("get_value")("resolution")); + map_length_ = py::cast(param_.attr("get_value")("true_map_length")); + map_n_ = py::cast(param_.attr("get_value")("true_cell_n")); + + + enable_normal_ = node_->get_parameter("enable_normal").as_bool(); + enable_normal_color_ = node_->get_parameter("enable_normal_color").as_bool(); } From 50d1623164d5e6e02f8e21a4038289397bd93a47 Mon Sep 17 00:00:00 2001 From: amilearning Date: Thu, 7 Nov 2024 14:49:09 +0100 Subject: [PATCH 450/504] upto initializationMap --- elevation_map_msgs/CMakeLists.txt | 2 +- elevation_mapping_cupy/CMakeLists.txt | 2 +- .../elevation_mapping_ros.hpp | 31 +- .../src/elevation_mapping_ros.cpp | 366 ++++++++++-------- 4 files changed, 227 insertions(+), 174 deletions(-) diff --git a/elevation_map_msgs/CMakeLists.txt b/elevation_map_msgs/CMakeLists.txt index 0ea3f7cb..08e4467b 100644 --- a/elevation_map_msgs/CMakeLists.txt +++ b/elevation_map_msgs/CMakeLists.txt @@ -19,7 +19,7 @@ set(srv_files rosidl_generate_interfaces(${PROJECT_NAME} ${msg_files} ${srv_files} - DEPENDENCIES geometry_msgs std_msgs # Added std_msgs + DEPENDENCIES geometry_msgs std_msgs std_msgs # Added std_msgs ) ament_export_dependencies(rosidl_default_runtime) diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index 91e4db8d..9925bc5d 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -65,7 +65,7 @@ set(dependencies # Include directories include_directories( - include + include ${PYTHON_INCLUDE_DIRS} ${Eigen3_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index b4abac57..f887afe4 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -26,8 +26,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -56,6 +56,7 @@ #include #include #include +#include #include "elevation_mapping_cupy/elevation_mapping_wrapper.hpp" @@ -108,19 +109,29 @@ void imageChannelCallback(const std::shared_ptr& // void pointCloudChannelCallback(const sensor_msgs::PointCloud2& cloud, const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg); // // void multiLayerImageCallback(const elevation_map_msgs::MultiLayerImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg); // void publishAsPointCloud(const grid_map::GridMap& map) const; -// bool getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response); +bool getSubmap( const std::shared_ptr request, std::shared_ptr response); + + // bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response); -// bool initializeMap(elevation_map_msgs::Initialize::Request& request, elevation_map_msgs::Initialize::Response& response); -// bool clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); -// bool clearMapWithInitializer(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + + void initializeMap(const std::shared_ptr request, std::shared_ptr response); + + + // bool clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + + +void clearMap(const std::shared_ptr request, std::shared_ptr response); +void clearMapWithInitializer(const std::shared_ptr request, std::shared_ptr response); + + // bool setPublishPoint(std_srvs::SetBool::Request& request, std_srvs::SetBool::Response& response); // void updatePose(const ros::TimerEvent&); // void updateVariance(const ros::TimerEvent&); // void updateTime(const ros::TimerEvent&); // void updateGridMap(const ros::TimerEvent&); // void publishNormalAsArrow(const grid_map::GridMap& map) const; -// void initializeWithTF(); -// void publishMapToOdom(double error); + void initializeWithTF(); + void publishMapToOdom(double error); // void publishStatistics(const ros::TimerEvent&); void publishMapOfIndex(int index); @@ -143,10 +154,10 @@ void imageChannelCallback(const std::shared_ptr& std::shared_ptr tfBuffer_; - rclcpp::Publisher::SharedPtr alivePub_; + rclcpp::Publisher::SharedPtr alivePub_; rclcpp::Publisher::SharedPtr pointPub_; - rclcpp::Publisher::SharedPtr normalPub_; - rclcpp::Publisher::SharedPtr statisticsPub_; + rclcpp::Publisher::SharedPtr normalPub_; + rclcpp::Publisher::SharedPtr statisticsPub_; rclcpp::Service::SharedPtr rawSubmapService_; rclcpp::Service::SharedPtr clearMapService_; rclcpp::Service::SharedPtr clearMapWithInitializerService_; diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 7ebb5dd2..0f29da25 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -214,19 +214,32 @@ ElevationMappingNode::ElevationMappingNode() setupMapPublishers(); -// pointPub_ = nh_.advertise("elevation_map_points", 1); -// alivePub_ = nh_.advertise("alive", 1); -// normalPub_ = nh_.advertise("normal", 1); -// statisticsPub_ = nh_.advertise("statistics", 1); - -// gridMap_.setFrameId(mapFrameId_); -// rawSubmapService_ = nh_.advertiseService("get_raw_submap", &ElevationMappingNode::getSubmap, this); -// clearMapService_ = nh_.advertiseService("clear_map", &ElevationMappingNode::clearMap, this); -// initializeMapService_ = nh_.advertiseService("initialize", &ElevationMappingNode::initializeMap, this); -// clearMapWithInitializerService_ = -// nh_.advertiseService("clear_map_with_initializer", &ElevationMappingNode::clearMapWithInitializer, this); -// setPublishPointService_ = nh_.advertiseService("set_publish_points", &ElevationMappingNode::setPublishPoint, this); -// checkSafetyService_ = nh_.advertiseService("check_safety", &ElevationMappingNode::checkSafety, this); + pointPub_ = this->create_publisher("elevation_map_points", 1); + alivePub_ = this->create_publisher("alive", 1); + normalPub_ = this->create_publisher("normal", 1); + statisticsPub_ = this->create_publisher("statistics", 1); + + gridMap_.setFrameId(mapFrameId_); + +rawSubmapService_ = this->create_service( + "get_raw_submap", std::bind(&ElevationMappingNode::getSubmap, this, std::placeholders::_1, std::placeholders::_2)); + +clearMapService_ = this->create_service( + "clear_map", std::bind(&ElevationMappingNode::clearMap, this, std::placeholders::_1, std::placeholders::_2)); + +clearMapWithInitializerService_ = this->create_service( + "clear_map_with_initializer", std::bind(&ElevationMappingNode::clearMapWithInitializer, this, std::placeholders::_1, std::placeholders::_2)); + + +initializeMapService_ = this->create_service( + "initialize", std::bind(&ElevationMappingNode::initializeMap, this, std::placeholders::_1, std::placeholders::_2)); + + +// setPublishPointService_ = this->create_service( +// "set_publish_points", std::bind(&ElevationMappingNode::setPublishPoint, this, std::placeholders::_1, std::placeholders::_2)); +// checkSafetyService_ = this->create_service( +// "check_safety", std::bind(&ElevationMappingNode::checkSafety, this, std::placeholders::_1, std::placeholders::_2)); + // if (updateVarianceFps > 0) { // double duration = 1.0 / (updateVarianceFps + 0.00001); @@ -390,12 +403,12 @@ void ElevationMappingNode::inputPointCloud(const sensor_msgs::msg::PointCloud2:: orientationError = orientationError_; } - // map_.input(points, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError, - // orientationError); + map_->input(points, channels, transformationSensorToMap.rotation(), transformationSensorToMap.translation(), positionError, + orientationError); - // if (enableDriftCorrectedTFPublishing_) { - // publishMapToOdom(map_.get_additive_mean_error()); - // } + if (enableDriftCorrectedTFPublishing_) { + publishMapToOdom(map_->get_additive_mean_error()); + } RCLCPP_DEBUG(this->get_logger(), "ElevationMap processed a point cloud (%i points) in %f sec.", static_cast(points.size()), (this->now() - start).seconds()); @@ -540,101 +553,118 @@ RCLCPP_DEBUG(this->get_logger(), "ElevationMap imageChannelCallback processed an // pointPub_.publish(msg); // } -// bool ElevationMappingNode::getSubmap(grid_map_msgs::GetGridMap::Request& request, grid_map_msgs::GetGridMap::Response& response) { -// std::string requestedFrameId = request.frame_id; -// Eigen::Isometry3d transformationOdomToMap; -// grid_map::Position requestedSubmapPosition(request.position_x, request.position_y); -// if (requestedFrameId != mapFrameId_) { -// tf::StampedTransform transformTf; -// const auto& timeStamp = ros::Time::now(); -// try { -// transformListener_.waitForTransform(requestedFrameId, mapFrameId_, timeStamp, ros::Duration(1.0)); -// transformListener_.lookupTransform(requestedFrameId, mapFrameId_, timeStamp, transformTf); -// tf::poseTFToEigen(transformTf, transformationOdomToMap); -// } catch (tf::TransformException& ex) { -// ROS_ERROR("%s", ex.what()); -// return false; -// } -// Eigen::Vector3d p(request.position_x, request.position_y, 0); -// Eigen::Vector3d mapP = transformationOdomToMap.inverse() * p; -// requestedSubmapPosition.x() = mapP.x(); -// requestedSubmapPosition.y() = mapP.y(); -// } -// grid_map::Length requestedSubmapLength(request.length_x, request.length_y); -// ROS_DEBUG("Elevation submap request: Position x=%f, y=%f, Length x=%f, y=%f.", requestedSubmapPosition.x(), requestedSubmapPosition.y(), -// requestedSubmapLength(0), requestedSubmapLength(1)); -// bool isSuccess; -// grid_map::Index index; -// grid_map::GridMap subMap; -// { -// std::lock_guard lock(mapMutex_); -// subMap = gridMap_.getSubmap(requestedSubmapPosition, requestedSubmapLength, index, isSuccess); -// } -// const auto& length = subMap.getLength(); -// if (requestedFrameId != mapFrameId_) { -// subMap = subMap.getTransformedMap(transformationOdomToMap, "elevation", requestedFrameId); -// } +bool ElevationMappingNode::getSubmap( + const std::shared_ptr request, + std::shared_ptr response) { + std::string requestedFrameId = request->frame_id; + Eigen::Isometry3d transformationOdomToMap; + geometry_msgs::msg::Pose pose; + grid_map::Position requestedSubmapPosition(request->position_x, request->position_y); + if (requestedFrameId != mapFrameId_) { + geometry_msgs::msg::TransformStamped transformStamped; + const auto& timeStamp = this->now(); + try { + transformStamped = tfBuffer_->lookupTransform(requestedFrameId, mapFrameId_, timeStamp, tf2::durationFromSec(1.0)); + + + pose.position.x = transformStamped.transform.translation.x; + pose.position.y = transformStamped.transform.translation.y; + pose.position.z = transformStamped.transform.translation.z; + pose.orientation = transformStamped.transform.rotation; -// if (request.layers.empty()) { -// grid_map::GridMapRosConverter::toMessage(subMap, response.map); -// } else { -// std::vector layers; -// for (const auto& layer : request.layers) { -// layers.push_back(layer); -// } -// grid_map::GridMapRosConverter::toMessage(subMap, layers, response.map); -// } -// return isSuccess; -// } + tf2::fromMsg(pose, transformationOdomToMap); + } catch (tf2::TransformException& ex) { + RCLCPP_ERROR(this->get_logger(), "%s", ex.what()); + return false; + } + Eigen::Vector3d p(request->position_x, request->position_y, 0); + Eigen::Vector3d mapP = transformationOdomToMap.inverse() * p; + requestedSubmapPosition.x() = mapP.x(); + requestedSubmapPosition.y() = mapP.y(); + } + grid_map::Length requestedSubmapLength(request->length_x, request->length_y); + RCLCPP_DEBUG(this->get_logger(), "Elevation submap request: Position x=%f, y=%f, Length x=%f, y=%f.", + requestedSubmapPosition.x(), requestedSubmapPosition.y(), + requestedSubmapLength(0), requestedSubmapLength(1)); + + bool isSuccess; + grid_map::Index index; + grid_map::GridMap subMap; + { + std::lock_guard lock(mapMutex_); + subMap = gridMap_.getSubmap(requestedSubmapPosition, requestedSubmapLength, isSuccess); + } + const auto& length = subMap.getLength(); + if (requestedFrameId != mapFrameId_) { + subMap = subMap.getTransformedMap(transformationOdomToMap, "elevation", requestedFrameId); + } -// bool ElevationMappingNode::clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) { -// ROS_INFO("Clearing map."); -// map_.clear(); -// if (alwaysClearWithInitializer_) { -// initializeWithTF(); -// } -// return true; -// } + if (request->layers.empty()) { + auto msg_ptr = grid_map::GridMapRosConverter::toMessage(subMap); + response->map = *msg_ptr; + } else { + std::vector layers; + for (const auto& layer : request->layers) { + layers.push_back(layer); + } + auto msg_ptr = grid_map::GridMapRosConverter::toMessage(subMap, layers); + response->map = *msg_ptr; -// bool ElevationMappingNode::clearMapWithInitializer(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) { -// ROS_INFO("Clearing map with initializer."); -// map_.clear(); -// initializeWithTF(); -// return true; -// } + } + return isSuccess; +} -// void ElevationMappingNode::initializeWithTF() { -// std::vector points; -// const auto& timeStamp = ros::Time::now(); -// int i = 0; -// Eigen::Vector3d p; -// for (const auto& frame_id : initialize_frame_id_) { -// // Get tf from map frame to tf frame -// Eigen::Affine3d transformationBaseToMap; -// tf::StampedTransform transformTf; -// try { -// transformListener_.waitForTransform(mapFrameId_, frame_id, timeStamp, ros::Duration(1.0)); -// transformListener_.lookupTransform(mapFrameId_, frame_id, timeStamp, transformTf); -// poseTFToEigen(transformTf, transformationBaseToMap); -// } catch (tf::TransformException& ex) { -// ROS_ERROR("%s", ex.what()); -// return; -// } -// p = transformationBaseToMap.translation(); -// p.z() += initialize_tf_offset_[i]; -// points.push_back(p); -// i++; -// } -// if (!points.empty() && points.size() < 3) { -// points.emplace_back(p + Eigen::Vector3d(initializeTfGridSize_, initializeTfGridSize_, 0)); -// points.emplace_back(p + Eigen::Vector3d(-initializeTfGridSize_, initializeTfGridSize_, 0)); -// points.emplace_back(p + Eigen::Vector3d(initializeTfGridSize_, -initializeTfGridSize_, 0)); -// points.emplace_back(p + Eigen::Vector3d(-initializeTfGridSize_, -initializeTfGridSize_, 0)); -// } -// ROS_INFO_STREAM("Initializing map with points using " << initializeMethod_); -// map_.initializeWithPoints(points, initializeMethod_); -// } + + +void ElevationMappingNode::clearMap(const std::shared_ptr request, + std::shared_ptr response) { + + std::lock_guard lock(mapMutex_); + RCLCPP_INFO(this->get_logger(), "Clearing map."); + map_->clear(); + if (alwaysClearWithInitializer_) { + initializeWithTF(); + } +} + +void ElevationMappingNode::clearMapWithInitializer(const std::shared_ptr request, std::shared_ptr response){ + RCLCPP_INFO(this->get_logger(), "Clearing map with initializer"); + map_->clear(); + initializeWithTF(); + +} + +void ElevationMappingNode::initializeWithTF() { + std::vector points; + const auto& timeStamp = this->now(); + int i = 0; + Eigen::Vector3d p; + for (const auto& frame_id : initialize_frame_id_) { + // Get tf from map frame to tf frame + Eigen::Affine3d transformationBaseToMap; + geometry_msgs::msg::TransformStamped transformStamped; + try { + transformStamped = tfBuffer_->lookupTransform(mapFrameId_, frame_id, timeStamp, tf2::durationFromSec(1.0)); + transformationBaseToMap = tf2::transformToEigen(transformStamped); + } catch (tf2::TransformException& ex) { + RCLCPP_ERROR(this->get_logger(), "%s", ex.what()); + return; + } + p = transformationBaseToMap.translation(); + p.z() += initialize_tf_offset_[i]; + points.push_back(p); + i++; + } + if (!points.empty() && points.size() < 3) { + points.emplace_back(p + Eigen::Vector3d(initializeTfGridSize_, initializeTfGridSize_, 0)); + points.emplace_back(p + Eigen::Vector3d(-initializeTfGridSize_, initializeTfGridSize_, 0)); + points.emplace_back(p + Eigen::Vector3d(initializeTfGridSize_, -initializeTfGridSize_, 0)); + points.emplace_back(p + Eigen::Vector3d(-initializeTfGridSize_, -initializeTfGridSize_, 0)); + } + RCLCPP_INFO(this->get_logger(), "Initializing map with points using %s", initializeMethod_.c_str()); + map_->initializeWithPoints(points, initializeMethod_); +} // bool ElevationMappingNode::checkSafety(elevation_map_msgs::CheckSafety::Request& request, // elevation_map_msgs::CheckSafety::Response& response) { @@ -737,52 +767,51 @@ RCLCPP_DEBUG(this->get_logger(), "ElevationMap imageChannelCallback processed an // isGridmapUpdated_ = true; // } -// bool ElevationMappingNode::initializeMap(elevation_map_msgs::Initialize::Request& request, -// elevation_map_msgs::Initialize::Response& response) { -// // If initialize method is points -// if (request.type == request.POINTS) { -// std::vector points; -// for (const auto& point : request.points) { -// const auto& pointFrameId = point.header.frame_id; -// const auto& timeStamp = point.header.stamp; -// const auto& pvector = Eigen::Vector3d(point.point.x, point.point.y, point.point.z); - -// // Get tf from map frame to points' frame -// if (mapFrameId_ != pointFrameId) { -// Eigen::Affine3d transformationBaseToMap; -// tf::StampedTransform transformTf; -// try { -// transformListener_.waitForTransform(mapFrameId_, pointFrameId, timeStamp, ros::Duration(1.0)); -// transformListener_.lookupTransform(mapFrameId_, pointFrameId, timeStamp, transformTf); -// poseTFToEigen(transformTf, transformationBaseToMap); -// } catch (tf::TransformException& ex) { -// ROS_ERROR("%s", ex.what()); -// return false; -// } -// const auto transformed_p = transformationBaseToMap * pvector; -// points.push_back(transformed_p); -// } else { -// points.push_back(pvector); -// } -// } -// std::string method; -// switch (request.method) { -// case request.NEAREST: -// method = "nearest"; -// break; -// case request.LINEAR: -// method = "linear"; -// break; -// case request.CUBIC: -// method = "cubic"; -// break; -// } -// ROS_INFO_STREAM("Initializing map with points using " << method); -// map_.initializeWithPoints(points, method); -// } -// response.success = true; -// return true; -// } +void ElevationMappingNode::initializeMap(const std::shared_ptr request, + std::shared_ptr response) { + // If initialize method is points + if (request->type == elevation_map_msgs::srv::Initialize::Request::POINTS) { + std::vector points; + for (const auto& point : request->points) { + const auto& pointFrameId = point.header.frame_id; + const auto& timeStamp = point.header.stamp; + const auto& pvector = Eigen::Vector3d(point.point.x, point.point.y, point.point.z); + + // Get tf from map frame to points' frame + if (mapFrameId_ != pointFrameId) { + Eigen::Affine3d transformationBaseToMap; + geometry_msgs::msg::TransformStamped transformStamped; + try { + transformStamped = tfBuffer_->lookupTransform(mapFrameId_, pointFrameId, timeStamp, tf2::durationFromSec(1.0)); + transformationBaseToMap = tf2::transformToEigen(transformStamped); + } catch (tf2::TransformException& ex) { + RCLCPP_ERROR(this->get_logger(), "%s", ex.what()); + response->success = false; + return; + } + const auto transformed_p = transformationBaseToMap * pvector; + points.push_back(transformed_p); + } else { + points.push_back(pvector); + } + } + std::string method; + switch (request->method) { + case elevation_map_msgs::srv::Initialize::Request::NEAREST: + method = "nearest"; + break; + case elevation_map_msgs::srv::Initialize::Request::LINEAR: + method = "linear"; + break; + case elevation_map_msgs::srv::Initialize::Request::CUBIC: + method = "cubic"; + break; + } + RCLCPP_INFO(this->get_logger(), "Initializing map with points using %s", method.c_str()); + map_->initializeWithPoints(points, method); + } + response->success = true; +} // void ElevationMappingNode::publishNormalAsArrow(const grid_map::GridMap& map) const { // auto startTime = ros::Time::now(); @@ -844,13 +873,26 @@ RCLCPP_DEBUG(this->get_logger(), "ElevationMap imageChannelCallback processed an // return marker; // } -// void ElevationMappingNode::publishMapToOdom(double error) { -// tf::Transform transform; -// transform.setOrigin(tf::Vector3(0.0, 0.0, error)); -// tf::Quaternion q; -// q.setRPY(0, 0, 0); -// transform.setRotation(q); -// tfBroadcaster_.sendTransform(tf::StampedTransform(transform, ros::Time::now(), mapFrameId_, correctedMapFrameId_)); -// } + +void ElevationMappingNode::publishMapToOdom(double error) { + geometry_msgs::msg::TransformStamped transform_stamped; + transform_stamped.header.stamp = this->now(); + transform_stamped.header.frame_id = mapFrameId_; + transform_stamped.child_frame_id = correctedMapFrameId_; + transform_stamped.transform.translation.x = 0.0; + transform_stamped.transform.translation.y = 0.0; + transform_stamped.transform.translation.z = error; + + tf2::Quaternion q; + q.setRPY(0, 0, 0); + transform_stamped.transform.rotation.x = q.x(); + transform_stamped.transform.rotation.y = q.y(); + transform_stamped.transform.rotation.z = q.z(); + transform_stamped.transform.rotation.w = q.w(); + + tfBroadcaster_->sendTransform(transform_stamped); +} + + } // namespace elevation_mapping_cupy From f71c3c36f60430f8c6013f712a45ce3fc8583f1b Mon Sep 17 00:00:00 2001 From: amilearning Date: Fri, 8 Nov 2024 04:43:12 +0100 Subject: [PATCH 451/504] pointcloud done --- .../config/core/core_param.yaml | 8 +- .../elevation_mapping_ros.hpp | 35 +- .../src/elevation_mapping_ros.cpp | 325 +++++++++--------- 3 files changed, 192 insertions(+), 176 deletions(-) diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 19f8aa28..c128291f 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -1,7 +1,7 @@ elevation_mapping: ros__parameters: #### Basic parameters ######## - cell_n: 10000 # number of cells in the map. + cell_n: 40000 # number of cells in the map. data_type: 'float32' # data type for the map. average_weight: 0.5 drift_compensation_variance_inlier: 0.1 @@ -9,8 +9,8 @@ elevation_mapping: min_filter_size: 5 # size of the filter for min filter. min_filter_iteration: 3 # number of iterations for min filter. initialized_variance: 10.0 # initial variance for each cell. - resolution: 0.04 # resolution in m. - map_length: 8.0 # map's size in m. + resolution: 0.1 # resolution in m. + map_length: 20.0 # map's size in m. sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). mahalanobis_thresh: 2.0 # points outside this distance is outlier. outlier_variance: 0.01 # if point is outlier, add this value to the cell. @@ -105,7 +105,7 @@ elevation_mapping: subscribers: pointcloud1: - topic_name: '/a200/sensors/camera_1/points' + topic_name: '/a200/sensors/camera_0/points' data_type: 'pointcloud' image1: topic_name: '/a200/sensors/camera_0/color/image' diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index f887afe4..7cf91ce1 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -108,34 +108,33 @@ void imageChannelCallback(const std::shared_ptr& // void pointCloudChannelCallback(const sensor_msgs::PointCloud2& cloud, const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg); // // void multiLayerImageCallback(const elevation_map_msgs::MultiLayerImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg); -// void publishAsPointCloud(const grid_map::GridMap& map) const; +void publishAsPointCloud(const grid_map::GridMap& map) const; bool getSubmap( const std::shared_ptr request, std::shared_ptr response); // bool checkSafety(elevation_map_msgs::CheckSafety::Request& request, elevation_map_msgs::CheckSafety::Response& response); - void initializeMap(const std::shared_ptr request, std::shared_ptr response); - - - // bool clearMap(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); - - +void initializeMap(const std::shared_ptr request, std::shared_ptr response); void clearMap(const std::shared_ptr request, std::shared_ptr response); void clearMapWithInitializer(const std::shared_ptr request, std::shared_ptr response); -// bool setPublishPoint(std_srvs::SetBool::Request& request, std_srvs::SetBool::Response& response); -// void updatePose(const ros::TimerEvent&); -// void updateVariance(const ros::TimerEvent&); -// void updateTime(const ros::TimerEvent&); -// void updateGridMap(const ros::TimerEvent&); -// void publishNormalAsArrow(const grid_map::GridMap& map) const; - void initializeWithTF(); - void publishMapToOdom(double error); -// void publishStatistics(const ros::TimerEvent&); - void publishMapOfIndex(int index); -// visualization_msgs::Marker vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id) const; +void setPublishPoint(const std::shared_ptr request, + std::shared_ptr response); + + +void updateVariance(); +void updateTime(); +void updatePose(); +void updateGridMap(); +void publishStatistics(); + +void publishNormalAsArrow(const grid_map::GridMap& map) const; +void initializeWithTF(); +void publishMapToOdom(double error); +void publishMapOfIndex(int index); +visualization_msgs::msg::Marker vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, const int id) const; rclcpp::Node::SharedPtr node_; // image_transport::ImageTransport it_; diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 0f29da25..57f8bd83 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -234,35 +234,40 @@ clearMapWithInitializerService_ = this->create_service( initializeMapService_ = this->create_service( "initialize", std::bind(&ElevationMappingNode::initializeMap, this, std::placeholders::_1, std::placeholders::_2)); +setPublishPointService_ = this->create_service( + "set_publish_points", std::bind(&ElevationMappingNode::setPublishPoint, this, std::placeholders::_1, std::placeholders::_2)); -// setPublishPointService_ = this->create_service( -// "set_publish_points", std::bind(&ElevationMappingNode::setPublishPoint, this, std::placeholders::_1, std::placeholders::_2)); // checkSafetyService_ = this->create_service( // "check_safety", std::bind(&ElevationMappingNode::checkSafety, this, std::placeholders::_1, std::placeholders::_2)); -// if (updateVarianceFps > 0) { -// double duration = 1.0 / (updateVarianceFps + 0.00001); -// updateVarianceTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updateVariance, this, false, true); -// } -// if (timeInterval > 0) { -// double duration = timeInterval; -// updateTimeTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updateTime, this, false, true); -// } -// if (updatePoseFps > 0) { -// double duration = 1.0 / (updatePoseFps + 0.00001); -// updatePoseTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updatePose, this, false, true); -// } -// if (updateGridMapFps > 0) { -// double duration = 1.0 / (updateGridMapFps + 0.00001); -// updateGridMapTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::updateGridMap, this, false, true); -// } -// if (publishStatisticsFps > 0) { -// double duration = 1.0 / (publishStatisticsFps + 0.00001); -// publishStatisticsTimer_ = nh_.createTimer(ros::Duration(duration), &ElevationMappingNode::publishStatistics, this, false, true); -// } -// lastStatisticsPublishedTime_ = ros::Time::now(); -// ROS_INFO("[ElevationMappingCupy] finish initialization"); + if (updateVarianceFps > 0) { + double duration = 1.0 / (updateVarianceFps + 0.00001); + updateVarianceTimer_ = this->create_wall_timer(std::chrono::duration(duration), + std::bind(&ElevationMappingNode::updateVariance, this)); + } + if (timeInterval > 0) { + double duration = timeInterval; + updateTimeTimer_ = this->create_wall_timer(std::chrono::duration(duration), + std::bind(&ElevationMappingNode::updateTime, this)); + } + if (updatePoseFps > 0) { + double duration = 1.0 / (updatePoseFps + 0.00001); + updatePoseTimer_ = this->create_wall_timer(std::chrono::duration(duration), + std::bind(&ElevationMappingNode::updatePose, this)); + } + if (updateGridMapFps > 0) { + double duration = 1.0 / (updateGridMapFps + 0.00001); + updateGridMapTimer_ = this->create_wall_timer(std::chrono::duration(duration), + std::bind(&ElevationMappingNode::updateGridMap, this)); + } + if (publishStatisticsFps > 0) { + double duration = 1.0 / (publishStatisticsFps + 0.00001); + publishStatisticsTimer_ = this->create_wall_timer(std::chrono::duration(duration), + std::bind(&ElevationMappingNode::publishStatistics, this)); + } + lastStatisticsPublishedTime_ = this->now(); + RCLCPP_INFO(this->get_logger(), "[ElevationMappingCupy] finish initialization"); } // namespace elevation_mapping_cupy @@ -513,45 +518,51 @@ auto start = this->now(); RCLCPP_DEBUG(this->get_logger(), "ElevationMap imageChannelCallback processed an image in %f sec.", (this->now() - start).seconds()); } -// void ElevationMappingNode::updatePose(const ros::TimerEvent&) { -// tf::StampedTransform transformTf; -// const auto& timeStamp = ros::Time::now(); -// Eigen::Affine3d transformationBaseToMap; -// try { -// transformListener_.waitForTransform(mapFrameId_, baseFrameId_, timeStamp, ros::Duration(1.0)); -// transformListener_.lookupTransform(mapFrameId_, baseFrameId_, timeStamp, transformTf); -// poseTFToEigen(transformTf, transformationBaseToMap); -// } catch (tf::TransformException& ex) { -// ROS_ERROR("%s", ex.what()); -// return; -// } -// // This is to check if the robot is moving. If the robot is not moving, drift compensation is disabled to avoid creating artifacts. -// Eigen::Vector3d position(transformTf.getOrigin().x(), transformTf.getOrigin().y(), transformTf.getOrigin().z()); -// map_.move_to(position, transformationBaseToMap.rotation().transpose()); -// Eigen::Vector3d position3(transformTf.getOrigin().x(), transformTf.getOrigin().y(), transformTf.getOrigin().z()); -// Eigen::Vector4d orientation(transformTf.getRotation().x(), transformTf.getRotation().y(), transformTf.getRotation().z(), -// transformTf.getRotation().w()); -// lowpassPosition_ = positionAlpha_ * position3 + (1 - positionAlpha_) * lowpassPosition_; -// lowpassOrientation_ = orientationAlpha_ * orientation + (1 - orientationAlpha_) * lowpassOrientation_; -// { -// std::lock_guard lock(errorMutex_); -// positionError_ = (position3 - lowpassPosition_).norm(); -// orientationError_ = (orientation - lowpassOrientation_).norm(); -// } +void ElevationMappingNode::updatePose() { + geometry_msgs::msg::TransformStamped transformStamped; + const auto& timeStamp = this->now(); + Eigen::Affine3d transformationBaseToMap; + try { + transformStamped = tfBuffer_->lookupTransform(mapFrameId_, baseFrameId_, timeStamp, tf2::durationFromSec(1.0)); + transformationBaseToMap = tf2::transformToEigen(transformStamped); + } catch (tf2::TransformException& ex) { + RCLCPP_ERROR(this->get_logger(), "%s", ex.what()); + return; + } -// if (useInitializerAtStart_) { -// ROS_INFO("Clearing map with initializer."); -// initializeWithTF(); -// useInitializerAtStart_ = false; -// } -// } + // This is to check if the robot is moving. If the robot is not moving, drift compensation is disabled to avoid creating artifacts. + Eigen::Vector3d position(transformStamped.transform.translation.x, + transformStamped.transform.translation.y, + transformStamped.transform.translation.z); + map_->move_to(position, transformationBaseToMap.rotation().transpose()); + Eigen::Vector3d position3(transformStamped.transform.translation.x, + transformStamped.transform.translation.y, + transformStamped.transform.translation.z); + Eigen::Vector4d orientation(transformStamped.transform.rotation.x, + transformStamped.transform.rotation.y, + transformStamped.transform.rotation.z, + transformStamped.transform.rotation.w); + lowpassPosition_ = positionAlpha_ * position3 + (1 - positionAlpha_) * lowpassPosition_; + lowpassOrientation_ = orientationAlpha_ * orientation + (1 - orientationAlpha_) * lowpassOrientation_; + { + std::lock_guard lock(errorMutex_); + positionError_ = (position3 - lowpassPosition_).norm(); + orientationError_ = (orientation - lowpassOrientation_).norm(); + } -// void ElevationMappingNode::publishAsPointCloud(const grid_map::GridMap& map) const { -// sensor_msgs::PointCloud2 msg; -// grid_map::GridMapRosConverter::toPointCloud(map, "elevation", msg); -// pointPub_.publish(msg); -// } + if (useInitializerAtStart_) { + RCLCPP_INFO(this->get_logger(), "Clearing map with initializer."); + initializeWithTF(); + useInitializerAtStart_ = false; + } +} + +void ElevationMappingNode::publishAsPointCloud(const grid_map::GridMap& map) const { + sensor_msgs::msg::PointCloud2 msg; + grid_map::GridMapRosConverter::toPointCloud(map, "elevation", msg); + pointPub_->publish(msg); +} bool ElevationMappingNode::getSubmap( @@ -723,49 +734,52 @@ void ElevationMappingNode::initializeWithTF() { // return true; // } -// bool ElevationMappingNode::setPublishPoint(std_srvs::SetBool::Request& request, std_srvs::SetBool::Response& response) { -// enablePointCloudPublishing_ = request.data; -// response.success = true; -// return true; -// } -// void ElevationMappingNode::updateVariance(const ros::TimerEvent&) { -// map_.update_variance(); -// } -// void ElevationMappingNode::updateTime(const ros::TimerEvent&) { -// map_.update_time(); -// } +void ElevationMappingNode::setPublishPoint(const std::shared_ptr request, + std::shared_ptr response) { + enablePointCloudPublishing_ = request->data; + response->success = true; +} -// void ElevationMappingNode::publishStatistics(const ros::TimerEvent&) { -// ros::Time now = ros::Time::now(); -// double dt = (now - lastStatisticsPublishedTime_).toSec(); -// lastStatisticsPublishedTime_ = now; -// elevation_map_msgs::Statistics msg; -// msg.header.stamp = now; -// if (dt > 0.0) { -// msg.pointcloud_process_fps = pointCloudProcessCounter_ / dt; -// } -// pointCloudProcessCounter_ = 0; -// statisticsPub_.publish(msg); -// } -// void ElevationMappingNode::updateGridMap(const ros::TimerEvent&) { -// std::vector layers(map_layers_all_.begin(), map_layers_all_.end()); -// std::lock_guard lock(mapMutex_); -// map_.get_grid_map(gridMap_, layers); -// gridMap_.setTimestamp(ros::Time::now().toNSec()); -// alivePub_.publish(std_msgs::Empty()); +void ElevationMappingNode::updateVariance() { + map_->update_variance(); +} -// // Mostly debug purpose -// if (enablePointCloudPublishing_) { -// publishAsPointCloud(gridMap_); -// } -// if (enableNormalArrowPublishing_) { -// publishNormalAsArrow(gridMap_); -// } -// isGridmapUpdated_ = true; -// } +void ElevationMappingNode::updateTime() { + map_->update_time(); +} + +void ElevationMappingNode::publishStatistics() { + auto now = this->now(); + double dt = (now - lastStatisticsPublishedTime_).seconds(); + lastStatisticsPublishedTime_ = now; + elevation_map_msgs::msg::Statistics msg; + msg.header.stamp = now; + if (dt > 0.0) { + msg.pointcloud_process_fps = pointCloudProcessCounter_ / dt; + } + pointCloudProcessCounter_ = 0; + statisticsPub_->publish(msg); +} + +void ElevationMappingNode::updateGridMap() { + std::vector layers(map_layers_all_.begin(), map_layers_all_.end()); + std::lock_guard lock(mapMutex_); + map_->get_grid_map(gridMap_, layers); + gridMap_.setTimestamp(this->now().nanoseconds()); + alivePub_->publish(std_msgs::msg::Empty()); + + // Mostly debug purpose + if (enablePointCloudPublishing_) { + publishAsPointCloud(gridMap_); + } + if (enableNormalArrowPublishing_) { + publishNormalAsArrow(gridMap_); + } + isGridmapUpdated_ = true; +} void ElevationMappingNode::initializeMap(const std::shared_ptr request, std::shared_ptr response) { @@ -813,65 +827,68 @@ void ElevationMappingNode::initializeMap(const std::shared_ptrsuccess = true; } -// void ElevationMappingNode::publishNormalAsArrow(const grid_map::GridMap& map) const { -// auto startTime = ros::Time::now(); +void ElevationMappingNode::publishNormalAsArrow(const grid_map::GridMap& map) const { + auto startTime = this->now(); -// const auto& normalX = map["normal_x"]; -// const auto& normalY = map["normal_y"]; -// const auto& normalZ = map["normal_z"]; -// double scale = 0.1; + const auto& normalX = map["normal_x"]; + const auto& normalY = map["normal_y"]; + const auto& normalZ = map["normal_z"]; + double scale = 0.1; -// visualization_msgs::MarkerArray markerArray; -// // For each cell in map. -// for (grid_map::GridMapIterator iterator(map); !iterator.isPastEnd(); ++iterator) { -// if (!map.isValid(*iterator, "elevation")) { -// continue; -// } -// grid_map::Position3 p; -// map.getPosition3("elevation", *iterator, p); -// Eigen::Vector3d start = p; -// const auto i = iterator.getLinearIndex(); -// Eigen::Vector3d normal(normalX(i), normalY(i), normalZ(i)); -// Eigen::Vector3d end = start + normal * scale; -// if (normal.norm() < 0.1) { -// continue; -// } -// markerArray.markers.push_back(vectorToArrowMarker(start, end, i)); -// } -// normalPub_.publish(markerArray); -// ROS_INFO_THROTTLE(1.0, "publish as normal in %f sec.", (ros::Time::now() - startTime).toSec()); -// } + visualization_msgs::msg::MarkerArray markerArray; + // For each cell in map. + for (grid_map::GridMapIterator iterator(map); !iterator.isPastEnd(); ++iterator) { + if (!map.isValid(*iterator, "elevation")) { + continue; + } + grid_map::Position3 p; + map.getPosition3("elevation", *iterator, p); + Eigen::Vector3d start = p; + const auto i = iterator.getLinearIndex(); + Eigen::Vector3d normal(normalX(i), normalY(i), normalZ(i)); + Eigen::Vector3d end = start + normal * scale; + if (normal.norm() < 0.1) { + continue; + } + markerArray.markers.push_back(vectorToArrowMarker(start, end, i)); + } + normalPub_->publish(markerArray); + double elapsed_time = (this->now() - startTime).seconds(); + RCLCPP_INFO(this->get_logger(), "Initializing ElevationMappingNode...");(this->get_logger(), std::chrono::seconds(1), "publish as normal in %f sec.", elapsed_time); +} -// visualization_msgs::Marker ElevationMappingNode::vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, -// const int id) const { -// visualization_msgs::Marker marker; -// marker.header.frame_id = mapFrameId_; -// marker.header.stamp = ros::Time::now(); -// marker.ns = "normal"; -// marker.id = id; -// marker.type = visualization_msgs::Marker::ARROW; -// marker.action = visualization_msgs::Marker::ADD; -// marker.points.resize(2); -// marker.points[0].x = start.x(); -// marker.points[0].y = start.y(); -// marker.points[0].z = start.z(); -// marker.points[1].x = end.x(); -// marker.points[1].y = end.y(); -// marker.points[1].z = end.z(); -// marker.pose.orientation.x = 0.0; -// marker.pose.orientation.y = 0.0; -// marker.pose.orientation.z = 0.0; -// marker.pose.orientation.w = 1.0; -// marker.scale.x = 0.01; -// marker.scale.y = 0.01; -// marker.scale.z = 0.01; -// marker.color.a = 1.0; // Don't forget to set the alpha! -// marker.color.r = 0.0; -// marker.color.g = 1.0; -// marker.color.b = 0.0; - -// return marker; -// } + + +visualization_msgs::msg::Marker ElevationMappingNode::vectorToArrowMarker(const Eigen::Vector3d& start, const Eigen::Vector3d& end, + const int id) const { + visualization_msgs::msg::Marker marker; + marker.header.frame_id = mapFrameId_; + marker.header.stamp = this->now(); + marker.ns = "normal"; + marker.id = id; + marker.type = visualization_msgs::msg::Marker::ARROW; + marker.action = visualization_msgs::msg::Marker::ADD; + marker.points.resize(2); + marker.points[0].x = start.x(); + marker.points[0].y = start.y(); + marker.points[0].z = start.z(); + marker.points[1].x = end.x(); + marker.points[1].y = end.y(); + marker.points[1].z = end.z(); + marker.pose.orientation.x = 0.0; + marker.pose.orientation.y = 0.0; + marker.pose.orientation.z = 0.0; + marker.pose.orientation.w = 1.0; + marker.scale.x = 0.01; + marker.scale.y = 0.01; + marker.scale.z = 0.01; + marker.color.a = 1.0; // Don't forget to set the alpha! + marker.color.r = 0.0; + marker.color.g = 1.0; + marker.color.b = 0.0; + + return marker; +} void ElevationMappingNode::publishMapToOdom(double error) { From 0526be49220890e8bba585b1040896187d35a592 Mon Sep 17 00:00:00 2001 From: amilearning Date: Fri, 8 Nov 2024 05:24:15 +0100 Subject: [PATCH 452/504] recording pointcloud update --- elevation_mapping_cupy/config/core/core_param.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index c128291f..8b5bf32c 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -50,7 +50,7 @@ elevation_mapping: overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) pose_topic: '/odom' - map_frame: 'base_footprint' # The map frame where the odometry source uses. + map_frame: 'odom' # The map frame where the odometry source uses. base_frame: 'base_link' # The robot's base frame. This frame will be a center of the map. corrected_map_frame: 'odom' From b0d06c3e04862f355a921cedb28fcf62ebc12a5e Mon Sep 17 00:00:00 2001 From: HO JIN LEE Date: Fri, 8 Nov 2024 06:08:24 +0100 Subject: [PATCH 453/504] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 057424df..f2f8338d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,16 @@ +## ROS2 Elevation Mapping Cupy + **Status**: Under Development 🚧 +### Features +- **Point cloud-based map update**: *Functional* +- **Image-based map update**: *Ongoing development* + +### Dependencies - +- **ROS 2 Humble** +- **CUDA 12.4** +- **PyTorch 2.4.0** + +![Elevation Map in ROS 2 Humble with Gazebo ](https://github.com/user-attachments/assets/0dd9ebbe-a90d-486f-9871-81921308fab9) + # Elevation Mapping cupy ![python tests](https://github.com/leggedrobotics/elevation_mapping_cupy/actions/workflows/python-tests.yml/badge.svg) From 80c2990c89d666bceb1036524f036fb456924c67 Mon Sep 17 00:00:00 2001 From: amilearning Date: Mon, 11 Nov 2024 06:06:42 +0900 Subject: [PATCH 454/504] orin topics --- .../config/core/core_param copy.yaml | 189 ++++++++++++++++++ .../config/core/core_param.yaml | 36 ++-- .../elevation_mapping_ros.hpp | 2 +- .../src/elevation_mapping_ros.cpp | 60 +++--- 4 files changed, 240 insertions(+), 47 deletions(-) create mode 100644 elevation_mapping_cupy/config/core/core_param copy.yaml diff --git a/elevation_mapping_cupy/config/core/core_param copy.yaml b/elevation_mapping_cupy/config/core/core_param copy.yaml new file mode 100644 index 00000000..bf5f1cd4 --- /dev/null +++ b/elevation_mapping_cupy/config/core/core_param copy.yaml @@ -0,0 +1,189 @@ +elevation_mapping: + ros__parameters: + #### Basic parameters ######## + enable_normal_arrow_publishing: true + cell_n: 40000 # number of cells in the map. + data_type: 'float32' # data type for the map. + average_weight: 0.5 + drift_compensation_variance_inlier: 0.1 + checker_layer: 'traversability' # layer name for checking the validity of the cell. + min_filter_size: 5 # size of the filter for min filter. + min_filter_iteration: 3 # number of iterations for min filter. + initialized_variance: 10.0 # initial variance for each cell. + resolution: 0.1 # resolution in m. + map_length: 20.0 # map's size in m. + sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). + mahalanobis_thresh: 2.0 # points outside this distance is outlier. + outlier_variance: 0.01 # if point is outlier, add this value to the cell. + drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. + max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) + drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation + time_variance: 0.0001 # add this value when update_variance is called. + max_variance: 100.0 # maximum variance for each cell. + initial_variance: 1000.0 # initial variance for each cell. + traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. + dilation_size: 3 # dilation filter size before traversability filter. + wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. + min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. + position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. + orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. + position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. + orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. + min_valid_distance: 0.5 # points with shorter distance will be filtered out. + max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. + ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + update_variance_fps: 5.0 # fps for updating variance. + update_pose_fps: 10.0 # fps for updating pose and shift the center of map. + time_interval: 0.1 # Time layer is updated with this interval. + map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. + publish_statistics_fps: 1.0 # Publish statistics topic in this fps. + + max_ray_length: 10.0 # maximum length for ray tracing. + cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + + safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. + safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. + max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + + overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) + overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + pose_topic: '/odom' + map_frame: 'odom' # The map frame where the odometry source uses. + base_frame: 'base_link' # The robot's base frame. This frame will be a center of the map. + corrected_map_frame: 'odom' + + + + #### Feature toggles ######## + enable_edge_sharpen: true + enable_visibility_cleanup: true + enable_drift_compensation: true + enable_overlap_clearance: true + enable_pointcloud_publishing: false + enable_drift_corrected_TF_publishing: false + enable_normal_color: true # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + + + #### Traversability filter ######## + use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. + weight_file: '/share/elevation_mapping_cupy/config/core/weights.dat' # Weight file for traversability filter + plugin_config_file: '/share/elevation_mapping_cupy/config/core/plugin_config.yaml' # Configuration file for the plugin. + #### Upper bound ######## + use_only_above_for_upper_bound: false + + #### Initializer ######## + initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' + initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. + initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. + dilation_size_initialize: 2 # dilation size after the init. + initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. + use_initializer_at_start: true # Use initializer when the node starts. + + #### Default Plugins ######## + + pointcloud_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'average' # 'average' fusion is used for channels not listed here + + image_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'exponential' # 'exponential' fusion is used for channels not listed here + feat_.*: 'exponential' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names + + #### Subscribers ######## + # pointcloud_sensor_name: + # topic_name: '/sensor/pointcloud_semantic' + # data_type: pointcloud # pointcloud or image + # + # image_sensor_name: + # topic_name: '/camera/image_semantic' + # data_type: image # pointcloud or image + # camera_info_topic_name: '/camera/depth/camera_info' + # channel_info_topic_name: '/camera/channel_info' + + + subscribers: + pointcloud1: + # topic_name: '/ouster/points' + topic_name: '/a200/sensors/camera_0/points' + data_type: 'pointcloud' + image1: + topic_name: '/a200/sensors/camera_0/color/image' + info_name: '/a200/sensors/camera_0/color/camera_info' + data_type: 'image' + # channel_name: '/front_cam/channel_info' + + # image_topic2: '/camera/rgb/image_raw2' + # image_info2: '/camera/depth/camera_info2' + # image_channel_info1: '/front_cam/channel_info' + + # image: # for semantic images + # topic_name: '/front_cam/semantic_image' + # camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' + # channel_info_topic_name: '/front_cam/channel_info' + # data_type: image + + #### Publishers ######## + # topic_name: + # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names + # basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. + # fps: # Publish rate. Use smaller value than `map_acquire_fps`. + + publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb', 'normal_x', 'normal_y', 'normal_z'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_recordable: + layers: ['elevation', 'traversability'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + basic_layers: ['min_filter'] + fps: 3.0 + + + # plugun info + + min_filter: + enable: True # whether to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # These params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations + + # Apply smoothing. + smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" + + # Apply inpainting using opencv + inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns + + # Apply smoothing for inpainted layer + erosion: + enable: True + fill_nan: False + is_height_layer: False + layer_name: "erosion" + extra_params: + input_layer_name: "traversability" + dilation_size: 3 + iteration_n: 20 + reverse: True \ No newline at end of file diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 8b5bf32c..6facd7d9 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -1,6 +1,7 @@ elevation_mapping: ros__parameters: - #### Basic parameters ######## + #### Basic parameters ######## + enable_normal_arrow_publishing: false cell_n: 40000 # number of cells in the map. data_type: 'float32' # data type for the map. average_weight: 0.5 @@ -10,7 +11,7 @@ elevation_mapping: min_filter_iteration: 3 # number of iterations for min filter. initialized_variance: 10.0 # initial variance for each cell. resolution: 0.1 # resolution in m. - map_length: 20.0 # map's size in m. + map_length: 20.0 # map's size in m. sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). mahalanobis_thresh: 2.0 # points outside this distance is outlier. outlier_variance: 0.01 # if point is outlier, add this value to the cell. @@ -63,8 +64,8 @@ elevation_mapping: enable_overlap_clearance: true enable_pointcloud_publishing: false enable_drift_corrected_TF_publishing: false - enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. - enable_normal: false + enable_normal_color: true # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + enable_normal: true #### Traversability filter ######## use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. @@ -105,12 +106,13 @@ elevation_mapping: subscribers: pointcloud1: + # topic_name: '/ouster/points' topic_name: '/a200/sensors/camera_0/points' data_type: 'pointcloud' - image1: - topic_name: '/a200/sensors/camera_0/color/image' - info_name: '/a200/sensors/camera_0/color/camera_info' - data_type: 'image' + # image1: + # topic_name: '/a200/sensors/camera_0/color/image' + # info_name: '/a200/sensors/camera_0/color/camera_info' + # data_type: 'image' # channel_name: '/front_cam/channel_info' # image_topic2: '/camera/rgb/image_raw2' @@ -133,17 +135,17 @@ elevation_mapping: publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb'] + layers: ['elevation', 'traversability', 'variance','normal_x', 'normal_y', 'normal_z'] basic_layers: ['elevation'] fps: 5.0 - elevation_map_recordable: - layers: ['elevation', 'traversability'] - basic_layers: ['elevation', 'traversability'] - fps: 2.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] - basic_layers: ['min_filter'] - fps: 3.0 + # elevation_map_recordable: + # layers: ['elevation', 'traversability'] + # basic_layers: ['elevation', 'traversability'] + # fps: 2.0 + # elevation_map_filter: + # layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + # basic_layers: ['min_filter'] + # fps: 3.0 # plugun info diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 7cf91ce1..220509e4 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -14,7 +14,7 @@ // Pybind #include // everything needed for embedding - +#include // ROS #include #include diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 57f8bd83..8825b97e 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -132,29 +132,29 @@ ElevationMappingNode::ElevationMappingNode() // } else { // transport_hint = "raw"; // In the default case we assume raw topic // } - - ImageSubscriberPtr image_sub = std::make_shared(this, camera_topic, rmw_qos_profile_sensor_data); - imageSubs_.push_back(image_sub); - - CameraInfoSubscriberPtr cam_info_sub = std::make_shared(this, info_topic, rmw_qos_profile_sensor_data); - cameraInfoSubs_.push_back(cam_info_sub); - - std::string channel_info_topic; - if (this->get_parameter("subscribers." + sub_name + ".channel_name", channel_info_topic)) { - ChannelInfoSubscriberPtr channel_info_sub = std::make_shared(this, channel_info_topic, rmw_qos_profile_sensor_data); - channelInfoSubs_.push_back(channel_info_sub); - CameraChannelSyncPtr sync = std::make_shared(CameraChannelPolicy(10), *image_sub, *cam_info_sub, *channel_info_sub); - sync->registerCallback(std::bind(&ElevationMappingNode::imageChannelCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - cameraChannelSyncs_.push_back(sync); - RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s, Camera info topic: %s, Channel info topic: %s", camera_topic.c_str(), info_topic.c_str(), channel_info_topic.c_str()); - }else{ - std::string key = sub_name; - channels_[key].push_back("rgb"); - // RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s, Camera info topic: %s. Channel info topic: %s", camera_topic.c_str(), info_topic.c_str(), (channel_info_topic.empty() ? ("Not found. Using channels: " + boost::algorithm::join(channels_[key], ", ")).c_str() : channel_info_topic.c_str())); - CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); - sync->registerCallback(std::bind(&ElevationMappingNode::imageCallback, this, std::placeholders::_1, std::placeholders::_2, key)); - cameraSyncs_.push_back(sync); - } + + ImageSubscriberPtr image_sub = std::make_shared(this, camera_topic, rmw_qos_profile_sensor_data); + imageSubs_.push_back(image_sub); + + CameraInfoSubscriberPtr cam_info_sub = std::make_shared(this, info_topic, rmw_qos_profile_sensor_data); + cameraInfoSubs_.push_back(cam_info_sub); + + std::string channel_info_topic; + if (this->get_parameter("subscribers." + sub_name + ".channel_name", channel_info_topic)) { + ChannelInfoSubscriberPtr channel_info_sub = std::make_shared(this, channel_info_topic, rmw_qos_profile_sensor_data); + channelInfoSubs_.push_back(channel_info_sub); + CameraChannelSyncPtr sync = std::make_shared(CameraChannelPolicy(10), *image_sub, *cam_info_sub, *channel_info_sub); + sync->registerCallback(std::bind(&ElevationMappingNode::imageChannelCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + cameraChannelSyncs_.push_back(sync); + RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s, Camera info topic: %s, Channel info topic: %s", camera_topic.c_str(), info_topic.c_str(), channel_info_topic.c_str()); + }else{ + std::string key = sub_name; + channels_[key].push_back("rgb"); + // RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s, Camera info topic: %s. Channel info topic: %s", camera_topic.c_str(), info_topic.c_str(), (channel_info_topic.empty() ? ("Not found. Using channels: " + boost::algorithm::join(channels_[key], ", ")).c_str() : channel_info_topic.c_str())); + CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); + sync->registerCallback(std::bind(&ElevationMappingNode::imageCallback, this, std::placeholders::_1, std::placeholders::_2, key)); + cameraSyncs_.push_back(sync); + } }else if(data_type == "pointcloud"){ std::string pointcloud_topic; this->get_parameter("subscribers." + sub_name + ".topic_name", pointcloud_topic); @@ -162,10 +162,13 @@ ElevationMappingNode::ElevationMappingNode() channels_[key].push_back("x"); channels_[key].push_back("y"); channels_[key].push_back("z"); + rmw_qos_profile_t qos_profile = rmw_qos_profile_default; + auto qos = rclcpp::QoS(rclcpp::QoSInitialization(qos_profile.history, qos_profile.depth), qos_profile); + auto callback = [this, key](const sensor_msgs::msg::PointCloud2::SharedPtr msg) { this->pointcloudCallback(msg, key); }; - auto sub = this->create_subscription(pointcloud_topic, 1, callback); + auto sub = this->create_subscription(pointcloud_topic, qos, callback); pointcloudSubs_.push_back(sub); RCLCPP_INFO(this->get_logger(), "Subscribed to PointCloud2 topic: %s", pointcloud_topic.c_str()); } @@ -356,8 +359,8 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::msg::PointCloud std::vector channels; for (size_t it = 0; it < fields.size(); it++) { - auto& field = fields[it]; - channels.push_back(field.name); + auto& field = fields[it]; + channels.push_back(field.name); } inputPointCloud(cloud, channels); @@ -775,6 +778,7 @@ void ElevationMappingNode::updateGridMap() { if (enablePointCloudPublishing_) { publishAsPointCloud(gridMap_); } + if (enableNormalArrowPublishing_) { publishNormalAsArrow(gridMap_); } @@ -852,9 +856,7 @@ void ElevationMappingNode::publishNormalAsArrow(const grid_map::GridMap& map) co } markerArray.markers.push_back(vectorToArrowMarker(start, end, i)); } - normalPub_->publish(markerArray); - double elapsed_time = (this->now() - startTime).seconds(); - RCLCPP_INFO(this->get_logger(), "Initializing ElevationMappingNode...");(this->get_logger(), std::chrono::seconds(1), "publish as normal in %f sec.", elapsed_time); + normalPub_->publish(markerArray); } From d336c47e3c6b85f085449ab87ab34d076dc06b27 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 12:17:46 +0100 Subject: [PATCH 455/504] basic version --- elevation_mapping_cupy/CMakeLists.txt | 24 - .../config/core/core_param.yaml | 131 ++-- .../setups/turtle_bot/turtle_bot_simple.yaml | 41 +- .../elevation_mapping.py | 38 +- .../elevation_mapping_ros.py | 565 +++++++++++++----- .../elevation_mapping_cupy/listener_test.py | 33 + .../launch/elevation_mapping.launch.py | 22 + .../launch/elevation_mapping_launch.py | 16 - .../launch/elevation_mapping_turtle.launch.py | 65 ++ .../launch/turtle_simple_example.launch.py | 68 +++ .../launch/turtlesim_init.launch.py | 185 ++++++ elevation_mapping_cupy/package.xml | 61 +- .../resource/elevation_mapping_cupy | 0 elevation_mapping_cupy/setup.cfg | 4 + elevation_mapping_cupy/setup.py | 11 +- 15 files changed, 945 insertions(+), 319 deletions(-) delete mode 100644 elevation_mapping_cupy/CMakeLists.txt create mode 100644 elevation_mapping_cupy/elevation_mapping_cupy/listener_test.py create mode 100755 elevation_mapping_cupy/launch/elevation_mapping.launch.py delete mode 100755 elevation_mapping_cupy/launch/elevation_mapping_launch.py create mode 100644 elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py create mode 100644 elevation_mapping_cupy/launch/turtle_simple_example.launch.py create mode 100644 elevation_mapping_cupy/launch/turtlesim_init.launch.py create mode 100644 elevation_mapping_cupy/resource/elevation_mapping_cupy create mode 100644 elevation_mapping_cupy/setup.cfg diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt deleted file mode 100644 index 68a1c1af..00000000 --- a/elevation_mapping_cupy/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(elevation_mapping_cupy) - -find_package(ament_cmake_python REQUIRED) -find_package(rclpy REQUIRED) -find_package(std_msgs REQUIRED) -find_package(sensor_msgs REQUIRED) -find_package(geometry_msgs REQUIRED) -find_package(elevation_map_msgs REQUIRED) -find_package(grid_map_msgs REQUIRED) -find_package(grid_map_ros REQUIRED) -find_package(image_transport REQUIRED) -find_package(pcl_ros REQUIRED) -find_package(pybind11 REQUIRED) - -# Install Python modules -ament_python_install_package(${PROJECT_NAME}) - -# Install launch and config directories -install(DIRECTORY launch config - DESTINATION share/${PROJECT_NAME}/ -) - -ament_package() diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 17baea09..38c2301b 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -1,72 +1,77 @@ -#### Basic parameters ######## -resolution: 0.04 # resolution in m. -map_length: 8.0 # map's size in m. -sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). -mahalanobis_thresh: 2.0 # points outside this distance is outlier. -outlier_variance: 0.01 # if point is outlier, add this value to the cell. -drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. -max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) -drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation -time_variance: 0.0001 # add this value when update_variance is called. -max_variance: 100.0 # maximum variance for each cell. -initial_variance: 1000.0 # initial variance for each cell. -traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. -dilation_size: 3 # dilation filter size before traversability filter. -wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. -min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. -position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. -orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. -position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -min_valid_distance: 0.5 # points with shorter distance will be filtered out. -max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. -ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -update_variance_fps: 5.0 # fps for updating variance. -update_pose_fps: 10.0 # fps for updating pose and shift the center of map. -time_interval: 0.1 # Time layer is updated with this interval. -map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. -publish_statistics_fps: 1.0 # Publish statistics topic in this fps. +elevation_mapping_node: + ros__parameters: + #### Basic parameters ######## + resolution: 0.04 # resolution in m. + map_length: 8.0 # map's size in m. + sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). + mahalanobis_thresh: 2.0 # points outside this distance is outlier. + outlier_variance: 0.01 # if point is outlier, add this value to the cell. + drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. + max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) + drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation + time_variance: 0.0001 # add this value when update_variance is called. + max_variance: 100.0 # maximum variance for each cell. + initial_variance: 1000.0 # initial variance for each cell. + traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. + dilation_size: 3 # dilation filter size before traversability filter. + wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. + min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. + position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. + orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. + position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. + orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. + min_valid_distance: 0.5 # points with shorter distance will be filtered out. + max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. + ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + update_variance_fps: 5.0 # fps for updating variance. + update_pose_fps: 3.0 # fps for updating pose and shift the center of map. + time_interval: 0.1 # Time layer is updated with this interval. + map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. + publish_statistics_fps: 1.0 # Publish statistics topic in this fps. + recordable_fps: 3.0 # Recordable fps for pointcloud. + enable_normal_arrow_publishing: false -max_ray_length: 10.0 # maximum length for ray tracing. -cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. -cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + max_ray_length: 10.0 # maximum length for ray tracing. + cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. -safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. -safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. -max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. + safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. + max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. -overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) -overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) + overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) -map_frame: 'odom' # The map frame where the odometry source uses. -base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'odom' + map_frame: 'odom' # The map frame where the odometry source uses. + base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. + corrected_map_frame: 'odom' + -#### Feature toggles ######## -enable_edge_sharpen: true -enable_visibility_cleanup: true -enable_drift_compensation: true -enable_overlap_clearance: true -enable_pointcloud_publishing: false -enable_drift_corrected_TF_publishing: false -enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + #### Feature toggles ######## + enable_edge_sharpen: true + enable_visibility_cleanup: true + enable_drift_compensation: true + enable_overlap_clearance: true + enable_pointcloud_publishing: false + enable_drift_corrected_TF_publishing: false + enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. -#### Traversability filter ######## -use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. -weight_file: '$(rospack find elevation_mapping_cupy)/config/core/weights.dat' # Weight file for traversability filter + #### Traversability filter ######## + use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. + weight_file: '$(find-pkg-share elevation_mapping_cupy)/config/core/weights.dat' # Weight file for traversability filter -#### Upper bound ######## -use_only_above_for_upper_bound: false + #### Upper bound ######## + use_only_above_for_upper_bound: false -#### Initializer ######## -initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. -dilation_size_initialize: 2 # dilation size after the init. -initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. -use_initializer_at_start: true # Use initializer when the node starts. + #### Initializer ######## + initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' + initialize_frame_id: 'nearest' # One tf (like ['footprint'] ) initializes a square around it. + initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. + dilation_size_initialize: 2 # dilation size after the init. + initialize_tf_grid_size: 50 # This is not used if number of tf is more than 3. + use_initializer_at_start: true # Use initializer when the node starts. -#### Default Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/core/plugin_config.yaml' \ No newline at end of file + #### Default Plugins ######## + plugin_config_file: '$(find-pkg-share elevation_mapping_cupy)/config/core/plugin_config.yaml' \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml index a76fcc61..0a38bfff 100644 --- a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml @@ -1,23 +1,18 @@ -pointcloud_channel_fusions: - rgb: 'color' - default: 'average' - -image_channel_fusions: - rgb: 'color' - default: 'exponential' - feat_.*: 'exponential' - -subscribers: - front_cam: - topic_name: '/camera/depth/points' - data_type: pointcloud - -publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb'] - basic_layers: ['elevation'] - fps: 5.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] - basic_layers: ['min_filter'] - fps: 3.0 \ No newline at end of file +/elevation_mapping_node: + ros__parameters: + pointcloud_channel_fusions: + rgb: 'color' + default: 'average' + image_channel_fusions: + rgb: 'color' + default: 'exponential' + feat_.*: 'exponential' + subscribers: + front_cam: + topic_name: '/intel_realsense_r200_depth/points' + data_type: 'pointcloud' + publishers: + elevation_map_raw: + layers: ['elevation'] + basic_layers: ['elevation'] + fps: 5.0 \ No newline at end of file diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py index c189fd68..967772cc 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py @@ -41,6 +41,7 @@ ) import cupy as cp +import rclpy # Import rclpy for ROS 2 logging xp = cp pool = cp.cuda.MemoryPool(cp.cuda.malloc_managed) @@ -56,6 +57,9 @@ def __init__(self, param: Parameter): Args: param (elevation_mapping_cupy.parameter.Parameter): """ + # Initialize the ROS logger + self.logger = rclpy.logging.get_logger('elevation_map') + self.param = param self.data_type = self.param.data_type self.resolution = param.resolution @@ -315,23 +319,17 @@ def shift_translation_to_map_center(self, t): t -= self.center def update_map_with_kernel(self, points_all, channels, R, t, position_noise, orientation_noise): - """Update map with new measurement. - - Args: - points_all (cupy._core.core.ndarray): - channels (List[str]): - R (cupy._core.core.ndarray): - t (cupy._core.core.ndarray): - position_noise (float): - orientation_noise (float): - """ + """Update map with new measurement.""" self.new_map *= 0.0 error = cp.array([0.0], dtype=cp.float32) error_cnt = cp.array([0], dtype=cp.float32) points = points_all[:, :3] - # additional_fusion = self.get_fusion_of_pcl(channels) + with self.map_lock: self.shift_translation_to_map_center(t) + + # Log before kernel execution + self.error_counting_kernel( self.elevation_map, points, @@ -344,6 +342,7 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori error_cnt, size=(points.shape[0]), ) + if ( self.param.enable_drift_compensation and error_cnt > self.param.min_height_drift_cnt @@ -356,6 +355,8 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori self.additive_mean_error += self.mean_error if np.abs(self.mean_error) < self.param.max_drift: self.elevation_map[0] += self.mean_error * self.param.drift_compensation_alpha + + self.add_points_kernel( cp.array([0.0], dtype=self.data_type), cp.array([0.0], dtype=self.data_type), @@ -367,13 +368,16 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori self.new_map, size=(points.shape[0]), ) + + # Log after adding points + self.average_map_kernel(self.new_map, self.elevation_map, size=(self.cell_n * self.cell_n)) self.semantic_map.update_layers_pointcloud(points_all, channels, R, t, self.new_map) if self.param.enable_overlap_clearance: self.clear_overlap_map(t) - # dilation before traversability_filter + self.traversability_input *= 0.0 self.dilation_filter_kernel( self.elevation_map[5], @@ -382,13 +386,13 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori self.traversability_mask_dummy, size=(self.cell_n * self.cell_n), ) - # calculate traversability + traversability = self.traversability_filter(self.traversability_input) self.elevation_map[3][3:-3, 3:-3] = traversability.reshape( (traversability.shape[2], traversability.shape[3]) ) - # calculate normal vectors + # Log final state self.update_normal(self.traversability_input) def clear_overlap_map(self, t): @@ -455,6 +459,12 @@ def input_pointcloud( None: """ raw_points = cp.asarray(raw_points, dtype=self.data_type) + + # Check for the sanity of the raw points + min_points = cp.min(raw_points, axis=0) + max_points = cp.max(raw_points, axis=0) + mean_points = cp.mean(raw_points, axis=0) + additional_channels = channels[3:] raw_points = raw_points[~cp.isnan(raw_points[:, :3]).any(axis=1)] self.update_map_with_kernel( diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py index 34d2b8a3..139264dd 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py @@ -1,29 +1,39 @@ -from elevation_mapping_cupy import ElevationMap -from elevation_mapping_cupy import Parameter - -# General -import os +#!/usr/bin/env python3 +import matplotlib.pyplot as plt +from mpl_toolkits.mplot3d import Axes3D import numpy as np +import os +from functools import partial +import threading +import time # Import time module for benchmarking -# ROS +# ROS 2 imports import rclpy from rclpy.node import Node -import ros_numpy -from tf.transformations import quaternion_matrix +from rclpy.callback_groups import ReentrantCallbackGroup +from ament_index_python.packages import get_package_share_directory +import ros2_numpy as rnp +from sensor_msgs.msg import PointCloud2, Image, CameraInfo +from sensor_msgs_py import point_cloud2 +from tf_transformations import quaternion_matrix import tf2_ros -import rospkg + import message_filters from cv_bridge import CvBridge - -from sensor_msgs.msg import PointCloud2, Image, CameraInfo +from rclpy.duration import Duration +# Message imports from grid_map_msgs.msg import GridMap from std_msgs.msg import Float32MultiArray from std_msgs.msg import MultiArrayLayout as MAL from std_msgs.msg import MultiArrayDimension as MAD +from geometry_msgs.msg import TransformStamped -import numpy as np -from functools import partial +# Custom module imports +from elevation_mapping_cupy import ElevationMap, Parameter +import concurrent.futures + +# Define point cloud data types PDC_DATATYPE = { "1": np.int8, "2": np.uint8, @@ -38,80 +48,274 @@ class ElevationMappingNode(Node): def __init__(self): - super().__init__('elevation_mapping_node') - rospack = rospkg.RosPack() - self.root = rospack.get_path("elevation_mapping_cupy") + # Initialize the node without passing callback_group to super() + super().__init__( + 'elevation_mapping_node', + automatically_declare_parameters_from_overrides=True + ) + + # Create a ReentrantCallbackGroup for subscriptions and timers + self.callback_group = ReentrantCallbackGroup() + + # Get package share directory + self.root = get_package_share_directory("elevation_mapping_cupy") weight_file = os.path.join(self.root, "config/core/weights.dat") plugin_config_file = os.path.join(self.root, "config/core/plugin_config.yaml") - self.param = Parameter(use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file) + + # Initialize Parameters + self.param = Parameter( + use_chainer=False, + weight_file=weight_file, + plugin_config_file=plugin_config_file + ) self.node_name = "elevation_mapping" - # ROS - self.initalize_ros() - self.param.subscriber_cfg = self.subscribers + # Initialize ROS components + self.initialize_ros() + + # Assign subscriber configuration to parameters + self.param.subscriber_cfg = self.my_subscribers - self.initalize_elevation_mapping() + # Initialize Elevation Mapping + self.initialize_elevation_mapping() + + # Register ROS subscribers, publishers, and timers self.register_subscribers() self.register_publishers() self.register_timers() + # Initialize last timestamp self._last_t = None - def initalize_elevation_mapping(self): + # Initialize transform storage with thread safety + self._transform_lock = threading.Lock() + self._current_transform = None + + # Initialize ThreadPoolExecutor for pointcloud processing + self.thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=2) + self.get_logger().info("ThreadPoolExecutor initialized with 2 workers.") + + def initialize_elevation_mapping(self): self.param.update() - # TODO add statistics across processed topics self._pointcloud_process_counter = 0 self._image_process_counter = 0 self._map = ElevationMap(self.param) - self._map_data = np.zeros((self._map.cell_n - 2, self._map.cell_n - 2), dtype=np.float32) + self._map_data = np.zeros( + (self._map.cell_n - 2, self._map.cell_n - 2), dtype=np.float32 + ) self._map_q = None self._map_t = None - def initalize_ros(self): + def initialize_ros(self): + # Initialize TF buffer and listener with increased cache time self._tf_buffer = tf2_ros.Buffer() - self._listener = tf2_ros.TransformListener(self._tf_buffer) + # Initialize TransformListener + self._listener = tf2_ros.TransformListener(self._tf_buffer, self) + + # Retrieve ROS parameters self.get_ros_params() + def get_ros_params(self): + # Get parameters with default values + self.use_chainer = self.get_parameter('use_chainer').get_parameter_value().bool_value + self.weight_file = self.get_parameter('weight_file').get_parameter_value().string_value + self.plugin_config_file = self.get_parameter('plugin_config_file').get_parameter_value().string_value + self.initialize_frame_id = self.get_parameter('initialize_frame_id').get_parameter_value().string_value + self.initialize_tf_offset = self.get_parameter('initialize_tf_offset').get_parameter_value().double_array_value + self.map_frame = self.get_parameter('map_frame').get_parameter_value().string_value + self.base_frame = self.get_parameter('base_frame').get_parameter_value().string_value + self.corrected_map_frame = self.get_parameter('corrected_map_frame').get_parameter_value().string_value + self.initialize_method = self.get_parameter('initialize_method').get_parameter_value().string_value + self.position_lowpass_alpha = self.get_parameter('position_lowpass_alpha').get_parameter_value().double_value + self.orientation_lowpass_alpha = self.get_parameter('orientation_lowpass_alpha').get_parameter_value().double_value + self.recordable_fps = self.get_parameter('recordable_fps').get_parameter_value().double_value + self.update_variance_fps = self.get_parameter('update_variance_fps').get_parameter_value().double_value + self.time_interval = self.get_parameter('time_interval').get_parameter_value().double_value + self.update_pose_fps = self.get_parameter('update_pose_fps').get_parameter_value().double_value + self.initialize_tf_grid_size = self.get_parameter('initialize_tf_grid_size').get_parameter_value().double_value + self.map_acquire_fps = self.get_parameter('map_acquire_fps').get_parameter_value().double_value + self.publish_statistics_fps = self.get_parameter('publish_statistics_fps').get_parameter_value().double_value + self.enable_pointcloud_publishing = self.get_parameter('enable_pointcloud_publishing').get_parameter_value().bool_value + self.enable_normal_arrow_publishing = self.get_parameter('enable_normal_arrow_publishing').get_parameter_value().bool_value + self.enable_drift_corrected_TF_publishing = self.get_parameter('enable_drift_corrected_TF_publishing').get_parameter_value().bool_value + self.use_initializer_at_start = self.get_parameter('use_initializer_at_start').get_parameter_value().bool_value + + # Log parameters + self.get_logger().info("\n=== Loaded Parameters ===") + self.get_logger().info(f"use_chainer: {self.use_chainer}") + self.get_logger().info(f"weight_file: {self.weight_file}") + self.get_logger().info(f"plugin_config_file: {self.plugin_config_file}") + self.get_logger().info(f"initialize_frame_id: {self.initialize_frame_id}") + self.get_logger().info(f"initialize_tf_offset: {self.initialize_tf_offset}") + self.get_logger().info(f"map_frame: {self.map_frame}") + self.get_logger().info(f"base_frame: {self.base_frame}") + self.get_logger().info(f"corrected_map_frame: {self.corrected_map_frame}") + self.get_logger().info(f"initialize_method: {self.initialize_method}") + self.get_logger().info(f"position_lowpass_alpha: {self.position_lowpass_alpha}") + self.get_logger().info(f"orientation_lowpass_alpha: {self.orientation_lowpass_alpha}") + self.get_logger().info(f"recordable_fps: {self.recordable_fps}") + self.get_logger().info(f"update_variance_fps: {self.update_variance_fps}") + self.get_logger().info(f"time_interval: {self.time_interval}") + self.get_logger().info(f"update_pose_fps: {self.update_pose_fps}") + self.get_logger().info(f"initialize_tf_grid_size: {self.initialize_tf_grid_size}") + self.get_logger().info(f"map_acquire_fps: {self.map_acquire_fps}") + self.get_logger().info(f"publish_statistics_fps: {self.publish_statistics_fps}") + self.get_logger().info(f"enable_pointcloud_publishing: {self.enable_pointcloud_publishing}") + self.get_logger().info(f"enable_normal_arrow_publishing: {self.enable_normal_arrow_publishing}") + self.get_logger().info(f"enable_drift_corrected_TF_publishing: {self.enable_drift_corrected_TF_publishing}") + self.get_logger().info(f"use_initializer_at_start: {self.use_initializer_at_start}") + self.get_logger().info("=======================\n") + + # Retrieve subscribers using prefix + subscribers_params = self.get_parameters_by_prefix('subscribers') + self.get_logger().info(f"Subscribers params: {subscribers_params}") + self.my_subscribers = {} + for param_name, param_value in subscribers_params.items(): + parts = param_name.split('.') + if len(parts) >= 2: + sub_key, sub_param = parts[:2] + if sub_key not in self.my_subscribers: + self.my_subscribers[sub_key] = {} + self.my_subscribers[sub_key][sub_param] = param_value.value + else: + self.get_logger().warn(f"Unexpected subscriber parameter format: {param_name}") + + # Retrieve publishers using prefix + publishers_params = self.get_parameters_by_prefix('publishers') + self.get_logger().info(f"Publishers params: {publishers_params}") + self.my_publishers = {} + for param_name, param_value in publishers_params.items(): + parts = param_name.split('.') + if len(parts) >= 2: + pub_key, pub_param = parts[:2] + if pub_key not in self.my_publishers: + self.my_publishers[pub_key] = {} + self.my_publishers[pub_key][pub_param] = param_value.value + else: + self.get_logger().warn(f"Unexpected publisher parameter format: {param_name}") + + # Log loaded subscribers and publishers for debugging + self.get_logger().info(f"Loaded Subscribers: {self.my_subscribers}") + self.get_logger().info(f"Loaded Publishers: {self.my_publishers}") + + # If you want to list all parameters for debugging + params = self.get_parameters_by_prefix('') + for param_name, param_value in params.items(): + self.get_logger().info(f"Parameter '{param_name}': {param_value.value}") + def register_subscribers(self): - # check if CV bridge is needed - for config in self.param.subscriber_cfg.values(): - if config["data_type"] == "image": + # Initialize CvBridge if needed + for config in self.my_subscribers.values(): + if config.get("data_type") == "image": self.cv_bridge = CvBridge() break + # Dictionaries to hold subscribers pointcloud_subs = {} image_subs = {} - for key, config in self.subscribers.items(): - if config["data_type"] == "image": - camera_sub = message_filters.Subscriber(config["topic_name_camera"], Image) - camera_info_sub = message_filters.Subscriber(config["topic_name_camera_info"], CameraInfo) - image_subs[key] = message_filters.ApproximateTimeSynchronizer( + + for key, config in self.my_subscribers.items(): + data_type = config.get("data_type") + if data_type == "image": + topic_name_camera = config.get("topic_name_camera", "/camera/image") + topic_name_camera_info = config.get("topic_name_camera_info", "/camera/camera_info") + + # Initialize message_filters Subscribers without passing callback_group + camera_sub = message_filters.Subscriber( + self, + Image, + topic_name_camera + ) + camera_info_sub = message_filters.Subscriber( + self, + CameraInfo, + topic_name_camera_info + ) + + # Synchronize image and camera info + image_sync = message_filters.ApproximateTimeSynchronizer( [camera_sub, camera_info_sub], queue_size=10, slop=0.5 ) - image_subs[key].registerCallback(self.image_callback, key) + image_sync.registerCallback(partial(self.image_callback, sub_key=key)) + image_subs[key] = image_sync + + elif data_type == "pointcloud": + topic_name = config.get("topic_name", "/pointcloud") + qos_profile = rclpy.qos.QoSProfile( + depth=10, + reliability=rclpy.qos.ReliabilityPolicy.BEST_EFFORT, + durability=rclpy.qos.DurabilityPolicy.VOLATILE, + history=rclpy.qos.HistoryPolicy.KEEP_LAST + ) - elif config["data_type"] == "pointcloud": - pointcloud_subs[key] = self.create_subscription( - PointCloud2, config["topic_name"], self.pointcloud_callback, key + # Create subscription with ReentrantCallbackGroup + subscription = self.create_subscription( + PointCloud2, + topic_name, + partial(self.pointcloud_callback, sub_key=key), + qos_profile, + callback_group=self.callback_group # Assign ReentrantCallbackGroup ) + pointcloud_subs[key] = subscription + + else: + self.get_logger().warn(f"Unknown data_type '{data_type}' for subscriber '{key}'") + + self.get_logger().info( + f"Registered {len(pointcloud_subs)} pointcloud subscribers and {len(image_subs)} image subscribers." + ) def register_publishers(self): - self._publishers = {} + self._publishers_dict = {} self._publishers_timers = [] - for k, v in self.publishers.items(): - self._publishers[k] = self.create_publisher(GridMap, f"/{self.node_name}/{k}", 10) - # partial(.) allows to pass a default argument to a callback - self._publishers_timers.append(self.create_timer(1 / v["fps"], partial(self.publish_map, k))) - def publish_map(self, k): - print("publish_map") + for pub_key, pub_config in self.my_publishers.items(): + topic_name = f"/{self.node_name}/{pub_key}" + publisher = self.create_publisher(GridMap, topic_name, 10) + self._publishers_dict[pub_key] = publisher + + fps = pub_config.get("fps", 1.0) + timer = self.create_timer( + 1.0 / fps, + partial(self.publish_map, key=pub_key), + callback_group=self.callback_group # Assign ReentrantCallbackGroup + ) + self._publishers_timers.append(timer) + + self.get_logger().info(f"Publisher '{pub_key}' registered on topic '{topic_name}' with {fps} Hz.") + + def register_timers(self): + # Remove separate transform_updater and update_pose timers + # Register the combined timer instead + self.time_pose_update = self.create_timer( + 0.1, + self.pose_update, + callback_group=self.callback_group # Assign ReentrantCallbackGroup + ) + + # Register additional timers with the ReentrantCallbackGroup + self.timer_variance = self.create_timer( + 1.0 / self.update_variance_fps, + self.update_variance, + callback_group=self.callback_group # Assign ReentrantCallbackGroup + ) + self.timer_time = self.create_timer( + self.time_interval, + self.update_time, + callback_group=self.callback_group # Assign ReentrantCallbackGroup + ) + + self.get_logger().info("Combined transform and pose updater timer, variance, and time timers registered.") + + def publish_map(self, key): + self.get_logger().info("publish_map entered") if self._map_q is None: + self.get_logger().info("No map pose available for publishing.") return gm = GridMap() - gm.info.header.frame_id = self.map_frame - gm.info.header.stamp = self.get_clock().now().to_msg() - gm.info.header.seq = 0 + gm.header.frame_id = self.map_frame + gm.header.stamp = self.get_clock().now().to_msg() gm.info.resolution = self._map.resolution gm.info.length_x = self._map.map_length gm.info.length_y = self._map.map_length @@ -123,164 +327,217 @@ def publish_map(self, k): gm.info.pose.orientation.y = 0.0 # self._map_q.y gm.info.pose.orientation.z = 0.0 # self._map_q.z gm.layers = [] - gm.basic_layers = self.publishers[k]["basic_layers"] - for i, layer in enumerate(self.publishers[k]["layers"]): + gm.basic_layers = self.my_publishers[key]["basic_layers"] + for layer in self.my_publishers[key].get("layers", []): gm.layers.append(layer) - try: - self._map.get_map_with_name_ref(layer, self._map_data) - data = self._map_data.copy() - arr = Float32MultiArray() - arr.layout = MAL() - N = self._map_data.shape[0] - arr.layout.dim.append(MAD(label="column_index", size=N, stride=int(N * N))) - arr.layout.dim.append(MAD(label="row_index", size=N, stride=N)) - arr.data = tuple(np.ascontiguousarray(data.T).reshape(-1)) - gm.data.append(arr) - except: - if layer in gm.basic_layers: - print("Error: Missed Layer in basic layers") - + self._map.get_map_with_name_ref(layer, self._map_data) + + arr = Float32MultiArray() + arr.layout = MAL() + N = self._map_data.shape[0] + arr.layout.dim.append(MAD(label="column_index", size=N, stride=int(N * N))) + arr.layout.dim.append(MAD(label="row_index", size=N, stride=N)) + + # Convert to a Python list to satisfy the message requirements + arr.data = self._map_data.T.flatten().tolist() + + gm.data.append(arr) gm.outer_start_index = 0 gm.inner_start_index = 0 - self._publishers[k].publish(gm) + self._publishers_dict[key].publish(gm) - def register_timers(self): - self.timer_variance = self.create_timer(1 / self.update_variance_fps, self.update_variance) - self.timer_pose = self.create_timer(1 / self.update_pose_fps, self.update_pose) - self.timer_time = self.create_timer(self.time_interval, self.update_time) def image_callback(self, camera_msg, camera_info_msg, sub_key): - # get pose of image + # Get pose of image ti = camera_msg.header.stamp self._last_t = ti - try: - transform = self._tf_buffer.lookup_transform( - camera_msg.header.frame_id, self.map_frame, ti, rospy.Duration(1.0) - ) - except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - print("Error: image_callback:", e) + + # Retrieve the latest transform + transform = self.get_current_transform() + if transform is None: + self.get_logger().warn("No available transform for image_callback.") return t = transform.transform.translation - t = np.array([t.x, t.y, t.z]) q = transform.transform.rotation + t_np = np.array([t.x, t.y, t.z]) R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] - semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") + try: + semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") + except Exception as e: + self.get_logger().error(f"CV Bridge conversion failed: {e}") + return + # Ensure image is grayscale or split channels if len(semantic_img.shape) != 2: - semantic_img = [semantic_img[:, :, k] for k in range(3)] - + semantic_img = [semantic_img[:, :, k] for k in range(semantic_img.shape[2])] else: semantic_img = [semantic_img] - K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) + K = np.array(camera_info_msg.k, dtype=np.float32).reshape(3, 3) + D = np.array(camera_info_msg.d, dtype=np.float32).reshape(-1, 1) + + if not np.all(D == 0.0): + self.get_logger().warn("Camera distortion coefficients are not zero. Undistortion not implemented.") - assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" - D = np.array(camera_info_msg.D, dtype=np.float32).reshape(5, 1) - - # process pointcloud - self._map.input_image(sub_key, semantic_img, R, t, K, D, camera_info_msg.height, camera_info_msg.width) + # Process image + self._map.input_image( + sub_key, semantic_img, R, t_np, K, D, camera_info_msg.height, camera_info_msg.width + ) self._image_process_counter += 1 + self.get_logger().debug(f"Images processed: {self._image_process_counter}") + def pointcloud_callback(self, msg, sub_key): - channels = ["x", "y", "z"] + self.param.subscriber_cfg[sub_key]["channels"] - - points = ros_numpy.numpify(msg) - pts = np.empty((points.shape[0], 0)) - for ch in channels: - p = points[ch] - if len(p.shape) == 1: - p = p[:, None] - pts = np.append(pts, p, axis=1) - - # get pose of pointcloud - ti = msg.header.stamp - self._last_t = ti + start_time = time.time() + self._last_t = msg.header.stamp + self._pointcloud_stamp = msg.header.stamp + channels = ["x", "y", "z"] + self.param.subscriber_cfg[sub_key].get("channels", []) + try: - transform = self._tf_buffer.lookup_transform(self.map_frame, msg.header.frame_id, ti, rospy.Duration(1.0)) - except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - print("Error: pointcloud_callback: ", e) + points = rnp.numpify(msg) + except Exception as e: + self.get_logger().error(f"Failed to numpify pointcloud: {e}") return - t = transform.transform.translation - t = np.array([t.x, t.y, t.z]) - q = transform.transform.rotation - R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] + if points['xyz'].size == 0: + self.get_logger().warn("Received empty point cloud.") + return + + frame_sensor_id = msg.header.frame_id + try: + # Await the transform lookup + transform_sensor_to_odom = self._tf_buffer.lookup_transform( + self.map_frame, + frame_sensor_id, + self._pointcloud_stamp + ) + + # Process the transform directly here instead of using callback + t = transform_sensor_to_odom.transform.translation + q = transform_sensor_to_odom.transform.rotation + t_np = np.array([t.x, t.y, t.z], dtype=np.float32) + R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) + + # Submit the processing to the executor + self.thread_pool.submit(self.process_pointcloud, points['xyz'], channels, R, t_np, sub_key) - # process pointcloud - self._map.input(pts, channels, R, t, 0, 0) - self._pointcloud_process_counter += 1 - print("Pointclouds processed: ", self._pointcloud_process_counter) + except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: + self.get_logger().warn(f"Transform lookup failed: {e}") + except Exception as e: + self.get_logger().error(f"Unexpected error in pointcloud_callback: {str(e)}") - def update_pose(self): - # get pose of base - # t = rospy.Time.now() + def process_pointcloud(self, xyz, channels, R, t_np, sub_key): + try: + callback_start = time.time() + self._map.input_pointcloud(xyz, channels, R, t_np, 0, 0) + self._pointcloud_process_counter += 1 + callback_end = time.time() + self.get_logger().info(f"[process_pointcloud] input_pointcloud execution time: {callback_end - callback_start:.4f} seconds") + except Exception as e: + self.get_logger().error(f"Error processing pointcloud in separate thread: {str(e)}") + + def pose_update(self): if self._last_t is None: + self.get_logger().debug("No timestamp available for pose update.") return + try: transform = self._tf_buffer.lookup_transform( - self.map_frame, self.base_frame, self._last_t, rospy.Duration(1.0) + self.map_frame, + self.base_frame, + self._last_t ) - except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - print("Error: update_pose error: ", e) - return - t = transform.transform.translation - trans = np.array([t.x, t.y, t.z]) - q = transform.transform.rotation - rot = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] - self._map.move_to(trans, rot) - self._map_t = t - self._map_q = q + # Update the current transform with thread safety + with self._transform_lock: + self._current_transform = transform + + # Update the pose + t = transform.transform.translation + q = transform.transform.rotation + trans = np.array([t.x, t.y, t.z], dtype=np.float32) + rot = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) + + self._map.move_to(trans, rot) + self._map_t = t + self._map_q = q + + self.get_logger().debug("Pose updated.") + + except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: + self.get_logger().warn(f"Transform lookup failed in pose_update: {e}") + except Exception as e: + self.get_logger().error(f"Unexpected error in pose_update: {str(e)}") def update_variance(self): self._map.update_variance() + self.get_logger().debug("Variance updated.") def update_time(self): self._map.update_time() + self.get_logger().debug("Time updated.") - def get_ros_params(self): - self.declare_parameter('use_chainer', False) - self.declare_parameter('weight_file', '$(rospack find elevation_mapping_cupy)/config/core/weights.dat') - self.declare_parameter('plugin_config_file', '$(rospack find elevation_mapping_cupy)/config/core/plugin_config.yaml') - - self.subscribers = self.get_parameter("subscribers").value - self.publishers = self.get_parameter("publishers").value - self.initialize_frame_id = self.get_parameter("initialize_frame_id").value - self.initialize_tf_offset = self.get_parameter("initialize_tf_offset").value - self.pose_topic = self.get_parameter("pose_topic").value - self.map_frame = self.get_parameter("map_frame").value - self.base_frame = self.get_parameter("base_frame").value - self.corrected_map_frame = self.get_parameter("corrected_map_frame").value - self.initialize_method = self.get_parameter("initialize_method").value - self.position_lowpass_alpha = self.get_parameter("position_lowpass_alpha").value - self.orientation_lowpass_alpha = self.get_parameter("orientation_lowpass_alpha").value - self.recordable_fps = self.get_parameter("recordable_fps").value - self.update_variance_fps = self.get_parameter("update_variance_fps").value - self.time_interval = self.get_parameter("time_interval").value - self.update_pose_fps = self.get_parameter("update_pose_fps").value - self.initialize_tf_grid_size = self.get_parameter("initialize_tf_grid_size").value - self.map_acquire_fps = self.get_parameter("map_acquire_fps").value - self.publish_statistics_fps = self.get_parameter("publish_statistics_fps").value - self.enable_pointcloud_publishing = self.get_parameter("enable_pointcloud_publishing").value - self.enable_normal_arrow_publishing = self.get_parameter("enable_normal_arrow_publishing").value - self.enable_drift_corrected_TF_publishing = self.get_parameter("enable_drift_corrected_TF_publishing").value - self.use_initializer_at_start = self.get_parameter("use_initializer_at_start").value + def get_current_transform(self): + """Thread-safe method to retrieve the latest transform.""" + with self._transform_lock: + return self._current_transform + + def print_tf_frames(self): + """Print all available transforms in the TF buffer with timestamp""" + try: + # Get current timestamp + current_time = self.get_clock().now() + + # Try to get the specific transform from odom to base_footprint + try: + transform = self._tf_buffer.lookup_transform( + self.map_frame, + 'base_footprint', + rclpy.time.Time(), # get the latest transform + rclpy.duration.Duration(seconds=2.0) + ) + self.get_logger().info(f"\nOdom to base_footprint transform timestamp: " + f"{transform.header.stamp.sec}.{transform.header.stamp.nanosec}") + except (tf2_ros.LookupException, tf2_ros.ConnectivityException, + tf2_ros.ExtrapolationException) as e: + self.get_logger().warn(f"Could not lookup odom to base_footprint transform: {e}") + + # Get all frame IDs + frames = self._tf_buffer.all_frames_as_string() + # Uncomment the line below if you want to log all available TF frames + # self.get_logger().info(f"Available TF frames:\n{frames}") + except Exception as e: + self.get_logger().error(f"Failed to get TF frames: {e}") + + def destroy_node(self): + self.get_logger().info("Shutting down ThreadPoolExecutor.") + self.thread_pool.shutdown(wait=True) + super().destroy_node() def main(args=None): rclpy.init(args=args) node = ElevationMappingNode() + + # Initialize a MultiThreadedExecutor instead of SingleThreadedExecutor + executor = rclpy.executors.MultiThreadedExecutor() + executor.add_node(node) + try: - rclpy.spin(node) + # Use the executor to spin + executor.spin() except KeyboardInterrupt: - pass + node.get_logger().info("Shutting down ElevationMappingNode.") finally: + # Shutdown the executor and destroy the node + executor.shutdown() node.destroy_node() rclpy.shutdown() + if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/listener_test.py b/elevation_mapping_cupy/elevation_mapping_cupy/listener_test.py new file mode 100644 index 00000000..212d13f4 --- /dev/null +++ b/elevation_mapping_cupy/elevation_mapping_cupy/listener_test.py @@ -0,0 +1,33 @@ +import rclpy +from rclpy.node import Node +import tf2_ros +from geometry_msgs.msg import TransformStamped +from tf2_msgs.msg import TFMessage + +class TfListener(Node): + def __init__(self): + super().__init__('tf_listener') + self.subscription = self.create_subscription( + TFMessage, + '/tf', + self.listener_callback, + 10) + self.last_time = None + + def listener_callback(self, msg): + for transform in msg.transforms: + current_time = transform.header.stamp.sec + transform.header.stamp.nanosec * 1e-9 + if self.last_time is not None: + delta = current_time - self.last_time + self.get_logger().info(f"Delta time: {delta:.6f} seconds") + self.last_time = current_time + +def main(args=None): + rclpy.init(args=args) + node = TfListener() + rclpy.spin(node) + node.destroy_node() + rclpy.shutdown() + +if __name__ == '__main__': + main() diff --git a/elevation_mapping_cupy/launch/elevation_mapping.launch.py b/elevation_mapping_cupy/launch/elevation_mapping.launch.py new file mode 100755 index 00000000..f8f4f848 --- /dev/null +++ b/elevation_mapping_cupy/launch/elevation_mapping.launch.py @@ -0,0 +1,22 @@ +import os +from launch import LaunchDescription +from launch_ros.actions import Node +from ament_index_python.packages import get_package_share_directory + +def generate_launch_description(): + package_name = 'elevation_mapping_cupy' + share_dir = get_package_share_directory(package_name) + + config_file = os.path.join(share_dir, 'config', 'core_param.yaml') + if not os.path.exists(config_file): + raise FileNotFoundError(f"Config file {config_file} does not exist") + + return LaunchDescription([ + Node( + package=package_name, + executable='elevation_mapping_node', + name='elevation_mapping_node', + output='screen', + parameters=[config_file] + ) + ]) \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/elevation_mapping_launch.py b/elevation_mapping_cupy/launch/elevation_mapping_launch.py deleted file mode 100755 index 36e3df9d..00000000 --- a/elevation_mapping_cupy/launch/elevation_mapping_launch.py +++ /dev/null @@ -1,16 +0,0 @@ -from launch import LaunchDescription -from launch_ros.actions import Node -from launch_ros.parameter_descriptions import ParameterFile - -def generate_launch_description(): - return LaunchDescription([ - Node( - package='elevation_mapping_cupy', - executable='elevation_mapping_node', - name='elevation_mapping_node', - output='screen', - parameters=[ - ParameterFile('config/core/core_param.yaml', allow_substs=True) - ] - ) - ]) \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py b/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py new file mode 100644 index 00000000..7c6b06c3 --- /dev/null +++ b/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py @@ -0,0 +1,65 @@ +import os +from launch import LaunchDescription +from launch_ros.actions import Node +from ament_index_python.packages import get_package_share_directory +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration, PathJoinSubstitution + + +def generate_launch_description(): + package_name = 'elevation_mapping_cupy' + share_dir = get_package_share_directory(package_name) + + core_param_path = os.path.join(share_dir, 'config', 'core', 'core_param.yaml') + turtle_param_path = os.path.join(share_dir, 'config', 'setups', 'turtle_bot', 'turtle_bot_simple.yaml') + + # Add verification + if not os.path.exists(core_param_path): + raise FileNotFoundError(f"Core param file not found: {core_param_path}") + if not os.path.exists(turtle_param_path): + raise FileNotFoundError(f"Turtle param file not found: {turtle_param_path}") + + # Declare launch arguments + use_sim_time_arg = DeclareLaunchArgument( + 'use_sim_time', + default_value='true', + description='Use simulation (Gazebo) clock if true' + ) + use_sim_time = LaunchConfiguration('use_sim_time') + + rviz_config_arg = DeclareLaunchArgument( + 'rviz_config', + default_value=PathJoinSubstitution([ + share_dir, 'rviz', 'turtle_sim_laser.rviz' + ]), + description='Path to the RViz config file' + ) + rviz_config = LaunchConfiguration('rviz_config') + + # RViz Node + rviz_node = Node( + package='rviz2', + executable='rviz2', + name='rviz2', + arguments=['-d', rviz_config], + parameters=[{'use_sim_time': use_sim_time}], + output='screen' + ) + elevation_mapping_node = Node( + package='elevation_mapping_cupy', + executable='elevation_mapping_node', + name='elevation_mapping_node', + output='screen', + parameters=[ + core_param_path, + turtle_param_path, + {'use_sim_time': use_sim_time} + ] + ) + + return LaunchDescription([ + use_sim_time_arg, + rviz_config_arg, + elevation_mapping_node, + rviz_node + ]) diff --git a/elevation_mapping_cupy/launch/turtle_simple_example.launch.py b/elevation_mapping_cupy/launch/turtle_simple_example.launch.py new file mode 100644 index 00000000..7af0c641 --- /dev/null +++ b/elevation_mapping_cupy/launch/turtle_simple_example.launch.py @@ -0,0 +1,68 @@ +# elevation_mapping_launch.py + +import os + +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription +from launch.conditions import IfCondition +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch.substitutions import LaunchConfiguration, PathJoinSubstitution, FindExecutable +from launch_ros.actions import Node +from ament_index_python.packages import get_package_share_directory + +def generate_launch_description(): + # Declare the 'rviz_config' launch argument with a default value + rviz_config_arg = DeclareLaunchArgument( + 'rviz_config', + default_value=os.path.join( + get_package_share_directory('elevation_mapping_cupy'), + 'rviz', + 'turtle_example.rviz' + ), + description='Path to the RViz config file' + ) + + # Define the path to the turtlesim_init launch file + turtlesim_init_launch = IncludeLaunchDescription( + PythonLaunchDescriptionSource( + os.path.join( + get_package_share_directory('elevation_mapping_cupy'), + 'launch', + 'turtlesim_init.launch.py' + ) + ), + launch_arguments={ + 'rviz_config': LaunchConfiguration('rviz_config'), + 'use_sim_time': 'true' # Set simulation time to true + }.items() + ) + + # Define the elevation_mapping node + elevation_mapping_node = Node( + package='elevation_mapping_cupy', + executable='elevation_mapping_node', # Ensure this is the correct executable name + name='elevation_mapping', + output='screen', + parameters=[ + os.path.join( + get_package_share_directory('elevation_mapping_cupy'), + 'config', + 'core', + 'core_param.yaml' + ), + os.path.join( + get_package_share_directory('elevation_mapping_cupy'), + 'config', + 'setups', + 'turtle_bot', + 'turtle_bot_simple.yaml' + ) + ] + ) + + # Create and return the LaunchDescription object + return LaunchDescription([ + rviz_config_arg, + turtlesim_init_launch, + # elevation_mapping_node, + ]) diff --git a/elevation_mapping_cupy/launch/turtlesim_init.launch.py b/elevation_mapping_cupy/launch/turtlesim_init.launch.py new file mode 100644 index 00000000..44502cf6 --- /dev/null +++ b/elevation_mapping_cupy/launch/turtlesim_init.launch.py @@ -0,0 +1,185 @@ +# turtlesim_init.launch.py + +import os + +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription, ExecuteProcess +from launch.substitutions import LaunchConfiguration, Command, PathJoinSubstitution, TextSubstitution +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch_ros.actions import Node +from ament_index_python.packages import get_package_share_directory + + +def generate_launch_description(): + # Get the package directories + try: + elevation_mapping_cupy_dir = get_package_share_directory('elevation_mapping_cupy') + gazebo_ros_dir = get_package_share_directory('gazebo_ros') + turtlebot3_gazebo_dir = get_package_share_directory('turtlebot3_gazebo') + turtlebot3_description_dir = get_package_share_directory('turtlebot3_description') + except Exception as e: + print(f"Error getting package directories: {e}") + return LaunchDescription() # Return an empty launch description to prevent further errors + + # Print debug information + print(f"elevation_mapping_cupy_dir: {elevation_mapping_cupy_dir}") + print(f"gazebo_ros_dir: {gazebo_ros_dir}") + print(f"turtlebot3_gazebo_dir: {turtlebot3_gazebo_dir}") + print(f"turtlebot3_description_dir: {turtlebot3_description_dir}") + + # Declare launch arguments + use_sim_time_arg = DeclareLaunchArgument( + 'use_sim_time', + default_value='true', + description='Use simulation (Gazebo) clock if true' + ) + + rviz_config_arg = DeclareLaunchArgument( + 'rviz_config', + default_value=PathJoinSubstitution([ + elevation_mapping_cupy_dir, 'rviz', 'turtle_sim_laser.rviz' + ]), + description='Path to the RViz config file' + ) + + # print rviz config used + print(f"rviz_config: {rviz_config_arg}") + + model_arg = DeclareLaunchArgument( + 'model', + default_value='waffle', + description='Model type [burger, waffle, waffle_pi]' + ) + + x_pos_arg = DeclareLaunchArgument( + 'x_pos', + default_value='0.0', + description='Initial X position of the robot' + ) + + y_pos_arg = DeclareLaunchArgument( + 'y_pos', + default_value='2.0', + description='Initial Y position of the robot' + ) + + z_pos_arg = DeclareLaunchArgument( + 'z_pos', + default_value='0.0', + description='Initial Z position of the robot' + ) + + # Launch configurations + use_sim_time = LaunchConfiguration('use_sim_time') + # rviz_config = LaunchConfiguration('rviz_config') + model = LaunchConfiguration('model') + x_pos = LaunchConfiguration('x_pos') + y_pos = LaunchConfiguration('y_pos') + z_pos = LaunchConfiguration('z_pos') + + # Set the /use_sim_time parameter + use_sim_time_param = Node( + package='rclcpp_components', + executable='parameter_server', + name='use_sim_time_param', + parameters=[{'use_sim_time': use_sim_time}] + ) + + # Include the Gazebo empty world launch file + gazebo_launch = IncludeLaunchDescription( + PythonLaunchDescriptionSource( + PathJoinSubstitution([ + gazebo_ros_dir, 'launch', 'gazebo.launch.py' + ]) + ), + launch_arguments={ + 'world': PathJoinSubstitution([ + turtlebot3_gazebo_dir, 'worlds', 'turtlebot3_world.world' + ]), + 'paused': 'false', + 'use_sim_time': use_sim_time, + 'gui': 'true', + 'headless': 'false', + 'debug': 'false' + }.items() + ) + + # Generate robot_description from urdf + robot_description_content = Command([ + 'cat ', + PathJoinSubstitution([ + turtlebot3_description_dir, 'urdf', 'turtlebot3_waffle_camera.urdf' + ]) + ]) + + robot_description = {'robot_description': robot_description_content} + + # Robot State Publisher + robot_state_publisher_node = Node( + package='robot_state_publisher', + executable='robot_state_publisher', + name='waffle_state_publisher', + output='screen', + parameters=[ + robot_description, + { + 'use_sim_time': use_sim_time, + 'publish_frequency': 50.0 # Set publishing frequency to 50 Hz + } + ] + ) + + # Spawn the TurtleBot3 model in Gazebo + spawn_entity = Node( + package='gazebo_ros', + executable='spawn_entity.py', + arguments=[ + '-entity', PathJoinSubstitution([ + TextSubstitution(text='turtlebot3_'), + model + ]), + '-topic', 'robot_description', + '-x', x_pos, + '-y', y_pos, + '-z', z_pos + ], + output='screen' + ) + + # # RViz Node + # rviz_node = Node( + # package='rviz2', + # executable='rviz2', + # name='rviz2', + # arguments=['-d', rviz_config], + # parameters=[{'use_sim_time': use_sim_time}], + # output='screen' + # ) + + # # Add Joint State Publisher + # joint_state_publisher_node = Node( + # package='joint_state_publisher', + # executable='joint_state_publisher', + # name='joint_state_publisher', + # parameters=[{'use_sim_time': use_sim_time}] + # ) + + # Define LaunchDescription variable + ld = LaunchDescription() + + # Add the declared arguments + # ld.add_action(use_sim_time_arg) + # ld.add_action(rviz_config_arg) + ld.add_action(model_arg) + ld.add_action(x_pos_arg) + ld.add_action(y_pos_arg) + ld.add_action(z_pos_arg) + + # Add actions + ld.add_action(gazebo_launch) + # ld.add_action(joint_state_publisher_node) + ld.add_action(robot_state_publisher_node) + ld.add_action(spawn_entity) + # ld.add_action(rviz_node) + + return ld \ No newline at end of file diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index 74c11f5f..e1bad0c5 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -1,30 +1,47 @@ - elevation_mapping_cupy - 2.0.0 - The elevation mapping on GPU + elevation_mapping_cupy + 2.0.0 + Elevation mapping on GPU + Your Name + MIT - Takahiro Miki + + ament_python + ament_cmake - MIT + + rclpy + std_msgs + sensor_msgs + geometry_msgs + elevation_map_msgs + grid_map_msgs + grid_map_ros + image_transport + pcl_ros + pybind11 + ros2_numpy + tf2_ros + message_filters + cv_bridge + ament_index_python + tf_transformations - - ament_cmake - ament_cmake_python + + rviz2 + gazebo_ros + robot_state_publisher + opencv-python + + + ament_python + ament_python - - rclpy - std_msgs - sensor_msgs - geometry_msgs - elevation_map_msgs - grid_map_msgs - grid_map_ros - image_transport - pcl_ros - pybind11 + + ament_python + - - ament_python - + + https://github.com/yourrepo/elevation_mapping_cupy diff --git a/elevation_mapping_cupy/resource/elevation_mapping_cupy b/elevation_mapping_cupy/resource/elevation_mapping_cupy new file mode 100644 index 00000000..e69de29b diff --git a/elevation_mapping_cupy/setup.cfg b/elevation_mapping_cupy/setup.cfg new file mode 100644 index 00000000..6ded92fd --- /dev/null +++ b/elevation_mapping_cupy/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script_dir=$base/lib/elevation_mapping_cupy +[install] +install_scripts=$base/lib/elevation_mapping_cupy \ No newline at end of file diff --git a/elevation_mapping_cupy/setup.py b/elevation_mapping_cupy/setup.py index 9225d74c..493eef6c 100644 --- a/elevation_mapping_cupy/setup.py +++ b/elevation_mapping_cupy/setup.py @@ -1,4 +1,5 @@ from setuptools import setup, find_packages +from glob import glob import os package_name = 'elevation_mapping_cupy' @@ -21,9 +22,13 @@ 'elevation_mapping_node = elevation_mapping_cupy.elevation_mapping_ros:main', ], }, - # Remove data_files for package.xml data_files=[ - # Add the launch file - (os.path.join('share', package_name, 'launch'), ['launch/elevation_mapping_launch.py']), + (os.path.join('share', package_name, 'launch'), glob('launch/*.launch.py')), + *[(os.path.join('share', package_name, os.path.dirname(yaml_file)), [yaml_file]) for yaml_file in glob('config/**/*.yaml', recursive=True)], + # also the .*dat files + *[(os.path.join('share', package_name, os.path.dirname(dat_file)), [dat_file]) for dat_file in glob('config/**/*.dat', recursive=True)], + # add rviz files + *[(os.path.join('share', package_name, os.path.dirname(rviz_file)), [rviz_file]) for rviz_file in glob('rviz/**/*.rviz', recursive=True)], + (os.path.join('share', package_name), ['package.xml']), ], ) From 94829557f17e7a634af51203ee10e2c36029ac63 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 12:22:28 +0100 Subject: [PATCH 456/504] works without multithreading --- .../elevation_mapping_ros.py | 32 ++++++------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py index 139264dd..10682d58 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py @@ -10,7 +10,6 @@ # ROS 2 imports import rclpy from rclpy.node import Node -from rclpy.callback_groups import ReentrantCallbackGroup from ament_index_python.packages import get_package_share_directory import ros2_numpy as rnp from sensor_msgs.msg import PointCloud2, Image, CameraInfo @@ -54,9 +53,6 @@ def __init__(self): automatically_declare_parameters_from_overrides=True ) - # Create a ReentrantCallbackGroup for subscriptions and timers - self.callback_group = ReentrantCallbackGroup() - # Get package share directory self.root = get_package_share_directory("elevation_mapping_cupy") weight_file = os.path.join(self.root, "config/core/weights.dat") @@ -249,13 +245,12 @@ def register_subscribers(self): history=rclpy.qos.HistoryPolicy.KEEP_LAST ) - # Create subscription with ReentrantCallbackGroup + # Create subscription without passing callback_group subscription = self.create_subscription( PointCloud2, topic_name, partial(self.pointcloud_callback, sub_key=key), - qos_profile, - callback_group=self.callback_group # Assign ReentrantCallbackGroup + qos_profile ) pointcloud_subs[key] = subscription @@ -278,8 +273,7 @@ def register_publishers(self): fps = pub_config.get("fps", 1.0) timer = self.create_timer( 1.0 / fps, - partial(self.publish_map, key=pub_key), - callback_group=self.callback_group # Assign ReentrantCallbackGroup + partial(self.publish_map, key=pub_key) ) self._publishers_timers.append(timer) @@ -290,26 +284,22 @@ def register_timers(self): # Register the combined timer instead self.time_pose_update = self.create_timer( 0.1, - self.pose_update, - callback_group=self.callback_group # Assign ReentrantCallbackGroup + self.pose_update ) - # Register additional timers with the ReentrantCallbackGroup + # Register additional timers without the ReentrantCallbackGroup self.timer_variance = self.create_timer( 1.0 / self.update_variance_fps, - self.update_variance, - callback_group=self.callback_group # Assign ReentrantCallbackGroup + self.update_variance ) self.timer_time = self.create_timer( self.time_interval, - self.update_time, - callback_group=self.callback_group # Assign ReentrantCallbackGroup + self.update_time ) self.get_logger().info("Combined transform and pose updater timer, variance, and time timers registered.") def publish_map(self, key): - self.get_logger().info("publish_map entered") if self._map_q is None: self.get_logger().info("No map pose available for publishing.") return @@ -331,23 +321,20 @@ def publish_map(self, key): for layer in self.my_publishers[key].get("layers", []): gm.layers.append(layer) self._map.get_map_with_name_ref(layer, self._map_data) - arr = Float32MultiArray() arr.layout = MAL() N = self._map_data.shape[0] arr.layout.dim.append(MAD(label="column_index", size=N, stride=int(N * N))) arr.layout.dim.append(MAD(label="row_index", size=N, stride=N)) - # Convert to a Python list to satisfy the message requirements arr.data = self._map_data.T.flatten().tolist() - gm.data.append(arr) + gm.outer_start_index = 0 gm.inner_start_index = 0 self._publishers_dict[key].publish(gm) - def image_callback(self, camera_msg, camera_info_msg, sub_key): # Get pose of image ti = camera_msg.header.stamp @@ -391,7 +378,6 @@ def image_callback(self, camera_msg, camera_info_msg, sub_key): def pointcloud_callback(self, msg, sub_key): - start_time = time.time() self._last_t = msg.header.stamp self._pointcloud_stamp = msg.header.stamp channels = ["x", "y", "z"] + self.param.subscriber_cfg[sub_key].get("channels", []) @@ -524,7 +510,7 @@ def main(args=None): node = ElevationMappingNode() # Initialize a MultiThreadedExecutor instead of SingleThreadedExecutor - executor = rclpy.executors.MultiThreadedExecutor() + executor = rclpy.executors.SingleThreadedExecutor() executor.add_node(node) try: From 16222e037876e285059950681af215a2d6ad6b16 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 14:01:09 +0100 Subject: [PATCH 457/504] removed thread pool --- .../elevation_mapping_ros.py | 31 ++++--------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py index 10682d58..fc6fabff 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py @@ -88,10 +88,6 @@ def __init__(self): self._transform_lock = threading.Lock() self._current_transform = None - # Initialize ThreadPoolExecutor for pointcloud processing - self.thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=2) - self.get_logger().info("ThreadPoolExecutor initialized with 2 workers.") - def initialize_elevation_mapping(self): self.param.update() self._pointcloud_process_counter = 0 @@ -376,7 +372,6 @@ def image_callback(self, camera_msg, camera_info_msg, sub_key): self._image_process_counter += 1 self.get_logger().debug(f"Images processed: {self._image_process_counter}") - def pointcloud_callback(self, msg, sub_key): self._last_t = msg.header.stamp self._pointcloud_stamp = msg.header.stamp @@ -394,36 +389,24 @@ def pointcloud_callback(self, msg, sub_key): frame_sensor_id = msg.header.frame_id try: - # Await the transform lookup transform_sensor_to_odom = self._tf_buffer.lookup_transform( self.map_frame, frame_sensor_id, self._pointcloud_stamp ) - # Process the transform directly here instead of using callback t = transform_sensor_to_odom.transform.translation q = transform_sensor_to_odom.transform.rotation t_np = np.array([t.x, t.y, t.z], dtype=np.float32) R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) - # Submit the processing to the executor - self.thread_pool.submit(self.process_pointcloud, points['xyz'], channels, R, t_np, sub_key) + self._map.input_pointcloud(points['xyz'], channels, R, t_np, 0, 0) + self._pointcloud_process_counter += 1 except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - self.get_logger().warn(f"Transform lookup failed: {e}") - except Exception as e: - self.get_logger().error(f"Unexpected error in pointcloud_callback: {str(e)}") - - def process_pointcloud(self, xyz, channels, R, t_np, sub_key): - try: - callback_start = time.time() - self._map.input_pointcloud(xyz, channels, R, t_np, 0, 0) - self._pointcloud_process_counter += 1 - callback_end = time.time() - self.get_logger().info(f"[process_pointcloud] input_pointcloud execution time: {callback_end - callback_start:.4f} seconds") + self.get_logger().warn(f"[pointcloud_callback] Transform lookup failed: {e}") except Exception as e: - self.get_logger().error(f"Error processing pointcloud in separate thread: {str(e)}") + self.get_logger().error(f"[pointcloud_callback] Unexpected error: {str(e)}") def pose_update(self): if self._last_t is None: @@ -454,9 +437,9 @@ def pose_update(self): self.get_logger().debug("Pose updated.") except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - self.get_logger().warn(f"Transform lookup failed in pose_update: {e}") + self.get_logger().warn(f"[pose_update] Transform lookup failed: {e}") except Exception as e: - self.get_logger().error(f"Unexpected error in pose_update: {str(e)}") + self.get_logger().error(f"[pose_update] Unexpected error: {str(e)}") def update_variance(self): self._map.update_variance() @@ -500,8 +483,6 @@ def print_tf_frames(self): self.get_logger().error(f"Failed to get TF frames: {e}") def destroy_node(self): - self.get_logger().info("Shutting down ThreadPoolExecutor.") - self.thread_pool.shutdown(wait=True) super().destroy_node() From 4f35ca8a50bb8adc5f90d203fc60d123b237dbce Mon Sep 17 00:00:00 2001 From: amilearning Date: Thu, 5 Dec 2024 14:01:59 +0100 Subject: [PATCH 458/504] image subscribe --- .../config/core/core_param.yaml | 43 +-- .../elevation_mapping_ros.hpp | 54 ++-- .../src/elevation_mapping_ros.cpp | 286 +++++++++++------- .../src/elevation_mapping_wrapper.cpp | 2 +- 4 files changed, 235 insertions(+), 150 deletions(-) diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 6facd7d9..3a693641 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -1,7 +1,8 @@ elevation_mapping: ros__parameters: - #### Basic parameters ######## - enable_normal_arrow_publishing: false + #### Basic parameters ######## + voxel_filter_size: 0.05 + enable_normal_arrow_publishing: true cell_n: 40000 # number of cells in the map. data_type: 'float32' # data type for the map. average_weight: 0.5 @@ -11,7 +12,7 @@ elevation_mapping: min_filter_iteration: 3 # number of iterations for min filter. initialized_variance: 10.0 # initial variance for each cell. resolution: 0.1 # resolution in m. - map_length: 20.0 # map's size in m. + map_length: 20.0 # map's size in m. sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). mahalanobis_thresh: 2.0 # points outside this distance is outlier. outlier_variance: 0.01 # if point is outlier, add this value to the cell. @@ -65,7 +66,7 @@ elevation_mapping: enable_pointcloud_publishing: false enable_drift_corrected_TF_publishing: false enable_normal_color: true # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. - enable_normal: true + #### Traversability filter ######## use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. @@ -104,23 +105,29 @@ elevation_mapping: # camera_info_topic_name: '/camera/depth/camera_info' # channel_info_topic_name: '/camera/channel_info' + subscribers: pointcloud1: - # topic_name: '/ouster/points' - topic_name: '/a200/sensors/camera_0/points' + # topic_name: '/ouster/points' + topic_name: '/a200/sensors/camera_0/points' data_type: 'pointcloud' - # image1: + image1: + topic_name: '/feat_processing_node/semantic_seg_feat' + info_name: '/feat_processing_node/a200/sensors/camera_0/color/camera_info_resized' + channel_name: '/feat_processing_node/feat_channel_info' + data_type: 'image' + # image2: # topic_name: '/a200/sensors/camera_0/color/image' # info_name: '/a200/sensors/camera_0/color/camera_info' # data_type: 'image' # channel_name: '/front_cam/channel_info' + # channel_name: '/front_cam/channel_info' + # image_topic2: '/camera/rgb/image_raw2' # image_info2: '/camera/depth/camera_info2' # image_channel_info1: '/front_cam/channel_info' - - # image: # for semantic images # topic_name: '/front_cam/semantic_image' # camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' @@ -135,17 +142,17 @@ elevation_mapping: publishers: elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','normal_x', 'normal_y', 'normal_z'] + layers: ['elevation', 'traversability', 'variance','rgb', 'normal_x', 'normal_y', 'normal_z', 'feat_0','feat_1','feat_2','feat_3','feat_4'] basic_layers: ['elevation'] fps: 5.0 - # elevation_map_recordable: - # layers: ['elevation', 'traversability'] - # basic_layers: ['elevation', 'traversability'] - # fps: 2.0 - # elevation_map_filter: - # layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] - # basic_layers: ['min_filter'] - # fps: 3.0 + elevation_map_recordable: + layers: ['elevation', 'traversability'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + basic_layers: ['min_filter'] + fps: 3.0 # plugun info diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 220509e4..aa843e8f 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -48,6 +48,7 @@ #include #include #include +#include // OpenCV #include @@ -89,23 +90,28 @@ class ElevationMappingNode : public rclcpp::Node { using CameraChannelSyncPtr = std::shared_ptr; // Subscriber and Synchronizer for Pointcloud messages - using PointCloudSubscriber = message_filters::Subscriber; - using PointCloudSubscriberPtr = std::shared_ptr; - using PointCloudPolicy = message_filters::sync_policies::ApproximateTime; - using PointCloudSync = message_filters::Synchronizer; - using PointCloudSyncPtr = std::shared_ptr; + // using PointCloudSubscriber = message_filters::Subscriber; + // using PointCloudSubscriberPtr = std::shared_ptr; + // using PointCloudPolicy = message_filters::sync_policies::ApproximateTime; + // using PointCloudSync = message_filters::Synchronizer; + // using PointCloudSyncPtr = std::shared_ptr; private: - void readParameters(); - void setupMapPublishers(); - void pointcloudCallback(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::string& key); - void inputPointCloud(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::vector& channels); -// void inputImage(const sensor_msgs::ImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg, const std::vector& channels); +void readParameters(); +void setupMapPublishers(); +void pointcloudCallback(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::string& key); +void inputPointCloud(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::vector& channels); + +void inputImage(const sensor_msgs::msg::Image::ConstSharedPtr& image_msg, + const sensor_msgs::msg::CameraInfo::ConstSharedPtr& camera_info_msg, + const std::vector& channels); + + // void imageCallback(const sensor_msgs::msg::Image::SharedPtr image_msg, const sensor_msgs::msg::CameraInfo::SharedPtr camera_info_msg, const std::string& key); // void imageChannelCallback(const sensor_msgs::msg::Image::SharedPtr image_msg, const sensor_msgs::msg::CameraInfo::SharedPtr camera_info_msg, const elevation_map_msgs::msg::ChannelInfo::SharedPtr channel_info_msg); -void imageCallback(const std::shared_ptr& image_msg, const std::shared_ptr& camera_info_msg, const std::string& key); -void imageChannelCallback(const std::shared_ptr& image_msg, const std::shared_ptr& camera_info_msg, const std::shared_ptr& channel_info_msg); - +void imageCallback(const sensor_msgs::msg::Image::SharedPtr cloud, const std::string& key); +void imageChannelCallback(const elevation_map_msgs::msg::ChannelInfo::SharedPtr chennel_info, const std::string& key); +void imageInfoCallback(const sensor_msgs::msg::CameraInfo::SharedPtr image_info, const std::string& key); // void pointCloudChannelCallback(const sensor_msgs::PointCloud2& cloud, const elevation_map_msgs::ChannelInfoConstPtr& channel_info_msg); // // void multiLayerImageCallback(const elevation_map_msgs::MultiLayerImageConstPtr& image_msg, const sensor_msgs::CameraInfoConstPtr& camera_info_msg); void publishAsPointCloud(const grid_map::GridMap& map) const; @@ -139,12 +145,18 @@ visualization_msgs::msg::Marker vectorToArrowMarker(const Eigen::Vector3d& start rclcpp::Node::SharedPtr node_; // image_transport::ImageTransport it_; std::vector::SharedPtr> pointcloudSubs_; - std::vector imageSubs_; - std::vector cameraInfoSubs_; - std::vector channelInfoSubs_; - std::vector cameraSyncs_; - std::vector cameraChannelSyncs_; - std::vector pointCloudSyncs_; + + std::vector::SharedPtr> imageSubs_; + std::vector::SharedPtr> cameraInfoSubs_; + std::vector::SharedPtr> channelInfoSubs_; + + + // std::vector imageSubs_; + // std::vector cameraInfoSubs_; + // std::vector channelInfoSubs_; + // std::vector cameraSyncs_; + // std::vector cameraChannelSyncs_; + // std::vector pointCloudSyncs_; std::vector::SharedPtr> mapPubs_; @@ -206,6 +218,7 @@ visualization_msgs::msg::Marker vectorToArrowMarker(const Eigen::Vector3d& start double positionAlpha_; double orientationAlpha_; + double voxel_filter_size_; double recordableFps_; std::atomic_bool enablePointCloudPublishing_; @@ -215,6 +228,9 @@ visualization_msgs::msg::Marker vectorToArrowMarker(const Eigen::Vector3d& start double initializeTfGridSize_; bool alwaysClearWithInitializer_; std::atomic_int pointCloudProcessCounter_; + + std::map> imageInfoReady_; + std::map> imageChannelReady_; }; } // namespace elevation_mapping_cupy diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 8825b97e..1e3f5505 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -70,6 +70,7 @@ ElevationMappingNode::ElevationMappingNode() this->get_parameter("enable_drift_corrected_TF_publishing", enableDriftCorrectedTFPublishing_); this->get_parameter("use_initializer_at_start", useInitializerAtStart_); this->get_parameter("always_clear_with_initializer", alwaysClearWithInitializer_); + this->get_parameter("voxel_filter_size", voxel_filter_size_); RCLCPP_INFO(this->get_logger(), "initialize_frame_id: %s", initialize_frame_id_.empty() ? "[]" : initialize_frame_id_[0].c_str()); RCLCPP_INFO(this->get_logger(), "initialize_tf_offset: [%f, %f, %f, %f]", initialize_tf_offset_[0], initialize_tf_offset_[1], initialize_tf_offset_[2], initialize_tf_offset_[3]); @@ -132,39 +133,59 @@ ElevationMappingNode::ElevationMappingNode() // } else { // transport_hint = "raw"; // In the default case we assume raw topic // } + + std::string key = sub_name; + - ImageSubscriberPtr image_sub = std::make_shared(this, camera_topic, rmw_qos_profile_sensor_data); - imageSubs_.push_back(image_sub); - - CameraInfoSubscriberPtr cam_info_sub = std::make_shared(this, info_topic, rmw_qos_profile_sensor_data); - cameraInfoSubs_.push_back(cam_info_sub); - - std::string channel_info_topic; - if (this->get_parameter("subscribers." + sub_name + ".channel_name", channel_info_topic)) { - ChannelInfoSubscriberPtr channel_info_sub = std::make_shared(this, channel_info_topic, rmw_qos_profile_sensor_data); - channelInfoSubs_.push_back(channel_info_sub); - CameraChannelSyncPtr sync = std::make_shared(CameraChannelPolicy(10), *image_sub, *cam_info_sub, *channel_info_sub); - sync->registerCallback(std::bind(&ElevationMappingNode::imageChannelCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - cameraChannelSyncs_.push_back(sync); - RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s, Camera info topic: %s, Channel info topic: %s", camera_topic.c_str(), info_topic.c_str(), channel_info_topic.c_str()); - }else{ - std::string key = sub_name; - channels_[key].push_back("rgb"); - // RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s, Camera info topic: %s. Channel info topic: %s", camera_topic.c_str(), info_topic.c_str(), (channel_info_topic.empty() ? ("Not found. Using channels: " + boost::algorithm::join(channels_[key], ", ")).c_str() : channel_info_topic.c_str())); - CameraSyncPtr sync = std::make_shared(CameraPolicy(10), *image_sub, *cam_info_sub); - sync->registerCallback(std::bind(&ElevationMappingNode::imageCallback, this, std::placeholders::_1, std::placeholders::_2, key)); - cameraSyncs_.push_back(sync); - } - }else if(data_type == "pointcloud"){ + sensor_msgs::msg::CameraInfo img_info; + elevation_map_msgs::msg::ChannelInfo channel_info; + imageInfoReady_[key] = std::make_pair(img_info, false); + imageChannelReady_[key] = std::make_pair(channel_info, false); + // Image subscriber init + + rmw_qos_profile_t sensor_qos_profile = rmw_qos_profile_sensor_data; + auto sensor_qos = rclcpp::QoS(rclcpp::QoSInitialization(sensor_qos_profile.history, sensor_qos_profile.depth), sensor_qos_profile); + + auto img_callback = [this, key](const sensor_msgs::msg::Image::SharedPtr msg) { + this->imageCallback(msg, key); + }; + auto img_sub = this->create_subscription(camera_topic, sensor_qos, img_callback); + imageSubs_.push_back(img_sub); + RCLCPP_INFO(this->get_logger(), "Subscribed to Image topic: %s", camera_topic.c_str()); + // Camera Info subscriber init + auto img_info_callback = [this, key](const sensor_msgs::msg::CameraInfo::SharedPtr msg) { + this->imageInfoCallback(msg, key); + }; + auto img_info_sub = this->create_subscription(info_topic, sensor_qos, img_info_callback); + cameraInfoSubs_.push_back(img_info_sub); + RCLCPP_INFO(this->get_logger(), "Subscribed to ImageInfo topic: %s", info_topic.c_str()); + + std::string channel_info_topic; + if (this->get_parameter("subscribers." + sub_name + ".channel_name", channel_info_topic)) { + // channel subscriber init + imageChannelReady_[key].second = false; + auto img_channel_callback = [this, key](const elevation_map_msgs::msg::ChannelInfo::SharedPtr msg) { + this->imageChannelCallback(msg, key); + }; + auto channel_info_sub = this->create_subscription(channel_info_topic, sensor_qos, img_channel_callback); + channelInfoSubs_.push_back(channel_info_sub); + RCLCPP_INFO(this->get_logger(), "Subscribed to ChannelInfo topic: %s", channel_info_topic.c_str()); + }else{ + imageChannelReady_[key].second = true; + channels_[key].push_back("rgb"); + } + }else if(data_type == "pointcloud"){ std::string pointcloud_topic; this->get_parameter("subscribers." + sub_name + ".topic_name", pointcloud_topic); std::string key = sub_name; channels_[key].push_back("x"); channels_[key].push_back("y"); channels_[key].push_back("z"); + rmw_qos_profile_t qos_profile = rmw_qos_profile_default; auto qos = rclcpp::QoS(rclcpp::QoSInitialization(qos_profile.history, qos_profile.depth), qos_profile); + auto callback = [this, key](const sensor_msgs::msg::PointCloud2::SharedPtr msg) { this->pointcloudCallback(msg, key); }; @@ -352,6 +373,29 @@ void ElevationMappingNode::publishMapOfIndex(int index) { mapPubs_[index]->publish(msg); } +void ElevationMappingNode::imageInfoCallback(const sensor_msgs::msg::CameraInfo::SharedPtr image_info, const std::string& key) { +imageInfoReady_[key] = std::make_pair(*image_info, true); + // Find and remove the subscription for this key + auto it = std::find_if(cameraInfoSubs_.begin(), cameraInfoSubs_.end(), + [key](const rclcpp::Subscription::SharedPtr& sub) { + return sub->get_topic_name() == key; + }); + if (it != cameraInfoSubs_.end()) { + cameraInfoSubs_.erase(it); + } + +} + +void ElevationMappingNode::imageChannelCallback(const elevation_map_msgs::msg::ChannelInfo::SharedPtr channel_info, const std::string& key) { +imageChannelReady_[key] = std::make_pair(*channel_info, true); + auto it = std::find_if(channelInfoSubs_.begin(), channelInfoSubs_.end(), + [key](const rclcpp::Subscription::SharedPtr& sub) { + return sub->get_topic_name() == key; + }); + if (it != channelInfoSubs_.end()) { + channelInfoSubs_.erase(it); + } +} void ElevationMappingNode::pointcloudCallback(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::string& key) { // get channels @@ -359,8 +403,8 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::msg::PointCloud std::vector channels; for (size_t it = 0; it < fields.size(); it++) { - auto& field = fields[it]; - channels.push_back(field.name); + auto& field = fields[it]; + channels.push_back(field.name); } inputPointCloud(cloud, channels); @@ -371,9 +415,19 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::msg::PointCloud void ElevationMappingNode::inputPointCloud(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::vector& channels) { auto start = this->now(); - auto* pcl_pc = new pcl::PCLPointCloud2; - pcl::PCLPointCloud2ConstPtr cloudPtr(pcl_pc); - pcl_conversions::toPCL(*cloud, *pcl_pc); + // auto* raw_pcl_pc = new pcl::PCLPointCloud2; + // pcl::PCLPointCloud2ConstPtr cloudPtr(raw_pcl_pc); + pcl::PCLPointCloud2::Ptr raw_pcl_pc(new pcl::PCLPointCloud2()); + pcl_conversions::toPCL(*cloud, *raw_pcl_pc); + + // apply the voxel filtering + pcl::PCLPointCloud2::Ptr pcl_pc (new pcl::PCLPointCloud2()); + pcl::VoxelGrid voxel_filter; + voxel_filter.setInputCloud(raw_pcl_pc); + voxel_filter.setLeafSize(voxel_filter_size_,voxel_filter_size_,voxel_filter_size_); + voxel_filter.filter(*pcl_pc); + + RCLCPP_DEBUG(this->get_logger(), "Voxel grid filtered point cloud from %d points to %d points.", static_cast(raw_pcl_pc->width * raw_pcl_pc->height), static_cast(pcl_pc->width * pcl_pc->height)); // Get channels auto fields = cloud->fields; @@ -427,98 +481,106 @@ void ElevationMappingNode::inputPointCloud(const sensor_msgs::msg::PointCloud2:: -// void ElevationMappingNode::inputImage(const sensor_msgs::ImageConstPtr& image_msg, -// const sensor_msgs::CameraInfoConstPtr& camera_info_msg, -// const std::vector& channels) { -// // Get image -// cv::Mat image = cv_bridge::toCvShare(image_msg, image_msg->encoding)->image; +void ElevationMappingNode::inputImage(const sensor_msgs::msg::Image::ConstSharedPtr& image_msg, + const sensor_msgs::msg::CameraInfo::ConstSharedPtr& camera_info_msg, + const std::vector& channels) { + // Get image + cv::Mat image = cv_bridge::toCvShare(image_msg, image_msg->encoding)->image; -// // Change encoding to RGB/RGBA -// if (image_msg->encoding == "bgr8") { -// cv::cvtColor(image, image, CV_BGR2RGB); -// } else if (image_msg->encoding == "bgra8") { -// cv::cvtColor(image, image, CV_BGRA2RGBA); -// } + // Change encoding to RGB/RGBA + if (image_msg->encoding == "bgr8") { + cv::cvtColor(image, image, CV_BGR2RGB); + } else if (image_msg->encoding == "bgra8") { + cv::cvtColor(image, image, CV_BGRA2RGBA); + } -// // Extract camera matrix -// Eigen::Map> cameraMatrix(&camera_info_msg->K[0]); - -// // Extract distortion coefficients -// Eigen::VectorXd distortionCoeffs; -// if (!camera_info_msg->D.empty()) { -// distortionCoeffs = Eigen::Map(camera_info_msg->D.data(), camera_info_msg->D.size()); -// } else { -// ROS_WARN("Distortion coefficients are empty."); -// distortionCoeffs = Eigen::VectorXd::Zero(5); -// // return; -// } + // Extract camera matrix + Eigen::Map> cameraMatrix(&camera_info_msg->k[0]); -// // distortion model -// std::string distortion_model = camera_info_msg->distortion_model; - -// // Get pose of sensor in map frame -// tf::StampedTransform transformTf; -// std::string sensorFrameId = image_msg->header.frame_id; -// auto timeStamp = image_msg->header.stamp; -// Eigen::Affine3d transformationMapToSensor; -// try { -// transformListener_.waitForTransform(sensorFrameId, mapFrameId_, timeStamp, ros::Duration(1.0)); -// transformListener_.lookupTransform(sensorFrameId, mapFrameId_, timeStamp, transformTf); -// poseTFToEigen(transformTf, transformationMapToSensor); -// } catch (tf::TransformException& ex) { -// ROS_ERROR("%s", ex.what()); -// return; -// } + // Extract distortion coefficients + Eigen::VectorXd distortionCoeffs; + if (!camera_info_msg->d.empty()) { + distortionCoeffs = Eigen::Map(camera_info_msg->d.data(), camera_info_msg->d.size()); + } else { + RCLCPP_WARN(this->get_logger(), "Distortion coefficients are empty."); + distortionCoeffs = Eigen::VectorXd::Zero(5); + // return; + } -// // Transform image to vector of Eigen matrices for easy pybind conversion -// std::vector image_split; -// std::vector multichannel_image; -// cv::split(image, image_split); -// for (auto img : image_split) { -// ColMatrixXf eigen_img; -// cv::cv2eigen(img, eigen_img); -// multichannel_image.push_back(eigen_img); -// } + // distortion model + std::string distortion_model = camera_info_msg->distortion_model; + + // Get pose of sensor in map frame + geometry_msgs::msg::TransformStamped transformStamped; + std::string sensorFrameId = image_msg->header.frame_id; + auto timeStamp = image_msg->header.stamp; + Eigen::Isometry3d transformationMapToSensor; + try { + transformStamped = tfBuffer_->lookupTransform(sensorFrameId, mapFrameId_, tf2::TimePointZero); + transformationMapToSensor = tf2::transformToEigen(transformStamped); + } catch (tf2::TransformException& ex) { + RCLCPP_ERROR(this->get_logger(), "%s", ex.what()); + return; + } -// // Check if the size of multichannel_image and channels and channel_methods matches. "rgb" counts for 3 layers. -// int total_channels = 0; -// for (const auto& channel : channels) { -// if (channel == "rgb") { -// total_channels += 3; -// } else { -// total_channels += 1; -// } -// } -// if (total_channels != multichannel_image.size()) { -// ROS_ERROR("Mismatch in the size of multichannel_image (%d), channels (%d). Please check the input.", multichannel_image.size(), channels.size()); -// ROS_ERROR_STREAM("Current Channels: " << boost::algorithm::join(channels, ", ")); -// return; -// } + // Transform image to vector of Eigen matrices for easy pybind conversion + std::vector image_split; + std::vector multichannel_image; + cv::split(image, image_split); + for (auto img : image_split) { + ColMatrixXf eigen_img; + cv::cv2eigen(img, eigen_img); + multichannel_image.push_back(eigen_img); + } -// // Pass image to pipeline -// map_.input_image(multichannel_image, channels, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, -// distortionCoeffs, distortion_model, image.rows, image.cols); -// } + // Check if the size of multichannel_image and channels and channel_methods matches. "rgb" counts for 3 layers. + int total_channels = 0; + for (const auto& channel : channels) { + if (channel == "rgb") { + total_channels += 3; + } else { + total_channels += 1; + } + } + if (total_channels != multichannel_image.size()) { + RCLCPP_ERROR(this->get_logger(), "Mismatch in the size of multichannel_image (%d), channels (%d). Please check the input.", multichannel_image.size(), channels.size()); + for (const auto& channel : channels) { + RCLCPP_INFO(this->get_logger(), "Channel: %s", channel.c_str()); + } + return; + } -void ElevationMappingNode::imageCallback(const std::shared_ptr& image_msg, - const std::shared_ptr& camera_info_msg, - const std::string& key) { - auto start = this->now(); - // inputImage(image_msg, camera_info_msg, channels_[key]); - RCLCPP_DEBUG(this->get_logger(), "ElevationMap imageCallback processed an image in %f sec.", (this->now() - start).seconds()); - + // Pass image to pipeline + map_->input_image(multichannel_image, channels, transformationMapToSensor.rotation(), transformationMapToSensor.translation(), cameraMatrix, + distortionCoeffs, distortion_model, image.rows, image.cols); } -void ElevationMappingNode::imageChannelCallback(const std::shared_ptr& image_msg, - const std::shared_ptr& camera_info_msg, - const std::shared_ptr& channel_info_msg) { -auto start = this->now(); -// Default channels and fusion methods for image is rgb and image_color -// std::vector channels; -// channels = channel_info_msg->channels; -// inputImage(image_msg, camera_info_msg, channels); -RCLCPP_DEBUG(this->get_logger(), "ElevationMap imageChannelCallback processed an image in %f sec.", (this->now() - start).seconds()); + +void ElevationMappingNode::imageCallback(const sensor_msgs::msg::Image::SharedPtr image_msg, const std::string& key){ + auto start = this->now(); + + if (!imageInfoReady_[key].second){ + RCLCPP_WARN(this->get_logger(), "CameraInfo for key %s is not available yet.", key.c_str()); + return; + } + + + auto camera_info_msg = std::make_shared(imageInfoReady_[key].first); + if (std::find(channels_[key].begin(), channels_[key].end(), "rgb") != channels_[key].end()){ + inputImage(image_msg, camera_info_msg, channels_[key]); + } + else{ + if (!imageChannelReady_[key].second){ + RCLCPP_WARN(this->get_logger(), "ChannelInfo for key %s is not available yet.", key.c_str()); + return; + } + // Default channels and fusion methods for image is rgb and image_color + std::vector channels; + channels = imageChannelReady_[key].first.channels; + inputImage(image_msg, camera_info_msg, channels); + } + RCLCPP_INFO(this->get_logger(), "ElevationMap imageChannelCallback processed an image in %f sec.", (this->now() - start).seconds()); } @@ -778,7 +840,6 @@ void ElevationMappingNode::updateGridMap() { if (enablePointCloudPublishing_) { publishAsPointCloud(gridMap_); } - if (enableNormalArrowPublishing_) { publishNormalAsArrow(gridMap_); } @@ -856,7 +917,8 @@ void ElevationMappingNode::publishNormalAsArrow(const grid_map::GridMap& map) co } markerArray.markers.push_back(vectorToArrowMarker(start, end, i)); } - normalPub_->publish(markerArray); + normalPub_->publish(markerArray); + } diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index 0e9f29c5..a90fae93 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -205,7 +205,7 @@ void ElevationMappingWrapper::setParameters() { map_n_ = py::cast(param_.attr("get_value")("true_cell_n")); - enable_normal_ = node_->get_parameter("enable_normal").as_bool(); + enable_normal_color_ = node_->get_parameter("enable_normal_color").as_bool(); } From fcab35b98f3bf013ed112638099ba4c63e3272a9 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 14:03:03 +0100 Subject: [PATCH 459/504] updated image callback --- .../elevation_mapping_ros.py | 54 ++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py index fc6fabff..82071b81 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py @@ -332,22 +332,11 @@ def publish_map(self, key): self._publishers_dict[key].publish(gm) def image_callback(self, camera_msg, camera_info_msg, sub_key): - # Get pose of image - ti = camera_msg.header.stamp - self._last_t = ti - - # Retrieve the latest transform - transform = self.get_current_transform() - if transform is None: - self.get_logger().warn("No available transform for image_callback.") - return - - t = transform.transform.translation - q = transform.transform.rotation - t_np = np.array([t.x, t.y, t.z]) - R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] - + # Store timestamps + self._last_t = camera_msg.header.stamp + try: + # Convert image using cv_bridge semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") except Exception as e: self.get_logger().error(f"CV Bridge conversion failed: {e}") @@ -359,18 +348,38 @@ def image_callback(self, camera_msg, camera_info_msg, sub_key): else: semantic_img = [semantic_img] + # Get camera parameters K = np.array(camera_info_msg.k, dtype=np.float32).reshape(3, 3) D = np.array(camera_info_msg.d, dtype=np.float32).reshape(-1, 1) if not np.all(D == 0.0): self.get_logger().warn("Camera distortion coefficients are not zero. Undistortion not implemented.") - # Process image - self._map.input_image( - sub_key, semantic_img, R, t_np, K, D, camera_info_msg.height, camera_info_msg.width - ) - self._image_process_counter += 1 - self.get_logger().debug(f"Images processed: {self._image_process_counter}") + # Get transform from camera frame to map frame + try: + transform_camera_to_map = self._tf_buffer.lookup_transform( + self.map_frame, + camera_msg.header.frame_id, + camera_msg.header.stamp + ) + + t = transform_camera_to_map.transform.translation + q = transform_camera_to_map.transform.rotation + t_np = np.array([t.x, t.y, t.z], dtype=np.float32) + R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) + + # Process image + self._map.input_image( + sub_key, semantic_img, R, t_np, K, D, + camera_info_msg.height, camera_info_msg.width + ) + self._image_process_counter += 1 + self.get_logger().debug(f"Images processed: {self._image_process_counter}") + + except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: + self.get_logger().warn(f"[image_callback] Transform lookup failed: {e}") + except Exception as e: + self.get_logger().error(f"[image_callback] Unexpected error: {str(e)}") def pointcloud_callback(self, msg, sub_key): self._last_t = msg.header.stamp @@ -434,8 +443,6 @@ def pose_update(self): self._map_t = t self._map_q = q - self.get_logger().debug("Pose updated.") - except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: self.get_logger().warn(f"[pose_update] Transform lookup failed: {e}") except Exception as e: @@ -449,7 +456,6 @@ def update_time(self): self._map.update_time() self.get_logger().debug("Time updated.") - def get_current_transform(self): """Thread-safe method to retrieve the latest transform.""" with self._transform_lock: From 387a231de1166e8336933b9996db46550c899491 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 17:34:02 +0100 Subject: [PATCH 460/504] updated configs to ros2 --- .../config/core/example_setup.yaml | 104 +++++------ .../config/core/plugin_config.yaml | 76 ++++---- .../setups/anymal/anymal_parameters.yaml | 156 +++++++++-------- .../setups/anymal/anymal_plugin_config.yaml | 54 +++--- .../anymal/anymal_sensor_parameter.yaml | 164 +++++++++--------- .../setups/turtle_bot/plugin_config.yaml | 127 +++++++------- .../turtle_bot_semantics_image.yaml | 80 ++++----- .../turtle_bot_semantics_pointcloud.yaml | 48 ++--- .../setups/turtle_bot/turtle_bot_simple.yaml | 13 +- 9 files changed, 422 insertions(+), 400 deletions(-) diff --git a/elevation_mapping_cupy/config/core/example_setup.yaml b/elevation_mapping_cupy/config/core/example_setup.yaml index a3f7a2f2..c5c4adb5 100644 --- a/elevation_mapping_cupy/config/core/example_setup.yaml +++ b/elevation_mapping_cupy/config/core/example_setup.yaml @@ -1,58 +1,60 @@ -#### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/core/plugin_config.yaml' +/elevation_mapping_node: + ros__parameters: + #### Plugins ######## + plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/core/plugin_config.yaml' -#### Channel Fusions ######## -pointcloud_channel_fusions: - rgb: 'color' # 'color' fusion is used for the 'rgb' channel - default: 'average' # 'average' fusion is used for channels not listed here + #### Channel Fusions ######## + pointcloud_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'average' # 'average' fusion is used for channels not listed here -image_channel_fusions: - rgb: 'color' # 'color' fusion is used for the 'rgb' channel - default: 'exponential' # 'exponential' fusion is used for channels not listed here - feat_.*: 'exponential' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names + image_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'exponential' # 'exponential' fusion is used for channels not listed here + feat_.*: 'exponential' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names -#### Subscribers ######## -# pointcloud_sensor_name: -# topic_name: '/sensor/pointcloud_semantic' -# data_type: pointcloud # pointcloud or image -# -# image_sensor_name: -# topic_name: '/camera/image_semantic' -# data_type: image # pointcloud or image -# camera_info_topic_name: '/camera/depth/camera_info' -# channel_info_topic_name: '/camera/channel_info' + #### Subscribers ######## + # pointcloud_sensor_name: + # topic_name: '/sensor/pointcloud_semantic' + # data_type: pointcloud # pointcloud or image + # + # image_sensor_name: + # topic_name: '/camera/image_semantic' + # data_type: image # pointcloud or image + # camera_info_topic_name: '/camera/depth/camera_info' + # channel_info_topic_name: '/camera/channel_info' -subscribers: - front_cam: - topic_name: '/camera/depth/points' - data_type: pointcloud - color_cam: # for color camera - topic_name: '/camera/rgb/image_raw' - camera_info_topic_name: '/camera/depth/camera_info' - data_type: image - semantic_cam: # for semantic images - topic_name: '/front_cam/semantic_image' - camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' - channel_info_topic_name: '/front_cam/channel_info' - data_type: image + subscribers: + front_cam: + topic_name: '/camera/depth/points' + data_type: pointcloud + color_cam: # for color camera + topic_name: '/camera/rgb/image_raw' + camera_info_topic_name: '/camera/depth/camera_info' + data_type: image + semantic_cam: # for semantic images + topic_name: '/front_cam/semantic_image' + camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' + channel_info_topic_name: '/front_cam/channel_info' + data_type: image -#### Publishers ######## -# topic_name: -# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names -# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. -# fps: # Publish rate. Use smaller value than `map_acquire_fps`. + #### Publishers ######## + # topic_name: + # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names + # basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. + # fps: # Publish rate. Use smaller value than `map_acquire_fps`. -publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb'] - basic_layers: ['elevation'] - fps: 5.0 - elevation_map_recordable: - layers: ['elevation', 'traversability'] - basic_layers: ['elevation', 'traversability'] - fps: 2.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] - basic_layers: ['min_filter'] - fps: 3.0 \ No newline at end of file + publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_recordable: + layers: ['elevation', 'traversability'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + basic_layers: ['min_filter'] + fps: 3.0 \ No newline at end of file diff --git a/elevation_mapping_cupy/config/core/plugin_config.yaml b/elevation_mapping_cupy/config/core/plugin_config.yaml index efb29b27..b0c622fa 100644 --- a/elevation_mapping_cupy/config/core/plugin_config.yaml +++ b/elevation_mapping_cupy/config/core/plugin_config.yaml @@ -1,38 +1,40 @@ -# Settings of the plugins. (The plugins should be stored in script/plugins) +/elevation_mapping_node: + ros__parameters: + # Settings of the plugins. (The plugins should be stored in script/plugins) -# min_filter fills in minimum value around the invalid cell. -min_filter: - enable: True # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - dilation_size: 1 # The patch size to apply - iteration_n: 30 # The number of iterations -# Apply smoothing. -smooth_filter: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth" - extra_params: - input_layer_name: "min_filter" -# Apply inpainting using opencv -inpainting: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "inpaint" - extra_params: - method: "telea" # telea or ns -# Apply smoothing for inpainted layer -erosion: - enable: True - fill_nan: False - is_height_layer: False - layer_name: "erosion" - extra_params: - input_layer_name: "traversability" - dilation_size: 3 - iteration_n: 20 - reverse: True \ No newline at end of file + # min_filter fills in minimum value around the invalid cell. + min_filter: + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations + # Apply smoothing. + smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" + # Apply inpainting using opencv + inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns + # Apply smoothing for inpainted layer + erosion: + enable: True + fill_nan: False + is_height_layer: False + layer_name: "erosion" + extra_params: + input_layer_name: "traversability" + dilation_size: 3 + iteration_n: 20 + reverse: True \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml index 4a2ed7f4..623ec6a6 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml @@ -1,89 +1,91 @@ -#### Basic parameters ######## -resolution: 0.04 # resolution in m. -map_length: 8 # map's size in m. -sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). -mahalanobis_thresh: 2.0 # points outside this distance is outlier. -outlier_variance: 0.01 # if point is outlier, add this value to the cell. -drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. -max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) -drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation -time_variance: 0.0001 # add this value when update_variance is called. -max_variance: 100.0 # maximum variance for each cell. -initial_variance: 1000.0 # initial variance for each cell. -traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. -dilation_size: 3 # dilation filter size before traversability filter. -wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. -min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. -position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. -orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. -position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. -min_valid_distance: 0.5 # points with shorter distance will be filtered out. -max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. -ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. -update_variance_fps: 5.0 # fps for updating variance. -update_pose_fps: 10.0 # fps for updating pose and shift the center of map. -time_interval: 0.1 # Time layer is updated with this interval. -map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. -publish_statistics_fps: 1.0 # Publish statistics topic in this fps. +/elevation_mapping_node: + ros__parameters: + #### Basic parameters ######## + resolution: 0.04 # resolution in m. + map_length: 8 # map's size in m. + sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). + mahalanobis_thresh: 2.0 # points outside this distance is outlier. + outlier_variance: 0.01 # if point is outlier, add this value to the cell. + drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. + max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) + drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation + time_variance: 0.0001 # add this value when update_variance is called. + max_variance: 100.0 # maximum variance for each cell. + initial_variance: 1000.0 # initial variance for each cell. + traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. + dilation_size: 3 # dilation filter size before traversability filter. + wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. + min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. + position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. + orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. + position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. + orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. + min_valid_distance: 0.5 # points with shorter distance will be filtered out. + max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. + ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + update_variance_fps: 5.0 # fps for updating variance. + update_pose_fps: 10.0 # fps for updating pose and shift the center of map. + time_interval: 0.1 # Time layer is updated with this interval. + map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. + publish_statistics_fps: 1.0 # Publish statistics topic in this fps. -max_ray_length: 10.0 # maximum length for ray tracing. -cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. -cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + max_ray_length: 10.0 # maximum length for ray tracing. + cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. -safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. -safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. -max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. + safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. + max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. -overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) -overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) + overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) -map_frame: 'odom' # The map frame where the odometry source uses. -base_frame: 'base' # The robot's base frame. This frame will be a center of the map. -corrected_map_frame: 'odom_corrected' + map_frame: 'odom' # The map frame where the odometry source uses. + base_frame: 'base' # The robot's base frame. This frame will be a center of the map. + corrected_map_frame: 'odom_corrected' -#### Feature toggles ######## -enable_edge_sharpen: true -enable_visibility_cleanup: true -enable_drift_compensation: true -enable_overlap_clearance: true -enable_pointcloud_publishing: false -enable_drift_corrected_TF_publishing: false -enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + #### Feature toggles ######## + enable_edge_sharpen: true + enable_visibility_cleanup: true + enable_drift_compensation: true + enable_overlap_clearance: true + enable_pointcloud_publishing: false + enable_drift_corrected_TF_publishing: false + enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. -#### Traversability filter ######## -use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. -weight_file: '$(rospack find elevation_mapping_cupy)/config/core/weights.dat' # Weight file for traversability filter + #### Traversability filter ######## + use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. + weight_file: '$(rospack find elevation_mapping_cupy)/config/core/weights.dat' # Weight file for traversability filter -#### Upper bound ######## -use_only_above_for_upper_bound: false + #### Upper bound ######## + use_only_above_for_upper_bound: false -#### Plugins ######## -# plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin_config.yaml' + #### Plugins ######## + # plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/anymal_plugin_config.yaml' -#### Publishers ######## -# topic_name: -# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names -# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. -# fps: # Publish rate. Use smaller value than `map_acquire_fps`. + #### Publishers ######## + # topic_name: + # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names + # basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. + # fps: # Publish rate. Use smaller value than `map_acquire_fps`. -# publishers: -# elevation_map_raw: -# layers: ['elevation', 'traversability', 'variance'] -# basic_layers: ['elevation', 'traversability'] -# fps: 5.0 + # publishers: + # elevation_map_raw: + # layers: ['elevation', 'traversability', 'variance'] + # basic_layers: ['elevation', 'traversability'] + # fps: 5.0 -# semantic_map_raw: -# layers: ['elevation', 'traversability'] -# basic_layers: ['elevation', 'traversability'] -# fps: 5.0 + # semantic_map_raw: + # layers: ['elevation', 'traversability'] + # basic_layers: ['elevation', 'traversability'] + # fps: 5.0 -#### Initializer ######## -initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' -initialize_frame_id: ['RF_FOOT', 'LF_FOOT', 'RH_FOOT', 'LH_FOOT'] # One tf (like ['footprint'] ) initializes a square around it. -initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. -dilation_size_initialize: 5 # dilation size after the init. -initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. -use_initializer_at_start: true # Use initializer when the node starts. \ No newline at end of file + #### Initializer ######## + initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' + initialize_frame_id: ['RF_FOOT', 'LF_FOOT', 'RH_FOOT', 'LH_FOOT'] # One tf (like ['footprint'] ) initializes a square around it. + initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. + dilation_size_initialize: 5 # dilation size after the init. + initialize_tf_grid_size: 0.4 # This is not used if number of tf is more than 3. + use_initializer_at_start: true # Use initializer when the node starts. \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_plugin_config.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_plugin_config.yaml index d5da9e67..5ffd1006 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_plugin_config.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_plugin_config.yaml @@ -1,28 +1,30 @@ -# Settings of the plugins. (The plugins should be stored in script/plugins) -# min_filter fills in minimum value around the invalid cell. -min_filter: - enable: True # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - dilation_size: 1 # The patch size to apply - iteration_n: 30 # The number of iterations +/elevation_mapping_node: + ros__parameters: + # Settings of the plugins. (The plugins should be stored in script/plugins) + # min_filter fills in minimum value around the invalid cell. + min_filter: + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations -# Apply smoothing. -smooth_filter: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth" - extra_params: - input_layer_name: "min_filter" + # Apply smoothing. + smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" -# Apply inpainting using opencv -inpainting: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "inpaint" - extra_params: - method: "telea" # telea or ns + # Apply inpainting using opencv + inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml index fff72063..f68e5864 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_sensor_parameter.yaml @@ -1,81 +1,83 @@ -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/anymal/anymal_plugin_config.yaml' - -pointcloud_channel_fusions: - rgb: 'color' - default: 'average' - -image_channel_fusions: - rgb: 'color' - default: 'exponential' - feat_.*: 'exponential' - sem_.*: 'exponential' - -#### Publishers ######## -# topic_name: -# layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names -# basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. -# fps: # Publish rate. Use smaller value than `map_acquire_fps`. - -publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance', 'rgb', 'upper_bound'] - basic_layers: ['elevation', 'traversability'] - fps: 5.0 - - elevation_map_recordable: - layers: ['elevation', 'traversability', 'variance', 'rgb'] - basic_layers: ['elevation', 'traversability'] - fps: 2.0 - - filtered_elevation_map: - layers: ['inpaint', 'smooth', 'min_filter', 'upper_bound'] - basic_layers: ['inpaint'] - fps: 5.0 - -#### Subscribers ######## -subscribers: - front_upper_depth: - topic_name: /depth_camera_front_upper/point_cloud_self_filtered - data_type: pointcloud - - front_lower_depth: - topic_name: /depth_camera_front_lower/point_cloud_self_filtered - data_type: pointcloud - - rear_upper_depth: - topic_name: /depth_camera_rear_upper/point_cloud_self_filtered - data_type: pointcloud - - rear_lower_depth: - topic_name: /depth_camera_rear_lower/point_cloud_self_filtered - data_type: pointcloud - - left_depth: - topic_name: /depth_camera_left/point_cloud_self_filtered - data_type: pointcloud - - right_depth: - topic_name: /depth_camera_right/point_cloud_self_filtered - data_type: pointcloud - - front_wide_angle: - topic_name: /wide_angle_camera_front/image_color_rect/compressed - camera_info_topic_name: /wide_angle_camera_front/camera_info - data_type: image - - rear_wide_angle: - topic_name: /wide_angle_camera_rear/image_color_rect/compressed - camera_info_topic_name: /wide_angle_camera_rear/camera_info - data_type: image - - velodyne: - topic_name: /point_cloud_filter/lidar/point_cloud_filtered - data_type: pointcloud - - front_bpearl: - topic_name: /robot_self_filter/bpearl_front/point_cloud - data_type: pointcloud - - rear_bpearl: - topic_name: /robot_self_filter/bpearl_rear/point_cloud - data_type: pointcloud \ No newline at end of file +/elevation_mapping_node: + ros__parameters: + plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/anymal/anymal_plugin_config.yaml' + + pointcloud_channel_fusions: + rgb: 'color' + default: 'average' + + image_channel_fusions: + rgb: 'color' + default: 'exponential' + feat_.*: 'exponential' + sem_.*: 'exponential' + + #### Publishers ######## + # topic_name: + # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names + # basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. + # fps: # Publish rate. Use smaller value than `map_acquire_fps`. + + publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance', 'rgb', 'upper_bound'] + basic_layers: ['elevation', 'traversability'] + fps: 5.0 + + elevation_map_recordable: + layers: ['elevation', 'traversability', 'variance', 'rgb'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + + filtered_elevation_map: + layers: ['inpaint', 'smooth', 'min_filter', 'upper_bound'] + basic_layers: ['inpaint'] + fps: 5.0 + + #### Subscribers ######## + subscribers: + front_upper_depth: + topic_name: /depth_camera_front_upper/point_cloud_self_filtered + data_type: pointcloud + + front_lower_depth: + topic_name: /depth_camera_front_lower/point_cloud_self_filtered + data_type: pointcloud + + rear_upper_depth: + topic_name: /depth_camera_rear_upper/point_cloud_self_filtered + data_type: pointcloud + + rear_lower_depth: + topic_name: /depth_camera_rear_lower/point_cloud_self_filtered + data_type: pointcloud + + left_depth: + topic_name: /depth_camera_left/point_cloud_self_filtered + data_type: pointcloud + + right_depth: + topic_name: /depth_camera_right/point_cloud_self_filtered + data_type: pointcloud + + front_wide_angle: + topic_name: /wide_angle_camera_front/image_color_rect/compressed + camera_info_topic_name: /wide_angle_camera_front/camera_info + data_type: image + + rear_wide_angle: + topic_name: /wide_angle_camera_rear/image_color_rect/compressed + camera_info_topic_name: /wide_angle_camera_rear/camera_info + data_type: image + + velodyne: + topic_name: /point_cloud_filter/lidar/point_cloud_filtered + data_type: pointcloud + + front_bpearl: + topic_name: /robot_self_filter/bpearl_front/point_cloud + data_type: pointcloud + + rear_bpearl: + topic_name: /robot_self_filter/bpearl_rear/point_cloud + data_type: pointcloud \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/plugin_config.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/plugin_config.yaml index fd745524..43c7b44e 100644 --- a/elevation_mapping_cupy/config/setups/turtle_bot/plugin_config.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/plugin_config.yaml @@ -1,67 +1,68 @@ -# Settings of the plugins. (The plugins should be stored in script/plugins) +/elevation_mapping_node: + ros__parameters: + # Settings of the plugins. (The plugins should be stored in script/plugins) + # min_filter fills in minimum value around the invalid cell. + min_filter: + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations + # Apply smoothing. + smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" + # Apply inpainting using opencv + inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns + # Apply smoothing for inpainted layer -# min_filter fills in minimum value around the invalid cell. -min_filter: - enable: True # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - dilation_size: 1 # The patch size to apply - iteration_n: 30 # The number of iterations -# Apply smoothing. -smooth_filter: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth" - extra_params: - input_layer_name: "min_filter" -# Apply inpainting using opencv -inpainting: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "inpaint" - extra_params: - method: "telea" # telea or ns -# Apply smoothing for inpainted layer + robot_centric_elevation: # Use the same name as your file name. + enable: False # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "robot_centric_elevation" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + resolution: 0.04 + threshold: 1.1 + use_threshold: True -robot_centric_elevation: # Use the same name as your file name. - enable: False # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "robot_centric_elevation" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - resolution: 0.04 - threshold: 1.1 - use_threshold: True + semantic_filter: + type: "semantic_filter" + enable: True + fill_nan: False + is_height_layer: False + layer_name: "max_categories" + extra_params: + classes: ['^sem_.*$'] -semantic_filter: - type: "semantic_filter" - enable: True - fill_nan: False - is_height_layer: False - layer_name: "max_categories" - extra_params: - classes: ['^sem_.*$'] + semantic_traversability: + type: "semantic_traversability" + enable: False + fill_nan: False + is_height_layer: False + layer_name: "semantic_traversability" + extra_params: + layers: ['traversability','robot_centric_elevation'] + thresholds: [0.3,0.5] + type: ['traversability', 'elevation'] -semantic_traversability: - type: "semantic_traversability" - enable: False - fill_nan: False - is_height_layer: False - layer_name: "semantic_traversability" - extra_params: - layers: ['traversability','robot_centric_elevation'] - thresholds: [0.3,0.5] - type: ['traversability', 'elevation'] - -features_pca: - type: "features_pca" - enable: True - fill_nan: False - is_height_layer: False - layer_name: "pca" - extra_params: - process_layer_names: ["^feat_.*$"] \ No newline at end of file + features_pca: + type: "features_pca" + enable: True + fill_nan: False + is_height_layer: False + layer_name: "pca" + extra_params: + process_layer_names: ["^feat_.*$"] \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_image.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_image.yaml index 0fd7d215..926c5fa9 100644 --- a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_image.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_image.yaml @@ -1,44 +1,46 @@ -#### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/turtle_bot/plugin_config.yaml' +/elevation_mapping_node: + ros__parameters: + #### Plugins ######## + plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/turtle_bot/plugin_config.yaml' -pointcloud_channel_fusions: - none: 'none' - # rgb: 'color' - # default: 'average' + pointcloud_channel_fusions: + none: 'none' + # rgb: 'color' + # default: 'average' -image_channel_fusions: - rgb: 'color' - default: 'exponential' - feat_.*: 'exponential' + image_channel_fusions: + rgb: 'color' + default: 'exponential' + feat_.*: 'exponential' -#### Subscribers ######## -subscribers: - color_cam: # for color camera - topic_name: '/camera/rgb/image_raw' - camera_info_topic_name: '/camera/depth/camera_info' - data_type: image - semantic_cam: # for semantic images - topic_name: '/front_cam/semantic_image' - camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' - channel_info_topic_name: '/front_cam/channel_info' - data_type: image - front_cam_pointcloud: - topic_name: '/camera/depth/points' - data_type: pointcloud - feat_front: - topic_name: '/front_cam/semantic_seg_feat' - camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' - channel_info_topic_name: '/front_cam/feat_channel_info' - data_type: image + #### Subscribers ######## + subscribers: + color_cam: # for color camera + topic_name: '/camera/rgb/image_raw' + camera_info_topic_name: '/camera/depth/camera_info' + data_type: image + semantic_cam: # for semantic images + topic_name: '/front_cam/semantic_image' + camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' + channel_info_topic_name: '/front_cam/channel_info' + data_type: image + front_cam_pointcloud: + topic_name: '/camera/depth/points' + data_type: pointcloud + feat_front: + topic_name: '/front_cam/semantic_seg_feat' + camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' + channel_info_topic_name: '/front_cam/feat_channel_info' + data_type: image -#### Publishers ######## -publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb','max_categories', 'pca'] - basic_layers: ['elevation'] - fps: 5.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','max_categories'] - basic_layers: ['min_filter'] - fps: 3.0 \ No newline at end of file + #### Publishers ######## + publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb','max_categories', 'pca'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','max_categories'] + basic_layers: ['min_filter'] + fps: 3.0 \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_pointcloud.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_pointcloud.yaml index 19db1159..ab84f7b3 100644 --- a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_pointcloud.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_semantics_pointcloud.yaml @@ -1,28 +1,30 @@ -#### Plugins ######## -plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/turtle_bot/plugin_config.yaml' +/elevation_mapping_node: + ros__parameters: + #### Plugins ######## + plugin_config_file: '$(rospack find elevation_mapping_cupy)/config/setups/turtle_bot/plugin_config.yaml' -pointcloud_channel_fusions: - rgb: 'color' - default: 'average' + pointcloud_channel_fusions: + rgb: 'color' + default: 'average' -image_channel_fusions: - rgb: 'color' - default: 'exponential' + image_channel_fusions: + rgb: 'color' + default: 'exponential' -#### Subscribers ######## -subscribers: - front_cam_pointcloud: - topic_name: '/camera/depth/points' - data_type: pointcloud + #### Subscribers ######## + subscribers: + front_cam_pointcloud: + topic_name: '/camera/depth/points' + data_type: pointcloud -#### Publishers ######## -publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb','max_categories'] - basic_layers: ['elevation'] - fps: 5.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','max_categories'] - basic_layers: ['min_filter'] - fps: 3.0 \ No newline at end of file + #### Publishers ######## + publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb','max_categories'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation','rgb','max_categories'] + basic_layers: ['min_filter'] + fps: 3.0 \ No newline at end of file diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml index 0a38bfff..637a99ae 100644 --- a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml @@ -3,16 +3,23 @@ pointcloud_channel_fusions: rgb: 'color' default: 'average' + image_channel_fusions: rgb: 'color' default: 'exponential' feat_.*: 'exponential' + subscribers: front_cam: topic_name: '/intel_realsense_r200_depth/points' - data_type: 'pointcloud' + data_type: pointcloud + publishers: elevation_map_raw: - layers: ['elevation'] + layers: ['elevation', 'traversability', 'variance','rgb'] basic_layers: ['elevation'] - fps: 5.0 \ No newline at end of file + fps: 5.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + basic_layers: ['min_filter'] + fps: 3.0 \ No newline at end of file From 5ae90bbdcdd516534612fee9b67b7a1bd59451be Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 17:34:14 +0100 Subject: [PATCH 461/504] added ros2 launch files --- .../launch/anymal.launch.py | 34 ++++++++++ .../launch/elevation_mapping_cupy.launch.py | 32 +++++++++ .../launch/turtle_simple_example.launch.py | 68 ------------------- .../launch/turtlesim_init.launch | 30 -------- .../launch/turtlesim_init.launch.py | 18 ----- ...esim_plane_decomposition_example.launch.py | 41 +++++++++++ ...turtlesim_semantic_image_example.launch.py | 68 +++++++++++++++++++ ...rtlesim_semantic_pointcloud_example.launch | 4 -- ...esim_semantic_pointcloud_example.launch.py | 68 +++++++++++++++++++ .../launch/turtlesim_simple_example.launch | 15 ---- 10 files changed, 243 insertions(+), 135 deletions(-) create mode 100644 elevation_mapping_cupy/launch/anymal.launch.py create mode 100644 elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py delete mode 100644 elevation_mapping_cupy/launch/turtle_simple_example.launch.py delete mode 100644 elevation_mapping_cupy/launch/turtlesim_init.launch create mode 100644 elevation_mapping_cupy/launch/turtlesim_plane_decomposition_example.launch.py create mode 100644 elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch.py create mode 100644 elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch.py delete mode 100644 elevation_mapping_cupy/launch/turtlesim_simple_example.launch diff --git a/elevation_mapping_cupy/launch/anymal.launch.py b/elevation_mapping_cupy/launch/anymal.launch.py new file mode 100644 index 00000000..5f3ea731 --- /dev/null +++ b/elevation_mapping_cupy/launch/anymal.launch.py @@ -0,0 +1,34 @@ +from launch import LaunchDescription +from launch_ros.actions import Node +from launch.substitutions import PathJoinSubstitution +from ament_index_python.packages import get_package_share_directory + + +def generate_launch_description(): + elevation_mapping_cupy_dir = get_package_share_directory('elevation_mapping_cupy') + + return LaunchDescription([ + # Elevation Mapping Node + Node( + package='elevation_mapping_cupy', + executable='elevation_mapping_node', + name='elevation_mapping', + parameters=[ + PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'config', + 'setups', + 'anymal', + 'anymal_parameters.yaml' + ]), + PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'config', + 'setups', + 'anymal', + 'anymal_sensor_parameter.yaml' + ]) + ], + output='screen' + ) + ]) \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py new file mode 100644 index 00000000..9a979b45 --- /dev/null +++ b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py @@ -0,0 +1,32 @@ +from launch import LaunchDescription +from launch_ros.actions import Node +from launch.substitutions import PathJoinSubstitution +from ament_index_python.packages import get_package_share_directory + + +def generate_launch_description(): + elevation_mapping_cupy_dir = get_package_share_directory('elevation_mapping_cupy') + + return LaunchDescription([ + # Elevation Mapping Node + Node( + package='elevation_mapping_cupy', + executable='elevation_mapping_node', + name='elevation_mapping', + parameters=[ + PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'config', + 'core', + 'core_param.yaml' + ]), + PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'config', + 'core', + 'example_setup.yaml' + ]) + ], + output='screen' + ) + ]) \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtle_simple_example.launch.py b/elevation_mapping_cupy/launch/turtle_simple_example.launch.py deleted file mode 100644 index 7af0c641..00000000 --- a/elevation_mapping_cupy/launch/turtle_simple_example.launch.py +++ /dev/null @@ -1,68 +0,0 @@ -# elevation_mapping_launch.py - -import os - -from launch import LaunchDescription -from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription -from launch.conditions import IfCondition -from launch.launch_description_sources import PythonLaunchDescriptionSource -from launch.substitutions import LaunchConfiguration, PathJoinSubstitution, FindExecutable -from launch_ros.actions import Node -from ament_index_python.packages import get_package_share_directory - -def generate_launch_description(): - # Declare the 'rviz_config' launch argument with a default value - rviz_config_arg = DeclareLaunchArgument( - 'rviz_config', - default_value=os.path.join( - get_package_share_directory('elevation_mapping_cupy'), - 'rviz', - 'turtle_example.rviz' - ), - description='Path to the RViz config file' - ) - - # Define the path to the turtlesim_init launch file - turtlesim_init_launch = IncludeLaunchDescription( - PythonLaunchDescriptionSource( - os.path.join( - get_package_share_directory('elevation_mapping_cupy'), - 'launch', - 'turtlesim_init.launch.py' - ) - ), - launch_arguments={ - 'rviz_config': LaunchConfiguration('rviz_config'), - 'use_sim_time': 'true' # Set simulation time to true - }.items() - ) - - # Define the elevation_mapping node - elevation_mapping_node = Node( - package='elevation_mapping_cupy', - executable='elevation_mapping_node', # Ensure this is the correct executable name - name='elevation_mapping', - output='screen', - parameters=[ - os.path.join( - get_package_share_directory('elevation_mapping_cupy'), - 'config', - 'core', - 'core_param.yaml' - ), - os.path.join( - get_package_share_directory('elevation_mapping_cupy'), - 'config', - 'setups', - 'turtle_bot', - 'turtle_bot_simple.yaml' - ) - ] - ) - - # Create and return the LaunchDescription object - return LaunchDescription([ - rviz_config_arg, - turtlesim_init_launch, - # elevation_mapping_node, - ]) diff --git a/elevation_mapping_cupy/launch/turtlesim_init.launch b/elevation_mapping_cupy/launch/turtlesim_init.launch deleted file mode 100644 index 7bd323a9..00000000 --- a/elevation_mapping_cupy/launch/turtlesim_init.launch +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/elevation_mapping_cupy/launch/turtlesim_init.launch.py b/elevation_mapping_cupy/launch/turtlesim_init.launch.py index 44502cf6..660f5410 100644 --- a/elevation_mapping_cupy/launch/turtlesim_init.launch.py +++ b/elevation_mapping_cupy/launch/turtlesim_init.launch.py @@ -146,24 +146,6 @@ def generate_launch_description(): output='screen' ) - # # RViz Node - # rviz_node = Node( - # package='rviz2', - # executable='rviz2', - # name='rviz2', - # arguments=['-d', rviz_config], - # parameters=[{'use_sim_time': use_sim_time}], - # output='screen' - # ) - - # # Add Joint State Publisher - # joint_state_publisher_node = Node( - # package='joint_state_publisher', - # executable='joint_state_publisher', - # name='joint_state_publisher', - # parameters=[{'use_sim_time': use_sim_time}] - # ) - # Define LaunchDescription variable ld = LaunchDescription() diff --git a/elevation_mapping_cupy/launch/turtlesim_plane_decomposition_example.launch.py b/elevation_mapping_cupy/launch/turtlesim_plane_decomposition_example.launch.py new file mode 100644 index 00000000..b1e8a178 --- /dev/null +++ b/elevation_mapping_cupy/launch/turtlesim_plane_decomposition_example.launch.py @@ -0,0 +1,41 @@ +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch.substitutions import PathJoinSubstitution +from ament_index_python.packages import get_package_share_directory + + +def generate_launch_description(): + elevation_mapping_cupy_dir = get_package_share_directory('elevation_mapping_cupy') + convex_plane_decomposition_dir = get_package_share_directory('convex_plane_decomposition_ros') + + return LaunchDescription([ + # Launch elevation mapping turtle sim + IncludeLaunchDescription( + PythonLaunchDescriptionSource( + PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'launch', + 'turtlesim_simple_example.launch.py' + ]) + ), + launch_arguments={ + 'rviz_config': PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'rviz', + 'turtle_segmentation_example.rviz' + ]) + }.items() + ), + + # Launch the plane decomposition node + IncludeLaunchDescription( + PythonLaunchDescriptionSource( + PathJoinSubstitution([ + convex_plane_decomposition_dir, + 'launch', + 'convex_plane_decomposition.launch.py' + ]) + ) + ) + ]) \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch.py b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch.py new file mode 100644 index 00000000..bcd2440e --- /dev/null +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_image_example.launch.py @@ -0,0 +1,68 @@ +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch_ros.actions import Node +from launch.substitutions import PathJoinSubstitution +from ament_index_python.packages import get_package_share_directory + + +def generate_launch_description(): + elevation_mapping_cupy_dir = get_package_share_directory('elevation_mapping_cupy') + semantic_sensor_dir = get_package_share_directory('semantic_sensor') + + return LaunchDescription([ + # Include the turtlesim_init launch file + IncludeLaunchDescription( + PythonLaunchDescriptionSource( + PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'launch', + 'turtlesim_init.launch.py' + ]) + ), + launch_arguments={ + 'rviz_config': PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'rviz', + 'turtle_example.rviz' + ]) + }.items() + ), + + # Semantic Sensor Image Node + Node( + package='semantic_sensor', + executable='image_node.py', + name='front_cam', + arguments=['front_cam_image'], + parameters=[PathJoinSubstitution([ + semantic_sensor_dir, + 'config', + 'sensor_parameter.yaml' + ])], + output='screen' + ), + + # Elevation Mapping Node + Node( + package='elevation_mapping_cupy', + executable='elevation_mapping_node', + name='elevation_mapping', + parameters=[ + PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'config', + 'core', + 'core_param.yaml' + ]), + PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'config', + 'setups', + 'turtle_bot', + 'turtle_bot_semantics_image.yaml' + ]) + ], + output='screen' + ) + ]) \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch b/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch index 65142465..a8286746 100644 --- a/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch @@ -6,10 +6,6 @@ - diff --git a/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch.py b/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch.py new file mode 100644 index 00000000..68da1935 --- /dev/null +++ b/elevation_mapping_cupy/launch/turtlesim_semantic_pointcloud_example.launch.py @@ -0,0 +1,68 @@ +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch_ros.actions import Node +from launch.substitutions import PathJoinSubstitution +from ament_index_python.packages import get_package_share_directory + + +def generate_launch_description(): + elevation_mapping_cupy_dir = get_package_share_directory('elevation_mapping_cupy') + semantic_sensor_dir = get_package_share_directory('semantic_sensor') + + return LaunchDescription([ + # Include the turtlesim_init launch file + IncludeLaunchDescription( + PythonLaunchDescriptionSource( + PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'launch', + 'turtlesim_init.launch.py' + ]) + ), + launch_arguments={ + 'rviz_config': PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'rviz', + 'turtle_segmentation_example.rviz' + ]) + }.items() + ), + + # Semantic Sensor Node + Node( + package='semantic_sensor', + executable='pointcloud_node.py', + name='front_cam', + arguments=['front_cam'], + parameters=[PathJoinSubstitution([ + semantic_sensor_dir, + 'config', + 'sensor_parameter.yaml' + ])], + output='screen' + ), + + # Elevation Mapping Node + Node( + package='elevation_mapping_cupy', + executable='elevation_mapping_node', + name='elevation_mapping', + parameters=[ + PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'config', + 'core', + 'core_param.yaml' + ]), + PathJoinSubstitution([ + elevation_mapping_cupy_dir, + 'config', + 'setups', + 'turtle_bot', + 'turtle_bot_semantics_pointcloud.yaml' + ]) + ], + output='screen' + ) + ]) \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/turtlesim_simple_example.launch b/elevation_mapping_cupy/launch/turtlesim_simple_example.launch deleted file mode 100644 index 5fd6e529..00000000 --- a/elevation_mapping_cupy/launch/turtlesim_simple_example.launch +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - From 4bdac28e4f52371391def5a51f579d78fafa2d06 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 17:34:27 +0100 Subject: [PATCH 462/504] clean up --- .../elevation_mapping_ros.py | 130 ++++++++---------- 1 file changed, 54 insertions(+), 76 deletions(-) diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py index 82071b81..a81e931f 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py @@ -26,6 +26,7 @@ from std_msgs.msg import MultiArrayLayout as MAL from std_msgs.msg import MultiArrayDimension as MAD from geometry_msgs.msg import TransformStamped +from rclpy.serialization import serialize_message # Custom module imports from elevation_mapping_cupy import ElevationMap, Parameter @@ -81,14 +82,11 @@ def __init__(self): self.register_publishers() self.register_timers() - # Initialize last timestamp + # timestamp of latest pcd or image msg self._last_t = None - # Initialize transform storage with thread safety - self._transform_lock = threading.Lock() - self._current_transform = None - - def initialize_elevation_mapping(self): + def initialize_elevation_mapping(self) -> None: + """Initialize the elevation mapping module.""" self.param.update() self._pointcloud_process_counter = 0 self._image_process_counter = 0 @@ -99,16 +97,14 @@ def initialize_elevation_mapping(self): self._map_q = None self._map_t = None - def initialize_ros(self): - # Initialize TF buffer and listener with increased cache time + def initialize_ros(self) -> None: + """Initialize ROS-related components such as TF buffer and listener.""" self._tf_buffer = tf2_ros.Buffer() - # Initialize TransformListener self._listener = tf2_ros.TransformListener(self._tf_buffer, self) - - # Retrieve ROS parameters self.get_ros_params() - def get_ros_params(self): + def get_ros_params(self) -> None: + """Retrieve ROS parameters from the node.""" # Get parameters with default values self.use_chainer = self.get_parameter('use_chainer').get_parameter_value().bool_value self.weight_file = self.get_parameter('weight_file').get_parameter_value().string_value @@ -196,12 +192,11 @@ def get_ros_params(self): for param_name, param_value in params.items(): self.get_logger().info(f"Parameter '{param_name}': {param_value.value}") - def register_subscribers(self): + def register_subscribers(self) -> None: + """Register ROS subscribers for pointclouds and images.""" # Initialize CvBridge if needed - for config in self.my_subscribers.values(): - if config.get("data_type") == "image": - self.cv_bridge = CvBridge() - break + if any(config.get("data_type") == "image" for config in self.my_subscribers.values()): + self.cv_bridge = CvBridge() # Dictionaries to hold subscribers pointcloud_subs = {} @@ -257,7 +252,8 @@ def register_subscribers(self): f"Registered {len(pointcloud_subs)} pointcloud subscribers and {len(image_subs)} image subscribers." ) - def register_publishers(self): + def register_publishers(self) -> None: + """Register ROS publishers for elevation maps.""" self._publishers_dict = {} self._publishers_timers = [] @@ -275,15 +271,12 @@ def register_publishers(self): self.get_logger().info(f"Publisher '{pub_key}' registered on topic '{topic_name}' with {fps} Hz.") - def register_timers(self): - # Remove separate transform_updater and update_pose timers - # Register the combined timer instead + def register_timers(self) -> None: + """Register ROS timers for pose update, variance update, and time update.""" self.time_pose_update = self.create_timer( 0.1, self.pose_update ) - - # Register additional timers without the ReentrantCallbackGroup self.timer_variance = self.create_timer( 1.0 / self.update_variance_fps, self.update_variance @@ -293,12 +286,17 @@ def register_timers(self): self.update_time ) - self.get_logger().info("Combined transform and pose updater timer, variance, and time timers registered.") + def publish_map(self, key: str) -> None: + """ + Publish the elevation map on the specified topic. - def publish_map(self, key): + Args: + key (str): The key identifying which publisher to use. + """ if self._map_q is None: self.get_logger().info("No map pose available for publishing.") return + gm = GridMap() gm.header.frame_id = self.map_frame gm.header.stamp = self.get_clock().now().to_msg() @@ -314,6 +312,7 @@ def publish_map(self, key): gm.info.pose.orientation.z = 0.0 # self._map_q.z gm.layers = [] gm.basic_layers = self.my_publishers[key]["basic_layers"] + for layer in self.my_publishers[key].get("layers", []): gm.layers.append(layer) self._map.get_map_with_name_ref(layer, self._map_data) @@ -331,7 +330,15 @@ def publish_map(self, key): self._publishers_dict[key].publish(gm) - def image_callback(self, camera_msg, camera_info_msg, sub_key): + def image_callback(self, camera_msg: Image, camera_info_msg: CameraInfo, sub_key: str) -> None: + """ + Callback function for synchronized image and camera info messages. + + Args: + camera_msg (Image): The image message. + camera_info_msg (CameraInfo): The camera info message. + sub_key (str): The subscriber key identifier. + """ # Store timestamps self._last_t = camera_msg.header.stamp @@ -381,9 +388,15 @@ def image_callback(self, camera_msg, camera_info_msg, sub_key): except Exception as e: self.get_logger().error(f"[image_callback] Unexpected error: {str(e)}") - def pointcloud_callback(self, msg, sub_key): + def pointcloud_callback(self, msg: PointCloud2, sub_key: str) -> None: + """ + Callback function for point cloud messages. + + Args: + msg (PointCloud2): The point cloud message. + sub_key (str): The subscriber key identifier. + """ self._last_t = msg.header.stamp - self._pointcloud_stamp = msg.header.stamp channels = ["x", "y", "z"] + self.param.subscriber_cfg[sub_key].get("channels", []) try: @@ -398,12 +411,13 @@ def pointcloud_callback(self, msg, sub_key): frame_sensor_id = msg.header.frame_id try: + # Add a timeout to wait for the transform to become available transform_sensor_to_odom = self._tf_buffer.lookup_transform( self.map_frame, frame_sensor_id, - self._pointcloud_stamp + self._last_t, ) - + t = transform_sensor_to_odom.transform.translation q = transform_sensor_to_odom.transform.rotation t_np = np.array([t.x, t.y, t.z], dtype=np.float32) @@ -413,15 +427,16 @@ def pointcloud_callback(self, msg, sub_key): self._pointcloud_process_counter += 1 except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - self.get_logger().warn(f"[pointcloud_callback] Transform lookup failed: {e}") + self.get_logger().debug(f"[pointcloud_callback] Transform lookup failed: {e}") except Exception as e: self.get_logger().error(f"[pointcloud_callback] Unexpected error: {str(e)}") - def pose_update(self): + def pose_update(self) -> None: + """Update the pose based on the latest transform.""" if self._last_t is None: self.get_logger().debug("No timestamp available for pose update.") return - + try: transform = self._tf_buffer.lookup_transform( self.map_frame, @@ -429,10 +444,6 @@ def pose_update(self): self._last_t ) - # Update the current transform with thread safety - with self._transform_lock: - self._current_transform = transform - # Update the pose t = transform.transform.translation q = transform.transform.rotation @@ -448,65 +459,32 @@ def pose_update(self): except Exception as e: self.get_logger().error(f"[pose_update] Unexpected error: {str(e)}") - def update_variance(self): + def update_variance(self) -> None: self._map.update_variance() self.get_logger().debug("Variance updated.") - def update_time(self): + def update_time(self) -> None: self._map.update_time() self.get_logger().debug("Time updated.") - def get_current_transform(self): - """Thread-safe method to retrieve the latest transform.""" - with self._transform_lock: - return self._current_transform - - def print_tf_frames(self): - """Print all available transforms in the TF buffer with timestamp""" - try: - # Get current timestamp - current_time = self.get_clock().now() - - # Try to get the specific transform from odom to base_footprint - try: - transform = self._tf_buffer.lookup_transform( - self.map_frame, - 'base_footprint', - rclpy.time.Time(), # get the latest transform - rclpy.duration.Duration(seconds=2.0) - ) - self.get_logger().info(f"\nOdom to base_footprint transform timestamp: " - f"{transform.header.stamp.sec}.{transform.header.stamp.nanosec}") - except (tf2_ros.LookupException, tf2_ros.ConnectivityException, - tf2_ros.ExtrapolationException) as e: - self.get_logger().warn(f"Could not lookup odom to base_footprint transform: {e}") - - # Get all frame IDs - frames = self._tf_buffer.all_frames_as_string() - # Uncomment the line below if you want to log all available TF frames - # self.get_logger().info(f"Available TF frames:\n{frames}") - except Exception as e: - self.get_logger().error(f"Failed to get TF frames: {e}") - - def destroy_node(self): + def destroy_node(self) -> None: super().destroy_node() -def main(args=None): +def main(args=None) -> None: + """Main entry point for the elevation mapping node.""" rclpy.init(args=args) node = ElevationMappingNode() - # Initialize a MultiThreadedExecutor instead of SingleThreadedExecutor + # Use a SingleThreadedExecutor as per original implementation executor = rclpy.executors.SingleThreadedExecutor() executor.add_node(node) try: - # Use the executor to spin executor.spin() except KeyboardInterrupt: node.get_logger().info("Shutting down ElevationMappingNode.") finally: - # Shutdown the executor and destroy the node executor.shutdown() node.destroy_node() rclpy.shutdown() From 87cd21ff76b6e15b3cfab1eb8c0b02c332fb9693 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 17:34:54 +0100 Subject: [PATCH 463/504] rename packages --- plane_segmentation/cgal5_ament/.gitignore | 32 +++++++++++++++++++ plane_segmentation/cgal5_ament/CMakeLists.txt | 30 +++++++++++++++++ plane_segmentation/cgal5_ament/README.md | 3 ++ .../cgal5_ament/cmake/cgal-extras.cmake.in | 6 ++++ plane_segmentation/cgal5_ament/package.xml | 19 +++++++++++ 5 files changed, 90 insertions(+) create mode 100644 plane_segmentation/cgal5_ament/.gitignore create mode 100644 plane_segmentation/cgal5_ament/CMakeLists.txt create mode 100644 plane_segmentation/cgal5_ament/README.md create mode 100644 plane_segmentation/cgal5_ament/cmake/cgal-extras.cmake.in create mode 100644 plane_segmentation/cgal5_ament/package.xml diff --git a/plane_segmentation/cgal5_ament/.gitignore b/plane_segmentation/cgal5_ament/.gitignore new file mode 100644 index 00000000..259148fa --- /dev/null +++ b/plane_segmentation/cgal5_ament/.gitignore @@ -0,0 +1,32 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app diff --git a/plane_segmentation/cgal5_ament/CMakeLists.txt b/plane_segmentation/cgal5_ament/CMakeLists.txt new file mode 100644 index 00000000..10107913 --- /dev/null +++ b/plane_segmentation/cgal5_ament/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 3.14) +project(cgal5_ament) + +# Use ament for ROS2 +find_package(ament_cmake REQUIRED) + +include(ExternalProject) + +set(VERSION 5.3) + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include) + +set(CGAL_VERSION 5.3) +ExternalProject_Add(cgal + URL https://github.com/CGAL/cgal/archive/refs/tags/v${CGAL_VERSION}.tar.gz + UPDATE_COMMAND "" + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR} + -DCMAKE_BUILD_TYPE:STRING=Release + BUILD_COMMAND $(MAKE) + INSTALL_COMMAND $(MAKE) install +) + +ament_export_include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) + +install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/CGAL/ + DESTINATION include/CGAL/ +) + +ament_package() diff --git a/plane_segmentation/cgal5_ament/README.md b/plane_segmentation/cgal5_ament/README.md new file mode 100644 index 00000000..af601fd7 --- /dev/null +++ b/plane_segmentation/cgal5_ament/README.md @@ -0,0 +1,3 @@ +# cgal5_catkin + +Catkin wrapper of the Computational Geometry Algorithms Library (CGAL) diff --git a/plane_segmentation/cgal5_ament/cmake/cgal-extras.cmake.in b/plane_segmentation/cgal5_ament/cmake/cgal-extras.cmake.in new file mode 100644 index 00000000..3db7988c --- /dev/null +++ b/plane_segmentation/cgal5_ament/cmake/cgal-extras.cmake.in @@ -0,0 +1,6 @@ +# Makes CGAL/find___.cmake available +list(APPEND CMAKE_MODULE_PATH @CATKIN_DEVEL_PREFIX@/lib/cmake/CGAL) + +# Cpp standard version +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) \ No newline at end of file diff --git a/plane_segmentation/cgal5_ament/package.xml b/plane_segmentation/cgal5_ament/package.xml new file mode 100644 index 00000000..672b22b3 --- /dev/null +++ b/plane_segmentation/cgal5_ament/package.xml @@ -0,0 +1,19 @@ + + + cgal5_ament + 0.0.1 + ROS2 package integrating CGAL + Lorenzo Terenzi + BSD-3-Clause + + + ament_cmake + + + Boost + + + + ament_cmake + + \ No newline at end of file From 33adf6a771ba4fdb6c5f693e663b558eae841883 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 17:35:04 +0100 Subject: [PATCH 464/504] rviz file --- .../rviz/turtle_sim_laser.rviz | 399 ++++++++++++++++++ 1 file changed, 399 insertions(+) create mode 100644 elevation_mapping_cupy/rviz/turtle_sim_laser.rviz diff --git a/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz b/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz new file mode 100644 index 00000000..7b97d78c --- /dev/null +++ b/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz @@ -0,0 +1,399 @@ +Panels: + - Class: rviz_common/Displays + Help Height: 78 + Name: Displays + Property Tree Widget: + Expanded: + - /Global Options1 + - /Status1 + - /PointCloud21 + - /RobotModel1 + - /TF1 + - /GridMap1 + Splitter Ratio: 0.5 + Tree Height: 272 + - Class: rviz_common/Selection + Name: Selection + - Class: rviz_common/Tool Properties + Expanded: + - /2D Goal Pose1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz_common/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz_common/Time + Experimental: false + Name: Time + SyncMode: 0 + SyncSource: PointCloud2 +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz_default_plugins/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.029999999329447746 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Autocompute Value Bounds: + Max Value: 10 + Min Value: -10 + Value: true + Axis: Z + Channel Name: intensity + Class: rviz_default_plugins/PointCloud2 + Color: 255; 255; 255 + Color Transformer: RGB8 + Decay Time: 0 + Enabled: true + Invert Rainbow: false + Max Color: 255; 255; 255 + Max Intensity: 4096 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: PointCloud2 + Position Transformer: XYZ + Selectable: true + Size (Pixels): 3 + Size (m): 0.009999999776482582 + Style: Points + Topic: + Depth: 5 + Durability Policy: Volatile + Filter size: 10 + History Policy: Keep Last + Reliability Policy: Reliable + Value: /intel_realsense_r200_depth/points + Use Fixed Frame: true + Use rainbow: true + Value: true + - Alpha: 1 + Class: rviz_default_plugins/RobotModel + Collision Enabled: false + Description File: "" + Description Source: Topic + Description Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /robot_description + Enabled: true + Links: + All Links Enabled: true + Expand Joint Details: false + Expand Link Details: false + Expand Tree: false + Link Tree Style: Links in Alphabetic Order + base_footprint: + Alpha: 1 + Show Axes: false + Show Trail: false + base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + base_scan: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + camera_depth_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + camera_rgb_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + camera_rgb_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + caster_back_left_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + caster_back_right_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + imu_link: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_depth_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + realsense_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + wheel_left_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + wheel_right_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + Mass Properties: + Inertia: false + Mass: false + Name: RobotModel + TF Prefix: "" + Update Interval: 0 + Value: true + Visual Enabled: true + - Class: rviz_default_plugins/TF + Enabled: true + Frame Timeout: 15 + Frames: + All Enabled: true + base_footprint: + Value: true + base_link: + Value: true + base_scan: + Value: true + camera_depth_optical_frame: + Value: true + camera_rgb_frame: + Value: true + camera_rgb_optical_frame: + Value: true + caster_back_left_link: + Value: true + caster_back_right_link: + Value: true + imu_link: + Value: true + odom: + Value: true + realsense_depth_frame: + Value: true + realsense_link: + Value: true + wheel_left_link: + Value: true + wheel_right_link: + Value: true + Marker Scale: 1 + Name: TF + Show Arrows: true + Show Axes: true + Show Names: false + Tree: + odom: + base_footprint: + base_link: + base_scan: + {} + caster_back_left_link: + {} + caster_back_right_link: + {} + imu_link: + {} + realsense_link: + camera_rgb_frame: + camera_rgb_optical_frame: + {} + realsense_depth_frame: + camera_depth_optical_frame: + {} + wheel_left_link: + {} + wheel_right_link: + {} + Update Interval: 0 + Value: true + - Class: rviz_default_plugins/Camera + Enabled: false + Far Plane Distance: 100 + Image Rendering: background and overlay + Name: Camera + Overlay Alpha: 0.5 + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /intel_realsense_r200_rgb/image_raw + Value: false + Visibility: + "": true + Grid: true + Image: true + PointCloud2: true + RobotModel: true + TF: true + Value: true + Zoom Factor: 1 + - Class: rviz_default_plugins/Image + Enabled: false + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /intel_realsense_r200_depth/image_raw + Value: false + - Class: rviz_default_plugins/Image + Enabled: true + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /intel_realsense_r200_rgb/image_raw + Value: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: elevation + Color Transformer: IntensityLayer + Enabled: true + Height Layer: elevation + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 255; 255; 255 + Max Intensity: 10 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: GridMap + Show Grid Lines: true + Topic: + Depth: 5 + Durability Policy: Volatile + Filter size: 10 + History Policy: Keep Last + Reliability Policy: Reliable + Value: /elevation_mapping/elevation_map_raw + Use Rainbow: true + Value: true + Enabled: true + Global Options: + Background Color: 48; 48; 48 + Fixed Frame: base_footprint + Frame Rate: 30 + Name: root + Tools: + - Class: rviz_default_plugins/Interact + Hide Inactive Objects: true + - Class: rviz_default_plugins/MoveCamera + - Class: rviz_default_plugins/Select + - Class: rviz_default_plugins/FocusCamera + - Class: rviz_default_plugins/Measure + Line color: 128; 128; 0 + - Class: rviz_default_plugins/SetInitialPose + Covariance x: 0.25 + Covariance y: 0.25 + Covariance yaw: 0.06853891909122467 + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /initialpose + - Class: rviz_default_plugins/SetGoal + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /goal_pose + - Class: rviz_default_plugins/PublishPoint + Single click: true + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /clicked_point + Transformation: + Current: + Class: rviz_default_plugins/TF + Value: true + Views: + Current: + Class: rviz_default_plugins/Orbit + Distance: 6.990833282470703 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Focal Point: + X: 0.13978521525859833 + Y: 0.045054733753204346 + Z: 0.2562030851840973 + Focal Shape Fixed Size: true + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 0.3597964644432068 + Target Frame: + Value: Orbit (rviz) + Yaw: 3.0935845375061035 + Saved: ~ +Window Geometry: + Camera: + collapsed: false + Displays: + collapsed: false + Height: 846 + Hide Left Dock: false + Hide Right Dock: false + Image: + collapsed: false + QMainWindow State: 000000ff00000000fd000000040000000000000156000002b4fc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003b00000199000000c700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000c00430061006d0065007200610000000136000000f70000002800fffffffb0000000a0049006d0061006700650000000157000000d60000002800fffffffb0000000a0049006d00610067006501000001da000001150000002800ffffff000000010000010f000002b4fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003b000002b4000000a000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004b00000003efc0100000002fb0000000800540069006d00650100000000000004b00000025300fffffffb0000000800540069006d006501000000000000045000000000000000000000023f000002b400000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: false + Width: 1200 + X: 60 + Y: 169 From 2601c7df7bdf3e94e35f196f9069cf34548c15e7 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 17:35:18 +0100 Subject: [PATCH 465/504] basic example --- elevation_mapping_cupy/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 elevation_mapping_cupy/README.md diff --git a/elevation_mapping_cupy/README.md b/elevation_mapping_cupy/README.md new file mode 100644 index 00000000..f7010dff --- /dev/null +++ b/elevation_mapping_cupy/README.md @@ -0,0 +1,12 @@ +## Example 1: Turtle Simple Example +Install the realsense wrapper for [TurtleBot3]([ros2_turtlebot3_waffle_intel_realsense](https://github.com/mlherd/ros2_turtlebot3_waffle_intel_realsense)) and place the model in your home .gazebo/models/ folder. +You can launch the turtlebot3 in Gazebo with the following command: +```bash +ros2 launch elevation_mapping_cupy turtle_simple_example.launch.py +``` +You can also maunally spawn the robot in Gazebo. + + +Launch the elevation mapping node: +```bash +ros2 launch elevation_mapping_cupy turtle_simple_example.launch.py``` \ No newline at end of file From 12d036e5641a2550968532985cb4bec78bdaae6c Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 17:35:45 +0100 Subject: [PATCH 466/504] compiles --- .../semantic_sensor/CMakeLists.txt | 28 -------------- .../launch/semantic_image.launch.py | 2 +- .../launch/semantic_pointcloud.launch.py | 2 +- sensor_processing/semantic_sensor/package.xml | 7 +++- .../__init__.py => resource/semantic_sensor} | 0 .../DINO}/__init__.py | 0 .../semantic_sensor/DINO/modules.py | 0 .../semantic_sensor/DINO/utils.py | 0 .../DINO/vision_transformer.py | 0 .../tests => semantic_sensor}/__init__.py | 0 .../semantic_sensor/image_node.py | 6 ++- .../semantic_sensor/image_parameters.py | 0 .../{script => }/semantic_sensor/networks.py | 0 .../semantic_sensor/pointcloud_node.py | 7 +++- .../semantic_sensor/pointcloud_parameters.py | 0 .../semantic_sensor/tests/__init__.py | 0 .../semantic_sensor/tests/test_pointcloud.py | 0 .../semantic_sensor/tests/test_utils.py | 0 .../{script => }/semantic_sensor/utils.py | 0 sensor_processing/semantic_sensor/setup.cfg | 4 ++ sensor_processing/semantic_sensor/setup.py | 37 ++++++++++++++++--- 21 files changed, 51 insertions(+), 42 deletions(-) delete mode 100644 sensor_processing/semantic_sensor/CMakeLists.txt rename sensor_processing/semantic_sensor/{script/semantic_sensor/DINO/__init__.py => resource/semantic_sensor} (100%) rename sensor_processing/semantic_sensor/{script/semantic_sensor => semantic_sensor/DINO}/__init__.py (100%) rename sensor_processing/semantic_sensor/{script => }/semantic_sensor/DINO/modules.py (100%) rename sensor_processing/semantic_sensor/{script => }/semantic_sensor/DINO/utils.py (100%) rename sensor_processing/semantic_sensor/{script => }/semantic_sensor/DINO/vision_transformer.py (100%) rename sensor_processing/semantic_sensor/{script/semantic_sensor/tests => semantic_sensor}/__init__.py (100%) rename sensor_processing/semantic_sensor/{script => }/semantic_sensor/image_node.py (99%) rename sensor_processing/semantic_sensor/{script => }/semantic_sensor/image_parameters.py (100%) rename sensor_processing/semantic_sensor/{script => }/semantic_sensor/networks.py (100%) rename sensor_processing/semantic_sensor/{script => }/semantic_sensor/pointcloud_node.py (99%) rename sensor_processing/semantic_sensor/{script => }/semantic_sensor/pointcloud_parameters.py (100%) create mode 100644 sensor_processing/semantic_sensor/semantic_sensor/tests/__init__.py rename sensor_processing/semantic_sensor/{script => }/semantic_sensor/tests/test_pointcloud.py (100%) rename sensor_processing/semantic_sensor/{script => }/semantic_sensor/tests/test_utils.py (100%) rename sensor_processing/semantic_sensor/{script => }/semantic_sensor/utils.py (100%) create mode 100644 sensor_processing/semantic_sensor/setup.cfg diff --git a/sensor_processing/semantic_sensor/CMakeLists.txt b/sensor_processing/semantic_sensor/CMakeLists.txt deleted file mode 100644 index 04fe1c0f..00000000 --- a/sensor_processing/semantic_sensor/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -cmake_minimum_required(VERSION 3.8) -project(semantic_sensor) - -# Find dependencies -find_package(ament_cmake REQUIRED) -find_package(rclpy REQUIRED) -find_package(tf2_ros REQUIRED) -find_package(sensor_msgs REQUIRED) -find_package(std_msgs REQUIRED) -find_package(geometry_msgs REQUIRED) - -# Install Python modules -ament_python_install_package(${PROJECT_NAME} PACKAGE_DIR script/semantic_sensor) - -# Install Python executables -install(PROGRAMS - script/semantic_sensor/pointcloud_node.py - script/semantic_sensor/image_node.py - DESTINATION lib/${PROJECT_NAME} -) - -# Install launch files -install(DIRECTORY - launch - DESTINATION share/${PROJECT_NAME} -) - -ament_package() \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/launch/semantic_image.launch.py b/sensor_processing/semantic_sensor/launch/semantic_image.launch.py index 50d551f2..32a190fd 100644 --- a/sensor_processing/semantic_sensor/launch/semantic_image.launch.py +++ b/sensor_processing/semantic_sensor/launch/semantic_image.launch.py @@ -5,7 +5,7 @@ def generate_launch_description(): return LaunchDescription([ Node( package='semantic_sensor', - executable='image_node.py', + executable='image_node', name='semantic_image', arguments=['front_cam_image'], output='screen', diff --git a/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch.py b/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch.py index 91fbb8c9..1ca06105 100644 --- a/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch.py +++ b/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch.py @@ -5,7 +5,7 @@ def generate_launch_description(): return LaunchDescription([ Node( package='semantic_sensor', - executable='pointcloud_node.py', + executable='pointcloud_node', name='semantic_pointcloud', arguments=['front_cam'], output='screen', diff --git a/sensor_processing/semantic_sensor/package.xml b/sensor_processing/semantic_sensor/package.xml index 5637b4d4..d789afb1 100644 --- a/sensor_processing/semantic_sensor/package.xml +++ b/sensor_processing/semantic_sensor/package.xml @@ -9,7 +9,7 @@ https://github.com/leggedrobotics/elevation_mapping_semantic_cupy - ament_cmake + ament_python rclpy tf2_ros sensor_msgs @@ -18,4 +18,7 @@ python3 - + + ament_python + + \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/__init__.py b/sensor_processing/semantic_sensor/resource/semantic_sensor similarity index 100% rename from sensor_processing/semantic_sensor/script/semantic_sensor/DINO/__init__.py rename to sensor_processing/semantic_sensor/resource/semantic_sensor diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/__init__.py b/sensor_processing/semantic_sensor/semantic_sensor/DINO/__init__.py similarity index 100% rename from sensor_processing/semantic_sensor/script/semantic_sensor/__init__.py rename to sensor_processing/semantic_sensor/semantic_sensor/DINO/__init__.py diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py b/sensor_processing/semantic_sensor/semantic_sensor/DINO/modules.py similarity index 100% rename from sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py rename to sensor_processing/semantic_sensor/semantic_sensor/DINO/modules.py diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/utils.py b/sensor_processing/semantic_sensor/semantic_sensor/DINO/utils.py similarity index 100% rename from sensor_processing/semantic_sensor/script/semantic_sensor/DINO/utils.py rename to sensor_processing/semantic_sensor/semantic_sensor/DINO/utils.py diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py b/sensor_processing/semantic_sensor/semantic_sensor/DINO/vision_transformer.py similarity index 100% rename from sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py rename to sensor_processing/semantic_sensor/semantic_sensor/DINO/vision_transformer.py diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/__init__.py b/sensor_processing/semantic_sensor/semantic_sensor/__init__.py similarity index 100% rename from sensor_processing/semantic_sensor/script/semantic_sensor/tests/__init__.py rename to sensor_processing/semantic_sensor/semantic_sensor/__init__.py diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py b/sensor_processing/semantic_sensor/semantic_sensor/image_node.py similarity index 99% rename from sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py rename to sensor_processing/semantic_sensor/semantic_sensor/image_node.py index e64991f1..5b22341f 100755 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py +++ b/sensor_processing/semantic_sensor/semantic_sensor/image_node.py @@ -285,10 +285,12 @@ def publish_feature_image(self, features): feat_msg.header.frame_id = self.header.frame_id self.feat_im_pub.publish(feat_msg) - -if __name__ == "__main__": +def main(): arg = sys.argv[1] sensor_name = arg rospy.init_node("semantic_segmentation_node", anonymous=True, log_level=rospy.INFO) node = SemanticSegmentationNode(sensor_name) rospy.spin() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py b/sensor_processing/semantic_sensor/semantic_sensor/image_parameters.py similarity index 100% rename from sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py rename to sensor_processing/semantic_sensor/semantic_sensor/image_parameters.py diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py b/sensor_processing/semantic_sensor/semantic_sensor/networks.py similarity index 100% rename from sensor_processing/semantic_sensor/script/semantic_sensor/networks.py rename to sensor_processing/semantic_sensor/semantic_sensor/networks.py diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py b/sensor_processing/semantic_sensor/semantic_sensor/pointcloud_node.py similarity index 99% rename from sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py rename to sensor_processing/semantic_sensor/semantic_sensor/pointcloud_node.py index a713f312..799527d4 100755 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py +++ b/sensor_processing/semantic_sensor/semantic_sensor/pointcloud_node.py @@ -360,9 +360,12 @@ def publish_pointcloud(self, pcl, header): # pc2.header.frame_id = self.param.cam_frame self.pcl_pub.publish(pc2) - -if __name__ == "__main__": +def main(): + arg = sys.argv[1] sensor_name = sys.argv[1] rospy.init_node("semantic_pointcloud_node", anonymous=True, log_level=rospy.INFO) node = PointcloudNode(sensor_name) rospy.spin() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py b/sensor_processing/semantic_sensor/semantic_sensor/pointcloud_parameters.py similarity index 100% rename from sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py rename to sensor_processing/semantic_sensor/semantic_sensor/pointcloud_parameters.py diff --git a/sensor_processing/semantic_sensor/semantic_sensor/tests/__init__.py b/sensor_processing/semantic_sensor/semantic_sensor/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py b/sensor_processing/semantic_sensor/semantic_sensor/tests/test_pointcloud.py similarity index 100% rename from sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py rename to sensor_processing/semantic_sensor/semantic_sensor/tests/test_pointcloud.py diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py b/sensor_processing/semantic_sensor/semantic_sensor/tests/test_utils.py similarity index 100% rename from sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py rename to sensor_processing/semantic_sensor/semantic_sensor/tests/test_utils.py diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/utils.py b/sensor_processing/semantic_sensor/semantic_sensor/utils.py similarity index 100% rename from sensor_processing/semantic_sensor/script/semantic_sensor/utils.py rename to sensor_processing/semantic_sensor/semantic_sensor/utils.py diff --git a/sensor_processing/semantic_sensor/setup.cfg b/sensor_processing/semantic_sensor/setup.cfg new file mode 100644 index 00000000..269422d8 --- /dev/null +++ b/sensor_processing/semantic_sensor/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script_dir=$base/lib/semantic_sensor +[install] +install_scripts=$base/lib/semantic_sensor \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/setup.py b/sensor_processing/semantic_sensor/setup.py index fef26672..a6127608 100644 --- a/sensor_processing/semantic_sensor/setup.py +++ b/sensor_processing/semantic_sensor/setup.py @@ -1,8 +1,33 @@ -from distutils.core import setup -from catkin_pkg.python_setup import generate_distutils_setup +from setuptools import setup +import os +from glob import glob -setup_args = generate_distutils_setup( - packages=["semantic_sensor",], install_requires=["torch", "torchvision",], package_dir={"": "script"}, -) +package_name = 'semantic_sensor' -setup(**setup_args) +setup( + name=package_name, + version='0.0.0', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + (os.path.join('share', package_name, 'launch'), + glob('launch/*.launch.py')), + (os.path.join('share', package_name, 'config'), + glob('config/*.yaml')) + ], + install_requires=['setuptools', 'torch', 'torchvision'], + zip_safe=True, + maintainer='Gian Erni', + maintainer_email='gerni@ethz.ch', + description='The semantic_sensor package', + license='MIT', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + 'pointcloud_node = semantic_sensor.pointcloud_node:main', + 'image_node = semantic_sensor.image_node:main', + ], + }, +) From 69d917117e416a4485fbab00046bed6d7e76eca7 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 17:36:01 +0100 Subject: [PATCH 467/504] cga5 ament --- plane_segmentation/cgal5_catkin/.gitignore | 32 ------------------- .../cgal5_catkin/CMakeLists.txt | 30 ----------------- plane_segmentation/cgal5_catkin/README.md | 3 -- .../cgal5_catkin/cmake/cgal-extras.cmake.in | 6 ---- plane_segmentation/cgal5_catkin/package.xml | 19 ----------- .../convex_plane_decomposition/CMakeLists.txt | 2 +- .../convex_plane_decomposition/package.xml | 2 +- 7 files changed, 2 insertions(+), 92 deletions(-) delete mode 100644 plane_segmentation/cgal5_catkin/.gitignore delete mode 100644 plane_segmentation/cgal5_catkin/CMakeLists.txt delete mode 100644 plane_segmentation/cgal5_catkin/README.md delete mode 100644 plane_segmentation/cgal5_catkin/cmake/cgal-extras.cmake.in delete mode 100644 plane_segmentation/cgal5_catkin/package.xml diff --git a/plane_segmentation/cgal5_catkin/.gitignore b/plane_segmentation/cgal5_catkin/.gitignore deleted file mode 100644 index 259148fa..00000000 --- a/plane_segmentation/cgal5_catkin/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app diff --git a/plane_segmentation/cgal5_catkin/CMakeLists.txt b/plane_segmentation/cgal5_catkin/CMakeLists.txt deleted file mode 100644 index 306a7905..00000000 --- a/plane_segmentation/cgal5_catkin/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -cmake_minimum_required(VERSION 3.14) -project(cgal5_catkin) - -# Use ament for ROS2 -find_package(ament_cmake REQUIRED) - -include(ExternalProject) - -set(VERSION 5.3) - -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include) - -set(CGAL_VERSION 5.3) -ExternalProject_Add(cgal - URL https://github.com/CGAL/cgal/archive/refs/tags/v${CGAL_VERSION}.tar.gz - UPDATE_COMMAND "" - CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR} - -DCMAKE_BUILD_TYPE:STRING=Release - BUILD_COMMAND $(MAKE) - INSTALL_COMMAND $(MAKE) install -) - -ament_export_include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) - -install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/CGAL/ - DESTINATION include/CGAL/ -) - -ament_package() diff --git a/plane_segmentation/cgal5_catkin/README.md b/plane_segmentation/cgal5_catkin/README.md deleted file mode 100644 index af601fd7..00000000 --- a/plane_segmentation/cgal5_catkin/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cgal5_catkin - -Catkin wrapper of the Computational Geometry Algorithms Library (CGAL) diff --git a/plane_segmentation/cgal5_catkin/cmake/cgal-extras.cmake.in b/plane_segmentation/cgal5_catkin/cmake/cgal-extras.cmake.in deleted file mode 100644 index 3db7988c..00000000 --- a/plane_segmentation/cgal5_catkin/cmake/cgal-extras.cmake.in +++ /dev/null @@ -1,6 +0,0 @@ -# Makes CGAL/find___.cmake available -list(APPEND CMAKE_MODULE_PATH @CATKIN_DEVEL_PREFIX@/lib/cmake/CGAL) - -# Cpp standard version -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) \ No newline at end of file diff --git a/plane_segmentation/cgal5_catkin/package.xml b/plane_segmentation/cgal5_catkin/package.xml deleted file mode 100644 index 1fb19b57..00000000 --- a/plane_segmentation/cgal5_catkin/package.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - cgal5_catkin - 0.0.1 - ROS2 package integrating CGAL - Lorenzo Terenzi - BSD-3-Clause - - - ament_cmake - - - Boost - - - - ament_cmake - - \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition/CMakeLists.txt index 2deb335a..44d7d67a 100644 --- a/plane_segmentation/convex_plane_decomposition/CMakeLists.txt +++ b/plane_segmentation/convex_plane_decomposition/CMakeLists.txt @@ -3,7 +3,7 @@ project(convex_plane_decomposition) # Catkin dependencies set(CATKIN_PACKAGE_DEPENDENCIES - cgal5_catkin + cgal5_ament grid_map_core grid_map_cv grid_map_filters_rsl diff --git a/plane_segmentation/convex_plane_decomposition/package.xml b/plane_segmentation/convex_plane_decomposition/package.xml index 5ccbe03f..85988116 100644 --- a/plane_segmentation/convex_plane_decomposition/package.xml +++ b/plane_segmentation/convex_plane_decomposition/package.xml @@ -9,7 +9,7 @@ MIT catkin - cgal5_catkin + cgal5_ament grid_map_core grid_map_cv grid_map_filters_rsl From 5340dbd2ec1191a14a95222e1caf326b3485498f Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 5 Dec 2024 17:36:11 +0100 Subject: [PATCH 468/504] missing todods --- TODO.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 00000000..89df8dc9 --- /dev/null +++ b/TODO.md @@ -0,0 +1,11 @@ +- [x] Compile "elevation_mapping_msgs" with ROS2 +- [x] Compile "elevation_mapping_cupy" with ROS2 +- [x] Compile "semantic_sensor" with ROS2 +- [x] Compile "convex_plane_decomposition_msgs" with ROS2 +- [ ] Compile "convex_plane_decomposition" with ROS2 +- [x] Compile "grid_map_filters_rsl" with ROS2 +- [x] Compile "cgal5_ament" with ROS2 + +- [x] Run "elevation_mapping_cupy" with ROS2 +- [ ] Run "semantic_sensor" with ROS2 +- [ ] Run "convex_plane_decomposition" with ROS2 From fa3693f4d232e6d530dc5ef83ab2b39246899f5f Mon Sep 17 00:00:00 2001 From: Idate96 Date: Sat, 7 Dec 2024 12:50:03 +0100 Subject: [PATCH 469/504] removed ros params --- .../config/core/plugin_config.yaml | 76 +++++++++---------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/elevation_mapping_cupy/config/core/plugin_config.yaml b/elevation_mapping_cupy/config/core/plugin_config.yaml index b0c622fa..36a1a580 100644 --- a/elevation_mapping_cupy/config/core/plugin_config.yaml +++ b/elevation_mapping_cupy/config/core/plugin_config.yaml @@ -1,40 +1,36 @@ -/elevation_mapping_node: - ros__parameters: - # Settings of the plugins. (The plugins should be stored in script/plugins) - - # min_filter fills in minimum value around the invalid cell. - min_filter: - enable: True # weather to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "min_filter" # The layer name. - extra_params: # This params are passed to the plugin class on initialization. - dilation_size: 1 # The patch size to apply - iteration_n: 30 # The number of iterations - # Apply smoothing. - smooth_filter: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth" - extra_params: - input_layer_name: "min_filter" - # Apply inpainting using opencv - inpainting: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "inpaint" - extra_params: - method: "telea" # telea or ns - # Apply smoothing for inpainted layer - erosion: - enable: True - fill_nan: False - is_height_layer: False - layer_name: "erosion" - extra_params: - input_layer_name: "traversability" - dilation_size: 3 - iteration_n: 20 - reverse: True \ No newline at end of file +# min_filter fills in minimum value around the invalid cell. +min_filter: + enable: True # weather to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # This params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations +# Apply smoothing. +smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" +# Apply inpainting using opencv +inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns +# Apply smoothing for inpainted layer +erosion: + enable: True + fill_nan: False + is_height_layer: False + layer_name: "erosion" + extra_params: + input_layer_name: "traversability" + dilation_size: 3 + iteration_n: 20 + reverse: True \ No newline at end of file From c5e3708927f90f1682692b2c64134b885328cc22 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Sat, 7 Dec 2024 17:49:45 +0100 Subject: [PATCH 470/504] sim time --- .../elevation_mapping_ros.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py index a81e931f..fc345141 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py @@ -1,11 +1,7 @@ #!/usr/bin/env python3 -import matplotlib.pyplot as plt -from mpl_toolkits.mplot3d import Axes3D import numpy as np import os from functools import partial -import threading -import time # Import time module for benchmarking # ROS 2 imports import rclpy @@ -25,7 +21,6 @@ from std_msgs.msg import Float32MultiArray from std_msgs.msg import MultiArrayLayout as MAL from std_msgs.msg import MultiArrayDimension as MAD -from geometry_msgs.msg import TransformStamped from rclpy.serialization import serialize_message # Custom module imports @@ -51,7 +46,12 @@ def __init__(self): # Initialize the node without passing callback_group to super() super().__init__( 'elevation_mapping_node', - automatically_declare_parameters_from_overrides=True + automatically_declare_parameters_from_overrides=True, + # Add this parameter to enable sim time + allow_undeclared_parameters=True, + parameter_overrides=[ + rclpy.Parameter('use_sim_time', rclpy.Parameter.Type.BOOL, True) + ] ) # Get package share directory @@ -412,14 +412,14 @@ def pointcloud_callback(self, msg: PointCloud2, sub_key: str) -> None: frame_sensor_id = msg.header.frame_id try: # Add a timeout to wait for the transform to become available - transform_sensor_to_odom = self._tf_buffer.lookup_transform( + transform_sensor_to_map = self._tf_buffer.lookup_transform( self.map_frame, frame_sensor_id, self._last_t, ) - t = transform_sensor_to_odom.transform.translation - q = transform_sensor_to_odom.transform.rotation + t = transform_sensor_to_map.transform.translation + q = transform_sensor_to_map.transform.rotation t_np = np.array([t.x, t.y, t.z], dtype=np.float32) R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) From 0f2fb18262b12d1dbd9fe49391d44dd313dd275c Mon Sep 17 00:00:00 2001 From: amilearning Date: Tue, 17 Dec 2024 14:05:29 +0100 Subject: [PATCH 471/504] elevation freq working with feat --- elevation_map_msgs/srv/CheckSafety.srv | 1 - elevation_mapping_cupy/CMakeLists.txt | 1 + .../lib/elevation_mapping_cupy/__init__.py | 4 - .../elevation_mapping.py | 970 ------------- .../elevation_mapping_ros.py | 322 ---- .../fusion/fusion_manager.py | 112 -- .../fusion/image_color.py | 86 -- .../fusion/pointcloud_average.py | 113 -- .../fusion/pointcloud_bayesian_inference.py | 122 -- .../fusion/pointcloud_class_average.py | 126 -- .../fusion/pointcloud_class_bayesian.py | 75 - .../fusion/pointcloud_class_max.py | 123 -- .../fusion/pointcloud_color.py | 152 -- .../kernels/__init__.py | 3 - .../kernels/custom_image_kernels.py | 271 ---- .../kernels/custom_kernels.py | 685 --------- .../kernels/custom_semantic_kernels.py | 375 ----- .../lib/elevation_mapping_cupy/kernels/kk.py | 1290 ----------------- .../elevation_mapping_cupy/map_initializer.py | 80 - .../lib/elevation_mapping_cupy/parameter.py | 300 ---- .../elevation_mapping_cupy/plugins/erosion.py | 113 -- .../plugins/features_pca.py | 96 -- .../plugins/inpainting.py | 63 - .../plugins/max_layer_filter.py | 108 -- .../plugins/min_filter.py | 118 -- .../plugins/plugin_manager.py | 268 ---- .../plugins/robot_centric_elevation.py | 121 -- .../plugins/semantic_filter.py | 133 -- .../plugins/semantic_traversability.py | 83 -- .../plugins/smooth_filter.py | 59 - .../elevation_mapping_cupy/semantic_map.py | 400 ----- .../elevation_mapping_cupy/tests/__init__.py | 0 .../tests/test_elevation_mapping.py | 118 -- .../tests/test_parameter.py | 17 - .../tests/test_plugins.py | 69 - .../tests/test_semantic_kernels.py | 307 ---- .../tests/test_semantic_map.py | 47 - .../traversability_filter.py | 100 -- .../traversability_polygon.py | 77 - .../config/core/core_param copy 2.yaml | 197 +++ .../config/core/core_param.yaml | 51 +- .../config/core/core_param_sim.yaml | 197 +++ .../elevation_mapping_ros.hpp | 1 + .../elevation_mapping.py | 6 + .../fusion/image_latest.py} | 18 +- .../src/elevation_mapping_ros.cpp | 15 +- filters | 1 + grid_map | 1 + nav2_common/CMakeLists.txt | 17 + nav2_common/cmake/nav2_package.cmake | 57 + nav2_common/nav2_common-extras.cmake | 17 + .../nav2_common}/__init__.py | 0 nav2_common/nav2_common/launch/__init__.py | 18 + .../nav2_common/launch/has_node_params.py | 60 + .../launch/parse_multirobot_pose.py | 82 ++ .../nav2_common/launch/replace_string.py | 87 ++ .../nav2_common/launch/rewritten_yaml.py | 190 +++ nav2_common/package.xml | 25 + .../__init__.py => nav2_msgs/CHANGELOG.rst | 0 nav2_msgs/CMakeLists.txt | 53 + nav2_msgs/README.md | 3 + nav2_msgs/action/AssistedTeleop.action | 8 + nav2_msgs/action/BackUp.action | 10 + .../action/ComputePathThroughPoses.action | 11 + nav2_msgs/action/ComputePathToPose.action | 11 + nav2_msgs/action/DriveOnHeading.action | 10 + nav2_msgs/action/DummyBehavior.action | 7 + nav2_msgs/action/FollowPath.action | 11 + nav2_msgs/action/FollowWaypoints.action | 8 + nav2_msgs/action/NavigateThroughPoses.action | 14 + nav2_msgs/action/NavigateToPose.action | 13 + nav2_msgs/action/SmoothPath.action | 12 + nav2_msgs/action/Spin.action | 9 + nav2_msgs/action/Wait.action | 8 + nav2_msgs/msg/BehaviorTreeLog.msg | 2 + nav2_msgs/msg/BehaviorTreeStatusChange.msg | 4 + nav2_msgs/msg/CollisionMonitorState.msg | 9 + nav2_msgs/msg/Costmap.msg | 9 + nav2_msgs/msg/CostmapFilterInfo.msg | 14 + nav2_msgs/msg/CostmapMetaData.msg | 23 + nav2_msgs/msg/Particle.msg | 5 + nav2_msgs/msg/ParticleCloud.msg | 6 + nav2_msgs/msg/SpeedLimit.msg | 6 + nav2_msgs/msg/VoxelGrid.msg | 7 + nav2_msgs/package.xml | 28 + nav2_msgs/srv/ClearCostmapAroundRobot.srv | 5 + nav2_msgs/srv/ClearCostmapExceptRegion.srv | 5 + nav2_msgs/srv/ClearEntireCostmap.srv | 5 + nav2_msgs/srv/GetCostmap.srv | 6 + nav2_msgs/srv/IsPathValid.srv | 6 + nav2_msgs/srv/LoadMap.srv | 15 + nav2_msgs/srv/ManageLifecycleNodes.srv | 9 + nav2_msgs/srv/SaveMap.srv | 14 + nav2_msgs/srv/SetInitialPose.srv | 3 + pcl_msgs | 1 + perception_pcl | 1 + plane_segmentation/README.md | 45 - plane_segmentation/cgal5_catkin/.gitignore | 32 - .../cgal5_catkin/CMakeLists.txt | 31 - plane_segmentation/cgal5_catkin/README.md | 3 - .../cgal5_catkin/cmake/cgal-extras.cmake.in | 6 - plane_segmentation/cgal5_catkin/package.xml | 13 - .../convex_plane_decomposition/CMakeLists.txt | 114 -- .../ConvexRegionGrowing.h | 20 - .../include/convex_plane_decomposition/Draw.h | 27 - .../GeometryUtils.h | 140 -- .../GridMapPreprocessing.h | 37 - .../LoadGridmapFromImage.h | 26 - .../convex_plane_decomposition/PlanarRegion.h | 66 - .../PlaneDecompositionPipeline.h | 77 - .../convex_plane_decomposition/PolygonTypes.h | 21 - .../Postprocessing.h | 47 - .../SegmentedPlaneProjection.h | 77 - .../SegmentedPlanesMap.h | 32 - .../convex_plane_decomposition/Timer.h | 82 -- .../contour_extraction/ContourExtraction.h | 47 - .../ContourExtractionParameters.h | 16 - .../contour_extraction/Upsampling.h | 31 - .../ransac/RansacPlaneExtractor.hpp | 53 - .../ransac/RansacPlaneExtractorParameters.h | 23 - .../SlidingWindowPlaneExtractor.h | 65 - .../SlidingWindowPlaneExtractorParameters.h | 44 - .../convex_plane_decomposition/package.xml | 17 - .../src/ConvexRegionGrowing.cpp | 229 --- .../convex_plane_decomposition/src/Draw.cpp | 60 - .../src/GridMapPreprocessing.cpp | 52 - .../src/LoadGridmapFromImage.cpp | 36 - .../src/PlanarRegion.cpp | 59 - .../src/PlaneDecompositionPipeline.cpp | 45 - .../src/Postprocessing.cpp | 146 -- .../src/SegmentedPlaneProjection.cpp | 150 -- .../contour_extraction/ContourExtraction.cpp | 145 -- .../src/contour_extraction/Upsampling.cpp | 71 - .../src/ransac/RansacPlaneExtractor.cpp | 39 - .../SlidingWindowPlaneExtractor.cpp | 311 ---- .../test/data/terrain.png | Bin 112548 -> 0 bytes .../test/testConvexApproximation.cpp | 101 -- .../test/testPipeline.cpp | 35 - .../test/testPlanarRegion.cpp | 85 -- .../test/testRegionGrowing.cpp | 69 - .../test/testUpsampling.cpp | 28 - .../CMakeLists.txt | 35 - .../msg/BoundingBox2d.msg | 5 - .../msg/PlanarRegion.msg | 7 - .../msg/PlanarTerrain.msg | 2 - .../msg/Point2d.msg | 2 - .../msg/Polygon2d.msg | 2 - .../msg/PolygonWithHoles2d.msg | 3 - .../package.xml | 23 - .../CMakeLists.txt | 129 -- .../config/demo_node.yaml | 8 - .../config/node.yaml | 8 - .../config/parameters.yaml | 34 - .../data/holes.png | Bin 350 -> 0 bytes .../data/real_stairs_125cm.png | Bin 4211 -> 0 bytes .../data/slope_1m_1m_20cm.png | Bin 358 -> 0 bytes .../data/straight_stairs_1m_1m_60cm.png | Bin 262 -> 0 bytes .../data/terrain.png | Bin 112548 -> 0 bytes .../ConvexPlaneDecompositionRos.h | 62 - .../MessageConversion.h | 42 - .../ParameterLoading.h | 30 - .../RosVisualizations.h | 23 - .../launch/convex_plane_decomposition.launch | 14 - .../launch/demo.launch | 52 - .../launch/save_elevation_map.launch | 11 - .../package.xml | 26 - .../rviz/config_demo.rviz | 194 --- .../src/ConvexApproximationDemoNode.cpp | 100 -- .../src/ConvexPlaneDecompositionNode.cpp | 23 - .../src/ConvexPlaneDecompositionRos.cpp | 187 --- .../src/MessageConversion.cpp | 143 -- .../src/ParameterLoading.cpp | 78 - .../src/RosVisualizations.cpp | 159 -- .../src/SaveElevationMapAsImageNode.cpp | 73 - .../src/noiseNode.cpp | 107 -- .../test/TestShapeGrowing.cpp | 46 - .../grid_map_filters_rsl/CMakeLists.txt | 126 -- .../GridMapDerivative.hpp | 75 - .../grid_map_filters_rsl/inpainting.hpp | 54 - .../include/grid_map_filters_rsl/lookup.hpp | 58 - .../grid_map_filters_rsl/processing.hpp | 66 - .../grid_map_filters_rsl/smoothing.hpp | 50 - .../grid_map_filters_rsl/package.xml | 19 - .../src/GridMapDerivative.cpp | 76 - .../grid_map_filters_rsl/src/inpainting.cpp | 290 ---- .../grid_map_filters_rsl/src/lookup.cpp | 106 -- .../grid_map_filters_rsl/src/processing.cpp | 180 --- .../grid_map_filters_rsl/src/smoothing.cpp | 109 -- .../test/TestDerivativeFilter.cpp | 39 - .../grid_map_filters_rsl/test/TestFilters.cpp | 144 -- .../grid_map_filters_rsl/test/TestLookup.cpp | 82 -- .../debug_publisher/image_debug_node.py | 38 - .../semantic_sensor/CMakeLists.txt | 33 - .../config/sensor_parameter.yaml | 31 - .../launch/semantic_image.launch | 7 - .../launch/semantic_pointcloud.launch | 7 - sensor_processing/semantic_sensor/package.xml | 27 - .../script/semantic_sensor/DINO/__init__.py | 0 .../script/semantic_sensor/DINO/modules.py | 126 -- .../script/semantic_sensor/DINO/utils.py | 46 - .../DINO/vision_transformer.py | 385 ----- .../script/semantic_sensor/__init__.py | 0 .../script/semantic_sensor/image_node.py | 294 ---- .../semantic_sensor/image_parameters.py | 42 - .../script/semantic_sensor/networks.py | 291 ---- .../script/semantic_sensor/pointcloud_node.py | 368 ----- .../semantic_sensor/pointcloud_parameters.py | 47 - .../script/semantic_sensor/tests/__init__.py | 0 .../semantic_sensor/tests/test_pointcloud.py | 64 - .../semantic_sensor/tests/test_utils.py | 44 - .../script/semantic_sensor/utils.py | 28 - sensor_processing/semantic_sensor/setup.py | 8 - 212 files changed, 1372 insertions(+), 15388 deletions(-) delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/__init__.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping_ros.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/fusion_manager.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_color.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_average.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_average.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_max.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_color.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/__init__.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_image_kernels.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_kernels.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_semantic_kernels.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/kk.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/map_initializer.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/parameter.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/erosion.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/features_pca.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/inpainting.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/max_layer_filter.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/min_filter.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/plugin_manager.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/robot_centric_elevation.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_filter.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_traversability.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/smooth_filter.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/semantic_map.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/__init__.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_elevation_mapping.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_parameter.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_plugins.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_kernels.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_map.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_filter.py delete mode 100644 elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_polygon.py create mode 100644 elevation_mapping_cupy/config/core/core_param copy 2.yaml create mode 100644 elevation_mapping_cupy/config/core/core_param_sim.yaml rename elevation_mapping_cupy/{build/lib/elevation_mapping_cupy/fusion/image_exponential.py => script/elevation_mapping_cupy/fusion/image_latest.py} (77%) create mode 160000 filters create mode 160000 grid_map create mode 100644 nav2_common/CMakeLists.txt create mode 100644 nav2_common/cmake/nav2_package.cmake create mode 100644 nav2_common/nav2_common-extras.cmake rename {elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion => nav2_common/nav2_common}/__init__.py (100%) create mode 100644 nav2_common/nav2_common/launch/__init__.py create mode 100644 nav2_common/nav2_common/launch/has_node_params.py create mode 100644 nav2_common/nav2_common/launch/parse_multirobot_pose.py create mode 100644 nav2_common/nav2_common/launch/replace_string.py create mode 100644 nav2_common/nav2_common/launch/rewritten_yaml.py create mode 100644 nav2_common/package.xml rename elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/__init__.py => nav2_msgs/CHANGELOG.rst (100%) create mode 100644 nav2_msgs/CMakeLists.txt create mode 100644 nav2_msgs/README.md create mode 100644 nav2_msgs/action/AssistedTeleop.action create mode 100644 nav2_msgs/action/BackUp.action create mode 100644 nav2_msgs/action/ComputePathThroughPoses.action create mode 100644 nav2_msgs/action/ComputePathToPose.action create mode 100644 nav2_msgs/action/DriveOnHeading.action create mode 100644 nav2_msgs/action/DummyBehavior.action create mode 100644 nav2_msgs/action/FollowPath.action create mode 100644 nav2_msgs/action/FollowWaypoints.action create mode 100644 nav2_msgs/action/NavigateThroughPoses.action create mode 100644 nav2_msgs/action/NavigateToPose.action create mode 100644 nav2_msgs/action/SmoothPath.action create mode 100644 nav2_msgs/action/Spin.action create mode 100644 nav2_msgs/action/Wait.action create mode 100644 nav2_msgs/msg/BehaviorTreeLog.msg create mode 100644 nav2_msgs/msg/BehaviorTreeStatusChange.msg create mode 100644 nav2_msgs/msg/CollisionMonitorState.msg create mode 100644 nav2_msgs/msg/Costmap.msg create mode 100644 nav2_msgs/msg/CostmapFilterInfo.msg create mode 100644 nav2_msgs/msg/CostmapMetaData.msg create mode 100644 nav2_msgs/msg/Particle.msg create mode 100644 nav2_msgs/msg/ParticleCloud.msg create mode 100644 nav2_msgs/msg/SpeedLimit.msg create mode 100644 nav2_msgs/msg/VoxelGrid.msg create mode 100644 nav2_msgs/package.xml create mode 100644 nav2_msgs/srv/ClearCostmapAroundRobot.srv create mode 100644 nav2_msgs/srv/ClearCostmapExceptRegion.srv create mode 100644 nav2_msgs/srv/ClearEntireCostmap.srv create mode 100644 nav2_msgs/srv/GetCostmap.srv create mode 100644 nav2_msgs/srv/IsPathValid.srv create mode 100644 nav2_msgs/srv/LoadMap.srv create mode 100644 nav2_msgs/srv/ManageLifecycleNodes.srv create mode 100644 nav2_msgs/srv/SaveMap.srv create mode 100644 nav2_msgs/srv/SetInitialPose.srv create mode 160000 pcl_msgs create mode 160000 perception_pcl delete mode 100644 plane_segmentation/README.md delete mode 100644 plane_segmentation/cgal5_catkin/.gitignore delete mode 100644 plane_segmentation/cgal5_catkin/CMakeLists.txt delete mode 100644 plane_segmentation/cgal5_catkin/README.md delete mode 100644 plane_segmentation/cgal5_catkin/cmake/cgal-extras.cmake.in delete mode 100644 plane_segmentation/cgal5_catkin/package.xml delete mode 100644 plane_segmentation/convex_plane_decomposition/CMakeLists.txt delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/LoadGridmapFromImage.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlaneProjection.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Timer.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/Upsampling.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h delete mode 100644 plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h delete mode 100644 plane_segmentation/convex_plane_decomposition/package.xml delete mode 100644 plane_segmentation/convex_plane_decomposition/src/ConvexRegionGrowing.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/src/Draw.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/src/GridMapPreprocessing.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/src/LoadGridmapFromImage.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/src/PlanarRegion.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/src/PlaneDecompositionPipeline.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/src/Postprocessing.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/src/SegmentedPlaneProjection.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/src/contour_extraction/Upsampling.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/test/data/terrain.png delete mode 100644 plane_segmentation/convex_plane_decomposition/test/testConvexApproximation.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/test/testPipeline.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/test/testPlanarRegion.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/test/testRegionGrowing.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition/test/testUpsampling.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition_msgs/CMakeLists.txt delete mode 100644 plane_segmentation/convex_plane_decomposition_msgs/msg/BoundingBox2d.msg delete mode 100644 plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarRegion.msg delete mode 100644 plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg delete mode 100644 plane_segmentation/convex_plane_decomposition_msgs/msg/Point2d.msg delete mode 100644 plane_segmentation/convex_plane_decomposition_msgs/msg/Polygon2d.msg delete mode 100644 plane_segmentation/convex_plane_decomposition_msgs/msg/PolygonWithHoles2d.msg delete mode 100644 plane_segmentation/convex_plane_decomposition_msgs/package.xml delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/config/demo_node.yaml delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/config/node.yaml delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/holes.png delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/real_stairs_125cm.png delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/slope_1m_1m_20cm.png delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/straight_stairs_1m_1m_60cm.png delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/data/terrain.png delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/launch/save_elevation_map.launch delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/package.xml delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/src/ConvexApproximationDemoNode.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/src/MessageConversion.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/src/ParameterLoading.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/src/noiseNode.cpp delete mode 100644 plane_segmentation/convex_plane_decomposition_ros/test/TestShapeGrowing.cpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/CMakeLists.txt delete mode 100644 plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/GridMapDerivative.hpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/lookup.hpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/processing.hpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/smoothing.hpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/package.xml delete mode 100644 plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/src/lookup.cpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/src/processing.cpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/src/smoothing.cpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/test/TestDerivativeFilter.cpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp delete mode 100644 plane_segmentation/grid_map_filters_rsl/test/TestLookup.cpp delete mode 100644 sensor_processing/debug_publisher/image_debug_node.py delete mode 100644 sensor_processing/semantic_sensor/CMakeLists.txt delete mode 100644 sensor_processing/semantic_sensor/config/sensor_parameter.yaml delete mode 100644 sensor_processing/semantic_sensor/launch/semantic_image.launch delete mode 100644 sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch delete mode 100644 sensor_processing/semantic_sensor/package.xml delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/DINO/__init__.py delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/DINO/utils.py delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/__init__.py delete mode 100755 sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/networks.py delete mode 100755 sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/tests/__init__.py delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py delete mode 100644 sensor_processing/semantic_sensor/script/semantic_sensor/utils.py delete mode 100644 sensor_processing/semantic_sensor/setup.py diff --git a/elevation_map_msgs/srv/CheckSafety.srv b/elevation_map_msgs/srv/CheckSafety.srv index ed864d4a..871b9b54 100644 --- a/elevation_map_msgs/srv/CheckSafety.srv +++ b/elevation_map_msgs/srv/CheckSafety.srv @@ -1,7 +1,6 @@ # Polygons to check geometry_msgs/PolygonStamped[] polygons bool compute_untraversable_polygon - # Results --- bool[] is_safe diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index 9925bc5d..20e8ab7f 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -70,6 +70,7 @@ include_directories( ${Eigen3_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${pybind11_INCLUDE_DIRS} + ${elevation_map_msgs_INCLUDE_DIRS} ) # Declare C++ library diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/__init__.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/__init__.py deleted file mode 100644 index 88d6a666..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# from .parameter import Parameter -# from .elevation_mapping import ElevationMap -# from .kernels import custom_image_kernels, custom_kernels, custom_semantic_kernels - diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping.py deleted file mode 100644 index 06f81dfb..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping.py +++ /dev/null @@ -1,970 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import os -from typing import List, Any, Tuple, Union - -import numpy as np -import threading -import subprocess - -from elevation_mapping_cupy.traversability_filter import ( - get_filter_chainer, - get_filter_torch, -) -from elevation_mapping_cupy.parameter import Parameter - - -from elevation_mapping_cupy.kernels import ( - add_points_kernel, - add_color_kernel, - color_average_kernel, -) -from elevation_mapping_cupy.kernels import sum_kernel -from elevation_mapping_cupy.kernels import error_counting_kernel -from elevation_mapping_cupy.kernels import average_map_kernel -from elevation_mapping_cupy.kernels import dilation_filter_kernel -from elevation_mapping_cupy.kernels import normal_filter_kernel -from elevation_mapping_cupy.kernels import polygon_mask_kernel -from elevation_mapping_cupy.kernels import image_to_map_correspondence_kernel - -from elevation_mapping_cupy.map_initializer import MapInitializer -from elevation_mapping_cupy.plugins.plugin_manager import PluginManager -from elevation_mapping_cupy.semantic_map import SemanticMap -from elevation_mapping_cupy.traversability_polygon import ( - get_masked_traversability, - is_traversable, - calculate_area, - transform_to_map_position, - transform_to_map_index, -) - -import cupy as cp - -xp = cp -pool = cp.cuda.MemoryPool(cp.cuda.malloc_managed) -cp.cuda.set_allocator(pool.malloc) - - -class ElevationMap: - """Core elevation mapping class.""" - - def __init__(self, param: Parameter): - """ - - Args: - param (elevation_mapping_cupy.parameter.Parameter): - """ - self.param = param - self.data_type = self.param.data_type - self.resolution = param.resolution - self.center = xp.array([0, 0, 0], dtype=self.data_type) - self.base_rotation = xp.eye(3, dtype=self.data_type) - self.map_length = param.map_length - self.cell_n = param.cell_n - - self.map_lock = threading.Lock() - self.semantic_map = SemanticMap(self.param) - self.elevation_map = xp.zeros((7, self.cell_n, self.cell_n), dtype=self.data_type) - self.layer_names = [ - "elevation", - "variance", - "is_valid", - "traversability", - "time", - "upper_bound", - "is_upper_bound", - ] - - # buffers - self.traversability_buffer = xp.full((self.cell_n, self.cell_n), xp.nan) - self.normal_map = xp.zeros((3, self.cell_n, self.cell_n), dtype=self.data_type) - # Initial variance - self.initial_variance = param.initial_variance - self.elevation_map[1] += self.initial_variance - self.elevation_map[3] += 1.0 - - # # overlap clearance - cell_range = int(self.param.overlap_clear_range_xy / self.resolution) - cell_range = np.clip(cell_range, 0, self.cell_n) - self.cell_min = self.cell_n // 2 - cell_range // 2 - self.cell_max = self.cell_n // 2 + cell_range // 2 - - # Initial mean_error - self.mean_error = 0.0 - self.additive_mean_error = 0.0 - - - self.compile_kernels() - - # self.compile_image_kernels() - - # self.semantic_map.initialize_fusion() - - # weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') - # param.load_weights(weight_file) - - # if param.use_chainer: - # self.traversability_filter = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) - # else: - # self.traversability_filter = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) - # self.untraversable_polygon = xp.zeros((1, 2)) - - # # Plugins - # self.plugin_manager = PluginManager(cell_n=self.cell_n) - # plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') - # self.plugin_manager.load_plugin_settings(plugin_config_file) - - # self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") - - def clear(self): - """Reset all the layers of the elevation & the semantic map.""" - with self.map_lock: - self.elevation_map *= 0.0 - # Initial variance - self.elevation_map[1] += self.initial_variance - self.semantic_map.clear() - - self.mean_error = 0.0 - self.additive_mean_error = 0.0 - - def get_position(self, position): - """Return the position of the map center. - - Args: - position (numpy.ndarray): - - """ - position[0][:] = xp.asnumpy(self.center) - - def move(self, delta_position): - """Shift the map along all three axes according to the input. - - Args: - delta_position (numpy.ndarray): - """ - # Shift map using delta position. - delta_position = xp.asarray(delta_position) - delta_pixel = xp.round(delta_position[:2] / self.resolution) - delta_position_xy = delta_pixel * self.resolution - self.center[:2] += xp.asarray(delta_position_xy) - self.center[2] += xp.asarray(delta_position[2]) - self.shift_map_xy(delta_pixel) - self.shift_map_z(-delta_position[2]) - - def move_to(self, position, R): - """Shift the map to an absolute position and update the rotation of the robot. - - Args: - position (numpy.ndarray): - R (cupy._core.core.ndarray): - """ - # Shift map to the center of robot. - self.base_rotation = xp.asarray(R, dtype=self.data_type) - position = xp.asarray(position) - delta = position - self.center - delta_pixel = xp.around(delta[:2] / self.resolution) - delta_xy = delta_pixel * self.resolution - self.center[:2] += delta_xy - self.center[2] += delta[2] - self.shift_map_xy(-delta_pixel) - self.shift_map_z(-delta[2]) - - def pad_value(self, x, shift_value, idx=None, value=0.0): - """Create a padding of the map along x,y-axis according to amount that has shifted. - - Args: - x (cupy._core.core.ndarray): - shift_value (cupy._core.core.ndarray): - idx (Union[None, int, None, None]): - value (float): - """ - if idx is None: - if shift_value[0] > 0: - x[:, : shift_value[0], :] = value - elif shift_value[0] < 0: - x[:, shift_value[0] :, :] = value - if shift_value[1] > 0: - x[:, :, : shift_value[1]] = value - elif shift_value[1] < 0: - x[:, :, shift_value[1] :] = value - else: - if shift_value[0] > 0: - x[idx, : shift_value[0], :] = value - elif shift_value[0] < 0: - x[idx, shift_value[0] :, :] = value - if shift_value[1] > 0: - x[idx, :, : shift_value[1]] = value - elif shift_value[1] < 0: - x[idx, :, shift_value[1] :] = value - - def shift_map_xy(self, delta_pixel): - """Shift the map along the horizontal axes according to the input. - - Args: - delta_pixel (cupy._core.core.ndarray): - - """ - shift_value = delta_pixel.astype(cp.int32) - if cp.abs(shift_value).sum() == 0: - return - with self.map_lock: - self.elevation_map = cp.roll(self.elevation_map, shift_value, axis=(1, 2)) - self.pad_value(self.elevation_map, shift_value, value=0.0) - self.pad_value(self.elevation_map, shift_value, idx=1, value=self.initial_variance) - self.semantic_map.shift_map_xy(shift_value) - - def shift_map_z(self, delta_z): - """Shift the relevant layers along the vertical axis. - - Args: - delta_z (cupy._core.core.ndarray): - """ - with self.map_lock: - # elevation - self.elevation_map[0] += delta_z - # upper bound - self.elevation_map[5] += delta_z - - def compile_kernels(self): - """Compile all kernels belonging to the elevation map.""" - - self.new_map = cp.zeros( - (self.elevation_map.shape[0], self.cell_n, self.cell_n), - dtype=self.data_type, - ) - self.traversability_input = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) - self.traversability_mask_dummy = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) - self.min_filtered = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) - self.min_filtered_mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) - self.mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) - self.add_points_kernel = add_points_kernel( - self.resolution, - self.cell_n, - self.cell_n, - self.param.sensor_noise_factor, - self.param.mahalanobis_thresh, - self.param.outlier_variance, - self.param.wall_num_thresh, - self.param.max_ray_length, - self.param.cleanup_step, - self.param.min_valid_distance, - self.param.max_height_range, - self.param.cleanup_cos_thresh, - self.param.ramped_height_range_a, - self.param.ramped_height_range_b, - self.param.ramped_height_range_c, - self.param.enable_edge_sharpen, - self.param.enable_visibility_cleanup, - ) - self.error_counting_kernel = error_counting_kernel( - self.resolution, - self.cell_n, - self.cell_n, - self.param.sensor_noise_factor, - self.param.mahalanobis_thresh, - self.param.drift_compensation_variance_inlier, - self.param.traversability_inlier, - self.param.min_valid_distance, - self.param.max_height_range, - self.param.ramped_height_range_a, - self.param.ramped_height_range_b, - self.param.ramped_height_range_c, - ) - self.average_map_kernel = average_map_kernel( - self.cell_n, self.cell_n, self.param.max_variance, self.initial_variance - ) - - self.dilation_filter_kernel = dilation_filter_kernel(self.cell_n, self.cell_n, self.param.dilation_size) - self.dilation_filter_kernel_initializer = dilation_filter_kernel( - self.cell_n, self.cell_n, self.param.dilation_size_initialize - ) - self.polygon_mask_kernel = polygon_mask_kernel(self.cell_n, self.cell_n, self.resolution) - self.normal_filter_kernel = normal_filter_kernel(self.cell_n, self.cell_n, self.resolution) - - def compile_image_kernels(self): - """Compile kernels related to processing image messages.""" - - for config in self.param.subscriber_cfg.values(): - if config["data_type"] == "image": - self.valid_correspondence = cp.asarray( - np.zeros((self.cell_n, self.cell_n), dtype=np.bool_), dtype=np.bool_ - ) - self.uv_correspondence = cp.asarray( - np.zeros((2, self.cell_n, self.cell_n), dtype=np.float32), - dtype=np.float32, - ) - # self.distance_correspondence = cp.asarray( - # np.zeros((self.cell_n, self.cell_n), dtype=np.float32), dtype=np.float32 - # ) - # TODO tolerance_z_collision add parameter - self.image_to_map_correspondence_kernel = image_to_map_correspondence_kernel( - resolution=self.resolution, - width=self.cell_n, - height=self.cell_n, - tolerance_z_collision=0.10, - ) - break - - def shift_translation_to_map_center(self, t): - """Deduct the map center to get the translation of a point w.r.t. the map center. - - Args: - t (cupy._core.core.ndarray): Absolute point position - """ - t -= self.center - - def update_map_with_kernel(self, points_all, channels, R, t, position_noise, orientation_noise): - """Update map with new measurement. - - Args: - points_all (cupy._core.core.ndarray): - channels (List[str]): - R (cupy._core.core.ndarray): - t (cupy._core.core.ndarray): - position_noise (float): - orientation_noise (float): - """ - self.new_map *= 0.0 - error = cp.array([0.0], dtype=cp.float32) - error_cnt = cp.array([0], dtype=cp.float32) - points = points_all[:, :3] - # additional_fusion = self.get_fusion_of_pcl(channels) - with self.map_lock: - self.shift_translation_to_map_center(t) - self.error_counting_kernel( - self.elevation_map, - points, - cp.array([0.0], dtype=self.data_type), - cp.array([0.0], dtype=self.data_type), - R, - t, - self.new_map, - error, - error_cnt, - size=(points.shape[0]), - ) - if ( - self.param.enable_drift_compensation - and error_cnt > self.param.min_height_drift_cnt - and ( - position_noise > self.param.position_noise_thresh - or orientation_noise > self.param.orientation_noise_thresh - ) - ): - self.mean_error = error / error_cnt - self.additive_mean_error += self.mean_error - if np.abs(self.mean_error) < self.param.max_drift: - self.elevation_map[0] += self.mean_error * self.param.drift_compensation_alpha - self.add_points_kernel( - cp.array([0.0], dtype=self.data_type), - cp.array([0.0], dtype=self.data_type), - R, - t, - self.normal_map, - points, - self.elevation_map, - self.new_map, - size=(points.shape[0]), - ) - self.average_map_kernel(self.new_map, self.elevation_map, size=(self.cell_n * self.cell_n)) - - self.semantic_map.update_layers_pointcloud(points_all, channels, R, t, self.new_map) - - if self.param.enable_overlap_clearance: - self.clear_overlap_map(t) - # dilation before traversability_filter - self.traversability_input *= 0.0 - self.dilation_filter_kernel( - self.elevation_map[5], - self.elevation_map[2] + self.elevation_map[6], - self.traversability_input, - self.traversability_mask_dummy, - size=(self.cell_n * self.cell_n), - ) - # calculate traversability - traversability = self.traversability_filter(self.traversability_input) - self.elevation_map[3][3:-3, 3:-3] = traversability.reshape( - (traversability.shape[2], traversability.shape[3]) - ) - - # calculate normal vectors - self.update_normal(self.traversability_input) - - def clear_overlap_map(self, t): - """Clear overlapping areas around the map center. - - Args: - t (cupy._core.core.ndarray): Absolute point position - """ - - height_min = t[2] - self.param.overlap_clear_range_z - height_max = t[2] + self.param.overlap_clear_range_z - near_map = self.elevation_map[:, self.cell_min : self.cell_max, self.cell_min : self.cell_max] - valid_idx = ~cp.logical_or(near_map[0] < height_min, near_map[0] > height_max) - near_map[0] = cp.where(valid_idx, near_map[0], 0.0) - near_map[1] = cp.where(valid_idx, near_map[1], self.initial_variance) - near_map[2] = cp.where(valid_idx, near_map[2], 0.0) - valid_idx = ~cp.logical_or(near_map[5] < height_min, near_map[5] > height_max) - near_map[5] = cp.where(valid_idx, near_map[5], 0.0) - near_map[6] = cp.where(valid_idx, near_map[6], 0.0) - self.elevation_map[:, self.cell_min : self.cell_max, self.cell_min : self.cell_max] = near_map - - def get_additive_mean_error(self): - """Returns the additive mean error. - - Returns: - - """ - return self.additive_mean_error - - def update_variance(self): - """Adds the time variacne to the valid cells.""" - self.elevation_map[1] += self.param.time_variance * self.elevation_map[2] - - def update_time(self): - """adds the time interval to the time layer.""" - self.elevation_map[4] += self.param.time_interval - - def update_upper_bound_with_valid_elevation(self): - """Filters all invalid cell's upper_bound and is_upper_bound layers.""" - mask = self.elevation_map[2] > 0.5 - self.elevation_map[5] = cp.where(mask, self.elevation_map[0], self.elevation_map[5]) - self.elevation_map[6] = cp.where(mask, 0.0, self.elevation_map[6]) - - def input_pointcloud( - self, - raw_points: cp._core.core.ndarray, - channels: List[str], - R: cp._core.core.ndarray, - t: cp._core.core.ndarray, - position_noise: float, - orientation_noise: float, - ): - """Input the point cloud and fuse the new measurements to update the elevation map. - - Args: - raw_points (cupy._core.core.ndarray): - channels (List[str]): - R (cupy._core.core.ndarray): - t (cupy._core.core.ndarray): - position_noise (float): - orientation_noise (float): - - Returns: - None: - """ - raw_points = cp.asarray(raw_points, dtype=self.data_type) - additional_channels = channels[3:] - raw_points = raw_points[~cp.isnan(raw_points[:, :3]).any(axis=1)] - self.update_map_with_kernel( - raw_points, - additional_channels, - cp.asarray(R, dtype=self.data_type), - cp.asarray(t, dtype=self.data_type), - position_noise, - orientation_noise, - ) - - def input_image( - self, - image: List[cp._core.core.ndarray], - channels: List[str], - # fusion_methods: List[str], - R: cp._core.core.ndarray, - t: cp._core.core.ndarray, - K: cp._core.core.ndarray, - D: cp._core.core.ndarray, - distortion_model: str, - image_height: int, - image_width: int, - ): - """Input image and fuse the new measurements to update the elevation map. - - Args: - sub_key (str): Key used to identify the subscriber configuration - image (List[cupy._core.core.ndarray]): List of array containing the individual image input channels - R (cupy._core.core.ndarray): Camera optical center rotation - t (cupy._core.core.ndarray): Camera optical center translation - K (cupy._core.core.ndarray): Camera intrinsics - image_height (int): Image height - image_width (int): Image width - - Returns: - None: - """ - - image = np.stack(image, axis=0) - if len(image.shape) == 2: - image = image[None] - - # Convert to cupy - image = cp.asarray(image, dtype=self.data_type) - K = cp.asarray(K, dtype=self.data_type) - R = cp.asarray(R, dtype=self.data_type) - t = cp.asarray(t, dtype=self.data_type) - D = cp.asarray(D, dtype=self.data_type) - image_height = cp.float32(image_height) - image_width = cp.float32(image_width) - - if len(D) < 4: - D = cp.zeros(5, dtype=self.data_type) - elif len(D) == 4: - D = cp.concatenate([D, cp.zeros(1, dtype=self.data_type)]) - else: - D = D[:5] - - if distortion_model == "radtan": - pass - elif distortion_model == "equidistant": - # Not implemented yet. - D *= 0 - elif distortion_model == "plumb_bob": - # Not implemented yet. - D *= 0 - else: - # Not implemented yet. - D *= 0 - - # Calculate transformation matrix - P = cp.asarray(K @ cp.concatenate([R, t[:, None]], 1), dtype=np.float32) - t_cam_map = -R.T @ t - self.center - t_cam_map = t_cam_map.get() - x1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[0]) / self.resolution)) - y1 = cp.uint32((self.cell_n / 2) + ((t_cam_map[1]) / self.resolution)) - z1 = cp.float32(t_cam_map[2]) - - self.uv_correspondence *= 0 - self.valid_correspondence[:, :] = False - - with self.map_lock: - self.image_to_map_correspondence_kernel( - self.elevation_map, - x1, - y1, - z1, - P.reshape(-1), - K.reshape(-1), - D.reshape(-1), - image_height, - image_width, - self.center, - self.uv_correspondence, - self.valid_correspondence, - size=int(self.cell_n * self.cell_n), - ) - self.semantic_map.update_layers_image( - image, - channels, - self.uv_correspondence, - self.valid_correspondence, - image_height, - image_width, - ) - - def update_normal(self, dilated_map): - """Clear the normal map and then apply the normal kernel with dilated map as input. - - Args: - dilated_map (cupy._core.core.ndarray): - """ - with self.map_lock: - self.normal_map *= 0.0 - self.normal_filter_kernel( - dilated_map, - self.elevation_map[2], - self.normal_map, - size=(self.cell_n * self.cell_n), - ) - - def process_map_for_publish(self, input_map, fill_nan=False, add_z=False, xp=cp): - """Process the input_map according to the fill_nan and add_z flags. - - Args: - input_map (cupy._core.core.ndarray): - fill_nan (bool): - add_z (bool): - xp (module): - - Returns: - cupy._core.core.ndarray: - """ - m = input_map.copy() - if fill_nan: - m = xp.where(self.elevation_map[2] > 0.5, m, xp.nan) - if add_z: - m = m + self.center[2] - return m[1:-1, 1:-1] - - def get_elevation(self): - """Get the elevation layer. - - Returns: - elevation layer - - """ - return self.process_map_for_publish(self.elevation_map[0], fill_nan=True, add_z=True) - - def get_variance(self): - """Get the variance layer. - - Returns: - variance layer - """ - return self.process_map_for_publish(self.elevation_map[1], fill_nan=False, add_z=False) - - def get_traversability(self): - """Get the traversability layer. - - Returns: - traversability layer - """ - traversability = cp.where( - (self.elevation_map[2] + self.elevation_map[6]) > 0.5, - self.elevation_map[3].copy(), - cp.nan, - ) - self.traversability_buffer[3:-3, 3:-3] = traversability[3:-3, 3:-3] - traversability = self.traversability_buffer[1:-1, 1:-1] - return traversability - - def get_time(self): - """Get the time layer. - - Returns: - time layer - """ - return self.process_map_for_publish(self.elevation_map[4], fill_nan=False, add_z=False) - - def get_upper_bound(self): - """Get the upper bound layer. - - Returns: - upper_bound: upper bound layer - """ - if self.param.use_only_above_for_upper_bound: - valid = cp.logical_or( - cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), - self.elevation_map[2] > 0.5, - ) - else: - valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) - upper_bound = cp.where(valid, self.elevation_map[5].copy(), cp.nan) - upper_bound = upper_bound[1:-1, 1:-1] + self.center[2] - return upper_bound - - def get_is_upper_bound(self): - """Get the is upper bound layer. - - Returns: - is_upper_bound: layer - """ - if self.param.use_only_above_for_upper_bound: - valid = cp.logical_or( - cp.logical_and(self.elevation_map[5] > 0.0, self.elevation_map[6] > 0.5), - self.elevation_map[2] > 0.5, - ) - else: - valid = cp.logical_or(self.elevation_map[2] > 0.5, self.elevation_map[6] > 0.5) - is_upper_bound = cp.where(valid, self.elevation_map[6].copy(), cp.nan) - is_upper_bound = is_upper_bound[1:-1, 1:-1] - return is_upper_bound - - def xp_of_array(self, array): - """Indicate which library is used for xp. - - Args: - array (cupy._core.core.ndarray): - - Returns: - module: either np or cp - """ - if type(array) == cp.ndarray: - return cp - elif type(array) == np.ndarray: - return np - - def copy_to_cpu(self, array, data, stream=None): - """Transforms the data to float32 and if on gpu loads it to cpu. - - Args: - array (cupy._core.core.ndarray): - data (numpy.ndarray): - stream (Union[None, cupy.cuda.stream.Stream, None, None, None, None, None, None, None]): - """ - if type(array) == np.ndarray: - data[...] = array.astype(np.float32) - elif type(array) == cp.ndarray: - if stream is not None: - data[...] = cp.asnumpy(array.astype(np.float32), stream=stream) - else: - data[...] = cp.asnumpy(array.astype(np.float32)) - - def exists_layer(self, name): - """Check if the layer exists in elevation map or in the semantic map. - - Args: - name (str): Layer name - - Returns: - bool: Indicates if layer exists. - """ - if name in self.layer_names: - return True - elif name in self.semantic_map.layer_names: - return True - elif name in self.plugin_manager.layer_names: - return True - else: - return False - - def get_map_with_name_ref(self, name, data): - """Load a layer according to the name input to the data input. - - Args: - name (str): Name of the layer. - data (numpy.ndarray): Data structure that contains layer. - - """ - use_stream = True - xp = cp - with self.map_lock: - if name == "elevation": - m = self.get_elevation() - use_stream = False - elif name == "variance": - m = self.get_variance() - elif name == "traversability": - m = self.get_traversability() - elif name == "time": - m = self.get_time() - elif name == "upper_bound": - m = self.get_upper_bound() - elif name == "is_upper_bound": - m = self.get_is_upper_bound() - elif name == "normal_x": - m = self.normal_map.copy()[0, 1:-1, 1:-1] - elif name == "normal_y": - m = self.normal_map.copy()[1, 1:-1, 1:-1] - elif name == "normal_z": - m = self.normal_map.copy()[2, 1:-1, 1:-1] - elif name in self.semantic_map.layer_names: - m = self.semantic_map.get_map_with_name(name) - elif name in self.plugin_manager.layer_names: - self.plugin_manager.update_with_name( - name, - self.elevation_map, - self.layer_names, - self.semantic_map.semantic_map, - self.semantic_map.layer_names, - self.base_rotation, - self.semantic_map.elements_to_shift, - ) - m = self.plugin_manager.get_map_with_name(name) - p = self.plugin_manager.get_param_with_name(name) - xp = self.xp_of_array(m) - m = self.process_map_for_publish(m, fill_nan=p.fill_nan, add_z=p.is_height_layer, xp=xp) - else: - print("Layer {} is not in the map".format(name)) - return - m = xp.flip(m, 0) - m = xp.flip(m, 1) - if use_stream: - stream = cp.cuda.Stream(non_blocking=False) - else: - stream = None - self.copy_to_cpu(m, data, stream=stream) - - def get_normal_maps(self): - """Get the normal maps. - - Returns: - maps: the three normal values for each cell - """ - normal = self.normal_map.copy() - normal_x = normal[0, 1:-1, 1:-1] - normal_y = normal[1, 1:-1, 1:-1] - normal_z = normal[2, 1:-1, 1:-1] - maps = xp.stack([normal_x, normal_y, normal_z], axis=0) - maps = xp.flip(maps, 1) - maps = xp.flip(maps, 2) - maps = xp.asnumpy(maps) - return maps - - def get_normal_ref(self, normal_x_data, normal_y_data, normal_z_data): - """Get the normal maps as reference. - - Args: - normal_x_data: - normal_y_data: - normal_z_data: - """ - maps = self.get_normal_maps() - self.stream = cp.cuda.Stream(non_blocking=True) - normal_x_data[...] = xp.asnumpy(maps[0], stream=self.stream) - normal_y_data[...] = xp.asnumpy(maps[1], stream=self.stream) - normal_z_data[...] = xp.asnumpy(maps[2], stream=self.stream) - - def get_layer(self, name): - """Return the layer with the name input. - - Args: - name: The layers name. - - Returns: - return_map: The rqeuested layer. - - """ - if name in self.layer_names: - idx = self.layer_names.index(name) - return_map = self.elevation_map[idx] - elif name in self.semantic_map.layer_names: - idx = self.semantic_map.layer_names.index(name) - return_map = self.semantic_map.semantic_map[idx] - elif name in self.plugin_manager.layer_names: - self.plugin_manager.update_with_name( - name, - self.elevation_map, - self.layer_names, - self.semantic_map, - self.base_rotation, - ) - return_map = self.plugin_manager.get_map_with_name(name) - else: - print("Layer {} is not in the map, returning traversabiltiy!".format(name)) - return - return return_map - - def get_polygon_traversability(self, polygon, result): - """Check if input polygons are traversable. - - Args: - polygon (cupy._core.core.ndarray): - result (numpy.ndarray): - - Returns: - Union[None, int]: - """ - polygon = xp.asarray(polygon) - area = calculate_area(polygon) - polygon = polygon.astype(self.data_type) - pmin = self.center[:2] - self.map_length / 2 + self.resolution - pmax = self.center[:2] + self.map_length / 2 - self.resolution - polygon[:, 0] = polygon[:, 0].clip(pmin[0], pmax[0]) - polygon[:, 1] = polygon[:, 1].clip(pmin[1], pmax[1]) - polygon_min = polygon.min(axis=0) - polygon_max = polygon.max(axis=0) - polygon_bbox = cp.concatenate([polygon_min, polygon_max]).flatten() - polygon_n = xp.array(polygon.shape[0], dtype=np.int16) - clipped_area = calculate_area(polygon) - self.polygon_mask_kernel( - polygon, - self.center[0], - self.center[1], - polygon_n, - polygon_bbox, - self.mask, - size=(self.cell_n * self.cell_n), - ) - tmp_map = self.get_layer(self.param.checker_layer) - masked, masked_isvalid = get_masked_traversability(self.elevation_map, self.mask, tmp_map) - if masked_isvalid.sum() > 0: - t = masked.sum() / masked_isvalid.sum() - else: - t = cp.asarray(0.0, dtype=self.data_type) - is_safe, un_polygon = is_traversable( - masked, - self.param.safe_thresh, - self.param.safe_min_thresh, - self.param.max_unsafe_n, - ) - untraversable_polygon_num = 0 - if un_polygon is not None: - un_polygon = transform_to_map_position(un_polygon, self.center[:2], self.cell_n, self.resolution) - untraversable_polygon_num = un_polygon.shape[0] - if clipped_area < 0.001: - is_safe = False - print("requested polygon is outside of the map") - result[...] = np.array([is_safe, t.get(), area.get()]) - self.untraversable_polygon = un_polygon - return untraversable_polygon_num - - def get_untraversable_polygon(self, untraversable_polygon): - """Copy the untraversable polygons to input untraversable_polygons. - - Args: - untraversable_polygon (numpy.ndarray): - """ - untraversable_polygon[...] = xp.asnumpy(self.untraversable_polygon) - - def initialize_map(self, points, method="cubic"): - """Initializes the map according to some points and using an approximation according to method. - - Args: - points (numpy.ndarray): - method (str): Interpolation method ['linear', 'cubic', 'nearest'] - """ - self.clear() - with self.map_lock: - points = cp.asarray(points, dtype=self.data_type) - indices = transform_to_map_index(points[:, :2], self.center[:2], self.cell_n, self.resolution) - points[:, :2] = indices.astype(points.dtype) - points[:, 2] -= self.center[2] - self.map_initializer(self.elevation_map, points, method) - if self.param.dilation_size_initialize > 0: - for i in range(2): - self.dilation_filter_kernel_initializer( - self.elevation_map[0], - self.elevation_map[2], - self.elevation_map[0], - self.elevation_map[2], - size=(self.cell_n * self.cell_n), - ) - self.update_upper_bound_with_valid_elevation() - - -if __name__ == "__main__": - # Test script for profiling. - # $ python -m cProfile -o profile.stats elevation_mapping.py - # $ snakeviz profile.stats - xp.random.seed(123) - R = xp.random.rand(3, 3) - t = xp.random.rand(3) - print(R, t) - param = Parameter( - use_chainer=False, - weight_file="/home/hojin/new_elev/src/elevation_mapping_cupy/elevation_mapping_cupy/config/core/weights.dat", - plugin_config_file="/home/hojin/new_elev/src/elevation_mapping_cupy/elevation_mapping_cupy/config/core/plugin_config.yaml", - ) - param.additional_layers = ["rgb", "grass", "tree", "people"] - # param.fusion_algorithms = ["color", "class_bayesian", "class_bayesian", "class_bayesian"] - param.fusion_algorithms = ["image_color", "pointcloud_color", "pointcloud_class_average"] - param.update() - elevation = ElevationMap(param) - layers = [ - "elevation", - "variance", - "traversability", - "min_filter", - "smooth", - "inpaint", - "rgb", - ] - points = xp.random.rand(100000, len(layers)) - - channels = ["x", "y", "z"] + param.additional_layers - print(channels) - data = np.zeros((elevation.cell_n - 2, elevation.cell_n - 2), dtype=np.float32) - for i in range(50): - elevation.input_pointcloud(points, channels, R, t, 0, 0) - elevation.update_normal(elevation.elevation_map[0]) - pos = np.array([i * 0.01, i * 0.02, i * 0.01]) - elevation.move_to(pos, R) - for layer in layers: - elevation.get_map_with_name_ref(layer, data) - print(i) - polygon = cp.array([[0, 0], [2, 0], [0, 2]], dtype=param.data_type) - result = np.array([0, 0, 0]) - elevation.get_polygon_traversability(polygon, result) - print(result) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping_ros.py deleted file mode 100644 index 94cc1e5c..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/elevation_mapping_ros.py +++ /dev/null @@ -1,322 +0,0 @@ -# # General -# import os -# import numpy as np -# import yaml - -# from elevation_mapping_cupy import ElevationMap, Parameter - - - -# # ROS2 -# import rclpy -# from rclpy.node import Node -# from tf_transformations import quaternion_matrix -# import tf2_ros -# from ament_index_python.packages import get_package_share_directory -# from cv_bridge import CvBridge - -# from sensor_msgs.msg import PointCloud2, Image, CameraInfo -# from grid_map_msgs.msg import GridMap -# from std_msgs.msg import Float32MultiArray, MultiArrayLayout as MAL, MultiArrayDimension as MAD - -# from functools import partial -# import message_filters - - -# PDC_DATATYPE = { -# "1": np.int8, -# "2": np.uint8, -# "3": np.int16, -# "4": np.uint16, -# "5": np.int32, -# "6": np.uint32, -# "7": np.float32, -# "8": np.float64, -# } - - -# class ElevationMapWrapper(Node): -# def __init__(self): -# super().__init__('elevation_mapping') -# self.node_name = "elevation_mapping" -# self.root = get_package_share_directory("elevation_mapping_cupy") -# weight_file = os.path.join(self.root, "config/core/weights.dat") -# plugin_config_file = os.path.join(self.root, "config/core/plugin_config.yaml") -# self.param = Parameter(use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file) - -# # ROS2 -# self.initialize_ros() -# self.param.subscriber_cfg = self.subscribers - -# self.initialize_elevation_mapping() -# # self.register_subscribers() -# # self.register_publishers() -# # self.register_timers() - -# self._last_t = None - - - - -# # # ROS -# # self.initalize_ros() -# # self.param.subscriber_cfg = self.subscribers - - -# def initialize_ros(self): -# self._tf_buffer = tf2_ros.Buffer() -# self._listener = tf2_ros.TransformListener(self._tf_buffer, self) -# self.get_ros_params() - - -# def initialize_elevation_mapping(self): -# self.param.update() -# # TODO add statistics across processed topics -# self._pointcloud_process_counter = 0 -# self._image_process_counter = 0 -# self._map = ElevationMap(self.param) -# self._map_data = np.zeros((self._map.cell_n - 2, self._map.cell_n - 2), dtype=np.float32) -# self._map_q = None -# self._map_t = None - - - - -# # def register_subscribers(self): -# # # check if CV bridge is needed -# # for config in self.param.subscriber_cfg.values(): -# # if config["data_type"] == "image": -# # self.cv_bridge = CvBridge() -# # break - -# # pointcloud_subs = {} -# # image_subs = {} -# # for key, config in self.subscribers.items(): -# # if config["data_type"] == "image": -# # camera_sub = message_filters.Subscriber(config["topic_name_camera"], Image) -# # camera_info_sub = message_filters.Subscriber(config["topic_name_camera_info"], CameraInfo) -# # image_subs[key] = message_filters.ApproximateTimeSynchronizer( -# # [camera_sub, camera_info_sub], queue_size=10, slop=0.5 -# # ) -# # image_subs[key].registerCallback(self.image_callback, key) - -# # elif config["data_type"] == "pointcloud": -# # pointcloud_subs[key] = rospy.Subscriber( -# # config["topic_name"], PointCloud2, self.pointcloud_callback, key -# # ) - -# # def register_publishers(self): -# # self._publishers = {} -# # self._publishers_timers = [] -# # for k, v in self.publishers.items(): -# # self._publishers[k] = rospy.Publisher(f"/{self.node_name}/{k}", GridMap, queue_size=10) -# # # partial(.) allows to pass a default argument to a callback -# # self._publishers_timers.append(rospy.Timer(rospy.Duration(1 / v["fps"]), partial(self.publish_map, k))) - -# # def publish_map(self, k, t): -# # print("publish_map") -# # if self._map_q is None: -# # return -# # gm = GridMap() -# # gm.info.header.frame_id = self.map_frame -# # gm.info.header.stamp = rospy.Time.now() -# # gm.info.header.seq = 0 -# # gm.info.resolution = self._map.resolution -# # gm.info.length_x = self._map.map_length -# # gm.info.length_y = self._map.map_length -# # gm.info.pose.position.x = self._map_t.x -# # gm.info.pose.position.y = self._map_t.y -# # gm.info.pose.position.z = 0.0 -# # gm.info.pose.orientation.w = 1.0 # self._map_q.w -# # gm.info.pose.orientation.x = 0.0 # self._map_q.x -# # gm.info.pose.orientation.y = 0.0 # self._map_q.y -# # gm.info.pose.orientation.z = 0.0 # self._map_q.z -# # gm.layers = [] -# # gm.basic_layers = self.publishers[k]["basic_layers"] -# # for i, layer in enumerate(self.publishers[k]["layers"]): -# # gm.layers.append(layer) -# # try: -# # self._map.get_map_with_name_ref(layer, self._map_data) -# # data = self._map_data.copy() -# # arr = Float32MultiArray() -# # arr.layout = MAL() -# # N = self._map_data.shape[0] -# # arr.layout.dim.append(MAD(label="column_index", size=N, stride=int(N * N))) -# # arr.layout.dim.append(MAD(label="row_index", size=N, stride=N)) -# # arr.data = tuple(np.ascontiguousarray(data.T).reshape(-1)) -# # gm.data.append(arr) -# # except: -# # if layer in gm.basic_layers: -# # print("Error: Missed Layer in basic layers") - -# # gm.outer_start_index = 0 -# # gm.inner_start_index = 0 - -# # self._publishers[k].publish(gm) - -# # def register_timers(self): -# # self.timer_variance = rospy.Timer(rospy.Duration(1 / self.update_variance_fps), self.update_variance) -# # self.timer_pose = rospy.Timer(rospy.Duration(1 / self.update_pose_fps), self.update_pose) -# # self.timer_time = rospy.Timer(rospy.Duration(self.time_interval), self.update_time) - -# # def image_callback(self, camera_msg, camera_info_msg, sub_key): -# # # get pose of image -# # ti = rospy.Time(secs=camera_msg.header.stamp.secs, nsecs=camera_msg.header.stamp.nsecs) -# # self._last_t = ti -# # try: -# # transform = self._tf_buffer.lookup_transform( -# # camera_msg.header.frame_id, self.map_frame, ti, rospy.Duration(1.0) -# # ) -# # except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: -# # print("Error: image_callback:", e) -# # return - -# # t = transform.transform.translation -# # t = np.array([t.x, t.y, t.z]) -# # q = transform.transform.rotation -# # R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] - -# # semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") - -# # if len(semantic_img.shape) != 2: -# # semantic_img = [semantic_img[:, :, k] for k in range(3)] - -# # else: -# # semantic_img = [semantic_img] - -# # K = np.array(camera_info_msg.K, dtype=np.float32).reshape(3, 3) - -# # assert np.all(np.array(camera_info_msg.D) == 0.0), "Undistortion not implemented" -# # D = np.array(camera_info_msg.D, dtype=np.float32).reshape(5, 1) - -# # # process pointcloud -# # self._map.input_image(sub_key, semantic_img, R, t, K, D, camera_info_msg.height, camera_info_msg.width) -# # self._image_process_counter += 1 - -# # def pointcloud_callback(self, msg, sub_key): -# # channels = ["x", "y", "z"] + self.param.subscriber_cfg[sub_key]["channels"] - -# # points = ros_numpy.numpify(msg) -# # pts = np.empty((points.shape[0], 0)) -# # for ch in channels: -# # p = points[ch] -# # if len(p.shape) == 1: -# # p = p[:, None] -# # pts = np.append(pts, p, axis=1) - -# # # get pose of pointcloud -# # ti = rospy.Time(secs=msg.header.stamp.secs, nsecs=msg.header.stamp.nsecs) -# # self._last_t = ti -# # try: -# # transform = self._tf_buffer.lookup_transform(self.map_frame, msg.header.frame_id, ti, rospy.Duration(1.0)) -# # except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: -# # print("Error: pointcloud_callback: ", e) -# # return - -# # t = transform.transform.translation -# # t = np.array([t.x, t.y, t.z]) -# # q = transform.transform.rotation -# # R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] - -# # # process pointcloud -# # self._map.input(pts, channels, R, t, 0, 0) -# # self._pointcloud_process_counter += 1 -# # print("Pointclouds processed: ", self._pointcloud_process_counter) - -# # def update_pose(self, t): -# # # get pose of base -# # # t = rospy.Time.now() -# # if self._last_t is None: -# # return -# # try: -# # transform = self._tf_buffer.lookup_transform( -# # self.map_frame, self.base_frame, self._last_t, rospy.Duration(1.0) -# # ) -# # except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: -# # print("Error: update_pose error: ", e) -# # return -# # t = transform.transform.translation -# # trans = np.array([t.x, t.y, t.z]) -# # q = transform.transform.rotation -# # rot = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3] -# # self._map.move_to(trans, rot) - -# # self._map_t = t -# # self._map_q = q - -# # def update_variance(self, t): -# # self._map.update_variance() - -# # def update_time(self, t): -# # self._map.update_time() - - - -# def declare_parameters_from_yaml(self, yaml_file): -# def declare_nested_parameters(parent_name, param_dict): -# for sub_name, sub_value in param_dict.items(): -# full_param_name = f"{parent_name}.{sub_name}" - -# if isinstance(sub_value, dict): -# declare_nested_parameters(full_param_name, sub_value) -# else: -# if "elevation_mapping.ros__parameters" in full_param_name: -# full_param_name = full_param_name.replace("elevation_mapping.ros__parameters.", "") -# self.declare_parameter(full_param_name, sub_value) - -# with open(yaml_file, 'r') as file: -# params = yaml.safe_load(file) - -# # Set parameters in the node -# for param_name, param_value in params.items(): -# if isinstance(param_value, dict): -# # For nested dictionaries, set each nested parameter individually -# declare_nested_parameters(param_name, param_value) -# else: -# # For top-level parameters -# if "elevation_mapping.ros__parameters" in param_name: -# param_name = param_name.replace("elevation_mapping.ros__parameters.", "") -# self.declare_parameter(param_name, param_value) - - - - -# def get_ros_params(self): -# # TODO fix this here when later launching with launch-file -# # This is currently {p} elevation_mapping") -# param_file = os.path.join(self.root, f"config/core/core_param.yaml") -# self.declare_parameters_from_yaml(param_file) - -# # os.system(f"rosparam delete /{self.node_name}") -# # os.system(f"rosparam load {para} elevation_mapping") -# # self.subscribers = self.get_parameter("subscribers").get_parameter_value().string_value -# # self.publishers = self.get_parameter("publishers").get_parameter_value().string_value -# self.initialize_frame_id = self.get_parameter("initialize_frame_id").get_parameter_value().string_array_value -# self.initialize_tf_offset = self.get_parameter("initialize_tf_offset").get_parameter_value().double_value -# self.pose_topic = self.get_parameter("pose_topic").get_parameter_value().string_value -# self.map_frame = self.get_parameter("map_frame").get_parameter_value().string_value -# self.base_frame = self.get_parameter("base_frame").get_parameter_value().string_value -# self.corrected_map_frame = self.get_parameter("corrected_map_frame").get_parameter_value().string_value -# self.initialize_method = self.get_parameter("initialize_method").get_parameter_value().string_value -# self.position_lowpass_alpha = self.get_parameter("position_lowpass_alpha").get_parameter_value().double_value -# self.orientation_lowpass_alpha = self.get_parameter("orientation_lowpass_alpha").get_parameter_value().double_value -# self.update_variance_fps = self.get_parameter("update_variance_fps").get_parameter_value().double_value -# self.time_interval = self.get_parameter("time_interval").get_parameter_value().double_value -# self.update_pose_fps = self.get_parameter("update_pose_fps").get_parameter_value().double_value -# self.initialize_tf_grid_size = self.get_parameter("initialize_tf_grid_size").get_parameter_value().double_value -# self.map_acquire_fps = self.get_parameter("map_acquire_fps").get_parameter_value().double_value -# self.publish_statistics_fps = self.get_parameter("publish_statistics_fps").get_parameter_value().double_value -# self.enable_pointcloud_publishing = self.get_parameter("enable_pointcloud_publishing").get_parameter_value().bool_value -# self.enable_normal_arrow_publishing = self.get_parameter("enable_normal_arrow_publishing").get_parameter_value().bool_value -# self.enable_drift_corrected_TF_publishing = self.get_parameter("enable_drift_corrected_TF_publishing").get_parameter_value().bool_value -# self.use_initializer_at_start = self.get_parameter("use_initializer_at_start").get_parameter_value().bool_value - - -# def main(args=None): -# rclpy.init(args=args) -# node = ElevationMapWrapper() -# rclpy.spin(node) -# rclpy.shutdown() - -# if __name__ == '__main__': -# main() \ No newline at end of file diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/fusion_manager.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/fusion_manager.py deleted file mode 100644 index aca34a6d..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/fusion_manager.py +++ /dev/null @@ -1,112 +0,0 @@ -# -# Copyright (c) 2023, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -from abc import ABC, abstractmethod -import cupy as cp -from typing import List, Dict, Any -from dataclasses import dataclass -import importlib -import inspect - - -# @dataclass -# class FusionParams: -# name: str - - -class FusionBase(ABC): - """ - This is a base class of Fusion - """ - - @abstractmethod - def __init__(self, *args, **kwargs): - """ - - Args: - fusion_params : FusionParams - The parameter of callback - """ - self.name = None - - @abstractmethod - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map): - pass - - -class FusionManager(object): - def __init__(self, params): - self.fusion_plugins: Dict[str, FusionBase] = {} - self.params = params - self.plugins = [] - - def register_plugin(self, plugin): - """ - Register a new fusion plugin - """ - try: - m = importlib.import_module("." + plugin, package="elevation_mapping_cupy.fusion") # -> 'module' - except: - raise ValueError("Plugin {} does not exist.".format(plugin)) - for name, obj in inspect.getmembers(m): - - if inspect.isclass(obj) and issubclass(obj, FusionBase) and name != "FusionBase": - self.plugins.append(obj(self.params)) - - def get_plugin_idx(self, name: str, data_type: str): - """ - Get a registered fusion plugin - """ - name = data_type + "_" + name - for idx, plugin in enumerate(self.plugins): - if plugin.name == name: - return idx - print("[WARNING] Plugin {} is not in the list: {}".format(name, self.plugins)) - return None - - def execute_plugin( - self, name: str, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, elements_to_shift - ): - """ - Execute a registered fusion plugin - """ - idx = self.get_plugin_idx(name, "pointcloud") - if idx is not None: - self.plugins[idx]( - points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, elements_to_shift - ) - # else: - # raise ValueError("Plugin {} is not registered".format(name)) - - def execute_image_plugin( - self, - name: str, - sem_map_idx, - image, - j, - uv_correspondence, - valid_correspondence, - image_height, - image_width, - semantic_map, - new_map, - ): - """ - Execute a registered fusion plugin - """ - idx = self.get_plugin_idx(name, "image") - if idx is not None: - self.plugins[idx]( - sem_map_idx, - image, - j, - uv_correspondence, - valid_correspondence, - image_height, - image_width, - semantic_map, - new_map, - ) - # else: - # raise ValueError("Plugin {} is not registered".format(name)) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_color.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_color.py deleted file mode 100644 index c882c1b0..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_color.py +++ /dev/null @@ -1,86 +0,0 @@ -# -# Copyright (c) 2023, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import numpy as np -import string - -from .fusion_manager import FusionBase - - -def color_correspondences_to_map_kernel(resolution, width, height): - color_correspondences_to_map_kernel = cp.ElementwiseKernel( - in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", - out_params="raw U new_sem_map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - int cell_idx = get_map_idx(i, 0); - if (valid_correspondence[cell_idx]){ - int cell_idx_2 = get_map_idx(i, 1); - - int idx_red = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; - int idx_green = image_width * image_height + idx_red; - int idx_blue = image_width * image_height * 2 + idx_red; - - unsigned int r = image_rgb[idx_red]; - unsigned int g = image_rgb[idx_green]; - unsigned int b = image_rgb[idx_blue]; - - unsigned int rgb = (r<<16) + (g << 8) + b; - float rgb_ = __uint_as_float(rgb); - new_sem_map[get_map_idx(i, map_idx)] = rgb_; - }else{ - new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; - } - """ - ).substitute(), - name="color_correspondences_to_map_kernel", - ) - return color_correspondences_to_map_kernel - - -class ImageColor(FusionBase): - def __init__(self, params, *args, **kwargs): - # super().__init__(fusion_params, *args, **kwargs) - # print("Initialize fusion kernel") - self.name = "image_color" - self.cell_n = params.cell_n - self.resolution = params.resolution - - self.color_correspondences_to_map_kernel = color_correspondences_to_map_kernel( - resolution=self.resolution, width=self.cell_n, height=self.cell_n, - ) - - def __call__( - self, - sem_map_idx, - image, - j, - uv_correspondence, - valid_correspondence, - image_height, - image_width, - semantic_map, - new_map, - ): - self.color_correspondences_to_map_kernel( - semantic_map, - cp.uint64(sem_map_idx), - image, - uv_correspondence, - valid_correspondence, - image_height, - image_width, - new_map, - size=int(self.cell_n * self.cell_n), - ) - semantic_map[sem_map_idx] = new_map[sem_map_idx] diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_average.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_average.py deleted file mode 100644 index c4165a54..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_average.py +++ /dev/null @@ -1,113 +0,0 @@ -import cupy as cp -import numpy as np -import string - -from .fusion_manager import FusionBase - - -def sum_kernel( - resolution, width, height, -): - """Sums the semantic values of the classes for the exponentiala verage or for the average. - - Args: - resolution: - width: - height: - - Returns: - - """ - # input the list of layers, amount of channels can slo be input through kernel - sum_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params="raw U map, raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(resolution=resolution, width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U idx = p[id * pcl_channels[0]]; - U valid = p[id * pcl_channels[0] + 1]; - U inside = p[id * pcl_channels[0] + 2]; - if (valid) { - if (inside) { - U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; - atomicAdd(&newmap[get_map_idx(idx, map_lay[layer])], feat); - } - } - """ - ).substitute(), - name="sum_kernel", - ) - return sum_kernel - - -def average_kernel( - width, height, -): - average_kernel = cp.ElementwiseKernel( - in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", - out_params="raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U cnt = new_elmap[get_map_idx(id, 2)]; - if (cnt>0){ - U feat = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); - map[get_map_idx(id, map_lay[layer])] = feat; - } - """ - ).substitute(), - name="average_map_kernel", - ) - return average_kernel - - -class Average(FusionBase): - def __init__(self, params, *args, **kwargs): - # super().__init__(fusion_params, *args, **kwargs) - # print("Initialize fusion kernel") - self.name = "pointcloud_average" - self.cell_n = params.cell_n - self.resolution = params.resolution - self.sum_kernel = sum_kernel(self.resolution, self.cell_n, self.cell_n,) - self.average_kernel = average_kernel(self.cell_n, self.cell_n,) - - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): - self.sum_kernel( - points_all, - R, - t, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - semantic_map, - new_map, - size=(points_all.shape[0] * pcl_ids.shape[0]), - ) - self.average_kernel( - new_map, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - elevation_map, - semantic_map, - size=(self.cell_n * self.cell_n * pcl_ids.shape[0]), - ) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py deleted file mode 100644 index 95dc8aea..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_bayesian_inference.py +++ /dev/null @@ -1,122 +0,0 @@ -# -# Copyright (c) 2023, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import numpy as np -import string - -from .fusion_manager import FusionBase - - -def sum_compact_kernel( - resolution, width, height, -): - # input the list of layers, amount of channels can slo be input through kernel - sum_compact_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params=" raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(resolution=resolution, width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U idx = p[id * pcl_channels[0]]; - U valid = p[id * pcl_channels[0] + 1]; - U inside = p[id * pcl_channels[0] + 2]; - if (valid) { - if (inside) { - U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; - atomicAdd(&newmap[get_map_idx(idx, layer)], feat); - } - } - """ - ).substitute(), - name="sum_compact_kernel", - ) - return sum_compact_kernel - - -def bayesian_inference_kernel( - width, height, -): - bayesian_inference_kernel = cp.ElementwiseKernel( - in_params=" raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", - out_params="raw U newmap, raw U sum_mean, raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U cnt = new_elmap[get_map_idx(id, 2)]; - if (cnt>0){ - U feat_ml = sum_mean[get_map_idx(id, layer)]/cnt; - U feat_old = map[get_map_idx(id, map_lay[layer])]; - U sigma_old = newmap[get_map_idx(id, map_lay[layer])]; - U sigma = 1.0; - U feat_new = sigma*feat_old /(cnt*sigma_old + sigma) +cnt*sigma_old *feat_ml /(cnt*sigma_old+sigma); - U sigma_new = sigma*sigma_old /(cnt*sigma_old +sigma); - map[get_map_idx(id, map_lay[layer])] = feat_new; - newmap[get_map_idx(id, map_lay[layer])] = sigma_new; - } - """ - ).substitute(), - name="bayesian_inference_kernel", - ) - return bayesian_inference_kernel - - -class BayesianInference(FusionBase): - def __init__(self, params, *args, **kwargs): - # super().__init__(fusion_params, *args, **kwargs) - # print("Initialize bayesian inference kernel") - self.name = "pointcloud_bayesian_inference" - - self.cell_n = params.cell_n - self.resolution = params.resolution - self.fusion_algorithms = params.fusion_algorithms - self.data_type = params.data_type - - self.sum_mean = cp.ones( - (self.fusion_algorithms.count("bayesian_inference"), self.cell_n, self.cell_n,), self.data_type, - ) - # TODO initialize the variance with a value different than 0 - self.sum_compact_kernel = sum_compact_kernel(self.resolution, self.cell_n, self.cell_n,) - self.bayesian_inference_kernel = bayesian_inference_kernel(self.cell_n, self.cell_n,) - - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): - self.sum_mean *= 0 - self.sum_compact_kernel( - points_all, - R, - t, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - self.sum_mean, - size=(points_all.shape[0]), - ) - self.bayesian_inference_kernel( - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - elevation_map, - new_map, - self.sum_mean, - semantic_map, - size=(self.cell_n * self.cell_n), - ) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_average.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_average.py deleted file mode 100644 index 80c96dc4..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_average.py +++ /dev/null @@ -1,126 +0,0 @@ -# -# Copyright (c) 2023, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import numpy as np -import string - -from .fusion_manager import FusionBase - - -def sum_kernel( - resolution, width, height, -): - """Sums the semantic values of the classes for the exponentiala verage or for the average. - - Args: - resolution: - width: - height: - - Returns: - - """ - # input the list of layers, amount of channels can slo be input through kernel - sum_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params="raw U map, raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(resolution=resolution, width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U idx = p[id * pcl_channels[0]]; - U valid = p[id * pcl_channels[0] + 1]; - U inside = p[id * pcl_channels[0] + 2]; - if (valid) { - if (inside) { - U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; - atomicAdd(&newmap[get_map_idx(idx, map_lay[layer])], feat); - } - } - """ - ).substitute(), - name="sum_kernel", - ) - return sum_kernel - - -def class_average_kernel( - width, height, alpha, -): - class_average_kernel = cp.ElementwiseKernel( - in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", - out_params="raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U cnt = new_elmap[get_map_idx(id, 2)]; - if (cnt>0){ - U prev_val = map[get_map_idx(id, map_lay[layer])]; - if (prev_val==0){ - U val = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); - map[get_map_idx(id, map_lay[layer])] = val; - } - else{ - U val = ${alpha} *prev_val + (1-${alpha}) * newmap[get_map_idx(id, map_lay[layer])]/(cnt); - map[get_map_idx(id, map_lay[layer])] = val; - } - } - """ - ).substitute(alpha=alpha,), - name="class_average_kernel", - ) - return class_average_kernel - - -class ClassAverage(FusionBase): - def __init__(self, params, *args, **kwargs): - # super().__init__(fusion_params, *args, **kwargs) - # print("Initialize fusion kernel") - self.name = "pointcloud_class_average" - self.cell_n = params.cell_n - self.resolution = params.resolution - self.average_weight = params.average_weight - - self.sum_kernel = sum_kernel(self.resolution, self.cell_n, self.cell_n,) - self.class_average_kernel = class_average_kernel(self.cell_n, self.cell_n, self.average_weight,) - - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): - self.sum_kernel( - points_all, - R, - t, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - semantic_map, - new_map, - size=(points_all.shape[0] * pcl_ids.shape[0]), - ) - self.class_average_kernel( - new_map, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - elevation_map, - semantic_map, - size=(self.cell_n * self.cell_n * pcl_ids.shape[0]), - ) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py deleted file mode 100644 index 5fec3a7d..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_bayesian.py +++ /dev/null @@ -1,75 +0,0 @@ -# -# Copyright (c) 2023, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import numpy as np -import string - -from .fusion_manager import FusionBase - - -def alpha_kernel( - resolution, width, height, -): - # input the list of layers, amount of channels can slo be input through kernel - alpha_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params="raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(resolution=resolution, width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U idx = p[id * pcl_channels[0]]; - U valid = p[id * pcl_channels[0] + 1]; - U inside = p[id * pcl_channels[0] + 2]; - if (valid) { - if (inside) { - U theta_max = 0; - W arg_max = 0; - U theta = p[id * pcl_channels[0] + pcl_chan[layer]]; - if (theta >=theta_max){ - arg_max = map_lay[layer]; - theta_max = theta; - } - atomicAdd(&newmap[get_map_idx(idx, arg_max)], theta_max); - } - } - """ - ).substitute(), - name="alpha_kernel", - ) - return alpha_kernel - - -class ClassBayesian(FusionBase): - def __init__(self, params, *args, **kwargs): - # super().__init__(fusion_params, *args, **kwargs) - # print("Initialize fusion kernel") - self.name = "pointcloud_class_bayesian" - self.cell_n = params.cell_n - self.resolution = params.resolution - self.alpha_kernel = alpha_kernel(self.resolution, self.cell_n, self.cell_n,) - - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): - self.alpha_kernel( - points_all, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - new_map, - size=(points_all.shape[0]), - ) - # calculate new thetas - sum_alpha = cp.sum(new_map[layer_ids], axis=0) - # do not divide by zero - sum_alpha[sum_alpha == 0] = 1 - semantic_map[layer_ids] = new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_max.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_max.py deleted file mode 100644 index e506571d..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/pointcloud_class_max.py +++ /dev/null @@ -1,123 +0,0 @@ -# -# Copyright (c) 2023, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import numpy as np -import string - -from .fusion_manager import FusionBase - - -def sum_max_kernel( - resolution, width, height, -): - # input the list of layers, amount of channels can slo be input through kernel - sum_max_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U max_pt, raw T max_id, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params=" raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(resolution=resolution, width=width, height=height), - operation=string.Template( - """ - U idx = p[i * pcl_channels[0]]; - U valid = p[i * pcl_channels[0] + 1]; - U inside = p[i * pcl_channels[0] + 2]; - if (valid) { - if (inside) { - // for every max value - for ( W it=0;it> 16; - return reds; - } - __device__ unsigned int get_g(unsigned int color){ - unsigned int green = 0xFF00; - unsigned int greens = (color & green) >> 8; - return greens; - } - __device__ unsigned int get_b(unsigned int color){ - unsigned int blue = 0xFF; - unsigned int blues = ( color & blue); - return blues; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U idx = p[id * pcl_channels[0]]; - U valid = p[id * pcl_channels[0] + 1]; - U inside = p[id * pcl_channels[0] + 2]; - if (valid && inside){ - unsigned int color = __float_as_uint(p[id * pcl_channels[0] + pcl_chan[layer]]); - atomicAdd(&color_map[get_map_idx(idx, layer*3)], get_r(color)); - atomicAdd(&color_map[get_map_idx(idx, layer*3+1)], get_g(color)); - atomicAdd(&color_map[get_map_idx(idx, layer*3 + 2)], get_b(color)); - atomicAdd(&color_map[get_map_idx(idx, pcl_channels[1]*3)], 1); - } - """ - ).substitute(width=width), - name="add_color_kernel", - ) - return add_color_kernel - - -def color_average_kernel( - width, height, -): - color_average_kernel = cp.ElementwiseKernel( - in_params="raw V color_map, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params="raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - __device__ unsigned int get_r(unsigned int color){ - unsigned int red = 0xFF0000; - unsigned int reds = (color & red) >> 16; - return reds; - } - __device__ unsigned int get_g(unsigned int color){ - unsigned int green = 0xFF00; - unsigned int greens = (color & green) >> 8; - return greens; - } - __device__ unsigned int get_b(unsigned int color){ - unsigned int blue = 0xFF; - unsigned int blues = (color & blue); - return blues; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - unsigned int cnt = color_map[get_map_idx(id, pcl_channels[1]*3)]; - if (cnt>0){ - // U prev_color = map[get_map_idx(id, map_lay[layer])]; - unsigned int r = color_map[get_map_idx(id, layer*3)]/(1*cnt); - unsigned int g = color_map[get_map_idx(id, layer*3+1)]/(1*cnt); - unsigned int b = color_map[get_map_idx(id, layer*3+2)]/(1*cnt); - //if (prev_color>=0){ - // unsigned int prev_r = get_r(prev_color); - // unsigned int prev_g = get_g(prev_color); - // unsigned int prev_b = get_b(prev_color); - // unsigned int r = prev_r/2 + color_map[get_map_idx(i, layer*3)]/(2*cnt); - // unsigned int g = prev_g/2 + color_map[get_map_idx(i, layer*3+1)]/(2*cnt); - // unsigned int b = prev_b/2 + color_map[get_map_idx(i, layer*3+2)]/(2*cnt); - //} - unsigned int rgb = (r<<16) + (g << 8) + b; - float rgb_ = __uint_as_float(rgb); - map[get_map_idx(id, map_lay[layer])] = rgb_; - } - """ - ).substitute(), - name="color_average_kernel", - ) - return color_average_kernel - - -class Color(FusionBase): - def __init__(self, params, *args, **kwargs): - # super().__init__(fusion_params, *args, **kwargs) - # print("Initialize fusion kernel") - self.name = "pointcloud_color" - self.cell_n = params.cell_n - self.resolution = params.resolution - - self.add_color_kernel = add_color_kernel(params.cell_n, params.cell_n,) - self.color_average_kernel = color_average_kernel(self.cell_n, self.cell_n) - - def __call__(self, points_all, R, t, pcl_ids, layer_ids, elevation_map, semantic_map, new_map, *args): - self.color_map = cp.zeros((1 + 3 * layer_ids.shape[0], self.cell_n, self.cell_n), dtype=cp.uint32,) - - points_all = points_all.astype(cp.float32) - self.add_color_kernel( - points_all, - R, - t, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - self.color_map, - size=(points_all.shape[0]), - ) - self.color_average_kernel( - self.color_map, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - semantic_map, - size=(self.cell_n * self.cell_n), - ) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/__init__.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/__init__.py deleted file mode 100644 index 06eecc38..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .custom_image_kernels import * -from .custom_kernels import * -from .custom_semantic_kernels import * diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_image_kernels.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_image_kernels.py deleted file mode 100644 index a020ba2e..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_image_kernels.py +++ /dev/null @@ -1,271 +0,0 @@ -# -# Copyright (c) 2023, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import string - - -def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_collision): - """ - This function calculates the correspondence between the image and the map. - It takes in the resolution, width, height, and tolerance_z_collision as parameters. - The function returns a kernel that can be used to perform the correspondence calculation. - """ - _image_to_map_correspondence_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U K, raw U D, raw U image_height, raw U image_width, raw U center", - out_params="raw U uv_correspondence, raw B valid_correspondence", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - __device__ bool is_inside_map(int x, int y) { - return (x >= 0 && y >= 0 && x<${width} && y<${height}); - } - __device__ float get_l2_distance(int x0, int y0, int x1, int y1) { - float dx = x0-x1; - float dy = y0-y1; - return sqrt( dx*dx + dy*dy); - } - """ - ).substitute(width=width, height=height, resolution=resolution), - operation=string.Template( - """ - int cell_idx = get_map_idx(i, 0); - - // return if gridcell has no valid height - if (map[get_map_idx(i, 2)] != 1){ - return; - } - - // get current cell position - int y0 = i % ${width}; - int x0 = i / ${width}; - - // gridcell 3D point in worldframe TODO reverse x and y - float p1 = (x0-(${width}/2)) * ${resolution} + center[0]; - float p2 = (y0-(${height}/2)) * ${resolution} + center[1]; - float p3 = map[cell_idx] + center[2]; - - // reproject 3D point into image plane - float u = p1 * P[0] + p2 * P[1] + p3 * P[2] + P[3]; - float v = p1 * P[4] + p2 * P[5] + p3 * P[6] + P[7]; - float d = p1 * P[8] + p2 * P[9] + p3 * P[10] + P[11]; - - // filter point behind image plane - if (d <= 0) { - return; - } - u = u/d; - v = v/d; - - // Check if D is all zeros - bool is_D_zero = (D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == 0 && D[4] == 0); - - // Apply undistortion using distortion matrix D if not all zeros - if (!is_D_zero) { - float k1 = D[0]; - float k2 = D[1]; - float p1 = D[2]; - float p2 = D[3]; - float k3 = D[4]; - float fx = K[0]; - float fy = K[4]; - float cx = K[2]; - float cy = K[5]; - float x = (u - cx) / fx; - float y = (v - cy) / fy; - float r2 = x * x + y * y; - float radial_distortion = 1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2; - float u_corrected = x * radial_distortion + 2 * p1 * x * y + p2 * (r2 + 2 * x * x); - float v_corrected = y * radial_distortion + 2 * p2 * x * y + p1 * (r2 + 2 * y * y); - u = fx * u_corrected + cx; - v = fy * v_corrected + cy; - } - - // filter point next to image plane - if ((u < 0) || (v < 0) || (u >= image_width) || (v >= image_height)){ - return; - } - - int y0_c = y0; - int x0_c = x0; - float total_dis = get_l2_distance(x0_c, y0_c, x1,y1); - float z0 = map[cell_idx]; - float delta_z = z1-z0; - - - // bresenham algorithm to iterate over cells in line between camera center and current gridmap cell - // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm - int dx = abs(x1-x0); - int sx = x0 < x1 ? 1 : -1; - int dy = -abs(y1 - y0); - int sy = y0 < y1 ? 1 : -1; - int error = dx + dy; - - bool is_valid = true; - - // iterate over all cells along line - while (1){ - // assumption we do not need to check the height for camera center cell - if (x0 == x1 && y0 == y1){ - break; - } - - // check if height is invalid - if (is_inside_map(x0,y0)){ - int idx = y0 + (x0 * ${width}); - if (map[get_map_idx(idx, 2)]){ - float dis = get_l2_distance(x0_c, y0_c, x0, y0); - float rayheight = z0 + ( dis / total_dis * delta_z); - if ( map[idx] - ${tolerance_z_collision} > rayheight){ - is_valid = false; - break; - } - } - } - - - // computation of next gridcell index in line - int e2 = 2 * error; - if (e2 >= dy){ - if(x0 == x1){ - break; - } - error = error + dy; - x0 = x0 + sx; - } - if (e2 <= dx){ - if (y0 == y1){ - break; - } - error = error + dx; - y0 = y0 + sy; - } - } - - // mark the correspondence - uv_correspondence[get_map_idx(i, 0)] = u; - uv_correspondence[get_map_idx(i, 1)] = v; - valid_correspondence[get_map_idx(i, 0)] = is_valid; - """ - ).substitute(height=height, width=width, resolution=resolution, tolerance_z_collision=tolerance_z_collision), - name="image_to_map_correspondence_kernel", - ) - return _image_to_map_correspondence_kernel - - -def average_correspondences_to_map_kernel(width, height): - """ - This function calculates the average correspondences to the map. - It takes in the width and height as parameters. - The function returns a kernel that can be used to perform the correspondence calculation. - """ - _average_correspondences_to_map_kernel = cp.ElementwiseKernel( - in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", - out_params="raw U new_sem_map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - int cell_idx = get_map_idx(i, 0); - if (valid_correspondence[cell_idx]){ - int cell_idx_2 = get_map_idx(i, 1); - int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; - new_sem_map[get_map_idx(i, map_idx)] = image_mono[idx]; - }else{ - new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; - } - - """ - ).substitute(), - name="average_correspondences_to_map_kernel", - ) - return _average_correspondences_to_map_kernel - - -def exponential_correspondences_to_map_kernel(width, height, alpha): - """ - This function calculates the exponential correspondences to the map. - It takes in the width, height, and alpha as parameters. - The function returns a kernel that can be used to perform the correspondence calculation. - """ - _exponential_correspondences_to_map_kernel = cp.ElementwiseKernel( - in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", - out_params="raw U new_sem_map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - int cell_idx = get_map_idx(i, 0); - if (valid_correspondence[cell_idx]){ - int cell_idx_2 = get_map_idx(i, 1); - int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; - new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)] * (1-${alpha}) + ${alpha} * image_mono[idx]; - }else{ - new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; - } - - """ - ).substitute(alpha=alpha), - name="exponential_correspondences_to_map_kernel", - ) - return _exponential_correspondences_to_map_kernel - - -def color_correspondences_to_map_kernel(width, height): - """ - This function calculates the color correspondences to the map. - It takes in the width and height as parameters. - The function returns a kernel that can be used to perform the correspondence calculation. - """ - _color_correspondences_to_map_kernel = cp.ElementwiseKernel( - in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", - out_params="raw U new_sem_map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - int cell_idx = get_map_idx(i, 0); - if (valid_correspondence[cell_idx]){ - int cell_idx_2 = get_map_idx(i, 1); - - int idx_red = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; - int idx_green = image_width * image_height + idx_red; - int idx_blue = image_width * image_height * 2 + idx_red; - - unsigned int r = image_rgb[idx_red]; - unsigned int g = image_rgb[idx_green]; - unsigned int b = image_rgb[idx_blue]; - - unsigned int rgb = (r<<16) + (g << 8) + b; - float rgb_ = __uint_as_float(rgb); - new_sem_map[get_map_idx(i, map_idx)] = rgb_; - }else{ - new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; - } - """ - ).substitute(), - name="color_correspondences_to_map_kernel", - ) - return _color_correspondences_to_map_kernel diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_kernels.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_kernels.py deleted file mode 100644 index d7025270..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_kernels.py +++ /dev/null @@ -1,685 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import string - - -def map_utils( - resolution, - width, - height, - sensor_noise_factor, - min_valid_distance, - max_height_range, - ramped_height_range_a, - ramped_height_range_b, - ramped_height_range_c, -): - util_preamble = string.Template( - """ - __device__ float16 clamp(float16 x, float16 min_x, float16 max_x) { - - return max(min(x, max_x), min_x); - } - __device__ int get_x_idx(float16 x, float16 center) { - int i = (x - center) / ${resolution} + 0.5 * ${width}; - return i; - } - __device__ int get_y_idx(float16 y, float16 center) { - int i = (y - center) / ${resolution} + 0.5 * ${height}; - return i; - } - __device__ bool is_inside(int idx) { - int idx_x = idx / ${width}; - int idx_y = idx % ${width}; - if (idx_x == 0 || idx_x == ${width} - 1) { - return false; - } - if (idx_y == 0 || idx_y == ${height} - 1) { - return false; - } - return true; - } - __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { - int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); - int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); - return ${width} * idx_x + idx_y; - } - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - __device__ float transform_p(float16 x, float16 y, float16 z, - float16 r0, float16 r1, float16 r2, float16 t) { - return r0 * x + r1 * y + r2 * z + t; - } - __device__ float z_noise(float16 z){ - return ${sensor_noise_factor} * z * z; - } - - __device__ float point_sensor_distance(float16 x, float16 y, float16 z, - float16 sx, float16 sy, float16 sz) { - float d = (x - sx) * (x - sx) + (y - sy) * (y - sy) + (z - sz) * (z - sz); - return d; - } - - __device__ bool is_valid(float16 x, float16 y, float16 z, - float16 sx, float16 sy, float16 sz) { - float d = point_sensor_distance(x, y, z, sx, sy, sz); - float dxy = max(sqrt(x * x + y * y) - ${ramped_height_range_b}, 0.0); - if (d < ${min_valid_distance} * ${min_valid_distance}) { - return false; - } - else if (z - sz > dxy * ${ramped_height_range_a} + ${ramped_height_range_c} || z - sz > ${max_height_range}) { - return false; - } - else { - return true; - } - } - - __device__ float ray_vector(float16 tx, float16 ty, float16 tz, - float16 px, float16 py, float16 pz, - float16& rx, float16& ry, float16& rz){ - float16 vx = px - tx; - float16 vy = py - ty; - float16 vz = pz - tz; - float16 norm = sqrt(vx * vx + vy * vy + vz * vz); - if (norm > 0) { - rx = vx / norm; - ry = vy / norm; - rz = vz / norm; - } - else { - rx = 0; - ry = 0; - rz = 0; - } - return norm; - } - - __device__ float inner_product(float16 x1, float16 y1, float16 z1, - float16 x2, float16 y2, float16 z2) { - - float product = (x1 * x2 + y1 * y2 + z1 * z2); - return product; - } - - """ - ).substitute( - resolution=resolution, - width=width, - height=height, - sensor_noise_factor=sensor_noise_factor, - min_valid_distance=min_valid_distance, - max_height_range=max_height_range, - ramped_height_range_a=ramped_height_range_a, - ramped_height_range_b=ramped_height_range_b, - ramped_height_range_c=ramped_height_range_c, - ) - return util_preamble - - -def add_points_kernel( - resolution, - width, - height, - sensor_noise_factor, - mahalanobis_thresh, - outlier_variance, - wall_num_thresh, - max_ray_length, - cleanup_step, - min_valid_distance, - max_height_range, - cleanup_cos_thresh, - ramped_height_range_a, - ramped_height_range_b, - ramped_height_range_c, - enable_edge_shaped=True, - enable_visibility_cleanup=True, -): - add_points_kernel = cp.ElementwiseKernel( - in_params="raw U center_x, raw U center_y, raw U R, raw U t, raw U norm_map", - out_params="raw U p, raw U map, raw T newmap", - preamble=map_utils( - resolution, - width, - height, - sensor_noise_factor, - min_valid_distance, - max_height_range, - ramped_height_range_a, - ramped_height_range_b, - ramped_height_range_c, - ), - operation=string.Template( - """ - U rx = p[i * 3]; - U ry = p[i * 3 + 1]; - U rz = p[i * 3 + 2]; - U x = transform_p(rx, ry, rz, R[0], R[1], R[2], t[0]); - U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); - U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); - U v = z_noise(rz); - int idx = get_idx(x, y, center_x[0], center_y[0]); - if (is_valid(x, y, z, t[0], t[1], t[2])) { - if (is_inside(idx)) { - U map_h = map[get_map_idx(idx, 0)]; - U map_v = map[get_map_idx(idx, 1)]; - U num_points = newmap[get_map_idx(idx, 4)]; - if (abs(map_h - z) > (map_v * ${mahalanobis_thresh})) { - atomicAdd(&map[get_map_idx(idx, 1)], ${outlier_variance}); - } - else { - if (${enable_edge_shaped} && (num_points > ${wall_num_thresh}) && (z < map_h - map_v * ${mahalanobis_thresh} / num_points)) { - // continue; - } - else { - T new_h = (map_h * v + z * map_v) / (map_v + v); - T new_v = (map_v * v) / (map_v + v); - atomicAdd(&newmap[get_map_idx(idx, 0)], new_h); - atomicAdd(&newmap[get_map_idx(idx, 1)], new_v); - atomicAdd(&newmap[get_map_idx(idx, 2)], 1.0); - // is Valid - map[get_map_idx(idx, 2)] = 1; - // Time layer - map[get_map_idx(idx, 4)] = 0.0; - // Upper bound - map[get_map_idx(idx, 5)] = new_h; - map[get_map_idx(idx, 6)] = 0.0; - } - // visibility cleanup - } - } - } - if (${enable_visibility_cleanup}) { - float16 ray_x, ray_y, ray_z; - float16 ray_length = ray_vector(t[0], t[1], t[2], x, y, z, ray_x, ray_y, ray_z); - ray_length = min(ray_length, (float16)${max_ray_length}); - int last_nidx = -1; - for (float16 s=${ray_step}; s < ray_length; s+=${ray_step}) { - // iterate through ray - U nx = t[0] + ray_x * s; - U ny = t[1] + ray_y * s; - U nz = t[2] + ray_z * s; - int nidx = get_idx(nx, ny, center_x[0], center_y[0]); - if (last_nidx == nidx) {continue;} // Skip if we're still in the same cell - else {last_nidx = nidx;} - if (!is_inside(nidx)) {continue;} - - U nmap_h = map[get_map_idx(nidx, 0)]; - U nmap_v = map[get_map_idx(nidx, 1)]; - U nmap_valid = map[get_map_idx(nidx, 2)]; - // traversability - U nmap_trav = map[get_map_idx(nidx, 3)]; - // Time layer - U non_updated_t = map[get_map_idx(nidx, 4)]; - // upper bound - U nmap_upper = map[get_map_idx(nidx, 5)]; - U nmap_is_upper = map[get_map_idx(nidx, 6)]; - - // If point is close or is farther away than ray length, skip. - float16 d = (x - nx) * (x - nx) + (y - ny) * (y - ny) + (z - nz) * (z - nz); - if (d < 0.1 || !is_valid(x, y, z, t[0], t[1], t[2])) {continue;} - - // If invalid, do upper bound check, then skip - if (nmap_valid < 0.5) { - if (nz < nmap_upper || nmap_is_upper < 0.5) { - map[get_map_idx(nidx, 5)] = nz; - map[get_map_idx(nidx, 6)] = 1.0f; - } - continue; - } - // If updated recently, skip - if (non_updated_t < 0.5) {continue;} - - if (nmap_h > nz + 0.01 - min(nmap_v, 1.0) * 0.05) { - // If ray and norm is vertical, skip - U norm_x = norm_map[get_map_idx(nidx, 0)]; - U norm_y = norm_map[get_map_idx(nidx, 1)]; - U norm_z = norm_map[get_map_idx(nidx, 2)]; - float product = inner_product(ray_x, ray_y, ray_z, norm_x, norm_y, norm_z); - if (fabs(product) < ${cleanup_cos_thresh}) {continue;} - U num_points = newmap[get_map_idx(nidx, 3)]; - if (num_points > ${wall_num_thresh} && non_updated_t < 1.0) {continue;} - - // Finally, this cell is penetrated by the ray. - atomicAdd(&map[get_map_idx(nidx, 2)], -${cleanup_step}/(ray_length / ${max_ray_length})); - atomicAdd(&map[get_map_idx(nidx, 1)], ${outlier_variance}); - // Do upper bound check. - if (nz < nmap_upper || nmap_is_upper < 0.5) { - map[get_map_idx(nidx, 5)] = nz; - map[get_map_idx(nidx, 6)] = 1.0f; - } - } - } - } - p[i * 3]= idx; - p[i * 3 + 1] = is_valid(x, y, z, t[0], t[1], t[2]); - p[i * 3 + 2] = is_inside(idx); - """ - ).substitute( - mahalanobis_thresh=mahalanobis_thresh, - outlier_variance=outlier_variance, - wall_num_thresh=wall_num_thresh, - ray_step=resolution / 2 ** 0.5, - max_ray_length=max_ray_length, - cleanup_step=cleanup_step, - cleanup_cos_thresh=cleanup_cos_thresh, - enable_edge_shaped=int(enable_edge_shaped), - enable_visibility_cleanup=int(enable_visibility_cleanup), - ), - name="add_points_kernel", - ) - return add_points_kernel - - -def error_counting_kernel( - resolution, - width, - height, - sensor_noise_factor, - mahalanobis_thresh, - outlier_variance, - traversability_inlier, - min_valid_distance, - max_height_range, - ramped_height_range_a, - ramped_height_range_b, - ramped_height_range_c, -): - error_counting_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U p, raw U center_x, raw U center_y, raw U R, raw U t", - out_params="raw U newmap, raw T error, raw T error_cnt", - preamble=map_utils( - resolution, - width, - height, - sensor_noise_factor, - min_valid_distance, - max_height_range, - ramped_height_range_a, - ramped_height_range_b, - ramped_height_range_c, - ), - operation=string.Template( - """ - U rx = p[i * 3]; - U ry = p[i * 3 + 1]; - U rz = p[i * 3 + 2]; - U x = transform_p(rx, ry, rz, R[0], R[1], R[2], t[0]); - U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); - U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); - U v = z_noise(rz); - // if (!is_valid(z, t[2])) {return;} - if (!is_valid(x, y, z, t[0], t[1], t[2])) {return;} - // if ((x - t[0]) * (x - t[0]) + (y - t[1]) * (y - t[1]) + (z - t[2]) * (z - t[2]) < 0.5) {return;} - int idx = get_idx(x, y, center_x[0], center_y[0]); - if (!is_inside(idx)) { - return; - } - U map_h = map[get_map_idx(idx, 0)]; - U map_v = map[get_map_idx(idx, 1)]; - U map_valid = map[get_map_idx(idx, 2)]; - U map_t = map[get_map_idx(idx, 3)]; - if (map_valid > 0.5 && (abs(map_h - z) < (map_v * ${mahalanobis_thresh})) - && map_v < ${outlier_variance} / 2.0 - && map_t > ${traversability_inlier}) { - T e = z - map_h; - atomicAdd(&error[0], e); - atomicAdd(&error_cnt[0], 1); - atomicAdd(&newmap[get_map_idx(idx, 3)], 1.0); - } - atomicAdd(&newmap[get_map_idx(idx, 4)], 1.0); - """ - ).substitute( - mahalanobis_thresh=mahalanobis_thresh, - outlier_variance=outlier_variance, - traversability_inlier=traversability_inlier, - ), - name="error_counting_kernel", - ) - return error_counting_kernel - - -def average_map_kernel(width, height, max_variance, initial_variance): - average_map_kernel = cp.ElementwiseKernel( - in_params="raw U newmap", - out_params="raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U h = map[get_map_idx(i, 0)]; - U v = map[get_map_idx(i, 1)]; - U valid = map[get_map_idx(i, 2)]; - U new_h = newmap[get_map_idx(i, 0)]; - U new_v = newmap[get_map_idx(i, 1)]; - U new_cnt = newmap[get_map_idx(i, 2)]; - if (new_cnt > 0) { - if (new_v / new_cnt > ${max_variance}) { - map[get_map_idx(i, 0)] = 0; - map[get_map_idx(i, 1)] = ${initial_variance}; - map[get_map_idx(i, 2)] = 0; - } - else { - map[get_map_idx(i, 0)] = new_h / new_cnt; - map[get_map_idx(i, 1)] = new_v / new_cnt; - map[get_map_idx(i, 2)] = 1; - } - } - if (valid < 0.5) { - map[get_map_idx(i, 0)] = 0; - map[get_map_idx(i, 1)] = ${initial_variance}; - map[get_map_idx(i, 2)] = 0; - } - """ - ).substitute(max_variance=max_variance, initial_variance=initial_variance), - name="average_map_kernel", - ) - return average_map_kernel - - -def dilation_filter_kernel(width, height, dilation_size): - dilation_filter_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U mask", - out_params="raw U newmap, raw U newmask", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - - __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { - const int layer = ${width} * ${height}; - const int relative_idx = idx + ${width} * dy + dx; - return layer * layer_n + relative_idx; - } - __device__ bool is_inside(int idx) { - int idx_x = idx / ${width}; - int idx_y = idx % ${width}; - if (idx_x <= 0 || idx_x >= ${width} - 1) { - return false; - } - if (idx_y <= 0 || idx_y >= ${height} - 1) { - return false; - } - return true; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U h = map[get_map_idx(i, 0)]; - U valid = mask[get_map_idx(i, 0)]; - newmap[get_map_idx(i, 0)] = h; - if (valid < 0.5) { - U distance = 100; - U near_value = 0; - for (int dy = -${dilation_size}; dy <= ${dilation_size}; dy++) { - for (int dx = -${dilation_size}; dx <= ${dilation_size}; dx++) { - int idx = get_relative_map_idx(i, dx, dy, 0); - if (!is_inside(idx)) {continue;} - U valid = mask[idx]; - if(valid > 0.5 && dx + dy < distance) { - distance = dx + dy; - near_value = map[idx]; - } - } - } - if(distance < 100) { - newmap[get_map_idx(i, 0)] = near_value; - newmask[get_map_idx(i, 0)] = 1.0; - } - } - """ - ).substitute(dilation_size=dilation_size), - name="dilation_filter_kernel", - ) - return dilation_filter_kernel - - -def normal_filter_kernel(width, height, resolution): - normal_filter_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U mask", - out_params="raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - - __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { - const int layer = ${width} * ${height}; - const int relative_idx = idx + ${width} * dy + dx; - return layer * layer_n + relative_idx; - } - __device__ bool is_inside(int idx) { - int idx_x = idx / ${width}; - int idx_y = idx % ${width}; - if (idx_x <= 0 || idx_x >= ${width} - 1) { - return false; - } - if (idx_y <= 0 || idx_y >= ${height} - 1) { - return false; - } - return true; - } - __device__ float resolution() { - return ${resolution}; - } - """ - ).substitute(width=width, height=height, resolution=resolution), - operation=string.Template( - """ - U h = map[get_map_idx(i, 0)]; - U valid = mask[get_map_idx(i, 0)]; - if (valid > 0.5) { - int idx_x = get_relative_map_idx(i, 1, 0, 0); - int idx_y = get_relative_map_idx(i, 0, 1, 0); - if (!is_inside(idx_x) || !is_inside(idx_y)) { return; } - float dzdx = (map[idx_x] - h); - float dzdy = (map[idx_y] - h); - float nx = -dzdy / resolution(); - float ny = -dzdx / resolution(); - float nz = 1; - float norm = sqrt((nx * nx) + (ny * ny) + 1); - newmap[get_map_idx(i, 0)] = nx / norm; - newmap[get_map_idx(i, 1)] = ny / norm; - newmap[get_map_idx(i, 2)] = nz / norm; - } - """ - ).substitute(), - name="normal_filter_kernel", - ) - return normal_filter_kernel - - -def polygon_mask_kernel(width, height, resolution): - polygon_mask_kernel = cp.ElementwiseKernel( - in_params="raw U polygon, raw U center_x, raw U center_y, raw int16 polygon_n, raw U polygon_bbox", - out_params="raw U mask", - preamble=string.Template( - """ - __device__ struct Point - { - int x; - int y; - }; - // Given three colinear points p, q, r, the function checks if - // point q lies on line segment 'pr' - __device__ bool onSegment(Point p, Point q, Point r) - { - if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) && - q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y)) - return true; - return false; - } - // To find orientation of ordered triplet (p, q, r). - // The function returns following values - // 0 --> p, q and r are colinear - // 1 --> Clockwise - // 2 --> Counterclockwise - __device__ int orientation(Point p, Point q, Point r) - { - int val = (q.y - p.y) * (r.x - q.x) - - (q.x - p.x) * (r.y - q.y); - if (val == 0) return 0; // colinear - return (val > 0)? 1: 2; // clock or counterclock wise - } - // The function that returns true if line segment 'p1q1' - // and 'p2q2' intersect. - __device__ bool doIntersect(Point p1, Point q1, Point p2, Point q2) - { - // Find the four orientations needed for general and - // special cases - int o1 = orientation(p1, q1, p2); - int o2 = orientation(p1, q1, q2); - int o3 = orientation(p2, q2, p1); - int o4 = orientation(p2, q2, q1); - // General case - if (o1 != o2 && o3 != o4) - return true; - // Special Cases - // p1, q1 and p2 are colinear and p2 lies on segment p1q1 - if (o1 == 0 && onSegment(p1, p2, q1)) return true; - // p1, q1 and p2 are colinear and q2 lies on segment p1q1 - if (o2 == 0 && onSegment(p1, q2, q1)) return true; - // p2, q2 and p1 are colinear and p1 lies on segment p2q2 - if (o3 == 0 && onSegment(p2, p1, q2)) return true; - // p2, q2 and q1 are colinear and q1 lies on segment p2q2 - if (o4 == 0 && onSegment(p2, q1, q2)) return true; - return false; // Doesn't fall in any of the above cases - } - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - - __device__ int get_idx_x(int idx){ - int idx_x = idx / ${width}; - return idx_x; - } - - __device__ int get_idx_y(int idx){ - int idx_y = idx % ${width}; - return idx_y; - } - - __device__ float16 clamp(float16 x, float16 min_x, float16 max_x) { - - return max(min(x, max_x), min_x); - } - __device__ float16 round(float16 x) { - return (int)x + (int)(2 * (x - (int)x)); - } - __device__ int get_x_idx(float16 x, float16 center) { - const float resolution = ${resolution}; - const float width = ${width}; - int i = (x - center) / resolution + 0.5 * width; - return i; - } - __device__ int get_y_idx(float16 y, float16 center) { - const float resolution = ${resolution}; - const float height = ${height}; - int i = (y - center) / resolution + 0.5 * height; - return i; - } - __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { - int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); - int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); - return ${width} * idx_x + idx_y; - } - - """ - ).substitute(width=width, height=height, resolution=resolution), - operation=string.Template( - """ - // Point p = {get_idx_x(i, center_x[0]), get_idx_y(i, center_y[0])}; - Point p = {get_idx_x(i), get_idx_y(i)}; - Point extreme = {100000, p.y}; - int bbox_min_idx = get_idx(polygon_bbox[0], polygon_bbox[1], center_x[0], center_y[0]); - int bbox_max_idx = get_idx(polygon_bbox[2], polygon_bbox[3], center_x[0], center_y[0]); - Point bmin = {get_idx_x(bbox_min_idx), get_idx_y(bbox_min_idx)}; - Point bmax = {get_idx_x(bbox_max_idx), get_idx_y(bbox_max_idx)}; - if (p.x < bmin.x || p.x > bmax.x || p.y < bmin.y || p.y > bmax.y){ - mask[i] = 0; - return; - } - else { - int intersect_cnt = 0; - for (int j = 0; j < polygon_n[0]; j++) { - Point p1, p2; - int i1 = get_idx(polygon[j * 2 + 0], polygon[j * 2 + 1], center_x[0], center_y[0]); - p1.x = get_idx_x(i1); - p1.y = get_idx_y(i1); - int j2 = (j + 1) % polygon_n[0]; - int i2 = get_idx(polygon[j2 * 2 + 0], polygon[j2 * 2 + 1], center_x[0], center_y[0]); - p2.x = get_idx_x(i2); - p2.y = get_idx_y(i2); - if (doIntersect(p1, p2, p, extreme)) - { - // If the point 'p' is colinear with line segment 'i-next', - // then check if it lies on segment. If it lies, return true, - // otherwise false - if (orientation(p1, p, p2) == 0) { - if (onSegment(p1, p, p2)){ - mask[i] = 1; - return; - } - } - else if(((p1.y <= p.y) && (p2.y > p.y)) || ((p1.y > p.y) && (p2.y <= p.y))){ - intersect_cnt++; - } - } - } - if (intersect_cnt % 2 == 0) { mask[i] = 0; } - else { mask[i] = 1; } - } - """ - ).substitute(a=1), - name="polygon_mask_kernel", - ) - return polygon_mask_kernel - - -if __name__ == "__main__": - for i in range(10): - import random - - a = cp.zeros((100, 100)) - n = random.randint(3, 5) - - # polygon = cp.array([[-1, -1], [3, 4], [2, 4], [1, 3]], dtype=float) - polygon = cp.array( - [[(random.random() - 0.5) * 10, (random.random() - 0.5) * 10] for i in range(n)], dtype=float - ) - print(polygon) - polygon_min = polygon.min(axis=0) - polygon_max = polygon.max(axis=0) - polygon_bbox = cp.concatenate([polygon_min, polygon_max]).flatten() - polygon_n = polygon.shape[0] - print(polygon_bbox) - # polygon_bbox = cp.array([-5, -5, 5, 5], dtype=float) - polygon_mask = polygon_mask_kernel(100, 100, 0.1) - import time - - start = time.time() - polygon_mask(polygon, 0.0, 0.0, polygon_n, polygon_bbox, a, size=(100 * 100)) - print(time.time() - start) - import pylab as plt - - print(a) - plt.imshow(cp.asnumpy(a)) - plt.show() diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_semantic_kernels.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_semantic_kernels.py deleted file mode 100644 index 26db74c0..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/custom_semantic_kernels.py +++ /dev/null @@ -1,375 +0,0 @@ -# -# Copyright (c) 2023, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import string - - -def sum_kernel( - resolution, width, height, -): - """Sums the semantic values of the classes for the exponentiala verage or for the average. - - Args: - resolution: - width: - height: - - Returns: - - """ - # input the list of layers, amount of channels can slo be input through kernel - sum_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params="raw U map, raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(resolution=resolution, width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U idx = p[id * pcl_channels[0]]; - U valid = p[id * pcl_channels[0] + 1]; - U inside = p[id * pcl_channels[0] + 2]; - if (valid) { - if (inside) { - U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; - atomicAdd(&newmap[get_map_idx(idx, map_lay[layer])], feat); - } - } - """ - ).substitute(), - name="sum_kernel", - ) - return sum_kernel - - -def sum_compact_kernel( - resolution, width, height, -): - # input the list of layers, amount of channels can slo be input through kernel - sum_compact_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params=" raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(resolution=resolution, width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U idx = p[id * pcl_channels[0]]; - U valid = p[id * pcl_channels[0] + 1]; - U inside = p[id * pcl_channels[0] + 2]; - if (valid) { - if (inside) { - U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; - atomicAdd(&newmap[get_map_idx(idx, layer)], feat); - } - } - """ - ).substitute(), - name="sum_compact_kernel", - ) - return sum_compact_kernel - - -def sum_max_kernel( - resolution, width, height, -): - # input the list of layers, amount of channels can slo be input through kernel - sum_max_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U max_pt, raw T max_id, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params=" raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(resolution=resolution, width=width, height=height), - operation=string.Template( - """ - U idx = p[i * pcl_channels[0]]; - U valid = p[i * pcl_channels[0] + 1]; - U inside = p[i * pcl_channels[0] + 2]; - if (valid) { - if (inside) { - // for every max value - for ( W it=0;it=theta_max){ - arg_max = map_lay[layer]; - theta_max = theta; - } - atomicAdd(&newmap[get_map_idx(idx, arg_max)], theta_max); - } - } - """ - ).substitute(), - name="alpha_kernel", - ) - return alpha_kernel - - -def average_kernel( - width, height, -): - average_kernel = cp.ElementwiseKernel( - in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", - out_params="raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U cnt = new_elmap[get_map_idx(id, 2)]; - if (cnt>0){ - U feat = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); - map[get_map_idx(id, map_lay[layer])] = feat; - } - """ - ).substitute(), - name="average_map_kernel", - ) - return average_kernel - - -def bayesian_inference_kernel( - width, height, -): - bayesian_inference_kernel = cp.ElementwiseKernel( - in_params=" raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", - out_params="raw U newmap, raw U sum_mean, raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U cnt = new_elmap[get_map_idx(id, 2)]; - if (cnt>0){ - U feat_ml = sum_mean[get_map_idx(id, layer)]/cnt; - U feat_old = map[get_map_idx(id, map_lay[layer])]; - U sigma_old = newmap[get_map_idx(id, map_lay[layer])]; - U sigma = 1.0; - U feat_new = sigma*feat_old /(cnt*sigma_old + sigma) +cnt*sigma_old *feat_ml /(cnt*sigma_old+sigma); - U sigma_new = sigma*sigma_old /(cnt*sigma_old +sigma); - map[get_map_idx(id, map_lay[layer])] = feat_new; - newmap[get_map_idx(id, map_lay[layer])] = sigma_new; - } - """ - ).substitute(), - name="bayesian_inference_kernel", - ) - return bayesian_inference_kernel - - -def class_average_kernel( - width, height, alpha, -): - class_average_kernel = cp.ElementwiseKernel( - in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", - out_params="raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U cnt = new_elmap[get_map_idx(id, 2)]; - if (cnt>0){ - U prev_val = map[get_map_idx(id, map_lay[layer])]; - if (prev_val==0){ - U val = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); - map[get_map_idx(id, map_lay[layer])] = val; - } - else{ - U val = ${alpha} *prev_val + (1-${alpha}) * newmap[get_map_idx(id, map_lay[layer])]/(cnt); - map[get_map_idx(id, map_lay[layer])] = val; - } - } - """ - ).substitute(alpha=alpha,), - name="class_average_kernel", - ) - return class_average_kernel - - -def add_color_kernel( - width, height, -): - add_color_kernel = cp.ElementwiseKernel( - in_params="raw T p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params="raw V color_map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - __device__ unsigned int get_r(unsigned int color){ - unsigned int red = 0xFF0000; - unsigned int reds = (color & red) >> 16; - return reds; - } - __device__ unsigned int get_g(unsigned int color){ - unsigned int green = 0xFF00; - unsigned int greens = (color & green) >> 8; - return greens; - } - __device__ unsigned int get_b(unsigned int color){ - unsigned int blue = 0xFF; - unsigned int blues = ( color & blue); - return blues; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U idx = p[id * pcl_channels[0]]; - U valid = p[id * pcl_channels[0] + 1]; - U inside = p[id * pcl_channels[0] + 2]; - if (valid && inside){ - unsigned int color = __float_as_uint(p[id * pcl_channels[0] + pcl_chan[layer]]); - atomicAdd(&color_map[get_map_idx(idx, layer*3)], get_r(color)); - atomicAdd(&color_map[get_map_idx(idx, layer*3+1)], get_g(color)); - atomicAdd(&color_map[get_map_idx(idx, layer*3 + 2)], get_b(color)); - atomicAdd(&color_map[get_map_idx(idx, pcl_channels[1]*3)], 1); - } - """ - ).substitute(width=width), - name="add_color_kernel", - ) - return add_color_kernel - - -def color_average_kernel( - width, height, -): - color_average_kernel = cp.ElementwiseKernel( - in_params="raw V color_map, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params="raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - __device__ unsigned int get_r(unsigned int color){ - unsigned int red = 0xFF0000; - unsigned int reds = (color & red) >> 16; - return reds; - } - __device__ unsigned int get_g(unsigned int color){ - unsigned int green = 0xFF00; - unsigned int greens = (color & green) >> 8; - return greens; - } - __device__ unsigned int get_b(unsigned int color){ - unsigned int blue = 0xFF; - unsigned int blues = (color & blue); - return blues; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - unsigned int cnt = color_map[get_map_idx(id, pcl_channels[1]*3)]; - if (cnt>0){ - // U prev_color = map[get_map_idx(id, map_lay[layer])]; - unsigned int r = color_map[get_map_idx(id, layer*3)]/(1*cnt); - unsigned int g = color_map[get_map_idx(id, layer*3+1)]/(1*cnt); - unsigned int b = color_map[get_map_idx(id, layer*3+2)]/(1*cnt); - //if (prev_color>=0){ - // unsigned int prev_r = get_r(prev_color); - // unsigned int prev_g = get_g(prev_color); - // unsigned int prev_b = get_b(prev_color); - // unsigned int r = prev_r/2 + color_map[get_map_idx(i, layer*3)]/(2*cnt); - // unsigned int g = prev_g/2 + color_map[get_map_idx(i, layer*3+1)]/(2*cnt); - // unsigned int b = prev_b/2 + color_map[get_map_idx(i, layer*3+2)]/(2*cnt); - //} - unsigned int rgb = (r<<16) + (g << 8) + b; - float rgb_ = __uint_as_float(rgb); - map[get_map_idx(id, map_lay[layer])] = rgb_; - } - """ - ).substitute(), - name="color_average_kernel", - ) - return color_average_kernel diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/kk.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/kk.py deleted file mode 100644 index 27562dda..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/kernels/kk.py +++ /dev/null @@ -1,1290 +0,0 @@ -# -# Copyright (c) 2023, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import string - - -def sum_kernel( - resolution, width, height, -): - """Sums the semantic values of the classes for the exponentiala verage or for the average. - - Args: - resolution: - width: - height: - - Returns: - - """ - # input the list of layers, amount of channels can slo be input through kernel - sum_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params="raw U map, raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(resolution=resolution, width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U idx = p[id * pcl_channels[0]]; - U valid = p[id * pcl_channels[0] + 1]; - U inside = p[id * pcl_channels[0] + 2]; - if (valid) { - if (inside) { - U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; - atomicAdd(&newmap[get_map_idx(idx, map_lay[layer])], feat); - } - } - """ - ).substitute(), - name="sum_kernel", - ) - return sum_kernel - - -def sum_compact_kernel( - resolution, width, height, -): - # input the list of layers, amount of channels can slo be input through kernel - sum_compact_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params=" raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(resolution=resolution, width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U idx = p[id * pcl_channels[0]]; - U valid = p[id * pcl_channels[0] + 1]; - U inside = p[id * pcl_channels[0] + 2]; - if (valid) { - if (inside) { - U feat = p[id * pcl_channels[0] + pcl_chan[layer]]; - atomicAdd(&newmap[get_map_idx(idx, layer)], feat); - } - } - """ - ).substitute(), - name="sum_compact_kernel", - ) - return sum_compact_kernel - - -def sum_max_kernel( - resolution, width, height, -): - # input the list of layers, amount of channels can slo be input through kernel - sum_max_kernel = cp.ElementwiseKernel( - in_params="raw U p, raw U max_pt, raw T max_id, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params=" raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(resolution=resolution, width=width, height=height), - operation=string.Template( - """ - U idx = p[i * pcl_channels[0]]; - U valid = p[i * pcl_channels[0] + 1]; - U inside = p[i * pcl_channels[0] + 2]; - if (valid) { - if (inside) { - // for every max value - for ( W it=0;it=theta_max){ - arg_max = map_lay[layer]; - theta_max = theta; - } - atomicAdd(&newmap[get_map_idx(idx, arg_max)], theta_max); - } - } - """ - ).substitute(), - name="alpha_kernel", - ) - return alpha_kernel - - -def average_kernel( - width, height, -): - average_kernel = cp.ElementwiseKernel( - in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", - out_params="raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U cnt = new_elmap[get_map_idx(id, 2)]; - if (cnt>0){ - U feat = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); - map[get_map_idx(id, map_lay[layer])] = feat; - } - """ - ).substitute(), - name="average_map_kernel", - ) - return average_kernel - - -def bayesian_inference_kernel( - width, height, -): - bayesian_inference_kernel = cp.ElementwiseKernel( - in_params=" raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", - out_params="raw U newmap, raw U sum_mean, raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U cnt = new_elmap[get_map_idx(id, 2)]; - if (cnt>0){ - U feat_ml = sum_mean[get_map_idx(id, layer)]/cnt; - U feat_old = map[get_map_idx(id, map_lay[layer])]; - U sigma_old = newmap[get_map_idx(id, map_lay[layer])]; - U sigma = 1.0; - U feat_new = sigma*feat_old /(cnt*sigma_old + sigma) +cnt*sigma_old *feat_ml /(cnt*sigma_old+sigma); - U sigma_new = sigma*sigma_old /(cnt*sigma_old +sigma); - map[get_map_idx(id, map_lay[layer])] = feat_new; - newmap[get_map_idx(id, map_lay[layer])] = sigma_new; - } - """ - ).substitute(), - name="bayesian_inference_kernel", - ) - return bayesian_inference_kernel - - -def class_average_kernel( - width, height, alpha, -): - class_average_kernel = cp.ElementwiseKernel( - in_params="raw V newmap, raw W pcl_chan, raw W map_lay, raw W pcl_channels, raw U new_elmap", - out_params="raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U cnt = new_elmap[get_map_idx(id, 2)]; - if (cnt>0){ - U prev_val = map[get_map_idx(id, map_lay[layer])]; - if (prev_val==0){ - U val = newmap[get_map_idx(id, map_lay[layer])]/(1*cnt); - map[get_map_idx(id, map_lay[layer])] = val; - } - else{ - U val = ${alpha} *prev_val + (1-${alpha}) * newmap[get_map_idx(id, map_lay[layer])]/(cnt); - map[get_map_idx(id, map_lay[layer])] = val; - } - } - """ - ).substitute(alpha=alpha,), - name="class_average_kernel", - ) - return class_average_kernel - - -def add_color_kernel( - width, height, -): - add_color_kernel = cp.ElementwiseKernel( - in_params="raw T p, raw U R, raw U t, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params="raw V color_map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - __device__ unsigned int get_r(unsigned int color){ - unsigned int red = 0xFF0000; - unsigned int reds = (color & red) >> 16; - return reds; - } - __device__ unsigned int get_g(unsigned int color){ - unsigned int green = 0xFF00; - unsigned int greens = (color & green) >> 8; - return greens; - } - __device__ unsigned int get_b(unsigned int color){ - unsigned int blue = 0xFF; - unsigned int blues = ( color & blue); - return blues; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - U idx = p[id * pcl_channels[0]]; - U valid = p[id * pcl_channels[0] + 1]; - U inside = p[id * pcl_channels[0] + 2]; - if (valid && inside){ - unsigned int color = __float_as_uint(p[id * pcl_channels[0] + pcl_chan[layer]]); - atomicAdd(&color_map[get_map_idx(idx, layer*3)], get_r(color)); - atomicAdd(&color_map[get_map_idx(idx, layer*3+1)], get_g(color)); - atomicAdd(&color_map[get_map_idx(idx, layer*3 + 2)], get_b(color)); - atomicAdd(&color_map[get_map_idx(idx, pcl_channels[1]*3)], 1); - } - """ - ).substitute(width=width), - name="add_color_kernel", - ) - return add_color_kernel - - -def color_average_kernel( - width, height, -): - color_average_kernel = cp.ElementwiseKernel( - in_params="raw V color_map, raw W pcl_chan, raw W map_lay, raw W pcl_channels", - out_params="raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - __device__ unsigned int get_r(unsigned int color){ - unsigned int red = 0xFF0000; - unsigned int reds = (color & red) >> 16; - return reds; - } - __device__ unsigned int get_g(unsigned int color){ - unsigned int green = 0xFF00; - unsigned int greens = (color & green) >> 8; - return greens; - } - __device__ unsigned int get_b(unsigned int color){ - unsigned int blue = 0xFF; - unsigned int blues = (color & blue); - return blues; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U id = floorf(i/pcl_channels[1]); - int layer = i % pcl_channels[1]; - unsigned int cnt = color_map[get_map_idx(id, pcl_channels[1]*3)]; - if (cnt>0){ - // U prev_color = map[get_map_idx(id, map_lay[layer])]; - unsigned int r = color_map[get_map_idx(id, layer*3)]/(1*cnt); - unsigned int g = color_map[get_map_idx(id, layer*3+1)]/(1*cnt); - unsigned int b = color_map[get_map_idx(id, layer*3+2)]/(1*cnt); - //if (prev_color>=0){ - // unsigned int prev_r = get_r(prev_color); - // unsigned int prev_g = get_g(prev_color); - // unsigned int prev_b = get_b(prev_color); - // unsigned int r = prev_r/2 + color_map[get_map_idx(i, layer*3)]/(2*cnt); - // unsigned int g = prev_g/2 + color_map[get_map_idx(i, layer*3+1)]/(2*cnt); - // unsigned int b = prev_b/2 + color_map[get_map_idx(i, layer*3+2)]/(2*cnt); - //} - unsigned int rgb = (r<<16) + (g << 8) + b; - float rgb_ = __uint_as_float(rgb); - map[get_map_idx(id, map_lay[layer])] = rgb_; - } - """ - ).substitute(), - name="color_average_kernel", - ) - return color_average_kernel - - - -def map_utils( - resolution, - width, - height, - sensor_noise_factor, - min_valid_distance, - max_height_range, - ramped_height_range_a, - ramped_height_range_b, - ramped_height_range_c, -): - util_preamble = string.Template( - """ - __device__ float16 clamp(float16 x, float16 min_x, float16 max_x) { - - return max(min(x, max_x), min_x); - } - __device__ int get_x_idx(float16 x, float16 center) { - int i = (x - center) / ${resolution} + 0.5 * ${width}; - return i; - } - __device__ int get_y_idx(float16 y, float16 center) { - int i = (y - center) / ${resolution} + 0.5 * ${height}; - return i; - } - __device__ bool is_inside(int idx) { - int idx_x = idx / ${width}; - int idx_y = idx % ${width}; - if (idx_x == 0 || idx_x == ${width} - 1) { - return false; - } - if (idx_y == 0 || idx_y == ${height} - 1) { - return false; - } - return true; - } - __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { - int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); - int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); - return ${width} * idx_x + idx_y; - } - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - __device__ float transform_p(float16 x, float16 y, float16 z, - float16 r0, float16 r1, float16 r2, float16 t) { - return r0 * x + r1 * y + r2 * z + t; - } - __device__ float z_noise(float16 z){ - return ${sensor_noise_factor} * z * z; - } - - __device__ float point_sensor_distance(float16 x, float16 y, float16 z, - float16 sx, float16 sy, float16 sz) { - float d = (x - sx) * (x - sx) + (y - sy) * (y - sy) + (z - sz) * (z - sz); - return d; - } - - __device__ bool is_valid(float16 x, float16 y, float16 z, - float16 sx, float16 sy, float16 sz) { - float d = point_sensor_distance(x, y, z, sx, sy, sz); - float dxy = max(sqrt(x * x + y * y) - ${ramped_height_range_b}, 0.0); - if (d < ${min_valid_distance} * ${min_valid_distance}) { - return false; - } - else if (z - sz > dxy * ${ramped_height_range_a} + ${ramped_height_range_c} || z - sz > ${max_height_range}) { - return false; - } - else { - return true; - } - } - - __device__ float ray_vector(float16 tx, float16 ty, float16 tz, - float16 px, float16 py, float16 pz, - float16& rx, float16& ry, float16& rz){ - float16 vx = px - tx; - float16 vy = py - ty; - float16 vz = pz - tz; - float16 norm = sqrt(vx * vx + vy * vy + vz * vz); - if (norm > 0) { - rx = vx / norm; - ry = vy / norm; - rz = vz / norm; - } - else { - rx = 0; - ry = 0; - rz = 0; - } - return norm; - } - - __device__ float inner_product(float16 x1, float16 y1, float16 z1, - float16 x2, float16 y2, float16 z2) { - - float product = (x1 * x2 + y1 * y2 + z1 * z2); - return product; - } - - """ - ).substitute( - resolution=resolution, - width=width, - height=height, - sensor_noise_factor=sensor_noise_factor, - min_valid_distance=min_valid_distance, - max_height_range=max_height_range, - ramped_height_range_a=ramped_height_range_a, - ramped_height_range_b=ramped_height_range_b, - ramped_height_range_c=ramped_height_range_c, - ) - return util_preamble - - -def add_points_kernel( - resolution, - width, - height, - sensor_noise_factor, - mahalanobis_thresh, - outlier_variance, - wall_num_thresh, - max_ray_length, - cleanup_step, - min_valid_distance, - max_height_range, - cleanup_cos_thresh, - ramped_height_range_a, - ramped_height_range_b, - ramped_height_range_c, - enable_edge_shaped=True, - enable_visibility_cleanup=True, -): - add_points_kernel = cp.ElementwiseKernel( - in_params="raw U center_x, raw U center_y, raw U R, raw U t, raw U norm_map", - out_params="raw U p, raw U map, raw T newmap", - preamble=map_utils( - resolution, - width, - height, - sensor_noise_factor, - min_valid_distance, - max_height_range, - ramped_height_range_a, - ramped_height_range_b, - ramped_height_range_c, - ), - operation=string.Template( - """ - U rx = p[i * 3]; - U ry = p[i * 3 + 1]; - U rz = p[i * 3 + 2]; - U x = transform_p(rx, ry, rz, R[0], R[1], R[2], t[0]); - U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); - U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); - U v = z_noise(rz); - int idx = get_idx(x, y, center_x[0], center_y[0]); - if (is_valid(x, y, z, t[0], t[1], t[2])) { - if (is_inside(idx)) { - U map_h = map[get_map_idx(idx, 0)]; - U map_v = map[get_map_idx(idx, 1)]; - U num_points = newmap[get_map_idx(idx, 4)]; - if (abs(map_h - z) > (map_v * ${mahalanobis_thresh})) { - atomicAdd(&map[get_map_idx(idx, 1)], ${outlier_variance}); - } - else { - if (${enable_edge_shaped} && (num_points > ${wall_num_thresh}) && (z < map_h - map_v * ${mahalanobis_thresh} / num_points)) { - // continue; - } - else { - T new_h = (map_h * v + z * map_v) / (map_v + v); - T new_v = (map_v * v) / (map_v + v); - atomicAdd(&newmap[get_map_idx(idx, 0)], new_h); - atomicAdd(&newmap[get_map_idx(idx, 1)], new_v); - atomicAdd(&newmap[get_map_idx(idx, 2)], 1.0); - // is Valid - map[get_map_idx(idx, 2)] = 1; - // Time layer - map[get_map_idx(idx, 4)] = 0.0; - // Upper bound - map[get_map_idx(idx, 5)] = new_h; - map[get_map_idx(idx, 6)] = 0.0; - } - // visibility cleanup - } - } - } - if (${enable_visibility_cleanup}) { - float16 ray_x, ray_y, ray_z; - float16 ray_length = ray_vector(t[0], t[1], t[2], x, y, z, ray_x, ray_y, ray_z); - ray_length = min(ray_length, (float16)${max_ray_length}); - int last_nidx = -1; - for (float16 s=${ray_step}; s < ray_length; s+=${ray_step}) { - // iterate through ray - U nx = t[0] + ray_x * s; - U ny = t[1] + ray_y * s; - U nz = t[2] + ray_z * s; - int nidx = get_idx(nx, ny, center_x[0], center_y[0]); - if (last_nidx == nidx) {continue;} // Skip if we're still in the same cell - else {last_nidx = nidx;} - if (!is_inside(nidx)) {continue;} - - U nmap_h = map[get_map_idx(nidx, 0)]; - U nmap_v = map[get_map_idx(nidx, 1)]; - U nmap_valid = map[get_map_idx(nidx, 2)]; - // traversability - U nmap_trav = map[get_map_idx(nidx, 3)]; - // Time layer - U non_updated_t = map[get_map_idx(nidx, 4)]; - // upper bound - U nmap_upper = map[get_map_idx(nidx, 5)]; - U nmap_is_upper = map[get_map_idx(nidx, 6)]; - - // If point is close or is farther away than ray length, skip. - float16 d = (x - nx) * (x - nx) + (y - ny) * (y - ny) + (z - nz) * (z - nz); - if (d < 0.1 || !is_valid(x, y, z, t[0], t[1], t[2])) {continue;} - - // If invalid, do upper bound check, then skip - if (nmap_valid < 0.5) { - if (nz < nmap_upper || nmap_is_upper < 0.5) { - map[get_map_idx(nidx, 5)] = nz; - map[get_map_idx(nidx, 6)] = 1.0f; - } - continue; - } - // If updated recently, skip - if (non_updated_t < 0.5) {continue;} - - if (nmap_h > nz + 0.01 - min(nmap_v, 1.0) * 0.05) { - // If ray and norm is vertical, skip - U norm_x = norm_map[get_map_idx(nidx, 0)]; - U norm_y = norm_map[get_map_idx(nidx, 1)]; - U norm_z = norm_map[get_map_idx(nidx, 2)]; - float product = inner_product(ray_x, ray_y, ray_z, norm_x, norm_y, norm_z); - if (fabs(product) < ${cleanup_cos_thresh}) {continue;} - U num_points = newmap[get_map_idx(nidx, 3)]; - if (num_points > ${wall_num_thresh} && non_updated_t < 1.0) {continue;} - - // Finally, this cell is penetrated by the ray. - atomicAdd(&map[get_map_idx(nidx, 2)], -${cleanup_step}/(ray_length / ${max_ray_length})); - atomicAdd(&map[get_map_idx(nidx, 1)], ${outlier_variance}); - // Do upper bound check. - if (nz < nmap_upper || nmap_is_upper < 0.5) { - map[get_map_idx(nidx, 5)] = nz; - map[get_map_idx(nidx, 6)] = 1.0f; - } - } - } - } - p[i * 3]= idx; - p[i * 3 + 1] = is_valid(x, y, z, t[0], t[1], t[2]); - p[i * 3 + 2] = is_inside(idx); - """ - ).substitute( - mahalanobis_thresh=mahalanobis_thresh, - outlier_variance=outlier_variance, - wall_num_thresh=wall_num_thresh, - ray_step=resolution / 2 ** 0.5, - max_ray_length=max_ray_length, - cleanup_step=cleanup_step, - cleanup_cos_thresh=cleanup_cos_thresh, - enable_edge_shaped=int(enable_edge_shaped), - enable_visibility_cleanup=int(enable_visibility_cleanup), - ), - name="add_points_kernel", - ) - return add_points_kernel - - -def error_counting_kernel( - resolution, - width, - height, - sensor_noise_factor, - mahalanobis_thresh, - outlier_variance, - traversability_inlier, - min_valid_distance, - max_height_range, - ramped_height_range_a, - ramped_height_range_b, - ramped_height_range_c, -): - error_counting_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U p, raw U center_x, raw U center_y, raw U R, raw U t", - out_params="raw U newmap, raw T error, raw T error_cnt", - preamble=map_utils( - resolution, - width, - height, - sensor_noise_factor, - min_valid_distance, - max_height_range, - ramped_height_range_a, - ramped_height_range_b, - ramped_height_range_c, - ), - operation=string.Template( - """ - U rx = p[i * 3]; - U ry = p[i * 3 + 1]; - U rz = p[i * 3 + 2]; - U x = transform_p(rx, ry, rz, R[0], R[1], R[2], t[0]); - U y = transform_p(rx, ry, rz, R[3], R[4], R[5], t[1]); - U z = transform_p(rx, ry, rz, R[6], R[7], R[8], t[2]); - U v = z_noise(rz); - // if (!is_valid(z, t[2])) {return;} - if (!is_valid(x, y, z, t[0], t[1], t[2])) {return;} - // if ((x - t[0]) * (x - t[0]) + (y - t[1]) * (y - t[1]) + (z - t[2]) * (z - t[2]) < 0.5) {return;} - int idx = get_idx(x, y, center_x[0], center_y[0]); - if (!is_inside(idx)) { - return; - } - U map_h = map[get_map_idx(idx, 0)]; - U map_v = map[get_map_idx(idx, 1)]; - U map_valid = map[get_map_idx(idx, 2)]; - U map_t = map[get_map_idx(idx, 3)]; - if (map_valid > 0.5 && (abs(map_h - z) < (map_v * ${mahalanobis_thresh})) - && map_v < ${outlier_variance} / 2.0 - && map_t > ${traversability_inlier}) { - T e = z - map_h; - atomicAdd(&error[0], e); - atomicAdd(&error_cnt[0], 1); - atomicAdd(&newmap[get_map_idx(idx, 3)], 1.0); - } - atomicAdd(&newmap[get_map_idx(idx, 4)], 1.0); - """ - ).substitute( - mahalanobis_thresh=mahalanobis_thresh, - outlier_variance=outlier_variance, - traversability_inlier=traversability_inlier, - ), - name="error_counting_kernel", - ) - return error_counting_kernel - - -def average_map_kernel(width, height, max_variance, initial_variance): - average_map_kernel = cp.ElementwiseKernel( - in_params="raw U newmap", - out_params="raw U map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U h = map[get_map_idx(i, 0)]; - U v = map[get_map_idx(i, 1)]; - U valid = map[get_map_idx(i, 2)]; - U new_h = newmap[get_map_idx(i, 0)]; - U new_v = newmap[get_map_idx(i, 1)]; - U new_cnt = newmap[get_map_idx(i, 2)]; - if (new_cnt > 0) { - if (new_v / new_cnt > ${max_variance}) { - map[get_map_idx(i, 0)] = 0; - map[get_map_idx(i, 1)] = ${initial_variance}; - map[get_map_idx(i, 2)] = 0; - } - else { - map[get_map_idx(i, 0)] = new_h / new_cnt; - map[get_map_idx(i, 1)] = new_v / new_cnt; - map[get_map_idx(i, 2)] = 1; - } - } - if (valid < 0.5) { - map[get_map_idx(i, 0)] = 0; - map[get_map_idx(i, 1)] = ${initial_variance}; - map[get_map_idx(i, 2)] = 0; - } - """ - ).substitute(max_variance=max_variance, initial_variance=initial_variance), - name="average_map_kernel", - ) - return average_map_kernel - - -def dilation_filter_kernel(width, height, dilation_size): - dilation_filter_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U mask", - out_params="raw U newmap, raw U newmask", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - - __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { - const int layer = ${width} * ${height}; - const int relative_idx = idx + ${width} * dy + dx; - return layer * layer_n + relative_idx; - } - __device__ bool is_inside(int idx) { - int idx_x = idx / ${width}; - int idx_y = idx % ${width}; - if (idx_x <= 0 || idx_x >= ${width} - 1) { - return false; - } - if (idx_y <= 0 || idx_y >= ${height} - 1) { - return false; - } - return true; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - U h = map[get_map_idx(i, 0)]; - U valid = mask[get_map_idx(i, 0)]; - newmap[get_map_idx(i, 0)] = h; - if (valid < 0.5) { - U distance = 100; - U near_value = 0; - for (int dy = -${dilation_size}; dy <= ${dilation_size}; dy++) { - for (int dx = -${dilation_size}; dx <= ${dilation_size}; dx++) { - int idx = get_relative_map_idx(i, dx, dy, 0); - if (!is_inside(idx)) {continue;} - U valid = mask[idx]; - if(valid > 0.5 && dx + dy < distance) { - distance = dx + dy; - near_value = map[idx]; - } - } - } - if(distance < 100) { - newmap[get_map_idx(i, 0)] = near_value; - newmask[get_map_idx(i, 0)] = 1.0; - } - } - """ - ).substitute(dilation_size=dilation_size), - name="dilation_filter_kernel", - ) - return dilation_filter_kernel - - -def normal_filter_kernel(width, height, resolution): - normal_filter_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U mask", - out_params="raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - - __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { - const int layer = ${width} * ${height}; - const int relative_idx = idx + ${width} * dy + dx; - return layer * layer_n + relative_idx; - } - __device__ bool is_inside(int idx) { - int idx_x = idx / ${width}; - int idx_y = idx % ${width}; - if (idx_x <= 0 || idx_x >= ${width} - 1) { - return false; - } - if (idx_y <= 0 || idx_y >= ${height} - 1) { - return false; - } - return true; - } - __device__ float resolution() { - return ${resolution}; - } - """ - ).substitute(width=width, height=height, resolution=resolution), - operation=string.Template( - """ - U h = map[get_map_idx(i, 0)]; - U valid = mask[get_map_idx(i, 0)]; - if (valid > 0.5) { - int idx_x = get_relative_map_idx(i, 1, 0, 0); - int idx_y = get_relative_map_idx(i, 0, 1, 0); - if (!is_inside(idx_x) || !is_inside(idx_y)) { return; } - float dzdx = (map[idx_x] - h); - float dzdy = (map[idx_y] - h); - float nx = -dzdy / resolution(); - float ny = -dzdx / resolution(); - float nz = 1; - float norm = sqrt((nx * nx) + (ny * ny) + 1); - newmap[get_map_idx(i, 0)] = nx / norm; - newmap[get_map_idx(i, 1)] = ny / norm; - newmap[get_map_idx(i, 2)] = nz / norm; - } - """ - ).substitute(), - name="normal_filter_kernel", - ) - return normal_filter_kernel - - -def polygon_mask_kernel(width, height, resolution): - polygon_mask_kernel = cp.ElementwiseKernel( - in_params="raw U polygon, raw U center_x, raw U center_y, raw int16 polygon_n, raw U polygon_bbox", - out_params="raw U mask", - preamble=string.Template( - """ - __device__ struct Point - { - int x; - int y; - }; - // Given three colinear points p, q, r, the function checks if - // point q lies on line segment 'pr' - __device__ bool onSegment(Point p, Point q, Point r) - { - if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) && - q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y)) - return true; - return false; - } - // To find orientation of ordered triplet (p, q, r). - // The function returns following values - // 0 --> p, q and r are colinear - // 1 --> Clockwise - // 2 --> Counterclockwise - __device__ int orientation(Point p, Point q, Point r) - { - int val = (q.y - p.y) * (r.x - q.x) - - (q.x - p.x) * (r.y - q.y); - if (val == 0) return 0; // colinear - return (val > 0)? 1: 2; // clock or counterclock wise - } - // The function that returns true if line segment 'p1q1' - // and 'p2q2' intersect. - __device__ bool doIntersect(Point p1, Point q1, Point p2, Point q2) - { - // Find the four orientations needed for general and - // special cases - int o1 = orientation(p1, q1, p2); - int o2 = orientation(p1, q1, q2); - int o3 = orientation(p2, q2, p1); - int o4 = orientation(p2, q2, q1); - // General case - if (o1 != o2 && o3 != o4) - return true; - // Special Cases - // p1, q1 and p2 are colinear and p2 lies on segment p1q1 - if (o1 == 0 && onSegment(p1, p2, q1)) return true; - // p1, q1 and p2 are colinear and q2 lies on segment p1q1 - if (o2 == 0 && onSegment(p1, q2, q1)) return true; - // p2, q2 and p1 are colinear and p1 lies on segment p2q2 - if (o3 == 0 && onSegment(p2, p1, q2)) return true; - // p2, q2 and q1 are colinear and q1 lies on segment p2q2 - if (o4 == 0 && onSegment(p2, q1, q2)) return true; - return false; // Doesn't fall in any of the above cases - } - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - - __device__ int get_idx_x(int idx){ - int idx_x = idx / ${width}; - return idx_x; - } - - __device__ int get_idx_y(int idx){ - int idx_y = idx % ${width}; - return idx_y; - } - - __device__ float16 clamp(float16 x, float16 min_x, float16 max_x) { - - return max(min(x, max_x), min_x); - } - __device__ float16 round(float16 x) { - return (int)x + (int)(2 * (x - (int)x)); - } - __device__ int get_x_idx(float16 x, float16 center) { - const float resolution = ${resolution}; - const float width = ${width}; - int i = (x - center) / resolution + 0.5 * width; - return i; - } - __device__ int get_y_idx(float16 y, float16 center) { - const float resolution = ${resolution}; - const float height = ${height}; - int i = (y - center) / resolution + 0.5 * height; - return i; - } - __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { - int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); - int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); - return ${width} * idx_x + idx_y; - } - - """ - ).substitute(width=width, height=height, resolution=resolution), - operation=string.Template( - """ - // Point p = {get_idx_x(i, center_x[0]), get_idx_y(i, center_y[0])}; - Point p = {get_idx_x(i), get_idx_y(i)}; - Point extreme = {100000, p.y}; - int bbox_min_idx = get_idx(polygon_bbox[0], polygon_bbox[1], center_x[0], center_y[0]); - int bbox_max_idx = get_idx(polygon_bbox[2], polygon_bbox[3], center_x[0], center_y[0]); - Point bmin = {get_idx_x(bbox_min_idx), get_idx_y(bbox_min_idx)}; - Point bmax = {get_idx_x(bbox_max_idx), get_idx_y(bbox_max_idx)}; - if (p.x < bmin.x || p.x > bmax.x || p.y < bmin.y || p.y > bmax.y){ - mask[i] = 0; - return; - } - else { - int intersect_cnt = 0; - for (int j = 0; j < polygon_n[0]; j++) { - Point p1, p2; - int i1 = get_idx(polygon[j * 2 + 0], polygon[j * 2 + 1], center_x[0], center_y[0]); - p1.x = get_idx_x(i1); - p1.y = get_idx_y(i1); - int j2 = (j + 1) % polygon_n[0]; - int i2 = get_idx(polygon[j2 * 2 + 0], polygon[j2 * 2 + 1], center_x[0], center_y[0]); - p2.x = get_idx_x(i2); - p2.y = get_idx_y(i2); - if (doIntersect(p1, p2, p, extreme)) - { - // If the point 'p' is colinear with line segment 'i-next', - // then check if it lies on segment. If it lies, return true, - // otherwise false - if (orientation(p1, p, p2) == 0) { - if (onSegment(p1, p, p2)){ - mask[i] = 1; - return; - } - } - else if(((p1.y <= p.y) && (p2.y > p.y)) || ((p1.y > p.y) && (p2.y <= p.y))){ - intersect_cnt++; - } - } - } - if (intersect_cnt % 2 == 0) { mask[i] = 0; } - else { mask[i] = 1; } - } - """ - ).substitute(a=1), - name="polygon_mask_kernel", - ) - return polygon_mask_kernel - - - -def image_to_map_correspondence_kernel(resolution, width, height, tolerance_z_collision): - """ - This function calculates the correspondence between the image and the map. - It takes in the resolution, width, height, and tolerance_z_collision as parameters. - The function returns a kernel that can be used to perform the correspondence calculation. - """ - _image_to_map_correspondence_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U x1, raw U y1, raw U z1, raw U P, raw U K, raw U D, raw U image_height, raw U image_width, raw U center", - out_params="raw U uv_correspondence, raw B valid_correspondence", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - __device__ bool is_inside_map(int x, int y) { - return (x >= 0 && y >= 0 && x<${width} && y<${height}); - } - __device__ float get_l2_distance(int x0, int y0, int x1, int y1) { - float dx = x0-x1; - float dy = y0-y1; - return sqrt( dx*dx + dy*dy); - } - """ - ).substitute(width=width, height=height, resolution=resolution), - operation=string.Template( - """ - int cell_idx = get_map_idx(i, 0); - - // return if gridcell has no valid height - if (map[get_map_idx(i, 2)] != 1){ - return; - } - - // get current cell position - int y0 = i % ${width}; - int x0 = i / ${width}; - - // gridcell 3D point in worldframe TODO reverse x and y - float p1 = (x0-(${width}/2)) * ${resolution} + center[0]; - float p2 = (y0-(${height}/2)) * ${resolution} + center[1]; - float p3 = map[cell_idx] + center[2]; - - // reproject 3D point into image plane - float u = p1 * P[0] + p2 * P[1] + p3 * P[2] + P[3]; - float v = p1 * P[4] + p2 * P[5] + p3 * P[6] + P[7]; - float d = p1 * P[8] + p2 * P[9] + p3 * P[10] + P[11]; - - // filter point behind image plane - if (d <= 0) { - return; - } - u = u/d; - v = v/d; - - // Check if D is all zeros - bool is_D_zero = (D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == 0 && D[4] == 0); - - // Apply undistortion using distortion matrix D if not all zeros - if (!is_D_zero) { - float k1 = D[0]; - float k2 = D[1]; - float p1 = D[2]; - float p2 = D[3]; - float k3 = D[4]; - float fx = K[0]; - float fy = K[4]; - float cx = K[2]; - float cy = K[5]; - float x = (u - cx) / fx; - float y = (v - cy) / fy; - float r2 = x * x + y * y; - float radial_distortion = 1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2; - float u_corrected = x * radial_distortion + 2 * p1 * x * y + p2 * (r2 + 2 * x * x); - float v_corrected = y * radial_distortion + 2 * p2 * x * y + p1 * (r2 + 2 * y * y); - u = fx * u_corrected + cx; - v = fy * v_corrected + cy; - } - - // filter point next to image plane - if ((u < 0) || (v < 0) || (u >= image_width) || (v >= image_height)){ - return; - } - - int y0_c = y0; - int x0_c = x0; - float total_dis = get_l2_distance(x0_c, y0_c, x1,y1); - float z0 = map[cell_idx]; - float delta_z = z1-z0; - - - // bresenham algorithm to iterate over cells in line between camera center and current gridmap cell - // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm - int dx = abs(x1-x0); - int sx = x0 < x1 ? 1 : -1; - int dy = -abs(y1 - y0); - int sy = y0 < y1 ? 1 : -1; - int error = dx + dy; - - bool is_valid = true; - - // iterate over all cells along line - while (1){ - // assumption we do not need to check the height for camera center cell - if (x0 == x1 && y0 == y1){ - break; - } - - // check if height is invalid - if (is_inside_map(x0,y0)){ - int idx = y0 + (x0 * ${width}); - if (map[get_map_idx(idx, 2)]){ - float dis = get_l2_distance(x0_c, y0_c, x0, y0); - float rayheight = z0 + ( dis / total_dis * delta_z); - if ( map[idx] - ${tolerance_z_collision} > rayheight){ - is_valid = false; - break; - } - } - } - - - // computation of next gridcell index in line - int e2 = 2 * error; - if (e2 >= dy){ - if(x0 == x1){ - break; - } - error = error + dy; - x0 = x0 + sx; - } - if (e2 <= dx){ - if (y0 == y1){ - break; - } - error = error + dx; - y0 = y0 + sy; - } - } - - // mark the correspondence - uv_correspondence[get_map_idx(i, 0)] = u; - uv_correspondence[get_map_idx(i, 1)] = v; - valid_correspondence[get_map_idx(i, 0)] = is_valid; - """ - ).substitute(height=height, width=width, resolution=resolution, tolerance_z_collision=tolerance_z_collision), - name="image_to_map_correspondence_kernel", - ) - return _image_to_map_correspondence_kernel - - -def average_correspondences_to_map_kernel(width, height): - """ - This function calculates the average correspondences to the map. - It takes in the width and height as parameters. - The function returns a kernel that can be used to perform the correspondence calculation. - """ - _average_correspondences_to_map_kernel = cp.ElementwiseKernel( - in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", - out_params="raw U new_sem_map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - int cell_idx = get_map_idx(i, 0); - if (valid_correspondence[cell_idx]){ - int cell_idx_2 = get_map_idx(i, 1); - int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; - new_sem_map[get_map_idx(i, map_idx)] = image_mono[idx]; - }else{ - new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; - } - - """ - ).substitute(), - name="average_correspondences_to_map_kernel", - ) - return _average_correspondences_to_map_kernel - - -def exponential_correspondences_to_map_kernel(width, height, alpha): - """ - This function calculates the exponential correspondences to the map. - It takes in the width, height, and alpha as parameters. - The function returns a kernel that can be used to perform the correspondence calculation. - """ - _exponential_correspondences_to_map_kernel = cp.ElementwiseKernel( - in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", - out_params="raw U new_sem_map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - int cell_idx = get_map_idx(i, 0); - if (valid_correspondence[cell_idx]){ - int cell_idx_2 = get_map_idx(i, 1); - int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; - new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)] * (1-${alpha}) + ${alpha} * image_mono[idx]; - }else{ - new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; - } - - """ - ).substitute(alpha=alpha), - name="exponential_correspondences_to_map_kernel", - ) - return _exponential_correspondences_to_map_kernel - - -def color_correspondences_to_map_kernel(width, height): - """ - This function calculates the color correspondences to the map. - It takes in the width and height as parameters. - The function returns a kernel that can be used to perform the correspondence calculation. - """ - _color_correspondences_to_map_kernel = cp.ElementwiseKernel( - in_params="raw U sem_map, raw U map_idx, raw U image_rgb, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", - out_params="raw U new_sem_map", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - """ - ).substitute(width=width, height=height), - operation=string.Template( - """ - int cell_idx = get_map_idx(i, 0); - if (valid_correspondence[cell_idx]){ - int cell_idx_2 = get_map_idx(i, 1); - - int idx_red = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; - int idx_green = image_width * image_height + idx_red; - int idx_blue = image_width * image_height * 2 + idx_red; - - unsigned int r = image_rgb[idx_red]; - unsigned int g = image_rgb[idx_green]; - unsigned int b = image_rgb[idx_blue]; - - unsigned int rgb = (r<<16) + (g << 8) + b; - float rgb_ = __uint_as_float(rgb); - new_sem_map[get_map_idx(i, map_idx)] = rgb_; - }else{ - new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; - } - """ - ).substitute(), - name="color_correspondences_to_map_kernel", - ) - return _color_correspondences_to_map_kernel diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/map_initializer.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/map_initializer.py deleted file mode 100644 index 0139ea76..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/map_initializer.py +++ /dev/null @@ -1,80 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -from scipy.interpolate import griddata -import numpy as np -import cupy as cp - - -class MapInitializer(object): - def __init__(self, initial_variance, new_variance, xp=np, method="points"): - self.methods = ["points"] - assert method in self.methods, "method should be chosen from {}".format(self.methods) - self.method = method - self.xp = xp - self.initial_variance = initial_variance - self.new_variance = new_variance - - def __call__(self, *args, **kwargs): - if self.method == "points": - self.points_initializer(*args, **kwargs) - else: - return - - def points_initializer(self, elevation_map, points, method="linear"): - """Initialize the map using interpolation between given points - - Args: - elevation_map (cupy._core.core.ndarray): elevation_map data. - points (cupy._core.core.ndarray): points used to interpolate. - method (str): method for interpolation. (nearest, linear, cubic) - - """ - # points from existing map. - points_idx = self.xp.where(elevation_map[2] > 0.5) - values = elevation_map[0, points_idx[0], points_idx[1]] - - # Add external points for interpolation. - points_idx = self.xp.stack(points_idx).T - points_idx = self.xp.vstack([points_idx, points[:, :2]]) - values = self.xp.hstack([values, points[:, 2]]) - - assert points_idx.shape[0] > 3, "Initialization points must be more than 3." - - # Interpolation using griddata function. - w = elevation_map.shape[1] - h = elevation_map.shape[2] - grid_x, grid_y = np.mgrid[0:w, 0:h] - if self.xp == cp: - points_idx = cp.asnumpy(points_idx) - values = cp.asnumpy(values) - interpolated = griddata(points_idx, values, (grid_x, grid_y), method=method) - if self.xp == cp: - interpolated = cp.asarray(interpolated) - - # Update elevation map. - elevation_map[0] = self.xp.nan_to_num(interpolated) - elevation_map[1] = self.xp.where( - self.xp.invert(self.xp.isnan(interpolated)), self.new_variance, self.initial_variance - ) - elevation_map[2] = self.xp.where(self.xp.invert(self.xp.isnan(interpolated)), 1.0, 0.0) - return - - -if __name__ == "__main__": - initializer = MapInitializer(100, 10, method="points", xp=cp) - m = np.zeros((4, 10, 10)) - m[0, 0:5, 2:5] = 0.3 - m[2, 0:5, 2:5] = 1.0 - np.set_printoptions(threshold=100) - print(m[0]) - print(m[1]) - print(m[2]) - points = cp.array([[0, 0, 0.2], [8, 0, 0.2], [6, 9, 0.2]]) - # [3, 3, 0.2]]) - m = cp.asarray(m) - initializer(m, points, method="cubic") - print(m[0]) - print(m[1]) - print(m[2]) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/parameter.py deleted file mode 100644 index 2193ad02..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/parameter.py +++ /dev/null @@ -1,300 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -from dataclasses import dataclass, field -import pickle -import numpy as np -from simple_parsing.helpers import Serializable -from dataclasses import field -from typing import Tuple - - -@dataclass -class Parameter(Serializable): - """ - This class holds the parameters for the elevation mapping algorithm. - - Attributes: - resolution: The resolution in meters. - (Default: ``0.04``) - subscriber_cfg: The configuration for the subscriber. - (Default: ``{ "front_cam": { "channels": ["rgb", "person"], "topic_name": "/elevation_mapping/pointcloud_semantic", "data_type": "pointcloud", } }``) - additional_layers: The additional layers for the map. - (Default: ``["color"]``) - fusion_algorithms: The list of fusion algorithms. - (Default: ``[ "image_color", "image_exponential", "pointcloud_average", "pointcloud_bayesian_inference", "pointcloud_class_average", "pointcloud_class_bayesian", "pointcloud_class_max", "pointcloud_color", ]``) - pointcloud_channel_fusions: The fusion for pointcloud channels. - (Default: ``{"rgb": "color", "default": "class_average"}``) - image_channel_fusions: The fusion for image channels. - (Default: ``{"rgb": "color", "default": "exponential"}``) - data_type: The data type for the map. - (Default: ``np.float32``) - average_weight: The weight for the average fusion. - (Default: ``0.5``) - map_length: The map's size in meters. - (Default: ``8.0``) - sensor_noise_factor: The point's noise is sensor_noise_factor*z^2 (z is distance from sensor). - (Default: ``0.05``) - mahalanobis_thresh: Points outside this distance is outlier. - (Default: ``2.0``) - outlier_variance: If point is outlier, add this value to the cell. - (Default: ``0.01``) - drift_compensation_variance_inlier: Cells under this value is used for drift compensation. - (Default: ``0.1``) - time_variance: Add this value when update_variance is called. - (Default: ``0.01``) - time_interval: Time layer is updated with this interval. - (Default: ``0.1``) - max_variance: The maximum variance for each cell. - (Default: ``1.0``) - dilation_size: The dilation filter size before traversability filter. - (Default: ``2``) - dilation_size_initialize: The dilation size after the init. - (Default: ``10``) - drift_compensation_alpha: The drift compensation alpha for smoother update of drift compensation. - (Default: ``1.0``) - traversability_inlier: Cells with higher traversability are used for drift compensation. - (Default: ``0.1``) - wall_num_thresh: If there are more points than this value, only higher points than the current height are used to make the wall more sharp. - (Default: ``100``) - min_height_drift_cnt: Drift compensation only happens if the valid cells are more than this number. - (Default: ``100``) - max_ray_length: The maximum length for ray tracing. - (Default: ``2.0``) - cleanup_step: Substitute this value from validity layer at visibility cleanup. - (Default: ``0.01``) - cleanup_cos_thresh: Substitute this value from validity layer at visibility cleanup. - (Default: ``0.5``) - min_valid_distance: Points with shorter distance will be filtered out. - (Default: ``0.3``) - max_height_range: Points higher than this value from sensor will be filtered out to disable ceiling. - (Default: ``1.0``) - ramped_height_range_a: If z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - (Default: ``0.3``) - ramped_height_range_b: If z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - (Default: ``1.0``) - ramped_height_range_c: If z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - (Default: ``0.2``) - safe_thresh: If traversability is smaller, it is counted as unsafe cell. - (Default: ``0.5``) - safe_min_thresh: Polygon is unsafe if there exists lower traversability than this. - (Default: ``0.5``) - max_unsafe_n: If the number of cells under safe_thresh exceeds this value, polygon is unsafe. - (Default: ``20``) - checker_layer: Layer used for checking safety. - (Default: ``"traversability"``) - min_filter_size: The minimum size for the filter. - (Default: ``5``) - min_filter_iteration: The minimum number of iterations for the filter. - (Default: ``3``) - max_drift: The maximum drift for the compensation. - (Default: ``0.10``) - overlap_clear_range_xy: XY range [m] for clearing overlapped area. This defines the valid area for overlap clearance. (used for multi floor setting) - (Default: ``4.0``) - overlap_clear_range_z: Z range [m] for clearing overlapped area. Cells outside this range will be cleared. (used for multi floor setting) - (Default: ``2.0``) - enable_edge_sharpen: Enable edge sharpening. - (Default: ``True``) - enable_drift_compensation: Enable drift compensation. - (Default: ``True``) - enable_visibility_cleanup: Enable visibility cleanup. - (Default: ``True``) - enable_overlap_clearance: Enable overlap clearance. - (Default: ``True``) - use_only_above_for_upper_bound: Use only above for upper bound. - (Default: ``True``) - use_chainer: Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. Pytorch requires ~2GB more GPU memory compared to chainer but runs faster. - (Default: ``True``) - position_noise_thresh: If the position change is bigger than this value, the drift compensation happens. - (Default: ``0.1``) - orientation_noise_thresh: If the orientation change is bigger than this value, the drift compensation happens. - (Default: ``0.1``) - plugin_config_file: Configuration file for the plugin. - (Default: ``"config/plugin_config.yaml"``) - weight_file: Weight file for traversability filter. - (Default: ``"config/weights.dat"``) - initial_variance: Initial variance for each cell. - (Default: ``10.0``) - initialized_variance: Initialized variance for each cell. - (Default: ``10.0``) - w1: Weights for the first layer. - (Default: ``np.zeros((4, 1, 3, 3))``) - w2: Weights for the second layer. - (Default: ``np.zeros((4, 1, 3, 3))``) - w3: Weights for the third layer. - (Default: ``np.zeros((4, 1, 3, 3))``) - w_out: Weights for the output layer. - (Default: ``np.zeros((1, 12, 1, 1))``) - true_map_length: True length of the map. - (Default: ``None``) - cell_n: Number of cells in the map. - (Default: ``None``) - true_cell_n: True number of cells in the map. - (Default: ``None``) - - """ - resolution: float = 0.04 # resolution in m. - subscriber_cfg: dict = field( - default_factory=lambda: { - "front_cam": { - "channels": ["rgb", "person"], - "topic_name": "/elevation_mapping/pointcloud_semantic", - "data_type": "pointcloud", - } - } - ) # configuration for the subscriber - additional_layers: list = field(default_factory=lambda: ["color"]) # additional layers for the map - fusion_algorithms: list = field( - default_factory=lambda: [ - "image_color", - "image_exponential", - "pointcloud_average", - "pointcloud_bayesian_inference", - "pointcloud_class_average", - "pointcloud_class_bayesian", - "pointcloud_class_max", - "pointcloud_color", - ] - ) # list of fusion algorithms - pointcloud_channel_fusions: dict = field(default_factory=lambda: {"rgb": "color", "default": "class_average"}) # fusion for pointcloud channels - image_channel_fusions: dict = field(default_factory=lambda: {"rgb": "color", "default": "exponential"}) # fusion for image channels - data_type: str = np.float32 # data type for the map - average_weight: float = 0.5 # weight for the average fusion - - map_length: float = 8.0 # map's size in m. - sensor_noise_factor: float = 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). - mahalanobis_thresh: float = 2.0 # points outside this distance is outlier. - outlier_variance: float = 0.01 # if point is outlier, add this value to the cell. - drift_compensation_variance_inlier: float = 0.1 # cells under this value is used for drift compensation. - time_variance: float = 0.01 # add this value when update_variance is called. - time_interval: float = 0.1 # Time layer is updated with this interval. - - max_variance: float = 1.0 # maximum variance for each cell. - dilation_size: int = 2 # dilation filter size before traversability filter. - dilation_size_initialize: int = 10 # dilation size after the init. - drift_compensation_alpha: float = 1.0 # drift compensation alpha for smoother update of drift compensation. - - traversability_inlier: float = 0.1 # cells with higher traversability are used for drift compensation. - wall_num_thresh: int = 100 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. - min_height_drift_cnt: int = 100 # drift compensation only happens if the valid cells are more than this number. - - max_ray_length: float = 2.0 # maximum length for ray tracing. - cleanup_step: float = 0.01 # substitute this value from validity layer at visibility cleanup. - cleanup_cos_thresh: float = 0.5 # substitute this value from validity layer at visibility cleanup. - min_valid_distance: float = 0.3 # points with shorter distance will be filtered out. - max_height_range: float = 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. - ramped_height_range_a: float = 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - ramped_height_range_b: float = 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - ramped_height_range_c: float = 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - - safe_thresh: float = 0.5 # if traversability is smaller, it is counted as unsafe cell. - safe_min_thresh: float = 0.5 # polygon is unsafe if there exists lower traversability than this. - max_unsafe_n: int = 20 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. - checker_layer: str = "traversability" # layer used for checking safety - - min_filter_size: int = 5 # minimum size for the filter - min_filter_iteration: int = 3 # minimum number of iterations for the filter - - max_drift: float = 0.10 # maximum drift for the compensation - - overlap_clear_range_xy: float = 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) - overlap_clear_range_z: float = 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - - enable_edge_sharpen: bool = True # enable edge sharpening - enable_drift_compensation: bool = True # enable drift compensation - enable_visibility_cleanup: bool = True # enable visibility cleanup - enable_overlap_clearance: bool = True # enable overlap clearance - use_only_above_for_upper_bound: bool = True # use only above for upper bound - use_chainer: bool = True # use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. - position_noise_thresh: float = 0.1 # if the position change is bigger than this value, the drift compensation happens. - orientation_noise_thresh: float = 0.1 # if the orientation change is bigger than this value, the drift compensation happens. - - # plugin_config_file: str = "config/plugin_config.yaml" # configuration file for the plugin - weight_file: str = "config/weights.dat" # weight file for traversability filter - - initial_variance: float = 10.0 # initial variance for each cell. - initialized_variance: float = 10.0 # initialized variance for each cell. - w1: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the first layer - w2: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the second layer - w3: np.ndarray = field(default_factory=lambda: np.zeros((4, 1, 3, 3))) # weights for the third layer - w_out: np.ndarray = field(default_factory=lambda: np.zeros((1, 12, 1, 1))) # weights for the output layer - - # # not configurable params - true_map_length: float = None # true length of the map - cell_n: int = None # number of cells in the map - true_cell_n: int = None # true number of cells in the map - - def load_weights(self, filename): - """ - Load weights from a file into the model's parameters. - - Args: - filename (str): The path to the file containing the weights. - """ - with open(filename, "rb") as file: - weights = pickle.load(file) - self.w1 = weights["conv1.weight"] - self.w2 = weights["conv2.weight"] - self.w3 = weights["conv3.weight"] - self.w_out = weights["conv_final.weight"] - - def get_names(self): - """ - Get the names of the parameters. - - Returns: - list: A list of parameter names. - """ - return list(self.__annotations__.keys()) - - def get_types(self): - """ - Get the types of the parameters. - - Returns: - list: A list of parameter types. - """ - return [v.__name__ for v in self.__annotations__.values()] - - def set_value(self, name, value): - """ - Set the value of a parameter. - - Args: - name (str): The name of the parameter. - value (any): The new value for the parameter. - """ - setattr(self, name, value) - - def get_value(self, name): - """ - Get the value of a parameter. - - Args: - name (str): The name of the parameter. - - Returns: - any: The value of the parameter. - """ - return getattr(self, name) - - def update(self): - """ - Update the parameters related to the map size and resolution. - """ - # +2 is a border for outside map - self.cell_n = int(round(self.map_length / self.resolution)) + 2 - self.true_cell_n = round(self.map_length / self.resolution) - self.true_map_length = self.true_cell_n * self.resolution - - -# if __name__ == "__main__": -# param = Parameter() -# print(param) -# print(param.resolution) -# param.set_value("resolution", 0.1) -# print(param.resolution) - -# print("names ", param.get_names()) -# print("types ", param.get_types()) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/erosion.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/erosion.py deleted file mode 100644 index 7b0211df..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/erosion.py +++ /dev/null @@ -1,113 +0,0 @@ -# -# Copyright (c) 2024, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cv2 as cv -import cupy as cp -import numpy as np - -from typing import List - -from .plugin_manager import PluginBase - - -class Erosion(PluginBase): - """ - This class is used for applying erosion to an elevation map or specific layers within it. - Erosion is a morphological operation that is used to remove small-scale details from a binary image. - - Args: - kernel_size (int): Size of the erosion kernel. Default is 3, which means a 3x3 square kernel. - iterations (int): Number of times erosion is applied. Default is 1. - **kwargs (): Additional keyword arguments. - """ - - def __init__( - self, - input_layer_name="traversability", - kernel_size: int = 3, - iterations: int = 1, - reverse: bool = False, - default_layer_name: str = "traversability", - **kwargs, - ): - super().__init__() - self.input_layer_name = input_layer_name - self.kernel_size = kernel_size - self.iterations = iterations - self.reverse = reverse - self.default_layer_name = default_layer_name - - def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - semantic_map: cp.ndarray, - semantic_layer_names: List[str], - *args, - ) -> cp.ndarray: - """ - Applies erosion to the given elevation map. - - Args: - elevation_map (cupy._core.core.ndarray): The elevation map to be eroded. - layer_names (List[str]): Names of the layers in the elevation map. - plugin_layers (cupy._core.core.ndarray): Layers provided by other plugins. - plugin_layer_names (List[str]): Names of the layers provided by other plugins. - *args (): Additional arguments. - - Returns: - cupy._core.core.ndarray: The eroded elevation map. - """ - # Convert the elevation map to a format suitable for erosion (if necessary) - layer_data = self.get_layer_data( - elevation_map, - layer_names, - plugin_layers, - plugin_layer_names, - semantic_map, - semantic_layer_names, - self.input_layer_name, - ) - if layer_data is None: - print(f"No layers are found, using {self.default_layer_name}!") - layer_data = self.get_layer_data( - elevation_map, - layer_names, - plugin_layers, - plugin_layer_names, - semantic_map, - semantic_layer_names, - self.default_layer_name, - ) - if layer_data is None: - print(f"No layers are found, using traversability!") - layer_data = self.get_layer_data( - elevation_map, - layer_names, - plugin_layers, - plugin_layer_names, - semantic_map, - semantic_layer_names, - "traversability", - ) - layer_np = cp.asnumpy(layer_data) - - # Define the erosion kernel - kernel = np.ones((self.kernel_size, self.kernel_size), np.uint8) - - if self.reverse: - layer_np = 1 - layer_np - # Apply erosion - layer_min = float(layer_np.min()) - layer_max = float(layer_np.max()) - layer_np_normalized = ((layer_np - layer_min) * 255 / (layer_max - layer_min)).astype("uint8") - eroded_map_np = cv.erode(layer_np_normalized, kernel, iterations=self.iterations) - eroded_map_np = eroded_map_np.astype(np.float32) * (layer_max - layer_min) / 255 + layer_min - if self.reverse: - eroded_map_np = 1 - eroded_map_np - - # Convert back to cupy array and return - return cp.asarray(eroded_map_np) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/features_pca.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/features_pca.py deleted file mode 100644 index 94f88823..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/features_pca.py +++ /dev/null @@ -1,96 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import numpy as np -from typing import List -import re - -from elevation_mapping_cupy.plugins.plugin_manager import PluginBase -from sklearn.decomposition import PCA - - -class FeaturesPca(PluginBase): - """This is a filter to create a pca layer of the semantic features in the map. - - Args: - cell_n (int): width and height of the elevation map. - classes (ruamel.yaml.comments.CommentedSeq): - **kwargs (): - """ - - def __init__( - self, cell_n: int = 100, process_layer_names: List[str] = [], **kwargs, - ): - super().__init__() - self.process_layer_names = process_layer_names - - def get_layer_indices(self, layer_names: List[str]) -> List[int]: - """ Get the indices of the layers that are to be processed using regular expressions. - Args: - layer_names (List[str]): List of layer names. - Returns: - List[int]: List of layer indices. - """ - indices = [] - for i, layer_name in enumerate(layer_names): - if any(re.match(pattern, layer_name) for pattern in self.process_layer_names): - indices.append(i) - return indices - - def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - semantic_map: cp.ndarray, - semantic_layer_names: List[str], - *args, - ) -> cp.ndarray: - """ - - Args: - elevation_map (cupy._core.core.ndarray): - layer_names (List[str]): - plugin_layers (cupy._core.core.ndarray): - plugin_layer_names (List[str]): - semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): - *args (): - - Returns: - cupy._core.core.ndarray: - """ - # get indices of all layers that contain semantic features information - data = [] - for m, layer_names in zip( - [elevation_map, plugin_layers, semantic_map], [layer_names, plugin_layer_names, semantic_layer_names] - ): - layer_indices = self.get_layer_indices(layer_names) - if len(layer_indices) > 0: - n_c = m[layer_indices].shape[1] - data_i = cp.reshape(m[layer_indices], (len(layer_indices), -1)).T.get() - data_i = np.clip(data_i, -1, 1) - data.append(data_i) - if len(data) > 0: - data = np.concatenate(data, axis=1) - # check which has the highest value - n_components = 3 - pca = PCA(n_components=n_components).fit(data) - pca_descriptors = pca.transform(data) - img_pca = pca_descriptors.reshape(n_c, n_c, n_components) - comp = img_pca # [:, :, -3:] - comp_min = comp.min(axis=(0, 1)) - comp_max = comp.max(axis=(0, 1)) - if (comp_max - comp_min).any() != 0: - comp_img = np.divide((comp - comp_min), (comp_max - comp_min)) - pca_map = (comp_img * 255).astype(np.uint8) - r = np.asarray(pca_map[:, :, 0], dtype=np.uint32) - g = np.asarray(pca_map[:, :, 1], dtype=np.uint32) - b = np.asarray(pca_map[:, :, 2], dtype=np.uint32) - rgb_arr = np.array((r << 16) | (g << 8) | (b << 0), dtype=np.uint32) - rgb_arr.dtype = np.float32 - return cp.asarray(rgb_arr) - else: - return cp.zeros_like(elevation_map[0]) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/inpainting.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/inpainting.py deleted file mode 100644 index 3e926b00..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/inpainting.py +++ /dev/null @@ -1,63 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -from typing import List -import cupyx.scipy.ndimage as ndimage -import numpy as np -import cv2 as cv - -from .plugin_manager import PluginBase - - -class Inpainting(PluginBase): - """ - This class is used for inpainting, a process of reconstructing lost or deteriorated parts of images and videos. - - Args: - cell_n (int): The number of cells. Default is 100. - method (str): The inpainting method. Options are 'telea' or 'ns' (Navier-Stokes). Default is 'telea'. - **kwargs (): Additional keyword arguments. - """ - - def __init__(self, cell_n: int = 100, method: str = "telea", **kwargs): - super().__init__() - if method == "telea": - self.method = cv.INPAINT_TELEA - elif method == "ns": # Navier-Stokes - self.method = cv.INPAINT_NS - else: # default method - self.method = cv.INPAINT_TELEA - - def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - *args, - ) -> cp.ndarray: - """ - - Args: - elevation_map (cupy._core.core.ndarray): - layer_names (List[str]): - plugin_layers (cupy._core.core.ndarray): - plugin_layer_names (List[str]): - *args (): - - Returns: - cupy._core.core.ndarray: - """ - mask = cp.asnumpy((elevation_map[2] < 0.5).astype("uint8")) - if (mask < 1).any(): - h = elevation_map[0] - h_max = float(h[mask < 1].max()) - h_min = float(h[mask < 1].min()) - h = cp.asnumpy((elevation_map[0] - h_min) * 255 / (h_max - h_min)).astype("uint8") - dst = np.array(cv.inpaint(h, mask, 1, self.method)) - h_inpainted = dst.astype(np.float32) * (h_max - h_min) / 255 + h_min - return cp.asarray(h_inpainted).astype(np.float64) - else: - return elevation_map[0] diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/max_layer_filter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/max_layer_filter.py deleted file mode 100644 index 33bc069a..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/max_layer_filter.py +++ /dev/null @@ -1,108 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import numpy as np -from typing import List - -from elevation_mapping_cupy.plugins.plugin_manager import PluginBase - - -class MaxLayerFilter(PluginBase): - """Applies a maximum filter to the input layers and updates the traversability map. - This can be used to enhance navigation by identifying traversable areas. - - Args: - cell_n (int): The width and height of the elevation map. - reverse (list): A list of boolean values indicating whether to reverse the filter operation for each layer. Default is [True]. - min_or_max (str): A string indicating whether to apply a minimum or maximum filter. Accepts "min" or "max". Default is "max". - layers (list): List of layers for semantic traversability. Default is ["traversability"]. - thresholds (list): List of thresholds for each layer. If the value is bigger than a threshold, assign 1.0 otherwise 0.0. If it is False, it does not apply. Default is [False]. - **kwargs: Additional keyword arguments. - """ - - def __init__( - self, - cell_n: int = 100, - layers: list = ["traversability"], - reverse: list = [True], - min_or_max: str = "max", - thresholds: list = [False], - scales: list = [1.0], - default_value: float = 0.0, - **kwargs, - ): - super().__init__() - self.layers = layers - self.reverse = reverse - self.min_or_max = min_or_max - self.thresholds = thresholds - self.scales = scales - self.default_value = default_value - - def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - semantic_map: cp.ndarray, - semantic_layer_names: List[str], - *args, - ) -> cp.ndarray: - """ - - Args: - elevation_map (cupy._core.core.ndarray): - layer_names (List[str]): - plugin_layers (cupy._core.core.ndarray): - plugin_layer_names (List[str]): - semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): - *args (): - - Returns: - cupy._core.core.ndarray: - """ - layers = [] - for it, name in enumerate(self.layers): - layer = self.get_layer_data( - elevation_map, layer_names, plugin_layers, plugin_layer_names, semantic_map, semantic_layer_names, name - ) - if layer is None: - continue - if isinstance(self.default_value, float): - layer = cp.where(layer == 0.0, float(self.default_value), layer) - elif isinstance(self.default_value, str): - default_layer = self.get_layer_data( - elevation_map, - layer_names, - plugin_layers, - plugin_layer_names, - semantic_map, - semantic_layer_names, - self.default_value, - ) - layer = cp.where(layer == 0, default_layer, layer) - if self.reverse[it]: - layer = 1.0 - layer - if len(self.scales) > it and isinstance(self.scales[it], float): - layer = layer * float(self.scales[it]) - if isinstance(self.thresholds[it], float): - layer = cp.where(layer > float(self.thresholds[it]), 1, 0) - layers.append(layer) - if len(layers) == 0: - print("No layers are found, returning traversability!") - if isinstance(self.default_value, float): - layer = cp.ones_like(elevation_map[0]) - layer *= float(self.default_value) - return layer - else: - idx = layer_names.index("traversability") - return elevation_map[idx] - result = cp.stack(layers, axis=0) - if self.min_or_max == "min": - result = cp.min(result, axis=0) - else: - result = cp.max(result, axis=0) - return result diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/min_filter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/min_filter.py deleted file mode 100644 index ebf4300a..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/min_filter.py +++ /dev/null @@ -1,118 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import string -from typing import List - -from .plugin_manager import PluginBase - - -class MinFilter(PluginBase): - """This is a filter to fill in invalid cells with minimum values around. - - Args: - cell_n (int): width of the elevation map. - dilation_size (int): The size of the patch to search for minimum value for each iteration. - iteration_n (int): The number of iteration to repeat the same filter. - **kwargs (): - """ - - def __init__(self, cell_n: int = 100, dilation_size: int = 5, iteration_n: int = 5, **kwargs): - super().__init__() - self.iteration_n = iteration_n - self.width = cell_n - self.height = cell_n - self.min_filtered = cp.zeros((self.width, self.height)) - self.min_filtered_mask = cp.zeros((self.width, self.height)) - self.min_filter_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U mask", - out_params="raw U newmap, raw U newmask", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - - __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { - const int layer = ${width} * ${height}; - const int relative_idx = idx + ${width} * dy + dx; - return layer * layer_n + relative_idx; - } - __device__ bool is_inside(int idx) { - int idx_x = idx / ${width}; - int idx_y = idx % ${width}; - if (idx_x <= 0 || idx_x >= ${width} - 1) { - return false; - } - if (idx_y <= 0 || idx_y >= ${height} - 1) { - return false; - } - return true; - } - """ - ).substitute(width=self.width, height=self.height), - operation=string.Template( - """ - U h = map[get_map_idx(i, 0)]; - U valid = mask[get_map_idx(i, 0)]; - if (valid < 0.5) { - U min_value = 1000000.0; - for (int dy = -${dilation_size}; dy <= ${dilation_size}; dy++) { - for (int dx = -${dilation_size}; dx <= ${dilation_size}; dx++) { - int idx = get_relative_map_idx(i, dx, dy, 0); - if (!is_inside(idx)) {continue;} - U valid = newmask[idx]; - U value = newmap[idx]; - if(valid > 0.5 && value < min_value) { - min_value = value; - } - } - } - if (min_value < 1000000 - 1) { - newmap[get_map_idx(i, 0)] = min_value; - newmask[get_map_idx(i, 0)] = 0.6; - } - } - """ - ).substitute(dilation_size=dilation_size), - name="min_filter_kernel", - ) - - def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - *args, - ) -> cp.ndarray: - """ - - Args: - elevation_map (cupy._core.core.ndarray): - layer_names (List[str]): - plugin_layers (cupy._core.core.ndarray): - plugin_layer_names (List[str]): - *args (): - - Returns: - cupy._core.core.ndarray: - """ - self.min_filtered = elevation_map[0].copy() - self.min_filtered_mask = elevation_map[2].copy() - for i in range(self.iteration_n): - self.min_filter_kernel( - elevation_map[0], - elevation_map[2], - self.min_filtered, - self.min_filtered_mask, - size=(self.width * self.height), - ) - # If there's no more mask, break - if (self.min_filtered_mask > 0.5).all(): - break - min_filtered = cp.where(self.min_filtered_mask > 0.5, self.min_filtered.copy(), cp.nan) - return min_filtered diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/plugin_manager.py deleted file mode 100644 index 26f81d21..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/plugin_manager.py +++ /dev/null @@ -1,268 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -from abc import ABC -import cupy as cp -from typing import List, Dict, Optional -import importlib -import inspect -from dataclasses import dataclass -from ruamel.yaml import YAML -from inspect import signature - - -@dataclass -class PluginParams: - name: str - layer_name: str - fill_nan: bool = False # fill nan to invalid region - is_height_layer: bool = False # if this is a height layer - - -class PluginBase(ABC): - """ - This is a base class of Plugins - """ - - def __init__(self, *args, **kwargs): - """ - - Args: - plugin_params : PluginParams - The parameter of callback - """ - - def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - semantic_map: cp.ndarray, - semantic_layer_names: List[str], - *args, - **kwargs, - ) -> cp.ndarray: - """This gets the elevation map data and plugin layers as a cupy array. - - - Args: - elevation_map (): - layer_names (): - plugin_layers (): - plugin_layer_names (): - semantic_map (): - semantic_layer_names (): - - Run your processing here and return the result. - layer of elevation_map 0: elevation - 1: variance - 2: is_valid - 3: traversability - 4: time - 5: upper_bound - 6: is_upper_bound - You can also access to the other plugins' layer with plugin_layers and plugin_layer_names - - """ - pass - - def get_layer_data( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - semantic_map: cp.ndarray, - semantic_layer_names: List[str], - name: str, - ) -> Optional[cp.ndarray]: - """ - Retrieve a copy of the layer data from the elevation, plugin, or semantic maps based on the layer name. - - Args: - elevation_map (cp.ndarray): The elevation map containing various layers. - layer_names (List[str]): A list of names for each layer in the elevation map. - plugin_layers (cp.ndarray): The plugin layers containing additional data. - plugin_layer_names (List[str]): A list of names for each layer in the plugin layers. - semantic_map (cp.ndarray): The semantic map containing various layers. - semantic_layer_names (List[str]): A list of names for each layer in the semantic map. - name (str): The name of the layer to retrieve. - - Returns: - Optional[cp.ndarray]: A copy of the requested layer as a cupy ndarray if found, otherwise None. - """ - if name in layer_names: - idx = layer_names.index(name) - layer = elevation_map[idx].copy() - elif name in plugin_layer_names: - idx = plugin_layer_names.index(name) - layer = plugin_layers[idx].copy() - elif name in semantic_layer_names: - idx = semantic_layer_names.index(name) - layer = semantic_map[idx].copy() - else: - print(f"Could not find layer {name}!") - layer = None - return layer - - -class PluginManager(object): - """ - This manages the plugins. - """ - - def __init__(self, cell_n: int): - self.cell_n = cell_n - - def init(self, plugin_params: List[PluginParams], extra_params: List[Dict]): - self.plugin_params = plugin_params - - self.plugins = [] - for param, extra_param in zip(plugin_params, extra_params): - m = importlib.import_module("." + param.name, package="elevation_mapping_cupy.plugins") # -> 'module' - for name, obj in inspect.getmembers(m): - if inspect.isclass(obj) and issubclass(obj, PluginBase) and name != "PluginBase": - # Add cell_n to params - extra_param["cell_n"] = self.cell_n - self.plugins.append(obj(**extra_param)) - self.layers = cp.zeros((len(self.plugins), self.cell_n, self.cell_n), dtype=cp.float32) - self.layer_names = self.get_layer_names() - self.plugin_names = self.get_plugin_names() - - def load_plugin_settings(self, file_path: str): - print("Start loading plugins...") - cfg = YAML().load(open(file_path, "r")) - plugin_params = [] - extra_params = [] - for k, v in cfg.items(): - if v["enable"]: - plugin_params.append( - PluginParams( - name=k if not "type" in v else v["type"], - layer_name=v["layer_name"], - fill_nan=v["fill_nan"], - is_height_layer=v["is_height_layer"], - ) - ) - extra_params.append(v["extra_params"]) - self.init(plugin_params, extra_params) - print("Loaded plugins are ", *self.plugin_names) - - def get_layer_names(self): - names = [] - for obj in self.plugin_params: - names.append(obj.layer_name) - return names - - def get_plugin_names(self): - names = [] - for obj in self.plugin_params: - names.append(obj.name) - return names - - def get_plugin_index_with_name(self, name: str) -> int: - try: - idx = self.plugin_names.index(name) - return idx - except Exception as e: - print("Error with plugin {}: {}".format(name, e)) - return None - - def get_layer_index_with_name(self, name: str) -> int: - try: - idx = self.layer_names.index(name) - return idx - except Exception as e: - print("Error with layer {}: {}".format(name, e)) - return None - - def update_with_name( - self, - name: str, - elevation_map: cp.ndarray, - layer_names: List[str], - semantic_map=None, - semantic_params=None, - rotation=None, - elements_to_shift={}, - ): - idx = self.get_layer_index_with_name(name) - if idx is not None and idx < len(self.plugins): - n_param = len(signature(self.plugins[idx]).parameters) - if n_param == 5: - self.layers[idx] = self.plugins[idx](elevation_map, layer_names, self.layers, self.layer_names) - elif n_param == 7: - self.layers[idx] = self.plugins[idx]( - elevation_map, - layer_names, - self.layers, - self.layer_names, - semantic_map, - semantic_params, - ) - elif n_param == 8: - self.layers[idx] = self.plugins[idx]( - elevation_map, - layer_names, - self.layers, - self.layer_names, - semantic_map, - semantic_params, - rotation, - ) - else: - self.layers[idx] = self.plugins[idx]( - elevation_map, - layer_names, - self.layers, - self.layer_names, - semantic_map, - semantic_params, - rotation, - elements_to_shift, - ) - - def get_map_with_name(self, name: str) -> cp.ndarray: - idx = self.get_layer_index_with_name(name) - if idx is not None: - return self.layers[idx] - - def get_param_with_name(self, name: str) -> PluginParams: - idx = self.get_layer_index_with_name(name) - if idx is not None: - return self.plugin_params[idx] - - -if __name__ == "__main__": - plugins = [ - PluginParams(name="min_filter", layer_name="min_filter"), - PluginParams(name="smooth_filter", layer_name="smooth"), - ] - extra_params = [ - {"dilation_size": 5, "iteration_n": 5}, - {"input_layer_name": "elevation2"}, - ] - manager = PluginManager(200) - manager.load_plugin_settings("../config/plugin_config.yaml") - print(manager.layer_names) - print(manager.plugin_names) - elevation_map = cp.zeros((7, 200, 200)).astype(cp.float32) - layer_names = [ - "elevation", - "variance", - "is_valid", - "traversability", - "time", - "upper_bound", - "is_upper_bound", - ] - elevation_map[0] = cp.random.randn(200, 200) - elevation_map[2] = cp.abs(cp.random.randn(200, 200)) - print("map", elevation_map[0]) - print("layer map ", manager.layers) - manager.update_with_name("min_filter", elevation_map, layer_names) - manager.update_with_name("smooth_filter", elevation_map, layer_names) - # manager.update_with_name("sem_fil", elevation_map, layer_names, semantic_map=semantic_map) - print(manager.get_map_with_name("smooth")) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/robot_centric_elevation.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/robot_centric_elevation.py deleted file mode 100644 index 80ac73a3..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/robot_centric_elevation.py +++ /dev/null @@ -1,121 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import string -from typing import List -from .plugin_manager import PluginBase - - -class RobotCentricElevation(PluginBase): - """Generates an elevation map with respect to the robot frame. - - Args: - cell_n (int): - resolution (ruamel.yaml.scalarfloat.ScalarFloat): - threshold (ruamel.yaml.scalarfloat.ScalarFloat): - use_threshold (bool): - **kwargs (): - """ - - def __init__( - self, cell_n: int = 100, resolution: float = 0.05, threshold: float = 0.4, use_threshold: bool = 0, **kwargs - ): - super().__init__() - self.width = cell_n - self.height = cell_n - self.min_filtered = cp.zeros((self.width, self.height), dtype=cp.float32) - - self.base_elevation_kernel = cp.ElementwiseKernel( - in_params="raw U map, raw U mask, raw U R", - out_params="raw U newmap", - preamble=string.Template( - """ - __device__ int get_map_idx(int idx, int layer_n) { - const int layer = ${width} * ${height}; - return layer * layer_n + idx; - } - - __device__ bool is_inside(int idx) { - int idx_x = idx / ${width}; - int idx_y = idx % ${width}; - if (idx_x <= 0 || idx_x >= ${width} - 1) { - return false; - } - if (idx_y <= 0 || idx_y >= ${height} - 1) { - return false; - } - return true; - } - __device__ float get_map_x(int idx){ - float idx_x = idx / ${width}* ${resolution}; - return idx_x; - } - __device__ float get_map_y(int idx){ - float idx_y = idx % ${width}* ${resolution}; - return idx_y; - } - __device__ float transform_p(float x, float y, float z, - float r0, float r1, float r2) { - return r0 * x + r1 * y + r2 * z ; - } - """ - ).substitute(width=self.width, height=self.height, resolution=resolution), - operation=string.Template( - """ - U rz = map[get_map_idx(i, 0)]; - U valid = mask[get_map_idx(i, 0)]; - if (valid > 0.5) { - U rx = get_map_x(get_map_idx(i, 0)); - U ry = get_map_y(get_map_idx(i, 0)); - U x_b = transform_p(rx, ry, rz, R[0], R[1], R[2]); - U y_b = transform_p(rx, ry, rz, R[3], R[4], R[5]); - U z_b = transform_p(rx, ry, rz, R[6], R[7], R[8]); - if (${use_threshold} && z_b>= ${threshold} ) { - newmap[get_map_idx(i, 0)] = 1.0; - } - else if (${use_threshold} && z_b< ${threshold} ){ - newmap[get_map_idx(i, 0)] = 0.0; - } - else{ - newmap[get_map_idx(i, 0)] = z_b; - } - } - """ - ).substitute(threshold=threshold, use_threshold=int(use_threshold)), - name="base_elevation_kernel", - ) - - def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - semantic_map: cp.ndarray, - semantic_layer_names: List[str], - rotation, - *args, - ) -> cp.ndarray: - """ - - Args: - elevation_map (cupy._core.core.ndarray): - layer_names (List[str]): - plugin_layers (cupy._core.core.ndarray): - plugin_layer_names (List[str]): - semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): - rotation (cupy._core.core.ndarray): - *args (): - - Returns: - cupy._core.core.ndarray: - """ - # Process maps here - # check that transform is a ndarray - self.min_filtered = elevation_map[0].copy() - self.base_elevation_kernel( - elevation_map[0], elevation_map[2], rotation, self.min_filtered, size=(self.width * self.height), - ) - return self.min_filtered diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_filter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_filter.py deleted file mode 100644 index 0ec56010..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_filter.py +++ /dev/null @@ -1,133 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import numpy as np -from typing import List -import re - -from elevation_mapping_cupy.plugins.plugin_manager import PluginBase - - -class SemanticFilter(PluginBase): - """This is a filter to create a one hot encoded map of the class probabilities. - - Args: - cell_n (int): width and height of the elevation map. - classes (list): List of classes for semantic filtering. Default is ["person", "grass"]. - **kwargs: Additional keyword arguments. - """ - - def __init__( - self, cell_n: int = 100, classes: list = ["person", "grass"], **kwargs, - ): - super().__init__() - self.indices = [] - self.classes = classes - self.color_encoding = self.transform_color() - - def color_map(self, N: int = 256, normalized: bool = False): - """ - Creates a color map with N different colors. - - Args: - N (int, optional): The number of colors in the map. Defaults to 256. - normalized (bool, optional): If True, the colors are normalized to the range [0,1]. Defaults to False. - - Returns: - np.ndarray: The color map. - """ - - def bitget(byteval, idx): - return (byteval & (1 << idx)) != 0 - - dtype = "float32" if normalized else "uint8" - cmap = np.zeros((N + 1, 3), dtype=dtype) - for i in range(N + 1): - r = g = b = 0 - c = i - for j in range(8): - r = r | (bitget(c, 0) << 7 - j) - g = g | (bitget(c, 1) << 7 - j) - b = b | (bitget(c, 2) << 7 - j) - c = c >> 3 - - cmap[i] = np.array([r, g, b]) - - cmap = cmap / 255 if normalized else cmap - cmap[1] = np.array([81, 113, 162]) - cmap[2] = np.array([81, 113, 162]) - cmap[3] = np.array([188, 63, 59]) - return cmap[1:] - - def transform_color(self): - """ - Transforms the color map into a format that can be used for semantic filtering. - - Returns: - cp.ndarray: The transformed color map. - """ - color_classes = self.color_map(255) - r = np.asarray(color_classes[:, 0], dtype=np.uint32) - g = np.asarray(color_classes[:, 1], dtype=np.uint32) - b = np.asarray(color_classes[:, 2], dtype=np.uint32) - rgb_arr = np.array((r << 16) | (g << 8) | (b << 0), dtype=np.uint32) - rgb_arr.dtype = np.float32 - return cp.asarray(rgb_arr) - - def get_layer_indices(self, layer_names: List[str]) -> List[int]: - """ Get the indices of the layers that are to be processed using regular expressions. - Args: - layer_names (List[str]): List of layer names. - Returns: - List[int]: List of layer indices. - """ - indices = [] - for i, layer_name in enumerate(layer_names): - if any(re.match(pattern, layer_name) for pattern in self.classes): - indices.append(i) - return indices - - def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - semantic_map: cp.ndarray, - semantic_layer_names: List[str], - rotation, - elements_to_shift, - *args, - ) -> cp.ndarray: - """ - - Args: - elevation_map (cupy._core.core.ndarray): - layer_names (List[str]): - plugin_layers (cupy._core.core.ndarray): - plugin_layer_names (List[str]): - semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): - *args (): - - Returns: - cupy._core.core.ndarray: - """ - # get indices of all layers that contain semantic class information - data = [] - for m, layer_names in zip( - [elevation_map, plugin_layers, semantic_map], [layer_names, plugin_layer_names, semantic_layer_names] - ): - layer_indices = self.get_layer_indices(layer_names) - if len(layer_indices) > 0: - data.append(m[layer_indices]) - if len(data) > 0: - data = cp.concatenate(data, axis=0) - class_map = cp.amax(data, axis=0) - class_map_id = cp.argmax(data, axis=0) - else: - class_map = cp.zeros_like(elevation_map[0]) - class_map_id = cp.zeros_like(elevation_map[0], dtype=cp.int32) - enc = self.color_encoding[class_map_id] - return enc diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_traversability.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_traversability.py deleted file mode 100644 index 5f6ef1d5..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/semantic_traversability.py +++ /dev/null @@ -1,83 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -import numpy as np -from typing import List - -from elevation_mapping_cupy.plugins.plugin_manager import PluginBase - - -class SemanticTraversability(PluginBase): - """Extracts traversability and elevations from layers and generates an updated traversability that can be used by checker. - - Args: - cell_n (int): The width and height of the elevation map. - layers (list): List of layers for semantic traversability. Default is ["traversability"]. - thresholds (list): List of thresholds for each layer. Default is [0.5]. - type (list): List of types for each layer. Default is ["traversability"]. - **kwargs: Additional keyword arguments. - """ - - def __init__( - self, - cell_n: int = 100, - layers: list = ["traversability"], - thresholds: list = [0.5], - type: list = ["traversability"], - **kwargs, - ): - super().__init__() - self.layers = layers - self.thresholds = cp.asarray(thresholds) - self.type = type - - def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - semantic_map: cp.ndarray, - semantic_layer_names: List[str], - *args, - ) -> cp.ndarray: - """ - - Args: - elevation_map (cupy._core.core.ndarray): - layer_names (List[str]): - plugin_layers (cupy._core.core.ndarray): - plugin_layer_names (List[str]): - semantic_map (elevation_mapping_cupy.semantic_map.SemanticMap): - *args (): - - Returns: - cupy._core.core.ndarray: - """ - # get indices of all layers that - map = cp.zeros(elevation_map[2].shape, np.float32) - tempo = cp.zeros(elevation_map[2].shape, np.float32) - for it, name in enumerate(self.layers): - if name in layer_names: - idx = layer_names.index(name) - tempo = elevation_map[idx] - # elif name in semantic_params.additional_layers: - # idx = semantic_params.additional_layers.index(name) - # tempo = semantic_map[idx] - elif name in plugin_layer_names: - idx = plugin_layer_names.index(name) - tempo = plugin_layers[idx] - else: - print("Layer {} is not in the map, returning traversabiltiy!".format(name)) - return - if self.type[it] == "traversability": - tempo = cp.where(tempo <= self.thresholds[it], 1, 0) - map += tempo - else: - tempo = cp.where(tempo >= self.thresholds[it], 1, 0) - map += tempo - map = cp.where(map <= 0.9, 0.1, 1) - - return map diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/smooth_filter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/smooth_filter.py deleted file mode 100644 index ae48b688..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/smooth_filter.py +++ /dev/null @@ -1,59 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp -from typing import List -import cupyx.scipy.ndimage as ndimage - -from .plugin_manager import PluginBase - - -class SmoothFilter(PluginBase): - """ - SmoothFilter is a class that applies a smoothing filter - to the elevation map. The filter is applied to the layer specified by the input_layer_name parameter. - If the specified layer is not found, the filter is applied to the elevation layer. - - Args: - cell_n (int): The width and height of the elevation map. Default is 100. - input_layer_name (str): The name of the layer to which the filter should be applied. Default is "elevation". - **kwargs: Additional keyword arguments. - """ - - def __init__(self, cell_n: int = 100, input_layer_name: str = "elevation", **kwargs): - super().__init__() - self.input_layer_name = input_layer_name - - def __call__( - self, - elevation_map: cp.ndarray, - layer_names: List[str], - plugin_layers: cp.ndarray, - plugin_layer_names: List[str], - *args, - ) -> cp.ndarray: - """ - - Args: - elevation_map (cupy._core.core.ndarray): - layer_names (List[str]): - plugin_layers (cupy._core.core.ndarray): - plugin_layer_names (List[str]): - *args (): - - Returns: - cupy._core.core.ndarray: - """ - if self.input_layer_name in layer_names: - idx = layer_names.index(self.input_layer_name) - h = elevation_map[idx] - elif self.input_layer_name in plugin_layer_names: - idx = plugin_layer_names.index(self.input_layer_name) - h = plugin_layers[idx] - else: - print("layer name {} was not found. Using elevation layer.".format(self.input_layer_name)) - h = elevation_map[0] - hs1 = ndimage.uniform_filter(h, size=3) - hs1 = ndimage.uniform_filter(hs1, size=3) - return hs1 diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/semantic_map.py deleted file mode 100644 index a06b7361..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/semantic_map.py +++ /dev/null @@ -1,400 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -from elevation_mapping_cupy.parameter import Parameter -import cupy as cp -import numpy as np -from typing import List, Dict -import re - - -from elevation_mapping_cupy.fusion.fusion_manager import FusionManager - -xp = cp - - -class SemanticMap: - def __init__(self, param: Parameter): - """ - - Args: - param (elevation_mapping_cupy.parameter.Parameter): - """ - - self.param = param - - self.layer_specs_points = {} - self.layer_specs_image = {} - self.layer_names = [] - self.unique_fusion = [] - self.unique_data = [] - self.elements_to_shift = {} - - self.unique_fusion = self.param.fusion_algorithms - - self.amount_layer_names = len(self.layer_names) - - self.semantic_map = xp.zeros( - (self.amount_layer_names, self.param.cell_n, self.param.cell_n), dtype=param.data_type, - ) - self.new_map = xp.zeros((self.amount_layer_names, self.param.cell_n, self.param.cell_n), param.data_type,) - # which layers should be reset to zero at each update, per default everyone, - # if a layer should not be reset, it is defined in compile_kernels function - self.delete_new_layers = cp.ones(self.new_map.shape[0], cp.bool8) - self.fusion_manager = FusionManager(self.param) - - def clear(self): - """Clear the semantic map.""" - self.semantic_map *= 0.0 - - def initialize_fusion(self): - """Initialize the fusion algorithms.""" - for fusion in self.unique_fusion: - if "pointcloud_class_bayesian" == fusion: - pcl_ids = self.get_layer_indices("class_bayesian", self.layer_specs_points) - self.delete_new_layers[pcl_ids] = 0 - if "pointcloud_class_max" == fusion: - pcl_ids = self.get_layer_indices("class_max", self.layer_specs_points) - self.delete_new_layers[pcl_ids] = 0 - layer_cnt = self.param.fusion_algorithms.count("class_max") - id_max = cp.zeros((layer_cnt, self.param.cell_n, self.param.cell_n), dtype=cp.uint32,) - self.elements_to_shift["id_max"] = id_max - self.fusion_manager.register_plugin(fusion) - - def update_fusion_setting(self): - """ - Update the fusion settings. - """ - for fusion in self.unique_fusion: - if "pointcloud_class_bayesian" == fusion: - pcl_ids = self.get_layer_indices("class_bayesian", self.layer_specs_points) - self.delete_new_layers[pcl_ids] = 0 - if "pointcloud_class_max" == fusion: - pcl_ids = self.get_layer_indices("class_max", self.layer_specs_points) - self.delete_new_layers[pcl_ids] = 0 - layer_cnt = self.param.fusion_algorithms.count("class_max") - id_max = cp.zeros((layer_cnt, self.param.cell_n, self.param.cell_n), dtype=cp.uint32,) - self.elements_to_shift["id_max"] = id_max - - def add_layer(self, name): - """ - Add a new layer to the semantic map. - - Args: - name (str): The name of the new layer. - """ - if name not in self.layer_names: - self.layer_names.append(name) - self.semantic_map = cp.append( - self.semantic_map, - cp.zeros((1, self.param.cell_n, self.param.cell_n), dtype=self.param.data_type), - axis=0, - ) - self.new_map = cp.append( - self.new_map, cp.zeros((1, self.param.cell_n, self.param.cell_n), dtype=self.param.data_type), axis=0, - ) - self.delete_new_layers = cp.append(self.delete_new_layers, cp.array([1], dtype=cp.bool8)) - - def pad_value(self, x, shift_value, idx=None, value=0.0): - """Create a padding of the map along x,y-axis according to amount that has shifted. - - Args: - x (cupy._core.core.ndarray): - shift_value (cupy._core.core.ndarray): - idx (Union[None, int, None, None]): - value (float): - """ - if idx is None: - if shift_value[0] > 0: - x[:, : shift_value[0], :] = value - elif shift_value[0] < 0: - x[:, shift_value[0] :, :] = value - if shift_value[1] > 0: - x[:, :, : shift_value[1]] = value - elif shift_value[1] < 0: - x[:, :, shift_value[1] :] = value - else: - if shift_value[0] > 0: - x[idx, : shift_value[0], :] = value - elif shift_value[0] < 0: - x[idx, shift_value[0] :, :] = value - if shift_value[1] > 0: - x[idx, :, : shift_value[1]] = value - elif shift_value[1] < 0: - x[idx, :, shift_value[1] :] = value - - def shift_map_xy(self, shift_value): - """Shift the map along x,y-axis according to shift values. - - Args: - shift_value: - """ - self.semantic_map = cp.roll(self.semantic_map, shift_value, axis=(1, 2)) - self.pad_value(self.semantic_map, shift_value, value=0.0) - self.new_map = cp.roll(self.new_map, shift_value, axis=(1, 2)) - self.pad_value(self.new_map, shift_value, value=0.0) - for el in self.elements_to_shift.values(): - el = cp.roll(el, shift_value, axis=(1, 2)) - self.pad_value(el, shift_value, value=0.0) - - def get_fusion( - self, channels: List[str], channel_fusions: Dict[str, str], layer_specs: Dict[str, str] - ) -> List[str]: - """Get all fusion algorithms that need to be applied to a specific pointcloud. - - Args: - channels (List[str]): - """ - fusion_list = [] - process_channels = [] - for channel in channels: - if channel not in layer_specs: - # If the channel is not in the layer_specs, we use the default fusion algorithm - matched_fusion = self.get_matching_fusion(channel, channel_fusions) - if matched_fusion is None: - if "default" in channel_fusions: - default_fusion = channel_fusions["default"] - print( - f"[WARNING] Layer {channel} not found in layer_specs. Using {default_fusion} algorithm as default." - ) - layer_specs[channel] = default_fusion - self.update_fusion_setting() - # If there's no default fusion algorithm, we skip this channel - else: - print( - f"[WARNING] Layer {channel} not found in layer_specs ({layer_specs}) and no default fusion is configured. Skipping." - ) - continue - else: - layer_specs[channel] = matched_fusion - self.update_fusion_setting() - x = layer_specs[channel] - fusion_list.append(x) - process_channels.append(channel) - return process_channels, fusion_list - - def get_matching_fusion(self, channel: str, fusion_algs: Dict[str, str]): - """ Use regular expression to check if the fusion algorithm matches the channel name.""" - for fusion_alg, alg_value in fusion_algs.items(): - if re.match(f"^{fusion_alg}$", channel): - return alg_value - return None - - def get_layer_indices(self, fusion_alg, layer_specs): - """Get the indices of the layers that are used for a specific fusion algorithm. - - Args: - fusion_alg(str): fusion algorithm name - - Returns: - cp.array: indices of the layers - """ - layer_indices = cp.array([], dtype=cp.int32) - for it, (key, val) in enumerate(layer_specs.items()): - if key in val == fusion_alg: - layer_indices = cp.append(layer_indices, it).astype(cp.int32) - return layer_indices - - def get_indices_fusion(self, pcl_channels: List[str], fusion_alg: str, layer_specs: Dict[str, str]): - """Computes the indices of the channels of the pointcloud and the layers of the semantic map of type fusion_alg. - - Args: - pcl_channels (List[str]): list of all channel names - fusion_alg (str): fusion algorithm type we want to use for channel selection - - Returns: - Union[Tuple[List[int], List[int]], Tuple[cupy._core.core.ndarray, cupy._core.core.ndarray]]: - - - """ - # this contains exactly the fusion alg type for each channel of the pcl - pcl_val_list = [layer_specs[x] for x in pcl_channels] - # this contains the indices of the point cloud where we have to perform a certain fusion - pcl_indices = cp.array([idp + 3 for idp, x in enumerate(pcl_val_list) if x == fusion_alg], dtype=cp.int32,) - # create a list of indices of the layers that will be updated by the point cloud with specific fusion alg - layer_indices = cp.array([], dtype=cp.int32) - for it, (key, val) in enumerate(layer_specs.items()): - if key in pcl_channels and val == fusion_alg: - layer_idx = self.layer_names.index(key) - layer_indices = cp.append(layer_indices, layer_idx).astype(cp.int32) - return pcl_indices, layer_indices - - def update_layers_pointcloud(self, points_all, channels, R, t, elevation_map): - """Update the semantic map with the pointcloud. - - Args: - points_all: semantic point cloud - channels: list of channel names - R: rotation matrix - t: translation vector - elevation_map: elevation map object - """ - process_channels, additional_fusion = self.get_fusion( - channels, self.param.pointcloud_channel_fusions, self.layer_specs_points - ) - # If channels has a new layer that is not in the semantic map, add it - for channel in process_channels: - if channel not in self.layer_names: - print(f"Layer {channel} not found, adding it to the semantic map") - self.add_layer(channel) - - # Resetting new_map for the layers that are to be deleted - self.new_map[self.delete_new_layers] = 0.0 - for fusion in list(set(additional_fusion)): - # which layers need to be updated with this fusion algorithm - pcl_ids, layer_ids = self.get_indices_fusion(process_channels, fusion, self.layer_specs_points) - # update the layers with the fusion algorithm - self.fusion_manager.execute_plugin( - fusion, - points_all, - R, - t, - pcl_ids, - layer_ids, - elevation_map, - self.semantic_map, - self.new_map, - self.elements_to_shift, - ) - - def update_layers_image( - self, - # sub_key: str, - image: cp._core.core.ndarray, - channels: List[str], - # fusion_methods: List[str], - uv_correspondence: cp._core.core.ndarray, - valid_correspondence: cp._core.core.ndarray, - image_height: cp._core.core.ndarray, - image_width: cp._core.core.ndarray, - ): - """Update the semantic map with the new image. - - Args: - sub_key: - image: - uv_correspondence: - valid_correspondence: - image_height: - image_width: - """ - - process_channels, fusion_methods = self.get_fusion( - channels, self.param.image_channel_fusions, self.layer_specs_image - ) - self.new_map[self.delete_new_layers] = 0.0 - for j, (fusion, channel) in enumerate(zip(fusion_methods, process_channels)): - if channel not in self.layer_names: - print(f"Layer {channel} not found, adding it to the semantic map") - self.add_layer(channel) - sem_map_idx = self.get_index(channel) - - if sem_map_idx == -1: - print(f"Layer {channel} not found!") - return - - # update the layers with the fusion algorithm - self.fusion_manager.execute_image_plugin( - fusion, - cp.uint64(sem_map_idx), - image, - j, - uv_correspondence, - valid_correspondence, - image_height, - image_width, - self.semantic_map, - self.new_map, - ) - - def decode_max(self, mer): - """Decode the float32 value into two 16 bit value containing the class probability and the class id. - - Args: - mer: - - Returns: - cp.array: probability - cp.array: class id - """ - mer = mer.astype(cp.float32) - mer = mer.view(dtype=cp.uint32) - ma = cp.bitwise_and(mer, 0xFFFF, dtype=np.uint16) - ma = ma.view(np.float16) - ma = ma.astype(np.float32) - ind = cp.right_shift(mer, 16) - return ma, ind - - def get_map_with_name(self, name): - """Return the map with the given name. - - Args: - name: layer name - - Returns: - cp.array: map - """ - # If the layer is a color layer, return the rgb map - if name in self.layer_specs_points and self.layer_specs_points[name] == "color": - m = self.get_rgb(name) - return m - elif name in self.layer_specs_image and self.layer_specs_image[name] == "color": - m = self.get_rgb(name) - return m - else: - m = self.get_semantic(name) - return m - - def get_rgb(self, name): - """Return the rgb map with the given name. - - Args: - name: - - Returns: - cp.array: rgb map - """ - idx = self.layer_names.index(name) - c = self.process_map_for_publish(self.semantic_map[idx]) - c = c.astype(np.float32) - return c - - def get_semantic(self, name): - """Return the semantic map layer with the given name. - - Args: - name(str): layer name - - Returns: - cp.array: semantic map layer - """ - idx = self.layer_names.index(name) - c = self.process_map_for_publish(self.semantic_map[idx]) - return c - - def process_map_for_publish(self, input_map): - """Remove padding. - - Args: - input_map(cp.array): map layer - - Returns: - cp.array: map layer without padding - """ - m = input_map.copy() - return m[1:-1, 1:-1] - - def get_index(self, name): - """Return the index of the layer with the given name. - - Args: - name(str): - - Returns: - int: index - """ - if name not in self.layer_names: - return -1 - else: - return self.layer_names.index(name) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/__init__.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_elevation_mapping.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_elevation_mapping.py deleted file mode 100644 index 7bdbb20b..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_elevation_mapping.py +++ /dev/null @@ -1,118 +0,0 @@ -import pytest -from elevation_mapping_cupy import parameter, elevation_mapping -import cupy as cp -import numpy as np - - -def encode_max(maxim, index): - maxim, index = cp.asarray(maxim, dtype=cp.float32), cp.asarray(index, dtype=cp.uint32) - # fuse them - maxim = maxim.astype(cp.float16) - maxim = maxim.view(cp.uint16) - maxim = maxim.astype(cp.uint32) - index = index.astype(cp.uint32) - mer = cp.array(cp.left_shift(index, 16) | maxim, dtype=cp.uint32) - mer = mer.view(cp.float32) - return mer - - -@pytest.fixture() -def elmap_ex(add_lay, fusion_alg): - additional_layer = add_lay - fusion_algorithms = fusion_alg - p = parameter.Parameter( - use_chainer=False, - weight_file="../../../config/weights.dat", - plugin_config_file="../../../config/plugin_config.yaml", - ) - p.subscriber_cfg["front_cam"]["channels"] = additional_layer - p.subscriber_cfg["front_cam"]["fusion"] = fusion_algorithms - p.update() - e = elevation_mapping.ElevationMap(p) - return e - - -@pytest.mark.parametrize( - "add_lay,fusion_alg", - [ - (["feat_0", "feat_1", "rgb"], ["average", "average", "color"]), - (["feat_0", "feat_1"], ["average", "average"]), - (["feat_0", "feat_1"], ["class_average", "class_average"]), - (["feat_0", "feat_1"], ["class_bayesian", "class_bayesian"]), - (["feat_0", "feat_1"], ["class_bayesian", "class_max"]), - (["feat_0", "feat_1"], ["bayesian_inference", "bayesian_inference"]), - ], -) -class TestElevationMap: - def test_init(self, elmap_ex): - assert len(elmap_ex.layer_names) == elmap_ex.elevation_map.shape[0] - # assert elmap_ex.color_map is None - - def test_input(self, elmap_ex): - channels = ["x", "y", "z"] + elmap_ex.param.additional_layers - if "class_max" in elmap_ex.param.fusion_algorithms: - val = cp.random.rand(100000, len(channels), dtype=cp.float32).astype(cp.float16) - ind = cp.random.randint(0, 2, (100000, len(channels)), dtype=cp.uint32).astype(cp.float32) - points = encode_max(val, ind) - else: - points = cp.random.rand(100000, len(channels), dtype=elmap_ex.param.data_type) - R = cp.random.rand(3, 3, dtype=elmap_ex.param.data_type) - t = cp.random.rand(3, dtype=elmap_ex.param.data_type) - elmap_ex.input_pointcloud(points, channels, R, t, 0, 0) - - def test_update_normal(self, elmap_ex): - elmap_ex.update_normal(elmap_ex.elevation_map[0]) - - def test_move_to(self, elmap_ex): - for i in range(20): - pos = np.array([i * 0.01, i * 0.02, i * 0.01]) - R = cp.random.rand(3, 3) - elmap_ex.move_to(pos, R) - - def test_get_map(self, elmap_ex): - layers = [ - "elevation", - "variance", - "traversability", - "min_filter", - "smooth", - "inpaint", - "rgb", - ] - data = np.zeros((elmap_ex.cell_n - 2, elmap_ex.cell_n - 2), dtype=cp.float32) - for layer in layers: - elmap_ex.get_map_with_name_ref(layer, data) - - def test_get_position(self, elmap_ex): - pos = np.random.rand(1, 3) - elmap_ex.get_position(pos) - - def test_clear(self, elmap_ex): - elmap_ex.clear() - - def test_move(self, elmap_ex): - delta_position = np.random.rand(3) - elmap_ex.move(delta_position) - - def test_exists_layer(self, elmap_ex, add_lay): - for layer in add_lay: - assert elmap_ex.exists_layer(layer) - - def test_polygon_traversability(self, elmap_ex): - polygon = cp.array([[0, 0], [2, 0], [0, 2]], dtype=np.float64) - result = np.array([0, 0, 0]) - number_polygons = elmap_ex.get_polygon_traversability(polygon, result) - untraversable_polygon = np.zeros((number_polygons, 2)) - elmap_ex.get_untraversable_polygon(untraversable_polygon) - - def test_initialize_map(self, elmap_ex): - methods = ["linear", "cubic", "nearest"] - for method in methods: - points = np.array([[-4.0, 0.0, 0.0], [-4.0, 8.0, 1.0], [4.0, 8.0, 0.0], [4.0, 0.0, 0.0]]) - elmap_ex.initialize_map(points, method) - - def test_plugins(self, elmap_ex): - layers = elmap_ex.plugin_manager.layer_names - data = np.zeros((200, 200), dtype=np.float32) - for layer in layers: - elmap_ex.get_map_with_name_ref(layer, data) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_parameter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_parameter.py deleted file mode 100644 index 4c497349..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_parameter.py +++ /dev/null @@ -1,17 +0,0 @@ -import pytest -from elevation_mapping_cupy.parameter import Parameter - - -def test_parameter(): - param = Parameter( - use_chainer=False, - weight_file="../../../config/weights.dat", - plugin_config_file="../../../config/plugin_config.yaml", - ) - res = param.resolution - param.set_value("resolution", 0.1) - param.get_types() - param.get_names() - param.update() - assert param.resolution == param.get_value("resolution") - param.load_weights(param.weight_file) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_plugins.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_plugins.py deleted file mode 100644 index f3e8cc1c..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_plugins.py +++ /dev/null @@ -1,69 +0,0 @@ -import pytest -from elevation_mapping_cupy import semantic_map, parameter -import cupy as cp -import numpy as np -from elevation_mapping_cupy.plugins.plugin_manager import PluginManager, PluginParams - -plugin_path = "plugin_config.yaml" - - -@pytest.fixture() -def semmap_ex(add_lay, fusion_alg): - p = parameter.Parameter( - use_chainer=False, weight_file="../../../config/weights.dat", plugin_config_file=plugin_path, - ) - p.subscriber_cfg["front_cam"]["channels"] = add_lay - p.subscriber_cfg["front_cam"]["fusion"] = fusion_alg - p.update() - e = semantic_map.SemanticMap(p) - e.initialize_fusion() - return e - - -@pytest.mark.parametrize( - "add_lay, fusion_alg,channels", - [ - ( - ["grass", "tree", "fence", "person"], - ["class_average", "class_average", "class_average", "class_average"], - ["grass"], - ), - (["grass", "tree"], ["class_average", "class_average"], ["grass"]), - (["grass", "tree"], ["class_average", "class_max"], ["tree"]), - (["max1", "max2"], ["class_max", "class_max"], ["max1", "max2"]), - ], -) -def test_plugin_manager(semmap_ex, channels): - manager = PluginManager(202) - manager.load_plugin_settings(plugin_path) - elevation_map = cp.zeros((7, 202, 202)).astype(cp.float32) - rotation = cp.eye(3, dtype=cp.float32) - layer_names = [ - "elevation", - "variance", - "is_valid", - "traversability", - "time", - "upper_bound", - "is_upper_bound", - ] - elevation_map[0] = cp.random.randn(202, 202) - elevation_map[2] = cp.abs(cp.random.randn(202, 202)) - elevation_map[0] - manager.layers[0] - manager.update_with_name("min_filter", elevation_map, layer_names) - manager.update_with_name("smooth_filter", elevation_map, layer_names) - manager.update_with_name("semantic_filter", elevation_map, layer_names, semmap_ex, rotation) - manager.update_with_name("semantic_traversability", elevation_map, layer_names, semmap_ex) - manager.get_map_with_name("smooth") - for lay in manager.get_layer_names(): - manager.update_with_name( - lay, - elevation_map, - layer_names, - semmap_ex.semantic_map, - semmap_ex.param, - rotation, - semmap_ex.elements_to_shift, - ) - manager.get_map_with_name(lay) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_kernels.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_kernels.py deleted file mode 100644 index 590946eb..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_kernels.py +++ /dev/null @@ -1,307 +0,0 @@ -import pytest -from elevation_mapping_cupy import parameter, elevation_mapping -import cupy as cp - -from elevation_mapping_cupy.parameter import Parameter - -from elevation_mapping_cupy.kernels import add_points_kernel -from elevation_mapping_cupy.kernels import ( - average_kernel, - class_average_kernel, - alpha_kernel, - bayesian_inference_kernel, - add_color_kernel, - color_average_kernel, - sum_compact_kernel, - sum_max_kernel, - sum_kernel, -) - - -# to check output run: pytest -rP test_semantic_kernels.py - - -# only kernel where we test only one layer -def test_color_kernel(): - # params - cell_n = 4 - pcl_ids, layer_ids = cp.array([3], dtype=cp.int32), cp.array([0], dtype=cp.int32) - R = cp.eye(3, dtype=cp.float32) - t = cp.array([0, 0, 0], dtype=cp.float32) - points_all = cp.array([[0.1, 0.1, 0.1, 0.3], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]], dtype=cp.float32) - semantic_map = cp.zeros((1, 4, 4), dtype=cp.float32) - - # compile kernel - add_color_kernel_ = add_color_kernel(cell_n, cell_n,) - color_average_kernel_ = color_average_kernel(cell_n, cell_n) - - # updatelayer - color_map = cp.zeros((1 + 3 * layer_ids.shape[0], cell_n, cell_n), dtype=cp.uint32,) - - points_all = points_all.astype(cp.float32) - add_color_kernel_( - points_all, - R, - t, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - color_map, - size=(points_all.shape[0] * pcl_ids.shape[0]), - ) - color_average_kernel_( - color_map, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - semantic_map, - size=(cell_n * cell_n * pcl_ids.shape[0]), - ) - print(color_map) - - -@pytest.mark.parametrize( - "map_shape, points_all,pcl_ids, layer_ids", - [ - ( - (4, 4, 4), - cp.array( - [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 - ), - cp.array([3, 4], dtype=cp.int32), - cp.array([1, 2], dtype=cp.int32), - ), - ], -) -def test_sum_kernel(map_shape, points_all, pcl_ids, layer_ids): - # create points - resolution = 0.9 - points = points_all[:, :3] - # arguments for kernel - semantic_map = cp.zeros(map_shape, dtype=cp.float32) - new_map = cp.zeros(map_shape, dtype=cp.float32) - R = cp.eye(3, dtype=cp.float32) - t = cp.array([0, 0, 0], dtype=cp.float32) - # compile kernel - sum_kernel_ = sum_kernel(0.9, 4, 4,) - # simulating adding the points - print("idx, valid, inside, values") - points_all[:, 0] = 1 - points_all[:, 1:3] = 1.0 - print("points all after ", points_all) - # run the kernel - sum_kernel_( - points_all, - R, - t, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - semantic_map, - new_map, - size=(points_all.shape[0] * pcl_ids.shape[0]), - ) - print("semantic_map", semantic_map) - print("new_map", new_map) - - -@pytest.mark.parametrize( - "map_shape, points_all,pcl_ids, layer_ids", - [ - ( - (4, 4, 4), - cp.array( - [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 - ), - cp.array([3, 4], dtype=cp.int32), - cp.array([1, 2], dtype=cp.int32), - ), - ], -) -def test_average_kernel(map_shape, points_all, pcl_ids, layer_ids): - elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) - elevation_map[2] = points_all.shape[0] - semantic_map = cp.zeros(map_shape, dtype=cp.float32) - new_map = cp.ones(map_shape, dtype=cp.float32) - R = cp.eye(3, dtype=cp.float32) - t = cp.array([0, 0, 0], dtype=cp.float32) - # compile kernel - average_kernel_ = average_kernel(4, 4,) - cell_n = 4 - print("new_map", new_map) - print("semantic_map", semantic_map) - print("elevation_map", elevation_map) - - average_kernel_( - new_map, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - elevation_map, - semantic_map, - size=(cell_n * cell_n * pcl_ids.shape[0]), - ) - print("semantic_map", semantic_map) - - -@pytest.mark.parametrize( - "map_shape, points_all,pcl_ids, layer_ids", - [ - ( - (3, 4, 4), - cp.array( - [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 - ), - cp.array([3], dtype=cp.int32), - cp.array([0], dtype=cp.int32), - ), - ], -) -def test_bayesian_inference_kernel(map_shape, points_all, pcl_ids, layer_ids): - # params - cell_n = 4 - resolution = 0.9 - elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) - elevation_map[2] = points_all.shape[0] - semantic_map = cp.zeros(map_shape, dtype=cp.float32) - new_map = cp.ones(map_shape, dtype=cp.float32) - R = cp.eye(3, dtype=cp.float32) - t = cp.array([0, 0, 0], dtype=cp.float32) - - # compile kernel - sum_mean = cp.ones((pcl_ids.shape[0], cell_n, cell_n,), cp.float32,) - sum_compact_kernel_ = sum_compact_kernel(resolution, cell_n, cell_n,) - bayesian_inference_kernel_ = bayesian_inference_kernel(cell_n, cell_n,) - # updatelayer - sum_mean *= 0 - sum_compact_kernel_( - points_all, - R, - t, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - sum_mean, - size=(points_all.shape[0] * pcl_ids.shape[0]), - ) - bayesian_inference_kernel_( - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - elevation_map, - new_map, - sum_mean, - semantic_map, - size=(cell_n * cell_n * pcl_ids.shape[0]), - ) - print("semantic_map", semantic_map) - - -@pytest.mark.parametrize( - "map_shape, points_all,pcl_ids, layer_ids", - [ - ( - (4, 4, 4), - cp.array( - [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 - ), - cp.array([3, 4], dtype=cp.int32), - cp.array([1, 2], dtype=cp.int32), - ), - ], -) -def test_class_average_kernel(map_shape, points_all, pcl_ids, layer_ids): - # params - cell_n = 4 - resolution = 0.9 - average_weight = 0.5 - elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) - elevation_map[2] = 3 - semantic_map = cp.zeros(map_shape, dtype=cp.float32) - new_map = cp.zeros(map_shape, dtype=cp.float32) - R = cp.eye(3, dtype=cp.float32) - t = cp.array([0, 0, 0], dtype=cp.float32) - # compile kernel - sum_kernel_ = sum_kernel(0.9, 4, 4,) - class_average_kernel_ = class_average_kernel(cell_n, cell_n, average_weight,) - print("x,y,z,class") - print("points all after ", points_all) - - # simulating adding the points - print("idx, valid, inside, values") - points_all[:, 0] = 1 - points_all[:, 1:3] = 1.0 - print("points all after ", points_all) - # run the kernel - sum_kernel_( - points_all, - R, - t, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - semantic_map, - new_map, - size=(points_all.shape[0] * pcl_ids.shape[0]), - ) - print("new_map bef", new_map) - print("pcl_ids.shape[0]", pcl_ids.shape[0]) - class_average_kernel_( - new_map, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - elevation_map, - semantic_map, - size=(cell_n * cell_n * pcl_ids.shape[0]), - ) - print("semantic_map", semantic_map) - print("new_map", new_map) - - -@pytest.mark.parametrize( - "map_shape, points_all,pcl_ids, layer_ids", - [ - ( - (4, 4, 4), - cp.array( - [[0.1, 0.1, 0.1, 0.3, 0.3], [0.1, 0.1, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.1, 0.2]], dtype=cp.float32 - ), - cp.array([3, 4], dtype=cp.int32), - cp.array([1, 2], dtype=cp.int32), - ), - ], -) -def test_class_bayesian_inference_fct(map_shape, points_all, pcl_ids, layer_ids): - # params - cell_n = 4 - resolution = 0.9 - elevation_map = cp.zeros((3, 4, 4), dtype=cp.float32) - elevation_map[2] = points_all.shape[0] - semantic_map = cp.zeros(map_shape, dtype=cp.float32) - new_map = cp.zeros(map_shape, dtype=cp.float32) - R = cp.eye(3, dtype=cp.float32) - t = cp.array([0, 0, 0], dtype=cp.float32) - # compile kernel - alpha_kernel_ = alpha_kernel(resolution, cell_n, cell_n,) - # simulating adding the points - print("idx, valid, inside, values") - points_all[:, 0] = 1 - points_all[:, 1:3] = 1.0 - print("points all after ", points_all) - # run the kernel - alpha_kernel_( - points_all, - pcl_ids, - layer_ids, - cp.array([points_all.shape[1], pcl_ids.shape[0]], dtype=cp.int32), - new_map, - size=(points_all.shape[0] * pcl_ids.shape[0]), - ) - # calculate new thetas - sum_alpha = cp.sum(new_map[layer_ids], axis=0) - # do not divide by zero - sum_alpha[sum_alpha == 0] = 1 - semantic_map[layer_ids] = new_map[layer_ids] / cp.expand_dims(sum_alpha, axis=0) - print("semantic_map", semantic_map) - print("new_map", new_map) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_map.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_map.py deleted file mode 100644 index 95966bc4..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/tests/test_semantic_map.py +++ /dev/null @@ -1,47 +0,0 @@ -import pytest -from elevation_mapping_cupy import semantic_map, parameter -import cupy as cp -import numpy as np - - -@pytest.fixture() -def semmap_ex(sem_lay, fusion_alg): - p = parameter.Parameter( - use_chainer=False, - weight_file="../../../config/weights.dat", - plugin_config_file="../../../config/plugin_config.yaml", - ) - for subs, value in p.subscriber_cfg.items(): - value["channels"] = sem_lay - value["fusion"] = fusion_alg - p.update() - e = semantic_map.SemanticMap(p) - return e - - -@pytest.mark.parametrize( - "sem_lay, fusion_alg,channels", - [ - (["feat_0", "feat_1"], ["average", "average"], ["feat_0"]), - (["feat_0", "feat_1"], ["average", "average"], []), - (["feat_0", "feat_1", "rgb"], ["average", "average", "color"], ["rgb", "feat_0"],), - (["feat_0", "feat_1", "rgb"], ["class_average", "average", "color"], ["rgb", "feat_0"],), - (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0"],), - (["feat_0", "feat_1", "rgb"], ["class_bayesian", "average", "color"], ["rgb", "feat_0", "feat_1"],), - (["feat_0", "feat_1", "rgb"], ["class_bayesian", "class_max", "color"], ["rgb", "feat_0", "feat_1"],), - (["max1", "max2", "rgb"], ["class_max", "class_max", "color"], ["rgb", "max1", "max2"],), - ], -) -def test_fusion_of_pcl(semmap_ex, channels): - fusion = semmap_ex.get_fusion_of_pcl(channels=channels) - assert len(fusion) <= len(channels) - assert len(fusion) > 0 or len(channels) == 0 - assert all(isinstance(item, str) for item in fusion) - - -@pytest.mark.parametrize( - "sem_lay, fusion_alg", [(["feat_0", "feat_1", "rgb"], ["average", "average", "color"]),], -) -@pytest.mark.parametrize("channels", [["rgb"], ["rgb", "feat_0"], []]) -def test_indices_fusion(semmap_ex, channels, fusion_alg): - pcl_indices, layer_indices = semmap_ex.get_indices_fusion(pcl_channels=channels, fusion_alg=fusion_alg[0]) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_filter.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_filter.py deleted file mode 100644 index 7dfb47c2..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_filter.py +++ /dev/null @@ -1,100 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import cupy as cp - - -def get_filter_torch(*args, **kwargs): - import torch - import torch.nn as nn - - class TraversabilityFilter(nn.Module): - def __init__(self, w1, w2, w3, w_out, device="cuda", use_bias=False): - super(TraversabilityFilter, self).__init__() - self.conv1 = nn.Conv2d(1, 4, 3, dilation=1, padding=0, bias=use_bias) - self.conv2 = nn.Conv2d(1, 4, 3, dilation=2, padding=0, bias=use_bias) - self.conv3 = nn.Conv2d(1, 4, 3, dilation=3, padding=0, bias=use_bias) - self.conv_out = nn.Conv2d(12, 1, 1, bias=use_bias) - - # Set weights. - self.conv1.weight = nn.Parameter(torch.from_numpy(w1).float()) - self.conv2.weight = nn.Parameter(torch.from_numpy(w2).float()) - self.conv3.weight = nn.Parameter(torch.from_numpy(w3).float()) - self.conv_out.weight = nn.Parameter(torch.from_numpy(w_out).float()) - - def __call__(self, elevation_cupy): - # Convert cupy tensor to pytorch. - elevation_cupy = elevation_cupy.astype(cp.float32) - elevation = torch.as_tensor(elevation_cupy, device=self.conv1.weight.device) - - with torch.no_grad(): - out1 = self.conv1(elevation.view(-1, 1, elevation.shape[0], elevation.shape[1])) - out2 = self.conv2(elevation.view(-1, 1, elevation.shape[0], elevation.shape[1])) - out3 = self.conv3(elevation.view(-1, 1, elevation.shape[0], elevation.shape[1])) - - out1 = out1[:, :, 2:-2, 2:-2] - out2 = out2[:, :, 1:-1, 1:-1] - out = torch.cat((out1, out2, out3), dim=1) - # out = F.concat((out1, out2, out3), axis=1) - out = self.conv_out(out.abs()) - out = torch.exp(-out) - out_cupy = cp.asarray(out) - - return out_cupy - - traversability_filter = TraversabilityFilter(*args, **kwargs).cuda().eval() - return traversability_filter - - -def get_filter_chainer(*args, **kwargs): - import os - - os.environ["CHAINER_WARN_VERSION_MISMATCH"] = "0" - import chainer - import chainer.links as L - import chainer.functions as F - - class TraversabilityFilter(chainer.Chain): - def __init__(self, w1, w2, w3, w_out, use_cupy=True): - super(TraversabilityFilter, self).__init__() - self.conv1 = L.Convolution2D(1, 4, ksize=3, pad=0, dilate=1, nobias=True, initialW=w1) - self.conv2 = L.Convolution2D(1, 4, ksize=3, pad=0, dilate=2, nobias=True, initialW=w2) - self.conv3 = L.Convolution2D(1, 4, ksize=3, pad=0, dilate=3, nobias=True, initialW=w3) - self.conv_out = L.Convolution2D(12, 1, ksize=1, nobias=True, initialW=w_out) - - if use_cupy: - self.conv1.to_gpu() - self.conv2.to_gpu() - self.conv3.to_gpu() - self.conv_out.to_gpu() - chainer.config.train = False - chainer.config.enable_backprop = False - - def __call__(self, elevation): - out1 = self.conv1(elevation.reshape(-1, 1, elevation.shape[0], elevation.shape[1])) - out2 = self.conv2(elevation.reshape(-1, 1, elevation.shape[0], elevation.shape[1])) - out3 = self.conv3(elevation.reshape(-1, 1, elevation.shape[0], elevation.shape[1])) - - out1 = out1[:, :, 2:-2, 2:-2] - out2 = out2[:, :, 1:-1, 1:-1] - out = F.concat((out1, out2, out3), axis=1) - out = self.conv_out(F.absolute(out)) - return F.exp(-out).array - - traversability_filter = TraversabilityFilter(*args, **kwargs) - return traversability_filter - - -if __name__ == "__main__": - import cupy as cp - from parameter import Parameter - - elevation = cp.random.randn(202, 202, dtype=cp.float32) - print("elevation ", elevation.shape) - param = Parameter() - fc = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) - print("chainer ", fc(elevation)) - - ft = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) - print("torch ", ft(elevation)) diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_polygon.py b/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_polygon.py deleted file mode 100644 index be874f1b..00000000 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/traversability_polygon.py +++ /dev/null @@ -1,77 +0,0 @@ -# -# Copyright (c) 2022, Takahiro Miki. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for details. -# -import numpy as np -import cupy as cp -from shapely.geometry import Polygon, MultiPoint - - -def get_masked_traversability(map_array, mask, traversability): - traversability = traversability[1:-1, 1:-1] - is_valid = map_array[2][1:-1, 1:-1] - mask = mask[1:-1, 1:-1] - - # invalid place is 0 traversability value - untraversability = cp.where(is_valid > 0.5, 1 - traversability, 0) - masked = untraversability * mask - masked_isvalid = is_valid * mask - return masked, masked_isvalid - - -def is_traversable(masked_untraversability, thresh, min_thresh, max_over_n): - untraversable_thresh = 1 - thresh - max_thresh = 1 - min_thresh - over_thresh = cp.where(masked_untraversability > untraversable_thresh, 1, 0) - polygon = calculate_untraversable_polygon(over_thresh) - max_untraversability = masked_untraversability.max() - if over_thresh.sum() > max_over_n: - is_safe = False - elif max_untraversability > max_thresh: - is_safe = False - else: - is_safe = True - return is_safe, polygon - - -def calculate_area(polygon): - area = 0 - for i in range(len(polygon)): - p1 = polygon[i - 1] - p2 = polygon[i] - area += (p1[0] * p2[1] - p1[1] * p2[0]) / 2.0 - return abs(area) - - -def calculate_untraversable_polygon(over_thresh): - x, y = cp.where(over_thresh > 0.5) - points = cp.stack([x, y]).T - convex_hull = MultiPoint(points.get()).convex_hull - if convex_hull.is_empty or convex_hull.geom_type == "Point" or convex_hull.geom_type == "LineString": - return None - else: - return cp.array(convex_hull.exterior.coords) - - -def transform_to_map_position(polygon, center, cell_n, resolution): - polygon = center.reshape(1, 2) + (polygon - cell_n / 2.0) * resolution - return polygon - - -def transform_to_map_index(points, center, cell_n, resolution): - indices = ((points - center.reshape(1, 2)) / resolution + cell_n / 2).astype(cp.int32) - return indices - - -if __name__ == "__main__": - polygon = [[0, 0], [2, 0], [0, 2]] - print(calculate_area(polygon)) - - under_thresh = cp.zeros((20, 20)) - # under_thresh[10:12, 8:10] = 1.0 - under_thresh[14:18, 8:10] = 1.0 - under_thresh[1:8, 2:9] = 1.0 - print(under_thresh) - polygon = calculate_untraversable_polygon(under_thresh) - print(polygon) - transform_to_map_position(polygon, cp.array([0.5, 1.0]), 6.0, 0.05) diff --git a/elevation_mapping_cupy/config/core/core_param copy 2.yaml b/elevation_mapping_cupy/config/core/core_param copy 2.yaml new file mode 100644 index 00000000..3a693641 --- /dev/null +++ b/elevation_mapping_cupy/config/core/core_param copy 2.yaml @@ -0,0 +1,197 @@ +elevation_mapping: + ros__parameters: + #### Basic parameters ######## + voxel_filter_size: 0.05 + enable_normal_arrow_publishing: true + cell_n: 40000 # number of cells in the map. + data_type: 'float32' # data type for the map. + average_weight: 0.5 + drift_compensation_variance_inlier: 0.1 + checker_layer: 'traversability' # layer name for checking the validity of the cell. + min_filter_size: 5 # size of the filter for min filter. + min_filter_iteration: 3 # number of iterations for min filter. + initialized_variance: 10.0 # initial variance for each cell. + resolution: 0.1 # resolution in m. + map_length: 20.0 # map's size in m. + sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). + mahalanobis_thresh: 2.0 # points outside this distance is outlier. + outlier_variance: 0.01 # if point is outlier, add this value to the cell. + drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. + max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) + drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation + time_variance: 0.0001 # add this value when update_variance is called. + max_variance: 100.0 # maximum variance for each cell. + initial_variance: 1000.0 # initial variance for each cell. + traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. + dilation_size: 3 # dilation filter size before traversability filter. + wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. + min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. + position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. + orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. + position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. + orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. + min_valid_distance: 0.5 # points with shorter distance will be filtered out. + max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. + ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + update_variance_fps: 5.0 # fps for updating variance. + update_pose_fps: 10.0 # fps for updating pose and shift the center of map. + time_interval: 0.1 # Time layer is updated with this interval. + map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. + publish_statistics_fps: 1.0 # Publish statistics topic in this fps. + + max_ray_length: 10.0 # maximum length for ray tracing. + cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + + safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. + safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. + max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + + overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) + overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + pose_topic: '/odom' + map_frame: 'odom' # The map frame where the odometry source uses. + base_frame: 'base_link' # The robot's base frame. This frame will be a center of the map. + corrected_map_frame: 'odom' + + + + #### Feature toggles ######## + enable_edge_sharpen: true + enable_visibility_cleanup: true + enable_drift_compensation: true + enable_overlap_clearance: true + enable_pointcloud_publishing: false + enable_drift_corrected_TF_publishing: false + enable_normal_color: true # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + + + #### Traversability filter ######## + use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. + weight_file: '/share/elevation_mapping_cupy/config/core/weights.dat' # Weight file for traversability filter + plugin_config_file: '/share/elevation_mapping_cupy/config/core/plugin_config.yaml' # Configuration file for the plugin. + #### Upper bound ######## + use_only_above_for_upper_bound: false + + #### Initializer ######## + initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' + initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. + initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. + dilation_size_initialize: 2 # dilation size after the init. + initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. + use_initializer_at_start: true # Use initializer when the node starts. + + #### Default Plugins ######## + + pointcloud_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'average' # 'average' fusion is used for channels not listed here + + image_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'exponential' # 'exponential' fusion is used for channels not listed here + feat_.*: 'exponential' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names + + #### Subscribers ######## + # pointcloud_sensor_name: + # topic_name: '/sensor/pointcloud_semantic' + # data_type: pointcloud # pointcloud or image + # + # image_sensor_name: + # topic_name: '/camera/image_semantic' + # data_type: image # pointcloud or image + # camera_info_topic_name: '/camera/depth/camera_info' + # channel_info_topic_name: '/camera/channel_info' + + + subscribers: + pointcloud1: + # topic_name: '/ouster/points' + topic_name: '/a200/sensors/camera_0/points' + data_type: 'pointcloud' + image1: + topic_name: '/feat_processing_node/semantic_seg_feat' + info_name: '/feat_processing_node/a200/sensors/camera_0/color/camera_info_resized' + channel_name: '/feat_processing_node/feat_channel_info' + data_type: 'image' + # image2: + # topic_name: '/a200/sensors/camera_0/color/image' + # info_name: '/a200/sensors/camera_0/color/camera_info' + # data_type: 'image' + # channel_name: '/front_cam/channel_info' + + # channel_name: '/front_cam/channel_info' + + # image_topic2: '/camera/rgb/image_raw2' + # image_info2: '/camera/depth/camera_info2' + # image_channel_info1: '/front_cam/channel_info' + + # image: # for semantic images + # topic_name: '/front_cam/semantic_image' + # camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' + # channel_info_topic_name: '/front_cam/channel_info' + # data_type: image + + #### Publishers ######## + # topic_name: + # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names + # basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. + # fps: # Publish rate. Use smaller value than `map_acquire_fps`. + + publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb', 'normal_x', 'normal_y', 'normal_z', 'feat_0','feat_1','feat_2','feat_3','feat_4'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_recordable: + layers: ['elevation', 'traversability'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + basic_layers: ['min_filter'] + fps: 3.0 + + + # plugun info + + min_filter: + enable: True # whether to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # These params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations + + # Apply smoothing. + smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" + + # Apply inpainting using opencv + inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns + + # Apply smoothing for inpainted layer + erosion: + enable: True + fill_nan: False + is_height_layer: False + layer_name: "erosion" + extra_params: + input_layer_name: "traversability" + dilation_size: 3 + iteration_n: 20 + reverse: True \ No newline at end of file diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 3a693641..8cc68a55 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -1,17 +1,17 @@ elevation_mapping: ros__parameters: #### Basic parameters ######## - voxel_filter_size: 0.05 + voxel_filter_size: 0.1 enable_normal_arrow_publishing: true - cell_n: 40000 # number of cells in the map. + cell_n: 10000 # number of cells in the map. data_type: 'float32' # data type for the map. average_weight: 0.5 drift_compensation_variance_inlier: 0.1 - checker_layer: 'traversability' # layer name for checking the validity of the cell. + checker_layer: 'elevation' # layer name for checking the validity of the cell. min_filter_size: 5 # size of the filter for min filter. min_filter_iteration: 3 # number of iterations for min filter. initialized_variance: 10.0 # initial variance for each cell. - resolution: 0.1 # resolution in m. + resolution: 0.25 # resolution in m. map_length: 20.0 # map's size in m. sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). mahalanobis_thresh: 2.0 # points outside this distance is outlier. @@ -51,10 +51,10 @@ elevation_mapping: overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - pose_topic: '/odom' - map_frame: 'odom' # The map frame where the odometry source uses. + pose_topic: '/dlio/odom_node/odom' + map_frame: 'map' # The map frame where the odometry source uses. base_frame: 'base_link' # The robot's base frame. This frame will be a center of the map. - corrected_map_frame: 'odom' + corrected_map_frame: 'map_corrected' @@ -77,7 +77,7 @@ elevation_mapping: #### Initializer ######## initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' - initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. + initialize_frame_id: ['base_link'] # One tf (like ['footprint'] ) initializes a square around it. initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 2 # dilation size after the init. initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. @@ -87,12 +87,12 @@ elevation_mapping: pointcloud_channel_fusions: rgb: 'color' # 'color' fusion is used for the 'rgb' channel - default: 'average' # 'average' fusion is used for channels not listed here + default: 'exponential' # 'average' fusion is used for channels not listed here image_channel_fusions: rgb: 'color' # 'color' fusion is used for the 'rgb' channel - default: 'exponential' # 'exponential' fusion is used for channels not listed here - feat_.*: 'exponential' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names + default: 'latest' # 'exponential' fusion is used for channels not listed here + feat_.*: 'latest' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names #### Subscribers ######## # pointcloud_sensor_name: @@ -109,12 +109,12 @@ elevation_mapping: subscribers: pointcloud1: # topic_name: '/ouster/points' - topic_name: '/a200/sensors/camera_0/points' + topic_name: '/camera/camera/depth/color/points' data_type: 'pointcloud' image1: - topic_name: '/feat_processing_node/semantic_seg_feat' - info_name: '/feat_processing_node/a200/sensors/camera_0/color/camera_info_resized' - channel_name: '/feat_processing_node/feat_channel_info' + topic_name: '/feat_processing_node/semantic_feat' + info_name: '/feat_processing_node/camera/camera/color/camera_info_resized' + channel_name: '/feat_processing_node/feat_channel_info' data_type: 'image' # image2: # topic_name: '/a200/sensors/camera_0/color/image' @@ -141,18 +141,19 @@ elevation_mapping: # fps: # Publish rate. Use smaller value than `map_acquire_fps`. publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb', 'normal_x', 'normal_y', 'normal_z', 'feat_0','feat_1','feat_2','feat_3','feat_4'] + elevation_map_raw: + # layers: ['us_valid','elevation', 'variance','rgb', 'normal_x', 'normal_y', 'normal_z', 'feat_0','feat_1','feat_2','feat_3','feat_4','feat_5','feat_6','feat_7','feat_8','feat_9'] + layers: ['is_valid','elevation', 'variance','rgb', 'normal_x', 'normal_y', 'normal_z', 'feat_0','feat_1','feat_2'] basic_layers: ['elevation'] fps: 5.0 - elevation_map_recordable: - layers: ['elevation', 'traversability'] - basic_layers: ['elevation', 'traversability'] - fps: 2.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] - basic_layers: ['min_filter'] - fps: 3.0 + # elevation_map_recordable: + # layers: ['elevation'] + # basic_layers: ['elevation'] + # fps: 1.0 + # elevation_map_filter: + # layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + # basic_layers: ['min_filter'] + # fps: 3.0 # plugun info diff --git a/elevation_mapping_cupy/config/core/core_param_sim.yaml b/elevation_mapping_cupy/config/core/core_param_sim.yaml new file mode 100644 index 00000000..acfedb86 --- /dev/null +++ b/elevation_mapping_cupy/config/core/core_param_sim.yaml @@ -0,0 +1,197 @@ +elevation_mapping: + ros__parameters: + #### Basic parameters ######## + voxel_filter_size: 0.05 + enable_normal_arrow_publishing: true + cell_n: 40000 # number of cells in the map. + data_type: 'float32' # data type for the map. + average_weight: 0.5 + drift_compensation_variance_inlier: 0.1 + checker_layer: 'traversability' # layer name for checking the validity of the cell. + min_filter_size: 5 # size of the filter for min filter. + min_filter_iteration: 3 # number of iterations for min filter. + initialized_variance: 10.0 # initial variance for each cell. + resolution: 0.1 # resolution in m. + map_length: 20.0 # map's size in m. + sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). + mahalanobis_thresh: 2.0 # points outside this distance is outlier. + outlier_variance: 0.01 # if point is outlier, add this value to the cell. + drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. + max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) + drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation + time_variance: 0.0001 # add this value when update_variance is called. + max_variance: 100.0 # maximum variance for each cell. + initial_variance: 1000.0 # initial variance for each cell. + traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. + dilation_size: 3 # dilation filter size before traversability filter. + wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. + min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. + position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. + orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. + position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. + orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. + min_valid_distance: 0.5 # points with shorter distance will be filtered out. + max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. + ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. + update_variance_fps: 5.0 # fps for updating variance. + update_pose_fps: 10.0 # fps for updating pose and shift the center of map. + time_interval: 0.1 # Time layer is updated with this interval. + map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. + publish_statistics_fps: 1.0 # Publish statistics topic in this fps. + + max_ray_length: 10.0 # maximum length for ray tracing. + cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. + + safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. + safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. + max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. + + overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) + overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) + pose_topic: '/a200/robot/gt_odom' + map_frame: 'map' # The map frame where the odometry source uses. + base_frame: 'base_link' # The robot's base frame. This frame will be a center of the map. + corrected_map_frame: 'map_corrected' # The map frame where the drift corrected map is published. + + + + #### Feature toggles ######## + enable_edge_sharpen: true + enable_visibility_cleanup: true + enable_drift_compensation: true + enable_overlap_clearance: true + enable_pointcloud_publishing: false + enable_drift_corrected_TF_publishing: false + enable_normal_color: true # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. + + + #### Traversability filter ######## + use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. + weight_file: '/share/elevation_mapping_cupy/config/core/weights.dat' # Weight file for traversability filter + plugin_config_file: '/share/elevation_mapping_cupy/config/core/plugin_config.yaml' # Configuration file for the plugin. + #### Upper bound ######## + use_only_above_for_upper_bound: false + + #### Initializer ######## + initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' + initialize_frame_id: ['base_link'] # One tf (like ['footprint'] ) initializes a square around it. + initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. + dilation_size_initialize: 2 # dilation size after the init. + initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. + use_initializer_at_start: true # Use initializer when the node starts. + + #### Default Plugins ######## + + pointcloud_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'latest' # 'average' fusion is used for channels not listed here + + image_channel_fusions: + rgb: 'color' # 'color' fusion is used for the 'rgb' channel + default: 'latest' # 'exponential' fusion is used for channels not listed here + feat_.*: 'latest' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names + + #### Subscribers ######## + # pointcloud_sensor_name: + # topic_name: '/sensor/pointcloud_semantic' + # data_type: pointcloud # pointcloud or image + # + # image_sensor_name: + # topic_name: '/camera/image_semantic' + # data_type: image # pointcloud or image + # camera_info_topic_name: '/camera/depth/camera_info' + # channel_info_topic_name: '/camera/channel_info' + + + subscribers: + pointcloud1: + # topic_name: '/ouster/points' + topic_name: '/a200/sensors/camera_0/points' + data_type: 'pointcloud' + image1: + topic_name: '/feat_processing_node/semantic_seg_feat' + info_name: '/feat_processing_node/a200/sensors/camera_0/color/camera_info_resized' + channel_name: '/feat_processing_node/feat_channel_info' + data_type: 'image' + # image2: + # topic_name: '/a200/sensors/camera_0/color/image' + # info_name: '/a200/sensors/camera_0/color/camera_info' + # data_type: 'image' + # channel_name: '/front_cam/channel_info' + + # channel_name: '/front_cam/channel_info' + + # image_topic2: '/camera/rgb/image_raw2' + # image_info2: '/camera/depth/camera_info2' + # image_channel_info1: '/front_cam/channel_info' + + # image: # for semantic images + # topic_name: '/front_cam/semantic_image' + # camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' + # channel_info_topic_name: '/front_cam/channel_info' + # data_type: image + + #### Publishers ######## + # topic_name: + # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names + # basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. + # fps: # Publish rate. Use smaller value than `map_acquire_fps`. + + publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb', 'normal_x', 'normal_y', 'normal_z', 'feat_0','feat_1','feat_2','feat_3','feat_4'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_recordable: + layers: ['elevation', 'traversability'] + basic_layers: ['elevation', 'traversability'] + fps: 2.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + basic_layers: ['min_filter'] + fps: 3.0 + + + # plugun info + + min_filter: + enable: True # whether to load this plugin + fill_nan: False # Fill nans to invalid cells of elevation layer. + is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) + layer_name: "min_filter" # The layer name. + extra_params: # These params are passed to the plugin class on initialization. + dilation_size: 1 # The patch size to apply + iteration_n: 30 # The number of iterations + + # Apply smoothing. + smooth_filter: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "smooth" + extra_params: + input_layer_name: "min_filter" + + # Apply inpainting using opencv + inpainting: + enable: True + fill_nan: False + is_height_layer: True + layer_name: "inpaint" + extra_params: + method: "telea" # telea or ns + + # Apply smoothing for inpainted layer + erosion: + enable: True + fill_nan: False + is_height_layer: False + layer_name: "erosion" + extra_params: + input_layer_name: "traversability" + dilation_size: 3 + iteration_n: 20 + reverse: True \ No newline at end of file diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index aa843e8f..32838ab4 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -219,6 +219,7 @@ visualization_msgs::msg::Marker vectorToArrowMarker(const Eigen::Vector3d& start double positionAlpha_; double orientationAlpha_; double voxel_filter_size_; + pcl::VoxelGrid voxel_filter; double recordableFps_; std::atomic_bool enablePointCloudPublishing_; diff --git a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py index ea19064c..8c0fc575 100644 --- a/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py @@ -613,6 +613,10 @@ def get_elevation(self): """ return self.process_map_for_publish(self.elevation_map[0], fill_nan=True, add_z=True) + + def get_is_valid(self): + m = xp.where(self.elevation_map[2] > 0.5, 1.0, 0.0) + return m[1:-1, 1:-1] def get_variance(self): """Get the variance layer. @@ -741,6 +745,8 @@ def get_map_with_name_ref(self, name, data): if name == "elevation": m = self.get_elevation() use_stream = False + elif name == "is_valid": + m = self.get_is_valid() elif name == "variance": m = self.get_variance() elif name == "traversability": diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_exponential.py b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_latest.py similarity index 77% rename from elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_exponential.py rename to elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_latest.py index 26aa2f89..e8e7eb14 100644 --- a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/image_exponential.py +++ b/elevation_mapping_cupy/script/elevation_mapping_cupy/fusion/image_latest.py @@ -9,8 +9,8 @@ from .fusion_manager import FusionBase -def exponential_correspondences_to_map_kernel(resolution, width, height, alpha): - exponential_correspondences_to_map_kernel = cp.ElementwiseKernel( +def latest_correspondences_to_map_kernel(resolution, width, height, alpha): + latest_correspondences_to_map_kernel = cp.ElementwiseKernel( in_params="raw U sem_map, raw U map_idx, raw U image_mono, raw U uv_correspondence, raw B valid_correspondence, raw U image_height, raw U image_width", out_params="raw U new_sem_map", preamble=string.Template( @@ -27,27 +27,27 @@ def exponential_correspondences_to_map_kernel(resolution, width, height, alpha): if (valid_correspondence[cell_idx]){ int cell_idx_2 = get_map_idx(i, 1); int idx = int(uv_correspondence[cell_idx]) + int(uv_correspondence[cell_idx_2]) * image_width; - new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)] * (1-${alpha}) + ${alpha} * image_mono[idx]; + new_sem_map[get_map_idx(i, map_idx)] = image_mono[idx]; }else{ new_sem_map[get_map_idx(i, map_idx)] = sem_map[get_map_idx(i, map_idx)]; } """ ).substitute(alpha=alpha), - name="exponential_correspondences_to_map_kernel", + name="latest_correspondences_to_map_kernel", ) - return exponential_correspondences_to_map_kernel + return latest_correspondences_to_map_kernel -class ImageExponential(FusionBase): +class ImageLatest(FusionBase): def __init__(self, params, *args, **kwargs): # super().__init__(fusion_params, *args, **kwargs) # print("Initialize fusion kernel") - self.name = "image_exponential" + self.name = "image_latest" self.cell_n = params.cell_n self.resolution = params.resolution - self.exponential_correspondences_to_map_kernel = exponential_correspondences_to_map_kernel( + self.latest_correspondences_to_map_kernel = latest_correspondences_to_map_kernel( resolution=self.resolution, width=self.cell_n, height=self.cell_n, alpha=0.7, ) @@ -63,7 +63,7 @@ def __call__( semantic_map, new_map, ): - self.exponential_correspondences_to_map_kernel( + self.latest_correspondences_to_map_kernel( semantic_map, sem_map_idx, image[j], diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index 1e3f5505..a16e6d3a 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -182,14 +182,17 @@ ElevationMappingNode::ElevationMappingNode() channels_[key].push_back("y"); channels_[key].push_back("z"); - rmw_qos_profile_t qos_profile = rmw_qos_profile_default; - auto qos = rclcpp::QoS(rclcpp::QoSInitialization(qos_profile.history, qos_profile.depth), qos_profile); + // rmw_qos_profile_t qos_profile = rmw_qos_profile_default; + // auto qos = rclcpp::QoS(rclcpp::QoSInitialization(qos_profile.history, qos_profile.depth), qos_profile); + + rmw_qos_profile_t sensor_qos_profile = rmw_qos_profile_sensor_data; + auto sensor_qos = rclcpp::QoS(rclcpp::QoSInitialization(sensor_qos_profile.history, sensor_qos_profile.depth), sensor_qos_profile); auto callback = [this, key](const sensor_msgs::msg::PointCloud2::SharedPtr msg) { this->pointcloudCallback(msg, key); }; - auto sub = this->create_subscription(pointcloud_topic, qos, callback); + auto sub = this->create_subscription(pointcloud_topic, sensor_qos, callback); pointcloudSubs_.push_back(sub); RCLCPP_INFO(this->get_logger(), "Subscribed to PointCloud2 topic: %s", pointcloud_topic.c_str()); } @@ -422,7 +425,7 @@ void ElevationMappingNode::inputPointCloud(const sensor_msgs::msg::PointCloud2:: // apply the voxel filtering pcl::PCLPointCloud2::Ptr pcl_pc (new pcl::PCLPointCloud2()); - pcl::VoxelGrid voxel_filter; + // pcl::VoxelGrid voxel_filter; voxel_filter.setInputCloud(raw_pcl_pc); voxel_filter.setLeafSize(voxel_filter_size_,voxel_filter_size_,voxel_filter_size_); voxel_filter.filter(*pcl_pc); @@ -579,8 +582,8 @@ void ElevationMappingNode::imageCallback(const sensor_msgs::msg::Image::SharedPt std::vector channels; channels = imageChannelReady_[key].first.channels; inputImage(image_msg, camera_info_msg, channels); - } - RCLCPP_INFO(this->get_logger(), "ElevationMap imageChannelCallback processed an image in %f sec.", (this->now() - start).seconds()); + } + RCLCPP_DEBUG(this->get_logger(), "ElevationMap imageChannelCallback processed an image in %f sec.", (this->now() - start).seconds()); } diff --git a/filters b/filters new file mode 160000 index 00000000..eebb5f5a --- /dev/null +++ b/filters @@ -0,0 +1 @@ +Subproject commit eebb5f5aaa223f87b8d7bb97c04dc76e991944a0 diff --git a/grid_map b/grid_map new file mode 160000 index 00000000..05ce0217 --- /dev/null +++ b/grid_map @@ -0,0 +1 @@ +Subproject commit 05ce0217e729d7d586df74b6163736fac541a3db diff --git a/nav2_common/CMakeLists.txt b/nav2_common/CMakeLists.txt new file mode 100644 index 00000000..139835a8 --- /dev/null +++ b/nav2_common/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.5) + +project(nav2_common NONE) + +find_package(ament_cmake_core REQUIRED) +find_package(ament_cmake_python REQUIRED) + +ament_python_install_package(nav2_common) + +ament_package( + CONFIG_EXTRAS "nav2_common-extras.cmake" +) + +install( + DIRECTORY cmake + DESTINATION share/${PROJECT_NAME} +) diff --git a/nav2_common/cmake/nav2_package.cmake b/nav2_common/cmake/nav2_package.cmake new file mode 100644 index 00000000..b00d30c1 --- /dev/null +++ b/nav2_common/cmake/nav2_package.cmake @@ -0,0 +1,57 @@ +# Copyright 2019 Intel Corporation +# +# 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. + +# +# Standard Nav2 project setup +# +# @public +# +macro(nav2_package) + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to Release as none was specified.") + set(CMAKE_BUILD_TYPE "Release" CACHE + STRING "Choose the type of build." FORCE) + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Release" "MinSizeRel" "RelWithDebInfo") + endif() + + # Default to C++14 + if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 17) + endif() + + if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic -Werror -Wdeprecated -fPIC) + endif() + + option(COVERAGE_ENABLED "Enable code coverage" FALSE) + if(COVERAGE_ENABLED) + add_compile_options(--coverage) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage") + endif() + + # Defaults for Microsoft C++ compiler + if(MSVC) + # https://blog.kitware.com/create-dlls-on-windows-without-declspec-using-new-cmake-export-all-feature/ + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + + # Enable Math Constants + # https://docs.microsoft.com/en-us/cpp/c-runtime-library/math-constants?view=vs-2019 + add_compile_definitions( + _USE_MATH_DEFINES + ) + endif() +endmacro() diff --git a/nav2_common/nav2_common-extras.cmake b/nav2_common/nav2_common-extras.cmake new file mode 100644 index 00000000..c5f930b3 --- /dev/null +++ b/nav2_common/nav2_common-extras.cmake @@ -0,0 +1,17 @@ +# Copyright 2019 Intel Corporation +# +# 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. + +set(AMENT_BUILD_CONFIGURATION_KEYWORD_SEPARATOR ":") + +include("${nav2_common_DIR}/nav2_package.cmake") diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/__init__.py b/nav2_common/nav2_common/__init__.py similarity index 100% rename from elevation_mapping_cupy/build/lib/elevation_mapping_cupy/fusion/__init__.py rename to nav2_common/nav2_common/__init__.py diff --git a/nav2_common/nav2_common/launch/__init__.py b/nav2_common/nav2_common/launch/__init__.py new file mode 100644 index 00000000..7eba78e1 --- /dev/null +++ b/nav2_common/nav2_common/launch/__init__.py @@ -0,0 +1,18 @@ +# Copyright (c) 2019 Intel Corporation +# +# 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 .has_node_params import HasNodeParams +from .rewritten_yaml import RewrittenYaml +from .replace_string import ReplaceString +from .parse_multirobot_pose import ParseMultiRobotPose diff --git a/nav2_common/nav2_common/launch/has_node_params.py b/nav2_common/nav2_common/launch/has_node_params.py new file mode 100644 index 00000000..92f96790 --- /dev/null +++ b/nav2_common/nav2_common/launch/has_node_params.py @@ -0,0 +1,60 @@ +# Copyright (c) 2021 PAL Robotics S.L. +# +# 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 typing import List +from typing import Text + +import yaml +import launch + +import sys # delete this + +class HasNodeParams(launch.Substitution): + """ + Substitution that checks if a param file contains parameters for a node + + Used in launch system + """ + + def __init__(self, + source_file: launch.SomeSubstitutionsType, + node_name: Text) -> None: + super().__init__() + """ + Construct the substitution + + :param: source_file the parameter YAML file + :param: node_name the name of the node to check + """ + + from launch.utilities import normalize_to_list_of_substitutions # import here to avoid loop + self.__source_file = normalize_to_list_of_substitutions(source_file) + self.__node_name = node_name + + @property + def name(self) -> List[launch.Substitution]: + """Getter for name.""" + return self.__source_file + + def describe(self) -> Text: + """Return a description of this substitution as a string.""" + return '' + + def perform(self, context: launch.LaunchContext) -> Text: + yaml_filename = launch.utilities.perform_substitutions(context, self.name) + data = yaml.safe_load(open(yaml_filename, 'r')) + + if self.__node_name in data.keys(): + return "True" + return "False" diff --git a/nav2_common/nav2_common/launch/parse_multirobot_pose.py b/nav2_common/nav2_common/launch/parse_multirobot_pose.py new file mode 100644 index 00000000..9025f967 --- /dev/null +++ b/nav2_common/nav2_common/launch/parse_multirobot_pose.py @@ -0,0 +1,82 @@ +# Copyright (c) 2023 LG Electronics. +# +# 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 yaml +import sys +from typing import Text, Dict + + +class ParseMultiRobotPose(): + """ + Parsing argument using sys module + """ + + def __init__(self, target_argument: Text): + """ + Parse arguments for multi-robot's pose + + for example, + `ros2 launch nav2_bringup bringup_multirobot_launch.py + robots:="robot1={x: 1.0, y: 1.0, yaw: 0.0}; + robot2={x: 1.0, y: 1.0, z: 1.0, roll: 0.0, pitch: 1.5707, yaw: 1.5707}"` + + `target_argument` shall be 'robots'. + Then, this will parse a string value for `robots` argument. + + Each robot name which is corresponding to namespace and pose of it will be separted by `;`. + The pose consists of x, y and yaw with YAML format. + + :param: target argument name to parse + """ + self.__args: Text = self.__parse_argument(target_argument) + + def __parse_argument(self, target_argument: Text) -> Text: + """ + get value of target argument + """ + if len(sys.argv) > 4: + argv = sys.argv[4:] + for arg in argv: + if arg.startswith(target_argument + ":="): + return arg.replace(target_argument + ":=", "") + return "" + + def value(self) -> Dict: + """ + get value of target argument + """ + args = self.__args + parsed_args = list() if len(args) == 0 else args.split(';') + multirobots = dict() + for arg in parsed_args: + key_val = arg.strip().split('=') + if len(key_val) != 2: + continue + key = key_val[0].strip() + val = key_val[1].strip() + robot_pose = yaml.safe_load(val) + if 'x' not in robot_pose: + robot_pose['x'] = 0.0 + if 'y' not in robot_pose: + robot_pose['y'] = 0.0 + if 'z' not in robot_pose: + robot_pose['z'] = 0.0 + if 'roll' not in robot_pose: + robot_pose['roll'] = 0.0 + if 'pitch' not in robot_pose: + robot_pose['pitch'] = 0.0 + if 'yaw' not in robot_pose: + robot_pose['yaw'] = 0.0 + multirobots[key] = robot_pose + return multirobots diff --git a/nav2_common/nav2_common/launch/replace_string.py b/nav2_common/nav2_common/launch/replace_string.py new file mode 100644 index 00000000..9d22f173 --- /dev/null +++ b/nav2_common/nav2_common/launch/replace_string.py @@ -0,0 +1,87 @@ +# Copyright (c) 2019 Intel Corporation +# +# 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 typing import Dict +from typing import List +from typing import Text +from typing import Optional +import tempfile +import launch + +class ReplaceString(launch.Substitution): + """ + Substitution that replaces strings on a given file. + + Used in launch system + """ + + def __init__(self, + source_file: launch.SomeSubstitutionsType, + replacements: Dict, + condition: Optional[launch.Condition] = None) -> None: + super().__init__() + + from launch.utilities import normalize_to_list_of_substitutions # import here to avoid loop + self.__source_file = normalize_to_list_of_substitutions(source_file) + self.__replacements = {} + for key in replacements: + self.__replacements[key] = normalize_to_list_of_substitutions(replacements[key]) + self.__condition = condition + + @property + def name(self) -> List[launch.Substitution]: + """Getter for name.""" + return self.__source_file + + @property + def condition(self) -> Optional[launch.Condition]: + """Getter for condition.""" + return self.__condition + + def describe(self) -> Text: + """Return a description of this substitution as a string.""" + return '' + + def perform(self, context: launch.LaunchContext) -> Text: + yaml_filename = launch.utilities.perform_substitutions(context, self.name) + if self.__condition is None or self.__condition.evaluate(context): + output_file = tempfile.NamedTemporaryFile(mode='w', delete=False) + replacements = self.resolve_replacements(context) + try: + input_file = open(yaml_filename, 'r') + self.replace(input_file, output_file, replacements) + except Exception as err: # noqa: B902 + print('ReplaceString substitution error: ', err) + finally: + input_file.close() + output_file.close() + return output_file.name + else: + return yaml_filename + + def resolve_replacements(self, context): + resolved_replacements = {} + for key in self.__replacements: + resolved_replacements[key] = launch.utilities.perform_substitutions(context, self.__replacements[key]) + return resolved_replacements + + def replace(self, input_file, output_file, replacements): + for line in input_file: + for key, value in replacements.items(): + if isinstance(key, str) and isinstance(value, str): + if key in line: + line = line.replace(key, value) + else: + raise TypeError('A provided replacement pair is not a string. Both key and value should be strings.') + output_file.write(line) diff --git a/nav2_common/nav2_common/launch/rewritten_yaml.py b/nav2_common/nav2_common/launch/rewritten_yaml.py new file mode 100644 index 00000000..2887fa55 --- /dev/null +++ b/nav2_common/nav2_common/launch/rewritten_yaml.py @@ -0,0 +1,190 @@ +# Copyright (c) 2019 Intel Corporation +# +# 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 typing import Dict +from typing import List +from typing import Text +from typing import Optional + +import yaml +import tempfile +import launch + + +class DictItemReference: + def __init__(self, dictionary, key): + self.dictionary = dictionary + self.dictKey = key + + def key(self): + return self.dictKey + + def setValue(self, value): + self.dictionary[self.dictKey] = value + + +class RewrittenYaml(launch.Substitution): + """ + Substitution that modifies the given YAML file. + + Used in launch system + """ + + def __init__(self, + source_file: launch.SomeSubstitutionsType, + param_rewrites: Dict, + root_key: Optional[launch.SomeSubstitutionsType] = None, + key_rewrites: Optional[Dict] = None, + convert_types = False) -> None: + super().__init__() + """ + Construct the substitution + + :param: source_file the original YAML file to modify + :param: param_rewrites mappings to replace + :param: root_key if provided, the contents are placed under this key + :param: key_rewrites keys of mappings to replace + :param: convert_types whether to attempt converting the string to a number or boolean + """ + + from launch.utilities import normalize_to_list_of_substitutions # import here to avoid loop + self.__source_file = normalize_to_list_of_substitutions(source_file) + self.__param_rewrites = {} + self.__key_rewrites = {} + self.__convert_types = convert_types + self.__root_key = None + for key in param_rewrites: + self.__param_rewrites[key] = normalize_to_list_of_substitutions(param_rewrites[key]) + if key_rewrites is not None: + for key in key_rewrites: + self.__key_rewrites[key] = normalize_to_list_of_substitutions(key_rewrites[key]) + if root_key is not None: + self.__root_key = normalize_to_list_of_substitutions(root_key) + + @property + def name(self) -> List[launch.Substitution]: + """Getter for name.""" + return self.__source_file + + def describe(self) -> Text: + """Return a description of this substitution as a string.""" + return '' + + def perform(self, context: launch.LaunchContext) -> Text: + yaml_filename = launch.utilities.perform_substitutions(context, self.name) + rewritten_yaml = tempfile.NamedTemporaryFile(mode='w', delete=False) + param_rewrites, keys_rewrites = self.resolve_rewrites(context) + data = yaml.safe_load(open(yaml_filename, 'r')) + self.substitute_params(data, param_rewrites) + self.substitute_keys(data, keys_rewrites) + if self.__root_key is not None: + root_key = launch.utilities.perform_substitutions(context, self.__root_key) + if root_key: + data = {root_key: data} + yaml.dump(data, rewritten_yaml) + rewritten_yaml.close() + return rewritten_yaml.name + + def resolve_rewrites(self, context): + resolved_params = {} + for key in self.__param_rewrites: + resolved_params[key] = launch.utilities.perform_substitutions(context, self.__param_rewrites[key]) + resolved_keys = {} + for key in self.__key_rewrites: + resolved_keys[key] = launch.utilities.perform_substitutions(context, self.__key_rewrites[key]) + return resolved_params, resolved_keys + + def substitute_params(self, yaml, param_rewrites): + # substitute leaf-only parameters + for key in self.getYamlLeafKeys(yaml): + if key.key() in param_rewrites: + raw_value = param_rewrites[key.key()] + key.setValue(self.convert(raw_value)) + + # substitute total path parameters + yaml_paths = self.pathify(yaml) + for path in yaml_paths: + if path in param_rewrites: + # this is an absolute path (ex. 'key.keyA.keyB.val') + rewrite_val = self.convert(param_rewrites[path]) + yaml_keys = path.split('.') + yaml = self.updateYamlPathVals(yaml, yaml_keys, rewrite_val) + + + def updateYamlPathVals(self, yaml, yaml_key_list, rewrite_val): + for key in yaml_key_list: + if key == yaml_key_list[-1]: + yaml[key] = rewrite_val + break + key = yaml_key_list.pop(0) + if isinstance(yaml, list): + yaml[int(key)] = self.updateYamlPathVals(yaml[int(key)], yaml_key_list, rewrite_val) + else: + yaml[key] = self.updateYamlPathVals(yaml.get(key, {}), yaml_key_list, rewrite_val) + return yaml + + def substitute_keys(self, yaml, key_rewrites): + if len(key_rewrites) != 0: + for key in list(yaml.keys()): + val = yaml[key] + if key in key_rewrites: + new_key = key_rewrites[key] + yaml[new_key] = yaml[key] + del yaml[key] + if isinstance(val, dict): + self.substitute_keys(val, key_rewrites) + + def getYamlLeafKeys(self, yamlData): + try: + for key in yamlData.keys(): + for k in self.getYamlLeafKeys(yamlData[key]): + yield k + yield DictItemReference(yamlData, key) + except AttributeError: + return + + def pathify(self, d, p=None, paths=None, joinchar='.'): + if p is None: + paths = {} + self.pathify(d, "", paths, joinchar=joinchar) + return paths + pn = p + if p != "": + pn += joinchar + if isinstance(d, dict): + for k in d: + v = d[k] + self.pathify(v, str(pn) + str(k), paths, joinchar=joinchar) + elif isinstance(d, list): + for idx, e in enumerate(d): + self.pathify(e, pn + str(idx), paths, joinchar=joinchar) + else: + paths[p] = d + + def convert(self, text_value): + if self.__convert_types: + # try converting to int or float + try: + return float(text_value) if '.' in text_value else int(text_value) + except ValueError: + pass + + # try converting to bool + if text_value.lower() == "true": + return True + if text_value.lower() == "false": + return False + + # nothing else worked so fall through and return text + return text_value diff --git a/nav2_common/package.xml b/nav2_common/package.xml new file mode 100644 index 00000000..4284710e --- /dev/null +++ b/nav2_common/package.xml @@ -0,0 +1,25 @@ + + + + nav2_common + 1.1.17 + Common support functionality used throughout the navigation 2 stack + Carl Delsey + Apache-2.0 + + launch + launch_ros + osrf_pycommon + rclpy + python3-yaml + + ament_cmake_core + + ament_cmake_python + + ament_cmake_core + + + ament_cmake + + diff --git a/elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/__init__.py b/nav2_msgs/CHANGELOG.rst similarity index 100% rename from elevation_mapping_cupy/build/lib/elevation_mapping_cupy/plugins/__init__.py rename to nav2_msgs/CHANGELOG.rst diff --git a/nav2_msgs/CMakeLists.txt b/nav2_msgs/CMakeLists.txt new file mode 100644 index 00000000..b9895f07 --- /dev/null +++ b/nav2_msgs/CMakeLists.txt @@ -0,0 +1,53 @@ +cmake_minimum_required(VERSION 3.5) +project(nav2_msgs) + +find_package(ament_cmake REQUIRED) +find_package(nav2_common REQUIRED) +find_package(builtin_interfaces REQUIRED) +find_package(nav_msgs REQUIRED) +find_package(geometry_msgs REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(std_msgs REQUIRED) +find_package(action_msgs REQUIRED) + +nav2_package() + +rosidl_generate_interfaces(${PROJECT_NAME} + "msg/CollisionMonitorState.msg" + "msg/Costmap.msg" + "msg/CostmapMetaData.msg" + "msg/CostmapFilterInfo.msg" + "msg/SpeedLimit.msg" + "msg/VoxelGrid.msg" + "msg/BehaviorTreeStatusChange.msg" + "msg/BehaviorTreeLog.msg" + "msg/Particle.msg" + "msg/ParticleCloud.msg" + "srv/GetCostmap.srv" + "srv/IsPathValid.srv" + "srv/ClearCostmapExceptRegion.srv" + "srv/ClearCostmapAroundRobot.srv" + "srv/ClearEntireCostmap.srv" + "srv/ManageLifecycleNodes.srv" + "srv/LoadMap.srv" + "srv/SaveMap.srv" + "srv/SetInitialPose.srv" + "action/AssistedTeleop.action" + "action/BackUp.action" + "action/ComputePathToPose.action" + "action/ComputePathThroughPoses.action" + "action/DriveOnHeading.action" + "action/SmoothPath.action" + "action/FollowPath.action" + "action/NavigateToPose.action" + "action/NavigateThroughPoses.action" + "action/Wait.action" + "action/Spin.action" + "action/DummyBehavior.action" + "action/FollowWaypoints.action" + DEPENDENCIES builtin_interfaces geometry_msgs std_msgs action_msgs nav_msgs +) + +ament_export_dependencies(rosidl_default_runtime) + +ament_package() diff --git a/nav2_msgs/README.md b/nav2_msgs/README.md new file mode 100644 index 00000000..868c049f --- /dev/null +++ b/nav2_msgs/README.md @@ -0,0 +1,3 @@ +# nav2_msgs + +The `nav2_msgs` package is a set of messages, services, and actions for the `Nav2` system. `Nav2` also makes use of the standard `nav_msgs`, where appropriate. diff --git a/nav2_msgs/action/AssistedTeleop.action b/nav2_msgs/action/AssistedTeleop.action new file mode 100644 index 00000000..ba830ebc --- /dev/null +++ b/nav2_msgs/action/AssistedTeleop.action @@ -0,0 +1,8 @@ +#goal definition +builtin_interfaces/Duration time_allowance +--- +#result definition +builtin_interfaces/Duration total_elapsed_time +--- +#feedback +builtin_interfaces/Duration current_teleop_duration diff --git a/nav2_msgs/action/BackUp.action b/nav2_msgs/action/BackUp.action new file mode 100644 index 00000000..99373025 --- /dev/null +++ b/nav2_msgs/action/BackUp.action @@ -0,0 +1,10 @@ +#goal definition +geometry_msgs/Point target +float32 speed +builtin_interfaces/Duration time_allowance +--- +#result definition +builtin_interfaces/Duration total_elapsed_time +--- +#feedback definition +float32 distance_traveled diff --git a/nav2_msgs/action/ComputePathThroughPoses.action b/nav2_msgs/action/ComputePathThroughPoses.action new file mode 100644 index 00000000..a1f609a9 --- /dev/null +++ b/nav2_msgs/action/ComputePathThroughPoses.action @@ -0,0 +1,11 @@ +#goal definition +geometry_msgs/PoseStamped[] goals +geometry_msgs/PoseStamped start +string planner_id +bool use_start # If false, use current robot pose as path start, if true, use start above instead +--- +#result definition +nav_msgs/Path path +builtin_interfaces/Duration planning_time +--- +#feedback definition diff --git a/nav2_msgs/action/ComputePathToPose.action b/nav2_msgs/action/ComputePathToPose.action new file mode 100644 index 00000000..a052c552 --- /dev/null +++ b/nav2_msgs/action/ComputePathToPose.action @@ -0,0 +1,11 @@ +#goal definition +geometry_msgs/PoseStamped goal +geometry_msgs/PoseStamped start +string planner_id +bool use_start # If false, use current robot pose as path start, if true, use start above instead +--- +#result definition +nav_msgs/Path path +builtin_interfaces/Duration planning_time +--- +#feedback definition diff --git a/nav2_msgs/action/DriveOnHeading.action b/nav2_msgs/action/DriveOnHeading.action new file mode 100644 index 00000000..99373025 --- /dev/null +++ b/nav2_msgs/action/DriveOnHeading.action @@ -0,0 +1,10 @@ +#goal definition +geometry_msgs/Point target +float32 speed +builtin_interfaces/Duration time_allowance +--- +#result definition +builtin_interfaces/Duration total_elapsed_time +--- +#feedback definition +float32 distance_traveled diff --git a/nav2_msgs/action/DummyBehavior.action b/nav2_msgs/action/DummyBehavior.action new file mode 100644 index 00000000..4b8db815 --- /dev/null +++ b/nav2_msgs/action/DummyBehavior.action @@ -0,0 +1,7 @@ +#goal definition +std_msgs/String command +--- +#result definition +builtin_interfaces/Duration total_elapsed_time +--- +#feedback definition diff --git a/nav2_msgs/action/FollowPath.action b/nav2_msgs/action/FollowPath.action new file mode 100644 index 00000000..5462faa2 --- /dev/null +++ b/nav2_msgs/action/FollowPath.action @@ -0,0 +1,11 @@ +#goal definition +nav_msgs/Path path +string controller_id +string goal_checker_id +--- +#result definition +std_msgs/Empty result +--- +#feedback definition +float32 distance_to_goal +float32 speed diff --git a/nav2_msgs/action/FollowWaypoints.action b/nav2_msgs/action/FollowWaypoints.action new file mode 100644 index 00000000..c4b47648 --- /dev/null +++ b/nav2_msgs/action/FollowWaypoints.action @@ -0,0 +1,8 @@ +#goal definition +geometry_msgs/PoseStamped[] poses +--- +#result definition +int32[] missed_waypoints +--- +#feedback definition +uint32 current_waypoint diff --git a/nav2_msgs/action/NavigateThroughPoses.action b/nav2_msgs/action/NavigateThroughPoses.action new file mode 100644 index 00000000..e2a57f25 --- /dev/null +++ b/nav2_msgs/action/NavigateThroughPoses.action @@ -0,0 +1,14 @@ +#goal definition +geometry_msgs/PoseStamped[] poses +string behavior_tree +--- +#result definition +std_msgs/Empty result +--- +#feedback definition +geometry_msgs/PoseStamped current_pose +builtin_interfaces/Duration navigation_time +builtin_interfaces/Duration estimated_time_remaining +int16 number_of_recoveries +float32 distance_remaining +int16 number_of_poses_remaining diff --git a/nav2_msgs/action/NavigateToPose.action b/nav2_msgs/action/NavigateToPose.action new file mode 100644 index 00000000..b7077922 --- /dev/null +++ b/nav2_msgs/action/NavigateToPose.action @@ -0,0 +1,13 @@ +#goal definition +geometry_msgs/PoseStamped pose +string behavior_tree +--- +#result definition +std_msgs/Empty result +--- +#feedback definition +geometry_msgs/PoseStamped current_pose +builtin_interfaces/Duration navigation_time +builtin_interfaces/Duration estimated_time_remaining +int16 number_of_recoveries +float32 distance_remaining diff --git a/nav2_msgs/action/SmoothPath.action b/nav2_msgs/action/SmoothPath.action new file mode 100644 index 00000000..18560d70 --- /dev/null +++ b/nav2_msgs/action/SmoothPath.action @@ -0,0 +1,12 @@ +#goal definition +nav_msgs/Path path +string smoother_id +builtin_interfaces/Duration max_smoothing_duration +bool check_for_collisions +--- +#result definition +nav_msgs/Path path +builtin_interfaces/Duration smoothing_duration +bool was_completed +--- +#feedback definition diff --git a/nav2_msgs/action/Spin.action b/nav2_msgs/action/Spin.action new file mode 100644 index 00000000..3e1c0aad --- /dev/null +++ b/nav2_msgs/action/Spin.action @@ -0,0 +1,9 @@ +#goal definition +float32 target_yaw +builtin_interfaces/Duration time_allowance +--- +#result definition +builtin_interfaces/Duration total_elapsed_time +--- +#feedback definition +float32 angular_distance_traveled diff --git a/nav2_msgs/action/Wait.action b/nav2_msgs/action/Wait.action new file mode 100644 index 00000000..8cf71194 --- /dev/null +++ b/nav2_msgs/action/Wait.action @@ -0,0 +1,8 @@ +#goal definition +builtin_interfaces/Duration time +--- +#result definition +builtin_interfaces/Duration total_elapsed_time +--- +#feedback definition +builtin_interfaces/Duration time_left diff --git a/nav2_msgs/msg/BehaviorTreeLog.msg b/nav2_msgs/msg/BehaviorTreeLog.msg new file mode 100644 index 00000000..0f6ce7ef --- /dev/null +++ b/nav2_msgs/msg/BehaviorTreeLog.msg @@ -0,0 +1,2 @@ +builtin_interfaces/Time timestamp # ROS time that this log message was sent. +BehaviorTreeStatusChange[] event_log diff --git a/nav2_msgs/msg/BehaviorTreeStatusChange.msg b/nav2_msgs/msg/BehaviorTreeStatusChange.msg new file mode 100644 index 00000000..01cd812c --- /dev/null +++ b/nav2_msgs/msg/BehaviorTreeStatusChange.msg @@ -0,0 +1,4 @@ +builtin_interfaces/Time timestamp # internal behavior tree event timestamp. Typically this is wall clock time +string node_name +string previous_status # IDLE, RUNNING, SUCCESS or FAILURE +string current_status # IDLE, RUNNING, SUCCESS or FAILURE diff --git a/nav2_msgs/msg/CollisionMonitorState.msg b/nav2_msgs/msg/CollisionMonitorState.msg new file mode 100644 index 00000000..e470df57 --- /dev/null +++ b/nav2_msgs/msg/CollisionMonitorState.msg @@ -0,0 +1,9 @@ +# Action type for robot in Collision Monitor +uint8 DO_NOTHING=0 # No action +uint8 STOP=1 # Stop the robot +uint8 SLOWDOWN=2 # Slowdown in percentage from current operating speed +uint8 APPROACH=3 # Keep constant time interval before collision +uint8 action_type + +# Name of triggered polygon +string polygon_name \ No newline at end of file diff --git a/nav2_msgs/msg/Costmap.msg b/nav2_msgs/msg/Costmap.msg new file mode 100644 index 00000000..4c3e90ca --- /dev/null +++ b/nav2_msgs/msg/Costmap.msg @@ -0,0 +1,9 @@ +# This represents a 2-D grid map, in which each cell has an associated cost + +std_msgs/Header header + +# MetaData for the map +CostmapMetaData metadata + +# The cost data, in row-major order, starting with (0,0). +uint8[] data diff --git a/nav2_msgs/msg/CostmapFilterInfo.msg b/nav2_msgs/msg/CostmapFilterInfo.msg new file mode 100644 index 00000000..fb9d9af4 --- /dev/null +++ b/nav2_msgs/msg/CostmapFilterInfo.msg @@ -0,0 +1,14 @@ +std_msgs/Header header +# Type of plugin used (keepout filter, speed limit in m/s, speed limit in percent, etc...) +# 0: keepout/lanes filter +# 1: speed limit filter in % of maximum speed +# 2: speed limit filter in absolute values (m/s) +uint8 type +# Name of filter mask topic +string filter_mask_topic +# Multiplier base offset and multiplier coefficient for conversion of OccGrid. +# Used to convert OccupancyGrid data values to filter space values. +# data -> into some other number space: +# space = data * multiplier + base +float32 base +float32 multiplier diff --git a/nav2_msgs/msg/CostmapMetaData.msg b/nav2_msgs/msg/CostmapMetaData.msg new file mode 100644 index 00000000..0c74b661 --- /dev/null +++ b/nav2_msgs/msg/CostmapMetaData.msg @@ -0,0 +1,23 @@ +# This hold basic information about the characteristics of the Costmap + +# The time at which the static map was loaded +builtin_interfaces/Time map_load_time + +# The time of the last update to costmap +builtin_interfaces/Time update_time + +# The corresponding layer name +string layer + +# The map resolution [m/cell] +float32 resolution + +# Number of cells in the horizontal direction +uint32 size_x + +# Number of cells in the vertical direction +uint32 size_y + +# The origin of the costmap [m, m, rad]. +# This is the real-world pose of the cell (0,0) in the map. +geometry_msgs/Pose origin diff --git a/nav2_msgs/msg/Particle.msg b/nav2_msgs/msg/Particle.msg new file mode 100644 index 00000000..294bbd17 --- /dev/null +++ b/nav2_msgs/msg/Particle.msg @@ -0,0 +1,5 @@ +# This represents an individual particle with weight produced by a particle filter + +geometry_msgs/Pose pose + +float64 weight diff --git a/nav2_msgs/msg/ParticleCloud.msg b/nav2_msgs/msg/ParticleCloud.msg new file mode 100644 index 00000000..17b07ac7 --- /dev/null +++ b/nav2_msgs/msg/ParticleCloud.msg @@ -0,0 +1,6 @@ +# This represents a particle cloud containing particle poses and weights + +std_msgs/Header header + +# Array of particles in the cloud +Particle[] particles diff --git a/nav2_msgs/msg/SpeedLimit.msg b/nav2_msgs/msg/SpeedLimit.msg new file mode 100644 index 00000000..ea9630fc --- /dev/null +++ b/nav2_msgs/msg/SpeedLimit.msg @@ -0,0 +1,6 @@ +std_msgs/Header header +# Setting speed limit in percentage if true or in absolute values in false case +bool percentage +# Maximum allowed speed (in percent of maximum robot speed or in m/s depending +# on "percentage" value). When no-limit it is set to 0.0 +float64 speed_limit diff --git a/nav2_msgs/msg/VoxelGrid.msg b/nav2_msgs/msg/VoxelGrid.msg new file mode 100644 index 00000000..7223f67e --- /dev/null +++ b/nav2_msgs/msg/VoxelGrid.msg @@ -0,0 +1,7 @@ +std_msgs/Header header +uint32[] data +geometry_msgs/Point32 origin +geometry_msgs/Vector3 resolutions +uint32 size_x +uint32 size_y +uint32 size_z diff --git a/nav2_msgs/package.xml b/nav2_msgs/package.xml new file mode 100644 index 00000000..02c844a6 --- /dev/null +++ b/nav2_msgs/package.xml @@ -0,0 +1,28 @@ + + + + nav2_msgs + 1.1.17 + Messages and service files for the Nav2 stack + Michael Jeronimo + Steve Macenski + Carlos Orduno + Apache-2.0 + + ament_cmake + nav2_common + + rclcpp + std_msgs + builtin_interfaces + rosidl_default_generators + geometry_msgs + action_msgs + nav_msgs + + rosidl_interface_packages + + + ament_cmake + + diff --git a/nav2_msgs/srv/ClearCostmapAroundRobot.srv b/nav2_msgs/srv/ClearCostmapAroundRobot.srv new file mode 100644 index 00000000..e3b41bf5 --- /dev/null +++ b/nav2_msgs/srv/ClearCostmapAroundRobot.srv @@ -0,0 +1,5 @@ +# Clears the costmap within a distance + +float32 reset_distance +--- +std_msgs/Empty response diff --git a/nav2_msgs/srv/ClearCostmapExceptRegion.srv b/nav2_msgs/srv/ClearCostmapExceptRegion.srv new file mode 100644 index 00000000..56bb2f49 --- /dev/null +++ b/nav2_msgs/srv/ClearCostmapExceptRegion.srv @@ -0,0 +1,5 @@ +# Clears the costmap except a rectangular region specified by reset_distance + +float32 reset_distance +--- +std_msgs/Empty response diff --git a/nav2_msgs/srv/ClearEntireCostmap.srv b/nav2_msgs/srv/ClearEntireCostmap.srv new file mode 100644 index 00000000..ed1b675f --- /dev/null +++ b/nav2_msgs/srv/ClearEntireCostmap.srv @@ -0,0 +1,5 @@ +# Clears all layers on the costmap + +std_msgs/Empty request +--- +std_msgs/Empty response diff --git a/nav2_msgs/srv/GetCostmap.srv b/nav2_msgs/srv/GetCostmap.srv new file mode 100644 index 00000000..8dddc64a --- /dev/null +++ b/nav2_msgs/srv/GetCostmap.srv @@ -0,0 +1,6 @@ +# Get the costmap + +# Specifications for the requested costmap +nav2_msgs/CostmapMetaData specs +--- +nav2_msgs/Costmap map diff --git a/nav2_msgs/srv/IsPathValid.srv b/nav2_msgs/srv/IsPathValid.srv new file mode 100644 index 00000000..8d6dc3b3 --- /dev/null +++ b/nav2_msgs/srv/IsPathValid.srv @@ -0,0 +1,6 @@ +#Determine if the current path is still valid + +nav_msgs/Path path +--- +bool is_valid +int32[] invalid_pose_indices diff --git a/nav2_msgs/srv/LoadMap.srv b/nav2_msgs/srv/LoadMap.srv new file mode 100644 index 00000000..3b9caaad --- /dev/null +++ b/nav2_msgs/srv/LoadMap.srv @@ -0,0 +1,15 @@ +# URL of map resource +# Can be an absolute path to a file: file:///path/to/maps/floor1.yaml +# Or, relative to a ROS package: package://my_ros_package/maps/floor2.yaml +string map_url +--- +# Result code defintions +uint8 RESULT_SUCCESS=0 +uint8 RESULT_MAP_DOES_NOT_EXIST=1 +uint8 RESULT_INVALID_MAP_DATA=2 +uint8 RESULT_INVALID_MAP_METADATA=3 +uint8 RESULT_UNDEFINED_FAILURE=255 + +# Returned map is only valid if result equals RESULT_SUCCESS +nav_msgs/OccupancyGrid map +uint8 result diff --git a/nav2_msgs/srv/ManageLifecycleNodes.srv b/nav2_msgs/srv/ManageLifecycleNodes.srv new file mode 100644 index 00000000..8f37cbf8 --- /dev/null +++ b/nav2_msgs/srv/ManageLifecycleNodes.srv @@ -0,0 +1,9 @@ +uint8 STARTUP = 0 +uint8 PAUSE = 1 +uint8 RESUME = 2 +uint8 RESET = 3 +uint8 SHUTDOWN = 4 + +uint8 command +--- +bool success diff --git a/nav2_msgs/srv/SaveMap.srv b/nav2_msgs/srv/SaveMap.srv new file mode 100644 index 00000000..f50a881d --- /dev/null +++ b/nav2_msgs/srv/SaveMap.srv @@ -0,0 +1,14 @@ +# URL of map resource +# Can be an absolute path to a file: file:///path/to/maps/floor1.yaml +# Or, relative to a ROS package: package://my_ros_package/maps/floor2.yaml +string map_topic +string map_url +# Constants for image_format. Supported formats: pgm, png, bmp +string image_format +# Map modes: trinary, scale or raw +string map_mode +# Thresholds. Values in range of [0.0 .. 1.0] +float32 free_thresh +float32 occupied_thresh +--- +bool result diff --git a/nav2_msgs/srv/SetInitialPose.srv b/nav2_msgs/srv/SetInitialPose.srv new file mode 100644 index 00000000..ec1e50b6 --- /dev/null +++ b/nav2_msgs/srv/SetInitialPose.srv @@ -0,0 +1,3 @@ +geometry_msgs/PoseWithCovarianceStamped pose +--- + diff --git a/pcl_msgs b/pcl_msgs new file mode 160000 index 00000000..c67c7323 --- /dev/null +++ b/pcl_msgs @@ -0,0 +1 @@ +Subproject commit c67c7323796cf003ad67429186fb8959092ef70d diff --git a/perception_pcl b/perception_pcl new file mode 160000 index 00000000..ca66aa21 --- /dev/null +++ b/perception_pcl @@ -0,0 +1 @@ +Subproject commit ca66aa21f28b7e2848870f08faace81554e78437 diff --git a/plane_segmentation/README.md b/plane_segmentation/README.md deleted file mode 100644 index d9c17ae7..00000000 --- a/plane_segmentation/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Plane Segmentation - -## Overview - -This is a C++ ROS package for extracting convex polygons from elevation maps. -In a first step, the terrain is segmented into planes, and their non-convex contour is extracted. -In a second step, a local convex approximation can be obtained. - -## Usage - -### Build - -```bash -catkin build convex_plane_decomposition_ros -``` - -### Run as node - -```bash -roslaunch convex_plane_decomposition_ros convex_plane_decomposition.launch -``` - -### Run demo - -```bash -roslaunch convex_plane_decomposition_ros demo.launch -``` - -### Convex approximation demo - -A simple 2D demo the convex inner approximation is available: - -```bash -rosrun convex_plane_decomposition_ros convex_plane_decomposition_ros_TestShapeGrowing -``` - -### Parameters - -You can select input map topics, pipeline parameters etc. in the respective yaml file in - -```bash -convex_plane_decomposition_ros/config/ -``` - -Some other parameters are set through the launch files. diff --git a/plane_segmentation/cgal5_catkin/.gitignore b/plane_segmentation/cgal5_catkin/.gitignore deleted file mode 100644 index 259148fa..00000000 --- a/plane_segmentation/cgal5_catkin/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app diff --git a/plane_segmentation/cgal5_catkin/CMakeLists.txt b/plane_segmentation/cgal5_catkin/CMakeLists.txt deleted file mode 100644 index 75aa205a..00000000 --- a/plane_segmentation/cgal5_catkin/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -cmake_minimum_required(VERSION 3.14) -project(cgal5_catkin) - -find_package(catkin REQUIRED) - -include(ExternalProject) - -set(VERSION 5.3) - -file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/include) - -set(CGAL_VERSION 5.3) -ExternalProject_Add(cgal - URL https://github.com/CGAL/cgal/archive/refs/tags/v${CGAL_VERSION}.tar.gz - UPDATE_COMMAND "" - CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX=${CATKIN_DEVEL_PREFIX} - -DCMAKE_BUILD_TYPE:STRING=Release - BUILD_COMMAND $(MAKE) - INSTALL_COMMAND $(MAKE) install -) - -catkin_package( - INCLUDE_DIRS ${CATKIN_DEVEL_PREFIX}/include - CFG_EXTRAS cgal-extras.cmake -) - -install(DIRECTORY ${CATKIN_DEVEL_PREFIX}/include/CGAL/ - DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/CGAL/ -) - diff --git a/plane_segmentation/cgal5_catkin/README.md b/plane_segmentation/cgal5_catkin/README.md deleted file mode 100644 index af601fd7..00000000 --- a/plane_segmentation/cgal5_catkin/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cgal5_catkin - -Catkin wrapper of the Computational Geometry Algorithms Library (CGAL) diff --git a/plane_segmentation/cgal5_catkin/cmake/cgal-extras.cmake.in b/plane_segmentation/cgal5_catkin/cmake/cgal-extras.cmake.in deleted file mode 100644 index 3db7988c..00000000 --- a/plane_segmentation/cgal5_catkin/cmake/cgal-extras.cmake.in +++ /dev/null @@ -1,6 +0,0 @@ -# Makes CGAL/find___.cmake available -list(APPEND CMAKE_MODULE_PATH @CATKIN_DEVEL_PREFIX@/lib/cmake/CGAL) - -# Cpp standard version -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) \ No newline at end of file diff --git a/plane_segmentation/cgal5_catkin/package.xml b/plane_segmentation/cgal5_catkin/package.xml deleted file mode 100644 index 9c3cf37a..00000000 --- a/plane_segmentation/cgal5_catkin/package.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - cgal5_catkin - 5.0.2 - Catkin wrapper for CGAL 5. - Ruben Grandia - - See package - - catkin - libgmp-dev - libmpfr-dev - diff --git a/plane_segmentation/convex_plane_decomposition/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition/CMakeLists.txt deleted file mode 100644 index 2deb335a..00000000 --- a/plane_segmentation/convex_plane_decomposition/CMakeLists.txt +++ /dev/null @@ -1,114 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(convex_plane_decomposition) - -# Catkin dependencies -set(CATKIN_PACKAGE_DEPENDENCIES - cgal5_catkin - grid_map_core - grid_map_cv - grid_map_filters_rsl -) - -find_package(catkin REQUIRED COMPONENTS - ${CATKIN_PACKAGE_DEPENDENCIES} -) - -# CGAL dependencies (QUIET because they cannot be found by Clion) -find_package(GMP 4.2 QUIET) -find_package(MPFR 2.2.1 QUIET) -find_package(Boost 1.57 QUIET) - -# OpenCv -find_package(OpenCV REQUIRED) - -# Eigen -find_package(Eigen3 3.3 REQUIRED NO_MODULE) - -# Cpp standard version -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -################################### -## catkin specific configuration ## -################################### -catkin_package( - INCLUDE_DIRS - include - ${EIGEN3_INCLUDE_DIRS} - LIBRARIES - ${PROJECT_NAME} - CATKIN_DEPENDS - ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS - OpenCV GMP MPFR Boost -) - -########### -## Build ## -########### - -include_directories( - include - ${catkin_INCLUDE_DIRS} - ${EIGEN3_INCLUDE_DIR} -) - -add_library(${PROJECT_NAME} - src/contour_extraction/ContourExtraction.cpp - src/contour_extraction/Upsampling.cpp - src/ransac/RansacPlaneExtractor.cpp - src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp - src/ConvexRegionGrowing.cpp - src/Draw.cpp - src/GridMapPreprocessing.cpp - src/LoadGridmapFromImage.cpp - src/PlanarRegion.cpp - src/PlaneDecompositionPipeline.cpp - src/Postprocessing.cpp - src/SegmentedPlaneProjection.cpp -) -add_dependencies(${PROJECT_NAME} - ${catkin_EXPORTED_TARGETS} -) -target_link_libraries(${PROJECT_NAME} - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - gmp - mpfr -) -target_compile_options(${PROJECT_NAME} - PUBLIC -DCGAL_HAS_THREADS -) - -############# -## Install ## -############# - -install(TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -) -install(DIRECTORY include/${PROJECT_NAME}/ - DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} -) - -############# -## Testing ## -############# - -catkin_add_gtest(test_${PROJECT_NAME} - test/testConvexApproximation.cpp - test/testPipeline.cpp - test/testPlanarRegion.cpp - test/testRegionGrowing.cpp - test/testUpsampling.cpp -) -target_link_libraries(test_${PROJECT_NAME} - ${PROJECT_NAME} - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - gmp - mpfr - gtest_main -) diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h deleted file mode 100644 index a760ecd7..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ConvexRegionGrowing.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// Created by rgrandia on 09.06.20. -// - -#pragma once - -#include "PolygonTypes.h" - -namespace convex_plane_decomposition { - -CgalPolygon2d createRegularPolygon(const CgalPoint2d& center, double radius, int numberOfVertices); - -CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygon2d& parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor); - -CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygonWithHoles2d& parentShape, CgalPoint2d center, int numberOfVertices, - double growthFactor); - -void updateMean(CgalPoint2d& mean, const CgalPoint2d& oldValue, const CgalPoint2d& updatedValue, int N); - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h deleted file mode 100644 index 07de3c16..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Draw.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Created by rgrandia on 09.06.20. -// - -#pragma once - -#include -#include -#include -#include "opencv2/imgproc/imgproc.hpp" - -#include "PolygonTypes.h" - -namespace convex_plane_decomposition { - -cv::Vec3b randomColor(); - -std::vector toCv(const CgalPolygon2d& polygon); - -void drawContour(cv::Mat& img, const CgalPoint2d& point, double radius = 1, const cv::Vec3b* color = nullptr); -void drawContour(cv::Mat& img, const CgalPolygon2d& polygon, const cv::Vec3b* color = nullptr); -void drawContour(cv::Mat& img, const CgalPolygonWithHoles2d& polygonWithHoles2d, const cv::Vec3b* color = nullptr); - -CgalPolygon2d scaleShape(const CgalPolygon2d& polygon, double scale); -CgalPolygonWithHoles2d scaleShape(const CgalPolygonWithHoles2d& polygonWithHoles, double scale); - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h deleted file mode 100644 index bd7c849d..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GeometryUtils.h +++ /dev/null @@ -1,140 +0,0 @@ -// -// Created by rgrandia on 09.06.20. -// - -#pragma once - -#include "PlanarRegion.h" -#include "PolygonTypes.h" - -namespace convex_plane_decomposition { - -inline bool doEdgesIntersect(const CgalSegment2d& line, const CgalPolygon2d& contour) { - for (auto edgeIt = contour.edges_begin(); edgeIt != contour.edges_end(); ++edgeIt) { - if (CGAL::do_intersect(line, *edgeIt)) { - return true; - } - } - return false; -} - -inline bool doEdgesIntersect(const CgalSegment2d& line, const CgalPolygonWithHoles2d& parentShape) { - if (doEdgesIntersect(line, parentShape.outer_boundary())) { - return true; - } else { - for (const auto& hole : parentShape.holes()) { - if (doEdgesIntersect(line, hole)) { - return true; - } - } - } - return false; -} - -inline double squaredDistance(const CgalPoint2d& point, const CgalPolygon2d& polygon) { - double minDistSquared = std::numeric_limits::max(); - for (auto edgeIt = polygon.edges_begin(); edgeIt != polygon.edges_end(); ++edgeIt) { - double distSquare = CGAL::squared_distance(point, *edgeIt); - minDistSquared = std::min(distSquare, minDistSquared); - } - return minDistSquared; -} - -inline double squaredDistance(const CgalPoint2d& point, const CgalPolygonWithHoles2d& parentShape) { - double minDistSquared = squaredDistance(point, parentShape.outer_boundary()); - for (const auto& hole : parentShape.holes()) { - double distSquare = squaredDistance(point, hole); - minDistSquared = std::min(distSquare, minDistSquared); - } - return minDistSquared; -} - -inline double squaredDistance(const CgalPoint2d& point, const CgalCircle2d& circle) { - auto dx = (point.x() - circle.center().x()); - auto dy = (point.y() - circle.center().y()); - return dx * dx + dy * dy; -} - -template -double distance(const CgalPoint2d& point, const T& shape) { - double distanceSquared = squaredDistance(point, shape); - return (distanceSquared > 0.0) ? std::sqrt(distanceSquared) : 0.0; -} - -inline bool isInside(const CgalPoint2d& point, const CgalCircle2d& circle) { - return squaredDistance(point, circle) <= circle.squared_radius(); -} - -inline bool isInside(const CgalPoint2d& point, const CgalPolygon2d& polygon) { - const auto boundedSide = CGAL::bounded_side_2(polygon.begin(), polygon.end(), point); - return boundedSide == CGAL::ON_BOUNDED_SIDE || boundedSide == CGAL::ON_BOUNDARY; -} - -inline bool isInside(const CgalPoint2d& point, const CgalPolygonWithHoles2d& polygonWithHoles) { - if (isInside(point, polygonWithHoles.outer_boundary())) { - // Inside the outer contour -> return false if the point is inside any of the holes - for (const auto& hole : polygonWithHoles.holes()) { - const auto boundedSide = CGAL::bounded_side_2(hole.begin(), hole.end(), point); - if (boundedSide == CGAL::ON_BOUNDED_SIDE) { // The edge of the hole is considered part of the polygon - return false; - } - } - return true; - } else { - return false; - } -} - -inline CgalPoint2d getPointOnLine(const CgalPoint2d& start, const CgalPoint2d& end, double factor) { - return {factor * (end.x() - start.x()) + start.x(), factor * (end.y() - start.y()) + start.y()}; -} - -inline CgalPoint2d projectToClosestPoint(const CgalPoint2d& point, const CgalSegment2d& segment) { - // The segment as a vector, with the source being the origin - const Eigen::Vector2d sourceToTarget{segment.target().x() - segment.source().x(), segment.target().y() - segment.source().y()}; - const double sourceToTargetDistance = sourceToTarget.norm(); - const Eigen::Vector2d n = sourceToTarget / sourceToTargetDistance; - - // Vector from source to the query point - const Eigen::Vector2d sourceToPoint{point.x() - segment.source().x(), point.y() - segment.source().y()}; - - // Projection to the line, clamped to be between source and target points - const double coeff = std::min(std::max(0.0, n.dot(sourceToPoint)), sourceToTargetDistance); - - return {coeff * n.x() + segment.source().x(), coeff * n.y() + segment.source().y()}; -} - -inline CgalPoint2d projectToClosestPoint(const CgalPoint2d& point, const CgalPolygon2d& polygon) { - double minDistSquared = CGAL::squared_distance(point, *polygon.edges_begin()); - auto closestEdge = polygon.edges_begin(); - for (auto edgeIt = std::next(polygon.edges_begin()); edgeIt != polygon.edges_end(); ++edgeIt) { - double distSquare = CGAL::squared_distance(point, *edgeIt); - if (distSquare < minDistSquared) { - closestEdge = edgeIt; - minDistSquared = distSquare; - } - } - return projectToClosestPoint(point, *closestEdge); -} - -inline void transformInPlace(CgalPolygon2d& polygon, const std::function& f) { - for (auto& point : polygon) { - f(point); - } -} - -inline void transformInPlace(CgalPolygonWithHoles2d& polygonWithHoles, const std::function& f) { - transformInPlace(polygonWithHoles.outer_boundary(), f); - for (auto& hole : polygonWithHoles.holes()) { - transformInPlace(hole, f); - } -} - -inline void transformInPlace(BoundaryWithInset& boundaryWithInset, const std::function& f) { - transformInPlace(boundaryWithInset.boundary, f); - for (auto& inset : boundaryWithInset.insets) { - transformInPlace(inset, f); - } -} - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h deleted file mode 100644 index ebd34b0f..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/GridMapPreprocessing.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include - -#include - -namespace convex_plane_decomposition { - -struct PreprocessingParameters { - /// Resample to this resolution, set to negative values to skip - double resolution = 0.04; - /// Kernel size of the median filter, either 3 or 5 - int kernelSize = 3; - /// Number of times the image is filtered - int numberOfRepeats = 2; -}; - -class GridMapPreprocessing { - public: - GridMapPreprocessing(const PreprocessingParameters& parameters); - - void preprocess(grid_map::GridMap& gridMap, const std::string& layer) const; - - private: - void denoise(grid_map::GridMap& gridMap, const std::string& layer) const; - void changeResolution(grid_map::GridMap& gridMap, const std::string& layer) const; - void inpaint(grid_map::GridMap& gridMap, const std::string& layer) const; - - PreprocessingParameters parameters_; -}; - -/** - * @return true if any of the elements in the map are finite - */ -bool containsFiniteValue(const grid_map::Matrix& map); - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/LoadGridmapFromImage.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/LoadGridmapFromImage.h deleted file mode 100644 index 1b8f117a..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/LoadGridmapFromImage.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Created by rgrandia on 16.03.22. -// - -#pragma once - -#include - -#include - -namespace convex_plane_decomposition { - -/** - * Load an elevation map from a grey scale image. - * - * @param filePath : absolute path to file - * @param elevationLayer : name of the elevation layer - * @param frameId : frame assigned to loaded map - * @param resolution : map resolution [m/pixel] - * @param scale : distance [m] between lowest and highest point in the map - * @return Gridmap with the loaded image as elevation layer. - */ -grid_map::GridMap loadGridmapFromImage(const std::string& filePath, const std::string& elevationLayer, const std::string& frameId, - double resolution, double scale); - -} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h deleted file mode 100644 index 5e90ac00..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlanarRegion.h +++ /dev/null @@ -1,66 +0,0 @@ -// -// Created by rgrandia on 10.06.20. -// - -#pragma once - -#include -#include - -#include - -#include "PolygonTypes.h" - -namespace convex_plane_decomposition { - -struct NormalAndPosition { - /// 3D position. - Eigen::Vector3d position; - - /// Surface normal. - Eigen::Vector3d normal; -}; - -struct BoundaryWithInset { - /// Boundary of the planar region. - CgalPolygonWithHoles2d boundary; - - /// Encodes an inward offset to the boundary. - std::vector insets; -}; - -struct PlanarRegion { - /// All 2d points are in the terrain frame - BoundaryWithInset boundaryWithInset; - - /// 2D bounding box in terrain frame containing all the boundary points - CgalBbox2d bbox2d; - - /// 3D Transformation from terrain to world. v_world = T * v_plane. Use .linear() for the rotation and .translation() for the translation - Eigen::Isometry3d transformPlaneToWorld; -}; - -struct PlanarTerrain { - std::vector planarRegions; - grid_map::GridMap gridMap; -}; - -/** - * Convert a position and normal the a transform from the induced local frame to the global frame. - * - * For example, if the normal and position are defined in world. We return a transform T, such that v_world = T * v_plane. - * The normal will be taken as the z-direction of the local frame. The x and y direction are arbitrary. - */ -Eigen::Isometry3d getTransformLocalToGlobal(const NormalAndPosition& normalAndPosition); - -/** - * Project a 2D point in world along gravity to obtain a 2D point in the plane - */ -CgalPoint2d projectToPlaneAlongGravity(const CgalPoint2d& worldFrameXY, const Eigen::Isometry3d& transformPlaneToWorld); - -/** - * Transforms a point on the plane to a 3D position expressed in the world frame - */ -Eigen::Vector3d positionInWorldFrameFromPosition2dInPlane(const CgalPoint2d& planeXY, const Eigen::Isometry3d& transformPlaneToWorld); - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h deleted file mode 100644 index 78fc52e0..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PlaneDecompositionPipeline.h +++ /dev/null @@ -1,77 +0,0 @@ -// -// Created by rgrandia on 16.03.22. -// - -#pragma once - -#include "convex_plane_decomposition/GridMapPreprocessing.h" -#include "convex_plane_decomposition/PlanarRegion.h" -#include "convex_plane_decomposition/Postprocessing.h" -#include "convex_plane_decomposition/Timer.h" -#include "convex_plane_decomposition/contour_extraction/ContourExtraction.h" -#include "convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h" - -namespace convex_plane_decomposition { - -/** - * Encloses the full plane decomposition pipeline: - * - * Input: - * - Elevation map - * Output: - * - Planar terrain (planes + filtered elevation map) - * - Segmented elevation map - */ -class PlaneDecompositionPipeline { - public: - /** Collection of all parameters of steps in the pipeline */ - struct Config { - PreprocessingParameters preprocessingParameters; - sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters slidingWindowPlaneExtractorParameters; - ransac_plane_extractor::RansacPlaneExtractorParameters ransacPlaneExtractorParameters; - contour_extraction::ContourExtractionParameters contourExtractionParameters; - PostprocessingParameters postprocessingParameters; - }; - - /** - * Constructor - * @param config : configuration containing all parameters of the pipeline - */ - PlaneDecompositionPipeline(const Config& config); - - /** - * Trigger update of the pipeline - * @param gridMap : gridmap to process. Will be modified and added to the resulting planar terrain. - * @param elevationLayer : Name of the elevation layer. - */ - void update(grid_map::GridMap&& gridMap, const std::string& elevationLayer); - - /// Access to the Pipeline result. - PlanarTerrain& getPlanarTerrain() { return planarTerrain_; } - - /// Fills in the resulting segmentation into a gridmap layer data. - void getSegmentation(grid_map::GridMap::Matrix& segmentation) const; - - // Timers - const Timer& getPrepocessTimer() const { return preprocessTimer_; } - const Timer& getSlidingWindowTimer() const { return slidingWindowTimer_; } - const Timer& getContourExtractionTimer() const { return contourExtractionTimer_; } - const Timer& getPostprocessTimer() const { return postprocessTimer_; } - - private: - PlanarTerrain planarTerrain_; - - // Pipeline - GridMapPreprocessing preprocessing_; - sliding_window_plane_extractor::SlidingWindowPlaneExtractor slidingWindowPlaneExtractor_; - contour_extraction::ContourExtraction contourExtraction_; - Postprocessing postprocessing_; - - // Timing - Timer preprocessTimer_; - Timer slidingWindowTimer_; - Timer contourExtractionTimer_; - Timer postprocessTimer_; -}; - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h deleted file mode 100644 index 40fe764f..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/PolygonTypes.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// Created by rgrandia on 07.06.20. -// - -#pragma once - -#include -#include -#include - -namespace convex_plane_decomposition { - -using K = CGAL::Exact_predicates_inexact_constructions_kernel; -using CgalPoint2d = K::Point_2; -using CgalCircle2d = K::Circle_2; -using CgalPolygon2d = CGAL::Polygon_2; -using CgalSegment2d = CgalPolygon2d::Segment_2; -using CgalPolygonWithHoles2d = CGAL::Polygon_with_holes_2; -using CgalBbox2d = CGAL::Bbox_2; - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h deleted file mode 100644 index 12b85323..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Postprocessing.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "convex_plane_decomposition/PlanarRegion.h" - -namespace convex_plane_decomposition { - -struct PostprocessingParameters { - /// Added offset in z direction to compensate for the location of the foot frame w.r.t. the elevation map - double extracted_planes_height_offset = 0.0; - - /// Added offset in z direction added in cells that are not traversable - double nonplanar_height_offset = 0.02; - - /// Size of the kernel creating the boundary offset. In number of pixels. - int nonplanar_horizontal_offset = 1; - - /// Half the width of the dilation used before the smooth layer [m] - double smoothing_dilation_size = 0.2; - - /// Half the width of the box kernel used for the smooth layer [m] - double smoothing_box_kernel_size = 0.1; - - /// Half the width of the Gaussian kernel used for the smooth layer [m] - double smoothing_gauss_kernel_size = 0.05; -}; - -class Postprocessing { - public: - Postprocessing(const PostprocessingParameters& parameters); - - /** - * @param planarTerrain - * @param elevationLayer : name of the elevation layer - * @param planeSegmentationLayer : name of the planarity layer with planar = 1.0, non-planar = 0.0 - */ - void postprocess(PlanarTerrain& planarTerrain, const std::string& elevationLayer, const std::string& planeSegmentationLayer) const; - - private: - void dilationInNonplanarRegions(Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const; - void addHeightOffset(Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const; - void addHeightOffset(std::vector& planarRegions) const; - void addSmoothLayer(grid_map::GridMap& gridMap, const Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const; - - PostprocessingParameters parameters_; -}; - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlaneProjection.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlaneProjection.h deleted file mode 100644 index a48f2236..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlaneProjection.h +++ /dev/null @@ -1,77 +0,0 @@ -// -// Created by rgrandia on 12.10.21. -// - -#pragma once - -#include - -#include -#include - -namespace convex_plane_decomposition { - -/** - * Projects a point in the plane to the closest point on the contour of a planar region. We take the inset (slight inward offset from the - * boundary) as the contour to project to. - * @param queryProjectedToPlane : 2D point in the frame of the planar regions - * @param planarRegion : planar region to project to - * @return projected 2D point in the frame of the planar regions - */ -CgalPoint2d projectToPlanarRegion(const CgalPoint2d& queryProjectedToPlane, const PlanarRegion& planarRegion); - -/** - * Sorting information as an intermediate step to find the best plane projection - */ -struct RegionSortingInfo { - const PlanarRegion* regionPtr{nullptr}; - CgalPoint2d positionInTerrainFrame{0.0, 0.0}; - double boundingBoxSquareDistance{0.0}; -}; - -/** - * Compute sorting info and sort according to the bounding box distances. - * - * @param positionInWorld : Query point in world frame - * @param planarRegions : Candidate planar regions - * @return RegionSortingInfo, sorted according to the bounding box distance - */ -std::vector sortWithBoundingBoxes(const Eigen::Vector3d& positionInWorld, - const std::vector& planarRegions); - -struct PlanarTerrainProjection { - EIGEN_MAKE_ALIGNED_OPERATOR_NEW - - /// Selected region - const PlanarRegion* regionPtr{nullptr}; - - /// Projected point in terrain frame of the selected region - CgalPoint2d positionInTerrainFrame{0.0, 0.0}; - - /// Projected point in world frame - Eigen::Vector3d positionInWorld{0.0, 0.0, 0.0}; - - /// Projection cost, see getBestPlanarRegionAtPositionInWorld - double cost{0.0}; -}; - -/** - * This function considers the projection of a 3D query point to a set of candidate regions. - * - * The "best" region is picked according to the following cost: - * cost = |p - p_projected|^2 + penaltyFunction(p_projected), - * where p is the query point, and p_projected is the Euclidean projection to the candidate region, both in world frame. - * - * The bounding box of each region is used to find a lower bound on this cost, it is therefore important the user defined penalty is - * non-negative. - * - * @param positionInWorld : Query point in world frame - * @param planarRegions : Candidate planar regions - * @param penaltyFunction : a non-negative (!) scoring function. - * @return Projection and information - */ -PlanarTerrainProjection getBestPlanarRegionAtPositionInWorld(const Eigen::Vector3d& positionInWorld, - const std::vector& planarRegions, - const std::function& penaltyFunction); - -} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h deleted file mode 100644 index f5576239..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/SegmentedPlanesMap.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// Created by rgrandia on 10.06.20. -// - -#pragma once - -#include -#include - -#include "PlanarRegion.h" - -namespace convex_plane_decomposition { - -struct SegmentedPlanesMap { - /// Unordered collection of all labels and corresponding plane parameters - std::vector> labelPlaneParameters; - - /// Image with a each pixel being assigned and integer value corresponding to the label. Might contain labels that are not in - /// labelPlaneParameters. These labels should be seen as background. - cv::Mat labeledImage; - - /// Size of each pixel [m] - double resolution; - - /// World X-Y position [m] of the (0, 0) pixel in the image. - Eigen::Vector2d mapOrigin; - - /// All label values are smaller than or equal to highestLabel - int highestLabel; -}; - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Timer.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Timer.h deleted file mode 100644 index 3eaa93e6..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/Timer.h +++ /dev/null @@ -1,82 +0,0 @@ -// -// Created by rgrandia on 15.03.22. -// - -#pragma once - -namespace convex_plane_decomposition { - -/** - * Timer class that can be repeatedly started and stopped. Statistics are collected for all measured intervals . - * - * Taken and adapted from ocs2_core - */ -class Timer { - public: - Timer() - : numTimedIntervals_(0), - totalTime_(std::chrono::nanoseconds::zero()), - maxIntervalTime_(std::chrono::nanoseconds::zero()), - lastIntervalTime_(std::chrono::nanoseconds::zero()), - startTime_(std::chrono::steady_clock::now()) {} - - /** - * Reset the timer statistics - */ - void reset() { - totalTime_ = std::chrono::nanoseconds::zero(); - maxIntervalTime_ = std::chrono::nanoseconds::zero(); - lastIntervalTime_ = std::chrono::nanoseconds::zero(); - numTimedIntervals_ = 0; - } - - /** - * Start timing an interval - */ - void startTimer() { startTime_ = std::chrono::steady_clock::now(); } - - /** - * Stop timing of an interval - */ - void endTimer() { - auto endTime = std::chrono::steady_clock::now(); - lastIntervalTime_ = std::chrono::duration_cast(endTime - startTime_); - maxIntervalTime_ = std::max(maxIntervalTime_, lastIntervalTime_); - totalTime_ += lastIntervalTime_; - numTimedIntervals_++; - }; - - /** - * @return Number of intervals that were timed - */ - int getNumTimedIntervals() const { return numTimedIntervals_; } - - /** - * @return Total cumulative time of timed intervals - */ - double getTotalInMilliseconds() const { return std::chrono::duration(totalTime_).count(); } - - /** - * @return Maximum duration of a single interval - */ - double getMaxIntervalInMilliseconds() const { return std::chrono::duration(maxIntervalTime_).count(); } - - /** - * @return Duration of the last timed interval - */ - double getLastIntervalInMilliseconds() const { return std::chrono::duration(lastIntervalTime_).count(); } - - /** - * @return Average duration of all timed intervals - */ - double getAverageInMilliseconds() const { return getTotalInMilliseconds() / numTimedIntervals_; } - - private: - int numTimedIntervals_; - std::chrono::nanoseconds totalTime_; - std::chrono::nanoseconds maxIntervalTime_; - std::chrono::nanoseconds lastIntervalTime_; - std::chrono::steady_clock::time_point startTime_; -}; - -} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h deleted file mode 100644 index 1c0cbe90..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtraction.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// Created by rgrandia on 04.06.20. -// - -#pragma once - -#include - -#include "convex_plane_decomposition/PlanarRegion.h" -#include "convex_plane_decomposition/PolygonTypes.h" -#include "convex_plane_decomposition/SegmentedPlanesMap.h" - -#include "ContourExtractionParameters.h" - -namespace convex_plane_decomposition { -namespace contour_extraction { - -/** - * Extracts the contours in map resolution, but with the x and y axis flipped. - * This way all contours are in counter clockwise direction. - */ -class ContourExtraction { - public: - ContourExtraction(const ContourExtractionParameters& parameters); - - std::vector extractPlanarRegions(const SegmentedPlanesMap& segmentedPlanesMap); - - private: - ContourExtractionParameters parameters_; - cv::Mat insetKernel_; - cv::Mat marginKernel_; - - // Memory to reuse between calls - cv::Mat binaryImage_; -}; - -/// Modifies the image in-place! -std::vector extractBoundaryAndInset(cv::Mat& binary_image, const cv::Mat& erosionKernel); - -std::vector extractPolygonsFromBinaryImage(const cv::Mat& binary_image); - -CgalPolygon2d cgalPolygonFromOpenCv(const std::vector& openCvPolygon); - -CgalPoint2d pixelToWorldFrame(const CgalPoint2d& pixelspaceCgalPoint2d, double resolution, const Eigen::Vector2d& mapOffset); - -} // namespace contour_extraction -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h deleted file mode 100644 index 009bc37e..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/ContourExtractionParameters.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// Created by rgrandia on 07.06.20. -// - -#pragma once - -namespace convex_plane_decomposition { -namespace contour_extraction { - -struct ContourExtractionParameters { - /// Size of the kernel creating the boundary offset. In number of (sub) pixels. - int marginSize = 1; -}; - -} // namespace contour_extraction -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/Upsampling.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/Upsampling.h deleted file mode 100644 index 0f80223b..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/contour_extraction/Upsampling.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// Created by rgrandia on 26.10.21. -// - -#pragma once - -#include "convex_plane_decomposition/SegmentedPlanesMap.h" - -namespace convex_plane_decomposition { -namespace contour_extraction { - -/** - * Upsamples an image such that all pixels are turned into 9 pixels, with the original pixel in the middle. - * Around the edges, each pixel is only upsamples in the inward direction. - * - * @param image : source image - * @return upsamples image - */ -cv::Mat upSample(const cv::Mat& image); - -/** - * Upsamples a segmented terrain such that the resulting terrain has 1/3 of the input resolution. (Each cell is split into 9 cells) - * This specific upsampling ratio makes it possible to keep labels in their exact original location in world frame. - * - * @param mapIn : source terrain - * @return upsampled terrain - */ -SegmentedPlanesMap upSample(const SegmentedPlanesMap& mapIn); - -} // namespace contour_extraction -} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp deleted file mode 100644 index ca76b89d..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include - -#include - -#include -#include -#include -#include - -#include "RansacPlaneExtractorParameters.h" - -namespace ransac_plane_extractor { - -// Point with normal related type declarations. -using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; -using Point3D = Kernel::Point_3; -using Vector3D = Kernel::Vector_3; -using PointWithNormal = std::pair; -using PwnVector = std::vector; - -// RANSAC plane extractor related type declarations. -using PointMap = CGAL::First_of_pair_property_map; -using NormalMap = CGAL::Second_of_pair_property_map; -using Traits = CGAL::Shape_detection::Efficient_RANSAC_traits; -using EfficientRansac = CGAL::Shape_detection::Efficient_RANSAC; -using Plane = CGAL::Shape_detection::Plane; -using Shape = CGAL::Shape_detection::Shape_base; - -class RansacPlaneExtractor { - public: - RansacPlaneExtractor(const RansacPlaneExtractorParameters& parameters); - - void setParameters(const RansacPlaneExtractorParameters& parameters); - - void detectPlanes(std::vector& points_with_normal); - - /// Return {plane normal, support vector} for the detected shape - static std::pair getPlaneParameters(Shape* shapePtr); - - /// Returns an iterator range. Data is still in the ransac_object - EfficientRansac::Shape_range getDetectedPlanes() const { return ransac_.shapes(); }; - - /// Returns an iterator range. Data is still in the ransac_object - EfficientRansac::Point_index_range getUnassignedPointIndices() { return ransac_.indices_of_unassigned_points(); } - - private: - EfficientRansac ransac_; - EfficientRansac::Parameters cgalRansacParameters_; -}; - -} // namespace ransac_plane_extractor diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h deleted file mode 100644 index ef94c557..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/ransac/RansacPlaneExtractorParameters.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// Created by rgrandia on 07.06.20. -// - -#pragma once - -namespace ransac_plane_extractor { - -struct RansacPlaneExtractorParameters { - /// Set probability to miss the largest primitive at each iteration. - double probability = 0.01; - /// Detect shapes with at least N points. - double min_points = 4; - /// [m] Set maximum Euclidean distance between a point and a shape. - double epsilon = 0.025; - /// Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most - /// 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon - double cluster_epsilon = 0.08; - /// [deg] Set maximum normal deviation between cluster surface_normal and point normal. - double normal_threshold = 25.0; -}; - -} // namespace ransac_plane_extractor diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h deleted file mode 100644 index f60398ad..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once - -#include - -#include -#include - -#include "convex_plane_decomposition/SegmentedPlanesMap.h" -#include "convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp" - -#include "SlidingWindowPlaneExtractorParameters.h" - -namespace convex_plane_decomposition { -namespace sliding_window_plane_extractor { - -class SlidingWindowPlaneExtractor { - public: - SlidingWindowPlaneExtractor(const SlidingWindowPlaneExtractorParameters& parameters, - const ransac_plane_extractor::RansacPlaneExtractorParameters& ransacParameters); - - void runExtraction(const grid_map::GridMap& map, const std::string& layer_height); - - const SegmentedPlanesMap& getSegmentedPlanesMap() const { return segmentedPlanesMap_; } - - const cv::Mat& getBinaryLabeledImage() const { return binaryImagePatch_; } - - /** Can be run after extraction for debugging purpose */ - void addSurfaceNormalToMap(grid_map::GridMap& map, const std::string& layerPrefix) const; - - private: - bool isGloballyPlanar(const Eigen::Vector3d& normalVectorPlane, const Eigen::Vector3d& supportVectorPlane, - const std::vector& pointsWithNormal) const; - bool isWithinInclinationLimit(const Eigen::Vector3d& normalVectorPlane) const; - - std::pair computeNormalAndErrorForWindow(const Eigen::MatrixXf& windowData) const; - bool isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanSquaredError) const; - - int getLinearIndex(int row, int col) const { return row + col * mapRows_; }; - - void computePlaneParametersForLabel(int label, std::vector& pointsWithNormal); - void refineLabelWithRansac(int label, std::vector& pointsWithNormal); - - void extractPlaneParametersFromLabeledImage(); - - void runSegmentation(); - - void runSlidingWindowDetector(); - - void setToBackground(int label); - - SlidingWindowPlaneExtractorParameters parameters_; - ransac_plane_extractor::RansacPlaneExtractorParameters ransacParameters_; - - const grid_map::GridMap* map_; - std::string elevationLayer_; - int mapRows_; - - std::vector surfaceNormals_; - std::vector pointsWithNormal_; - - cv::Mat binaryImagePatch_; - SegmentedPlanesMap segmentedPlanesMap_; -}; -} // namespace sliding_window_plane_extractor -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h b/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h deleted file mode 100644 index 51009a4f..00000000 --- a/plane_segmentation/convex_plane_decomposition/include/convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractorParameters.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// Created by rgrandia on 07.06.20. -// - -#pragma once - -namespace convex_plane_decomposition { -namespace sliding_window_plane_extractor { - -struct SlidingWindowPlaneExtractorParameters { - /// Size of the sliding window patch used for normal vector calculation and planarity detection - /// Should be an odd number and at least 3. - int kernel_size = 3; - - /// [#] Apply opening filter (erosion -> dilation) to planarity detection by this amount of pixels - int planarity_opening_filter = 0; - - /// [-] Maximum allowed angle between the surface normal and the world-z direction for a patch (converted to dotproduct bound) - double plane_inclination_threshold = std::cos(30.0 * M_PI / 180.0); - - /// [-] Maximum allowed angle between the surface normal and the world-z direction for a cell (converted to dotproduct bound) - double local_plane_inclination_threshold = std::cos(35.0 * M_PI / 180.0); - - /// [m] The allowed root-mean-squared deviation from the plane fitted to the patch. Higher -> not planar - double plane_patch_error_threshold = 0.02; - - /// [#] Labels with less points assigned to them are discarded - int min_number_points_per_label = 4; - - /// Label kernel connectivity. 4 or 8 (cross or box) - int connectivity = 4; - - /// Enable RANSAC refinement if the plane is not globally fitting to the assigned points. - bool include_ransac_refinement = true; - - /// [m] Allowed maximum distance from a point to the plane. If any point violates this, RANSAC is triggered - double global_plane_fit_distance_error_threshold = 0.025; - - /// [deg] Allowed normal vector deviation for a point w.r.t. the plane normal. If any point violates this, RANSAC is triggered - double global_plane_fit_angle_error_threshold_degrees = 25.0; -}; - -} // namespace sliding_window_plane_extractor -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/package.xml b/plane_segmentation/convex_plane_decomposition/package.xml deleted file mode 100644 index 5ccbe03f..00000000 --- a/plane_segmentation/convex_plane_decomposition/package.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - convex_plane_decomposition - 0.0.0 - The convex_plane_decomposition package - - Ruben Grandia - - MIT - - catkin - cgal5_catkin - grid_map_core - grid_map_cv - grid_map_filters_rsl - - diff --git a/plane_segmentation/convex_plane_decomposition/src/ConvexRegionGrowing.cpp b/plane_segmentation/convex_plane_decomposition/src/ConvexRegionGrowing.cpp deleted file mode 100644 index 052a0c97..00000000 --- a/plane_segmentation/convex_plane_decomposition/src/ConvexRegionGrowing.cpp +++ /dev/null @@ -1,229 +0,0 @@ -// -// Created by rgrandia on 09.06.20. -// - -#include "convex_plane_decomposition/ConvexRegionGrowing.h" - -#include "convex_plane_decomposition/GeometryUtils.h" - -namespace convex_plane_decomposition { - -namespace { - -int getCounterClockWiseNeighbour(int i, int lastVertex) { - return (i > 0) ? i - 1 : lastVertex; -} - -int getClockWiseNeighbour(int i, int lastVertex) { - return (i < lastVertex) ? i + 1 : 0; -} - -std::array getNeighbours(const CgalPolygon2d& polygon, int i) { - assert(i < polygon.size()); - assert(polygon.size() > 1); - int lastVertex = static_cast(polygon.size()) - 1; - int cwNeighbour = getClockWiseNeighbour(i, lastVertex); - int ccwNeighbour = getCounterClockWiseNeighbour(i, lastVertex); - return {polygon.vertex(cwNeighbour), polygon.vertex(ccwNeighbour)}; -} - -std::array get2ndNeighbours(const CgalPolygon2d& polygon, int i) { - assert(i < polygon.size()); - assert(polygon.size() > 1); - int lastVertex = static_cast(polygon.size()) - 1; - int cwNeighbour1 = getClockWiseNeighbour(i, lastVertex); - int cwNeighbour2 = getClockWiseNeighbour(cwNeighbour1, lastVertex); - int ccwNeighbour1 = getCounterClockWiseNeighbour(i, lastVertex); - int ccwNeighbour2 = getCounterClockWiseNeighbour(ccwNeighbour1, lastVertex); - return {polygon.vertex(cwNeighbour2), polygon.vertex(cwNeighbour1), polygon.vertex(ccwNeighbour1), polygon.vertex(ccwNeighbour2)}; -} - -bool remainsConvexWhenMovingPoint(const CgalPolygon2d& polygon, int i, const CgalPoint2d& point) { - auto secondNeighbours = get2ndNeighbours(polygon, i); - using CgalPolygon2dFixedSize = CGAL::Polygon_2>; - - CgalPolygon2dFixedSize subPolygon; - subPolygon.container()[0] = secondNeighbours[0]; - subPolygon.container()[1] = secondNeighbours[1]; - subPolygon.container()[2] = point; - subPolygon.container()[3] = secondNeighbours[2]; - subPolygon.container()[4] = secondNeighbours[3]; - return subPolygon.is_convex(); -} - -bool pointAndNeighboursAreWithinFreeSphere(const std::array& neighbours, const CgalPoint2d& point, - const CgalCircle2d& circle) { - return isInside(neighbours[0], circle) && isInside(point, circle) && isInside(neighbours[1], circle); -} - -/** - * Returns {true, 0.0} if either one of the point -> neighbour segments intersects the parent shape - * Returns {false, minSquareDistance} if none of the segments intersects. minSquareDistance is the minimum square distance between the - * point and the parent shape - */ -template -std::pair doEdgesIntersectAndSquareDistance(const std::array& neighbours, const CgalPoint2d& point, - const T& parentShape); - -template <> -std::pair doEdgesIntersectAndSquareDistance(const std::array& neighbours, const CgalPoint2d& point, - const CgalPolygon2d& parentShape) { - CgalSegment2d segment0{neighbours[0], point}; - CgalSegment2d segment1{neighbours[1], point}; - - double minDistSquared = std::numeric_limits::max(); - for (auto edgeIt = parentShape.edges_begin(); edgeIt != parentShape.edges_end(); ++edgeIt) { - const auto edge = *edgeIt; - if (CGAL::do_intersect(segment0, edge) || CGAL::do_intersect(segment1, edge)) { - return {true, 0.0}; - } else { - minDistSquared = std::min(minDistSquared, CGAL::squared_distance(point, edge)); - } - } - - return {false, minDistSquared}; -} - -template <> -std::pair doEdgesIntersectAndSquareDistance(const std::array& neighbours, const CgalPoint2d& point, - const CgalPolygonWithHoles2d& parentShape) { - const auto intersectAndDistance = doEdgesIntersectAndSquareDistance(neighbours, point, parentShape.outer_boundary()); - if (intersectAndDistance.first) { - return {true, 0.0}; - } - - double minDistSquared = intersectAndDistance.second; - for (const auto& hole : parentShape.holes()) { - const auto holeIntersectAndDistance = doEdgesIntersectAndSquareDistance(neighbours, point, hole); - if (holeIntersectAndDistance.first) { - return {true, 0.0}; - } else { - minDistSquared = std::min(minDistSquared, holeIntersectAndDistance.second); - } - } - - return {false, minDistSquared}; -} - -template -bool pointCanBeMoved(const CgalPolygon2d& growthShape, int i, const CgalPoint2d& candidatePoint, CgalCircle2d& freeSphere, - const T& parentShape) { - if (remainsConvexWhenMovingPoint(growthShape, i, candidatePoint)) { - auto neighbours = getNeighbours(growthShape, i); - if (pointAndNeighboursAreWithinFreeSphere(neighbours, candidatePoint, freeSphere)) { - return true; - } else { - // Look for intersections and minimum distances simultaneously - const auto intersectAndDistance = doEdgesIntersectAndSquareDistance(neighbours, candidatePoint, parentShape); - - if (intersectAndDistance.first) { - return false; - } else { - // Update free sphere around new point - freeSphere = CgalCircle2d(candidatePoint, intersectAndDistance.second); - return true; - } - } - } else { - return false; - } -} - -inline std::ostream& operator<<(std::ostream& os, const CgalPolygon2d& p) { - os << "CgalPolygon2d: \n"; - for (auto it = p.vertices_begin(); it != p.vertices_end(); ++it) { - os << "\t(" << it->x() << ", " << it->y() << ")\n"; - } - return os; -} - -inline std::ostream& operator<<(std::ostream& os, const CgalPolygonWithHoles2d& p) { - os << "CgalPolygonWithHoles2d: \n"; - os << "\t" << p.outer_boundary() << "\n"; - os << "\tHoles: \n"; - for (auto it = p.holes_begin(); it != p.holes_end(); ++it) { - os << "\t\t" << *it << "\n"; - } - return os; -} - -template -CgalPolygon2d growConvexPolygonInsideShape_impl(const T& parentShape, CgalPoint2d center, int numberOfVertices, double growthFactor) { - const auto centerCopy = center; - constexpr double initialRadiusFactor = 0.999; - constexpr int maxIter = 1000; - double radius = initialRadiusFactor * distance(center, parentShape); - - CgalPolygon2d growthShape = createRegularPolygon(center, radius, numberOfVertices); - - if (radius == 0.0) { - std::cerr << "[growConvexPolygonInsideShape] Zero initial radius. Provide a point with a non-zero offset to the boundary.\n"; - return growthShape; - } - - // Cached values per vertex - std::vector blocked(numberOfVertices, false); - std::vector freeSpheres(numberOfVertices, CgalCircle2d(center, radius * radius)); - - int Nblocked = 0; - int iter = 0; - while (Nblocked < numberOfVertices && iter < maxIter) { - for (int i = 0; i < numberOfVertices; i++) { - if (!blocked[i]) { - const auto candidatePoint = getPointOnLine(center, growthShape.vertex(i), growthFactor); - if (pointCanBeMoved(growthShape, i, candidatePoint, freeSpheres[i], parentShape)) { - updateMean(center, growthShape.vertex(i), candidatePoint, numberOfVertices); - growthShape.vertex(i) = candidatePoint; - } else { - blocked[i] = true; - ++Nblocked; - } - } - } - ++iter; - } - - if (iter == maxIter) { - std::cerr << "[growConvexPolygonInsideShape] max iteration in region growing! Debug information: \n"; - std::cerr << "numberOfVertices: " << numberOfVertices << "\n"; - std::cerr << "growthFactor: " << growthFactor << "\n"; - std::cerr << "Center: " << centerCopy.x() << ", " << centerCopy.y() << "\n"; - std::cerr << parentShape << "\n"; - } - return growthShape; -} - -} // namespace - -CgalPolygon2d createRegularPolygon(const CgalPoint2d& center, double radius, int numberOfVertices) { - assert(numberOfVertices > 2); - CgalPolygon2d polygon; - polygon.container().reserve(numberOfVertices); - double angle = (2. * M_PI) / numberOfVertices; - for (int i = 0; i < numberOfVertices; ++i) { - double phi = i * angle; - double px = radius * std::cos(phi) + center.x(); - double py = radius * std::sin(phi) + center.y(); - // Counter clockwise - polygon.push_back({px, py}); - } - return polygon; -} - -CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygon2d& parentShape, CgalPoint2d center, int numberOfVertices, - double growthFactor) { - return growConvexPolygonInsideShape_impl(parentShape, center, numberOfVertices, growthFactor); -} - -CgalPolygon2d growConvexPolygonInsideShape(const CgalPolygonWithHoles2d& parentShape, CgalPoint2d center, int numberOfVertices, - double growthFactor) { - return growConvexPolygonInsideShape_impl(parentShape, center, numberOfVertices, growthFactor); -} - -void updateMean(CgalPoint2d& mean, const CgalPoint2d& oldValue, const CgalPoint2d& updatedValue, int N) { - // old_mean = 1/N * ( others + old_value); -> others = N*old_mean - old_value - // new_mean = 1/N * ( others + new_value); -> new_mean = old_mean - 1/N * oldValue + 1/N * updatedValue - mean += 1.0 / N * (updatedValue - oldValue); -} - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/src/Draw.cpp b/plane_segmentation/convex_plane_decomposition/src/Draw.cpp deleted file mode 100644 index 3c20b8c4..00000000 --- a/plane_segmentation/convex_plane_decomposition/src/Draw.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// -// Created by rgrandia on 09.06.20. -// - -#include "convex_plane_decomposition/Draw.h" - -namespace convex_plane_decomposition { - -cv::Vec3b randomColor() { - return cv::Vec3b((rand() & 255), (rand() & 255), (rand() & 255)); -} - -std::vector toCv(const CgalPolygon2d& polygon) { - std::vector contour; - contour.reserve(polygon.size()); - for (const auto& point : polygon) { - contour.emplace_back(point.x(), point.y()); - } - return contour; -} - -void drawContour(cv::Mat& img, const CgalPoint2d& point, double radius, const cv::Vec3b* color) { - const cv::Vec3b contourColor = (color == nullptr) ? randomColor() : *color; - cv::Point cvPoint(point.x(), point.y()); - cv::circle(img, cvPoint, radius, contourColor); -} - -void drawContour(cv::Mat& img, const CgalPolygon2d& polygon, const cv::Vec3b* color) { - const cv::Vec3b contourColor = (color == nullptr) ? randomColor() : *color; - std::vector> contours{toCv(polygon)}; - drawContours(img, contours, 0, contourColor); -} - -void drawContour(cv::Mat& img, const CgalPolygonWithHoles2d& polygonWithHoles2d, const cv::Vec3b* color) { - const cv::Vec3b contourColor = (color == nullptr) ? randomColor() : *color; - - drawContour(img, polygonWithHoles2d.outer_boundary(), &contourColor); - for (const auto& hole : polygonWithHoles2d.holes()) { - drawContour(img, hole, &contourColor); - } -} - -CgalPolygon2d scaleShape(const CgalPolygon2d& polygon, double scale) { - CgalPolygon2d scaledShape; - scaledShape.container().reserve(polygon.size()); - for (const auto& point : polygon) { - scaledShape.push_back({scale * point.x(), scale * point.y()}); - } - return scaledShape; -} -CgalPolygonWithHoles2d scaleShape(const CgalPolygonWithHoles2d& polygonWithHoles, double scale) { - CgalPolygonWithHoles2d scaledShape(scaleShape(polygonWithHoles.outer_boundary(), scale)); - - for (const auto& hole : polygonWithHoles.holes()) { - scaledShape.add_hole(scaleShape(hole, scale)); - } - return scaledShape; -} - -} \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/src/GridMapPreprocessing.cpp b/plane_segmentation/convex_plane_decomposition/src/GridMapPreprocessing.cpp deleted file mode 100644 index 265918e6..00000000 --- a/plane_segmentation/convex_plane_decomposition/src/GridMapPreprocessing.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "convex_plane_decomposition/GridMapPreprocessing.h" - -#include -#include -#include - -#include -#include - -namespace convex_plane_decomposition { - -GridMapPreprocessing::GridMapPreprocessing(const PreprocessingParameters& parameters) : parameters_(parameters) {} - -void GridMapPreprocessing::preprocess(grid_map::GridMap& gridMap, const std::string& layer) const { - inpaint(gridMap, layer); - denoise(gridMap, layer); - changeResolution(gridMap, layer); -} - -void GridMapPreprocessing::denoise(grid_map::GridMap& gridMap, const std::string& layer) const { - int kernelSize = std::max(1, std::min(parameters_.kernelSize, 5)); // must be 1, 3 or 5 for current image type, see doc of cv::medianBlur - grid_map::smoothing::median(gridMap, layer, layer, kernelSize, 0, parameters_.numberOfRepeats); -} - -void GridMapPreprocessing::changeResolution(grid_map::GridMap& gridMap, const std::string& layer) const { - bool hasSameResolution = std::abs(gridMap.getResolution() - parameters_.resolution) < 1e-6; - - if (parameters_.resolution > 0.0 && !hasSameResolution) { - grid_map::inpainting::resample(gridMap, layer, parameters_.resolution); - } -} - -void GridMapPreprocessing::inpaint(grid_map::GridMap& gridMap, const std::string& layer) const { - const std::string& layerOut = "tmp"; - grid_map::inpainting::minValues(gridMap, layer, layerOut); - - gridMap.get(layer) = std::move(gridMap.get(layerOut)); - gridMap.erase(layerOut); -} - -bool containsFiniteValue(const grid_map::Matrix& map) { - for (int col = 0; col < map.cols(); ++col) { - for (int row = 0; row < map.rows(); ++row) { - if (std::isfinite(map(col, row))) { - return true; - } - } - } - return false; -} - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/src/LoadGridmapFromImage.cpp b/plane_segmentation/convex_plane_decomposition/src/LoadGridmapFromImage.cpp deleted file mode 100644 index 2f1fc783..00000000 --- a/plane_segmentation/convex_plane_decomposition/src/LoadGridmapFromImage.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// -// Created by rgrandia on 16.03.22. -// - -#include "convex_plane_decomposition/LoadGridmapFromImage.h" - -#include -#include - -#include - -namespace convex_plane_decomposition { - -grid_map::GridMap loadGridmapFromImage(const std::string& filePath, const std::string& elevationLayer, const std::string& frameId, - double resolution, double scale) { - // Read the file - cv::Mat image; - image = cv::imread(filePath, cv::ImreadModes::IMREAD_GRAYSCALE); - - // Check for invalid input - if (!image.data) { - throw std::runtime_error("Could not open or find the image"); - } - - // Min max values - double minValue, maxValue; - cv::minMaxLoc(image, &minValue, &maxValue); - - grid_map::GridMap mapOut({elevationLayer}); - mapOut.setFrameId(frameId); - grid_map::GridMapCvConverter::initializeFromImage(image, resolution, mapOut, grid_map::Position(0.0, 0.0)); - grid_map::GridMapCvConverter::addLayerFromImage(image, elevationLayer, mapOut, float(0.0), float(scale), 0.5); - return mapOut; -} - -} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/src/PlanarRegion.cpp b/plane_segmentation/convex_plane_decomposition/src/PlanarRegion.cpp deleted file mode 100644 index f0aa09f6..00000000 --- a/plane_segmentation/convex_plane_decomposition/src/PlanarRegion.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "convex_plane_decomposition/PlanarRegion.h" - -namespace convex_plane_decomposition { - -Eigen::Isometry3d getTransformLocalToGlobal(const NormalAndPosition& normalAndPosition) { - const Eigen::Vector3d zAxisInGlobal = normalAndPosition.normal.normalized(); - const auto& positionInGlobal = normalAndPosition.position; - - // Cross with any vector that is not equal to surfaceNormal - Eigen::Vector3d yAxisInGlobal = zAxisInGlobal.cross(Eigen::Vector3d::UnitX()); - { // Normalize the yAxis. Need to pick a different direction if z happened to intersect with unitX - const auto ySquaredNorm = yAxisInGlobal.squaredNorm(); - const double crossTolerance = 1e-3; - if (ySquaredNorm > crossTolerance) { - yAxisInGlobal /= std::sqrt(ySquaredNorm); - } else { - // normal was almost equal to unitX. Pick the y-axis in a different way (approximately equal to unitY): - yAxisInGlobal = zAxisInGlobal.cross(Eigen::Vector3d::UnitY().cross(zAxisInGlobal)).normalized(); - } - } - - Eigen::Isometry3d transform; - transform.linear().col(0) = yAxisInGlobal.cross(zAxisInGlobal); - transform.linear().col(1) = yAxisInGlobal; - transform.linear().col(2) = zAxisInGlobal; - transform.translation() = positionInGlobal; - - return transform; -} - -CgalPoint2d projectToPlaneAlongGravity(const CgalPoint2d& worldFrameXY, const Eigen::Isometry3d& transformPlaneToWorld) { - // Shorthands - const auto& xAxis = transformPlaneToWorld.linear().col(0); - const auto& yAxis = transformPlaneToWorld.linear().col(1); - const auto& surfaceNormalInWorld = transformPlaneToWorld.linear().col(2); - const auto& planeOriginInWorld = transformPlaneToWorld.translation(); - - // Horizontal difference - const double dx = worldFrameXY.x() - planeOriginInWorld.x(); - const double dy = worldFrameXY.y() - planeOriginInWorld.y(); - - // Vertical difference - // solve surfaceNormalInWorld.dot(projectedPosition - planeOriginInWorld) = 0 - // with projectPosition XY = worldFrameXY; - Eigen::Vector3d planeOriginToProjectedPointInWorld( - dx, dy, (-dx * surfaceNormalInWorld.x() - dy * surfaceNormalInWorld.y()) / surfaceNormalInWorld.z()); - - // Project XY coordinates to the plane frame - return {xAxis.dot(planeOriginToProjectedPointInWorld), yAxis.dot(planeOriginToProjectedPointInWorld)}; -} - -Eigen::Vector3d positionInWorldFrameFromPosition2dInPlane(const CgalPoint2d& planeXY, const Eigen::Isometry3d& transformPlaneToWorld) { - // Compute transform given that z in plane = 0.0 - Eigen::Vector3d pointInWorld = transformPlaneToWorld.translation() + planeXY.x() * transformPlaneToWorld.linear().col(0) + - planeXY.y() * transformPlaneToWorld.linear().col(1); - return pointInWorld; -} - -} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/src/PlaneDecompositionPipeline.cpp b/plane_segmentation/convex_plane_decomposition/src/PlaneDecompositionPipeline.cpp deleted file mode 100644 index 573fc580..00000000 --- a/plane_segmentation/convex_plane_decomposition/src/PlaneDecompositionPipeline.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "convex_plane_decomposition/PlaneDecompositionPipeline.h" - -#include - -namespace convex_plane_decomposition { - -PlaneDecompositionPipeline::PlaneDecompositionPipeline(const Config& config) - : preprocessing_(config.preprocessingParameters), - slidingWindowPlaneExtractor_(config.slidingWindowPlaneExtractorParameters, config.ransacPlaneExtractorParameters), - contourExtraction_(config.contourExtractionParameters), - postprocessing_(config.postprocessingParameters) {} - -void PlaneDecompositionPipeline::update(grid_map::GridMap&& gridMap, const std::string& elevationLayer) { - // Clear / Overwrite old result - planarTerrain_.planarRegions.clear(); - planarTerrain_.gridMap = std::move(gridMap); - - preprocessTimer_.startTimer(); - preprocessing_.preprocess(planarTerrain_.gridMap, elevationLayer); - preprocessTimer_.endTimer(); - - slidingWindowTimer_.startTimer(); - slidingWindowPlaneExtractor_.runExtraction(planarTerrain_.gridMap, elevationLayer); - slidingWindowTimer_.endTimer(); - - contourExtractionTimer_.startTimer(); - planarTerrain_.planarRegions = contourExtraction_.extractPlanarRegions(slidingWindowPlaneExtractor_.getSegmentedPlanesMap()); - contourExtractionTimer_.endTimer(); - - postprocessTimer_.startTimer(); - // Add binary map - const std::string planeClassificationLayer{"plane_classification"}; - planarTerrain_.gridMap.add(planeClassificationLayer); - auto& traversabilityMask = planarTerrain_.gridMap.get(planeClassificationLayer); - cv::cv2eigen(slidingWindowPlaneExtractor_.getBinaryLabeledImage(), traversabilityMask); - - postprocessing_.postprocess(planarTerrain_, elevationLayer, planeClassificationLayer); - postprocessTimer_.endTimer(); -} - -void PlaneDecompositionPipeline::getSegmentation(grid_map::GridMap::Matrix& segmentation) const { - cv::cv2eigen(slidingWindowPlaneExtractor_.getSegmentedPlanesMap().labeledImage, segmentation); -} - -} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/src/Postprocessing.cpp b/plane_segmentation/convex_plane_decomposition/src/Postprocessing.cpp deleted file mode 100644 index 4b07aadf..00000000 --- a/plane_segmentation/convex_plane_decomposition/src/Postprocessing.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include "convex_plane_decomposition/Postprocessing.h" - -#include -#include -#include - -#include -#include - -namespace convex_plane_decomposition { - -Postprocessing::Postprocessing(const PostprocessingParameters& parameters) : parameters_(parameters) {} - -void Postprocessing::postprocess(PlanarTerrain& planarTerrain, const std::string& elevationLayer, - const std::string& planeSegmentationLayer) const { - auto& elevationData = planarTerrain.gridMap.get(elevationLayer); - const auto& planarityMask = planarTerrain.gridMap.get(planeSegmentationLayer); - - // Store the unaltered map - planarTerrain.gridMap.add(elevationLayer + "_before_postprocess", elevationData); - - // post process planar regions - addHeightOffset(planarTerrain.planarRegions); - - // Add smooth layer for base reference - addSmoothLayer(planarTerrain.gridMap, elevationData, planarityMask); - - // post process elevation map - dilationInNonplanarRegions(elevationData, planarityMask); - addHeightOffset(elevationData, planarityMask); -} - -void Postprocessing::dilationInNonplanarRegions(Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const { - if (parameters_.nonplanar_horizontal_offset > 0) { - // Convert to opencv image - cv::Mat elevationImage; - cv::eigen2cv(elevationData, elevationImage); // creates CV_32F image - - // dilate - const int dilationSize = 2 * parameters_.nonplanar_horizontal_offset + 1; // - const int dilationType = cv::MORPH_ELLIPSE; // ellipse inscribed in the square of size dilationSize - const auto dilationKernel_ = cv::getStructuringElement(dilationType, cv::Size(dilationSize, dilationSize)); - cv::dilate(elevationImage, elevationImage, dilationKernel_, cv::Point(-1, -1), 1, cv::BORDER_REPLICATE); - - // convert back - Eigen::MatrixXf elevationDilated; - cv::cv2eigen(elevationImage, elevationDilated); - - // merge: original elevation for planar regions (mask = 1.0), dilated elevation for non-planar (mask = 0.0) - elevationData = planarityMask.array() * elevationData.array() + (1.0 - planarityMask.array()) * elevationDilated.array(); - } -} - -void Postprocessing::addHeightOffset(Eigen::MatrixXf& elevationData, const Eigen::MatrixXf& planarityMask) const { - // lift elevation layer. For untraversable offset we first add the offset everywhere and substract it again in traversable regions. - if (parameters_.extracted_planes_height_offset != 0.0 || parameters_.nonplanar_height_offset != 0.0) { - elevationData.array() += (parameters_.extracted_planes_height_offset + parameters_.nonplanar_height_offset); - - if (parameters_.nonplanar_height_offset != 0.0) { - elevationData.noalias() -= parameters_.nonplanar_height_offset * planarityMask; - } - } -} - -void Postprocessing::addHeightOffset(std::vector& planarRegions) const { - if (parameters_.extracted_planes_height_offset != 0.0) { - for (auto& planarRegion : planarRegions) { - planarRegion.transformPlaneToWorld.translation().z() += parameters_.extracted_planes_height_offset; - } - } -} - -void Postprocessing::addSmoothLayer(grid_map::GridMap& gridMap, const Eigen::MatrixXf& elevationData, - const Eigen::MatrixXf& planarityMask) const { - auto kernelSizeInPixels = [res = gridMap.getResolution()](double realSize) { - return 2 * static_cast(std::round(realSize / res)) + 1; - }; - - // Helper to convert to Eigen - auto toEigen = [](const cv::Mat& image) { - Eigen::MatrixXf data; - cv::cv2eigen(image, data); - return data; - }; - - // Helper to openCV - auto toCv = [](const Eigen::MatrixXf& data) { - cv::Mat image; - cv::eigen2cv(data, image); - return image; - }; - - const int dilationSize = kernelSizeInPixels(parameters_.smoothing_dilation_size); - const int kernel = kernelSizeInPixels(parameters_.smoothing_box_kernel_size); - const int kernelGauss = kernelSizeInPixels(parameters_.smoothing_gauss_kernel_size); - - - // Set non planar regions to NaN - Eigen::MatrixXf elevationWithNaN = - (planarityMask.array() == 1.0) - .select(elevationData, Eigen::MatrixXf::Constant(elevationData.rows(), elevationData.cols(), NAN)); - gridMap.add("elevationWithNaN", elevationWithNaN); - - // Inpainting - grid_map::inpainting::minValues(gridMap, "elevationWithNaN", "elevationWithNaN_i"); - - // Closing - auto elevationWithNaNCv = toCv(gridMap.get("elevationWithNaN_i")); - const int dilationType = cv::MORPH_ELLIPSE; // ellipse inscribed in the square of size dilationSize - const auto dilationKernel_ = cv::getStructuringElement(dilationType, cv::Size(dilationSize, dilationSize)); - cv::morphologyEx(elevationWithNaNCv, elevationWithNaNCv, cv::MORPH_CLOSE, dilationKernel_, cv::Point(-1, -1), 1, cv::BORDER_REPLICATE); - - gridMap.add("elevationWithNaNClosed", toEigen(elevationWithNaNCv)); - - // Dilation with a slope of 45 deg - int halfDilationSize = (dilationSize - 1) / 2; - float slope = gridMap.getResolution(); // dh dpixel - Eigen::MatrixXf offsets(dilationSize, dilationSize); - for (int i = 0; i < dilationSize; ++i) { - for (int j = 0; j < dilationSize; ++j) { - const auto dx = (i - halfDilationSize); - const auto dy = (j - halfDilationSize); - offsets(i, j) = slope * std::sqrt(dx * dx + dy * dy); - } - } - grid_map::processing::applyKernelFunction( - gridMap, "elevationWithNaNClosed", "elevationWithNaNClosedDilated", dilationSize, - [&](const Eigen::Ref& data) -> float { return (data - offsets).maxCoeffOfFinites(); }); - - // Convert to openCV - auto elevationWithNaNImage = toCv(gridMap.get("elevationWithNaNClosedDilated")); - - // Filter definition - auto smoothingFilter = [kernel, kernelGauss](const cv::Mat& imageIn) { - cv::Mat imageOut; - cv::boxFilter(imageIn, imageOut, -1, {kernel, kernel}, cv::Point(-1, -1), true, cv::BorderTypes::BORDER_REPLICATE); - cv::GaussianBlur(imageOut, imageOut, {kernelGauss, kernelGauss}, 0, 0, cv::BorderTypes::BORDER_REPLICATE); - return imageOut; - }; - auto smooth_planar = smoothingFilter(elevationWithNaNImage); - - // Add layer to map. - gridMap.add("smooth_planar", toEigen(smooth_planar)); -} - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/src/SegmentedPlaneProjection.cpp b/plane_segmentation/convex_plane_decomposition/src/SegmentedPlaneProjection.cpp deleted file mode 100644 index ca4a4988..00000000 --- a/plane_segmentation/convex_plane_decomposition/src/SegmentedPlaneProjection.cpp +++ /dev/null @@ -1,150 +0,0 @@ -// -// Created by rgrandia on 12.10.21. -// - -#include "convex_plane_decomposition/SegmentedPlaneProjection.h" - -#include "convex_plane_decomposition/GeometryUtils.h" - -namespace convex_plane_decomposition { - -namespace { // Helper functions that only make sense in this context - -double distanceCost(const Eigen::Vector3d& query, const Eigen::Vector3d& terrainPoint) { - const double dx = query.x() - terrainPoint.x(); - const double dy = query.y() - terrainPoint.y(); - const double dz = query.z() - terrainPoint.z(); - return dx * dx + dy * dy + dz * dz; -} - -double distanceCostLowerbound(double distanceSquared) { - return distanceSquared; -} - -double intervalSquareDistance(double value, double min, double max) { - // - | 0 | + - // min max - // Returns 0.0 if between min and max. Returns the distance to one boundary otherwise. - if (value < min) { - double diff = min - value; - return diff * diff; - } else if (value < max) { - return 0.0; - } else { - double diff = max - value; - return diff * diff; - } -} - -double squaredDistanceToBoundingBox(const CgalPoint2d& point, const CgalBbox2d& boundingBox) { - const double dxdx = intervalSquareDistance(point.x(), boundingBox.xmin(), boundingBox.xmax()); - const double dydy = intervalSquareDistance(point.y(), boundingBox.ymin(), boundingBox.ymax()); - return dxdx + dydy; -} - -const CgalPolygonWithHoles2d* findInsetContainingThePoint(const CgalPoint2d& point, const std::vector& insets) { - for (const auto& inset : insets) { - if (isInside(point, inset.outer_boundary())) { - return &inset; - } - } - return nullptr; -} - -} // namespace - -CgalPoint2d projectToPlanarRegion(const CgalPoint2d& queryProjectedToPlane, const PlanarRegion& planarRegion) { - // First search if the projected point is inside any of the insets. - // Note: we know that all insets are non-overlapping, and are not nested (no shape is contained in the hole of another shape) - const auto* const insetPtrContainingPoint = findInsetContainingThePoint(queryProjectedToPlane, planarRegion.boundaryWithInset.insets); - - // Compute the projection - CgalPoint2d projectedPoint; - if (insetPtrContainingPoint == nullptr) { - // Not inside any of the insets. Need to look for the closest one. The projection will be to the boundary - double minDistSquared = std::numeric_limits::max(); - for (const auto& inset : planarRegion.boundaryWithInset.insets) { - const auto closestPoint = projectToClosestPoint(queryProjectedToPlane, inset.outer_boundary()); - double distSquare = squaredDistance(closestPoint, queryProjectedToPlane); - if (distSquare < minDistSquared) { - projectedPoint = closestPoint; - minDistSquared = distSquare; - } - } - } else { - // Query point is inside and does not need projection... - projectedPoint = queryProjectedToPlane; - - // ... unless it is inside a hole - for (const auto& hole : insetPtrContainingPoint->holes()) { - if (isInside(queryProjectedToPlane, hole)) { - projectedPoint = projectToClosestPoint(queryProjectedToPlane, hole); - break; // No need to search other holes. Holes are not overlapping - } - } - } - - return projectedPoint; -} - -std::vector sortWithBoundingBoxes(const Eigen::Vector3d& positionInWorld, - const std::vector& planarRegions) { - // Compute distance to bounding boxes - std::vector regionsAndBboxSquareDistances; - regionsAndBboxSquareDistances.reserve(planarRegions.size()); - for (const auto& planarRegion : planarRegions) { - const Eigen::Vector3d positionInTerrainFrame = planarRegion.transformPlaneToWorld.inverse() * positionInWorld; - const double dzdz = positionInTerrainFrame.z() * positionInTerrainFrame.z(); - - RegionSortingInfo regionSortingInfo; - regionSortingInfo.regionPtr = &planarRegion; - regionSortingInfo.positionInTerrainFrame = {positionInTerrainFrame.x(), positionInTerrainFrame.y()}; - regionSortingInfo.boundingBoxSquareDistance = - squaredDistanceToBoundingBox(regionSortingInfo.positionInTerrainFrame, planarRegion.bbox2d) + dzdz; - - regionsAndBboxSquareDistances.push_back(regionSortingInfo); - } - - // Sort regions close to far - std::sort(regionsAndBboxSquareDistances.begin(), regionsAndBboxSquareDistances.end(), - [](const RegionSortingInfo& lhs, const RegionSortingInfo& rhs) { - return lhs.boundingBoxSquareDistance < rhs.boundingBoxSquareDistance; - }); - - return regionsAndBboxSquareDistances; -} - -PlanarTerrainProjection getBestPlanarRegionAtPositionInWorld(const Eigen::Vector3d& positionInWorld, - const std::vector& planarRegions, - const std::function& penaltyFunction) { - const auto sortedRegions = sortWithBoundingBoxes(positionInWorld, planarRegions); - - // Look for closest planar region. - PlanarTerrainProjection projection; - projection.cost = std::numeric_limits::max(); - for (const auto& regionInfo : sortedRegions) { - // Skip based on lower bound - if (distanceCostLowerbound(regionInfo.boundingBoxSquareDistance) > projection.cost) { - continue; - } - - // Project onto planar region - const auto projectedPointInTerrainFrame = projectToPlanarRegion(regionInfo.positionInTerrainFrame, *regionInfo.regionPtr); - - // Express projected point in World frame - const auto projectionInWorldFrame = - positionInWorldFrameFromPosition2dInPlane(projectedPointInTerrainFrame, regionInfo.regionPtr->transformPlaneToWorld); - - const auto cost = distanceCost(positionInWorld, projectionInWorldFrame) + penaltyFunction(projectionInWorldFrame); - if (cost < projection.cost) { - projection.cost = cost; - projection.regionPtr = regionInfo.regionPtr; - projection.positionInTerrainFrame = projectedPointInTerrainFrame; - projection.positionInWorld = projectionInWorldFrame; - } - } - - return projection; -} - -} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp b/plane_segmentation/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp deleted file mode 100644 index ee5a3fc9..00000000 --- a/plane_segmentation/convex_plane_decomposition/src/contour_extraction/ContourExtraction.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// Created by rgrandia on 04.06.20. -// - -#include "convex_plane_decomposition/contour_extraction/ContourExtraction.h" -#include "convex_plane_decomposition/contour_extraction/Upsampling.h" - -#include -#include - -namespace convex_plane_decomposition { -namespace contour_extraction { - -ContourExtraction::ContourExtraction(const ContourExtractionParameters& parameters) - : parameters_(parameters), binaryImage_(cv::Size(0, 0), CV_8UC1) { - { - int erosionSize = 1; // single sided length of the kernel - int erosionType = cv::MORPH_CROSS; - insetKernel_ = cv::getStructuringElement(erosionType, cv::Size(2 * erosionSize + 1, 2 * erosionSize + 1)); - } - { - int erosionSize = 1 + parameters_.marginSize; // single sided length of the kernel - int erosionType = cv::MORPH_ELLIPSE; - marginKernel_ = cv::getStructuringElement(erosionType, cv::Size(2 * erosionSize + 1, 2 * erosionSize + 1)); - } -} - -std::vector ContourExtraction::extractPlanarRegions(const SegmentedPlanesMap& segmentedPlanesMap) { - const auto upSampledMap = upSample(segmentedPlanesMap); - - std::vector planarRegions; - planarRegions.reserve(upSampledMap.highestLabel + 1); // Can be more or less in the end if regions are split or removed. - for (const auto& label_plane : upSampledMap.labelPlaneParameters) { - const int label = label_plane.first; - binaryImage_ = upSampledMap.labeledImage == label; - - // Try with safety margin - cv::erode(binaryImage_, binaryImage_, marginKernel_, cv::Point(-1,-1), 1, cv::BORDER_REPLICATE); - auto boundariesAndInsets = contour_extraction::extractBoundaryAndInset(binaryImage_, insetKernel_); - - // If safety margin makes the region disappear -> try without - if (boundariesAndInsets.empty()) { - binaryImage_ = upSampledMap.labeledImage == label; - // still 1 pixel erosion to remove the growth after upsampling - cv::erode(binaryImage_, binaryImage_, insetKernel_, cv::Point(-1,-1), 1, cv::BORDER_REPLICATE); - boundariesAndInsets = contour_extraction::extractBoundaryAndInset(binaryImage_, insetKernel_); - } - - const auto plane_parameters = getTransformLocalToGlobal(label_plane.second); - for (auto& boundaryAndInset : boundariesAndInsets) { - // Transform points from pixel space to local terrain frame - transformInPlace(boundaryAndInset, [&](CgalPoint2d& point) { - auto pointInWorld = pixelToWorldFrame(point, upSampledMap.resolution, upSampledMap.mapOrigin); - point = projectToPlaneAlongGravity(pointInWorld, plane_parameters); - }); - - PlanarRegion planarRegion; - planarRegion.boundaryWithInset = std::move(boundaryAndInset); - planarRegion.transformPlaneToWorld = plane_parameters; - planarRegion.bbox2d = planarRegion.boundaryWithInset.boundary.outer_boundary().bbox(); - planarRegions.push_back(std::move(planarRegion)); - } - } - return planarRegions; -} - -std::vector extractBoundaryAndInset(cv::Mat& binary_image, const cv::Mat& erosionKernel) { - // Get boundary - std::vector boundaries = extractPolygonsFromBinaryImage(binary_image); - - // Erode - cv::erode(binary_image, binary_image, erosionKernel, cv::Point(-1,-1), 1, cv::BORDER_REPLICATE); - - // Erosion of the edge of the map - binary_image.row(0) = 0; - binary_image.row(binary_image.rows - 1) = 0; - binary_image.col(0) = 0; - binary_image.col(binary_image.cols - 1) = 0; - - // Get insets - std::vector insets = extractPolygonsFromBinaryImage(binary_image); - - // Associate boundaries with insets - std::vector boundariesWithInsets; - for (const auto& boundary : boundaries) { - std::vector assignedInsets; - for (const auto& inset : insets) { - if (isInside(inset.outer_boundary().vertex(0), boundary)) { - assignedInsets.push_back(inset); - } - } - - if (!assignedInsets.empty()) { - BoundaryWithInset boundaryWithInset; - boundaryWithInset.boundary = boundary; - boundaryWithInset.insets = assignedInsets; - boundariesWithInsets.push_back(std::move(boundaryWithInset)); - } - } - return boundariesWithInsets; -} - -std::vector extractPolygonsFromBinaryImage(const cv::Mat& binary_image) { - std::vector> contours; - std::vector hierarchy; // [Next, Previous, First_Child, Parent] - auto isOuterContour = [](const cv::Vec4i& hierarchyVector) { - return hierarchyVector[3] < 0; // no parent - }; - - cv::findContours(binary_image, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE); - - std::vector plane_polygons; - for (int i = 0; i < contours.size(); i++) { - if (isOuterContour(hierarchy[i]) && contours[i].size() > 1) { - CgalPolygonWithHoles2d polygon; - polygon.outer_boundary() = cgalPolygonFromOpenCv(contours[i]); - - // Add children as holes - int childIndex = hierarchy[i][2]; // First child - while (childIndex > 0) { - polygon.add_hole(cgalPolygonFromOpenCv(contours[childIndex])); - childIndex = hierarchy[childIndex][0]; // Next child - } - plane_polygons.push_back(std::move(polygon)); - } - } - return plane_polygons; -} - -CgalPolygon2d cgalPolygonFromOpenCv(const std::vector& openCvPolygon) { - CgalPolygon2d polygon; - polygon.container().reserve(openCvPolygon.size()); - for (const auto& point : openCvPolygon) { - polygon.container().emplace_back(point.x, point.y); - } - return polygon; -} - -CgalPoint2d pixelToWorldFrame(const CgalPoint2d& pixelspaceCgalPoint2d, double resolution, const Eigen::Vector2d& mapOffset) { - // Notice the transpose of x and y! - return {mapOffset.x() - resolution * pixelspaceCgalPoint2d.y(), mapOffset.y() - resolution * pixelspaceCgalPoint2d.x()}; -} - -} // namespace contour_extraction -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/src/contour_extraction/Upsampling.cpp b/plane_segmentation/convex_plane_decomposition/src/contour_extraction/Upsampling.cpp deleted file mode 100644 index a742d069..00000000 --- a/plane_segmentation/convex_plane_decomposition/src/contour_extraction/Upsampling.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// -// Created by rgrandia on 26.10.21. -// - -#include "convex_plane_decomposition/contour_extraction/Upsampling.h" - -namespace convex_plane_decomposition { -namespace contour_extraction { - -namespace { -// Helper function that upsamples a single column. Writes into a target that is already allocated with the right size -void upSampleColumn(const cv::Mat& column, cv::Mat& target, int col, int rows, int upsampledRows) { - for (int row = 0; row < rows; ++row) { - const auto value = column.at(row); - if (row == 0) { - target.at(0, col) = value; - target.at(1, col) = value; - } else if (row + 1 == rows) { - target.at(upsampledRows - 2, col) = value; - target.at(upsampledRows - 1, col) = value; - } else { - const int targetRow = 2 + 3 * (row - 1); - target.at(targetRow, col) = value; - target.at(targetRow + 1, col) = value; - target.at(targetRow + 2, col) = value; - } - } -} -} // namespace - -cv::Mat upSample(const cv::Mat& image) { - const int rows = image.rows; - const int cols = image.cols; - assert(rows >= 2); - assert(cols >= 2); - const int upsampledRows = 4 + 3 * (rows - 2); - const int upsampledCols = 4 + 3 * (cols - 2); - - cv::Mat result(upsampledRows, upsampledCols, image.type()); - - for (int col = 0; col < cols; ++col) { - const auto& column = image.col(col); - if (col == 0) { - upSampleColumn(column, result, 0, rows, upsampledRows); - result.col(0).copyTo(result.col(1)); - } else if (col + 1 == cols) { - upSampleColumn(column, result, upsampledCols - 2, rows, upsampledRows); - result.col(upsampledCols - 2).copyTo(result.col(upsampledCols - 1)); - } else { - const int targetCol = 2 + 3 * (col - 1); - upSampleColumn(column, result, targetCol, rows, upsampledRows); - result.col(targetCol).copyTo(result.col(targetCol + 1)); - result.col(targetCol + 1).copyTo(result.col(targetCol + 2)); - } - } - - return result; -} - -SegmentedPlanesMap upSample(const SegmentedPlanesMap& mapIn) { - SegmentedPlanesMap mapOut; - mapOut.labelPlaneParameters = mapIn.labelPlaneParameters; - mapOut.labeledImage = upSample(mapIn.labeledImage); - mapOut.resolution = mapIn.resolution / 3.0; - mapOut.mapOrigin = mapIn.mapOrigin; - mapOut.highestLabel = mapIn.highestLabel; - return mapOut; -} - -} // namespace contour_extraction -} // namespace convex_plane_decomposition \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp b/plane_segmentation/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp deleted file mode 100644 index 98dc720e..00000000 --- a/plane_segmentation/convex_plane_decomposition/src/ransac/RansacPlaneExtractor.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "convex_plane_decomposition/ransac/RansacPlaneExtractor.hpp" - -namespace ransac_plane_extractor { - -RansacPlaneExtractor::RansacPlaneExtractor(const RansacPlaneExtractorParameters& parameters) { - setParameters(parameters); - ransac_.add_shape_factory(); -} - -void RansacPlaneExtractor::setParameters(const RansacPlaneExtractorParameters& parameters) { - cgalRansacParameters_.probability = parameters.probability; - cgalRansacParameters_.min_points = parameters.min_points; - cgalRansacParameters_.epsilon = parameters.epsilon / 3.0; // CGAL ransac puts the inlier tolerance at 3 times epsilon - cgalRansacParameters_.cluster_epsilon = parameters.cluster_epsilon; - cgalRansacParameters_.normal_threshold = std::cos(parameters.normal_threshold * M_PI / 180.0); -} - -void RansacPlaneExtractor::detectPlanes(std::vector& points_with_normal) { - ransac_.set_input(points_with_normal); - ransac_.detect(cgalRansacParameters_); -} - -std::pair RansacPlaneExtractor::getPlaneParameters(Shape* shapePtr) { - const auto* planePtr = static_cast(shapePtr); - - // Get Normal, pointing upwards - Eigen::Vector3d normalVector(planePtr->plane_normal().x(), planePtr->plane_normal().y(), planePtr->plane_normal().z()); - if (normalVector.z() < 0.0) { - normalVector = -normalVector; - } - - // Project origin to get a point on the plane. - const auto support = planePtr->projection({0.0, 0.0, 0.0}); - const Eigen::Vector3d supportVector(support.x(), support.y(), support.z()); - - return {normalVector, supportVector}; -} - -} // namespace ransac_plane_extractor diff --git a/plane_segmentation/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp b/plane_segmentation/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp deleted file mode 100644 index 04c488d6..00000000 --- a/plane_segmentation/convex_plane_decomposition/src/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.cpp +++ /dev/null @@ -1,311 +0,0 @@ -#include "convex_plane_decomposition/sliding_window_plane_extraction/SlidingWindowPlaneExtractor.h" - -#include -#include -#include - -#include - -#include -#include - -#include - -namespace convex_plane_decomposition { -namespace sliding_window_plane_extractor { - -namespace { - -std::pair normalAndErrorFromCovariance(int numPoint, const Eigen::Vector3d& mean, - const Eigen::Matrix3d& sumSquared) { - const Eigen::Matrix3d covarianceMatrix = sumSquared / numPoint - mean * mean.transpose(); - - // Compute Eigenvectors. - // Eigenvalues are ordered small to large. - // Worst case bound for zero eigenvalue from : https://eigen.tuxfamily.org/dox/classEigen_1_1SelfAdjointEigenSolver.html - Eigen::SelfAdjointEigenSolver solver; - solver.computeDirect(covarianceMatrix, Eigen::DecompositionOptions::ComputeEigenvectors); - if (solver.eigenvalues()(1) > 1e-8) { - Eigen::Vector3d unitaryNormalVector = solver.eigenvectors().col(0); - - // Check direction of the normal vector and flip the sign upwards - if (unitaryNormalVector.z() < 0.0) { - unitaryNormalVector = -unitaryNormalVector; - } - // The first eigenvalue might become slightly negative due to numerics. - double squareError = (solver.eigenvalues()(0) > 0.0) ? solver.eigenvalues()(0) : 0.0; - return {unitaryNormalVector, squareError}; - } else { // If second eigenvalue is zero, the normal is not defined. - return {Eigen::Vector3d::UnitZ(), 1e30}; - } -} - -} // namespace - -SlidingWindowPlaneExtractor::SlidingWindowPlaneExtractor(const SlidingWindowPlaneExtractorParameters& parameters, - const ransac_plane_extractor::RansacPlaneExtractorParameters& ransacParameters) - : parameters_(parameters), ransacParameters_(ransacParameters) {} - -void SlidingWindowPlaneExtractor::runExtraction(const grid_map::GridMap& map, const std::string& layer_height) { - // Extract basic map information - map_ = ↦ - elevationLayer_ = layer_height; - mapRows_ = map_->getSize()[0]; - segmentedPlanesMap_.resolution = map_->getResolution(); - map_->getPosition(Eigen::Vector2i(0, 0), segmentedPlanesMap_.mapOrigin); - - // Initialize based on map size. - segmentedPlanesMap_.highestLabel = -1; - segmentedPlanesMap_.labelPlaneParameters.clear(); - const auto& mapSize = map_->getSize(); - binaryImagePatch_ = cv::Mat(mapSize(0), mapSize(1), CV_8U, 0.0); // Zero initialize to set untouched pixels to not planar; - // Need a buffer of at least the linear size of the image. But no need to shrink if the buffer is already bigger. - const int linearMapSize = mapSize(0) * mapSize(1); - if (surfaceNormals_.size() < linearMapSize) { - surfaceNormals_.reserve(linearMapSize); - std::fill_n(surfaceNormals_.begin(), linearMapSize, Eigen::Vector3d::Zero()); - } - - // Run - runSlidingWindowDetector(); - runSegmentation(); - extractPlaneParametersFromLabeledImage(); - - // Get classification from segmentation to account for unassigned points. - binaryImagePatch_ = segmentedPlanesMap_.labeledImage > 0; - binaryImagePatch_.setTo(1, binaryImagePatch_ == 255); -} - -std::pair SlidingWindowPlaneExtractor::computeNormalAndErrorForWindow(const Eigen::MatrixXf& windowData) const { - // Gather surrounding data. - size_t nPoints = 0; - Eigen::Vector3d sum = Eigen::Vector3d::Zero(); - Eigen::Matrix3d sumSquared = Eigen::Matrix3d::Zero(); - for (int kernel_col = 0; kernel_col < parameters_.kernel_size; ++kernel_col) { - for (int kernel_row = 0; kernel_row < parameters_.kernel_size; ++kernel_row) { - float height = windowData(kernel_row, kernel_col); - if (!std::isfinite(height)) { - continue; - } - // No need to account for map offset. Will substract the mean anyway. - Eigen::Vector3d point{-kernel_row * segmentedPlanesMap_.resolution, -kernel_col * segmentedPlanesMap_.resolution, height}; - nPoints++; - sum += point; - sumSquared.noalias() += point * point.transpose(); - } - } - - if (nPoints < 3) { - // Not enough points to establish normal direction - return {Eigen::Vector3d::UnitZ(), 1e30}; - } else { - const Eigen::Vector3d mean = sum / nPoints; - return normalAndErrorFromCovariance(nPoints, mean, sumSquared); - } -} - -bool SlidingWindowPlaneExtractor::isLocallyPlanar(const Eigen::Vector3d& localNormal, double meanSquaredError) const { - const double thresholdSquared = parameters_.plane_patch_error_threshold * parameters_.plane_patch_error_threshold; - - // Dotproduct between normal and Eigen::Vector3d::UnitZ(); - const double normalDotProduct = localNormal.z(); - return (meanSquaredError < thresholdSquared && normalDotProduct > parameters_.local_plane_inclination_threshold); -} - -void SlidingWindowPlaneExtractor::runSlidingWindowDetector() { - grid_map::SlidingWindowIterator window_iterator(*map_, elevationLayer_, grid_map::SlidingWindowIterator::EdgeHandling::EMPTY, - parameters_.kernel_size); - const int kernelMiddle = (parameters_.kernel_size - 1) / 2; - - for (; !window_iterator.isPastEnd(); ++window_iterator) { - grid_map::Index index = *window_iterator; - Eigen::MatrixXf window_data = window_iterator.getData(); - const auto middleValue = window_data(kernelMiddle, kernelMiddle); - - if (!std::isfinite(middleValue)) { - binaryImagePatch_.at(index.x(), index.y()) = false; - } else { - Eigen::Vector3d n; - double meanSquaredError; - std::tie(n, meanSquaredError) = computeNormalAndErrorForWindow(window_data); - - surfaceNormals_[getLinearIndex(index.x(), index.y())] = n; - binaryImagePatch_.at(index.x(), index.y()) = isLocallyPlanar(n, meanSquaredError); - } - } - - // opening filter - if (parameters_.planarity_opening_filter > 0) { - const int openingKernelSize = 2 * parameters_.planarity_opening_filter + 1; - const int openingKernelType = cv::MORPH_CROSS; - const auto kernel_ = cv::getStructuringElement(openingKernelType, cv::Size(openingKernelSize, openingKernelSize)); - cv::morphologyEx(binaryImagePatch_, binaryImagePatch_, cv::MORPH_OPEN, kernel_, cv::Point(-1, -1), 1, cv::BORDER_REPLICATE); - } -} - -// Label cells according to which cell they belong to using connected component labeling. -void SlidingWindowPlaneExtractor::runSegmentation() { - int numberOfLabel = cv::connectedComponents(binaryImagePatch_, segmentedPlanesMap_.labeledImage, parameters_.connectivity, CV_32S); - segmentedPlanesMap_.highestLabel = numberOfLabel - 1; // Labels are [0, N-1] -} - -void SlidingWindowPlaneExtractor::extractPlaneParametersFromLabeledImage() { - const int numberOfExtractedPlanesWithoutRefinement = - segmentedPlanesMap_.highestLabel; // Make local copy. The highestLabel is incremented inside the loop - - // Reserve a workvector that is reused between processing labels - pointsWithNormal_.reserve(segmentedPlanesMap_.labeledImage.rows * segmentedPlanesMap_.labeledImage.cols); - - // Skip label 0. This is the background, i.e. non-planar region. - for (int label = 1; label <= numberOfExtractedPlanesWithoutRefinement; ++label) { - computePlaneParametersForLabel(label, pointsWithNormal_); - } -} - -void SlidingWindowPlaneExtractor::computePlaneParametersForLabel(int label, - std::vector& pointsWithNormal) { - const auto& elevationData = (*map_)[elevationLayer_]; - pointsWithNormal.clear(); // clear the workvector - - int numPoints = 0; - Eigen::Vector3d sum = Eigen::Vector3d::Zero(); - Eigen::Matrix3d sumSquared = Eigen::Matrix3d::Zero(); - for (int col = 0; col < segmentedPlanesMap_.labeledImage.cols; ++col) { - for (int row = 0; row < segmentedPlanesMap_.labeledImage.rows; ++row) { - if (segmentedPlanesMap_.labeledImage.at(row, col) == label) { - double height = elevationData(row, col); - if (std::isfinite(height)) { - const Eigen::Vector3d point3d{segmentedPlanesMap_.mapOrigin.x() - row * segmentedPlanesMap_.resolution, - segmentedPlanesMap_.mapOrigin.y() - col * segmentedPlanesMap_.resolution, height}; - - ++numPoints; - sum += point3d; - sumSquared.noalias() += point3d * point3d.transpose(); - - const auto& localSurfaceNormal = surfaceNormals_[getLinearIndex(row, col)]; - pointsWithNormal.emplace_back( - ransac_plane_extractor::Point3D(point3d.x(), point3d.y(), point3d.z()), - ransac_plane_extractor::Vector3D(localSurfaceNormal.x(), localSurfaceNormal.y(), localSurfaceNormal.z())); - } - } - } - } - if (numPoints < parameters_.min_number_points_per_label || numPoints < 3) { - // Label has too little points, no plane parameters are created - return; - } - - const Eigen::Vector3d supportVector = sum / numPoints; - const Eigen::Vector3d normalVector = normalAndErrorFromCovariance(numPoints, supportVector, sumSquared).first; - - if (parameters_.include_ransac_refinement) { // with RANSAC - if (isGloballyPlanar(normalVector, supportVector, pointsWithNormal)) { // Already planar enough - if (isWithinInclinationLimit(normalVector)) { - segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, NormalAndPosition{supportVector, normalVector}); - } else { - setToBackground(label); - } - } else { - // Set entire label to background, so unassigned points are automatically in background - setToBackground(label); - refineLabelWithRansac(label, pointsWithNormal); - } - } else { // no RANSAC - if (isWithinInclinationLimit(normalVector)) { - segmentedPlanesMap_.labelPlaneParameters.emplace_back(label, NormalAndPosition{supportVector, normalVector}); - } else { - setToBackground(label); - } - } -} - -void SlidingWindowPlaneExtractor::refineLabelWithRansac(int label, std::vector& pointsWithNormal) { - // Fix the seed for each label to get deterministic behaviour - CGAL::get_default_random() = CGAL::Random(0); - - // Run ransac - ransac_plane_extractor::RansacPlaneExtractor ransac_plane_extractor(ransacParameters_); - ransac_plane_extractor.detectPlanes(pointsWithNormal); - const auto& planes = ransac_plane_extractor.getDetectedPlanes(); - - bool reuseLabel = true; - for (const auto& plane : planes) { - const auto planeInfo = ransac_plane_extractor::RansacPlaneExtractor::getPlaneParameters(plane.get()); - const auto& normalVector = planeInfo.first; - const auto& supportVector = planeInfo.second; - - if (isWithinInclinationLimit(normalVector)) { - // Bookkeeping of labels : reuse old label for the first plane - const int newLabel = (reuseLabel) ? label : ++segmentedPlanesMap_.highestLabel; - reuseLabel = false; - - segmentedPlanesMap_.labelPlaneParameters.emplace_back(newLabel, NormalAndPosition{supportVector, normalVector}); - - // Assign label in segmentation - for (const auto index : plane->indices_of_assigned_points()) { - const auto& point = pointsWithNormal[index].first; - - // Need to lookup indices in map, because RANSAC has reordered the points - Eigen::Array2i map_indices; - map_->getIndex(Eigen::Vector2d(point.x(), point.y()), map_indices); - segmentedPlanesMap_.labeledImage.at(map_indices(0), map_indices(1)) = newLabel; - } - } - } -} - -void SlidingWindowPlaneExtractor::addSurfaceNormalToMap(grid_map::GridMap& map, const std::string& layerPrefix) const { - map.add(layerPrefix + "_x"); - map.add(layerPrefix + "_y"); - map.add(layerPrefix + "_z"); - auto& dataX = map.get(layerPrefix + "_x"); - auto& dataY = map.get(layerPrefix + "_y"); - auto& dataZ = map.get(layerPrefix + "_z"); - - grid_map::SlidingWindowIterator window_iterator(map, layerPrefix + "_x", grid_map::SlidingWindowIterator::EdgeHandling::EMPTY, - parameters_.kernel_size); - - for (; !window_iterator.isPastEnd(); ++window_iterator) { - grid_map::Index index = *window_iterator; - const auto& n = surfaceNormals_[getLinearIndex(index.x(), index.y())]; - dataX(index.x(), index.y()) = n.x(); - dataY(index.x(), index.y()) = n.y(); - dataZ(index.x(), index.y()) = n.z(); - } -} - -bool SlidingWindowPlaneExtractor::isGloballyPlanar(const Eigen::Vector3d& normalVectorPlane, const Eigen::Vector3d& supportVectorPlane, - const std::vector& pointsWithNormal) const { - // Part of the plane projection that is independent of the point - const double normalDotSupportvector = normalVectorPlane.dot(supportVectorPlane); - - // Convert threshold in degrees to threshold on dot product (between normalized vectors) - const double dotProductThreshold = std::cos(parameters_.global_plane_fit_angle_error_threshold_degrees * M_PI / 180.0); - - for (const auto& pointWithNormal : pointsWithNormal) { - const double normalDotPoint = normalVectorPlane.x() * pointWithNormal.first.x() + normalVectorPlane.y() * pointWithNormal.first.y() + - normalVectorPlane.z() * pointWithNormal.first.z(); - const double distanceError = std::abs(normalDotPoint - normalDotSupportvector); - - const double dotProductNormals = normalVectorPlane.x() * pointWithNormal.second.x() + - normalVectorPlane.y() * pointWithNormal.second.y() + - normalVectorPlane.z() * pointWithNormal.second.z(); - - if (distanceError > parameters_.global_plane_fit_distance_error_threshold || dotProductNormals < dotProductThreshold) { - return false; - } - } - - return true; -} - -bool SlidingWindowPlaneExtractor::isWithinInclinationLimit(const Eigen::Vector3d& normalVectorPlane) const { - return normalVectorPlane.z() > parameters_.plane_inclination_threshold; -} - -void SlidingWindowPlaneExtractor::setToBackground(int label) { - segmentedPlanesMap_.labeledImage.setTo(0, segmentedPlanesMap_.labeledImage == label); -} - -} // namespace sliding_window_plane_extractor -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition/test/data/terrain.png b/plane_segmentation/convex_plane_decomposition/test/data/terrain.png deleted file mode 100644 index 65cfe247f929043833c3d49de1f345a4a17f7adf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 112548 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≶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 g`e0c+1#i3!b+ - -#include - -#include - -#include "convex_plane_decomposition/ConvexRegionGrowing.h" -#include "convex_plane_decomposition/GeometryUtils.h" -#include "convex_plane_decomposition/LoadGridmapFromImage.h" -#include "convex_plane_decomposition/PlaneDecompositionPipeline.h" -#include "convex_plane_decomposition/SegmentedPlaneProjection.h" - -using namespace convex_plane_decomposition; - -namespace { - -/** - * Brute force version of getBestPlanarRegionAtPositionInWorld, searches through all candidates without shortcuts - */ -PlanarTerrainProjection getBestPlanarRegionAtPositionInWorldNaive(const Eigen::Vector3d& positionInWorld, - const std::vector& planarRegions, - const std::function& penaltyFunction) { - // Do full project per region first - std::vector individualProjections; - std::for_each(planarRegions.begin(), planarRegions.end(), [&](const PlanarRegion& planarRegion) { - const Eigen::Vector3d positionInTerrainFrame = planarRegion.transformPlaneToWorld.inverse() * positionInWorld; - - PlanarTerrainProjection projection; - projection.regionPtr = &planarRegion; - projection.positionInTerrainFrame = projectToPlanarRegion({positionInTerrainFrame.x(), positionInTerrainFrame.y()}, planarRegion); - projection.positionInWorld = - positionInWorldFrameFromPosition2dInPlane(projection.positionInTerrainFrame, planarRegion.transformPlaneToWorld); - projection.cost = (positionInWorld - projection.positionInWorld).squaredNorm() + penaltyFunction(projection.positionInWorld); - individualProjections.push_back(projection); - }); - - // Find the minimum cost projection - return *std::min_element(individualProjections.begin(), individualProjections.end(), - [](const PlanarTerrainProjection& lhs, const PlanarTerrainProjection& rhs) { return lhs.cost < rhs.cost; }); -} -} // namespace - -TEST(TestConvexApproximation, runOnDemoMap) { - // Config - PlaneDecompositionPipeline::Config config; - const auto resolution = config.preprocessingParameters.resolution; - const std::string elevationLayer{"elevation_test"}; - const std::string frameId{"odom_test"}; - const Eigen::Array2d submapSize(3.0, 3.0); - std::string file = "terrain.png"; - double heightScale = 1.25; - - // Terrain Loading - boost::filesystem::path filePath(__FILE__); - std::string folder = filePath.parent_path().generic_string() + std::string{"/data/"}; - const auto loadedMap = loadGridmapFromImage(folder + file, elevationLayer, frameId, resolution, heightScale); - bool success = false; - auto elevationMap = loadedMap.getSubmap(loadedMap.getPosition(), submapSize, success); - ASSERT_TRUE(success); - - // Run pipeline. - PlaneDecompositionPipeline pipeline(config); - pipeline.update(std::move(elevationMap), elevationLayer); - const auto& planarTerrain = pipeline.getPlanarTerrain(); - - // Query a range of points - for (double x = -submapSize.x() / 2.0; x < submapSize.x() / 2.0; x += submapSize.x() / 4.0) { - for (double y = -submapSize.y() / 2.0; y < submapSize.y() / 2.0; y += submapSize.y() / 4.0) { - for (double z = -heightScale; z < heightScale; z += heightScale / 2.0) { - Eigen::Vector3d query{x, y, z}; - auto penaltyFunction = [](const Eigen::Vector3d& projectedPoint) { return 0.1 * std::abs(projectedPoint.z()); }; - - // Run projection and naive projection - const auto projection = getBestPlanarRegionAtPositionInWorld(query, planarTerrain.planarRegions, penaltyFunction); - const auto projectionCheck = getBestPlanarRegionAtPositionInWorldNaive(query, planarTerrain.planarRegions, penaltyFunction); - - // Check they are the same - ASSERT_EQ(projection.regionPtr, projectionCheck.regionPtr); - ASSERT_DOUBLE_EQ(projection.cost, projectionCheck.cost); - ASSERT_DOUBLE_EQ(projection.positionInTerrainFrame.x(), projectionCheck.positionInTerrainFrame.x()); - ASSERT_DOUBLE_EQ(projection.positionInTerrainFrame.y(), projectionCheck.positionInTerrainFrame.y()); - ASSERT_TRUE(projection.positionInWorld.isApprox(projectionCheck.positionInWorld)); - - // Check convex approximation with a range of settings - for (int numberOfVertices = 3; numberOfVertices < 7; ++numberOfVertices) { - for (double growthFactor = 1.01; growthFactor < 1.3; growthFactor += 0.1) { - const auto convexRegion = convex_plane_decomposition::growConvexPolygonInsideShape( - projection.regionPtr->boundaryWithInset.boundary, projection.positionInTerrainFrame, numberOfVertices, growthFactor); - - ASSERT_TRUE(std::all_of(convexRegion.vertices_begin(), convexRegion.vertices_end(), - [&](const CgalPoint2d& p) { return isInside(p, projection.regionPtr->boundaryWithInset.boundary); })); - } - } - } - } - } -} diff --git a/plane_segmentation/convex_plane_decomposition/test/testPipeline.cpp b/plane_segmentation/convex_plane_decomposition/test/testPipeline.cpp deleted file mode 100644 index 50e6df78..00000000 --- a/plane_segmentation/convex_plane_decomposition/test/testPipeline.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// Created by rgrandia on 16.03.22. -// - -#include - -#include - -#include "convex_plane_decomposition/LoadGridmapFromImage.h" -#include "convex_plane_decomposition/PlaneDecompositionPipeline.h" - -using namespace convex_plane_decomposition; - -TEST(TestPipeline, runOnDemoMap) { - // Config - PlaneDecompositionPipeline::Config config; - const auto resolution = config.preprocessingParameters.resolution; - const std::string elevationLayer{"elevation_test"}; - const std::string frameId{"odom_test"}; - const Eigen::Array2d submapSize(3.0, 3.0); - std::string file = "terrain.png"; - double heightScale = 1.25; - - // Terrain Loading - boost::filesystem::path filePath(__FILE__); - std::string folder = filePath.parent_path().generic_string() + std::string{"/data/"}; - const auto loadedMap = loadGridmapFromImage(folder + file, elevationLayer, frameId, resolution, heightScale); - bool success = false; - auto elevationMap = loadedMap.getSubmap(loadedMap.getPosition(), submapSize, success); - ASSERT_TRUE(success); - - // Run - PlaneDecompositionPipeline pipeline(config); - ASSERT_NO_THROW(pipeline.update(std::move(elevationMap), elevationLayer)); -} diff --git a/plane_segmentation/convex_plane_decomposition/test/testPlanarRegion.cpp b/plane_segmentation/convex_plane_decomposition/test/testPlanarRegion.cpp deleted file mode 100644 index 3b33818e..00000000 --- a/plane_segmentation/convex_plane_decomposition/test/testPlanarRegion.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// -// Created by rgrandia on 15.03.22. -// - -#include - -#include "convex_plane_decomposition/PlanarRegion.h" - -using namespace convex_plane_decomposition; - -TEST(TestPlanarRegion, getTransformFromNormalAndPosition_identity) { - NormalAndPosition normalAndPosition = {Eigen::Vector3d::Zero(), Eigen::Vector3d::UnitZ()}; - const auto transform = getTransformLocalToGlobal(normalAndPosition); - - // Orientation - ASSERT_TRUE(transform.linear().isApprox(Eigen::Matrix3d::Identity())); - - // Position - ASSERT_TRUE(transform.translation().isApprox(normalAndPosition.position)); -} - -TEST(TestPlanarRegion, getTransformFromNormalAndPosition_random) { - NormalAndPosition normalAndPosition = {Eigen::Vector3d(0.1, 0.2, 0.3), Eigen::Vector3d(0.4, 0.5, 0.6).normalized()}; - const auto transform = getTransformLocalToGlobal(normalAndPosition); - - const Eigen::Vector3d xAxisInWorld = transform.linear().col(0); - const Eigen::Vector3d yAxisInWorld = transform.linear().col(1); - const Eigen::Vector3d zAxisInWorld = transform.linear().col(2); - - // Z direction - ASSERT_TRUE(zAxisInWorld.isApprox(normalAndPosition.normal)); - - // Orthogonal - ASSERT_LT(std::abs(zAxisInWorld.dot(yAxisInWorld)), 1e-12); - ASSERT_LT(std::abs(zAxisInWorld.dot(xAxisInWorld)), 1e-12); - - // Scale - ASSERT_DOUBLE_EQ(xAxisInWorld.norm(), 1.0); - ASSERT_DOUBLE_EQ(yAxisInWorld.norm(), 1.0); - - // Position - ASSERT_TRUE(transform.translation().isApprox(normalAndPosition.position)); -} - -TEST(TestPlanarRegion, getTransformFromNormalAndPosition_unitX) { - NormalAndPosition normalAndPosition = {Eigen::Vector3d(0.1, 0.2, 0.3), Eigen::Vector3d::UnitX()}; - const auto transform = getTransformLocalToGlobal(normalAndPosition); - - const Eigen::Vector3d xAxisInWorld = transform.linear().col(0); - const Eigen::Vector3d yAxisInWorld = transform.linear().col(1); - const Eigen::Vector3d zAxisInWorld = transform.linear().col(2); - - // Z direction - ASSERT_TRUE(zAxisInWorld.isApprox(normalAndPosition.normal)); - - // XY - ASSERT_TRUE(xAxisInWorld.isApprox(-Eigen::Vector3d::UnitZ())); - ASSERT_TRUE(yAxisInWorld.isApprox(Eigen::Vector3d::UnitY())); - - // Position - ASSERT_TRUE(transform.translation().isApprox(normalAndPosition.position)); -} - -TEST(TestPlanarRegion, projectPositionInWorldOntoPlaneAlongGravity) { - const NormalAndPosition normalAndPosition = {Eigen::Vector3d(0.1, 0.2, 0.3), Eigen::Vector3d(0.4, 0.5, 0.6).normalized()}; - const auto transformPlaneToWorld = getTransformLocalToGlobal(normalAndPosition); - - // Origin of plane is projected to 0, 0 - const CgalPoint2d originXY = {normalAndPosition.position.x(), normalAndPosition.position.y()}; - const CgalPoint2d originInPlane = projectToPlaneAlongGravity(originXY, transformPlaneToWorld); - ASSERT_LT(std::abs(originInPlane.x()), 1e-12); - ASSERT_LT(std::abs(originInPlane.y()), 1e-12); - - // Random point projected - const Eigen::Vector2d queryPosition = Eigen::Vector2d::Random(); - const CgalPoint2d projectedPositionInPlane = projectToPlaneAlongGravity({queryPosition.x(), queryPosition.y()}, transformPlaneToWorld); - - // Convert back to world to check - Eigen::Vector3d projectedPositionInPlane3d = {projectedPositionInPlane.x(), projectedPositionInPlane.y(), 0.0}; - Eigen::Vector3d projectedPositionInWorld3d = transformPlaneToWorld * projectedPositionInPlane3d; - - // x, y position remained to same - ASSERT_DOUBLE_EQ(projectedPositionInWorld3d.x(), queryPosition.x()); - ASSERT_DOUBLE_EQ(projectedPositionInWorld3d.y(), queryPosition.y()); -} \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/test/testRegionGrowing.cpp b/plane_segmentation/convex_plane_decomposition/test/testRegionGrowing.cpp deleted file mode 100644 index dca141a4..00000000 --- a/plane_segmentation/convex_plane_decomposition/test/testRegionGrowing.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// Created by rgrandia on 02.02.22. -// - - -#include - -#include "convex_plane_decomposition/ConvexRegionGrowing.h" - -#include - -using namespace convex_plane_decomposition; - -TEST(TestRegionGrowing, center_on_border) { - // Rare case where the region algorithm go stuck - const int numberOfVertices = 16; // Multiple of 4 is nice for symmetry. - const double growthFactor = 1.05; - CgalPoint2d center(0.0, 1.0); - - CgalPolygonWithHoles2d parentShape; - parentShape.outer_boundary().container() = {{1, -1}, {1, 1}, {-1, 1}, {-1, -1}}; - - const auto convexInnerApprox = growConvexPolygonInsideShape(parentShape, center, numberOfVertices, growthFactor); - ASSERT_TRUE(convexInnerApprox.is_convex()); - for (auto it = convexInnerApprox.vertices_begin(); it!=convexInnerApprox.vertices_end(); ++it) { - ASSERT_TRUE(isInside(*it, parentShape)); - } -} - -TEST(TestRegionGrowing, debug_case) { - // Rare case where the region algorithm got stuck - const int numberOfVertices = 16; - const double growthFactor = 1.05; - CgalPoint2d center(-0.147433, 0.800114); - - CgalPolygonWithHoles2d parentShape; - parentShape.outer_boundary().container() = { - {1.03923, -0.946553}, {1.03923, 0.840114}, {0.7859, 0.840114}, {0.772567, 0.853447}, {0.759233, 0.853447}, - {0.7459, 0.86678}, {0.7459, 0.880114}, {0.732567, 0.893447}, {0.719233, 0.893447}, {0.7059, 0.90678}, - {0.7059, 1.05345}, {0.652567, 1.05345}, {0.652567, 0.90678}, {0.639233, 0.893447}, {0.6259, 0.893447}, - {0.612567, 0.880114}, {0.612567, 0.86678}, {0.599233, 0.853447}, {0.5859, 0.853447}, {0.572567, 0.840114}, - {0.532567, 0.840114}, {0.532567, 0.82678}, {0.519233, 0.813447}, {0.5059, 0.813447}, {0.492567, 0.800114}, - {0.3059, 0.800114}, {0.292567, 0.813447}, {0.279233, 0.813447}, {0.2659, 0.82678}, {0.2659, 0.840114}, - {0.252567, 0.853447}, {0.239233, 0.853447}, {0.2259, 0.86678}, {0.2259, 0.920114}, {0.212567, 0.933447}, - {0.199233, 0.933447}, {0.1859, 0.94678}, {0.1859, 1.05345}, {0.132567, 1.05345}, {0.132567, 0.86678}, - {0.119233, 0.853447}, {0.1059, 0.853447}, {0.0925666, 0.840114}, {0.0925666, 0.82678}, {0.0792332, 0.813447}, - {0.0658999, 0.813447}, {0.0525666, 0.800114}, {-0.1341, 0.800114}, {-0.147433, 0.813447}, {-0.160767, 0.813447}, - {-0.1741, 0.82678}, {-0.1741, 0.840114}, {-0.2141, 0.840114}, {-0.227433, 0.853447}, {-0.240767, 0.853447}, - {-0.2541, 0.86678}, {-0.2541, 0.880114}, {-0.267433, 0.893447}, {-0.280767, 0.893447}, {-0.2941, 0.90678}, - {-0.2941, 1.05345}, {-0.960767, 1.05345}, {-0.960767, -0.946553}}; - - CgalPolygon2d hole; - hole.container() = {{0.5459, -0.266553}, {0.532566, -0.279886}, {0.3059, -0.279886}, {0.292566, -0.266553}, {0.279233, -0.266553}, - {0.2659, -0.25322}, {0.2659, -0.239886}, {0.252566, -0.226553}, {0.239233, -0.226553}, {0.2259, -0.21322}, - {0.2259, 0.320114}, {0.239233, 0.333447}, {0.252566, 0.333447}, {0.2659, 0.34678}, {0.532567, 0.34678}, - {0.5459, 0.333447}, {0.559233, 0.333447}, {0.572567, 0.320114}, {0.572567, 0.30678}, {0.5859, 0.293447}, - {0.599233, 0.293447}, {0.612567, 0.280114}, {0.612566, 0.0667803}, {0.6259, 0.053447}, {0.639233, 0.053447}, - {0.652566, 0.0401136}, {0.652566, -0.17322}, {0.639233, -0.186553}, {0.6259, -0.186553}, {0.612566, -0.199886}, - {0.612566, -0.21322}, {0.599233, -0.226553}, {0.5859, -0.226553}, {0.572566, -0.239886}, {0.572566, -0.25322}, - {0.559233, -0.266553}}; - parentShape.holes().push_back(std::move(hole)); - - const auto convexInnerApprox = growConvexPolygonInsideShape(parentShape, center, numberOfVertices, growthFactor); - - ASSERT_TRUE(convexInnerApprox.is_convex()); - for (auto it = convexInnerApprox.vertices_begin(); it!=convexInnerApprox.vertices_end(); ++it) { - ASSERT_TRUE(isInside(*it, parentShape)); - } -} \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition/test/testUpsampling.cpp b/plane_segmentation/convex_plane_decomposition/test/testUpsampling.cpp deleted file mode 100644 index 06538b10..00000000 --- a/plane_segmentation/convex_plane_decomposition/test/testUpsampling.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// -// Created by rgrandia on 26.10.21. -// - -#include - -#include "convex_plane_decomposition/contour_extraction/Upsampling.h" - -TEST(TestUpsampling, upsampleImage) { - // clang-format off - cv::Mat M = (cv::Mat_(3, 3) << - 1, 2, 3, - 4, 5, 6, - 7, 8, 9); - cv::Mat MoutCheck = (cv::Mat_(7, 7) << - 1, 1, 2, 2, 2, 3, 3, - 1, 1, 2, 2, 2, 3, 3, - 4, 4, 5, 5, 5, 6, 6, - 4, 4, 5, 5, 5, 6, 6, - 4, 4, 5, 5, 5, 6, 6, - 7, 7, 8, 8, 8, 9, 9, - 7, 7, 8, 8, 8, 9, 9); - // clang-format on - - const auto Mout = convex_plane_decomposition::contour_extraction::upSample(M); - - ASSERT_TRUE(std::equal(MoutCheck.begin(), MoutCheck.end(), Mout.begin())); -} \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_msgs/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition_msgs/CMakeLists.txt deleted file mode 100644 index 12f1b2b4..00000000 --- a/plane_segmentation/convex_plane_decomposition_msgs/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(convex_plane_decomposition_msgs) - -set(CATKIN_PACKAGE_DEPENDENCIES - std_msgs - geometry_msgs - grid_map_msgs -) - -find_package(catkin REQUIRED - COMPONENTS - ${CATKIN_PACKAGE_DEPENDENCIES} - message_generation -) - -add_message_files( - FILES - BoundingBox2d.msg - PlanarRegion.msg - PlanarTerrain.msg - Point2d.msg - Polygon2d.msg - PolygonWithHoles2d.msg -) - -generate_messages( - DEPENDENCIES - ${CATKIN_PACKAGE_DEPENDENCIES} -) - -catkin_package( - CATKIN_DEPENDS - ${CATKIN_PACKAGE_DEPENDENCIES} - message_runtime -) diff --git a/plane_segmentation/convex_plane_decomposition_msgs/msg/BoundingBox2d.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/BoundingBox2d.msg deleted file mode 100644 index 2327348a..00000000 --- a/plane_segmentation/convex_plane_decomposition_msgs/msg/BoundingBox2d.msg +++ /dev/null @@ -1,5 +0,0 @@ -# 3D, axis-aligned, bounding box -float32 min_x -float32 min_y -float32 max_x -float32 max_y \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarRegion.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarRegion.msg deleted file mode 100644 index d93d2478..00000000 --- a/plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarRegion.msg +++ /dev/null @@ -1,7 +0,0 @@ -geometry_msgs/Pose plane_parameters - -BoundingBox2d bbox2d - -PolygonWithHoles2d boundary - -PolygonWithHoles2d[] insets diff --git a/plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg deleted file mode 100644 index c50376ee..00000000 --- a/plane_segmentation/convex_plane_decomposition_msgs/msg/PlanarTerrain.msg +++ /dev/null @@ -1,2 +0,0 @@ -PlanarRegion[] planarRegions -grid_map_msgs/GridMap gridmap \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_msgs/msg/Point2d.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/Point2d.msg deleted file mode 100644 index 220abf75..00000000 --- a/plane_segmentation/convex_plane_decomposition_msgs/msg/Point2d.msg +++ /dev/null @@ -1,2 +0,0 @@ -float32 x -float32 y \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_msgs/msg/Polygon2d.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/Polygon2d.msg deleted file mode 100644 index e52128c5..00000000 --- a/plane_segmentation/convex_plane_decomposition_msgs/msg/Polygon2d.msg +++ /dev/null @@ -1,2 +0,0 @@ -# Specification of a 2D polygon where the first and last points are connected -Point2d[] points \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_msgs/msg/PolygonWithHoles2d.msg b/plane_segmentation/convex_plane_decomposition_msgs/msg/PolygonWithHoles2d.msg deleted file mode 100644 index 8513f45c..00000000 --- a/plane_segmentation/convex_plane_decomposition_msgs/msg/PolygonWithHoles2d.msg +++ /dev/null @@ -1,3 +0,0 @@ -# Specification of a 2D polygon with holes -Polygon2d outer_boundary -Polygon2d[] holes \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_msgs/package.xml b/plane_segmentation/convex_plane_decomposition_msgs/package.xml deleted file mode 100644 index 2af22815..00000000 --- a/plane_segmentation/convex_plane_decomposition_msgs/package.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - convex_plane_decomposition_msgs - 0.0.0 - Convex plane decomposition message definitions. - - Ruben Grandia - - MIT - - catkin - - message_generation - - std_msgs - geometry_msgs - grid_map_msgs - - message_runtime - - diff --git a/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt b/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt deleted file mode 100644 index f94b85c6..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/CMakeLists.txt +++ /dev/null @@ -1,129 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(convex_plane_decomposition_ros) - -# Catkin dependencies -set(CATKIN_PACKAGE_DEPENDENCIES - roscpp - grid_map_core - grid_map_ros - grid_map_cv - grid_map_msgs - geometry_msgs - convex_plane_decomposition - convex_plane_decomposition_msgs - tf2_ros - visualization_msgs -) - -find_package(catkin REQUIRED COMPONENTS - ${CATKIN_PACKAGE_DEPENDENCIES} -) - -# OpenCv -find_package(OpenCV REQUIRED) - -# Eigen -find_package(Eigen3 3.3 REQUIRED NO_MODULE) - -# Cpp standard version -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -################################### -## catkin specific configuration ## -################################### -catkin_package( - INCLUDE_DIRS include ${EIGEN3_INCLUDE_DIRS} - LIBRARIES ${PROJECT_NAME} - CATKIN_DEPENDS ${CATKIN_PACKAGE_DEPENDENCIES} - DEPENDS OpenCV -) - -########### -## Build ## -########### - -include_directories( - include - ${EIGEN3_INCLUDE_DIRS} - ${catkin_INCLUDE_DIRS} -) - -add_library(${PROJECT_NAME} - src/ConvexPlaneDecompositionRos.cpp - src/MessageConversion.cpp - src/ParameterLoading.cpp - src/RosVisualizations.cpp - ) -add_dependencies(${PROJECT_NAME} - ${catkin_EXPORTED_TARGETS} - ) -target_link_libraries(${PROJECT_NAME} - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - ) - -add_executable(${PROJECT_NAME}_node - src/ConvexPlaneDecompositionNode.cpp -) -target_link_libraries(${PROJECT_NAME}_node - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - ${PROJECT_NAME} -) - -add_executable(${PROJECT_NAME}_add_noise - src/noiseNode.cpp -) -target_link_libraries(${PROJECT_NAME}_add_noise - ${catkin_LIBRARIES} -) - -add_executable(${PROJECT_NAME}_save_elevationmap - src/SaveElevationMapAsImageNode.cpp - ) -target_link_libraries(${PROJECT_NAME}_save_elevationmap - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - ) - -add_executable(${PROJECT_NAME}_approximation_demo_node - src/ConvexApproximationDemoNode.cpp - ) -target_link_libraries(${PROJECT_NAME}_approximation_demo_node - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} - ${PROJECT_NAME} - ) - -############# -## Install ## -############# - -install(TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} - ) -install(DIRECTORY include/${PROJECT_NAME}/ - DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} - ) - -install(TARGETS ${PROJECT_NAME}_node - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -) - -install(DIRECTORY config data launch rviz - DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} -) - -############# -## Testing ## -############# -add_executable(${PROJECT_NAME}_TestShapeGrowing - test/TestShapeGrowing.cpp -) -target_link_libraries(${PROJECT_NAME}_TestShapeGrowing - ${catkin_LIBRARIES} - ${OpenCV_LIBRARIES} -) \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_ros/config/demo_node.yaml b/plane_segmentation/convex_plane_decomposition_ros/config/demo_node.yaml deleted file mode 100644 index 6ded383e..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/config/demo_node.yaml +++ /dev/null @@ -1,8 +0,0 @@ -elevation_topic: '/elevation_mapping/elevation_map_raw' -height_layer: 'elevation' -target_frame_id: 'odom' -submap: - width: 8.0 - length: 8.0 -publish_to_controller: true -frequency: 1.0 diff --git a/plane_segmentation/convex_plane_decomposition_ros/config/node.yaml b/plane_segmentation/convex_plane_decomposition_ros/config/node.yaml deleted file mode 100644 index 68790760..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/config/node.yaml +++ /dev/null @@ -1,8 +0,0 @@ -elevation_topic: '/elevation_mapping/elevation_map_raw' -height_layer: 'elevation' -target_frame_id: 'odom' -submap: - width: 3.0 - length: 3.0 -publish_to_controller: true -frequency: 20.0 diff --git a/plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml b/plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml deleted file mode 100644 index fa153584..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/config/parameters.yaml +++ /dev/null @@ -1,34 +0,0 @@ -preprocessing: - resolution: 0.04 # Resampling resolution, set negative to skip, requires inpainting to be used - kernelSize: 3 # Kernel size of the median filter, either 3 or 5 - numberOfRepeats: 1 # Number of times to apply the same filter - -sliding_window_plane_extractor: - kernel_size: 3 # Size of the sliding window patch used for normal vector calculation and planarity detection. Should be an odd number and at least 3. - planarity_opening_filter: 0 # [#] Apply opening filter (erosion -> dilation) to planarity detection by this amount of pixels - plane_inclination_threshold_degrees: 30.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a patch - local_plane_inclination_threshold_degrees: 35.0 # [deg] Maximum allowed angle between the surface normal and the world-z direction for a cell - plane_patch_error_threshold: 0.02 # [m] The allowed root-mean-squared deviation from the plane fitted to the sliding window. - min_number_points_per_label: 4 # [#] Labels with less points assigned to them are discarded - connectivity: 4 # Label kernel connectivity. 4 or 8 (cross or box) - include_ransac_refinement: true # Enable RANSAC refinement if the plane is not globally fitting to the assigned points. - global_plane_fit_distance_error_threshold: 0.025 # [m] Allowed maximum distance from a point to the plane. If any point violates this, RANSAC is triggered - global_plane_fit_angle_error_threshold_degrees: 25.0 # [deg] Allowed normal vector deviation for a point w.r.t. the plane normal. If any point violates this, RANSAC is triggered - -ransac_plane_refinement: - probability: 0.001 # Probability to miss the largest candidate shape. A lower probability provides a higher reliability and determinism at the cost of longer running times - min_points: 4 # This minimum number of points per plane. Controls the termination of the algorithm. - epsilon: 0.025 # Maximum distance to plane - cluster_epsilon: 0.041 # [m] Set maximum Euclidean distance between points to be clustered. Two points are connected if separated by a distance of at most 2*sqrt(2)*cluster_epsilon = 2.828 * cluster_epsilon. Set this higher than resolution - normal_threshold: 25.0 # [deg] Set maximum normal deviation between cluster surface_normal and point normal. - -contour_extraction: - marginSize: 1 # Size of the kernel creating the boundary offset. In number of (sub) pixels. - -postprocessing: - extracted_planes_height_offset: 0.0 # Added offset in Z direction for the full map to compensate for the location of the foot frame w.r.t. the contact point - nonplanar_height_offset: 0.02 # Added offset in Z direction for non-planar cells of the map. (Additional to extracted_planes_height_offset) - nonplanar_horizontal_offset: 1 # Added offset in XY direction for non-planar cells of the map. In number of pixels. - smoothing_dilation_size: 0.2 # Half the width of the dilation used before the smooth layer [m] - smoothing_box_kernel_size: 0.1 # Half the width of the box kernel used for the smooth layer [m] - smoothing_gauss_kernel_size: 0.05 # Half the width of the Gaussian kernel used for the smooth layer [m] \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_ros/data/holes.png b/plane_segmentation/convex_plane_decomposition_ros/data/holes.png deleted file mode 100644 index f997bbe5cde44f8e8aa11078a273d362296d2453..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 350 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 Eg4imfYybcN diff --git a/plane_segmentation/convex_plane_decomposition_ros/data/straight_stairs_1m_1m_60cm.png b/plane_segmentation/convex_plane_decomposition_ros/data/straight_stairs_1m_1m_60cm.png deleted file mode 100644 index cf42ffd2448fb87825a12d922d1058e000bb801d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETvz{)FAsNnZryb-yqQJxA+qlJ{ zaEn9Z9KVV0*srlYbh-1vtk7n2i;D50+}K(=#4hgQ_;6K9b>Y@+5|gTL7oU6Q_EIiUVEXet49asR z9_8rWCcO6X;!v-fBJ+MGXRpnR2g|Cv)vmdK II;Vst0L1)fo&W#< diff --git a/plane_segmentation/convex_plane_decomposition_ros/data/terrain.png b/plane_segmentation/convex_plane_decomposition_ros/data/terrain.png deleted file mode 100644 index 65cfe247f929043833c3d49de1f345a4a17f7adf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 112548 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≶Erua4x&T@gTZvQu7VrH})NTB{tZx;yyNxSwbh&F(RaHy(aknTq>DKji+%{7wE+Zkn6uE}}IcAv^proJq-@)A9Qj zj7RO&go2NV8bw~*WqE-pN&N5yd5e6_^OQ0EujMyLREYDd9rjZVi%1}@y6MY9)}{S3 zZwQ3z>ZYywcem~X*d~*J#}2@sobdVRb4CML!%PCL3KeNOtV0O8=p=Q`>any z57mbe(3+Us|Fr{YX=zupB;VL4-*M{S1_e5xfW`Z!96wG?7c z%nMX~Bt#L*mj81BXugZWE=T5`0H$LO<<6O!E;&^SW2okA2t~PXpK?~8(wC;ft`m-b zO4#VM_cS&C6)XBL)s&P+bu5ORlnOjdBSGf&apl zIxwI9*(Bsyl)szi5K&lG(eoh{&m)^z@WZE#vn$HXXmuf526_b=43#YP{(+Ehvw12t zNGob>{&*6Vy8le&kmjsr*0ln;r+5OgZ?eB$4_Hg+;=7}oFdkAVD412< zsdbT|Dra-hs9Nn^Lu8}MhYE{IJQU@7J=OSn^2ktHMrtUfKM{R&$gsQW^%qCOiRvwR zZbNJ!5Dj>Ub0IhQm4&6t;f!}H11d~+T+eZ6wrAgf=da$rVN`O@n1@QDJ5yaw49>=<`4QUXJ|rdpo1{>B zpfe0GVEv-u#S`e;0CYPS$K5?#IDo6}x}sux-+#YeNZF?~#K>rW@9c_MBnJ|tj3w~w z8TNcd`kYZ!@*&*DYC-{5*Lv2ua@@VVf5zNR#95ejx^#6G2M8Mtx)WnYaBA2o-QMhn zS>lzq=jdN0kSmW%NxjMM$B^Z{On*H*9I=f%eAM%qj0;Tv>$#_(kcGc$Fm$$c|wuG3}xfa95E)JgrG600|5^aPVH?%e7+cE4&OK4j=d554#c zUg~rw!d?jz7U3>rzIFZU&zkE~juzO(jf^uv-jQ=p6!T$}11Zn<;bZfD7aoF3Wa=-e-RM6^P;RV}_{963aVW6t4ZXRzrSR?d#1=JAXL_?eWo$z}6JJ zh}q9>yT3^pym>@NyzyUkVmKJ5hD*q!j1JT)O(gP+cs)BH**{yj4{YEf2p?oqcnRgva98E z>Vw5}e03GA5`3m7ZAfQi$`1~1H>T-rUlJXnP^918*(rNZrlVBwv3?#IywZASH!*%$D=N>l%?)O9bS6O)X(+HP6I{7 zx_uN2xn|i835-QvPpLmNx|w{qS@8%=1_B>QzIXQdm|x=4tw8%03`=U{X)KXhTX@k zFRrGqR-aV+wkU0lHrCm>1eq~TZi5E{c(4jvpskKb-H*Vq?CR`PylBt-y2{E>=0JK4 zz?SZNpV+c5=H{)6-ZjzGoP_=6I2v)!5Xu)v+XmilVbljuiKOcd+hIT1rpH{=mDVM`nSR z`kL}sAT01zoB@m;0)#9p{QXGmLGGGxo$AY0M$wRHDUy0S!%^q*JSj3D@B z$wU1T2!lEEyn8@@py}l-u47pV&3}=VIcAbAQrUZRb;b(Fqhn+XLNW;Vp3Q802>0`= zHN7Em*)=yWgdX>Dh-t5_MSZsRgdG{!$w_T(=qIP%N~0)1EHP7Q=H#5c4`uC**5^p~ zKZ~(ak6PjGR0$M>G6{_M+Y#vB3~W65e&d1nBf=c_XJsH{F`_y!*Y3?``x`nS>7 zDx@)E>896~x3At#DjmPUi4y%l0HV8IsQWg_UH-}IRe#;s*bFBF>#YAoGJQnsDuU5M zMtp9hVeEb|a7~-R7_#wV4$g2)Gba4v8#QA+H@(j8oETQbfM&{lZBc5n_HC~Z>y-sJ znN*m%M<`R~ac(CHlL2HM{`DG{V-TlB`PYj+Ltxozm0r6e8b~JNn_LGV$R22?yPfp@ z*6=noAuzV@1D^gMAGe&Y7qLzt6UK!?E)`;yetqgD1P27rk9=yXkk-~oeNkxe2!PNW ze6*MLY~E*4f>fx2KDA*(25?=vI+24C4^%vsL2bp-+f0k?rL*;_#{;x}tr!U| zhSsmV0bdU(-2B0T(ZjQ;Xw^e7nXzT`dO$E4&=-UTl00QO+(DOp%>lRY4(C)d*nB;H zj(?2-JtI;$P5)|J&gdaPVQ!D!Gh70MJT6bh?WaD_MLTeP*~LN0&wt&l5>}SRM8hfP zq(u3jgpXmLr10d~u;~^lPu|10yvfw!$N5@mWl)BTUEg^=2q^DS+H2e`a8G$19j*brWqc^Qug$Z8#`k0nxoSzp$j|=V}Ft##D87Y=iYM)mlGe8 zi^!4b)s!cC-FFjEe18Cb(dVQhJwd-$NV!m? zv!UfBCC)8p@$)WaHP2;nF7u8j;kmpeRs0e{FYt9h4Lf(-@6*W!);%fcuxtH1EIP~n z(|Q)Z^q1lgzr5Hv3ktYCKNMpQ7#z6TZx`h7F3(~Db)N#ox`*izk94v<=fX2t$bMJT zQ6}8?eO^OMIW>e&YNE3DZCI9hvXsoHk52xMe|#!*^po9h_rJHhN!J{zwunkO{aLtI z>@JafozeDj>NwJc)6XEQ+BZc#UMnsdRPsery2gMssN%N!*n3caSoW;JB_U`~w|aCW zz-=)%8C(nKjHbIElP7_hb@{C;PL4z|U>fgGz_Z0%-nKqf!VIyK4SI{oo8=GcS4i+4 zZ7iUm_8+8t0d+iLvED9@YT@LN&oQZUtr08vbn&KV@PUM(#4VAL(amQ7HZl%S*<)Jn z{qkcNcB;1NE8d8_M2em6gXF^nKeO(ozKHPfkAfRBieJXbWE-3xAntQ3ANkjA(SeEm zNt==>(fE?<<2%p4)YDzr+1Y-k?ZO*!zMOque-^$$Ybt_4j4>x}9KdBX20(Z;=wvNL zTNtLtIoZ|w%-b&*v zMqBIXSv)FTVsg)Y#ziZwwfe?g^iu%XeR@!6o>RKuuZPaA;V$gB{jYt?ucFs@(hD0Y zP>nh!zZ%GXI=9L1YI*%#z(Z-W54zk?+#_zOA0di`&xh?=Eh5245#s#MD%QqZ-y>pv zx#R1YH^aW}tpga6A9uaFFI27Amhv)?o&hhWo)!hL$cHXGiC?4%mXj!=i(vuhv^DAt z=)dO8mgpLF$iJLeaetXE{oOj$q7O~OXu+s{gCBOFqz`3lmT{c0lW@siIwP`ZUPSBs2oN;Y$3h>2NEs^>)j>zImAN zhvq4rH%=d@%5F0xBnjyxCzi-qJrbldP}s^C;*LTK<*}leacf6nzB8h@&!dkPMMBjh z$c|Bb&$*ZW!oWKdfU%D*D7G`MxE<||T(HCi@=Ki|^Ccosb2x4<%TM66up*%UWJFuJ zwo%7&FEETs-%8@}8EF%&<&<_h7`#_k`S%`<_XFs#po%|Ci_r`k2I;9_WpQaZCS=}T zh5bp82y}N~c=dZ-%0ZQ7W>k@;jD8PJEhjC#jtpKhy?VwXcsuDt=H4Bh?$Oq!Bh7ZX znT2cGh#95v)t9s!!hBYxnn{a6UO_-CgO8jiA&}1)^X$w_bC>LaK2n!!FvhGX+J`G* zuc@%v@^8A0@*faqx`6@~7*M;gaDzyg25333D;8*G3J8&z|)2(T$t*E9;Y~%i~c5b6BedQ2s_qA@w zDL;R=I@K_(#OI5HZVEM(W~GGd2{_hJd?%)1REvv$u}88P^j?7 z;M=Uqe9ui}i;{YC^kzWXBHjC`r~7k%>(Az87&tl>tbqE#*zWjFPMS_q5Syv@U4NSts)3Fyia<`7u!9dkIaZB1amBMNtE#=?D6$!051*@ zr`wwDdqrPRZ=LXpM!g^^1n#s=%j+FV`N9AwqiD=cXj1*9NI-2xUu03gW>M7K$cVKL zWnHkH0+h<_`&)|-wzjdr=|uV@1RRV#79?jj;v-v`)lXCE05J#0bD!I&%hvNfi@GKUvoy)7?YnWQx$4lfq`blWT zBIf`_PRuB>(FD}*y?dJ_lZcaL#X~C;OA@jpcCJ~6z5WGJt5i|E1{9;!S(L?f0?3Q zMX#*&tP)JqPnEQnSYA6gOAM0H9=~2JDG99=yHyoA4j5~gAc=Nq5{(D1rT>IZ6%5AW zuDCzX7qy;+X(?kG-5FgysV>~8E}r1I%%z|^-GbMlXu4xuCOG?SNxrAsx=#EhQ7Qxj zBaJ2Bi`0uYW_5-g(HB~lzr)|Ul6x>xI23PVsy;629U8i1Qk;I*fq6=e!|xPJs{>3d z-LLvVD>cOLIUS1>D#`YU>t|iN&aX%>wY$0ua&HV6Qzx*Z8-L*XIzDCVqPBzXZ~Bk9 zDPe6vvPKcA6*`xE%;oHofzbpaXsR@Wbg9WtFZY&OucEF@*10x$pHYf1!kQ|=ri1Pv zF1tl>00*W=PtBaCw@ z4<=*fNDB>;EjBeaO1VWWbex&4*)FFW=B7pQ3|a)o`|6IT@EPZZ7aAme!J+2_Kh9S zoX~grZfv>3cg(y!;TuhE6>^*&)CwQ&4b2W30)T&v23`mZW&i;YfG&` z@xL0q-9$8N^|P)@Dz+`3CdT8hx+@+iB?GW2iWawf^(#}~Z8fFfpT$EpMNV2{B8Yipu;ku*@N+uV z$WhxrteE?lyw$)P{u)tF{!IcRmGagEX*K6hne>YiA5Hco5;L?_0>R(gP_Cv$vBD_= zJQ<&zV_T=5#;K+>{lG2CY^dD!bBX9Q7SWoN3*buq4^}!k-Ge)0Ju1jNBnDKKv%dD3 zQ#E?T@<}$W71xTXveJXx@#R$?UG-QKw$G^^wVf@YeH@8OonN{#DvRKA=@fZl`lLfB zwrrd@I6jvA7Y{nX*zF-???;3ke&d~e6)qm-8f)w62fQ8}D;C1y3y!{0=OW(8*a!&^ z=*A}wPZMTkPy_#4+<%QWA35!?ib4j=jsDE{75%a*JN3Y>dfim(mtMi--W3@`g<$y> z@tPX`%5enbkKi0iN(CJH7rvs;+>qkQVqv>3Ru3F9BVtE|H1HKPAe}zr^aLafb?SU- zJM<^n{yzr(kZOXS33eh7Y&koN&TW|PI)yS;9{}gbjp2R#O= zH+TmP_tPCWy#D=ij@S#|p6U16u9 zSpaxnOY0G18{Fp=DgGL`4x>Ic*AJ43{$MjI`ItPig4*kn?HMZ_-;e!j1pYnV*wcq`Wiiu#IyDXCr4 z%gLZSJn4B;x^(sSnTppB30KT;^+Bxg&&nTm7ll!9fO7vq4eY5&PMjDPQiDRJ9`9IL zZQHX-g_Xn!xgdg=tl96u)#8$y6dxAdP^f zu|NWeuf?Q?I^L+RPaBA-`$ZQz5mBUZr43JV8u=Mr z@Zrx<>k80|FZ1d7Ur9N5lZn)u>@j-0^MXu-z&YPmR*}1V(T?*!4(Aez@-$k+;&#l$ z`3oX#x;%Bi5}HAT4^G<7#dVPWfdfIoc8s;7p{Rd7Z*(^Hx)4Jvu6;b5UKmj1lupFq z4O35YE@#9o*o}*pit9`4LT}pu*f+}mOYAL9>2UzmpBCPvE>Cwlci73H;Q9Rpx-ZB7 zTw@`acgnZL`~!rl&rVn2CHG8!ExJoX33MJ7kl)&li-vupBDJ?)2maavG74h3J)_?+ z2KpNM^xwPiT*%f@Q|N;lJknYl$FSPkr1kZ=xy_Pv;4a{0>lBNAL!%0i`#ygI7Cz2g zWZkRH3xZFLWIsv!_kH0{6~fpg={A&Dc!*xJWRM3UXfP1ut(j?)ohhBdXQ^c81Ih~6 z3n7my*uSD1WXR}-d-nj3Me1bSomxN7guqOK5LcSz?QH?OLA2igkEX8-Yw~^nHV}{y z5RlO&Al;oxN+~H_qZ>xIfOJa3NTs_S(#Yt65~CYNBOr|Cxxc^v@$3z6ICgN4Yu9<6 zpE{A36OAMK4!KQd|KWpfzN9EHdAcPiLnT>cIAPkevdbl=$VW%cL=a9wBv|iVS#fR1 zph*EfO0&{$!Q3)+MJ&Bae)tX2O1HXVgAzG&^lmA)m5QT~qNj4NYoB|ozS#7q`*yNb zVkcGWfO3qKAmDY_khy(kNNaJZm@WnP9@+0!$J7D9fyELF|m%w{?L_6 zelna7JPOn^)0P=OBHwbWZtv5KL)iT>&;UU5C-Vatl? zjOU#i5lkz6t5hUoM6Pkk87&DO{du^8n^5L)G;eU@HYorX^>%4CAXV*coLMGHmOkuQ z0fChx21VDmcAyJQa12wC6>2)%3S6XPKuwA@W8a}Z>w1?}_1&g(E4yc2j=66_=X0)Q z9i4L%4HAOkhDDx2LO7X~)2LqL)6l3)m8}AfQqqN{jVGngFo_dzFzi=3TsOx@eY^L| zAjoxoqn6TzrG_HfaUyYT)jATZ_R@OUt2G5GmFiZ~gu#vctE-7*D+h_r-vVPu zK$q3E)6rEtJ23--SXXn#6!8cosHeOzrWnAao0){h3$3t^v{3*VC!>+_8ka?HW(<-O zXrIKDpzqC%k<$9e3A#RNeMqG&RpirDI0h+Wy_DnB|vAbR@y zzW_$sM{13F_(gi7^rciGcy*0EcG!rYka?@F6%}LT+r?)UkZe3q*d+j8)p*u!T>WwH z6!YvwU z)FOD zzZoP~-JywR=JU(;uREjk5;n7v5$aE6HytPFF~3p2TqHnqAbq`cM;!3SfS&dt!%F{^ zr*T*GVCs0HpMzJpo^)QJ0!DA*Nomp?Nvy$j{%5tx}bT)yF^0Gr^r;uJouA`dYV zY8+{vk#Ilz^yyQs_TxAaN=;|BFinMRRvzE@ctI%c(pZAZwSX^?(PyA`Mwh{Y@=U4X zQUn*S^xci6lwz_EYoC9;^h-`%PZu(f9sV>9)-s9_yp_l;X2nFw4=RppkQ(uky0LAe z)g%)^7D85Ph-r6hR%7SsZVcgl2dI8;EZArJWs|IEz$2m5!JEM)$` z6>>|cYAVAO^0*zp(x&d1w7g3Iu-guFe*H{dy_f-e-MXR8x*~990_9pkxJA}nl@^S> z8VqqU7LcwPfiaus^*%!&VzJtO?UTK>7k?^v8z_I7^Uy*Q6%8KOi7D2);sL}`X&;p) zNaBUD+9Omfih&sx=L`p(^I}t*(&=mqAe^iX@2uxmu{WsT|e+Tsz^7co&gs?y@zoB{|!T|X9@%M z;6?JdLj45wD?P3(pdS9P{Yl@r4AZ?|mk@R?ijT>s0DCcLilI1gbIke_d5?yV;GjStY4Zk%yXKyw-=>$xjTo2!u zYs`z5GAnO*XEA(Dq!>~VR#Ti5zK9c3j66y8SJKH+bsESKEBWDlyv&&AnmdKmz@xOh zeUVJ=tsa|(TfY$!pU=ou{j-|vtwU2MGs6nU$f>zu;&ST~6_W|6tgJYzY$2V@s zg7?r*uFj|xKWvQ22pZFk`eBX_6=4QK%bq0j;a-?IE_%jOcY^4NE1YA%Zfc8fO5{Vj z`0Ke_qR%de8>j?!R9Hi{K(S1zE9zUIxWk#2DYsHSWeCcz3d}ckeO^M8(>c}u^2H{U zuOD{isx{dC5@q;=w1Mh5eau?=cPir(GUD$ZL78T2E3cAW^c-sSQZWYVU892jE((zj zc6-aw8K}QnaPdJaQYkHhMkvtkVV%+1q%( z`(~?<4*J!)!27K{lMbPNI@3CUY_u5%&ZlNY1x_yyNZi}`X)1zKl^4tCC<6Q_ZJz`u zK`~N<>&vePhDdiYhxHZ*0QH!6fKo@^oB$8AaI1Tbwa+9tp!1mRK+lHM?;&_HxD zKMQ!9)%$MTt)M9Z4&DE?oWhj5*V$ptc9z$rY%R5~{)vhek{~d{m70@IxOiOysd<$w zOpg`YwQo&L*TH*`KnVuT0LZUXV+MbaxkqZ^8$)qg5DVdxq% za+ZWl5Mmk;tT;!W=Pwed<2=LJf4fEbP(SJkDYUXtl6I)BMeO1RC^-D>dpwcc8euu- zw&uW(L(Ff)3tKb7GE1;W&Yq34dS?+k#fy4Hh^!N$KV$I$gZ@0lYB9*1uY;phQgNw$B3OuBf*78k0AO)@k#zp5i*wRe4sRLF_ys+j* zP<1j^U%BcwxG$tkOPHCy9Jz9_{BYI4(M88V01kg)%oWMo3cd-A3i$0GTqEga8`ano zK2L52c3uuu>Wp_C2k^q#&*q+Dn}wciGL$lhsji&DlmSa+5$~OCYn~KQ627_{{SiRW zg;IASY+tj1+Y*!p`Oufrd0KbxzcI)_?4m>kBc(7X$LWzAX~a;i@tmJmw*^D)Tsj5< z=kvl=Q|`gSQ~zw(q%9GW<6ETAirn4uDV$Oa3~Ix8Y-8b#N4Hhc3V0BQF;{C%V)l-d zjBTo)Q2{$04>eJ@b-df8MDxbcr}Fr z#t%aTj5}sf#lYwb{*#ekFCA`QY2q1hHFJzS_%<5^0!S++l$N=)-%@3c{12Yrk`b1x z;8DtNvYEh0BDo;yB*9YQ)$mmpgRnfqoV}NV5d#bfMwfW92XUA@vH61M`l>({j4O#I z<#TCS-RHlc0S`ATvWw_kTpacRK(an|%Z!?=Tqj8+2BPzMouF zRiLyOYqySQuNG&zI5Wz8Ag zAVyu5E>dfUEO@9``8VS?fD-TeMx@t@v9{mua@lP0s?8O&deDzoUSYPw@lj3L@|O~K z0OxrH(er?Mtx^~xZSd_$yrP{--#0MBHkoKqC+n+!MmAehcA@2H_muL~;_V&nz?lr? z50Wkebf{eJ|H0tGGSr{>3bB8`RJ7pvx_^ERKE7Ld6SK|;Fp3D6VB@AIP0P}y%JCiC z-^ILOe(W|2eV+l)JA}y}q6fJFsRRIxelT=!aTuHhow3gtFf!!FZmDL`J5}G60<{bY zI%7lmie67uYt9wW6=6M2fUE})v@uf!JOYn?^7^?%_QT`DT?gZ8sK;la8Kb=~`>t}M z5$Wdc>cpUh5Xw_}@Ww4t_?}9o zYh6mq%Arm4gZkWjs@m$56`N?@4OP=BNe)sIHnSM-73~{DbG4?`_gjTtrBwSlRi#5x zg__OxtJLw;lH45!eAavg3VArItNOamedN<0ayO zfFeObw384d_fJR-vS3^=PL^_lRTxzd>mnm6nhA)^vEQx_pZtx61`{rP&SU6Eaj5%8 zA#xs|PG39bi{55X?O*!oO>5Uf;yC*8pMCt0I0Cj(KXac1IZANyR^_V!#0S8*QmgNP zoM5tf#m`{Q?9n5lqrziM(F9+00U*|`jt61#i)q1$!{)AOfw2dxIA1{amOX$8 zuKX6DPUf2WoUx+N)>*HpZN~FeXU#eCfnT{hg7AC^%8sS{*d}oR7b6m~9QVSO<#9z2 z1q0IVMZ%s2%^>vIZLPzt+xV)BEru*=-FyP|^_Mf-yaC^JmtAsZxv5bh;3TNec~BeK zLwrddhzqnUOoRHNN#=!Zqy_{IeKjueO0|9Qq8twrqf$jtZ7avYa&l63alTuC63I$h0qQ%eOo;|J1; zvY{4X%}W8)>Wb&_j3t6R){d|N_>pvLgzwH3{D>7L)$}dZ-$iQyo?sr87`QU~>R!Ee2{madoO4#{*e`RgwwURJmHAM@f)1X?nHIDZgai-ol)%>nmv+O?%cp}p$HCKvb&=B@fdepTy{TG+=&oIj>~_4;?3OC|B+IJm!U!FMIe{uMVR{?Q|7pE zGP}t-REx=EK&C}DDL~cJ`TgtFl4fG(JtN`YL7qeYS(7Egsnxq!BU^IR`zy{tMnagf zzZ}gINX*OD-b_5X1H>p{4ID0%U}fe-yK~V9)pP6GwG*#fQ?le0;$&JRo82L%ssC|) zx|O~XdvNScc?G~SU6(ft-Nwh=!+5vT6`pqATU(gx=m7Jj3WG(~v+>g=R}Ty7wI;3N z-%qw#>Y`#ITAIEUc%s2LfdMXy2BhO@_>9sv#~sl8{K(}H1 zG`CI&O=#DfPLO{3j)s`Pmvh~lHt2F~2fAt`!k>}0jD%XgaQvw)bmI;_}RW2=&m}q$eOR{_Hciv*fs-|e3$#s&Fg85M8J+)0sZRquq}9m zuQm#U=$YT~LtfNvVN?JB79l8kQZ~&-`~ z)CaxgHeE>MPu>&xK1*H!zC)2#)%)e-V%rI}I|`BQ+-SD}pU33`!@~?Yu(M^#ng{Dk zz5N>Y^>smz4jKpfx&g#W0CS1>dE!0T$wzD=d!8xFtm>X%g1ZQ`EvJ$~xAi6`t{h1- z=AKe{lmQQyCmWP2x9Rh)C3!5*n#W;qR-ui~e|_b7lP~dZa(FIynfg&{9{n>HvF}Vq z$2Ri))VA&=JRNmWrDokCq3=w-GImVcpXUN9mL5?w!AQd*?*U%l_n%H3z)m`jucs;S z%zXRoZK1xQcG1>>Aj|4IEO=%}B(MQ)BsEE#G?_bkFn?VQH==pzZ!5qFgR7U^xjNz# zTGb}oH=qlr7|U&*DndDGiiGmwqy|b6{uRW2uJM93BmJ7bjTbH-@+JLWxevFozHmRf zU7T1j>T+Gw`;xXR_nq-i(a)@E-Acl9hK`0gN6W@JqYXNqoP2hICdOW*Sy6$4-``vG zP2k`XZuSdiDpxn0n3{+OVpSfWsA^=2mY3L4Mi8K3%gPiusdxPDh)RxJqs zj>6n(rle@TxnN3zr5bSuFFyActq7sHMi94QXU53DQW2gpI z0Vy#cpu40~)SSi8If4K+Ar*3TWZ%r@LwC)udi_qZx~)dK*`QigKm8eKa_14CQV()y zoI3#EWk9?p>2UY}kfW6VasHyn*d$J@O&IPdVz6P`bmylg7o;vnbGkiCk&K+#KOZLt z)AX(~P3{O<~{VG);AFE1iRyX0EvxP*h0cXOuKvEbPJTvs{NNj$ax3Bx{KY2w&RVL;@ z0y{ybeC<}SZ=6AhBAO3r1s?r8p&|H9_A=v3VAE8U!g~;>xh5U)eN)P`K)giItbUqnK{LEJ-e=zE%grauwSI2m?o=cH{y=u1Q`!^5F@UcPn%f+~UUcdu6pd7{rdbLPOTeZKo3x9 zmyMhEH;F$=z~=V>Wa+`cKV{x`?Pel(Gn0A@jLPEvi)(Mv6n*SR4e{9oW? zTQW2Cc;90^<*dqDw*fU&QoiuRDsv5lxR+B4**j&6_7(pr3+{YHKkhRV*s<`Tep`k5 z{qD6R&(x>NG$Rv}2nkjOZII1y?t?6VnFG3-)Ts7e;xCJDP(jVfcK8#DCbYhR>^nGvL1WMT@cuZ_rgj z8f)w?Qq9j@sDl33Fj1OGHY;U-D)gyVu#MCR;UWd4%^v@?55DZFO>+sb&T3#=FN1e` znINbX_LgjlXxL;u`df80|xWxPmG(E3p|{i2Mtm(!LeRP8U&Gfhr~3$tuy z$#3TCIRv8*4h|AO>73&rt7Lth0leet3Z|`dt_aYF!87yYx;manQJXcY|7w~VsQ7~c z0nI=IuT?1d(X$uW-|*T8!I(V;{s7D%2zL~a7}elMb~6s(3i&%0)^mwNN$)~D^=Z07 zc&FKou@W~fsWKTs?u55K-zMJ)P?(@@W|ATL>4lv%`%%YXxnY?&i(WquzXNPk@0rRQ zb(ZmQDjXBaYtf$fTN|ESQo>|N@Be%xe^j`ixmymKsWZvpJIVPyMfzRH=G&aI1S@z? zQc^q}1ok6>lS1hSSXq!!fv6?#6}8S3*wrRgeU{PNY^I?&SP@Tc`)SPW!T5dEVu!zQ z`K6Em?L6!BzMS}ZAd=jD6h2sUAv$`!5Af8d)3rf5M~ko&Z6a0CNZwM<=zqEi-J14C zVi(W2sTrI=HlSkw-L`uadQ4>H;4Y&e>w@l*Nch<`5orschz3U0plp1ob>&&?FL;Ljv;=`; zS!QbSfhJT zRQQ>ADoXeu7fp1|UR(w&&S#*Az@za7@b>m929fEHr3^o)z?erE5IRkwuR)2W0*z7f zlWkBw;q08E^|W^{EWS^&zOK+3f9>-BwE*Q6wpv2y%+IQTu@;qP#R?#@X`f631;swF zfO0MmQ})h=-i~LTQ<7t9vK;- zi|UPd@|rEwy6ca?7^=G2oBU4*QG}(fc)>WpVA`~!YYiP#h@OYCC*gnj6#uMY$+_=b z?uETI@ac82GXVTB<*eKfZXXWrnx6&q=Q0?TfP$ns?(GaE~VS2_cX)v29T zt8DO~6~7Wh-9iH}x zRkqE;=C%6VFQH~oH21TmQ*=GPnoHh1-M^l+`hAD$TY5dd7S^qp-W^~!!0N|gGiOOO z;aA#is6z1R|kR|q}dp{%;K(cs3hHA!<+w9{lGkV zm0P(jA!gs1SGHKAxq?B{_|w%k(X3f=1_kBaml+<)=0Y66D3Dk^`5fp*(rsk z3}RLCPl02gufz*~OPj#CY&sb|gDq6_Sl<`$HI)}CY(9NL>0R~C#K57@)Hl-j<(BD_DldMBigP`9^K=yQM}%a0lSRMkx8H|dnU-4Yc5K!&Ze z-Mh>@ug%W50g%buM2``g8$Cl8s3u2a=){m=-8kmhFVT;H$W;OZ|?cV&307&^B{`!KYK0)Z0Xdh3MwV< zvcRX+^?oxE^uouqO+C2EOnGGm zCH6GX80q8GpOi?Y$N~7&$W301MkFA+@+Tp5It7b4RHf`*w|a_#7YY4v%B)gn zePXCAZ@vi)B<< z7)>>t@&n^J;tA#Kn0243Pwv^p@{J8V^StMxR$RD0T&yi|JZcb7WvEcv83E4gYV>mS z;4?}QuFtV=Q=_y+KYSp5Kv`^A)~m(MZAHy`&Smexf;b;Y8R_xsGp_pojHxs=5`~4r zd=n5hjfyqX|1^CaB>cUEM7s!Vo}M9$aFH5 zIC$4ewVfrlc24+b_NAUZ3=FSY6q(iUqfg#nqUe{0X4`#e4Fn^gFpT8MP(quy=V}rl zspUg2dV&~yQX(Fq9la%9WFEjOCK#dS=Jeml_ieW=9Ev3g;tuoJRXI6bd&lvvSO&T* zK9ya@*!_=M&e(5TrfVJ65G%&%1dJlcN*l%&H{)P1j7MytxHq3eN2Erk&ALmX+o30FJ(E>>N=gy($6TFA-{QZ8bNBs8?8h zp8J{ZOffkL33Tw+{HnQz-o6g)~B=Y6nK0J}EJF(4;TOmmX zVC;K5GQhE-a6jY=OiJzCR_kx2lHLUzN;x6Og6T`Tou`|a z5wx44oPK?tM}v(JztE9qb7kO~OW#x9^IN#~ZaOnUm6r=fXjl>cri3*qCPr%`T7I`a zz(QR;NEsoLemokTeJwNtJknJ%?NxHZ8C1Ll#5a+#F%Cmh$qE+t3{PAEG2PS^;qU}u z-6z>8HZ<=nG)YNd=zNRGfgkU{>`zKcbR&G2VSad`0}hJcH-|75;|*MI6V4J2^sABk zGGAp8+2_lT2g0BckQ!ZfAeW{mT4r;u_wJ#}F5C2EIT&v6^K(yu-@gUG=sMO)~AQmt5b=$qZ8+Oo$|3fYyqi4n>q5!uroCZw_01-#C zt{*&!<|x3+F4^0kd9C|mlX9Z#PPPQX($l92_ky~PH#fjMw;wrM{`^gJzIJR9eHdek z&Fm}vkPpE88UOM8jMQ-Kbb#x1ede)mRIM@2isK9$wxblGY|qP>*Mq$0VSQFp$cs0< zbkXC@+iP5N@}7LHJRyne9NKVITx9JOU>bbqd3BZl;Ol#Lj>MW|(8>jpwk|$yu9OC( z@2jq%5~c6;g0?;d$>&MT55Gc%Z4KSjWmg`vN*Pg#3N3+Q=9MX*x31@x7X_xAOK z>h*N)Gw0}0;nn3m8MP*wpHUupjFdLa77f|PagTBS80)7~b3VH(&bzU^xSS}FNJWl) z-nh;j2y|Sd?}^Xk=TD`je%V0&l(Ym4NepwXSne z=UL74E!pF{E)>+ijIzt;*c5PLtN=EYDGgjGwFs9|*p5L!#GhJ8GkM*~oLDZ|*z*je zX_=4NTk?oHdh$_MNoXk$r3E1Axt?$aZm7$E4L28;So3AuQiaezym82tDGq+7?7Lld z&Jm4JiusUhp_0yVJo2;l5|X|gJ5vEcfe4aRX=Vmm`y9o0ttW&(@n{nzHn^3lpO znYnI81D8ZMhSRDyF$QwZ(SzCg1Au?ecmxoG`5bf0TiV3I09UyU&o8{h1~CxHo`*Au zqyHeH_i}*29y}_(eB%k&BzL6_sUH8ibIyev>p8SKzP^&5E~XS~9rN82%DxY8zF3Jb z=Z_wA0I*B&(|)^05le0+oX~G%*r+c3icj3wn+<7HE~RSraikOrQ_XUvN6y8?PVcvB z`7>N!T8v5f1SsLw_dR-P9A|{B9X81#A;ifssYtW8u%m^^h5mBLk4d4fPM$n9l7IRa zjPav9f>V*6L(m4iy2b0evUs~e#VGoWW{fGIpQ>thTo#FpS8_-3V7(jPium5(c4v=gZ*iPyW4tUx=gTE0&(X4;gR<|KwXzE~>ox}}Cbt?=2BbE4 z!3fb$TvRpG%xa7A#*ip*5xy%2OTIgzM6Rd)>&l`HB?Oet@rgP`VSf@YlhH)mB1}P` z$}KRW^E~{Od_4e4LjYq}9r~UojwTL1J*`8SW%q3j_=H4>laZiK`R}8}Du5`ju=#?v zHG6kO0DfE5e4%C5xUmTMHB#Yr*j;z%&&?NG+TH?Ama|Izpvi-YZnKb~u~Cmak7^f$ zs7J?-=Cwc7+_1$MRP2z=qAgQPw7bBVsC|%~MZC`J)t_Yc#-*&_?&g(jx`Fu5s~CUg zW4@ZL>J{9^FPt{?(kL>@IC(@ukGmXf#; zrR7Ik?rozk2DTU9tWUn3xaJUD-&o{GiT%OS#^$E~))-&?aa@}Q;JU2J@j+Ln1=!pWsDq!)jVK`M_8-Vkb%+K;o zjSz{Msx+q`zFF)a?(i{LRoeYR5!-um_g_CtuZp|6GmqA81WCO>;1cG<#>P5;C)7zQ zaqOS#-xc+^It=Lt{nq~h2;eJH7($+wZ*eqRzU1&NcIvqjXb+lB_z4jD28_ z5gb4CyI8MdhkwO8VHS2R2Hmhsvu$GZ1mo;a%#~tpyoco`{wMTSAu|7We3N?VaSwUZ7TOrbH^t;HnaK25 z(*J@3G|5ym7fJW)=y-koofH~2K4j?9krr1Lf%i%Mg}>_kEs3ct(g(fdy(JucCd@+K zR|pNvH!!Smqk5O92~E`dxAf`HW%P%DcgsOHPQHiDNcB@AcPgo+ui|J(SU7S#=%O*t zF#FUR@uw0>fOSAk?6fAqBxDcb1TjaLkt=`6#HRF($eXKca0~y|L){CSnSR3Aq;a3k zyZr=HQ?bgRCY3hA`FL3LP)hHkFfF~uS{EN&0uXdaZ|=K=A3<;MkMCT3jvv6I_^o_a zETKOu+?E2Xj9AmrG1E=^4HEZwd6b0I3YumU^_a7wy?6D6*10~`yM1=6=g;LrkObOT zK;siKeIi_CXG>Psca9bO7fS{CW}#m6ij`;})1w=@kI2d?cIb+P3#ImE5*H%wRMkm) zK~H9=%6x{ihkVmnQUA1)y^r)DM4!tc?UoKRtQ+je{bnGrp@8n+Lo2#@?5pv#uft(r z+fC=c(T+1_YlW9#GK}5WLtlBm($ReSEIn(cl~(4M!d?EIO=ny9bpU^Gcm9F)mSN}o zcMBFTHl6zT_wV{cLd*XXRx80ME3j^aYfCTbPO}!vIFg$2eGlH3`gdI#fYjKhjyL;j zpf^a94>W$7*`VC3Cc&a;TAF;F3y14aXZI&69UWr~e~N4KZmv6fS=HXw@7EJVzuY`H z{y{by%wdS&Pl0eJvS$hhni%T9gR916-^#J~7*#TTv^Kne|8|tGWUQVdYMagzr%1Q8 zB6(NP*C#ve_D~-cU?o8#-9MW6a!J_bHw_2TGwYyA^*1HUH}70N0@A0js7|1pUuIg=Wc;kc2yS|xsJ?%tc&(psM9uW0?_B}CBi!2yRf z?oAa=G5ZKDaYw4USf0Pu2VGMz`QMn-s;~pi`!SYv z-K(OA8dmC?zuipi+w{Btg;smFFMrrHSPckH>4G4YA%iC8|9d1B!_trh+^<}DE$`ln ze!!mx?8pdM7h6oIEOr+mc(Lz^rt0yRM z9MJcnMj9l(L`QL5&{>IFZO8g`zJY$FIO#oWdQ0d(NHIb373=b11kh>C`9JIu_Ufyc zIfOPP--dgYfI|L?aMt66v0w({W&a4KCe_jr4zJU~eyR)C(cv^c(~QQuKodQC`}Ec8 zQT;8UJ3PuC^_s}ncq&<3!No77YN!g!#SFr?_REcm zdO<*t(RL0>t<&reTpK4WRAOB=ruj z1p(j*Vs`?hOnXK}WH6whuwkPIjEYZHTb z<|;tFaV`#U2c)BEnZlgXa=)2*y}bRqbqd75|cXb+}-WPT|*w-E`=2%Qzo>>jX`aL3o z6VbS(x1=u=s4Suw293Jah&x&Nq{E~uB_zla`%AL=qi3Gj^nS}dN>8oSW0yCHnuexk z@bCKZ1k;#bJmVU{@8|M*bvj|;@8zHWTk*R?orwZ^G#9{TyKZe|@AgaWX?x(dhaVW2 z&gAE6-j6K3`^!Rj^M6;sB&k>eIV(q8k35;$fi&A<`9xc9x7W6QrAT#nl?4ffjoGur z4u4!0hmRl6h*Ayvhq;(uSq#)!#I0Cv*Ycm0%2^ViR`#82__6}zAC%^u#V~N8M z@HaB(2Uh8j@JlPm#W}s$pNZ%&4`0(yGL8P<-~C|v%%dr1szBrB zD>rHDM6#;9PHIOD#XRVMr1Mkk=x6q=6}6?VBUv*2I|;lfLMTB8y0PD) zzOlKvx%jw0NDQ;^*TG+UqPxr}WqdkN-8<}`vHj~{oUo0!CMNH4OJ|(-b-GRGg8mf5 zRJhR_H_5e0e4ahs-$>aRSX*f0-+zeVttAyofa<4-s|gA081Pb2vB*A?UW(kKnq|x1 zq4lBIdlsS~nrX&BVL`g5y+TXORyBW^X-Z7QRh$y^a`pdCQWoxxp5U4i5no|_#Z*Z2 z_0o*TTQWnulEHPj%$HxxuWi=e*|YmneaIfOHl>bN;2r=4^TIDV=Iu+W`0C$Pqi-aL zBok{4{TyR39G#r1%Qnm(HCi@k)3vU1vNDU|9GQ(gp?9(LU)YaIJ9ZQ@q=y!3fBCm; z=l_8Nhs+8sZcSm_O;J=(`{;EOr3U3nuOZ!4Yrc*tU)6`vm9for}-EVQy zhQ5DJ1hWvF6pXTU%^b5HDfpgW{5<61ll*2b0`}WSqVqd$-NlDPUUS1o#@&A(va41* z33+AosKTnN`Eq{gHpTpsS@@2h_(aO@j<<}CqlPUAl=@eMum!$a^Oz`wRt_XU-e~Wx zJEf41-!3$(tl_i7Oy{+U|HZbhxe)z$%ZU@m42JParyfIDV8IUjIcu*xALA1E28+)H z?L9U|H4}wSS3D)BeMn5razsr>zX(^BX`u!MJNk1@xq5oHRSUe5JUq|Aay<_~?* zPaXx0uF@1YI}SWUT2ILY9N&JWUe;>DQ0V!_TyoPUlh;5dIj8>LUF2{0v<*|KYT|&Z zHuq3|r}g~}QaN%a_U~lM(54-GV+{BMJx2C8YGhfgVMFIiO>rdkZS8TED)UJG?nwa$ zJEr{tLBuL==}nC_D%w`%X^nB+?`NuEA3O59EVj?&{z+N-f_dQG_E%UGO|H(=&%M%f z6C;HDf`NOHhVHBWrQUHRADn1eap`lo)ltk=nG~b$QyL~n^&Ac&p3$bLg00Q_n1<;0 zpRDoWUbZtD&-rAVg04xM_tL>q`P^F}o-d!KR8GwrXr(QatbTZM^?w)Bc}Pu~P)v_) zLERDfM*)*{->0dqD#aG#zf}riM0ef(4@}m}Hrt7CkoU(tlIh8hzIaO=O~b8s0jc%P z*Gt(Sr`~S308v*)aVL!c*}*X%k|h3ak0J>WpsSfGIAT@~}`Nt>i#`h4XU^=?l z*8PF>{(9<5_=ep+-uINf1C3;_(P1iWI<gHf#%1-Aaop z%yUUlz_jbL_j+XlnD2XD!+oqJX!5yYdIvyuLOH+7wMuD1f_O!CZS2hk3W}%Of@*r} zTh=kv&SH7tD}R?w~@#pu0<>f_*u4?IPk{`!3+%zRru&JO$C>TU=D zDCz!s{*>y&q`!Uhv0&Z4jlL#z%k%6OA+PxVU(&0`=p|yNIo`#Hxm)`uD3LU#B}6I3 zozTI3{3U2Iu7hx?_bp7&y4-*^apdgkwogt#qhZFPzTn%pZ(DCOtVGY2S8(X5DsXZ! zy+}yQD`Ng@H|#A3e<(zm(%*=Qm@*W7ApXsSr%dq!SPAgh+`++NPPS#8Q^e2|tAh3m zp|kxlc^LD{QAcqZ|8wld{lGe~bNbuF17C5P$m*v7lFS_CS^nR=(2xAU{=>tQnd+qi zx#}6{=P4ww$qdGPRgL}`6hU$@Z-7G3+bomlsj5&#q_%e}q_dILWAu-JANRg%*XCk; zYb3+4OWLN(>A?u*UVP#`+J2ffaB_8xie||Zxfmb3Iy-0_zgSj8h&uX>l}eqL&m50* zcbZ!{KfI^P8%(0@qo6Z-=hbzc&dB`Q{jYpKN*iQ;NkY0aA9{ zU4kZ^+3ZaqWqpfNxz*MNGfCevC6jk+tEga+#U}pp!GRB{B)2>=N-&N(yF2k|ugc^J znH?rlT%L*ZHO8Tr=+fihA|JeeT&d-;-76CfIiKmB%=Vdjym^Lz0jWeQa4ZUW?Ycir zqfQcBc%#@?MLT%PnG789-wb^4E?o_++YfaXOgaLobq`o0emId92=H9|JEw72H$TVu z*Z$9YP^&Jf&7JzM*iK{F&{HE-pV}KjgDqDLB_iUA{I9HCyPer*Qq188!e`^Zu-0BLl~I2>`Pe5GocpFD?Hhool!S9Zw3S zDbqDn0(_gXfLT&oNzeZ~h(s&SAvI7(pgSgi75|;S_VJx})Xt6W9Dct}hzHu3;o3Rw z#MgRRzBe0_(&_1HW&zXe+7%sE4^CY{4#oY8w`vas(mzI`Di;USIip1m&$|(&xhg$MNoKoe= z^ym7lL+dr9=(g3Lb}OR!Sz3jTIGY1H)tjBp#@)_ZI^NY&LV+f1AHvBM|mDr@Yh*xO( z`BMb}v$9Bf8PQ`yZWVbVw)VqReMQ3NWN7!NunrKRSv<~ASDroBB!e#hE^HjDo%a7q zx(dIh+PAL~g5+qB+9ajBd!SO%-CY9_2ht6ryGvR|*Ju!=K|)Fy0!j=Sh)SpLdEVdo z6VB(H`@XJkem%25_wsYT@3^d6{KN9Ba`~)yheFb)K{bc1T0>aOff~(uIpZqSc3DgY zmxndj+Jc`@Sr0xUF&$Iljd4EqqS3 zu!S1tlI4(l$zD@>#c*bURs5|-P^#x}Uu+yC+&KH^$@(?fDBY}C?aPCbC+3ekAM&ga z>*DYjBEw0OtefCAc(5k3mE+b53C-gFj_vWd9cq(|Yy&S4C0Ve1)xyt5UN+K2{FDhl z-*nskh;$gB+Y%o9xIO0dyL$sDu;%4tOLY!2>VJFab7g5sTe3#n?^!HBW$Hm{6y?UNVgl66$+k#iQ8Lz@>t@c1BUJ1wZeF;BRj%3n;Q4TxSTW+3uDg#!Iw0GFTGE z8!6`vEo?x{{PAUg2|JWxUV<}Y0todh=9 zb=_$+nf@Rcv$~5rjOsfreDt(BdXB>s%MhgJaV>8VTR02*`0%H`Eyl{nJgV(5qeFG^ z^{hnoPCH@IR9}_WfS;3d0^L@J3PB~JS7G$+48A&v(dn!eXIa7Y4KrqKd47IAlp;-m zy-ddBtJ2(sRpOtQ&~0k-wD@uT^7*~W35UOuGqjPu7bK7?CeURBNffv1GLVI$FnaM& zy<54Hp?%UY!J_tA)JAi9N0U@?pXsOL7T%mhFOnz*L_1zsnP|8YGz^v0q#{>cxbwEoV+H(<1Da3I}L@TS|I z`A0Dfc_t2)x711F--unqut~hY{w7u4qI;1x7E(&l<68 zw&qY2+=`K>W8UQ?AJI#re1Qk@SB^x$LqCRTKv&|+a##KBMStHL|2LaZ)~N~=Fuh=i z6vF3-E^qG(b7;Q0s6`?@hv}-+uz=%3<9PmUTuso@NKd z5@oDEj9RE?M+%R57ZMXjG8CrKxd#8LpL&c^s*{(+w+k*R<8$*#Xk2m!YROlNl_0hS zHtXU9q`KeV{Dh-y$Gjlx?KPUKsk2wf&Lm$4d^mIrQT%FC-$AQu$HMN{$WgpgY!rdc^f1#Gx6i{B1iG#B4$Od zAENJ$;Fz^OBvPKiKFExRml%I}mx5*$2O`Z@25dBqkm;mXf{zeyj~c;)M3l6BTsnCF zhNb*0al-MvEDzGslC|CU=wiYf`Zpy|C{#!_5(#9_E4X5&=GQ9v8wO^lY4a|v%WX6# z%?xMF@w~}HKF;$OrgbP01)^*EGwTEDw|UI+kg1w(ECEU6NzLREGsP^-%<^H{Hs;S~ zd$=BT2cG{DuF-j;Dn+s!xt{#6?7K!mvBgYIJK5H^eh$1EPl}Iw@%M;@%4HW_boKFy z^e46v(Qlair`RPu_p=(dr0UGaV^hKMq~9wFS5Atso*IHO+SxbceV5{xjQpLKhpmE| zZZDx^rs-+?{YFuddFN1vS!Tt_CzjBeVY%me-j>3r z;`U}R8l7IXv*XwOn^H^bZ}R0{W0haBkEi|QerYLKkJWSMM+hZnn{o=UDS^Ff?`~6aFX5mrz}yLF zLPJdqm$1`8U0m_inXIu&l{K$XfW@aZp3@-PksHzonm+^%B3uz`otQo`-Wr@4>`a$L z?xnX=2$ij!te4}D@{Vqjb(2Hel3YX;IO?UHVe+IC7n!;BM|Xt5CZkk-BWuqZ>M<{G zQd~GwqegIPy)@&mhtx$iqrpkTmgHqB2h|TR`mOWA8j7iq-HZ0 zbf(w*5AnASZX<;d3MtC_SD0trsBppux(r9G)zhM%j=t4^dXCWX5T`=lWFYQ_q|OJ5 zd}1%|ab-3R64j#0xEw?on1GPEp=ly5@KQ}s6mUmS^!WXSFTr;) zP*=l!=yfx~Ve`V^5nKnWbFhWJeDye$FTQm539vZ>6JF1ahsNs15P1%I?xWYeB}O8O z6VACNrB?DNye5g{vs&M5<~YA@fy}t}aML57N5w#p;cDO*_7(7Y*!65m5A>_GY|^o5_gUYFK~Hik=BV5a3&zU2c4Pjuv)>VwPhKmeI0Il7ld55svN zVmxgzLKmtCRfrP`i9*O52>jw7m9*WBKtM$Pg(2=f1X`2Ndr4vVmlB>+rFq4TANe0u z3yp?8fgCBlHBW)dG7H!)OS4h~1hqEw2pAm_iy|8+({l1IwIJQQg*_06bDlqo&2LkJ z?=k0hy$BE2tY3Wt%=R}=MM~6S9>}ml5|j`k6}9=qAYM*3gT4<|FQN&xqE5^)Hh^EjXB%e_4;Z(mxGb zx<)O(^wHY~O-XeC8IJ^@ zL;Fgc!QF?DzbYVl%6Z_OIzm=!Xt#KP%by9_Mr|)ko@NY4_-uF2DdxE)b0f)z_yG1U z@3L>Ei|C7hD!ox%1eW!?>NX=oq|Ga&z^KOhbxX)~@p;Is$w2>)!fOEhHwXC}MSiqv zmei+;28^%lWxxXKtWWkt`PziNN>lvgg160cbFXoPZo_WZ{r%U5#=)o&BWLx_k3vEg z7wrMd?_zNkWwlROS8lfwCEX}lG51sM$E7Wcd=ozX6C^r6grU%~nmZ+HwB4s49Da&7 z>smSRBKoH!p_66iem9pD41(Tfp6bSa71wn|MkE&;EUL}(=j7&2)r^M^#u{*Wlj}!j8lUDiS1;L;UW__oxWGK3}(1!@rMPVN#6!nUs zeY5#55jZF(?_U#Fe2!gWimi>#a_iYpdu+D}?^*NfkzzMXYAZgNmHa$5e9P!L{>ObfN)lpOg4-B!D~>XWyi2qAnq(#F(8fV}T9>wD)#uC^ zps4__*U!{njQsH5lX_<~aB3#uGWTfP)7GA6Eu(w)?Rqv*%ZxNl#^=oYS|#xvNp<@i z6SHgQ7~Xr>h@b-B4;)O#;KHT+ZL`?Dmt>&KD+3FuF-g$^Iry|!&aow}=~wXy9W-ul z!mSqzg8)Tq$t7-BDQ`bHacN$n(G@OP&n^o$F1xU%JrrWuW86@}0A z0mXtvbX#El{)7>`{ldV0(x&P;S-jf;ciZed1Yq_SDU2PZ9BzJk0Ok?(OngC_+w};1 z6Mr5;W)nbiK?@*7j zOrayuBPAtu@$<_;b#$=ghIXh4Xk|S_w$$h|B)_*cOx{X-%T(vX*fOvC$mG*oy(OG7 z0u2|!o2@jZlmE_ zk*nJkyuFXjoK3FfRB#|d!qS({%si31J-9paEANOX(yxgnq@SmRk7l80aQjZhGjpB-G014UcXY=nnR0lMD?%Vb3+8!}neJN9i!|SNT!oj8?VM zd%+T;7qO7P6e0>vWBug1_h>tUw@JUmQo~%Ea~hP4;J;6=Ae3u~H=wI8Sa`>_tYf@; z>T=YJ$a=Bk=36-#(pZlG4U}eZoZ$VYggp7j*|3zAN^VKO`Bl(+-Zn6>@snt|vMfZV z^m{{shczg%lxKirH`u&68%}6YKp#?&h{26#3@=47tdH$%E=hdYr-ell<@X0Sm*dDDvXRNov*LCPwo4DF{Sp z6oc4nJ2l}fGu5T?LW~pBe;;2|+oLVrq}noS3`bG&n$E=6nxs*)rGGz_l$JKLtu?2! zQkZQsH$sG;F{a|W@TeC`tz0MYJ;E{x7JM?QqMd_%LJ|G;f6h02wL0OD-e&#nB>GoN z6RA)`YaCnaL_JT({x62ynrq#@F$a2ZR|14SR^(q?+7uTi8wp3OBnp@w0`;{ z^f^=nv!p| z6hl%}o<`KDeIm8U25-DF;{CAud)yZCp=$u1P3Q|rc+G0R-m-WowgAPCWar?=vYPb1 zya=ejI8^bfCR(QdY*VtD{!_02-${nSIYYX>KP5RiJB}{Db+a#;?I7HjApPz{T9YHg z$c|pc@N011SXc0-Rz-={#B|lMmwwR~)XNo{1>eCVJtY_tfu4N7YZM71&!}o1f;-8; z0v9ZCH1xwhrSZwnWGf~&Ys~n}qxgInVX2E)qHiGn&9}DA0c}m0j^-aXLIofIS$n?N zzd2=NXzZv9-95!}P9Ly#e!@zf4S>s1gpOlV9bzg3RNNNqrBBvF%jHob;HbFvFT<++ z^2HH(LB&AB|`E+ki#ceNS{;EUtp*vd6vAc!;LKN>9WhZWF`-A`fZ^>R18o#(dHHhVVvAm1A zu~J2q^KGXAx_kYje94Mxm@A^p=3Ahp`jIrdN4T4(8rL>8=#tXuj$g6K9P)Zys>2;e zvF|8w{kl;a)2|FYPgGy)KU-&4wC0gQ1^&16bjcI{5L)`hWkP4+3{r| zU|MZu^fIRn5=2x_zj}@AhbNTW-ihM0?bx3`Xx-(tQU9B; ze$Aci`3ZAOZ75gQAVz0q>EC7q+n+L(l))>l3>c$3$t0+*kRch)e(qBH%ER6S)3cbv zs!EPL!b=+4dU&;kxF?GDOp~-}BN-WTF6mqN{k1hrh(U@$^=wBg);Vccm(Zhz}j zKdBHlV|qKp`Re3{{;WmXXS5jE1Q--tes?5=S)=(d;YFcKo|Xc@WRl}$cddH$52(6< zAT}R3b8)N%}N-U#J-)5~> z?WutHb7xv^b#ArdL1XheC7OTS@}`+7og(1{`@Mbl#^4Z5ZGB{LszpO0$hYVd(`ZaQ4EyRZQLI%@&)#(qX-*8_T_!ZEY5@<1P6fU*pUtmV8H4xb2G#|Tfey-Kx zqg%E{^Ks78uWNXD`%6AP4e^_*(B6^hmy6V&v%~FYV#%SmQBtM`{d{Xs=cKU)j~p3W@` zzWLeLnCnkv&nu|(neD~1k5n^bVb<9@7*&S>Br?U;F-~diY(jTTZe(SQta^Bs5(4^t$zDvNuTv`_~Yt3 zI{~XS8W}&JE=%s|RQgP@oV(>MzIoKuS$wR+;s8^^FX{IomLuO(|N0`f+{{PB!1lrH zAwJd%Y8$K)gZt>&U&_y?2v^7Cgwi4(5wp{x&-1=TG05AL#IG(Jd6eG;K7$skPrxbW z9YI|l-#%=@{gB8jl#l0bA==5wnRX*HA(M%_iKstIapbWmb4pGbKfx(_b7>1O|5zHQdF4QP+E_JVz!0;NUqLU-IE z)|_S5lxelTF=jZ1mR-L<^9$3!A5@-6khtF|a=emv848;B5gN5dh8js>;>(in(P=iv zlYw!a`uQOX^Dd(8(??L9zzoDB-4-V>r_!6NxDg2$$y zuN{Z?4}PxJgl85@-I1*9CqVw<0s7=IIsuzXSO&hV_HAgy<3EbON6vo;v2HiY9|I!0 ziT96&GVk4^iFg53G8pNP!wG9F(&XS7maR2HEcre)RYXabvC>d0$}1uN4qg{&h`X29 zuCu$G|6JM?jK8K>er>zNzi-~fdt*@h-u*|qh+5~&j@$E37hvLmL`ni@SCdt%$RmanD-_DEkpIDcraAOsD zUhL!fQlJ6Z4$dP^GWVEL%qTSotD|k=2KA|c@Z6^(vP6+5VA+&_ThvD4QfS5;IcVNP z{C`kk-E^`2P;_}z{P36cK9a?Y5Tb8e55nUJmG^VQ-i`LKQB>DvceRJAP07n5>fptUs+&MfgW>bU&eB*W) z*B_POjjKibFCcMWSj5_Bk40<_8|M8CYDES<08|@FN4J6TWj0aQ&9O;PX*o`|TH6v7 z>0fZvtD?MWsOX5#;8}$7=Tohqn7op~5CN2m9=VKBqp$AJdDXZt&18o(E?pC7evnnB zWcKIY9s-~Ramx7LucRonlJTKfe)n%_%7XwZWnOrqwc(9cLi3X7_+i3MVl>G_=ix%^ z6xgJl-dvhgtdD=j7*@Mo7?{RGo|&M05`GMX-Blo`P_x)n9WV6RoOh{8my43Q@)r44 zQdhZO@G|0ogM?SYIEhn8Ji_YL3~cL0P$VU84`;fUwaiCN;YQ2pZeaRG$!Wb+Q1EQP zI~*S;Lu0!4u&`k0=J+F|g%c7eG`iAv?iK$$E>(0o_GR2&hKa423%X@mNU`*fM({jo zp-*G7S~;L8qE&Tx%wuQ%)9j^prsqhA>dVQZV)aq{-2Z*ozXvpb^rwTe5Wa-tubWH)ok9r4&^GrK zFnu|6Tk3*iHW9uR<0g$b3vDr&=4yX+sP>Z2j}_=P!&zhVU#Of{-NF7A`Oz(8l&;9f z{;2PzQl#3;pqJ2Mr(HnBO7Pt}3P`yyG&J0?Yvw|@;FeohKPk(J+hdPD{Zkm{Vn#Ir z%-qal*!OYa)QPSw_q9I!6=g`u4oyYGjw7P$4nM{=iF1$$jXKuiaxw_c{qWu=?sdGx z5pKPy160EQVeYrLx9qNbmFY{+9}Dy1Xz}Ot1g30YJQYkpQiqW81X#V27#{Qf2Rd=+ z6s#+jRvbfB@Y4(gQwF~-z0nHzi%pN$5`2}D{c^>*G{sfJ7}t@28{L1H*f6eV4c$Fd zQ}nlM?5Q~X z-{DDEbeCA1%6rCIM-7kv2@869mr(&7PNLkgU5mMeh&jMgqq-glj6qt(FZs9EoaJRX zZN%|%OHG@DzkKLAVhX6Jh8=}k{@zP(+E#3X4O?{^HK~B5f{RNV&V8ScUXi~yEjaQ* z{|raXu2s3`7m#y~Ewd5;SBquWKn|cT8)|8Ukv&9?$Usl1Apv4hzZpS>GhMfITdE-L zgZp+%4z;QuQPy`M%_czbC6Hedi2zjZmNrf)%3uhE3W49~)}K#E+JoZ!+ zL)f)90%?y^DOl9=TE4i^QHr!pE@5kT1!?-4Tepo`*O~1nwP{F#oA97e7uq%Y)x&PV zDz!%5(062P8}KMsgqst=>@RqNZ^7L)hv|GF-rMnbVdpiT>d&)3iO6b_bGEXVX_tNm zBwAJ(T(NbjwDY_k5a=2+GZ~~bc@7a77@Q8(5vf(+gV4JBUO?7Ezvm))qsy`C`vBev z5(!-k{P&A|=o|SE4Je6Ml=OB7dAAkk;y~-Umo`)6vr^;(SPZW;WhkZyj9A9%_Ak+yGdQgO^1h)?DR&7;mkkWHbJtxS=fVtUOE zEt#ZUS*auaL6fO?&zAJ$ym?C9nZ{FbQeP*wDlNuOZ1$-x(06i@onZcSS0Wi4YR&%^ zo=Pl3pGkoLqqsJ+3`gu4gI~QJ+Tn+m^%|JKQKjXbgwns@+}U8B64dmMwexd!#hvaC zJH_sl4{a8@+D-*oAn%wsr58ALO;@gd2Fi7#Bw|D>OqG8bb=ArLj9h&Ii$$!Pi?qZc zXxiIfg9q<3+}VA@f6H-N+5EY!<|%y!byWR|p*%vc;%Y9J zb@NCtPtYRn;jnd+Ui;P?C=_6{3=FA@qe=)1*nEBpyUHjZcjqb4lc+ zt*Iv59A=&#Jkghl0wQLkWhCbJ1Cv(S*kEkVvCp6OP(W7N$zRXbOo<3XHF%ug)E~W3 z%WCq%*n+UPs!%J3U5!qg zmBs;(eNg3H;uDfW0G+Hwc56Xnjp#MOU#}zuM(IM!k;sJUAfUzc9Jqj<^_}C*Fq(5n ze95sQ02dCj;w+tpI_xU6zCyV*KJh{C=WoS81ZKMY3BEssisBreKNMDBDsR0e1>fL- zg4qq}0UpPEsmf-3G14RO*7r`Bs6Ka+yFGYGLFyEHrM*3UatX#z6(@-~snG6*Oh zrj~!e++k(yUJy@c!au>~=iBG1>uO)H$}!>cm)Ps^`yPs~s}vpG`GwmSW8y2W1cTY~ zF?`rMO|(U1zxZ?TT3pu4u+uDuYp9# z93?6*=(o^5D*Kx@OAC1OGVX`;pXAChHtwY>M}~&&G7L$;N}|s;_mw7$#3O*1%R^6O z?O%4D!ZT%BdfpLI@+^q!I%u+SL7@WXZq zp`m%#PxyC>bwS7ngFd*wMkeKb{rrsSei;ePTTyEcB?#h+7Qze}g{oxcF&|!%@&{Fc@IywiN>B1;x!4zry6NslS*bBc(`SFj)ui$lC)d5_kmHlqb`5n^7b9x%! zAzSbj>wfcjz`olb6qq4COP%`z@nh@P)z~e6BdB({9YgXkccMFEpKtDE-Fe8A(eA}1 z-8fuH<)5cLtIrFl{9&JUn*EZ4TBPjRT(g$#*qq+3RIWjV$>x_8Ph<@50y9oemX>Oq zX&@u2F(oTdeR=sQ;Sabfy%lybR{izGw5eQBuSCtV^3!)@s&=kV?4_Znt;tafY>>Oz_DR*{=D4%4wX?WWb+#q9xX zE$4JlIO44N^U{{___x*9W*felUTQ(m7n2W0{^MD|8inYxy_t5bu$uC2vI{?mF|9pwLI(|0ObvR4@A!3t$WXYzKBmF5Yw98PWoB_#|=b2}^3BMo+P%v|!vBftE3!QN?km0`(~&|o+r z{X9tj!CdvfRljNHjD55H_4e?Fp7m-iw)#S6d&{Fxrq8zLX~G(-ZwkB2POzIl3Y}}F z`lf-9JZEAd-T5+d}JwVzg%~LtUX=;zQ`k>%KjC4QLKx52%n~W-nu6 zBvB@43n3qy4tfDSEA%0YL$p$ZPWp{+ro3&Ji~W$#5@?%{$eco-EQH1LnxfLGpu|7< z=XaRA%ZO&XCHa3ifBzT4>Zb zZja%calUyTZO2?r5k~uKwb_!CyGp*<^Sa*}`-4N-G0|Q6)V)UEj9M*ciL@;8g_o$f zb^ax#hU}kn&nP87f2I%bA^dS5vb%)e%`!yovG5=(Qs;!7t)3{T>v$Mu`&o-i!<iMY5E{&!{eX>u0Q7+q;+aI?h*?9P`+00kx zJF8+@vc9K|BMwP5EnWxiS<)|#fgOaYRAe6F&*pt%rWj(0m-@DR)$XpkGWxytP^vMq zMgq)ZiRZYAijNUproXzBOx|2S{mS@Sopq{k#7L{@LMv_$?^L4E(L8}_F*>~x{^~d6 z_2ii_7}5K)Ffi+v`}mQoW8$uQNlYw&YC%T1iyTh|zZX~sXT1ft}w5!dt`|}s0{FA=WPwBsZw-Qfy?{p1rgB?Q_P{!-K zQ(s5yd%aj)dU8?WO8T>*){zPFhHo~Q56JJ^Gbu0N|D4E*Jq#$hBA{Rbv=|&JC1A$= zD>g%wPKw>c?aE9wpP6bG2;1P}G3W{6kY2#=-je@hJ|&N6R6EutXhzCUEUGD%O*nc4 z*7U*6vevXVqaoZwIPVKvWug$X@bOTK9rdpjtH$%Y?DIQ~>7e91Yw|Q0iTd*gZF@0} zH`Pu9B;Bt@t#~w*iIrgcg#}elO&=$wy^6__2+3Y@@!Hpr=qjjuvn;eJK$DOqq@qdF z{4!-iTfOU(@b~8PWIp2Fvnv^mFPiL%Qupg>qg>Ga0W0dkmiJ~=^}7x1yX4nZ*ahR- zYnB)Tlf%Zz2i-ELu~oB8(v$_OG%99ksQH|u$C^G#uq!q~m4pG})1Wpb0ln}(p?B51 zPY+|{Y)PsB9Fnz60@yE92y*l#2vp^e$g+8tHa)SW-=~fmz3PVM1Yqn%jw-%K3JvW) zx-E8)f2psUIpMpv^KOTKya~S7o!^Oqx)zg~e-A(iT?8Xu^`MAe(@1q09W^_x^iwRx>Qagy}8Ml$+zL!^L~~xRn7vYm8ENXe(|u zB!a)jMBQB_^Pi^8dmLZ!W7b3&zE(e2r-BxwXNsdLVWPVdgNs^(#tVNM+_~Fdtah`q z2g7{OkAA!fN5#f`Lr>n2US6tb>Fx49a z2X0Xjh`aEvhF3Do*7b+lj;8!6s`MA!CL2b?bT0ZnI|Z7$b^dX8jF@$O9a4%R-oH)S z|2hvNW5-h6j4R%(o%UA{m>G4=;0G2QRDQWFh%hgSmo>gTI9!X_>%bIab%tyBgC|R$ zWh}E>SdRO`8YjHJ)S?I}V8fYLjQR~#isp;1|E#oVzlNT$K1{1#T6b4!Zh@}Z0+E*4)V4JPO7P-t8c%|-` zLt}3Ph*Ip~jco0O4;x%Pi0ffOHt6m9B)<7b|83n0GtwHQ9G*RsvjTthBk6|C{+e{G z`pJ~(w9m~pnm0t{#HnX!wo8o#_Q1hdwYjwDu)9oB#ha`SYgclP;h>gU;Xdyvh;*ta g`e0c+1#i3!b+ -#include - -#include -#include -#include - -#include - -#include - -#include - -namespace convex_plane_decomposition { - -// Forward declaration of the pipeline -class PlaneDecompositionPipeline; - -class ConvexPlaneExtractionROS { - public: - ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle); - - ~ConvexPlaneExtractionROS(); - - private: - bool loadParameters(const ros::NodeHandle& nodeHandle); - - /** - * Callback method for the incoming grid map message. - * @param message the incoming message. - */ - void callback(const grid_map_msgs::GridMap& message); - - Eigen::Isometry3d getTransformToTargetFrame(const std::string& sourceFrame, const ros::Time& time); - - // Parameters - std::string elevationMapTopic_; - std::string elevationLayer_; - std::string targetFrameId_; - double subMapWidth_; - double subMapLength_; - bool publishToController_; - - // ROS communication - ros::Subscriber elevationMapSubscriber_; - ros::Publisher filteredmapPublisher_; - ros::Publisher boundaryPublisher_; - ros::Publisher insetPublisher_; - ros::Publisher regionPublisher_; - tf2_ros::Buffer tfBuffer_; - tf2_ros::TransformListener tfListener_; - - // Pipeline - std::unique_ptr planeDecompositionPipeline_; - - // Timing - Timer callbackTimer_; -}; - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h deleted file mode 100644 index 53006225..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/MessageConversion.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Created by rgrandia on 14.06.20. -// - -#pragma once - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace convex_plane_decomposition { - -CgalBbox2d fromMessage(const convex_plane_decomposition_msgs::BoundingBox2d& msg); -convex_plane_decomposition_msgs::BoundingBox2d toMessage(const CgalBbox2d& bbox2d); - -PlanarRegion fromMessage(const convex_plane_decomposition_msgs::PlanarRegion& msg); -convex_plane_decomposition_msgs::PlanarRegion toMessage(const PlanarRegion& planarRegion); - -PlanarTerrain fromMessage(const convex_plane_decomposition_msgs::PlanarTerrain& msg); -convex_plane_decomposition_msgs::PlanarTerrain toMessage(const PlanarTerrain& planarTerrain); - -Eigen::Isometry3d fromMessage(const geometry_msgs::Pose& msg); -geometry_msgs::Pose toMessage(const Eigen::Isometry3d& transform); - -CgalPoint2d fromMessage(const convex_plane_decomposition_msgs::Point2d& msg); -convex_plane_decomposition_msgs::Point2d toMessage(const CgalPoint2d& point2d); - -CgalPolygon2d fromMessage(const convex_plane_decomposition_msgs::Polygon2d& msg); -convex_plane_decomposition_msgs::Polygon2d toMessage(const CgalPolygon2d& polygon2d); - -CgalPolygonWithHoles2d fromMessage(const convex_plane_decomposition_msgs::PolygonWithHoles2d& msg); -convex_plane_decomposition_msgs::PolygonWithHoles2d toMessage(const CgalPolygonWithHoles2d& polygonWithHoles2d); - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h deleted file mode 100644 index 704ad73a..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/ParameterLoading.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// Created by rgrandia on 10.06.20. -// - -#pragma once - -#include - -#include -#include -#include -#include -#include - -namespace convex_plane_decomposition { - -PreprocessingParameters loadPreprocessingParameters(const ros::NodeHandle& nodeHandle, const std::string& prefix); - -contour_extraction::ContourExtractionParameters loadContourExtractionParameters(const ros::NodeHandle& nodeHandle, - const std::string& prefix); - -ransac_plane_extractor::RansacPlaneExtractorParameters loadRansacPlaneExtractorParameters(const ros::NodeHandle& nodeHandle, - const std::string& prefix); - -sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters loadSlidingWindowPlaneExtractorParameters( - const ros::NodeHandle& nodeHandle, const std::string& prefix); - -PostprocessingParameters loadPostprocessingParameters(const ros::NodeHandle& nodeHandle, const std::string& prefix); - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h b/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h deleted file mode 100644 index e3596562..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/include/convex_plane_decomposition_ros/RosVisualizations.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -namespace convex_plane_decomposition { - -geometry_msgs::PolygonStamped to3dRosPolygon(const CgalPolygon2d& polygon, const Eigen::Isometry3d& transformPlaneToWorld, - const std_msgs::Header& header); - -std::vector to3dRosPolygon(const CgalPolygonWithHoles2d& polygonWithHoles, - const Eigen::Isometry3d& transformPlaneToWorld, const std_msgs::Header& header); - -visualization_msgs::MarkerArray convertBoundariesToRosMarkers(const std::vector& planarRegions, const std::string& frameId, - grid_map::Time time, double lineWidth); - -visualization_msgs::MarkerArray convertInsetsToRosMarkers(const std::vector& planarRegions, const std::string& frameId, - grid_map::Time time, double lineWidth); - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch deleted file mode 100644 index 6f7053b6..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/launch/convex_plane_decomposition.launch +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - diff --git a/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch deleted file mode 100644 index d592db55..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/launch/demo.launch +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plane_segmentation/convex_plane_decomposition_ros/launch/save_elevation_map.launch b/plane_segmentation/convex_plane_decomposition_ros/launch/save_elevation_map.launch deleted file mode 100644 index 4197e474..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/launch/save_elevation_map.launch +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/plane_segmentation/convex_plane_decomposition_ros/package.xml b/plane_segmentation/convex_plane_decomposition_ros/package.xml deleted file mode 100644 index fac0c52b..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/package.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - convex_plane_decomposition_ros - 0.0.0 - The convex_plane_decomposition_ros package - - Ruben Grandia - - MIT - - catkin - - roscpp - grid_map_core - grid_map_ros - grid_map_cv - grid_map_msgs - geometry_msgs - convex_plane_decomposition - convex_plane_decomposition_msgs - tf2_ros - visualization_msgs - - grid_map_demos - - diff --git a/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz b/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz deleted file mode 100644 index 0d306212..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/rviz/config_demo.rviz +++ /dev/null @@ -1,194 +0,0 @@ -Panels: - - Class: rviz/Displays - Help Height: 0 - Name: Displays - Property Tree Widget: - Expanded: - - /Global Options1 - Splitter Ratio: 0.45271122455596924 - Tree Height: 1658 - - Class: rviz/Selection - Name: Selection - - Class: rviz/Tool Properties - Expanded: - - /2D Pose Estimate1 - - /2D Nav Goal1 - - /Publish Point1 - Name: Tool Properties - Splitter Ratio: 0.5886790156364441 - - Class: rviz/Views - Expanded: - - /Current View1 - Name: Views - Splitter Ratio: 0.5 - - Class: rviz/Time - Experimental: false - Name: Time - SyncMode: 0 - SyncSource: "" -Preferences: - PromptSaveOnExit: true -Toolbars: - toolButtonStyle: 2 -Visualization Manager: - Class: "" - Displays: - - Class: rviz/MarkerArray - Enabled: true - Marker Topic: /convex_plane_decomposition_ros/boundaries - Name: Boundaries - Namespaces: - "": true - Queue Size: 100 - Value: true - - Class: rviz/MarkerArray - Enabled: false - Marker Topic: /convex_plane_decomposition_ros/insets - Name: Insets - Namespaces: - { } - Queue Size: 100 - Value: false - - Alpha: 0.10000000149011612 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: elevation - Color Transformer: GridMapLayer - Enabled: false - Grid Cell Decimation: 1 - Grid Line Thickness: 0.10000000149011612 - Height Layer: elevation - Height Transformer: GridMapLayer - History Length: 1 - Invert Rainbow: false - Max Color: 255; 255; 255 - Max Intensity: 10 - Min Color: 0; 0; 0 - Min Intensity: 0 - Name: GridMap - Show Grid Lines: true - Topic: /elevation_mapping/elevation_map_raw - Unreliable: false - Use Rainbow: true - Value: false - - Alpha: 0.6000000238418579 - Autocompute Intensity Bounds: true - Class: grid_map_rviz_plugin/GridMap - Color: 200; 200; 200 - Color Layer: plane_classification - Color Transformer: IntensityLayer - Enabled: false - Grid Cell Decimation: 1 - Grid Line Thickness: 0.10000000149011612 - Height Layer: elevation_before_postprocess - Height Transformer: "" - History Length: 1 - Invert Rainbow: false - Max Color: 255; 255; 255 - Max Intensity: 10 - Min Color: 0; 0; 0 - Min Intensity: 0 - Name: FilteredMap - Show Grid Lines: true - Topic: /convex_plane_decomposition_ros/filtered_map - Unreliable: false - Use Rainbow: false - Value: false - - Alpha: 1 - Class: rviz/PointStamped - Color: 204; 41; 204 - Enabled: true - History Length: 1 - Name: Query - Queue Size: 10 - Radius: 0.10000000149011612 - Topic: /convex_plane_decomposition_ros_approximation_demo_node/queryPosition - Unreliable: false - Value: true - - Alpha: 1 - Class: rviz/PointStamped - Color: 245; 121; 0 - Enabled: true - History Length: 1 - Name: Projection - Queue Size: 10 - Radius: 0.10000000149011612 - Topic: /convex_plane_decomposition_ros_approximation_demo_node/projectedQueryPosition - Unreliable: false - Value: true - - Alpha: 1 - Class: rviz/Polygon - Color: 245; 121; 0 - Enabled: true - Name: ConvexApproximation - Queue Size: 10 - Topic: /convex_plane_decomposition_ros_approximation_demo_node/convex_terrain - Unreliable: false - Value: true - Enabled: true - Global Options: - Background Color: 255; 255; 255 - Default Light: true - Fixed Frame: odom - Frame Rate: 30 - Name: root - Tools: - - Class: rviz/Interact - Hide Inactive Objects: true - - Class: rviz/MoveCamera - - Class: rviz/Select - - Class: rviz/FocusCamera - - Class: rviz/Measure - - Class: rviz/SetInitialPose - Theta std deviation: 0.2617993950843811 - Topic: /initialpose - X std deviation: 0.5 - Y std deviation: 0.5 - - Class: rviz/SetGoal - Topic: /move_base_simple/goal - - Class: rviz/PublishPoint - Single click: true - Topic: /clicked_point - Value: true - Views: - Current: - Class: rviz/XYOrbit - Distance: 7.742486953735352 - Enable Stereo Rendering: - Stereo Eye Separation: 0.05999999865889549 - Stereo Focal Distance: 1 - Swap Stereo Eyes: false - Value: false - Field of View: 0.7853981852531433 - Focal Point: - X: -3.113455057144165 - Y: 1.4824542999267578 - Z: 3.337860107421875e-05 - Focal Shape Fixed Size: true - Focal Shape Size: 0.05000000074505806 - Invert Z Axis: false - Name: Current View - Near Clip Distance: 0.009999999776482582 - Pitch: 0.3057960569858551 - Target Frame: - Yaw: 2.410000801086426 - Saved: ~ -Window Geometry: - Displays: - collapsed: false - Height: 2032 - Hide Left Dock: false - Hide Right Dock: false - QMainWindow State: 000000ff00000000fd0000000400000000000002b8000006e8fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b000000b000fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed0000033300000185000000b0fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000006e000006e80000018200fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f00000375fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d000003750000013200fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e1000001970000000300000e7000000060fc0100000002fb0000000800540069006d0065010000000000000e700000057100fffffffb0000000800540069006d0065010000000000000450000000000000000000000bac000006e800000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 - Selection: - collapsed: false - Time: - collapsed: false - Tool Properties: - collapsed: false - Views: - collapsed: false - Width: 3696 - X: 144 - Y: 54 diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/ConvexApproximationDemoNode.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/ConvexApproximationDemoNode.cpp deleted file mode 100644 index 3447091f..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/src/ConvexApproximationDemoNode.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// -// Created by rgrandia on 24.06.20. -// - -#include - -#include - -#include - -#include -#include -#include - -#include - -#include -#include - -const std::string frameId = "odom"; -std::mutex terrainMutex; -std::unique_ptr planarTerrainPtr; - -void callback(const convex_plane_decomposition_msgs::PlanarTerrain::ConstPtr& msg) { - std::unique_ptr newTerrain( - new convex_plane_decomposition::PlanarTerrain(convex_plane_decomposition::fromMessage(*msg))); - - std::lock_guard lock(terrainMutex); - planarTerrainPtr.swap(newTerrain); -} - -geometry_msgs::PointStamped toMarker(const Eigen::Vector3d& position, const std_msgs::Header& header) { - geometry_msgs::PointStamped sphere; - sphere.header = header; - sphere.point.x = position.x(); - sphere.point.y = position.y(); - sphere.point.z = position.z(); - return sphere; -} - -float randomFloat(float a, float b) { - float random = ((float)rand()) / (float)RAND_MAX; - float diff = b - a; - float r = random * diff; - return a + r; -} - -int main(int argc, char** argv) { - ros::init(argc, argv, "convex_approximation_demo_node"); - ros::NodeHandle nodeHandle("~"); - - // Publishers for visualization - auto positionPublisher = nodeHandle.advertise("queryPosition", 1); - auto projectionPublisher = nodeHandle.advertise("projectedQueryPosition", 1); - auto convexTerrainPublisher = nodeHandle.advertise("convex_terrain", 1); - auto terrainSubscriber = nodeHandle.subscribe("/convex_plane_decomposition_ros/planar_terrain", 1, &callback); - - // Node loop - ros::Rate rate(ros::Duration(1.0)); - while (ros::ok()) { - { - std::lock_guard lock(terrainMutex); - if (planarTerrainPtr) { - const auto& map = planarTerrainPtr->gridMap; - - // Find edges. - double maxX = map.getPosition().x() + map.getLength().x() * 0.5; - double minX = map.getPosition().x() - map.getLength().x() * 0.5; - double maxY = map.getPosition().y() + map.getLength().y() * 0.5; - double minY = map.getPosition().y() - map.getLength().y() * 0.5; - - Eigen::Vector3d query{randomFloat(minX, maxX), randomFloat(minY, maxY), randomFloat(0.0, 1.0)}; - auto penaltyFunction = [](const Eigen::Vector3d& projectedPoint) { return 0.0; }; - - const auto projection = getBestPlanarRegionAtPositionInWorld(query, planarTerrainPtr->planarRegions, penaltyFunction); - - int numberOfVertices = 16; - double growthFactor = 1.05; - const auto convexRegion = convex_plane_decomposition::growConvexPolygonInsideShape( - projection.regionPtr->boundaryWithInset.boundary, projection.positionInTerrainFrame, numberOfVertices, growthFactor); - - std_msgs::Header header; - header.stamp.fromNSec(planarTerrainPtr->gridMap.getTimestamp()); - header.frame_id = frameId; - - auto convexRegionMsg = - convex_plane_decomposition::to3dRosPolygon(convexRegion, projection.regionPtr->transformPlaneToWorld, header); - - convexTerrainPublisher.publish(convexRegionMsg); - positionPublisher.publish(toMarker(query, header)); - projectionPublisher.publish(toMarker(projection.positionInWorld, header)); - } - } - - ros::spinOnce(); - rate.sleep(); - } - - return 0; -} \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp deleted file mode 100644 index 3d622df7..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionNode.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h" - -#include - -int main(int argc, char** argv) { - ros::init(argc, argv, "convex_plane_decomposition_ros"); - ros::NodeHandle nodeHandle("~"); - - double frequency; - if (!nodeHandle.getParam("frequency", frequency)) { - ROS_ERROR("[ConvexPlaneDecompositionNode] Could not read parameter `frequency`."); - return 1; - } - - convex_plane_decomposition::ConvexPlaneExtractionROS convex_plane_decomposition_ros(nodeHandle); - - ros::Rate rate(frequency); - while (ros::ok()) { - ros::spinOnce(); - rate.sleep(); - } - return 0; -} diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp deleted file mode 100644 index 04c6f2e1..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/src/ConvexPlaneDecompositionRos.cpp +++ /dev/null @@ -1,187 +0,0 @@ -#include "convex_plane_decomposition_ros/ConvexPlaneDecompositionRos.h" - -#include -#include -#include - -#include -#include - -#include "convex_plane_decomposition_ros/MessageConversion.h" -#include "convex_plane_decomposition_ros/ParameterLoading.h" -#include "convex_plane_decomposition_ros/RosVisualizations.h" - -namespace convex_plane_decomposition { - -ConvexPlaneExtractionROS::ConvexPlaneExtractionROS(ros::NodeHandle& nodeHandle) : tfBuffer_(), tfListener_(tfBuffer_) { - bool parametersLoaded = loadParameters(nodeHandle); - - if (parametersLoaded) { - elevationMapSubscriber_ = nodeHandle.subscribe(elevationMapTopic_, 1, &ConvexPlaneExtractionROS::callback, this); - filteredmapPublisher_ = nodeHandle.advertise("filtered_map", 1); - boundaryPublisher_ = nodeHandle.advertise("boundaries", 1); - insetPublisher_ = nodeHandle.advertise("insets", 1); - regionPublisher_ = nodeHandle.advertise("planar_terrain", 1); - } -} - -ConvexPlaneExtractionROS::~ConvexPlaneExtractionROS() { - if (callbackTimer_.getNumTimedIntervals() > 0 && planeDecompositionPipeline_ != nullptr) { - std::stringstream infoStream; - infoStream << "\n########################################################################\n"; - infoStream << "The benchmarking is computed over " << callbackTimer_.getNumTimedIntervals() << " iterations. \n"; - infoStream << "PlaneExtraction Benchmarking : Average time [ms], Max time [ms]\n"; - auto printLine = [](std::string name, const Timer& timer) { - std::stringstream ss; - ss << std::fixed << std::setprecision(2); - ss << "\t" << name << "\t: " << std::setw(17) << timer.getAverageInMilliseconds() << ", " << std::setw(13) - << timer.getMaxIntervalInMilliseconds() << "\n"; - return ss.str(); - }; - infoStream << printLine("Pre-process ", planeDecompositionPipeline_->getPrepocessTimer()); - infoStream << printLine("Sliding window ", planeDecompositionPipeline_->getSlidingWindowTimer()); - infoStream << printLine("Contour extraction ", planeDecompositionPipeline_->getContourExtractionTimer()); - infoStream << printLine("Post-process ", planeDecompositionPipeline_->getPostprocessTimer()); - infoStream << printLine("Total callback ", callbackTimer_); - std::cerr << infoStream.str() << std::endl; - } -} - -bool ConvexPlaneExtractionROS::loadParameters(const ros::NodeHandle& nodeHandle) { - if (!nodeHandle.getParam("elevation_topic", elevationMapTopic_)) { - ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `elevation_topic`."); - return false; - } - if (!nodeHandle.getParam("target_frame_id", targetFrameId_)) { - ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `target_frame_id`."); - return false; - } - if (!nodeHandle.getParam("height_layer", elevationLayer_)) { - ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `height_layer`."); - return false; - } - if (!nodeHandle.getParam("submap/width", subMapWidth_)) { - ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `submap/width`."); - return false; - } - if (!nodeHandle.getParam("submap/length", subMapLength_)) { - ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `submap/length`."); - return false; - } - if (!nodeHandle.getParam("publish_to_controller", publishToController_)) { - ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `publish_to_controller`."); - return false; - } - - PlaneDecompositionPipeline::Config config; - config.preprocessingParameters = loadPreprocessingParameters(nodeHandle, "preprocessing/"); - config.contourExtractionParameters = loadContourExtractionParameters(nodeHandle, "contour_extraction/"); - config.ransacPlaneExtractorParameters = loadRansacPlaneExtractorParameters(nodeHandle, "ransac_plane_refinement/"); - config.slidingWindowPlaneExtractorParameters = loadSlidingWindowPlaneExtractorParameters(nodeHandle, "sliding_window_plane_extractor/"); - config.postprocessingParameters = loadPostprocessingParameters(nodeHandle, "postprocessing/"); - - planeDecompositionPipeline_ = std::make_unique(config); - - return true; -} - -void ConvexPlaneExtractionROS::callback(const grid_map_msgs::GridMap& message) { - callbackTimer_.startTimer(); - - // Convert message to map. - grid_map::GridMap messageMap; - std::vector layers{elevationLayer_}; - grid_map::GridMapRosConverter::fromMessage(message, messageMap, layers, false, false); - if (!containsFiniteValue(messageMap.get(elevationLayer_))) { - ROS_WARN("[ConvexPlaneExtractionROS] map does not contain any values"); - callbackTimer_.endTimer(); - return; - } - - // Transform map if necessary - if (targetFrameId_ != messageMap.getFrameId()) { - std::string errorMsg; - ros::Time timeStamp = ros::Time(0); // Use Time(0) to get the latest transform. - if (tfBuffer_.canTransform(targetFrameId_, messageMap.getFrameId(), timeStamp, &errorMsg)) { - const auto transform = getTransformToTargetFrame(messageMap.getFrameId(), timeStamp); - messageMap = grid_map::GridMapCvProcessing::getTransformedMap(std::move(messageMap), transform, elevationLayer_, targetFrameId_); - } else { - ROS_ERROR_STREAM("[ConvexPlaneExtractionROS] " << errorMsg); - callbackTimer_.endTimer(); - return; - } - } - - // Extract submap - bool success; - const grid_map::Position submapPosition = [&]() { - // The map center might be between cells. Taking the submap there can result in changing submap dimensions. - // project map center to an index and index to center s.t. we get the location of a cell. - grid_map::Index centerIndex; - grid_map::Position centerPosition; - messageMap.getIndex(messageMap.getPosition(), centerIndex); - messageMap.getPosition(centerIndex, centerPosition); - return centerPosition; - }(); - grid_map::GridMap elevationMap = messageMap.getSubmap(submapPosition, Eigen::Array2d(subMapLength_, subMapWidth_), success); - if (!success) { - ROS_WARN("[ConvexPlaneExtractionROS] Could not extract submap"); - callbackTimer_.endTimer(); - return; - } - const grid_map::Matrix elevationRaw = elevationMap.get(elevationLayer_); - - // Run pipeline. - planeDecompositionPipeline_->update(std::move(elevationMap), elevationLayer_); - auto& planarTerrain = planeDecompositionPipeline_->getPlanarTerrain(); - - // Publish terrain - if (publishToController_) { - regionPublisher_.publish(toMessage(planarTerrain)); - } - - // --- Visualize in Rviz --- Not published to the controller - // Add raw map - planarTerrain.gridMap.add("elevation_raw", elevationRaw); - - // Add segmentation - planarTerrain.gridMap.add("segmentation"); - planeDecompositionPipeline_->getSegmentation(planarTerrain.gridMap.get("segmentation")); - - grid_map_msgs::GridMap outputMessage; - grid_map::GridMapRosConverter::toMessage(planarTerrain.gridMap, outputMessage); - filteredmapPublisher_.publish(outputMessage); - - const double lineWidth = 0.005; // [m] RViz marker size - boundaryPublisher_.publish(convertBoundariesToRosMarkers(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId(), - planarTerrain.gridMap.getTimestamp(), lineWidth)); - insetPublisher_.publish(convertInsetsToRosMarkers(planarTerrain.planarRegions, planarTerrain.gridMap.getFrameId(), - planarTerrain.gridMap.getTimestamp(), lineWidth)); - - callbackTimer_.endTimer(); -} - -Eigen::Isometry3d ConvexPlaneExtractionROS::getTransformToTargetFrame(const std::string& sourceFrame, const ros::Time& time) { - geometry_msgs::TransformStamped transformStamped; - try { - transformStamped = tfBuffer_.lookupTransform(targetFrameId_, sourceFrame, time); - } catch (tf2::TransformException& ex) { - ROS_ERROR("[ConvexPlaneExtractionROS] %s", ex.what()); - return Eigen::Isometry3d::Identity(); - } - - Eigen::Isometry3d transformation; - - // Extract translation. - transformation.translation().x() = transformStamped.transform.translation.x; - transformation.translation().y() = transformStamped.transform.translation.y; - transformation.translation().z() = transformStamped.transform.translation.z; - - // Extract rotation. - Eigen::Quaterniond rotationQuaternion(transformStamped.transform.rotation.w, transformStamped.transform.rotation.x, - transformStamped.transform.rotation.y, transformStamped.transform.rotation.z); - transformation.linear() = rotationQuaternion.toRotationMatrix(); - return transformation; -} - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/MessageConversion.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/MessageConversion.cpp deleted file mode 100644 index 5194bfe0..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/src/MessageConversion.cpp +++ /dev/null @@ -1,143 +0,0 @@ -// -// Created by rgrandia on 14.06.20. -// - -#include "convex_plane_decomposition_ros/MessageConversion.h" - -#include - -namespace convex_plane_decomposition { - -CgalBbox2d fromMessage(const convex_plane_decomposition_msgs::BoundingBox2d& msg) { - return {msg.min_x, msg.min_y, msg.max_x, msg.max_y}; -} - -convex_plane_decomposition_msgs::BoundingBox2d toMessage(const CgalBbox2d& bbox2d) { - convex_plane_decomposition_msgs::BoundingBox2d msg; - msg.min_x = bbox2d.xmin(); - msg.min_y = bbox2d.ymin(); - msg.max_x = bbox2d.xmax(); - msg.max_y = bbox2d.ymax(); - return msg; -} - -PlanarRegion fromMessage(const convex_plane_decomposition_msgs::PlanarRegion& msg) { - PlanarRegion planarRegion; - planarRegion.transformPlaneToWorld = fromMessage(msg.plane_parameters); - planarRegion.boundaryWithInset.boundary = fromMessage(msg.boundary); - planarRegion.boundaryWithInset.insets.reserve(msg.insets.size()); - for (const auto& inset : msg.insets) { - planarRegion.boundaryWithInset.insets.emplace_back(fromMessage(inset)); - } - planarRegion.bbox2d = fromMessage(msg.bbox2d); - return planarRegion; -} - -convex_plane_decomposition_msgs::PlanarRegion toMessage(const PlanarRegion& planarRegion) { - convex_plane_decomposition_msgs::PlanarRegion msg; - msg.plane_parameters = toMessage(planarRegion.transformPlaneToWorld); - msg.boundary = toMessage(planarRegion.boundaryWithInset.boundary); - msg.insets.reserve(planarRegion.boundaryWithInset.insets.size()); - for (const auto& inset : planarRegion.boundaryWithInset.insets) { - msg.insets.emplace_back(toMessage(inset)); - } - msg.bbox2d = toMessage(planarRegion.bbox2d); - return msg; -} - -PlanarTerrain fromMessage(const convex_plane_decomposition_msgs::PlanarTerrain& msg) { - PlanarTerrain planarTerrain; - planarTerrain.planarRegions.reserve(msg.planarRegions.size()); - for (const auto& planarRegion : msg.planarRegions) { - planarTerrain.planarRegions.emplace_back(fromMessage(planarRegion)); - } - grid_map::GridMapRosConverter::fromMessage(msg.gridmap, planarTerrain.gridMap); - return planarTerrain; -} - -convex_plane_decomposition_msgs::PlanarTerrain toMessage(const PlanarTerrain& planarTerrain) { - convex_plane_decomposition_msgs::PlanarTerrain msg; - msg.planarRegions.reserve(planarTerrain.planarRegions.size()); - for (const auto& planarRegion : planarTerrain.planarRegions) { - msg.planarRegions.emplace_back(toMessage(planarRegion)); - } - grid_map::GridMapRosConverter::toMessage(planarTerrain.gridMap, msg.gridmap); - return msg; -} - -Eigen::Isometry3d fromMessage(const geometry_msgs::Pose& msg) { - Eigen::Isometry3d transform; - transform.translation().x() = msg.position.x; - transform.translation().y() = msg.position.y; - transform.translation().z() = msg.position.z; - Eigen::Quaterniond orientation; - orientation.x() = msg.orientation.x; - orientation.y() = msg.orientation.y; - orientation.z() = msg.orientation.z; - orientation.w() = msg.orientation.w; - transform.linear() = orientation.toRotationMatrix(); - return transform; -} - -geometry_msgs::Pose toMessage(const Eigen::Isometry3d& transform) { - geometry_msgs::Pose pose; - pose.position.x = transform.translation().x(); - pose.position.y = transform.translation().y(); - pose.position.z = transform.translation().z(); - Eigen::Quaterniond terrainOrientation(transform.linear()); - pose.orientation.x = terrainOrientation.x(); - pose.orientation.y = terrainOrientation.y(); - pose.orientation.z = terrainOrientation.z(); - pose.orientation.w = terrainOrientation.w(); - return pose; -} - -CgalPoint2d fromMessage(const convex_plane_decomposition_msgs::Point2d& msg) { - return {msg.x, msg.y}; -} - -convex_plane_decomposition_msgs::Point2d toMessage(const CgalPoint2d& point2d) { - convex_plane_decomposition_msgs::Point2d msg; - msg.x = point2d.x(); - msg.y = point2d.y(); - return msg; -} - -CgalPolygon2d fromMessage(const convex_plane_decomposition_msgs::Polygon2d& msg) { - CgalPolygon2d polygon2d; - polygon2d.container().reserve(msg.points.size()); - for (const auto& point : msg.points) { - polygon2d.container().emplace_back(fromMessage(point)); - } - return polygon2d; -} - -convex_plane_decomposition_msgs::Polygon2d toMessage(const CgalPolygon2d& polygon2d) { - convex_plane_decomposition_msgs::Polygon2d msg; - msg.points.reserve(polygon2d.container().size()); - for (const auto& point : polygon2d) { - msg.points.emplace_back(toMessage(point)); - } - return msg; -} - -CgalPolygonWithHoles2d fromMessage(const convex_plane_decomposition_msgs::PolygonWithHoles2d& msg) { - CgalPolygonWithHoles2d polygonWithHoles2d; - polygonWithHoles2d.outer_boundary() = fromMessage(msg.outer_boundary); - for (const auto& hole : msg.holes) { - polygonWithHoles2d.add_hole(fromMessage(hole)); - } - return polygonWithHoles2d; -} - -convex_plane_decomposition_msgs::PolygonWithHoles2d toMessage(const CgalPolygonWithHoles2d& polygonWithHoles2d) { - convex_plane_decomposition_msgs::PolygonWithHoles2d msg; - msg.outer_boundary = toMessage(polygonWithHoles2d.outer_boundary()); - msg.holes.reserve(polygonWithHoles2d.number_of_holes()); - for (const auto& hole : polygonWithHoles2d.holes()) { - msg.holes.emplace_back(toMessage(hole)); - } - return msg; -} - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/ParameterLoading.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/ParameterLoading.cpp deleted file mode 100644 index 3fac5d4c..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/src/ParameterLoading.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// -// Created by rgrandia on 10.06.20. -// - -#include "convex_plane_decomposition_ros/ParameterLoading.h" - -namespace convex_plane_decomposition { - -template -bool loadParameter(const ros::NodeHandle& nodeHandle, const std::string& prefix, const std::string& param, T& value) { - if (!nodeHandle.getParam(prefix + param, value)) { - ROS_ERROR_STREAM("[ConvexPlaneExtractionROS] Could not read parameter `" - << param << "`. Setting parameter to default value : " << std::to_string(value)); - return false; - } else { - return true; - } -} - -PreprocessingParameters loadPreprocessingParameters(const ros::NodeHandle& nodeHandle, const std::string& prefix) { - PreprocessingParameters preprocessingParameters; - loadParameter(nodeHandle, prefix, "resolution", preprocessingParameters.resolution); - loadParameter(nodeHandle, prefix, "kernelSize", preprocessingParameters.kernelSize); - loadParameter(nodeHandle, prefix, "numberOfRepeats", preprocessingParameters.numberOfRepeats); - return preprocessingParameters; -} - -contour_extraction::ContourExtractionParameters loadContourExtractionParameters(const ros::NodeHandle& nodeHandle, - const std::string& prefix) { - contour_extraction::ContourExtractionParameters contourParams; - loadParameter(nodeHandle, prefix, "marginSize", contourParams.marginSize); - return contourParams; -} - -ransac_plane_extractor::RansacPlaneExtractorParameters loadRansacPlaneExtractorParameters(const ros::NodeHandle& nodeHandle, - const std::string& prefix) { - ransac_plane_extractor::RansacPlaneExtractorParameters ransacParams; - loadParameter(nodeHandle, prefix, "probability", ransacParams.probability); - loadParameter(nodeHandle, prefix, "min_points", ransacParams.min_points); - loadParameter(nodeHandle, prefix, "epsilon", ransacParams.epsilon); - loadParameter(nodeHandle, prefix, "cluster_epsilon", ransacParams.cluster_epsilon); - loadParameter(nodeHandle, prefix, "normal_threshold", ransacParams.normal_threshold); - return ransacParams; -} - -sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters loadSlidingWindowPlaneExtractorParameters( - const ros::NodeHandle& nodeHandle, const std::string& prefix) { - sliding_window_plane_extractor::SlidingWindowPlaneExtractorParameters swParams; - loadParameter(nodeHandle, prefix, "kernel_size", swParams.kernel_size); - loadParameter(nodeHandle, prefix, "planarity_opening_filter", swParams.planarity_opening_filter); - if (loadParameter(nodeHandle, prefix, "plane_inclination_threshold_degrees", swParams.plane_inclination_threshold)) { - swParams.plane_inclination_threshold = std::cos(swParams.plane_inclination_threshold * M_PI / 180.0); - } - if (loadParameter(nodeHandle, prefix, "local_plane_inclination_threshold_degrees", swParams.local_plane_inclination_threshold)) { - swParams.local_plane_inclination_threshold = std::cos(swParams.local_plane_inclination_threshold * M_PI / 180.0); - } - loadParameter(nodeHandle, prefix, "plane_patch_error_threshold", swParams.plane_patch_error_threshold); - loadParameter(nodeHandle, prefix, "min_number_points_per_label", swParams.min_number_points_per_label); - loadParameter(nodeHandle, prefix, "connectivity", swParams.connectivity); - loadParameter(nodeHandle, prefix, "include_ransac_refinement", swParams.include_ransac_refinement); - loadParameter(nodeHandle, prefix, "global_plane_fit_distance_error_threshold", swParams.global_plane_fit_distance_error_threshold); - loadParameter(nodeHandle, prefix, "global_plane_fit_angle_error_threshold_degrees", - swParams.global_plane_fit_angle_error_threshold_degrees); - return swParams; -} - -PostprocessingParameters loadPostprocessingParameters(const ros::NodeHandle& nodeHandle, const std::string& prefix) { - PostprocessingParameters postprocessingParameters; - loadParameter(nodeHandle, prefix, "extracted_planes_height_offset", postprocessingParameters.extracted_planes_height_offset); - loadParameter(nodeHandle, prefix, "nonplanar_height_offset", postprocessingParameters.nonplanar_height_offset); - loadParameter(nodeHandle, prefix, "nonplanar_horizontal_offset", postprocessingParameters.nonplanar_horizontal_offset); - loadParameter(nodeHandle, prefix, "smoothing_dilation_size", postprocessingParameters.smoothing_dilation_size); - loadParameter(nodeHandle, prefix, "smoothing_box_kernel_size", postprocessingParameters.smoothing_box_kernel_size); - loadParameter(nodeHandle, prefix, "smoothing_gauss_kernel_size", postprocessingParameters.smoothing_gauss_kernel_size); - return postprocessingParameters; -} - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp deleted file mode 100644 index 8cd1b72e..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/src/RosVisualizations.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include "convex_plane_decomposition_ros/RosVisualizations.h" - -#include - -namespace convex_plane_decomposition { - -geometry_msgs::PolygonStamped to3dRosPolygon(const CgalPolygon2d& polygon, const Eigen::Isometry3d& transformPlaneToWorld, - const std_msgs::Header& header) { - geometry_msgs::PolygonStamped polygon3d; - polygon3d.header = header; - polygon3d.polygon.points.reserve(polygon.size()); - for (const auto& point : polygon) { - geometry_msgs::Point32 point_ros; - const auto pointInWorld = positionInWorldFrameFromPosition2dInPlane(point, transformPlaneToWorld); - point_ros.x = static_cast(pointInWorld.x()); - point_ros.y = static_cast(pointInWorld.y()); - point_ros.z = static_cast(pointInWorld.z()); - polygon3d.polygon.points.push_back(point_ros); - } - return polygon3d; -} - -std::vector to3dRosPolygon(const CgalPolygonWithHoles2d& polygonWithHoles, - const Eigen::Isometry3d& transformPlaneToWorld, const std_msgs::Header& header) { - std::vector polygons; - - polygons.reserve(polygonWithHoles.number_of_holes() + 1); - polygons.emplace_back(to3dRosPolygon(polygonWithHoles.outer_boundary(), transformPlaneToWorld, header)); - - for (const auto& hole : polygonWithHoles.holes()) { - polygons.emplace_back(to3dRosPolygon(hole, transformPlaneToWorld, header)); - } - return polygons; -} - -namespace { // Helper functions for convertBoundariesToRosMarkers and convertInsetsToRosMarkers -std_msgs::ColorRGBA getColor(int id, float alpha = 1.0) { - constexpr int numColors = 7; - using RGB = std::array; - // clang-format off - static const std::array, numColors> colorMap{ - RGB{0.0000F, 0.4470F, 0.7410F}, - RGB{0.8500F, 0.3250F, 0.0980F}, - RGB{0.9290F, 0.6940F, 0.1250F}, - RGB{0.4940F, 0.1840F, 0.5560F}, - RGB{0.4660F, 0.6740F, 0.1880F}, - RGB{0.6350F, 0.0780F, 0.1840F}, - RGB{0.2500F, 0.2500F, 0.2500F} - }; - // clang-format on - - std_msgs::ColorRGBA colorMsg; - const auto& rgb = colorMap[id % numColors]; - colorMsg.r = rgb[0]; - colorMsg.g = rgb[1]; - colorMsg.b = rgb[2]; - colorMsg.a = alpha; - return colorMsg; -} - -visualization_msgs::Marker to3dRosMarker(const CgalPolygon2d& polygon, const Eigen::Isometry3d& transformPlaneToWorld, - const std_msgs::Header& header, const std_msgs::ColorRGBA& color, int id, double lineWidth) { - visualization_msgs::Marker line; - line.id = id; - line.header = header; - line.type = visualization_msgs::Marker::LINE_STRIP; - line.scale.x = lineWidth; - line.color = color; - if (!polygon.is_empty()) { - line.points.reserve(polygon.size() + 1); - for (const auto& point : polygon) { - const auto pointInWorld = positionInWorldFrameFromPosition2dInPlane(point, transformPlaneToWorld); - geometry_msgs::Point point_ros; - point_ros.x = pointInWorld.x(); - point_ros.y = pointInWorld.y(); - point_ros.z = pointInWorld.z(); - line.points.push_back(point_ros); - } - // repeat the first point to close to polygon - const auto pointInWorld = positionInWorldFrameFromPosition2dInPlane(polygon.vertex(0), transformPlaneToWorld); - geometry_msgs::Point point_ros; - point_ros.x = pointInWorld.x(); - point_ros.y = pointInWorld.y(); - point_ros.z = pointInWorld.z(); - line.points.push_back(point_ros); - } - line.pose.orientation.w = 1.0; - line.pose.orientation.x = 0.0; - line.pose.orientation.y = 0.0; - line.pose.orientation.z = 0.0; - return line; -} - -visualization_msgs::MarkerArray to3dRosMarker(const CgalPolygonWithHoles2d& polygonWithHoles, - const Eigen::Isometry3d& transformPlaneToWorld, const std_msgs::Header& header, - const std_msgs::ColorRGBA& color, int id, double lineWidth) { - visualization_msgs::MarkerArray polygons; - - polygons.markers.reserve(polygonWithHoles.number_of_holes() + 1); - polygons.markers.emplace_back(to3dRosMarker(polygonWithHoles.outer_boundary(), transformPlaneToWorld, header, color, id, lineWidth)); - ++id; - - for (const auto& hole : polygonWithHoles.holes()) { - polygons.markers.emplace_back(to3dRosMarker(hole, transformPlaneToWorld, header, color, id, lineWidth)); - ++id; - } - return polygons; -} -} // namespace - -visualization_msgs::MarkerArray convertBoundariesToRosMarkers(const std::vector& planarRegions, const std::string& frameId, - grid_map::Time time, double lineWidth) { - std_msgs::Header header; - header.stamp.fromNSec(time); - header.frame_id = frameId; - - visualization_msgs::Marker deleteMarker; - deleteMarker.action = visualization_msgs::Marker::DELETEALL; - - visualization_msgs::MarkerArray polygon_buffer; - polygon_buffer.markers.reserve(planarRegions.size() + 1); // lower bound - polygon_buffer.markers.push_back(deleteMarker); - int colorIdx = 0; - for (const auto& planarRegion : planarRegions) { - const auto color = getColor(colorIdx++); - int label = polygon_buffer.markers.size(); - auto boundaries = - to3dRosMarker(planarRegion.boundaryWithInset.boundary, planarRegion.transformPlaneToWorld, header, color, label, lineWidth); - std::move(boundaries.markers.begin(), boundaries.markers.end(), std::back_inserter(polygon_buffer.markers)); - } - - return polygon_buffer; -} - -visualization_msgs::MarkerArray convertInsetsToRosMarkers(const std::vector& planarRegions, const std::string& frameId, - grid_map::Time time, double lineWidth) { - std_msgs::Header header; - header.stamp.fromNSec(time); - header.frame_id = frameId; - - visualization_msgs::Marker deleteMarker; - deleteMarker.action = visualization_msgs::Marker::DELETEALL; - - visualization_msgs::MarkerArray polygon_buffer; - polygon_buffer.markers.reserve(planarRegions.size() + 1); // lower bound - polygon_buffer.markers.push_back(deleteMarker); - int colorIdx = 0; - for (const auto& planarRegion : planarRegions) { - const auto color = getColor(colorIdx++); - for (const auto& inset : planarRegion.boundaryWithInset.insets) { - int label = polygon_buffer.markers.size(); - auto insets = to3dRosMarker(inset, planarRegion.transformPlaneToWorld, header, color, label, lineWidth); - std::move(insets.markers.begin(), insets.markers.end(), std::back_inserter(polygon_buffer.markers)); - } - } - return polygon_buffer; -} - -} // namespace convex_plane_decomposition diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp deleted file mode 100644 index 8f471b22..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/src/SaveElevationMapAsImageNode.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// -// Created by rgrandia on 11.06.20. -// - -#include - -#include -#include -#include - -#include - -int count = 0; -double frequency; -std::string elevationMapTopic; -std::string elevationLayer; -std::string imageName; - -void callback(const grid_map_msgs::GridMap::ConstPtr& message) { - grid_map::GridMap messageMap; - grid_map::GridMapRosConverter::fromMessage(*message, messageMap); - - const auto& data = messageMap[elevationLayer]; - float maxHeight = std::numeric_limits::lowest(); - float minHeight = std::numeric_limits::max(); - for (int i = 0; i < data.rows(); i++) { - for (int j = 0; j < data.cols(); j++) { - const auto value = data(i, j); - if (!std::isnan(value)) { - maxHeight = std::max(maxHeight, value); - minHeight = std::min(minHeight, value); - } - } - } - - cv::Mat image; - grid_map::GridMapCvConverter::toImage(messageMap, elevationLayer, CV_8UC1, minHeight, maxHeight, image); - - int range = 100 * (maxHeight - minHeight); - cv::imwrite(imageName + "_" + std::to_string(count++) + "_" + std::to_string(range) + "cm.png", image); -} - -int main(int argc, char** argv) { - ros::init(argc, argv, "save_elevation_map_to_image"); - ros::NodeHandle nodeHandle("~"); - - if (!nodeHandle.getParam("frequency", frequency)) { - ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `frequency`."); - return 1; - } - if (!nodeHandle.getParam("elevation_topic", elevationMapTopic)) { - ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `elevation_topic`."); - return 1; - } - if (!nodeHandle.getParam("height_layer", elevationLayer)) { - ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `height_layer`."); - return 1; - } - if (!nodeHandle.getParam("imageName", imageName)) { - ROS_ERROR("[ConvexPlaneExtractionROS] Could not read parameter `imageName`."); - return 1; - } - - auto elevationMapSubscriber_ = nodeHandle.subscribe(elevationMapTopic, 1, callback); - - ros::Rate rate(frequency); - while (ros::ok()) { - ros::spinOnce(); - rate.sleep(); - } - - return 0; -} \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_ros/src/noiseNode.cpp b/plane_segmentation/convex_plane_decomposition_ros/src/noiseNode.cpp deleted file mode 100644 index c65f03de..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/src/noiseNode.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// -// Created by rgrandia on 25.10.21. -// - -#include - -#include -#include - -#include -#include - -double noiseUniform; -double noiseGauss; -double outlierPercentage; -bool blur; -double frequency; -std::string elevationMapTopicIn; -std::string elevationMapTopicOut; -std::string elevationLayer; -ros::Publisher publisher; -grid_map::GridMap::Matrix noiseLayer; - -void createNoise(size_t row, size_t col) { - // Box-Muller Transform - grid_map::GridMap::Matrix u1 = 0.5 * grid_map::GridMap::Matrix::Random(row, col).array() + 0.5; - grid_map::GridMap::Matrix u2 = 0.5 * grid_map::GridMap::Matrix::Random(row, col).array() + 0.5; - grid_map::GridMap::Matrix gauss01 = - u1.binaryExpr(u2, [&](float v1, float v2) { return std::sqrt(-2.0f * log(v1)) * cos(2.0f * M_PIf32 * v2); }); - - noiseLayer = noiseUniform * grid_map::GridMap::Matrix::Random(row, col) + noiseGauss * gauss01; -} - -void callback(const grid_map_msgs::GridMap::ConstPtr& message) { - grid_map::GridMap messageMap; - grid_map::GridMapRosConverter::fromMessage(*message, messageMap); - - if (blur) { - // Copy! - auto originalMap = messageMap.get(elevationLayer); - - // Blur (remove nan -> filter -> put back nan - grid_map::inpainting::minValues(messageMap, elevationLayer, "i"); - grid_map::smoothing::boxBlur(messageMap, "i", elevationLayer, 3, 1); - messageMap.get(elevationLayer) = (originalMap.array().isFinite()).select(messageMap.get(elevationLayer), originalMap); - } - - auto& elevation = messageMap.get(elevationLayer); - if (noiseLayer.size() != elevation.size()) { - createNoise(elevation.rows(), elevation.cols()); - } - - elevation += noiseLayer; - - grid_map_msgs::GridMap messageMapOut; - grid_map::GridMapRosConverter::toMessage(messageMap, messageMapOut); - publisher.publish(messageMapOut); -} - -int main(int argc, char** argv) { - ros::init(argc, argv, "noise_node"); - ros::NodeHandle nodeHandle("~"); - - if (!nodeHandle.getParam("frequency", frequency)) { - ROS_ERROR("[ConvexPlaneExtractionROS::NoiseNode] Could not read parameter `frequency`."); - return 1; - } - if (!nodeHandle.getParam("noiseGauss", noiseGauss)) { - ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `noiseGauss`."); - return 1; - } - if (!nodeHandle.getParam("noiseUniform", noiseUniform)) { - ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `noiseUniform`."); - return 1; - } - if (!nodeHandle.getParam("blur", blur)) { - ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `blur`."); - return 1; - } - if (!nodeHandle.getParam("outlier_percentage", outlierPercentage)) { - ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `outlier_percentage`."); - return 1; - } - if (!nodeHandle.getParam("elevation_topic_in", elevationMapTopicIn)) { - ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `elevation_topic_in`."); - return 1; - } - if (!nodeHandle.getParam("elevation_topic_out", elevationMapTopicOut)) { - ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `elevation_topic_out`."); - return 1; - } - if (!nodeHandle.getParam("height_layer", elevationLayer)) { - ROS_ERROR("[ConvexPlaneExtractionROS:NoiseNode] Could not read parameter `height_layer`."); - return 1; - } - - publisher = nodeHandle.advertise(elevationMapTopicOut, 1); - auto elevationMapSubscriber_ = nodeHandle.subscribe(elevationMapTopicIn, 1, callback); - - ros::Rate rate(frequency); - while (ros::ok()) { - ros::spinOnce(); - rate.sleep(); - } - - return 0; -} \ No newline at end of file diff --git a/plane_segmentation/convex_plane_decomposition_ros/test/TestShapeGrowing.cpp b/plane_segmentation/convex_plane_decomposition_ros/test/TestShapeGrowing.cpp deleted file mode 100644 index 0dcc4c92..00000000 --- a/plane_segmentation/convex_plane_decomposition_ros/test/TestShapeGrowing.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// Created by rgrandia on 08.06.20. -// - -#include -#include -#include - -using namespace convex_plane_decomposition; - -int main(int argc, char** argv) { - CgalPolygonWithHoles2d parentShape; - parentShape.outer_boundary().push_back({0.0, 0.0}); - parentShape.outer_boundary().push_back({0.0, 1000.0}); - parentShape.outer_boundary().push_back({400.0, 800.0}); - parentShape.outer_boundary().push_back({1000.0, 1000.0}); - parentShape.outer_boundary().push_back({800.0, 400.0}); - parentShape.outer_boundary().push_back({1000.0, 0.0}); - parentShape.add_hole(createRegularPolygon(CgalPoint2d(200.0, 200.0), 50, 4)); - parentShape.add_hole(createRegularPolygon(CgalPoint2d(600.0, 700.0), 100, 100)); - - int numberOfVertices = 16; - double growthFactor = 1.05; - - cv::Size imgSize(1000, 1000); - const auto parentColor = randomColor(); - const auto fitColor = randomColor(); - - int N_test = 10; - for (int i = 0; i < N_test; i++) { - CgalPoint2d center = CgalPoint2d(rand() % imgSize.width, rand() % imgSize.height); - cv::Mat polygonImage(imgSize, CV_8UC3, cv::Vec3b(0, 0, 0)); - drawContour(polygonImage, parentShape, &parentColor); - drawContour(polygonImage, center, 2, &fitColor); - if (isInside(center, parentShape)) { - const auto fittedPolygon2d = growConvexPolygonInsideShape(parentShape, center, numberOfVertices, growthFactor); - drawContour(polygonImage, fittedPolygon2d, &fitColor); - } - - cv::namedWindow("TestShapeGrowing", cv::WindowFlags::WINDOW_NORMAL); - cv::imshow("TestShapeGrowing", polygonImage); - cv::waitKey(0); // Wait for a keystroke in the window - } - - return 0; -} diff --git a/plane_segmentation/grid_map_filters_rsl/CMakeLists.txt b/plane_segmentation/grid_map_filters_rsl/CMakeLists.txt deleted file mode 100644 index 444929cb..00000000 --- a/plane_segmentation/grid_map_filters_rsl/CMakeLists.txt +++ /dev/null @@ -1,126 +0,0 @@ -# Project configuration -cmake_minimum_required (VERSION 3.5.1) -project(grid_map_filters_rsl) - -set(CMAKE_CXX_STANDARD 14) -add_compile_options(-Wall -Wextra -Wpedantic) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -set(CATKIN_PACKAGE_DEPENDENCIES - grid_map_cv - grid_map_core -) - -find_package(catkin REQUIRED - COMPONENTS - ${CATKIN_PACKAGE_DEPENDENCIES} -) - -find_package(Eigen3 REQUIRED) - -################################### -## catkin specific configuration ## -################################### -catkin_package( - INCLUDE_DIRS - include - ${EIGEN3_INCLUDE_DIR} - LIBRARIES - ${PROJECT_NAME} - CATKIN_DEPENDS - ${CATKIN_PACKAGE_DEPENDENCIES} -) - -########### -## Build ## -########### -add_library(${PROJECT_NAME} - src/GridMapDerivative.cpp - src/inpainting.cpp - src/lookup.cpp - src/smoothing.cpp - src/processing.cpp -) - -target_include_directories(${PROJECT_NAME} PRIVATE - include -) - -target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC - ${catkin_INCLUDE_DIRS} - ${EIGEN3_INCLUDE_DIR} -) - - -target_link_libraries(${PROJECT_NAME} - ${catkin_LIBRARIES} -) - -########## -## Test ## -########## - -## GTest. -if(CATKIN_ENABLE_TESTING) - ## Find catkin dependencies, including test dependencies. - find_package(catkin REQUIRED - COMPONENTS - ${CATKIN_PACKAGE_DEPENDENCIES} - ) - - catkin_add_gtest(test_${PROJECT_NAME} - test/TestDerivativeFilter.cpp - test/TestFilters.cpp - test/TestLookup.cpp - ) -endif() - -## Link GTest. -if(TARGET test_${PROJECT_NAME}) - target_link_libraries(test_${PROJECT_NAME} - ${PROJECT_NAME} - ${catkin_LIBRARIES} - gtest_main - ) - - target_include_directories(test_${PROJECT_NAME} PRIVATE - include - ) - - target_include_directories(test_${PROJECT_NAME} SYSTEM PUBLIC - ${catkin_INCLUDE_DIRS} - ) - - # Generate test coverage report - find_package(cmake_code_coverage QUIET) - if(cmake_code_coverage_FOUND) - add_gtest_coverage( - TEST_BUILD_TARGETS test_${PROJECT_NAME} - ) - endif(cmake_code_coverage_FOUND) -endif() - -############# -## Install ## -############# -install( - TARGETS - ${PROJECT_NAME} - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -) - -install( - DIRECTORY - include/${PROJECT_NAME}/ - DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} -) - -########### -## Clang ## -########### -find_package(cmake_clang_tools QUIET) -if(cmake_clang_tools_FOUND) - add_default_clang_tooling() -endif(cmake_clang_tools_FOUND) \ No newline at end of file diff --git a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/GridMapDerivative.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/GridMapDerivative.hpp deleted file mode 100644 index 41dd3ac4..00000000 --- a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/GridMapDerivative.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file GridMapDerivative.hpp - * @authors Fabian Jenelten - * @date 20.05, 2021 - * @affiliation ETH RSL - * @brief Computes first and second order derivatives for a grid map. Intended to be used for online applications (i.e, derivatives - * are not precomputed but computed at the time and location where they are needed). - */ - -#pragma once - -// grid_map_core -#include - -namespace grid_map { -namespace derivative { - -class GridMapDerivative { - private: - static constexpr int kernelSize_ = 5; - using Gradient = Eigen::Vector2d; - using Curvature = Eigen::Matrix2d; - using Kernel = Eigen::Matrix; - - public: - GridMapDerivative(); - ~GridMapDerivative() = default; - - /** - * @brief Initialize function - * @param res resolution of the grid map - * @return true iff successful - */ - bool initialize(float res); - - /** - * @brief Compute local gradient using grid map. Gradient is set to zero if the index is outside of the grid map. - * @param gridMap The grid map - * @param gradient gradient vector in world frame - * @param index grid map index - * @param H grid map corresponding to layer (Eigen implementation) - */ - void estimateGradient(const grid_map::GridMap& gridMap, Gradient& gradient, const grid_map::Index& index, - const grid_map::Matrix& H) const; - - /** - * @brief Compute local height gradient and curvature using grid map. Gradient and curvature are set to zero if the index is outside of - * the grid map. - * @param gridMap The grid map - * @param gradient gradient vector in world frame - * @param curvature curvature matrix in world frame - * @param index grid map index - * @param H grid map corresponding to layer (Eigen implementation) - */ - void estimateGradientAndCurvature(const grid_map::GridMap& gridMap, Gradient& gradient, Curvature& curvature, - const grid_map::Index& index, const grid_map::Matrix& H) const; - - private: - /** - * @brief Return center of kernel s.t. kernel does not reach boundaries of grid map. By default returns 0 (equals central difference). - * @param gridMap The grid map - * @param centerIndex index at which we want to apply the kernel - * @param maxKernelId max index of kernel in positive direction - * @return center of kernel - */ - static Eigen::Vector2i getKernelCenter(const grid_map::GridMap& gridMap, const grid_map::Index& centerIndex, int maxKernelId); - - //! First order derivative kernel. - Kernel kernelD1_; - - //! Second order derivative kernel. - Kernel kernelD2_; -}; -} // namespace derivative -} // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp deleted file mode 100644 index f8f89e5f..00000000 --- a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/inpainting.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file inpainting.hpp - * @authors Fabian Jenelten - * @date 18.05, 2021 - * @affiliation ETH RSL - * @brief Inpainting filter (extrapolate nan values from surrounding data). - */ - -#pragma once - -// grid map. -#include - -namespace grid_map { -namespace inpainting { - -/** - * @brief Inpaint missing data using min-value in neighborhood. The neighborhood search is performed along the contour of nan-patches. - * In-place operation (layerIn = layerOut) is NOT supported. - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - */ -void minValues(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut); - -/** - * @brief Inpaint missing data using bi-linear interpolation. The neighborhood search is only performed along the column and the row of the - * missing element. In-place operation (layerIn = layerOut) is NOT supported. - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - */ -void biLinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut); - -/** - * @brief nonlinear interpolation (open-cv function). In-place operation (layerIn = layerOut) is supported. - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - * @param inpaintRadius vicinity considered by inpaint filter. - */ -void nonlinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, double inpaintRadius); - -/** - * @brief Up- or down-sample elevation map (open-cv function). In-place operation only. Only the layer with name "layer" is resampled, while - * all other layers (if there are any) are left untouched (exception if layer="all", which applies filter to all layers). - * @param map grid map - * @param layer resampling is done based in this layer. If "all", resamples all layers - * @param newRes new resolution. - */ -void resample(grid_map::GridMap& map, const std::string& layer, double newRes); - -} // namespace inpainting -} // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/lookup.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/lookup.hpp deleted file mode 100644 index cd3bae45..00000000 --- a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/lookup.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file lookup.hpp - * @authors Fabian Jenelten, Ruben Grandia - * @date 04.08, 2021 - * @affiliation ETH RSL - * @brief Extracting information from a gridmap - */ - -#pragma once - -// grid map. -#include - -namespace grid_map { -namespace lookup { - -struct LookupResult { - bool isValid{false}; - float value{0.0}; - grid_map::Position position{0.0, 0.0}; -}; - -/** - * Finds the maximum value between two points in a map - * - * @param position1 : starting point of the lookup line. - * @param position2 : ending point of the lookup line. - * @param gridMap : map object for map information. - * @param data : map data to find the maximum in. - * @return validity, value, and location of the maximum. A result is flagged as invalid if there are no finite values found. - */ -LookupResult maxValueBetweenLocations(const grid_map::Position& position1, const grid_map::Position& position2, - const grid_map::GridMap& gridMap, const grid_map::Matrix& data); - -/** - * Returns all values along a line between two points in a map - * - * @param position1 : starting point of the lookup line. - * @param position2 : ending point of the lookup line. - * @param gridMap : map object for map information. - * @param data : map data to get the values from. - * @return vector of all points generated by a line iteration - */ -std::vector valuesBetweenLocations(const grid_map::Position& position1, const grid_map::Position& position2, - const grid_map::GridMap& gridMap, const grid_map::Matrix& data); - -/** - * Project a point to inside the given gridmap with a specified margin - * - * @param gridMap : map object for map information. - * @param position : point to project to map - * @param margin : (minimum) distance from the map border after projection - * @return Projected position - */ -grid_map::Position projectToMapWithMargin(const grid_map::GridMap& gridMap, const grid_map::Position& position, double margin = 1e-6); - -} // namespace lookup -} // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/processing.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/processing.hpp deleted file mode 100644 index ff9688bc..00000000 --- a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/processing.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file processing.hpp - * @authors Fabian Jenelten - * @date 04.08, 2021 - * @affiliation ETH RSL - * @brief Processing filter (everything that is not smoothing or inpainting). - */ - -#pragma once - -#include - -// grid map. -#include - -namespace grid_map { -namespace processing { - -/** - * @brief Replaces values by max in region. In-place operation (layerIn = layerOut) is NOT supported. Supports nan values. - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - * @param mask Filter is applied only where mask contains values of 1 and omitted where values are nan. If mask is an empty matrix, - * applies unmasked dilation. - * @param kernelSize vicinity considered by filter (must be odd). - * @param inpaint if true, also replaces potential nan values by the maximum - */ -void dilate(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, const grid_map::Matrix& mask, int kernelSize, - bool inpaint = true); - -/** - * @brief Replaces values by min in region. In-place operation (layerIn = layerOut) is NOT supported. Supports nan values. - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - * @param mask Filter is applied only where mask contains values of 1 and omitted where values are nan. If mask is an empty matrix, - * applies unmasked dilation. - * @param kernelSize vicinity considered by filter (must be odd). - * @param inpaint if true, also replaces potential nan values by the minimum - */ -void erode(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, const grid_map::Matrix& mask, int kernelSize, - bool inpaint = true); - -/** - * @brief Extracts a thin layer of height values, surrounding patches of nan-values. In-place operation (layerIn = layerOut) is NOT - * supported. Supports nan values. - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - */ -void outline(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut); - -/** - * @brief Replaces values by output of a function. In-place operation (layerIn = layerOut) is NOT supported. Supports nan values. - * - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - * @param kernelSize vicinity considered by filter (must be odd). - */ -void applyKernelFunction(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize, - std::function&)> func); - -} // namespace processing -} // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/smoothing.hpp b/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/smoothing.hpp deleted file mode 100644 index 99ae3e2b..00000000 --- a/plane_segmentation/grid_map_filters_rsl/include/grid_map_filters_rsl/smoothing.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file smoothing.hpp - * @authors Fabian Jenelten - * @date 18.05, 2021 - * @affiliation ETH RSL - * @brief Smoothing and outlier rejection filters. - */ - -#pragma once - -// grid map. -#include - -namespace grid_map { -namespace smoothing { - -/** - * @brief Sequential median filter (open-cv function). In-place operation (layerIn = layerOut) is supported. - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - * @param kernelSize size of the smoothing window (must be an odd number) - * @param deltaKernelSize kernel size is increased by this value, if numberOfRepeats > 1 - * @param numberOfRepeats number of sequentially applied median filters (approaches to gaussian blurring if increased) - */ -void median(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize, int deltaKernelSize = 2, - int numberOfRepeats = 1); - -/** - * @brief Sequential box blur filter (open cv-function). In-place operation (layerIn = layerOut) is supported. - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - * @param kernelSize size of the smoothing window (should be an odd number, otherwise, introduces offset) - * @param numberOfRepeats number of sequentially applied blurring filters (approaches to gaussian blurring if increased) - */ -void boxBlur(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize, int numberOfRepeats = 1); - -/** - * @brief Gaussian blur filter (open cv-function). In-place operation (layerIn = layerOut) is supported. - * @param map grid map - * @param layerIn reference layer (filter is applied wrt this layer) - * @param layerOut output layer (filtered map is written into this layer) - * @param kernelSize size of the smoothing window (should be an odd number, otherwise, introduces offset) - * @param sigma variance - */ -void gaussianBlur(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize, double sigma); - -} // namespace smoothing -} // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/package.xml b/plane_segmentation/grid_map_filters_rsl/package.xml deleted file mode 100644 index 3df62480..00000000 --- a/plane_segmentation/grid_map_filters_rsl/package.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - grid_map_filters_rsl - 0.1.0 - Extension of grid map filters package with op-cv filters and others - Fabian Jenelten - - Fabian Jenelten - - MIT - - catkin - cmake_clang_tools - grid_map_cv - grid_map_core - - gtest - cmake_code_coverage - diff --git a/plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp b/plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp deleted file mode 100644 index 1796dfde..00000000 --- a/plane_segmentation/grid_map_filters_rsl/src/GridMapDerivative.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file GridMapDerivative.cpp - * @authors Fabian Jenelten - * @date 20.05, 2021 - * @affiliation ETH RSL - * @brief Computes first and second order derivatives for a grid map. Intended to be used for online applications (i.e, derivatives - * are not precomputed but computed at the time and location where they are needed). - */ - -// grid map filters rsl. -#include - -namespace grid_map { -namespace derivative { -constexpr int GridMapDerivative::kernelSize_; - -GridMapDerivative::GridMapDerivative() : kernelD1_(Kernel::Zero()), kernelD2_(Kernel::Zero()) {} - -bool GridMapDerivative::initialize(float res) { - // Central finite difference: https://en.wikipedia.org/wiki/Finite_difference_coefficient - kernelD1_ << -1.0 / 12.0, 2.0 / 3.0, 0.0, -2.0 / 3.0, 1.0 / 12.0; - kernelD2_ << -1.0 / 12.0, 4.0 / 3.0, -5.0 / 2.0, 4.0 / 3.0, -1.0 / 12.0; - kernelD1_ /= res; - kernelD2_ /= (res * res); - return res > 0.0; -} - -void GridMapDerivative::estimateGradient(const grid_map::GridMap& gridMap, Gradient& gradient, const grid_map::Index& index, - const grid_map::Matrix& H) const { - // Indices. - constexpr auto maxKernelId = (kernelSize_ - 1) / 2; - const Eigen::Vector2i centerId = getKernelCenter(gridMap, index, maxKernelId); - - // Gradient. - gradient.x() = kernelD1_.dot(H.block(index.x() - maxKernelId + centerId.x(), index.y())); - gradient.y() = kernelD1_.dot(H.block<1, kernelSize_>(index.x(), index.y() - maxKernelId + centerId.y())); -} - -void GridMapDerivative::estimateGradientAndCurvature(const grid_map::GridMap& gridMap, Gradient& gradient, Curvature& curvature, - const grid_map::Index& index, const grid_map::Matrix& H) const { - // Note: Block implementation is twice as fast as iterating over the grid cells. - - // Indices. - constexpr auto maxKernelId = (kernelSize_ - 1) / 2; - const Eigen::Vector2i centerId = getKernelCenter(gridMap, index, maxKernelId); - const Eigen::Vector2i shiftedId(index.x() - maxKernelId + centerId.x(), index.y() - maxKernelId + centerId.y()); - - // Gradient in x for different y (used for computing the cross hessian). - Kernel gradientYArray; - for (auto idY = 0; idY < kernelSize_; ++idY) { - gradientYArray[idY] = kernelD1_.dot(H.block(shiftedId.x(), shiftedId.y() + idY)); - } - - // Gradient. - gradient(0U) = kernelD1_.dot(H.block(shiftedId.x(), index.y())); - gradient(1U) = kernelD1_.dot(H.block<1, kernelSize_>(index.x(), shiftedId.y())); - - // Curvature. - curvature(0U, 0U) = kernelD2_.dot(H.block(shiftedId.x(), index.y())); - curvature(1U, 1U) = kernelD2_.dot(H.block<1, kernelSize_>(index.x(), shiftedId.y())); - curvature(0U, 1U) = kernelD1_.dot(gradientYArray); - curvature(1U, 0U) = curvature(0U, 1U); -} - -Eigen::Vector2i GridMapDerivative::getKernelCenter(const grid_map::GridMap& gridMap, const grid_map::Index& centerIndex, int maxKernelId) { - constexpr auto minId = 0; - Eigen::Vector2i centerId; - for (auto dim = 0; dim < 2; ++dim) { - const auto maxId = gridMap.getSize()(dim) - 1; - centerId(dim) = -std::min(centerIndex(dim) - maxKernelId, minId) - std::max(centerIndex(dim) + maxKernelId - maxId, 0); - } - return centerId; -} - -} // namespace derivative -} // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp b/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp deleted file mode 100644 index a3aaa19b..00000000 --- a/plane_segmentation/grid_map_filters_rsl/src/inpainting.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/** - * @file inpainting.cpp - * @authors Fabian Jenelten - * @date 18.05, 2021 - * @affiliation ETH RSL - * @brief Inpainting filter (extrapolate nan values from surrounding data). - */ - -// grid map filters rsl. -#include -#include - -// open cv. -#include -#include -#include -#include - -// stl. -#include - -namespace grid_map { -namespace inpainting { - -void minValues(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut) { - // Create new layer if missing - if (!map.exists(layerOut)) { - map.add(layerOut, map.get(layerIn)); - } - - // Reference to in, and out maps, initialize with copy - const grid_map::Matrix& H_in = map.get(layerIn); - grid_map::Matrix& H_out = map.get(layerOut); - H_out = H_in; - - // Some constant - const int numCols = H_in.cols(); - const int maxColId = numCols - 1; - const int numRows = H_in.rows(); - const int maxRowId = numRows - 1; - - // Common operation of updating the minimum and keeping track if the minimum was updated. - auto compareAndStoreMin = [](float newValue, float& currentMin, bool& changedValue) { - if (!std::isnan(newValue)) { - if (newValue < currentMin || std::isnan(currentMin)) { - currentMin = newValue; - changedValue = true; - } - } - }; - - /* - * Fill each cell that needs inpainting with the min of its neighbours until the map doesn't change anymore. - * This way each inpainted area gets the minimum value along its contour. - * - * We will be reading and writing to H_out during iteration. However, the aliasing does not break the correctness of the algorithm. - */ - bool hasAtLeastOneValue = true; - bool changedValue = true; - while (changedValue && hasAtLeastOneValue) { - hasAtLeastOneValue = false; - changedValue = false; - for (int colId = 0; colId < numCols; ++colId) { - for (int rowId = 0; rowId < numRows; ++rowId) { - if (std::isnan(H_in(rowId, colId))) { - auto& middleValue = H_out(rowId, colId); - - // left - if (colId > 0) { - const auto leftValue = H_out(rowId, colId - 1); - compareAndStoreMin(leftValue, middleValue, changedValue); - } - // right - if (colId < maxColId) { - const auto rightValue = H_out(rowId, colId + 1); - compareAndStoreMin(rightValue, middleValue, changedValue); - } - // top - if (rowId > 0) { - const auto topValue = H_out(rowId - 1, colId); - compareAndStoreMin(topValue, middleValue, changedValue); - } - // bottom - if (rowId < maxRowId) { - const auto bottomValue = H_out(rowId + 1, colId); - compareAndStoreMin(bottomValue, middleValue, changedValue); - } - } else { - hasAtLeastOneValue = true; - } - } - } - } -} - -void biLinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut) { - // Create new layer if missing - if (!map.exists(layerOut)) { - map.add(layerOut, map.get(layerIn)); - } else { - // initialize with a copy - map.get(layerOut) = map.get(layerIn); - } - - // Helper variables. - std::array indices; - std::array values; - Eigen::Matrix4f A; - Eigen::Vector4f b; - A.setOnes(); - Eigen::Vector4f weights; - bool success = true; - constexpr auto infinity = std::numeric_limits::max(); - - // Init. - std::fill(values.begin(), values.end(), NAN); - std::fill(indices.begin(), indices.end(), Eigen::Vector2i(0, 0)); - - // Reference to in and out maps. - const grid_map::Matrix& H_in = map.get(layerIn); - grid_map::Matrix& H_out = map.get(layerOut); - - for (auto colId = 0; colId < H_in.cols(); ++colId) { - for (auto rowId = 0; rowId < H_in.rows(); ++rowId) { - if (std::isnan(H_in(rowId, colId))) { - // Note: if we don't find a valid neighbour, we use the previous index-value pair. - auto minValue = infinity; - const Eigen::Vector2i index0(rowId, colId); - - // Search in negative direction. - for (auto id = rowId - 1; id >= 0; --id) { - auto newValue = H_in(id, colId); - if (!std::isnan(newValue)) { - indices[0] = Eigen::Vector2i(id, colId); - values[0] = newValue; - minValue = std::fmin(minValue, newValue); - break; - } - } - - for (auto id = colId - 1; id >= 0; --id) { - auto newValue = H_in(rowId, id); - if (!std::isnan(newValue)) { - indices[1] = Eigen::Vector2i(rowId, id); - values[1] = newValue; - minValue = std::fmin(minValue, newValue); - break; - } - } - - // Search in positive direction. - for (auto id = rowId + 1; id < H_in.rows(); ++id) { - auto newValue = H_in(id, colId); - if (!std::isnan(newValue)) { - indices[2] = Eigen::Vector2i(id, colId); - values[2] = newValue; - minValue = std::fmin(minValue, newValue); - break; - } - } - - for (auto id = colId + 1; id < H_in.cols(); ++id) { - auto newValue = H_in(rowId, id); - if (!std::isnan(newValue)) { - indices[3] = Eigen::Vector2i(rowId, id); - values[3] = newValue; - minValue = std::fmin(minValue, newValue); - break; - } - } - - // Cannot interpolate if there are not 4 corner points. - if (std::any_of(values.begin(), values.end(), [](float value) { return std::isnan(value); })) { - if (minValue < infinity) { - H_out(rowId, colId) = minValue; - } else { - success = false; - } - continue; - } - - // Interpolation weights (https://en.wikipedia.org/wiki/Bilinear_interpolation). - for (auto id = 0U; id < 4U; ++id) { - A(id, 1U) = static_cast(indices[id].x()); - A(id, 2U) = static_cast(indices[id].y()); - A(id, 3U) = static_cast(indices[id].x() * indices[id].y()); - b(id) = values[id]; - } - weights = A.colPivHouseholderQr().solve(b); - - // Value according to bi-linear interpolation. - H_out(rowId, colId) = weights.dot(Eigen::Vector4f(1.0, static_cast(index0.x()), static_cast(index0.y()), - static_cast(index0.x() * index0.y()))); - } - } - } - - // If failed, try again. - if (!success) { - map.get(layerIn) = map.get(layerOut); - return nonlinearInterpolation(map, layerIn, layerOut, 2. * map.getResolution()); - } -} - -void nonlinearInterpolation(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, double inpaintRadius) { - // Create new layer if missing. - if (!map.exists(layerOut)) { - map.add(layerOut); - } - - // Reference to in map. - const grid_map::Matrix& H_in = map.get(layerIn); - - // Create mask. - Eigen::Matrix mask = H_in.unaryExpr([](float val) { return (std::isnan(val)) ? uchar(1) : uchar(0); }); - cv::Mat maskImage; - cv::eigen2cv(mask, maskImage); - - // Convert grid map to image. - cv::Mat elevationImageIn; - const float minValue = H_in.minCoeffOfFinites(); - const float maxValue = H_in.maxCoeffOfFinites(); - grid_map::GridMapCvConverter::toImage(map, layerIn, CV_8UC1, minValue, maxValue, elevationImageIn); - - // Inpainting. - cv::Mat elevationImageOut; - const double radiusInPixels = inpaintRadius / map.getResolution(); - cv::inpaint(elevationImageIn, maskImage, elevationImageOut, radiusInPixels, cv::INPAINT_NS); - - // Get inpainting as float. - cv::Mat filledImageFloat; - constexpr float maxUCharValue = 255.F; - elevationImageOut.convertTo(filledImageFloat, CV_32F, (maxValue - minValue) / maxUCharValue, minValue); - - // Copy inpainted values back to elevation map. - cv::Mat elevationImageFloat; - cv::eigen2cv(H_in, elevationImageFloat); - filledImageFloat.copyTo(elevationImageFloat, maskImage); - - // Set new output layer. - cv::cv2eigen(elevationImageFloat, map.get(layerOut)); -} - -void resample(grid_map::GridMap& map, const std::string& layer, double newRes) { - // Original map info - const auto oldPos = map.getPosition(); - const auto oldSize = map.getSize(); - const auto oldRes = map.getResolution(); - - if (oldRes == newRes) { - return; - } - - // Layers to be resampled. - std::vector layer_names; - if (layer == "all") { - layer_names = map.getLayers(); - } else { - layer_names.push_back(layer); - } - - for (const auto& layer_name : layer_names) { - Eigen::MatrixXf elevationMap = std::move(map.get(layer_name)); - - // Convert elevation map to open-cv image. - cv::Mat elevationImage; - cv::eigen2cv(elevationMap, elevationImage); - - // Compute new dimensions. - const double scaling = oldRes / newRes; - int width = int(elevationImage.size[1] * scaling); - int height = int(elevationImage.size[0] * scaling); - cv::Size dim{width, height}; - - // Resize image - cv::Mat resizedImage; - cv::resize(elevationImage, resizedImage, dim, 0, 0, cv::INTER_LINEAR); - cv::cv2eigen(resizedImage, elevationMap); - - // Compute true new resolution. Might be slightly different due to rounding. Take average of both dimensions. - grid_map::Size newSize = {elevationMap.rows(), elevationMap.cols()}; - newRes = 0.5 * ((oldSize[0] * oldRes) / newSize[0] + (oldSize[1] * oldRes) / newSize[1]); - - // Store new map. - map.setGeometry({newSize[0] * newRes, newSize[1] * newRes}, newRes, oldPos); - map.get(layer_name) = std::move(elevationMap); - } -} -} // namespace inpainting -} // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/src/lookup.cpp b/plane_segmentation/grid_map_filters_rsl/src/lookup.cpp deleted file mode 100644 index 61409e7a..00000000 --- a/plane_segmentation/grid_map_filters_rsl/src/lookup.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @file lookup.cpp - * @authors Fabian Jenelten, Ruben Grandia - * @date 04.08, 2021 - * @affiliation ETH RSL - * @brief implementation of lookup - */ - -// grid map filters rsl. -#include - -// stl. -#include - -namespace grid_map { -namespace lookup { - -LookupResult maxValueBetweenLocations(const grid_map::Position& position1, const grid_map::Position& position2, - const grid_map::GridMap& gridMap, const grid_map::Matrix& data) { - // Map corner points into grid map. The line iteration doesn't account for the case where the line does not intersect the map. - const grid_map::Position startPos = projectToMapWithMargin(gridMap, position1); - const grid_map::Position endPos = projectToMapWithMargin(gridMap, position2); - - // Line iteration - float searchMaxValue = std::numeric_limits::lowest(); - grid_map::Index maxIndex(0, 0); - for (grid_map::LineIterator iterator(gridMap, startPos, endPos); !iterator.isPastEnd(); ++iterator) { - const grid_map::Index index = *iterator; - const auto value = data(index(0), index(1)); - if (std::isfinite(value)) { - searchMaxValue = std::max(searchMaxValue, value); - maxIndex = index; - } - } - - // Get position of max - grid_map::Position maxPosition; - gridMap.getPosition(maxIndex, maxPosition); - - const bool maxValueFound = searchMaxValue > std::numeric_limits::lowest(); - return {maxValueFound, searchMaxValue, maxPosition}; -} - -std::vector valuesBetweenLocations(const grid_map::Position& position1, const grid_map::Position& position2, - const grid_map::GridMap& gridMap, const grid_map::Matrix& data) { - // Map corner points into grid map. The line iteration doesn't account for the case where the line does not intersect the map. - const grid_map::Position startPos = projectToMapWithMargin(gridMap, position1); - const grid_map::Position endPos = projectToMapWithMargin(gridMap, position2); - - // Approximate amount of points to reserve memory - const auto manhattanDistance = std::max(std::abs(endPos.x() - startPos.x()), std::abs(endPos.y() - startPos.y())); - const int manhattanPixels = std::ceil(manhattanDistance / gridMap.getResolution()) + 1; - - // Container for results - std::vector lineValues; - lineValues.reserve(manhattanPixels); - - // Line iteration - grid_map::Position position; - for (grid_map::LineIterator iterator(gridMap, startPos, endPos); !iterator.isPastEnd(); ++iterator) { - const auto& index = *iterator; - const auto value = data(index(0), index(1)); - - if (std::isfinite(value)) { - gridMap.getPosition(index, position); - lineValues.push_back({position.x(), position.y(), value}); - } - } - - return lineValues; -} - -grid_map::Position projectToMapWithMargin(const grid_map::GridMap& gridMap, const grid_map::Position& position, double margin) { - const auto length = gridMap.getLength(); - const auto mapPosition = gridMap.getPosition(); - - // Find edges. - const double halfLengthX = length.x() * 0.5; - const double halfLengthY = length.y() * 0.5; - - // Margin can't be larger than half the length - margin = std::max(margin, 0.0); - margin = std::min(margin, halfLengthX); - margin = std::min(margin, halfLengthY); - - // Find constraints. - double maxX = mapPosition.x() + halfLengthX - margin; - double minX = mapPosition.x() - halfLengthX + margin; - double maxY = mapPosition.y() + halfLengthY - margin; - double minY = mapPosition.y() - halfLengthY + margin; - - // Projection - auto projection = position; - - // Clip to box constraints - projection.x() = std::fmin(projection.x(), maxX); - projection.y() = std::fmin(projection.y(), maxY); - - projection.x() = std::fmax(projection.x(), minX); - projection.y() = std::fmax(projection.y(), minY); - - return projection; -} - -} // namespace lookup -} // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/src/processing.cpp b/plane_segmentation/grid_map_filters_rsl/src/processing.cpp deleted file mode 100644 index 1249937e..00000000 --- a/plane_segmentation/grid_map_filters_rsl/src/processing.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/** - * @file processing.cpp - * @authors Fabian Jenelten - * @date 04.08, 2021 - * @affiliation ETH RSL - * @brief Processing filter (everything that is not smoothing or inpainting). - */ - -// grid map filters rsl. -#include - -namespace grid_map { -namespace processing { - -void dilate(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, const grid_map::Matrix& mask, int kernelSize, - bool inpaint) { - // Create new layer if missing - if (!map.exists(layerOut)) { - map.add(layerOut, map.get(layerIn)); - } - - // Reference to in and out maps. - const grid_map::Matrix& H_in = map.get(layerIn); - grid_map::Matrix& H_out = map.get(layerOut); - - // Apply mask. - grid_map::Matrix H_in_masked; - if (mask.cols() == 0 || mask.rows() == 0) { - H_in_masked = H_in; - } else { - H_in_masked = H_in.cwiseProduct(mask); - } - const auto maxKernelId = (kernelSize - 1) / 2; - - for (auto colId = 0; colId < H_in.cols(); ++colId) { - for (auto rowId = 0; rowId < H_in.rows(); ++rowId) { - // Move index to the korner of the kernel window. - auto cornerColId = std::max(colId - maxKernelId, 0); - auto cornerRowId = std::max(rowId - maxKernelId, 0); - - // Make sure we don't overshoot. - if (cornerColId + kernelSize > H_in.cols()) { - cornerColId = H_in.cols() - kernelSize; - } - - if (cornerRowId + kernelSize > H_in.rows()) { - cornerRowId = H_in.rows() - kernelSize; - } - - // Find maximum in region. - if (inpaint || !std::isnan(H_in(rowId, colId))) { - const auto maxInKernel = H_in_masked.block(cornerRowId, cornerColId, kernelSize, kernelSize).maxCoeffOfFinites(); - H_out(rowId, colId) = std::isnan(maxInKernel) ? H_in(rowId, colId) : maxInKernel; - } else { - H_out(rowId, colId) = NAN; - } - } - } -} - -void erode(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, const grid_map::Matrix& mask, int kernelSize, - bool inpaint) { - // Create new layer if missing - if (!map.exists(layerOut)) { - map.add(layerOut, map.get(layerIn)); - } - - // Reference to in and out maps. - const grid_map::Matrix& H_in = map.get(layerIn); - grid_map::Matrix& H_out = map.get(layerOut); - - // Apply mask. - grid_map::Matrix H_in_masked; - if (mask.cols() == 0 || mask.rows() == 0) { - H_in_masked = H_in; - } else { - H_in_masked = H_in.cwiseProduct(mask); - } - const auto maxKernelId = (kernelSize - 1) / 2; - - for (auto colId = 0; colId < H_in.cols(); ++colId) { - for (auto rowId = 0; rowId < H_in.rows(); ++rowId) { - // Move index to the korner of the kernel window. - auto cornerColId = std::max(colId - maxKernelId, 0); - auto cornerRowId = std::max(rowId - maxKernelId, 0); - - // Make sure we don't overshoot. - if (cornerColId + kernelSize > H_in.cols()) { - cornerColId = H_in.cols() - kernelSize; - } - - if (cornerRowId + kernelSize > H_in.rows()) { - cornerRowId = H_in.rows() - kernelSize; - } - - // Find minimum in region. - if (inpaint || !std::isnan(H_in(rowId, colId))) { - const auto minInKernel = H_in_masked.block(cornerRowId, cornerColId, kernelSize, kernelSize).minCoeffOfFinites(); - H_out(rowId, colId) = std::isnan(minInKernel) ? H_in(rowId, colId) : minInKernel; - } else { - H_out(rowId, colId) = NAN; - } - } - } -} - -void outline(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut) { - // Create new layer if missing - if (!map.exists(layerOut)) { - map.add(layerOut, map.get(layerIn)); - } - - // Reference to in and out maps. - const grid_map::Matrix& H_in = map.get(layerIn); - grid_map::Matrix& H_out = map.get(layerOut); - - constexpr auto kernelSize = 3; - constexpr auto maxKernelId = (kernelSize - 1) / 2; - - for (auto colId = 0; colId < H_in.cols(); ++colId) { - for (auto rowId = 0; rowId < H_in.rows(); ++rowId) { - // Move index to the korner of the kernel window. - auto cornerColId = std::max(colId - maxKernelId, 0); - auto cornerRowId = std::max(rowId - maxKernelId, 0); - - // Make sure we don't overshoot. - if (cornerColId + kernelSize > H_in.cols()) { - cornerColId = H_in.cols() - kernelSize; - } - - if (cornerRowId + kernelSize > H_in.rows()) { - cornerRowId = H_in.rows() - kernelSize; - } - - // Check if grid cell touches the nan grid cell. - if (H_in.block(cornerRowId, cornerColId, kernelSize, kernelSize).hasNaN()) { - H_out(rowId, colId) = H_in(rowId, colId); - } else { - H_out(rowId, colId) = NAN; - } - } - } -} - -void applyKernelFunction(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize, - std::function&)> func) { - // Create new layer if missing - if (!map.exists(layerOut)) { - map.add(layerOut, map.get(layerIn)); - } - - // Reference to in and out maps. - const grid_map::Matrix& H_in = map.get(layerIn); - grid_map::Matrix& H_out = map.get(layerOut); - - const auto maxKernelId = (kernelSize - 1) / 2; - - for (auto colId = 0; colId < H_in.cols(); ++colId) { - for (auto rowId = 0; rowId < H_in.rows(); ++rowId) { - // Move index to the korner of the kernel window. - auto cornerColId = std::max(colId - maxKernelId, 0); - auto cornerRowId = std::max(rowId - maxKernelId, 0); - - // Make sure we don't overshoot. - if (cornerColId + kernelSize > H_in.cols()) { - cornerColId = H_in.cols() - kernelSize; - } - - if (cornerRowId + kernelSize > H_in.rows()) { - cornerRowId = H_in.rows() - kernelSize; - } - - // Apply user defined function - H_out(rowId, colId) = func(H_in.block(cornerRowId, cornerColId, kernelSize, kernelSize)); - } - } -} - -} // namespace processing -} // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/src/smoothing.cpp b/plane_segmentation/grid_map_filters_rsl/src/smoothing.cpp deleted file mode 100644 index 24e89e04..00000000 --- a/plane_segmentation/grid_map_filters_rsl/src/smoothing.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/** - * @file smoothing.cpp - * @authors Fabian Jenelten - * @date 18.05, 2021 - * @affiliation ETH RSL - * @brief Smoothing and outlier rejection filters. - */ - -// grid map filters rsl. -#include - -// open cv. -#include -#include -#include -#include -#include -#include - -namespace grid_map { -namespace smoothing { - -void median(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize, int deltaKernelSize, - int numberOfRepeats) { - // Create new layer if missing. - if (!map.exists(layerOut)) { - map.add(layerOut); - } - - if (kernelSize + deltaKernelSize * (numberOfRepeats - 1) <= 5) { - // Convert to image. - cv::Mat elevationImage; - cv::eigen2cv(map.get(layerIn), elevationImage); - - for (auto iter = 0; iter < numberOfRepeats; ++iter) { - cv::medianBlur(elevationImage, elevationImage, kernelSize); - kernelSize += deltaKernelSize; - } - - // Set output layer. - cv::cv2eigen(elevationImage, map.get(layerOut)); - } - - // Larger kernel sizes require a specific format. - else { - // Reference to in map. - const grid_map::Matrix& H_in = map.get(layerIn); - - // Convert grid map to image. - cv::Mat elevationImage; - const float minValue = H_in.minCoeffOfFinites(); - const float maxValue = H_in.maxCoeffOfFinites(); - grid_map::GridMapCvConverter::toImage(map, layerIn, CV_8UC1, minValue, maxValue, elevationImage); - - for (auto iter = 0; iter < numberOfRepeats; ++iter) { - cv::medianBlur(elevationImage, elevationImage, kernelSize); - kernelSize += deltaKernelSize; - } - - // Get image as float. - cv::Mat elevationImageFloat; - constexpr float maxUCharValue = 255.F; - elevationImage.convertTo(elevationImageFloat, CV_32F, (maxValue - minValue) / maxUCharValue, minValue); - - // Convert back to grid map. - cv::cv2eigen(elevationImageFloat, map.get(layerOut)); - } -} - -void boxBlur(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize, int numberOfRepeats) { - // Create new layer if missing. - if (!map.exists(layerOut)) { - map.add(layerOut); - } - - // Convert to image. - cv::Mat elevationImage; - cv::eigen2cv(map.get(layerIn), elevationImage); - - // Box blur. - cv::Size kernelSize2D(kernelSize, kernelSize); - for (auto iter = 0; iter < numberOfRepeats; ++iter) { - cv::blur(elevationImage, elevationImage, kernelSize2D); - } - - // Set output layer. - cv::cv2eigen(elevationImage, map.get(layerOut)); -} - -void gaussianBlur(grid_map::GridMap& map, const std::string& layerIn, const std::string& layerOut, int kernelSize, double sigma) { - // Create new layer if missing. - if (!map.exists(layerOut)) { - map.add(layerOut); - } - - // Convert to image. - cv::Mat elevationImage; - cv::eigen2cv(map.get(layerIn), elevationImage); - - // Box blur. - cv::Size kernelSize2D(kernelSize, kernelSize); - cv::GaussianBlur(elevationImage, elevationImage, kernelSize2D, sigma); - - // Set output layer. - cv::cv2eigen(elevationImage, map.get(layerOut)); -} - -} // namespace smoothing -} // namespace grid_map diff --git a/plane_segmentation/grid_map_filters_rsl/test/TestDerivativeFilter.cpp b/plane_segmentation/grid_map_filters_rsl/test/TestDerivativeFilter.cpp deleted file mode 100644 index 6f04270a..00000000 --- a/plane_segmentation/grid_map_filters_rsl/test/TestDerivativeFilter.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @authors Fabian Jenelten - * @affiliation RSL - * @brief Tests for grid map derivative filter. - */ - -#include - -#include - -using namespace grid_map; - -TEST(TestGridMapDerivative, initialization) { // NOLINT - // Grid map with constant gradient. - GridMap map; - map.setGeometry(Length(1.0, 2.0), 0.1, Position(0.0, 0.0)); - map.add("elevation", 1.0); - const Eigen::MatrixXf H = map.get("elevation"); - GridMapIterator iterator(map); - - // Derivative filter. - derivative::GridMapDerivative derivativeFilter; - Eigen::Vector2d gradient; - Eigen::Matrix2d curvature; - - // Compute derivatives for each element and check if constant. - constexpr double threshold = 1.0e-9; - for (; !iterator.isPastEnd(); ++iterator) { - // Compute only gradient. - derivativeFilter.estimateGradient(map, gradient, *iterator, H); - EXPECT_TRUE(gradient.norm() < threshold); - - // Compute gradient and curvature. - derivativeFilter.estimateGradientAndCurvature(map, gradient, curvature, *iterator, H); - EXPECT_TRUE(gradient.norm() < threshold && curvature.norm() < threshold); - } - - EXPECT_TRUE(iterator.isPastEnd()); -} diff --git a/plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp b/plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp deleted file mode 100644 index c090a1e6..00000000 --- a/plane_segmentation/grid_map_filters_rsl/test/TestFilters.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/** - * @authors Fabian Jenelten - * @affiliation RSL - * @brief Tests for grid map filters. - */ - -#include - -#include - -using namespace grid_map; - -TEST(TestInpainting, initialization) { // NOLINT - // Grid map with constant gradient. - GridMap map; - map.setGeometry(Length(1.0, 2.0), 0.1, Position(0.0, 0.0)); - map.add("elevation", 1.0); - const Eigen::MatrixXf H0 = map.get("elevation"); - Eigen::MatrixXf& H_in = map.get("elevation"); - - // Set nan patches. - H_in.topLeftCorner<3, 3>(3, 3).setConstant(NAN); - H_in.middleRows<2>(5).setConstant(NAN); - - // Fill in nan values. - inpainting::nonlinearInterpolation(map, "elevation", "filled_nonlin", 0.1); - inpainting::minValues(map, "elevation", "filled_min"); - inpainting::biLinearInterpolation(map, "elevation", "filled_bilinear"); - - // Check if open-cv in-painting was successful. - constexpr double threshold = 1.0e-9; - const Eigen::MatrixXf& H_out_ref = map.get("filled_nonlin"); - EXPECT_FALSE(std::isnan(H_out_ref.norm())); - EXPECT_TRUE((H_out_ref - H0).norm() < threshold); - - // Compare against open-cv in-painting. - EXPECT_TRUE((H_out_ref - map.get("filled_min")).norm() < threshold); - EXPECT_TRUE((H_out_ref - map.get("filled_bilinear")).norm() < threshold); -} - -TEST(TestInpainting, minValuesAroundContour) { // NOLINT - // Grid map with constant gradient. - GridMap map; - map.setGeometry(Length(3.0, 3.0), 1.0, Position(0.0, 0.0)); - map.add("input", 1.0); - const Eigen::MatrixXf H0 = map.get("input"); - Eigen::MatrixXf& H_in = map.get("input"); - - // Set nan patches. - // clang-format off - H_in << NAN, 0.0, -1.0, - 1.0, NAN, NAN, - -2.0, 0.0, NAN; - Eigen::MatrixXf H_expected(3, 3); - H_expected << 0.0, 0.0, -1.0, - 1.0, -1.0, -1.0, - -2.0, 0.0, -1.0; - // clang-format on - - inpainting::minValues(map, "input", "filled_min"); - constexpr double threshold = 1.0e-9; - EXPECT_TRUE((H_expected - map.get("filled_min")).norm() < threshold); -} - -TEST(TestInpainting, minValuesOnlyNaN) { // NOLINT - // Grid map with only NaN, check that we don't end in infinite loop - GridMap map; - map.setGeometry(Length(3.0, 3.0), 1.0, Position(0.0, 0.0)); - map.add("input_nan", NAN); // layer with only NaN - map.add("input_nonan", 1.0); // layer with constant value - - inpainting::minValues(map, "input_nan", "filled_min_nan"); - inpainting::minValues(map, "input_nonan", "filled_min_nonan"); - - EXPECT_TRUE(map.get("filled_min_nan").hasNaN()); - EXPECT_DOUBLE_EQ(map.get("filled_min_nonan").minCoeff(), 1.0); -} - -TEST(TestResampling, resampleSameSize) { // NOLINT - const std::string layerName = "layer"; - - GridMap map; - map.setGeometry(Length(3.0, 2.01), 0.33, Position(0.1, 0.2)); - map.add(layerName); - map.get(layerName).setRandom(); - - GridMap resampleMap = map; - - inpainting::resample(resampleMap, layerName, map.getResolution()); - - // Compare geometry - EXPECT_TRUE(resampleMap.getSize().isApprox(map.getSize())); - EXPECT_TRUE(resampleMap.getPosition().isApprox(map.getPosition())); - EXPECT_DOUBLE_EQ(resampleMap.getResolution(), map.getResolution()); - - // Compare content - EXPECT_TRUE(resampleMap.get(layerName).isApprox(map.get(layerName))); -} - -TEST(TestResampling, resampleUpsample) { // NOLINT - const std::string layerName = "layer"; - const double oldRes = 1.0; - const double newRes = 0.5; - - GridMap map; - map.setGeometry(Length(3.0, 2.0), oldRes, Position(0.1, 0.2)); - map.add(layerName); - map.get(layerName).setRandom(); - - GridMap resampleMap = map; - - inpainting::resample(resampleMap, layerName, newRes); - - // Compare geometry - const Eigen::Vector2d oldTrueSize(map.getResolution() * map.getSize().x(), map.getResolution() * map.getSize().y()); - const Eigen::Vector2d newTrueSize(resampleMap.getResolution() * resampleMap.getSize().x(), - resampleMap.getResolution() * resampleMap.getSize().y()); - EXPECT_TRUE(newTrueSize.isApprox(oldTrueSize)); - EXPECT_TRUE(resampleMap.getPosition().isApprox(map.getPosition())); - EXPECT_DOUBLE_EQ(resampleMap.getResolution(), newRes); -} - -TEST(TestResampling, resampleDownsample) { // NOLINT - const std::string layerName = "layer"; - const double oldRes = 0.5; - const double newRes = 1.0; - - GridMap map; - map.setGeometry(Length(3.0, 2.0), oldRes, Position(0.1, 0.2)); - map.add(layerName); - map.get(layerName).setRandom(); - - GridMap resampleMap = map; - - inpainting::resample(resampleMap, layerName, newRes); - - // Compare geometry - const Eigen::Vector2d oldTrueSize(map.getResolution() * map.getSize().x(), map.getResolution() * map.getSize().y()); - const Eigen::Vector2d newTrueSize(resampleMap.getResolution() * resampleMap.getSize().x(), - resampleMap.getResolution() * resampleMap.getSize().y()); - EXPECT_TRUE(newTrueSize.isApprox(oldTrueSize)); - EXPECT_TRUE(resampleMap.getPosition().isApprox(map.getPosition())); - EXPECT_DOUBLE_EQ(resampleMap.getResolution(), newRes); -} \ No newline at end of file diff --git a/plane_segmentation/grid_map_filters_rsl/test/TestLookup.cpp b/plane_segmentation/grid_map_filters_rsl/test/TestLookup.cpp deleted file mode 100644 index b85fb6d3..00000000 --- a/plane_segmentation/grid_map_filters_rsl/test/TestLookup.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @authors Fabian Jenelten, Ruben Grandia - * @affiliation RSL - * @brief Tests for grid map lookup functions. - */ - -#include - -#include - -using namespace grid_map; - -TEST(TestLookup, maxValue_constant_map) { // NOLINT - // Grid map with constant value. - GridMap map; - map.setGeometry(Length(1.0, 2.0), 0.1, Position(0.1, 0.2)); - const float mapValue = 133.7; - map.add("elevation", mapValue); - const auto& data = map.get("elevation"); - - { // Normal lookup - const grid_map::Position position1(-0.1, -0.2); - const grid_map::Position position2(0.3, 0.4); - const auto result = lookup::maxValueBetweenLocations(position1, position2, map, data); - ASSERT_TRUE(result.isValid); - EXPECT_DOUBLE_EQ(result.value, mapValue); - } - - { // Start and end are the same - const grid_map::Position position1(-0.1, -0.2); - const grid_map::Position position2 = position1; - const auto result = lookup::maxValueBetweenLocations(position1, position2, map, data); - ASSERT_TRUE(result.isValid); - EXPECT_DOUBLE_EQ(result.value, mapValue); - } - - { // Start and end are outside of the map - const grid_map::Position position1(1000.0, 1000.0); - const grid_map::Position position2(2000.0, 2000.0); - const auto result = lookup::maxValueBetweenLocations(position1, position2, map, data); - ASSERT_TRUE(result.isValid); - EXPECT_DOUBLE_EQ(result.value, mapValue); - } -} - -TEST(TestLookup, maxValue_in_middle_map) { // NOLINT - // Grid map with random - GridMap map; - map.setGeometry(Length(1.0, 2.0), 0.1, Position(0.1, 0.2)); - map.add("elevation", 0.0); - auto& data = map.get("elevation"); - - // Create a parabola on the map - float checkMaxValue = std::numeric_limits::lowest(); - for (int col = 0; col < data.cols(); ++col) { - grid_map::Position p; - map.getPosition({0, col}, p); - float addedValue = -p.y() * p.y(); - checkMaxValue = std::max(checkMaxValue, addedValue); - data.col(col).setConstant(-p.y() * p.y()); - } - - const grid_map::Position position1(-0.5, -0.5); - const grid_map::Position position2(0.5, 0.5); - const auto result = lookup::maxValueBetweenLocations(position1, position2, map, data); - ASSERT_TRUE(result.isValid); - EXPECT_DOUBLE_EQ(result.value, checkMaxValue); -} - -TEST(TestLookup, maxValue_onlyNaN) { // NOLINT - // Grid map with constant value. - GridMap map; - map.setGeometry(Length(1.0, 2.0), 0.1, Position(0.1, 0.2)); - const float mapValue = std::numeric_limits::quiet_NaN(); - map.add("elevation", mapValue); - const auto& data = map.get("elevation"); - - const grid_map::Position position1(-0.1, -0.2); - const grid_map::Position position2(0.3, 0.4); - const auto result = lookup::maxValueBetweenLocations(position1, position2, map, data); - ASSERT_FALSE(result.isValid); -} diff --git a/sensor_processing/debug_publisher/image_debug_node.py b/sensor_processing/debug_publisher/image_debug_node.py deleted file mode 100644 index 6d625a68..00000000 --- a/sensor_processing/debug_publisher/image_debug_node.py +++ /dev/null @@ -1,38 +0,0 @@ -import rospy -import sys - -import numpy as np -import ros_numpy -import matplotlib.pyplot as plt -from skimage.io import imshow - -import message_filters -from sensor_msgs.msg import Image, CameraInfo -from sensor_msgs.msg import PointCloud2, Image -from cv_bridge import CvBridge - - -class ImageDebugNode: - def __init__(self): - # setup pointcloud creation - self.cv_bridge = CvBridge() - # rospy.Subscriber("", CameraInfo, self.cam_info_callback) - rospy.Subscriber("/zed2i/zed_node/right/image_rect_color", Image, self.image_callback) - self.debug_pub = rospy.Publisher("/debug_image", Image, queue_size=2) - - def image_callback(self, rgb_msg): - img = self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8") - out = np.zeros((img.shape[0], img.shape[1]), dtype=np.uint16) - out[:, : int(img.shape[1] / 2)] = 1 - seg_msg = self.cv_bridge.cv2_to_imgmsg(out, encoding="mono16") - seg_msg.header = rgb_msg.header - self.debug_pub.publish(seg_msg) - # seg_msg.header.frame_id = self.header.frame_id - # self.seg_pub.publish(seg_msg) - - -if __name__ == "__main__": - rospy.init_node("image_debug_node", anonymous=True, log_level=rospy.INFO) - print("Start Debug Image Node") - node = ImageDebugNode() - rospy.spin() diff --git a/sensor_processing/semantic_sensor/CMakeLists.txt b/sensor_processing/semantic_sensor/CMakeLists.txt deleted file mode 100644 index bdc8a1b7..00000000 --- a/sensor_processing/semantic_sensor/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -cmake_minimum_required(VERSION 3.0.2) -project(semantic_sensor) - -find_package(PythonInterp 3 REQUIRED) -find_package(PythonLibs 3 REQUIRED) - -if(PYTHONLIBS_FOUND) - message(STATUS "Using Python Libraries at: " ${PYTHON_LIBRARIES}) - message(STATUS "Using Python include directories at: " ${PYTHON_INCLUDE_DIRS}) -else() - message(WARNING "Could not find Python Libraries") -endif() - - -find_package(catkin REQUIRED COMPONENTS - message_generation - rospy - tf - tf_conversions - sensor_msgs - std_msgs - geometry_msgs -) - -catkin_package() - -catkin_python_setup() - - - -catkin_install_python(PROGRAMS script/semantic_sensor/pointcloud_node.py script/semantic_sensor/image_node.py - DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) - diff --git a/sensor_processing/semantic_sensor/config/sensor_parameter.yaml b/sensor_processing/semantic_sensor/config/sensor_parameter.yaml deleted file mode 100644 index 81fde9b1..00000000 --- a/sensor_processing/semantic_sensor/config/sensor_parameter.yaml +++ /dev/null @@ -1,31 +0,0 @@ -front_cam_pointcloud: - channels: ['rgb', 'chair','sofa',"person" ] - fusion: ['color','class_average','class_average','class_average'] - topic_name: 'front_camera/semantic_pointcloud' - semantic_segmentation: True - publish_segmentation_image: True - segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large - show_label_legend: False - data_type: pointcloud - - cam_info_topic: "camera/depth/camera_info" - image_topic: "camera/rgb/image_raw" - depth_topic: "camera/depth/image_raw" - cam_frame: "camera_rgb_optical_frame" - -front_cam_image: - channels: ['chair','sofa',"person"] - fusion_methods: ['exponential','exponential','exponential'] - publish_topic: 'semantic_image' - publish_image_topic: "semantic_image_debug" - publish_camera_info_topic: 'semantic_image_info' - publish_fusion_info_topic: 'semantic_image_fusion_info' - data_type: image - - semantic_segmentation: True - feature_extractor: True - segmentation_model: 'lraspp_mobilenet_v3_large' # detectron_coco_panoptic_fpn_R_101_3x, lraspp_mobilenet_v3_large - show_label_legend: False - image_topic: "camera/rgb/image_raw" - camera_info_topic: "camera/depth/camera_info" - resize: 0.5 \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/launch/semantic_image.launch b/sensor_processing/semantic_sensor/launch/semantic_image.launch deleted file mode 100644 index 8b6c01a1..00000000 --- a/sensor_processing/semantic_sensor/launch/semantic_image.launch +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch b/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch deleted file mode 100644 index 550638ff..00000000 --- a/sensor_processing/semantic_sensor/launch/semantic_pointcloud.launch +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/sensor_processing/semantic_sensor/package.xml b/sensor_processing/semantic_sensor/package.xml deleted file mode 100644 index 635775eb..00000000 --- a/sensor_processing/semantic_sensor/package.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - semantic_sensor - 0.0.0 - The semantic_sensor package - Gian Erni - - - MIT - - - https://github.com/leggedrobotics/elevation_mapping_semantic_cupy - - - Gian Erni - - catkin - rospy - roslib - tf - tf_conversions - sensor_msgs - std_msgs - geometry_msgs - - - diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/__init__.py b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py deleted file mode 100644 index 24e4bff9..00000000 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/modules.py +++ /dev/null @@ -1,126 +0,0 @@ -import semantic_sensor.DINO.vision_transformer as vits -import torch.nn as nn -import torch - - -class DinoFeaturizer(nn.Module): - def __init__(self, weights, cfg): - super().__init__() - self.cfg = cfg - self.dim = cfg.dim - - self.feat_type = self.cfg.dino_feat_type - arch = self.cfg.model - self.model = vits.__dict__[arch](patch_size=self.cfg.patch_size, num_classes=0) - for p in self.model.parameters(): - p.requires_grad = False - self.model.eval().cuda() - self.dropout = torch.nn.Dropout2d(p=0.1) - - if arch == "vit_small" and self.cfg.patch_size == 16: - url = "dino_deitsmall16_pretrain/dino_deitsmall16_pretrain.pth" - elif arch == "vit_small" and self.cfg.patch_size == 8: - url = "dino_deitsmall8_300ep_pretrain/dino_deitsmall8_300ep_pretrain.pth" - elif arch == "vit_base" and self.cfg.patch_size == 16: - url = "dino_vitbase16_pretrain/dino_vitbase16_pretrain.pth" - elif arch == "vit_base" and self.cfg.patch_size == 8: - url = "dino_vitbase8_pretrain/dino_vitbase8_pretrain.pth" - else: - raise ValueError("Unknown arch and patch size") - - state_dict = torch.hub.load_state_dict_from_url(url="https://dl.fbaipublicfiles.com/dino/" + url) - - self.model.load_state_dict(state_dict, strict=True) - - if arch == "vit_small": - self.n_feats = 384 - else: - self.n_feats = 768 - self.cluster1 = self.make_clusterer(self.n_feats) - self.proj_type = cfg.projection_type - if self.proj_type == "nonlinear": - self.cluster2 = self.make_nonlinear_clusterer(self.n_feats) - - def make_clusterer(self, in_channels): - """ - Function to make the clusterer model which consists of a single Conv2d layer. - The input channels are taken as the argument, and the output channels are equal to the `dim` of the model. - - Parameters: - in_channels (int): The number of input channels. - - Returns: - nn.Sequential: A sequential model consisting of a single Conv2d layer.""" - - return torch.nn.Sequential(torch.nn.Conv2d(in_channels, self.dim, (1, 1))) # , - - def make_nonlinear_clusterer(self, in_channels): - """ - Function to make the nonlinear clusterer model which consists of a series of Conv2d and ReLU layers. - The input channels are taken as the argument, and the output channels are equal to the `dim` of the model. - - Parameters: - in_channels (int): The number of input channels. - - Returns: - nn.Sequential: A sequential model consisting of a Conv2d layer, a ReLU layer, and another Conv2d layer. - """ - return torch.nn.Sequential( - torch.nn.Conv2d(in_channels, in_channels, (1, 1)), - torch.nn.ReLU(), - torch.nn.Conv2d(in_channels, self.dim, (1, 1)), - ) - - def forward(self, img, n=1, return_class_feat=False): - """ - Forward pass of the model. - The input image is passed through the `model` to get the intermediate features. - The intermediate features are then processed to get the final image feature and code. - If `return_class_feat` is set to True, the class features are returned instead. - - Parameters: - img (torch.Tensor): The input image tensor. - n (int, optional): The number of intermediate features to get. Default value is 1. 1 means only the features of the last block. - return_class_feat (bool, optional): Whether to return the class features. Default value is False. - - Returns: - tuple: If `cfg.dropout` is True, a tuple containing the final image feature and code is returned. - Otherwise, only the final image feature is returned. - If `return_class_feat` is True, the class features are returned instead. - """ - self.model.eval() - with torch.no_grad(): - assert img.shape[2] % self.cfg.patch_size == 0 - assert img.shape[3] % self.cfg.patch_size == 0 - - # get selected layer activations - feat, attn, qkv = self.model.get_intermediate_feat(img, n=n) - feat, attn, qkv = feat[0], attn[0], qkv[0] - - feat_h = img.shape[2] // self.cfg.patch_size - feat_w = img.shape[3] // self.cfg.patch_size - - if self.feat_type == "feat": - # deflatten - image_feat = feat[:, 1:, :].reshape(feat.shape[0], feat_h, feat_w, -1).permute(0, 3, 1, 2) - elif self.feat_type == "KK": - image_k = qkv[1, :, :, 1:, :].reshape(feat.shape[0], 6, feat_h, feat_w, -1) - B, H, I, J, D = image_k.shape - image_feat = image_k.permute(0, 1, 4, 2, 3).reshape(B, H * D, I, J) - else: - raise ValueError("Unknown feat type:{}".format(self.feat_type)) - - if return_class_feat: - return feat[:, :1, :].reshape(feat.shape[0], 1, 1, -1).permute(0, 3, 1, 2) - - if self.proj_type is not None: - code = self.cluster1(self.dropout(image_feat)) - if self.proj_type == "nonlinear": - code += self.cluster2(self.dropout(image_feat)) - else: - code = image_feat - - if self.cfg.dropout: - return self.dropout(image_feat), code - else: - return image_feat, code diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/utils.py b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/utils.py deleted file mode 100644 index 1bc84057..00000000 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/utils.py +++ /dev/null @@ -1,46 +0,0 @@ -import torch -import warnings -import math - - -def _no_grad_trunc_normal_(tensor, mean, std, a, b): - # Cut & paste from PyTorch official master until it's in a few official releases - RW - # Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf - def norm_cdf(x): - # Computes standard normal cumulative distribution function - return (1.0 + math.erf(x / math.sqrt(2.0))) / 2.0 - - if (mean < a - 2 * std) or (mean > b + 2 * std): - warnings.warn( - "mean is more than 2 std from [a, b] in nn.init.trunc_normal_. " - "The distribution of values may be incorrect.", - stacklevel=2, - ) - - with torch.no_grad(): - # Values are generated by using a truncated uniform distribution and - # then using the inverse CDF for the normal distribution. - # Get upper and lower cdf values - l = norm_cdf((a - mean) / std) - u = norm_cdf((b - mean) / std) - - # Uniformly fill tensor with values from [l, u], then translate to - # [2l-1, 2u-1]. - tensor.uniform_(2 * l - 1, 2 * u - 1) - - # Use inverse cdf transform for normal distribution to get truncated - # standard normal - tensor.erfinv_() - - # Transform to proper mean, std - tensor.mul_(std * math.sqrt(2.0)) - tensor.add_(mean) - - # Clamp to ensure it's in the proper range - tensor.clamp_(min=a, max=b) - return tensor - - -def trunc_normal_(tensor, mean=0.0, std=1.0, a=-2.0, b=2.0): - # type: (Tensor, float, float, float, float) -> Tensor - return _no_grad_trunc_normal_(tensor, mean, std, a, b) diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py b/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py deleted file mode 100644 index 53abd17a..00000000 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/DINO/vision_transformer.py +++ /dev/null @@ -1,385 +0,0 @@ -""" -Mostly copy-paste from timm library. -https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py -""" -import math -from functools import partial - -import torch -import torch.nn as nn -from semantic_sensor.DINO.utils import trunc_normal_ - - -def drop_path(x, drop_prob: float = 0.0, training: bool = False): - if drop_prob == 0.0 or not training: - return x - keep_prob = 1 - drop_prob - shape = (x.shape[0],) + (1,) * (x.ndim - 1) # work with diff dim tensors, not just 2D ConvNets - random_tensor = keep_prob + torch.rand(shape, dtype=x.dtype, device=x.device) - random_tensor.floor_() # binarize - output = x.div(keep_prob) * random_tensor - return output - - -class DropPath(nn.Module): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" - - def __init__(self, drop_prob=None): - super(DropPath, self).__init__() - self.drop_prob = drop_prob - - def forward(self, x): - return drop_path(x, self.drop_prob, self.training) - - -class Mlp(nn.Module): - def __init__( - self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.0, - ): - super().__init__() - out_features = out_features or in_features - hidden_features = hidden_features or in_features - self.fc1 = nn.Linear(in_features, hidden_features) - self.act = act_layer() - self.fc2 = nn.Linear(hidden_features, out_features) - self.drop = nn.Dropout(drop) - - def forward(self, x): - x = self.fc1(x) - x = self.act(x) - x = self.drop(x) - x = self.fc2(x) - x = self.drop(x) - return x - - -class Attention(nn.Module): - def __init__( - self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0.0, proj_drop=0.0, - ): - super().__init__() - # number of attention heads - self.num_heads = num_heads - # dimension of each head - head_dim = dim // num_heads - # scale factor for the attention scores - self.scale = qk_scale or head_dim ** -0.5 - - # linear layer to project the input to 3 times the dimension - self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) - # dropout layer to drop out activations in the attention mechanism - self.attn_drop = nn.Dropout(attn_drop) - # linear layer to project the output back to the original dimension - self.proj = nn.Linear(dim, dim) - # dropout layer to drop out activations in the projection layer - self.proj_drop = nn.Dropout(proj_drop) - - def forward(self, x, return_qkv=False): - # get the batch size, sequence length, and input dimension - B, N, C = x.shape - # project the input to 3 times the dimension, multiplication with W matrix - qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) - # separate the input into queries: info about word in relation to others, keys: how one word influences others, and values: how word sees itself - q, k, v = qkv[0], qkv[1], qkv[2] - - # compute the attention scores - attn = (q @ k.transpose(-2, -1)) * self.scale - attn = attn.softmax(dim=-1) - # drop out activations in the attention mechanism - attn = self.attn_drop(attn) - - # compute the weighted sum of values - x = (attn @ v).transpose(1, 2).reshape(B, N, C) - # project the output back to the original dimension - x = self.proj(x) - # drop out activations in the projection layer - x = self.proj_drop(x) - - # return the attention mechanism and the projected input - return x, attn, qkv if return_qkv else x - - -class Block(nn.Module): - def __init__( - self, - dim, - num_heads, - mlp_ratio=4.0, - qkv_bias=False, - qk_scale=None, - drop=0.0, - attn_drop=0.0, - drop_path=0.0, - act_layer=nn.GELU, - norm_layer=nn.LayerNorm, - ): - super().__init__() - self.norm1 = norm_layer(dim) - self.attn = Attention( - dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop, - ) - self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity() - self.norm2 = norm_layer(dim) - mlp_hidden_dim = int(dim * mlp_ratio) - self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop,) - - def forward(self, x, return_attention=False, return_qkv=False): - y, attn, qkv = self.attn(self.norm1(x)) - if return_attention: - return attn - x = x + self.drop_path(y) - x = x + self.drop_path(self.mlp(self.norm2(x))) - if return_qkv: - return x, attn, qkv - return x - - -class PatchEmbed(nn.Module): - """Image to Patch Embedding""" - - def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768): - super().__init__() - num_patches = (img_size // patch_size) * (img_size // patch_size) - self.img_size = img_size - self.patch_size = patch_size - self.num_patches = num_patches - - self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) - - def forward(self, x): - B, C, H, W = x.shape - x = self.proj(x).flatten(2).transpose(1, 2) - return x - - -class VisionTransformer(nn.Module): - """Vision Transformer""" - - def __init__( - self, - img_size=[224], - patch_size=16, - in_chans=3, - num_classes=0, - embed_dim=768, - depth=12, - num_heads=12, - mlp_ratio=4.0, - qkv_bias=False, - qk_scale=None, - drop_rate=0.0, - attn_drop_rate=0.0, - drop_path_rate=0.0, - norm_layer=nn.LayerNorm, - **kwargs - ): - super().__init__() - - self.num_features = self.embed_dim = embed_dim - - self.patch_embed = PatchEmbed( - img_size=img_size[0], patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim, - ) - num_patches = self.patch_embed.num_patches - - self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim)) - self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim)) - self.pos_drop = nn.Dropout(p=drop_rate) - - dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)] # stochastic depth decay rule - self.blocks = nn.ModuleList( - [ - Block( - dim=embed_dim, - num_heads=num_heads, - mlp_ratio=mlp_ratio, - qkv_bias=qkv_bias, - qk_scale=qk_scale, - drop=drop_rate, - attn_drop=attn_drop_rate, - drop_path=dpr[i], - norm_layer=norm_layer, - ) - for i in range(depth) - ] - ) - self.norm = norm_layer(embed_dim) - - # Classifier head - self.head = nn.Linear(embed_dim, num_classes) if num_classes > 0 else nn.Identity() - - trunc_normal_(self.pos_embed, std=0.02) - trunc_normal_(self.cls_token, std=0.02) - self.apply(self._init_weights) - - def _init_weights(self, m): - if isinstance(m, nn.Linear): - trunc_normal_(m.weight, std=0.02) - if isinstance(m, nn.Linear) and m.bias is not None: - nn.init.constant_(m.bias, 0) - elif isinstance(m, nn.LayerNorm): - nn.init.constant_(m.bias, 0) - nn.init.constant_(m.weight, 1.0) - - def interpolate_pos_encoding(self, x, w, h): - npatch = x.shape[1] - 1 - N = self.pos_embed.shape[1] - 1 - if npatch == N and w == h: - return self.pos_embed - class_pos_embed = self.pos_embed[:, 0] - patch_pos_embed = self.pos_embed[:, 1:] - dim = x.shape[-1] - w0 = w // self.patch_embed.patch_size - h0 = h // self.patch_embed.patch_size - # we add a small number to avoid floating point error in the interpolation - # see discussion at https://github.com/facebookresearch/dino/issues/8 - w0, h0 = w0 + 0.1, h0 + 0.1 - patch_pos_embed = nn.functional.interpolate( - patch_pos_embed.reshape(1, int(math.sqrt(N)), int(math.sqrt(N)), dim).permute(0, 3, 1, 2), - scale_factor=(w0 / math.sqrt(N), h0 / math.sqrt(N)), - mode="bicubic", - ) - assert int(w0) == patch_pos_embed.shape[-2] and int(h0) == patch_pos_embed.shape[-1] - patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim) - return torch.cat((class_pos_embed.unsqueeze(0), patch_pos_embed), dim=1) - - def prepare_tokens(self, x): - B, nc, w, h = x.shape - x = self.patch_embed(x) # patch linear embedding - - # add the [CLS] token to the embed patch tokens - cls_tokens = self.cls_token.expand(B, -1, -1) - x = torch.cat((cls_tokens, x), dim=1) - - # add positional encoding to each token - x = x + self.interpolate_pos_encoding(x, w, h) - - return self.pos_drop(x) - - def forward(self, x): - x = self.prepare_tokens(x) - for blk in self.blocks: - x = blk(x) - x = self.norm(x) - return x[:, 0] - - def forward_feats(self, x): - x = self.prepare_tokens(x) - for blk in self.blocks: - x = blk(x) - x = self.norm(x) - return x - - def get_intermediate_feat(self, x, n=1): - x = self.prepare_tokens(x) - # we return the output tokens from the `n` last blocks - feat = [] - attns = [] - qkvs = [] - for i, blk in enumerate(self.blocks): - x, attn, qkv = blk(x, return_qkv=True) - if len(self.blocks) - i <= n: - feat.append(self.norm(x)) - qkvs.append(qkv) - attns.append(attn) - return feat, attns, qkvs - - def get_last_selfattention(self, x): - x = self.prepare_tokens(x) - for i, blk in enumerate(self.blocks): - if i < len(self.blocks) - 1: - x = blk(x) - else: - # return attention of the last block - return blk(x, return_attention=True) - - def get_intermediate_layers(self, x, n=1): - x = self.prepare_tokens(x) - # we return the output tokens from the `n` last blocks - output = [] - for i, blk in enumerate(self.blocks): - x = blk(x) - if len(self.blocks) - i <= n: - output.append(self.norm(x)) - return output - - -def vit_tiny(patch_size=16, **kwargs): - model = VisionTransformer( - patch_size=patch_size, - embed_dim=192, - depth=12, - num_heads=3, - mlp_ratio=4, - qkv_bias=True, - norm_layer=partial(nn.LayerNorm, eps=1e-6), - **kwargs - ) - return model - - -def vit_small(patch_size=16, **kwargs): - model = VisionTransformer( - patch_size=patch_size, - embed_dim=384, - depth=12, - num_heads=6, - mlp_ratio=4, - qkv_bias=True, - norm_layer=partial(nn.LayerNorm, eps=1e-6), - **kwargs - ) - return model - - -def vit_base(patch_size=16, **kwargs): - model = VisionTransformer( - patch_size=patch_size, - embed_dim=768, - depth=12, - num_heads=12, - mlp_ratio=4, - qkv_bias=True, - norm_layer=partial(nn.LayerNorm, eps=1e-6), - **kwargs - ) - return model - - -class DINOHead(nn.Module): - def __init__( - self, in_dim, out_dim, use_bn=False, norm_last_layer=True, nlayers=3, hidden_dim=2048, bottleneck_dim=256, - ): - super().__init__() - nlayers = max(nlayers, 1) - if nlayers == 1: - self.mlp = nn.Linear(in_dim, bottleneck_dim) - else: - layers = [nn.Linear(in_dim, hidden_dim)] - if use_bn: - layers.append(nn.BatchNorm1d(hidden_dim)) - layers.append(nn.GELU()) - for _ in range(nlayers - 2): - layers.append(nn.Linear(hidden_dim, hidden_dim)) - if use_bn: - layers.append(nn.BatchNorm1d(hidden_dim)) - layers.append(nn.GELU()) - layers.append(nn.Linear(hidden_dim, bottleneck_dim)) - self.mlp = nn.Sequential(*layers) - self.apply(self._init_weights) - self.last_layer = nn.utils.weight_norm(nn.Linear(bottleneck_dim, out_dim, bias=False)) - self.last_layer.weight_g.data.fill_(1) - if norm_last_layer: - self.last_layer.weight_g.requires_grad = False - - def _init_weights(self, m): - if isinstance(m, nn.Linear): - trunc_normal_(m.weight, std=0.02) - if isinstance(m, nn.Linear) and m.bias is not None: - nn.init.constant_(m.bias, 0) - - def forward(self, x): - x = self.mlp(x) - x = nn.functional.normalize(x, dim=-1, p=2) - x = self.last_layer(x) - return x diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/__init__.py b/sensor_processing/semantic_sensor/script/semantic_sensor/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py deleted file mode 100755 index e64991f1..00000000 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_node.py +++ /dev/null @@ -1,294 +0,0 @@ -#!/usr/bin/env python - -import rospy -import sys - -import numpy as np -import cupy as cp -import cv2 - -np.float = np.float64 # temp fix for following import suggested at https://github.com/eric-wieser/ros_numpy/issues/37 -np.bool = np.bool_ -import ros_numpy -import matplotlib.pyplot as plt -from skimage.io import imshow - -import message_filters -from sensor_msgs.msg import Image, CameraInfo -from sensor_msgs.msg import PointCloud2, Image, CompressedImage -from cv_bridge import CvBridge - -from semantic_sensor.image_parameters import ImageParameter -from semantic_sensor.networks import resolve_model -from sklearn.decomposition import PCA - -from elevation_map_msgs.msg import ChannelInfo - - -class SemanticSegmentationNode: - def __init__(self, sensor_name): - """Get parameter from server, initialize variables and semantics, register publishers and subscribers. - - Args: - sensor_name (str): Name of the sensor in the ros param server. - """ - # TODO: if this is going to be loaded from another package we might need to change namespace - self.param: ImageParameter = ImageParameter() - self.param.feature_config.input_size = [80, 160] - namespace = rospy.get_name() - if rospy.has_param(namespace): - config = rospy.get_param(namespace) - self.param: ImageParameter = ImageParameter.from_dict(config[sensor_name]) - else: - print("NO ROS ENV found.") - - print("--------------Pointcloud Parameters-------------------") - print(self.param.dumps_yaml()) - print("--------------End of Parameters-----------------------") - self.semseg_color_map = None - # setup custom dtype - # setup semantics - self.feature_extractor = None - self.semantic_model = None - self.initialize_semantics() - - # setup pointcloud creation - self.cv_bridge = CvBridge() - self.P = None - self.header = None - self.register_sub_pub() - self.prediction_img = None - - def initialize_semantics(self): - if self.param.semantic_segmentation: - self.semantic_model = resolve_model(self.param.segmentation_model, self.param) - - if self.param.feature_extractor: - self.feature_extractor = resolve_model(self.param.feature_config.name, self.param.feature_config) - - def register_sub_pub(self): - """Register publishers and subscribers.""" - - node_name = rospy.get_name() - # subscribers - if self.param.camera_info_topic is not None and self.param.resize is not None: - rospy.Subscriber(self.param.camera_info_topic, CameraInfo, self.image_info_callback) - self.feat_im_info_pub = rospy.Publisher( - node_name + "/" + self.param.camera_info_topic + "_resized", CameraInfo, queue_size=2 - ) - - if "compressed" in self.param.image_topic: - self.compressed = True - self.subscriber = rospy.Subscriber( - self.param.image_topic, CompressedImage, self.image_callback, queue_size=2 - ) - else: - self.compressed = False - rospy.Subscriber(self.param.image_topic, Image, self.image_callback) - - # publishers - if self.param.semantic_segmentation: - self.seg_pub = rospy.Publisher(node_name + "/" + self.param.publish_topic, Image, queue_size=2) - self.seg_im_pub = rospy.Publisher(node_name + "/" + self.param.publish_image_topic, Image, queue_size=2) - self.semseg_color_map = self.color_map(len(self.param.channels)) - if self.param.show_label_legend: - self.color_map_viz() - if self.param.feature_extractor: - self.feature_pub = rospy.Publisher(node_name + "/" + self.param.feature_topic, Image, queue_size=2) - self.feat_im_pub = rospy.Publisher(node_name + "/" + self.param.feat_image_topic, Image, queue_size=2) - self.feat_channel_info_pub = rospy.Publisher( - node_name + "/" + self.param.feat_channel_info_topic, ChannelInfo, queue_size=2 - ) - - self.channel_info_pub = rospy.Publisher( - node_name + "/" + self.param.channel_info_topic, ChannelInfo, queue_size=2 - ) - - def color_map(self, N=256, normalized=False): - """Create a color map for the class labels. - - Args: - N (int): - normalized (bool): - """ - - def bitget(byteval, idx): - return (byteval & (1 << idx)) != 0 - - dtype = "float32" if normalized else "uint8" - cmap = np.zeros((N + 1, 3), dtype=dtype) - for i in range(N + 1): - r = g = b = 0 - c = i - for j in range(8): - r = r | (bitget(c, 0) << 7 - j) - g = g | (bitget(c, 1) << 7 - j) - b = b | (bitget(c, 2) << 7 - j) - c = c >> 3 - - cmap[i] = np.array([r, g, b]) - cmap[1] = np.array([81, 113, 162]) - cmap[2] = np.array([81, 113, 162]) - cmap[3] = np.array([188, 63, 59]) - cmap = cmap / 255 if normalized else cmap - return cmap[1:] - - def color_map_viz(self): - """Display the color map of the classes.""" - nclasses = len(self.param.channels) - row_size = 50 - col_size = 500 - if self.param.semantic_segmentation: - cmap = self.semseg_color_map - array = np.empty((row_size * (nclasses), col_size, cmap.shape[1]), dtype=cmap.dtype) - for i in range(nclasses): - array[i * row_size : i * row_size + row_size, :] = cmap[i] - imshow(array) - plt.yticks([row_size * i + row_size / 2 for i in range(nclasses)], self.param.channels) - plt.xticks([]) - plt.show() - - def image_info_callback(self, msg): - """Callback for camera info. - - Args: - msg (CameraInfo): - """ - self.P = np.array(msg.P).reshape(3, 4) - self.height = int(self.param.resize * msg.height) - self.width = int(self.param.resize * msg.width) - self.info = msg - self.info.height = self.height - self.info.width = self.width - self.P = np.array(msg.P).reshape(3, 4) - self.P[:2, :3] = self.P[:2, :3] * self.param.resize - self.info.K = self.P[:3, :3].flatten().tolist() - self.info.P = self.P.flatten().tolist() - - def image_callback(self, rgb_msg): - if self.P is None: - return - if self.compressed: - image = self.cv_bridge.compressed_imgmsg_to_cv2(rgb_msg) - if self.param.resize is not None: - image = cv2.resize(image, dsize=(self.width, self.height)) - image = cp.asarray(image) - else: - image = self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8") - if self.param.resize is not None: - image = cv2.resize(image, dsize=(self.width, self.height)) - image = cp.asarray(image) - self.header = rgb_msg.header - self.process_image(image) - - if self.param.semantic_segmentation: - self.publish_segmentation() - self.publish_segmentation_image() - self.publish_channel_info([f"sem_{c}" for c in self.param.channels], self.channel_info_pub) - if self.param.feature_extractor: - self.publish_feature() - self.publish_feature_image(self.features) - self.publish_channel_info([f"feat_{i}" for i in range(self.features.shape[0])], self.feat_channel_info_pub) - if self.param.resize is not None: - self.pub_info() - - def pub_info(self): - self.feat_im_info_pub.publish(self.info) - - def publish_channel_info(self, channels, pub): - """Publish fusion info.""" - info = ChannelInfo() - info.header = self.header - info.channels = channels - pub.publish(info) - - def process_image(self, image): - """Depending on setting generate color, semantic segmentation or feature channels. - - Args: - image: - u: - v: - points: - """ - if self.param.semantic_segmentation: - self.sem_seg = self.semantic_model["model"](image) - - if self.param.feature_extractor: - self.features = self.feature_extractor["model"](image) - - def publish_segmentation(self): - probabilities = self.sem_seg - img = probabilities.get() - img = np.transpose(img, (1, 2, 0)).astype(np.float32) - seg_msg = self.cv_bridge.cv2_to_imgmsg(img, encoding="passthrough") - seg_msg.header.frame_id = self.header.frame_id - seg_msg.header.stamp = self.header.stamp - self.seg_pub.publish(seg_msg) - - def publish_feature(self): - features = self.features - img = features.cpu().detach().numpy() - img = np.transpose(img, (1, 2, 0)).astype(np.float32) - feature_msg = self.cv_bridge.cv2_to_imgmsg(img, encoding="passthrough") - feature_msg.header.frame_id = self.header.frame_id - feature_msg.header.stamp = self.header.stamp - self.feature_pub.publish(feature_msg) - - def publish_segmentation_image(self): - colors = None - probabilities = self.sem_seg - if self.param.semantic_segmentation: - colors = cp.asarray(self.semseg_color_map) - assert colors.ndim == 2 and colors.shape[1] == 3 - - # prob = cp.zeros((len(self.param.channels),) + probabilities.shape[1:]) - # if "class_max" in self.param.fusion: - # # decode, create an array with all possible classes and insert probabilities - # it = 0 - # for iit, (chan, fuse) in enumerate(zip(self.param.channels, self.param.fusion)): - # if fuse in ["class_max"]: - # temp = probabilities[it] - # temp_p, temp_i = decode_max(temp) - # temp_i.choose(prob) - # c = cp.mgrid[0 : temp_i.shape[0], 0 : temp_i.shape[1]] - # prob[temp_i, c[0], c[1]] = temp_p - # it += 1 - # elif fuse in ["class_bayesian", "class_average"]: - # # assign fixed probability to correct index - # if chan in self.semantic_model["model"].segmentation_channels: - # prob[self.semantic_model["model"].segmentation_channels[chan]] = probabilities[it] - # it += 1 - # img = cp.argmax(prob, axis=0) - # - # else: - img = cp.argmax(probabilities, axis=0) - img = colors[img].astype(cp.uint8) # N x H x W x 3 - img = img.get() - seg_msg = self.cv_bridge.cv2_to_imgmsg(img, encoding="rgb8") - seg_msg.header.frame_id = self.header.frame_id - seg_msg.header.stamp = self.header.stamp - self.seg_im_pub.publish(seg_msg) - - def publish_feature_image(self, features): - data = np.reshape(features.cpu().detach().numpy(), (features.shape[0], -1)).T - n_components = 3 - pca = PCA(n_components=n_components).fit(data) - pca_descriptors = pca.transform(data) - img_pca = pca_descriptors.reshape(features.shape[1], features.shape[2], n_components) - comp = img_pca # [:, :, -3:] - comp_min = comp.min(axis=(0, 1)) - comp_max = comp.max(axis=(0, 1)) - comp_img = (comp - comp_min) / (comp_max - comp_min) - comp_img = (comp_img * 255).astype(np.uint8) - feat_msg = self.cv_bridge.cv2_to_imgmsg(comp_img, encoding="passthrough") - feat_msg.header.frame_id = self.header.frame_id - self.feat_im_pub.publish(feat_msg) - - -if __name__ == "__main__": - arg = sys.argv[1] - sensor_name = arg - rospy.init_node("semantic_segmentation_node", anonymous=True, log_level=rospy.INFO) - node = SemanticSegmentationNode(sensor_name) - rospy.spin() diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py b/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py deleted file mode 100644 index 6ad67027..00000000 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/image_parameters.py +++ /dev/null @@ -1,42 +0,0 @@ -from dataclasses import dataclass, field -from simple_parsing.helpers import Serializable - - -@dataclass -class FeatureExtractorParameter(Serializable): - name: str = "DINO" - interpolation: str = "bilinear" - model: str = "vit_small" - patch_size: int = 16 - dim: int = 10 - dropout: bool = False - dino_feat_type: str = "feat" - projection_type: str = "nonlinear" - input_size: list = field(default_factory=lambda: [80, 160]) - pcl: bool = False - - -@dataclass -class ImageParameter(Serializable): - image_topic: str = "/alphasense_driver_ros/cam4/debayered" - - semantic_segmentation: bool = True - # sem_seg_topic: str = "semantic_seg" - # sem_seg_image_topic: str = "semantic_seg_im" - # publish_camera_info_topic: str = "semantic_seg/camera_info" - segmentation_model: str = "detectron_coco_panoptic_fpn_R_101_3x" - show_label_legend: bool = False - channels: list = field(default_factory=lambda: ["grass", "road", "tree", "sky"]) - - publish_topic: str = "semantic_seg" - publish_image_topic: str = "semantic_seg_img" - channel_info_topic: str = "channel_info" - - feature_extractor: bool = False - feature_config: FeatureExtractorParameter = FeatureExtractorParameter - # feature_config.input_size: list = field(default_factory=lambda: [80, 160]) - feature_topic: str = "semantic_seg_feat" - feat_image_topic: str = "semantic_seg_feat_im" - feat_channel_info_topic: str = "feat_channel_info" - resize: float = None - camera_info_topic: str = "camera_info" diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py b/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py deleted file mode 100644 index e64b4497..00000000 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/networks.py +++ /dev/null @@ -1,291 +0,0 @@ -from torchvision.models.segmentation import fcn_resnet50, FCN_ResNet50_Weights -from torchvision.models.segmentation import ( - lraspp_mobilenet_v3_large, - LRASPP_MobileNet_V3_Large_Weights, -) -from torchvision.models.segmentation import deeplabv3_mobilenet_v3_large, DeepLabV3_MobileNet_V3_Large_Weights -import torch -import torchvision.transforms.functional as TF -from torchvision.transforms import Resize -import torch.nn.functional as NF -import numpy as np -import cupy as cp - -from detectron2.utils.logger import setup_logger - -setup_logger() - -from detectron2 import model_zoo -from detectron2.engine import DefaultPredictor -from detectron2.config import get_cfg -from detectron2.data import MetadataCatalog - -from semantic_sensor.DINO.modules import DinoFeaturizer - -from semantic_sensor.pointcloud_parameters import ( - PointcloudParameter, - FeatureExtractorParameter, -) -from semantic_sensor.utils import encode_max - - -def resolve_model(name, config=None): - """Get the model class based on the name of the pretrained model. - - Args: - name (str): Name of pretrained model - [fcn_resnet50,lraspp_mobilenet_v3_large,detectron_coco_panoptic_fpn_R_101_3x] - - Returns: - Dict[str, str]: - """ - if name == "fcn_resnet50": - weights = FCN_ResNet50_Weights.DEFAULT - net = fcn_resnet50 - model = PytorchModel(net, weights, config) - return { - "name": "fcn_resnet50", - "model": model, - } - elif name == "lraspp_mobilenet_v3_large": - weights = LRASPP_MobileNet_V3_Large_Weights.DEFAULT - net = lraspp_mobilenet_v3_large - model = PytorchModel(net, weights, config) - return { - "name": "lraspp_mobilenet_v3_large", - "model": model, - } - elif name == "deeplabv3_mobilenet_v3_large": - weights = DeepLabV3_MobileNet_V3_Large_Weights.COCO_WITH_VOC_LABELS_V1 - net = deeplabv3_mobilenet_v3_large - model = PytorchModel(net, weights, config) - return { - "name": "deeplabv3_mobilenet_v3_large", - "model": model, - } - elif name == "detectron_coco_panoptic_fpn_R_101_3x": - # "Cityscapes/mask_rcnn_R_50_FPN.yaml" - # "Misc/semantic_R_50_FPN_1x.yaml" - # "Cityscapes-SemanticSegmentation/deeplab_v3_plus_R_103_os16_mg124_poly_90k_bs16.yaml" - # "COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml" - weights = "COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml" - model = DetectronModel(weights, config) - return { - "name": "detectron_coco_panoptic_fpn_R_101_3x", - "model": model, - } - elif name == "DINO": - weights = config.model + str(config.patch_size) - model = STEGOModel(weights, config) - return { - "name": config.model + str(config.patch_size), - "model": model, - } - else: - raise NotImplementedError - - -class PytorchModel: - """ - - segemntation_cahnnels contains only classes - actual_channels: array of all channels of output - """ - - def __init__(self, net, weights, param): - self.model = net(weights=weights) - self.weights = weights - self.param = param - self.model.eval() - device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") - self.model.to(device=device) - self.resolve_categories() - - def resolve_categories(self): - """Create a segmentation_channels containing the actual values that are processed.""" - # get all classes - class_to_idx = {cls: idx for (idx, cls) in enumerate(self.get_classes())} - print( - "Semantic Segmentation possible channels: ", self.get_classes(), - ) - indices = [] - channels = [] - self.actual_channels = [] - # check correspondence of semseg and paramter classes, class_max - for it, chan in enumerate(self.param.channels): - if chan in [cls for cls in list(class_to_idx.keys())]: - indices.append(class_to_idx[chan]) - channels.append(chan) - self.actual_channels.append(chan) - else: - self.actual_channels.append(chan) - # elif self.param.fusion_methods[it] in ["class_average", "class_bayesian"]: - # print(chan, " is not in the semantic segmentation model.") - # for it, chan in enumerate(self.param.channels): - # self.actual_channels.append(chan) - # if self.param.fusion_methods[it] in ["class_max"]: - # self.actual_channels.append(chan) - # print( - # chan, - # " is not in the semantic segmentation model but is a max channel.", - # ) - # else: - # pass - self.stuff_categories = dict(zip(channels, indices)) - self.segmentation_channels = dict(zip(channels, indices)) - - def __call__(self, image, *args, **kwargs): - """Feedforward image through model and then create channels - - Args: - image (cupy._core.core.ndarray): - *args (): - **kwargs (): - - Returns: - torch.Tensor: - """ - batch = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) - batch = TF.convert_image_dtype(batch, torch.float32) - with torch.no_grad(): - prediction = self.model(batch)["out"] - normalized_masks = torch.squeeze(prediction.softmax(dim=1), dim=0) - # get masks of fix classes - selected_masks = cp.asarray(normalized_masks[list(self.stuff_categories.values())]) - # get values of max, first remove the ones we already have - normalized_masks[list(self.stuff_categories.values())] = 0 - # for i in range(self.param.fusion_methods.count("class_max")): - # maxim, index = torch.max(normalized_masks, dim=0) - # mer = encode_max(maxim, index) - # selected_masks = cp.concatenate((selected_masks, cp.expand_dims(mer, axis=0)), axis=0) - # x = torch.arange(0, index.shape[0]) - # y = torch.arange(0, index.shape[1]) - # c = torch.meshgrid(x, y, indexing="ij") - # normalized_masks[index, c[0], c[1]] = 0 - assert len(self.actual_channels) == selected_masks.shape[0] - return cp.asarray(selected_masks) - - def get_classes(self): - """Get list of strings containing all the classes. - - Returns: - List[str]: List of classes - """ - return self.weights.meta["categories"] - - -class DetectronModel: - def __init__(self, weights, param): - self.cfg = get_cfg() - self.param = param - - # add project-specific config (e.g., TensorMask) here if you're not running a model in detectron2's core library - self.cfg.merge_from_file(model_zoo.get_config_file(weights)) - self.cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5 # set threshold for this model - # Find a model from detectron2's model zoo. You can use the https://dl.fbaipublicfiles... url as well - self.cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(weights) - self.predictor = DefaultPredictor(self.cfg) - self.metadata = MetadataCatalog.get(self.cfg.DATASETS.TRAIN[0]) - self.stuff_categories, self.is_stuff = self.resolve_categories("stuff_classes") - self.thing_categories, self.is_thing = self.resolve_categories("thing_classes") - self.segmentation_channels = {} - for chan in self.param.channels: - if chan in self.stuff_categories.keys(): - self.segmentation_channels[chan] = self.stuff_categories[chan] - elif chan in self.thing_categories.keys(): - self.segmentation_channels[chan] = self.thing_categories[chan] - else: - # remove it - pass - self.actual_channels = self.segmentation_channels.keys() - - def resolve_categories(self, name): - classes = self.get_category(name) - class_to_idx = {cls: idx for (idx, cls) in enumerate(classes)} - print( - "Semantic Segmentation possible channels: ", classes, - ) - indices = [] - channels = [] - is_thing = [] - for it, channel in enumerate(self.param.channels): - if channel in [cls for cls in list(class_to_idx.keys())]: - indices.append(class_to_idx[channel]) - channels.append(channel) - is_thing.append(True) - elif self.param.fusion_methods[it] in ["class_average", "class_bayesian"]: - is_thing.append(False) - print(channel, " is not in the semantic segmentation model.") - categories = dict(zip(channels, indices)) - category_isthing = dict(zip(self.param.channels, is_thing)) - return categories, category_isthing - - def __call__(self, image, *args, **kwargs): - # TODO: there are some instruction on how to change input type - image = cp.flip(image, axis=2) - prediction = self.predictor(image.get()) - probabilities = cp.asarray(torch.softmax(prediction["sem_seg"], dim=0)) - output = cp.zeros((len(self.segmentation_channels), probabilities.shape[1], probabilities.shape[2],)) - # add semseg - output[cp.array(list(self.is_stuff.values()))] = probabilities[list(self.stuff_categories.values())] - # add instances - indices, instance_info = prediction["panoptic_seg"] - # TODO dont know why i need temp, look into how to avoid - temp = output[cp.array(list(self.is_thing.values()))] - for i, instance in enumerate(instance_info): - if instance is None or not instance["isthing"]: - continue - mask = cp.asarray((indices == instance["id"]).int()) - if instance["instance_id"] in self.thing_categories.values(): - temp[i] = mask * instance["score"] - output[cp.array(list(self.is_thing.values()))] = temp - return output - - def get_category(self, name): - return self.metadata.get(name) - - def get_classes(self): - return self.get_category("thing_classes") + self.get_category("stuff_classes") - - -class STEGOModel: - def __init__(self, weights, cfg): - self.cfg: FeatureExtractorParameter = cfg - self.model = DinoFeaturizer(weights, cfg=self.cfg) - self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") - self.model.to(self.device) - self.model.eval() - self.shrink = Resize(size=(self.cfg.input_size[0], self.cfg.input_size[1]), antialias=True) - - def to_tensor(self, data): - data = data.astype(np.float32) - if len(data.shape) == 3: # transpose image-like data - data = data.transpose(2, 0, 1) - elif len(data.shape) == 2: - data = data.reshape((1,) + data.shape) - if len(data.shape) == 3 and data.shape[0] == 3: # normalization of rgb images - data = data / 255.0 - tens = torch.as_tensor(data, device="cuda") - return tens - - def __call__(self, image, *args, **kwargs): - # image = torch.as_tensor(image, device="cuda").permute(2, 0, 1).unsqueeze(0) - image = self.to_tensor(image).unsqueeze(0) - # if self.cfg.pcl: - reset_size = Resize(image.shape[-2:], interpolation=TF.InterpolationMode.NEAREST, antialias=True) - im_size = image.shape[-2:] - image = self.shrink(image) - image = TF.normalize(image, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)) - - feat1, code1 = self.model(image) - feat2, code2 = self.model(image.flip(dims=[3])) - - code = (code1 + code2.flip(dims=[3])) / 2 - # code = NF.interpolate(code, image.shape[-2:], mode=self.cfg.interpolation, align_corners=False).detach() - # if we just use first ten - # code = (feat1[:,:10] + feat2[:,:10].flip(dims=[3])) / 2 - - # if self.cfg.pcl: - code = NF.interpolate(code, im_size, mode=self.cfg.interpolation, align_corners=False).detach() - code = torch.squeeze(code, dim=0) - return code diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py deleted file mode 100755 index a713f312..00000000 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_node.py +++ /dev/null @@ -1,368 +0,0 @@ -import rospy -import sys - -import numpy as np -import cupy as cp - -np.float = np.float64 # temp fix for following import suggested at https://github.com/eric-wieser/ros_numpy/issues/37 -import ros_numpy -import matplotlib.pyplot as plt -from skimage.io import imshow - -import message_filters -from sensor_msgs.msg import Image, CameraInfo -from sensor_msgs.msg import PointCloud2, Image -from cv_bridge import CvBridge - -from semantic_sensor.pointcloud_parameters import PointcloudParameter -from semantic_sensor.networks import resolve_model -from semantic_sensor.utils import decode_max -from sklearn.decomposition import PCA - - -class PointcloudNode: - def __init__(self, sensor_name): - """Get parameter from server, initialize variables and semantics, register publishers and subscribers. - - Args: - sensor_name (str): Name of the sensor in the ros param server. - """ - # TODO: if this is going to be loaded from another package we might need to change namespace - self.param: PointcloudParameter = PointcloudParameter() - self.param.feature_config.input_size = [80, 160] - namesp = rospy.get_name() - if rospy.has_param(namesp + "/subscribers"): - config = rospy.get_param(namesp + "/subscribers") - self.param: PointcloudParameter = PointcloudParameter.from_dict(config[sensor_name]) - else: - print("NO ROS ENV found.") - - self.param.sensor_name = sensor_name - print("--------------Pointcloud Parameters-------------------") - print(self.param.dumps_yaml()) - print("--------------End of Parameters-----------------------") - self.semseg_color_map = None - # setup custom dtype - self.create_custom_dtype() - # setup semantics - self.feature_extractor = None - self.semantic_model = None - self.segmentation_channels = None - self.feature_channels = None - self.initialize_semantics() - - # setup pointcloud creation - self.cv_bridge = CvBridge() - self.P = None - self.header = None - self.register_sub_pub() - self.prediction_img = None - self.feat_img = None - - def initialize_semantics(self): - """Resolve the feature and segmentation mode and create segmentation_channel and feature_channels. - - - segmentation_channels: is a dictionary that contains the segmentation channel names as key and the fusion algorithm as value. - - feature_channels: is a dictionary that contains the features channel names as key and the fusion algorithm as value. - """ - if self.param.semantic_segmentation: - self.semantic_model = resolve_model(self.param.segmentation_model, self.param) - self.segmentation_channels = {} - for i, (chan, fusion) in enumerate(zip(self.param.channels, self.param.fusion)): - if fusion in ["class_bayesian", "class_average", "class_max"]: - self.segmentation_channels[chan] = fusion - assert len(self.segmentation_channels.keys()) > 0 - if self.param.feature_extractor: - self.feature_extractor = resolve_model(self.param.feature_config.name, self.param.feature_config) - self.feature_channels = {} - for i, (chan, fusion) in enumerate(zip(self.param.channels, self.param.fusion)): - if fusion in ["average"]: - self.feature_channels[chan] = fusion - assert len(self.feature_channels.keys()) > 0 - - def register_sub_pub(self): - """Register publishers and subscribers.""" - # subscribers - rospy.Subscriber(self.param.cam_info_topic, CameraInfo, self.cam_info_callback) - rgb_sub = message_filters.Subscriber(self.param.image_topic, Image) - depth_sub = message_filters.Subscriber(self.param.depth_topic, Image) - if self.param.confidence: - confidence_sub = message_filters.Subscriber(self.param.confidence_topic, Image) - ts = message_filters.ApproximateTimeSynchronizer( - [depth_sub, rgb_sub, confidence_sub,], queue_size=10, slop=0.5, - ) - else: - ts = message_filters.ApproximateTimeSynchronizer([depth_sub, rgb_sub,], queue_size=10, slop=0.5,) - ts.registerCallback(self.image_callback) - - self.pcl_pub = rospy.Publisher(self.param.topic_name, PointCloud2, queue_size=2) - # publishers - if self.param.semantic_segmentation: - if self.param.publish_segmentation_image: - self.seg_pub = rospy.Publisher(self.param.segmentation_image_topic, Image, queue_size=2) - if "class_max" in self.param.fusion: - self.labels = self.semantic_model["model"].get_classes() - else: - self.labels = list(self.segmentation_channels.keys()) - self.semseg_color_map = self.color_map(len(self.labels)) - if self.param.show_label_legend: - self.color_map_viz() - if self.param.feature_extractor: - # todo - if True: - self.feat_pub = rospy.Publisher(self.param.feature_config.feature_image_topic, Image, queue_size=2) - - def color_map(self, N=256, normalized=False): - """Create a color map for the class labels. - - Args: - N (int): - normalized (bool): - """ - - def bitget(byteval, idx): - return (byteval & (1 << idx)) != 0 - - dtype = "float32" if normalized else "uint8" - cmap = np.zeros((N + 1, 3), dtype=dtype) - for i in range(N + 1): - r = g = b = 0 - c = i - for j in range(8): - r = r | (bitget(c, 0) << 7 - j) - g = g | (bitget(c, 1) << 7 - j) - b = b | (bitget(c, 2) << 7 - j) - c = c >> 3 - - cmap[i] = np.array([r, g, b]) - cmap[1] = np.array([188, 63, 59]) - cmap[2] = np.array([81, 113, 162]) - cmap[3] = np.array([136, 49, 132]) - cmap = cmap / 255 if normalized else cmap - return cmap[1:] - - def color_map_viz(self): - """Display the color map of the classes.""" - nclasses = len(self.labels) - row_size = 50 - col_size = 500 - if self.param.semantic_segmentation: - cmap = self.semseg_color_map - array = np.empty((row_size * (nclasses), col_size, cmap.shape[1]), dtype=cmap.dtype) - for i in range(nclasses): - array[i * row_size : i * row_size + row_size, :] = cmap[i] - imshow(array) - plt.yticks([row_size * i + row_size / 2 for i in range(nclasses)], self.labels) - plt.xticks([]) - plt.show() - - def create_custom_dtype(self): - """Generate a new dtype according to the channels in the params. - - Some channels might remain empty. - """ - self.dtype = [ - ("x", np.float32), - ("y", np.float32), - ("z", np.float32), - ] - for chan, fus in zip(self.param.channels, self.param.fusion): - self.dtype.append((chan, np.float32)) - print(self.dtype) - - def cam_info_callback(self, msg): - """Subscribe to the camera infos to get projection matrix and header. - - Args: - msg: - """ - a = cp.asarray(msg.P) - self.P = cp.resize(a, (3, 4)) - self.height = msg.height - self.width = msg.width - self.header = msg.header - - def image_callback(self, depth_msg, rgb_msg=None, confidence_msg=None): - confidence = None - image = None - if self.P is None: - return - if rgb_msg is not None: - image = cp.asarray(self.cv_bridge.imgmsg_to_cv2(rgb_msg, desired_encoding="rgb8")) - depth = cp.asarray(self.cv_bridge.imgmsg_to_cv2(depth_msg, desired_encoding="passthrough")) - if confidence_msg is not None: - confidence = cp.asarray(self.cv_bridge.imgmsg_to_cv2(confidence_msg, desired_encoding="passthrough")) - - pcl = self.create_pcl_from_image(image, depth, confidence) - self.publish_pointcloud(pcl, depth_msg.header) - - if self.param.publish_segmentation_image: - self.publish_segmentation_image(self.prediction_img) - # todo - if self.param.publish_feature_image and self.param.feature_extractor: - self.publish_feature_image(self.feat_img) - - def create_pcl_from_image(self, image, depth, confidence): - """Generate the pointcloud from the depth map and process the image. - - Args: - image: - depth: - confidence: - - Returns: - - """ - u, v = self.get_coordinates(depth, confidence) - - # create pointcloud - world_x = (u.astype(np.float32) - self.P[0, 2]) * depth[v, u] / self.P[0, 0] - world_y = (v.astype(np.float32) - self.P[1, 2]) * depth[v, u] / self.P[1, 1] - world_z = depth[v, u] - points = np.zeros(world_x.shape, dtype=self.dtype) - points["x"] = cp.asnumpy(world_x) - points["y"] = cp.asnumpy(world_y) - points["z"] = cp.asnumpy(world_z) - self.process_image(image, u, v, points) - return points - - def get_coordinates(self, depth, confidence): - """Define which pixels are valid to generate the pointcloud. - - Args: - depth: - confidence: - - Returns: - - """ - pos = cp.where(depth > 0, 1, 0) - low = cp.where(depth < 8, 1, 0) - if confidence is not None: - conf = cp.where(confidence >= self.param.confidence_threshold, 1, 0) - else: - conf = cp.ones(pos.shape) - fin = cp.isfinite(depth) - temp = cp.maximum(cp.rint(fin + pos + conf + low - 2.6), 0) - mask = cp.nonzero(temp) - u = mask[1] - v = mask[0] - return u, v - - def process_image(self, image, u, v, points): - """Depending on setting generate color, semantic segmentation or feature channels. - - Args: - image: - u: - v: - points: - """ - if "color" in self.param.fusion: - valid_rgb = image[v, u].get() - r = np.asarray(valid_rgb[:, 0], dtype=np.uint32) - g = np.asarray(valid_rgb[:, 1], dtype=np.uint32) - b = np.asarray(valid_rgb[:, 2], dtype=np.uint32) - rgb_arr = np.array((r << 16) | (g << 8) | (b << 0), dtype=np.uint32) - rgb_arr.dtype = np.float32 - position = self.param.fusion.index("color") - points[self.param.channels[position]] = rgb_arr - - if self.segmentation_channels is not None: - self.perform_segmentation(image, points, u, v) - if self.feature_channels is not None: - self.extract_features(image, points, u, v) - - def perform_segmentation(self, image, points, u, v): - """Feedforward image through semseg NN and then append pixels to pcl and save image for publication. - - Args: - image: - points: - u: - v: - """ - prediction = self.semantic_model["model"](image) - values = prediction[:, v.get(), u.get()].get() - for it, channel in enumerate(self.semantic_model["model"].actual_channels): - points[channel] = values[it] - if self.param.publish_segmentation_image and self.param.semantic_segmentation: - self.prediction_img = prediction - - def extract_features(self, image, points, u, v): - """Feedforward image through feature extraction NN and then append pixels to pcl. - - Args: - image: - points: - u: - v: - """ - prediction = self.feature_extractor["model"](image) - values = prediction[:, v.get(), u.get()].cpu().detach().numpy() - for it, channel in enumerate(self.feature_channels.keys()): - points[channel] = values[it] - # todo - if False and self.param.feature_extractor: - self.feat_img = prediction - - def publish_segmentation_image(self, probabilities): - if self.param.semantic_segmentation: - colors = cp.asarray(self.semseg_color_map) - assert colors.ndim == 2 and colors.shape[1] == 3 - if self.P is None: - return - prob = cp.zeros((len(self.labels),) + probabilities.shape[1:]) - if "class_max" in self.param.fusion: - # decode, create an array with all possible classes and insert probabilities - it = 0 - for iit, (chan, fuse) in enumerate(zip(self.param.channels, self.param.fusion)): - if fuse in ["class_max"]: - temp = probabilities[it] - temp_p, temp_i = decode_max(temp) - temp_i.choose(prob) - c = cp.mgrid[0 : temp_i.shape[0], 0 : temp_i.shape[1]] - prob[temp_i, c[0], c[1]] = temp_p - it += 1 - elif fuse in ["class_bayesian", "class_average"]: - # assign fixed probability to correct index - if chan in self.semantic_model["model"].segmentation_channels: - prob[self.semantic_model["model"].segmentation_channels[chan]] = probabilities[it] - it += 1 - img = cp.argmax(prob, axis=0) - - else: - img = cp.argmax(probabilities, axis=0) - img = colors[img].astype(cp.uint8) # N x H x W x 3 - img = img.get() - seg_msg = self.cv_bridge.cv2_to_imgmsg(img, encoding="rgb8") - seg_msg.header.frame_id = self.header.frame_id - self.seg_pub.publish(seg_msg) - - def publish_feature_image(self, features): - data = np.reshape(features.cpu().detach().numpy(), (features.shape[0], -1)).T - n_components = 3 - pca = PCA(n_components=n_components).fit(data) - pca_descriptors = pca.transform(data) - img_pca = pca_descriptors.reshape(features.shape[1], features.shape[2], n_components) - comp = img_pca # [:, :, -3:] - comp_min = comp.min(axis=(0, 1)) - comp_max = comp.max(axis=(0, 1)) - comp_img = (comp - comp_min) / (comp_max - comp_min) - comp_img = (comp_img * 255).astype(np.uint8) - feat_msg = self.cv_bridge.cv2_to_imgmsg(comp_img, encoding="passthrough") - feat_msg.header.frame_id = self.header.frame_id - self.feat_pub.publish(feat_msg) - - def publish_pointcloud(self, pcl, header): - pc2 = ros_numpy.msgify(PointCloud2, pcl) - pc2.header = header - # pc2.header.frame_id = self.param.cam_frame - self.pcl_pub.publish(pc2) - - -if __name__ == "__main__": - sensor_name = sys.argv[1] - rospy.init_node("semantic_pointcloud_node", anonymous=True, log_level=rospy.INFO) - node = PointcloudNode(sensor_name) - rospy.spin() diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py b/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py deleted file mode 100644 index a4837c67..00000000 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/pointcloud_parameters.py +++ /dev/null @@ -1,47 +0,0 @@ -from dataclasses import dataclass, field -from simple_parsing.helpers import Serializable - - -@dataclass -class FeatureExtractorParameter(Serializable): - name: str = "DINO" - interpolation: str = "bilinear" - model: str = "vit_small" - patch_size: int = 16 - dim: int = 5 - dropout: bool = False - dino_feat_type: str = "feat" - projection_type: str = "nonlinear" - input_size: list = field(default_factory=lambda: [80, 160]) - feature_image_topic: str = "/semantic_sensor/feature_image" - pcl: bool = True - - -@dataclass -class PointcloudParameter(Serializable): - sensor_name: str = "camera" - topic_name: str = "/elvation_mapping/pointcloud_semantic" - channels: list = field(default_factory=lambda: ["rgb", "person", "grass", "tree", "max"]) - fusion: list = field( - default_factory=lambda: ["color", "class_average", "class_average", "class_average", "class_max",] - ) - - semantic_segmentation: bool = False - segmentation_model: str = "lraspp_mobilenet_v3_large" - publish_segmentation_image: bool = False - segmentation_image_topic: str = "/semantic_sensor/sem_seg" - pub_all: bool = False - show_label_legend: bool = False - - cam_info_topic: str = "/zed2i/zed_node/depth/camera_info" - image_topic: str = "/zed2i/zed_node/left/image_rect_color" - depth_topic: str = "/zed2i/zed_node/depth/depth_registered" - cam_frame: str = "zed2i_right_camera_optical_frame" - confidence: bool = False - confidence_topic: str = "/zed2i/zed_node/confidence/confidence_map" - confidence_threshold: int = 10 - - feature_extractor: bool = False - publish_feature_image: bool = False - feature_config: FeatureExtractorParameter = FeatureExtractorParameter - feature_config.input_size: list = field(default_factory=lambda: [80, 160]) diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/__init__.py b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py deleted file mode 100644 index 724b6b51..00000000 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_pointcloud.py +++ /dev/null @@ -1,64 +0,0 @@ -import pytest -from ..pointcloud_node import PointcloudNode -import cupy as cp -from ..utils import encode_max - -"""This test file only works if ros is installed and the ros master is running. -""" - - -@pytest.fixture() -def pointcloud_ex(cam_name, channels, fusion, semseg, segpub, showlbl): - node = PointcloudNode(cam_name) - node.param.channels = channels - node.param.fusion = fusion - node.param.semantic_segmentation = semseg - node.param.show_label_legend = showlbl - node.param.publish_segmentation_image = segpub - node.__init__(cam_name) - return node - - -@pytest.mark.parametrize( - "cam_name,channels, fusion,semseg", - [ - ("front_cam", ["feat_0", "feat_1"], ["average", "average"], False), - ("front_cam", ["feat_0", "feat_1"], ["class_max", "average"], True), - ("front_cam", ["feat_0", "feat_1"], ["class_bayesian", "average"], True), - ], -) -@pytest.mark.parametrize( - "segpub", [True, False], -) -@pytest.mark.parametrize( - "showlbl", [True, False], -) -def test_initialize(pointcloud_ex): - # todo here we can add more test - # params: semseg, channels, class max, publish seg, showlabellegend - pointcloud_ex.initialize_semantics() - pointcloud_ex.register_sub_pub() - - -# if semseg then segpub and showlbl might be displayed -@pytest.mark.parametrize( - "cam_name,channels, fusion,semseg,segpub,showlbl", - [ - ("front_cam", ["feat_0", "feat_1"], ["average", "average"], False, False, False,), - ("front_cam", ["feat_0", "feat_1"], ["class_max", "average"], True, True, True), - ("front_cam", ["feat_0", "feat_1"], ["class_max", "average"], True, False, False,), - ("front_cam", ["feat_0", "feat_1"], ["class_bayesian", "average"], True, True, True,), - ("front_cam", ["feat_0", "feat_1"], ["class_bayesian", "average"], True, False, False,), - ], -) -def test_pcl_creation(pointcloud_ex, channels, fusion, semseg, segpub, showlbl): - amount = 3 - if "class_max" in pointcloud_ex.param.fusion: - val = cp.random.rand(360, 640, amount, dtype=cp.float32).astype(cp.float16) - ind = cp.random.randint(0, 2, (360, 640, amount), dtype=cp.uint32).astype(cp.float32) - img = encode_max(val, ind) - else: - img = (cp.random.rand(360, 640, amount) * 255).astype(cp.int32) - pointcloud_ex.P = cp.random.rand(3, 4) - depth = cp.random.rand(360, 640) * 8 - pointcloud_ex.create_pcl_from_image(img, depth, None) diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py b/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py deleted file mode 100644 index e50ca9e5..00000000 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/tests/test_utils.py +++ /dev/null @@ -1,44 +0,0 @@ -import pytest -from semantic_sensor.networks import resolve_model -import cupy as cp -import torch -from semantic_sensor.pointcloud_parameters import ( - FeatureExtractorParameter, - PointcloudParameter, -) - - -@pytest.mark.parametrize( - "model_name,channels, fusion", - [ - ("fcn_resnet50", [], []), - ("lraspp_mobilenet_v3_large", [], []), - ("detectron_coco_panoptic_fpn_R_101_3x", [], []), - ], -) -def test_semantic_segmentation(model_name, channels, fusion): - param = PointcloudParameter() - param.segmentation_model = model_name - m = resolve_model(model_name, param) - im_sz = [360, 640] - image = cp.random.random((im_sz[0], im_sz[1], 3)) - classes = m["model"].get_classes() - assert type(classes) is list - prediction = m["model"](image) - # assert prediction.shape == torch.Size([len(param.channels), im_sz[0], im_sz[1]]) - # assert (prediction <= 1).all() - # assert (0 <= prediction).all() - - -@pytest.mark.parametrize( - "model_name", ["DINO",], -) -def test_feature_extractor(model_name): - param = FeatureExtractorParameter() - param.name = model_name - m = resolve_model(model_name, param) - im_sz = [320, 640] - image = cp.random.random((im_sz[0], im_sz[1], 3)) - prediction = m["model"](image.get()) - assert prediction.shape == torch.Size([param.dim, im_sz[0], im_sz[1]]) - assert prediction.shape[-2:] == torch.Size([im_sz[0], im_sz[1]]) diff --git a/sensor_processing/semantic_sensor/script/semantic_sensor/utils.py b/sensor_processing/semantic_sensor/script/semantic_sensor/utils.py deleted file mode 100644 index 9959213f..00000000 --- a/sensor_processing/semantic_sensor/script/semantic_sensor/utils.py +++ /dev/null @@ -1,28 +0,0 @@ -import numpy as np -import cupy as cp - -from detectron2.utils.logger import setup_logger - -setup_logger() - - -def encode_max(maxim, index): - maxim, index = cp.asarray(maxim, dtype=cp.float32), cp.asarray(index, dtype=cp.uint32) - # fuse them - maxim = maxim.astype(cp.float16) - maxim = maxim.view(cp.uint16) - maxim = maxim.astype(cp.uint32) - index = index.astype(cp.uint32) - mer = cp.array(cp.left_shift(index, 16) | maxim, dtype=cp.uint32) - mer = mer.view(cp.float32) - return mer - - -def decode_max(mer): - mer = mer.astype(cp.float32) - mer = mer.view(dtype=cp.uint32) - ma = cp.bitwise_and(mer, 0xFFFF, dtype=np.uint16) - ma = ma.view(np.float16) - ma = ma.astype(np.float32) - ind = cp.right_shift(mer, 16) - return ma, ind diff --git a/sensor_processing/semantic_sensor/setup.py b/sensor_processing/semantic_sensor/setup.py deleted file mode 100644 index fef26672..00000000 --- a/sensor_processing/semantic_sensor/setup.py +++ /dev/null @@ -1,8 +0,0 @@ -from distutils.core import setup -from catkin_pkg.python_setup import generate_distutils_setup - -setup_args = generate_distutils_setup( - packages=["semantic_sensor",], install_requires=["torch", "torchvision",], package_dir={"": "script"}, -) - -setup(**setup_args) From 4a62c13b20702db1efefbb804424963272714b67 Mon Sep 17 00:00:00 2001 From: amilearning Date: Wed, 18 Dec 2024 13:54:17 +0100 Subject: [PATCH 472/504] change visibility setup --- elevation_mapping_cupy/config/core/core_param.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 8cc68a55..eb0539a4 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -60,7 +60,7 @@ elevation_mapping: #### Feature toggles ######## enable_edge_sharpen: true - enable_visibility_cleanup: true + enable_visibility_cleanup: false enable_drift_compensation: true enable_overlap_clearance: true enable_pointcloud_publishing: false From 0f617f5a0d68a9d1023b996962ed847408d7de6f Mon Sep 17 00:00:00 2001 From: amilearning Date: Tue, 14 Jan 2025 09:34:59 +0100 Subject: [PATCH 473/504] pointcloud transport --- elevation_mapping_cupy/CMakeLists.txt | 3 +- .../config/core/core_param.yaml | 3 +- .../elevation_mapping_ros.hpp | 10 ++- elevation_mapping_cupy/package.xml | 1 + .../src/elevation_mapping_ros.cpp | 64 +++++++++++++++++-- point_cloud_transport | 1 + point_cloud_transport_plugins | 1 + 7 files changed, 72 insertions(+), 11 deletions(-) create mode 160000 point_cloud_transport create mode 160000 point_cloud_transport_plugins diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index 20e8ab7f..11743e1a 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -40,7 +40,7 @@ find_package(pcl_ros REQUIRED) find_package(tf2_eigen REQUIRED) find_package(ament_cmake_python REQUIRED) find_package(python_cmake_module REQUIRED) - +find_package(point_cloud_transport REQUIRED) _ament_cmake_python_register_environment_hook() ament_python_install_package(${PROJECT_NAME} PACKAGE_DIR script/${PROJECT_NAME}) @@ -61,6 +61,7 @@ set(dependencies pcl_ros message_filters tf2_eigen + point_cloud_transport ) # Include directories diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index eb0539a4..48d41871 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -109,7 +109,8 @@ elevation_mapping: subscribers: pointcloud1: # topic_name: '/ouster/points' - topic_name: '/camera/camera/depth/color/points' + # topic_name: '/left/zed_node_1/point_cloud/cloud_registered' + topic_name: '/left/zed_node/point_cloud/cloud_registered' data_type: 'pointcloud' image1: topic_name: '/feat_processing_node/semantic_feat' diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 32838ab4..4dc658fd 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -15,8 +15,9 @@ // Pybind #include // everything needed for embedding #include -// ROS +// ROS2 #include +#include #include #include #include "message_filters/subscriber.h" @@ -100,7 +101,9 @@ class ElevationMappingNode : public rclcpp::Node { void readParameters(); void setupMapPublishers(); void pointcloudCallback(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::string& key); -void inputPointCloud(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::vector& channels); +void pointcloudtransportCallback(const sensor_msgs::msg::PointCloud2::ConstSharedPtr cloud, const std::string& key); + +void inputPointCloud(const sensor_msgs::msg::PointCloud2::ConstSharedPtr cloud, const std::vector& channels); void inputImage(const sensor_msgs::msg::Image::ConstSharedPtr& image_msg, const sensor_msgs::msg::CameraInfo::ConstSharedPtr& camera_info_msg, @@ -146,6 +149,9 @@ visualization_msgs::msg::Marker vectorToArrowMarker(const Eigen::Vector3d& start // image_transport::ImageTransport it_; std::vector::SharedPtr> pointcloudSubs_; + // std::vector::SharedPtr> pointcloudtransportSubs_; + std::vector pointcloudtransportSubs_; + std::vector::SharedPtr> imageSubs_; std::vector::SharedPtr> cameraInfoSubs_; std::vector::SharedPtr> channelInfoSubs_; diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index c1395b61..fd73a8fa 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -15,6 +15,7 @@ std_srvs sensor_msgs geometry_msgs + point_cloud_transport message_filters grid_map_msgs diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index a16e6d3a..aba48d1b 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -189,11 +189,40 @@ ElevationMappingNode::ElevationMappingNode() auto sensor_qos = rclcpp::QoS(rclcpp::QoSInitialization(sensor_qos_profile.history, sensor_qos_profile.depth), sensor_qos_profile); - auto callback = [this, key](const sensor_msgs::msg::PointCloud2::SharedPtr msg) { - this->pointcloudCallback(msg, key); - }; - auto sub = this->create_subscription(pointcloud_topic, sensor_qos, callback); - pointcloudSubs_.push_back(sub); + // point_cloud_transport::Subscriber pct_sub = pct.subscribe( + // "pct/point_cloud", 100, + // [node](const sensor_msgs::msg::PointCloud2::ConstSharedPtr & msg) + // { + // RCLCPP_INFO_STREAM( + // node->get_logger(), + // "Message received, number of points is: " << msg->width * msg->height); + // }, {}); + // point_cloud_transport::Subscriber sub = pct.subscribe(pointcloud_topic, 100, callback, {}, transport_hint.get()) + + + auto callback_transport = [this, key](const sensor_msgs::msg::PointCloud2::ConstSharedPtr msg) { + this->pointcloudtransportCallback(msg, key); + }; + + // Create transport hints (e.g., "draco") + // auto transport_hint = std::make_shared("draco"); + + + // Use PointCloudTransport to create a subscriber + point_cloud_transport::PointCloudTransport pct(node_); + auto sub_transport = pct.subscribe(pointcloud_topic, 100, callback_transport); + + // Add the subscriber to the vector to manage its lifetime + pointcloudtransportSubs_.push_back(sub_transport); + + + // auto callback = [this, key](const sensor_msgs::msg::PointCloud2::SharedPtr msg) { + // this->pointcloudCallback(msg, key); + // }; + + // auto sub = this->create_subscription(pointcloud_topic, sensor_qos, callback); + + // pointcloudSubs_.push_back(sub); RCLCPP_INFO(this->get_logger(), "Subscribed to PointCloud2 topic: %s", pointcloud_topic.c_str()); } } @@ -400,6 +429,23 @@ imageChannelReady_[key] = std::make_pair(*channel_info, true); } } + +void ElevationMappingNode::pointcloudtransportCallback(const sensor_msgs::msg::PointCloud2::ConstSharedPtr cloud, const std::string& key) { + + // get channels + auto fields = cloud->fields; + std::vector channels; + + for (size_t it = 0; it < fields.size(); it++) { + auto& field = fields[it]; + channels.push_back(field.name); + } + inputPointCloud(cloud, channels); + + // This is used for publishing as statistics. + pointCloudProcessCounter_++; +} + void ElevationMappingNode::pointcloudCallback(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, const std::string& key) { // get channels auto fields = cloud->fields; @@ -415,7 +461,7 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::msg::PointCloud pointCloudProcessCounter_++; } -void ElevationMappingNode::inputPointCloud(const sensor_msgs::msg::PointCloud2::SharedPtr cloud, +void ElevationMappingNode::inputPointCloud(const sensor_msgs::msg::PointCloud2::ConstSharedPtr cloud, const std::vector& channels) { auto start = this->now(); // auto* raw_pcl_pc = new pcl::PCLPointCloud2; @@ -640,10 +686,13 @@ bool ElevationMappingNode::getSubmap( Eigen::Isometry3d transformationOdomToMap; geometry_msgs::msg::Pose pose; grid_map::Position requestedSubmapPosition(request->position_x, request->position_y); + + if (requestedFrameId != mapFrameId_) { geometry_msgs::msg::TransformStamped transformStamped; - const auto& timeStamp = this->now(); + try { + const auto& timeStamp = this->now(); transformStamped = tfBuffer_->lookupTransform(requestedFrameId, mapFrameId_, timeStamp, tf2::durationFromSec(1.0)); @@ -691,6 +740,7 @@ bool ElevationMappingNode::getSubmap( response->map = *msg_ptr; } + return isSuccess; } diff --git a/point_cloud_transport b/point_cloud_transport new file mode 160000 index 00000000..fd9eb0d3 --- /dev/null +++ b/point_cloud_transport @@ -0,0 +1 @@ +Subproject commit fd9eb0d371c62cf3155de9ea8e312df3beafc59a diff --git a/point_cloud_transport_plugins b/point_cloud_transport_plugins new file mode 160000 index 00000000..f5005add --- /dev/null +++ b/point_cloud_transport_plugins @@ -0,0 +1 @@ +Subproject commit f5005add81c3af44b33f884a7c99f87d407d70c7 From 1fa47ae08467c7bd5ab4d1264a60bfdc22492907 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Tue, 21 Jan 2025 14:36:37 +0100 Subject: [PATCH 474/504] works reliably --- .../config/core/core_param.yaml | 22 +- .../setups/anymal/anymal_parameters.yaml | 2 +- .../config/setups/menzi/base.yaml | 25 ++ .../elevation_mapping.py | 20 + .../elevation_mapping_ros.py | 356 +++++++----------- .../plugins/plugin_manager.py | 1 - .../launch/elevation_mapping.launch.py | 81 +++- elevation_mapping_cupy/launch/menzi.launch | 0 .../launch/turtlesim_init.launch.py | 4 +- 9 files changed, 272 insertions(+), 239 deletions(-) create mode 100644 elevation_mapping_cupy/config/setups/menzi/base.yaml create mode 100644 elevation_mapping_cupy/launch/menzi.launch diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 38c2301b..3786b25f 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -1,11 +1,11 @@ elevation_mapping_node: ros__parameters: #### Basic parameters ######## - resolution: 0.04 # resolution in m. - map_length: 8.0 # map's size in m. + resolution: 0.1 # resolution in m. + map_length: 15.0 # map's size in m. sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). mahalanobis_thresh: 2.0 # points outside this distance is outlier. - outlier_variance: 0.01 # if point is outlier, add this value to the cell. + outlier_variance: 0.0`1 # if point is outlier, add this value to the cell. drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation @@ -20,8 +20,8 @@ elevation_mapping_node: orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. - min_valid_distance: 0.5 # points with shorter distance will be filtered out. - max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. + min_valid_distance: 4.0 # points with shorter distance will be filtered out. + max_height_range: 10.5 # points higher than this value from sensor will be filtered out ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. @@ -44,16 +44,20 @@ elevation_mapping_node: overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - map_frame: 'odom' # The map frame where the odometry source uses. - base_frame: 'base_footprint' # The robot's base frame. This frame will be a center of the map. - corrected_map_frame: 'odom' + map_frame: 'World' # The map frame where the odometry source uses. + base_frame: 'BASE' # The robot's base frame. This frame will be a center of the map. + corrected_map_frame: 'World' + # map_frame: 'World' # The map frame where the odometry source uses. + # base_frame: 'BASE' # The robot's base frame. This frame will be a center of the map. + # corrected_map_frame: 'World' + #### Feature toggles ######## enable_edge_sharpen: true enable_visibility_cleanup: true enable_drift_compensation: true - enable_overlap_clearance: true + enable_overlap_clearance: true` enable_pointcloud_publishing: false enable_drift_corrected_TF_publishing: false enable_normal_color: false # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. diff --git a/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml b/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml index 623ec6a6..8bd080d6 100644 --- a/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml +++ b/elevation_mapping_cupy/config/setups/anymal/anymal_parameters.yaml @@ -1,7 +1,7 @@ /elevation_mapping_node: ros__parameters: #### Basic parameters ######## - resolution: 0.04 # resolution in m. + resolution: 0.04 # resolution in m. map_length: 8 # map's size in m. sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). mahalanobis_thresh: 2.0 # points outside this distance is outlier. diff --git a/elevation_mapping_cupy/config/setups/menzi/base.yaml b/elevation_mapping_cupy/config/setups/menzi/base.yaml new file mode 100644 index 00000000..9d8234ad --- /dev/null +++ b/elevation_mapping_cupy/config/setups/menzi/base.yaml @@ -0,0 +1,25 @@ +elevation_mapping_node: + ros__parameters: + pointcloud_channel_fusions: + rgb: 'color' + default: 'average' + + image_channel_fusions: + rgb: 'color' + default: 'exponential' + feat_.*: 'exponential' + + subscribers: + front_cam: + topic_name: '/ouster_points_self_filtered' + data_type: pointcloud + + publishers: + elevation_map_raw: + layers: ['elevation', 'traversability', 'variance','rgb'] + basic_layers: ['elevation'] + fps: 5.0 + elevation_map_filter: + layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] + basic_layers: ['min_filter'] + fps: 3.0 \ No newline at end of file diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py index 967772cc..39b2994d 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py @@ -242,6 +242,26 @@ def compile_kernels(self): self.min_filtered = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) self.min_filtered_mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) self.mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) + + # Log parameter values before kernel initialization + self.logger.info("Initializing add_points_kernel with parameters:") + self.logger.info(f" resolution: {self.resolution}") + self.logger.info(f" cell_n: {self.cell_n}") + self.logger.info(f" sensor_noise_factor: {self.param.sensor_noise_factor}") + self.logger.info(f" mahalanobis_thresh: {self.param.mahalanobis_thresh}") + self.logger.info(f" outlier_variance: {self.param.outlier_variance}") + self.logger.info(f" wall_num_thresh: {self.param.wall_num_thresh}") + self.logger.info(f" max_ray_length: {self.param.max_ray_length}") + self.logger.info(f" cleanup_step: {self.param.cleanup_step}") + self.logger.info(f" min_valid_distance: {self.param.min_valid_distance}") + self.logger.info(f" max_height_range: {self.param.max_height_range}") + self.logger.info(f" cleanup_cos_thresh: {self.param.cleanup_cos_thresh}") + self.logger.info(f" ramped_height_range_a: {self.param.ramped_height_range_a}") + self.logger.info(f" ramped_height_range_b: {self.param.ramped_height_range_b}") + self.logger.info(f" ramped_height_range_c: {self.param.ramped_height_range_c}") + self.logger.info(f" enable_edge_sharpen: {self.param.enable_edge_sharpen}") + self.logger.info(f" enable_visibility_cleanup: {self.param.enable_visibility_cleanup}") + self.add_points_kernel = add_points_kernel( self.resolution, self.cell_n, diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py index fc345141..83f19ad4 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py @@ -3,7 +3,6 @@ import os from functools import partial -# ROS 2 imports import rclpy from rclpy.node import Node from ament_index_python.packages import get_package_share_directory @@ -12,23 +11,16 @@ from sensor_msgs_py import point_cloud2 from tf_transformations import quaternion_matrix import tf2_ros - import message_filters from cv_bridge import CvBridge from rclpy.duration import Duration -# Message imports from grid_map_msgs.msg import GridMap from std_msgs.msg import Float32MultiArray from std_msgs.msg import MultiArrayLayout as MAL from std_msgs.msg import MultiArrayDimension as MAD from rclpy.serialization import serialize_message - -# Custom module imports from elevation_mapping_cupy import ElevationMap, Parameter -import concurrent.futures - -# Define point cloud data types PDC_DATATYPE = { "1": np.int8, "2": np.uint8, @@ -40,53 +32,41 @@ "8": np.float64, } - class ElevationMappingNode(Node): def __init__(self): - # Initialize the node without passing callback_group to super() super().__init__( 'elevation_mapping_node', automatically_declare_parameters_from_overrides=True, - # Add this parameter to enable sim time allow_undeclared_parameters=True, parameter_overrides=[ rclpy.Parameter('use_sim_time', rclpy.Parameter.Type.BOOL, True) ] ) - - # Get package share directory self.root = get_package_share_directory("elevation_mapping_cupy") weight_file = os.path.join(self.root, "config/core/weights.dat") plugin_config_file = os.path.join(self.root, "config/core/plugin_config.yaml") - # Initialize Parameters + # Initialize parameters with some defaults self.param = Parameter( use_chainer=False, weight_file=weight_file, plugin_config_file=plugin_config_file ) - self.node_name = "elevation_mapping" - - # Initialize ROS components + # Read ROS parameters (including YAML) self.initialize_ros() + self.set_param_values_from_ros() - # Assign subscriber configuration to parameters + # Overwrite subscriber_cfg from loaded YAML self.param.subscriber_cfg = self.my_subscribers - # Initialize Elevation Mapping self.initialize_elevation_mapping() - - # Register ROS subscribers, publishers, and timers self.register_subscribers() self.register_publishers() self.register_timers() - - # timestamp of latest pcd or image msg self._last_t = None def initialize_elevation_mapping(self) -> None: - """Initialize the elevation mapping module.""" self.param.update() self._pointcloud_process_counter = 0 self._image_process_counter = 0 @@ -94,18 +74,17 @@ def initialize_elevation_mapping(self) -> None: self._map_data = np.zeros( (self._map.cell_n - 2, self._map.cell_n - 2), dtype=np.float32 ) + self.get_logger().info(f"Initialized map with length: {self._map.map_length}, resolution: {self._map.resolution}, cells: {self._map.cell_n}") + self._map_q = None self._map_t = None def initialize_ros(self) -> None: - """Initialize ROS-related components such as TF buffer and listener.""" self._tf_buffer = tf2_ros.Buffer() self._listener = tf2_ros.TransformListener(self._tf_buffer, self) self.get_ros_params() def get_ros_params(self) -> None: - """Retrieve ROS parameters from the node.""" - # Get parameters with default values self.use_chainer = self.get_parameter('use_chainer').get_parameter_value().bool_value self.weight_file = self.get_parameter('weight_file').get_parameter_value().string_value self.plugin_config_file = self.get_parameter('plugin_config_file').get_parameter_value().string_value @@ -128,36 +107,7 @@ def get_ros_params(self) -> None: self.enable_normal_arrow_publishing = self.get_parameter('enable_normal_arrow_publishing').get_parameter_value().bool_value self.enable_drift_corrected_TF_publishing = self.get_parameter('enable_drift_corrected_TF_publishing').get_parameter_value().bool_value self.use_initializer_at_start = self.get_parameter('use_initializer_at_start').get_parameter_value().bool_value - - # Log parameters - self.get_logger().info("\n=== Loaded Parameters ===") - self.get_logger().info(f"use_chainer: {self.use_chainer}") - self.get_logger().info(f"weight_file: {self.weight_file}") - self.get_logger().info(f"plugin_config_file: {self.plugin_config_file}") - self.get_logger().info(f"initialize_frame_id: {self.initialize_frame_id}") - self.get_logger().info(f"initialize_tf_offset: {self.initialize_tf_offset}") - self.get_logger().info(f"map_frame: {self.map_frame}") - self.get_logger().info(f"base_frame: {self.base_frame}") - self.get_logger().info(f"corrected_map_frame: {self.corrected_map_frame}") - self.get_logger().info(f"initialize_method: {self.initialize_method}") - self.get_logger().info(f"position_lowpass_alpha: {self.position_lowpass_alpha}") - self.get_logger().info(f"orientation_lowpass_alpha: {self.orientation_lowpass_alpha}") - self.get_logger().info(f"recordable_fps: {self.recordable_fps}") - self.get_logger().info(f"update_variance_fps: {self.update_variance_fps}") - self.get_logger().info(f"time_interval: {self.time_interval}") - self.get_logger().info(f"update_pose_fps: {self.update_pose_fps}") - self.get_logger().info(f"initialize_tf_grid_size: {self.initialize_tf_grid_size}") - self.get_logger().info(f"map_acquire_fps: {self.map_acquire_fps}") - self.get_logger().info(f"publish_statistics_fps: {self.publish_statistics_fps}") - self.get_logger().info(f"enable_pointcloud_publishing: {self.enable_pointcloud_publishing}") - self.get_logger().info(f"enable_normal_arrow_publishing: {self.enable_normal_arrow_publishing}") - self.get_logger().info(f"enable_drift_corrected_TF_publishing: {self.enable_drift_corrected_TF_publishing}") - self.get_logger().info(f"use_initializer_at_start: {self.use_initializer_at_start}") - self.get_logger().info("=======================\n") - - # Retrieve subscribers using prefix subscribers_params = self.get_parameters_by_prefix('subscribers') - self.get_logger().info(f"Subscribers params: {subscribers_params}") self.my_subscribers = {} for param_name, param_value in subscribers_params.items(): parts = param_name.split('.') @@ -166,12 +116,7 @@ def get_ros_params(self) -> None: if sub_key not in self.my_subscribers: self.my_subscribers[sub_key] = {} self.my_subscribers[sub_key][sub_param] = param_value.value - else: - self.get_logger().warn(f"Unexpected subscriber parameter format: {param_name}") - - # Retrieve publishers using prefix publishers_params = self.get_parameters_by_prefix('publishers') - self.get_logger().info(f"Publishers params: {publishers_params}") self.my_publishers = {} for param_name, param_value in publishers_params.items(): parts = param_name.split('.') @@ -180,25 +125,88 @@ def get_ros_params(self) -> None: if pub_key not in self.my_publishers: self.my_publishers[pub_key] = {} self.my_publishers[pub_key][pub_param] = param_value.value - else: - self.get_logger().warn(f"Unexpected publisher parameter format: {param_name}") - # Log loaded subscribers and publishers for debugging - self.get_logger().info(f"Loaded Subscribers: {self.my_subscribers}") - self.get_logger().info(f"Loaded Publishers: {self.my_publishers}") - # If you want to list all parameters for debugging - params = self.get_parameters_by_prefix('') - for param_name, param_value in params.items(): - self.get_logger().info(f"Parameter '{param_name}': {param_value.value}") + def set_param_values_from_ros(self): + # Assign to self.param so it won't use defaults + # Use try/except so missing params won't cause errors + try: self.param.resolution = self.get_parameter('resolution').get_parameter_value().double_value + except: pass + try: self.param.map_length = self.get_parameter('map_length').get_parameter_value().double_value + except: pass + try: self.param.sensor_noise_factor = self.get_parameter('sensor_noise_factor').get_parameter_value().double_value + except: pass + try: self.param.mahalanobis_thresh = self.get_parameter('mahalanobis_thresh').get_parameter_value().double_value + except: pass + try: self.param.outlier_variance = self.get_parameter('outlier_variance').get_parameter_value().double_value + except: pass + try: + # The YAML has 'drift_compensation_variance_inler', but our param is 'drift_compensation_variance_inlier' + self.param.drift_compensation_variance_inlier = self.get_parameter('drift_compensation_variance_inler').get_parameter_value().double_value + except: pass + try: self.param.max_drift = self.get_parameter('max_drift').get_parameter_value().double_value + except: pass + try: self.param.drift_compensation_alpha = self.get_parameter('drift_compensation_alpha').get_parameter_value().double_value + except: pass + try: self.param.time_variance = self.get_parameter('time_variance').get_parameter_value().double_value + except: pass + try: self.param.max_variance = self.get_parameter('max_variance').get_parameter_value().double_value + except: pass + try: self.param.initial_variance = self.get_parameter('initial_variance').get_parameter_value().double_value + except: pass + try: self.param.traversability_inlier = self.get_parameter('traversability_inlier').get_parameter_value().double_value + except: pass + try: self.param.dilation_size = self.get_parameter('dilation_size').get_parameter_value().integer_value + except: pass + try: self.param.wall_num_thresh = self.get_parameter('wall_num_thresh').get_parameter_value().double_value + except: pass + try: self.param.min_height_drift_cnt = self.get_parameter('min_height_drift_cnt').get_parameter_value().double_value + except: pass + try: self.param.position_noise_thresh = self.get_parameter('position_noise_thresh').get_parameter_value().double_value + except: pass + try: self.param.orientation_noise_thresh = self.get_parameter('orientation_noise_thresh').get_parameter_value().double_value + except: pass + try: self.param.min_valid_distance = self.get_parameter('min_valid_distance').get_parameter_value().double_value + except: pass + try: self.param.max_height_range = self.get_parameter('max_height_range').get_parameter_value().double_value + except: pass + try: self.param.ramped_height_range_a = self.get_parameter('ramped_height_range_a').get_parameter_value().double_value + except: pass + try: self.param.ramped_height_range_b = self.get_parameter('ramped_height_range_b').get_parameter_value().double_value + except: pass + try: self.param.ramped_height_range_c = self.get_parameter('ramped_height_range_c').get_parameter_value().double_value + except: pass + try: self.param.max_ray_length = self.get_parameter('max_ray_length').get_parameter_value().double_value + except: pass + try: self.param.cleanup_step = self.get_parameter('cleanup_step').get_parameter_value().double_value + except: pass + try: self.param.cleanup_cos_thresh = self.get_parameter('cleanup_cos_thresh').get_parameter_value().double_value + except: pass + try: self.param.safe_thresh = self.get_parameter('safe_thresh').get_parameter_value().double_value + except: pass + try: self.param.safe_min_thresh = self.get_parameter('safe_min_thresh').get_parameter_value().double_value + except: pass + try: self.param.max_unsafe_n = self.get_parameter('max_unsafe_n').get_parameter_value().integer_value + except: pass + try: self.param.overlap_clear_range_xy = self.get_parameter('overlap_clear_range_xy').get_parameter_value().double_value + except: pass + try: self.param.overlap_clear_range_z = self.get_parameter('overlap_clear_range_z').get_parameter_value().double_value + except: pass + try: self.param.enable_edge_sharpen = self.get_parameter('enable_edge_sharpen').get_parameter_value().bool_value + except: pass + try: self.param.enable_visibility_cleanup = self.get_parameter('enable_visibility_cleanup').get_parameter_value().bool_value + except: pass + try: self.param.enable_drift_compensation = self.get_parameter('enable_drift_compensation').get_parameter_value().bool_value + except: pass + try: self.param.enable_overlap_clearance = self.get_parameter('enable_overlap_clearance').get_parameter_value().bool_value + except: pass + try: self.param.use_only_above_for_upper_bound = self.get_parameter('use_only_above_for_upper_bound').get_parameter_value().bool_value + except: pass def register_subscribers(self) -> None: - """Register ROS subscribers for pointclouds and images.""" - # Initialize CvBridge if needed if any(config.get("data_type") == "image" for config in self.my_subscribers.values()): self.cv_bridge = CvBridge() - # Dictionaries to hold subscribers pointcloud_subs = {} image_subs = {} @@ -207,8 +215,6 @@ def register_subscribers(self) -> None: if data_type == "image": topic_name_camera = config.get("topic_name_camera", "/camera/image") topic_name_camera_info = config.get("topic_name_camera_info", "/camera/camera_info") - - # Initialize message_filters Subscribers without passing callback_group camera_sub = message_filters.Subscriber( self, Image, @@ -219,14 +225,11 @@ def register_subscribers(self) -> None: CameraInfo, topic_name_camera_info ) - - # Synchronize image and camera info image_sync = message_filters.ApproximateTimeSynchronizer( [camera_sub, camera_info_sub], queue_size=10, slop=0.5 ) image_sync.registerCallback(partial(self.image_callback, sub_key=key)) image_subs[key] = image_sync - elif data_type == "pointcloud": topic_name = config.get("topic_name", "/pointcloud") qos_profile = rclpy.qos.QoSProfile( @@ -235,8 +238,6 @@ def register_subscribers(self) -> None: durability=rclpy.qos.DurabilityPolicy.VOLATILE, history=rclpy.qos.HistoryPolicy.KEEP_LAST ) - - # Create subscription without passing callback_group subscription = self.create_subscription( PointCloud2, topic_name, @@ -245,20 +246,12 @@ def register_subscribers(self) -> None: ) pointcloud_subs[key] = subscription - else: - self.get_logger().warn(f"Unknown data_type '{data_type}' for subscriber '{key}'") - - self.get_logger().info( - f"Registered {len(pointcloud_subs)} pointcloud subscribers and {len(image_subs)} image subscribers." - ) - def register_publishers(self) -> None: - """Register ROS publishers for elevation maps.""" self._publishers_dict = {} self._publishers_timers = [] for pub_key, pub_config in self.my_publishers.items(): - topic_name = f"/{self.node_name}/{pub_key}" + topic_name = f"/{self.get_name()}/{pub_key}" publisher = self.create_publisher(GridMap, topic_name, 10) self._publishers_dict[pub_key] = publisher @@ -269,10 +262,7 @@ def register_publishers(self) -> None: ) self._publishers_timers.append(timer) - self.get_logger().info(f"Publisher '{pub_key}' registered on topic '{topic_name}' with {fps} Hz.") - def register_timers(self) -> None: - """Register ROS timers for pose update, variance update, and time update.""" self.time_pose_update = self.create_timer( 0.1, self.pose_update @@ -287,16 +277,8 @@ def register_timers(self) -> None: ) def publish_map(self, key: str) -> None: - """ - Publish the elevation map on the specified topic. - - Args: - key (str): The key identifying which publisher to use. - """ if self._map_q is None: - self.get_logger().info("No map pose available for publishing.") return - gm = GridMap() gm.header.frame_id = self.map_frame gm.header.stamp = self.get_clock().now().to_msg() @@ -306,10 +288,10 @@ def publish_map(self, key: str) -> None: gm.info.pose.position.x = self._map_t.x gm.info.pose.position.y = self._map_t.y gm.info.pose.position.z = 0.0 - gm.info.pose.orientation.w = 1.0 # self._map_q.w - gm.info.pose.orientation.x = 0.0 # self._map_q.x - gm.info.pose.orientation.y = 0.0 # self._map_q.y - gm.info.pose.orientation.z = 0.0 # self._map_q.z + gm.info.pose.orientation.w = 1.0 + gm.info.pose.orientation.x = 0.0 + gm.info.pose.orientation.y = 0.0 + gm.info.pose.orientation.z = 0.0 gm.layers = [] gm.basic_layers = self.my_publishers[key]["basic_layers"] @@ -321,174 +303,116 @@ def publish_map(self, key: str) -> None: N = self._map_data.shape[0] arr.layout.dim.append(MAD(label="column_index", size=N, stride=int(N * N))) arr.layout.dim.append(MAD(label="row_index", size=N, stride=N)) - # Convert to a Python list to satisfy the message requirements arr.data = self._map_data.T.flatten().tolist() gm.data.append(arr) gm.outer_start_index = 0 gm.inner_start_index = 0 - self._publishers_dict[key].publish(gm) + def safe_lookup_transform(self, target_frame, source_frame, time): + try: + return self._tf_buffer.lookup_transform( + target_frame, + source_frame, + time + ) + except tf2_ros.ExtrapolationException: + return self._tf_buffer.lookup_transform( + target_frame, + source_frame, + rclpy.time.Time() + ) + def image_callback(self, camera_msg: Image, camera_info_msg: CameraInfo, sub_key: str) -> None: - """ - Callback function for synchronized image and camera info messages. - - Args: - camera_msg (Image): The image message. - camera_info_msg (CameraInfo): The camera info message. - sub_key (str): The subscriber key identifier. - """ - # Store timestamps self._last_t = camera_msg.header.stamp - try: - # Convert image using cv_bridge semantic_img = self.cv_bridge.imgmsg_to_cv2(camera_msg, desired_encoding="passthrough") - except Exception as e: - self.get_logger().error(f"CV Bridge conversion failed: {e}") + except: return - - # Ensure image is grayscale or split channels if len(semantic_img.shape) != 2: semantic_img = [semantic_img[:, :, k] for k in range(semantic_img.shape[2])] else: semantic_img = [semantic_img] - # Get camera parameters K = np.array(camera_info_msg.k, dtype=np.float32).reshape(3, 3) D = np.array(camera_info_msg.d, dtype=np.float32).reshape(-1, 1) - if not np.all(D == 0.0): - self.get_logger().warn("Camera distortion coefficients are not zero. Undistortion not implemented.") - - # Get transform from camera frame to map frame - try: - transform_camera_to_map = self._tf_buffer.lookup_transform( - self.map_frame, - camera_msg.header.frame_id, - camera_msg.header.stamp - ) - - t = transform_camera_to_map.transform.translation - q = transform_camera_to_map.transform.rotation - t_np = np.array([t.x, t.y, t.z], dtype=np.float32) - R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) - - # Process image - self._map.input_image( - sub_key, semantic_img, R, t_np, K, D, - camera_info_msg.height, camera_info_msg.width - ) - self._image_process_counter += 1 - self.get_logger().debug(f"Images processed: {self._image_process_counter}") - - except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - self.get_logger().warn(f"[image_callback] Transform lookup failed: {e}") - except Exception as e: - self.get_logger().error(f"[image_callback] Unexpected error: {str(e)}") + transform_camera_to_map = self.safe_lookup_transform( + self.map_frame, + camera_msg.header.frame_id, + camera_msg.header.stamp + ) + t = transform_camera_to_map.transform.translation + q = transform_camera_to_map.transform.rotation + t_np = np.array([t.x, t.y, t.z], dtype=np.float32) + R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) + self._map.input_image( + sub_key, semantic_img, R, t_np, K, D, + camera_info_msg.height, camera_info_msg.width + ) + self._image_process_counter += 1 def pointcloud_callback(self, msg: PointCloud2, sub_key: str) -> None: - """ - Callback function for point cloud messages. - - Args: - msg (PointCloud2): The point cloud message. - sub_key (str): The subscriber key identifier. - """ self._last_t = msg.header.stamp channels = ["x", "y", "z"] + self.param.subscriber_cfg[sub_key].get("channels", []) - try: points = rnp.numpify(msg) - except Exception as e: - self.get_logger().error(f"Failed to numpify pointcloud: {e}") + except: return - if points['xyz'].size == 0: - self.get_logger().warn("Received empty point cloud.") return - frame_sensor_id = msg.header.frame_id - try: - # Add a timeout to wait for the transform to become available - transform_sensor_to_map = self._tf_buffer.lookup_transform( - self.map_frame, - frame_sensor_id, - self._last_t, - ) - - t = transform_sensor_to_map.transform.translation - q = transform_sensor_to_map.transform.rotation - t_np = np.array([t.x, t.y, t.z], dtype=np.float32) - R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) - - self._map.input_pointcloud(points['xyz'], channels, R, t_np, 0, 0) - self._pointcloud_process_counter += 1 - - except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - self.get_logger().debug(f"[pointcloud_callback] Transform lookup failed: {e}") - except Exception as e: - self.get_logger().error(f"[pointcloud_callback] Unexpected error: {str(e)}") + transform_sensor_to_map = self.safe_lookup_transform( + self.map_frame, + frame_sensor_id, + msg.header.stamp + ) + t = transform_sensor_to_map.transform.translation + q = transform_sensor_to_map.transform.rotation + t_np = np.array([t.x, t.y, t.z], dtype=np.float32) + R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) + self._map.input_pointcloud(points['xyz'], channels, R, t_np, 0, 0) + self._pointcloud_process_counter += 1 def pose_update(self) -> None: - """Update the pose based on the latest transform.""" if self._last_t is None: - self.get_logger().debug("No timestamp available for pose update.") return - - try: - transform = self._tf_buffer.lookup_transform( - self.map_frame, - self.base_frame, - self._last_t - ) - - # Update the pose - t = transform.transform.translation - q = transform.transform.rotation - trans = np.array([t.x, t.y, t.z], dtype=np.float32) - rot = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) - - self._map.move_to(trans, rot) - self._map_t = t - self._map_q = q - - except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: - self.get_logger().warn(f"[pose_update] Transform lookup failed: {e}") - except Exception as e: - self.get_logger().error(f"[pose_update] Unexpected error: {str(e)}") + transform = self.safe_lookup_transform( + self.map_frame, + self.base_frame, + self._last_t + ) + t = transform.transform.translation + q = transform.transform.rotation + trans = np.array([t.x, t.y, t.z], dtype=np.float32) + rot = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) + self._map.move_to(trans, rot) + self._map_t = t + self._map_q = q def update_variance(self) -> None: self._map.update_variance() - self.get_logger().debug("Variance updated.") def update_time(self) -> None: self._map.update_time() - self.get_logger().debug("Time updated.") def destroy_node(self) -> None: super().destroy_node() - def main(args=None) -> None: - """Main entry point for the elevation mapping node.""" rclpy.init(args=args) node = ElevationMappingNode() - - # Use a SingleThreadedExecutor as per original implementation executor = rclpy.executors.SingleThreadedExecutor() executor.add_node(node) - try: executor.spin() except KeyboardInterrupt: - node.get_logger().info("Shutting down ElevationMappingNode.") + pass finally: executor.shutdown() node.destroy_node() rclpy.shutdown() - if __name__ == '__main__': main() diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/plugins/plugin_manager.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/plugin_manager.py index 26f81d21..048ca016 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/plugins/plugin_manager.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/plugin_manager.py @@ -132,7 +132,6 @@ def init(self, plugin_params: List[PluginParams], extra_params: List[Dict]): self.plugin_names = self.get_plugin_names() def load_plugin_settings(self, file_path: str): - print("Start loading plugins...") cfg = YAML().load(open(file_path, "r")) plugin_params = [] extra_params = [] diff --git a/elevation_mapping_cupy/launch/elevation_mapping.launch.py b/elevation_mapping_cupy/launch/elevation_mapping.launch.py index f8f4f848..f2bf3cf2 100755 --- a/elevation_mapping_cupy/launch/elevation_mapping.launch.py +++ b/elevation_mapping_cupy/launch/elevation_mapping.launch.py @@ -2,21 +2,82 @@ from launch import LaunchDescription from launch_ros.actions import Node from ament_index_python.packages import get_package_share_directory +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration, PathJoinSubstitution +from launch.conditions import IfCondition def generate_launch_description(): package_name = 'elevation_mapping_cupy' share_dir = get_package_share_directory(package_name) - config_file = os.path.join(share_dir, 'config', 'core_param.yaml') - if not os.path.exists(config_file): - raise FileNotFoundError(f"Config file {config_file} does not exist") + # Define paths + core_param_path = os.path.join(share_dir, 'config', 'core', 'core_param.yaml') + + # Declare launch arguments + robot_param_arg = DeclareLaunchArgument( + 'robot_config', + # default_value='turtle_bot/turle_bot_simple.yaml', + default_value='menzi/base.yaml', + description='Name of the robot-specific config file within config/setups/' + ) + + launch_rviz_arg = DeclareLaunchArgument( + 'launch_rviz', + default_value='false', + description='Whether to launch RViz' + ) + + rviz_config_arg = DeclareLaunchArgument( + 'rviz_config', + default_value='', + description='Path to the RViz config file' + ) + + use_sim_time_arg = DeclareLaunchArgument( + 'use_sim_time', + default_value='false', + description='Use simulation clock if true' + ) + + # Get launch configurations + robot_config = LaunchConfiguration('robot_config') + robot_param_path = PathJoinSubstitution([share_dir, 'config', 'setups', robot_config]) + launch_rviz = LaunchConfiguration('launch_rviz') + rviz_config = LaunchConfiguration('rviz_config') + use_sim_time = LaunchConfiguration('use_sim_time') + + # Verify core config exists + if not os.path.exists(core_param_path): + raise FileNotFoundError(f"Config file {core_param_path} does not exist") + + # Define nodes + elevation_mapping_node = Node( + package=package_name, + executable='elevation_mapping_node', + name='elevation_mapping_node', + output='screen', + parameters=[ + core_param_path, + robot_param_path, + {'use_sim_time': use_sim_time} + ] + ) + + rviz_node = Node( + package='rviz2', + executable='rviz2', + name='rviz2', + arguments=['-d', rviz_config], + parameters=[{'use_sim_time': use_sim_time}], + output='screen', + condition=IfCondition(launch_rviz) + ) return LaunchDescription([ - Node( - package=package_name, - executable='elevation_mapping_node', - name='elevation_mapping_node', - output='screen', - parameters=[config_file] - ) + robot_param_arg, + launch_rviz_arg, + rviz_config_arg, + use_sim_time_arg, + elevation_mapping_node, + rviz_node ]) \ No newline at end of file diff --git a/elevation_mapping_cupy/launch/menzi.launch b/elevation_mapping_cupy/launch/menzi.launch new file mode 100644 index 00000000..e69de29b diff --git a/elevation_mapping_cupy/launch/turtlesim_init.launch.py b/elevation_mapping_cupy/launch/turtlesim_init.launch.py index 660f5410..90530e4b 100644 --- a/elevation_mapping_cupy/launch/turtlesim_init.launch.py +++ b/elevation_mapping_cupy/launch/turtlesim_init.launch.py @@ -108,7 +108,7 @@ def generate_launch_description(): robot_description_content = Command([ 'cat ', PathJoinSubstitution([ - turtlebot3_description_dir, 'urdf', 'turtlebot3_waffle_camera.urdf' + turtlebot3_description_dir, 'urdf', 'turtlebot3_waffle.urdf' ]) ]) @@ -150,7 +150,7 @@ def generate_launch_description(): ld = LaunchDescription() # Add the declared arguments - # ld.add_action(use_sim_time_arg) + ld.add_action(use_sim_time_arg) # ld.add_action(rviz_config_arg) ld.add_action(model_arg) ld.add_action(x_pos_arg) From 1eaf94b8ab7a1a08e873b2376e76ffa30179e23f Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Fri, 7 Feb 2025 21:49:59 +0000 Subject: [PATCH 475/504] Getting working with turtlebot3 example: fixing cupy/numpy bool8 type issue, updating package.xmls Adjusting quality of service a bit Enabling other layers e.g. rgb in pointcloud2 subscriber --- elevation_mapping_cupy/README.md | 28 +++++++- .../config/core/core_param.yaml | 8 +-- .../setups/turtle_bot/turtle_bot_simple.yaml | 1 + .../elevation_mapping_ros.py | 33 ++++++--- .../elevation_mapping_cupy/semantic_map.py | 4 +- elevation_mapping_cupy/package.xml | 13 +++- .../rviz/turtle_sim_laser.rviz | 69 ++++++++++++------- plane_segmentation/cgal5_ament/package.xml | 2 +- .../grid_map_filters_rsl/CMakeLists.txt | 8 +-- .../grid_map_filters_rsl/package.xml | 4 +- sensor_processing/semantic_sensor/package.xml | 3 +- 11 files changed, 125 insertions(+), 48 deletions(-) diff --git a/elevation_mapping_cupy/README.md b/elevation_mapping_cupy/README.md index f7010dff..fe60536e 100644 --- a/elevation_mapping_cupy/README.md +++ b/elevation_mapping_cupy/README.md @@ -9,4 +9,30 @@ You can also maunally spawn the robot in Gazebo. Launch the elevation mapping node: ```bash -ros2 launch elevation_mapping_cupy turtle_simple_example.launch.py``` \ No newline at end of file +ros2 launch elevation_mapping_cupy turtle_simple_example.launch.py +``` + + +## (Corrected) Example 1: Turtle Simple Example +Set the env in the Dockerfile +```dockerfile +ENV TURTLEBOT3_MODEL=waffle_realsense_depth +``` +or in the terminal +```bash +export TURTLEBOT3_MODEL=waffle_realsense_depth +``` +If using zenoh as rmw then start one terminal up and run the router +```bash +ros2 run rmw_zenoh_cpp rmw_zenohd +``` + +Now launch the turtlebot3 in Gazebo with the following command: +```bash +ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py +``` + +Launch the elevation mapping node with the configs for the turtle: +```bash +ros2 launch elevation_mapping_cupy elevation_mapping_turtle.launch.py +``` \ No newline at end of file diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 3786b25f..60771890 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -20,7 +20,7 @@ elevation_mapping_node: orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. - min_valid_distance: 4.0 # points with shorter distance will be filtered out. + min_valid_distance: 0.1 # points with shorter distance will be filtered out. max_height_range: 10.5 # points higher than this value from sensor will be filtered out ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. @@ -44,9 +44,9 @@ elevation_mapping_node: overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - map_frame: 'World' # The map frame where the odometry source uses. - base_frame: 'BASE' # The robot's base frame. This frame will be a center of the map. - corrected_map_frame: 'World' + map_frame: 'odom' # The map frame where the odometry source uses. + base_frame: 'base_link' # The robot's base frame. This frame will be a center of the map. + corrected_map_frame: 'odom' # map_frame: 'World' # The map frame where the odometry source uses. diff --git a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml index 637a99ae..6d274f25 100644 --- a/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml +++ b/elevation_mapping_cupy/config/setups/turtle_bot/turtle_bot_simple.yaml @@ -13,6 +13,7 @@ front_cam: topic_name: '/intel_realsense_r200_depth/points' data_type: pointcloud + channels: ['rgb'] publishers: elevation_map_raw: diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py index 83f19ad4..5c0bf337 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py @@ -5,6 +5,7 @@ import rclpy from rclpy.node import Node +from rclpy.qos import QoSPresetProfiles from ament_index_python.packages import get_package_share_directory import ros2_numpy as rnp from sensor_msgs.msg import PointCloud2, Image, CameraInfo @@ -232,12 +233,15 @@ def register_subscribers(self) -> None: image_subs[key] = image_sync elif data_type == "pointcloud": topic_name = config.get("topic_name", "/pointcloud") - qos_profile = rclpy.qos.QoSProfile( - depth=10, - reliability=rclpy.qos.ReliabilityPolicy.BEST_EFFORT, - durability=rclpy.qos.DurabilityPolicy.VOLATILE, - history=rclpy.qos.HistoryPolicy.KEEP_LAST - ) + # qos_profile = rclpy.qos.QoSProfile( + # depth=10, + # reliability=rclpy.qos.ReliabilityPolicy.BEST_EFFORT, + # durability=rclpy.qos.DurabilityPolicy.VOLATILE, + # history=rclpy.qos.HistoryPolicy.KEEP_LAST + # ) + # qos_profile = QoSPresetProfiles.get_from_short_key("sensor_data") + # qos_profile = rclpy.qos.QoSProfile(depth=10) + qos_profile = 10 subscription = self.create_subscription( PointCloud2, topic_name, @@ -355,12 +359,14 @@ def image_callback(self, camera_msg: Image, camera_info_msg: CameraInfo, sub_key def pointcloud_callback(self, msg: PointCloud2, sub_key: str) -> None: self._last_t = msg.header.stamp - channels = ["x", "y", "z"] + self.param.subscriber_cfg[sub_key].get("channels", []) + # self.get_logger().info(f"Received pointcloud with {msg.width} points") + additional_channels = self.param.subscriber_cfg[sub_key].get("channels", []) + channels = ["x", "y", "z"] + additional_channels try: points = rnp.numpify(msg) except: return - if points['xyz'].size == 0: + if points['x'].size == 0: return frame_sensor_id = msg.header.frame_id transform_sensor_to_map = self.safe_lookup_transform( @@ -372,7 +378,16 @@ def pointcloud_callback(self, msg: PointCloud2, sub_key: str) -> None: q = transform_sensor_to_map.transform.rotation t_np = np.array([t.x, t.y, t.z], dtype=np.float32) R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) - self._map.input_pointcloud(points['xyz'], channels, R, t_np, 0, 0) + pts = rnp.point_cloud2.get_xyz_points(points) + # TODO: This is probably expensive. Consider modifying rnp or input_pointcloud() + # Append additional channels to pts + for channel in additional_channels: + if channel in points.dtype.names: + data = points[channel] + if data.ndim == 1: + data = data[:, np.newaxis] + pts = np.hstack((pts, data)) + self._map.input_pointcloud(pts, channels, R, t_np, 0, 0) self._pointcloud_process_counter += 1 def pose_update(self) -> None: diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/semantic_map.py b/elevation_mapping_cupy/elevation_mapping_cupy/semantic_map.py index a06b7361..390597b6 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/semantic_map.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/semantic_map.py @@ -41,7 +41,7 @@ def __init__(self, param: Parameter): self.new_map = xp.zeros((self.amount_layer_names, self.param.cell_n, self.param.cell_n), param.data_type,) # which layers should be reset to zero at each update, per default everyone, # if a layer should not be reset, it is defined in compile_kernels function - self.delete_new_layers = cp.ones(self.new_map.shape[0], cp.bool8) + self.delete_new_layers = cp.ones(self.new_map.shape[0], cp.bool_) self.fusion_manager = FusionManager(self.param) def clear(self): @@ -94,7 +94,7 @@ def add_layer(self, name): self.new_map = cp.append( self.new_map, cp.zeros((1, self.param.cell_n, self.param.cell_n), dtype=self.param.data_type), axis=0, ) - self.delete_new_layers = cp.append(self.delete_new_layers, cp.array([1], dtype=cp.bool8)) + self.delete_new_layers = cp.append(self.delete_new_layers, cp.array([1], dtype=cp.bool_)) def pad_value(self, x, shift_value, idx=None, value=0.0): """Create a padding of the map along x,y-axis according to amount that has shifted. diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index e1bad0c5..4fa63b9f 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -7,7 +7,7 @@ MIT - ament_python + ament_cmake @@ -21,20 +21,31 @@ image_transport pcl_ros pybind11 + ros2_numpy + + numpy tf2_ros message_filters cv_bridge ament_index_python tf_transformations + rviz2 gazebo_ros robot_state_publisher + opencv-python + + + + cupy-cuda12x + simple-parsing + ament_python ament_python diff --git a/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz b/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz index 7b97d78c..2b4ecd2f 100644 --- a/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz +++ b/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz @@ -6,12 +6,8 @@ Panels: Expanded: - /Global Options1 - /Status1 - - /PointCloud21 - - /RobotModel1 - - /TF1 - - /GridMap1 Splitter Ratio: 0.5 - Tree Height: 272 + Tree Height: 551 - Class: rviz_common/Selection Name: Selection - Class: rviz_common/Tool Properties @@ -247,8 +243,9 @@ Visualization Manager: Value: /intel_realsense_r200_rgb/image_raw Value: false Visibility: - "": true Grid: true + GridMap: true + GridMapFiltered: true Image: true PointCloud2: true RobotModel: true @@ -256,7 +253,7 @@ Visualization Manager: Value: true Zoom Factor: 1 - Class: rviz_default_plugins/Image - Enabled: false + Enabled: true Max Value: 1 Median window: 5 Min Value: 0 @@ -268,7 +265,7 @@ Visualization Manager: History Policy: Keep Last Reliability Policy: Reliable Value: /intel_realsense_r200_depth/image_raw - Value: false + Value: true - Class: rviz_default_plugins/Image Enabled: true Max Value: 1 @@ -287,8 +284,8 @@ Visualization Manager: Autocompute Intensity Bounds: true Class: grid_map_rviz_plugin/GridMap Color: 200; 200; 200 - Color Layer: elevation - Color Transformer: IntensityLayer + Color Layer: rgb + Color Transformer: ColorLayer Enabled: true Height Layer: elevation Height Transformer: GridMapLayer @@ -306,13 +303,39 @@ Visualization Manager: Filter size: 10 History Policy: Keep Last Reliability Policy: Reliable - Value: /elevation_mapping/elevation_map_raw + Value: /elevation_mapping_node/elevation_map_raw Use Rainbow: true Value: true + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: elevation + Color Transformer: IntensityLayer + Enabled: false + Height Layer: smooth + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 255; 255; 255 + Max Intensity: 10 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: GridMapFiltered + Show Grid Lines: true + Topic: + Depth: 5 + Durability Policy: Volatile + Filter size: 10 + History Policy: Keep Last + Reliability Policy: Reliable + Value: /elevation_mapping_node/elevation_map_filter + Use Rainbow: true + Value: false Enabled: true Global Options: Background Color: 48; 48; 48 - Fixed Frame: base_footprint + Fixed Frame: odom Frame Rate: 30 Name: root Tools: @@ -355,37 +378,37 @@ Visualization Manager: Views: Current: Class: rviz_default_plugins/Orbit - Distance: 6.990833282470703 + Distance: 16.440555572509766 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 Swap Stereo Eyes: false Value: false Focal Point: - X: 0.13978521525859833 - Y: 0.045054733753204346 - Z: 0.2562030851840973 + X: 1.3501025438308716 + Y: 2.9009647369384766 + Z: 0.35463666915893555 Focal Shape Fixed Size: true Focal Shape Size: 0.05000000074505806 Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.3597964644432068 + Pitch: 0.6447965502738953 Target Frame: Value: Orbit (rviz) - Yaw: 3.0935845375061035 + Yaw: 2.8535845279693604 Saved: ~ Window Geometry: Camera: collapsed: false Displays: collapsed: false - Height: 846 + Height: 1314 Hide Left Dock: false Hide Right Dock: false Image: collapsed: false - QMainWindow State: 000000ff00000000fd000000040000000000000156000002b4fc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003b00000199000000c700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000c00430061006d0065007200610000000136000000f70000002800fffffffb0000000a0049006d0061006700650000000157000000d60000002800fffffffb0000000a0049006d00610067006501000001da000001150000002800ffffff000000010000010f000002b4fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003b000002b4000000a000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004b00000003efc0100000002fb0000000800540069006d00650100000000000004b00000025300fffffffb0000000800540069006d006501000000000000045000000000000000000000023f000002b400000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd00000004000000000000025f00000488fc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003b000002b0000000c700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000c00430061006d0065007200610000000136000000f70000002800fffffffb0000000a0049006d0061006700650000000157000000d60000002800fffffffb0000000a0049006d00610067006501000002f1000001d20000002800ffffff000000010000010f00000488fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003b00000488000000a000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e1000001970000000300000a000000003efc0100000002fb0000000800540069006d0065010000000000000a000000025300fffffffb0000000800540069006d00650100000000000004500000000000000000000006860000048800000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -394,6 +417,6 @@ Window Geometry: collapsed: false Views: collapsed: false - Width: 1200 - X: 60 - Y: 169 + Width: 2560 + X: 0 + Y: 27 diff --git a/plane_segmentation/cgal5_ament/package.xml b/plane_segmentation/cgal5_ament/package.xml index 672b22b3..d280c209 100644 --- a/plane_segmentation/cgal5_ament/package.xml +++ b/plane_segmentation/cgal5_ament/package.xml @@ -10,7 +10,7 @@ ament_cmake - Boost + boost diff --git a/plane_segmentation/grid_map_filters_rsl/CMakeLists.txt b/plane_segmentation/grid_map_filters_rsl/CMakeLists.txt index 515f0536..47a9f1a4 100644 --- a/plane_segmentation/grid_map_filters_rsl/CMakeLists.txt +++ b/plane_segmentation/grid_map_filters_rsl/CMakeLists.txt @@ -73,9 +73,9 @@ install(DIRECTORY include/${PROJECT_NAME}/ # Clang tools (optional) -find_package(cmake_clang_tools QUIET) -if(cmake_clang_tools_FOUND) - add_default_clang_tooling() -endif() +# find_package(cmake_clang_tools QUIET) +# if(cmake_clang_tools_FOUND) +# add_default_clang_tooling() +# endif() ament_package() \ No newline at end of file diff --git a/plane_segmentation/grid_map_filters_rsl/package.xml b/plane_segmentation/grid_map_filters_rsl/package.xml index fbea7dc0..786e5637 100644 --- a/plane_segmentation/grid_map_filters_rsl/package.xml +++ b/plane_segmentation/grid_map_filters_rsl/package.xml @@ -14,10 +14,10 @@ ament_cmake - cmake_clang_tools + grid_map_cv grid_map_core - Eigen3 + eigen rosidl_runtime_cpp diff --git a/sensor_processing/semantic_sensor/package.xml b/sensor_processing/semantic_sensor/package.xml index d789afb1..e4b66f31 100644 --- a/sensor_processing/semantic_sensor/package.xml +++ b/sensor_processing/semantic_sensor/package.xml @@ -9,7 +9,7 @@ https://github.com/leggedrobotics/elevation_mapping_semantic_cupy - ament_python + rclpy tf2_ros sensor_msgs @@ -18,6 +18,7 @@ python3 + ament_python From a3906932bbade6b1f039e49de529d08981129251 Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Fri, 14 Feb 2025 14:31:34 -0600 Subject: [PATCH 476/504] Trying to get building in container with ros2 Mostly fixing rosdep names --- elevation_mapping_cupy/package.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index 4fa63b9f..2f27dede 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -39,9 +39,8 @@ opencv-python - - cupy-cuda12x + simple-parsing From ff7bc6471bb722e6001d77b71b61bcbcc5f33d0e Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Fri, 14 Feb 2025 14:34:43 -0600 Subject: [PATCH 477/504] Got nominally working by messing with quality of service a bit --- .../rviz/turtle_sim_laser.rviz | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz b/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz index 2b4ecd2f..2b4544c1 100644 --- a/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz +++ b/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz @@ -243,6 +243,7 @@ Visualization Manager: Value: /intel_realsense_r200_rgb/image_raw Value: false Visibility: + "": true Grid: true GridMap: true GridMapFiltered: true @@ -305,6 +306,32 @@ Visualization Manager: Reliability Policy: Reliable Value: /elevation_mapping_node/elevation_map_raw Use Rainbow: true + Value: false + - Alpha: 1 + Autocompute Intensity Bounds: true + Class: grid_map_rviz_plugin/GridMap + Color: 200; 200; 200 + Color Layer: elevation + Color Transformer: IntensityLayer + Enabled: true + Height Layer: smooth + Height Transformer: GridMapLayer + History Length: 1 + Invert Rainbow: false + Max Color: 255; 255; 255 + Max Intensity: 10 + Min Color: 0; 0; 0 + Min Intensity: 0 + Name: GridMapFiltered + Show Grid Lines: true + Topic: + Depth: 5 + Durability Policy: Volatile + Filter size: 10 + History Policy: Keep Last + Reliability Policy: Reliable + Value: /elevation_mapping_node/elevation_map_filter + Use Rainbow: true Value: true - Alpha: 1 Autocompute Intensity Bounds: true From b6465a3fb8503a5582e270427090d6ee0d93792c Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Fri, 14 Feb 2025 14:34:59 -0600 Subject: [PATCH 478/504] Enabling other layers e.g. rgb in pointcloud2 subscriber --- elevation_mapping_cupy/rviz/turtle_sim_laser.rviz | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz b/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz index 2b4544c1..eee8d140 100644 --- a/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz +++ b/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz @@ -243,7 +243,6 @@ Visualization Manager: Value: /intel_realsense_r200_rgb/image_raw Value: false Visibility: - "": true Grid: true GridMap: true GridMapFiltered: true @@ -306,14 +305,14 @@ Visualization Manager: Reliability Policy: Reliable Value: /elevation_mapping_node/elevation_map_raw Use Rainbow: true - Value: false + Value: true - Alpha: 1 Autocompute Intensity Bounds: true Class: grid_map_rviz_plugin/GridMap Color: 200; 200; 200 Color Layer: elevation Color Transformer: IntensityLayer - Enabled: true + Enabled: false Height Layer: smooth Height Transformer: GridMapLayer History Length: 1 From 6280caf65ffd6e138a6ddfd26d2db91d33fe6e69 Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Fri, 14 Feb 2025 16:39:14 -0600 Subject: [PATCH 479/504] Got python version working again and cpp version building. Still need to test cpp version --- elevation_mapping_cupy/CMakeLists.txt | 71 ++++++++----------- .../elevation_mapping.py | 23 +++--- .../launch/elevation_mapping_turtle.launch.py | 2 +- elevation_mapping_cupy/package.xml | 12 ++-- .../resource/elevation_mapping_cupy | 0 .../elevation_mapping_node.py} | 0 6 files changed, 45 insertions(+), 63 deletions(-) delete mode 100644 elevation_mapping_cupy/resource/elevation_mapping_cupy rename elevation_mapping_cupy/{elevation_mapping_cupy/elevation_mapping_ros.py => scripts/elevation_mapping_node.py} (100%) mode change 100644 => 100755 diff --git a/elevation_mapping_cupy/CMakeLists.txt b/elevation_mapping_cupy/CMakeLists.txt index 11743e1a..e2a66c5c 100644 --- a/elevation_mapping_cupy/CMakeLists.txt +++ b/elevation_mapping_cupy/CMakeLists.txt @@ -5,10 +5,16 @@ project(elevation_mapping_cupy) # set(CMAKE_CXX_STANDARD 11) # set(CMAKE_CXX_STANDARD_REQUIRED ON) +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + # Compiler options if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() + # Additional dependencies # find_package(Python COMPONENTS Interpreter Development) find_package(PythonInterp 3 REQUIRED) @@ -17,17 +23,17 @@ find_package(Eigen3 REQUIRED) find_package(OpenCV REQUIRED) # Find pybind11 - message([MAIN] "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}") message([MAIN] "pybind11_INCLUDE_DIRS = ${pybind11_INCLUDE_DIRS}") message([MAIN] "pybind11_LIBRARIES = ${pybind11_LIBRARIES}") # Find ROS 2 dependencies -find_package(message_filters REQUIRED) find_package(ament_cmake REQUIRED) +find_package(ament_cmake_python REQUIRED) find_package(rclcpp REQUIRED) find_package(rclpy REQUIRED) find_package(builtin_interfaces REQUIRED) +find_package(message_filters REQUIRED) find_package(std_msgs REQUIRED) find_package(std_srvs REQUIRED) find_package(sensor_msgs REQUIRED) @@ -38,13 +44,9 @@ find_package(grid_map_ros REQUIRED) find_package(image_transport REQUIRED) find_package(pcl_ros REQUIRED) find_package(tf2_eigen REQUIRED) -find_package(ament_cmake_python REQUIRED) find_package(python_cmake_module REQUIRED) find_package(point_cloud_transport REQUIRED) -_ament_cmake_python_register_environment_hook() -ament_python_install_package(${PROJECT_NAME} PACKAGE_DIR script/${PROJECT_NAME}) - # List dependencies for ament_target_dependencies set(dependencies rclcpp @@ -92,52 +94,39 @@ target_link_libraries(elevation_mapping_node elevation_mapping_ros ${OpenCV_LIBR ament_target_dependencies(elevation_mapping_node ${dependencies}) +# Install targets Not sure if these other argrs are necessary +# install( +# TARGETS elevation_mapping_ros elevation_mapping_node +# DESTINATION lib/${PROJECT_NAME} +# ARCHIVE DESTINATION lib +# LIBRARY DESTINATION lib +# RUNTIME DESTINATION bin +# ) -# Install targets -install( - TARGETS elevation_mapping_node - DESTINATION lib/${PROJECT_NAME} - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin -) - - -install(TARGETS - elevation_mapping_node +install(TARGETS elevation_mapping_ros elevation_mapping_node DESTINATION lib/${PROJECT_NAME} ) +# install(PROGRAMS +# DESTINATION lib/${PROJECT_NAME} +# ) +# Install launch, config, and rviz directories install( - TARGETS elevation_mapping_ros - DESTINATION lib/${PROJECT_NAME} - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin + DIRECTORY launch config rviz + DESTINATION share/${PROJECT_NAME} ) +# TODO: Understand if this line is necessary +# _ament_cmake_python_register_environment_hook() +# For use as a Python module outside of ROS 2 +ament_python_install_package(${PROJECT_NAME}) - - -install(PROGRAMS +# Install the Python ROS 2 modules +install(PROGRAMS + scripts/elevation_mapping_node.py DESTINATION lib/${PROJECT_NAME} ) -# Install launch and config directories -install( - DIRECTORY launch config - DESTINATION share/${PROJECT_NAME} -) - - - -_ament_cmake_python_register_environment_hook() - - -# ament_python_install_package(script/${PROJECT_NAME}) -# ament_python_install_package(script/${PROJECT_NAME}) - - # Ament package declaration ament_package() diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py index 70ecb9a0..48838da5 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py @@ -5,8 +5,6 @@ import os from typing import List, Any, Tuple, Union -import rclpy # Import rclpy for ROS 2 logging -from ament_index_python.packages import get_package_prefix import numpy as np import threading import subprocess @@ -17,7 +15,6 @@ ) from elevation_mapping_cupy.parameter import Parameter - from elevation_mapping_cupy.kernels import ( add_points_kernel, add_color_kernel, @@ -44,6 +41,7 @@ ) import cupy as cp +import rclpy # Import rclpy for ROS 2 logging xp = cp pool = cp.cuda.MemoryPool(cp.cuda.malloc_managed) @@ -61,6 +59,7 @@ def __init__(self, param: Parameter): """ # Initialize the ROS logger self.logger = rclpy.logging.get_logger('elevation_map') + self.param = param self.data_type = self.param.data_type self.resolution = param.resolution @@ -101,29 +100,24 @@ def __init__(self, param: Parameter): self.additive_mean_error = 0.0 self.compile_kernels() - self.logger.info("Finished compiling kernels.") + self.compile_image_kernels() - self.logger.info("Finished compiling image kernels.") + self.semantic_map.initialize_fusion() - self.logger.info("Finished compiling semantic_map kernels.") weight_file = subprocess.getoutput('echo "' + param.weight_file + '"') - package_prefix = get_package_prefix('elevation_mapping_cupy') - self.logger.info("weight file : ." + str(package_prefix) + str(weight_file)) - param.load_weights(package_prefix+weight_file) + param.load_weights(weight_file) if param.use_chainer: self.traversability_filter = get_filter_chainer(param.w1, param.w2, param.w3, param.w_out) else: self.traversability_filter = get_filter_torch(param.w1, param.w2, param.w3, param.w_out) - self.untraversable_polygon = xp.zeros((1, 2)) # Plugins self.plugin_manager = PluginManager(cell_n=self.cell_n) plugin_config_file = subprocess.getoutput('echo "' + param.plugin_config_file + '"') - self.logger.info("plugin file : ." + str(package_prefix) + str(plugin_config_file)) - self.plugin_manager.load_plugin_settings(package_prefix+plugin_config_file) + self.plugin_manager.load_plugin_settings(plugin_config_file) self.map_initializer = MapInitializer(self.initial_variance, param.initialized_variance, xp=cp, method="points") @@ -359,7 +353,7 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori error = cp.array([0.0], dtype=cp.float32) error_cnt = cp.array([0], dtype=cp.float32) points = points_all[:, :3] - # additional_fusion = self.get_fusion_of_pcl(channels) + with self.map_lock: self.shift_translation_to_map_center(t) @@ -982,8 +976,7 @@ def initialize_map(self, points, method="cubic"): plugin_config_file="../config/plugin_config.yaml", ) param.additional_layers = ["rgb", "grass", "tree", "people"] - # param.fusion_algorithms = ["color", "class_bayesian", "class_bayesian", "class_bayesian"] - param.fusion_algorithms = ["image_color", "pointcloud_color", "pointcloud_class_average"] + param.fusion_algorithms = ["color", "class_bayesian", "class_bayesian", "class_bayesian"] param.update() elevation = ElevationMap(param) layers = [ diff --git a/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py b/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py index 7c6b06c3..1d901933 100644 --- a/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py +++ b/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py @@ -47,7 +47,7 @@ def generate_launch_description(): ) elevation_mapping_node = Node( package='elevation_mapping_cupy', - executable='elevation_mapping_node', + executable='elevation_mapping_node.py', name='elevation_mapping_node', output='screen', parameters=[ diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index 894cbbe9..3dd01595 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -5,6 +5,7 @@ Elevation mapping on GPU Takahiro Miki MIT + ament_cmake ament_cmake_python @@ -15,7 +16,8 @@ std_srvs sensor_msgs geometry_msgs - point_cloud_transport + + point_cloud_transport message_filters elevation_map_msgs grid_map_msgs @@ -28,7 +30,6 @@ numpy tf2_ros - message_filters cv_bridge ament_index_python tf_transformations @@ -47,15 +48,14 @@ simple-parsing - - ament_python - ament_python + + ament_lint_auto ament_lint_common - ament_python + ament_cmake diff --git a/elevation_mapping_cupy/resource/elevation_mapping_cupy b/elevation_mapping_cupy/resource/elevation_mapping_cupy deleted file mode 100644 index e69de29b..00000000 diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/scripts/elevation_mapping_node.py old mode 100644 new mode 100755 similarity index 100% rename from elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py rename to elevation_mapping_cupy/scripts/elevation_mapping_node.py From 5423cecfeac1bb2f63f46de56c8b091329d53271 Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Fri, 14 Feb 2025 16:39:36 -0600 Subject: [PATCH 480/504] remove ros from base python module fix import of param file --- .../elevation_mapping.py | 21 ------------------- .../launch/elevation_mapping_turtle.launch.py | 5 +++-- 2 files changed, 3 insertions(+), 23 deletions(-) diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py index 48838da5..f76756d5 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py @@ -57,8 +57,6 @@ def __init__(self, param: Parameter): Args: param (elevation_mapping_cupy.parameter.Parameter): """ - # Initialize the ROS logger - self.logger = rclpy.logging.get_logger('elevation_map') self.param = param self.data_type = self.param.data_type @@ -243,25 +241,6 @@ def compile_kernels(self): self.min_filtered_mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) self.mask = cp.zeros((self.cell_n, self.cell_n), dtype=self.data_type) - # Log parameter values before kernel initialization - self.logger.info("Initializing add_points_kernel with parameters:") - self.logger.info(f" resolution: {self.resolution}") - self.logger.info(f" cell_n: {self.cell_n}") - self.logger.info(f" sensor_noise_factor: {self.param.sensor_noise_factor}") - self.logger.info(f" mahalanobis_thresh: {self.param.mahalanobis_thresh}") - self.logger.info(f" outlier_variance: {self.param.outlier_variance}") - self.logger.info(f" wall_num_thresh: {self.param.wall_num_thresh}") - self.logger.info(f" max_ray_length: {self.param.max_ray_length}") - self.logger.info(f" cleanup_step: {self.param.cleanup_step}") - self.logger.info(f" min_valid_distance: {self.param.min_valid_distance}") - self.logger.info(f" max_height_range: {self.param.max_height_range}") - self.logger.info(f" cleanup_cos_thresh: {self.param.cleanup_cos_thresh}") - self.logger.info(f" ramped_height_range_a: {self.param.ramped_height_range_a}") - self.logger.info(f" ramped_height_range_b: {self.param.ramped_height_range_b}") - self.logger.info(f" ramped_height_range_c: {self.param.ramped_height_range_c}") - self.logger.info(f" enable_edge_sharpen: {self.param.enable_edge_sharpen}") - self.logger.info(f" enable_visibility_cleanup: {self.param.enable_visibility_cleanup}") - self.add_points_kernel = add_points_kernel( self.resolution, self.cell_n, diff --git a/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py b/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py index 1d901933..ca5fda23 100644 --- a/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py +++ b/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py @@ -4,6 +4,7 @@ from ament_index_python.packages import get_package_share_directory from launch.actions import DeclareLaunchArgument from launch.substitutions import LaunchConfiguration, PathJoinSubstitution +from launch_ros.descriptions import ParameterFile def generate_launch_description(): @@ -47,11 +48,11 @@ def generate_launch_description(): ) elevation_mapping_node = Node( package='elevation_mapping_cupy', - executable='elevation_mapping_node.py', + executable='elevation_mapping_node', name='elevation_mapping_node', output='screen', parameters=[ - core_param_path, + ParameterFile(core_param_path, allow_substs=True), turtle_param_path, {'use_sim_time': use_sim_time} ] From 0866290b6764e2a71c2b2d4e39b3a2fde3c85a27 Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Fri, 14 Feb 2025 16:41:03 -0600 Subject: [PATCH 481/504] Cleaning up a bit fixing published map topic namespacing Got rid of some unused parameters --- .../config/core/core_param copy 2.yaml | 197 ------------------ .../config/core/core_param copy.yaml | 189 ----------------- .../config/core/core_param.yaml | 14 +- .../config/core/core_param_sim.yaml | 197 ------------------ .../elevation_mapping_cupy/parameter.py | 7 - .../src/elevation_mapping_ros.cpp | 4 +- 6 files changed, 9 insertions(+), 599 deletions(-) delete mode 100644 elevation_mapping_cupy/config/core/core_param copy 2.yaml delete mode 100644 elevation_mapping_cupy/config/core/core_param copy.yaml delete mode 100644 elevation_mapping_cupy/config/core/core_param_sim.yaml diff --git a/elevation_mapping_cupy/config/core/core_param copy 2.yaml b/elevation_mapping_cupy/config/core/core_param copy 2.yaml deleted file mode 100644 index 3a693641..00000000 --- a/elevation_mapping_cupy/config/core/core_param copy 2.yaml +++ /dev/null @@ -1,197 +0,0 @@ -elevation_mapping: - ros__parameters: - #### Basic parameters ######## - voxel_filter_size: 0.05 - enable_normal_arrow_publishing: true - cell_n: 40000 # number of cells in the map. - data_type: 'float32' # data type for the map. - average_weight: 0.5 - drift_compensation_variance_inlier: 0.1 - checker_layer: 'traversability' # layer name for checking the validity of the cell. - min_filter_size: 5 # size of the filter for min filter. - min_filter_iteration: 3 # number of iterations for min filter. - initialized_variance: 10.0 # initial variance for each cell. - resolution: 0.1 # resolution in m. - map_length: 20.0 # map's size in m. - sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). - mahalanobis_thresh: 2.0 # points outside this distance is outlier. - outlier_variance: 0.01 # if point is outlier, add this value to the cell. - drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. - max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) - drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation - time_variance: 0.0001 # add this value when update_variance is called. - max_variance: 100.0 # maximum variance for each cell. - initial_variance: 1000.0 # initial variance for each cell. - traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. - dilation_size: 3 # dilation filter size before traversability filter. - wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. - min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. - position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. - orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. - position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. - orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. - min_valid_distance: 0.5 # points with shorter distance will be filtered out. - max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. - ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - update_variance_fps: 5.0 # fps for updating variance. - update_pose_fps: 10.0 # fps for updating pose and shift the center of map. - time_interval: 0.1 # Time layer is updated with this interval. - map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. - publish_statistics_fps: 1.0 # Publish statistics topic in this fps. - - max_ray_length: 10.0 # maximum length for ray tracing. - cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. - cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. - - safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. - safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. - max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. - - overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) - overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - pose_topic: '/odom' - map_frame: 'odom' # The map frame where the odometry source uses. - base_frame: 'base_link' # The robot's base frame. This frame will be a center of the map. - corrected_map_frame: 'odom' - - - - #### Feature toggles ######## - enable_edge_sharpen: true - enable_visibility_cleanup: true - enable_drift_compensation: true - enable_overlap_clearance: true - enable_pointcloud_publishing: false - enable_drift_corrected_TF_publishing: false - enable_normal_color: true # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. - - - #### Traversability filter ######## - use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. - weight_file: '/share/elevation_mapping_cupy/config/core/weights.dat' # Weight file for traversability filter - plugin_config_file: '/share/elevation_mapping_cupy/config/core/plugin_config.yaml' # Configuration file for the plugin. - #### Upper bound ######## - use_only_above_for_upper_bound: false - - #### Initializer ######## - initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' - initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. - initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. - dilation_size_initialize: 2 # dilation size after the init. - initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. - use_initializer_at_start: true # Use initializer when the node starts. - - #### Default Plugins ######## - - pointcloud_channel_fusions: - rgb: 'color' # 'color' fusion is used for the 'rgb' channel - default: 'average' # 'average' fusion is used for channels not listed here - - image_channel_fusions: - rgb: 'color' # 'color' fusion is used for the 'rgb' channel - default: 'exponential' # 'exponential' fusion is used for channels not listed here - feat_.*: 'exponential' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names - - #### Subscribers ######## - # pointcloud_sensor_name: - # topic_name: '/sensor/pointcloud_semantic' - # data_type: pointcloud # pointcloud or image - # - # image_sensor_name: - # topic_name: '/camera/image_semantic' - # data_type: image # pointcloud or image - # camera_info_topic_name: '/camera/depth/camera_info' - # channel_info_topic_name: '/camera/channel_info' - - - subscribers: - pointcloud1: - # topic_name: '/ouster/points' - topic_name: '/a200/sensors/camera_0/points' - data_type: 'pointcloud' - image1: - topic_name: '/feat_processing_node/semantic_seg_feat' - info_name: '/feat_processing_node/a200/sensors/camera_0/color/camera_info_resized' - channel_name: '/feat_processing_node/feat_channel_info' - data_type: 'image' - # image2: - # topic_name: '/a200/sensors/camera_0/color/image' - # info_name: '/a200/sensors/camera_0/color/camera_info' - # data_type: 'image' - # channel_name: '/front_cam/channel_info' - - # channel_name: '/front_cam/channel_info' - - # image_topic2: '/camera/rgb/image_raw2' - # image_info2: '/camera/depth/camera_info2' - # image_channel_info1: '/front_cam/channel_info' - - # image: # for semantic images - # topic_name: '/front_cam/semantic_image' - # camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' - # channel_info_topic_name: '/front_cam/channel_info' - # data_type: image - - #### Publishers ######## - # topic_name: - # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names - # basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. - # fps: # Publish rate. Use smaller value than `map_acquire_fps`. - - publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb', 'normal_x', 'normal_y', 'normal_z', 'feat_0','feat_1','feat_2','feat_3','feat_4'] - basic_layers: ['elevation'] - fps: 5.0 - elevation_map_recordable: - layers: ['elevation', 'traversability'] - basic_layers: ['elevation', 'traversability'] - fps: 2.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] - basic_layers: ['min_filter'] - fps: 3.0 - - - # plugun info - - min_filter: - enable: True # whether to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "min_filter" # The layer name. - extra_params: # These params are passed to the plugin class on initialization. - dilation_size: 1 # The patch size to apply - iteration_n: 30 # The number of iterations - - # Apply smoothing. - smooth_filter: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth" - extra_params: - input_layer_name: "min_filter" - - # Apply inpainting using opencv - inpainting: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "inpaint" - extra_params: - method: "telea" # telea or ns - - # Apply smoothing for inpainted layer - erosion: - enable: True - fill_nan: False - is_height_layer: False - layer_name: "erosion" - extra_params: - input_layer_name: "traversability" - dilation_size: 3 - iteration_n: 20 - reverse: True \ No newline at end of file diff --git a/elevation_mapping_cupy/config/core/core_param copy.yaml b/elevation_mapping_cupy/config/core/core_param copy.yaml deleted file mode 100644 index bf5f1cd4..00000000 --- a/elevation_mapping_cupy/config/core/core_param copy.yaml +++ /dev/null @@ -1,189 +0,0 @@ -elevation_mapping: - ros__parameters: - #### Basic parameters ######## - enable_normal_arrow_publishing: true - cell_n: 40000 # number of cells in the map. - data_type: 'float32' # data type for the map. - average_weight: 0.5 - drift_compensation_variance_inlier: 0.1 - checker_layer: 'traversability' # layer name for checking the validity of the cell. - min_filter_size: 5 # size of the filter for min filter. - min_filter_iteration: 3 # number of iterations for min filter. - initialized_variance: 10.0 # initial variance for each cell. - resolution: 0.1 # resolution in m. - map_length: 20.0 # map's size in m. - sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). - mahalanobis_thresh: 2.0 # points outside this distance is outlier. - outlier_variance: 0.01 # if point is outlier, add this value to the cell. - drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. - max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) - drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation - time_variance: 0.0001 # add this value when update_variance is called. - max_variance: 100.0 # maximum variance for each cell. - initial_variance: 1000.0 # initial variance for each cell. - traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. - dilation_size: 3 # dilation filter size before traversability filter. - wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. - min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. - position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. - orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. - position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. - orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. - min_valid_distance: 0.5 # points with shorter distance will be filtered out. - max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. - ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - update_variance_fps: 5.0 # fps for updating variance. - update_pose_fps: 10.0 # fps for updating pose and shift the center of map. - time_interval: 0.1 # Time layer is updated with this interval. - map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. - publish_statistics_fps: 1.0 # Publish statistics topic in this fps. - - max_ray_length: 10.0 # maximum length for ray tracing. - cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. - cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. - - safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. - safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. - max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. - - overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) - overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - pose_topic: '/odom' - map_frame: 'odom' # The map frame where the odometry source uses. - base_frame: 'base_link' # The robot's base frame. This frame will be a center of the map. - corrected_map_frame: 'odom' - - - - #### Feature toggles ######## - enable_edge_sharpen: true - enable_visibility_cleanup: true - enable_drift_compensation: true - enable_overlap_clearance: true - enable_pointcloud_publishing: false - enable_drift_corrected_TF_publishing: false - enable_normal_color: true # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. - - - #### Traversability filter ######## - use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. - weight_file: '/share/elevation_mapping_cupy/config/core/weights.dat' # Weight file for traversability filter - plugin_config_file: '/share/elevation_mapping_cupy/config/core/plugin_config.yaml' # Configuration file for the plugin. - #### Upper bound ######## - use_only_above_for_upper_bound: false - - #### Initializer ######## - initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' - initialize_frame_id: ['base_footprint'] # One tf (like ['footprint'] ) initializes a square around it. - initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. - dilation_size_initialize: 2 # dilation size after the init. - initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. - use_initializer_at_start: true # Use initializer when the node starts. - - #### Default Plugins ######## - - pointcloud_channel_fusions: - rgb: 'color' # 'color' fusion is used for the 'rgb' channel - default: 'average' # 'average' fusion is used for channels not listed here - - image_channel_fusions: - rgb: 'color' # 'color' fusion is used for the 'rgb' channel - default: 'exponential' # 'exponential' fusion is used for channels not listed here - feat_.*: 'exponential' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names - - #### Subscribers ######## - # pointcloud_sensor_name: - # topic_name: '/sensor/pointcloud_semantic' - # data_type: pointcloud # pointcloud or image - # - # image_sensor_name: - # topic_name: '/camera/image_semantic' - # data_type: image # pointcloud or image - # camera_info_topic_name: '/camera/depth/camera_info' - # channel_info_topic_name: '/camera/channel_info' - - - subscribers: - pointcloud1: - # topic_name: '/ouster/points' - topic_name: '/a200/sensors/camera_0/points' - data_type: 'pointcloud' - image1: - topic_name: '/a200/sensors/camera_0/color/image' - info_name: '/a200/sensors/camera_0/color/camera_info' - data_type: 'image' - # channel_name: '/front_cam/channel_info' - - # image_topic2: '/camera/rgb/image_raw2' - # image_info2: '/camera/depth/camera_info2' - # image_channel_info1: '/front_cam/channel_info' - - # image: # for semantic images - # topic_name: '/front_cam/semantic_image' - # camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' - # channel_info_topic_name: '/front_cam/channel_info' - # data_type: image - - #### Publishers ######## - # topic_name: - # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names - # basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. - # fps: # Publish rate. Use smaller value than `map_acquire_fps`. - - publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb', 'normal_x', 'normal_y', 'normal_z'] - basic_layers: ['elevation'] - fps: 5.0 - elevation_map_recordable: - layers: ['elevation', 'traversability'] - basic_layers: ['elevation', 'traversability'] - fps: 2.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] - basic_layers: ['min_filter'] - fps: 3.0 - - - # plugun info - - min_filter: - enable: True # whether to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "min_filter" # The layer name. - extra_params: # These params are passed to the plugin class on initialization. - dilation_size: 1 # The patch size to apply - iteration_n: 30 # The number of iterations - - # Apply smoothing. - smooth_filter: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth" - extra_params: - input_layer_name: "min_filter" - - # Apply inpainting using opencv - inpainting: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "inpaint" - extra_params: - method: "telea" # telea or ns - - # Apply smoothing for inpainted layer - erosion: - enable: True - fill_nan: False - is_height_layer: False - layer_name: "erosion" - extra_params: - input_layer_name: "traversability" - dilation_size: 3 - iteration_n: 20 - reverse: True \ No newline at end of file diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 667be92a..64b501bd 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -1,14 +1,12 @@ elevation_mapping_node: ros__parameters: #### Basic parameters ######## - # voxel_filter_size: 0.1 - # average_weight: 0.5 - # drift_compensation_variance_inlier: 0.1 - # checker_layer: 'elevation' # layer name for checking the validity of the cell. - # min_filter_size: 5 # size of the filter for min filter. - # min_filter_iteration: 3 # number of iterations for min filter. - # initialized_variance: 10.0 # initial variance for each cell. - resolution: 0.25 # resolution in m. + voxel_filter_size: 0.1 + average_weight: 0.5 + drift_compensation_variance_inlier: 0.1 + checker_layer: 'elevation' # layer name for checking the validity of the cell. + initialized_variance: 10.0 # initial variance for each cell. + resolution: 0.1 # resolution in m. map_length: 20.0 # map's size in m. sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). mahalanobis_thresh: 2.0 # points outside this distance is outlier. diff --git a/elevation_mapping_cupy/config/core/core_param_sim.yaml b/elevation_mapping_cupy/config/core/core_param_sim.yaml deleted file mode 100644 index acfedb86..00000000 --- a/elevation_mapping_cupy/config/core/core_param_sim.yaml +++ /dev/null @@ -1,197 +0,0 @@ -elevation_mapping: - ros__parameters: - #### Basic parameters ######## - voxel_filter_size: 0.05 - enable_normal_arrow_publishing: true - cell_n: 40000 # number of cells in the map. - data_type: 'float32' # data type for the map. - average_weight: 0.5 - drift_compensation_variance_inlier: 0.1 - checker_layer: 'traversability' # layer name for checking the validity of the cell. - min_filter_size: 5 # size of the filter for min filter. - min_filter_iteration: 3 # number of iterations for min filter. - initialized_variance: 10.0 # initial variance for each cell. - resolution: 0.1 # resolution in m. - map_length: 20.0 # map's size in m. - sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). - mahalanobis_thresh: 2.0 # points outside this distance is outlier. - outlier_variance: 0.01 # if point is outlier, add this value to the cell. - drift_compensation_variance_inler: 0.05 # cells under this value is used for drift compensation. - max_drift: 0.1 # drift compensation happens only the drift is smaller than this value (for safety) - drift_compensation_alpha: 0.1 # drift compensation alpha for smoother update of drift compensation - time_variance: 0.0001 # add this value when update_variance is called. - max_variance: 100.0 # maximum variance for each cell. - initial_variance: 1000.0 # initial variance for each cell. - traversability_inlier: 0.9 # cells with higher traversability are used for drift compensation. - dilation_size: 3 # dilation filter size before traversability filter. - wall_num_thresh: 20 # if there are more points than this value, only higher points than the current height are used to make the wall more sharp. - min_height_drift_cnt: 100 # drift compensation only happens if the valid cells are more than this number. - position_noise_thresh: 0.01 # if the position change is bigger than this value, the drift compensation happens. - orientation_noise_thresh: 0.01 # if the orientation change is bigger than this value, the drift compensation happens. - position_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. - orientation_lowpass_alpha: 0.2 # lowpass filter alpha used for detecting movements. - min_valid_distance: 0.5 # points with shorter distance will be filtered out. - max_height_range: 1.0 # points higher than this value from sensor will be filtered out to disable ceiling. - ramped_height_range_a: 0.3 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - ramped_height_range_b: 1.0 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - ramped_height_range_c: 0.2 # if z > max(d - ramped_height_range_b, 0) * ramped_height_range_a + ramped_height_range_c, reject. - update_variance_fps: 5.0 # fps for updating variance. - update_pose_fps: 10.0 # fps for updating pose and shift the center of map. - time_interval: 0.1 # Time layer is updated with this interval. - map_acquire_fps: 5.0 # Raw map is fetched from GPU memory in this fps. - publish_statistics_fps: 1.0 # Publish statistics topic in this fps. - - max_ray_length: 10.0 # maximum length for ray tracing. - cleanup_step: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. - cleanup_cos_thresh: 0.1 # subtitute this value from validity layer at visibiltiy cleanup. - - safe_thresh: 0.7 # if traversability is smaller, it is counted as unsafe cell. - safe_min_thresh: 0.4 # polygon is unsafe if there exists lower traversability than this. - max_unsafe_n: 10 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. - - overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) - overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - pose_topic: '/a200/robot/gt_odom' - map_frame: 'map' # The map frame where the odometry source uses. - base_frame: 'base_link' # The robot's base frame. This frame will be a center of the map. - corrected_map_frame: 'map_corrected' # The map frame where the drift corrected map is published. - - - - #### Feature toggles ######## - enable_edge_sharpen: true - enable_visibility_cleanup: true - enable_drift_compensation: true - enable_overlap_clearance: true - enable_pointcloud_publishing: false - enable_drift_corrected_TF_publishing: false - enable_normal_color: true # If true, the map contains 'color' layer corresponding to normal. Add 'color' layer to the publishers setting if you want to visualize. - - - #### Traversability filter ######## - use_chainer: false # Use chainer as a backend of traversability filter or pytorch. If false, it uses pytorch. pytorch requires ~2GB more GPU memory compared to chainer but runs faster. - weight_file: '/share/elevation_mapping_cupy/config/core/weights.dat' # Weight file for traversability filter - plugin_config_file: '/share/elevation_mapping_cupy/config/core/plugin_config.yaml' # Configuration file for the plugin. - #### Upper bound ######## - use_only_above_for_upper_bound: false - - #### Initializer ######## - initialize_method: 'linear' # Choose one from 'nearest', 'linear', 'cubic' - initialize_frame_id: ['base_link'] # One tf (like ['footprint'] ) initializes a square around it. - initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. - dilation_size_initialize: 2 # dilation size after the init. - initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. - use_initializer_at_start: true # Use initializer when the node starts. - - #### Default Plugins ######## - - pointcloud_channel_fusions: - rgb: 'color' # 'color' fusion is used for the 'rgb' channel - default: 'latest' # 'average' fusion is used for channels not listed here - - image_channel_fusions: - rgb: 'color' # 'color' fusion is used for the 'rgb' channel - default: 'latest' # 'exponential' fusion is used for channels not listed here - feat_.*: 'latest' # 'exponential' fusion is also used for any channel starting with 'feat_' Regular expressions can be used for channel names - - #### Subscribers ######## - # pointcloud_sensor_name: - # topic_name: '/sensor/pointcloud_semantic' - # data_type: pointcloud # pointcloud or image - # - # image_sensor_name: - # topic_name: '/camera/image_semantic' - # data_type: image # pointcloud or image - # camera_info_topic_name: '/camera/depth/camera_info' - # channel_info_topic_name: '/camera/channel_info' - - - subscribers: - pointcloud1: - # topic_name: '/ouster/points' - topic_name: '/a200/sensors/camera_0/points' - data_type: 'pointcloud' - image1: - topic_name: '/feat_processing_node/semantic_seg_feat' - info_name: '/feat_processing_node/a200/sensors/camera_0/color/camera_info_resized' - channel_name: '/feat_processing_node/feat_channel_info' - data_type: 'image' - # image2: - # topic_name: '/a200/sensors/camera_0/color/image' - # info_name: '/a200/sensors/camera_0/color/camera_info' - # data_type: 'image' - # channel_name: '/front_cam/channel_info' - - # channel_name: '/front_cam/channel_info' - - # image_topic2: '/camera/rgb/image_raw2' - # image_info2: '/camera/depth/camera_info2' - # image_channel_info1: '/front_cam/channel_info' - - # image: # for semantic images - # topic_name: '/front_cam/semantic_image' - # camera_info_topic_name: '/front_cam/camera/depth/camera_info_resized' - # channel_info_topic_name: '/front_cam/channel_info' - # data_type: image - - #### Publishers ######## - # topic_name: - # layers: # Choose from 'elevation', 'variance', 'traversability', 'time', 'normal_x', 'normal_y', 'normal_z', 'color', plugin_layer_names - # basic_layers: # basic_layers for valid cell computation (e.g. Rviz): Choose a subset of `layers`. - # fps: # Publish rate. Use smaller value than `map_acquire_fps`. - - publishers: - elevation_map_raw: - layers: ['elevation', 'traversability', 'variance','rgb', 'normal_x', 'normal_y', 'normal_z', 'feat_0','feat_1','feat_2','feat_3','feat_4'] - basic_layers: ['elevation'] - fps: 5.0 - elevation_map_recordable: - layers: ['elevation', 'traversability'] - basic_layers: ['elevation', 'traversability'] - fps: 2.0 - elevation_map_filter: - layers: ['min_filter', 'smooth', 'inpaint', 'elevation'] - basic_layers: ['min_filter'] - fps: 3.0 - - - # plugun info - - min_filter: - enable: True # whether to load this plugin - fill_nan: False # Fill nans to invalid cells of elevation layer. - is_height_layer: True # If this is a height layer (such as elevation) or not (such as traversability) - layer_name: "min_filter" # The layer name. - extra_params: # These params are passed to the plugin class on initialization. - dilation_size: 1 # The patch size to apply - iteration_n: 30 # The number of iterations - - # Apply smoothing. - smooth_filter: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "smooth" - extra_params: - input_layer_name: "min_filter" - - # Apply inpainting using opencv - inpainting: - enable: True - fill_nan: False - is_height_layer: True - layer_name: "inpaint" - extra_params: - method: "telea" # telea or ns - - # Apply smoothing for inpainted layer - erosion: - enable: True - fill_nan: False - is_height_layer: False - layer_name: "erosion" - extra_params: - input_layer_name: "traversability" - dilation_size: 3 - iteration_n: 20 - reverse: True \ No newline at end of file diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/parameter.py b/elevation_mapping_cupy/elevation_mapping_cupy/parameter.py index dea7e01e..059fbb4c 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/parameter.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/parameter.py @@ -84,10 +84,6 @@ class Parameter(Serializable): (Default: ``20``) checker_layer: Layer used for checking safety. (Default: ``"traversability"``) - min_filter_size: The minimum size for the filter. - (Default: ``5``) - min_filter_iteration: The minimum number of iterations for the filter. - (Default: ``3``) max_drift: The maximum drift for the compensation. (Default: ``0.10``) overlap_clear_range_xy: XY range [m] for clearing overlapped area. This defines the valid area for overlap clearance. (used for multi floor setting) @@ -193,9 +189,6 @@ class Parameter(Serializable): max_unsafe_n: int = 20 # if the number of cells under safe_thresh exceeds this value, polygon is unsafe. checker_layer: str = "traversability" # layer used for checking safety - min_filter_size: int = 5 # minimum size for the filter - min_filter_iteration: int = 3 # minimum number of iterations for the filter - max_drift: float = 0.10 # maximum drift for the compensation overlap_clear_range_xy: float = 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index aba48d1b..e5f766c8 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -233,9 +233,11 @@ ElevationMappingNode::ElevationMappingNode() auto unique_pub_names = extract_unique_names(publisher_params); + std::string node_name = this->get_name(); for (const auto& pub_name : unique_pub_names) { - std::string topic_name = pub_name; + // Namespacing published topics under node_name + std::string topic_name = node_name + "/" + pub_name; double fps; std::vector layers_list; std::vector basic_layers_list; From 02ad5b21e5c5f4c5bca106a6805a10084a1c093c Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Fri, 14 Feb 2025 16:41:39 -0600 Subject: [PATCH 482/504] added ability to launch python or cpp turtle example --- .../launch/elevation_mapping_turtle.launch.py | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py b/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py index ca5fda23..92ac9d72 100644 --- a/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py +++ b/elevation_mapping_cupy/launch/elevation_mapping_turtle.launch.py @@ -3,7 +3,8 @@ from launch_ros.actions import Node from ament_index_python.packages import get_package_share_directory from launch.actions import DeclareLaunchArgument -from launch.substitutions import LaunchConfiguration, PathJoinSubstitution +from launch.substitutions import LaunchConfiguration, PathJoinSubstitution, PythonExpression +from launch.conditions import IfCondition, UnlessCondition from launch_ros.descriptions import ParameterFile @@ -37,6 +38,13 @@ def generate_launch_description(): ) rviz_config = LaunchConfiguration('rviz_config') + use_python_node_arg = DeclareLaunchArgument( + 'use_python_node', + default_value='false', + description='Use the Python node if true' + ) + use_python_node = LaunchConfiguration('use_python_node') + # RViz Node rviz_node = Node( package='rviz2', @@ -46,6 +54,20 @@ def generate_launch_description(): parameters=[{'use_sim_time': use_sim_time}], output='screen' ) + elevation_mapping_node_py = Node( + package='elevation_mapping_cupy', + executable='elevation_mapping_node.py', + name='elevation_mapping_node', + output='screen', + parameters=[ + ParameterFile(core_param_path, allow_substs=True), + turtle_param_path, + {'use_sim_time': use_sim_time} + ], + condition=IfCondition(use_python_node) + # condition=IfCondition(PythonExpression(use_python_node)) + ) + elevation_mapping_node = Node( package='elevation_mapping_cupy', executable='elevation_mapping_node', @@ -55,12 +77,16 @@ def generate_launch_description(): ParameterFile(core_param_path, allow_substs=True), turtle_param_path, {'use_sim_time': use_sim_time} - ] - ) + ], + condition=UnlessCondition(use_python_node) + # condition=UnlessCondition(PythonExpression(use_python_node)) + ) return LaunchDescription([ use_sim_time_arg, rviz_config_arg, + use_python_node_arg, + elevation_mapping_node_py, elevation_mapping_node, rviz_node ]) From f737e8af6ae78452e5394ede61ad1952d5b4488f Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Fri, 14 Feb 2025 16:42:10 -0600 Subject: [PATCH 483/504] Made some changes to allow switching between ament_python and ament_cmake_python. Currently requires comment in and out parts of package.xml Idea is that if you don't want the cpp package you could just use the python one without building using cmake --- elevation_mapping_cupy/README.md | 4 ++-- .../elevation_mapping_cupy/elevation_mapping_node.py | 1 + elevation_mapping_cupy/package.xml | 9 ++++++++- elevation_mapping_cupy/resource/elevation_mapping_cupy | 0 elevation_mapping_cupy/setup.py | 3 ++- 5 files changed, 13 insertions(+), 4 deletions(-) create mode 120000 elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_node.py create mode 100644 elevation_mapping_cupy/resource/elevation_mapping_cupy diff --git a/elevation_mapping_cupy/README.md b/elevation_mapping_cupy/README.md index fe60536e..69d48e9d 100644 --- a/elevation_mapping_cupy/README.md +++ b/elevation_mapping_cupy/README.md @@ -32,7 +32,7 @@ Now launch the turtlebot3 in Gazebo with the following command: ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py ``` -Launch the elevation mapping node with the configs for the turtle: +Launch the elevation mapping node with the configs for the turtle. Set use_python_node to true to use it instead of the cpp node: ```bash -ros2 launch elevation_mapping_cupy elevation_mapping_turtle.launch.py +ros2 launch elevation_mapping_cupy elevation_mapping_turtle.launch.py use_python_node:=false ``` \ No newline at end of file diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_node.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_node.py new file mode 120000 index 00000000..e586b9ef --- /dev/null +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_node.py @@ -0,0 +1 @@ +/workspaces/reo-ws/src/mapping/elevation_mapping_cupy/elevation_mapping_cupy/scripts/elevation_mapping_node.py \ No newline at end of file diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index 3dd01595..f65efb19 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -6,11 +6,16 @@ Takahiro Miki MIT + ament_cmake ament_cmake_python + + + rclpy + rclcpp std_msgs std_srvs @@ -55,8 +60,10 @@ ament_lint_common - + ament_cmake + + \ No newline at end of file diff --git a/elevation_mapping_cupy/resource/elevation_mapping_cupy b/elevation_mapping_cupy/resource/elevation_mapping_cupy new file mode 100644 index 00000000..e69de29b diff --git a/elevation_mapping_cupy/setup.py b/elevation_mapping_cupy/setup.py index 493eef6c..6cd48a96 100644 --- a/elevation_mapping_cupy/setup.py +++ b/elevation_mapping_cupy/setup.py @@ -19,10 +19,11 @@ tests_require=['pytest'], entry_points={ 'console_scripts': [ - 'elevation_mapping_node = elevation_mapping_cupy.elevation_mapping_ros:main', + 'elevation_mapping_node.py = elevation_mapping_cupy.elevation_mapping_node:main', ], }, data_files=[ + ('share/ament_index/resource_index/packages',['resource/' + package_name]), (os.path.join('share', package_name, 'launch'), glob('launch/*.launch.py')), *[(os.path.join('share', package_name, os.path.dirname(yaml_file)), [yaml_file]) for yaml_file in glob('config/**/*.yaml', recursive=True)], # also the .*dat files From d29b1532506b15d47e7f04df93224aacdd94a88e Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Fri, 14 Feb 2025 16:43:49 -0600 Subject: [PATCH 484/504] Added instructions for testing with teleop --- elevation_mapping_cupy/README.md | 5 ++++ .../rviz/turtle_sim_laser.rviz | 29 ++++++++++--------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/elevation_mapping_cupy/README.md b/elevation_mapping_cupy/README.md index 69d48e9d..05509b58 100644 --- a/elevation_mapping_cupy/README.md +++ b/elevation_mapping_cupy/README.md @@ -35,4 +35,9 @@ ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py Launch the elevation mapping node with the configs for the turtle. Set use_python_node to true to use it instead of the cpp node: ```bash ros2 launch elevation_mapping_cupy elevation_mapping_turtle.launch.py use_python_node:=false +``` + +If you want to drive the turtlebot around using the keyboard then run: +```bash +ros2 run turtlebot3_teleop teleop_keyboard ``` \ No newline at end of file diff --git a/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz b/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz index 2b4ecd2f..8f247cfd 100644 --- a/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz +++ b/elevation_mapping_cupy/rviz/turtle_sim_laser.rviz @@ -7,7 +7,7 @@ Panels: - /Global Options1 - /Status1 Splitter Ratio: 0.5 - Tree Height: 551 + Tree Height: 336 - Class: rviz_common/Selection Name: Selection - Class: rviz_common/Tool Properties @@ -19,6 +19,7 @@ Panels: - Class: rviz_common/Views Expanded: - /Current View1 + - /Current View1/Focal Point1 Name: Views Splitter Ratio: 0.5 - Class: rviz_common/Time @@ -377,38 +378,38 @@ Visualization Manager: Value: true Views: Current: - Class: rviz_default_plugins/Orbit - Distance: 16.440555572509766 + Class: rviz_default_plugins/ThirdPersonFollower + Distance: 3.38887095451355 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 Swap Stereo Eyes: false Value: false Focal Point: - X: 1.3501025438308716 - Y: 2.9009647369384766 - Z: 0.35463666915893555 + X: -0.7572358250617981 + Y: -0.10913658142089844 + Z: -0.018636569380760193 Focal Shape Fixed Size: true Focal Shape Size: 0.05000000074505806 Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.6447965502738953 - Target Frame: - Value: Orbit (rviz) - Yaw: 2.8535845279693604 + Pitch: 0.6897954940795898 + Target Frame: base_link + Value: ThirdPersonFollower (rviz_default_plugins) + Yaw: 3.08858585357666 Saved: ~ Window Geometry: Camera: collapsed: false Displays: collapsed: false - Height: 1314 + Height: 954 Hide Left Dock: false Hide Right Dock: false Image: collapsed: false - QMainWindow State: 000000ff00000000fd00000004000000000000025f00000488fc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003b000002b0000000c700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000c00430061006d0065007200610000000136000000f70000002800fffffffb0000000a0049006d0061006700650000000157000000d60000002800fffffffb0000000a0049006d00610067006501000002f1000001d20000002800ffffff000000010000010f00000488fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003b00000488000000a000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e1000001970000000300000a000000003efc0100000002fb0000000800540069006d0065010000000000000a000000025300fffffffb0000000800540069006d00650100000000000004500000000000000000000006860000048800000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd00000004000000000000025f00000320fc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003b000001d9000000c700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000c00430061006d0065007200610000000136000000f70000002800fffffffb0000000a0049006d0061006700650000000157000000d60000002800fffffffb0000000a0049006d006100670065010000021a000001410000002800ffffff000000010000010f00000320fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003b00000320000000a000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007800000003efc0100000002fb0000000800540069006d00650100000000000007800000025300fffffffb0000000800540069006d00650100000000000004500000000000000000000004060000032000000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -417,6 +418,6 @@ Window Geometry: collapsed: false Views: collapsed: false - Width: 2560 - X: 0 + Width: 1920 + X: 1920 Y: 27 From 4c34b3aca1ed457c86f22c5df9c3f50173bb88a3 Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Fri, 14 Feb 2025 16:48:54 -0600 Subject: [PATCH 485/504] WIP updating docker --- .devcontainer/devcontainer.json | 70 +++++++++ docker/Dockerfile.x64 | 254 ++++++++++++++++++++++++++------ docker/setup.sh | 7 + docker/src.repos | 15 ++ 4 files changed, 300 insertions(+), 46 deletions(-) create mode 100644 .devcontainer/devcontainer.json create mode 100755 docker/setup.sh create mode 100644 docker/src.repos diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..5b0d02a1 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,70 @@ +// See https://aka.ms/vscode-remote/devcontainer.json for format details. +{ + "name": "Demo Elevation Mapping CUPY Workspace", + "dockerFile": "../docker/Dockerfile.x64", + "context": "../", + "remoteUser": "ros", + "runArgs": [ + "--network=host", + "--cap-add=SYS_PTRACE", + "--cap-add=SYS_NICE", + "--security-opt=seccomp:unconfined", + "--security-opt=apparmor:unconfined", + // "--volume=/tmp/.X11-unix:/tmp/.X11-unix", + "--volume=/mnt/wslg:/mnt/wslg", + "--ipc=host", + "--pid=host", + "--runtime=nvidia", + "--gpus=all", + "--privileged", + "--ulimit=rtprio=98", + "--ulimit=rttime=-1", + "--ulimit=memlock=8428281856", + "--name=emcupy-ros2-devcontainer" + ], + "containerEnv": { + "DISPLAY": "${localEnv:DISPLAY}", // Needed for GUI try ":0" for windows + "WAYLAND_DISPLAY": "${localEnv:WAYLAND_DISPLAY}", + "XDG_RUNTIME_DIR": "${localEnv:XDG_RUNTIME_DIR}", + "PULSE_SERVER": "${localEnv:PULSE_SERVER}", + "LIBGL_ALWAYS_SOFTWARE": "1" // Needed for software rendering of opengl + }, + "mounts": [ + "source=/dev,target=/dev,type=bind,consistency=cached" + // "source=~/bag_files,target=/workspaces/vscode-container-workspace/bag_files,type=bind,consistency=cached" + ], + "customizations": { + "vscode": { + "settings": { + "remote.autoForwardPorts": false, + "remote.autoForwardPortsSource": "output", + "otherPortsAttributes": { "onAutoForward" : "ignore" } + }, + "extensions": [ + "althack.ament-task-provider", + "betwo.b2-catkin-tools", + "DotJoshJohnson.xml", + "ms-azuretools.vscode-docker", + "ms-vscode.cmake-tools", + "ms-python.python", + "ms-vscode.cpptools", + "redhat.vscode-yaml", + "smilerobotics.urdf", + "streetsidesoftware.code-spell-checker", + "twxs.cmake", + "yzhang.markdown-all-in-one", + "zachflower.uncrustify", + "mhutchie.git-graph", + "eamodio.gitlens", + "ms-vscode.cpptools-extension-pack", + "usernamehw.errorlens", + "ms-iot.vscode-ros", + "alefragnani.Bookmarks", + "ms-vscode.live-server" + + ] + } + }, + "workspaceMount": "source=${localWorkspaceFolder}/../,target=/workspace/src,type=bind", + "workspaceFolder": "/workspace/src" +} \ No newline at end of file diff --git a/docker/Dockerfile.x64 b/docker/Dockerfile.x64 index 26bb85f4..af9a74d4 100644 --- a/docker/Dockerfile.x64 +++ b/docker/Dockerfile.x64 @@ -1,46 +1,208 @@ -FROM nvidia/cuda:11.6.2-cudnn8-devel-ubuntu20.04 - -# Set noninteractive mode for apt-get -ENV DEBIAN_FRONTEND=noninteractive - -# Preconfigure tzdata -RUN echo "Etc/UTC" > /etc/timezone && \ - ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime && \ - apt-get update && apt-get install -y tzdata && \ - dpkg-reconfigure --frontend noninteractive tzdata - -# Install Python -RUN apt-get update && apt-get install -y \ - python3.8 \ - python3-pip \ - git - -# Install PyTorch -COPY requirements.txt /tmp/requirements.txt -RUN pip3 install -r /tmp/requirements.txt -RUN pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 - -# Install other Python packages -RUN pip3 install cupy-cuda11x scikit-learn -RUN pip3 install 'git+https://github.com/facebookresearch/detectron2.git' - -# Install ROS -RUN apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 -RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu focal main" > /etc/apt/sources.list.d/ros-latest.list' - -RUN apt-get update && apt-get install -y --no-install-recommends \ - ros-noetic-desktop-full - -# Install ROS packages -RUN apt install -y ros-noetic-pybind11-catkin \ - ros-noetic-grid-map-core ros-noetic-grid-map-msgs ros-noetic-grid-map-ros ros-noetic-grid-map-rviz-plugin \ - libopencv-dev \ - libeigen3-dev \ - libgmp-dev \ - libmpfr-dev \ - libboost-all-dev \ - ros-noetic-turtlebot3-gazebo ros-noetic-turtlebot3-teleop \ - ros-noetic-ros-numpy - -RUN pip3 install catkin-tools -ENV TURTLEBOT3_MODEL=waffle \ No newline at end of file +# syntax=docker/dockerfile:1.4 + +# Base image +FROM nvidia/cuda:12.1.1-cudnn8-devel-ubuntu22.04 AS base + +# Metadata +LABEL description="ROS2 environment with CUDA support" +LABEL version="1.0" + +# Build arguments +ARG ROS_DISTRO=humble +ARG USERNAME=ros +ARG USER_UID=1000 +ARG USER_GID=$USER_UID +ARG RMW_NAME=zenoh + +# Environment variables +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=en_US.UTF-8 \ + LC_ALL=${LANG}\ + TZ=UTC \ + PYTHONUNBUFFERED=1 \ + ROS_DISTRO=${ROS_DISTRO} \ + ROS_ROOT=/opt/ros/${ROS_DISTRO} \ + AMENT_PREFIX_PATH=/opt/ros/${ROS_DISTRO} \ + COLCON_PREFIX_PATH=/opt/ros/${ROS_DISTRO} \ + LD_LIBRARY_PATH=/opt/ros/${ROS_DISTRO}/lib:/usr/local/cuda/lib64 \ + PATH=/opt/ros/${ROS_DISTRO}/bin:/usr/src/tensorrt/bin:/usr/local/cuda/bin:$PATH \ + PYTHONPATH=/opt/ros/${ROS_DISTRO}/lib/python3.10/site-packages \ + # Used by various ROS2 packages + RMW_IMPLEMENTATION=rmw_${RMW_NAME}_cpp \ + # Should be the same as above but with dashes instead of underscores + RMW_IMPLEMENTATION_DASH=rmw-${RMW_NAME}-cpp + +# Install basic utilities and dependencies +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + apt update && apt install -y --no-install-recommends \ + locales \ + tzdata \ + curl \ + gnupg2 \ + lsb-release \ + sudo \ + software-properties-common \ + wget \ + git \ + git-lfs \ + nano \ + && locale-gen ${LANG} \ + && update-locale LC_ALL=${LC_ALL} LANG=${LANG}\ + && ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime \ + && dpkg-reconfigure -f ${DEBIAN_FRONTEND} tzdata \ + && apt clean \ + && rm -rf /var/lib/apt/lists/* + +# Install ROS2 +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null \ + && apt update && apt install -y --no-install-recommends \ + ros-${ROS_DISTRO}-ros-base \ + python3-argcomplete \ + ros-${ROS_DISTRO}-${RMW_IMPLEMENTATION_DASH} \ + && apt clean \ + && rm -rf /var/lib/apt/lists/* + +# Development stage +FROM base AS dev + +# Install development tools and dependencies +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + apt update && apt install -y --no-install-recommends \ + bash-completion \ + build-essential \ + cmake \ + gdb \ + openssh-client \ + python3-pip \ + vim \ + doxygen \ + graphviz \ + python3-sphinx \ + python3-breathe \ + ros-dev-tools \ + ros-${ROS_DISTRO}-ament-* \ + python3-rosdep \ + libxine2-dev \ + libtiff5-dev \ + libpostproc-dev \ + libopencv-dev \ + && apt clean \ + && rm -rf /var/lib/apt/lists/* + +# Initialize rosdep +RUN rosdep init && rosdep update + +# Pytorch +# Used by elevation_mapping_cupy +RUN python3 -m pip install -U --extra-index-url https://download.pytorch.org/whl/cu121 \ + torch \ + torchvision \ + torchaudio + +# Install Python packages +RUN python3 -m pip install \ + # colcon extension to enable easier workspace cleaning + colcon-clean\ + # Almost all ros2 packages + rosdoc2\ + # sphinx is used across packages for documentation + sphinx_rtd_theme \ + sphinx-multiversion \ + sphinx-copybutton\ + sphinx-tabs\ + # For VS Code python code formatting I think? + autopep8\ + # Used by multiple packages for linting I think? + flake8-builtins\ + flake8-comprehensions\ + flake8-docstrings\ + flake8-import-order\ + flake8-class-newline\ + flake8-blind-except\ + flake8-quotes\ + # For Python code formatting. Not sure what package uses it + # black==21.12b0\ + #### For elevation_mapping_cupy #### + ruamel.yaml\ + scikit-learn\ + shapely\ + opencv-python\ + cupy-cuda12x\ + scipy\ + simple-parsing\ + "numpy<2.0.0" + +# Needed for elevation_mapping_cupy to not have run-time errors +RUN python3 -m pip install transforms3d -U + +# Set up non-root user +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \ + && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ + && chmod 0440 /etc/sudoers.d/$USERNAME + +# Set up autocompletion and source ROS environment for user +RUN echo "source /opt/ros/${ROS_DISTRO}/setup.bash" >> /home/$USERNAME/.bashrc \ + && echo "source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash" >> /home/$USERNAME/.bashrc + +# For building GPU supported containers? +# Install NVIDIA Container Toolkit +RUN distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \ + && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \ + && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list \ + && apt update && apt install -y nvidia-container-toolkit \ + && apt clean \ + && rm -rf /var/lib/apt/lists/* + +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + apt update && apt install -y --no-install-recommends \ + # For elevation_mapping_cupy + libboost-all-dev\ + && apt clean && \ + rm -rf /var/lib/apt/lists/* + +RUN apt update && \ + DEBIAN_FRONTEND=${DEBIAN_FRONTEND} apt install -y \ + #### For elevation_mapping_cupy #### + ros-${ROS_DISTRO}-grid-map-msgs\ + ros-${ROS_DISTRO}-grid-map-ros\ + ros-${ROS_DISTRO}-image-transport\ + ros-${ROS_DISTRO}-pcl-ros\ + ros-${ROS_DISTRO}-cv-bridge\ + ros-${ROS_DISTRO}-tf-transformations\ + ros-${ROS_DISTRO}-rviz2\ + ros-${ROS_DISTRO}-gazebo-ros\ + ros-${ROS_DISTRO}-grid-map-cv\ + ros-${ROS_DISTRO}-grid-map-core\ + ros-${ROS_DISTRO}-grid-map-demos\ + ################################## + #### For debugging elevation_mapping_cupy by setting up turtlebot3_simulations#### + # ros-${ROS_DISTRO}-turtlebot3*\ + ros-${ROS_DISTRO}-camera-calibration-parsers\ + ros-${ROS_DISTRO}-camera-info-manager\ + ros-${ROS_DISTRO}-gazebo-plugins\ + ros-${ROS_DISTRO}-turtlebot3-msgs\ + ros-${ROS_DISTRO}-turtlebot3-teleop\ + ros-${ROS_DISTRO}-gazebo-ros-pkgs\ + ############################################## + && apt clean && \ + rm -rf /var/lib/apt/lists/* + + +# Switch to non-root user +USER $USERNAME + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD ros2 topic list > /dev/null 2>&1 || exit 1 + +# Set ID to value not used by others on your network +ENV ROS_DOMAIN_ID=12 + +# For elevation_mapping_cupy +ENV TURTLEBOT3_MODEL=waffle_realsense_depth + +# Set the default command to bash +CMD ["bash"] \ No newline at end of file diff --git a/docker/setup.sh b/docker/setup.sh new file mode 100755 index 00000000..00e2955f --- /dev/null +++ b/docker/setup.sh @@ -0,0 +1,7 @@ +#!/bin/bash +cd /workspace +vcs import < src/elevation_mapping_cupy/docker/src.repos src/ --recursive -w $(($(nproc)/2)) + +sudo apt update +rosdep update +rosdep install --from-paths src --ignore-src -y -r \ No newline at end of file diff --git a/docker/src.repos b/docker/src.repos new file mode 100644 index 00000000..b0d9f6c3 --- /dev/null +++ b/docker/src.repos @@ -0,0 +1,15 @@ +repositories: + # elevation_mapping_cupy: + # type: git + # url: https://github.com/jwag/elevation_mapping_cupy.git + # version: ros2_humble + # ros2_numpy needed by elevation_mapping_cupy + ros2_numpy: + type: git + url: https://github.com/Box-Robotics/ros2_numpy.git + version: humble + # added for testing elevation_mapping_cupy + turtlebot3_simulations: + type: git + url: https://github.com/jwag/turtlebot3_simulations.git + version: humble_realsense_depth From 56d6fd380b4cd53afb4c48faf68a1ec0910c9edb Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Fri, 14 Feb 2025 23:33:43 +0000 Subject: [PATCH 486/504] Got running with cpp version. still needs work, but somewhat functional --- .../config/core/core_param.yaml | 2 +- .../elevation_mapping_ros.hpp | 2 +- .../src/elevation_mapping_node.cpp | 7 +- .../src/elevation_mapping_ros.cpp | 9 +- .../src/elevation_mapping_wrapper.cpp | 96 +++++++++---------- 5 files changed, 60 insertions(+), 56 deletions(-) diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 64b501bd..5f01ceed 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -75,7 +75,7 @@ elevation_mapping_node: initialize_frame_id: ['base_link'] # One tf (like ['footprint'] ) initializes a square around it. initialize_tf_offset: [0.0, 0.0, 0.0, 0.0] # z direction. Should be same number as initialize_frame_id. dilation_size_initialize: 2 # dilation size after the init. - initialize_tf_grid_size: 0.5 # This is not used if number of tf is more than 3. + initialize_tf_grid_size: 1.0 # This is not used if number of tf is more than 3. use_initializer_at_start: true # Use initializer when the node starts. #### Default Plugins ######## diff --git a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp index 4dc658fd..ebdd016e 100644 --- a/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp +++ b/elevation_mapping_cupy/include/elevation_mapping_cupy/elevation_mapping_ros.hpp @@ -68,7 +68,7 @@ namespace elevation_mapping_cupy { class ElevationMappingNode : public rclcpp::Node { public: - ElevationMappingNode(); + ElevationMappingNode(const rclcpp::NodeOptions& options); using RowMatrixXd = Eigen::Matrix; using ColMatrixXf = Eigen::Matrix; diff --git a/elevation_mapping_cupy/src/elevation_mapping_node.cpp b/elevation_mapping_cupy/src/elevation_mapping_node.cpp index ca70b5db..131e25cc 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_node.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_node.cpp @@ -12,9 +12,14 @@ int main(int argc, char** argv) { rclcpp::init(argc, argv); + + // Allow declaring parameters from the yaml files + rclcpp::NodeOptions options; + options.automatically_declare_parameters_from_overrides(true); + options.allow_undeclared_parameters(true); py::scoped_interpreter guard{}; // start the interpreter and keep it alive - auto mapNode = std::make_shared(); // Correct instantiation + auto mapNode = std::make_shared(options); py::gil_scoped_release release; diff --git a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp index e5f766c8..9d18dc4e 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_ros.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_ros.cpp @@ -22,9 +22,8 @@ namespace elevation_mapping_cupy { - -ElevationMappingNode::ElevationMappingNode() - : rclcpp::Node("elevation_mapping_node", rclcpp::NodeOptions().automatically_declare_parameters_from_overrides(true)), +ElevationMappingNode::ElevationMappingNode(const rclcpp::NodeOptions& options) + : Node("elevation_mapping_node", options), node_(std::shared_ptr(this, [](auto *) {})), // it_(node_), lowpassPosition_(0, 0, 0), @@ -35,7 +34,8 @@ ElevationMappingNode::ElevationMappingNode() orientationAlpha_(0.1), enablePointCloudPublishing_(false), isGridmapUpdated_(false){ - RCLCPP_INFO(this->get_logger(), "Initializing ElevationMappingNode..."); + + RCLCPP_INFO(this->get_logger(), "Initializing ElevationMappingNode..."); tfBroadcaster_ = std::make_shared(*this);// ROS2构造TransformBroadcaster tfBuffer_ = std::make_shared(this->get_clock()); @@ -93,6 +93,7 @@ ElevationMappingNode::ElevationMappingNode() RCLCPP_INFO(this->get_logger(), "enable_drift_corrected_TF_publishing: %s", enableDriftCorrectedTFPublishing_ ? "true" : "false"); RCLCPP_INFO(this->get_logger(), "use_initializer_at_start: %s", useInitializerAtStart_ ? "true" : "false"); RCLCPP_INFO(this->get_logger(), "always_clear_with_initializer: %s", alwaysClearWithInitializer_ ? "true" : "false"); + RCLCPP_INFO(this->get_logger(), "voxel_filter_size: %f", voxel_filter_size_); enablePointCloudPublishing_ = enablePointCloudPublishing; diff --git a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp index a90fae93..93beb0b4 100644 --- a/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp +++ b/elevation_mapping_cupy/src/elevation_mapping_wrapper.cpp @@ -46,11 +46,6 @@ void ElevationMappingWrapper::initialize(const std::shared_ptr& no auto threading = py::module::import("threading"); py::gil_scoped_acquire acquire; - auto sys = py::module::import("sys"); - auto path = sys.attr("path"); - std::string module_path = ament_index_cpp::get_package_share_directory("elevation_mapping_cupy"); - module_path = module_path + "/script"; - path.attr("insert")(0, module_path); auto elevation_mapping = py::module::import("elevation_mapping_cupy.elevation_mapping"); auto parameter = py::module::import("elevation_mapping_cupy.parameter"); @@ -117,45 +112,45 @@ void ElevationMappingWrapper::setParameters() { } } + + py::dict sub_dict; + // rclcpp::Parameter subscribers; + std::vector parameter_prefixes; + auto parameters = node_->list_parameters(parameter_prefixes, 2); // List all parameters with a maximum depth of 10 - py::dict sub_dict; - // rclcpp::Parameter subscribers; - std::vector parameter_prefixes; - auto parameters = node_->list_parameters(parameter_prefixes, 2); // List all parameters with a maximum depth of 10 - - - std::map subscriber_params; - if (!node_->get_parameters("subscribers", subscriber_params)) { - RCLCPP_FATAL(node_->get_logger(), "There aren't any subscribers to be configured, the elevation mapping cannot be configured. Exit"); - rclcpp::shutdown(); - } - auto unique_sub_names = extract_unique_names(subscriber_params); - for (const auto& name : unique_sub_names) { - const char* const name_c = name.c_str(); - if (!sub_dict.contains(name_c)) { - sub_dict[name_c] = py::dict(); - } - std::string topic_name; - if(node_->get_parameter("subscribers." + name + ".topic_name", topic_name)){ - const char* topic_name_cstr = "topic_name"; - sub_dict[name_c][topic_name_cstr] = static_cast(topic_name); - std::string data_type; - if(node_->get_parameter("subscribers." + name + ".data_type", data_type)){ - const char* data_type_cstr = "data_type"; - sub_dict[name_c][data_type_cstr] = static_cast(data_type); - } - std::string info_name; - if(node_->get_parameter("subscribers." + name + ".data_type", info_name)){ - const char* info_name_cstr = "info_name"; - sub_dict[name_c][info_name_cstr] = static_cast(info_name); - } - std::string channel_name; - if(node_->get_parameter("subscribers." + name + ".data_type", channel_name)){ - const char* channel_name_cstr = "channel_name"; - sub_dict[name_c][channel_name_cstr] = static_cast(channel_name); + + std::map subscriber_params; + if (!node_->get_parameters("subscribers", subscriber_params)) { + RCLCPP_FATAL(node_->get_logger(), "There aren't any subscribers to be configured, the elevation mapping cannot be configured. Exit"); + rclcpp::shutdown(); + } + auto unique_sub_names = extract_unique_names(subscriber_params); + for (const auto& name : unique_sub_names) { + const char* const name_c = name.c_str(); + if (!sub_dict.contains(name_c)) { + sub_dict[name_c] = py::dict(); } - } + std::string topic_name; + if(node_->get_parameter("subscribers." + name + ".topic_name", topic_name)){ + const char* topic_name_cstr = "topic_name"; + sub_dict[name_c][topic_name_cstr] = static_cast(topic_name); + std::string data_type; + if(node_->get_parameter("subscribers." + name + ".data_type", data_type)){ + const char* data_type_cstr = "data_type"; + sub_dict[name_c][data_type_cstr] = static_cast(data_type); + } + std::string info_name; + if(node_->get_parameter("subscribers." + name + ".data_type", info_name)){ + const char* info_name_cstr = "info_name"; + sub_dict[name_c][info_name_cstr] = static_cast(info_name); + } + std::string channel_name; + if(node_->get_parameter("subscribers." + name + ".data_type", channel_name)){ + const char* channel_name_cstr = "channel_name"; + sub_dict[name_c][channel_name_cstr] = static_cast(channel_name); + } } + } @@ -199,14 +194,17 @@ void ElevationMappingWrapper::setParameters() { } - param_.attr("update")(); - resolution_ = py::cast(param_.attr("get_value")("resolution")); - map_length_ = py::cast(param_.attr("get_value")("true_map_length")); - map_n_ = py::cast(param_.attr("get_value")("true_cell_n")); - - - - enable_normal_color_ = node_->get_parameter("enable_normal_color").as_bool(); + // Update the cell_n parameters based on the map length and resolution + RCLCPP_INFO(node_->get_logger(), "Updating cell_n parameters based on map length and resolution"); + param_.attr("update")(); + resolution_ = py::cast(param_.attr("get_value")("resolution")); + map_length_ = py::cast(param_.attr("get_value")("true_map_length")); + map_n_ = py::cast(param_.attr("get_value")("true_cell_n")); + RCLCPP_INFO(node_->get_logger(), "cell_n: %d", map_n_); + RCLCPP_INFO(node_->get_logger(), "resolution: %f", resolution_); + RCLCPP_INFO(node_->get_logger(), "true_map_length: %f", map_length_); + + enable_normal_color_ = node_->get_parameter("enable_normal_color").as_bool(); } From cda0a096848015c80d12369fbdcae1da3fe30a8d Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Sat, 15 Feb 2025 20:21:48 +0000 Subject: [PATCH 487/504] Fixing up dev container and adding build script Still debugging issue with ament_python_install_package() --- .devcontainer/devcontainer.json | 6 +++--- docker/Dockerfile.x64 | 10 ++++++++++ docker/build.sh | 25 ++++++++++++++++++++++--- docker/setup.sh | 2 +- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 5b0d02a1..cf7fa5b6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -61,10 +61,10 @@ "ms-iot.vscode-ros", "alefragnani.Bookmarks", "ms-vscode.live-server" - + ] } }, - "workspaceMount": "source=${localWorkspaceFolder}/../,target=/workspace/src,type=bind", - "workspaceFolder": "/workspace/src" + "workspaceMount": "source=${localWorkspaceFolder}/,target=/home/ros/workspace/src/elevation_mapping_cupy/,type=bind", + "workspaceFolder": "/home/ros/workspace/src/elevation_mapping_cupy/" } \ No newline at end of file diff --git a/docker/Dockerfile.x64 b/docker/Dockerfile.x64 index af9a74d4..42f99c08 100644 --- a/docker/Dockerfile.x64 +++ b/docker/Dockerfile.x64 @@ -190,7 +190,17 @@ RUN apt update && \ && apt clean && \ rm -rf /var/lib/apt/lists/* +# Development stage +FROM dev as dev2 +ARG WORKSPACE="/home/ros/workspace" + +# Print workspace to terminal +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + echo "Workspace: ${WORKSPACE}" +RUN mkdir -p ${WORKSPACE}/src/elevation_mapping_cupy && chown -R ${USER_UID}:${USER_GID} /home/${USERNAME} +RUN echo "if [ -f ${WORKSPACE}/install/setup.bash ]; then source ${WORKSPACE}/install/setup.bash; fi" >> /home/ros/.bashrc +WORKDIR ${WORKSPACE} # Switch to non-root user USER $USERNAME diff --git a/docker/build.sh b/docker/build.sh index 1d92a220..6d67ad53 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -1,3 +1,22 @@ -#! /bin/bash -home=`realpath "$(dirname "$0")"/../` -cd $home && sudo docker build -t elevation_mapping_cupy -f docker/Dockerfile.x64 --no-cache . \ No newline at end of file +#!/bin/bash +set -e +cd ~/workspace +# Set the default build type +source /opt/ros/$ROS_DISTRO/setup.bash +BUILD_TYPE=RelWithDebInfo #Debug, Release, RelWithDebInfo, MinSizeRel +colcon build \ + --continue-on-error \ + --parallel-workers $(nproc) \ + --merge-install \ + --symlink-install \ + --event-handlers console_cohesion+ \ + --base-paths src \ + --cmake-args \ + "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" \ + "-DCMAKE_EXPORT_COMPILE_COMMANDS=On" \ + "-DBUILD_TESTING=OFF"\ + "-DCMAKE_CXX_FLAGS="-Wl,--allow-shlib-undefined""\ + -Wall -Wextra -Wpedantic -Wshadow \ + --packages-skip \ + convex_plane_decomposition \ + convex_plane_decomposition_ros \ No newline at end of file diff --git a/docker/setup.sh b/docker/setup.sh index 00e2955f..128e53bc 100755 --- a/docker/setup.sh +++ b/docker/setup.sh @@ -1,5 +1,5 @@ #!/bin/bash -cd /workspace +cd ~/workspace vcs import < src/elevation_mapping_cupy/docker/src.repos src/ --recursive -w $(($(nproc)/2)) sudo apt update From 6f970b895447b2d83d90d5758854e8d30baf1b4a Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Sat, 15 Feb 2025 20:33:06 +0000 Subject: [PATCH 488/504] Fixed broken symbolic link Builds now --- .../elevation_mapping_cupy/elevation_mapping_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_node.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_node.py index e586b9ef..4740ecba 120000 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_node.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_node.py @@ -1 +1 @@ -/workspaces/reo-ws/src/mapping/elevation_mapping_cupy/elevation_mapping_cupy/scripts/elevation_mapping_node.py \ No newline at end of file +../scripts/elevation_mapping_node.py \ No newline at end of file From 3f60953fa0e1963c8b37c9dd3b6133c9792c06cb Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Sat, 15 Feb 2025 17:37:13 -0600 Subject: [PATCH 489/504] WIP fixing up package.xml --- docker/Dockerfile.x64 | 88 ++++++++++++++++-------------- docker/extra_rosdeps.yaml | 12 ++++ elevation_mapping_cupy/package.xml | 28 +++++++--- 3 files changed, 78 insertions(+), 50 deletions(-) create mode 100644 docker/extra_rosdeps.yaml diff --git a/docker/Dockerfile.x64 b/docker/Dockerfile.x64 index 42f99c08..e3d92fda 100644 --- a/docker/Dockerfile.x64 +++ b/docker/Dockerfile.x64 @@ -95,7 +95,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ RUN rosdep init && rosdep update # Pytorch -# Used by elevation_mapping_cupy +# Used by elevation_mapping_cupy and not rosdep resolvable for cuda version RUN python3 -m pip install -U --extra-index-url https://download.pytorch.org/whl/cu121 \ torch \ torchvision \ @@ -121,21 +121,21 @@ RUN python3 -m pip install \ flake8-import-order\ flake8-class-newline\ flake8-blind-except\ - flake8-quotes\ + flake8-quotes # For Python code formatting. Not sure what package uses it # black==21.12b0\ #### For elevation_mapping_cupy #### - ruamel.yaml\ - scikit-learn\ - shapely\ - opencv-python\ - cupy-cuda12x\ - scipy\ - simple-parsing\ - "numpy<2.0.0" + # ruamel.yaml\ # replacing with apt python-ruamel.yaml + # scikit-learn\ # replacing with apt python3-sklearn - might not be needeed + # shapely\ # replacing with apt python3-shapely + # opencv-python\ # replacing with apt installed python3-opencv + # cupy-cuda12x\ # extra rosdeps + # scipy\ # apt install scipy instead + # simple-parsing\ # extra rosdeps + # "numpy<2.0.0" # extra rosdeps # Needed for elevation_mapping_cupy to not have run-time errors -RUN python3 -m pip install transforms3d -U +# RUN python3 -m pip install transforms3d -U # Replacing with rosdep python3-transforms3d # Set up non-root user RUN groupadd --gid $USER_GID $USERNAME \ @@ -156,51 +156,57 @@ RUN distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \ && apt clean \ && rm -rf /var/lib/apt/lists/* -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ - apt update && apt install -y --no-install-recommends \ +# RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ +# apt update && apt install -y --no-install-recommends \ # For elevation_mapping_cupy - libboost-all-dev\ - && apt clean && \ - rm -rf /var/lib/apt/lists/* + # libboost-all-dev\ # resolved by rosdep as boost + # && apt clean && \ + # rm -rf /var/lib/apt/lists/* -RUN apt update && \ - DEBIAN_FRONTEND=${DEBIAN_FRONTEND} apt install -y \ +# RUN apt update && \ + # DEBIAN_FRONTEND=${DEBIAN_FRONTEND} apt install -y \ #### For elevation_mapping_cupy #### - ros-${ROS_DISTRO}-grid-map-msgs\ - ros-${ROS_DISTRO}-grid-map-ros\ - ros-${ROS_DISTRO}-image-transport\ - ros-${ROS_DISTRO}-pcl-ros\ - ros-${ROS_DISTRO}-cv-bridge\ - ros-${ROS_DISTRO}-tf-transformations\ - ros-${ROS_DISTRO}-rviz2\ - ros-${ROS_DISTRO}-gazebo-ros\ - ros-${ROS_DISTRO}-grid-map-cv\ - ros-${ROS_DISTRO}-grid-map-core\ - ros-${ROS_DISTRO}-grid-map-demos\ + # ros-${ROS_DISTRO}-grid-map-msgs\ # rosdep grid_map_msgs + # ros-${ROS_DISTRO}-grid-map-ros\ # rosdep grid_map_ros + # ros-${ROS_DISTRO}-image-transport\ # rosdep image_transport + # ros-${ROS_DISTRO}-pcl-ros\# rosdep pcl_ros + # ros-${ROS_DISTRO}-cv-bridge\ # rosdep cv_bridge + # ros-${ROS_DISTRO}-tf-transformations\ # rosdep tf-transformations + # ros-${ROS_DISTRO}-rviz2\ # rosdep rviz2 + # ros-${ROS_DISTRO}-gazebo-ros\ # replacing with rosdep gazebo_ros_pkgs + # ros-${ROS_DISTRO}-grid-map-cv\ # rosdep grid_map_cv + # ros-${ROS_DISTRO}-grid-map-core\ # rosdep grid_map_core + # ros-${ROS_DISTRO}-grid-map-demos\ # rosdep grid_map_demos ################################## #### For debugging elevation_mapping_cupy by setting up turtlebot3_simulations#### # ros-${ROS_DISTRO}-turtlebot3*\ - ros-${ROS_DISTRO}-camera-calibration-parsers\ - ros-${ROS_DISTRO}-camera-info-manager\ - ros-${ROS_DISTRO}-gazebo-plugins\ - ros-${ROS_DISTRO}-turtlebot3-msgs\ - ros-${ROS_DISTRO}-turtlebot3-teleop\ - ros-${ROS_DISTRO}-gazebo-ros-pkgs\ + # ros-${ROS_DISTRO}-camera-calibration-parsers\ + # ros-${ROS_DISTRO}-camera-info-manager\ + # ros-${ROS_DISTRO}-gazebo-plugins\ + # ros-${ROS_DISTRO}-turtlebot3-msgs\ + # ros-${ROS_DISTRO}-turtlebot3-teleop\ + # ros-${ROS_DISTRO}-gazebo-ros-pkgs\ # replacing with rosdep gazebo_ros_pkgs ############################################## - && apt clean && \ - rm -rf /var/lib/apt/lists/* + # && apt clean && \ + # rm -rf /var/lib/apt/lists/* # Development stage FROM dev as dev2 ARG WORKSPACE="/home/ros/workspace" -# Print workspace to terminal -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ - echo "Workspace: ${WORKSPACE}" - RUN mkdir -p ${WORKSPACE}/src/elevation_mapping_cupy && chown -R ${USER_UID}:${USER_GID} /home/${USERNAME} RUN echo "if [ -f ${WORKSPACE}/install/setup.bash ]; then source ${WORKSPACE}/install/setup.bash; fi" >> /home/ros/.bashrc WORKDIR ${WORKSPACE} + +# TODO: move up later before commiting +# Setup rosdep +# COPY extra_rosdeps.yaml /etc/ros/rosdep/sources.list.d/emcupy-rosdeps.yaml +RUN ln -s /home/ros/workspace/src/elevation_mapping_cupy/docker/extra_rosdeps.yaml /etc/ros/rosdep/sources.list.d/emcupy-rosdeps.yaml +RUN --mount=type=cache,target=/var/cache/apt \ + rosdep init \ + && echo "yaml file:///home/ros/workspace/src/elevation_mapping_cupy/docker/extra_rosdeps.yaml" | tee /etc/ros/rosdep/sources.list.d/00-emcupy-rosdeps.list \ + && rosdep update + # Switch to non-root user USER $USERNAME diff --git a/docker/extra_rosdeps.yaml b/docker/extra_rosdeps.yaml new file mode 100644 index 00000000..5081f24b --- /dev/null +++ b/docker/extra_rosdeps.yaml @@ -0,0 +1,12 @@ +numpy_lessthan_2: + ubuntu: + pip: + packages: ["numpy<2.0.0"] +simple-parsing: + ubuntu: + pip: + packages: [simple-parsing] +cupy-cuda12x: + ubuntu: + pip: + packages: [cupy-cuda12x] \ No newline at end of file diff --git a/elevation_mapping_cupy/package.xml b/elevation_mapping_cupy/package.xml index f65efb19..f6880b52 100644 --- a/elevation_mapping_cupy/package.xml +++ b/elevation_mapping_cupy/package.xml @@ -29,11 +29,11 @@ grid_map_ros image_transport pcl_ros - pybind11 - + pybind11-dev ros2_numpy + python3-scipy - numpy + numpy_lessthan_2 tf2_ros cv_bridge ament_index_python @@ -42,15 +42,25 @@ rviz2 - gazebo_ros + robot_state_publisher - - opencv-python - - - + python3-opencv cupy-cuda12x simple-parsing + python3-shapely + python3-ruamel.yaml + boost + python3-transforms3d + + + gazebo_ros_pkgs + turtlebot3_msgs + turtlebot3_teleop + camera_info_manager + camera_calibration_parsers + + + From 67fade911a5416ebb674fb3a2ba4f960d55500b8 Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Sun, 16 Feb 2025 01:23:40 +0000 Subject: [PATCH 490/504] Got rosdep stuff nominally working --- docker/Dockerfile.x64 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docker/Dockerfile.x64 b/docker/Dockerfile.x64 index e3d92fda..6420915b 100644 --- a/docker/Dockerfile.x64 +++ b/docker/Dockerfile.x64 @@ -91,9 +91,6 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ && apt clean \ && rm -rf /var/lib/apt/lists/* -# Initialize rosdep -RUN rosdep init && rosdep update - # Pytorch # Used by elevation_mapping_cupy and not rosdep resolvable for cuda version RUN python3 -m pip install -U --extra-index-url https://download.pytorch.org/whl/cu121 \ @@ -192,7 +189,7 @@ RUN distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \ # Development stage FROM dev as dev2 -ARG WORKSPACE="/home/ros/workspace" +ARG WORKSPACE="/home/${USERNAME}/workspace" RUN mkdir -p ${WORKSPACE}/src/elevation_mapping_cupy && chown -R ${USER_UID}:${USER_GID} /home/${USERNAME} RUN echo "if [ -f ${WORKSPACE}/install/setup.bash ]; then source ${WORKSPACE}/install/setup.bash; fi" >> /home/ros/.bashrc @@ -200,12 +197,15 @@ WORKDIR ${WORKSPACE} # TODO: move up later before commiting # Setup rosdep -# COPY extra_rosdeps.yaml /etc/ros/rosdep/sources.list.d/emcupy-rosdeps.yaml -RUN ln -s /home/ros/workspace/src/elevation_mapping_cupy/docker/extra_rosdeps.yaml /etc/ros/rosdep/sources.list.d/emcupy-rosdeps.yaml -RUN --mount=type=cache,target=/var/cache/apt \ - rosdep init \ - && echo "yaml file:///home/ros/workspace/src/elevation_mapping_cupy/docker/extra_rosdeps.yaml" | tee /etc/ros/rosdep/sources.list.d/00-emcupy-rosdeps.list \ - && rosdep update +# Could cache this, but since we are linking extra-rosdeps.yaml instead of copying this doesn't do anything +# RUN --mount=type=cache,target=/home/${USERNAME}/.ros/rosdep/sources.cache \ +RUN rosdep init \ + && ln -s ${WORKSPACE}/src/elevation_mapping_cupy/docker/extra_rosdeps.yaml /etc/ros/rosdep/sources.list.d/emcupy-rosdeps.yaml\ + && echo "yaml file:///etc/ros/rosdep/sources.list.d/emcupy-rosdeps.yaml" | tee /etc/ros/rosdep/sources.list.d/00-emcupy-rosdeps.list +# Linking only works if you don't run rosdep update here and wait until it is loaded, otherwise can use copy +# The benefit is that you can update the rosdeps in your workspace and they will be used +# COPY docker/extra_rosdeps.yaml /etc/ros/rosdep/sources.list.d/emcupy-rosdeps.yaml +# RUN rosdep update # Switch to non-root user USER $USERNAME From 38531493a1778d1cdd5ffe20284fde094cd75e67 Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Sat, 15 Feb 2025 20:47:18 -0600 Subject: [PATCH 491/504] Updated dockerfile to build with or without dependencies in the contianer Fixed bug in numpy array conversion --- docker/Dockerfile.x64 | 133 +++++++++++------- .../scripts/elevation_mapping_node.py | 2 +- 2 files changed, 82 insertions(+), 53 deletions(-) diff --git a/docker/Dockerfile.x64 b/docker/Dockerfile.x64 index 6420915b..e0fa08c9 100644 --- a/docker/Dockerfile.x64 +++ b/docker/Dockerfile.x64 @@ -13,6 +13,7 @@ ARG USERNAME=ros ARG USER_UID=1000 ARG USER_GID=$USER_UID ARG RMW_NAME=zenoh +ARG INSTALL_EMCUPY_ROSDEPS=true # Environment variables ENV DEBIAN_FRONTEND=noninteractive \ @@ -121,18 +122,27 @@ RUN python3 -m pip install \ flake8-quotes # For Python code formatting. Not sure what package uses it # black==21.12b0\ - #### For elevation_mapping_cupy #### - # ruamel.yaml\ # replacing with apt python-ruamel.yaml - # scikit-learn\ # replacing with apt python3-sklearn - might not be needeed - # shapely\ # replacing with apt python3-shapely - # opencv-python\ # replacing with apt installed python3-opencv - # cupy-cuda12x\ # extra rosdeps - # scipy\ # apt install scipy instead - # simple-parsing\ # extra rosdeps - # "numpy<2.0.0" # extra rosdeps +#### For elevation_mapping_cupy #### +RUN if [ "$INSTALL_EMCUPY_ROSDEPS" = true ]; then \ + python3 -m pip install \ + # rosdep resolves with apt python-ruamel.yaml + # ruamel.yaml\ + # rosdep resolves with apt python3-sklearn - might not be needed + scikit-learn\ + # rosdep resolves with apt python3-shapely + # shapely\ + # rosdep resolves with apt python3-opencv + opencv-python\ + # rosdep resolves using extra rosdeps + cupy-cuda12x\ + # rosdep resolves using extra rosdeps + simple-parsing\ + # rosdep resolves using extra rosdeps + "numpy<2.0.0"; \ + fi # Needed for elevation_mapping_cupy to not have run-time errors -# RUN python3 -m pip install transforms3d -U # Replacing with rosdep python3-transforms3d +RUN python3 -m pip install transforms3d scipy -U # Set up non-root user RUN groupadd --gid $USER_GID $USERNAME \ @@ -153,40 +163,53 @@ RUN distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \ && apt clean \ && rm -rf /var/lib/apt/lists/* -# RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ -# apt update && apt install -y --no-install-recommends \ - # For elevation_mapping_cupy - # libboost-all-dev\ # resolved by rosdep as boost - # && apt clean && \ - # rm -rf /var/lib/apt/lists/* - -# RUN apt update && \ - # DEBIAN_FRONTEND=${DEBIAN_FRONTEND} apt install -y \ - #### For elevation_mapping_cupy #### - # ros-${ROS_DISTRO}-grid-map-msgs\ # rosdep grid_map_msgs - # ros-${ROS_DISTRO}-grid-map-ros\ # rosdep grid_map_ros - # ros-${ROS_DISTRO}-image-transport\ # rosdep image_transport - # ros-${ROS_DISTRO}-pcl-ros\# rosdep pcl_ros - # ros-${ROS_DISTRO}-cv-bridge\ # rosdep cv_bridge - # ros-${ROS_DISTRO}-tf-transformations\ # rosdep tf-transformations - # ros-${ROS_DISTRO}-rviz2\ # rosdep rviz2 - # ros-${ROS_DISTRO}-gazebo-ros\ # replacing with rosdep gazebo_ros_pkgs - # ros-${ROS_DISTRO}-grid-map-cv\ # rosdep grid_map_cv - # ros-${ROS_DISTRO}-grid-map-core\ # rosdep grid_map_core - # ros-${ROS_DISTRO}-grid-map-demos\ # rosdep grid_map_demos - ################################## - #### For debugging elevation_mapping_cupy by setting up turtlebot3_simulations#### - # ros-${ROS_DISTRO}-turtlebot3*\ - # ros-${ROS_DISTRO}-camera-calibration-parsers\ - # ros-${ROS_DISTRO}-camera-info-manager\ - # ros-${ROS_DISTRO}-gazebo-plugins\ - # ros-${ROS_DISTRO}-turtlebot3-msgs\ - # ros-${ROS_DISTRO}-turtlebot3-teleop\ - # ros-${ROS_DISTRO}-gazebo-ros-pkgs\ # replacing with rosdep gazebo_ros_pkgs - ############################################## - # && apt clean && \ - # rm -rf /var/lib/apt/lists/* +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + if [ "$INSTALL_EMCUPY_ROSDEPS" = true ]; then \ + apt update && DEBIAN_FRONTEND=${DEBIAN_FRONTEND} apt install -y --no-install-recommends \ + # resolved by rosdep as boost + libboost-all-dev\ + ### For elevation_mapping_cupy #### + # rosdep grid_map_msgs + ros-${ROS_DISTRO}-grid-map-msgs\ + # rosdep grid_map_ros + ros-${ROS_DISTRO}-grid-map-ros\ + # rosdep image_transport + ros-${ROS_DISTRO}-image-transport\ + # rosdep pcl_ros + ros-${ROS_DISTRO}-pcl-ros\ + # rosdep cv_bridge + ros-${ROS_DISTRO}-cv-bridge\ + # rosdep tf-transformations + ros-${ROS_DISTRO}-tf-transformations\ + # rosdep rviz2 + ros-${ROS_DISTRO}-rviz2\ + # replacing with rosdep gazebo_ros_pkgs + ros-${ROS_DISTRO}-gazebo-ros\ + # rosdep grid_map_cv + ros-${ROS_DISTRO}-grid-map-cv\ + # rosdep grid_map_core + ros-${ROS_DISTRO}-grid-map-core\ + # rosdep grid_map_demos + ros-${ROS_DISTRO}-grid-map-demos\ + ros-${ROS_DISTRO}-point-cloud-transport\ + python3-shapely\ + python3-scipy\ + python3-ruamel.yaml\ + ################################# + ### For debugging elevation_mapping_cupy by setting up turtlebot3_simulations#### + # ros-${ROS_DISTRO}-turtlebot3*\ + ros-${ROS_DISTRO}-camera-calibration-parsers\ + ros-${ROS_DISTRO}-camera-info-manager\ + ros-${ROS_DISTRO}-gazebo-plugins\ + ros-${ROS_DISTRO}-turtlebot3-msgs\ + ros-${ROS_DISTRO}-turtlebot3-teleop\ + # replacing with rosdep gazebo_ros_pkgs + ros-${ROS_DISTRO}-gazebo-ros-pkgs\ + ############################################# + && apt clean && \ + rm -rf /var/lib/apt/lists/* ;\ + fi # Development stage FROM dev as dev2 ARG WORKSPACE="/home/${USERNAME}/workspace" @@ -195,17 +218,23 @@ RUN mkdir -p ${WORKSPACE}/src/elevation_mapping_cupy && chown -R ${USER_UID}:${U RUN echo "if [ -f ${WORKSPACE}/install/setup.bash ]; then source ${WORKSPACE}/install/setup.bash; fi" >> /home/ros/.bashrc WORKDIR ${WORKSPACE} -# TODO: move up later before commiting + # Setup rosdep -# Could cache this, but since we are linking extra-rosdeps.yaml instead of copying this doesn't do anything +RUN rosdep init +# COPY docker/extra_rosdeps.yaml /etc/ros/rosdep/sources.list.d/emcupy-rosdeps-fixed.yaml +# Setup rosdep with extra rosdeps and install them for elevation_mapping_cupy # RUN --mount=type=cache,target=/home/${USERNAME}/.ros/rosdep/sources.cache \ -RUN rosdep init \ - && ln -s ${WORKSPACE}/src/elevation_mapping_cupy/docker/extra_rosdeps.yaml /etc/ros/rosdep/sources.list.d/emcupy-rosdeps.yaml\ - && echo "yaml file:///etc/ros/rosdep/sources.list.d/emcupy-rosdeps.yaml" | tee /etc/ros/rosdep/sources.list.d/00-emcupy-rosdeps.list -# Linking only works if you don't run rosdep update here and wait until it is loaded, otherwise can use copy -# The benefit is that you can update the rosdeps in your workspace and they will be used -# COPY docker/extra_rosdeps.yaml /etc/ros/rosdep/sources.list.d/emcupy-rosdeps.yaml -# RUN rosdep update +# RUN if [ "$INSTALL_EMCUPY_ROSDEPS" = true ]; then \ +# echo "yaml file:///etc/ros/rosdep/sources.list.d/emcupy-rosdeps-fixed.yaml" | tee /etc/ros/rosdep/sources.list.d/01-emcupy-rosdeps.list && \ +# rosdep update && \ +# # This install doesn't seem to actually install anything, so removing +# apt update && \ +# rosdep install --from-paths . --ignore-src -y -r; \ +# fi +# Now add the same file again, but this one is symlinked so will change if you change the file in your workspace +RUN ln -s ${WORKSPACE}/src/elevation_mapping_cupy/docker/extra_rosdeps.yaml /etc/ros/rosdep/sources.list.d/emcupy-rosdeps.yaml && \ + echo "yaml file:///etc/ros/rosdep/sources.list.d/emcupy-rosdeps.yaml" | tee /etc/ros/rosdep/sources.list.d/00-emcupy-rosdeps.list; + # Switch to non-root user USER $USERNAME diff --git a/elevation_mapping_cupy/scripts/elevation_mapping_node.py b/elevation_mapping_cupy/scripts/elevation_mapping_node.py index 5c0bf337..50915c91 100755 --- a/elevation_mapping_cupy/scripts/elevation_mapping_node.py +++ b/elevation_mapping_cupy/scripts/elevation_mapping_node.py @@ -383,7 +383,7 @@ def pointcloud_callback(self, msg: PointCloud2, sub_key: str) -> None: # Append additional channels to pts for channel in additional_channels: if channel in points.dtype.names: - data = points[channel] + data = points[channel].flatten() if data.ndim == 1: data = data[:, np.newaxis] pts = np.hstack((pts, data)) From cb57082852e0869ad2b336f6a76679a08998a1fc Mon Sep 17 00:00:00 2001 From: "W. Jacob Wagner" Date: Sun, 16 Feb 2025 19:50:03 +0000 Subject: [PATCH 492/504] Updating READMEs with installation and demo instructions --- README.md | 139 +++++++++++++++++++++++++++++-- elevation_mapping_cupy/README.md | 17 +--- 2 files changed, 132 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index f2f8338d..7365b632 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,140 @@ -## ROS2 Elevation Mapping Cupy +# ROS2 Elevation Mapping Cupy **Status**: Under Development 🚧 -### Features +## Features - **Point cloud-based map update**: *Functional* - **Image-based map update**: *Ongoing development* +- **C++ Node**: *Functional* +- **Python Node**: *Functional* +- **Docker & VS Code Devcontainer**: *Provided* + + + +## Installation +A docker file, installation and build scripts, and a VS Code Dev Container have all been provided to ease integration and development. +This has been tested with Ubuntu 22.04, ROS 2 Humble, Zenoh RMW, CUDA 12.1, and PyTorch 2.6.0. +Some dependency issues with numpy, transforms3d, scipy, and ros2_numpy arose during setup so if versions of any of these packages are changed you may run into issues. +The package.xml has been updated to ensure most dependencies are automatically installed via rosdep and some extra rosdep entries are provided to ensure proper versioning. +This is not possible for some packages, e.g. pytorch, due to need for providing an --extra-index-url during installation. +Therefore, this requirement is satsified inside of the docker build. + +To test out this package with the turtlebot3 Gazebo (classic) simulation you will need to install: +- VS Code +- Docker +- NVIDIA Container Toolkit +- NVIDIA CUDA Toolkit + +### Visual Studio Code +```bash +sudo snap install --classic code +``` + +### Docker Installation +```bash +# Add Docker's official GPG key +sudo apt-get update +sudo apt-get install ca-certificates curl gnupg -y +sudo install -m 0755 -d /etc/apt/keyrings +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg +sudo chmod a+r /etc/apt/keyrings/docker.gpg + +# Add Docker repository +echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +sudo apt-get update + +# Install Docker +sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y + +``` + +### NVIDIA Container Toolkit Installation +```bash +# Configure the repository +curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg +curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list + +# Update and install +sudo apt-get update +sudo apt-get install -y nvidia-container-toolkit + +# Configure Docker for NVIDIA +sudo nvidia-ctk runtime configure --runtime=docker +sudo systemctl restart docker + +# Change Docker root folder +cd +mkdir docker +sudo tee /etc/docker/daemon.json > /dev/null </ +git clone -b ros2_humble https://github.com/jwag/elevation_mapping_cupy.git +``` + +#### Building the Docker Workspace Container +- Open the folder with VS Code +- Select **"Dev Containers: Reopen in container"** in the bottom left from the blue button which will build the docker image. +- Setup the workspace + ```bash + ./docker/setup.sh + ``` +- Build the workspace + ```bash + ./docker/build.sh + +#### Run The Turtlebot3 Demo +The docker should set the environmental variable `TURTLEBOT3_MODEL=waffle_realsense_depth` to select the correct version of the turtlebot to simulate. + +In the first terminal start the zenoh router: +```bash +ros2 run rmw_zenoh_cpp rmw_zenohd +``` + +In a second terminal launch the turtlebot3 in Gazebo with the following command: +```bash +ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py +``` + +In a third terminal launch the elevation mapping node with the configs for the turtle. Set use_python_node to true to override the default use of the cpp node if you wish: +```bash +ros2 launch elevation_mapping_cupy elevation_mapping_turtle.launch.py use_python_node:=false +``` + +In a fourth terminal run the turtlebot3 teleop node if you want to drive the turtlebot around using the keyboard: +```bash +ros2 run turtlebot3_teleop teleop_keyboard +``` -![Elevation Map in ROS 2 Humble with Gazebo ](https://github.com/user-attachments/assets/0dd9ebbe-a90d-486f-9871-81921308fab9) +--- -# Elevation Mapping cupy +# Elevation Mapping cupy (*Instructions Not Updated for ROS2*) ![python tests](https://github.com/leggedrobotics/elevation_mapping_cupy/actions/workflows/python-tests.yml/badge.svg) diff --git a/elevation_mapping_cupy/README.md b/elevation_mapping_cupy/README.md index 05509b58..671de643 100644 --- a/elevation_mapping_cupy/README.md +++ b/elevation_mapping_cupy/README.md @@ -1,19 +1,4 @@ -## Example 1: Turtle Simple Example -Install the realsense wrapper for [TurtleBot3]([ros2_turtlebot3_waffle_intel_realsense](https://github.com/mlherd/ros2_turtlebot3_waffle_intel_realsense)) and place the model in your home .gazebo/models/ folder. -You can launch the turtlebot3 in Gazebo with the following command: -```bash -ros2 launch elevation_mapping_cupy turtle_simple_example.launch.py -``` -You can also maunally spawn the robot in Gazebo. - - -Launch the elevation mapping node: -```bash -ros2 launch elevation_mapping_cupy turtle_simple_example.launch.py -``` - - -## (Corrected) Example 1: Turtle Simple Example +# Example 1: Turtle Simple Example Set the env in the Dockerfile ```dockerfile ENV TURTLEBOT3_MODEL=waffle_realsense_depth From 56e5aa07505ceec1bbff8755bd81395e66854774 Mon Sep 17 00:00:00 2001 From: Lorenzo Terenzi Date: Mon, 17 Feb 2025 09:33:48 +0100 Subject: [PATCH 493/504] fix time for deployment --- .../elevation_mapping_cupy/elevation_mapping_ros.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py index 83f19ad4..a7fbda14 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py @@ -37,11 +37,9 @@ def __init__(self): super().__init__( 'elevation_mapping_node', automatically_declare_parameters_from_overrides=True, - allow_undeclared_parameters=True, - parameter_overrides=[ - rclpy.Parameter('use_sim_time', rclpy.Parameter.Type.BOOL, True) - ] + allow_undeclared_parameters=True ) + self.root = get_package_share_directory("elevation_mapping_cupy") weight_file = os.path.join(self.root, "config/core/weights.dat") plugin_config_file = os.path.join(self.root, "config/core/plugin_config.yaml") From e54a9414e8c75bf238d185e526114496b7fdeed3 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 13 Mar 2025 15:55:35 +0100 Subject: [PATCH 494/504] less confusing name --- .../elevation_mapping_cupy/elevation_mapping.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py index 39b2994d..82eebfff 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py @@ -132,7 +132,7 @@ def clear(self): self.mean_error = 0.0 self.additive_mean_error = 0.0 - def get_position(self, position): + def get_center_position(self, position): """Return the position of the map center. Args: From bbdfb84fdf24c9cc119ffd731e4a50b7b806676d Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 13 Mar 2025 15:56:00 +0100 Subject: [PATCH 495/504] lints --- .../launch/elevation_mapping.launch.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/elevation_mapping_cupy/launch/elevation_mapping.launch.py b/elevation_mapping_cupy/launch/elevation_mapping.launch.py index f2bf3cf2..cb60b8e2 100755 --- a/elevation_mapping_cupy/launch/elevation_mapping.launch.py +++ b/elevation_mapping_cupy/launch/elevation_mapping.launch.py @@ -6,19 +6,22 @@ from launch.substitutions import LaunchConfiguration, PathJoinSubstitution from launch.conditions import IfCondition + def generate_launch_description(): package_name = 'elevation_mapping_cupy' share_dir = get_package_share_directory(package_name) # Define paths - core_param_path = os.path.join(share_dir, 'config', 'core', 'core_param.yaml') + core_param_path = os.path.join( + share_dir, 'config', 'core', 'core_param.yaml') # Declare launch arguments robot_param_arg = DeclareLaunchArgument( 'robot_config', # default_value='turtle_bot/turle_bot_simple.yaml', default_value='menzi/base.yaml', - description='Name of the robot-specific config file within config/setups/' + description='Name of the robot-specific config file within ' + 'config/setups/' ) launch_rviz_arg = DeclareLaunchArgument( @@ -35,20 +38,22 @@ def generate_launch_description(): use_sim_time_arg = DeclareLaunchArgument( 'use_sim_time', - default_value='false', + default_value='true', description='Use simulation clock if true' ) # Get launch configurations robot_config = LaunchConfiguration('robot_config') - robot_param_path = PathJoinSubstitution([share_dir, 'config', 'setups', robot_config]) + robot_param_path = PathJoinSubstitution( + [share_dir, 'config', 'setups', robot_config]) launch_rviz = LaunchConfiguration('launch_rviz') rviz_config = LaunchConfiguration('rviz_config') use_sim_time = LaunchConfiguration('use_sim_time') # Verify core config exists if not os.path.exists(core_param_path): - raise FileNotFoundError(f"Config file {core_param_path} does not exist") + raise FileNotFoundError( + f"Config file {core_param_path} does not exist") # Define nodes elevation_mapping_node = Node( From bdc2e4d84aafe020d44e6ec22e9fe01d711f392c Mon Sep 17 00:00:00 2001 From: Idate96 Date: Thu, 27 Mar 2025 13:23:01 +0100 Subject: [PATCH 496/504] base frame --- elevation_mapping_cupy/config/core/core_param.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 3786b25f..29d967c0 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -2,7 +2,7 @@ elevation_mapping_node: ros__parameters: #### Basic parameters ######## resolution: 0.1 # resolution in m. - map_length: 15.0 # map's size in m. + map_length: 20.0 # map's size in m. sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). mahalanobis_thresh: 2.0 # points outside this distance is outlier. outlier_variance: 0.0`1 # if point is outlier, add this value to the cell. @@ -44,9 +44,9 @@ elevation_mapping_node: overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - map_frame: 'World' # The map frame where the odometry source uses. + map_frame: 'BASE' # The map frame where the odometry source uses. base_frame: 'BASE' # The robot's base frame. This frame will be a center of the map. - corrected_map_frame: 'World' + corrected_map_frame: 'BASE' # map_frame: 'World' # The map frame where the odometry source uses. From a4348d298757b935ccafca5250ed0b7219bc49d3 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Fri, 9 May 2025 15:00:41 +0200 Subject: [PATCH 497/504] correct timestamp and dimensions --- .../elevation_mapping_ros.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py index a7fbda14..0c592d87 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py @@ -279,10 +279,11 @@ def publish_map(self, key: str) -> None: return gm = GridMap() gm.header.frame_id = self.map_frame - gm.header.stamp = self.get_clock().now().to_msg() + gm.header.stamp = self._last_t if self._last_t is not None else self.get_clock().now().to_msg() gm.info.resolution = self._map.resolution - gm.info.length_x = self._map.map_length - gm.info.length_y = self._map.map_length + actual_map_length = (self._map.cell_n - 2) * self._map.resolution + gm.info.length_x = actual_map_length + gm.info.length_y = actual_map_length gm.info.pose.position.x = self._map_t.x gm.info.pose.position.y = self._map_t.y gm.info.pose.position.z = 0.0 @@ -296,12 +297,12 @@ def publish_map(self, key: str) -> None: for layer in self.my_publishers[key].get("layers", []): gm.layers.append(layer) self._map.get_map_with_name_ref(layer, self._map_data) + map_data_for_gridmap = np.flip(self._map_data, axis=1) arr = Float32MultiArray() arr.layout = MAL() - N = self._map_data.shape[0] - arr.layout.dim.append(MAD(label="column_index", size=N, stride=int(N * N))) - arr.layout.dim.append(MAD(label="row_index", size=N, stride=N)) - arr.data = self._map_data.T.flatten().tolist() + arr.layout.dim.append(MAD(label="column_index", size=map_data_for_gridmap.shape[1], stride=map_data_for_gridmap.shape[0] * map_data_for_gridmap.shape[1])) + arr.layout.dim.append(MAD(label="row_index", size=map_data_for_gridmap.shape[0], stride=map_data_for_gridmap.shape[0])) + arr.data = map_data_for_gridmap.flatten().tolist() gm.data.append(arr) gm.outer_start_index = 0 From e6c7ce44bc81c4aef4ed6d3d24dd6b200f82e56d Mon Sep 17 00:00:00 2001 From: Lorenzo Date: Tue, 19 Aug 2025 12:17:51 +0000 Subject: [PATCH 498/504] Fix elevation map rotation issue with Row-Major indexing - Fixed CUDA kernels to use proper Row-Major convention (Row=Y, Col=X) - Updated is_inside() and get_idx() functions in all kernels - Fixed normal vector calculation (removed swapped components) - Adjusted data flipping for correct GridMap publishing - Kept 180-degree rotation in internal representation - Removed extra flip in elevation_mapping_ros.py The elevation map now correctly aligns with LiDAR data. --- .../elevation_mapping.py | 1 + .../elevation_mapping_ros.py | 4 +- .../kernels/custom_kernels.py | 44 ++++++++++++++----- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py index 82eebfff..22c8531b 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py @@ -797,6 +797,7 @@ def get_map_with_name_ref(self, name, data): else: print("Layer {} is not in the map".format(name)) return + # Need 180 degree rotation to match coordinate system m = xp.flip(m, 0) m = xp.flip(m, 1) if use_stream: diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py index 0c592d87..5ccbbf5f 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping_ros.py @@ -297,9 +297,11 @@ def publish_map(self, key: str) -> None: for layer in self.my_publishers[key].get("layers", []): gm.layers.append(layer) self._map.get_map_with_name_ref(layer, self._map_data) - map_data_for_gridmap = np.flip(self._map_data, axis=1) + # After fixing CUDA kernels and removing flips in elevation_mapping.py, no flip needed here + map_data_for_gridmap = self._map_data arr = Float32MultiArray() arr.layout = MAL() + # Keep original dimension order but fix strides arr.layout.dim.append(MAD(label="column_index", size=map_data_for_gridmap.shape[1], stride=map_data_for_gridmap.shape[0] * map_data_for_gridmap.shape[1])) arr.layout.dim.append(MAD(label="row_index", size=map_data_for_gridmap.shape[0], stride=map_data_for_gridmap.shape[0])) arr.data = map_data_for_gridmap.flatten().tolist() diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/kernels/custom_kernels.py b/elevation_mapping_cupy/elevation_mapping_cupy/kernels/custom_kernels.py index d7025270..238a0a57 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/kernels/custom_kernels.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/kernels/custom_kernels.py @@ -32,11 +32,16 @@ def map_utils( return i; } __device__ bool is_inside(int idx) { - int idx_x = idx / ${width}; - int idx_y = idx % ${width}; + // Fixed: Row-Major (Row=Y, Col=X) + // Row index (Y) + int idx_y = idx / ${width}; + // Column index (X) + int idx_x = idx % ${width}; + // Check Col bounds (Width) if (idx_x == 0 || idx_x == ${width} - 1) { return false; } + // Check Row bounds (Height) if (idx_y == 0 || idx_y == ${height} - 1) { return false; } @@ -45,7 +50,8 @@ def map_utils( __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); - return ${width} * idx_x + idx_y; + // Fixed: Row-Major (Row=Y, Col=X) + return ${width} * idx_y + idx_x; } __device__ int get_map_idx(int idx, int layer_n) { const int layer = ${width} * ${height}; @@ -406,11 +412,16 @@ def dilation_filter_kernel(width, height, dilation_size): return layer * layer_n + relative_idx; } __device__ bool is_inside(int idx) { - int idx_x = idx / ${width}; - int idx_y = idx % ${width}; + // Fixed: Row-Major (Row=Y, Col=X) + // Row index (Y) + int idx_y = idx / ${width}; + // Column index (X) + int idx_x = idx % ${width}; + // Check Col bounds (Width) if (idx_x <= 0 || idx_x >= ${width} - 1) { return false; } + // Check Row bounds (Height) if (idx_y <= 0 || idx_y >= ${height} - 1) { return false; } @@ -466,11 +477,16 @@ def normal_filter_kernel(width, height, resolution): return layer * layer_n + relative_idx; } __device__ bool is_inside(int idx) { - int idx_x = idx / ${width}; - int idx_y = idx % ${width}; + // Fixed: Row-Major (Row=Y, Col=X) + // Row index (Y) + int idx_y = idx / ${width}; + // Column index (X) + int idx_x = idx % ${width}; + // Check Col bounds (Width) if (idx_x <= 0 || idx_x >= ${width} - 1) { return false; } + // Check Row bounds (Height) if (idx_y <= 0 || idx_y >= ${height} - 1) { return false; } @@ -491,8 +507,9 @@ def normal_filter_kernel(width, height, resolution): if (!is_inside(idx_x) || !is_inside(idx_y)) { return; } float dzdx = (map[idx_x] - h); float dzdy = (map[idx_y] - h); - float nx = -dzdy / resolution(); - float ny = -dzdx / resolution(); + // Fixed: Normal = (-dH/dx, -dH/dy, 1) + float nx = -dzdx / resolution(); + float ny = -dzdy / resolution(); float nz = 1; float norm = sqrt((nx * nx) + (ny * ny) + 1); newmap[get_map_idx(i, 0)] = nx / norm; @@ -568,12 +585,14 @@ def polygon_mask_kernel(width, height, resolution): } __device__ int get_idx_x(int idx){ - int idx_x = idx / ${width}; + // Fixed: Column index (X) + int idx_x = idx % ${width}; return idx_x; } __device__ int get_idx_y(int idx){ - int idx_y = idx % ${width}; + // Fixed: Row index (Y) + int idx_y = idx / ${width}; return idx_y; } @@ -599,7 +618,8 @@ def polygon_mask_kernel(width, height, resolution): __device__ int get_idx(float16 x, float16 y, float16 center_x, float16 center_y) { int idx_x = clamp(get_x_idx(x, center_x), 0, ${width} - 1); int idx_y = clamp(get_y_idx(y, center_y), 0, ${height} - 1); - return ${width} * idx_x + idx_y; + // Fixed: Row-Major (Row=Y, Col=X) + return ${width} * idx_y + idx_x; } """ From b182b06d074068dc81c7069a3877111ff315a226 Mon Sep 17 00:00:00 2001 From: Lorenzo Date: Tue, 19 Aug 2025 12:37:39 +0000 Subject: [PATCH 499/504] Restore generic defaults in core config for PR - Reset map_frame to 'map' and base_frame to 'base_link' (standard ROS) - Reset map_length to 15.0m default - Reset use_sim_time default to 'false' - Excavator-specific configs remain in mole_perception_bringup --- elevation_mapping_cupy/config/core/core_param.yaml | 8 ++++---- elevation_mapping_cupy/launch/elevation_mapping.launch.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/elevation_mapping_cupy/config/core/core_param.yaml b/elevation_mapping_cupy/config/core/core_param.yaml index 29d967c0..05c64c3b 100644 --- a/elevation_mapping_cupy/config/core/core_param.yaml +++ b/elevation_mapping_cupy/config/core/core_param.yaml @@ -2,7 +2,7 @@ elevation_mapping_node: ros__parameters: #### Basic parameters ######## resolution: 0.1 # resolution in m. - map_length: 20.0 # map's size in m. + map_length: 15.0 # map's size in m. sensor_noise_factor: 0.05 # point's noise is sensor_noise_factor*z^2 (z is distance from sensor). mahalanobis_thresh: 2.0 # points outside this distance is outlier. outlier_variance: 0.0`1 # if point is outlier, add this value to the cell. @@ -44,9 +44,9 @@ elevation_mapping_node: overlap_clear_range_xy: 4.0 # xy range [m] for clearing overlapped area. this defines the valid area for overlap clearance. (used for multi floor setting) overlap_clear_range_z: 2.0 # z range [m] for clearing overlapped area. cells outside this range will be cleared. (used for multi floor setting) - map_frame: 'BASE' # The map frame where the odometry source uses. - base_frame: 'BASE' # The robot's base frame. This frame will be a center of the map. - corrected_map_frame: 'BASE' + map_frame: 'map' # The map frame where the odometry source uses. + base_frame: 'base_link' # The robot's base frame. This frame will be a center of the map. + corrected_map_frame: 'map' # map_frame: 'World' # The map frame where the odometry source uses. diff --git a/elevation_mapping_cupy/launch/elevation_mapping.launch.py b/elevation_mapping_cupy/launch/elevation_mapping.launch.py index cb60b8e2..0afc4948 100755 --- a/elevation_mapping_cupy/launch/elevation_mapping.launch.py +++ b/elevation_mapping_cupy/launch/elevation_mapping.launch.py @@ -38,7 +38,7 @@ def generate_launch_description(): use_sim_time_arg = DeclareLaunchArgument( 'use_sim_time', - default_value='true', + default_value='false', description='Use simulation clock if true' ) From e311bfdbcd1f8ddb698b9295a7116e25475581ac Mon Sep 17 00:00:00 2001 From: Lorenzo Terenzi Date: Tue, 19 Aug 2025 14:38:51 +0000 Subject: [PATCH 500/504] Add support for Livox point cloud 'xyz' field format - Handle both dict and structured array formats from ros2_numpy - Support Livox MID-360's combined 'xyz' field instead of separate x,y,z - Add robust error handling for various point cloud structures - Prevent KeyError when processing Livox lidar data --- .../scripts/elevation_mapping_node.py | 83 ++++++++++++++++--- 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/elevation_mapping_cupy/scripts/elevation_mapping_node.py b/elevation_mapping_cupy/scripts/elevation_mapping_node.py index 142ecdbc..5c599d9a 100755 --- a/elevation_mapping_cupy/scripts/elevation_mapping_node.py +++ b/elevation_mapping_cupy/scripts/elevation_mapping_node.py @@ -365,10 +365,36 @@ def pointcloud_callback(self, msg: PointCloud2, sub_key: str) -> None: channels = ["x", "y", "z"] + additional_channels try: points = rnp.numpify(msg) - except: + except Exception as e: + self.get_logger().warn(f"Failed to numpify point cloud: {e}") return - if points['x'].size == 0: + + # Check if points is empty - handle both structured array and dict cases + if points is None: return + + # Handle different data structures from rnp.numpify + if isinstance(points, dict): + # If it's a dict, check if it has data + if not points or (len(points) == 0): + return + # Check for x,y,z keys or xyz field in dict + if 'xyz' in points: + # Handle combined xyz field (common in Livox lidars) + xyz_data = points['xyz'] + if len(xyz_data) == 0: + return + elif 'x' in points: + # Handle separate x,y,z fields + if len(points['x']) == 0: + return + else: + self.get_logger().warn(f"Point cloud dict missing 'x' or 'xyz' field. Available fields: {list(points.keys())}") + return + else: + # It's a structured numpy array + if points.size == 0: + return frame_sensor_id = msg.header.frame_id transform_sensor_to_map = self.safe_lookup_transform( self.map_frame, @@ -379,15 +405,50 @@ def pointcloud_callback(self, msg: PointCloud2, sub_key: str) -> None: q = transform_sensor_to_map.transform.rotation t_np = np.array([t.x, t.y, t.z], dtype=np.float32) R = quaternion_matrix([q.x, q.y, q.z, q.w])[:3, :3].astype(np.float32) - pts = rnp.point_cloud2.get_xyz_points(points) - # TODO: This is probably expensive. Consider modifying rnp or input_pointcloud() - # Append additional channels to pts - for channel in additional_channels: - if channel in points.dtype.names: - data = points[channel].flatten() - if data.ndim == 1: - data = data[:, np.newaxis] - pts = np.hstack((pts, data)) + + # Extract xyz points based on data structure + if isinstance(points, dict): + # If points is a dict, manually construct xyz array + if 'xyz' in points: + # Handle combined xyz field (common in Livox lidars) + xyz_array = np.array(points['xyz']) + if xyz_array.ndim == 2 and xyz_array.shape[1] == 3: + pts = xyz_array + elif xyz_array.ndim == 1: + # Reshape if flattened + pts = xyz_array.reshape(-1, 3) + else: + # Try to extract x, y, z from the structure + pts = xyz_array[:, :3] if xyz_array.shape[1] >= 3 else xyz_array + elif 'x' in points and 'y' in points and 'z' in points: + # Handle separate x,y,z fields + x = np.array(points['x']).flatten() + y = np.array(points['y']).flatten() + z = np.array(points['z']).flatten() + pts = np.column_stack((x, y, z)) + else: + # Fallback: try to use any available method + self.get_logger().warn(f"Unexpected point cloud structure, attempting fallback") + return + + # Append additional channels + for channel in additional_channels: + if channel in points: + data = np.array(points[channel]).flatten() + if data.ndim == 1: + data = data[:, np.newaxis] + pts = np.hstack((pts, data)) + else: + # Use standard method for structured arrays + pts = rnp.point_cloud2.get_xyz_points(points) + # TODO: This is probably expensive. Consider modifying rnp or input_pointcloud() + # Append additional channels to pts + for channel in additional_channels: + if hasattr(points, 'dtype') and hasattr(points.dtype, 'names') and channel in points.dtype.names: + data = points[channel].flatten() + if data.ndim == 1: + data = data[:, np.newaxis] + pts = np.hstack((pts, data)) self._map.input_pointcloud(pts, channels, R, t_np, 0, 0) self._pointcloud_process_counter += 1 From 50dd1191ad35eeceed3116d620d1d497737deac2 Mon Sep 17 00:00:00 2001 From: Lorenzo Terenzi Date: Tue, 19 Aug 2025 17:01:05 +0200 Subject: [PATCH 501/504] Update README.md --- README.md | 138 +----------------------------------------------------- 1 file changed, 1 insertion(+), 137 deletions(-) diff --git a/README.md b/README.md index 7365b632..27cb1a6c 100644 --- a/README.md +++ b/README.md @@ -1,141 +1,5 @@ # ROS2 Elevation Mapping Cupy - **Status**: Under Development 🚧 -## Features -- **Point cloud-based map update**: *Functional* -- **Image-based map update**: *Ongoing development* -- **C++ Node**: *Functional* -- **Python Node**: *Functional* -- **Docker & VS Code Devcontainer**: *Provided* - - - -## Installation -A docker file, installation and build scripts, and a VS Code Dev Container have all been provided to ease integration and development. -This has been tested with Ubuntu 22.04, ROS 2 Humble, Zenoh RMW, CUDA 12.1, and PyTorch 2.6.0. -Some dependency issues with numpy, transforms3d, scipy, and ros2_numpy arose during setup so if versions of any of these packages are changed you may run into issues. -The package.xml has been updated to ensure most dependencies are automatically installed via rosdep and some extra rosdep entries are provided to ensure proper versioning. -This is not possible for some packages, e.g. pytorch, due to need for providing an --extra-index-url during installation. -Therefore, this requirement is satsified inside of the docker build. - -To test out this package with the turtlebot3 Gazebo (classic) simulation you will need to install: -- VS Code -- Docker -- NVIDIA Container Toolkit -- NVIDIA CUDA Toolkit - -### Visual Studio Code -```bash -sudo snap install --classic code -``` - -### Docker Installation -```bash -# Add Docker's official GPG key -sudo apt-get update -sudo apt-get install ca-certificates curl gnupg -y -sudo install -m 0755 -d /etc/apt/keyrings -curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg -sudo chmod a+r /etc/apt/keyrings/docker.gpg - -# Add Docker repository -echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null -sudo apt-get update - -# Install Docker -sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y - -``` - -### NVIDIA Container Toolkit Installation -```bash -# Configure the repository -curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg -curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list - -# Update and install -sudo apt-get update -sudo apt-get install -y nvidia-container-toolkit - -# Configure Docker for NVIDIA -sudo nvidia-ctk runtime configure --runtime=docker -sudo systemctl restart docker - -# Change Docker root folder -cd -mkdir docker -sudo tee /etc/docker/daemon.json > /dev/null </ -git clone -b ros2_humble https://github.com/jwag/elevation_mapping_cupy.git -``` - -#### Building the Docker Workspace Container -- Open the folder with VS Code -- Select **"Dev Containers: Reopen in container"** in the bottom left from the blue button which will build the docker image. -- Setup the workspace - ```bash - ./docker/setup.sh - ``` -- Build the workspace - ```bash - ./docker/build.sh - -#### Run The Turtlebot3 Demo -The docker should set the environmental variable `TURTLEBOT3_MODEL=waffle_realsense_depth` to select the correct version of the turtlebot to simulate. - -In the first terminal start the zenoh router: -```bash -ros2 run rmw_zenoh_cpp rmw_zenohd -``` - -In a second terminal launch the turtlebot3 in Gazebo with the following command: -```bash -ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py -``` - -In a third terminal launch the elevation mapping node with the configs for the turtle. Set use_python_node to true to override the default use of the cpp node if you wish: -```bash -ros2 launch elevation_mapping_cupy elevation_mapping_turtle.launch.py use_python_node:=false -``` - -In a fourth terminal run the turtlebot3 teleop node if you want to drive the turtlebot around using the keyboard: -```bash -ros2 run turtlebot3_teleop teleop_keyboard -``` - ---- - -# Elevation Mapping cupy (*Instructions Not Updated for ROS2*) - + ![python tests](https://github.com/leggedrobotics/elevation_mapping_cupy/actions/workflows/python-tests.yml/badge.svg) [Documentation](https://leggedrobotics.github.io/elevation_mapping_cupy/) From 1caf0e98eb162ea616a2bb7291225c9edfac7a71 Mon Sep 17 00:00:00 2001 From: Lorenzo Terenzi Date: Tue, 19 Aug 2025 15:39:48 +0000 Subject: [PATCH 502/504] Port useful features from main branch to ROS2 - Fix 'Layer rgb is not in the map' error spam by adding special handling for RGB layer requests - Add max_filter plugin from main branch for filling invalid cells with maximum values - RGB layer now properly retrieves data from semantic layers using color fusion These changes eliminate the repetitive error messages and add the max_filter functionality that was missing in the ROS2 branch. --- .../elevation_mapping.py | 19 +++ .../plugins/max_filter.py | 111 ++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 elevation_mapping_cupy/elevation_mapping_cupy/plugins/max_filter.py diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py index 55cd0fb7..b9e11caa 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py @@ -782,6 +782,25 @@ def get_map_with_name_ref(self, name, data): p = self.plugin_manager.get_param_with_name(name) xp = self.xp_of_array(m) m = self.process_map_for_publish(m, fill_nan=p.fill_nan, add_z=p.is_height_layer, xp=xp) + elif name == "rgb": + # Special handling for rgb layer - check if any semantic layer uses color fusion + color_layer = None + for layer_name in self.semantic_map.layer_names: + if (layer_name in self.semantic_map.layer_specs_points and + self.semantic_map.layer_specs_points[layer_name] == "color"): + color_layer = layer_name + break + elif (layer_name in self.semantic_map.layer_specs_image and + self.semantic_map.layer_specs_image[layer_name] == "color"): + color_layer = layer_name + break + + if color_layer: + # Get the RGB data from the color layer + m = self.semantic_map.get_rgb(color_layer) + else: + # No RGB data available, return silently + return else: print("Layer {} is not in the map".format(name)) return diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/plugins/max_filter.py b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/max_filter.py new file mode 100644 index 00000000..865470b9 --- /dev/null +++ b/elevation_mapping_cupy/elevation_mapping_cupy/plugins/max_filter.py @@ -0,0 +1,111 @@ +# +# Copyright (c) 2022, Takahiro Miki. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for details. +# +import cupy as cp +import string +from typing import List + +from .plugin_manager import PluginBase + + +class MaxFilter(PluginBase): + """This is a filter to fill in invalid cells with maximum values around. + + ... + + Attributes + ---------- + width: int + width of the elevation map. + height: int + height of the elevation map. + dilation_size: int + The size of the patch to search for maximum value for each iteration. + iteration_n: int + The number of iteration to repeat the same filter. + """ + + def __init__(self, cell_n: int = 100, dilation_size: int = 5, iteration_n: int = 5, **kwargs): + super().__init__() + self.iteration_n = iteration_n + self.width = cell_n + self.height = cell_n + self.max_filtered = cp.zeros((self.width, self.height)) + self.max_filtered_mask = cp.zeros((self.width, self.height)) + self.max_filter_kernel = cp.ElementwiseKernel( + in_params="raw U map, raw U mask", + out_params="raw U newmap, raw U newmask", + preamble=string.Template( + """ + __device__ int get_map_idx(int idx, int layer_n) { + const int layer = ${width} * ${height}; + return layer * layer_n + idx; + } + + __device__ int get_relative_map_idx(int idx, int dx, int dy, int layer_n) { + const int layer = ${width} * ${height}; + const int relative_idx = idx + ${width} * dy + dx; + return layer * layer_n + relative_idx; + } + __device__ bool is_inside(int idx) { + int idx_x = idx / ${width}; + int idx_y = idx % ${width}; + if (idx_x <= 0 || idx_x >= ${width} - 1) { + return false; + } + if (idx_y <= 0 || idx_y >= ${height} - 1) { + return false; + } + return true; + } + """ + ).substitute(width=self.width, height=self.height), + operation=string.Template( + """ + U valid = mask[get_map_idx(i, 0)]; + if (valid < 0.5) { + U max_value = -1000000.0; + for (int dy = -${dilation_size}; dy <= ${dilation_size}; dy++) { + for (int dx = -${dilation_size}; dx <= ${dilation_size}; dx++) { + int idx = get_relative_map_idx(i, dx, dy, 0); + if (!is_inside(idx)) {continue;} + U valid = mask[idx]; + U value = map[idx]; + if(valid > 0.5 && value > max_value) { + max_value = value; + } + } + } + if (max_value > -1000000 + 1) { + newmap[get_map_idx(i, 0)] = max_value; + newmask[get_map_idx(i, 0)] = 0.6; + } + } + """ + ).substitute(dilation_size=dilation_size), + name="max_filter_kernel", + ) + + def __call__( + self, + elevation_map: cp.ndarray, + layer_names: List[str], + plugin_layers: cp.ndarray, + plugin_layer_names: List[str], + ) -> cp.ndarray: + self.max_filtered = elevation_map[0].copy() + self.max_filtered_mask = elevation_map[2].copy() + for i in range(self.iteration_n): + self.max_filter_kernel( + self.max_filtered.copy(), + self.max_filtered_mask.copy(), + self.max_filtered, + self.max_filtered_mask, + size=(self.width * self.height), + ) + # If there's no more mask, break + if (self.max_filtered_mask > 0.5).all(): + break + max_filtered = cp.where(self.max_filtered_mask > 0.5, self.max_filtered.copy(), cp.nan) + return max_filtered \ No newline at end of file From df85d97ae512e4c848931755825a787b4ccb7102 Mon Sep 17 00:00:00 2001 From: Idate96 Date: Wed, 27 Aug 2025 23:09:10 +0200 Subject: [PATCH 503/504] feat: Make Python node the default executable for elevation_mapping_cupy - Change executable from 'elevation_mapping_node' to 'elevation_mapping_node.py' in launch files - Use pure Python implementation instead of C++ wrapper to avoid API mismatches - Ensures compatibility with latest Python API changes --- elevation_mapping_cupy/launch/elevation_mapping.launch.py | 2 +- elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/launch/elevation_mapping.launch.py b/elevation_mapping_cupy/launch/elevation_mapping.launch.py index 0afc4948..cb418578 100755 --- a/elevation_mapping_cupy/launch/elevation_mapping.launch.py +++ b/elevation_mapping_cupy/launch/elevation_mapping.launch.py @@ -58,7 +58,7 @@ def generate_launch_description(): # Define nodes elevation_mapping_node = Node( package=package_name, - executable='elevation_mapping_node', + executable='elevation_mapping_node.py', name='elevation_mapping_node', output='screen', parameters=[ diff --git a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py index 03d18530..ac46fb70 100644 --- a/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py +++ b/elevation_mapping_cupy/launch/elevation_mapping_cupy.launch.py @@ -11,7 +11,7 @@ def generate_launch_description(): launch_ros.actions.SetParameter(name='use_sim_time', value=True), Node( package='elevation_mapping_cupy', - executable='elevation_mapping_node', + executable='elevation_mapping_node.py', name='elevation_mapping', parameters=[ PathJoinSubstitution([ From ef80f85d69cef42772406bfec79173fbe291e3ae Mon Sep 17 00:00:00 2001 From: Fredrikhb Date: Tue, 23 Sep 2025 14:09:56 +0200 Subject: [PATCH 504/504] fix shift_map_xy handling: use [dy,dx] for cp.roll axes --- .../elevation_mapping_cupy/elevation_mapping.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py index b9e11caa..90b841c7 100644 --- a/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py +++ b/elevation_mapping_cupy/elevation_mapping_cupy/elevation_mapping.py @@ -151,7 +151,8 @@ def move(self, delta_position): delta_position_xy = delta_pixel * self.resolution self.center[:2] += xp.asarray(delta_position_xy) self.center[2] += xp.asarray(delta_position[2]) - self.shift_map_xy(delta_pixel) + dy_dx = xp.array([delta_pixel[1], delta_pixel[0]]) + self.shift_map_xy(dy_dx) self.shift_map_z(-delta_position[2]) def move_to(self, position, R): @@ -169,7 +170,8 @@ def move_to(self, position, R): delta_xy = delta_pixel * self.resolution self.center[:2] += delta_xy self.center[2] += delta[2] - self.shift_map_xy(-delta_pixel) + dy_dx = xp.array([delta_pixel[1], delta_pixel[0]]) + self.shift_map_xy(-dy_dx) self.shift_map_z(-delta[2]) def pad_value(self, x, shift_value, idx=None, value=0.0):

    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

    T<-US%-HS=YC96pjiucFAoB{ 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

1=hR6Z|cGgTNRl?zW;`PvF#uOX7`b4 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�gzIRfH!>Y+GCe2eD&qm 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%0D$YR))ymZU4 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%0D$YR))ymZU4 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

&zwDHWy5oFA_u2lf7lP9|2rB# z*i!{&%Jdijk?Vr$duhQ~5dCtKc2*XHHB|FHn_HOMXe6QDvOxGa;?8*$IxE8A*JEb| zdcOK1b3*om6?!NJ_K0wsx zb!Ea9&UOIh1gflX@y4}Pw@43&h62Y8!206u|8TmA41)i0y0A-@@K?uK9E=6iQkLcu zXz)?oMl?+-DLi)t)FsfO5mYcJ2orenEQIq3z|`9Ji;PR5lIJs=z62aiKnOb32Gu16 zET&kSbPBFRIm8W>-ivJBC1m?9IoRN~pchfFkVsxiD|P*kx+9rq3yC`Hen4}p*FODQoBmf%VzO@4(B z4FA)16LbDg+fBs!p%b4E6pk`O*7F}eAK1|%PybE-gyog4KKkHcyNfN_y|)M;v0Rm=XRYG9;qcb2lk13NnN4=XAr7cyMMT5dCUR_5#LR0DW%^m8Q6JWBBaS!aGP|S z08xHDByBfn7DOFARb`){l6*(Lj!ylEY>G(nD0A?@IlFXe;tN@a`~V=KSgnJbG+wW> z3>qn(sJ~02Ug{Afwho?#`H4-rkFPdFHcr!n?iNnI{I!ZwjJ(s78l50S$4R6ZYNa4g zyK?d5>b=8M_k&XAzDeZ&LcExgwyFNzKV9j4$WW4^9M~LgD(}*5e=PEPI+vhY!l;Fu z2=f~qk7>8NY-rcGQVv|iTVm*5WzJ4!Qjz<^;TyUB))Qd41nCoCZW8gpo{lXI_Sc&} z&w9XjoZ;1Ql=RNX(V1sy!oFdwc*Mm1&JqXswq_mpF>sK*7G^Vk`ID9n1rkE# z-}VIlHuf0zKe(7$9uw&~dA~sB4C-0w3q;IFNi3>R&POV9sz%kZJy>B3PUW`_(~beQ0mm@}GP~DuxE6xnf(JXuP#I;xj2P-GPAHk0YAkl8 zL|?m{o|0oLQpLZ*sHqV2yX0CvygsCpD zHp$9qjl~`fMqOz>BKw+lV@c?VqDp7&(nMnnY|-w{k`J>YTSU1{gje~Fug%1lo*m6g zXBeh;j-P9$rYKR56S#Ur62NC{`V)1vS4W~&`3qLfEY)$%Ltw%(0`)3VWP$@UI7P8i zro8Pl{aIS%(^SkOR?d!@l&Z#<9Ay>Sdu!qDzbib};NSgG&wS!BKK;`VGX~3gr*(5O9nImmTPok5azBC&2gID; zr?a0oV!cn+!npY%zPx+0rgVdzqmHpO`W`!)0jT45TD!*eA}?TzB*e3&zS+LKyM+ND zUNI%to<=$C1O%iS**CqcS_2Aifc{ZvL4a2|2irHqdZrDIsBtY8&8O(`3jW_4k??5? z)jINik=8xn|;L6jCMeQebcWOwcFG4lK68QFuX6e?^ zdjsdCoCoI^PVj8zK2Mq_SKwO)&zDD*>bx1A2RA?!ho^#B3ofER6+wd}RhTYd&QSWZ zdP{NL)nnhTO-ye~@>QB=(ZgL-=ZuezDI|98?0)i9{G=EIQC{LD~=&83+x!#pWDs&e6O_2NUMRSeg3GMYiB$$ThQO9}Uu zJcUCpk&4%De$Vv2>RpSU&J}u;k1Rz{P5>VFt~A-`U47g5lSN&N|M*(3Y`*3aDZ|eR z0-%L-2EvcNrMBuk8KDd+_oGlQvMaY?)O_|!N6tej^w&IAmmU#k8wGa z#%cMxGt88!#|Eco;tXSXmKpbSVEBMuT*n>6x$*sS0|dVsC}&ckejfq*w8poV6^lo( zLsgi>`!2pG^yFBZ9Ak-w8>11{awdO!Lk1L{h&xOSa*YcblF9LMX7OaCs=yLRiW$8<&UD3leaF zS&=x`b2N6Dhr_G$I%Q1cGy+BXQh=hQP;O~rF@#O&w@g3LP~3>0)eIbZl7=y;O$-2_ zawg5Ok=yJBire$;-{tRz&*jKFUm2W@V^XHYCZdwY3Iw!%{*Hf$Lbd@sS$ho+xtOjj zFji!twJ5R__`Fj=8XERbnz}N33lox8bGW!`)}IlSv*Z3odY0eLUmTMS_ab`cGX<`v za33)hd(A&%`qJU@fHNYItJvnUTE;p}dJd4f!#ak)UnCZQM*uJ*AY(Xv23U(}6Z2nP z`bya?6Xm$1S^~eq$xwVkb*uh3pWM6p+$VprUdU-?OeveoAayGn^ad4BIre#rj;6;h zD%*S^TS>E2?CR{Sa3F6zW!5{ZJ7EjLn?Qzat4($ooD0vML1m|^2f{&VV$VYbzr8Vl z&d#@i4t~wQkh=?U4~WX&lm6$oy{+DSQzeoAt%3G&b9sdp$M#0X%U7y;wf$dy35Id0 zK69ylZqUHV{ezktvp}jT2MrF5=n+K>8{N^K+5E@lvfTh~V00roO4dr;-};u9HFX6-_5$AfXDJaH;{^H)DCGTqej9D6C~PEf=V zM71>4B-s;$v;r!{$QLe&AGY5wE`NfB+6-KuJKaEvOMV*V_CzO3oQ0_$|Lvz1%JkMY zPBXkMnl=Ct|pQ}9Y)48U(|8SoHIseY~B*%d>i;g}AFm$S-N}l!cb@5X#^oIEU=Qb%g#S_*T1^*-aA`dR(nOl_q6{ z`2xM};^*pDo&*-(fbvIPqZ}g~dfkX)Z&XX|37doTGJr@l$(^?)pB7i8n4Xa(K-j|s zg5g>lCV%n0;dx?Y>uuSfBSLdWA^2vqc5U~7Sv1ApCw*Kskkij7m&0L?8^f->DY?~L zl9wSF^c&`SHnGSYo|S47^lVDAL0mogPH+K&8%J(+W)lRwg+F>vY$_8s*-~!P&ibz3 z<$WRGcCh%pZ^`;=C}z~{^W=jnU+x47r)GtN$%kP#T9jV--yVA!NExBErOIP1u2Qr4FKB<>`}^PtVTzKkO{Lg0MSEvzK4W_SSgg9%4H+`| zA(M$~5l2bftG5w0fxK_3x!+2M_1Qj^S}TUlNJdAMCuMNF{E^|VZjA zP47}zr4De)s&C;Cm(1GtKQ#SO6Zfji7`_l3OTB=NmqyZ30r~5sKFr&t17YoEtG>0e=d=n>ud^` z3BXa}4SDZ8|R%>3(JVsVrA&x&8Zzd%MO^z2|jg`n1Qo_ceiHy74A`ZgM z-sAESL7WO2ZTowG(v*59XWchp&aWF(P;AMO>r>CozKJISU(DEBeiuFqY4I!;3DCGU zB9zYrfXrH11XiyI{?T|#s&&~wa9+daG1@S7JjDu#?;>?|R`KO?tlbbE+1gefl(Rvj zM6=Z~2*$}A%B!?%LF(EP{&bBz!6)gdOW6WWE-Bs#iI-j)$)2Ucf=*~C5GR)m!Hgvs zh$py+DzR2!kFYxj(yIA+g9VlA>qVU{E6>a z<^Q_BfG#Fbzl-Gl;yD!#C<(bF_cu{AmXgB;Dq%}u+&;cY91q{p9XeEoM|Q}zD)x7G zqfvufk`tIZfSRrZB!?%Vza58F(aZ7`2L@sf`j95ElZU*`S$gR#VD?!MDZixhh&N78 zuIRmv&lbIxq^b=D^ro6mJyL&njPg=_4BAtzZ-9U3+&j1yBLu%-cqv7EMPV?klO}>O zU=*J!GBEgJ-|=yduqq)YJ_No}Iz=%ACTDuupiy^oLZ6pKc-sbl_lA)fS4s1{tgbKXtCBY|{Zr3UY*=AokAy|~`@DEvo}Sd#b~Cr`zfJh?&Q zep_FE@k9Q{{o=F5yh&Z7seKDd4vZ-yfz;z1KmB9E{H_cRpq1(#|0n(;$8FfuErMES0Ckn2vvVMw1fN&LN#CK1o9$%!@>#+-p*eTw!mZh^Tzt3ssoFU@r1QM|~9 z*Ccs%xOX1H^j6P583toWc>??3_G;D1yyws|CzVR$yLbjMfg*1*+hF1gk3~stu}R+m z?+{x3g^}r$kyg`!RCc;dMM3Z3Gf?+iDyDbu%m?+$Cj8s1W}eFpagW$eXEDu!E}F~ zWh1OAXQGm2w>GJAF=dBFZhgSZadpn>$Vk7qM-BjX|0p*eVKw*!7_mPEs$cp4gO-iy86l zeNt$4(;uOcvH=?|Y^e}jwYF_HEo~uI70}ELfc`OWaNGfVT*(1s)xrSi0&0JeU_1-6uk(!)J4=jiXbC`vBzrVu_>luR{}i@NR_r4Z=j`(|?<8Tyiaqz8{|6a4p+%LeD&xUh%){ z8Y2TLUn`)%?cI?9(H(gX%zU{ayl2Z4dr6{w*Qo+n#X;6ZyA?YR$(VeMM+QKI9TM&P zEY`!J?lasEpeB5Erg2mKv9q_g1Ehgo>ZPZCm6u<6@A!rI8+Fr`m;8IULs2tDJ?Xkt z8Xo;Ps2K78F!Rls*(-+XD{t!;va!sYVqWXvdGbuLWa}bQtzWh~H(3jJe3HEM>in!G zDJR|uWrRBcDXQ!juX$!cPTOhIsoSo<$HE*v)ln-#J>7ClYi^El@>+zdV*fk;eE%%m zV!NNtTa1S=exHXI2Ig=ZdPP`!mR+m|rQ=W6R^^E`t=hC@%L8 zl4|YH%S_!#GelD$v}xfP4h6#y6A%jNWTHlA()qES-;{Pg zCbfLId@tq`*b-Cws+2E*~UZJlTSEEFSVsp zEmU04!bau6Xv9qcEWtAp-kVBHWCGNQ=Xa>>Ok`7=AgoWBugHa8u-*%ik_)UT zk6)6BYE(sXa>U-U4yGl5n=kkCh~z#Tu}{8b!XABVyjkv?9jdvIg-ZUZTo}c_u7qQV z)0#b{zP8WS(>)4<tFHGpZU>o)PlE^&F>Cl{KxV{ zr^@h8ow2@)I+R5)T7pl7P4H5F_>^b1PVHEi=N-$L-+I7o*zTzqJ6O!-T)7*1DOMMi zXFs;%;4q59+ww=ozovUmd9iWrqJche?BhPApeBXs-*>7$bWA7B*1-)JysbEx)+w3n zBBgp)o;KRLR?*E}_N!@lVSSrLImC3o1x)=&&DildJ^O!DG z_#;z)i|byuMg7~yoPZj#rybFf&OzcCoSqXPacN!>mmr#sR!vDvVes|vzCa5;KIiS= zuOf83Ecv3^Qz^EVJn>LkzCTNcKcx?so_WqS8-~YGveE{lnQ)1E0jwc#qr!MF<%5Dd z28GzzU~n+qsAsfv|2vrbIT0hMj=x*~bR1In{oT9zW@gNDHA78XDj**$d{2VdT--G)+fYH;5p(MkOUSthaHcmYuaWdK*POup90kX*=I{LwFseX~^|D@hoq3(o!2rps9=SD|( z(*S3P=YKTsx>W{ONV|7!oNrgG=rB_yCm=pDA8bw>NkH z*7r%x87lq_)fQlSUSb5@%9p^=X3ChGFMnOZjF~*7{0KQAML@9Cq)(etly|>JG8R$M zsfoNgd^&oqH}$x!jKYFvr*Z2657sp!4SlhaBK%TrQ}TyaBAN5O`4SpBR*Mh8Q=-le z8ub;XP3vj0|F)_Wg4f&j*rrpzK9|dh2}cO+5qo>H-!r#2Orr{E@BU>e*DcuQo4rqI zQ108r>MQ#7$~<5nlflC zd|w?0uII~|Rdy$ndSh}dC4egz2YB(=p%FA5NoRK?eGFQ3{w%E)pWFcU+{7YR!@Kk& z)dIjNAjY+wa%bo9>o8<~TjKI9(CDKD3k z|EOVvfg*3{{UYS@;*BvBte|Iog(|t2O4^*lA;GVa50pO#p_9FwZJ97aopKm(G8yLA zh-YV))IOq3zW}wMnR(LMjMi7%Dvf3&-~bc;`brq;aEo4O3>+Mki`3h3f(n(Ir8mcH zFEN=kimHfQ%0_`_*k;Bgq~V?+Hu|s87=(@(7dRv0aEOf7WPnbL78MEA5FS_SC6^;) zQks+qKOY2{l&0yqKuK-0e4c`Rj8V+KMP`yz%$axn&8|20KtBdF7lFk6RR>&A(z zTyjo@jl)5Q~@@M3}NFNgj)yvrjQZXQew@xg~ z2fYxmMjF}(1ZVs0K)ZYzJa8w_y0~F{Ke+&{`x%FNa`+RFQ(T8@3YS~0*L<91css3J zIhc75JC)tlhfq_u^d1zS$&vzrZPKrNg6v2jQ|i`h|p8VUnz zch{7MQejCy$xiYs8$5@> z^}OLuB1N+4Lp#2duR1oPc8|=T93lc*)%{)^#m3oSV68LHU@Uo6f|m6%uQcB}h>>{Q zzQZ1BukVz9j_^zroKSTpEX7sSE^FbZWrh=u6wR2q-JM;ocBWy#=F*UXUOPNiluu7D z*G%4Zy5eo&UD>`nT>7rtiy}~h(8vZmnl0r_{2%2_R>w4mVq^s+Ea<`)*S zB<{Rnkm94CE`B$#?V0HzGl*#b)$C#*X=maR!N)>dMbLDn)Cl;Z&?}J9QEQra?saGG z&s+GH`0j_5oK*|IN9Lf$5VMhCnaGOH@K#OMoozt1`_n`tGLhEfB|B)<>66&mSn)I_ zNI^Y|ERo@713pj)j#A)U3(zutb>nOPbDJ-AZnvg4#m?iz+jrfgs^)LXzr1Dn9jKj? z`_6O}tFOV``QS*s1r~Q?^SakaYbCl&6Ahu)>06PnHKcLPYq@L{$JR2DwF|&$^hWO# zyxA##I`fcrN@eQBSyOFkdPFH}!ir7FIt}Azg+)!=-TPqrJuGD(-d(Z11EY?*V00@x zUom)jqV9CI`N0p)ys-D0oH=UGn%+jidGXZm+#d`-{B``=q0+z9&|LP8?OpW;zo7Ja zS3QfXXkZSsr19aefcghDa@^BQHPvmd4x2>J8bRwny0w=&Se`b*QblA?a3%R=Q-HkGoG7c?4n(p7Ghh>nNUmTS*lzoCokmOmsa1G*Qc%7%7o;%vPOp1dlU!ydrOrU0j zZEO5lDz=;sRgqeGeSr-km1j8)SFa!n!ly9u0IV@Tt^cO9G~N_d_9hBMy`*s@Q3;zN z1I$W*yBenzn^K=y^+dRpM%cG6mi)%vf|V~_=OXq0oGps*p}}m}kAEvnMO+&9E18*@ zPYr7N(vN=PQ}71{5kok-lNF6hYDge){76Ul zK>`ES&3{>A#1Ylwk4s@1ZC}yvVWi*+{Ipis`B{8zZXF)^7iP#c$r?0%J0I&s~ zM>w10Aap*xV&-++;ng*HT`TywR`YQp-YF-=Y1NW8eE#E6lv)7g5cLv6>kxjyu*A*o z>if(JkkLkqH~_|jVHyDEX9K9oCDtLF=WcsN0zhOrman8xDaAIrcKn@E%jV=&s;;EKLges>P%Mx)4~`^y<@5PC)|#@= zDX;A$ZIw{GG}6%}hf@(FbeuPsKauU#;Awb{ncZ6VszF>%+H@ErGdINi3`Zek2=qzWDF>7FjNLD`_&>g%mr* zulSY>Y_JQ)U=?Q`BJ8=z;Q|i_xDVg)m{hx%nIZREhoxT*M~%2f5ZxizJtK;Kh98f} z9lhim^Vr!0xqj{WVJ|&Om5JI%Tpin<;S_jIX@KqlJ&X-|L^9dsY7xn~*`0NTRCLk) z)!{n1XG~)`BF=s*9;WCd8%=!41RTeAla*pWi{!vAfhq0+sYZewDMJ(rZiPP*{&Qe? z8X!Zlx!Gys)pZ4F_0_#sw`1ItW$3jhv^d0wA3Fr1?6|$fyi8*7e@OtWR3$F5iiNH6 zQk49e=}z36S{{~UkGt9rw1B)qm~(#z^%F=QK+ zR_=b{fK_nCZ7`nU*+2sWn@tk2-My4@g1Iq3yI{e+Iz4el1n;HysT3^yJi95S`xitzj=cQ~Ds%fuf4=|EMyc33W`m|J z+nqH9f8(tuUcbtRz?x(=dt@j6OJZWs7j@zDoPll)x)=eA>&<9(tV!@@xK7%EQJYXPlliNBVU;A@;OtZ45D zhkVQ~ZdkrvK!o=~=L zNBQ3%>39*FhG;<;8}m?_7n7GAw@mRh<5kZLvt-!~;7Ps)YYcV(4NxN=)vvfDQuqY> ztZs3Z4|3u$HFe#qPcS&)zecTdNZ}cO#F_Z;w@#QzbQ8G^Ka7=fGJK~&*}mI`uz>4klMw4kWdGC(~)51XHdEkaPameXQ>}Ra}P~4yF8bI!n9DG6X z%1$ho;QIpH0v#PeB&f}F?iz_>kG31j9Ca3oaBo!bAA28V72^7^Ss<+Qp-j`K9Ru3m z;%u&CV=h-A+MKE*PqihEn;Z66Gps1>1sJR;>s^Xsuh!YU#cZ=XaeNbpC}L5WM|AfR z>hPjht%C;+%`N)0eB?bno9lR=&mu>+xjb{59FFxD5{^K-seuBe^vxNEK8H1j+Tuh= zAYS<1b+KFeS7+*MW_?ZI*M9B<>pC@lW5$XfK&`1B+7Itp=9^U&_nCCnF!avjcN7 z`Rh}!%b&NkoTdEwtU(t2Mf$i+^?rg!QVr<}aJPs4?fbdYU@6;0133AVGdN1EM8Ft4 zrNk-jUi$!2cn_tZMcRO0N>06N~`E5|=2A+|J+n`GvgqQ;4h*WI-tV*#~o3SG4_XD{) zY(lP-kAbfh9NvZZbN>dFv7gy|ry2*`5gI4HQ+{vU4^XA1tb0Ji4_|}lN3BW#x^X~= zgso07{vWp5*Wvn}iO=)%1yF7Gk;pO2%zE{^E32m3;^kxQj8Tq|uQiBauRsjBL=v)VBG&GK=!y!t!cvVBX^arr!{2&; z6y+;~0Nj`JWgTp7XL@mlrJW&jbuRxuN!7$hY(W}82cFSLb%#Cg^c?9*P<#yxRdU4O z;|(G`MxL;X&z8 zm9ulv8G2vs!6Xtg9tx3Tu#mUKU{Q5Z__@wUHx&|BNnN~6>6)}W*I&L&M2ql? ze3`I{`vbN;IMRP4FprJk{24nU7k^vYFP^??w8y$Yq3+u+-`RsE2B{WV!>XfQ&x}#b z>o&jbL(UrDbolh2i#EjIS1JNj5E2gYi!J^Ja3G^vBYr#0qxd(=3Ab;9?#Tx+MzB)E z-dH{}KbIA}xhzJwl<{W*VC_GOZ}i$AiD0ST2yMBZ%il%`mLiW7iQE+DT6l?@NSBf4 zjCI$wiH$6W18q0Qn`Gs#=Hig6g zJJp7aWBiF+qpzbz7&UW^e8&rDIj0#UwAvHNOgsJe!)LYv1;sBd+n-I>h~SRA8CQi{ErB;ukJGT z2g6P+gb%?M{J*rj?Sx}M{h|>m`oCWkY^fyy4)5>E!y4M`*5o|6O(Ml{N+o?Mpm8KV38QbWl0^xoCrc;$U*h;Eq22ZJI1!k= zR$@E?!H%M^iK6v1DpQR5ar%?iOAn5uiX_b9u(O$}tL~*%Lj&tPx+rUd7dP_4gRhE^O8Mb`S;GC6Lz$6YCb4l- zFiL1)`QPVTz^8DIc{UZiNZ|J5BKcnCBCb>}5*Kvzw_v|uEZnI5XBL+si>zRKt@maY z5eMGiFCISG8DmwV%4YGyyCWE=rhcBEUvgl(6C^R|u;3~}90IB%MuhuHu7jwk_SR$J z6sfv3eZi7?H3*bTYd=bplu*;hR)g3riM)00R4k z!GTB>f=O05$VtOf7b`<3xnv(Oj_G_cEckf$@89z(c$^cZQzz9E%wq9HZnD@7TH0SlCgH##x8S~)J`xxz+X7hdb`+ANTQ3J z+($Ig1f@I<&bVz5D_Qa%P5aR#1hZW&&jL6XMdozygPb1VJ!(5%dI=Y%Pbjo<%v{Lx zf>&%p_bR&_OTKhc#(R5qNk$Vt)#P2rv``)9-#!R?y!Koa&hSo(zwJ#YZzA-B%{R4F@ zS>GJcN+;Vh{TkHlO=JkH#a0_Oy8M_-AthE5AsalPI@)ZIsEr!!gJe)(!}%b`zk#y7nMtz*We>5`k^Jj$$$o7-7x89fR%Tt=`Hvf zrP*I$%R=O8f9@yG`m-fu8z1I*kCS7>8u0YCoaLciH7suGP$}i;?^5dEU#HT)Q&Z2);RNJZWKiwUft#lZ^uqF zcoT)kFrq*ZBoUxYj>krv)P!%F^ZblYxx{6W&t*|=1IiyrHyN*3PiZiiW>{xdg=kWH zH!OKHlydT#J&q+vfwiPpr)+@GvVg6V0R?@ zt!WfH@L2BWf*C!ZD1181FmQw4u)l~0_8Oll|vv0+?L~>Bz)R_7PB%Phi?!n zW%H<|x536`zsJKh82jcn$|2ZGZAP<+EYQhH0G`=?z|VBn2?krxHg~!HaN)Wag*2 ze;632qGaWkce+AgzqoPqqtEAxvhWZ{VWCG%UO8u(=ezJPUB4X0*>Eg~-_>*PDUN_oSQP>nDQ1Yjqc{}1-Hh^jk8&>`2h0^|| zWl(dTF7R%w@~`2PknDFa`eN{tq(3$}im%^1`d42Y=drXb%?UZ)e?^&0%w-(pqY8C0 z(&uO|a07pKv;^8;YQJdHSB=?ZOx>f`iP4aABEXQ02G@)38044#?ERf^Cntk)E%ff+ z&5X&H9~mz@h*4qiI&Z^aYSdbxXeDAO`cIPfy+8Xm8*V#ZczK{-u8P`TE=_&B1h-Bt zX`XU>qY#X zy+OzgSK(k+$ffx#EVk-TdJ?CIvHZg0A@mU}%mt=D^*wkN@nPd%bgSKv*wjC2i8!Er z^$S8aF~`7<>``E&QzgKiWG>YpJv9Z&MUij1z!vq9T_}oJu3fukkD-8Fr!k=Yu|vB! zg>U_MX)EPsptzq1I55-N0R9hfjX?2{$(v9KyTBYqs4p{7@^R+GfZIkem^T%u9o8Pu zjDn12M2e$@kFS0Ga^*?lZ@r^;Z;#qm#?ft+S3Zf;=^u+?0?4^X^78{O16-(8X*vvO zNbLkV_cshph>I~3C_4aIddQE$Q!9RBh<6b_sbsiM!yF&C5jf=y9r+kIkmN@xcqq;+ z5yx;T`IM#Yn7b57!~G3-n0dJFwjY|r(m{jbKW3UXWe?j}vy*UJGGxSo*Yl|iCxY1d zM>G14uAU!HavAv&YJRJ^Ty@xqxOhYV5yeVr#tD+x6%+S9$}Ey{!TcS%%6Ni#@Wvhe zmP^)*OJIgE3+^NCL?i0rLip+?kjmY$L5YyyUCd&&y>9FyiWAXzxsnh;1zhXIAj4aD z^<5BiPx<3dHeA$xV@C2@HTV>qj4NjrrV{uQ&3Lp-xht}TOtbv654m!Dadl>+Co}>* zXc5IYk|GNoe3mSJB0Oy-Djl~+3=;izpTYS=^xN^@-XJkoa`xI2vHp{P4}!0?ycNDY zJGs{XRtOOiQvFt()?9=efLIwzeAqcUJ(l1%=jN-U5^TFwa~~~{BYABDwf#);a!^O* zfLnb|ikk~*Z0<&NOVV;qn%?E^(1!G7qV!y_jPdt=)V@rUyVQ*k*?V&;;_KIAL#(6c zWKztf_xaK?%`H;R#fw5jZ%?vUBZQsd9xD3#*bj4#8e#+fSTe z-*2igwyO#@e`A}EX0cHF{rzBR4tJ$pjrz1a4zDUJCHIe3gE}|%Bv9jx}cPN#8jT?=%o6%?v*KBxVNkIG3($1*pSsZ~eV1xPwo$_Z7s z4OJ>T#pLHo`C8~9a=ta@O0w4Iww!A0hG^f*(d)vm_O$h8ixP z>f&Od!Y9(7qztxm<>dhgSFXmegwdIW=CY_UWr)F~g$b;q>knG)UAqZwo+2|6(wQT7 zOlNj2Oi!4=_B8R*PZwL|%1hKg{WF3mfO8}9~~EG5`GEIsKtdEQC1 z<>*54td?`_FEDzFZRQb{Hq>g$e?zakhuP$uVb)syihnoJx3p!?z4PPH=2BPMuBF3D z5P)n*D2345J?${$##86sx|T(6|2oe`(@ei$*8a^q2N2%&l{CepGlzpSOm&X%`*)59 zmKg@^yzyZ-AqyhncxHLD6NJGTM6g-R`*$ksOe^C^neE7t??U5Z`t6OgaJ~y~-VOg_ zCus&ZW+zbe8zYG$R~&;oy_Lf)30HF&ckWKQo?J_Ze2;JRWP*7PO&uN)GMswtt`$da zQQ@Aup7z_~UWry-@8-nrwYq05co&_i|IN_5ZR%JSZdHcVb!c_|)$Y@jZ^e6N%^K+Q zde(O`oC}_B&k?8_kN2Hk@E2C|W@ea3ZSeoN5Wo-ic^t0uTgvC#g3skK%5yWocYNX2 z6dQu|o|iw% zU$i=pEa?)74Eksy8c|jd&9CM*+Tn)qiGEUWTQS)E;LuR0E97}W3@z8KE$|TRqK*A-?=s%I9S-8M4tTeF_dDbN$KGB4H5vYW<3E>-9z9A%cPO2X zPU#q>13^I$kP<037%);$8YHAsLZo#d9fF8R>QE#U5D^72`0n$$?(6>k6Zao*?x*8% z>^$G`eBoL2Lau(f4OzsCeu(}i6~mlQ5FShx<7oWQNiFL-emSoCmlr3wD04!_RwM_@ zs>bVM@xO4s$#r-`RKnS`>gW06^%T{FD{6uk@VF4uIFH3d5OC|o&x{)`iEj!hZuOzl;3 zRqMKY$Br}{k@hwM&mxg*dOQ6iis1Y$7Vn?(33X36F6LVPohPV_@2Jcu&d7Ey+%7g9 zqJA&=sS@v2I)N*zp%ZdKhP;e0c$c3n&`m1HNpVt4ljnX=vyZWOohNw&*v=V;ZXJOSs#ySZ1)y7Tk6 zg^$LZgsXE3oD0w7<9rAa2;Vz}?Z1SCx}9GQXI^qHI$t0iSD^Z$EBA#u@%Y5i$q<-B z6~FqG6Ow=byN_2As^sghQ7JretNRA(b;&pGGI2faZ;V#U+>n3jWo#NkB_|Ixg|8{# znKA3d9H)uLr~=R>JC?#nsxE^2ra6W~H<(T{)e9^AIM}DuFy~w<%nPgJZMA#5-~PE% z=~`IL=vi#ctzhr+$gi+QS}6M$?%|aeWllXcsmleg9c#bbsZK4dYbYqSv8(1StON1n zdAKOpN7mK2G{m!|Zh;%bBO4$~$tRRY?Q#|E8vmhbZMo~-3sok&G<}S`#D^7G znkT&7L$fp9)%4gYSNcOovU8WdYiZMRSDKywsRYHDjs%S9lpXha@B3*dhv+g>PR5pXo%bB?c&j>)zQ0rWAScdNyTHS zt5lkH{DIqeUh#O*>Ub&NM1|W#P4Ps->cnHd$#%EN&f>}5)ye04Q!m`6MvJE=SEpw9 zreC{Fzb&3#S)G2*_wu9L%dO&Hh=X!TrZ(GKLp$fPtz3kVSzxFRQGM(=2P%D+_ z$MG$9K0l-v(%a*<3HY^B_gHT5VCw2`tQ^V9eS55PEs;$@T;fJs$776zQS@>Cq+?CO>} zcw-g|jac6?s2yZ2JP1bfJpxHb7~tL@8B$T@3+UVKhMiYm;&`Qwa#&K66 zjHFVsoSfJ_4+m@6ln;@21EMRMe~Kfx5$6+1ippWV*k^{wZ@1&-uQuK2LP*Zt5_fm| z$R$u`;>N-n=B$Jh@@vzVxpph#PNPT@Ykv2|xZnp$eU-@e7Wk)f+wA6G!OfO21IFF2 zIf~t0!tH>W_+Xn+_G>Z^r_FP*6Ee-EOaeN{G#7nsAhY>TGQU&Zfb~CHgJxba!HoYx zlm+fs1Fn(oOGXMGI8p%uV)MSi;$CpL50sAkuf(X>Wjp=K-9Z%(+?gecOpZ-OdkB>p zTcBpwOF=(Axh@);%et_MhckF+eEn4h>a#A=Ik?V(x-}&y0fAU2w?O% z!7ytP5@}Ifj6-_^G`S6{Dk7Bb8Bu&Fuj~CRIq+jcJm``yX6>33IpSzT)c@ER|2G-v z`x;vBFHkYkcuKVzTg)scO_NSzA3S~tc?V-fubxAxf*?o{2tol*k5U7X6!xLSRQM;k zw`@ZW3Ut=9@g@u&h#BRU(3)PIM;YNQ2@cn9kIz|lH3#Qt|JjY?67HM0=24{C6d3-c zll0}>{1ahIQO9&&>yqjxkAL$bKqtRl&%`jp{M;>}%>L_815YqHMsjyHp)&jeE#gl0d>Z<>!!BE?f%2|^HSl=o}f7=FOP@( z&9X6*G4Bl<1xx5&Dc>cyZsUr)$+@xn!NR(}*QF!6N`mxM%hs8wQ=#zfd2&tf+CzGm zh5R2)^2YSMTbcI_knU*NXzjL(Q{Fi&ch3H{|8?PZjbn&->yvNzy!&P@BbO$~dfz~2 zzMSbc8Q=cCLM_xK?M=+Y;_9XCFLYOhz`QSjQC8Ybh4edf1J9gyBCjFHQEL>sEBMVY z?zRiz`$46=Dqr-({|j!W$2|yXVoL$HQR0Kyz)iYvOzMp0k4sxWraOPG4v9bdV)Ezd z02`ok4V4LCFcA3Xpp%Q<2fa_Yj6s*M19XMRD^+RpFKIeX9cf&z1hw()v3QVS8DHKr zOXw&;Pw?XB-hbca;RNA2`+T?EZX3yfe+0k9AEb9CzRYS7{>>pr7ZM<)IFJJw zqKpB<)R2f4L?}7tofC(vla~PAm$}RDnHYh_#+fjTkfwm?@_Fi=U?SEKCp3)T1T1b1 zam0Wff709F7@P`FRVoSaD9(jWjPLvLAwb;&f0Xn&r}JBAp9(gAz?0%Y*6g7hMhAA#A%)BV4W1M2Gf_&g5cvFt&=pd5Gv^j?5{`#jwLn<#S+as)cTB+A)_sB2Nb3b$^Vw+nQ$a20ftRJV z+jPzC3Qp{tTDoo(&s$WMCW`2VV(D>&>DNLMOh~2xEk{9;wQnXz77>iWJvvDiB*R)M zh!jL7Rp5h|vc1huug50wM`YF>Wos$GSi4j77PD(F0Iev{6Q5LccWN{hA)EyenYjq6 zE>GIkKO;uHdUUCV=;-qf0uJ_fsnq`LELT$%CVW7&D8EIkXUS8>f}Cl<}!$)pI|TTTg#1SwtmZ zQ_2vfK@g2Hi1;l0*EJTDMy~f#`QUgyYdJw5k>h}ag_DY81@n~4GPNS|!f%MTplD+5 zq*}GquAFg0nf}9lmdO1t_et5xH=KpKqgdoFpf)gZGK5#KI@pDj0%Vq8YhmXbSh;Jp5JWvh zwM-UaxGtORPLAoRnC<~QwdXz-4;3z`5cg%fg@@(x&{*qUzc5z9qYI2Ucoms8HMi1q z2G!RrSGHQ)Do}#v@%T$X5{&_y2`W`82-t`$GtbJtnViH)VejUlt+@k!DhZ=1pqtwb zM;a_mzY2R@;HE&P6qOTQ|1h9g6OC@=glXRf$w_uD3RJ@yvX+@4 zt^oN`3lS`)kzoQ22t6`HD+ngul5$6aBc!Y2_F{^k5U`!{AOBPG*MIy^toeWZ z&#+D~arVxyYY$%h@N@qXO${NlEMu5$vD>0BpQO~kpdjezSxiX)#TPKf*77U?H0Jpi zia1;*YuF@-%&wfw<29KSxFV2w7pUr1@4Ob(nuj4>bIzCJ>XFn1TqfI`C~b{hP40uB zB~wsR)PEGvPwM^p<-i4WeCR=xTvCYYnX^ZQ6fbb>#zuk89?)fO1vS&%N~O@f2zp!_ zN#BR2RrGK$UF>18A=NwZ}oUVZC zU-(1Ov^S#~(-s+hr0X0AnKj*g@pSFNbYe^`_sJ&g5DZA#x5QQuK~#ua+rpIKz+y-y z0Zh>RwZ6D=FD`sy-&243nrDp0jB*NBO_Y&bWlZ0q=wBRk%L@Vt$^C4gRK_5HpWLIv z!0P6bCxRj0&gxS>pp7L}qx>>ZMTPL{nwv6ZnzbqP$!(0cKvD-Z>1s9C$9wI|2~(0; z=D(`kE&wJ6aO^>a3?C@xEON{?t1EQ{%2VdY^%In72B99h)b7Wjal{f@u55^ii{n3g-d4D8Mm_s3`?7l0i@YJf90q>9{cO;4N(N1CJ+gA^k>7gKob7|cI7}S8DZLoP?qqTedCvr2p&bb^@ZbL7F?%4 zy%?TGBVxu;u)=%Xo+aVKKP*`Pn0Is(zp67Hrt%1`7JVw;vi-X|XLnF0+v!x{)UIxd zbV8rpbx-L``?XTcYvnz)~C@yd;1 z7z?kyM7Skpe4^T$ET$DO@Zhu>=YH&;JZgMZ*`;u+ewWJ{qRAmM0c!A@)SP(Iv-;{T zT^6Tb-krtapz~8S|HVePb}~(TG+*RCPmEbKM5Uz2Qs)-l{=uzu&;89Nhl=9G?|+clU6}Gn%ytuk5S#E>#99j2snf z?<{w?lxnld@XQJCz4|Q;{OujqaA9TlPm+`F#T;f&t7i$Id!P3U!pTe6%$K@Z?b4F{ z_Gbe#hAk!UCRs3z{_b0}ja;;^J}sMohV*d}{kcIORUgY8yXPi2_1=tWsN($70CxQY zoPJ@6EEw+HUF6pVX5BhDo!5A6Gi#gTMf?X`wMA|P^&5LErG8$sl)WoQf%qXy?Jfo3 zOvX#Bz3Hy4Fk~Pf_Tl~}jQ5M()Yc++do9QvJm&Mp-cse_jroscIxfrlhnI#Q-*WL8 z%Uf)o`T>yj=HR2%go;%q(5sy*qD#9Y?x?J>Qfv!XY)hN8@H!Otvmj>n23Tt z@1jcW<4Xad|Ez+r=}}odH24;gn8`~G!`8eM&Tn<8FXJ5mQBk^iaqG@$&0fVr;Bbm& zS(ZI71NQj_hf?Mpex1s&(9LvCZx4z39KXlgLU_Wa zS@OkA0QBnRqg&*US<7Q1+8dcJUoZE4h5h>qwaHAd>`$?R#md^Sk?B{xOdM?%9nk@-e`V)3 zdRU%Cza{S`)L_f+)Ys4oa1Tp%5_pKgyybWLTWU9!mncECT6 zccB8=2P#)cfiYbpZ0Q1XC;z_SFCq<1D5_Ud2KsyQ1l~deIv(6(@jL7OuI&S(2>kZV zo^zp}zBN^o*c>k&1Z%8K;?AGjbSkIkCO)AfQXc;c`(4}<$l?ef#hdLx*0YrVnv`CP zv+MdK7E#Me?5hukY23<}y)f(J4-gD08GMrDkGvvqlV-1OYlA!vxosKS*}3XLP#h-o zn~g|yDo0wh3|P=)<5DgJilPLSy?70WLm4nBK>(PEpGhg-<;|C&2F8;5h}j>0x>byA z0m_)1$^Uqk*)s$>$r^S<>%SW)$ZqXm_xV~WX;rkHzFPu z5%iX)aOep1K_ZyQz>aXy9~(_6HN+`7SLzOgY^%Z05eG;3l-g^zm?MHH)b|kxImt?j zLZGX0^S$e>K#hT}q446K=fJ!0#8H$}JoAhg*eJct%ei6bK(2;dtOpvrN5A+AdRS}nv_vTSwheQjA@mCuqPV)Ay&Fg z6o$crB=meRmLNv54|U}W?*fABEtIYI3efy{Tt}yYx9Vs4&GtnbD&rRX=-)Y?6j{|Q zGxLU~sk4(O3c|F^rAfS+w_5qLQBfv9}xnLzOWg9v}7?Q zmov&c%*= zHn(zwK##;{`*XkB{7PbKzIeE~L9y_^^6ad>j%ncsw>T6CmC~s(o?GaLABiM`;NRxV_h>G8 zlR&zr9gpU_rN2i!LjI$8e(nG9?`j%Sq>k;8^;fg$l%c1aV;CmchDVAV*V&T^5wySt zdzy50#C@oQIKYAtd$sZ5l2Sn>o7H4TS^MCjM&CUB{!7IA%VspedpP9nnkyuD1Pm%= z!F;GdLl++k!m>S}X1W(1U7*)%3H3OYr5y)DS>7F4y$mWBI*y2iVeQuH?;Tq;(v9go zc<$Ta@H{&GGM~D~ynTBbFmmpDTGGY6)hH>Dg*WCtg1~(WR~ztv2G9zpWsp0O2HMJW+kL!P7X1A zn+KOLivuii3SHQ5n~W0YOPCmi5PIwbFvGHO{gf(#p^~8U>k4>#PYe93&y3E;cq>;t zLZ|A9vD-CBMa=4JLR(C$=*o*3$AwW=rdBy+WU#%13VYo7Kf0_;HUNlmEa7(A7)5`N59eV=4vusBi*XcD*Hwu^}zO%>I6@ zus||-!9q`3L<^k*0Lw>(6~I*j1~R`+%U?~yUan@2d?96v>UXSeV+_uv=`M6UihmK3 zGpha3R@nT5QcdI8z&-bqB0+O#Ssc8#7@qxoW3I+c{_-&=sX!@r51PJwhk{N6Bs!x zF(RKg%)cvYt7`Vkie_Rc_tu3_!QBC79vIp-@K=(Bb5z|mujT$)`v(T^=Xtr1wXcap zH0Q-ImT?hi#b49yEa5nFw@o3b8ElX+zH3oLZNch(bTeCxf(QRk^<=yJjH@!)TuHmb zFQpqz=n8CoUDqNxnGm$}hG{-fA~A_cCPX6+L%uxlM5HQ|(aL9j*;U1u_f z^>8A#Er$8b7Cv~@Dp`sJoUx84gviu>Sm?2xW>XDHO~1aWqB^_ERGKFvxTB=9(4L?W zT6l89&#J4HnROo{t>_;Z z+v1tZ&`1aMZ(U1JBQHSTn!rR}SxWS;WdvywAn`8>%v#?lGa%PLS#+smYLSvh{2o~O z#8$>?rXGmcK}lqLyrUG;b;SxGlD?7LGF0y3dS^fW!C>~E%22;op))A{;w*)yS%pLV zbt3k&uQ4}H&|C`QXnD>1dWXyRcNnX~6|Z>mqH9-X`)&Ozehn zc{i`&-)Rw;$*D>Pm0_iH7AGLv){tvy1sqi088+W&hR}IM;>})m`w%h#8at7aoTBn; z$R>xL&2y?c%R(N|pLSF6cAt&Rr=?IYP~?J96=vOf+HNxPaHNy#3h{h=q|>fZn=8RW zcU1&^{N%3vd(+U4QSdWbNNvjCrEr&bko_^<5_0=0BU#w^WUY_IcWR*8W+9fqbCyS& z3LI)-)^7z_MY{yY2S&%E-Xm!=@_v8OVq8^L%m>M+y}R|yx|!~SWo^X5{NgVuL+bo~ z_1h_}rK!VdW+{Zcer~!alvM#5XAoFxW-ie?P)B#;=BtG`|CPCQ&QUf~yjY73jlqfQ z=ZR10FK^^(Cfl;p^Wj5L;~P4*T(5ObXqBCpZJR@sDLuK*NZii^)7*w0e(-0$ch|y& zaQz?YV@uf-JNnx#atI%*T~MIjV3&JUh*%i9(UmzO>OAc{^{=|lP zO)gJ@N{c1kuL+Ns?un}nk)N;NQ4hr=)Wa5kKLu$QH|(PniVH*|$dE|jROk$|K6UYu zt2fi{mZC{Q;bkaS(7h-*qAr8nAJPkM&Zkatl;eBf|JweAkbwxwHy4Y6*O@;QLd&Xe z)Q9EaH*>VEi$2O${#d-laVJY$U>?->qJD)k;l8kzptPQnqrnKd( zCC8uBQy7ltzJFK<-09>0*25H1hcKX*3sFlsfo-PtZrKsXSxay1;9bohWc}{#?-h(k z0U3&-#Pw2Rq4vk7&nSqB->448sk8}*NKXjjbmC|b>euL0l{aK*QB!spSre8(v_3M z%@7^WE&{e&@|LLzD~Ms2P3tlQFNx?Q^J=5#^i?0-+w;ZK_&hi_!~jwg=c`13PX;t5 z2jg2RLqDER-yu#Xt6DG&ck1Db2OyTO`E9l0RD%FMIvF|X2S)7e^u)&fR`Qfd?|bRg zh+hy-+_SBZ34%V{E>pccy7?EO-9$kxPBV^szq?))iC0nZ@CFvAv|;0;6cGNY5W5I# z!_di!3<%qEN3&{}k|twfOh?6(6Ll z@3T%oND$XP^5K}F>UoIMNy3E|wPDj#MKfIvEh8+#;F=J@1y778JzzTNSL+%R&B_IM zkV-=gU*{TsHgu<;1}~Ce9C&sZ7MgyVoUzP$orTarG$jw|fyTHC2{{cUpjaeB*m{_s z94C<~S=M-AR9|uDb+e+`#rW=&R*_QgxvBTRM}3?Jc8kEU0)k6EK@vfjWB?`X=73Di zCx}`?N0OOO5aqUn5~YjW5v=9k?kkgp7}avmN`pW~XksRv#fHU8Vh|=)agv9n6o!f8 zFXM2Cj^n3Lo4}C9c_H;~O+R1#jm&0iKQ*1Bf)GKr<`eT53=_C7ERa_dk_uEX75ZB1 zk{(~*WofZ0YjYVIg!K*7DPX zAPjipL(VTfyjmHs1GR~I0XY*P0nMa3+0QLE)L*Fn8sFrZsnQbtsZhrxVWsVzVqNiS zRjuz^v`tnE(6nJ@z-sF*tVOG2V`pyrOmO^R!~DZ9l7(Ng!~~)HIO~+4*)kBF#x`rk ziLKqk9`q}2u@kzpuJPi^m&(I%Q2hft(&CJNa^Lguii;#g0h>h83zk-4=hpv-%H|Mk zwH?CWw3&YFT&*NgO~s+9aaHV8!L2C>+3|%NwM$XmKFN8AnnXxE7>b{#Ug~PKqY;;| zY+4IPjdVLwSlu5=XWpW7zghs3S{N=Jf%Zvcl_2=Q;xZYR)No+s<<~*J*hMywUcOM7 zPp*thvNWT^2Y+yw;bQoj^KjO<;3Lx%WGUjn8tH8@+KAt49EV`>OxxJ|2$>5@4yXh< zmsEhmWO?}XUff=r$t;LJC{AeFQC-)}vzXs#c%~vh?llp{8ssve2+exPe5OFOkZ?xh zz!niqyp4-_Uib=v^R=Cf;9-Q6Gqgw+T+A<4;=cNh$6{lmAyLhWF5=CwLGy^nD^qBN zy2sM8gjy38zz!|fUA;$#b9vPy_kVQMAmab%s3z7GK0=HBbI!5qu7jy#yHR6n_?0u( zF{l_u6NCfb?^t0C0@y=cg}=K>+dSIQT`f)@AKXj6@+e-`-Dza)op)h>itWUINYqS6 zrH3ykVyH!bFpY%yYLnghM{kzVb=8Z@x5nM_jx1iV+EQz6f(|s9io% zUkiV|)-~3#8!}LY13!q7%=!K3PCD?dX(hAY^|!JEtPJGc@@{+Bna6tObHY0g^5rn^ z%lqyg8|2xE{r zwi7QN#3Rt=v3qW?j4>DNit!OMLe5$4nd3D*{NA8k>;Uwmth3)kPx+>IXZhO_vf7q~ z2|~zcOUg)N&gPF=P&0WwAX~c)bZ}*(olUvVBR*`1!&0++_caew2K_8ZFv6WmyuuJN z)bB8H+{T+dxOmyeU!L|Ey&t5RR?<(_sq492+VDC6c`otF70q`H@2-yY+af-hBT;UH zZvbx}aOo_d`Of>YN(YU?nl|FiH%Dww?!1deBbdW9&hifDSPc;c6VZGR` z9PriIhg%<6@Mhs&f<9i0KdAVrS6r-@wTjSmv6%Jj@&{ z{g5bdxSmH1U$b_Lk@I~ZM|<_})r1pMd${|)#*RPC{w}*`X*cy3<4jOsV&dB4wH+!s zd)=tY$HD|$w|(oGBMmQLL4wG^w!quTN zH-Pl%P4iQPOVLhKHFME^qOXn*fBq)2_8L~wF;TRTdLFCgocBUo1g^zds3q21Uf&su z`xHdTxPSRR=YQnWa-Wj+4FB<;PY&}78zol87xHK%*1Yzgdp{$Zw6KVq_$;}9(FT1C z^61D^vLiiP2~K>#phA56^s2JauBaKO02Y$@(*NE5&9nD%nGuQD!i9(QT~Pi5m0Z_r z#$puBlJ_sqC8q@J!SinlKJj_r4ep1>`3yr}KUJ_6g^vBZ`R!cbVXRARz>Kr!##?0{ zd0yZXCpiAH&v*UCxbzqC<9?2Eph`}vPrQ=4uwQMo^iwtvEPs&Dg{Q)xFd9Qho(7Ys z9|z{+N9r0?=CzW4_`fYXU9s*r#8`?dv9zN`ii|-IAMvH6#V?GkfC7U!xdPd-U{umK z9o&KZo0Ubk)vNF?`!5+EitPzTFu}LK`DQ?Snwgm}W_O>Z3;g`*7%MsP%F#*@_;T)j z+CIl=As}NF#Ga2A@Vh0Sq;&c@AG!_UMS<8Qg3o05@K)pms}ra@8K$NR(R^pe|JCAC zfaj)Bs-~0Aw1V(#I#%HP4Y_lnXa%U?vy?vz6pop+|Er&x+&eN(I#QtfZ=rTb-A#U2W$KQzn=i_zoq3qlAY}eJ9^$6GQhO%`X$-NJ~Sy}}p9Z}8Gz_0Ov z#)JrSAgC1Yd?u@i|BjO(g`Ghq!mcx=1J!@SR@!~%o`uB&KAoF8NK{u#+3n#ueux@8 zu*4@t?wvv2cIYU{=x%7RIL{dz8-61%^t$-5#ryDdfh^>*2%|0noEaK=mlRO?ZDT&c zYVjVGKJ_|QopZRH7##TH-;UN-9l_49(LuxYfQVJVU(xYfrV_xedUa{@R}wbdRFyzG z7D^QxQ*Vb`ypO13K7!^`B}W1kKebbU@oq=*DiG{$ovLqh!}IZeHMeZ|@TzA}#R$Mj zKdgdz7=D27de2hyG^nr>T_En`E?#qp4||p%mayfy$AIpan`9OElPVWpsc@TQ{ClY` z^2XyMzk8>3&;P6-1g!-KO`QZ$1%m7`TITU-^Tq!vsF|cTnwT-JDc+zEHRCWdpF4Hm znP>mX7KO(P&K#T}7Y{^c3GxAS)t7?H6Bl#^LiK~Z#aT<$Ou{c*0jG_wCEt#mVE&sn z8ohgkBpn#u{PvWE{L{4nCWVc&JO5k#gneR%8w~uYqOmYV#YL$4_EsD_%l=^Wz3n83 z*M59w2S5nsK@mRGy=DR&i~@YN4+MuutRUPVbp~uCjYla_neAReiCLrNW9z$w{-^Wr&uJ?YDjG@MQU03)mDfX*>x*QCh9rCCZKKJt z+`eK&p_J%g2$!JS0y`UF%Eaq*0YmxjpD*`-dKoEW!ckv#WEZil;k_P8@F zO`RxB0TUf2l)#i?vOq#+Ate_fG=@mDgT*|jiP((RgZm&9BaW0Lm|HfN$J3#L2O(p} z$(I)Ry$5CVf;s9!G%bU4A3cmbm8?B|s63df%z^`RR9@)x)fcQ%1=DSL4=rHJmm~d% za<_0;7$2&|BUrGjo2J+js_Y@06*D3k3*&IqEg%~WLuCnS3AD&Z^9yk#3(Bc1#Nd-s zo$c#i621@K*Z0cx?!D~Tkm;FL1!q_1dqSd^&L6y!2_OHBY-;V%R2Z;(<&4sMX7+_2 zVu{G|7d1s3RU-uq28UbnLWQs2P7{hIL+GtU@i!&ahXJ;NN^DyyOuXle&r(C^(}Qj- zOHliy`j@`;ED7sYgSu*}HzQ+|kA4Le-q3V%m-sWOIRE*lF?F~;C9O2>UW^#eP>R}l zBAcnbUL(?SY{Ds!(I6;aFPa-UHW3ev^RbKPT#j2!bmQ-cRk*I9XSHnj>D^K^Z>-vf zNOw%2K*HN>Jfpn@h77wt(+X`gpFUo2PmcO0TEX{+rmdoksT>lY!3e@2z=qW%rYUOW z|DjhQE$Zp=!h(gEtZL5hrxlc+M_UvJnhnd4S-02E*!<0+zr8ZQ_*b6|Bk64iO~b%k zj$f`@he(jla$QZ`$;BrUQ>@ZCV);m=AKyZ18a(I?R^&h$2XklB`ZYE0#zq=HuoA=2 zUKCyKReN?szqY8iwBNwZXz`2R49u?0w$2*}Rdv$_x5N)?I@I&2vTagGQ9^y=wm}=u zN=T2*#4;x@-S{-XeWOa*J_PePK()nWcR=?B7>gLHmYGx&wdk`&96eRU`x8te2vS09 zX27Gqz4XKw-*;Vc+4xNRpkT*8La2~jylB-I$5R3I<7GIYvXO5)=+3r>Ofy5}!qnWs{R(d}1y75cF z$)K1M?mtE*j~~i-(5BNf@Me8@7HkSN_SvZ9d-3Gy3#bG&lav?FmgvyPD2ch}MNjw$ z$10m{rX&kS!h;Lvc-dv!Znr?w-k;8PU$<>9G&E!8cy^qgpv`-{G22)O7)%IXKF*YL{k&5Aq^)^&FUz-FXntX|EP163O$92_Yy8@v+ ztiNO{1Rird@R@k^@bF2Ey9*!3)=*m+a2w?I;%kCj*j(A2=Guu zF3ed4gep^D*~Zf?KN)SiIq#Tnz4SCfTzAv(8^Q8yl{>~PIonoFP{TW2>hgCUsV|16 z$_wR=d(qjYo50S56UnKd-{AP^ytMD9s5ie$CFCF z9u$G@WKBLZev02Jj#Vn!oz-O%)9t`rb=gyJOMe74&tS*Kg3JgK&+Iik_W#v|gb&?2 zo-2jhlR zN`IP%Tw*ua+B4b!yWts@9Cw?a%CRCIu9=82@wf=fHqV0N=`x-kFMBsQnl}U}J*kjo zDg6;9wO_YdKV!R>D28EsfcS0zoRueAlDZq{N!LLhjm_+p6o}+O9M`IXiNYJ3A$!3c zv(z^ws?w7$JBiazH*%*kir+MKNzOsN2p<=1y&XP#Wzf1w)4#dkw#@lFq84J|-H%85 zFd7bZvFLi+ls;mkBu?NSMLnM})MLCs9^i7xN|dLd871?NEihA?SL_l1kNEZ_AtArL z(qCv%vD-pACqH zOqOzTZwHY7embBWG?|2hBLl2oOnYCzvriRsG$s+6Ttvb^C=+d7}yq48EA9}OAGa%=aTLxW1BFD@A=19Sn@Q;x;bJ^U5c*}@h zwx@Xq2?A~&vb~qB;Yhps6)jzU^6F;XCrzdsu?h39o2Qssj>AO=J<)l4%qczw!e~2M z!yv*PeT5f{0T@~{;*~#wnM3WjuL4gJ5vn%q!#CmQShDMGvqysm6<6!8&p0K2cIk|C z6j@0pz#9Euedfny{>^#KH(PzHD1PZ2+5iou%dkhV^(0uF>P}NXs`<&qT+!shN(_zE zdyN8KCfd?(f863lbgysY=d^*7HN1cpUW7px!7u=rfEf}?xhZ8E>A9O8?@Ibmm(qyr z-tQzD4Pv89SS-#~&wji^aByz_o#I2G!IuT&WA2Y~&p4y=Ki`?}?su8zu;L9uGc67< zJQ*m=U+0dE6F_0$hlU%pu)RzH(Ibk{s|*3+dxnhl00cf+ZNgbue={fV&rKqb29}MO zOjRgnODS={@NL)Sx_gw1p3YYcuWx6Ka+=%RP9pWdayIX$l}s z)T6_crz6OWUF)A`p^)fO{*o(?$}IkIc=}$VMP>u5vv66Z_$)Oce^A-<(R;u1Z$yo* z>f5Z0|4oRix*V(SSnvEsA`%ISCW{(Cm<(Qsp6Ggk$nbCqS9Dnu0|v1xlx8}pnR12s z#)m(Yv+NYKorwabrH=G>7@mHMc0qal!h~n7@+j*@zLH#}9?P4X2{c!9d2Tjw%eue$ zW10)>(!nt1j1jtrON2gM1Cji7jaa1qtejM00@I!kB zmM!n3703c~W0>4X&OAteKLkkL=nZhbKIEK1StCD=7MNfpJQ33|hc*&A--dc~^jSpC}YsOs_ zWDHXgq$(HLPgJFp{C(Zj-VJ{) zlp?(V7$EThC69QCPBjQ4??QoVbL)_3J%pQJ@K4lc{^feojMLcLP$nN`Z}A!e%`PqW z#=Fc=Zt<`Y5KPTSJ*$#SNsN4ik?5)kOf)k)#Kp`(e|;0;+@Jh}UO>p0+N9fAvPz^z zGC{0YY=lI!Wy)xNB|)t5f2Xe5>sA#g15Qr{0+w|Xny*J4UJDJUy>(a?WO-(Azh?v4 zxE;n-XPG%5Fq`IP zb52Ip#8`S=Ysr$$9cVt7L&Ezu&Q4q?!+c2BUntS=B_|{Zqg8J7@FlSz*2}Rc%i(Dp zlfQT@aQ!5!s(8QbBun(R3K?t-z$ml#H|y$HMIo7^`YFb7m$y12vJ0}L3O+l*tntp^ zk#|)f=_fnXOytbfb>A~<**N*V*0kzQu08^&$tUxBLxK+;l}^caGog!G;t!)DhqrnzRW3U znlFV#v+M1Z@ze)7I+no^7&4Rpz_Z3-)1@39=K2W1+R&{6?JvWOr1vXLa>(a4`%0WBU1Nrn zr^Gr*FVAC$&~0g`@yw0q0ROmJ_t4{0mde7hcRlIQ@m*Zif>_eCNHUcu<)eH3#)#Vc zZ2GXDx9D=ik^HWnb$p%=nsJ}WJ<(T78M9($C^@&Pad<}dnA>w0EaJ~@<~ky8CenB( zzK8fj`$pimR%|Ih!K^qtx z1)7WWHvhTqHB$EAUlXvi-=QaPg%ex^Gdn96pZ@zXJTnMA-hI8 zhgRV^9Upu?ylm63vikVhI4p6^K6~$b)!BEAiv~|J>hJB3u1J-B>Ck1|2Ccs1qumC6 z#$sfy41am)r+e%3=;u)YFEts^Ld%w@b{wF6CG;qJ6Co@k$CUWp^wVw6BO?Y3RVmdq zH{?DS1oo4^RCy%&qIip`ZeveDy%Xx4afSDal*02ihXR*}SU+g-6BFhzVJcBN`#7S~ z*oAE6r^SEx&L<<_+k#osCM#{`@&IEz?$VP18vH(9yB?Sf&FT_G;CHxn z&Q#@fg+SVSew`gbb3Ji^aUAi+WWd?J2fd2VcZ+(JZ?Oz`@h5sRm=1FA8|sZ$weIecXVV~Fy?ZXKioHQZ^3kS8L$8br-P(1}h82y@iY+y<~f{gYI} zl8gnDXkJF{grSo z-~%ISytWXlO%4{{YArvxheQ}`e=`~^*AYJ924A*AzBem9|I?-RN!_kAO@#ierJg}o z^068Y|B&Ux_f+Nf72~kv-)AS;RID`ZhSe8E8n_Z^t2(efj zPgp(wJIqEDM1Y@^cMqUvkpfD*vUH^4&WN*m$- z51gjexQ`G1sE`)?mK*3v1C zUL5v#`iQ5CV5g>)dr!IV{})RMwVUma%6eNGG+Vg-zIv^?u+=}w01!`gHQf8(2_T=^ z;h%Duikz%b=A)Os(tyzeGc^5TJb>vC5f}ooPW@$q>Ow-#Vko!&(MKs|JZ;{J;w<{u zK5*5bH#@=5c5Ay9w-q2*Mfnv{A8^xP_;CrHo#H7P&pLpUU? zw{hsJCJ6$4(KhkI_9^TEbCt9X@puEUZ`jw_)j4)Va`-tmxps%Uk73Tp@pMdD)}&c78F>6ZCS|iD9L|~jsZ2#~kXiZ7 z(cifVF==^8lnEb3v4!j09U2uxoA7o9nz{Kx5W}xACLP9u3qSvGhx)v#FwIk8#9=TX==&}RfrFP%9FEuH;YcOVwc(K{)X&3<-5#bSbVQZ)Wf1CF5?h*jg(k(?NzmBS> zZjrs?yAv-O2dsP?&r`j7E+%pwt}*|ELIDDQeBXInDvyUOA>f{+I&L9c#X<$!aqPR+ z73#w}`u`t$clj0N7ypfZ3K)9mhM^mWZlt@rK^h4`x^!j$8M+%`=#cKzAq5Olx&#p< z6ch!MGvE7nYMn>t54a!Bvuo{jU2FE*pZ$Kl@i!XV1x6d2@CT3rN_<_E<7CoXSsLF6 zRk7es0b3*((tZk?q_vv3-%6oyf^As$+CL?g-GCz!tzi>-xBPRA7sL&(1u*SGkebua z#3BlE!IOMXW2yB8f>Uv*3|&LvS&^Qtubf*a50R1^V*Q}@QvV6Fmmj?_Gdd9V>cFml z4JAR1m2MxX=ajy0g^0Gx*`ANwxE|!rt5-~c%_^YAe|6L0d7qR`2oA@p5jf)j*`WA5)W={zEhBC)~%|n{m(IqJAq1Xj9xbleQpG*L)DZX zOYao9Cz;0}XIGqK`VMl8WP}`YG)fov%F1&aRPWg9X%Gb&bajt@8G8jqLH8Azjn}uK!&8 zwW}q*n|sa+|HjXrz}?p$8ZA-Cb_e?0Q8Y(nqKFVs>UF}`d>Azz%Pf|!(`IC+&XlbQ z4qsm<{`jhF^F4grOz}z=UO9et!Jw1rl}4pS?AM?z5<2 z7MvTAh@2_=zng>mt4KLZx+v41RG?Q#B4#wq(-|$x8VagQE+~b-W=>-g5EG>vAtNA5rJIBqNDnz8ZJcNHfit zklU=Vm!|iL&D4V2xC1nhl*gR3qeVCpwudN(`{tB1#~*}~?OylEJqefUE~Mz-siYWw znLibq1K7uvY#ZLW!vURQ>?)#i@p_o+m-kU_W`GV7scLb-ZT}5qJ?fU;3F;O(N~vK) zv}f}X2%=_XO?1cZy`{kdTXaKNk#Df%SP;Zt_1{VrTj;C>mQ~2ni7~2#v<#JM_S1+2 z-7!P^N3x2Ou2GH9v@mAs95^rKV@0M~u$oS*g^4yP(jGU<`s`87cFz9Ebz`ZVD=#lc zxQxj87Za;Fph~5O^7hg6!#8s<*PQK%6j9FNSF{(FjdlbAL>M92R?eVWdp%#lo{~!X zjwdO|*RzJbGkPulmbn7m9(JFY^}!I%r$$|dM`KO-K!{;W*mu*w&jprkYl{hiPN&?8 zLN?AM^qo>txR_t|qA&BvZNmibdr0z3Yfg@~JH7Xo6K$uPvbRbsvkCwcsTSluY_6fe z8i9LNSKf*Bl+ZSxsXS(S`_fn|Cf(@$g9i><-Qs)2y@>%jRq`dkP>;STY4UFy)+nzr zg4`0;&(_0?Gn6o!!S@8rHj04m7h>?ik7VjTlcnrPE2%r{kc!Lq}5pqS6iK-1kdgOLlZ_Wqj4C0aQho;IgQuu zMiNX*dqhM9qa#ld7(2t3oanutOE(;bUL>FCz-mBrYW}|IYp0B=0%3+CfZTV}_|g-` znZ!=_2Du-v2|S8K$zTp4x&9RigG-Y2TK7QFWmKeFoz>9|>iIKDLND_Q-2qc)JuuV4 z>-;DU-NwMQ-5iT&>~_`O6Ov^=&uWMuqc2!kn!v|pbZ_k_X5-jJv@T_s6(6k6J6T`V zNb?{&c?RtswyLIcE^<+60bb=zWqI#@(_Aq9PF9H+)u~rUk~(6aR~1MnIXn9JY4JBa zAzT2~N}t}+nO!T>0rGVGN9ZO%x$hJQ0K{CQzAkqiWXKu->$CAJ>g-q~1!f$q+Kc@A zA8ESQ+r_Y`Zs#`0g;uf`syyczWW#N48Mlk9v$@b+yUsa%P6fbS z0F~&NJx?ZhexsXU=lfcxPv5(zr_UdJHC-yH3`|W(Os=N2XZ;}bD+H^RJ5>E$Au>&o z>wfuwZ>zr?CcuwnCX+gF_x+R2>MeBdPnw779Y&!Cnf~4!L|bZPP6A=vP)@@4}j<&Pe^fuhi2Qo!G?A^O^d?*1g+aZb@s-j zf!15LFIQ2Q@A^88@hkk0G+#>Hnz$!LqXysUZ9hi0qxkPI*m#Tn708hr&>^dO9z|pw z$hv1a=W{1F!)Z@6y)|lSH3>-75a3`h7vyI1rws9k6#Off`AKKPBQTFE0X;$nXX8tH zsT7x#KGoz#^z$X-U%;n(60t{f{1gsyxIJ-o*}p!+ZsBKu?+abV&h?2u!1CqxBri+) z?s7=Ic2Ipz@tBIHe((6W@UE}9{;m8&)` z*A@UvyHc4kkQfB)MSf`*6Bja7F1r7*J(IIvyMP_}o7Ge(2)v`B4l#i_+rI)M5Zt!~ z(?Ioku9JNLkN%#37*Cp3K?Wtkt(M4JE>HvvdIYW%s}VYTQrGVW=tTm~-Jc4$l43-K zy1{J;Vo;XPk9!Y^o|%%qS^*^~AxUKClm%QXn?Xr6cS!q8IWGnxhI_LrKVw#{sl`)Sy6B_^;)cndpu$e{^V{nlaDBgL?sQZo~J-tYN1U zWB4CW6&7UdACQKN!QNNZetp2)#U;WHXI@%hGjIp}&g7@ZF;}RcO}ia=EXcf_Wsx+K zkx6UVFlD}5$F{owzss$FnG|SR_{ZlKU^^}{8!XlIiMYi8&S?f94yLF4DgXfhdERr$ zoAVIQ(N^r2(Jms)6N_a!E43RJwoZKo;4ih!dHgd^e5m;k$1--(`2SHLEo-?EZTR|{ zzmf4ia&QXkaTet-N+Rj=MeU$)W1^%wnd?)4v?)mJk3k9J1}A=USM;I<;5MI zMz>Dm4jKFVr1*`K1MKULxmbkThbxoFiMg+DAL6FR7`+dG$Y8NsVXs3_E<$i@(IeA^ z#7Ag+p@xJ;h;T`qy9<09$X8r@y&^JUZ6YC?EBQ(5d%?VYmVuD8M`vq?WJFaEh3Xv> z8tAhH(!)u7Kzn@Az4L39v_{n*B~|GMU6Q9cE)#^jb6_)crm%e1A9UNDC<`7+NqOSh znqGL@)VKlK^@zkwp10}`wobk+m)oUTqSzDmg60G&d|_?D(`9kfZy|rT%cZ=FN%1v6 zTd$zmLRpa?w&pbpg9Q&nO4H@5CilLo zY^Zh{btNFr#f?U-0|X?@Yw+(@e|e$)fK~&4X+>&Eyt_lF;gtBY?(Tyw?eskT?F6-- zhw{}+0%gnPRhIf+EOZ;C5Nr!tMxHRWZ(N$MS+2(oUgUucEe#K7rS;9-A1;e>svCjp zQa&tm*5#QTUNIPTx%{J%3YxCcrLi)!=+N2h0wHiROz09;SEII9W-sWN5;?d;C^*) z(9mFCvtSNc?@KFF-a@XEm4~_X4;p*#iOYtR7C0`@-&ej4sSNiw=-b-IvUJdg`K_2s zb%inMgqg^M4;4K0W03ZeH4pCdW6BAM4@>qbj93cy)9MTHE~HF~2sDWZjxP+$@4KHA z9u(simd+4;WVPYZWtV6j(Q+MqoexI9ALOn?jam;3gRjXA2Zn8e_81IDFT^)eP@8)eO)$+#x}~`>D`$0HH-uPP9oKlV%ro_H*d;5L}6q~?adgg zjdGk^>I>UHTmW!Rcj^#B+FU=}@J6A7F@1C``GI80rfmi>*CWN;^drXfFNH~mi>a4u znfYNrgewNzm3h0C1q39UFn;)alXZEM-Y5~t(VxxF1o%u6u9cH5_%o9wB9mw_O`0i> z$s3rk1}Bxrw|rz*$|Vxqgc z=8v`Q=Hx?7*TY^E8$=xTR`y3^vxelJo1=K9CKO4LMZ9+xx_s{;zwYhIDm;!VnI zOf4#^$9b@^ez0cCE}Qpd-MgqJe!F^ZgX*5>XM*w#oCZa=^39?fMi(~i1;3g%2jP$G z8m(6Aw@X^H1wc1AnPSYB|RVPOG!&Rc;~_4w(S+Z ztt_P-ub7(dCbtMWbeUCyE`Bu?^6K!%bV;)$k17yUo5xbcbf<0vMTTdvTE_B6_H36} z<|;fakm>Pu=+iR~%%927jOmL|{H|2mWBR);o@L-piTPcYf;5Mo+|3pT+g=00UO$4t zHbqW8(oSijJ_eSd7o|1j(J?NygGMaF!h=l_g}&;)`{y=Ci1ypSXZ~xy2X;$4YGZtx zhMu1fb&zB0103uIV_y6$?Gz6TBrPseeRW`9hz$c{F4(!K0LTfU8MrvHt@)VRX)VAd0f zSX{`TLGq(lGCf zm_4|})N$;^)@y>Qp2x%H6O3(9e_oS13@Ju6PUCUPvJTO6TxsjC_I2|Rjf1*+MB>H=tyYq?C ztyAjHr~2}mhMki(_R}us)4uZ4p`Ftg>}TW7XD`doUhSOCv7awFpRbmmZ|zLi^#~e5DE;mUPH>tZfnH)cJU49l;{4Cx5S@Ad+4EoHl^~ z|F=u}|JxVnx7J z2mgzoC#y*h%rA?-i475=0lULD_;Xrq8l%w4KS$qQX###WfX6?o295k%ptRdeWn)x$ zdAH0|ECOih{EK2*yvjdey{VXtFsbC z1ioY_i60OYLnoB}-H%6Ssd0!;t17J|U>Y4XzZTSMYiu+nrmk_pW8Bn5t*IX2x_H`Z zZbo(gnL;vRYlzMIpi*dHUL!4UGkej1N}YItr1$|#7eK{vw$n;l=^o!>#@UKyYO>-h zZfNL@0jrrY*v}U7uVfF*A*Du$zTmaXThq}qH!l^Z@{nDynelqkkiNj9CCxMnWyHZB zryiq~-p#zV5dlHCibw_Nd~XeyCd35-nmswRrqx2ceB!50(F)t^#(v@Vs1h|XARo99 zUMqbH6ZLUiOEQ%D*HI=r0}yPCG>KR70a!RrsNXY%Xj^uXn%VN{GF1U!BKve_S3to6 z;~(x|-DZDCK)q*7LQP@LQ!=gb#KT*FaAU@0gEE&o9+7X`R@L6ur*8|D8MQ z>?5eS(DEPD1UR2pM=3IE%y=A1z8gzyU%UP`!b=Uz{PdO3@8g$$A)52wn4#jE3Qlj2C6gxQ#% zEyX z5h(cimrVt8X2mE$c{n&_o8x(Sf0}r;l*{{gE$En#K`lR<_36ste$OBQ>W*QPg2U7= zBE`)~U+d25ZL@AK)x+a;wfxdc0U*{co{mOO@64fg!uQmCVD#}tQhTcWNHH>Yk!)}6+>)x^FX(}_l7Z-(`J$GG&kDgH2HJx+Kfg8Shg2c)od27e z{&PZtht{tIW!6mIG#}B&u~0EG3<^iq->n}x+ZMnQ3)`yEynU8eB7>qhcWklnOn;Cx z7PdJF?6R_JI{DM9C@1+`hMRsg5R0_}zuI&<@{xV2E;;t*hvkpaIBv8S&Xqs~fNJ4P zIFaFIF6F-6mGhBOCGq#eYE4#OPTq-e&p)cGBXLP6cd}g4a@-`ilVn6FVoJci45yai zfPx11j2_V|TQ)97n_$@U9 zgbGGP2#WyS!^?0GMHn#fh?;AjAmC#t3~he2;#FN>r}KoFN*81u^k`fM7Ni4!WC4f~ zK$>|%nhT&Z5~S>!D7Z%~IG^}Ag1E4qqA-h)-xM`wLoinVh_WNRUlsr|jmd$59>Yj8 zE}}@}2s!7GQsR&9xITJu6lr|{g22%v;uxz7phZ>!Qa9XST4?I_8XrH8ecgv%NCMKD z0?CnpXbg-H2AMwslt$7r??tRXfzxP39`}M6^6x73Fl*|79@&DWFMt6sVve9xn>Fy@ z8n|nZco37?4NWvXP8fApg&=^+d&G--1l}+b-yq^25g>k55NAi^Lq<|PTvXM|{|nH> zhB;oN(u=4LRtfE|W7wflUaNxmm^3RAtves9=o&A=2%&`$l{C13_W<7+A(cL~l7wKf z_8@W{N15fgCp!1vdxy16qili*ocmMlZh$$6N8?8c0ew_948($Pa#w*Tm3xFXh;VB} z_?-)oiwyzG`zNc%&9OpgEe{6iACBvb~6v zVT{vN1yaoe#O0{}uEnY$0VdhL$^sAd-zn#L+FgD$KW-0HA7FfP9K(+#3fv>)$0fdC zBqoNriircv`V$vnB$e|duEzv{Sg=A6D8Lj$Kl&)dHc3J+*SDTZGvbNW1t>)~T}=Fu zmMrRI8Uys@=kWmqs{+*!$tLr~*T(>&3%pTVK!yi1RpSgVXhS|m7{MY>sX`L6Qg*$A zT7tvuBMPqT3k2uE=FmdL_X);(#NQd7oVHW+1`%+;&;0C zCYKK{QJrgHZb^^s-%xAZGGwqYW;Q4+ofs~0Kn@n<*k0wi2UWs>ZGu4Nt_0cqbg6}5 zIiDh>Zvjz<7(NgpPS+KnsTOa7B%%V;X=DT8K>@<5Bv(IJ#aHt$!+jP$dP;PJL$hiL zv9%K#dC-z%r4l;GJRwC&0d)x|TNOj51~|ntsyNawdyuheS}rKLYX-x!R zx2PT+{TSW^ZM~>>L=aM{22TE>eF9B&V94HOiVB?NWi`#D#Wu>|i&!o)PlRYm;9v$F zqKydFe*^BdC4p_K35O@t7K7mzhfgSRwa(E+=4xm=*#@6asR2Pi8gW2O5NV$)*%Yjq z13+iv{j3X4-ZBr($3k6Rg2`jFwl`p2{N`YI-6H{ltZPk3d;Md0bhupZ&RU!PEfp$T zkl8R|%V^lrOPCW-a??8E75krz z34f*{Os(Ww5ba9pTMQzGyL2GPXbd{&hA6BSu%G+VBBP=>g{n9=8W@maK1F>#m;}e` zBy-h_=a8-pEV*QAl8ytNW>N+#6q7OAZTvr0rfa?i3$Wg9fM~Pvas{F$3*)j%o74tp zhWi`;df<{u1xB z7(PIeKM!r4AO0HgpMLyUn1J83UL6ZI&KlWJjM-u#-eCbz-U6O;!iYH$kenc(4?|MC z9pRgpmX54`>wDE1It>R+xz=bv0^qSLKJLD<8|x;K7zUgp%ZxW z)S$hGwAXqQz&77g5=j%=-|4iP*o7<2+JudN8}c*g=)0hB6$dU}0C}b#;bqLS)#qow zNmuQWGOwTG8%$)khD)yhgE6C?<-Bj|O5bQ7{>4LOnu&)ozehFVVNAUtkl0>)^`)WE z_h57XrfVr5OEWYp>=|KcJrp`7n5Gzg${@79psvp9ijCT!IEg#q5gbd8Vp{$D0$P<-Pv zYRG&e8ChhRIKVN=pR6pO(;;r02LOGAPm!D2X^m{tOj;9C%G5U*TzmesSc5wT@qIo@QyU+YK7 z#RhE6@pA$)uuz5h8HsFw-L1e<#$`*2Pr1O)28A3T?R>FX$$b7FNUl9y*$KFkwdqku zO(^dqS(;gQlp9Mr*2!V506|a45wx{h4JM z>0v|Gb~Pz8;ED#G5k2pJ#WqSXp-MKEMLGZ{t3c90E`VcctV%z_9Qe}{XEF4q+>}`_ zVlQygqpR0ZbaDKXmapkYH6umBW_Pzd(IeD_cC~oc()tapX7O8s(wgQipwN6%?^D=; z&Im)@YI~FFUCPE4w!VM7p~adfq&`!cwyT>xQ)&pjN~c!T z#r?u%N?83y&�jeHHWF>cRfqkHzM)+*qbT>Nc^ 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 PinDF|9@J4gmn>z`F9)=SWZkAqCbZ3cBl~)8 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