ros2_control async controllers: an on-time trigger can reuse an older result

A regular Controller Manager loop does not prove that an asynchronous controller completed a fresh update on every trigger. The Kilted documentation describes an async handler that can reuse the previous callback result when the preceding update is still running. Record accepted triggers, completed work and the command handoff separately before treating loop frequency as evidence of fresh control output.

This article reads the current Kilted documentation and an exact Kilted source revision checked on October 13, 2026. It does not verify an installed package or report a controller, hardware or timing test.

Count accepted triggers separately from completed work

The asynchronous-controller documentation distinguishes the controller manager’s scheduling loop from a controller’s asynchronous update(). The controller has its own configured update rate. If earlier work has not completed when another trigger arrives, the handler can reuse its previous result and report missed update cycles.

That result needs a precise meaning. In the examined controller-interface implementation, the async handler is parameterized with the controller’s return_type. Trigger success and the returned callback result occupy different status fields. The result is not itself a timestamped joint-command packet or evidence that a drive applied a newly computed command.

Prepare a trace record that can answer four questions without guessing from a frequency display:

EventEvidence to retainWhat it leaves unresolved
Manager schedules a triggerController identity and trigger timeWhether the callback accepted work
Handler accepts workAcceptance result and callback identityWhen the computation will finish
Callback completesCompletion time and return statusWhich command object was handed onward
Consumer uses a commandCommand identity, production time and application evidenceWhether another interface delayed it

This is a proposed instrumentation record. Match each event to the installed implementation rather than assuming that every controller exports these fields already. A command sequence counter supplied by one layer cannot automatically stand in for a callback-completion counter in another.

Make a missed-update warning part of the run record

The documentation’s warning compares missed cycles with total triggers. Keep those counts with the controller’s configured rate, observed execution time and configuration lifetime. A log message on its own is too little context to compare two runs with different schedules.

The source revision increments separate trigger statistics and resets them during configuration. Its warning is throttled. Therefore, counting visible warning lines is a poor substitute for retaining the underlying missed and total values. A quiet log interval should not be interpreted as proof that every update was accepted.

If work regularly exceeds its allotted period, first identify what consumes that time. Consider a lower controller trigger rate or moving unsuitable work away from the update path, then evaluate the resulting control requirement again. Increasing thread priority is not evidence that a blocking operation became bounded. Reducing a rate is also an engineering change, not an automatic cure for a robot’s tracking or stability problem.

Keep the comparison local to the configuration under examination. A diagnostic result from one controller does not establish the timing of every controller, the hardware read/write path or the network between the host and drive.

Retain the command handoff as its own contract

Inspect where the controller publishes or writes command values and which consumer reads them. Record the intended policy for incomplete work, retained commands, age limits and faults. Those details belong to the actual controller and application; the async scheduler’s return status does not specify them for you.

Controller scheduling also differs from asynchronous hardware scheduling. The examined Kilted controller configuration rejects detached scheduling. A hardware component’s independently timed read/write policy must be assessed on its own supported interface, rather than copied into the controller configuration because both mechanisms use an async handler.

For the underlying resource and hardware boundaries, use the ros2_control hardware-interface guide. Start the next timing investigation with one controller, one configuration interval and the four-event record above. That makes it possible to separate a missed trigger from slow completion or a later command-transfer delay without claiming a measured result before the evidence exists.