ساخت ربات عنکبوتی
طراحی و کنترل ربات عنکبوتی چهارپا با ESP32
طبیعت همیشه منبع باورنکردنی الهام برای پیشرفتهای تکنولوژی بوده و مهندسان به دنبال تکرار مکانیسمهای پیچیده موجود در حیوانات مختلف بودهاند.
یکی از این خلاقیت های قابل توجه ربات عنکبوتی است. این ربات به دلیل داشتن چهار پا می تواند به عنوان یک ربات چهارپا نیز شناخته شود. هدف این پروژه رباتیک نوآورانه شبیه سازی حرکت و رفتار عنکبوت ها است.
ربات عنکبوتی یک ربات راه رونده ی چهار پا است که از عنکبوت الهام گرفته شده است که از پاهای خود برای حرکت استفاده می کند. پاها به گونه ای چیده شده اند که به آنها امکان می دهد به روش های مختلف از جمله راه رفتن، دویدن و بالا رفتن حرکت کنند. یکی از اجزای جدایی ناپذیر این پروژه، ادغام میکروکنترلر ESP32 است که کنترل بی سیم و هماهنگی حرکتی پیشرفته را امکان پذیر می کند. ESP32 به عنوان یک پلت فرم ایده آل برای ربات عنکبوتی عمل می کند و چابکی، تطبیق پذیری و ظرفیت آن را برای پیمایش موثر در زمین های پیچیده افزایش می دهد. رباتهای عنکبوتی با چابکی، تطبیق پذیری و توانایی فوقالعاده خود برای عبور از زمینهای پیچیده، پتانسیل بسیار زیادی در زمینههای مختلف، از جمله مأموریتهای جستجو و نجات، اکتشاف، و حتی کمکهای خانگی دارند.
مکانیزم کارکرد ربات عنکبوتی
مکانیسم یک ربات عنکبوتی شامل چندین مؤلفه و اصول کلیدی است که حرکت و عملکرد آن را امکان پذیر می کند.
رباتهای عنکبوتی متعلق به دسته روباتهای پادار هستند که معمولاً پیچیدهتر از روباتهای چرخدار هستند. ربات های پادار در عبور از زمین های چالش برانگیز در مقایسه با ربات های چرخ دار برتر هستند. در حالی که ربات های چرخ دار معمولاً دارای موتورهای DC هستند در حالی که ربات های پادار معمولاً دارای موتورهای سروو هستند.
یکی از تمایزات اساسی بین ربات های چرخدار و پادار در درجات آزادی آنها (DOF) نهفته است. ربات های چرخ دار فقط یک درجه آزادی دارند در حالی که ربات های پادار دارای حرکت پیچیده تری هستند.
درجات آزادی (DOF) یک جسم با تعداد پارامترهایی که برای تعیین موقعیت همان جسم لازم است تعریف می شود. در مورد ربات عنکبوتی ما ۲ موتور سروو در هر یک از پاهای خود دارد تا ۲ جهت مختلف حرکت را نشان دهد. این بدان معنی است که درجه آزادی (DOF) برای یک پا ۲ است. بنابراین مجموع درجات آزادی (DOF) ربات عنکبوتی ۸ است.
این پروژه ممکن است از نظر سیم کشی و مونتاژ خیلی پیچیده نباشد، اما درک سینماتیک پشت حرکت ربات عنکبوتی چهارپا بسیار پیچیده است. برای دستیابی به حرکت کنترل شده، ربات باید تعداد متفاوتی از حالت ها را انجام دهد که در مجموع یک حرکت واحد ایجاد می کنند. این کار را می توان با اجرای راه رفتن کرال (الگوی حرکت) انجام داد که در آن یک پا در هوا و سه پای باقی مانده باید در هنگام حرکت با زمین در تماس باشند. به طور معمول، برای برداشتن یک قدم به جلو، ربات ۶ حالت متمایز را پشت سر می گذارد.
راه رفتن چهارپا برای حرکت به جلو
راه رفتن به الگوی خاصی از حرکت پا اشاره دارد که برای حرکت بدن به سمت مقصد مورد نظر لازم است. در مورد ربات های چهارپا، راه رفتن شامل بلند کردن یک پا در یک زمان است در حالی که سه پایه باقی مانده یک سه پایه حمایتی را تشکیل می دهند. این حرکت هماهنگ ثبات و حرکت کارآمد را تضمین می کند.
برای دستیابی به راه رفتن چهارپا، نکته کلیدی این است که تعیین کنید هر پا چه زمانی و در چه موقعیتی حرکت کند. این فرآیند به عنوان سینماتیک معکوس شناخته می شود. سینماتیک معکوس ما را قادر می سازد تا مقادیر لازم را برای سروو موتورهای کنترل کننده پاها محاسبه کنیم و به موقعیت دقیق پاها اجازه می دهد تا به الگوی راه رفتن مورد نظر دست یابیم.
سینماتیک معکوس نقش مهمی در اجرای صاف راه رفتن چهارپا دارد. با ارائه دستورالعمل های لازم به سروو موتورها، می توان پاهای ربات را به طور دقیق به موقعیت های مورد نظر حرکت داد. این به حفظ تعادل و دستیابی به حرکت موثر کمک می کند

نمودار بالا راه رفتن چهارپا رو به جلو را نشان می دهد و دنباله ای از حرکات پا را نشان می دهد که برای حرکت موثر روبات به جلو لازم است. خط نقطه نشان می دهد که پا بلند شده است.

برای اطمینان از پایداری ربات، بسیار مهم است که مرکز جرم (COM) در چند ضلعی پشتیبانی باقی بماند. چند ضلعی پشتیبانی به یک چند ضلعی خیالی اشاره دارد که در صورت قرار گرفتن COM در داخل آن، ربات می تواند تعادل خود را حفظ کند. با این حال، اگر COM به خارج از چند ضلعی پشتیبانی جابجا شود، ربات ناپایدار می شود و ممکن است واژگون شود. این مفهوم در شکل زیر نشان داده شده است، جایی که ربات تا زمانی که COM در داخل چند ضلعی پشتیبانی قرار دارد متعادل باقی می ماند. این به عنوان یک اصل مهم برای حفظ ثبات و جلوگیری از سقوط در عملکرد ربات عمل می کند.

اجزای مورد نیاز برای ربات عنکبوتی
میکروکنترلر ESP32
سروو موتور دنده پلاستیکی SG90 – هشت عدد
عدد مبدل DC-DC Buck LM2596
باتری ۱۲ ولت لیتیوم یونی
سوییچ
سیم های جامپر
برد بورد یا PCB (برد مدار چاپی)
پیچ، مهره، اسپیسر
فایل های برش لیزری ربات عنکبوتی
ما قطعات اکریلیک Quadruped Spider Robot را با استفاده از SolidWorks طراحی کرده ایم. فایل های .dxf را می توانید در اینجا دانلود کنید. اگر می خواهید تغییری ایجاد کنید، می توانید فایل .svg را نیز پیدا کنید. این قطعات همچنین به راحتی در بسیاری از وب سایت های تجارت الکترونیک در دسترس هستند.
مونتاژ ربات عنکبوتی

تنظیم موقعیت سروو موتورها
قبل از شروع مونتاژ، باید تنظیم زاویه سروو موتورها را تنظیم کنیم. در غیر این صورت ربات شما به درستی کار نخواهد کرد.

برای شروع، بازوی سروو را با تراز کردن و محکم کردن آن در جای خود به سروو متصل کنید. ما می توانیم به صورت دستی زاویه موتور سروو را کالیبره و تنظیم کنیم، اما مدتی کالیبراسیون دستی دقیق نیست یا ممکن است امکان پذیر نباشد. بنابراین می توانید سروو موتورهای خود را با استفاده از کد شماره ۱ کالیبره کنید. به نمودار مدار ذکر شده در زیر مراجعه کنید و سروو موتورهای خود را بر این اساس به پایه های ۲۱، ۱۹، ۳۳، ۲۵، ۲۷، ۱۴، ۱۲ و ۱۳ متصل کنید. کد شماره ۱ ارائه شده را در ESP32 خود آپلود کنید، که فرآیند کالیبراسیون را تسهیل می کند. عدم اجرای این مرحله ممکن است منجر به عملکرد ناپایدار ربات شما شود.

با اطمینان از تراز و کالیبراسیون مناسب سرووها، پایه و اساس یک ربات پایدار و با عملکرد خوب را ایجاد می کنید. پس از انجام تنظیمات سروو، می توانید به مراحل مونتاژ پاهای ربات بروید.
مونتاژ پاهای ربات

مرحله ۱: یک بازوی سروو را بردارید و آن را روی صفحه پایه پایه قرار دهید. پیچ نصب سروو را از سمت عقب صفحه محوری پا به بالا وارد بازوی تکی سروو کنید. پیچ را سفت کنید تا بازوی تک سروو به طور ایمن به صفحه محوری متصل شود.
مرحله ۲: اکنون یک بازوی سروو دیگر را به بازوی سروو ایستاده وصل کنید. برای انجام این کار، یک پیچ نصب سروو را از پشت بازوی سروو پا وارد کنید و آن را به بازوی تک سروو محکم کنید. اطمینان حاصل کنید که اتصال محکم و پایدار است.
مرحله ۳: حرکت به سمت جلو، اتصال موازی پا را با استفاده از یک پیچ M3x10mm و یک مهره فیبر M3 به قطعه ساق وصل کنید. سفتی پیچ را دوبار بررسی کنید تا مطمئن شوید که اتصال محکم به قطعه ساق متصل شده است.
مرحله ۴: سپس با استفاده از یک پیچ M3x10mm و یک مهره فیبر M3، قطعه ساق را به بازوی سروو پا متصل کنید.

مرحله ۵: سروو دیگری را در نگهدارنده سرو قرار دهید.
مرحله ۶: انتهای بالایی سرو دوم را در شیار سروو پایه قرار دهید.
مرحله ۷: نگهدارنده سروو را با استفاده از دو پیچ M3x12mm و دو مهره فیبر M3 به سوکت سروو پا ببندید.
مرحله ۸: اکنون یک صفحه موازی پایه را با استفاده از یک پیچ M3x10mm و یک مهره فیبر M3 به انتهای دیگر ساق وصل کنید.

مرحله ۹: با هر دو سروو در موقعیت مرکزی و مفصل موازی پا به صورت افقی، بازوی سروو پا را با استفاده از پیچ بازوی سروو ارائه شده به سروو اول وصل کنید.
مرحله ۱۰: در نهایت مونتاژ پا را که در مراحل قبل تکمیل شد، با استفاده از دو پیچ M3x10mm و دو مهره M3 به Pivot Plate Leg Bottom متصل کنید. مرحله مونتاژ پا ممکن است چالش برانگیز باشد، اما پس از تکمیل این مراحل، فرآیند باقی مانده قابل مدیریت تر می شود. اگر این مراحل را با موفقیت به پایان رسانده اید، به قسمت Body Assembly (مونتاژ بدنه ) می رویم.
مونتاژ بدنه ربات
در این مرحله باید مراقب اعداد باشید. شماتیک ها با توجه به شماره قطعات توضیح داده شده است، به طوری که شما باید لیست هایی را که ایجاد کردیم، قبل از اسمبلی مطالعه کنید.
قسمت های شماتیک مونتاژ ۱و ۲ :
۱- صفحه بالایی بدنه
۲- پیچ M3x10mm
۳- سرو موتور
۴ – M3 مهره
M3 -5 – مهره فیبر
M3*12MM 7 – پیچ
۸ – اسپیسر
۱۰ – نگهدارنده سرو

مرحله ۱: مونتاژ را با اتصال چهار فاصله دهنده بدنه به صفحه پایین بدنه شروع کنید. از چهار پیچ M3x10mm و چهار مهره مسطح M3 برای محکم کردن اسپیسرها در جای خود استفاده کنید.
مرحله ۲: چهار سروو را بردارید و آنها را روی صفحه بالایی شاسی قرار دهید و مطمئن شوید که به درستی تراز شده اند.
مرحله ۳: برای هر سروو، یک نگهدارنده سرو در بالا وصل کنید. نگهدارنده را به درستی تراز کنید و آن را در جای خود محکم کنید.
مرحله ۴: هر نگهدارنده سروو را با استفاده از پیچ های M3x12mm و مهره های فیبر M3 به صفحه بالایی شاسی ببندید. اطمینان حاصل کنید که آنها به طور ایمن سفت شده اند

