Volver a Guides

Idiomas de programación de robots: Python, C++, ROS

Mejores lenguajes de programación para la robótica: Python para el prototipado, C++ para el control en tiempo real, ROS para la integración del sistema.

Comparación de idiomas

Language Typical Latencia Key Libraries Best For Limitation
Python 1-10 ms (non-deterministic) NumPy, OpenCV, PyTorch, rclpy Rapid prototyping, ML/AI, data processing, research GIL prevents true parallelism; not real-time safe
C++ <1 ms (deterministic with RT kernel) Eigen, rclcpp, MoveIt2, Drake Real-time control loops, drivers, production systems Slow iteration; complex build systems; memory management
Rust <1 ms (deterministic) ros2_rust, nalgebra Safety-critical systems, memory-safe drivers Small robotics ecosystem; steep learning curve
MATLAB / Simulink N/A (offline / codegen) Robotics System Toolbox, ROS Toolbox Control system design, simulation, academic research Expensive license ($2K+/yr); not used in production
Proprietary (KRL, RAPID, Karel) <1 ms (built into controller) Vendor-specific Industrial robot programming on OEM controllers No portability; vendor lock-in; limited ecosystem

Arquitectura ROS2 para el control de robots

ROS2 (Robo Operating System 2) no es un lenguaje, es un marco de software intermedio que proporciona comunicación (DDS), gestión de paquetes y una arquitectura estándar para construir software de robots.

  • Nodos: Procesos independientes (uno por sensor, controlador, planificador).
  • Temas: Transmisión de mensajes sincrónicos. T2 (sensor_msgs/JointState) publica posiciones conjuntas a 100-1000 Hz. T3 (sensor_msgs/Imagen) publica cuadros a 30-60 Hz.
  • Jerarquía de circuito de control: Nivel de servo (1-10 kHz, se ejecuta en firmware del controlador motor) → Nivel conjunto (100-1000 Hz, ros2_control) → Nivel de tarea (10-30 Hz, MoveIt2/inferencia de política)

La recomendación práctica: escribir nodos Python para la percepción, la planificación y la lógica de alto nivel. escribir nodos C++ para los bucles de control que deben cumplir con las garantías de tiempo. Este es el patrón utilizado por todos los principales controladores de robots ROS2.

Requisitos de control en tiempo real

Los diferentes componentes del robot tienen diferentes requisitos de tiempo:

  • Luz de control de servo: <1 ms (1-10 kHz). Se ejecuta en el firmware del controlador del motor (no en su código).
  • Colección conjunta de control: 1-10 ms (100-1000 Hz). Envía posiciones/velocidades/torques objetivo a los motores. Debe ser determinista. Utilice T4 con un núcleo en tiempo real (PREEMPT_RT parche para Linux).
  • Planamiento de movimiento: 10-100 ms por plan. MoveIt2 genera trayectorias libres de colisiones. No en tiempo real, pero debe ser lo suficientemente rápido para una replantación reactiva.
  • Las políticas de la red neuronal (imitación de aprendizaje, RL) se ejecutan en la GPU. Python está bien aquí - la GPU maneja la computación pesada.
  • Procesamiento de visión: 16-33 ms por fotograma (30-60 Hz). Detección, segmentación, estimación de la posición. GPU acelerada, Python con PyTorch/ONNX.

Código de muestra: Control básico de brazos con Python ROS2

import rclpy
from rclpy.node import Node
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint
from builtin_interfaces.msg import Duration

class ArmController(Node):
    def __init__(self):
        super().__init__('arm_controller')
        self.publisher = self.create_publisher(
            JointTrajectory,
            '/joint_trajectory_controller/joint_trajectory',
            10
        )
        self.joint_names = [
            'joint1', 'joint2', 'joint3',
            'joint4', 'joint5', 'joint6'
        ]

    def move_to_pose(self, positions, duration_sec=2.0):
        """Send arm to target joint positions."""
        msg = JointTrajectory()
        msg.joint_names = self.joint_names

        point = JointTrajectoryPoint()
        point.positions = positions  # radians
        point.time_from_start = Duration(sec=int(duration_sec),
            nanosec=int((duration_sec % 1) * 1e9))
        msg.points = [point]

        self.publisher.publish(msg)
        self.get_logger().info(f'Moving to: {positions}')

def main():
    rclpy.init()
    controller = ArmController()

    # Home position
    controller.move_to_pose([0.0, -1.57, 1.57, 0.0, 1.57, 0.0])

    rclpy.spin(controller)
    rclpy.shutdown()

