In order to implement a car in UE4 ,I read the src code sample_vheicle in PhysX SDK.
When I read the function Create4WVehicle,I find it first compute SimulationData.
But I’m not clear about how to compute the sprung masses of each suspension spring.
Which paper or pdf link explain the formulation of it?
I know how to use Jacobian and GaussisSeidel Iter when I learn Bullet Physics Engine.
I can’t understand the meaning of g0,g1,g2 ,and why build the matrix A in this way?
//Compute the sprung masses of each suspension spring using a helper function.
PxF32 suspSprungMasses[4];
PxVehicleComputeSprungMasses(4, wheelCentreOffsets, chassisCMOffset, chassisMass, 1, suspSprungMasses);
if(numSprungMasses>=4)
{
const PxU32 d0=(gravityDirection+1)%3;
const PxU32 d1=(gravityDirection+2)%3;
const PxF32 mbar = totalMass/(numSprungMasses*1.0f);
//See http://en.wikipedia.org/wiki/Lagrange_multiplier
//particularly the section on multiple constraints.
//3 Constraint equations.
//g0 = sum_ xi*mi=xcm
//g1 = sum_ zi*mi=zcm
//g2 = sum_ mi = totalMass
//Minimisation function to achieve solution with minimum mass variance.
//f = sum_ (mi - mave)^2
//Lagrange terms (N equations, N+3 unknowns)
//2*mi - xi*lambda0 - zi*lambda1 - 1*lambda2 = 2*mave
MatrixNN A(numSprungMasses+3);
VectorN b(numSprungMasses+3);
//g0, g1, g2
for(PxU32 i=0;i<numSprungMasses;i++)
{
A.set(0,i,sprungMassCoordinates[i][d0]); //g0
A.set(1,i,sprungMassCoordinates[i][d1]); //g1
A.set(2,i,1.0f); //g2
}
for(PxU32 i=numSprungMasses;i<numSprungMasses+3;i++)
{
A.set(0,i,0); //g0 independent of lambda0,lambda1,lambda2
A.set(1,i,0); //g1 independent of lambda0,lambda1,lambda2
A.set(2,i,0); //g2 independent of lambda0,lambda1,lambda2
}
b[0] = totalMass*(centreOfMass[d0]); //g0
b[1] = totalMass*(centreOfMass[d1]); //g1
b[2] = totalMass; //g2
//Lagrange terms.
for(PxU32 i=0;i<numSprungMasses;i++)
{
//Off-diagonal terms from the derivative of f
for(PxU32 j=0;j<numSprungMasses;j++)
{
A.set(i+3,j,0);
}
//Diagonal term from the derivative of f
A.set(i+3,i,2.f);
//Derivative of g
A.set(i+3,numSprungMasses+0,sprungMassCoordinates[i][d0]);
A.set(i+3,numSprungMasses+1,sprungMassCoordinates[i][d1]);
A.set(i+3,numSprungMasses+2,1.0f);
//rhs.
b[i+3] = 2*mbar;
}