Ters trigonometrik fonksiyonlar açı

Başlatan Erhan YILMAZ, 09 Mart 2014, 12:33:21

Erhan YILMAZ

İvme sensöründen aldığım bilgiye göre cismin yer yüzü ile yaptığı açıyı hesaplamak için ters kosinüs(acos) fonksiyonunu kullanıyorum. Fakat çıktı olarak 0-pi arasında bir açı alıyorum. Fonksiyon içerisinde mutlak değer alıyorsa demek negatif açı döndürmüyor. Bu sorunu nasıl halledebilirim?  Studio'nun hazır bir çözümü var mı? Yada daha önce başına gelen, çözen arkadaşlar yardımcı olabilir mi? Amacım acos fonksiyonun çıktısını -pi, +pi yada 0, 2pi arasında bir açıya çevirmek.

z

#1
Cos fonksiyonu 0...2Pi araliginda girdiye karsilik   -1....+1 araliginda sonuclar uretir.

Pi+X ve Pi-X icin Cos ayni sonucu verir. Dolayisi ile bu degerin Acos sonucu Pi+X mi yoksa Pi-X mi bilemezsin.

Ek bir bilgiye ihtiyac var. Bu acinin Asin degerine bakarak Pi'nin altindamisin ustundemisin yorum yapabilirsin.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Erhan YILMAZ

Hocam tam kafamda canlandıramadım eksenleri ama asin bulmak için yeterli veri yok gibi. Elimde +g, -g arasında 3 eksen ivme bilgisi var bide bunların karelerinin toplamının kökünü alıp bileşke kuvveti buluyorum. Netten buldum eksen bilgilerinin tek tek bileşke vektöre oranlarını acos fonkuna parametre geçip açıyı elde ediyorum. Sonuçta giriş değeri negatif olabiliyor ama negatif açı vermiyor. Hesap makinesinde denedim sorun yok. Studionun math fonkları mı yetersiz anlamadım. Ardışık gelen açıların farkına göre dönme yönünü, eksen değerlerine göre hangi bölgede olduğuda bulunabilir. Bunları kullanarak sorunu çözebilir miyiz.

z

Sorun girdinin negatif olup olmamasi degil.

Radyan cinsinden;

3.24 un cosinusu -0,99
3.04 un cosinusu de -0.99

Simdi -0.99 un ACcos degeri hangi acidir? 3.24 mu yoksa 3.04 mu? Dikkat edersen bu degerlerden birisi Pi nin altinda digerisi ustunde.

Istersen sorunu sayisal degerlerle tekrar yaz.

Hesap makinesinde ve C de elde ettigin degerleri ayri ayri yazarmisin?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Erhan YILMAZ

Yanlış işlem yapmışım hocam asin fonkunu denemişim ikisinde de sonuç aynı çıkıyor. Sonuç olarak kafam karıştı. Kartın hareketlerini modellemeye çalışıyorum ama beceremedim. Bu iş için ivme bilgisi yeterli değil mi? Gyro bilgisi de mi gerekli? Elde ettiğim veriler ve yazdığım kod parçasını aşağıda veriyorum.

// HID cihazdan gelen 3 eksen 16bit işaretli ivme değerleri 
                int x = (int)(short)(In_Data[2] << 8 | In_Data[1]);
                int y = (int)(short)(In_Data[4] << 8 | In_Data[3]);
                int z = (int)(short)(In_Data[6] << 8 | In_Data[5]);

                // G cinsinden ivme değerleri elde edilir (tam skala -2g, -2g)
                if (x < 0)
                    X = Convert.ToDouble(x) * 2 / 32768;
                else
                    X = Convert.ToDouble(x) * 2 / 32767;
                if (y < 0)
                    Y = Convert.ToDouble(y) * 2 / 32768;
                else
                    Y = Convert.ToDouble(y) * 2 / 32767;
                if (z < 0)
                    Z = Convert.ToDouble(z) * 2 / 32768;
                else
                    Z = Convert.ToDouble(z) * 2 / 32767;

                R = Math.Sqrt(Math.Pow(X, 2.0) + Math.Pow(Y, 2.0) + Math.Pow(Z, 2.0));
                // İvme bilgisine göre açı değerleri hesaplanır.
                AngleX = Math.Acos(X / R) * 180.0 / Math.PI;
                AngleY = Math.Acos(Y / R) * 180.0 / Math.PI;          
                AngleZ = Math.Acos(Z / R) * 180.0 / Math.PI;


Discovery kitin durumuna göre gelen ivme değerleri ve benim hesapladığım açı değerleri

Kart normal poziyonda
Açı:     X=88,77703 Y=87,84490 Z=2,47821
İvme: X=0,02051 Y=0,03613 Z=0,95999

Ters Döndürülmüş
Açı:    X=89,39256 Y=91,87777 Z=178,02636
İvme: X=0,01074 Y=-0,03320 Z=-1,01270

Sol tarafına doğru diklenmiş
Açı:     X=88,93516 Y=1,58726 Z=88,82306
İvme: X=0,01856 Y=0,99808 Z=0,02051

Sağ tarafına doğru diklenmiş
Açı:     X=89,77424 Y=173,66204 Z=96,33391
İvme: X=0,00391 Y=-0,98535 Z=-0,10938

Alt tarafına doğru diklenmiş
Açı:    X=178,33506 Y=88,39503 Z=89,55730
İvme: X=-1,01074 Y=0,02832 Z=0,00781

Üst tarafına doğru diklenmiş
Açı:     X=5,34231 Y=91,04625 Z=95,23827
İvme: X=1,01175 Y=-0,01855 Z=-0,09277

fatih6761

Hocam arctan2 kullanırsanız işareti de alırsınız. Mesela yaptığım projede internette dolaşan bir formülü kullandım. Yalnız ben hesabı mcu tarafında yapıp LCD'ye yazdırmıştım ama hesap aynı:
        X_Value = (float)(olculen_x);
    	Y_Value = (float)(olculen_y);
    	Z_Value = (float)(olculen_z);

        /* Calibrate sensitivity */
    	X_Value *= LIS302DL_SENSITIVITY_2_3G / 1000.0f;
    	Y_Value *= LIS302DL_SENSITIVITY_2_3G / 1000.0f;
    	Z_Value *= LIS302DL_SENSITIVITY_2_3G / 1000.0f;

    	/* Calculate angles with arctan */
    	X_Angle = atan2f(X_Value, sqrtf(Y_Value * Y_Value + Z_Value * Z_Value));
    	Y_Angle = atan2f(Y_Value, sqrtf(X_Value * X_Value + Z_Value * Z_Value));

    	/* Convert angles from radians to degrees */
    	X_Angle *= 180.0f;
    	Y_Angle *= 180.0f;

    	X_Angle /= __PI;
    	Y_Angle /= __PI;


X_Value,Y_Value,Z_Value ve X_Angle,Y_Angle değerlerin C# için float veya double türünden olabilir. atan2f için Math.Atan2 kullanabilirsiniz.

Erhan YILMAZ

Sağolun hocam yönlendirmeniz doğrultusunda aşağıdaki şekilde sorunu çözdüm gibi kurcalamaya devam ediyorum.

                AngleX = Math.Atan2(X,Z) * 180.0 / Math.PI;
                AngleY = Math.Atan2(Y,Z) * 180.0 / Math.PI;

Mucit23