ompl+win10+vs2017規劃庫,安裝,執行示例
阿新 • • 發佈:2018-12-21
說明
OMPL庫在Linux下使用較為方便,由於要使用到其核心演算法庫的部分功能。軟體在WIN10平臺下使用,故整理總結本文。其中通過官方的方法安裝存在一定問題,安裝報錯,在官網討論區有所討論但還未解決。主要是python繫結使用存在一些問題,但其核心c++庫依舊可以使用。
準備
- ompl官方原始碼 本文使用的為ompl 非.app
- vcpkg,微軟第三方開源庫整合器
- VS2017
- cmake
安裝
第一步:安裝vcpkg,安裝方法
第二步:按照官方建議,利用vcpkg安裝第三方庫
vcpkg install boost:x64-windows vcpkg install eigen3:x64-windows vcpkg install assimp:x64-windows vcpkg install fcl:x64-windows vcpkg install pqp:x64-windows
該步驟中,若按照fcl等報錯,可能是未安裝cmake工具或缺少其他外掛。利用VS2017安裝相關工具 開始菜開啟“Visual Studio Installer 點選“修改” 在“單個元件”中找到“用於CMake和Linux的VisualC++工具”勾選之 修改安裝,靜候佳音。
第三步:安裝完依賴庫後,開啟ompl目錄,利用cmake構建sln方案。按住shift點選右鍵開啟powershell,輸入下列程式碼
mkdir build cd build cmake -G"Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="C:\tools\vcpkg\scripts\buildsystems\vcpkg.cmake" -DOMPL_REGISTRATION=OFF ..
上圖即為官方網站上討論的還未解決的情況,跟python有關,具體不是很清楚。 生成完成後的build資料夾裡的內容
第四步:開啟ompl.sln 直接開啟ompl.sln載入的情況如下
若直接點選生成會報一堆錯誤,而由於我需要的僅為C++庫,故將除ompl外的其他方案移除,然後點選生成。
第五步:自己呼叫OMPL庫 在VS中新建一個空專案,其中需要注意的是一些配置檔案需要設定。引數的設定可以參照bulid/demos資料夾的相關解決方案進行配置。 C++語言項裡面需要尤其注意。部分用到的boost的dll和lib也自己加入到配置當中去。
執行示例原始碼
/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2010, Rice University * 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 Rice University 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 OWNER 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. *********************************************************************/ /* Author: Mark Moll */ #include <ompl/base/spaces/DubinsStateSpace.h> #include <ompl/base/spaces/ReedsSheppStateSpace.h> #include <ompl/base/ScopedState.h> #include <ompl/geometric/SimpleSetup.h> #include <boost/program_options.hpp> namespace ob = ompl::base; namespace og = ompl::geometric; namespace po = boost::program_options; // The easy problem is the standard narrow passage problem: two big open // spaces connected by a narrow passage. The hard problem is essentially // one long narrow passage with the robot facing towards the long walls // in both the start and goal configurations. bool isStateValidEasy(const ob::SpaceInformation *si, const ob::State *state) { const auto *s = state->as<ob::SE2StateSpace::StateType>(); double x = s->getX(), y = s->getY(); return si->satisfiesBounds(s) && (x < 5 || x > 13 || (y > 8.5 && y < 9.5)); } bool isStateValidHard(const ob::SpaceInformation *si, const ob::State *state) { return si->satisfiesBounds(state); } void plan(const ob::StateSpacePtr &space, bool easy) { ob::ScopedState<> start(space), goal(space); ob::RealVectorBounds bounds(2); bounds.setLow(0); if (easy) bounds.setHigh(18); else { bounds.high[0] = 6; bounds.high[1] = .6; } space->as<ob::SE2StateSpace>()->setBounds(bounds); // define a simple setup class og::SimpleSetup ss(space); // set state validity checking for this space const ob::SpaceInformation *si = ss.getSpaceInformation().get(); auto isStateValid = easy ? isStateValidEasy : isStateValidHard; ss.setStateValidityChecker([isStateValid, si](const ob::State *state) { return isStateValid(si, state); }); // set the start and goal states if (easy) { start[0] = start[1] = 1.; start[2] = 0.; goal[0] = goal[1] = 17; goal[2] = -.99 * boost::math::constants::pi<double>(); } else { start[0] = start[1] = .5; start[2] = .5 * boost::math::constants::pi<double>(); ; goal[0] = 5.5; goal[1] = .5; goal[2] = .5 * boost::math::constants::pi<double>(); } ss.setStartAndGoalStates(start, goal); // this call is optional, but we put it in to get more output information ss.getSpaceInformation()->setStateValidityCheckingResolution(0.005); ss.setup(); ss.print(); // attempt to solve the problem within 30 seconds of planning time ob::PlannerStatus solved = ss.solve(30.0); if (solved) { std::vector<double> reals; std::cout << "Found solution:" << std::endl; ss.simplifySolution(); og::PathGeometric path = ss.getSolutionPath(); path.interpolate(1000); path.printAsMatrix(std::cout); } else std::cout << "No solution found" << std::endl; } void printTrajectory(const ob::StateSpacePtr &space, const std::vector<double> &pt) { if (pt.size() != 3) throw ompl::Exception("3 arguments required for trajectory option"); const unsigned int num_pts = 50; ob::ScopedState<> from(space), to(space), s(space); std::vector<double> reals; from[0] = from[1] = from[2] = 0.; to[0] = pt[0]; to[1] = pt[1]; to[2] = pt[2]; std::cout << "distance: " << space->distance(from(), to()) << "\npath:\n"; for (unsigned int i = 0; i <= num_pts; ++i) { space->interpolate(from(), to(), (double)i / num_pts, s()); reals = s.reals(); std::cout << "path " << reals[0] << ' ' << reals[1] << ' ' << reals[2] << ' ' << std::endl; } } void printDistanceGrid(const ob::StateSpacePtr &space) { // print the distance for (x,y,theta) for all points in a 3D grid in SE(2) // over [-5,5) x [-5, 5) x [-pi,pi). // // The output should be redirected to a file, say, distance.txt. This // can then be read and plotted in Matlab like so: // x = reshape(load('distance.txt'),200,200,200); // for i=1:200, // contourf(squeeze(x(i,:,:)),30); // axis equal; axis tight; colorbar; pause; // end; const unsigned int num_pts = 200; ob::ScopedState<> from(space), to(space); from[0] = from[1] = from[2] = 0.; for (unsigned int i = 0; i < num_pts; ++i) for (unsigned int j = 0; j < num_pts; ++j) for (unsigned int k = 0; k < num_pts; ++k) { to[0] = 5. * (2. * (double)i / num_pts - 1.); to[1] = 5. * (2. * (double)j / num_pts - 1.); to[2] = boost::math::constants::pi<double>() * (2. * (double)k / num_pts - 1.); std::cout << space->distance(from(), to()) << '\n'; } } int main(int argc, char *argv[]) { try { po::options_description desc("Options"); desc.add_options() ("help", "show help message") ("dubins", "use Dubins state space") ("dubinssym", "use " "symmetrized " "Dubins state " "space") ("reedsshepp", "use Reeds-Shepp state space (default)") ("easyplan", "solve easy planning problem and print " "path") ("hardplan", "solve hard ""planning problem ""and print path") ("trajectory", po::value<std::vector<double>>()->multitoken(), "print trajectory from (0,0,0) to a user-specified x, y, and theta") ("distance", "print distance grid"); argc = 3; argv[0] = ""; argv[1] = "--dubins"; argv[2] = "--easyplan"; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc, po::command_line_style::unix_style ^ po::command_line_style::allow_short), vm); po::notify(vm); if ((vm.count("help") != 0u) || argc == 1) { std::cout << desc << "\n"; return 1; } ob::StateSpacePtr space(std::make_shared<ob::ReedsSheppStateSpace>()); if (vm.count("dubins") != 0u) space = std::make_shared<ob::DubinsStateSpace>(); if (vm.count("dubinssym") != 0u) space = std::make_shared<ob::DubinsStateSpace>(1., true); if (vm.count("easyplan") != 0u) plan(space, true); if (vm.count("hardplan") != 0u) plan(space, false); if (vm.count("trajectory") != 0u) printTrajectory(space, vm["trajectory"].as<std::vector<double>>()); if (vm.count("distance") != 0u) printDistanceGrid(space); } catch (std::exception &e) { std::cerr << "error: " << e.what() << "\n"; return 1; } catch (...) { std::cerr << "Exception of unknown type!\n"; } return 0; }
結果