Đề tài Robot di dộng bám theo vật

Tài liệu Đề tài Robot di dộng bám theo vật: Trong thời đại ngày nay, ngành công nghiệp đóng vai trò quan trọng trong nền kinh tế, khoa học… những ROBOT tự động, sẽ giúp cho con người rất nhiều, chúng đã thay thế sức con người một cách hiệu quả nhất. ROBOT được sử dụng rộng rãi cuộc sống, nơi mà môi trường có tính độc hại , nguy hiểm cũng như các công việc yêu cầu có độ chính xác cao. Do vậy ROBOT có tầm quan trọng rất lớn trong thời đại ngày nay. Là sinh viên chuyên ngành điện tử tự động, để bổ sung những kiến thức đã học cũng như nghiên cứu những vấn đề mới trong lĩnh vực điều khiển tự động nên chúng em quyết định chọn đề tài “ROBOT DI DỘNG BÁM THEO VẬT”. Mặc dù đã cố gắng hoàn thành đồ án đúng thời hạn nhưng trong quá trình thực hiện không tránh khỏi những thiếu sót. Chúng em rất mong nhận được sự đóng góp ý kiến từ quý Thầy cô và các bạn. Chúng em xin chân thành cảm ơn: Thầy PHẠM THÀNH DANH đã tận tình hướng dẫn chúng em trong quá trình chuẩn bị cũng như thực hiện đề tài này. NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN: Chữ...

doc95 trang | Chia sẻ: hunglv | Lượt xem: 1451 | Lượt tải: 2download
Bạn đang xem trước 20 trang mẫu tài liệu Đề tài Robot di dộng bám theo vật, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Trong thời đại ngày nay, ngành công nghiệp đóng vai trò quan trọng trong nền kinh tế, khoa học… những ROBOT tự động, sẽ giúp cho con người rất nhiều, chúng đã thay thế sức con người một cách hiệu quả nhất. ROBOT được sử dụng rộng rãi cuộc sống, nơi mà môi trường có tính độc hại , nguy hiểm cũng như các công việc yêu cầu có độ chính xác cao. Do vậy ROBOT có tầm quan trọng rất lớn trong thời đại ngày nay. Là sinh viên chuyên ngành điện tử tự động, để bổ sung những kiến thức đã học cũng như nghiên cứu những vấn đề mới trong lĩnh vực điều khiển tự động nên chúng em quyết định chọn đề tài “ROBOT DI DỘNG BÁM THEO VẬT”. Mặc dù đã cố gắng hoàn thành đồ án đúng thời hạn nhưng trong quá trình thực hiện không tránh khỏi những thiếu sót. Chúng em rất mong nhận được sự đóng góp ý kiến từ quý Thầy cô và các bạn. Chúng em xin chân thành cảm ơn: Thầy PHẠM THÀNH DANH đã tận tình hướng dẫn chúng em trong quá trình chuẩn bị cũng như thực hiện đề tài này. NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN: Chữ ký giáo viên: NHẬN XÉT CỦA GIÁO VIÊN PHẢN BIỆN: Chữ ký giáo viên: MỤC LỤC PHẦN Trang Phần 1.Lý thuyết định vị robot 6 Phần 2.Thiết kế mạch điều khiển 9 Phần 3. Thiết kế phần cơ Robot 18 Phần 4. Điều khiển Robot 20 Phần 5. Xử lý ảnh 25 Phần 6.Tổng quan về OPENCV 30 Phần 7. Truyền dữ liệu bằng module RF 40 Phần 8. Chương trình điều khiển 46 Phần 1: LÝ THUYẾT VỀ ĐỊNH VỊ ROBOT Định vị cho robot: Có 2 cách: định vị tương đối và tuyệt đối Định vị tương đối Là một phương pháp phổ biến dùng để xác định vị trí tương đối của  robot di động trong mặt phẳng sau một quá trình duy chuyển nào đó so với vị trí ban đầu. Việc giải bài toán định vị tương đối thực ra là giải bài toán động học cho robot di động, nhằm xác định vị trí và hướng tức thời của robot sau một quá trình chuyển động trong gốc tọa độ với bề mặt sàn của robot ở thời điểm ban đầu. Việc khó khăn là robot liên kết với sàn thi đấu bằng bánh xe và lớp cao su, vì vậy việc chuyển động là nhờ vào lực ma sát, do đó việc chính xác không cao lắm vì phục thuộc tương đối vào hai bánh xe, sự trượt của bánh.....Sai số hệ thống là do những cơ cấu chấp hành,những thiết kế không chính xác như: hai bánh xe không bằng nhau,không cân bằng… Phương pháp định vị tương đối chủ yếu dựa vào số vòng quay của motor, để xác định vị trí tương đối của robot sau một quá trình chuyển động. Phương pháp này thì đơn giản, nhưng có khuyết điểm lớn nhất là bán kính sai số lớn và là sai số tích lũy. Sau đây là 1 ví dụ đơn giản: Hình 1.1: Mô hình robot đơn giản Trong hình hai bánh xe được truyền động bằng hai motor giảm tốc riêng biệt và có hai encorder hồi tiếp xung cho mỗi motor. Đặt vấn đề là bài toán yêu cầu cho robot chạy một đoạn thẳng 10 cm thì có sai số không và sai số là bao nhiêu. Để giải quyết bài toán trên ta giả sử dùng 2 encoder cho hai bánh xe với độ phân giải là 100 xung/vòng quay và encoder được gắn trên bánh xe có đường kính 5cm, Gọi D là đường kính của bánh xe Encorder S là chu vi của bánh xe encorder P là độ phân giải của encoder D=50mm è S=2*3.14*25= 157 mm (1 vòng quay) P=100 è 1góc =3.60 và 1xung=1.57mm 100 xung=64 xung Yêu cầu bài toán là cho robot chạy 1 đoạn 10cm(100mm) è robot phải chạy sao cho bánh xe encoder phải quay hết 64 xung Trên đây chỉ là tính toán tuyệt đối và encorder xoay trong điều kiện lý tưởng,nhưng thực tế thì thường có sai số vì: Bánh xe không tròn Đường kính bánh xe thực tế không bằng với bánh xe dùng trong tính toán Bánh xe lệch trục Vị trí lắp bánh xe không thích hợp dẫn đến bánh xe có thể không tiếp xúc nền Tần số lấy mẫu của encoder Mặt sàn không cân bằng Trượt bánh xe so với nền Khi quay quá nhanh làm bánh xe bị trượt một khoảng Định vị tuyệt đối: Định vị tuyệt đối là phương pháp xác định vị trí chính xác của robot, phương pháp này được thực hiện không thể thiếu các cảm biến, encoder, công tắc hành trình ... những phần tử này tạo cơ sở cho robot nhận biết đang ở đâu, toạ độ bao nhiêu. Điểm khác so với định vị tương đối là: Các phần thiết kế cơ khí không cần tuyệt đối chính xác Luôn luôn đọc giá trị hiện tại Điều khiển theo cơ sở logic Ưu điểm của phương pháp định vị tuyệt đối: Định vị chính xác Vị trí sai số nhỏ,không đáng kể Cơ khí không cần thiết kế tuyệt đối chính xác b. Nhược điểm của phương pháp này: Tốn kém kinh phí đầu tư Mạch thiết kế phức tạp, để đáp ứng yêu cầu điều khiển Cần cập nhật giá trị cảm biến liên tục Phần 2: THIẾT KẾ PHẦN MẠCH ĐIỀU KHIỂN Tìm hiểu encoder: Hình 2.1 Mô hình Encoder và encoder đang sử dụng E6B2 Ngõ ra của encoder có thể được xem như kênh A và kênh B như hình dưới. Hình2.2: Trạng thái ngõ ra kênh A và kênh B Ngõ ra của kênh A là điện áp được khuếch đại bởi transisstor Q1 và tương thích TTL với thời gian tăng và giảm bằng mạch kích Schmittriger L1. Hoạt động tương tự ở kênh B qua Q2 và L2. Rõ ràng là mạch kích Schmitt kênh A tạo ra xung clock để chốt và mạch kích Schmitt kênh B nối với ngõ vào diode của chốt. Với cấu hình này, trạng thái của ngõ ra Q của chốt sẽ cho biết chiều quay của đĩa mã hoá. Giả sử trạng thái logic của ngõ ra Q của SN7474 là mức cao. Thế thì kênh B được ưu tiên dẫn trước kênh A. Nói cách khác, khi chốt được kích cạnh, có 1 tín hiệu logic ở ngõ vào diode của nó. Dưới các điều kiện này, bảng sự thật của mạch chốt sẽ biểu diễn ngõ ra Q của nó sẽ lên mức cao. Chiều quay ngược chiều kim đồng hồ tồn tại dưới điều kiện kênh B dẫn trước kênh A. Các điều kiện ngược lại làm quay theo chiều kim đồng hồ và ngõ raQ của mạch chốt ở mức thấp. Mạch điều khiển động cơ: Hình 2.3: Mạch điều khiển động cơ Giản đồ trạng thái điện áp: Hình 2.4: Giản đồ trạng thái điện áp ngõ ra Nếu cho động cơ chạy thì chân 1 Opto(PWM1) phải ở mức logic 1,lúc này nội trở hai chân 3 và 4 của Opto sẽ thấp, nguồn 12v qua R5(do Opto) dẫn nên tại chân B của Q2 sẽ đạt mức logic thấpè Q2 tắt è Q3 dẫn bão hoà è Q4 tắt è Q5 dẫn è Động cơ chạy. Ngược lại, khi Opto tắt è Q2 dẫn bão hòa è Q3 tắt è Q4 dẫn(nếu có điện áp rơi trên chân E của Q4) è Q5 tắt è Động cơ tắt Khi muốn đảo chiều động cơ ta chỉ cần xuất mức logic 0 tại chân DKRL1, lúc này role 2 sẽ ON, nhờ vào những tiếp điểm của role ta sẽ đảo chiều cấp nguồn của động cơ è Động cơ chạy ngược chiều Mạch Detect màu trên sân thi đấu: Hình 2.5: Mạch detect màu trên sân thi đấu Nguyên lý hoạt động: Dựa vào sự thay đổi nội trở của Photo Resistor khi được chiếu sáng hay che tối, điều này làm thay đổi nội trở (dạng analog) tại chân (-) của Opam.Chân (+) là áp ngưỡng so sánh cho ngõ vào (-).Vì vậy ở ngõ ra chỉ tồn tại hai trạng thái 1 nếu áp chân (-) nhỏ hơn áp tại chân (+) và ngược lại là mức 0. Trong sân thi đấu có hai màu, xanh và trắng, nếu led phát vào màu trắng thì ánh sáng phản chiếu vào quang trở sẽ mạnh hơn khi đi vào màu xanh vì vậy khi vào vạch trắng thì điện áp tại chân (-) nhỏ hơn áp tại chân (+) è ngõ ra = 1.Ngược lại khi ra khỏi vạch trắng thì áp tại chân (-) lớn hơn áp tại chân (+) è ngõ ra = 0,lấy mức logic này đưa vào mạch đảo tín hiệu để tạo mức logic chính xác trước khi đưa vào vi điều khiển để nhận biết màu và đưa ra điều khiển thích hợp. Ta có dạng trạng thái xung trong hình sau: Hình 2.6: Trạng thái xung Mạch chọn kênh chương trình: Dùng vi mạch 4067 chúng ta có thể chọn được 16 chương trình từ 5 chân của vi điều khiển Bảng hoạt động như sau: Select 4 Select 3 Select 2 Select 1 EN Output 0 0 0 0 0 Pro_1 0 0 0 1 0 Pro_2 0 0 1 0 0 Pro_3 0 0 1 1 0 Pro_4 0 1 0 0 0 Pro_5 0 1 0 1 0 Pro_6 0 1 1 0 0 Pro_7 0 1 1 1 0 Pro_8 1 0 0 0 0 Pro_9 1 0 0 1 0 Pro_10 1 0 1 0 0 SW1 1 0 1 1 0 SW2 1 1 0 0 0 SW3 1 1 0 1 0 SW4 1 1 1 0 0 SW5 1 1 1 1 0 SW6 X X X X 1 No(*) No(*) không kết nối với bất kỳ ngõ input nào,lúc này ngõ ra ở mức 1,nếu được tích cực thì ứng với mỗi trạng thái select X thì ngõ ra output sẽ kết nối với 1 input mà ta vừa mới select X. Mạch nạp chương trình vào vi điều khiển: Mạch trên dùng vi mạch Max232 dùng để chuyển từ chuẩn RS232 sang mức logic 0 ;1.Nhờ vi điều khiển có chức năng nạp trực tiếp từ max 232 nên ta đưa trực tiếp hai chân TXD,RXD từ max232 vào vi điều khiển (Dùng phần mềm Flash Magic của Phillips để load chương trình vào,ra vi điều khiển) Mạch tổng quát: A. Sơ đồ mạch Layout: Sơ đồ mạch Capture: Phần 3: THIẾT KẾ PHẦN CƠ CHO ROBOT Các hình chiếu của robot: a. Hình chiếu đứng: Hình 3.a: Hình chiếu đứng robot tự động b. Hình chiếu bằng: Hình 3.b: Hình chiếu bằng robot tự động c. Hình chiếu cạnh: Hình 3.c: Hình chiếu cạnh robot tự động Phần 4: ĐIỀU KHIỂN ROBOT Vi xử lý và các ngõ vào ra: Vi điều khiển P89V51RB2FN 16KB chương trình,5 kênh điều rộng xung,hai thanh ghi DPTR,Watch dog timer,Brown out detect 16 CTHT tương ứng cho 16 chương trình hoặc 16 công tắc hành trình 8 ngõ vào sensor dò đường 2 ngõ vào encoder, 2 ngõ vào ngắt ngoài 5 motor điều rộng xung 2 SW tổ hợp chọn chế độ hoạt động,1 nút chọn màu của đội đỏ/xanh Lập trình cho robot: Đọc tín hiệu từ máy tính: Phân vùng cảm biến : 8 led được chia thành 16 vùng (8 vùng trái và 8 vùng phải) L3 L2 L1 CL CR R1 R2 R3 Với: L3 sensor trái thứ 3 so với sensor trung tâm L2 sensor trái thứ 2 so với sensor trung tâm L1 sensor trái thứ 1so với sensor trung tâm CL sensor trung tâm bên trái CR sensor trung tâm bên phải R1 sensor phải thứ 1 so với sensor trung tâm R2 sensor phải thứ 2 so với sensor trung tâm R3 sensor phải thứ 3 so với sensor trung tâm Đọc cảm biến theo nguyên tắc : đọc từ trong ra ngoài, tức là kiểm tra giá trị sensor từ CL,CR è L1,R1 è L2,R2 è L3,R3 è Vùng error Vùng Error sẽ được thực thi khi và chỉ khi robot đang chạy dò đường nhưng bất ngờ không có sensor nào tích cực è đã chạy sai vạch è tăng tốc bánh bên trái nếu trước đó rẽ phải hoặc tăng tốc bánh bên phải nếu trước đó rẽ trái Bảng phân vùng : L3 L2 L1 CL CR R1 R2 R3 Phân vùng 1 1 1 0 0 1 1 1 Vùng trung tâm (Clr 00,01H) 1 1 1 0 1 1 1 1 Vùng trái 1 1 1 0 0 1 1 1 1 Vùng trái 2 1 1 0 1 1 1 1 1 Vùng trái 3 1 0 0 1 1 1 1 1 Vùng trái 4 1 0 1 1 1 1 1 1 Vùng trái 5 0 0 1 1 1 1 1 1 Vùng trái 6 (Setb 00H,Clr 01H) 0 1 1 1 1 1 1 1 Vùng trái 7 1 1 1 1 0 1 1 1 Vùng phải 1 1 1 1 1 0 0 1 1 Vùng phải 2 1 1 1 1 1 0 1 1 Vùng phải 3 1 1 1 1 1 0 0 1 Vùng phải 4 1 1 1 1 1 1 0 1 Vùng phải 5 1 1 1 1 1 1 0 0 Vùng phải 6 (Setb 01H,Clr 01H) 1 1 1 1 1 1 1 0 Vùng phải 7 1 1 1 1 1 1 1 1 XXX 00H 01H Vùng lạc 0 1 Lạc phải 1 0 Lạc trái (XXX) nếu không có sensor nào tích cực thì phải xét thêm hai bit 00H,01H Ứng với mỗi vùng có 1 tốc độ riêng biệt è robot không thể lạc vạch được B: Bảng tốc độ: ta có 4 hàm tốc độ ứng vời mỗi hàm có 16 tốc độ khác nhau Vùng Tốc độ Chậm Bánh trái Bánh phải Speed 1 Vùng trung tâm 60 60 Vùng trái 1 55 60 Vùng trái 2 50 60 Vùng trái 3 45 60 Vùng trái 4 40 60 Vùng trái 5 30 60 Vùng trái 6 20 60 Vùng trái 7 10 60 Vùng phải 1 60 55 Vùng phải 2 60 50 Vùng phải 3 60 45 Vùng phải 4 60 40 Speed 1 Vùng phải 5 60 30 Vùng phải 6 60 20 Vùng phải 7 60 10 Lạc trái 00 60 Lạc phải 60 00 Vùng trung tâm Vừa 120 120 Speed 2 Vùng trái 1 100 120 Vùng trái 2 80 120 Vùng trái 3 60 120 Vùng trái 4 40 120 Vùng trái 5 30 120 Vùng trái 6 20 120 Vùng trái 7 10 120 Vùng phải 1 120 100 Vùng phải 2 120 80 Vùng phải 3 120 60 Vùng phải 4 120 40 Vùng phải 5 120 30 Vùng phải 6 120 20 Vùng phải 7 120 10 Lạc trái 00 120 Lạc phải 120 00 Vùng trung tâm Nhanh 180 180 Speed 3 Vùng trái 1 140 180 Vùng trái 2 100 180 Vùng trái 3 80 180 Vùng trái 4 60 180 Vùng trái 5 40 180 Vùng trái 6 30 180 Vùng trái 7 20 180 Vùng phải 1 180 140 Vùng phải 2 180 100 Vùng phải 3 180 80 Vùng phải 4 180 60 Vùng phải 5 180 40 Vùng phải 6 180 30 Vùng phải 7 180 20 Lạc trái 00 180 Lạc phải 180 00 Vùng trung tâm Nhanh Nhất 255 255 Speed 4 Vùng trái 1 230 255 Vùng trái 2 200 255 Vùng trái 3 170 255 Vùng trái 4 140 255 Vùng trái 5 100 255 Vùng trái 6 50 255 Vùng trái 7 20 255 Vùng phải 1 255 230 Vùng phải 2 255 200 Vùng phải 3 255 170 Vùng phải 4 255 140 Vùng phải 5 255 100 Vùng phải 6 255 50 Vùng phải 7 255 20 Lạc trái 00 200 Lạc phải 200 00 Giải thuật đọc tín hiệu: PHẦN 5: XỬ LÝ ẢNH 3.1.1 Các khái niệm cơ bản: 3.1.1.1 Điểm ảnh: Ảnh trong tự nhiên là ảnh liên tục về không gian và độ sáng. Khi ảnh được lưu vào máy tính thì ảnh đã được số hóa. Số hóa là sự biến đổi gần đúng của một ảnh liên tục thành một tập hợp điểm phù hợp với ảnh thật về vị trí không gian và độ sáng. Mỗi điểm như vậy gọi là một điểm ảnh ( PEL : Picture Element ) hay còn gọi là Pixel. Điểm ảnh Pixel là là một phần tử của ảnh số tại tọa độ (x,y) với độ sáng hoặc màu nhất định. Tập hợp những điểm ảnh tạo thành ma trận ảnh. 3.1.1.2 Độ phân giải của ảnh: Độ phân giải ảnh là mật độ điểm ảnh được ấn định trên một ảnh số được hiển thị. Khoảng cách các điểm ảnh được chọn sao cho mắt người thấy được sự liên tục của ảnh và tạo nên mật độ phân bố theo hai trục x và y trong không gian hai chiều. 3.1.1.3 Mức xám: Mỗi điểm ảnh được đặc trưng cơ bản bởi tọa độ x, y của điểm ảnh và độ xám. Mức xám của điểm ảnh là cường độ sáng của nó được gán giá trị số tại điểm đó. Các thang mức xám thường dùng là: 16, 32, 64, 128, 256.Trong đó mức 256 thường dùng nhất vì máy tính dùng 1 byte ( 2^8=256) để biểu diễn từ 0 đến 255 mức. 3.1.2 Các loại ảnh: 3.1.2.1 Ảnh đen trắng: Ảnh đen chỉ bao gồm hai màu: màu đen và màu trắng. Người ta phân biệt thành nhiều mức khác nhau. Nếu chỉ có hai mức: mức 0 và mức 1 hay còn gọi là ảnh nhị phân. Mức 1 ứng với màu sáng và mức 0 ứng với màu tối. Nếu số mức lớn hơn 2 người ta gọi là ảnh đa cấp xám. Việc xác định số mức là phụ thuộc vào tiêu chí lượng hóa. Với ảnh nhị phân, mỗi Pixel mã hóa trên một bit, còn với ảnh 256 mức mỗi Pixel được mã hóa trên 8 bit. Ảnh nhị phân khá đơn giản, các phân tử ảnh có thể coi như các phần tử logic, ứng dụng chính là tính toán logic để phân biệt đối tượng ảnh với nền hoặc phân biệt điểm biên với các điểm khác. 3.1.2.2 Ảnh cường độ: Ảnh cường độ là một ma trận dữ liệu ảnh, mà giá trị của nó đại diện cho cường độ trong một số vùng nào đó của ảnh . Matlab chứa một ảnh cường độ như một ma trận dơn , với mỗi phần tử của ma trận tương ứng với một pixel của ảnh . Ma trận có thể thuộc lớp double , uint8 hay uint16 . Trong khi ảnh cường độ hiếm khi được lưu với bản đồ màu , Matlab sử dụng bản đồ màu để hiển thị chúng . Những phần tử trong ma trận cường độ đại diện cho các cường độ khác nhau hoặc độ xám . Những điểm có cường độ bằng 0 thường được đại diện bằng màu đen và cường độ 1,255 hoặc 65535 thường đại diện cho cường độ cao nhất hay màu trắng . 3.1.2.3 Ảnh màu: Ảnh màu là ảnh tổ hợp từ 3 màu cơ bản: đỏ (Red), lục (Green), xanh lơ (Blue) và thường thu nhận trên các dải tầng khác nhau. Mỗi Pixel ảnh màu gồm 3 thành phần. Mỗi thành phần cũng được chia thành L cấp khác nhau( thường là 256). Do vậy để lưu ảnh màu, người ta lưu trữ từng mặt màu riêng biệt, mỗi màu lưu trữ như một ảnh xám đa cấp. Do đó không gian nhớ cho ảnh màu lớn gấp 3 lần một ảnh đa cấp xám cùng kích thước. Một mảng ảnh RGB có thể thuộc lớp double , uint8 hoặc uint16 . Trong một mảng RGB thuộc lớp double , mỗi thành phần màu có giá trị giữa 0 và 1 . Một pixel mà thành phần màu của nó là (0,0,0) được hiển thị với màu đen và một pixel mà thành phần màu là (1,1,1 ) được hiển thị với màu trắng . Ba thành phần màu của mỗi pixel được lưu trữ cùng với chiều thứ 3 của mảng dữ liệu . Ví dụ giá trị màu R,G,B của pixel (2,5) được lưu trữ trong RGB(2,5,1) , RGB(2,5,2) và RGB(2,5,3) tương ứng . Mô hình ảnh màu dựa trên hệ tọa độ Decac. Không gian ảnh màu RGB Ngoài ra trong các camera số, máy chụp ảnh số người ta còn thường dùng mô hình màu HSV, mô hình YcbCr và mô hình YIQ: H: Hue –đặc trưng cho màu sắc. S: Saturation – đặc trưng cho mức độ đậm nhạt của màu sắc. V: Value – đặc trưng cho cường độ ánh sáng. Mô hình màu HSV. Mô hình màu YCbCr Mô hình màu YIQ. Phần 6: TỒNG QUAN VỀ OPENCV Tổng quan về OpenCV: OpenCV (Open Source Computer Vision Library) là một thư viện xử lý hình ảnh nguồn mở của Intel. Nó có rất nhiều tác dụng như: tương tác giữa người và máy tính, nhận dạng vật, phân đoạn và nhận dạng, nhận dạng khuôn mặt, nhận biết, hiểu về cử chỉ, cấu trúc của vận động, và trong Robot di động. Thêm vào đó nó cải thiện rất nhiều các thuật toán cở bản của thị giác máy như các hàm API cấp thấp hơn. Intel đưa ra phiên bản OpenCV đầu tiên vào năm 1999. Ban đầu nó yêu cầu phải có thư viện xử lý ảnh của Intel. Sau đó vì sự lệ thuộc này mà họ đã phải gỡ bỏ và bây giờ chúng ta có thể sử dụng thư viện này hoàn toàn độc lập. OpenCV rất đa dạng, nó hỗ trợ rất nhiểu hệ điểu hành như: Window, Linux và MacOSX. Những điểm đặc trưng: Open CV có rất nhiều chức năng bạn có thể bị bất ngờ khi lần đầu tiên tiếp xúc nhưng chỉ sau vài lần sử dụng bạn sẽ thấy dễ dàng hơn. Sau đây là tóm tắt các chức năng cơ bản của openCV 1.0 Image and video I/O: Những giao tiếp này cho phép đọc dữ liệu ảnh từ các file, hoặc từ những video. Bạn cũng có thể tạo những files hình ảnh và video nữa. Thị giác máy tính và thuật toán xử lý( mức trung bình và thấp): Sử dụng giao tiếp này bạn có thể thử nghiệm với rất nhiều thuật toán về thị giác máy tính mà không cần viết thêm code. Nó bao gồm đường mép, đường thẳng và góc phát hiện, hình elip, hình ảnh kim tụ tháp cho xử lý đa tỉ lệ, mẫu phù hợp, biến đổi đa dạng và nhiều hơn nữa. Module thị giác máy tính cấp cao: OpenCV chứa đựng vài chức năng cao cấp. như nhận dạng khuôn mặt, nhận dạng vật thể và tracking, nó bao gồm luồng quang học ( sử dụng camera để xác định cấu trúc 3D), camera xác định kich thước và âm thanh stereo. AI và phương pháp học của máy: Thị giác máy tính thường đòi hỏi phương pháp học của máy hay phương pháp AI khác một vài phương pháp đó có trong OpenCV. Lấy mẫu hình ảnh và sự chuyển đổi: Nó rất có ích để xử lý một nhóm pixels thành một đơn vị. Open CV có giao tiếp để trích những phân miền ảnh, lấy mẫu ngẫu nhiên, chỉnh sửa kích cỡ ảnh, làm cong, xoay, và cho phép tạo hiệu ứng cho ảnh. Phương pháp để tạo và phân tích ảnh nhị phân: ảnh nhị phân thường được dùng trong hệ thông kiểm tra, nó quét để tìm ra sự thay đổi hình dạng hoặc đếm các phần trên ảnh. Sự biểu diễn ảnh cũng rất thuận tiện khi chúng ta biết rõ vật thể cần bắt. Cách thức tính toán thông tin 3D: Những hàm này rất có ích khi cần sắp xếp và xác định một vật thể với âm thanh stereo hoặc không gian đa chiều phức tạp từ một camera. Mã lệnh toán để xử lý ảnh, thị giác máy tính và biên dịch ảnh: OpenCV sử dụng các phép toán thông dụng như: đại số, thống kê, hình học. Đồ họa: Những giao diện này cho phép bạn viết chữ và vẽ trên hình ảnh, thêm vào đó những chức năng thú vị có thể tạo ảnh, và những tính năng này còn được dùng để tạo nhãn và đánh dấu. ví dụ nếu bạn muốn viết một chương trình nhận dạng vật thể, nó sẽ giúp bạn tạo nhãn ảnh với kích thước và vị trí định sẵn. Phương thức GUI: OpenCV có cửa sổ giao diện riêng trong khi đó nó bị giới hạn khi làm việc trong mỗi môi trường, chúng cung cấp đa môi trường API để hiển thị hình ảnh và cho phép người dùng nhập dữ liệu thông qua chuột hoặc bàn phím và điều khiển quá trình. Cấu trúc dữ liệu và thuật toán Với những giao diện này bạn có thể lưu, tìm kiếm, và cách danh mục điều khiển, các tuyển tập(cũng như các tập hợp lệnh được gọi ), đồ họa và sơ đồ nhánh một cách hiệu quả. Khả năng tồn tại của dữ liệu Những phương pháp này cung cấp các giao diện một cách thuận lợi để lưu trữ các dạng khác nhau của dữ liệu vào đĩa để có thể khôi phục khi cần thiết. Cấu tạo Những hàm của OpenCV có chứa ở trong vài modules. CXCORE chứa đựng các định nghĩa về kiểu dữ liệu cơ bản. ví dụ, cấu trúc dữ liệu của ảnh, các điểm và các hình chữ nhật được xác định trong file cxtypes.h. CXCORE cũng chứa đựng các phép toán đại số tuyến tính,thống kê,các hàm lâu dài và lỗi thao tác. Có một chút kỳ cục o đây là các hàm đồ họa phục vụ cho vẽ trên ảnh được giữ ở đây. CV chứa đựng quá trình xử lý ảnh và các phương pháp đánh giá sơ bộ kích thước ảnh. Những hàm tính toán hình học cũng được lưu trữ tại đây. CVAUX được mô tả trong văn bản của OpenCV như là modul cũ và chỉ dùng để thí nghiệm. Tuy nhiên, giao diện đơn giản nhất cho nhận dạng mặt được nằm trong modul này. Những mã nguồn nằm trong module này rất phù hợp cho việc nhận dạng mặt và chúng được sử dụng rộng rãi cho mục đích này. ML chứa đựng giao diện mechine-learning Những hàm còn lại được nằm trong HighGUI và CVCAM. Cả hai đều nẳm ở thư mục có tên “otherlibs”, sử dụng chúng rất dễ gặp lỗi. Vì rằng HighGUI chứa các thư viện vào ra cơ bản , bạn sẽ muốn chắc chắn hơn, đừng bỏ sót nó.Nó cũng chứa đựng nhiều cửa sổ đa chức năng. CVCAM là thư viện chứa các hàm truy nhập video thông qua DirectX trên môi trường Window 32 bit. Tuy nhiên, HighGUI cũng có các giao diện video.Trong bài báo này, tôi chỉ xem xét HighGUI. Chúng đơn giản, làm việc trên nhiều môi trường. Nếu bạn sử dụng Window XP hoặc 2000, bạn có thể làm tăng hiểu quả của nó bằng cách chuyển qua giao diện CVCAM, nhưng học OpenCV sẽ đơn giản hơn khi dùng HighGUI. Cài đặt OpenCV Cài đặt cơ bản OpenCV cho Linux và MacOSX được đóng gói như một gói mã nguồn lưu trữ. Bạn sẽ phải xây dựng cả thư viện tĩnh và cả những đối tượng chia sẻ (shared-object). Bạn cần xây dựng RPM trước tiên và cài đặt từ nó, hoặc biên dịch và cài đặt nó ngay.Cấu trúc cho cả hai được nằm trong INSTALL. Với Window ta khi cài đặt OpenCV,nó sẽ cop file OpenCV vào thư mục mà bạn chọn.Cách thức lựa chọn trong đường dẫn hệ thống của bạn chứa mã nhị phân OpenCV, đăng kí một vài bộ lọc DirectX.Mặc định nó cài đặt đến C:/Program Files/OpenCV/ Những yêu cầu khi cài đặt trong windows Đối với người dùng xài Windows, OpenCV rất dễ dàng cài đặtvà luôn hoạt động. nhưng một chút cải tiến nhỏ sẽ cho bạn kết quả tốt hơn. Sau đây là một vài đề nghị. OpenCV chỉ là một công cụ hỗ trợ cho người lập trình không phải là một chương trình bạn có thể lưu giữ nó ở một nơi nào đó khác thư mục Progam files. Nếu bạn thích cài vào một nơi khác hãy chọn thư mục đó trước khi nó hỏi. Tôi đề nghị bạn cũng quyết định trước khi cài đặt – bạn muốn windows tìm kiếm những files dll của OpenCV như thế nào. Bạn có thể chỉnh sửa đường dẫn của hệ thống của bạn thay vì của hệ thống, hoặc bạn có thể di chuyển chúng sau khi cài đặt từ thư mục “bin” của OpenCV bằng thư mục gốc của bạn. Nếu bạn muốn di chuyển các files dll nhưng bạn không chắc thư mục gốc của bạn nằm ở đâu, bạn có thể lưu chúng bằng cách chạy tiện ích Sysinfo có sẵn ở địa chỉ www.cognotics.com/utilities. Nếu bạn thích chỉnh đường dẫn hơn di chuyển các file dll, bạn có thể cài đặt bằng cách lựa chọn các check box “ Add bin directory to path”. Sau khi cài đặt Thư mục OpenCV có chứa và thư mục con. Thư mục “docs” có chứa các tài liệu html cho tất cả các hàm và kiểu dữ liệu. từ các tài liệu này bạn có thể làm các ví dụ, bạn cũng có thể duyệt (browse) thư mục “samples”. Bạn cũng cần đến những file header khi biên dịch chương trình nó có ở trong các module của OpenCv. Mặc dù bạn không cần làm việc này. Tôi thích tập hợp chúng lại với nhau vào trong một thư mục. Trên cả Linux và Windows, bạn có thể xác định vị trí của những header bằng cách tìm kiếm thư mục cài đặt và các thư mục con của nó với các file có đuôi mở rộng là *.h, *.hpp. sẽ có rất nhiều file được tìm thấy. bạn sẽ không cần tất cả các file. Header cho tất cả các modules ngoại trừ HighGUI đã được đính sẵn trong mỗi module. Bạn có thể bỏ các header trong thư mục “src” cho nhưng module này. Với HighGUI bạn sẽ cần đến file highgui.h được lưu ở otherlibs/highgui. Lập trình với OpenCV: vài điều cơ bản Những điều cần biết về Header và Libraries Hầu hết chương trình OpenCV cần cv.h và highgui.h.Sau đó để nhận dạng mặt chúng ta cần thêm cvaux.h. Phần còn lại của file header được thêm vào bởi những header cao nhất ( high-level headers). Nếu bạn để các file header trong các thư mục khác nhau( cài đặt mặc định), hãy chắc chắn rằng đường dẫn của trình biên dịch có các thư mục đó. Nếu bạn gom chúng lại một thư mục hãy chắc chắn rằng nó trùng với đường dẫn của trình biên dịch của bạn. Figure 1:Ví dụ chương trình đọc một ảnh từ file và ghi nó vào một file khác với dịnh dạng khác Mối liên kết của bạn sẽ cần cả hai thư viện và tên của thư viện tĩnh để sử dụng. thư viện tĩnh bạn cần liên kết đến file cxcore.lib, cv.lib, và highgui.lib. và sau đó bạn cần thêm file cvaux.lib để nhận dạng gương mặt. tất cả các file này đều nằm trong thư mục “lib”. Đọc và ghi ảnh Xuất nhập ảnh rất dễ dàng với OpenCV/ hình 1 chỉ cho chúng ta thấy một chương trình hoàn chỉnh để đọc một ảnh và ghi ảnh đó sang một file thứ hai trong một định dạng khác. Để đọc một file ảnh đơn giản ta chỉ cần gọi cvloadImage(), trong ví dụ nó nằm ở dòng thứ 14. OpenCV hỗ trợ hầu hết các định dạng ảnh phổ biến như JPEG, PNG và BMP. Bạn không cần phải cung cấp thông tin của định dạng ảnh. cvLoadImage xác định định dạng file bằng cách đọc các file header. Để ghi một hình ảnh ra file, gọi hàm cvSaveImage(). Hàm này quyết định định dạng file nào sẽ được dùng từ đuôi mở rộng. trong ví dụ này đuôi mở rộng là “PNG”. Vì vậy nó sẽ ghi dữ liệu ảnh dưới định dạng PNG. Cả hai hàm cvLoadImage() và cvSaveImage() đều nằm trong HighGUI module. Khi bạn hoàn thành việc sử dụng nhập ảnh từ cvLoadImage(), bạn cần thả free bằng cách gọi hàm cvReleaseImage(), như ở dòng 29 hàm này sẽ lấy địa chỉ của một điểm làm input tạo “ngắt an toàn”. Nó trả tự do cho cấu trúc ảnh chỉ khi ảnh không rỗng. sau khi trả tự do, nó sẽ đặt giá trị điểm ảnh về 0. Thu video trục tiếp Chụp một khung hình từ một webcam, hoặc từ các thiết bị quay video kĩ thuật số khác dễ dàng như load hình từ một file. Hình 2 cho chúng ta thấy một danh sách các lệnh để khởi tạo cấu trúc chụp, và lưu các video frames và đóng các giao diện chụp. Figure 2: Ví dụ chương trình chụp ảnh video và lưu chúng vào một file Giao diện chụp được khởi tạo tại dòng 19 bằng cách gọi hàm cvCaptureFromCAM(). Hàm này trả một pointer về cấu trúc cvCapture. Bạn không thể truy cập trực tiếp vào cấu trúc này. Thay vào đó bạn sẽ lưu pointer qua lệnh cvQueryFrame(). Khi bạn hoàn thành việc sử dụng thu video, bạn gọi lệnh cvReleaveCapture() để thả nổi thu video. Giống như hàm cvReleaseImage(), bạn hãy lưu địa chỉ của pointer cvCapture bằng hàm cvReleaseCapture(). Không được thả rỗi hoặc chỉnh sửa IplImage bạn nhận được từ cvQueryFrame()! Nếu bạn cần sửa dữ liệu ảnh hãy tạo một bản copy với câu lệnh như sau: // Copy the video frame IplImage *pImgToChange = cvCloneImage(pVideoFrame); // Insert your image-processing code here ... // Free the copy after using it cvReleaseImage(&pImgToChange); Chuyển đổi màu Hình 3 biểu diễn mã lệnh để chuyển đổi một ảnh màu sang một ảnh xám. OpenCV hỗ trợ chuyển đổi từ nhiều chuẩn mẫu màu khác nhau, gồm RGB, HSV, YCrCb và CIELAB. Lưu ý các hàm chuyển đổi cvCvtColor() đòi hỏi hai ảnh đầu vào. ảnh thứ nhất pRGBImag là ảnh nguồn còn ảnh thứ hai pGrayImag là ảnh sản phẩm nó sẽ chứa kết quả chuyển đổi khi hàm cvCvtColor() được gọi lại. Figure 3: Ví dụ chương trình chuyển đổi ảnh màu qua ảnh đen trắng Bởi mô hình này có nguồn ngẫu nhiên và hình ảnh kết quả để xử lý hàm và rất phổ biến trong OpenCV bạn sẽ cần chúng để tạo ảnh sản phẩm. như ở dòng 25 lệnh gọi hàm cvCreateImage() tạo ra một ảnh có cùng kích thước như ảnh ban đầu. OpenCV lưu ảnh như thế nào OpenCV lưu hình ảnh giống như C,IplImage. IPL ở trong thư viện xử lý ảnh là một thừa kế từ phiên bản trước của OpenCV. Kiểu dữ liệu IplImage được xác định trong CXCORE. Thêm vào đó là dữ liệu ảnh thô, nó chứa một số mô tả chi tiết gọi header của ảnh bao gồm: Width – chiều rộng ảnh bằng pixels Height – chiều cao ảnh bằng pixels Depth – một vài phần tử bất biến xác định nó chỉ ra số bits trên mỗi pixel trên mỗi kênh. Ví dụ nếu depth=IPL_DEPTH_8U dữ liệu cho mỗi pixel được lưu trong 8 bit với giá trị unsigned (unsigned values). nChannels – số kênh dữ liệu(từ 1 đến 4). Mỗi kênh chứa một kiểu dữ liệu pixel. Ví dụ một ảnh RGB có 3 channels – đỏ, xanh lá, xanh dương (đôi khi nó được gọi là ảnh BGR bởi vì dữ liệu pixel được lưu ở dạng xanh dương, xanh lá, đỏ). ảnh đen trắng chỉ có chứa một kênh là độ sáng của pixel. Truy xuất giá trị pixel Bạn có thể tạo nhiều kiểu hàm khác nhau nhờ OpenCV mà không cần truy xuất trực tiếp vào dữ liệu pixel thô. Ví dụ, như nhận dạng khuôn mặt, tracking, và nhận dạng chương trình được nêu sau,trong series này bạn không cần truy xuất dữ liệu thô bằng tay mà thay vào đó chúng hoạt động bằng pointer của ảnh và các cấu trúc cấp cao khác. Sự tính toán các mức pixel được thi hành bên trong các hàm của OpenCV. Tuy nhiên nếu bạn ghi thuật toán xử lya ảnh của chính bạn bạn có thể cần đến truy xuất vào dữ liệu pixel thô. Có hai cách để thực hiện như sau: Truy xuất pixel đơn giản Cách dễ dàng nhất để đọc các pixel riêng lẻ là với hàm cvGet2D(): CvScalar cvGet2D(const CvArr*, int row, int col); Hàm này lấy 3 thông số là một pointer chứa dữ liệu (CVArr*), và mảng được xếp theo hang và theo cột. Dữ liệu chứa đựng có thể có cấu trúc IplImage. Cái hang cao nhất của điểm ảnh có row = 0 và hang thấp nhất có row = chiều cao -1 Hàm cvGet2D() trả về cấu trúc dạng C là CvScalar được xác định như sau: typedef struct CvScalar { double val[4]; } CvScalar; Giá trị của mỗi điểm ảnh cho mỗi kênh được nằm trong val[i]. Với ảnh đen trắng, val[0] chứa độ sáng của điểm ảnh, ba giá trị khác được đặt bằng 0. Với ảnh có 3 kênh BGR thì blue = val[0], green = val[1],và red = val[2]. Các hàm bổ sung cvSet2D() cho phép bạn chỉnh sửa giá trị điểm ảnh. Nó được khai báo như sau: void cvSet2D(CvArr*, int row, int col, CvScalar); Truy xuất nhanh điểm ảnh Mặc dù hàm cvGet2D() và cvSet2D() rất dễ dàng sử dụng nếu bạn muốn truy xuất nhiều hơn vài giá trị điểm ảnh và gặp vấn đề bạn sẽ phải đọc dữ liệu trực tiếp từ bộ nhớ đệm IplImage.imageData. Dữ liệu ảnh trong bộ nhớ đệm được lưu dưới dạng 1 chiều, trong chủ yếu một hang. Điều đó có nghĩa tất cả các giá trị điểm ảnh trong hang đầu tiên được liệt kê ra trước tiếp theo sau là giá trị điểm ảnh của hang thứ hai và cứ tiếp tục như thế cho đến hang cuối cùng. Bởi vì dữ liệu điểm ảnh được xếp hàng và chèn thêm vào nếu cần thiết vì thế mỗi dòng đều bắt đầu là bội của 4 byte. Ngoài ra IplImage.WidthStep biểu thị số byte dữ liệu điểm ảnh của mỗi dòng. Đó là dòng thứ i bắt đầu ở IplImage.imageData+i*IplImage.widthStep. IplImage.imageData định nghĩa theo kiểu char* vì vậy bạn cần hiểu kiểu dữ liệu này, ví dụ, nếu dữ liệu ảnh của bạn ở dạng unsigned bytes ( một kiểu dữ liệu phổ biến), bạn nên hiểu mỗi giá trị theo kiểu unsigned char* trước khi gán, hoặc sử dụng theo cách khác. Nếu bạn truy xuất dữ liệu từ một ảnh đen trắng ( kênh đơn), và độ sâu của dữ liệu là 8 bits( một byte trong mỗi pixel), bạn nên truy xuất hàng cột của điểm ảnh như sau: pixel[row][col] = ((uchar*) (pImg->imageData + row*pImg->widthStep + col)); trong ảnh đa kênh, kênh dữ liệu quét chẵn lẻ xen kẽ nhau. Đây là một đoạn mã lệnh để truy xuất các giá trị điểm ảnh blue, green, red: step = pImg->widthStep; nChan = pImg->nChannels; // = 3 for a BGR image buf = pImg->imageData; blue[row][col] = ((uchar*)(buf + row*widthStep + nChan*col); green[row][col] = ((uchar*)(buf + row*widthStep + nChan*col + 1); red[row][col] = ((uchar*)(buf + row*widthStep + nChan*col + 2); cuối cùng nếu độ sâu ảnh của bạn lớn hơn 8 bits ví dụ IPL_DEPTH_32S. bạn cần chuyển đổi byte bội số cho mỗi giá trị và nhân nó với bộ đệm bằng số byte dữ liệu với độ sâu của ảnh. Điều đó rất khó thành công tuy nhiên bạn sẽ gặp phải hoàn cảnh đó và bạn sẽ phải truy xuất trực tiếp giá trị các điểm ảnh Phần 7 TRUYỀN DỮ LIỆU BẰNG MODULE RF Đặc điểm của module HM TR: Công nghệ FSK, chế độ bán song công, nhưng nhiễu rất mạng Băng tần ISM, không cần đăng ký tần số Có thể cấu hình tần số và có thể sử dụng ứng dụng FDMA Có thể chọn được độ lệch tần số phát sóng và băng thông thu Giao thức dịch tự điều khiển và rất dễ sử dụng Tốc độ truyền dữ liệu có thể lựa chọn nhiều phạm vi Có chân Enable để điều khiển công suất cho những ứng dụng khác nhau Độ nhạy cao, phạm vi truyền tải rộng Giao tiếp UART tiêu chuẩn, TTL hoặc RS232 với mức logic tùy chọn Rất gọn nhẹ độ tin cậy cao, kích thước nhỏ gọn, dễ dàng lắp đặt Không có chỉnh sóng trên thiết bị Ứng dụng: Điều khiển từ xa, điều khiển thiết bị đo Đo không dây Điều khiển truy xuất Nhận dạng tách lọc Thu thập dữ liệu Thiết bị điện máy trong nhà Sản phẩm cho căn nhà thông minh Quản lý trẻ em Hình dạng thực tế: Sơ đồ chân Chân Tên chân Mô tả VCC Nguồn +5V DTX Phát dữ liệu Module phát DRX Nhận dữ liệu Module nhận CONFIG Chọn chế độ Nếu chân này ở mức cao nó sẽ đặt thông số làm việc ENABLE Tính năng làm việc Nếu chân này ở mức cao thì mạch bắt đầu phát tín hiệu Module ứng dụng Module có hai chế độ hoạt động: chế độ giao tiếp và chế độ cấu hình được xác định bởi trạng thái của chân config khi nguồn mở Config = low: hoạt động ở chế độ thu phát Config = high: hoạt động ở chế độ cấu hình Chế độ cấu hình Nếu chân config ở mức thấp khi nguồn mở thì module sẽ hoạt động ở chế độ truyền nhận thông tin. Module cung cấp kết nối RS232 để kết nối với máy tính hoặc TTL với MCU trực tiếp Nó có thể hoạt động với cấu hình mặc định như sau (9.6kbps, 8bits, không kiểm tra 1 bit dừng) Khi dữ liệu truyền tải dưới 9.6kbps thì module HM TR hỗ trợ tiếp tục truyền tải và tốc độ tối đa có thể đạt 1mb tuy nhiên tốc độ truyền tải không vượt quá 32bytes ở tốc độ cao. HM-TR hoạt động ở chế độ bán song công khi nhận 32bytes dữ liệu ở cổng nối tiếp nó sẽ phát dữ liệu ra một lần. nếu dữ liệu nhận được ít hơn 32bytes thì module sẽ đợi 30ms và gửi lại. dữ liệu được gửi tức thì và việc gửi 32bytes là cần thiết. Sau khi phát dữ liệu thì module sẽ chuyển sang chế độ nhận dữ liệu một cách tự động và mất 5ms. Chân enable dùng để điều khiển lượng điện tiêu thụ nếu chân này ở mức thấp thì module hoạt động ở chế độ ngủ đông. Người dùng có thể dùng chân này để điều khiển chu kỳ nhận năng lượng. Chế độ configuration(cấu hình) Nếu chân config ở mức cao thì module sẽ hoạt động ở chế độ cấu hình ở trong chế độ này module truyền tin với host bằng định dạng nối tiếp cố định Phần mềm cài đặt HM-TR Bạn có thể kiểm tra thông số của HM-TR và cài đặt các thông số bằng tiện ích HM-TR setup utility Nút read: đọc các thông số mà module đang dùng Nút write:ghi cấu hình mới vào module Nút default: chế độ mặc định Phần 8: CHƯƠNG TRÌNH ĐIỀU KHIỂN I.Bảng điều khiển: Bảng điều khiển Robot. II.LƯU ĐỒ GIẢI THUẬT: 1.Giải thuật tổng thể: (1) - Thông tin về vị trí đối tượng (2) -Ccamera (3) - Máy tính thu thập các khung ảnh bằng thư viện OPENCV (4) - Quá trình xử lý các khung ảnh thu được thông tin về vị trí của đối tượng (5) - Dựa vào các thông tin để tính toán lệnh điều khiển (6) - Gửi thông tin điều khiển qua cổng COM (7) - Mạch điều khiển các động cơ (8) – Motor - điều chỉnh tốc độ quay của động cơ (thay đổi vị trí của robot) Quá trình thu và xử lý ảnh được tóm tắt qua lưu đồ bên: 2.Giải thuật xử lý ảnh: 3Gải thuật robot: III. Chương trình điều khiển: Giải thuật điều khiển: 1.Phần C#: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; using OpenCVDotNet; using Media; using System.IO; using System.IO.Ports; namespace nhandang { public partial class frm_nhandang : Form { #region Khaibao //========================================== private CVImage range_image = null; private CVImage image = null; private CVImage imageSave = null; private CVCapture Camera = new CVCapture(); private CVHistogram initialHistogram = null; private CVHistogram laserHis = null; private DialogResult thoat = new DialogResult(); //========================================== private int Freq_update = 0; //========= Port control =================== private int control_R = 0; private int control_L = 0; private int Hex_PositionX; private int Hex_PositionY; #endregion //---------------------------------------------------------- public frm_nhandang() { InitializeComponent(); } //-------------------------------------------------------- private void frm_nhandang_Load(object sender, EventArgs e) { ReadData(); Binsize_histo.Value = 20;//giá trị ban đầu trackbar khi load form iteration_trackBar.Value = 1; lb_bieudomau.Text = Binsize_histo.Value.ToString();//hiển thị giá trị lên label lb_phantichanh.Text = iteration_trackBar.Value.ToString(); } //=================================================================== #region Xulyanh private void Xulyanh() { if (image == null) return; image.Resize(Nhandang_pic.Width, Nhandang_pic.Height); // calculate the back projection of the current image on top of the initial histogram. using (CVImage Picture_255 = image.CalcBackProject(this.initialHistogram)) { Region_select.Image = Picture_255.ToBitmap(); CVConnectedComp Move = Picture_255.MeanShift(Nhandang_pic.SelectionRect, (int)Convert.ToInt32(lb_phantichanh.Text), 2000, 5000); Nhandang_pic.SelectionRect = Move.Rect; } Freq_update = (Freq_update + 1) % 500;//500 x 20ms lan dem cap nhat mot lan //Counter.Text = Convert.ToString(Freq_update); if (Freq_update == 0) UpdateHistogram(); RefreshImages(); } //--------------------------------------------------------------- private void UpdateHistogram() //Cập nhật hình ảnh cũ (nếu có) hoặc mới, tính toán vùng hiển thị { if (initialHistogram != null) initialHistogram.Release(); //nếu ko có ảnh thì return if (image == null) return; //+++++++++++++++++++++++++++++++++ int[] bpBins = { Binsize_histo.Value, Binsize_histo.Value, Binsize_histo.Value }; CVPair[] bpRanges = { new CVPair(0, 255), new CVPair(0, 255), new CVPair(0, 255) }; //tính toán biểu đồ màu vùng nhận dạng để hiển thị image.RegionOfInterest = Nhandang_pic.SelectionRect; this.initialHistogram = image.CalcHistogram(bpBins, bpRanges); image.ResetROI(); RefreshImages(); } //=================================================================== private void RefreshImages() //Làm tươi ảnh { //------------------------------------------------ image.RegionOfInterest = Nhandang_pic.SelectionRect; image.ResetROI(); image.Resize(Nhandang_pic.Width, Nhandang_pic.Height); Nhandang_pic.Image = image.ToBitmap(); } //---------------------------------------------------------------- private void timer1_Tick(object sender, EventArgs e)//timer cho phép hiển thị video { image.Dispose();//reset image image = null; image = Camera.QueryFrame(); try { if (image == null) { Camera.Dispose(); Camera.Restart(); } if ((initialHistogram != null) && (flashPic == false)) Xulyanh(); else { flashPic = false; image.Resize(Nhandang_pic.Width, Nhandang_pic.Height); //định dạng ảnh nhận dạng Nhandang_pic.Image = image.ToBitmap();//show camera } //hiển thị vùng video nhận dạng image.RegionOfInterest = System.Drawing.Rectangle.Inflate(Rectangle.FromLTRB ( Nhandang_pic.SelectionRect.X, Nhandang_pic.SelectionRect.Y, Nhandang_pic.SelectionRect.X + Nhandang_pic.SelectionRect.Width + 8, Nhandang_pic.SelectionRect.Y + ((Nhandang_pic.SelectionRect.Width + 8) * 100) / 80 ), 0, 0); Region_select.Image = image.ToBitmap(); //cho phép hiển thị vùng nhận dạng //Đưa dữ liệu từ hình ảnh ban đầu lên biểu đồ màu initHisto.ShowHistogram(image); //xác định tọa độ X Y và hiện lên textbox PositionX.Text = Convert.ToString(Nhandang_pic.SelectionRect.X + (Nhandang_pic.SelectionRect.Width / 2));//chia 2 để lấy tâm PositionY.Text = Convert.ToString(Nhandang_pic.SelectionRect.Y + (Nhandang_pic.SelectionRect.Height / 2)); Hex_PositionX = (int)((float)(Nhandang_pic.SelectionRect.X + (Nhandang_pic.SelectionRect.Width / 2))); // initPicture.Width * 255); } catch { timer1.Enabled = false; MessageBox.Show("Có lỗi từ Camera, vui lòng kiểm lại Camera kết nối", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } //------------------------------------------------------------- private void TimerWaitforResuft_Tick(object sender, EventArgs e) { lbFilename.Text = "Đã nhận dạng OK!"; } #endregion //==================================================================== //các nút điều khiển #region NUT private void start_camera_Click(object sender, EventArgs e) { tab_all.SelectTab(0); image.Dispose(); image = Camera.QueryFrame(); if (image != null) { if (timer1.Enabled == true) { timer1.Enabled = false; open_camera.Text = "Open Camera"; start_camera.Text = "Open Camera"; } else { timer1.Enabled = true; open_camera.Text = "Close Camera"; start_camera.Text = "Close Camera"; } } else MessageBox.Show("Không kết nối được với Camera", "Thông báo"); } //----------------------------------------------------------------- private void start_image_Click(object sender, EventArgs e) { OpenFileDialog openFile = new OpenFileDialog(); openFile.Title = "Open Image";//tên cửa sổ openFile.Filter = "File ảnh(*.jpg,*.bmp)|*.jpg;*.bmp";//loại ảnh if (openFile.ShowDialog() != DialogResult.OK) return; //show image image = new CVImage(openFile.FileName); Nhandang_pic.Image = image.ToBitmap(); } private void open_camera_Click(object sender, EventArgs e) { tab_all.SelectTab(0); image = Camera.QueryFrame(); if (image != null) { if (timer1.Enabled == true) { timer1.Enabled = false; open_camera.Text = "Open Camera"; start_camera.Text = "Open Camera"; } else { timer1.Enabled = true; open_camera.Text = "Close Camera"; start_camera.Text = "Close Camera"; } } else MessageBox.Show("Không kết nối được với Camera ", "Thông báo"); } //--------------------------------------------------------------- private void open_image_Click(object sender, EventArgs e) { OpenFileDialog openFile = new OpenFileDialog(); openFile.Title = "Open Image"; openFile.Filter = "File ảnh(*.jpg,*.bmp)|*.jpg;*.bmp"; if (openFile.ShowDialog() != DialogResult.OK) return; image = new CVImage(openFile.FileName); Nhandang_pic.Image = image.ToBitmap();// bitmap hien thi anh } //================================================================ private void bt_exit_Click(object sender, EventArgs e) { thoat = MessageBox.Show("Bạn muốn thoát khỏi chương trình?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (thoat == DialogResult.Yes) { Camera_center(); Camera_exit(); this.Dispose(); } } #endregion //==================================================================== #region nhandang private void WriteRecognize(string Value) { StreamWriter SW = new StreamWriter("D:\\nhap\\Recognize.crt"); SW.WriteLine(Value); SW.Close(); } //-------------------------------------------------------------- private void WriteMatlapRun(string value) { StreamWriter SW = new StreamWriter("C:\\in\\Matlap.crt"); SW.WriteLine(value); SW.Close(); } #endregion //----------------------------------------------------------- private void initPicture_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) initialHistogram = null; } //------------------------------------------------------------- private void initPicture_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) initialHistogram = null; } //------------------------------------------------------------- private void initPicture_MouseUp(object sender, MouseEventArgs e) { try { if (e.Button == MouseButtons.Left) UpdateHistogram(); TimerWaitforResuft.Enabled = true;//timer cho lbfilename lbFilename.Text = "Đang nhận dạng.."; } catch { MessageBox.Show("Có lỗi!Không thể nhận dạng.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information); } } //---------------------------------------------------------------- //Thanh trượt phân tích biểu đồ màu Track_bar #region Track_bar private void Binsize_histo_ValueChanged(object sender, EventArgs e) { lb_bieudomau.Text = Binsize_histo.Value.ToString(); initHisto.BinsPerChannel = Binsize_histo.Value; UpdateHistogram();//cập nhật histogtam } private void Binsize_histo_Scroll(object sender, EventArgs e) { lb_bieudomau.Text = Binsize_histo.Value.ToString(); UpdateHistogram();//cập nhật histogram } private void iteration_trackBar_Scroll(object sender, EventArgs e) { lb_phantichanh.Text = iteration_trackBar.Value.ToString(); } #endregion #region Port private void optionsToolStripMenuItem_Click_1(object sender, EventArgs e) { tab_all.SelectTab(1); } //-------------------------------------------------------------- private void select_port_DropDown(object sender, EventArgs e) { GetPort(); lbComport.Visible = true; } //--------------------------------------------------------------- private void select_port_SelectedIndexChanged(object sender, EventArgs e) { PortSelectOpen(); } //----------------------------------------------------------------- private void GetPort() { string[] ports = SerialPort.GetPortNames(); select_port.Items.Clear(); // Add all port names to the combo box: foreach (string port in ports) { select_port.Items.Add(port); } } //------------------------------------------------------ private void PortSelectOpen() { try { if (serialPort1.IsOpen) serialPort1.Close(); serialPort1.PortName = select_port.SelectedItem.ToString(); lbport.Text = serialPort1.PortName + ": 9600,8N1"; //Mo Port duoc chon neu co the } catch { } try { serialPort1.Open(); lbComport.Text = serialPort1.PortName; WriteData(); } catch { //Hien thi message neu khong the mo MessageBox.Show("Cổng nối tiếp " + serialPort1.PortName + " không thể mở được!", "Serial Port", MessageBoxButtons.OK, MessageBoxIcon.Warning); select_port.SelectedText = ""; lbport.Text = "Chọn cổng nối tiếp!"; lbComport.Text = ""; } } //--------------------------------------------------------------------------- private void lbComport_TextChanged(object sender, EventArgs e) { serialPort1.PortName = lbComport.Text; serialPort1.Open(); } #endregion //===================================================================================== #region DevidePort private void WriteData() { StreamWriter SW = new StreamWriter("Data.ini"); SW.WriteLine(""); SW.WriteLine(serialPort1.PortName); SW.WriteLine("End section>"); SW.Close(); } private void ReadData() { StreamReader SR = new StreamReader("Data.ini"); if (serialPort1.IsOpen) serialPort1.Close(); SR.ReadLine();//read section serialPort1.PortName = SR.ReadLine(); SR.Close(); lbport.Text = serialPort1.PortName + ":9600,8N1"; try { serialPort1.Open(); lbComport.Text = serialPort1.PortName; } catch { //Hien thi message neu khong the mo MessageBox.Show("Cổng nối tiếp " + serialPort1.PortName + " không thể mở được! Vui lòng chọn cổng khác trước khi sử dụng", "Serial Port", MessageBoxButtons.OK, MessageBoxIcon.Warning); tab_all.SelectTab(1); select_port.SelectedText = ""; lbport.Text = "Chọn cổng nối tiếp!"; lbComport.Text = ""; } } #endregion //======================================================================= #region Robot control private void bt_nhandang_Click(object sender, EventArgs e) { if (box_tdong.Checked & TimerWaitforResuft.Enabled==true) { //box_tdong.Checked = false; bt_startnhandang.Text = "Stop"; timer3.Enabled = true; timer4.Enabled = true; } else { bt_startnhandang.Text = "Start"; timer3.Enabled = false; timer4.Enabled = false; } if (timer1.Enabled == false) { bt_startnhandang.Text = "Start"; timer3.Enabled = false; timer4.Enabled = false; MessageBox.Show("Bạn chưa mở Camera!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning); } //----------------------------------------------------------------- //Đã truyền dc dữ liệu ra cổng com dk_td; //xác định hướng quay cho camera private void box_tdong_CheckStateChanged(object sender, EventArgs e) { if (box_tdong.Checked) { Dung(); box_btay.Enabled = false; } else { box_btay.Enabled = true; } } //----------------------------------------------------------------------5 private void box_btay_CheckStateChanged(object sender, EventArgs e) { if (box_btay.Checked) { ca_L.Enabled = true; ca_R.Enabled = true; bt_tien.Enabled = true; bt_lui.Enabled = true; bt_phai.Enabled = true; bt_trai.Enabled = true; bt_tdo1.Enabled = true; bt_tdo2.Enabled = true; bt_tdo3.Enabled = true; } else { ca_L.Enabled = false ; ca_R.Enabled = false; bt_tien.Enabled = false; bt_lui.Enabled = false; bt_phai.Enabled = false; bt_trai.Enabled = false; bt_tdo1.Enabled = false; bt_tdo2.Enabled = false; bt_tdo3.Enabled = false; } } //----------------------------------------------------------------------- private void timer3_Tick(object sender, EventArgs e)//định hướng quay cho camera { try { if (control_L == 1) { Camera_RotaL(); } if (control_R == 1) { Camera_RotaR(); } if (control_L == 2) { C_outL(); } if (control_R == 2) { C_outR(); } if (control_R == 0 & control_L==0) { Camera_center(); //Camera_exit(); } if (box_tdong.Checked == false) { Camera_center(); Camera_exit(); timer3.Enabled = false; timer4.Enabled = false; } } catch { timer3.Enabled = false; timer4.Enabled = false; box_tdong.Checked = false; bt_startnhandang.Text = "Start"; MessageBox.Show("Vui lòng kiểm tra lại kết nối!", "Comport", MessageBoxButtons.OK, MessageBoxIcon.Warning);// lỗi khi chưa kết nối cổng com khi check dk_td } } //----------------------------------------------------------- private void timer4_Tick(object sender, EventArgs e) //tính toán giá tri X de xác định camera quay trái hay phải { if (box_tdong.Checked) { //Quay trai if (Hex_PositionX > 180 & Hex_PositionX <270) { control_L = 1; } if (Hex_PositionX < 200) { control_L = 0; } if (Hex_PositionX > 270) { control_L = 2; } //--------------------------------------------- //Quay phai if (Hex_PositionX >45 & Hex_PositionX < 100) { control_R = 1; } if (Hex_PositionX > 100 ) { control_R = 0; } if (Hex_PositionX < 45) { control_R = 2; } } } //---------gửi dữ liệu ra cổng com------------------ private void Camera_RotaL() { int RotaLeft = 239; serialPort1.Write(new byte[] { (byte)RotaLeft }, 0, 1); } //------------------------------------------------------------ private void Camera_RotaR() { int RotalRight = 247; serialPort1.Write(new byte[] { (byte)RotalRight }, 0, 1); } //------------------------------------------------------------- private void C_outR() { int out_r = 251; serialPort1.Write(new byte[] { (byte)out_r }, 0, 1); } private void C_outL() { int out_l = 223; serialPort1.Write(new byte[] { (byte)out_l }, 0, 1); } private void Camera_center() { int center = 231; serialPort1.Write(new byte[] { (byte)center }, 0, 1); } private void Camera_exit() { int Car_exit = 255; serialPort1.Write(new byte[] { (byte)Car_exit }, 0, 1); } #endregion //==================================================================== #region DK_Bangtay #region Nut private void bt_tien_Click(object sender, EventArgs e) { R_tien(); } private void bt_lui_Click(object sender, EventArgs e) { R_lui(); } private void bt_trai_Click(object sender, EventArgs e) { R_lelf(); } private void bt_phai_Click(object sender, EventArgs e) { R_right(); } private void ca_L_Click(object sender, EventArgs e) { Camera_trai(); } private void ca_R_Click(object sender, EventArgs e) { Camera_phai(); } private void bt_dung_Click(object sender, EventArgs e) { Camera_exit(); Dung(); } #endregion //============================================================= #region data private void R_tien() { int R_t = 191; serialPort1.Write(new byte[] { (byte)R_t }, 0, 1); } //------------------------------------------------------------ private void R_lui() { int R_l = 63; serialPort1.Write(new byte[] { (byte)R_l }, 0, 1); } //------------------------------------------------------------ private void R_right() { int R_p = 127; serialPort1.Write(new byte[] { (byte)R_p }, 0, 1); } //------------------------------------------------------------- private void R_lelf() { int R_t = 253; serialPort1.Write(new byte[] { (byte)R_t }, 0, 1); } //----------------------------------------------------------- private void Camera_phai() { int C_p = 252; serialPort1.Write(new byte[] { (byte)C_p }, 0, 1); } private void Camera_trai() { int C_t = 254; serialPort1.Write(new byte[] { (byte)C_t }, 0, 1); } private void Dung() { int stop = 255; serialPort1.Write(new byte[] { (byte)stop }, 0, 1); } private void Start() { int start = 240; serialPort1.Write(new byte[] { (byte)start }, 0, 1); } private void toc_do_1() { int td1 = 31; serialPort1.Write(new byte[] { (byte)td1 }, 0, 1); } private void toc_do_2() { int td2 = 15; serialPort1.Write(new byte[] { (byte)td2 }, 0, 1); } private void toc_do_3() { int td3 = 7; serialPort1.Write(new byte[] { (byte)td3 }, 0, 1); } #endregion #endregion } } 2.Chương trình vi xử lý: $MOD51 ;CAC QUY UOC BAN DAU ;================PORT 2====================================== PRO BIT P2.0 ;chan nay nhan tin hieu tu IC to hop chon chuong trinh SELECT1 BIT P2.1 ;bit to hop chon chuong trinh 1 SELECT2 BIT P2.2 ;bit to hop chon chuong trinh 2 SELECT3 BIT P2.3 ;bit to hop chon chuong trinh 3 SELECT4 BIT P2.4 ;bit to hop chon chuong trinh 4 MAU BIT P2.5 ;bang 0 mau Xanh,1 mau do LED BIT P2.6 ;bao khi di qua 1 giao diem hoac tuy y lua chon WAITING BIT P2.7 ;bao trang thai sang sang (ready) ;================PORT 3====================================== ENCODER1 BIT P3.4 ;chan dem xung tu encoder 1 ENCODER2 BIT P3.5 ;chan dem xung tu encoder 2 RL4 BIT P3.6 ;dao chieu motor 4 BANH TRAI RL5 BIT P3.7 ;dao chieu motor 5 BANH PHAI RL1 BIT P1.0 ;dao chieu motor 1 RL2 BIT P1.1 ;dao chieu motor 2 RL3 BIT P1.2 ;dao chieu motor 3 DK CAMERA SELECT_MODE_A BIT P3.0 ;LSB NUT BEN TAY TRAI SELECT_MODE_B BIT P3.1 ;MSB NUT BEN TAY PHAI MAT_THAN_TO BIT P3.2 ;CAM BIEN BAO DU KHOANG CACH MAT_THAN_NHO BIT P3.3 ;CAM BIEN LUI ;==============SENSOR======================================== LEFT3 BIT P0.0 ;cam bien trai thu 3 LEFT2 BIT P0.1 ;cam bien trai thu 2 LEFT1 BIT P0.2 ;cam bien trai thu 1 CENTERL BIT P0.3 ;cam bien giua trai CENTERR BIT P0.4 ;cam bien giua phai RIGHT1 BIT P0.5 ;cam bien phai thu 1 RIGHT2 BIT P0.6 ;cam bien phai thu 2 RIGHT3 BIT P0.7 ;cam bien phai thu 3 ;==============MOTOR========================================= MOTORL DATA CCAP0H ; P1.3 ;dieu xung cho motor trai MOTORR DATA CCAP1H ; P1.4 ;dieu xung cho motor phai MOTOR1 DATA CCAP2H ; P1.5 ;dieu xung cho motor 3 MOTOR2 DATA CCAP3H ; P1.6 ;dieu xung cho motor 4 MOTOR3 DATA CCAP4H ; P1.7 ;dieu xung cho motor 5 ;=====================VAN TOC CHO BANH TRAI============================= V_MOTORL_VT1 DATA 40H V_MOTORL_VT2 DATA 41H V_MOTORL_VT3 DATA 42H V_MOTORL_VT4 DATA 43H V_MOTORL_VT5 DATA 44H V_MOTORL_VT6 DATA 45H V_MOTORL_VT7 DATA 46H V_MOTORL_VT8 DATA 47H ;===============CAC BIT TRUNG GIAN============================= BLUE BIT 00H ;bit bao dang la doi xanh hay do(CLR - Xanh,SETB-Do) DEM_PHU BIT 07H ;LAY CANH XUONG CUA SENSOR DE NHAN DIEN VACH NHO_TRAI BIT 03H ;da re trai truoc do NHO_PHAI BIT 04H ;da re phai truoc do BIT_RUN BIT 0BH ;CHO PHEP CHAY TRACKING(SETB) ;============================================================================== L_BYTE DATA 30H ;byte thap dung trong counter H_BYTE DATA 31H ;byte cao dung trong counter LUU_VACH DATA 32H ;luu so vach trung gian truoc khi xu ly van de(T0ISR) VUNG DATA 37H ;LUU S VUNG (DO PHAN VUNG CAM BIEN)(KHOANG 16 VUNG KHAC NHAU) VACH DATA 07H ;luu so vach da di qua = so giao diem(R7) ;===========BAT DAU VIET CHUONG TRINH================== ;Cac thanh ghi da su dung R0,R1,R7,R2,R6,R3,R4,R5 ;R0 DUNG DE LAY MAU TIN HIEU(CHONG NHIEU) ;R1 DUNG TRONG HAM DELAY(CO THE LAY LAM TRUNG GIAN) ;R2 LUU SO VACH NGANG(TRUNG GIAN CHO VIEC TANG HAY GIAM VACH (R7)) ;R3 LUU SO VACH TRUNG GIAN TRUOC KHI XU LY (CTRINH CON DI? VACH) ;R7 LUU SO VACH DA DI QUA ;A TRUNG GIAN CHO VIEC KTRA LOI KHI QUA VACH NGANG MA CAM BIEN KO LEN(DUNG TRONG T0ISR) ;B LUU CAM BIEN KHI XAC DINH VACH(DUNG TRONG XAC DINH DEM VACH(TRACKING)) ;R5 AP DUNG TRONG CHUONG TRINH CON DK PWM ORG 0000H ;reset he thong SJMP MAIN ORG 0003H ;ngat ngoai 0 LJMP INT0ISR ORG 000BH ;ngat timer 0 LJMP T0ISR ORG 0013H ;ngat ngoai 1 LJMP INT1ISR ORG 001BH ;ngat timer 1 LJMP T1ISR ORG 002BH LJMP T2ISR ORG 0030H ;ngat port noi tiep SJMP MAIN ORG 004BH LJMP POWER_DOWN MAIN: MOV SCON,#12H ;CHO PHEP PORT NOI TIEP HOAT DONG ;====== ====>>==== ;ngung hoat dong tat ca cac timer CLR TF0 CLR TR1 CLR TF1 MOV TH0,#00H MOV TL0,#00H MOV TH1,#00H MOV TL1,#00H SETB EA ;ngat toan cuc ;-- ----------------------------------------------- CLR NHO_TRAI CLR NHO_PHAI MOV LUU_VACH,#00H ; CLR BIT_RUN ;BO QUA QUET CAM BIEN ;---------- -------------------------------------------- MOV MOTOR1,#00H MOV MOTOR2,#00H MOV MOTOR3,#00H LCALL TEST_MAU JNB MAU,MODE_BLUE MODE_RED: CLR WAITING LCALL DOI1S SETB WAITING LCALL DOI1S CLR WAITING LCALL DOI1S SETB WAITING LCALL DOI1S LCALL RESET_ROBOT LCALL TEST_MAU ACALL SCAN_PRO_RED LJMP MAIN MODE_BLUE: CLR WAITING LCALL DOI1S SETB WAITING LCALL DOI1S LCALL RESET_ROBOT LCALL TEST_MAU ACALL SCAN_PRO_BLUE LJMP MAIN ;======================TEST_MAU===================================== TEST_MAU: MOV R0,#255 T_MAUXANH: JNB MAU,GIAM_XANH SJMP T_MAUDO GIAM_XANH: DJNZ R0,T_MAUXANH CLR BLUE ;DOI XANH SETB LED ;DEN LED SANG SJMP EXIT_TEST_MAU T_MAUDO: MOV R0,#255 CHO_MAU: JB MAU,GIAM_DO SJMP T_MAUXANH GIAM_DO: DJNZ R0,CHO_MAU SETB BLUE ;DOI DO CLR LED ;DEN LED SANG EXIT_TEST_MAU: RET ;========================SCAN_PRO_RED===================================== SCAN_PRO_RED: JNB MAU,MODE_BLUE LCALL DOI50MS LCALL CHAYR1 LJMP SCAN_PRO_RED CHAYR1: CLR WAITING LCALL DOI1S LCALL PRO_R1 LJMP EXIT_SCAN_PRO_R EXIT_SCAN_PRO_R: RET ;========================SCAN_PRO_BLUE===================================== SCAN_PRO_BLUE: JB MAU,MODE_RED LCALL DOI50MS LCALL CHAYB1 LJMP SCAN_PRO_BLUE CHAYB1: CLR WAITING LCALL DOI1S LCALL PRO_B2 LJMP EXIT_SCAN_PRO_B EXIT_SCAN_PRO_B: RET ;=======BAT DAU CHAY CHUONG TRINH=========================== START: ============>>============================================ PRO_R1: LCALL TOC_DO_CHAM LCALL SCAN_CHUONG_TRINH SJMP PRO_R1 RET ;==============================================<<<===PRO_R2 ;============-CAC CONG TAC HANH TRINH============= SW1: ;CONG TAC PHAI SETB SELECT1 ;1 CLR SELECT2 ;0 SETB SELECT3 ;1 SETB SELECT4 ;1 LCALL DOI50ms RET ;================================================ SW2: ;CONG TAC TRAI CLR SELECT1 ;0 SETB SELECT2 ;1 SETB SELECT3 ;1 SETB SELECT4 ;1 LCALL DOI50ms RET ;================================================= SW3: ;CONG TAC TRAI SETB SELECT1 ;1 SETB SELECT2 ;1 SETB SELECT3 ;1 SETB SELECT4 ;1 LCALL DOI50ms RET ;================================================= STOP_CAMERA: MOV MOTOR1,#5 CLR RL3 LCALL DOI1S SETB RL3 CLR TR1 MOV MOTOR1,#00H RET STOP: MOV MOTOR2,#10 MOV MOTOR3,#10 CLR RL4 CLR RL5 LCALL DOI1S SETB RL4 ;TRA ROLE VE TRANG THAI BINH THUONG SETB RL5 CLR TR1 ;NGUNG NGAT T1,CHO ROBOT STOP LAI MOV MOTOR2,#00H MOV MOTOR3,#00H RET ;======================================================= CHAY_TOI: SETB RL4 SETB RL5 LCALL DOI50MS MOV MOTOR2,#180 ;BANH TRAI MOV MOTOR3,#200 ;BANH PHAI RET CHAY_LUI: CLR RL4 CLR RL5 LCALL DOI50MS MOV MOTOR2,#100 MOV MOTOR3,#170 RET CUA_PHAI: MOV MOTOR2,#40 MOV MOTOR3,#40 CLR RL5 SETB RL4 RET CUA_TRAI: MOV MOTOR2,#40 MOV MOTOR3,#40 CLR RL4 SETB RL5 RET QUAY_TRAI_C: SETB RL3 MOV MOTOR1,#20 RET QUAY_PHAI_C: CLR RL3 MOV MOTOR1,#20 RET RESET_ROBOT: LCALL STOP LCALL DOI1S LCALL STOP_CAMERA RET ;-------------xxxxxxx------------xxxxxxx------------------ ENABLE_INT0: CLR IT0 ;cho phep ngat ngoai 0 CANH AM SETB EX0 ;BAT DAU CHAY NGAT NGOAI 0 SETB EA ;ngat toan cuc dc set len 1 RETI ;======= ====INT0ISR================================== INT0ISR: RETI ;====== =====INT1ISR================================== INT1ISR: RETI ;=== ===T0ISR==================================== T0ISR: CLR TR0 CLR TF0 RETI ;=== ==T1ISR==================================== T1ISR: CLR TR1 CLR TF1 RETI T2ISR: RETI ;======== =====CHE DO NHIEU NGUON====================== POWER_DOWN: MOV MOTORL,#00H MOV MOTORR,#00H LCALL DELAY800MS LCALL DELAY800MS MOV IEN1,#00000000B RETI SCAN_CHUONG_TRINH: SETB WAITING VUNG_TRUNG_TAM: ;01234567 MOV C,CENTERL ;11100111 ORL C,CENTERR JC VUNG_PHAI_1 MOV VUNG,#00H LJMP EXIT_TRACKING VUNG_PHAI_1: MOV B,P0 ;01234567 CPL B.3 ;LAY BU CPL B.5 MOV C,CENTERR ;11110111 ORL C,B.3 ORL C,B.5 JC VUNG_LAC_PHAI MOV VUNG,#01H SETB NHO_PHAI CLR NHO_TRAI LJMP EXIT_TRACKING VUNG_LAC_PHAI: MOV B,P0 ;01234567 ;11111011 CPL B.4 CPL B.6 MOV C,RIGHT1 ORL C,B.4 ORL C,B.6 JC VUNG_TRAI_1 MOV VUNG,#02H SETB NHO_PHAI CLR NHO_TRAI LJMP EXIT_TRACKING VUNG_TRAI_1: MOV B,P0 ;01234567 CPL B.2 ;LAY BU CPL B.4 MOV C,CENTERL ;11101111 ORL C,B.2 ORL C,B.4 JC VUNG_LAC_TRAI MOV VUNG,#03 SETB NHO_TRAI CLR NHO_PHAI LJMP EXIT_TRACKING VUNG_LAC_TRAI: MOV B,P0 ;01234567 ;11011111 CPL B.1 CPL B.3 MOV C,LEFT1 ORL C,B.1 ORL C,B.3 JC KIEM_TRA_R_TIEN MOV VUNG,#04 SETB NHO_TRAI CLR NHO_PHAI LJMP EXIT_TRACKING ;------------------------------------------------------------------- KIEM_TRA_R_TIEN: MOV B,P0 ;01234567 ;11111101 CPL B.5 CPL B.7 MOV C,RIGHT2 ORL C,B.5 ORL C,B.7 JC KIEM_TRA_R_LUI MOV VUNG,#11 LJMP EXIT_SCAN_PHIM KIEM_TRA_R_LUI: MOV C,RIGHT2 ;01234567 ORL C,RIGHT3 ;11111100 JC KIEM_TRA_R_PHAI MOV VUNG,#12 LJMP EXIT_SCAN_PHIM KIEM_TRA_R_PHAI: MOV C,RIGHT3 ;01234567 MOV B,P0 ;11111110 CPL B.6 ORL C,B.6 JC KIEM_TRA_R_TRAI MOV VUNG,#13 LJMP EXIT_SCAN_PHIM KIEM_TRA_R_TRAI: MOV B,P0 ;01234567 ;10111111 CPL B.0 CPL B.2 MOV C,LEFT2 ORL C,B.0 ORL C,B.2 JC KIEM_TRA_C_PHAI MOV VUNG,#14 LJMP EXIT_SCAN_PHIM KIEM_TRA_C_PHAI: MOV C,LEFT2 ;01234567 ORL C,LEFT3 ;00111111 ORL C,LEFT1 JC KIEM_TRA_C_TRAI MOV VUNG,#15 LJMP EXIT_SCAN_PHIM KIEM_TRA_C_TRAI: MOV C,LEFT3 ;01234567 MOV B,P0 ;01111111 CPL B.1 ORL C,B.1 JC DUNG_LAI MOV VUNG,#16 LJMP EXIT_SCAN_PHIM DUNG_LAI: MOV A,P0 CJNE A,#0FFH,EXIT_SCAN_PHIM MOV VUNG,#17 LJMP EXIT_SCAN_PHIM EXIT_SCAN_PHIM: ACALL DIEU_XUNG_ROBOT RET DIEU_XUNG_ROBOT: DK_R_TIEN: MOV R5,VUNG CJNE R5,#11,DK_R_LUI LCALL STOP_CAMERA SETB RL4 SETB RL5 MOV MOTOR2,V_MOTORL_VT3 MOV MOTOR3,V_MOTORR_VP3 LJMP EXIT_DIEU_XUNG_ROBOT DK_R_LUI: CJNE R5,#12,DK_R_PHAI LCALL STOP_CAMERA CLR RL4 CLR RL5 MOV MOTOR2,V_MOTORL_VT3 MOV MOTOR3,V_MOTORR_VP3 LJMP EXIT_DIEU_XUNG_ROBOT DK_R_PHAI: CJNE R5,#13,DK_R_TRAI LCALL STOP_CAMERA CLR RL4 SETB RL5 MOV MOTOR2,V_MOTORL_VT3 MOV MOTOR3,V_MOTORR_VP3 LJMP EXIT_DIEU_XUNG_ROBOT DK_R_TRAI: CJNE R5,#14,DK_C_PHAI LCALL STOP_CAMERA SETB RL4 CLR RL5 MOV MOTOR2,V_MOTORL_VT3 MOV MOTOR3,V_MOTORR_VP3 LJMP EXIT_DIEU_XUNG_ROBOT DK_C_PHAI: CJNE R5,#15,DK_C_TRAI LCALL STOP ;CHO 2 BANH DUNG LAI NEU KHONG VUA QUAY VUA CUA CLR RL3 MOV MOTOR1,V_MOTORR_VP6 LJMP EXIT_DIEU_XUNG_ROBOT DK_C_TRAI: CJNE R5,#16,DUNG_ROBOT_LAI LCALL STOP ;// SETB RL3 MOV MOTOR1,V_MOTORR_VP6 LJMP EXIT_DIEU_XUNG_ROBOT DUNG_ROBOT_LAI: CJNE R5,#17,EXIT_DIEU_XUNG_ROBOT MOV MOTOR2,#00H MOV MOTOR3,#00H MOV MOTOR1,#00H RET EXIT_DIEU_XUNG_ROBOT: RET CHUONG TRINH SCAN DIEU KHIEN CAMERA DUA VAO TIN HIEU NHAN DC TU MAY TINH========================== EXIT_TRACKING: JNB MAT_THAN_TO,DIEU_XUNG_PWM ACALL DIEU_XUNG_PWM_ROBOT RET ;==== ====>>====================== DIEU_XUNG_PWM: MOV R5,VUNG CJNE R5,#00,DK_VUNG_PHAI_1 JB MAT_THAN_NHO,LUI_LAI1 MOV MOTOR1,#00H ;STOP CAMERA MOV MOTOR2,#00H ;STOP ROBOT MOV MOTOR3,#00H RET DK_VUNG_PHAI_1: CJNE R5,#01,DK_VUNG_LAC_PHAI RET DUNG_CONG_TAC3: LCALL QUAY_TRAI_C LCALL DELAY5 LJMP DUNG_QUAY KT_TIEP: CJNE R5,#02,DUNG_CONG_TAC3 LJMP DUNG_QUAY ;------------------------------------- LUI_LAI1: CLR RL4 ;CHO ROBOT CHAY LUI LAI CLR RL5 MOV MOTOR2,V_MOTORL_VT3 MOV MOTOR3,V_MOTORR_VP3 JB MAT_THAN_NHO,LUI_LAI1 MOV MOTOR2,#00H MOV MOTOR3,#00H RET ;------------------------------------- DK_VUNG_LAC_PHAI: CJNE R5,#02,DK_VUNG_TRAI_1 MOV R2,#50 KT_VUNG_LAC_PHAI: MOV B,P0 ;01234567 ; DJNZ R2,KT_VUNG_LAC_PHAI LJMP XU_LY XU_LY: CLR RL3 MOV MOTOR1,#V_MOTORL_VT2 LCALL SW3 JNB PRO,TIM_VAT_PHAI SJMP DK_VUNG_LAC_PHAI TIM_VAT_PHAI: LCALL STOP_CAMERA LCALL CUA_PHAI LCALL DELAY4 LCALL STOP LJMP CHO_NHAN_VAT_MOI2 CHO_NHAN_VAT_MOI2: LCALL STOP VE_TT2: ;QUAY CAMERA VE GIUA SETB RL3 MOV MOTOR1,#30 LCALL SW2 JNB PRO,DA_VE_TT2 LJMP VE_TT2 DA_VE_TT2: LCALL STOP_CAMERA LJMP DA_VE_TT2 RET CHUYEN: RET ;------------------------------------ DK_VUNG_TRAI_1: CJNE R5,#03,DK_VUNG_LAC_TRAI SETB RL3 MOV MOTOR1,V_MOTORL_VT2 LCALL SW1 JNB PRO,DUNG_CONG_TAC1 RET DUNG_CONG_TAC1: LCALL QUAY_PHAI_C LCALL DELAY5 MOV MOTOR2,#40 MOV MOTOR3,#40 CLR RL4 SETB RL5 K_VUNG_LAC_TRAI: MOV B,P0 ;01234567 ;11011111 CPL B.1 CPL B.3 MOV C,LEFT1 ORL C,B.1 ORL C,B.3 JC DK_VUNG_RA_NGOAI DJNZ R2,KT_VUNG_LAC_TRAI LJMP XU_LY2 XU_LY2: SETB RL3 MOV MOTOR1,#V_MOTORL_VT2 LCALL SW1 JNB PRO,TIM_VAT_TRAI SJMP DK_VUNG_LAC_TRAI TIM_VAT_TRAI: LCALL STOP_CAMERA LCALL CUA_TRAI LCALL DELAY4 LCALL STOP LJMP CHO_NHAN_VAT_MOI DK_VUNG_RA_NGOAI: RET CHO_NHAN_VAT_MOI: LCALL STOP VE_TT: ;QUAY CAMERA VE GIUA CLR RL3 MOV MOTOR1,#30 LCALL SW2 JNB PRO,DA_VE_TT LJMP VE_TT DA_VE_TT: LCALL STOP_CAMERA LJMP DA_VE_TT RET ;============ ============================================= DIEU_XUNG_PWM_ROBOT: MOV R5,VUNG CJNE R5,#00,DK_VUNG_PHAI_ROBOT1 JNB MAT_THAN_TO,KO_DUOI JB MAT_THAN_NHO,LUI_LAI LCALL STOP_CAMERA SETB RL4 ;CHO ROBOT CHAY TOI VAT SETB RL5 MOV MOTOR2,V_MOTORL_VT3 MOV MOTOR3,V_MOTORR_VP3 RET KO_DUOI: MOV MOTOR2,#00H MOV MOTOR3,#00H RET LUI_LAI: CLR RL4 ;CHO ROBOT CHAY LUI LAI CLR RL5 MOV MOTOR2,V_MOTORL_VT3 MOV MOTOR3,V_MOTORR_VP3 JB MAT_THAN_NHO,LUI_LAI MOV MOTOR2,#00H MOV MOTOR3,#00H RET DK_VUNG_PHAI_ROBOT1: CJNE R5,#01,DK_VUNG_TRAI_ROBOT1 LCALL STOP_CAMERA CLR RL5 ;QUAY PHAI ROBOT SETB RL4 MOV MOTOR2,V_MOTORL_VT3 MOV MOTOR3,V_MOTORR_VP3 RET ;------------------------------------ DK_VUNG_TRAI_ROBOT1: CJNE R5,#03,DK_LAC_VAT_TRAI LCALL STOP_CAMERA CLR RL4 ;QUAY TRAI ROBOT SETB RL5 MOV MOTOR2,V_MOTORL_VT3 MOV MOTOR3,V_MOTORR_VP3 LJMP EXIT_DIEU_XUNG_PWM DK_LAC_VAT_TRAI: CJNE R5,#04,DK_LAC_VAT_PHAI LCALL STOP_CAMERA CLR RL4 ;QUAY TRAI ROBOT SETB RL5 MOV MOTOR2,V_MOTORL_VT3 MOV MOTOR3,V_MOTORR_VP3 ;LCALL DELAY4 RET DK_LAC_VAT_PHAI: CJNE R5,#02,EXIT_DIEU_XUNG_PWM LCALL STOP_CAMERA CLR RL5 ;QUAY PHAI ROBOT SETB RL4 MOV MOTOR2,V_MOTORL_VT3 MOV MOTOR3,V_MOTORR_VP3 RET EXIT_DIEU_XUNG_PWM: RET ;==== ==========CAC HAM VAN TOC =========================== TOC_DO_CHAM: ;====== ===VAN TOC CHO BEN TRAI============================= MOV V_MOTORL_VT1,#00 MOV V_MOTORL_VT2,#20 MOV V_MOTORL_VT3,#30 ;0000 ;===== =====VAN TOC CHO BEN PHAI============================= MOV V_MOTORR_VP1,#00 MOV V_MOTORR_VP2,#20 MOV V_MOTORR_VP3,#30 ;000 MOV V_MOTORR_VP6,#30 RET TOC_DO_TRUNG_BINH: ;==== =====VAN TOC CHO BANH TRAI============================= MOV V_MOTORL_VT1,#150 MOV V_MOTORL_VT2,#130 MOV V_MOTORL_VT3,#30 ;0000 MOV V_MOTORL_VT4,#80 MOV V_MOTORL_VT5,#50 MOV V_MOTORL_VT6,#20 MOV V_MOTORL_VT7,#10 MOV V_MOTORL_VT8,#00 ;====== =====VAN TOC CHO BANH PHAI============================= MOV V_MOTORR_VP1,#150 MOV V_MOTORR_VP2,#130 MOV V_MOTORR_VP3,#40 ;000 MOV V_MOTORR_VP4,#80 MOV V_MOTORR_VP5,#50 MOV V_MOTORR_VP6,#30 MOV V_MOTORR_VP7,#10 MOV V_MOTORR_VP8,#00 RET TOC_DO_NHANH: ;======= ==VAN TOC CHO BANH TRAI============================= MOV V_MOTORL_VT1,#210 MOV V_MOTORL_VT2,#150 MOV V_MOTORL_VT3,#120 MOV V_MOTORL_VT4,#100 MOV V_MOTORL_VT5,#80 MOV V_MOTORL_VT6,#50 MOV V_MOTORL_VT7,#20 MOV V_MOTORL_VT8,#10 ;===== ======VAN TOC CHO BANH PHAI========================== MOV V_MOTORR_VP1,#210 MOV V_MOTORR_VP2,#150 MOV V_MOTORR_VP3,#120 MOV V_MOTORR_VP4,#100 MOV V_MOTORR_VP5,#80 MOV V_MOTORR_VP6,#50 MOV V_MOTORR_VP7,#20 MOV V_MOTORR_VP8,#10 RET DOI50ms: MOV R1,#15 LOOP_DOI50MS: MOV R0,#255 DJNZ R0,$ DJNZ R1,LOOP_DOI50ms MOV R0,#00H MOV R1,#00H RET ;============================================================ DELAY800MS: LCALL DOI50ms LCALL DOI50ms RET ;============================================================= DOI1S: MOV R1,#255 LOOP_DOI1S: MOV R0,#255 DJNZ R0,$ DJNZ R1,LOOP_DOI1S RET DELAY4: PUSH 00H MOV R0,#100 MOV TMOD,#01H DL44: MOV TH0,#HIGH(200) MOV TL0,#LOW(200) SETB TR0 JNB TF0,$ CLR TF0 CLR TR0 DJNZ R0,DL44 POP 00H RET DELAY5: PUSH 00H MOV R0,#1 MOV TMOD,#01H DL5: MOV TH0,#HIGH(50) MOV TL0,#LOW(50) SETB TR0 JNB TF0,$ CLR TF0 CLR TR0 DJNZ R0,DL5 POP 00H RET END

Các file đính kèm theo tài liệu này:

  • docBao cao do an 2.doc