LẬP TRÌNH HỆ THỐNG

Một phần của tài liệu Tối ưu hóa dữ liệu đầu vào và cải tiến tính ổn định cho xe tự hành đồ án tốt nghiệp ngành công nghệ kỹ thuật ô tô (Trang 62)

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ộ filter của kiến trúc CNN cũ đồng thời gia tăng số lượng filter lên gấp 4 lần. điều này giúp việc máy học được các đặc tính của ảnh một cách rõ ràng và chi tiết hơn đồng thời giảm số lần dùng ma trận tổng hợp nhằm giảm sự chuyển dịch giá trị đặc tính của ma trận.

70 Để kiểm soát và quan sát quá trình train, thì cách đơn giản và hiệu quả là chèn biểu đồ các giá trị accuracy và loss và thuật toán kiểm soát giá trị bằng biểu đồ được thiết kế như sau:

data = np.array(data) labels = np.array(labels)

print(data.shape, labels.shape)

#Splitting training and testing dataset

71 X_train, X_test, y_train, y_test = train_test_split(data, labels, test_siz e=0.2, random_state=42)

print(X_train.shape, X_test.shape, y_train.shape, y_test.shape) #Converting the labels into one hot encoding

y_train = to_categorical(y_train, 43) y_test = to_categorical(y_test, 43)

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=[

'accuracy']) epochs = 15

history = model.fit(X_train, y_train, batch_size=32, epochs=epochs, valida

tion_data=(X_test, y_test))

model.save("D:\\kethuc\\filetrain\\my_model.h5") #plotting graphs for accuracy

plt.figure(0)

plt.plot(history.history['accuracy'], label='training accuracy') plt.plot(history.history['val_accuracy'], label='val accuracy') plt.title('Accuracy') plt.xlabel('epochs') plt.ylabel('accuracy') plt.legend() plt.show() plt.figure(1)

plt.plot(history.history['loss'], label='training loss') plt.plot(history.history['val_loss'], label='val loss') plt.title('Loss')

plt.xlabel('epochs') plt.ylabel('loss') plt.legend() plt.show()

Ở biểu đồ cho thấy độ chính xác của thuật toán là 98% giá trị bị mất là 5% một kết quả rất cao so với một số lần thực nghiệm khác chỉ có mức ở 90% tuy nhiên để đảm bảo giá trị này là giá trị thực bằng cách dùng một mô hình test được thiết lập sẵn, thuật toán khá đơn giản để kiểm tra.

#testing accuracy on test dataset

from sklearn.metrics import accuracy_score y_test = pd.read_csv('Test.csv')

labels = y_test["ClassId"].values imgs = y_test["Path"].values data=[]

72

for img in imgs:

image = Image.open(img) image = image.resize((30,30)) data.append(np.array(image)) X_test=np.array(data)

pred = model.predict_classes(X_test) #Accuracy with the test data

from sklearn.metrics import accuracy_score

print(accuracy_score(labels, pred))

Sau khi kiểm tra trên mô hình test thì ta tiến hành sử dụng file train thực nghiệm để kiểm tra độ chính xác và hiệu quả ở môi trường tự nhiên.

73

CHƯƠNG 4: THỰC NGHIỆM VÀ ĐÁNH GIÁ

4.1. KẾT QUẢ

Sau 10 tuần thiết kế và thi công, nhóm đã hoàn thành mô hình xe tự hành dựa trên mô hình và cơ sở của nhóm cũ.

Về phần khung xe nhóm đã thay đổi 4 bánh xe từ bánh nhựa thành bánh cao su, hệ thống lái với 2 bánh răng thành bánh răng trục vít, vị trí lắp đặt camera vẫn không thay đổi, thiết kế bộ pid cho khối động cơ phía sau, lắp đặt hệ thống mạch điện, lắp đặt cầu chì trên xe, tháo dỡ một số bộ phận không cần thiết.

Hình 4.2. Mô hình xe sau khi thi công

74 Trong quá trình vận hành mặc dù hệ thống được lắp đặt PID nhưng vẫn chưa hoàn toàn làm xe hoạt động thẳng tuyệt đối. Thước lái được cải tạo tuy vẫn giữ được cho xe

Hình 4.5. Khi xe nhận diện thẳng

Hình 4.3. Mạch điện mới

75 chạy ổn định nhưng vào góc đánh lái vẫn chưa được tốt và chính xác.

Hình 4.6. Khi xe đi thẳng

76

4.2. THỰC NGHIỆM

4.2.1. Thực nghiệm xe nhận diện biển báo và lane

Nhóm chúng em thực nghiệm trong môi trường thực tế, với môi trường tự nhiên thì việc xe bị ảnh hưởng bởi ánh sáng ngoài trời là điều không thể tránh khỏi và rất khó để khắc phục. Vậy nên quá trình thực nghiệm nhóm chúng em sẽ dựa theo phương pháp của nhóm cũ tiến hành thực nghiệm trong nhiều ngày theo những điểm thời gian và cường độ sáng khác nhau, từ đó xây dựng bảng số liệu các lần cho xe chạy thực nghiệm.

Hình 4.8. Khi xe vào cua

77 - Nhận xét:

Qua quá trình thực nghiệm nhóm chúng em nhận thấy rằng việc gia cố thêm kết cấu của xe trở nên chắc chắn hơn rất quan trọng, việc lựa chọn tốc độ phù hợp cho xe, lựa chọn số ảnh mỗi giây trên khung hình, góc đánh lái ở mỗi đoạn cua là điều cần thiết để xe hoạt chính xác yêu cầu được đề ra.

Điều tiếp theo là về độ nhiễu vì ánh sáng và góc đổ bóng của tán cây thậm chí là bóng của chính chiếc xe là vẫn còn ảnh hưởng rất nhiều đến độ chính xác của xe.

4.2.2. Thực nghiệm PID ở khối động cơ của xe

Như trình bày ở bên trên, chúng em sẽ không để xe chạy Pid không tải và quan sát trên biểu đồ như các ví dụ trên lớp học, mà nhóm chúng em sẽ quan sát ra các bộ số Kp, Ki, Kd và tốc độ được cài đặt sẵn tiềm năng, sau đó tiến hành cho xe chạy thử (có tải) ở môi trường thực tế (khuôn viên khoa cơ khí động lực) từ đó đưa ra bảng thống kế và lựa chọn ra chỉ số Kp Ki Kd phù hợp nhất, ngoài ra để đảm bảo xe chạy đúng với yêu cầu nhóm chúng em còn lắp thêm 1 module đo đạc điện áp đầu ra của động cơ.

78 - Nhận xét: Tuy được thiết kế bộ PID cho động cơ trên xe, tuy nhiên khối động cơ vẫn không hoạt động chính xác như mong muốn mặc dù vẫn đáp ứng được các yêu cầu cơ bản đã đề ra.

4.3. THỐNG KÊ

4.3.1. Thống kê khi cho xe nhận diện biến báo và lane 4.3.1.1. Lập bảng thống kê 4.3.1.1. Lập bảng thống kê

Ở bảng thống kê của nhóm Nguyễn Trung Trực và Lê Mình Hùng được thực hiện vào tháng 5 và 6 2020 tức là vào mùa hè là thời điểm nắng lớn nhất trong năm, đồng nghĩa là ánh sáng có được nhiều nhất điều này là điều kiện gia tăng độ chính xác khi nhận diện lane và biển báo vì cường độ ánh sáng ảnh hưởng rất quan trọng đến quá trình nhận diện của thuật toán, bảng thống kê đó được mô tả ở bên dưới.

Bảng 4.8. Bảng thống kê thực nghiệm Giờ Số lần 7 AM 8 AM 9 AM 10 AM 11 AM 12 AM 1 PM 2 PM 3 PM 4 PM 5 PM 6 PM 1 O O O X O O O O O O O X 2 O O O O O O X O X X O X 3 X O O O O O X O O X O X 4 O O O O O O O O X O O O 5 O X X O O O O X X O X O 6 X O O X X O O O O X X X 7 O O O O X O O O O X O X

Một phần của tài liệu Tối ưu hóa dữ liệu đầu vào và cải tiến tính ổn định cho xe tự hành đồ án tốt nghiệp ngành công nghệ kỹ thuật ô tô (Trang 62)