Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

Robot Pengikut Baris - Kontrol PID - Penyiapan Android

Komponen dan persediaan

Arduino Nano R3
× 1
Sensor RedBot SparkFun - Pengikut Garis
× 1
Modul Sensor Pengikut Jalur Jalur Inframerah 4CH TCRT5000
× 1
Perangkat Android
× 1
tempat baterai 4xAA
× 2
Servo Rotasi Berkelanjutan RobotGeek
× 2

Aplikasi dan layanan online

Arduino IDE
MIT App Inventor 2

Tentang proyek ini

Tujuan dari proyek ini adalah untuk membangun Robot Line Follower dengan kontrol PID. Kami juga akan menggunakan perangkat Android untuk dengan mudah mengatur parameter kontrol utama untuk penyetelan yang lebih baik dan cepat.

Proyek ini adalah yang pertama dari 2 bagian proyek yang lebih kompleks di mana tujuan saya adalah untuk mengeksplorasi potensi Robot Pengikut Garis. Bagian 2 :Robot Pemecah Labirin, menggunakan Artificial Intelligence dengan Arduino, robot akan menjelajahi dan memecahkan Mazes, menggunakan teknik kecerdasan buatan sederhana.

Di bawah ini adalah video yang memperlihatkan robot mengikuti rangkaian garis:

Langkah 1:Daftar Bahan

Daftar bahan yang dibutuhkan sangat sederhana dan robot final sangat murah (sekitar $75,00):

Body (dapat disesuaikan dengan kebutuhan Anda):

  • 2 Kotak kayu (80X80mm)
  • 3 Klip pengikat
  • 2 Roda kayu (diameter:50mm)
  • 1 Kastor bola
  • 9 Pita elastis
  • Strip bingkai Perintah 3M
  • Sambungan plastik untuk pemasangan sensor
  • BreadBoard dan kabel
  • 2 set Baterai Hidrida 4XNi-Metal (setiap set 5V)
  • 2 X SM-S4303R Rotasi Terus Menerus Servo Plastik 360 Derajat
  • Arduino Nano
  • Modul Bluetooth HC-06
  • 5 X Sensor garis (Modul Sensor Pengikut Jalur Inframerah 4CH TCRT5000 + 1 sensor Track independen)
  • 1 LED
  • 1 tombol

Langkah 2:Menyetel motor

Untuk motor, 2 servos kontinu (SM-S4303R) digunakan. Mereka akan "direkatkan" bersama-sama membuat blok tunggal dan padat seperti yang Anda lihat di foto (gunakan strip Perintah 3M, lem atau selotip ganda). Servo tersebut akan berjalan pada kecepatan tertentu, ditentukan oleh lebar pulsa yang diterima pada input datanya. Untuk servo khusus ini, lebar pulsa berubah dari 1,0 ms (1.000 mikrodetik) menjadi 2,0 ms (2.000 mikrodetik). Servo lain dapat bekerja dengan lebar pulsa yang berbeda.

Melihat secara detail:

  • Sebuah pulsa 1,5 ms akan memposisikan servo pada posisi netral, atau ”berhenti”.
  • Denyut 1,0 ms akan memerintahkan servo ke kecepatan penuh (sekitar 70 RPM) dalam satu arah
  • Denyut dengan kecepatan penuh 2,0 mdtk ke arah yang berlawanan.
  • Pulsa antara 1.0 dan 1.5ms atau 1.5ms dan 2.0ms, akan menghasilkan kecepatan yang proporsional.

Setelah Anda memiliki kedua servos yang terhubung secara fisik, ikuti rangkaian gambar di atas untuk mendapatkan sumbernya (eksternal 5V atau 6V) dan berikan sinyal Arduino:

  • Servo Kiri:Arduino Pin 5
  • Servo Kanan:Arduino Pin 3

Setelah semua terhubung, hal pertama yang harus dilakukan adalah mengirim pulsa 1,5 ms untuk memverifikasi apakah motor "berhenti" (tidak berjalan). Jika tidak, servo harus disetel hingga berhenti penuh (cari baut kuning, di bawah servo).

CATATAN :Jika servo Anda tidak memiliki penyesuaian fisik ini, coba ubah parameter "1500" mikrodetik di dalam fungsi (naik atau turun) hingga Anda mendapatkan titik penuh.

Kode Arduino di bawah ini dapat melakukan pekerjaan itu:

#include  // Pustaka Servo Servo kiriServo;Servo kananServo;Pengaturan kosong(){ leftServo.attach(5); kananServo.attach(3); leftServo.writeMicroseconds(1500); rightServo.writeMicroseconds(1500);}void loop(){} 

