'''NOTE''' The base methods base::nan<>() and base::infinity<>() will be added to base/types if this proposal gets accepted
This details the acceptable semantics of NaN and Infinity as special values in oroGen interfaces and/or C++ libraries
Floating-point values (float and double in C++) have two "special" values: Not A Number (NaN) and Infinity. This page details the accepted semantic, in Rock, of these special values across component boundaries.
== Unset parameters ==
NaN can be used in configuration data structures to represent that a special parameter has not been set. In C++ for a float parameter, this is done with
{{{
#include
config.value = base::unset();
}}}
If you do not want to add a dependency to base/types, use the standard C++ method (rock uses quiet_nan())
{{{
#include
config.value = std::numeric_limits::quiet_nan();
}}}
A not-set value can be interpreted in two ways:
* as an error (if the caller should set this particular value)
* as a way to disable some part of the functionality.
It can be tested with
{{{
#include
if (base::isUnset(config.value))
// generate an error
}}}
Note that one CANNOT use if (config.value == base::unset()) as, in IEEE 754, NaN != NaN
It must NOT be interpreted as a "use default value" indicator. If a sane default value exists, it should be used instead of NaN.
== Unknown values ==
On data structures that do not represent uncertainty, NaN can be used to represent unknown values. For instance, a 3-vector of
{{{
base::Vector3d v(0, 0, base::unknown())
}}}
can be used to represent a position that is known in X, Y but completely unknown in Z. It can then be tested with
{{{
if (base::isUnknown(v.x()))
// generate an error
}}}
On data structures that represent uncertainty, the unknown is not represented can be set in two ways:
* in e.g. in information filters, the value of zero is used to represent no information
* in e.g. covariance matrix representations, no information is represented as infinity
{{{
#include
covariance(3, 2) = base::infinity();
}}}
If you do not want to add a dependency to base/types, use the standard C++ method:
{{{
#include
covariance(3, 2) = std::numeric_limits::infinity();
}}}
Even though one can test against infinity, for consistency reasons, testing should be done using base::isInfinity(v)
It is encouraged for such types to have some invalidation / validity test methods. For instance, [http://rock-robotics.org/api/base/types/structbase_1_1samples_1_1RigidBodyState.html RigidBodyState] offers the invalidate(), invalidatePosition(), invalidateOrientation() methods to resp. set all covariance values to infinity, the position covariance to infinity and/or the orientation covariance to infinity. The corresponding test methods hasValidPosition() and hasValidOrientation() allows then to test if some information is present in these fields.
== In Ruby ==
In the Typelib/Ruby bindings, i.e. when interacting with log data and/or live orocos components, one can set floating-point values to Infinity and NaN in the following way:
{{{
config.value = Infinity
covariance.data[5] = NaN
}}}
I.e. infinity is mapped to the Infinity toplevel constant, while NaN is mapped to the NaN constant.
For consistency reasons, the base/types_ruby package also defines the following:
{{{
require 'base/float'
Base::infinity()
Base::infinity?(v)
Base::unset()
Base::unset?(v)
Base::unknown()
Base::unknown?(v)
}}}