What do you think about adding “Design By Contract” functionality to ROS?
“Design By Contract is an approach for designing software. It prescribes that software designers should define formal, precise and verifiable interface specifications for software components, which extend the ordinary definition of abstract data types with preconditions, postconditions and invariants.” Design By Contract (wikipedia.org)
“Design By Contract (DBC)” can dramatically decrease the effort during software integration and dramatically increase the overall system reliability.
“Design By Contract (DbC)” is a built-in feature of many recent programming languages. Usually the verification of these interface specifications is supported on different levels of abstractions during “debug” builds at runtime. D (contracts) supports runtime checking of contracts on the interface, the class and the (member) function level for example:
On the class level the caller of a member function ensures defined preconditions. When the preconditions are fulfilled the member functions guarantees proper functioning and defined postconditions. Invariant checks ensure that an object remains in a valid state during runtime. The validity of the internal state (e.g. class members) is checked after the execution of the constructor, before the execution of the destructor, before and after the execution of a public member function. [Cehreli, Ali: Programming in D, IngramSpark, 1st edition, 2017, p. 218 and 386 or somewhere in the online version]
In ROS one could think of node level contracts w.r.t. … (impact of DbC on timing):
- if node is topic publisher (postcondition checks)
- (“guaranteed” topic publish rate)
- “guaranteed” topic message type values
- if node is topic subscriber (precondition checks)
- (“expected” topic reception rate)
- “expected” topic message type values
- if node is service server
- (“guaranteed” service response time) (postcondition check)
- “expected” service request message type values (precondition check)
- “guaranteed” service response message type values (postcondition check)
- if node is service client
- “guaranteed” service request message type values (postcondition check)
- “expected” service response message type values (precondition check)
- if node is action server
- (“guaranteed” feedback transmission delay after goal request has been received) (postcondition check)
- (“guaranteed” result transmission delay after goal request has been received) (postcondition check)
- “expected” action goal message type values (precondition check)
- “guaranteed” action feedback message type values (postcondition check)
- “guaranteed” action result message type values (postcondition check)
- if node is action client
- (“expected” feedback message delay after goal request has been transmitted) (precondition check)
- (“expected” goal message delay after goal request has been transmitted) (precondition check)
- “guaranteed” action goal message type values (postcondition check)
- “expected” action feedback message type values (precondition check)
- “expected” action result message type values (precondition check)
Checks w.r.t. to timing could be heavily impacted by the prrocessing overhead of checks for complex message types. However in some circumstances (comparably low processing overhead due to checks) they could at least give some rough estimate w.r.t. to “dynamic” node dependencies.