자력계 ∞ 모양 교정


15

3 축 전자 나침반을 사용하는 휴대폰 및 기타 장치에서는 ∞ / 8 / S 모양의 움직임 이이 비디오에 표시된대로 자력계를 교정하는 데 사용됩니다 .

이 동작이 수행되는 이유는 무엇이며 이론은 무엇이며이를 구현하기 위해 C 코드 예제를 제공 할 수 있습니까?

더 많은 정보가 포함 된 비슷한 질문 을 거쳐야합니다 .


이 특정 질문에 대한 추가 정보 : 플랫폼은 AVR Studio 5를 사용하는 8 비트 AtMega32입니다.

지금까지 시도했습니다 : 모양을 만드는 자력계의 벡터 값 중 2 개로 평균을 나눕니다 . 사고는 오프셋 계산에 도움이 될 수 있습니다. 모양의 동일한 두 부분 /면이 어떻게 지구 자기장을 상쇄하고 오프셋 값을 제공하는지 생각합니다. 제가 틀렸을 수 있습니다. 그러나 특히 형상 기반 보정의 경우 현재 위치입니다. 교정이 이런 식으로 작동한다고 생각합니다. 아이디어는 그것이 이런 식으로 작동하는지 알아내는 것입니다.


오프셋을 계산하고 나중에 Raw magnetic 3D 벡터에서 오프셋을 빼는 코드를 확인하십시오. 나는 완전히 틀렸고 그것이 어떻게 작동하는지에 대한 설명이 없습니다. 비디오와 데이터가 구체에 그려진 후 어떻게 든 내 생각을 가속화했으며 그 생각을 방정식의 형태로 사용했습니다. 비)

암호:

Read_accl();Read_magnato(1);기능은 센서 데이터를 판독한다. 코드가 자명하기를 바랍니다. 현명한 ppl을 기대하면 훨씬 더 나은 방법으로 이것을 사용할 것입니다. : \

void InfinityShapedCallibration()
{
    unsigned char ProcessStarted = 0;
    unsigned long cnt = 0; 

    while (1)
    {

            Read_accl();

            // Keep reading Acc data
            // Detect Horizontal position
            // Detect Upside down position
            // Then detect the Horizontal position again.
            // Meanwhile an infinity shaped movement will be created.
            // Sum up all the data, divide by the count, divide by 2 .
            // !We've offsets.          

                if (ProcessStarted!=3)
                {
                //
                    //USART_Transmit_String("\r");
                    //rprintfFloat(4, g_structAccelerometerData.accx_RAW);
                    //USART_Transmit_String(",");
                    //rprintfFloat(4, g_structAccelerometerData.accy_RAW);
                    //USART_Transmit_String(",");
                    //rprintfFloat(4, g_structAccelerometerData.accz_RAW);

                }


            if (
             abs( g_structAccelerometerData.accx_RAW) < 100 
            && abs(g_structAccelerometerData.accy_RAW) < 100 
            && g_structAccelerometerData.accz_RAW < -350 
            && ProcessStarted != 2 && ProcessStarted != 3 && ProcessStarted != 1 )
            {
                ProcessStarted = 1; 
            }   

            if (ProcessStarted==1)
            { 

            Read_magnato(1);

                structMagnetometerOffsetDataToEEPROM.Off_X += g_structMegnetometerData.magx_RAW;
                structMagnetometerOffsetDataToEEPROM.Off_Y += g_structMegnetometerData.magy_RAW;
                structMagnetometerOffsetDataToEEPROM.Off_Z += g_structMegnetometerData.magz_RAW;

                cnt++;

            }               
                if ( g_structAccelerometerData.accz_RAW > 350 
                && ProcessStarted==1)
                {
                    ProcessStarted = 2; 
                }

                if ( g_structAccelerometerData.accz_RAW < -350 
                && ProcessStarted == 2 )
                {
                    ProcessStarted=3; 
                    structMagnetometerOffsetDataToEEPROM.Off_X /= cnt;
                    structMagnetometerOffsetDataToEEPROM.Off_X /= 2;

                    structMagnetometerOffsetDataToEEPROM.Off_Y /= cnt;
                    structMagnetometerOffsetDataToEEPROM.Off_Y /= 2;

                    structMagnetometerOffsetDataToEEPROM.Off_Z /= cnt;
                    structMagnetometerOffsetDataToEEPROM.Off_Z /= 2;  

                    UpdateOFFSETDATAinEEPROM();  

                    break;

                } 
    }   
} 

이 오프셋을 얻은 후 다음과 같이 사용했습니다.

void main()
{
...

Read_magnato(1);
        g_structMegnetometerData.magx_RAW -= structMagnetometerOffsetDataToEEPROM.Off_X ;
        g_structMegnetometerData.magy_RAW -= structMagnetometerOffsetDataToEEPROM.Off_Y ;
        g_structMegnetometerData.magz_RAW -= structMagnetometerOffsetDataToEEPROM.Off_Z ;
...
}

내가 말했듯이.


2
이 질문에는 많은 도움이 필요합니다. 프로그래밍에 도움이 필요하십니까? 자력계에 대한 이론? 어떤 플랫폼? 무엇을 시도하거나 찾아 보셨습니까?
Kellenjb

그림 8은 단순히 교정을 시작하는 제스처가 아닙니까?
geometrikal

1
왜 ppl이 마치 로봇 인 것처럼 행동하는지 모르겠습니다. 동일한 작업에 대한 링크를 제공했습니다. 나는 그것을 알지 못하고 그것에 투표하기 위해 많은 노력을 기울였습니다. 내 불명확 한 질문으로 인해 내 질문에 투표하지 않을 때 나는 그것을 싫어한다. 투표하기 전에 필요한 것을 물어보십시오. 나는 실제로 출력을 얻기 위해 죽어 가고 있으며 ppl은 투표하기 전에 생각조차하지 않습니다. 기분이 나쁘고 올바른 방향으로 일하지 못하게합니다. 투표의 어느 쪽도 도움이 필요하지 않습니다.
Rick2047

1
@ Kellenjb : 간단한 8 비트 atmega32를 사용하여 IMU를 만들고 있습니다. 32 비트 uC가 바늘 대신 칼을 사용하는 것과 같다는 결론을 내 렸습니다. (수수께끼 : 죄송합니다.)) 모양을 만드는 자력계의 모든 RAW 값을 합산하려고했습니다. 그런 다음 입력 수로 나눕니다. 생각은 오프셋을 계산하는 데 도움이 될 수 있습니다. 모양의 동일한 두 부분 /면이 어떻게 지구의 자기장을 상쇄하고 오프셋 값을 주는지 생각합니다. 제가 틀렸을 수 있습니다. 그러나 특히 형상 기반 보정의 경우 현재 위치입니다. 나는 생각합니다 ...
Rick2047

1
문제는 질문에 관한 것이 아니라이 사이트에있는 사람들의 수가 질문에 대한 내용을 이해하기에 충분히 익숙하지 않기 때문에 질문에 대한 의견을 줄였습니다. 모르는 경우에는 그대로 두십시오!
Chris Stratton

답변:


21

8 / S 모양의 패턴은 휴대폰 및 기타 장치에서 자력계를 교정하는 데 사용됩니다.

배경

일반적인 휴대폰 시대의 자력계는 다음과 같은 세 개의 직교 축을 따라 자기장 강도를 측정합니다.

m=mxı^+myȷ^+mzk^

주어진 필드의 크기로

m=mx2+my2+mz2

각 축의 회전 각도는

θk=cos1mkm, where k[x,y,z]

구경 측정

지구의 magenetic field가 비교적 일정하기 때문에, 자력계에 의해 측정 된 as field의 크기 는 센서의 방향에 관계없이 일정해야합니다 . 즉, 센서를 회전시켜 3D로 , 및 를 플롯하는 경우 경로는 반경이 일정한 구의 표면을 합니다.mxmymz

이상적으로는 다음과 같이 보일 것입니다.

구체

그러나 단단하고 부드러운 철 효과와 기타 왜곡으로 인해 변형 된 구처럼 보입니다.

변형

센서에 의해 측정 된 자기장의 크기가 방향에 따라 변하기 때문입니다. 결과는 상기 식에 따라 계산 될 때 자기장의 방향이 실제 방향과 다르다는 것이다.

