Example #1
0
/**
 * Implementation of the learning rule described in Bell & Sejnowski,
 * Vision Research, in press for 1997, that contained the natural
 * gradient (W' * W).
 *
 * Bell & Sejnowski hold the patent for this learning rule.
 *
 * SEP goes once through the mixed signals X in batch blocks of size B,
 * adjusting weights W at the end of each block.
 *
 * sepout is called every F counts.
 *
 * I suggest a learning rate (L) of 0.006, and a block size (B) of
 * 300, at least for 2->2 separation.  When annealing to the right
 * solution for 10->10, however, L < 0.0001 and B = 10 were most successful.
 *
 * @param X  "sphered" input matrix
 * @param W  weight matrix
 * @param B  block size
 * @param L  learning rate
 * @param F  interval to print training stats
 */
void sep96(matrix_t *X, matrix_t *W, int B, double L, int F)
{
    matrix_t *BI = m_identity(X->rows);
    m_elem_mult(BI, B);

    int t;
    for ( t = 0; t < X->cols; t += B ) {
        int end = (t + B < X->cols)
            ? t + B
            : X->cols;

        matrix_t *W0 = m_copy(W);
        matrix_t *X_batch = m_copy_columns(X, t, end);
        matrix_t *U = m_product(W0, X_batch);

        // compute Y' = 1 - 2 * f(U), f(u) = 1 / (1 + e^(-u))
        matrix_t *Y_p = m_initialize(U->rows, U->cols);

        int i, j;
        for ( i = 0; i < Y_p->rows; i++ ) {
            for ( j = 0; j < Y_p->cols; j++ ) {
                elem(Y_p, i, j) = 1 - 2 * (1 / (1 + exp(-elem(U, i, j))));
            }
        }

        // compute dW = L * (BI + Y'U') * W0
        matrix_t *U_tr = m_transpose(U);
        matrix_t *dW_temp1 = m_product(Y_p, U_tr);
        m_add(dW_temp1, BI);

        matrix_t *dW = m_product(dW_temp1, W0);
        m_elem_mult(dW, L);

        // compute W = W0 + dW
        m_add(W, dW);

        // print training stats
        if ( t % F == 0 ) {
            precision_t norm = m_norm(dW);
            precision_t angle = m_angle(W0, W);

            printf("*** norm(dW) = %.4lf, angle(W0, W) = %.1lf deg\n", norm, 180 * angle / M_PI);
        }

        // cleanup
        m_free(W0);
        m_free(X_batch);
        m_free(U);
        m_free(Y_p);
        m_free(U_tr);
        m_free(dW_temp1);
        m_free(dW);
    }
}
/*
 * Kalman filter update
 *
 * P is [4,4] and holds the covariance matrix
 * R is [3,3] and holds the measurement weights
 * C is [4,3] and holds the euler to quat tranform
 * X is [4,1] and holds the estimated state as a quaterion
 * Xe is [3,1] and holds the euler angles of the estimated state
 * Xm is [3,1] and holds the measured euler angles
 */
static inline void
kalman_update(
	m_t			P,
	m_t			R,
	m_t			C,
	v_t			X,
	const v_t		Xe,
	const v_t		Xm
)
{
	m_t			T1;
	m_t			T2;
	m_t			E;
	m_t			K;
	v_t			err;
	v_t			temp;

	/* E[3,3] = C[3,4] P[4,4] C'[4,3] + R[3,3] */
	m_mult( T1, C, P, 3, 4, 4 );
	m_transpose( T2, C, 3, 4 );
	m_mult( E, T1, T2, 3, 4, 3 );
	m_add( E, R, E, 3, 3 );

	/* K[4,3] = P[4,4] C'[4,3] inv(E)[3,3] */
	m_mult( T1, P, T2, 4, 4, 3 );
	m33_inv( E, T2 );
	m_mult( K, T1, T2, 4, 3, 3 );

	/* X[4] = X[4] + K[4,3] ( Xm[3] - Xe[3] ) */
	v_sub( err, Xm, Xe, 3 );
	mv_mult( temp, K, err, 4, 3 );
	v_add( X, temp, X, 4 );

	/* P[4,4] = P[4,4] - K[4,3] C[3,4] P[4,4] */
	m_mult( T1, K, C, 4, 3, 4 );
	m_mult( T2, T1, P, 4, 4, 4 );
	m_sub( P, T2, P, 4, 4 );
}
Example #3
0
/**
 * Test matrix transpose.
 */
