PlatformKalmanFilter.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2017, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarX
19 * @author Mirko Waechter( mirko.waechter at kit dot edu)
20 * @date 2018
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
25
27
28namespace memoryx
29{
30
31 PlatformKalmanFilter::PlatformKalmanFilter(Eigen::Vector2d initialPosition,
32 double initialRotation,
33 double translationSensorStdDev,
34 double rotationSensorStdDev,
35 double translationVelocitySensorStdDev,
36 double rotationVelocitySensorStdDev)
37 {
38 pose.head(2) = initialPosition;
39 pose(2) = initialRotation;
40 Eigen::Vector4d motionNoiseCov;
41 motionNoiseCov << translationVelocitySensorStdDev * translationVelocitySensorStdDev,
42 translationVelocitySensorStdDev * translationVelocitySensorStdDev,
43 rotationVelocitySensorStdDev * rotationVelocitySensorStdDev,
44 rotationVelocitySensorStdDev * rotationVelocitySensorStdDev;
45 motionNoise = Gaussian(Eigen::Vector4d::Zero(), motionNoiseCov.asDiagonal());
46 filter.setMotionModel(
47 Eigen::Matrix4d::Identity(), Eigen::Matrix4d::Identity(), motionNoise);
48
49 Eigen::Vector4d measurementNoiseCov;
50 measurementNoiseCov << translationSensorStdDev * translationSensorStdDev,
51 translationSensorStdDev * translationSensorStdDev,
52 rotationSensorStdDev * rotationSensorStdDev,
53 rotationSensorStdDev * rotationSensorStdDev;
54 Gaussian measurementNoise(Eigen::Vector4d::Zero(), measurementNoiseCov.asDiagonal());
55 filter.setMeasurementModel(Eigen::Matrix4d::Identity(), measurementNoise);
56
57 Eigen::Vector4d pose2d = transformPose(pose);
58
59 state = Gaussian(4);
60 state.setMean(pose2d);
61 state.setCovariance(Eigen::Vector4d(translationSensorStdDev * translationSensorStdDev * 10,
62 translationSensorStdDev * translationSensorStdDev * 10,
63 rotationSensorStdDev * rotationSensorStdDev * 10,
64 rotationSensorStdDev * rotationSensorStdDev * 10)
65 .asDiagonal());
66 }
67
68 void
70 double velY,
71 double velTheta,
72 const IceUtil::Time& deltaT)
73 {
74 Eigen::Matrix2d rotation = Eigen::Rotation2Dd(pose(2)).matrix();
75 Eigen::Vector2d globalV0 = rotation * Eigen::Vector2d(velX, velY);
76 Eigen::Vector4d currentVelocity;
77 currentVelocity << globalV0(0), globalV0(1), -velTheta * sin(pose(2)),
78 velTheta * cos(pose(2));
79
80
81 auto posDelta = currentVelocity * deltaT.toSecondsDouble();
82
83 // scale motion noise with velocity
84 Eigen::MatrixXd adjustedMotionNoiseCov =
85 motionNoise.getCovariance() * Eigen::Vector4d(std::abs(currentVelocity(0)),
86 std::abs(currentVelocity(1)),
87 std::abs(velTheta),
88 std::abs(velTheta))
89 .asDiagonal();
90
91 Gaussian adjustedMotionNoise(Eigen::Vector4d::Zero(), adjustedMotionNoiseCov);
92 filter.setMotionModel(
93 Eigen::Matrix4d::Identity(), Eigen::Matrix4d::Identity(), adjustedMotionNoise);
94
95
96 state = filter.predict(state, posDelta);
97 pose = inverseTransformPose(state.getMean());
98 }
99
100 void
101 PlatformKalmanFilter::update(double x, double y, double alpha)
102 {
103 Eigen::Vector4d pose2d = transformPose(Eigen::Vector3d(x, y, alpha));
104
105
106 state = filter.update(state, pose2d);
107
108 pose = inverseTransformPose(state.getMean());
109 }
110
111 const Eigen::Vector3d&
113 {
114 return pose;
115 }
116
117 Eigen::Vector2d
119 {
120 return pose.head<2>();
121 }
122
123 double
125 {
126 return pose(2);
127 }
128
129 Eigen::Matrix3d
131 {
132 Eigen::Matrix3d result;
133 result.block<2, 2>(0, 0) = state.getCovariance().block<2, 2>(0, 0);
134 result(2, 2) = (state.getCovariance()(2, 2) + state.getCovariance()(3, 3)) * 0.5;
135 return result;
136 }
137
138 const KalmanFilter&
140 {
141 return filter;
142 }
143
144 void
146 {
147 filter = value;
148 }
149
150 Eigen::Vector4d
151 PlatformKalmanFilter::transformPose(const Eigen::Vector3d& pose) const
152 {
153 Eigen::Vector4d pose2d;
154 // rotation stored for Mean_of_circular_quantities
155 // http://en.wikipedia.org/wiki/Mean_of_circular_quantities
156 pose2d << pose(0), pose(1), cos(pose(2)), sin(pose(2));
157 return pose2d;
158 }
159
160 Eigen::Vector3d
162 {
163 Eigen::Matrix3d ori;
164 ori.setIdentity();
165
166 double angle = atan2(pose(3), pose(2));
167 ori = Eigen::AngleAxisd(angle, Eigen::Vector3d::UnitZ());
168 Eigen::Vector3d result;
169 result[0] = pose(0);
170 result[1] = pose(1);
171 result[2] = angle;
172 return result;
173 }
174
175} // namespace memoryx
Eigen::Vector3d inverseTransformPose(const Eigen::Vector4d &pose) const
const KalmanFilter & getFilter() const
Eigen::Vector4d transformPose(const Eigen::Vector3d &pose) const
void predict(double velX, double velY, double velTheta, const IceUtil::Time &deltaT)
Performs the predict-step of the Kalman filter.
PlatformKalmanFilter(Eigen::Vector2d initialPosition, double initialRotation, double translationSensorStdDev=100.0, double rotationSensorStdDev=0.1, double translationVelocitySensorStdDev=1., double rotationVelocitySensorStdDev=1.)
PlatformKalmanFilter.
const Eigen::Vector3d & getPose() const
Global pose of the holonomic platform.
void setFilter(const KalmanFilter &value)
Change the internal Kalman Filter.
void update(double x, double y, double alpha)
Performs the update-step of the Kalman filter.
Eigen::Matrix3d getCovariance() const
Covariance matrix of the current belief of the state.
This file offers overloads of toIce() and fromIce() functions for STL container types.
VirtualRobot headers.
double angle(const Point &a, const Point &b, const Point &c)
Definition point.hpp:109