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

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

文章目录

  • 前言
  • RULE_BASED_STOP_DECIDER相关配置
  • RULE_BASED_STOP_DECIDER总体流程
    • StopOnSidePass
      • CheckClearDone
      • CheckSidePassStop
      • IsPerceptionBlocked
      • IsClearToChangeLane
      • CheckSidePassStop
      • BuildStopDecision
      • ELSE:涉及到的一些其他函数
        • NormalizeAngle
        • SelfRotate
    • CheckLaneChangeUrgency
    • AddPathEndStop
  • 参考

前言

在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的第8个TASK——RULE_BASED_STOP_DECIDER

基于规则的停止决策是规划模块的任务,属于task中的decider类别。基于规则的停止决策根据一些规则来设置停止标志。

RULE_BASED_STOP_DECIDER相关配置

modules/planning/conf/planning_config.pb.txt

default_task_config: {task_type: RULE_BASED_STOP_DECIDERrule_based_stop_decider_config {max_adc_stop_speed: 0.5max_valid_stop_distance: 1.0search_beam_length: 20.0search_beam_radius_intensity: 0.08search_range: 3.14is_block_angle_threshold: 0.5}
}

modules/planning/proto/task_config.proto

// RuleBasedStopDeciderConfigmessage RuleBasedStopDeciderConfig {optional double max_adc_stop_speed = 1 [default = 0.3];optional double max_valid_stop_distance = 2 [default = 0.5];optional double search_beam_length = 3 [default = 5.0];optional double search_beam_radius_intensity = 4 [default = 0.08];optional double search_range = 5 [default = 3.14];optional double is_block_angle_threshold = 6 [default = 1.57];optional double approach_distance_for_lane_change = 10 [default = 80.0];optional double urgent_distance_for_lane_change = 11 [default = 50.0];
}

RULE_BASED_STOP_DECIDER总体流程

在这里插入图片描述

  • 输入
    apollo::common::Status RuleBasedStopDecider::Process(Frame *const frame, ReferenceLineInfo *const reference_line_info)
    输入是frame和reference_line_info。

  • 输出
    输出保存到reference_line_info中。

代码流程及框架
Process中的代码流程如下图所示。

在这里插入图片描述

apollo::common::Status RuleBasedStopDecider::Process(Frame *const frame, ReferenceLineInfo *const reference_line_info) {// 1. Rule_based stop for side pass onto reverse laneStopOnSidePass(frame, reference_line_info);// 2. Rule_based stop for urgent lane changeif (FLAGS_enable_lane_change_urgency_checking) {CheckLaneChangeUrgency(frame);}// 3. Rule_based stop at path end positionAddPathEndStop(frame, reference_line_info);return Status::OK();
}

主要核心的函数就是StopOnSidePassCheckLaneChangeUrgency以及AddPathEndStop,接着分别对三者进行剖析。

StopOnSidePass

在这里插入图片描述
在这里插入图片描述

void RuleBasedStopDecider::StopOnSidePass(Frame *const frame, ReferenceLineInfo *const reference_line_info) {static bool check_clear;// 默认falsestatic common::PathPoint change_lane_stop_path_point;// 获取path dataconst PathData &path_data = reference_line_info->path_data();double stop_s_on_pathdata = 0.0;// 找到"self"类型的路径,returnif (path_data.path_label().find("self") != std::string::npos) {check_clear = false;change_lane_stop_path_point.Clear();return;}// CheckClearDone:Check if needed to check clear again for side pass// 如果check_clear为true,且CheckClearDone成功。设置check_clear为falseif (check_clear &&CheckClearDone(*reference_line_info, change_lane_stop_path_point)) {check_clear = false;}// CheckSidePassStop:Check if necessary to set stop fence used for nonscenario side pass// 如果check_clear为false,CheckSidePassStop为trueif (!check_clear &&CheckSidePassStop(path_data, *reference_line_info, &stop_s_on_pathdata)) {// 如果障碍物没有阻塞且可以换道,直接returnif (!LaneChangeDecider::IsPerceptionBlocked(*reference_line_info,rule_based_stop_decider_config_.search_beam_length(),rule_based_stop_decider_config_.search_beam_radius_intensity(),rule_based_stop_decider_config_.search_range(),rule_based_stop_decider_config_.is_block_angle_threshold()) &&LaneChangeDecider::IsClearToChangeLane(reference_line_info)) {return;}// 检查adc是否停在了stop fence前,否返回trueif (!CheckADCStop(path_data, *reference_line_info, stop_s_on_pathdata)) {// 设置stop fence,成功就执行 check_clear = true;if (!BuildSidePassStopFence(path_data, stop_s_on_pathdata,&change_lane_stop_path_point, frame,reference_line_info)) {AERROR << "Set side pass stop fail";}} else {if (LaneChangeDecider::IsClearToChangeLane(reference_line_info)) {check_clear = true;}}}
}

CheckClearDone

// Check if needed to check clear again for side pass
bool RuleBasedStopDecider::CheckClearDone(const ReferenceLineInfo &reference_line_info,const common::PathPoint &stop_point) {// 获取ADC的SL坐标const double adc_front_edge_s = reference_line_info.AdcSlBoundary().end_s();const double adc_back_edge_s = reference_line_info.AdcSlBoundary().start_s();const double adc_start_l = reference_line_info.AdcSlBoundary().start_l();const double adc_end_l = reference_line_info.AdcSlBoundary().end_l();double lane_left_width = 0.0;double lane_right_width = 0.0;reference_line_info.reference_line().GetLaneWidth((adc_front_edge_s + adc_back_edge_s) / 2.0, &lane_left_width,&lane_right_width);SLPoint stop_sl_point;// 获取停止点的SL坐标reference_line_info.reference_line().XYToSL(stop_point, &stop_sl_point);// use distance to last stop point to determine if needed to check clear// againif (adc_back_edge_s > stop_sl_point.s()) {if (adc_start_l > -lane_right_width || adc_end_l < lane_left_width) {return true;}}return false;
}

CheckSidePassStop

// @brief Check if necessary to set stop fence used for nonscenario side pass
bool RuleBasedStopDecider::CheckSidePassStop(const PathData &path_data, const ReferenceLineInfo &reference_line_info,double *stop_s_on_pathdata) {const std::vector<std::tuple<double, PathData::PathPointType, double>>&path_point_decision_guide = path_data.path_point_decision_guide();// 初始化类型PathData::PathPointType last_path_point_type =PathData::PathPointType::UNKNOWN;// 遍历 path_point_decision_guidefor (const auto &point_guide : path_point_decision_guide) {// 若上一点在车道内,这一点在逆行车道上if (last_path_point_type == PathData::PathPointType::IN_LANE &&std::get<1>(point_guide) ==PathData::PathPointType::OUT_ON_REVERSE_LANE) {*stop_s_on_pathdata = std::get<0>(point_guide);// Approximate the stop fence s based on the vehicle positionconst auto &vehicle_config =common::VehicleConfigHelper::Instance()->GetConfig();const double ego_front_to_center =vehicle_config.vehicle_param().front_edge_to_center();common::PathPoint stop_pathpoint;// 获取stop pointif (!path_data.GetPathPointWithRefS(*stop_s_on_pathdata,&stop_pathpoint)) {AERROR << "Can't get stop point on path data";return false;}const double ego_theta = stop_pathpoint.theta();Vec2d shift_vec{ego_front_to_center * std::cos(ego_theta),ego_front_to_center * std::sin(ego_theta)};// stop_fence的位置const Vec2d stop_fence_pose =shift_vec + Vec2d(stop_pathpoint.x(), stop_pathpoint.y());double stop_l_on_pathdata = 0.0;const auto &nearby_path = reference_line_info.reference_line().map_path();nearby_path.GetNearestPoint(stop_fence_pose, stop_s_on_pathdata,&stop_l_on_pathdata);return true;}last_path_point_type = std::get<1>(point_guide);}return false;
}