void test_m_transpose()
{
	precision_t data[][4] = {
		{ 16,  2,  3, 13 },
		{  5, 11, 10,  8 },
		{  9,  7,  6, 12 },
		{  4, 14, 15,  1 }
	};

	matrix_t *A = m_initialize(4, 4);
	fill_matrix_data(A, data);

	matrix_t *B = m_transpose(A);

	printf("A = \n");
	m_fprint(stdout, A);

	printf("B = A' = \n");
	m_fprint(stdout, B);

	m_free(A);
	m_free(B);
}
Example #4
0
void Vehicle::vehicle_model(veh_str *vehicl, double Sim_Time)
{
  	//char dummy[256];
  	double dp,dr,ds;
  	//double dp1;
  	double u[3];
  	static double u_old,old_phi,old_theta,old_omegac;
  	double heading_rads;
  	double head_err, depth_err, pitch_err, prop_err;
  	static double cosomega, sinomega;
  	static double costheta, sintheta, tantheta;
  	static double cosphi, sinphi;
  	static double rb2t[9];    //(3,3)
  	static double rt2b[9];    //(3,3)

  	double *pos;
  	double *ang;
  	double *vect;

  	double dpos[3];
  	double dang[3];
  	double dvect[6];

  	double dvec1[6];
  	double dvec2[6];
  	double dvec3[6];
  	double dvec4[6];
  	double dxth;
  	double dxuv[2];
  	double dxu1[2];
  	double dxu2[2];
   int i;

  	(*vehicl).phi = (*vehicl).phi*PI/180;       // Wei
	(*vehicl).theta = (*vehicl).theta*PI/180;

  	if (init_flag == 1) {
  		m_invert(Mhinv,Mh,3);
      m_mul(Ah,Mhinv,Ch,3,3,3);
      m_mul(Bh,Mhinv,Dh,3,3,1);

      m_invert(Mdinv,Md,4);
      m_mul(Ad,Mdinv,Cd,4,4,4);
      m_mul(Bd,Mdinv,Dd,4,4,1);

      memset(A, 0, 36*sizeof(double));
      A[0] = Xu/(mm - Xud);        //(0,0)
   	A[7] = Ah[0];                //(1,1)=(0,0)
      A[11] = Ah[2];               //(1,5)=(0,2)
      A[14] = Ad[0];               //(2,2)=(0,0)
      A[16] = Ad[1];               //(2,4)=(0,1)
      A[21] = Kp/(Ixx - Kpd);      //(3,3)
      A[23] = (*vehicl).u*mm*zg;   //(3,5)
      A[26] = Ad[4];               //(4,2)=(1,0)
      A[28] = Ad[5];               //(4,4)=(1,1)
      A[31] = Ah[6];               //(5,1)=(2,0)
      A[35] = Ah[8];               //(5,5)=(2,2)

      memset(B, 0, 18*sizeof(double));
      B[0] = Xdp/(mm-Xud);         //(0,0)
      B[1] = Xdr/(mm-Xud);         //(0,1)
      B[2] = Xds/(mm-Xud);         //(0,2)
      B[4] = Bh[0];                //(1,1)=(0,0)
      B[8] = Bd[0];                //(2,2)=(0,0)
      B[9] = Kdp/(Ixx-Kpd);        //(3,0)
      B[14] = Bd[1];               //(4,2)=(1,0)
      B[16] = Bh[2];               //(5,1)=(2,0)

      memset(C, 0, 18*sizeof(double));
      C[5] = Ah[1];                //(1,2)=(0,1)
      C[7] = Ad[3];                //(2,1)=(0,3)
      C[9] = Kphi/(Ixx-Kpd);       //(3,0)
      C[13] = Ad[7];               //(4,1)=(1,3)
      C[17] = Ah[7];               //(5,2)=(2,1)

      for(i = 0; i < 16; i++) {
	 		Cd1[i]=Cd[i];
  	   }

      for(i = 0; i < 9; i++) {
	 		Ch1[i]=Ch[i];
  	   }

     	d2r = PI/180.0;

     	rw2a[0] = 1;                    //(0,0)
     	rw2a[3] = 0;                    //(1,0)
     	rw2a[6] = 0;                    //(2,0)

     	u_old = 100;
     	old_phi = 100;
     	old_theta = 100;
     	old_omegac = 100;
	}

   if(abs((int)((*vehicl).u - u_old))>0.2){
   	u_old = (*vehicl).u;
	   Cd1[1] = (*vehicl).u*mm + Zq;       //(0,1)
 		Cd1[4] = (*vehicl).u*(-mm)*xg + Mq; //(1,1)
  		Cd1[11] = -(*vehicl).u;             //(2,3)

  		Ch1[2] = Yr - (*vehicl).u*mm;       //(0,2)
  		Ch1[5] = Nr - (*vehicl).u*mm*xg;    //(1,2)

 		m_mul(Ah,Mhinv,Ch1,3,3,3);
  		m_mul(Ad,Mdinv,Cd1,4,4,4);

  		A[23] = (*vehicl).u*mm*zg;        //(3,5)
  		A[35] = Ah[8];                    //(5,5)=(2,2)
  		A[16] = Ad[1];                    //(2,4)=(0,1)
  		A[28] = Ad[5];                    //(4,4)=(1,1)
   } 

  	heading_rads = (*vehicl).omega*d2r;

   	old_phi =  (int)((*vehicl).phi);
   	old_theta = (*vehicl).theta;
   	old_omegac = (*vehicl).omega;

  		cosomega = cos(heading_rads);
  		costheta = cos((*vehicl).theta); //wei
  		sinomega = sin(heading_rads);
  		sintheta = sin((*vehicl).theta);
  		cosphi   = cos((*vehicl).phi);
  		sinphi   = sin((*vehicl).phi);
  		tantheta = tan((*vehicl).theta);

  		rt2b[0] = cosomega*costheta;               //(0,0)
  		rt2b[1] = sinomega*costheta;               //(0,1)
  		rt2b[2] = -sintheta;                       //(0,2)
  		rt2b[3] = -sinomega*cosphi+cosomega*sintheta*sinphi;       //(1,0)
  		rt2b[4] = cosomega*cosphi+sinomega*sintheta*sinphi;        //(1,1)
  		rt2b[5] = costheta*sinphi;                                 //(1,2)
  		rt2b[6] = sinomega*sinphi+cosomega*sintheta*cosphi;        //(2,0)
  		rt2b[7] = -cosomega*sinphi+sinomega*sintheta*cosphi;       //(2,1)
  		rt2b[8] = costheta*cosphi;                                 //(2,2)

  		m_transpose(rb2t,rt2b,3,3);

  		rw2a[1] = sinphi*tantheta;                                //(0,1)
  		rw2a[2] = cosphi*tantheta;                                //(0,2)
  		rw2a[4] = cosphi;                                         //(1,1)
  		rw2a[5] = -sinphi;                                        //(1,2)
  		rw2a[7] = sinphi/costheta;                                //(2,1)
  		rw2a[8] = cosphi/costheta;                                //(2,2)

  	pos  = &((*vehicl).x);
  	ang  = &((*vehicl).phi);
  	vect = &((*vehicl).u);

  //---------------------------heading control---------------------------------

  	head_err = ((vehicl->omega_c) - (vehicl->omega));			// degrees
  	head_err = head_err*d2r;											// radians
  	while(head_err>PI)
  	   head_err = head_err - 2.0*PI;

	while(head_err<-PI)
   	head_err = head_err + 2.0*PI;

  	dr = head_err*-0.2;                                     // Calculate dr

  //--------------------------------depth control-----------------------------

  	depth_err = (*vehicl).z_c - (*vehicl).z;
  	(*vehicl).theta_c = (-0.772*depth_err);

  	if((*vehicl).theta_c>0.5)
  	  	(*vehicl).theta_c = 0.5;
  	if((*vehicl).theta_c<-0.5)
  		(*vehicl).theta_c = -0.5;

  	pitch_err = ((*vehicl).theta_c - (*vehicl).theta);
  	ds = ((*vehicl).xth)*Cth + Dth*pitch_err;         // Calculate ds

  	if(ds>0.8)                                    // saturation
  	  	ds = 0.8;
  	if(ds<-0.8)
     ds = -0.8;

  //-----------------------------propulsion control---------------------------

  	prop_err = (*vehicl).vel_c - (*vehicl).u;
  	dp = Cu[0]*(*vehicl).xu1 + Cu[1]*(*vehicl).xu2 + prop_err*Du; // Calculate dp

  	u[0] = dp;
  	u[1] = dr;
  	u[2] = ds;

  	m_mul(dpos,rb2t,vect,3,3,1);
  	m_mul(dang,rw2a,(vect+3),3,3,1);

  	m_mul(dvec1,A,vect,6,6,1);
  	m_mul(dvec2,B,u,6,3,1);
  	m_mul(dvec3,C,ang,6,3,1);
  	m_add(dvec4,dvec1,dvec2,6,1);

  	m_add(dvect,dvec3,dvec4,6,1);

  	m_mul(dxu1,Au,&((*vehicl).xu1),2,2,1);
  	m_muls(dxu2,Bu,prop_err,2,1);
  	m_add(dxuv,dxu1,dxu2,2,1);

  	dxth = (Ath*((*vehicl).xth) + Bth*pitch_err);       // jay
  	(*vehicl).xth += dxth*dt;

   /*
  	for (i=0;i<3;i++) {    // jay
	 	pos[i] += dpos[i]*dt;
  	}
   */
   pos[0] += dpos[0]*dt;      // x
   pos[1] += (-1)*dpos[1]*dt; // y, invert because of axis flip
   pos[2] += dpos[2]*dt;      // z
   //

  	for (i=0;i<2;i++){        //jay
  	 	ang[i] += dang[i]*dt;  //Wei
  	}
  	ang[2] += dang[2]*dt*180.0/PI;

   (*vehicl).phi = ang[0]*180/PI;       // Wei
	(*vehicl).theta = ang[1]*180/PI;
   (*vehicl).omega = ang[2];

  	for (int j=0;j<6;j++){
  		vect[j] += dvect[j]*dt;
  	}

  	(*vehicl).xu1 += dxuv[0]*dt;
  	(*vehicl).xu2 += dxuv[1]*dt;

	//--------------------------------------------------------------------------

  	if(((*vehicl).src_find_tm) > Sim_Time){      // if not source found
  		(*vehicl).dsf   += ((*vehicl).u)*(dt);}	// integrated path length to source
  	if(((*vehicl).plm_find_tm) > Sim_Time){      // if not plume found
  		(*vehicl).dpf   += ((*vehicl).u)*(dt);}	// integrated path length to plume
  	if(!((*vehicl).src_fnd_flg)){      			   // if src fnd has not been declared
  		(*vehicl).dsd   += ((*vehicl).u)*(dt);}	// integrated path length to plume

  	while((*vehicl).omega >= 180.0)
  		(*vehicl).omega = (*vehicl).omega - 360.0;
  	while((*vehicl).omega < -180.0)
   	(*vehicl).omega = (*vehicl).omega + 360.0;
}
/**
 *  ahrs_step() takes the values from the IMU and produces the
 * new estimated attitude.
 */
