GPOPS-II教程(1): 语法和一个最优控制问题案例

文章目录

  • 一、写在前面
  • 二、GPOPS-II结构
    • 2.1 setup的语法
    • 2.2 function的语法
      • 2.2.1 setup.functions.continuousfun
      • 2.2.2 setup.functions.endpoint
    • 2.3 bounds的语法
        • setup.guess
        • output
  • 三、例题
    • 3.1 问题描述
    • 3.2 代码部分
      • 3.2.1 `main function`
        • 3.2.1.1 初始参数设置
        • 3.2.1.2 边界条件设置
        • 3.2.1.3 初值猜测
        • 3.2.1.4 设置GPOPS-II求解器参数
        • 3.2.1.5 求解
        • 3.2.1.6 画图
      • 3.2.2 `continuous function`
      • 3.2.3 `endpoint function`
    • 3.3 结果分析
    • 3.4 完整代码

原文链接:https://leilie.top/2024-06-20/Study-GPOPS-II-guidance-1

一、写在前面

很多同学都在用GPOPS-II做轨迹优化,我在后台里也看见了许许多多的问题来问我。所以想写一个教程,把一些GPOPS-II的例子讲讲,从这些例子中教会如何使用GPOPS-II。

这个教程会分成几个部分,前面几个部分会讲解GPOPS-II的官方案例。通过讲解这些官方案例,说明GPOPS-II的语法应该怎么写,会有什么样的trips。

然后会给出一个总结,总结内容是关于使用GPOPS-II遇见不同问题时,有什么样共性的解决方法,以及各类针对性的解决方法。最后行有余力,给出一个如何调试BUG的教程。

参考文章:

  1. GPOPS-II教程
  2. A general-purpose MATLAB software for solving multiple-phase optimal control problems
  3. A general-purpose MATLAB toolbox for solving optimal control problems using variable-order gaussian quadrature collocation methods

二、GPOPS-II结构

GPOPS-II主要由3部分组成:

  • 主函数 main function:用于设置求解问题的各类初始参数,配置GPOPS参数,进行计算并得出结果。
  • 连续函数 continuous function:用于表示求解问题的动力学关系,计算每个阶段的被积函数和路径约束。
  • 端点函数 endpoint function:用于定义各个阶段初始点和终端点的值,计算求解问题的成本(性能指标)。

main function里,要指定求解问题的上下限,以一个阶段(phase)为例,一般包括如下几类:

  • 边界条件 bounds
    • 初始时间、终端时间
    • 初始状态、终端状态
    • 控制量
    • 积分量
  • 初值猜测 guess
    • 初始时间、终端时间
    • 初始状态、终端状态
    • 控制量
    • 积分量
  • 路径约束 path
  • 事件约束 event
  • 静态参数 auxdata

上述变量,统一被 setup 纳入结构体变量之中。可写作

ouput = gpops2(setup)

其中,其中setup是一个用户定义的结构体变量,该结构体变量包含有关要解决的最优控制问题的所有信息;output是一个结构体变量,其包含通过解决最优控制的问题而获得的信息。下面对setup进行详细解释。

2.1 setup的语法

setup包含必填字段和可选字段。setup中的必填字段如下:

  • name:不带空格的字符串,对要求解问题的描述;
  • function:包含连续函数continuous function和端点函数endpoint function的结构体;
  • bounds:包含变量和约束的上下限信息的结构体;
  • guess:包含对问题中的时间、状态、控制、积分和静态参数的猜测的结构体。

可选字段如下:

  • auxdata:辅助数据的结构体,这样就可以不使用全局变量而使用auxdata.args来传递求解问题时所需要用到的部分常量。(args代表任意需要命名的参数,即参数arguments的缩写,无实际意义。)

  • derivatives:指定 NLP 求解器所使用的导数近似和 NLP 求解器所使用的导数阶次(firstsecond)的结构。衍生字段包含

    • derivatives.supplier:NLP 求解器所使用的导数近似,可选值为sparseFD, sparseBD, sparseCD,默认值为 sparseFD
    • derivatives.derivativelevel:NLP 求解器使用的导数阶次,可选值为 first, second,默认值为 first
    • derivatives.dependencies:NLP 求解器的依赖关系,可选值为 full, sparse, spareseNaN,默认值为 sparseNaN
  • scales:求解问题时要使用的尺度类型,可选项为noneautomatic-bounds,默认值为none

  • mesh:求解问题的网格细化方法,包括网格细化类型、精度公差及初始网格。衍生字段包含

    • mesh.method:网格细化方法,可选值为 hp, hp1,默认值为hp1
    • mesh.options.tolerance:网格要求的精度容差,为0到1之间的正数,默认值为 10 10 10
    • mesh.options.maxiteration:网格细化最大的迭代次数,为非负整数,默认值为 1 0 − 3 10^{-3} 103
    • mesh.colpointsmin:网格间隔中配置点最小数量,默认值为 3 3 3
    • mesh.colpointsmax:网格间隔中配置点最大数量,默认值为 10 10 10
    • mesh.phase.fraction:每个阶段的网络间隔,是一个0到1的缩放区间,N个间隔,行向量加起来等于1,默认值为0.1*ones(1,10)
    • mesh.phase.colpoints:每个阶段的配置点,也是行向量,默认值为4*ones(1,10)
  • nlp:要使用的 NLP 求解器类型结构体,可选字段包含

    • nlp.solver:求解器类型,可选值为 snopt, ipopt
    • nlp.ipoptoptions
      • nlp.ipoptoptions.linear_solvermumps or ma57
      • nlp.ipoptoptions.tolerance:默认值 1 0 − 7 10^{-7} 107
      • nlp.ipoptoptions.maxiterations: 默认值为 2000 2000 2000
    • nlp.snoptoptions
      • nlp.snoptoptions.tolerance: 默认值为 1 0 − 6 10^{−6} 106
      • nlp.snoptoptions.maxiterations: 默认 2000 2000 2000

2.2 function的语法

指定连续函数和端点函数的函数句柄,代码为

setup.functions.continuous = @continuousfun
setup.functions.endpoint   = @endpointfun

2.2.1 setup.functions.continuousfun

格式为

f u n c t i o n o u t p u t = c o n t i n u o u s f u n ( i n p u t ) \rm function\ output = continuousfun(input) function output=continuousfun(input)

输入包括

  • input.phase(p).time:时间。
  • input.phase(p).state:状态量。
  • input.phase(p).control:控制量。
  • input.phase(p).parameter:静态参数量。

输出是一个长度为 P P P 的结构向量,包括

  • output.dynamics:微分状态。
  • output.path:路径约束。
  • output.integrand:积分。

2.2.2 setup.functions.endpoint

格式为

f u n c t i o n o u t p u t = e n d p o i n t f u n ( i n p u t ) \rm function\ output = endpointfun(input) function output=endpointfun(input)

输入包括

  • input.phase(p).initialtime:阶段p的起始时间。
  • input.phase(p).finaltime:阶段p的起始时间。
  • input.phase(p).initialstate:阶段p的起始状态。
  • input.phase(p).finalstate:阶段p的终止状态。
  • input.phase(p).integral:阶段p的积分。
  • input.parameter:阶段p的静态参数。

输出包括两个成员

  • output.objective:标量,目标函数。
  • output.eventgroup

2.3 bounds的语法

此处参考GPOPS-II教程。

包括3个成员:

  • bounds.phase: 指定了时间、状态、控制、路径约束和每个阶段的积分的界限。
    • phase.initialtime.lower: 起始时间的下界。
    • phase.initialtime.upper: 起始时间的上界。
    • phase(p).finaltime.lower: 终止时间的下界。
    • phase(p).finaltime.upper: 终止时间的上界。
    • phase(p).initialstate.lower: 初始状态的下界。
    • phase(p).initialstate.upper: 初始状态的上界。
    • phase(p).state.lower: 每个阶段状态的下界。
    • phase(p).state.upper: 每个阶段状态的上界。
    • phase(p).finalstate.lower: 终止状态的下界。
    • phase(p).finalstate.upper: 终止状态的上界。
    • phase(p).control.lower: 每个阶段控制的下界。
    • phase(p).control.upper: 每个阶段控制的上界。
    • phase(p).path.lower: 每个阶段路径约束的下界。
    • phase(p).path.upper: 每个阶段路径约束的上界。
    • phase(p).integral.lower: 每个阶段积分的下界。
    • phase(p).integral.upper: 每个阶段积分的上界。
    • phase(p).duration.lower: 每个阶段时间的下界。
    • phase(p).duration.upper: 每个阶段时间的上界。
  • bounds.parameters: 包含问题中静态参数的下界和上界。
  • bounds.eventgroup: 长度为G的结构数组,其中G是问题中事件组的数量。
setup.guess

guess结构体里面的值代表了整个求解过程的初始值

  • guess.phase(p).time: 阶段p的时间猜测。
  • guess.phase(p).state: 阶段p的状态量猜测。
  • guess.phase(p).control: 阶段p的控制量猜测。
  • guess.phase(p).integral: 阶段p的积分量猜测。
output

gpops2的输出包括

  • result
    • result.solution: 最优的时间、状态和控制以及静态参数。
      • solution.phase(p).time:时间。
      • solution.phase(p).state:状态量。
      • solution.phase(p).control:控制量。
      • solution.parameter:静态参数。
    • result.objective: 最优值。
    • result.setup:问题设置。
    • result.nextsetup
  • meshhistory: 对每个求解NLP的网格进行求解和误差估计。
  • meshiterations: 迭代次数。

上述内容参考自文章GPOPS-II教程,作者kunpeng,遵循CC BY 4.0协议。

三、例题

上面是GPOPS-II的语法部分,了解了GPOPS-II的语法之后,需要例题来帮助理解GPOPS-II的用法。这篇教程里针对一个典型最优控制问题讲解,通过这个理解希望能够让大家明白GPOPS-II中,main functioncontinuous functioinendpoint function怎么用。

3.1 问题描述

求解最优控制问题——有约束的停车能耗最优问题

