Mục lục:

Sử dụng Arduino Uno cho XYZ Định vị 6 cánh tay robot DOF: 4 bước
Sử dụng Arduino Uno cho XYZ Định vị 6 cánh tay robot DOF: 4 bước

Video: Sử dụng Arduino Uno cho XYZ Định vị 6 cánh tay robot DOF: 4 bước

Video: Sử dụng Arduino Uno cho XYZ Định vị 6 cánh tay robot DOF: 4 bước
Video: Đồ án tốt nghiệp BKĐN | Cánh Tay Robot 4 Bậc Tự do phân loại sản phẩm theo màu sắc | Robot arm 4 dof 2024, Tháng mười một
Anonim
Image
Image

Dự án này là về việc thực hiện một bản phác thảo Arduino ngắn và tương đối dễ dàng để cung cấp định vị động học nghịch đảo XYZ. Tôi đã chế tạo một cánh tay robot 6 servo nhưng khi tìm phần mềm để chạy nó, không có nhiều thứ ngoài đó ngoại trừ các chương trình tùy chỉnh chạy trên lá chắn servo tùy chỉnh như SSC-32 (U) hoặc các chương trình và ứng dụng khác. phức tạp để cài đặt và giao tiếp với cánh tay. Sau đó, tôi tìm thấy "Chuyển động nghịch đảo cánh tay robot trên Arduino" xuất sắc nhất của Oleg Mazurov, nơi ông thực hiện chuyển động học nghịch đảo trong một bản phác thảo Arduino đơn giản.

Tôi đã thực hiện hai sửa đổi để điều chỉnh mã của anh ấy:

1. Tôi đã sử dụng thư viện VarSpeedServo thay cho thư viện lá chắn servo tùy chỉnh của anh ấy vì sau đó tôi có thể kiểm soát tốc độ của servo và tôi sẽ không phải sử dụng lá chắn servo mà anh ấy đã sử dụng. Đối với bất kỳ ai đang xem xét chạy mã được cung cấp ở đây, tôi khuyên bạn nên sử dụng thư viện VarSpeedServo này, thay vì thư viện servo.h, để bạn có thể làm chậm chuyển động của cánh tay robot của mình trong quá trình phát triển hoặc bạn có thể thấy rằng cánh tay sẽ bất ngờ chọc vào bạn mặt hoặc tệ hơn vì nó sẽ di chuyển ở tốc độ servo tối đa.

2. Tôi sử dụng một cảm biến / lá chắn servo đơn giản để kết nối servo với Arduino Uno nhưng nó không yêu cầu thư viện servo đặc biệt vì nó chỉ sử dụng các chân của Arduino. Nó chỉ tốn một vài đô la nhưng nó không phải là bắt buộc. Nó tạo ra một kết nối rõ ràng của Servos với Arduino. Và tôi sẽ không bao giờ quay lại việc cài đặt các Servos cho Arduino Uno bây giờ. Nếu bạn sử dụng cảm biến / lá chắn servo này, bạn cần thực hiện một sửa đổi nhỏ mà tôi sẽ trình bày bên dưới.

Mã hoạt động tuyệt vời và cho phép bạn vận hành cánh tay bằng cách sử dụng một hàm duy nhất trong đó bạn chuyển các tham số x, y, x và tốc độ. Ví dụ:

set_arm (0, 240, 100, 0, 20); // các tham số là (x, y, z, góc kẹp, tốc độ servo)

chậm trễ (3000); // cần có độ trễ để cho phép thời gian cánh tay di chuyển đến vị trí này

Không thể đơn giản hơn. Tôi sẽ bao gồm bản phác thảo bên dưới.

Video của Oleg ở đây: Điều khiển Cánh tay Robot bằng Arduino và Chuột USB

Chương trình, mô tả và tài nguyên gốc của Oleg: Chuyển động ngược của Oleg cho Arduino Uno

Tôi không hiểu tất cả các phép toán đằng sau quy trình nhưng điều tốt đẹp là bạn không cần phải sử dụng mã. Hy vọng bạn sẽ cung cấp cho nó một thử.

Bước 1: Sửa đổi phần cứng

Modifcations phần cứng
Modifcations phần cứng

1. Điều duy nhất được yêu cầu là servo của bạn quay theo các hướng dự kiến có thể yêu cầu bạn phải đảo ngược vật lý việc lắp các servo của bạn. Truy cập trang này để xem hướng servo dự kiến cho các servo cơ bản, vai, khuỷu tay và cổ tay:

2. Nếu bạn sử dụng tấm chắn cảm biến mà tôi đang sử dụng, bạn cần phải làm một việc với nó: bẻ cong chốt kết nối 5v từ tấm chắn với Arduino Uno ra khỏi đường để nó không kết nối với bo mạch Uno. Bạn muốn sử dụng điện áp bên ngoài trên tấm chắn để chỉ cấp nguồn cho Servos của bạn, không phải Arduino Uno hoặc nó có thể phá hủy Uno, tôi biết là tôi đã đốt cháy hai bảng Uno khi điện áp bên ngoài của tôi là 6 volt thay vì 5. Điều này cho phép bạn để sử dụng cao hơn 5v để cấp nguồn cho Servos của bạn nhưng nếu điện áp bên ngoài của bạn cao hơn 5 volt thì không kết nối bất kỳ cảm biến 5 volt nào với tấm chắn nếu không chúng sẽ bị chiên.

Bước 2: Tải xuống Thư viện VarSpeedServo

Bạn cần sử dụng thư viện này thay thế thư viện servo arduino tiêu chuẩn vì nó cho phép bạn chuyển tốc độ servo vào câu lệnh ghi servo. Thư viện nằm ở đây:

Thư viện VarSpeedServo

Bạn chỉ có thể sử dụng nút zip, tải xuống tệp zip và sau đó cài đặt nó với Arduino IDE. Sau khi cài đặt, lệnh trong chương trình của bạn sẽ giống như: servo.write (100, 20);

Tham số đầu tiên là góc và tham số thứ hai là tốc độ của servo từ 0 đến 255 (tốc độ đầy đủ).

Bước 3: Chạy Sketch này

Đây là chương trình cạnh tranh. Bạn cần sửa đổi một vài thông số cho kích thước cánh tay robot của mình:

1. Độ dài BASE_HGT, HUMERUS, ULNA, GRIPPER tính bằng milimét.

2. Nhập số pin servo của bạn

3. Nhập tối thiểu và tối đa của servo trong các câu lệnh đính kèm.

4. Sau đó, hãy thử một lệnh set_arm () đơn giản và sau đó là các hàm zero_x (), line () và circle () để kiểm tra. Đảm bảo tốc độ servo của bạn thấp trong lần đầu tiên bạn chạy các chức năng này để tránh làm hỏng cánh tay và cánh tay của bạn.

Chúc may mắn.

#include VarSpeedServo.h

/ * Điều khiển Servo cho cánh tay AL5D * /

/ * Kích thước cánh tay (mm) * /

#define BASE_HGT 90 // chiều cao cơ sở

#define HUMERUS 100 // "xương" từ vai đến khuỷu tay

#define ULNA 135 // "xương" từ khuỷu tay đến cổ tay

#define GRIPPER 200 // Gripper (bao gồm cơ chế xoay cổ tay có nhiệm vụ lượn sóng) chiều dài"

#define ftl (x) ((x)> = 0? (long) ((x) +0,5):(long) ((x) -0,5)) // chuyển thành chuyển đổi dài

/ * Tên / số Servo *

* Servo cơ sở HS-485HB * /

#define BAS_SERVO 4

/ * Servo vai HS-5745-MG * /

#define SHL_SERVO 5

/ * Servo khuỷu tay HS-5745-MG * /

#define ELB_SERVO 6

/ * Servo cổ tay HS-645MG * /

#define WRI_SERVO 7

/ * Servo xoay cổ tay HS-485HB * /

#define WRO_SERVO 8

/ * Gripper servo HS-422 * /

#define GRI_SERVO 9

/ * tính toán trước * /

float hum_sq = HUMERUS * HUMERUS;

float uln_sq = ULNA * ULNA;

int servoSPeed = 10;

// ServoShield servos; // Đối tượng ServoShield

VarSpeedServo servo1, servo2, servo3, servo4, servo5, servo6;

int loopCounter = 0;

int xungWidth = 6,6;

int microsecondsToDegrees;

void setup ()

