【Apollo学习笔记】——规划模块TASK之PATH_REUSE_DECIDER
文章目录
- 前言
- PATH_REUSE_DECIDER功能简介
- PATH_REUSE_DECIDER相关配置
- PATH_REUSE_DECIDER总体流程
- PATH_REUSE_DECIDER相关子函数
- IsCollisionFree
- TrimHistoryPath
- IsIgnoredBlockingObstacle和GetBlockingObstacleS
- Else
- 参考
前言
在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
本文将继续介绍LaneFollow的第二个TASK——PATH_REUSE_DECIDER
PATH_REUSE_DECIDER功能简介

主要功能:检查路径是否可重用,提高帧间平顺性。
主要逻辑:主要判断是否可以重用上一帧规划的路径。若上一帧的路径未与障碍物发生碰撞,则可以重用,提高稳定性,节省计算量。若上一帧的规划出的路径发生碰撞,则重新规划路径。
PATH_REUSE_DECIDER相关配置
PATH_REUSE_DECIDER的相关配置集中在以下两个文件:modules/planning/conf/planning_config.pb.txt和modules/planning/conf/scenario/lane_follow_config.pb.txt
// modules/planning/conf/planning_config.pb.txt
default_task_config: {task_type: PATH_REUSE_DECIDERpath_reuse_decider_config {reuse_path: false}
}
// modules/planning/conf/scenario/lane_follow_config.pb.txttask_config: {task_type: PATH_REUSE_DECIDERpath_reuse_decider_config {reuse_path: false}}
可以看到,默认情况不启用PATH_REUSE,改为true后启用。
PATH_REUSE_DECIDER总体流程

接着来看一看PATH_REUSE_DECIDER的代码逻辑。代码路径:modules/planning/tasks/deciders/path_reuse_decider/path_reuse_decider.cc
主函数逻辑集中在Process函数中:
Status PathReuseDecider::Process(Frame* const frame,ReferenceLineInfo* const reference_line_info) {// Sanity checks.CHECK_NOTNULL(frame);CHECK_NOTNULL(reference_line_info);if (!Decider::config_.path_reuse_decider_config().reuse_path()) {ADEBUG << "skipping reusing path: conf";reference_line_info->set_path_reusable(false);return Status::OK();}// skip path reuse if not in LANE_FOLLOW_SCENARIOconst auto scenario_type = injector_->planning_context()->planning_status().scenario().scenario_type();if (scenario_type != ScenarioType::LANE_FOLLOW) {ADEBUG << "skipping reusing path: not in LANE_FOLLOW scenario";reference_line_info->set_path_reusable(false);return Status::OK();}// active path reuse during change_lane onlyauto* lane_change_status = injector_->planning_context()->mutable_planning_status()->mutable_change_lane();ADEBUG << "lane change status: " << lane_change_status->ShortDebugString();// skip path reuse if not in_change_laneif (lane_change_status->status() != ChangeLaneStatus::IN_CHANGE_LANE &&!FLAGS_enable_reuse_path_in_lane_follow) {ADEBUG << "skipping reusing path: not in lane_change";reference_line_info->set_path_reusable(false);return Status::OK();}// for hybrid model: skip reuse path for valid path referenceconst bool valid_model_output =reference_line_info->path_data().is_valid_path_reference();if (valid_model_output) {ADEBUG << "skipping reusing path: path reference is valid";reference_line_info->set_path_reusable(false);return Status::OK();}/*count total_path_ when in_change_lane && reuse_path*/++total_path_counter_;/*reuse path when in non_change_lane reference line oroptimization succeeded in change_lane reference line*/bool is_change_lane_path = reference_line_info->IsChangeLanePath();if (is_change_lane_path && !lane_change_status->is_current_opt_succeed()) {reference_line_info->set_path_reusable(false);ADEBUG << "reusable_path_counter[" << reusable_path_counter_<< "] total_path_counter[" << total_path_counter_ << "]";ADEBUG << "Stop reusing path when optimization failed on change lane path";return Status::OK();}// stop reusing current path:// 1. replan path// 2. collision// 3. failed to trim previous path// 4. speed optimization failed on previous pathbool speed_optimization_successful = false;const auto& history_frame = injector_->frame_history()->Latest();if (history_frame) {const auto history_trajectory_type =history_frame->reference_line_info().front().trajectory_type();speed_optimization_successful =(history_trajectory_type != ADCTrajectory::SPEED_FALLBACK);}// const auto history_trajectory_type = injector_->FrameHistory()s// ->Latest()// ->reference_line_info()// .front()// .trajectory_type();if (path_reusable_) {if (!frame->current_frame_planned_trajectory().is_replan() &&speed_optimization_successful && IsCollisionFree(reference_line_info) &&TrimHistoryPath(frame, reference_line_info)) {ADEBUG << "reuse path";++reusable_path_counter_; // count reusable path} else {// stop reuse pathADEBUG << "stop reuse path";path_reusable_ = false;}} else {// F -> Tauto* mutable_path_decider_status = injector_->planning_context()->mutable_planning_status()->mutable_path_decider();static constexpr int kWaitCycle = -2; // wait 2 cycleconst int front_static_obstacle_cycle_counter =mutable_path_decider_status->front_static_obstacle_cycle_counter();const bool ignore_blocking_obstacle =IsIgnoredBlockingObstacle(reference_line_info);ADEBUG << "counter[" << front_static_obstacle_cycle_counter<< "] IsIgnoredBlockingObstacle[" << ignore_blocking_obstacle << "]";// stop reusing current path:// 1. blocking obstacle disappeared or moving far away// 2. trimming successful// 3. no statical obstacle collision.if ((front_static_obstacle_cycle_counter <= kWaitCycle ||ignore_blocking_obstacle) &&speed_optimization_successful && IsCollisionFree(reference_line_info) &&TrimHistoryPath(frame, reference_line_info)) {// enable reuse pathADEBUG << "reuse path: front_blocking_obstacle ignorable";path_reusable_ = true;++reusable_path_counter_;}}reference_line_info->set_path_reusable(path_reusable_);ADEBUG << "reusable_path_counter[" << reusable_path_counter_<< "] total_path_counter[" << total_path_counter_ << "]";return Status::OK();
}
PATH_REUSE_DECIDER相关子函数
IsCollisionFree

