通过编程创建凸轮
作为 CODESYS SoftMotion 版本 4.17.0.0, CamBuilder
功能块提供了在 IEC 应用程序中直接以编程方式创建凸轮的接口。
有关详细信息,请参阅示例: 通过编程创建凸轮
使用 CamBuilder 功能块(自 SM 4.17.0.0 起)
在设备树中创建凸轮对象时,默认创建以下凸轮:

凸轮由三个五次多项式组成,具有以下四个边界值:
X | Y | V | A |
---|---|---|---|
0 | 0 | 0 | 0 |
120 | 120 | 1 | 0 |
240 | 240 | 1 | 0 |
360 | 360 | 0 | 0 |
要以编程方式创建此凸轮, CamBuilder
功能块首先声明:
VAR camBuilder : SMCB.CamBuilder; END_VAR
在实现部分, CamBuilder
实例必须先初始化。三个类型的段 Poly5
然后可以使用 Append
方法:
camBuilder.Init(); camBuilder.Append( SMCB.Poly5( SMCB.BoundImplicit(), SMCB.Bound(120, 120, 1))); camBuilder.Append( SMCB.Poly5( SMCB.BoundImplicit(), SMCB.Bound(240, 240, 1))); camBuilder.Append( SMCB.Poly5( SMCB.BoundImplicit(), SMCB.Bound(360, 360)));
多项式通过左边界条件和右边界条件定义。在本例中, BoundImplicit
函数始终用于左边界。因此,将应用前一段的右边界条件。如果 BoundImplicit
函数用作第一个段的左边界,那么它从零开始:在这个例子中,Poly5 段位于 (X, Y, V, A) = (0, 0, 0, 0)。
当 MC_CamTableSelect
和 MC_CamIn
使用功能块,凸轮定义在 CamBuilder
最后必须将功能块转换为 MC_CamRef
。有两种方法可以执行此操作,具体取决于调用 CamBuilder 的位置
在总线任务中调用 CamBuilder:
首先,声明部分必须通过相应的实例进行扩展:
VAR ... camRef : MC_CAM_REF; aCamSegments : ARRAY[1..3] OF SMC_CAM_SEGMENT; END_VAR
然后是函数块实例
MC_CAM_REF
使用初始化和写入Write
的方法CamBuilder
功能块。SMCB.InitCamRef(camRef, ADR(aCamSegments), XSIZEOF(aCamSegments)); camBuilder.Write(camRef);
在另一项任务(多任务、多核)中调用 CamBuilder:
首先,在 GVL 中创建 Cam 的多任务/多核安全实例,总线任务和 CamBuilder 任务均可访问该实例。
VAR_GLOBAL safeCam : SMCB.CAM_REF_MULTICORE_SAFE; END_VAR
然后,从总线任务开始在另一个任务中创建摄像头。
为了确定总线任务中何时在另一个任务中写入新摄像头,程序会记住
CamId
在STATE_INIT_ONLINE_TABLE_MULTITASK
在创建摄像头之前。然后,在另一个任务中开始创建摄像头
STATE_START_CREATE_ONLINE_TABLE_MULTITASK
州。然后,将创建的摄像头读入
STATE_READ_ONLINE_TABLE_MULTITASK
州。
PROGRAM BUS_TASK VAR state : UDINT; error : SMC_ERROR; camIdBeforeCreate : UDINT; camSegments: ARRAY[0..99] OF SMC_CAM_SEGMENT; camRef: MC_CAM_REF; END_VAR VAR CONSTANT STATE_INIT_ONLINE_TABLE_MULTITASK : UDINT := 0; STATE_START_CREATE_ONLINE_TABLE_MULTITASK : UDINT := 10; STATE_READ_ONLINE_TABLE_MULTITASK : UDINT := 20; STATE_ERROR : UDINT := 1000; END_VAR CASE state OF STATE_INIT_ONLINE_TABLE_MULTITASK: camIdBeforeCreate := GVL.safeCam.CamId; state := STATE_START_CREATE_ONLINE_TABLE_MULTITASK; STATE_START_CREATE_ONLINE_TABLE_MULTITASK: CamBuilderTask.BuildCam := TRUE; state := STATE_READ_ONLINE_TABLE_MULTITASK; STATE_READ_ONLINE_TABLE_MULTITASK: IF CamBuilderTask.Error THEN error := CamBuilderTask.ErrorId; state := state + STATE_ERROR; ELSIF GVL.safeCam.CamId <> camIdBeforeCreate THEN error := GVL.safeCam.GetCopy( camRef:= camRef, pCamSegments:= ADR(camSegments), arraySize:= XSIZEOF(camSegments)); IF error = SMC_NO_ERROR THEN state := state + 10; ELSE state := state + STATE_ERROR; END_IF END_IF END_CASE
在 CamBuilder 任务中,多任务/多核安全摄像头是通过调用编写的
CamBuilder.WriteMulticoreSafe()
:PROGRAM CamBuilderTask VAR_INPUT BuildCam : BOOL; END_VAR VAR_OUTPUT Error : BOOL; ErrorId : SMC_ERROR; END_VAR VAR camBuilder : SMCB.CamBuilder; END_VAR IF BuildCam THEN BuildCam := FALSE; camBuilder.Init(); camBuilder.Append(SMCB.Poly5(SMCB.BoundImplicit(), SMCB.Bound(120, 120, 1))); camBuilder.Append(SMCB.Poly5(SMCB.BoundImplicit(), SMCB.Bound(240, 240, 1))); camBuilder.Append(SMCB.Poly5(SMCB.BoundImplicit(), SMCB.Bound(360, 360))); Error := camBuilder.IsErrorPending(errorID=> ErrorId); IF NOT Error THEN ErrorId := camBuilder.WriteMulticoreSafe(GVL.safeCam); Error := ErrorId <> SMC_NO_ERROR; END_IF END_IF
隐式和显式边界条件
隐式边界条件定义为 BoundImplicit
确保与相邻段的过渡尽可能平稳。为此,需要使用 Bound
方法。因此,如果某段的左边界条件是隐式的,则前一段的右边界条件必须是显式的。相反,如果右边界条件是隐式的,则后一段的左边界条件必须是显式的。
最常见的用例大概是仅明确指定段的右边界条件,如上例所示。由于隐式左边界条件,段过渡自动尽可能平滑,并且定义区域中没有间隙。以下示例是一个简单的案例,偏离此方法是有帮助的:
从属轴应以恒定速度从位置 20 移动到 100:
camBuilder.Append( SMCB.Line( SMCB.Bound(20, 20), SMCB.Bound(100, 100)));
在此之前和之后, Poly5
段用于加速和减速:
camBuilder.Append( SMCB.Poly5( SMCB.BoundImplicit(), SMCB.BoundImplicit())); camBuilder.Append( SMCB.Line( SMCB.Bound(20, 20), SMCB.Bound(100, 100))); camBuilder.Append( SMCB.Poly5( SMCB.BoundImplicit(), SMCB.Bound(120, 120, 0)));
以此方式定义的凸轮在 Poly5 段中具有不必要的加速和减速阶段(速度以蓝色表示):

为了避免这种情况,只需调整类型段中的主位置即可 Line
(例如左边界从 20 到 30,右边界从 100 到 90):
... camBuilder.Append( SMCB.Line( SMCB.Bound(30, 20), SMCB.Bound(90, 100))); ...

无需调整字型 Poly5
因为它们会根据使用定义的边界条件自动尽可能平滑地添加到线段 BoundImplicit
功能。
错误处理
这 Append
方法 CamBuilder
功能块返回 TRUE
当成功添加段时,返回 FALSE
如果发生错误。发生错误后,无法再添加任何段,并且 CamBuilder
功能块必须使用重新初始化 Init
方法。可以使用 IsErrorPending
方法:
camBuilder.IsErrorPending(errorId=> errorId);
手动创建数据结构 MC_CAM_REF(SM 4.17.0.0 之前)
重要
建议使用 SM3_CamBuilder 图书馆 CODESYS SoftMotion 4.17.0.0。
凸轮的数据结构
在项目编译时,创建的凸轮数据将在内部转换为全局变量列表。通过单击 显示生成的代码 在凸轮编辑器中,您可以显示自动创建的全局变量。
每个凸轮由数据结构表示 MC_CAM_REF
。您可以通过 IEC 程序或预处理函数和功能块访问此数据结构。它可通过 SM3_Basic
图书馆。
描述凸轮的功能块也可由 IEC 程序在运行时生成或填充。
数据结构定义:
TYPE mySMC_CAMTable_LREAL_10000_2 : STRUCT Table: ARRAY[0..9999] OF ARRAY[0..1] OF LREAL; (* set all scaling definitions to 0 and 1 result: all values of the table are not scaled *) fEditorMasterMin: REAL := 0; fEditorMasterMax: REAL := 1; fEditorSlaveMin: REAL := 0; fEditorSlaveMax: REAL := 1; fTableMasterMin: REAL := 0; fTableMasterMax: REAL := 1; fTableSlaveMin: REAL := 0; fTableSlaveMax: REAL := 1; END_STRUCT END_TYPE
实例化数据结构:
Cam: MC_CAM_REF; Cam_PointArray : mySMC_CAMTable_LREAL_10000_2;
计算凸轮:
Cam.byType:=2; Cam.byVarType:=6; Cam.nTappets:=0; Cam.strCAMName:='myCAM'; Cam.pce:= ADR(CAM_PointArray); FOR i:=0 TO 9999 DO (* example cam: master 0..360, slave 0..100, constant velocity *) Cam_PointArray.Table[i][0]:=UDINT_TO_LREAL(I)/10000 * 360; (* X *) Cam_PointArray.Table[i][1]:=UDINT_TO_LREAL(I)/10000 * 100; (* Y *) END_FOR Cam.nElements:=10000 Cam.xStart:=0.0; Cam.xEnd:=360.0;
手动生成的凸轮
无需使用凸轮编辑器即可在 IEC 程序中创建凸轮。
宣言:
VAR i: INT; CAM: MC_CAM_REF := ( byType:=2, (* non-equidistant *) byVarType:=2, (* UINT *) nElements:=128, xStart:=0, xEnd:=360); Table: SMC_CAMTable_UINT_128_2 := ( fEditorMasterMin := 0, fEditorMasterMax := 360, fTableMasterMin := 0, fTableMasterMax := 6000, fEditorSlaveMin := 0, fEditorSlaveMax := 360, fTableSlaveMin := 0, fTableSlaveMax := 6000); END_VAR
执行:
(* Create cam disk (example straight line); unambiguous *) FOR i:=0 TO 127 DO Table.Table[i][0] := Table.Table[i][1] := REAL_TO_UINT(i / 127.0 * 6000); END_FOR (* Link pointer; must be done in every cycle! *) CAM.pce := ADR(Table);
生成的凸轮可以在 MC_CamTableSelect
功能块及其输出再次用于 MC_CamIn
。
编译凸轮定义
在编译时,类型变量 MC_CAM_REF
为凸轮创建。它们包括凸轮每个部分的描述。这种数据结构被传递给 MC_凸轮表选择
功能块。结构是 SM3_Basic
图书馆。