多机编队—(3)Fast_planner无人机模型替换为Turtlebot3模型实现无地图的轨迹规划

文章目录

  • 前言
  • 一、模型替换
  • 二、Riz可视化
  • 三、坐标变换
  • 四、轨迹规划
  • 最后


前言

前段时间已经成功将Fast_planner配置到ubuntu机器人中,这段时间将Fast_planner中的无人机模型替换为了Turtlebot3_waffle模型,机器人识别到环境中的三维障碍物信息,并完成无地图的轨迹规划。


一、模型替换

先把turtlebot3功能包拷贝到配置成功的Fast_planner工作空间下,turtlebot3中含有turtlebot3_description功能包,里面包含了turtlebot3所有的模型文件。

普通在gazebo中加载turtlebot3的模型文件如图所示:

在这里插入图片描述
但Fast_planner需要环境中的三维信息,以进行路径的规划,故这里需要将2D激光雷达替换为3D激光雷达,如下所示在turtlebot3_waffle.urdf.xacro文件中加入VLP-16激光雷达,以获取环境中的三维信息。

<?xml version="1.0" ?>
<robot name="turtlebot3_waffle" xmlns:xacro="http://ros.org/wiki/xacro"><xacro:include filename="$(find turtlebot3_description)/urdf/common_properties.xacro"/><xacro:include filename="$(find turtlebot3_description)/urdf/turtlebot3_waffle.gazebo.xacro"/><xacro:property name="support_length" value="0.3" />      <!--0.3--><xacro:arg name="gpu" default="false"/><xacro:property name="gpu" value="$(arg gpu)" /><xacro:arg name="organize_cloud" default="true"/><xacro:property name="organize_cloud" value="$(arg organize_cloud)" /><xacro:property name="base_z_size" value="0.122" />        <!--0.122--><xacro:include filename="$(find turtlebot3_description)/urdf/sensors/inertial.xacro" /><xacro:include filename="$(find turtlebot3_description)/urdf/sensors/laser_support.xacro" /><xacro:include filename="$(find velodyne_description)/urdf/VLP-16.urdf.xacro"/><xacro:VLP-16 parent="support" name="velodyne" topic="/velodyne_points" organize_cloud="${organize_cloud}" hz="10" samples="400" gpu="${gpu}"><origin xyz="0 0 ${support_length/4}" rpy="0 0 0" /> </xacro:VLP-16><xacro:include filename="$(find turtlebot3_description)/urdf/sensors/imu.xacro"/><xacro:imu sensor_name="imu" parent_link="base_link"><origin rpy="0 0 0" xyz="-0.064 0 ${base_z_size/2}"/> </xacro:imu>

其中的关键点为(上面代码也已展现出):需要将相关的模型加载文件放在设置的路径下。

然后在gazebo中加载新模型:

在这里插入图片描述

二、Riz可视化

<launch><node name="rvizvisualisation" pkg="rviz" type="rviz" output="log" args="-d $(find plan_manage)/config/traj.rviz" />
</launch>

在这里插入图片描述

三、坐标变换

在模型加装VLP-16激光雷达时设置了雷达的话题:topic=“/velodyne_points”,为使雷达能得到地图中障碍物信息。

写下面的一段代码实现订阅激光雷达(如Velodyne)产生的点云数据,并将这些点云从base_link的坐标系转换到odom坐标系。转换后的点云数据再发布出去,以供其他节点使用。

#include <ros/ros.h>
#include <sensor_msgs/PointCloud.h>
#include <tf2_ros/transform_listener.h>
#include <tf2_sensor_msgs/tf2_sensor_msgs.h>
#include <tf2/transform_datatypes.h>ros::Publisher points_pub;
tf2_ros::Buffer tfBuffer;void pointCloudCallback(const sensor_msgs::PointCloud2::ConstPtr &msg) {try {geometry_msgs::TransformStamped transformStamped = tfBuffer.lookupTransform("odom", "base_link", ros::Time(0));sensor_msgs::PointCloud2 transformed_cloud;tf2::doTransform(*msg, transformed_cloud, transformStamped);transformed_cloud.header.frame_id = "odom";points_pub.publish(transformed_cloud);} catch(tf2::TransformException &e) {ROS_WARN("Failed to transform point cloud: %s", e.what());}}int main(int argc, char **argv) 
{ros::init(argc, argv, "point_cloud_transform_node");ros::NodeHandle nh;ros::Subscriber points_sub = nh.subscribe("/velodyne_points", 10, pointCloudCallback);points_pub = nh.advertise<sensor_msgs::PointCloud2>("point_cloud_map", 10);tf2_ros::TransformListener tfListener(tfBuffer);ros::spin();return 0;
}

