PX4多旋翼期望姿态矩阵生成算法

1. PX4多旋翼期望姿态生成算法

PX4多旋翼期望姿态生成采用旋转矩阵方法,基本思路为根据外环解算获得期望推力方向(即期望体轴Z轴向量,因为多旋翼推力方向与体轴Z轴重合),再求期望体轴X轴向量,最后根据X轴、Z轴求得Y轴,再根据三个轴的向量求得期望姿态的旋转矩阵,最后根据期望姿态旋转矩阵求得期望姿态角(欧拉角主要用于记录和调试)。

当前PX4固件该段算法代码位于src\modules\mc_pos_control\PositionControl\ControlMath.cpp中的bodyzToAttitude()函数中实现。

void bodyzToAttitude(Vector3f body_z, const float yaw_sp, vehicle_attitude_setpoint_s &att_sp)
{
	// zero vector, no direction, set safe level value
	if (body_z.norm_squared() < FLT_EPSILON) {
		body_z(2) = 1.f;
	}

	body_z.normalize();

	// vector of desired yaw direction in XY plane, rotated by PI/2
	Vector3f y_C(-sinf(yaw_sp), cosf(yaw_sp), 0.0f);

	// desired body_x axis, orthogonal to body_z
	Vector3f body_x = y_C % body_z;

	// keep nose to front while inverted upside down
	if (body_z(2) < 0.0f) {
		body_x = -body_x;
	}

	if (fabsf(body_z(2)) < 0.000001f) {
		// desired thrust is in XY plane, set X downside to construct correct matrix,
		// but yaw component will not be used actually
		body_x.zero();
		body_x(2) = 1.0f;
	}

	body_x.normalize();

	// desired body_y axis
	Vector3f body_y = body_z % body_x;

	Dcmf R_sp;

	// fill rotation matrix
	for (int i = 0; i < 3; i++) {
		R_sp(i, 0) = body_x(i);
		R_sp(i, 1) = body_y(i);
		R_sp(i, 2) = body_z(i);
	}

	// copy quaternion setpoint to attitude setpoint topic
	Quatf q_sp = R_sp;
	q_sp.copyTo(att_sp.q_d);

	// calculate euler angles, for logging only, must not be used for control
	Eulerf euler = R_sp;
	att_sp.roll_body = euler(0);
	att_sp.pitch_body = euler(1);
	att_sp.yaw_body = euler(2);
}

1.1. 求期望体轴X轴向量

  // vector of desired yaw direction in XY plane, rotated by PI/2
	Vector3f y_C(-sinf(yaw_sp), cosf(yaw_sp), 0.0f);

	// desired body_x axis, orthogonal to body_z
	Vector3f body_x = y_C % body_z;

求期望体轴X轴向量主要由上面两行程序执行,其中yaw_sp根据外环解算已经获得,据此可获得期望体轴X轴单位向量在NED坐标系XY平面的投影(cosf(yaw_sp),sinf(yaw_sp),0.0f)y_C为将投影向量向左旋转90°后的向量(交换xy坐标,并新向量的x坐标添加负号,表示左转,这样使用y_C叉乘body_z后即为body_x),根据空间几何特性可知,y_C向量也垂直于期望体轴X轴(平面a内的直线x垂直于直线y在平面a里的投影y`,则直线x垂直于直线y —— 因为:直线x垂直于投影y`,直线y到平面a的垂线垂直于直线x,所以直线x垂直于投影y`与垂线组成的平面,而直线y位于投影y`与垂线组成的平面内,所以直线x垂直于直线y)。

期望体轴Z轴向量body_z已知,根据期望体轴X轴垂直于y_C,垂直于body_z,可通过y_Cbody_z的向量积求得期望体轴的X轴向量body_x

1.2. 求期望体轴Y轴向量

	// desired body_y axis
	Vector3f body_y = body_z % body_x;

期望体轴Y轴向量body_y通过期望体轴Z轴向量body_z与期望体轴X轴向量body_x求向量积可求得(注意向量积顺序)。

1.3. 求期望姿态矩阵

	Dcmf R_sp;

	// fill rotation matrix
	for (int i = 0; i < 3; i++) {
		R_sp(i, 0) = body_x(i);
		R_sp(i, 1) = body_y(i);
		R_sp(i, 2) = body_z(i);
	}

期望姿态矩阵根据求得的期望体轴向量借助旋转矩阵作用原理求得。

R e b ⋅ v e ⃗ = v b ⃗ R_e^b \cdot \vec{v_e} = \vec{v_b} Rebve =vb

其中 R e b R_e^b Reb为NED到体轴的旋转矩阵, v e ⃗ \vec{v_e} ve 为NED坐标系下的向量, v b ⃗ \vec{v_b} vb 为经过旋转后的体轴坐标系下的向量。 R e b R_e^b Reb向量如下:

R e b = [ a 00 a 01 a 02 a 10 a 11 a 12 a 20 a 21 a 22 ] R_e^b = \left[ \begin{matrix} a_{00}&a_{01}&a_{02}\\ a_{10}&a_{11}&a_{12}\\ a_{20}&a_{21}&a_{22}\\ \end{matrix} \right] Reb=a00a10a20a01a11a21a02a12a22

v e ⃗ \vec{v_e} ve 为NED坐标系下 x x x轴的单位向量 x e i ⃗ = [ 1 0 0 ] ′ \vec{x_{ei}} = \left[\begin{matrix}1&0&0\end{matrix}\right]' xei =[100],经过旋转后成为体轴坐标系下的向量 x b i ⃗ \vec{x_{bi}} xbi ,即body_x,即:
R e b ⋅ x e i ⃗ = [ a 00 a 01 a 02 a 10 a 11 a 12 a 20 a 21 a 22 ] ⋅ [ 1 0 0 ] = [ a 00 a 10 a 20 ] = [ b o d y _ x ( 0 ) b o d y _ x ( 1 ) b o d y _ x ( 2 ) ] R_e^b \cdot \vec{x_{ei}} = \left[ \begin{matrix} a_{00}&a_{01}&a_{02}\\ a_{10}&a_{11}&a_{12}\\ a_{20}&a_{21}&a_{22}\\ \end{matrix} \right] \cdot \left[\begin{matrix}1\\0\\0\end{matrix}\right]=\left[\begin{matrix}a_{00}\\a_{10}\\a_{20}\end{matrix}\right]=\left[\begin{matrix}body\_x(0)\\body\_x(1)\\body\_x(2)\end{matrix}\right] Rebxei =a00a10a20a01a11a21a02a12a22100=a00a10a20=body_x(0)body_x(1)body_x(2)
据此可根据body_x求得 R e b R_e^b Reb中对应位置变量,同理可采用同样方法通过body_ybody_z求得 R e b R_e^b Reb其他位置变量,据此可得出期望姿态旋转矩阵 R e b R_e^b Reb

1.4. 求期望姿态角

	// calculate euler angles, for logging only, must not be used for control
	Eulerf euler = R_sp;
	att_sp.roll_body = euler(0);
	att_sp.pitch_body = euler(1);
	att_sp.yaw_body = euler(2);

根据旋转矩阵求欧拉角,px4中使用的旋转顺序为ZYX。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值