Example #1
0
double weight_gaussian_predictive_rev(Gaussian &g1, Gaussian &g2)
{
    int dim = g1.dim;
    double energy1 = 0.;
            Eigen::MatrixXd cov = g1.predictive_covariance + g1.predictive_covariance;
            Eigen::VectorXd mean = g1.predictive_mean - g1.predictive_mean;
            Eigen::MatrixXd invij = cov.inverse();
            double a = mean.transpose()*invij*mean;
            double gauss = 1./sqrt(pow(2*pi,dim)*cov.determinant())*exp(-0.5*a);
            energy1 += gauss;

    double energy2 = 0.;

            cov = g1.predictive_covariance + g2.predictive_covariance;
            mean = g1.predictive_mean - g2.predictive_mean;
            invij = cov.inverse();
            a = mean.transpose()*invij*mean;
            gauss = 1./sqrt(pow(2*pi,dim)*cov.determinant())*exp(-0.5*a);
            energy2 += gauss;

    double energy3 = 0.;
            cov = g2.predictive_covariance + g2.predictive_covariance;
            mean = g2.predictive_mean - g2.predictive_mean;
            invij = cov.inverse();
            a = mean.transpose()*invij*mean;
            gauss = 1./sqrt(pow(2*pi,dim)*cov.determinant())*exp(-0.5*a);
            energy3 += gauss;
//    cout<<(maxDist - (energy1 - 2*energy2 + energy3))/maxDist<<endl;
    return energy1 - 2*energy2 + energy3;

}
Example #2
0
double weight_l2_rev(PCObject &o1, PCObject &o2)
{
    double last = pcl::getTime ();
    // reference :
    // Robust Point Set Registration Using Gaussian Mixture Models
    // Bing Jina, and Baba C. Vemuri
    // IEEE Transactions on Pattern Analysis and Machine Intelligence 2010
    int n = o1.gmm.size();
    int m = o2.gmm.size();

    double energy1 = 0.;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            int dim = o1.gmm.at(i).dim;
            Eigen::MatrixXd cov = o1.gmm.at(i).covariance + o1.gmm.at(j).covariance;
            Eigen::VectorXd mean = o1.gmm.at(i).mean - o1.gmm.at(j).mean;
            Eigen::MatrixXd invij = cov.inverse();
            double a = mean.transpose()*invij*mean;
            double gauss = 1./sqrt(pow(2*pi,dim)*cov.determinant())*exp(-0.5*a);
            energy1 += o1.gmm.at(i).weight*o1.gmm.at(j).weight*gauss;
        }
    }
    double energy2 = 0.;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            int dim = o1.gmm.at(i).dim;
            Eigen::MatrixXd cov = o1.gmm.at(i).covariance + o2.gmm.at(j).covariance;
            Eigen::VectorXd mean = o1.gmm.at(i).mean - o2.gmm.at(j).mean;
            Eigen::MatrixXd invij = cov.inverse();
            double a = mean.transpose()*invij*mean;
            double gauss = 1./sqrt(pow(2*pi,dim)*cov.determinant())*exp(-0.5*a);
            energy2 += o1.gmm.at(i).weight*o2.gmm.at(j).weight*gauss;
        }
    }
    double energy3 = 0.;
    for(int i=0;i<m;i++){
        for(int j=0;j<m;j++){
            int dim = o2.gmm.at(i).dim;
            Eigen::MatrixXd cov = o2.gmm.at(i).covariance + o2.gmm.at(j).covariance;
            Eigen::VectorXd mean = o2.gmm.at(i).mean - o2.gmm.at(j).mean;
            Eigen::MatrixXd invij = cov.inverse();
            double a = mean.transpose()*invij*mean;
            double gauss = 1./sqrt(pow(2*pi,dim)*cov.determinant())*exp(-0.5*a);
            energy3 += o2.gmm.at(i).weight*o2.gmm.at(j).weight*gauss;
        }
    }
    double now = pcl::getTime ();
