Pages: [1]   Go Down
Author Topic: asin() *always* returns 0  (Read 1132 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50098
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 209
Posts: 13015
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


http://www.nongnu.org/avr-libc/user-manual/group__avr__math.html#ga98384ad60834911ec93ac5ae1af4cf0a

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yup, that's it, looks like I'm going to need to liberally apply the scale() function...
Logged

0
Offline Offline
Shannon Member
****
Karma: 214
Posts: 12406
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
  float pitchRadians = atan2 (accX, accZ) ;
  float rollRadians = atan2 (accY, accZ) ;
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
  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).
Logged

0
Offline Offline
Shannon Member
****
Karma: 214
Posts: 12406
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

[ I won't respond to messages, use the forum please ]

Pages: [1]   Go Up
Jump to: