mirror of
https://git.intern.spaceteamaachen.de/ALPAKA/TACOS.git
synced 2025-06-10 00:25:59 +00:00
Documentation for the statemachine.
This commit is contained in:
parent
9ff5e34a27
commit
e89b21ddcc
116
README.md
116
README.md
@ -247,7 +247,7 @@ namespace sta
|
||||
|
||||
## TACOS Usage Guide
|
||||
|
||||
Almost all of the important aspects of working with TACOS have already been discussed when setting up the project itself. The following sections will give you an in-depth explanation of how to use the statemachine, CAN-Bus and inter-thread communication.
|
||||
Almost all of the important aspects of working with TACOS have already been discussed when setting up the project itself. The following sections will give you an in-depth explanation of how to use the statemachine, inter-thread communication and the CAN-Bus.
|
||||
|
||||
### Using the Statemachine
|
||||
|
||||
@ -257,7 +257,119 @@ The statemachine forms the heart and soul of a TACOS-based project. Upon initial
|
||||
> [!IMPORTANT]
|
||||
> The statemachine does immediately stop a thread and deletes it from memory. Instead, the thread is allowed to finish the current execution of its `func` before entering a blocked state. This allows the thread to release all its resources.
|
||||
|
||||
A state transition can be triggered by calling the functions `requestState()`, `forceState()` or `setStateTimed()` that are provided in `sta/tacos.hpp`. Additionally, state transitions can be triggered remotely using the CAN-Bus. This is discussed in more detail in the section discussing the CAN Bus.
|
||||
In order to fully understand the statemachine, we have to take a look at the _lockout_ and _failsafe timer_. These lockout and failsafe timers are the result of design choices made during early stages of STAHR. The goal was to combine the state estimation (i.e. sensor fusion using a Kalman filter) with timer-based safety mechanisms. For example, our goal was to block any state transition to the state `DROGUE` before 60 seconds after liftoff. Additionally, a timer was started to automatically switch to state `DROGUE` after 120 seconds after liftoff.
|
||||
|
||||
These safety mechanisms resulted in the implementation of the lockout and failsafe timer in TACOS:
|
||||
1. The lockout timer can be started after a state transition. As long as it is running, all state transitions are blocked by the statemachines, unless the user actively chooses to bypass the safety mechanism using `forceState()`.
|
||||
2. The failsafe timer can be used to request a state transition after a certain period of time has elapsed. This transition will be blocked if the lockout time is running at that time. The failsafe timer obeys the following rules:
|
||||
- A timed state transition can be requested even when the lockout timer is active. It only matters if the lockout timer is running at the end of the time span of the lockout timer.
|
||||
- If a state transition is triggered before the end of the time span, the failsafe timer is stopped.
|
||||
|
||||
A state transition can be triggered by calling the functions `requestState()`, `forceState()` or `setStateTimed()` that are provided in `sta/tacos.hpp`. Additionally, state transitions can be triggered remotely using the CAN-Bus, however, this is discussed in more detail in the section on the CAN Bus.
|
||||
|
||||
#### `requestState(uint32_t from, uint32_t to, uint32_t lockout = 0, bool publish = true)`
|
||||
|
||||
Requests a state transition from state `from` to the state `to`. Will be blocked if `from` is not the current state or if the lockout time is running. Optinally, use the `lockout` parameter to also start the lockout timer if the state transition is successful. The argument `publish` tells the TACOS to also publish the state on via the CAN bus
|
||||
|
||||
#### `forceState(uint32_t from, uint32_t to, uint32_t lockout = 0, bool publish = true)`
|
||||
|
||||
Forces a state transition from state `from` to the state `to`, bypassing the lockout timer. However, in order to protect the integrity of the statemachine, `from` has to match the current state. Similar to `requestState()`, an optional lockout timer can be set and the state can be published via CAN.
|
||||
|
||||
#### `setStateTimed(uint32_t from, uint32_t to, uint32_t millis, uint32_t lockout = 0, bool publish = false)`
|
||||
|
||||
Schedules a state transition from state `from` to state `to` in `millis` milliseconds. Additionally, a lockout timer of `lockout` milliseconds can be set which will become active _after_ successful state transition from `from` to `to`. Similarly, setting `publish` to `true` will result in a successful state transition being broadcast on the CAN bus.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> If the failsafe timer is already running with a different state transition, calling `setStateTimed` will overwrite this request.
|
||||
|
||||
#### Example Usage
|
||||
|
||||
Generally, the state transitions are requested in the `startup()` function or in TacosThread instances implemented by the user. It is good practise to give your states names by defining an enum in a header file `states.hpp` that can be included everywhere in your project.
|
||||
|
||||
```cpp
|
||||
#ifndef MY_PROJECT_STATES_HPP
|
||||
#define MY_PROJECT_STATES_HPP
|
||||
|
||||
namespace my_project
|
||||
{
|
||||
enum class States : uint16_t
|
||||
{
|
||||
STARTUP = 0,
|
||||
PING = 1,
|
||||
PONG = 2
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MY_PROJECT_STATES_HPP
|
||||
```
|
||||
|
||||
This gives us three states: `STARTUP`, `PING` and `PONG`. Generally, these names have no meaning for TACOS but they make your software more readable. Next, we define two modified tasks based on `SpamTask` for our project:
|
||||
```cpp
|
||||
#include <tasks/ping_task.hpp>
|
||||
#include <tasks/pong_task.hpp>
|
||||
#include <path/to/states.hpp>
|
||||
|
||||
namespace tasks {
|
||||
PingTask::PingTask() :
|
||||
TacosThread("PING", osPriorityNormal){}
|
||||
|
||||
void PingTask::func() {
|
||||
sleep(100);
|
||||
|
||||
STA_DEBUG_PRINTLN("PING");
|
||||
|
||||
sta::tacos::requestState(my_project::PING, my_project::PONG);
|
||||
}
|
||||
|
||||
PongTask::PongTask() :
|
||||
TacosThread("PONG", osPriorityNormal){}
|
||||
|
||||
void PongTask::func() {
|
||||
sleep(100);
|
||||
|
||||
STA_DEBUG_PRINTLN("PONG");
|
||||
|
||||
sta::tacos::requestState(my_project::PONG, my_project::PING);
|
||||
}
|
||||
} // namespace tasks
|
||||
```
|
||||
> [!IMPORTANT]
|
||||
> Generally, you want both tasks to be implemented in separate .cpp files.
|
||||
|
||||
Using these two threads we can implement our `startup()` function:
|
||||
|
||||
```cpp
|
||||
|
||||
#include <sta/tacos.hpp>
|
||||
#include <tasks/spam_task.hpp>
|
||||
#include <path/to/states.hpp>
|
||||
|
||||
#include <sta/debug/debug.hpp>
|
||||
|
||||
namespace sta
|
||||
{
|
||||
namespace tacos
|
||||
{
|
||||
void startup()
|
||||
{
|
||||
// Register a "PingTask" thread for the state PING.
|
||||
sta::tacos::addThread<tasks::PingTask>({my_project::PING});
|
||||
sta::tacos::addThread<tasks::PongTask>({my_project::PONG});
|
||||
|
||||
// Start with the spam after one second.
|
||||
sta::tacos::setStateTimed(my_project::STARTUP, my_project::PING, 1000);
|
||||
}
|
||||
} // namespace tacos
|
||||
} // namespace sta
|
||||
```
|
||||
|
||||
The resulting program switches between the states `PING` and `PONG` and alternately outputs "PING" and "PONG" via UART. While this is just a toy example, building more complicated applications is not much harder!
|
||||
|
||||
### Using Inter-Thread Communication
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Coming soon!
|
||||
|
||||
|
||||
### Further information
|
||||
To look into other function of TACOS please consult the READMEs in the include folder or the doxygen documentation. Also consult the sta-core and rtos2-utils READMEs for further information on the features that TACOS uses.
|
Loading…
x
Reference in New Issue
Block a user