Ejemplo n.º 1
0
// average pos and speed
void average_params() {
	float n_pos = v_norm(pos_);
	float n_sp = v_norm(speed_);

	total_sum_pos = total_sum_pos - pos_buffer[avg_index] + n_pos;
	total_sum_speed = total_sum_speed - speed_buffer[avg_index] + n_sp;
	pos_buffer[avg_index] = n_pos;
	speed_buffer[avg_index] = n_sp;

	avg_pos = total_sum_pos / 4.0;
	avg_speed = total_sum_speed / 4.0;
		
	avg_index = (avg_index + 1) % 4;
}
Ejemplo n.º 2
0
void Remesh::selectClosest_tmp() { 
	int i=0;
	FILE *select = fopen("select.dat", "w");
	Vertex_handle vdst;	
	for (Vertex_iterator vi = dst_mesh.p.vertices_begin(); vi != dst_mesh.p.vertices_end(); vi++) {
	vi->id = -1;
	}

	for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) {
		Kernel::Point_3 closest_point = dst_mesh.closestPoint(vi->point());
		cerr << i << ": " << vi->point() << " closest to " << closest_point << endl; 
		if(v_norm(closest_point - vi->point()) < dst_mesh.edge_avg*alg_smoothing) {
			vdst = dst_mesh.vertex_mapping[closest_point]; 
			cerr << "whose id is " << vdst->id; 
			vdst->weight = 2;
			vdst->id = i; 
			cerr << " changed to " << vdst->id << endl;
		} i++;
	}
	i=0;
	for (Vertex_iterator vi = dst_mesh.p.vertices_begin(); vi != dst_mesh.p.vertices_end(); vi++) {
		if(vi->weight == 2) {
			fprintf(select, "%d\t%d\n", i,vi->id);
		}
		i++;
	}
	fclose(select);
	cerr << "Done with printing out stuff ! Exiting " << endl;
	exit(0);
}
Ejemplo n.º 3
0
// init_scene initializes the global variable g_projectiles immediately after
// a shot has been fired.
void init_scene()
{
    struct Tank *t = &g_tanks[g_current_tank];
    Vector dir = {
        sin(D2R(t->s.turret_angle))*cos(D2R(t->s.weapon_angle)),
        sin(D2R(t->s.weapon_angle)),
        cos(D2R(t->s.turret_angle))*cos(D2R(t->s.weapon_angle)),
    };
    Vector pos;

    // FIX ME!! Is this the right way to handle tank angle?
    // vv_add(dir, t->o.props.angular_position);
    v_norm(dir);

    // FIX ME!! We do not fire from the end of the barrel
    vv_cpy(pos, t->o.props.position);
    vv_add(pos, t->m.turret_base);
    vv_add(pos, t->m.weapon_base);

    printf("New projectile\n");
    printf("Position: %f %f %f\n", pos[0], pos[1], pos[2]);
    printf("Direction: %f %f %f\n", dir[0], dir[1], dir[2]);
    printf("Tank pos: %f %f %f\n",
        t->o.props.position[0], t->o.props.position[1], t->o.props.position[2]);

    new_projectile(
        dir,                                // Direction
        t->s.power,                         // Magnitude
        pos,                                // Position
        Missile_I                           // Type
    );
}
Ejemplo n.º 4
0
vector2d normalize(vector2d v) {
	float norm = v_norm(v);
	if( norm == 0.0) {
		return v_mul(0.0, v);	
	} else {
		return v_mul(1.0/norm, v);
	}
}
Ejemplo n.º 5
0
static void orthonormalize(float dcm[3][3])
{
	/* Orthogonalize the i and j unit vectors (DCMDraft2 Eqn. 19). */
	dcm_err = v_dotp(dcm[0], dcm[1]);
	v_scale(dcm[1], -dcm_err/2, dcm_d[0]);   /* i vector correction */
	v_scale(dcm[0], -dcm_err/2, dcm_d[1]);   /* i vector correction */
	v_add(dcm[0], dcm_d[0], dcm[0]);
	v_add(dcm[1], dcm_d[1], dcm[1]);

	/* k = i x j */
	v_crossp(dcm[0], dcm[1], dcm[2]);

	/* Normalize all three vectors. */
	v_norm(dcm[0]);
	v_norm(dcm[1]);
	v_norm(dcm[2]);
}
Ejemplo n.º 6
0
// this is the method used in starlight aurora vsx, quite handy actually
void beginBlobs(vsx_module_engine_info* engine)
{
	glEnable(GL_TEXTURE_2D);
	GLfloat tmpMat[16];


  glGetFloatv(GL_MODELVIEW_MATRIX, blobMat);


  glMatrixMode(GL_PROJECTION);

	glPushMatrix();


  glGetFloatv(GL_PROJECTION_MATRIX, tmpMat);

	tmpMat[3] = 0;
	tmpMat[7] = 0;
	tmpMat[11] = 0;
	tmpMat[12] = 0;
	tmpMat[13] = 0;
	tmpMat[14] = 0;
	tmpMat[15] = 1;

	v_norm(tmpMat);
	v_norm(tmpMat + 4);
	v_norm(tmpMat + 8);

  glLoadIdentity();

  glMultMatrixf(tmpMat);

	blobMat[3] = 0;
	blobMat[7] = 0;
	blobMat[11] = 0;
	blobMat[12] = 0;
	blobMat[13] = 0;
	blobMat[14] = 0;
	blobMat[15] = 1;

	v_norm(blobMat);
	v_norm(blobMat + 4);
	v_norm(blobMat + 8);

  glMultMatrixf(blobMat);

  glGetFloatv(GL_PROJECTION_MATRIX, blobMat);

	glPopMatrix();

	glMatrixMode(GL_MODELVIEW);

	//inv_mat(blobMat, blobMatInv);

	GLfloat upLeft[] = {-0.5f, 0.5f, 0.0f, 1.0f};
	GLfloat upRight[] = {0.5f, 0.5f, 0.0f, 1.0f};

	mat_vec_mult(blobMat, upLeft, blobVec0);
	mat_vec_mult(blobMat, upRight, blobVec1);
}
Ejemplo n.º 7
0
// normalizes ball position and returns normalized ball speed
void normalizeBallParams(int x_pos, int y_pos, uint sim_time) {
	// position normalization
	pos_.x = A_X*x_pos + B_X;
	pos_.y = A_Y*y_pos + B_Y;


	// normalizing pos
	float n_pos = v_norm(pos_);
	if(n_pos > 1.0) {
		pos_.x /= n_pos;
		pos_.y /= n_pos;
	}

	compute_speed(sim_time);

	average_params();
}
Ejemplo n.º 8
0
// Actor neural network
int move(uint sim_time) {
	int i = 0;
	float theta = 0.0;
	float psi = 0.0;

	for(i = 0; i < N_MFM; i++) {
		theta += w_A_theta_array[i] * phi_MFM_x(i);
		psi += w_A_psi_array[i] * phi_MFM_y(i);
	}

	theta /= N_MFM;
	psi /= N_MFM;


	// range: [-1;1]	
	theta = theta + sigma_x() * n.x;
	psi = psi + sigma_y() * n.y;
	
	//io_printf(IO_BUF,"theta %f, psi %f\n", theta, psi);


	theta = range(theta, -1.0, 1.0);
	psi = range(psi, -1.0, 1.0);

	if(sim_time > 300 && avg_pos < 0.15 && avg_speed < 0.03) {
		sendNormMotorCommand(0.0, 0.0);
		return STATE_BALANCED; // ball balanced
	}
	else if(sim_time % RESET_STEP == 0) {
		// send an impulse from time to time
		// if the ball is stucked on a place
		if(v_norm(pos_) > 0.6){
			sendNormMotorCommand(pos_.x, pos_.y);
		}
	}
	else {	
		sendNormMotorCommand(theta, psi);
	}



	return STATE_UNBALANCED;
}
Ejemplo n.º 9
0
vector2d project(vector2d a, vector2d b) {
	float coef = dot(a, b)/v_norm(b);
	
	return v_mul(coef, normalize(b));
}
Ejemplo n.º 10
0
float Remesh::RunStep() {
	cur_iter++;
	// COMPUTE THE MESH DISPLACEMENT

	for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) 
		vi->delta = Kernel::Vector_3(0,0,0);

	
	// from current to the closest destination point
	for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) {
		Kernel::Point_3 closest_point = dst_mesh.closestPoint(vi->point());		
		//cerr << "closest_point (" << closest_point << ") has ID " << dst_mesh.vertex_mapping[closest_point]->id << endl;	
		Kernel::Vector_3 closest_normal = dst_mesh.vertex_mapping[closest_point]->normal();
		//Kernel::Vector_3 closest_normal = dst_mesh.vertexMapping(closest_point)->normal();

/*		
		vi->delta = closest_point - vi->point();
					
		bool is_outside = v_norm((closest_point + closest_normal*v_norm(vi->delta)) - vi->point()) < v_norm(vi->delta);
//		bool is_outside = v_norm(v_normalized(closest_normal) + v_normalized(vi->delta)) < 1.4142;
//		bool is_outside = v_angle(closest_normal, vi->delta) > PI/2;		
		double dist_sign = (is_outside?1:-1);
		vi->delta = vi->normal()*v_norm(vi->delta)*(-1)*dist_sign;
*/
		
		vi->delta = vi->normal()* (closest_normal*(closest_point-vi->point())); 

//		vi->delta == v_normalized(data->mesh.computeVectorComponent(vi->normal(),vi->delta,1))*v_norm(vi->delta);
//		vi->delta = v_normalized(vi->delta)*data->mesh.computeVertexStatistics(*vi,1)*0.05;
		//		vi->delta = vi->normal(); //*alg_dt
	}

	// NORMALIZE the movements
	float total_movement = 0;
	int total_elements = 0;
	double max_delta = data->mesh.edge_avg*alg_dt;
	for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) {	
		//vi->delta = v_normalized(vi->delta)*data->mesh.computeVertexStatistics(*vi,1)*0.1;
//		double max_delta = data->mesh.computeVertexStatistics(*vi,1)*alg_dt;
//		double min_delta = data->mesh.edge_avg/5;

		
//		vi->delta = vi->delta;
//		vi->delta = vi->delta + v_normalized(vi->delta)*(RAND_MAX/2-std::rand())*1.0/RAND_MAX*data->mesh.edge_avg/2*alg_smoothing;
//		vi->delta = v_normalized(vi->delta)*max_delta;
		


		double the_norm = v_norm(vi->delta);		
		if (the_norm > max_delta) {
			 vi->delta = v_normalized(vi->delta)*max_delta;
		}
//		if (the_norm < min_delta) vi->delta = v_normalized(vi->delta)*min_delta;	
		the_norm = v_norm(vi->delta);
		if (the_norm > max_delta*0.5) {
			total_elements++;
			total_movement	+= v_norm(vi->delta);
		}
		
		//vi->delta = vi->delta + Kernel::Vector_3((RAND_MAX/2-std::rand())*1.0/RAND_MAX, (RAND_MAX/2-std::rand())*1.0/RAND_MAX, (RAND_MAX/2-std::rand())*1.0/RAND_MAX)*data->mesh.computeVertexStatistics(*vi,1)*alg_smoothing;
//		vi->delta = vi->delta + data->mesh.computeVectorComponent(vi->normal(),vi->laplacian()*alg_dt,0);		
		if (vi->border()==false) vi->delta = vi->delta + vi->laplacian()*alg_smoothing;	
	}
	// MOVE THE MESH
	OpenGLContext::mutex.lock();
	data->mesh.lock();
	
	for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) {
		if (alg_keepVerticesConstant) vi->delta = vi->normal()*(vi->delta*vi->normal());	
		vi->prev_delta = vi->delta;
		vi->border()=false;
		vi->move ( vi->delta );
	}
	data->mesh.unlock();
	data->mesh.updateMeshData();
	OpenGLContext::mutex.unlock();
	
	//saveOutput
	if (alg_saveOutput) {
		char filename[300];
		sprintf(filename,"%s/output_%04d.off",alg_saveOutputPrefix,cur_iter);
		data->mesh.saveFormat(filename,"off");
		sprintf(filename,"%s/output_%04d.diff",alg_saveOutputPrefix,cur_iter);
		data->mesh.saveVectorField(filename);
		sprintf(filename,"%s/output_%04d.idx",alg_saveOutputPrefix,cur_iter);
		data->mesh.saveVertexIndices(filename);
		
	}
	
	emit stepFinished();
	return total_elements;