在这里插入图片描述

四、轨迹规划

该部分借助Fast_planner来实现,前端通过混合A*生成初始路径,后端在对其进行B样条优化和重规划。
为使Turtlebot3使用下面是配置的接口文件:

<launch><!-- size of map, change the size in x, y, z according to your application --><arg name="map_size_x" value="40.0"/><arg name="map_size_y" value="40.0"/><arg name="map_size_z" value="0.5 "/><!-- topic of your odometry such as VIO or LIO --><arg name="odom_topic" value="/odom" /><!-- main algorithm params --><include file="$(find plan_manage)/launch/lidar.xml"><arg name="map_size_x_" value="$(arg map_size_x)"/><arg name="map_size_y_" value="$(arg map_size_y)"/><arg name="map_size_z_" value="$(arg map_size_z)"/><arg name="odometry_topic" value="$(arg odom_topic)"/><!-- camera pose: transform of camera frame in the world frame --><!-- depth topic: depth image, 640x480 by default --><!-- don't set cloud_topic if you already set these ones! --><arg name="camera_pose_topic" value="/pcl_render_node/camera_pose"/><!--geometry_msgs::PoseStamped--><arg name="depth_topic" value="/pcl_render_node/depth"/><!-- topic of point cloud measurement, such as from LIDAR  --><!-- don't set camera pose and depth, if you already set this one! --><arg name="cloud_topic" value="/point_cloud_map"/><!-- intrinsic params of the depth camera --><arg name="cx" value="321.04638671875"/><arg name="cy" value="243.44969177246094"/><arg name="fx" value="387.229248046875"/><arg name="fy" value="387.229248046875"/><!-- maximum velocity and acceleration the drone will reach --><arg name="max_vel" value="3" /><arg name="max_acc" value="2" /><!-- 1: use 2D Nav Goal to select goal  --><!-- 2: use global waypoints below  --><arg name="flight_type" value="1" /><!-- global waypoints --><!-- If flight_type is set to 2, the drone will travel these waypoints one by one --><arg name="point_num" value="3" /><arg name="point0_x" value="2" /><arg name="point0_y" value="0" /><arg name="point0_z" value="0" /><!-- set more waypoints if you need --><arg name="point1_x" value="2" /><arg name="point1_y" value="-5" /><arg name="point1_z" value="0" /><arg name="point2_x" value="5.0" /><arg name="point2_y" value="-10.0" /><arg name="point2_z" value="0.0" /></include><!-- trajectory server --><node pkg="plan_manage" name="traj_server" type="traj_server" output="screen"><remap from="/position_cmd" to="/planning/pos_cmd"/><remap from="/odom_world" to="$(arg odom_topic)"/><param name="traj_server/time_forward" value="1.5" type="double"/></node><node pkg="waypoint_generator" name="waypoint_generator" type="waypoint_generator" output="screen"><remap from="~odom" to="$(arg odom_topic)"/>        <remap from="~goal" to="/move_base_simple/goal"/><remap from="~traj_start_trigger" to="/traj_start_trigger" /><param name="waypoint_type" value="manual-lonely-waypoint"/>    </node></launch>

lidar.xml

<launch><arg name="map_size_x_"/><arg name="map_size_y_"/><arg name="map_size_z_"/><arg name="odometry_topic"/><arg name="camera_pose_topic"/><arg name="depth_topic"/><arg name="cloud_topic"/><arg name="cx"/><arg name="cy"/><arg name="fx"/><arg name="fy"/><arg name="max_vel"/><arg name="max_acc"/><arg name="point_num"/><arg name="point0_x"/><arg name="point0_y"/><arg name="point0_z"/><arg name="point1_x"/><arg name="point1_y"/><arg name="point1_z"/><arg name="point2_x"/><arg name="point2_y"/><arg name="point2_z"/><arg name="flight_type"/><!-- main node --><node pkg="plan_manage" name="fast_planner_node" type="fast_planner_node" output="screen"><remap from="/odom_world" to="$(arg odometry_topic)"/><remap from="/sdf_map/odom" to="$(arg odometry_topic)"/><remap from="/sdf_map/cloud" to="$(arg cloud_topic)"/><remap from = "/sdf_map/pose"   to = "$(arg camera_pose_topic)"/> <remap from = "/sdf_map/depth" to = "$(arg depth_topic)"/><!-- replanning method --><param name="planner_node/planner" value="1" type="int"/><!-- planning fsm --><param name="fsm/flight_type" value="$(arg flight_type)" type="int"/><param name="fsm/thresh_replan" value="1.5" type="double"/><param name="fsm/thresh_no_replan" value="1.0" type="double"/><param name="fsm/waypoint_num" value="$(arg point_num)" type="int"/><param name="fsm/waypoint0_x" value="$(arg point0_x)" type="double"/><param name="fsm/waypoint0_y" value="$(arg point0_y)" type="double"/><param name="fsm/waypoint0_z" value="$(arg point0_z)" type="double"/><param name="fsm/waypoint1_x" value="$(arg point1_x)" type="double"/><param name="fsm/waypoint1_y" value="$(arg point1_y)" type="double"/><param name="fsm/waypoint1_z" value="$(arg point1_z)" type="double"/><param name="fsm/waypoint2_x" value="$(arg point2_x)" type="double"/><param name="fsm/waypoint2_y" value="$(arg point2_y)" type="double"/><param name="fsm/waypoint2_z" value="$(arg point2_z)" type="double"/><param name="sdf_map/resolution"      value="0.15" /> <param name="sdf_map/map_size_x"   value="$(arg map_size_x_)" /> <param name="sdf_map/map_size_y"   value="$(arg map_size_y_)" /> <param name="sdf_map/map_size_z"   value="$(arg map_size_z_)" /> <param name="sdf_map/local_update_range_x"  value="5.5" /> <param name="sdf_map/local_update_range_y"  value="5.5" /> <param name="sdf_map/local_update_range_z"  value="4.5" /> <param name="sdf_map/obstacles_inflation"     value="0.3" /> <!--<膨胀的半径  单位米>--><param name="sdf_map/local_bound_inflate"    value="0.0"/><param name="sdf_map/local_map_margin" value="10"/><param name="sdf_map/ground_height"        value="0"/><!-- camera parameter --><param name="sdf_map/cx" value="$(arg cx)"/><param name="sdf_map/cy" value="$(arg cy)"/><param name="sdf_map/fx" value="$(arg fx)"/><param name="sdf_map/fy" value="$(arg fy)"/><!-- depth filter --><param name="sdf_map/use_depth_filter" value="false"/><param name="sdf_map/depth_filter_tolerance" value="0.15"/><param name="sdf_map/depth_filter_maxdist"   value="5.0"/><!--5.0--><param name="sdf_map/depth_filter_mindist"   value="0.2"/><param name="sdf_map/depth_filter_margin"    value="2"/><param name="sdf_map/k_depth_scaling_factor" value="1000.0"/><param name="sdf_map/skip_pixel" value="2"/><!-- local fusion --><param name="sdf_map/p_hit"  value="0.65"/><param name="sdf_map/p_miss" value="0.35"/><param name="sdf_map/p_min"  value="0.12"/><param name="sdf_map/p_max"  value="0.90"/><param name="sdf_map/p_occ"  value="0.80"/><param name="sdf_map/min_ray_length" value="0.3"/><param name="sdf_map/max_ray_length" value="5.0"/><param name="sdf_map/esdf_slice_height" value="0.3"/><param name="sdf_map/visualization_truncate_height"   value="2.49"/><param name="sdf_map/virtual_ceil_height"   value="2.5"/><param name="sdf_map/show_occ_time"  value="false"/><param name="sdf_map/show_esdf_time" value="false"/><param name="sdf_map/pose_type"     value="1"/>  <param name="sdf_map/frame_id"      value="odom"/><!-- planner manager --><param name="manager/max_vel" value="$(arg max_vel)" type="double"/><param name="manager/max_acc" value="$(arg max_acc)" type="double"/><param name="manager/max_jerk" value="4" type="double"/><param name="manager/dynamic_environment" value="0" type="int"/><param name="manager/local_segment_length" value="12.0" type="double"/><param name="manager/clearance_threshold" value="0.2" type="double"/><param name="manager/control_points_distance" value="0.5" type="double"/><param name="manager/use_geometric_path" value="false" type="bool"/><param name="manager/use_kinodynamic_path" value="true" type="bool"/><param name="manager/use_topo_path" value="false" type="bool"/><param name="manager/use_optimization" value="true" type="bool"/><!-- kinodynamic path searching --><param name="search/max_tau" value="1.0" type="double"/><!--如果考虑对时间维度进行划分才设置--><param name="search/init_max_tau" value="0.8" type="double"/><param name="search/max_vel" value="$(arg max_vel)" type="double"/><param name="search/max_acc" value="$(arg max_acc)" type="double"/><param name="search/w_time" value="10.0" type="double"/><param name="search/horizon" value="5.0" type="double"/><!--限制全局规划的距离,保证实时性--><param name="search/lambda_heu" value="4.0" type="double"/><!--启发函数权重--><param name="search/resolution_astar" value="0.1" type="double"/><!--空间分辨率--><param name="search/time_resolution" value="0.8" type="double"/><!--时间维度分辨率--><param name="search/margin" value="0.2" type="double"/><!--检测碰撞--><param name="search/allocate_num" value="100000" type="int"/><!--最大节点数目--><param name="search/check_num" value="5" type="int"/><!--对中间状态安全检查--><!-- trajectory optimization --><param name="optimization/lambda1" value="10.0" type="double"/><param name="optimization/lambda2" value="5.0" type="double"/><param name="optimization/lambda3" value="0.00001" type="double"/><param name="optimization/lambda4" value="0.01" type="double"/><param name="optimization/lambda7" value="100.0" type="double"/><!-- reduces 'optimization/lambda7' to make the yaw changes slower--><param name="optimization/dist0" value="0.4" type="double"/><param name="optimization/max_vel" value="$(arg max_vel)" type="double"/><param name="optimization/max_acc" value="$(arg max_acc)" type="double"/><param name="optimization/algorithm1" value="15" type="int"/><param name="optimization/algorithm2" value="11" type="int"/><param name="optimization/max_iteration_num1" value="2" type="int"/><param name="optimization/max_iteration_num2" value="300" type="int"/><param name="optimization/max_iteration_num3" value="200" type="int"/><param name="optimization/max_iteration_num4" value="200" type="int"/><param name="optimization/max_iteration_time1" value="0.0001" type="double"/><param name="optimization/max_iteration_time2" value="0.005" type="double"/><param name="optimization/max_iteration_time3" value="0.003" type="double"/><param name="optimization/max_iteration_time4" value="0.003" type="double"/><param name="optimization/order" value="3" type="int"/><param name="bspline/limit_vel" value="$(arg max_vel)" type="double"/><param name="bspline/limit_acc" value="$(arg max_acc)" type="double"/><param name="bspline/limit_ratio" value="1.1" type="double"/><param name="bspline/limit_vel" value="$(arg max_vel)" type="double"/><param name="bspline/limit_acc" value="$(arg max_acc)" type="double"/><param name="bspline/limit_ratio" value="1.1" type="double"/></node>
</launch>

