V8 Release Work Thread

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
36,350
Reaction score
845
Points
203
Location
Langendernbach
Could you elaborate a bit on what you mean by this?

Like, since the checklists essentially formulate already from the "user perspective", what the spacecraft should do, run an automated test process over the add-on by executing a checklist and comparing the results to the quantities that should be noted or observed according to this checklist.

This is a different perspective as unit tests, which test individual units of code or subsystems.

For example, when you change something in NASSP, without correcting the checklists, you would find it by the test failing. If you run a new mission, the test should fail, if the checklists have assumptions that are not according to the mission conditions.

It would not be a fast test, that you could run in a build pipeline, but you could run multiple such tests over a weekend, if each test just covers maybe a sequence of maximal one hour flight. And since it is automated, it would complain ever for minor issues that are wrong with the test, instead of being wrong with the add-on. And much more great: The test artifacts are also release artifacts, since you need correct checklists as well there.
 

indy91

Addon Developer
Addon Developer
Joined
Oct 26, 2011
Messages
994
Reaction score
288
Points
78
The big missing piece of the Checklist MFD for that would be an automated check of the simulation state. At the moment the checklist controller only has access to panel elements. It can check if switches are in the right position, but it can't access e.g. if the voltage on main bus A is right. The checklist can only tell the user to do that check.

I think the more interesting application of automatically running checklists is to automate all tasks of one crewmember, like the CMP who is alone in the CSM, while the NASSP user can focus on flying the LM. I don't think this needs much to be automated, but isn't really possible right now.
 

sw34669

Active member
Joined
Dec 16, 2020
Messages
202
Reaction score
29
Points
28
Location
uk
It's not far away from this . Although, as Urwumpe suggested, regression testing of the state would be handy, before any major planned man. happens, a circ breakers and switch position run is done for most positions. This should catch any "fingerpokin" by the user from whatever scenario they loaded or that accidental click on something, when you sneeze. Oh shit, what did I just click on that panel with many switches.

The automatic switch function, although a bit slow, is good for long boring switch flipping whilst you are in the other craft. It works on both of course I sometimes use it.

The degree level maths bit comes when those yellow user interaction lines appear in the checklist. Usually, this is something from a pad, but, it can be something you need to tgo read about or fieddle with.

My request would be, when using the automatic switch flipping, can we have this a little faster ?
 

indy91

Addon Developer
Addon Developer
Joined
Oct 26, 2011
Messages
994
Reaction score
288
Points
78
I've implemented a new way to simulate short impulses from the LM RCS. This will hopefully improve automatic attitude control with the ascent stage. Here is why we needed a better system.

The Problem:

The minimum allowed duration of a CSM or LM RCS thruster firing is 13 milliseconds. That is the duration from the electrical on signal to the electrical off signal. Here is the figure about this from the LM AOH:

xAasfHe.png


As you can see, there is a delay before any thrust is actually happening. The off signal is already present before any significant thrust even developed. And there also is delay until the thrust is going down again. The maximum thrust of the RCS is 100 lbf, so in this minimum impulse firing it never reaches that. So a very small total impulse is generated by such a short pulse.

With 13ms being the absolute minimum, the DAP of the AGC has a built in limit of 14ms. That is the shortest duration the AGC will command an RCS thruster on. It will only do so if very fine attitude control is required, which is usually the case for the LM ascent stage. It can happen for other cases, descent stage and even in the CSM, but almost every RCS firing for attitude control of the ascent stage will be commanded for 14ms.

Now, most people, I think, will run NASSP with 60fps. That is my preferred display setting, VSync with 60fps. CSM main panel has problems sometimes reaching that for me, but in the LM it works fine. With a stable frame rate this means that one timestep is 16.666 milliseconds long. The problem is apparent. There is no way the simulation can resolve a minimum impulse RCS firing like this if that firing is already shorter than one timestep. So in a simple simulation, where the thrusters are just set on and off to 100% thrust as the AGC commands it, the thruster will usually be on for one timestep. In the worst case, because the AGC is doing all its computer cycles for one timestep at once, the thruster on and off signals can happen on the same timestep. It's a game of chance basically, in about 84% of the cases the thruster will be on for one timestep, in 16% of the cases it will never be on (all this for 60fps of course). This is how the CMC minimum impulse mode is currently working. This will need some improvements eventually as well, but right now I am only talking about the LGC.

The Old Solution:

NASSP has had a solution for this for a long time. It tries to simulate the thrust rise phase, the steady state phase and the thrust decay phase. In the process of working on this I discovered this has some bugs and isn't actually working as intended. Here is a figure with both the intended and the actual behavior we are currently having in NASSP:

yCH2KBb.gif


This covers the case where a timestep was commanded on for one timestep, 1/60 seconds long.

This is still a game of chance for the thrust that is actually generated. Usually what happens is that no thrust is generated during the timestep the thruster was commanded on. The next timestep will have 100% thrust and there is a random chance that a third timestep has 100% or 0% thrust, depending on the actual framelength (slightly below 60fps for example). This solution (partially due to the bugs) eliminates the cases where the thruster isn't fired at all, because it delays the thruster off signal sufficiently. So it's better than the most simple solution. But it generates a much larger total impulse than desired and intended by the DAP with its 14ms on signal. The main effect is, the DAP wastes a lot of propellant in attitude hold, especially with the light ascent stage after insertion. It really isn't able to keep the ascent stage completely steady.

The New Solution:

I've tried a bunch of ways like averaging the thrust value of the curve from the LM AOH and use that as the thrust value over the next timestep. But the idea that has proven successful for me is prediciting the impulse (instead of thrust) that the thruster should generate over the next timestep and divide that by the step length to get a thrust value. For this I got rid of the thrust rise and decay phases, as that would complicate the logic quite a bit. Instead I used simple step delays, the same values that the MIT hybrid simulator of the Lunar Module was using. With that it takes 19ms from thruster on signal to a thrust step from 0% to 100%. And it takes 15ms from thruster off signal to the step down from 100% to 0% thrust.

The solution predicting the impulse is basically the integral version of this step delay logic. It takes the current time from engine on, the current time from engine off (if that has already been commanded) and the current simulation step length to predict what should happen over the next timestep, so what the impulse is that is being generated over that step, and then calculates thrust = impulse/steplength for the next timestep. If both thruster on and off have been commanded on the same timestep it delays the off signal by 13ms and uses that in the impulse calculation. The simplest case is of course: thruster on for more than 19ms already and no thruster off signal present yet. In this case no impulse calculation is necessary, the logic just sets the thrust level to 1.

A very typical case for a minimum impulse firing looks like this in my debug log:

Start 448238.6676 1
Stop 448238.6842 1
448238.6842 1 0.760387

This is thruster no. 1, commanded on at 448238.6676, off at 448238.6842 (both mission time), actual thrust level applied is 0.760387 during the timestep starting at 448238.6842. Because of the on delay a thrust is applied during the same timestep as the off command. And that thrust level is consistent with the duration of the thruster on signal. 16.6ms between on and off command, and there is a 4ms difference in the on and off delays (19 vs 15ms). So the thruster should be on for 12.4ms. 12.4/16.6 roughly gives that 0.760387 thrust level used for that one timestep.

This leads to much improved attitude hold behavior of light ascent stages, as the RCS is able to provide much finer impulses than before. The main disadvantage of this approach is that it doesn't really fix the delay from the LGC sending a command to that command actually being processed. So this gives the realistic amount of impulse of a 16.6ms firing, and not 14ms like the LGC wanted to. And in other cases, where on and off have been commanded at the same timestep, this gives the realistic amount of impulse for a 13ms firing. So this approach works even when you don't quite get the 60 frames per second. Time acceleration however is still not something I can recommend trying with the DAP in control, due to that remaining delay in processing the thruster command.