bool PathReuseDecider::IsCollisionFree(ReferenceLineInfo* const reference_line_info) {const ReferenceLine& reference_line = reference_line_info->reference_line();static constexpr double kMinObstacleArea = 1e-4;const double kSBuffer = 0.5;static constexpr int kNumExtraTailBoundPoint = 21;static constexpr double kPathBoundsDeciderResolution = 0.5;// current vehicle sl positioncommon::SLPoint adc_position_sl;GetADCSLPoint(reference_line, &adc_position_sl);// current obstaclesstd::vector<Polygon2d> obstacle_polygons;for (auto obstacle :reference_line_info->path_decision()->obstacles().Items()) {// filtered all non-static objects and virtual obstacleif (!obstacle->IsStatic() || obstacle->IsVirtual()) {if (!obstacle->IsStatic()) {ADEBUG << "SPOT a dynamic obstacle";}if (obstacle->IsVirtual()) {ADEBUG << "SPOT a virtual obstacle";}continue;}const auto& obstacle_sl = obstacle->PerceptionSLBoundary();// Ignore obstacles behind ADCif ((obstacle_sl.end_s() < adc_position_sl.s() - kSBuffer) ||// Ignore too small obstacles.(obstacle_sl.end_s() - obstacle_sl.start_s()) *(obstacle_sl.end_l() - obstacle_sl.start_l()) <kMinObstacleArea) {continue;}obstacle_polygons.push_back(Polygon2d({Vec2d(obstacle_sl.start_s(), obstacle_sl.start_l()),Vec2d(obstacle_sl.start_s(), obstacle_sl.end_l()),Vec2d(obstacle_sl.end_s(), obstacle_sl.end_l()),Vec2d(obstacle_sl.end_s(), obstacle_sl.start_l())}));}if (obstacle_polygons.empty()) {return true;}const auto& history_frame = injector_->frame_history()->Latest();if (!history_frame) {return false;}const DiscretizedPath& history_path =history_frame->current_frame_planned_path();// path end point// 将上一段轨迹的终点投影到SL坐标系下common::SLPoint path_end_position_sl;common::math::Vec2d path_end_position = {history_path.back().x(),history_path.back().y()};reference_line.XYToSL(path_end_position, &path_end_position_sl);for (size_t i = 0; i < history_path.size(); ++i) {common::SLPoint path_position_sl;common::math::Vec2d path_position = {history_path[i].x(),history_path[i].y()};reference_line.XYToSL(path_position, &path_position_sl);if (path_end_position_sl.s() - path_position_sl.s() <=kNumExtraTailBoundPoint * kPathBoundsDeciderResolution) {break;}if (path_position_sl.s() < adc_position_sl.s() - kSBuffer) {continue;}const auto& vehicle_box =common::VehicleConfigHelper::Instance()->GetBoundingBox(history_path[i]);std::vector<Vec2d> ABCDpoints = vehicle_box.GetAllCorners();for (const auto& corner_point : ABCDpoints) {// For each corner point, project it onto reference_linecommon::SLPoint curr_point_sl;if (!reference_line.XYToSL(corner_point, &curr_point_sl)) {AERROR << "Failed to get the projection from point onto ""reference_line";return false;}auto curr_point = Vec2d(curr_point_sl.s(), curr_point_sl.l());// Check if it's in any polygon of other static obstacles.for (const auto& obstacle_polygon : obstacle_polygons) {if (obstacle_polygon.IsPointIn(curr_point)) {// for debugADEBUG << "s distance to end point:" << path_end_position_sl.s();ADEBUG << "s distance to end point:" << path_position_sl.s();ADEBUG << "[" << i << "]"<< ", history_path[i].x(): " << std::setprecision(9)<< history_path[i].x() << ", history_path[i].y()"<< std::setprecision(9) << history_path[i].y();ADEBUG << "collision:" << curr_point.x() << ", " << curr_point.y();Vec2d xy_point;reference_line.SLToXY(curr_point_sl, &xy_point);ADEBUG << "collision:" << xy_point.x() << ", " << xy_point.y();return false;}}}}return true;
}
TrimHistoryPath

