Robot Car Project

Hauptprojekt.ino.cpp 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. #include <Arduino.h>
  2. #line 1 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  3. #line 1 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  4. //Verfassser: Felix Stange, 4056379, MET2016
  5. //Datum: erstellt am 19.07.2017, zuletzt geändert am 13.04.2018
  6. //Projektbeschreibung: Der Zumo fährt automatisch zwischen 2 Linien ohne diese zu überfahren mithilfe
  7. //der Liniensensoren (3), ähnlich einer Spurhalteautomatik (heller Belag und dunkle Streifen).
  8. //Außerdem werden Kollisionen verhindert durch Nutzung der vorderen Abstandssensoren. Kommt es
  9. //dennoch zu einer Kollision, wird diese durch den Beschleunigungssensor (LSM303) erkannt.
  10. //Für den Überholvorgang werden die seitlichen Abstandssensoren und der Drehbewegungssensor (L3G)
  11. //genutzt. Mithilfe der Quadraturencoder in den Motoren können Wegstrecken vermessen werden.
  12. //Der Zumo kommuniziert über ein Bluetooth-Modul (HC-05) mit anderen Geräten. Die
  13. //Kommunikation erfolgt seriell ('SERIAL' für USB, 'SERIAL1' für Bluetooth).
  14. //Das LCD kann bei Bluetoothnutzung nicht verwendet werden.
  15. #include <Wire.h>
  16. #include <Zumo32U4.h>
  17. Zumo32U4ProximitySensors proxSensors; //Abstandssensoren
  18. Zumo32U4LineSensors lineSensors; //Liniensensoren
  19. Zumo32U4Motors motors; //Motoren
  20. Zumo32U4ButtonA buttonA; //Taste A
  21. Zumo32U4Encoders encoders; //Motorencoder
  22. LSM303 compass; //Beschleunigungssensor x-Achse
  23. L3G gyro; //Drehbewegungssensor z-Achse
  24. #define MARKLINE0 150
  25. #define MARKLINE1 100
  26. #define MARKLINE2 170
  27. #define SIGN0 400
  28. #define SIGN1 350
  29. #define SIGN2 450
  30. #define MAXSPEED 400
  31. #define FULLSPEEDLEFT 107
  32. #define HALFSPEEDLEFT 54
  33. #define SLOWSPEEDLEFT 27
  34. #define FULLSPEEDRIGHT 100
  35. #define HALFSPEEDRIGHT 50
  36. #define SLOWSPEEDRIGHT 25
  37. int16_t lineValue[3]; //Liniensensoren
  38. uint16_t lineOffset[3]; //von links (0) nach rechts (2)
  39. uint8_t proxValue[4]; //Abstandssensoren v.l. (0) n.r. (3)
  40. int16_t encoderCounts[2]; //Anzahl der Umdrehungen
  41. int16_t driveRotation[2]; //von links (0) nach rechts (1)
  42. int32_t rotationAngle = 0; //Drehwinkel
  43. int32_t turnAngle = 0;
  44. int16_t turnRate;
  45. int16_t gyroOffset;
  46. uint16_t gyroLastUpdate;
  47. //int32_t moveDisplay = 0; //Beschleunigung
  48. //int32_t moveDistance = 0;
  49. int16_t moveRate;
  50. int16_t compassOffset;
  51. //uint16_t compassLastUpdate;
  52. uint16_t lastUpdate = 0; //Systemzeit
  53. uint16_t eventTime = 0; //Zeit seit letzter Geschwindigkeitsänderung
  54. char report[200]; //Ausgabe
  55. float eventSpeed = 1; //vermindert die Geschwindigkeit bei Manövern
  56. int btData = 0; //Gelesene Daten aus Bluetooth
  57. bool alarm = false; //zeigt Manöver abhängig von btData
  58. /*-----------------------------------------------------------------*/
  59. //Setup Bluetoothverbindung
  60. #line 68 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  61. void BlueSetup();
  62. #line 76 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  63. void LineSetup();
  64. #line 105 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  65. void ProxSetup();
  66. #line 111 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  67. void GyroSetup();
  68. #line 144 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  69. void CompassSetup();
  70. #line 175 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  71. void setup();
  72. #line 201 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  73. void TimeUpdate();
  74. #line 207 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  75. void LoopTiming();
  76. #line 251 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  77. void ProxUpdate();
  78. #line 261 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  79. void LineUpdate();
  80. #line 271 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  81. void GyroUpdate();
  82. #line 284 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  83. void CompassUpdate();
  84. #line 297 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  85. void EncoderUpdate();
  86. #line 308 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  87. void Kontaktvermeiden();
  88. #line 328 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  89. void Hindernisumfahren();
  90. #line 438 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  91. void Abbiegen();
  92. #line 594 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  93. void Spurhalten();
  94. #line 642 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  95. void SerielleAusgabe();
  96. #line 657 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  97. void loop();
  98. #line 68 "c:\\Users\\Carolin\\Downloads\\VSCode\\Zumo32U4\\Zumo32U4\\Hauptprojekt\\Hauptprojekt.ino"
  99. void BlueSetup()
  100. {
  101. Serial1.begin(9600); //Initialisierung mit Datengeschwindigkeit(Baud)
  102. Serial1.setTimeout(10); //verkürzt Serial(1).read auf 10 ms statt 1000 ms
  103. if(Serial1.available()) Serial.println("Bluetoothverbindung hergestellt");
  104. }
  105. //Setup Liniensensoren
  106. void LineSetup()
  107. {
  108. ledYellow(1);
  109. lineSensors.initThreeSensors(); //Initialisierung von 3 Sensoren (max 5)
  110. // //Kalibrierung
  111. // uint32_t total[3] = {0, 0, 0};
  112. // for(uint8_t i = 0; i < 120; i++)
  113. // {
  114. // if (i > 30 && i <= 90) motors.setSpeeds(FULLSPEEDLEFT, -FULLSPEEDRIGHT);
  115. // else motors.setSpeeds(-FULLSPEEDLEFT, FULLSPEEDRIGHT);
  116. // lineSensors.read(lineOffset);
  117. // total[0] += lineOffset[0];
  118. // total[1] += lineOffset[1];
  119. // total[2] += lineOffset[2];
  120. lineSensors.calibrate();
  121. // }
  122. // motors.setSpeeds(0, 0);
  123. // lineOffset[0] = total[0] / 120;
  124. // lineOffset[1] = total[1] / 120;
  125. // lineOffset[2] = total[2] / 120;
  126. ledYellow(0);
  127. lineOffset[0] = 240;
  128. lineOffset[1] = 120;
  129. lineOffset[2] = 220;
  130. }
  131. //Setup Abstandssensoren
  132. void ProxSetup()
  133. {
  134. proxSensors.initThreeSensors();
  135. }
  136. //Setup Drehbewegungssensor
  137. void GyroSetup()
  138. {
  139. ledYellow(1);
  140. gyro.init(); //Initialisierung
  141. if(!gyro.init()) //Fehlerabfrage
  142. {
  143. //Fehler beim Initialisieren des Drehbewegungssensors
  144. ledRed(1);
  145. while(1)
  146. {
  147. //Serial1.println("Fehler Drehbewegungssensors");
  148. delay(1000);
  149. }
  150. }
  151. gyro.writeReg(L3G::CTRL1, 0b11111111); //Ausgaberate 800Hz, Tiefpassfilter 100Hz
  152. gyro.writeReg(L3G::CTRL4, 0b00100000); //2000dps Auflösung
  153. gyro.writeReg(L3G::CTRL5, 0b00000000); //Hochpassfilter ausgeschaltet
  154. //Kalibrierung
  155. int32_t total = 0;
  156. for(uint16_t i = 0; i < 1024; i++)
  157. {
  158. while(!gyro.readReg(L3G::STATUS_REG) & 0x08); //Fehlerabfrage
  159. gyro.read();
  160. total += gyro.g.z;
  161. }
  162. gyroOffset = total / 1024;
  163. gyroLastUpdate = micros();
  164. ledYellow(0);
  165. }
  166. //Setup Beschleunigungssensor
  167. void CompassSetup()
  168. {
  169. ledYellow(1);
  170. compass.init(); //Initialisierung
  171. if(!compass.init()) //Fehlerabfrage
  172. {
  173. //Fehler beim Initialisieren des Beschleunigungssensors
  174. ledRed(1);
  175. while(1)
  176. {
  177. //Serial1.println("Fehler Beschleunigungssensors");
  178. delay(1000);
  179. }
  180. }
  181. compass.enableDefault();
  182. //Kalibrierung
  183. int32_t total = 0;
  184. for (uint16_t i = 0; i < 1024; i++)
  185. {
  186. compass.read();
  187. total += compass.a.x;
  188. }
  189. compassOffset = total / 1024;
  190. //compassLastUpdate = micros();
  191. ledYellow(0);
  192. }
  193. /*-----------------------------------------------------------------*/
  194. void setup()
  195. {
  196. //Initialisierung der Bluetoothverbindung
  197. BlueSetup();
  198. //Initialisierung und Kalibrierung der Sensoren
  199. //Serial1.println("Sensorkalibrierung");
  200. Wire.begin();
  201. delay(500);
  202. ProxSetup();
  203. LineSetup();
  204. GyroSetup();
  205. CompassSetup();
  206. //Zumo bereit zu starten
  207. //Serial1.println("Zumo bereit, starte mit A");
  208. ledGreen(1);
  209. buttonA.waitForButton();
  210. randomSeed(millis());
  211. delay(500);
  212. //Serial1.println("Start");
  213. }
  214. /*-----------------------------------------------------------------*/
  215. //Update Durchlaufzeit
  216. void TimeUpdate()
  217. {
  218. uint16_t m = millis();
  219. eventTime = m - lastUpdate;
  220. }
  221. void LoopTiming()
  222. {
  223. const int AL = 100; // Arraylänge, NUR GERADE Zahlen verwenden!
  224. static unsigned long LoopTime[AL];
  225. static unsigned int Index=0, Messung=0, Min=0xFFFF, Max, Avg;
  226. if (Messung % 2 == 0) // wenn Messung X gerade (0,2,4,6 usw.), entspricht immer Anfang der Loop
  227. {
  228. LoopTime[Index] = millis();
  229. Messung++;
  230. Index++;
  231. return; // Funktion sofort beenden, spart etwas Zeit
  232. }
  233. if (Messung % 2 == 1) // wenn Messung X ungerade (1,3,5,7 usw.), entspricht immer Ende der Loop
  234. {
  235. LoopTime[Index] = millis();
  236. LoopTime[Index-1] = LoopTime[Index] - LoopTime[Index-1]; // Loopdauer einen Index niedriger einspeichern wie aktuell
  237. Messung++;
  238. }
  239. if (Index >= AL) // Array voll, Daten auswerten
  240. {
  241. for (int i = 0; i<AL; i++)
  242. {
  243. Min = min(Min, LoopTime[i]);
  244. Max = max(Max, LoopTime[i]);
  245. Avg += LoopTime[i];
  246. }
  247. Avg = Avg / AL;
  248. Serial1.print(F("Minimal "));Serial1.print(Min);Serial1.println(" ms ");
  249. Serial1.print(F("Durchschnitt "));Serial1.print(Avg);Serial1.println(" ms ");
  250. Serial1.print(F("Maximal "));Serial1.print(Max);Serial1.println(" ms ");
  251. SerielleAusgabe();
  252. Min = 0xFFFF;
  253. Max = 0;
  254. Avg = 0;
  255. Messung = 0;
  256. Index = 0;
  257. }
  258. }
  259. //Update Abstandssensoren
  260. void ProxUpdate()
  261. {
  262. proxSensors.read();
  263. proxValue[0] = proxSensors.countsLeftWithLeftLeds();
  264. proxValue[1] = proxSensors.countsFrontWithLeftLeds();
  265. proxValue[2] = proxSensors.countsFrontWithRightLeds();
  266. proxValue[3] = proxSensors.countsRightWithRightLeds();
  267. }
  268. //Update Liniensensoren
  269. void LineUpdate()
  270. {
  271. uint16_t lineRaw[3];
  272. lineSensors.read(lineRaw);
  273. lineValue[0] = lineRaw[0] - lineOffset[0];
  274. lineValue[1] = lineRaw[1] - lineOffset[1];
  275. lineValue[2] = lineRaw[2] - lineOffset[2];
  276. }
  277. //Update Drehbewegungssensor
  278. void GyroUpdate()
  279. {
  280. gyro.read(); //Rohwert 10285 entspricht 90° bzw.
  281. turnRate = gyro.g.z - gyroOffset; //8,75mdps/LSB
  282. uint16_t m = micros();
  283. uint16_t dt = m - gyroLastUpdate;
  284. gyroLastUpdate = m;
  285. int32_t d = (int32_t)turnRate * dt;
  286. turnAngle += (int64_t)d * 14680064 / 17578125;
  287. rotationAngle = (((int32_t)turnAngle >> 16) * 360) >> 16;
  288. }
  289. //Update Beschleunigungssensor
  290. void CompassUpdate()
  291. {
  292. compass.read(); //Rohwert 16384 entspricht 1g (9,81m/s²) bzw.
  293. moveRate = compass.a.x - compassOffset; //bei +/-2g Messbereich 0,61mg/LSB
  294. // uint16_t m = micros();
  295. // uint16_t dt = m - compassLastUpdate;
  296. // compassLastUpdate = m;
  297. // int32_t d = (int32_t)moveRate * dt;
  298. // moveDistance += (int64_t)d * dt >> 14;
  299. // moveDisplay = moveDistance * 9,81 / 1000;
  300. }
  301. //Update Encoder
  302. void EncoderUpdate()
  303. {
  304. encoderCounts[0] = encoders.getCountsLeft();
  305. driveRotation[0] = encoderCounts[0] / 910; //12cpr (Motorwelle) * 75,81:1 (Getriebe) = 909,7cpr (Antriebszahnrad)
  306. encoderCounts[1] = encoders.getCountsRight();
  307. driveRotation[1] = encoderCounts[1] / 910;
  308. }
  309. /*-----------------------------------------------------------------*/
  310. //Funktion Kontaktvermeiden
  311. void Kontaktvermeiden()
  312. {
  313. //Serial1.println("Kontaktvermeiden");
  314. Serial1.println(1);
  315. ledRed(1);
  316. motors.setSpeeds(0, 0);
  317. delay(500);
  318. while(proxValue[1] == 0 || proxValue[2] == 0)
  319. {
  320. ProxUpdate();
  321. motors.setSpeeds(-HALFSPEEDLEFT, -HALFSPEEDRIGHT);
  322. if(lineValue[0] > MARKLINE0 || lineValue[2] > MARKLINE2) break;
  323. }
  324. delay(500);
  325. //Serial1.println("Vermeiden beendet");
  326. Serial1.println(0);
  327. }
  328. //Funktion Hindernisumfahrung
  329. void Hindernisumfahren()
  330. {
  331. //Serial1.println("Hindernisumfahren");
  332. Serial1.println(1);
  333. ledYellow(1);
  334. //Schritt 1: Spurwechsel links
  335. //links drehen
  336. turnAngle = 0;
  337. rotationAngle = 0;
  338. GyroUpdate();
  339. while(rotationAngle < 45)
  340. {
  341. GyroUpdate();
  342. LineUpdate();
  343. motors.setSpeeds(SLOWSPEEDLEFT, FULLSPEEDRIGHT);
  344. if(lineValue[2] > MARKLINE2 && lineValue[2] < SIGN2) break;
  345. }
  346. //geradeaus über Mittellinie fahren
  347. LineUpdate();
  348. while(lineValue[2] < MARKLINE2)
  349. {
  350. LineUpdate();
  351. motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT);
  352. //if(lineValue[0] > MARKLINE0) break;
  353. }
  354. //rechts drehen
  355. GyroUpdate();
  356. while(rotationAngle > 10)
  357. {
  358. GyroUpdate();
  359. LineUpdate();
  360. if(lineValue[0] > MARKLINE0 && lineValue[0] < SIGN0) motors.setSpeeds(FULLSPEEDLEFT, 0);
  361. else if(lineValue[2] > MARKLINE2 && lineValue[2] < SIGN2) motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT);
  362. else motors.setSpeeds(FULLSPEEDLEFT, SLOWSPEEDRIGHT);
  363. }
  364. //geradeaus fahren
  365. motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT);
  366. //Gegenverkehr beachten
  367. ProxUpdate();
  368. //if(proxValue[1] < 5 || proxValue[2] < 5)
  369. //{
  370. //Schritt 2: Hindernis passieren
  371. //Serial1.println("Aufholen");
  372. lastUpdate = millis();
  373. while(proxValue[3] < 6 && eventTime < 3000)
  374. {
  375. TimeUpdate();
  376. ProxUpdate();
  377. LineUpdate();
  378. Spurhalten();
  379. }
  380. //Serial1.println("Überholen");
  381. ProxUpdate();
  382. while(proxValue[3] == 6)
  383. {
  384. ProxUpdate();
  385. LineUpdate();
  386. Spurhalten();
  387. }
  388. //Serial1.println("Abstand gewinnen");
  389. lastUpdate = millis();
  390. TimeUpdate();
  391. while(eventTime < 3000)
  392. {
  393. //Serial1.println(eventTime);
  394. TimeUpdate();
  395. LineUpdate();
  396. Spurhalten();
  397. }
  398. //}
  399. //Schritt 3: Spurwechsel rechts
  400. //rechts drehen
  401. turnAngle = 0;
  402. rotationAngle = 0;
  403. GyroUpdate();
  404. while(rotationAngle > -45)
  405. {
  406. GyroUpdate();
  407. LineUpdate();
  408. motors.setSpeeds(FULLSPEEDLEFT, SLOWSPEEDRIGHT);
  409. if(lineValue[0] > MARKLINE0 && lineValue[0] < SIGN0) break;
  410. }
  411. //geradeaus über Mittellinie fahren
  412. LineUpdate();
  413. while(lineValue[0] < MARKLINE0)
  414. {
  415. LineUpdate();
  416. motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT);
  417. //if(lineValue[0] > MARKLINE0) break;
  418. }
  419. //links drehen
  420. GyroUpdate();
  421. while(rotationAngle < -10)
  422. {
  423. GyroUpdate();
  424. LineUpdate();
  425. if(lineValue[2] > MARKLINE2 && lineValue[2] < SIGN2) motors.setSpeeds(0, FULLSPEEDRIGHT);
  426. else if(lineValue[0] > MARKLINE0 && lineValue[0] < SIGN0) motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT);
  427. else motors.setSpeeds(SLOWSPEEDLEFT, FULLSPEEDRIGHT);
  428. }
  429. //geradeaus fahren
  430. //Serial1.println("Umfahren beendet");
  431. Serial1.println(0);
  432. motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT);
  433. }
  434. //Funktion Abbiegen
  435. void Abbiegen()
  436. {
  437. ledYellow(1);
  438. //Serial1.println("Abbiegen");
  439. Serial1.println(1);
  440. //Markierung analysieren
  441. LineUpdate();
  442. bool leftCode; //links => 1
  443. bool rightCode; //rechts => 2
  444. if(lineValue[0] > SIGN0) leftCode = true;
  445. else leftCode = false;
  446. if(lineValue[2] > SIGN2) rightCode = true;
  447. else rightCode = false;
  448. //Zufallszahl erzeugen
  449. uint8_t randy; //geradeaus => 0
  450. if(leftCode == true && rightCode == true) randy = random(1, 3); //1, 2
  451. else if(leftCode == true && rightCode == false) randy = 1;
  452. // else if(leftCode == true && rightCode == false)
  453. // {
  454. // randy = random(0, 2); //0, 1
  455. // if(randy == 0) randy = random(0, 2); //erhöht Wahrscheinlickeit abzubiegen
  456. // }
  457. else if(leftCode == false && rightCode == true) randy = 2;
  458. // else if(leftCode == false && rightCode == true)
  459. // {
  460. // randy = random(3); //0, (1), 2
  461. // if(randy == 0) randy = random(3); //erhöht Wahrscheinlickeit abzubiegen
  462. // while(randy == 1) randy = random(3); //!1 => 0, 2
  463. // }
  464. //links Abbiegen (von der Verbindungsstrecke)
  465. if(randy == 1 && rightCode == true)
  466. {
  467. //Serial1.println("links Abbiegen von der Verbindungsstrecke");
  468. //geradeaus zur Mittellinie fahren
  469. motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT+10);
  470. lastUpdate = millis();
  471. TimeUpdate();
  472. while(eventTime < 300)
  473. {
  474. TimeUpdate();
  475. //Serial1.println(eventTime);
  476. motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT+10);
  477. }
  478. LineUpdate();
  479. //Serial1.println("Linie suchen");
  480. while(lineValue[0] < MARKLINE0 && lineValue[2] < MARKLINE2)
  481. {
  482. LineUpdate();
  483. motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT);
  484. }
  485. //links drehen
  486. turnAngle = 0;
  487. rotationAngle = 0;
  488. GyroUpdate();
  489. //Serial1.println("Drehen");
  490. while(rotationAngle < 90)
  491. {
  492. GyroUpdate();
  493. LineUpdate();
  494. if(lineValue[2] > MARKLINE2 && lineValue[2] < SIGN2) motors.setSpeeds(0, FULLSPEEDRIGHT);
  495. else if(lineValue[0] > MARKLINE0 && lineValue[0] < SIGN0) motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT);
  496. else motors.setSpeeds(SLOWSPEEDLEFT, FULLSPEEDRIGHT);
  497. }
  498. //geradeaus fahren
  499. motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT);
  500. }
  501. //links Abbiegen (vom Rundkurs)
  502. else if(randy == 1 && leftCode == true)
  503. {
  504. //Serial1.println("links Abbiegen vom Rundkurs");
  505. //links drehen
  506. turnAngle = 0;
  507. rotationAngle = 0;
  508. driveRotation[1] = 0;
  509. GyroUpdate();
  510. while(rotationAngle < 40)
  511. {
  512. GyroUpdate();
  513. EncoderUpdate();
  514. motors.setSpeeds(SLOWSPEEDLEFT, FULLSPEEDRIGHT);
  515. if(driveRotation[1] > 1) break;
  516. }
  517. driveRotation[1] = 0;
  518. GyroUpdate();
  519. while(rotationAngle < 85)
  520. {
  521. GyroUpdate();
  522. EncoderUpdate();
  523. motors.setSpeeds(SLOWSPEEDLEFT, FULLSPEEDRIGHT);
  524. if(driveRotation[1] > 1) break;
  525. }
  526. //geradeaus fahren
  527. motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT);
  528. lastUpdate = millis();
  529. TimeUpdate();
  530. while(eventTime < 1000)
  531. {
  532. TimeUpdate();
  533. LineUpdate();
  534. if(lineValue[2] > MARKLINE2 && lineValue[2] < SIGN2) break;
  535. }
  536. }
  537. //rechts Abbiegen
  538. else if(randy == 2 && rightCode == true)
  539. {
  540. //rechts drehen
  541. turnAngle = 0;
  542. rotationAngle = 0;
  543. driveRotation[0] = 0;
  544. GyroUpdate();
  545. while(rotationAngle > -40)
  546. {
  547. GyroUpdate();
  548. EncoderUpdate();
  549. LineUpdate();
  550. motors.setSpeeds(FULLSPEEDLEFT, SLOWSPEEDRIGHT);
  551. if(driveRotation[0] > 1 || (lineValue[0] > MARKLINE0 && lineValue[0] < SIGN0)) break;
  552. }
  553. GyroUpdate();
  554. lastUpdate = millis();
  555. while(rotationAngle > -85)
  556. {
  557. TimeUpdate();
  558. GyroUpdate();
  559. LineUpdate();
  560. if(eventTime > 3000) break;
  561. if(lineValue[0] > MARKLINE0 && lineValue[0] < SIGN0) motors.setSpeeds(FULLSPEEDLEFT, 0);
  562. //else if(lineValue[1] > MARKLINE1 && lineValue[1] < SIGN1) motors.setSpeeds(-SLOWSPEEDLEFT, -SLOWSPEEDRIGHT);
  563. else if(lineValue[2] > MARKLINE2 && lineValue[2] < SIGN2) motors.setSpeeds(FULLSPEEDLEFT, HALFSPEEDRIGHT);
  564. else motors.setSpeeds(FULLSPEEDLEFT, SLOWSPEEDRIGHT);
  565. }
  566. }
  567. //nicht Abbiegen, geradeaus fahren
  568. else
  569. {
  570. motors.setSpeeds(FULLSPEEDLEFT, FULLSPEEDRIGHT);
  571. lastUpdate = millis();
  572. TimeUpdate();
  573. while(eventTime < 1000)
  574. {
  575. TimeUpdate();
  576. LineUpdate();
  577. Spurhalten();
  578. }
  579. }
  580. //Serial1.println("Abbiegen beendet");
  581. Serial1.println(0);
  582. }
  583. //Funktion Spurhalten
  584. void Spurhalten()
  585. {
  586. //linke Linie erreicht, nach rechts fahren
  587. if(lineValue[0] > MARKLINE0 && lineValue[0] < SIGN0)
  588. {
  589. ledYellow(1);
  590. //Serial1.println("Spur nach rechts korrigieren");
  591. motors.setSpeeds(FULLSPEEDLEFT/eventSpeed, SLOWSPEEDRIGHT/eventSpeed);
  592. delay(100);
  593. }
  594. //rechte Linie erreicht, nach links fahren
  595. else if(lineValue[2] > MARKLINE2 && lineValue[2] < SIGN2)
  596. {
  597. ledYellow(1);
  598. //Serial1.println("Spur nach links korrigieren");
  599. motors.setSpeeds(SLOWSPEEDLEFT/eventSpeed, FULLSPEEDRIGHT/eventSpeed);
  600. delay(100);
  601. }
  602. //Linie überfahren, zurücksetzen
  603. else if(lineValue[1] > MARKLINE1 && lineValue[1] < SIGN1)
  604. {
  605. ledRed(1);
  606. //Serial1.println("Spurfinden");
  607. Serial1.println(1);
  608. lastUpdate = millis();
  609. while(lineValue[0] < MARKLINE0 && lineValue[2] < MARKLINE2) //Zumo fährt solange rückwärst bis er wieder auf der Spur steht
  610. {
  611. TimeUpdate();
  612. LineUpdate();
  613. motors.setSpeeds(-FULLSPEEDLEFT/eventSpeed, -FULLSPEEDRIGHT/eventSpeed);
  614. if(eventTime > 3000) break;
  615. }
  616. delay(100);
  617. //Serial1.println("Spur gefunden");
  618. Serial1.println(0);
  619. }
  620. //normale Fahrt
  621. else
  622. {
  623. ledGreen(1);
  624. motors.setSpeeds(FULLSPEEDLEFT/eventSpeed, FULLSPEEDRIGHT/eventSpeed);
  625. }
  626. }
  627. //Funktion Serielle Ausgabe
  628. void SerielleAusgabe()
  629. {
  630. snprintf_P(report, sizeof(report),
  631. PSTR("Abstand: %d %d %d %d Linie: %d %d %d"),
  632. proxValue[0], proxValue[1], proxValue[2], proxValue[3],
  633. lineValue[0], lineValue[1], lineValue[2]);
  634. Serial1.println(report);
  635. snprintf_P(report, sizeof(report),
  636. PSTR("Weg: %d %d Winkel: %d Beschleunigung: %d"),
  637. driveRotation[0], driveRotation[1], rotationAngle, moveRate);
  638. Serial1.println(report);
  639. }
  640. /*-----------------------------------------------------------------*/
  641. void loop()
  642. {
  643. //LoopTiming(); //Zykluszeit beträgt max. 30ms im Idle
  644. ledGreen(0);
  645. ledYellow(0);
  646. ledRed(0);
  647. //Abfragen der Sensordaten
  648. LineUpdate();
  649. ProxUpdate();
  650. EncoderUpdate();
  651. GyroUpdate();
  652. CompassUpdate();
  653. TimeUpdate();
  654. //Funktionsauswahl
  655. //btData = Serial1.readString();
  656. if(Serial1.available() > 0) btData = Serial1.read();
  657. if(btData == '1') alarm = true;
  658. else if(btData == '0') alarm = false;
  659. //verfügbare Funktionen bei laufenden Manövern
  660. //if(btData == "Abbiegen" || btData == "Hindernisumfahren" || btData == "Kontaktvermeiden"|| btData == "Spurfinden")
  661. if(alarm == true)
  662. {
  663. //Serial1.println("Verstanden");
  664. eventSpeed = 2;
  665. if(moveRate > 1000 || proxValue[1] == 6 || proxValue[2] == 6 || lineValue[0] > SIGN0 || lineValue[2] > SIGN2) motors.setSpeeds(0, 0);
  666. else Spurhalten();
  667. }
  668. //verfügbare Funktionen im Normalfall
  669. else
  670. {
  671. eventSpeed = 1;
  672. //if(abs(moveRate) > 1500 && eventTime > 1000) Kontaktvermeiden();
  673. if(proxValue[2] == 6) Hindernisumfahren();
  674. else if(lineValue[0] > SIGN0 && lineValue[0] < 1000 || lineValue[2] > SIGN2 && lineValue[2] < 1000) Abbiegen();
  675. else Spurhalten();
  676. }
  677. //LoopTiming();
  678. }