ROS چیست و چرا برای UGV پیشرفته لازم است؟
ROS (Robot Operating System) یک چارچوب نرمافزاری متنباز برای رباتها است که روی Linux اجرا میشود. درست مثل سیستمعامل کامپیوتر، به ماژولهای مختلف (node) اجازه میدهد از طریق پیامرسانی با هم ارتباط برقرار کنند. ناوبری، مدیریت حسگر، SLAM و کنترل همه در قالب nodeهای مجزا هستند.
rosserial یک bridge است که به آردوینو اجازه میدهد مستقیماً در شبکه ROS شرکت کند — publish و subscribe توکنهای ROS از داخل کد آردوینو. Raspberry Pi نقش master را دارد و آردوینو node.
🛠️ کارت پروژه
| پردازنده | Raspberry Pi 4 (ROS master) + Arduino (node) |
| ROS | ROS Noetic (Ubuntu 20.04) |
نصب rosserial روی Raspberry Pi
sudo apt install ros-noetic-rosserial-arduino ros-noetic-rosserial
# نصب کتابخانه در Arduino IDE:
# Sketch → Include Library → Manage Libraries → جستجو "rosserial"
کد آردوینو — Subscribe به cmd_vel و Publish Odometry
#include <ros.h>
#include <geometry_msgs/Twist.h>
#include <nav_msgs/Odometry.h>
ros::NodeHandle nh;
nav_msgs::Odometry odom_msg;
ros::Publisher odom_pub("odom", &odom_msg);
// دریافت دستور حرکت از ROS
void cmdVelCallback(const geometry_msgs::Twist& cmd){
float linear = cmd.linear.x; // m/s
float angular = cmd.angular.z; // rad/s
// تبدیل به سرعت چرخ (Differential Drive)
float v_r = (2*linear + angular*WHEEL_BASE) / (2*WHEEL_RADIUS);
float v_l = (2*linear - angular*WHEEL_BASE) / (2*WHEEL_RADIUS);
int pwm_r = constrain((int)(v_r * 128/MAX_SPEED), -255, 255);
int pwm_l = constrain((int)(v_l * 128/MAX_SPEED), -255, 255);
driveDiff(pwm_l, pwm_r);
}
ros::Subscriber<geometry_msgs::Twist> cmd_sub("cmd_vel", &cmdVelCallback);
void setup(){
nh.initNode();
nh.subscribe(cmd_sub);
nh.advertise(odom_pub);
}
void loop(){
// انتشار Odometry از encoder
updateOdometry();
odom_pub.publish(&odom_msg);
nh.spinOnce();
delay(20);
}
اجرا روی Raspberry Pi
# ترمینال ۱: ROS Master
roscore
# ترمینال ۲: اتصال آردوینو
rosrun rosserial_python serial_node.py /dev/ttyACM0
# ترمینال ۳: کنترل صفحهکلید
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
# ترمینال ۴: مشاهده Odometry
rostopic echo /odom