مرحله ۵: اکنون، هر تکه پا را به صفحه پایین بدنه وصل کنید. برای هر قطعه پایه از یک پیچ M3x10mm و یک مهره فیبر M3 استفاده کنید. مراقب باشید پیچ ها را بیش از حد سفت نکنید، زیرا ممکن است منجر به خرابی سروو شود.
مرحله ۶: صفحه پایینی بدنه و صفحه بالایی بدنه را کنار هم قرار دهید. برای اتصال محکم این دو جزء از چهار پیچ M3x10mm و مهره M3 استفاده کنید.
مرحله ۷: در حالی که سرووها و قطعات پا در جای خود قرار دارند، همانطور که در دستورالعمل نشان داده شده است، هر پا را با دقت به زاویه ۴۵ درجه بچرخانید. صفحه محوری بالای پایه را نصب کنید و با استفاده از دو پیچ M3x10mm و دو مهره M3 برای هر پایه، آن را روی هر سروو و پایه محکم کنید.
مرحله ۸: در نهایت با استفاده از پیچ سروو، تک بازوی سروو را به سرووی مربوطه خود محکم کنید و مطمئن شوید که محکم وصل شده است.

بعد از مونتاژ به صورت زیر در می آید:

نمودار مدار ESP32 برای ربات عنکبوتی چهارپا (۸ موتور سروو)
این نمودار مدار ادغام ۱۲ سروو موتور را نشان می دهد که حرکت را در تمام جهات برای ربات امکان پذیر می کند.

این ربات از چهار پایه تشکیل شده است که هر پایه آن به دو موتور سروو متصل است. یک سروو وظیفه چرخش محور (معروف به سروو محوری) را بر عهده دارد، در حالی که سروو دیگر حرکت بلند کردن پا را کنترل می کند (معروف به سروو بالابر). برای دستیابی به حرکت هماهنگ، سروو موتورها به ترتیب یا ترتیب خاصی به هم متصل می شوند. ترتیب دقیق و اتصالات به الگوی راه رفتن مورد نظر و الگوریتم کنترل خاصی که به کار گرفته می شود بستگی دارد. با کنترل حرکت این سروو موتورها به صورت هماهنگ، ربات می تواند به حرکت پایدار و هماهنگ دست یابد.

ESP32 و سروو موتورها:
برای کنترل سرووها، پین های با قابلیت PWM (مدولاسیون عرض پالس) را روی ESP32 اختصاص دهید. این پین ها سیگنال های PWM لازم را برای تنظیم موقعیت هر سروو موتور تولید می کنند. سیم سیگنال (معمولاً به رنگ زرد یا سفید) از هر سروو موتور به یک پین جداگانه با قابلیت PWM در ESP32 وصل کنید.