//    cout << "l2-distance time " << now-last << " second" << endl;
    //    cout<<"l2distance"<<energy1 - 2*energy2 + energy3<<endl;

    return (energy1 - 2*energy2 + energy3);
}
Example #3
0
void Assembler2D::precomputeShapeFunctionDerivatives() {
    Eigen::MatrixXd selector = Eigen::MatrixXd::Zero(3,2);
    selector << 0.0, 0.0,
             1.0, 0.0,
             0.0, 1.0;

    m_DN.resize(m_mesh->getNbrElements());
    for (size_t i=0; i<m_mesh->getNbrElements(); ++i)
    {
        VectorI idx = m_mesh->getElement(i);
        assert(idx.size() == 3);
        VectorF u[3];
        u[0] = m_mesh->getNode(idx[0]);
        u[1] = m_mesh->getNode(idx[1]);
        u[2] = m_mesh->getNode(idx[2]);

        Eigen::MatrixXd P = Eigen::MatrixXd::Zero(3,3);
        P <<     1.0,     1.0,     1.0,
        u[0][0], u[1][0], u[2][0],
        u[0][1], u[1][1], u[2][1];

        // DN is a 4x3 matrix containing the gradients of the
        // 4 shape functions (one for each node)
        //
        m_DN[i] = P.inverse() * selector /* * -1.0 */;
    }
}
Example #4
0
void benchmark( )
{
    for (size_t i = 1; i < 12; i++) 
    {
        const size_t N = (size_t)pow(2, i);
        Eigen::MatrixXd m = MatrixXd::Random(N, N);

        clock_t t0 = clock();
        auto mInv = m.inverse();
        clock_t t1 = clock();
        double eigenT = (double)(t1-t0)/CLOCKS_PER_SEC;

        t0 = clock();
        auto m1 = m;
        invert( m1 );
        t1 = clock();

        if( (m1-mInv).norm() > 1e-6 )
        {
            cout << "Got " << endl << m1 << endl;
            cout << "Expected " << endl << mInv << endl;
            cout << "Original matrix was " << endl << m << endl;
            cout<< "Error : " << endl << (m1 - mInv).norm() << endl;
            throw;
        }

        cout << N << ' ' << (double)(t1-t0) / CLOCKS_PER_SEC <<  ' ' << eigenT << endl;
    }

}
// Convert joint torques to end effector force/torque
void computeFT(Eigen::VectorXd& ee_ft) {
	Eigen::MatrixXd jac;
	mRobot->getJacobian(jac);
	Eigen::MatrixXd trans = jac*jac.transpose() + singular_tol*Eigen::MatrixXd::Identity(jac.rows(), jac.rows());
	// f = inv(J*J')*J*tau
	ee_ft = (trans.inverse()*jac)*read_torque;
}
Example #6
0
void IEFSolver::buildIsotropicMatrix(const Cavity & cav, const IGreensFunction & gf_i, const IGreensFunction & gf_o)
{
    // The total size of the cavity
    size_t cavitySize = cav.size();
    // The number of irreps in the group
    int nrBlocks = cav.pointGroup().nrIrrep();
    // The size of the irreducible portion of the cavity
    int dimBlock = cav.irreducible_size();

    // Compute SI and DI on the whole cavity, regardless of symmetry
    Eigen::MatrixXd SI = gf_i.singleLayer(cav.elements());
    Eigen::MatrixXd DI = gf_i.doubleLayer(cav.elements());

    // Perform symmetry blocking
    // If the group is C1 avoid symmetry blocking, we will just pack the fullPCMMatrix
    // into "block diagonal" when all other manipulations are done.
    if (cav.pointGroup().nrGenerators() != 0) {
        symmetryBlocking(DI, cavitySize, dimBlock, nrBlocks);
        symmetryBlocking(SI, cavitySize, dimBlock, nrBlocks);
    }

    Eigen::MatrixXd a = cav.elementArea().asDiagonal();
    Eigen::MatrixXd aInv = Eigen::MatrixXd::Zero(cavitySize, cavitySize);
    aInv = a.inverse();

    // Tq = -Rv -> q = -(T^-1 * R)v = -Kv
    // T = (2 * M_PI * fact * aInv - DI) * a * SI; R = (2 * M_PI * aInv - DI)
    // fullPCMMatrix_ = K = T^-1 * R * a
    // 1. Form T
    double epsilon = profiles::epsilon(gf_o.permittivity());
    double fact = (epsilon + 1.0)/(epsilon - 1.0);
    fullPCMMatrix_ = (2 * M_PI * fact * aInv - DI) * a * SI;
    // 2. Invert T using LU decomposition with full pivoting
    //    This is a rank-revealing LU decomposition, this allows us
    //    to test if T is invertible before attempting to invert it.
    Eigen::FullPivLU<Eigen::MatrixXd> T_LU(fullPCMMatrix_);
    if (!(T_LU.isInvertible()))
        PCMSOLVER_ERROR("T matrix is not invertible!");
    fullPCMMatrix_ = T_LU.inverse();
    // 3. Multiply T^-1 and R
    fullPCMMatrix_ *= (2 * M_PI * aInv - DI);
    // 4. Multiply by a
    fullPCMMatrix_ *= a;
    // 5. Symmetrize K := (K + K+)/2
    if (hermitivitize_) {
        hermitivitize(fullPCMMatrix_);
    }
    // Pack into a block diagonal matrix
    // For the moment just packs into a std::vector<Eigen::MatrixXd>
    symmetryPacking(blockPCMMatrix_, fullPCMMatrix_, dimBlock, nrBlocks);
    std::ofstream matrixOut("PCM_matrix");
    matrixOut << "fullPCMMatrix" << std::endl;
    matrixOut << fullPCMMatrix_ << std::endl;
    for (int i = 0; i < nrBlocks; ++i) {
        matrixOut << "Block number " << i << std::endl;
        matrixOut << blockPCMMatrix_[i] << std::endl;
    }

    built_ = true;
}
Example #7
0
void MSF_MeasurementBase<EKFState_T>::calculateAndApplyCorrection(
    shared_ptr<EKFState_T> state, MSF_Core<EKFState_T>& core,
    const Eigen::MatrixXd& H_delayed, const Eigen::MatrixXd & res_delayed,
    const Eigen::MatrixXd& R_delayed) {

  // Get measurements.
  /// Correction from EKF update.
  Eigen::Matrix<double, MSF_Core<EKFState_T>::nErrorStatesAtCompileTime, 1> correction_;

  Eigen::MatrixXd S;
  Eigen::MatrixXd K(
      static_cast<int>(MSF_Core<EKFState_T>::nErrorStatesAtCompileTime),
      R_delayed.rows());
  typename MSF_Core<EKFState_T>::ErrorStateCov & P = state->P;

  S = H_delayed * P * H_delayed.transpose() + R_delayed;
  K = P * H_delayed.transpose() * S.inverse();

  correction_ = K * res_delayed;
  const typename MSF_Core<EKFState_T>::ErrorStateCov KH =
      (MSF_Core<EKFState_T>::ErrorStateCov::Identity() - K * H_delayed);
  P = KH * P * KH.transpose() + K * R_delayed * K.transpose();

  // Make sure P stays symmetric.
  P = 0.5 * (P + P.transpose());

  core.applyCorrection(state, correction_);
}
double* simulatePlant(double *state_vect, double *input_vect, double *state_op_vect, double sampling_time)
{
	double input_op_vect[4] = {0.0, 0.0, 0.0, 0.0};
	Eigen::Map<Eigen::VectorXd> x(state_vect, num_states_);
	Eigen::Map<Eigen::VectorXd> x_bar(state_op_vect, num_states_);
	Eigen::Map<Eigen::VectorXd> u(input_vect, num_inputs_);
	Eigen::Map<Eigen::VectorXd> u_bar(&input_op_vect[0], num_inputs_);
	
	Eigen::MatrixXd A = Eigen::MatrixXd::Identity(num_states_, num_states_);
	Eigen::MatrixXd B = Eigen::MatrixXd::Zero(num_states_, num_inputs_);
	
	Eigen::MatrixXd M = Eigen::MatrixXd::Zero(num_inputs_, num_inputs_);
	Eigen::VectorXd f_bar = Eigen::MatrixXd::Zero(num_inputs_, 1);
	
	double phi = x_bar(6);
	double theta = x_bar(7);
	double p = x_bar(9);
	double q = x_bar(10);
	double r = x_bar(11);
	
	M << 1., 1., 1., 1., 0., -1., 0., 1., 1., 0., -1., 0., -1., 1., -1., 1.;
	f_bar(0) = g_ * m_ / (Ct_ * cos(phi) * cos(theta));
	f_bar(1) = (Izz_ - Iyy_) * q * r / (Ct_ * d_);
	f_bar(2) = (Izz_ - Ixx_) * p * r / (Ct_ * d_);
	f_bar(3) = (Iyy_ - Ixx_) * p * q / Cq_;
	u_bar = M.inverse() * f_bar;
	u_bar = u_bar.cwiseSqrt();
	
	// Compute the matrices of the linear dynamic model	
	computeLTIModel(A, B, state_op_vect, input_op_vect);
	
	x = x_bar + A * (x - x_bar) + B * (u - u_bar);
		
	return state_vect;
}
Example #9
0
void IEFSolver::buildAnisotropicMatrix(const Cavity & cav, const IGreensFunction & gf_i, const IGreensFunction & gf_o)
{
    // The total size of the cavity
    size_t cavitySize = cav.size();
    // The number of irreps in the group
    int nrBlocks = cav.pointGroup().nrIrrep();
    // The size of the irreducible portion of the cavity
    int dimBlock = cav.irreducible_size();

    // Compute SI, DI and SE, DE on the whole cavity, regardless of symmetry
    Eigen::MatrixXd SI = gf_i.singleLayer(cav.elements());
    Eigen::MatrixXd DI = gf_i.doubleLayer(cav.elements());
    Eigen::MatrixXd SE = gf_o.singleLayer(cav.elements());
    Eigen::MatrixXd DE = gf_o.doubleLayer(cav.elements());

    // Perform symmetry blocking
    // If the group is C1 avoid symmetry blocking, we will just pack the fullPCMMatrix
    // into "block diagonal" when all other manipulations are done.
    if (cav.pointGroup().nrGenerators() != 0) {
        symmetryBlocking(DI, cavitySize, dimBlock, nrBlocks);
        symmetryBlocking(SI, cavitySize, dimBlock, nrBlocks);
        symmetryBlocking(DE, cavitySize, dimBlock, nrBlocks);
        symmetryBlocking(SE, cavitySize, dimBlock, nrBlocks);
    }

    Eigen::MatrixXd a = cav.elementArea().asDiagonal();
    Eigen::MatrixXd aInv = a.inverse();

    // 1. Form T
    fullPCMMatrix_ = ((2 * M_PI * aInv - DE) * a * SI + SE * a * (2 * M_PI * aInv + DI.adjoint().eval()));
    // 2. Invert T using LU decomposition with full pivoting
    //    This is a rank-revealing LU decomposition, this allows us
    //    to test if T is invertible before attempting to invert it.
    Eigen::FullPivLU<Eigen::MatrixXd> T_LU(fullPCMMatrix_);
    if (!(T_LU.isInvertible())) PCMSOLVER_ERROR("T matrix is not invertible!");
    fullPCMMatrix_ = T_LU.inverse();
    Eigen::FullPivLU<Eigen::MatrixXd> SI_LU(SI);
    if (!(SI_LU.isInvertible())) PCMSOLVER_ERROR("SI matrix is not invertible!");
    fullPCMMatrix_ *= ((2 * M_PI * aInv - DE) - SE * SI_LU.inverse() * (2 * M_PI * aInv - DI));
    fullPCMMatrix_ *= a;
    // 5. Symmetrize K := (K + K+)/2
    if (hermitivitize_) {
        hermitivitize(fullPCMMatrix_);
    }
    // Pack into a block diagonal matrix
    // For the moment just packs into a std::vector<Eigen::MatrixXd>
    symmetryPacking(blockPCMMatrix_, fullPCMMatrix_, dimBlock, nrBlocks);
    std::ofstream matrixOut("PCM_matrix");
    matrixOut << "fullPCMMatrix" << std::endl;
    matrixOut << fullPCMMatrix_ << std::endl;
    for (int i = 0; i < nrBlocks; ++i) {
        matrixOut << "Block number " << i << std::endl;
        matrixOut << blockPCMMatrix_[i] << std::endl;
    }

    built_ = true;
}
Example #10
0
void calc()
{
  Eigen::MatrixXd M_inv1 = M1.inverse();
  Eigen::MatrixXd M_inv2 = M2.inverse();
  Eigen::MatrixXd Jv1 = J1.block(0, 0, 3, J1.cols());
  Eigen::MatrixXd Jv2 = J2.block(0, 0, 3, J2.cols());
  Eigen::MatrixXd Lambda_inv1 = Jv1 * M_inv1 * Jv1.transpose();
  Eigen::MatrixXd Lambda_inv2 = Jv2 * M_inv2 * Jv2.transpose();
  Eigen::MatrixXd Lambda1 = Lambda_inv1.inverse();
  Eigen::MatrixXd Lambda2 = Lambda_inv2.inverse();
  Eigen::MatrixXd J_dyn_inv1 = M_inv1 * Jv1.transpose() * Lambda1;
  Eigen::MatrixXd J_dyn_inv2 = M_inv2 * Jv2.transpose() * Lambda2;
  Eigen::MatrixXd I = Eigen::MatrixXd::Identity(M_inv1.rows(), M_inv1.rows());
  Eigen::MatrixXd N1 = I - J_dyn_inv1 * Jv1;
  Eigen::MatrixXd N2 = I - J_dyn_inv2 * Jv2;

  //std::cout << N.transpose() << std::endl << std::endl;
}
Example #11
0
void PseudoInverse(const ::Eigen::MatrixXd& inputMatrix, ::Eigen::MatrixXd& outputMatrix, const ::Eigen::MatrixXd& weight)
{
	Eigen::MatrixXd tmp;
	if (weight.size() > 0)
		tmp = inputMatrix.transpose() * weight.transpose() * weight * inputMatrix;
	else
		tmp = inputMatrix * inputMatrix.transpose();
	tmp = tmp.inverse();
	outputMatrix =  inputMatrix.transpose() * tmp;

}
Example #12
0
double weight_l2_gauss(PCObject &o1, PCObject &o2)
{
    // l2 distance
    Eigen::MatrixXd covsum = o1.gaussian.covariance+o2.gaussian.covariance;
    Eigen::VectorXd meandiff = o1.gaussian.mean - o2.gaussian.mean;
    Eigen::MatrixXd inv = covsum.inverse();
    double det = covsum.determinant();
    double a = meandiff.transpose()*inv*meandiff;
    double l2 = 2.-2.*(1./sqrt(pow(2*pi,3)*det)) * exp(-0.5*a);
    if(l2 < 0) l2 = 0.;
    return l2;
}
Example #13
0
  double multivariateGaussianDensity(const Eigen::VectorXd& mean,
                                         const Eigen::MatrixXd& cov,
                                         const Eigen::VectorXd& z)
  {
    Eigen::VectorXd diff = mean - z;

    Eigen::VectorXd exponent = -0.5 * (diff.transpose() * cov.inverse() * diff);

    return pow(2 * M_PI, (double) z.size() / -2.0) * pow(cov.determinant(), -0.5) *
    exp(exponent(0));

  }
