const Quaternion QuaternionManipulator::qFromAngleAxis(float theta, Vector axis)
{
	Vector axisn = vNormalize(axis);

	Quaternion q;
	float a = theta * (float)DEGREES_TO_RADIANS;
	q.t = cos(a / 2.0f);
	float s = sin(a / 2.0f);
	q.x = axisn.x * s;
	q.y = axisn.y * s;
	q.z = axisn.z * s;

	qClean(q);
	return qNormalize(q);
	//return q;
}
Exemple #2
0
// -----------------------------------------------------------------------------
int 
iDcmLoop (void) {
  static uint16_t usLoopCount;
  
  // Indicate that the DCM is ready when > 5s.
  if (++usLoopCount > (CFG_DCM_READY_DELAY / DCM_DT)) {

    xState.bReady = 1;
  }	

  // Read from the sensors
  vReadSensors();
  if (xState.iError >= 0) {
  
    // Predict next state of DCM
    vDcmPredict();
    
    // Normalize the DCM
    vNormalize();
    
    // Correct the gyro drift
    vDcmCorrectDrift();
    
    // Convert the DCM to Euler angle
    vCalculateEuler();
    
    // Convert the yaw angle to 0 - 2PI
    CONVERT_0_2PI(xAttitudeTemp.fAtt[YAW]);
    
    // Calculate the actual rate
    vVector3fAdd (xAttitudeTemp.fRate, fGyroVector, fRateCorrectionI);
    
    // Copy the attitude to the private global variable.
    // We don't want to switch the context during this process
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
    
      xAttitude = xAttitudeTemp;
    }
    if (xState.bReady == 0)
      xState.iError = DCM_NOT_READY;
  }