可能会出现规划出的路径实际位置与目标期望位置存在偏差的情况:

Fast_planner规划期望位置与实际位置偏差-解决前

这是由于OneShot中检查边界出现问题,令其返回了false,即认为最后寻找的目标点是不可达的,上一节点可达,故此时规划目标位置接近目标点但不是目标点。
sdf_map.cpp

  node_.param("sdf_map/map_size_x", x_size, -1.0);node_.param("sdf_map/map_size_y", y_size, -1.0);node_.param("sdf_map/map_size_z", z_size, -1.0);

kinodynamic_astar.cpp

if (coord(0) < origin_(0) || coord(0) >= map_size_3d_(0) || coord(1) < origin_(1) || coord(1) >= map_size_3d_(1) || coord(2) < origin_(2)  || coord(2) >= map_size_3d_(2)){return false;}

在进行OneShot时边界约束判断当前点是否存在一条路经直到终点,因为coord(2)小车z轴信息为-0.000981506, origin(2)为0,小车z值为负一直小于origin(2),则会一直满足判断条件返回false,故无法到目标点。

在这里插入图片描述
如果仍有问题,请检查其他的约束条件。
由当前点寻找到终点的最优路径简单证明思路如下(感兴趣可以自己推一下):
在这里插入图片描述


最后

