Apollo Planning——PathLaneBorrowDecider

引用

组件数据缓存 DependencyInjector

  • DependencyInjector:依赖注入器,这是一个过于专业的名词,来自软件设计模式的依赖倒置原则的一种具体实现方式,起到模块解耦作用。
  • “依赖倒置原则(Dependence Inversion Principle)是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。”
  • DependencyInjector本质上是一个数据缓存中心,叫做DataCacheCenter更为贴切,可以叫做数据缓存器
  • DependencyInjector对象内部管理了planning模块工程过程中的实时数据和几乎全部历史数据,以便于规划任务的前后帧之间的承接,以及异常处理的回溯。
  • DependencyInjector是以空对象的形式引入到planning组件中,进而引入到planning模块中用来承载中间数据。

DependencyInjector类结构如下:
在这里插入图片描述
依赖注入结构中主要有6类成员变量,分别如下:

  • PlanningContext planning_context_:负责planning上下文的缓存,比如是否触发重新路由的ReroutingStatus信息

  • History history_: 负责障碍物状态的缓存,包括运动状态,决策结果。该数据与routing结果绑定,routing变更后会清理掉历史数据

  • FrameHistory  frame_history_:是一个可索引队列,负责planning的输入,输出等主要信息的缓存,以Frame类进行组织,内部包含LocalView结构体(负责输入数据的融合管理)。与上述的History是不同的是,该缓数据自模块启动后就开始缓存所有的Frame对象,不受routing变动的影响。

  • EgoInfo ego_info_:提供车辆动、静信息,即车辆运动状态参数(轨迹、速度、加速度等)和车辆结构参数(长宽高等)

  • apollo::common::VehicleStateProvider vehicle_state_:车辆状态提供器,用于获取车辆实时信息

  • LearningBasedData learning_based_data_:基于学习的数据,用于学习建模等

modules/planning/common/dependency_injector.h

class DependencyInjector {
 public:
  DependencyInjector() = default;
  ~DependencyInjector() = default;

  PlanningContext* planning_context() {
    return &planning_context_;
  }
  FrameHistory* frame_history() {
    return &frame_history_;
  }
  History* history() {
    return &history_;
  }
  EgoInfo* ego_info() {
    return &ego_info_;
  }
  apollo::common::VehicleStateProvider* vehicle_state() {
    return &vehicle_state_;
  }
  LearningBasedData* learning_based_data() {
    return &learning_based_data_;
  }

 private:
  PlanningContext planning_context_;
  FrameHistory frame_history_;
  History history_;
  EgoInfo ego_info_;
  apollo::common::VehicleStateProvider vehicle_state_;
  LearningBasedData learning_based_data_;
};

modules/planning/common/planning_context.h

class PlanningContext {
 public:
  PlanningContext() = default;

  void Clear();
  void Init();

  /*
   * please put all status info inside PlanningStatus for easy maintenance.
   * do NOT create new struct at this level.
   * */

  const PlanningStatus& planning_status() const { return planning_status_; }
  PlanningStatus* mutable_planning_status() { return &planning_status_; }

 private:

  /**
   * modules/planning/proto/planning_status.proto
   * 
   * message PlanningStatus {
   * optional BareIntersectionStatus bare_intersection = 1;
   * optional ChangeLaneStatus change_lane = 2;
   * optional CreepDeciderStatus creep_decider = 3;
   * optional CrosswalkStatus crosswalk = 4;
   * optional DestinationStatus destination = 5;
   * optional EmergencyStopStatus emergency_stop = 6;
   * optional OpenSpaceStatus open_space = 7;
   * optional ParkAndGoStatus park_and_go = 8;
   * optional PathDeciderStatus path_decider = 9;
   * optional PullOverStatus pull_over = 10;
   * optional ReroutingStatus rerouting = 11;
   * optional ScenarioStatus scenario = 12;
   * optional SpeedDeciderStatus speed_decider = 13;
   * optional StopSignStatus stop_sign = 14;
   * optional TrafficLightStatus traffic_light = 15;
   * optional YieldSignStatus yield_sign = 16;
   * }
   * **/
  PlanningStatus planning_status_;
};

PlanningStatus

message PlanningStatus {
  optional BareIntersectionStatus bare_intersection = 1;
  optional ChangeLaneStatus change_lane = 2;
  optional CreepDeciderStatus creep_decider = 3;
  optional CrosswalkStatus crosswalk = 4;
  optional DestinationStatus destination = 5;
  optional EmergencyStopStatus emergency_stop = 6;
  optional OpenSpaceStatus open_space = 7;
  optional ParkAndGoStatus park_and_go = 8;
  optional PathDeciderStatus path_decider = 9;
  optional PullOverStatus pull_over = 10;
  optional ReroutingStatus rerouting = 11;
  optional ScenarioStatus scenario = 12;
  optional SpeedDeciderStatus speed_decider = 13;
  optional StopSignStatus stop_sign = 14;
  optional TrafficLightStatus traffic_light = 15;
  optional YieldSignStatus yield_sign = 16;
}

PathDeciderStatus

message PathDeciderStatus {
  enum LaneBorrowDirection {
    LEFT_BORROW = 1;   // borrow left neighbor lane
    RIGHT_BORROW = 2;  // borrow right neighbor lane
  }
  optional int32 front_static_obstacle_cycle_counter = 1 [default = 0];
  optional int32 able_to_use_self_lane_counter = 2 [default = 0];
  optional bool is_in_path_lane_borrow_scenario = 3 [default = false];
  optional string front_static_obstacle_id = 4 [default = ""];
  repeated LaneBorrowDirection decided_side_pass_direction = 5;
}

它包含以下字段:

  • LaneBorrowDirection:枚举类型,表示车道借用的方向,包括LEFT_BORROW和RIGHT_BORROW两种。

  • front_static_obstacle_cycle_counter:可选的int32类型字段,表示前方静态障碍物的循环计数器,默认值为0。

  • able_to_use_self_lane_counter:可选的int32类型字段,表示能够使用自身车道的计数器,默认值为0。

  • is_in_path_lane_borrow_scenario:可选的bool类型字段,表示是否处于车道借用场景中,默认值为false。

  • front_static_obstacle_id:可选的string类型字段,表示前方静态障碍物的ID,默认值为空字符串。

  • decided_side_pass_direction:重复的LaneBorrowDirection类型字段,表示已经决定的侧向通行方向。

PathDeciderStatus消息类型用于在路径决策过程中存储状态信息,例如前方障碍物的信息、车道借用的方向等

概述

借道决策器的主要功能为判断当前车辆是否具备借道能力,其实现在类PathLaneBorrowDecider的成员函数process()中。process()函数的功能一共分为三部分:检查输入、如果路径复用则跳过借道决策。

路径:modules/planning/tasks/deciders/path_lane_borrow_decider/path_lane_borrow_decider.cc

Status PathLaneBorrowDecider::Process(
    Frame* const frame, ReferenceLineInfo* const reference_line_info) {
  // Sanity checks.
  CHECK_NOTNULL(frame);
  CHECK_NOTNULL(reference_line_info);

  // 如果路径复用则跳过借道决策
  if (FLAGS_enable_skip_path_tasks && reference_line_info->path_reusable()) {
    // for debug
    AINFO << "skip due to reusing path";
    return Status::OK();
  }

  // By default, don't borrow any lane.
  reference_line_info->set_is_path_lane_borrow(false);
  /*
    task_config: {
    task_type: PATH_LANE_BORROW_DECIDER
    path_lane_borrow_decider_config {
      allow_lane_borrowing: true
    }
  }
  */
  if (Decider::config_.path_lane_borrow_decider_config().allow_lane_borrowing() &&
      IsNecessaryToBorrowLane(*frame, *reference_line_info)) {
    reference_line_info->set_is_path_lane_borrow(true);
  }
  return Status::OK();
}

输入、输出

在这里插入图片描述

输出信息

在这里插入图片描述

借道判断IsNecessaryToBorrowLane()

借道判断主要通过核心函数IsNecessaryToBorrowLane()判断是否借道,主要涉及一些rules,包括距离信号交叉口的距离,与静态障碍物的距离,是否是单行道,是否所在车道左右车道线是虚线等规则。主要有两个功能:

  • 已处于借道场景下判断是否退出避让;

  • 未处于借道场景下判断是否具备借道能力。

