 |
WiiLi.org a new revolution
|
| View previous topic :: View next topic |
| Author |
Message |
CarlKenner Site Admin
Joined: 29 Nov 2006 Posts: 614
Digg It |
Posted: Tue Jan 23, 2007 1:07 am Post subject: 5DOF Tracking (using Sensor Bar) |
|
|
Edit: Oops, I forgot the IR offset.
OK, I finally got 5DOF tracking working! But it only works while you are pointing the Wiimote at the sensor bar. There is no limit to the tracking range, except for the strength and angle of your leds. But if you want to track the position of your wiimote down near the ground, you need to point it up towards the sensor bar.
For the 5DOF you have two choices... either you promise not to yaw the Wiimote at all (you can pitch and roll, but you must keep the horizontal rotation at 0), or you promise never to move the wiimote sideways at all and you only yaw it (note that it measures from the sensor at the front, so you need to keep the front still while you yaw). Set var.NoYawAllowed to true or false below to choose which one you want.
You must measure the distance between the middle of the left dot and the middle of the right dot on your sensor bar, and put that number into the script below. You can use whatever units you want.
| Code: | // My best IR Mouse Script, with 5DOF Tracking
// By Carl Kenner
// Change these values:
var.SensorBarSeparation = 7.5 inches // distance between middles of two sensor bar dots
var.NoYawAllowed = true // Calculates X if no yaw is allowed, otherwise calculates Yaw but not X
var.IRMulX = 1.2
var.IRMulY = 1.2
var.IROffsetX = 0 // add to mouse.x
var.IROffsetY = 0 // add to mouse.y
var.IRLeftButton = Wiimote.A
var.IRRightButton = Wiimote.B
// Compensate for roll
var.c = cos(Smooth(wiimote.roll, 10))
var.s = sin(Smooth(wiimote.roll, 10))
if wiimote.dot1vis then
var.dot1x = var.c*(511.5-wiimote.dot1x)/511.5 - var.s*(wiimote.dot1y-383.5)/511.5
var.dot1y = var.s*(511.5-wiimote.dot1x)/511.5 + var.c*(wiimote.dot1y-383.5)/511.5
end if
if wiimote.dot2vis then
var.dot2x = var.c*(511.5-wiimote.dot2x)/511.5 - var.s*(wiimote.dot2y-383.5)/511.5
var.dot2y = var.s*(511.5-wiimote.dot2x)/511.5 + var.c*(wiimote.dot2y-383.5)/511.5
end if
// if both dots are visible check which is which and how far apart
if wiimote.dot1vis and wiimote.dot2vis then
if var.dot1x <= var.dot2x then
var.leftdot = 1
var.dotdeltay = var.dot2y - var.dot1y
else
var.leftdot = 2
var.dotdeltay = var.dot1y - var.dot2y
end if
var.dotdeltax = abs(var.dot1x-var.dot2x)
var.DotSep = hypot(var.dotdeltax, var.dotdeltay) * 511.5
var.IRDistance = var.SensorBarSeparation * 1320 / var.DotSep
end if
// sort out the position of the left and right dots
if var.leftdot = 1 then
if wiimote.dot1vis and wiimote.dot2vis then
var.LeftDotX = var.dot1x
var.LeftDotY = var.dot1y
var.LeftDotVis = true
var.RightDotX = var.dot2x
var.RightDotY = var.dot2y
var.RightDotVis = true
else if wiimote.dot1vis then
if hypot(var.leftdotx-var.dot1x,var.leftdoty-var.dot1y) <= hypot(var.rightdotx-var.dot1x,var.rightdoty-var.dot1y) then
// is the real dot 1
var.LeftDotX = var.dot1x
var.LeftDotY = var.dot1y
var.RightDotX = var.dot1x + var.dotdeltax
var.RightDotY = var.dot1y + var.dotdeltay
var.LeftDotVis = true
var.RightDotVis = false
else
// was originally dot 2, but now called dot 1.
var.leftdot = 2 // this dot (1) is actually the right dot
var.LeftDotX = var.dot1x - var.dotdeltax
var.LeftDotY = var.dot1y - var.dotdeltay
var.RightDotX = var.dot1x
var.RightDotY = var.dot1y
var.RightDotVis = true
var.LeftDotVis = false
end if
else if wiimote.dot2vis then
var.LeftDotX = var.dot2x - var.dotdeltax
var.LeftDotY = var.dot2y - var.dotdeltay
var.RightDotX = var.dot2x
var.RightDotY = var.dot2y
var.RightDotVis = true
var.LeftDotVis = false
end if
else if var.leftdot = 2 then
if wiimote.dot1vis and wiimote.dot2vis then
var.LeftDotX = var.dot2x
var.LeftDotY = var.dot2y
var.LeftDotVis = true
var.RightDotX = var.dot1x
var.RightDotY = var.dot1y
var.RightDotVis = true
else if wiimote.dot1vis then
if hypot(var.leftdotx-var.dot1x,var.leftdoty-var.dot1y) <= hypot(var.rightdotx-var.dot1x,var.rightdoty-var.dot1y) then
var.leftdot = 1 // dot 1 is now the left dot
var.LeftDotX = var.dot1x
var.LeftDotY = var.dot1y
var.RightDotX = var.dot1x + var.dotdeltax
var.RightDotY = var.dot1y + var.dotdeltay
var.LeftDotVis = true
var.RightDotVis = false
else
// the real dot 1 (on the right)
var.LeftDotX = var.dot1x - var.dotdeltax
var.LeftDotY = var.dot1y - var.dotdeltay
var.RightDotX = var.dot1x
var.RightDotY = var.dot1y
var.RightDotVis = true
var.LeftDotVis = false
end if
else if wiimote.dot2vis then
var.RightDotX = var.dot2x + var.dotdeltax
var.RightDotY = var.dot2y + var.dotdeltay
var.LeftDotX = var.dot2x
var.LeftDotY = var.dot2y
var.LeftDotVis = true
var.RightDotVis = false
end if
else
var.LeftDotX = var.dot1x
var.LeftDotY = var.dot1y
var.RightDotX = var.LeftDotX
var.RightDotY = var.LeftDotY
var.LeftDotVis = true
var.RightDotVis = true
end if
// Find the imaginary middle dot
var.MiddleDotX = (var.leftdotx + var.rightdotx)/2
var.MiddleDotY = (var.leftdoty + var.rightdoty)/2
var.MiddleDotVis = wiimote.dot1vis or wiimote.dot2vis
if var.MiddleDotVis then
var.TotalPitch = atan2(511.5*var.MiddleDotY,1320) + Wiimote.Pitch
var.DotYaw = atan2(-511.5*var.MiddleDotX,1320) // assume yaw is 0
var.WiimoteYawNoX = atan2(511.5*var.MiddleDotX,1320)
var.WiimoteXNoYaw = -sin(var.dotyaw)*var.IRDistance
var.WiimoteY = -sin(var.totalpitch)*var.IRDistance
var.WiimoteZ = (-sqrt(sqr(var.IRDistance) - sqr(var.WiimoteY)))*var.IRDistance/RemoveUnits(var.IRDistance)
end if
// scale it to the screen range 0 to 1
var.IRx = var.IRMulX*var.middledotx/2 + 0.5 + var.IROffsetX
var.IRy = var.IRMulY*var.middledoty*1023/767/2 + 0.5 + var.IROffsetY
var.IRvis = wiimote.dot1vis or wiimote.dot2vis
var.IROnScreen = 0 <= var.IRx <= 1 and 0 <= var.IRy <= 1
// is it off the screen?
var.IRTooFarLeft = var.IRx < 0 or (var.IRx < 0.1 and (not var.IRvis))
var.IRTooFarRight = var.IRx > 1 or (var.IRx > 1-0.1 and (not var.IRvis))
var.IRTooFarUp = var.IRy < 0 or (var.IRy < 0.1 and (not var.IRvis))
var.IRTooFarDown = var.IRy > 1 or (var.IRy > 1-0.1 and (not var.IRvis))
// Heavily smooth small movements, but do zero lag for quick movements
var.MoveAmount = 1024*hypot(delta(var.IRx), delta(var.IRy))
if smooth(var.MoveAmount) > 12 then
var.SmoothX = var.IRx
var.SmoothY = var.IRy
var.LastSureFrame = PIE.Frame
else if (PIE.frame-var.LastSureFrame) > 18 then
var.SmoothX = Smooth(var.IRx, 18, 4/1024)
var.SmoothY = Smooth(var.IRy, 18, 4/1024)
else if (PIE.frame-var.LastSureFrame) > 14 then
var.SmoothX = Smooth(var.IRx, 14, 4/1024)
var.SmoothY = Smooth(var.IRy, 14, 4/1024)
else if (PIE.frame-var.LastSureFrame) > 10 then
var.SmoothX = Smooth(var.IRx, 10, 4/1024)
var.SmoothY = Smooth(var.IRy, 10, 4/1024)
else if (PIE.frame-var.LastSureFrame) > 6 then
var.SmoothX = Smooth(var.IRx, 6, 4/1024)
var.SmoothY = Smooth(var.IRy, 6, 4/1024)
else if (PIE.frame-var.LastSureFrame) > 2 then
var.SmoothX = Smooth(var.IRx, 2, 4/1024)
var.SmoothY = Smooth(var.IRy, 2, 4/1024)
end if
// Freeze the mouse cursor while they start pressing the button
// otherwise it will make the cursor jump
var.Freeze = (var.IRLeftButton or var.IRRightButton) and KeepDown(pressed(var.IRLeftButton) or pressed(var.IRRightButton), 600ms)
// Only change the mouse position if pointing at the screen
// otherwise they can still use a real mouse
if var.IRvis and (not var.Freeze) then
mouse.x = var.SmoothX
mouse.y = var.SmoothY
end if
// delay the buttons slightly so we have time to freeze the cursor (is that needed?)
mouse.LeftButton = var.IRLeftButton and (not KeepDown(pressed(var.IRLeftButton), 40ms))
mouse.RightButton = var.IRRightButton and (not KeepDown(pressed(var.IRRightButton), 40ms))
if var.NoYawAllowed then
debug = 'X: '+var.WiimoteXNoYaw+', Y: '+var.WiimoteY+', Z: '+var.WiimoteZ+', Yaw: 0, Pitch: '+Wiimote.Pitch+', Roll: '+Wiimote.Roll
else
debug = 'X: 0, Y: '+var.WiimoteY+', Z: '+var.WiimoteZ+', Yaw: '+var.WiimoteYawNoX+', Pitch: '+Wiimote.Pitch+', Roll: '+Wiimote.Roll
endif
|
Last edited by CarlKenner on Thu Feb 01, 2007 1:57 am; edited 1 time in total |
|
| Back to top |
|
 |
