Go Down

### Topic: asin() *always* returns 0 (Read 2898 times)previous topic - next topic

#### cjdavies

##### Apr 26, 2012, 06:14 pm
I'm trying to follow this tutorial which uses asin() but whatever I do it always returns 0.

asin(27)
asin(27.0)
asin((float)27.0)

All return 0. What am I doing wrong?!

#### PaulS

#1
##### Apr 26, 2012, 06:22 pm
Quote
What am I doing wrong?!

You are not showing your real code. That snippet looks fine, so the culprit is what you are doing with the output from the asin function.

#2
##### Apr 26, 2012, 06:23 pm

Quote
The asin() function computes the principal value of the arc sine of __x. The returned value is in the range [-pi/2, pi/2] radians. A domain error occurs for arguments not in the range [-1, +1].

AVR Libc does not produce run-time exceptions.  The developers chose to return zero instead.

#### cjdavies

#3
##### Apr 26, 2012, 06:50 pm
Yup, that's it, looks like I'm going to need to liberally apply the scale() function...

#### MarkT

#4
##### Apr 26, 2012, 07:05 pm
That tutorial sensibly uses atan2 for compass orientation, but for some obscure reason resorts to asin for tilt.  The atan2 approach is superior, since you don't need to calibrate the accelerometer/compass nor to scale its output and it will work with the sensor upside down.
Code: [Select]
`  float pitchRadians = atan2 (accX, accZ) ;  float rollRadians = atan2 (accY, accZ) ;`
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

#### cjdavies

#5
##### Apr 27, 2012, 02:17 pm

That tutorial sensibly uses atan2 for compass orientation, but for some obscure reason resorts to asin for tilt.  The atan2 approach is superior, since you don't need to calibrate the accelerometer/compass nor to scale its output and it will work with the sensor upside down.
Code: [Select]
`  float pitchRadians = atan2 (accX, accZ) ;  float rollRadians = atan2 (accY, accZ) ;`

When you say that it won't require calibration/scaling does this assume that both the accelerometer & compass are physically level with each other, with their axis all parallel? If I just replace asin in the tutorial with atan2 as you've provided the tilt compensation is completely wrong (applying 150 degrees of compensation to the heading when the compass & accelerometer are flat on the desk).

#### MarkT

#6
##### Apr 27, 2012, 05:58 pm
I'm confused - I'm just showing how to calculate pitch and roll correctly from 3-axis accelerometer data - nothing to do with compass, that's already handled isn't it?  The asin method is assuming that the accel data is correctly scaled, and doesn't handle the case where there is acceleration in addition to that due to gravity, nor does it have any meaningful accuracy when the tilt angle approaches 90 to the vertical.

Of course the roll/pitch you get when there is more than just gravity is perhaps less physically meaningful, but atan2 measures the actual angle from the acceleration vector to the z-axis

If you only had 2-axis accelerometer data you'd be forced to resort to asin and assume there was only tilt and no acceleration w.r.t. the earth's surface.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Go Up

Please enter a valid email to subscribe

To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy