42 std::function<
void(
float)> setActuator)
43 : getCurrentPosition(getCurrentPosition), config(config),
44 setActuator(setActuator), pi(config.KP, config.KI, config.TS),
45 trajectorySet(trajectorySet)
56 lastPosition = getCurrentPosition();
57 chooseTrajectory(lastPosition);
63 auto currentPosition = getCurrentPosition();
66 if (lastPosition.
timestamp >= currentPosition.timestamp)
69 lastPosition = currentPosition;
71 auto setPoint = getSetpoint(currentPosition);
72 float rho = getRho(currentPosition.z);
74 float targetDrag = piStep(currentPosition, setPoint, rho);
75 float surface = getSurface(currentPosition, rho, targetDrag);
76 setActuator(surface / config.
SURFACE);
79float AirBrakesPI::getRho(
float z)
81 return Constants::RHO_0 * expf(-z / Constants::Hn);
84float AirBrakesPI::getSurface(
const TimedTrajectoryPoint& currentPosition,
85 float rho,
float targetDrag)
87 float bestDDrag = numeric_limits<float>::infinity();
88 float bestSurface = 0;
95 float extension = getExtension(surface);
96 float cd = getCD(currentPosition, extension);
97 float drag = getDrag(currentPosition, cd, rho);
98 float dDrag = abs(targetDrag - drag);
100 if (dDrag < bestDDrag)
103 bestSurface = surface;
110float AirBrakesPI::getExtension(
float surface)
121float AirBrakesPI::getCD(TimedTrajectoryPoint currentPosition,
float extension)
123 const float mach1 = currentPosition.getMac();
124 const float mach2 = powf(mach1, 2);
125 const float mach3 = powf(mach1, 3);
126 const float mach4 = powf(mach1, 4);
127 const float mach5 = powf(mach1, 5);
128 const float mach6 = powf(mach1, 6);
130 const float extension2 = powf(extension, 2);
135 config.
N100 * mach1 +
136 config.
N200 * mach2 +
137 config.
N300 * mach3 +
138 config.
N400 * mach4 +
139 config.
N500 * mach5 +
140 config.
N600 * mach6 +
141 config.
N010 * extension +
142 config.
N020 * extension2 +
143 config.
N110 * extension * mach1 +
144 config.
N120 * extension2 * mach1 +
145 config.
N210 * extension * mach2 +
146 config.
N220 * extension2 * mach2 +
147 config.
N310 * extension * mach3 +
148 config.
N320 * extension2 * mach3 +
149 config.
N410 * extension * mach4 +
150 config.
N420 * extension2 * mach4 +
151 config.
N510 * extension * mach5 +
152 config.
N520 * extension2 * mach5 +
153 config.
N001 * currentPosition.z;
157float AirBrakesPI::getDrag(TimedTrajectoryPoint currentPosition,
float cd,
160 return 0.5 * rho * config.
S0 * cd * currentPosition.vz *
161 currentPosition.vMod;
164void AirBrakesPI::chooseTrajectory(TrajectoryPoint currentPosition)
166 float minDistance = numeric_limits<float>::infinity();
167 uint8_t trjIndexMin = trajectorySet.
length() / 2;
169 for (uint8_t trjIndex = 0; trjIndex < trajectorySet.
length(); trjIndex++)
171 Trajectory& trajectory = trajectorySet.
trajectories[trjIndex];
173 for (uint32_t ptIndex = 0; ptIndex < trajectory.size(); ptIndex++)
175 TrajectoryPoint point = trajectory.
points[ptIndex];
179 if (distance < minDistance)
181 minDistance = distance;
182 trjIndexMin = trjIndex;
183 lastSelectedPointIndex = ptIndex;
184 chosenTrajectory = &trajectory;
189 chosenTrajectory = &(trajectorySet.
trajectories[trjIndexMin]);
192TrajectoryPoint AirBrakesPI::getSetpoint(TrajectoryPoint currentPosition)
194 if (chosenTrajectory ==
nullptr)
197 float minDistance = numeric_limits<float>::infinity();
199 uint32_t
end = chosenTrajectory->
size();
200 for (uint32_t ptIndex = lastSelectedPointIndex; ptIndex <
end; ptIndex++)
202 float distanceFromCurrentInput =
203 abs(chosenTrajectory->
points[ptIndex].
z - currentPosition.z);
205 if (distanceFromCurrentInput < minDistance)
207 minDistance = distanceFromCurrentInput;
208 lastSelectedPointIndex = ptIndex;
212 return chosenTrajectory->
points[lastSelectedPointIndex];
215float AirBrakesPI::piStep(TimedTrajectoryPoint currentPosition,
216 TrajectoryPoint setPoint,
float rho)
218 const float cdMin = getCD(currentPosition, 0);
219 const float dragMin = getDrag(currentPosition, cdMin, rho);
221 const float cdMax = getCD(currentPosition, config.
EXTENSION);
222 const float dragMax = getDrag(currentPosition, cdMax, rho);
225 const float cdRef = getCD(currentPosition, chosenTrajectory->
extension);
226 const float dragRef = getDrag(currentPosition, cdRef, rho);
229 const float error = currentPosition.vz - setPoint.vz;
void begin()
This method chooses the trajectory the rocket will follow and starts the algorithm.
bool init() override
Initializes the Algorithm object, must be called as soon as the object is created.
void step() override
Looks for nearest point in the current chosen trajectory and moves the airbraks according to the curr...
AirBrakesPI(std::function< TimedTrajectoryPoint()> getCurrentPosition, const TrajectorySet &trajectorySet, const AirBrakesPIConfig &config, std::function< void(float)> setActuator)
void begin()
Starts the execution of the algorithm and set the running flag to true.
void end()
Terminates the algorithm's execution and sets the running flag to false.
std::atomic< bool > running
float antiWindUp(float u)
float update(float error)
Update the PI internal state.
Trajectory point with timestamp and velocity module.
float extension
AirBrakes target extension for this trajectory [m].
float z
Vertical position [m].
static float distanceSquared(TrajectoryPoint a, TrajectoryPoint b)
Returns the distance squared between the two points.
Trajectory * trajectories
This file includes all the types the logdecoder script will decode.
float S0
Rocket surface [m^2].
float SURFACE
AirBrakes max surface [m^2].