运动模型非线性扩展卡尔曼跟踪融合滤波算法(Matlab仿真)

        卡尔曼滤波的原理和理论在CSDN已有很多文章,这里不再赘述,仅分享个人的理解和Matlab仿真代码。

1 单目标跟踪

        匀速转弯(CTRV)运动模型下,摄像头输出目标状态camera_state = [x, y, theta, v],雷达输出目标状态radar_state = [x, y, theta, v]。如果状态为[x, y, vx, vy],也可以转成[x, y, theta, v]。其中theta=atan(vy/vx),v=sqrt(vx*vx + vy*vy),测量噪声设置要相应改变。

        目标运动状态可以表示为:

        由于存在非线性,可以用一阶泰勒展开的雅可比矩阵做线性化,考虑到w的除0情况,区分w=0或w≠0的结果。

        w≠0时,

        w=0时,

        估计值和测量值为线性关系,状态观测矩阵可以用下面的矩阵表示。

        

        和线性卡尔曼滤波的对比如下:

        这里由于测量和估计是线性关系,因此后验估计和卡尔曼滤波一样,直接用H矩阵。将上述公式用matlab编程即可得到滤波结果。

% 匀速转弯运动模型的扩展卡尔曼滤波算法仿真
% 目标的测量值为x,y,theta,v
clc;clear;close all;

% 匀速转弯运动的初始值
x0 = 0;                                     % 目标的初始横向位置
y0 = 0;                                     % 目标的初始纵向位置
theta = 0;                                  % 目标的偏航角(目标在当前坐标系下和x轴的夹角)
v = 3;                                      % 目标的速度
omga = 0.1;                                 % 目标的偏航角速度
N = 150;                                    % 数据量
dt = 0.2;                                   % 单帧时间
t = dt*(1:1:N);                             % 时间轴

% 更新超参数
sigma_q_x = 0.2;
sigma_q_y = 0.2;
sigma_q_theta = 0.01;
sigma_q_v = 0.1;
sigma_q_omga = 0.01;
Q_mat_ctrv = diag([sigma_q_x^2, sigma_q_y^2, sigma_q_theta^2, sigma_q_v^2, sigma_q_omga^2]);
sigma_R_ctrv = 0.4;
R_ctrv = diag([sigma_R_ctrv^2, sigma_R_ctrv^2, sigma_R_ctrv^2, sigma_R_ctrv^2]);

% 初始化参数
Xest_ekf = zeros(5, N);
P_ekf = zeros(5, 5, N);
P_ekf(:,:,1) = eye(5);
Z_ctrv = zeros(4, N);                               % 4维测量向量
H_ctrv = [1 0 0 0 0;
          0 1 0 0 0;
          0 0 1 0 0;
          0 0 0 1 0];
X_ctrv = zeros(5, N);
X_ctrv(:,1) = [1; 1; 0; 1; 0.1];                    % 初始状态,包括位置、偏航角、速度和偏航角速度
V_ctrv = mvnrnd(zeros(1,4), R_ctrv)';               % 观测误差矩阵
Z_ctrv(:,1) = H_ctrv * X_ctrv(:, 1) + V_ctrv;
Xest_ekf(1:4,1) = Z_ctrv(:,1);

% 扩展卡尔曼滤波的核心算法
for i = 2:N
    % 状态更新
    X_ctrv(:,i) = ekf_predict(X_ctrv(:,i-1), dt);
    W_ctrv = mvnrnd(zeros(1,5), Q_mat_ctrv)';       % 过程噪声向量
    X_ctrv(:,i) = X_ctrv(:,i) + W_ctrv;             % 加过程噪声

    % 预测步骤
    Xest_ekf(:,i) = ekf_predict(Xest_ekf(:,i-1), dt);
    F = ekf_jacobian(Xest_ekf(:,i-1), dt);
    P_ekf(:,:,i) = F * P_ekf(:,:,i-1) * F' + Q_mat_ctrv;

    % 测量模型更新
    V_ctrv = mvnrnd(zeros(1,4), R_ctrv)';           % 观测误差矩阵
    Z_ctrv(:,i) = H_ctrv * X_ctrv(:, i) + V_ctrv;

    % 更新步骤
    H_ekf = H_ctrv;                                 % 测量模型的雅可比矩阵
    K_ekf = P_ekf(:,:,i) * H_ekf' / (H_ekf * P_ekf(:,:,i) * H_ekf' + R_ctrv);
    Xest_ekf(:,i) = Xest_ekf(:,i) + K_ekf * (Z_ctrv(:,i) - H_ekf * Xest_ekf(:,i));
    P_ekf(:,:,i) = (eye(5) - K_ekf * H_ekf) * P_ekf(:,:,i); 
