Kalmanize this... no, seriously... Samsung phone as a HMD

Official forum for open source FreePIE discussion and development.
Post Reply
Elwood
One Eyed Hopeful
Posts: 22
Joined: Mon May 12, 2014 7:51 am

Kalmanize this... no, seriously... Samsung phone as a HMD

Post by Elwood »

Hello!

I've been trying recently to setup my Opendive HMD to work with freetrack/ trackIR via Freepie.

So I found out that I have to use the .googleYaw, .googlePitch if I want to use the phone in the HMD for tracking. Ok, no problem.

Then I found out I have a Samsung phone. S3. So... big problems ahead. The .google readouts are extremely noisy even when the phone is resting, have inertia and worst of all bounce back after fast movements.

Utilising my leet programming skills (hint: none whatsoever) I managed to put together a 3-level filering "technique" that kinda works. It uses filters.simple. A LOT. Here goes:

Code: Select all

def update():
	global yaw
	yaw = -filters.simple((android[0].googleYaw), 0.75)/3
	global pitch
	pitch = -filters.simple((android[0].googleRoll), 0.5)/3
	global lastYaw
	global lastPitch
	global yawShift
	global pitchShift
	global DeadBand
	global FilterType

	if (abs(filters.delta(yaw)) > DeadBand):
		yawShift = yaw
		lastYaw = filters.mapRange(abs(filters.delta(yawShift)), 0, 0.005, 0, 1)
		FilterType = 1
	else:
		if (filters.delta(lastYaw) == 0):
			if ((abs(abs(yawShift)-abs(yaw))) > DeadBand_max):
				yawShift = yaw
				lastYaw = 0.01
				FilterType = 2
			else:
				lastYaw = 0.001
				FilterType = 3
	if (lastYaw > 1):
		lastYaw = 1	

	if (abs(filters.delta(pitch)) > DeadBand):
		pitchShift = pitch
		lastPitch = filters.mapRange(abs(filters.delta(pitchShift)), 0, 0.005, 0, 1)
	else:
		if (filters.delta(lastPitch) == 0):
			if ((abs(abs(pitchShift)-abs(pitch))) > DeadBand_max):
				pitchShift = pitch
				lastPitch = 0.01
			else:
				lastPitch = 0.001
				FilterType = 3
	if (lastPitch > 1):
		lastPitch = 1	

if starting:
	centerYaw = 0
	centerPitch = 0
	DeadBand = 0.001
	DeadBand_max = 0.001
	yaw = 0
	pitch = 0
	yawShift = 0
	pitchShift = 0
	yawDiff = 0
	pitchDiff = 0
	lastYaw = 0
	lastPitch = 0
	FilterType = 0

	android[0].update += update

freeTrack.yaw  = filters.simple(yawShift, (1 - lastYaw)) - centerYaw
freeTrack.pitch  = filters.simple(pitchShift, (1 - lastPitch)) - centerPitch

if keyboard.getKeyDown(Key.LeftControl) and keyboard.getPressed(Key.C):
	centerYaw = yaw
	centerPitch = pitch
	centerRoll = roll
What it does is filter the values with variable strength: only some filtering when there is serious movement, then when there is no big movement the script checks if the position has not drifted too much (when moving the phone very slowly so that check no. 1 fails) and applies a .99 filter on that, then it filters everything else with an extreme .999 filters.simple.

I tried reading about this Kalman filtering technique. I'm no programmer or math expert, so it took only a couple of sentences to make my head hurt. So I went with the above brute "simple" method instead. But as you imagine, the effect is not perfect - too slow due to excessive filtering.

So the question is: are you planning to implement better filtering techniques in freePIE? One that would possibly look like filters.Kalman(input, filter value)? or is that not that simple?

I read here that you are using Kalman to filter the other readout method (not raw data), is that possible to filter single values the same way?
User avatar
Fredz
Petrif-Eyed
Posts: 2255
Joined: Sat Jan 09, 2010 2:06 pm
Location: Perpignan, France
Contact:

