Advertisement
Guest User

Untitled

a guest
Mar 24th, 2017
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.63 KB | None | 0 0
  1. #include "simpletools.h" // Library includes
  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.  
  83. void stack_push(STACK *stack, int num) {
  84. if (stack->top == (STACK_SIZE - 1)) {
  85. printf("Stack is full.\n");
  86. return;
  87. }
  88.  
  89. stack->top = stack->top + 1;
  90. stack->stk[stack->top] = num;
  91. }
  92.  
  93. int stack_pop(STACK *stack) {
  94. if (stack->top == - 1) {
  95. printf("Stack is empty.\n");
  96. return -1;
  97. }
  98.  
  99. int num = stack->stk[stack->top];
  100. stack->top -= 1;
  101. return num;
  102. }
  103.  
  104. int stack_top(STACK *stack) {
  105. if (stack->top == - 1) {
  106. printf("Stack is empty.\n");
  107. return 0;
  108. }
  109.  
  110. int num = stack->stk[stack->top];
  111. return num;
  112. }
  113.  
  114. void move_initial() {
  115. drive_goto(DIS_INITIAL, DIS_INITIAL);
  116. }
  117.  
  118. void move_up() {
  119. drive_goto(DIS_UNIT, DIS_UNIT);
  120. }
  121.  
  122. void move_down() {
  123. drive_goto(-DIS_UNIT, -DIS_UNIT);
  124. }
  125.  
  126. void move_left() {
  127. drive_goto(-26, 25);
  128. drive_goto(DIS_UNIT, DIS_UNIT);
  129. drive_goto(25, -26);
  130. }
  131.  
  132. void move_right() {
  133. drive_goto(25, -26);
  134. drive_goto(DIS_UNIT, DIS_UNIT);
  135. drive_goto(-26, 25);
  136. }
  137.  
  138. void print_stack(STACK *stack) {
  139. for(int i = 0; i < stack->top; ++i) {
  140. printf("%i : ", stack->stk[i]);
  141. }
  142.  
  143. printf("\n");
  144. }
  145.  
  146. void dijsktra() {
  147. int dist[DIM_SQUARES], prev[DIM_SQUARES], selected[DIM_SQUARES] = {0}, i, m, min, start, d, j;
  148. int path_reversed[DIM_SQUARES];
  149.  
  150. for(i = 0; i < DIM_SQUARES; i++) {
  151. dist[i] = GRA_INVW;
  152. prev[i] = -1;
  153. }
  154.  
  155. start = GRA_START;
  156. selected[start] = 1;
  157. dist[start] = 0;
  158.  
  159. while(selected[GRA_END] == 0) {
  160. min = GRA_INVW;
  161. m = 0;
  162.  
  163. for(i = 0; i < DIM_SQUARES; i++) {
  164. d = dist[start] + c[start][i] ? 1 : GRA_INVW;
  165.  
  166. if(d < dist[i] && selected[i] == 0) {
  167. dist[i] = d;
  168. prev[i] = start;
  169. }
  170.  
  171. if(min > dist[i] && selected[i] == 0) {
  172. min = dist[i];
  173. m = i;
  174. }
  175. }
  176.  
  177. start = m;
  178. selected[start] = 1;
  179. }
  180.  
  181. start = GRA_END;
  182. j = 0;
  183.  
  184. while(start != -1) {
  185. path_reversed[j++] = start;
  186. start = prev[start];
  187. }
  188.  
  189. for(int k = 0; k < j; ++k) stack_push(&p, path_reversed[k]);
  190. }
  191.  
  192. void follow_shortest() {
  193. int current = stack_pop(&p);
  194. int next;
  195.  
  196. while(current > 0) {
  197. next = stack_pop(&p);
  198.  
  199. DIRECTION direction_dominant = direction_between(current, next);
  200. printf("Direction: %i, ID: %i.\n", direction_dominant, next);
  201.  
  202. if(direction_dominant == UP) move_up();
  203. if(direction_dominant == LEFT) move_left();
  204. if(direction_dominant == RIGHT) move_right();
  205. if(direction_dominant == DOWN) move_down();
  206.  
  207. current = next;
  208. }
  209. }
  210.  
  211. int traverse() {
  212. int current = stack_top(&s);
  213. if(current == 0 && v[current]) return true;
  214.  
  215. int id_left = direction_from(current, LEFT);
  216. int id_right = direction_from(current, RIGHT);
  217. int id_up = direction_from(current, UP);
  218. int id_down = direction_from(current, DOWN);
  219. bool direction_left, direction_right, direction_up, direction_down;
  220.  
  221. if(!v[current]) {
  222. int distance_left = distance_ir_left();
  223. int distance_right = distance_ir_right();
  224. drive_goto(25, -26);
  225.  
  226. int distance_up = distance_ir_left();
  227. int distance_down = distance_ir_right();
  228. drive_goto(-26, 25);
  229.  
  230. direction_left = distance_left > IR_DISTANCE_THRESHOLD;
  231. direction_right = distance_right > IR_DISTANCE_THRESHOLD;
  232. direction_up = distance_up > IR_DISTANCE_THRESHOLD;
  233. direction_down = distance_down > IR_DISTANCE_THRESHOLD;
  234.  
  235. c[current][id_left] = direction_left;
  236. c[current][id_right] = direction_right;
  237. c[current][id_up] = direction_up;
  238. c[current][id_down] = direction_down;
  239.  
  240. c[id_left][current] = direction_left;
  241. c[id_right][current] = direction_right;
  242. c[id_up][current] = direction_up;
  243. c[id_down][current] = direction_down;
  244.  
  245. printf("ID: %i, U: %i, D: %i, L: %i, R: %i.\n", current, distance_up, distance_down, distance_left, distance_right);
  246. } else {
  247. direction_left = c[current][id_left];
  248. direction_right = c[current][id_right];
  249. direction_up = c[current][id_up];
  250. direction_down = c[current][id_down];
  251. }
  252.  
  253. v[current] = true;
  254.  
  255. int idx_dominant;
  256. DIRECTION direction_dominant;
  257.  
  258. if(direction_left && id_left != -1 && !v[id_left]) {
  259. idx_dominant = id_left;
  260. direction_dominant = LEFT;
  261. } else if(direction_right && id_right != -1 && !v[id_right]) {
  262. idx_dominant = id_right;
  263. direction_dominant = RIGHT;
  264. } else if(direction_up && id_up != -1 && !v[id_up]) {
  265. idx_dominant = id_up;
  266. direction_dominant = UP;
  267. } else if(direction_down && id_down != -1 && !v[id_down]) {
  268. idx_dominant = id_down;
  269. direction_dominant = DOWN;
  270. } else {
  271. idx_dominant = -1;
  272. direction_dominant = NONE;
  273. }
  274.  
  275. if(idx_dominant != -1) {
  276. if(direction_dominant == UP) move_up();
  277. if(direction_dominant == LEFT) move_left();
  278. if(direction_dominant == RIGHT) move_right();
  279. if(direction_dominant == DOWN) move_down();
  280. stack_push(&s, idx_dominant);
  281.  
  282. printf("Direction: %i, ID: %i.\n", direction_dominant, idx_dominant);
  283. } else {
  284. stack_pop(&s);
  285. int previous = stack_top(&s);
  286. direction_dominant = direction_between(current, previous);
  287.  
  288. printf("Direction: %i, ID: %i.\n", direction_dominant, previous);
  289.  
  290. if(direction_dominant == UP) move_up();
  291. if(direction_dominant == LEFT) move_left();
  292. if(direction_dominant == RIGHT) move_right();
  293. if(direction_dominant == DOWN) move_down();
  294. }
  295.  
  296. print_stack(&s);
  297.  
  298. return traverse();
  299. }
  300.  
  301. int main() {
  302. // Initialization
  303. s.top = -1;
  304.  
  305. for(int i = 0; i < DIM_SQUARES; ++i) {
  306. v[i] = false;
  307.  
  308. for(int j = 0; j < DIM_SQUARES; ++j) c[i][j] = i == j ? true : false;
  309. }
  310.  
  311. stack_push(&s, 0);
  312.  
  313. // Step 0: Move to the first square.
  314. move_initial();
  315.  
  316. // Step 1: Build a connection matrix by traversing the maze and return back.
  317. traverse();
  318.  
  319. // Step 2:
  320. printf("Test 1.\n");
  321. dijsktra();
  322. printf("Test 2.\n");
  323. print_stack(&p);
  324. follow_shortest();
  325. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement