WiiLi Wiki frontpage Include your post in the News Get links Hoteles Quito
WiiLi.org Forum Index WiiLi.org
a new revolution
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

5DOF Tracking (using Sensor Bar)
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    WiiLi.org Forum Index -> Wii Scripts
View previous topic :: View next topic  
Author Message
CarlKenner
Site Admin


Joined: 29 Nov 2006
Posts: 614

Digg It
PostPosted: 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
View user's profile Send private message Send e-mail
blahblah



Joined: 18 Dec 2006
Posts: 9

Digg It
PostPosted: 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
View user's profile Send private message
CarlKenner
Site Admin


Joined: 29 Nov 2006
Posts: 614

Digg It
PostPosted: 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
View user's profile Send private message Send e-mail
TylerK



Joined: 18 Dec 2006
Posts: 384
Location: Springfield, IL

Digg It
PostPosted: 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
View user's profile Send private message
kunalkunal2



Joined: 13 Dec 2006
Posts: 279

Digg It
PostPosted: 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
View user's profile Send private message
blahblah



Joined: 18 Dec 2006
Posts: 9

Digg It
PostPosted: 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
View user's profile Send private message
kunalkunal2



Joined: 13 Dec 2006
Posts: 279

Digg It
PostPosted: 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..... Shocked
_________________
Check out my collection of my wii script's
freewebs.com/kunalkunal2
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    WiiLi.org Forum Index -> Wii Scripts All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
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