if __name__ == '__main__':
    main()

Este ejemplo funciona con cualquier brazo compatible con ROS2 (OpenArm 1, UR, Kinova) que expone un T5. Para el OpenArm 1, los nombres conjuntos están documentados en la configuración de URDF y MoveIt2 proporcionada con el brazo.

Bibliotécas y marcos clave

  • MoveIt2: Marco de planificación de movimiento. generación de trayectorias conscientes de colisiones, cinemática inversa, planificación de captura. API de Python y C ++.
  • Nav2: Estaca de navegación para robots móviles. Planificación de caminos, evitación de obstáculos, localización (AMCL).
  • Drake: Biblioteca de robótica del MIT para dinámica multibodies, control basado en optimización y simulación. C++ con enlaces de Python. Excelente para la investigación de manipulación rica en contactos.
  • PyTorch / JAX: Marco ML para políticas de manipulación de entrenamiento. PyTorch domina en la investigación robótica (utilizada por RT-2, Octo, ACT). JAX está ganando tracción para RL (brax, mujoco-mjx).
  • OpenCV: Visión por ordenador. Calibración de cámara, procesamiento de imágenes, detección de ArUco. Disponible en Python y C++.
  • LeRobot (Hugging Face): Marco de código abierto para el aprendizaje de robots. Gestión de conjuntos de datos, capacitación en políticas (ACT, Política de difusión) y implementación. Basado en Python.

Cuándo usar cada lengua

  • Use Python cuando: Prototipando nuevos comportamientos, escribiendo tuberías de entrenamiento de ML, procesando datos de sensores, experimentando scripting, construyendo paneles de control web.
  • Use C++ cuando: Escriba controladores de motor, implementa bucles de control que deben cumplir con plazos de tiempo difíciles (<1ms jitter), construye sistemas de producción donde el rendimiento importa, contribuye a MoveIt2 o Nav2.
  • Use Rust cuando: Construye componentes críticos para la seguridad donde la seguridad de la memoria es primordial, escriba nuevos conductores de motores o cuando su equipo tenga experiencia en Rust.
  • Use lenguajes propietarios cuando: Usted debe programar un robot industrial (KUKA, ABB, FANUC) en su controlador nativo. Evite si es posible - prefiere puentes ROS2.

Comparación de idiomas

Language Typical Latencia Key Libraries Best For Limitation
Python 1-10 ms (non-deterministic) NumPy, OpenCV, PyTorch, rclpy Rapid prototyping, ML/AI, data processing, research GIL prevents true parallelism; not real-time safe
C++ <1 ms (deterministic with RT kernel) Eigen, rclcpp, MoveIt2, Drake Real-time control loops, drivers, production systems Slow iteration; complex build systems; memory management
Rust <1 ms (deterministic) ros2_rust, nalgebra Safety-critical systems, memory-safe drivers Small robotics ecosystem; steep learning curve
MATLAB / Simulink N/A (offline / codegen) Robotics System Toolbox, ROS Toolbox Control system design, simulation, academic research Expensive license ($2K+/yr); not used in production
Proprietary (KRL, RAPID, Karel) <1 ms (built into controller) Vendor-specific Industrial robot programming on OEM controllers No portability; vendor lock-in; limited ecosystem

Arquitectura ROS2 para el control de robots

ROS2 (Robo Operating System 2) no es un lenguaje, es un marco de software intermedio que proporciona comunicación (DDS), gestión de paquetes y una arquitectura estándar para construir software de robots.

  • Nodos: Procesos independientes (uno por sensor, controlador, planificador).
  • Temas: Transmisión de mensajes sincrónicos. T6 (sensor_msgs/JointState) publica posiciones conjuntas a 100-1000 Hz. T7 (sensor_msgs/Imagen) publica cuadros a 30-60 Hz.
  • Jerarquía de circuito de control: Nivel de servo (1-10 kHz, se ejecuta en firmware del controlador motor) → Nivel conjunto (100-1000 Hz, ros2_control) → Nivel de tarea (10-30 Hz, MoveIt2/inferencia de política)

La recomendación práctica: escribir nodos Python para la percepción, la planificación y la lógica de alto nivel. escribir nodos C++ para los bucles de control que deben cumplir con las garantías de tiempo. Este es el patrón utilizado por todos los principales controladores de robots ROS2.

Requisitos de control en tiempo real

