دوچرخه چطور بدون راننده تعادل نگه میدارد؟
دو روش اصلی برای تعادل دوچرخه بدون راننده وجود دارد: روش فرمان زدن (مثل پست موتورسیکلت) و روش چرخ واکنشی (Reaction Wheel). در روش دوم یک دیسک سنگین با موتور BLDC در بالای دوچرخه نصب میشود. وقتی دوچرخه کج میشود، این دیسک خلاف جهت میچرخد و با اثر ممان اینرسی زاویهای (Angular Momentum) دوچرخه را سرپا نگه میدارد — دقیقاً مثل فضاپیماها که با reaction wheel جهتگیری را حفظ میکنند.
این روش برای دوچرخه در جای ثابت (پارکشده) عالی کار میکند و نیازی به حرکت ندارد — برخلاف روش فرمان که باید دوچرخه در حال حرکت باشد تا تعادل برقرار شود.
🛠️ کارت پروژه
| چه میسازیم؟ | دوچرخه ۲۶ اینچ با Reaction Wheel روی فریم |
| بودجه | ~۱.۸M تومان (با موتور BLDC و VESC) |
| زمان | ۱ آخر هفته ساخت + ۱ روز تنظیم PID |
BOM
| قطعه | مشخصات | قیمت |
|---|---|---|
| دوچرخه کارکرده | ۲۶ اینچ — هر مدل | ~۵۰۰K |
| موتور BLDC 5065 140KV | برای reaction wheel | ~۴۰۰K |
| VESC 4.12 یا FSESC | درایور FOC موتور | ~۵۰۰K |
| دیسک آلومینیوم ۲۰cm قطر، ۱cm ضخامت | وزن reaction wheel | ~۲۰۰K |
| Arduino Mega 2560 | کنترل PID | ~۲۵۰K |
| MPU-6050 | IMU | ~۴۰K |
| باتری LiPo 4S 5000mAh | ۱۴.۸V برای VESC | ~۶۰۰K |
محاسبه ممان اینرسی دیسک
برای یک دیسک توپر با جرم m و شعاع r: I = ½ × m × r²
دیسک آلومینیوم ۲۰cm قطر، ۱cm ضخامت: m ≈ ۰.۸۵kg → I = ½ × ۰.۸۵ × ۰.۱² = 0.00425 kg·m²
با چرخش ۳۰۰۰ RPM گشتاور واکنشی: T = I × α — برای اصلاح ۱°/s² نیاز است: T = 0.00425 × 0.0175 ≈ 74 mN·m — کافی برای دوچرخه ۱۵kg.
مراحل نصب Reaction Wheel
- یک پایه L-شکل از آلومینیوم ۵mm روی لوله افقی فریم دوچرخه (بالاترین نقطه) جوش یا ببند.
- موتور BLDC را در مرکز دیسک با Hub Adapter وصل کن.
- مجموعه دیسک+موتور را عمود بر صفحه دوچرخه (محور چرخش = محور طولی) نصب کن.
- MPU-6050 را روی فریم نصب کن — محور X باید موازی جهت حرکت باشد.
- VESC را زیر فریم با تسمه ولکرو ثابت کن.
کد PID برای Reaction Wheel
#include <Wire.h>
#include <MPU6050.h>
MPU6050 imu;
// VESC درایو از طریق UART یا PWM
// این مثال از PWM روی D9 استفاده میکند (0-255 → سرعت BLDC)
float Kp=120.0, Ki=2.0, Kd=8.0;
float angle=0, setpoint=0;
float errSum=0, lastErr=0;
unsigned long lastTime;
void setup(){
Wire.begin(); imu.initialize();
pinMode(9, OUTPUT);
lastTime = millis();
}
void loop(){
int16_t ax,ay,az,gx,gy,gz;
imu.getMotion6(&ax,&ay,&az,&gx,&gy,&gz);
float dt = (millis()-lastTime)/1000.0; lastTime=millis();
// roll angle (چپ-راست)
float accelRoll = atan2(ax, az)*180.0/PI;
angle = 0.98*(angle+(gz/131.0)*dt)+0.02*accelRoll;
float err = setpoint - angle;
errSum += err*dt; errSum=constrain(errSum,-50,50);
float dErr=(err-lastErr)/dt; lastErr=err;
float out = Kp*err + Ki*errSum + Kd*dErr;
// تبدیل خروجی PID به سرعت reaction wheel
// مثبت = چرخش یک جهت، منفی = معکوس
int pwmVal = 128 + constrain((int)out,-128,127);
analogWrite(9, pwmVal);
delay(5);
}