diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fee4f26d..17120b311 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +### [KUKA] KRC5 raw data exchange, coordinate-mirror diagnostics, and auto-mode severity fix ([#1151](https://github.com/Inxton/AXOpen/pull/1151)) + +**Note:** KRC5-only change in `src/components.kuka.robotics/`. `AxoKrc5` now diverges from `AxoKrc4` in three respects — `AxoKrc4` is intentionally left unchanged in this PR. Fixes #1148. + +- feat: `AxoKrc5` exposes raw application-defined passthrough members `DataFromPlcToRobot : ARRAY[0..19] OF BYTE` (PLC → robot, output bytes `_data[44..63]`) and `DataFromRobotToPlc : ARRAY[0..15] OF BYTE` (robot → PLC, input bytes `_data[48..63]`). Both carry `RenderIgnore`; `Run()` transports them verbatim without interpretation. Wrapped in the new `` source region. +- feat: `AxoKrc5` adds per-axis coordinate-mirror task-`potential` identifiers `1501–1506` (`StartMotorsProgramAndMovements`) and `1511–1516` (`StartMovements`), raised via `TaskMessenger` while waiting for each `Inputs.Coordinates.{X,Y,Z,Rx,Ry,Rz}` to mirror the commanded value within `0.01` tolerance. Matching `.NET` twin entries added to both the `TaskMessenger` text list and `errorDescriptionDict` in `AxoKrc5.cs`. +- fix: `AxoKrc5` safety message `20002` (`Inputs.Automatic = FALSE` while a task is busy) is now raised as category `Info` instead of `Error` — losing auto mode mid-task is informational on KRC5, not a hard fault. +- feat: Showcase `AxoKrc5_v_5_x_x_Showcase.st` gained an "Exchange raw data with the robot" sequencer step (in `//` markers); `Steps` widened `[0..19]` → `[0..20]`, `_lastByteFromRobot` status field added. +- docs: `AxoKrc5.md` relaxed the "identical public API to `AxoKrc4`" wording, added a **Data exchange** section (library declaration + showcase usage refs), and a note listing the three KRC5-only differences. `TROUBLES.md` flags the per-class differences (1501–1516, 20002 severity split). Appended `0.54.0` entry to `src/components.kuka.robotics/docs/CHANGELOG.md`. + +**Impact:** +- Applications driving a KRC5 can now push and pull arbitrary byte payloads alongside the structured motion interface, without a library change. +- Operators see which specific axis is holding up a movement (per-coordinate `potential` IDs) rather than a single "coordinates not mirrored" wait. +- Dropping out of automatic mode mid-task no longer latches a KRC5 error state. + +**Risks/Review:** +- `AxoKrc4` and `AxoKrc5` are no longer API/behaviour-identical. Documentation now states the divergence explicitly; if a follow-up backports these changes to `AxoKrc4`, the "KRC5-only" wording in `AxoKrc5.md` / `TROUBLES.md` must be reverted. +- The PLC→robot (`44..63`) and robot→PLC (`48..63`) windows overlap on the same physical I/O block in opposite directions — verify the controller-side mapping matches before relying on the passthrough. + +**Testing:** +- `apax ib` in `src/showcase/app/` — the new KRC5 data-exchange sequencer step builds and runs through to `CompleteSequence`. +- `dotnet build` on `src/showcase/app/ix-blazor/showcase.blazor/` — the `AxoKrc5.cs` messenger/error-dictionary additions compile. +- `scripts/_build_documentation.ps1` — the new `[!code-pascal[]]` (showcase `DataExchange`) and `[!code-smalltalk[]]` (`AxoKrc5DataExchangeDeclaration`) directives resolve. + ### [CORE] AxoToggleTaskView aligned with AxoTaskView ([#1143](https://github.com/Inxton/AXOpen/pull/1143)) **Note:** Blazor UI-only change in `src/core/src/AXOpen.Core.Blazor/AxoToggleTask/`. The PLC `AxoToggleTask` class and its public API (`SwitchOn()`, `SwitchOff()`, `Toggle()`, `IsSwitchOn()`, `IsSwitchOff()`, event-like overrides) are unchanged. Bundled with the AxoCmmtAs view expansion under the same PR; the toggle-view refactor is the core-library portion. 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 84b845fe2..7bd774d01 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 @@ -138,6 +138,15 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x HardwareDiagnosticsTask : AXOpen.Io.AxoHardwareDiagnostics; END_VAR + // + VAR PUBLIC //Data + {#ix-attr:[RenderIgnore()]} + DataFromPlcToRobot : ARRAY[0..19] OF BYTE; + {#ix-attr:[RenderIgnore()]} + DataFromRobotToPlc : ARRAY[0..15] OF BYTE; + END_VAR + // + /// /// Runs tasks and logic of this component. /// >[!IMPORTANT] This method must or one of its overloads be called cyclically. @@ -388,6 +397,23 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x _dword.%B2 := _data[46]; _dword.%B3 := _data[47]; Inputs.EventId := TO_UDINT(_dword); + + DataFromRobotToPlc[0] := _data[48]; + DataFromRobotToPlc[1] := _data[49]; + DataFromRobotToPlc[2] := _data[50]; + DataFromRobotToPlc[3] := _data[51]; + DataFromRobotToPlc[4] := _data[52]; + DataFromRobotToPlc[5] := _data[53]; + DataFromRobotToPlc[6] := _data[54]; + DataFromRobotToPlc[7] := _data[55]; + DataFromRobotToPlc[8] := _data[56]; + DataFromRobotToPlc[9] := _data[57]; + DataFromRobotToPlc[10] := _data[58]; + DataFromRobotToPlc[11] := _data[59]; + DataFromRobotToPlc[12] := _data[60]; + DataFromRobotToPlc[13] := _data[61]; + DataFromRobotToPlc[14] := _data[62]; + DataFromRobotToPlc[15] := _data[63]; //******************************************* _context := THIS.GetContext(); @@ -819,6 +845,30 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x TaskMessenger.Activate( UINT#533, eAxoMessageCategory#Potential); Status.Error.Id := UINT#533;//<#Waiting for Inputs.UserSpecSpeed2 to be equal to MovementParameters.UserSpecSpeed2! END_IF; + IF NOT AXOpen.Components.Robotics.IsNearlyEqual(Inputs.Coordinates.X,Status.CurrentMovementParameters.Coordinates.X,REAL#0.01) THEN + TaskMessenger.Activate( UINT#1501, eAxoMessageCategory#Potential); + Status.Error.Id := UINT#1501;//<#Waiting for Inputs.Coordinates.X to be equal to MovementParameters.Coordinates.X! + END_IF; + IF NOT AXOpen.Components.Robotics.IsNearlyEqual(Inputs.Coordinates.Y,Status.CurrentMovementParameters.Coordinates.Y,REAL#0.01) THEN + TaskMessenger.Activate( UINT#1502, eAxoMessageCategory#Potential); + Status.Error.Id := UINT#1502;//<#Waiting for Inputs.Coordinates.Y to be equal to MovementParameters.Coordinates.Y! + END_IF; + IF NOT AXOpen.Components.Robotics.IsNearlyEqual(Inputs.Coordinates.Z,Status.CurrentMovementParameters.Coordinates.Z,REAL#0.01) THEN + TaskMessenger.Activate( UINT#1503, eAxoMessageCategory#Potential); + Status.Error.Id := UINT#1503;//<#Waiting for Inputs.Coordinates.Z to be equal to MovementParameters.Coordinates.Z! + END_IF; + IF NOT AXOpen.Components.Robotics.IsNearlyEqual(Inputs.Coordinates.Rx,Status.CurrentMovementParameters.Coordinates.Rx,REAL#0.01) THEN + TaskMessenger.Activate( UINT#1504, eAxoMessageCategory#Potential); + Status.Error.Id := UINT#1504;//<#Waiting for Inputs.Coordinates.Rx to be equal to MovementParameters.Coordinates.Rx! + END_IF; + IF NOT AXOpen.Components.Robotics.IsNearlyEqual(Inputs.Coordinates.Ry,Status.CurrentMovementParameters.Coordinates.Ry,REAL#0.01) THEN + TaskMessenger.Activate( UINT#1505, eAxoMessageCategory#Potential); + Status.Error.Id := UINT#1505;//<#Waiting for Inputs.Coordinates.Ry to be equal to MovementParameters.Coordinates.Ry! + END_IF; + IF NOT AXOpen.Components.Robotics.IsNearlyEqual(Inputs.Coordinates.Rz,Status.CurrentMovementParameters.Coordinates.Rz,REAL#0.01) THEN + TaskMessenger.Activate( UINT#1506, eAxoMessageCategory#Potential); + Status.Error.Id := UINT#1506;//<#Waiting for Inputs.Coordinates.Rz to be equal to MovementParameters.Coordinates.Rz! + END_IF; END_IF; IF Inputs.GlobalSpeed = Status.CurrentMovementParameters.GlobalSpeed AND @@ -1098,6 +1148,30 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x TaskMessenger.Activate( UINT#559, eAxoMessageCategory#Potential); Status.Error.Id := UINT#559;//<#Waiting for Inputs.UserSpecSpeed2 to be equal to MovementParameters.UserSpecSpeed2! END_IF; + IF NOT AXOpen.Components.Robotics.IsNearlyEqual(Inputs.Coordinates.X,Status.CurrentMovementParameters.Coordinates.X,REAL#0.01) THEN + TaskMessenger.Activate( UINT#1511, eAxoMessageCategory#Potential); + Status.Error.Id := UINT#1511;//<#Waiting for Inputs.Coordinates.X to be equal to MovementParameters.Coordinates.X! + END_IF; + IF NOT AXOpen.Components.Robotics.IsNearlyEqual(Inputs.Coordinates.Y,Status.CurrentMovementParameters.Coordinates.Y,REAL#0.01) THEN + TaskMessenger.Activate( UINT#1512, eAxoMessageCategory#Potential); + Status.Error.Id := UINT#1512;//<#Waiting for Inputs.Coordinates.Y to be equal to MovementParameters.Coordinates.Y! + END_IF; + IF NOT AXOpen.Components.Robotics.IsNearlyEqual(Inputs.Coordinates.Z,Status.CurrentMovementParameters.Coordinates.Z,REAL#0.01) THEN + TaskMessenger.Activate( UINT#1513, eAxoMessageCategory#Potential); + Status.Error.Id := UINT#1513;//<#Waiting for Inputs.Coordinates.Z to be equal to MovementParameters.Coordinates.Z! + END_IF; + IF NOT AXOpen.Components.Robotics.IsNearlyEqual(Inputs.Coordinates.Rx,Status.CurrentMovementParameters.Coordinates.Rx,REAL#0.01) THEN + TaskMessenger.Activate( UINT#1514, eAxoMessageCategory#Potential); + Status.Error.Id := UINT#1514;//<#Waiting for Inputs.Coordinates.Rx to be equal to MovementParameters.Coordinates.Rx! + END_IF; + IF NOT AXOpen.Components.Robotics.IsNearlyEqual(Inputs.Coordinates.Ry,Status.CurrentMovementParameters.Coordinates.Ry,REAL#0.01) THEN + TaskMessenger.Activate( UINT#1515, eAxoMessageCategory#Potential); + Status.Error.Id := UINT#1515;//<#Waiting for Inputs.Coordinates.Ry to be equal to MovementParameters.Coordinates.Ry! + END_IF; + IF NOT AXOpen.Components.Robotics.IsNearlyEqual(Inputs.Coordinates.Rz,Status.CurrentMovementParameters.Coordinates.Rz,REAL#0.01) THEN + TaskMessenger.Activate( UINT#1516, eAxoMessageCategory#Potential); + Status.Error.Id := UINT#1516;//<#Waiting for Inputs.Coordinates.Rz to be equal to MovementParameters.Coordinates.Rz! + END_IF; END_IF; IF Inputs.GlobalSpeed = Status.CurrentMovementParameters.GlobalSpeed AND @@ -1702,7 +1776,7 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x Status.Error.Id := UINT#20001; END_IF; IF(NOT Inputs.Automatic) THEN - Messenger.Activate(UINT#20002,eAxoMessageCategory#Error); + Messenger.Activate(UINT#20002,eAxoMessageCategory#Info); Status.Error.Id := UINT#20002; END_IF; IF(NOT Inputs.AlarmStopActive) THEN @@ -1814,6 +1888,27 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x _data[42] := _dword.%B2; _data[43] := _dword.%B3; + _data[44] := DataFromPlcToRobot[0]; + _data[45] := DataFromPlcToRobot[1]; + _data[46] := DataFromPlcToRobot[2]; + _data[47] := DataFromPlcToRobot[3]; + _data[48] := DataFromPlcToRobot[4]; + _data[49] := DataFromPlcToRobot[5]; + _data[50] := DataFromPlcToRobot[6]; + _data[51] := DataFromPlcToRobot[7]; + _data[52] := DataFromPlcToRobot[8]; + _data[53] := DataFromPlcToRobot[9]; + _data[54] := DataFromPlcToRobot[10]; + _data[55] := DataFromPlcToRobot[11]; + _data[56] := DataFromPlcToRobot[12]; + _data[57] := DataFromPlcToRobot[13]; + _data[58] := DataFromPlcToRobot[14]; + _data[59] := DataFromPlcToRobot[15]; + _data[60] := DataFromPlcToRobot[16]; + _data[61] := DataFromPlcToRobot[17]; + _data[62] := DataFromPlcToRobot[18]; + _data[63] := DataFromPlcToRobot[19]; + _retVal := Siemens.Simatic.DistributedIO.WriteData((Config.HWIDs.HwID_512_DI_DO),_data); IF _retVal > WORD#0 THEN Messenger.Activate(UINT#1231, eAxoMessageCategory#Error); diff --git a/src/components.kuka.robotics/docs/AxoKrc5.md b/src/components.kuka.robotics/docs/AxoKrc5.md index 320551792..24419fcad 100644 --- a/src/components.kuka.robotics/docs/AxoKrc5.md +++ b/src/components.kuka.robotics/docs/AxoKrc5.md @@ -11,19 +11,32 @@ inside the component's `Run()` call. ## Relationship to `AxoKrc4` -`AxoKrc5` exposes the **same public API** as [`AxoKrc4`](AxoKrc4.md) — the -tasks, configuration members, status type, error catalogue, and `Run(inParent, -hwID)` signature are identical, and so is the AXOpen slot layout (slot 1 -reserved/empty, slot 2 = `DIO512` with 64-byte cyclic I/O). Refer to the -[`AxoKrc4`](AxoKrc4.md) page for: +`AxoKrc5` shares **almost all** of its public API with +[`AxoKrc4`](AxoKrc4.md) — the tasks, configuration members, status type, +`Run(inParent, hwID)` signature, and the AXOpen slot layout (slot 1 +reserved/empty, slot 2 = `DIO512` with 64-byte cyclic I/O) are the same. +Refer to the [`AxoKrc4`](AxoKrc4.md) page for: - The full capabilities list, configuration parameter table, and Config / HWIDs declarations. - The .NET twin and Blazor wiring patterns (the patterns transfer 1:1 — only the type name changes). -- The error-state semantics (programming errors 700/701, hardware bring-up - errors 702/710/720–726/1130–1133, transport errors 1201/1231, runtime - safety errors 20001–20005, task-`potential` IDs in the 500-range). +- The shared error-state semantics (programming errors 700/701, hardware + bring-up errors 702/710/720–726/1130–1133, transport errors 1201/1231, + 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`): +> +> - 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`. The differences between KRC4 and KRC5 are confined to: @@ -48,6 +61,33 @@ each field. [!code-smalltalk[](../ctrl/src/AxoKrc5/v_5_x_x/TypesStructuresAndEnums/AxoKrc5_HWIDs.st?name=AxoKrc5HWIDsDeclaration)] +## Data exchange + +`AxoKrc5` reserves part of the 64-byte cyclic I/O block for raw, +application-defined payloads that pass through the component untouched +(both members carry `RenderIgnore`, so they are excluded from the proxy +view). This is a KRC5-only addition — `AxoKrc4` does not expose these +members. + +| Member | Direction | Mapped onto | +|--------|-----------|-------------| +| `DataFromPlcToRobot : ARRAY[0..19] OF BYTE` | PLC → robot | Output bytes `_data[44..63]`, written each cycle in the output-pack phase of `Run()`. | +| `DataFromRobotToPlc : ARRAY[0..15] OF BYTE` | robot → PLC | Input bytes `_data[48..63]`, copied each cycle after the input-unpack phase of `Run()`. | + +Write to `DataFromPlcToRobot` and read from `DataFromRobotToPlc` from +application code; the component transports the bytes verbatim and does not +interpret them. The two ranges overlap on the wire because the PLC→robot +window (`44..63`) is wider than the robot→PLC window (`48..63`) — they occupy +the same physical I/O block in opposite directions. + +[!code-smalltalk[](../ctrl/src/AxoKrc5/v_5_x_x/AxoKrc5.st?name=AxoKrc5DataExchangeDeclaration)] + +The showcase demonstrates the round-trip — writing an application payload to +`DataFromPlcToRobot` and reading the robot's published bytes from +`DataFromRobotToPlc`: + +[!code-pascal[](../../showcase/app/src/components.kuka.robotics/Documentation/AxoKrc5_v_5_x_x_Showcase.st?name=DataExchange)] + # [CONTROLLER](#tab/controller) ## Declare component diff --git a/src/components.kuka.robotics/docs/CHANGELOG.md b/src/components.kuka.robotics/docs/CHANGELOG.md index 2a8ceb51c..24c4edb69 100644 --- a/src/components.kuka.robotics/docs/CHANGELOG.md +++ b/src/components.kuka.robotics/docs/CHANGELOG.md @@ -126,3 +126,47 @@ control remains available through the existing `axoKrcN_v_5_x_x.ActivateManualControl` toggle on the sequenced showcases — no library-side API was removed. + +### 0.54.0 + +**New features:** +- `AxoKrc5` now exposes raw application-defined data-exchange members + `DataFromPlcToRobot : ARRAY[0..19] OF BYTE` (PLC → robot, mapped onto + output bytes `_data[44..63]`) and `DataFromRobotToPlc : ARRAY[0..15] OF BYTE` + (robot → PLC, mapped onto input bytes `_data[48..63]`). Both carry + `RenderIgnore` and are transported verbatim by `Run()` without + interpretation (#1148). + +**Bug fixes:** +- `AxoKrc5` safety message **20002** (`Inputs.Automatic = FALSE` while a task + is busy) is now raised as category `Info` instead of `Error`; losing auto + mode mid-task is an informational condition rather than a hard fault on + KRC5 (#1148). + +**Other:** +- `AxoKrc5` adds per-axis coordinate-mirror task-`potential` identifiers + **1501–1506** (`StartMotorsProgramAndMovements`) and **1511–1516** + (`StartMovements`), reported via `TaskMessenger` while waiting for each + `Inputs.Coordinates.{X,Y,Z,Rx,Ry,Rz}` to mirror the commanded value within + `0.01` tolerance. Matching `.NET` twin entries were added to both the + `TaskMessenger` text list and `errorDescriptionDict` in `AxoKrc5.cs`. +- `AxoKrc5.md` — relaxed the "identical public API to `AxoKrc4`" wording to + reflect the #1148 divergence; added a **Data exchange** section documenting + the new byte-array members (wired to the new + `` source region) and a note listing the + three KRC5-only differences. +- `TROUBLES.md` — header note now flags the per-class differences; the 20002 + rows record the `Error` (KRC4) vs `Info` (KRC5) split; the task-`potential` + reference and the "Movement parameters never take effect" section document + the new 1501–1516 coordinate-mirror IDs. +- Showcase: `AxoKrc5_v_5_x_x_Showcase.st` gained an "Exchange raw data with + the robot" sequencer step (inside new `//` markers) that + writes a sample payload to `DataFromPlcToRobot` and reads `DataFromRobotToPlc`; + the `Steps` array was widened `[0..19]` → `[0..20]` and a + `_lastByteFromRobot` status field added. `AxoKrc5.md`'s **Data exchange** + section references this snippet via `[!code-pascal[]]`. The `AxoKrc4` + showcase is unchanged. + +**New regions:** +- `AxoKrc5.st` — `` around the public + `DataFromPlcToRobot` / `DataFromRobotToPlc` block. diff --git a/src/components.kuka.robotics/docs/TROUBLES.md b/src/components.kuka.robotics/docs/TROUBLES.md index 8650d274f..ce312a6f7 100644 --- a/src/components.kuka.robotics/docs/TROUBLES.md +++ b/src/components.kuka.robotics/docs/TROUBLES.md @@ -2,11 +2,20 @@ This page catalogues the error states surfaced by `AxoKrc4` and `AxoKrc5` (both in `AXOpen.Components.Kuka.Robotics.v_5_x_x`), each tied back to its -raising site in the PLC source. The two classes share an identical error -catalogue and bring-up logic, so every entry below applies to both. Error -identifiers are published through `Status.Error.Id` and the component's -`Messenger` / `TaskMessenger`, so the ID seen in a log or on the HMI always -maps to one of the entries below. +raising site in the PLC source. The two classes share the same bring-up +logic and the bulk of the error catalogue, so unless an entry is flagged +otherwise it applies to both. Error identifiers are published through +`Status.Error.Id` and the component's `Messenger` / `TaskMessenger`, so the +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): +> +> - **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`. ## Common issues @@ -80,7 +89,11 @@ If the mirror never happens the task is stuck at `_movement_progress = 354`. the KRC4 programme is not advancing. - `AXOpen.Components.Robotics.CoordinatesAreNearlyEqual` returns `TRUE` for the commanded vs. echoed coordinates within `0.01` tolerance. Values - outside that tolerance keep the task in the acknowledge state. + outside that tolerance keep the task in the acknowledge state. On + `AxoKrc5`, the specific axis that has not yet mirrored is reported through + the per-coordinate *potential* IDs **1501–1506** (combined + motors/program/movements task) or **1511–1516** (movements task) — + `X/Y/Z/Rx/Ry/Rz` in that order. These are KRC5-only. ### PROFINET read / write transport failures @@ -114,7 +127,7 @@ 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` | KRC4 dropped out of auto — task is now illegal. | +| 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. | | 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. | @@ -157,7 +170,7 @@ task. | Id | Category | Raised when | |----|----------|-------------| | 20001 | Error | `Inputs.Manual = TRUE`. | -| 20002 | Error | `Inputs.Automatic = FALSE`. | +| 20002 | Error (`AxoKrc4`) / Info (`AxoKrc5`) | `Inputs.Automatic = FALSE`. Severity differs 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`. | @@ -181,6 +194,8 @@ ranges: | 580 | `StartProgram` | Programme start acknowledgement. | | 590, 591 | `StopProgram`, `StopMovementsAndProgram` | Programme stop acknowledgement. | | 600, 610, 620 | `StopMovements`, `StopMotors`, `ResetAllOutputs` | Final shutdown handshakes. | +| 1501–1506 *(KRC5 only)* | `StartMotorsProgramAndMovements` | Per-axis coordinate mirror — waiting for `Inputs.Coordinates.{X,Y,Z,Rx,Ry,Rz}` to match the commanded value within tolerance. | +| 1511–1516 *(KRC5 only)* | `StartMovements` | Per-axis coordinate mirror — same `X/Y/Z/Rx/Ry/Rz` ordering as 1501–1506, for the movements task. | A *potential* entry is not a fault — inspect the KRC4 inputs named in the task's current step comment. A task only converts to an error (`10020`, 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 c3f61b3c8..17a32b5d3 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 @@ -213,6 +213,21 @@ private void InitializeTaskMessenger() new KeyValuePair(620, new AxoMessengerTextItem("Waiting for all output signals to be reseted!", "Check the status of the `ProActive` signal.")), + + new KeyValuePair(1501, new AxoMessengerTextItem("Waiting for the value of the `Inputs.Coordinates.X` to be the same as the value of the `CurrentMovementParameters.Coordinates.X `.", "Check the value of the Inputs.Coordinates.X ")), + new KeyValuePair(1502, new AxoMessengerTextItem("Waiting for the value of the `Inputs.Coordinates.Y` to be the same as the value of the `CurrentMovementParameters.Coordinates.Y `.", "Check the value of the Inputs.Coordinates.Y ")), + new KeyValuePair(1503, new AxoMessengerTextItem("Waiting for the value of the `Inputs.Coordinates.Z` to be the same as the value of the `CurrentMovementParameters.Coordinates.Z `.", "Check the value of the Inputs.Coordinates.Z ")), + new KeyValuePair(1504, new AxoMessengerTextItem("Waiting for the value of the `Inputs.Coordinates.Rx` to be the same as the value of the `CurrentMovementParameters.Coordinates.Rx`.", "Check the value of the Inputs.Coordinates.Rx")), + new KeyValuePair(1505, new AxoMessengerTextItem("Waiting for the value of the `Inputs.Coordinates.Ry` to be the same as the value of the `CurrentMovementParameters.Coordinates.Ry`.", "Check the value of the Inputs.Coordinates.Ry")), + new KeyValuePair(1506, new AxoMessengerTextItem("Waiting for the value of the `Inputs.Coordinates.Rz` to be the same as the value of the `CurrentMovementParameters.Coordinates.Rz`.", "Check the value of the Inputs.Coordinates.Rz")), + + new KeyValuePair(1511, new AxoMessengerTextItem("Waiting for the value of the `Inputs.Coordinates.X` to be the same as the value of the `CurrentMovementParameters.Coordinates.X `.", "Check the value of the Inputs.Coordinates.X ")), + new KeyValuePair(1512, new AxoMessengerTextItem("Waiting for the value of the `Inputs.Coordinates.Y` to be the same as the value of the `CurrentMovementParameters.Coordinates.Y `.", "Check the value of the Inputs.Coordinates.Y ")), + new KeyValuePair(1513, new AxoMessengerTextItem("Waiting for the value of the `Inputs.Coordinates.Z` to be the same as the value of the `CurrentMovementParameters.Coordinates.Z `.", "Check the value of the Inputs.Coordinates.Z ")), + new KeyValuePair(1514, new AxoMessengerTextItem("Waiting for the value of the `Inputs.Coordinates.Rx` to be the same as the value of the `CurrentMovementParameters.Coordinates.Rx`.", "Check the value of the Inputs.Coordinates.Rx")), + new KeyValuePair(1515, new AxoMessengerTextItem("Waiting for the value of the `Inputs.Coordinates.Ry` to be the same as the value of the `CurrentMovementParameters.Coordinates.Ry`.", "Check the value of the Inputs.Coordinates.Ry")), + new KeyValuePair(1516, new AxoMessengerTextItem("Waiting for the value of the `Inputs.Coordinates.Rz` to be the same as the value of the `CurrentMovementParameters.Coordinates.Rz`.", "Check the value of the Inputs.Coordinates.Rz")), + }; TaskMessenger.DotNetMessengerTextList = messengerTextList; @@ -320,6 +335,21 @@ public string ErrorDescription errorDescriptionDict.Add(1231, "Error writing the output data (Config.HWIDs.HwID_512_DI_DO)!"); + + errorDescriptionDict.Add(1501, "Waiting for the value of the `Inputs.Coordinates.X` to be the same as the value of the `CurrentMovementParameters.Coordinates.X `."); + errorDescriptionDict.Add(1502, "Waiting for the value of the `Inputs.Coordinates.Y` to be the same as the value of the `CurrentMovementParameters.Coordinates.Y `."); + errorDescriptionDict.Add(1503, "Waiting for the value of the `Inputs.Coordinates.Z` to be the same as the value of the `CurrentMovementParameters.Coordinates.Z `."); + errorDescriptionDict.Add(1504, "Waiting for the value of the `Inputs.Coordinates.Rx` to be the same as the value of the `CurrentMovementParameters.Coordinates.Rx`."); + errorDescriptionDict.Add(1505, "Waiting for the value of the `Inputs.Coordinates.Ry` to be the same as the value of the `CurrentMovementParameters.Coordinates.Ry`."); + errorDescriptionDict.Add(1506, "Waiting for the value of the `Inputs.Coordinates.Rz` to be the same as the value of the `CurrentMovementParameters.Coordinates.Rz`."); + errorDescriptionDict.Add(1511, "Waiting for the value of the `Inputs.Coordinates.X` to be the same as the value of the `CurrentMovementParameters.Coordinates.X `."); + errorDescriptionDict.Add(1512, "Waiting for the value of the `Inputs.Coordinates.Y` to be the same as the value of the `CurrentMovementParameters.Coordinates.Y `."); + errorDescriptionDict.Add(1513, "Waiting for the value of the `Inputs.Coordinates.Z` to be the same as the value of the `CurrentMovementParameters.Coordinates.Z `."); + errorDescriptionDict.Add(1514, "Waiting for the value of the `Inputs.Coordinates.Rx` to be the same as the value of the `CurrentMovementParameters.Coordinates.Rx`."); + errorDescriptionDict.Add(1515, "Waiting for the value of the `Inputs.Coordinates.Ry` to be the same as the value of the `CurrentMovementParameters.Coordinates.Ry`."); + errorDescriptionDict.Add(1516, "Waiting for the value of the `Inputs.Coordinates.Rz` to be the same as the value of the `CurrentMovementParameters.Coordinates.Rz`."); + + errorDescriptionDict.Add(10000, "Start at main finished with error!"); errorDescriptionDict.Add(10001, "Start at main was aborted, while not yet completed!"); errorDescriptionDict.Add(10010, "Start motors and program finished with error!"); diff --git a/src/showcase/app/src/components.kuka.robotics/Documentation/AxoKrc5_v_5_x_x_Showcase.st b/src/showcase/app/src/components.kuka.robotics/Documentation/AxoKrc5_v_5_x_x_Showcase.st index acf5a722a..af733bcdb 100644 --- a/src/showcase/app/src/components.kuka.robotics/Documentation/AxoKrc5_v_5_x_x_Showcase.st +++ b/src/showcase/app/src/components.kuka.robotics/Documentation/AxoKrc5_v_5_x_x_Showcase.st @@ -36,10 +36,12 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x THIS.UseInSequencer(); END_METHOD - // - VAR PUBLIC - Sequencer : AxoSequencer; - Steps : ARRAY[0..19] OF AXOpen.Core.AxoStep; + // + VAR PUBLIC + Sequencer : AxoSequencer; + Steps : ARRAY[0..20] OF AXOpen.Core.AxoStep; + {#ix-set:AttributeName = "<#Last byte received from robot#>"} + _lastByteFromRobot : BYTE; END_VAR METHOD PRIVATE UseInSequencer @@ -202,10 +204,32 @@ NAMESPACE AXOpen.Components.Kuka.Robotics.v_5_x_x END_IF; END_IF; - IF(Steps[19].Execute(Sequencer, 'Restore')) THEN + // + // KRC5-only raw passthrough (#1148): the component transports these + // byte arrays verbatim over the same 64-byte cyclic block, without + // interpreting them. They carry `RenderIgnore`, so they are not part + // of the proxy view — exchange them from application code instead. + IF(Steps[19].Execute(Sequencer, '<#Exchange raw data with the robot#>')) THEN + // PLC -> robot: write an application-defined payload + // (mapped onto output bytes 44..63 of the cyclic block). + ExampleRobot.DataFromPlcToRobot[0] := BYTE#16#A1; + ExampleRobot.DataFromPlcToRobot[1] := BYTE#16#B2; + ExampleRobot.DataFromPlcToRobot[19] := BYTE#16#FF; + + // robot -> PLC: read the bytes the robot publishes back + // (mapped from input bytes 48..63 of the cyclic block). + _lastByteFromRobot := ExampleRobot.DataFromRobotToPlc[0]; + + IF(Sequencer.CurrentStep.Duration >= T#500ms) THEN + Sequencer.MoveNext(); + END_IF; + END_IF; + // + + IF(Steps[20].Execute(Sequencer, 'Restore')) THEN ExampleRobot.Restore(); Sequencer.CompleteSequence(); - END_IF; + END_IF; END_METHOD //