IsPerceptionBlocked

参数解释:

search_beam_length 扫描长度
search_beam_radius_intensity 扫描间隔
search_range 依据ADC中心的扫描范围
is_block_angle_threshold 筛选障碍物所占角度大小的阈值

bool LaneChangeDecider::IsPerceptionBlocked(const ReferenceLineInfo& reference_line_info,const double search_beam_length, const double search_beam_radius_intensity,const double search_range, const double is_block_angle_threshold) {// search_beam_length: 20.0 //is the length of scanning beam// search_beam_radius_intensity: 0.08 //is the resolution of scanning// search_range: 3.14 	//is the scanning range centering at ADV heading// is_block_angle_threshold: 0.5 //is the threshold to tell how big a block angle range is perception blocking// 获取车辆状态、位置、航向角const auto& vehicle_state = reference_line_info.vehicle_state();const common::math::Vec2d adv_pos(vehicle_state.x(), vehicle_state.y());const double adv_heading = vehicle_state.heading();// 遍历障碍物for (auto* obstacle :reference_line_info.path_decision().obstacles().Items()) {// NormalizeAngle将给定的角度值规范化到一个特定的范围内(-π到π之间)double left_most_angle =common::math::NormalizeAngle(adv_heading + 0.5 * search_range);double right_most_angle =common::math::NormalizeAngle(adv_heading - 0.5 * search_range);bool right_most_found = false;// 跳过虚拟障碍物if (obstacle->IsVirtual()) {ADEBUG << "skip one virtual obstacle";continue;}// 获取障碍物多边形const auto& obstacle_polygon = obstacle->PerceptionPolygon();// 按角度进行搜索for (double search_angle = 0.0; search_angle < search_range;search_angle += search_beam_radius_intensity) {common::math::Vec2d search_beam_end(search_beam_length, 0.0);const double beam_heading = common::math::NormalizeAngle(adv_heading - 0.5 * search_range + search_angle);// search_beam_end绕adv_pos旋转beam_heading角度search_beam_end.SelfRotate(beam_heading);search_beam_end += adv_pos;// 构造线段common::math::LineSegment2d search_beam(adv_pos, search_beam_end);// 判断最右边界是否找到,并更新右边界角度if (!right_most_found && obstacle_polygon.HasOverlap(search_beam)) {right_most_found = true;right_most_angle = beam_heading;}// 如果最右边界已找到,且障碍物的感知多边形与搜索光束无重叠,则更新左边界角度并跳出循环。if (right_most_found && !obstacle_polygon.HasOverlap(search_beam)) {left_most_angle = beam_heading;break;}}// 如果最右边界未找到,则继续处理下一个障碍物。(说明该障碍物不在搜索范围内)if (!right_most_found) {// obstacle is not in search rangecontinue;}// 判断阈值,过滤掉小的障碍物if (std::fabs(common::math::NormalizeAngle(left_most_angle - right_most_angle)) > is_block_angle_threshold) {return true;}}return false;
}

IsClearToChangeLane

这个在【Apollo学习笔记】——规划模块TASK之LANE_CHANGE_DECIDER已经有过介绍。

CheckSidePassStop

