152 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			152 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /*
 | ||
|  | Bullet Continuous Collision Detection and Physics Library | ||
|  | Copyright (c) 2003-2013 Erwin Coumans  http://bulletphysics.org
 | ||
|  | 
 | ||
|  | This software is provided 'as-is', without any express or implied warranty. | ||
|  | In no event will the authors be held liable for any damages arising from the use of this software. | ||
|  | Permission is granted to anyone to use this software for any purpose,  | ||
|  | including commercial applications, and to alter it and redistribute it freely,  | ||
|  | subject to the following restrictions: | ||
|  | 
 | ||
|  | 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. | ||
|  | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | ||
|  | 3. This notice may not be removed or altered from any source distribution. | ||
|  | */ | ||
|  | ///original version written by Erwin Coumans, October 2013
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #ifndef BT_PATH_SOLVER_H
 | ||
|  | #define BT_PATH_SOLVER_H
 | ||
|  | 
 | ||
|  | //#define BT_USE_PATH
 | ||
|  | #ifdef BT_USE_PATH
 | ||
|  | 
 | ||
|  | extern "C" { | ||
|  | #include "PATH/SimpleLCP.h"
 | ||
|  | #include "PATH/License.h"
 | ||
|  | #include "PATH/Error_Interface.h"
 | ||
|  | }; | ||
|  |   void __stdcall MyError(Void *data, Char *msg) | ||
|  | { | ||
|  | 	printf("Path Error: %s\n",msg); | ||
|  | } | ||
|  |   void __stdcall MyWarning(Void *data, Char *msg) | ||
|  | { | ||
|  | 	printf("Path Warning: %s\n",msg); | ||
|  | } | ||
|  | 
 | ||
|  | Error_Interface e; | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #include "btMLCPSolverInterface.h"
 | ||
|  | #include "Dantzig/lcp.h"
 | ||
|  | 
 | ||
|  | class btPathSolver : public btMLCPSolverInterface | ||
|  | { | ||
|  | public: | ||
|  | 
 | ||
|  | 	btPathSolver() | ||
|  | 	{ | ||
|  | 		License_SetString("2069810742&Courtesy_License&&&USR&2013&14_12_2011&1000&PATH&GEN&31_12_2013&0_0_0&0&0_0"); | ||
|  | 		e.error_data = 0; | ||
|  | 		e.warning = MyWarning; | ||
|  | 		e.error = MyError; | ||
|  | 		Error_SetInterface(&e); | ||
|  | 	} | ||
|  | 
 | ||
|  | 
 | ||
|  | 	virtual bool solveMLCP(const btMatrixXu & A, const btVectorXu & b, btVectorXu& x, const btVectorXu & lo,const btVectorXu & hi,const btAlignedObjectArray<int>& limitDependency, int numIterations, bool useSparsity = true) | ||
|  | 	{ | ||
|  | 		MCP_Termination status; | ||
|  | 		 | ||
|  | 
 | ||
|  | 		int numVariables = b.rows(); | ||
|  | 		if (0==numVariables) | ||
|  | 			return true; | ||
|  | 
 | ||
|  | 			/*	 - variables - the number of variables in the problem
 | ||
|  | 			- m_nnz - the number of nonzeros in the M matrix | ||
|  | 			- m_i - a vector of size m_nnz containing the row indices for M | ||
|  | 			- m_j - a vector of size m_nnz containing the column indices for M | ||
|  | 			- m_ij - a vector of size m_nnz containing the data for M | ||
|  | 			- q - a vector of size variables | ||
|  | 			- lb - a vector of size variables containing the lower bounds on x | ||
|  | 			- ub - a vector of size variables containing the upper bounds on x | ||
|  | 			*/ | ||
|  | 		btAlignedObjectArray<double> values; | ||
|  | 		btAlignedObjectArray<int> rowIndices; | ||
|  | 		btAlignedObjectArray<int> colIndices; | ||
|  | 
 | ||
|  | 		for (int i=0;i<A.rows();i++) | ||
|  | 		{ | ||
|  | 			for (int j=0;j<A.cols();j++) | ||
|  | 			{ | ||
|  | 				if (A(i,j)!=0.f) | ||
|  | 				{ | ||
|  | 					//add 1, because Path starts at 1, instead of 0
 | ||
|  | 					rowIndices.push_back(i+1); | ||
|  | 					colIndices.push_back(j+1); | ||
|  | 					values.push_back(A(i,j)); | ||
|  | 				} | ||
|  | 			} | ||
|  | 		} | ||
|  | 		int numNonZero = rowIndices.size(); | ||
|  | 		btAlignedObjectArray<double> zResult; | ||
|  | 		zResult.resize(numVariables); | ||
|  | 		btAlignedObjectArray<double> rhs; | ||
|  | 		btAlignedObjectArray<double> upperBounds; | ||
|  | 		btAlignedObjectArray<double> lowerBounds; | ||
|  | 		for (int i=0;i<numVariables;i++) | ||
|  | 		{ | ||
|  | 			upperBounds.push_back(hi[i]); | ||
|  | 			lowerBounds.push_back(lo[i]); | ||
|  | 			rhs.push_back(-b[i]); | ||
|  | 		} | ||
|  | 
 | ||
|  | 
 | ||
|  | 		SimpleLCP(numVariables,numNonZero,&rowIndices[0],&colIndices[0],&values[0],&rhs[0],&lowerBounds[0],&upperBounds[0], &status, &zResult[0]); | ||
|  | 
 | ||
|  | 		if (status != MCP_Solved) | ||
|  | 		{ | ||
|  | 			static const char* gReturnMsgs[] = { | ||
|  | 				"Invalid return", | ||
|  | 				"MCP_Solved: The problem was solved", | ||
|  | 				"MCP_NoProgress: A stationary point was found", | ||
|  | 				"MCP_MajorIterationLimit: Major iteration limit met", | ||
|  | 				"MCP_MinorIterationLimit: Cumulative minor iteration limit met", | ||
|  | 				"MCP_TimeLimit: Ran out of time", | ||
|  | 				"MCP_UserInterrupt: Control-C, typically", | ||
|  | 				"MCP_BoundError: Problem has a bound error", | ||
|  | 				"MCP_DomainError: Could not find starting point", | ||
|  | 				"MCP_Infeasible: Problem has no solution", | ||
|  | 				"MCP_Error: An error occurred within the code", | ||
|  | 				"MCP_LicenseError: License could not be found", | ||
|  | 				"MCP_OK" | ||
|  | 			}; | ||
|  | 
 | ||
|  | 			printf("ERROR: The PATH MCP solver failed: %s\n", gReturnMsgs[(unsigned int)status]);// << std::endl;
 | ||
|  | 			printf("using Projected Gauss Seidel fallback\n"); | ||
|  | 			 | ||
|  | 			return false; | ||
|  | 		} else | ||
|  | 		{ | ||
|  | 			for (int i=0;i<numVariables;i++) | ||
|  | 			{ | ||
|  | 				x[i] = zResult[i]; | ||
|  | 				//check for #NAN
 | ||
|  | 				if (x[i] != zResult[i]) | ||
|  | 					return false; | ||
|  | 			} | ||
|  | 			return true; | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 	} | ||
|  | }; | ||
|  | 
 | ||
|  | #endif //BT_USE_PATH
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #endif //BT_PATH_SOLVER_H
 |