Skip to content

B8: LiDAR y Evitación de Obstáculos

El topic /scan

ros2 topic echo /scan --once
# angle_min: -3.14159  # -180°
# angle_max:  3.14159  # +180°
# angle_increment: 0.01745  # 1° por rayo
# ranges: [3.5, 3.5, 0.8, 0.8, ...]  # metros; 3.5 = sin obstáculo

Evitación reactiva

#!/usr/bin/env python3
import rclpy, math
from rclpy.node import Node
from sensor_msgs.msg import LaserScan
from geometry_msgs.msg import TwistStamped

class ObstacleAvoider(Node):
    def __init__(self):
        super().__init__('obstacle_avoider')
        self.create_subscription(LaserScan, '/scan', self.scan_cb, 10)
        self.pub = self.create_publisher(TwistStamped, '/cmd_vel', 10)

    def scan_cb(self, msg):
        ranges = msg.ranges
        n = len(ranges)
        safe = 0.6  # metros — distancia de seguridad

        def sector(start_deg, end_deg):
            # Extrae mínima distancia en un sector angular
            i0 = int((start_deg + 180) / 360 * n)
            i1 = int((end_deg   + 180) / 360 * n)
            sector_ranges = [r for r in ranges[i0:i1] if 0.05 < r < msg.range_max]
            return min(sector_ranges) if sector_ranges else msg.range_max

        front = sector(-30, 30)
        left  = sector(30,  90)
        right = sector(-90, -30)

        cmd = TwistStamped()
        cmd.header.stamp = self.get_clock().now().to_msg()

        if front < safe:
            if left > right:
                cmd.twist.angular.z =  0.5   # girar izquierda
            else:
                cmd.twist.angular.z = -0.5   # girar derecha
        else:
            cmd.twist.linear.x = 0.15        # avanzar

        self.pub.publish(cmd)

Tarea

Modifica el nodo para que el robot navegue hasta alcanzar la posición (2.0, 0.0) en odometría, evitando obstáculos en el camino.