States are an interesting topic.
1a. Keeping track of the engine 'state' is a good idea. I have 3 states (stall, crank, run), called EngineOpMode. These are mostly used to track timers and switch crank vs run tables. Idle, run, and over-run are not separate states at all for mechanical throttle software, and are part of the ETC state for ETC software, instead of including them in the engine state. I chose to limit the number of states here because EngineOpMode is mostly used to see if the engine is running or not.
1b. For ETC I have tried two methods. In one case, I first determine which state to utilize, output the state, and then select the calculation results based on the state. For this, I have Stall, Crank, Idle, Idle-1cyl (for a 2cyl, which idles on only one), Power-On, Power-Off, and DFSO. Based on EngineOpMode, pedal value, RPM, and ECT, I select the ETC control mode ID. I also latch the last mode, and keep a timer of time since the mode was switched. This is used to handle transitions in some cases. Each mode has a block to calculate TPS, desired Phi/power enrichment, spark map to use, and a vector of which cylinders are enabled. The last-mode and timers are used to soften transitions between some states (e.g dropping a cylinder, and rewetting one cylinder at a time).
1c. The second method which I am trying now for Diesel is to calculate the requests from each mode first, and then determine the state. Each block outputs a torque request only, or a min and max request. All of the positive requests are run through a MAX block, then all of the limit requests through a MIN block, and the final torque is determined. I then back-calculate which input was used, for probes. The positive requestors I have are pedal and idle. The limiting ones are over-rev, over-speed (MPH/KPH), power curve shaping (a table to set the maximum torque vs RPM), and soot limiting (calculated from airflow). Diesel software, at least compared to ETC, is a bit simpler because the torque request is directly converted to a fuel mass request and commanded immediately, without any transient delays or compensation required for ETC and port fuel injection.
Task rates:
2. I currently have three task rates with the Woodward modules, TDC, 5ms Foreground, and 20ms Background. The first can pre-empt the other two, and the second can pre-empt the third, so the BG task may be interrupted several times if the engine is spinning fast enough. I can define tasks at multiples of the FG and BG rates, but they are just implemented as a counter which skips n iterations.
If you don't need the CPU bandwidth it's not worth messing with, or using very few rates. The system I currently work on professionally does everything at 20ms. Another system I worked on before did 1, 2, 2.5, 7, 5, 10, 20, 40, 80, 160, 320, 640, 1280, and 2560ms tasks, with different 'stuff' in each one.
Since I don't think you're having CPU load issues, you could probably have very few tasks. Probably Core Engine (5ms/once per cycle), 10ms for ETC, 50ms+ for everything else. What kind of non-engine features are you planning (cooling fan, ....)?
For your trims, can you select which table to interpolate each interval and do one of them each time (e.g. every fuel/spark calculation, run the individual cylinder calculations for one specific cylinder, so each cylinder is calculated once per 12 calculation cycles)? This way you could calculate the trims for whatever cylinder will spark next. You could also do all of the transient calculations (puddle accumulation/depletion) only for one cylinder at a time, whichever cylinder you just fueled or are about to fuel. My Woodward system won't tell me which cylinder it is on (the TDC task doesn't say which cylinder is at TDC), but I only have two cylinders to calculate worst-case so I do them both every iteration. Since you have 12, splitting them up somehow might be beneficial.
_________________ "Sometimes, the elegant implementation is a function. Not a method. Not a class. Not a framework. Just a function." ~ John Carmack
"Any sufficiently advanced technology is indistinguishable from magic" ~Arthur C. Clarke
|