end

% 绘图部分保持不变
figure;
size = 10;
width = 2;
% 位置曲线图
subplot(2,2,1);
plot(Z_ctrv(1,:),'.g','MarkerSize',size); hold on;              % 画出测量值
plot(Xest_ekf(1,:),'b','LineWidth',width);hold on;              % 画出最优估计值
plot(X_ctrv(1,:),'r','LineWidth',width);                        % 画出实际状态值
title('X位置状态曲线');
legend('位置测量值', '位置最优估计值', '实际位置');

% 位置曲线图
subplot(2,2,2);
plot(Z_ctrv(2,:),'.g','MarkerSize',size);hold on;               % 画出测量值
plot(Xest_ekf(2,:),'b','LineWidth',width);hold on;              % 画出最优估计值
plot(X_ctrv(2,:),'r','LineWidth',width);                        % 画出实际状态值
title('Y位置状态曲线');
legend('位置测量值', '位置最优估计值', '实际位置');

% 偏航角曲线图
subplot(2,2,3);
plot(Z_ctrv(3,:),'.g','MarkerSize',size); hold on;              % 画出测量值
plot(Xest_ekf(3,:),'b','LineWidth',width); hold on;             % 画出最优估计值
plot(X_ctrv(3,:),'r','LineWidth',width);                        % 画出实际状态值
title('偏航角状态曲线');
legend('偏航角测量值', '偏航角最优估计值', '实际偏航角');

% 速度曲线图
subplot(2,2,4);
plot(Z_ctrv(4,:),'.g','MarkerSize',size); hold on;              % 画出测量值
plot(Xest_ekf(4,:),'b','LineWidth',width); hold on;             % 画出最优估计值
plot(X_ctrv(4,:),'r','LineWidth',width);                        % 画出实际状态值
title('速度状态曲线');
legend('速度测量值', '速度最优估计值', '实际速度');

% 位置平面图
% figure;
% plot(Z_ctrv(1,:),Z_ctrv(2,:));hold on;          % 画出测量值
% plot(Xest_ekf(1,:),Xest_ekf(2,:));              % 画出最优估计值
% plot(X_ctrv(1,:),X_ctrv(2,:));hold on;          % 画出实际值
% title('目标运动曲线');
% legend('位置测量值', '位置最优估计值', '实际位置');

% 扩展卡尔曼滤波的预测模型
function x_pred = ekf_predict(x, dt)
    % CTRV模型的预测模型
    theta = x(3);
    v = x(4);
    omega = x(5);

    if omega == 0 % 避免除以0
        dx = v * cos(theta) * dt;
        dy = v * sin(theta) * dt;
    else
        dx = v/omega * (sin(theta + omega * dt) - sin(theta));
        dy = v/omega * (-cos(theta + omega * dt) + cos(theta));
    end

    dtheta = omega * dt;
    
    x_pred = x + [dx; dy; dtheta; 0; 0];              % 速度和转向率的变化假设为0
end

