154class MultiSensorEKF :
public KalmanFilterBase<stateDim, inputDim> {
156 using state_t = navtypes::Vectord<stateDim>;
157 using input_t = navtypes::Vectord<inputDim>;
158 using processnoise_t = navtypes::Vectord<processNoiseDim>;
161 std::function<state_t(
const state_t&,
const input_t&,
const processnoise_t&)>;
164 const statefunc_t& stateFunc,
167 : stateFunc(stateFunc), Q(processNoise), dt(dt), outputs(outputs) {}
169 void predict(
const input_t& input)
override {
170 navtypes::Matrixd<stateDim, stateDim> F = stateFuncJacobianX(this->xHat, input);
171 navtypes::Matrixd<processNoiseDim, processNoiseDim> processNoise =
172 Q.
get(this->xHat, input);
174 navtypes::Matrixd<stateDim, processNoiseDim> L = stateFuncJacobianW(this->xHat, input);
176 this->xHat = stateFunc(this->xHat, input, processnoise_t::Zero());
177 this->P = F * this->P * F.transpose() + L * processNoise * L.transpose();
180 void correct(
int outputIdx,
const Eigen::VectorXd& measurement) {
181 Output& output = outputs[outputIdx];
184 Eigen::MatrixXd outputNoise = output.covMat.get(this->xHat, measurement);
186 Eigen::MatrixXd S = H * this->P * H.transpose() +
187 M * outputNoise * M.transpose();
190 S.
transpose().colPivHouseholderQr().solve(H * this->P.transpose()).transpose();
193 output.outputFunc(this->xHat, Eigen::VectorXd::Zero(
194 output.outputNoiseDim));
196 this->xHat = this->xHat + K * y;
200 template <
int outputIdx>
201 void correct(
const Eigen::VectorXd& measurement) {
202 static_assert(0 <= outputIdx && outputIdx < numOutputs);
203 correct(outputIdx, measurement);
206 void setStateFuncJacobianX(
207 const std::function<navtypes::Matrixd<stateDim, stateDim>(
208 const state_t&,
const input_t&,
const processnoise_t&)>& stateFuncJacobianX) {
209 this->stateFuncJacobianXSol = stateFuncJacobianX;
212 void setStateFuncJacobianW(
213 const std::function<navtypes::Matrixd<stateDim, processNoiseDim>(
214 const state_t&,
const input_t&,
const processnoise_t&)>& stateFuncJacobianW) {
215 this->stateFuncJacobianWSol = stateFuncJacobianW;
218 navtypes::Matrixd<stateDim, stateDim> stateFuncJacobianX(
const state_t& x,
220 processnoise_t w = processnoise_t::Zero();
221 if (stateFuncJacobianXSol) {
222 return stateFuncJacobianXSol(x, u, w);
224 auto func = [&](
const state_t& state) {
return stateFunc(state, u, w); };
229 navtypes::Matrixd<stateDim, processNoiseDim> stateFuncJacobianW(
const state_t& x,
231 processnoise_t w = processnoise_t::Zero();
232 if (stateFuncJacobianWSol) {
233 return stateFuncJacobianWSol(x, u, w);
235 auto func = [&](
const processnoise_t& noise) {
return stateFunc(x, u, noise); };
241 statefunc_t stateFunc;
246 std::function<navtypes::Matrixd<stateDim, stateDim>(
const state_t&,
const input_t&,
247 const processnoise_t&)>
248 stateFuncJacobianXSol;
250 std::function<navtypes::Matrixd<stateDim, processNoiseDim>(
const state_t&,
const input_t&,
251 const processnoise_t&)>
252 stateFuncJacobianWSol;
Output(int stateDim, int outputDim, int outputNoiseDim, const outputfunc_t &outputFunc, const statespace::NoiseCovMatX &covMat)
Create an output for a model.
Definition MultiSensorEKF.h:44
Eigen::Matrix< double, size, size > get(const state_t &x, const param_t ¶m)
Gets the noise covariance matrix, given the current state and additonal parameter.
Definition StateSpaceUtil.h:298