根據旋轉矩陣R求解歐拉角yaw,pitch,roll源代碼

///Data storage for the matrix, each vector is a row of the matrix
	Vector3 m_el[3];
/**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR
	* @param yaw Yaw around Z axis
	* @param pitch Pitch around Y axis
	* @param roll around X axis */	
	void getEulerYPR(tfScalar& yaw, tfScalar& pitch, tfScalar& roll, unsigned int solution_number = 1) const
	{
		struct Euler
		{
			tfScalar yaw;
			tfScalar pitch;
			tfScalar roll;
		};

		Euler euler_out;
		Euler euler_out2; //second solution
		//get the pointer to the raw data

		// Check that pitch is not at a singularity
  		// Check that pitch is not at a singularity
		if (tfFabs(m_el[2].x()) >= 1)
		{
			euler_out.yaw = 0;
			euler_out2.yaw = 0;
	
			// From difference of angles formula
			if (m_el[2].x() < 0)  //gimbal locked down
			{
			  tfScalar delta = tfAtan2(m_el[0].y(),m_el[0].z());
				euler_out.pitch = TFSIMD_PI / tfScalar(2.0);
				euler_out2.pitch = TFSIMD_PI / tfScalar(2.0);
				euler_out.roll = delta;
				euler_out2.roll = delta;
			}
			else // gimbal locked up
			{
			  tfScalar delta = tfAtan2(-m_el[0].y(),-m_el[0].z());
				euler_out.pitch = -TFSIMD_PI / tfScalar(2.0);
				euler_out2.pitch = -TFSIMD_PI / tfScalar(2.0);
				euler_out.roll = delta;
				euler_out2.roll = delta;
			}
		}
		else
		{
			euler_out.pitch = - tfAsin(m_el[2].x());
			euler_out2.pitch = TFSIMD_PI - euler_out.pitch;

			euler_out.roll = tfAtan2(m_el[2].y()/tfCos(euler_out.pitch), 
				m_el[2].z()/tfCos(euler_out.pitch));
			euler_out2.roll = tfAtan2(m_el[2].y()/tfCos(euler_out2.pitch), 
				m_el[2].z()/tfCos(euler_out2.pitch));

			euler_out.yaw = tfAtan2(m_el[1].x()/tfCos(euler_out.pitch), 
				m_el[0].x()/tfCos(euler_out.pitch));
			euler_out2.yaw = tfAtan2(m_el[1].x()/tfCos(euler_out2.pitch), 
				m_el[0].x()/tfCos(euler_out2.pitch));
		}

		if (solution_number == 1)
		{ 
			yaw = euler_out.yaw; 
			pitch = euler_out.pitch;
			roll = euler_out.roll;
		}
		else
		{ 
			yaw = euler_out2.yaw; 
			pitch = euler_out2.pitch;
			roll = euler_out2.roll;
		}
	}

代碼來源:ros/LinearMath/Matrix3x3.h

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章