diff --git a/CHANGELOG.md b/CHANGELOG.md index be6e1abfb..bd8ae6978 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +### [FIX] `AxoKrc5` local E-stop monitoring, 20002 rekey, opt-in task-timeout watchdog + +**Note:** PLC fix in `src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/`. KRC5-only — `AxoKrc4` is unchanged. **Breaking:** public input `Inputs.Automatic` renamed to `Inputs.LocalEstopOk`. Branch: `1168-bug-update-krc4-following-the-updates-on-krc5` ([#1177](https://github.com/Inxton/AXOpen/pull/1177), refs #1168). + +- fix!: Input bit `%X2` repurposed from `Inputs.Automatic` ("Automatic [AUT]") to `Inputs.LocalEstopOk` ("Local Emergency Stop OK"). Whenever `LocalEstopOk = FALSE` the component raises new error **20006** (`Error`) — unconditionally, every cycle, outside the task-busy safety gate that drives 20001–20005. Matching messenger text and `errorDescriptionDict` entries added to the .NET twin (`AxoKrc5.cs`); `AxoKrc5View.razor` header badge and inputs panel rebound to `LocalEstopOk` (polling updated in `AxoKrc5View.razor.cs`). +- fix: Safety message **20002** rekeyed to `Inputs.ExternalAutomatic = FALSE` (previously `Inputs.Automatic`, whose bit was repurposed); still raised as `Info` while a task is busy. +- fix: Task-duration watchdog reinstated as **opt-in** (partially reverting #1167): every task except `StartMotors` calls `ThrowWhen(Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s, '{TaskName} timeout.')`. Config defaults changed `ErrorTime LT#5S → LT#0S`, `TaskTimeout LT#50S → LT#0S`, so the watchdog stays disabled out of the box; the `_errorTimer` (`ErrorTime`) watchdog remains removed. +- feat: Robot-side stop messages are auto-acknowledged — `Outputs.ErrorConfirmation := Inputs.StopMess AND NOT _blink.output` pulses during the waiting phases of `StartAtMain`, `StartMotorsAndProgram`, `StartMotorsProgramAndMovements`, `StartMotors`, `StartMovements`, and `StartProgram`. Blinker centralised to a single 1 s `_blink.Blink()` tick per `Run()` cycle (`BLINKER_TIME : TIME := T#1S`); per-task 500 ms blink calls removed. +- docs: `AxoKrc5.md` divergence note and Configuration section rewritten; `TROUBLES.md` records the per-class 20002 keying split, the new 20006 entry, and the KRC4 default-on vs KRC5 opt-in watchdog. Library CHANGELOG bumped to `0.63.0`; `GitVersion.yml` `next-version` `0.62.3 → 0.63.0` (minor — breaking rename recorded). + +**Impact:** A dropped local E-stop is now reported immediately and persistently (20006) instead of masquerading as a mode condition; stuck robot stop messages self-acknowledge; integrators can re-arm the task watchdog per application by setting `Config.TaskTimeout > 0s`. + +**Risks/Review:** Twin consumers and Blazor bindings referencing `AxoKrc5.Inputs.Automatic` must migrate to `Inputs.LocalEstopOk` (`AxoKrc4.Inputs.Automatic` unaffected). `StartMotorsTask` is the only task without the reinstated `ThrowWhen` — suspected oversight, documented as-is. Watchdog now defaults OFF (`LT#0S`) — applications relying on the old `LT#50S` self-abort must set it explicitly. + +**Testing:** `apax ib` in `src/components.kuka.robotics`; exercise KRC5 cell: 20006 on local E-stop drop, 20002 on external-auto drop, timeout abort with `TaskTimeout > 0s`, `ErrorConfirmation` pulse while `StopMess` active. + ### [CORE] `AxoRemoteTask` start/done handshake priority is now configurable (default Normal) (#TBD) **Note:** API addition + behavioral change in `src/core/src/AXOpen.Core/AxoRemoteTask/AxoRemoteTask.cs` (.NET twin only). No PLC source or PLC-side API change. Branch: `deps-update-0-47-0-alpha-495`. PR link to be filled in before merge. Follow-up to the High-priority batching entry below (commit `2a70cb744`). diff --git a/GitVersion.yml b/GitVersion.yml index f91634499..9de7fea54 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,5 +1,5 @@ mode: ContinuousDeployment -next-version: 0.62.3 +next-version: 0.63.0 branches: main: regex: ^master$|^main$ diff --git a/src/components.elements/src/AXOpen.Components.Elements.blazor/Resources/Strings.sk-SK.resx b/src/components.elements/src/AXOpen.Components.Elements.blazor/Resources/Strings.sk-SK.resx index b9b6ffdc3..d60523a1c 100644 --- a/src/components.elements/src/AXOpen.Components.Elements.blazor/Resources/Strings.sk-SK.resx +++ b/src/components.elements/src/AXOpen.Components.Elements.blazor/Resources/Strings.sk-SK.resx @@ -121,25 +121,25 @@ Požadovaná hodnota - Očakávajte HIGH + Očakávajte signál je prítomný - Očakávajte nízku úroveň + Očakávajte signál je neprítomný - VYSOKÁ kontrola + Signál prítomný? - NÍZKA kontrola + Signál neprítomný? Signál - Signál HIGH + Signál prítomný - Signál LOW + Signál neprítomný Prítomná pozitívna spätná väzba @@ -154,16 +154,16 @@ Vstup je bez napätia - Zapnutie spínača + Zapnúť - Vypínač OFF + Vypnúť Zapnutý signál - Signál OFF + Signál vypnutý Výstup je aktívny @@ -269,10 +269,10 @@ Prepínať akustický výstup, keď je požadovaný zvukový alarm. - Siréna ZAPNUTÁ + Siréna zapnutá - Siréna VYPNUTÁ + Siréna vypnutá Manuálne ovládanie diff --git a/src/components.elements/src/AXOpen.Components.Elements.blazor/Resources/Strings.sk.resx b/src/components.elements/src/AXOpen.Components.Elements.blazor/Resources/Strings.sk.resx index 916b924b8..12804287f 100644 --- a/src/components.elements/src/AXOpen.Components.Elements.blazor/Resources/Strings.sk.resx +++ b/src/components.elements/src/AXOpen.Components.Elements.blazor/Resources/Strings.sk.resx @@ -118,31 +118,28 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Signál VYPNUTÝ + Signál vypnutý Požadovaná hodnota - Očakávajte VYSOKÚ + Očakávajte signál je prítomný - Očakávajte NÍZKU + Očakávajte signál je neprítomný - Kontrola HIGH - - - Kontrola LOW + Signál prítomný? Signál - Signál HIGH + Signál prítomný - Signál LOW + Signál neprítomný Prítomná pozitívna spätná väzba @@ -159,9 +156,6 @@ Zapnúť - - Vypnúť - Signál zapnutý @@ -269,10 +263,10 @@ Prepínať akustický výstup, keď je požadovaný zvukový alarm. - Siréna ZAPNUTÁ + Siréna zapnutá - Siréna VYPNUTÁ + Siréna vypnutá Manuálne ovládanie @@ -313,4 +307,10 @@ Modrá + + Vypnúť + + + Signál neprítomný? + \ No newline at end of file diff --git a/src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/AxoKrc5.st b/src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/AxoKrc5.st index 4886e1e76..603c43eab 100644 --- a/src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/AxoKrc5.st +++ b/src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/AxoKrc5.st @@ -99,6 +99,11 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Config : AxoKrc5_Config; END_VAR + VAR CONSTANT INTERNAL + BLINKER_TIME : TIME := T#1S; + END_VAR + + VAR PUBLIC //STATUS {#ix-attr:[Container(Layout.Stack)]} {#ix-attr:[ComponentDetails("Status")]} @@ -306,7 +311,7 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Inputs.InHome := _data[1].%X0; Inputs.Manual := _data[1].%X1; - Inputs.Automatic := _data[1].%X2; + Inputs.LocalEstopOk := _data[1].%X2; Inputs.ExternalAutomatic := _data[1].%X3; Inputs.ProActive := _data[1].%X4; Inputs.PpMoved := _data[1].%X5; @@ -454,6 +459,8 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x END_IF; //**************************************** + _blink.Blink(Context := _context, inOnTime:=BLINKER_TIME,inOffTime:=BLINKER_TIME); + //*************StartAtMainTask************ StartAtMainTask.SetIsDisabled(_stopTasksAreActive); IF StartAtMainTask.StartTriggered() THEN @@ -462,13 +469,14 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Messenger.ActivateOnCondition(ULINT#100,StartAtMainTask.IsBusy(), eAxoMessageCategory#Info); Messenger.ActivateOnCondition(ULINT#101,StartAtMainTask.IsDone(), eAxoMessageCategory#Info); IF StartAtMainTask.Execute(THIS) THEN - _blink.Blink(Context := _context, inOnTime:=T#500MS,inOffTime:=T#500MS); + //_blink.Blink(Context := _context, inOnTime:=BLINKER_TIME,inOffTime:=BLINKER_TIME); IF _power_progress = 0 THEN Status.Error.Id := UINT#0; TaskMessenger.Restore(); THIS.CallTimers(FALSE); _power_progress := 300; END_IF; + // Start at main running: waiting for the program pointer changed. IF _power_progress = 300 THEN IF _infoTimer.output THEN @@ -480,6 +488,8 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Outputs.DrivesOff := TRUE; Outputs.ActionNo := BYTE#255; + Outputs.ErrorConfirmation := Inputs.StopMess AND NOT _blink.output; // try to ack error + Outputs.StartAtMain := NOT Inputs.PpMoved AND _blink.output; IF Inputs.PpMoved THEN @@ -496,7 +506,9 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x END_IF; THIS.CallTimers(TRUE); + //StartAtMainTask.ThrowWhen(_errorTimer.output ); Status.Action.Id := TO_UINT(_power_progress); + StartAtMainTask.ThrowWhen(StartAtMainTask.Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s ,'<#StartAtMainTask timeout.#>'); END_IF; IF StartAtMainTask.DoneReached() THEN Status.Action.Id := UINT#101; @@ -526,8 +538,7 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Messenger.ActivateOnCondition(ULINT#110,StartMotorsAndProgramTask.IsBusy(), eAxoMessageCategory#Info); Messenger.ActivateOnCondition(ULINT#111,StartMotorsAndProgramTask.IsDone(), eAxoMessageCategory#Info); IF StartMotorsAndProgramTask.Execute(THIS) THEN - _blink.Blink(Context := _context, inOnTime:=T#500MS,inOffTime:=T#500MS); - + //_blink.Blink(Context := _context, inOnTime:=BLINKER_TIME,inOffTime:=BLINKER_TIME); IF _power_progress = 0 THEN Status.Error.Id := UINT#0; TaskMessenger.Restore(); @@ -543,6 +554,8 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Outputs.MoveEnable := TRUE; Outputs.DrivesOff := TRUE; Outputs.ActionNo := BYTE#255; + + Outputs.ErrorConfirmation := Inputs.StopMess AND NOT _blink.output; // try to ack error IF Inputs.UserSafetySwitchClosed THEN THIS.CallTimers(FALSE); @@ -571,6 +584,8 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Outputs.DrivesOff:=TRUE; Outputs.DrivesOn:=_blink.output; + Outputs.ErrorConfirmation := Inputs.StopMess AND NOT _blink.output; // try to ack error + IF Inputs.DrivesReady THEN Outputs.DrivesOn:=FALSE; THIS.CallTimers(FALSE); @@ -646,7 +661,9 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x END_IF; THIS.CallTimers(TRUE); + //StartMotorsAndProgramTask.ThrowWhen(_errorTimer.output); Status.Action.Id := TO_UINT(_power_progress); + StartMotorsAndProgramTask.ThrowWhen(StartMotorsAndProgramTask.Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s ,'<#StartMotorsAndProgramTask timeout.#>'); END_IF; IF StartMotorsAndProgramTask.DoneReached() THEN Status.Action.Id := UINT#111; @@ -675,7 +692,7 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Messenger.ActivateOnCondition(ULINT#120,StartMotorsProgramAndMovementsTask.IsBusy(), eAxoMessageCategory#Info); Messenger.ActivateOnCondition(ULINT#121,StartMotorsProgramAndMovementsTask.IsDone(), eAxoMessageCategory#Info); IF StartMotorsProgramAndMovementsTask.Execute(THIS) THEN - _blink.Blink(Context := _context, inOnTime:=T#500MS,inOffTime:=T#500MS); + //_blink.Blink(Context := _context, inOnTime:=BLINKER_TIME,inOffTime:=BLINKER_TIME); IF _power_progress = 0 THEN Status.Error.Id := UINT#0; @@ -694,6 +711,8 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Outputs.DrivesOff := TRUE; Outputs.ActionNo := BYTE#255; + Outputs.ErrorConfirmation := Inputs.StopMess AND NOT _blink.output; // try to ack error + IF Inputs.UserSafetySwitchClosed THEN THIS.CallTimers(FALSE); _power_progress := 321; @@ -929,7 +948,9 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x END_IF; THIS.CallTimers(NOT _movementExecuting); + //StartMotorsProgramAndMovementsTask.ThrowWhen(_errorTimer.output); Status.Action.Id := TO_UINT(_power_progress); + StartMotorsProgramAndMovementsTask.ThrowWhen(StartMotorsProgramAndMovementsTask.Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s ,'<#StartMotorsProgramAndMovementsTask timeout.#>'); END_IF; IF StartMotorsProgramAndMovementsTask.IsFirstExecutionCycle() THEN MovementParameters := Status.CurrentMovementParameters; @@ -961,8 +982,7 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Messenger.ActivateOnCondition(ULINT#140,StartMotorsTask.IsBusy(), eAxoMessageCategory#Info); Messenger.ActivateOnCondition(ULINT#141,StartMotorsTask.IsDone(), eAxoMessageCategory#Info); IF StartMotorsTask.Execute(THIS) THEN - _blink.Blink(Context := _context, inOnTime:=T#500MS,inOffTime:=T#500MS); - + //_blink.Blink(Context := _context, inOnTime:=BLINKER_TIME,inOffTime:=BLINKER_TIME); IF _power_progress = 0 THEN Status.Error.Id := UINT#0; TaskMessenger.Restore(); @@ -978,6 +998,8 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Outputs.MoveEnable := TRUE; Outputs.DrivesOff := TRUE; + Outputs.ErrorConfirmation := Inputs.StopMess AND NOT _blink.output; // try to ack error + IF Inputs.UserSafetySwitchClosed THEN THIS.CallTimers(FALSE); _power_progress := 341; @@ -1019,6 +1041,7 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x END_IF; THIS.CallTimers(TRUE); + //StartMotorsTask.ThrowWhen(_errorTimer.output); Status.Action.Id := TO_UINT(_power_progress); END_IF; IF StartMotorsTask.DoneReached() THEN @@ -1048,6 +1071,7 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Messenger.ActivateOnCondition(ULINT#150,StartMovementsTask.IsBusy(), eAxoMessageCategory#Info); Messenger.ActivateOnCondition(ULINT#151,StartMovementsTask.IsDone(), eAxoMessageCategory#Info); IF StartMovementsTask.Execute(THIS) THEN + // _blink.Blink(Context := _context, inOnTime:=BLINKER_TIME,inOffTime:=BLINKER_TIME); IF _movement_progress = 0 THEN Status.Error.Id := UINT#0; TaskMessenger.Restore(); @@ -1063,6 +1087,8 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Outputs.MoveEnable := TRUE; Outputs.DrivesOff := TRUE; + Outputs.ErrorConfirmation := Inputs.StopMess AND NOT _blink.output; // try to ack error + IF Inputs.ProActive THEN THIS.CallTimers(FALSE); _movement_progress := 351; @@ -1231,7 +1257,9 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x THIS.CallTimers(NOT _movementExecuting); + //StartMovementsTask.ThrowWhen(_errorTimer.output); Status.Action.Id := TO_UINT(_movement_progress); + StartMovementsTask.ThrowWhen(StartMovementsTask.Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s ,'<#StartMovementsTask timeout.#>'); END_IF; IF StartMovementsTask.IsFirstExecutionCycle() THEN MovementParameters := Status.CurrentMovementParameters; @@ -1263,8 +1291,7 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Messenger.ActivateOnCondition(ULINT#170,StartAtMainTask.IsBusy(), eAxoMessageCategory#Info); Messenger.ActivateOnCondition(ULINT#171,StartAtMainTask.IsDone(), eAxoMessageCategory#Info); IF StartProgramTask.Execute(THIS) THEN - _blink.Blink(Context := _context, inOnTime:=T#500MS,inOffTime:=T#500MS); - + //_blink.Blink(Context := _context, inOnTime:=BLINKER_TIME,inOffTime:=BLINKER_TIME); IF _power_progress = 0 THEN Status.Error.Id := UINT#0; TaskMessenger.Restore(); @@ -1280,6 +1307,8 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Outputs.MoveEnable := TRUE; Outputs.DrivesOff := TRUE; Outputs.ActionNo := BYTE#255; + + Outputs.ErrorConfirmation := Inputs.StopMess AND NOT _blink.output; // try to ack error IF Inputs.UserSafetySwitchClosed THEN THIS.CallTimers(FALSE); @@ -1383,7 +1412,9 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x END_IF; THIS.CallTimers(TRUE); + //StartProgramTask.ThrowWhen(_errorTimer.output); Status.Action.Id := TO_UINT(_power_progress); + StartProgramTask.ThrowWhen(StartProgramTask.Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s ,'<#StartProgramTask timeout.#>'); END_IF; IF StartProgramTask.DoneReached() THEN Status.Action.Id := UINT#171; @@ -1412,7 +1443,7 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Messenger.ActivateOnCondition(ULINT#180,StartAtMainTask.IsBusy(), eAxoMessageCategory#Info); Messenger.ActivateOnCondition(ULINT#181,StartAtMainTask.IsDone(), eAxoMessageCategory#Info); IF StopMotorsTask.Execute(THIS) THEN - _blink.Blink(Context := _context, inOnTime:=T#500MS,inOffTime:=T#500MS); + //_blink.Blink(Context := _context, inOnTime:=BLINKER_TIME,inOffTime:=BLINKER_TIME); IF _power_progress = 0 THEN Status.Error.Id := UINT#0; @@ -1444,7 +1475,9 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x END_IF; THIS.CallTimers(TRUE); + //StopMotorsTask.ThrowWhen(_errorTimer.output); Status.Action.Id := TO_UINT(_power_progress); + StopMotorsTask.ThrowWhen(StopMotorsTask.Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s ,'<#StopMotorsTask timeout.#>'); END_IF; IF StopMotorsTask.DoneReached() THEN Status.Action.Id := UINT#181; @@ -1514,7 +1547,9 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x THIS.CallTimers(TRUE); + //StopMovementsAndProgramTask.ThrowWhen(_errorTimer.output); Status.Action.Id := TO_UINT(_power_progress); + StopMovementsAndProgramTask.ThrowWhen(StopMovementsAndProgramTask.Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s ,'<#StopMovementsAndProgramTask timeout.#>'); END_IF; IF StopMovementsAndProgramTask.DoneReached() THEN Status.Action.Id := UINT#191; @@ -1572,7 +1607,9 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x THIS.CallTimers(TRUE); + //StopMovementsTask.ThrowWhen(_errorTimer.output); Status.Action.Id := TO_UINT(_power_progress); + StopMovementsTask.ThrowWhen(StopMovementsTask.Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s ,'<#StopMovementsTask timeout.#>'); END_IF; IF StopMovementsTask.DoneReached() THEN Status.Action.Id := UINT#201; @@ -1629,7 +1666,9 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x THIS.CallTimers(TRUE); + //StopProgramTask.ThrowWhen(_errorTimer.output); Status.Action.Id := TO_UINT(_power_progress); + StopProgramTask.ThrowWhen(StopProgramTask.Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s ,'<#StopProgramTask timeout.#>'); END_IF; IF StopProgramTask.DoneReached() THEN Status.Action.Id := UINT#911; @@ -1720,7 +1759,9 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x THIS.CallTimers(TRUE); + //ResetAllOutputsTask.ThrowWhen(_errorTimer.output); Status.Action.Id := TO_UINT(_power_progress); + ResetAllOutputsTask.ThrowWhen(ResetAllOutputsTask.Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s ,'<#ResetAllOutputsTask timeout.#>'); END_IF; IF ResetAllOutputsTask.DoneReached() THEN Status.Action.Id := UINT#921; @@ -1754,7 +1795,7 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Messenger.Activate(UINT#20001,eAxoMessageCategory#Error); Status.Error.Id := UINT#20001; END_IF; - IF(NOT Inputs.Automatic) THEN + IF(NOT Inputs.ExternalAutomatic) THEN Messenger.Activate(UINT#20002,eAxoMessageCategory#Info); Status.Error.Id := UINT#20002; END_IF; @@ -1772,6 +1813,11 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x END_IF; END_IF; + IF(NOT Inputs.LocalEstopOk) THEN + Messenger.Activate(UINT#20006,eAxoMessageCategory#Error); + Status.Error.Id := UINT#20006; + END_IF; + //***********UPDATE**OUTPUTS***************** //SYSTEM OUTPUTS _data[0].%X0 := Outputs.ExternalStart; diff --git a/src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/TypesStructuresAndEnums/AxoKrc5_Config.st b/src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/TypesStructuresAndEnums/AxoKrc5_Config.st index bab3bfe4f..374275332 100644 --- a/src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/TypesStructuresAndEnums/AxoKrc5_Config.st +++ b/src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/TypesStructuresAndEnums/AxoKrc5_Config.st @@ -8,9 +8,9 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x {#ix-set:AttributeName = "<#Info time#>"} InfoTime : LTIME := LT#2S; {#ix-set:AttributeName = "<#Error time#>"} - ErrorTime : LTIME := LT#5S; + ErrorTime : LTIME := LT#0S; {#ix-set:AttributeName = "<#Task timeout#>"} - TaskTimeout : LTIME := LT#50S; + TaskTimeout : LTIME := LT#0S; {#ix-set:AttributeName = "<#Hardware IDs#>"} HWIDs : AxoKrc5_HWIDs; END_VAR diff --git a/src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/TypesStructuresAndEnums/AxoKrc5_State.st b/src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/TypesStructuresAndEnums/AxoKrc5_State.st index 1ccd655be..a9c3841a0 100644 --- a/src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/TypesStructuresAndEnums/AxoKrc5_State.st +++ b/src/components.kuka.robotics/ctrl/src/AxoKrc5/v_5_x_x/TypesStructuresAndEnums/AxoKrc5_State.st @@ -29,8 +29,8 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x InHome : BOOL; {#ix-set:AttributeName = "<#Manual [T1]#>"} Manual : BOOL; - {#ix-set:AttributeName = "<#Automatic [AUT]#>"} - Automatic : BOOL; + {#ix-set:AttributeName = "<#Local Emergency Stop OK#>"} + LocalEstopOk : BOOL; {#ix-set:AttributeName = "<#ExternalAutomatic [EXT]#>"} ExternalAutomatic : BOOL; {#ix-set:AttributeName = "<#ProcesActive [PRO_ACT]#>"} diff --git a/src/components.kuka.robotics/docs/AxoKrc5.md b/src/components.kuka.robotics/docs/AxoKrc5.md index 48fef6a89..ce788134e 100644 --- a/src/components.kuka.robotics/docs/AxoKrc5.md +++ b/src/components.kuka.robotics/docs/AxoKrc5.md @@ -26,22 +26,36 @@ Refer to the [`AxoKrc4`](AxoKrc4.md) page for: runtime safety errors 20001–20005, task-`potential` IDs in the 500-range). > [!NOTE] -> Since the KRC5 fix in **#1148**, `AxoKrc5` has diverged from `AxoKrc4` in -> three KRC5-only respects (none of these are present on `AxoKrc4`): +> Since the KRC5 fixes in **#1148** and **#1168**, `AxoKrc5` has diverged +> from `AxoKrc4` in the following KRC5-only respects (none of these are +> present on `AxoKrc4`): > > - It exposes the raw byte-array data-exchange members > `DataFromPlcToRobot` / `DataFromRobotToPlc` (see [Data exchange](#data-exchange)). > - It raises additional coordinate-mirror task-`potential` identifiers > **1501–1506** and **1511–1516** (see the > [TROUBLES error reference](TROUBLES.md#task-potential-waiting-on-input-identifiers)). -> - Safety message **20002** (`Inputs.Automatic = FALSE` while a task is busy) -> is raised as `Info` on `AxoKrc5`, where `AxoKrc4` still raises it as -> `Error`. -> - Its tasks no longer self-abort on the duration/error-timer watchdog -> (#1167). `AxoKrc5` no longer calls `ThrowWhen` on `Config.TaskTimeout` -> or `Config.ErrorTime` (`_errorTimer.output`); a stalled task now surfaces -> through the component's own status message instead of a redundant -> task-timeout error. `AxoKrc4` still applies both watchdogs. +> - Input bit `%X2` is **`Inputs.LocalEstopOk`** ("Local Emergency Stop OK", +> #1168) — on `AxoKrc4` the same bit is still `Inputs.Automatic`. Whenever +> `LocalEstopOk` is `FALSE`, `AxoKrc5` raises error **20006** +> unconditionally — every cycle, not only while a task is busy (unlike +> 20001–20005). +> - Safety message **20002** is keyed on `Inputs.ExternalAutomatic = FALSE` +> while a task is busy (#1168 — previously `Inputs.Automatic`, which no +> longer exists on KRC5) and is raised as `Info`, where `AxoKrc4` raises +> its `Inputs.Automatic`-keyed 20002 as `Error`. +> - The task-duration watchdog is **opt-in** (#1168): every task except +> `StartMotors` calls +> `ThrowWhen(Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s, '{TaskName} timeout.')`, +> and the default `Config.TaskTimeout = LT#0S` keeps it disabled. The +> `Config.ErrorTime` (`_errorTimer.output`) watchdog remains removed +> (#1167). `AxoKrc4` still applies both watchdogs with non-zero defaults. +> - While a busy task is waiting and the robot reports `Inputs.StopMess`, +> `AxoKrc5` automatically pulses `Outputs.ErrorConfirmation` (gated by the +> component blinker) to try to acknowledge the robot-side error (#1168). +> - The component blinker is ticked once per `Run()` cycle with a fixed +> `BLINKER_TIME = T#1S` on/off period (#1168 — previously each task ran +> its own 500 ms blink while executing). The differences between KRC4 and KRC5 are confined to: @@ -57,16 +71,21 @@ The differences between KRC4 and KRC5 are confined to: ## Configuration `AxoKrc5` is configured via the nested `Config : AxoKrc5_Config` member -(structurally identical to `AxoKrc4_Config`). The defaults (`InfoTime = -LT#2S`, `ErrorTime = LT#5S`, `TaskTimeout = LT#50S`) match KRC4 — see the +(structurally identical to `AxoKrc4_Config`). See the [`AxoKrc4` configuration table](AxoKrc4.md#configuration) for the meaning of -each field. +each field, but note the KRC5 defaults differ since #1168: `InfoTime = LT#2S` +matches KRC4, while `ErrorTime = LT#0S` and `TaskTimeout = LT#0S` (KRC4 +defaults to `LT#5S` / `LT#50S`). > [!NOTE] -> Since #1167, `ErrorTime` and `TaskTimeout` no longer abort `AxoKrc5` tasks -> (the `ThrowWhen` watchdogs were removed). They are still applied by `AxoKrc4`. -> On `AxoKrc5` a stalled task is reported through the component's status -> message rather than raising a task-timeout error. +> On `AxoKrc5` the task-duration watchdog is **opt-in** (#1168): with the +> default `TaskTimeout = LT#0S` it is disabled and a stalled task is reported +> through the component's status message only. Setting `TaskTimeout > T#0s` +> arms a per-task `ThrowWhen` that aborts the task with a +> `'{TaskName} timeout.'` error once `Duration` exceeds the configured value +> (every task except `StartMotors`). The `ErrorTime` watchdog remains removed +> on KRC5 (#1167) — the field only feeds the step timers — while `AxoKrc4` +> still applies both watchdogs. [!code-smalltalk[](../ctrl/src/AxoKrc5/v_5_x_x/TypesStructuresAndEnums/AxoKrc5_Config.st?name=AxoKrc5ConfigDeclaration)] diff --git a/src/components.kuka.robotics/docs/CHANGELOG.md b/src/components.kuka.robotics/docs/CHANGELOG.md index 327d40b32..4e68e7daf 100644 --- a/src/components.kuka.robotics/docs/CHANGELOG.md +++ b/src/components.kuka.robotics/docs/CHANGELOG.md @@ -23,6 +23,57 @@ on every run. --> +### 0.63.0 + +**New features:** +- `AxoKrc5` now monitors the local emergency-stop circuit: input bit `%X2` + is `Inputs.LocalEstopOk` ("Local Emergency Stop OK"), and whenever it is + `FALSE` the component raises error **20006** (`Error`) — unconditionally, + every cycle, not only while a task is busy (#1168). Matching messenger + text and `errorDescriptionDict` entries were added to the .NET twin + (`AxoKrc5.cs`). +- `AxoKrc5` task-duration watchdog reinstated as **opt-in** (#1168): every + task except `StartMotors` now calls + `ThrowWhen(Duration >= Config.TaskTimeout AND Config.TaskTimeout > T#0s, '{TaskName} timeout.')`. + With the new default `Config.TaskTimeout = LT#0S` the watchdog stays + disabled; the `Config.ErrorTime` (`_errorTimer`) watchdog remains removed + (#1167). +- `AxoKrc5` automatically pulses `Outputs.ErrorConfirmation` + (`Inputs.StopMess AND NOT _blink.output`) during the waiting phases of + `StartAtMain`, `StartMotorsAndProgram`, `StartMotorsProgramAndMovements`, + `StartMotors`, `StartMovements`, and `StartProgram`, acknowledging + robot-side stop messages without operator action (#1168). + +**Bug fixes:** +- `AxoKrc5` safety message **20002** is now keyed on + `Inputs.ExternalAutomatic = FALSE` (previously `Inputs.Automatic`, whose + bit `%X2` was repurposed to `LocalEstopOk`); still raised as `Info` + while a task is busy (#1168). + +**Other:** +- `AxoKrc5` blinker centralised: `_blink.Blink()` is ticked once per `Run()` + cycle with a new `BLINKER_TIME : TIME := T#1S` internal constant — the + per-task 500 ms blink calls were removed (#1168). +- `AxoKrc5_Config` defaults changed: `ErrorTime LT#5S → LT#0S`, + `TaskTimeout LT#50S → LT#0S` (watchdog disabled out of the box). +- `AxoKrc5View.razor` — header badge and inputs panel now bind to + `Inputs.LocalEstopOk` (EStop badge, `badge-danger` when not OK) instead + of `Inputs.Automatic`; polling updated in `AxoKrc5View.razor.cs`. +- `AxoKrc5.md` — divergence note rewritten for #1168 (LocalEstopOk / 20006, + 20002 rekey, opt-in watchdog, auto error-ack, 1 s blinker); Configuration + section records the new `LT#0S` defaults. +- `TROUBLES.md` — 20002 rows record the per-class keying input split; + new 20006 entry with the unconditional-gate note; task-timeout bullet + rewritten (KRC4 default-on vs KRC5 opt-in); auto error-ack documented. +- `AxoKrc4` is unchanged in this release. + +**Breaking changes:** +- `AxoKrc5` public input `Inputs.Automatic` was renamed to + `Inputs.LocalEstopOk` with new semantics (E-stop OK instead of AUT mode, + #1168). .NET twin consumers and Blazor bindings referencing + `Inputs.Automatic` on `AxoKrc5` must migrate; `AxoKrc4.Inputs.Automatic` + is unaffected. + ### 0.61.1 **Bug fixes:** diff --git a/src/components.kuka.robotics/docs/TROUBLES.md b/src/components.kuka.robotics/docs/TROUBLES.md index b516f38dd..4cebd7e17 100644 --- a/src/components.kuka.robotics/docs/TROUBLES.md +++ b/src/components.kuka.robotics/docs/TROUBLES.md @@ -9,13 +9,19 @@ otherwise it applies to both. Error identifiers are published through ID seen in a log or on the HMI always maps to one of the entries below. > [!NOTE] -> Since the KRC5 fix in **#1148**, a few identifiers differ between the two -> classes (the rest are identical): +> Since the KRC5 fixes in **#1148** and **#1168**, a few identifiers differ +> between the two classes (the rest are identical): > > - **1501–1506** and **1511–1516** (coordinate-mirror task-`potential` IDs) > are raised by `AxoKrc5` only. -> - **20002** (`Inputs.Automatic = FALSE` while a task is busy) is raised as -> category `Info` on `AxoKrc5`, but as `Error` on `AxoKrc4`. +> - **20002** (raised while a task is busy) is keyed on +> `Inputs.Automatic = FALSE` and category `Error` on `AxoKrc4`, but on +> `Inputs.ExternalAutomatic = FALSE` and category `Info` on `AxoKrc5` +> (`Inputs.Automatic` no longer exists on KRC5 — bit `%X2` is +> `Inputs.LocalEstopOk` since #1168). +> - **20006** (`Inputs.LocalEstopOk = FALSE`, category `Error`) is raised by +> `AxoKrc5` only — and unconditionally, every cycle, not only while a task +> is busy. ## Common issues @@ -65,12 +71,18 @@ They are not errors. these; if they never assert, inspect the E-stop chain on the robot cell. - `Inputs.Error = TRUE` raises error 20005 while a task is busy; clear the KRC4-side fault, then call `ExampleRobot.ErrorConfirmation` via - `Outputs.ErrorConfirmation` or run the `Restore` sequencer step. -- **(KRC4 only)** `Config.TaskTimeout` has not elapsed (default `LT#50S`). - Set to `0s` during commissioning to disable the watchdog. Since #1167 - `AxoKrc5` no longer aborts tasks on `TaskTimeout` / `ErrorTime`; a stalled - KRC5 task is reported through the component status message instead, so - there is no task-timeout watchdog to disable on KRC5. + `Outputs.ErrorConfirmation` or run the `Restore` sequencer step. On + `AxoKrc5` (since #1168) the component already pulses + `Outputs.ErrorConfirmation` automatically while `Inputs.StopMess` is + active during a task's waiting phase, so a robot-side stop message is + acknowledged without operator action where possible. +- `Config.TaskTimeout` has not elapsed. On `AxoKrc4` the watchdog is armed + by default (`LT#50S`) — set to `0s` during commissioning to disable it. + On `AxoKrc5` the watchdog is **opt-in** since #1168: the default is + `LT#0S` (disabled), and only a value `> T#0s` arms the per-task + `ThrowWhen` that aborts with `'{TaskName} timeout.'` (every task except + `StartMotors`). The `Config.ErrorTime` watchdog applies to `AxoKrc4` + only (#1167). ### Movement parameters never take effect @@ -130,11 +142,16 @@ corresponding input asserts/deasserts: | Id | Condition | Meaning | |----|-----------|---------| | 20001 | `Inputs.Manual = TRUE` | KRC4 went to T1 while a task is executing — automation path invalid. | -| 20002 | `Inputs.Automatic = FALSE` | Controller dropped out of auto. Raised as `Error` on `AxoKrc4`; raised as `Info` on `AxoKrc5` (#1148), since losing auto mode mid-task is treated as an informational condition there. | +| 20002 | `Inputs.Automatic = FALSE` (KRC4) / `Inputs.ExternalAutomatic = FALSE` (KRC5, #1168) | Controller dropped out of auto. Raised as `Error` on `AxoKrc4`; raised as `Info` on `AxoKrc5` (#1148), since losing auto mode mid-task is treated as an informational condition there. | | 20003 | `Inputs.AlarmStopActive = FALSE` | Alarm-stop dropped, likely external E-stop. | | 20004 | `Inputs.UserSafetySwitchClosed = FALSE` | User safety gate opened during motion. | | 20005 | `Inputs.Error = TRUE` | KRC4 itself raised an error while the task was running. | +On `AxoKrc5` only, error **20006** (`Inputs.LocalEstopOk = FALSE`, category +`Error`) sits outside this task-busy gate — it is raised every cycle the +local E-stop circuit reports not-OK, whether or not a task is executing +(#1168). Restore the local E-stop chain on the robot cell to clear it. + Resolution: bring the cell back into the safe automatic state, call the task's `Restore()` method so its state machine rewinds, then re-invoke the task. @@ -173,10 +190,11 @@ task. | Id | Category | Raised when | |----|----------|-------------| | 20001 | Error | `Inputs.Manual = TRUE`. | -| 20002 | Error (`AxoKrc4`) / Info (`AxoKrc5`) | `Inputs.Automatic = FALSE`. Severity differs per class — see the note at the top of this page. | +| 20002 | Error (`AxoKrc4`) / Info (`AxoKrc5`) | `Inputs.Automatic = FALSE` on `AxoKrc4`; `Inputs.ExternalAutomatic = FALSE` on `AxoKrc5` (#1168). Severity and keying input differ per class — see the note at the top of this page. | | 20003 | Error | `Inputs.AlarmStopActive = FALSE`. | | 20004 | Error | `Inputs.UserSafetySwitchClosed = FALSE`. | | 20005 | Error | `Inputs.Error = TRUE`. | +| 20006 *(KRC5 only)* | Error | `Inputs.LocalEstopOk = FALSE`. Raised unconditionally every cycle — not gated on a busy task (#1168). | ### Task "potential" (waiting-on-input) identifiers diff --git a/src/components.kuka.robotics/src/AXOpen.Components.Kuka.Robotics.blazor/AxoKrc5/v_5_x_x/AxoKrc5View.razor b/src/components.kuka.robotics/src/AXOpen.Components.Kuka.Robotics.blazor/AxoKrc5/v_5_x_x/AxoKrc5View.razor index 1492a0ddf..a441db47f 100644 --- a/src/components.kuka.robotics/src/AXOpen.Components.Kuka.Robotics.blazor/AxoKrc5/v_5_x_x/AxoKrc5View.razor +++ b/src/components.kuka.robotics/src/AXOpen.Components.Kuka.Robotics.blazor/AxoKrc5/v_5_x_x/AxoKrc5View.razor @@ -6,9 +6,9 @@
- @if (Component.Inputs.Automatic.Cyclic) + @if (Component.Inputs.LocalEstopOk.Cyclic) { - @Localizer["Automatic"] + @Localizer["EStop"] } else if (Component.Inputs.ExternalAutomatic.Cyclic) { @@ -236,8 +236,8 @@ @Localizer["Manual"]
- - @Localizer["Automatic"] + + @Localizer["LocalEstopOk"]
diff --git a/src/components.kuka.robotics/src/AXOpen.Components.Kuka.Robotics.blazor/AxoKrc5/v_5_x_x/AxoKrc5View.razor.cs b/src/components.kuka.robotics/src/AXOpen.Components.Kuka.Robotics.blazor/AxoKrc5/v_5_x_x/AxoKrc5View.razor.cs index f66e08a43..9461f81d1 100644 --- a/src/components.kuka.robotics/src/AXOpen.Components.Kuka.Robotics.blazor/AxoKrc5/v_5_x_x/AxoKrc5View.razor.cs +++ b/src/components.kuka.robotics/src/AXOpen.Components.Kuka.Robotics.blazor/AxoKrc5/v_5_x_x/AxoKrc5View.razor.cs @@ -19,7 +19,7 @@ public override void ConfigurePolling() this.StartPolling(Component.Inputs.InHome); this.StartPolling(Component.Inputs.Manual); - this.StartPolling(Component.Inputs.Automatic); + this.StartPolling(Component.Inputs.LocalEstopOk); this.StartPolling(Component.Inputs.ExternalAutomatic); this.StartPolling(Component.Inputs.ProActive); this.StartPolling(Component.Inputs.ProgramMoveActive); diff --git a/src/components.kuka.robotics/src/AXOpen.Components.Kuka.Robotics/AxoKrc5/v_5_x_x/AxoKrc5.cs b/src/components.kuka.robotics/src/AXOpen.Components.Kuka.Robotics/AxoKrc5/v_5_x_x/AxoKrc5.cs index 17a32b5d3..ddd968f4c 100644 --- a/src/components.kuka.robotics/src/AXOpen.Components.Kuka.Robotics/AxoKrc5/v_5_x_x/AxoKrc5.cs +++ b/src/components.kuka.robotics/src/AXOpen.Components.Kuka.Robotics/AxoKrc5/v_5_x_x/AxoKrc5.cs @@ -133,6 +133,7 @@ private void InitializeMessenger() new KeyValuePair(20003, new AxoMessengerTextItem("Waiting for signal 'Inputs.AlarmStopActive' to be set!","Check the signal.")), new KeyValuePair(20004, new AxoMessengerTextItem("Waiting for signal 'Inputs.UserSafetySwitchClosed' to be set!","Check the signal.")), new KeyValuePair(20005, new AxoMessengerTextItem("Waiting for signal 'Inputs.Error' to be reseted!","Check the signal.")), + new KeyValuePair(20006, new AxoMessengerTextItem("Waiting for signal 'Inputs.LocalEstopOk' to be set!","Check the signal.")), @@ -378,6 +379,7 @@ public string ErrorDescription errorDescriptionDict.Add(20003, "Waiting for signal 'Inputs.AlarmStopActive' to be set!"); errorDescriptionDict.Add(20004, "Waiting for signal 'Inputs.UserSafetySwitchClosed' to be set!"); errorDescriptionDict.Add(20005, "Waiting for signal 'Inputs.Error' to be reseted!"); + errorDescriptionDict.Add(20006, "Waiting for signal 'Inputs.LocalEstopOk' to be set!"); } string errorDescription = " "; diff --git a/src/components.pneumatics/src/AXOpen.Components.Pneumatics.blazor/AxoCylinder/AxoCylinderView.razor b/src/components.pneumatics/src/AXOpen.Components.Pneumatics.blazor/AxoCylinder/AxoCylinderView.razor index 3059655a6..3e3512906 100644 --- a/src/components.pneumatics/src/AXOpen.Components.Pneumatics.blazor/AxoCylinder/AxoCylinderView.razor +++ b/src/components.pneumatics/src/AXOpen.Components.Pneumatics.blazor/AxoCylinder/AxoCylinderView.razor @@ -1,4 +1,4 @@ -@namespace AXOpen.Components.Pneumatics +@namespace AXOpen.Components.Pneumatics @using AXOpen.Core.Blazor @inherits AxoComponentViewBase @@ -11,7 +11,7 @@ } else if (IsInOuterPosition) { - @Component.OutLabel + @Component.OutLabel } else if (IsMoving) { @@ -87,7 +87,7 @@
-
+
@Component.OutLabel
diff --git a/src/core/ctrl/src/AxoTask/AxoTaskLight.st b/src/core/ctrl/src/AxoTask/AxoTaskLight.st index 0cc75ce90..93cd9621f 100644 --- a/src/core/ctrl/src/AxoTask/AxoTaskLight.st +++ b/src/core/ctrl/src/AxoTask/AxoTaskLight.st @@ -361,6 +361,7 @@ NAMESPACE AXOpen.Core IF IsDisabled && (_stateKicking || Status = eAxoTaskState#Busy) THEN THIS.Abort(); + ErrorDetails := 'Aborted - disabled during kicking and busy'; END_IF; diff --git a/src/core/src/AXOpen.Core.Blazor/AxoMessenger/Static/AxoIncidentBarView.razor b/src/core/src/AXOpen.Core.Blazor/AxoMessenger/Static/AxoIncidentBarView.razor index acdf0b7b7..06ef42076 100644 --- a/src/core/src/AXOpen.Core.Blazor/AxoMessenger/Static/AxoIncidentBarView.razor +++ b/src/core/src/AXOpen.Core.Blazor/AxoMessenger/Static/AxoIncidentBarView.razor @@ -18,7 +18,7 @@