Re: Kalmanize this... no, seriously... Samsung phone as a HM

Post by Fredz »

You may have a look here for a simpler algorithm for sensor fusion :
http://www.x-io.co.uk/open-source-imu-a ... lgorithms/
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Kalmanize this... no, seriously... Samsung phone as a HM

Post by CyberVillain »

When using orientation mode (googleYaw etc) the values are already fused and filtered by the phone. We use the Mahony filter in FreePIE to fuse raw data but I do not know how it can be used on allready fused data

edit: A kalman filter uses two signals (gyro and acc for example) and fuses the two to one. Here we only have one signal. Maybe if you fuse it with the last known sample
Elwood
One Eyed Hopeful
Posts: 22
Joined: Mon May 12, 2014 7:51 am

Re: Kalmanize this... no, seriously... Samsung phone as a HM

Post by Elwood »

Thank you for the answers!

@Fredz:
Thank you for the example scripts, however I will not be able to implement those in FreePIE... these are in C and Matlab, not Python. And they contain evil things like quart... quurt... qanterniars? Last time I had a math lesson was in highschool, and that was almost 20 years ago. And even then I don't recall seeing any of these guys;).
Hence my question - is implementing more sophisticated filering techniques part of the FreePIE's Official Development Plan? :twisted:

@Cybervilain:
I can't imagine how the unfiltered values must look, if the >supposedly< filtered by the phone .google readouts vary by as much as 0.5 degree frame-to-frame while the phone is resting... the sensors must be some garbage bin hardware, or the internal filtering sucks.

I did not do much testing of your implemented Mahony filter method, cause it was said it was unsuitable for HMD (phone must be positioned flat) but from what I've seen the results are much better. I will check that again tonight.

Is there a reason that the same method cannot be implemented for HMD mode?
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Kalmanize this... no, seriously... Samsung phone as a HM

Post by CyberVillain »

Elwood wrote: Hence my question - is implementing more sophisticated filering techniques part of the FreePIE's Official Development Plan? :twisted:
Yupp, filters.simple was just a quick mockup I did, but i never got around to implement more. There are too few devs workign on FreePIE ;)
Elwood wrote: @Cybervilain:
I can't imagine how the unfiltered values must look, if the >supposedly< filtered by the phone .google readouts vary by as much as 0.5 degree frame-to-frame while the phone is resting... the sensors must be some garbage bin hardware, or the internal filtering sucks.
Its a Samsung phone ;) (HTC owner myself)
Elwood wrote: I did not do much testing of your implemented Mahony filter method, cause it was said it was unsuitable for HMD (phone must be positioned flat) but from what I've seen the results are much better. I will check that again tonight.

Is there a reason that the same method cannot be implemented for HMD mode?
Well, I'm actually not an expert on IMU fusing. My guess is that the onboard fusing somehow takes into account that the magnometer behaves strange when not placed flat. Its just a guess. Anyway, Mahony fusion does not. But this can very, from phone to phone so please try

Maohny is not a raw implementation of kalman, it has special cases for gyro and acc. I do not know what will happen if you give it gyro = current sample and acc = last sample
Elwood
One Eyed Hopeful
Posts: 22
Joined: Mon May 12, 2014 7:51 am

Re: Kalmanize this... no, seriously... Samsung phone as a HM

Post by Elwood »

So for now there is no way to test these filters, unless somebody is able to implement them?

I guess I'll have to wait for that to happen ;) and live with the latency in the meantime.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Kalmanize this... no, seriously... Samsung phone as a HM

Post by CyberVillain »

I can create a test version where you can access Mahony from script.. I am very busy lately though
Elwood
One Eyed Hopeful
Posts: 22
Joined: Mon May 12, 2014 7:51 am

Re: Kalmanize this... no, seriously... Samsung phone as a HM

Post by Elwood »

That would be great, however if you have lots of work I can wait ;)

BTW, thanks for the work you are doing for the community!
Post Reply

Return to “FreePIE”