MIRA
|
MIRA integrates Eigen and its datatypes such as Eigen::Matrix, etc. It provides several methods and tools for frequently needed maths, such as angles and rotations. The most important ones are described below. Others can be found in the API Reference.
The <math/Angle.h> header provides classes in different flavors to represent angles. Degree represents angles using degrees, hence its values range from 0 to 360:
Radian represents angles using radians from 0 to 2pi:
Since the same angle can be represented by different values (e.g. by adding multiples of 2pi), the angle classes automatically normalize the angle values after operations like additions, multiplications with scalars etc. Values that become larger then 360 or 2pi and values that become smaller than 0 are wrapped to make sure that the values will always stay within the given ranges.
If you prefer to use angles in the symmetric interval -180 to 180, you can use the "Signed" counterparts of the above classes. SignedDegree represents signed angles from -180 to 180 degrees and SignedRadian represents signed angles from -pi to pi.
All of these classes can be used with different floating point datatypes:
The Degree classes can also be used with integer datatypes. Radian cannot be used with integers since the precision is not sufficient:
For convenience, there are several typedefs to shorten the declaration, e.g: Degreei, Degreef, Degreed, Radianf, Radiand.
The different angle types are interchangeable with each other, conversions will be done automatically between them:
Please note that conversions between angles of different types (e.g. float to int or double to float) need to be made explicitly, while conversions between different angle representations (e.g. degree to radian) are done implicitly:
Also note that for conversions from floating point angles to integer type angles the same rules apply that are used for conversions between floating point numbers and integer values: The number is truncated and the decimal part is dropped, i.e. the value will NOT be rounded.
As shown in the above example, the angle types support different operators, like addition, subtraction, multiplication, division and comparison operators. For more information, please refer to the API documentation.
An often used computation with angles is the calculation of the difference between two angles.
Beside the subtraction operator, the angle classes provide a smallestDifference() method. This method takes into account that there are always two differences between two angles (remember that an angle is defined in a cyclic interval and you can go into two different directions to reach any different angle). The smallestDifference() method will always return the smallest of these two angles. Also note, that smallestDifference() returns a signed angle:
Beside the above Degree and Radian classes there exists an Angle and SignedAngle class. Both are almost the same as Radian and SignedRadian, i.e. they also store the angle using radians. The only difference is that the angle values are serialized using degrees. This allows a more user-friendly handling of angles e.g. in config files, while internally they are represented in radians.
The table below gives an overview of all angle types:
angle class | unit | range | unit for serialization |
---|---|---|---|
Degree | degree | [0, 360) | degree |
SignedDegree | degree | [-180, 180) | degree |
Radian | radian | [0, 2pi) | radian |
SignedRadian | radian | [-pi, pi) | radian |
Angle | radian | [0, 2pi) | degree |
SignedAngle | radian | [-pi, pi) | degree |
2D rotations are represented using a single angle. Usually, it describes a rotation within the xy-plane.
The standard representation for 3D rotations are Quaternions. Quaternions have several desirable properties:
Alternatively, rotations can also be represented using a 3x3 rotation matrix or using yaw/pitch/roll angles. To convert between those three representations, several methods are provided in the <math/YawPitchRoll.h> header:
Conversions between quaternions and rotation matrices are provided directly by Eigen:
When using Yaw/Pitch/Roll angles, the following rotation order has to be taken into account:
where:
For input and output of formatted matrices, the format() method is provided by <math/EigenFormat.h>. It allows to read and write matrices from streams using different formats. Currently, the following matrix formats are supported:
To write a matrix in Matlab format, use:
To parse a matrix in Python format, use:
If an error occurs during parsing, an XIO Exception will be thrown.
MIRA provides different ways to produce random numbers:
Both methods have different pros and cons:
MIRA_RANDOM | boost::random | |
---|---|---|
Pros |
|
|
Cons |
|
|
MIRA_RANDOM can be used whenever you need a simple random number and when you do not have any requirements to the random number sequence and when you do not need special random distributions.
Sampling from a uniform distribution:
Sampling from a univariate normal distribution:
The boost::random library provides different random distributions and different random generator engines.
To simplify their usage, MIRA provides the RandomGenerator<> template.
A random generator with a certain random distribution, e.g. boost::boost::uniform_01 can be used as follows:
MIRA provides the UniformRandomGenerator class - a random generator that samples random numbers within the interval that is passed to the contructor. The UniformRandomGenerator template class can be used with floating point and integer datatypes. For integer types, the sampled values are within the interval [vmin,vmax]. For floating point types, the sampled values are within the interval [vmin,vmax).
Example:
MIRA also provides NormalRandomGenerator, a random generator for drawing samples from zero-mean univariate or multivariate normal distributions. The dimension of the generated samples are specified as template parameter D (univariate distribution if D==1 or multivariate if D>1).
For the multivariate distributions, the covariance matrix must be specified via the constructor or using the setSigma method.
Example:
To produce non-zero mean samples you can simply add the mean to the returned samples.