《重构项目》基于Apollo架构设计的项目重构方案(多种地图、多阶段、多任务、状态机管理)

1. 项目结构设计

复制代码
project/
├── config/                  # 配置文件(定义 Scenario、Stage、Task 的映射)
├── src/
│   ├── base/                # 抽象基类定义
│   │   ├── scenario_base.h/.cpp
│   │   ├── stage_base.h/.cpp
│   │   └── task_base.h/.cpp
│   ├── scenarios/           # 不同样本架地图的 Scenario 实现
│   │   ├── map_a_scenario.cpp
│   │   └── map_b_scenario.cpp
│   ├── stages/              # 阶段(Stage)实现
│   │   ├── stage1.cpp
│   │   ├── stage2.cpp
│   │   └── ...
│   ├── tasks/               # 任务(Task)实现
│   │   ├── task1.cpp
│   │   ├── task2.cpp
│   │   └── ...
│   └── main.cpp             # 入口逻辑
└── include/                 # 头文件

2. 抽象基类定义

(1) Scenario 基类
cpp 复制代码
// base/scenario_base.h
class ScenarioBase {
 public:
  virtual ~ScenarioBase() = default;

  // 初始化 Scenario(如加载配置、初始化 Stage 列表)
  virtual bool Init(const std::string& config_file) = 0;

  // 执行当前 Stage 的 Task
  virtual void Process() = 0;

  // 状态机切换接口:根据条件判断是否切换 Stage 或 Scenario
  virtual ScenarioStatus UpdateStatus() = 0;

  // 获取当前 Stage 名称
  virtual std::string GetCurrentStageName() const = 0;

 protected:
  std::string name_;                      // Scenario 名称(如 MapA/MapB)
  std::vector<std::shared_ptr<StageBase>> stages_;  // 当前 Scenario 的 Stage 列表
  size_t current_stage_index_ = 0;        // 当前 Stage 的索引
};
(2) Stage 基类
cpp 复制代码
// base/stage_base.h
class StageBase {
 public:
  virtual ~StageBase() = default;

  // 执行当前 Stage 的所有 Task
  virtual StageStatus Run() = 0;

  // 获取下一 Stage 名称(根据 Task 返回状态决定)
  virtual std::string NextStage() const = 0;

  // 获取 Stage 名称
  virtual std::string Name() const = 0;

 protected:
  std::string name_;                      // Stage 名称(如 Stage1/Stage2)
  std::vector<std::shared_ptr<TaskBase>> tasks_;  // 当前 Stage 的 Task 列表
};
(3) Task 基类
cpp 复制代码
// base/task_base.h
class TaskBase {
 public:
  virtual ~TaskBase() = default;

  // 执行单个 Task 的逻辑
  virtual TaskStatus Execute() = 0;

  // 获取 Task 名称
  virtual std::string Name() const = 0;
};

3. 状态机实现原理

(1) 状态定义
cpp 复制代码
// base/status.h
enum class ScenarioStatus {
  SUCCESS,      // 当前 Scenario 成功完成
  RUNNING,      // 当前 Scenario 继续执行
  ERROR,        // 当前 Scenario 出错
  TRANSITION    // 需要切换到其他 Scenario
};

enum class StageStatus {
  SUCCESS,      // 当前 Stage 成功完成
  RUNNING,      // 当前 Stage 继续执行
  ERROR         // 当前 Stage 出错
};

enum class TaskStatus {
  SUCCESS,      // 当前 Task 成功完成
  RUNNING,      // 当前 Task 继续执行
  ERROR         // 当前 Task 出错
};
(2) 状态机切换逻辑
  • Scenario 状态机
    • UpdateStatus() 中根据感知数据(如样本架地图类型、任务完成状态)决定是否切换 Scenario。
    • 示例:如果检测到地图类型从 MapA 切换为 MapB,则调用 SetScenario("MapB")
  • Stage 状态机
    • Run() 中依次执行所有 Task,根据 Task 返回的 TaskStatus 决定是否继续或切换 Stage。
    • 示例:如果某个 Task 返回 SUCCESS,则执行下一个 Task;如果返回 ERROR,则触发 Scenario 的重规划。

4. 样本架地图的实现示例

(1) 地图 A 的 Scenario 实现
cpp 复制代码
// scenarios/map_a_scenario.cpp
class MapAScenario : public ScenarioBase {
 public:
  std::string Name() const override { return "MapA"; }

  bool Init(const std::string& config_file) override {
    // 加载 Stage 列表(如 Stage1 -> Stage2)
    stages_.push_back(std::make_shared<Stage1>());
    stages_.push_back(std::make_shared<Stage2>());
    return true;
  }

