Based on the original Rocket Workbench on SourceForge in CVS at: https://sourceforge.net/projects/rocketworkbench
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
6.9 KiB

  1. /* modeles.cc - Simulation of rocket flight */
  2. /* Copyright (C) 2000 */
  3. /* Antoine Lefebvre <antoine.lefebvre@polymtl.ca> */
  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; either version 2 of the License, or */
  7. /* (at your option) any later version. */
  8. /* This program is distributed in the hope that it will be useful, */
  9. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  10. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  11. /* GNU General Public License for more details. */
  12. /* You should have received a copy of the GNU General Public License */
  13. /* along with this program; if not, write to the Free Software */
  14. /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  15. #include <cmath>
  16. #include "simulation.h"
  17. #include "c++rocket.h"
  18. // modified arctan function
  19. double Atan(double x, double y);
  20. double coef(double v);
  21. double T(double time);
  22. double mass(double time);
  23. int model_1(int neq, double time,
  24. double *z, double *dy, int ierr);
  25. int model_2(int neq, double time,
  26. double* z, double* dy, int ierr);
  27. extern simulation *simptr;
  28. /**********************************************************************
  29. MODEL_1: This model takes care of the principal aerodynamic effects
  30. that takes place in a rocket flight. The mathematical relation
  31. come from 'Mathematical theory of rocket flight' McGraw-Hill
  32. Book company. Author are J. Barkley Rosser, Robert R. Newton,
  33. George L. Gross.
  34. COMMENTS: I will eventually explain the theory in some documentation
  35. **********************************************************************/
  36. int model_1(int neq, double time,
  37. double *z, double *dy, int ierr)
  38. {
  39. //double s = z[0]; not use
  40. double x = z[1]; // position in the x coordinate
  41. double y = z[2]; // position in the y coordinate
  42. double theta = z[3]; // angle about the horizontal
  43. double phi = z[4]; // angle of the rocket axis about the horizontal
  44. double v = z[5]; // speed
  45. double dphi = z[6]; // first derivative of phi
  46. double h = sqrt(pow(x,2) + pow(y,2));
  47. double g = G*simptr->p_data[masse]/(pow(h,2));
  48. double delta = phi - theta;
  49. double rho = simptr->densiteatm(h - simptr->p_data[rayon]);
  50. double drag_correction = coef(v)/0.15;
  51. double Drag = -simptr->r_data[Kdrag]*(1+simptr->r_data[Kdd]*pow(delta,2))\
  52. *rho*pow(simptr->r_data[Diameter],2)*pow(v,2)*drag_correction;
  53. double Lift = simptr->r_data[Klift]*rho*pow(simptr->r_data[Diameter],2) * pow(v,2)*sin(delta - simptr->r_data[dlift]);
  54. double Spin = simptr->r_data[Kspin]*rho*pow(simptr->r_data[Diameter],3)*v*dphi;
  55. double Moment = -simptr->r_data[Kmoment]*rho*pow(simptr->r_data[Diameter],3)*pow(v,2)*sin(delta-simptr->r_data[dmoment]);
  56. double Damping = -simptr->r_data[Kdamping]*rho*pow(simptr->r_data[Diameter],4)*v*dphi;
  57. double thrust = T(time);
  58. double dmasse = 0; // mass flow
  59. double angle = Atan(x, y);
  60. dy[0] = v;
  61. dy[1] = v*cos(theta);
  62. dy[2] = v*sin(theta);
  63. dy[3] = (thrust* sin( delta - simptr->r_data[dt] ) - mass(time)*g*cos(theta + PI/2 - angle) + Lift + Spin*cos(delta))/(mass(time)*v); //dtheta
  64. dy[4] = dphi;
  65. dy[5] = (thrust*cos(delta-simptr->r_data[dt])-mass(time)*g*sin(theta+PI/2-angle) + Drag + Spin*sin(delta))/mass(time);
  66. dy[6] = (thrust*simptr->r_data[rcm_throat]*sin(simptr->r_data[dt]) + Moment + Damping - dmasse*dphi*(simptr->r_data[rcm_throat]*simptr->r_data[rcm_exit]-pow(simptr->r_data[k],2)))/(mass(time)*pow(simptr->r_data[k],2));
  67. return 0;
  68. }
  69. double Atan(double x, double y)
  70. {
  71. double angle;
  72. if ((x == 0)&&(y > 0))
  73. angle = PI/2;
  74. else if ((x == 0)&&(y < 0))
  75. angle = -PI/2;
  76. else if ((x > 0))
  77. angle = atan(y/x);
  78. else if ((x < 0))
  79. angle = PI + atan(y/x);
  80. return angle;
  81. }
  82. // table de variation des du coefficient de frottement en
  83. // fonction de la vitesse
  84. // table of the drag coefficient variation with speed
  85. //
  86. double coef(double v)
  87. {
  88. static const int V[] = {0, 50, 100, 150, 200, 250, 300, 350, 400, 450,
  89. 500, 550, 600, 650, 700, 750, 800, 850, 900, 950,
  90. 1000, 1050, 1100, 1150, 1200};
  91. static const double C[] = {0.15, 0.13, 0.125, 0.12, 0.135, 0.15, 0.2,
  92. 0.3, 0.37, 0.39, 0.38, 0.37, 0.36, 0.35, 0.34,
  93. 0.33, 0.32, 0.315, 0.31,0.305, 0.302, 0.3,
  94. 0.299, 0.298, 0.297};
  95. if (v > 1200)
  96. return 0.295;
  97. else {
  98. int b = (int)floor(v/50)+1;
  99. return ( (C[b+1]-C[b]) / (V[b+1]-V[b]) )*(v-V[b]) + C[b];
  100. }
  101. }
  102. double mass(double time)
  103. {
  104. double trel = 0;
  105. double M = simptr->r_data[Mass];
  106. if (simptr->n_prop() == 0)
  107. return M;
  108. for (int i = 0; i < simptr->n_prop(); i++)
  109. M += simptr->prop[i].M(0);
  110. if (time < simptr->ta[0])
  111. return M;
  112. M -= simptr->prop[0].M(0);
  113. for (int i = 0; i < simptr->n_prop(); i++)
  114. if (time < (simptr->tl[i]+simptr->ta[i]+simptr->prop[i].burntime+trel) )
  115. return (M + simptr->prop[i].M(time - trel - simptr->ta[i]));
  116. else
  117. {
  118. trel += simptr->ta[i] + simptr->tl[i] + simptr->prop[i].burntime;
  119. M -= simptr->prop[i].M(0);
  120. }
  121. return simptr->r_data[Mass];
  122. }
  123. // give the thrust of the rocket in function of time, flight program and
  124. // motor that are loaded
  125. double T(double time)
  126. {
  127. double trel = 0;
  128. if (simptr->n_prop() == 0)
  129. return 0.0;
  130. if (time < simptr->ta[0])
  131. return 0.0;
  132. for (int i = 0; i < simptr->n_prop(); i++) {
  133. if (time < (simptr->tl[i]+simptr->ta[i]+simptr->prop[i].burntime+trel) )
  134. return simptr->prop[i].T(time - trel - simptr->ta[i]);
  135. else
  136. trel += simptr->ta[i] + simptr->tl[i] + simptr->prop[i].burntime;
  137. }
  138. return 0.0;
  139. }
  140. /**********************************************************************
  141. MODEL_2: Simple model that do not take care of aerodynamic parameter
  142. **********************************************************************/
  143. int model_2(int neq, double time,
  144. double* z, double* dy, int ierr)
  145. {
  146. //double s = z[0];
  147. double x = z[1];
  148. double y = z[2];
  149. double theta = z[3];
  150. double v = z[4];
  151. double h = sqrt(pow(x,2) + pow(y,2));
  152. double g = G*simptr->p_data[masse]/(pow(h,2));
  153. double rho = simptr->densiteatm(h - simptr->p_data[rayon]);
  154. double drag_correction = coef(v)/0.15;
  155. double Drag = -simptr->r_data[Kdrag]*rho*pow(simptr->r_data[Diameter],2)*pow(v,2)*drag_correction;
  156. double thrust = T(time);
  157. //double dmasse = 0; //mass flow
  158. double angle = Atan(x, y);
  159. dy[0] = v;
  160. dy[1] = v*cos(theta);
  161. dy[2] = v*sin(theta);
  162. dy[3] = (thrust - mass(time)*g*cos(theta+PI/2-angle) )/(mass(time)*v); //dtheta
  163. dy[4] = (thrust-mass(time)*g*sin(theta+PI/2-angle) + Drag )/mass(time);
  164. return 0;
  165. }