ESP32 و منبع تغذیه:
ترمینال مثبت منبع تغذیه را به پین های VCC هر سروو موتور وصل کنید.
ترمینال زمین منبع تغذیه را به پایه های زمین (GND) همه سروو موتورها وصل کنید.
پایه زمین (GND) ESP32 را به ترمینال زمین (-) منبع تغذیه خود وصل کنید.
پین Vin ESP32 را با کمک سوئیچ به ترمینال مثبت (+) منبع تغذیه خود وصل کنید.
هنگام کار با چندین سروو موتور در یک ربات عنکبوتی، توان مورد نیاز بیشتر از آن چیزی است که میکروکنترلر ESP32 نمی تواند ارائه دهد. بنابراین، یک ورودی برق خارجی ضروری است. با این حال، بسیار مهم است که اطمینان حاصل شود که ولتاژ ورودی از ۵ ولت تجاوز نمی کند تا از آسیب به میکروکنترلر ESP32 جلوگیری شود.
در صورت استفاده از باتری با ولتاژ بالاتر، از مدار کاهنده ولتاژ (مبدل DC – DC) استفاده کنید تا آن را به ۵ ولت کاهش دهید. خروجی مدار کاهنده ولتاژ را به هر دو موتور ESP32 و سروو وصل کنید. این منبع تغذیه ایمن و کارآمد را تضمین می کند.
لطفاً توجه داشته باشید که اتصالات پین خاص و کد برنامهنویسی ممکن است بسته به مدل دقیق برد ESP32 که استفاده میکنید و سروو موتورهایی که دارید متفاوت باشد. برای تخصیص دقیق پین ها و الزامات ولتاژ، مهم است که به دیتاشیت ها و نمودارهای پین اوت قطعات خود مراجعه کنید. علاوه بر این، مطمئن شوید که منبع تغذیه و اتصالات را با رعایت بهترین روشها برای جلوگیری از آسیبدیدگی به قطعات، ایمن انجام میدهید.
توضیح کدهای ربات عنکبوتی چهارپا ESP32
ربات عنکبوتی که در این پروژه توضیح داده شده است از طریق کنترل از راه دور عمل نمی کند. در عوض، از عملکردهای مختلفی برای اعمال مختلف مانند حرکات رو به جلو، عقب، راست و چپ استفاده می کند. این توابع مبتنی بر راه رفتن خزیدن (همچنین به عنوان راه رفتن چهارپا) هستند. الگوی راه رفتن خزیدن به یک برنامه تبدیل شده و در میکروکنترلر ESP32 تعبیه شده است. این برنامه دستورالعمل هایی را به سروو موتورها ارائه می دهد و آنها را هدایت می کند تا پاهای ربات را در موقعیت های مورد نظر برای حرکات مورد نظر حرکت دهند. با اجرای راه رفتن خزیدن برنامه ریزی شده، ربات عنکبوتی می تواند به حرکت هماهنگ و کنترل شده دست یابد.
اجرای این کد #۱ قبل از شروع مراحل اسمبلی بسیار مهم است. این کد برای کالیبره کردن و تنظیم سروو موتورها در زوایای صحیح آنها طراحی شده است. با اجرای این کد می توانید اطمینان حاصل کنید که سروو موتورها به درستی کار می کنند و به درستی در محل قرار می گیرند. این به جلوگیری از هرگونه مشکل یا عوارض احتمالی در مراحل بعدی فرآیند مونتاژ کمک می کند.
توجه: لطفاً اطمینان حاصل کنید که همیشه قبل از آپلود کد در ESP32 سوئیچ را خاموش کرده و منبع تغذیه خارجی را قطع کنید. این مرحله بسیار مهم است زیرا سوئیچ جداسازی الکتریکی بین پین Vin ESP32 و پین Vcc سروو را فراهم می کند. این اقدام احتیاطی ایمنی و عملکرد صحیح اجزا را در طول فرآیند آپلود کد تضمین می کند. به یاد داشته باشید که هر بار که کد را برای ربات عنکبوتی در ESP32 آپلود می کنید، این روش را دنبال کنید، و جداسازی الکتریکی بین ESP32 و سرووها را حفظ کنید تا از هرگونه عارضه یا آسیب ناخواسته جلوگیری کنید.
کد #۱
#include <ESP32_Servo.h> // include servo library
// Define 8 Servos
Servo myServo1; // Front Left Pivot Servo
Servo myServo2; // Front Left Lift Servo
Servo myServo3; // Back Left Pivot Servo
Servo myServo4; // Back Left Lift Servo
Servo myServo5; // Back Right Pivot Servo
Servo myServo6; // Back Right Lift Servo
Servo myServo7; // Front Right Pivot Servo
Servo myServo8; // Front Right Lift Servo
void setup() {
// Attach servos to Arduino Pins
myServo1.attach(21);
myServo2.attach(19);
myServo3.attach(33);
myServo4.attach(25);
myServo5.attach(27);
myServo6.attach(14);
myServo7.attach(12);
myServo8.attach(13);
myServo1.write(90);
myServo2.write(90);
myServo3.write(90);
myServo4.write(90);
myServo5.write(90);
myServo6.write(90);
myServo7.write(90);
myServo8.write(90);
}
void loop() {
}
این کد شماره ۲ شامل تمام حرکات موتور سروو لازم برای عملکرد ربات شما می باشد. بدون این کد، نمی توانید پروژه را با موفقیت به پایان برسانید. برای عملکرد صحیح ربات بسیار مهم است. علاوه بر این، کد به خوبی توضیح داده شده است و توضیحاتی را برای هر بلوک کد ارائه می دهد. این نظرات به عنوان یک راهنما عمل می کنند و به شما امکان می دهند به راحتی تشخیص دهید کدام بلوک با حرکات یا عملکردهای خاص مطابقت دارد. در صورت نیاز به انجام هر گونه اصلاح یا تنظیم، نظرات به شما در درک هدف و عملکرد هر بلوک کد کمک می کند.
کد #۲ :
#include <ESP32_Servo.h> // include servo library
This line includes the ESP32_Servo library, which provides functions for controlling servo motors using the ESP32 microcontroller.
// Define the delay between function calls (in milliseconds)
const unsigned long FUNCTION_DELAY = 2000; // 2 seconds
این خط یک ثابت جهانی به نام FUNCTION_DELAY را اعلام می کند که نشان دهنده تاخیر در میلی ثانیه بین هر فراخوانی تابع است.
// Define 8 Servos
Servo myServo1; // Front Left Pivot Servo
Servo myServo2; // Front Left Lift Servo
Servo myServo3; // Back Left Pivot Servo
Servo myServo4; // Back Left Lift Servo
Servo myServo5; // Back Right Pivot Servo
Servo myServo6; // Back Right Lift Servo
Servo myServo7; // Front Right Pivot Servo
Servo myServo8; // Front Right Lift Servo
این بلوک هشت شیء سروو را «myServo1» به «myServo8» اعلام میکند. هر جسم نشان دهنده یک موتور سروو است و با یک عملکرد خاص (به عنوان مثال، محور یا بالابر) و یک پای خاص از ربات عنکبوتی مرتبط است.
void setup() {
// Attach servos to Arduino Pins
myServo1.attach(21);
myServo2.attach(19);
myServo3.attach(33);
myServo4.attach(25);
myServo5.attach(27);
myServo6.attach(14);
myServo7.attach(12);
myServo8.attach(13);
center_servos();
Serial.println("center");
delay(2000);
}
هنگام راه اندازی میکروکنترلر، عملکرد راه اندازی یک بار اجرا می شود. هر شی Servo را با استفاده از متد attach() به پین آردوینو مربوطه متصل می کند. تابع center_servos() فراخوانی می شود تا تمام سروو موتورها را در موقعیت مرکزی خود قرار دهد و برای پایداری یک تاخیر ۲ ثانیه ای اضافه می شود.
void loop() {
// Move Forward 10 step
for (int i = 0; i < 10; i++) {
moveLegServos_Forward();
}
center_servos();
delay(FUNCTION_DELAY);
// Move Backward 10 step
for (int i = 0; i < 10; i++) {
moveLegServos_Backward();
}
center_servos();
delay(FUNCTION_DELAY);
// Move Right 10 step
for (int i = 0; i < 10; i++) {
moveLegServos_Right();
}
center_servos();
delay(FUNCTION_DELAY);
// Move Left 10 step
for (int i = 0; i < 10; i++) {
moveLegServos_Left();
}
center_servos();
delay(FUNCTION_DELAY);
// dance 10 step
for (int i = 0; i < 10; i++) {
dance();
}
center_servos();
delay(FUNCTION_DELAY);
// pushup 10 step
for (int i = 0; i < 10; i++) {
pushup();
}
center_servos();
delay(FUNCTION_DELAY);
}
این بلوک حاوی تابع “loop()” است که به طور مکرر پس از تابع “setup()” اجرا می شود. این شامل چندین حلقه “for” است که هر کدام تعداد مراحل را برای یک حرکت خاص کنترل می کند. در هر تکرار، یک تابع حرکتی مربوطه نامیده میشود (“moveLegServos_Forward()”، “moveLegServos_Backward()”، “moveLegServos_Right()”، “moveLegServos_Left()”، “pushup()”، “dance()”). پس از هر حرکت، تابع “center_servos()” فراخوانی می شود تا همه موتورهای سروو را به موقعیت مرکزی خود بازنشانی کند. تاخیر “FUNCTION_DELAY” میلی ثانیه بین هر حرکت معرفی می شود.
// Move Spider Robot Forward Function
void moveLegServos_Forward() {
// Control the servo actions for each leg
// Left side leg - Leg 1
moveLeg_Left_Forward(myServo8, myServo7, myServo8);
// Left side leg - Leg 4
moveLeg_Left_Forward(myServo2, myServo1, myServo2);
// Left side leg - Legs 1 and 4
for (int angle = 0; angle <= 90; angle += 2) {
myServo7.write(angle);
myServo1.write(angle);
delay(10);
}
// Right side leg - Leg 2
moveLeg_Right_Forward(myServo6, myServo5, myServo6);
// Right side leg - Leg 3
moveLeg_Right_Forward(myServo4, myServo3, myServo4);
// Right side leg - Legs 2 and 3
for (int angle = 180; angle >= 90; angle -= 2) {
myServo5.write(angle);
myServo3.write(angle);
delay(10);
}
}
این بلوک تابع “moveLegServos_Forward()” را تعریف می کند، که اقدامات سروو را برای حرکت روبات عنکبوتی به جلو کنترل می کند. توابع “moveLeg_Left_Forward()” و “moveLeg_Right_Forward()” را برای کنترل حرکت هر پا فراخوانی می کند. عملکرد به تدریج زوایای سروو را تنظیم می کند تا به موقعیت های مطلوب پا برای حرکت رو به جلو دست یابد.
// Move Spider Robot Backward Function
void moveLegServos_Backward() {
// Control the servo actions for each leg
// Left side leg - Leg 1
moveLeg_Left_Backward(myServo2, myServo1, myServo2);
// Left side leg - Leg 4
moveLeg_Left_Backward(myServo8, myServo7, myServo8);
// Left side leg - Legs 1 and 4
for (int angle = 180; angle >= 90; angle -= 2) {
myServo1.write(angle);
myServo7.write(angle);
delay(10);
}
// Right side leg - Leg 2
moveLeg_Right_Backward(myServo4, myServo3, myServo4);
// Right side leg - Leg 3
moveLeg_Right_Backward(myServo6, myServo5, myServo6);
// Right side leg - Legs 2 and 3
for (int angle = 0; angle <= 90; angle += 2) {
myServo3.write(angle);
myServo5.write(angle);
delay(10);
}
}
این بلوک تابع “moveLegServos_Backward()” را تعریف می کند، که عملکردهای سروو را برای حرکت روبات عنکبوتی به جلو کنترل می کند. توابع “moveLeg_Left_Backward()” و “moveLeg_Right_Backward()” را برای کنترل حرکت هر پا فراخوانی می کند. عملکرد به تدریج زوایای سروو را تنظیم می کند تا به موقعیت های مطلوب پا برای حرکت به عقب دست یابد.
// Move Spider Robot Right Function
void moveLegServos_Right() {
// Control the Right turn servo actions for each leg
moveLeg_Right(myServo8, myServo7, myServo1); // Leg 4
moveLeg_Right(myServo6, myServo5, myServo7); // Leg 3
moveLeg_Right(myServo4, myServo3, myServo5); // Leg 2
moveLeg_Right(myServo2, myServo1, myServo3); // Leg 1
}
// Move Spider Robot Left Function
void moveLegServos_Left() {
// Control the Left turn servo actions for each leg
moveLeg_Left(myServo8, myServo7, myServo1); // Leg 4
moveLeg_Left(myServo6, myServo5, myServo7); // Leg 3
moveLeg_Left(myServo4, myServo3, myServo5); // Leg 2
moveLeg_Left(myServo2, myServo1, myServo3); // Leg 1
}
در این بلوک کد، توابع «moveLegServos_Right()» و «moveLegServos_Left()» به ترتیب عملکردهای سروو را برای حرکت روبات عنکبوتی به راست و چپ کنترل می کنند. این عملکردها حرکات سرووهای پا را برای دستیابی به حرکت مورد نظر ربات عنکبوتی، به سمت راست یا چپ، هماهنگ می کند. هر تابع تابع “moveLeg_Right()” یا “moveLeg_Left()” مناسب را برای هر پایه ربات فراخوانی می کند و اشیاء سروو مربوطه را به عنوان آرگومان ارسال می کند.
// Spider Robot dance Function
void dance(){
// Move the selected servos from 0 to 180 degrees
for (int angle = 0; angle <= 180; angle += 2) {
myServo1.write(angle);
myServo3.write(angle);
myServo5.write(angle);
myServo7.write(angle);
delay(10); // Delay between each angle change (adjust as needed)
}
// Move the selected servos from 180 to 0 degrees
for (int angle = 180; angle >= 0; angle -= 2) {
myServo1.write(angle);
myServo3.write(angle);
myServo5.write(angle);
myServo7.write(angle);
delay(10); // Delay between each angle change (adjust as needed)
}
}
// Spider Robot pushup Function
void pushup(){
// Move the selected servos from 0 to 180 degrees
for (int angle = 0; angle <= 180; angle += 2) {
myServo2.write(angle);
myServo4.write(angle);
myServo6.write(angle);
myServo8.write(angle);
delay(10); // Delay between each angle change (adjust as needed)
}
// Move the selected servos from 180 to 0 degrees
for (int angle = 180; angle >= 0; angle -= 2) {
myServo2.write(angle);
myServo4.write(angle);
myServo6.write(angle);
myServo8.write(angle);
delay(10); // Delay between each angle change (adjust as needed)
}
}
این بلوک تابع pushup() و dance() را تعریف می کند که عملکردهای سروو را برای ربات عنکبوتی برای انجام یک حرکت pushup و رقص کنترل می کند. زوایای سروو را بین ۰ تا ۱۸۰ درجه برای سرووهای انتخابی (myServo1، myServo3، myServo5، myServo7) برای دستیابی به افکت حرکت رقص و (myServo2، myServo4، myServo6، myServo8) برای جلوه حرکت فشاری تغییر میدهد.
// Move Spider Robot Forward logic
void moveLeg_Left_Forward(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo) {
// Move the lift servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
liftServo.write(angle);
delay(10);
}
// Move the pivot servo from 90 to 0
for (int angle = 90; angle >= 0; angle -= 2) {
pivotServo.write(angle);
delay(10);
}
// Move the lift servo from 180 to 90
for (int angle = 180; angle >= 90; angle -= 2) {
liftServo.write(angle);
delay(10);
}
}
void moveLeg_Right_Forward(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo) {
// Move the lift servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
liftServo.write(angle);
delay(10);
}
// Move the pivot servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
pivotServo.write(angle);
delay(10);
}
// Move the lift servo from 180 to 90
for (int angle = 180; angle >= 90; angle -= 2) {
liftServo.write(angle);
delay(10);
}
}
// Move Spider Robot Backward logic
void moveLeg_Left_Backward(Servo& liftServo, Servo& pivotServo, Servo& oppositePivotServo) {
// Move the lift servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
liftServo.write(angle);
delay(10);
}
// Move the pivot servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
pivotServo.write(angle);
delay(10);
}
// Move the lift servo from 180 to 90
for (int angle = 180; angle >= 90; angle -= 2) {
liftServo.write(angle);
delay(10);
}
}
void moveLeg_Right_Backward(Servo& liftServo, Servo& pivotServo, Servo& oppositePivotServo) {
// Move the lift servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
liftServo.write(angle);
delay(10);
}
// Move the pivot servo from 90 to 0
for (int angle = 90; angle >= 0; angle -= 2) {
pivotServo.write(angle);
delay(10);
}
// Move the lift servo from 180 to 90
for (int angle = 180; angle >= 90; angle -= 2) {
liftServo.write(angle);
delay(10);
}
}
این بلوک کد شامل چهار تابع «moveLeg_Left_Forward()»، «moveLeg_Right_Forward()»، «moveLeg_Left_Backward()» و «moveLeg_Right_Backward()» است. moveLeg_Left_Forward(): این تابع وظیفه حرکت پای چپ ربات عنکبوتی را به جلو بر عهده دارد. سه شی سروو را به عنوان پارامتر می گیرد: liftServo، pivotServo، و counterPivotServo. این تابع ابتدا liftServo را از ۹۰ درجه به ۱۸۰ درجه با افزایش ۲ درجه حرکت می دهد. سپس، PivotServo را از ۹۰ درجه به ۰ درجه با همان افزایش حرکت می دهد. در نهایت، liftServo را از ۱۸۰ به ۹۰ درجه به عقب می برد. با استفاده از عبارت delay(10) هر حرکت با تاخیر ۱۰ میلی ثانیه ای همراه است. moveLeg_Right_Forward(): این تابع وظیفه حرکت پای راست ربات عنکبوتی را به جلو بر عهده دارد. ساختاری شبیه به moveLeg_Left_Forward() دارد، اما با اضافه شدن یک حرکت اضافی. پس از حرکت liftServo و pivotServo همانطور که در بالا توضیح داده شد، PivotServo مقابل را از ۰ به ۹۰ درجه منتقل می کند. هدف از این حرکت اضافی هماهنگ کردن حرکات پا برای حرکت رو به جلو است.
moveLeg_Left_Backward(): این تابع وظیفه حرکت دادن پای چپ ربات عنکبوتی را به سمت عقب بر عهده دارد. ساختاری شبیه به moveLeg_Left_Forward() دارد، اما با تغییراتی در افزایش زاویه و جهت. PivotServo از ۹۰ به ۱۸۰ درجه و liftServo از ۱۸۰ به ۹۰ درجه منتقل می شود. این تغییرات منجر به حرکت پا در جهت مخالف می شود. moveLeg_Right_Backward(): این تابع وظیفه حرکت دادن پای راست ربات عنکبوتی به عقب را بر عهده دارد. ساختاری شبیه به moveLeg_Left_Backward()، با اضافه کردن یک حرکت اضافی دارد. پس از حرکت liftServo و pivotServo همانطور که در بالا توضیح داده شد، PivotServo مقابل را از ۹۰ به ۰ درجه منتقل می کند.
// Move Spider Robot Right logic
void moveLeg_Right(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo) {
// Move the lift servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
liftServo.write(angle);
delay(10);
}
// Move the pivot servo from 90 to 0
for (int angle = 90; angle >= 0; angle -= 2) {
pivotServo.write(angle);
delay(10);
}
// Move the opposite pivot servo from 0 to 90
for (int angle = 0; angle <= 90; angle += 2) {
oppositePivotServo.write(angle);
delay(10);
}
// Move the lift servo from 90 to 180
for (int angle = 180; angle >= 90; angle -= 2) {
liftServo.write(angle);
delay(10);
}
}
// Move Spider Robot Left logic
void moveLeg_Left(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo) {
// Move the lift servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
liftServo.write(angle);
delay(10);
}
// Move the pivot servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
pivotServo.write(angle);
delay(10);
}
// Move the opposite pivot servo from 180 to 90
for (int angle = 180; angle >= 90; angle -= 2) {
oppositePivotServo.write(angle);
delay(10);
}
// Move the lift servo from 180 to 90
for (int angle = 180; angle >= 90; angle -= 2) {
liftServo.write(angle);
delay(10);
}
}
این بلوک کد شامل دو تابع moveLeg_Right() و moveLeg_Left(). در اینجا توضیحی در مورد هر تابع آورده شده است: () moveLeg_Right: این تابع وظیفه حرکت دادن پای راست ربات عنکبوتی را در جهت یا چرخش درست دارد. سه شی سروو را به عنوان پارامتر می گیرد: liftServo، pivotServo، و counterPivotServo. عملکرد با حرکت liftServo از ۹۰ درجه به ۱۸۰ درجه با افزایش ۲ درجه شروع می شود. سپس، PivotServo را از ۹۰ درجه به ۰ درجه با همان افزایش حرکت می دهد. سپس، PivotServo مقابل را از ۰ به ۹۰ درجه منتقل می کند. در نهایت، liftServo را از ۱۸۰ به ۹۰ درجه به عقب می برد. با استفاده از عبارت delay(10) هر حرکت با تاخیر ۱۰ میلی ثانیه ای همراه است. () moveLeg_Left: این تابع وظیفه حرکت پای چپ ربات عنکبوتی را در جهت یا چرخش به چپ بر عهده دارد. ساختاری مشابه با moveLeg_Right () دارد، اما با تغییراتی در افزایش زاویه و جهت. PivotServo از ۹۰ به ۱۸۰ درجه و PivotServo مخالف از ۱۸۰ به ۹۰ درجه منتقل می شود. این تغییرات منجر به حرکت پا در جهت مخالف می شود.
// All Servos Centor function
void center_servos() {
myServo1.write(90);
myServo2.write(90);
myServo3.write(90);
myServo4.write(90);
myServo5.write(90);
myServo6.write(90);
myServo7.write(90);
myServo8.write(90);
}
این بلوک تابع ()center_servos را تعریف می کند که با نوشتن زاویه ۹۰ درجه برای هر سروو، همه موتورهای سروو را در موقعیت مرکزی خود قرار می دهد.
به طور کلی، این کد یک چارچوب اساسی برای کنترل ربات عنکبوتی با استفاده از میکروکنترلر ESP32 و موتورهای سروو فراهم می کند و آن را قادر می سازد تا حرکات و اقدامات مختلفی را انجام دهد.
کد
کد #۱:
#include <ESP32_Servo.h> // include servo library
// Define 8 Servos
Servo myServo1; // Front Left Pivot Servo
Servo myServo2; // Front Left Lift Servo
Servo myServo3; // Back Left Pivot Servo
Servo myServo4; // Back Left Lift Servo
Servo myServo5; // Back Right Pivot Servo
Servo myServo6; // Back Right Lift Servo
Servo myServo7; // Front Right Pivot Servo
Servo myServo8; // Front Right Lift Servo
void setup()
{
// Attach servos to Arduino Pins
myServo1.attach(21);
myServo2.attach(19);
myServo3.attach(33);
myServo4.attach(25);
myServo5.attach(27);
myServo6.attach(14);
myServo7.attach(12);
myServo8.attach(13);
myServo1.write(90);
myServo2.write(90);
myServo3.write(90);
myServo4.write(90);
myServo5.write(90);
myServo6.write(90);
myServo7.write(90);
myServo8.write(90);
}
void loop()
{
}
کد #۲ :
#include <ESP32_Servo.h> // include servo library
// Define the delay between function calls (in milliseconds)
const unsigned long FUNCTION_DELAY = 2000; // 2 seconds
const unsigned long t = 2;
const unsigned long tt = 5;
// Define 8 Servos
Servo myServo1; // Front Left Pivot Servo
Servo myServo2; // Front Left Lift Servo
Servo myServo3; // Back Left Pivot Servo
Servo myServo4; // Back Left Lift Servo
Servo myServo5; // Back Right Pivot Servo
Servo myServo6; // Back Right Lift Servo
Servo myServo7; // Front Right Pivot Servo
Servo myServo8; // Front Right Lift Servo
void setup()
{
// Attach servos to Arduino Pins
myServo1.attach(21);
myServo2.attach(19);
myServo3.attach(33);
myServo4.attach(25);
myServo5.attach(27);
myServo6.attach(14);
myServo7.attach(12);
myServo8.attach(13);
center_servos();
Serial.println("center");
delay(2000);
}
void loop()
{
//Move Forward 10 step
for (int i = 0; i < 10; i++) {
moveLegServos_Forward();
}
center_servos();
delay(FUNCTION_DELAY);
// Move Backward 10 step
for (int i = 0; i < 10; i++) {
moveLegServos_Backward();
}
center_servos();
delay(FUNCTION_DELAY);
// Move Right 10 step
for (int i = 0; i < 10; i++) {
moveLegServos_Right();
}
center_servos();
delay(FUNCTION_DELAY);
// Move Left 10 step
for (int i = 0; i < 10; i++) {
moveLegServos_Left();
}
center_servos();
delay(FUNCTION_DELAY);
// dance 10 step
for (int i = 0; i < 5; i++) {
dance();
}
center_servos();
delay(FUNCTION_DELAY);
// pushup 10 step
for (int i = 0; i < 10; i++) {
pushup();
}
center_servos();
delay(FUNCTION_DELAY);
}
// Move Spider Robot Forward Function
void moveLegServos_Forward()
{
// Control the servo actions for each leg
// Left side leg - Leg 1
moveLeg_Left_Forward(myServo8, myServo7, myServo8);
// Left side leg - Leg 4
moveLeg_Left_Forward(myServo2, myServo1, myServo2);
// Left side leg - Legs 1 and 4
for (int angle = 0; angle <= 90; angle += 2) {
myServo7.write(angle);
myServo1.write(angle);
delay(tt);
}
// Right side leg - Leg 2
moveLeg_Right_Forward(myServo6, myServo5, myServo6);
// Right side leg - Leg 3
moveLeg_Right_Forward(myServo4, myServo3, myServo4);
// Right side leg - Legs 2 and 3
for (int angle = 180; angle >= 90; angle -= 2) {
myServo5.write(angle);
myServo3.write(angle);
delay(tt);
}
}
// Move Spider Robot Backward Function
void moveLegServos_Backward()
{
// Control the servo actions for each leg
// Left side leg - Leg 1
moveLeg_Left_Backward(myServo2, myServo1, myServo2);
// Left side leg - Leg 4
moveLeg_Left_Backward(myServo8, myServo7, myServo8);
// Left side leg - Legs 1 and 4
for (int angle = 180; angle >= 90; angle -= 2) {
myServo1.write(angle);
myServo7.write(angle);
delay(tt);
}
// Right side leg - Leg 2
moveLeg_Right_Backward(myServo4, myServo3, myServo4);
// Right side leg - Leg 3
moveLeg_Right_Backward(myServo6, myServo5, myServo6);
// Right side leg - Legs 2 and 3
for (int angle = 0; angle <= 90; angle += 2) {
myServo3.write(angle);
myServo5.write(angle);
delay(tt);
}
}
// Move Spider Robot Right Function
void moveLegServos_Right() {
// Control the Right turn servo actions for each leg
moveLeg_Right(myServo8, myServo7, myServo5); // Leg 4
moveLeg_Right(myServo2, myServo1, myServo7); // Leg 3
moveLeg_Right(myServo4, myServo3, myServo1); // Leg 2
moveLeg_Right(myServo6, myServo5, myServo3); // Leg 1
}
// Move Spider Robot Left Function
void moveLegServos_Left() {
// Control the Left turn servo actions for each leg
moveLeg_Left(myServo8, myServo7, myServo1); // Leg 4
moveLeg_Left(myServo6, myServo5, myServo7); // Leg 3
moveLeg_Left(myServo4, myServo3, myServo5); // Leg 2
moveLeg_Left(myServo2, myServo1, myServo3); // Leg 1
}
// Spider Robot dance Function
void dance(){
// Move the selected servos from 0 to 180 degrees
for (int angle = 0; angle <= 180; angle += 2) {
myServo1.write(angle);
myServo3.write(angle);
myServo5.write(angle);
myServo7.write(angle);
delay(t); // Delay between each angle change (adjust as needed)
}
// Move the selected servos from 180 to 0 degrees
for (int angle = 180; angle >= 0; angle -= 2) {
myServo1.write(angle);
myServo3.write(angle);
myServo5.write(angle);
myServo7.write(angle);
delay(t); // Delay between each angle change (adjust as needed)
}
center_servos();
delay(100);
lean_left();
delay(300);
lean_right();
delay(300);
lean_left();
delay(300);
lean_right();
delay(300);
lean_left();
delay(300);
lean_right();
delay(300);
lean_left();
delay(300);
lean_right();
delay(500);
center_servos();
delay(300);
bow();
center_servos();
}
// Spider Robot pushup Function
void pushup(){
// Move the selected servos from 0 to 180 degrees
for (int angle = 0; angle <= 180; angle += 2) {
myServo2.write(angle);
myServo4.write(angle);
myServo6.write(angle);
myServo8.write(angle);
delay(10); // Delay between each angle change (adjust as needed)
}
// Move the selected servos from 180 to 0 degrees
for (int angle = 180; angle >= 0; angle -= 2) {
myServo2.write(angle);
myServo4.write(angle);
myServo6.write(angle);
myServo8.write(angle);
delay(10); // Delay between each angle change (adjust as needed)
}
}
// Move Spider Robot Forward logic
void moveLeg_Left_Forward(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo)
{
// Move the lift servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
liftServo.write(angle);
delay(tt);
}
// Move the pivot servo from 90 to 0
for (int angle = 90; angle >= 0; angle -= 2) {
pivotServo.write(angle);
delay(tt);
}
// Move the lift servo from 180 to 90
for (int angle = 180; angle >= 90; angle -= 2) {
liftServo.write(angle);
delay(tt);
}
}
void moveLeg_Right_Forward(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo)
{
// Move the lift servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
liftServo.write(angle);
delay(tt);
}
// Move the pivot servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
pivotServo.write(angle);
delay(tt);
}
// Move the lift servo from 180 to 90
for (int angle = 180; angle >= 90; angle -= 2) {
liftServo.write(angle);
delay(tt);
}
}
// Move Spider Robot Backward logic
void moveLeg_Left_Backward(Servo& liftServo, Servo& pivotServo, Servo& oppositePivotServo)
{
// Move the lift servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
liftServo.write(angle);
delay(tt);
}
// Move the pivot servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
pivotServo.write(angle);
delay(tt);
}
// Move the lift servo from 180 to 90
for (int angle = 180; angle >= 90; angle -= 2) {
liftServo.write(angle);
delay(tt);
}
}
void moveLeg_Right_Backward(Servo& liftServo, Servo& pivotServo, Servo& oppositePivotServo)
{
// Move the lift servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
liftServo.write(angle);
delay(tt);
}
// Move the pivot servo from 90 to 0
for (int angle = 90; angle >= 0; angle -= 2) {
pivotServo.write(angle);
delay(tt);
}
// Move the lift servo from 180 to 90
for (int angle = 180; angle >= 90; angle -= 2) {
liftServo.write(angle);
delay(tt);
}
}
// Move Spider Robot Right logic
void moveLeg_Right(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo)
{
// Move the lift servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
liftServo.write(angle);
delay(t);
}
// Move the pivot servo from 90 to 0
for (int angle = 90; angle >= 0; angle -= 2) {
pivotServo.write(angle);
delay(t);
}
// Move the opposite pivot servo from 0 to 90
for (int angle = 0; angle <= 90; angle += 2) {
oppositePivotServo.write(angle);
delay(t);
}
// Move the lift servo from 90 to 180
for (int angle = 180; angle >= 90; angle -= 2) {
liftServo.write(angle);
delay(t);
}
}
// Move Spider Robot Left logic
void moveLeg_Left(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo)
{
// Move the lift servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
liftServo.write(angle);
delay(t);
}
// Move the pivot servo from 90 to 180
for (int angle = 90; angle <= 180; angle += 2) {
pivotServo.write(angle);
delay(t);
}
// Move the opposite pivot servo from 180 to 90
for (int angle = 180; angle >= 90; angle -= 2) {
oppositePivotServo.write(angle);
delay(t);
}
// Move the lift servo from 180 to 90
for (int angle = 180; angle >= 90; angle -= 2) {
liftServo.write(angle);
delay(t);
}
}
void bow()
{
center_servos();
delay(200);
myServo2.write(15);
myServo8.write(15);
delay(700);
myServo2.write(90);
myServo8.write(90);
delay(700);
}
void lean_left()
{
myServo2.write(15);
myServo4.write(15);
myServo6.write(150);
myServo8.write(150);
}
void lean_right()
{
myServo2.write(150);
myServo4.write(150);
myServo6.write(15);
myServo8.write(15);
}
// All Servos Centor function
void center_servos()
{
myServo1.write(90);
myServo2.write(90);
myServo3.write(90);
myServo4.write(90);
myServo5.write(90);
myServo6.write(90);
myServo7.write(90);
myServo8.write(90);
}