PID各种算法的基本优缺点

PID时间系数对PID本身的影响

图片

积分时间过小积分作用增强。

微分时间过大,微分控制作用过强,容易产生振荡。

在这里的时间系统,一般指的是采样的时间,也就是PID控制的周期。在无人机当中一般采用10ms控制一次。

一般来说采样周期越小,数字模拟越精确,控制效果越接近连续控制。

对大多数算法,缩短采样周期可使控制回路性能改善,但采样周期缩短时,频繁的采样必然会占用较多的计算工作时间,同时也会增加计算机的计算负担。

对于变化迅速的,采样周期应适当减小。多回路控制,采样周期应该适当延长,使得有足够的时间控制。

位置式PID

离散化后的公式:

图片

优点:静态误差小,溢出的影响小。

缺点:计算量很大,累积误差相对大,在系统出现错误的情况下,容易使系统失控,积分饱和。

使用:一般需要结合输出限幅和积分限幅使用。积分限幅是避免积分失控的一种手段,也是为了加快调节时间,减少积分饱和的影响,输出限幅是为了使系统输出不过度,也能够减少系统的调节时间,减少超调量。

位置式PID适用于执行没有积分部件的对象。

增量式PID

离散化后的公式:

图片

优点:溢出的影响小,在系统出现错误的情况下,影响相对较小(因为只与过去的三次误差有关),运算量也相对较小。

缺点:有静态误差(因为没有累积误差)。

使用:位置式PID适用于执行有积分部件的对象。

位置式PID和增量式PID

C语言实现:

//积分限幅#define INERGRAL_MAX 200#define INERGRAL_MAX -200//输出限幅#define OUT_MIN    -1000#define OUT_MAX    1000
// 滤波系数a(0-1)  #define PARAMETER   0.01                //PID结构体typedef struct{   volatile float    Proportion;             // 比例常数 Proportional Const   volatile float    Integral;               // 积分常数 Integral Const   volatile float    Derivative;             // 微分常数 Derivative Const   volatile int      Error1;                 // Error[n-1]   volatile int      Error2;                 // Error[n-2]   volatile int      iError;                 // Error[n]   volatile  int     Error_sum;} PID
/****************************************************************************************/                                                        //                位置式PID//                    //pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]  /****************************************************************************************/float PID_Postion (int iError,PID* sptr) {  float  iIncpid=0;  sptr->iError=iError;                                    // 计算当前误差       //sptr->iError=filter(sptr->iError,sptr->Error1); 一阶滤波器  sptr->Error_sum+=sptr->iError;//积分项      ///当输出限幅的时候,积分累加部分也应同时进行限幅,以防输出不变而积分项继续累加,也即所谓的积分饱和过深。  //积分量限幅  if(sptr->Error_sum >INERGRAL_MAX)  {    sptr->Error_sum = PID_InitStruct->INERGRAL_MAX ;  }  if(sptr->Error_sum < INERGRAL_MIN)  {    sptr->Error_sum = PID_InitStruct->INERGRAL_MIN ;  }      iIncpid=sptr->Proportion * sptr->iError                  // P         +sptr->Integral * sptr->Error_sum                // I         +sptr->Derivative * (sptr->iError-sptr->Error1); // D  sptr->Error1=sptr->iError;          // 存储误差,用于下次计算      iIncpid=PID_OutputLimit(sptr,iIncpid);//PID输出限幅          return(iIncpid);          // 返回计算值  }
/****************************************************************************************/                                    //增量式PID                                            //        pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]                                      ///****************************************************************************************/float PID_increase(int iError,PID* sptr) {    float  iIncpid=0;  sptr->iError=iError;//直接检测当前偏差  iIncpid=sptr->Proportion * (sptr->iError-sptr->Error1)                  // P         +sptr->Integral * sptr->iError                                   // I         +sptr->Derivative * (sptr->iError-2*sptr->Error1+sptr->Error2);  // D               sptr->Error2=sptr->Error1;                          // 存储误差,用于下次计算  sptr->Error1=sptr->iError;  iIncpid=PID_OutputLimit(sptr,iIncpid);//输出限幅处理        return(iIncpid);   // 返回增量值  }
//PID初始化void PID_Init(PID *sptr){    sptr->Derivative=0;//Kd    sptr->Proportion=0;//Kp    sptr->Integral=0;//Ki    sptr->Error2=0;//第二次误差    sptr->Error1=0;    sptr->iError=0;    sptr->Error_sum=0;//第一次误差}

