RTDE Register Conflict: Ownership Is Shared, Not Reserved

Erik Lindqvist6 min read
Industrial NetworkingOther ManufacturerTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

The number that matters is writers per register: one. When two software components target the same RTDE register, the later write replaces the earlier value and the symptom appears intermittent. This is state ownership and task timing, not current or thermal load; the affected controller setup provides no enforced reservation that prevents another component from reusing the address.

Register symptom interpretation

A collision usually appears as a valid value that changes unexpectedly rather than as a communication fault. A command may take effect briefly, revert on the next producer update, or vary with program state. Reconnecting can change the timing without removing the duplicate writer.

First identify the complete address: direction, data type, register index, and bit position where applicable. An index alone is insufficient because Boolean, integer, and floating-point banks are separate namespaces.

Quantity or condition Limit or interpretation Where to read it
Active writers per register One designated owner RTDE clients, controller program, URCaps, and service configuration
Register direction Input or output from the controller viewpoint RTDE recipe and controller interface documentation
Register type and index Must match at every endpoint Recipe definitions and application configuration
Observed update order The last writer determines the visible value Timestamped client logs and controller traces
Allocation inventory Allocation records coordinate users but do not lock registers URCap register-usage documentation
Known allocation-table coverage input_boolean_registers 64-127 and input_float_registers 24-46 appear in the documented map Register-usage table

Controller and client direction

RTDE direction names use the controller as the reference. An RTDE input is data entering the controller from an external client; an RTDE output is data produced by the controller for a client to read. A client application that reports that it is “writing an output” may be referring to its own application-level output, writing through controller-side logic, or using an API label differently from RTDE.

Resolve that terminology before moving addresses. Inspect the RTDE recipe and determine whether the disputed field is configured as client-to-controller data or controller-to-client data. If it is an RTDE output, trace the controller program or installed component that produces it. If it is an RTDE input, trace every connected client that can transmit it.

A successful connection or accepted recipe proves that the field is syntactically usable. It does not prove exclusive ownership. URCap allocation documentation helps integrators avoid overlap, but documentation alone cannot reject a conflicting connection or prevent controller-side software from writing the same location.

Last-writer timing mechanism

Each producer executes on its own schedule. One component may write only during initialization, another on every control update, and a third after a state transition. When their schedules overlap, the visible register contains whichever value was committed last. That explains why a value can look stable during commissioning and fail only when another feature starts.

Boolean registers add a second collision mode. Two components can share a storage location unintentionally while believing they own different logical flags. If either component writes the complete Boolean value or bit field without preserving the other component’s bits, unrelated flags change together. Track the register and bit allocation, including any hexadecimal mask, rather than recording only the parent register.

The same index written with an incorrect type is a different diagnostic problem: recipe validation, conversion, or application interpretation may fail. A genuine ownership collision uses the same effective bank and address and produces otherwise valid values from multiple sources.

Conflict diagnostic checks

  1. Capture the exact disputed address, including RTDE direction, register type, index, and Boolean bit or mask. Record the expected producer and every consumer.

  2. Read all RTDE recipes used by external clients. Search controller programs, URCap configuration, startup scripts, and background services for the same effective address.

  3. Build a writer table with one row per component. Record when each writer starts, what causes an update, and whether it writes continuously, on change, or only during initialization.

  4. Log the register value with timestamps while reproducing the symptom. Correlate each transition with client transmissions, program-state changes, and component startup events.

  5. Use a controlled test pattern from the intended owner. Choose several values that normal operation will not produce, then observe whether another component replaces them. Use values valid for the declared data type.

  6. Disable one suspected writer through its normal configuration or stop sequence and repeat the test. A stable register after that writer stops identifies the collision path; a reconnect-only improvement indicates changed timing, not a corrected allocation.

  7. Confirm direction from the controller viewpoint. If an external client is attempting to write a controller output through ordinary RTDE input configuration, correct the data-flow design before investigating ownership further.

Single-owner allocation procedure

  1. Assign one producer to every register. Treat all other components as consumers, even if their software permits a write operation.

  2. Create an allocation table containing component, direction, type, index, bit or mask, purpose, producer, and consumers. Record components that use no RTDE registers as well; that prevents uncertainty during later upgrades.

  3. Select an unused address after comparing every installed URCap and client allocation. The documented ranges for input_boolean_registers and input_float_registers show why type-specific inventories matter, but an entry in a table is coordination data rather than a controller reservation.

  4. Move the less stable or locally configurable component when two deployed components overlap. Update its recipe, controller logic, client mapping, diagnostics, and allocation record together.

  5. Use separate controller-input and controller-output registers for bidirectional exchange. One side owns the command location; the other side owns a separate status or acknowledgement location.

  6. Restart the affected components through their normal stop and start sequence so cached recipes and startup writes use the new mapping.

Verification and recurring pitfalls

Run the complete operating sequence, not only an idle-state test. Exercise initialization, program start, mode changes, recovery, client reconnect, and controller restart. Log both the old and new addresses: the old location must remain untouched, while the new location must change only when its designated producer updates it.

Pitfall Observed result Correction
Recording only the numeric index Different banks appear to conflict or the actual overlap is missed Record direction, type, index, and bit or mask
Treating an allocation list as a lock A second component still writes the address Audit every active producer and enforce ownership in configuration
Testing only after reconnection The fault disappears temporarily Repeat the full state and startup sequence with timestamped logs
Using one register for command and status Controller and client overwrite each other Assign separate registers with opposite owners
Moving one endpoint only Stale data or apparent communication loss Change recipe, logic, mapping, and documentation as one revision

FAQ

Why does my RTDE register value change back after I write it?

Another producer is writing the same effective register after your update. Log transitions with timestamps, then disable suspected writers one at a time until the value remains stable.

Why can I write RTDE input registers but not output registers?

RTDE direction is named from the controller viewpoint: inputs enter the controller from a client, while outputs are produced by the controller for clients to read. Check the recipe direction and use separate command and status registers for bidirectional data.

When should I stop troubleshooting an RTDE register conflict?

Stop after confirming the full address and direction when an undocumented writer remains active, the conflicting address cannot be changed, or the controller behavior differs from its interface documentation. Escalate to official manufacturer support with the RTDE recipes, allocation table, installed component list, timestamped trace, and a minimal reproduction sequence.

Back to blog