Skip to the content
FixTheRobot Explore Robotics / UAV / Module 7 / M7-T17

UAV Systems Engineering · Module 7

M7-T17: Interface Control Documents

Most integration failures are interface failures. Write the contract down, check it with a script, and test it.

  • Lesson 17 of 19
  • Embedded Systems, Timing and System Integration
  • Established engineering
  • About 6 minutes to read

When the perception team publishes an odometry message and the autopilot team consumes it, what are the units, the frame, the covariance convention, the rate, the latency budget and the behaviour when it stops? If the answers live in people’s heads, the first flight will find the disagreement. An ICD records them, and a script can check it.

Learning objectives

After this lesson, you should be able to:

  • List the attributes that must be specified for every interface.
  • Write an interface entry with units, frames, rates, timing and failure behaviour.
  • Check an ICD automatically for missing fields and inconsistencies between producer and consumer.
  • Version, review and verify interfaces through change control and interface tests.

Conceptual explanation

Established ICDs are standard systems-engineering artefacts. The attribute list below is a practical minimum for flight software; programme standards may require more.

An Interface Control Document defines everything two components need to know about each other so that each can be built and tested independently. For each interface the entry should state:

undefined
AttributeContentTypical omission
ID and nameUnique, stable identifierNames that change between documents
Producer and consumerOwning component for each endUnknown consumers
Physical / transportBus or network, protocol, topic or message id, QoSQoS and queue depth
Data definitionFields, types, units, ranges, resolutionUnits, valid ranges
Frames and conventionsCoordinate frames, quaternion order, covariance layout, time baseThe most common cause of flipped axes
Rate and latencyNominal rate, tolerance, maximum age, latency budgetMaximum age
Timing and timestampsWhat the timestamp refers to and its clockWhich clock
Validity and failure behaviourValidity flags, timeout, what each side does on loss, invalid or stale dataFailure behaviour
Version and change policyVersion number, compatibility rule, owners to notifyCompatibility rule
ICD lifecycleInterfaces are identified from the architecture, specified with every attribute needed to implement both ends, reviewed by both owners, versioned, and verified by test. A change is a controlled event that notifies both sides.Identifyfrom architectureSpecifyall attributesReviewboth ownersVersionbaselineVerifyinterface testAn interface is a contract between two teams; the document is the only thing both sides share.
An interface is a managed object with an owner and a version.
Animation of an automated check of an interface control document. A table lists the signals exchanged between a producer and a consumer, with their frame, unit, rate and timestamp base as declared by each side. A scanner moves down the table and compares each field; matching rows turn green and mismatches turn red, such as a frame declared as ENU on one side and NED on the other or a unit of degrees against radians. The final line counts the defects found.
The interface is the document; the check is code that compares the two declarations. Frames, units, rates and time bases are the usual silent mismatches. Illustrative signals; the comparison is performed on the data shown. (Looping, about 5 seconds; drawn and computed for this course with illustrative values.)

Engineering intuition

Think of the ICD as the specification you would give to someone who has never spoken to the other team. If a field says “position” the reader needs to know metres or centimetres, which frame, which origin, relative to what time. If the sender stops, what does the receiver do? Having to write the failure behaviour is the useful part: it forces the conversation about the failsafe before the crash.

Machine-checkable ICDs are even better: a structured file (YAML or JSON) from which message definitions, documentation and validation scripts can be generated. Then “producer rate 20 Hz, consumer expects 30 Hz” is a failed check in review, not a surprise in flight.

Mathematical formulation

Consistency rules that can be checked mechanically between a producer PP and a consumer CC of the same interface:

Rate
fP≥fC,min⁡f_P \ge f_{C,\min}
Latency
LP+Ltransport+LC≤LbudgetL_P + L_{\text{transport}} + L_C \le L_{\text{budget}}
Age
agemax⁡,C≥1fP+Ltransport (+ jitter)\text{age}_{\max,C} \ge \frac{1}{f_P} + L_{\text{transport}}\ (+\ \text{jitter})
Timeout
timeoutC≥mfPandtimeoutC≤time to hazard\text{timeout}_C \ge \frac{m}{f_P} \quad\text{and}\quad \text{timeout}_C \le \text{time to hazard}
m is the number of missed messages tolerated.

where ff is the rate, LL the latency contributions, and the last condition ties the consumer’s loss-detection time to the hazard analysis: too short and it triggers spuriously, too long and the failure is not handled in time. For a message of nn bytes at rate ff on a link, the bandwidth is 8 nn ff bits per second (plus protocol overhead), which must fit the link budget from the previous lesson.

fPf_{P}, fCf_{C},min
producer rate and minimum rate the consumer needs.
LbudgetL_{\text{budget}}
latency allocated to this interface in the end-to-end budget.
mm
number of consecutive missed messages that declare loss.

Architecture and data flow

Architecture diagram → interface list (IDs) → ICD source file (YAML/JSON) in the repository → generated documentation, message definitions and unit tests → review by producer and consumer owners → baseline tag → interface tests in SIL, HIL and flight. Changes go through the same review; the version in the message (or a version topic) lets the consumer reject incompatible data.

Real-world UAV applications

  • Specifying the external-odometry interface between a VIO node and the autopilot.
  • Reviewing integration of a third-party sensor.
  • Preparing the interface section of a safety case.
  • Generating tests that check every interface against its specification.

Implementation example

This runs as shown. A small ICD as data, and a checker that finds missing attributes and producer-consumer inconsistencies. The example interfaces are illustrative.