Exemple #3
0
void InitBeam(void)
// initialize beam; produce description string
{
	double w0; // beam width
	/* TO ADD NEW BEAM
	 * Add here all intermediate variables, which are used only inside this function.
	 */

	// initialization of global option index for error messages
	opt=opt_beam;
	// beam initialization
	switch (beamtype) {
		case B_PLANE:
			if (IFROOT) strcpy(beam_descr,"plane wave");
			beam_asym=false;
			if (surface) {
				if (prop_0[2]==0) PrintError("Ambiguous setting of beam propagating along the surface. Please specify "
					"the incident direction to have (arbitrary) small positive or negative z-component");
				if (msubInf && prop_0[2]>0) PrintError("Perfectly reflecting surface ('-surf ... inf') is incompatible "
					"with incident direction from below (including the default one)");
				// Here we set ki,kt,ktVec and propagation directions prIncRefl,prIncTran
				if (prop_0[2]>0) { // beam comes from the substrate (below)
					// here msub should always be defined
					inc_scale=1/creal(msub);
					ki=msub*prop_0[2];
					/* Special case for msub near 1 to remove discontinuities for near-grazing incidence. The details
					 * are discussed in CalcFieldSurf() in crosssec.c.
					 */
					if (cabs(msub-1)<ROUND_ERR && fabs(ki)<SQRT_RND_ERR) kt=ki;
					else kt=cSqrtCut(1 - msub*msub*(prop_0[0]*prop_0[0]+prop_0[1]*prop_0[1]));
					// determine propagation direction and full wavevector of wave transmitted into substrate
					ktVec[0]=msub*prop_0[0];
					ktVec[1]=msub*prop_0[1];
					ktVec[2]=kt;
				}
				else if (prop_0[2]<0) { // beam comes from above the substrate
					inc_scale=1;
					vRefl(prop_0,prIncRefl);
					ki=-prop_0[2];
					if (!msubInf) {
						// same special case as above
						if (cabs(msub-1)<ROUND_ERR && fabs(ki)<SQRT_RND_ERR) kt=ki;
						else kt=cSqrtCut(msub*msub - (prop_0[0]*prop_0[0]+prop_0[1]*prop_0[1]));
						// determine propagation direction of wave transmitted into substrate
						ktVec[0]=prop_0[0];
						ktVec[1]=prop_0[1];
						ktVec[2]=-kt;
					}
				}
				else LogError(ONE_POS,"Ambiguous setting of beam propagating along the surface. Please specify the"
					"incident direction to have (arbitrary) small positive or negative z-component");
				vRefl(prop_0,prIncRefl);
				if (!msubInf) {
					vReal(ktVec,prIncTran);
					vNormalize(prIncTran);
				}
			}
			return;
		case B_DIPOLE:
			vCopy(beam_pars,beam_center_0);
			if (surface) {
				if (beam_center_0[2]<=-hsub)
					PrintErrorHelp("External dipole should be placed strictly above the surface");
				inc_scale=1; // but scaling of Mueller matrix is weird anyway
			}
			// in weird scenarios the dipole can be positioned exactly at the origin; reused code from Gaussian beams
			beam_asym=(beam_center_0[0]!=0 || beam_center_0[1]!=0 || beam_center_0[2]!=0);
			if (!beam_asym) vInit(beam_center);
			/* definition of p0 is important for scaling of many scattering quantities (that are normalized to incident
			 * irradiance). Alternative definition is p0=1, but then the results will scale with unit of length
			 * (breaking scale invariance)
			 */
			p0=1/(WaveNum*WaveNum*WaveNum);
			if (IFROOT) sprintf(beam_descr,"point dipole at "GFORMDEF3V,COMP3V(beam_center_0));
			return;
		case B_LMINUS:
		case B_DAVIS3:
		case B_BARTON5:
			if (surface) PrintError("Currently, Gaussian incident beam is not supported for '-surf'");
			// initialize parameters
			w0=beam_pars[0];
			TestPositive(w0,"beam width");
			vCopy(beam_pars+1,beam_center_0);
			beam_asym=(beam_Npars==4 && (beam_center_0[0]!=0 || beam_center_0[1]!=0 || beam_center_0[2]!=0));
			if (!beam_asym) vInit(beam_center);
			s=1/(WaveNum*w0);
			s2=s*s;
			scale_x=1/w0;
			scale_z=s*scale_x; // 1/(k*w0^2)
			// beam info
			if (IFROOT) {
				strcpy(beam_descr,"Gaussian beam (");
				switch (beamtype) {
					case B_LMINUS:
						strcat(beam_descr,"L- approximation)\n");
						break;
					case B_DAVIS3:
						strcat(beam_descr,"3rd order approximation, by Davis)\n");
						break;
					case B_BARTON5:
						strcat(beam_descr,"5th order approximation, by Barton)\n");
						break;
					default: break;
				}
				sprintf(beam_descr+strlen(beam_descr),"\tWidth="GFORMDEF" (confinement factor s="GFORMDEF")\n"
				                                      "\tCenter position: "GFORMDEF3V,w0,s,COMP3V(beam_center_0));
			}
			return;
		case B_READ:
			// the safest is to assume cancellation of all symmetries
			symX=symY=symZ=symR=false;
			if (surface) inc_scale=1; // since we can't know it, we assume the default case
			if (IFROOT) {
				if (beam_Npars==1) sprintf(beam_descr,"specified by file '%s'",beam_fnameY);
				else sprintf(beam_descr,"specified by files '%s' and '%s'",beam_fnameY,beam_fnameX);
			}
			// we do not define beam_asym here, because beam_center is not defined anyway
			return;
	}
	LogError(ONE_POS,"Unknown type of incident beam (%d)",(int)beamtype);
	/* TO ADD NEW BEAM
	 * add a case above. Identifier ('B_...') should be defined inside 'enum beam' in const.h. The case should
	 * 1) save all the input parameters from array 'beam_pars' to local variables (defined in the beginning of this
	 *    source files)
	 * 2) test all input parameters (for that you're encouraged to use functions from param.h since they would
	 *    automatically produce informative output in case of error).
	 * 3) the symmetry breaking due to prop or beam_center is taken care of in VariablesInterconnect() in param.c.
	 *    But if there are other reasons why beam would break any symmetry, corresponding variable should be set to
	 *    false here. Do not set any of them to true, as they can be set to false by other factors.
	 *    symX, symY, symZ - symmetries of reflection over planes YZ, XZ, XY respectively.
	 *    symR - symmetry of rotation for 90 degrees over the Z axis
	 * 4) initialize the following:
	 *    beam_descr - descriptive string, which will appear in log file.
	 *    beam_asym - whether beam center does not coincide with the reference frame origin. If it is set to true, then
	 *                set also beam_center_0 - 3D radius-vector of beam center in the laboratory reference frame (it
	 *                will be then automatically transformed to particle reference frame, if required).
	 * 5) Consider the case of surface (substrate near the particle). If the new beam type is incompatible with it, add
	 *    an explicit exception, like "if (surface) PrintErrorHelp(...);". Otherwise, you also need to define inc_scale.
	 * All other auxiliary variables, which are used in beam generation (GenerateB(), see below), should be defined in
	 * the beginning of this file. If you need temporary local variables (which are used only in this part of the code),
	 * define them in the beginning of this function.
	 */
}