Platinum Maestro运动控制器 —— PVT模式笔记

2023-11-09 17:20

本文主要是介绍Platinum Maestro运动控制器 —— PVT模式笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 0. 文章说明
  • 1. PVT说明
  • 2.PVT 插值模式
    • 2.1 三次多项式插值(eCUBIC_POLYNOM)
    • 2.2 五次多项式插值(eQUINTIC_ON_CUBIC)
    • 2.3 七次样条多项式(eSEPTIC_ON_CUBIC)
    • 2.4 正弦插值
      • 2.4.1 三角正弦插值(eCYCLOID_VELOCITY_MODIFIED1)
      • 2.4.2 梯形正弦插值(eCYCLOID_VELOCITY_MODIFIED2)
      • 2.4.3 正弦速度插值(eCYCLOID_POSITION)
  • 3. 数据加载
  • 4. PVT 运动
  • 5.动态模式
    • 5.1 初始化列表
    • 5.2 加载数据
    • 5.3 循环模式(Cyclic Mode)
  • 6.PVT在C++中的实现
    • 6.1 PVT表初始化函数
    • 6.2 PVT数据点加载函数
    • 6.3 PVT移动函数
  • 7.PVT 使用教程
    • 7.1 使用方法
    • 7.2 例程

0. 文章说明

请忽略前面的扯淡内容,直接跳至3

1. PVT说明

详情参见API手册P783

       通常,PV/PVT运动由一组点定义,如果在当前位置之前提供了多个点,profiler可以构建一个三次多项式来计算下一个要下载到驱动器的位置。该路径是实时计算的,因此所有多项式系数的计算都在实时模块中进行。PV/PVT运动不需要执行完整的数据,只需要最少的点。
       与样条相似,输入表存储在共享内存中,但与样条不同的是,只存储坐标,而多项式系数在实时模块中计算。表可以通过文件加载,也可以通过用户提供的N x M数组加载。可以选择将一行或几行附加到表中,但要在合理的约束条件下;例如,不能将数据附加到当前段,分析器正在操作。PV/PVT函数块仅适用于NC循环/插补模式。
       用户提供的点多于3个,即可应用PVT插补。

2.PVT 插值模式

       对于PVT表的定义,遵循以下格式:
在这里插入图片描述
Ti为时间,有两种模式:两点之间的相对时间、各点分别对应的绝对时间。
轴的数量不受三个坐标轴的限制,最多可达16个坐标轴。

2.1 三次多项式插值(eCUBIC_POLYNOM)

三次多项式保证了位置和速度的连续性。它的缺点是在每一个连接点上都有加速度和加加速度(即簇动jerk)造成的不连续。
在这里插入图片描述

2.2 五次多项式插值(eQUINTIC_ON_CUBIC)

五次多项式保证了位置、速度和加速度的连续性。它的缺点是在每一个连接点上都有加加速度造成的不连续。
在这里插入图片描述

2.3 七次样条多项式(eSEPTIC_ON_CUBIC)

七次多项式保证了连续的位置,速度,加速度和加加速度。它的缺点是振幅变化比我们看到的低次多项式更高。这是在大多数情况下可以推荐的最通用的插值模式。
在这里插入图片描述

2.4 正弦插值

2.4.1 三角正弦插值(eCYCLOID_VELOCITY_MODIFIED1)

三角形正弦加速度-修正三角形加速度与AC(t)和DC(t)由正弦增加到某个最大值,然后下降到零。它保证连续的位置,速度,加速度和加加速度。
在这里插入图片描述
在这里插入图片描述

2.4.2 梯形正弦插值(eCYCLOID_VELOCITY_MODIFIED2)

梯形正弦加速度或修正梯形加速度通常由两部分组成:

  • 加速度随正弦曲线从0增加到ACmax,运动与ACmax(抛物线位置,线速度剖面)和加速度下降的正弦为零。
  • 由正弦波由零到-ACmax减速运动,由-ACmax减速运动(抛物线位置剖面,线速度剖面),由正弦波减速增加到零。

它保证连续的位置,速度,加速度和加加速度(如果所有的段定义与此插值模式)。
在这里插入图片描述
在这里插入图片描述

2.4.3 正弦速度插值(eCYCLOID_POSITION)

这种插补方式产生摆线位置和正弦速度插补。正弦速度是这种插值类型的一个优点,但它有两个明显的缺点。首先,它的开始和结束都伴随着最大的jerk。其次,它的应用具有局限性,当Y(i)≠0和Y(i+1)≠0时必须满足开始和结束导数服从条件△Y(i)=0.5(Y(i)+Y(i+1))△X(i)。(此处存疑) 因此,这种插补方式主要用于Y(i)≠0或者Y(i)=0的情况。

3. 数据加载

将每一行输入数据作为表存储在共享内存中,表示时间、位置、速度和向量位置。例如,我们在使用m个轴的情况下,表中第n行按如下格式生成:
在这里插入图片描述
用户可以通过以下几种方式提供数据:

  • 提供一个包含数据点的表的文件
  • 提供一个包含数据点的数组,这些数据点也可以附加到给定索引中的现有路径

当用户决定向现有路径添加点时,他必须知道:

  • 表的大小是有限的,应该知道它的最大大小
  • 仅对于dynamic Append(动态添加),当点的数量超过表的上限时,这些点将被附加到表的开头。
  • 不可能追加到当前段(目前,如果当前索引是X,用户只能从X + 3追加)。

在数据加载期间,从文件中读取这些点。然而,与样条不同的是,它们无需预先计算就可以插入共享内存。

禁止将数据附加到从文件加载的表中。如果T等于循环时间,应该使用一个简单的profiler。

4. PVT 运动

运动是使用一种特殊类型的函数块来执行的。当插入这个函数块类型时,应用一个特殊的轮廓仪来计算多项式系数并沿着计算的轨迹移动。

每一个循环下一段都向前计算。函数块包括指向当前选定路径数据起点的指针,包括所有路径常数数据,即维数、点数等。此外,函数块包含当前工作索引,因此如果用户希望添加点,系统将避免在当前工作索引中添加这些点。当PVT函数块处于运动状态时,只能通过STOP命令(类似于样条行为)以任何缓冲模式插入其他函数块。

5.动态模式

Maestro还支持动态地将数据加载到Maestro,即用户可以基于现有数据启动运动,剩余数据可以稍后添加。这个概念允许用户在考虑软件约束的情况下动态地更改路径。此时,实现了两种附加子模式:自动和手动。

  • 在自动模式下,大师将记住添加数据的最后一个索引,并将在下一次添加到该索引中。
  • 在手动模式下,用户必须提供索引,并在其中添加他希望添加的点。

实时模块使用计算出的点数来检查路径是否到达终点,即如果分配了2000个点数,而用户只插入了1000个点数,则不应遍历1000个点数的限制。此外,仅在动态模式下,当索引接近路径末尾时,才可以发送潜流事件。

5.1 初始化列表

在向表添加点之前,用户应该初始化它。这可以通过两种方式实现;通过从文件中加载一个表,或调用一个专用函数,该函数将初始化“常量”路径参数,如维度、最大点数等。

此外,用户应该选择附加操作是静态执行还是动态执行。如果选择动态附加,则用户应该选择下溢阀值。

5.2 加载数据

从数组中加载数据有两种模式——静态和动态。静态模式非常类似于从文件模式加载,当表中填充了最大值时,将加载表,并且不允许添加值。动态模式默认为循环模式,当超过潜流阀值时将生成实时事件。每次插入点的数量下降到预定义阈值以下时,就会向用户空间生成一个事件。使用现有的事件机制——用户根据需要处理溢出。

在向表中添加数据时,用户可以控制两个参数;是否附加在自动模式?如果没有,则第二个参数是要追加的索引。基于这两个参数,算法安全插入数据。

如果轴/向量在运动,则使用索引delta来维持计算出的路径(索引delta = 3)。如果当前索引与要追加的起始索引之差小于delta,则禁止插入。

在循环模式下,数据被附加到给定的索引(自动或手动),当数据到达PVT段的末尾时,数据被自动附加到开头。在非循环模式下,当数据到达PVT段的末尾时,返回一个错误。

文件中的数据被识别为double型,则对于m轴一行数据需要((M2 + 1) * size of(double)) bytes,分配的总内存将是(N * (M2 + 1) * size (double))
在这里插入图片描述

5.3 循环模式(Cyclic Mode)

为了支持循环模式,对循环缓冲区进行了管理。主要的限制是附加的缓冲区的大小不能超过表的大小,因为这样结束时将运行在开始时。此外,如果附加索引在当前索引之后,用户应该保持一个最小的增量: Abs(current – start) < 3
如果追加的索引在当前索引之前,则应保持以下内容:start + block size < current

6.PVT在C++中的实现

PVT (ECAM和样条,在将来)的基类是继承自CMMCMotionAxis的类CMMCAxis,即它包含所有CMMCAxis成员和方法。类CMMCMotionAxis函数在第8章中详细介绍:位置、速度、时间(PVT)运动。类CMMCMotionAxis保留了本文档中描述的用于C函数块的字段参数属性和值。
在这里插入图片描述
应该注意的是,私有和受保护的函数及其操作应该对用户透明,而不是供用户一般应用。

PVT和ECAM的基类CMMCMotionAxis继承自CMMCAxis,即它包含所有CMMCAxis成员和方法。

该方法继承自CMMCAxis类,但在CMMCMotionAxis类中重载,因为该方法不适合CMMCAxis实现的需求。而是使用BindAxis方法,InitAxisData只会抛出一个异常。

PVT包含以下方法:

函数说明
InitPVTTable该方法是MMC_InitTableCmd()命令的包装器。
LoadPVTTable该方法从文件中加载PVT表
AppendPointsToPVTTable此方法将点附加到当前PVT表(在自动模式下)
AppendPointsToPVTTable此方法将点附加到当前PVT表(在手动模式下)
MovePVT该方法插入PVT函数块
UnloadPVTTable卸载PVT表

详细请参考《Maestro Administrative and Motion API》手册第8章

6.1 PVT表初始化函数

// 初始化列表函数介绍
//此函数根据维度和点数在共享内存中分配内存段。
//应该注意的是,当使用这个函数时,没有加载任何数据。函数返回hMemHandle,它是唯一的路径ID(类似于样条)。virtual MC_PATH_REF InitPVTTable(unsigned long ulMaxPoints,unsigned long ulUnderflowThreshold,unsigned char ucIsCyclic,unsigned char ucIsPosAbsolute,unsigned short usDimension,MC_COORD_SYSTEM_ENUM eCoordSystem,NC_MOTION_TABLE_TYPE_ENUM eTableMode = eNC_TABLE_PVT_ARRAY) throw (CMMCException);/** \参数 ulMaxPoints - 表能够包含的最大点数(在非循环模式下),任何+ve值都可以接受。* \参数 ulUnderflowThreshold - 如果当前索引和结束索引之间的点数低于此值,则将生成一个事件。值不能大于ulMaxPoints值。* \参数 ucIsCyclic - 这个列表应该是循环的吗?也就是说,当索引到达表的末尾时,它会滚动并从头开始?。布尔值为0或1* \参数 ucIsDynamic - 是否允许动态追加* \参数 ucIsPosAbsolute - 是否是绝对位置,1为绝对位置,0为相对位置* \参数 usDimension - PVT表的维度* \参数 eSplineMode	- 定义样条函数的计算方法 (FT/VT/CV_DWELL)* \参数 ConstVelocity	- 所有的线段都必须有恒定的速度* \参数 FixedType	- 在所有段上强制使用常数时间(ms)* \参数 eCoordSystem - 支持的坐标系类型* \参数 eTableMode - 这个枚举用作这些函数的输入,以便区分ECAM和PVT.目前只能应用eNC_TABLE_PVT_FILE和eNC_TABLE_PVT_ARRAY(默认采用三次样条插补)。*                   //对于插补这一点,可能不如PMAC。* \return void*/

6.2 PVT数据点加载函数

//自动添加void AppendPVTPoints(MC_PATH_REF hMemHandle,double (&dTable)[NC_PVT_ECAM_MAX_ARRAY_SIZE],unsigned long ulNumberOfPoints,unsigned char ucIsTimeAbsolute = 0,NC_MOTION_TABLE_TYPE_ENUM eTableType = eNC_TABLE_PVT_ARRAY) throw (CMMCException);/** \brief 此函数将点追加到现有表* \参数  hMemHandle - 指向共享内存指针所在的日志项的句柄* \参数  dTable[NC_PVT_ECAM_MAX_ARRAY_SIZE] - 指向数组值表的指针,数组最大值限制为170。* \参数  ulNumberOfPoints - 要追加的行中点数,任何+ve值都可以接受。* 					例如:对于三轴,一个轨迹点即一行,有7个参数(T,Px,Vx,Py,Vy,Pz,Vz),要添加n个轨迹点,则数组中共有7n个点,此时ulNumberOfPoints为n* \参数  ucIsTimeAbsolute - 时间是绝对的吗?*                	0为绝对,每一个“时间”输入都被用作绝对时间,此时当前点将结束运动并到达所需位置。*                  1为相对,每一个“时间”输入都被用作从以前的点移动到当前点结束所花费的时间。* \参数  NC_MOTION_TABLE_TYPE_ENUM eTableType - 这个枚举用作这些函数的输入,以便区分ECAM和PVT.目前只能应用eNC_TABLE_PVT_FILE和eNC_TABLE_PVT_ARRAY。* \return void*///--------------------------------------------------------------------------------------------
//手动添加void AppendPVTPoints(MC_PATH_REF hMemHandle,double (&dTable)[NC_PVT_ECAM_MAX_ARRAY_SIZE],unsigned long ulNumberOfPoints,unsigned long ulStartIndex,unsigned char ucIsTimeAbsolute = 0,NC_MOTION_TABLE_TYPE_ENUM eTableType = eNC_TABLE_PVT_ARRAY) throw (CMMCException);

6.3 PVT移动函数

//PVT运动virtual void MovePVT(MC_PATH_REF hMemHandle, MC_COORD_SYSTEM_ENUM eCoordSystem) throw (CMMCException);/** \brief  这个函数沿着PT/PVT表移动(在线样条)* \param hMemHandle - 表访问句柄* \param eCoordSystem - 坐标系设置 - 与单轴无关* \return 0 执行成功则返回0,否则执行错误*///PT运动virtual int MovePT(MC_PATH_REF hMemHandle, MC_COORD_SYSTEM_ENUM eCoordSystem) throw (CMMCException);

7.PVT 使用教程

7.1 使用方法

三步走(数组方式静态加载):

  1. InitPVTTable()
  2. AppendPVTPoints() / AppendPointsToPVTTable()
  3. MovePVT()

7.2 例程

在这里插入图片描述

/*================================================================================Name: 		pvt_motor.cppAuthor:	Jack SoongVersion:	1.00Description:	测试数组加载的PVT功能================================================================================*/
#include "mmc_definitions.h"
#include "mmcpplib.h"
#include <iostream>
#include <unistd.h>using namespace std;int giAxis1Status,giAxis2Status,giAxis3Status,giAxis4Status;void TableUnderflow(unsigned short usAxisRef);
void Emergency_Received(unsigned short usAxisRef, short sEmcyCode);
int  CallbackFunc(unsigned char* recvBuffer, short recvBufferSize,void* lpsock);
void SetData();
//===========================================================================================
int main(int argc, char* argv[])
{CMMCConnection MyConnectionClass;unsigned int ui_conn_hndl;CMMCGroupAxis Group1;CMMCSingleAxis Axis1,Axis2,Axis3,Axis4;ui_conn_hndl = MyConnectionClass.ConnectIPCEx(0x7fffffff,(MMC_MB_CLBK)CallbackFunc);MyConnectionClass.GetVersion();MyConnectionClass.GetVersion_Ex();//关联轴Axis1.InitAxisData("a01",ui_conn_hndl);Axis2.InitAxisData("a02",ui_conn_hndl);Axis3.InitAxisData("a03",ui_conn_hndl);Axis4.InitAxisData("a04",ui_conn_hndl);//为特定类型回调注册事件回调MyConnectionClass.RegisterEventCallback(MMCPP_TABLE_UNDERFLOW,(void*)TableUnderflow);MyConnectionClass.RegisterEventCallback(MMCPP_EMCY, (void*)Emergency_Received);MMC_MOTIONPARAMS_GROUP	stVectorDefault ;stVectorDefault.fAcceleration	= 1000000;                             //加速度stVectorDefault.fDeceleration	= 1000000;                           //负加速度stVectorDefault.fJerk			= 20000000;                         //加加速度stVectorDefault.fVelocity		= 1000000;                          //速度stVectorDefault.eBufferMode		= MC_BUFFERED_MODE;             //定义轴的行为stVectorDefault.eTransitionMode	= MC_TM_NONE_MODE;                 //转换模式stVectorDefault.eCoordSystem	= MC_ACS_COORD;                //定义支持的坐标系统的类型stVectorDefault.m_uiExecDelayMs = 0;                             //执行下一个动作的延迟(以秒为单位)。任意+ve整数值stVectorDefault.ucSuperimposed 	= 0;                            //是否操作了叠加选项stVectorDefault.ucExecute		=1;                           //从上升边缘启动执行命令// Initialize Vctor names and default parameters.初始化Vctor名称和默认参数。Group1.InitAxisData("v01",ui_conn_hndl) ; //关联轴组Group1.SetDefaultParams(stVectorDefault); //更新轴组参数///giAxis1Status 	= Axis1.ReadStatus() ;if(giAxis1Status & NC_AXIS_ERROR_STOP_MASK){Axis1.Reset() ;giAxis1Status 	= Axis1.ReadStatus() ;}giAxis2Status 	= Axis2.ReadStatus() ;if(giAxis2Status & NC_AXIS_ERROR_STOP_MASK){Axis2.Reset() ;giAxis2Status 	= Axis2.ReadStatus() ;}giAxis3Status 	= Axis3.ReadStatus() ;if(giAxis3Status & NC_AXIS_ERROR_STOP_MASK){Axis3.Reset() ;giAxis3Status 	= Axis3.ReadStatus() ;}giAxis4Status 	= Axis4.ReadStatus() ;if(giAxis4Status & NC_AXIS_ERROR_STOP_MASK){Axis4.Reset() ;giAxis4Status 	= Axis4.ReadStatus() ;}/*-----------------------   All axis and group enable     ----------------------------*/Axis1.PowerOn();while (!(Axis1.ReadStatus() & NC_AXIS_STAND_STILL_MASK));Axis2.PowerOn();while (!(Axis2.ReadStatus() & NC_AXIS_STAND_STILL_MASK));Axis3.PowerOn();while (!(Axis3.ReadStatus() & NC_AXIS_STAND_STILL_MASK));Axis4.PowerOn();while (!(Axis4.ReadStatus() & NC_AXIS_STAND_STILL_MASK));cout<<"aaa"<<endl;Group1.GroupEnable();cout<<"bbb"<<endl;while (!(Group1.ReadStatus() & NC_GROUP_STANDBY_MASK));cout<<"ccc"<<endl;/*-----------------------    Go Home    ----------------------------*//* All axis go back to absolute 0 position *///所有电机回零//两种写法,如果不用类,直接指定,则可以直接赋值,具体参考手册 Group移动部分//轴组回零有问题double db_pos[4] = {0,0,0,0};Group1.MoveLinearAbsolute(100000, db_pos); //参数1为最大的速度值,参数2为轴运动目标while (!(Group1.ReadStatus() & NC_GROUP_STANDBY_MASK));sleep(0.5);/*-----------------------    Set data table       ----------------------------*//*-----------------------    PVT Table Setting    ----------------------------*/MC_PATH_REF PVTReference;double dTable[170]={0,	0,	0,	0,	0,	0,	0,	0,	0,1,	655360,	1000000,	655360,	1000000,	655360,	1000000,	655360,	1000000,0.2,	1310720,	1000000,	1310720,	1000000,	1310720,	1000000,	1310720,	1000000,0.2,	1966080,	1000000,	1966080,	1000000,	1966080,	1000000,	1966080,	1000000,0.2,	2621440,	1000000,	2621440,	1000000,	2621440,	1000000,	2621440,	1000000,0.2,	3276800,	1000000,	3276800,	1000000,	3276800,	1000000,	3276800,	1000000,0.2,	3932160,	1000000,	3932160,	1000000,	3932160,	1000000,	3932160,	1000000,0.2,	4587520,	1000000,	4587520,	1000000,	4587520,	1000000,	4587520,	1000000,0.2,	5242880,	1000000,	5242880,	1000000,	5242880,	1000000,	5242880,	1000000,0.2,	5898240,	1000000,	5898240,	1000000,	5898240,	1000000,	5898240,	1000000,1,	6553600,	0,	6553600,	0,	6553600,	0,	6553600,	0,};///*-----------------------    PVT Motion    ----------------------------*/PVTReference = Group1.InitPVTTable(300,3,0,1,4,MC_ACS_COORD);Group1.AppendPVTPoints(PVTReference,dTable,11);//相对时间Group1.MovePVT(PVTReference,MC_ACS_COORD);int GroupStatus;while(!((GroupStatus = Group1.ReadStatus()) & NC_GROUP_STANDBY_MASK)){usleep(1000);cout << "Moving !!!" << endl;}/*-----------------------    卸载PVT数据,Disable各轴及轴组      ----------------------------*/Group1.UnloadPVTTable(PVTReference);Group1.GroupDisable();Axis1.PowerOff();Axis2.PowerOff();Axis3.PowerOff();Axis4.PowerOff();MMC_CloseConnection(ui_conn_hndl);printf("Program finished\n");return 0;
}
//===========================================================================================void TableUnderflow(unsigned short usAxisRef)
{cout << "usAxisRef = " << usAxisRef << endl;//bSendpoints = true;return;
}void Emergency_Received(unsigned short usAxisRef, short sEmcyCode)
{printf("Emergency Message Received on Axis %d. Code: %x\n",usAxisRef,sEmcyCode) ;
}int CallbackFunc(unsigned char* recvBuffer, short recvBufferSize,void* lpsock)
{switch(recvBuffer[1]){case EMCY_EVT:printf("Emergency Event received\r\n") ;break ;case MOTIONENDED_EVT:printf("Motion Ended Event received\r\n") ;break ;case HBEAT_EVT:printf("H Beat Fail Event received\r\n") ;break ;case PDORCV_EVT:printf("PDO Received Event received - Updating Inputs\r\n") ;break ;case DRVERROR_EVT:printf("Drive Error Received Event received\r\n") ;break ;case HOME_ENDED_EVT:printf("Home Ended Event received\r\n") ;break ;case SYSTEMERROR_EVT:printf("System Error Event received\r\n") ;break ;}return 1 ;
}

在这里插入图片描述

这篇关于Platinum Maestro运动控制器 —— PVT模式笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/377501

相关文章

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

模版方法模式template method

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序

迭代器模式iterator

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/iterator 不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素

查看提交历史 —— Git 学习笔记 11

查看提交历史 查看提交历史 不带任何选项的git log-p选项--stat 选项--pretty=oneline选项--pretty=format选项git log常用选项列表参考资料 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的 工具是 git log 命令。 接下来的例子会用一个用于演示的 simplegit