OneEuroFilterUnreal icon indicating copy to clipboard operation
OneEuroFilterUnreal copied to clipboard

Rotator wrap around error.

Open RMKeene opened this issue 3 years ago • 2 comments

With Rotator One Euro Filters the wrap around 0 to 360 degrees is not handled. E.g. if raw yaw is currently 295 degrees and the new yaw is 3 degrees that should be a +8 degrees difference. Instead it is seen as a -292 degree difference and so the interpolation in the filter slews the long way around the yaw circle.

The correct way to do it is to have the input check incoming new values of rotation against the current raw value and if the difference is > 180 or < -180 fudge the incoming angle by adding or subtracting 360 degrees. I did this in blueprints and it works.

It should be in the C++. I may submit a C++ code fix and pull request.

RMKeene avatar Jan 20 '22 00:01 RMKeene

Ok, fixed. But I do not have permission to push (even as a branch).

Here is the code in OneEuroFilterBlueprintDatatypes.cpp...

void FOneEuroFilterRotator::SetValue(FRotator NewValue) {

if (!bInitialized)
{
	TheFilter = MakeShareable(new OneEuroFilter<FRotator>(Frequency, MinCutoff, Beta, DCutoff));

	bInitialized = true;
}

// Compensate for circle degrees wrap around.
float diff = NewValue.Roll - Value.Roll;
if (diff > 180.0f)
	NewValue.Roll -= 360.0f;
else if (diff < -180.0)
	NewValue.Roll += 360.0f;

diff = NewValue.Pitch - Value.Pitch;
if (diff > 180.0f)
	NewValue.Pitch -= 360.0f;
else if (diff < -180.0)
	NewValue.Pitch += 360.0f;

diff = NewValue.Yaw - Value.Yaw;
if (diff > 180.0f)
	NewValue.Yaw -= 360.0f;
else if (diff < -180.0)
	NewValue.Yaw += 360.0f;

Value = NewValue;

if (TheFilter.IsValid())
	FilteredValue = TheFilter->Filter(Value);

};

RMKeene avatar Jan 20 '22 01:01 RMKeene

Note that the Unity version of the filter has this problem. The solution there would be to flag Rotator style values as needing wrap around and then do a very similar fix for those.

RMKeene avatar Jan 20 '22 01:01 RMKeene