So the behavior is definitely a lot more consistent than before, even if it still doesn't provide exactly the right amount of impulse the LGC wanted. That could only be solved by adding some logic to the loop that does the LGC computer cycles. It would basically have to check if the LGC commands a thruster on or off, then save the exact time that happened (not the current Orbiter simulation time) and use that for the RCS. But that seems quite excessive. And of course as I wrote earlier, another possible improvement would be to simulate thrust rise and decay again. But this makes it quite complex to predict the exact impulse generated, taking into account thrust rise/decay, exact timing of the thruster off signal etc. The thrust rise looks like a quadratic function, so that becomes cubic in the impulse generated. Might make it more complicated than necessary.

Feel free to leave any thoughts about this new approach, I would be interested to hear any additional ideas or critique. Any NASSP user is of course invited to test it out and see if it improves things for you. It definitely does for me.

Thanks for reading :hailprobe:
 

sw34669

Active member
Joined
Dec 16, 2020
Messages
202
Reaction score
29
Points
28
Location
uk
> and divide that by the step length to get a thrust value .

Interesting I had wondered about this and indeed how to sync the simulation to so many old and analogue relics ! It uses a bit too much rcs prop and indeed ive just tuned the dap down after my p52. Great thinking and solution. Also very green, uses less virtual gas !

Stupid question, but, could changing this have a knock on effect to anything else in the codebase that be have been tweaked to cater for the thrust framing misalignment?
 

indy91

Addon Developer
Addon Developer
Joined
Oct 26, 2011
Messages
994
Reaction score
288
Points
78
Interesting I had wondered about this and indeed how to sync the simulation to so many old and analogue relics ! It uses a bit too much rcs prop and indeed ive just tuned the dap down after my p52. Great thinking and solution. Also very green, uses less virtual gas !

Yeah that's what I have often done, and the real missions as well sometimes. PGNS att hold, V76, and just let it drift a bit, occasionally correcting the attitude manually.
Stupid question, but, could changing this have a knock on effect to anything else in the codebase that be have been tweaked to cater for the thrust framing misalignment?

Well I hope not! I have tried as many RCS control modes as I could think of and everything seems to still work fine (or better). Even found some bugs elsewhere in that process. Hopefully no major issue comes up now that I have released this update.
 

indy91

Addon Developer
Addon Developer
Joined
Oct 26, 2011
Messages
994
Reaction score
288
Points
78
My Apollo 11 update is done.

-MCC now uses the new targeting for TLMCC and LOI maneuvers (RTCC MFD has used these for a while already). With this I could finally delete a lot of old RTCC code.
-A more correct RTCC time keeping system is now used for Apollo 11 (I previously implemented this for the MCC for Apollo 8 and 10 and the MFD uses it anyway).
-New Apollo 11 mission scenarios have been added.
-All PAD data from the MCC is now written to a file called MCCPreAdvisoryData.log in the main Orbiter folder. So if a PAD has been replaced by the next one before you could write it down, you can now look it up in this file. The file gets cleared out of old PADs when you get your first PAD in a new Orbiter session. So if you save/load and want to keep the PAD data better save them elsewhere before the next PAD comes in. The only restriction to this new feature is that you have to have PAD auto show enabled. What is even the point of disabling that, I've only done that by accident...

The MCC update for Apollo 11 breaks old scenarios, so if you are in the middle of flying Apollo 11, do not update your NASSP installation. Or use one of the new mission scenarios.
 

sw34669

Active member
Joined
Dec 16, 2020
Messages
202
Reaction score
29
Points
28
Location
uk
thank you indy, great additions, that's a chunk of work. The PAD file will help a lot. Have a gut weekend !
 

indy91

Addon Developer
Addon Developer
Joined
Oct 26, 2011
Messages
994
Reaction score
288
Points
78
The LM ascent stage has gotten a big update. It now simulates center of gravity shifts and more realistic moments of inertia. The APS now has a 1.5° cant angle to account for that. Here are some graphs. Let's begin with the moments of inertia:


So they now agree closely with the real data I took from LM-7 (from the Spacecraft Operational Data Book Volume 3). They are now somewhat lower than before, especially in roll with a light ascent stage. But that seems to be realistic. I think in terms of controlability that will somewhat negate the previous gains made by fixing some stuff in the LM RCS. And about the LM RCS, I was probably a bit too excited about that update. One case hasn't been fixed by that. Which is the PGNS switching on a thruster and then off, before that command could be processed on the next timestep. For these minimum impulse firings of 14ms that still means that you are going to loose about 16% of all commands at 60fps and more if your framerate is lower. But that has always been the case and is difficult to fix. I'll probably try some day.

Now to the even more significant change, a shifting center of gravity. Mostly caused by the weight of the astronauts the CG of the ascent stage is shifted a few inches forward of the centerline. The APS is canted at an angle of 1.5° to compensate for that, although in most cases it doesn't really point through the center of gravity until the APS propellant is nearly empty. At ignition on the lunar surface that causes a very large angular acceleration that the RCS needs to counter. This could be up to 8 degree per second squared. So yes, if no RCS is firing the moment offset caused by the APS causes a attitude rate of nearly 8°/s in pitch in just one second. Needless to say, that's a lot of RCS firing early in the ascent to handle that. Here is the mass data I used from LM-7:


On the right are the moment offsets in pitch and roll. Pitch goes from 7.7 to -0.6 at cutoff, while roll is smaller but becomes more significant during the ascent. I have flown an ascent with these mass data and logged the estimate of the DAP in the LGC of these values.


Blue is pitch, orange is roll. I cut off the graph when pitch reaches zero as I hadn't set up the logging to handle negative numbers (-0 is 77777 in octal as coming from the AGC so my conversion broke down). But you can see the same trends as in the numbers for LM-7. The LGC has an initial guess loaded before the state estimator can calculate the actual accelerations, for pitch it starts at 6.25 for Apollo 11 and you can see that it fairly quickly adjusts itself.

Now, this change makes a fairly significant difference for any APS burn. I think the powered ascent looks a lot more like the videos from the actual missions now. The LM-7 values are actually a bit on the large side (the nearly 8°/s² in pitch). So I think I'll make the CG shift mission specific so that smaller, more realistic values, and closer to the initial prediction in the LGC can be used for the other missions.
 

sw34669

Active member
Joined
Dec 16, 2020
Messages
202
Reaction score
29
Points
28
Location
uk
Outstanding work indy thanks.
Question : I looked over the rcs timing/framing mod , would it be better to run @ 100fps for better resolution. My monitor is only 60 but i do have a 3080.
Can't wait to try both of these (once i'm home from my A11 mission, currently Mcc-7 scrubbed and earth is looming large in my window :)
Not sure what to fly next, should I go for 7 or 12 ?
Schönes Wochenende.
 

indy91

Addon Developer
Addon Developer
Joined
Oct 26, 2011
Messages
994
Reaction score
288
Points
78
There is a slight advantage of running more than 60, above 71 fps (1/0.014) the simulation can resolve all minimum impulse RCS commands from the PGNS, otherwise there is a small random chance that they aren't being processed. But a stable 60 fps is all you need to properly run the LM. Even if it dips lower it still isn't too bad I would say.

Apollo 12 and later have no Checklist MFD and MCC support yet, so they are definitely more difficult to do. Apollo 7-10 all have their unique aspects that make them fun and they are well supported in NASSP. The second half of Apollo 7 is a bit boring though. They just stayed in orbit as long as possible to see when things would start breaking.
 

sw34669

Active member
Joined
Dec 16, 2020
Messages
202
Reaction score
29
Points
28
Location
uk
Funny enough, the men were the ones who started breaking.
what urine content in your drinking water would be acceptable, in % terms :)
thank god for fuel cells

i'm nearly home now but see something on the checklist MFD i've not seen before. Will the rest of the checklist pop up or was this an unfished bit of the version i'm using and, if so, can I get the new version and just cherry pick the needed checklist stuff?thx.

1615133224770.png
 

indy91

Addon Developer
Addon Developer
Joined
Oct 26, 2011
Messages
994
Reaction score
288
Points
78
I think that can happen a few times in a mission, another point would be before TLI where you can also run out of checklists to do before the next one pops up. I checked the Checklist MFD file, the entry checklist should start automatically at 192:30h.
 

sw34669

Active member
Joined
Dec 16, 2020
Messages
202
Reaction score
29
Points
28
Location
uk
thank you i will report back. Earth is looming large in my windows up here Houston :)

i've read through the flight plan and the comms for A11 re-entry can you give me a couple of lines of wisdom about what's real important/critical and what might be easy to overlook in the next final hours. I see range, rate, heat, G, descent all need to be managed. I found a vid of yours online so that was helpful but it didn't have any context of what you were keeping an eye on number and instrument wise and what steering actions you were taking to control a safe descent. TIA.
 

MrFickles

Active member
Joined
Mar 14, 2010
Messages
125
Reaction score
26
Points
43
A G&N controlled reentry is quite straightforward. Just monitor the DSKY and let the AGC fly you to the target.

Watch for 0.05g on P63 V06N64 R1. Once it senses 0.05g, the AGC will advance to P64. Watch the g build up to your GMAX, then go back down. You'll most likely see the CM roll from 180 to 0, and then back to 180 during the 'skip' portion of the entry. You may not necessarily have a P65 and P66, it depends on your range to the target.

When the AGC switches to P67 (the 'normal' part of entry):
Ensure that R1- Roll angle, corresponds with your roll on the FDAI.
Monitor R2 and R3, watch the x-range and downrange errors fluctuate down to near zero.

When the display changes to a flashing V16N67:
ELS logic to ON and ELS to auto for automatic drogue and main chutes.

Splashdown and await recovery. Congratulations! You've completed Apollo 11!

Of course, there's the EMS which I did not mention. It's used as a backup source of information like speed, range, and trajectory that's used to ensure the AGC isn't doing anything stupid. It's also used when you need to fly the entry manually.
 
Last edited:

n72.75

Addon Developer
Addon Developer
Tutorial Publisher
Donator
Joined
Mar 21, 2008
Messages
2,033
Reaction score
428
Points
98
Location
Biddeford ME
Website
www.adabsurdumpublishing.com
Well, we just merged my big upgrade to the fuel cell code today, so I owe you guys a post with a writeup and some pretty graphs :).

A little background info. The Apollo CSM is powered by 3 bacon-type fuel cells (alkaline cells), which produce energy in the form of electrical current by the oxidation of hydrogen. Each of the fuel cell power plants consists of a stack of 31 cells, connected in series. The voltage-temperature-current relationship of these cells is not a simple one, and the cells rely heavily upon maintaining the proper temperature in order to produce the desired power output and useable voltage.

The model of fuel cell performance that NASSP used before was solid, but very simple, and I have been working since roughly October on an upgrade to it.

A contour plot of this relationship is shown below:
FC1.png


The colors and contour labels show voltage at particular current-temperature relationships.

The calculation for the model is:
C++:
//coefficients for 5th order approximation of fuel cell performance, taken from:
//CSM/LM Spacecraft Operational Data Book, Volume I CSM Data Book, Part I Constraints and Performance. Figure 4.1-10
double A = 0.023951368224792 * Temp + 23.9241562583015 - cloggVoltageDrop;
double B = 0.003480859912024 * Temp - 2.19986938582928;
double C = -0.0001779207513 * Temp + 0.104916556604259;
double D = 5.0656524872309E-06 * Temp - 0.002885372247954;
double E = -6.42229870072935E-08 * Temp + 3.58599071612147E-05;
double F = 3.02098031429142E-10 * Temp - 1.66275376548748E-07;

loadResistance = 784.0 / (power_load); //<R_F>, 784 = (28.0V)^2 which is the voltage that DrawPower() expects. use this calculate the resistive load on the fuel cell

//use an iterative procedure to solve for voltage and current. Should converge in ~2-3 steps, see https://gist.github.com/n7275/46a399d648721367a2bead3a6c2ae9ff
int NumSteps = 0;
while(NumSteps < 10) //10 is an absolute maximum to prevent hangs, and really should never get much higher than ~6-7 during extream transients
{
    Volts = A + B * Amperes + C * Amperes*Amperes + D * Amperes*Amperes*Amperes + E * Amperes*Amperes*Amperes*Amperes + F * Amperes*Amperes*Amperes*Amperes*Amperes;
    Amperes = Volts / loadResistance;
    ++NumSteps;
    if ((abs(Volts - voltsLastTimestep) < 0.00001) && (abs(Amperes - ampsLastTimestep) < 0.00001))
    {
        break;
    }
    voltsLastTimestep = Volts;
    ampsLastTimestep = Amperes;
}
        
power_load = Amperes * Volts; //recalculate power_load

Something note here is is the iterative solver. The way our systems code draws power from the fuel cells/batteries/inverters is with the
C++:
void e_object::DrawPower(double watts)
function. When we pass the nominal power-draw values found in the systems handbooks, the actual power drawn may be higher or lower than what DrawPower() is asking for depending upon the voltage of its power source. Because our power source here (the fuel cells) varies in output voltage as a function of temperature and current, this becomes a more complicated problem to solve than the old fuel cell code with it's fixed 28.8V and Ohm's Law voltage-current-power relationship. For this reason an iterative solver is needed. In essence, it calculates Ohm's Law recursively, using an initial guess voltage of 31V.

This process is best illustrated by the figure below. Keep in mind that this runs entirely within one timestep, and future iteration sequences use past values as their initial guess

Solver.png




The temperature-efficiency model is a function of cell current density and is as follows:

C++:
//efficiency and heat generation
//efficiency model calculated from APOLLO TRAINING | ELECTRICAL POWER SYSTEMSTUDY GUIDE COURSE NO.A212, and referenced documents
double heat = (power_load / (0.9063642805859956 +
    -0.00040191337758397755 * power_load +
    0.0000003368939782880486 * power_load * power_load +
    -1.5580350625528442e-10 * power_load * power_load * power_load +
    3.2902028095999155e-14 * power_load * power_load * power_load * power_load +
    -2.581100488488906e-18 * power_load * power_load * power_load * power_load * power_load) - power_load)*dt; //I think this executes faster than calling pow()

When rendered and plotted, the performance map looks something like this:

FC2.png


If we take into account the energy lost to the structure/heating up incoming reactants, than the net heat output is:

FC3.png


Finally, here is a figure showing steady-state temperature of the cells, as a function of current and voltage. Because of how this is calculated it doesn't map nicely to the rectangular grid space, unfortunately, and my contour labels are a tad messed up, but it's illustrative nonetheless.

FC4.png


Reactant consumption has been improved in accuracy and is now:

C++:
#define H2RATIO 0.1119
#define O2RATIO 0.8881

// Reactant consumption
H2_flow = ((Amperes * MMASS[SUBSTANCE_H2]) / (2*FaradaysConstant)) * numCells * dt; //Faraday's 2nd law electrolysis. confirmed against CSM databook equation
O2_flow = H2_flow / H2RATIO * O2RATIO; //consume a stoichiometric amount of oxygen


How will this effect users?

Short answer: it won't other than that the gauges/telemetry will show more realistic temperature/voltage/power/current values for the fuel cells and busses.

If you're flying missions in NASSP than the only thing you need to remember is to follow your purge schedule.

Long answer: if you're doing things with the CSM EPS outside of its nominal operating power conditions than you need to pay attention to temperatures.

Here's some helpful tips for experimentation and playing with emergency, off-spec operation.
*Read the Apollo Operations Handbook and CSM Databook sections (2.6 and 4.1 respectively) on fuel cells if you plan on doing anything "off spec" ( e.g. emergency running on one cell).
*If you're operating in an [intentionally simulated] emergency power situation pay close attention to your voltage as you add and remove load.
*A hot cell produces more voltage than a cold cell so don't remove high-draw items all at once, similarly add loads slowly to colder cells, until they heat up.

This change won't break old scenarios, and you can in theory upgrade to the latest rev mid-mission, but It's probably better not to if you can stand it.

So please take it for a spin and if you find anything odd or something that doesn't make sense, let me know and I will fix it as quick as I can.

Thanks.

Matt
 

Sverige

Member
Joined
Apr 26, 2018
Messages
74
Reaction score
2
Points
23
Well, we just merged my big upgrade to the fuel cell code today, so I owe you guys a post with a writeup and some pretty graphs :).

A little background info. The Apollo CSM is powered by 3 bacon-type fuel cells (alkaline cells), which produce energy in the form of electrical current by the oxidation of hydrogen. Each of the fuel cell power plants consists of a stack of 31 cells, connected in series. The voltage-temperature-current relationship of these cells is not a simple one, and the cells rely heavily upon maintaining the proper temperature in order to produce the desired power output and useable voltage.

The model of fuel cell performance that NASSP used before was solid, but very simple, and I have been working since roughly October on an upgrade to it.

A contour plot of this relationship is shown below:
View attachment 24787

The colors and contour labels show voltage at particular current-temperature relationships.

The calculation for the model is:
C++:
//coefficients for 5th order approximation of fuel cell performance, taken from:
//CSM/LM Spacecraft Operational Data Book, Volume I CSM Data Book, Part I Constraints and Performance. Figure 4.1-10
double A = 0.023951368224792 * Temp + 23.9241562583015 - cloggVoltageDrop;
double B = 0.003480859912024 * Temp - 2.19986938582928;
double C = -0.0001779207513 * Temp + 0.104916556604259;
double D = 5.0656524872309E-06 * Temp - 0.002885372247954;
double E = -6.42229870072935E-08 * Temp + 3.58599071612147E-05;
double F = 3.02098031429142E-10 * Temp - 1.66275376548748E-07;

loadResistance = 784.0 / (power_load); //<R_F>, 784 = (28.0V)^2 which is the voltage that DrawPower() expects. use this calculate the resistive load on the fuel cell

//use an iterative procedure to solve for voltage and current. Should converge in ~2-3 steps, see https://gist.github.com/n7275/46a399d648721367a2bead3a6c2ae9ff
int NumSteps = 0;
while(NumSteps < 10) //10 is an absolute maximum to prevent hangs, and really should never get much higher than ~6-7 during extream transients
{
    Volts = A + B * Amperes + C * Amperes*Amperes + D * Amperes*Amperes*Amperes + E * Amperes*Amperes*Amperes*Amperes + F * Amperes*Amperes*Amperes*Amperes*Amperes;
    Amperes = Volts / loadResistance;
    ++NumSteps;
    if ((abs(Volts - voltsLastTimestep) < 0.00001) && (abs(Amperes - ampsLastTimestep) < 0.00001))
    {
        break;
    }
    voltsLastTimestep = Volts;
    ampsLastTimestep = Amperes;
}
       
power_load = Amperes * Volts; //recalculate power_load

Something note here is is the iterative solver. The way our systems code draws power from the fuel cells/batteries/inverters is with the
C++:
void e_object::DrawPower(double watts)
function. When we pass the nominal power-draw values found in the systems handbooks, the actual power drawn may be higher or lower than what DrawPower() is asking for depending upon the voltage of its power source. Because our power source here (the fuel cells) varies in output voltage as a function of temperature and current, this becomes a more complicated problem to solve than the old fuel cell code with it's fixed 28.8V and Ohm's Law voltage-current-power relationship. For this reason an iterative solver is needed. In essence, it calculates Ohm's Law recursively, using an initial guess voltage of 31V.

This process is best illustrated by the figure below. Keep in mind that this runs entirely within one timestep, and future iteration sequences use past values as their initial guess

View attachment 24789



The temperature-efficiency model is a function of cell current density and is as follows:

C++:
//efficiency and heat generation
//efficiency model calculated from APOLLO TRAINING | ELECTRICAL POWER SYSTEMSTUDY GUIDE COURSE NO.A212, and referenced documents
double heat = (power_load / (0.9063642805859956 +
    -0.00040191337758397755 * power_load +
    0.0000003368939782880486 * power_load * power_load +
    -1.5580350625528442e-10 * power_load * power_load * power_load +
    3.2902028095999155e-14 * power_load * power_load * power_load * power_load +
    -2.581100488488906e-18 * power_load * power_load * power_load * power_load * power_load) - power_load)*dt; //I think this executes faster than calling pow()

When rendered and plotted, the performance map looks something like this:

View attachment 24790

If we take into account the energy lost to the structure/heating up incoming reactants, than the net heat output is:

View attachment 24791

Finally, here is a figure showing steady-state temperature of the cells, as a function of current and voltage. Because of how this is calculated it doesn't map nicely to the rectangular grid space, unfortunately, and my contour labels are a tad messed up, but it's illustrative nonetheless.

View attachment 24793

Reactant consumption has been improved in accuracy and is now:

C++:
#define H2RATIO 0.1119
#define O2RATIO 0.8881

// Reactant consumption
H2_flow = ((Amperes * MMASS[SUBSTANCE_H2]) / (2*FaradaysConstant)) * numCells * dt; //Faraday's 2nd law electrolysis. confirmed against CSM databook equation
O2_flow = H2_flow / H2RATIO * O2RATIO; //consume a stoichiometric amount of oxygen


How will this effect users?

Short answer: it won't other than that the gauges/telemetry will show more realistic temperature/voltage/power/current values for the fuel cells and busses.

If you're flying missions in NASSP than the only thing you need to remember is to follow your purge schedule.

Long answer: if you're doing things with the CSM EPS outside of its nominal operating power conditions than you need to pay attention to temperatures.

Here's some helpful tips for experimentation and playing with emergency, off-spec operation.
*Read the Apollo Operations Handbook and CSM Databook sections (2.6 and 4.1 respectively) on fuel cells if you plan on doing anything "off spec" ( e.g. emergency running on one cell).
*If you're operating in an [intentionally simulated] emergency power situation pay close attention to your voltage as you add and remove load.
*A hot cell produces more voltage than a cold cell so don't remove high-draw items all at once, similarly add loads slowly to colder cells, until they heat up.

This change won't break old scenarios, and you can in theory upgrade to the latest rev mid-mission, but It's probably better not to if you can stand it.

So please take it for a spin and if you find anything odd or something that doesn't make sense, let me know and I will fix it as quick as I can.

Thanks.

Matt
Really cool! I think the simulation of the systems is an important part of the simulator. It's fun to simulate different emergencies.
 

obsoletepower

New member
Joined
Apr 25, 2021
Messages
1
Reaction score
1
Points
3
Location
Toronto, Canada
@indy91 and @n72.75 I want to say I have been using NASSP for a couple years now and it really inspired me to build my own DSKY. I apologize in advance if this has been asked before (I tried searching but could not find any posts about this) but are there any plans to have NASSP feed from an external Virtual AGC instead of the integrated one? I built my DSKY to basically utilize the (modified) methods in the PiDSKY2.py file. My alarm panel, display and keyboard all interface with the Raspberry Pi running Virtual AGC.
 
Last edited:
Top