Calculating Angles Between Two 3-Space Sensor Devices On A Human Body
Calculating Angles Between Two 3-Space Sensor Devices On A Human Body
1atents 1ending
<'34
1atents 1ending
3'34
1atents 1ending
3'34
2. Saddle Joint
" saddle !oint allows for the same movements as the ellipsoid !oint. " saddle !oint e ample in the human body is the carpometacarpal !oint of the thumbs.
>ow using some algebra we can combine E)$ation 3 and E)$ation 4 into an e*uation defining ?.
v :v <cos = x : x < y : y < z : z < x x y: y< z: z< = arccos : < v :v <
E)n. E)n. *
/e can simplify E)$ation * -nowing that the lengths of the vectors are <. = arccos x : x < y : y < z : z < E)n. +
So ? represents the angle between these two vectors. This algorithm can be applied to the forward and down vectors received from the 3-Space Sensor devices to calculate the angle between them.
/here n is a unit vector perpendicular to v0 and v1, and where ? is the angle between them. To calculate ?, remember that the vectors are unit vectors so the lengths of the vectors are <. Ta-e note however, that the cross vector may not have a length of < due to ?. v 0 v 1 =v 0v 1sin n =v 0v 1sin n 93::;-3:<3 Yost Engineering Inc. 1atents 1ending E)n. 1. E)n. 11 4'34
sin =v 0 v 1 = arcsin v 0v 1
E)n. 12 E)n. 13
So ? represents the angle between these two vectors. This algorithm can be applied to the forward and down vectors received from the 3-Space Sensor devices to calculate the angle between them.
5uaternion 1ultiplication
) 0 = ( v 0 , w: ) ) 1 = ( v 1 , w< ) ) 0 )1 = ( w : v1 +w < v 0 +v 0 v1 , w :+w <v 0v 1) E)n. 1E)n. 2. E)n. 21
E)n. 22 E)n. 23
must calculate the 5ravity vector0s offset from the @artesian coordinate a is we denote as the true gravity vector and correct for it.
= arccos g dg a = g dg ) o = a sin / 3 , cos / 3
/here gd is the 5ravity vector from the device and g is the gravity vector we want, a is a unit vector that denotes the a is of rotation from gd to g, and )o is the rotational offset as a *uaternion. +nowing this, all we need to do is offset gd so it is lined up with the g. This is done by multiplying the filtered orientation of the device by )o and set the result as the tare orientation of the device. >ote that we must retain this offset so that we can post-multiply the orientation of the device by it later.
-orwar% 7ector
To calculate the forward vector of a device, we are going to use the filtered tared orientation of the device and a vector in the device0s reference frame that will be denoted as the forward vector. $emember the rotational offset of the device must be applied to the filtered tared orientation before calculating the forward vector of the device. v 4 = )t )o v E)n. 2+
/here )t is the filtered tared orientation of the device, v4 is the device0s forward vector in global-space, and v is the unrotated forward vector in the sensor0s space.
!own 7ector
To calculate the down vector of a device, we are going to use the filtered tared orientation of the device and a vector in the device0s reference frame that will be denoted as the down vector. $emember the rotational offset of the device must be applied to the filtered tared orientation before calculating the down vector of the device.
v 3 = )t )o v
E)n. 2,
/here )t is the filtered tared orientation of the device, v3 is the device0s down vector in global-space, and v is the unrotated down vector in the sensor0s space.
8p 7ector
To calculate the up vector of a device, a simple negation of the calculated down-vector is all that is necessary.
1atents 1ending
B'34
v U = v 3
E)n. 2-
9ig,t 7ector
To calculate the right vector of a device, we are going to use the forward and down vectors of the device and perform the cross product on them.
v 5 = v 4 v 3
E)n. 3.
/here v5 is the right vector of the device. "lso, note that the forward and down vectors already have the compensation applied to them so v5 will also already compensated and that the 3-Space Sensor uses a lefthanded space by default.
Ta-e note that arccos will always return a positive value, so we must use the dot product of a and vU. to calculate the sign of ?. The function copysign, is a function that returns the first parameter with the same sign as the second parameter, so using the dot product is perfect because it ranges from -< to <.
= copysign , v 4.a
E)n. 3*
Ta-e note that arccos will always return a positive value, so we must use the dot product of a and v4. to calculate the sign of ?. The function copysign, is a function that returns the first parameter with the same sign as the second parameter. )sing the dot product is perfect because it ranges from -< to <.
The *uaternion )5o, is the rotational offset for the right vectors. >ow we can start decomposing the angles. The first step in decomposing the angles is to undo any rotations on the vertical a is %this will be the yaw angle&. So we will be using the forward vector of each device to calculate the yaw angle. #owever, we must first apply the offset )5o to v41. v &41 = ) 5o v 41 The vector v&41, is the transformed vector of v41. >ow calculate the angle between v&41 and v4..
yaw = arccos v &41v 4.
E)n. 4.
E)n. 41
The angle ?yaw, is the yaw angle of the !oint. >ow we must undo this rotation by calculating a *uaternion and transforming v41 again, but this time to be on the same frontal plane as v4.. /e must also transform v31 to be used for a later calculation. a = v &41v 4. ) = a sin yaw / 3 , cos yaw / 3 v &41 = ) v 41 v &31 = ) v 31 E)n. 42 E)n. 43 E)n. 44 E)n. 4
The *uaternion );, is the rotational offset of ?yaw. >ow ta-e note that arccos will always return a positive value, so we must use the dot product of a and v5. to calculate the sign of ?yaw.
1atents 1ending
E'34
E)n. 4*
The function copysign, is a function that returns the first parameter with the same sign as the second parameter, so using the dot product is perfect because it ranges from -< to <. >e t we must undo any rotations on the frontal hori.ontal a is %this will be the pitch angle&. So we will be using v&41 and v4. to calculate the pitch angle.
pitch = arccos v &41v 4.
E)n. 4+
The angle Fpitch, is the pitch angle of the !oint. >ow we must undo this rotation by calculating a *uaternion and transforming v&31 again, but this time so it will be on the same sagittal plane as v3.. a = v &41v 4. ) = a sin pitch / 3 , cos pitch / 3 v &31 = ) v &31 The *uaternion )<, is the rotational offset of Fpitch. >ow we must use the dot product of a and v3. to calculate the sign of Fpitch.
pitch = copysign picth , av 3.
E)n. 1
2inally calculate any rotations on the sagittal hori.ontal a is %this will be the roll angle&. /e will be using v&31 and v3. to calculate the roll angle. roll = arccos v &31v 3. E)n. 2
The angle Groll, is the roll angle of the !oint. >ow we must calculate the sign of Groll using the cross product of v&31 and v3., a, and the dot product of a and v4.. a = v &31v 3. E)n. 3 roll = copysign roll , av 4. E)n. 4 The planes and a es mentioned are described in C3D. "nd as mentioned in C<D, there are two positions in which the so called Hgimbal-loc-I will occur. Those positions are when the arm is straight up or straight down, ma-ing ?yaw and Groll ambiguous.
=. So*tware I$ple$entation
The reference 1ython code in this documentation is written in 1ython 3.;, uses the internal libraries math and struct, and the e ternal library, serial, which is provided by 1ySerial 3.B. " custom library, threespace, has functions for calculating the angles and performing vector ans *uaternion operations. @ommunication with the 3-Space Sensor devices is done with 1ySerial0s Serial class. It ta-es the @,( port name the device was given by the computer when plugged in to connect to it for writing and reading data to and from the device.
1atents 1ending
J'34
1atents 1ending
<:'34
vec:= " unit vector. vec<= " unit vector. vec3= " unit vector perpendicular to vec: and vec<. MMM QQ The ma and min is used to account for possible floating point error dotKproduct L ma %min%vector6ot%vec:, vec<&, <.:&, -<.:& angle L math.acos%dotKproduct& if vec3 is not >one= a is L vector>ormali.e%vector@ross%vec:, vec<&& angle L math.copysign%angle, vector6ot%vec3, a is&& return angle
1atents 1ending
<<'34
QQ Eighth, calculate a vector perpendicular to the transformed forward vector and the forward vector QQ of the first device a is L vector>ormali.e%vector@ross%transformedKforward<, forward:&& QQ >inth, create a *uaternion using the calculated a is and pitch angle that will be used to transform QQ the transformed down vector so that it is on the same vertical plane as the down vector of the first QQ device *uat L createTuaternion%a is, pitch& transformedKdown< L vector>ormali.e%*uaternionUector(ultiplication%*uat, transformedKdown<&& QQ Set the sign of pitch using the a is calculated and the down vector of the first device pitch L math.copysign%pitch, vector6ot%a is, down:&& QQ Tenth, calculate the angle between the transformed down vector and the down vector of the first QQ device QQ This angle is the roll roll L calculate"ngle%transformedKdown<, down:& a is L vector>ormali.e%vector@ross%transformedKdown<, down:&& QQ Set the sign of roll using the a is calculated and the forward vector of the first device roll L math.copysign%roll, vector6ot%a is, forward:&& return Cpitch, yaw, rollD
1atents 1ending
<3'34
1atents 1ending
<3'34
<, y<, .< L vec< return : O < P y: O y< P .: O .< def vector8ength%vec&= MMM @alculates the length of a vector given. "rgs= vec= " vector. MMM return %vector6ot%vec, vec& OO :.A& def vector>ormali.e%vec&= MMM >ormali.es the vector given. "rgs= vec= " vector. MMM length L vector8ength%vec& , y, . L vec return C ' length, y ' length, . ' lengthD def createTuaternion%vec, angle&= MMM @reates a *uaternion from an a is and an angle. "rgs= vec= " unit vector. angle= "n angle in radians. MMM QQ Tuaternions represent half the angle in comple space so the angle must be halved , y, . L vec tmpK*uat L C:.:D O 4 tmpK*uatC:D L O math.sin%angle ' 3.:& tmpK*uatC<D L y O math.sin%angle ' 3.:& tmpK*uatC3D L . O math.sin%angle ' 3.:& tmpK*uatC3D L math.cos%angle ' 3.:& QQ >ormali.e the *uaternion * , *y, *., *w L tmpK*uat length L %* O * P *y O *y P *. O *. P *w O *w& OO :.A tmpK*uatC:D 'L length tmpK*uatC<D 'L length tmpK*uatC3D 'L length tmpK*uatC3D 'L length return tmpK*uat def *uaternion(ultiplication%*uat:, *uat<&= MMM 1erforms *uaternion multiplication on the two given *uaternions. "rgs= *uat:= " unit *uaternion. *uat<= " unit *uaternion. MMM :, y:, .:, w: L *uat: <, y<, .<, w< L *uat< Kcross, yKcross, .Kcross L vector@ross%C :, y:, .:D, C <, y<, .<D& wKnew L w: O w< - vector6ot%C :, y:, .:D, C <, y<, .<D& Knew L < O w: P : O w< P Kcross yKnew L y< O w: P y: O w< P yKcross .Knew L .< O w: P .: O w< P .Kcross return C Knew, yKnew, .Knew, wKnewD def *uaternionUector(ultiplication%*uat, vec&= MMM $otates the given vector by the given *uaternion.
1atents 1ending
<4'34
"rgs= *uat= " unit *uaternion. vec= " unit vector. MMM QQ 1rocedure= *uat O vecK*uat O -*uat * , *y, *., *w L *uat v , vy, v. L vec vw L :.: negK* L -* negK*y L -*y negK*. L -*. negK*w L *w QQ 2irst (ultiply Kcross, yKcross, .Kcross L vector@ross%C* , *y, *.D, vec& wKnew L *w O vw - vector6ot%C* , *y, *.D, vec& Knew L v O *w P * O vw P Kcross yKnew L vy O *w P *y O vw P yKcross .Knew L v. O *w P *. O vw P .Kcross QQ Second (ultiply Kcross, yKcross, .Kcross L vector@ross%C Knew, yKnew, .KnewD, CnegK* , negK*y, negK*.D& w L wKnew O negK*w - vector6ot%C Knew, yKnew, .KnewD, CnegK* , negK*y, negK*.D& L negK* O wKnew P Knew O negK*w P Kcross y L negK*y O wKnew P yKnew O negK*w P yKcross . L negK*. O wKnew P .Knew O negK*w P .Kcross return C , y, .D def calculate"ngle%vec:, vec<, vec3L>one&= MMM @alculates the angle between the two given vectors using the dot product. "rgs= vec:= " unit vector. vec<= " unit vector. vec3= " unit vector perpendicular to vec: and vec<. MMM QQ The ma and min is used to account for possible floating point error dotKproduct L ma %min%vector6ot%vec:, vec<&, <.:&, -<.:& angle L math.acos%dotKproduct& if vec3 is not >one= a is L vector>ormali.e%vector@ross%vec:, vec<&& angle L math.copysign%angle, vector6ot%vec3, a is&& return angle def calculate1itchYaw$oll%forward:, down:, forward<, down<&= MMM @alculates the pitch, yaw, and roll angles using the forward and down vectors calculated from two 3-Space Sensor devices. "rgs= forward:= " unit vector that denotes the forward vector of the first 3-Space Sensor device. down:= " unit vector that denotes the down vector of the first 3-Space Sensor device. forward<= " unit vector that denotes the forward vector of the second 3-Space Sensor device. down<= " unit vector that denotes the down vector of the second 3-Space Sensor device. MMM QQ "ssumes the devices0 a is directions are default %RYS& and are positioned or has had its QQ orientation manipulated so that the $ight a is is up QQ 2irst, calculate the right vector for both devices using the forward and down vectors right: L vector>ormali.e%vector@ross%forward:, down:&& right< L vector>ormali.e%vector@ross%forward<, down<&& QQ Second, calculate the angle between the right vectors and a vector perpendicular to them angle L calculate"ngle%right<, right:& a is L vector>ormali.e%vector@ross%right<, right:&& QQ Third, create a *uaternion using the calculated a is and angle that will be used to transform the QQ forward vector of the second device so that it is on the same hori.ontal plane as the forward QQ vector of the first device
1atents 1ending
<A'34
*uat L createTuaternion%a is, angle& transformedKforward< L vector>ormali.e%*uaternionUector(ultiplication%*uat, forward<&& QQ 2ourth, calculate the angle between the transformed forward vector and the forward vector of the QQ first device QQ This angle is the yaw yaw L calculate"ngle%transformedKforward<, forward:& QQ 2ifth, calculate a vector perpendicular to the transformed forward vector and the forward vector QQ of the first device a is L vector>ormali.e%vector@ross%transformedKforward<, forward:&& QQ Si th, create a *uaternion using the calculated a is and yaw angle that will be used to transform QQ the forward vector of the second device so that it is on the same vertical plane as the forward QQ vector of the first device and to transform the down vector of the second device to be used in a QQ later calculation *uat L createTuaternion%a is, yaw& transformedKforward< L vector>ormali.e%*uaternionUector(ultiplication%*uat, forward<&& transformedKdown< L vector>ormali.e%*uaternionUector(ultiplication%*uat, down<&& QQ Set the sign of yaw using the a is calculated and the right vector of the first device yaw L math.copysign%yaw, vector6ot%a is, right:&& QQ Seventh, calculate the angle between the transformed forward vector and the forward vector of QQ the first device QQ This angle is the pitch pitch L calculate"ngle%transformedKforward<, forward:& QQ Eighth, calculate a vector perpendicular to the transformed forward vector and the forward vector QQ of the first device a is L vector>ormali.e%vector@ross%transformedKforward<, forward:&& QQ >inth, create a *uaternion using the calculated a is and pitch angle that will be used to transform QQ the transformed down vector so that it is on the same vertical plane as the down vector of the first QQ device *uat L createTuaternion%a is, pitch& transformedKdown< L vector>ormali.e%*uaternionUector(ultiplication%*uat, transformedKdown<&& QQ Set the sign of pitch using the a is calculated and the down vector of the first device pitch L math.copysign%pitch, vector6ot%a is, down:&& QQ Tenth, calculate the angle between the transformed down vector and the down vector of the first QQ device QQ This angle is the roll roll L calculate"ngle%transformedKdown<, down:& a is L vector>ormali.e%vector@ross%transformedKdown<, down:&& QQ Set the sign of roll using the a is calculated and the forward vector of the first device roll L math.copysign%roll, vector6ot%a is, forward:&& return Cpitch, yaw, rollD def create@hec-Sum%charKdata&= MMM @alculates the chec-sum for the given data. "rgs= charKdata= " string of data. MMM chec-sum L : for byte in charKdata= chec-sum PL ord%byte& return chr%chec-sum W 3AB& def offsetTuaternion%serialKport, gravityLC-<.:, :.:, :.:D, initKoffsetL>one&= MMM @alculates the offset of the 3-Space Sensor device on the human body. "rgs= serialKport= " Serial ob!ect that is communicating with a 3-Space Sensor device. gravity= " unit vector that denotes the gravity direction the 3-Space Sensor device should be reading. initKoffset= " unit *uaternion the denotes a rotational offset for a 3-Space Sensor device.
1atents 1ending
<B'34
MMM QQ 2irst, find what the device reads as the gravity direction using the read >orth 5ravity command QQ The command returns B floats, the first 3 ma-e the >orth vector and the last 3 ma-e the 5ravity QQ vector northKgravity L command/rite$ead%serialKport, $E"6K>,$T#K5$"UITYK@,((">6, byteKsi.eL34, dataKformatL0Nffffff0& sensorKgravity L northKgravityC3=D QQ Second, read the current filtered orientation as a *uaternion from the device using the read QQ 2iltered Tuaternion command filtKdata L command/rite$ead%serialKport, $E"6K2I8TKT)"TK@,((">6, byteKsi.eL<B, dataKformatL0Nffff0& QQ Third, using the gravity vector given and the 5ravity vector from the device, calculate the angle QQ between them and a vector perpendicular to them angle L calculate"ngle%sensorKgravity, gravity& a is L vector>ormali.e%vector@ross%sensorKgravity, gravity&& QQ 2ourth, create a *uaternion using the calculated a is and angle that will be used to offset the QQ filtered *uaternion of the device so the gravity vectors will line up QQ "lso apply the initial offset if any offset L createTuaternion%a is, -angle& if initKoffset is not >one= offset L *uaternion(ultiplication%offset, initKoffset& tareKdata L *uaternion(ultiplication%filtKdata, offset& QQ 2ifth, set the offset filtered *uaternion as the tare orientation for the device using the set Tare QQ Tuaternion command command/rite$ead%serialKport, SETKT"$EKT)"TK@,((">6, dataKformatL0Nffff0, inputKdataLtareKdata& QQ The calculated offset *uaternion is returned because it needs to be applied to the filtered tared QQ *uaternion received from the device return offset def open1ort%comKport&= try= serialKport L serial.Serial%comKport, timeoutL:.<, writeTimeoutL:.<, baudrateL<<A3::& return serialKport e cept E ception as e = print M2ailed to create a serial port on port=M, comKport raise e def close1ort%serialKport&= try= serialKport.close%& e cept E ception as e = print M2ailed to close the port=M, serialKport.name raise e def command/rite$ead%serialKport, command, byteKsi.eL:, dataKformatL00, inputKdataLCD&= MMM /rites and reads data to and from a serial port given. "rgs= serialKport= " Serial ob!ect that is communicating with a 3-Space Sensor device. command= " char string of one of the 3-Space Sensor device0s commands. byteKsi.e= The number of bytes to read from the serial port. dataKformat= The format for which struct is to pac- or unpac- data. inputKdata= 6ata to be sent to the 3-Space Sensor device. MMM dataKstr L 00 if len%inputKdata& N := dataKstr L struct.pac-%dataKformat, OinputKdata& commandKdata L ST"$TK7YTE P command P dataKstr P create@hec-Sum%command P dataKstr& try= serialKport.write%commandKdata& e cept E ception as e = print MThere was an error writing command to the portM, serialKport.name raise e
1atents 1ending
<;'34
if byteKsi.e N := try= dataKstr L serialKport.read%byteKsi.e& e cept E ception as e = print MThere was an error reading from the portM, serialKport.name raise e outputKdata L list%struct.unpac-%dataKformat, dataKstr&& return outputKdata return >one def calculate6eviceUector%serialKport, vec, offset&= MMM @alculates a vector in a 3-Space Sensor device0s reference frame. "rgs= serialKport= " Serial ob!ect that is communicating with a 3-Space Sensor device. vec= " unit vector. offset= " unit *uaternion that denotes the offset of the 3-Space Sensor device. MMM QQ 5et the filtered tared orientation of the device data L command/rite$ead%serialKport, $E"6K2I8TKT"$E6KT)"TK@,((">6, byteKsi.eL<B, dataKformatL0Nffff0& QQ "pply the offset for the device *uat L *uaternion(ultiplication%data, offset& QQ @alculate a vector for the device with its orientation vector L *uaternionUector(ultiplication%*uat, vec& return vector
=.@ -ull Source Co%e *or Calculating t,e Angle o* a #inge +oint
QV'usr'bin'env python3.; QQ QQ Script >ame= hinge.py QQ QQ "pplication >ote= @alculating "ngles 7etween Two YEI 3-Space Sensor 6evices using Two Uectors QQ on a #uman 7ody QQ QQ 6escription= @alculates the hinge angle between two YEI 3-Space Sensor devices in 1ython 3.; QQ QQ /ebsite= www.3-space-sensor.com QQ QQ @opyright= @opyright %@& 3:<3 Yost Engineering, Inc. QQ 1ermission is hereby granted, free of charge, to any person obtaining a copy of this software QQ and associated documentation files %the MSoftwareM&, to deal in the Software without QQ restriction, including without limitation the rights to use, copy, modify, merge, publish, QQ distribute, sublicense, and'or sell copies of the Software, and to permit persons to whom the QQ Software is furnished to do so, sub!ect to the following conditions= QQ The above copyright notice and this permission notice shall be included in all copies or QQ substantial portions of the Software. QQ T#E S,2T/"$E IS 1$,UI6E6 M"S ISM, /IT#,)T /"$$">TY ,2 ">Y +I>6, QQ ER1$ESS ,$ I(18IE6, I>@8)6I>5 7)T >,T 8I(ITE6 T, T#E /"$$">TIES QQ ,2 (E$@#">T"7I8ITY, 2IT>ESS 2,$ " 1"$TI@)8"$ 1)$1,SE ">6 QQ >,>I>2$I>5E(E>T. I> >, EUE>T S#"88 T#E ")T#,$S ,$ @,1Y$I5#T QQ #,86E$S 7E 8I"78E 2,$ ">Y @8"I(, 6"("5ES ,$ ,T#E$ 8I"7I8ITY, QQ /#ET#E$ I> "> "@TI,> ,2 @,>T$"@T, T,$T ,$ ,T#E$/ISE, "$ISI>5 QQ 2$,(, ,)T ,2 ,$ I> @,>>E@TI,> /IT# T#E S,2T/"$E ,$ T#E )SE ,$ QQ ,T#E$ 6E"8I>5S I> T#E S,2T/"$E. QQ import time import threespace QQ @hange the @,( port names as needed QQ 2irst device serialKport: L threespace.open1ort%M@,(<:M&
1atents 1ending
<E'34
QQ Second device serialKport< L threespace.open1ort%M@,(<<M& print MTo *uit, hold down XM@trlXM -ey and press XM@XM -eyM print M---------------------------------------------------M print M5et into the starting position.M time.sleep%3& print M1lease hold for <: seconds to compensate for device positioning.M time.sleep%A& QQ @alculate the rotational offset of the compensation for the the first device offset: L threespace.offsetTuaternion%serialKport:& QQ @alculate the rotational offset of the compensation for the the second device offset< L threespace.offsetTuaternion%serialKport<& time.sleep%3& while True= QQ @alculate the forward vector of the first device QQ The initial forward vector to use depends on the orientation and a is direction of the device QQ The resultant vector must be heading up the arm forward: L threespace.calculate6eviceUector%serialKport:, C:.:, :.:, <.:D, offset:& QQ @alculate the forward vector of the second device QQ The initial forward vector to use depends on the orientation and a is direction of the device QQ The resultant vector must be heading up the arm forward< L threespace.calculate6eviceUector%serialKport<, C:.:, :.:, <.:D, offset<& QQ @alculate a vector perpendicular to the forward vectors and parallel to the a is of rotation to use QQ for determining the sign of the angle QQ )sing the first device0s orientation will give the best results QQ The initial vector to use depends on the initial forward vector up: L threespace.calculate6eviceUector%serialKport:, C:.:, <.:, :.:D, offset:& QQ @alculate the angle between the two devices angle L threespace.calculate"ngle%forward<, forward:, up:& QQ 1rint as radians and degrees print M#ingeM print M$adians= W:.4fXt6egrees= W:.4fM W %angle, threespace.math.degrees%angle&& print MLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLM QQ @lose the serial ports threespace.close1ort%serialKport:& threespace.close1ort%serialKport<&
=.A -ull Source Co%e *or Calculating t,e Angle o* a 0i"ot +oint
QV'usr'bin'env python3.; QQ QQ Script >ame= pivot.py QQ QQ "pplication >ote= @alculating "ngles 7etween Two YEI 3-Space Sensor 6evices using Two Uectors QQ on a #uman 7ody QQ QQ 6escription= @alculates the pivot angle between two YEI 3-Space Sensor devices in 1ython 3.; QQ QQ /ebsite= www.3-space-sensor.com QQ QQ @opyright= @opyright %@& 3:<3 Yost Engineering, Inc. QQ 1ermission is hereby granted, free of charge, to any person obtaining a copy of this software QQ and associated documentation files %the MSoftwareM&, to deal in the Software without QQ restriction, including without limitation the rights to use, copy, modify, merge, publish, QQ distribute, sublicense, and'or sell copies of the Software, and to permit persons to whom the QQ Software is furnished to do so, sub!ect to the following conditions= QQ The above copyright notice and this permission notice shall be included in all copies or QQ substantial portions of the Software. QQ T#E S,2T/"$E IS 1$,UI6E6 M"S ISM, /IT#,)T /"$$">TY ,2 ">Y +I>6, QQ ER1$ESS ,$ I(18IE6, I>@8)6I>5 7)T >,T 8I(ITE6 T, T#E /"$$">TIES
1atents 1ending
<J'34
QQ QQ QQ QQ QQ QQ QQ
,2 (E$@#">T"7I8ITY, 2IT>ESS 2,$ " 1"$TI@)8"$ 1)$1,SE ">6 >,>I>2$I>5E(E>T. I> >, EUE>T S#"88 T#E ")T#,$S ,$ @,1Y$I5#T #,86E$S 7E 8I"78E 2,$ ">Y @8"I(, 6"("5ES ,$ ,T#E$ 8I"7I8ITY, /#ET#E$ I> "> "@TI,> ,2 @,>T$"@T, T,$T ,$ ,T#E$/ISE, "$ISI>5 2$,(, ,)T ,2 ,$ I> @,>>E@TI,> /IT# T#E S,2T/"$E ,$ T#E )SE ,$ ,T#E$ 6E"8I>5S I> T#E S,2T/"$E.
import time import threespace QQ @hange the @,( port names as needed QQ 2irst device serialKport: L threespace.open1ort%M@,(<:M& QQ Second device serialKport< L threespace.open1ort%M@,(<<M& print MTo *uit, hold down XM@trlXM -ey and press XM@XM -eyM print M---------------------------------------------------M print M5et into the starting position.M time.sleep%3& print M1lease hold for <: seconds to compensate for device positioning.M time.sleep%A& QQ @alculate the rotational offset of the compensation for the the first device offset: L threespace.offsetTuaternion%serialKport:& QQ @alculate the rotational offset of the compensation for the the second device offset< L threespace.offsetTuaternion%serialKport<& time.sleep%3& while True= QQ @alculate the down vector of the first device with its orientation QQ The initial down vector to use depends on the orientation and a is direction of the device QQ The resultant vector must be heading into the arm down: L threespace.calculate6eviceUector%serialKport:, C:.:, -<.:, :.:D, offset:& QQ @alculate the down vector of the second device with its orientation QQ The initial down vector to use depends on the orientation and a is direction of the device QQ The resultant vector must be heading into the arm down< L threespace.calculate6eviceUector%serialKport<, C:.:, -<.:, :.:D, offset<& QQ @alculate a vector perpendicular to the down vectors and parallel to the a is of rotation to use for QQ determining the sign of the angle QQ )sing the first device0s orientation will give the best results QQ The initial vector to use depends on the initial down vector forward: L threespace.calculate6eviceUector%serialKport:, C:.:, :.:, <.:D, offset:& QQ @alculate the angle between the two devices angle L threespace.calculate"ngle%down<, down:, forward:& QQ 1rint as radians and degrees print M1ivotM print M$adians= W:.4fXt6egrees= W:.4fM W %angle, threespace.math.degrees%angle&& print MLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLM QQ @lose the serial ports threespace.close1ort%serialKport:& threespace.close1ort%serialKport<&
=.B -ull Source Co%e *or Calculating t,e 0itc,: Yaw: an% 9oll Angles o* a 1ulti-A(is +oint
V'usr'bin'env python3.; QQ QQ Script >ame= multiKa is.py QQ QQ "pplication >ote= @alculating "ngles 7etween Two YEI 3-Space Sensor 6evices using Two Uectors QQ on a #uman 7ody
1atents 1ending
3:'34
QQ QQ 6escription= @alculates the pitch, yaw, and roll angles between two YEI 3-Space Sensor devices in QQ 1ython 3.; QQ QQ /ebsite= www.3-space-sensor.com QQ QQ @opyright= @opyright %@& 3:<3 Yost Engineering, Inc. QQ 1ermission is hereby granted, free of charge, to any person obtaining a copy of this software QQ and associated documentation files %the MSoftwareM&, to deal in the Software without QQ restriction, including without limitation the rights to use, copy, modify, merge, publish, QQ distribute, sublicense, and'or sell copies of the Software, and to permit persons to whom the QQ Software is furnished to do so, sub!ect to the following conditions= QQ The above copyright notice and this permission notice shall be included in all copies or QQ substantial portions of the Software. QQ T#E S,2T/"$E IS 1$,UI6E6 M"S ISM, /IT#,)T /"$$">TY ,2 ">Y +I>6, QQ ER1$ESS ,$ I(18IE6, I>@8)6I>5 7)T >,T 8I(ITE6 T, T#E /"$$">TIES QQ ,2 (E$@#">T"7I8ITY, 2IT>ESS 2,$ " 1"$TI@)8"$ 1)$1,SE ">6 QQ >,>I>2$I>5E(E>T. I> >, EUE>T S#"88 T#E ")T#,$S ,$ @,1Y$I5#T QQ #,86E$S 7E 8I"78E 2,$ ">Y @8"I(, 6"("5ES ,$ ,T#E$ 8I"7I8ITY, QQ /#ET#E$ I> "> "@TI,> ,2 @,>T$"@T, T,$T ,$ ,T#E$/ISE, "$ISI>5 QQ 2$,(, ,)T ,2 ,$ I> @,>>E@TI,> /IT# T#E S,2T/"$E ,$ T#E )SE ,$ QQ ,T#E$ 6E"8I>5S I> T#E S,2T/"$E. QQ import time import threespace QQ @hange the @,( port names as needed QQ 2irst device serialKport: L threespace.open1ort%M@,(<:M& QQ Second device serialKport< L threespace.open1ort%M@,(<<M& print MTo *uit, hold down XM@trlXM -ey and press XM@XM -eyM print M---------------------------------------------------M print M5et into the starting position.M time.sleep%3& print M1lease hold for <: seconds to compensate for device positioning.M time.sleep%A& QQ @reate a *uaternion to be used to orient the first device to the same orientational space as the second QQ device *uat L threespace.createTuaternion%C:.:, <.:, :.:D, -threespace.math.pi ' 3.:& QQ @alculate the rotational offset of the compensation for the the first device offset: L threespace.offsetTuaternion%serialKport:, C:.:, :.:, -<.:D, *uat& QQ @alculate the rotational offset of the compensation for the the second device offset< L threespace.offsetTuaternion%serialKport<& time.sleep%3& while True= QQ @alculate the forward and down vectors of the first device with its orientation QQ The initial forward vector to use depends on the orientation and a is direction of the device QQ The resultant vector must be heading to the left of the body forward: L threespace.calculate6eviceUector%serialKport:, C:.:, :.:, <.:D, offset:& QQ The initial down vector to use depends on the orientation and a is direction of the device QQ The resultant vector must be heading into the body down: L threespace.calculate6eviceUector%serialKport:, C:.:, -<.:, :.:D, offset:& QQ @alculate the forward and down vectors of the second device with its orientation QQ The initial forward vector to use depends on the orientation and a is direction of the device QQ The resultant vector must be heading up the arm forward< L threespace.calculate6eviceUector%serialKport<, C:.:, :.:, <.:D, offset<& QQ The initial down vector to use depends on the orientation and a is direction of the device QQ The resultant vector must be heading into the arm down< L threespace.calculate6eviceUector%serialKport<, C:.:, -<.:, :.:D, offset<&
1atents 1ending
3<'34
QQ @alculate the 1itch Yaw and $oll between the two devices angleKlist L threespace.calculate1itchYaw$oll%forward:, down:, forward<, down<& QQ 1rint as radians and degrees print M1itchM print M$adians= W:.4fXt6egrees= W:.4fM W %angleKlistC:D, threespace.math.degrees%angleKlistC:D&& print MLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLM print MYawM print M$adians= W:.4fXt6egrees= W:.4fM W %angleKlistC<D, threespace.math.degrees%angleKlistC<D&& print MLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLM print M$ollM print M$adians= W:.4fXt6egrees= W:.4fM W %angleKlistC3D, threespace.math.degrees%angleKlistC3D&& print MLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLM QQ @lose the serial ports threespace.close1ort%serialKport:& threespace.close1ort%serialKport<&
1atents 1ending
33'34
C. 9e*erences
<. 6oorenbosch, #arlaar, and Ueeger. The globe system= "n unambiguous description of shoulder positions in daily life movements http=''www.rehab.research.va.gov'!our':3'4:'3'162'doorenbosch.pdf 3. )nderstanding E ercise Y 1lanes, " es and (ovement http=''www.todaysfitnesstrainer.com'understanding-e ercise-planes-a es-movement' 3. The Zoints http=''www.shoc-family.net's-eleton'Z,I>TS.#T(8 4. 2ive 6ifferent Types of Zoints http=''www.livestrong.com'article'<<AEEJ-five-different-types-!oints' A. ,pen, Sesamoid= Types of Zoints http=''science.howstuffwor-s.com'life'human-biology'bone<<.htm
1atents 1ending
33'34
YEI Technology
B3: Second Street 1ortsmouth, ,hio 4ABB3
www.YeiTechnology.com www.3SpaceSensor.com