// @brief Check if necessary to set stop fence used for nonscenario side pass
bool RuleBasedStopDecider::CheckSidePassStop(const PathData &path_data, const ReferenceLineInfo &reference_line_info,double *stop_s_on_pathdata) {const std::vector<std::tuple<double, PathData::PathPointType, double>>&path_point_decision_guide = path_data.path_point_decision_guide();// 初始化类型PathData::PathPointType last_path_point_type =PathData::PathPointType::UNKNOWN;// 遍历 path_point_decision_guidefor (const auto &point_guide : path_point_decision_guide) {// 若上一点在车道内,这一点在逆行车道上if (last_path_point_type == PathData::PathPointType::IN_LANE &&std::get<1>(point_guide) ==PathData::PathPointType::OUT_ON_REVERSE_LANE) {*stop_s_on_pathdata = std::get<0>(point_guide);// Approximate the stop fence s based on the vehicle positionconst auto &vehicle_config =common::VehicleConfigHelper::Instance()->GetConfig();const double ego_front_to_center =vehicle_config.vehicle_param().front_edge_to_center();common::PathPoint stop_pathpoint;// 获取stop pointif (!path_data.GetPathPointWithRefS(*stop_s_on_pathdata,&stop_pathpoint)) {AERROR << "Can't get stop point on path data";return false;}const double ego_theta = stop_pathpoint.theta();Vec2d shift_vec{ego_front_to_center * std::cos(ego_theta),ego_front_to_center * std::sin(ego_theta)};// stop_fence的位置const Vec2d stop_fence_pose =shift_vec + Vec2d(stop_pathpoint.x(), stop_pathpoint.y());double stop_l_on_pathdata = 0.0;const auto &nearby_path = reference_line_info.reference_line().map_path();nearby_path.GetNearestPoint(stop_fence_pose, stop_s_on_pathdata,&stop_l_on_pathdata);return true;}last_path_point_type = std::get<1>(point_guide);}return false;
}

BuildStopDecision

/** @brief: build virtual obstacle of stop wall, and add STOP decision*/
int BuildStopDecision(const std::string& stop_wall_id, const double stop_line_s,const double stop_distance,const StopReasonCode& stop_reason_code,const std::vector<std::string>& wait_for_obstacles,const std::string& decision_tag, Frame* const frame,ReferenceLineInfo* const reference_line_info) {CHECK_NOTNULL(frame);CHECK_NOTNULL(reference_line_info);// 检查停止线是否在参考线上const auto& reference_line = reference_line_info->reference_line();if (!WithinBound(0.0, reference_line.Length(), stop_line_s)) {AERROR << "stop_line_s[" << stop_line_s << "] is not on reference line";return 0;}// create virtual stop wallconst auto* obstacle =frame->CreateStopObstacle(reference_line_info, stop_wall_id, stop_line_s);if (!obstacle) {AERROR << "Failed to create obstacle [" << stop_wall_id << "]";return -1;}const Obstacle* stop_wall = reference_line_info->AddObstacle(obstacle);if (!stop_wall) {AERROR << "Failed to add obstacle[" << stop_wall_id << "]";return -1;}// build stop decisionconst double stop_s = stop_line_s - stop_distance;const auto& stop_point = reference_line.GetReferencePoint(stop_s);const double stop_heading =reference_line.GetReferencePoint(stop_s).heading();ObjectDecisionType stop;auto* stop_decision = stop.mutable_stop();stop_decision->set_reason_code(stop_reason_code);stop_decision->set_distance_s(-stop_distance);stop_decision->set_stop_heading(stop_heading);stop_decision->mutable_stop_point()->set_x(stop_point.x());stop_decision->mutable_stop_point()->set_y(stop_point.y());stop_decision->mutable_stop_point()->set_z(0.0);for (size_t i = 0; i < wait_for_obstacles.size(); ++i) {stop_decision->add_wait_for_obstacle(wait_for_obstacles[i]);}auto* path_decision = reference_line_info->path_decision();path_decision->AddLongitudinalDecision(decision_tag, stop_wall->Id(), stop);return 0;
}

ELSE:涉及到的一些其他函数

NormalizeAngle

NormalizeAngle将给定的角度值规范化到一个特定的范围内(-π到π之间)

double NormalizeAngle(const double angle) {double a = std::fmod(angle + M_PI, 2.0 * M_PI);if (a < 0.0) {a += (2.0 * M_PI);}return a - M_PI;
}

SelfRotate

将向量绕原点旋转 a n g l e angle angle角。

void Vec2d::SelfRotate(const double angle) {double tmp_x = x_;x_ = x_ * cos(angle) - y_ * sin(angle);y_ = tmp_x * sin(angle) + y_ * cos(angle);
}

CheckLaneChangeUrgency

检查紧急换道,当FLAGS_enable_lane_change_urgency_checking为true时,启用函数。
在这里插入图片描述在这里插入图片描述

