How to control hand 3D model in blender by accelerometer data in real time?
I can tell you what you can do with the 3D model.
How do you get this data into the BGE?
3d model controlling is used for analysis of motion of hand.
This does not answer my question. I mean you have this accelerometer. How do you transfer the data from that device to an application on your PC?
I am using arduino nano for sending data from accelerometer to pc. For Coding Arduino IDE is used.
In this case I assume you have an arduino Python binding.
What kind of data do you get from the arduino Python API?
I receive acceleration value in x, y & z axis. These values are in float type.
So you have three input channels (I). You should map them to according “Scene channels” (S) that modify the scene. I think you might need a conversion from source number space to target number space.
Example:
-32768 <= Ix <= +32768 -> converted to -1.0 <= Sx <= +1.0
or
-32768 <= Ix <= +32768 -> converted to 0.0 <= Sx <= +1.0
This depends on what number space you need. Lets assume you want to play a pose according to the X-axis. The frames are between 0 and 160. So you can convert:
inputValue = ... # in range from inputMin to inputMax
inputMin = -32767
inputMax = 32768
inputRange = inputMax - inputMin
normalizedValue = inputValue / inputRange
frameMin = 0
frameMax = 160
frameRange = frameMax - frameMin
frameValue = (normalizedValue * frameRange) + frameMin # frameValue in range from frameMin to frameMax)
With that value you can play the according pose of an action (e.g. via action actuator in property mode, or directly via Python).
And yes you can use the value on any other operation (such as motion, turning, scaling).
My acceleration is in range of +/-3g. So I just need a code which translate or rotate hand with change in acceleration value in x, y & z axis.
If you input the accelerations as forces on the object you automatically get the conversion to translation, Force = mass x acceleration (you might want to multiply with object mass to scale it properly). However depending on accuracy of accelerometer data I would at least also expect that a slow drift of the hand might happen, which you need to find something for. Also anything on a very fast time-scale will be less accurate, default logic tick rate is 60 Hz.
You need pySerial for the communication to the Arduino.
Then convert your input string into three float values for X,Y,Z.
Then you can use on of this three solutions.
from bge import logic
from math import sqrt, atan, atan2, sin, cos, degrees
own = logic.getCurrentController().owner
X = 0.0
Y = 0.5
Z = 0.5
#------------------------------------------------------
# easiest way in Blender
own.alignAxisToVect([X, Y, Z], 0, 1.0)
#------------------------------------------------------
# normal mathematical approach
roll = atan2(Y, Z)
pitch = atan2(-X, sqrt(Y*Y + Z*Z))
#or:
#roll = atan(Y / sqrt(X*X + Z*Z))
#pitch = atan(X / sqrt(Y*Y + Z*Z))
#own.localOrientation = roll, pitch, 0.0
#------------------------------------------------------
# if you need the angles in degrees
degRoll = degrees(roll)
degPitch = degrees(pitch)
#------------------------------------------------------
# Building rotation matrix for old Blender versions (2.49b)
def orientationMat(alpha, beta, gamma):
a = cos(alpha)
b = sin(alpha)
c = cos(beta)
d = sin(beta)
e = cos(gamma)
f = sin(gamma)
ad = a*d
bd = b*d
matrix = [[c*e, -a*f+b*d*e, b*f+a*d*e], [c*f, a*e+b*d*f, -b*e+a*d*f], [-d, b*c, a*c]]
return matrix
#own.localOrientation = orientationMat(roll, pitch, 0)