Los diferentes componentes del robot tienen diferentes requisitos de tiempo:

  • Luz de control de servo: <1 ms (1-10 kHz). Se ejecuta en el firmware del controlador del motor (no en su código).
  • Búsqueda de control conjunto: 1-10 ms (100-1000 Hz). Envía posiciones/velocidades/torques objetivo a los motores. Debe ser determinista. Utilice T8 con un núcleo en tiempo real (PREEMPT_RT parche para Linux).
  • Planamiento de movimiento: 10-100 ms por plan. MoveIt2 genera trayectorias libres de colisiones. No en tiempo real, pero debe ser lo suficientemente rápido para una replantación reactiva.
  • Las políticas de la red neuronal (imitación de aprendizaje, RL) se ejecutan en la GPU. Python está bien aquí - la GPU maneja la computación pesada.
  • Procesamiento de visión: 16-33 ms por fotograma (30-60 Hz). Detección, segmentación, estimación de la posición. GPU acelerada, Python con PyTorch/ONNX.

Código de muestra: Control básico de brazos con Python ROS2

import rclpy
from rclpy.node import Node
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint
from builtin_interfaces.msg import Duration

class ArmController(Node):
    def __init__(self):
        super().__init__('arm_controller')
        self.publisher = self.create_publisher(
            JointTrajectory,
            '/joint_trajectory_controller/joint_trajectory',
            10
        )
        self.joint_names = [
            'joint1', 'joint2', 'joint3',
            'joint4', 'joint5', 'joint6'
        ]

    def move_to_pose(self, positions, duration_sec=2.0):
        """Send arm to target joint positions."""
        msg = JointTrajectory()
        msg.joint_names = self.joint_names

        point = JointTrajectoryPoint()
        point.positions = positions  # radians
        point.time_from_start = Duration(sec=int(duration_sec),
            nanosec=int((duration_sec % 1) * 1e9))
        msg.points = [point]

        self.publisher.publish(msg)
        self.get_logger().info(f'Moving to: {positions}')

def main():
    rclpy.init()
    controller = ArmController()

    # Home position
    controller.move_to_pose([0.0, -1.57, 1.57, 0.0, 1.57, 0.0])

    rclpy.spin(controller)
    rclpy.shutdown()

if __name__ == '__main__':
    main()

Este ejemplo funciona con cualquier brazo compatible con ROS2 (OpenArm 1, UR, Kinova) que expone un T9. Para el OpenArm 1, los nombres conjuntos están documentados en la configuración de URDF y MoveIt2 proporcionada con el brazo.

Bibliotécas y marcos clave

  • MoveIt2: Marco de planificación de movimiento. generación de trayectorias conscientes de colisiones, cinemática inversa, planificación de captura. API de Python y C ++.
  • Nav2: Estaca de navegación para robots móviles. Planificación de caminos, evitación de obstáculos, localización (AMCL).
  • Drake: Biblioteca de robótica del MIT para dinámica multibodies, control basado en optimización y simulación. C++ con enlaces de Python. Excelente para la investigación de manipulación rica en contactos.
  • PyTorch / JAX: Marco ML para políticas de manipulación de entrenamiento. PyTorch domina en la investigación robótica (utilizada por RT-2, Octo, ACT). JAX está ganando tracción para RL (brax, mujoco-mjx).
  • OpenCV: Visión por ordenador. Calibración de cámara, procesamiento de imágenes, detección de ArUco. Disponible en Python y C++.
  • LeRobot (Hugging Face): Marco de código abierto para el aprendizaje de robots. Gestión de conjuntos de datos, capacitación en políticas (ACT, Política de difusión) y implementación. Basado en Python.

Cuándo usar cada lengua

  • Use Python cuando: Prototipando nuevos comportamientos, escribiendo tuberías de entrenamiento de ML, procesando datos de sensores, experimentando scripting, construyendo paneles de control web.
  • Use C++ cuando: Escriba controladores de motor, implementa bucles de control que deben cumplir con plazos de tiempo difíciles (<1ms jitter), construye sistemas de producción donde el rendimiento importa, contribuye a MoveIt2 o Nav2.
  • Use Rust cuando: Construye componentes críticos para la seguridad donde la seguridad de la memoria es primordial, escriba nuevos conductores de motores o cuando su equipo tenga experiencia en Rust.
  • Use lenguajes propietarios cuando: Usted debe programar un robot industrial (KUKA, ABB, FANUC) en su controlador nativo. Evite si es posible - prefiere puentes ROS2.