|
| 1 | +// 气动系数--三维线性插值完成测试 -- 2024 - 12-02 |
| 2 | +// findIndices()函数的气动表的行数需要更改 |
| 3 | + |
| 4 | +#include "AeroDynamic.h" |
| 5 | +#include <iostream> |
| 6 | +#include <cmath> |
| 7 | +#include <string> |
| 8 | +#include<vector> |
| 9 | +#include <fstream> |
| 10 | +#include <sstream> |
| 11 | + |
| 12 | +using namespace std; |
| 13 | +// |
| 14 | + |
| 15 | +// 函数:查找所有等于 Ma0 - alpha0 -beta0 的索引 |
| 16 | +vector<int> findIndices(double Data_QidongBiao[877][10], double Ma_alpha_beta0, int col) { |
| 17 | + vector<int> indices; // 用于存储符合条件的行索引 |
| 18 | + |
| 19 | + // 遍历 Data_QidongBiao 的指定列 |
| 20 | + for (int i = 0; i < 877; ++i) { |
| 21 | + if (Data_QidongBiao[i][col] == Ma_alpha_beta0) { // 如果当前列的值等于 Ma0 |
| 22 | + indices.push_back(i); // 保存符合条件的行索引 |
| 23 | + } |
| 24 | + } |
| 25 | + return indices; |
| 26 | +} |
| 27 | + |
| 28 | +// 函数:计算三个索引数组的交集 |
| 29 | +vector<int> findCommonIndex(const vector<int>& indices_Ma1, const vector<int>& indices_alpha1, const vector<int>& indices_beta1) { |
| 30 | + vector<int> index_common; |
| 31 | + |
| 32 | + // 遍历第一个数组 |
| 33 | + for (int ma : indices_Ma1) { |
| 34 | + // 如果 ma 也在第二个数组中 |
| 35 | + if (find(indices_alpha1.begin(), indices_alpha1.end(), ma) != indices_alpha1.end()) { |
| 36 | + // 并且在第三个数组中 |
| 37 | + if (find(indices_beta1.begin(), indices_beta1.end(), ma) != indices_beta1.end()) { |
| 38 | + index_common.push_back(ma); // 找到交集元素,加入结果数组 |
| 39 | + } |
| 40 | + } |
| 41 | + } |
| 42 | + return index_common; |
| 43 | +} |
| 44 | + |
| 45 | + |
| 46 | +AerodynamicCoefficients::AerodynamicCoefficients() |
| 47 | +{ |
| 48 | + // 该处代码作用---得到6个三维气动系数数组 |
| 49 | + // 这里初始化气动系数数据 -- 将 CSV 数据正确地加载并填充到三维数组中 |
| 50 | + // 你可以从文件中加载这些数据,或者使用某些已知的气动数据进行初始化 |
| 51 | + |
| 52 | +// 文件路径 ---- 转化为[文本文件.txt] 制表符分隔的数据文件 , 一般不用读取.csv的逗号分隔的数据文件 ,读取时易出错! |
| 53 | + string filePath = R"(D:\GNC\工作_火箭姿控系统\火箭六自由度仿真程序\ZS_1_AttitudeControl_v1.5\RK4\Project1\data_qidong11.txt)"; |
| 54 | + |
| 55 | + // 打开文件 |
| 56 | + ifstream file(filePath); |
| 57 | + if (!file.is_open()) { |
| 58 | + cerr << "Error opening file: " << filePath << endl; |
| 59 | + //return 1; // 文件打开失败,退出程序 |
| 60 | + } |
| 61 | + |
| 62 | + string line; |
| 63 | + vector<vector<double>> QiDongdata; // 用于存储读取的数据 |
| 64 | + |
| 65 | + // 逐行读取文件 |
| 66 | + while (getline(file, line)) { |
| 67 | + // 跳过空行 |
| 68 | + if (line.empty()) { |
| 69 | + continue; |
| 70 | + } |
| 71 | + |
| 72 | + //cout << "Reading line: " << line << endl; // 调试:输出读取的行 |
| 73 | + stringstream ss(line); // 使用 stringstream 来拆分每一行的内容 |
| 74 | + string value; |
| 75 | + vector<double> row; // 用于存储每一行的数据 |
| 76 | + |
| 77 | + // 逐个读取制表符分隔的值并转化为 double |
| 78 | + while (getline(ss, value, '\t')) { |
| 79 | + try { |
| 80 | + row.push_back(stod(value)); // 将字符串转换为 double 并存储 |
| 81 | + } |
| 82 | + catch (const invalid_argument& e) { |
| 83 | + cerr << "Error converting value: '" << value << "' to double." << endl; |
| 84 | + } |
| 85 | + } |
| 86 | + |
| 87 | + // 如果当前行的数据不完整(列数不符合要求),则跳过 |
| 88 | + if (row.size() < 10) { |
| 89 | + cerr << "Skipping row with insufficient columns: " << line << endl; |
| 90 | + continue; |
| 91 | + } |
| 92 | + |
| 93 | + // 将有效数据添加到 QiDongdata 中 |
| 94 | + QiDongdata.push_back(row); |
| 95 | + } |
| 96 | + |
| 97 | + file.close(); // 关闭文件 |
| 98 | + |
| 99 | + int n = QiDongdata.size(); // 获取数据的行数 |
| 100 | + cout << "原始气动数据表的行数"<<n << endl; |
| 101 | + |
| 102 | + int NN = n; |
| 103 | + |
| 104 | + // Data_QidongBiao;// = QiDongdata; // n*10的数组 |
| 105 | + // 创建一个二维数组,初始值为零 |
| 106 | + double Data_QidongBiao[877][10] = { {0} }; |
| 107 | + for (int i = 0; i < NN; ++i) { |
| 108 | + for (int j = 0; j < 10; ++j) { |
| 109 | + // 将 QiDongdata 的数据复制到 Data_QidongBiao 数组 |
| 110 | + if (i < NN) { // 确保不越界 |
| 111 | + Data_QidongBiao[i][j] = QiDongdata[i][j]; |
| 112 | + } |
| 113 | + } |
| 114 | + } |
| 115 | + |
| 116 | + // 遍历三维数组并赋值 |
| 117 | + for (int i = 0; i < Mach_num; i++) { |
| 118 | + for (int j = 0; j < Alpha_num; j++) { |
| 119 | + for (int k = 0; k < Beta_num; k++) { |
| 120 | + // 循环遍历-->获得三维插值数组:CX[i][j][k]、CY[i][j][k]、CZ[i][j][k]、CMX[i][j][k]、CMY[i][j][k]、CMZ[i][j][k] |
| 121 | + |
| 122 | + double Ma1 = Ma[i]; |
| 123 | + double alpha1 = Alpha[j]; |
| 124 | + double beta1 = Beta[k]; |
| 125 | + |
| 126 | + vector<int> indices_Ma1 = findIndices(Data_QidongBiao, Ma1, 1); |
| 127 | + vector<int> indices_alpha1 = findIndices(Data_QidongBiao, alpha1, 2); |
| 128 | + vector<int> indices_beta1 = findIndices(Data_QidongBiao, beta1, 3); |
| 129 | + // 调用 findCommonIndex 函数计算交集-确定唯一一组[Ma,alpha,beta]对应的在气动表中的索引行数 |
| 130 | + vector<int> commonIndices = findCommonIndex(indices_Ma1, indices_alpha1, indices_beta1); |
| 131 | + |
| 132 | + int IndexOnly; |
| 133 | + // 获取交集的索引 |
| 134 | + if (!commonIndices.empty()) |
| 135 | + { |
| 136 | + IndexOnly = commonIndices.back(); |
| 137 | + // cout << "共同索引是:" << IndexOnly << endl; |
| 138 | + } |
| 139 | + else |
| 140 | + { |
| 141 | + break; |
| 142 | + } |
| 143 | + CX[i][j][k] = Data_QidongBiao[IndexOnly][4]; // Data_QidongBiao 中第 5 列是 CX |
| 144 | + CY[i][j][k] = Data_QidongBiao[IndexOnly][5]; // Data_QidongBiao 中第 6 列是 CY |
| 145 | + CZ[i][j][k] = Data_QidongBiao[IndexOnly][6]; // Data_QidongBiao 中第 7 列是 CZ |
| 146 | + CMX[i][j][k] = Data_QidongBiao[IndexOnly][7]; // Data_QidongBiao 中第 8 列是 CMX |
| 147 | + CMY[i][j][k] = Data_QidongBiao[IndexOnly][8]; // Data_QidongBiao 中第 9 列是 CMY |
| 148 | + CMZ[i][j][k] = Data_QidongBiao[IndexOnly][9]; // Data_QidongBiao 中第 10 列是 CMZ |
| 149 | + } |
| 150 | + } |
| 151 | + } |
| 152 | +} |
| 153 | + |
| 154 | +void AerodynamicCoefficients::ComputeCoefficients(double mach, double alpha, double beta) |
| 155 | +{ |
| 156 | + int i = 0, j = 0, k = 0; |
| 157 | + |
| 158 | + // 查找最接近的马赫数、攻角和侧滑角的离散点值 |
| 159 | + for (int ii = 0; ii < Mach_num; ii++) { |
| 160 | + if (Ma[ii] >= mach) { |
| 161 | + i = ii; |
| 162 | + break; |
| 163 | + } |
| 164 | + } |
| 165 | + for (int jj = 0; jj < Alpha_num; jj++) { |
| 166 | + if (Alpha[jj] >= alpha) { |
| 167 | + j = jj; |
| 168 | + break; |
| 169 | + } |
| 170 | + } |
| 171 | + for (int kk = 0; kk < Beta_num; kk++) { |
| 172 | + if (Beta[kk] >= beta) { |
| 173 | + k = kk; |
| 174 | + break; |
| 175 | + } |
| 176 | + } |
| 177 | + // 查找对应的马赫数、攻角、侧滑角的实际值 |
| 178 | + double Ma1 = Ma[i - 1]; |
| 179 | + double Ma2 = Ma[i]; |
| 180 | + double alpha1 = Alpha[j - 1]; |
| 181 | + double alpha2 = Alpha[j]; |
| 182 | + double beta1 = Beta[k - 1]; |
| 183 | + double beta2 = Beta[k]; |
| 184 | + |
| 185 | + |
| 186 | + // CX--三维线性插值 |
| 187 | + double CX1 = CX[i - 1][j - 1][k - 1]; |
| 188 | + double CX2 = CX[i - 1][j - 1][k]; |
| 189 | + double CX3 = CX[i - 1][j][k - 1]; |
| 190 | + double CX4 = CX[i - 1][j][k]; |
| 191 | + double CX5 = CX[i][j - 1][k - 1]; |
| 192 | + double CX6 = CX[i][j - 1][k]; |
| 193 | + double CX7 = CX[i][j][k - 1]; |
| 194 | + double CX8 = CX[i][j][k]; |
| 195 | + |
| 196 | + // 在侧滑角插值、攻角、马赫数 (Ma) 上三维插值 |
| 197 | + double inter_CX_beta, inter_CX_alpha, inter_CX_Ma, interpolatedCX; |
| 198 | + inter_CX_beta = CX7 + (CX8 - CX7) / (beta2 - beta1) * (beta - beta1); // 侧滑角插值 |
| 199 | + inter_CX_alpha = CX6 + (CX8 - CX6) / (alpha2 - alpha1) * (alpha - alpha1); // 攻角插值 |
| 200 | + inter_CX_Ma = CX4 + (CX8 - CX4) / (Ma2 - Ma1) * (mach - Ma1); // 马赫数插值 |
| 201 | + interpolatedCX = (inter_CX_Ma + inter_CX_alpha + inter_CX_beta) / 3.0; |
| 202 | + |
| 203 | + //cout << "测试的数据 biao_inter_CX :" << CX8 << endl; |
| 204 | + //cout << "测试的数据 inter_CX::" << interpolatedCX << endl; |
| 205 | + // |
| 206 | + // CY-三维线性插值 |
| 207 | + double CY1 = CY[i - 1][j - 1][k - 1]; |
| 208 | + double CY2 = CY[i - 1][j - 1][k]; |
| 209 | + double CY3 = CY[i - 1][j][k - 1]; |
| 210 | + double CY4 = CY[i - 1][j][k]; |
| 211 | + double CY5 = CY[i][j - 1][k - 1]; |
| 212 | + double CY6 = CY[i][j - 1][k]; |
| 213 | + double CY7 = CY[i][j][k - 1]; |
| 214 | + double CY8 = CY[i][j][k]; |
| 215 | + |
| 216 | + double inter_CY_beta, inter_CY_alpha, inter_CY_Ma, interpolatedCY; |
| 217 | + inter_CY_beta = CY7 + (CY8 - CY7) / (beta2 - beta1) * (beta - beta1); // 侧滑角插值 |
| 218 | + inter_CY_alpha = CY6 + (CY8 - CY6) / (alpha2 - alpha1) * (alpha - alpha1); // 攻角插值 |
| 219 | + inter_CY_Ma = CY4 + (CY8 - CY4) / (Ma2 - Ma1) * (mach - Ma1); // 马赫数插值 |
| 220 | + interpolatedCY = (inter_CY_Ma + inter_CY_alpha + inter_CY_beta) / 3.0; |
| 221 | + |
| 222 | + //cout << "测试的数据 biao_inter_CY :" << CY8 << endl; |
| 223 | + // cout << "测试的数据 inter_CY::" << interpolatedCY << endl; |
| 224 | + |
| 225 | + // CZ-三维线性插值 |
| 226 | + double CZ1 = CZ[i - 1][j - 1][k - 1]; |
| 227 | + double CZ2 = CZ[i - 1][j - 1][k]; |
| 228 | + double CZ3 = CZ[i - 1][j][k - 1]; |
| 229 | + double CZ4 = CZ[i - 1][j][k]; |
| 230 | + double CZ5 = CZ[i][j - 1][k - 1]; |
| 231 | + double CZ6 = CZ[i][j - 1][k]; |
| 232 | + double CZ7 = CZ[i][j][k - 1]; |
| 233 | + double CZ8 = CZ[i][j][k]; |
| 234 | + |
| 235 | + double inter_CZ_beta, inter_CZ_alpha, inter_CZ_Ma, interpolatedCZ; |
| 236 | + inter_CZ_beta = CZ7 + (CZ8 - CZ7) / (beta2 - beta1) * (beta - beta1); // 侧滑角插值 |
| 237 | + inter_CZ_alpha = CZ6 + (CZ8 - CZ6) / (alpha2 - alpha1) * (alpha - alpha1); // 攻角插值 |
| 238 | + inter_CZ_Ma = CZ4 + (CZ8 - CZ4) / (Ma2 - Ma1) * (mach - Ma1); // 马赫数插值 |
| 239 | + interpolatedCZ = (inter_CZ_Ma + inter_CZ_alpha + inter_CZ_beta) / 3.0; |
| 240 | + |
| 241 | + |
| 242 | + // CMX-三维线性插值 |
| 243 | + double CMX1 = CMX[i - 1][j - 1][k - 1]; |
| 244 | + double CMX2 = CMX[i - 1][j - 1][k]; |
| 245 | + double CMX3 = CMX[i - 1][j][k - 1]; |
| 246 | + double CMX4 = CMX[i - 1][j][k]; |
| 247 | + double CMX5 = CMX[i][j - 1][k - 1]; |
| 248 | + double CMX6 = CMX[i][j - 1][k]; |
| 249 | + double CMX7 = CMX[i][j][k - 1]; |
| 250 | + double CMX8 = CMX[i][j][k]; |
| 251 | + double inter_CMX_beta, inter_CMX_alpha, inter_CMX_Ma, interpolatedCMX; |
| 252 | + inter_CMX_beta = CMX7 + (CMX8 - CMX7) / (beta2 - beta1) * (beta - beta1); // 侧滑角插值 |
| 253 | + inter_CMX_alpha = CMX6 + (CMX8 - CMX6) / (alpha2 - alpha1) * (alpha - alpha1); // 攻角插值 |
| 254 | + inter_CMX_Ma = CMX4 + (CMX8 - CMX4) / (Ma2 - Ma1) * (mach - Ma1); // 马赫数插值 |
| 255 | + interpolatedCMX = (inter_CMX_Ma + inter_CMX_alpha + inter_CMX_beta) / 3.0; |
| 256 | + |
| 257 | + // CMY-三维线性插值 |
| 258 | + double CMY1 = CMY[i - 1][j - 1][k - 1]; |
| 259 | + double CMY2 = CMY[i - 1][j - 1][k]; |
| 260 | + double CMY3 = CMY[i - 1][j][k - 1]; |
| 261 | + double CMY4 = CMY[i - 1][j][k]; |
| 262 | + double CMY5 = CMY[i][j - 1][k - 1]; |
| 263 | + double CMY6 = CMY[i][j - 1][k]; |
| 264 | + double CMY7 = CMY[i][j][k - 1]; |
| 265 | + double CMY8 = CMY[i][j][k]; |
| 266 | + double inter_CMY_beta, inter_CMY_alpha, inter_CMY_Ma, interpolatedCMY; |
| 267 | + inter_CMY_beta = CMY7 + (CMY8 - CMY7) / (beta2 - beta1) * (beta - beta1); // 侧滑角插值 |
| 268 | + inter_CMY_alpha = CMY6 + (CMY8 - CMY6) / (alpha2 - alpha1) * (alpha - alpha1); // 攻角插值 |
| 269 | + inter_CMY_Ma = CMY4 + (CMY8 - CMY4) / (Ma2 - Ma1) * (mach - Ma1); // 马赫数插值 |
| 270 | + interpolatedCMY = (inter_CMY_Ma + inter_CMY_alpha + inter_CMY_beta) / 3.0; |
| 271 | + |
| 272 | + // CMZ-三维线性插值 |
| 273 | + double CMZ1 = CMZ[i - 1][j - 1][k - 1]; |
| 274 | + double CMZ2 = CMZ[i - 1][j - 1][k]; |
| 275 | + double CMZ3 = CMZ[i - 1][j][k - 1]; |
| 276 | + double CMZ4 = CMZ[i - 1][j][k]; |
| 277 | + double CMZ5 = CMZ[i][j - 1][k - 1]; |
| 278 | + double CMZ6 = CMZ[i][j - 1][k]; |
| 279 | + double CMZ7 = CMZ[i][j][k - 1]; |
| 280 | + double CMZ8 = CMZ[i][j][k]; |
| 281 | + double inter_CMZ_beta, inter_CMZ_alpha, inter_CMZ_Ma, interpolatedCMZ; |
| 282 | + inter_CMZ_beta = CMZ7 + (CMZ8 - CMZ7) / (beta2 - beta1) * (beta - beta1); // 侧滑角插值 |
| 283 | + inter_CMZ_alpha = CMZ6 + (CMZ8 - CMZ6) / (alpha2 - alpha1) * (alpha - alpha1); // 攻角插值 |
| 284 | + inter_CMZ_Ma = CMZ4 + (CMZ8 - CMZ4) / (Ma2 - Ma1) * (mach - Ma1); // 马赫数插值 |
| 285 | + interpolatedCMZ = (inter_CMZ_Ma + inter_CMZ_alpha + inter_CMZ_beta) / 3.0; |
| 286 | + |
| 287 | + CxyzCMxyz[0] = interpolatedCX; |
| 288 | + CxyzCMxyz[1] = interpolatedCY; |
| 289 | + CxyzCMxyz[2] = interpolatedCZ; |
| 290 | + CxyzCMxyz[3] = interpolatedCMX; |
| 291 | + CxyzCMxyz[4] = interpolatedCMY; |
| 292 | + CxyzCMxyz[5] = interpolatedCMZ; |
| 293 | + |
| 294 | +} |
| 295 | + |
| 296 | +void AerodynamicCoefficients::GetCoefficients(double CxyzCmxyz[6]) { |
| 297 | + // 返回当前的气动系数 |
| 298 | + for (int i = 0; i < 6; i++) { |
| 299 | + CxyzCmxyz[i] = this->CxyzCMxyz[i]; //this 是一个指针,指向当前类的实例(this->FxyzMxyz[i]) |
| 300 | + } |
| 301 | +} |
0 commit comments