diff --git a/CMakeLists.txt b/CMakeLists.txt index 2246b4955..49e0467f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ set(library_name rl_lib) rosidl_generate_interfaces(${PROJECT_NAME} "srv/FromLL.srv" + "srv/FromLLArray.srv" "srv/GetState.srv" "srv/SetDatum.srv" "srv/SetPose.srv" diff --git a/include/robot_localization/navsat_transform.hpp b/include/robot_localization/navsat_transform.hpp index c53cd92c7..9074fbefa 100644 --- a/include/robot_localization/navsat_transform.hpp +++ b/include/robot_localization/navsat_transform.hpp @@ -36,10 +36,13 @@ #include #include #include +#include #include #include #include +#include +#include #include #include #include @@ -50,6 +53,7 @@ #include #include +#include #include namespace robot_localization @@ -99,6 +103,16 @@ class NavSatTransform : public rclcpp::Node const std::shared_ptr request, std::shared_ptr response); + //! @brief Callback for the from Lat Long Array service + //! + bool fromLLArrayCallback( + const std::shared_ptr request, + std::shared_ptr response); + + //! @brief Method for convert point from Lat Lon to the map coordinates system + //! + geometry_msgs::msg::Point fromLL(const geographic_msgs::msg::GeoPoint & geo_point); + /** * @brief Given the pose of the navsat sensor in the Cartesian frame, removes the * offset from the vehicle's centroid and returns the Cartesian-frame pose of said @@ -211,6 +225,11 @@ class NavSatTransform : public rclcpp::Node */ rclcpp::Service::SharedPtr from_ll_srv_; + /** + * @brief Service for from Lat Long Array + */ + rclcpp::Service::SharedPtr from_ll_array_srv_; + /** * @brief Navsatfix publisher */ diff --git a/src/navsat_transform.cpp b/src/navsat_transform.cpp index d9bdef80b..945144c2f 100644 --- a/src/navsat_transform.cpp +++ b/src/navsat_transform.cpp @@ -142,7 +142,8 @@ NavSatTransform::NavSatTransform(const rclcpp::NodeOptions & options) "toLL", std::bind(&NavSatTransform::toLLCallback, this, _1, _2)); from_ll_srv_ = this->create_service( "fromLL", std::bind(&NavSatTransform::fromLLCallback, this, _1, _2)); - + from_ll_array_srv_ = this->create_service( + "fromLLArray", std::bind(&NavSatTransform::fromLLArrayCallback, this, _1, _2)); std::vector datum_vals; if (use_manual_datum_) { datum_vals = this->declare_parameter("datum", datum_vals); @@ -407,9 +408,38 @@ bool NavSatTransform::fromLLCallback( const std::shared_ptr request, std::shared_ptr response) { - double altitude = request->ll_point.altitude; - double longitude = request->ll_point.longitude; - double latitude = request->ll_point.latitude; + try { + response->map_point = fromLL(request->ll_point); + } + catch(const std::runtime_error& e) { + return false; + } + + return true; +} + +bool NavSatTransform::fromLLArrayCallback( + const std::shared_ptr request, + std::shared_ptr response) +{ + for (auto it = request->ll_points.begin(); it != request->ll_points.end(); ++it) { + try { + response->map_points.push_back(fromLL(*it)); + } + catch(const std::runtime_error& e) { + return false; + } + } + + return true; +} + +geometry_msgs::msg::Point NavSatTransform::fromLL( + const geographic_msgs::msg::GeoPoint& geo_point) +{ + double altitude = geo_point.altitude; + double longitude = geo_point.longitude; + double latitude = geo_point.latitude; tf2::Transform cartesian_pose; @@ -437,15 +467,11 @@ bool NavSatTransform::fromLLCallback( cartesian_pose.setOrigin(tf2::Vector3(cartesian_x, cartesian_y, altitude)); - nav_msgs::msg::Odometry gps_odom; - if (!transform_good_) { - return false; + throw std::runtime_error("Invalid transform."); } - response->map_point = cartesianToMap(cartesian_pose).pose.pose.position; - - return true; + return cartesianToMap(cartesian_pose).pose.pose.position; } nav_msgs::msg::Odometry NavSatTransform::cartesianToMap( @@ -485,14 +511,24 @@ void NavSatTransform::mapToLL( odom_as_cartesian.mult(cartesian_world_trans_inverse_, pose); odom_as_cartesian.setRotation(tf2::Quaternion::getIdentity()); - - // Now convert the data back to lat/long and place into the message - navsat_conversions::UTMtoLL( - odom_as_cartesian.getOrigin().getY(), - odom_as_cartesian.getOrigin().getX(), - utm_zone_, - latitude, - longitude); + if (use_local_cartesian_) { + gps_local_cartesian_.Reverse( + odom_as_cartesian.getOrigin().getX(), + odom_as_cartesian.getOrigin().getY(), + odom_as_cartesian.getOrigin().getZ(), + latitude, + longitude, + altitude + ); + } else { + // Now convert the data back to lat/long and place into the message + navsat_conversions::UTMtoLL( + odom_as_cartesian.getOrigin().getY(), + odom_as_cartesian.getOrigin().getX(), + utm_zone_, + latitude, + longitude); + } altitude = odom_as_cartesian.getOrigin().getZ(); } diff --git a/srv/FromLLArray.srv b/srv/FromLLArray.srv new file mode 100644 index 000000000..4a727e0b2 --- /dev/null +++ b/srv/FromLLArray.srv @@ -0,0 +1,3 @@ +geographic_msgs/GeoPoint[] ll_points +--- +geometry_msgs/Point[] map_points