bool PathReuseDecider::TrimHistoryPath(Frame* frame, ReferenceLineInfo* const reference_line_info) {const ReferenceLine& reference_line = reference_line_info->reference_line();const auto& history_frame = injector_->frame_history()->Latest();if (!history_frame) {ADEBUG << "no history frame";return false;}// 找到上一帧轨迹的起始点const common::TrajectoryPoint history_planning_start_point =history_frame->PlanningStartPoint();common::PathPoint history_init_path_point =history_planning_start_point.path_point();ADEBUG << "history_init_path_point x:[" << std::setprecision(9)<< history_init_path_point.x() << "], y["<< history_init_path_point.y() << "], s: ["<< history_init_path_point.s() << "]";// 当前周期规划的起点const common::TrajectoryPoint planning_start_point =frame->PlanningStartPoint();common::PathPoint init_path_point = planning_start_point.path_point();ADEBUG << "init_path_point x:[" << std::setprecision(9) << init_path_point.x()<< "], y[" << init_path_point.y() << "], s: [" << init_path_point.s()<< "]";const DiscretizedPath& history_path =history_frame->current_frame_planned_path();DiscretizedPath trimmed_path;// 获取自车的SL坐标common::SLPoint adc_position_sl; // current vehicle sl positionGetADCSLPoint(reference_line, &adc_position_sl);ADEBUG << "adc_position_sl.s(): " << adc_position_sl.s();size_t path_start_index = 0;for (size_t i = 0; i < history_path.size(); ++i) {// find previous init point// 找到上周期轨迹规划的起点索引if (history_path[i].s() > 0) {path_start_index = i;break;}}ADEBUG << "!!!path_start_index[" << path_start_index << "]";// get current s=0common::SLPoint init_path_position_sl;// 当前轨迹的起点reference_line.XYToSL(init_path_point, &init_path_position_sl);bool inserted_init_point = false;//匹配当前规划起点位置,裁剪该点之后的轨迹for (size_t i = path_start_index; i < history_path.size(); ++i) {common::SLPoint path_position_sl;common::math::Vec2d path_position = {history_path[i].x(),history_path[i].y()};reference_line.XYToSL(path_position, &path_position_sl);double updated_s = path_position_sl.s() - init_path_position_sl.s();// insert init pointif (updated_s > 0 && !inserted_init_point) {trimmed_path.emplace_back(init_path_point);trimmed_path.back().set_s(0);inserted_init_point = true;}trimmed_path.emplace_back(history_path[i]);// if (i < 50) {// ADEBUG << "path_point:[" << i << "]" << updated_s;// path_position_sl.s();// ADEBUG << std::setprecision(9) << "path_point:[" << i << "]"// << "x: [" << history_path[i].x() << "], y:[" <<// history_path[i].y()// << "]. s[" << history_path[i].s() << "]";// }trimmed_path.back().set_s(updated_s);}ADEBUG << "trimmed_path[0]: " << trimmed_path.front().s();ADEBUG << "[END] trimmed_path.size(): " << trimmed_path.size();// 检查裁剪出来的轨迹是不是过短if (!NotShortPath(trimmed_path)) {ADEBUG << "short path: " << trimmed_path.size();return false;}// set pathauto path_data = reference_line_info->mutable_path_data();ADEBUG << "previous path_data size: " << history_path.size();path_data->SetReferenceLine(&reference_line);ADEBUG << "previous path_data size: " << path_data->discretized_path().size();path_data->SetDiscretizedPath(DiscretizedPath(std::move(trimmed_path)));ADEBUG << "not short path: " << trimmed_path.size();ADEBUG << "current path size: "<< reference_line_info->path_data().discretized_path().size();return true;
}
IsIgnoredBlockingObstacle和GetBlockingObstacleS
前方堵塞的障碍物是否离开足够远的距离
bool PathReuseDecider::IsIgnoredBlockingObstacle(ReferenceLineInfo* const reference_line_info) {const ReferenceLine& reference_line = reference_line_info->reference_line();static constexpr double kSDistBuffer = 30.0; // meterstatic constexpr int kTimeBuffer = 3; // second// vehicle speeddouble adc_speed = injector_->vehicle_state()->linear_velocity();double final_s_buffer = std::max(kSDistBuffer, kTimeBuffer * adc_speed);// current vehicle s positioncommon::SLPoint adc_position_sl;GetADCSLPoint(reference_line, &adc_position_sl);// blocking obstacle start sdouble blocking_obstacle_start_s;if (GetBlockingObstacleS(reference_line_info, &blocking_obstacle_start_s) &&// distance to blocking obstacle(blocking_obstacle_start_s - adc_position_sl.s() > final_s_buffer)) {ADEBUG << "blocking obstacle distance: "<< blocking_obstacle_start_s - adc_position_sl.s();return true;} else {return false;}
}
bool PathReuseDecider::GetBlockingObstacleS(ReferenceLineInfo* const reference_line_info, double* blocking_obstacle_s) {auto* mutable_path_decider_status = injector_->planning_context()->mutable_planning_status()->mutable_path_decider();// get blocking obstacle ID (front_static_obstacle_id)const std::string& blocking_obstacle_ID =mutable_path_decider_status->front_static_obstacle_id();const IndexedList<std::string, Obstacle>& indexed_obstacles =reference_line_info->path_decision()->obstacles();const auto* blocking_obstacle = indexed_obstacles.Find(blocking_obstacle_ID);if (blocking_obstacle == nullptr) {return false;}const auto& obstacle_sl = blocking_obstacle->PerceptionSLBoundary();*blocking_obstacle_s = obstacle_sl.start_s();ADEBUG << "blocking obstacle distance: " << obstacle_sl.start_s();return true;
}
Else
在启用reuse之后,之后的task会有这样一段代码,用以跳过以下流程,沿用之前的path
// skip path_lane_borrow_decider if reused pathif (FLAGS_enable_skip_path_tasks && reference_line_info->path_reusable()) {// for debugAINFO << "skip due to reusing path";return Status::OK();}
参考
[1] Apollo Planning决策规划代码详细解析 (7): PathReuseDecider
[2] Apollo6.0 PathReuseDecider流程与代码解析
相关文章:
【Apollo学习笔记】——规划模块TASK之PATH_REUSE_DECIDER
文章目录 前言PATH_REUSE_DECIDER功能简介PATH_REUSE_DECIDER相关配置PATH_REUSE_DECIDER总体流程PATH_REUSE_DECIDER相关子函数IsCollisionFreeTrimHistoryPathIsIgnoredBlockingObstacle和GetBlockingObstacleS Else参考 前言 在Apollo星火计划学习笔记——Apollo路径规划算…...
框架分析(6)-Ruby on Rails
框架分析(6)-Ruby on Rails 专栏介绍Ruby on Rails核心概念以及组件讲解MVC架构模式约定优于配置强大的ORM支持自动化测试丰富的插件生态系统RESTful路由安全性总结 优缺点优点快速开发简单易学MVC架构强大的ORM支持大量的插件和Gem支持 缺点性能问题学习…...
LLMs NLP模型评估Model evaluation ROUGE and BLEU SCORE
在整个课程中,你看到过类似模型在这个任务上表现良好,或者这个微调模型在性能上相对于基础模型有显著提升等陈述。 这些陈述是什么意思?如何形式化你的微调模型在你起初的预训练模型上的性能改进?让我们探讨一些由大型语言模型开…...
BlazorServer中C#与JavaScript的相互调用
BlazorServer中C#与JavaScript的相互调用 前言: 虽然BlazorServer中推荐使用C#在razor页面中的替代JavaScript来完成逻辑的编写,但当需要使用第三方的javascript文件/组件里的内容时,则难免要在C#中调用其方法或对象。反之当你的(用到第…...
深入理解 MD5 消息摘要算法和在密码存储中的应用及安全隐患
MD5 算法相信很多开发人员都听说过, 一个最常见的使用到它的地方就是密码的存储. 当然, 很多人会说, 这个算法已经不太安全了, 确实如果你想更安全的保存密码, 则应该考虑其它更安全的算法, 不过这不属于此次讨论的主题. 什么是 MD5 MD5 是一种算法, MD5 中的 MD 代表 Message…...
python网络爬虫指南二:多线程网络爬虫、动态内容爬取(待续)
文章目录 一、多线程网络爬虫1.1 线程的基础内容、GIL1.2 创建线程的两种方式1.3 threading.Thread类1.4 线程常用方法和锁机制1.5 生产者-消费者模式1.5.1 生产者-消费者模式简介1.5.2 Condition 类协调线程 1.6 线程中的安全队列1.6 多线程爬取王者荣耀壁纸1.6.1 网页分析1.6…...
华为AirEgine9700S AC配置示例
Vlan97为管理Vlan <AirEgine9700S>dis cu Software Version V200R021C00SPC100 #sysname AirEgine9700S #http timeout 60http secure-server ssl-policy default_policyhttp secure-server server-source -i allhttp server enable #set np rss hash-mode 5-tuple # md…...
VUE3基础
一、vue-router v4.x 介绍 | Vue Router 1、安装 yarn add vue-routernext next代表最新的版本 2、路由配置 在src目录下,新建router/index.ts,具体配置如下 import {RouteRecordRaw,createRouter,createWebHashHistory} from vue-router const r…...
Qt应用开发(基础篇)——日历 QCalendarWidget
一、前言 QCalendarWidget类继承于QWidget,是Qt设计用来让用户更直观的选择日期的窗口部件。 时间微调输入框 QCalendarWidget根据年份和月份初始化,程序员也通过提供公共函数去改变他们,默认日期为当前的系统时间,用户通过鼠标和…...
Python学习笔记:正则表达式、逻辑运算符、lamda、二叉树遍历规则、类的判断
1.正则表达式如何写? 序号实例说明1.匹配任何字符(除换行符以外)2\d等效于[0-9],匹配数字3\D等效于[^0-9],匹配非数字4\s等效于[\t\r\n\f],匹配空格字符5\S等效于[^\t\r\n\f],匹配非空格字符6\w等效于[A-Za-z0-9]&…...
【滑动窗口】leetcode1004:最大连续1的个数
一.题目描述 最大连续1的个数 这道题要我们找最大连续1的个数,看到“连续”二字,我们要想到滑动窗口的方法。滑动窗口的研究对象是一个连续的区间,这个区间需要满足某个条件。那么本题要找的是怎样的区间呢?是一个通过翻转0后得到…...
力扣:73. 矩阵置零(Python3)
题目: 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 来源:力扣(LeetCode) 链接:力扣(LeetCode)官网 - 全球极客挚…...
VB|基础语法 变量定义 函数定义 循环语句 IF判断语句等
文章目录 变量定义函数定义控制台输入输出switch case语句IF语句FOR循环语句不等于逻辑运算符 变量定义 int Dim 变量名 As Int32 0 string Dim 变量名 As String "" bool Dim 变量名 As Boolean False 枚举 Dim 变量名 As 枚举名 数组 Dim array(256) As String…...
Github 博客搭建
Github 博客搭建 准备工作 准备一个 github 账号;建立 github 仓库,仓库名为 username.github.io,同时设置仓库为 public;clone 仓库,写入一个 index.html 文件,推送到仓库(许多网上的教程会有…...
模型预测笔记(三):通过交叉验证网格搜索机器学习的最优参数
文章目录 网络搜索介绍步骤参数代码实现 网络搜索 介绍 网格搜索(Grid Search)是一种超参数优化方法,用于选择最佳的模型超参数组合。在机器学习中,超参数是在训练模型之前设置的参数,无法通过模型学习得到。网格搜索…...
创建型模式-建造者模式
使用多个简单的对象一步一步构建成一个复杂的对象 主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部…...
Rust常用加密算法
哈希运算(以Sha256为例) main.rs: use crypto::digest::Digest;use crypto::sha2::Sha256;fn main() { let input "dashen"; let mut sha Sha256::new(); sha.input_str(input); println!("{}", sha.result_str());} Cargo.toml: [package]n…...
[管理与领导-55]:IT基层管理者 - 扩展技能 - 1 - 时间管理 -2- 自律与自身作则,管理者管好自己时间的五步法
前言: 管理好自己的时间,不仅仅是理念,也是方法和流程。 步骤1:理清各种待办事项 当提到工作事项时,这通常指的是要完成或处理的工作任务或事务。这些事项可以包括以下内容: 任务分配:根据工作…...
电子商务员考试题库及答案(中级)--判断题
电子商务员题库 一、判断题 1.EDI就是按照商定的协议,将商业文件分类,并通过计算机网络,在贸易伙伴的计算机网络系统之间进行数据交换和自动处理。〔〕 2.相互通信的EDI的用户必须使用相同类型的计算机。〔 〕 3.EDI采用共同…...
(WAF)Web应用程序防火墙介绍
(WAF)Web应用程序防火墙介绍 1. WAF概述 Web应用程序防火墙(WAF)是一种关键的网络安全解决方案,用于保护Web应用程序免受各种网络攻击和威胁。随着互联网的不断发展,Web应用程序变得越来越复杂&#x…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
