When implementing a service client, there are a few possible approaches for handling Command messages (RequestControl, SetWrenchEffort, etc):
- Send the message once and hope it makes it to the server.
- Send the message continuously at some interval.
- Send the message continuously until the desired change is confirmed by either:
- Receiving a Confirm message.
- Receiving a Report message that indicates the change has occurred.
When choosing an approach, you should consider:
- The service being commanded
- The reliability of the communication network
- Other system design constraints
Example 1: Primitive Driver Service
Approach 1 - Reliability & safety issues
In any network where data loss is possible, the single message may be lost and the vehicle will never move. Even if we have a perfectly lossless communication network, sending a message once requires that the receiving robot latch (cache and continuously execute until changed) the provided command which is a major safety issue. Most well design systems will have some kind of drive timeout, where if a new command is not received within a specified interval, the robot will stop.
Approach 3 - Unnecessary complexity & bandwidth use
The open loop nature of the Primitive Driver means that the command messages will be constantly changing as part of a control loop (either by a human operator or some other software) and verifying that the commanded values have been received/executed does not add any value. If the commanded value has not been executed, it is likely that the same command will not be sent again as the control loop may attempt to compensate for the missed command.
Approach 2 - Best option
The best option for this service is to send the command messages continuously at some rate. We want to send the message fast enough to ensure a responsive system but slow enough such that we are not flooding the network.
Example 2: Management Service
Approach 2 - Introduces undesirable side effects in some situations
The Reset and SetEmergency commands have undesirable side effects when they are sent multiple times. If Reset is continuously sent, then the robot will continuously reset. When a SetEmergency message is received, the robot pushes it's current state onto the state stack and enters Emergency again. If SetEmergency is continuously sent, you could encounter a "stack overflow" condition.
Approach 1 - Best option on very reliable network
The potential side effects of approach 1, may encourage us to send a message once and hope it is received on the robot. If we have a very reliable network, this may be fine. However, on a network that is less reliable losing messages could introduce safety concerns. If a SetEmergency message is not received by the robot, the robot would continue to function until a command finally received. In the send once approach, the operator will probably be required to manually send the command again (via some button on the controller) and during the time between the first send command and the command that is actually executed the robot is unsafe.
Approach 3 - Best option in general
This approach balances the issues with approach 2 while dealing with a less than ideal network (unlike approach 1). Commands that have undesirable side effects such as Reset or SetEmergency will be sent until it can be confirmed the command has been executed. In the case of Reset, this could lead to the robot resetting more times than necessary but that may be okay. For SetEmergency, if the Emergency state is pushed multiple times, when we send the ClearEmergency message, we will automatically ClearEmergency the correct number of times as the command will be sent until Emergency state is exited. In other cases, sending the message multiple times improves reliability.