HCV_main.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #include <iostream>
  2. #include <armadillo>
  3. #include <time.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include "GPM.h"
  7. #include "HCV.h"
  8. using namespace std;
  9. using namespace arma;
  10. #ifndef Liulu20220630_PSLINUX / //修改的内容
  11. int main_HCV() {
  12. #else
  13. int main_HCV() {
  14. #endif
  15. // 计时器开始
  16. double dur;
  17. clock_t start, end;
  18. start = clock();
  19. ////////////////////////////////////参数初始化//////////////////////////////////////////////
  20. input0 input;
  21. output0* output;
  22. auxdata1 auxdata;
  23. // 伪谱法条件初始化
  24. Intput_Initial(&input);
  25. //基本参数
  26. auxdata.Sref = 150;//飞行器截面积
  27. auxdata.M0 = 100e3; //飞行器质量,单位:kg
  28. auxdata.g = 9.80665;
  29. auxdata.Re = 6371004;//假设地球为一个完美的球体
  30. auxdata.GMe = 3.986005e14;//地球质量
  31. auxdata.J2 = 1.08263e-3; //考虑J2项
  32. auxdata.omige = 7.292115e-5;//考虑地球自转
  33. auxdata.Ac = 10;
  34. auxdata.ae = 6378137;
  35. auxdata.re = 6371004;
  36. //归一化处理
  37. double pi = datum::pi;
  38. double g = auxdata.g;
  39. double Re = auxdata.Re;
  40. double tc = sqrt(Re / g);
  41. double rc = Re;
  42. double vc = sqrt(Re*g);
  43. double rad2deg = 180 / pi;
  44. input.setup.auxdata = auxdata;
  45. //禁飞区设置
  46. double a[] = { 100,48,500e3 };
  47. double b[] = { 90,43,300e3 };
  48. double c[] = { 62,43,360e3 };
  49. //飞行器初始状态
  50. double state0[] = { 49,90,2100,70,1 };
  51. //飞行器中间状态
  52. double state1[] = { 0,0,2040,0,0.1,-3 };
  53. double state2[] = { 180,180,2380,180,1,21 };
  54. //飞行器末端位置
  55. double state[] = { 116,47 };
  56. //控制量范围约束
  57. double con1[] = { 0.1,-1,-pi / 2 };
  58. double con2[] = { 1,1,pi / 2 };
  59. // 范围赋值
  60. ////////////////////////////////////////////////
  61. int length_state = 5;
  62. int length_control = 3;
  63. double initialtime_lower = 0;
  64. double initialtime_upper = 0;
  65. double finaltime_lower = 0 / tc;
  66. double finaltime_upper = 1500 / tc;
  67. vec state_c; state_c << rad2deg << rad2deg << vc << rad2deg << 1 << endr;
  68. vec initialstate_lower; initialstate_lower << state0[0] << state0[1] << state0[2] << state0[3] << state0[4] << endr;
  69. vec initialstate_upper; initialstate_upper << state0[0] << state0[1] << state0[2] << state0[3] << state0[4] << endr;
  70. vec state_lower; state_lower << state1[1] << state1[0] << state1[2] << state1[3] << state1[4] << endr;
  71. vec state_upper; state_upper << state2[1] << state2[0] << state2[2] << state2[3] << state2[4] << endr;
  72. vec finalstate_lower; finalstate_lower << state[1] << state[0] << state1[2] << state1[3] << state1[4] << endr;
  73. vec finalstate_upper; finalstate_upper << state[1] << state[0] << state2[2] << state2[3] << state2[4] << endr;
  74. vec control_lower; control_lower << con1[0] << -3 / rad2deg << con1[2] << endr;
  75. vec control_upper; control_upper << con2[0] << 21 / rad2deg << con2[2] << endr;
  76. vec path_lower; path_lower << -0.001 << 0 << 480e3 / Re << 350e3 / Re << 360e3 / Re << endr;
  77. vec path_upper; path_upper << 0.001 << 0 << 2 << 2 << 2 << endr;
  78. vec event_lower; event_lower.reset();
  79. vec event_upper; event_upper.reset();
  80. input.setup.state_length = length_state;
  81. input.setup.control_length = length_control;
  82. input.setup.bounds.phase.initialtime.lower = initialtime_lower;
  83. input.setup.bounds.phase.initialtime.upper = initialtime_upper;
  84. input.setup.bounds.phase.finaltime.lower = finaltime_lower;
  85. input.setup.bounds.phase.finaltime.upper = finaltime_upper;
  86. input.setup.bounds.phase.initialstate.lower = initialstate_lower / state_c;
  87. input.setup.bounds.phase.initialstate.upper = initialstate_upper / state_c;
  88. input.setup.bounds.phase.state.lower = state_lower / state_c;
  89. input.setup.bounds.phase.state.upper = state_upper / state_c;
  90. input.setup.bounds.phase.finalstate.lower = finalstate_lower / state_c;
  91. input.setup.bounds.phase.finalstate.upper = finalstate_upper / state_c;
  92. input.setup.bounds.phase.control.lower = control_lower;
  93. input.setup.bounds.phase.control.upper = control_upper;
  94. input.setup.bounds.phase.path.lower = path_lower;
  95. input.setup.bounds.phase.path.upper = path_upper;
  96. input.setup.bounds.phase.event.lower = event_lower;
  97. input.setup.bounds.phase.event.upper = event_upper;
  98. // 猜测值
  99. guess0 guess;
  100. vec guess_time; guess_time << 0 << endr
  101. << 300 / tc << endr
  102. << 1400 / tc << endr;
  103. mat guess_state; guess_state << state0[0] / rad2deg << state0[1] / rad2deg << state0[2] / vc << state0[3] / rad2deg << state0[4] << endr
  104. << 54 / rad2deg << 100 / rad2deg << 2100 / vc << 50 / rad2deg << 0.6 << endr
  105. << state[1] / rad2deg << state[0] / rad2deg << 2100 / vc << 130 / rad2deg << 0.3 << endr;
  106. mat guess_control; guess_control << 0.7 << 15 / rad2deg << -40 / rad2deg << endr
  107. << 0.6 << 13 / rad2deg << 40 / rad2deg << endr
  108. << 0.5 << 9 / rad2deg << 0 / rad2deg << endr;
  109. mat guess_path(3, 5, fill::zeros);
  110. guess_path.row(0) = input.setup.bounds.phase.path.lower.t();
  111. guess_path.row(1) = input.setup.bounds.phase.path.upper.t();
  112. guess.phase.time = guess_time;
  113. guess.phase.state = guess_state;
  114. guess.phase.control = guess_control;
  115. guess.phase.path = guess_path;
  116. input.setup.guess = guess;
  117. // 配点设置
  118. int inter_num = 8;
  119. input.setup.name = "Cruise_opt"; // 问题
  120. mesh1 mesh;
  121. mesh.method = "p-h"; // 网格细化方法的名字,字符串表示
  122. mesh.tolerance = 1e-4; // 网格细化精度的允许值
  123. mesh.maxiterration = 20; // 网格细化最大迭代次数
  124. mesh.colpointsmin = 8; // 网格细化产生新interval下的最小配点数目
  125. mesh.colpointsmax = 20; // 网格细化产生新interval下的最大配点数目
  126. mesh.splitmult = 1.2; // 比例因子,确定创建新网格的间隔数目
  127. mesh.curveratio = 2; // 网格间隔中解的最大平均曲率比的阈值,以确定是否增加新间隔
  128. mesh.phase.inter_num = inter_num; // 段p内的间隔数目, 整数
  129. mesh.phase.colpoints = 8 * ones(inter_num, 1); // 段p内的配置点数目,整数数组,长度与间隔数目相等
  130. mesh.phase.i_proportion = 2.0 / inter_num * ones(inter_num, 1); // 初始网格划分的比例(当前为均等划分,和为2)
  131. input.setup.mesh = mesh; // 组合setup.mesh结构体
  132. input.setup.warmstart = 0;
  133. input.setup.Scal = 0;
  134. input.setup.interp.method = "linear";
  135. // 函数设置
  136. functions1 functions;
  137. functions.continous1 = Dynamics_HCV;
  138. functions.endpoint = Objective_HCV;
  139. // 求解器设置
  140. NLP1 NLP;
  141. NLP.ipoptoptions.print_level = 2;
  142. NLP.ipoptoptions.hessian_approximation = "limited-memory";
  143. NLP.ipoptoptions.mu_strategy = "adaptive";
  144. #ifndef LIULU20220630_PSLINUX / //修改求解器
  145. NLP.ipoptoptions.linear_solver = "ma27";
  146. #else
  147. NLP.ipoptoptions.linear_solver = "mumps";
  148. #endif
  149. NLP.ipoptoptions.tolerance = 1e-6;
  150. NLP.ipoptoptions.maxiterration = 2000;
  151. input.setup.NLP = NLP;
  152. input.setup.derivatives.supplier = "FD";
  153. // 伪谱法过程实现
  154. int iteration_final;
  155. output = PM_Process(&input, functions, &iteration_final);
  156. // 计时结束
  157. end = clock();
  158. dur = (double)(end - start);
  159. #ifndef LIULU20220629_PSLINUX //修改printf_s为printf
  160. printf("总耗时: %f \n", (dur / CLOCKS_PER_SEC));
  161. #else
  162. printf_s("总耗时: %f \n", (dur / CLOCKS_PER_SEC));
  163. #endif
  164. vec t_ans = output[iteration_final].result.time;
  165. mat Y_ans = output[iteration_final].result.state;
  166. mat U_ans = output[iteration_final].result.control;
  167. #ifndef LIULU20220629_PSLINUX //将新生成的文件路径改为当前想要保存位置的路径
  168. t_ans.save("D:\\...\\t_ans1.txt", raw_ascii);
  169. Y_ans.save("D:\\...\\Y_ans1.txt", raw_ascii);
  170. U_ans.save("D:\\...\\U_ans1.txt", raw_ascii);
  171. #else
  172. t_ans.save("/public/home/ulijing/GPM_CPP/example/HCV_example/t_ans1.txt", raw_ascii);
  173. Y_ans.save("/public/home/ulijing/GPM_CPP/example/HCV_example/Y_ans1.txt", raw_ascii);
  174. U_ans.save("/public/home/ulijing/GPM_CPP/example/HCV_example/U_ans1.txt", raw_ascii);
  175. #endif
  176. getchar();
  177. return 1;
  178. }