Langkah 3:Pasang Bodi dan Motor untuk uji gerakan

  • Dengan strip bingkai Perintah 3M, pasang 2 Servo ke salah satu potongan kayu persegi.
  • Perbaiki kayu kuadrat ke-2 ke yang di atas menggunakan Binder Clips. Sesuaikan panjang platform dengan kebutuhan Anda.
  • Perbaiki Kastor Bola menggunakan Klip Pengikat.
  • Suplai Daya untuk motor akan berasal dari salah satu baterai 5V. Set baterai ini akan dipasang di antara papan tempat memotong roti dan rangka bodi.
  • Hubungkan Baterai untuk digunakan dengan servos:Kiri salah satu jaringan listrik lateral khusus untuk sumber servos
  • Hubungkan Arduino Nano ke papan tempat memotong roti
  • Hubungkan GND Jaringan Listrik ke Arduino GND.
  • Hubungkan Servo ke Arduino:KIRI ==> Pin 5; KANAN ==> Pin 3
  • Hubungkan LED ke Arduino Pin 13
  • Hubungkan tombol ke Arduino Pin 9

Perhatikan bahwa karena cara servo dipasang (berlawanan), rentang kecepatannya adalah:

  • Kecepatan maju Servo Kanan berubah dari 1.500us (berhenti) menjadi 2.000us (kecepatan penuh)
  • Kecepatan maju Servo Kiri berubah dari 1.500us (berhenti) menjadi 1.000 (kecepatan penuh)

LED eksternal ditambahkan ke pin13, untuk sinyalisasi dan tujuan pengujian (Anda dapat menggunakan LED Arduino internal, bukan eksternal jika Anda mau, tetapi pertimbangkan bahwa akan sulit untuk melihatnya di tengah kabel).

Juga tombol terhubung ke pin 9. Tombol ini sangat berguna untuk tujuan pengujian dan untuk memulai robot.

Misalnya:

sementara(digitalRead(buttonPin)) { }motorTurn (KIRI, 500);motorTurn (KANAN, 500); 

Perhatikan bahwa 2 baris yang akan memerintahkan Robot untuk belok KIRI, tunggu 500ms dan belok KANAN hanya akan terjadi setelah Anda menekan tombol (buttonPin =0). Sebelum itu, program akan dihentikan dalam infinite loop.

