5.1 Kết quả
5.1.1 Kết quả mô phỏng trên Matlab Simulink
Mơ hình hóa Robot Scara trên Matlab Simulink từ mơ hình thiết kế 3D:
Hình 5.1: Mơ hình hóa Robot Scara trên Matlab Simulink
Mơ hình 3D mơ phỏng trên Matlab Simulink
5.1.2 Kết quả thực tế của mơ hình Robot Scara5.1.2.1 Kết quả thực nghiệm PID từng khớp 5.1.2.1 Kết quả thực nghiệm PID từng khớp
Sau khi áp dụng các phương pháp xác định thông số của bộ điều khiển PID được nêu ở chương 2 và tiến hành thử thực nghiệm trên động cơ DC thì em đã xác định được thơng số PID cho từng khớp như sau:
Khớp 1: Thông số PID được hiệu chỉnh qua thực nghiệm như sau: KP
=7.5; KI=0.17; KD = 0.045
Hình 5.3: Kết quả chạy thực nghiệm PID trên khớp 1
Nhận xét: Kết quả đạt được không sai lệch quá nhiều so với giá trị đặt, số
mm thu được sau khi hồn tất q trình là 64,04 mm so với giá trị đặt ban đầu là 64mm , tốc độ đáp ứng của động cơ tương đối nhanh và ổn định.
Khớp 2: Thông số PID được hiệu chỉnh qua thực nghiệm như sau: KP
=7.5; KI=0.17; KD = 0.04
Nhận xét: Kết quả đạt được không sai lệch quá nhiều so với giá trị đặt, số độ
thu được sau khi hồn tất q trình là 45,36 độ so với giá trị đặt ban đầu là 45 độ, tốc độ đáp ứng của động cơ tương đối nhanh và ổn định.
Khớp 3: Thông số PID được hiệu chỉnh qua thực nghiệm như sau: KP
=7.5; KI=0.18; KD = 0.045
Hình 5.5: Kết quả chạy thực nghiệm PID trên khâu 3
Nhận xét: Kết quả đạt được không sai lệch quá nhiều so với giá trị đặt, số độ
thu được sau khi hồn tất q trình là 45,29 độ so với giá trị đặt ban đầu là 45 độ, tốc độ đáp ứng của động cơ tương đối nhanh và ổn định.
5.1.2.2 Kết quả thực tế của tay gắp
Để có thể gắp và thả vật thì ta khơng ta bỏ qua hoạt động của tay gắp. Dưới đây là những hình ảnh về hoạt động của tay gắp trong thực tế.
Hình 5.6: Tay gắp thực hiện gắp vật
5.1.2.3 Kết quả thực tế động học của Robot Scara
Để đánh giá được tính ổn định và độ chính xác của Robot thì ta tiến hành chạy thực tế động học thuận và động học ngược của Robot.
Động học thuận
Nhập các thông số ban đầu như sau: d1 = 64; theta2 = 45; theta3 = 45.
Hình 5.8: Kết quả chạy thực tế động học thuận của Robot Scara
Động học ngược
Nhập các thông số ban đầu như sau: PX = 300; PY = 100; PZ = 50.
Hình 5.9: Kết quả chạy thực tế động học ngược của Robot Scara
Nhận xét: Thông qua việc chạy thực tế động học thuận và động học ngược
nhiều lần trên mơ hình thì em nhận thấy rằng: mơ hình hoạt động tương đối ổn định, tốc độ đáp ứng của động cơ nhanh, các giá trị thông số khớp và vị trí của tay gắp đạt đúng giá trị đã đặt ban đầu.
5.1.3 Kết quả chạy thực tế của mơ hình Robot Scara phân loại sản phẩm5.1.3.1 Phân loại sản phẩm theo màu sắc 5.1.3.1 Phân loại sản phẩm theo màu sắc
Trường hợp các vật đều là hình trịn
Hình 5.11: Quá trình phân loại màu sắc các vật hình tròn của Robot Scara
Trường hợp các vật đều là hình vng
Hình 5.13: Quá trình phân loại màu sắc các vật hình vuông của Robot Scara
5.1.3.2 Phân loại sản phẩm theo hình dạng
Trường hợp các vật đều là màu đỏ
Hình 5.15: Quá trình phân loại hình dạng các vật màu đỏ của Robot Scara
Trường hợp các vật đều là màu xanh lá
Hình 5.17: Quá trình phân loại hình dạng các vật màu xanh lá của Robot Scara
Trường hợp các vật đều là màu xanh dương
Hình 5.19: Quá trình phân loại hình dạng các vật màu xanh dương của Robot Scara
5.1.3.3 Phân loại sản phẩm theo màu sắc và hình dạng
Hình 5.21: Quá trình phân loại màu sắc và hình dạng của Robot Scara
5.2 Đánh giá
- Khả năng nhận dạng màu sắc từ q trình xử lý ảnh là hồn tồn ổn định và chính xác cho cả ba màu đỏ, xanh lá và xanh dương.
- Khả năng nhận dạng hình dạng từ q trình xử lý ảnh là tương đối chính xác, do vẫn cịn xuất hiện những trường hợp khơng nhận dạng được hình dạng của sản phẩm chủ yếu là hình vng. Nhưng tỷ lệ xảy ra trường hợp này thấp nên có thể tạm chấp nhận được.
- Giải thuật điều khiển PID tốt, đáp ứng nhanh và sai số thấp dưới 1 %. - Mơ hình thiết kế cơ khí Robot hoạt động tương đối ổn định.
- Robot vận hành tốt gắp và thả vật chính xác đúng vị trí đã đặt ban đầu.
5.3 Kết luận
Đề tài cơ bản đã hoàn thành được các nhiệm vụ được giao ban đầu, xây dựng được chương trình điều khiển hồn chỉnh cho một mơ hình Robot phân loại sản phẩm theo màu sắc và hình dạng thơng qua giao diện người dùng. Tuy nhiên, vẫn không
khỏi nhiều thiếu sót, xảy ra các vấn đề chưa giải quyết như: q trình xử lý ảnh cịn phụ thuộc vào độ sáng môi trường, nhiễu sáng, dẫn đến kết quả phân tích cịn sai sót.
5.3.1 Kết quả đạt được
- Xây dựng thành cơng phương trình động học thuận và động học ngược cho Robot.
- Thiết kế hồn chỉnh mơ hình 3D trên phần mềm Autodesk Inventor. - Mơ phỏng thành cơng mơ hình Robot Scara trên Matlab Simulink. - Chế tạo thành cơng mơ hình Robot Scara thực tế.
- Xây dựng được sơ đồ mạch điều khiển cho Robot.
- Áp dụng giải thuật PID điều khiển vị trí cho động cơ DC. - Giao tiếp cổng COM thành cơng cho máy tính với Arduino. - Giao tiếp I2C giữa các board Arduino với nhau.
- Thiết kế được giao diện người dùng trên phần mềm Matlab.
- Xác định được vị trí, màu sắc, hình dạng của sản phẩm thơng qua camera. - Hồn thành phân loại sản phẩm theo màu sắc: màu đỏ, xanh lá và xanh dương. - Hồn thành phân loại sản phẩm theo theo hình dạng: hình trịn và hình vng. - Robot Scara vận hành tốt, gắp và thả vật chính xác đúng vị trí đã đặt ban đầu.
5.3.2 Những hạn chế của đề tài
- Do sai sót trong q trình thiết kế và chế tạo nên khâu tịnh tiến của Robot khi hoạt động sinh ra tiếng ồn.
- Khi điều khiển với tốc độ nhanh sẽ xảy ra hiện tượng giật lắc.
- Đề tài chỉ dừng lại ở việc phân loại được các màu sắc và hình dạng cơ bản.
5.4 Hướng phát triển
- Cải tiến mơ hình cơ khí cứng vững hơn và chọn động cơ có cơng suất cao hơn để giúp cho Robot vận hành tốt hơn, ít sai số và gắp được các vật nặng.
- Cải tiến khả năng nhận dạng sản phẩm, để có thể nhận dạng được nhiều màu sắc và hình dạng hơn.
- Thiết kế bộ điều khiển cánh tay đi theo một quỹ đạo mong muốn trong không gian làm việc.
- Sử dụng các bộ điều khiển thông minh như: điều khiển trượt, điều khiển luật mờ, điều khiển động lực học ngược, trí thơng minh nhân tạo,… để tạo ra cánh tay di chuyển có độ chính xác cao, tối ưu hóa năng lượng, tuyến tính hóa tính phi tuyến của cánh tay.
- Ứng dụng xử lý ảnh, nhận dạng xác định tọa độ đối tượng từ đó ra lệnh điều khiển cánh tay bám theo đối tượng.
- Nghiên cứu các giải thuật về xử lý ảnh sâu hơn, để lọc và khử các nhiễu nâng cao độ chính xác trong xử lý ảnh với camera chất lượng thấp, thuận tiện cho việc nghiên cứu.
- Kết hợp thêm Robot di chuyển đa hướng dưới đế Robot nhằm nâng cao khả năng cơ động, ứng dụng hơn nữa trong nhiều lĩnh vực khác nhau.
TÀI LIỆU THAM KHẢO
[1]. Ts.Ngơ Quang Hiếu, PGS Ts. Nguyễn Chí Ngơn (2016), Giáo trình kỹ thuật
Robot, Nhà xuất bản đại học Cần Thơ, Cần Thơ.
[2]. Nguyễn Thị Phương Hà (2005), Lí thuyết điều khiển tự động, Nhà xuất bản đại học quốc gia TP.Hồ Chí Minh, TP.Hồ Chí Minh.
[3]. Ts.Nguyễn Ngọc Phương (2004), Hướng dẫn thiết kế và lắp ráp Robot, Nhà xuất
bản Đà Nẵng, TP Hồ Chí Minh.
[4]. Hồ Văn Sung, Xử lý ảnh số - Lý thuyết và thực hành với Matlab (2009), Nhà xuất bản Khoa học và Kỹ thuật.
[5]. Nguyễn Quang Hoan, Giáo trình Xử lý ảnh (Năm 2006), Học viện công nghệ bưu chính viễn thơng.
[6]. Trương Tấn Thành, Trần Chí Nguyện, Thiết kế và chế tạo mơ hình Robot Scara phân loại sản phẩm (2019), Đại học Kỹ thuật – Công nghệ Cần Thơ.
[7]. “ Điều khiển cánh tay Robot phân loại vật theo màu sắc”. Một số đề tài luận văn tốt nghiệp Đại học Bách khoa thành phố Hồ Chí Minh.
Các website tham khảo:
[8]. https://ch.mathworks.com/Matlabcentral/answers/325725-sending-values-fromMatlab- to-Arduino-using-serial-communication [9]. https://circuitdigest.com/microcontroller-projects/serial-communicationbetween- Matlab-and-Arduino [10]. https://www.quora.com/How-can-I-send-MATLAB-data-strings-to-Arduino [11]. http://Arduino.vn/bai-viet/1053-giao-tiep-i2c-voi-nhieu-module [12]. https://project.makerbox.vn/2018/05/02/chia-se-cach-dieu-khien-pid-thuat-toan-pid/ [13]. https://vutienblog.com/lap-trinh-Matlab-gui-lam-quen-giao-dien-gui-trong-Matlab/ [14]. https://www.mathworks.com/Matlabcentral/fileexchange/37611-color-detection
PHỤ LỤC Code Master #include <Servo.h> #include <Wire.h> #define SERVO_PIN 9 Servo gServo;
int servoAVal servoBVal servoCVal; void setup() {
gServo.attach(SERVO_PIN); Wire.begin();
Serial.begin(9600); //initialize serial comunication }
void loop() {
while (Serial.available () > 2) { //Check if the serial data is available. delay(20);
char serialRead = Serial.read (); if (serialRead == 'a') {
servoAVal = Serial.parseInt (); Serial.print(servoAVal);
int16_t bigNum = servoAVal; byte myArray[2];
myArray[0] = (bigNum >> 8) &0xFF; myArray[1] = bigNum &0xFF;
Wire.beginTransmission(2); // Transmit to device #8 Wire.write(myArray, 2);
Wire.endTransmission(); // Stop transmitting }
if (serialRead == 'b') {
int16_t bigNum = servoBVal; byte myArray[2];
myArray[0] = (bigNum >> 8) &0xFF; myArray[1] = bigNum &0xFF;
Wire.beginTransmission(3); // Transmit to device #8 Wire.write(myArray, 2);
Wire.endTransmission(); // Stop transmitting }
if (serialRead == 'c') {
servoCVal = Serial.parseInt (); Serial.print(servoCVal);
int16_t bigNum = servoCVal; byte myArray[2];
myArray[0] = (bigNum >> 8) &0xFF; myArray[1] = bigNum &0xFF;
Wire.beginTransmission(4); // Transmit to device #8 Wire.write(myArray, 2);
Wire.endTransmission(); // Stop transmitting } if (serialRead == 'o') { gServo.write(170); } if (serialRead == 'f') { gServo.write(80); } } } Code Slave #include <Wire.h> #include <PID_v1.h>
#define MotEnable 6 //Motor Enamble pin Runs on PWM signal #define MotFwd 4 // Motor Forward pin
#define MotRev 7 // Motor Reverse pin int16_t bigNum;
int encoderPin1 = 2; //Encoder Output 'A' must connected with intreput pin of Arduino.
int encoderPin2 = 3; //Encoder Otput 'B' must connected with intreput pin of Arduino.
volatile int lastEncoded = 0; // Here updated value of encoder store. volatile long encoderValue = 0; // Raw encoder value
int REV = 0; // Set point REQUIRED ENCODER VALUE int lastMSB = 0; int lastLSB = 0;
double kp = 7.5 , ki = 0.18 , kd = 0.045 ; // Modify for optimal performance double input = 0, output = 0, setpoint = 0;
PID myPID(&input, &output, &setpoint, kp, ki, kd, DIRECT); void setup() {
Wire.begin(3);
Wire.onReceive(receiveEvent); pinMode(MotEnable, OUTPUT); pinMode(MotFwd, OUTPUT); pinMode(MotRev, OUTPUT);
Serial.begin(9600); //Initialize serial comunication pinMode(encoderPin1, INPUT_PULLUP);
pinMode(encoderPin2, INPUT_PULLUP);
digitalWrite(encoderPin1, HIGH); //Turn pullup resistor on digitalWrite(encoderPin2, HIGH); //Turn pullup resistor on //Call updateEncoder() when any high/low changed
seen //on interrupt 0 (pin 2), or interrupt 1 (pin 3) attachInterrupt(0, updateEncoder, CHANGE); attachInterrupt(1, updateEncoder, CHANGE);
TCCR1B = TCCR1B &0b11111000 | 1;
myPID.SetMode(AUTOMATIC); //Set PID in Auto mode
myPID.SetSampleTime(1); // Refresh rate of PID controller
myPID.SetOutputLimits(-175, 175); // This is the MAX PWM value to move motor, here change in value reflect change in speed of motor.
} void loop(){ while (Wire.available()) { byte a,b; a = Wire.read(); b = Wire.read(); bigNum = a; bigNum = bigNum << 8 | b; }
REV = map (bigNum, 0, 360, 0, 9360); // Mapping degree into pulse Serial.print("This is REV - ");
Serial.println(REV); // printing REV value
setpoint = REV; //PID while work to achive this value consider as SET value
input = encoderValue ; // Data from encoder consider as a Process value Serial.println("encoderValue- ");
Serial.println(encoderValue);
myPID.Compute(); // Calculate new output pwmOut(output);
}
// Drive motor CW
void receiveEvent(int howMany) {} void pwmOut(int out) {
if (out > 0) { // if REV > encoderValue motor move in forward direction. analogWrite(MotEnable, out);
digitalWrite(MotFwd, HIGH); digitalWrite(MotRev, LOW); }
else { // if REV < encoderValue motor move in reverse direction. analogWrite(MotEnable, abs(out)); digitalWrite(MotFwd, LOW);
digitalWrite(MotRev, HIGH); }
}
void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum ==
0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
lastEncoded = encoded; //store this value for next time }
Code Matlab GUIDE
function varargout = GUIDE_LV(varargin)
%GUIDE_LV MATLAB code file for GUIDE_LV.fig
% GUIDE_LV, by itself, creates a new GUIDE_LV or raises the existing % singleton*.
% H = GUIDE_LV returns the handle to a new GUIDE_LV or the handle to % the existing singleton*.
% GUIDE_LV('Property','Value',...) creates a new GUIDE_LV using the % given property value pairs. Unrecognized properties are passed via % varargin to GUIDE_LV_OpeningFcn. This calling syntax produces a
% warning when there is an existing singleton*.
% GUIDE_LV('CALLBACK') and GUIDE_LV('CALLBACK',hObject,...) call the
% local function named CALLBACK in GUIDE_LV.M with the given input
% arguments.
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)".
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help GUIDE_LV % Last Modified by GUIDE v2.5 25-Jun-2020 07:21:30
% Begin initialization code - DO NOT EDIT gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @GUIDE_LV_OpeningFcn, ... 'gui_OutputFcn', @GUIDE_LV_OutputFcn, ... 'gui_LayoutFcn', [], ...
'gui_Callback', []); if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1}); end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else
gui_mainfcn(gui_State, varargin{:}); end
% End initialization code - DO NOT EDIT
% --- Executes just before GUIDE_LV is made visible.
% This function has no output args, see OutputFcn. % hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% varargin unrecognized PropertyName/PropertyValue pairs from the % command line (see VARARGIN)
% Choose default command line output for GUIDE_LV handles.output = hObject; % Update handles structure
guidata(hObject, handles);
% UIWAIT makes GUIDE_LV wait for user response (see UIRESUME) % uiwait(handles.figure1); global s; global connect; global l1 l2 l3; l1 = 200; l2 = 185; l3 = 180; connect = 0; if (strcmp(get(s,'Status'),'open')) fclose(s); end set(handles.pumPorts,'Enable','on'); delete(s); s = serial('COM1'); set(handles.pumPorts,'String',getAvailableComPort);
% --- Outputs from this function are returned to the command line. function varargout = GUIDE_LV_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure varargout{1} = handles.output;
% --- Executes during object deletion, before destroying properties. function figure1_DeleteFcn(hObject, eventdata, handles)
% hObject handle to figure1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) global s; global myCam; if (strcmp(get(s,'Status'),'open')) fclose(s); end delete(s); clear all;
% --- Executes on selection change in pumPorts. function pumPorts_Callback(hObject, eventdata, handles)
% hObject handle to pumPorts (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% Hints: contents = cellstr(get(hObject,'String')) returns pumPorts contents as cell