From bc304f1e76db205c4a50e56d78fd73318000a186 Mon Sep 17 00:00:00 2001 From: Joseph Mirabel <jmirabel@laas.fr> Date: Wed, 10 May 2017 13:31:39 +0200 Subject: [PATCH] Add profile test. --- test/CMakeLists.txt | 2 + test/test_fcl_profiling.cpp | 178 ++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 test/test_fcl_profiling.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9e44dc97..65aac2e7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -43,6 +43,8 @@ add_fcl_test(test_fcl_capsule_box_2 test_fcl_capsule_box_2.cpp test_fcl_utility. add_fcl_test(test_fcl_bvh_models test_fcl_bvh_models.cpp test_fcl_utility.cpp) +add_fcl_test(test_fcl_profiling test_fcl_profiling.cpp test_fcl_utility.cpp) + if (FCL_HAVE_OCTOMAP) add_fcl_test(test_fcl_octomap test_fcl_octomap.cpp test_fcl_utility.cpp) PKG_CONFIG_USE_DEPENDENCY(test_fcl_octomap octomap) diff --git a/test/test_fcl_profiling.cpp b/test/test_fcl_profiling.cpp new file mode 100644 index 00000000..9cff1f8c --- /dev/null +++ b/test/test_fcl_profiling.cpp @@ -0,0 +1,178 @@ +// Copyright (c) 2017, Joseph Mirabel +// Authors: Joseph Mirabel (joseph.mirabel@laas.fr) +// +// This file is part of hpp-fcl. +// hpp-fcl is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation, either version +// 3 of the License, or (at your option) any later version. +// +// hpp-fcl 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 Lesser Public License for more details. You should have +// received a copy of the GNU Lesser General Public License along with +// hpp-fcl. If not, see <http://www.gnu.org/licenses/>. + + +#include <boost/shared_ptr.hpp> +#include <boost/filesystem.hpp> + +#include <hpp/fcl/fwd.hh> +#include <hpp/fcl/collision.h> +#include <hpp/fcl/BVH/BVH_model.h> +#include <hpp/fcl/shape/geometric_shapes.h> +#include <hpp/fcl/collision_func_matrix.h> +#include <hpp/fcl/narrowphase/narrowphase.h> +#include "test_fcl_utility.h" +#include "fcl_resources/config.h" + +using namespace fcl; + +CollisionFunctionMatrix<GJKSolver_indep> lookupTable; +bool supportedPair(const CollisionGeometry* o1, const CollisionGeometry* o2) +{ + OBJECT_TYPE object_type1 = o1->getObjectType(); + OBJECT_TYPE object_type2 = o2->getObjectType(); + NODE_TYPE node_type1 = o1->getNodeType(); + NODE_TYPE node_type2 = o2->getNodeType(); + + if(object_type1 == OT_GEOM && object_type2 == OT_BVH) + return (lookupTable.collision_matrix[node_type2][node_type1] != NULL); + else + return (lookupTable.collision_matrix[node_type1][node_type2] != NULL); +} + +template <typename BV/*, SplitMethodType split_method*/> +CollisionGeometryPtr_t objToGeom (const std::string& filename) +{ + std::vector<Vec3f> pt; + std::vector<Triangle> tri; + loadOBJFile(filename.c_str(), pt, tri); + + BVHModel<BV>* model (new BVHModel<BV>()); + // model->bv_splitter.reset(new BVSplitter<BV>(split_method)); + + model->beginModel(); + model->addSubModel(pt, tri); + model->endModel(); + + return CollisionGeometryPtr_t (model); +} + +struct Geometry { + std::string type; + CollisionGeometryPtr_t o; + + Geometry (const std::string& t, CollisionGeometry* ob) : + type(t), o(ob) + {} + Geometry (const std::string& t, const CollisionGeometryPtr_t& ob) : + type(t), o(ob) + {} +}; + +// struct Result { + // CollisionResult r; + // double time_us; +// }; + +struct Results { + std::vector<CollisionResult> rs; + Eigen::VectorXd times; // micro-seconds + + Results (int i) : rs(i), times(i) {} +}; + +void collide(const std::vector<Transform3f>& tf, + const CollisionGeometry* o1, + const CollisionGeometry* o2, + const CollisionRequest& request, + Results& results) +{ + Transform3f Id; + Timer timer; + for (std::size_t i = 0; i < tf.size(); ++i) { + timer.start(); + /* int num_contact = */ + collide (o1, tf[i], o2, Id, request, results.rs[i]); + timer.stop(); + results.times[i] = timer.getElapsedTimeInMicroSec(); + } +} + +const char* sep = ", "; + +void printResultHeaders () +{ + std::cout << "Type 1" << sep << "Type 2" << sep << "mean time" << sep << "time std dev" << sep << "min time" << sep << "max time" << std::endl; +} + +void printResults (const Geometry& g1, const Geometry& g2, const Results& rs) +{ + double mean = rs.times.mean(); + double var = rs.times.cwiseAbs2().mean() - mean*mean; + std::cout << g1.type << sep << g2.type << sep << mean << sep << std::sqrt(var) << sep << rs.times.minCoeff() << sep << rs.times.maxCoeff() << std::endl; +} + +// int main(int argc, char** argv) +int main(int, char**) +{ + boost::filesystem::path path(TEST_RESOURCES_DIR); + + std::vector<Geometry> geoms; +// | | box | sphere | capsule | cone | cylinder | plane | half-space | triangle | + geoms.push_back(Geometry ("Box" , new Box (1, 2, 3) )); + geoms.push_back(Geometry ("Sphere" , new Sphere (2) )); + geoms.push_back(Geometry ("Capsule" , new Capsule (2, 1) )); + geoms.push_back(Geometry ("Cone" , new Cone (2, 1) )); + geoms.push_back(Geometry ("Cylinder" , new Cylinder (2, 1) )); + geoms.push_back(Geometry ("Plane" , new Plane (Vec3f(1,1,1).normalized(), 0) )); + geoms.push_back(Geometry ("Halfspace" , new Halfspace (Vec3f(1,1,1).normalized(), 0) )); + // not implemented // geoms.push_back(Geometry ("TriangleP" , new TriangleP (Vec3f(0,1,0), Vec3f(0,0,1), Vec3f(-1,0,0)) )); + + geoms.push_back(Geometry ("rob BVHModel<OBB>" , objToGeom<OBB> ((path / "rob.obj").string()))); + // geoms.push_back(Geometry ("rob BVHModel<RSS>" , objToGeom<RSS> ((path / "rob.obj").string()))); + // geoms.push_back(Geometry ("rob BVHModel<kIOS>" , objToGeom<kIOS> ((path / "rob.obj").string()))); + geoms.push_back(Geometry ("rob BVHModel<OBBRSS>", objToGeom<OBBRSS>((path / "rob.obj").string()))); + + geoms.push_back(Geometry ("env BVHModel<OBB>" , objToGeom<OBB> ((path / "env.obj").string()))); + // geoms.push_back(Geometry ("env BVHModel<RSS>" , objToGeom<RSS> ((path / "env.obj").string()))); + // geoms.push_back(Geometry ("env BVHModel<kIOS>" , objToGeom<kIOS> ((path / "env.obj").string()))); + geoms.push_back(Geometry ("env BVHModel<OBBRSS>", objToGeom<OBBRSS>((path / "env.obj").string()))); + + std::vector<Transform3f> transforms; + FCL_REAL extents[] = {-20, -20, 0, 20, 20, 20}; + std::size_t n = 100; + // bool verbose = false; + + generateRandomTransforms(extents, transforms, n); + + printResultHeaders(); + + // collision + CollisionRequest request; + // request.num_max_contacts = 1; + // request.enable_contact = false; + // request.enable_distance_lower_bound = false; + // request.num_max_cost_sources = 1; + // request.enable_cost = false; + // request.use_approximate_cost = true; + // request.gjk_solver_type = GST_INDEP; + for(std::size_t i = 0; i < geoms.size(); ++i) { + for (std::size_t j = i; j < geoms.size(); ++j) { + if (!supportedPair(geoms[i].o.get(), geoms[j].o.get())) continue; + Results results (n); + collide(transforms, geoms[i].o.get(), geoms[j].o.get(), request, results); + printResults(geoms[i], geoms[j], results); + } + } + + // request.enable_distance_lower_bound = true; + // for(std::size_t i = 0; i < geoms.size(); ++i) + // { + // Results results (n); + // selfCollide(transforms, geoms[i].o.get(), request, results); + // printResults(geoms[i], results); + // } +} -- GitLab