Skyward boardcore
Loading...
Searching...
No Matches
HILTransceiver.h
Go to the documentation of this file.
1/* Copyright (c) 2020-2024 Skyward Experimental Rocketry
2 * Author: Emilio Corigliano
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#pragma once
24
25#include <ActiveObject.h>
27#include <drivers/usart/USART.h>
28#include <utils/Debug.h>
29
30#include "HIL.h"
31#include "drivers/usart/USART.h"
32
33namespace Boardcore
34{
35
36template <class FlightPhases, class SimulatorData, class ActuatorData>
37class HIL;
38
40{
41public:
46
52 int getLostUpdates() const { return nLostUpdates; }
53
59
60protected:
65 {
66 miosix::Lock<miosix::FastMutex> l(mutex);
67 while (!updated)
68 condVar.wait(l);
69 updated = false;
70 }
71
73 bool receivedFirstPacket = false;
74 bool updated = false;
75 int nLostUpdates = 0;
76 int64_t timestampSimulatorData = 0; // timestamp of the last received
77 // simulatorData [ns]
78 miosix::FastMutex mutex;
79 miosix::ConditionVariable condVar;
81};
82
87template <class FlightPhases, class SimulatorData, class ActuatorData>
89{
90public:
97 HILPhasesManager<FlightPhases, SimulatorData,
98 ActuatorData>* hilPhasesManager)
99 : HILTransceiverBase(hilSerial), actuatorData(),
100 hilPhasesManager(hilPhasesManager)
101 {
102 }
103
111 void setActuatorData(ActuatorData actuatorData)
112 {
113 miosix::Lock<miosix::FastMutex> l(mutex);
114
115 // If already updated increment lost updates
116 if (updated)
117 nLostUpdates++;
118
119 this->actuatorData = actuatorData;
120 updated = true;
121 condVar.signal();
122 }
123
129 const SimulatorData* getSensorData() const { return &simulatorData; }
130
131private:
132 void run() override;
133
134 SimulatorData simulatorData;
135 ActuatorData actuatorData;
136 HILPhasesManager<FlightPhases, SimulatorData, ActuatorData>*
137 hilPhasesManager;
138};
139
150template <class FlightPhases, class SimulatorData, class ActuatorData>
151void HILTransceiver<FlightPhases, SimulatorData, ActuatorData>::run()
152{
153 LOG_INFO(logger, "HIL Transceiver started");
154 hilSerial.clearQueue();
155
156 miosix::led2On();
157 hilSerial.write(&actuatorData, sizeof(ActuatorData));
158 miosix::led2Off();
159
160 while (!shouldStop())
161 {
162 // Pausing the kernel in order to copy the data in the shared structure
163 {
164 SimulatorData tempData;
165 nLostUpdates = 0;
166 miosix::led3On();
167 size_t nRead = 0;
168 if (!hilSerial.readBlocking(&tempData, sizeof(SimulatorData),
169 nRead))
170 {
171 LOG_ERR(logger, "Failed serial read");
172 }
173
174 assert(nRead == sizeof(SimulatorData) &&
175 "Read less then SimulatorData bytes");
176
177 hilSerial.clearQueue();
178 miosix::led3Off();
179
180 miosix::PauseKernelLock kLock;
181 simulatorData = tempData;
182 timestampSimulatorData = miosix::getTime();
183 }
184
185 // If this is the first packet to be received, then update the flight
186 // phase manager
187 if (!receivedFirstPacket)
188 {
189 receivedFirstPacket = true;
190 hilPhasesManager->simulationStarted();
191 }
192
193 // Trigger events relative to the flight phases
194 hilPhasesManager->processFlags(simulatorData);
195
196 if (nLostUpdates > 0)
197 {
198 // This means also that the number of samples used for the mean sent
199 // to the HIL simulator is made up of more than the number of
200 // samples we though
201 LOG_WARN(logger, "%d Lost updates", nLostUpdates);
202 }
203
204 waitActuatorData();
205 miosix::led2On();
206 hilSerial.write(&actuatorData, sizeof(ActuatorData));
207 miosix::led2Off();
208 }
209}
210} // namespace Boardcore
#define LOG_WARN(logger,...)
#define LOG_INFO(logger,...)
#define LOG_ERR(logger,...)
Singleton object that manages all the phases of the simulation. After his instantiation we need to se...
miosix::ConditionVariable condVar
void waitActuatorData()
Waits for the control algorithm(s) to update actuatorData.
int getLostUpdates() const
Returns the number of lost updates.
HILTransceiverBase(USART &hilSerial)
Construct a serial connection attached to a control algorithm.
int64_t getTimestampSimulatorData() const
Returns the value in ns of the timestamp of the last received simulatorData.
HILTransceiver is a Singleton and provides an easy interface for the control algorithms to send and r...
HILTransceiver(USART &hilSerial, HILPhasesManager< FlightPhases, SimulatorData, ActuatorData > *hilPhasesManager)
Construct a serial connection attached to a control algorithm.
const SimulatorData * getSensorData() const
returns the reference of the SimulatorData
void setActuatorData(ActuatorData actuatorData)
sets the actuator data and then wakes up the MatlabTransceiver thread in order to send the data back ...
static PrintLogger getLogger(const string &name)
Driver for STM32F4 low level USART/UART peripheral.
Definition USART.h:170
This file includes all the types the logdecoder script will decode.