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库,用于图像编辑处理。…

linux常用API接口

linux常用API接口 文章目录 linux常用API接口1.应用层内存映射mmap取消内存映射munmap终端打印可用方式1.puts 函数2.文件操作函数 fprintf3.字符输出函数 putchar4.fwrite 函数 2.内核层 1.应用层 内存映射mmap mmap 是一个用于内存映射的系统调用,它可以将一个文…

Java零基础-集合:List

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一…

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种方法)

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

使用Metropolis蒙特卡洛方法的原子模拟

文章目录 1.蒙特卡罗方法的目标2.热力学系综3.连续体系4.Metropolis算法1.Metropolis算法介绍2.Metropolis算法思路 5.原子体系的蒙特卡洛算法1.算法的基本思想2.算法的实现过程 1.蒙特卡罗方法的目标 蒙特卡罗方法可以做什么? 提供材料的热力学信息; 评…

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

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

Linux之时间显示

在linux中使用使用date的方式来显示时间,但是如果想按照自己想要的格式展示,那就需要加上一点参数了 显示当前时间 date 2024年 06月 23日 星期日 23:21:42 CST 显示当前年份 date %Y 2024 显示当前月份 date %m 6 显示当前日期 date %d 23 自定义显示格…

代码随想录算法跟练 | Day9 | 字符串 Part02

个人博客主页:http://myblog.nxx.nx.cn 代码GitHub地址:https://github.com/nx-xn2002/Data_Structure.git Day9 151. 反转字符串中的单词 题目链接: https://leetcode.cn/problems/reverse-words-in-a-string/ 题目描述: 给你…

vue怎么处理跨域

Vue.js 本身并不直接解决跨域问题,因为跨域问题主要是浏览器基于同源策略(Same-origin policy)的一种安全限制。然而,在Vue.js项目中,我们可以采取一些策略来绕过或处理跨域问题。 解决跨域问题的常用方法&#xff1a…

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&…

线程进程以及多线程多进程(超详解)

目录 前言 一、什么是进程和线程 进程 (Process) 线程 (Thread) 多线程 (Multithreading) 多进程 (Multiprocessing) 相互组合关系 二、资源分配 进程 私有资源 共享资源 线程 私有资源 共享资源 多进程 私有资源 共享资源 多线程 私有资源 共享资源 进程的…

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;并提供了导出音频字幕文件的…