50 #include <px4_platform_common/defines.h> 51 #include <px4_platform_common/module.h> 52 #include <px4_platform_common/module_params.h> 53 #include <px4_platform_common/posix.h> 72 class AttitudeEstimatorQ :
public ModuleBase<AttitudeEstimatorQ>,
public ModuleParams,
public px4::WorkItem
80 static int task_spawn(
int argc,
char *argv[]);
83 static int custom_command(
int argc,
char *argv[]);
86 static int print_usage(
const char *reason =
nullptr);
98 bool update(
float dt);
101 void update_mag_declination(
float new_declination);
104 const float _eo_max_std_dev = 100.0f;
105 const float _dt_min = 0.00001f;
106 const float _dt_max = 0.02f;
118 float _mag_decl{0.0f};
119 float _bias_max{0.0f};
140 bool _data_good{
false};
141 bool _ext_hdg_good{
false};
144 (ParamFloat<px4::params::ATT_W_ACC>) _param_att_w_acc,
145 (ParamFloat<px4::params::ATT_W_MAG>) _param_att_w_mag,
146 (ParamFloat<px4::params::ATT_W_EXT_HDG>) _param_att_w_ext_hdg,
147 (ParamFloat<px4::params::ATT_W_GYRO_BIAS>) _param_att_w_gyro_bias,
148 (ParamFloat<px4::params::ATT_MAG_DECL>) _param_att_mag_decl,
149 (ParamInt<px4::params::ATT_MAG_DECL_A>) _param_att_mag_decl_a,
150 (ParamInt<px4::params::ATT_EXT_HDG_M>) _param_att_ext_hdg_m,
151 (ParamInt<px4::params::ATT_ACC_COMP>) _param_att_acc_comp,
152 (ParamFloat<px4::params::ATT_BIAS_MAX>) _param_att_bias_mas,
153 (ParamInt<px4::params::SYS_HAS_MAG>) _param_sys_has_mag
158 ModuleParams(nullptr),
159 WorkItem(MODULE_NAME,
px4::wq_configurations::att_pos_ctrl)
182 PX4_ERR(
"sensor combined callback registration failed!");
216 if (
_accel.length() < 0.01f) {
217 PX4_ERR(
"degenerate accel!");
231 if (
_mag.length() < 0.01f) {
232 PX4_ERR(
"degenerate mag!");
249 bool vision_att_valid = PX4_ISFINITE(vision.
q[0])
250 && (PX4_ISFINITE(vision.
pose_covariance[vision.COVARIANCE_MATRIX_ROLL_VARIANCE]) ? sqrtf(fmaxf(
255 if (vision_att_valid) {
265 if (_param_att_ext_hdg_m.get() == 1) {
278 bool mocap_att_valid = PX4_ISFINITE(mocap.
q[0])
279 && (PX4_ISFINITE(mocap.
pose_covariance[mocap.COVARIANCE_MATRIX_ROLL_VARIANCE]) ? sqrtf(fmaxf(
284 if (mocap_att_valid) {
294 if (_param_att_ext_hdg_m.get() == 2) {
365 if (_param_sys_has_mag.get() == 0) {
366 _param_att_w_mag.set(0.0
f);
406 _q =
_q * decl_rotation;
410 if (PX4_ISFINITE(
_q(0)) && PX4_ISFINITE(
_q(1)) &&
411 PX4_ISFINITE(
_q(2)) && PX4_ISFINITE(
_q(3)) &&
412 _q.length() > 0.95f &&
_q.length() < 1.05f) {
438 float spinRate =
_gyro.length();
441 if (_param_att_ext_hdg_m.get() == 1) {
445 float vision_hdg_err =
wrap_pi(atan2f(vision_hdg_earth(1), vision_hdg_earth(0)));
447 corr +=
_q.conjugate_inversed(
Vector3f(0.0
f, 0.0
f, -vision_hdg_err)) * _param_att_w_ext_hdg.get();
450 if (_param_att_ext_hdg_m.get() == 2) {
454 float mocap_hdg_err =
wrap_pi(atan2f(mocap_hdg_earth(1), mocap_hdg_earth(0)));
456 corr +=
_q.conjugate_inversed(
Vector3f(0.0
f, 0.0
f, -mocap_hdg_err)) * _param_att_w_ext_hdg.get();
465 float gainMult = 1.0f;
466 const float fifty_dps = 0.873f;
468 if (spinRate > fifty_dps) {
469 gainMult =
math::min(spinRate / fifty_dps, 10.0
f);
473 corr +=
_q.conjugate_inversed(
Vector3f(0.0
f, 0.0
f, -mag_err)) * _param_att_w_mag.get() * gainMult;
491 const float accel_norm_sq =
_accel.norm_squared();
495 if (_param_att_acc_comp.get() || ((accel_norm_sq > lower_accel_limit * lower_accel_limit) &&
496 (accel_norm_sq < upper_accel_limit * upper_accel_limit))) {
498 corr += (k % (
_accel -
_pos_acc).normalized()) * _param_att_w_acc.get();
502 if (spinRate < 0.175
f) {
503 _gyro_bias += corr * (_param_att_w_gyro_bias.get() *
dt);
505 for (
int i = 0; i < 3; i++) {
517 _q +=
_q.derivative1(corr) *
dt;
522 if (!(PX4_ISFINITE(
_q(0)) && PX4_ISFINITE(
_q(1)) &&
523 PX4_ISFINITE(
_q(2)) && PX4_ISFINITE(
_q(3)))) {
545 _q =
_q * decl_rotation;
562 _object.store(instance);
563 _task_id = task_id_is_work_queue;
565 if (instance->
init()) {
570 PX4_ERR(
"alloc failed");
574 _object.store(
nullptr);
584 PX4_WARN(
"%s\n", reason);
587 PRINT_MODULE_DESCRIPTION(
590 Attitude estimator q. 594 PRINT_MODULE_USAGE_NAME("AttitudeEstimatorQ",
"estimator");
595 PRINT_MODULE_USAGE_COMMAND(
"start");
596 PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
constexpr _Tp constrain(_Tp val, _Tp min_val, _Tp max_val)
void update_parameters(bool force=false)
const float _eo_max_std_dev
Maximum permissible standard deviation for estimated orientation.
static int task_spawn(int argc, char *argv[])
bool update(void *dst)
Copy the struct if updated.
Definition of geo / math functions to perform geodesic calculations.
uORB::Subscription _global_pos_sub
int main(int argc, char **argv)
float accelerometer_m_s2[3]
static void print_usage()
High-resolution timer with callouts and timekeeping.
static constexpr float CONSTANTS_ONE_G
Global flash based parameter store.
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
uORB::Subscription _mocap_odom_sub
bool publish(const T &data)
Publish the struct.
void init()
Activates/configures the hardware registers.
constexpr T radians(T degrees)
void update_mag_declination(float new_declination)
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
static hrt_abstime hrt_elapsed_time(const hrt_abstime *then)
Compute the delta between a timestamp taken in the past and now.
uORB::SubscriptionCallbackWorkItem _sensors_sub
uORB::Publication< vehicle_attitude_s > _att_pub
bool updated()
Check if there is a new update.
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
constexpr _Tp min(_Tp a, _Tp b)
Type wrap_pi(Type x)
Wrap value in range [-π, π)
Calculation / lookup table for Earth's magnetic field declination, inclination and strength...
uORB::Subscription _magnetometer_sub
Vector3< float > Vector3f
int update_parameters(const ParameterHandles ¶meter_handles, Parameters ¶meters)
Read out the parameters using the handles into the parameters struct.
Quaternion< float > Quatf
uORB::Subscription _parameter_update_sub
uORB::Subscription _vision_odom_sub
float pose_covariance[21]
const Slice< Type, 1, N, M, N > row(size_t i) const
void unregisterCallback()
static int print_usage(const char *reason=nullptr)
__EXPORT int attitude_estimator_q_main(int argc, char *argv[])
int32_t accelerometer_timestamp_relative
float get_mag_declination(float lat, float lon)
static int custom_command(int argc, char *argv[])
bool copy(void *dst)
Copy the struct.
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).