Automatické autíčko: Rozdiel medzi revíziami
Z SensorWiki
(→Analýza a opis riešenia) |
(→Analýza a opis riešenia) |
||
(10 medziľahlých úprav od rovnakého používateľa nie je zobrazených.) | |||
Riadok 17: | Riadok 17: | ||
'''Literatúra:''' | '''Literatúra:''' | ||
− | * [http://ap.urpi.fei.stuba.sk/sensorwiki/index.php/Acrob_technical_description Dokumentácia k | + | * [http://ap.urpi.fei.stuba.sk/sensorwiki/index.php/Acrob_technical_description Dokumentácia k autíčku] |
* [http://www.humanbenchmark.com/tests/reactiontime/index.php Vyskúšajte si zmerať reakciu on-line] | * [http://www.humanbenchmark.com/tests/reactiontime/index.php Vyskúšajte si zmerať reakciu on-line] | ||
'''Popis autíčka''' | '''Popis autíčka''' | ||
Riadok 25: | Riadok 25: | ||
== Analýza a opis riešenia == | == Analýza a opis riešenia == | ||
− | + | Ako teda autíčko funguje? Úlohu sledovania čiary zabezpečujú tri IR senzory, ktoré fungujú na princípe odrazenia sa signálu z IR led diódy do Photo diódy. Ak je podklad pod autíčkom čierny, tak sa od podkladu signál neodrazí a Photo dióda ho nezachytí. Akonáhle ale autíčko prejde mimo jeho stanovenej dráhy (mimo čiernej čiary) tak je naprogramované najprv zotrvať sekundu na jeho mieste a potom vybrať si smer rovno alebo pravý, ľavý. Pričom vždy jeden z týchto smerov ho navedie naspäť na dráhu. | |
[[Súbor:IR senzorw.jpg|600px|thumb|center|Prinip fungovania IR senzoru.]] | [[Súbor:IR senzorw.jpg|600px|thumb|center|Prinip fungovania IR senzoru.]] | ||
− | |||
− | + | Postup ako sa robot vracia späť na dráhu je jednoduchý. V našom funguje aj tak že vedia obe ľavé kolesa sa otáčať jedným smerom a kolesa vpravo do protismeru takže je veľmi efektívny pri otáčaní a zatáčaní. | |
− | + | [[Súbor:funkcia.png|600px|thumb|center|Prinip fungovania sledovania čiary.]] | |
− | [[Súbor: | + | Schéma zapojenia autíčka: Štyri motory sú napojene na napäťový menič L298N, ktorý rozdeľuje napätie do motorčekov. Je napájaný na 12V do arduina. Tri IR senzory sú potom napojené do PINOV 2,4,10. |
+ | |||
+ | [[Súbor:schemar.png|600px|thumb|center|Schéma zapojenia autíčka sledujúceho čiernu čiaru.]] | ||
=== Algoritmus a program === | === Algoritmus a program === | ||
− | + | Zdrojový kód do autíčka v prostredí AVR | |
Riadok 46: | Riadok 47: | ||
<tab name="AVR C-code"><source lang="c++" style="background: LightYellow;"> | <tab name="AVR C-code"><source lang="c++" style="background: LightYellow;"> | ||
#include <avr/io.h> | #include <avr/io.h> | ||
+ | #include <avr/interrupt.h> | ||
+ | #include <util/delay.h> | ||
+ | |||
+ | // Line Tracking IO define | ||
+ | #define LT_R !(PIND & (1 << PD2)) | ||
+ | #define LT_M !(PIND & (1 << PD4)) | ||
+ | #define LT_L !(PINB & (1 << PB2)) | ||
+ | |||
+ | #define ENA PD5 | ||
+ | #define ENB PD6 | ||
+ | #define IN1 PD7 | ||
+ | #define IN2 PB0 | ||
+ | #define IN3 PB1 | ||
+ | #define IN4 PB3 | ||
+ | |||
+ | #define carSpeed 82 | ||
+ | #define otocka 180 | ||
+ | #define STOJ 250 | ||
+ | |||
+ | volatile unsigned long millis_count = 0; | ||
+ | |||
+ | ISR(TIMER0_COMPA_vect) { | ||
+ | millis_count++; | ||
+ | } | ||
+ | |||
+ | void forward() { | ||
+ | OCR0A = carSpeed; | ||
+ | OCR0B = carSpeed; | ||
+ | PORTD |= (1 << IN1) | (1 << IN4); | ||
+ | PORTB &= ~((1 << IN2) | (1 << IN3)); | ||
+ | } | ||
+ | |||
+ | void Mleft() { | ||
+ | OCR0A = otocka; | ||
+ | OCR0B = otocka; | ||
+ | PORTD |= (1 << IN2) | (1 << IN4); | ||
+ | PORTB &= ~((1 << IN1) | (1 << IN3)); | ||
+ | } | ||
+ | |||
+ | void Mright() { | ||
+ | OCR0A = otocka; | ||
+ | OCR0B = otocka; | ||
+ | PORTB |= (1 << IN1) | (1 << IN3); | ||
+ | PORTD &= ~((1 << IN2) | (1 << IN4)); | ||
+ | } | ||
+ | |||
+ | void stop() { | ||
+ | OCR0A = 0; | ||
+ | OCR0B = 0; | ||
+ | PORTD &= ~((1 << IN1) | (1 << IN2) | (1 << IN4)); | ||
+ | PORTB &= ~(1 << IN3); | ||
+ | } | ||
− | + | void setup() { | |
− | + | DDRD &= ~((1 << PD2) | (1 << PD4)); // Set PD2, PD4 as inputs | |
− | + | DDRB &= ~(1 << PB2); // Set PB2 as input | |
+ | DDRD |= ((1 << ENA) | (1 << ENB) | (1 << IN1)); // Set PD5-PD7 as outputs | ||
+ | DDRB |= ((1 << IN2) | (1 << IN3) | (1 << IN4)); // Set PB0-PB1 as outputs | ||
− | + | // Initialize timer for millis() | |
− | + | TCCR0A |= (1 << WGM01); // CTC mode | |
− | / | + | OCR0A = 249; // 1ms at 16MHz |
− | + | TIMSK0 |= (1 << OCIE0A); // Enable compare match interrupt | |
+ | sei(); // Enable global interrupts | ||
+ | TCCR0B |= (1 << CS01) | (1 << CS00); // Start Timer0 with prescaler 64 | ||
− | + | // PWM setup for ENA and ENB pins (OC0A and OC0B) | |
+ | TCCR0A |= (1 << COM0A1) | (1 << COM0A0) | (1 << COM0B1) | (1 << COM0B0); // Set non-inverting mode for OC0A and OC0B | ||
+ | TCCR0A |= (1 << WGM00) | (1 << WGM01); // Fast PWM mode | ||
+ | } | ||
+ | |||
+ | int main() { | ||
+ | setup(); | ||
+ | |||
+ | while(1) { | ||
+ | if (LT_M) { | ||
+ | forward(); | ||
+ | // Reset the time when line detected | ||
+ | millis_count = 0; | ||
+ | } else if (LT_R) { | ||
+ | Mright(); | ||
+ | while (LT_R); | ||
+ | } else if (LT_L) { | ||
+ | Mleft(); | ||
+ | while (LT_L); | ||
+ | } else if (!LT_L && !LT_M && !LT_R) { | ||
+ | // If no line detected for more than 700ms | ||
+ | if (millis_count > 700) { | ||
+ | stop(); // Stop the car | ||
+ | _delay_ms(1000); // Wait for 1 second | ||
+ | if (LT_L || LT_M || LT_R) continue; // If line detected, continue | ||
+ | Mleft(); // Else, turn left | ||
+ | _delay_ms(120); // Wait for turn to complete | ||
+ | if (LT_L || LT_M || LT_R) continue; | ||
+ | Mleft(); | ||
+ | _delay_ms(100); | ||
+ | if (LT_L || LT_M || LT_R) continue; | ||
+ | Mleft(); | ||
+ | _delay_ms(100); | ||
+ | if (LT_L || LT_M || LT_R) continue; | ||
+ | Mright(); | ||
+ | _delay_ms(400); | ||
+ | stop(); | ||
+ | _delay_ms(1000); | ||
+ | if (LT_L || LT_M || LT_R) continue; | ||
+ | Mright(); | ||
+ | _delay_ms(100); | ||
+ | if (LT_L || LT_M || LT_R) continue; | ||
+ | Mright(); | ||
+ | _delay_ms(100); | ||
+ | } | ||
+ | } else { | ||
+ | forward(); | ||
+ | millis_count = 0; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return 0; | ||
} | } | ||
Riadok 72: | Riadok 180: | ||
Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]] | Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]] | ||
− | |||
=== Overenie === | === Overenie === |
Verzia zo dňa a času 21:18, 29. apríl 2024
Záverečný projekt predmetu MIPS / LS2024 - Meno Priezvisko
Automatické autíčko sledujúce čiernu čiaru
Sledovanie čiary je základnou technikou používanou v rôznych odvetviach robotiky, vrátane priemyselných robotov, autonómnych vozidiel, ale aj v domácich aplikáciách, ako sú napríklad čistiace roboty. Táto technika umožňuje vozidlám efektívne navigovať v prostredí, kde sú k dispozícii jednoduché vizuálne orientačné body, ako je napríklad čiara na zemi.
V tejto práci sa zameriame na implementáciu sledovania čiary v prostredí AVR, pričom sa budeme venovať nielen samotnému algoritmu sledovania čiary, ale aj analýze vplyvu rôznych parametrov a technických obmedzení na výkon a spoľahlivosť systému. Na základe tejto analýzy budeme schopní navrhnúť a implementovať optimalizovaný algoritmus sledovania čiary, ktorý bude schopný účinne navigovať v rôznych prostrediach a podmienkach.
Zadanie úlohy
Rozhodli sme sa pre náš záverečný projekt z MIPS vytvoriť autíčko, ktoré sleduje čiernu čiaru. Autíčko musí absolvovať celú dráhu zloženú z rôznych zatáčok a prerušení tejto čiary, ktoré musí zvládnuť.
Literatúra:
Popis autíčka
Obsah
Analýza a opis riešenia
Ako teda autíčko funguje? Úlohu sledovania čiary zabezpečujú tri IR senzory, ktoré fungujú na princípe odrazenia sa signálu z IR led diódy do Photo diódy. Ak je podklad pod autíčkom čierny, tak sa od podkladu signál neodrazí a Photo dióda ho nezachytí. Akonáhle ale autíčko prejde mimo jeho stanovenej dráhy (mimo čiernej čiary) tak je naprogramované najprv zotrvať sekundu na jeho mieste a potom vybrať si smer rovno alebo pravý, ľavý. Pričom vždy jeden z týchto smerov ho navedie naspäť na dráhu.
Postup ako sa robot vracia späť na dráhu je jednoduchý. V našom funguje aj tak že vedia obe ľavé kolesa sa otáčať jedným smerom a kolesa vpravo do protismeru takže je veľmi efektívny pri otáčaní a zatáčaní.
Schéma zapojenia autíčka: Štyri motory sú napojene na napäťový menič L298N, ktorý rozdeľuje napätie do motorčekov. Je napájaný na 12V do arduina. Tri IR senzory sú potom napojené do PINOV 2,4,10.
Algoritmus a program
Zdrojový kód do autíčka v prostredí AVR
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
// Line Tracking IO define
#define LT_R !(PIND & (1 << PD2))
#define LT_M !(PIND & (1 << PD4))
#define LT_L !(PINB & (1 << PB2))
#define ENA PD5
#define ENB PD6
#define IN1 PD7
#define IN2 PB0
#define IN3 PB1
#define IN4 PB3
#define carSpeed 82
#define otocka 180
#define STOJ 250
volatile unsigned long millis_count = 0;
ISR(TIMER0_COMPA_vect) {
millis_count++;
}
void forward() {
OCR0A = carSpeed;
OCR0B = carSpeed;
PORTD |= (1 << IN1) | (1 << IN4);
PORTB &= ~((1 << IN2) | (1 << IN3));
}
void Mleft() {
OCR0A = otocka;
OCR0B = otocka;
PORTD |= (1 << IN2) | (1 << IN4);
PORTB &= ~((1 << IN1) | (1 << IN3));
}
void Mright() {
OCR0A = otocka;
OCR0B = otocka;
PORTB |= (1 << IN1) | (1 << IN3);
PORTD &= ~((1 << IN2) | (1 << IN4));
}
void stop() {
OCR0A = 0;
OCR0B = 0;
PORTD &= ~((1 << IN1) | (1 << IN2) | (1 << IN4));
PORTB &= ~(1 << IN3);
}
void setup() {
DDRD &= ~((1 << PD2) | (1 << PD4)); // Set PD2, PD4 as inputs
DDRB &= ~(1 << PB2); // Set PB2 as input
DDRD |= ((1 << ENA) | (1 << ENB) | (1 << IN1)); // Set PD5-PD7 as outputs
DDRB |= ((1 << IN2) | (1 << IN3) | (1 << IN4)); // Set PB0-PB1 as outputs
// Initialize timer for millis()
TCCR0A |= (1 << WGM01); // CTC mode
OCR0A = 249; // 1ms at 16MHz
TIMSK0 |= (1 << OCIE0A); // Enable compare match interrupt
sei(); // Enable global interrupts
TCCR0B |= (1 << CS01) | (1 << CS00); // Start Timer0 with prescaler 64
// PWM setup for ENA and ENB pins (OC0A and OC0B)
TCCR0A |= (1 << COM0A1) | (1 << COM0A0) | (1 << COM0B1) | (1 << COM0B0); // Set non-inverting mode for OC0A and OC0B
TCCR0A |= (1 << WGM00) | (1 << WGM01); // Fast PWM mode
}
int main() {
setup();
while(1) {
if (LT_M) {
forward();
// Reset the time when line detected
millis_count = 0;
} else if (LT_R) {
Mright();
while (LT_R);
} else if (LT_L) {
Mleft();
while (LT_L);
} else if (!LT_L && !LT_M && !LT_R) {
// If no line detected for more than 700ms
if (millis_count > 700) {
stop(); // Stop the car
_delay_ms(1000); // Wait for 1 second
if (LT_L || LT_M || LT_R) continue; // If line detected, continue
Mleft(); // Else, turn left
_delay_ms(120); // Wait for turn to complete
if (LT_L || LT_M || LT_R) continue;
Mleft();
_delay_ms(100);
if (LT_L || LT_M || LT_R) continue;
Mleft();
_delay_ms(100);
if (LT_L || LT_M || LT_R) continue;
Mright();
_delay_ms(400);
stop();
_delay_ms(1000);
if (LT_L || LT_M || LT_R) continue;
Mright();
_delay_ms(100);
if (LT_L || LT_M || LT_R) continue;
Mright();
_delay_ms(100);
}
} else {
forward();
millis_count = 0;
}
}
return 0;
}
#include <avr/io.h>
void adc_init(void); // A/D converter initialization
unsigned int adc_read(char a_pin);
Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x zdrojaky.zip:
Zdrojový kód: zdrojaky.zip
Overenie
Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia. Na konci uvádzame fotku záverečnej obrazovky pred resetom. Vypísaný je tu priemerný čas a najlepší čas.
Video:
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.