فهرست مطالب:

استفاده از Arduino Uno برای موقعیت یابی XYZ بازوی رباتیک 6 DOF: 4 مرحله
استفاده از Arduino Uno برای موقعیت یابی XYZ بازوی رباتیک 6 DOF: 4 مرحله

تصویری: استفاده از Arduino Uno برای موقعیت یابی XYZ بازوی رباتیک 6 DOF: 4 مرحله

تصویری: استفاده از Arduino Uno برای موقعیت یابی XYZ بازوی رباتیک 6 DOF: 4 مرحله
تصویری: راه اندازی سرو درایور AMD60 در مُد کنترل موقعیت 2024, نوامبر
Anonim
Image
Image

این پروژه در مورد اجرای یک طرح کوتاه و نسبتاً آسان آردوینو برای ارائه موقعیت سینماتیکی معکوس XYZ است. من یک بازوی رباتیک 6 سروو ساخته بودم ، اما وقتی نوبت به یافتن نرم افزاری برای اجرای آن رسید ، چیزهای زیادی به جز برنامه های سفارشی که روی سپرهای سروو سفارشی مانند SSC-32 (U) یا برنامه ها و برنامه های دیگر اجرا می شد ، وجود نداشت. نصب و ارتباط با بازو پیچیده است. سپس من عالی ترین "سینماتیک معکوس بازوی روباتیک در آردوینو" اولگ مازوروف را پیدا کردم که در آن او یک سینماتیک معکوس را در یک طرح ساده آردوینو اجرا کرد.

من دو اصلاح برای تطبیق کد او انجام دادم:

1. من از کتابخانه VarSpeedServo به جای کتابخانه سروو سپر سفارشی اش استفاده کردم ، زیرا می توانستم سرعت سروها را کنترل کنم و مجبور نباشم از سپر سروو که استفاده می کرد استفاده کنم. برای کسانی که قصد دارند کد ارائه شده در اینجا را در نظر بگیرند ، توصیه می کنم از این کتابخانه VarSpeedServo و نه از کتابخانه servo.h استفاده کنید تا بتوانید حرکت بازوی روباتیک خود را در حین توسعه کاهش دهید یا ممکن است متوجه شوید که بازو به طور غیرمنتظره شما را وارد می کند. صورت یا بدتر زیرا با سرعت کامل سروو حرکت می کند.

2. من از یک سنسور/سروو ساده برای اتصال سرووها به Arduino Uno استفاده می کنم ، اما نیازی به کتابخانه سرو خاصی ندارد زیرا فقط از پین های آردوینو استفاده می کند. فقط چند دلار هزینه دارد اما نیازی به آن نیست. این یک اتصال تمیز خوب سرویس ها به آردوینو را ایجاد می کند. و من دیگر هرگز به سرویس های سخت افزاری Arduino Uno بر نمی گردم. اگر از این محافظ سنسور/سروو استفاده می کنید ، باید یک تغییر جزئی ایجاد کنید که در زیر به آن اشاره می کنم.

کد فوق العاده کار می کند و به شما اجازه می دهد تا با استفاده از یک تابع که در آن پارامترهای x ، y ، x و سرعت را رد می کنید ، بازو را کار کنید. مثلا:

set_arm (0 ، 240 ، 100 ، 0 ، 20) ؛ // پارامترها عبارتند از (x ، y ، z ، زاویه گیر ، سرعت سروو)

تاخیر (3000) ؛ // تأخیر لازم است تا زمان بازو بتواند به این مکان منتقل شود

ساده تر نمی شود من طرح زیر را درج می کنم.

ویدئوی اولگ اینجاست: کنترل بازوی روباتیک با آردوینو و ماوس USB

برنامه ، توضیحات و منابع اصلی اولگ: سینماتیک معکوس اولگ برای آردوینو اونو

من همه ریاضیات پشت روال را نمی فهمم ، اما نکته خوب این است که مجبور نیستید از کد استفاده کنید. امیدوارم امتحان کنید.

مرحله 1: تغییرات سخت افزاری

تغییرات سخت افزاری
تغییرات سخت افزاری

