π― Π€ΠΈΠ½Π°Π»ΡΠ½ΡΠΉ ΠΏΡΠΎΠ΅ΠΊΡ: ΠΠ±ΡΠ΅Π΄ΠΈΠ½ΡΠ΅ΠΌ Π²ΡΠ΅ ΠΈΠ·ΡΡΠ΅Π½Π½ΡΠ΅ ΡΠ΅Ρ
Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ
β Π Π΅Π·ΡΠ»ΡΡΠ°Ρ: Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΡΠΌΠ½ΠΎΠ³ΠΎ ΡΠΎΠ±ΠΎΡΠ° Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌΠΈ Π΄Π°ΡΡΠΈΠΊΠ°ΠΌΠΈ
π¨βπ« Π£ΡΠΈΡΠ΅Π»Ρ: ΠΡ
ΠΌΠ΅ΡΠΎΠ² Π ΡΡΡΠ°ΠΌ
π« Π¨ΠΊΠΎΠ»Π°: ΠΠΠΠ£ β 1362
π
ΠΠ°ΡΠ°: 2025-06-14
β° ΠΡΠ΅ΠΌΡ: 105 ΠΌΠΈΠ½ΡΡ
Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΡΠΎΠ±ΠΎΡΠ°-ΡΠ½ΠΈΠ²Π΅ΡΡΠ°Π»Π°, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΌΠ΅Π΅Ρ:
ΠΠ°Ρ ΡΠΎΠ±ΠΎΡ Π΄ΠΎΠ»ΠΆΠ΅Π½:
πͺ ΠΡΠΎ Π½Π°ΡΡΠΎΡΡΠΈΠΉ Π²ΡΠ·ΠΎΠ² Π΄Π»Ρ ΠΈΠ½ΠΆΠ΅Π½Π΅ΡΠΎΠ²-ΡΠΎΠ±ΠΎΡΠΎΡΠ΅Ρ Π½ΠΈΠΊΠΎΠ²!
ΠΠ°ΡΠΈ “Π³Π»Π°Π·Π° ΠΈ ΡΡΠΈ”:
ΠΠΎΠ³ΠΈΠΊΠ° ΠΏΡΠΈΠ½ΡΡΠΈΡ ΡΠ΅ΡΠ΅Π½ΠΈΠΉ:
11. ΠΠΠΠΠΠΠ‘ΠΠΠ‘Π’Π¬ (Π²ΡΡΡΠΈΠΉ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ)
2 β³ ΠΡΡΡ ΠΏΡΠ΅ΠΏΡΡΡΡΠ²ΠΈΠ΅? β ΠΠ±Ρ
ΠΎΠ΄ΠΈΠΌ!
3
42. ΠΠΠΠΠΠΠ¦ΠΠ― (ΡΡΠ΅Π΄Π½ΠΈΠΉ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ)
5 β³ ΠΠΎΡΠ΅ΡΡΠ»ΠΈ Π»ΠΈΠ½ΠΈΡ? β ΠΡΠ΅ΠΌ!
6
73. Π‘ΠΠΠΠΠΠΠΠΠ (Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ)
8 β³ ΠΠΈΠ΄ΠΈΠΌ Π»ΠΈΠ½ΠΈΡ? β ΠΠ΄Π΅ΠΌ ΠΏΠΎ Π½Π΅ΠΉ!
ΠΡΠΈΠ½ΡΠΈΠΏ: ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ Π²Π°ΠΆΠ½Π΅Π΅ ΡΠΊΠΎΡΠΎΡΡΠΈ, ΡΠΎΡΠ½ΠΎΡΡΡ Π²Π°ΠΆΠ½Π΅Π΅ ΡΡΡΠ΅ΠΊΡΠ½ΠΎΡΡΠΈ!
ΠΡΠΈΠ½ΡΠΈΠΏ ΡΠ°Π±ΠΎΡΡ:
ΠΠ°ΡΠ΅ΠΌΠ°ΡΠΈΠΊΠ° Π΄Π°ΡΡΠΈΠΊΠ°:
\[\text{ΠΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅} = \frac{\text{ΠΠ½ΡΠ΅Π½ΡΠΈΠ²Π½ΠΎΡΡΡ ΠΎΡΡΠ°ΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ²Π΅ΡΠ°}}{\text{ΠΠ½ΡΠ΅Π½ΡΠΈΠ²Π½ΠΎΡΡΡ ΠΈΠ·Π»ΡΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ²Π΅ΡΠ°}}\]ΠΠΎΡΠΎΠ³ΠΎΠ²ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ:
ΠΡΠΈΠ½ΡΠΈΠΏ ΡΠ°Π±ΠΎΡΡ:
Π€ΠΎΡΠΌΡΠ»Π° ΡΠ°ΡΡΠ΅ΡΠ° ΡΠ°ΡΡΡΠΎΡΠ½ΠΈΡ:
\[d = \frac{v \cdot t}{2}\]Π³Π΄Π΅:
ΠΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΠ°ΡΡΠ΅Ρ:
\[d_{ΡΠΌ} = \frac{t_{ΠΌΠΈΠΊΡΠΎΡΠ΅ΠΊΡΠ½Π΄Ρ}}{58}\]ΠΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½ΡΡ ΠΎΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ Π΄Π°ΡΡΠΈΠΊΠΎΠ²:
Weighted fusion Π΄Π»Ρ Π΄Π°ΡΡΠΈΠΊΠΎΠ² Π»ΠΈΠ½ΠΈΠΈ:
\[\text{ΠΠΎΠ·ΠΈΡΠΈΡ} = w_L \cdot S_L + w_R \cdot S_R\]Π³Π΄Π΅ $w_L$ ΠΈ $w_R$ - Π²Π΅ΡΠ° Π»Π΅Π²ΠΎΠ³ΠΎ ΠΈ ΠΏΡΠ°Π²ΠΎΠ³ΠΎ Π΄Π°ΡΡΠΈΠΊΠΎΠ², $S_L$ ΠΈ $S_R$ - ΠΈΡ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΈΡ
ΠΠΎΠ³ΠΈΠΊΠ° ΠΏΡΠΈΠ½ΡΡΠΈΡ ΡΠ΅ΡΠ΅Π½ΠΈΠΉ:
\[\text{ΠΠ΅ΠΉΡΡΠ²ΠΈΠ΅} = \begin{cases} \text{STOP} & \text{if } d < d_{ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΎΠ΅} \\ \text{AVOID} & \text{if } d < d_{Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΠ΅} \\ \text{FOLLOW} & \text{if } \text{line detected} \\ \text{SEARCH} & \text{otherwise} \end{cases}\]ΠΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ΡΠΈΠ»ΡΡΡΠ°ΡΠΈΡ ΡΡΠΌΠΎΠ²:
\[S_{filtered}(t) = \alpha \cdot S_{raw}(t) + (1-\alpha) \cdot S_{filtered}(t-1)\]Π³Π΄Π΅ Ξ± β 0.3 (ΠΊΠΎΡΡΡΠΈΡΠΈΠ΅Π½Ρ ΡΠ³Π»Π°ΠΆΠΈΠ²Π°Π½ΠΈΡ)
ΠΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΡΠΎΠ±ΠΎΡΠ°:
ΠΡΠΈΠ½ΡΠΈΠΏΡ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ²:
ΠΠΏΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠ΅ ΡΠ°ΡΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅:
1 [Π ΠΎΠ±ΠΎΡ ΡΠ²Π΅ΡΡ
Ρ]
2
3 [O] [O] β ΠΠΎΠ»Π΅ΡΠ°
4 | |
5 [β] [β] β ΠΠ°ΡΡΠΈΠΊΠΈ Π»ΠΈΠ½ΠΈΠΈ
6 \ /
7 \ /
8 [βββ] β Π§Π΅ΡΠ½Π°Ρ Π»ΠΈΠ½ΠΈΡ
Π Π°ΡΡΡΠΎΡΠ½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π°ΡΡΠΈΠΊΠ°ΠΌΠΈ:
\[d_{sensors} = 1.5 \times \text{ΡΠΈΡΠΈΠ½Π° Π»ΠΈΠ½ΠΈΠΈ}\]ΠΠ»Ρ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ Π»ΠΈΠ½ΠΈΠΈ 20 ΠΌΠΌ: ΡΠ°ΡΡΡΠΎΡΠ½ΠΈΠ΅ β 30 ΠΌΠΌ
ΠΡΠ΅ΠΏΠ»Π΅Π½ΠΈΠ΅ Π½Π° ΠΏΠ΅ΡΠ΅Π΄Π½Π΅ΠΉ ΡΠ°ΡΡΠΈ:
1// ΠΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π΄Π°ΡΡΠΈΠΊΠΎΠ² ΠΊ Arduino
2const int TRIG_PIN = 7; // Π£Π»ΡΡΡΠ°Π·Π²ΡΠΊ - trigger
3const int ECHO_PIN = 6; // Π£Π»ΡΡΡΠ°Π·Π²ΡΠΊ - echo
4const int LINE_LEFT_PIN = A0; // ΠΠ΅Π²ΡΠΉ Π΄Π°ΡΡΠΈΠΊ Π»ΠΈΠ½ΠΈΠΈ
5const int LINE_RIGHT_PIN = A1; // ΠΡΠ°Π²ΡΠΉ Π΄Π°ΡΡΠΈΠΊ Π»ΠΈΠ½ΠΈΠΈ
6const int MOTOR_LEFT_A = 3; // ΠΠ΅Π²ΡΠΉ ΠΌΠΎΡΠΎΡ - Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅
7const int MOTOR_LEFT_B = 4; // ΠΠ΅Π²ΡΠΉ ΠΌΠΎΡΠΎΡ - Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅
8const int MOTOR_RIGHT_A = 5; // ΠΡΠ°Π²ΡΠΉ ΠΌΠΎΡΠΎΡ - Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅
9const int MOTOR_RIGHT_B = 8; // ΠΡΠ°Π²ΡΠΉ ΠΌΠΎΡΠΎΡ - Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅
ΠΡΡΠΎΠ΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΏΡΠΈΠ½ΡΠΈΠΏΡ: ΠΠ°ΠΆΠ΅ Π΄Π»Ρ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠΎΠ±ΠΎΡΠ° ΡΠΎΡΠΌΠ° ΠΈΠΌΠ΅Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅:
Π¦Π΅Π½ΡΡ ΠΌΠ°ΡΡ ΠΈ ΡΡΡΠΎΠΉΡΠΈΠ²ΠΎΡΡΡ:
\[h_{max} = \frac{b \cdot g}{2 \cdot a_{max}}\]Π³Π΄Π΅:
ΠΠΎΠΌΠ΅Π½Ρ ΠΈΠ½Π΅ΡΡΠΈΠΈ Π΄Π»Ρ ΠΏΠΎΠ²ΠΎΡΠΎΡΠΎΠ²:
\[I = m \cdot r_{gyration}^2\]ΠΠΎΠΌΠΏΠ°ΠΊΡΠ½Π°Ρ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΈΡ ΠΏΠΎΠ²ΠΎΡΠ°ΡΠΈΠ²Π°Π΅ΡΡΡ Π±ΡΡΡΡΠ΅Π΅!
ΠΡΠ½ΠΎΠ²Π½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ:
1// ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΠΈΡΡΠ΅ΠΌΡ
2void setup() {
3 Serial.begin(9600);
4 initializeSensors();
5 initializeMotors();
6 calibrateSensors();
7}
8
9// ΠΠ»Π°Π²Π½ΡΠΉ ΡΠΈΠΊΠ»
10void loop() {
11 updateSensors(); // Π§ΠΈΡΠ°Π΅ΠΌ Π²ΡΠ΅ Π΄Π°ΡΡΠΈΠΊΠΈ
12 makeDecision(); // ΠΡΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅
13 executeAction(); // ΠΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅
14 delay(20); // 50 Hz update rate
15}
1// Π‘ΡΡΡΠΊΡΡΡΠ° Π΄Π»Ρ Ρ
ΡΠ°Π½Π΅Π½ΠΈΡ Π΄Π°Π½Π½ΡΡ
Π΄Π°ΡΡΠΈΠΊΠΎΠ²
2struct SensorData {
3 int leftLine; // ΠΠ΅Π²ΡΠΉ Π΄Π°ΡΡΠΈΠΊ Π»ΠΈΠ½ΠΈΠΈ (0-1023)
4 int rightLine; // ΠΡΠ°Π²ΡΠΉ Π΄Π°ΡΡΠΈΠΊ Π»ΠΈΠ½ΠΈΠΈ (0-1023)
5 float distance; // Π Π°ΡΡΡΠΎΡΠ½ΠΈΠ΅ Π² ΡΠΌ
6 bool lineDetected; // ΠΠ±Π½Π°ΡΡΠΆΠ΅Π½Π° Π»ΠΈ Π»ΠΈΠ½ΠΈΡ
7 bool obstacleAhead; // ΠΡΡΡ Π»ΠΈ ΠΏΡΠ΅ΠΏΡΡΡΡΠ²ΠΈΠ΅ Π²ΠΏΠ΅ΡΠ΅Π΄ΠΈ
8};
9
10SensorData sensors;
11
12void updateSensors() {
13 // Π§ΠΈΡΠ°Π΅ΠΌ Π΄Π°ΡΡΠΈΠΊΠΈ Π»ΠΈΠ½ΠΈΠΈ
14 sensors.leftLine = analogRead(LINE_LEFT_PIN);
15 sensors.rightLine = analogRead(LINE_RIGHT_PIN);
16
17 // Π§ΠΈΡΠ°Π΅ΠΌ ΡΠ»ΡΡΡΠ°Π·Π²ΡΠΊΠΎΠ²ΠΎΠΉ Π΄Π°ΡΡΠΈΠΊ
18 sensors.distance = readUltrasonic();
19
20 // ΠΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ
21 sensors.lineDetected = (sensors.leftLine < 300) || (sensors.rightLine < 300);
22 sensors.obstacleAhead = sensors.distance < 20.0; // 20 ΡΠΌ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½Π°Ρ Π·ΠΎΠ½Π°
23}
24
25float readUltrasonic() {
26 digitalWrite(TRIG_PIN, LOW);
27 delayMicroseconds(2);
28 digitalWrite(TRIG_PIN, HIGH);
29 delayMicroseconds(10);
30 digitalWrite(TRIG_PIN, LOW);
31
32 long duration = pulseIn(ECHO_PIN, HIGH);
33 return duration * 0.034 / 2; // ΠΠ΅ΡΠ΅Π²ΠΎΠ΄ Π² ΡΠ°Π½ΡΠΈΠΌΠ΅ΡΡΡ
34}
Π‘ΠΎΡΡΠΎΡΠ½ΠΈΡ ΡΠΎΠ±ΠΎΡΠ°:
1enum RobotState {
2 FOLLOWING_LINE, // Π‘Π»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎ Π»ΠΈΠ½ΠΈΠΈ
3 AVOIDING_OBSTACLE, // ΠΠ±Ρ
ΠΎΠ΄ ΠΏΡΠ΅ΠΏΡΡΡΡΠ²ΠΈΡ
4 SEARCHING_LINE, // ΠΠΎΠΈΡΠΊ ΠΏΠΎΡΠ΅ΡΡΠ½Π½ΠΎΠΉ Π»ΠΈΠ½ΠΈΠΈ
5 STOPPED // ΠΡΡΠ°Π½ΠΎΠ²ΠΊΠ° (Π°Π²Π°ΡΠΈΠΉΠ½Π°Ρ ΡΠΈΡΡΠ°ΡΠΈΡ)
6};
7
8RobotState currentState = FOLLOWING_LINE;
9
10void makeDecision() {
11 switch (currentState) {
12 case FOLLOWING_LINE:
13 if (sensors.obstacleAhead) {
14 currentState = AVOIDING_OBSTACLE;
15 Serial.println("Switching to OBSTACLE AVOIDANCE");
16 } else if (!sensors.lineDetected) {
17 currentState = SEARCHING_LINE;
18 Serial.println("LINE LOST - Searching...");
19 }
20 break;
21
22 case AVOIDING_OBSTACLE:
23 if (!sensors.obstacleAhead && sensors.lineDetected) {
24 currentState = FOLLOWING_LINE;
25 Serial.println("Obstacle cleared - Following line");
26 }
27 break;
28
29 case SEARCHING_LINE:
30 if (sensors.lineDetected) {
31 currentState = FOLLOWING_LINE;
32 Serial.println("Line found - Following");
33 }
34 break;
35
36 case STOPPED:
37 // Π’ΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΡΡΠ½ΠΎΠ΅ Π²ΠΌΠ΅ΡΠ°ΡΠ΅Π»ΡΡΡΠ²ΠΎ
38 break;
39 }
40}
1void executeAction() {
2 switch (currentState) {
3 case FOLLOWING_LINE:
4 followLine();
5 break;
6
7 case AVOIDING_OBSTACLE:
8 avoidObstacle();
9 break;
10
11 case SEARCHING_LINE:
12 searchLine();
13 break;
14
15 case STOPPED:
16 stopMotors();
17 break;
18 }
19}
20
21void followLine() {
22 int leftSensor = sensors.leftLine;
23 int rightSensor = sensors.rightLine;
24
25 // PID-ΡΠ΅Π³ΡΠ»ΡΡΠΎΡ Π΄Π»Ρ ΡΠΎΡΠ½ΠΎΠ³ΠΎ ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΡ
26 int error = leftSensor - rightSensor;
27 static int lastError = 0;
28 static int integral = 0;
29
30 float Kp = 0.5; // ΠΡΠΎΠΏΠΎΡΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠΉ ΠΊΠΎΡΡΡΠΈΡΠΈΠ΅Π½Ρ
31 float Ki = 0.01; // ΠΠ½ΡΠ΅Π³ΡΠ°Π»ΡΠ½ΡΠΉ ΠΊΠΎΡΡΡΠΈΡΠΈΠ΅Π½Ρ
32 float Kd = 0.1; // ΠΠΈΡΡΠ΅ΡΠ΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΠΉ ΠΊΠΎΡΡΡΠΈΡΠΈΠ΅Π½Ρ
33
34 integral += error;
35 int derivative = error - lastError;
36
37 int correction = Kp * error + Ki * integral + Kd * derivative;
38
39 int baseSpeed = 150; // ΠΠ°Π·ΠΎΠ²Π°Ρ ΡΠΊΠΎΡΠΎΡΡΡ
40 int leftSpeed = baseSpeed + correction;
41 int rightSpeed = baseSpeed - correction;
42
43 // ΠΠ³ΡΠ°Π½ΠΈΡΠΈΠ²Π°Π΅ΠΌ ΡΠΊΠΎΡΠΎΡΡΠΈ
44 leftSpeed = constrain(leftSpeed, 0, 255);
45 rightSpeed = constrain(rightSpeed, 0, 255);
46
47 setMotorSpeeds(leftSpeed, rightSpeed);
48 lastError = error;
49}
ΠΠ΄Π°ΠΏΡΠΈΠ²Π½ΡΠΉ PID-ΡΠ΅Π³ΡΠ»ΡΡΠΎΡ:
1class AdaptivePID {
2private:
3 float kp, ki, kd;
4 float integral, lastError;
5 float maxIntegral = 1000;
6
7public:
8 AdaptivePID(float p, float i, float d) : kp(p), ki(i), kd(d) {
9 integral = 0;
10 lastError = 0;
11 }
12
13 float calculate(float error, float speed) {
14 // ΠΠ΄Π°ΠΏΡΠ°ΡΠΈΡ ΠΊΠΎΡΡΡΠΈΡΠΈΠ΅Π½ΡΠΎΠ² Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΡΠΊΠΎΡΠΎΡΡΠΈ
15 float adaptiveKp = kp * (1.0 + speed / 255.0);
16 float adaptiveKd = kd * (1.0 + speed / 255.0);
17
18 integral += error;
19 integral = constrain(integral, -maxIntegral, maxIntegral);
20
21 float derivative = error - lastError;
22
23 float output = adaptiveKp * error + ki * integral + adaptiveKd * derivative;
24
25 lastError = error;
26 return output;
27 }
28};
ΠΡΠ΅Π΄ΠΈΠΊΡΠΈΠ²Π½ΠΎΠ΅ ΠΈΠ·Π±Π΅Π³Π°Π½ΠΈΠ΅ ΠΏΡΠ΅ΠΏΡΡΡΡΠ²ΠΈΠΉ:
1float predictCollisionTime(float distance, float speed) {
2 if (speed <= 0) return INFINITY;
3 return distance / speed;
4}
5
6void smartObstacleAvoidance() {
7 float currentSpeed = getCurrentSpeed();
8 float timeToCollision = predictCollisionTime(sensors.distance, currentSpeed);
9
10 if (timeToCollision < 2.0) { // 2 ΡΠ΅ΠΊΡΠ½Π΄Ρ Π΄ΠΎ ΡΡΠΎΠ»ΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΡ
11 // ΠΠ°ΡΠΈΠ½Π°Π΅ΠΌ ΠΌΠ°Π½Π΅Π²Ρ Π·Π°ΡΠ°Π½Π΅Π΅
12 executeAvoidanceManeuver();
13 }
14}
ΠΠ°Π·ΠΎΠ²ΡΠΉ Π°Π»Π³ΠΎΡΠΈΡΠΌ:
1void basicLineFollowing() {
2 bool leftOnLine = (sensors.leftLine < 300);
3 bool rightOnLine = (sensors.rightLine < 300);
4
5 if (leftOnLine && rightOnLine) {
6 // ΠΠ±Π° Π΄Π°ΡΡΠΈΠΊΠ° Π½Π° Π»ΠΈΠ½ΠΈΠΈ - Π΅Π΄Π΅ΠΌ ΠΏΡΡΠΌΠΎ
7 setMotorSpeeds(150, 150);
8 } else if (leftOnLine && !rightOnLine) {
9 // ΠΠΈΠ½ΠΈΡ ΡΠ»Π΅Π²Π° - ΠΏΠΎΠ²ΠΎΡΠ°ΡΠΈΠ²Π°Π΅ΠΌ Π²Π»Π΅Π²ΠΎ
10 setMotorSpeeds(100, 200);
11 } else if (!leftOnLine && rightOnLine) {
12 // ΠΠΈΠ½ΠΈΡ ΡΠΏΡΠ°Π²Π° - ΠΏΠΎΠ²ΠΎΡΠ°ΡΠΈΠ²Π°Π΅ΠΌ Π²ΠΏΡΠ°Π²ΠΎ
13 setMotorSpeeds(200, 100);
14 } else {
15 // ΠΠΈΠ½ΠΈΡ ΠΏΠΎΡΠ΅ΡΡΠ½Π° - ΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌΡΡ
16 setMotorSpeeds(0, 0);
17 currentState = SEARCHING_LINE;
18 }
19}
ΠΠ»Π³ΠΎΡΠΈΡΠΌ ΠΏΡΠ°Π²ΠΎΠΉ ΡΡΠΊΠΈ:
1void avoidObstacle() {
2 static int avoidanceStep = 0;
3 static unsigned long stepStartTime = 0;
4
5 switch (avoidanceStep) {
6 case 0: // ΠΡΡΠ°Π½ΠΎΠ²ΠΊΠ°
7 stopMotors();
8 delay(500);
9 avoidanceStep = 1;
10 stepStartTime = millis();
11 break;
12
13 case 1: // ΠΠΎΠ²ΠΎΡΠΎΡ Π²Π»Π΅Π²ΠΎ Π½Π° 90Β°
14 setMotorSpeeds(-150, 150); // ΠΠΎΠ²ΠΎΡΠΎΡ Π½Π° ΠΌΠ΅ΡΡΠ΅
15 if (millis() - stepStartTime > 800) { // ~90Β°
16 avoidanceStep = 2;
17 stepStartTime = millis();
18 }
19 break;
20
21 case 2: // ΠΠ²ΠΈΠΆΠ΅Π½ΠΈΠ΅ Π²ΠΏΠ΅ΡΠ΅Π΄
22 setMotorSpeeds(150, 150);
23 if (millis() - stepStartTime > 1000) { // ΠΡΠΎΠ΅Π·ΠΆΠ°Π΅ΠΌ ΠΏΡΠ΅ΠΏΡΡΡΡΠ²ΠΈΠ΅
24 avoidanceStep = 3;
25 stepStartTime = millis();
26 }
27 break;
28
29 case 3: // ΠΠΎΠ²ΠΎΡΠΎΡ Π²ΠΏΡΠ°Π²ΠΎ Π½Π° 90Β°
30 setMotorSpeeds(150, -150);
31 if (millis() - stepStartTime > 800) {
32 avoidanceStep = 4;
33 stepStartTime = millis();
34 }
35 break;
36
37 case 4: // ΠΠ²ΠΈΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΎ Π»ΠΈΠ½ΠΈΠΈ
38 setMotorSpeeds(150, 150);
39 if (sensors.lineDetected) {
40 avoidanceStep = 5;
41 stepStartTime = millis();
42 }
43 break;
44
45 case 5: // ΠΠΎΠ²ΠΎΡΠΎΡ Π²ΠΏΡΠ°Π²ΠΎ Π΄Π»Ρ Π²ΡΡ
ΠΎΠ΄Π° Π½Π° Π»ΠΈΠ½ΠΈΡ
46 setMotorSpeeds(150, -150);
47 if (millis() - stepStartTime > 800) {
48 avoidanceStep = 0; // Π‘Π±ΡΠΎΡ
49 currentState = FOLLOWING_LINE;
50 }
51 break;
52 }
53}
Π‘ΠΏΠΈΡΠ°Π»ΡΠ½ΡΠΉ ΠΏΠΎΠΈΡΠΊ:
1void searchLine() {
2 static unsigned long searchStartTime = 0;
3 static bool searchInitialized = false;
4 static int searchRadius = 100; // ΠΌΡ ΠΏΠΎΠ²ΠΎΡΠΎΡΠ°
5 static int searchDirection = 1; // 1 = ΠΏΡΠ°Π²ΠΎ, -1 = Π»Π΅Π²ΠΎ
6
7 if (!searchInitialized) {
8 searchStartTime = millis();
9 searchInitialized = true;
10 }
11
12 // ΠΠΎΠ²ΠΎΡΠΎΡ Ρ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°ΡΡΠΈΠΌΡΡ ΡΠ°Π΄ΠΈΡΡΠΎΠΌ
13 if (searchDirection > 0) {
14 setMotorSpeeds(150, -150); // ΠΠΎΠ²ΠΎΡΠΎΡ Π²ΠΏΡΠ°Π²ΠΎ
15 } else {
16 setMotorSpeeds(-150, 150); // ΠΠΎΠ²ΠΎΡΠΎΡ Π²Π»Π΅Π²ΠΎ
17 }
18
19 if (millis() - searchStartTime > searchRadius) {
20 searchDirection *= -1; // ΠΠ΅Π½ΡΠ΅ΠΌ Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅
21 searchRadius += 50; // Π£Π²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅ΠΌ ΡΠ°Π΄ΠΈΡΡ ΠΏΠΎΠΈΡΠΊΠ°
22 searchStartTime = millis();
23
24 // ΠΠ³ΡΠ°Π½ΠΈΡΠΈΠ²Π°Π΅ΠΌ Π²ΡΠ΅ΠΌΡ ΠΏΠΎΠΈΡΠΊΠ°
25 if (searchRadius > 2000) {
26 currentState = STOPPED; // ΠΠΈΠ½ΠΈΡ Π±Π΅Π·Π½Π°Π΄Π΅ΠΆΠ½ΠΎ ΠΏΠΎΡΠ΅ΡΡΠ½Π°
27 Serial.println("Line search failed - STOPPING");
28 }
29 }
30
31 // ΠΡΠ»ΠΈ Π½Π°ΡΠ»ΠΈ Π»ΠΈΠ½ΠΈΡ
32 if (sensors.lineDetected) {
33 searchInitialized = false;
34 searchRadius = 100; // Π‘Π±ΡΠΎΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ²
35 currentState = FOLLOWING_LINE;
36 Serial.println("Line found!");
37 }
38}
Q-Learning Π΄Π»Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΡ:
1class QLearningRobot {
2private:
3 float qTable[NUM_STATES][NUM_ACTIONS];
4 float learningRate = 0.1;
5 float discountFactor = 0.9;
6 float explorationRate = 0.1;
7
8 enum State {
9 ON_LINE_CLEAR = 0,
10 ON_LINE_OBSTACLE = 1,
11 OFF_LINE_CLEAR = 2,
12 OFF_LINE_OBSTACLE = 3
13 };
14
15 enum Action {
16 MOVE_FORWARD = 0,
17 TURN_LEFT = 1,
18 TURN_RIGHT = 2,
19 REVERSE = 3
20 };
21
22public:
23 int selectAction(int state) {
24 if (random(100) < explorationRate * 100) {
25 return random(NUM_ACTIONS); // ΠΡΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΠ΅
26 } else {
27 return getBestAction(state); // ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π½Π°Π½ΠΈΠΉ
28 }
29 }
30
31 void updateQ(int state, int action, float reward, int nextState) {
32 float maxQ = getMaxQ(nextState);
33 float oldQ = qTable[state][action];
34
35 qTable[state][action] = oldQ + learningRate *
36 (reward + discountFactor * maxQ - oldQ);
37 }
38
39 float calculateReward() {
40 float reward = 0;
41
42 if (sensors.lineDetected) reward += 10; // ΠΠ°Π³ΡΠ°Π΄Π° Π·Π° ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΠ΅ Π»ΠΈΠ½ΠΈΠΈ
43 if (sensors.obstacleAhead) reward -= 50; // Π¨ΡΡΠ°Ρ Π·Π° ΡΠΈΡΠΊ ΡΡΠΎΠ»ΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΡ
44 if (getCurrentSpeed() > 100) reward += 1; // ΠΠ°Π³ΡΠ°Π΄Π° Π·Π° ΡΠΊΠΎΡΠΎΡΡΡ
45
46 return reward;
47 }
48};
ΠΡΠ°ΠΏ 1: Π’Π΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π΄Π°ΡΡΠΈΠΊΠΎΠ²
1void testSensors() {
2 Serial.println("=== SENSOR TEST ===");
3
4 // Π’Π΅ΡΡ Π΄Π°ΡΡΠΈΠΊΠΎΠ² Π»ΠΈΠ½ΠΈΠΈ
5 Serial.print("Left Line: ");
6 Serial.print(analogRead(LINE_LEFT_PIN));
7 Serial.print(" | Right Line: ");
8 Serial.println(analogRead(LINE_RIGHT_PIN));
9
10 // Π’Π΅ΡΡ ΡΠ»ΡΡΡΠ°Π·Π²ΡΠΊΠ°
11 Serial.print("Distance: ");
12 Serial.print(readUltrasonic());
13 Serial.println(" cm");
14
15 delay(500);
16}
ΠΡΠ°ΠΏ 2: Π’Π΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠΎΡΠΎΡΠΎΠ²
1void testMotors() {
2 Serial.println("Testing motors...");
3
4 // ΠΠΏΠ΅ΡΠ΅Π΄
5 setMotorSpeeds(150, 150);
6 delay(1000);
7
8 // ΠΠΎΠ²ΠΎΡΠΎΡ Π²Π»Π΅Π²ΠΎ
9 setMotorSpeeds(100, 200);
10 delay(500);
11
12 // ΠΠΎΠ²ΠΎΡΠΎΡ Π²ΠΏΡΠ°Π²ΠΎ
13 setMotorSpeeds(200, 100);
14 delay(500);
15
16 // Π‘ΡΠΎΠΏ
17 stopMotors();
18}
ΠΡΠ°ΠΏ 3: ΠΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠ΅ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅
1void integrationTest() {
2 Serial.println("Integration test starting...");
3
4 // Π’Π΅ΡΡ 1: Π’ΠΎΠ»ΡΠΊΠΎ ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎ Π»ΠΈΠ½ΠΈΠΈ (Π±Π΅Π· ΠΏΡΠ΅ΠΏΡΡΡΡΠ²ΠΈΠΉ)
5 testLineFollowing();
6
7 // Π’Π΅ΡΡ 2: Π’ΠΎΠ»ΡΠΊΠΎ ΠΎΠ±Ρ
ΠΎΠ΄ ΠΏΡΠ΅ΠΏΡΡΡΡΠ²ΠΈΠΉ (Π±Π΅Π· Π»ΠΈΠ½ΠΈΠΈ)
8 testObstacleAvoidance();
9
10 // Π’Π΅ΡΡ 3: ΠΠΎΠΌΠ±ΠΈΠ½ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΡΠ΅ΡΡ
11 testComplexBehavior();
12}
1void calibrateSensors() {
2 Serial.println("Calibrating sensors...");
3 Serial.println("Place robot on WHITE surface and press button");
4
5 waitForButtonPress();
6
7 // ΠΠ°Π»ΠΈΠ±ΡΠΎΠ²ΠΊΠ° Π½Π° Π±Π΅Π»ΠΎΠΌ ΡΠΎΠ½Π΅
8 int whiteLeft = 0, whiteRight = 0;
9 for (int i = 0; i < 100; i++) {
10 whiteLeft += analogRead(LINE_LEFT_PIN);
11 whiteRight += analogRead(LINE_RIGHT_PIN);
12 delay(10);
13 }
14 whiteLeft /= 100;
15 whiteRight /= 100;
16
17 Serial.println("Now place on BLACK line and press button");
18 waitForButtonPress();
19
20 // ΠΠ°Π»ΠΈΠ±ΡΠΎΠ²ΠΊΠ° Π½Π° ΡΠ΅ΡΠ½ΠΎΠΉ Π»ΠΈΠ½ΠΈΠΈ
21 int blackLeft = 0, blackRight = 0;
22 for (int i = 0; i < 100; i++) {
23 blackLeft += analogRead(LINE_LEFT_PIN);
24 blackRight += analogRead(LINE_RIGHT_PIN);
25 delay(10);
26 }
27 blackLeft /= 100;
28 blackRight /= 100;
29
30 // ΠΡΡΠΈΡΠ»ΡΠ΅ΠΌ ΠΏΠΎΡΠΎΠ³ΠΎΠ²ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ
31 int thresholdLeft = (whiteLeft + blackLeft) / 2;
32 int thresholdRight = (whiteRight + blackRight) / 2;
33
34 Serial.print("Thresholds - Left: ");
35 Serial.print(thresholdLeft);
36 Serial.print(", Right: ");
37 Serial.println(thresholdRight);
38}
ΠΡΠΈΡΠ΅ΡΠΈΠΈ:
Π‘ΠΈΡΡΠ΅ΠΌΠ° Π±Π°Π»Π»ΠΎΠ²:
ΠΡΠΈΡΠ΅ΡΠΈΠΈ:
Π‘ΠΈΡΡΠ΅ΠΌΠ° Π±Π°Π»Π»ΠΎΠ²:
ΠΡΠΈΡΠ΅ΡΠΈΠΈ:
Π€ΠΎΡΠΌΡΠ»Π° ΠΈΡΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ Π±Π°Π»Π»Π°: \[\text{ΠΠ°Π»Π»} = \frac{\text{ΠΠ°Π»Π»Ρ Π·Π° ΡΠΎΡΠ½ΠΎΡΡΡ} \times 1000}{\text{ΠΡΠ΅ΠΌΡ Π² ΡΠ΅ΠΊΡΠ½Π΄Π°Ρ }}\]
ΠΠΎΠ½ΡΡΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅:
ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅:
Π‘ΠΈΡΡΠ΅ΠΌΠ½ΠΎΠ΅ ΠΌΡΡΠ»Π΅Π½ΠΈΠ΅:
ΠΠ½ΠΆΠ΅Π½Π΅ΡΠ½ΡΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄:
“Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠΌΠ½ΠΎΠ³ΠΎ ΡΠΎΠ±ΠΎΡΠ° - ΡΡΠΎ Π½Π΅ ΠΏΡΠΎΡΡΠΎ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Π΄Π°ΡΡΠΈΠΊΠΎΠ² ΠΈ ΠΌΠΎΡΠΎΡΠΎΠ². ΠΡΠΎ ΠΈΡΠΊΡΡΡΡΠ²ΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠΈΡΡΠ΅ΠΌΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡ ΡΠ°Π·ΡΠΌΠ½ΡΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π² ΡΠ»ΠΎΠΆΠ½ΠΎΠΌ ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΡΠΈΠ²ΠΎΠΌ ΠΌΠΈΡΠ΅!”
1. Π’Π΅Ρ Π½ΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΎΡΡΠ΅Ρ Π‘ΠΎΡΡΠ°Π²ΡΡΠ΅ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΡΠΉ ΠΎΡΡΠ΅Ρ ΠΎ Π²Π°ΡΠ΅ΠΌ ΡΠΎΠ±ΠΎΡΠ΅:
2. ΠΠ½Π°Π»ΠΈΠ· ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΡ ΠΠΏΠΈΡΠΈΡΠ΅, ΠΊΠ°ΠΊ Π²Π°Ρ ΡΠΎΠ±ΠΎΡ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π² ΡΠ»Π΅Π΄ΡΡΡΠΈΡ ΡΠΈΡΡΠ°ΡΠΈΡΡ :
3. Π Π°ΡΡΠΈΡΠ΅Π½Π½Π°Ρ ΡΠ΅Π½ΡΠΎΡΠ½Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° Π‘ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΡΠΉΡΠ΅ ΡΠΎΠ±ΠΎΡΠ° Ρ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΌΠΈ Π΄Π°ΡΡΠΈΠΊΠ°ΠΌΠΈ:
4. ΠΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ Π°Π»Π³ΠΎΡΠΈΡΠΌΠΎΠ² ΠΡΡΠ»Π΅Π΄ΡΠΉΡΠ΅ ΠΈ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠΈΡΠ΅ ΡΠ»ΡΡΡΠ΅Π½ΠΈΡ:
5. Π‘ΠΈΠΌΡΠ»ΡΡΠΈΡ Π² Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΠΎΠΉ ΡΡΠ΅Π΄Π΅ Π‘ΠΎΠ·Π΄Π°ΠΉΡΠ΅ ΠΊΠΎΠΌΠΏΡΡΡΠ΅ΡΠ½ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π²Π°ΡΠ΅Π³ΠΎ ΡΠΎΠ±ΠΎΡΠ°:
6. ΠΡΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΏΡΠΎΠ΅ΠΊΡ ΠΡΠ±Π΅ΡΠΈΡΠ΅ ΠΎΠ΄Π½Ρ ΠΈΠ· ΡΠ΅ΠΌ Π΄Π»Ρ ΡΠ³Π»ΡΠ±Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΈΠ·ΡΡΠ΅Π½ΠΈΡ:
π§ ΠΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π½Π°Π²ΡΠΊΠΈ:
π§ Π’Π΅ΠΎΡΠ΅ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π·Π½Π°Π½ΠΈΡ:
π ΠΠ½ΠΆΠ΅Π½Π΅ΡΠ½ΠΎΠ΅ ΠΌΡΡΠ»Π΅Π½ΠΈΠ΅:
ΠΠ΄Π΅ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΠ΅ Π·Π½Π°Π½ΠΈΡ:
Π‘Π»Π΅Π΄ΡΡΡΠΈΠ΅ ΡΠ°Π³ΠΈ Π² ΠΎΠ±ΡΡΠ΅Π½ΠΈΠΈ:
ΠΡ Π·Π°Π²Π΅ΡΡΠΈΠ»ΠΈ ΠΊΡΡΡ ΠΌΠΎΠ±ΠΈΠ»ΡΠ½ΠΎΠΉ ΡΠΎΠ±ΠΎΡΠΎΡΠ΅Ρ Π½ΠΈΠΊΠΈ!
Π‘Π΅Π³ΠΎΠ΄Π½Ρ Π²Ρ ΡΠΎΠ·Π΄Π°Π»ΠΈ ΡΠΎΠ±ΠΎΡΠ°, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΠΎΠΆΠ΅Ρ:
ΠΡΠΎ Π½Π΅ ΠΊΠΎΠ½Π΅Ρ, Π° ΡΠΎΠ»ΡΠΊΠΎ Π½Π°ΡΠ°Π»ΠΎ Π²Π°ΡΠ΅Π³ΠΎ ΠΏΡΡΠΈ Π² ΠΌΠΈΡΠ΅ ΡΠΎΠ±ΠΎΡΠΎΡΠ΅Ρ Π½ΠΈΠΊΠΈ!
ΠΡΠΎΠ΄ΠΎΠ»ΠΆΠ°ΠΉΡΠ΅ ΠΈΠ·ΡΡΠ°ΡΡ, ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΠΎΠ²Π°ΡΡ ΠΈ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ. ΠΡΠ΄ΡΡΠ΅Π΅ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΠΉ Π² Π²Π°ΡΠΈΡ ΡΡΠΊΠ°Ρ ! π€β¨
ΠΠ½Π»Π°ΠΉΠ½-ΠΊΡΡΡΡ:
ΠΠ½ΠΈΠ³ΠΈ Π΄Π»Ρ ΡΠ³Π»ΡΠ±Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΈΠ·ΡΡΠ΅Π½ΠΈΡ:
Π‘ΠΈΠΌΡΠ»ΡΡΠΎΡΡ:
Π€ΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊΠΈ:
ΠΡΠ·Ρ Ρ ΡΠΈΠ»ΡΠ½ΡΠΌΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°ΠΌΠΈ ΠΏΠΎ ΡΠΎΠ±ΠΎΡΠΎΡΠ΅Ρ Π½ΠΈΠΊΠ΅:
ΠΠ»ΠΈΠΌΠΏΠΈΠ°Π΄Ρ ΠΈ ΡΠΎΡΠ΅Π²Π½ΠΎΠ²Π°Π½ΠΈΡ:
Π£Π΄Π°ΡΠΈ Π² Π²Π°ΡΠΈΡ Π±ΡΠ΄ΡΡΠΈΡ ΡΠΎΠ±ΠΎΡΠΎΡΠ΅Ρ Π½ΠΈΡΠ΅ΡΠΊΠΈΡ ΠΏΡΠΎΠ΅ΠΊΡΠ°Ρ ! ππ€β¨