//	return (++cur_iter < iter);	

}
Ejemplo n.º 11
0
//////////////////////////////////////////////////////////////////////////////////////////////////////
// run a step
float Remesh::RunColorStep() {
	cur_iter++;
	cerr << "ITERATION ( " << cur_iter << ") " << endl;
	// COMPUTE THE MESH DISPLACEMENT

	for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) {
		vi->delta = Kernel::Vector_3(0,0,0);
		vi->delta_tmp = Kernel::Vector_3(0,0,0);
	}

	
	// from current to the closest destination point
	for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) {

#if MOVE_THE_MESH
		Kernel::Point_3 closest_point = dst_mesh.closestColorPoint(vi->point(), (float *)(vi->color));	
		//Kernel::Point_3 closest_point = dst_mesh.closestPoint(vi->point());	
#else 
		Kernel::Point_3 tmp_point = vi->point() + vi->motion_vec;
		Kernel::Point_3 closest_point = dst_mesh.closestColorPoint(tmp_point,  (float *)(vi->color));	
#endif
		//cerr << "closest_point (" << closest_point << ") has ID " << dst_mesh.vertex_mapping[closest_point]->id << endl;	
		//Kernel::Vector_3 closest_normal = dst_mesh.vertex_mapping[closest_point]->normal();
		//Kernel::Vector_3 closest_normal = dst_mesh.vertexMapping(closest_point)->normal();

/*		
		vi->delta = closest_point - vi->point();
					
		bool is_outside = v_norm((closest_point + closest_normal*v_norm(vi->delta)) - vi->point()) < v_norm(vi->delta);
//		bool is_outside = v_norm(v_normalized(closest_normal) + v_normalized(vi->delta)) < 1.4142;
//		bool is_outside = v_angle(closest_normal, vi->delta) > PI/2;		
		double dist_sign = (is_outside?1:-1);
		vi->delta = vi->normal()*v_norm(vi->delta)*(-1)*dist_sign;
*/
		
		vi->delta = closest_point- (vi->point() + vi->motion_vec); 
 
		//vi->delta = vi->normal()* (closest_normal*(closest_point-vi->point())); 

//		vi->delta == v_normalized(data->mesh.computeVectorComponent(vi->normal(),vi->delta,1))*v_norm(vi->delta);
//		vi->delta = v_normalized(vi->delta)*data->mesh.computeVertexStatistics(*vi,1)*0.05;
		//		vi->delta = vi->normal(); //*alg_dt
	}

	// NORMALIZE the movements
	float total_movement = 0;
	int total_elements = 0;
	double max_delta = data->mesh.edge_avg*alg_dt;
	for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) {	
		//vi->delta = v_normalized(vi->delta)*data->mesh.computeVertexStatistics(*vi,1)*0.1;
//		double max_delta = data->mesh.computeVertexStatistics(*vi,1)*alg_dt;
//		double min_delta = data->mesh.edge_avg/5;

		
//		vi->delta = vi->delta;
//		vi->delta = vi->delta + v_normalized(vi->delta)*(RAND_MAX/2-std::rand())*1.0/RAND_MAX*data->mesh.edge_avg/2*alg_smoothing;
//		vi->delta = v_normalized(vi->delta)*max_delta;
		


		double the_norm = v_norm(vi->delta);		
		if (the_norm > max_delta) {
			 vi->delta = v_normalized(vi->delta)*max_delta;
		}
//		if (the_norm < min_delta) vi->delta = v_normalized(vi->delta)*min_delta;	
		the_norm = v_norm(vi->delta);

		if (! MOVE_THE_MESH || the_norm > max_delta*0.5) {
			total_elements++;
			total_movement	+= v_norm(vi->delta);
		}
		
		//vi->delta = vi->delta + Kernel::Vector_3((RAND_MAX/2-std::rand())*1.0/RAND_MAX, (RAND_MAX/2-std::rand())*1.0/RAND_MAX, (RAND_MAX/2-std::rand())*1.0/RAND_MAX)*data->mesh.computeVertexStatistics(*vi,1)*alg_smoothing;
//		vi->delta = vi->delta + data->mesh.computeVectorComponent(vi->normal(),vi->laplacian()*alg_dt,0);		
		//vi->delta = vi->delta + vi->laplacian()*alg_smoothing;	
	}
	data->mesh.diffuse(alg_smoothing, 0); 
#if ADD_LENGTH_CONSTRAINT
	for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) {	
	// Add a cost for preserving the smoothness and the geometry of the mesh
	       HV_circulator h = vi->vertex_begin();
	       double geom_vx = 0 ;
	       double geom_vy = 0 ;
	       double geom_vz = 0 ;   
	       int order=0;

	       do
	       {
	           const float xx = TO_FLOAT ( vi->point().x() );
	           const float yy = TO_FLOAT ( vi->point().y() );
        	   const float zz = TO_FLOAT ( vi->point().z() );
                   const float xxx = TO_FLOAT ( h->opposite()->vertex()->point().x()) ;
        	   const float yyy = TO_FLOAT ( h->opposite()->vertex()->point().y()) ;
	           const float zzz = TO_FLOAT ( h->opposite()->vertex()->point().z()) ;

        	   double d = (xx - xxx) * (xx - xxx)  + (yy - yyy) * (yy - yyy) + (zz - zzz) * (zz - zzz) ;
#if MOVE_THE_MESH
	           double t_d2x = (xx + vi->delta[0]) - (xxx + h->opposite()->vertex()->delta[0]) ;
        	   double t_d2y = (yy + vi->delta[1]) - (yyy + h->opposite()->vertex()->delta[1]) ;
	           double t_d2z = (zz + vi->delta[2]) - (zzz + h->opposite()->vertex()->delta[2]) ;
#else
	           double t_d2x = (xx + vi->motion_vec[0] + vi->delta[0]) - (xxx + h->opposite()->vertex()->motion_vec[0] + h->opposite()->vertex()->delta[0]) ;
        	   double t_d2y = (yy + vi->motion_vec[1] + vi->delta[1]) - (yyy + h->opposite()->vertex()->motion_vec[1] + h->opposite()->vertex()->delta[1]) ;
	           double t_d2z = (zz + vi->motion_vec[2] + vi->delta[2]) - (zzz + h->opposite()->vertex()->motion_vec[2] + h->opposite()->vertex()->delta[2]) ;
#endif
	           double d2 = t_d2x * t_d2x + t_d2y * t_d2y + t_d2z * t_d2z;
                   geom_vx += t_d2x * (sqrt(d2) - sqrt(d)) / sqrt(d2) ;
        	   geom_vy += t_d2y * (sqrt(d2) - sqrt(d)) / sqrt(d2) ;
	           geom_vz += t_d2z * (sqrt(d2) - sqrt(d)) / sqrt(d2) ;
        	   order++;

	       }
	       while ( ++h != vi->vertex_begin() );
	       geom_vx /= order ;
	       geom_vy /= order ;
	       geom_vz /= order ;
	       double alpha = 1 ;
	       vi->delta_tmp =  alpha * Vector(-geom_vx, -geom_vy, -geom_vz) ; 
#if 0
	if(v_norm(vi->delta_tmp) > 0.001)  
	       std::cout << vi->delta << " +  " << geom_vx << " " << geom_vy << " " << geom_vz <<std::endl ;
#endif
	}
	for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) {	
	       double alpha1 = 0.9, alpha2 = 0.1 ;
		if(v_norm(vi->delta)<0.01) { alpha2 = 0.9; alpha1 = 0.1; }
		vi->delta = alpha1 * vi->delta + alpha2 * vi->delta_tmp;
	}
#endif 
	// MOVE THE MESH
	OpenGLContext::mutex.lock();
	data->mesh.lock();
	for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) {
		if (alg_keepVerticesConstant) vi->delta = vi->normal()*(vi->delta*vi->normal());	
		vi->prev_delta = vi->delta;
#if MOVE_THE_MESH
		vi->move ( vi->delta );
#else
		vi->motion_vec = vi->motion_vec + vi->delta;
#endif
	}
	data->mesh.unlock();
#if MOVE_THE_MESH
	data->mesh.updateMeshData();
#else
	//for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) {
	//	vi->motion_vec = vi->motion_vec + vi->laplacian() * alg_smoothing; // smooth the motion vectors
	//}
#endif
	OpenGLContext::mutex.unlock();
	
	//saveOutput
	if (alg_saveOutput) {
		char filename[300];
		sprintf(filename,"%s/output_%04d.off",alg_saveOutputPrefix,cur_iter);
		data->mesh.saveFormat(filename,"off");
		sprintf(filename,"%s/output_%04d.diff",alg_saveOutputPrefix,cur_iter);
		data->mesh.saveVectorField(filename);
		sprintf(filename,"%s/output_%04d.idx",alg_saveOutputPrefix,cur_iter);
		data->mesh.saveVertexIndices(filename);
		
	}
	
	emit stepFinished();
	return total_movement;
	//return total_elements;
//	return (++cur_iter < iter);	

}
Ejemplo n.º 12
0
void update_ahrs(float dt, float dcm_out[3][3], float gyr_out[3])
{
	static uint8_t i;

	read_mpu(v_gyr, v_acc);
	for (i=0; i<3; i++) {
		gyr_out[i] = v_gyr[i];
	}

	/**
	 * Accelerometer
	 *     Frame of reference: body
	 *     Units: G (gravitational acceleration)
	 *     Purpose: Measure the acceleration vector v_acc with components
	 *              codirectional with the i, j, and k vectors. Note that the
	 *              gravitational vector is the negative of the K vector.
	 */
	#ifdef ACC_WEIGHT
	// Take weighted average.
	#ifdef ACC_SELF_WEIGHT
	for (i=0; i<3; i++) {
		v_acc[i] = ACC_SELF_WEIGHT * v_acc[i] + (1-ACC_SELF_WEIGHT) * v_acc_last[i];
		v_acc_last[i] = v_acc[i];

		// Kalman filtering?
		//v_acc_last[i] = acc.get(i);
		//kalmanUpdate(v_acc[i], accVar, v_acc_last[i], ACC_UPDATE_SIG);
		//kalmanPredict(v_acc[i], accVar, 0.0, ACC_PREDICT_SIG);
	}
	#endif // ACC_SELF_WEIGHT
	acc_scale = v_norm(v_acc);

	/**
	 * Reduce accelerometer weight if the magnitude of the measured
	 * acceleration is significantly greater than or less than 1 g.
	 *
	 * TODO: Magnitude of acceleration should be reported over telemetry so
	 * ACC_SCALE_WEIGHT can be more accurately determined.
	 */
	#ifdef ACC_SCALE_WEIGHT
	acc_scale = (1.0 - MIN(1.0, ACC_SCALE_WEIGHT * ABS(acc_scale - 1.0)));
	acc_weight = ACC_WEIGHT * acc_scale;
	#else
	acc_weight = ACC_WEIGHT;

	// Ignore accelerometer if it measures anything 0.5g past gravity.
	if (acc_scale > 1.5 || acc_scale < 0.5) {
		acc_weight = 0;
	}
	#endif // ACC_SCALE_WEIGHT

	/**
	 * Express K global unit vector in body frame as k_gb for use in drift
	 * correction (we need K to be described in the body frame because gravity
	 * is measured by the accelerometer in the body frame). Technically we
	 * could just create a transpose of dcm_gyro, but since we don't (yet) have
	 * a magnetometer, we don't need the first two rows of the transpose. This
	 * saves a few clock cycles.
	 */
	for (i=0; i<3; i++) {
		k_gb[i] = dcm_gyro[i][2];
	}

	/**
	 * Calculate gyro drift correction rotation vector w_a, which will be used
	 * later to bring KB closer to the gravity vector (i.e., the negative of
	 * the K vector). Although we do not explicitly negate the gravity vector,
	 * the cross product below produces a rotation vector that we can later add
	 * to the angular displacement vector to correct for gyro drift in the
	 * X and Y axes. Note we negate w_a because our acceleration vector is
	 * actually the negative of our gravity vector.
	 */
	v_crossp(k_gb, v_acc, w_a);
	v_scale(w_a, -1, w_a);
	#endif // ACC_WEIGHT

	/**
	 * Magnetometer
	 *     Frame of reference: body
	 *     Units: N/A
	 *     Purpose: Measure the magnetic north vector v_mag with components
	 *              codirectional with the body's i, j, and k vectors.
	 */
	#ifdef MAG_WEIGHT
	// Express J global unit vectory in body frame as j_gb.
	for (i=0; i<3; i++) {
		j_gb[i] = dcm_gyro[i][1];
	}

	// Calculate yaw drift correction vector w_m.
	v_crossp(j_gb, v_mag, w_m);
	#endif // MAG_WEIGHT

	/**
	 * Gyroscope
	 *     Frame of reference: body
	 *     Units: rad/s
	 *     Purpose: Measure the rotation rate of the body about the body's i,
	 *              j, and k axes.
	 * ========================================================================
	 * Scale v_gyr by elapsed time (in seconds) to get angle w*dt in radians,
	 * then compute weighted average with the accelerometer and magnetometer
	 * correction vectors to obtain final w*dt.
	 * TODO: This is still not exactly correct.
	 */
	for (i=0; i<3; i++) {
		w_dt[i] = v_gyr[i] * dt;

		#ifdef ACC_WEIGHT
		w_dt[i] += acc_weight * w_a[i];
		#endif // ACC_WEIGHT

		#ifdef MAG_WEIGHT
		w_dt[i] += MAG_WEIGHT * w_m[i];
		#endif // MAG_WEIGHT
	}

	/**
	 * Direction Cosine Matrix
	 *     Frame of reference: global
	 *     Units: None (unit vectors)
	 *     Purpose: Calculate the components of the body's i, j, and k unit
	 *              vectors in the global frame of reference.
	 * ========================================================================
	 * Skew the rotation vector and sum appropriate components by combining the
	 * skew symmetric matrix with the identity matrix. The math can be
	 * summarized as follows:
	 *
	 * All of this is calculated in the body frame. If w is the angular
	 * velocity vector, let w_dt (w*dt) be the angular displacement vector of
	 * the DCM over a time interval dt. Let w_dt_i, w_dt_j, and w_dt_k be the
	 * components of w_dt codirectional with the i, j, and k unit vectors,
	 * respectively. Also, let dr be the linear displacement vector of the DCM
	 * and dr_i, dr_j, and dr_k once again be the i, j, and k components,
	 * respectively.
	 *
	 * In very small dt, certain vectors approach orthogonality, so we can
	 * assume that (draw this out for yourself!):
	 *
	 *     dr_x = <    0,  dw_k, -dw_j>,
	 *     dr_y = <-dw_k,     0,  dw_i>, and
	 *     dr_z = < dw_j, -dw_i,     0>,
	 *
	 * which can be expressed as the rotation matrix:
	 *
	 *          [     0  dw_k -dw_j ]
	 *     dr = [ -dw_k     0  dw_i ]
	 *          [  dw_j -dw_i     0 ].
	 *
	 * This can then be multiplied by the current DCM and added to the current
	 * DCM to update the DCM. To minimize the number of calculations performed
	 * by the processor, however, we can combine the last two steps by
	 * combining dr with the identity matrix to produce:
	 *
	 *              [     1  dw_k -dw_j ]
	 *     dr + I = [ -dw_k     1  dw_i ]
	 *              [  dw_j -dw_i     1 ],
	 *
	 * which we multiply with the current DCM to produce the updated DCM
	 * directly.
	 *
	 * It may be helpful to read the Wikipedia pages on cross products and
	 * rotation representation.
	 */
	dcm_d[0][0] =        1;
	dcm_d[0][1] =  w_dt[2];
	dcm_d[0][2] = -w_dt[1];
	dcm_d[1][0] = -w_dt[2];
	dcm_d[1][1] =        1;
	dcm_d[1][2] =  w_dt[0];
	dcm_d[2][0] =  w_dt[1];
	dcm_d[2][1] = -w_dt[0];
	dcm_d[2][2] =        1;

	// Multiply the current DCM with the change in DCM and update.
	m_product(dcm_d, dcm_gyro, dcm_gyro);

	// Remove any distortions introduced by the small-angle approximations.
	orthonormalize(dcm_gyro);

	// Apply rotational offset (in case IMU is not installed orthogonally to
	// the airframe).
	dcm_offset[0][0] =              1;
	dcm_offset[0][1] =              0;
	dcm_offset[0][2] = -trim_angle[1];
	dcm_offset[1][0] =              0;
	dcm_offset[1][1] =              1;
	dcm_offset[1][2] =  trim_angle[0];
	dcm_offset[2][0] =  trim_angle[1];
	dcm_offset[2][1] = -trim_angle[0];
	dcm_offset[2][2] =              1;
	m_product(dcm_offset, dcm_gyro, dcm_out);
}
Ejemplo n.º 13
0
int  getGeoDataTria( double *p1, double *p2, double *p3, double *Ix, double *Iy, double *Ixy,
                double *A, double *pcg)
/*             p3         */
/*   Tri_2    /|\   Tri_1 */
/*           p1_p2        */
/*           (p4)         */
{
  int i;
  static double vx[]={1.,0.,0.};

  double p4[3], v12[3], v13[3], v23[3], v14[3], v43[3], vnorm[3], vbuf[3], vbuf2[3];
  double p_puf[3][3], vb; /* pktnr,xyz */
  double l12, l13, l23, b1, b2, b_ges, h, A1, A2;
  double Ix1_p4,  Iy1_p4, Ixy1_p4;
  double Ix2_p4,  Iy2_p4, Ixy2_p4;
  double Ix_p4,  Iy_p4, Ixy_p4;

  double spx_p4, spy_p4, sp1x_p4, sp2x_p4;
  double Ix_sp,  Iy_sp, Ixy_sp;

  double alfa_z, a, b, c;

  /* v12 muss den groeste Laenge haben, sonst umsortieren und checken ob es ein dreieck ist v12xv13 != 0.  */
  v_result(p1, p2, v12);
  l12=v_betrag(v12);
  v_result(p1, p3, v13);
  v_prod(v12,v13,vbuf);
  if((int)(1.e20*v_betrag(vbuf))==0) return(0);
  l13=v_betrag(v13);
  v_result(p2, p3, v23);
  l23=v_betrag(v23);
  vb=l12;
  if (l13 > vb)
  {
    vb=l13;
    for (i=0; i<3; i++) p_puf[0][i]= p3[i];
    for (i=0; i<3; i++) p_puf[1][i]= p1[i];
    for (i=0; i<3; i++) p_puf[2][i]= p2[i];
    for (i=0; i<3; i++) p1[i]=p_puf[0][i];
    for (i=0; i<3; i++) p2[i]=p_puf[1][i];
    for (i=0; i<3; i++) p3[i]=p_puf[2][i];
  }
  if (l23 > vb)
  {
    vb=l23;
    for (i=0; i<3; i++) p_puf[0][i]= p2[i];
    for (i=0; i<3; i++) p_puf[1][i]= p3[i];
    for (i=0; i<3; i++) p_puf[2][i]= p1[i];
    for (i=0; i<3; i++) p1[i]=p_puf[0][i];
    for (i=0; i<3; i++) p2[i]=p_puf[1][i];
    for (i=0; i<3; i++) p3[i]=p_puf[2][i];
  }

  /* berechnung der Geometiegroessen (2D-Elementsys.)  aus 3D Punktkoordinaten*/
  v_result(p1, p3, v13);
  v_result(p1, p2, v12);
  b_ges=v_betrag(v12);
  b2=v_sprod( v13, v12);
  b2=b2/b_ges;
  b1=b_ges-b2;

  v_norm( v12, vnorm);
  v_scal( &b2, vnorm, v14);
  v_add( p1, v14, p4);
  v_result(p4, p3, v43);
  h=v_betrag(v43);

  A1= b1*h/2.;
  *A= b_ges*h/2.;
  A2= *A-A1;

  /* Schwerpunkte (sp) bezogen auf p4  IM LOKALEN SYSTEM */

  sp1x_p4= b1/3.;
  sp2x_p4= -b2/3.;
  spx_p4 = (A1*sp1x_p4 + A2*sp2x_p4) / *A;
  spy_p4 = h/3.;

  /* Traegheitsmomente bezogen auf p4  IM LOKALEN SYSTEM */

  Ix1_p4=  b1*h*h*h/12.;
  Iy1_p4=  h*b1*b1*b1/12.;
  Ixy1_p4= b1*b1*h*h/24.;

  Ix2_p4=  b2*h*h*h/12.;
  Iy2_p4=  h*b2*b2*b2/12.;
  Ixy2_p4= b2*b2*h*h/24.;

  Ix_p4= Ix1_p4 + Ix2_p4;
  Iy_p4= Iy1_p4 + Iy2_p4;
  Ixy_p4= Ixy1_p4 - Ixy2_p4;
  /*
  printf ("\nA:%lf b1:%lf b2:%lf h:%lf \n", *A, b1, b2, h);
  printf ("Tri1_P4 Ix:%lf Iy:%lf Ixy:%lf  \n", Ix1_p4,  Iy1_p4, Ixy1_p4);
  printf ("Tri2_P4 Ix:%lf Iy:%lf Ixy:%lf  \n", Ix2_p4,  Iy2_p4, Ixy2_p4);
  printf ("Tri _P4 Ix:%lf Iy:%lf Ixy:%lf  \n", Ix_p4,  Iy_p4, Ixy_p4); 
  */
  /* Traegheitsmomente bezogen auf Schwp. (nach Steiner) */

  Ix_sp = Ix_p4 - spy_p4*spy_p4 * *A;
  Iy_sp = Iy_p4 - spx_p4*spx_p4 * *A;
  Ixy_sp = Ixy_p4 - spx_p4*spy_p4 * *A;
  /*
  printf ("\nA:%lf b1:%lf b2:%lf h:%lf \n", *A, b1, b2, h);
  printf ("sp_p4  spx:%lf spy:%lf   \n", spx_p4,  spy_p4);
  printf ("Tri _sp Ix:%lf Iy:%lf Ixy:%lf  \n", Ix_sp,  Iy_sp, Ixy_sp);
  */

  /* umrechnen aufs Gloabale System (2D Elementsystem -> 3D Globalsystem) */
  v_norm( v12, vnorm);
  v_scal( &spx_p4, vnorm, vbuf);
  v_add( p4, vbuf, vbuf2);

  v_norm( v43, vnorm);
  v_scal( &spy_p4, vnorm, vbuf);
  v_add( vbuf2, vbuf, pcg);

  
  /* ACHTUNG: z. Z. wird nur in der xy-ebene gedreht!  */
  v12[2] = 0.;

  alfa_z= acos( v_sprod(v12,vx) / v_betrag(v12) / v_betrag(vx) ) * (-1.);

  a = (Ix_sp+Iy_sp)/2.;
  b = (Ix_sp-Iy_sp)/2. * cos(2.*alfa_z);
  c =  Ixy_sp * sin(2.*alfa_z);
  *Ix= a+b-c;
  *Iy= a-b+c;
  *Ixy= a * sin(2.*alfa_z) + Ixy_sp * cos(2.*alfa_z);

  /* Traegheitsmomente bezogen auf Globalsystem (nach Steiner) */

  *Ix= *Ix + pcg[1]*pcg[1] * *A;
  *Iy= *Iy + pcg[0]*pcg[0] * *A;
  *Ixy= *Ixy + pcg[0]*pcg[1] * *A;

  return(1);

}
Ejemplo n.º 14
0
/* Third version of draw triangle uses a z_buffer
	And we're using flat shading 
	clear_z_buffer needs to be run in the main loop before every frame. */
void draw_triangle3(int *a,int *b,int *c,vect_t pos,vect_t rot,rgb color){
	int x0,y0,x1,y1,x2,y2;
	// this is is the format that the triangles should be passed to us already 
	vect_t x={a[0],a[1],a[2]+Z};
	vect_t y={b[0],b[1],b[2]+Z};
	vect_t z={c[0],c[1],c[2]+Z};

// Lighting	
	vect_t n=v_norm(v_cross(x,y));
//	vect_t l=v_sub(cam.pos,x);
	vect_t l=cam.pos;
	double lum=1.0;

//	if( lum < 0 ) return 0; 
	rgb colors[3];



	point p[3];

	x=v_rot(x,rot);
	y=v_rot(y,rot);
	z=v_rot(z,rot);
// should we do the translation here as well does this make sense?  
	x=v_add(x,pos);
	y=v_add(y,pos);
	z=v_add(z,pos);

	double lums[3];
	lums[0]=v_dot(l,x)/(v_len(l)*v_len(x));
	lums[1]=v_dot(l,y)/(v_len(l)*v_len(y));
	lums[2]=v_dot(l,z)/(v_len(l)*v_len(z));

#if 1
	for(int i=0;i<3;i++){
	#if 0 
		lum=lums[i];
		if( lum < 0 ) lum=0;
	#else 
		lum=1.0;
	#endif 

		colors[i].r=clip(color.r*lum);
		colors[i].g=clip(color.g*lum);
		colors[i].b=clip(color.b*lum);
	}
#else 
	for(int i=0;i<3;i++){
		colors[i].r=color.r;
		colors[i].g=color.g;
		colors[i].b=color.b;
	}
#endif 


	int q,w,e;
	q=project_coord(x,&p[0].x,&p[0].y);
	w=project_coord(y,&p[1].x,&p[1].y);
	e=project_coord(z,&p[2].x,&p[2].y);

	if(outside_of_screen(p)){
		return;
	}

	rgb ca[3];
	ca[0]=ca[1]=ca[2]=color;	

	vect_t v3[3];
	v3[0]=x; v3[1]=y; v3[2]=z;

	double distances[3];
	
	// introduce max distance of 5000 
	distances[0]=clipfloat(v_len(v_sub(x,cam.pos)),0,MAX_DIST)/MAX_DIST;	
	distances[1]=clipfloat(v_len(v_sub(y,cam.pos)),0,MAX_DIST)/MAX_DIST;	
	distances[2]=clipfloat(v_len(v_sub(z,cam.pos)),0,MAX_DIST)/MAX_DIST;	

/*	
	distances[0]=v_len(v_sub(z,cam.pos));	
	distances[1]=v_len(v_sub(y,cam.pos));	
	distances[2]=v_len(v_sub(x,cam.pos));	
		*/


	draw_triangle_gradient_new(p,v3,distances,colors);	
#if 0
	draw_line_color(p[0].x,p[0].y,p[1].x,p[1].y,black);
	draw_line_color(p[1].x,p[1].y,p[2].x,p[2].y,black);
	draw_line_color(p[1].x,p[1].y,p[0].x,p[0].y,black);
#endif 
}
Ejemplo n.º 15
0
int draw_3d_tri(
	pVector v1p, Graph3dColor c1p, pVector n1p,
	pVector v2p, Graph3dColor c2p, pVector n2p,
	pVector v3p, Graph3dColor c3p, pVector n3p) {

	int j;
	int x1, x2, x3;
	int y1, y2, y3;

	// First, convert the colors to floats
	Vector c1 = {
		(float)c1p.r / 255.0,
		(float)c1p.g / 255.0,
		(float)c1p.b / 255.0,
		1.0
	};
	Vector c2 = {
		(float)c2p.r / 255.0,
		(float)c2p.g / 255.0,
		(float)c2p.b / 255.0,
		1.0
	};
	Vector c3 = {
		(float)c3p.r / 255.0,
		(float)c3p.g / 255.0,
		(float)c3p.b / 255.0,
		1.0
	};

	Vector v1, v2, v3;
	Vector n1, n2, n3;
	Vector L1, L2, L3;

	// Next, apply the modelview matrix to the triangle's vertices
	vv_cpy(v1, v1p); vv_cpy(v2, v2p); vv_cpy(v3, v3p);
	vm_mul(v1, modelview);
	vm_mul(v2, modelview);
	vm_mul(v3, modelview);

	// And also to the normals
	vv_cpy(n1, n1p); vv_cpy(n2, n2p); vv_cpy(n3, n3p);
	vm_mul(n1, modelview);
	vm_mul(n2, modelview);
	vm_mul(n3, modelview);

	// Find the distance for each point from the light
	vv_cpy(L1, lightpos); vv_sub(L1, v1); v_norm(L1);
	vv_cpy(L2, lightpos); vv_sub(L2, v2); v_norm(L2);
	vv_cpy(L3, lightpos); vv_sub(L3, v3); v_norm(L3);

	// Then, apply our lighting equations
	// We assume that the triangle's ambient and diffuse values are the same
	// We also assume that 
	for(j = 0; j < 4; j++) {
		c1[j] = light_transform(c1[j], n1, L1, j);
		c2[j] = light_transform(c2[j], n2, L2, j);
		c2[j] = light_transform(c3[j], n3, L3, j);
	}

	// Convert the color values to values the graphics card will accept
	// c1p et al were passed by value, so we can modify them
	c1p.r = c1[0] * 255;
	c1p.g = c1[1] * 255;
	c1p.b = c1[2] * 255;
	c2p.r = c2[0] * 255;
	c2p.g = c2[1] * 255;
	c2p.b = c2[2] * 255;
	c3p.r = c3[0] * 255;
	c3p.g = c3[1] * 255;
	c3p.b = c3[2] * 255;

	// Lastly, find the coordinates on the screen for each point,
	// and draw the triangle
	x1 = 800 * (depth/height) * (v1[0] / v1[2]);
	y1 = 600 * (depth/height) * (v1[1] / v1[2]);
	x2 = 800 * (depth/height) * (v2[0] / v2[2]);
	y2 = 600 * (depth/height) * (v2[1] / v2[2]);
	x3 = 800 * (depth/height) * (v3[0] / v3[2]);
	y3 = 600 * (depth/height) * (v3[1] / v3[2]);
	draw_2d_tri(x1, y1, c1p, x2, y2, c2p, x3, y3, c3p);

	printf("v1: %f %f %f\n", v1[0], v1[1], v1[2]);
	printf("v2: %f %f %f\n", v2[0], v2[1], v2[2]);
	printf("v2: %f %f %f\n", v3[0], v3[1], v3[2]);
	printf("%d %d; %d %d; %d %d\n", x1, y1, x2, y2, x3, y3);

	return GRAPH3D_OK;
}