1. تنها چیزی که مورد نیاز است این است که سروو به جهت مورد انتظار بچرخد که می تواند شما را ملزم کند که نصب سروهای خود را از نظر فیزیکی معکوس کنید. برای مشاهده جهت سرو مورد انتظار برای سروهای پایه ، شانه ، آرنج و مچ به این صفحه بروید:

2. اگر از محافظ سنسوری که من استفاده می کنم استفاده می کنید ، باید یک کار را با آن انجام دهید: پین را که 5v را از سپر به Arduino Uno متصل می کند ، از راه خم کنید تا به برد Uno متصل نشود. شما می خواهید از ولتاژ خارجی روی سپر برای تغذیه فقط سرویس های خود استفاده کنید ، نه Arduino Uno یا ممکن است Uno را خراب کند ، من می دانم که دو تخته Uno را سوزاندم وقتی ولتاژ خارجی من 6 ولت بود نه 5. این به شما امکان می دهد برای تغذیه سرووها از ولتاژ بالاتر از 5 ولت استفاده کنید اما اگر ولتاژ خارجی شما بیشتر از 5 ولت است ، هیچ سنسور 5 ولت را به سپر وصل نکنید وگرنه سرخ می شوند.

مرحله 2: کتابخانه VarSpeedServo را بارگیری کنید

شما باید از این کتابخانه استفاده کنید که جایگزین کتابخانه استاندارد سروو آردوینو می شود زیرا به شما اجازه می دهد تا سرعت سروو را به دستور نوشتن سروو منتقل کنید. کتابخانه در اینجا قرار دارد:

کتابخانه VarSpeedServo

فقط می توانید از دکمه zip استفاده کنید ، فایل zip را بارگیری کرده و سپس آن را با Arduino IDE نصب کنید. پس از نصب دستور در برنامه شما به صورت زیر خواهد بود: servo.write (100 ، 20)؛

پارامتر اول زاویه و دوم سرعت سروو از 0 تا 255 (سرعت کامل) است.

مرحله 3: این طرح را اجرا کنید

در اینجا برنامه رقابت است. شما باید چند پارامتر را برای ابعاد بازوی روباتیک خود تغییر دهید:

1. طول BASE_HGT ، HUMERUS ، ULNA ، GRIPPER در میلی متر.

2. شماره پین سروو خود را وارد کنید

3. سروو min و max را در دستورات ضمیمه وارد کنید.

4. سپس یک دستور ساده set_arm () و سپس توابع zero_x () ، line () و circle () را برای آزمایش امتحان کنید. اطمینان حاصل کنید که سرعت سروو برای اولین بار که این عملکردها را اجرا می کنید پایین است تا از آسیب رساندن به بازو و بازوی خود جلوگیری کنید.

موفق باشید.

#شامل VarSpeedServo.h

/ * کنترل سروو برای بازوی AL5D */

/ * ابعاد بازو (میلی متر) */

#تعریف BASE_HGT 90 // ارتفاع پایه

#تعریف HUMERUS 100 // "استخوان" شانه به آرنج

#تعریف ULNA 135 // آرنج تا مچ "استخوان"

#deepine GRIPPER 200 // gripper (شامل مکانیزم چرخش مچ دست سنگین) طول"

#defl ftl (x) ((x)> = 0؟ (long) ((x) +0.5):(long) ((x) -0.5)) // شناور به تبدیل طولانی

/ * نام/شماره سروو *

* سروو پایه HS-485HB */

#تعریف BAS_SERVO 4

/ * شانه سرو HS-5745-MG */

#SHL_SERVO 5 را تعریف کنید

/ * آرنج سرو HS-5745-MG */

#ELB_SERVO را تعریف کنید 6

/ * مچ سروو HS-645MG */

#تعریف WRI_SERVO 7

/ * سروو چرخش مچ دست HS-485HB */

#تعریف WRO_SERVO 8

/ * گیربکس سرو HS-422 *//

#تعریف GRI_SERVO 9

/ * پیش محاسبات */

float hum_sq = HUMERUS*HUMERUS؛

float uln_sq = ULNA*ULNA ؛

int servoSPeed = 10؛

// سرویس های ServoShield ؛ // شیء ServoShield

VarSpeedServo servo1 ، servo2 ، servo3 ، servo4 ، servo5 ، servo6 ؛

int loopCounter = 0؛

int pulseWidth = 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) ؛

