Bu, konunun uzun ve teknik rehberi (ESP-IDF, MicroPython, rclcpp gibi alternatiflerle). Adım adım yol için Porti görevlerine dön.

Ana rota · Hafta 2 · 7–14 saat

ESP32 ROS 2 konuşuyor

micro-ROS: /cmd_vel al, durum yayınla, her şeyi kaydet

1. haftanın motoru artık ROS 2 dünyasının bir parçası. Bilgisayardaki klavye komutu WiFi üzerinden ESP32'ye gidiyor, motorun durumu geri geliyor, hepsi bir bag dosyasına kaydediliyor. Kontrol döngüsü ESP32'de kalıyor: ağ koparsa motor 0.5 saniyede duruyor.

Günün sonunda elinde
  • Ubuntu + ROS 2 Jazzy kurulu; node, topic, service, param kavramları elinde
  • ESP32 micro-ROS node'u: /cmd_vel → motor, motor → /motor/state
  • Agent kapanıp açılınca ESP32 kendiliğinden yeniden bağlanıyor
  • Aynı test node'u hem rclpy hem rclcpp ile
  • MCAP kaydı ve Foxglove'da çizilmiş grafik
2.1

ROS 2 Jazzy'yi kur, kavramları dene

Ubuntu 24.04'te ROS 2 Jazzy çalışıyor. turtlesim üzerinde node, topic, service ve parametreyi komut satırından kullandın.

Yap
Kod
kurulum.sh
# Ubuntu 24.04 + ROS 2 Jazzy (resmi deb paketleri)
sudo apt install -y software-properties-common curl
sudo add-apt-repository universe
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" \
  | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
sudo apt update && sudo apt install -y ros-jazzy-desktop ros-dev-tools
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc && source ~/.bashrc

# Kurulum kontrolü: iki terminal
ros2 run demo_nodes_cpp talker
ros2 run demo_nodes_py listener

# Ağdaki her şey aynı domain'de olsun (robot, PC, Pi)
echo "export ROS_DOMAIN_ID=7" >> ~/.bashrc
Kanıt: rqt_graph ekran görüntüsü ve "service ile topic arasındaki fark" üzerine kendi cümlelerinle 3 satır.
Tuzaklar
  • Mac'te Docker ile GUI (RViz, rqt) zahmetli; USB cihazlar da görünmez. Bu rota için Ubuntu bir makine, ikinci el bir mini PC bile olsa, çok zaman kazandırır.
  • Her yeni terminalde source /opt/ros/jazzy/setup.bash gerekir. .bashrc'ye yazmadıysan "ros2: command not found" görürsün.
Daha derin
2.2

ESP32'yi ROS 2 node'una çevir

ESP32 WiFi üzerinden agent'a bağlanıyor, /cmd_vel dinliyor, /motor/state yayınlıyor. Agent'ı kapatıp açtığında kendini yeniden bağlıyor.

Önce simülasyonda
Dene:
  • Gecikmeyi 20-40 ms yap: WiFi üzerinden PID koşarsan ne olacağını görürsün.
  • Bu yüzden döngü ESP32'de kalıyor; ağdan yalnız hedef hız geliyor.
Simülasyon yükleniyor…
Yap
Kod
platformio.ini
; platformio.ini — micro-ROS (Jazzy) + WiFi UDP transport
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
board_microros_distro = jazzy
board_microros_transport = wifi
lib_deps =
  https://github.com/micro-ROS/micro_ros_platformio
Kanıt: ros2 topic hz /motor/state çıktısı (~50 Hz) ve teleop ile sürülen motorun videosu.
Tuzaklar
  • micro-ROS build zinciri hassastır: PlatformIO önbelleğini (.pio) silip temiz derlemek çoğu tuhaf hatayı çözer.
  • ESP32 ile PC farklı alt ağdaysa (misafir WiFi, VPN) agent bulunamaz.
  • sensor_msgs/JointState gibi dizi içeren mesajlar micro-ROS'ta önceden bellek ayırmayı ister. Bu yüzden ilk adımda sabit boyutlu Vector3 kullandık.
Daha derin
  • Transport'u seri porta çevir (board_microros_transport = serial), gecikme ve kaybı WiFi ile karşılaştır.
  • micro_ros_utilities ile JointState için statik bellek ayır, /joint_states yayınla.
  • ROS 2 middleware'ini rmw_zenoh_cpp'ye çevir; WiFi'de multicast sorunlarını nasıl çözdüğüne bak.
