ctags_target_for_gcc_minus_e.cpp 22 KB

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