xioTechnologies / Fusion

MIT License
1.01k stars 241 forks source link

Question: about the output quaternion regarding to "North-West-Up (NWU)" #51

Closed mingrenzhu closed 1 year ago

mingrenzhu commented 1 year ago

hello, can you explain why the output quaternion is based on the North-West-Up (NWU) ? I have no idea about this discription, " The quaternion describes the orientation of the sensor relative to the Earth using the North-West-Up (NWU) convention" . And I want to know the principle, can you give me some tips about this ? thanks a lot

xioTechnologies commented 1 year ago

The North-West-Up (NWU) describes the axis directions relative to the Earth as X = North, Y = West, and Z = Up.

mingrenzhu commented 1 year ago

thanks for your reply, I means why to set the North-West-Up coordinate. In general, we can use the one piece of acc and mag data to calculate transformation matrix based on ENU or NWU between the earth coordinate and imu coordinate, and set this transformation as the intial pose q0. In fusion algorithm, we set the initial quaternion pose as identity matrix, and the output pose will be correct with the feed of acc and mag data, that is why the "ahrs->rampedGain" coefficient is large, because we use the acc and mag data to converge into right pose. and during this convergence process, we make sure the NWU coordinate, not ENU coordinate, is the viewpoint right ? following codes are related with the decision with the NWU coordinate, is it right ?

   const FusionVector halfGravity = {
            .axis.x = Q.x * Q.z - Q.w * Q.y,
            .axis.y = Q.y * Q.z + Q.w * Q.x,
            .axis.z = Q.w * Q.w - 0.5f + Q.z * Q.z,
    };
   ahrs->halfAccelerometerFeedback = FusionVectorCrossProduct(FusionVectorNormalise(accelerometer), halfGravity);
   const FusionVector halfWest = {
                .axis.x = Q.x * Q.y + Q.w * Q.z,
                .axis.y = Q.w * Q.w - 0.5f + Q.y * Q.y,
                .axis.z = Q.y * Q.z - Q.w * Q.x
        };
    ahrs->halfMagnetometerFeedback = FusionVectorCrossProduct(FusionVectorNormalise(FusionVectorCrossProduct(halfGravity, magnetometer)), halfWest);
xioTechnologies commented 1 year ago

I am sorry but I do not understand your description and question. NWU and ENU are conventions. Fusion uses NWU.

mingrenzhu commented 1 year ago

Sorry for confusing you, i change my question to another. if I want to change the output quaternion pose to be based on ENU ? what should i do ?

mingrenzhu commented 1 year ago

I am sorry but I do not understand your description and question. NWU and ENU are conventions. Fusion uses NWU.

Sorry for giving this uncomfortable understanding for you. I want to give further explanations for you. In your thesis, you mentioned that your output is based the North-West coordinate. My question is that which step in your algorithm is based on the North-West coordinate.

Thanks for your patience and hope your reply. Cheers!

xioTechnologies commented 1 year ago

A change from NWU to ENU would only affect line 164. If you are only using a gyroscope and accelerometer then no change is required. In this case, NWU and ENU are identical because the algorithm would have no reference of heading.

mingrenzhu commented 1 year ago

I see, and if i want to change the NWU to ENU, how can i revise the line 164 to change into ENU ? can you give me an example or some related materials ?

Thanks for your patience and hope your reply. Cheers!

xioTechnologies commented 1 year ago

My previous comment was incorrect, several other changes would be required. The changes are too complex to guide you through here. I will consider this a feature request for Fusion to support NWU, NED, and ENU. I cannot suggest a completion date at this time. However, you can access the WIP once the feature branch is available.

mingrenzhu commented 1 year ago

Cool, thanks a lot.

xioTechnologies commented 1 year ago

ENU and NED support has been added in axes-convention.

mingrenzhu commented 1 year ago

Wonderful !! very thankful !!

mingrenzhu commented 1 year ago

One more question, i want to know the theory behind the Ned or END calculation code, can you give me some documents or advice about that ? thanks.

mingrenzhu commented 1 year ago

Hello, I check the axes-convention branch code, and discover that the code realization about function named by "HalfGravity(const FusionAhrs *const ahrs)" is not complete. the "case FusionConventionNwu" is not realized.

static FusionVector HalfGravity(const FusionAhrs *const ahrs) {
#define Q ahrs->quaternion.element
    switch (ahrs->settings.convention) {
        case FusionConventionNwu:
        case FusionConventionEnu:
            return (FusionVector) {
                    .axis.x = Q.x * Q.z - Q.w * Q.y,
                    .axis.y = Q.y * Q.z + Q.w * Q.x,
                    .axis.z = Q.w * Q.w - 0.5f + Q.z * Q.z,
            }; // third column of transposed rotation matrix scaled by 0.5
        case FusionConventionNed:
            return (FusionVector) {
                    .axis.x = -1.0f * (Q.x * Q.z - Q.w * Q.y),
                    .axis.y = -1.0f * (Q.y * Q.z + Q.w * Q.x),
                    .axis.z = -1.0f * (Q.w * Q.w - 0.5f + Q.z * Q.z),
            }; // third column of transposed rotation matrix scaled by -0.5
        default:
            return FUSION_VECTOR_ZERO; // avoid compiler warning
    }
#undef Q
}

Thanks for your patience and hope your reply. Cheers!

xioTechnologies commented 1 year ago

North-West-Up (NWU), East-North-Up (ENU), and North-East-Down (NED) describe the alignment of the Earth XYZ axes. I do not have any documentation for how calculations differ for each. It should be clear from the code and comments, assuming the reader is familiar with the underlying mathematics. For example, the acceleration of gravity is in the up direction. For NWU and ENU, up is aligned with +Z and so gravity must be equal to the third column of a rotation matrix. For NED, up is aligned with -Z and so gravity must be equal to the negated third column of a rotation matrix.

The code is complete. The value of halfGravity is the same for FusionConventionNwu and FusionConventionEnu so the switch statement implements a fall through.

mingrenzhu commented 1 year ago

Thanks for your reply. I check the theory from chapter 7 of Madgwick's PhD thesis combined with your explanation, and i understand the calculation of "HalfGravity" vector based on different axe conversions. thanks again.