Make planner work again for CCR dives

The latest CCR patches had rendered the planner not usable for CCR dives.
This patch corrects this (and reenables the CCR set point column for
segments). The problem was that a new member setpoint of struct divepoint
had been introduced, but there was already po2 which had the same meaning.
This patch merges the two and renames them setpoint to prevent future
confusion.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Robert C. Helling 2014-10-19 07:07:07 -07:00 committed by Dirk Hohndel
parent 839bcaaf70
commit 5f44fdd9cf
11 changed files with 53 additions and 52 deletions

8
dive.c
View file

@ -1167,10 +1167,10 @@ static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
}
// If there are consecutive identical CCR O2 setpoint readings, throw away the redundant ones.
o2val = sample->o2setpoint.mbar;
o2val = sample->setpoint.mbar;
if (o2val) {
if (lasto2setpoint == o2val)
sample->o2setpoint.mbar = 0;
sample->setpoint.mbar = 0;
else
lasto2setpoint = o2val;
}
@ -1378,8 +1378,8 @@ static void merge_samples(struct divecomputer *res, struct divecomputer *a, stru
sample.sensor = as->sensor;
if (as->cns)
sample.cns = as->cns;
if (as->po2.mbar)
sample.po2 = as->po2;
if (as->setpoint.mbar)
sample.setpoint = as->setpoint;
if (as->ndl.seconds)
sample.ndl = as->ndl;
if (as->stoptime.seconds)

5
dive.h
View file

@ -180,8 +180,7 @@ struct sample // BASE TYPE BYTES UNITS RANGE DE
temperature_t temperature; // int32_t 4 mdegrK (0-2 MdegK) ambient temperature
pressure_t cylinderpressure; // int32_t 4 mbar (0-2 Mbar) main cylinder pressure
pressure_t diluentpressure; // int32_t 4 mbar (0-2 Mbar) CCR diluent pressure (rebreather)
o2pressure_t po2; // uint16_t 2 mbar (0-65 bar) O2 partial pressure
o2pressure_t o2setpoint; // uint16_t 2 mbar (0-65 bar) CCR O2 setpoint (rebreather)
o2pressure_t setpoint; // uint16_t 2 mbar (0-65 bar) O2 partial pressure (will be setpoint)
o2pressure_t o2sensor[3]; // uint16_t 6 mbar (0-65 bar) Up to 3 PO2 sensor values (rebreather)
bearing_t bearing; // int16_t 2 degrees (-32k to 32k deg) compass bearing
uint8_t sensor; // uint8_t 1 sensorID (0-255) ID of cylinder pressure sensor
@ -735,7 +734,7 @@ struct divedatapoint {
int time;
unsigned int depth;
struct gasmix gasmix;
int po2;
int setpoint;
bool entered;
struct divedatapoint *next;
};

View file

@ -171,8 +171,8 @@ static int calculate_otu(struct dive *dive)
struct sample *sample = dc->sample + i;
struct sample *psample = sample - 1;
t = sample->time.seconds - psample->time.seconds;
if (sample->po2.mbar) {
po2 = sample->po2.mbar;
if (sample->setpoint.mbar) {
po2 = sample->setpoint.mbar;
} else {
int o2 = active_o2(dive, dc, sample->time);
po2 = o2 * depth_to_atm(sample->depth.mm, dive);
@ -235,8 +235,8 @@ static int calculate_cns(struct dive *dive)
struct sample *sample = dc->sample + i;
struct sample *psample = sample - 1;
t = sample->time.seconds - psample->time.seconds;
if (sample->po2.mbar) {
po2 = sample->po2.mbar;
if (sample->setpoint.mbar) {
po2 = sample->setpoint.mbar;
} else {
int o2 = active_o2(dive, dc, sample->time);
po2 = o2 * depth_to_atm(sample->depth.mm, dive);
@ -322,7 +322,7 @@ static void add_dive_to_deco(struct dive *dive)
for (j = t0; j < t1; j++) {
int depth = interpolate(psample->depth.mm, sample->depth.mm, j - t0, t1 - t0);
(void)add_segment(depth_to_mbar(depth, dive) / 1000.0,
&dive->cylinder[sample->sensor].gasmix, 1, sample->po2.mbar, dive);
&dive->cylinder[sample->sensor].gasmix, 1, sample->setpoint.mbar, dive);
}
}
}

View file

@ -208,7 +208,7 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
sample->ndl.seconds = ndl;
sample->stoptime.seconds = stoptime;
sample->stopdepth.mm = stopdepth;
sample->po2.mbar = po2;
sample->setpoint.mbar = po2;
sample->cns = cns;
}
sample = prepare_sample(dc);
@ -247,10 +247,10 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
#if DC_VERSION_CHECK(0, 3, 0)
case DC_SAMPLE_SETPOINT:
/* for us a setpoint means constant pO2 from here */
sample->po2.mbar = po2 = rint(value.setpoint * 1000);
sample->setpoint.mbar = po2 = rint(value.setpoint * 1000);
break;
case DC_SAMPLE_PPO2:
sample->po2.mbar = po2 = rint(value.ppo2 * 1000);
sample->setpoint.mbar = po2 = rint(value.ppo2 * 1000);
break;
case DC_SAMPLE_CNS:
sample->cns = cns = rint(value.cns * 100);

View file

@ -379,7 +379,7 @@ static void parse_sample_keyvalue(void *_sample, const char *key, const char *va
}
if (!strcmp(key, "po2")) {
pressure_t p = get_pressure(value);
sample->po2.mbar = p.mbar;
sample->setpoint.mbar = p.mbar;
return;
}
if (!strcmp(key, "heartbeat")) {

View file

@ -895,9 +895,7 @@ static void try_to_fill_sample(struct sample *sample, const char *name, char *bu
return;
if (MATCH("sensor3.sample", double_to_o2pressure, &sample->o2sensor[2])) // up to 3 CCR sensors
return;
if (MATCH("setpoint.sample", double_to_o2pressure, &sample->o2setpoint))
return;
if (MATCH("po2.sample", double_to_o2pressure, &sample->po2))
if (MATCH("po2.sample", double_to_o2pressure, &sample->setpoint))
return;
if (MATCH("heartbeat", get_uint8, &sample->heartbeat))
return;
@ -1427,7 +1425,7 @@ static void sample_start(void)
cur_sample->stoptime.seconds = laststoptime;
cur_sample->stopdepth.mm = laststopdepth;
cur_sample->cns = lastcns;
cur_sample->po2.mbar = lastpo2;
cur_sample->setpoint.mbar = lastpo2;
cur_sample->sensor = lastsensor;
}
@ -1442,7 +1440,7 @@ static void sample_end(void)
laststoptime = cur_sample->stoptime.seconds;
laststopdepth = cur_sample->stopdepth.mm;
lastcns = cur_sample->cns;
lastpo2 = cur_sample->po2.mbar;
lastpo2 = cur_sample->setpoint.mbar;
cur_sample = NULL;
}
@ -2030,7 +2028,7 @@ extern int shearwater_profile_sample(void *handle, int columns, char **data, cha
if (data[2])
cur_sample->temperature.mkelvin = metric ? C_to_mkelvin(atof(data[2])) : F_to_mkelvin(atof(data[2]));
if (data[3])
cur_sample->po2.mbar = atof(data[3]) * 1000;
cur_sample->setpoint.mbar = atof(data[3]) * 1000;
if (data[4])
cur_sample->ndl.seconds = atoi(data[4]) * 60;
if (data[5])

View file

@ -161,7 +161,7 @@ double tissue_at_end(struct dive *dive, char **cached_datap)
get_gas_at_time(dive, dc, t0, &gas);
if (i > 0)
lastdepth = psample->depth;
tissue_tolerance = interpolate_transition(dive, t0, t1, lastdepth, sample->depth, &gas, sample->po2);
tissue_tolerance = interpolate_transition(dive, t0, t1, lastdepth, sample->depth, &gas, sample->setpoint);
psample = sample;
t0 = t1;
}
@ -251,6 +251,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas)
int oldpo2 = 0;
int lasttime = 0;
int lastdepth = 0;
enum dive_comp_type type = OC;
if (!diveplan || !diveplan->dp)
return;
@ -275,14 +276,17 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas)
cyl = &displayed_dive.cylinder[0];
oldgasmix = cyl->gasmix;
sample = prepare_sample(dc);
sample->po2.mbar = dp->po2;
sample->setpoint.mbar = dp->setpoint;
oldpo2 = dp->setpoint;
if (track_gas && cyl->type.workingpressure.mbar)
sample->cylinderpressure.mbar = cyl->end.mbar;
sample->manually_entered = true;
finish_sample(dc);
while (dp) {
struct gasmix gasmix = dp->gasmix;
int po2 = dp->po2;
int po2 = dp->setpoint;
if (dp->setpoint)
type = CCR;
int time = dp->time;
int depth = dp->depth;
@ -314,7 +318,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas)
add_gas_switch_event(&displayed_dive, dc, lasttime + 1, idx);
cyl = &displayed_dive.cylinder[idx];
sample = prepare_sample(dc);
sample[-1].po2.mbar = po2;
sample[-1].setpoint.mbar = po2;
sample->time.seconds = lasttime + 1;
sample->depth.mm = lastdepth;
sample->manually_entered = dp->entered;
@ -327,8 +331,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas)
sample = prepare_sample(dc);
/* set po2 at beginning of this segment */
/* and keep it valid for last sample - where it likely doesn't matter */
sample[-1].po2.mbar = po2;
sample->po2.mbar = po2;
sample->setpoint.mbar = po2;
sample->time.seconds = lasttime = time;
sample->depth.mm = lastdepth = depth;
sample->manually_entered = dp->entered;
@ -341,6 +344,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas)
finish_sample(dc);
dp = dp->next;
}
dc->dctype = type;
#if DEBUG_PLAN & 32
save_dive(stdout, &displayed_dive);
#endif
@ -372,7 +376,7 @@ struct divedatapoint *create_dp(int time_incr, int depth, struct gasmix gasmix,
dp->time = time_incr;
dp->depth = depth;
dp->gasmix = gasmix;
dp->po2 = po2;
dp->setpoint = po2;
dp->entered = false;
dp->next = NULL;
return dp;
@ -556,12 +560,12 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool
double depthvalue;
int decimals;
nextdp = dp->next;
if (dp->time == 0)
continue;
gasmix = dp->gasmix;
depthvalue = get_depth_units(dp->depth, &decimals, &depth_unit);
/* analyze the dive points ahead */
nextdp = dp->next;
while (nextdp && nextdp->time == 0)
nextdp = nextdp->next;
if (nextdp)
@ -757,7 +761,7 @@ int plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool s
get_gas_at_time(&displayed_dive, &displayed_dive.dc, sample->time, &gas);
po2 = displayed_dive.dc.sample[displayed_dive.dc.samples - 1].po2.mbar;
po2 = sample->setpoint.mbar;
if ((current_cylinder = get_gasidx(&displayed_dive, &gas)) == -1) {
report_error(translate("gettextFromC", "Can't find gas %s"), gasname(&gas));
current_cylinder = 0;
@ -802,6 +806,7 @@ int plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool s
current_cylinder = best_first_ascend_cylinder;
gas = displayed_dive.cylinder[current_cylinder].gasmix;
#if DEBUG_PLAN & 16
printf("switch to gas %d (%d/%d) @ %5.2lfm\n", best_first_ascend_cylinder,
(get_o2(&gas) + 5) / 10, (get_he(&gas) + 5) / 10, gaschanges[best_first_ascend_cylinder].depth / 1000.0);

View file

@ -558,12 +558,12 @@ struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *
entry->in_deco = sample->in_deco;
entry->cns = sample->cns;
if (dc->dctype == CCR) {
entry->o2setpoint = sample->o2setpoint.mbar / 1000.0; // for rebreathers
entry->o2setpoint = sample->setpoint.mbar / 1000.0; // for rebreathers
entry->o2sensor[0] = sample->o2sensor[0].mbar / 1000.0; // for up to three rebreather O2 sensors
entry->o2sensor[1] = sample->o2sensor[1].mbar / 1000.0;
entry->o2sensor[2] = sample->o2sensor[2].mbar / 1000.0;
} else {
entry->pressures.o2 = sample->po2.mbar / 1000.0;
entry->pressures.o2 = sample->setpoint.mbar / 1000.0;
}
/* FIXME! sensor index -> cylinder index translation! */
entry->cylinderindex = sample->sensor;
@ -913,7 +913,7 @@ void fill_o2_values(struct divecomputer *dc, struct plot_info *pi, struct dive *
/* For CCR:
* In the samples from each dive computer, any duplicate values for the
* oxygen sensors were removed (i.e. set to 0) in order to conserve
* storage space (see function fuxup_dive_dc). But for drawing the prodile
* storage space (see function fixup_dive_dc). But for drawing the profile
* a complete series of valid o2 pressure values is required. This function
* takes the oxygen sensor data and setpoint values from the structures
* of plotinfo and re-inserts the duplicate values set to 0 so
@ -1008,10 +1008,9 @@ void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plo
check_gas_change_events(dive, dc, pi); /* Populate the gas index from the gas change events */
setup_gas_sensor_pressure(dive, dc, pi); /* Try to populate our gas pressure knowledge */
populate_pressure_information(dive, dc, pi, NONDILUENT); /* .. calculate missing pressure entries for all gasses except diluent */
if (dc->dctype == CCR) { /* For CCR dives.. */
printf("CCR DIVE: %s (%d O2 sensors)\n", dc->model, dc->no_o2sensors);
if (dc->dctype == CCR) /* For CCR dives.. */
populate_pressure_information(dive, dc, pi, DILUENT); /* .. calculate missing diluent gas pressure entries */
}
fill_o2_values(dc, pi, dive); /* .. and insert the O2 sensor data having 0 values. */
calculate_sac(dive, pi); /* Calculate sac */
calculate_deco_information(dive, dc, pi, false); /* and ceiling information, using gradient factor values in Preferences) */

View file

@ -589,7 +589,7 @@ bool DivePlannerPointsModel::recalcQ()
int DivePlannerPointsModel::columnCount(const QModelIndex &parent) const
{
return COLUMNS - 1; // don't show CCSETPOINT until we can plan CC dives
return COLUMNS; // to disable CCSETPOINT subtract one
}
QVariant DivePlannerPointsModel::data(const QModelIndex &index, int role) const
@ -598,7 +598,7 @@ QVariant DivePlannerPointsModel::data(const QModelIndex &index, int role) const
if (role == Qt::DisplayRole || role == Qt::EditRole) {
switch (index.column()) {
case CCSETPOINT:
return (double)p.po2 / 1000;
return (double)p.setpoint / 1000;
case DEPTH:
return (int) rint(get_depth_units(p.depth, NULL, NULL));
case RUNTIME:
@ -656,7 +656,7 @@ bool DivePlannerPointsModel::setData(const QModelIndex &index, const QVariant &v
int po2 = 0;
QByteArray gasv = value.toByteArray();
if (validate_po2(gasv.data(), &po2))
p.po2 = po2;
p.setpoint = po2;
} break;
case GAS:
QByteArray gasv = value.toByteArray();
@ -911,7 +911,7 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, gasmix *gas_in,
milimeters = t.depth;
seconds = t.time + 600; // 10 minutes.
gas = t.gasmix;
ccpoint = t.po2;
ccpoint = t.setpoint;
} else if (seconds == 0 && milimeters == 0 && row == 0) {
milimeters = M_OR_FT(5, 15); // 5m / 15ft
seconds = 600; // 10 min
@ -959,7 +959,7 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, gasmix *gas_in,
point.depth = milimeters;
point.time = seconds;
point.gasmix = gas;
point.po2 = ccpoint;
point.setpoint = ccpoint;
point.entered = entered;
point.next = NULL;
divepoints.append(point);
@ -1119,11 +1119,11 @@ void DivePlannerPointsModel::createTemporaryPlan()
lastIndex = i;
if (i == 0 && prefs.drop_stone_mode) {
/* Okay, we add a fist segment where we go down to depth */
plan_add_segment(&diveplan, p.depth / prefs.descrate, p.depth, p.gasmix, p.po2, false);
plan_add_segment(&diveplan, p.depth / prefs.descrate, p.depth, p.gasmix, p.setpoint, true);
deltaT -= p.depth / prefs.descrate;
}
if (p.entered)
plan_add_segment(&diveplan, deltaT, p.depth, p.gasmix, p.po2, true);
plan_add_segment(&diveplan, deltaT, p.depth, p.gasmix, p.setpoint, true);
}
// what does the cache do???
@ -1134,8 +1134,8 @@ void DivePlannerPointsModel::createTemporaryPlan()
if (cyl->depth.mm) {
dp = create_dp(0, cyl->depth.mm, cyl->gasmix, 0);
if (diveplan.dp) {
dp->next = diveplan.dp->next;
diveplan.dp->next = dp;
dp->next = diveplan.dp;
diveplan.dp = dp;
} else {
dp->next = NULL;
diveplan.dp = dp;

View file

@ -272,9 +272,9 @@ static void save_sample(struct membuffer *b, struct sample *sample, struct sampl
old->cns = sample->cns;
}
if (sample->po2.mbar != old->po2.mbar) {
put_milli(b, " po2=", sample->po2.mbar, "bar");
old->po2 = sample->po2;
if (sample->setpoint.mbar != old->setpoint.mbar) {
put_milli(b, " po2=", sample->setpoint.mbar, "bar");
old->setpoint = sample->setpoint;
}
show_index(b, sample->heartbeat, "heartbeat=", "");
show_index(b, sample->bearing.degrees, "bearing=", "°");

View file

@ -251,9 +251,9 @@ static void save_sample(struct membuffer *b, struct sample *sample, struct sampl
old->cns = sample->cns;
}
if (sample->po2.mbar != old->po2.mbar) {
put_milli(b, " po2='", sample->po2.mbar, " bar'");
old->po2 = sample->po2;
if (sample->setpoint.mbar != old->setpoint.mbar) {
put_milli(b, " po2='", sample->setpoint.mbar, " bar'");
old->setpoint = sample->setpoint;
}
show_index(b, sample->heartbeat, "heartbeat='", "'");
show_index(b, sample->bearing.degrees, "bearing='", "'");