背景:我在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
我做错了什么想法?
答案 0 :(得分:1)
π无法准确表示为float
,因此使用fmod(currentRot,PI*2);
或比较if(currentRot > PI){
的任何修改都可能无法为边缘情况提供预期结果。
请注意,currentRot = currentRot + 2 * PI;
是(foat) + (double)
,转换为float
。这种转换的边缘是有问题的,以避免轻微的负面结果。最好避免将float
和double
数学混合用于此敏感转换。
即使有@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()
与float
和fmod()
与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开始。