Nulamir / IMUMocap

Motion capture suit with IMU sensor 6050 or 9255 and data transfer with esp8866 to Autodesk MotionBuilder
MIT License
9 stars 1 forks source link

coordinate system #1

Open BestPolarBear opened 2 years ago

BestPolarBear commented 2 years ago

Hello, how do you convert the sensor coordinate system to the model node coordinate system?I'm doing something similar to you, but there are some problems with coordinate system conversion.

Nulamir commented 2 years ago

Hi,

IMU sensors generate quaternions and only rotation information, not position information. Autodesk Motion builder wait for euler angle and mdT (position of node)

Wee need to convert this data

Facts:

  1. Sensor initial state is start from lying on the table chip Z axis look in to roof. X and Y lying on the table. But on the motionbuilder model. Skeleton is faced to you. Z axis look on you.

2 Sensor physical implementation (crafted hard device) a unified (they are all likes each on enover), But on you body you need to hang sensor on stomach legs head vertically, and in left side of body sensor hanged one method on right side another

3 there is a little deviation then you hang sensors 10-15 degrees from strightly vertical or horizontal position

All calculation made in ordeviceskeleton_hardware.cxx ORDeviceSkeletonHardware::FetchDataPacket(FBTime& pTime)

To get 1,2 Facts you need to remix and redirect axes of quaternion.

cQuaternion.mValue[1] = mSkDataBuffer.mChannel[i].iR[0][0] tempx + mSkDataBuffer.mChannel[i].iR[0][1] tempy + mSkDataBuffer.mChannel[i].iR[0][2] tempz; // -tempz cQuaternion.mValue[2] = mSkDataBuffer.mChannel[i].iR[1][0] tempx + mSkDataBuffer.mChannel[i].iR[1][1] tempy + mSkDataBuffer.mChannel[i].iR[1][2] tempz;//-tempx; cQuaternion.mValue[3] = mSkDataBuffer.mChannel[i].iR[2][0] tempx + mSkDataBuffer.mChannel[i].iR[2][1] tempy + mSkDataBuffer.mChannel[i].iR[2][2] * tempz;//tempy;

Data for how to remix axes stored in ordeviceskeleton_hardware .h void SetupBuffer()

in example of left foot^

mChannel[3].iR[0][0] = -1; mChannel[3].iR[0][1] = 0; mChannel[3].iR[0][2] = 0; x axis reversed mChannel[3].iR[1][0] = 0; mChannel[3].iR[1][1] = 0; mChannel[3].iR[1][2] = 1; y,z a swapped mChannel[3].iR[2][0] = 0; mChannel[3].iR[2][1] = 1; mChannel[3].iR[2][2] = 0; y,z a swapped

Now you may hang your sensor on you comfort

To get 3 Fact you need to multiply correction quaternion on sensor quaternion

multiplyQuaternion(resultQuaternion, correctionQuaternion, cQuaternion);

Now we get Euler angels

getEulerFromQuaternion(cRotationOfNode, resultQuaternion, zyx);

Code below get transformation data mT (position of node) from rotation of bones. code use sceleton data. length of bones they initial position.

mSkDataBuffer.mChannel[i].mR[0] = cRotationOfNode.mValue[0];// +correctionVector.mValue[0]; mSkDataBuffer.mChannel[i].mR[1] = cRotationOfNode.mValue[1];// -correctionVector.mValue[1]; mSkDataBuffer.mChannel[i].mR[2] = cRotationOfNode.mValue[2];// -correctionVector.mValue[2];

// Copy data to head SkeletonNodeInfo* lIter; lIter = &mChannel[i]; // значение ноды //memcpy(lIter->mT, mSkDataBuffer.mChannel[i].mT, sizeof(lIter->mT)); memcpy(lIter->mR, mSkDataBuffer.mChannel[i].mR, sizeof(lIter->mR));

if (true) { FBMatrix lTransformation, lChannelTransformation, gTransformatilon; // prepare martix to rotation

//FBQuaternionToMatrix(lTransformation, cQuaternion);

FBRotationToMatrix(lTransformation, mSkDataBuffer.mChannel[i].mR);

for (int j = 0; j < mSkDataBuffer.ChildrensCount; j++) { int children = mSkDataBuffer.mChannel[i].children[j]; if (children != -1) // 0 = hips {

memcpy(&lChannelTransformation[0], mSkDataBuffer.mChannel[children].mdT, sizeof(mSkDataBuffer.mChannel[children].mT)); //дельту от родителя //берем FBMatrixMult(lChannelTransformation, lTransformation, lChannelTransformation);// поворачиваем на кватернион родителя

memcpy(&gTransformatilon[0], mSkDataBuffer.mChannel[i].mT, sizeof(mSkDataBuffer.mChannel[i].mT)); //достаем родительскую ноду текущую

lChannelTransformation = lChannelTransformation + gTransformatilon; //вернуть нужно в глобальных координатах, то есть сложить с родительской нодой

memcpy(&mSkDataBuffer.mChannel[children].mT, &lChannelTransformation[0], sizeof(mSkDataBuffer.mChannel[children].mT)); // here is updating transfers

lIter = &mChannel[children];

memcpy(lIter->mT, mSkDataBuffer.mChannel[children].mT, sizeof(lIter->mT));// значение ноды

}

} }

чт, 30 дек. 2021 г. в 05:38, BestPolarBear @.***>:

Hello, how do you convert the sensor coordinate system to the model node coordinate system?I'm doing something similar to you, but there are some problems with coordinate system conversion.

— Reply to this email directly, view it on GitHub https://github.com/Nulamir/IMUMocap/issues/1, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMBIYG6EVRMATBASFQLUPLLUTPA3ZANCNFSM5K66ODNQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you are subscribed to this thread.Message ID: @.***>