add humble-navigation2

This commit is contained in:
X-lanni
2025-05-27 19:03:40 +08:00
parent 974abb5e1e
commit e74ec539c2
1280 changed files with 204114 additions and 0 deletions
@@ -0,0 +1,82 @@
cmake_minimum_required(VERSION 3.5)
project(nav_2d_utils)
find_package(ament_cmake REQUIRED)
find_package(nav2_common REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(std_msgs REQUIRED)
find_package(nav_2d_msgs REQUIRED)
find_package(nav_msgs REQUIRED)
find_package(rclcpp REQUIRED)
find_package(tf2 REQUIRED)
find_package(tf2_geometry_msgs REQUIRED)
find_package(nav2_msgs REQUIRED)
find_package(nav2_util REQUIRED)
nav2_package()
set(dependencies
geometry_msgs
nav_2d_msgs
nav_msgs
std_msgs
rclcpp
tf2
tf2_geometry_msgs
nav2_msgs
nav2_util
nav_2d_msgs
)
include_directories(
include
)
add_library(conversions SHARED
src/conversions.cpp)
ament_target_dependencies(conversions
${dependencies}
)
add_library(path_ops SHARED
src/path_ops.cpp)
ament_target_dependencies(path_ops
${dependencies}
)
add_library(tf_help SHARED
src/tf_help.cpp
)
ament_target_dependencies(tf_help
${dependencies}
)
target_link_libraries(tf_help conversions)
install(TARGETS conversions path_ops tf_help
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
install(DIRECTORY include/
DESTINATION include/
)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
set(ament_cmake_copyright_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
find_package(ament_cmake_gtest REQUIRED)
add_subdirectory(test)
endif()
ament_export_include_directories(include)
ament_export_libraries(conversions path_ops tf_help)
ament_export_dependencies(${dependencies})
ament_package()
@@ -0,0 +1,71 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Locus Robotics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NAV_2D_UTILS__CONVERSIONS_HPP_
#define NAV_2D_UTILS__CONVERSIONS_HPP_
#include <vector>
#include <string>
#include "geometry_msgs/msg/pose.hpp"
#include "geometry_msgs/msg/twist.hpp"
#include "nav_2d_msgs/msg/twist2_d.hpp"
#include "nav_2d_msgs/msg/path2_d.hpp"
#include "nav_2d_msgs/msg/pose2_d_stamped.hpp"
#include "nav_msgs/msg/path.hpp"
#include "rclcpp/rclcpp.hpp"
#include "tf2/convert.h"
namespace nav_2d_utils
{
geometry_msgs::msg::Twist twist2Dto3D(const nav_2d_msgs::msg::Twist2D & cmd_vel_2d);
nav_2d_msgs::msg::Twist2D twist3Dto2D(const geometry_msgs::msg::Twist & cmd_vel);
// nav_2d_msgs::msg::Pose2DStamped stampedPoseToPose2D(const tf2::Stamped<tf2::Pose>& pose);
nav_2d_msgs::msg::Pose2DStamped poseStampedToPose2D(const geometry_msgs::msg::PoseStamped & pose);
geometry_msgs::msg::Pose2D poseToPose2D(const geometry_msgs::msg::Pose & pose);
geometry_msgs::msg::Pose pose2DToPose(const geometry_msgs::msg::Pose2D & pose2d);
geometry_msgs::msg::PoseStamped pose2DToPoseStamped(
const nav_2d_msgs::msg::Pose2DStamped & pose2d);
geometry_msgs::msg::PoseStamped pose2DToPoseStamped(
const geometry_msgs::msg::Pose2D & pose2d,
const std::string & frame, const rclcpp::Time & stamp);
nav_msgs::msg::Path posesToPath(const std::vector<geometry_msgs::msg::PoseStamped> & poses);
nav_2d_msgs::msg::Path2D pathToPath2D(const nav_msgs::msg::Path & path);
nav_msgs::msg::Path poses2DToPath(
const std::vector<geometry_msgs::msg::Pose2D> & poses,
const std::string & frame, const rclcpp::Time & stamp);
nav_msgs::msg::Path pathToPath(const nav_2d_msgs::msg::Path2D & path2d);
} // namespace nav_2d_utils
#endif // NAV_2D_UTILS__CONVERSIONS_HPP_
@@ -0,0 +1,101 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Locus Robotics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NAV_2D_UTILS__ODOM_SUBSCRIBER_HPP_
#define NAV_2D_UTILS__ODOM_SUBSCRIBER_HPP_
#include <cmath>
#include <memory>
#include <mutex>
#include <string>
#include "nav_2d_msgs/msg/twist2_d_stamped.hpp"
#include "nav_msgs/msg/odometry.hpp"
#include "nav2_util/lifecycle_node.hpp"
#include "rclcpp/rclcpp.hpp"
#include "nav2_util/node_utils.hpp"
namespace nav_2d_utils
{
/**
* @class OdomSubscriber
* Wrapper for some common odometry operations. Subscribes to the topic with a mutex.
*/
class OdomSubscriber
{
public:
/**
* @brief Constructor that subscribes to an Odometry topic
*
* @param nh NodeHandle for creating subscriber
* @param default_topic Name of the topic that will be loaded of the odom_topic param is not set.
*/
explicit OdomSubscriber(
nav2_util::LifecycleNode::SharedPtr nh,
std::string default_topic = "odom")
{
nav2_util::declare_parameter_if_not_declared(
nh, "odom_topic", rclcpp::ParameterValue(default_topic));
std::string odom_topic;
nh->get_parameter_or("odom_topic", odom_topic, default_topic);
odom_sub_ =
nh->create_subscription<nav_msgs::msg::Odometry>(
odom_topic,
rclcpp::SystemDefaultsQoS(),
std::bind(&OdomSubscriber::odomCallback, this, std::placeholders::_1));
}
inline nav_2d_msgs::msg::Twist2D getTwist() {return odom_vel_.velocity;}
inline nav_2d_msgs::msg::Twist2DStamped getTwistStamped() {return odom_vel_;}
protected:
void odomCallback(const nav_msgs::msg::Odometry::SharedPtr msg)
{
// ROS_INFO_ONCE("odom received!");
std::lock_guard<std::mutex> lock(odom_mutex_);
odom_vel_.header = msg->header;
odom_vel_.velocity.x = msg->twist.twist.linear.x;
odom_vel_.velocity.y = msg->twist.twist.linear.y;
odom_vel_.velocity.theta = msg->twist.twist.angular.z;
}
rclcpp::Subscription<nav_msgs::msg::Odometry>::SharedPtr odom_sub_;
nav_2d_msgs::msg::Twist2DStamped odom_vel_;
std::mutex odom_mutex_;
};
} // namespace nav_2d_utils
#endif // NAV_2D_UTILS__ODOM_SUBSCRIBER_HPP_
@@ -0,0 +1,78 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Locus Robotics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NAV_2D_UTILS__PARAMETERS_HPP_
#define NAV_2D_UTILS__PARAMETERS_HPP_
#include <string>
#include <memory>
#include "rclcpp/rclcpp.hpp"
#include "nav2_util/lifecycle_node.hpp"
#include "nav2_util/node_utils.hpp"
// TODO(crdelsey): Remove when code is re-enabled
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
namespace nav_2d_utils
{
/**
* @brief Search for a parameter and load it, or use the default value
*
* This templated function shortens a commonly used ROS pattern in which you
* search for a parameter and get its value if it exists, otherwise returning a default value.
*
* @param nh NodeHandle to start the parameter search from
* @param param_name Name of the parameter to search for
* @param default_value Value to return if not found
* @return Value of parameter if found, otherwise the default_value
*/
template<class param_t>
param_t searchAndGetParam(
const nav2_util::LifecycleNode::SharedPtr & nh, const std::string & param_name,
const param_t & default_value)
{
param_t value;
nav2_util::declare_parameter_if_not_declared(
nh, param_name,
rclcpp::ParameterValue(default_value));
nh->get_parameter(param_name, value);
return value;
}
} // namespace nav_2d_utils
#pragma GCC diagnostic pop
#endif // NAV_2D_UTILS__PARAMETERS_HPP_
@@ -0,0 +1,54 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Locus Robotics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NAV_2D_UTILS__PATH_OPS_HPP_
#define NAV_2D_UTILS__PATH_OPS_HPP_
#include "nav_2d_msgs/msg/path2_d.hpp"
namespace nav_2d_utils
{
/**
* @brief Increase plan resolution to match that of the costmap by adding points linearly between points
*
* @param global_plan_in input plan
* @param resolution desired distance between waypoints
* @return Higher resolution plan
*/
nav_2d_msgs::msg::Path2D adjustPlanResolution(
const nav_2d_msgs::msg::Path2D & global_plan_in,
double resolution);
} // namespace nav_2d_utils
#endif // NAV_2D_UTILS__PATH_OPS_HPP_
@@ -0,0 +1,86 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Locus Robotics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NAV_2D_UTILS__TF_HELP_HPP_
#define NAV_2D_UTILS__TF_HELP_HPP_
#include <string>
#include <memory>
#include "tf2_ros/buffer.h"
#include "nav_2d_utils/conversions.hpp"
#include "geometry_msgs/msg/pose_stamped.hpp"
#include "nav_2d_msgs/msg/pose2_d_stamped.hpp"
#include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
namespace nav_2d_utils
{
/**
* @brief Transform a PoseStamped from one frame to another while catching exceptions
*
* Also returns immediately if the frames are equal.
* @param tf Smart pointer to TFListener
* @param frame Frame to transform the pose into
* @param in_pose Pose to transform
* @param out_pose Place to store the resulting transformed pose
* @return True if successful transform
*/
bool transformPose(
const std::shared_ptr<tf2_ros::Buffer> tf,
const std::string frame,
const geometry_msgs::msg::PoseStamped & in_pose,
geometry_msgs::msg::PoseStamped & out_pose,
rclcpp::Duration & transform_tolerance
);
/**
* @brief Transform a Pose2DStamped from one frame to another while catching exceptions
*
* Also returns immediately if the frames are equal.
* @param tf Smart pointer to TFListener
* @param frame Frame to transform the pose into
* @param in_pose Pose to transform
* @param out_pose Place to store the resulting transformed pose
* @return True if successful transform
*/
bool transformPose(
const std::shared_ptr<tf2_ros::Buffer> tf,
const std::string frame,
const nav_2d_msgs::msg::Pose2DStamped & in_pose,
nav_2d_msgs::msg::Pose2DStamped & out_pose,
rclcpp::Duration & transform_tolerance
);
} // namespace nav_2d_utils
#endif // NAV_2D_UTILS__TF_HELP_HPP_
@@ -0,0 +1,29 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>nav_2d_utils</name>
<version>1.1.18</version>
<description>A handful of useful utility functions for nav_2d packages.</description>
<maintainer email="davidvlu@gmail.com">David V. Lu!!</maintainer>
<license>BSD-3-Clause</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<build_depend>nav2_common</build_depend>
<depend>geometry_msgs</depend>
<depend>nav_2d_msgs</depend>
<depend>nav_msgs</depend>
<depend>std_msgs</depend>
<depend>tf2</depend>
<depend>tf2_geometry_msgs</depend>
<depend>nav2_msgs</depend>
<depend>nav2_util</depend>
<test_depend>ament_lint_common</test_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_cmake_gtest</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
@@ -0,0 +1,187 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Locus Robotics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "nav_2d_utils/conversions.hpp"
#include <vector>
#include <string>
#include "geometry_msgs/msg/pose.hpp"
#include "geometry_msgs/msg/pose2_d.hpp"
#include "geometry_msgs/msg/pose_stamped.hpp"
#include "geometry_msgs/msg/twist.hpp"
#include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#include "tf2/utils.h"
#pragma GCC diagnostic pop
#include "nav2_util/geometry_utils.hpp"
namespace nav_2d_utils
{
using nav2_util::geometry_utils::orientationAroundZAxis;
geometry_msgs::msg::Twist twist2Dto3D(const nav_2d_msgs::msg::Twist2D & cmd_vel_2d)
{
geometry_msgs::msg::Twist cmd_vel;
cmd_vel.linear.x = cmd_vel_2d.x;
cmd_vel.linear.y = cmd_vel_2d.y;
cmd_vel.angular.z = cmd_vel_2d.theta;
return cmd_vel;
}
nav_2d_msgs::msg::Twist2D twist3Dto2D(const geometry_msgs::msg::Twist & cmd_vel)
{
nav_2d_msgs::msg::Twist2D cmd_vel_2d;
cmd_vel_2d.x = cmd_vel.linear.x;
cmd_vel_2d.y = cmd_vel.linear.y;
cmd_vel_2d.theta = cmd_vel.angular.z;
return cmd_vel_2d;
}
// nav_2d_msgs::msg::Pose2DStamped stampedPoseToPose2D(const tf2::Stamped<tf2::Pose>& pose)
// {
// nav_2d_msgs::msg::Pose2DStamped pose2d;
// pose2d.header.stamp = pose.stamp_;
// pose2d.header.frame_id = pose.frame_id_;
// pose2d.pose.x = pose.getOrigin().getX();
// pose2d.pose.y = pose.getOrigin().getY();
// pose2d.pose.theta = tf::getYaw(pose.getRotation());
// return pose2d;
// }
nav_2d_msgs::msg::Pose2DStamped poseStampedToPose2D(const geometry_msgs::msg::PoseStamped & pose)
{
nav_2d_msgs::msg::Pose2DStamped pose2d;
pose2d.header = pose.header;
pose2d.pose.x = pose.pose.position.x;
pose2d.pose.y = pose.pose.position.y;
pose2d.pose.theta = tf2::getYaw(pose.pose.orientation);
return pose2d;
}
geometry_msgs::msg::Pose2D poseToPose2D(const geometry_msgs::msg::Pose & pose)
{
geometry_msgs::msg::Pose2D pose2d;
pose2d.x = pose.position.x;
pose2d.y = pose.position.y;
pose2d.theta = tf2::getYaw(pose.orientation);
return pose2d;
}
geometry_msgs::msg::Pose pose2DToPose(const geometry_msgs::msg::Pose2D & pose2d)
{
geometry_msgs::msg::Pose pose;
pose.position.x = pose2d.x;
pose.position.y = pose2d.y;
pose.orientation = orientationAroundZAxis(pose2d.theta);
return pose;
}
geometry_msgs::msg::PoseStamped pose2DToPoseStamped(
const nav_2d_msgs::msg::Pose2DStamped & pose2d)
{
geometry_msgs::msg::PoseStamped pose;
pose.header = pose2d.header;
pose.pose = pose2DToPose(pose2d.pose);
return pose;
}
geometry_msgs::msg::PoseStamped pose2DToPoseStamped(
const geometry_msgs::msg::Pose2D & pose2d,
const std::string & frame, const rclcpp::Time & stamp)
{
geometry_msgs::msg::PoseStamped pose;
pose.header.frame_id = frame;
pose.header.stamp = stamp;
pose.pose.position.x = pose2d.x;
pose.pose.position.y = pose2d.y;
pose.pose.orientation = orientationAroundZAxis(pose2d.theta);
return pose;
}
nav_msgs::msg::Path posesToPath(const std::vector<geometry_msgs::msg::PoseStamped> & poses)
{
nav_msgs::msg::Path path;
if (poses.empty()) {
return path;
}
path.poses.resize(poses.size());
path.header.frame_id = poses[0].header.frame_id;
path.header.stamp = poses[0].header.stamp;
for (unsigned int i = 0; i < poses.size(); i++) {
path.poses[i] = poses[i];
}
return path;
}
nav_2d_msgs::msg::Path2D pathToPath2D(const nav_msgs::msg::Path & path)
{
nav_2d_msgs::msg::Path2D path2d;
path2d.header = path.header;
for (auto & pose : path.poses) {
path2d.poses.push_back(poseToPose2D(pose.pose));
}
return path2d;
}
nav_msgs::msg::Path poses2DToPath(
const std::vector<geometry_msgs::msg::Pose2D> & poses,
const std::string & frame, const rclcpp::Time & stamp)
{
nav_msgs::msg::Path path;
path.poses.resize(poses.size());
path.header.frame_id = frame;
path.header.stamp = stamp;
for (unsigned int i = 0; i < poses.size(); i++) {
path.poses[i] = pose2DToPoseStamped(poses[i], frame, stamp);
}
return path;
}
nav_msgs::msg::Path pathToPath(const nav_2d_msgs::msg::Path2D & path2d)
{
nav_msgs::msg::Path path;
path.header = path2d.header;
path.poses.resize(path2d.poses.size());
for (unsigned int i = 0; i < path.poses.size(); i++) {
path.poses[i].header = path2d.header;
path.poses[i].pose = pose2DToPose(path2d.poses[i]);
}
return path;
}
} // namespace nav_2d_utils
@@ -0,0 +1,84 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Locus Robotics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "nav_2d_utils/path_ops.hpp"
#include <cmath>
using std::sqrt;
namespace nav_2d_utils
{
nav_2d_msgs::msg::Path2D adjustPlanResolution(
const nav_2d_msgs::msg::Path2D & global_plan_in,
double resolution)
{
nav_2d_msgs::msg::Path2D global_plan_out;
if (global_plan_in.poses.size() == 0) {
return global_plan_out;
}
geometry_msgs::msg::Pose2D last = global_plan_in.poses[0];
global_plan_out.poses.push_back(last);
// we can take "holes" in the plan smaller than 2 grid cells (squared = 4)
double min_sq_resolution = resolution * resolution * 4.0;
for (unsigned int i = 1; i < global_plan_in.poses.size(); ++i) {
geometry_msgs::msg::Pose2D loop = global_plan_in.poses[i];
double sq_dist = (loop.x - last.x) * (loop.x - last.x) + (loop.y - last.y) * (loop.y - last.y);
if (sq_dist > min_sq_resolution) {
// add points in-between
double diff = sqrt(sq_dist) - sqrt(min_sq_resolution);
int steps = static_cast<int>(diff / resolution) - 1;
double steps_double = static_cast<double>(steps);
double delta_x = (loop.x - last.x) / steps_double;
double delta_y = (loop.y - last.y) / steps_double;
double delta_t = (loop.theta - last.theta) / steps_double;
for (int j = 1; j < steps; ++j) {
geometry_msgs::msg::Pose2D pose;
pose.x = last.x + j * delta_x;
pose.y = last.y + j * delta_y;
pose.theta = last.theta + j * delta_t;
global_plan_out.poses.push_back(pose);
}
}
global_plan_out.poses.push_back(global_plan_in.poses[i]);
last.x = loop.x;
last.y = loop.y;
}
return global_plan_out;
}
} // namespace nav_2d_utils
@@ -0,0 +1,115 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Locus Robotics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <memory>
#include <string>
#include "nav_2d_utils/tf_help.hpp"
namespace nav_2d_utils
{
bool transformPose(
const std::shared_ptr<tf2_ros::Buffer> tf,
const std::string frame,
const geometry_msgs::msg::PoseStamped & in_pose,
geometry_msgs::msg::PoseStamped & out_pose,
rclcpp::Duration & transform_tolerance
)
{
if (in_pose.header.frame_id == frame) {
out_pose = in_pose;
return true;
}
try {
tf->transform(in_pose, out_pose, frame);
return true;
} catch (tf2::ExtrapolationException & ex) {
auto transform = tf->lookupTransform(
frame,
in_pose.header.frame_id,
tf2::TimePointZero
);
if (
(rclcpp::Time(in_pose.header.stamp) - rclcpp::Time(transform.header.stamp)) >
transform_tolerance)
{
RCLCPP_ERROR(
rclcpp::get_logger("tf_help"),
"Transform data too old when converting from %s to %s",
in_pose.header.frame_id.c_str(),
frame.c_str()
);
RCLCPP_ERROR(
rclcpp::get_logger("tf_help"),
"Data time: %ds %uns, Transform time: %ds %uns",
in_pose.header.stamp.sec,
in_pose.header.stamp.nanosec,
transform.header.stamp.sec,
transform.header.stamp.nanosec
);
return false;
} else {
tf2::doTransform(in_pose, out_pose, transform);
return true;
}
} catch (tf2::TransformException & ex) {
RCLCPP_ERROR(
rclcpp::get_logger("tf_help"),
"Exception in transformPose: %s",
ex.what()
);
return false;
}
return false;
}
bool transformPose(
const std::shared_ptr<tf2_ros::Buffer> tf,
const std::string frame,
const nav_2d_msgs::msg::Pose2DStamped & in_pose,
nav_2d_msgs::msg::Pose2DStamped & out_pose,
rclcpp::Duration & transform_tolerance
)
{
geometry_msgs::msg::PoseStamped in_3d_pose = pose2DToPoseStamped(in_pose);
geometry_msgs::msg::PoseStamped out_3d_pose;
bool ret = transformPose(tf, frame, in_3d_pose, out_3d_pose, transform_tolerance);
if (ret) {
out_pose = poseStampedToPose2D(out_3d_pose);
}
return ret;
}
} // namespace nav_2d_utils
@@ -0,0 +1,162 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2018, Wilco Bonestroo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <math.h>
#include <tf2/LinearMath/Quaternion.h>
#include <vector>
#include "gtest/gtest.h"
#include "nav_2d_utils/conversions.hpp"
#include "rclcpp/rclcpp.hpp"
#include "rclcpp/time.hpp"
using nav_2d_utils::posesToPath;
using nav_2d_utils::pathToPath;
TEST(nav_2d_utils, PosesToPathEmpty)
{
std::vector<geometry_msgs::msg::PoseStamped> poses;
nav_msgs::msg::Path path = posesToPath(poses);
EXPECT_EQ(path.poses.size(), 0ul);
}
TEST(nav_2d_utils, PosesToPathNonEmpty)
{
std::vector<geometry_msgs::msg::PoseStamped> poses;
geometry_msgs::msg::PoseStamped pose1;
rclcpp::Time time1, time2;
auto node = rclcpp::Node::make_shared("twod_utils_test_node");
time1 = node->now();
tf2::Quaternion quat1, quat2;
quat1.setRPY(0, 0, 0.123);
pose1.pose.position.x = 1.0;
pose1.pose.position.y = 2.0;
pose1.pose.orientation.w = quat1.w();
pose1.pose.orientation.x = quat1.x();
pose1.pose.orientation.y = quat1.y();
pose1.pose.orientation.z = quat1.z();
pose1.header.stamp = time1;
pose1.header.frame_id = "frame1_id";
geometry_msgs::msg::PoseStamped pose2;
pose2.pose.position.x = 4.0;
pose2.pose.position.y = 5.0;
quat2.setRPY(0, 0, 0.987);
pose2.pose.orientation.w = quat2.w();
pose2.pose.orientation.x = quat2.x();
pose2.pose.orientation.y = quat2.y();
pose2.pose.orientation.z = quat2.z();
time2 = node->now();
pose2.header.stamp = time2;
pose2.header.frame_id = "frame2_id";
poses.push_back(pose1);
poses.push_back(pose2);
nav_msgs::msg::Path path = posesToPath(poses);
EXPECT_EQ(path.poses.size(), 2ul);
EXPECT_EQ(path.poses[0].pose.position.x, 1.0);
EXPECT_EQ(path.poses[0].pose.position.y, 2.0);
EXPECT_EQ(path.poses[0].header.stamp, time1);
EXPECT_EQ(path.poses[0].header.frame_id, "frame1_id");
EXPECT_EQ(path.poses[1].pose.position.x, 4.0);
EXPECT_EQ(path.poses[1].pose.position.y, 5.0);
EXPECT_EQ(path.poses[1].header.frame_id, "frame2_id");
EXPECT_EQ(path.header.stamp, time1);
}
TEST(nav_2d_utils, PathToPathEmpty)
{
nav_2d_msgs::msg::Path2D path2d;
nav_msgs::msg::Path path = pathToPath(path2d);
EXPECT_EQ(path.poses.size(), 0ul);
}
TEST(nav_2d_utils, PathToPathNoNEmpty)
{
nav_2d_msgs::msg::Path2D path2d;
geometry_msgs::msg::Pose2D pose1;
pose1.x = 1.0;
pose1.y = 2.0;
pose1.theta = M_PI / 2.0;
geometry_msgs::msg::Pose2D pose2;
pose2.x = 4.0;
pose2.y = 5.0;
pose2.theta = M_PI;
path2d.poses.push_back(pose1);
path2d.poses.push_back(pose2);
nav_msgs::msg::Path path = pathToPath(path2d);
EXPECT_EQ(path.poses.size(), 2ul);
EXPECT_EQ(path.poses[0].pose.position.x, 1.0);
EXPECT_EQ(path.poses[0].pose.position.y, 2.0);
tf2::Quaternion quat;
quat.setRPY(0, 0, M_PI / 2.0);
EXPECT_EQ(path.poses[0].pose.orientation.w, quat.w());
EXPECT_EQ(path.poses[0].pose.orientation.x, quat.x());
EXPECT_EQ(path.poses[0].pose.orientation.y, quat.x());
EXPECT_EQ(path.poses[0].pose.orientation.z, quat.z());
EXPECT_EQ(path.poses[1].pose.position.x, 4.0);
EXPECT_EQ(path.poses[1].pose.position.y, 5.0);
quat.setRPY(0, 0, M_PI);
EXPECT_EQ(path.poses[1].pose.orientation.w, quat.w());
EXPECT_EQ(path.poses[1].pose.orientation.x, quat.x());
EXPECT_EQ(path.poses[1].pose.orientation.y, quat.x());
EXPECT_EQ(path.poses[1].pose.orientation.z, quat.z());
}
int main(int argc, char ** argv)
{
::testing::InitGoogleTest(&argc, argv);
// initialize ROS
rclcpp::init(argc, argv);
bool all_successful = RUN_ALL_TESTS();
// shutdown ROS
rclcpp::shutdown();
return all_successful;
}
@@ -0,0 +1,9 @@
ament_add_gtest(2d_utils_tests 2d_utils_test.cpp)
target_link_libraries(2d_utils_tests conversions)
ament_add_gtest(path_ops_tests path_ops_test.cpp)
target_link_libraries(path_ops_tests path_ops)
ament_add_gtest(tf_help_tests tf_help_test.cpp)
target_link_libraries(tf_help_tests tf_help conversions)
@@ -0,0 +1,79 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2018, Wilco Bonestroo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <cmath>
#include "gtest/gtest.h"
#include "nav_2d_utils/path_ops.hpp"
using std::sqrt;
using nav_2d_utils::adjustPlanResolution;
TEST(path_ops_test, AdjustResolutionEmpty)
{
nav_2d_msgs::msg::Path2D in;
nav_2d_msgs::msg::Path2D out = adjustPlanResolution(in, 2.0);
EXPECT_EQ(out.poses.size(), 0ul);
}
TEST(path_ops_test, AdjustResolutionSimple)
{
nav_2d_msgs::msg::Path2D in;
const float RESOLUTION = 20.0;
geometry_msgs::msg::Pose2D pose1;
pose1.x = 0.0;
pose1.y = 0.0;
geometry_msgs::msg::Pose2D pose2;
pose2.x = 100.0;
pose2.y = 0.0;
in.poses.push_back(pose1);
in.poses.push_back(pose2);
nav_2d_msgs::msg::Path2D out = adjustPlanResolution(in, RESOLUTION);
float length = 100;
uint32_t number_of_points = ceil(length / (2 * RESOLUTION));
EXPECT_EQ(out.poses.size(), number_of_points);
float max_length = length / (number_of_points - 1);
for (unsigned int i = 1; i < out.poses.size(); i++) {
pose1 = out.poses[i - 1];
pose2 = out.poses[i];
double sq_dist = (pose1.x - pose2.x) * (pose1.x - pose2.x) +
(pose1.y - pose2.y) * (pose1.y - pose2.y);
EXPECT_TRUE(sqrt(sq_dist) <= max_length);
}
}
@@ -0,0 +1,98 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2018, Wilco Bonestroo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <memory>
#include <string>
#include "gtest/gtest.h"
#include "nav_2d_utils/tf_help.hpp"
TEST(TF_Help, TransformToSelf) {
bool result;
std::shared_ptr<tf2_ros::Buffer> tf;
std::string frame = "frame_id";
geometry_msgs::msg::PoseStamped in_pose;
in_pose.header.frame_id = "frame_id";
in_pose.pose.position.x = 1.0;
in_pose.pose.position.y = 2.0;
in_pose.pose.position.z = 3.0;
tf2::Quaternion qt;
qt.setRPY(0.5, 1.0, 1.5);
in_pose.pose.orientation.w = qt.w();
in_pose.pose.orientation.x = qt.x();
in_pose.pose.orientation.y = qt.y();
in_pose.pose.orientation.z = qt.z();
geometry_msgs::msg::PoseStamped out_pose;
rclcpp::Duration transform_tolerance(0, 500);
result = nav_2d_utils::transformPose(tf, frame, in_pose, out_pose, transform_tolerance);
EXPECT_TRUE(result);
EXPECT_EQ(out_pose.header.frame_id, "frame_id");
EXPECT_EQ(out_pose.pose.position.x, 1.0);
EXPECT_EQ(out_pose.pose.position.y, 2.0);
EXPECT_EQ(out_pose.pose.position.z, 3.0);
EXPECT_EQ(out_pose.pose.orientation.w, qt.w());
EXPECT_EQ(out_pose.pose.orientation.x, qt.x());
EXPECT_EQ(out_pose.pose.orientation.y, qt.y());
EXPECT_EQ(out_pose.pose.orientation.z, qt.z());
}
TEST(TF_Help, EmptyBuffer) {
auto clock = std::make_shared<rclcpp::Clock>(RCL_ROS_TIME);
auto buffer = std::make_shared<tf2_ros::Buffer>(clock);
std::string frame = "frame_id";
geometry_msgs::msg::PoseStamped in_pose;
in_pose.header.frame_id = "other_frame_id";
in_pose.pose.position.x = 1.0;
in_pose.pose.position.y = 2.0;
in_pose.pose.position.z = 3.0;
tf2::Quaternion qt;
qt.setRPY(0.5, 1.0, 1.5);
in_pose.pose.orientation.w = qt.w();
in_pose.pose.orientation.x = qt.x();
in_pose.pose.orientation.y = qt.y();
in_pose.pose.orientation.z = qt.z();
geometry_msgs::msg::PoseStamped out_pose;
rclcpp::Duration transform_tolerance(0, 500);
bool result;
result = nav_2d_utils::transformPose(buffer, frame, in_pose, out_pose, transform_tolerance);
EXPECT_FALSE(result);
}