Ejemplo n.º 1
0
FGColumnVector3 FGRotor::rotor::hub_vel_body2ca( const FGColumnVector3 &uvw, 
                                                 const FGColumnVector3 &pqr,
                                                 double a_ic, double b_ic)
{

  FGColumnVector3  v_r, v_shaft, v_w;
  FGColumnVector3  pos(RelDistance_xhub,0.0,RelHeight_zhub);

  v_r = uvw + pqr*pos;
  v_shaft = BodyToShaft * v_r;

  beta_orient = atan2(v_shaft(eV),v_shaft(eU));

  v_w(eU) = v_shaft(eU)*cos(beta_orient) + v_shaft(eV)*sin(beta_orient);
  v_w(eV) = 0.0;
  v_w(eW) = v_shaft(eW) - b_ic*v_shaft(eU) - a_ic*v_shaft(eV);

  return v_w;
}
Ejemplo n.º 2
0
//----------- Begin of function LinAlg::quadratic_prog ------//
//! Interior Point Quadratic Programming
//! c, Q, A, b, xNames (no global or member variable access)
//!
//! try, by BM:
//!		c = { 0,0 }
//!		Q = { {2,0}, {0,5} }
//!		A = { {5,6} }
//!		b = { 10 }
//!		xNames={x1,x2}
//!
bool LinearAlgebra::quadratic_prog(const Vector &v_c, const Matrix &m_Q, const Matrix &m_A, const Vector &v_b, Vector &v_xNames, int loopCountMultiplier) {
    // init local variables
    int maxIteration = 20;
    const REAL SIGMA    = 1/15.0;                   // 1/10.0;
    const REAL R      = 9.0/10;
    int iter    = 0;

    int n = v_c.Storage();
    int m = v_b.Storage();

    maxIteration *= loopCountMultiplier;

#ifdef DEBUG_VC
    DEBUG_LOG("----------- quadratic_prog begin -----------");
    // print_input(c,Q,A,b,xNames)
    if ( n==10 && m==12 ) {
	char s[500];

	DEBUG_LOG("c = ");
	sprintf(s, "{ %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f };",
		v_c(1),v_c(2),v_c(3),
		v_c(4),v_c(5),v_c(6),
		v_c(7),v_c(8),v_c(9), v_c(10));
	DEBUG_LOG(s);
	DEBUG_LOG("Q = ");
	for (int i=1; i<=n; i++) {
	    sprintf(s, "{%f, %f, %f, %f, %f, %f, %f, %f, %f, %f},",
		    m_Q(i,1),m_Q(i,2),m_Q(i,3),m_Q(i,4),m_Q(i,5),m_Q(i,6),m_Q(i,7),m_Q(i,8),m_Q(i,9),m_Q(i,10)
		);
	    DEBUG_LOG(s);
	}
	DEBUG_LOG("A = ");
	for (i=1; i<=m; i++) {
	    sprintf(s, "{%f, %f, %f, %f, %f, %f, %f, %f, %f, %f},",
		    m_A(i,1),m_A(i,2),m_A(i,3),m_A(i,4),m_A(i,5),m_A(i,6),m_A(i,7),m_A(i,8),m_A(i,9),m_A(i,10)
		);
	    DEBUG_LOG(s);
	}
	DEBUG_LOG("b = ");
	sprintf(s, "{%.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f,",
		v_b(1),v_b(2),v_b(3),
		v_b(4),v_b(5),v_b(6),
		v_b(7),v_b(8),v_b(9), v_b(10), v_b(11), v_b(12)
	    );
	DEBUG_LOG(s);
	/*sprintf(s, "%f, %f, %f, %f, %f, %f, %f, %f, %f,",
	  v_b(10),v_b(11),v_b(12),
	  v_b(13),v_b(14),v_b(15),
	  v_b(16),v_b(17),v_b(18)
	  );
	  DEBUG_LOG(s);
	  sprintf(s, "%f, %f};",
	  v_b(19),v_b(20));
	  DEBUG_LOG(s);*/

    }
    else if ( n==9 && m==20 ) {                     // stage 1
	char s[500];

	DEBUG_LOG("c = ");
	sprintf(s, "{ %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f };",
		v_c(1),v_c(2),v_c(3),
		v_c(4),v_c(5),v_c(6),
		v_c(7),v_c(8),v_c(9));
	DEBUG_LOG(s);
	DEBUG_LOG("Q = ");
	for (int i=1; i<=n; i++) {
	    sprintf(s, "{%f, %f, %f, %f, %f, %f, %f, %f, %f, },",
		    m_Q(i,1),m_Q(i,2),m_Q(i,3),m_Q(i,4),m_Q(i,5),m_Q(i,6),m_Q(i,7),m_Q(i,8),m_Q(i,9)
		);
	    DEBUG_LOG(s);
	}
	DEBUG_LOG("A = ");
	for (i=1; i<=m; i++) {
	    sprintf(s, "{%f, %f, %f, %f, %f, %f, %f, %f, %f },",
		    m_A(i,1),m_A(i,2),m_A(i,3),m_A(i,4),m_A(i,5),m_A(i,6),m_A(i,7),m_A(i,8),m_A(i,9)
		);
	    DEBUG_LOG(s);
	}
	DEBUG_LOG("b = ");
	sprintf(s, "{%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, }, ",
		v_b(1),v_b(2),v_b(3),
		v_b(4),v_b(5),v_b(6),
		v_b(7),v_b(8),v_b(9), v_b(10), v_b(11), v_b(12),
		v_b(13),v_b(14),v_b(15), v_b(16), v_b(17), v_b(18), v_b(19), v_b(20)
	    );
	DEBUG_LOG(s);
    }
    else if ( n==10 && m==22 ) {                    // stage 2
	char s[500];

	DEBUG_LOG("c = ");
	sprintf(s, "{ %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f };",
		v_c(1),v_c(2),v_c(3),
		v_c(4),v_c(5),v_c(6),
		v_c(7),v_c(8),v_c(9),v_c(10));
	DEBUG_LOG(s);
	DEBUG_LOG("Q = ");
	for (int i=1; i<=n; i++) {
	    sprintf(s, "{%.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, },",
		    m_Q(i,1),m_Q(i,2),m_Q(i,3),m_Q(i,4),m_Q(i,5),m_Q(i,6),m_Q(i,7),m_Q(i,8),m_Q(i,9),m_Q(i,10)
		);
	    DEBUG_LOG(s);
	}
	DEBUG_LOG("A = ");
	for (i=1; i<=m; i++) {
	    sprintf(s, "{%.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f },",
		    m_A(i,1),m_A(i,2),m_A(i,3),m_A(i,4),m_A(i,5),m_A(i,6),m_A(i,7),m_A(i,8),m_A(i,9),m_A(i,10)
		);
	    DEBUG_LOG(s);
	}
	DEBUG_LOG("b = ");
	sprintf(s, "{%.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, }, ",
		v_b(1),v_b(2),v_b(3),
		v_b(4),v_b(5),v_b(6),
		v_b(7),v_b(8),v_b(9), v_b(10), v_b(11), v_b(12),
		v_b(13),v_b(14),v_b(15), v_b(16), v_b(17), v_b(18), v_b(19), v_b(20), v_b(21), v_b(22)
	    );
	DEBUG_LOG(s);
    }
#endif

    Vector  v_eN(n);    v_eN = 1;
    Vector  v_eM(m);    v_eM = 1;

    Vector  v_x(n);   v_x = 1;
    Vector  v_z(n);   v_z = 1;
    Vector  v_y(m);   v_y = 1;
    Vector  v_w(m);   v_w = 1;

    // check  m_A is nxm, m_Q is nxn
    err_when(m_A.Nrows() != m || m_A.Ncols() != n );
    err_when(m_Q.Nrows() != n || m_Q.Ncols() != n );

    // init for while loop not_converged() checking
    //
    Vector v_Road = v_b - m_A*(v_x) + v_w;
    Vector v_Sigma = v_c - m_A.t() * v_y - v_z + m_Q*v_x;
    REAL  gamma   = (v_z.t()*v_x + v_y.t()*v_w).AsScalar();
    REAL  mute    = SIGMA*gamma / (n+m);

    DiagonalMatrix X(n),  Xinv(n);
    DiagonalMatrix Y(m),  Yinv(m);
    DiagonalMatrix Z(n);
    DiagonalMatrix W(m);
    Matrix T1(n,n), T2(n,m), T3(m,n), T4(m,m);

    Vector KKFvec(n+m);                             //, v_tmp1(n), v_tmp2(m);

    Vector m_temp(m+n);
    Vector v_dx(n), v_dy(m), v_dz(n), v_dw(m);
    REAL  theeta;

    X=0; Xinv=0; Z=0;
    Y=0; Yinv=0; W=0; {

	//	Matrix _t1(n,n), _t2(n,n);		_t1=1;	_t2=2;
	//	_t1 = SP(_t1,_t2);
    }

    Matrix KKFmat(m+n,m+n);
    Matrix KKFmatInverse(m+n,m+n);

    REAL min=1;

    while ( quadratic_prog_not_converged(v_x,v_y,v_Road,v_Sigma,gamma) && iter <= maxIteration && min > 0.0000000001 ) {
	iter++;
	v_Road  = v_b - m_A*v_x + v_w;
	v_Sigma = v_c - m_A.t()*v_y - v_z + m_Q*v_x;
	gamma   = (v_z.t()*v_x + v_y.t()*v_w).AsScalar();
	mute    = SIGMA*gamma / (n+m);

	X.set_diagonal(v_x);
	Y.set_diagonal(v_y);
	Z.set_diagonal(v_z);
	W.set_diagonal(v_w);

	Xinv.set_diagonal(ElmDivide(v_eN, v_x));
	Yinv.set_diagonal(ElmDivide(v_eM, v_y));

	T1 = -(Xinv * Z + m_Q);
	T2 = m_A.t();
	T3 = m_A;
	T4 = Yinv*W;
	//PRT_MAT << "T1: " << T1 << endl;
	KKFmat = (T1|T2) & (T3|T4);

	KKFvec = (v_c - T2*v_y - mute*Xinv*v_eN + m_Q*v_x)
	    & (v_b - m_A*v_x + mute*Yinv*v_eM);

	Try {
	    /*{
	      bool _f;
	      DiagonalMatrix _dmat(n+m);		_dmat=1;
	      Matrix _inv(n+m,n+m);

	      SVD(KKFmat, _dmat, _inv);

	      _dmat=1;
	      if ( KKFmat*_inv == _dmat )
	      _f = true;
	      else
	      _f = false;
	      }*/

	    min = fabs(KKFmat(1,1));

	    for (int i=2; i<=m+n; i++) {
		if ( min > fabs(KKFmat(i,i)) )            // check diagonal element
		    min = fabs(KKFmat(i,i));
	    }

	    KKFmatInverse = KKFmat.i();

	    /*
	      if ( KKFmat.LogDeterminant().Value() )
	      KKFmatInverse = KKFmat.i();
	      else
	      break;
	    */

	    m_temp =  KKFmatInverse * KKFvec;

	    v_dx  = m_temp.Rows(1,n);
	    v_dy  = m_temp.Rows(n+1,n+m);

	    v_dz  = Xinv*(mute*v_eN - X*Z*v_eN - Z*v_dx);
	    v_dw  = Yinv*(mute*v_eM - Y*W*v_eM - W*v_dy);
	    //PRT_MAT << "v_dx,z,y,w: " << (v_dx|v_dz) <<", "<< (v_dy|v_dw) <<endl;
	    //PRT_MAT << "v_x: " << v_x << endl;
	    //PRT_MAT << "ElmDivide(v_x,v_dx): " << ElmDivide(v_x,v_dx) << endl;

	    theeta =
		(R/((
		    ElmDivide(-v_dx,v_x)
		    & ElmDivide(-v_dw,v_w)
		    & ElmDivide(-v_dy,v_y)
		    & ElmDivide(-v_dz,v_z)
		    )).MaximumValue()
		    );
	    if(theeta>1)                                // theeta = min(theeta,1)
		theeta = 1;

	    v_x += theeta * v_dx;
	    v_y += theeta * v_dy;
	    v_w += theeta * v_dw;
	    v_z += theeta * v_dz;

#ifdef DEBUG_CONSOLE
	    cout << "#iter "<< iter << ": " << v_Road.Sum() << ", " << v_Sigma.Sum() << ", " << gamma << endl;
	    cout << "Ro:" << v_Road << endl;
	    PRT_MAT15 << "v_x:" << v_x << endl;
	    PRT_MAT15 << "v_y:" << v_y << endl;
	    PRT_MAT15 << "v_w:" << v_w << endl;
	    PRT_MAT15 << "v_z:" << v_z << endl;
#elif defined(DEBUG_VC)

	    char s[200];
	    sprintf(s, "#iter %d: %f, %f, %f",
		    iter, v_Road.Sum(), v_Sigma.Sum(), gamma);
	    DEBUG_LOG(s);
	    if ( n == 9 && false ) {
		DEBUG_LOG("x = ");
		sprintf(s, "   %f, %f, %f, %f, %f, %f, %f, %f, %f",
			v_x(1),v_x(2),v_x(3),
			v_x(4),v_x(5),v_x(6),
			v_x(7),v_x(8),v_x(9));
		DEBUG_LOG(s);
	    }
#endif
	}
	CatchAll {
#ifdef DEBUG_CONSOLE
	    cout << Exception::what();
#endif
#ifdef DEBUG_VC
	    DEBUG_LOG("olinalg: failure in quad_prog");
	    DEBUG_LOG((char *)Exception::what());
#endif
	    return false;
	}
    }                                               // while

    v_xNames = v_x;

    if ( min < 0.00001 ) {                          // 1214 || KKFmat.LogDeterminant().Value() == 0 )
	//char s[200];

	//sprintf(s, "#iter %d: %f, %f, %f",
	//	iter, v_Road.Sum(), v_Sigma.Sum(), gamma);
	//DEBUG_LOG(s);
	DEBUG_LOG("--- quad_prog early exit for min < 0.00001 ---");
    }
    else
	DEBUG_LOG("----------- quad_prog normal exit -----------");

#ifdef DEBUG_CONSOLE
    cout << "#iter: " << iter;
#endif

    return true;
}