방향에 관계없이 크기가 일정하도록 3 축 판독 값 각각을 조정하려면 교정을 수행해야합니다. 변형 된 구가 완벽한 구로 뒤틀려 야한다고 생각할 수 있습니다. LSM303의 애플리케이션 노트에서는이를 수행하는 방법에 대한 자세한 내용은 많이 있습니다.

그렇다면 그림 8 패턴은 어떻습니까!?

그림 8 패턴을 수행하면 변형 된 구의 일부가 '추적됩니다'. 얻어진 좌표로부터 구의 변형을 추정 할 수 있고, 교정 계수를 얻을 수있다. 좋은 패턴은 가장 넓은 범위의 오리엔테이션을 추적하므로 실제 일정한 크기와의 최대 편차를 추정합니다.

변형 된 구의 모양을 추정하기 위해 최소 제곱 타원 피팅을 사용할 수 있습니다. LSM303 애플리케이션 노트에도 이에 대한 정보가 있습니다.

기본 보정을위한 간단한 방법

앱 노트에 따르면 연철 왜곡이 없다고 가정하면 변형 된 구가 기울어지지 않습니다. 따라서 간단한 기본 보정 방법이 가능할 수 있습니다.

  • 각 축의 최대 값과 최소값을 찾아 1/2 범위와 영점을 얻습니다.

rk=12(max(mk)min(mk))

zk=max(mk)rk

  • 각 축 측정을 이동 및 스케일

mk=mkzkrk

  • 사용하지 이전과 같이 값을 계산하십시오.mk

이것은 여기에 있는 코드를 기반으로합니다 .

최소 제곱을 사용하여 풀기

최소 제곱을 사용하여 해결하기위한 MATLAB 코드는 다음과 같습니다. 코드는 mag열이 xyz 값인 변수를 가정 합니다.

H = [mag(:,1), mag(:,2), mag(:,3), - mag(:,2).^2, - mag(:,3).^2, ones(size(mag(:,1)))];
w = mag(:,1).^2;
X = (H'*H)\H'*w;
offX = X(1)/2;
offY = X(2)/(2*X(4));
offZ = X(3)/(2*X(5));
temp = X(6) + offX^2 + X(4)*offY^2 + X(5)*offZ^2;
scaleX = sqrt(temp);
scaleY = sqrt(temp / X(4));
scaleZ= sqrt(temp / X(5));

동적 그림 8 교정을 수행하려면 오프셋 및 스케일 팩터가 안정화 될 때마다 새 판독 값마다 최소 제곱 루틴을 실행하고 종료 할 수 있습니다.

지구 자기장

지구의 자기장은 일반적으로 표면과 평행 하지 않으며 아래로 큰 구성 요소가있을 수 있습니다.


안녕하세요, 그림 8 패턴 문제를 해결하기위한 노력을 기울였습니다. 이제 이전 작업과 현재 작업을 연결할 수 있습니다. 개선 된 부분은 있지만 개선점은 표시되지 않았습니다. 질문 만; NEWS는 8 개의 모양을 만든 후 출력 데이터를 사용하여 올바르게 표시되며 모든 벡터의 평균의 절반을 얻습니다. 놀랍게도 수평 계획 (플루크)에 대해 작동합니다. 나는 8 개의 모양의 알고에서 작업을 시작했다.
Rick2047

... 내 경우에도 구가 Z 축에서 변형 된 것 같습니다. 플롯 된 3D 구에 대한 하드 및 소프트 아이언 효과에 대해 알고 있습니다. 3D에 다시 그려 보겠습니다. 보자.
Rick2047

@ Rahul2047 글쎄, 나는 그것이 정확하기를 희망하지만 나에게는 의미가 있습니다. 내가 만들고있는 계측기에서 비슷한 교정을 수행해야하지만 아직 코드를 구현하지는 않습니다.
geometrikal

보통 수평면 방향에만 관심이있는 전화의 경우 간단한 제스처로 필요한 모든 점을 다룰 수 있습니다. matlab을 사용하십니까? 거기에 맞는 것은 쉽습니다. 최소 제곱은 오차 측정 방법을 나타냅니다.
geometrikal

1
이 기사의 일부 이미지 링크가 끊어졌습니다. 이미지를 다시 추가 할 수 있습니까? SE는 이제 미래의 파손을 방지하기 위해 이미지를 업로드하고 로컬에 저장하는 기능을 가지고 있습니다. 감사!
새로운 Alexandria
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.