初始时刻车辆位置为 x 1 ( 0 ) = − 2 x_1(0)=-2 x1(0)=2,速度为 x 2 ( 0 ) = 1 x_2(0)=1 x2(0)=1,状态方程为
{ x ˙ 1 ( t ) = x 2 ( t ) x ˙ 2 ( t ) = u ( t ) (1) \left\{\begin{matrix} \begin{aligned} \dot x_1(t) &= x_2(t) \\ \dot x_2(t) &= u(t) \end{aligned} \end{matrix}\right. \tag{1} {x˙1(t)x˙2(t)=x2(t)=u(t)(1)
容许控制为
∣ u ∣ ≤ M 1 = 1.5 (2) \left | u \right | \le M_1 =1.5 \tag{2} uM1=1.5(2)
终止条件为
x 1 ( t f ) = 0 , x 2 ( t f ) = 0 , t f = 2 (3) x_1(t_f)=0,\ x_2(t_f)=0,\ t_f=2 \tag{3} x1(tf)=0, x2(tf)=0, tf=2(3)
要最小化的性能指标为总能耗,其表达式为
J ( u ) = ∫ t 0 t f 1 2 u 2 ( t ) d t (4) J(u)=\int_{t_0}^{t_f}\frac{1}{2}u^2(t)\mathrm dt \tag{4} J(u)=t0tf21u2(t)dt(4)

3.2 代码部分

3.2.1 main function

一般会从main function开始写起。

3.2.1.1 初始参数设置

注意到状态初值为 x 1 ( 0 ) = − 2 x_1(0)=-2 x1(0)=2 x 2 ( 0 ) = 1 x_2(0)=1 x2(0)=1,终止条件里有 t f = 2 t_f=2 tf=2,控制约束为 ∣ u ∣ ≤ M 1 = 1.5 | u | \le M_1 =1.5 uM1=1.5。这些都是写代码时首先要加上的初始边界参数,也就是bounds,那么根据式 ( 2 ) (2) (2) ( 3 ) (3) (3)和初始条件,给出如下代码:

% 设置时间
t0 = 0;
tf = 2;
% 设置状态量初值
x10 = -2;
x20 = 1;
% 设置控制量边界条件
uMin  = -1.5;
uMax  = 1.5;
% 设置状态量边界条件
x1Min = -5;
x1Max = 5;
x2Min = -5;
x2Max = 5;

注意,最后4行代码

x1Min = -5;
x1Max = 5;
x2Min = -5;
x2Max = 5;

是按照自己的经验给出的值,不一定非要是这个数值。

3.2.1.2 边界条件设置

下面开始设置边界条件,给出代码如下。

ounds.phase.initialtime.lower  = t0;
bounds.phase.initialtime.upper  = t0;
bounds.phase.finaltime.lower    = tf; 
bounds.phase.finaltime.upper    = tf;
bounds.phase.initialstate.lower = [x10 x20]; 
bounds.phase.initialstate.upper = [x10 x20];
bounds.phase.state.lower        = [x1Min x2Min]; 
bounds.phase.state.upper        = [x1Max x2Max];
bounds.phase.finalstate.lower   = [0 0];
bounds.phase.finalstate.upper   = [0 0];
bounds.phase.control.lower      = uMin; 
bounds.phase.control.upper      = uMax;
bounds.phase.integral.lower     = 0; 
bounds.phase.integral.upper     = 10000;

上述代码的意义在上一章全部说明过,这里就不再赘述,只要根据问题的要求就能很自然地写出边界条件。

3.2.1.3 初值猜测

初值猜测的代码如下。

guess.phase.time     = [t0; tf]; 
guess.phase.state    = [[x10 x20];[0 0]];
guess.phase.control  = [1; uMin];
guess.phase.integral = 100;

写初值猜测的代码时,要注意符号。这里是加的是分号;

guess.phase.time = [t0; tf]; 为例,t0是初始时间的猜测值,tf是终端是时间的猜测值,用分号;隔开。其余行的代码同理。

多讲一句,有的同学可能看见第2行代码guess.phase.state = [[x10 x20];[0 0]];很迷糊,因为这里有2个变量。要注意,这个题目里是有2个状态量, x 1 x_1 x1 x 2 x_2 x2。所以在写初值猜测guess.phase.state时,也要写成2维变量。[x10 x20]为初始状态的猜测值,[0 0]为终端状态的猜测值。

很多同学问我这里的初值猜测是怎么给出的。

我的回答是只能凭经验给出

给初值有的时候需要一些运气,给得好,就算得准。

另外,因为该问题只有一个阶段,所以phase为默认值,没有给它设置数值。

3.2.1.4 设置GPOPS-II求解器参数

按照上一章的内容,设置GPOPS-II求解器参数,一般用setup作变量名称。代码如下。

setup.name = 'Vehicle-Stopping-OCP';
setup.functions.continuous  = @vsopcContinuous;
setup.functions.endpoint   	= @vsopcEndpoint;
setup.bounds                = bounds;
setup.guess                 = guess;
setup.nlp.solver            = 'snopt';
setup.derivatives.supplier  = 'sparseCD';
setup.derivatives.derivativelevel = 'second';
setup.mesh.method           = 'hp1';
setup.mesh.tolerance        = 1e-6;
setup.mesh.maxiteration     = 45;
setup.mesh.colpointsmax     = 4;
setup.mesh.colpointsmin     = 10;
setup.mesh.phase.fraction   = 0.1*ones(1,10);
setup.mesh.phase.colpoints  = 4*ones(1,10);
setup.method = 'RPMintegration';

上述代码已在前述章节中讲过,不再赘述。如果同学们在解决自己的问题时,发现求解效果不好的话,可以根据每个变量的选项选择更加合适的选项,优化求解效果。

3.2.1.5 求解

求解代码很简单,代码如下。

output = gpops2(setup);
solution = output.result.solution;

第1行代码是用GPOPS-II进行求解。可不能小看这短短1行代码,它背后的工作是很多很多很多的,GPOPS-II里围绕这个函数做了大量工作,有很多没有显现的函数都是为了GPOPS-II能够正常求解。

第2行代码是获得GPOPS-II求解结果。获得求解结果后,可以开始数据处理了。一般而言,数据处理的方式就是数据可视化(画图)、数据保存、数据分析。

3.2.1.6 画图

这里只给出画图的代码。数据保存和数据分析的代码按需自拟。

figure('Color',[1,1,1]);
plot(solution.phase.time(:,1),solution.phase.state(:,1),'-','LineWidth',1.5);hold on;
plot(solution.phase.time(:,1),solution.phase.state(:,2),'-.','LineWidth',1.5);
plot(solution.phase.time(:,1),solution.phase.control(:,1),'--','LineWidth',1.5);
axis([0 2 -2.5 2]);
xlabel('Time',...'FontWeight','bold');
ylabel('States',...'FontWeight','bold');
legend('Pos','Vel','Acc',...'LineWidth',1,...'EdgeColor',[1,1,1],...'Orientation','horizontal',...'Position',[0.5,0.93,0.40,0.055]);
set(gca,'FontName','Times New Roman',...'FontSize',15,...'LineWidth',1.3);
print -dpng Result.png

3.2.2 continuous function

这个部分是问题的动力学方程,防止大家忘记例题的动力学方程是什么样子,在这里再写一遍式 ( 1 ) (1) (1),公式如下。
{ x ˙ 1 ( t ) = x 2 ( t ) x ˙ 2 ( t ) = u ( t ) \left\{\begin{matrix} \begin{aligned} \dot x_1(t) &= x_2(t) \\ \dot x_2(t) &= u(t) \end{aligned} \end{matrix}\right. {x˙1(t)x˙2(t)=x2(t)=u(t)
根据动力学方程,写出对应的continuous function,代码如下。

function phaseout = vsopcContinuous(input)t  = input.phase.time;x2  = input.phase.state(:,2);u   = input.phase.control(:,1);dx1 = x2;dx2 = u;phaseout.dynamics = [dx1, dx2];phaseout.integrand = 0.5*u.^2;
end

dx1=x2dx2=u就是动力学方程。

phaseout.integrand = 0.5*u.^2;是性能指标的积分项。同样,再复习一遍该问题的性能指标形式,公式如下。
J ( u ) = ∫ t 0 t f 1 2 u 2 ( t ) d t J(u)=\int_{t_0}^{t_f}\frac{1}{2}u^2(t)\text{d}t J(u)=t0tf21u2(t)dt
代码和公式是相互对应的。

3.2.3 endpoint function

这个部分是问题的性能指标函数,即式 ( 4 ) (4) (4)。可以看出,这个问题的性能指标是积分项,所以代码可以像下面这么写:

function output = vsopcEndpoint(input)J  = input.phase.integral;output.objective = J;
end

3.3 结果分析

根据前述代码,可以得到如下图所示结果。
在这里插入图片描述

3.4 完整代码

这里给出完整代码。

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 功能描述:最优控制问题
% 文件名解释:main_Vehicle_Stopping_OCP.m 中,main 代表 主函数
%             Vehcle_Stopping 代表 停车能耗问题
%			  OCP 代表 最优控制问题.
% 作者:Lei Lie
% 时间:2024/06/21
% 版本:1.0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;clear;close all;
tic;
%% 01.初始参数设置
%-------------------------------------------------------------------------%
%----------------------- 设置问题的求解边界 ------------------------------%
%-------------------------------------------------------------------------%
% 设置时间
t0 = 0;
tf = 2;
% 设置状态量初值
x10 = -2;
x20 = 1;
% 设置状态量边界条件
x1Min = -5;
x1Max = 5;
x2Min = -5;
x2Max = 5;
% 设置控制量边界条件
uMin  = -1.5;
uMax  = 1.5;%% 02.边界条件设置
%-------------------------------------------------------------------------%
%------------------------ 将求解边界设置于问题中 -------------------------%
%-------------------------------------------------------------------------%
bounds.phase.initialtime.lower  = t0; 
bounds.phase.initialtime.upper  = t0;
bounds.phase.finaltime.lower    = tf; 
bounds.phase.finaltime.upper    = tf;
bounds.phase.initialstate.lower = [x10 x20]; 
bounds.phase.initialstate.upper = [x10 x20];
bounds.phase.state.lower        = [x1Min x2Min]; 
bounds.phase.state.upper        = [x1Max x2Max];
bounds.phase.finalstate.lower   = [0 0];
bounds.phase.finalstate.upper   = [0 0];
bounds.phase.control.lower      = uMin; 
bounds.phase.control.upper      = uMax;
bounds.phase.integral.lower     = 0; 
bounds.phase.integral.upper     = 10000;%% 03.初值猜测
%-------------------------------------------------------------------------%
%------------------------------- 初值猜想 --------------------------------%
%-------------------------------------------------------------------------%
guess.phase.time     = [t0; tf]; 
guess.phase.state    = [[x10 x20];[0 0]];
guess.phase.control  = [1; uMin];
guess.phase.integral = 100;%% 04.设置GPOPS求解器参数
%-------------------------------------------------------------------------%
%---------------------------- 设置求解器参数 -----------------------------%        
%-------------------------------------------------------------------------%
setup.name = 'Vehicle-Stopping-OCP';
setup.functions.continuous  = @vsopcContinuous;
setup.functions.endpoint   	= @vsopcEndpoint;
setup.bounds                = bounds;
setup.guess                 = guess;
setup.nlp.solver            = 'snopt';
setup.derivatives.supplier  = 'sparseCD';
setup.derivatives.derivativelevel = 'second';
setup.mesh.method           = 'hp1';
setup.mesh.tolerance        = 1e-6;
setup.mesh.maxiteration     = 45;
setup.mesh.colpointsmax     = 4;
setup.mesh.colpointsmin     = 10;
setup.mesh.phase.fraction   = 0.1*ones(1,10);
setup.mesh.phase.colpoints  = 4*ones(1,10);
setup.method = 'RPMintegration';%% 05.求解
%-------------------------------------------------------------------------%
%----------------------- 使用 GPOPS2 求解最优控制问题 --------------------%
%-------------------------------------------------------------------------%
output = gpops2(setup);
solution = output.result.solution;
toc;%% 06.画图
figure('Color',[1,1,1]);
plot(solution.phase.time(:,1),solution.phase.state(:,1),'-','LineWidth',1.5);hold on;
plot(solution.phase.time(:,1),solution.phase.state(:,2),'-.','LineWidth',1.5);
plot(solution.phase.time(:,1),solution.phase.control(:,1),'--','LineWidth',1.5);
axis([0 2 -2.5 2]);
xlabel('Time',...'FontWeight','bold');
ylabel('States',...'FontWeight','bold');
legend('Pos','Vel','Acc',...'LineWidth',1,...'EdgeColor',[1,1,1],...'Orientation','horizontal',...'Position',[0.5,0.93,0.40,0.055]);
set(gca,'FontName','Times New Roman',...'FontSize',15,...'LineWidth',1.3);
print -dpng Result.png%% 函数模块部分
% ----------------------------------------------------------------------- %
% ------------------------- BEGIN: vsopcContinuous.m -------------------- %
% ----------------------------------------------------------------------- %
function phaseout = vsopcContinuous(input)t  = input.phase.time;x2  = input.phase.state(:,2);u   = input.phase.control(:,1);dx1 = x2;dx2 = u;phaseout.dynamics = [dx1, dx2];phaseout.integrand = 0.5*u.^2;
end
% ----------------------------------------------------------------------- %
% -------------------------- END: vsopcContinuous.m --------------------- %
% ----------------------------------------------------------------------- %% ----------------------------------------------------------------------- %
% -------------------------- BEGIN: vsopcEndpoint.m --------------------- %
% ----------------------------------------------------------------------- %
function output = vsopcEndpoint(input)J  = input.phase.integral;output.objective = J;
end
% ----------------------------------------------------------------------- %
% --------------------------- END: vsopcEndpoint.m ---------------------- %
% ----------------------------------------------------------------------- %

欢迎通过邮件联系我:lordofdapanji@foxmail.com

来信请注明你的身份,否则恕不回信。

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

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

相关文章

安装VEX外部编辑器

Houdini20配置VEX外部编辑器方法_哔哩哔哩_bilibili 下载并安装Visual Studio Code软件:Download Visual Studio Code - Mac, Linux, Windows 在Visual Studio Code软件内,安装相关插件,如: 中文汉化插件vex插件 安装Houdini Expr…

图像处理Python库--图片裁剪、缩放、灰度图、圆角等

图像处理Python库 py-img-processor1. 安装2. 使用(Usage)2.1 运行配置2.2 图像处理处理函数图像处理参数为字符串图像处理参数为JSON 命令行提取图像主色调 py-img-processor Image editor using Python and Pillow. 依赖Pillow开发的Python库,用于图像编辑处理。…

nest.js关键笔记

Nest.js 介绍核心功能设计模式:IOC 控制反转 DI 依赖注入前置知识:装饰器前置知识装饰器-实现一个GET请求 Nestjs脚手架Nestjs cli 常用命令 RESTful 风格设计Nestjs 控制器控制器中常见的参数装饰器 Session 实例Nestjs 提供者**工厂模式**异步模式 Nes…

【Unity服务器01】之【AssetBundle上传加载u3d模型】

首先打开一个项目导入一个简单的场景 导入怪物资源, AssetBundle知识点: 1.指定资源的AssetBundle属性标签 (1)找到AssetBundle属性标签 (2)A标签 代表:资源目录(决定打包之后在哪…

如何给文档设置密码?电脑文件安全加密的详细操作步骤(10种方法)

在数字化时代,电脑文件的安全和隐私至关重要。通过给电脑的文件或者文件夹设置密码和加密,可以有效保护你的重要文件不被未经授权的人员访问,特别是公司的重要岗位,一些特殊的机密文件,投标文件,资金文件等…

动手学深度学习(Pytorch版)代码实践 -深度学习基础-10权重衰减

10权重衰减 """ 正则化是处理过拟合的常用方法:在训练集的损失函数中加入惩罚项,以降低学习到的模型的复杂度。 保持模型简单的一个特别的选择是使用L2惩罚的权重衰减。这会导致学习算法更新步骤中的权重衰减。 """impor…

html--好看的手机充值单页

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>线上充值-首页</title><meta content"widthdevice-width,initial-scale1.0,maximum-scale1.0,user-scalable0" name"viewport&…

maya模型仓鼠制作

小仓鼠建模&#xff08;6&#xff09;_哔哩哔哩_bilibili 20240623作品---个人评价&#xff1a;第一次做的&#xff0c;虽然有点丑&#xff0c;但是还能看&#xff01;希望后面有些进步

论文阅读--Efficient Hybrid Zoom using Camera Fusion on Mobile Phones

这是谷歌影像团队 2023 年发表在 Siggraph Asia 上的一篇文章&#xff0c;主要介绍的是利用多摄融合的思路进行变焦。 单反相机因为卓越的硬件性能&#xff0c;可以非常方便的实现光学变焦。不过目前的智能手机&#xff0c;受制于物理空间的限制&#xff0c;还不能做到像单反一…

线程封装,互斥

文章目录 线程封装线程互斥加锁、解锁认识接口解决问题理解锁 线程封装 C/C代码混编引起的问题 此处pthread_create函数要求传入参数为void * func(void * )类型,按理来说ThreadRoutine满足,但是 这是在内类完成封装,所以ThreadRoutine函数实际是两个参数,第一个参数Thread* …

【建设方案】大数据湖一体化建设方案(ppt原件)

1、背景&#xff1a;大数据湖的发展背景与建设理念 2、体系&#xff1a;大数据湖体系规划与建设思路 3、生态圈&#xff1a;探索新兴业务入湖建设模式 4、共享&#xff1a;大数据湖统一访问共享规划 5、运营&#xff1a;大数据湖一体化运营管理建设 &#xff08;本方案及更多方…

Kafka~基础原理与架构了解

Kafka是什么 Kafka我们了解一直认为是一个消息队列&#xff0c;但是其设计初&#xff0c;是一个&#xff1a;分布式流式处理平台。流平台具有三个关键功能&#xff1a; 消息队列&#xff1a;发布和订阅消息流&#xff0c;这个功能类似于消息队列&#xff0c;这也是 Kafka 也被…

Comfyui-ChatTTS-OpenVoice 为ComfyUI添加语音合成、语音克隆功能

‍‍ 生成多人播客&#xff1a; Comfyui-ChatTTS是一个开源的GitHub项目&#xff0c;致力于为ComfyUI添加语音合成功能。该项目提供了一系列功能强大的节点和模型&#xff0c;支持用户创建和复用音色&#xff0c;支持多人对话模式的生成&#xff0c;并提供了导出音频字幕文件的…

“Jedis与Redis整合指南:实现高效的Java应用与Redis交互“

目录 #. 概念 1. 导入jedis依赖 2. 写一个类&#xff08;ping通redis&#xff09; 3. String字符串使用 3.1 set&#xff0c;get方法使用&#xff08;设值&#xff0c;取值&#xff09; 3.2 mset&#xff0c;mget方法使用&#xff08;设置多个值&#xff0c;取多个值&…

怎么在vscode里运行一个cpp文件

文章目录 1.需要下载g编译器&#xff0c;或clang&#xff08;快&#xff0c;但是优化效果没有g好&#xff09;2.新建文件夹和cpp文件&#xff08;tasks.json&#xff09;3.怎么在vscode里调试(launch.json)4.怎么设置让中断输出的字符是中文&#xff01;5.飞机大战 1.需要下载g…

iis下asp.netcore后台定时任务会取消

问题 使用BackgroundService或者IHostedService做后台定时任务的时候部署到iis会出现不定时定时任务取消的问题&#xff0c;原因是iis会定时的关闭网站 解决 应用程序池修改为AlwaysRunning 修改web.config <?xml version"1.0" encoding"utf-8"?…

Android studio登录Google账号超时的解决方法

确保自己已经打开了代理&#xff08;科学上网&#xff09;在设置-外观与行为-系统设置-HTTP代理 中打开“自动检测代理设置”&#xff1a; 再次重新尝试登录Google账号&#xff0c;登陆成功&#xff01; 学术会议征稿 想要了解国内主办的覆盖学科最全最广的学术会议&#xff0c…

代码-功能-python-爬取博客网标题作者发布时间

环境&#xff1a; python 3.8 代码&#xff1a; # 爬取博客园内容 # https://www.cnblogs.com/import re from lxml import etree import requests import json import threading from queue import Queue import pymysql import timeclass HeiMa:def __init__(self):# 请…

k8s 部署 ruoyi 前后端分离项目

本文视频版 https://www.bilibili.com/video/BV17ugkePEeN 参考 https://blog.csdn.net/qq_50247813/article/details/136934090 https://gitee.com/nasaa/RuoYi-Vue-cloud https://www.itsgeekhead.com/tuts/kubernetes-129-ubuntu-22-04-3/ https://kubernetes.io/docs/se…

【漏洞复现】畅捷通T+ keyEdit.aspx SQL漏洞

0x01 产品简介 畅捷通 T 是一款灵动&#xff0c;智慧&#xff0c;时尚的基于互联网时代开发的管理软件&#xff0c;主要针对中小型工贸与商贸企业&#xff0c;尤其适合有异地多组织机构(多工厂&#xff0c;多仓库&#xff0c;多办事处&#xff0c;多经销商)的企业&#xff0c;…