mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-05-17 17:47:34 +08:00
Make wrap() work with integer types (#145)
* Make wrap() work with integers
This commit is contained in:
committed by
GitHub
parent
25c0455348
commit
cd8ad1584c
+50
-11
@@ -39,25 +39,64 @@ bool isEqualF(const Type x, const Type y, const Type eps = 1e-4f)
|
|||||||
|| (isinf(x) && isinf(y) && isnan(x - y));
|
|| (isinf(x) && isinf(y) && isnan(x - y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename Floating>
|
||||||
|
Floating wrap_floating(Floating x, Floating low, Floating high) {
|
||||||
|
// already in range
|
||||||
|
if (low <= x && x < high) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto range = high - low;
|
||||||
|
const auto inv_range = Floating(1) / range; // should evaluate at compile time, multiplies below at runtime
|
||||||
|
const auto num_wraps = floor((x - low) * inv_range);
|
||||||
|
return x - range * num_wraps;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap value to stay in range [low, high)
|
* Wrap single precision floating point value to stay in range [low, high)
|
||||||
*
|
*
|
||||||
* @param x input possibly outside of the range
|
* @param x input possibly outside of the range
|
||||||
* @param low lower limit of the allowed range
|
* @param low lower limit of the allowed range
|
||||||
* @param high upper limit of the allowed range
|
* @param high upper limit of the allowed range
|
||||||
* @return wrapped value inside the range
|
* @return wrapped value inside the range
|
||||||
*/
|
*/
|
||||||
template<typename Type>
|
float wrap(float x, float low, float high) {
|
||||||
Type wrap(Type x, Type low, Type high) {
|
return matrix::detail::wrap_floating(x, low, high);
|
||||||
// already in range
|
}
|
||||||
if (low <= x && x < high) {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Type range = high - low;
|
/**
|
||||||
const Type inv_range = Type(1) / range; // should evaluate at compile time, multiplies below at runtime
|
* Wrap double precision floating point value to stay in range [low, high)
|
||||||
const Type num_wraps = floor((x - low) * inv_range);
|
*
|
||||||
return x - range * num_wraps;
|
* @param x input possibly outside of the range
|
||||||
|
* @param low lower limit of the allowed range
|
||||||
|
* @param high upper limit of the allowed range
|
||||||
|
* @return wrapped value inside the range
|
||||||
|
*/
|
||||||
|
double wrap(double x, double low, double high) {
|
||||||
|
return matrix::detail::wrap_floating(x, low, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap integer value to stay in range [low, high)
|
||||||
|
*
|
||||||
|
* @param x input possibly outside of the range
|
||||||
|
* @param low lower limit of the allowed range
|
||||||
|
* @param high upper limit of the allowed range
|
||||||
|
* @return wrapped value inside the range
|
||||||
|
*/
|
||||||
|
template<typename Integer>
|
||||||
|
Integer wrap(Integer x, Integer low, Integer high) {
|
||||||
|
const auto range = high - low;
|
||||||
|
|
||||||
|
if (x < low)
|
||||||
|
x += range * ((low - x) / range + 1);
|
||||||
|
|
||||||
|
return low + (x - low) % range;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ int main()
|
|||||||
TEST(fabs(wrap(360. - FLT_EPSILON, 0., 360.) - (360. - FLT_EPSILON)) < FLT_EPSILON);
|
TEST(fabs(wrap(360. - FLT_EPSILON, 0., 360.) - (360. - FLT_EPSILON)) < FLT_EPSILON);
|
||||||
TEST(fabs(wrap(360. + FLT_EPSILON, 0., 360.) - FLT_EPSILON) < FLT_EPSILON);
|
TEST(fabs(wrap(360. + FLT_EPSILON, 0., 360.) - FLT_EPSILON) < FLT_EPSILON);
|
||||||
|
|
||||||
|
// integer wraps
|
||||||
|
TEST(wrap(-10, 0, 10) == 0);
|
||||||
|
TEST(wrap(-4, 0, 10) == 6);
|
||||||
|
TEST(wrap(0, 0, 10) == 0)
|
||||||
|
TEST(wrap(4, 0, 10) == 4);
|
||||||
|
TEST(wrap(10, 0, 10) == 0);
|
||||||
|
|
||||||
// wrap pi
|
// wrap pi
|
||||||
TEST(fabs(wrap_pi(0.)) < FLT_EPSILON);
|
TEST(fabs(wrap_pi(0.)) < FLT_EPSILON);
|
||||||
TEST(fabs(wrap_pi(4.) - (4. - M_TWOPI)) < FLT_EPSILON);
|
TEST(fabs(wrap_pi(4.) - (4. - M_TWOPI)) < FLT_EPSILON);
|
||||||
|
|||||||
Reference in New Issue
Block a user