//PID输出限制,根据PWM的输出值进行增量式PID输出限制float PID_OutputLimit(PID *this, double output)  {        if ((int)output < OUT_MIN)    {        output = OUT_MIN;    }        else if ((int)output > OUT_MAX)        {        output = OUT_MAX;    }    return output;}//一阶低通滤波器//减少毛刺,//滤波系数。取值范围为0~1, 值越小越稳定,越大越灵敏。使用使需要根据实际情况调整滤波系数//输入:新的采样值//输出:滤波后的值float filter(float value,float new_value)   {         return (1-PARAMETER)*value +PARAMETER*new_value;  }  

两种针对积分的PID:

主要目的是为了尽可能利用积分的优势,消除静态误差,也同时减少积分的副作用。

使PID控制器的超调量减少,调节时间减少,系统更加稳定。

积分分离式PID

积分分离式PID主要是针对位置式PID的积分,引入判断误差大小条件,是否使用积分项。

优点:

判定误差比较大的时候,取消积分项的,使用PD或者P控制,没有I的控制,这样,超调量和调节时间都会同时减少。当误差比较小的时候,引入积分项,消除静态误差。

缺点: 

需要经验来确定判断误差的大小,在什么时候使用积分分离比较合适,也就是误差多大的时候取消积分。

应用:

主要用于消除余差,该方法特别适用于生产设备启动阶段的控制。

C语言实现:PID位置式上面有,这里只需要添加一句判断语句和对积分处理。

无积分分离式的PID:

sptr->Error_sum+=sptr->iError;//积分累加 iIncpid=sptr->Proportion * sptr->iError                  // P         +sptr->Integral * sptr->Error_sum                // I         +sptr->Derivative * (sptr->iError-sptr->Error1); // D

积分分离式PID:

#include<math.h>int index=0;//积分分离标志   //积分分离处理   if(abs(sptr->iError)> 40) sptr->index=0;   else   {    sptr->index=1;  sptr->Error_sum+=sptr->iError;//积分累加  }  iIncpid=sptr->Proportion * sptr->iError                  // P         +sptr->Integral * (sptr->Error_sum * index)              // I         +sptr->Derivative * (sptr->iError-sptr->Error1); // D

变速积分PID

变积分PID我的理解是积分分离式PID的变体,积分分离式PID 积分的的权重是1或者0,而变积分PID积分的权重会动态变化。取决于偏差,偏差越大,积分越慢。

优缺点和积分分离式PID差不多,只不过,这个变速积分PID更加科学。

积分分离式PID:

#include<math.h>#define I_MAX 40#define I_MIN 5int index=0;//积分分离标志   //变积分处理   if(abs(sptr->iError)> I_MAX) index=0;   else if(abs(sptr->iError)< I_MIN) index=1;  else   index=(I_MAX -  abs(sptr->iError) / (I_MAX -  I_MIN);  if(index!=0) sptr->Error_sum+=sptr->iError;//积分累加  iIncpid=sptr->Proportion * sptr->iError                  // P         +sptr->Integral * (sptr->Error_sum * index)              // I         +sptr->Derivative * (sptr->iError-sptr->Error1); // D          //变速积分也可以这样处理:更加灵活  if(fabs(sptr->iError)> I_MAX) index=0;   else if(fabs(sptr->iError)< I_MIN) index=1;  else if(fabs(sptr->iError>10&&abs(sptr->iError)<20)) index=0.4;  else if(fabs(sptr->iError>30&&abs(sptr->iError)<50)) index=0.8;  else   index=(I_MAX -  abs(sptr->iError) / (I_MAX -  I_MIN);