blahblah
Joined: 18 Dec 2006 Posts: 9
Digg It |
Posted: Tue Jan 23, 2007 7:14 pm Post subject: |
|
|
This is great! Finally getting close to what I was hoping for from the wiimote as a midi controller. My hope is that someone can take this and create some more sophisticated smoothing and ballistic characteristics., making it even more fun to use.
Thanks Carl |
|
| Back to top |
|
 |
CarlKenner Site Admin
Joined: 29 Nov 2006 Posts: 614
Digg It |
Posted: Tue Jan 23, 2007 10:58 pm Post subject: |
|
|
I'm surprised this didn't get more responses. I thought it was really cool. Oh well!
Now I just need to see if I can work out some way of calculating the velocity based on the acceleration, and then working out the position based on the velocity. Then I can make it keep tracking even when it can't see the sensor bar. |
|
| Back to top |
|
 |
TylerK

Joined: 18 Dec 2006 Posts: 384 Location: Springfield, IL
Digg It |
Posted: Wed Jan 24, 2007 1:47 am Post subject: |
|
|
| I think that technically it's an amazing feat, but I can't think of a way to apply it to game or application or... anything really. But I'm sure someone will come along that can put this to a brilliant use. Good work, Carl! |
|
| Back to top |
|
 |
kunalkunal2
Joined: 13 Dec 2006 Posts: 279
Digg It |
Posted: Wed Jan 24, 2007 2:09 am Post subject: |
|
|
So what exactly does this do?
you can use pitch/roll with a sensor bar?
(Sry im kinda inexperienced) _________________ Check out my collection of my wii script's
freewebs.com/kunalkunal2 |
|
| Back to top |
|
 |
