|
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