void RuleBasedStopDecider::CheckLaneChangeUrgency(Frame *const frame) {// 直接进入循环,检查每个reference_line_infofor (auto &reference_line_info : *frame->mutable_reference_line_info()) {// Check if the target lane is blocked or not// 1. 检查目标道路是否阻塞,如果在change lane path上,就跳过if (reference_line_info.IsChangeLanePath()) {is_clear_to_change_lane_ =LaneChangeDecider::IsClearToChangeLane(&reference_line_info);is_change_lane_planning_succeed_ =reference_line_info.Cost() < kStraightForwardLineCost;continue;}// If it's not in lane-change scenario || (target lane is not blocked &&// change lane planning succeed), skip// 2.如果不是换道的场景,或者(目标lane没有阻塞)并且换道规划成功,跳过if (frame->reference_line_info().size() <= 1 ||(is_clear_to_change_lane_ && is_change_lane_planning_succeed_)) {continue;}// When the target lane is blocked in change-lane case, check the urgency// Get the end point of current routingconst auto &route_end_waypoint =reference_line_info.Lanes().RouteEndWaypoint();// If can't get lane from the route's end waypoint, then skip// 3.在route的末端无法获得lane,跳过if (!route_end_waypoint.lane) {continue;}auto point = route_end_waypoint.lane->GetSmoothPoint(route_end_waypoint.s);auto *reference_line = reference_line_info.mutable_reference_line();common::SLPoint sl_point;// Project the end point to sl_point on current reference lane// 将当前参考线的点映射到frenet坐标系下if (reference_line->XYToSL(point, &sl_point) &&reference_line->IsOnLane(sl_point)) {// Check the distance from ADC to the end point of current routingdouble distance_to_passage_end =sl_point.s() - reference_line_info.AdcSlBoundary().end_s();// If ADC is still far from the end of routing, no need to stop, skip// 4. 如果adc距离routing终点较远,不需要停止,跳过if (distance_to_passage_end >rule_based_stop_decider_config_.approach_distance_for_lane_change()) {continue;}// In urgent case, set a temporary stop fence and wait to change lane// TODO(Jiaxuan Xu): replace the stop fence to more intelligent actions// 5.如果遇到紧急情况,设置临时的stop fence,等待换道const std::string stop_wall_id = "lane_change_stop";std::vector<std::string> wait_for_obstacles;util::BuildStopDecision(stop_wall_id, sl_point.s(),rule_based_stop_decider_config_.urgent_distance_for_lane_change(),StopReasonCode::STOP_REASON_LANE_CHANGE_URGENCY, wait_for_obstacles,"RuleBasedStopDecider", frame, &reference_line_info);}}
}

AddPathEndStop

在这里插入图片描述

void RuleBasedStopDecider::AddPathEndStop(Frame *const frame, ReferenceLineInfo *const reference_line_info) {// 路径不为空且起点到终点的距离不小于20mif (!reference_line_info->path_data().path_label().empty() &&reference_line_info->path_data().frenet_frame_path().back().s() -reference_line_info->path_data().frenet_frame_path().front().s() <FLAGS_short_path_length_threshold) { // FLAGS_short_path_length_threshold: Threshold for too short path length(20m)// 创建虚拟墙的IDconst std::string stop_wall_id =PATH_END_VO_ID_PREFIX + reference_line_info->path_data().path_label();std::vector<std::string> wait_for_obstacles;// 创建stop fenceutil::BuildStopDecision(stop_wall_id,reference_line_info->path_data().frenet_frame_path().back().s() - 5.0,0.0, StopReasonCode::STOP_REASON_REFERENCE_END, wait_for_obstacles,"RuleBasedStopDecider", frame, reference_line_info);}
}

参考

[1] 基于规则的停止决策

相关文章:

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

文章目录 前言RULE_BASED_STOP_DECIDER相关配置RULE_BASED_STOP_DECIDER总体流程StopOnSidePassCheckClearDoneCheckSidePassStopIsPerceptionBlockedIsClearToChangeLaneCheckSidePassStopBuildStopDecisionELSE:涉及到的一些其他函数NormalizeAngleSelfRotate CheckLaneChang…...