Example #14
0
void calc()
{
  //std::cout << "M : " << std::endl << M.inverse() << std::endl;
  //          << "J : " << std::endl << J << std::endl << std::endl;
  Eigen::MatrixXd M_inv = M.inverse();
  Eigen::MatrixXd Jv = J.block(0, 0, 3, J.cols());
  Eigen::MatrixXd Lambda_inv = Jv * M_inv * Jv.transpose();
  Eigen::MatrixXd Lambda = Lambda_inv.inverse();
  Eigen::MatrixXd J_dyn_inv = M_inv * Jv.transpose() * Lambda;
  Eigen::MatrixXd I = Eigen::MatrixXd::Identity(15, 15);
  Eigen::MatrixXd N = I - J_dyn_inv * Jv;

  //std::cout << N.transpose() << std::endl << std::endl;
}
Example #15
0
/**
 * @function Residual 
 */
void Residual( Eigen::MatrixXd _M, std::vector<Eigen::VectorXi> _points2D, 
                                   std::vector<Eigen::VectorXd> _points3D,
                                   std::vector<Eigen::VectorXd> _normPoints2D, 
                                   std::vector<Eigen::VectorXd> _normPoints3D,
                                   Eigen::MatrixXd T2 )
{
   int N = _points2D.size();
   Eigen::VectorXd uvh;
   double u; double v;
   std::vector<Eigen::VectorXd> uv_normPredicted;
   std::vector<Eigen::VectorXd> uv_predicted;
   std::vector<Eigen::VectorXd> normResidual;
   std::vector<Eigen::VectorXd> residual;
   Eigen::MatrixXd T2inv;

   for( int i = 0; i < N; i++ )
   {
      Eigen::VectorXd normPoint3D_h(4);
      normPoint3D_h << _normPoints3D[i](0), _normPoints3D[i](1), _normPoints3D[i](2), 1; 
      uvh = _M*normPoint3D_h;
      u = uvh(0) / uvh(2);  v = uvh(1) / uvh(2);

      uv_normPredicted.push_back( Eigen::Vector2d( u, v ) );
      double nru = u - _normPoints2D[i](0); 
      double nrv = v - _normPoints2D[i](1);
      double nrd = sqrt( nru*nru + nrv*nrv );
      normResidual.push_back( Eigen::Vector3d( nru, nrv, nrd) );

      T2inv = T2.inverse();
      Eigen::VectorXd uvp = T2inv*Eigen::Vector3d( u, v, 1 );
      double ru = uvp(0) - _points2D[i](0); 
      double rv = uvp(1) - _points2D[i](1);
      double rd = sqrt( ru*ru + rv*rv );
      uv_predicted.push_back( Eigen::Vector2d( uvp(0), uvp(1) ) );
      residual.push_back( Eigen::Vector3d( ru, rv, rd ) );

   }


   /** Display */
   printf("Residual!! \n");
   for( unsigned int i = 0; i < N; i++ )
   {
      printf("[%d] P2D: (%d , %d) -- Predicted: (%.4f , %.4f) - Residual: (%.4f %.4f) Mod: %.4f \n",i, _points2D[i](0), _points2D[i](1), uv_predicted[i](0), uv_predicted[i](1), residual[i](0), residual[i](1), residual[i](2));
   }

}
CCircle CMinSquareRecognizing::getCircleByPoints( std::vector<cv::Point> points )
{
    Eigen::MatrixXd C( 4, 4 );
    C.fill( 0 );
    C( 0, 0 ) = 4.;

    Eigen::MatrixXd S = generateScatterMatrix( points );

    Eigen::MatrixXd InverseS = S.inverse();
    Eigen::MatrixXd engineM = InverseS * C;

    Eigen::EigenSolver<Eigen::MatrixXd> es( engineM, true );

    Eigen::MatrixXd vecs = es.eigenvectors().real();
    Eigen::MatrixXd vals = es.eigenvalues().real();

    for( int i = 0; i < vecs.rows(); ++i ) {
        Eigen::MatrixXd row = vecs.row( i );
        Eigen::MatrixXd rowTranspose = row.transpose();
        double tmp = ( row * S * rowTranspose )( 0, 0 );

        if( ( 1. / vals( i, 0 ) ) > 0
            && !isAbsInf( 1. / vals( i, 0 ) )
            && !isAbsInf( vals( i, 0 ) )
            && tmp > 0 ) {

            //нормируем коэффициент перед квадратами до 1
            double a = vecs( 0, i );
            double b = vecs( 1, i ) / a;
            double c = vecs( 2, i ) / a;
            double d = vecs( 3, i ) / a;


            double x = -b / 2.;
            double y = -c / 2.;
            double r = sqrt( b * b + c * c - 4 * d ) / 2.;

            double accuracy = countCircleAccuracy( x, y, r, points );
            return CCircle( cvRound( x ), cvRound( y ), cvRound( r ), accuracy );
        }
    }

    return CCircle( 0, 0, 0 );
}
Example #17
0
/**
 * @function main
 */
