foxBMS  1.4.1
The foxBMS Battery Management System API Documentation
sof_trapezoid.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2022, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file sof_trapezoid.c
44  * @author foxBMS Team
45  * @date 2020-10-07 (date of creation)
46  * @updated 2022-10-27 (date of last update)
47  * @version v1.4.1
48  * @ingroup APPLICATION_CONFIGURATION
49  * @prefix SOF
50  *
51  * @brief SOX module responsible for current derating calculation
52  *
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "sof_trapezoid.h"
57 
58 #include "battery_cell_cfg.h"
59 #include "battery_system_cfg.h"
60 
61 #include "bms.h"
62 #include "database.h"
63 #include "foxmath.h"
64 #include "state_estimation.h"
65 
66 #include <float.h>
67 
68 /*========== Macros and Definitions =========================================*/
69 
70 /*========== Static Constant and Variable Definitions =======================*/
71 /** @{
72  * module-local static variable that is calculated at startup and used later to avoid divisions at runtime
73  */
75 /** @} */
76 
77 /** local copies of database tables */
78 /**@{*/
81 /**@}*/
82 
83 /*========== Extern Constant and Variable Definitions =======================*/
84 
85 /*========== Static Function Prototypes =====================================*/
86 
87 /**
88  * @brief calculate SOF curve depending on configured configuration values
89  *
90  * @param[in] pConfigurationValues SOF curve configuration values
91  * @param[out] pCalculatedSofCurveValues calculate SOF curve
92  */
93 static void SOF_CalculateCurves(const SOF_CONFIG_s *pConfigurationValues, SOF_CURVE_s *pCalculatedSofCurveValues);
94 
95 /**
96  * @brief calculates the SoF from voltage data (i.e., minimum and maximum voltage)
97  *
98  * @param[in] minimumCellVoltage_mV minimum cell voltage
99  * @param[in] maximumCellVoltage_mV maximum cell voltage
100  * @param[out] pAllowedVoltageBasedCurrent Voltage-based SOF
101  * @param[in] pConfigLimitValues pointer to the SOF configuration structure
102  * @param[in] pCalculatedSofCurves pointer to the SOF curve structure
103  */
105  int16_t minimumCellVoltage_mV,
106  int16_t maximumCellVoltage_mV,
107  SOF_CURRENT_LIMITS_s *pAllowedVoltageBasedCurrent,
108  const SOF_CONFIG_s *pConfigLimitValues,
109  SOF_CURVE_s *pCalculatedSofCurves);
110 
111 /**
112  * @brief calculates the SoF from temperature data (i.e., minimum and maximum temperature of cells)
113  *
114  * @param[in] minimumCellTemperature_ddegC minimum temperature of cells
115  * @param[in] maximumCellTemperature_ddegC maximum temperature of cells
116  * @param[out] pAllowedTemperatureBasedCurrent pointer where to store the results
117  * @param[in] pConfigLimitValues pointer to the structure used for SOF calculation
118  * @param[in] pCalculatedSofCurves pointer to the structure containing limit values
119  */
121  int16_t minimumCellTemperature_ddegC,
122  int16_t maximumCellTemperature_ddegC,
123  SOF_CURRENT_LIMITS_s *pAllowedTemperatureBasedCurrent,
124  const SOF_CONFIG_s *pConfigLimitValues,
125  SOF_CURVE_s *pCalculatedSofCurves);
126 
127 /**
128  * @brief get the minimum current values of all variants of SoF calculation
129  *
130  * @param[in] voltageBasedLimits voltage constrained current derating values
131  * @param[in] temperatureBasedLimits temperature constrained current derating values
132  *
133  * @return minimum SoF current values
134  */
136  SOF_CURRENT_LIMITS_s voltageBasedLimits,
137  SOF_CURRENT_LIMITS_s temperatureBasedLimits);
138 
139 /*========== Static Function Implementations ================================*/
140 static void SOF_CalculateCurves(const SOF_CONFIG_s *pConfigurationValues, SOF_CURVE_s *pCalculatedSofCurveValues) {
141  FAS_ASSERT(pConfigurationValues != NULL_PTR);
142  FAS_ASSERT(pCalculatedSofCurveValues != NULL_PTR);
143 
144  /* Calculating SOF curve for the maximum allowed current for MOL/RSL/MSL */
145  pCalculatedSofCurveValues->slopeLowTemperatureDischarge =
146  (pConfigurationValues->maximumDischargeCurrent_mA - pConfigurationValues->limpHomeCurrent_mA) /
147  (pConfigurationValues->cutoffLowTemperatureDischarge_ddegC -
148  pConfigurationValues->limitLowTemperatureDischarge_ddegC);
149  pCalculatedSofCurveValues->offsetLowTemperatureDischarge =
150  pConfigurationValues->limpHomeCurrent_mA - (pCalculatedSofCurveValues->slopeLowTemperatureDischarge *
151  pConfigurationValues->limitLowTemperatureDischarge_ddegC);
152 
153  pCalculatedSofCurveValues->slopeHighTemperatureDischarge =
154  (0.0f - pConfigurationValues->maximumDischargeCurrent_mA) /
155  (pConfigurationValues->limitHighTemperatureDischarge_ddegC -
156  pConfigurationValues->cutoffHighTemperatureDischarge_ddegC);
157  pCalculatedSofCurveValues->offsetHighTemperatureDischarge =
158  0.0f - (pCalculatedSofCurveValues->slopeHighTemperatureDischarge *
159  pConfigurationValues->limitHighTemperatureDischarge_ddegC);
160 
161  pCalculatedSofCurveValues->slopeLowTemperatureCharge = (pConfigurationValues->maximumChargeCurrent_mA - 0.0f) /
162  (pConfigurationValues->cutoffLowTemperatureCharge_ddegC -
163  pConfigurationValues->limitLowTemperatureCharge_ddegC);
164  pCalculatedSofCurveValues->offsetLowTemperatureCharge =
165  0.0f -
166  (pCalculatedSofCurveValues->slopeLowTemperatureCharge * pConfigurationValues->limitLowTemperatureCharge_ddegC);
167 
168  pCalculatedSofCurveValues->slopeHighTemperatureCharge = (0.0f - pConfigurationValues->maximumChargeCurrent_mA) /
169  (pConfigurationValues->limitHighTemperatureCharge_ddegC -
170  pConfigurationValues->cutoffHighTemperatureCharge_ddegC);
171  pCalculatedSofCurveValues->offsetHighTemperatureCharge = 0.0f -
172  (pCalculatedSofCurveValues->slopeHighTemperatureCharge *
173  pConfigurationValues->limitHighTemperatureCharge_ddegC);
174 
175  pCalculatedSofCurveValues->slopeUpperCellVoltage =
176  (pConfigurationValues->maximumDischargeCurrent_mA - 0.0f) /
177  (pConfigurationValues->cutoffLowerCellVoltage_mV - pConfigurationValues->limitLowerCellVoltage_mV);
178  pCalculatedSofCurveValues->offsetUpperCellVoltage =
179  0.0f - (pCalculatedSofCurveValues->slopeUpperCellVoltage * pConfigurationValues->limitLowerCellVoltage_mV);
180 
181  pCalculatedSofCurveValues->slopeLowerCellVoltage =
182  (pConfigurationValues->maximumChargeCurrent_mA - 0.0f) /
183  (pConfigurationValues->cutoffUpperCellVoltage_mV - pConfigurationValues->limitUpperCellVoltage_mV);
184  pCalculatedSofCurveValues->offsetLowerCellVoltage =
185  0.0f - (pCalculatedSofCurveValues->slopeLowerCellVoltage * pConfigurationValues->limitLowerCellVoltage_mV);
186 }
187 
189  int16_t minimumCellVoltage_mV,
190  int16_t maximumCellVoltage_mV,
191  SOF_CURRENT_LIMITS_s *pAllowedVoltageBasedCurrent,
192  const SOF_CONFIG_s *pConfigLimitValues,
193  SOF_CURVE_s *pCalculatedSofCurves) {
194  FAS_ASSERT(pAllowedVoltageBasedCurrent != NULL_PTR);
195  FAS_ASSERT(pConfigLimitValues != NULL_PTR);
196  FAS_ASSERT(pCalculatedSofCurves != NULL_PTR);
197  /* AXIVION Routine Generic-MissingParameterAssert: minimumCellVoltage_mV: parameter accept whole range */
198  /* AXIVION Routine Generic-MissingParameterAssert: maximumCellVoltage_mV: parameter accept whole range */
199 
200  /* minimum cell voltage calculation */
201  if (minimumCellVoltage_mV <= pConfigLimitValues->limitLowerCellVoltage_mV) {
202  pAllowedVoltageBasedCurrent->continuousDischargeCurrent_mA = 0.0f;
203  pAllowedVoltageBasedCurrent->peakDischargeCurrent_mA = 0.0f;
204  } else {
205  if (minimumCellVoltage_mV <= pConfigLimitValues->cutoffLowerCellVoltage_mV) {
206  pAllowedVoltageBasedCurrent->continuousDischargeCurrent_mA =
207  (pCalculatedSofCurves->slopeUpperCellVoltage *
208  (minimumCellVoltage_mV - pConfigLimitValues->limitLowerCellVoltage_mV));
209  pAllowedVoltageBasedCurrent->peakDischargeCurrent_mA =
210  pAllowedVoltageBasedCurrent->continuousDischargeCurrent_mA;
211  } else {
212  pAllowedVoltageBasedCurrent->continuousDischargeCurrent_mA = pConfigLimitValues->maximumDischargeCurrent_mA;
213  pAllowedVoltageBasedCurrent->peakDischargeCurrent_mA = pConfigLimitValues->maximumDischargeCurrent_mA;
214  }
215  }
216  /* maximum cell voltage calculation */
217  if (maximumCellVoltage_mV >= pConfigLimitValues->limitUpperCellVoltage_mV) {
218  pAllowedVoltageBasedCurrent->continuousChargeCurrent_mA = 0.0f;
219  pAllowedVoltageBasedCurrent->peakChargeCurrent_mA = 0.0f;
220  } else {
221  if (maximumCellVoltage_mV >= pConfigLimitValues->cutoffUpperCellVoltage_mV) {
222  pAllowedVoltageBasedCurrent->continuousChargeCurrent_mA =
223  (pCalculatedSofCurves->slopeLowerCellVoltage *
224  (maximumCellVoltage_mV - pConfigLimitValues->limitUpperCellVoltage_mV));
225  pAllowedVoltageBasedCurrent->peakChargeCurrent_mA = pAllowedVoltageBasedCurrent->continuousChargeCurrent_mA;
226  } else {
227  pAllowedVoltageBasedCurrent->continuousChargeCurrent_mA = pConfigLimitValues->maximumChargeCurrent_mA;
228  pAllowedVoltageBasedCurrent->peakChargeCurrent_mA = pConfigLimitValues->maximumChargeCurrent_mA;
229  }
230  }
231 }
232 
234  int16_t minimumCellTemperature_ddegC,
235  int16_t maximumCellTemperature_ddegC,
236  SOF_CURRENT_LIMITS_s *pAllowedTemperatureBasedCurrent,
237  const SOF_CONFIG_s *pConfigLimitValues,
238  SOF_CURVE_s *pCalculatedSofCurves) {
239  FAS_ASSERT(pAllowedTemperatureBasedCurrent != NULL_PTR);
240  FAS_ASSERT(pConfigLimitValues != NULL_PTR);
241  FAS_ASSERT(pCalculatedSofCurves != NULL_PTR);
242  /* AXIVION Routine Generic-MissingParameterAssert: minimumCellTemperature_ddegC: parameter accepts whole range */
243  /* AXIVION Routine Generic-MissingParameterAssert: maximumCellTemperature_ddegC: parameter accepts whole range */
244 
245  SOF_CURRENT_LIMITS_s temporaryCurrentLimits = {0.0f, 0.0f, 0.0f, 0.0f};
246  /* Temperature low Discharge */
247  if (minimumCellTemperature_ddegC <= pConfigLimitValues->limitLowTemperatureDischarge_ddegC) {
248  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA = pConfigLimitValues->limpHomeCurrent_mA;
249  pAllowedTemperatureBasedCurrent->peakDischargeCurrent_mA = pConfigLimitValues->limpHomeCurrent_mA;
250  } else {
251  if (minimumCellTemperature_ddegC <= pConfigLimitValues->cutoffLowTemperatureDischarge_ddegC) {
252  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA =
253  (pCalculatedSofCurves->slopeLowTemperatureDischarge * minimumCellTemperature_ddegC) +
254  pCalculatedSofCurves->offsetLowTemperatureDischarge;
255  pAllowedTemperatureBasedCurrent->peakDischargeCurrent_mA =
256  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA;
257  } else {
258  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA =
259  pConfigLimitValues->maximumDischargeCurrent_mA;
260  pAllowedTemperatureBasedCurrent->peakDischargeCurrent_mA = pConfigLimitValues->maximumDischargeCurrent_mA;
261  }
262  }
263  /* Temperature low charge */
264  if (minimumCellTemperature_ddegC <= pConfigLimitValues->limitLowTemperatureCharge_ddegC) {
265  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA = 0;
266  pAllowedTemperatureBasedCurrent->peakChargeCurrent_mA = 0;
267  } else {
268  if (minimumCellTemperature_ddegC <= pConfigLimitValues->cutoffLowTemperatureCharge_ddegC) {
269  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA =
270  (pCalculatedSofCurves->slopeLowTemperatureCharge * minimumCellTemperature_ddegC) +
271  pCalculatedSofCurves->offsetLowTemperatureCharge;
272  pAllowedTemperatureBasedCurrent->peakChargeCurrent_mA =
273  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA;
274  } else {
275  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA = pConfigLimitValues->maximumChargeCurrent_mA;
276  pAllowedTemperatureBasedCurrent->peakChargeCurrent_mA = pConfigLimitValues->maximumChargeCurrent_mA;
277  }
278  }
279  /* Temperature high discharge */
280  if (maximumCellTemperature_ddegC >= pConfigLimitValues->limitHighTemperatureDischarge_ddegC) {
281  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA = 0.0f;
282  pAllowedTemperatureBasedCurrent->peakDischargeCurrent_mA = 0.0f;
283  } else {
284  if (maximumCellTemperature_ddegC >= pConfigLimitValues->cutoffHighTemperatureDischarge_ddegC) {
285  temporaryCurrentLimits.continuousDischargeCurrent_mA =
286  (pCalculatedSofCurves->slopeHighTemperatureDischarge * maximumCellTemperature_ddegC) +
287  pCalculatedSofCurves->offsetHighTemperatureDischarge;
288  temporaryCurrentLimits.peakDischargeCurrent_mA = temporaryCurrentLimits.continuousDischargeCurrent_mA;
289  } else {
290  /* do nothing because this situation is handled with minimumCellTemperature_ddegC */
291  temporaryCurrentLimits.continuousDischargeCurrent_mA = pConfigLimitValues->maximumDischargeCurrent_mA;
292  temporaryCurrentLimits.peakDischargeCurrent_mA = pConfigLimitValues->maximumDischargeCurrent_mA;
293  }
294  /* Derating value for minimum cell temperature has already been calculated and result is saved in
295  pAllowedTemperatureBasedCurrentCheck. Check now if newly calculated derating value for maximum
296  cell temperatures is smaller than the previously calculated value */
297  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA = MATH_MinimumOfTwoFloats(
298  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA,
299  temporaryCurrentLimits.continuousDischargeCurrent_mA);
300  pAllowedTemperatureBasedCurrent->peakDischargeCurrent_mA = MATH_MinimumOfTwoFloats(
301  pAllowedTemperatureBasedCurrent->peakDischargeCurrent_mA, temporaryCurrentLimits.peakDischargeCurrent_mA);
302  }
303  /* Temperature high Charge */
304  if (maximumCellTemperature_ddegC >= pConfigLimitValues->limitHighTemperatureCharge_ddegC) {
305  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA = 0.0f;
306  pAllowedTemperatureBasedCurrent->peakChargeCurrent_mA = 0.0f;
307  } else {
308  if (maximumCellTemperature_ddegC >= pConfigLimitValues->cutoffHighTemperatureCharge_ddegC) {
309  temporaryCurrentLimits.continuousChargeCurrent_mA =
310  (pCalculatedSofCurves->slopeHighTemperatureCharge * maximumCellTemperature_ddegC) +
311  pCalculatedSofCurves->offsetHighTemperatureCharge;
312  temporaryCurrentLimits.peakChargeCurrent_mA = temporaryCurrentLimits.continuousChargeCurrent_mA;
313  } else {
314  /* do nothing because this situation is handled with minimumCellTemperature_ddegC */
315  temporaryCurrentLimits.continuousChargeCurrent_mA = pConfigLimitValues->maximumChargeCurrent_mA;
316  temporaryCurrentLimits.peakChargeCurrent_mA = pConfigLimitValues->maximumChargeCurrent_mA;
317  }
318  /* Derating value for minimum cell temperature has already been calculated and result is saved in
319  pAllowedTemperatureBasedCurrentCheck. Check now if newly calculated derating value for maximum
320  cell temperatures is smaller than the previously calculated value */
321  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA = MATH_MinimumOfTwoFloats(
322  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA,
323  temporaryCurrentLimits.continuousChargeCurrent_mA);
324  pAllowedTemperatureBasedCurrent->peakChargeCurrent_mA = MATH_MinimumOfTwoFloats(
325  pAllowedTemperatureBasedCurrent->peakChargeCurrent_mA, temporaryCurrentLimits.peakChargeCurrent_mA);
326  }
327 }
328 
330  SOF_CURRENT_LIMITS_s voltageBasedLimits,
331  SOF_CURRENT_LIMITS_s temperatureBasedLimits) {
332  /* AXIVION Routine Generic-MissingParameterAssert: voltageBasedLimits: parameter accepts whole range */
333  /* AXIVION Routine Generic-MissingParameterAssert: temperatureBasedLimits: parameter accepts whole range */
334  SOF_CURRENT_LIMITS_s retval = {0};
336  voltageBasedLimits.continuousChargeCurrent_mA, temperatureBasedLimits.continuousChargeCurrent_mA);
337  retval.peakChargeCurrent_mA =
338  MATH_MinimumOfTwoFloats(voltageBasedLimits.peakChargeCurrent_mA, temperatureBasedLimits.peakChargeCurrent_mA);
340  voltageBasedLimits.continuousDischargeCurrent_mA, temperatureBasedLimits.continuousDischargeCurrent_mA);
342  voltageBasedLimits.peakDischargeCurrent_mA, temperatureBasedLimits.peakDischargeCurrent_mA);
343  return retval;
344 }
345 
346 /*========== Extern Function Implementations ================================*/
347 extern void SOF_Init(void) {
348  /* Calculating SOF curve for the recommended operating current */
350 }
351 
352 extern void SOF_Calculation(void) {
353  SOF_CURRENT_LIMITS_s allowedCurrent = {0};
354 
356 
357  /* Reset allowed current values */
362 
363  uint8_t nrClosedStrings = 0;
364  float minDischarge_mA = FLT_MAX;
365  float minCharge_mA = FLT_MAX;
366 
367  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
368  SOF_CURRENT_LIMITS_s voltageBasedSof = {0};
369  SOF_CURRENT_LIMITS_s temperatureBasedSof = {0};
370  /* Calculate allowed current if string is connected */
371  if (BMS_IsStringClosed(s) == true) {
375  &voltageBasedSof,
381  &temperatureBasedSof,
384  allowedCurrent = SOF_MinimumOfTwoSofValues(voltageBasedSof, temperatureBasedSof);
385 
388  allowedCurrent.continuousDischargeCurrent_mA;
391 
392  nrClosedStrings++;
395  }
398  }
399  } else {
404  }
405  }
406 
407  if (minCharge_mA > (float)BS_MAXIMUM_STRING_CURRENT_mA) {
408  minCharge_mA = (float)BS_MAXIMUM_STRING_CURRENT_mA;
409  }
410  if (minDischarge_mA > (float)BS_MAXIMUM_STRING_CURRENT_mA) {
411  minDischarge_mA = (float)BS_MAXIMUM_STRING_CURRENT_mA;
412  }
413 
414  /* Compute recommended pack values */
415  sof_tableSofValues.recommendedContinuousPackChargeCurrent_mA = (float)nrClosedStrings * minCharge_mA;
416  sof_tableSofValues.recommendedContinuousPackDischargeCurrent_mA = (float)nrClosedStrings * minDischarge_mA;
417  sof_tableSofValues.recommendedPeakPackChargeCurrent_mA = (float)nrClosedStrings * minCharge_mA;
418  sof_tableSofValues.recommendedPeakPackDischargeCurrent_mA = (float)nrClosedStrings * minDischarge_mA;
419 
420  /* Check if currently a transition into ERROR state in the BMS state
421  * machine is ongoing. Set allowed current to 0 if this is the case.
422  */
423  if (BMS_IsTransitionToErrorStateActive() == true) {
428  }
429 
431 }
432 
433 /*========== Externalized Static Function Implementations (Unit Test) =======*/
434 #ifdef UNITY_UNIT_TEST
435 extern void TEST_SOF_CalculateCurves(const SOF_CONFIG_s *pConfigurationValues, SOF_CURVE_s *pCalculatedSofCurveValues) {
436  SOF_CalculateCurves(pConfigurationValues, pCalculatedSofCurveValues);
437 }
438 extern void TEST_SOF_CalculateVoltageBasedCurrentLimit(
439  int16_t minimumCellVoltage_mV,
440  int16_t maximumCellVoltage_mV,
441  SOF_CURRENT_LIMITS_s *pAllowedVoltageBasedCurrent,
442  const SOF_CONFIG_s *pConfigLimitValues,
443  SOF_CURVE_s *pCalculatedSofCurves) {
445  minimumCellVoltage_mV,
446  maximumCellVoltage_mV,
447  pAllowedVoltageBasedCurrent,
448  pConfigLimitValues,
449  pCalculatedSofCurves);
450 }
451 extern void TEST_SOF_CalculateTemperatureBasedCurrentLimit(
452  int16_t minimumCellTemperature_ddegC,
453  int16_t maximumCellTemperature_ddegC,
454  SOF_CURRENT_LIMITS_s *pAllowedTemperatureBasedCurrent,
455  const SOF_CONFIG_s *pConfigLimitValues,
456  SOF_CURVE_s *pCalculatedSofCurves) {
458  minimumCellTemperature_ddegC,
459  maximumCellTemperature_ddegC,
460  pAllowedTemperatureBasedCurrent,
461  pConfigLimitValues,
462  pCalculatedSofCurves);
463 }
464 extern SOF_CURRENT_LIMITS_s TEST_SOF_MinimumOfTwoSofValues(
465  SOF_CURRENT_LIMITS_s voltageBasedLimits,
466  SOF_CURRENT_LIMITS_s temperatureBasedLimits) {
467  return SOF_MinimumOfTwoSofValues(voltageBasedLimits, temperatureBasedLimits);
468 }
469 #endif
Configuration of the battery cell (e.g., minimum and maximum cell voltage)
Configuration of the battery system (e.g., number of battery modules, battery cells,...
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
#define BS_MAXIMUM_STRING_CURRENT_mA
Maximum string current limit in mA that is used in the SOA module to check for string overcurrent.
bool BMS_IsTransitionToErrorStateActive(void)
Check if transition in to error state is active.
Definition: bms.c:1619
bool BMS_IsStringClosed(uint8_t stringNumber)
Returns string state (closed or open)
Definition: bms.c:1597
bms driver header
Database module header.
#define DATA_READ_DATA(...)
Definition: database.h:83
#define DATA_WRITE_DATA(...)
Definition: database.h:93
@ DATA_BLOCK_ID_MIN_MAX
Definition: database_cfg.h:78
@ DATA_BLOCK_ID_SOF
Definition: database_cfg.h:89
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:252
float MATH_MinimumOfTwoFloats(const float value1, const float value2)
Returns the minimum of the passed float values.
Definition: foxmath.c:134
math library for often used math functions
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:76
static void SOF_CalculateTemperatureBasedCurrentLimit(int16_t minimumCellTemperature_ddegC, int16_t maximumCellTemperature_ddegC, SOF_CURRENT_LIMITS_s *pAllowedTemperatureBasedCurrent, const SOF_CONFIG_s *pConfigLimitValues, SOF_CURVE_s *pCalculatedSofCurves)
calculates the SoF from temperature data (i.e., minimum and maximum temperature of cells)
void SOF_Calculation(void)
triggers SOF calculation
static DATA_BLOCK_SOF_s sof_tableSofValues
Definition: sof_trapezoid.c:80
static DATA_BLOCK_MIN_MAX_s sof_tableMinimumMaximumValues
Definition: sof_trapezoid.c:79
static void SOF_CalculateVoltageBasedCurrentLimit(int16_t minimumCellVoltage_mV, int16_t maximumCellVoltage_mV, SOF_CURRENT_LIMITS_s *pAllowedVoltageBasedCurrent, const SOF_CONFIG_s *pConfigLimitValues, SOF_CURVE_s *pCalculatedSofCurves)
calculates the SoF from voltage data (i.e., minimum and maximum voltage)
static void SOF_CalculateCurves(const SOF_CONFIG_s *pConfigurationValues, SOF_CURVE_s *pCalculatedSofCurveValues)
calculate SOF curve depending on configured configuration values
static SOF_CURRENT_LIMITS_s SOF_MinimumOfTwoSofValues(SOF_CURRENT_LIMITS_s voltageBasedLimits, SOF_CURRENT_LIMITS_s temperatureBasedLimits)
get the minimum current values of all variants of SoF calculation
static SOF_CURVE_s sof_curveRecommendedOperatingCurrent
Definition: sof_trapezoid.c:74
void SOF_Init(void)
initializes the area for SOF (where derating starts and is fully active).
Header for SOX module, responsible for current derating calculation.
const SOF_CONFIG_s sof_recommendedCurrent
Header for state-estimation module responsible for the estimation of state-of-charge (SOC),...
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:119
int16_t minimumTemperature_ddegC[BS_NR_OF_STRINGS]
Definition: database_cfg.h:172
int16_t maximumTemperature_ddegC[BS_NR_OF_STRINGS]
Definition: database_cfg.h:175
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:159
int16_t maximumCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:164
int16_t minimumCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:162
float recommendedPeakPackChargeCurrent_mA
Definition: database_cfg.h:416
float recommendedPeakPackDischargeCurrent_mA
Definition: database_cfg.h:417
float recommendedContinuousPackChargeCurrent_mA
Definition: database_cfg.h:414
float recommendedContinuousChargeCurrent_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:419
float recommendedContinuousPackDischargeCurrent_mA
Definition: database_cfg.h:415
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:413
float recommendedPeakDischargeCurrent_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:423
float recommendedContinuousDischargeCurrent_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:421
float recommendedPeakChargeCurrent_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:422
float maximumDischargeCurrent_mA
float maximumChargeCurrent_mA
int16_t limitLowTemperatureCharge_ddegC
int16_t limitLowerCellVoltage_mV
int16_t limitUpperCellVoltage_mV
int16_t cutoffHighTemperatureDischarge_ddegC
int16_t cutoffHighTemperatureCharge_ddegC
int16_t limitHighTemperatureCharge_ddegC
int16_t cutoffLowerCellVoltage_mV
int16_t limitHighTemperatureDischarge_ddegC
int16_t limitLowTemperatureDischarge_ddegC
int16_t cutoffLowTemperatureCharge_ddegC
int16_t cutoffLowTemperatureDischarge_ddegC
int16_t cutoffUpperCellVoltage_mV
float continuousDischargeCurrent_mA
Definition: sof_trapezoid.h:69
float continuousChargeCurrent_mA
Definition: sof_trapezoid.h:67
float offsetLowTemperatureDischarge
Definition: sof_trapezoid.h:79
float offsetHighTemperatureCharge
Definition: sof_trapezoid.h:86
float slopeHighTemperatureDischarge
Definition: sof_trapezoid.h:80
float offsetHighTemperatureDischarge
Definition: sof_trapezoid.h:81
float offsetUpperCellVoltage
Definition: sof_trapezoid.h:89
float slopeHighTemperatureCharge
Definition: sof_trapezoid.h:85
float slopeUpperCellVoltage
Definition: sof_trapezoid.h:88
float offsetLowerCellVoltage
Definition: sof_trapezoid.h:91
float slopeLowerCellVoltage
Definition: sof_trapezoid.h:90
float offsetLowTemperatureCharge
Definition: sof_trapezoid.h:84
float slopeLowTemperatureDischarge
Definition: sof_trapezoid.h:78
float slopeLowTemperatureCharge
Definition: sof_trapezoid.h:83