【SpringBoot】最基础的项目架构(SpringBoot+Mybatis-plus+lombok+knife4j+hutool)

汝之观览&#xff0c;吾之幸也&#xff01; 从本文开始讲下项目中用到的一些框架和技术&#xff0c;最基本的框架使用的是SpringBoot(2.5.10)Mybatis-plus(3.5.3.2)lombok(1.18.28)knife4j(3.0.3)hutool(5.8.21),可以做到代码自动生成&#xff0c;满足最基本的增删查改。 一、新…...

RNN 单元:分析 GRU 方程与 LSTM,以及何时选择 RNN 而不是变压器

一、说明 深度学习往往感觉像是在雪山上找到自己的道路。拥有坚实的原则会让你对做出决定更有信心。我们都去过那里 在上一篇文章中&#xff0c;我们彻底介绍并检查了 LSTM 单元的各个方面。有人可能会争辩说&#xff0c;RNN方法已经过时了&#xff0c;研究它们是没有意义的。的…...

Linux音频了解

ALPHA I.MX6U 开发板支持音频&#xff0c;板上搭载了音频编解码芯片 WM8960&#xff0c;支持播放以及录音功能&#xff01; 本章将会讨论如下主题内容。 ⚫ Linux 下 ALSA 框架概述&#xff1b; ⚫ alsa-lib 库介绍&#xff1b; ⚫ alsa-lib 库移植&#xff1b; ⚫ alsa-l…...

精心整理了优秀的GitHub开源项目,包含前端、后端、AI人工智能、游戏、黑客工具、网络工具、AI医疗等等,空闲的时候方便看看提高自己的视野

精心整理了优秀的GitHub开源项目&#xff0c;包含前端、后端、AI人工智能、游戏、黑客工具、网络工具、AI医疗等等&#xff0c;空闲的时候方便看看提高自己的视野。 刚开源就变成新星的 igl&#xff0c;不仅获得了 2k star&#xff0c;也能提高你开发游戏的效率&#xff0c;摆…...

Leetcode54螺旋矩阵

思路&#xff1a;用set记录走过的地方&#xff0c;记下走的方向&#xff0c;根据方向碰壁变换 class Solution:def spiralOrder(self, matrix: list[list[int]]) -> list[int]:max_rows len(matrix)max_cols len(matrix[0])block_nums max_cols * max_rowscount 1i 0j…...

element-plus 表格-方法、事件、属性的使用

记录element-plus 表格的使用。方法、事件、属性的使用。因为是vue3的方式用到了const install getCurrentInstance();才能获取表格的相关信息 没解决怎么获取选中的行的行号&#xff0c;采用自己记的方式实习的。 利用row-class-name"setRowClass"实现样式的简单…...

NVME Linux的查询命令-继续更新

NVME Linux的查询命令 查看NVMe设备 # nvme list 查看nvme controller 支持的一些特性 # nvme id-ctrl /dev/nvme0 查看设备smart log信息 # nvme smart-log /dev/nvme0 查看设备error 信息 # nvme error-log /dev/nvme0 设备的所有命名空间 # nvme list-ns /dev/nvmeX 检…...

pyqt5-自定义文本域1

快捷键支持&#xff1a; CTRL鼠标滚轮实现字体大小调整 支持复制当前行 剪切当前行 # 多行文本框 class TextEdit(QTextEdit):def __init__(self, parentNone):super().__init__(parent)self.setStyleSheet("background-color: #262626;color: #d0d0d0;")self.setFon…...

Go实现LogCollect:海量日志收集系统【上篇——LogAgent实现】

Go实现LogCollect&#xff1a;海量日志收集系统【上篇——LogAgent实现】 下篇&#xff1a;Go实现LogCollect&#xff1a;海量日志收集系统【下篇——开发LogTransfer】 项目架构图&#xff1a; 0 项目背景与方案选择 背景 当公司发展的越来越大&#xff0c;业务越来越复杂…...

