当前位置: 首页 > news >正文

【Apollo学习笔记】——规划模块TASK之LANE_CHANGE_DECIDER

文章目录

  • 前言
  • LANE_CHANGE_DECIDER功能简介
  • LANE_CHANGE_DECIDER相关配置
  • LANE_CHANGE_DECIDER总体流程
  • LANE_CHANGE_DECIDER相关子函数
    • PrioritizeChangeLane
    • UpdateStatus
    • IsClearToChangeLane
    • HysteresisFilter
  • 参考

前言

在Apollo星火计划学习笔记——Apollo路径规划算法原理与实践与【Apollo学习笔记】——Planning模块讲到……Stage::Process的PlanOnReferenceLine函数会依次调用task_list中的TASK,本文将会继续以LaneFollow为例依次介绍其中的TASK部分究竟做了哪些工作。由于个人能力所限,文章可能有纰漏的地方,还请批评斧正。

modules/planning/conf/scenario/lane_follow_config.pb.txt配置文件中,我们可以看到LaneFollow所需要执行的所有task。

stage_config: {stage_type: LANE_FOLLOW_DEFAULT_STAGEenabled: truetask_type: LANE_CHANGE_DECIDERtask_type: PATH_REUSE_DECIDERtask_type: PATH_LANE_BORROW_DECIDERtask_type: PATH_BOUNDS_DECIDERtask_type: PIECEWISE_JERK_PATH_OPTIMIZERtask_type: PATH_ASSESSMENT_DECIDERtask_type: PATH_DECIDERtask_type: RULE_BASED_STOP_DECIDERtask_type: SPEED_BOUNDS_PRIORI_DECIDERtask_type: SPEED_HEURISTIC_OPTIMIZERtask_type: SPEED_DECIDERtask_type: SPEED_BOUNDS_FINAL_DECIDERtask_type: PIECEWISE_JERK_SPEED_OPTIMIZER# task_type: PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZERtask_type: RSS_DECIDER

本文将从第一个task——LANE_CHANGE_DECIDER开始介绍。

LANE_CHANGE_DECIDER功能简介

在这里插入图片描述
LANE_CHANGE_DECIDER主要功能是:产生是否换道的决策,更新换道状态
主要逻辑是:首先判断是否产生多条参考线,若只有一条参考线,则保持直行。若有多条参考线,则根据一些条件(主车的前方和后方一定距离内是否有障碍物,旁边车道在一定距离内是否有障碍物)进行判断是否换道,当所有条件都满足时,则进行换道决策。

LANE_CHANGE_DECIDER相关配置

LANE_CHANGE_DECIDER的相关配置集中在以下两个文件:modules/planning/conf/planning_config.pb.txtmodules/planning/conf/scenario/lane_follow_config.pb.txt

// modules/planning/conf/planning_config.pb.txt
default_task_config: {task_type: LANE_CHANGE_DECIDERlane_change_decider_config {enable_lane_change_urgency_check: falseenable_prioritize_change_lane: falseenable_remove_change_lane: falsereckless_change_lane: falsechange_lane_success_freeze_time: 1.5change_lane_fail_freeze_time: 1.0}
}
// modules/planning/conf/scenario/lane_follow_config.pb.txttask_config: {task_type: LANE_CHANGE_DECIDERlane_change_decider_config {enable_lane_change_urgency_check: true}}

LANE_CHANGE_DECIDER总体流程

总体流程图如下所示:
在这里插入图片描述

接着来看一看LANE_CHANGE_DECIDER的整体代码,文件路径:modules/planning/tasks/deciders/lane_change_decider/lane_change_decider.cc
LANE_CHANGE_DECIDER实现逻辑在Process函数中:

// added a dummy parameter to enable this task in ExecuteTaskOnReferenceLine
Status LaneChangeDecider::Process(Frame* frame, ReferenceLineInfo* const current_reference_line_info) {// Sanity checks.CHECK_NOTNULL(frame);// 读取配置文件const auto& lane_change_decider_config = config_.lane_change_decider_config();// 读取ReferenceLineInfo,并检查是否为空std::list<ReferenceLineInfo>* reference_line_info =frame->mutable_reference_line_info();if (reference_line_info->empty()) {const std::string msg = "Reference lines empty.";AERROR << msg;return Status(ErrorCode::PLANNING_ERROR, msg);}// 始终允许车辆变道。车辆可能持续变道 config_path:modules/planning/proto/task_config.protoif (lane_change_decider_config.reckless_change_lane()) {PrioritizeChangeLane(true, reference_line_info);return Status::OK();}// 获取上一时刻变道状态信息并记录时间戳auto* prev_status = injector_->planning_context()->mutable_planning_status()->mutable_change_lane();double now = Clock::NowInSeconds();// 判断当前参考线是否安全可用prev_status->set_is_clear_to_change_lane(false);if (current_reference_line_info->IsChangeLanePath()) {prev_status->set_is_clear_to_change_lane(IsClearToChangeLane(current_reference_line_info));}// 是否获取到状态信息if (!prev_status->has_status()) {UpdateStatus(now, ChangeLaneStatus::CHANGE_LANE_FINISHED,GetCurrentPathId(*reference_line_info));prev_status->set_last_succeed_timestamp(now);return Status::OK();}// 参考线的数目是否大于1// 根据reference line的数量判断是否处于变道场景中,size() > 1则处于变道过程中,需要判断变道的状态bool has_change_lane = reference_line_info->size() > 1;ADEBUG << "has_change_lane: " << has_change_lane;// 只有一条reference line,没有进行变道if (!has_change_lane) {// 根据当前唯一的reference line,获得当前道路lane的IDconst auto& path_id = reference_line_info->front().Lanes().Id();// 上一时刻是否变道完成if (prev_status->status() == ChangeLaneStatus::CHANGE_LANE_FINISHED) {// 上一时刻是否在变道中。若有,这一时刻只有一条reference line,说明变道成功} else if (prev_status->status() == ChangeLaneStatus::IN_CHANGE_LANE) {// 更新当前时刻,变道完成状态,以及当前道路的IDUpdateStatus(now, ChangeLaneStatus::CHANGE_LANE_FINISHED, path_id);// 上一时刻是否变道失败} else if (prev_status->status() == ChangeLaneStatus::CHANGE_LANE_FAILED) {} else {const std::string msg =absl::StrCat("Unknown state: ", prev_status->ShortDebugString());AERROR << msg;return Status(ErrorCode::PLANNING_ERROR, msg);}// 返回LaneChangeDecider::Process 的状态为OKreturn Status::OK();} else {  // has change lane in reference lines.// 获取自车当前所在车道的IDauto current_path_id = GetCurrentPathId(*reference_line_info);// 如果当前所在车道为空,则返回error状态if (current_path_id.empty()) {const std::string msg = "The vehicle is not on any reference line";AERROR << msg;return Status(ErrorCode::PLANNING_ERROR, msg);}// 如果上一时刻处在变道中,根据上一时刻自车所处道路ID与当前时刻所处道路ID对比,来确认变道状态if (prev_status->status() == ChangeLaneStatus::IN_CHANGE_LANE) {// ID相同则说明变道还在进行中,if (prev_status->path_id() == current_path_id) {// 同时调用PrioritizeChangeLane(),将目标车道的reference line放在首位PrioritizeChangeLane(true, reference_line_info);} else {// RemoveChangeLane(reference_line_info);// ID不同则说明变道已经完成,PrioritizeChangeLane(false, reference_line_info);ADEBUG << "removed change lane.";// 更新状态UpdateStatus(now, ChangeLaneStatus::CHANGE_LANE_FINISHED,current_path_id);}return Status::OK();// 上一时刻变道失败} else if (prev_status->status() == ChangeLaneStatus::CHANGE_LANE_FAILED) {// TODO(SHU): add an optimization_failure counter to enter// change_lane_failed status// 判断当前时刻减上一时刻的时间差是否小于换道失败冻结时间// not allowed to change lane this amount of time if just failedif (now - prev_status->timestamp() <lane_change_decider_config.change_lane_fail_freeze_time()) {// RemoveChangeLane(reference_line_info);PrioritizeChangeLane(false, reference_line_info);ADEBUG << "freezed after failed";} else {UpdateStatus(now, ChangeLaneStatus::IN_CHANGE_LANE, current_path_id);ADEBUG << "change lane again after failed";}return Status::OK();// 若上一时刻换道完成} else if (prev_status->status() ==ChangeLaneStatus::CHANGE_LANE_FINISHED) {// 判断当前时刻减上一时刻的时间差是否小于换道完成冻结时间if (now - prev_status->timestamp() <lane_change_decider_config.change_lane_success_freeze_time()) {// RemoveChangeLane(reference_line_info);PrioritizeChangeLane(false, reference_line_info);ADEBUG << "freezed after completed lane change";} else {PrioritizeChangeLane(true, reference_line_info);UpdateStatus(now, ChangeLaneStatus::IN_CHANGE_LANE, current_path_id);ADEBUG << "change lane again after success";}} else {const std::string msg =absl::StrCat("Unknown state: ", prev_status->ShortDebugString());AERROR << msg;return Status(ErrorCode::PLANNING_ERROR, msg);}}return Status::OK();
}

LANE_CHANGE_DECIDER相关子函数

PrioritizeChangeLane

// 提升变道的优先级,找到变道的参考线,并将其置于首位(is_prioritize_change_lane == true)
void LaneChangeDecider::PrioritizeChangeLane(const bool is_prioritize_change_lane,std::list<ReferenceLineInfo>* reference_line_info) const {if (reference_line_info->empty()) {AERROR << "Reference line info empty";return;}const auto& lane_change_decider_config = config_.lane_change_decider_config();// TODO(SHU): disable the reference line order change for nowif (!lane_change_decider_config.enable_prioritize_change_lane()) {return;}// 遍历reference_line_info列表中的元素,并检查当前元素是否为变道路径(IsChangeLanePath)// 找到第一个需要优先排序的元素后,循环会被中断// 0、is_prioritize_change_lane 根据参考线数量置位True 或 False// 1、如果is_prioritize_change_lane为True// 首先获取第一条参考线的迭代器,然后遍历所有的参考线,// 如果当前的参考线为允许变道参考线,则将第一条参考线更换为当前迭代器所指向的参考线,// 注意,可变车道为按迭代器的顺序求取,一旦发现可变车道,即推出循环。// // 2、如果is_prioritize_change_lane 为False,// 找到第一条不可变道的参考线,将第一条参考线更新为当前不可变道的参考线auto iter = reference_line_info->begin();while (iter != reference_line_info->end()) {ADEBUG << "iter->IsChangeLanePath(): " << iter->IsChangeLanePath();/* is_prioritize_change_lane == true: prioritize change_lane_reference_lineis_prioritize_change_lane == false: prioritizenon_change_lane_reference_line */if ((is_prioritize_change_lane && iter->IsChangeLanePath()) ||(!is_prioritize_change_lane && !iter->IsChangeLanePath())) {ADEBUG << "is_prioritize_change_lane: " << is_prioritize_change_lane;ADEBUG << "iter->IsChangeLanePath(): " << iter->IsChangeLanePath();break;}++iter;}// 将变道的参考线置于列表首位(is_prioritize_change_lane == true)reference_line_info->splice(reference_line_info->begin(),*reference_line_info, iter);ADEBUG << "reference_line_info->IsChangeLanePath(): "<< reference_line_info->begin()->IsChangeLanePath();
}

UpdateStatus

void LaneChangeDecider::UpdateStatus(double timestamp,ChangeLaneStatus::Status status_code,const std::string& path_id) {auto* lane_change_status = injector_->planning_context()->mutable_planning_status()->mutable_change_lane();lane_change_status->set_timestamp(timestamp);lane_change_status->set_path_id(path_id);lane_change_status->set_status(status_code);
}

IsClearToChangeLane

// 用于检查当前参考线是否安全,或者当前参考线是否可以偏离后返回
bool LaneChangeDecider::IsClearToChangeLane(ReferenceLineInfo* reference_line_info) {// 获得当前参考线自车的s坐标的起点与终点,以及自车线速度double ego_start_s = reference_line_info->AdcSlBoundary().start_s();double ego_end_s = reference_line_info->AdcSlBoundary().end_s();double ego_v =std::abs(reference_line_info->vehicle_state().linear_velocity());// 遍历障碍物,跳过虚拟的和静止的for (const auto* obstacle :reference_line_info->path_decision()->obstacles().Items()) {if (obstacle->IsVirtual() || obstacle->IsStatic()) {ADEBUG << "skip one virtual or static obstacle";continue;}// 初始化SLdouble start_s = std::numeric_limits<double>::max();double end_s = -std::numeric_limits<double>::max();double start_l = std::numeric_limits<double>::max();double end_l = -std::numeric_limits<double>::max();// 获取动态障碍物的边界点并转化为SL坐标for (const auto& p : obstacle->PerceptionPolygon().points()) {SLPoint sl_point;reference_line_info->reference_line().XYToSL(p, &sl_point);start_s = std::fmin(start_s, sl_point.s());end_s = std::fmax(end_s, sl_point.s());start_l = std::fmin(start_l, sl_point.l());end_l = std::fmax(end_l, sl_point.l());}// 以障碍物在S方向上的起始点与终点之和的二分之一作为障碍物中心点si,获取si点的道路宽度// 若障碍物在车道线之外,则不考虑if (reference_line_info->IsChangeLanePath()) {double left_width(0), right_width(0);reference_line_info->mutable_reference_line()->GetLaneWidth((start_s + end_s) * 0.5, &left_width, &right_width);if (end_l < -right_width || start_l > left_width) {continue;}}// Raw estimation on whether same direction with ADC or not based on// prediction trajectory// 根据预测轨迹粗略判断障碍物的方向是否和自车相同bool same_direction = true;if (obstacle->HasTrajectory()) {double obstacle_moving_direction =obstacle->Trajectory().trajectory_point(0).path_point().theta();const auto& vehicle_state = reference_line_info->vehicle_state();// 获取车辆航向角double vehicle_moving_direction = vehicle_state.heading();if (vehicle_state.gear() == canbus::Chassis::GEAR_REVERSE) {vehicle_moving_direction =common::math::NormalizeAngle(vehicle_moving_direction + M_PI);}double heading_difference = std::abs(common::math::NormalizeAngle(obstacle_moving_direction - vehicle_moving_direction));same_direction = heading_difference < (M_PI / 2.0);}// TODO(All) move to confsstatic constexpr double kSafeTimeOnSameDirection = 3.0;static constexpr double kSafeTimeOnOppositeDirection = 5.0;static constexpr double kForwardMinSafeDistanceOnSameDirection = 10.0;static constexpr double kBackwardMinSafeDistanceOnSameDirection = 10.0;static constexpr double kForwardMinSafeDistanceOnOppositeDirection = 50.0;static constexpr double kBackwardMinSafeDistanceOnOppositeDirection = 1.0;static constexpr double kDistanceBuffer = 0.5;double kForwardSafeDistance = 0.0;double kBackwardSafeDistance = 0.0;// 根据方向、自车与运动障碍物之间速度关系设置安全距离if (same_direction) {kForwardSafeDistance =std::fmax(kForwardMinSafeDistanceOnSameDirection,(ego_v - obstacle->speed()) * kSafeTimeOnSameDirection);kBackwardSafeDistance =std::fmax(kBackwardMinSafeDistanceOnSameDirection,(obstacle->speed() - ego_v) * kSafeTimeOnSameDirection);} else {kForwardSafeDistance =std::fmax(kForwardMinSafeDistanceOnOppositeDirection,(ego_v + obstacle->speed()) * kSafeTimeOnOppositeDirection);kBackwardSafeDistance = kBackwardMinSafeDistanceOnOppositeDirection;}// 通过滞后滤波器判断障碍物是否满足安全距离if (HysteresisFilter(ego_start_s - end_s, kBackwardSafeDistance,kDistanceBuffer, obstacle->IsLaneChangeBlocking()) &&HysteresisFilter(start_s - ego_end_s, kForwardSafeDistance,kDistanceBuffer, obstacle->IsLaneChangeBlocking())) {reference_line_info->path_decision()->Find(obstacle->Id())->SetLaneChangeBlocking(true);ADEBUG << "Lane Change is blocked by obstacle" << obstacle->Id();return false;} else {reference_line_info->path_decision()->Find(obstacle->Id())->SetLaneChangeBlocking(false);}}return true;
}

HysteresisFilter

// 滞后滤波器
// 在安全距离附近的情况下,通过引入距离缓冲区来调整安全距离的大小,从而避免频繁进行车道变换。
bool LaneChangeDecider::HysteresisFilter(const double obstacle_distance,const double safe_distance,const double distance_buffer,const bool is_obstacle_blocking) {if (is_obstacle_blocking) {// obstacle_distance是否小于safe_distance + distance_buffer,如果是则返回true,否则返回false。return obstacle_distance < safe_distance + distance_buffer;} else {// obstacle_distance是否小于safe_distance - distance_buffer,如果是则返回true,否则返回false。return obstacle_distance < safe_distance - distance_buffer;}
}

参考

[1] Apollo规划模块详解(五):算法实现-lane change decider
[2] Apollo Planning决策规划代码详细解析 (6):LaneChangeDecider
[3] 百度Apollo5.0规划模块代码学习(四)换道决策分析
[4] Apollo planning lane_change_decider解析

相关文章:

【Apollo学习笔记】——规划模块TASK之LANE_CHANGE_DECIDER

文章目录 前言LANE_CHANGE_DECIDER功能简介LANE_CHANGE_DECIDER相关配置LANE_CHANGE_DECIDER总体流程LANE_CHANGE_DECIDER相关子函数PrioritizeChangeLaneUpdateStatusIsClearToChangeLaneHysteresisFilter 参考 前言 在Apollo星火计划学习笔记——Apollo路径规划算法原理与实…...

rabbitmq的死信队列

目录 成为死信的条件 消息TTL过期 队列达到最大长度 消息被拒 延迟队列 延迟队列使用场景 消息设置 TTL 队列设置 TTL 两者区别 producer 将消息投递到 broker 或者直接到 queue 里了&#xff0c; consumer 从 queue 取出消息 进行消费&#xff0c;但某些时候由…...

利用网络对拷工具进行系统安装与恢复

各学校计算机机房经常批量安装操作系统和应用软件。实现对批量计算机的安 装&#xff0c;应用较多的是使用 Symantec 的 ghost 企业版。但笔者采用的是网络还原精灵 &#xff08;Net Recovery Genius&#xff09;软件附带的网络对拷 Ncp.com 工具&#xff0c;利用它能够轻松实…...

opencv-python使用鼠标点击图片显示该点坐标和像素值IPM逆透视变换车道线二值化处理

OpenCV的鼠标操作 实现获取像素点的功能主要基于OpenCV的内置函数cv2.setMouseCallback()&#xff0c;即鼠标事件回调 setMouseCallback(winname, onMouse,userdata0) winname: 接收鼠标事件的窗口名称 onMouse: 处理鼠标事件的回调函数指针 userdata: 传给回调函数的用户数据…...

AIGC绘画:kaggle部署stable diffusion项目绘画

文章目录 kaggle介绍项目部署edit my copy链接显示 结果展示 kaggle介绍 Kaggle成立于2010年&#xff0c;是一个进行数据发掘和预测竞赛的在线平台。从公司的角度来讲&#xff0c;可以提供一些数据&#xff0c;进而提出一个实际需要解决的问题&#xff1b;从参赛者的角度来讲&…...

微服务概述-7

Shiro 框架 Shiro 是一个用于 Java 应用程序的安全框架。它提供了身份验证、授权、加密和会话管理等功能&#xff0c;可以帮助开发人员构建安全可靠的应用程序。 Java 中针对权限管理常见的有 2 个著名的框架&#xff1a;spring security 和 shiro shiro 基本概念 credentia…...

十二、Linux如何修改文件/文件夹所属用户or用户组?chown命令

目录 1、基础语法 2、修改目标用户&#xff1a; 3、修改用户组&#xff1a; 4、使用-R命令&#xff0c;并同时修改用户/用户组 1、基础语法 chown [-R] [目标用户][:][目标用户组] 被修改文件/文件夹 &#xff08;1&#xff09;选项-R&#xff1a;同chmod&#xff0c;对文…...

企业百家号蓝V认证后,百度营销基木鱼落地页如何嵌入百家号中

首先搭建百度营销基木鱼落地页 在我们的百度营销后台&#xff0c;点击基木鱼跳转至百度营销基木鱼页面&#xff0c;在我的站点位置&#xff0c;可以创建H5站点&#xff0c;PC站点等&#xff0c;创建完成后可以点击复制基木鱼落地页的链接。 注意事项 1、企业百家号需要进行…...

Redis缓存读写策略(三种)数据结构(5+3)

Redis缓存读写策略&#xff08;三种&#xff09; Cache Aside Pattern&#xff08;旁路缓存模式&#xff09; Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式&#xff0c;比较适合读请求比较多的场景。 写&#xff1a; 先更新 db然后直接删除 cache 。 读 : …...

计算机竞赛 Yolov安全帽佩戴检测 危险区域进入检测 - 深度学习 opencv

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; Yolov安全帽佩戴检测 危险区域进入检测 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&am…...

使用python向窗口发送鼠标点击命令

今天遇到一个问题。公司让用电脑在网页上看个视频。网页有个判断&#xff1a;一段时间没有鼠标活动&#xff0c;视频就会暂停。于是就想&#xff0c;能否隔一段时间就模拟鼠标点击一下视频暂停&#xff0c;再点一下继续播放。省得它自己停止播放。这样我就可以让网页窗口在后台…...

C++11并发与多线程笔记(6) unique_lock(类模板)

C11并发与多线程笔记&#xff08;6&#xff09; unique_lock&#xff08;类模板&#xff09; 1、unique_lock取代lock_guard2、unique_lock的第二个参数2.1 std::adopt_lock&#xff1a;2.2 std::try_to_lock&#xff1a;2.3 std::defer_lock&#xff1a; 3、unique_lock的成员…...

计算机网络——OSI与TCP/IP各层的结构与功能,都有哪些协议?

文章目录 一 OSI与TCP/IP各层的结构与功能,都有哪些协议?1.1 应用层1.2 运输层1.3 网络层1.4 数据链路层1.5 物理层1.6 总结一下 二 ⭐TCP 三次握手和四次挥手(面试常客)2.1 TCP 三次握手漫画图解2.2 为什么要三次握手⭐2.3 第2次握手传回了ACK&#xff0c;为什么还要传回SYN&…...

Win7 x86 家庭版SP1 配置 Python 开发环境

1 Win7 下载地址 来源于 MSDN, 我告诉你 - 做一个安静的工具站 ed2k://|file|cn_windows_7_home_basic_with_sp1_x86_dvd_u_676500.iso|2653276160|843E7A78F2126FAC726CF5342710082D|/ 2 Python 版本选择 Python 3.7.9 Python Release Python 3.7.9 | Python.org 3 Pychar…...

从零玩转系列之微信支付实战PC端装修我的订单页面 | 技术创作特训营第一期

一、前言 欢迎来到本期的博客&#xff01;本篇文章是 PC 端的结尾了,前面经历过九个章节到本章节刚刚好十章节感谢观看我的文章,那么接下来我们将要编写的是我的订单页面. GGBOM! 本篇完毕后将是 UniApp 的篇章感受移动端的诱惑 &#x1f497; 本次为前端知识点如果不懂前段可以…...

ChatGPT和Claude的能力全测评

创造性思维/语言 提示&#xff1a;“写一首 4 行诗&#xff0c;每行只有 3 个词&#xff0c;描写重庆” ChatGPT写诗&#x1f447; Claude写诗&#x1f447; 仁者见仁&#xff0c;您怎么看谁更强&#xff1f; 提示&#xff1a; "如果你随机选择这个问题的答案&#xff0c;…...

ffmpeg简介

1.什么是ffmpeg ffmpeg即使一款音视频编解码工具&#xff0c;同时也是一组音视频编解码开发套件&#xff0c;作为编解码开发套件&#xff0c;它为开发者提供了丰富的音视频处理的调用接口。 ffmpeg提供了多种媒体格式的封装和解封装&#xff0c;包括多种音视频编码、多种协议…...

AI绘画 stable diffusion Midjourney 官方GPT文档 AIGC百科全书资料收集

教学AI绘画 AIGC工具 SD教程 ###Redis面试题 单机Redis的qps大概是多少&#xff1f; 项目中用到了哪些Redis的数据类型&#xff1f;为什么这么用&#xff1f; Redis的key到了过期时间就被删除了吗&#xff1f;简述下Redis的过期策略&#xff1f; Redis有哪几种内存淘汰策略…...

Lombok注解大全

一、安装插件&#xff0c;eclipse 对于 lombok 的支持 二、引入依赖 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version> <!-- Spring Boot 项目此部分可以不写 --&g…...

STM32--ADC模数转换

文章目录 ADC简介逐次逼近型ADCADC框图转换模式数据对齐转换时间校准ADC基本结构ADC单通道工程代码&#xff1a; ADC简介 STM32的ADC&#xff08;Analog-Digital Converter&#xff09;模拟-数字转换器&#xff0c;是一种逐次逼近型模拟数字转换器&#xff0c;可以将引脚上连续…...

陕西科技大学改考408!附考情分析

改考信息 8月14日&#xff0c;陕西科技大学公布了2024年硕士研究生招生目录&#xff08;初稿&#xff09;&#xff0c;其中不难发现083500软件工程初试专业课由819数据结构改为408计算机学科专业基础 图片&#xff1a;陕西科技大学24专业目录-软件工程学硕 https://yjszs.sus…...

02.有监督算法——朴素贝叶斯

1.朴素贝叶斯 1.1条件概率 如果两个事件A和B不是相互独立&#xff0c;并且知道事件B已经发生&#xff0c;A在B中的条件概率&#xff1a; P ( A ∣ B ) P ( A B ) P ( B ) P(A|B) {P(AB) \over P(B)} P(A∣B)P(B)P(AB)​ 先验概率&#xff1a; 根据以往经验和分析得到的概…...

前端新手学习路线

文章目录 前端学习路线&#xff01;特点符号表大纲前言 - 学编程需要的特质一、前端入门⭐️ 开发工具浏览器编辑器文档笔记 ⭐️ HTML⭐️ CSS⭐️ JavaScript✅ ES6 特性 二、巩固基础前端基础知识计算机基础✅ 算法和数据结构✅ 计算机网络✅ 操作系统 软件开发基础✅ 设计模…...

vactor中迭代器失效问题

目录 什么是迭代器失效导致迭代器失效的操作VS和g环境下对与迭代器失效的态度 什么是迭代器失效 迭代器的底层其实就是一个指针&#xff0c;或者对指针进行了封装 vector的迭代器就是一个指针T* 一个迭代器指向某一个空间&#xff0c;此时这块空间被释放了&#xff0c;这个迭…...

电子商务防火墙的作用

1.作为网络安全的屏障 只有经过精心选择的应用协议才能通过防火墙&#xff0c;可使网络环境变得更安全。如 防火墙可以禁止 NFS 协议进出受保护的网络&#xff0c;这样外部的攻击者就不可能利用这些 脆弱的协议来攻击内部网络。防火墙同时可以保护网络免受基于路由的攻击&am…...

「UG/NX」Block UI 选择特征SelectFeature

✨博客主页何曾参静谧的博客📌文章专栏「UG/NX」BlockUI集合📚全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C+&#...

【数据分享】2006-2021年我国城市级别的节约用水相关指标(免费获取\20多项指标)

《中国城市建设统计年鉴》中细致地统计了我国城市市政公用设施建设与发展情况&#xff0c;在之前的文章中&#xff0c;我们分享过基于2006-2021年《中国城市建设统计年鉴》整理的2006—2021年我国城市级别的市政设施水平相关指标、2006-2021年我国城市级别的各类建设用地面积数…...

Azure不可变Blob存储

文章目录 Azure不可变Blob存储介绍Azure不可变性策略实战演练 Azure不可变Blob存储介绍 不可变的存储是一种用于存储业务关键型 Blob 数据的存储方式。与可变存储相反&#xff0c;不可变存储的特点是一旦数据被写入后&#xff0c;便无法再对其进行修改或删除。这种存储方式提供…...

No mapping found for HTTP request with URI

参考: 参考地址 说明 ssm老项目,接过来别人的项目 临时建了一个Controller方便测试用的,结果访问掉不通,报: No mapping found for HTTP request with URIxxxx 这样的错误 解决办法 看了下web,xml配置 在 webmvc-config.xml 配置文件里面添加了几行配置 说明: com.iph.h…...

视频转云存的痛点

现在整个运营商体系里面&#xff0c;有大量的视频转云存储的需求&#xff0c;但是视频云存储有一个比较大的痛点&#xff0c;就是成本&#xff01; 成本一&#xff1a;存储成本&#xff1b; 我们以1000路2M视频转云存&#xff0c;存储时间为90天为例&#xff08;B端存储时间有…...

快速学制作网站/阿里指数

最近工作的事情比较忙&#xff0c;导致CLR很久没有更新了&#xff0c;恰巧周五听了涛涛的关于GC和内存管理的技术分享&#xff0c;想了下自己对CLR的学习得跟上&#xff0c;另外之前武哥推荐了一本书叫《码农翻身》&#xff0c;是一个IBM架构师写的&#xff0c;读了几页觉的非常…...

塘沽网站建设/最新舆情信息网

题意&#xff1a; 中文 思路&#xff1a; 将数插入到01字典树中并记录子树的大小和子树中所有数的位信息。 查询时在字典树中搜索前K个即可。 注意数是可以重复的 代码&#xff1a; #include <iostream> #include <cstring> #include <cstdio> using n…...

最全的网站大全/如何进行app推广

SpringBoot 内置了三种servlet 容器供大家选择&#xff0c;默认的是tomcat&#xff0c;说明它还是大众最多的选择。另外&#xff0c;也可以看出另外两种也还是有自己独有的优势。 从另一方面来说&#xff0c;SpringBoot 提供的默认配置也不一定最实用&#xff0c;对于版本的使用…...

做网站聚合做权重难吗/网页优化包括

Oracle 数据库字符集为 WE8DEC&#xff0c;报表直接从数据库中取数时&#xff0c;中文乱码。解决办法&#xff1a;可以使用报表的自定义函数或者集算器的自定义函数对中文进行转码操作。集算器中脚本&#xff1a;A3 中表达式A2.run(invoke(toWe8.toWe8,MAXDESC):MAXDESC,invoke…...

建设银行业务管理中心网站/淘宝搜索关键词技巧

本文目录英文文档float()小结英文文档lass float([x])Return a floating point number constructed from a number or string x.float()1、函数功能将一个数值或者字符转换成浮点型数值。>>> float(1) 1.0 >>> float(1) 1.02、不提供参数的时候&#xff0c;返…...

如何让网站被百度收录/百度公司推广

方式1&#xff0c;splice 1 2 3var ary [1,2,3,4]; ary.splice(0,ary.length); console.log(ary); // 输出 Array[0]&#xff0c;空数组&#xff0c;即被清空了 方式2&#xff0c;length赋值为0 这种方式很有意思&#xff0c;其它语言如Java&#xff0c;其数组的length是只读的…...