% 根据推导的公式计算状态转移雅可比矩阵
function F = ekf_jacobian(x, dt)
    theta = x(3);
    v = x(4);
    omega = x(5);

    F = eye(5);

    if omega == 0 % 避免除以0
        F(1, 3) = -v * sin(theta) * dt;
        F(1, 4) = cos(theta) * dt;
        F(2, 3) = v * cos(theta) * dt;
        F(2, 4) = sin(theta) * dt;
    else
        F(1, 3) = v/omega * (cos(theta + omega * dt) - cos(theta));
        F(1, 4) = 1/omega * (sin(theta + omega * dt) - sin(theta));
        F(1, 5) = v/omega^2 * (sin(theta) - sin(theta + omega * dt)) + v * dt * cos(theta + omega * dt)/omega;
        F(2, 3) = v/omega * (sin(theta + omega * dt) - sin(theta));
        F(2, 4) = 1/omega * (-cos(theta + omega * dt) + cos(theta));
        F(2, 5) = v/omega^2 * (-cos(theta) + cos(theta + omega * dt)) + v * dt * sin(theta + omega * dt)/omega;
    end

    F(3, 5) = dt;
end

        下图仿真运行的结果,这个文件仿真了单个匀速转弯扩展卡尔曼滤波算法结果。

2 多传感器融合定位跟踪 

        如果是两个或多个目标,类似线性卡尔曼跟踪融合滤波算法(Matlab仿真)-CSDN博客中的融合仿真算法,分别交错仿真摄像头和雷达目标,代码如下。

% 匀速转弯运动模型的扩展卡尔曼滤波算法仿真
% 摄像头和雷达的测量值为x,y,theta,v
clc;clear;close all;

% 匀速转弯运动的初始值
x0 = 0;                                     % 目标的初始横向位置
y0 = 0;                                     % 目标的初始纵向位置
theta = 0;                                  % 目标的偏航角(目标在当前坐标系下和x轴的夹角)
v = 3;                                      % 目标的速度
omga = 0.1;                                 % 目标的偏航角速度
N = 150;                                    % 数据量
dt = 0.2;                                   % 单帧时间
t = dt*(1:1:N);                             % 时间轴

% 更新超参数
sigma_q_x = 0.2;
sigma_q_y = 0.2;
sigma_q_theta = 0.01;
sigma_q_v = 0.1;
sigma_q_omga = 0.01;
Q_matrix_ctrv = diag([sigma_q_x^2, sigma_q_y^2, sigma_q_theta^2, sigma_q_v^2, sigma_q_omga^2]);
% 设置测量噪声协方差矩阵R,噪声来自测量的误差
sigma_r_x = 1.0;
sigma_r_y = 0.2; 
sigma_r_theta = 0.01; 
sigma_r_v = 0.5;
R_matrix_ctrv_camera = diag([sigma_r_x^2, sigma_r_y^2, sigma_r_theta^2, sigma_r_v^2]);
% 上面是摄像头噪声协方差矩阵,下面是雷达噪声协方差矩阵
sigma_r_x = 0.4;
sigma_r_y = 0.4; 
sigma_r_theta = 0.01; 
sigma_r_v = 0.1;
R_matrix_ctrv_radar = diag([sigma_r_x^2, sigma_r_y^2, sigma_r_theta^2, sigma_r_v^2]);

% 初始化参数
Xest_ekf = zeros(5, N);
P_ekf = zeros(5, 5, N);
P_ekf(:,:,1) = eye(5);
Z_ctrv = zeros(4, N);                               % 4维测量向量
H_ctrv = [1 0 0 0 0;
          0 1 0 0 0;
          0 0 1 0 0;
          0 0 0 1 0];
X_ctrv = zeros(5, N);
X_ctrv(:,1) = [1; 1; 0; 1; 0.1];                    % 初始状态,包括位置、偏航角、速度和偏航角速度
R_matrix_ctrv = R_matrix_ctrv_camera;               % 第1帧为摄像头
V_ctrv = mvnrnd(zeros(1,4), R_matrix_ctrv)';        % 观测误差矩阵
Z_ctrv(:,1) = H_ctrv * X_ctrv(:, 1) + V_ctrv;
Xest_ekf(1:4,1) = Z_ctrv(:,1);

% 扩展卡尔曼滤波的核心算法
for i = 2:N
    % 选择摄像头或雷达,摄像头是奇数帧,雷达是偶数帧
    if mod(i,2) == 1
        R_matrix_ctrv = R_matrix_ctrv_camera;
    else
        R_matrix_ctrv = R_matrix_ctrv_radar;
    end
    % 状态更新
    X_ctrv(:,i) = ekf_predict(X_ctrv(:,i-1), dt);
    W_ctrv = mvnrnd(zeros(1,5), Q_matrix_ctrv)';        % 过程噪声向量
    X_ctrv(:,i) = X_ctrv(:,i) + W_ctrv;                 % 加过程噪声

    % 预测步骤
    Xest_ekf(:,i) = ekf_predict(Xest_ekf(:,i-1), dt);
    F = ekf_jacobian(Xest_ekf(:,i-1), dt);
    P_ekf(:,:,i) = F * P_ekf(:,:,i-1) * F' + Q_matrix_ctrv;

    % 测量模型更新
    V_ctrv = mvnrnd(zeros(1,4), R_matrix_ctrv)';            % 观测误差矩阵
    Z_ctrv(:,i) = H_ctrv * X_ctrv(:, i) + V_ctrv;

    % 更新步骤
    H_ekf = H_ctrv;                                         % 测量模型的雅可比矩阵
    K_ekf = P_ekf(:,:,i) * H_ekf' / (H_ekf * P_ekf(:,:,i) * H_ekf' + R_matrix_ctrv);
    Xest_ekf(:,i) = Xest_ekf(:,i) + K_ekf * (Z_ctrv(:,i) - H_ekf * Xest_ekf(:,i));
    P_ekf(:,:,i) = (eye(5) - K_ekf * H_ekf) * P_ekf(:,:,i); 
end

% 绘图部分保持不变
figure;
size = 10;
width = 2;
% 位置曲线图
subplot(2,2,1);
plot(Z_ctrv(1,:),'.g','MarkerSize',size); hold on;              % 画出测量值
plot(Xest_ekf(1,:),'b','LineWidth',width);hold on;              % 画出最优估计值
plot(X_ctrv(1,:),'r','LineWidth',width);                        % 画出实际状态值
title('X位置状态曲线');
legend('位置测量值', '位置最优估计值', '实际位置');

% 位置曲线图
subplot(2,2,2);
plot(Z_ctrv(2,:),'.g','MarkerSize',size);hold on;               % 画出测量值
plot(Xest_ekf(2,:),'b','LineWidth',width);hold on;              % 画出最优估计值
plot(X_ctrv(2,:),'r','LineWidth',width);                        % 画出实际状态值
title('Y位置状态曲线');
legend('位置测量值', '位置最优估计值', '实际位置');

% 偏航角曲线图
subplot(2,2,3);
plot(Z_ctrv(3,:),'.g','MarkerSize',size); hold on;              % 画出测量值
plot(Xest_ekf(3,:),'b','LineWidth',width); hold on;             % 画出最优估计值
plot(X_ctrv(3,:),'r','LineWidth',width);                        % 画出实际状态值
title('偏航角状态曲线');
legend('偏航角测量值', '偏航角最优估计值', '实际偏航角');

% 速度曲线图
subplot(2,2,4);
plot(Z_ctrv(4,:),'.g','MarkerSize',size); hold on;              % 画出测量值
plot(Xest_ekf(4,:),'b','LineWidth',width); hold on;             % 画出最优估计值
plot(X_ctrv(4,:),'r','LineWidth',width);                        % 画出实际状态值
title('速度状态曲线');
legend('速度测量值', '速度最优估计值', '实际速度');

% 分别提取摄像头和雷达目标
% 确定摄像头和雷达帧数
if mod(N,2) == 0
    N_camera = N/2;
    N_radar = N/2;
else
    N_camera = floor(N/2) + 1;
    N_radar = floor(N/2);
end
Z_ctrv_camera = zeros(4,N_camera);
Z_ctrv_radar = zeros(4,N_radar);
camera_frame = zeros(1,N_camera);
radar_frame = zeros(1,N_radar);
camera_count = 0;
radar_count = 0;
% 提取摄像头和雷达帧的数据,摄像头在奇数帧,雷达在偶数帧
for i = 1:N
    if mod(i,2) == 1                                        
        camera_count = camera_count + 1;
        camera_frame(camera_count) = i;
        Z_ctrv_camera(:,camera_count) = Z_ctrv(:,i);            % 摄像头数据
    else
        radar_count = radar_count + 1;
        radar_frame(radar_count) = i;
        Z_ctrv_radar(:,radar_count) = Z_ctrv(:,i);              % 雷达数据
    end
end

% 绘图部分保持不变
figure;size = 10;width = 2;
% X位置曲线图
subplot(2,2,1);
plot(camera_frame,Z_ctrv_camera(1,:),'.g','MarkerSize',size); hold on;                % 画出测量值
plot(radar_frame,Z_ctrv_radar(1,:),'.k','MarkerSize',size); hold on;                  % 画出测量值
plot(Xest_ekf(1,:),'b','LineWidth',width);hold on;                                    % 画出最优估计值
plot(X_ctrv(1,:),'r','LineWidth',width);                                              % 画出实际状态值
title('X位置状态曲线');
legend('摄像头位置测量值', '雷达位置测量值','位置最优估计值', '实际位置');

% Y位置曲线图
subplot(2,2,2);
plot(camera_frame,Z_ctrv_camera(2,:),'.g','MarkerSize',size); hold on;                % 画出测量值
plot(radar_frame,Z_ctrv_radar(2,:),'.k','MarkerSize',size); hold on;                  % 画出测量值
plot(Xest_ekf(2,:),'b','LineWidth',width);hold on;                                    % 画出最优估计值
plot(X_ctrv(2,:),'r','LineWidth',width);                                              % 画出实际状态值
title('Y位置状态曲线');
legend('摄像头位置测量值', '雷达位置测量值','位置最优估计值', '实际位置');

% 偏航角曲线图
subplot(2,2,3);
plot(camera_frame,Z_ctrv_camera(3,:),'.g','MarkerSize',size); hold on;                % 画出测量值
plot(radar_frame,Z_ctrv_radar(3,:),'.k','MarkerSize',size); hold on;                  % 画出测量值
plot(Xest_ekf(3,:),'b','LineWidth',width); hold on;                                   % 画出最优估计值
plot(X_ctrv(3,:),'r','LineWidth',width);                                              % 画出实际状态值
title('偏航角状态曲线');
legend('偏航角测量值', '偏航角测量值', '偏航角最优估计值', '实际偏航角');

% 速度曲线图
subplot(2,2,4);
plot(camera_frame,Z_ctrv_camera(4,:),'.g','MarkerSize',size); hold on;                % 画出测量值
plot(radar_frame,Z_ctrv_radar(4,:),'.k','MarkerSize',size); hold on;                  % 画出测量值
plot(Xest_ekf(4,:),'b','LineWidth',width); hold on;                                   % 画出最优估计值
plot(X_ctrv(4,:),'r','LineWidth',width);                                              % 画出实际状态值
title('速度状态曲线');
legend('摄像头速度测量值', '雷达速度测量值', '速度最优估计值', '实际速度');

% 位置平面图
% figure;
% plot(Z_ctrv(1,:),Z_ctrv(2,:));hold on;          % 画出测量值
% plot(Xest_ekf(1,:),Xest_ekf(2,:));              % 画出最优估计值
% plot(X_ctrv(1,:),X_ctrv(2,:));hold on;          % 画出实际值
% title('目标运动曲线');
% legend('位置测量值', '位置最优估计值', '实际位置');

% 扩展卡尔曼滤波的预测模型
function x_pred = ekf_predict(x, dt)
    % CTRV模型的预测模型
    theta = x(3);
    v = x(4);
    omega = x(5);

    if omega == 0 % 避免除以0
        dx = v * cos(theta) * dt;
        dy = v * sin(theta) * dt;
    else
        dx = v/omega * (sin(theta + omega * dt) - sin(theta));
        dy = v/omega * (-cos(theta + omega * dt) + cos(theta));
    end

    dtheta = omega * dt;
    
    x_pred = x + [dx; dy; dtheta; 0; 0]; % 速度和转向率的变化假设为0
end

function F = ekf_jacobian(x, dt)
    theta = x(3);
    v = x(4);
    omega = x(5);

    F = eye(5);

    if omega == 0 % 避免除以0
        F(1, 3) = -v * sin(theta) * dt;
        F(1, 4) = cos(theta) * dt;
        F(2, 3) = v * cos(theta) * dt;
        F(2, 4) = sin(theta) * dt;
    else
        F(1, 3) = v/omega * (cos(theta + omega * dt) - cos(theta));
        F(1, 4) = 1/omega * (sin(theta + omega * dt) - sin(theta));
        F(1, 5) = v/omega^2 * (sin(theta) - sin(theta + omega * dt)) + v * dt * cos(theta + omega * dt)/omega;
        F(2, 3) = v/omega * (sin(theta + omega * dt) - sin(theta));
        F(2, 4) = 1/omega * (-cos(theta + omega * dt) + cos(theta));
        F(2, 5) = v/omega^2 * (-cos(theta) + cos(theta + omega * dt)) + v * dt * sin(theta + omega * dt)/omega;
    end

    F(3, 5) = dt;
end

       仿真代码给出摄像头和雷达目标定位跟踪融合的结果,第一张图的测量值没有区分摄像头和雷达,第二张图做了区分。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【浅尝C++】引用

🎈归属专栏:浅尝C 🚗个人主页:Jammingpro 🐟记录一句:大半夜写博客的感觉就是不一样!! 文章前言:本篇文章简要介绍C中的引用,每个介绍的技术点,在…

井盖异动传感器,守护脚下安全

随着城市化进程的加速,城市基础设施的安全问题日益受到关注。其中,井盖作为城市地下管道的重要入口,其安全问题不容忽视。然而,传统的井盖监控方式往往存在盲区,无法及时发现井盖的异常移动。为此,我们推出…

数据库与低代码:加速开发,提升效率的完美结合

随着技术的不断进步,数据库和低代码开发成为了现代应用程序开发中的两大关键要素。本文将探讨如何通过结合数据库和低代码开发,加速应用程序的开发过程,并提高开发效率和质量。 在过去的几十年中,数据库一直被视为应用程序开发中不…

【Linux进程】查看进程fork创建进程

目录 前言 1. 查看进程 2. 通过系统调用创建进程-fork初识 总结 前言 你有没有想过在使用Linux操作系统时,后台运行的程序是如何管理的?在Linux中,进程是一个非常重要的概念。本文将介绍如何查看当前运行的进程,并且讨论如何使用…

Sip - Ubuntu 配置 miniSIPServer 服务器(测试用)

客户提供的账号过期了,简单搭建 SIP 服务器,以便测试使用。个人认为这个配置起来最为简单,且测试功能足够。 官网miniSIPServer - 基于 Windows 以及 Linux 平台的 VoIP (SIP) 服务器软件. miniSIPServer 可能是最容易使用的 VoIP(SIP) 服务器…

获取进行逗号分隔的id值 Split的使用