تاخیر (5500) ؛

//servos.start ()؛ // محافظ سروو را راه اندازی کنید

servo_park ()؛

تأخیر (4000) ؛

Serial.begin (9600)؛

Serial.println ("شروع") ؛

}

حلقه خالی ()

{

loopCounter += 1؛

// set_arm (-300 ، 0 ، 100 ، 0 ، 10) ؛ //

// تأخیر (7000) ؛

// zero_x ()؛

// خط ()؛

//دایره()؛

تأخیر (4000) ؛

if (loopCounter> 1) {

servo_park ()؛

// set_arm (0 ، 0 ، 0 ، 0 ، 10) ؛ // پارک

تأخیر (5000) ؛

خروج (0) ؛ } // برنامه مکث - برای ادامه گزینه reset را فشار دهید

// خروج (0) ؛

}

/ * روال موقعیت یابی بازو با استفاده از سینماتیک معکوس */

/* z ارتفاع ، y فاصله از مرکز پایه به بیرون ، x سمت به طرف است. y ، z فقط می تواند مثبت باشد */

// 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)

{

شناور grip_angle_r = رادیان (grip_angle_d) ؛ // زاویه گرفتن در رادیان برای استفاده در محاسبات

/ * زاویه پایه و فاصله شعاعی از مختصات x ، y */

شناور bas_angle_r = atan2 (x ، y) ؛

شناور rdist = sqrt ((x * x) + (y * y)) ؛

/ * rdist y مختص بازو */است

y = rdist؛

/ * جابجایی های گریپ بر اساس زاویه گرفتن محاسبه می شود */

float grip_off_z = (گناه (grip_angle_r)) * GRIPPER ؛

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

/ * موقعیت مچ */

float wrist_z = (z - grip_off_z) - BASE_HGT ؛

float wrist_y = y - grip_off_y؛

/ * فاصله شانه تا مچ (AKA sw) */

float s_w = (wrist_z * wrist_z) + (wrist_y * wrist_y) ؛

شناور s_w_sqrt = sqrt (s_w) ؛

/ * s_w زاویه به زمین */

float a1 = atan2 (wrist_z، wrist_y)؛

/ * s_w angle to humerus */

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

/ * زاویه شانه */

شناور shl_angle_r = a1 + a2؛

شناور shl_angle_d = درجه (shl_angle_r) ؛

/ * زاویه آرنج */

شناور elb_angle_r = acos ((hum_sq + uln_sq - s_w) / (2 * HUMERUS * ULNA)) ؛

شناور elb_angle_d = درجه (elb_angle_r) ؛

شناور elb_angle_dn = - (180.0 - elb_angle_d) ؛

/ * زاویه مچ */

شناور wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d ؛

/ * پالس سرو */

شناور bas_servopulse = 1500.0 - ((درجه (bas_angle_r)) * pulseWidth) ؛

شناور shl_servopulse = 1500.0 + ((shl_angle_d - 90.0) * pulseWidth) ؛

شناور elb_servopulse = 1500.0 - ((elb_angle_d - 90.0) * pulseWidth) ؛

// float wri_servopulse = 1500+ (wri_angle_d * pulseWidth)؛

// float wri_servopulse = 1500+ (wri_angle_d * pulseWidth)؛

float wri_servopulse = 1500 - (wri_angle_d * pulseWidth) ؛ // به روز شده 2018/2/11 توسط jimrd - من بعلاوه آن را به یک منفی تغییر دادم - مطمئن نیستم که این کد قبلاً برای هر کسی چگونه کار می کرد. ممکن است سروو آرنج با صفر درجه به سمت پایین و نه به سمت بالا نصب شده باشد.

/ * تنظیم سروها */

//servos.setposition(BAS_SERVO ، ftl (bas_servopulse)) ؛

microsecondsToDegrees = نقشه (ftl (bas_servopulse) ، 544 ، 2400 ، 0 ، 180) ؛

servo1.write (microsecondsToDegrees ، servoSpeed) ؛ // از این عملکرد استفاده کنید تا بتوانید سرعت سروو را تنظیم کنید //

//servos.setposition(SHL_SERVO ، ftl (shl_servopulse)) ؛

microsecondsToDegrees = نقشه (ftl (shl_servopulse) ، 544 ، 2400 ، 0 ، 180) ؛

servo2.write (microsecondsToDegrees ، servoSpeed) ؛

//servos.setposition(ELB_SERVO ، ftl (elb_servopulse)) ؛

microsecondsToDegrees = نقشه (ftl (elb_servopulse) ، 544 ، 2400 ، 0 ، 180) ؛

servo3.write (microsecondsToDegrees ، servoSpeed) ؛

//servos.setposition(WRI_SERVO ، ftl (wri_servopulse)) ؛

microsecondsToDegrees = نقشه (ftl (wri_servopulse) ، 544 ، 2400 ، 0 ، 180) ؛

servo4.write (microsecondsToDegrees ، servoSpeed) ؛

}

