Bu, konunun uzun ve teknik rehberi (ESP-IDF, MicroPython, rclcpp gibi alternatiflerle). Adım adım yol için Porti görevlerine dön.
Aynı robot, iki dünya
ros2_control: mock, Gazebo ve gerçek robot tek launch'ta
Robotunun dijital ikizini kuruyorsun. diff_drive_controller hem Gazebo'da hem gerçek robotta aynı; aradaki tek fark bir launch argümanı. Bunun için ESP32'yle seri porttan konuşan ilk C++ ros2_control donanım arayüzünü yazıyorsun. Robotik yazılım ilanlarının çoğu tam olarak bu katmanı istiyor.
- ros2_control_demos'taki DiffBot'u çalıştırıp içini okudun
- Robotun Gazebo Harmonic'te teleop ile sürülüyor
- C++ SystemInterface eklentisi: seri port, bloklamayan okuma, watchdog
- hw:=mock | gazebo | real tek launch dosyası
- Aynı komut dizisinde sim ve gerçek odometry aynı grafikte
Hazır örnekte ros2_control'ü gör
ros2_control_demos example 2 çalışıyor; controller ve donanım arayüzlerini CLI ile inceleyebiliyor, mock donanımla robotu sürebiliyorsun.
# ros2_control'ü önce hazır örnekte gör (mock donanım)
sudo apt install -y ros-jazzy-ros2-control ros-jazzy-ros2-controllers ros-jazzy-ros2-control-demos
ros2 launch ros2_control_demo_example_2 diffbot.launch.py
ros2 control list_controllers # diffbot_base_controller active
ros2 control list_hardware_interfaces # left_wheel_joint/velocity [claimed]
ros2 topic pub --rate 10 /diffbot_base_controller/cmd_vel geometry_msgs/msg/TwistStamped \
"{twist: {linear: {x: 0.3}, angular: {z: 0.5}}}"
Kendi robotun Gazebo'da
3. haftanın URDF'i Gazebo Harmonic'te doğuyor, gz_ros2_control ile diff_drive_controller çalışıyor, teleop ile sürülüyor.
- Tarayıcıdaki simülasyon "idealleştirilmiş" bir ikiz: Gazebo da öyle. Tekerlek sürtünmesi, kütle ve ataletin simdeki değerleri gerçeği belirler.
<!-- urdf/rover.ros2_control.xacro — aynı controller, üç farklı donanım -->
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:arg name="hw" default="mock"/> <!-- mock | gazebo | real -->
<ros2_control name="RoverSystem" type="system">
<hardware>
<xacro:if value="${'$(arg hw)' == 'gazebo'}">
<plugin>gz_ros2_control/GazeboSimSystem</plugin>
</xacro:if>
<xacro:if value="${'$(arg hw)' == 'mock'}">
<plugin>mock_components/GenericSystem</plugin>
<param name="calculate_dynamics">true</param>
</xacro:if>
<xacro:if value="${'$(arg hw)' == 'real'}">
<plugin>rover_hardware/RoverSystem</plugin>
<param name="device">/dev/ttyUSB0</param>
<param name="baud">115200</param>
<param name="ticks_per_rev">1400</param>
</xacro:if>
</hardware>
<joint name="left_wheel_joint">
<command_interface name="velocity"><param name="min">-30</param><param name="max">30</param></command_interface>
<state_interface name="position"/>
<state_interface name="velocity"/>
</joint>
<joint name="right_wheel_joint">
<command_interface name="velocity"><param name="min">-30</param><param name="max">30</param></command_interface>
<state_interface name="position"/>
<state_interface name="velocity"/>
</joint>
</ros2_control>
<xacro:if value="${'$(arg hw)' == 'gazebo'}">
<gazebo>
<plugin filename="gz_ros2_control-system" name="gz_ros2_control::GazeboSimROS2ControlPlugin">
<parameters>$(find rover_bringup)/config/controllers.yaml</parameters>
</plugin>
</gazebo>
</xacro:if>
</robot>- Gazebo'da robot zıplıyor ya da kayıyorsa atalet değerleri gerçekçi değil ya da çarpışma geometrileri iç içe.
- Robot simde düz gitmiyorsa tekerlek ekseni yönünü (axis) kontrol et.
- teleop_twist_keyboard varsayılanı Twist; Jazzy diff_drive_controller TwistStamped ister: -p stamped:=true.
C++ donanım arayüzün
ros2_control, ESP32'ye seri porttan tekerlek hızı yazıyor ve tick okuyor. Aynı controller gerçek robotu sürüyor.
// rover_hardware/include/rover_hardware/rover_system.hpp
#pragma once
#include <hardware_interface/system_interface.hpp>
#include <hardware_interface/types/hardware_interface_return_values.hpp>
#include <rclcpp/rclcpp.hpp>
#include <string>
#include <vector>
namespace rover_hardware {
class RoverSystem : public hardware_interface::SystemInterface {
public:
RCLCPP_SHARED_PTR_DEFINITIONS(RoverSystem)
CallbackReturn on_init(const hardware_interface::HardwareInfo& info) override;
CallbackReturn on_activate(const rclcpp_lifecycle::State&) override;
CallbackReturn on_deactivate(const rclcpp_lifecycle::State&) override;
std::vector<hardware_interface::StateInterface> export_state_interfaces() override;
std::vector<hardware_interface::CommandInterface> export_command_interfaces() override;
hardware_interface::return_type read(const rclcpp::Time&, const rclcpp::Duration&) override;
hardware_interface::return_type write(const rclcpp::Time&, const rclcpp::Duration&) override;
private:
bool openPort();
void closePort();
std::string device_;
int baud_ = 115200;
double ticksPerRev_ = 1400;
int fd_ = -1;
std::string rx_; // satır biriktirme tamponu
int32_t lastTicks_[2] = {0, 0};
bool haveTicks_ = false;
// ros2_control bu dizilere pointer tutar: boyutları on_init'te sabitlenir
std::vector<double> pos_, vel_, cmd_;
};
} // namespace rover_hardware
- Seri port izni: kullanıcını dialout grubuna ekle (sudo usermod -aG dialout $USER), oturumu yeniden aç.
- Port adı her takışta değişiyorsa udev kuralı yaz: /dev/rover sabit olsun.
- read/write içinde log yazma, bellek ayırma, bloklama yapma: döngü 100 Hz'i tutturamaz.
Daha derin
- Seri protokolü ikili (binary) ve CRC'li yap; bozuk satır yüzünden hız sıçramasın.
- Donanım arayüzünü gtest ile test et: sahte bir seri port (pty çifti) ile.
Tek launch, üç mod, bir karşılaştırma
Aynı komut dizisini mock, Gazebo ve gerçek robotta koşturup üç odometry'yi aynı grafikte karşılaştırdın.
- Simde patinaj ve aks hatasını gerçek robotta ölçtüğün değerlere ayarla. Gazebo'yu da aynı yöne nasıl itebilirsin?
# MuJoCo ile aynı ros2_control (Jazzy için paket var)
sudo apt install -y ros-jazzy-mujoco-ros2-control ros-jazzy-mujoco-ros2-control-demos
ros2 launch mujoco_ros2_control_demos 01_basic_robot.launch.py
# Kendi robotun için: ros2_control etiketinde plugin
# mujoco_ros2_control/MujocoSystemInterface
# ve param mujoco_model → MJCF sahne dosyan (ya da URDF'ten çalışma anında üretilen MJCF).
Daha derin
- Aynı ros2_control yapısını MuJoCo ile çalıştır (mujoco_ros2_control); temas modellerini Gazebo ile karşılaştır.
- Gazebo'ya sensör gürültüsü ekle; tarayıcıdaki simülasyonla aynı davranışı yakalayabiliyor musun?
Kavramlar
Kaynaklar
- ros2_control dokümanı
- Articulated Robotics · Mobil robotu ros2_control ile gerçekte sürme
- diffdrive_arduino · Mikrodenetleyici donanım arayüzü örneği
- Strands Robots: Simulation and hardware