Skyward boardcore
Loading...
Searching...
No Matches
AirBrakesInterp.cpp
Go to the documentation of this file.
1/* Copyright (c) 2021-2022 Skyward Experimental Rocketry
2 * Authors: Vincenzo Santomarco, Alberto Nidasio, 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#include "AirBrakesInterp.h"
24
25#include <logger/Logger.h>
26#include <utils/Constants.h>
27
28#include <limits>
29
31#include "utils/Debug.h"
32
33namespace Boardcore
34{
35
37 std::function<TimedTrajectoryPoint()> getCurrentPosition,
38 const TrajectorySet& trajectoryOpenSet,
39 const TrajectorySet& trajectoryCloseSet,
40 const AirBrakesInterpConfig& configInterp,
41 std::function<void(float)> setActuator)
42 : getCurrentPosition(getCurrentPosition), setActuator(setActuator),
43 trajectoryOpenSet(trajectoryOpenSet),
44 trajectoryCloseSet(trajectoryCloseSet), configInterp(configInterp)
45{
46}
47
48bool AirBrakesInterp::init() { return true; }
49
50void AirBrakesInterp::begin(float currentMass)
51{
52 if (running)
53 return;
54
55 // Choose the best trajectories depending on the mass and the delta mass
56 if (configInterp.DM == 0)
57 {
58 // Compatibility in case the mass information is not provided
59 choosenOpenTrajectory = &trajectoryOpenSet.trajectories[0];
60 choosenCloseTrajectory = &trajectoryCloseSet.trajectories[0];
61 }
62 else
63 {
64 int index =
65 round((currentMass - configInterp.INITIAL_MASS) / configInterp.DM);
66
67 // Bound the index in order to have an indexable element
68 index = std::max(index, 0);
69 uint32_t boundedIndex = std::min(static_cast<uint32_t>(index),
70 trajectoryOpenSet.length() - 1);
71
72 choosenOpenTrajectory = &trajectoryOpenSet.trajectories[boundedIndex];
73 choosenCloseTrajectory = &trajectoryCloseSet.trajectories[boundedIndex];
74 }
75
77}
78
79void AirBrakesInterp::step()
80{
81 auto currentPosition = getCurrentPosition();
82
83 // Do nothing if we have no new data
84 if (lastPosition.timestamp >= currentPosition.timestamp)
85 return;
86
87 lastPosition = currentPosition;
88
89 // Interpolation
90 float percentage = controlInterp(currentPosition);
91
92 // Filtering
93 float filterCoeff = 0;
94
95 // If the altitude is lower than the minimum one, the filter is kept at the
96 // same value, to avoid misleading filtering actions
97 if (currentPosition.z < configInterp.FILTER_MINIMUM_ALTITUDE)
98 {
99 filterCoeff = configInterp.STARTING_FILTER_VALUE;
100 }
101 else
102 {
103 filterCoeff =
104 configInterp.STARTING_FILTER_VALUE -
105 (currentPosition.z - configInterp.FILTER_MINIMUM_ALTITUDE) *
106 ((configInterp.STARTING_FILTER_VALUE) /
107 (configInterp.FILTER_MAXIMUM_ALTITUDE -
108 configInterp.FILTER_MINIMUM_ALTITUDE));
109 }
110
111 if (currentPosition.z < configInterp.ABK_CRITICAL_ALTITUDE)
112 {
113 // Compute the actual value filtered
114 percentage =
115 lastPercentage + (percentage - lastPercentage) * filterCoeff;
116 }
117 else
118 {
119 // If the height is beyond the target one, the algorithm tries to brake
120 // as much as possible
121 percentage = 1;
122 }
123
124 lastPercentage = percentage;
125 setActuator(percentage);
126}
127
128float AirBrakesInterp::controlInterp(TrajectoryPoint currentPosition)
129{
130 // we take the index of the current point of the trajectory and we look
131 // ahead of N points
132 int index_z =
133 floor((currentPosition.z / configInterp.DZ)) + configInterp.N_FORWARD;
134
135 index_z = std::max(index_z, 0);
136
137 // for safety we check whether the index exceeds the maximum index of the
138 // trajectory sets
139 index_z = std::min(index_z, std::min(choosenCloseTrajectory->trjSize - 1,
140 choosenOpenTrajectory->trjSize - 1));
141
142 Boardcore::TrajectoryPoint trjPointClosed =
143 choosenCloseTrajectory->points[index_z];
144 Boardcore::TrajectoryPoint trjPointOpen =
145 choosenOpenTrajectory->points[index_z];
146
147 // TRACE("z: %+.3f, curr: %+.3f, clos: %+.3f, open: %+.3f\n",
148 // currentPosition.z, currentPosition.vz, trjPointClosed.vz,
149 // trjPointOpen.vz);
150
151 if (currentPosition.vz <= trjPointClosed.vz)
152 {
153 return 0;
154 }
155 else if (currentPosition.vz >= trjPointOpen.vz)
156 {
157 return 1;
158 }
159 else
160 {
161 return (currentPosition.vz - trjPointClosed.vz) /
162 (trjPointOpen.vz - trjPointClosed.vz);
163 }
164}
165
166} // namespace Boardcore
bool init() override
Initializes the Algorithm object, must be called as soon as the object is created.
AirBrakesInterp(std::function< TimedTrajectoryPoint()> getCurrentPosition, const TrajectorySet &trajectoryOpenSet, const TrajectorySet &trajectoryCloseSet, const AirBrakesInterpConfig &configInterp, std::function< void(float)> setActuator)
void begin()
Starts the execution of the algorithm and set the running flag to true.
Definition Algorithm.h:42
std::atomic< bool > running
Definition Algorithm.h:68
Trajectory point with timestamp and velocity module.
TrajectoryPoint * points
Definition Trajectory.h:34
float vz
Vertical velocity [m/s].
uint32_t length() const
This file includes all the types the logdecoder script will decode.