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.
 
 
 
 
 

215 lines
6.3 KiB

  1. #include "control_parser.h"
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <sys/socket.h>
  5. typedef control_parser_ctx context;
  6. static void extract(context *ctx, char *fpc) {
  7. gssize curpos = (fpc - ctx->buffer->str);
  8. gssize len = curpos - ctx->mark;
  9. g_string_truncate(ctx->tmp, 0);
  10. g_string_append_len(ctx->tmp, ctx->buffer->str + ctx->mark, len);
  11. ctx->mark = -1;
  12. /* printf("Read chunk '%s'\n", ctx->tmp->str); */
  13. }
  14. static double extract_double(context *ctx, char *fpc) {
  15. extract(ctx, fpc);
  16. return strtod(ctx->tmp->str, NULL);
  17. }
  18. static timestamp extract_ts(context *ctx, char *fpc) {
  19. extract(ctx, fpc);
  20. return atoi(ctx->tmp->str);
  21. }
  22. %%{
  23. machine control_parser;
  24. variable cs ctx->cs;
  25. action done {
  26. t->alive = 0;
  27. /* fprintf(stderr, "Run finished\n"); */
  28. fbreak;
  29. }
  30. action mark { ctx->mark = fpc - ctx->buffer->str; }
  31. action telemetrystart { ctx->tm = telemetry_new(); }
  32. action telemetrystop {
  33. g_queue_push_tail(&t->telemetry, ctx->tm);
  34. if (!t->alive) {
  35. t->vehicle.accel = ctx->tm->vehicle.accel;
  36. t->vehicle.turn = ctx->tm->vehicle.turn;
  37. gettimeofday(&t->started, NULL);
  38. /* fprintf(stderr, "New run\n"); */
  39. } else {
  40. /* fprintf(stderr, "time difference [ms]: %i\n", getcurts(t) - ctx->tm->ts); */
  41. fprintf(stderr, "Miss predict: dx=%f, dy=%f, ddir=%f, steps=%u\n",
  42. t->sim.tm.vehicle.x - t->vehicle.x,
  43. t->sim.tm.vehicle.y - t->vehicle.y,
  44. t->sim.tm.vehicle.dir - t->vehicle.dir,
  45. t->sim.steps);
  46. }
  47. /* Reset simulation */
  48. t->sim.tm.ts = ctx->tm->ts;
  49. t->sim.tm.vehicle = ctx->tm->vehicle;
  50. g_array_set_size(t->sim.tm.objects, 0);
  51. g_array_append_vals(t->sim.tm.objects, ctx->tm->objects->data, ctx->tm->objects->len);
  52. t->sim.steps = 0;
  53. t->last_ts = ctx->tm->ts;
  54. ctx->tm = NULL;
  55. t->alive = 1;
  56. }
  57. action vehicle {
  58. ctx->tm->ts = ctx->ts;
  59. ctx->tm->vehicle.x = ctx->x;
  60. ctx->tm->vehicle.y = ctx->y;
  61. ctx->tm->vehicle.dir = ctx->dir;
  62. ctx->tm->vehicle.speed = ctx->speed;
  63. t->vehicle.x = ctx->x;
  64. t->vehicle.y = ctx->y;
  65. t->vehicle.dir = ctx->dir;
  66. t->vehicle.speed = ctx->speed;
  67. /* printf("Vehicle at %f / %f\n", ctx->x, ctx->y); */
  68. }
  69. SP = " ";
  70. double = '-'? (digit | '.')*;
  71. dx = double >mark % { t->map.dx = extract_double(ctx, fpc); };
  72. dy = double >mark % { t->map.dy = extract_double(ctx, fpc); };
  73. min_sensor = double >mark % { t->map.min_sensor = extract_double(ctx, fpc); };
  74. max_sensor = double >mark % { t->map.max_sensor = extract_double(ctx, fpc); };
  75. max_speed = double >mark % { t->map.max_speed = extract_double(ctx, fpc); };
  76. max_turn = double >mark % { t->map.max_turn = extract_double(ctx, fpc); };
  77. max_hard_turn = double >mark % { t->map.max_hard_turn = extract_double(ctx, fpc); };
  78. init = "I" SP dx SP dy SP double SP min_sensor SP max_sensor SP max_speed SP max_turn SP max_hard_turn SP ";";
  79. x = double >mark % { ctx->x = extract_double(ctx, fpc); };
  80. y = double >mark % { ctx->y = extract_double(ctx, fpc); };
  81. r = double >mark % { ctx->r = extract_double(ctx, fpc); };
  82. dir = double >mark % { ctx->dir = extract_double(ctx, fpc); };
  83. speed = double >mark % { ctx->speed = extract_double(ctx, fpc); };
  84. ctl = (
  85. "a" @ { ctx->tm->vehicle.accel = ACCEL; }
  86. | "-" @ { ctx->tm->vehicle.accel = ROLL; }
  87. | "b" @ { ctx->tm->vehicle.accel = BRAKE; }
  88. ) (
  89. "L" @ { ctx->tm->vehicle.turn = TURN_HARD_LEFT; }
  90. | "l" @ { ctx->tm->vehicle.turn = TURN_LEFT; }
  91. | "-" @ { ctx->tm->vehicle.turn = TURN_STRAIGHT; }
  92. | "r" @ { ctx->tm->vehicle.turn = TURN_RIGHT; }
  93. | "R" @ { ctx->tm->vehicle.turn = TURN_HARD_RIGHT; }
  94. );
  95. timestamp = (digit*) >mark % { ctx->ts = extract_ts(ctx, fpc); };
  96. score = (digit*) >mark % { printf("Score %u\n", extract_ts(ctx, fpc)); };
  97. boulder = "b" SP x SP y SP r SP % {
  98. object *o = object_new(BOLDER, ctx->x, ctx->y, ctx->r, 0, 0);
  99. /* g_array_append_vals(ctx->tm->objects, o, 1); */
  100. g_hash_table_replace(t->map.solid_objects, o, o);
  101. };
  102. crater = "c" SP x SP y SP r SP % {
  103. object *o = object_new(CRATER, ctx->x, ctx->y, ctx->r, 0, 0);
  104. /* g_array_append_vals(ctx->tm->objects, o, 1); */
  105. g_hash_table_replace(t->map.solid_objects, o, o);
  106. };
  107. homebase = "h" SP x SP y SP r SP; # ignore it
  108. martian = "m" SP x SP y SP dir SP speed SP % {
  109. object o = { MARTIAN, ctx->x, ctx->y, MARTIAN_RADIUS, ctx->dir, ctx->speed };
  110. g_array_append_val(ctx->tm->objects, o);
  111. };
  112. object = boulder | crater | homebase | martian;
  113. objects = object*;
  114. telemetry = ( ("T" SP timestamp SP ctl SP x SP y SP dir SP speed SP) %vehicle objects) >telemetrystart ";" % telemetrystop;
  115. # crash
  116. Boulder = "B" SP timestamp SP ";";
  117. # fell
  118. Crater = "C" SP timestamp SP ";";
  119. # killed by martian
  120. Kill = "K" SP timestamp SP ";";
  121. Success = "S" SP timestamp SP ";";
  122. End = "E" SP timestamp SP score SP ";";
  123. main := init? (telemetry | Boulder)* (Crater | Kill | Success)? End @ done;
  124. }%%
  125. %% write data;
  126. static int control_parser_has_error(context *ctx) {
  127. return ctx->cs == control_parser_error;
  128. }
  129. static int control_parser_is_finished(context *ctx) {
  130. return ctx->cs >= control_parser_first_final;
  131. }
  132. void control_parser_new(trial *t) {
  133. context *ctx = t->parse_ctx = g_slice_new(context);
  134. %% write init;
  135. ctx->buffer = g_string_sized_new(0);
  136. ctx->tmp = g_string_sized_new(0);
  137. ctx->mark = -1;
  138. ctx->pos = 0;
  139. }
  140. void control_parser_reset(trial *t) {
  141. context *ctx = t->parse_ctx;
  142. %% write init;
  143. g_string_truncate(ctx->tmp, 0);
  144. ctx->mark = -1;
  145. /* fprintf(stderr, "Parser reset\n"); */
  146. }
  147. void control_parser_free(trial *t) {
  148. g_string_free(t->parse_ctx->buffer, TRUE);
  149. g_string_free(t->parse_ctx->tmp, TRUE);
  150. g_slice_free(context, t->parse_ctx);
  151. }
  152. run_t control_parse(trial *t) {
  153. context *ctx = t->parse_ctx;
  154. gsize wehave;
  155. if (0 < (wehave = ctx->buffer->len - ctx->pos)) {
  156. char *p, *pe;
  157. p = ctx->buffer->str + ctx->pos;
  158. pe = p + wehave;
  159. /* fprintf(stderr, "Parsing '%s' (len=%zu)\n", p, wehave); */
  160. %% write exec;
  161. ctx->pos = p - ctx->buffer->str;
  162. if (ctx->mark == -1) {
  163. g_string_erase(ctx->buffer, 0, ctx->pos);
  164. ctx->pos = 0;
  165. } else if (ctx->mark) {
  166. g_string_erase(ctx->buffer, 0, ctx->mark);
  167. ctx->pos -= ctx->mark;
  168. ctx->mark = 0;
  169. }
  170. } else {
  171. fprintf(stderr, "No data to parse\n");
  172. }
  173. if (control_parser_has_error(ctx)) {
  174. fprintf(stderr, "Parse error: '%s'\n", ctx->buffer->str + ctx->pos);
  175. shutdown(t->socket, SHUT_RDWR);
  176. close(t->socket);
  177. exit(126);
  178. return RUN_ERROR;
  179. }
  180. if (control_parser_is_finished(ctx)) return RUN_DONE;
  181. return RUN_GO_ON;
  182. }