Fast_planner规划期望目标位置与实际位置-解决后

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

5 首页框架及路由配置

1 添加首页LayoutVue.vue组件&#xff0c;登录成功之后跳转到该组件 <script setup> import {Management,Promotion,UserFilled,User,Crop,EditPen,SwitchButton,CaretBottom } from element-plus/icons-vue import avatar from /assets/default.png// 导入ref import {…

GitLab 老旧版本如何升级?

极狐GitLab 正式对外推出 GitLab 专业升级服务 https://dl.gitlab.cn/cm33bsfv&#xff01; 专业的技术人员为您的 GitLab 老旧版本实例进行专业升级&#xff01;服务详情可以在官网查看详细解读&#xff01; 那些因为老旧版本而被攻击的例子 话不多说&#xff0c;直接上图&a…

RTMP、FFmpeg安装测试

RTMP、FFmpeg安装测试 1.使用 Docker 部署 RTMP 服务1.拉取带有 RTMP 模块的 NGINX 镜像&#xff1a;2.运行容器 2. 防火墙放行3.windows安装ffmpeg1. [下载链接](https://ffmpeg.org//download.html)2.解压3.环境变量配置 4.常用的 FFmpeg 推流和拉流命令1.推流命令1. 推流到 …

SQL实现给表添加数据及其触发器操作

新建一个表实现添加数据&#xff0c;数据不重复&#xff0c;。判断两个字段是否存在&#xff0c;如果存在&#xff0c;就修改对应字段&#xff0c;如果不存在就新增数据。 测试表格Test如下&#xff1a; 新建触发器如图&#xff1a; 触发程式如下&#xff1a; USE [Test] GO/*…

C语言_字符串+内存函数的介绍

字符函数和字符串函数 本章重点 重点介绍处理字符和字符串的库函数的使用和注意事项 求字符串长度 strlen 长度不受限制的字符串函数 strcpy strcat strcmp 字符串查找 strstr strtok 错误信息报告 strerror 字符操作内存操作函数 memcpy memmove memset memcmp 1. 字…

【含文档】基于Springboot+Vue的白云山景点门票销售管理系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

Mysql(七) --- 索引

文章目录 前言1.简介1.1.索引是什么&#xff1f;1.2.为什么使用索引? 2.索引应该使用什么数据结构&#xff1f;2.1.Hash2.2.二叉搜索树2.3.N叉树2.4.B树2.4.1. 简介2.4.2. B树的特点2.4.3. B树和B树的对比 3.Mysql中的页3.1.为什么要使用页3.2.页文件头和页文件尾3.3.页主体3.…

小新学习Docker之Docker--harbor私有仓库部署与管理

目录 一、Harbor简介 1.1、Harbor概述 1.2、Harbor的特性 1.3、Harbor的构成 二、Harbor构建Docker私有仓库 2.1、部署Harbor服务 2.2、启动 Harbor 2.3、查看 Harbor 启动镜像&#xff0c;检查harbor是否安装成功 2.4、创建一个新项目 2.5、非本地主机进行下载镜像 …

STM32学习--4-1 OLED显示屏

接线图 OLED.c #include "stm32f10x.h" #include "OLED_Font.h"/*引脚配置*/ #define OLED_W_SCL(x) GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)(x)) #define OLED_W_SDA(x) GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)(x))/*引脚初始化*/ void …

软件安全漏洞挖掘: 基础知识和概念

1. 软件漏洞原理和漏洞检测方法 文章目录 1. 软件漏洞原理和漏洞检测方法1. 漏洞披露2. 漏洞定义和分类1. 漏洞的定义2. 漏洞的分类3. 漏洞检测方法常见方法1. 程序切片2. 形式化方法1. 符号执行3. 污点分析污点分析步骤/流程*污点分析流程的详细介绍1. 识别source和sink点2. 污…

