Dive data are stored internally using integral types using
appropriately fine units (mm, mbar, mkelvin, etc.). These
are converted with functions defined in units.h for display
(m, bar, C, etc.). Usually floating points are returned by
these functions, to retain the necessary precision. There
is one exception: the to_PSI() and mbar_to_PSI() functions.
For consistency, make these functions likewise return floats.
This will be needed for the rework of the profile-axes.
The plan is to use the conversion functions to make the
axes aware of the displayed values. This in turn will be
necessary to place the ticks at sensible distances. However,
the conversions need to be precise, which is not the
case for the current to_PSI() functions.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In an effort to reduce the size of dive.h and dive.c, break out
the event related functions. Moreover event-names were handled
by the profile-code, collect that also in the new source files.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of accessing the cylinder table directly, use the get_cylinder()
function. This gives less unwieldy expressions. But more importantly,
the function does bound checking. This is crucial for now as the code
hasn't be properly audited since the change to arbitrarily sized
cylinder tables. Accesses of invalid cylinder indexes may lead to
silent data-corruption that is sometimes not even noticed by
valgrind. Returning NULL instead of an invalid pointer will make
debugging much easier.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of using fixed size arrays, use a new cylinder_table structure.
The code copies the weightsystem code, but is significantly more complex
because cylinders are such an integral part of the core.
Two functions to access the cylinders were added:
get_cylinder() and get_or_create_cylinder()
The former does a simple array access and supposes that the cylinder
exists. The latter is used by the parser(s) and if a cylinder with
the given id does not exist, cylinders up to that id are generated.
One point will make C programmers cringe: the cylinder structure is
passed by value. This is due to the way the table-macros work. A
refactoring of the table macros is planned. It has to be noted that
the size of a cylinder_t is 64 bytes, i.e. 8 long words on a 64-bit
architecture, so passing on the stack is probably not even significantly
slower than passing as reference.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The pressure data was directly accessed in fill_missing_tank_pressures().
Use the already existing functions so that the structures can be adapted
easily.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Continue with replacing pointers to struct plot_data entries
by indexes. Thus the pressure data can be kept in its own
array and can by dynamically sized.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of assigning the the lvalue of the SENSOR_PRESSURE
macro, introduce a general function to set pressure values.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The comment to populate_pressure_information() was mentioning
gas pressures that didn't exist. Remove these parts.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Replace the INTERPOLATED_PRESSURE and SENSOR_PRESSURE macros by
inline functions. Generate a common inline function that reads
a pressure value for a dynamic sensor.
Not all SENSOR_PRESSURE macros can be replaced, because the
macro is also used to set the value and C sadly doesn't know
the concept of "return reference from a function".
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
DILUENT_PRESSURE and INTERPOLATED_DILUENT_PRESSURE do not exist
anymore. No point in trying to output them.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
gaspressure.h had definitions of non-exported structs, but did
not declare the only function exported by gaspressure.c.
Therefore, move the struct definitions into gaspressure.c and
the declarations of the populate_pressure_information() function
from profile.c to gaspressures.h.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is another entry in the series to make more things
"const-clean" with the ultimate goal of merge_dive() take
const pointers.
This concerns functions taking pointers to events and
the fallout from making these const.
The somewhat debatable part of this commit might be
that get_next_event() is split in a two distinct
(const and non-const) versions with different names,
since C doesn't allow overloading. The linker should
recognize that these functions are identical and remove
one of them.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Calculate the correct cylinder pressures for rebreather dives with
bailout. Currently the cylinder pressures for a dive are calculated
assuming a single dive mode for that dive. Bailout indroduces more
than one dive mode for a single dive, i.e. transitions from
CCR or PSCR to OC and back. Currently the start and end pressures
for each cylinder are used to interpolate cylinder pressures while that
cylinder is used. However, the different gas consumption rates for
OC, PSCR and CCR are not taken into account in this interpolation
and the cylinder pressure is indicated by an averaged interpolation
accross the rebreather and OC legs of the dive. Consequently the
increased drop in cylinder pressure during OC is not shown. This
PR allows differentiation between CCR/PSCR legs of the dive and
the OC bailout segments, showing realistic interpolation that
indicate the increased rate of gas use during OC.
Signed-off-by: Willem Ferguson <willemferguson@zoology.up.ac.za>
It's already used in core/gaspressures.c where it was declared
privately, and we'll have a new user in the profile code, so just
declare it in a proper header file like it should have been.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
So the manual gas pressure case keeps showing issues, and in many ways it
really is a fairly complex thing, since it needs interpolation of the
intermediate pressures - possibly over several gas changes.
So you might have beginning and ending pressures for one cylinder, but
then use another cylinder in between.
We've historically got all the code to do this, but the big rewrite for
multiple cylinder pressures didn't get all the details right, and so
here's a few more fixes for the case that was shown by a dive by Robert
Helling. Hopefully we're approaching the old code situation, except now
with concurrent gas pressure handling support.
Reported-by: Robert Helling <helling@atdotde.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This finally handles multiple cylinder pressures, both overlapping and
consecutive, and it seems to work on the nasty cases I've thrown at it.
Want to just track five different cylinders all at once, without any
pesky gas switch events? Sure, you can do that. It will show five
different gas pressures for your five cylinders, and they will go down
as you breathe down the cylinders.
I obviously don't have any real data for that case, but I do have a test
file with five actual cylinders that all have samples over the whole
course of the dive. The end result looks messy as hell, but what did
you expect?
HOWEVER.
The only way to do this sanely was
- actually make the "struct plot_info" have all the cylinder pressures
(so no "sensor index and pressure" - every cylinder has a pressure for
every plot info entry)
This obviously makes the plot_info much bigger. We used to have
MAX_CYLINDERS be a fairly generous 8, which seems sane. The planning
code made that 8 be 20. That seems questionable. But whatever.
The good news is that the plot-info should hopefully get freed, and
only be allocated one dive at a time, so the fact that it is big and
nasty shouldn't be a scaling issue, though.
- the "populate_pressure_information()" function had to be rewritten
quite a bit. The good news is that it's actually simpler now, although
I would not go so far as to really call it simple. It's still
complicated and suble, but now it explicitly just does one cylinder at
a time.
It *used* to have this insanely complicated "keep track of the pressure
ranges for every cylinder at once". I just couldn't stand that model
and keep my sanity, so it now just tracks one cylinder at a time, and
doesn't have an array of live data, instead the caller will just call
it for each cylinder.
- get rid of some of our hackier stuff, like the code that populates the
plot_info data code with the currently selected cylinder number, and
clears out any other pressures. That obviously does *not* work when you
may not have a single primary cylinder any more.
Now, the above sounds like all good things. Yeah, it mostly is.
BUT.
There's a few big downsides from the above:
- there's no sane way to do this as a series of small changes.
The change to make the plot_info take an array of cylinder pressures
rather than the sensor+pressure model really isn't amenable to "fix up
one use at a time". When you switch over to the new data structure
model, you have to switch over to the new way of populating the
pressure ranges. The two just go hand in hand.
- Some of our code *depended* on the "sensor+pressure" model. I fixed all
the ones I could sanely fix. There was one particular case that I just
couldn't sanely fix, and I didn't care enough about it to do something
insane.
So the only _known_ breakage is the "TankItem" profile widget. That's
the bar at the bottom of the profile that shows which cylinder is in
use right now. You'd think that would be trivial to fix up, and yes it
would be - I could just use the regular model of
firstcyl = explicit_first_cylinder(dive, dc)
.. then iterate over the gas change events to see the others ..
but the problem with the "TankItem" widget is that it does its own
model, and it has thrown away the dive and the dive computer
information. It just doesn't even know. It only knows what cylinders
there are, and the plot_info. And it just used to look at the sensor
number in the plot_info, and be done with that. That number no longer
exists.
- I have tested it, and I think the code is better, but hey, it's a
fairly large patch to some of the more complex code in our code base.
That "interpolate missing pressure fields" code really isn't pretty. It
may be prettier, but..
Anyway, without further ado, here's the patch. No sign-off yet, because I
do think people should look and comment. But I think the patch is fine,
and I'll fix anythign that anybody can find, *except* for that TankItem
thing that I will refuse to touch. That class is ugly. It needs to have
access to the actual dive.
Note how it actually does remove more lines than it adds, and that's
despite added comments etc. The code really is simpler, but there may be
cases in there that need more work.
Known missing pieces that don't currently take advantage of concurrent
cylinder pressure data:
- the momentary SAC rate coloring for dives will need more work
- dive merging (but we expect to generally normally not merge dive
computers, which is the main source of sensor data)
- actually taking advantage of different sensor data from different
dive computers
But most of all: Testing. Lots and lots of testing to find all the
corner cases.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This is a very timid start at making us actually use multiple sensors
without the magical special case for just CCR oxygen tracking.
It mainly does:
- turn the "sample->sensor" index into an array of two indexes, to
match the pressures themselves.
- get rid of dive->{oxygen_cylinder_index,diluent_cylinder_index},
since a CCR dive should now simply set the sample->sensor[] indices
correctly instead.
- in a couple of places, start actually looping over the sensors rather
than special-case the O2 case (although often the small "loops" are
just unrolled, since it's just two cases.
but in many cases we still end up only covering the zero sensor case,
because the CCR O2 sensor code coverage was fairly limited.
It's entirely possible (even likely) that this migth break some existing
case: it tries to be a fairly direct ("stupid") translation of the old
code, but unlike the preparatory patch this does actually does change
some semantics.
For example, right now the git loader code assumes that if the git save
data contains a o2pressure entry, it just hardcodes the O2 sensor index
to 1.
In fact, one issue is going to simply be that our file formats do not
have that multiple sensor format, but instead had very clearly encoded
things as being the CCR O2 pressure sensor.
But this is hopefully close to usable, and I will need feedback (and
maybe test cases) from people who have existing CCR dives with pressure
data.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We currently carry two pressures around for all the samples and plot
info, but the second pressure is reserved for CCR dives as the O2
cylinder pressure.
That's kind of annoying when we *could* use it for regular sidemount
dives as the secondary pressure.
So start prepping for that instead: don't make it "pressure" and
"o2pressure", make it just be an array of two pressure values.
NOTE! This is purely mindless prepwork. It literally just does a
search-and-replace, keeping the exact same semantics, so "pressure[1]"
is still just O2 pressure.
But at some future date, we can now start using it for a second sensor
value for sidemount instead.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Not using lrint(f) when converting double/float to int
creates rounding errors.
This error was detected by TestParse::testParseDM4 failure
on Windows. It was creating rounding inconsistencies
on Linux too, see change in TestDiveDM4.xml.
Enable -Wfloat-conversion for gcc version greater than 4.9.0
Signed-off-by: Jeremie Guichard <djebrest@gmail.com>
Using gcc option "-Wfloat-conversion" is useful to catch
potential conversion errors (where lrint should be used).
rint returns double and still raises the same warning,
this is why this change updates all rint calls to lrint.
In few places, where input type is a float, corresponding
lrinf is used.
Signed-off-by: Jeremie Guichard <djebrest@gmail.com>
Having subsurface-core as a directory name really messes with
autocomplete and is obviously redundant. Simmilarly, qt-mobile caused an
autocomplete conflict and also was inconsistent with the desktop-widget
name for the directory containing the "other" UI.
And while cleaning up the resulting change in the path name for include
files, I decided to clean up those even more to make them consistent
overall.
This could have been handled in more commits, but since this requires a
make clean before the build, it seemed more sensible to do it all in one.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2016-04-04 22:33:58 -07:00
Renamed from subsurface-core/gaspressures.c (Browse further)