MySQL (1)

目录 操作须知 数据类型 1 DDL 1.1 操作库 1.2 操作表 1.3 操作字段(ALTER TABLE 表名) 2 DML 3 DQL(见下章) 操作须知 ※ MySQL在windows环境不区分大小写,但在Linux环境严格区分大小写 ※ 不同的数据库可能存在同名的表,可以给表前加"数据库前缀" //例:…...

MR混合现实汽车维修情景实训教学演示

MR混合现实技术应用于汽车维修课堂中&#xff0c;能够赋予学生更加真实&#xff0c;逼真地学习环境&#xff0c;让学生在情景体验中不断提高自己的专业能力。 MR混合现实汽车维修情景实训教学演示具体体现在&#xff1a; 1. 虚拟维修指导&#xff1a;利用MR技术&#xff0c;可…...

ChatGPT在航空航天工程和太空探索中的潜在应用如何?

ChatGPT在航空航天工程和太空探索领域具有广泛的潜在应用。这些应用可以涵盖从设计和模拟到任务控制和数据分析的多个方面。本文将探讨ChatGPT在航空航天和太空探索中的各种可能应用&#xff0c;包括设计优化、任务规划、智能导航、卫星通信、数据分析和太空探测器运行。 ### …...

算法基础第三章

算法基础第三章 1、dfs(深度搜索)1.1、 递归回溯1.2、递归剪枝&#xff08;剪枝就是判断接下来的递归都不会满足条件&#xff0c;直接回溯&#xff0c;不再继续往下无意义的递归&#xff09; 2、bfs(广度搜索)2.1、最优路径&#xff08;只适合于边权都相等的题&#xff09; 3、…...

ElementUI浅尝辄止20:Pagination 分页

分页组件常见于管理系统的列表查询页面&#xff0c;数据量巨大时需要分页的操作。 当数据量过多时&#xff0c;使用分页分解数据。 1.如何使用&#xff1f; /*设置layout&#xff0c;表示需要显示的内容&#xff0c;用逗号分隔&#xff0c;布局元素会依次显示。prev表示上一页…...

Docker从认识到实践再到底层原理(二-1)|容器技术发展史+虚拟化容器概念和简介

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…...

什么是大模型?1750亿、700GB的GPT大模型大在哪?

文章目录 什么是大模型&#xff1f;1750亿、700GB的GPT大模型大在哪&#xff1f; 什么是大模型&#xff1f; 在人工智能领域&#xff0c;模型是指一种对数据进行处理和分析的数学结构。模型越复杂&#xff0c;能够处理的数据量和处理的准确性都会得到提高。 随着人工智能技术…...

剑指 Offer 10- II. 青蛙跳台阶问题

剑指 Offer 10- II. 青蛙跳台阶问题 和 剑指 Offer 10- I. 斐波那契数列 很像&#xff0c;改一下初始值就行了。 方法一 class Solution {int mod (int) 1e9 7;public int numWays(int n) {if(n < 1) return 1;int[] dp new int[n 1];dp[1] 1;dp[2] 2;for(int i 3…...

oracle10和11功能说明比较

Oracle 10g/11g的特点和优势 首先&#xff0c;Oracle 10g/11g具有以下几个特点&#xff1a; 1. 可靠性和稳定性&#xff1a;Oracle 10g采用了多种技术来确保数据的可靠性和稳定性&#xff0c;如ACID事务处理和数据备份与恢复机制。它还提供了高可用性的解决方案&#xff0c;如…...

golang-bufio 缓冲写

1. 缓冲写 在阅读这篇博客之前&#xff0c;请先阅读上一篇&#xff1a;golang-bufio 缓冲读 // buffered output// Writer implements buffering for an io.Writer object. // If an error occurs writing to a Writer, no more data will be // accepted and all subsequent…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...

【Linux】Linux安装并配置RabbitMQ

目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的&#xff0c;需要先安…...

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...