Ackermann calculation seems to swap left and right wheels

I noticed that the resulting steering-angles of the ackermann-function are switched. The following code shows the corresponding part in the PxVehicleUpdate.cpp (Line 1779 - 1799)

PX_ASSERT(steer>=-1.01f && steer<=1.01f);

const PxF32 steerAngle=steer*steerGain;


//Work out the ackermann steer for +ve steer then swap and negate the steer angles if the steer is -ve.
//TODO: use faster approximate functions for PxTan/PxATan because the results don't need to be too accurate here.
const PxF32 rightSteerAngle=PxAbs(steerAngle);
const PxF32 dz=axleSeparation;
const PxF32 dx=width + dz/PxTan(rightSteerAngle);
const PxF32 leftSteerAnglePerfect=PxAtan(dz/dx);
const PxF32 leftSteerAngle=rightSteerAngle + ackermannAccuracy*(leftSteerAnglePerfect-rightSteerAngle);
*rightAckermannSteerAngle=physx::intrinsics::fsel(steerAngle, rightSteerAngle, -leftSteerAngle);
*leftAckermannSteerAngle=physx::intrinsics::fsel(steerAngle, leftSteerAngle, -rightSteerAngle);

In case of a positive steeering-input (steering to the left) the rightSteerAngle results in a greater angle than the leftSteerAngle. The opposite should be the case. Same is true for negative incoming steering-values.
I was able to fix the issue by changing the lines 1793-1797 like this, to keep the calculation comprehensible:

const PxF32 leftSteerAngle=PxAbs(steerAngle);
const PxF32 dz=axleSeparation;
const PxF32 dx=width + dz/PxTan(leftSteerAngle);
const PxF32 rightSteerAnglePerfect=PxAtan(dz/dx);
const PxF32 rightSteerAngle=leftSteerAngle + ackermannAccuracy*(rightSteerAnglePerfect-leftSteerAngle);

In the vehicle-sample and the vehicle-snippet, this is countered by negating the x-coordinate of the wheels position, so the left wheel is on the negative x-axis side and the right wheel is on the positive side. But in a right-handed coordination (like the rest is) with up-vector is the y-axis and forward equals the z-axis (like I have it configured for the vehicle-simulation), the left wheel should be on the positive x-axis-side.

Can someone else confirm this behaviour or did I miss something else?

Left and right are indeed relative to the handedness of the chosen axis system.

The key point here is that the Ackermann angle for the left wheel is applied to eFRONT_LEFT and the right angle applied to eFRONT_RIGHT. The naming convention in the code may be a bit woolly but I don’t see a bug here.



Thanks for your answer Gordon,

so this means that the naming of left and right is based on a left handed system?
Based on the samples I thought everything is kept right handed. Even the visual debugger uses right handed as default. But I now see, that even the inputs are swapped, so I guess I just have to take that into account.



Left and right are not documented in the sdk so I can see plenty of scope for confusion.

“Right” means further along the relevant axis in a positive direction than “left”. I hope this definition makes sense.