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.

454 lines
12 KiB

  1. #include <X11/Xlib.h> // Every Xlib program must include this
  2. #include <linux/mc146818rtc.h>
  3. #include <sys/ioctl.h>
  4. #include <sys/time.h>
  5. #include <sys/types.h>
  6. #include <fcntl.h>
  7. #include <unistd.h> // So we got the profile for 10 seconds
  8. #include <stdlib.h>
  9. #include <math.h>
  10. #include <stdio.h>
  11. #include <errno.h>
  12. #include "rocflight.h"
  13. #include "num.h"
  14. #include "state.h"
  15. #define PIXEL_M 15
  16. #define PIXEL_M_S 15
  17. #define H 40
  18. #define L 40
  19. #define SCALEY 1
  20. #define WIDTH L * PIXEL_M
  21. #define HEIGHT (int)(H * PIXEL_M * SCALEY)
  22. #define MAX_HISTORY 200
  23. #define FREQ 32
  24. #define STEP (1.0/FREQ)
  25. #define POSX_TO_PIXEL(x) (WIDTH/2 + (int)((x) * PIXEL_M))
  26. #define POSY_TO_PIXEL(y) (HEIGHT - (int)((y) * PIXEL_M * SCALEY))
  27. struct rocketAnim_t
  28. {
  29. int width, height;
  30. GC gc;
  31. GC tmpgc;
  32. Display *display;
  33. Window window;
  34. Pixmap pixmap;
  35. unsigned long red, blue, white, green;
  36. XFontStruct *font_info;
  37. int font_height;
  38. } rocket;
  39. int eom(int neq, double time, double *y, double *dy, void *data);
  40. unsigned long AllocColor(char *colName)
  41. {
  42. Colormap cmap;
  43. XColor c0, c1;
  44. cmap = DefaultColormap(rocket.display, 0);
  45. XAllocNamedColor(rocket.display, cmap, colName, &c1, &c0);
  46. return(c1.pixel);
  47. }
  48. void ExposeScreen(void)
  49. {
  50. XCopyArea(rocket.display, rocket.pixmap,
  51. rocket.window, rocket.tmpgc,
  52. 0, 0, rocket.width, rocket.height, 0, 0);
  53. }
  54. void rocketInit(void)
  55. {
  56. Display *d;
  57. Window w;
  58. Pixmap p;
  59. XEvent e;
  60. d = rocket.display = XOpenDisplay(NULL);
  61. w = rocket.window = XCreateSimpleWindow(d, DefaultRootWindow(d),
  62. 0, 0,
  63. rocket.width, rocket.height,
  64. 2, BlackPixel(d, 0),
  65. WhitePixel(d, 0));
  66. p = rocket.pixmap = XCreatePixmap(d, DefaultRootWindow(d),
  67. rocket.width, rocket.height,
  68. DefaultDepth(d, 0));
  69. rocket.gc = XCreateGC(d, w, 0, 0);
  70. rocket.tmpgc = XCreateGC(d, w, 0, 0);
  71. rocket.red = AllocColor("red");
  72. rocket.blue = AllocColor("blue");
  73. rocket.white = AllocColor("white");
  74. rocket.green = AllocColor("green");
  75. rocket.font_info = XQueryFont(d, XGContextFromGC(rocket.gc));
  76. rocket.font_height = rocket.font_info->ascent + rocket.font_info->descent;
  77. XSetForeground(rocket.display, rocket.gc, rocket.white);
  78. XFillRectangle(d, p, rocket.gc, 0, 0, rocket.width, rocket.height);
  79. XMapWindow(d, w);
  80. XSelectInput(d, w, StructureNotifyMask);
  81. for(;;) {
  82. XNextEvent(d, &e);
  83. if (e.type == MapNotify)
  84. break;
  85. }
  86. XFlush(d);
  87. }
  88. void DrawLine(int x1, int y1, int x2, int y2)
  89. {
  90. /* Draw the new line */
  91. XDrawLine(rocket.display, rocket.pixmap, rocket.gc, x1, y1, x2, y2);
  92. }
  93. void DrawPoint(int x, int y)
  94. {
  95. /* draw the point */
  96. XSetForeground(rocket.display, rocket.gc, rocket.red);
  97. XDrawPoint(rocket.display, rocket.pixmap, rocket.gc, x, y);
  98. }
  99. void DrawFillCircle(int x, int y, int r)
  100. {
  101. /* Draw the circle */
  102. XSetForeground(rocket.display, rocket.gc, rocket.red);
  103. XFillArc(rocket.display, rocket.pixmap, rocket.gc,
  104. x - r, y - r, 2*r, 2*r, 0, 360*64);
  105. }
  106. void DrawSystem(double *y)
  107. {
  108. int i, j;
  109. double x1, y1;
  110. double theta;
  111. double vitesse_tot;
  112. char vitessex[32];
  113. char vitessey[32];
  114. char vitesset[32];
  115. char alpha_str[32];
  116. char theta_str[32];
  117. char velocity_str[32];
  118. double velocity;
  119. theta = y[10];
  120. velocity = sqrt(y[0]*y[0] + y[1]*y[1] + y[2]*y[2]);
  121. vitesse_tot =
  122. sqrt(pow(y[0], 2) + pow(y[2], 2));
  123. sprintf(velocity_str, "Velocity : % .2f m/s", velocity);
  124. sprintf(alpha_str, "Angle of attack : % 6.2f deg", atan(y[2]/y[0])*180/M_PI);
  125. sprintf(theta_str, "Theta : % .2f deg", theta*180/M_PI);
  126. sprintf(vitessex, "Vitesse axe x : % .2f", y[0]);
  127. sprintf(vitessey, "Vitesse axe y : % .2f", y[2]);
  128. sprintf(vitesset, "Vitesse absolue: % .2f", vitesse_tot);
  129. /* Clear the screen */
  130. XSetForeground(rocket.display, rocket.gc, rocket.white);
  131. XFillRectangle(rocket.display, rocket.pixmap,
  132. rocket.gc, 0, 0, rocket.width, rocket.height);
  133. //DrawFillCircle(POSX_TO_PIXEL(x), POSY_TO_PIXEL(y), 10);
  134. //printf("%f\n", y[10]);
  135. /* Draw the rocket */
  136. XSetForeground(rocket.display, rocket.gc, rocket.red);
  137. x1 = 0 + 8*cos(theta);
  138. y1 = 20 + 8*sin(theta);
  139. DrawLine(POSX_TO_PIXEL(0 - sin(theta)), POSY_TO_PIXEL(20 + cos(theta)),
  140. POSX_TO_PIXEL(x1 - sin(theta)), POSY_TO_PIXEL(y1 + cos(theta)));
  141. DrawLine(POSX_TO_PIXEL(0 + sin(theta)), POSY_TO_PIXEL(20 - cos(theta)),
  142. POSX_TO_PIXEL(x1 + sin(theta)), POSY_TO_PIXEL(y1 - cos(theta)));
  143. DrawLine(POSX_TO_PIXEL(x1 - sin(theta)), POSY_TO_PIXEL(y1 + cos(theta)),
  144. POSX_TO_PIXEL(x1 + 4*cos(theta)), POSY_TO_PIXEL(y1 + 4*sin(theta)));
  145. DrawLine(POSX_TO_PIXEL(x1 + sin(theta)), POSY_TO_PIXEL(y1 - cos(theta)),
  146. POSX_TO_PIXEL(x1 + 4*cos(theta)), POSY_TO_PIXEL(y1 + 4*sin(theta)));
  147. XSetForeground(rocket.display, rocket.gc, rocket.blue);
  148. x1 = (y[0]*cos(theta) - y[2]*sin(theta))/50;
  149. y1 = 20 + (y[0]*sin(theta) + y[2]*cos(theta))/50;
  150. DrawLine(POSX_TO_PIXEL(0), POSY_TO_PIXEL(20),
  151. POSX_TO_PIXEL(x1), POSY_TO_PIXEL(y1));
  152. //DrawLine(x, y,
  153. /*
  154. if (modeleInfo.full)
  155. j = MAX_HISTORY;
  156. else
  157. j = modeleInfo.lasthistory;
  158. for (i = 0; i < j; i++)
  159. DrawPoint(POSX_TO_PIXEL(modeleInfo.pointhistory[i][0]),
  160. POSY_TO_PIXEL(modeleInfo.pointhistory[i][1]));
  161. */
  162. XDrawString(rocket.display, rocket.pixmap, rocket.gc, 10,
  163. HEIGHT - 3*rocket.font_height, velocity_str,
  164. strlen(velocity_str));
  165. XDrawString(rocket.display, rocket.pixmap, rocket.gc, 10,
  166. HEIGHT - 2*rocket.font_height, alpha_str, strlen(alpha_str));
  167. XDrawString(rocket.display, rocket.pixmap, rocket.gc, 10,
  168. HEIGHT - rocket.font_height, theta_str, strlen(theta_str));
  169. XDrawString(rocket.display, rocket.pixmap, rocket.gc, 100,
  170. HEIGHT - 3*rocket.font_height, vitessex,
  171. strlen(vitessex));
  172. XDrawString(rocket.display, rocket.pixmap, rocket.gc, 100,
  173. HEIGHT - 2*rocket.font_height, vitessey,
  174. strlen(vitessey));
  175. XDrawString(rocket.display, rocket.pixmap, rocket.gc, 100,
  176. HEIGHT - 1*rocket.font_height, vitesset,
  177. strlen(vitesset));
  178. /* XFillRectangle(rocket.display, rocket.pixmap, rocket.gc, 140,
  179. HEIGHT - 4*rocket.font_height + rocket.font_info->ascent/2,
  180. (int)(PIXEL_M_S * fabs(modeleInfo.state[2])),
  181. rocket.font_height/2);
  182. XFillRectangle(rocket.display, rocket.pixmap, rocket.gc, 140,
  183. HEIGHT - 3*rocket.font_height + rocket.font_info->ascent/2,
  184. (int)(PIXEL_M_S * fabs(modeleInfo.state[3])),
  185. rocket.font_height/2);
  186. XFillRectangle(rocket.display, rocket.pixmap, rocket.gc, 140,
  187. HEIGHT - 2*rocket.font_height + rocket.font_info->ascent/2,
  188. (int)(PIXEL_M_S * vitesse_tot),
  189. rocket.font_height/2);
  190. */
  191. ExposeScreen();
  192. XFlush(rocket.display);
  193. }
  194. int main(int argc, char *argv[])
  195. {
  196. int i, n;
  197. int neq = 12;
  198. double time;
  199. double res[12];
  200. double *ans;
  201. double *init_cond;
  202. double u = 100; /* velocity component in x */
  203. double v = 0; /* velocity component in y */
  204. double w = 0; /* velocity component in z */
  205. double P = 0; /* angular velocity */
  206. double Q = 0; /* */
  207. double R = 0; /* */
  208. double lambda = 0*(M_PI/180); /* latitude (positive north) */
  209. double mu = 0*(M_PI/180); /* longitude (positive east) */
  210. double Re = EARTH_RAD + 5000; /* distance from earth center */
  211. double phi = 0*(M_PI/180); /* */
  212. double theta = 45*(M_PI/180); /* positive up */
  213. double psi = 0*(M_PI/180); /* positive cw*/
  214. // double dt = 0.05;
  215. double duration = 10;
  216. state_t s;
  217. int fd, retval;
  218. unsigned long tmp, data;
  219. struct rtc_time rtc_tm;
  220. /* Initialize the window */
  221. rocket.width = WIDTH;
  222. rocket.height = HEIGHT;
  223. rocketInit();
  224. /* open and configure the realtime clock */
  225. fd = open ("/dev/rtc", O_RDONLY);
  226. if (fd == -1)
  227. {
  228. perror("/dev/rtc");
  229. exit(errno);
  230. }
  231. /* Set the periodic IRQ rate to FREQ Hz */
  232. retval = ioctl(fd, RTC_IRQP_SET, FREQ);
  233. if (retval == -1)
  234. {
  235. perror("ioctl");
  236. exit(errno);
  237. }
  238. /* Enable periodic interrupts */
  239. retval = ioctl(fd, RTC_PIE_ON, 0);
  240. if (retval == -1)
  241. {
  242. perror("ioctl");
  243. exit(errno);
  244. }
  245. //initModele();
  246. s.m = 10.0;
  247. s.Ix = 25e-3;
  248. s.Iy = 3;
  249. s.Iz = 3;
  250. s.Faero[0] = 0;
  251. s.Faero[1] = 0;
  252. s.Faero[2] = 0;
  253. s.Maero[0] = 0;
  254. s.Maero[1] = 0;
  255. s.Maero[2] = 0;
  256. init_cond = (double *) malloc(sizeof(double) * neq);
  257. s.L_BV[0][0] = cos(theta)*cos(psi);
  258. s.L_BV[0][1] = cos(theta)*sin(psi);
  259. s.L_BV[0][2] =-sin(theta);
  260. s.L_BV[1][0] = sin(phi)*sin(theta)*cos(psi) - cos(phi)*sin(psi);
  261. s.L_BV[1][1] = sin(phi)*sin(theta)*sin(psi) + cos(phi)*cos(psi);
  262. s.L_BV[1][2] = sin(phi)*cos(theta);
  263. s.L_BV[2][0] = cos(phi)*sin(theta)*cos(psi) + sin(phi)*sin(psi);
  264. s.L_BV[2][1] = cos(phi)*sin(theta)*sin(psi) - sin(phi)*cos(psi);
  265. s.L_BV[2][2] = cos(phi)*cos(theta);
  266. init_cond[0] = u; /* velocity component in x */
  267. init_cond[1] = v; /* velocity component in y */
  268. init_cond[2] = w; /* velocity component in z */
  269. init_cond[3] = P+ (s.L_BV[0][0]*WE*cos(lambda)-s.L_BV[0][2]*WE*sin(lambda));
  270. init_cond[4] = Q+ (s.L_BV[1][0]*WE*cos(lambda)-s.L_BV[1][2]*WE*sin(lambda));
  271. init_cond[5] = R+ (s.L_BV[2][0]*WE*cos(lambda)-s.L_BV[2][2]*WE*sin(lambda));
  272. init_cond[6] = lambda; /* latitude */
  273. init_cond[7] = mu; /* longitude */
  274. init_cond[8] = Re; /* radius */
  275. init_cond[9] = phi; /* phi */
  276. init_cond[10] = theta; /* theta */
  277. init_cond[11] = psi; /* psi */
  278. time = 0;
  279. // eom(neq, time, init_cond, res, &s);
  280. /*
  281. fprintf(stderr, "% e (u dot)\n", res[0]);
  282. fprintf(stderr, "% e (v dot)\n", res[1]);
  283. fprintf(stderr, "% e (w dot)\n", res[2]);
  284. fprintf(stderr, "% e (p dot)\n", res[3]);
  285. fprintf(stderr, "% e (q dot)\n", res[4]);
  286. fprintf(stderr, "% e (r dot)\n", res[5]);
  287. fprintf(stderr, "% e (lambda dot)\n", res[6]);
  288. fprintf(stderr, "% e (mu dot)\n", res[7]);
  289. fprintf(stderr, "% e (R dot)\n", res[8]);
  290. fprintf(stderr, "% e (phi dot)\n", res[9]);
  291. fprintf(stderr, "% e (theta dot)\n", res[10]);
  292. fprintf(stderr, "% e (psi dot)\n", res[11]);
  293. */
  294. n = NUM_rk4 (eom, neq, STEP, duration, init_cond, &ans, &s);
  295. /* set the initial conditions */
  296. //modeleInfo.state[0] = 7.0;
  297. //modeleInfo.state[1] = 25.0;//.3944;
  298. //modeleInfo.state[2] = 0.0;
  299. //modeleInfo.state[3] = 0.0;
  300. // for( i = 0; i < n; i++)
  301. // {
  302. // printf("% .12e ", ans[0 + neq*i]); /* u */
  303. // printf("% .12e ", ans[1 + neq*i]); /* v */
  304. // printf("% .12e ", ans[2 + neq*i]); /* w */
  305. // printf("% .12e ", ans[3 + neq*i]); /* p */
  306. // printf("% .12e ", ans[4 + neq*i]); /* q */
  307. // printf("% .12e ", ans[5 + neq*i]); /* r */
  308. // printf("% .12e ", ans[6 + neq*i]); /* lambda */
  309. // printf("% .12e ", ans[7 + neq*i]); /* mu */
  310. // printf("% .12e ", ans[8 + neq*i]); /* R */
  311. // printf("% .12e ", ans[9 + neq*i]); /* phi */
  312. // printf("% .12e ", ans[10 + neq*i]); /* theta */
  313. // printf("% .12e \n", ans[11 + neq*i]); /* psi */
  314. // }
  315. // DrawSystem(y);
  316. for (i = 0; i < n; i++)
  317. {
  318. /* This blocks */
  319. retval = read(fd, &data, sizeof(unsigned long));
  320. if (retval == -1)
  321. {
  322. perror("read");
  323. exit(errno);
  324. }
  325. DrawSystem(ans + neq*i);
  326. }
  327. /* Disable periodic interrupts */
  328. retval = ioctl(fd, RTC_PIE_OFF, 0);
  329. if (retval == -1)
  330. {
  331. perror("ioctl");
  332. exit(errno);
  333. }
  334. free(init_cond);
  335. //free(ans);
  336. return 0;
  337. }