{

servo1.attach (BAS_SERVO, 544, 2400);

servo2.attach (SHL_SERVO, 544, 2400);

servo3.attach (ELB_SERVO, 544, 2400);

servo4.attach (WRI_SERVO, 544, 2400);

servo5.attach (WRO_SERVO, 544, 2400);

servo6.attach (GRI_SERVO, 544, 2400);

chậm trễ (5500);

//servos.start (); // Khởi động lá chắn servo

servo_park ();

chậm trễ (4000);

Serial.begin (9600);

Serial.println ("Bắt đầu");

}

void loop ()

{

loopCounter + = 1;

// set_arm (-300, 0, 100, 0, 10); //

// delay (7000);

// zero_x ();

//hàng();

//khoanh tròn();

chậm trễ (4000);

if (loopCounter> 1) {

servo_park ();

// set_arm (0, 0, 0, 0, 10); // công viên

chậm trễ (5000);

thoát ra (0); } // tạm dừng chương trình - nhấn đặt lại để tiếp tục

// thoát ra (0);

}

/ * quy trình định vị cánh tay sử dụng chuyển động học nghịch đảo * /

/ * z là chiều cao, y là khoảng cách từ tâm cơ sở ra ngoài, x là cạnh bên. y, z chỉ có thể là số dương * /

// void set_arm (uint16_t x, uint16_t y, uint16_t z, uint16_t grip_angle)

void set_arm (float x, float y, float z, float grip_angle_d, int servoSpeed)

{

float grip_angle_r = radians (grip_angle_d); // góc kẹp tính bằng radian để sử dụng trong tính toán

/ * Góc cơ sở và khoảng cách bán kính từ các tọa độ x, y * /

float bas_angle_r = atan2 (x, y);

float rdist = sqrt ((x * x) + (y * y));

/ * rdist là tọa độ y cho cánh tay * /

y = rdist;

/ * Hiệu số tay cầm được tính toán dựa trên góc nắm * /

float grip_off_z = (sin (grip_angle_r)) * GRIPPER;

float grip_off_y = (cos (grip_angle_r)) * GRIPPER;

/ * Vị trí cổ tay * /

float cổ tay_z = (z - grip_off_z) - BASE_HGT;

phao cổ tay_y = y - nắm_cửa_y;

/ * Khoảng cách từ vai đến cổ tay (AKA sw) * /

float s_w = (cổ tay_z * cổ tay_z) + (cổ tay_y * cổ tay_y);

float s_w_sqrt = sqrt (s_w);

/ * góc s_w so với mặt đất * /

float a1 = atan2 (cổ tay_z, cổ tay_y);

/ * góc s_w so với humerus * /

float a2 = acos (((hum_sq - uln_sq) + s_w) / (2 * HUMERUS * s_w_sqrt));

/ * góc vai * /

float shl_angle_r = a1 + a2;

float shl_angle_d = độ (shl_angle_r);

/ * góc khuỷu tay * /

float elb_angle_r = acos ((hum_sq + uln_sq - s_w) / (2 * HUMERUS * ULNA));

float elb_angle_d = độ (elb_angle_r);

float elb_angle_dn = - (180.0 - elb_angle_d);

/ * góc cổ tay * /

float wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d;

/ * Xung Servo * /

float bas_servopulse = 1500.0 - ((độ (bas_angle_r)) * xungWidth);

float shl_servopulse = 1500.0 + ((shl_angle_d - 90.0) * xungWidth);

float elb_servopulse = 1500.0 - ((elb_angle_d - 90.0) * xungWidth);

// float wri_servopulse = 1500 + (wri_angle_d * xungWidth);

// float wri_servopulse = 1500 + (wri_angle_d * xungWidth);

float wri_servopulse = 1500 - (wri_angle_d * xungWidth); // được cập nhật 2018/2/11 bởi jimrd - Tôi đã thay đổi dấu cộng thành dấu trừ - không chắc chắn cách mã này hoạt động với bất kỳ ai trước đây. Có thể là do servo khuỷu tay được gắn với 0 độ hướng xuống chứ không phải hướng lên.

/ * Đặt servos * /

//servos.setposition(BAS_SERVO, ftl (bas_servopulse));

microsecondsToDegrees = map (ftl (bas_servopulse), 544, 2400, 0, 180);

servo1.write (micro giâyToDegrees, servoSpeed); // sử dụng chức năng này để bạn có thể đặt tốc độ servo //

//servos.setposition(SHL_SERVO, ftl (shl_servopulse));

microsecondsToDegrees = map (ftl (shl_servopulse), 544, 2400, 0, 180);

servo2.write (micro giâyToDegrees, servoSpeed);

//servos.setposition(ELB_SERVO, ftl (elb_servopulse));

microsecondsToDegrees = map (ftl (elb_servopulse), 544, 2400, 0, 180);

servo3.write (micro giâyToDegrees, servoSpeed);

//servos.setposition(WRI_SERVO, ftl (wri_servopulse));

microsecondsToDegrees = map (ftl (wri_servopulse), 544, 2400, 0, 180);

servo4.write (micro giâyToDegrees, servoSpeed);

}

