Advertisement
Guest User

Untitled

a guest
Jan 14th, 2019
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.20 KB | None | 0 0
  1. #include <SPI.h>
  2. #include <SD.h>
  3.  
  4. #include <AFMotor.h>
  5. //#include <NewPing.h>
  6. #include "SR04.h"
  7. #include "TimerOne.h"
  8. #include <IRremote.h>
  9.  
  10. //Ustawienia karty SD
  11. File myFile;
  12. const int8_t DISABLE_CHIP_SELECT = 10;
  13.  
  14. int pinCS = 53; // Pin komunikacji z karta SD
  15.  
  16. //Ustawienie timera
  17. unsigned long startTime;
  18. unsigned long followWallTime;
  19. unsigned long followWall_frontTime;
  20.  
  21. //Ustawienie predkosciomierza
  22. const byte motor_A = 20; //Motor1 pin przerwania
  23. const byte motor_B = 21; //Motor2 pin przerwania
  24.  
  25. volatile int counter_A = 0; //zmienne do licznika pulsow
  26. volatile int counter_B = 0;
  27.  
  28. float diskslots = 20.00; // liczba otworow w dysku enkoderow
  29.  
  30. const float wheeldiameter = 65.10; // srednica kola w milimetrach
  31.  
  32. //Ustawienie sensorow
  33. int LEFT_SENSOR_TRIG = A2;
  34. int LEFT_SENSOR_ECHO = A3;
  35. int FRONT_SENSOR_TRIG = A0;
  36. int FRONT_SENSOR_ECHO = A1;
  37.  
  38. SR04 sr04_left = SR04(LEFT_SENSOR_ECHO, LEFT_SENSOR_TRIG);
  39. SR04 sr04_front = SR04(FRONT_SENSOR_ECHO, FRONT_SENSOR_TRIG);
  40.  
  41. //Ustawienie pilota
  42. int RECV_PIN = 22;
  43.  
  44. IRrecv irrecv(RECV_PIN);
  45. decode_results results;
  46.  
  47. //Ustawienie silnikow
  48. AF_DCMotor motor1(1, MOTOR12_1KHZ);
  49. AF_DCMotor motor2(3, MOTOR34_1KHZ);
  50.  
  51. int NO_OBSTACLE = 0;
  52. int OBSTACLE = 1;
  53.  
  54. //Zmienne PID
  55. const float Kp_wall = 16; // stala uzyta do skretu
  56. const float Ki_wall = 0.003; // stala calki uzyta do poprawy bledu
  57. const float Kd_wall = 11; // stala rozniczki uzyta do poprawy predkosci poprawy bledu
  58.  
  59. const float Kp_front = 30; // stala uzyta do skretu
  60. const float Ki_front = 0; // stala calki uzyta do poprawy bledu
  61. const float Kd_front = 15; // stala rozniczki uzyta do poprawy predkosci poprawy bledu
  62.  
  63. const int offset = 12; // docelowa odleglosc
  64. const int max_front_distance = 16; // maksymalna odleglosc z przodu
  65.  
  66. int Tp = 128; // docelowa predkosc - target power
  67.  
  68. float error_wall = 0;
  69. float lastError_wall = 0;
  70. int correction_wall = 0;
  71. float p_wall = 0; //proporcja
  72. float i_wall = 0; //calka
  73. float d_wall = 0; //rozniczka
  74.  
  75. int Wall = 0;
  76. int Front = 0;
  77.  
  78. float error_front = 0;
  79. float lastError_front = 0;
  80. float correction_front = 0;
  81. float p_front = 0; //proporcja
  82. float i_front = 0; //calka
  83. float d_front = 0; //rozniczka
  84.  
  85. int leftMotorSpeed = 0;
  86. int rightMotorSpeed = 0;
  87.  
  88. int front_status = 0;
  89.  
  90. //int rangeFrontObstacle = 0;
  91. //int rangeWallObstacle = 0;
  92. //int rangeFront = 0;
  93. //int rangeWall = 0;
  94. //int speedSet = 0;
  95.  
  96. //0 - true; 1 - false
  97. int rightTurnBegin = 0;
  98. int leftTurnBegin = 0;
  99. int straightLineBegin = 0;
  100.  
  101. int speedSet = 0;
  102.  
  103.  
  104.  
  105. void setup() {
  106. // Ustawienie pilota
  107. pinMode(RECV_PIN, INPUT);
  108. irrecv.enableIRIn();
  109.  
  110. Serial.begin(9600);
  111.  
  112. //Ustawienie czytnika kart SD
  113. pinMode(53, OUTPUT);
  114. delay(5000);
  115.  
  116. //Ustawienie timera
  117. Timer1.initialize(1000000); // ustawienie timera na sekunde
  118. //zwieksz counter1 gdy pin predkosciomieza jest na Hig
  119. attachInterrupt(digitalPinToInterrupt (motor_A), ISR_count_A, RISING);
  120. //zwieksz counter2 gdy pin predkosciomieza jest na High
  121. attachInterrupt(digitalPinToInterrupt (motor_B), ISR_count_B, RISING);
  122. Timer1.attachInterrupt(ISR_timerone);
  123.  
  124. if (SD.begin(SS))
  125. {
  126. Serial.println("SD card is ready to use.");
  127. } else
  128. {
  129. Serial.println("SD card initialization failed");
  130. return;
  131. }
  132.  
  133. myFile = SD.open("DaneMapy.txt", FILE_WRITE);
  134.  
  135. if(myFile){
  136. myFile.print("Lewy silnik cm/s, Prawy silnik cm/s");
  137. }
  138. myFile.close();
  139. }
  140.  
  141. void loop() {
  142.  
  143. // put your main code here, to run repeatedly:
  144. beginning:
  145.  
  146. if (irrecv.decode(&results))
  147. {
  148. switch (results.value)
  149. {
  150. case 0xFF22DD: //vol-
  151. Serial.print("falling back");
  152. fall_back();
  153. break;
  154.  
  155. case 0xFF02FD: //vol+
  156. drive_forward();
  157. break;
  158.  
  159. case 0xFFC23D: //play/pause
  160. motor_stop();
  161. break;
  162. }
  163. irrecv.resume();
  164. }
  165. //sprawdzam czy jest przeszkoda z przodu
  166. front_status = GET_FRONT_STATUS();
  167.  
  168. if (front_status == OBSTACLE) {
  169.  
  170. if (leftTurnBegin == 0) {
  171. zero_wall();
  172. }
  173. followWall_front();
  174.  
  175. // Zmieniam flage skretu na false do nastepnego czasu az natrafi na przeszkode
  176. rightTurnBegin = 1;
  177. straightLineBegin = 0;
  178.  
  179. goto beginning;
  180. }
  181.  
  182. followWall();
  183.  
  184. }
  185.  
  186. void followWall() {
  187. //Kiedy robot zaczyna jechac prosto (dopoki nie ma przeszkody) zmieniam flage na true
  188. rightTurnBegin = 0;
  189.  
  190. Wall = sr04_left.Distance();
  191. error_wall = Wall - offset;
  192. i_wall = (i_wall + error_wall);
  193. d_wall = (error_wall - lastError_wall);
  194.  
  195. correction_wall = Kp_wall * error_wall + Ki_wall * i_wall + Kd_wall * d_wall;
  196.  
  197. //jezeli error_wall jest mniejszy od 10, oznacza to ze robot jedzie obok sciany poprawnie
  198. if (error_wall < 10) {
  199.  
  200. if (straightLineBegin == 0) {
  201. zero_wall();
  202. }
  203.  
  204. if (correction_wall > 127 && correction_wall > 0) {
  205. correction_wall = 127;
  206. }
  207.  
  208. if (correction_wall < -127 && correction_wall < 0) {
  209. correction_wall = -127;
  210. }
  211.  
  212. rightMotorSpeed = Tp + correction_wall;
  213. leftMotorSpeed = Tp - correction_wall;
  214.  
  215. leftTurnBegin = 0;
  216. straightLineBegin = 1;
  217. } else {
  218.  
  219. //jezeli error_wall jest wiekszy od 10, oznacza to ze robot musi skrecic w prawo
  220.  
  221. //zeruje wartosci na poczatku skretu w lewo
  222. if (leftTurnBegin == 0) {
  223. zero_wall();
  224. zero_front();
  225. }
  226.  
  227. //PID do skretu w lewo
  228. int speed = 2.5 * error_wall + 8 * d_wall;
  229.  
  230. if (speed > 127 && speed > 0) {
  231. speed = 127;
  232. }
  233.  
  234. if (speed < -127 && speed < 0) {
  235. speed = -127;
  236. }
  237.  
  238. rightMotorSpeed = Tp + (speed);
  239. leftMotorSpeed = Tp - (speed);
  240.  
  241. leftTurnBegin = 1;
  242. straightLineBegin = 0;
  243. }
  244.  
  245. motor1.setSpeed(rightMotorSpeed);
  246. motor1.run(FORWARD);
  247. motor2.setSpeed(leftMotorSpeed);
  248. motor2.run(FORWARD);
  249.  
  250. lastError_wall = error_wall;
  251. zero_front();
  252. }
  253.  
  254. void zero_wall(void) {
  255. i_wall = 0;
  256. d_wall = 0;
  257. lastError_wall = 0;
  258. }
  259.  
  260. void zero_front(void) {
  261. i_front = 0;
  262. d_front = 0;
  263. lastError_front = 0;
  264. }
  265.  
  266. void followWall_front()
  267. {
  268. //tu umiec zczytywanie z sensora
  269. Front = sr04_front.Distance();
  270. error_front = (Front - max_front_distance);
  271. i_front = (i_front + error_front);
  272. d_front = (error_front - lastError_front);
  273.  
  274. correction_front = Kp_front * error_front + Ki_front * i_front + Kd_front * d_front;
  275.  
  276.  
  277. if (correction_front > 160 && correction_front > 0) {
  278. correction_front = 160;
  279. }
  280.  
  281. if (correction_front < -160 && correction_front < 0) {
  282. correction_front = -160;
  283. }
  284.  
  285. rightMotorSpeed = 95 + correction_front;
  286. leftMotorSpeed = 95 - correction_front;
  287.  
  288. motor1.setSpeed(rightMotorSpeed);
  289. motor1.run(FORWARD);
  290. motor2.setSpeed(leftMotorSpeed);
  291. motor2.run(FORWARD);
  292.  
  293. lastError_front = error_front;
  294. }
  295.  
  296. void drive_forward() {
  297. motor1.setSpeed(128);
  298. motor2.setSpeed(128);
  299. motor1.run(FORWARD);
  300. motor2.run(FORWARD);
  301. delay(400);
  302. }
  303. //zatrzymuje robota na 5 sekund
  304. void motor_stop() {
  305. motor1.run(RELEASE);
  306. motor2.run(RELEASE);
  307. delay(5000);
  308. }
  309.  
  310. //wycofanie gdy robot wjedzie w przeszkode
  311. void fall_back() {
  312. motor1.setSpeed(128);
  313. motor2.setSpeed(128);
  314. motor1.run(BACKWARD);
  315. motor2.run(BACKWARD);
  316. delay(500);
  317. motor1.run(BACKWARD);
  318. motor2.run(FORWARD);
  319. delay(400);
  320. Serial.print("falling back");
  321. Serial.println();
  322. }
  323.  
  324. //funkcja konwertujaca centymetry na kroki
  325. int RMPtoCmS(float RPM){
  326. int result;
  327. float radius = (wheeldiameter / 2);
  328. float metersPerSecond = (radius * 0.001) * RPM * 0.10472; //obliczenie predkosci m/s
  329. float cmPerSec = metersPerSecond * 100; //przeliczanie m/s na cm/s
  330.  
  331. float f_result = cmPerSec;
  332. result = (int) f_result; //rzutowanie wyniku float na int, NIE ZAOKRAGLONE
  333.  
  334. return result;
  335. }
  336.  
  337. //obsluga przerwan (Interupt Service Routines ISR)
  338. // zliczanie pulsow motor1
  339. void ISR_count_A(){
  340. counter_A++;
  341. }
  342.  
  343. //zliczanie pulsow motor2
  344. void ISR_count_B(){
  345. counter_B++;
  346. }
  347.  
  348. //TimerOne ISR - timer przerwania
  349. void ISR_timerone(){
  350. Timer1.detachInterrupt(); //Stop timera
  351.  
  352. Serial.print("Motor1 Speed: ");
  353. float rotation_A = (counter_A / diskslots) * 60.00; //obliczenie obrotow na minute (RPM) dla motor1
  354. Serial.print(RMPtoCmS(rotation_A));
  355. Serial.print(" Cm/s - ");
  356. counter_A = 0;
  357.  
  358. Serial.print("Motor2 Speed: ");
  359. float rotation_B = (counter_B / diskslots) * 60.00; //obliczenie obrotow na minute (RPM) dla motor2
  360. Serial.print(RMPtoCmS(rotation_B));
  361. Serial.println(" Cm/s");
  362. counter_B = 0;
  363.  
  364. float srednia_predkosc = (RMPtoCmS(rotation_A) + RMPtoCmS(rotation_B)) /2;
  365.  
  366. myFile = SD.open("DaneMapy.txt", FILE_WRITE);
  367. if (myFile) {
  368. Serial.println("Writing to file...");
  369. myFile.print("Motor1: ");
  370. myFile.print(RMPtoCmS(rotation_A));
  371. myFile.print("Motor2: ");
  372. myFile.print(RMPtoCmS(rotation_B));
  373. myFile.print(" Średnia prędkość: ");
  374. myFile.print(srednia_predkosc);
  375. myFile.close();
  376. // delay(500);
  377. Serial.println("Done.");
  378. }
  379.  
  380. Timer1.attachInterrupt(ISR_timerone);
  381. }
  382.  
  383. int GET_LEFT_STATUS(void) {
  384. if (sr04_left.Distance() < offset)
  385. return OBSTACLE;
  386. else
  387. return NO_OBSTACLE;
  388. }
  389.  
  390. int GET_FRONT_STATUS(void) {
  391. if (sr04_front.Distance() < max_front_distance)
  392. return OBSTACLE;
  393. else
  394. return NO_OBSTACLE;
  395. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement