예제 #1
0
void kalman2(const float *A, const float *Q, const float *R, float *x, const float *z, float *P) {
    float x_apriori[2], P_apriori[4], At[4];
    float K[4];
    float tmp1[4], tmp2[4];
    
    // x_apriori = A*x
    mat_mul(A, x, x_apriori, 2, 2, 1);
    
    // P_apriori = A*P_aposteriori*At + Q
    mat_mul(A, P, tmp1, 2, 2, 2);
    transpose(A, At, 2, 2);
    mat_mul(tmp1, At, tmp2, 2, 2, 2);
    mat_add(tmp2, Q, P_apriori, 2, 2);
    
    // K = P_apriori(P_apriori + R)^-1
    mat_add(P_apriori, R, tmp1, 2, 2);
    mat2_inv(tmp1, tmp2);
    mat_mul(P_apriori, tmp2, K, 2, 2, 2);
    
    // x_aposteriori = x_apriori + K(z - x_apriori)
    mat_sub(z, x_apriori, tmp1, 2, 1);
    mat_mul(K, tmp1, tmp2, 2, 2, 1);
    mat_add(x_apriori, tmp2, x, 2, 1);
    
    // P_aposteriori = (I - K)P_apriori
    mat_sub(I, K, tmp1, 2, 2);
    mat_mul(tmp1, P_apriori, P, 2, 2, 2);
}
예제 #2
0
파일: pos.c 프로젝트: Aerobota/PenguPilot
static void kalman_correct(kalman_t *kf, float pos, float speed)
{
   /* update H matrix: */
   kf->H.me[1][1] = 1.0f * (kf->use_speed && speed != 0.0f);
   kf->z.ve[0] = pos;
   kf->z.ve[1] = speed;

   /* K = P * HT * inv(H * P * HT + R) */
   mat_mul(&kf->T0, &kf->H, &kf->P);   // T0 = H * P
   mmtr_mul(&kf->T1, &kf->T0, &kf->H); // T1 = T0 * HT
   mat_add(&kf->T0, &kf->T1, &kf->R);  // T0 = T1 + R
   mat_inv(&kf->T1, &kf->T0);          // T1 = inv(T0)
   mmtr_mul(&kf->T0, &kf->P, &kf->H);  // T0 = P * HT
   mat_mul(&kf->K, &kf->T0, &kf->T1);  // K = T0 * T1

   /* x = x + K * (z - H * x) */
   mat_vec_mul(&kf->t0, &kf->H, &kf->x);  // t0 = H * x
   vec_sub(&kf->t1, &kf->z, &kf->t0);     // t1 = z - t0
   mat_vec_mul(&kf->t0, &kf->K, &kf->t1); // t0 = K * t1
   vec_add(&kf->x, &kf->x, &kf->t0);      // x = x + t0

   /* P = (I - K * H) * P */
   mat_mul(&kf->T0, &kf->K, &kf->H);  // T0 = K * H
   mat_sub(&kf->T1, &kf->I, &kf->T0); // T1 = I - T0
   mat_mul(&kf->T0, &kf->T1, &kf->P); // T0 = T1 * P
   mat_copy(&kf->P, &kf->T0);         // P = T0
}
double second_subproblem_obj (double ** ytwo, double ** z, double ** wtwo, double rho, int N, double* lambda) {

    double ** temp = mat_init (N, N);
    double ** difftwo = mat_init (N, N);
    mat_zeros (difftwo, N, N);

    // reg = 0.5 * sum_k max_n | w_nk |  -> group-lasso
    mat_zeros (temp, N, N);
    double * maxn = new double [N];
    for (int i = 0; i < N; i ++) { // Ian: need initial
        maxn[i] = -INF;
    }

    for (int i = 0; i < N; i ++) {
        for (int j = 0; j < N; j ++) {
            if (wtwo[i][j] > maxn[j])
                maxn[j] = wtwo[i][j];
        }
    }
    double sumk = 0.0;
    for (int i = 0; i < N; i ++) {
        sumk += lambda[i]*maxn[i];
    }
    double group_lasso = sumk;

    // sum2 = y_2^T dot (w_2 - z) -> linear
    mat_zeros (temp, N, N);
    mat_sub (wtwo, z, difftwo, N, N);
    mat_tdot (ytwo, difftwo, temp, N, N);
    double sum2 = mat_sum (temp, N, N);

    // sum3 = 0.5 * rho * || w_2 - z_2 ||^2 -> quadratic mat_zeros (temp, N, N);
    mat_sub (wtwo, z, temp, N, N);
    double sum3 = 0.5 * rho * mat_norm2 (temp, N, N);

    mat_free (temp, N, N);

    // ouput values of each components
#ifdef BLOCKWISE_DUMP
    cout << "[Blockwise] (group_lasso, linear, quadratic) = ("
         << group_lasso << ", " << sum2 << ", " << sum3
         << ")" << endl;
#endif

    //cerr << group_lasso << ", " << sum2 << ", " << sum3 << endl;
    return group_lasso + sum2 + sum3;
}
int main(void) 
{
  Item x = 5, y = 2, x2 = 6, y2 = 3;
  mat m1, m2, k1, k2;
  int i, j;

  printf("\nItems: ");
  item_print(x);
  printf(" ");
  item_print(y);
  printf("\n");
  printf("Item Addition: ");
  item_print(item_add(x, y));
  printf("\n");
  printf("Item Multiplication: ");
  item_print(item_mul(x, y));
  printf("\n");
  printf("Item Substraction: ");
  item_print(item_sub(x, y));
  printf("\n");
  printf("Item Division: ");
  item_print(item_div(x, y));
  printf("\n\n");
  m1 = mat_create(3, 2);
  m2 = mat_create(2, 3);
  k1 = mat_create(2, 2);
  k2 = mat_create(2, 2);
  for (i = 0; i < mat_rows(m1); i++)
    for (j = 0; j < mat_cols(m1); j++)
      mat_add_elem(m1, i, j, x);
  for (i = 0; i < mat_rows(m2); i++)
    for (j = 0; j < mat_cols(m2); j++)
      mat_add_elem(m2, i, j, y);
  for (i = 0; i < mat_rows(k1); i++)
    for (j = 0; j < mat_cols(k1); j++)
      {
  	mat_add_elem(k1, i, j, x2);
  	mat_add_elem(k2, i, j, y2);
      }
  printf("k1 Matrix: \n");
  mat_print(k1);
  printf("k2 Matrix: \n");
  mat_print(k2);
  printf("Addition: \n");
  mat_print(mat_add(k1, k2));
  printf("Substraction: \n");
  mat_print(mat_sub(k1, k2));
  printf("m1 Matrix: \n");
  mat_print(m1);
  printf("m2 Matrix: \n");
  mat_print(m2);
  printf("Multiplication: \n");
  mat_print(mat_mul(m1, m2));
  return 0;
}
double first_subproblm_obj (double ** dist_mat, double ** yone, double ** zone, double ** wone, double rho, int N) {
    double ** temp = mat_init (N, N);
    double ** diffone = mat_init (N, N);
    mat_zeros (diffone, N, N);

    // sum1 = 0.5 * sum_n sum_k (w_nk * d^2_nk) -> loss
    mat_zeros (temp, N, N);
    mat_times (wone, dist_mat, temp, N, N);
    double sum1 = 0.5 * mat_sum (temp, N, N);

    // sum2 = y_1^T dot (w_1 - z) -> linear
    mat_zeros (temp, N, N);
    mat_sub (wone, zone, diffone, N, N); // temp = w_1 - z_1
    mat_tdot (yone, diffone, temp, N, N);
    double sum2 = mat_sum (temp, N, N);

    // sum3 = 0.5 * rho * || w_1 - z_1 ||^2 -> quadratic
    mat_zeros (temp, N, N);
    mat_sub (wone, zone, temp, N, N);
    double sum3 = 0.5 * rho * mat_norm2 (temp, N, N);

    // sum4 = r dot (1 - sum_k w_nk) -> dummy
    double * temp_vec = new double [N];
    mat_sum_row (wone, temp_vec, N, N);
    double dummy_penalty = 0.0;
    for (int i = 0; i < N; i ++) {
        dummy_penalty += r*(1 - temp_vec[i]);
    }
    double total = sum1+sum2+sum3+dummy_penalty;
#ifdef FRANK_WOLFE_DUMP
    cout << "[Frank_wolfe] (loss, linear, quadratic, dummy, total) = ("
         << sum1 << ", " << sum2 << ", " << sum3 << ", " << dummy_penalty << ", " << total
         <<  ")" << endl;
#endif

    mat_free (temp, N, N);
    mat_free (diffone, N, N);
    delete [] temp_vec;

    return total;
}
예제 #6
0
void EcefToEnu(MATRIX outputVector, MATRIX inputVector, MATRIX position)
{

  int i;
  double lat, lon;
  MATRIX C, ned, ref_position;
  MATRIX position_copy, delta_pos;

  C = mat_creat(3,3,ZERO_MATRIX);
  ref_position = mat_creat(3,1,ZERO_MATRIX);
  delta_pos = mat_creat(3,1,ZERO_MATRIX);
  position_copy = mat_creat(MatRow(position),MatCol(position),ZERO_MATRIX);
  mat_copy(position, position_copy);

  lat = position[0][0];
  lon = position[1][0];

  LatLonAltToEcef(ref_position,position_copy);

  mat_sub(inputVector,ref_position,delta_pos);

  C[0][0] = -sin(lon);
  C[0][1] = cos(lon);
  C[0][2] = 0;

  C[1][0] = -sin(lat)*cos(lon);
  C[1][1] = -sin(lat)*sin(lon);
  C[1][2] = cos(lat);

  C[2][0] = cos(lat)*cos(lon);
  C[2][1] = cos(lat)*sin(lon);
  C[2][2] = sin(lat);

  ned = mat_creat(MatRow(C),MatCol(delta_pos),ZERO_MATRIX);
  mat_mul(C,delta_pos,ned);

  for (i = 0; i < 3; i++)
    {
      outputVector[i][0] = ned[i][0];
    }

  mat_free(ned);
  mat_free(C);
  mat_free(delta_pos);
  mat_free(ref_position);
  mat_free(position_copy);

}
예제 #7
0
파일: layout.c 프로젝트: ekg/mars
static double stress(mat z, mat dij, int* anchors, int power)
{
    int i,j;
    double sum;
    mat d = some_pairs_dist(z,anchors,dij->r);
    mat_sub(d,dij);
    for(i = 0; i < d->r; i++) {
        for(j = 0; j < d->c; j++) {
            d->m[mindex(i,j,d)] = pow(d->m[mindex(i,j,d)],2);
            if(dij->m[mindex(i,j,d)] != 0) {
                d->m[mindex(i,j,d)] *= 1.0 / pow(dij->m[mindex(i,j,d)], power);
            }   
        }
    }
    sum = mat_accu(d);
    mat_free(d);
    return sum;
}
예제 #8
0
파일: ekf.c 프로젝트: 1bitsquared/paparazzi
void ekf_filter_update(struct ekf_filter* filter, double *y) {

  /* update

     E = H * P * H' + R
     K = P * H' * inv(E)
     P = P - K * H * P
     X = X + K * err

  */
  double err;
  int n = filter->state_dim;
  int m = filter->measure_dim;
  filter->mfun(y, &err, filter->X, filter->H);

  /*  E = H * P * H' + R */
  mat_mult(m, n, n, filter->tmp1, filter->H, filter->P);
  mat_transpose(m, n, filter->tmp2, filter->H);
  mat_mult(m, n, m, filter->tmp3, filter->tmp1, filter->tmp2);
  mat_add(m, m, filter->E, filter->tmp3, filter->R);

  /*  K = P * H' * inv(E) */
  mat_transpose(m, n, filter->tmp1, filter->H);
  mat_mult(n, n, m, filter->tmp2, filter->P, filter->tmp1);
  if (filter->measure_dim != 1) { printf("only dim 1 measure implemented for now\n"); exit(-1);}
  mat_scal_mult(n, m, filter->K, 1./filter->E[0], filter->tmp2);

  /* P = P - K * H * P */
  mat_mult(n, m, n, filter->tmp1, filter->K, filter->H);
  mat_mult(n, n, n, filter->tmp2, filter->tmp1, filter->P);
  mat_sub(n, n, filter->P, filter->P, filter->tmp2);

  /*  X = X + err * K */
  mat_add_scal_mult(n, m, filter->X, filter->X, err, filter->K);

}
void cvx_clustering ( double ** dist_mat, int fw_max_iter, int max_iter, int D, int N, double* lambda, double ** W) {
    // parameters
    double alpha = 0.1;
    double rho = 1;
    // iterative optimization
    double error = INF;
    double ** wone = mat_init (N, N);
    double ** wtwo = mat_init (N, N);
    double ** yone = mat_init (N, N);
    double ** ytwo = mat_init (N, N);
    double ** z = mat_init (N, N);
    double ** diffzero = mat_init (N, N);
    double ** diffone = mat_init (N, N);
    double ** difftwo = mat_init (N, N);
    mat_zeros (yone, N, N);
    mat_zeros (ytwo, N, N);
    mat_zeros (z, N, N);
    mat_zeros (diffzero, N, N);
    mat_zeros (diffone, N, N);
    mat_zeros (difftwo, N, N);

    int iter = 0; // Ian: usually we count up (instead of count down)
    while ( iter < max_iter ) { // stopping criteria

#ifdef SPARSE_CLUSTERING_DUMP
        cout << "it is place 0 iteration #" << iter << ", going to get into frank_wolfe"  << endl;
#endif
        // mat_set (wone, z, N, N);
        // mat_set (wtwo, z, N, N);
        // mat_zeros (wone, N, N);
        // mat_zeros (wtwo, N, N);
        // STEP ONE: resolve w_1 and w_2
        frank_wolf (dist_mat, yone, z, wone, rho, N, fw_max_iter); // for w_1
#ifdef SPARSE_CLUSTERING_DUMP
        cout << "norm2(w_1) = " << mat_norm2 (wone, N, N) << endl;
#endif

        blockwise_closed_form (ytwo, z, wtwo, rho, lambda, N);  // for w_2
#ifdef SPARSE_CLUSTERING_DUMP
        cout << "norm2(w_2) = " << mat_norm2 (wtwo, N, N) << endl;
#endif

        // STEP TWO: update z by averaging w_1 and w_2
        mat_add (wone, wtwo, z, N, N);
        mat_dot (0.5, z, z, N, N);
#ifdef SPARSE_CLUSTERING_DUMP
        cout << "norm2(z) = " << mat_norm2 (z, N, N) << endl;
#endif

        // STEP THREE: update the y_1 and y_2 by w_1, w_2 and z

        mat_sub (wone, z, diffone, N, N);
        double trace_wone_minus_z = mat_norm2 (diffone, N, N);
        mat_dot (alpha, diffone, diffone, N, N);
        mat_add (yone, diffone, yone, N, N);

        mat_sub (wtwo, z, difftwo, N, N);
        //double trace_wtwo_minus_z = mat_norm2 (difftwo, N, N);
        mat_dot (alpha, difftwo, difftwo, N, N);
        mat_add (ytwo, difftwo, ytwo, N, N);

        // STEP FOUR: trace the objective function
        if (iter % 100 == 0) {
            error = overall_objective (dist_mat, lambda, N, z);
            // get current number of employed centroid
#ifdef NCENTROID_DUMP
            int nCentroids = get_nCentroids (z, N, N);
#endif
            cout << "[Overall] iter = " << iter
                 << ", Overall Error: " << error
#ifdef NCENTROID_DUMP
                 << ", nCentroids: " << nCentroids
#endif
                 << endl;
        }
        iter ++;
    }

    // STEP FIVE: memory recollection
    mat_free (wone, N, N);
    mat_free (wtwo, N, N);
    mat_free (yone, N, N);
    mat_free (ytwo, N, N);
    mat_free (diffone, N, N);
    mat_free (difftwo, N, N);
    // STEP SIX: put converged solution to destination W
    mat_copy (z, W, N, N);
}
void blockwise_closed_form (double ** ytwo, double ** ztwo, double ** wtwo, double rho, double* lambda, int N) {

    // STEP ONE: compute the optimal solution for truncated problem
    double ** wbar = mat_init (N, N);
    mat_zeros (wbar, N, N);
    mat_dot (rho, ztwo, wbar, N, N); // wbar = rho * z_2
    mat_sub (wbar, ytwo, wbar, N, N); // wbar = rho * z_2 - y_2
    mat_dot (1.0/rho, wbar, wbar, N, N); // wbar = (rho * z_2 - y_2) / rho

    // STEP TWO: find the closed-form solution for second subproblem
    for (int j = 0; j < N; j ++) {
        // 1. bifurcate the set of values
        vector< pair<int,double> > alpha_vec;
        for (int i = 0; i < N; i ++) {
            double value = wbar[i][j];
            /*if( wbar[i][j] < 0 ){
              cerr << "wbar[" << i << "][" << j << "]" << endl;
              exit(0);
              }*/
            alpha_vec.push_back (make_pair(i, abs(value)));
        }
        // 2. sorting
        std::sort (alpha_vec.begin(), alpha_vec.end(), pairComparator);
        /*
           for (int i = 0; i < N; i ++) {
           if (alpha_vec[i].second != 0)
           cout << alpha_vec[i].second << endl;
           }
           */
        // 3. find mstar
        int mstar = 0; // number of elements support the sky
        double separator;
        double max_term = -INF, new_term;
        double sum_alpha = 0.0;
        for (int i = 0; i < N; i ++) {
            sum_alpha += alpha_vec[i].second;
            new_term = (sum_alpha - lambda[j]) / (i + 1.0);
            if ( new_term > max_term ) {
                separator = alpha_vec[i].second;
                max_term = new_term;
                mstar = i;
            }
        }
        // 4. assign closed-form solution to wtwo
        if( max_term < 0 ) {
            for(int i=0; i<N; i++)
                wtwo[i][j] = 0.0;
            continue;
        }
        for (int i = 0; i < N; i ++) {
            // harness vector of pair
            double value = wbar[i][j];
            if ( abs(value) >= separator ) {
                wtwo[i][j] = max_term;
            } else {
                // its ranking is above m*, directly inherit the wbar
                wtwo[i][j] = max(wbar[i][j],0.0);
            }
        }
    }
    // compute value of objective function
    double penalty = second_subproblem_obj (ytwo, ztwo, wtwo, rho, N, lambda);
    // report the #iter and objective function
    /*cout << "[Blockwise] second_subproblem_obj: " << penalty << endl;
      cout << endl;*/

    // STEP THREE: recollect temporary variable - wbar
    mat_free (wbar, N, N);
}
예제 #11
0
extern void get_guidance(double time, struct sensordata *sensorData_ptr, struct nav *navData_ptr, struct control *controlData_ptr, struct mission *missionData_ptr){       
	if (time>0.05){
    
	#ifdef AIRCRAFT_THOR
		controlData_ptr->ias_cmd = 17;				//Trim airspeed (m/s)
	#endif
	#ifdef AIRCRAFT_TYR
		controlData_ptr->ias_cmd = 17;				//Trim airspeed (m/s)
	#endif
	#ifdef AIRCRAFT_FASER
		controlData_ptr->ias_cmd = 23;
	#endif
	#ifdef AIRCRAFT_IBIS
		controlData_ptr->ias_cmd = 23;
	#endif
	#ifdef AIRCRAFT_BALDR
		controlData_ptr->ias_cmd = 23;
	#endif


	// Initialization of algorithm and variables	
    if (guide_init==0)  // init variables
    {
        pos_lla     = mat_creat(3,1,ZERO_MATRIX);   // LAT, LON, alt vector
        pos_ecef    = mat_creat(3,1,ZERO_MATRIX);   // ECEF position vector
        pos_ecef0   = mat_creat(3,1,ZERO_MATRIX);   // ECEF position vector of initial point
        v_ned       = mat_creat(3,1,ZERO_MATRIX);   // vector of NED velocity
        pos_ned     = mat_creat(3,1,ZERO_MATRIX);   // vector of NED position
        tmp31       = mat_creat(3,1,ZERO_MATRIX);   // temporary 3x1 vector
        T_ecef2ned  = mat_creat(3,3,ZERO_MATRIX);   // transformation matrix from ECEF to NED
        WP_goal     = mat_creat(2,1,ZERO_MATRIX);   // Vector of North / East goal coordinates (actaul waypoint)       
        guide_init=1;                               // guidance initialization finished
    }	    
    
    
    if (guide_start==0)
    {
        pos_lla[0][0]=navData_ptr->lat;
        pos_lla[1][0]=navData_ptr->lon;
        pos_lla[2][0]=navData_ptr->alt;
        
        // transform starting point from LLA to ECEF
        LatLonAltToEcef2(pos_ecef0, pos_lla);
        
        // transformation matrix for LaunchPoint ECEF |--> NED for initial point
        T_ecef2ned[0][0] = -sin(pos_lla[0][0])*cos(pos_lla[1][0]); T_ecef2ned[0][1] = -sin(pos_lla[0][0])*sin(pos_lla[1][0]); T_ecef2ned[0][2] =  cos(pos_lla[0][0]);
        T_ecef2ned[1][0] = -sin(pos_lla[1][0]);                    T_ecef2ned[1][1] =  cos(pos_lla[1][0]);                    T_ecef2ned[1][2] =  0.0;
        T_ecef2ned[2][0] = -cos(pos_lla[0][0])*cos(pos_lla[1][0]); T_ecef2ned[2][1] = -cos(pos_lla[0][0])*sin(pos_lla[1][0]); T_ecef2ned[2][2] = -sin(pos_lla[0][0]);
        
        //save next waypoint coordinates
        WP_goal[0][0]=waypoints[nextwaypoint][0];
        WP_goal[1][0]=waypoints[nextwaypoint][1];       
        
        guide_start=1;
    }
    else
        cpsi=0; //to handle SIL initial zero data
    
    // current vehicle position/vel (computed at every iteration)
    pos_lla[0][0]=navData_ptr->lat;
    pos_lla[1][0]=navData_ptr->lon;
    pos_lla[2][0]=navData_ptr->alt;
    v_ned[0][0] = navData_ptr->vn;
    v_ned[1][0] = navData_ptr->ve;
    v_ned[2][0] = navData_ptr->vd;
    // azimuth angle from ground speed
    psi=atan2(v_ned[1][0], v_ned[0][0]);
    
    // Transfrom the difference of actual coordinates from the starting point into NED frame
    LatLonAltToEcef2(pos_ecef, pos_lla);
    mat_sub(pos_ecef, pos_ecef0, tmp31);
    mat_mul(T_ecef2ned, tmp31, pos_ned);
    
    // Calculate waypoint distance from actual point
    d2WP=distance2waypoint(WP_goal, pos_ned);
    
    // change of target waypoint: check if vehicle is within x meters of the target waypoint
    if ((d2WP < WPTOL) && (guide_start==1)) {
        if(nextwaypoint == numofwaypoints-1) nextwaypoint = 0; // change back to first waypoint
        else  nextwaypoint++;
        
        // select new waypoint parameters        
        WP_goal[0][0] = waypoints[nextwaypoint][0];
        WP_goal[1][0] = waypoints[nextwaypoint][1];
        
        pinit=0;
    }
    
    // actual aircraft position
    xA=pos_ned[0][0];   // North
    yA=pos_ned[1][0];   // East
    
    // Target coordinates
    xT=WP_goal[0][0];
    yT=WP_goal[1][0];
    
    if (pinit==0)   // decide about tracking method
    {
        if (sensorData_ptr->adData_ptr->ias_filt>10)   // only for SIL because nonzero initial conditions
        {
            psiT=atan2(yT-yA, xT-xA);    // Aircraft target azimuth angle
            // azimuth angle correction if required:
            if (fabs(psiT-wraparound(psi))>PI)
                psiT=psiT+mysign(wraparound(psi))*PI2;
            
            Rt=pow(controlData_ptr->ias_cmd, 2)/g/tan(PHI0);  // possible turn radius
            // center of circle:
            dpsi=mysign(psiT-wraparound(psi))*90*D2R;            
            xC=xA+Rt*cos(psi+dpsi);
            yC=yA+Rt*sin(psi+dpsi);
            // check feasibility
            R2=sqrt(pow(WP_goal[0][0]-xC, 2)+pow(WP_goal[1][0]-yC, 2)); // distance of waypoint from circle center
            if (R2<Rt+FTOL)   // infeasible problem turn into opposite direction
            {
                cpsi=-dpsi*4;
                lc=8;
                pinit=1;
            }
            else    // feasible problem, go to waypoint
            {
                cpsi=psiT-wraparound(psi);
                lc=0;
                pinit=1;
            }
        } // end if nonzero velocity
    }   // end decide about tracking method
   
    if (lc==8)  // check if the algorithm can change to circular segment tracking
    {
        // calculate actual circle parameters
        Rt=pow(controlData_ptr->ias_cmd, 2)/g/tan(PHI0);  // turn radius
        // center of circle:
        psiT=atan2(yT-yA, xT-xA);
        // azimuth angle correction if required:
        if (fabs(psiT-wraparound(psi))>PI)
            psiT=psiT+mysign(wraparound(psi))*PI2;
        // center of circle:
        dpsi=mysign(psiT-wraparound(psi))*90*D2R;       
        xC=xA+Rt*cos(psi+dpsi);
        yC=yA+Rt*sin(psi+dpsi);
        // check feasibility
        R2=sqrt(pow(WP_goal[0][0]-xC, 2)+pow(WP_goal[1][0]-yC, 2));
        if (R2>=Rt+FTOL)   // fasible problem, track circle
        {
            cpsi=psiT-wraparound(psi);
            lc=0;
        }
        else
            cpsi=-dpsi*4;
    }
    else if (lc==0) {
        psiT=atan2(yT-yA, xT-xA);
        // azimuth angle correction if required:
        if (fabs(psiT-wraparound(psi))>PI)
            psiT=psiT+mysign(wraparound(psi))*PI2;
        cpsi=psiT-wraparound(psi);
    }
    
    // send out control command
    controlData_ptr->psi_cmd=cpsi;
    
    // send out diagnostic variable
    controlData_ptr->r_cmd=((nextwaypoint+1)*10+lc);
    }
}
예제 #12
0
파일: mat_util.c 프로젝트: RobotLearning/SL
void expm(Matrix A, Matrix B, double h) {

	static int firsttime = TRUE;
	static Matrix M;
	static Matrix M2;
	static Matrix M3;
	static Matrix D;
	static Matrix N;

	if (firsttime) {
		firsttime = FALSE;
		M = my_matrix(1,3*N_DOFS,1,3*N_DOFS);
		M2 = my_matrix(1,3*N_DOFS,1,3*N_DOFS);
		M3 = my_matrix(1,3*N_DOFS,1,3*N_DOFS);
		D = my_matrix(1,3*N_DOFS,1,3*N_DOFS);
		N = my_matrix(1,3*N_DOFS,1,3*N_DOFS);
	}

	int norm = 0;
	double c = 0.5;
	int q = 6; // uneven p-q order for Pade approx.
	int p = 1;
	int i,j,k;

	// Form the big matrix
	mat_mult_scalar(A, h, A);
	mat_equal_size(A, 2*N_DOFS, 2*N_DOFS, M);
	for (i = 1; i <= 2*N_DOFS; ++i) {
		for (j = 1; j <= N_DOFS; ++j) {
			M[i][2*N_DOFS + j] = h * B[i][j];
	    }
	}
	//print_mat("M is:\n", M);

	// scale M by power of 2 so that its norm < 1/2
	norm = (int)(log2(inf_norm(M))) + 2;
	//printf("Inf norm of M: %f \n", inf_norm(M));
	if (norm < 0)
		norm = 0;

	mat_mult_scalar(M, 1/pow(2,(double)norm), M);
	//printf("Norm of M logged, floored and 2 added is: %d\n", norm);
	//print_mat("M after scaling is:\n", M);

	for (i = 1; i <= 3*N_DOFS; i++) {
		for (j = 1; j <= 3*N_DOFS; j++) {
			N[i][j] = c * M[i][j];
			D[i][j] = -c * M[i][j];
		}
		N[i][i] = N[i][i] + 1.0;
		D[i][i] = D[i][i] + 1.0;
	}

	// set M2 equal to M
	mat_equal(M, M2);

	// start pade approximation

	for (k = 2; k <= q; k++) {
		c = c * (q - k + 1) / (double)(k * (2*q - k + 1));
		mat_mult(M,M2,M2);
		mat_mult_scalar(M2,c,M3);
		mat_add(N,M3,N);
		if (p == 1)
			mat_add(D,M3,D);
		else
			mat_sub(D,M3,D);
		p = -1 * p;
	}

	// multiply denominator with nominator i.e. D\E
	my_inv_ludcmp(D, 3*N_DOFS, D);
	mat_mult(D,N,N);

	// undo scaling by repeated squaring
	for (k = 1; k <= norm; k++)
		mat_mult(N,N,N);

	// get the matrices out
	// read off the entries
	for (i = 1; i <= 2*N_DOFS; i++) {
		for (j = 1; j <= 2*N_DOFS; j++) {
			A[i][j] = N[i][j];
		}
		for (j = 1; j <= N_DOFS; j++) {
			B[i][j] = N[i][2*N_DOFS + j];
		}
	}
}
예제 #13
0
MATRIX ortho(MATRIX C, MATRIX C_ortho)
{
	/*
	This function orthogonalizes a DCM by method presented in the paper
	Bar-Itzhack: "Orthogonalization Techniques of DCM" (1969, IEEE)
	Input:
		C: DCM, 3x3
	Output:
		C_ortho: Orthogonalized DCM, 3x3
	Programmer:    Adhika Lie
	Created:    	 May 10, 2011
	Last Modified: May 10, 2011
	*/
	
	MATRIX e = mat_creat(3,1,ONES_MATRIX);
	MATRIX w1 = mat_creat(3,1,ONES_MATRIX);
	MATRIX w1_p = mat_creat(3,1,ONES_MATRIX);
	MATRIX w1_n = mat_creat(3,1,ONES_MATRIX);
	MATRIX w2 = mat_creat(3,1,ONES_MATRIX);
	MATRIX w2_p = mat_creat(3,1,ONES_MATRIX);
	MATRIX w2_n = mat_creat(3,1,ONES_MATRIX);
	MATRIX w3 = mat_creat(3,1,ONES_MATRIX);
	MATRIX w3_p = mat_creat(3,1,ONES_MATRIX);
	MATRIX w3_n = mat_creat(3,1,ONES_MATRIX);
	double mag_w1, mag_w2, mag_w3;
	
	w1[0][0] = C[0][0]; 
	w1[1][0] = C[1][0];
	w1[2][0] = C[2][0];
	mag_w1 = norm(w1);
	mag_w1 = 1.0/mag_w1;
	w1 = mat_scalMul(w1,mag_w1,w1);
	
	w2[0][0] = C[0][1]; 
	w2[1][0] = C[1][1];
	w2[2][0] = C[2][1];
	mag_w2 = norm(w2);
	mag_w2 = 1.0/mag_w2;
	w2 = mat_scalMul(w2,mag_w2,w2);
	
	w3[0][0] = C[0][2]; 
	w3[1][0] = C[1][2];
	w3[2][0] = C[2][2];
	mag_w3 = norm(w3);
	mag_w3 = 1.0/mag_w3;
	w3 = mat_scalMul(w3,mag_w3,w3);
	
	while (norm(e) > 1e-15){
		w1_p = cross(w2,w3,w1_p);
		w2_p = cross(w3,w1,w2_p);
		w3_p = cross(w1,w2,w3_p);
		
		w1_n = mat_add(w1,w1_p,w1_n);
		w1_n = mat_scalMul(w1_n,0.5,w1_n);
		w1 = mat_scalMul(w1_n,1.0/norm(w1_n),w1);
		
		w2_n = mat_add(w2,w2_p,w2_n);
		w2_n = mat_scalMul(w2_n,0.5,w2_n);
		w2 = mat_scalMul(w2_n,1.0/norm(w2_n),w2);
		
		w3_n = mat_add(w3,w3_p,w3_n);
		w3_n = mat_scalMul(w3_n,0.5,w3_n);
		w3 = mat_scalMul(w3_n,1.0/norm(w3_n),w3);
		
		w1_p = cross(w2,w3,w1_p);
		w2_p = cross(w3,w1,w2_p);
		w3_p = cross(w1,w2,w3_p);
		
		w1_n = mat_sub(w1,w1_p,w1_n);
		e[0][0] = norm(w1_n);
		w2_n = mat_sub(w2,w2_p,w2_n);
		e[1][0] = norm(w2_n);
		w3_n = mat_sub(w3,w3_p,w3_n);
		e[2][0] = norm(w3_n);
	}
	
	C_ortho[0][0] = w1[0][0]; C_ortho[0][1] = w2[0][0];	C_ortho[0][2] = w3[0][0];
	C_ortho[1][0] = w1[1][0]; C_ortho[1][1] = w2[1][0];	C_ortho[1][2] = w3[1][0];
	C_ortho[2][0] = w1[2][0]; C_ortho[2][1] = w2[2][0];	C_ortho[2][2] = w3[2][0];
	
	return C_ortho;
}
예제 #14
0
// Main get_nav filter function
void get_nav(struct sensordata *sensorData_ptr, struct nav *navData_ptr, struct control *controlData_ptr){
	double tnow, imu_dt;
	double dq[4], quat_new[4];

	// compute time-elapsed 'dt'
	// This compute the navigation state at the DAQ's Time Stamp
	tnow = sensorData_ptr->imuData_ptr->time;
	imu_dt = tnow - tprev;
	tprev = tnow;		
	
	// ==================  Time Update  ===================
	// Temporary storage in Matrix form
	quat[0] = navData_ptr->quat[0];
	quat[1] = navData_ptr->quat[1];
	quat[2] = navData_ptr->quat[2];
	quat[3] = navData_ptr->quat[3];
	
	a_temp31[0][0] = navData_ptr->vn; a_temp31[1][0] = navData_ptr->ve;
	a_temp31[2][0] = navData_ptr->vd;
	
	b_temp31[0][0] = navData_ptr->lat; b_temp31[1][0] = navData_ptr->lon;
	b_temp31[2][0] = navData_ptr->alt;
	
	// AHRS Transformations
	C_N2B = quat2dcm(quat, C_N2B);
	C_B2N = mat_tran(C_N2B, C_B2N);
	
	// Attitude Update
	// ... Calculate Navigation Rate
	nr = navrate(a_temp31,b_temp31,nr);
	
	dq[0] = 1;
	dq[1] = 0.5*om_ib[0][0]*imu_dt;
	dq[2] = 0.5*om_ib[1][0]*imu_dt;
	dq[3] = 0.5*om_ib[2][0]*imu_dt;
	
	qmult(quat,dq,quat_new);
	
	quat[0] = quat_new[0]/sqrt(quat_new[0]*quat_new[0] + quat_new[1]*quat_new[1] + quat_new[2]*quat_new[2] + quat_new[3]*quat_new[3]);
	quat[1] = quat_new[1]/sqrt(quat_new[0]*quat_new[0] + quat_new[1]*quat_new[1] + quat_new[2]*quat_new[2] + quat_new[3]*quat_new[3]);
	quat[2] = quat_new[2]/sqrt(quat_new[0]*quat_new[0] + quat_new[1]*quat_new[1] + quat_new[2]*quat_new[2] + quat_new[3]*quat_new[3]);
	quat[3] = quat_new[3]/sqrt(quat_new[0]*quat_new[0] + quat_new[1]*quat_new[1] + quat_new[2]*quat_new[2] + quat_new[3]*quat_new[3]);
	
    if(quat[0] < 0) {
        // Avoid quaternion flips sign
        quat[0] = -quat[0];
        quat[1] = -quat[1];
        quat[2] = -quat[2];
        quat[3] = -quat[3];
    }
    
	navData_ptr->quat[0] = quat[0];
	navData_ptr->quat[1] = quat[1];
	navData_ptr->quat[2] = quat[2];
	navData_ptr->quat[3] = quat[3];
	
	quat2eul(navData_ptr->quat,&(navData_ptr->phi),&(navData_ptr->the),&(navData_ptr->psi));
	
	// Velocity Update
	dx = mat_mul(C_B2N,f_b,dx);
	dx = mat_add(dx,grav,dx);
	navData_ptr->vn += imu_dt*dx[0][0];
	navData_ptr->ve += imu_dt*dx[1][0];
	navData_ptr->vd += imu_dt*dx[2][0];
	
	// Position Update
	dx = llarate(a_temp31,b_temp31,dx);
	navData_ptr->lat += imu_dt*dx[0][0];
	navData_ptr->lon += imu_dt*dx[1][0];
	navData_ptr->alt += imu_dt*dx[2][0];
	
	// JACOBIAN
	F = mat_fill(F, ZERO_MATRIX);
	// ... pos2gs
	F[0][3] = 1.0; 	F[1][4] = 1.0; 	F[2][5] = 1.0;
	// ... gs2pos
	F[5][2] = -2*g/EARTH_RADIUS;
	
	// ... gs2att
	temp33 = sk(f_b,temp33);
	atemp33 = mat_mul(C_B2N,temp33,atemp33);
	
	F[3][6] = -2.0*atemp33[0][0]; F[3][7] = -2.0*atemp33[0][1]; F[3][8] = -2.0*atemp33[0][2];
	F[4][6] = -2.0*atemp33[1][0]; F[4][7] = -2.0*atemp33[1][1]; F[4][8] = -2.0*atemp33[1][2];
	F[5][6] = -2.0*atemp33[2][0]; F[5][7] = -2.0*atemp33[2][1]; F[5][8] = -2.0*atemp33[2][2];
	
	// ... gs2acc
	F[3][9] = -C_B2N[0][0]; F[3][10] = -C_B2N[0][1]; F[3][11] = -C_B2N[0][2];
	F[4][9] = -C_B2N[1][0]; F[4][10] = -C_B2N[1][1]; F[4][11] = -C_B2N[1][2];
	F[5][9] = -C_B2N[2][0]; F[5][10] = -C_B2N[2][1]; F[5][11] = -C_B2N[2][2];
	
	// ... att2att
	temp33 = sk(om_ib,temp33);
	F[6][6] = -temp33[0][0]; F[6][7] = -temp33[0][1]; F[6][8] = -temp33[0][2];
	F[7][6] = -temp33[1][0]; F[7][7] = -temp33[1][1]; F[7][8] = -temp33[1][2];
	F[8][6] = -temp33[2][0]; F[8][7] = -temp33[2][1]; F[8][8] = -temp33[2][2];
	
	// ... att2gyr
	F[6][12] = -0.5;
	F[7][13] = -0.5;
	F[8][14] = -0.5;
	
	// ... Accel Markov Bias
	F[9][9] = -1.0/TAU_A; 	F[10][10] = -1.0/TAU_A;	F[11][11] = -1.0/TAU_A;
	F[12][12] = -1.0/TAU_G; F[13][13] = -1.0/TAU_G;	F[14][14] = -1.0/TAU_G;
	
	//fprintf(stderr,"Jacobian Created\n");
	
	// State Transition Matrix: PHI = I15 + F*dt;
	temp1515 = mat_scalMul(F,imu_dt,temp1515);
	PHI = mat_add(I15,temp1515,PHI);
	
	// Process Noise
	G = mat_fill(G, ZERO_MATRIX);
	G[3][0] = -C_B2N[0][0];	G[3][1] = -C_B2N[0][1]; G[3][2] = -C_B2N[0][2];
	G[4][0] = -C_B2N[1][0];	G[4][1] = -C_B2N[1][1]; G[4][2] = -C_B2N[1][2];
	G[5][0] = -C_B2N[2][0];	G[5][1] = -C_B2N[2][1]; G[5][2] = -C_B2N[2][2];
	
	G[6][3] = -0.5;
	G[7][4] = -0.5;
	G[8][5] = -0.5;
	
	G[9][6] = 1.0; 			G[10][7] = 1.0; 		G[11][8] = 1.0;
	G[12][9] = 1.0; 		G[13][10] = 1.0; 		G[14][11] = 1.0;
	//fprintf(stderr,"Process Noise Matrix G is created\n");
	// Discrete Process Noise
	temp1512 = mat_mul(G,Rw,temp1512);
	temp1515 = mat_transmul(temp1512,G,temp1515);	// Qw = G*Rw*G'
	Qw = mat_scalMul(temp1515,imu_dt,Qw);			// Qw = dt*G*Rw*G'
	Q = mat_mul(PHI,Qw,Q);						// Q = (I+F*dt)*Qw
	
	temp1515 = mat_tran(Q,temp1515);
	Q = mat_add(Q,temp1515,Q);
	Q = mat_scalMul(Q,0.5,Q);				// Q = 0.5*(Q+Q')
	//fprintf(stderr,"Discrete Process Noise is created\n");
	
	// Covariance Time Update
	temp1515 = mat_mul(PHI,P,temp1515);
	P = mat_transmul(temp1515,PHI,P); 		// P = PHI*P*PHI'
	P = mat_add(P,Q,P);						// P = PHI*P*PHI' + Q
	temp1515 = mat_tran(P, temp1515);
	P = mat_add(P,temp1515,P);
	P = mat_scalMul(P,0.5,P);				// P = 0.5*(P+P')
	//fprintf(stderr,"Covariance Updated through Time Update\n");
	
	navData_ptr->Pp[0] = P[0][0]; navData_ptr->Pp[1] = P[1][1]; navData_ptr->Pp[2] = P[2][2];
	navData_ptr->Pv[0] = P[3][3]; navData_ptr->Pv[1] = P[4][4]; navData_ptr->Pv[2] = P[5][5];
	navData_ptr->Pa[0] = P[6][6]; navData_ptr->Pa[1] = P[7][7]; navData_ptr->Pa[2] = P[8][8];
	navData_ptr->Pab[0] = P[9][9]; navData_ptr->Pab[1] = P[10][10]; navData_ptr->Pab[2] = P[11][11];
	navData_ptr->Pgb[0] = P[12][12]; navData_ptr->Pgb[1] = P[13][13]; navData_ptr->Pgb[2] = P[14][14];
	
	navData_ptr->err_type = TU_only;
	//fprintf(stderr,"Time Update Done\n");
	// ==================  DONE TU  ===================
	
	if(sensorData_ptr->gpsData_ptr->newData){
	
		// ==================  GPS Update  ===================
		sensorData_ptr->gpsData_ptr->newData = 0; // Reset the flag
		
		// Position, converted to NED
		a_temp31[0][0] = navData_ptr->lat;
		a_temp31[1][0] = navData_ptr->lon; a_temp31[2][0] = navData_ptr->alt;
		pos_ins_ecef = lla2ecef(a_temp31,pos_ins_ecef);
		
		a_temp31[2][0] = 0.0;
		//pos_ref = lla2ecef(a_temp31,pos_ref);
		pos_ref = mat_copy(a_temp31,pos_ref);
		pos_ins_ned = ecef2ned(pos_ins_ecef,pos_ins_ned,pos_ref);
		
		pos_gps[0][0] = sensorData_ptr->gpsData_ptr->lat*D2R;
		pos_gps[1][0] = sensorData_ptr->gpsData_ptr->lon*D2R;
		pos_gps[2][0] = sensorData_ptr->gpsData_ptr->alt;
		
		pos_gps_ecef = lla2ecef(pos_gps,pos_gps_ecef);
		
		pos_gps_ned = ecef2ned(pos_gps_ecef,pos_gps_ned,pos_ref);
		
		// Create Measurement: y
		y[0][0] = pos_gps_ned[0][0] - pos_ins_ned[0][0];
		y[1][0] = pos_gps_ned[1][0] - pos_ins_ned[1][0];
		y[2][0] = pos_gps_ned[2][0] - pos_ins_ned[2][0];
		
		y[3][0] = sensorData_ptr->gpsData_ptr->vn - navData_ptr->vn;
		y[4][0] = sensorData_ptr->gpsData_ptr->ve - navData_ptr->ve;
		y[5][0] = sensorData_ptr->gpsData_ptr->vd - navData_ptr->vd;
		
		//fprintf(stderr,"Measurement Matrix, y, created\n");
		
		// Kalman Gain
		temp615 = mat_mul(H,P,temp615);
		temp66 = mat_transmul(temp615,H,temp66);
		atemp66 = mat_add(temp66,R,atemp66);
		temp66 = mat_inv(atemp66,temp66); // temp66 = inv(H*P*H'+R)
		//fprintf(stderr,"inv(H*P*H'+R) Computed\n");
		
		temp156 = mat_transmul(P,H,temp156); // P*H'
		//fprintf(stderr,"P*H' Computed\n");
		K = mat_mul(temp156,temp66,K);	   // K = P*H'*inv(H*P*H'+R)
		//fprintf(stderr,"Kalman Gain Computed\n");
		
		// Covariance Update
		temp1515 = mat_mul(K,H,temp1515);
		ImKH = mat_sub(I15,temp1515,ImKH);	// ImKH = I - K*H
		
		temp615 = mat_transmul(R,K,temp615);
		KRKt = mat_mul(K,temp615,KRKt);		// KRKt = K*R*K'
		
		temp1515 = mat_transmul(P,ImKH,temp1515);
		P = mat_mul(ImKH,temp1515,P);		// ImKH*P*ImKH'
		temp1515 = mat_add(P,KRKt,temp1515);
		P = mat_copy(temp1515,P);			// P = ImKH*P*ImKH' + KRKt
		//fprintf(stderr,"Covariance Updated through GPS Update\n");
		
		navData_ptr->Pp[0] = P[0][0]; navData_ptr->Pp[1] = P[1][1]; navData_ptr->Pp[2] = P[2][2];
		navData_ptr->Pv[0] = P[3][3]; navData_ptr->Pv[1] = P[4][4]; navData_ptr->Pv[2] = P[5][5];
		navData_ptr->Pa[0] = P[6][6]; navData_ptr->Pa[1] = P[7][7]; navData_ptr->Pa[2] = P[8][8];
		navData_ptr->Pab[0] = P[9][9]; navData_ptr->Pab[1] = P[10][10]; navData_ptr->Pab[2] = P[11][11];
		navData_ptr->Pgb[0] = P[12][12]; navData_ptr->Pgb[1] = P[13][13]; navData_ptr->Pgb[2] = P[14][14];
		
		// State Update
		x = mat_mul(K,y,x);
		denom = (1.0 - (ECC2 * sin(navData_ptr->lat) * sin(navData_ptr->lat)));
		denom = sqrt(denom*denom);

		Re = EARTH_RADIUS / sqrt(denom);
		Rn = EARTH_RADIUS*(1-ECC2) / denom*sqrt(denom);
		navData_ptr->alt = navData_ptr->alt - x[2][0];
		navData_ptr->lat = navData_ptr->lat + x[0][0]/(Re + navData_ptr->alt);
		navData_ptr->lon = navData_ptr->lon + x[1][0]/(Rn + navData_ptr->alt)/cos(navData_ptr->lat);
		
		navData_ptr->vn = navData_ptr->vn + x[3][0];
		navData_ptr->ve = navData_ptr->ve + x[4][0];
		navData_ptr->vd = navData_ptr->vd + x[5][0];
		
		quat[0] = navData_ptr->quat[0];
		quat[1] = navData_ptr->quat[1];
		quat[2] = navData_ptr->quat[2];
		quat[3] = navData_ptr->quat[3];
		
		// Attitude correction
		dq[0] = 1.0;
		dq[1] = x[6][0];
		dq[2] = x[7][0];
		dq[3] = x[8][0];
		
		qmult(quat,dq,quat_new);
		
		quat[0] = quat_new[0]/sqrt(quat_new[0]*quat_new[0] + quat_new[1]*quat_new[1] + quat_new[2]*quat_new[2] + quat_new[3]*quat_new[3]);
		quat[1] = quat_new[1]/sqrt(quat_new[0]*quat_new[0] + quat_new[1]*quat_new[1] + quat_new[2]*quat_new[2] + quat_new[3]*quat_new[3]);
		quat[2] = quat_new[2]/sqrt(quat_new[0]*quat_new[0] + quat_new[1]*quat_new[1] + quat_new[2]*quat_new[2] + quat_new[3]*quat_new[3]);
		quat[3] = quat_new[3]/sqrt(quat_new[0]*quat_new[0] + quat_new[1]*quat_new[1] + quat_new[2]*quat_new[2] + quat_new[3]*quat_new[3]);
		
		navData_ptr->quat[0] = quat[0];
		navData_ptr->quat[1] = quat[1];
		navData_ptr->quat[2] = quat[2];
		navData_ptr->quat[3] = quat[3];
		
		quat2eul(navData_ptr->quat,&(navData_ptr->phi),&(navData_ptr->the),&(navData_ptr->psi));
		
		navData_ptr->ab[0] = navData_ptr->ab[0] + x[9][0];
		navData_ptr->ab[1] = navData_ptr->ab[1] + x[10][0];
		navData_ptr->ab[2] = navData_ptr->ab[2] + x[11][0];
		
		navData_ptr->gb[0] = navData_ptr->gb[0] + x[12][0];
		navData_ptr->gb[1] = navData_ptr->gb[1] + x[13][0];
		navData_ptr->gb[2] = navData_ptr->gb[2] + x[14][0];
		
		navData_ptr->err_type = gps_aided;
		//fprintf(stderr,"Measurement Update Done\n");
	}
	
	// Remove current estimated biases from rate gyro and accels
	sensorData_ptr->imuData_ptr->p -= navData_ptr->gb[0];
	sensorData_ptr->imuData_ptr->q -= navData_ptr->gb[1];
	sensorData_ptr->imuData_ptr->r -= navData_ptr->gb[2];
	sensorData_ptr->imuData_ptr->ax -= navData_ptr->ab[0];
	sensorData_ptr->imuData_ptr->ay -= navData_ptr->ab[1];
	sensorData_ptr->imuData_ptr->az -= navData_ptr->ab[2];

	// Get the new Specific forces and Rotation Rate,
	// use in the next time update
	f_b[0][0] = sensorData_ptr->imuData_ptr->ax;
	f_b[1][0] = sensorData_ptr->imuData_ptr->ay;
	f_b[2][0] = sensorData_ptr->imuData_ptr->az;

	om_ib[0][0] = sensorData_ptr->imuData_ptr->p;
	om_ib[1][0] = sensorData_ptr->imuData_ptr->q;
	om_ib[2][0] = sensorData_ptr->imuData_ptr->r;


}
예제 #15
0
/**
 * ICA function. Computes the W matrix from the
 * preprocessed data.
 */
static mat ICA_compute(mat X, int rows, int cols)
{
	mat TXp, GWX, W, Wd, W1, D, TU, TMP;
	vect d, lim;
	int i, it;

	// matrix creation
	TXp = mat_create(cols, rows);
	GWX = mat_create(rows, cols);
	W = mat_create(rows, rows);
	Wd = mat_create(rows, rows);
	D = mat_create(rows, rows);
	TMP = mat_create(rows, rows);
	TU = mat_create(rows, rows);
	W1 = mat_create(rows, rows);
	d = vect_create(rows);

	// W rand init
	mat_apply_fx(W, rows, rows, fx_rand, 0);

	// sW <- La.svd(W)
	mat_copy(W, rows, rows, Wd);
	svdcmp(Wd, rows, rows, d, D);

	// W <- sW$u %*% diag(1/sW$d) %*% t(sW$u) %*% W
	mat_transpose(Wd, rows, rows, TU);
	vect_apply_fx(d, rows, fx_inv, 0);
	mat_diag(d, rows, D);
	mat_mult(Wd, rows, rows, D, rows, rows, TMP);
	mat_mult(TMP, rows, rows, TU, rows, rows, D);
	mat_mult(D, rows, rows, W, rows, rows, Wd); // W = Wd

	// W1 <- W 
	mat_copy(Wd, rows, rows, W1);

	// lim <- rep(1000, maxit); it = 1
	lim = vect_create(MAX_ITERATIONS);
	for (i=0; i<MAX_ITERATIONS; i++)
		lim[i] = 1000;
	it = 0;


	// t(X)/p
	mat_transpose(X, rows, cols, TXp);
	mat_apply_fx(TXp, cols, rows, fx_div_c, cols);

	while (lim[it] > TOLERANCE && it < MAX_ITERATIONS) {
		// wx <- W %*% X
		mat_mult(Wd, rows, rows, X, rows, cols, GWX);

		// gwx <- tanh(alpha * wx)
		mat_apply_fx(GWX, rows, cols, fx_tanh, 0);
		
		// v1 <- gwx %*% t(X)/p
		mat_mult(GWX, rows, cols, TXp, cols, rows, TMP); // V1 = TMP
		
		// g.wx <- alpha * (1 - (gwx)^2)
		mat_apply_fx(GWX, rows, cols, fx_1sub_sqr, 0);

		// v2 <- diag(apply(g.wx, 1, FUN = mean)) %*% W
		mat_mean_rows(GWX, rows, cols, d);
		mat_diag(d, rows, D);
		mat_mult(D, rows, rows, Wd, rows, rows, TU); // V2 = TU

		// W1 <- v1 - v2
		mat_sub(TMP, TU, rows, rows, W1);
		
		// sW1 <- La.svd(W1)
		mat_copy(W1, rows, rows, W);
		svdcmp(W, rows, rows, d, D);

		// W1 <- sW1$u %*% diag(1/sW1$d) %*% t(sW1$u) %*% W1
		mat_transpose(W, rows, rows, TU);
		vect_apply_fx(d, rows, fx_inv, 0);
		mat_diag(d, rows, D);
		mat_mult(W, rows, rows, D, rows, rows, TMP);
		mat_mult(TMP, rows, rows, TU, rows, rows, D);
		mat_mult(D, rows, rows, W1, rows, rows, W); // W1 = W
		
		// lim[it + 1] <- max(Mod(Mod(diag(W1 %*% t(W))) - 1))
		mat_transpose(Wd, rows, rows, TU);
		mat_mult(W, rows, rows, TU, rows, rows, TMP);
		lim[it+1] = fabs(mat_max_diag(TMP, rows, rows) - 1);

		// W <- W1
		mat_copy(W, rows, rows, Wd);

		it++;
	}

	// clean up
	mat_delete(TXp, cols, rows);
	mat_delete(GWX, rows, cols);
	mat_delete(W, rows, rows);
	mat_delete(D, rows, rows);
	mat_delete(TMP, rows, rows);
	mat_delete(TU, rows, rows);
	mat_delete(W1, rows, rows);
	vect_delete(d);	

	return Wd;
}
예제 #16
0
/*!*****************************************************************************
 *******************************************************************************
\note  compute_kinematics
\date  June 99
   
\remarks 

       computes kinematic variables

 *******************************************************************************
 Function Parameters: [in]=input,[out]=output

    none

 ******************************************************************************/
