rusefi-1/firmware/util/math/pid.h

111 lines
2.8 KiB
C
Raw Normal View History

2015-07-10 06:01:56 -07:00
/**
* @file pid.h
*
* @date Sep 16, 2014
2017-01-03 03:05:22 -08:00
* @author Andrey Belomutskiy, (c) 2012-2017
2015-07-10 06:01:56 -07:00
*/
#ifndef PID_H_
#define PID_H_
2018-09-16 19:26:57 -07:00
#include "global.h"
2016-01-20 20:03:03 -08:00
#include "engine_configuration_generated_structures.h"
2019-08-15 18:01:04 -07:00
#include "engine_state_generated.h"
2017-05-25 05:49:04 -07:00
2016-02-06 09:02:24 -08:00
#if EFI_PROD_CODE || EFI_SIMULATOR
#include "tunerstudio_configuration.h"
#endif
2016-01-20 20:03:03 -08:00
2017-12-24 18:17:10 -08:00
// See PidCic below
#define PID_AVG_BUF_SIZE_SHIFT 5
#define PID_AVG_BUF_SIZE (1<<PID_AVG_BUF_SIZE_SHIFT) // 32*sizeof(float)
2019-04-25 18:31:33 -07:00
#define NOT_TIME_BASED_PID 1
2019-04-25 15:49:16 -07:00
// minimal period 5m meaning maximum control frequency 200Hz
#define PID_MINIMAL_PERIOD_MS 5
#define GET_PERIOD_LIMITED(pid_s_ptr) maxI(PID_MINIMAL_PERIOD_MS, ((pid_s_ptr)->periodMs))
#define MS2SEC(x) (x * 0.001)
2019-08-15 18:01:04 -07:00
class Pid : public pid_state_s {
2015-07-10 06:01:56 -07:00
public:
2016-02-06 09:02:24 -08:00
Pid();
explicit Pid(pid_s *pid);
2018-07-29 13:30:23 -07:00
void initPidClass(pid_s *pid);
bool isSame(pid_s *pid) const;
2016-02-06 09:02:24 -08:00
/**
2019-07-21 14:05:41 -07:00
* This version of the method takes dTime from pid_s
2019-04-25 18:36:41 -07:00
*
* @param Controller input / process output
* @returns Output from the PID controller / the input to the process
*/
float getOutput(float target, float input);
virtual float getOutput(float target, float input, float dTime);
2017-12-24 18:17:10 -08:00
// doesn't limit the result (used in incremental CIC PID, see below)
float getUnclampedOutput(float target, float input, float dTime);
2015-07-10 06:01:56 -07:00
void updateFactors(float pFactor, float iFactor, float dFactor);
2017-12-24 18:17:10 -08:00
virtual void reset(void);
float getP(void) const;
float getI(void) const;
float getD(void) const;
float getOffset(void) const;
float getIntegration(void) const;
float getPrevError(void) const;
void setErrorAmplification(float coef);
2019-04-12 19:10:57 -07:00
#if EFI_TUNER_STUDIO
2016-02-06 09:02:24 -08:00
void postState(TunerStudioOutputChannels *tsOutputChannels);
2017-07-23 09:12:35 -07:00
void postState(TunerStudioOutputChannels *tsOutputChannels, int pMult);
2018-11-16 05:08:20 -08:00
#endif /* EFI_TUNER_STUDIO */
2015-07-10 06:01:56 -07:00
float minResult;
float maxResult;
2017-05-29 20:15:07 -07:00
void showPidStatus(Logging *logging, const char*msg);
2017-05-28 19:10:35 -07:00
void sleep();
2017-06-02 18:34:00 -07:00
int resetCounter;
2019-03-02 11:00:32 -08:00
// todo: move this to pid_s one day
float iTermMin = -1000000.0;
float iTermMax = 1000000.0;
2017-04-10 12:16:00 -07:00
private:
pid_s *pid;
2015-07-10 06:01:56 -07:00
float previousError;
2019-08-30 14:11:12 -07:00
2017-12-24 18:17:10 -08:00
private:
virtual void updateITerm(float value);
};
/**
2019-04-25 21:45:53 -07:00
* A PID implementation with a modified cascaded integrator-comb (CIC) filtering.
2017-12-24 18:17:10 -08:00
* Used for incremental auto-IAC control. See autoIdle() in idle_thread.cpp
2017-12-24 18:26:42 -08:00
*
* https://rusefi.com/forum/viewtopic.php?f=9&t=1315
2017-12-24 18:17:10 -08:00
*/
class PidCic : public Pid {
public:
PidCic();
explicit PidCic(pid_s *pid);
2017-12-24 18:17:10 -08:00
void reset(void) override;
2019-04-25 21:45:53 -07:00
using Pid::getOutput;
float getOutput(float target, float input, float dTime) override;
2017-12-24 18:17:10 -08:00
private:
// Circular running-average buffer for I-term, used by CIC-like filter
float iTermBuf[PID_AVG_BUF_SIZE];
// Needed by averaging (smoothing) of iTerm sums
float iTermInvNum;
// Total PID iterations (>240 days max. for 10ms update period)
int totalItermCnt;
private:
void updateITerm(float value) override;
2015-07-10 06:01:56 -07:00
};
#endif /* PID_H_ */