ヘッダ
#ifndef CRUISECONTROL_H_ #define CRUISECONTROL_H_ #include#ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct { <09>double desiredSpeed; <09>double actualSpeed; } CruiseControl_Input; typedef struct { <09>double power; } CruiseControl_Output; void CruiseControl_initialize(void); void CruiseControl_execute(const CruiseControl_Input *input, CruiseControl_Output *output); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* CRUISECONTROL_H_ */
実装
#include#include "CruiseControl.h" typedef struct { double sum[2]; uint_fast8_t sum_index; } CruiseControl_DiscreteIntegrator_Context; typedef struct { CruiseControl_DiscreteIntegrator_Context CruiseControl_DiscreteIntegrator; } CruiseControl_Context; typedef struct { double data[2]; } CruiseControl_Vector; static CruiseControl_Context CruiseControl_context; void CruiseControl_initialize(void) { /* DiscreteIntegrator */ { CruiseControl_context.CruiseControl_DiscreteIntegrator.sum_index = 0; { CruiseControl_context.CruiseControl_DiscreteIntegrator.sum[CruiseControl_context.CruiseControl_DiscreteIntegrator.sum_index] = 0.0; } } } void CruiseControl_execute(const CruiseControl_Input *input, CruiseControl_Output *output) { double CruiseControl_Sum_y; double CruiseControl_Gain_y; double CruiseControl_DiscreteIntegrator_y; int32_t CruiseControl_Constant_y; double CruiseControl_Sum2_y; double CruiseControl_Saturation_y; uint_fast8_t CruiseControl_Compare_y; double CruiseControl_Switch_y; /* * Compute outputs */ /* Sum */ { CruiseControl_Vector sum_input = { { input->desiredSpeed, input->actualSpeed } }; { CruiseControl_Sum_y = (1.0 * sum_input.data[INT32_C(0)] + -1.0 * sum_input.data[INT32_C(1)]); } } /* Gain */ { { CruiseControl_Gain_y = 0.1 * CruiseControl_Sum_y; } } /* DiscreteIntegrator */ { { CruiseControl_DiscreteIntegrator_y = CruiseControl_context.CruiseControl_DiscreteIntegrator.sum[CruiseControl_context.CruiseControl_DiscreteIntegrator.s } } /* Constant */ { { CruiseControl_Constant_y = INT32_C(0); } } /* Sum2 */ { CruiseControl_Vector sum2_input = { { CruiseControl_Gain_y, CruiseControl_DiscreteIntegrator_y } }; { CruiseControl_Sum2_y = (1.0 * sum2_input.data[INT32_C(0)] + 1.0 * sum2_input.data[INT32_C(1)]); } } /* Saturation */ { { double ifresult; if (CruiseControl_Sum2_y > 1.0) { ifresult = 1.0; } else { double ifresult2; if (CruiseControl_Sum2_y < -1.0) { ifresult2 = -1.0; } else { ifresult2 = CruiseControl_Sum2_y; } ifresult = ifresult2; } CruiseControl_Saturation_y = ifresult; } } /* Compare */ { { CruiseControl_Compare_y = CruiseControl_Sum2_y == CruiseControl_Saturation_y; } } /* Power */ { output->power = CruiseControl_Saturation_y; } /* Switch */ { { double ifresult; if (CruiseControl_Compare_y) { ifresult = CruiseControl_Sum_y; } else { ifresult = ((double) (CruiseControl_Constant_y)); } CruiseControl_Switch_y = ifresult; } } /* * Update states */ /* DiscreteIntegrator */ { { CruiseControl_context.CruiseControl_DiscreteIntegrator.sum[(CruiseControl_context.CruiseControl_DiscreteIntegrator.sum_index + 1) % 2] = CruiseControl_c } CruiseControl_context.CruiseControl_DiscreteIntegrator.sum_index = (CruiseControl_context.CruiseControl_DiscreteIntegrator.sum_index + 1) % 2; } }