magnetic.cpp
Go to the documentation of this file.
1 //=================================================================================================
2 // Copyright (c) 2011, Johannes Meyer, TU Darmstadt
3 // All rights reserved.
4 
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
12 // * Neither the name of the Flight Systems and Automatic Control group,
13 // TU Darmstadt, nor the names of its contributors may be used to
14 // endorse or promote products derived from this software without
15 // specific prior written permission.
16 
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //=================================================================================================
28 
31 
32 #include <Eigen/Geometry>
33 
34 namespace hector_pose_estimation {
35 
36 template class Measurement_<MagneticModel>;
37 
39  : declination_(0.0), inclination_(60.0 * M_PI/180.0), magnitude_(0.0)
40 {
41  parameters().add("stddev", stddev_, 1.0);
42  parameters().add("declination", declination_);
43  parameters().add("inclination", inclination_);
44  parameters().add("magnitude", magnitude_);
45 }
46 
48 
49 bool MagneticModel::init(PoseEstimation &estimator, Measurement &measurement, State &state)
50 {
52  return true;
53 }
54 
55 void MagneticModel::setReference(const GlobalReference::Heading &reference_heading) {
56  magnetic_field_reference_.x() = reference_heading.cos * magnetic_field_north_.x() - reference_heading.sin * magnetic_field_north_.y();
57  magnetic_field_reference_.y() = reference_heading.sin * magnetic_field_north_.x() + reference_heading.cos * magnetic_field_north_.y();
59 }
60 
61 void MagneticModel::getMeasurementNoise(NoiseVariance& R, const State&, bool init)
62 {
63  if (init) {
64  R(0,0) = R(1,1) = R(2,2) = pow(stddev_, 2);
65  }
66 }
67 
68 void MagneticModel::getExpectedValue(MeasurementVector& y_pred, const State& state)
69 {
70  const State::RotationMatrix &R = state.R();
71  y_pred = R.transpose() * magnetic_field_reference_;
72 }
73 
74 void MagneticModel::getStateJacobian(MeasurementMatrix& C, const State& state, bool)
75 {
76  if (state.orientation()) {
77  const State::RotationMatrix &R = state.R();
78  state.orientation()->cols(C)(X,Z) = R(0,0) * magnetic_field_reference_.y() - R(1,0) * magnetic_field_reference_.x();
79  state.orientation()->cols(C)(Y,Z) = R(0,1) * magnetic_field_reference_.y() - R(1,1) * magnetic_field_reference_.x();
80  state.orientation()->cols(C)(Z,Z) = R(0,2) * magnetic_field_reference_.y() - R(1,2) * magnetic_field_reference_.x();
81  }
82 }
83 
84 double MagneticModel::getMagneticHeading(const State& state, const MeasurementVector &y) const {
85  MeasurementVector y_nav;
86  y_nav = state.R() * y;
87  return atan2(y_nav.y(), y_nav.x()) - state.getYaw();
88 }
89 
90 double MagneticModel::getTrueHeading(const State& state, const MeasurementVector &y) const {
91  return getMagneticHeading(state, y) + declination_;
92 }
93 
95 {
96  double cos_inclination, sin_inclination;
97  sincos(inclination_, &sin_inclination, &cos_inclination);
98 
99  double cos_declination, sin_declination;
100  sincos(declination_, &sin_declination, &cos_declination);
101 
102  // return normalized magnetic field if magnitude is zero
103  double magnitude = magnitude_;
104  if (magnitude == 0.0) magnitude = 1.0;
105 
106  magnetic_field_north_.x() = magnitude * (cos_inclination * cos_declination);
107  magnetic_field_north_.y() = magnitude * (cos_inclination * (-sin_declination));
108  magnetic_field_north_.z() = magnitude * (-sin_inclination);
109 }
110 
111 Magnetic::Magnetic(const std::string &name)
112  : Measurement_<MagneticModel>(name)
113  , auto_heading_(true)
114  , deviation_(3)
115 {
116  deviation_.setZero();
117  parameters().add("auto_heading", auto_heading_);
118  parameters().add("deviation", deviation_);
119 }
120 
122  reference_.reset();
123 }
124 
125 const MagneticModel::MeasurementVector& Magnetic::getVector(const Magnetic::Update& update, const State& state) {
127  if (getModel()->hasMagnitude()) return y_;
128 
129  double norm = y_.norm();
130  if (norm < 1e-5) {
131  y_.setZero();
132  } else {
133  y_ = y_ / norm;
134  }
135  return y_;
136 }
137 
138 //const MagneticModel::NoiseVariance& Magnetic::getVariance(const Magnetic::Update& update, const State& state) {
139 // if (getModel()->hasMagnitude()) return Measurement_<MagneticModel>::getVariance(update, state);
140 
141 // R_ = Measurement_<MagneticModel>::getVariance(update, state);
142 // double norm = Measurement_<MagneticModel>::getVector(update, state).norm();
143 // if (norm < 1e-5) {
144 // R_ = NoiseVariance(1.0, 1.0, 1.0);
145 // } else {
146 // R_ = R_ / (norm*norm);
147 // }
148 // return R_;
149 //}
150 
152  // reset reference position if Magnetic has not been updated for a while
153  if (timedout()) reference_.reset();
154 
157  if (auto_heading_) reference_->setCurrentHeading(state, getModel()->getTrueHeading(state, update.getVector()));
158  }
159 
160  getModel()->setReference(reference_->heading());
161  return true;
162 }
163 
164 } // namespace hector_pose_estimation
virtual void getMeasurementNoise(NoiseVariance &R, const State &, bool init)
Definition: magnetic.cpp:61
Magnetic(const std::string &name="height")
Definition: magnetic.cpp:111
virtual bool update(const MeasurementUpdate &update)
virtual const boost::shared_ptr< OrientationStateType > & orientation() const
Definition: state.h:112
virtual MeasurementVector const & getVector(const Update &update, const State &)
Definition: magnetic.cpp:125
Matrix_< 3, 3 >::type RotationMatrix
Definition: state.h:71
virtual void getExpectedValue(MeasurementVector &y_pred, const State &state)
Definition: magnetic.cpp:68
static const GlobalReferencePtr & Instance()
const State::RotationMatrix & R() const
Definition: state.cpp:131
virtual ParameterList & parameters()
Definition: measurement.h:63
virtual bool prepareUpdate(State &state, const Update &update)
Definition: magnetic.cpp:151
ParameterList & add(const std::string &key, T &value, const T &default_value)
Definition: parameters.h:148
ParameterList & parameters()
Definition: model.h:47
double getMagneticHeading(const State &state, const MeasurementVector &y) const
Definition: magnetic.cpp:84
virtual bool init(PoseEstimation &estimator, Measurement &measurement, State &state)
Definition: magnetic.cpp:49
GlobalReferencePtr reference_
Definition: magnetic.h:93
virtual Vector const & getVector() const
virtual void getStateJacobian(MeasurementMatrix &C, const State &state, bool init)
Definition: magnetic.cpp:74
double getYaw() const
Definition: state.cpp:139
MeasurementVector magnetic_field_north_
Definition: magnetic.h:63
EIGEN_MAKE_ALIGNED_OPERATOR_NEW MagneticModel()
Definition: magnetic.cpp:38
void setReference(const GlobalReference::Heading &reference_heading)
Definition: magnetic.cpp:55
MeasurementVector magnetic_field_reference_
Definition: magnetic.h:64
double getTrueHeading(const State &state, const MeasurementVector &y) const
Definition: magnetic.cpp:90
virtual MeasurementVector const & getVector(const Update &update, const State &state)
Definition: measurement.h:154


hector_pose_estimation_core
Author(s): Johannes Meyer
autogenerated on Thu Feb 18 2021 03:29:30