1. 为什么设计模式对机器人自动驾驶如此重要
在机器人自动驾驶系统中,设计模式不是象牙塔里的学术概念,而是直接影响系统可靠性和开发效率的工程实践。我曾在多个自动驾驶项目中亲眼见证:同样的功能需求,采用合适设计模式的代码比"面条式"代码的维护成本低60%以上。
自动驾驶系统通常需要处理:
- 多传感器数据融合(雷达、摄像头、IMU等)
- 实时路径规划与决策
- 车辆控制指令生成
- 异常状态处理
这些模块间的交互如果缺乏良好的设计模式规范,很快就会陷入"牵一发而动全身"的维护噩梦。比如当新增一个激光雷达传感器时,没有采用观察者模式的代码可能需要修改5-6个关联文件,而良好设计的系统只需新增一个传感器类并注册到消息总线。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 自动驾驶必备的5大设计模式与C++实现
2.1 工厂模式:传感器对象的智能创建
在自动驾驶系统中,工厂模式最常见的应用场景是传感器模块的初始化。不同厂商的雷达、摄像头可能有不同的初始化参数和接口,但上层系统应该用统一的方式调用。
cpp复制class Sensor {
public:
virtual void init() = 0;
virtual SensorData read() = 0;
};
class LidarFactory {
public:
static std::unique_ptr<Sensor> createLidar(const std::string& model) {
if (model == "Velodyne_VLP16") {
return std::make_unique<VelodyneLidar>();
} else if (model == "Hesai_Pandar40P") {
return std::make_unique<HesaiLidar>();
}
throw std::runtime_error("Unsupported lidar model");
}
};
实际经验:在Apollo项目中,工厂类通常会配合配置文件使用,通过JSON或YAML动态指定要创建的传感器类型,避免硬编码。
2.2 观察者模式:高效的事件通知机制
自动驾驶系统中最典型的观察者模式应用是传感器数据的分发。多个模块(定位、感知、规划)可能需要订阅同一个传感器的数据。
cpp复制class SensorDataPublisher {
std::vector<std::function<void(const SensorData&)>> callbacks_;
public:
void subscribe(std::function<void(const SensorData&)> cb) {
callbacks_.push_back(cb);
}
void publish(const SensorData& data) {
for (auto& cb : callbacks_) {
cb(data);
}
}
};
// 使用示例
publisher.subscribe([](const SensorData& data) {
localization.update(data);
});
性能优化点:在实际项目中,我们会用无锁队列替代简单的vector回调,避免在高频数据发布时的线程阻塞问题。
2.3 策略模式:可切换的规划算法
路径规划模块经常需要根据不同场景切换算法,策略模式让算法切换变得灵活:
cpp复制class PlanningStrategy {
public:
virtual Trajectory plan(const VehicleState& state,
const Environment& env) = 0;
};
class HybridAStarStrategy : public PlanningStrategy { /*...*/ };
class RRTStarStrategy : public PlanningStrategy { /*...*/ };
class Planner {
std::unique_ptr<PlanningStrategy> strategy_;
public:
void setStrategy(std::unique_ptr<PlanningStrategy> strategy) {
strategy_ = std::move(strategy);
}
Trajectory executePlan() {
return strategy_->plan(current_state_, environment_);
}
};
2.4 状态模式:处理复杂的车辆状态转换
自动驾驶车辆可能有多种状态:初始化、待命、自动驾驶、紧急停止等。状态模式可以优雅地管理这些状态转换:
cpp复制class VehicleState {
public:
virtual void enter() = 0;
virtual void handleCommand(Command cmd) = 0;
};
class StandbyState : public VehicleState {
void enter() override {
logger.info("Entering standby mode");
disableActuators();
}
void handleCommand(Command cmd) override {
if (cmd == Command::START) {
context.transitionTo(std::make_unique<AutonomousState>());
}
}
};
2.5 命令模式:可撤销的控制指令
对于车辆控制指令,特别是需要支持"撤销"功能的场景(如
