User Tools

Site Tools


getting_started:practical_problems:abort

Shutting down a System Properly

How does a robot control system properly shut down? In general it does never stop. Pressing an emergency button might switch to a emergency safety level. From there it might restart again after certain steps are taken.
However, in a system under development it is often desirable to end an application. That usually means to switch to a specific safety level where the necessary steps for a well controlled stopping of the application takes place. Only after this happened the executor stops running and returns control to the main program, which then stops as well.
The following example shows how this can be accomplished. The code can be found in Example with a More Complex Safety System. First of all you have to define a signal handler which handles all kind of signals, among them the SIGINT signal which is sent by pressing Ctrl-C.

#include "MySafetyProperties.hpp>
#include <signal.h>
 
void signalHandler(int signum) {
  SafetySystem::exitHandler();
}
 
int main() {
  signal(SIGINT, signalHandler);
 
  ...
 
  // Create and initialize safety system
  double period = 1;
  MySafetyProperties ssProperties;
  SafetySystem safetySys(ssProperties, period);
 
  ... 
}

The exitHandler in the safety system runs a predefined exit function which must be defined in your safety properties.

exitFunction = [&](SafetyContext* privateContext) {
  privateContext->triggerEvent(seShutDown);
};

In the example this function triggers a safety event seShutDown. You have to add this event to all safety levels where you actually want to allow shutting down the machine.

After pressing Ctrl-C the safety system will go into the safety level slShuttingDown, see example in Example with a More Complex Safety System. The system will stay in the level as long as the shutting down will take. This could include a whole sequence of steps such as applying brakes or driving to a safe position. As soon as this point is reached another safety event, seSwitchingOff is triggered which leads to a safety level change to slOff. The action to be taken in this level is stopping the executor. Therefore, you have to assign a level action in your safety properties as follows:

slOff.setLevelAction([&](SafetyContext* privateContext) {
  Executor::stop();
  Sequencer::instance().abort();
});

This will cause the executor to stop running and return control to the main programm. Further, any running sequences will terminate and the main program will exit.

Define Signal Handler when using ROS

If you use ROS you have to keep in mind to register the signal handler only after the ROS node is created and initialized, otherwise the registration will be overwritten by ROS.

int main() {
  ...
  // init ROS node
 
  signal(SIGINT, signalHandler);
  ...
}
getting_started/practical_problems/abort.txt · Last modified: 2024/02/16 08:16 by ursgraf