2016-02-25 13:13:02 -04:00
|
|
|
#pragma once
|
2010-09-08 05:21:46 -03:00
|
|
|
|
2016-05-02 18:39:03 -03:00
|
|
|
#include <cmath>
|
2016-02-25 13:13:02 -04:00
|
|
|
#include <limits>
|
2016-05-02 18:39:03 -03:00
|
|
|
#include <stdint.h>
|
2016-02-25 13:13:02 -04:00
|
|
|
#include <type_traits>
|
2010-09-08 05:21:46 -03:00
|
|
|
|
2015-08-11 03:28:44 -03:00
|
|
|
#include <AP_Common/AP_Common.h>
|
|
|
|
#include <AP_Param/AP_Param.h>
|
2016-02-25 13:13:02 -04:00
|
|
|
|
2016-05-02 18:39:03 -03:00
|
|
|
#include "definitions.h"
|
2019-05-19 09:05:36 -03:00
|
|
|
#include "crc.h"
|
2016-05-02 18:39:03 -03:00
|
|
|
#include "matrix3.h"
|
|
|
|
#include "polygon.h"
|
|
|
|
#include "quaternion.h"
|
2012-03-09 22:44:36 -04:00
|
|
|
#include "rotations.h"
|
2010-09-08 05:21:46 -03:00
|
|
|
#include "vector2.h"
|
|
|
|
#include "vector3.h"
|
2018-03-23 01:08:34 -03:00
|
|
|
#include "spline5.h"
|
2019-03-11 14:15:09 -03:00
|
|
|
#include "location.h"
|
2020-09-07 05:47:51 -03:00
|
|
|
#include "control.h"
|
2014-04-03 19:44:56 -03:00
|
|
|
|
2024-09-23 06:43:11 -03:00
|
|
|
static const float NaNf = nanf("0x4152");
|
|
|
|
|
2021-05-04 08:12:23 -03:00
|
|
|
#if HAL_WITH_EKF_DOUBLE
|
|
|
|
typedef Vector2<double> Vector2F;
|
|
|
|
typedef Vector3<double> Vector3F;
|
|
|
|
typedef Matrix3<double> Matrix3F;
|
|
|
|
typedef QuaternionD QuaternionF;
|
|
|
|
#else
|
|
|
|
typedef Vector2<float> Vector2F;
|
|
|
|
typedef Vector3<float> Vector3F;
|
|
|
|
typedef Matrix3<float> Matrix3F;
|
|
|
|
typedef Quaternion QuaternionF;
|
|
|
|
#endif
|
|
|
|
|
2012-02-17 19:00:26 -04:00
|
|
|
// define AP_Param types AP_Vector3f and Ap_Matrix3f
|
|
|
|
AP_PARAMDEFV(Vector3f, Vector3f, AP_PARAM_VECTOR3F);
|
2012-02-23 07:56:40 -04:00
|
|
|
|
2016-04-16 06:59:20 -03:00
|
|
|
/*
|
|
|
|
* Check whether two floats are equal
|
|
|
|
*/
|
2017-06-20 21:42:39 -03:00
|
|
|
template <typename Arithmetic1, typename Arithmetic2>
|
2016-12-17 14:16:39 -04:00
|
|
|
typename std::enable_if<std::is_integral<typename std::common_type<Arithmetic1, Arithmetic2>::type>::value ,bool>::type
|
|
|
|
is_equal(const Arithmetic1 v_1, const Arithmetic2 v_2);
|
|
|
|
|
2017-06-20 21:42:39 -03:00
|
|
|
template <typename Arithmetic1, typename Arithmetic2>
|
2016-12-17 14:16:39 -04:00
|
|
|
typename std::enable_if<std::is_floating_point<typename std::common_type<Arithmetic1, Arithmetic2>::type>::value, bool>::type
|
|
|
|
is_equal(const Arithmetic1 v_1, const Arithmetic2 v_2);
|
2015-04-28 03:06:13 -03:00
|
|
|
|
2016-05-16 15:14:55 -03:00
|
|
|
/*
|
|
|
|
* @brief: Check whether a float is zero
|
|
|
|
*/
|
2017-06-20 21:42:39 -03:00
|
|
|
template <typename T>
|
2016-05-16 15:14:55 -03:00
|
|
|
inline bool is_zero(const T fVal1) {
|
|
|
|
static_assert(std::is_floating_point<T>::value || std::is_base_of<T,AP_Float>::value,
|
|
|
|
"Template parameter not of type float");
|
2022-01-25 16:15:41 -04:00
|
|
|
return is_zero(static_cast<float>(fVal1));
|
2016-05-16 15:14:55 -03:00
|
|
|
}
|
2016-04-16 06:59:08 -03:00
|
|
|
|
2017-05-18 23:47:56 -03:00
|
|
|
/*
|
|
|
|
* @brief: Check whether a float is greater than zero
|
|
|
|
*/
|
2017-06-20 21:42:39 -03:00
|
|
|
template <typename T>
|
2017-05-18 23:47:56 -03:00
|
|
|
inline bool is_positive(const T fVal1) {
|
|
|
|
static_assert(std::is_floating_point<T>::value || std::is_base_of<T,AP_Float>::value,
|
|
|
|
"Template parameter not of type float");
|
2017-05-26 21:20:10 -03:00
|
|
|
return (static_cast<float>(fVal1) >= FLT_EPSILON);
|
2017-05-18 23:47:56 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @brief: Check whether a float is less than zero
|
|
|
|
*/
|
2017-06-20 21:42:39 -03:00
|
|
|
template <typename T>
|
2017-05-18 23:47:56 -03:00
|
|
|
inline bool is_negative(const T fVal1) {
|
|
|
|
static_assert(std::is_floating_point<T>::value || std::is_base_of<T,AP_Float>::value,
|
|
|
|
"Template parameter not of type float");
|
2017-05-26 21:20:10 -03:00
|
|
|
return (static_cast<float>(fVal1) <= (-1.0 * FLT_EPSILON));
|
2017-05-18 23:47:56 -03:00
|
|
|
}
|
|
|
|
|
2021-12-14 05:05:33 -04:00
|
|
|
/*
|
|
|
|
* @brief: Check whether a double is greater than zero
|
|
|
|
*/
|
|
|
|
inline bool is_positive(const double fVal1) {
|
|
|
|
return (fVal1 >= static_cast<double>(FLT_EPSILON));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @brief: Check whether a double is less than zero
|
|
|
|
*/
|
|
|
|
inline bool is_negative(const double fVal1) {
|
|
|
|
return (fVal1 <= static_cast<double>((-1.0 * FLT_EPSILON)));
|
|
|
|
}
|
|
|
|
|
2016-04-16 06:59:08 -03:00
|
|
|
/*
|
|
|
|
* A variant of asin() that checks the input ranges and ensures a valid angle
|
|
|
|
* as output. If nan is given as input then zero is returned.
|
|
|
|
*/
|
2017-06-20 21:42:39 -03:00
|
|
|
template <typename T>
|
2016-04-16 06:59:08 -03:00
|
|
|
float safe_asin(const T v);
|
2012-02-23 19:40:56 -04:00
|
|
|
|
2016-04-16 06:59:08 -03:00
|
|
|
/*
|
|
|
|
* A variant of sqrt() that checks the input ranges and ensures a valid value
|
|
|
|
* as output. If a negative number is given then 0 is returned. The reasoning
|
|
|
|
* is that a negative number for sqrt() in our code is usually caused by small
|
|
|
|
* numerical rounding errors, so the real input should have been zero
|
|
|
|
*/
|
2017-06-20 21:42:39 -03:00
|
|
|
template <typename T>
|
2016-04-16 06:59:08 -03:00
|
|
|
float safe_sqrt(const T v);
|
2012-02-23 20:23:12 -04:00
|
|
|
|
2021-01-17 20:39:26 -04:00
|
|
|
// matrix multiplication of two NxN matrices
|
2021-01-09 14:09:13 -04:00
|
|
|
template <typename T>
|
2021-01-17 20:39:26 -04:00
|
|
|
void mat_mul(const T *A, const T *B, T *C, uint16_t n);
|
2015-12-05 05:10:07 -04:00
|
|
|
|
2021-01-17 20:39:26 -04:00
|
|
|
// matrix inverse
|
2021-01-09 14:09:13 -04:00
|
|
|
template <typename T>
|
2021-01-17 20:39:26 -04:00
|
|
|
bool mat_inverse(const T *x, T *y, uint16_t dim) WARN_IF_UNUSED;
|
2016-05-03 21:32:49 -03:00
|
|
|
|
2021-01-17 20:39:26 -04:00
|
|
|
// matrix identity
|
2021-01-09 14:09:13 -04:00
|
|
|
template <typename T>
|
2021-01-17 20:39:26 -04:00
|
|
|
void mat_identity(T *x, uint16_t dim);
|
2015-12-28 19:19:05 -04:00
|
|
|
|
2013-03-28 23:13:37 -03:00
|
|
|
/*
|
2016-04-27 06:35:18 -03:00
|
|
|
* Constrain an angle to be within the range: -180 to 180 degrees. The second
|
|
|
|
* parameter changes the units. Default: 1 == degrees, 10 == dezi,
|
|
|
|
* 100 == centi.
|
2013-03-28 23:13:37 -03:00
|
|
|
*/
|
2017-06-20 21:42:39 -03:00
|
|
|
template <typename T>
|
2019-09-18 00:13:51 -03:00
|
|
|
T wrap_180(const T angle);
|
2013-03-28 23:13:37 -03:00
|
|
|
|
2013-06-01 05:18:50 -03:00
|
|
|
/*
|
2016-04-27 06:35:18 -03:00
|
|
|
* Wrap an angle in centi-degrees. See wrap_180().
|
2013-06-01 05:18:50 -03:00
|
|
|
*/
|
2019-09-18 00:13:51 -03:00
|
|
|
template <typename T>
|
|
|
|
T wrap_180_cd(const T angle);
|
2013-06-01 05:18:50 -03:00
|
|
|
|
2015-11-24 17:11:34 -04:00
|
|
|
/*
|
2016-04-27 06:35:18 -03:00
|
|
|
* Constrain an euler angle to be within the range: 0 to 360 degrees. The
|
|
|
|
* second parameter changes the units. Default: 1 == degrees, 10 == dezi,
|
|
|
|
* 100 == centi.
|
2015-11-24 17:11:34 -04:00
|
|
|
*/
|
2019-09-18 00:13:51 -03:00
|
|
|
float wrap_360(const float angle);
|
2019-09-17 06:50:00 -03:00
|
|
|
#ifdef ALLOW_DOUBLE_MATH_FUNCTIONS
|
2019-09-18 00:13:51 -03:00
|
|
|
double wrap_360(const double angle);
|
2019-09-17 06:50:00 -03:00
|
|
|
#endif
|
2019-09-18 00:13:51 -03:00
|
|
|
int wrap_360(const int angle);
|
2019-09-17 06:50:00 -03:00
|
|
|
|
2019-09-18 00:13:51 -03:00
|
|
|
int wrap_360_cd(const int angle);
|
|
|
|
long wrap_360_cd(const long angle);
|
|
|
|
float wrap_360_cd(const float angle);
|
2019-09-17 06:50:00 -03:00
|
|
|
#ifdef ALLOW_DOUBLE_MATH_FUNCTIONS
|
2019-09-18 00:13:51 -03:00
|
|
|
double wrap_360_cd(const double angle);
|
2019-09-17 06:50:00 -03:00
|
|
|
#endif
|
2016-04-27 06:35:18 -03:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
wrap an angle in radians to -PI ~ PI (equivalent to +- 180 degrees)
|
|
|
|
*/
|
2021-07-08 23:29:47 -03:00
|
|
|
ftype wrap_PI(const ftype radian);
|
2016-04-27 06:35:18 -03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* wrap an angle in radians to 0..2PI
|
|
|
|
*/
|
2021-07-08 23:29:47 -03:00
|
|
|
ftype wrap_2PI(const ftype radian);
|
2015-11-24 17:11:34 -04:00
|
|
|
|
2016-04-16 06:58:58 -03:00
|
|
|
/*
|
|
|
|
* Constrain a value to be within the range: low and high
|
|
|
|
*/
|
2017-06-20 21:42:39 -03:00
|
|
|
template <typename T>
|
2016-04-16 06:58:58 -03:00
|
|
|
T constrain_value(const T amt, const T low, const T high);
|
2016-04-27 06:35:18 -03:00
|
|
|
|
2020-10-09 15:54:45 -03:00
|
|
|
template <typename T>
|
|
|
|
T constrain_value_line(const T amt, const T low, const T high, uint32_t line);
|
|
|
|
|
2023-02-15 07:20:52 -04:00
|
|
|
#define constrain_float(amt, low, high) constrain_value_line(float(amt), float(low), float(high), uint32_t(__AP_LINE__))
|
|
|
|
#define constrain_ftype(amt, low, high) constrain_value_line(ftype(amt), ftype(low), ftype(high), uint32_t(__AP_LINE__))
|
2016-05-11 14:35:30 -03:00
|
|
|
|
|
|
|
inline int16_t constrain_int16(const int16_t amt, const int16_t low, const int16_t high)
|
|
|
|
{
|
|
|
|
return constrain_value(amt, low, high);
|
|
|
|
}
|
|
|
|
|
2022-04-03 19:17:10 -03:00
|
|
|
inline uint16_t constrain_uint16(const uint16_t amt, const uint16_t low, const uint16_t high)
|
|
|
|
{
|
|
|
|
return constrain_value(amt, low, high);
|
|
|
|
}
|
|
|
|
|
2016-05-11 14:35:30 -03:00
|
|
|
inline int32_t constrain_int32(const int32_t amt, const int32_t low, const int32_t high)
|
|
|
|
{
|
|
|
|
return constrain_value(amt, low, high);
|
|
|
|
}
|
2015-03-21 05:48:46 -03:00
|
|
|
|
2022-04-03 19:17:10 -03:00
|
|
|
inline uint32_t constrain_uint32(const uint32_t amt, const uint32_t low, const uint32_t high)
|
|
|
|
{
|
|
|
|
return constrain_value(amt, low, high);
|
|
|
|
}
|
|
|
|
|
2018-04-17 00:54:06 -03:00
|
|
|
inline int64_t constrain_int64(const int64_t amt, const int64_t low, const int64_t high)
|
|
|
|
{
|
|
|
|
return constrain_value(amt, low, high);
|
|
|
|
}
|
|
|
|
|
2022-04-03 19:17:10 -03:00
|
|
|
inline uint64_t constrain_uint64(const uint64_t amt, const uint64_t low, const uint64_t high)
|
|
|
|
{
|
|
|
|
return constrain_value(amt, low, high);
|
|
|
|
}
|
|
|
|
|
2022-07-20 22:26:09 -03:00
|
|
|
inline double constrain_double(const double amt, const double low, const double high)
|
|
|
|
{
|
|
|
|
return constrain_value(amt, low, high);
|
|
|
|
}
|
|
|
|
|
2012-12-18 22:33:52 -04:00
|
|
|
// degrees -> radians
|
2021-07-08 23:20:50 -03:00
|
|
|
static inline constexpr ftype radians(ftype deg)
|
2016-05-03 21:32:49 -03:00
|
|
|
{
|
|
|
|
return deg * DEG_TO_RAD;
|
2015-03-21 05:48:46 -03:00
|
|
|
}
|
2012-12-18 22:33:52 -04:00
|
|
|
|
|
|
|
// radians -> degrees
|
2017-09-30 08:10:57 -03:00
|
|
|
static inline constexpr float degrees(float rad)
|
2016-05-03 21:32:49 -03:00
|
|
|
{
|
|
|
|
return rad * RAD_TO_DEG;
|
2015-03-21 05:48:46 -03:00
|
|
|
}
|
2012-12-18 22:33:52 -04:00
|
|
|
|
2017-06-20 21:42:39 -03:00
|
|
|
template<typename T>
|
2021-05-04 08:12:23 -03:00
|
|
|
ftype sq(const T val)
|
2016-04-16 06:58:46 -03:00
|
|
|
{
|
2021-05-04 08:12:23 -03:00
|
|
|
ftype v = static_cast<ftype>(val);
|
2019-02-22 23:10:10 -04:00
|
|
|
return v*v;
|
2015-03-21 05:48:46 -03:00
|
|
|
}
|
2022-03-22 03:24:47 -03:00
|
|
|
static inline constexpr float sq(const float val)
|
|
|
|
{
|
|
|
|
return val*val;
|
|
|
|
}
|
2015-03-21 05:48:46 -03:00
|
|
|
|
2016-04-16 06:58:46 -03:00
|
|
|
/*
|
|
|
|
* Variadic template for calculating the square norm of a vector of any
|
|
|
|
* dimension.
|
|
|
|
*/
|
2017-06-20 21:42:39 -03:00
|
|
|
template<typename T, typename... Params>
|
2021-05-04 08:12:23 -03:00
|
|
|
ftype sq(const T first, const Params... parameters)
|
2016-04-16 06:58:46 -03:00
|
|
|
{
|
|
|
|
return sq(first) + sq(parameters...);
|
2015-03-21 05:48:46 -03:00
|
|
|
}
|
2012-12-18 22:33:52 -04:00
|
|
|
|
2016-04-16 06:58:46 -03:00
|
|
|
/*
|
|
|
|
* Variadic template for calculating the norm (pythagoras) of a vector of any
|
|
|
|
* dimension.
|
|
|
|
*/
|
2017-06-20 21:42:39 -03:00
|
|
|
template<typename T, typename U, typename... Params>
|
2021-05-04 08:12:23 -03:00
|
|
|
ftype norm(const T first, const U second, const Params... parameters)
|
2016-04-16 06:58:46 -03:00
|
|
|
{
|
2021-05-04 08:12:23 -03:00
|
|
|
return sqrtF(sq(first, second, parameters...));
|
2015-03-21 05:48:46 -03:00
|
|
|
}
|
2012-12-18 22:33:52 -04:00
|
|
|
|
2021-10-27 05:06:42 -03:00
|
|
|
#undef MIN
|
AP_Math: turn MIN/MAX macros into inline functions
The problem with the current MIN/MAX macros is that they evaluate twice
the arguments. For example, these cases provide unintended results:
// a is incremented twice
a = MIN(a++, b);
// foo() with side-effects
a = MIN(foo(), b);
The alternative implementation here was provided by Daniel Frenzel using
template function. It doesn't have type safety as std::min and std::max,
but adding type safety would mean to check case by case what would be a
reasonable type and add proper casts. Here the arguments for MIN and MAX
can have different types and the return type is deduced from the
expression in the function.
Inspecting the current callers no place was found with the unintended
results above, but some in which now we don't calculate twice the
parameters will benefit from this new version. Examples:
float velocity_max = MIN(_pos_control.get_speed_xy(), safe_sqrt(0.5f*_pos_control.get_accel_xy()*_radius));
float acro_level_mix = constrain_float(1-MAX(MAX(abs(roll_in), abs(pitch_in)), abs(yaw_in))/4500.0, 0, 1)*ahrs.cos_pitch()
accel_x_cmss = (GRAVITY_MSS * 100) * (-(_ahrs.cos_yaw() * _ahrs.sin_pitch() / MAX(_ahrs.cos_pitch(),0.5f)) - _ahrs.sin_yaw() * _ahrs.sin_roll() / MAX(_ahrs.cos_roll(),0.5f));
track_leash_slack = MIN(_track_leash_length*(leash_z-track_error_z)/leash_z, _track_leash_length*(leash_xy-track_error_xy)/leash_xy);
RC_Channel_aux::move_servo(RC_Channel_aux::k_sprayer_pump, MIN(MAX(ground_speed * _pump_pct_1ms, 100 *_pump_min_pct),10000),0,10000);
2015-11-27 13:27:32 -04:00
|
|
|
template<typename A, typename B>
|
2016-05-03 21:32:49 -03:00
|
|
|
static inline auto MIN(const A &one, const B &two) -> decltype(one < two ? one : two)
|
|
|
|
{
|
AP_Math: turn MIN/MAX macros into inline functions
The problem with the current MIN/MAX macros is that they evaluate twice
the arguments. For example, these cases provide unintended results:
// a is incremented twice
a = MIN(a++, b);
// foo() with side-effects
a = MIN(foo(), b);
The alternative implementation here was provided by Daniel Frenzel using
template function. It doesn't have type safety as std::min and std::max,
but adding type safety would mean to check case by case what would be a
reasonable type and add proper casts. Here the arguments for MIN and MAX
can have different types and the return type is deduced from the
expression in the function.
Inspecting the current callers no place was found with the unintended
results above, but some in which now we don't calculate twice the
parameters will benefit from this new version. Examples:
float velocity_max = MIN(_pos_control.get_speed_xy(), safe_sqrt(0.5f*_pos_control.get_accel_xy()*_radius));
float acro_level_mix = constrain_float(1-MAX(MAX(abs(roll_in), abs(pitch_in)), abs(yaw_in))/4500.0, 0, 1)*ahrs.cos_pitch()
accel_x_cmss = (GRAVITY_MSS * 100) * (-(_ahrs.cos_yaw() * _ahrs.sin_pitch() / MAX(_ahrs.cos_pitch(),0.5f)) - _ahrs.sin_yaw() * _ahrs.sin_roll() / MAX(_ahrs.cos_roll(),0.5f));
track_leash_slack = MIN(_track_leash_length*(leash_z-track_error_z)/leash_z, _track_leash_length*(leash_xy-track_error_xy)/leash_xy);
RC_Channel_aux::move_servo(RC_Channel_aux::k_sprayer_pump, MIN(MAX(ground_speed * _pump_pct_1ms, 100 *_pump_min_pct),10000),0,10000);
2015-11-27 13:27:32 -04:00
|
|
|
return one < two ? one : two;
|
|
|
|
}
|
|
|
|
|
2021-10-27 05:06:42 -03:00
|
|
|
#undef MAX
|
AP_Math: turn MIN/MAX macros into inline functions
The problem with the current MIN/MAX macros is that they evaluate twice
the arguments. For example, these cases provide unintended results:
// a is incremented twice
a = MIN(a++, b);
// foo() with side-effects
a = MIN(foo(), b);
The alternative implementation here was provided by Daniel Frenzel using
template function. It doesn't have type safety as std::min and std::max,
but adding type safety would mean to check case by case what would be a
reasonable type and add proper casts. Here the arguments for MIN and MAX
can have different types and the return type is deduced from the
expression in the function.
Inspecting the current callers no place was found with the unintended
results above, but some in which now we don't calculate twice the
parameters will benefit from this new version. Examples:
float velocity_max = MIN(_pos_control.get_speed_xy(), safe_sqrt(0.5f*_pos_control.get_accel_xy()*_radius));
float acro_level_mix = constrain_float(1-MAX(MAX(abs(roll_in), abs(pitch_in)), abs(yaw_in))/4500.0, 0, 1)*ahrs.cos_pitch()
accel_x_cmss = (GRAVITY_MSS * 100) * (-(_ahrs.cos_yaw() * _ahrs.sin_pitch() / MAX(_ahrs.cos_pitch(),0.5f)) - _ahrs.sin_yaw() * _ahrs.sin_roll() / MAX(_ahrs.cos_roll(),0.5f));
track_leash_slack = MIN(_track_leash_length*(leash_z-track_error_z)/leash_z, _track_leash_length*(leash_xy-track_error_xy)/leash_xy);
RC_Channel_aux::move_servo(RC_Channel_aux::k_sprayer_pump, MIN(MAX(ground_speed * _pump_pct_1ms, 100 *_pump_min_pct),10000),0,10000);
2015-11-27 13:27:32 -04:00
|
|
|
template<typename A, typename B>
|
2016-05-03 21:32:49 -03:00
|
|
|
static inline auto MAX(const A &one, const B &two) -> decltype(one > two ? one : two)
|
|
|
|
{
|
AP_Math: turn MIN/MAX macros into inline functions
The problem with the current MIN/MAX macros is that they evaluate twice
the arguments. For example, these cases provide unintended results:
// a is incremented twice
a = MIN(a++, b);
// foo() with side-effects
a = MIN(foo(), b);
The alternative implementation here was provided by Daniel Frenzel using
template function. It doesn't have type safety as std::min and std::max,
but adding type safety would mean to check case by case what would be a
reasonable type and add proper casts. Here the arguments for MIN and MAX
can have different types and the return type is deduced from the
expression in the function.
Inspecting the current callers no place was found with the unintended
results above, but some in which now we don't calculate twice the
parameters will benefit from this new version. Examples:
float velocity_max = MIN(_pos_control.get_speed_xy(), safe_sqrt(0.5f*_pos_control.get_accel_xy()*_radius));
float acro_level_mix = constrain_float(1-MAX(MAX(abs(roll_in), abs(pitch_in)), abs(yaw_in))/4500.0, 0, 1)*ahrs.cos_pitch()
accel_x_cmss = (GRAVITY_MSS * 100) * (-(_ahrs.cos_yaw() * _ahrs.sin_pitch() / MAX(_ahrs.cos_pitch(),0.5f)) - _ahrs.sin_yaw() * _ahrs.sin_roll() / MAX(_ahrs.cos_roll(),0.5f));
track_leash_slack = MIN(_track_leash_length*(leash_z-track_error_z)/leash_z, _track_leash_length*(leash_xy-track_error_xy)/leash_xy);
RC_Channel_aux::move_servo(RC_Channel_aux::k_sprayer_pump, MIN(MAX(ground_speed * _pump_pct_1ms, 100 *_pump_min_pct),10000),0,10000);
2015-11-27 13:27:32 -04:00
|
|
|
return one > two ? one : two;
|
|
|
|
}
|
2012-12-18 22:33:52 -04:00
|
|
|
|
2020-03-04 15:33:16 -04:00
|
|
|
inline constexpr uint32_t hz_to_nsec(uint32_t freq)
|
2015-10-27 13:07:07 -03:00
|
|
|
{
|
2017-05-05 07:09:29 -03:00
|
|
|
return AP_NSEC_PER_SEC / freq;
|
2015-10-27 13:07:07 -03:00
|
|
|
}
|
|
|
|
|
2020-03-04 15:33:16 -04:00
|
|
|
inline constexpr uint32_t nsec_to_hz(uint32_t nsec)
|
2015-10-27 13:07:07 -03:00
|
|
|
{
|
2017-05-05 07:09:29 -03:00
|
|
|
return AP_NSEC_PER_SEC / nsec;
|
2015-10-27 13:07:07 -03:00
|
|
|
}
|
|
|
|
|
2020-03-04 15:33:16 -04:00
|
|
|
inline constexpr uint32_t usec_to_nsec(uint32_t usec)
|
2015-10-27 13:07:51 -03:00
|
|
|
{
|
2017-05-05 07:09:29 -03:00
|
|
|
return usec * AP_NSEC_PER_USEC;
|
2015-10-27 13:07:51 -03:00
|
|
|
}
|
|
|
|
|
2020-03-04 15:33:16 -04:00
|
|
|
inline constexpr uint32_t nsec_to_usec(uint32_t nsec)
|
2015-10-27 13:07:51 -03:00
|
|
|
{
|
2017-05-05 07:09:29 -03:00
|
|
|
return nsec / AP_NSEC_PER_USEC;
|
2015-10-27 13:07:51 -03:00
|
|
|
}
|
|
|
|
|
2020-03-04 15:33:16 -04:00
|
|
|
inline constexpr uint32_t hz_to_usec(uint32_t freq)
|
2015-12-07 12:19:50 -04:00
|
|
|
{
|
2017-05-05 07:09:29 -03:00
|
|
|
return AP_USEC_PER_SEC / freq;
|
2015-12-07 12:19:50 -04:00
|
|
|
}
|
|
|
|
|
2020-03-04 15:33:16 -04:00
|
|
|
inline constexpr uint32_t usec_to_hz(uint32_t usec)
|
2015-12-07 12:19:50 -04:00
|
|
|
{
|
2017-05-05 07:09:29 -03:00
|
|
|
return AP_USEC_PER_SEC / usec;
|
2015-12-07 12:19:50 -04:00
|
|
|
}
|
|
|
|
|
2016-04-02 08:44:47 -03:00
|
|
|
/*
|
|
|
|
linear interpolation based on a variable in a range
|
2021-05-18 20:19:52 -03:00
|
|
|
return value will be in the range [var_low,var_high]
|
|
|
|
|
|
|
|
Either polarity is supported, so var_low can be higher than var_high
|
2016-04-02 08:44:47 -03:00
|
|
|
*/
|
|
|
|
float linear_interpolate(float low_output, float high_output,
|
|
|
|
float var_value,
|
|
|
|
float var_low, float var_high);
|
2016-11-17 01:23:11 -04:00
|
|
|
|
2019-04-06 15:38:40 -03:00
|
|
|
/* cubic "expo" curve generator
|
|
|
|
* alpha range: [0,1] min to max expo
|
|
|
|
* input range: [-1,1]
|
|
|
|
*/
|
2021-07-17 03:39:46 -03:00
|
|
|
float expo_curve(float alpha, float input);
|
2019-04-06 15:38:40 -03:00
|
|
|
|
|
|
|
/* throttle curve generator
|
|
|
|
* thr_mid: output at mid stick
|
|
|
|
* alpha: expo coefficient
|
|
|
|
* thr_in: [0-1]
|
|
|
|
*/
|
|
|
|
float throttle_curve(float thr_mid, float alpha, float thr_in);
|
|
|
|
|
2016-11-17 01:23:11 -04:00
|
|
|
/* simple 16 bit random number generator */
|
|
|
|
uint16_t get_random16(void);
|
|
|
|
|
2017-04-12 08:16:07 -03:00
|
|
|
// generate a random float between -1 and 1, for use in SITL
|
|
|
|
float rand_float(void);
|
|
|
|
|
2022-11-16 07:21:45 -04:00
|
|
|
// generate a random Vector3f with each value between -1.0 and 1.0
|
2017-06-21 14:39:07 -03:00
|
|
|
Vector3f rand_vec3f(void);
|
2018-05-22 14:33:07 -03:00
|
|
|
|
2018-10-01 00:04:11 -03:00
|
|
|
// return true if two rotations are equal
|
2019-07-24 20:25:06 -03:00
|
|
|
bool rotation_equal(enum Rotation r1, enum Rotation r2) WARN_IF_UNUSED;
|
2019-09-20 21:32:54 -03:00
|
|
|
|
2020-05-19 02:05:48 -03:00
|
|
|
/*
|
|
|
|
* return a velocity correction (in m/s in NED) for a sensor's position given it's position offsets
|
2020-05-28 22:14:54 -03:00
|
|
|
* this correction should be added to the sensor NED measurement
|
2020-05-19 02:05:48 -03:00
|
|
|
* sensor_offset_bf is in meters in body frame (Foward, Right, Down)
|
|
|
|
* rot_ef_to_bf is a rotation matrix to rotate from earth-frame (NED) to body frame
|
|
|
|
* angular_rate is rad/sec
|
|
|
|
*/
|
2021-05-04 08:12:23 -03:00
|
|
|
Vector3F get_vel_correction_for_sensor_offset(const Vector3F &sensor_offset_bf, const Matrix3F &rot_ef_to_bf, const Vector3F &angular_rate);
|
2020-05-19 02:05:48 -03:00
|
|
|
|
2020-11-08 06:56:41 -04:00
|
|
|
/*
|
|
|
|
calculate a low pass filter alpha value
|
|
|
|
*/
|
|
|
|
float calc_lowpass_alpha_dt(float dt, float cutoff_freq);
|
|
|
|
|
2019-09-28 04:31:46 -03:00
|
|
|
#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
|
2019-09-20 21:32:54 -03:00
|
|
|
// fill an array of float with NaN, used to invalidate memory in SITL
|
|
|
|
void fill_nanf(float *f, uint16_t count);
|
2021-05-04 08:12:23 -03:00
|
|
|
void fill_nanf(double *f, uint16_t count);
|
2019-09-28 04:31:46 -03:00
|
|
|
#endif
|
|
|
|
|
2021-04-22 12:54:02 -03:00
|
|
|
// from https://embeddedartistry.com/blog/2018/07/12/simple-fixed-point-conversion-in-c/
|
|
|
|
// Convert to/from 16-bit fixed-point and float
|
|
|
|
float fixed2float(const uint16_t input, const uint8_t fractional_bits = 8);
|
|
|
|
uint16_t float2fixed(const float input, const uint8_t fractional_bits = 8);
|
|
|
|
|
2021-02-26 22:36:36 -04:00
|
|
|
/*
|
|
|
|
calculate turn rate in deg/sec given a bank angle and airspeed for a
|
|
|
|
fixed wing aircraft
|
|
|
|
*/
|
|
|
|
float fixedwing_turn_rate(float bank_angle_deg, float airspeed);
|
2021-12-22 17:26:26 -04:00
|
|
|
|
|
|
|
// convert degrees farenheight to Kelvin
|
|
|
|
float degF_to_Kelvin(float temp_f);
|
|
|
|
|
2022-07-10 20:18:21 -03:00
|
|
|
/*
|
2023-05-29 21:42:08 -03:00
|
|
|
constraining conversion functions to prevent undefined behaviour
|
2022-07-10 20:18:21 -03:00
|
|
|
*/
|
|
|
|
int16_t float_to_int16(const float v);
|
|
|
|
uint16_t float_to_uint16(const float v);
|
|
|
|
int32_t float_to_int32(const float v);
|
|
|
|
uint32_t float_to_uint32(const float v);
|
2022-07-20 22:26:09 -03:00
|
|
|
uint32_t double_to_uint32(const double v);
|
|
|
|
int32_t double_to_int32(const double v);
|
2022-07-10 20:18:21 -03:00
|
|
|
|
2023-05-29 21:42:08 -03:00
|
|
|
/*
|
|
|
|
Convert from float to int32_t without breaking Wstrict-aliasing due to type punning
|
|
|
|
*/
|
|
|
|
int32_t float_to_int32_le(const float& value) WARN_IF_UNUSED;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Convert from uint32_t to float without breaking Wstrict-aliasing due to type punning
|
|
|
|
*/
|
|
|
|
float int32_to_float_le(const uint32_t& value) WARN_IF_UNUSED;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Convert from uint64_t to double without breaking Wstrict-aliasing due to type punning
|
|
|
|
*/
|
|
|
|
double uint64_to_double_le(const uint64_t& value) WARN_IF_UNUSED;
|