Thanks for the inquiry. You are right that there are many possible methods to determine the identity of a marker. Intensity and color are not possible with our hardware. In fact, the PPT hardware does not ever inform you of the lights’ absolute identity. What we do provide is tracking of multiple points but whose identity may be swapping in a manner that you’ve experienced. We are finalizing the release of a free PPT upgrade that will greatly reduce the incidence of swapping, but even then it is still up to the application engineer to determine absolute identity. For you particular application, our suggest right now is to apply the constraint that the users hands must always be below the head. This then reduces the problem to identity which of two lights is the left and right hand. If again you apply a constraint that the left handle is always to the left of the right hand, then this determination too becomes almost trivial.
Below I show some code that solves the identification for the scenario described above. I first show a snippet which I expect replicates what I guess to be your current programming method in which you automatically engage automatic head tracking of the first of 3 lights. The problem with method is that you’re always stuck with the light always updating the head even when that light changes identity and becomes the hand.
PHP Code:
leftHand = viz.add('thehand.wrl') # model of a hand
rightHand = viz.add('thehand.wrl') # model of a hand
ori = viz.add('intersense.dls')
pos = viz.add('vizppt.dls')
# Turn on automatic head tracking / Vizard will use any sensor
# devices added prior to this call, which here means both
# orientation and position tracking will be turned on for the
# main viewpoint.
viz.tracker()
# Get handles to lights #2 and #3
light2 = viz.add('vizppt.dls') # Left hand
light3 = viz.add('vizppt.dls') # Right hand
def ontimer(num):
data = handL.get()
leftHand.translate(data[0], data[1], data[2])
data = handR.get()
rightHand.translate(data[0], data[1], data[2])
viz.callback(viz.TIMER_EVENT,ontimer)
viz.starttimer(1, .01, viz.FOREVER)
Now, the next snippet of code shows how to manually update the head position (orientation tracking is still engaged in automatic mode but even this can be done manually if you prefer). You see a big if-then-else statement that checks for which light is highest and then which light is most left and then assigns the light’s accordingly. This should be all it takes to make the light identities 100% robust.
PHP Code:
leftHand = viz.add('thehand.wrl') # model of a hand
rightHand = viz.add('thehand.wrl') # model of a hand
view = viz.get(viz.MAIN_VIEWPOINT)
ori = viz.add('intersense.dls')
# Turn on automatic head tracking but now only for orientation
# tracking since the position sensor is added after the
# viz.tracker() call
viz.tracker()
# Get handles to all lights
light1 = viz.add('vizppt.dls') # Head
light2 = viz.add('vizppt.dls') # Left hand
light3 = viz.add('vizppt.dls') # Right hand
# Don't turn on automatic head tracking for position
data = []
def ontimer(num):
data1 = light1.get()
data2 = light2.get()
data3 = light3.get()
# Head is light with highest Y value. Go through the three
# light values and compare 1 & 2, and then the hightest of that
# pair with 3. In each case, take the two that aren't the head
# and check to see which is furthest left in the coordinate
# system (i.e., furthest in -X direction) and call this leftHand.
# The remaining light must be the right hand.
if data1[1] > data2[1]:
if data1[1] > data3[1]:
headPos = data1
if data2[0] < data3[0]:
leftPos = data2
rightPos = data3
else:
leftPos = data3
rightPos = data2
else:
headPos = data3
if data1[0] < data2[0]:
leftPos = data1
rightPos = data2
else:
leftPos = data2
rightPos = data1
else:
if data2[1] > data3[1]:
headPos = data2
if data1[0] < data3[0]:
leftPos = data1
rightPos = data3
else:
leftPos = data3
rightPos = data1
else:
headPos = data3
if data1[0] < data2[0]:
leftPos = data1
rightPos = data2
else:
leftPos = data2
rightPos = data1
# Manually update the position of the main viewpoint (orientation
# is being handled automatically.
view.translate(headPos[0], headPos[1], headPos[2])
# Update position of left and right hand
leftHand.translate(leftPos[0], leftPos[1], leftPos[2])
rightHand.translate(rightPos[0], rightPos[1], rightPos[2])
viz.callback(viz.TIMER_EVENT,ontimer)
viz.starttimer(1, .01, viz.FOREVER)
Let me know if this solution makes sense and if you find it acceptable.