REQUIRED = ['id', 'producer', 'consumer', 'transport', 'fields', 'frame', 'rate_hz', 'rate_min_hz', 'max_age_s', 'timestamp', 'timeout_s', 'loss_action', 'version']
icd = [
  dict(id='IF-ODOM-01', producer='vio', consumer='autopilot', transport='DDS /fmu/in/vehicle_visual_odometry (best-effort, depth 1)',
       fields={'position': 'm', 'q': 'unitless (w,x,y,z)', 'pose_covariance': 'm^2, rad^2'}, frame='FRD body, NED world', rate_hz=30, rate_min_hz=20, max_age_s=0.1,
       timestamp='image exposure midpoint, vehicle clock', timeout_s=0.5, loss_action='autopilot stops fusing EV, falls back to non-EV mode, raises warning', version='1.2'),
  dict(id='IF-SP-01', producer='planner', consumer='autopilot', transport='DDS /fmu/in/trajectory_setpoint (best-effort, depth 1)',
       fields={'position': 'm', 'velocity': 'm/s', 'yaw': 'rad'}, frame='NED', rate_hz=20, rate_min_hz=30, max_age_s=0.15,
       timestamp='vehicle clock', timeout_s=0.3, loss_action='autopilot leaves offboard and holds', version='1.0'),
  dict(id='IF-HB-01', producer='companion', consumer='autopilot', transport='MAVLink HEARTBEAT', fields={'status': 'enum'}, frame='n/a', rate_hz=1, rate_min_hz=1,
       max_age_s=3.0, timestamp='n/a', timeout_s=3.0, version='1.0')]                               # note: no loss_action specified
def check(icd):
    problems = []
    for i in icd:
        for k in REQUIRED:
            if k not in i or i[k] in ('', None): problems.append(f"{i['id']}: missing '{k}'")
        if i.get('rate_hz', 0) < i.get('rate_min_hz', 0): problems.append(f"{i['id']}: producer rate {i['rate_hz']} Hz below consumer minimum {i['rate_min_hz']} Hz")
        if i.get('rate_hz') and i.get('timeout_s') is not None and i['timeout_s'] < 3 / i['rate_hz'] - 1e-9: problems.append(f"{i['id']}: timeout {i['timeout_s']} s shorter than 3 message periods ({3 / i['rate_hz']:.3f} s): spurious loss likely")
        if i.get('rate_hz') and i.get('max_age_s') is not None and i['max_age_s'] < 1 / i['rate_hz']: problems.append(f"{i['id']}: max age shorter than the message period")
    return problems
problems = check(icd)
for p in problems: print("PROBLEM:", p)
assert any('IF-SP-01' in p and 'below consumer minimum' in p for p in problems) and any('IF-HB-01' in p and 'loss_action' in p for p in problems)
assert not any('IF-ODOM-01' in p for p in problems)
An ICD as data, with a checker for missing attributes and rate, timeout and age inconsistencies.

Common engineering mistakes

Describing fields without units and frames

The classic source of mirrored motion and scale errors.

No failure behaviour

The most important column is the one most often left blank.

Specifying a nominal rate only

Give the minimum acceptable rate and the maximum age.

Unversioned changes

A silent change on one side breaks the other; version and notify.

An ICD that is never tested

Write an interface test per ID and run it in SIL and HIL.

Failure modes

Failure modes, symptoms and causes
Failure modeHow it shows upLikely cause
Mirrored or scaled motionVehicle goes the wrong way or too farFrame, unit or quaternion-order mismatch
Spurious loss eventsFailsafes trigger in normal flightTimeout shorter than a few message periods or jitter
Silent degradation on lossNo warning, strange behaviourNo specified failure behaviour
Break after an updateInterface fails after a releaseNo version check or compatibility rule

Debugging approach

  1. Compare the actual message rate, age and fields in a log against the ICD entry.
  2. Run the checker in continuous integration.
  3. Inject the failure (stop the stream, send stale data) and compare with the specified behaviour.
  4. Review the ICD at every release with both owners.

Practical exercises

  1. Write the ICD entry for the camera-trigger feedback interface between flight controller and companion.
  2. Add a check to the script: producer and consumer frame fields must match or specify a conversion.
  3. Compute the bandwidth of the three example interfaces.
  4. Define the compatibility rule for a message version change (add field, rename field, change unit).

Interview questions

Write an answer in your own words, then reveal the model answer. Nothing is sent anywhere.

Question 1

What belongs in an interface specification beyond the message fields?

Model answer

Units, frames and conventions, rates and maximum age, timestamp meaning and clock, validity flags, timeouts, behaviour on loss or invalid data, and the version and change policy.

Question 2

Why is failure behaviour part of the ICD?

Model answer

The consumer’s response to a missing, stale or invalid message is a safety function that both teams must agree on and test; leaving it implicit hides hazards.

Question 3

How can you make an ICD enforceable?

Model answer

Keep it as structured data, generate definitions and tests from it, run a consistency checker in CI, and verify each interface in SIL, HIL and flight tests.

References and further reading

Primary papers, official documentation and standards. Each claim above that is specific to a tool or version points here.

What’s next

Mark this lesson

Saved in this browser and synced to your account when you are signed in.

Practice this lesson

M7-L6: Develop a system architecture and interface diagram

Document interfaces.

Next lesson

M7-T18: Requirements traceability

Trace requirements to design elements and test cases, and detect gaps and orphans in a traceability matrix.