**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 <base/float.h> config.value = base::unset<float>();

If you do not want to add a dependency to base/types, use the standard C++ method (rock uses quiet_nan())

#include <limits> config.value = std::numeric_limits<float>::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 <float.h> 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<double>())

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 <base/float.hpp> covariance(3, 2) = base::infinity<double>();

If you do not want to add a dependency to base/types, use the standard C++ method:

#include <limits> covariance(3, 2) = std::numeric_limits<double>::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, 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)