forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			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
 |