两种针对微分的PID如下:

不完全微分PID

这里针对微分的PID控制算法,是减少微分作用的副作用的一些算法,以便更好地利用微分作用的作用。我们知道,当系统引入微分作用得时候会,引进高频干扰。为了抑制这种干扰,便引入低通滤波器。

这种滤波器得优缺点

优点:

对周期性干扰具有良好的抑制作用

适用于波动频率较高的场合

缺点:

相位滞后,灵敏度低

滞后程度取决于a值大小

不能消除滤波频率高于采样频率的1/2的干扰信号

应用:对于诸如阶跃信号等信号变化很大信号。采用不完全微分能够使得微分作用更为持续平缓。

控制图:

图片

位置式PID不完全微分:

公式:

图片

增量式PID不完全微分:

公式:

图片

//PID结构体typedef struct{   volatile float    Proportion;             // 比例常数 Proportional Const   volatile float    Integral;               // 积分常数 Integral Const   volatile float    Derivative;             // 微分常数 Derivative Const   volatile int      Error1;                 // Error[n-1]   volatile int      Error2;                 // Error[n-2]   volatile int      iError;                 // Error[n]   volatile  int     Error_sum;   volatile  float    thisdev;//前一拍时的微分项值   volatile  float    lastdev ;//前一拍时的微分项值   float        dev_per;//微分系数   } PID;
//位置式PID不完全微分float PID_Postion (int iError,PID* sptr) {  float  iIncpid=0;  sptr->iError=iError;                                      // 计算当前误差  sptr->Error_sum+=sptr->iError;//积分项  //不完全微分    sptr->thisdev=sptr->Derivative*(1-sptr->dev_per)*(sptr->iError-sptr->Error1)+sptr->dev_per*sptr->lastdev;    iIncpid=sptr->Proportion * sptr->iError                  // P         +sptr->Integral * sptr->Error_sum                // I         +sptr->thisdev; // D   //更新值  sptr->Error1=sptr->iError;            sptr->lastdev=sptr->thisdev;//更新下次微分值    return(iIncpid);          // 返回计算值  }
//增量式PID不完全微分float PID_increase(int iError,PID* sptr) {    float  iIncpid=0;  sptr->iError=iError;//直接检测当前偏差    sptr->thisdev=sptr->Derivative*(1-sptr->dev_per)*(sptr->iError-2*sptr->Error1+sptr->Error2)+sptr->dev_per*sptr->lastdev;    iIncpid=sptr->Proportion * (sptr->iError-sptr->Error1)                  // P         +sptr->Integral * sptr->iError                                   // I         +sptr->thisdev;  // D       //更新           sptr->Error2=sptr->Error1;                            sptr->Error1=sptr->iError;  sptr->lastdev=sptr->thisdev;//更新下次微分值    return(iIncpid);   // 返回增量值  }

微分先行PID

控制器采用PI控制,将微分作用移动到反馈回路上。微分作用直接对被控量进行微分,对被控量速度进行控制。

优点:在给定值频繁变化的情况下,优先采用微分先行的控制方案能够更迅速的反应,对变化更为敏感。

缺点:更为敏感也就意味着更加不稳定,变化量比较大的情况下,微分作用过分凸显,容易导致超调,引起系统振荡加大。

图示:

图片

对微分部分引入一阶惯性滤波器,进行离散化后的公式:

位置式:

图片

图片

  增量式:

图片

C语言实现:

//PID结构体//位置式typedef struct{   volatile float   Proportion;             // 比例常数 Proportional Const   volatile float   Integral;               // 积分常数 Integral Const   volatile float   Derivative;             // 微分常数 Derivative Const   volatile int     Error1;                 // Error[n-1]   volatile int     Error2;                 // Error[n-2]   volatile int     iError;                 // Error[n]   volatile  int    Error_sum;      volatile   float  lastPv;             //前一拍的测量值   volatile   float  gama;               //微分先行滤波系数   volatile   float  derivative;//微分项      } PID;
//位置式微分先行PIDfloat PID_Postion (float set_point,float processValue,PID* sptr) {  float  iIncpid=0;  float  temp=0,c1,c2,c3;  sptr->iError=set_point-processValue;                                      // 计算当前误差  sptr->Error_sum+=sptr->iError;//积分项  //微分先行  temp=sptr-> gama * sptr-> Derivative+ sptr-> Proportion;//γKp+Kd  c3=sptr-> Derivative/temp;//Kd/γKp+Kd  c2=(sptr-> Derivative+ sptr-> Proportion)/temp;//Kd+Kp/γKp+Kd  c1=c3*sptr-> gama;//γ(Kp/γKp+Kd)    sptr-> derivative=c1* sptr-> derivative+c2*processValue-c3* sptr-> lastPv;
  iIncpid=sptr->Proportion * sptr->iError                  // P         +sptr->Integral * sptr->Error_sum                // I         +sptr->derivative; // D   //更新值  sptr->Error1=sptr->iError;            sptr->lastPv=sptr->processValue;//更新下次微分值    return(iIncpid);          // 返回计算值  }
//***********************************************************////              增量式微分先行PID//***********************************************************////增量式PID结构体typedef struct{   volatile float   Proportion;             // 比例常数 Proportional Const   volatile float   Integral;               // 积分常数 Integral Const   volatile float   Derivative;             // 微分常数 Derivative Const   volatile int     Error1;                 // Error[n-1]   volatile int     iError;                 // Error[n]   volatile   float  lastout;   //上一次的测量量     volatile   float  lastout_proinc;                 //前一拍的过程测量增量   volatile   float  gama;                  //微分先行滤波系数   volatile   float  out_proinc;         //过程测量增量   volatile   float  derivative_inc;    //微分项      } PID;
//增量式PID不完全微分PID_increasefloat PID_increase(float set_point,float processValue,PID* sptr) {  float  iIncpid=0;  float  temp=0,c1,c2,c3;  sptr->iError=set_point-processValue;                                         // 计算当前误差  //微分先行    out_proinc=processValue-lastout;//这次输出增量      temp=sptr-> gama * sptr-> Derivative+ sptr-> Proportion;//γKp+Kd  c3=sptr-> Derivative/temp;//Kd/γKp+Kd  c2=(sptr-> Derivative+ sptr-> Proportion)/temp;//Kd+Kp/γKp+Kd  c1=c3*sptr-> gama;//γ(Kp/γKp+Kd)    sptr-> derivative_inc=c1* sptr-> derivative_inc+c2*out_proinc-c3* sptr-> lastout_proinc;
  iIncpid=sptr->Proportion * (sptr->iError-sptr->               Error1)// P         +sptr->Integral * sptr->iError// I         +sptr->derivative_inc; // D   //更新值  sptr->Error1=sptr->iError;  sptr->lastout_proinc=sptr->out_proinc;//过程增量更新            sptr->lastout=processValue;//上一次的测量量更新    return(iIncpid);          // 返回增量值}

带死区的PID

死区控制简单理解:

死区,就是到了一个区域,在这个区域内,PID算法不起作用,也就是不做控制。

图片

优势:

可以抑制由于控制器输出量的量化造成的连续的较小的振荡,也就是消除稳定点附近的抖动。这是因为,现实中,总存在误差,一些较小误差难以消除。

缺点:

会造成一定的滞后。设定死区的值也是需要考虑,太小每作用,太大滞后严重。在零点附近时,若偏差很小,进入死去后,偏差置0会造成积分消失,如是系统存在静差将不能消除,所以需要人为处理这一点。

应用:

减少机械磨损,延长设备寿命等。

总结来说:PID调节器中设置死区,牺牲的是调节精度,换来的是稳定性。适用于精度不是很高的系统。

死区的输出为0时,pid控制器的比例部分和微分部分均为0,积分部分保持不变。虽然误差值在死区宽度设置的范围内变化,控制器的输出却保持不变。

C语言实现:

#define DEAD_BAND 50//死区控制值   #define PID_OUT_MAX 200 //PID输出上限#define PID_OUT_MAX 200 //PID输出上限
#include "math.h"           //PID结构体typedef struct{   volatile float    Proportion;             // 比例常数 Proportional Const   volatile float    Integral;               // 积分常数 Integral Const   volatile float    Derivative;             // 微分常数 Derivative Const   volatile int      Error1;                 // Error[n-1]   volatile int      Error2;                 // Error[n-2]   volatile int      iError;                 // Error[n]   volatile  int     Error_sum;} PID
/****************************************************************************************/                                                        //                位置式PID//                    //pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]  /****************************************************************************************/float PID_Postion (float set_point,,float now_point,PID* sptr) {  float  iIncpid=0;  sptr->iError=now_point-set_point; // 计算当前误差  //死区控制算法                                       if(fabs(sptr->iError)>DEAD_BAND)   {  sptr->Error_sum+=sptr->iError;//积分项        iIncpid=sptr->Proportion * sptr->iError                  // P         +sptr->Integral * sptr->Error_sum                // I         +sptr->Derivative * (sptr->iError-sptr->Error1); // D  sptr->Error1=sptr->iError ;          // 存储误差,用于下次计算
  }    else   {    iIncpid=0;    //sptr->Error_sum+=sptr->iError;//积分项        sptr->Error1=sptr->iError;  // 存储误差,用于下次计算  }        return(iIncpid);          // 返回计算值                  }
/****************************************************************************************/                                    //增量式PID                                            //        pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]                                      ///****************************************************************************************/float PID_increase(int iError,PID* sptr) {    float  iIncpid=0;  sptr->iError=iError;//直接检测当前偏差  if(fabs(sptr->iError)>DEAD_BAND)   {  iIncpid=sptr->Proportion * (sptr->iError-sptr->Error1)                  // P         +sptr->Integral * sptr->iError                                   // I         +sptr->Derivative * (sptr->iError-2*sptr->Error1+sptr->Error2);  // D               sptr->Error2=sptr->Error1;                          // 存储误差,用于下次计算  sptr->Error1=sptr->iError;
}else {  iIncpid=0;//输出增量值为0  sptr->Error2=sptr->Error1; // 存储误差,用于下次计算                           sptr->Error1=sptr->iError;}  return(iIncpid);   // 返回增量值  }

PID梯形积分

积分会有余差,消除不了,为了减少余差,提高运算的精度。便有了PID梯形积分,也能抑制一些随机干扰。

缺点便是,曲线到达设定值的时间会延长。

总的来说:也就积分的作用削弱了。带来的是余差进一步减小。

图片

C语言实现:

typedef struct{   volatile float    Proportion;             // 比例常数 Proportional Const   volatile float    Integral;               // 积分常数 Integral Const   volatile float    Derivative;             // 微分常数 Derivative Const   volatile int      Error1;                 // Error[n-1]   volatile int      Error2;                 // Error[n-2]   volatile int      iError;                 // Error[n]   volatile  int     Error_sum;} PID
/****************************************************************************************/                                                        //                位置式PID//                    //pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]  /****************************************************************************************/float PID_Postion (float set_point,,float now_point,PID* sptr) {  float  iIncpid=0;  sptr->iError=now_point-set_point; // 计算当前误差  //死区控制算法                                       sptr->Error_sum+=sptr->iError;//积分项        iIncpid=sptr->Proportion * sptr->iError                  // P         +sptr->Integral * sptr->Error_sum/2                // 改变的只是这里,多除了2         +sptr->Derivative * (sptr->iError-sptr->Error1); // D  sptr->Error1=sptr->iError ;          // 存储误差,用于下次计算
      return(iIncpid);          // 返回计算值                  }

总结

PID的变体还有很多,除了上文,还有专家PID与模糊PID是本文不能承载,也是我不能输出,便作罢。

事物都有两面性,该怎么选择比较合适,怎么将PID的各种变体组合在一起合适自己的系统,这个是需要综合衡量和测试的,要知其然知其所以然。

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

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

相关文章

【Docker】容器的相关命令

上一篇&#xff1a;创建&#xff0c;查看&#xff0c;进入容器 https://blog.csdn.net/m0_67930426/article/details/135430093?spm1001.2014.3001.5502 目录 1. 关闭容器 2.启动容器 3.删除容器 4.查看容器的信息 查看容器 1. 关闭容器 从图上来看&#xff0c;容器 aa…

如何在 Xftp 中使用自定义编辑器编辑远程服务器文件

1、简介 很多时候我们使用 Xshell 远程登录linux服务器进行文本编辑&#xff0c;通过命令行窗口难以进行快速编辑&#xff0c;因此&#xff0c;借助 Xftp 工具&#xff0c;指定文本编辑器&#xff0c;能够快速帮助我们实现文本编辑。 2、Xftp 使用 在上文中&#xff08;https:…

软件工程概论------文件管理

目录 1.文件的相关概念 2.文件目录 3.位示图 4.索引文件 5.例题 1.文件的相关概念 文件:具有符号名的、在逻辑上具有完整意义的一组相关信息项的集合。 逻辑结构:有结构的记录式文件、无结构的流式文件。 物理结构: 连续结构、链接结构、索引结构、多个物理块的索引表。 …

乔布斯在斯坦福大学经典演讲

今天&#xff0c;很荣幸来到各位从世界上最好的学校之一毕业的毕业典礼上。我从来没从大学毕业过&#xff0c;说实话&#xff0c;这是我离大学毕业最近的一刻。 今天&#xff0c;我只说三个故事&#xff0c;不谈大道理&#xff0c;三个故事就好。 第一个故事&#xff0c;是关于…

【ChatGPT】提示设计的艺术:使用清晰的语法

探索清晰的语法如何使您能够将意图传达给语言模型&#xff0c;并帮助确保输出易于解析 All images were generated by Scott and Marco. 这是与Marco Tulio Ribeiro共同撰写的关于如何使用指导来控制大型语言模型&#xff08;LLM&#xff09;的系列文章的第一部分。我们将从基…

Spring中的工厂类ApplicationContext和BeanFactory

1.ApplicationContext ApplicationContext的实现类&#xff0c;如下图 ClassPathXmlApplicationContext&#xff1a;加载类路径下 Spring 的配置文件 FileSystemXmlApplicationContext&#xff1a;加载本地磁盘下 Spring 的配置文件 ApplicationContext由BeanFactory派生而…

标签函数 - 打造JavaScript组件

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; CSS专栏&#xff1a;想学CSS的&#xff0c;冲这里 &#x1f4…

计算机基础知识——校验码概述

目录 1 码距 2 奇偶校验 3 CRC循环冗余校验码 3.1 多项式 3.2 编码的组成 3.3 生成多项式 3.4 校验码的生成 4 海明校验码和恒比码 4.1 校验方程 4.2 恒比码 1 码距 码距是恒量一种编码方式的抗错误能力的一个指标。数字信息在传输和存取的过程中&#xff0c;由于…

权威认可!甄知科技猪齿鱼产品荣获信创产品评估证书

近日&#xff0c;依据《信息技术应用创新产品评估规范 第1部分&#xff1a;应用软件》&#xff08;T/SSIA 2001-2022&#xff09;&#xff0c;经过严格评估&#xff0c;甄知科技旗下自主研发的猪齿鱼数智化开发管理平台 V2.0.0&#xff0c;通过信创测试认证&#xff0c;获得上海…

Jmeter相关知识介绍

Jmeter 是Apache 组织开发的基于JAVA 的压力测试工具,用于对软件做压力测试,特别适合于WEB 应用测试(包括压力,接口测试) 今天简单介绍Jemeter的入门相关概念的理解 一、在安装目录下有一个Bin\Jmeter.bat 双击打开 打开之后是一个这样的界面 二、测试计划 1、添加和删…

基础语法(一)(1)

常量和表达式 在这里&#xff0c;我们可以把Python当成一个计算器&#xff0c;来进行一些算术运算 例如&#xff1a; print(1 2 - 3) print(1 2 * 3) print(1 2 / 3)注意&#xff1a; print是一个python内置的函数&#xff0c;这个稍后我们会进行介绍 可以使用-*/&…

java 音乐会售票平台系统Myeclipse开发mysql数据库struts2结构java编程计算机网页项目

一、源码特点 java 音乐会售票平台系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助struts2框架开发mvc模式&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发 环境为TOCAT7.0,Myeclipse8.5开发&#xff0c;数据…

揭开 JavaScript 作用域的神秘面纱(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Halcon计算最小外接矩形Smallest_rectangle2

Halcon计算最小外接矩形Smallest_rectangle2 该算子用于求最小外接矩形。该算子的原型如下&#xff1a; smallest _rectangle2 (Regions : : : Row, Column, Phi, Lengthl, Length2)其各参数的含义如下。 参数1&#xff1a;Regions 表示输入的区域。 参数2和3&#xff1a;Row…

如何通过HACS+Cpolar实现远程控制米家和HomeKit等智能家居设备

文章目录 基本条件一、下载HACS源码二、添加HACS集成三、绑定米家设备 ​ 上文介绍了如何实现群晖Docker部署HomeAssistant&#xff0c;通过内网穿透在户外控制家庭中枢。本文将介绍如何安装HACS插件商店&#xff0c;将米家&#xff0c;果家设备接入 Home Assistant。 基本条件…

Spring AI和Ollama

概述 Spring AI 不仅提供了与 OpenAI 进行API交互&#xff0c;同样支持与 Ollama 进行API交互。Ollama 是一个发布在GitHub上的项目&#xff0c;专为运行、创建和分享大型语言模型而设计&#xff0c;可以轻松地在本地启动和运行大型语言模型。 Docker环境安装Ollama 1.获取D…

python 模块搜索路径

前言 当我们import os的时候&#xff0c;Python解释器去哪找os模块呢&#xff1f;如果多处都有os模块&#xff0c;选择哪个os模块呢&#xff1f; 去哪找os模块&#xff1f; Python解释器不是很神奇&#xff0c;它会从以下2个地方找os模块 1、内置模块 sys.builtin_module_nam…

ROS-arbotix安装

方式一&#xff1a;命令行输入&#xff1a; sudo apt-get install ros-melodic-arbotix如果ROS为其他版本&#xff0c;可将melodic替换为对应版本。 方式二&#xff1a; 先从 github 下载源码&#xff0c;然后调用 catkin_make 编译 git clone https://github.com/vanadiumla…

P59 生成式对抗网络GAN-理论介绍 Theory behind GAN

Object Normal Distribution 的数据 经过 Generator 后生成分布更加复杂的PG. 真实数据的分布为 Pdata , 希望 PG和Pdata 越近越好 LOSS 是 两者之间的分布距离 问题: 如何计算 divergence? Sampling is goog enough Discriminator 希望V越大越好 y~Pdata 代表从 Pdata里…

项目整合积木报表-设计页面

项目整合积木报表-设计页面 <template><div><iframe id"dome" :srcsrc ></iframe></div> </template><script>export default {data(){return{src:configSrc.src"/jmreport/view/836138868821839872"}}} </…