## 2 Materials and Methods
### Software  
The firmware for the smart lifejacket needed to incorporate multiple functionalities, all of which would require memory allocation, task scheduling and preemption, as well as intertask communication and synchronization in the form of flags and shared data structures. These included the following:  
* Indoor localization;
* Wireless connection to a central system;
* Clock synchronization;
* Haptic navigation;
* Detection and reading of near-field tags on a peripheral device;
* Wireless connection to a peripheral device. An open-source real-time operating system kernel [31] was selected, both for its feature list and maturity, as well as its close integration with the microcontroller unit selected. A number of required API's were already provided in the software tool set. Different functionalities for the navigation module were written as one or more separate tasks running concurrently and with potentially different priorities on the lifejacket to achieve the desired operation. On initialization, the lifejacket attempts to connect to the wireless network and, having done that, synchronize and connect to the message broker. At the same time, it starts up the connection to the UWB, IMU and NFC reader, as well as other peripheral devices, and attempts to configure their operation as required. The localization module starts after the UWB module has been initialized and starts to poll it in order to obtain the calculated position. A lightweight JSON [32] protocol message format was designed to exchange messages with the central system over MQTT [33], a good fit for the use case. Three basic messages were implemented: registration, data update and route request/response. With the exception of the route request, all messages do not require a response. Since the lifejacket guides the passenger on demand, there was a need for some type of RPC call over the underlying messaging protocol so that the lifejacket can receive a route which has as a starting point its current position. In order to obtain a better position estimate, a linear Kalman filter was added to be run each time the UWB module was polled for a location estimate. This is a widely used technique to produce estimations from a noisy signal using a statistical model [34; 35]. It was considered suitable for the navigation component due to its small memory footprint and light computational requirements. It works by means of a feedback loop to calculate a measurement estimation based on sensor readings and the previous estimation. This way, the navigation algorithm has a smoother and more predictable calculation that is free from sensor noise to the extent that it is feasible. Ultimately, one such lightweight library was used to provide estimates for the location and speed of the user at each step. Navigation is provided to the user when it is requested by holding the push button. The application utilizes an RPC-style mechanism over the MQTT client to request a route from the central system. The latter replies with a list of points forming a route from the passenger's current location, present at the original message, to a suitable destination. The route is parsed and the passenger is notified that the navigation procedure has started. While the navigation process is ongoing, a haptic signal is triggered when a timeout occurs, as long as a minimum speed is maintained, which serves to guide the passenger towards the next point in the route. When the passenger arrives at the point currently active at the route, an additional haptic indication is provided to them which helps navigate along sharp turns in confined spaces. These indications are in addition to the ones provided on a schedule, as previously mentioned. A different approach is used when the passenger needs to move between floors. When the next point is on a different height, the algorithm indicates that moving upwards or downwards is required without regard for where the passenger is facing.