On 2014-09-14 04:03, Janice McLaughlin wrote:
My thought was not to replace the existing Gas Switch model at all, but just to add the tank model for those dive computers that it makes sense for. So perhaps a ostc and Shearwater return 1 or 4(8) for DC_FIELD_GASMIX_COUNT and return 0 for DC_FIELD_TANK_COUNT. And they would continue to put gas switch events, (with id's probably to fix the problem you reference) in the sample stream. But an eg: Atomic would return 0 for DC_FIELD_GASMIX_COUNT and would return 3 for DC_FIELD_TANK_COUNT. And the corresponding dc_tank_t would have the tank capacity (where this all started) and starting and ending pressure in it, just like the DC itself does. All of the DC's that support a tank model seem to have all of that information available about each tank, including gas mix.
That's not entirely correct. There are also air-integrated dive computers, that support gas switches, and also record tank pressure, but which do not follow the tank switch model.
Take for example the Suunto Cobra 2 (just to name one). It's an air integrated model (hose), which supplies tank data in the sense that it records tank pressure, but without any info about the tank size. Being a hose based model, it can of course only support a single tank sensor. It also support multiple gas mixes, and the gas switches are recorded using the gas switch model.
So in this case, you can't really replace DC_FIELD_GASMIX with DC_FIELD_TANK, because there are more gas mixes than tanks. Of course those extra gas mixes are also stored in a tank, but we just don't have any info about that. We don't even know which gas mix is in the tank connected to the tank sensor. Most likely it will be the main tank, and the other gas mixes will be some deco mixes in stages. But we can't guarantee that. So the DC_FIELD_TANK is still needed for the tank pressure, but there should be no gasmix inside.
That's the main reason why I proposed to keep the DC_FIELD_GASMIX as the main (and only) interface for the gas mixes. The DC_FIELD_TANK would be an optional interface for devices which also provide some info about the tank (tank pressure, tank size, etc). And if the exact gas mix is known (e.g. for tank switch based devices, or if the device provides this info in some other way), you would also get its id there. Thus there is no need to also include the actual O2/He percentages in the dc_tank_t structure.
With my proposal, the cobalt parser would return the same value for both DC_FIELD_GASMIX_COUNT and DC_FIELD_TANK_COUNT (note that the newer cobalt 2 supports more than 3 gas mixes). The gasmix field in the dc_tank_t struct would contain the id of the corresponding dc_gasmix_t structure.
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!
FYI The Liquivision Lynx allows you to monitor the air supply of up to 10 other divers (in addition to your own) and give's pressure samples for each throughout the dive. Now, why you would want to "log" someone else's pressure samples is a good question :-) But I'm assuming that you can use some of this capacity to get pressure data from more than one of your own tanks.
With wireless sensors it's certainly possible to use multiple sensors with a single dive computer. I assume several libdivecomputer supported models (from Uwatec, Mares, Uwatec, etc) already support that. I just don't have data where that feature is being used.
Some Oceanics are also capable of monitoring someone else' tank pressure. Although that might be a useful feature during the dive, I also don't really see the use-case from a logging point of view.
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.
Seems like a good idea to instead put the gas mix id in the event.
Indeed. Unfortunately we can't fix this right now, without breaking all existing applications. So this will have to wait until after the v0.5 release :-(
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; ... };
But to address your point of decoupling the gas mix from the tank information .... this would not be *my* preference. That would mean that the sample stream would return both a gas change AND a tank change event every each time there was a tank change. And, as you suggest, you'd have to put the gas mix id inside the tank information ..... and that just seems confusing. I'd rather see the gas mix inside the tank info and only 1 event in the stream. Which may or may not mean a gas change as well depending on what's in the tank.
No, I think you misunderstood me. The idea is that in the samples, there will be no tank changes, only gas changes. For a device using the tank switch model, the gasmix field provides a fixed one to one relationship between the dc_tank_t structure and the corresponding dc_gamix_t structure. So you don't really need a tank switch.
For devices using a true tank switch model like the cobalt one, the number of dc_tank_t and dc_gasmix_t structures will always be identical. Thus if the id's is a simple zero based index, then the id in the gas change event can be directly mapped to the tank structure.
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!)
Again, I would not change anything for devices that "don't track tanks" and continue to do what you are doing. And for DC's that have a one to one mapping, then put the gas mix inside the dc_tank_t.
How do you deal with the "hybrid" case that I explained above (e.g. Suunto Cobra 2)?
I think having the gasmix in either the DC_FIELD_GASMIX or the DC_FIELD_TANK interface, depending on how the device stores it internally, will be confusing. It basically forces an application that is interested in the gas mixes, to always check the DC_FIELD_TANK interface too. That's counterintuitive is you ask me.
This would mean that none of the applications would need to change much. I think that each application that is using libdivecomputer will also have their own model for how they communicate this information to the end user. I think if libdivecomputer gives more "hints" about the DC itself and how it works, then it gives the application more flexibility on how to give the information to the end user and map it to their own data model.
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.
You've done this enough that perhaps you could write a new backend for a new device simply based on some USB traces. I just meant that *I* could not do this :-) There was talk of trying to get more people to contribute to the project and so if I were to contribute a new backend to libdivecomputer, I could reverse engineer it but I would also need one in my hands to test with.
Ah ok. I misunderstood. I thought you suggested to capture the communication and then send the files to someone else for analysis. In that case, the person doing the reverse engineering still has no physical access, and thus it makes no difference how the data was captured. But if you do everything yourself (capture, analyze, implement and test), then that's another story or course.
I've always relied on the device owner to capture the data and run the tests for me, so I guess I'm already used to that. I think the only device I have reverse engineered with physical access is the Diverite Nitek Q.
Jef