版本说明:
PX4 v1.14.0 的加速度转换姿态四元数代码有些问题,z轴期望加速度不为0时,xy轴期望加速度会移入额外误差,这个 BUG 在 PX4 v1.15.1 中已经修正,但是又有额外的问题。因此还是使用 v1.14.0,只是修复相关代码。
先比较一下 1.14.0 与 1.15.1 源码
https://github.com/PX4/PX4-Autopilot/compare/1e4fcfc..2e6dd24
搜索 src/modules/mc_pos_control/PositionControl/PositionControl.cpp
查看两个版本 void PositionControl::_accelerationControl()
函数的代码对比
v1.14.0
void PositionControl::_accelerationControl()
{
// Assume standard acceleration due to gravity in vertical direction for attitude generation
Vector3f body_z = Vector3f(-_acc_sp(0), -_acc_sp(1), CONSTANTS_ONE_G).normalized();
ControlMath::limitTilt(body_z, Vector3f(0, 0, 1), _lim_tilt);
// Scale thrust assuming hover thrust produces standard gravity
float collective_thrust = _acc_sp(2) * (_hover_thrust / CONSTANTS_ONE_G) - _hover_thrust;
// Project thrust to planned body attitude
collective_thrust /= (Vector3f(0, 0, 1).dot(body_z));
collective_thrust = math::min(collective_thrust, -_lim_thr_min);
_thr_sp = body_z * collective_thrust;
}
v1.15.1
void PositionControl::_accelerationControl()
{
// Assume standard acceleration due to gravity in vertical direction for attitude generation
float z_specific_force = -CONSTANTS_ONE_G;
if (!_decouple_horizontal_and_vertical_acceleration) {
// Include vertical acceleration setpoint for better horizontal acceleration tracking
z_specific_force += _acc_sp(2);
}
Vector3f body_z = Vector3f(-_acc_sp(0), -_acc_sp(1), -z_specific_force).normalized();
ControlMath::limitTilt(body_z, Vector3f(0, 0, 1), _lim_tilt);
// Convert to thrust assuming hover thrust produ // Modified by Zhang San, based on v1.15.1.ces standard gravity
const float thrust_ned_z = _acc_sp(2) * (_hover_thrust / CONSTANTS_ONE_G) - _hover_thrust;
// Project thrust to planned body attitude
const float cos_ned_body = (Vector3f(0, 0, 1).dot(body_z));
const float collective_thrust = math::min(thrust_ned_z / cos_ned_body, -_lim_thr_min);
_thr_sp = body_z * collective_thrust;
}
注意到_decouple_horizontal_and_vertical_acceleration
,在PositionControl.hpp
中定义。
bool _decouple_horizontal_and_vertical_acceleration{false}; ///< Ignore vertical acceleration setpoint to remove its effect on the tilt setpoint
void decoupleHorizontalAndVecticalAcceleration(bool val) { _decouple_horizontal_and_vertical_acceleration = val; }
MulticopterPositionControl.cpp
中调用了decoupleHorizontalAndVecticalAcceleration()
函数将该值设置为MPC_ACC_DECOUPLE
的值。
_control.decoupleHorizontalAndVecticalAcceleration(_param_mpc_acc_decouple.get());
可以看到 1.15.1 新引入了一个参数 MPC_ACC_DECOUPLE
。来控制 Z轴的加速度控制策略。
-
MPC_ACC_DECOUPLE (
INT32
)Acceleration to tilt coupling.
Set to decouple tilt from vertical acceleration. This provides smoother flight but slightly worse tracking in position and auto modes. Unset if accurate position tracking during dynamic maneuvers is more important than a smooth flight.
参考
该参数默认值为 Enable(解耦),所以存在和 PX4 1.14.0 一样的问题。需要手动设置为 false。这里我们修改 1.14.0 的源码,不用管该参数。直接将函数改为
// Modified by Zhang San, based on v1.15.1.
void PositionControl::_accelerationControl()
{
// Assume standard acceleration due to gravity in vertical direction for attitude generation
float z_specific_force = -CONSTANTS_ONE_G;
// if (!_decouple_horizontal_and_vertical_acceleration) {
// Include vertical acceleration setpoint for better horizontal acceleration tracking
z_specific_force += _acc_sp(2);
// }
Vector3f body_z = Vector3f(-_acc_sp(0), -_acc_sp(1), -z_specific_force).normalized();
ControlMath::limitTilt(body_z, Vector3f(0, 0, 1), _lim_tilt);
// Convert to thrust assuming hover thrust produces standard gravity
const float thrust_ned_z = _acc_sp(2) * (_hover_thrust / CONSTANTS_ONE_G) - _hover_thrust;
// Project thrust to planned body attitude
const float cos_ned_body = (Vector3f(0, 0, 1).dot(body_z));
const float collective_thrust = math::min(thrust_ned_z / cos_ned_body, -_lim_thr_min);
_thr_sp = body_z * collective_thrust;
}
然后编译飞控即可