static void
compute_kinematics(void)
{
  int i,j,r,o;
  static int firsttime = TRUE;
  static SL_DJstate *temp;
  static Matrix last_J;
  static Matrix last_Jbase;
  
  if (firsttime) {
    temp=(SL_DJstate *)my_calloc((unsigned long)(n_dofs+1),sizeof(SL_DJstate),MY_STOP);
    last_J      = my_matrix(1,6*n_endeffs,1,n_dofs);
    last_Jbase  = my_matrix(1,6*n_endeffs,1,2*N_CART);
  }

  /* compute the desired link positions */
  linkInformationDes(joint_des_state,&base_state,&base_orient,endeff,
		     joint_cog_mpos_des,joint_axis_pos_des,joint_origin_pos_des,
		     link_pos_des,Alink_des,Adof_des);

  /* the desired endeffector information */
  for (i=1; i<=N_CART; ++i) {
    for (j=1; j<=n_endeffs; ++j) {
      cart_des_state[j].x[i] = link_pos_des[link2endeffmap[j]][i];
    }
  }

  /* the desired quaternian of the endeffector */
  for (j=1; j<=n_endeffs; ++j) {
    linkQuat(Alink_des[link2endeffmap[j]],&(cart_des_orient[j]));
  }


  /* addititional link information */
  linkInformation(joint_state,&base_state,&base_orient,endeff,
		  joint_cog_mpos,joint_axis_pos,joint_origin_pos,
		  link_pos,Alink,Adof);

  /* create the endeffector information */
  for (i=1; i<=N_CART; ++i) {
    for (j=1; j<=n_endeffs; ++j) {
      cart_state[j].x[i] = link_pos[link2endeffmap[j]][i];
    }
  }

  /* the quaternian of the endeffector */
  for (j=1; j<=n_endeffs; ++j) {
    linkQuat(Alink[link2endeffmap[j]],&(cart_orient[j]));
  }

  /* the COG position */
  compute_cog();

  /* the jacobian */
  jacobian(link_pos,joint_origin_pos,joint_axis_pos,J);
  baseJacobian(link_pos,joint_origin_pos,joint_axis_pos,Jbase);

  jacobian(link_pos_des,joint_origin_pos_des,joint_axis_pos_des,Jdes);
  baseJacobian(link_pos_des,joint_origin_pos_des,joint_axis_pos_des,Jbasedes);

  /* numerical time derivative of Jacobian */
  if (!firsttime) {
    mat_sub(J,last_J,dJdt);
    mat_mult_scalar(dJdt,(double)ros_servo_rate,dJdt);
    mat_sub(Jbase,last_Jbase,dJbasedt);
    mat_mult_scalar(dJbasedt,(double)ros_servo_rate,dJbasedt);
  }
  mat_equal(J,last_J);
  mat_equal(Jbase,last_Jbase);

  /* compute the cartesian velocities and accelerations */

  for (j=1; j<=n_endeffs; ++j) {

    for (i=1; i<=N_CART; ++i) {

      cart_state[j].xd[i]     = 0.0;
      cart_state[j].xdd[i]    = 0.0;

      cart_orient[j].ad[i]     = 0.0;
      cart_orient[j].add[i]    = 0.0;

      cart_des_state[j].xd[i] = 0.0;
      cart_des_orient[j].ad[i] = 0.0;

      /* contributations from the joints */
      for (r=1; r<=n_dofs; ++r) {
	cart_state[j].xd[i]     += J[(j-1)*6+i][r] * joint_state[r].thd;
	cart_orient[j].ad[i]    += J[(j-1)*6+i+3][r] * joint_state[r].thd;

	cart_des_state[j].xd[i] += Jdes[(j-1)*6+i][r] *joint_des_state[r].thd;
	cart_des_orient[j].ad[i]+= Jdes[(j-1)*6+i+3][r] * joint_des_state[r].thd;

	cart_state[j].xdd[i]    += J[(j-1)*6+i][r] * joint_state[r].thdd + 
	  dJdt[(j-1)*6+i][r] * joint_state[r].thd;
	cart_orient[j].add[i]   += J[(j-1)*6+i+3][r] * joint_state[r].thdd + 
	  dJdt[(j-1)*6+i+3][r] * joint_state[r].thd;
      }

      /* contributations from the base */
      for (r=1; r<=N_CART; ++r) {
	cart_state[j].xd[i]     += Jbase[(j-1)*6+i][r] * base_state.xd[r];
	cart_orient[j].ad[i]    += Jbase[(j-1)*6+i+3][r] * base_state.xd[r];

	cart_state[j].xd[i]     += Jbase[(j-1)*6+i][3+r] * base_orient.ad[r];
	cart_orient[j].ad[i]    += Jbase[(j-1)*6+i+3][3+r] * base_orient.ad[r];

	cart_des_state[j].xd[i]     += Jbasedes[(j-1)*6+i][r] * base_state.xd[r];
	cart_des_orient[j].ad[i]    += Jbasedes[(j-1)*6+i+3][r] * base_state.xd[r];

	cart_des_state[j].xd[i]     += Jbasedes[(j-1)*6+i][3+r] * base_orient.ad[r];
	cart_des_orient[j].ad[i]    += Jbasedes[(j-1)*6+i+3][3+r] * base_orient.ad[r];

	cart_state[j].xdd[i]    += Jbase[(j-1)*6+i][r] * base_state.xdd[r] + 
	  dJbasedt[(j-1)*6+i][r] * base_state.xd[r];
	cart_orient[j].add[i]   += Jbase[(j-1)*6+i+3][r] * base_state.xdd[r] + 
	  dJbasedt[(j-1)*6+i+3][r] * base_state.xd[r];

	cart_state[j].xdd[i]    += Jbase[(j-1)*6+i][3+r] * base_orient.add[r] + 
	  dJbasedt[(j-1)*6+i][3+r] * base_orient.ad[r];
	cart_orient[j].add[i]   += Jbase[(j-1)*6+i+3][3+r] * base_orient.add[r] + 
	  dJbasedt[(j-1)*6+i+3][3+r] * base_orient.ad[r];
      }

    }

    /* compute quaternion derivatives */
    quatDerivatives(&(cart_orient[j]));
    quatDerivatives(&(cart_des_orient[j]));
    for (r=1; r<=N_QUAT; ++r)
      cart_des_orient[j].qdd[r] = 0.0; // we don't have dJdes_dt so far

  }

  /* reset first time flag */
  firsttime = FALSE;

}
예제 #17
0
파일: matrix.c 프로젝트: ankitpati/fds
int main()
{
    unsigned r1, c1, r2, c2, ch;
    mat m1, m2, t;

    puts("Enter row and column numbers of matrices 1 and 2:");
    scanf(" %u %u %u %u%*c", &r1, &c1, &r2, &c2);
    putchar('\n');

    m1=mat_alloc(r1, c1);
    m2=mat_alloc(r2, c2);

    printf("Enter value of Matrix 1 (%ux%u):\n", r1, c1);
    mat_read(m1);
    putchar('\n');
    printf("Enter value of Matrix 2 (%ux%u):\n", r2, c2);
    mat_read(m2);
    putchar('\n');

    do{
        puts("What would you like to do?");
        puts(" ( 0) Exit");
        puts(" ( 1) Display");
        puts(" ( 2) Transpose");
        puts(" ( 3) Sum");
        puts(" ( 4) Difference");
        puts(" ( 5) Product");
        puts(" ( 6) Greatest Element of Rows");
        puts(" ( 7) Sum of Major Diagonal");
        puts(" ( 8) Sum of Minor Diagonal");
        puts(" ( 9) Check Symmetricity");
        puts(" (10) Upper-Triangular Matrix");
        puts(" (11) Lower-Triangular Matrix");
        scanf(" %u%*c", &ch);
        switch(ch){
        case 0:
            puts("Bye!");
            break;
        case 1:
            puts("Matrix 1:");
            mat_write(m1);
            putchar('\n');
            puts("Matrix 2:");
            mat_write(m2);
            break;
        case 2:
            t=mat_trn(m1);
            mat_write(t);
            mat_free(t);
            break;
        case 3:
            if((t=mat_add(m1, m2)).r){
                mat_write(t);
                mat_free(t);
            }
            else puts("Not Possible");
            break;
        case 4:
            if((t=mat_sub(m1, m2)).r){
                mat_write(t);
                mat_free(t);
            }
            else puts("Not Possible");
            break;
        case 5:
            if((t=mat_mul(m1, m2)).r){
                mat_write(t);
                mat_free(t);
            }
            else puts("Not Possible");
            break;
        case 6:
            row_great(m1);
            break;
        case 7:
            add_major(m1);
            break;
        case 8:
            add_minor(m1);
            break;
        case 9:
            if(issymm(m1)) puts("Symmetric");
            else puts("Unsymmetric");
            break;
        case 10:
            up_tri(m1);
            break;
        case 11:
            lo_tri(m1);
            break;
        default:
            puts("Incorrect Choice!");
            break;
        }
        putchar('\n');
    } while(ch);

    mat_free(m1);
    mat_free(m2);
    return 0;
}
예제 #18
0
/**
 * ICA function. Computes the W matrix from the
 * preprocessed data.
 */
