HPFP control strategy
Posted: Thu Nov 04, 2021 12:08 am
I'd like to implement the HPFP control strategy. I pushed a first draft of what I think will work: https://github.com/rusefi/rusefi/pull/3453
It is based heavily on an existing standlone ECU control strategy, so I won't claim to have come up with it myself. I did however write all the code.
First, some background on how HPFP works. Note I am not an expert but this is what I found in my research.
There are two basic types of pumps. A solenoid pump, like the Bosch HDP5, works by having a pump be driven by lobes on a camshaft (or something similar). There is another type (used on, say, a BMW N54) but I don't know much about it other than it seems to be much more rare. I think it can be driven by the same type of ECU (for example, Motec does not have separate ECUs for the two pump types) but I'll just ignore this type for now.
For the solenoid type pump, the pump has a certain volume. You can activate the solenoid to request that the pump start pressurizing. Once it reaches a certain pressure, it is effectively self running and won't unlatch until the pump reaches the top. This means that if you are going to activate the pump, you activate it for a certain number of degrees BTDC of the lobe peak. You can't just activate it for the first x% of the lobe, it has to be the last x% of the lobe. Within this pump type there are two different solenoids - normally open (Bosch) and normally closed (Hitachi maybe?). I don't know much about the latter.
Thus activating the solenoid has two functions - replace the fuel consumed by the injectors, and add to the pressure of the rail. We can hopefully calculate the former, but it's really hard to calculate the latter (unless you model the volume of the rail).
Since the solenoid latches itself, you don't have to keep it activated for the whole lobe. You just need to activate it until it latches and then let it do the rest of the work. This means that if you don't know where the lobe top is, and you try to request 100% fuel, you might get 0% fuel if your peak is too early (HPFP falls flat very quickly), or you might get something under 100% fuel if your peak is after (HPFP trends gently down).
Also note that at least Bosch says the solenoids are peak and hold, meaning you really should be driving this using a special circuit. I don't know if you guys did that in your initial experiments; I remember reading on one post that you burned out the driver or something, maybe it was due to either latching it too long (previous paragraph) or allowing too much current (this paragraph). Of course solenoids have dead time / activation delay, so we need a table for that.
So with that out of the way....
The idea is to use the calculation of fuel volume needed by peeking at the fuel injection calculation. We can take this value and look it up in a table that represents how many degrees of the lobe equals how many CC of the pump volume. These are roughly sinusoidal, and I have used that in the past, but I have been told by people with more experience than me that you HAVE to measure the lobe. Personally, I have done both and haven't noticed a difference.
We would also like to add a PI controller on top. Besides accounting for variations in real life fuel delivery and pump rates, it is the only way to actually achieve a given pressure (without modelling the rail volume). But who wants to measure the fuel rail? That'd involve removing it from the engine and .... and I'm lazy. So PI controller it is. HOWEVER, you don't really want the PI controller to work in the degrees domain, as the lobe is nonlinear. So we want to apply the PI correction in the "% pump volume" domain, which means before the %->deg mapping we did in the previous paragraph.
This model based on fuel volume is reasonably good, but it has errors. Yes we could rely on a PI controller to fix that, but in order to reduce the work of the PI controller we add a compensation table. The compensation table is just another adder in the % domain. This table is very easy to tune (just measure the PI controller delta at various load cells and plug it into the table). Personally I am convinced that this table can give you hints on misconfiguration (are your injectors really larger than you think? is the pump volume different than you think? Maybe the lobe peak angle isn't where you think, or maybe the lobe profile isn't what you think) and would like to investigate adding something to analyze the table and suggest changes to other settings, but if you "just want it to run" this table lets you do that very easily.
The code as submitted tries to capture all these factors. It is untested as I didn't want to write a bunch of tests only to be told that a) someone else already did it, or b) you don't like the algorithm, so I figured I'd put it out there for comment. And I do want to review another ECU or two to see if there are more ideas out there - I think Motec has or allows tables for some of the fields that Link keeps as scalars.
It is based heavily on an existing standlone ECU control strategy, so I won't claim to have come up with it myself. I did however write all the code.
First, some background on how HPFP works. Note I am not an expert but this is what I found in my research.
There are two basic types of pumps. A solenoid pump, like the Bosch HDP5, works by having a pump be driven by lobes on a camshaft (or something similar). There is another type (used on, say, a BMW N54) but I don't know much about it other than it seems to be much more rare. I think it can be driven by the same type of ECU (for example, Motec does not have separate ECUs for the two pump types) but I'll just ignore this type for now.
For the solenoid type pump, the pump has a certain volume. You can activate the solenoid to request that the pump start pressurizing. Once it reaches a certain pressure, it is effectively self running and won't unlatch until the pump reaches the top. This means that if you are going to activate the pump, you activate it for a certain number of degrees BTDC of the lobe peak. You can't just activate it for the first x% of the lobe, it has to be the last x% of the lobe. Within this pump type there are two different solenoids - normally open (Bosch) and normally closed (Hitachi maybe?). I don't know much about the latter.
Thus activating the solenoid has two functions - replace the fuel consumed by the injectors, and add to the pressure of the rail. We can hopefully calculate the former, but it's really hard to calculate the latter (unless you model the volume of the rail).
Since the solenoid latches itself, you don't have to keep it activated for the whole lobe. You just need to activate it until it latches and then let it do the rest of the work. This means that if you don't know where the lobe top is, and you try to request 100% fuel, you might get 0% fuel if your peak is too early (HPFP falls flat very quickly), or you might get something under 100% fuel if your peak is after (HPFP trends gently down).
Also note that at least Bosch says the solenoids are peak and hold, meaning you really should be driving this using a special circuit. I don't know if you guys did that in your initial experiments; I remember reading on one post that you burned out the driver or something, maybe it was due to either latching it too long (previous paragraph) or allowing too much current (this paragraph). Of course solenoids have dead time / activation delay, so we need a table for that.
So with that out of the way....
The idea is to use the calculation of fuel volume needed by peeking at the fuel injection calculation. We can take this value and look it up in a table that represents how many degrees of the lobe equals how many CC of the pump volume. These are roughly sinusoidal, and I have used that in the past, but I have been told by people with more experience than me that you HAVE to measure the lobe. Personally, I have done both and haven't noticed a difference.
We would also like to add a PI controller on top. Besides accounting for variations in real life fuel delivery and pump rates, it is the only way to actually achieve a given pressure (without modelling the rail volume). But who wants to measure the fuel rail? That'd involve removing it from the engine and .... and I'm lazy. So PI controller it is. HOWEVER, you don't really want the PI controller to work in the degrees domain, as the lobe is nonlinear. So we want to apply the PI correction in the "% pump volume" domain, which means before the %->deg mapping we did in the previous paragraph.
This model based on fuel volume is reasonably good, but it has errors. Yes we could rely on a PI controller to fix that, but in order to reduce the work of the PI controller we add a compensation table. The compensation table is just another adder in the % domain. This table is very easy to tune (just measure the PI controller delta at various load cells and plug it into the table). Personally I am convinced that this table can give you hints on misconfiguration (are your injectors really larger than you think? is the pump volume different than you think? Maybe the lobe peak angle isn't where you think, or maybe the lobe profile isn't what you think) and would like to investigate adding something to analyze the table and suggest changes to other settings, but if you "just want it to run" this table lets you do that very easily.
The code as submitted tries to capture all these factors. It is untested as I didn't want to write a bunch of tests only to be told that a) someone else already did it, or b) you don't like the algorithm, so I figured I'd put it out there for comment. And I do want to review another ECU or two to see if there are more ideas out there - I think Motec has or allows tables for some of the fields that Link keeps as scalars.