/ * انتقال سرووها به موقعیت پارکینگ */

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) ؛

برگشت؛

}

خالی zero_x ()

{

برای (double yaxis = 250.0؛ yaxis <400.0؛ yaxis += 1) {

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

set_arm (0 ، yaxis ، 200.0 ، 0 ، 10) ؛

تأخیر (10) ؛

}

برای (double yaxis = 400.0 ؛ yaxis> 250.0 ؛ yaxis -= 1) {

set_arm (0 ، yaxis ، 200.0 ، 0 ، 10) ؛

تأخیر (10) ؛

}

}

/ * بازو را در یک خط مستقیم حرکت می دهد */

خط خالی ()

{

برای (xaxis دوگانه = -100.0 ؛ xaxis <100.0 ؛ xaxis += 0.5) {

set_arm (xaxis ، 250 ، 120 ، 0 ، 10) ؛

تأخیر (10) ؛

}

برای (floax xaxis = 100.0 ؛ xaxis> -100.0 ؛ xaxis -= 0.5) {

set_arm (xaxis ، 250 ، 120 ، 0 ، 10) ؛

تأخیر (10) ؛

}

}

دایره خالی ()

{

#تعریف RADIUS 50.0

// شناور زاویه = 0؛

float zaxis، yaxis؛

برای (زاویه شناور = 0.0 ؛ زاویه <360.0 ؛ زاویه += 1.0) {

yaxis = RADIUS * sin (رادیان (زاویه)) + 300 ؛

zaxis = RADIUS * cos (رادیان (زاویه)) + 200 ؛

set_arm (0، yaxis، zaxis، 0، 50)؛

تأخیر (10) ؛

}

}

مرحله 4: حقایق ، مسائل و موارد مشابه…

حقایق ، مسائل و موارد مشابه…
حقایق ، مسائل و موارد مشابه…

1. هنگامی که زیر روال دایره () را اجرا می کنم ، ربات من بیشتر به شکل بیضوی حرکت می کند تا یک دایره. من فکر می کنم این به این دلیل است که سرویس های من کالیبره نشده اند. من یکی از آنها را آزمایش کردم و 1500 میکرو ثانیه با 90 درجه یکسان نبود. در تلاش برای یافتن راه حلی در این زمینه تلاش خواهد کرد. باور نکنید که الگوریتم مشکلی ندارد ، بلکه تنظیمات من است. به روز رسانی 2018/2/11 - به تازگی متوجه شده اید که این به دلیل خطا در کد اصلی است. من نمی بینم که برنامه او چگونه کار می کرد کد ثابت با استفاده از این: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth)؛ (کد اصلی اضافه شد)

2. از کجا می توانم اطلاعات بیشتری در مورد نحوه عملکرد () set_arm پیدا کنم: وب سایت اولگ مازوروف همه چیز را توضیح می دهد یا پیوندهایی برای اطلاعات بیشتر ارائه می دهد:

3. آیا شرایط مرزی وجود دارد؟ خیر. هنگامی که بازوی ربات من از یک مختصات xyz نامعتبر عبور می کند ، این حرکت خنده دار را مانند حرکت گربه انجام می دهد. من معتقدم اولگ در آخرین برنامه خود که از USB برای برنامه ریزی حرکات بازو استفاده می کند ، بررسی می کند. ویدیوی او را ببینید و پیوند آخرین کد او را مشاهده کنید.

4. کد باید تمیز شود و کد میکروثانیه قابل حذف باشد.

توصیه شده: