|
20 | 20 | #include "LottieLemonLineFollow.h"
|
21 | 21 | using namespace LottieLemon;
|
22 | 22 |
|
23 |
| -//#define KP 19 //0.1 units |
24 |
| -//#define KD 14 |
25 |
| -//#define ROBOT_SPEED 100 //percentage |
26 |
| - |
27 |
| -//#define KP 11 |
28 |
| -//#define KD 5 |
29 |
| -//#define ROBOT_SPEED 50 |
30 |
| - |
31 |
| -//#define INTEGRATION_TIME 10 //En ms |
32 |
| - |
33 |
| -/*uint8_t KP=11; |
34 |
| -uint8_t KD=5; |
35 |
| -uint8_t robotSpeed=50; //percentage |
36 |
| -uint8_t intergrationTime=10;*/ |
37 |
| - |
38 |
| -#define NIVEL_PARA_LINEA 50 |
39 |
| - |
40 |
| -/*int lectura_sensor[5], last_error=0, acu=0; |
41 |
| -
|
42 |
| -//Estos son los arrays que hay que rellenar con los valores de los sensores |
43 |
| -//de suelo sobre blanco y negro. |
44 |
| -int sensor_blanco[]={ |
45 |
| -0,0,0,0,0}; |
46 |
| -int sensor_negro[]={ |
47 |
| -1023,1023,1023,1023,1023}; |
48 |
| -*/ |
49 |
| -//unsigned long time; |
50 |
| - |
51 |
| -//void mueve_robot(int vel_izq, int vel_der); |
52 |
| -//void para_robot(); |
53 |
| -//void doCalibration(int speedPct, int time); |
54 |
| -//void ajusta_niveles(); //calibrate values |
55 |
| - |
56 | 23 | LineFollow::LineFollow() {
|
57 |
| - /*KP=11; |
58 |
| - KD=5; |
59 |
| - robotSpeed=50; //percentage |
60 |
| - intergrationTime=10;*/ |
61 | 24 | config(11, 5, 50, 10);
|
62 |
| - |
63 |
| - for (int i = 0; i<5; i++) { |
64 |
| - sensor_blanco[i] = 0; |
65 |
| - sensor_negro[i] = 1023; |
66 |
| - } |
67 | 25 | }
|
68 | 26 |
|
69 |
| -void LineFollow::config(uint8_t KP, uint8_t KD, uint8_t robotSpeed, uint8_t intergrationTime) { |
70 |
| - this->KP = KP; |
71 |
| - this->KD = KD; |
72 |
| - this->robotSpeed = robotSpeed; |
73 |
| - this->intergrationTime = intergrationTime; |
74 |
| - /*Serial.print("LFC: "); |
75 |
| - Serial.print(KP); |
76 |
| - Serial.print(' '); |
77 |
| - Serial.print(KD); |
78 |
| - Serial.print(' '); |
79 |
| - Serial.print(robotSpeed); |
80 |
| - Serial.print(' '); |
81 |
| - Serial.println(intergrationTime);*/ |
| 27 | +void LineFollow::config(uint8_t KP, uint8_t KD, |
| 28 | + uint8_t robotSpeedPct, uint8_t integrationTimeMillis) { |
| 29 | + config(KP, 0, KD, robotSpeedPct, integrationTimeMillis); |
| 30 | +} |
82 | 31 |
|
| 32 | +void LineFollow::config(uint8_t KP, uint8_t KI, uint8_t KD, |
| 33 | + uint8_t robotSpeedPct, uint8_t integrationTimeMillis) { |
| 34 | + _KP = KP; |
| 35 | + _KI = KI; |
| 36 | + _KD = KD; |
| 37 | + _robotSpeedPct = robotSpeedPct; |
| 38 | + _integrationTimeMillis = integrationTimeMillis; |
83 | 39 | }
|
84 |
| -void LineFollow::calibIRs() { |
85 |
| - static bool isInited = false;//So only init once |
86 |
| - if (isInited)return; |
87 | 40 |
|
| 41 | +void LineFollow::calibIRs() { |
| 42 | + // So only init once. |
| 43 | + static bool isInited = false; |
| 44 | + if (isInited) { |
| 45 | + return; |
| 46 | + } |
88 | 47 | delay(1000);
|
89 |
| - |
90 | 48 | doCalibration(30, 500);
|
91 | 49 | doCalibration(-30, 800);
|
92 | 50 | doCalibration(30, 500);
|
93 |
| - |
94 | 51 | delay(1000);
|
95 | 52 | isInited = true;
|
96 | 53 | }
|
97 | 54 |
|
98 | 55 | void LineFollow::runLineFollow() {
|
99 |
| - for (int count = 0; count<5; count++) |
100 |
| - { |
101 |
| - lectura_sensor[count] = map(_IRread(count), sensor_negro[count], sensor_blanco[count], 0, 127); |
102 |
| - acu += lectura_sensor[count]; |
103 |
| - } |
104 |
| - |
105 |
| - //Serial.println(millis()); |
106 |
| - if (acu > NIVEL_PARA_LINEA) |
107 |
| - { |
108 |
| - acu /= 5; |
109 |
| - |
110 |
| - int error = ((lectura_sensor[0] << 6) + (lectura_sensor[1] << 5) - (lectura_sensor[3] << 5) - (lectura_sensor[4] << 6)) / acu; |
111 |
| - |
112 |
| - error = constrain(error, -100, 100); |
113 |
| - |
114 |
| - //Calculamos la correcion de velocidad mediante un filtro PD |
115 |
| - int vel = (error * KP) / 10 + (error - last_error)*KD; |
116 |
| - |
117 |
| - last_error = error; |
118 |
| - |
119 |
| - //Corregimos la velocidad de avance con el error de salida del filtro PD |
120 |
| - int motor_left = constrain((robotSpeed + vel), -100, 100); |
121 |
| - int motor_right = constrain((robotSpeed - vel), -100, 100); |
122 |
| - |
123 |
| - //Movemos el robot |
124 |
| - //motorsWritePct(motor_left,motor_right); |
125 |
| - motorsWritePct(motor_left, motor_right); |
126 |
| - |
127 |
| - //Esperamos un poquito a que el robot reaccione |
128 |
| - delay(intergrationTime); |
| 56 | + enum { STOP_LINE_VALUE = 1500 }; |
| 57 | + uint32_t weight = 0; |
| 58 | + uint16_t sum = 0; |
| 59 | + for (int i = 0; i < 5; i++) { |
| 60 | + _sensors[i] = _IRread(i); |
| 61 | + weight += _sensors[i] * (i + 1); |
| 62 | + sum += _sensors[i]; |
129 | 63 | }
|
130 |
| - else |
131 |
| - { |
132 |
| - //Hemos encontrado una linea negra |
133 |
| - //perpendicular a nuestro camino |
134 |
| - //paramos el robot |
| 64 | + if (sum > STOP_LINE_VALUE) { |
| 65 | + if ((millis() - _tStartMillis) <= _integrationTimeMillis) { |
| 66 | + return; |
| 67 | + } |
| 68 | + _tStartMillis = millis(); |
| 69 | + int16_t error = 100 * weight / sum - 300; |
| 70 | + _integral = _integral + error; |
| 71 | + _derivative = error - _lastError; |
| 72 | + _lastError = error; |
| 73 | + // Calculate the adjustment with PID control. |
| 74 | + int16_t change = _KP * error + _KI * _integral + _KD * _derivative; |
| 75 | + change = change / 10; |
| 76 | + // Change motor speed. |
| 77 | + int16_t leftSpeed = constrain((_robotSpeedPct + change), -100, 100); |
| 78 | + int16_t rightSpeed = constrain((_robotSpeedPct - change), -100, 100); |
| 79 | + motorsWritePct(leftSpeed, rightSpeed); |
| 80 | + } else { |
| 81 | + // The robot discovered a perpendicular black line. Stop motors. |
135 | 82 | motorsStop();
|
136 |
| - |
137 |
| - //y detenemos la ejecucion del programa |
138 |
| - //while(true); |
| 83 | + // Stop the execution of the control board program. |
139 | 84 | reportActionDone();
|
140 |
| - //setMode(MODE_SIMPLE); |
141 | 85 | }
|
142 | 86 | }
|
143 | 87 |
|
144 |
| - |
145 | 88 | void LineFollow::doCalibration(int speedPct, unsigned int time) {
|
146 | 89 | motorsWritePct(speedPct, -speedPct);
|
147 | 90 | unsigned long beginTime = millis();
|
148 |
| - while ((millis() - beginTime)<time) |
149 |
| - ajusta_niveles(); |
| 91 | + while ((millis() - beginTime) < time); |
| 92 | + _tStartMillis = millis(); |
150 | 93 | motorsStop();
|
151 | 94 | }
|
152 |
| -void LineFollow::ajusta_niveles() |
153 |
| -{ |
154 |
| - int lectura = 0; |
155 |
| - |
156 |
| - for (int count = 0; count<5; count++) { |
157 |
| - lectura = _IRread(count); |
158 |
| - |
159 |
| - if (lectura > sensor_blanco[count]) |
160 |
| - sensor_blanco[count] = lectura; |
161 |
| - |
162 |
| - if (lectura < sensor_negro[count]) |
163 |
| - sensor_negro[count] = lectura; |
164 |
| - } |
165 |
| -} |
166 |
| - |
167 |
| - |
168 |
| - |
169 |
| - |
170 |
| - |
0 commit comments