0

Possible Duplicate:
C: How to wrap a float to the interval [-pi, pi)

I have the following code and I want to optimize it in order to prevent the while loops in the rotate function when the second parameter is huge. The code is:

#include <math.h>
#include <stdio.h>
#include <string.h>

typedef struct {
   double x;
   double y;
} pos_t;

typedef struct {
   double a;
} ori_t;

typedef struct {
   pos_t pos;
   ori_t ori;
} pose_t;


void forward(pose_t *pose, double dist_units) {
   pose->pos.x += cos(pose->ori.a)*dist_units;
   pose->pos.y += sin(pose->ori.a)*dist_units;
}

inline double deg_to_rad(double angle_deg) {
   return angle_deg*M_PI/180.0;
}

inline double rad_to_deg(double angle_rad) {
   return 180.0*angle_rad/M_PI;
}

void rotate(pose_t *pose, double angle_deg) {
   pose->ori.a += deg_to_rad(angle_deg);
   while (pose->ori.a<0.0) pose->ori.a += 2.0*M_PI;
   while (pose->ori.a>=2.0*M_PI) pose->ori.a -= 2.0*M_PI;
}

int main() {
pose_t pose;
pose.pos.x = 0.0;
pose.pos.y = 0.0;
pose.ori.a = 0.0;
char command[3];
double parameter;
printf("robot:");
while (scanf("%2s %lf",command,&parameter)==2) {
    if (strcmp(command,"fw")==0) {
        forward(&pose, parameter);
        printf("Moved to (%.1f,%.1f,%.0f)!\n",pose.pos.x,pose.pos.y,rad_to_deg(pose.ori.a));
    } else if (strcmp(command,"rt")==0) {
        rotate(&pose, parameter);
        printf("Turned to (%.1f,%.1f,%.0f)!\n",pose.pos.x,pose.pos.y,rad_to_deg(pose.ori.a));
    } else {
        printf("Command '%s' not recognized!\n",command);
    }
    printf("robot:");
}
return 0;
}

Any idea on what changing in the rotate function?

Community
  • 1
  • 1
kokosg
  • 123
  • 3
  • 11
  • 2
    You can use the `fmod` function. – Steve Jessop Oct 21 '12 at 22:20
  • 2
    This answer: "http://stackoverflow.com/questions/4633177/c-how-to-wrap-a-float-to-the-interval-pi-pi" is quite related and will help you efficiently keep your angle to within the required range. – PKG Oct 21 '12 at 22:20
  • The `rotate` function is performing trigonometric argument reduction. This is a notorious problem because very large relative errors can occur for certain inputs. Some representable floating-point numbers are much closer to a multiple of 2π than `2*M_PI` is. Reducing these numbers using `2*M_PI` produces a result that is much greater than it should be. If accuracy matters to your application, you should consider accuracy as well as performance. Addressing this issue is worthy of a question by itself. – Eric Postpischil Oct 22 '12 at 11:26

0 Answers0