Wiimote Mouse Script v:1.4.1

Official forum for open source FreePIE discussion and development.
Post Reply
WestleyTwain
One Eyed Hopeful
Posts: 13
Joined: Mon Jan 29, 2018 4:41 pm

Wiimote Mouse Script v:1.4.1

Post by WestleyTwain »

Hello all! I wanted to share with you all my take on a wiiMotionPlus mouse script.

Here's the releases page on GitHub.

Features Include:
-Hold B to move Cursor, Left Click = A, Right Click = +, Mid Click = Home
-Hold - and point up and down to scroll up and down
-Hold 1 and roll like a volume knob to adjust the volume
I also put all the button mappings and fine tuning near the top of the script so that you can more easily make it your own.

1.4.1: now with lednerg's cursor movement with roll correction!

Enjoy!
WestleyTwain
One Eyed Hopeful
Posts: 13
Joined: Mon Jan 29, 2018 4:41 pm

Re: Wiimote Mouse Script v:1.4.1

Post by WestleyTwain »

Version 1.4.1 is now out!
MeteorFalling2
One Eyed Hopeful
Posts: 42
Joined: Thu Dec 08, 2016 10:23 pm

Re: Wiimote Mouse Script v:1.4.1

Post by MeteorFalling2 »

Nice! glad someone else was interested in having roll compensation. I managed to get similar results relying on accelerator data. Just much crappier programming on my end. Unfortunately it doesn't quite work well enough for fps games as quick movements tend to cause drift. It seems your script does this too.

There is a more advanced version of lednerg mouse script that uses gyro information in addition to accelerometer information. I found it here: https://www.youtube.com/watch?v=CK7zAX-NHzo It is named 'WiimotePlus FPS - COD Series'. It removes the 'arc' that the accel data causes as well as the drifting cursor.

I tried to replicate the script without luck. It seems to use something like a complementary filter that relies on samples of gyro and accel data over time. This is something I don't know how to do in freepie in any meaningful way.

This is the closest I got, and is great for movements with periodic resting. It uses gyro data and compares it with 3 time stamps of accel data over a period of 100 ms. If the accel time stamps are similar for 200 ms, it means the wiimote is relatively still. If this is the case, then the gyro roll information is discarded, and the new gyro roll become what the accel roll is. This is how I deal with the drift of the gyro. I know the code looks horrible, I'm a newbie. There is leftover pieces of the complementary filter in this code as I tried several version of ideas trying to implement it. I eventually just gave up as a true complementary filter would be the best option. This leftover code doesn't impact the function much.

Code: Select all

def update():
	global roll
	global trigger1
	global trigger2
	global trigger3
	global pitchAcc1
	global pitchAcc2
	global pitchAcc3
	global pitch
	global roll
	global rotation_drift_offset
	
	#diagnostics.watch(math.radians(filters.mapRange(wiimote[0].ahrs.roll), -180, 180, 0, 0))

   #roll = math.degrees(math.atan2(-wiimote[0].acceleration.x, -wiimote[0].acceleration.z) + math.pi)
	#angle = 0.98 * (roll + wiimote[0].ahrs.roll * 0.01)	
	yaw = wiimote[0].ahrs.yaw
	pitch = wiimote[0].ahrs.pitch
	roll = wiimote[0].ahrs.roll - rotation_drift_offset


	if filters.stopWatch((trigger1 == True), 2):
		pitchAcc1 = math.atan2(wiimote[0].acceleration.x, wiimote[0].acceleration.z) *180 / 3.14159265359
		trigger2 = True
		trigger1 = False
		
	if filters.stopWatch((trigger2 == True), 50):
		pitchAcc2 = math.atan2(wiimote[0].acceleration.x, wiimote[0].acceleration.z) *180 / 3.14159265359
		trigger3 = True
		trigger2 = False
		
	if filters.stopWatch((trigger3 == True), 100):
		pitchAcc3 = math.atan2(wiimote[0].acceleration.x, wiimote[0].acceleration.z) *180 / 3.14159265359
		trigger1 = True
		trigger3 = False	

	pitchAcc = (pitchAcc1 + pitchAcc2 + pitchAcc3)/ 3
	
	if filters.stopWatch(((pitchAcc2 + 1 >= pitchAcc1) and (pitchAcc1 + 2 >= pitchAcc2) and (pitchAcc3 + 1 >= pitchAcc1) and  (pitchAcc1 + 2 >= pitchAcc3)), 200):
		rotation_drift_offset = wiimote[0].ahrs.roll - pitchAcc
			
	#roll = 0.98 * (pitchAcc + wiimote[0].ahrs.roll * 0.01) + (wiimote[0].acceleration.x * 0.02)
	roll = roll * 0.98 + pitchAcc * 0.04
	x = filters.deadband(filters.delta(yaw),0.01)* mouse_sensitivity
	y = filters.deadband(-filters.delta(pitch),0.01)* mouse_sensitivity
	
	if wiimote[0].buttons.button_down(WiimoteButtons.A): 
		mouse.deltaX = math.cos(math.radians(roll))*x -math.sin(math.radians(roll))*y;
		mouse.deltaY = math.sin(math.radians(roll))*x +math.cos(math.radians(roll))*y;
		



	diagnostics.watch(math.cos(wiimote[0].ahrs.roll)*-wiimote[0].motionplus.yaw_down)
	diagnostics.watch(math.sin(wiimote[0].ahrs.roll)*wiimote[0].motionplus.pitch_left)
	diagnostics.watch(wiimote[0].acceleration.z)
	diagnostics.watch(roll)	
	diagnostics.watch(pitchAcc1)
	diagnostics.watch(pitchAcc2)
	diagnostics.watch(pitchAcc3)
	diagnostics.watch(math.cos(math.radians(wiimote[0].ahrs.roll)))	

if starting:
	rotation_drift_offset = 0
	roll = 0
	pitch = 0
	trigger1 = True
	trigger2 = 0
	trigger3 = 0
	pitchAcc1 = 0
	pitchAcc2 = 0
	pitchAcc3 = 0
	roll = 0
	mouse_sensitivity = 10
	system.setThreadTiming(TimingTypes.HighresSystemTimer)
	system.threadExecutionInterval = 2
	wiimote[0].motionplus.update += update
	wiimote[0].enable(WiimoteCapabilities.MotionPlus | WiimoteCapabilities.MotionPlus)
Post Reply

Return to “FreePIE”