2.3

Aynı node: Python ve C++

Bir test node'u /cmd_vel'e step profili yolluyor ve sonucu CSV'ye yazıyor. Aynısını rclpy ve rclcpp ile yazıp farkı gördün.

Yap
Kod
motor_tools/step_test.py
#!/usr/bin/env python3
"""step_test.py — /cmd_vel'e step profili yollar, /motor/state'i CSV'ye yazar.

  ros2 run motor_tools step_test --ros-args -p speed:=0.4 -p out:=step.csv
Parametreler çalışırken değişebilir: ros2 param set /step_test speed 0.2
"""
import csv

import rclpy
from geometry_msgs.msg import Twist, Vector3
from rclpy.node import Node
from rclpy.qos import qos_profile_sensor_data


class StepTest(Node):
    def __init__(self):
        super().__init__("step_test")
        self.declare_parameter("speed", 0.3)       # m/s
        self.declare_parameter("out", "step.csv")
        self.pub = self.create_publisher(Twist, "cmd_vel", 10)
        self.create_subscription(Vector3, "motor/state", self.on_state, qos_profile_sensor_data)
        self.t0 = self.get_clock().now()
        self.file = open(self.get_parameter("out").value, "w", newline="")
        self.csv = csv.writer(self.file)
        self.csv.writerow(["t", "target_rpm", "rpm", "duty"])
        self.create_timer(0.05, self.tick)          # 20 Hz komut: watchdog'u besler

    def elapsed(self) -> float:
        return (self.get_clock().now() - self.t0).nanoseconds * 1e-9

    def tick(self):
        t = self.elapsed()
        v = self.get_parameter("speed").value
        cmd = Twist()
        cmd.linear.x = 0.0 if t < 0.5 else v if t < 3 else v * 0.4 if t < 5 else v if t < 7 else 0.0
        self.pub.publish(cmd)
        if t > 8:
            self.get_logger().info("bitti → " + self.get_parameter("out").value)
            self.file.close()
            raise SystemExit

    def on_state(self, m: Vector3):
        self.csv.writerow([f"{self.elapsed():.3f}", m.x, m.y, m.z])


def main():
    rclpy.init()
    node = StepTest()
    try:
        rclpy.spin(node)
    except SystemExit:
        pass
    finally:
        node.destroy_node()
        rclpy.try_shutdown()


if __name__ == "__main__":
    main()
Kanıt: CSV'den çizilmiş step grafiği; 1. haftadaki seri port grafiğiyle karşılaştırması (gecikme eklendi mi?).
Tuzaklar
  • colcon build sonrası source install/setup.bash yapmazsan yeni paket görünmez.
Daha derin
  • Aynı node'u rclnodejs ile TypeScript'te yaz; ROS 2'nin istemci kütüphanesi katmanını anlamak için iyi bir egzersiz.
2.4

Kaydet, oynat, Foxglove'da bak

Her deney bir MCAP dosyası. Foxglove'da hedef ve ölçülen hız aynı grafikte; deneyi istediğin zaman tekrar oynatabiliyorsun.

Yap
Kanıt: Foxglove ekran görüntüsü + bags/ klasöründe en az 3 kayıt.
Daha derin
  • foxglove_bridge ile canlı veriyi Foxglove'a akıt; 6. haftada web arayüzünde bunu kullanacaksın.

Kavramlar

Node / TopicNode bir süreç; topic sürekli akan, yayınla-abone ol veri kanalı. Web'deki pub/sub'ın karşılığı.
Service / ActionService tek seferlik istek-cevap (RPC). Action uzun süren, ilerleme bildiren, iptal edilebilen görev.
QoSReliable: kayıp yok, gecikebilir. Best effort: kayıp olabilir, hep taze. Sensör ve komut akışı best effort.
micro-ROS agentMikrodenetleyici ile DDS ağı arasındaki köprü. ESP32 agent'a UDP ile konuşur.
ROS_DOMAIN_IDAynı ağdaki ROS sistemlerini ayıran numara. Farklıysa node'lar birbirini görmez.
rosbag2 / MCAPTopic'leri zaman damgasıyla kaydeder. Bir hatayı tekrar üretebilmenin yolu.

Kaynaklar