Skip to content

Instructions: P5 Glove

Ravbug edited this page Jan 14, 2019 · 2 revisions

Essential Reality P5 Glove

You can read the P5 Virtual Reality Glove values using either the “P5” object, or the “Glove” object. Using Glove is better if you want to put a number after it (“P52” would look silly).

The Virtual Reality glove has lots of different fields you can set, in four main categories: Buttons, Finger bends, Location, and Rotation.

About

The Essential Reality P5 Glove is a cheap full-featured Virtual Reality glove. It has 5 bend sensors, one per finger, 4 buttons A, B, C, and D (D doubles as the power button), and a tracking device that tracks the 8 IR LEDs on the glove to calculate the glove's position and orientation. It also acts as a 3-button USB mouse when mouse-mode is turned on.

You can use it for input in GlovePIE, and you can also change some of its settings.

Control Panel Settings

You can turn mouse mode off for all P5 Gloves from the GlovePIE menu with CP-Settings > Turn P5 Mouse Mode Off. You don't have to do this, you can still use all VR features of the glove while it is in mouse mode, but it can be annoying having the glove control the mouse. Also the GUI will automatically detect finger bends and glove movement as a mouse input rather than a P5 input if mouse mode is switched on.

You can also adjust the other P5 settings from the GlovePIE menu with CP-Settings > P5. That will only work with a single glove at a time though. To calibrate or set up multiple gloves I recommend downloading the Dual Mode Driver and using VBControlPanel instead. If you are wearing the glove on your left hand, or you have the receptor at a funny angle or location, you will also need to create a p5dll.ini file in your GlovePIE directory. You will need to download the Dual Mode Driver to see how to do this.

GUI

You can use the GUI with the P5 Glove. For example... to make a script that presses Enter when you bend your index finger:

First turn mouse mode off from the CP-Settings menu.

Turn the glove on (with the D button) so the red light is on.

Click on the GUI tab.

Press the "Detect Output to Emulate" button.

Press Enter.

Press the "Detect Input" button that appeared.

Bend your index finger.

Make sure it says "Glove" and "Index" in the boxes. If not, repeat the "Detect Input" button and finger bend. When it is right, click the highlighted "Apply" button.

It is now done. You can run or save your script, or add additional inputs by clicking "Detect Output to Emulate" again.

You can also add things manually. Click "Choose Manually" if you can't see the manual entry boxes. Choose the Output Device in the "Ouput Device" box. If it is MIDI then you need to choose a channel, and a category. You then choose which item of the device you want to emulate. On the input side, choose "Glove" from the Input Device box. Choose a glove number (or leave it blank). And choose a part of the device from the "part of device" box. You can also type a 5-letter code in the box where each letter represents a finger, starting from the thumb. "l" for straight, "n" for bent, "r" for half-bent, "x" for don't care.

There are other more obscure values you can use by clicking on the "More..." button. All the extra items will be added to the drop-down box alphabetically (like "AbsoluteIndex"). The "More..." button will also make maths and function buttons appear.

For example, if you want to hold down the Left arrow key when the glove is more than 3 inches to the left, do this:

Choose the keyboard's left key from the boxes on the left hand side (it is near the bottom), or use the "Detect Output" button. Choose "Glove" and "x" on the right hand side, or use the "Detect output" button and move the glove sideways. Click the more button to make the other boxes appear. In the "Maths" button click the "<" less than operator. In the right hand side box type "3 inches" without quotes. In the "Units" box you need to change it to "Units" (at the top). Unfortunately the units box applies to the final result, not just the right hand side, so for comparisons you need to enter the units in the right hand side box and set the units box to "Units" for no units. Then click Apply.

You can also smooth values by choosing "Smooth" in the functions box.

NOTE: The P5 is listed as "Glove" in the GUI. "Glove" only refers to the P5 Glove, not other glove types.

Buttons

The P5 Glove has 4 buttons on the back, labelled A, B, C, and D. The D button doubles as the Power button, and it only registers when you are turning the glove on. All the buttons (including the D button) can tell how long their are held down for. The buttons only work when the glove is visible to the receptor.

If you want to use the D button, you need to tell the user to double click it, (to your script it will look like a single click).

You can read them like this:

debug = P5.A

The button values will be True when the button is held down and False when it is up or not in range.

So to control a key with the buttons on the glove, write a script like this:

Escape = P5.A

You can also use combinations like this:

Escape = Shift+P5.A+P5.B

Fingers

The five fingers are called Thumb, Index, Middle, Ring and Pinky. They return a value between 0 and 63 (unless you assign them to something true or false, like a key, then they return true if >= 32).

0 means as straight as the maximum straightness for that finger during calibration. 63 means as bent as the maximum bent-ness during calibration.

You use them like this:

Enter = p5.Index > 32

Raw Finger Bends

If you want to know the raw bend sensor values, then you can get an approximate version by reading the values AbsoluteThumb, AbsoluteIndex, AbsoluteMiddle, AbsoluteRing, and AbsolutePinky. They are converted from the 0 to 63 values, so it won’t give you more precision, or tell you if it is outside the calibration range. But it will let you know what raw bend sensor value it corresponds to. The raw bend sensor values are backwards (small means bent) and may be roughly between 400 and 1000. These values are less useful than the ones above.

Joint Angles

If you want to know what angles the bend values represent for the different finger joints, then you can use the ThumbProximal, ThumbMedial, ThumbDistal, IndexProximal, IndexMedial, IndexDistal, etc. values.

Proximal is the closest joint on your finger where it joins the hand, Medial is the middle one, and Distal is the finger tip joint. Note that the thumb’s proximal joint is actually INSIDE your hand.

These angles are only guesses, since the P5 only returns one value per finger between 0 and 63. They only work if you calibrate the glove to the range: fingers completely flat to fingers bent as much as possible.

Index Fingertip Position

You can find the position of the index finger tip by using the P5.IndexPos vector. It is measured in P5 Units (51.2ths of an inch, or half a mm) but you can convert it to whatever units you want. It is unfiltered, so you should use the Smooth function, preferably with a both an average and a deadband parameter. It is calculated based on the position of LED 4, and the joint angles above. It is not very reliable, it is more experimental.

Finger Gestures

You can recognize various hand-shapes in GlovePIE by using the 5 letter codes for fingers. Each letter corresponds to one finger, and can be either “l” (L) for straight, “r” for partly bent, “n” for completely bent, or “x” for “don’t care”. Note that the shape of the letter corresponds to the shape of the finger.

So for example, to find out if the user is pointing, use this:

debug = p5.xlnnn

The first letter x means don’t care about the thumb. The second letter (l) means the index finger must be straight. The third letter (n) means the middle finger must be completely bent, and the same for the last two fingers.

Note that the thumb comes first in these codes, even if it is your left hand.

You can use any five-letter combination of those letters.

It will be either true or false.

You can set the values of p5.maxl and p5.minn to values between 0 and 63 if you don’t like the default bend amounts that correspond to those three ranges.

Finger Velocity and Acceleration

I stupidly decided to use the absolute values for velocity and acceleration. So they will be in the opposite direction to what you expect, and have a different magnitude. Sorry.

They are FingerVelocity0, FingerVelocity1, FingerVelocity2, FingerVelocity3, and FingerVelocity4 for velocity, and FingerAcceleration0, etc. for acceleration.

These values probably need smoothing, or they aren’t very useful.

Values that have nothing to do with Finger Bends

Beware of values like ThumbUp or FingersForwards. They have absolutely nothing to do with the thumb or finger bends, and are actually about the glove’s ROTATION. They say what direction those parts WOULD be pointing IF they were not bent at all.

Location

The glove’s filtered location is given by P5.x, P5.y, and P5.z. Or you can read them as a vector with P5.Pos.

The units are in P5 Units by default. P5 Units are equal to a 51.2th of an inch, or roughly half a mm. But because GlovePIE supports units, you can read these values in any units that you want, like this:

debug = p5.x in cm

Also GlovePIE allows you to compare values that are in different units like this:

Enter = p5.x > 1.5 inches

GlovePIE uses Left-Handed coordinates, like Direct3D does (which was a bad decision in hindsight). So x is the sideways position, with negative to the left and positive to the right. y is the vertical position with negative down and positive up. And z is the forwards/backwards position with negative away from the screen and positive towards the screen. Note that the z value will always be negative, since you can’t physically move the hand past the receptor. That makes z values confusing, and I’m sorry. Just get used to negative numbers.

Filtering

You can set the amount of filtering with P5.FilterFrames and P5.FilterDistance. P5.FilterFrames is the number of past frames to average together with the current frame to calculate a smoother position. P5.FilterDistance is the minimum distance the glove has to move in order to register any movement at all. It is good for keeping the position completely still even if you move the glove a tiny bit. It is in P5 Units by default, but you can use any units you want.

eg.

P5.FilterFrames = 10
P5.FilterDistance = 5 mm
debug = P5.x

Unfiltered Position

You can also read the unfiltered position of the glove using P5.AbsoluteX, P5.AbsoluteY and P5.AbsoluteZ. You can also read it as a vector with P5.AbsPos.