bool PathLaneBorrowDecider::IsNecessaryToBorrowLane(
    const Frame& frame, const ReferenceLineInfo& reference_line_info) {
  auto* mutable_path_decider_status = injector_->planning_context()->mutable_planning_status()->mutable_path_decider();
  // 如果当前处于借道场景中                                        
  if (mutable_path_decider_status->is_in_path_lane_borrow_scenario()) {
    // 根据数值优化求解轨迹后的信息计算是否退出借道场景(如:避让输出轨迹无解时退出借道),
    // 滤波周期为6 able_to_use_self_lane_counter:能够使用自身车道的计数器
    if (mutable_path_decider_status->able_to_use_self_lane_counter() >= 6) {
      // 如果已经能够使用自车道一段时间,那么就切换到非借道。
      mutable_path_decider_status->set_is_in_path_lane_borrow_scenario(false);
      mutable_path_decider_status->clear_decided_side_pass_direction();
      AINFO << "Switch from LANE-BORROW path to SELF-LANE path.";
    }
  } else { // 如果当前不处于借道场景中
    // If originally not borrowing neighbor lane:
    ADEBUG << "Blocking obstacle ID[" << mutable_path_decider_status->front_static_obstacle_id() << "]";
    // ADC requirements check for lane-borrowing:

    // 当下面这些条件必须全部满足,才能借道:
    // 只有一条参考线,才能借道
    if (!HasSingleReferenceLine(frame)) {
      return false;
    }
    // 起点速度小于最大借道允许速度
    if (!IsWithinSidePassingSpeedADC(frame)) {
      return false;
    }

    // 阻塞障碍物必须远离路口
    if (!IsBlockingObstacleFarFromIntersection(reference_line_info)) {
      return false;
    }
    // 阻塞障碍物会一直存在
    if (!IsLongTermBlockingObstacle()) {
      return false;
    }
    // 阻塞障碍物与终点位置满足要求
    if (!IsBlockingObstacleWithinDestination(reference_line_info)) {
      return false;
    }
    // 为可侧面通过的障碍物
    if (!IsSidePassableObstacle(reference_line_info)) {
      return false;
    }

    // 在无避让方向时重新计算避让方向,若左、右借道空间均不满足则不借道,is_in_path_lane_borrow_scenario_标志为false;
    // 左借道条件满足左借道、右借道条件满足右借道,is_in_path_lane_borrow_scenario_为true。
    const auto& path_decider_status = injector_->planning_context()->planning_status().path_decider();
    if (path_decider_status.decided_side_pass_direction().empty()) {
      // first time init decided_side_pass_direction
      bool left_borrowable;
      bool right_borrowable;
      // 2m间隔一个点遍历车前100m参考线或全部参考线,如果车道线类型为黄实线、白实线则不借道。
      CheckLaneBorrow(reference_line_info, &left_borrowable, &right_borrowable);
      if (!left_borrowable && !right_borrowable) {
        mutable_path_decider_status->set_is_in_path_lane_borrow_scenario(false);
        return false;
      } else {
        mutable_path_decider_status->set_is_in_path_lane_borrow_scenario(true);
        if (left_borrowable) {
          mutable_path_decider_status->add_decided_side_pass_direction(PathDeciderStatus::LEFT_BORROW);
        }
        if (right_borrowable) {
          mutable_path_decider_status->add_decided_side_pass_direction(PathDeciderStatus::RIGHT_BORROW);
        }
      }
    }

    AINFO << "Switch from SELF-LANE path to LANE-BORROW path.";
  }
  return mutable_path_decider_status->is_in_path_lane_borrow_scenario();
}

已处于借道场景下

已处于避让场景下,根据数值优化求解轨迹后的信息计算是否退出借道场景(如:避让输出轨迹无解时退出借道),滤波周期为6,条件满足后is_path_lane_borrow_标志、is_in_path_lane_borrow_scenario_标志均为false。

  auto* mutable_path_decider_status = injector_->planning_context()->mutable_planning_status()->mutable_path_decider();
  // 如果当前处于借道场景中                                        
  if (mutable_path_decider_status->is_in_path_lane_borrow_scenario()) {
    // 根据数值优化求解轨迹后的信息计算是否退出借道场景(如:避让输出轨迹无解时退出借道),
    // 滤波周期为6 able_to_use_self_lane_counter:能够使用自身车道的计数器
    if (mutable_path_decider_status->able_to_use_self_lane_counter() >= 6) {
      // 如果已经能够使用自车道一段时间,那么就切换到非借道。
      mutable_path_decider_status->set_is_in_path_lane_borrow_scenario(false);
      mutable_path_decider_status->clear_decided_side_pass_direction();
      AINFO << "Switch from LANE-BORROW path to SELF-LANE path.";
    }
  } else { // 如果当前不处于借道场景中

未处于借道场景下

在车辆未借道时输出车辆当前的借道状态:左借道、右借道 、不借道。

1)避让约束条件如下:

    // 当下面这些条件必须全部满足,才能借道:
    // 只有一条参考线,才能借道
    if (!HasSingleReferenceLine(frame)) {
      return false;
    }
    // 起点速度小于最大借道允许速度
    if (!IsWithinSidePassingSpeedADC(frame)) {
      return false;
    }
    // 阻塞障碍物必须远离路口
    if (!IsBlockingObstacleFarFromIntersection(reference_line_info)) {
      return false;
    }
    // 阻塞障碍物会一直存在
    if (!IsLongTermBlockingObstacle()) {
      return false;
    }
    // 阻塞障碍物与终点位置满足要求
    if (!IsBlockingObstacleWithinDestination(reference_line_info)) {
      return false;
    }
    // 为可侧面通过的障碍物
    if (!IsSidePassableObstacle(reference_line_info)) {
      return false;
    }

2.避让方向
在无避让方向时重新计算避让方向,若左、右借道空间均不满足则不借道,is_in_path_lane_borrow_scenario_标志为false;左借道条件满足左借道、右借道条件满足右借道,is_in_path_lane_borrow_scenario_为true。

    // 在无避让方向时重新计算避让方向,若左、右借道空间均不满足则不借道,is_in_path_lane_borrow_scenario_标志为false;
    // 左借道条件满足左借道、右借道条件满足右借道,is_in_path_lane_borrow_scenario_为true。
    const auto& path_decider_status = injector_->planning_context()->planning_status().path_decider();
    if (path_decider_status.decided_side_pass_direction().empty()) {
      // first time init decided_side_pass_direction
      bool left_borrowable;
      bool right_borrowable;
      // 2m间隔一个点遍历车前100m参考线或全部参考线,如果车道线类型为黄实线、白实线则不借道。
      CheckLaneBorrow(reference_line_info, &left_borrowable, &right_borrowable);
      if (!left_borrowable && !right_borrowable) {
        mutable_path_decider_status->set_is_in_path_lane_borrow_scenario(false);
        return false;
      } else {
        mutable_path_decider_status->set_is_in_path_lane_borrow_scenario(true);
        if (left_borrowable) {
          mutable_path_decider_status->add_decided_side_pass_direction(PathDeciderStatus::LEFT_BORROW);
        }
        if (right_borrowable) {
          mutable_path_decider_status->add_decided_side_pass_direction(PathDeciderStatus::RIGHT_BORROW);
        }
      }
    }

重要子函数

CheckLaneBorrow()

在此函数中2m间隔一个点遍历车前100m参考线或全部参考线,如果车道线类型为黄实线、白实线则不借道。

void PathLaneBorrowDecider::CheckLaneBorrow(
    const ReferenceLineInfo& reference_line_info,
    bool* left_neighbor_lane_borrowable, bool* right_neighbor_lane_borrowable) {
  // 获取参考线信息中的参考线
  const ReferenceLine& reference_line = reference_line_info.reference_line();

  *left_neighbor_lane_borrowable = true;
  *right_neighbor_lane_borrowable = true;

  static constexpr double kLookforwardDistance = 100.0;
  double check_s = reference_line_info.AdcSlBoundary().end_s();
  const double lookforward_distance = std::min(check_s + kLookforwardDistance, reference_line.Length());
  // 2m间隔一个点遍历车前100m参考线或全部参考线,如果车道线类型为黄实线、白实线则不借道。
  while (check_s < lookforward_distance) {
    auto ref_point = reference_line.GetNearestReferencePoint(check_s);
    if (ref_point.lane_waypoints().empty()) {
      *left_neighbor_lane_borrowable = false;
      *right_neighbor_lane_borrowable = false;
      return;
    }

    const auto waypoint = ref_point.lane_waypoints().front();
    hdmap::LaneBoundaryType::Type lane_boundary_type = hdmap::LaneBoundaryType::UNKNOWN;

    if (*left_neighbor_lane_borrowable) {
      lane_boundary_type = hdmap::LeftBoundaryType(waypoint);
      if (lane_boundary_type == hdmap::LaneBoundaryType::SOLID_YELLOW || lane_boundary_type == hdmap::LaneBoundaryType::SOLID_WHITE) {
        *left_neighbor_lane_borrowable = false;
      }
      ADEBUG << "s[" << check_s << "] left_lane_boundary_type[" << LaneBoundaryType_Type_Name(lane_boundary_type) << "]";
    }
    if (*right_neighbor_lane_borrowable) {
      lane_boundary_type = hdmap::RightBoundaryType(waypoint);
      if (lane_boundary_type == hdmap::LaneBoundaryType::SOLID_YELLOW || lane_boundary_type == hdmap::LaneBoundaryType::SOLID_WHITE) {
        *right_neighbor_lane_borrowable = false;
      }
      ADEBUG << "s[" << check_s << "] right_neighbor_lane_borrowable[" << LaneBoundaryType_Type_Name(lane_boundary_type) << "]";
    }
    check_s += 2.0;
  }
}

IsSidePassableObstacle()

IsSidePassableObstacle()的实现主要在IsNonmovableObstacle()函数中实现。

IsNonmovableObstacle()函数中障碍物距离车辆很远不借道、前方障碍物停车借道、障碍物是被其他障碍物阻塞不借道

总结

经过借道决策模块计算输出的借道能力仅表示为当前车辆有借道需求且满足借道条件,但是否真的借道仍需要下游的路径生成、路径选优决定。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/256839.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

全国国控监测点点位数据,shp/excel格式,已可视化

基本信息. 数据名称: 全国国控监测点点位数据 数据格式: shpexcel 时间版本&#xff1a;2023年 数据几何类型: 点 数据精度&#xff1a;全国 数据坐标系: WGS84 数据来源&#xff1a;网络公开数据 数据字段&#xff1a; 序号字段名称字段说明1province省名称2city城市…

设计模式 原型模式 与 Spring 原型模式源码解析(包含Bean的创建过程)

原型模式 原型模式(Prototype模式)是指&#xff1a;用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型&#xff0c;创建新的对象。 原型模式是一种创建型设计模式&#xff0c;允许一个对象再创建另外一个可定制的对象&#xff0c;无需知道如何创建的细节。 工作原…

SQLturning:定位连续值范围起点和终点

在上一篇blog说到&#xff0c;如何去优化查询连续值范围&#xff0c;没看过的朋友&#xff0c;上篇blog链接[在此]。(https://blog.csdn.net/weixin_42575078/article/details/135067645?spm1001.2014.3001.5501) 那么今天来说说怎么将连续的数据合并&#xff0c;然后返回合并…

Android的组件、布局学习

介绍 公司组织架构调整&#xff0c;项目组需要承接其他项目组的android项目&#xff0c;负责维护和开发新需求&#xff0c;故学习下基础语法和项目开发。 组件学习 Toolbarheader布局部分 就是app最顶部的部分 他的显示与否&#xff0c;是与F:\androidProject\android_lear…

HTML有哪些列表以及具体的使用!!!

文章目录 一、HTML列表二、列表的应用1、无序列表2、有序列表3、自定义列表 三、总结 一、HTML列表 html的列表有三种&#xff0c;一种是无序列表&#xff0c;一种是有序列表&#xff0c;还有一种为自定义列表。 二、列表的应用 1、无序列表 <ul> <li>无序列表…

【ONE·English || 翻译作业 Development: Mendel‘s Legacy to Genetics】

总言 作业&#xff1a;没有严格按照语句结构进行翻译&#xff0c;有不规范之处。下述目录中每一小节是按照原文段落划分。   相关链接&#xff1a;pubmed中查阅的链接&#xff0c;提供了两处文章平台。 文章目录 总言part11.11.21.3 part2&#xff1a;Entwicklung and develo…

LabVIEW开发自动驾驶的双目测距系统

LabVIEW开发自动驾驶的双目测距系统 随着车辆驾驶技术的不断发展&#xff0c;自动驾驶技术正日益成为现实。从L2级别的辅助驾驶技术到L3级别的受条件约束的自动驾驶技术&#xff0c;车辆安全性和智能化水平正在不断提升。在这个过程中&#xff0c;车辆主动安全预警系统发挥着关…

hive企业级调优策略之Join优化

测试所用到的数据参考&#xff1a; 原文链接&#xff1a;https://blog.csdn.net/m0_52606060/article/details/135080511 本教程的计算环境为Hive on MR。计算资源的调整主要包括Yarn和MR。 Join算法概述 Hive拥有多种join算法&#xff0c;包括Common Join&#xff0c;Map …

Android 应用基准分析

先推荐一个作者的开源项目 最快的Json解析方式 参考 benchmark数据参考 benchmark的例子 可以参考json-benchmark 应用基准分析 是衡量时间维度的框架,是App界的鲁大师跑分,常用于耗时判断,冷启动,热启动,框架对比 预热对比等方面 开局一张图 下面再编 今天要做的是Microbe…

使用Python编写简单网络爬虫实例:爬取图片

&#x1f34e;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 ​编辑 简介 步骤 1. 安装依赖库 2. 创建目录 3. 发送HTTP请求并解析页面 4. 查找图片标签并下载图片 注意事项 结语 我的其他博客 简介 网络爬虫是一种…

我的游戏被DDoS攻击了怎么办?

“我的游戏最近一直在被攻击&#xff0c;有什么办法可以解决”&#xff0c;最近遇到不少用户来问德迅云安全提到了自己目前遇到的这个攻击问题&#xff0c;询问有没有什么好的解决办法&#xff1f; 那遇到用户反馈的DDOS攻击&#xff0c;德迅云安全是怎么做的。 很多用户现在遇…

js数组方法总结,数组遍历方法,判断数组方法总结

目录 原生数组方法数组方法用法说明数组乱序和数组拆解会改变数组的方法不改变数组的方法JS 中的数组存储 判断数组的方法数组遍历的方法forEach和map方法有什么区别 原生数组方法 1.数组和字符串转换方法&#xff1a;toString&#xff0c;toLocalString&#xff0c;join&…

如何使用Qu1ckdr0p2快速通过HTTP或HTTPS实现文件托管

关于Qu1ckdr0p2 Qu1ckdr0p2是一款功能强大的文件托管工具&#xff0c;在该工具的帮助下&#xff0c;广大研究人员可以快速通过HTTP或HTTPS托管包括Payload和后渗透代码在内的任何文件。 Qu1ckdr0p2提供了别名和搜索功能&#xff0c;相关功能模块位于qu1ckdr0p2-tools库中。默…

半导体管路连接PFA阀门的应用说明

PFA阀门在半导体行业中具有广泛的应用。以下是PFA阀门在半导体行业中的几个应用领域&#xff1a; 1. 超纯水系统&#xff1a;在半导体行业中&#xff0c;超纯水是一个至关重要的介质&#xff0c;用于洗涤和清洁半导体芯片及其他关键器件。PFA阀门由于其优异的耐腐蚀性和高纯度特…

Java设计模式之七大设计原则

七大设计原则 设计原则概述 单一职责原则 定义 一个类仅有一个引起它变化的原因 分析 模拟场景 访客用户 普通用户 VIP用户 代码实现 /*** 视频用户接口*/ public interface IVideoUserService {void definition();void advertisement(); }/*** 访客用户*/ public class…

【容器Docker】Docker学习笔记

1、什么是Docker&#xff1a; Docker 将程序和程序运行所依赖的所有环境都打包到镜像里。“build once, run anywhere”Docker 是容器的一种实现。 Windows 下如何安装Docker: 官方安装教程&#xff1a;Install Docker Desktop on Windows | Docker Docs有两种安装套装&…

【基础篇】YOLO系列之训练环境(GPU)搭建篇

&#x1f680;Pytorch环境配置&#xff08;Windows&#xff09; &#x1f528; Anaconda安装 此处下载安装即可 ⭐温馨提示&#xff1a;安装路径不能含有中文&#xff0c;建议不要安在c盘&#xff08;很占内存&#xff09; 环境变量配置 编辑系统环境变量 -> 环境变量 ->…

短视频账号矩阵系统源码3年技术服务部署

安装Web服务器&#xff1a;搭建系统需要一个Web服务器&#xff0c;例如Apache或Nginx。 安装PHP环境&#xff1a;PHP是一种服务器端脚本语言&#xff0c;用于处理Web应用程序中的动态内容。你需要安装和配置PHP环境。 一、安装MySQL数据库&#xff1a;抖音短视频SEO矩阵系统需…

React基础巩固日志1

书写了一篇vue3的基础构建之后&#xff0c;不能带着各位一起学习vue3了&#xff0c;因为我要面试上海的前端岗位了&#xff0c;所以从现在开始&#xff0c;我要带着大家一起学习React了。 以下是我使用react书写的要掌握的react的知识点&#xff1a; ** ** 那么下面我们就一一通…

链路状态路由协议——OSPF

文章目录 一、链路状态路由协议-OSPF1. 开放式最短路径优先&#xff08;OSPF&#xff09;2. OSPF 原理介绍3. OSPF 报文4. 邻居状态5. Router ID、邻居和邻接6. 邻居发现7. 数据库同步8. 支持的网络类型9. DR 和 BDR10. DR 和 BDR选举11. OSPF 区域13. OSPF 开销14. OSPF 配置1…