From fb32a74090a90ec062b24e05932b88e3a8cea24c Mon Sep 17 00:00:00 2001 From: Mohammad Haghighipanah <mohammad.haghighipanah@intel.com> Date: Mon, 15 Oct 2018 16:29:45 -0700 Subject: [PATCH] Adding unit test to Robot Class --- nav2_robot/CMakeLists.txt | 3 + nav2_robot/src/ros_robot.cpp | 2 +- nav2_robot/test/CMakeLists.txt | 10 ++ nav2_robot/test/test_robot_class.cpp | 165 +++++++++++++++++++++++++++ 4 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 nav2_robot/test/CMakeLists.txt create mode 100644 nav2_robot/test/test_robot_class.cpp diff --git a/nav2_robot/CMakeLists.txt b/nav2_robot/CMakeLists.txt index f635ec94..7bde237c 100644 --- a/nav2_robot/CMakeLists.txt +++ b/nav2_robot/CMakeLists.txt @@ -42,8 +42,11 @@ install(DIRECTORY include/ ) if(BUILD_TESTING) + find_package(ament_cmake_pytest REQUIRED) + find_package(ament_cmake_gtest REQUIRED) find_package(ament_lint_auto REQUIRED) ament_lint_auto_find_test_dependencies() + add_subdirectory(test) endif() ament_export_include_directories(include) diff --git a/nav2_robot/src/ros_robot.cpp b/nav2_robot/src/ros_robot.cpp index 41be7555..2577c994 100644 --- a/nav2_robot/src/ros_robot.cpp +++ b/nav2_robot/src/ros_robot.cpp @@ -97,7 +97,7 @@ RosRobot::getCurrentVelocity(nav_msgs::msg::Odometry::SharedPtr & robot_velocity return true; } -// TODO(mhpanah): modify this method name and implementation to include robot types and Serial # (ID) +// TODO(mhpanah): modify this method name and implementation to include robot types and Serial #(ID) std::string RosRobot::getRobotName() { diff --git a/nav2_robot/test/CMakeLists.txt b/nav2_robot/test/CMakeLists.txt new file mode 100644 index 00000000..2298461f --- /dev/null +++ b/nav2_robot/test/CMakeLists.txt @@ -0,0 +1,10 @@ +include_directories( ${PROJECT_SOURCE_DIR}/src ) + +ament_add_gtest(test_robot_class + test_robot_class.cpp +) +ament_target_dependencies(test_robot_class + ${dependencies} +) +target_link_libraries(test_robot_class nav2_robot) + diff --git a/nav2_robot/test/test_robot_class.cpp b/nav2_robot/test/test_robot_class.cpp new file mode 100644 index 00000000..0540c72d --- /dev/null +++ b/nav2_robot/test/test_robot_class.cpp @@ -0,0 +1,165 @@ +// Copyright (c) 2018 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. + +#include <gtest/gtest.h> +#include <string> +#include <memory> +#include "rclcpp/rclcpp.hpp" +#include "nav2_robot/ros_robot.hpp" +#include "geometry_msgs/msg/pose_with_covariance_stamped.hpp" +#include "nav_msgs/msg/odometry.hpp" + +using std::placeholders::_1; + +class RclCppFixture +{ +public: + RclCppFixture() {rclcpp::init(0, nullptr);} + ~RclCppFixture() {rclcpp::shutdown();} +}; +RclCppFixture g_rclcppfixture; + +class TestRobotClass : public ::testing::Test +{ +public: + TestRobotClass() + { + node = rclcpp::Node::make_shared("robot_class_test"); + robot_ = std::make_unique<nav2_robot::RosRobot>(node.get()); + + pose_pub_ = node->create_publisher<geometry_msgs::msg::PoseWithCovarianceStamped>("amcl_pose"); + odom_pub_ = node->create_publisher<nav_msgs::msg::Odometry>("odom"); + + vel_sub_ = node->create_subscription<geometry_msgs::msg::Twist>("cmdVelocity", + std::bind(&TestRobotClass::velocityReceived, this, std::placeholders::_1)); + + velocityCmdReceived_ = false; + } + void velocityReceived(const geometry_msgs::msg::Twist::SharedPtr msg); + +protected: + std::shared_ptr<rclcpp::Node> node; + std::unique_ptr<nav2_robot::RosRobot> robot_; + void publishPose(); + void publishOdom(); + geometry_msgs::msg::PoseWithCovarianceStamped testPose_; + nav_msgs::msg::Odometry testOdom_; + geometry_msgs::msg::Twist velocityReceived_; + bool velocityCmdReceived_; + +private: + rclcpp::Publisher<geometry_msgs::msg::PoseWithCovarianceStamped>::SharedPtr pose_pub_; + rclcpp::Publisher<nav_msgs::msg::Odometry>::SharedPtr odom_pub_; + rclcpp::Subscription<geometry_msgs::msg::Twist>::ConstSharedPtr vel_sub_; +}; + +void +TestRobotClass::publishPose() +{ + testPose_.header.frame_id = "map"; + testPose_.header.stamp = rclcpp::Time(); + testPose_.pose.pose.position.x = 1.1; + testPose_.pose.pose.position.y = 1.2; + testPose_.pose.pose.position.z = 1.3; + testPose_.pose.pose.orientation.x = 0.1; + testPose_.pose.pose.orientation.y = 0.2; + testPose_.pose.pose.orientation.z = 0.3; + testPose_.pose.pose.orientation.w = 0.4; + for (int i = 0; i < 12; i++) { + testPose_.pose.covariance[i] = i; + } + pose_pub_->publish(testPose_); +} + +void +TestRobotClass::publishOdom() +{ + testOdom_.header.frame_id = "base_footprint"; + testOdom_.header.stamp = rclcpp::Time(); + + testOdom_.pose.pose.position.x = 1.1; + testOdom_.pose.pose.position.y = 1.2; + testOdom_.pose.pose.position.z = 1.3; + testOdom_.pose.pose.orientation.x = 0.1; + testOdom_.pose.pose.orientation.y = 0.2; + testOdom_.pose.pose.orientation.z = 0.3; + testOdom_.pose.pose.orientation.w = 0.4; + for (int i = 0; i < 12; i++) { + testOdom_.pose.covariance[i] = i; + } + + testOdom_.twist.twist.linear.x = 1.1; + testOdom_.twist.twist.linear.y = 1.2; + testOdom_.twist.twist.linear.z = 1.3; + testOdom_.twist.twist.angular.x = 1.1; + testOdom_.twist.twist.angular.y = 1.2; + testOdom_.twist.twist.angular.z = 1.3; + + for (int i = 0; i < 12; i++) { + testOdom_.twist.covariance[i] = i; + } + + odom_pub_->publish(testOdom_); +} + +void +TestRobotClass::velocityReceived(const geometry_msgs::msg::Twist::SharedPtr msg) +{ + velocityReceived_ = *msg; + velocityCmdReceived_ = true; +} + +TEST_F(TestRobotClass, getNameTest) +{ + std::string robotName = robot_->getRobotName(); + EXPECT_EQ(robotName, "turtlebot"); +} + +TEST_F(TestRobotClass, getPoseTest) +{ + auto currentPose = std::make_shared<geometry_msgs::msg::PoseWithCovarianceStamped>(); + while (!(robot_->getCurrentPose(currentPose))) { + publishPose(); + rclcpp::spin_some(node); + } + EXPECT_EQ(*currentPose, testPose_); +} + +TEST_F(TestRobotClass, getVelocityTest) +{ + auto currentOdom = std::make_shared<nav_msgs::msg::Odometry>(); + while (!(robot_->getCurrentVelocity(currentOdom))) { + publishOdom(); + rclcpp::spin_some(node); + } + EXPECT_EQ(*currentOdom, testOdom_); +} + +TEST_F(TestRobotClass, sendVelocityTest) +{ + geometry_msgs::msg::Twist velocity_cmd; + velocity_cmd.linear.x = 1.1; + velocity_cmd.linear.y = 1.2; + velocity_cmd.linear.z = 1.3; + velocity_cmd.angular.x = 1.1; + velocity_cmd.angular.y = 1.2; + velocity_cmd.angular.z = 1.3; + + robot_->sendVelocity(velocity_cmd); + + while (!velocityCmdReceived_) { + rclcpp::spin_some(node); + } + EXPECT_EQ(velocity_cmd, velocityReceived_); +} -- GitLab