Kode di bawah ini dapat digunakan sebagai dasar untuk tes motor lengkap (Maju, Mundur, Berhenti Penuh, Belok Kiri, Belok Kanan). Jika perlu, Anda harus menyesuaikan penundaan untuk sudut belok yang diperlukan tergantung pada motor Anda (juga, terkadang nilai pulsa kiri dan kanan harus sedikit berbeda untuk mengkompensasi kekurangan keseimbangan motor.

FDDQRQOIN4TTVY0.ino

Langkah 4:Modul Bluetooth (opsional)

Modul Bluetooth HC-06 harus dipasang di papan tempat memotong roti seperti yang ditunjukkan pada gambar. SoftSerial perpustakaan Arduino akan digunakan.

Di bawah koneksi pin HC-06:

  • Pin Tx ke Arduino pin 10 (Rx)
  • Pin RX ke Arduino pin 11 (Tx)
  • VCC/GND ke Arduino 5V/GND

Robot akan bekerja dengan atau tanpa Bluetooth. Kode dibuat sedemikian rupa sehingga jika Anda tidak mengaktifkan BT, parameter default akan digunakan oleh robot. Jadi, jangan khawatir jika Anda memilih untuk tidak menginstal modul HC-06, kodenya masih akan berfungsi dengan baik. Di bagian terakhir dari tutorial ini, saya akan mengeksplorasi cara menggunakan Aplikasi Android untuk mengirim data untuk penyetelan parameter robot yang lebih baik dan/atau memindahkan robot dalam mode manual. Saya akan meninggalkan penggunaan Bluetooth dan Aplikasi sebagai opsional jika seseorang ingin menjelajahi lebih banyak penggunaan Robot Pengikut Garis untuk kompetisi, misalnya.

Langkah 5:Menambahkan Sensor Garis

Hubungkan kabel ke pin Arduino seperti di bawah ini:

  • Sensor 0 =12
  • Sensor 1 =18
  • Sensor 2 =17
  • Sensor 3 =16
  • Sensor 4 =19
  • Perbaiki 5 sensor pada batang plastik seperti yang ditunjukkan pada foto
  • Disarankan untuk memberi label pada sensor untuk tujuan pengujian. Nama sensor berubah dari "0" (lebih ke kiri) ke "4" (lebih ke kanan)
  • Jalankan kabel di bawah rangka, menggunakan karet gelang untuk mengencangkannya. Berhati-hatilah agar tidak tercampur dengan roda atau Kastor.
  • Perbaiki set kedua baterai 5V dan hubungkan ke Arduino Vin.

Dalam kasus saya, saya menggunakan modul dengan 4 sensor terintegrasi + 1 ekstra. Semuanya kompatibel. Untuk mempermudah, dalam diagram saya menyertakan 5 sensor yang berdiri sendiri yang terhubung bersama. Hasil akhirnya sama di kedua konfigurasi.

Langkah 6:Menerapkan Logika Sensor IR

Sensor IR terdiri dari LED IR individu dan Fotodioda IR. Cahaya IR yang dipancarkan oleh LED mengenai permukaan dan dipantulkan kembali ke Fotodioda IR. Fotodioda kemudian menghasilkan tegangan output sebanding dengan tingkat reflektansi permukaan (nilai yang lebih tinggi untuk "permukaan terang" dan lebih rendah untuk "permukaan hitam/gelap").

Dalam hal sensor yang digunakan, sirkuit terpadu pada modul menghasilkan sinyal digital sederhana sebagai keluaran (TINGGI:Gelap; RENDAH:Terang). Potensiometer yang dipasang di modul (lihat foto) akan menyesuaikan tingkat cahaya yang benar untuk dianggap "gelap" atau "terang". Ini bekerja dengan cara bahwa ketika warna cahaya yang dipantulkan adalah hitam/gelap, tingkat digital TINGGI ("1") dihasilkan pada outputnya dan RENDAH ("0") untuk warna lain yang lebih terang. Di sini saya menggunakan modul terintegrasi dengan 4 sensor dan dan modul tambahan dengan satu sensor (bentuk berbeda, tetapi logika yang sama). Kombinasi tersebut merupakan susunan dari 5 sensor yang menurut saya bagus untuk kontrol yang bagus dan mulus, seperti yang dijelaskan di bawah ini.

Susunan 5 sensor dipasang sedemikian rupa sehingga jika hanya satu sensor yang dipusatkan sehubungan dengan garis hitam, hanya sensor tertentu yang akan menghasilkan TINGGI. Di sisi lain, jarak antar sensor harus dihitung untuk memungkinkan 2 sensor dapat menutupi lebar penuh garis hitam secara bersamaan, menghasilkan juga TINGGI pada kedua sensor (lihat gambar di atas).

Output array sensor yang mungkin saat mengikuti garis adalah:

  • 0 0 0 0 1
  • 0 0 0 1 1
  • 0 0 0 1 0
  • 0 0 1 1 0
  • 0 0 1 0 0
  • 0 1 1 0 0
  • 0 1 0 0 0
  • 1 1 0 0 0
  • 1 0 0 0 0

Memiliki 5 sensor, memungkinkan pembuatan "variabel kesalahan" yang akan membantu mengontrol posisi robot melewati garis, seperti yang ditunjukkan di bawah.

Mari kita pertimbangkan bahwa kondisi optimal adalah ketika robot berada di tengah, memiliki garis tepat di bawah "sensor tengah" (Sensor 2). Output dari array akan menjadi:0 0 1 0 0 dan dalam situasi ini, "kesalahan" akan menjadi "nol". Jika robot mulai bergerak ke kiri (garis "sepertinya bergerak" ke kanan") kesalahan harus meningkat dengan sinyal positif. Jika robot mulai bergerak ke kanan (garis "sepertinya bergerak" ke kiri"), di dengan cara yang sama, kesalahan harus meningkat, tetapi sekarang dengan sinyal negatif.

Variabel kesalahan, yang terkait dengan status sensor adalah:

0 0 1 0 0 ==> Kesalahan =0

  • 0 0 0 0 1 ==> Kesalahan =4
  • 0 0 0 1 1 ==> Kesalahan =3
  • 0 0 0 1 0 ==> Kesalahan =2
  • 0 0 1 1 0 ==> Kesalahan =1
  • 0 1 1 0 0 ==> Kesalahan =-1
  • 0 1 0 0 0 ==> Kesalahan =-2
  • 1 1 0 0 0 ==> Kesalahan =-3
  • 1 0 0 0 0 ==> Kesalahan =-4

Melihat kode Arduino, masing-masing sensor akan ditentukan dengan nama tertentu (pertimbangkan bahwa Sensor Line Follow lebih ke Kiri harus diberi label "0"):

const int lineFollowSensor0 =12;const int lineFollowSensor1 =18;const int lineFollowSensor2 =17;const int lineFollowSensor3 =16;const int lineFollowSensor4 =19; 

Untuk menyimpan nilai setiap sensor, variabel array akan dibuat:

int LFSensor[5]={0, 0, 0, 0, 0}; 

Setiap posisi larik akan terus diperbarui dengan output dari masing-masing sensor:

LFSensor[0] =digitalRead(lineFollowSensor0);LFSensor[1] =digitalRead(lineFollowSensor1);LFSensor[2] =digitalRead(lineFollowSensor2);LFSensor[3] =digitalRead(lineFollowSensor3);LFSensor[4] =digitalRead(lineFollowSensor4); 

Memiliki nilai masing-masing sensor, logika harus diimplementasikan untuk menghasilkan variabel kesalahan:

if((LFSensor[0]==0 )&&(LFSensor[1]==0 )&&(LFSensor[2]==0 )&&(LFSensor[3]==0 )&&(LFSensor[2]==0 )&&(LFSensor[3]==0 )&&(LFSensor [4]==1 )) kesalahan =4;else if((LFSensor[0]==0 )&&(LFSensor[1]==0 )&&(LFSensor[2]==0 )&&(LFSensor[3] ==1 )&&(LFSensor[4]==1 )) kesalahan =3; else if((LFSensor[0]==0 )&&(LFSensor[1]==0 )&&(LFSensor[2]==0 )&&(LFSensor[3]==1 )&&(LFSensor[4]==0 )) kesalahan =2;else if((LFSensor[0]==0 )&&(LFSensor[1]==0 )&&(LFSensor[2]==1 )&&(LFSensor[3]==1 )&&(LFSensor[4]==0 )) kesalahan =1;else if((LFSensor[0]==0 )&&(LFSensor[1]==0 )&&(LFSensor[2]==1 )&&(LFSensor[ 3]==0 )&&(LFSensor[4]==0 )) kesalahan =0;else if((LFSensor[0]==0 )&&(LFSensor[1]==1 )&&(LFSensor[2]==1 )&&(LFSensor[3]==0 )&&(LFSensor[4]==0 )) kesalahan =- 1;else if((LFSensor[0]==0 )&&(LFSensor[1]==1 )&&(LFSensor[2]==0 )&&(LFSensor[3]==0 )&&(LFSensor[4]==0 )) kesalahan =-2;else if((LFSensor[0]==1 )&&(LFSensor[1]==1 )&&(LFSensor[2]==0 )&&(LFSensor[3]==0 )&&(LFSensor[4]==0 )) error =-3;else if((LFSensor [0]==1 )&&(LFSensor[1]==0 )&&(LFSensor[2]==0 )&&(LFSensor[3]==0 )&&(LFSensor[4]==0 )) kesalahan =-4; 

Langkah 7:Mengontrol arah (Kontrol Proporsional - P)

Sempurna! Pada titik ini, Robot kami dirakit dan beroperasi. Anda harus melakukan beberapa tes dasar dengan motor, membaca output sensor dan mengujinya melalui saluran. Apa yang hilang adalah "otak" yang sebenarnya, langkah pertama dari "kecerdasan buatan". Kami akan mendapatkan ini, menerapkan logika kontrol yang akan menjamin bahwa Robot akan tetap mengikuti garis.

Kontrol Proporsional Sederhana:

Misalkan Robot berjalan di atas garis dan output Sensor Array adalah:"0 0 1 0 0 " . Kesalahan koresponden adalah "0". Dalam situasi ini, kedua motor harus berjalan maju dengan kecepatan konstan.

Misalnya:

Mendefinisikan variabel:iniMotorSpeed ​​=250 ; berarti servo KIRI akan menerima pulsa 1.250us dan servo KANAN 1.750us. Dengan parameter tersebut, Robot akan bergerak maju dengan kecepatan setengah. Ingat bahwa kecepatan maju servo KANAN akan berkisar dengan panjang pulsa dari 1.500 us (berhenti) hingga 2.000 us (kecepatan penuh) dan servo KIRI dari 1.500 us (berhenti) hingga 1.000 us (kecepatan penuh).

rightServo.writeMicroseconds(1500 + iniMotorPower);leftServo.writeMicroseconds(1500 - iniMotorPower); 

Misalkan sekarang Robot didorong ke kiri (seperti "GARIS ke kanan") dan menutupi juga sensor 3. Output Array akan menjadi:"0 0 1 1 0 " dan kesalahan =1 . Dalam situasi ini yang Anda butuhkan adalah memutar Robot ke kanan. Untuk melakukan itu, Anda harus mengurangi kecepatan servo KANAN yang berarti mengurangi panjang pulsa. Juga, kecepatan servo KIRI harus meningkat, yang berarti mengurangi panjang pulsa servo KIRI. Untuk melakukan itu, kita perlu mengubah fungsi kontrol motor:

rightServo.writeMicroseconds(1500 + iniMotorPower - kesalahan); ==> Kesalahan positif:kurangi velocityleftServo.writeMicroseconds(1500 - iniMotorPower - error); ==> Kesalahan positif:tingkatkan kecepatan 

Logika di atas benar, tetapi mudah dipahami bahwa menambah atau mengurangi "1" mikrodetik pada panjang pulsa tidak akan menghasilkan koreksi yang diperlukan pada waktu yang realistis. Adalah intuitif bahwa angka yang akan ditambahkan atau dikurangi harus lebih besar, misalnya 50, 100, dll. Untuk mendapatkannya, "kesalahan" harus dikalikan dengan konstanta (sebut saja "K"). Setelah pengaruh konstanta ini sebanding dengan kesalahan, kita akan menamakannya "Konstanta Proporsional:Kp" .

Fungsi motoriknya adalah:

int Kp =50;rightServo.writeMicroseconds(1500 + iniMotorPower - Kp*error);leftServo.writeMicroseconds(1500 - iniMotorPower - Kp*error); 

Kita dapat melanjutkan apa yang akan terjadi dengan motor seperti yang ditunjukkan di bawah ini:

  • Array Sensor:0 0 1 0 0 ==> kesalahan =0 ==> Panjang pulsa Servo Kanan =1,750us ==> Panjang pulsa Servo Kiri =1,250us (kedua motor pada kecepatan yang sama)
  • Array Sensor:0 0 1 1 0 ==> kesalahan =1 ==> Panjang pulsa Servo Kanan =1.700us (lebih lambat) ==> Panjang pulsa Servo Kiri =1.200us (lebih cepat)

Jika situasinya berlawanan dan Robot didorong ke kanan, kesalahannya akan menjadi "negatif" dan kecepatan servo harus berubah:

  • Array Sensor:0 0 1 0 0 ==> kesalahan =0 ==> Panjang pulsa Servo Kanan =1,750us ==> Panjang pulsa Servo Kiri =1,250us (kedua motor pada kecepatan yang sama)
  • Array Sensor:0 1 1 0 0 ==> kesalahan =-1 ==> Panjang pulsa Servo Kanan =1.800us (lebih cepat) ==> Panjang pulsa Servo Kiri =1.300us (lebih lambat)

Pada titik ini jelas bahwa semakin banyak Robot didorong ke satu sisi, semakin besar kesalahannya dan semakin cepat ia harus kembali ke tengah. Kecepatan dengan Robot akan bereaksi terhadap kesalahan akan sebanding dengan itu. Ini disebut "Kontrol Proporsional" , yaitu komponen "P" dari jaringan kontrol yang lebih kompleks, PDI (Proporsional, Derivatif, Integral).

Langkah 8:Kontrol PID (opsional)

Jika Anda ingin melompat ke bagian ini, tidak apa-apa. Anda dapat tetap dengan kontrol proporsional yang dijelaskan pada langkah terakhir, atau membakar beberapa otak untuk menerapkan sistem kontrol yang lebih kompleks di robot Anda, itu adalah pilihan Anda.

Jika Anda sudah memutuskan, ayo pergi!

PID (Proporsional, Derivatif dan Integral) adalah salah satu skema kontrol yang paling umum. Kebanyakan loop kontrol industri menggunakan beberapa rasa kontrol PID. Ada banyak cara untuk menyetel loop PID, termasuk teknik manual yang digunakan dalam contoh ini.

Pikirkan PID sebagai pegas sederhana. Sebuah pegas memiliki panjang semula, yang ketika terganggu oleh ekspansi atau kontraksi, cenderung untuk mendapatkan kembali panjang aslinya dalam waktu sesingkat mungkin. Demikian pula, algoritma PID dalam suatu sistem memiliki nilai set dari kuantitas fisik tertentu yang akan dikontrol, yang disebut ‘set point. ', yang ketika diubah karena alasan tertentu, sistem mengontrol fitur lain yang diperlukan di dalamnya, untuk kembali ke titik setel awal dalam waktu sesingkat mungkin. Kontroler PID digunakan di mana pun ada kebutuhan untuk mengontrol kuantitas fisik dan membuatnya sama dengan nilai yang ditentukan. Contoh, Pengontrol Pelayaran di mobil, Robot, Pengatur suhu, Pengatur tegangan, dll.

Bagaimana cara kerja PID?

Sistem menghitung ‘error ’, atau ‘deviasi ' dari kuantitas fisik dari titik setel, dengan mengukur nilai saat ini dari kuantitas fisik tersebut menggunakan sensor. Untuk kembali ke titik setel, 'error ini ' harus diminimalkan, dan idealnya dibuat sama dengan nol. Juga, proses ini harus terjadi secepat mungkin. Idealnya, harus ada jeda nol dalam respons sistem terhadap perubahan titik setelnya.

Informasi lebih lanjut dapat ditemukan di banyak buku dan situs web, termasuk di sini.

Menerapkan PID

i) Istilah Kesalahan (e):

Ini sama dengan perbedaan antara titik setel dan nilai saat ini dari kuantitas yang dikendalikan. Kesalahan =set_pointcurrent_value (dalam kasus kami adalah variabel kesalahan yang didapat dari posisi Robot di atas garis

ii) Suku Proporsional (P):

Istilah ini sebanding dengan kesalahannya.

P =kesalahan

Nilai ini bertanggung jawab atas besarnya perubahan yang diperlukan dalam kuantitas fisik untuk mencapai titik setel. Istilah proporsi inilah yang menentukan waktu naik loop kontrol atau seberapa cepat ia akan mencapai titik setel.

iii) Suku Integral (I):

Istilah ini adalah jumlah dari semua nilai kesalahan sebelumnya.

I =I + error

Nilai ini bertanggung jawab atas kecepatan respon sistem terhadap perubahan dari set point. Istilah integral digunakan untuk menghilangkan kesalahan keadaan tunak yang diperlukan oleh istilah proporsional. Biasanya, Robot kecil tidak menggunakan istilah integral karena kita tidak mempermasalahkan kesalahan keadaan tunak dan dapat memperumit "loop tuning ".

iv) Suku Diferensial atau Turunan (D):

Istilah ini adalah perbedaan antara kesalahan sesaat dari titik setel, dan kesalahan dari saat sebelumnya.

D =kesalahan - kesalahan sebelumnya

Nilai ini bertanggung jawab untuk memperlambat laju perubahan kuantitas fisik ketika mendekati titik setel. Istilah turunan digunakan untuk mengurangi overshoot atau seberapa banyak sistem harus "over correct ".

Persamaan:

Nilai PID =(Kp*P) + (Ki*I) + (Kd*D)

Di mana:

Kp adalah konstanta yang digunakan untuk memvariasikan besarnya perubahan diperlukan untuk mencapai set point. Ki adalah konstanta yang digunakan untuk memvariasikan laju perubahan harus dibawa dalam kuantitas fisik untuk mencapai titik setel. Kd adalah konstanta yang digunakan untuk memvariasikan stabilitas dari sistem.

Salah satu pendekatan untuk menyetel loop adalah Metode tentatif try-error :

Setel variabel Kd ke 0 dan menyetel istilah Kp saja terlebih dahulu. Kp dari 25 adalah tempat yang baik untuk memulai dalam kasus kami di sini. Pada langkah terakhir kami menggunakan Kp 50 yang bekerja sangat baik dengan Robot saya. Setelah robot merespons secara wajar, setel bagian turunan dari loop kontrol (Kd ). Pertama atur nilai Kp dan Kd masing-masing menjadi 1/2 dari nilai Kp. Misalnya, jika respons robot masuk akal dengan Kp =50, maka atur Kp =25 dan Kd =25 untuk memulai. Tingkatkan gain Kd (derivatif) untuk mengurangi overshoot, kurangi jika robot menjadi tidak stabil.

  • Jika robot bereaksi terlalu lambat, naikkan nilainya.
  • Jika robot tampaknya bereaksi cepat menjadi tidak stabil, kurangi nilainya.

Satu komponen loop lain yang perlu dipertimbangkan adalah Sampel/Rasio Loop actual yang sebenarnya . Mempercepat parameter ini atau memperlambatnya dapat membuat perbedaan yang signifikan dalam kinerja robot. Ini disetel oleh delay pernyataan yang Anda miliki dalam kode Anda. Ini adalah metode tentatif Try-error untuk mendapatkan hasil yang optimal.

Berdasarkan pendekatan di atas, fungsi di bawah ini diimplementasikan:

void countPID(){ P =error; saya =saya + kesalahan; D =error-previousError; Nilai PID =(Kp*P) + (Ki*I) + (Kd*D); sebelumnyaError =kesalahan;} 

Konstanta Kp sederhana yang digunakan pada langkah terakhir akan diganti untuk PIDvalue yang lebih lengkap ini :

void motorPIDcontrol(){ int leftMotorSpeed ​​=1500 - iniMotorPower - PIDvalue; int rightMotorSpeed ​​=1500 + iniMotorPower - nilai PID; leftServo.writeMicroseconds(leftMotorSpeed); rightServo.writeMicroseconds(rightMotorSpeed);} 

Tetapi perhatikan bahwa jika Anda memiliki Kd dan Ki =0 , nilai PID hanya Kp*error yang digunakan pada langkah terakhir.

Langkah 9:Kode terakhir

Pada langkah ini, Robot dapat mengikuti putaran konstan dan akan melakukannya tanpa berhenti. Program loopnya adalah:

void loop(){ readLFSsensors(); // baca sensor, simpan nilai di Sensor Array dan hitung "error" hitungPID(); motorPIDcontrol();} 

Tetapi untuk operasi yang lebih lengkap dan nyata, Penting untuk menambahkan setidaknya beberapa dasar "perintah " selesai "dengan baris ". Misalnya, mari kita perkenalkan variabel baru:"mode ". Kami akan mendefinisikan 3 status untuk variabel ini:

Modus:

  • #define DIHENTIKAN 0
  • #define FOLLOWING_LINE 1
  • #define NO_LINE 2

Jika semua sensor menemukan garis hitam, output Sensor Array akan menjadi:1 1 1 1 1. Dalam kondisi ini, kita dapat mendefinisikan mode sebagai "STOPPED" dan Robot harus melakukan "full stop ".

if((LFSensor[0]==1 )&&(LFSensor[1]==1 )&&(LFSensor[2]==1 )&&(LFSensor[3]==1 )&&(LFSensor[2]==1 )&&(LFSensor[3]==1 )&&(LFSensor [4]==1 )) { mode =DIHENTIKAN;} 

Situasi umum lainnya dengan Robot Garis Pengikut adalah di mana ia menemukan "tanpa garis ", atau output Sensor Array adalah:0 0 0 0 0. Dalam hal ini kita dapat memprogramnya untuk berbalik 180o atau berbelok ke sudut kecil sampai garis ditemukan dan kondisi Line Follow normal dilanjutkan.

else if((LFSensor[0]==0 )&&(LFSensor[1]==0 )&&(LFSensor[2]==0 )&&(LFSensor[3]==0 )&&( LFSensor[4]==0 )) { mode =NO_LINE;} 

loop () yang lengkap akan menjadi:

void loop() { readLFSsensors(); sakelar (mode) { kasus DIHENTIKAN:motorStop(); merusak; kasus NO_LINE:motorStop(); putaran motor(KIRI, 180); merusak; kasus FOLLOWING_LINE:hitungPID(); motorPIDkontrol(); merusak; }} 

Kode akhir yang sebenarnya akan mengintegrasikan beberapa logika tambahan dan juga beberapa variabel yang harus diinisialisasi, dll. Selama penjelasan di atas saya mengabaikannya untuk kesederhanaan, tetapi semuanya harus jelas melihat kode akhir.

Di bawah ini adalah Kode Arduino terakhir:

FUXCUEAIN699SZC.ino FLD2J3KIN699SZF.h FOFYXFZIN699SZT.ino FMPX9KJIN699SZU.ino FFE5AZ3IN699T06.ino

Langkah 10:Menyetel kontrol PID menggunakan Aplikasi Android

In the previous code, you can find at "robotDefines.h " tab the following definitions for the constants to be used with the PID control:

float Kp=50;float Ki=0;float Kd=0; 

As explained at previous step, the best way to define the correct constant to be used with a PID controller is using the "Try-error" methodology. The bad side of that is that you must re-compile the program each time that you must change it. One way to speed-up the process is to use the Android App to send the constants at the "Set-Up Phase" .

I developed an Android App exclusively for that. In short there are the traditional manual commands:

  • FW, BW, Left, Right and Stop where the app will send respectively to the BT module:'f', 'b', 'l', 'r' and 's'.

Also 3 sliders were included, one for each PID constants:

  • Kd:"d/XXX" where "XXX" it is a number from 0 to 100.
  • Kp:"p/XXX"
  • Ki:"i/XXX"

An extra button was included that will work exactly as the button connected on Arduino Pin9. You can use one or the other, it does not matter.

Below you can find the .aia file that can be modified at MIT AppInventor and the .apk file to be installed directly in your Android device.

FTH62BVIN699T4B.aia F60H7R0IN699T4I.apk

Step 11:Changing the Code for PID remote tuning

During the Setup, we will introduce a loop where you can send the PID parameters to the Robot before you put him over the line:

 while (digitalRead(buttonPin) &&!mode) { checkBTcmd(); // verify if a comand is received from BT remote control manualCmd (); command =""; } checkPIDvalues(); mode =STOPPED; 

The manual command function will be:

void manualCmd(){ switch (command[0]) { case 'g':mode =FOLLOWING_LINE; merusak; case 's':motorStop(); //turn off both motors break; case 'f':motorForward(); merusak; case 'r':motorTurn(RIGHT, 30); motorStop(); merusak; case 'l':motorTurn(LEFT, 30); motorStop(); merusak; case 'b':motorBackward(); merusak; case 'p':Kp =command[2]; merusak; case 'i':Ki =command[2]; merusak; case 'd':Kd =command[2]; merusak; }} 

In the video, you can see some tests using the Android App. Below the final code including the PID setup via Android:

FGAEB9BIN7QQQAW.ino FBMONSNIN7QQQCD.ino F8B3CDHIN7QQQCL.h FNOMRUNIN7QQQCP.ino FA3K57ZIN7QQQCR.ino

Step 12:Conclusion

This is the first part of a more complex project, exploring the potentiality of a line follower robot. In the next part, I will develop a Maze solve robot, based on this this project here. Hopefully I can contribute for others to learn more about electronics, robot, Arduino, etc.

The update files for this project can be found at GITHUB. For more tutorials, please visit my Blog:MJRoBot.org

Greetings from the south of the world!

Thanks

Marcelo

Kode

  • Code snippet #1
  • Cuplikan kode #2
  • Code snippet #3
  • Code snippet #5
  • Code snippet #6
  • Code snippet #10
  • Code snippet #11
  • Code snippet #12
  • Code snippet #15
  • Code snippet #17
  • Code snippet #18
Code snippet #1Plain text
#include  // Servo library Servo leftServo;Servo rightServo;Void setup(){ leftServo.attach(5); rightServo.attach(3); leftServo.writeMicroseconds(1500); rightServo.writeMicroseconds(1500);}void loop(){}
Cuplikan kode #2Teks biasa
while(digitalRead(buttonPin)) { }motorTurn (LEFT, 500);motorTurn (RIGHT, 500);
Code snippet #3Plain text
const int lineFollowSensor0 =12;const int lineFollowSensor1 =18;const int lineFollowSensor2 =17;const int lineFollowSensor3 =16;const int lineFollowSensor4 =19;
Code snippet #5Plain text
LFSensor[0] =digitalRead(lineFollowSensor0);LFSensor[1] =digitalRead(lineFollowSensor1);LFSensor[2] =digitalRead(lineFollowSensor2);LFSensor[3] =digitalRead(lineFollowSensor3);LFSensor[4] =digitalRead(lineFollowSensor4);
Code snippet #6Plain text
if((LFSensor[0]==0 )&&(LFSensor[1]==0 )&&(LFSensor[2]==0 )&&(LFSensor[3]==0 )&&(LFSensor[4]==1 )) error =4;else if((LFSensor[0]==0 )&&(LFSensor[1]==0 )&&(LFSensor[2]==0 )&&(LFSensor[3]==1 )&&(LFSensor[4]==1 )) error =3; else if((LFSensor[0]==0 )&&(LFSensor[1]==0 )&&(LFSensor[2]==0 )&&(LFSensor[3]==1 )&&(LFSensor[4]==0 )) error =2;else if((LFSensor[0]==0 )&&(LFSensor[1]==0 )&&(LFSensor[2]==1 )&&(LFSensor[3]==1 )&&(LFSensor[4]==0 )) error =1;else if((LFSensor[0]==0 )&&(LFSensor[1]==0 )&&(LFSensor[2]==1 )&&(LFSensor[3]==0 )&&(LFSensor[4]==0 )) error =0;else if((LFSensor[0]==0 )&&(LFSensor[1]==1 )&&(LFSensor[2]==1 )&&(LFSensor[3]==0 )&&(LFSensor[4]==0 )) error =- 1;else if((LFSensor[0]==0 )&&(LFSensor[1]==1 )&&(LFSensor[2]==0 )&&(LFSensor[3]==0 )&&(LFSensor[4]==0 )) error =-2;else if((LFSensor[0]==1 )&&(LFSensor[1]==1 )&&(LFSensor[2]==0 )&&(LFSensor[3]==0 )&&(LFSensor[4]==0 )) error =-3;else if((LFSensor[0]==1 )&&(LFSensor[1]==0 )&&(LFSensor[2]==0 )&&(LFSensor[3]==0 )&&(LFSensor[4]==0 )) error =-4;
Code snippet #10Plain text
void calculatePID(){ P =error; I =I + error; D =error-previousError; PIDvalue =(Kp*P) + (Ki*I) + (Kd*D); previousError =error;}
Code snippet #11Plain text
void motorPIDcontrol(){ int leftMotorSpeed =1500 - iniMotorPower - PIDvalue; int rightMotorSpeed =1500 + iniMotorPower - PIDvalue; leftServo.writeMicroseconds(leftMotorSpeed); rightServo.writeMicroseconds(rightMotorSpeed);}
Code snippet #12Plain text
void loop (){ readLFSsensors(); // read sensors, storage values at Sensor Array and calculate "error" calculatePID(); motorPIDcontrol();}
Code snippet #15Plain text
void loop() { readLFSsensors(); switch (mode) { case STOPPED:motorStop(); merusak; case NO_LINE:motorStop(); motorTurn(LEFT, 180); merusak; case FOLLOWING_LINE:calculatePID(); motorPIDcontrol(); merusak; }}
Code snippet #17Plain text
 while (digitalRead(buttonPin) &&!mode) { checkBTcmd(); // verify if a comand is received from BT remote control manualCmd (); command =""; } checkPIDvalues(); mode =STOPPED;
Code snippet #18Plain text
void manualCmd(){ switch (command[0]) { case 'g':mode =FOLLOWING_LINE; merusak; case 's':motorStop(); //turn off both motors break; case 'f':motorForward(); merusak; case 'r':motorTurn(RIGHT, 30); motorStop(); merusak; case 'l':motorTurn(LEFT, 30); motorStop(); merusak; case 'b':motorBackward(); merusak; case 'p':Kp =command[2]; merusak; case 'i':Ki =command[2]; merusak; case 'd':Kd =command[2]; merusak; }}
Github
https://github.com/Mjrovai/MJRoBot-Line-Followerhttps://github.com/Mjrovai/MJRoBot-Line-Follower

Skema

oIDhLcHQ30lDgVBXZvb8.fzz

Proses manufaktur

  1. Masa Depan Robotika
  2. Sensor pelacakan garis dengan RPi
  3. Sensor Pi Raspberry dan Kontrol Aktuator
  4. ROBOT WIFI RASPBERRY PI DIKONTROL DARI PONSEL PINTAR ANDROID
  5. Otomasi:Garis Robot Didesain Ulang
  6. SCARA Robot Line Diperluas
  7. Kontrol Jarak Jauh Universal menggunakan Arduino, 1Sheeld, dan Android
  8. Pengikut Lini Industri untuk Pengadaan Bahan
  9. Kontrol PID dari Robot Gripper di Matlab / Simulink
  10. Kontrol Kualitas Jalur Pengemasan Otomatis