void
ahrs_step(
	v_t			angles_out,
	f_t			dt,
	f_t			p,
	f_t			q,
	f_t			r,
	f_t			ax,
	f_t			ay,
	f_t			az,
	f_t			heading
)
{
	m_t			C;

	m_t			A;
	m_t			AT;
	v_t			X_dot;
	m_t			temp;

	v_t			Xm;
	v_t			Xe;

	/* Construct the quaternion omega matrix */
	rotate2omega( A, p, q, r );

	/* X_dot = AX */
	mv_mult( X_dot, A, X, 4, 4 );

	/* X += X_dot dt */
	v_scale( X_dot, X_dot, dt, 4 );

	v_add( X, X_dot, X, 4 );
	v_normq( X, X );

/*
	printf( "X =" );
	Vprint( X, 4 );
	printf( "\n" );
*/
	
	/* AT = transpose(A) */
	m_transpose( AT, A, 4, 4 );

	/* P = A * P * AT + Q */
	m_mult( temp, A, P, 4, 4, 4 );
	m_mult( P, temp, AT, 4, 4, 4 );
	m_add( P, Q, P, 4, 4 );
	
	
	compute_c( C, X );

	/* Compute the euler angles of the measured attitude */
	accel2euler(
		Xm,
		ax,
		ay,
		az,
		heading
	);

	/*
	 * Compute the euler angles of the estimated attitude
	 * Xe = quat2euler( X )
	 */
	quat2euler( Xe, X );

	/* Kalman filter update */
	kalman_update(
		P,
		R,
		C,
		X,
		Xe,
		Xm
	);

	/* Estimated attitude extraction */
	quat2euler( angles_out, X );
}
Example #6
0
void transpose_matrix(matrix_t *m)
{
    print_matrix("Original Matrix", m);
    m_transpose(m);
    print_matrix("Transposed Matrix", m);
}