/ * di chuyển servo đến vị trí đậu xe * /

void servo_park ()

{

//servos.setposition(BAS_SERVO, 1500);

servo1.write (90, 10);

//servos.setposition(SHL_SERVO, 2100);

servo2.write (90, 10);

//servos.setposition(ELB_SERVO, 2100);

servo3.write (90, 10);

//servos.setposition(WRI_SERVO, 1800);

servo4.write (90, 10);

//servos.setposition(WRO_SERVO, 600);

servo5.write (90, 10);

//servos.setposition(GRI_SERVO, 900);

servo6.write (80, 10);

trở lại;

}

void zero_x ()

{

for (yaxis kép = 250.0; yaxis <400.0; yaxis + = 1) {

Serial.print ("yaxis =:"); Serial.println (yaxis);

set_arm (0, yaxis, 200.0, 0, 10);

chậm trễ (10);

}

for (yaxis kép = 400.0; yaxis> 250.0; yaxis - = 1) {

set_arm (0, yaxis, 200.0, 0, 10);

chậm trễ (10);

}

}

/ * di chuyển cánh tay theo đường thẳng * /

dòng void ()

{

for (double xaxis = -100.0; xaxis <100.0; xaxis + = 0.5) {

set_arm (xaxis, 250, 120, 0, 10);

chậm trễ (10);

}

for (float xaxis = 100.0; xaxis> -100.0; xaxis - = 0.5) {

set_arm (xaxis, 250, 120, 0, 10);

chậm trễ (10);

}

}

void circle ()

{

#define RADIUS 50.0

// float angle = 0;

float zaxis, yaxis;

for (float angle = 0.0; angle <360.0; angle + = 1.0) {

yaxis = RADIUS * sin (radian (góc)) + 300;

zaxis = RADIUS * cos (radian (góc)) + 200;

set_arm (0, yaxis, zaxis, 0, 50);

chậm trễ (10);

}

}

Bước 4: Sự kiện, Vấn đề và Tương tự…

Sự thật, Vấn đề và Tương tự…
Sự thật, Vấn đề và Tương tự…

1. Khi tôi chạy chương trình con circle (), rô bốt của tôi di chuyển theo hình elip nhiều hơn là hình tròn. Tôi nghĩ đó là do các servo của tôi chưa được hiệu chỉnh. Tôi đã thử nghiệm một trong số chúng và 1500 micro giây không giống với 90 độ. Sẽ làm việc trên này để thử và tìm ra giải pháp. Đừng tin rằng có bất cứ điều gì sai với thuật toán mà là với cài đặt của tôi. Cập nhật 2018/2/11 - mới phát hiện ra điều này là do lỗi trong mã gốc. Tôi không thấy chương trình của anh ấy hoạt động như thế nào Mã sửa lỗi sử dụng cái này: float wri_servopulse = 1500 - (wri_angle_d * xungWidth); (mã gốc đã được thêm vào)

2. Tôi có thể tìm thêm thông tin về cách hoạt động của hàm set_arm () ở đâu: Trang web của Oleg Mazurov giải thích mọi thứ hoặc cung cấp liên kết để biết thêm thông tin:

3. Có kiểm tra điều kiện biên không? Không. Khi cánh tay rô bốt của tôi được vượt qua một tọa độ xyz không hợp lệ, nó sẽ thực hiện kiểu chuyển động cong người vui nhộn này giống như một con mèo đang vươn vai. Tôi tin rằng Oleg đã thực hiện một số kiểm tra trong chương trình mới nhất của anh ấy sử dụng USB để lập trình các chuyển động của cánh tay. Xem video của anh ấy và liên kết đến mã mới nhất của anh ấy.

4. Mã cần được làm sạch và mã micro giây có thể được thực hiện với.

Đề xuất: