以参考圆方式将弧度转换为度数

时间:2017-10-08 14:57:52

标签: c floating-point range radians

背景:我在C中为机器人创建地图重新计划器,它应该在环境中添加障碍物,这取决于哪些红外传感器获得高读数。

为此我需要检查机器人在内部地图(指向北方)中的位置与IRL的对比情况。但出于某种原因,我有时会在转换中获得负值。我有什么想法我做错了吗?

永远不应该有任何负面价值观。允许的值应介于0-360之间。截至目前,我有时会得到负值。

#define     PI   3.14159265358979323846264338327950
#define     DEG(x)   (x*57.2957795130823208767981548141)

代码:

float currentRot  = now.th; //current rotation-reading in RAD from function.
if(currentRot > PI){        //normalize values       
   currentRot     = currentRot - 2 * PI;
}
if(currentRot < -PI){
   currentRot     = currentRot + 2 * PI;
}
currentRot        = fmod(currentRot,PI*2); //convert into RAD-modular
currentRot        = DEG(currentRot);       //convert to degrees

我做错了什么想法?

2 个答案:

答案 0 :(得分:1)

π无法准确表示为float,因此使用fmod(currentRot,PI*2);或比较if(currentRot > PI){的任何修改都可能无法为边缘情况提供预期结果。

请注意,currentRot = currentRot + 2 * PI;(foat) + (double),转换为float。这种转换的边缘是有问题的,以避免轻微的负面结果。最好避免将floatdouble数学混合用于此敏感转换。

即使有@M Oehm的好评,不精确PI和混合float/double数学也可能导致否定currentRot

相反,首先将弧度转换为度数,然后转换为mod。

float RadianToDegree(float r);
  float d = (float)(PI/180.0) * r;
  d = fmodf(d, 360.0f);
  if (d < 0.0f) d += 360.0f;
  return d;
}

结果将是[0.0 - 360.0]。

360的修改预计会导致round-off error

fmodf()floatfmod()double一起使用,以避免不必要的转化。

在更高级别的注释中,“允许值应介于0-360之间”的目标牺牲精度。考虑介于-180 - +180之间的主要范围。

答案 1 :(得分:-1)

下面:

if(currentRot > PI){        //normalize values       
  currentRot     = currentRot - 2 * PI;
}
if(currentRot < -PI){
  currentRot     = currentRot + 2 * PI;
}

你试图规范化为-π&lt; currentRot&lt; π,然后你做:

currentRot = fmod(currentRot,PI*2);

“返回numer / denom的浮点余数”(ref),意味着结果的符号将是相同的。

这并不能确保禁止使用负值。我的意思是你的范围不是从0开始。