ROS2 驱动思岚G4雷达(ydlidar)- Rviz显示
记录G4雷达的配置
系统环境为:Ubuntu22.04
配置步骤
1、安装雷达SDK
2、构建 G4 雷达 ROS2 项目工程文件
3、使用Rviz可视化界面显示
1、安装雷达SDK
1.1 安装CMake
YDLidar SDK需要CMake 2.8.2+作为依赖项
- Ubuntu 18.04或者Ubuntu 22.04
sudo apt install cmake pkg-config
如果使用python API,您需要安装python和swig(3.0或更高版本)
sudo apt-get install python swig
sudo apt-get install python-pip
1.2 构建YDLidar SDK
在YDLidar SDK目录中,运行以下命令来编译项目:
git clone https://github.com/YDLIDAR/YDLidar-SDK.git
cd YDLidar-SDK/build
cmake ..
make
sudo make install
注意:如果已经安装了python和swig,sudo make install命令也将安装python API,而无需执行以下操作,在这里建议大家还是使用一次 sudo make install 确认安装成功
至此,若在编译过程中未出现错误,即为SDK安装成功
2、构建 G4 雷达 ROS2 项目工程文件
2.1 编译和安装YDLidar SDK
ydlidar_ros2_driver依赖于ydlidar SDK库。如果从未安装过YDLidar SDK库,则必须首先安装YDLidar SDK库,具体的可以参考上一点:
2.2 Cylinder_ros2_driver克隆
(1)为github克隆ydlidar_ros2_driver包:
git clone https://github.com/YDLIDAR/ydlidar_ros2_driver.git ydlidar_ros2_ws/src/ydlidar_ros2_driver
(2)构建ydlidar_ros2_driver包
cd ydlidar_ros2_ws
colcon build --symlink-install
(3)程序包环境设置:
将工作空间添加到环境变量里面
source ./install/setup.bash
同样可以使用比较长久的方法:
echo "source ~/ydlidar_ros2_ws/install/setup.bash" >> ~/.bashrc
source ~/.bashrc
在这里 “~/ydlidar_ros2_ws/install/setup.bash路径要对应上自己的工作空间当中的setup.bash位置。
(4)确认要确认包路径已设置,请打印grep-i ROS变量
printenv | grep -i ROS
应该看到类似的内容:OLDPWD=/home/tony/ydlidar_ros2_ws/install
(5)创建串行端口别名[可选]
sudo chmod 0777 src/ydlidar_ros2_driver/startup/*
sudo sh src/ydlidar_ros2_driver/startup/initenv.sh
3、使用Rviz可视化界面显示
使用启动文件运行ydlidar_ros2_driver
3.1 运行雷达启动launch文件
ros2 launch ydlidar_ros2_driver ydlidar_launch.py
或者
ros2 launch $(ros2 pkg prefix ydlidar_ros2_driver)/share/ydlidar_ros2_driver/launch/ydlidar.py
3.2运行可视化界面
如果想要运行可视化界面的话可以使用一下命令,单独在终端里运行即可
ros2 launch ydlidar_ros2_driver ydlidar_launch_view.py
3、查看一下雷达扫描话题信息
ros2 run ydlidar_ros2_driver ydlidar_ros2_driver_client or ros2 topic echo /scan
问题解决
1、launch文件修改
在编译过程当中,出现了ydlidar_launch_view.py文件或者ydlidar_launch.py文件中的
[ERROR] [launch]: Caught exception in launch LifecycleNode: __init__() missing 1 required keyword-only argument: 'node_executable'
这样的错误警告,将两个文件当中含有node_[后缀名称]更改为[后缀名称即可]
例如,在本次报错当中,需要将LifecycleNode这个节点的node_executable更改为executable即可,其他的node_name同样的更改为 name
#!/usr/bin/python3
# Copyright 2020, EAIBOT
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.from ament_index_python.packages import get_package_share_directoryfrom launch import LaunchDescription
from launch_ros.actions import LifecycleNode
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch.actions import LogInfoimport lifecycle_msgs.msg
import osdef generate_launch_description():share_dir = get_package_share_directory('ydlidar_ros2_driver')rviz_config_file = os.path.join(share_dir, 'config','ydlidar.rviz')parameter_file = LaunchConfiguration('params_file')# node_name = 'ydlidar_ros2_driver_node'params_declare = DeclareLaunchArgument('params_file',default_value=os.path.join(share_dir, 'params', 'ydlidar.yaml'),description='FPath to the ROS2 parameters file to use.')driver_node = LifecycleNode(package='ydlidar_ros2_driver',executable='ydlidar_ros2_driver_node',name='ydlidar_ros2_driver_node',output='screen',emulate_tty=True,parameters=[parameter_file],namespace='/',)tf2_node = Node(package='tf2_ros',executable='static_transform_publisher',name='static_tf_pub_laser',arguments=['0', '0', '0.02','0', '0', '0', '1','base_link','laser_frame'],)rviz2_node = Node(package='rviz2',executable='rviz2',name='rviz2',arguments=['-d', rviz_config_file],)return LaunchDescription([params_declare,driver_node,tf2_node,rviz2_node,])
上图对应的是 "ydlidar_launch_view.py"文件,然后ydlidar_launch.py文件中对应的两个参数,也就是node_executable和node_name 两个变量名字做出修改,修改后如下代码所示:
#!/usr/bin/python3
# Copyright 2020, EAIBOT
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.from ament_index_python.packages import get_package_share_directoryfrom launch import LaunchDescription
from launch_ros.actions import LifecycleNode
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch.actions import LogInfoimport lifecycle_msgs.msg
import osdef generate_launch_description():share_dir = get_package_share_directory('ydlidar_ros2_driver')parameter_file = LaunchConfiguration('params_file')# node_name = 'ydlidar_ros2_driver_node'params_declare = DeclareLaunchArgument('params_file',default_value=os.path.join(share_dir, 'params', 'ydlidar.yaml'),description='FPath to the ROS2 parameters file to use.')driver_node = LifecycleNode(package='ydlidar_ros2_driver',executable='ydlidar_ros2_driver_node',name='ydlidar_ros2_driver_node',output='screen',emulate_tty=True,parameters=[parameter_file],namespace='/',)tf2_node = Node(package='tf2_ros',executable='static_transform_publisher',name='static_tf_pub_laser',arguments=['0', '0', '0.02','0', '0', '0', '1','base_link','laser_frame'],)return LaunchDescription([params_declare,driver_node,tf2_node,])
建议使用 vscode 编辑器对文本进行更改,以便可以重复撤回和更加便携式的文本切换
2、如果出现node节点链接错误
然后就是在编译过程(colcon build --symlink-install)中,如果出现node节点链接错误的情况,需要更改当前目录下的
ydlidar_ros2_driver/src/ydlidar_ros2_driver_node.cpp 这个文件内容(直接复制替换即可)
/** YDLIDAR SYSTEM* YDLIDAR ROS 2 Node** Copyright 2017 - 2020 EAI TEAM* http://www.eaibot.com**//* Modified for Humble by @lghrainbow 10/2022 */#ifdef _MSC_VER
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#endif
#endif#include "src/CYdLidar.h"
#include <math.h>
#include <chrono>
#include <iostream>
#include <memory>#include "rclcpp/clock.hpp"
#include "rclcpp/rclcpp.hpp"
#include "rclcpp/time_source.hpp"
#include "sensor_msgs/msg/laser_scan.hpp"
#include "std_srvs/srv/empty.hpp"
#include <vector>
#include <iostream>
#include <string>
#include <signal.h>#define ROS2Verision "1.0.2" /* 1.0.1 modified */int main(int argc, char *argv[]) {rclcpp::init(argc, argv);auto node = rclcpp::Node::make_shared("ydlidar_ros2_driver_node");RCLCPP_INFO(node->get_logger(), "[YDLIDAR INFO] Current ROS Driver Version: %s\n", ((std::string)ROS2Verision).c_str());CYdLidar laser;std::string str_optvalue = "/dev/ydlidar";node->declare_parameter<std::string>("port");node->get_parameter("port", str_optvalue);///lidar portlaser.setlidaropt(LidarPropSerialPort, str_optvalue.c_str(), str_optvalue.size());///ignore arraystr_optvalue = "";node->declare_parameter<std::string>("ignore_array");node->get_parameter("ignore_array", str_optvalue);laser.setlidaropt(LidarPropIgnoreArray, str_optvalue.c_str(), str_optvalue.size());std::string frame_id = "laser_frame";node->declare_parameter<std::string>("frame_id");node->get_parameter("frame_id", frame_id);//int property//// lidar baudrateint optval = 230400;node->declare_parameter<int>("baudrate");node->get_parameter("baudrate", optval);laser.setlidaropt(LidarPropSerialBaudrate, &optval, sizeof(int));/// tof lidaroptval = TYPE_TRIANGLE;node->declare_parameter<int>("lidar_type");node->get_parameter("lidar_type", optval);laser.setlidaropt(LidarPropLidarType, &optval, sizeof(int));/// device typeoptval = YDLIDAR_TYPE_SERIAL;node->declare_parameter<int>("device_type");node->get_parameter("device_type", optval);laser.setlidaropt(LidarPropDeviceType, &optval, sizeof(int));/// sample rateoptval = 9;node->declare_parameter<int>("sample_rate");node->get_parameter("sample_rate", optval);laser.setlidaropt(LidarPropSampleRate, &optval, sizeof(int));/// abnormal countoptval = 4;node->declare_parameter<int>("abnormal_check_count");node->get_parameter("abnormal_check_count", optval);laser.setlidaropt(LidarPropAbnormalCheckCount, &optval, sizeof(int));//bool property//// fixed angle resolutionbool b_optvalue = false;node->declare_parameter<bool>("fixed_resolution");node->get_parameter("fixed_resolution", b_optvalue);laser.setlidaropt(LidarPropFixedResolution, &b_optvalue, sizeof(bool));/// rotate 180b_optvalue = true;node->declare_parameter<bool>("reversion");node->get_parameter("reversion", b_optvalue);laser.setlidaropt(LidarPropReversion, &b_optvalue, sizeof(bool));/// Counterclockwiseb_optvalue = true;node->declare_parameter<bool>("inverted");node->get_parameter("inverted", b_optvalue);laser.setlidaropt(LidarPropInverted, &b_optvalue, sizeof(bool));b_optvalue = true;node->declare_parameter<bool>("auto_reconnect");node->get_parameter("auto_reconnect", b_optvalue);laser.setlidaropt(LidarPropAutoReconnect, &b_optvalue, sizeof(bool));/// one-way communicationb_optvalue = false;node->declare_parameter<bool>("isSingleChannel");node->get_parameter("isSingleChannel", b_optvalue);laser.setlidaropt(LidarPropSingleChannel, &b_optvalue, sizeof(bool));/// intensityb_optvalue = false;node->declare_parameter<bool>("intensity");node->get_parameter("intensity", b_optvalue);laser.setlidaropt(LidarPropIntenstiy, &b_optvalue, sizeof(bool));/// Motor DTRb_optvalue = false;node->declare_parameter<bool>("support_motor_dtr");node->get_parameter("support_motor_dtr", b_optvalue);laser.setlidaropt(LidarPropSupportMotorDtrCtrl, &b_optvalue, sizeof(bool));//float property//// unit: °float f_optvalue = 180.0f;node->declare_parameter<float>("angle_max");node->get_parameter("angle_max", f_optvalue);laser.setlidaropt(LidarPropMaxAngle, &f_optvalue, sizeof(float));f_optvalue = -180.0f;node->declare_parameter<float>("angle_min");node->get_parameter("angle_min", f_optvalue);laser.setlidaropt(LidarPropMinAngle, &f_optvalue, sizeof(float));/// unit: mf_optvalue = 64.f;node->declare_parameter<float>("range_max");node->get_parameter("range_max", f_optvalue);laser.setlidaropt(LidarPropMaxRange, &f_optvalue, sizeof(float));f_optvalue = 0.1f;node->declare_parameter<float>("range_min");node->get_parameter("range_min", f_optvalue);laser.setlidaropt(LidarPropMinRange, &f_optvalue, sizeof(float));/// unit: Hzf_optvalue = 10.f;node->declare_parameter<float>("frequency");node->get_parameter("frequency", f_optvalue);laser.setlidaropt(LidarPropScanFrequency, &f_optvalue, sizeof(float));bool invalid_range_is_inf = false;node->declare_parameter<bool>("invalid_range_is_inf");node->get_parameter("invalid_range_is_inf", invalid_range_is_inf);bool ret = laser.initialize();if (ret) {ret = laser.turnOn();} else {RCLCPP_ERROR(node->get_logger(), "%s\n", laser.DescribeError());}auto laser_pub = node->create_publisher<sensor_msgs::msg::LaserScan>("scan", rclcpp::QoS(rclcpp::SensorDataQoS()));auto stop_scan_service =[&laser](const std::shared_ptr<rmw_request_id_t> request_header,const std::shared_ptr<std_srvs::srv::Empty::Request> req,std::shared_ptr<std_srvs::srv::Empty::Response> response) -> bool{return laser.turnOff();};auto stop_service = node->create_service<std_srvs::srv::Empty>("stop_scan",stop_scan_service);auto start_scan_service =[&laser](const std::shared_ptr<rmw_request_id_t> request_header,const std::shared_ptr<std_srvs::srv::Empty::Request> req,std::shared_ptr<std_srvs::srv::Empty::Response> response) -> bool{return laser.turnOn();};auto start_service = node->create_service<std_srvs::srv::Empty>("start_scan",start_scan_service);rclcpp::WallRate loop_rate(20);while (ret && rclcpp::ok()) {LaserScan scan;//if (laser.doProcessSimple(scan)) {auto scan_msg = std::make_shared<sensor_msgs::msg::LaserScan>();scan_msg->header.stamp.sec = RCL_NS_TO_S(scan.stamp);scan_msg->header.stamp.nanosec = scan.stamp - RCL_S_TO_NS(scan_msg->header.stamp.sec);scan_msg->header.frame_id = frame_id;scan_msg->angle_min = scan.config.min_angle;scan_msg->angle_max = scan.config.max_angle;scan_msg->angle_increment = scan.config.angle_increment;scan_msg->scan_time = scan.config.scan_time;scan_msg->time_increment = scan.config.time_increment;scan_msg->range_min = scan.config.min_range;scan_msg->range_max = scan.config.max_range;int size = (scan.config.max_angle - scan.config.min_angle)/ scan.config.angle_increment + 1;scan_msg->ranges.resize(size);scan_msg->intensities.resize(size);for(size_t i=0; i < scan.points.size(); i++) {int index = std::ceil((scan.points[i].angle - scan.config.min_angle)/scan.config.angle_increment);if(index >=0 && index < size) {scan_msg->ranges[index] = scan.points[i].range;scan_msg->intensities[index] = scan.points[i].intensity;}}laser_pub->publish(*scan_msg);} else {RCLCPP_ERROR(node->get_logger(), "Failed to get scan");}if(!rclcpp::ok()) {break;}rclcpp::spin_some(node);loop_rate.sleep();}RCLCPP_INFO(node->get_logger(), "[YDLIDAR INFO] Now YDLIDAR is stopping .......");laser.turnOff();laser.disconnecting();rclcpp::shutdown();return 0;
}
🌸🌸🌸完结撒花🌸🌸🌸
🌈🌈Redamancy🌈🌈
相关文章:

ROS2 驱动思岚G4雷达(ydlidar)- Rviz显示
记录G4雷达的配置 系统环境为:Ubuntu22.04 配置步骤 1、安装雷达SDK 2、构建 G4 雷达 ROS2 项目工程文件 3、使用Rviz可视化界面显示 1、安装雷达SDK 1.1 安装CMake YDLidar SDK需要CMake 2.8.2作为依赖项 Ubuntu 18.04或者Ubuntu 22.04 sudo apt install cmak…...

Spring Cloud Alibaba Sentinel流量防卫兵
文章目录 Spring Cloud Alibaba Sentinel流量防卫兵1. 分布式遇到的问题2.解决的方法 Sentinel: 分布式系统的流量防卫兵1. 简介和特折 Sentinel流量防卫兵的搭建1.引入依赖2.添加配置类3.运行类上添加SentinelResource,并配置blockHandler和fallback4. linux中放入…...

1.简单工厂模式
UML类图 代码 main.cpp #include <iostream> #include "OperationFactory.h" using namespace std;int main(void) {float num1;float num2;char operate;cin >> num1 >> num2 >> operate;Operation* oper OperationFactory::createOpera…...

GitHub Copilot Chat
9月21日,GitHub在官网宣布,所有个人开发者可以使用GitHub Copilot Chat。用户通过文本问答方式就能生成、检查、分析各种代码。 据悉,GitHub Copilot Chat是基于OpenAI的GPT-4模型打造而成,整体使用方法与ChatGPT类似。例如&…...
利用 QT 完成一个人脸识别系统,完成登录操作
1.配置文件 # Project created by QtCreator 2023-09-22T10:34:23 # #-------------------------------------------------QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsTARGET project TEMPLATE appSOURCES main.cpp\widget.cppHEADERS widget.hFOR…...

MATLAB APP纯小白入门 两数相加
万事开头难,最怕第一次。使用matlab APP 实现两数求和,如下图所示,c a b,输入数字后,按 “” 就计算。 步骤 拖拽三个 Edit Field(Numeric) 过来,并且双击名字分别改为 a,b,c。注意修改名字后右边会有点变…...

ubuntu右上角的网络连接图标消失解决办法
ubuntu更新了几个文件后,我的ubuntu系统右上角的网络连接图标就消失了,然后怎么也找不到了,怎么办呢? 1、按快捷键ctrlaltt打开终端 2、按以下顺序输入如下的命令行 sudo service network-manager stop sudo rm /var/lib/Netw…...

conda创建虚拟环境安装aix360
目录 创建虚拟环境查看已有虚拟环境进入所创建的虚拟环境查看已安装的程序查看已安装的python模块配置镜像pipconda 安装aix360将环境添加到jupyter删除虚拟环境 创建虚拟环境 conda create -n aix360 python3.9查看已有虚拟环境 conda env list进入所创建的虚拟环境 activa…...
CentOS安装mariadb
1、 安装 [rootlocalhost ~]# yum install mariadb mariadb-server2、 启动并自启 [rootecs-3f21 ~]# systemctl enable mariadb –now3、 查看启动状态 [rootecs-3f21 ~]# systemctl status mariadb4、 初始化mariadb并设置root密码 [rootecs-3f21 ~]# mysql_secure_inst…...

