On Wed, Jul 4, 2012 at 8:53 AM, Jef Driesen jefdriesen@telenet.be wrote:
Now that we are discussing major api improvements, let's also have a look at the sample parsing api. The current api generates a stream of sample values, where the time value is special in the sense that it starts a new sample. I think it would be cleaner to somehow return an opaque sample, and then get all the values available for that sample. Something similar to this:
I think that would result in simpler code, yes. That said, at least for the really fundamental ones I would actually prefer to not have to see those "dc_sample_get_xyz()" calls for each.
Because we *know* that for each sample, we're going to want time, depth, temperature and cylinder pressure if available. So if we want a really convenient format, just give those directly without even asking for it (so maybe "dc_sample_t" could have them as defined members that we can just access, or maybe there would be a separate structure that contains the standard ones).
The first question is of course which sample types do we want to support? The absolute minimum to support is:
- time
- depth
- pressure
- temperature
Note that you already do "pressure" wrong, in that there doesn't seem to be any way to get the pressure samples from *multiple* cylinders in the same sample.
And no, gas-change events are not sufficient (although we can work around *some* of the limitations with them). There are literally dive computers out there that can listen to four different HP sensors at the same time, and people actually use them for more complex cases than just switching between cylinders for one diver. One dive instructor talked about tracking student air use from his dive computer using that kind of setup, for example.
So I haven't seen it personally yet, but the "there is only one pressure per sample" is not correct.
At a minimum, the pressure needs to have an index, and then for the multi-cylinder case you could generate multiple samples with the same time (but different high pressure index and values).
(And again, cylinder change events are *independent* of the HP samples: when you switch cylinders, the pressure sensor does not move with the cylinder switch. So for my own setup, for example, the HP sensor is always connected to one particular cylinder, and the pressure samples keep coming from that one even if I switch cylinders on the dive computer and start breathing from the other one. So please never try to mix up "pressure info" with "cylinder change" events, that way lies madness).
At the moment we also have:
- events: Anything that happens only at specific point in time. All other
sample types are typically measurements obtained from a sensor (or calculations based on them), with values available for each sample point (or at least every x sample points). But that is not the case for events. Typical examples are warnings, gas changes, etc. At the moment many events are supported, but the api sucks. The current plan is remove the events, use the vendor type instead (see below), and then add back support for the important events with a better api. The details of this last part are still unclear, but support for gas switches is definitely high on the list.
I wouldn't mind that. Right now subsurface takes the events pretty much the way you feed them to us (except we then generate a string for them), and quite frankly, the end result is not pretty. We have this "filter events" thing in subsurface just to get rid of the crazy ones.
For example, the Suunto Vyper Air claims to do deco diving with multiple gases, and yes, it does do the calculations for it. But the frigging thing is totally broken.
With the Suunto Vyper Air, if you have a deco gas (say 50% oxygen) that you obviously want to use at the *end* of your dive to off-gas, the f*cking idiotic dive computer will constantly complain about the fact that you are using your bottom gas (say, air) until you hit 70 ft ON THE WAY DOWN. Because the idiot computer things that since you are shallow (never mind that you are at the beginning of your dive) you should use your high-oxygen cylinder.
As a result, all my deco dives are completely *full* of the idiotic Suunto "gas change warning" events. In fact, I won't even tell my dive computer that I have nitrox in my second cylinder if I'm not actually going to do a real deco dive, because it's so annoying (not just in the logs - it's actually distracting on the dive itself, because the "you should change gas" warning will actually replace the PSI reading with the O2% reading just to try to remind me).
So the "raw events" from the dive computer are often totally useless. It would be much better to have some sane per-computer "turn this event into something useful" model that can fix things like this.
(Sure, some people may again want the raw data, so have some raw data model for those things, but I'm talking about uses like subsurface that really want the *abstraction* part of libdivecomputer that makes all computers look sane - whether they really are that or not)
- rbt: The RBT (remaining bottom time) is the time you can spend at the
current depth and still have enough gas supply to make a safe ascent. It's currently available for the Uwatec Smart/Galileo only. Other air integrated dive computers often support a similar concept, so I think we can just keep this. Maybe rename it to the less cryptic "airtime"? Note that the actual interpretation may vary between models, depending on whether factors like the safety reserve, the ascent time, decompression time, etc are taking into account or not.
I'm not convinced the rbt is all that useful in post-dive logging. The dive computers that log it do so because they already calculated it, and the log is often just basically a "this is what I'm going to display" (many dive computers that *don't* log the rbt will still log the fact that they warned about low rbt - you can often set these things to warn when they think you are getting low).
But post-dive, what's the advantage of seeing the rbt? It's kind of pointless, and it was always really just calculated to begin with (ie it has no *real* data behind it, and the dive logging software could calculate its own version using the SAC rate etc). At the time of the dive, rbt is useful as a "this is what I estimate", but *after* the dive the fact that it is just an estimate makes it kind of pointless.
And as you say, it's not well-specified to begin with, since different computers calculate the remaining time totally differently (not just in details, but in the whole "what does it mean" department).
- heartbeat: Another Uwatec Smart/Galileo feature. Although I don't know
any other model that supports a heart monitor sensor, but it doesn't cause any trouble either. So I think we can keep this one too. BTW, is the correct name heartbeat or heartrate? I think it's heartrate, expressed in beats per minute (bpm). It's a bit confusing because both have the same translation in my native language.
I would call it heartrate.
- bearing: Yet another Uwatec Smart/Galileo feature. There are several
other models that have a digital compass, but they usually report it as an event, not a sample type. I also believe it makes more sense to consider a change in the compass bearing as an event. It's a setting you change, not some sensor that is polled every sample. I don't think any dive computer will ever generate a continuous stream with compass bearings. So I think we should drop this. BTW, is the correct name comnpass bearing or heading?
Either bearing or heading, and yes, at least for mine, it's an event (and I think it only happens when you ask for it with a bookmark).
- vendor: A vendor specific extension. This is intended for all samples
that don't fit well into one of the types supported by the libdivecomputer library. The application is responsible for parsing the raw data, but at least it doesn't have to care about where and how the samples are stored. There are actually two variants of the vendor type today. For the first variant each piece of info gets its own vendor sample. That means a dc_sample_t can contain multiple vendor values. The second variant is the raw data representing the entire dc_sample_t data. Both have their use, so I propose to reserve the vendor type for the first case, and add a new raw type for the second case.
Fair enough.
What else should we support? Some common requests I get are:
- gas switches
- no decompression time
- decompression stops
- ...
Gas switching is a real event (just as long as you don't mix it up with the pressure data). I would suggest against bothering with the computed stuff, although the "violated deco stop" event is obviously an interesting event.
Decompression is a bit troublesome. Some models have just a simple deco flag. Others provide a time and depth, which is typically the time to surface (TTS) (e.g. total time for all stops and ascent combined) and the depth of the current stop. But their are plenty of other interpretations possible too. I won't be surprised some of the more technical dive computers provide a full decoplan (e.g. time at each depth). I have no idea how to support something like this in a clean way.
I despise the deco events I see from suunto. In the raw format we get it now, there's a "you are now in deco" and then a second "you are now no longer in deco" event. I guess it makes sense, but I really don't know how to sensibly even show it sanely. Rigth now subsurface shows it as two events, and it's just annoying.
At the same time, the fact that the computer thinks you are in deco (or not) _is_ interesting information, so I think it's roughly the right thing to do. It's just that I don't like how libdivecomputer gives the data: it was not at all clear to me what the deco events meant initially.
Note that an alternative solution would be to implement a decompression algorithm in the application and calculate all kinds of deco related parameters (tissue saturation, deco stops, etc) that way. It won't necessary match with your dive computer, but at least you would get a consistent application experience, regardless of the type of dive computer you have. Personally, I think this makes more sense for a general purpose logbook application, but not everyone may agree with that of course.
I agree with you. *If* we really care, we could calculate most of these things on our own. In many cases, calculating them on our own is way more interesting than what the computer gives us, because then you can change the model and see "oh, according to *that* model I am already dead".
Linus