int main( int argc, char* argv[] )
{
    if( argc < 3 )
    {
        printf("Error. Give me two files with 2D and 3D Points \n");
        return 1;
    }


    /** Normalize */
    normalizePoints2D( argv[1], T2a, points2Da, normPoints2Da );
    normalizePoints2D( argv[2], T2b, points2Db, normPoints2Db );

    /** SVD */
    calculateF_SVD( normPoints2Da, normPoints2Db, Fh );

    /** Print Fh */
    std::cout << Fh << std::endl;

    std::cout << Fh.inverse() << std::endl;
    return 0;
}
		// Eigen version
		virtual ReturnValue evaluate()
		{
			CPad* pad = getPad("SqMatrixPad");
			SqMatrix* sqMatrix = (SqMatrix*) pad->getRootObject(sizeof(SqMatrix));

			if (sqMatrix == NULL)
				throwUdxException("Pad does not exist.");

			Eigen::MatrixXd m = Eigen::Map<RMatrixXd>(
				sqMatrix->matrix,
				sqMatrix->dimension,
				sqMatrix->dimension);

			RMatrixXd i = m.inverse();

			Eigen::Map<RMatrixXd>(
				sqMatrix->matrix,
				sqMatrix->dimension,
				sqMatrix->dimension) = i;

			NZ_UDX_RETURN_BOOL(true);
		}
