巡线避障思路

目前在做巡线避障,请问有什么好的思路吗,如果开环的话,先往一个方向拐,拐完回正,参数不是很好调;如果是那种规划的又容易冲出赛道,拐完就找不到线了

你好!看到你在做巡线避障时遇到了控制策略的难题。这是智能车竞赛中最经典的问题,你的困惑(开环难调参、规划易冲线)非常典型。

结合社区已有的成熟方案,给你三个层级的解决思路,建议根据你的基础选择:


:bullseye: 核心结论:推荐「视觉感知 + PID闭环 + 状态机」方案

不要做开环控制(定时转弯),也不要做复杂的路径规划(容易冲出赛道)。最佳实践是:

  1. 视觉实时检测赛道中心点和障碍物位置
  2. PID闭环控制巡线(稳定、易调参)
  3. 状态机切换巡线/避障模式(逻辑清晰)

:books: 方案一:快速上手(推荐新手)

使用社区已验证的 NodeHub 功能包,1小时内可跑通:

步骤 1:部署视觉感知节点

# 安装赛道检测(ResNet18)
sudo apt update
sudo apt install -y tros-racing-track-detection-resnet

# 安装障碍物检测(YOLOv5s)
sudo apt install -y tros-racing-obstacle-detection-yolo

# 安装巡线控制节点
sudo apt install -y tros-racing-control

步骤 2:启动系统

# 终端1:摄像头
ros2 launch mipi_cam mipi_cam_640x480_nv12_hbmem.launch.py

# 终端2:视觉感知
ros2 launch racing_track_detection_resnet racing_track_detection_resnet.launch.py
ros2 launch racing_obstacle_detection_yolo racing_obstacle_detection_yolo.launch.py

# 终端3:控制
ros2 launch racing_control racing_control.launch.py

步骤 3:关键参数调优

编辑 racing_control.launch.py

parameters=[
    {"follow_linear_speed": 0.3},      # 巡线速度(先调低)
    {"follow_angular_ratio": 1.2},     # 转向灵敏度
    {"bottom_threshold": 400},         # 避障触发距离(像素)
    {"obstacle_avoidance_speed": 0.2}, # 避障时减速
]

优势:无需自己写算法,社区已调优好,参考教程


:hammer_and_wrench: 方案二:自主开发(适合想深入理解)

如果你希望自己写控制逻辑,核心是状态机 + PID

控制逻辑框架

// 伪代码示例
enum State { LINE_FOLLOWING, OBSTACLE_AVOIDING };
State current_state = LINE_FOLLOWING;

void timer_callback() {
    // 1. 读取视觉数据
    auto track_center = get_track_center();  // 赛道中心点
    auto obstacles = get_obstacles();        // 障碍物列表
    
    // 2. 状态切换
    if (has_nearby_obstacle(obstacles)) {
        current_state = OBSTACLE_AVOIDING;
    } else {
        current_state = LINE_FOLLOWING;
    }
    
    // 3. 执行控制
    if (current_state == LINE_FOLLOWING) {
        pid_follow_line(track_center);
    } else {
        avoid_obstacle(obstacles);
    }
}

PID巡线核心代码

void pid_follow_line(Point track_center) {
    int error = track_center.x - image_center_x;  // 偏差
    integral += error * dt;
    derivative = (error - last_error) / dt;
    
    float angular_velocity = Kp * error + Ki * integral + Kd * derivative;
    publish_velocity(linear_speed, angular_velocity);
    
    last_error = error;
}

避障策略(简单有效)

void avoid_obstacle(vector<Obstacle> obstacles) {
    // 找最近的障碍物
    Obstacle nearest = find_nearest(obstacles);
    
    // 判断障碍物在左侧还是右侧
    int obs_center_x = nearest.x + nearest.width / 2;
    if (obs_center_x < image_center_x) {
        // 障碍物在左,向右转
        publish_velocity(0.2, -1.5);  // 减速 + 右转
    } else {
        // 障碍物在右,向左转
        publish_velocity(0.2, 1.5);
    }
}

调参技巧

  • 先调巡线:直线速度 0.3m/s,角速度系数从 0.5 开始逐步增加
  • 再调避障:触发距离设为图像高度的 2/3 处(约 400 像素)
  • 最后调切换:确保避障后能平滑回到巡线

:rocket: 方案三:进阶优化(适合冲奖)

参考 20届智能车备赛指南,核心优化点:

1. 统一模型检测

YOLOv5s 同时检测:赛道线 + 障碍物 + 二维码

  • 单一模型,帧率更高(X3可达30fps)
  • 减少模型切换开销

2. 预测性避障

// 结合赛道中心点预判
int track_direction = track_center.x - image_center_x;
int obstacle_direction = obs_center_x - image_center_x;

// 如果障碍物阻挡预期路径,提前避障
if ((track_direction > 0 && obstacle_direction > 0) ||
    (track_direction < 0 && obstacle_direction < 0)) {
    early_avoidance = true;
}

3. 渐进式转向

根据障碍物距离动态调整转向强度:

float distance_ratio = bottom_y / image_height;
float dynamic_angular_speed = base_speed * (1.0 + distance_ratio);

:red_question_mark: 针对你的问题

问题1:开环参数难调

原因:开环控制无法适应赛道变化(弯道曲率、速度波动)
解决:必须用闭环PID,根据实时偏差调整转向

问题2:规划后找不到线

原因:避障时转向过大/时间过长,导致赛道线移出视野
解决

  1. 避障时减速(线速度降到 0.2m/s)
  2. 避障角度不要超过 45 度
  3. 避障后立即恢复巡线,让PID把车拉回赛道

:open_book: 推荐学习路径

  1. 先跑通方案一:理解数据流(摄像头→检测→控制)
  2. 阅读源码:学习 racing_control 节点的状态机实现
  3. 自己改写:加入自己的避障逻辑
  4. 优化调参:根据实际赛道调整 PID 参数

关键资源


:light_bulb: 最后建议

  1. 先用低速测试(0.2m/s),稳定后再加速
  2. Web界面实时监控:访问 http://[设备IP]:8000 查看检测效果
  3. 记录日志:用 ros2 topic echo /cmd_vel 观察控制指令
  4. 社区提问:遇到具体报错时,带上日志和代码片段再问

需要我帮你分析具体的代码实现或参数配置吗?