On 2014-09-11 04:00, Janice McLaughlin wrote:
I've been reluctant to venture into this discussion because I don't have a strong opinion about this aspect directly. But this is because I've already implemented my own strategy because it was missing from libdivecomputer. There would have to be a compelling reason to switch from what I have now, that is working and shipping, to something new and untested. Getting the same information in a different way is not that compelling. Perhaps other application developers are in the same boat. However a later discussion about a different subject is related to this and I think tied in.
First, my dc_tankinfo_t looks like this: typedef struct dc_tankinfo_t { float helium; float oxygen; float nitrogen; float startpressure; float endpressure; float tanksize; float workingpressure; float minPPO2; float maxPPO2; int type; int sensor; } dc_tankinfo_t;
This is simply a direct result of what the UWatec Trimix firmware delivers for each of 10 tanks. So I grab this information from the DC and fill out the structure. Right now I'm only using this for UWatec Trimix firmware and no other manufacturers though as it hasn't been needed. But that may change soon. (BTW - UWatec does NOT give tank size or working pressure however so I don't use those elements and I don't use the type or sensor yet either; the UWatec also has an additional field per tank that is still TBD for me though) (BTW - I could skip Imperial tanksize units altogether too as calling it "braindead" is being too kind)
My point here though is that it also includes the gas mix for each of the tanks. So my only comment is that if you're going to add a new API for tanks, I would make it as expansive as possible and just have a way to indicate "no value" for the fields that are not applicable. That would accommodate the largest range of dive computers.
One of the main problems here, is that most dive computers don't have any knowledge about the tanks, only the gas mixes. That's why libdivecomputer does not even try to match gas mixes with tanks. In most cases, there is simply not enough information to do this correctly. And we're not talking about some odd corner cases, but very common scenarios!
Currently, libdivecomputer can report the list of available gas mixes, and also the gas switch events in the sample data. This is a very simple model that can easily be supported by all dive computers. (I'm aware that the current api for the gas switches has a serious design flaw. It doesn't deal well with multiple identical gas mixes. But that's another story, so let's ignore that for a moment.)
For the air integrated models, libdivecomputer provides the tank pressure in the sample data. Multiple tank pressure sensors are fully supported, because each pressure is tagged with the tank id (which is just a zero based index). Because the tank pressure is fully decoupled from the gas mixes, this model also works well for all dive computers. Non-air integrated models just don't report any tank pressure.
If you want to integrate the gas mixes into the tank info, then you'll run into problems with devices that do not track tank info, but only the gas mixes. And those are still the majority of the devices. Even air integrated models typically only track those tanks for which they have a pressure sensor. The only case where you can do this correctly, are those devices that model gas switches as tank switches. Because there you have a direct association between the tank and its gas mix.
On Sep 9, 2014, at 12:00 PM, Jef Driesen jef@libdivecomputer.org wrote:
[To give a bit more context on why I picked the gas mixes as an example. It has been discussed several times already that the current libdivecomputer api for gas switches is far from ideal. A much better design would be to provide the id of the current gas instead of the O2/He percentages directly. That would for example solve the problem that right now you don't really know which mix you switched to, if you happen to have configured two identical gas mixes. But that means libdivecomputer has to collect all gas mixes up front, to be able to assign an id!]
So this is why I think that what you do for tanks now might have a greater impact in the future. Right now libdivecomputer will report gas switches but not tank switches. Based on your explanation of how this came about, this make sense.
That's not entirely correct. There are no explicit tank switch events, but in many (all?) cases the necessary info is already there. As far as I know, all supported devices support at most one active tank sensor. Once you switch to a certain tank sensor, all others are suspended and will no longer record a tank pressure. The result is that in the sample data, you'll only see one tank pressure, corresponding to the active sensor. That means that if you receive a tank pressure sample with a tank id that is different from the previous sample, then that means there has been a tank switch.
In theory it's possible that a device records tank pressure from multiple sensors at once. The libdivecomputer api supports this, and some data formats are in theory also capable of doing this, but I've never seen this in practice.
Data from a dive computer with multiple pressure sensors is difficult to find. If anyone has such a setup, I would love to get some real data from it!
However, I would like to see the addition of tank switches to accommodate the dive computers that use this concept. And - you can model gas switches AS tank switches if you want to but you can't model tank switches as gas switches.
So, you mention that ostc and nitekq use the gas switch model. And so does Shearwater, although you can get the list of gases up front. But Atomic, Liquivision, Pelagic, and UWatec all have a tank switch model. I'm not sure about Suunto as I don't have good switching data, but it *seems* like it's tank based but could be gas based. Same for the newer Mares. But right now, if a diver switches from one tank to another with the same mix in it, it may not get recorded. In any case, I think there is a good argument for also having tank switch capability in libdivecomputer for more accurate information from the DC.
Anyway, I suggest that libdivecomputer could keep the existing DC_FIELD_GASMIX_COUNT and DC_FIELD_GASMIX API, and could also add a DC_FIELD_TANK_COUNT and DC_FIELD_TANKINFO interface, and then that would nicely give id's and a way to get SAMPLE_EVENT_TANKCHANGE events in the sample stream for those DC's that support it.
The problem of not being able to detect a switch to another tank with the same gasmix is due to the fact that the gas change events carry the O2/He percentages instead of a gasmix index. This is a design flaw that I intent to fix after v0.5. It's not directly related to not having tank switches.
When I read your email for the first time, I thought introducing tank change events would indeed be a good idea. But the more I think about it, the more I doubt whether that's the right solution.
For devices with a tank based switch model, and those are the ones where this info would be useful, the tank switches and gas switches will always coincide. So you kind of get this information already. You just don't know whether you have such device or not, because libdivecomputer doesn't tell you that. So maybe what we really need here is a way to tell the application that there is a one to one mapping between the tanks and the gas mixes? One property of these devices with a tank based switch model, is that the number of tanks will always be equal to the number of gas mixes. Maybe that's something the application can use for that purpose?
Also, assuming we introduce tank switch events in the samples, then the application still has to work out which gas mix is associated with a particular tank. But even while this association is fixed for the entire dive, you'll have to this by manually processing the tank and gas switches in the samples. That's a bit odd if you ask me. It also means you'll only be able to do this for those tanks and gas mixes that have been used on the dive. Maybe it's a better idea to include the id of the gas mix in our tank structure?
struct dc_tank_t { unsigned int gasmix; ... };
When we don't have enough information to provide this info, we set the field to some predefined value to indicate "unknown". Unfortunately we can't use zero here. The gasmix index is zero based, so zero would be a valid value. But something like 0xFFFFFFFF should do:
#define DC_GASMIX_UNKNOWN 0xFFFFFFFF
The key point here is that we keep the gas mixes outside the tank structure. We need that in order to support devices that don't track tanks. But for devices where there is a known one to one mapping between tanks and gas mixes, we can also provide this info to the application.
(I'm just thinking aloud here, feel free to join!)
I have a USB analyzer that I needed for my driver work. If someone can deliver one of these units into my hands, I'd be happy to take a look and take some traces. And we could go from there.
For capturing USB communication there are also software solutions. That's basically what I have been doing all those years for serial communication. It's certainly a bit more practical than having to send an (expensive) dive computer. But if the owner doesn't mind doing that, that's certainly also an option.
Jef