/* * ===================================================================================== * * Filename: state.cpp * * Description: A Class for managing body and features. * * Version: 1.0 * Created: 03/17/2017 07:55:56 PM * Revision: none * Compiler: gcc * * Author: Martin Miller (MHM), miller7@illinois.edu * Organization: Aerospace Robotics and Controls Lab (ARC) * * ===================================================================================== */ #include "state.h" State::State ( ) { body = new Body; P = Matrix::Zero(9,9); P.block(6,6,3,3) = 1e-6*Matrix3d::Identity(); return ; } /* ----- end of method State::State ----- */ void State::vel ( const Matrix &v ) { body->vel(v); return ; } /* ----- end of method State::vel ----- */ void State::enu ( const UTM &utm ) { utm_c = utm.zone_c; utm_i = utm.zone_i; body->enu(utm); return ; } /* ----- end of method State::enu ----- */ void State::update ( const Matrix &z ) { Matrix H; H=body->H(); Matrix S; S=body->S(P); Matrix K; K = P*H.transpose()*S.inverse(); P = (Matrix::Identity()-K*H)*P; P = 0.5*(P+P.transpose()); Matrix dx; Matrix h; h = body->h(); dx = K*(z-h); body->update(dx); } void State::feature_update ( const std::vector &z, const Quaterniond &q) { std::vector featuresToAdd; for (auto i=z.begin(); i!=z.end(); ++i) { if (exists(i->id)) { ; } else { featuresToAdd.push_back(*i); } } addFeatures( featuresToAdd, q); return ; } /* ----- end of method State::feature_update ----- */ void State::addFeatures ( std::vector &F, const Quaterniond &q) { // Expand P matrix all at once expandP(F.size()); // // Add new features for (auto i=F.begin(); i!=F.end(); ++i) { // Estimate initial depth Vector3d xib; // Create feature Feature *f = new Feature(i->id, i->source, i->reflection, body->ned(), q, -0.44); features.push_back(f); // Initialize P values int j=features.size(); Matrix Pi; Pi = f->P0(); initializePi(j,Pi); } return ; } /* ----- end of method State::addFeatures ----- */ /* *-------------------------------------------------------------------------------------- * Class: State * Method: State :: initializePi * Description: Zeros out the off-diagonal blocks and sets the Pii block to Pi. *-------------------------------------------------------------------------------------- */ void State::initializePi ( int i, const Matrix &Pi ) { int pt=9+3*(i-1); std::cout << pt << std::endl; std::cout << P.cols() << std::endl; P.block(pt,0,3,P.cols()) = MatrixXd::Zero(3,P.cols()); P.block(0,pt,P.rows(),3) = MatrixXd::Zero(P.rows(),3); P.block<3,3>(pt,pt) = Pi; return ; } /* ----- end of method State::initializePi ----- */ /* *-------------------------------------------------------------------------------------- * Class: State * Method: State :: Q * Description: Compose full Q from body and features. *-------------------------------------------------------------------------------------- */ MatrixXd State::Q ( double dt ) { MatrixXd q; int rows = 9 + 3*features.size(); q = MatrixXd::Zero(rows,rows); q.topLeftCorner<9,9>() = body->Q(dt); { // limit i's scope auto i = features.begin(); for (int row=9; row(row,row) = (*i)->Q(dt); } } return q; } /* ----- end of method State::q ----- */ /* *-------------------------------------------------------------------------------------- * Class: State * Method: State :: F * Description: Compose full F from body and features *-------------------------------------------------------------------------------------- */ MatrixXd State::F ( const Quaterniond &q, const Vector3d &w, double dt ) { Vector3d v; v = body->vel(); // Allocate matrix F MatrixXd f; int rows = 9 + 3*features.size(); f = MatrixXd::Zero(rows,rows); // Set body F f.topLeftCorner<9,9>() = body->F(w,q,dt); // Set Fxi Fyi { // limit i's scope auto i = features.begin(); for (int row=9; row(row,0) = (*i)->Fx(dt); f.block<3,3>(row,row) = (*i)->Fy(v,w,dt); } } return f ; } /* ----- end of method State::F ----- */ /* *-------------------------------------------------------------------------------------- * Class: State * Method: State :: Pkk1 * Description: Updates P_k|k-1 *-------------------------------------------------------------------------------------- */ void State::Pkk1 ( const Vector3d &ang, const Quaterniond &q, const double dt) { MatrixXd f,fullQ; fullQ = Q(dt); f = F ( q, ang, dt ); P = f*P*f.transpose()+fullQ; // Enforce symmetry P = 0.5*(P+P.transpose()); return ; } /* ----- end of method State::Pkk1 ----- */ void State::motionModel ( const Vector3d &acc, const Vector3d &ang, const Quaterniond &q, const double dt) { Pkk1(ang,q,dt); body->motionModel(acc,ang,q,dt); return ; } /* ----- end of method State::motionModel ----- */ void State::position_covariance ( const Matrix &p ) { P.block(0,0,3,3) = p; return ; } /* ----- end of method State::position_covariance ----- */ void State::velocity_covariance ( const Matrix &p ) { P.block(3,3,3,3) = p; return ; } /* ----- end of method State::velocity_covariance ----- */ void State::unicsv ( ) { body->unicsv(); return ; } /* ----- end of method State::unicsv ----- */ void State::accelerometer_bias ( const Vector3d &b) { body->accelerometer_bias(b); return ; } /* ----- end of method State::accelerometer_bias ----- */ /* *-------------------------------------------------------------------------------------- * Class: State * Method: State :: exists * Description: Tests if the id is a current feature. *-------------------------------------------------------------------------------------- */ bool State::exists ( int id ) { for (auto i=features.begin(); i!=features.end(); ++i) { if ((*i)->id()==id) return true; } return false; } /* ----- end of method State::exists ----- */ /* *-------------------------------------------------------------------------------------- * Class: State * Method: State :: expandP * Description: Grows P so that Nnew new features can be added. This could mean * explicitly resizing the P matrix or P being a block of a preallocated matrix. *-------------------------------------------------------------------------------------- */ void State::expandP ( int Nnew ) { int curRows, newRows; curRows = P.rows(); newRows = curRows + 3*Nnew; P.conservativeResize(newRows,newRows); return ; } /* ----- end of method State::expandP ----- */