test_navigate.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2017, the neonavigation authors
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the copyright holder nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <ros/ros.h>
00031 #include <tf2/utils.h>
00032 #include <tf2_geometry_msgs/tf2_geometry_msgs.h>
00033 #include <tf2_ros/transform_listener.h>
00034 #include <nav_msgs/Path.h>
00035 #include <nav_msgs/GetPlan.h>
00036 #include <nav_msgs/OccupancyGrid.h>
00037 
00038 #include <cstddef>
00039 
00040 #include <gtest/gtest.h>
00041 
00042 TEST(Navigate, Navigate)
00043 {
00044   nav_msgs::OccupancyGrid::ConstPtr map;
00045 
00046   const boost::function<void(const nav_msgs::OccupancyGrid::ConstPtr&)> cb_map =
00047       [&map](const nav_msgs::OccupancyGrid::ConstPtr& msg) -> void
00048   {
00049     map = msg;
00050     std::cerr << "Map received." << std::endl;
00051   };
00052 
00053   ros::NodeHandle nh("");
00054   tf2_ros::Buffer tfbuf;
00055   tf2_ros::TransformListener tfl(tfbuf);
00056   ros::Publisher pub_path = nh.advertise<nav_msgs::Path>("patrol_nodes", 1, true);
00057   ros::Subscriber sub_map = nh.subscribe("map", 1, cb_map);
00058 
00059   ros::Duration(2.0).sleep();
00060   nav_msgs::Path path;
00061   path.poses.resize(2);
00062   path.header.frame_id = "map";
00063   path.poses[0].header.frame_id = path.header.frame_id;
00064   path.poses[0].pose.position.x = 1.7;
00065   path.poses[0].pose.position.y = 2.8;
00066   path.poses[0].pose.orientation = tf2::toMsg(tf2::Quaternion(tf2::Vector3(0.0, 0.0, 1.0), -3.14));
00067   path.poses[1].header.frame_id = path.header.frame_id;
00068   path.poses[1].pose.position.x = 1.9;
00069   path.poses[1].pose.position.y = 2.8;
00070   path.poses[1].pose.orientation = tf2::toMsg(tf2::Quaternion(tf2::Vector3(0.0, 0.0, 1.0), -1.57));
00071   pub_path.publish(path);
00072 
00073   tf2::Transform goal;
00074   tf2::fromMsg(path.poses.back().pose, goal);
00075 
00076   ros::Rate wait(10);
00077   while (ros::ok())
00078   {
00079     ros::spinOnce();
00080     wait.sleep();
00081 
00082     tf2::Stamped<tf2::Transform> trans;
00083     try
00084     {
00085       const ros::Time now = ros::Time::now();
00086       geometry_msgs::TransformStamped trans_tmp =
00087           tfbuf.lookupTransform("map", "base_link", now, ros::Duration(0.5));
00088       tf2::fromMsg(trans_tmp, trans);
00089     }
00090     catch (tf2::TransformException& e)
00091     {
00092       std::cerr << e.what() << std::endl;
00093       continue;
00094     }
00095 
00096     auto goal_rel = trans.inverse() * goal;
00097     if (goal_rel.getOrigin().length() < 0.2 &&
00098         fabs(tf2::getYaw(goal_rel.getRotation())) < 0.2)
00099     {
00100       std::cerr << "Navagation success." << std::endl;
00101       ros::Duration(2.0).sleep();
00102       return;
00103     }
00104 
00105     if (!map)
00106     {
00107       std::cerr << "Waiting map." << std::endl;
00108       continue;
00109     }
00110 
00111     for (int x = -2; x <= 2; ++x)
00112     {
00113       for (int y = -1; y <= 1; ++y)
00114       {
00115         const tf2::Vector3 pos =
00116             trans * tf2::Vector3(x * map->info.resolution, y * map->info.resolution, 0);
00117         const int map_x = pos.x() / map->info.resolution;
00118         const int map_y = pos.y() / map->info.resolution;
00119         const size_t addr = map_x + map_y * map->info.width;
00120         ASSERT_LT(addr, map->data.size());
00121         ASSERT_LT(map_x, static_cast<int>(map->info.width));
00122         ASSERT_LT(map_y, static_cast<int>(map->info.height));
00123         ASSERT_GE(map_x, 0);
00124         ASSERT_GE(map_y, 0);
00125         ASSERT_NE(map->data[addr], 100);
00126       }
00127     }
00128   }
00129   ASSERT_TRUE(false);
00130 }
00131 
00132 TEST(Navigate, GlobalPlan)
00133 {
00134   nav_msgs::OccupancyGrid::ConstPtr map;
00135 
00136   const boost::function<void(const nav_msgs::OccupancyGrid::ConstPtr&)> cb_map =
00137       [&map](const nav_msgs::OccupancyGrid::ConstPtr& msg) -> void
00138   {
00139     map = msg;
00140     std::cerr << "Map received." << std::endl;
00141   };
00142 
00143   ros::NodeHandle nh("");
00144   tf2_ros::Buffer tfbuf;
00145   tf2_ros::TransformListener tfl(tfbuf);
00146   ros::ServiceClient srv_plan =
00147       nh.serviceClient<nav_msgs::GetPlanRequest, nav_msgs::GetPlanResponse>(
00148           "/planner_3d/make_plan");
00149   ros::Subscriber sub_map = nh.subscribe("map", 1, cb_map);
00150 
00151   ros::Duration(2.0).sleep();
00152   ros::spinOnce();
00153   ASSERT_TRUE(static_cast<bool>(map));
00154 
00155   nav_msgs::GetPlanRequest req;
00156   nav_msgs::GetPlanResponse res;
00157 
00158   req.start.header.frame_id = "map";
00159   req.start.pose.position.x = 2.0;
00160   req.start.pose.position.y = 0.45;
00161   req.start.pose.orientation =
00162       tf2::toMsg(tf2::Quaternion(tf2::Vector3(0.0, 0.0, 1.0), 3.14));
00163 
00164   req.goal.header.frame_id = "map";
00165   req.goal.pose.position.x = 1.2;
00166   req.goal.pose.position.y = 1.9;
00167   req.goal.pose.orientation =
00168       tf2::toMsg(tf2::Quaternion(tf2::Vector3(0.0, 0.0, 1.0), -3.14));
00169   ASSERT_FALSE(srv_plan.call(req, res));
00170 
00171   req.goal.header.frame_id = "map";
00172   req.goal.pose.position.x = 1.9;
00173   req.goal.pose.position.y = 2.8;
00174   req.goal.pose.orientation =
00175       tf2::toMsg(tf2::Quaternion(tf2::Vector3(0.0, 0.0, 1.0), -1.57));
00176   ASSERT_TRUE(srv_plan.call(req, res));
00177 
00178   ASSERT_NEAR(req.start.pose.position.x, res.plan.poses.front().pose.position.x, 0.1);
00179   ASSERT_NEAR(req.start.pose.position.y, res.plan.poses.front().pose.position.y, 0.1);
00180   ASSERT_NEAR(req.goal.pose.position.x, res.plan.poses.back().pose.position.x, 0.1);
00181   ASSERT_NEAR(req.goal.pose.position.y, res.plan.poses.back().pose.position.y, 0.1);
00182 
00183   for (const geometry_msgs::PoseStamped& p : res.plan.poses)
00184   {
00185     const int map_x = p.pose.position.x / map->info.resolution;
00186     const int map_y = p.pose.position.y / map->info.resolution;
00187     const size_t addr = map_x + map_y * map->info.width;
00188     ASSERT_LT(addr, map->data.size());
00189     ASSERT_LT(map_x, static_cast<int>(map->info.width));
00190     ASSERT_LT(map_y, static_cast<int>(map->info.height));
00191     ASSERT_GE(map_x, 0);
00192     ASSERT_GE(map_y, 0);
00193     ASSERT_NE(map->data[addr], 100);
00194   }
00195 }
00196 
00197 int main(int argc, char** argv)
00198 {
00199   testing::InitGoogleTest(&argc, argv);
00200   ros::init(argc, argv, "test_navigate");
00201 
00202   return RUN_ALL_TESTS();
00203 }


planner_cspace
Author(s): Atsushi Watanabe
autogenerated on Sat Jun 22 2019 20:07:27