PX4代码解析:姿态期望生成

转载自 PX4代码解析:姿态期望生成位置控制输出\x0a姿态期望生成 https://mp.weixin.qq.com/s/weGCgpAWEgilw9KPh5OZ9Q

如有侵权可以私信联系删除

PX4代码解析:姿态期望生成

原创 无人机系统技术 无人机系统技术 2019年09月14日 20:00

 

引言

 

关于PX4源码中控制器的设计部分我们前几讲已经对位置控制、姿态控制等核心函数进行了详细分析,逐行解释。今天我们就将剩下的最后一部分内容:位置控制器输出到姿态控制器输入的转换部分做一个解读。

 

转换部分的函数就一个:

 

vehicle_attitude_setpoint_s thrustToAttitude(const Vector3f &thr_sp, const float yaw_sp)在Firmware\src\modules\mc_pos_control\Utility\ControlMath.cpp文件中。

 

我们先贴出此函数的源码:

vehicle_attitude_setpoint_s thrustToAttitude(const Vector3f &thr_sp, const float yaw_sp){  vehicle_attitude_setpoint_s att_sp = {};  att_sp.yaw_body = yaw_sp;
  // desired body_z axis = -normalize(thrust_vector)  Vector3f body_x, body_y, body_z;
  if (thr_sp.length() > 0.00001f) {    body_z = -thr_sp.normalized();
  } else {    // no thrust, set Z axis to safe value    body_z = Vector3f(0.f, 0.f, 1.f);  }
  // vector of desired yaw direction in XY plane, rotated by PI/2  Vector3f y_C(-sinf(att_sp.yaw_body), cosf(att_sp.yaw_body), 0.0f);
  if (fabsf(body_z(2)) > 0.000001f) {    // desired body_x axis, orthogonal to body_z    body_x = y_C % body_z;
    // keep nose to front while inverted upside down    if (body_z(2) < 0.0f) {      body_x = -body_x;    }
    body_x.normalize();
  } else {    // 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;  }
  // desired body_y axis  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);  att_sp.q_d_valid = true;
  // 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.thrust_body[2] = -thr_sp.length();
  return att_sp;}

 

 

代码解读

 

//函数开始:

vehicle_attitude_setpoint_s thrustToAttitude(const Vector3f &thr_sp, const float yaw_sp){

 

//定义姿态期望,赋值期望偏航角​​​​​​

  vehicle_attitude_setpoint_s att_sp = {};  att_sp.yaw_body = yaw_sp;

 

//定义期望机体轴系三个轴的单位向量在机载NED系下的表示

  // desired body_z axis = -normalize(thrust_vector)  Vector3f body_x, body_y, body_z;

 

//根据期望升力的方向给期望机体轴系的Z轴单位向量赋值​​​​​​​

  if (thr_sp.length() > 0.00001f) {    body_z = -thr_sp.normalized();
  } else {

 

//如果期望升力向量模为0时,归一化会出现奇异,赋值成(0,0,1)    ​​​​​​​

    // no thrust, set Z axis to safe value    body_z = Vector3f(0.f, 0.f, 1.f);  }

 

//机体轴系X轴单位向量在NE平面的投影绕D轴旋转PI/2角度后的向量​​​​​​​​​​​​​​

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

 

//期望机体轴系的X轴与Z轴以及上一行计算出来的向量垂直,因此通过叉乘计算可以得到期望机体轴系的X轴单位向量​​​​​​​

  if (fabsf(body_z(2)) > 0.000001f) {    // desired body_x axis, orthogonal to body_z    body_x = y_C % body_z;

 

//期望机体轴系的X轴在计算时与Z轴的方向是相关的,因为R3r的第三个元素的正负代表飞行器是否需要翻过来,如果飞行器需要翻过来,那么此时要保持机头方向还是向前需要加负号。计算后再做归一化处理。​​​​​​​

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

 

//如果期望机体轴系Z轴位于NE平面内,则将X轴赋值为(0,0,1),即机头垂直向下,此时,期望偏航角就不起作用了。​​​​​​​

  } else {    // 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;  }

 

//根据期望机体轴系三轴互相垂直的关系计算Y轴单位向量的值​​​​​​​​​​​​​​

  // desired body_y axis  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);  att_sp.q_d_valid = true;

 

//将旋转矩阵期望转换成欧拉角以及油门期望,用于日志记录,便于分析

  // 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.thrust_body[2] = -thr_sp.length();
  return att_sp;}

 

总结

 

本篇内容对PX4中位置控制器的输出转换成期望姿态的过程进行了详细解读,代码进行了逐行分析,关于算法公式的推导,大家可以参考之前的文章:无人机控制器设计(二):位置控制器设计

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值