获取进行逗号分隔的id值,Split的使用 后台实现对有逗号进行分割的字符串 使用这行代码就不会有一个空数组值,直接过滤调数组中的空值 var ids = key.Split(,).Where(s => !string.IsNullOrEmpty(s

进行交流负载测试的步骤和规范

交流负载测试是一种评估系统在正常或峰值负载下的性能和稳定性的测试方法。以下是进行交流负载测试的步骤和规范: 1. 确定测试目标:首先,需要明确测试的目标,例如,测试系统的响应时间、吞吐量、错误率等。 2. 设计测试…

Linux系统操作命令

Linux管理 在线查询Linux命令: https://www.runoob.com/linux/linux-install.htmlhttps://www.linuxcool.com/https://man.linuxde.net/ 1.Linux系统目录结构 Linux系统的目录结构是一个树状结构,每一个文件或目录都从根目录开始,并且根目…

双亲委派机制[人话版]

本篇文章仅作为记录学习之用,不具有参考价值. 如果您想系统学习,请移步最下方参考资料. 介绍 今天逛了一下牛客网, 看到有面试问到了双亲委派机制是什么, tomcat有没有打破双亲委派 , 瞬间懵逼, 听都没听过的名字, 听着就稀奇古怪. 然后翻了一下网上的答案,大概了解怎么回事.…

Python自动化测试数据驱动解决数据错误

数据驱动将测试数据和测试行为完全分离,实施数据驱动测试步骤如下: A、编写测试脚本,脚本需要支持从程序对象、文件或者数据库读入测试数据; B、将测试脚本使用的测试数据存入程序对象、文件或者数据库等外部介质中;…

知识库软件有很多,这几个最好用

时代进步的同时,逐渐优化的企业知识库已经成为企业优化工作效率、提升企业竞争力的重要工具。随着云计算和大数据技术的快速发展,知识库软件如雨后春笋般出现在人们的视野中。下面,我从寻宝者的角度,向大家稳稳地推荐三款最优秀的…

mp-html 微信原生小程序渲染富文本

引入组件 "usingComponents": {"mp-html": "/components/mp-html/index"}使用 <mp-html content"{{info.course_info.info}}" />获取组件 介绍 mp-html&#xff0c;小程序富文本解析利器 全面支持html标签 小程序大多数都是…

C++重新认知:拷贝构造函数

一、什么是拷贝构造函数 对于简单变量来说&#xff0c;可以轻松完成拷贝。 int a 10; int b a;但是对于复杂的类对象来说&#xff0c;不仅存在变量成员&#xff0c;也存在各种函数等。因此相同类型的类对象是通过拷贝构造函数来完成复制过程的。 #include<iostream>…

使用Notepad++将多行数据合并成一行

步骤 1、按CtrlF&#xff0c;弹出“替换”的窗口&#xff1b; 2、选择“替换”菜单&#xff1b; 3、“查找目标”内容输入为&#xff1a;\r\n&#xff1b; 4、“替换为”内容为空&#xff1b; 5、“查找模式”选择为正则表达式&#xff1b; 6、设置好之后&#xff0c;点击“全…

Spring Data JPA 踩过的坑实录

前言 游戏中台一直在使用spring 全家桶&#xff0c; 本文会左右使用Spring Data JPA的坑点记录总结 主要给大家总结介绍了关于使用Spring JPA注意事项及踩过的坑。 案例1&#xff1a; 为什么只调用了 org.springframework.data.repository.CrudRepository#findById(ID id) 却…

STM32入门教程-2023版【3-4】总结GPIO使用方法

三、总结GPIO使用方法 总体上来说是比较简单的 首先初始化时钟&#xff0c;然后定义结构体&#xff0c;赋值结构体 GPIO_Mode可以选择那8种输入输出模式&#xff0c;GPIO_Pin选择引脚&#xff0c;可以用按位或的方式同时选中多个引脚,GPIO_Speed选择输出速度&#xff0c;最后使…

基于springboot+vue的个人健康管理系统(有文档、Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

《异侠传S1赛季侠义九州》公测版本三端互通PC客户端与IOS下载地址!!!

尊敬的各位异侠玩家们&#xff1a; 我们怀着无比激动的心情&#xff0c;充满感激地向大家宣布&#xff1a;今天上午10&#xff1a;00我们即将迎来《异侠传S1赛季&#xff1a;侠义九州》的首发公测&#xff01;在这个特殊的时刻&#xff0c;我们想将我们最诚挚的感谢献给每一位…

MES管理系统解决方案在汽配企业中的重要性

在汽车制造业中&#xff0c;MES管理系统解决方案已成为引领精益生产的关键要素。该系统专注于监控和管理汽车生产流程&#xff0c;利用实时数据分析和采集技术&#xff0c;为企业提供了提高效率、降低成本和确保高质量产品的有效手段。本文将详细介绍汽配企业MES管理系统的特点…

MindOpt:阿里巴巴达摩院打造的优化求解器及其组件全面介绍

MindOpt 简介和获取 MindOpt 是阿里巴巴达摩院决策智能实验室研发的决策优化软件。团队组建于2019年&#xff0c;聚焦于研发尖端运筹优化和机器学习技术&#xff0c;构建智能决策系统&#xff0c;更快更好地向各行各业提供数学建模与求解能力&#xff0c;帮助业务更快更好地做…
最新文章