模式定義
原型模式(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() << "m2" << 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.64m2
行人 #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;// 實現對象復用邏輯
};
原型模式總結
核心價值:
- 通過對象克隆替代昂貴的新建操作
- 保持新對象與原型的一致性
- 支持動態運行時對象類型擴展
適用場景:
- 需要高效創建大量相似障礙物實例的感知系統
- 需要保存和恢復傳感器數據快照的場景
- 支持動態加載新障礙物類型的自動駕駛平臺
本實現展示了原型模式在自動駕駛感知系統中的典型應用,通過標準化的克隆接口和統一的原型管理,顯著提升了系統創建障礙物對象的效率和靈活性。