#1
  1. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Feb 2008
    Posts
    601
    Rep Power
    43

    Logic not trapping


    Hi,

    This code is short and sweet. It is complete as posted. The problem is this: when the value of hdg_ins exceeds M_PI*2.0 (360 degrees) or goes negative (less than 0) the bounds check fails and doesn't execute.

    1) Why
    2) How to fix it?

    Code:
    {
    	hdg_error = hdg_error + ((7.0/25920000.0)*M_PI);
    	if(hdg_error >= (M_PI*2.0)) hdg_error = hdg_error - (M_PI*2.0);
    	if(hdg_error < 0.0) hdg_error = hdg_error + M_PI*2;
    
    	inertial_hdg = inertial_hdg + (rateyaw * cos(-roll)) + (ratepitch * sin(-roll));
    	hdg_ins = (inertial_hdg * 0.025) + hdg_error;
    
    	if(hdg_ins >= (M_PI*2.0)) hdg_ins = hdg_ins - (M_PI*2.0);
    	if(hdg_ins < 0.0) hdg_ins = hdg_ins + (M_PI*2.0);
    }
    Many thanks in advance.

    Best regards,
    AstroTux.
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,417
    Rep Power
    1871
    I think you would need to post a test case we can copy/paste/run for ourselves.

    Compiling a bit of code and stepping through with gdb shows nothing unexpected here.
    Code:
    Breakpoint 1, main () at foo.c:18
    18	    if(hdg_ins >= (M_PI*2.0)) hdg_ins = hdg_ins - (M_PI*2.0);
    (gdb) list
    13	    if(hdg_error < 0.0) hdg_error = hdg_error + M_PI*2;
    14	
    15	    inertial_hdg = inertial_hdg + (rateyaw * cos(-roll)) + (ratepitch * sin(-roll));
    16	    hdg_ins = (inertial_hdg * 0.025) + hdg_error;
    17	
    18	    if(hdg_ins >= (M_PI*2.0)) hdg_ins = hdg_ins - (M_PI*2.0);
    19	    if(hdg_ins < 0.0) hdg_ins = hdg_ins + (M_PI*2.0);
    20	    }
    21	    
    22	    return 0;
    (gdb) set hdg_ins = 7
    (gdb) step
    19	    if(hdg_ins < 0.0) hdg_ins = hdg_ins + (M_PI*2.0);
    (gdb) step
    22	    return 0;
    (gdb) print hdg_ins
    $5 = 0.71681469282041377
    
    (gdb) run
    Breakpoint 1, main () at foo.c:18
    18	    if(hdg_ins >= (M_PI*2.0)) hdg_ins = hdg_ins - (M_PI*2.0);
    (gdb) set hdg_ins = -7
    (gdb) step
    19	    if(hdg_ins < 0.0) hdg_ins = hdg_ins + (M_PI*2.0);
    (gdb) step
    22	    return 0;
    (gdb) print hdg_ins
    $6 = -0.71681469282041377
    (gdb)
    I set positive and negative out of range values, and it all seems fine.

    The only thing I can think of is if hdg_ins is a float, and you're getting some weird rounding very close to the range limits, which results in the adjustments still being out of range.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    It would also help if you gave us the test input values that you're using. Plus the variable declarations as salem alluded to.
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,995
    Rep Power
    481

    use fmod, not if if if


    Code:
    #define PI2 (2*M_PI)
    {
      hdg_error += (7.0/25920000.0)*M_PI;
      hdg_error = fmod(hdg_error+PI2,PI2);
      inertial_hdg = inertial_hdg + (rateyaw * cos(-roll)) + (ratepitch * sin(-roll));
      hdg_ins = (inertial_hdg * 0.025) + hdg_error;
      hdg_ins = fmod(hdg_ins+PI2,PI2);
    }
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Feb 2008
    Posts
    601
    Rep Power
    43
    Hi,

    It was the float vs. integer thing.

    e.g.

    Code:
    double result = 1/6;
    1/6 treated like an integer. Destination type is double. How can I change this default behavior?

    If I have:

    Code:
    double result = 1.0/6.0;
    I get the correct result.

    Best regards,
    AstroTux.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    3
    Try this code & compare results.
    Code:
         #include <stdio.h>
    
         int
         main (void)
         {
            double result;
    
    
            result = 1/6;
            printf ("\nresult = %f",result);
    
            result = 1./6.;
            printf ("\nresult = %f",result);
    
            result = (float) 1/6;
            printf ("\nresult = %f",result);
    
            result = (double) 1/6;
            printf ("\nresult = %f",result);
    
           return 0;
         }
    Last edited by EEmaestro; September 7th, 2012 at 01:23 PM.

IMN logo majestic logo threadwatch logo seochat tools logo