Để ổn định tốc độ của xe, nhóm đã ứng dụng thuật toán PID vào điều khiển 2 động cơ. Lấy tín hiệu tốc độ đầu ra của từng động cơ, nhóm đã sử dụng 2 Encoder cho từng bánh xe. Mạch Volume xoay Rotary Encoder 360 độ không giới hạn số vòng quay, encoder đưa
Hình 3.30. Mô phỏng khối động cơ trên Proteus
Hình 3.28. Sơ đồ chân Module BTS7690 43A
47 ra 2 xung vuông 90 độ gọi là 2 phase A và B, xung từ encoder đưa ra có thể dùng để nhận biết chiều quay, tốc độ quay, vị trí, module cung cấp 2 ngõ ra cho 2 phase và 1 ngõ ra dạng nút nhấn.
Thông số:
- Điện áp sử dụng: 3~5VDC - Độ phân giải 20 xung/vòng. Các chân tín hiệu: - VCC: Chân cấp nguồn 3~5VDC - GND: chân âm - CLK: phase A - DT: phase B - SW: button 3.2.5. Nguồn ắc quy
Khối nguồn cung cấp dòng điện và điện áp cho các khối khác hoạt động, dựa vào ngõ vào điện áp, dòng điện cấp vào của các thiết bị để chọn lựa nguồn cho thích hợp.
Dòng điện và điện áp hoạt động của Arduino Uno R3 là 30mA và 5VDC.Lựa chọn nguồn cung cấp cho Arduino hoạt động cần chú ý đến điện áp và dòng điện. Đặc biệt là dòng điện.
Công suất tải trong mạch:
- 3 Arduino Uno R3:5 x 0.03 x 3= 0.45 (W)
48 - Động cơ DC: 2 x 35 W= 70 (W)
- Step motor: 12 x 3 = 36 (W) - Tổng công suất P = 106.45 (W)
Lựa chọn bình ắc quy cung cấp nguồn cho sự hoạt động của xe là điều vô cùng quan trọng.Thời gian sử dụng ắc quy được tính như sau:
t = × × = × × .
. = 7 (h)
Với:A là dung lượng của ắc quy; V là điện áp ngõ ra của ắc quy; n là hệ số sử dụng của ắc quy ( thông thường là 0.7); P là công suất tải (tổng công suất trên mạch).
Thông số kỹ thuật của bình ắc quy Đồng Nai: Dung lượng: 12V – 90Ah
Hình 3.32. Ắc quy
Kết luận: sau khi tính toán và đưa ra giá trị kết hợp cho xe chạy thực nghiệm trên khuôn viên khoa cơ khí động lực, chúng em cấp nguồn cho khối động cơ gồm hai bình acquy nối song song, khối điều khiển lái là một bình.Để đảm bảo an toàn cho các linh kiện chúng em gắn thêm 1 bộ cầu chì đề phòng quá dòng
49
3.3. THIẾT BỊ, LINH KIỆN, MÔ-ĐUN VÀ SƠ ĐỒ NGUYÊN LÝ TOÀN MẠCH CỦA HỆ THỐNG CỦA HỆ THỐNG
Bảng 3.2. Bảng thống kê các linh kiện, thiết bị nhóm đã sử dụng
Tên linh
kiện Hình ảnh Chức năng Thông số kỹ thuật
Động cơ bước size 57 Dẫn động cho hệ thống bánh răng trục vít Giữ cho hệ thống lái chạy thẳng Góc bước: 1.8 độ Số pha: 2 pha Dòng điện: 3.0A Momen xoắn: 1.8Nm Khối lượng: 1.05KG Đường kính trục: 6.35mm Số dây: 4 dây Drive TB6600 Điều khiển động cơ bước nhờ tín hiệu từ arduino
Nối với nguồn điện từ 9 - 40VDC Bánh răng trục vít Nhận mô-men từ động cơ bước và dẫn động thước lái Tỉ số truyền 55 Modun 1 Góc ren xoắn 8.0171 độ Khoáng cách trục 32 Góc biên dạng ren 19.8198 độ Bước ren 3.14 mm Chiều rộng bánh vít 42.75 mm Mo-men xoắn 0.194Nm 18.727 Nm
50 Laptop HP
pavilion 15
Triển khai thuật toán, traning các model, chạy thuật toán chính, điều khiển Arduino
CPU Intel Core i5-8265U Ram 4 GB, DDR4, 2666 MHz
GPU NVIDIA GeForce MX130 2 GB & Intel UHD Graphics 620
Arduino Uno R3
Điều khiển động cơ bước, điều khiển PID SRAM 2 KB (ATmega328P) EEPROM 1KB Tốc độ 16Mhz Arduino Nano Điều khiển hệ thống giảm rung cho camera ATmega328P-AU UART: CH340. EEPROM: 1KB Clock Speed: 16Mhz. SRAM: 2KB Camera Logitech C270 Thu thập hình ảnh về cho thuật toán Độ phân giải 3MP Kết nối qua cổng USB Khối lượng 0.2 kg Servo MR
996
Cân bằng 3 góc Pitch Yaw Roll theo điều khiển của arduino nano Chủng loại: Analog RC Servo. Điện áp: 4.8~6.6VDC Tốc độ quay: 0.17sec / 60 degrees 0.13sec / 60 degrees Cảm biến MPU 6050 Thu thập tín hiệu gia tốc gửi về cho arduino nano
Điện áp sử dụng: 3~5VDC Điện áp giao tiếp: 3~5VDC Chuẩn giao tiếp: I2C Giá trị Gyroscopes trong khoảng: +/- 250 500 1000 2000 degree/sec
51 Giá trị Acceleration trong khoảng: +/- 2g, +/- 4g, +/- 8g, +/- 16g Module Encoder Nhận tính hiệu thông qua bánh răng dẫn động từ động cơ Điện áp sử dụng: 3~5VDC Độ phân giải 20 xung/vòng.
Giảm áp 12V Giảm áp 12v cho hệ thống giảm rung và driver TB6600
Điện áp đầu vào: Từ 3V đến 30V.
Điện áp đầu ra: Điều chỉnh được rong khoảng 1.5V đến 30V.
Dòng đáp ứng tối đa là 3A. Hiệu suất: 92% Công suất: 15W Module Rơle Đóng ngắt nguồn động cơ khi có biển báo Stop
Sử dụng điện áp nuôi DC 5V.
Relay mỗi Relay tiêu thụ dòng khoảng 80mA. Điện thế đóng ngắt tối đa: AC250V ~ 10A hoặc DC30V ~ 10A.
Có đèn báo đóng ngắt trên mỗi Relay.
Có thể chọn mức tín hiệu kích 0 hoặc 1 qua jumper.
52 Động RS 550 Làm lực đẩy cho xe di chuyển DC 6V: tốc độ 3600 vòng/phút không tải. Dòng điện: 1.3A DC 9.6V: tốc độ 7000vòng/phút không tải. Dòng điện: 1.6A DC 12V: tốc độ 11000vòng/phút không tải. Dòng điện: 1.8A Module BTS 7690 43A Điều khiển động cơ RS 550 thông qua Arduino Nguồn: 6 ~ 27V.
Dòng điện tải mach: 43A (Tải trở) hoặc 15A (Tải cảm).
Tín hiệu logic điều khiển: 3.3 ~ 5V.
Tần số điều khiển tối đa: 25KHz.
Ắc qui 12V Cấp nguồn cho
toàn bộ hệ thống
Ắc quy thắp sáng dân dụng. - Điện thế: 12V.
- Dung lượng: 20Ah. - Kích thước (Dài x Rộng x Cao): 232 x 91 x 165 mm. - Tổng cao: 185 mm. - Icc (CCA) (A): 60. - Dung tích axít: 2.0L. - Số tấm cực/ hộc: 9. - Vị trí cọc: Trái. - Trọng lượng: 4.44 kg.
53
54
3.4. LẬP TRÌNH HỆ THỐNG 3.4.1. Lập trình PID cho động cơ 3.4.1. Lập trình PID cho động cơ
Động cơ ban đầu được lập trình điều khiển qua mạch BTS với thuật toán đơn giản như sau: Serial.begin(9600); pinMode(motorA1, OUTPUT); pinMode(motorA2, OUTPUT); pinMode(motorB1, OUTPUT); pinMode(motorB2, OUTPUT);
pinMode(9,OUTPUT); //toc do banh phai pinMode(11,OUTPUT); //toc do banh trai
digitalWrite(motorA1, 1); digitalWrite(motorA2, 0); digitalWrite(motorB1, 1); digitalWrite(motorB2, 0); analogWrite(9,vSpeed);
analogWrite(11,vSpeed-them); digitalWrite(2,HIGH);
Nguyên lý của thuật toán bao gồm việc đóng mở các chân transistor để điều khiển động cơ, nhược điểm của thuật toán này sẽ làm động cơ chạy không đồng tốc độ với nhau, dẫn đến xe sẽ chạy lệch so với đường thẳng, nhược điểm sẽ ảnh hưởng rất nhiều tới độ chính xác của xe nếu cho xe chạy với đường dài, khi thực nghiệm ở sa hình rộng hơn và phức tạp hơn. Vì vậy nhóm em đã tạo thêm một thuật toán pid số dựa trên cơ sở có sẵn.
PID được tính như sau:
Tốc độ được thiết lập là: 995 vòng Thời gian lấy mẫu là T: 0,01 giây
Biến Error = tốc độ đặt – tốc độ, tốc độ được tính theo số xung của động cơ x = 2*T*Kp + Ki*T*T + 2*Kd
y = T*T*Ki – 4xKd - 2*T*Kp z = 2*Kd
55 Thuật toán được tham khảo từ Ths.Nguyễn Văn Đông Hải khoa Điện - Điện tử trường Đại học Sư Phạm Kỹ Thuật Tp.HCM.
Vì động cơ dẫn động thông qua hộp số bao gồm 4 bánh răng và tín hiệu encoder được dẫn động từ một bánh răng được thiết kế đi kèm nên việc tính toán chỉ số Kp Ki Kd trên lý thuyết là rất khó khăn vì sai số từ động cơ và bánh răng dẫn động module PID là rất lớn kèm theo khi xe di chuyển với các điều kiện có tải hoặc không tải, vì vậy nên chúng em quyết định cho xe chạy không tải và cho kết nối với một mạch đo điện áp từ động cơ, sau đó tiến hành quan sát mức thay đổi điện áp của động cơ chúng em tiến hành chọn lọc ra chỉ số phù hợp và ổn định nhất. Sau đó tiến hành cho xe chạy có tải và chạy trực tiếp trên mặt đường nhiều lần và tiến hành đo đạc, quan sát xe khi chạy, độ lệch của xe so với điểm xuất phát ban đầu, và chọn ra các chỉ số phù hợp nhất, bảng thống kê các lần chạy thử sẽ được liệt kê ở mục kết luận và đánh giá.
.
Hình 3.35. Mạch đo điện áp từ động cơ
56 - Phương pháp dò chỉ số Kp Ki Kd
Hình 3.37. Mô phỏng 2D bánh răng dẫn động encoder
Hình 3.38. Bánh răng hoàn chỉnh được lắp đặt trên xe
57
3.4.2. Cài đặt Anaconda3 và NvidiaCuda
Cài đặt Anaconda3: Yêu cầu phần cứng và phần mềm:
- Hệ điều hành: Win 7, Win 8/8.1, Win 10, Red Hat Enterprise Linux/CentOS 6.7, 7.3, 7.4, and 7.5, and Ubuntu 12.04+.
- Ram tối thiểu 4GB
- Ổ cứng trống tối thiểu 3GB để tải và cài đặt Tiến hành cài đặt Anaconda3 theo các bước:
59
60 Anaconda3 là chương trình tạo ra các môi trường để chạy thuật toán, ta khới tạo môi trường Anaconda với ngôn ngữ Python với câu lệnh như sau:
conda create -n name anaconda python=3.6.8 *name là tên môi trường đặt
Cách mở môi trường đã cài theo câu lệnh:
Activate name
Trong đó name là tên môi trường ta đã đặt lúc khởi tạo Câu lệnh tải và cài đặt thư viện như sau
Conda install numpy==1.1.2
Numpy là tên thư viện 1.1.2 là phiên bản của thư viện
Câu lệnh kiểm tra các thư viện đã cài trên môi trường như sau
Conda list
3.4.3. Sửa đổi thuật toán training
Để việc training thuật toán của xe có hiệu suất tốt nhất và ổn định, nhóm em đã khởi tạo 2 môi trường khác nhau, một môi trường traning và một môi trường chạy thuật toán, nguyên nhân xuất phát từ việc GPU của các máy có đời và phiên bản khác nhau nên việc thích ứng các phiên bản của thư viện cũng khác nhau.
61
62
63 Thuật toán training được chỉnh sửa bao gồm:
Số lượng thư mục ảnh đầu vào tăng từ 3 ở thuật toán cũ y1 = len(glob.glob(os.path.join("D:\\thuthapanh\\thang1",'*jpg'))) y2 = len(glob.glob(os.path.join("D:\\thuthapanh\\cong1",'*jpg'))) y3 = len(glob.glob(os.path.join("D:\\thuthapanh\\thang2",'*jpg')))
được gia tăng lên 8
y1 = len(glob.glob(os.path.join("D:\\thuthapanh\\t1",'*jpg'))) y2 = len(glob.glob(os.path.join("D:\\thuthapanh\\t2",'*jpg'))) y3 = len(glob.glob(os.path.join("D:\\thuthapanh\\t3",'*jpg'))) y4 = len(glob.glob(os.path.join("D:\\thuthapanh\\t4",'*jpg'))) y5 = len(glob.glob(os.path.join("D:\\thuthapanh\\c1",'*jpg'))) y6 = len(glob.glob(os.path.join("D:\\thuthapanh\\c2",'*jpg'))) y7 = len(glob.glob(os.path.join("D:\\thuthapanh\\c3",'*jpg'))) y8 = len(glob.glob(os.path.join("D:\\thuthapanh\\c4",'*jpg')))
Số lớp quét tăng từ 4 lên 8 number_class = 4 => 8
Số ảnh 1 lần quét giảm từ 500 xuống 300 batchsize = 500 => 300 # số hình 1 lần quét
Ma trận gán cho số lượng hình được tăng từ 3 lên 8 y = np.asarray([0]*y1 + [1]*y2 + [2]*y3 )
tăng lên thành
y = np.asarray([0]*y1+[1]*y2+[2]*y3+[3]*y4+[4]*y5+[5]*y6+[6]*y7+7*[y8])
Việc thay đổi thuật toán này là vì mở rộng phạm vi hoạt động của xe nên việc gia tăng số lượng ảnh đầu vào là điều cần thiết
Đồng thời việc gia tăng số lượng ảnh thì đi kèm theo đó là số lớp quét và ma trận gán cho các mục ảnh cũng được gia tăng theo phù hợp
Tuy nhiên vì số lượng ảnh train được giảm đi so với bản cũ trung bình từ 4000 ~ 5000 còn 800 ~ 1000 ảnh nên số ảnh quét cho 1 lần được giảm xuống còn 300 để tăng độ chính xác, ổn định cho file sau khi train
64
Cài đặt CUDA 10:
Vì thuật toán vẫn sử dụng tensorflow nên việc cần thiết là phải cài đúng CUDA và lib cuDNN, CUDA dùng để tính toán song song còn cuDNN là thư viện hỗ trợ Deeplearning gọi lệnh CUDA, vậy nên khi cài đặt cần cài CUDA trước sau đó tiến hành cài cuDNN sau.
Kiểm tra GPU có thích hợp cài CUDA hay không phải dùng GPUz, CUDA là công nghệ của Nvidia nên các máy tính có card đồ họa AMD/ATI sẽ không chạy được CUDA.
Tiến hành cài đặt CUDA 10.1:
Download CUDA 10 trên web của Nvidia, chọn phiên bản phù hợp với window
Sau khi tải xong tiến hành cài đặt bình thường, sau đó khởi động lại máy tính.
Cài thư viện cuDNN
Đầu tiên đăng ký tài khoản developer, sau khi đăng kí xong tải cuDNN Chọn cuDNN library for windows 10, không nện chọn bản mới hơn 7.6.5
65 Sau khi tải xong, giải nén và copy tất cả các file vào thư mục theo đường dẫn
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1. Sau đó khởi động máy vậy là xong.
66
3.4.4. Xây dựng lưu đồ giải thuật 3.4.4.1. Lưu đồ nhận diện lane 3.4.4.1. Lưu đồ nhận diện lane
Khi đã có module được traning, ta sẽ dùng model này để nhận diện và điều khiển. Tùy thuộc vào phạm vi hoạt động của xe ta có thể xây dựng các class tương ứng để xe có thể hoạt động một cách chính xác nhất.
3.4.4.2. Lưu đồ nhận diện biển báo Stop
Việc đầu tiên chúng ta cần phải khởi tạo các thư viện của Opencv để hỗ trợ cho việc thu thập dữ liệu. Tương tự phần trên sau khi lấy được ảnh đầu vào ta tiến hành chuẩn hóa theo lưu đồ giải thuật trên.
Đọc ảnh đầu vào và tiến hành xử lý giống với phần thu thập dữ liệu để phù hợp với model nhiện diện biển báo Stop đã được huấn luyện. Đưa ảnh vào nhận diện, khi nhận diện được biển báo Stop thì thuật toán sẽ vẽ một hình chữ nhật bao xung quanh biển báo để thông báo là đã xác định được vât.Sau đó diện tích của biển báo sẽ được tính toán theo đơn vị là pixel,khi diện tích biển báo lớn hơn giá trị cho phép thì tính hiệu sẽ được truyền xuống
67 để dừng xe,còn ngược lại khi diện tích biển báo nhỏ hơn chứng tỏ xe chưa đến vị trí cần dừng lại thì xe vẫn xe đi thẳng.
Hình 3.56. Nhận diện biến báo Stop ở trong xưởng
68
3.4.4.3 Cải tiến thuật toán training cho ảnh màu và thiết kế bộ CNN mới
Thuật toán training cũ chỉ train được các hình ảnh trắng đen, điều này làm khả năng tiếp cận các hình ảnh màu hoặc ảnh thực tế bị gặp khó khăn, vì vậy việc phát triển một thuật toán traning mới và kiểm soát tốt quá trình train bằng cách tạo các biểu đồ tương ứng, đồng thời tạo dựng kiến trúc CNN mới tốt hơn
Tạo kiến trúc CNN mới
Để tạo kiến trúc CNN mới tốt hơn kiến trúc CNN cũ ta cần tạo dựng CNN cũ và phân tích rõ thành phần cấu tạo bên trong kiến trúc CNN cũ.
model = Sequential()
model.add(Conv2D(8, kernel_size=(7, 7), # 8 chanel . 7*7 kích thước c ửa sổ để quét các object, tùy vào kích thước object để chọn kích thước cửa sổ
activation='relu', # bỏ giá trị âm
strides=(2, 2), # độ trượt input_shape= (400,200,3), # kích thước ảnh 60*200*3(RGB) padding='valid',)) model.add(Conv2D(16, kernel_size=(5, 5), activation='relu', strides=(2, 2), padding='valid',)) model.add(Conv2D(32, kernel_size=(5, 5), activation='relu', strides=(2, 2), padding='valid',)) model.add(Conv2D(64, kernel_size=(3, 3), activation='relu', strides=(1, 1), padding='valid',)) model.add(Conv2D(64, kernel_size=(3, 3), activation='relu', strides=(1, 1), padding='valid',))
model.add(Dense(number_class, activation='softmax'))
model.summary()
- Phân tích: số lượng tích chập
Lần tích chập đầu tiên là tích chập với filter lớn số lượng filter nhỏ mục đích là để lấy đặc điểm ảnh 1 cách cục bộ và giảm thiểu thời gian traning vì lượng ảnh cần training quá lớn 4000 đến 6000 ảnh cho một cung đường
Các lần tích chập lần sau thì số lượng filter và kích thước filter được giảm dần, từ ma trận được tích chập bởi các lần tích chập trước.
69 Hàm kích hoạt là relu và dùng solfmax để chuyển đổi ma trận thành các vecto xác suất.
Bảng 3.3. Phân tích số lượng tích chập
Số lần Số lượng ma trận
filter Kích thước filter Kích thước ma trận tổng hợp
1 8 7x7 2x2
2 16 5x5 2x2
3 32 5x5 2x2
4 64 3x3 1x1
5 64 3x3 1x1
Tạo dựng kiến trúc CNN mới: model = Sequential()
model.add(Conv2D(filters=32, kernel_size=(5,5), activation='relu', input_s
hape=X_train.shape[1:]))
model.add(Conv2D(filters=32, kernel_size=(5,5), activation='relu')) model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Dropout(rate=0.25))
model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu')) model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu')) model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Dropout(rate=0.25)) model.add(Flatten())
model.add(Dense(256, activation='relu')) model.add(Dropout(rate=0.5))
model.add(Dense(43, activation='softmax'))
Điều khác biệt khi tạo dựng kiến trúc mới là sử dụng bộ filter nhỏ hơn so với bộ