Relative Mode

Back in the dark ages of the P5 Glove, it was only able to support Relative Mode. Relative Mode means it works like a 3D mouse. You can read its movements, but you can’t tell where it is currently located in physical space. The advantage of relative mode is that it is smoother, and that it doesn’t matter if the rotation isn’t calculated correctly. The disadvantage is that you don’t know where the glove is.

You can read the Relative Mode position with P5.RelativeX, P5.RelativeY, and P5.RelativeZ, (or P5.RelativePos for a vector). The units are still in P5 Units.

I recommend using RelativeMode (with the smooth function) for things like aiming where you don’t care about the glove’s position, and the normal x, y, and z values when you care about the position.

LED Positions

The glove has 8 yellow infra-red LEDs mounted on it at fixed locations. The receptor needs to see one of them to calculate a rough position, and three of them to calculate a rotation. It can see a maximum of four of them at a time.

You can read the positions of each LED individually with P5.Led0x, P5.Led0y, P5.Led0z, P5.Led1x, P5.Led1y, P5.Led1z, …, P5.Led7x, P5.Led7y, P5.Led7z. The default units are P5 Units. You can also use P5.Led0Pos, etc. if you prefer a vector.

If the LED is visible it will return the actual position of the LED, otherwise it will guess the position based on the positions of the other LEDs it can see.

LED 0 is the top one above the right hand side of your wrist.
LED 1 is the one to the right of your little (pinky) finger.
LED 2 is the one on the left of your little (pinky) finger.
LED 3 is the one on the back of your hand.
LED 4 is the one near your index finger.
LED 5 is the top one above your thumb.
LED 6 is the lower one on the right hand side of your wrist.
LED 7 is the lower one near your thumb.

You can tell whether an LED is visible or not, using p5.Led0vis, etc.

You can also find out the raw (well almost raw) tan values that the glove returns for that LED. There are 3 values.

“h” is the horizontal position measured by the sensor at the top of the receptor tower. Negative means left, positive means right. 512 means roughly 45 degrees to the left, -512 means roughly 45 degrees to the right. It can exceed that range.

“v1” is the vertical position measured by the sensor at the top of the receptor tower. Negative means down, positive means up. This sensor is angled downwards about 10 degrees. The range is the same.

“v2” is the vertical position measured by the sensor at the bottom of the receptor tower. This sensor is angled up about 17 degrees.

These values are p5.Led0h, p5.Led0v1, p5.Led0v2, p5.Led1h, etc.

These raw tan values are the ONLY values the glove hardware gives the computer about the position of the glove. Everything else is to be calculated from these values. Use them for testing how to improve the driver, or if you think you can do better than my driver.

If you want to know the position of the LEDs relative to the glove (their unchanging physical position) use p5.ActualLed0Pos, p5.ActualLed1Pos, etc. They are vectors. Their values never change, unless you buy a new version of the glove.

P5.LedsVisible tells you how many LEDs are currently visible.

Speed and Acceleration

You can tell how fast the glove is moving with P5.Speed. It is just a number measured in P5Units Per Second.

If you want to know the velocity (speed with direction) of the glove, on the x, y and z axes, then you can use P5.XVelocity, P5.YVelocity and P5.ZVelocity. They are also in P5Units per second.

XVelocity is how fast it is moving to the right. Or negative if it is moving to the left.
YVelocity is how fast it is moving up. Or negative if it is moving down.
ZVelocity is how fast it is moving towards the screen. Or negative if it is moving backwards.

If you want a vector, use P5.Velocity.

To find out how fast the velocity is increasing (the acceleration) you can read P5.XAcceleration, P5.YAcceleration, and P5.ZAcceleration. Or the vector P5.Acceleration. They are measured in metres per second per second.

Velocity is good for detecting punches and gestures like that.

When the glove is in range

You can tell whether or not the glove is visible to the receptor by reading P5.InRange, or by the number P5.LedsVisible.

If you want to know WHY the glove isn’t visible you can use one of these other values:

P5.BehindSomething
P5.SwitchedOff
P5.TooFarLeft
P5.TooFarRight
P5.TooFarUp
P5.TooFarDown
P5.TooFarForward
P5.TooFarBack
P5.UntrackableAngle

They are all only GlovePIE’s best guess. They are not guaranteed. The UntrackableAngle one doesn’t work very well.

They are true if the glove isn’t visible for that reason, and false if the glove is visible or if it is not visible for some other reason.

Rotation

Note that rotation requires at least 3 LEDs to be visible and accurate before it can be calculated. Otherwise the rotation will stay much the same as it was before.

Directions of Parts of the Hand

The recommended way to get the glove’s orientation in GlovePIE is to use the values that tell you which way the parts of the glove are facing. For example:

debug = P5.FingersForward

Or if you want to be more precise:

debug = P5.FingersForward and P5.PalmDown

You need to specify two values to uniquely identify an orientation.

IMPORTANT: These do NOT refer to the finger bends. The fingers are assumed to be straight and the thumb is assumed to be sticking out the side of your hand at right angles, for the purposes of these rotation values. The finger bends make no difference to these values.

You can check the direction of the following parts:

BackOfHand, Fingers, Palm, Thumb, or Wrist

And you can check for one of the following directions:

Forwards, Backwards, Left, Right, Up, Down

The part will always be pointing in one, and only one, of those 6 directions. It can be pointing in that direction +/- 45 degrees in order to count as that direction.

Note that a Left handed glove the thumb is on the other side. So for example:

debug = P5.FingersForward and P5.ThumbRight

Will be palm-up if your glove is right-handed, and palm-down if your glove is left-handed. If you want to make your right-handed glove left-handed, please download the Dual Mode Driver and read the instructions about how to create a .ini file.

Diagonal Directions

You can also check for the diagonal directions:

DownBackLeft, DownBack, DownBackRight, DownLeft, DownRight DownForwardsLeft, DownForwards, DownForwardsRight BackLeft, BackRight ForwardsLeft, ForwardsRight UpBackLeft, UpBack, UpBackRight UpLeft, UpRight UpForwardsLeft, UpForwards, UpForwardsRight.

But these directions overlap with each other, and the non-diagonal directions above. For example the Fingers might register as both DownBackLeft and DownBack at the same time.

It needs to be within +/- 45 degrees of that angle for it to be true.

Vague Directions

If you don’t want to be that precise, for example, you only want to know whether the palm is facing up or down, you can use the vague directions.

For example:

debug = P5.PalmUpVague

Will be true whenever the Palm is closer to being up than it is to being down. Either PalmUpVague or PalmDownVague will always be true. Even if the palm is facing left or forwards.

In other words, the angle only has to be +/- 90 degrees.

Vague also works for diagonals

Strict Directions

If you want to be even more precise than normal, you can use the strict directions. For example if you want to know if the palm is facing directly up, but not facing diagonally up and to the left, then you can use the Strict version.

eg.

Debug = P5.PalmUpStrict.

This also works with diagonals (which is the whole point).

The angle must be within 22.5 degrees.

Angle from Directions

You can also tell how far the part of your hand is from pointing in that direction. For example, how close are your fingers to pointing forwards?

You can do comparisons like this: Enter = P5.FingersAngleFromForward <= 30 degrees

That will hold down the Enter key whenever the fingers are within 30 degrees of pointing forwards.

Direction Vectors and Matrix

The other way of finding which direction the parts of the hand are pointing is to use the following direction vectors:

P5.FingersDir
P5.ThumbDir
P5.PalmDir
P5.WristDir
P5.BackOfHandDir

These are vectors, which means they have an x, y, and z component like this:

[1, 0, 0]

The total length will equal 1.

The first component is the x component. It says how much of it is pointing in a right/left direction. In this example it is 1 which means it is pointing all the way to the right. The second component is the y component, which says how much of it is pointing in an up/down direction. In this case none, because it is pointing exactly to the right. The third component is the z component, how much is pointing forwards/backwards, in this case none.

There is also a rotation matrix, which is just three rows of direction vectors like the ones above.

The third row of the rotation matrix is the fingers direction. The second row is the back of hand direction. And the first row of the rotation matrix is the right hand side of your hand direction (which isn’t mentioned above).

You can read the components of the rotation matrix individually, by specifying the row first and then the column:

debug = p5.mat31

In the above example it will use the fingers direction (row three), and get the x component of it. In other words, how much are the fingers pointing to the right?

debug = p5.mat22

The above example would get the back-of-hand direction (row two) and get the y component of it. In other words, how much is the back of the hand pointing up?

You can also get the entire matrix as a 3x3 matrix, by using P5.RotMat.

You can also access the unfiltered rotation matrix with P5.UnfilteredRotMat for the whole matrix, or P5.UnfilteredRotMat11 to P5.UnfilteredRotMat33.

Using Trigonometry to Convert Them to Angles (Isn’t as hard as you might think)

