mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-21 16:18:29 -04:00
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);
This commit is contained in:
parent
2591261af6
commit
e0a0514c79
@ -220,9 +220,15 @@ static inline float pythagorous3(float a, float b, float c) {
|
||||
#error "Build is including Arduino base headers"
|
||||
#endif
|
||||
|
||||
/* The following three functions used to be arduino core macros */
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
template<typename A, typename B>
|
||||
static inline auto MIN(const A &one, const B &two) -> decltype(one < two ? one : two) {
|
||||
return one < two ? one : two;
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
static inline auto MAX(const A &one, const B &two) -> decltype(one > two ? one : two) {
|
||||
return one > two ? one : two;
|
||||
}
|
||||
|
||||
static inline float maxf(float a, float b)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user