FPGA——基础知识合集
文章目录 前言1、简述触发器与锁存器的区别2、简述 if-else 语句和 case 语句的区别3、相对 ARM、DSP 等处理器,谈谈 FPGA 具有哪些优势4、简述 Verilog 语句中阻塞赋值与非阻塞赋值的含义与区别,以及各自的适用的场景5、什么是同步电路,什么…...

【pytest】 标记冒烟用例 @pytest.mark.smoke
1. 使用 pytest.mark.smoke 标记用例 import pytest class Test_Smoke:def test_01(self):assert 112pytest.mark.smokedef test_02(self):assert 121pytest.mark.smokedef test_03(self):assert 1 2 3 2.配置文件pytest.ini [pytest] markers smoke 3. 运行指定标签 运…...

数据结构入门-14-排序
一、选择排序 1.1 选择排序思想 先把最小的元素拿出来 剩下的,再把最小的拿出来 剩下的,再把最小的拿出来 但是这样 空间复杂度是O(n) 优化一下,希望原地排序 1.1.2 选择原地排序 索引i指向0的位置 索引j指向i1的元素 j 后面的元素遍历&…...

Gin学习记录4——Controller和中间件
一. Controller 用不同的Controller可以实现业务的分类,不同类型的请求可以共用同一套中间件 1.1 单文件Controller 几乎等同于函数封装,直接将ctrl的代码写入到一个文件里然后调用: package adminimport ("net/http""git…...

FL Studio21.2中文版数字音乐制作软件
现在的FL也可以像splice一样啦,需要什么样的声音只需在fl里搜索,就会自动展示给你! FL Studio 简称FL,全称:Fruity Loops Studio,国人习惯叫它"水果"。软件现有版本是 FL Studio 21,已全面升级支…...

ELK 企业级日志分析系统 ELFK
目录 一、概述 二、组件介绍 2.1、ElasticSearch 2.2、Kiabana 2.3、Logstash 2.4、可以添加的其它组件:Filebeat 2.5、缓存/消息队列(redis、kafka、RabbitMQ等) 2.6、Fluentd 三、ELK工作原理 四、实例演示 1.ELK之 部署"E&q…...

IDEA中创建Java Web项目方法1
以下过程使用IntelliJ IDEA 2021.3 一、File-> New -> Project... 1. 项目类型中选择 Java Enterprise 项目 2. Name:填写自己的项目名称 3. Project template:选择项目的模板,Web application。支持JSP和Servlet的项目 4. Applica…...

源码:TMS FlexCel Studio for .NET 7.19
TMS FlexCel Studio for .NET 是100% 托管代码 Excel 文件操作引擎以及 Excel 和 PDF 报告生成,适用于 .NET、Xamarin.iOS、Xamarin.Android、Xamarin.Mac、Windows Phone 和 Windows Store 功能概述 使用 FlexCel Studio for .NET 创建可动态快速读写 Excel 文件的…...

多输入多输出 | MATLAB实现PSO-BP粒子群优化BP神经网络多输入多输出
多输入多输出 | MATLAB实现PSO-BP粒子群优化BP神经网络多输入多输出 目录 多输入多输出 | MATLAB实现PSO-BP粒子群优化BP神经网络多输入多输出预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 Matlab实现PSO-BP粒子群优化BP神经网络多输入多输出预测 1.data为数据…...

操作系统:系统引导以及虚拟机
1.操作系统引导的过程 ①CPU从一个特定主存地址开始取指令,执行ROM中的引导程序(先进行硬件自检,再开机)②将磁盘的第一块:主引导记录读入内存,执行磁盘引导程序,扫描分区表③从活动分区(又称主…...

AIGC绘本——海马搬家来喽
随着ChatGPT的快速发展,人工智能领域也发生了翻天覆地的变化。今天,我们迎合科技潮流,利用AIGC的强大能力,可以创作很多精彩的作品,比如这样一本名为《海马搬家》的绘本(注:此绘本根据同名儿童故…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...