Advertisement
Guest User

Untitled

a guest
Mar 24th, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.56 KB | None | 0 0
  1. #include "simpletools.h"
  2. #include "abdrive.h"
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <math.h>
  6. #include <stdbool.h>
  7.  
  8. #define DIM_SQUARES 16
  9. #define DIS_INITIAL 146
  10. #define DIS_UNIT 125
  11. #define GRA_START 0
  12. #define GRA_END 15
  13. #define GRA_INVW 999
  14. #define STACK_SIZE DIM_SQUARES * DIM_SQUARES
  15. #define IR_DISTANCE_THRESHOLD 39
  16.  
  17. typedef enum {UP, DOWN, LEFT, RIGHT, NONE} DIRECTION;
  18. typedef struct STACK {
  19. int stk[STACK_SIZE];
  20. int top;
  21. } STACK;
  22.  
  23. STACK s;
  24. STACK p;
  25. bool c[DIM_SQUARES][DIM_SQUARES];
  26. bool v[DIM_SQUARES];
  27.  
  28. int distance_ir_left() {
  29. int left = 0;
  30.  
  31. for(int dacVal = 0; dacVal < 160; dacVal += 4) {
  32. dac_ctr(26, 0, dacVal);
  33. freqout(11, 1, 38000);
  34. left += input(10);
  35. }
  36.  
  37. return left;
  38. }
  39.  
  40. int distance_ir_right() {
  41. int right = 0;
  42.  
  43. for(int dacVal = 0; dacVal < 160; dacVal += 4) {
  44. dac_ctr(27, 1, dacVal);
  45. freqout(1, 1, 38000);
  46. right += input(2);
  47. }
  48.  
  49. return right;
  50. }
  51.  
  52. int direction_from(int current, DIRECTION direction) {
  53. int x = current % 4;
  54. int y = (current - x) / 4;
  55.  
  56. if(direction == UP) y += 1;
  57. if(direction == DOWN) y -= 1;
  58. if(direction == LEFT) x -= 1;
  59. if(direction == RIGHT) x += 1;
  60.  
  61. current = y * 4 + x; // Value recomposition.
  62.  
  63. if(current >= DIM_SQUARES || current < 0) return -1;
  64. return current;
  65. }
  66.  
  67. DIRECTION direction_between(int source, int destination) {
  68. int source_x = source % 4;
  69. int source_y = (source - source_x) / 4;
  70.  
  71. int destination_x = destination % 4;
  72. int destination_y = (destination - destination_x) / 4;
  73.  
  74. int delta_x = source_x - destination_x;
  75. int delta_y = source_y - destination_y;
  76.  
  77. if(delta_x == 1) return LEFT;
  78. if(delta_x == -1) return RIGHT;
  79. if(delta_y == 1) return DOWN;
  80. if(delta_y == -1) return UP;
  81.  
  82. return NONE;
  83. }
  84.  
  85. void stack_push(STACK *stack, int num) {
  86. if (stack->top == (STACK_SIZE - 1)) {
  87. printf("Stack is full.\n");
  88. return;
  89. }
  90.  
  91. stack->top = stack->top + 1;
  92. stack->stk[stack->top] = num;
  93. }
  94.  
  95. int stack_pop(STACK *stack) {
  96. if (stack->top == - 1) {
  97. printf("Stack is empty.\n");
  98. return -1;
  99. }
  100.  
  101. int num = stack->stk[stack->top];
  102. stack->top -= 1;
  103. return num;
  104. }
  105.  
  106. int stack_top(STACK *stack) {
  107. if (stack->top == - 1) {
  108. printf("Stack is empty.\n");
  109. return 0;
  110. }
  111.  
  112. int num = stack->stk[stack->top];
  113. return num;
  114. }
  115.  
  116. void move_initial() {
  117. drive_goto(DIS_INITIAL, DIS_INITIAL);
  118. }
  119.  
  120. void move_up() {
  121. drive_goto(DIS_UNIT, DIS_UNIT);
  122. }
  123.  
  124. void move_down() {
  125. drive_goto(-DIS_UNIT, -DIS_UNIT);
  126. }
  127.  
  128. void move_left() {
  129. drive_goto(-26, 25);
  130. drive_goto(DIS_UNIT, DIS_UNIT);
  131. drive_goto(25, -26);
  132. }
  133.  
  134. void move_right() {
  135. drive_goto(25, -26);
  136. drive_goto(DIS_UNIT, DIS_UNIT);
  137. drive_goto(-26, 25);
  138. }
  139.  
  140. void print_stack(STACK *stack) {
  141. for(int i = 0; i < stack->top; ++i) {
  142. printf("%i : ", stack->stk[i]);
  143. }
  144.  
  145. printf("\n");
  146. }
  147.  
  148. void dijkstra() {
  149. int dist[DIM_SQUARES], prev[DIM_SQUARES], selected[DIM_SQUARES] = {0}, i, m, min, start, d, j, reversed[DIM_SQUARES];
  150.  
  151. for(i = 0; i < DIM_SQUARES; i++) {
  152. dist[i] = GRA_INVW;
  153. prev[i] = -1;
  154. }
  155.  
  156. start = GRA_START;
  157. selected[start] = 1;
  158. dist[start] = 0;
  159.  
  160. while(selected[GRA_END] == 0) {
  161. min = GRA_INVW;
  162. m = 0;
  163.  
  164. for(i = 0; i < DIM_SQUARES; i++) {
  165. d = dist[start] + (c[start][i] ? 1 : GRA_INVW);
  166.  
  167. if(d < dist[i] && selected[i] == 0) {
  168. dist[i] = d;
  169. printf("Setting previous of %i to %i.\n", i, start);
  170. prev[i] = start;
  171. }
  172.  
  173. if(min > dist[i] && selected[i] == 0) {
  174. min = dist[i];
  175. m = i;
  176. }
  177. }
  178.  
  179. start = m;
  180. selected[start] = 1;
  181. }
  182.  
  183. start = GRA_END;
  184. j = 0;
  185.  
  186. while(start != -1) {
  187. reversed[j++] = start;
  188. start = prev[start];
  189. }
  190.  
  191. for(i = 0; i < j; ++i) {
  192. stack_push(&p, reversed[i]);
  193. }
  194.  
  195. stack_push(&p, GRA_START);
  196. }
  197.  
  198. void follow_shortest() {
  199. int current = stack_pop(&p);
  200. int next;
  201.  
  202. while(current > 0) {
  203. next = stack_pop(&p);
  204.  
  205. DIRECTION direction_dominant = direction_between(current, next);
  206. printf("Direction: %i, ID: %i.\n", direction_dominant, next);
  207.  
  208. if(direction_dominant == UP) move_up();
  209. if(direction_dominant == LEFT) move_left();
  210. if(direction_dominant == RIGHT) move_right();
  211. if(direction_dominant == DOWN) move_down();
  212.  
  213. current = next;
  214. }
  215. }
  216.  
  217. int traverse() {
  218. int current = stack_top(&s);
  219. if(current == 0 && v[current]) return true;
  220.  
  221. int id_left = direction_from(current, LEFT);
  222. int id_right = direction_from(current, RIGHT);
  223. int id_up = direction_from(current, UP);
  224. int id_down = direction_from(current, DOWN);
  225. bool direction_left, direction_right, direction_up, direction_down;
  226.  
  227. if(!v[current]) {
  228. int distance_left = distance_ir_left();
  229. int distance_right = distance_ir_right();
  230. drive_goto(25, -26);
  231.  
  232. int distance_up = distance_ir_left();
  233. int distance_down = distance_ir_right();
  234. drive_goto(-26, 25);
  235.  
  236. direction_left = distance_left > IR_DISTANCE_THRESHOLD;
  237. direction_right = distance_right > IR_DISTANCE_THRESHOLD;
  238. direction_up = distance_up > IR_DISTANCE_THRESHOLD;
  239. direction_down = distance_down > IR_DISTANCE_THRESHOLD;
  240.  
  241. c[current][id_left] = direction_left;
  242. c[current][id_right] = direction_right;
  243. c[current][id_up] = direction_up;
  244. c[current][id_down] = direction_down;
  245.  
  246. c[id_left][current] = direction_left;
  247. c[id_right][current] = direction_right;
  248. c[id_up][current] = direction_up;
  249. c[id_down][current] = direction_down;
  250.  
  251. printf("ID: %i, U: %i, D: %i, L: %i, R: %i.\n", current, distance_up, distance_down, distance_left, distance_right);
  252. } else {
  253. direction_left = c[current][id_left];
  254. direction_right = c[current][id_right];
  255. direction_up = c[current][id_up];
  256. direction_down = c[current][id_down];
  257. }
  258.  
  259. v[current] = true;
  260.  
  261. int idx_dominant;
  262. DIRECTION direction_dominant;
  263.  
  264. if(direction_left && id_left != -1 && !v[id_left]) {
  265. idx_dominant = id_left;
  266. direction_dominant = LEFT;
  267. } else if(direction_right && id_right != -1 && !v[id_right]) {
  268. idx_dominant = id_right;
  269. direction_dominant = RIGHT;
  270. } else if(direction_up && id_up != -1 && !v[id_up]) {
  271. idx_dominant = id_up;
  272. direction_dominant = UP;
  273. } else if(direction_down && id_down != -1 && !v[id_down]) {
  274. idx_dominant = id_down;
  275. direction_dominant = DOWN;
  276. } else {
  277. idx_dominant = -1;
  278. direction_dominant = NONE;
  279. }
  280.  
  281. if(idx_dominant != -1) {
  282. if(direction_dominant == UP) move_up();
  283. if(direction_dominant == LEFT) move_left();
  284. if(direction_dominant == RIGHT) move_right();
  285. if(direction_dominant == DOWN) move_down();
  286. stack_push(&s, idx_dominant);
  287.  
  288. printf("Direction: %i, ID: %i.\n", direction_dominant, idx_dominant);
  289. } else {
  290. stack_pop(&s);
  291. int previous = stack_top(&s);
  292. direction_dominant = direction_between(current, previous);
  293.  
  294. printf("Direction: %i, ID: %i.\n", direction_dominant, previous);
  295.  
  296. if(direction_dominant == UP) move_up();
  297. if(direction_dominant == LEFT) move_left();
  298. if(direction_dominant == RIGHT) move_right();
  299. if(direction_dominant == DOWN) move_down();
  300. }
  301.  
  302. print_stack(&s);
  303.  
  304. return traverse();
  305. }
  306.  
  307. int main() {
  308. // Initialization
  309. s.top = -1;
  310.  
  311. for(int i = 0; i < DIM_SQUARES; ++i) {
  312. v[i] = false;
  313.  
  314. for(int j = 0; j < DIM_SQUARES; ++j) c[i][j] = i == j ? true : false;
  315. }
  316.  
  317. stack_push(&s, 0);
  318.  
  319. // Phase 0
  320. move_initial();
  321.  
  322. // Phase 1
  323. traverse();
  324.  
  325. // Phase 2
  326. dijkstra();
  327. print_stack(&p);
  328. follow_shortest();
  329. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement