Started kuka robot integration with hardware

- Modified PackML state machine to be able to disable unused states
- Added PackTag datatypes for recipe handling
- Started recipe parameter description in json file
- Added schema file for recipe json
- Added state machine drawing for packml
This commit is contained in:
2026-01-30 09:09:30 +01:00
parent 3946e45c65
commit 67ba80893f
44 changed files with 2006 additions and 1366 deletions

View File

@@ -4,6 +4,9 @@
<Declaration><![CDATA[// Positionen in um <=> 0.001mm
FUNCTION_BLOCK FINAL FB_KukaRobot EXTENDS FB_PackMLGeneric
VAR_INPUT
eRobotJob : E_KukaRobot_JobNumberRobot;
xReleaseAlarms : BOOL;
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
@@ -56,13 +59,16 @@ VAR
_xError : BOOL;
// ======
// Alarms
// ======
_fbAlarmNotInExtMode : FB_AlarmMessage(stEventEntry := TC_EVENTS.RobotEvents.RobotNotInExtMode, xWithConfirmation := FALSE);
_fbAlarmEStopActive : FB_AlarmMessage(stEventEntry := TC_EVENTS.RobotEvents.RobotEStopActive, xWithConfirmation := FALSE);
_fbAlarmOperatorSafetyNotOk : FB_AlarmMessage(stEventEntry := TC_EVENTS.RobotEvents.OperatorSafetyNotOk, xWithConfirmation := FALSE);
_fbAlarmNotInExtMode : FB_AlarmMessage(stEventEntry := TC_EVENTS.KukaRobot.NotInExtMode, xWithConfirmation := FALSE);
_fbAlarmEStopActive : FB_AlarmMessage(stEventEntry := TC_EVENTS.KukaRobot.EStopActive, xWithConfirmation := FALSE);
_fbAlarmOperatorSafetyNotOk : FB_AlarmMessage(stEventEntry := TC_EVENTS.KukaRobot.OperatorSafetyNotOk, xWithConfirmation := FALSE);
_fbAlarmRobotErrorResetTimeout : FB_AlarmMessage(stEventEntry := TC_EVENTS.KukaRobot.ErrorResetTimeout, xWithConfirmation := TRUE);
_fbAlarmDrivesEnableTimeout : FB_AlarmMessage(stEventEntry := TC_EVENTS.KukaRobot.DrivesEnableTimeout, xWithConfirmation := TRUE);
END_VAR
]]></Declaration>
<Implementation>
@@ -91,12 +97,22 @@ _fbAlarmOperatorSafetyNotOk(
timOnDelay:= T#0S,
timOffDelay:= T#0S);
// Handled by M_Resetting
_fbAlarmDrivesEnableTimeout(
xRelease:= xReleaseAlarms,
xAcknowledge:= xConfirmAlarms);
// Handled by M_Resetting
_fbAlarmRobotErrorResetTimeout(
xRelease:= xReleaseAlarms,
xAcknowledge:= xConfirmAlarms);
// =======================
// Check if robot is ready
// =======================
_xRobotReady := _uState.stState.bExt
_xRobotReady := _uState.stState.bExt
AND _uState.stState.bAlarmStop
AND _uState.stState.bUserSAF
AND _uState.stState.bPeriRdy
@@ -118,9 +134,7 @@ SUPER^();
_uCtrl.stCtrl.bNotDisableAxes := 1;
// Disable move if in T2 for safety reasons
IF (NOT _uState.stState.bT2) THEN
_uCtrl.stCtrl.bEnableMove := 1;
ELSE
IF _uState.stState.bT2 THEN
_uCtrl.stCtrl.bEnableMove := 0;
END_IF
@@ -129,8 +143,8 @@ END_IF
// Write job outputs
// ==================
_uJobs.stJobs.wJobNrForRobot := _eRobotJob;
_uJobs.stJobs.wFinishedJobNrFromPlc := _ePlcJob;
//_uJobs.stJobs.wJobNrForRobot := _eRobotJob;
//_uJobs.stJobs.wFinishedJobNrFromPlc := _ePlcJob;
// =================
@@ -140,15 +154,225 @@ _uJobs.stJobs.wFinishedJobNrFromPlc := _ePlcJob;
xReady := _xRobotReady;
xError := _xError;]]></ST>
</Implementation>
<Method Name="FB_Init" Id="{71a3f6f0-d3bb-4348-acc7-be533d7488d2}">
<Declaration><![CDATA[//FB_Init ist immer implizit verfügbar und wird primär für die Initialisierung verwendet.
//Der Rückgabewert wird nicht ausgewertet. Für gezielte Einflussnahme können Sie
//die Methoden explizit deklarieren und darin mit dem Standard-Initialisierungscode
//zusätzlichen Code bereitstellen. Sie können den Rückgabewert auswerten.
METHOD FB_Init: BOOL
VAR_INPUT
bInitRetains: BOOL; // TRUE: Die Retain-Variablen werden initialisiert (Reset warm / Reset kalt)
bInCopyCode: BOOL; // TRUE: Die Instanz wird danach in den Kopiercode kopiert (Online-Change)
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[_stSMConfig.xStoppingDisabled := TRUE;
_stSMConfig.xCompletingDisabled := TRUE;
_stSMConfig.xCompletedDisabled := TRUE;
_stSMConfig.xAbortingDisabled := TRUE;]]></ST>
</Implementation>
</Method>
<Method Name="M_Aborted" Id="{0c0c17ce-5c1c-4640-9d39-f25b22309d5d}">
<Declaration><![CDATA[METHOD M_Aborted
]]></Declaration>
<Implementation>
<ST><![CDATA[// Reset all relevant robot control signals
_uCtrl.stCtrl.bConfMess := 0;
_uCtrl.stCtrl.bExtStart := 0;
_uCtrl.stCtrl.bEnableAxes := 0;
_uCtrl.stCtrl.bEnableMove := 0;
_uCtrl.stCtrl.bNotDisableAxes := 1;
_uCtrl.stCtrl.bAbortJob := 1;
// Reset robot program and plc job number
_uJobs.stJobs.wJobNrForRobot := E_KukaRobot_JobNumberRobot.NO_JOB;
_uJobs.stJobs.wFinishedJobNrFromPlc := E_KukaRobot_JobNumerPLC.NO_JOB;]]></ST>
</Implementation>
</Method>
<Method Name="M_Clearing" Id="{e6152288-8c7d-4b38-bfbc-4f861d76ccc5}">
<Declaration><![CDATA[METHOD M_Clearing
VAR_INST
_tonWait : TON;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[_tonWait(IN := TRUE, PT := T#1S);
_uCtrl.stCtrl.bEnableMove := 1;
_uCtrl.stCtrl.bAbortJob := 0;
IF _tonWait.Q THEN
_tonWait(IN := FALSE, PT := T#1S);
M_StateComplete();
END_IF
]]></ST>
</Implementation>
</Method>
<Method Name="M_Execute" Id="{bc86876c-a8db-4285-b95c-7c6858a2ca66}">
<Declaration><![CDATA[METHOD M_Execute
]]></Declaration>
<Implementation>
<ST><![CDATA[// Wait for robot to be done
IF _awJobStatesFromRobot[0] = 0 THEN
_eCmd := E_PackMLCmd.COMPLETE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Held" Id="{22ddbad0-0b66-427e-a2aa-f177f8adbc94}">
<Declaration><![CDATA[METHOD M_Held
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Holding" Id="{ff8c2c8e-1fe0-4c63-ad7b-790d72bd9217}">
<Declaration><![CDATA[METHOD M_Holding
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Idle" Id="{025437ab-beb0-4ad6-bdc3-468dec599ff4}">
<Declaration><![CDATA[METHOD M_Idle
]]></Declaration>
<Implementation>
<ST><![CDATA[
]]></ST>
</Implementation>
</Method>
<Method Name="M_Resetting" Id="{dfe4d36a-80aa-4364-bfd8-6ddd41636d59}">
<Declaration><![CDATA[METHOD M_Resetting
VAR_INST
_tonTimeout : TON;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[_tonTimeout(PT := T#10S);
CASE _iSSM OF
0:
_uCtrl.stCtrl.bEnableAxes := 1;
_tonTimeout.IN := TRUE;
// Wait for drives to be ready
IF _uState.stState.bPeriRdy THEN
_uCtrl.stCtrl.bEnableAxes := 0;
_tonTimeout(IN := FALSE);
_iSSM := 10;
END_IF
// Timeout drives ready
IF _tonTimeout.Q THEN
_uCtrl.stCtrl.bEnableAxes := 0;
_fbAlarmDrivesEnableTimeout.xRelease := TRUE;
_tonTimeout(IN := FALSE);
_eCmd := E_PackMLCmd.ABORT;
END_IF
10:
_uCtrl.stCtrl.bConfMess := 1;
_tonTimeout.IN := TRUE;
// Wait for errors to be reset
IF (NOT _uState.stState.bStopMess) THEN
_uCtrl.stCtrl.bConfMess := 0;
_tonTimeout(IN := FALSE);
_iSSM := 20;
END_IF
// Timeout reset errors
IF _tonTimeout.Q THEN
_fbAlarmRobotErrorResetTimeout.xRelease := TRUE;
_tonTimeout(IN := FALSE);
_eCmd := E_PackMLCmd.ABORT;
END_IF
20:
// Start main program
_uCtrl.stCtrl.bExtStart := 1;
_tonTimeout.IN := TRUE;
IF _tonTimeout.Q THEN
_tonTimeout(IN := FALSE);
_eCmd := E_PackMLCmd.ABORT;
END_IF
IF _uState.stState.bProAct THEN
_uCtrl.stCtrl.bExtStart := 0;
_tonTimeout(IN := FALSE);
M_StateComplete();
END_IF
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="M_Starting" Id="{011f85d8-1225-4288-876f-918df6e4f235}">
<Declaration><![CDATA[METHOD M_Starting
]]></Declaration>
<Implementation>
<ST><![CDATA[// Write robot job number
_uJobs.stJobs.wJobNrForRobot := DINT_TO_WORD(_stRecipe.stProcessVariables.astParameterDInt[0].Value);
// Gripper number
_abToolsAndPositions[0] := DINT_TO_BYTE(_stRecipe.stProcessVariables.astParameterDInt[1].Value);
// If job number is read back correct, go to next state
IF _awJobStatesFromRobot[0] = _uJobs.stJobs.wJobNrForRobot THEN
_uJobs.stJobs.wJobNrForRobot := E_KukaRobot_JobNumberRobot.NO_JOB;
M_StateComplete();
END_IF
// Wrong job read back from robot -> Abort
// IF _awJobStatesFromRobot[0] <> 0 AND _awJobStatesFromRobot[0] <> E_KukaRobot_JobNumberRobot.WARMUP THEN
// _eCmd := E_PackMLCmd.ABORT;
// END_IF
//
// // Robot has error
// IF _dwErrorBits <> 0 THEN
// _eCmd := E_PackMLCmd.ABORT;
// END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Stopped" Id="{50813767-4bd7-4147-b5dc-1bbd18ae1555}">
<Declaration><![CDATA[METHOD M_Stopped
]]></Declaration>
<Implementation>
<ST><![CDATA[_uCtrl.stCtrl.bConfMess := 0;
_uCtrl.stCtrl.bEnableAxes := 0;
_uCtrl.stCtrl.bNotDisableAxes := 1;
_uCtrl.stCtrl.bExtStart := 0;
_eRobotJob := E_KukaRobot_JobNumberRobot.NO_JOB;
_ePlcJob := E_KukaRobot_JobNumerPLC.NO_JOB;
]]></ST>
_ePlcJob := E_KukaRobot_JobNumerPLC.NO_JOB;]]></ST>
</Implementation>
</Method>
<Method Name="M_Suspended" Id="{c2db015c-1cd0-491a-8ce6-6c0bffba7631}">
<Declaration><![CDATA[METHOD M_Suspended
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Suspending" Id="{5b0e5227-d5bb-40c6-a1b8-8e81b852b9b9}">
<Declaration><![CDATA[METHOD M_Suspending
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Unholding" Id="{786f4949-9630-4ace-9e30-65bea4e87cb2}">
<Declaration><![CDATA[METHOD M_Unholding
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Unsuspending" Id="{d7ce33fd-cd94-44f1-9289-25a3ab3829eb}">
<Declaration><![CDATA[METHOD M_Unsuspending
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
</POU>