模式定义
原型模式(Prototype Pattern)是一种创建型设计模式,通过克隆已有对象来创建新对象,避免重复执行昂贵的初始化操作。该模式特别适用于需要高效创建相似对象的场景,是自动驾驶感知系统中处理大量重复数据结构的理想选择。
自动驾驶感知场景分析
在自动驾驶感知系统中,典型的应用场景包括:
- 障碍物克隆:快速复制已识别的障碍物模板
- 点云分割:高效生成相似的点云聚类实例
- 传感器配置:复用基础配置模板创建新传感器实例
本文将重点实现障碍物对象的原型管理模块。
C++实现代码(含详细注释)
#include <iostream>
#include <unordered_map>
#include <memory>
#include <cmath>
// ---------------------------- 抽象原型接口 ----------------------------
class ObstaclePrototype {
public:
virtual ~ObstaclePrototype() = default;
// 克隆接口(关键方法)
virtual std::unique_ptr<ObstaclePrototype> clone() const = 0;
// 更新状态(示例方法)
virtual void updatePosition(float delta_x, float delta_y) = 0;
// 显示信息(示例方法)
virtual void display() const = 0;
};
// ---------------------------- 具体原型实现 ----------------------------
// 车辆障碍物原型
class Vehicle : public ObstaclePrototype {
private:
float pos_x; // X坐标
float pos_y; // Y坐标
float length; // 车长
float width; // 车宽
std::string type; // 车辆类型
public:
Vehicle(float x, float y, float l, float w, std::string t)
: pos_x(x), pos_y(y), length(l), width(w), type(std::move(t)) {}
// 实现克隆方法(关键实现)
std::unique_ptr<ObstaclePrototype> clone() const override {
std::cout << "克隆车辆对象 [" << type << "]" << std::endl;
return std::make_unique<Vehicle>(*this); // 调用拷贝构造函数
}
void updatePosition(float delta_x, float delta_y) override {
pos_x += delta_x;
pos_y += delta_y;
}
void display() const override {
std::cout << "车辆类型: " << type
<< " 位置(" << pos_x << ", " << pos_y
<< ") 尺寸: " << length << "x" << width << std::endl;
}
// 特有方法:计算占据面积
float calculateArea() const {
return length * width;
}
};
// 行人原型
class Pedestrian : public ObstaclePrototype {
private:
float pos_x;
float pos_y;
float speed;
int id;
public:
Pedestrian(float x, float y, float s, int i)
: pos_x(x), pos_y(y), speed(s), id(i) {}
std::unique_ptr<ObstaclePrototype> clone() const override {
std::cout << "克隆行人对象 #" << id << std::endl;
return std::make_unique<Pedestrian>(*this);
}
void updatePosition(float delta_x, float delta_y) override {
pos_x += delta_x * speed;
pos_y += delta_y * speed;
}
void display() const override {
std::cout << "行人 #" << id
<< " 位置(" << pos_x << ", " << pos_y
<< ") 速度: " << speed << "m/s" << std::endl;
}
// 特有方法:预测运动轨迹
void predictTrajectory(float time) const {
std::cout << "预测 " << time << "秒后位置: ("
<< pos_x + speed * time << ", "
<< pos_y + speed * time << ")" << std::endl;
}
};
// ---------------------------- 原型管理器 ----------------------------
class PrototypeManager {
private:
std::unordered_map<std::string, std::unique_ptr<ObstaclePrototype>> prototypes;
public:
// 注册原型
void registerPrototype(const std::string& key,
std::unique_ptr<ObstaclePrototype> proto) {
prototypes[key] = std::move(proto);
std::cout << "已注册原型: " << key << std::endl;
}
// 创建克隆
std::unique_ptr<ObstaclePrototype> createClone(const std::string& key) {
if (prototypes.find(key) != prototypes.end()) {
return prototypes[key]->clone();
}
std::cerr << "错误: 未找到原型 " << key << std::endl;
return nullptr;
}
// 显示已注册原型
void listPrototypes() const {
std::cout << "\n=== 已注册原型列表 ===" << std::endl;
for (const auto& pair : prototypes) {
std::cout << "- " << pair.first << std::endl;
}
}
};
// ---------------------------- 场景演示 ----------------------------
int main() {
PrototypeManager manager;
// 初始化并注册原型
manager.registerPrototype("sedan",
std::make_unique<Vehicle>(0, 0, 4.8f, 1.8f, "轿车"));
manager.registerPrototype("truck",
std::make_unique<Vehicle>(0, 0, 8.5f, 2.5f, "卡车"));
manager.registerPrototype("adult",
std::make_unique<Pedestrian>(0, 0, 1.2f, 1001));
// 显示可用原型
manager.listPrototypes();
// 动态创建障碍物实例
auto obstacle1 = manager.createClone("sedan");
auto obstacle2 = manager.createClone("adult");
auto obstacle3 = manager.createClone("truck");
// 使用克隆对象
if (obstacle1) {
obstacle1->updatePosition(10.5f, 3.2f);
obstacle1->display();
// 类型特定操作(需要向下转型)
if (auto vehicle = dynamic_cast<Vehicle*>(obstacle1.get())) {
std::cout << "车辆面积: " << vehicle->calculateArea() << "m²" << std::endl;
}
}
if (obstacle2) {
obstacle2->updatePosition(2.0f, 1.5f);
obstacle2->display();
if (auto ped = dynamic_cast<Pedestrian*>(obstacle2.get())) {
ped->predictTrajectory(5.0f);
}
}
return 0;
}
代码解析
1. 原型接口设计
class ObstaclePrototype {
public:
virtual std::unique_ptr<ObstaclePrototype> clone() const = 0;
// ...
};
- 核心克隆方法:强制子类实现对象复制功能
- 多态支持:统一接口处理各种障碍物类型
2. 具体原型实现
class Vehicle : public ObstaclePrototype {
std::unique_ptr<ObstaclePrototype> clone() const override {
return std::make_unique<Vehicle>(*this); // 调用拷贝构造函数
}
// ...
};
- 深拷贝实现:利用C++的拷贝构造函数确保对象独立性
- 特有方法保留:各子类可保持专属行为特征
3. 原型管理器
class PrototypeManager {
std::unordered_map<std::string, std::unique_ptr<ObstaclePrototype>> prototypes;
// ...
};
- 中央注册表:统一管理所有可用原型
- 动态扩展:运行时添加/移除原型
运行结果
已注册原型: sedan
已注册原型: truck
已注册原型: adult
=== 已注册原型列表 ===
- sedan
- truck
- adult
克隆车辆对象 [轿车]
克隆行人对象 #1001
克隆车辆对象 [卡车]
车辆类型: 轿车 位置(10.5, 3.2) 尺寸: 4.8x1.8
车辆面积: 8.64m²
行人 #1001 位置(2.4, 1.8) 速度: 1.2m/s
预测 5秒后位置: (8.4, 7.8)
模式优势分析
在自动驾驶中的价值
-
性能优化
- 避免重复初始化复杂对象(如3D点云数据)
- 快速复制预处理后的标准障碍物模板
-
动态配置
- 运行时添加新障碍物类型(如特殊车辆)
- 支持OTA更新障碍物识别参数
-
状态保存
- 克隆历史帧数据用于轨迹预测
- 创建障碍物快照用于安全校验
扩展改进建议
1. 差异克隆控制
// 扩展克隆接口
enum CloneType { FULL, LIGHTWEIGHT };
virtual std::unique_ptr<ObstaclePrototype> clone(CloneType type) const;
2. 原型版本管理
class VersionedPrototype : public ObstaclePrototype {
int version = 1;
void updateParameters() { /*...*/ version++; }
};
3. 原型池优化
class PrototypePool {
std::vector<std::unique_ptr<ObstaclePrototype>> pool;
// 实现对象复用逻辑
};
原型模式总结
核心价值:
- 通过对象克隆替代昂贵的新建操作
- 保持新对象与原型的一致性
- 支持动态运行时对象类型扩展
适用场景:
- 需要高效创建大量相似障碍物实例的感知系统
- 需要保存和恢复传感器数据快照的场景
- 支持动态加载新障碍物类型的自动驾驶平台
本实现展示了原型模式在自动驾驶感知系统中的典型应用,通过标准化的克隆接口和统一的原型管理,显著提升了系统创建障碍物对象的效率和灵活性。