Pycharm通过ssh远程docker容器搭建开发环境

本地pycharm通过ssh方式远程连接服务器&#xff08;Ubuntu&#xff09;上的docker容器&#xff0c;搭建开发环境。实现功能&#xff1a;将环境依赖打包成docker镜像&#xff0c;并在远程服务器中启动容器&#xff08;启动时做好端口映射和文件夹挂载&#xff09;&#xff0c;通…

使用vscode导入库失败解决方法

导入库失败原因 在使用vscode写python代码时&#xff0c;有时会遇见导入库失败的情况&#xff0c;如下图&#xff1a;无法解析导入“xxxxx” 或者 运行时报错&#xff1a;ModuleNotFoundError: No module named xxxxx。 原因可能有&#xff1a; 根本没有下载库&#xff1b…

Luminar Neo v1.21.0.13934 图像编辑软件绿色便携版

skylum Luminar Neo 是一款由未来 AI 技术驱动的创意图像编辑器。并且支持微软Windows及苹果Mac OX系统&#xff0c;它使创作者能够将他们最大胆的想法变为现实并乐在其中。借助 Luminar Neo 领先的 AI 技术和灵活的工作流程&#xff0c;完成创意任务并获得专业品质的编辑结果。…

java基础(5)继承与多态

目录 ​编辑 1.前言 2.正文 2.1继承 2.1.1继承概念 2.1.2继承语法 2.1.3子类访问父类 2.1.4super关键字 2.2多态 2.2.1多态概念 2.2.2多态条件 2.2.3重写 2.2.4向上转型与向下转型 2.2.5为什么要使用多态 3.小结 1.前言 哈喽大家好啊&#xff0c;今天继续来为大…

C++ operator new和operator delete的深入讲解

个人主页&#xff1a;Jason_from_China-CSDN博客 所属栏目&#xff1a;C系统性学习_Jason_from_China的博客-CSDN博客 所属栏目&#xff1a;C知识点的补充_Jason_from_China的博客-CSDN博客 前言 关于operator new和operator delete我们需要明确一个概念&#xff0c;这两个都是…

15.5 JDBC数据库编程5——DAO

目录 15.1.1 引言 实体类Product.java 异常类DaoException.java Dao.java ProductDao.java ProductDaoImpl.java ProductDaoTest.java 15.1.1 引言 Java是面向对象编程语言&#xff0c;主要操作对象&#xff0c;而关系数据库的数据并不是对象&#xff0c;Java程序插入…

linux线程 | 线程的控制(下)

前言&#xff1a; 本节内容是线程的控制部分的第二个小节。 主要是列出我们的线程控制部分的几个细节性问题以及我们的线程分离。这些都是需要大量的代码去进行实验的。所以&#xff0c; 准备好接受新知识的友友们请耐心观看。 现在开始我们的学习吧。 ps:本节内容适合了解线程…

动态内存管理(C语言 VS C++)

目录 一.动态内存管理的前置知识 1.栈区 a.栈区的特点 b.注意事项 2.堆区 a.堆区的特点 b.注意事项 3.全局/静态区 a.作用域和生命周期 b.注意事项 4.常量区 二.C语言动态内存管理 1.malloc 函数 a.接口简介与使用实例 b.注意要点 2.calloc 函数&#xff1a; 3.…

Flink Web UI 是使用和调试保姆级教程(持续更新)

Flink Web UI 是调试和监控 Flink 应用程序的重要工具&#xff0c;通过它&#xff0c;你可以实时查看正在运行的 Flink 任务的详细信息&#xff0c;包括作业的状态、性能指标、各子任务的运行情况、故障恢复情况等。Flink Web UI 的这些功能为开发者和运维人员提供了调试和优化…

软考系统分析师知识点十三:软件需求工程

前言 今年报考了11月份的软考高级&#xff1a;系统分析师。 考试时间为&#xff1a;11月9日。 倒计时&#xff1a;24天。 目标&#xff1a;优先应试&#xff0c;其次学习&#xff0c;再次实践。 复习计划第一阶段&#xff1a;扫平基础知识点&#xff0c;仅抽取有用信息&am…