blahblah
Joined: 18 Dec 2006 Posts: 9
Digg It |
Posted: Wed Jan 24, 2007 2:54 am Post subject: |
|
|
There are 6 things that you can know about the position of an object in space. This allows you to know 5 of them about your wiimote.
Practically :
a) for pointing tasks this allows _very_ natural and intuitive screen pointing - much more so than other scripts
b) for gaming purposes it allows you to interpret the users motions much more fully than with other scripts
c) if you use the wiimote as a gestural controller for musical instruments (my use) you can derive a lot of parameters from simple movements in a fairly predictable and intuitive way, making it a much more pleasing way of interacting with your instruments. |
|
| Back to top |
|
 |
kunalkunal2
Joined: 13 Dec 2006 Posts: 279
Digg It |
Posted: Thu Jan 25, 2007 3:19 am Post subject: |
|
|
| blahblah wrote: | There are 6 things that you can know about the position of an object in space. This allows you to know 5 of them about your wiimote.
Practically :
a) for pointing tasks this allows _very_ natural and intuitive screen pointing - much more so than other scripts
b) for gaming purposes it allows you to interpret the users motions much more fully than with other scripts
c) if you use the wiimote as a gestural controller for musical instruments (my use) you can derive a lot of parameters from simple movements in a fairly predictable and intuitive way, making it a much more pleasing way of interacting with your instruments. |
WOW, Im going to try this out, but now time 2 sleep.....  _________________ Check out my collection of my wii script's
freewebs.com/kunalkunal2 |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|