Bu, konunun uzun ve teknik rehberi (ESP-IDF, MicroPython, rclcpp gibi alternatiflerle). Adım adım yol için Porti görevlerine dön.
Evin haritası
LiDAR + IMU, EKF ile füzyon, SLAM Toolbox
Robota göz takıyorsun. LiDAR ile evin haritasını çıkarıyor, tekerlek odometry'si ile gyro'yu EKF'de birleştirip yön tahminini güçlendiriyorsun. Haritanın kalitesinin neden doğrudan odometry'nin kalitesine bağlı olduğunu önce simülasyonda, sonra kendi evinde görüyorsun.
- Raspberry Pi robotta: ros2_control + LiDAR sürücüsü; ağır iş PC'de
- LiDAR /scan RViz'de, TF ağacında doğru yerde
- robot_localization EKF: tekerlek + gyro; önce/sonra yön kayması
- SLAM Toolbox ile evin haritası (.pgm + .yaml)
- Haritayı çıkarırken çekilmiş hızlandırılmış video
Pi'yi robota koy, LiDAR'ı gör
Robotta Pi + LiDAR çalışıyor, PC'deki RViz'de /scan doğru yönde görünüyor.
# Raspberry Pi 4/5: Ubuntu Server 24.04 (64-bit) + ROS 2 Jazzy ros-base
# Raspberry Pi Imager → Ubuntu Server 24.04 LTS, SSH ve WiFi'yi imager'da ayarla.
sudo apt update && sudo apt install -y ros-jazzy-ros-base ros-dev-tools \
ros-jazzy-ros2-control ros-jazzy-ros2-controllers ros-jazzy-robot-localization
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc
echo "export ROS_DOMAIN_ID=7" >> ~/.bashrc
# LiDAR ve ESP32 için sabit cihaz adları (idVendor/idProduct: udevadm info -a -n /dev/ttyUSB0)
sudo tee /etc/udev/rules.d/99-rover.rules > /dev/null <<'RULES'
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ATTRS{serial}=="LIDAR_SERI_NO", SYMLINK+="lidar"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="rover"
RULES
sudo udevadm control --reload-rules && sudo udevadm trigger
# Mimari: Pi'de ros2_control + LiDAR sürücüsü, PC'de SLAM / Nav2 / RViz.
# İkisi aynı ROS_DOMAIN_ID ile aynı ağda.- Tarama 180° ters görünüyorsa laser_joint'in yaw'ı yanlış: LiDAR'ın 0° yönü üretici dokümanında.
- WiFi'de DDS multicast sorunluysa node'lar birbirini görmez. Önce aynı makinede dene, sonra ağ ayarına bak (ya da rmw_zenoh).
- LiDAR motoru dönmüyor ya da tarama kesik geliyorsa güç yetersiz: ayrı 5V hattından besle.
Kalman'ın özü ve EKF
robot_localization tekerlek odometry'sini ve gyro'yu birleştiriyor. Yerinde 10 tur döndürünce yön hatası EKF ile ve EKF'siz ölçülü.
- IMU açık ve kapalı iken kareyi sür: yön hatası nasıl değişiyor?
- Patinajı artır: gyro patinajdan etkilenmiyor, tekerlek etkileniyor.
#!/usr/bin/env python3
"""kalman_1d.py — Kalman filtresinin özü, 30 satır. EKF'nin ne yaptığını sezmek için.
Robotun yönünü (yaw) iki kaynaktan tahmin ediyoruz:
- tahmin: gyro ile entegrasyon (kayar, ama kısa vadede pürüzsüz)
- ölçüm: tekerlek odometry'sinin yönü (patinajla sıçrar, ama kaymaz)
"""
import numpy as np
rng = np.random.default_rng(0)
dt, n = 0.02, 1500
true_rate = 0.4 * np.sin(np.arange(n) * dt * 0.5) # rad/s
true_yaw = np.cumsum(true_rate) * dt
gyro = true_rate + 0.01 + rng.normal(0, 0.02, n) # 0.01 rad/s bias
wheel_yaw = true_yaw + rng.normal(0, 0.05, n)
wheel_yaw[700:720] += np.linspace(0, 0.3, 20) # patinaj anı
wheel_yaw[720:] += 0.3
x, P = 0.0, 1.0 # durum: yaw, belirsizliği
Q, R = (0.02 * dt) ** 2, 0.05**2
est = []
for k in range(n):
x, P = x + gyro[k] * dt, P + Q # tahmin
K = P / (P + R) # Kalman kazancı
x, P = x + K * (wheel_yaw[k] - x), (1 - K) * P # düzeltme
est.append(x)
gyro_only = np.cumsum(gyro) * dt
for name, e in [("sadece gyro", gyro_only), ("sadece tekerlek", wheel_yaw), ("kalman", np.array(est))]:
print(f"{name:16s} RMS hata: {np.degrees(np.sqrt(np.mean((e - true_yaw) ** 2))):.2f}°")
# Q ve R'yi değiştir: filtre hangi kaynağa ne kadar güveniyor?
- Aynı bilgiyi iki kez verme (örn. hem odometry'nin yaw'ı hem gyro): EKF ona fazla güvenir.
- IMU'nun eksenleri REP 103'e uymuyorsa (x ileri, y sol, z yukarı) EKF ters döner. TF ile imu_link yönelimini düzelt.
Evin haritasını çıkar
SLAM Toolbox ile evin bir bölümünün temiz haritası kayıtlı; loop closure'ın haritayı nasıl düzelttiğini gördün.
- Varsayılan ayarlarla haritayı çıkar: duvarlar çiftleşiyor, oran düşük.
- IMU + EKF'yi aç: yön kayması 10 kat azalıyor, harita toparlanıyor.
- SLAM düzeltmesini aç: tek ve tutarlı bir harita.
- Yön kaymasını 0, mesafe hatasını 6% yap: hangisi haritayı daha çok bozuyor?
# PC'de: SLAM Toolbox ile harita çıkar
sudo apt install -y ros-jazzy-slam-toolbox ros-jazzy-nav2-map-server
ros2 launch slam_toolbox online_async_launch.py use_sim_time:=false
# RViz: Fixed Frame = map · Add > Map (/map) · LaserScan (/scan) · TF
# Robotu YAVAŞ sür (teleop'ta hızı 0.15 m/s, dönüşü 0.5 rad/s'ye indir).
# Aynı yerden ikinci kez geçince loop closure'ı izle.
# Haritayı kaydet: Nav2 formatı (pgm + yaml) ve SLAM Toolbox'ın kendi formatı
ros2 run nav2_map_server map_saver_cli -f ~/maps/ev
ros2 service call /slam_toolbox/serialize_map slam_toolbox/srv/SerializePoseGraph "{filename: '/home/$USER/maps/ev'}"
- Hızlı dönüşte tarama "bulanıklaşır": robot dönerken LiDAR bir turu tamamlamadan pozisyon değişir.
- Cam yüzeyler ve aynalar LiDAR'ı şaşırtır; haritada hayalet duvarlar normal.
- Harita kayıyorsa sorun çoğunlukla odometry'de ya da TF zaman damgalarında, SLAM'de değil.
Daha derin
- Aynı bag dosyasını Cartographer ile haritala, sonuçları karşılaştır.
- Henki Robotics'in açık kursundaki SLAM alıştırmalarını Gazebo'da Andino robotuyla yap.
Kavramlar
Kaynaklar
- SLAM Toolbox
- robot_localization
- Maker's Pet · ESP32 + LiDAR, ağır iş PC'de: Pi'siz alternatif
- sllidar_ros2