1. 程式人生 > >ompl+win10+vs2017規劃庫,安裝,執行示例

ompl+win10+vs2017規劃庫,安裝,執行示例

說明

OMPL庫在Linux下使用較為方便,由於要使用到其核心演算法庫的部分功能。軟體在WIN10平臺下使用,故整理總結本文。其中通過官方的方法安裝存在一定問題,安裝報錯,在官網討論區有所討論但還未解決。主要是python繫結使用存在一些問題,但其核心c++庫依舊可以使用。

準備

  1. ompl官方原始碼 本文使用的為ompl 非.app
  2. vcpkg,微軟第三方開源庫整合器
  3. VS2017
  4. 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;
}

結果 在這裡插入圖片描述