static mat ICA_compute(mat X, int rows, int cols) {
    mat TXp, GWX, W, Wd, W1, D, TU, TMP;
    vect d, lim;
    int i, it;

    FILE *OutputFile;

    clock_t clock1, clock2;
    float time;

    //char ascii_path[512];
    //strcpy(ascii_path, "/storage/sdcard0/NickGun/EEG/Log.txt");
    //FILE *Log;

    // matrix creation
    TXp = mat_create(cols, rows);
    GWX = mat_create(rows, cols);
    W = mat_create(rows, rows);
    Wd = mat_create(rows, rows);
    D = mat_create(rows, rows);
    TMP = mat_create(rows, rows);
    TU = mat_create(rows, rows);
    W1 = mat_create(rows, rows);
    d = vect_create(rows);

    // W rand init
    mat_apply_fx(W, rows, rows, fx_rand, 0);

    // sW <- La.svd(W)
    mat_copy(W, rows, rows, Wd);
    svdcmp(Wd, rows, rows, d, D);

    // W <- sW$u %*% diag(1/sW$d) %*% t(sW$u) %*% W
    mat_transpose(Wd, rows, rows, TU);
    vect_apply_fx(d, rows, fx_inv, 0);
    mat_diag(d, rows, D);
    mat_mult(Wd, rows, rows, D, rows, rows, TMP);
    mat_mult(TMP, rows, rows, TU, rows, rows, D);
    mat_mult(D, rows, rows, W, rows, rows, Wd); // W = Wd

    // W1 <- W
    mat_copy(Wd, rows, rows, W1);

    // lim <- rep(1000, maxit); it = 1
    lim = vect_create(MAX_ITERATIONS);
    for (i = 0; i < MAX_ITERATIONS; i++)
        lim[i] = 1000;
    it = 0;

    // t(X)/p
    mat_transpose(X, rows, cols, TXp);
    mat_apply_fx(TXp, cols, rows, fx_div_c, cols);

    while (lim[it] > TOLERANCE && it < MAX_ITERATIONS) {
        // wx <- W %*% X
        mat_mult(Wd, rows, rows, X, rows, cols, GWX);

        // gwx <- tanh(alpha * wx)
        mat_apply_fx(GWX, rows, cols, fx_tanh, 0);

        // v1 <- gwx %*% t(X)/p
        mat_mult(GWX, rows, cols, TXp, cols, rows, TMP); // V1 = TMP

        // g.wx <- alpha * (1 - (gwx)^2)
        mat_apply_fx(GWX, rows, cols, fx_1sub_sqr, 0);

        // v2 <- diag(apply(g.wx, 1, FUN = mean)) %*% W
        mat_mean_rows(GWX, rows, cols, d);
        mat_diag(d, rows, D);
        mat_mult(D, rows, rows, Wd, rows, rows, TU); // V2 = TU

        // W1 <- v1 - v2
        mat_sub(TMP, TU, rows, rows, W1);

        // sW1 <- La.svd(W1)
        mat_copy(W1, rows, rows, W);
        svdcmp(W, rows, rows, d, D);

        // W1 <- sW1$u %*% diag(1/sW1$d) %*% t(sW1$u) %*% W1
        mat_transpose(W, rows, rows, TU);
        vect_apply_fx(d, rows, fx_inv, 0);
        mat_diag(d, rows, D);
        mat_mult(W, rows, rows, D, rows, rows, TMP);
        mat_mult(TMP, rows, rows, TU, rows, rows, D);
        mat_mult(D, rows, rows, W1, rows, rows, W); // W1 = W

        // lim[it + 1] <- max(Mod(Mod(diag(W1 %*% t(W))) - 1))
        mat_transpose(Wd, rows, rows, TU); //chuyen vi
        mat_mult(W, rows, rows, TU, rows, rows, TMP); //TMP=WxTU
        lim[it + 1] = fabs(mat_max_diag(TMP, rows, rows) - 1);

        if(lim[it+1]<0.1)
            break;


        /*
        OutputFile = fopen("/storage/sdcard0/Nickgun/EEG/data/lim",
        			"at");
        fprintf(OutputFile, "%f \n", lim[it+1]);

        fclose(OutputFile);
        // W <- W1
        */
        mat_copy(W, rows, rows, Wd);

        it++;
    }

    // clean up
    mat_delete(TXp, cols, rows);
    mat_delete(GWX, rows, cols);
    mat_delete(W, rows, rows);
    mat_delete(D, rows, rows);
    mat_delete(TMP, rows, rows);
    mat_delete(TU, rows, rows);
    mat_delete(W1, rows, rows);
    vect_delete(d);

    return Wd;
}