common_math.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020-2023 RaccoonLab.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, version 3.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Author: Dmitry Ponomarev <ponomarevda96@gmail.com>
17  */
18 
19 
20 #include "common_math.hpp"
21 #include <Eigen/Geometry>
22 
23 namespace Math
24 {
25 
26 double lerp(double a, double b, double f){
27  return a + f * (b - a);
28 }
29 
30 double polyval(const Eigen::VectorXd& poly, double val){
31  double result = 0;
32  for(uint8_t idx = 0; idx < poly.rows(); idx++){
33  result += poly[idx] * std::pow(val, poly.rows() - 1 - idx);
34  }
35  return result;
36 }
37 
38 size_t findPrevRowIdxInMonotonicSequence(const Eigen::MatrixXd& matrix, double key){
39  size_t row_idx;
40  bool is_increasing_sequence = matrix(matrix.rows() - 1, 0) > matrix(0, 0);
41  if(is_increasing_sequence){
42  for(row_idx = 1; row_idx < matrix.rows() - 1; row_idx++){
43  if(key <= matrix(row_idx, 0)){
44  break;
45  }
46  }
47  row_idx--;
48  }else{
49  for(row_idx = 1; row_idx < matrix.rows() - 1; row_idx++){
50  if(key >= matrix(row_idx, 0)){
51  break;
52  }
53  }
54  row_idx--;
55  }
56  return row_idx;
57 }
58 
59 size_t findPrevRowIdxInIncreasingSequence(const Eigen::MatrixXd& table, double value){
60  size_t row_idx = 0;
61  size_t num_of_rows = table.rows();
62  while(row_idx + 2 < num_of_rows && table(row_idx + 1, 0) < value){
63  row_idx++;
64  }
65  return row_idx;
66 }
67 
68 double griddata(const Eigen::MatrixXd& x,
69  const Eigen::MatrixXd& y,
70  const Eigen::MatrixXd& z,
71  double x_val,
72  double y_val){
73  size_t x1_idx = findPrevRowIdxInMonotonicSequence(x, x_val);
74  size_t y1_idx = findPrevRowIdxInMonotonicSequence(y, y_val);
75  size_t x2_idx = x1_idx + 1;
76  size_t y2_idx = y1_idx + 1;
77  double Q11 = z(y1_idx, x1_idx);
78  double Q12 = z(y2_idx, x1_idx);
79  double Q21 = z(y1_idx, x2_idx);
80  double Q22 = z(y2_idx, x2_idx);
81  double R1 = ((x(x2_idx) - x_val) * Q11 + (x_val - x(x1_idx)) * Q21) / (x(x2_idx) - x(x1_idx));
82  double R2 = ((x(x2_idx) - x_val) * Q12 + (x_val - x(x1_idx)) * Q22) / (x(x2_idx) - x(x1_idx));
83  double f = ((y(y2_idx) - y_val) * R1 + (y_val - y(y1_idx)) * R2) / (y(y2_idx) - y(y1_idx));
84  return f;
85 }
86 
87 bool calculatePolynomial(const Eigen::MatrixXd& table,
88  double airSpeedMod,
89  Eigen::VectorXd& polynomialCoeffs){
90  if(table.cols() < 2 || table.rows() < 2 || polynomialCoeffs.rows() < table.cols() - 1){
91  return false; // wrong input
92  }
93 
94  const size_t prevRowIdx = Math::findPrevRowIdxInMonotonicSequence(table, airSpeedMod);
95  if(prevRowIdx + 2 > table.rows()){
96  return false; // wrong found row
97  }
98 
99  const size_t nextRowIdx = prevRowIdx + 1;
100  const double airspeedStep = table.row(nextRowIdx)(0, 0) - table.row(prevRowIdx)(0, 0);
101  if (abs(airspeedStep) < 0.001) {
102  return false; // wrong table, prevent division on zero
103  }
104 
105  double delta = (airSpeedMod - table.row(prevRowIdx)(0, 0)) / airspeedStep;
106  const size_t numberOfCoeffs = table.cols() - 1;
107  for(size_t coeff_idx = 0; coeff_idx < numberOfCoeffs; coeff_idx++){
108  const double prevValue = table.row(prevRowIdx)(0, coeff_idx + 1);
109  const double nextValue = table.row(nextRowIdx)(0, coeff_idx + 1);
110  polynomialCoeffs[coeff_idx] = Math::lerp(prevValue, nextValue, delta);
111  }
112 
113  return true;
114 }
115 
116 } // namespace Math
double lerp(double a, double b, double f)
Definition: common_math.cpp:26
f
size_t findPrevRowIdxInMonotonicSequence(const Eigen::MatrixXd &matrix, double key)
Given monotonic sequence (increasing or decreasing) and key, return the index of the previous element...
Definition: common_math.cpp:38
double polyval(const Eigen::VectorXd &poly, double val)
Definition: common_math.cpp:30
double griddata(const Eigen::MatrixXd &x, const Eigen::MatrixXd &y, const Eigen::MatrixXd &z, double x_val, double y_val)
Definition: common_math.cpp:68
bool calculatePolynomial(const Eigen::MatrixXd &table, double airSpeedMod, Eigen::VectorXd &polynomialCoeffs)
Definition: common_math.cpp:87
size_t findPrevRowIdxInIncreasingSequence(const Eigen::MatrixXd &table, double value)
Given an increasing sequence and a key, return the index of the previous element closest to the key...
Definition: common_math.cpp:59


inno_vtol_dynamics
Author(s): Roman Fedorenko, Dmitry Ponomarev, Ezra Tal, Winter Guerra
autogenerated on Sat Jul 1 2023 02:13:44