Advertisement
Guest User

Untitled

a guest
Jan 16th, 2013
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.04 KB | None | 0 0
  1. /*This code (excluding external libraries) is the intellectual property of Team 1127 Lotus Robotics*/
  2. #include <Keypad.h>
  3. #include <Arduino.h>
  4. #include <avr/pgmspace.h>
  5. #include <TVout.h>
  6. #include <TVoutfonts.h>
  7. #include <fontALL.h>
  8. #include "lyle.h"
  9. #include "testimage.h"
  10.  
  11. #define led1 2
  12. #define led2 11
  13. #define led3 9
  14. #define segbl 44
  15. #define segtl 42
  16. #define segm 40
  17. #define segt 38
  18. #define segtr 36
  19. #define segbr 34
  20. #define segb 32
  21. #define MAX_LOOP 76800
  22. #define DELAY_TIME 6
  23. #define RED_MIN 36
  24. #define RED_MAX 197
  25. #define GREEN_MIN 51
  26. #define GREEN_MAX 175
  27. #define BLUE_MIN 120
  28. #define BLUE_MAX 220
  29. #define PIXELS_IN_IMAGE 2700
  30. #define IMAGE_ROWS 45
  31. #define IMAGE_COLS 60
  32. /*#define RED_MIN 36
  33. #define RED_MAX 116
  34. #define GREEN_MIN 51
  35. #define GREEN_MAX 211
  36. #define BLUE_MIN 120
  37. #define BLUE_MAX 243*/
  38. #define VERTICAL_LINE_START 22
  39. #define VSCALE 2
  40. #define KEYPAD_ROWS 6
  41. #define KEYPAD_COLS 4
  42. #define CONVEX_HULL_ANGLE_CHANGE .1
  43.  
  44. #define DISABLE_CAMERA
  45. #define SPLASH_SCREEN
  46.  
  47. #ifndef DISABLE_CAMERA
  48. byte colorImage [2700][3];//Forum users: change this line to "int x;" or whatever you see fit to remove ram usage from the equation
  49. #endif
  50. byte binaryImage[45][60];
  51. byte currentPixel[3];
  52. byte segs[7] = {segbl, segtl, segm, segt, segtr, segbr, segb};
  53. byte segPatterns[10][7] = {{LOW, LOW, HIGH, LOW, LOW, LOW, LOW}, //0
  54. {HIGH, HIGH, HIGH, HIGH, LOW, LOW, HIGH}, //1
  55. {LOW, HIGH, LOW, LOW, LOW, HIGH, LOW}, //2
  56. {HIGH, HIGH, LOW, LOW, LOW, LOW, LOW}, //3
  57. {HIGH, LOW, LOW, HIGH, LOW, LOW, HIGH}, //4
  58. {HIGH, LOW, LOW, LOW, HIGH, LOW, LOW}, //5
  59. {LOW, LOW, LOW, LOW, HIGH, LOW, LOW}, //6
  60. {HIGH, HIGH, HIGH, LOW, LOW, LOW, HIGH}, //7
  61. {LOW, LOW, LOW, LOW, LOW, LOW, LOW}, //8
  62. {HIGH, LOW, LOW, LOW, LOW, LOW, LOW}}; //9
  63. char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
  64. {'1', '2', '3', '4'},
  65. {'5', '6', '7', '8'},
  66. {'9', 'a', 'b', 'c'},
  67. {'d', 'e', 'f', 'g'},
  68. {'h', 'i', 'j', 'k'},
  69. {'+', '-', 'p', 'n'}
  70. };
  71. byte rowPins[KEYPAD_ROWS] = {41, 39, 37, 35, 33, 31};
  72. byte colPins[KEYPAD_COLS] = {49, 47, 45, 43};
  73. Keypad remote = Keypad( makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);
  74. byte numberOfBlobs;
  75.  
  76. TVout TV;
  77. #ifdef SPLASH_SCREEN
  78. TVout warmUp;
  79. #endif
  80.  
  81. void printNumberTo7Seg(byte num);
  82.  
  83.  
  84. void setup()
  85. {
  86. pinMode(led1, OUTPUT);
  87. pinMode(led2, OUTPUT);
  88. pinMode(led3, OUTPUT);
  89. Serial.begin(115200);
  90. remote.setDebounceTime(50);
  91. #ifdef SPLASH_SCREEN
  92. warmUp.begin(NTSC);
  93. warmUp.select_font(font8x8ext);
  94. warmUp.println("Team 1127 Lotus\nRobotics Vision\nTracking\nDiagnostics\nUtility");
  95. warmUp.draw_rect(0, 50, warmUp.hres()-1, 10, WHITE, BLACK);
  96. for (byte i = 0; i < warmUp.hres(); i++)
  97. {
  98. warmUp.draw_column(i, 50, 60, WHITE);
  99. warmUp.delay(1);
  100. }
  101. warmUp.end();
  102. #endif
  103. TV.begin(NTSC);//, 64, 45);
  104. TV.select_font(font4x6);
  105. pinMode(segbl, OUTPUT);
  106. pinMode(segtl, OUTPUT);
  107. pinMode(segm, OUTPUT);
  108. pinMode(segt, OUTPUT);
  109. pinMode(segtr, OUTPUT);
  110. pinMode(segbr, OUTPUT);
  111. pinMode(segb, OUTPUT);
  112. digitalWrite(segbl, HIGH);
  113. digitalWrite(segtl, HIGH);
  114. digitalWrite(segt, HIGH);
  115. digitalWrite(segtr, HIGH);
  116. digitalWrite(segbr, HIGH);
  117. digitalWrite(segb, HIGH);
  118. digitalWrite(segm, HIGH);
  119. printNumberTo7Seg(0);
  120. Serial.println(micros());
  121. for (int i = 0; i < 2700; i++)
  122. {
  123. #ifdef DISABLE_CAMERA
  124. currentPixel[0] = pgm_read_byte_near(&(testimage[i][0]));
  125. currentPixel[1] = pgm_read_byte_near(&(testimage[i][1]));
  126. currentPixel[2] = pgm_read_byte_near(&(testimage[i][2]));
  127. #else
  128. currentPixel[0] = random(256);
  129. currentPixel[1] = random(256);
  130. currentPixel[2] = random(256);
  131. #endif
  132. if (currentPixel[0] >= RED_MIN && currentPixel[0] <= RED_MAX && currentPixel[1] >= GREEN_MIN && currentPixel[1] <= GREEN_MAX && currentPixel[2] >= BLUE_MIN && currentPixel[0] <= BLUE_MAX)
  133. binaryImage[i/60][i%60] = true;
  134. else
  135. binaryImage[i/60][i%60] = false;
  136. }
  137. printNumberTo7Seg(1);
  138. removeSmallObjects(false);
  139. printNumberTo7Seg(2);
  140. dumpFullStatusToTV();
  141. printNumberTo7Seg(3);
  142. TV.bitmap(72, 0, lyle);
  143. randomSeed(analogRead(0));
  144. blobifyBinaryImage2();
  145. removeBlobsSmallerThan(10);
  146. reorderBlobs();
  147. dumpFullStatusToTV();
  148. dumpBinaryImageToSerial();
  149.  
  150. }
  151. void loop()
  152. {
  153. #ifndef DISABLE_LYLE_BLINKS
  154. if (random(1000000) == 0 || analogRead(4) > 10 )
  155. {
  156. TV.draw_rect(90, 8, 3, 5, WHITE, WHITE);
  157. TV.draw_rect(101, 5, 3, 3, WHITE, WHITE);
  158. TV.draw_rect(102, 4, 1, 5, WHITE, WHITE);
  159. delay(100);
  160. TV.draw_rect(90, 8, 3, 5, BLACK, BLACK);
  161. TV.draw_rect(101, 5, 3, 3, BLACK, BLACK);
  162. TV.draw_rect(102, 4, 1, 5, BLACK, BLACK);
  163. randomSeed(analogRead(0));
  164. }
  165. #endif
  166. //TV.print(remote.getKey());
  167. for (byte i = 2; i < numberOfBlobs+2; i++)
  168. {
  169. highlightSpecifiedBlobOnTV(i);
  170. delay(500);
  171. }
  172. }
  173.  
  174. void dumpBinaryImageToSerial()
  175. {
  176. for (byte i = 0; i < 45; i++)
  177. {
  178. for (byte k = 0; k < 60; k++)
  179. if (binaryImage[i][k])
  180. Serial.print(binaryImage[i][k]);
  181. else
  182. Serial.print(' ');
  183. Serial.println();
  184. }
  185. }
  186.  
  187. void dumpBinaryImageToTV()
  188. {
  189. for (byte i = 0; i < 45; i++)
  190. {
  191. for (byte k = 0; k < 60; k++)
  192. if (binaryImage[i][k])
  193. TV.set_pixel(k+1, i+1, WHITE);
  194. else
  195. TV.set_pixel(k+1, i+1, BLACK);
  196. }
  197. /*TV.set_pixel(0, 0,WHITE);
  198. TV.set_pixel(63, 0,WHITE);
  199. TV.set_pixel(0, 44,WHITE);
  200. TV.set_pixel(63, 44,WHITE);
  201. */
  202. }
  203.  
  204. void dumpFullStatusToTV()
  205. {
  206. dumpBinaryImageToTV();
  207. TV.draw_rect(0,0,61,46,1);
  208. TV.set_cursor(0,48);
  209. TV.print("Team 1127\n");
  210. #ifdef DISABLE_CAMERA
  211. TV.print("Not using Axis camera. Using\ninternal test images instead\n");
  212. #endif
  213.  
  214. }
  215.  
  216. void highlightSpecifiedBlobOnTV(byte specifiedBlob)
  217. {
  218. for (byte i = 0; i < IMAGE_ROWS; i++)
  219. for (byte k = 0; k < IMAGE_COLS; k++)
  220. if (binaryImage[i][k] == specifiedBlob)
  221. TV.set_pixel(k+1, i+1, WHITE); //+1s account for 1 pixel border around camera feed on the screen
  222. else
  223. TV.set_pixel(k+1, i+1, BLACK);
  224. }
  225.  
  226.  
  227. byte retriveColorValueFromFlash(int pixelNo, byte color)
  228. {
  229. return pgm_read_byte_near(&(testimage[pixelNo][color]));
  230. }
  231.  
  232. void removeSmallObjects(boolean useAll8Corners)
  233. {
  234. byte row, col;
  235. for (int i = 0; i < PIXELS_IN_IMAGE; i++)
  236. {
  237. row = i/60;
  238. col = i%60;
  239. if (binaryImage[row][col])
  240. {
  241. if (useAll8Corners)
  242. {
  243. }
  244. else
  245. {
  246. if ((row == 0 || !binaryImage[row-1][col]) && (row == 45 || !binaryImage[row+1][col]) && (col == 0 || !binaryImage[row][col-1]) && (col == 60 || !binaryImage[row][col+1]))
  247. binaryImage[row][col] = false;
  248. }
  249. }
  250. else
  251. continue;
  252. }
  253. }
  254.  
  255. /** do not use */
  256. void removeNotSoSmallObjects()
  257. {
  258. Serial.println("WARNING: Using removeNotSoSmallObjects.\nResults may be invalid.");
  259. byte row, col;
  260. for (int i = 0; i < PIXELS_IN_IMAGE; i++)
  261. {
  262. row = i/60;
  263. col = i%60;
  264. if (binaryImage[row][col])
  265. {
  266. binaryImage[row][col] = false;
  267. removeSmallObjects(false);
  268. binaryImage[row][col] = true;
  269. }
  270. }
  271. removeSmallObjects(false);
  272. }
  273.  
  274. void blobifyBinaryImage()
  275. {
  276. byte blobIndex = 2; // 0 means "black" pixel, 1 means "white" pixel, >2 means pixel belongs the the same group as others with its id
  277. for (byte row = 0; row < 45; row++)
  278. {
  279. for (byte col = 0; col < 60; col++)
  280. {
  281. if (binaryImage[row][col])
  282. {
  283. //Find out if this pixel belongs to the same blob by checking the 8 adjacesnt squares for a pixel with the same blobIndex
  284. for ( char offsetRow = -1; offsetRow <= 1; offsetRow++)
  285. {
  286. if (row + offsetRow < 0 || row + offsetRow > 45)
  287. continue;
  288. for (char offsetCol = -1; offsetCol <= 1; offsetCol++)
  289. {
  290. if (col + offsetCol < 0 || col + offsetCol > 60)
  291. continue;
  292. byte tempPixel = binaryImage[row+offsetRow][col+offsetCol];
  293. if (tempPixel == 0 || tempPixel == 1 || tempPixel == blobIndex)
  294. {
  295. //Not a different blob
  296. }
  297. else
  298. {
  299. }}}}}}}
  300. void blobifyBinaryImage2()
  301. {
  302. byte blobId = 2;
  303. byte currentPixel;
  304. for (byte row = 0; row < IMAGE_ROWS; row++)
  305. {
  306. for (byte col = 0; col < IMAGE_COLS; col++)
  307. {
  308. currentPixel = binaryImage[row][col];
  309. if (currentPixel == 1)
  310. {
  311. recursivelyFloodPixelIdToAdjacentPixels(row, col, blobId);
  312. blobId++;
  313. }
  314. }
  315. }
  316. numberOfBlobs = blobId - 2;
  317. }
  318. void recursivelyFloodPixelIdToAdjacentPixels(byte row, byte col, byte blobId)
  319. {
  320. binaryImage[row][col] = blobId;
  321. for (char offsetRow = -1; offsetRow <= 1; offsetRow++)
  322. {
  323. if (row + offsetRow < 0 || row + offsetRow > IMAGE_ROWS)
  324. continue; //Prevents it from going outside the picture
  325. for (char offsetCol = -1; offsetCol <= 1; offsetCol++)
  326. {
  327. if (offsetRow == 0 && offsetCol == 0)
  328. continue;//It only checks adjacent pixels, not the one it is working with
  329. if (col + offsetCol < 0 || col + offsetCol > IMAGE_COLS)
  330. continue;//Prevents it from going outside the picture
  331. byte newPixel = binaryImage[row + offsetRow][col + offsetCol];
  332. if (newPixel == 1)
  333. recursivelyFloodPixelIdToAdjacentPixels(row+offsetRow, col+offsetCol, blobId);
  334. }
  335. }
  336. }
  337.  
  338. void removeBlobsSmallerThan(byte minBlobSize)
  339. {
  340. byte blobSizes[numberOfBlobs + 2];// The first two will not be true blobs, so they are safe to ignore
  341. for (byte i = 0; i < numberOfBlobs+2; i++)
  342. blobSizes[i] = 0;
  343. for (byte row = 0; row < IMAGE_ROWS; row++)
  344. for (byte col = 0; col < IMAGE_COLS; col++)
  345. blobSizes[ binaryImage[row][col] ] ++;// Counts the population of each blob, and puts it in blobSizes
  346. /*for (byte i = 0; i < numberOfBlobs+2; i++)
  347. {
  348. Serial.print(i);
  349. Serial.print(": ");
  350. Serial.println(blobSizes[i]);
  351. }*/
  352. if (blobSizes[1] != 0)
  353. {
  354. TV.print("Assertion failed! blobSizes[1] = ");
  355. TV.println((int)blobSizes[1]);
  356. }
  357. for (byte blobId = 2; blobId < numberOfBlobs + 2; blobId++)
  358. if (blobSizes[blobId] < minBlobSize)
  359. for (byte row = 0; row < IMAGE_ROWS; row++)
  360. for (byte col = 0; col < IMAGE_COLS; col++)
  361. if (binaryImage[row][col] == blobId)
  362. binaryImage[row][col] = 0;
  363. // Blobs are now inconsistently indexed
  364. }
  365.  
  366. void reorderBlobs()
  367. {
  368. for (byte row = 0; row < IMAGE_ROWS; row++)
  369. for (byte col = 0; col < IMAGE_COLS; col++)
  370. if (binaryImage[row][col])
  371. binaryImage[row][col] = 1;
  372. blobifyBinaryImage2();
  373. }
  374.  
  375. void convexHull(byte blobId)
  376. {
  377. char currentPixel[] = {-1, -1};
  378. }
  379.  
  380. void printNumberTo7Seg(byte num)
  381. {
  382. for (byte i = 0; i < 7; i++)
  383. digitalWrite(segs[i], segPatterns[num % 10][i]);
  384. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement