mirror of
https://github.com/cemu-project/DS4Windows.git
synced 2024-11-30 04:54:20 +01:00
Changed precision of angle values sent to x360 virtual controller from 1 degree to 1/10th degree precision. Also, minimized "center deadzone" gap (the previous optimization of angle calculation was too aggressive in wheel center position).
This commit is contained in:
parent
4f9831cf3f
commit
1cb04d03ad
@ -3781,6 +3781,9 @@ namespace DS4Windows
|
|||||||
|
|
||||||
// BEGIN: SixAxis steering wheel emulation logic
|
// BEGIN: SixAxis steering wheel emulation logic
|
||||||
|
|
||||||
|
private const int C_WHEEL_ANGLE_PRECISION = 10; // 1=precision of one degree, 10=precision of 1/10 of degree. Bigger number means fine graned precision
|
||||||
|
private const int C_WHEEL_ANGLE_PRECISION_DECIMALS = (C_WHEEL_ANGLE_PRECISION == 1 ? 0 : C_WHEEL_ANGLE_PRECISION/10);
|
||||||
|
|
||||||
// "In-game" calibration process:
|
// "In-game" calibration process:
|
||||||
// TODO: Launching a calibration process should probably be a special action which allows multiple key bindings to launch a specific task.
|
// TODO: Launching a calibration process should probably be a special action which allows multiple key bindings to launch a specific task.
|
||||||
// - Place controller at "steering wheel center" position and press DS4 Option button to start the calibration (Profile should have "SASteeringWheelEmulationAxis" option set to LXPos, LYPos, RXPos or RYPos value).
|
// - Place controller at "steering wheel center" position and press DS4 Option button to start the calibration (Profile should have "SASteeringWheelEmulationAxis" option set to LXPos, LYPos, RXPos or RYPos value).
|
||||||
@ -3829,7 +3832,7 @@ namespace DS4Windows
|
|||||||
{
|
{
|
||||||
Int32 result;
|
Int32 result;
|
||||||
|
|
||||||
if (Math.Abs(gyroAccelX - controller.wheelCenterPoint.X) <= 1 && Math.Abs(gyroAccelZ - controller.wheelCenterPoint.Y) <= 1)
|
if (gyroAccelX == controller.wheelCenterPoint.X && Math.Abs(gyroAccelZ - controller.wheelCenterPoint.Y) <= 1)
|
||||||
{
|
{
|
||||||
// When the current gyro position is "close enough" the wheel center point then no need to go through the hassle of calculating an angle
|
// When the current gyro position is "close enough" the wheel center point then no need to go through the hassle of calculating an angle
|
||||||
result = 0;
|
result = 0;
|
||||||
@ -3860,14 +3863,24 @@ namespace DS4Windows
|
|||||||
double magCD = Math.Sqrt(vectorCD.X * vectorCD.X + vectorCD.Y * vectorCD.Y);
|
double magCD = Math.Sqrt(vectorCD.X * vectorCD.X + vectorCD.Y * vectorCD.Y);
|
||||||
|
|
||||||
// Calculate angle between vectors and convert radian to degrees
|
// Calculate angle between vectors and convert radian to degrees
|
||||||
double angle = Math.Acos(dotProduct / (magAB * magCD));
|
if (magAB == 0 || magCD == 0)
|
||||||
result = Convert.ToInt32(Math.Round(angle * (180.0 / Math.PI)));
|
{
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double angle = Math.Acos(dotProduct / (magAB * magCD));
|
||||||
|
result = Convert.ToInt32( Clamp(-180.0 * C_WHEEL_ANGLE_PRECISION,
|
||||||
|
Math.Round((angle * (180.0 / Math.PI)), C_WHEEL_ANGLE_PRECISION_DECIMALS) * C_WHEEL_ANGLE_PRECISION,
|
||||||
|
180.0 * C_WHEEL_ANGLE_PRECISION)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Left turn is -180..0 and right turn 0..180 degrees
|
// Left turn is -180..0 and right turn 0..180 degrees
|
||||||
if (gyroAccelX < controller.wheelCenterPoint.X) result = -result;
|
if (gyroAccelX < controller.wheelCenterPoint.X) result = -result;
|
||||||
|
|
||||||
// Just to be sure.. Probably not needed. TODO: Add support for 360/720/900 turn ranges by counting "laps" how many times the steering wheel is turned around
|
// Just to be sure.. Probably not needed. TODO: Add support for 360/720/900 turn ranges by counting "laps" how many times the steering wheel is turned around
|
||||||
result = ClampInt(-180, result, 180);
|
//result = ClampInt(-180, result, 180);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -3974,7 +3987,6 @@ namespace DS4Windows
|
|||||||
// Show lightbar color feedback how the calibration process is proceeding.
|
// Show lightbar color feedback how the calibration process is proceeding.
|
||||||
// red / yellow / blue / green = No calibration anchors/one anchor/two anchors/three anchors calibrated (center, 90DegLeft, 90DegRight)
|
// red / yellow / blue / green = No calibration anchors/one anchor/two anchors/three anchors calibrated (center, 90DegLeft, 90DegRight)
|
||||||
// Blinking led = Controller is tilted at the current calibration point (or calibration routine just set a new anchor point)
|
// Blinking led = Controller is tilted at the current calibration point (or calibration routine just set a new anchor point)
|
||||||
// TODO: device num to flash led idx (use red for center calibrated, yellow for one 90deg and green for both 90deg calibration and then reset back to normal led)
|
|
||||||
int bitsSet = CountNumOfSetBits((int)controller.wheelCalibratedAxisBitmask);
|
int bitsSet = CountNumOfSetBits((int)controller.wheelCalibratedAxisBitmask);
|
||||||
if (bitsSet >= 3) DS4LightBar.forcedColor[device] = calibrationColor_3;
|
if (bitsSet >= 3) DS4LightBar.forcedColor[device] = calibrationColor_3;
|
||||||
else if (bitsSet == 2) DS4LightBar.forcedColor[device] = calibrationColor_2;
|
else if (bitsSet == 2) DS4LightBar.forcedColor[device] = calibrationColor_2;
|
||||||
@ -3982,13 +3994,19 @@ namespace DS4Windows
|
|||||||
else DS4LightBar.forcedColor[device] = calibrationColor_0;
|
else DS4LightBar.forcedColor[device] = calibrationColor_0;
|
||||||
|
|
||||||
result = CalculateControllerAngle(gyroAccelX, gyroAccelZ, controller);
|
result = CalculateControllerAngle(gyroAccelX, gyroAccelZ, controller);
|
||||||
if (bitsSet >= 1 && (Math.Abs(result) <= 1 || (Math.Abs(result) >= 88 && Math.Abs(result) <= 92) || Math.Abs(result) >= 178)) DS4LightBar.forcedFlash[device] = 2;
|
if (bitsSet >= 1 && (
|
||||||
else DS4LightBar.forcedFlash[device] = 0;
|
Math.Abs(result) <= 1 * C_WHEEL_ANGLE_PRECISION
|
||||||
|
|| (Math.Abs(result) >= 88 * C_WHEEL_ANGLE_PRECISION && Math.Abs(result) <= 92 * C_WHEEL_ANGLE_PRECISION)
|
||||||
|
|| Math.Abs(result) >= 178 * C_WHEEL_ANGLE_PRECISION
|
||||||
|
))
|
||||||
|
DS4LightBar.forcedFlash[device] = 2;
|
||||||
|
else
|
||||||
|
DS4LightBar.forcedFlash[device] = 0;
|
||||||
|
|
||||||
DS4LightBar.forcelight[device] = true;
|
DS4LightBar.forcelight[device] = true;
|
||||||
//DS4LightBar.updateLightBar(controller, device);
|
//DS4LightBar.updateLightBar(controller, device);
|
||||||
|
|
||||||
LogToGuiSACalibrationDebugMsg($"Calibration values ({gyroAccelX}, {gyroAccelZ}) angle={result}\n");
|
LogToGuiSACalibrationDebugMsg($"Calibration values ({gyroAccelX}, {gyroAccelZ}) angle={result / (1.0 * C_WHEEL_ANGLE_PRECISION)}\n");
|
||||||
|
|
||||||
// Return center wheel position while gyro is calibrated, not the calculated angle
|
// Return center wheel position while gyro is calibrated, not the calculated angle
|
||||||
return 0;
|
return 0;
|
||||||
@ -3996,7 +4014,6 @@ namespace DS4Windows
|
|||||||
|
|
||||||
|
|
||||||
// If calibration values are missing then use "educated guesses" about good starting values.
|
// If calibration values are missing then use "educated guesses" about good starting values.
|
||||||
// TODO. Use pre-calibrated default values from configuration file.
|
|
||||||
if (controller.wheelCenterPoint.IsEmpty)
|
if (controller.wheelCenterPoint.IsEmpty)
|
||||||
{
|
{
|
||||||
if (!Global.LoadControllerConfigs(controller))
|
if (!Global.LoadControllerConfigs(controller))
|
||||||
@ -4026,10 +4043,10 @@ namespace DS4Windows
|
|||||||
|
|
||||||
// Keep outputting debug data 30secs after the latest re-calibration event (user can check these values from the log screen of DS4Windows GUI)
|
// Keep outputting debug data 30secs after the latest re-calibration event (user can check these values from the log screen of DS4Windows GUI)
|
||||||
//if (((TimeSpan)(DateTime.Now - prevRecalibrateTime)).TotalSeconds < 30)
|
//if (((TimeSpan)(DateTime.Now - prevRecalibrateTime)).TotalSeconds < 30)
|
||||||
// LogToGuiSACalibrationDebugMsg($"DEBUG gyro=({gyroAccelX}, {gyroAccelZ}) angle={result}");
|
// LogToGuiSACalibrationDebugMsg($"DEBUG gyro=({gyroAccelX}, {gyroAccelZ}) angle={result / (1.0 * C_WHEEL_ANGLE_PRECISION)}");
|
||||||
|
|
||||||
// Scale input to a raw x360 thumbstick output scale
|
// Scale input to a raw x360 thumbstick output scale
|
||||||
return (((result - (-180)) * (32767 - (-32768))) / (180 - (-180))) + (-32768);
|
return (((result - (-180 * C_WHEEL_ANGLE_PRECISION)) * (32767 - (-32768))) / (180 * C_WHEEL_ANGLE_PRECISION - (-180 * C_WHEEL_ANGLE_PRECISION))) + (-32768);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// END: SixAxis steering wheel emulation logic
|
// END: SixAxis steering wheel emulation logic
|
||||||
|
Loading…
Reference in New Issue
Block a user