Example #19
0
void mexFunction (int numOutputs, mxArray *outputs[],
                 int numInputs, const mxArray *inputs[])
{      
    if(numInputs == 3){
        //Eigen::initParallel();

        ConstMatrix<double, Eigen::Dynamic, Eigen::Dynamic> X(inputs[0]);

        // Get size of data. 
        int samples = X.rows(); 
        int dimension = X.cols();

        if (dimension<1){
            mexErrMsgTxt("stats:mvnpdf:TooFewDimensions");
        }    
   
        ConstMatrix<double, 1, Eigen::Dynamic> mu(inputs[1]);
        ConstMatrix<double, Eigen::Dynamic, Eigen::Dynamic> C(inputs[2]);
        
        if (mu.cols()!=dimension || C.rows()!=dimension || C.cols()!=dimension ){
            mexErrMsgTxt("stats:mvnpdf:invalidparameters");
        }

        outputs[0] = mxCreateDoubleMatrix (samples, 1, mxREAL);
        double* result = mxGetPr(outputs[0]);  
        
        double lognormconst;
        switch(dimension){
            case 1:
                {
                    lognormconst = log(1.0/sqrt(2 * M_PI*C(0,0)));
                    double factor =  -0.5 /C(0,0);
                    //#pragma omp parallel for
                    for (int i=0; i<samples; i++){
                        double x = X(i,0) - mu(0,0);
                        double exponent =x*x*factor;
                        result[i] = lognormconst + exponent;
                    }
                    fmath::expd_v(result, X.rows());
                }
                break;
            case 2:
                calculateGaussPdf<2>(X, mu, C, result);
                break;
            case 3:
                calculateGaussPdf<3>(X, mu, C, result);
                break;
            case 4:
                calculateGaussPdf<4>(X, mu, C, result);
                break;
                /*
            case 5:
                calculateGaussPdf<5>(X, mu, C, result);
                break;                
            case 6:
                calculateGaussPdf<6>(X, mu, C, result);
                break;                
            case 7:
                calculateGaussPdf<7>(X, mu, C, result);
                break;       */         
            default:
                //calculateGaussPdf<Eigen::Dynamic>(X, mu, C, result);
                //break;
                
                Eigen::MatrixXd L = C.llt().matrixL().transpose(); // cholesky decomposition
                Eigen::MatrixXd Linv = L.inverse();

                double det = L.diagonal().prod(); //determinant of L is equal to square rooot of determinant of C
                lognormconst = -log(2 * M_PI)*dimension/2 - log(fabs(det));
                
                
                Eigen::MatrixXd X0 = (X.rowwise() - mu)*Linv;
                Eigen::Map<Eigen::Matrix<double,Eigen::Dynamic,1> > resultMap(result, samples);
                resultMap = (X0.rowwise().squaredNorm()).array() * (-0.5) + lognormconst;

                /*
                Eigen::Matrix<double,1,Eigen::Dynamic> x = mu;
                Eigen::Matrix<double,1,Eigen::Dynamic> tmp = x;

                for (int i=0; i< samples; i++){
                    x = X.row(i) - mu;
                    tmp.noalias() = x*Linv;
                    double exponent = -0.5 * (tmp.cwiseProduct(tmp)).sum();
                    result[i] = lognormconst+exponent;
                }*/
                
                fmath::expd_v(result, X.rows());
                break;
        }
    }
    else{
        mexErrMsgTxt("stats:mvnpdf:invalidparameters");
    }
}
Example #20
0
//                      left             right              back          front
// constantCoord => 0: (-0.5, _, _), 1: (0.5, _, _), 2: (_, -0.5, _), 3: (_, 0.5, _)
// also include the minimum and maximum values in the non-constant coord (mn, mx)
// and the minimum and maximum values for this coord (o_mn, o_mx)
void SliceStack::triangulateSide(int constantCoord,
                                 double fixedCoord,
                                 vector<Eigen::Vector3d> &verts,
                                 Eigen::MatrixXd &V, Eigen::MatrixXi &F) {
  // Compute the mid z-coord.
  sort(verts.begin(), verts.end(), customSortByZ);

  double mid = 0;
  for (const auto & v : verts) {
    mid += v(2);
  }
  mid /= verts.size();

  vector<Eigen::Vector3d> topV;
  vector<Eigen::Vector3d> botV;

  // Fill the botV and topV vectors
  for (int i = 0; i < verts.size(); ++i) {
    if (verts[i][2] < mid)
      botV.push_back(verts[i]);
    else
      topV.push_back(verts[i]);
  }

  // Set the z-scaling as the distance between the top and the bottom vert
  double z_spacing = verts.back()(2) - verts.front()(2);

  // If the constant coord is y, sort by x direction.
  if (constantCoord == GLOBAL::FRONT || constantCoord == GLOBAL::BACK) {
    sort(botV.begin(), botV.end(), customSortByX);
    sort(topV.rbegin(), topV.rend(), customSortByX); // backwards
  }
  // otherwise, sort by y direction.
  else {
    sort(botV.begin(), botV.end(), customSortByY);
    sort(topV.rbegin(), topV.rend(), customSortByY); // backwards
  }

  Eigen::MatrixXd inputV(verts.size() + GLOBAL::EXTRA * 2, 2);
  Eigen::MatrixXi inputE(verts.size() + GLOBAL::EXTRA * 2, 2);

  int offset = 0;

  // Add bottom points, from left to right
  for (int i = 0; i < botV.size(); ++i) {
    if (constantCoord == GLOBAL::LEFT || constantCoord == GLOBAL::RIGHT) {
      inputV.row(offset++) << botV[i][1], botV[i][2];
    } else {
      inputV.row(offset++) << botV[i][0], botV[i][2];
    }
  }

  // Add right points
  // Get the vector that extends from the top corner to the bottom corner.
  Eigen::Vector3d bot2Top = topV.front() - botV.back(); // top is sorted backwards
  for (int i = 1; i <= GLOBAL::EXTRA; ++i) {
    auto shift_by = botV.back() + bot2Top * i / (GLOBAL::EXTRA + 1);
    if (constantCoord == GLOBAL::LEFT || constantCoord == GLOBAL::RIGHT)
      inputV.row(offset++) << shift_by(1), shift_by(2);
    else
      inputV.row(offset++) << shift_by(0), shift_by(2);
  }

  // Add top points, from right to left
  for (int i = 0; i < topV.size(); ++i) {
    if (constantCoord == GLOBAL::LEFT || constantCoord == GLOBAL::RIGHT)
      inputV.row(offset++) << topV[i][1], topV[i][2];
    else
      inputV.row(offset++) << topV[i][0], topV[i][2];
  }

  // Add left points
  Eigen::Vector3d top2Bot = botV.front() - topV.back();
  for (int i = 1; i <= GLOBAL::EXTRA; ++i) {
    auto shift_by = topV.back() + top2Bot * i / (GLOBAL::EXTRA + 1);
    if (constantCoord == GLOBAL::LEFT || constantCoord == GLOBAL::RIGHT)
      inputV.row(offset++) << shift_by(1), shift_by(2);
    else
      inputV.row(offset++) << shift_by(0), shift_by(2);
  }

  // Add all the new edges.
  for (int i = 0; i < inputV.rows(); ++i) {
    inputE.row(i) << i, (i + 1) % (inputV.rows());
  }

  Eigen::MatrixXd tmpV;
  Helpers::triangulate(inputV, inputE, tmpV, F);

  // 3D-ifying the slice.
  V.resize(tmpV.rows(), 3);
  for (int i = 0; i < tmpV.rows(); ++i) {
    switch(constantCoord) {
      case GLOBAL::LEFT : V.row(i) << fixedCoord, tmpV(i, 0), tmpV(i, 1);
                          break;
      case GLOBAL::RIGHT : V.row(i) << fixedCoord, tmpV(i, 0), tmpV(i, 1);
                           break;
      case GLOBAL::FRONT : V.row(i) << tmpV(i, 0), fixedCoord, tmpV(i, 1);
                           break;
      case GLOBAL::BACK : V.row(i) << tmpV(i, 0), fixedCoord, tmpV(i, 1);
                          break;
    }
  }

  // Find the projection to map the corners back.
  Eigen::MatrixXd XT(3, 3);
  XT << V.row(0),
        V.row(botV.size() - 1),
        V.row(botV.size() + GLOBAL::EXTRA);

  Eigen::MatrixXd X = XT.transpose();

  Eigen::MatrixXd B(3, 3);
  B.col(0) << botV[0];
  B.col(1) << botV[botV.size()-1];
  B.col(2) << topV[0];

  Eigen::MatrixXd A = B * X.inverse();

  V = (A * V.transpose()).transpose();
}
Example #21
0
int main(int argc, char *argv[])
{
    TCLAP::CmdLine cmd("LINE3D++");

    TCLAP::ValueArg<std::string> inputArg("i", "input_folder", "folder containing the images", true, ".", "string");
    cmd.add(inputArg);

    TCLAP::ValueArg<std::string> mavmapArg("b", "mavmap_output", "full path to the mavmap output (image-data-*.txt)", true, "", "string");
    cmd.add(mavmapArg);

    TCLAP::ValueArg<std::string> extArg("t", "image_extension", "image extension (case sensitive), if not specified: jpg, png or bmp expected", false, "", "string");
    cmd.add(extArg);

    TCLAP::ValueArg<std::string> prefixArg("f", "image_prefix", "optional image prefix", false, "", "string");
    cmd.add(prefixArg);

    TCLAP::ValueArg<std::string> outputArg("o", "output_folder", "folder where result and temporary files are stored (if not specified --> input_folder+'/Line3D++/')", false, "", "string");
    cmd.add(outputArg);

    TCLAP::ValueArg<int> scaleArg("w", "max_image_width", "scale image down to fixed max width for line segment detection", false, L3D_DEF_MAX_IMG_WIDTH, "int");
    cmd.add(scaleArg);

    TCLAP::ValueArg<int> neighborArg("n", "num_matching_neighbors", "number of neighbors for matching", false, L3D_DEF_MATCHING_NEIGHBORS, "int");
    cmd.add(neighborArg);

    TCLAP::ValueArg<float> sigma_A_Arg("a", "sigma_a", "angle regularizer", false, L3D_DEF_SCORING_ANG_REGULARIZER, "float");
    cmd.add(sigma_A_Arg);

    TCLAP::ValueArg<float> sigma_P_Arg("p", "sigma_p", "position regularizer (if negative: fixed sigma_p in world-coordinates)", false, L3D_DEF_SCORING_POS_REGULARIZER, "float");
    cmd.add(sigma_P_Arg);

    TCLAP::ValueArg<float> epipolarArg("e", "min_epipolar_overlap", "minimum epipolar overlap for matching", false, L3D_DEF_EPIPOLAR_OVERLAP, "float");
    cmd.add(epipolarArg);

    TCLAP::ValueArg<int> knnArg("k", "knn_matches", "number of matches to be kept (<= 0 --> use all that fulfill overlap)", false, L3D_DEF_KNN, "int");
    cmd.add(knnArg);

    TCLAP::ValueArg<int> segNumArg("y", "num_segments_per_image", "maximum number of 2D segments per image (longest)", false, L3D_DEF_MAX_NUM_SEGMENTS, "int");
    cmd.add(segNumArg);

    TCLAP::ValueArg<int> visibilityArg("v", "visibility_t", "minimum number of cameras to see a valid 3D line", false, L3D_DEF_MIN_VISIBILITY_T, "int");
    cmd.add(visibilityArg);

    TCLAP::ValueArg<bool> diffusionArg("d", "diffusion", "perform Replicator Dynamics Diffusion before clustering", false, L3D_DEF_PERFORM_RDD, "bool");
    cmd.add(diffusionArg);

    TCLAP::ValueArg<bool> loadArg("l", "load_and_store_flag", "load/store segments (recommended for big images)", false, L3D_DEF_LOAD_AND_STORE_SEGMENTS, "bool");
    cmd.add(loadArg);

    TCLAP::ValueArg<float> collinArg("r", "collinearity_t", "threshold for collinearity", false, L3D_DEF_COLLINEARITY_T, "float");
    cmd.add(collinArg);

    TCLAP::ValueArg<bool> cudaArg("g", "use_cuda", "use the GPU (CUDA)", false, true, "bool");
    cmd.add(cudaArg);

    TCLAP::ValueArg<bool> ceresArg("c", "use_ceres", "use CERES (for 3D line optimization)", false, L3D_DEF_USE_CERES, "bool");
    cmd.add(ceresArg);

    TCLAP::ValueArg<float> constRegDepthArg("z", "const_reg_depth", "use a constant regularization depth (only when sigma_p is metric!)", false, -1.0f, "float");
    cmd.add(constRegDepthArg);

    // read arguments
    cmd.parse(argc,argv);
    std::string inputFolder = inputArg.getValue().c_str();
    std::string mavmapFile = mavmapArg.getValue().c_str();
    std::string outputFolder = outputArg.getValue().c_str();
    std::string imgExtension = extArg.getValue().c_str();
    std::string imgPrefix = prefixArg.getValue().c_str();
    if(outputFolder.length() == 0)
        outputFolder = inputFolder+"/Line3D++/";

    int maxWidth = scaleArg.getValue();
    unsigned int neighbors = std::max(neighborArg.getValue(),2);
    bool diffusion = diffusionArg.getValue();
    bool loadAndStore = loadArg.getValue();
    float collinearity = collinArg.getValue();
    bool useGPU = cudaArg.getValue();
    bool useCERES = ceresArg.getValue();
    float epipolarOverlap = fmin(fabs(epipolarArg.getValue()),0.99f);
    float sigmaA = fabs(sigma_A_Arg.getValue());
    float sigmaP = sigma_P_Arg.getValue();
    int kNN = knnArg.getValue();
    unsigned int maxNumSegments = segNumArg.getValue();
    unsigned int visibility_t = visibilityArg.getValue();
    float constRegDepth = constRegDepthArg.getValue();

    if(imgExtension.substr(0,1) != ".")
        imgExtension = "."+imgExtension;

    // since no median depth can be computed without camera-to-worldpoint links
    // sigma_p MUST be positive and in pixels!
    if(sigmaP < L3D_EPS && constRegDepth < L3D_EPS)
    {
        std::cout << "sigma_p cannot be negative (i.e. in world coordiantes) when no valid regularization depth (--const_reg_depth) is given!" << std::endl;
        std::cout << "reverting to: sigma_p = 2.5px" << std::endl;
        sigmaP = 2.5f;
    }

    // check if mavmap file exists
    boost::filesystem::path bf(mavmapFile);
    if(!boost::filesystem::exists(bf))
    {
        std::cerr << "mavmap file '" << mavmapFile << "' does not exist!" << std::endl;
        return -1;
    }

    // create output directory
    boost::filesystem::path dir(outputFolder);
    boost::filesystem::create_directory(dir);

    // create Line3D++ object
    L3DPP::Line3D* Line3D = new L3DPP::Line3D(outputFolder,loadAndStore,maxWidth,
                                              maxNumSegments,false,useGPU);

    // read mavmap result
    std::ifstream mavmap_file;
    mavmap_file.open(mavmapFile.c_str());

    std::string mavmap_line;
    // check for comments...
    while(std::getline(mavmap_file,mavmap_line))
    {
        if(mavmap_line.substr(0,1) != "#")
            break;
    }

    // read camera data (sequentially)
    std::vector<std::string> cams_filenames;
    std::vector<std::pair<double,double> > cams_focals;
    std::vector<Eigen::Matrix3d> cams_rotation;
    std::vector<Eigen::Vector3d> cams_translation;
    std::vector<Eigen::Vector2d> cams_principle;
    do
    {
        if(mavmap_line.length() < 28)
            break;

        std::string filename,roll,pitch,yaw;
        std::string lat,lon,alt,h;
        std::string tx,ty,tz;
        std::string camID,camModel,fx,fy,cx,cy;

        std::stringstream mavmap_stream(mavmap_line);
        mavmap_stream >> filename >> roll >> pitch >> yaw;
        mavmap_stream >> lat >> lon >> alt >> h;
        mavmap_stream >> tx >> ty >> tz;
        mavmap_stream >> camID >> camModel >> fx >> fy >> cx >> cy;

        // check camera model
        if(camModel.substr(0,camModel.length()-1) != "PINHOLE")
        {
            std::cout << "only PINHOLE camera model supported..." << std::endl;
            return -1;
        }

        // filename
        cams_filenames.push_back(filename.substr(0,filename.length()-1));

        // rotation
        double r,y,p;
        std::stringstream  dat_stream(roll.substr(0,roll.length()-1));
        dat_stream >> r; dat_stream.str(""); dat_stream.clear();
        dat_stream.str(pitch.substr(0,pitch.length()-1));
        dat_stream >> p; dat_stream.str(""); dat_stream.clear();
        dat_stream.str(yaw.substr(0,yaw.length()-1));
        dat_stream >> y; dat_stream.str(""); dat_stream.clear();

        Eigen::Matrix3d R = Line3D->rotationFromRPY(r,p,y);

        // translation
        double Tx,Ty,Tz;
        dat_stream.str(tx.substr(0,tx.length()-1));
        dat_stream >> Tx; dat_stream.str(""); dat_stream.clear();
        dat_stream.str(ty.substr(0,ty.length()-1));
        dat_stream >> Ty; dat_stream.str(""); dat_stream.clear();
        dat_stream.str(tz.substr(0,tz.length()-1));
        dat_stream >> Tz; dat_stream.str(""); dat_stream.clear();

        Eigen::Vector3d t(Tx,Ty,Tz);

        // invert
        Eigen::MatrixXd Rt = Eigen::MatrixXd::Identity(4,4);
        Rt.block<3,3>(0,0) = R;
        Rt.block<3,1>(0,3) = t;
        Eigen::MatrixXd Rt_inv = Rt.inverse().eval().block<3, 4>(0,0);

        R = Rt_inv.block<3,3>(0,0);
        t = Rt_inv.block<3,1>(0,3);

        cams_rotation.push_back(R);
        cams_translation.push_back(t);

        // focal lengths
        double foc_x,foc_y;
        dat_stream.str(fx.substr(0,fx.length()-1));
        dat_stream >> foc_x; dat_stream.str(""); dat_stream.clear();
        dat_stream.str(fy.substr(0,fy.length()-1));
        dat_stream >> foc_y; dat_stream.str(""); dat_stream.clear();

        cams_focals.push_back(std::pair<double,double>(foc_x,foc_y));

        // principle point
        double pp_x,pp_y;
        dat_stream.str(cx.substr(0,cx.length()-1));
        dat_stream >> pp_x; dat_stream.str(""); dat_stream.clear();
        dat_stream.str(cy.substr(0,cy.length()-1));
        dat_stream >> pp_y; dat_stream.str(""); dat_stream.clear();

        cams_principle.push_back(Eigen::Vector2d(pp_x,pp_y));

    }while(std::getline(mavmap_file,mavmap_line));
    mavmap_file.close();

    // load images (parallel)
#ifdef L3DPP_OPENMP
    #pragma omp parallel for
#endif //L3DPP_OPENMP
    for(unsigned int i=0; i<cams_rotation.size(); ++i)
    {
        // load image
        std::string img_filename = imgPrefix+cams_filenames[i];
        cv::Mat image;
        std::vector<boost::filesystem::wpath> possible_imgs;

        if(imgExtension.length() == 0)
        {
            // look for common image extensions
            possible_imgs.push_back(boost::filesystem::wpath(inputFolder+"/"+img_filename+".jpg"));
            possible_imgs.push_back(boost::filesystem::wpath(inputFolder+"/"+img_filename+".JPG"));
            possible_imgs.push_back(boost::filesystem::wpath(inputFolder+"/"+img_filename+".png"));
            possible_imgs.push_back(boost::filesystem::wpath(inputFolder+"/"+img_filename+".PNG"));
            possible_imgs.push_back(boost::filesystem::wpath(inputFolder+"/"+img_filename+".jpeg"));
            possible_imgs.push_back(boost::filesystem::wpath(inputFolder+"/"+img_filename+".JPEG"));
            possible_imgs.push_back(boost::filesystem::wpath(inputFolder+"/"+img_filename+".bmp"));
            possible_imgs.push_back(boost::filesystem::wpath(inputFolder+"/"+img_filename+".BMP"));
        }
        else
        {
            // use given extension
            possible_imgs.push_back(boost::filesystem::wpath(inputFolder+"/"+img_filename+imgExtension));
        }

        bool image_found = false;
        unsigned int pos = 0;
        while(!image_found && pos < possible_imgs.size())
        {
            if(boost::filesystem::exists(possible_imgs[pos]))
            {
                image_found = true;
                img_filename = possible_imgs[pos].string();
            }
            ++pos;
        }

        if(image_found)
        {
            // load image
            image = cv::imread(img_filename,CV_LOAD_IMAGE_GRAYSCALE);

            // setup intrinsics
            double px = cams_principle[i].x();
            double py = cams_principle[i].y();
            double fx = cams_focals[i].first;
            double fy = cams_focals[i].second;

            Eigen::Matrix3d K = Eigen::Matrix3d::Zero();
            K(0,0) = fx;
            K(1,1) = fy;
            K(0,2) = px;
            K(1,2) = py;
            K(2,2) = 1.0;

            // set neighbors
            std::list<unsigned int> neighbor_list;
            size_t n_before = neighbors/2;
            for(int nID=int(i)-1; nID >= 0 && neighbor_list.size()<n_before; --nID)
            {
                neighbor_list.push_back(nID);
            }
            for(int nID=int(i)+1; nID < int(cams_rotation.size()) && neighbor_list.size() < neighbors; ++nID)
            {
                neighbor_list.push_back(nID);
            }

            // add to system
            Line3D->addImage(i,image,K,cams_rotation[i],
                             cams_translation[i],constRegDepth,neighbor_list);
        }
    }

    // match images
    Line3D->matchImages(sigmaP,sigmaA,neighbors,epipolarOverlap,
                        kNN,constRegDepth);

    // compute result
    Line3D->reconstruct3Dlines(visibility_t,diffusion,collinearity,useCERES);

    // save end result
    std::vector<L3DPP::FinalLine3D> result;
    Line3D->get3Dlines(result);

    // save as STL
    Line3D->saveResultAsSTL(outputFolder);
    // save as OBJ
    Line3D->saveResultAsOBJ(outputFolder);
    // save as TXT
    Line3D->save3DLinesAsTXT(outputFolder);
    // save as BIN
    Line3D->save3DLinesAsBIN(outputFolder);

    // cleanup
    delete Line3D;
}
Example #22
0
pcl::MLSResult::MLSProjectionResults
pcl::MLSResult::projectPointOrthogonalToPolynomialSurface (const double u, const double v, const double w) const
{
  double gu = u;
  double gv = v;
  double gw = 0;

  MLSProjectionResults result;
  result.normal = plane_normal;
  if (order > 1 && c_vec.size () >= (order + 1) * (order + 2) / 2 && pcl_isfinite (c_vec[0]))
  {
    PolynomialPartialDerivative d = getPolynomialPartialDerivative (gu, gv);
    gw = d.z;
    double err_total;
    double dist1 = std::abs (gw - w);
    double dist2;
    do
    {
      double e1 = (gu - u) + d.z_u * gw - d.z_u * w;
      double e2 = (gv - v) + d.z_v * gw - d.z_v * w;

      double F1u = 1 + d.z_uu * gw + d.z_u * d.z_u - d.z_uu * w;
      double F1v = d.z_uv * gw + d.z_u * d.z_v - d.z_uv * w;

      double F2u = d.z_uv * gw + d.z_v * d.z_u - d.z_uv * w;
      double F2v = 1 + d.z_vv * gw + d.z_v * d.z_v - d.z_vv * w;

      Eigen::MatrixXd J (2, 2);
      J (0, 0) = F1u;
      J (0, 1) = F1v;
      J (1, 0) = F2u;
      J (1, 1) = F2v;

      Eigen::Vector2d err (e1, e2);
      Eigen::Vector2d update = J.inverse () * err;
      gu -= update (0);
      gv -= update (1);

      d = getPolynomialPartialDerivative (gu, gv);
      gw = d.z;
      dist2 = std::sqrt ((gu - u) * (gu - u) + (gv - v) * (gv - v) + (gw - w) * (gw - w));

      err_total = std::sqrt (e1 * e1 + e2 * e2);

    } while (err_total > 1e-8 && dist2 < dist1);

    if (dist2 > dist1) // the optimization was diverging reset the coordinates for simple projection
    {
      gu = u;
      gv = v;
      d = getPolynomialPartialDerivative (u, v);
      gw = d.z;
    }

    result.u = gu;
    result.v = gv;
    result.normal -= (d.z_u * u_axis + d.z_v * v_axis);
    result.normal.normalize ();
  }

  result.point = mean + gu * u_axis + gv * v_axis + gw * plane_normal;

  return (result);
}
Example #23
0
// another simple example: invert a matrix,
// returning a matrix
//
// [[Rcpp::export]]
Eigen::MatrixXd rcppeigen_matinv(const Eigen::MatrixXd & x) {
  Eigen::MatrixXd Xinv(x.inverse());
  return Xinv;
}
TEST(SparseMatrixFunctionTests, testSchurComplement1)
{
  try {
    using namespace aslam::backend;
    typedef sparse_block_matrix::SparseBlockMatrix<Eigen::MatrixXd> SparseBlockMatrix;
    // Create the sparse Hessian. Two dense blocks. Three sparse.
    int structure[5] = {2, 2, 3, 3, 3};
    std::partial_sum(structure, structure + 5, structure);
    int marginalizedStartingBlock = 2;
    int marginalizedStartingIndex = structure[ marginalizedStartingBlock - 1 ];
    double lambda = 1;
    SparseBlockMatrix H(structure, structure, 5, 5, true);
    Eigen::VectorXd e(H.rows());
    e.setRandom();
    Eigen::VectorXd b(H.rowBaseOfBlock(marginalizedStartingBlock));
    b.setZero();
    boost::shared_ptr<SparseBlockMatrix> A(H.slice(0, marginalizedStartingBlock, 0, marginalizedStartingBlock, true));
    ASSERT_EQ(marginalizedStartingBlock, A->bRows());
    ASSERT_EQ(marginalizedStartingBlock, A->bCols());
    A->clear(false);
    std::vector<Eigen::MatrixXd> invVi;
    invVi.resize(H.bRows() - marginalizedStartingBlock);
    // Fill in H.
    *H.block(0, 0, true) = sm::eigen::randomCovariance<2>() * 100;
    *H.block(1, 1, true) = sm::eigen::randomCovariance<2>() * 100;
    *H.block(2, 2, true) = sm::eigen::randomCovariance<3>() * 100;
    *H.block(3, 3, true) = sm::eigen::randomCovariance<3>() * 100;
    *H.block(4, 4, true) = sm::eigen::randomCovariance<3>() * 100;
    // Start with two off diagonals.
    H.block(0, 4, true)->setRandom();
    H.block(0, 4, true)->array() *= 100;
    H.block(1, 4, true)->setRandom();
    H.block(1, 4, true)->array() *= 100;
    //std::cout << "H:\n" << H << std::endl;
    applySchurComplement(H,
                         e,
                         lambda,
                         marginalizedStartingBlock,
                         true,
                         *A,
                         invVi,
                         b);
    Eigen::MatrixXd Hd = H.toDense();
    Eigen::MatrixXd U = Hd.topLeftCorner(marginalizedStartingIndex, marginalizedStartingIndex);
    Eigen::MatrixXd V = Hd.bottomRightCorner(H.rows() - marginalizedStartingIndex, H.rows() - marginalizedStartingIndex);
    Eigen::MatrixXd W = Hd.topRightCorner(marginalizedStartingIndex, H.rows() - marginalizedStartingIndex);
    V.diagonal().array() += lambda;
    Eigen::MatrixXd AA = U - W * V.inverse() * W.transpose();
    AA.diagonal().array() += lambda;
    Eigen::VectorXd epsSparse = e.tail(e.size() - marginalizedStartingIndex);
    Eigen::VectorXd epsDense = e.head(marginalizedStartingIndex);
    Eigen::VectorXd bb = epsDense - W * V.inverse() * epsSparse;
    {
      SCOPED_TRACE("");
      Eigen::MatrixXd Asa = A->toDense().selfadjointView<Eigen::Upper>();
      sm::eigen::assertNear(Asa, AA, 1e-12, SM_SOURCE_FILE_POS, "Testing the lhs schur complement");
    }
    {
      SCOPED_TRACE("");
      sm::eigen::assertNear(b, bb, 1e-12, SM_SOURCE_FILE_POS, "Testing the rhs schur complement");
    }
    // Let's try it again to make sure stuff gets initialized correctly.
    applySchurComplement(H,
                         e,
                         lambda,
                         marginalizedStartingBlock,
                         true,
                         *A,
                         invVi,
                         b);
    {
      SCOPED_TRACE("");
      Eigen::MatrixXd Asa = A->toDense().selfadjointView<Eigen::Upper>();
      sm::eigen::assertNear(Asa, AA, 1e-12, SM_SOURCE_FILE_POS, "Testing the lhs schur complement");
    }
    {
      SCOPED_TRACE("");
      sm::eigen::assertNear(b, bb, 1e-12, SM_SOURCE_FILE_POS, "Testing the rhs schur complement");
    }
    // Now we check the update function.
    Eigen::VectorXd dx(marginalizedStartingIndex);
    dx.setRandom();
    Eigen::VectorXd denseDs = V.inverse() * (epsSparse - W.transpose() * dx);
    for (int i = 0; i < H.bRows() - marginalizedStartingBlock; ++i) {
      Eigen::VectorXd outDsi;
      buildDsi(i, H, e, marginalizedStartingBlock, invVi[i], dx, outDsi);
      Eigen::VectorXd dsi = denseDs.segment(H.rowBaseOfBlock(i + marginalizedStartingBlock) - marginalizedStartingIndex, H.rowsOfBlock(i + marginalizedStartingBlock));
      sm::eigen::assertNear(outDsi, dsi, 1e-12, SM_SOURCE_FILE_POS, "Checking the update step calculation");
    }
  } catch (const std::exception& e) {
    FAIL() << "Exception: " << e.what();
  }
}
Example #25
0
void CDKF::measurementUpdate(const ros::Time& prev_stamp,
                             const ros::Time& current_stamp,
                             const double image_angular_velocity,
                             const IMUList& imu_rotations,
                             const bool calc_offset) {
  // convert tracked points to measurement
  Eigen::VectorXd real_measurement(kMeasurementSize);
  accessM(real_measurement, MEASURED_TIMESTAMP).array() =
      (current_stamp - zero_timestamp_).toSec();

  accessM(real_measurement, ANGULAR_VELOCITY).array() = image_angular_velocity;

  if (verbose_) {
    ROS_INFO_STREAM("Measured Values: \n" << real_measurement.transpose());
  }

  // create sigma points
  MeasurementSigmaPoints sigma_points(
      state_, cov_, measurement_noise_sd_, CDKF::stateToMeasurementEstimate,
      imu_rotations, zero_timestamp_, calc_offset);

  // get mean and cov
  Eigen::VectorXd predicted_measurement;
  sigma_points.calcEstimatedMean(&predicted_measurement);
  Eigen::MatrixXd innovation;
  sigma_points.calcEstimatedCov(&innovation);

  if (verbose_) {
    ROS_INFO_STREAM("Predicted Measurements: \n"
                    << predicted_measurement.transpose());
  }

  // calc mah distance
  Eigen::VectorXd diff = real_measurement - predicted_measurement;
  double mah_dist = std::sqrt(diff.transpose() * innovation.inverse() * diff);
  if (mah_dist > mah_threshold_) {
    ROS_WARN("Outlier detected, measurement rejected");
    return;
  }

  Eigen::MatrixXd cross_cov;
  sigma_points.calcEstimatedCrossCov(&cross_cov);

  Eigen::MatrixXd gain = cross_cov * innovation.inverse();

  const Eigen::VectorXd state_diff =
      gain * (real_measurement - predicted_measurement);

  state_ += state_diff;

  cov_ -= gain * innovation * gain.transpose();

  if (verbose_) {
    ROS_INFO_STREAM("Updated State: \n" << state_.transpose());
    ROS_INFO_STREAM("Updated Cov: \n" << cov_);
  }

  // guard against precision issues
  constexpr double kMaxTime = 10000.0;
  if (accessS(state_, STATE_TIMESTAMP)[0] > kMaxTime) {
    rezeroTimestamps(current_stamp);
  }
}