Esempio n. 1
0
void acc_update( void )
{
  volatile avr32_adc_t *adc = &AVR32_ADC;

  // start + get from adc
  acc_get_value(adc, &acc.m) ;

  // ak  = acceleration = m - k
  xyz_diff( acc.m , acc.k, &acc.ak ) ;
  acc.ak2 = xyz_sumsq( acc.ak ) ;

  if ( is_acc_slow() ) {
     // update g for next move
     acc.g.x = acc.m.x ;
     acc.g.y = acc.m.y ;
     acc.g.z = acc.m.z ;
  }
  else {
     xyz_diff( acc.m , acc.g, &acc.ag ) ;
     xyz_round0( acc.ag , 16, &acc.ag ) ;
     xyz_add( acc.s , acc.ag, &acc.s ) ;
     //xyz_round0( acc.s , 256, &acc.s ) ;
     //print_dbg("m = "); print_xyz( acc.m ) ;
     //print_dbg("k = "); print_xyz( acc.k ) ;
     //print_dbg("g = "); print_xyz( acc.g ) ;
     //print_dbg("ag = "); print_xyz( acc.ag ) ;
     //print_dbg("s = "); print_xyz( acc.s ) ;
     //print_dbg("\r\n");
     ////acc.s2 = xyz_sumsq( acc.s ) ;
     //print_dbg("s2 = 0x"); print_dbg_hex(acc.s2); print_dbg("\r\n");
  }
}
Esempio n. 2
0
// return norm(a - b)
double
xyz_distance( const xyz_t * const a, const xyz_t * const b )
{
  xyz_t diff;
  xyz_diff( &diff, a, b);
  return xyz_norm( &diff );
}
Esempio n. 3
0
int project_o_tron(aero_table_output_t * out,
		   aero_model_t * model,
		   quat_t ref_to_body, int w, int h, int *pix_buf_panel)
{

	int n = model->n_panels;

	// *** Input parameters
	xyz_t UU e_v_ref = { 1, 0, 0 };	// velocity unit vector in ref frame
	// todo: check that is normalized
	double res = 0.001 / MEGARES;	// Resolution
	double sig_n = 0.8;	// normal momentum exchange coeff
	double sig_t = 0.8;	// tangential momentum exchange coeff

	// *** Let's choose a new "freestream" frame so that the velocity vector is just +X
	quat_t body_to_fs;
	xyz_t e_v_fs = { 1, 0, 0 };
	// Don't need to rotate at all, the frames are already aligned
	// Now form the quaternion rotating the body frame to the freestream frame
	quat_inv(&body_to_fs, &ref_to_body);

	// *** Rotate "everything" into the new frame
	//

	//  Rotate the center of mass
	xyz_t cg_fs;
	rot_vec_by_quat_a2b(&cg_fs, &body_to_fs, &model->cg);

	//  Rotate the panels' coordinates 
	panel_t panels_fs[model->n_panels];
	for (int i = 0; i < n; i++) {
		rot_vec_by_quat_a2b(&panels_fs[i].origin, &body_to_fs,
				    &model->panels[i].origin);
		rot_vec_by_quat_a2b(&panels_fs[i].side_a, &body_to_fs,
				    &model->panels[i].side_a);
		rot_vec_by_quat_a2b(&panels_fs[i].side_b, &body_to_fs,
				    &model->panels[i].side_b);
	}

	//  Find the centroids
	xyz_t centroid_fs[n];
	for (int i = 0; i < n; i++) {
		centroid_fs[i] = panels_fs[i].origin;
		//  This handy function does (a <= a*A + b*B + c*C)
		xyz_sum_scale(&centroid_fs[i], 1, &panels_fs[i].side_a, 0.5,
			      &panels_fs[i].side_b, 0.5);
	}

	// Sort by the X coordinate of the centroids
	struct indirect_element sort_list[n];
	for (int i = 0; i < n; i++) {
		sort_list[i].index = i;
		sort_list[i].val = centroid_fs[i].x;
	}
	qsort(sort_list, n, sizeof(sort_list[0]), compare_indirect_elements);

	double *pix_buf_x = malloc(w * h * sizeof(double));
	// Holds the fs frame X coordinate
	// of the panel element at each pixel
	if (!pix_buf_x) {
		fprintf(stderr, "Unable to allocate %zu bytes for pix_buf_x\n",
			w * h * sizeof(double));
		return 1;
	}
	// Iterate over the panels, rearmost centroid first
	for (int i = 0; i < n; i++) {	// if(sort_list[i].index==0){
		panel_t *p = &panels_fs[sort_list[i].index];
		//printf("Panel %d:::\n",sort_list[i].index);

		double res_a = res / xyz_norm(&p->side_a) / sqrt(2);
		double res_b = res / xyz_norm(&p->side_b) / sqrt(2);

		// Iterate over side a
		for (double a = 0; a <= 1; a += res_a) {
			//  Iterate over side b
			for (double b = 0; b <= 1; b += res_b) {
				xyz_t panel_cell = p->origin;
				xyz_sum_scale(&panel_cell, 1, &p->side_a, a,
					      &p->side_b, b);
				int pix_y =
				    (int)round(panel_cell.y / res + w / 2);
				int pix_z =
				    (int)round(panel_cell.z / res + h / 2);
				pix_buf_panel[pix_z + pix_y * w] =
				    sort_list[i].index + 1;
				pix_buf_x[pix_z + pix_y * w] = panel_cell.x;
				//   printf("\t%+7.4f\t%+7.4f\t%d\t%d\n",panel_cell.y,panel_cell.z,pix_y,pix_z);
			}
		}
	}

	// Find the unit normal vector in fs frame, and e_v.e_n for all panels
	xyz_t e_n_fs[n];
	double e_v_dot_e_n[n];
	for (int p = 0; p < n; p++) {
		xyz_cross(&e_n_fs[p], &panels_fs[p].side_a,
			  &panels_fs[p].side_b);
		xyz_normalize_self(&e_n_fs[p]);
		e_v_dot_e_n[p] = xyz_dot(&e_n_fs[p], &e_v_fs);
//    if (e_v_dot_e_n[p] < 0)
//      printf("e_v dot e_n negative for panel %d\n",p);
	}

//  double A = 0;
	int n_pix[n];
	memset(n_pix, 0, sizeof(n_pix));
	xyz_t panel_sum_pos[n];
	memset(panel_sum_pos, 0, sizeof(panel_sum_pos));

	//printf("sizeof(n_pix)=%zu\n",sizeof(n_pix));

  xyz_t F_fs = {0, 0, 0};
  xyz_t T_fs = {0, 0, 0};

	// Now iterate over the pixels
	for (int pix_y = 0; pix_y < w; pix_y++)
		for (int pix_z = 0; pix_z < h; pix_z++) {
			int p = pix_buf_panel[pix_z + pix_y * w];
			if (p) {
				// There is a panel at this pixel.
        p--;  // Actual panel index number is one less

				if (e_v_dot_e_n[p] < 0) {
					// Skip panels facing the wrong way
					continue;
				}

				n_pix[p]++;

				// Find the coordinates in the fs frame
				xyz_t fs_p;
				fs_p.x = pix_buf_x[pix_z * w + pix_y];
				fs_p.y = (pix_y - w / 2) * res;
				fs_p.z = (pix_z - h / 2) * res;

				// Where is it wrt the center of mass?
				xyz_t r_from_cg_fs;
				xyz_diff(&r_from_cg_fs, &fs_p, &cg_fs);

				// Let's compute the forces on this element
				// ref: NASA SP-8058 eq 2-2 (page 5).
				// Dynamic pressure (1/2 rho v^2) factored out, hence leading 2 *
				xyz_t dF = { 0, 0, 0 };
				xyz_sum_scale(&dF, 0,
					      &e_n_fs[p],
					      2 * -1 * res * res * (2 - sig_n -
							       sig_t) *
					      xyz_dot(&e_v_fs, &e_n_fs[p]),
					      &e_v_fs, 2 * -1 * res * res * sig_t);

				// Torque contribution from this element
				xyz_t dT;
				xyz_cross(&dT, &r_from_cg_fs, &dF);

				xyz_sum(&F_fs, &F_fs, &dF);
				xyz_sum(&T_fs, &T_fs, &dT);

			}
		}


  rot_vec_by_quat_b2a(&out->force,  &body_to_fs, &F_fs);
  rot_vec_by_quat_b2a(&out->torque, &body_to_fs, &T_fs);
  
  printf("F = %f %f %f (norm=%f)\n",out->force.x, out->force.y, out->force.z, xyz_norm(&out->force));
  printf("T = %f %f %f (norm=%f)\n",out->torque.x, out->torque.y, out->torque.z, xyz_norm(&out->torque));
//	 printf("%d pixels dropped due to e_v dot e_n negative\n",n_pix);

	free(pix_buf_x);
	return 0;
}