UnscentedTransform.cpp
Go to the documentation of this file.
1// *****************************************************************
2// Filename: UnscentedTransform.cpp
3// Copyright: Kai Welke, Chair Prof. Dillmann (IAIM),
4// Institute for Anthropomatics (IFA),
5// Humanoids and Intelligence Systems Lab,
6// Karlsruhe Institute of Technology. All rights reserved.
7// Author: Kai Welke
8// Date: 20.01.2010
9// *****************************************************************
10
11
12#include "UnscentedTransform.h"
13
14#include <cstdio>
15#include <iostream>
16
17UnscentedTransform::UnscentedTransform(float fAlpha, float fKappa, float fBeta)
18{
19 m_fAlpha = fAlpha;
20 m_fBeta = fBeta;
21 m_fKappa = fKappa;
22}
23
24Eigen::MatrixXd
26{
27 // ctreate required matrices
28 int nNumberDimensions = gaussian.getDimensions();
29 int nNumberSigmaPoints = 2 * nNumberDimensions + 1;
30 Eigen::MatrixXd sigmaPoints(nNumberDimensions, nNumberSigmaPoints);
31 Eigen::VectorXd w_m(nNumberSigmaPoints);
32 Eigen::VectorXd w_c(nNumberSigmaPoints);
33
34 // calculate lamda factor
35 float fLamda = m_fAlpha * m_fAlpha * (nNumberDimensions - m_fKappa) - nNumberDimensions;
36
37 // first sigmapoint is mean
38 sigmaPoints.block(0, 0, sigmaPoints.rows(), 1) = gaussian.getMean();
39 w_m(0) = fLamda / (nNumberDimensions + fLamda);
40 w_c(0) = fLamda / (nNumberDimensions + fLamda) + (1 - m_fAlpha * m_fAlpha + m_fBeta);
41
42 // precalculate square root of matrix
43 Eigen::MatrixXd diff(nNumberDimensions, nNumberDimensions);
44 diff = (nNumberDimensions + fLamda) * gaussian.getCovariance();
45
46 // square root of diagonal matrix
47 diff = squareRoot(diff);
48
49 // generate 2n sigmapoints
50 Eigen::VectorXd point1(nNumberDimensions);
51 Eigen::VectorXd point2(nNumberDimensions);
52
53 float fWeight;
54
55 for (int i = 0; i < nNumberDimensions; i++)
56 {
57 // points
58 point1 = gaussian.getMean() + diff.block(i, 0, 1, diff.cols()).transpose();
59 point2 = gaussian.getMean() - diff.block(i, 0, 1, diff.cols()).transpose();
60 sigmaPoints.block(0, 2 * i + 1, sigmaPoints.rows(), 1) = point1;
61 sigmaPoints.block(0, 2 * i + 2, sigmaPoints.rows(), 1) = point2;
62
63 // calculate weight
64 fWeight = 1.0f / (2 * (nNumberDimensions + fLamda));
65 w_m(2 * i + 1) = fWeight;
66 w_m(2 * i + 2) = fWeight;
67 w_c(2 * i + 1) = fWeight;
68 w_c(2 * i + 2) = fWeight;
69 }
70
71 m_weights_m = w_m;
72 m_weights_c = w_c;
73
74 return sigmaPoints;
75}
76
78UnscentedTransform::extractGaussian(Eigen::MatrixXd processedSigmaPoints)
79{
80 Gaussian result(processedSigmaPoints.rows());
81
82 // assemble mean
83 for (int i = 0; i < m_weights_c.rows(); i++)
84 {
85 result.setMean(result.getMean() +
86 m_weights_m(i) *
87 processedSigmaPoints.block(0, i, processedSigmaPoints.rows(), 1));
88 }
89
90 // assemble cov
91 Eigen::MatrixXd cov = result.getCovariance();
92 cov.setIdentity();
93 result.setCovariance(cov);
94
95 for (int i = 0; i < m_weights_c.rows(); i++)
96 {
97 result.setCovariance(
98 result.getCovariance() +
99 m_weights_c(i) * ((processedSigmaPoints.block(0, i, processedSigmaPoints.rows(), 1) -
100 result.getMean()) *
101 ((processedSigmaPoints.block(0, i, processedSigmaPoints.rows(), 1) -
102 result.getMean())
103 .transpose())));
104 }
105
106 return result;
107}
108
109Eigen::MatrixXd
110UnscentedTransform::squareRoot(Eigen::MatrixXd input)
111{
112 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(input);
113
114 Eigen::MatrixXd sqrtA = es.operatorSqrt();
115
116 return sqrtA;
117}
const covariance_type & getCovariance() const
Definition Gaussian.h:82
int getDimensions() const
Definition Gaussian.h:94
void setCovariance(const covariance_type &cov)
Definition Gaussian.cpp:272
void setMean(const value_type &mean)
Definition Gaussian.cpp:255
const value_type & getMean() const
Definition Gaussian.h:88
Gaussian extractGaussian(Eigen::MatrixXd processedSigmaPoints)
UnscentedTransform(float fAlpha=0.1, float fKappa=0.0f, float fBeta=2.0f)
Eigen::MatrixXd getSigmaPoints(const Gaussian &gaussian)