If you understand a very tiny bit of trigonometry then you can convert those numbers into an angle. For example, if we want to know how much the fingers are pointing up, that would be p5.mat32. But that is a fraction, between 0 and 1, or 0 and -1. To convert a fraction to an angle, you use the inverse of the sin, cos, and tan functions. The inverse is called ArcSin, ArcCos, and ArcTan in GlovePIE (But in C they are shortened to asin, acos and atan).

ArcSin converts 0 to 0 degrees, and converts 1 to 90 degrees. ArcCos does the opposite, and converts 0 to 90 degrees and converts 1 to 0 degrees. ArcTan converts 0 to 0 degrees and converts 1 to 45 degrees.

Note that you have to use these functions, rather than just multiplying by 90, because it is not linear. Sin(45 degrees) is actually about 0.7 not 0.5.

Let’s say we want an angle which says how much the fingers are angled upwards. We want 1 (completely up) to be 90 degrees, so we choose ArcSin.

debug = ArcSin(p5.mat32) // a half-circle kind of pitch

You could also write it like this:

debug = ArcSin(p5.FingersDir[2]) // the same half-circle kind of pitch

That will tell you how much the fingers are angled upwards. If they are angled downwards the value will be -90 degrees. In other words, this is a version of the “pitch” angle.

There is also an ArcTan2 function, which works like ArcTan but it can give you the angles of a full circle if you give it the fractions for the two directions. It can tell the difference between 45 degrees and 225 degrees.

ArcTan2 works like this: the first parameter is the fraction which corresponds to 90 degrees and the second parameter is the fraction that corresponds to 0 degrees. For example, lets say we want to find the horizontal angle of the fingers, with 0 degrees meaning forwards, 90 degrees meaning right, 180 degrees meaning backwards and -90 degrees meaning left. So we will use the forwards component (z or column 3) of the fingers for the second parameter (which represents 0 degrees) and we will use the right component (x or column 1) of the fingers for the first parameter (which represents 90 degrees). So it looks like this:

debug = ArcTan2(p5.mat31, p5.mat33) // a full circle, from forwards, kind of yaw

This gives us a version of the “yaw” angle. Note that it is different from what we did above, because we want a complete circle for the yaw, from -180 to 180. But for the pitch we only wanted -90 to +90. Of course, we just decided that arbitrarily. We could have got different versions of the angles. For example, with these two angles, if you pitch your hand back 110 degrees then it will be considered to be a yaw of 180 degrees and a pitch of 80 degrees, because we made pitch only go up to 90, and yaw go all the way around. We could just as easily choose the opposite way around:

Lets say we want the pitch to have forwards as 0, up as 90, and backwards as 180. That means we need to use ArcTan2 (for the whole circle) and we want the first parameter (90 degrees) to be the y part of the fingers row, and we want the second parameter (0 degrees) to be the z part of the fingers row.

debug = ArcTan2(p5.mat32, p5.mat33) // a full-circle, from forwards, kind of pitch

That kind of pitch actually makes less sense to most people, since if you tilt your hand up a bit (say 10 degrees), then rotate it to the right 80 degree, the pitch will stay the same as you expect, but if you then rotate it 20 degrees more to the right, the pitch will change to 170 degrees. Of course that was the same problem we would have with the yaw if we rotated up more than 90 degrees, the yaw would have jumped.

There is no perfect set of angles that makes the most sense. It depends which angles suit you and your application most. Just think what information you really want.

Euler Angles

Euler angles suck. They exist solely to make a set of three steps to get to a particular orientation. Individually they mean nothing though.

If you rotate an object several times, the order is important. A different order gives you a different orientation. Not all programs use the same order, or directions.

The Euler angles GlovePIE provides are in the order pitch, yaw, roll. First it rotates the hand upwards by the first angle. Then it takes the result of that and twists that thing sideways to the right by the second angle. Then whatever is left you tip over to the right by the third angle, so that whatever was at the top after the first two steps becomes at the right after the third step.

So the Pitch, Yaw and Roll angles provide one way to get to the current orientation of the glove in three steps.

Anyway, these angles can be read form P5.Pitch, P5.Yaw, and P5.Roll, but their usage is not recommended.

Angular (rotation) velocity (speed)

If you want to measure how fast the hand is rotating, you can use PitchVelocity, YawVelocity and RollVelocity. Unlike Pitch, Yaw and Roll, they are not steps, and they do make sense individually. Their usage is recommended.

They are measured in degrees per second.

PitchVelocity is how fast the front is becoming the top. YawVelocity is how fast the front is becoming the right. RollVelocity is how fast the top is becoming the right.

You can also get the acceleration in degrees-per-second per second. They are PitchAcceleration, YawAcceleration and RollAcceleration.

All these values may require smoothing to make them worth using.

Clone this wiki locally