Next round of api improvements.

Dirk Hohndel dirk at hohndel.org
Wed Dec 5 16:53:18 UTC 2012


Hi Jef,

Thanks for the detailed summary email. That's really helpful.

Overall I think we made great progress here. To keep this email
manageable I'll cut everything out where I would otherwise just say
"excellent - I'm glad that's the direction we are taking" :-)

Jef Driesen <jefdriesen at telenet.be> writes:
> There has been some discussion regarding the exact semantics of the 
> temperature field. On one hand it's important to clearly define the 
> exact semantics, but on the other hand the device may provide one or 
> more temperature temperature values with some different semantics. For 
> example we can define the temperature field to be the minimum 
> temperature, but the device can provide the minimum, maximum or average 
> value, or the temperature before and after the dive, or the temperature 
> at maximum depth, or one or more of the above. How do we support this?
>
> One option is to keep the exact semantics vague, and just supply 
> whatever temperature value the device supplies. This is not ideal, 
> because it leaves applications that care about the exact interpretation 
> in the cold, and it also doesn't work well in case the device provides 
> more than one value.
>
> An alternative option is to move the temperature data into the samples. 
> All the values mentioned above can easily be attached to the correct 
> sample. You still won't get a full temperature profile (only a few data 
> points), but at least their is no confusion about the semantics. For 
> example a temperature value attached to sample at maximum depth, is 
> clearly the temperature at max depth, and so on.
>
> Another suggestion was to use flags to make the exact semantics clear. 
> For example if the default semantics is the minimum temperature, provide 
> a flag to overrule this interpretation with another one (e.g at max 
> depth, etc).
>
> struct temperature {
>      flags;
>      value;
>      ... /* Maybe multiple values here? */
> };
>
> And last but not least we can provide a struct with all possible 
> values:
>
> struct temperature {
>      minimum;
>      maximum;
>      average;
>      ...
> };
>
> and then provide some means to let the application know which values 
> are available (using a bitmap again, or some magic values to indicate 
> "not present").
>
> No decision for the temperature issue has been made yet.

Since I was somewhat outspoken on this before, I'll comment again.

The one solution that I don't like is "let's keep it vague and provide
some value where it is rather unclear what it might mean". That is in
general bad API design - especially as in many cases we do know exactly
what the temperature is supposed to mean.

I still like the idea of the flags where one flag could indeed be
DC_WE_DONT_KNOW_EXACTLY_WHAT_TYPE_OF_TEMP_THIS_IS (ok, maybe a shorter
name would be better). But as an application author, if the backend
KNOWS that this is air temperature before the dive, then I want it to
tell me. And if the backend knows that this is the the minimum water
temperature (vs. the temperature at the deepest spot), then I want to
know that, too. Flags are not the only possible implementation - but
they seem a straight forward one. And usually "simple is good".

> 3b. Sample data
> ================
>
> The basic list doesn't need much discussion:
>
>   * time
>   * depth
>   * temperature
>   * tank pressure
>
> There are also a couple less important ones, but as long as they are 
> reasonable device independent, I see no reason not to support them too:
>
>   * heartrate
>   * airtime
>   * CNS/OTU
>   * ...
>
> Note that this is definitely not a complete list. We'll probably need a 
> few extra types for tec divers (setpoints), and there may be others that 
> I forgot.
>
>
> There has been some discussion regarding the CNS values (but the 
> underlying discussion applies to any other type too). The natural unit 
> for the CNS values is obviously a percentage. But there are devices that 
> don't supply a percentage. For example the Suunto has OLF (Oxygen Limit 
> Fraction), which is hybrid between CNS and OTU (e.g. whichever is 
> highest), and Oceanic has their 02 bar graphs. Although both give some 
> indication of the CNS loading, they are not easily translated to a 
> percentage.
>
> What to do in this case? Just not support it, or again provide some 
> flag with the exact interpretation?

You know what I'll say... I'd love to get the data that is there plus a
flag that helps me make sense of it. The Suunto OLF could be roughly
mapped to percentages (in the application, not in libdivecomputer), I
guess (especially if the app does it's own CNS calculation and then can
show the data from the dive computer as additional data to the user).

> 3c. Events
> ===========
>
> The current proposal is to reserve the events exclusively for things 
> that have no duration (and thus no need for the begin/end flags) and 
> don't need to carry any data values. In that case, we can use a simple 
> bitfield to get all the events for the sample at once.
>
> dc_sample_get_available (sample, &bitmap);
>
> if (bitmap & DC_SAMPLE_EVENTS) {
>      dc_sample_get_events (sample, &events);
>
>      if (events & DC_SAMPLE_EVENT_BOOKMARK) {
>          /* Bookmark event. */
>      }
>      if (events & DC_SAMPLE_EVENT_VIOLATION) {
>          /* Decostop violation event. */
>      }
> }
>
> While this should work well for true events like the decostop 
> violations, bookmarks, etc we'll need another solution for things like 
> gas changes, decompression info, etc. The idea is deliver this info as 
> sample values, rather than events.

Yay! Yay! Yay!
(oops, I said I would remove things where I just wholeheartedly agree,
but this one I am really, really happy about :-) )

> For example the gasswitch event would be changed into an "active 
> gasmix" sample value. The main difference is that you will now get the 
> current gasmix on every sample, and not just the gaschange. For the 
> gasmix sample value, the corresponding data type would be the index of 
> the gasmix in the header (see above).
>
>
> Decompression data can be supported in a similar way. For each sample 
> you can get the deco status, with a data structure like this:
>
> dc_deco_t {
>      enum {NDL, DECOSTOP} type;
>      time; /* Optional */
>      depth; /* Optional */
> };
>
> If you're not in deco, the type will be set to NDL, and the time 
> contains the remaining no decompression limit (if available). If you're 
> in deco, the type will be set to DECOSTOP, and the time and depth 
> contain the time and depth of the next decompression stop (if 
> available). With such a structure we can support both devices that 
> provide just a simple ndl/deco flag, or a some more detailed info.

BTW: I ran into a fun special case when implementing this in Subsurface
(which, coincidentally stores all the ndl/deco info in samples...): The
special case is the safety stop. You have NDL remaining (obviously) and
you have a stop (weak obligation) with a time and depth.  Subsurface
doesn't show a ceiling for such stops but shows detailed information if
your mouse hovers over the profile.

I don't think it's necessary to have an additional time value in the
dc_deco_t (because the NDL at the safety stop is usually close to
infinity and isn't really a critical piece of information at that
stage), but maybe we could add a third value to the enum {NDL, DECOSTOP,
SAFETYSTOP} ?

> We already committed some changes to the master branch to move into 
> that direction. The DC_EVENT_DECOSTOP now contains the depth (in meters) 
> and time (in seconds) as two packed 16bit values, and a new DC_EVENT_NDL 
> was introduced. It's not perfect yet, because for the current api we 
> were limited to the existing data structures (hence the packing), but 
> it's a step in the direction of the model explained here.

Yes - and if I may say so, it's very appreciated by the Subsurface
team. I am happy with the stop-gap implementation in 0.3 and even more
happy with the direction this is going for the next-API.

> Of course we can consider to extend the type with deepstops and safety 
> stops, or add an extra field for TTS (Time To Surface), and things like 
> that. But the main point is that we move away from the event model as 
> much as possible.

Ahh - should have read the whole section before responding above.  

I think safety stop and deep stops could just be different enum values.
TTS would have to be a fourth member of the dc_deco_t structure; I would
still have it in there as the deco obligation is a major component of
TTS...


Thanks, Jef!

/D




More information about the Devel mailing list