  void Process() override {
    auto& current_stage = stages_[current_stage_index_];
    auto status = current_stage->Run();
    if (status == StageStatus::SUCCESS) {
      // 切换到下一 Stage
      current_stage_index_++;
    } else if (status == StageStatus::ERROR) {
      // 触发 Scenario 重规划
      ResetStageIndex();
    }
  }

  ScenarioStatus UpdateStatus() override {
    // 根据感知数据判断是否需要切换 Scenario
    if (CheckMapTypeChangedToB()) {
      return ScenarioStatus::TRANSITION;
    }
    return ScenarioStatus::RUNNING;
  }
};
(2) 地图 B 的 Scenario 实现
cpp 复制代码
// scenarios/map_b_scenario.cpp
class MapBScenario : public ScenarioBase {
 public:
  std::string Name() const override { return "MapB"; }

  bool Init(const std::string& config_file) override {
    // 加载 Stage 列表(如 Stage3 -> Stage4)
    stages_.push_back(std::make_shared<Stage3>());
    stages_.push_back(std::make_shared<Stage4>());
    return true;
  }

  // ... 其他方法类似
};

5. 配置文件示例

cpp 复制代码
# config/scenario_config.yaml
scenarios:
  - name: MapA
    stages:
      - name: Stage1
        tasks:
          - name: Task1
          - name: Task2
      - name: Stage2
        tasks:
          - name: Task3
  - name: MapB
    stages:
      - name: Stage3
        tasks:
          - name: Task4
          - name: Task5

6. 状态机管理器(主逻辑)

cpp 复制代码
// main.cpp
int main() {
  // 1. 加载配置文件
  std::string config_file = "config/scenario_config.yaml";
  ScenarioConfig config = LoadScenarioConfig(config_file);

  // 2. 创建初始 Scenario
  std::shared_ptr<ScenarioBase> current_scenario = CreateScenario("MapA");

  // 3. 初始化 Scenario
  if (!current_scenario->Init(config_file)) {
    return -1;
  }

  // 4. 主循环
  while (true) {
    // 4.1 执行当前 Scenario 的 Stage
    current_scenario->Process();

    // 4.2 更新 Scenario 状态
    auto status = current_scenario->UpdateStatus();
    if (status == ScenarioStatus::SUCCESS) {
      break;
    } else if (status == ScenarioStatus::TRANSITION) {
      // 切换到新的 Scenario
      std::string new_scenario_name = GetNextScenarioName();  // 通过感知数据获取
      current_scenario = CreateScenario(new_scenario_name);
      current_scenario->Init(config_file);
    }
  }

  return 0;
}

7. 关键设计原则

  1. 解耦与扩展性

    • 通过抽象基类和工厂模式(CreateScenario)实现模块解耦。
    • 新增 Scenario/Stage/Task 时无需修改现有代码,只需扩展配置文件和实现类。
  2. 状态驱动

    • 每个组件(Scenario/Stage/Task)通过返回状态(SUCCESS/RUNNING/ERROR)驱动状态机切换。
  3. 配置化

    • 通过 YAML 文件定义 Scenario、Stage、Task 的映射关系,支持快速调整流程。
  4. 容错性

    • 每个 Stage/Task 的错误状态会触发上层重规划或降级策略。

8. 总结

  • 架构层级Scenario → Stage → Task,符合 Apollo 的分层设计。
  • 状态机实现 :通过 Status 枚举和 NextStage() 方法实现动态切换。
  • 灵活性:支持两种样本架地图的差异化处理,通过配置文件灵活扩展。

你可以根据实际需求补充具体的 Task 逻辑(如路径规划、障碍物避让等),并结合感知模块的数据驱动状态机切换。

相关推荐
十秒耿直拆包选手1 小时前
Qt:主窗体(QMainwindow)初始化注意事项
c++·qt
说私域2 小时前
开源链动2+1模式与AI智能名片融合下的S2B2C商城小程序源码:重构大零售时代新生态
人工智能·重构·开源
霖003 小时前
C++学习笔记三
运维·开发语言·c++·笔记·学习·fpga开发
mit6.8243 小时前
[shad-PS4] Vulkan渲染器 | 着色器_重新编译器 | SPIR-V 格式
c++·游戏引擎·ps4
tan77º4 小时前
【Linux网络编程】Socket - TCP
linux·网络·c++·tcp/ip
Mike_Zhang5 小时前
C++使用WinHTTP访问http/https服务
c++
CHANG_THE_WORLD5 小时前
「macOS 系统字体收集器 (C++17 实现)」
开发语言·c++·macos
GiraKoo6 小时前
【GiraKoo】Breakpad 崩溃分析系统
c++
妄想出头的工业炼药师6 小时前
python和C++相互调用使用
开发语言·c++
景彡先生6 小时前
C++17 并行算法:std::execution::par
开发语言·c++