Esempio n. 1
0
void DivePlannerPointsModel::computeVariations()
{
	bool oldRecalc = setRecalc(false);
	struct dive *dive = alloc_dive();
	copy_dive(&displayed_dive, dive);
	struct decostop original[60], deeper[60], shallower[60], shorter[60], longer[60];
	struct deco_state *cache = NULL, *save = NULL;
	struct diveplan plan_copy;
	struct divedatapoint *last_segment;

	if(in_planner() && prefs.display_variations) {
		cache_deco_state(&save);
		cloneDiveplan(&plan_copy);
		plan(&plan_copy, dive, 1, original, &cache, true, false);
		free_dps(&plan_copy);
		restore_deco_state(save, false);

		last_segment = cloneDiveplan(&plan_copy);
		last_segment->depth.mm += 1000;
		last_segment->next->depth.mm += 1000;
		plan(&plan_copy, dive, 1, deeper, &cache, true, false);
		free_dps(&plan_copy);
		restore_deco_state(save, false);

		last_segment = cloneDiveplan(&plan_copy);
		last_segment->depth.mm -= 1000;
		last_segment->next->depth.mm -= 1000;
		plan(&plan_copy, dive, 1, shallower, &cache, true, false);
		free_dps(&plan_copy);
		restore_deco_state(save, false);

		last_segment = cloneDiveplan(&plan_copy);
		last_segment->next->time += 60;
		plan(&plan_copy, dive, 1, longer, &cache, true, false);
		free_dps(&plan_copy);
		restore_deco_state(save, false);

		last_segment = cloneDiveplan(&plan_copy);
		last_segment->next->time -= 60;
		plan(&plan_copy, dive, 1, shorter, &cache, true, false);
		free_dps(&plan_copy);
		restore_deco_state(save, false);
#ifdef SHOWSTOPVARIATIONS
		printf("\n\n");
#endif

		QString notes(displayed_dive.notes);
		free(displayed_dive.notes);

		char buf[200];
		sprintf(buf, "+ %d:%02d /m + %d:%02d /min", FRACTION(analyzeVariations(shallower, original, deeper, "m"),60),
			FRACTION(analyzeVariations(shorter, original, longer, "min"), 60));

		displayed_dive.notes = strdup(notes.replace("VARIATIONS", QString(buf)).toUtf8().data());
	}
	setRecalc(oldRecalc);
}
Esempio n. 2
0
void setupPlanVpmb100m10min(struct diveplan *dp)
{
	dp->salinity = 10300;
	dp->surface_pressure = 1013;
	dp->bottomsac = prefs.bottomsac;
	dp->decosac = prefs.decosac;

	struct gasmix bottomgas = {{180}, {450}};
	struct gasmix ean50 = {{500}, {0}};
	struct gasmix oxygen = {{1000}, {0}};
	pressure_t po2 = {1600};
	displayed_dive.cylinder[0].gasmix = bottomgas;
	displayed_dive.cylinder[0].type.size.mliter = 60000;
	displayed_dive.cylinder[0].type.workingpressure.mbar = 232000;
	displayed_dive.cylinder[1].gasmix = ean50;
	displayed_dive.cylinder[2].gasmix = oxygen;
	displayed_dive.surface_pressure.mbar = 1013;
	reset_cylinders(&displayed_dive, true);
	free_dps(dp);

	int droptime = M_OR_FT(100, 330) * 60 / M_OR_FT(99, 330);
	plan_add_segment(dp, 0, gas_mod(ean50, po2, &displayed_dive, M_OR_FT(3, 10)).mm, 1, 0, 1, OC);
	plan_add_segment(dp, 0, gas_mod(oxygen, po2, &displayed_dive, M_OR_FT(3, 10)).mm, 2, 0, 1, OC);
	plan_add_segment(dp, droptime, M_OR_FT(100, 330), 0, 0, 1, OC);
	plan_add_segment(dp, 10 * 60 - droptime, M_OR_FT(100, 330), 0, 0, 1, OC);
}
Esempio n. 3
0
void DivePlannerPointsModel::loadFromDive(dive *d)
{
	bool oldRec = recalc;
	recalc = false;
	CylindersModel::instance()->updateDive();
	duration_t lasttime = {};
	struct gasmix gas;
	free_dps(&diveplan);
	diveplan.when = d->when;
	// is this a "new" dive where we marked manually entered samples?
	// if yes then the first sample should be marked
	// if it is we only add the manually entered samples as waypoints to the diveplan
	// otherwise we have to add all of them
	bool hasMarkedSamples = d->dc.sample[0].manually_entered;
	for (int i = 0; i < d->dc.samples - 1; i++) {
		const sample &s = d->dc.sample[i];
		if (s.time.seconds == 0 || (hasMarkedSamples && !s.manually_entered))
			continue;
		get_gas_at_time(d, &d->dc, lasttime, &gas);
		plannerModel->addStop(s.depth.mm, s.time.seconds, &gas, 0, true);
		lasttime = s.time;
	}
	recalc = oldRec;
	emitDataChanged();
}
Esempio n. 4
0
void setupPlanVpmb60m10mTx(struct diveplan *dp)
{
	dp->salinity = 10300;
	dp->surface_pressure = 1013;
	dp->gfhigh = 100;
	dp->gflow = 100;
	dp->bottomsac = prefs.bottomsac;
	dp->decosac = prefs.decosac;

	struct gasmix bottomgas = {{180}, {450}};
	struct gasmix tx50_15 = {{500}, {150}};
	struct gasmix oxygen = {{1000}, {0}};
	pressure_t po2 = {1600};
	displayed_dive.cylinder[0].gasmix = bottomgas;
	displayed_dive.cylinder[0].type.size.mliter = 24000;
	displayed_dive.cylinder[0].type.workingpressure.mbar = 232000;
	displayed_dive.cylinder[1].gasmix = tx50_15;
	displayed_dive.cylinder[2].gasmix = oxygen;
	reset_cylinders(&displayed_dive, true);
	free_dps(dp);

	int droptime = M_OR_FT(60, 200) * 60 / M_OR_FT(23, 75);
	plan_add_segment(dp, 0, gas_mod(tx50_15, po2, &displayed_dive, M_OR_FT(3, 10)).mm, 1, 0, 1, OC);
	plan_add_segment(dp, 0, gas_mod(oxygen, po2, &displayed_dive, M_OR_FT(3, 10)).mm, 2, 0, 1, OC);
	plan_add_segment(dp, droptime, M_OR_FT(60, 200), 0, 0, 1, OC);
	plan_add_segment(dp, 10 * 60 - droptime, M_OR_FT(60, 200), 0, 0, 1, OC);
}
Esempio n. 5
0
void DivePlannerPointsModel::createPlan()
{
	// Ok, so, here the diveplan creates a dive
	char *cache = NULL;
	bool oldRecalc = plannerModel->setRecalc(false);
	removeDeco();
	createTemporaryPlan();
	plannerModel->setRecalc(oldRecalc);

	//TODO: C-based function here?
	plan(&diveplan, &cache, isPlanner(), true);
	if (!current_dive || displayed_dive.id != current_dive->id) {
		// we were planning a new dive, not re-planning an existing on
		record_dive(clone_dive(&displayed_dive));
	} else if (current_dive && displayed_dive.id == current_dive->id) {
		// we are replanning a dive - make sure changes are reflected
		// correctly in the dive structure and copy it back into the dive table
		fixup_dive(&displayed_dive);
		copy_dive(&displayed_dive, current_dive);
	}
	mark_divelist_changed(true);

	// Remove and clean the diveplan, so we don't delete
	// the dive by mistake.
	free_dps(&diveplan);
	setPlanMode(NOTHING);
	planCreated();
}
Esempio n. 6
0
void setupPlan(struct diveplan *dp)
{
	dp->salinity = 10300;
	dp->surface_pressure = 1013;
	dp->gfhigh = 100;
	dp->gflow = 100;
	dp->bottomsac = 0;
	dp->decosac = 0;

	struct gasmix bottomgas = { {150}, {450} };
	struct gasmix ean36 = { {360}, {0} };
	struct gasmix oxygen = { {1000}, {0} };
	pressure_t po2 = { 1600 };
	displayed_dive.cylinder[0].gasmix = bottomgas;
	displayed_dive.cylinder[1].gasmix = ean36;
	displayed_dive.cylinder[2].gasmix = oxygen;
	reset_cylinders(&displayed_dive, true);
	free_dps(dp);

	int droptime = M_OR_FT(79, 260) * 60 / M_OR_FT(23, 75);
	plan_add_segment(dp, droptime, M_OR_FT(79, 260), bottomgas, 0, 1);
	plan_add_segment(dp, 30*60 - droptime, M_OR_FT(79, 260), bottomgas, 0, 1);
	plan_add_segment(dp, 0, gas_mod(&ean36, po2, &displayed_dive, M_OR_FT(3,10)).mm, ean36, 0, 1);
	plan_add_segment(dp, 0, gas_mod(&oxygen, po2, &displayed_dive, M_OR_FT(3,10)).mm, oxygen, 0, 1);
}
Esempio n. 7
0
void setupPlanVpmb100mTo70m30min(struct diveplan *dp)
{
	dp->salinity = 10300;
	dp->surface_pressure = 1013;
	dp->bottomsac = 0;
	dp->decosac = 0;

	struct gasmix bottomgas = { {120}, {650} };
	struct gasmix tx21_35 = { {210}, {350} };
	struct gasmix ean50 = { {500}, {0} };
	struct gasmix oxygen = { {1000}, {0} };
	pressure_t po2 = { 1600 };
	displayed_dive.cylinder[0].gasmix = bottomgas;
	displayed_dive.cylinder[1].gasmix = tx21_35;
	displayed_dive.cylinder[2].gasmix = ean50;
	displayed_dive.cylinder[3].gasmix = oxygen;
	displayed_dive.surface_pressure.mbar = 1013;
	reset_cylinders(&displayed_dive, true);
	free_dps(dp);

	int droptime = M_OR_FT(100, 330) * 60 / M_OR_FT(18, 60);
	plan_add_segment(dp, droptime, M_OR_FT(100, 330), bottomgas, 0, 1);
	plan_add_segment(dp, 20*60 - droptime, M_OR_FT(100, 330), bottomgas, 0, 1);
	plan_add_segment(dp, 3*60, M_OR_FT(70, 230), bottomgas, 0, 1);
	plan_add_segment(dp, (30 - 20 - 3) * 60, M_OR_FT(70, 230), bottomgas, 0, 1);
	plan_add_segment(dp, 0, gas_mod(&tx21_35, po2, &displayed_dive, M_OR_FT(3,10)).mm, tx21_35, 0, 1);
	plan_add_segment(dp, 0, gas_mod(&ean50, po2, &displayed_dive, M_OR_FT(3,10)).mm, ean50, 0, 1);
	plan_add_segment(dp, 0, gas_mod(&oxygen, po2, &displayed_dive, M_OR_FT(3,10)).mm, oxygen, 0, 1);
}
Esempio n. 8
0
void DivePlannerPointsModel::createPlan(bool replanCopy)
{
	// Ok, so, here the diveplan creates a dive
	struct deco_state *cache = NULL;
	bool oldRecalc = setRecalc(false);
	removeDeco();
	createTemporaryPlan();
	setRecalc(oldRecalc);

	//TODO: C-based function here?
	struct decostop stoptable[60];
	plan(&diveplan, &displayed_dive, DECOTIMESTEP, stoptable, &cache, isPlanner(), true);
	free(cache);
	if (!current_dive || displayed_dive.id != current_dive->id) {
		// we were planning a new dive, not re-planning an existing on
		record_dive(clone_dive(&displayed_dive));
	} else if (current_dive && displayed_dive.id == current_dive->id) {
		// we are replanning a dive - make sure changes are reflected
		// correctly in the dive structure and copy it back into the dive table
		displayed_dive.maxdepth.mm = 0;
		displayed_dive.dc.maxdepth.mm = 0;
		fixup_dive(&displayed_dive);
		// Try to identify old planner output and remove only this part
		// Treat user provided text as plain text.
		QTextDocument notesDocument;
		notesDocument.setHtml(current_dive->notes);
		QString oldnotes(notesDocument.toPlainText());
		int disclaimerPosition = oldnotes.indexOf(disclaimer);
		if (disclaimerPosition == 0)
			oldnotes.clear();
		else if (disclaimerPosition >= 1)
			oldnotes.truncate(disclaimerPosition-1);
		// Deal with line breaks
		oldnotes.replace("\n", "<br>");
		oldnotes.append(displayed_dive.notes);
		displayed_dive.notes = strdup(oldnotes.toUtf8().data());
		// If we save as new create a copy of the dive here
		if (replanCopy) {
			struct dive *copy = alloc_dive();
			copy_dive(current_dive, copy);
			copy->id = 0;
			copy->selected = false;
			copy->divetrip = NULL;
			if (current_dive->divetrip)
				add_dive_to_trip(copy, current_dive->divetrip);
			record_dive(copy);
		}
		copy_dive(&displayed_dive, current_dive);
	}
	mark_divelist_changed(true);

	// Remove and clean the diveplan, so we don't delete
	// the dive by mistake.
	free_dps(&diveplan);
	setPlanMode(NOTHING);
	planCreated();
}
Esempio n. 9
0
void DivePlannerPointsModel::createTemporaryPlan()
{
	// Get the user-input and calculate the dive info
	free_dps(&diveplan);
	int lastIndex = -1;
	for (int i = 0; i < rowCount(); i++) {
		divedatapoint p = at(i);
		int deltaT = lastIndex != -1 ? p.time - at(lastIndex).time : p.time;
		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.setpoint, true);
			deltaT -= p.depth / prefs.descrate;
		}
		if (p.entered)
			plan_add_segment(&diveplan, deltaT, p.depth, p.gasmix, p.setpoint, true);
	}

	// what does the cache do???
	char *cache = NULL;
	struct divedatapoint *dp = NULL;
	for (int i = 0; i < MAX_CYLINDERS; i++) {
		cylinder_t *cyl = &displayed_dive.cylinder[i];
		if (cyl->depth.mm) {
			dp = create_dp(0, cyl->depth.mm, cyl->gasmix, 0);
			if (diveplan.dp) {
				dp->next = diveplan.dp;
				diveplan.dp = dp;
			} else {
				dp->next = NULL;
				diveplan.dp = dp;
			}
		}
	}
#if DEBUG_PLAN
	dump_plan(&diveplan);
#endif
	if (recalcQ() && !diveplan_empty(&diveplan)) {
		plan(&diveplan, &cache, isPlanner(), false);
		/* TODO:
		 * Hook this signal to the mainwindow(s), the call to MainWindow
		 * can't be here as we are now dealing with QML too.
		 */
		//MainWindow::instance()->setPlanNotes(displayed_dive.notes);
		emit calculatedPlanNotes(displayed_dive.notes);
	}
	// throw away the cache
	free(cache);
#if DEBUG_PLAN
	save_dive(stderr, &displayed_dive);
	dump_plan(&diveplan);
#endif
}
Esempio n. 10
0
void DivePlannerPointsModel::cancelPlan()
{
	if (mode == PLAN && rowCount()) {
		if (QMessageBox::warning(MainWindow::instance(), TITLE_OR_TEXT(tr("Discard the plan?"),
									       tr("You are about to discard your plan.")),
					 QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard) != QMessageBox::Discard) {
			return;
		}
	}
	setPlanMode(NOTHING);
	free_dps(&diveplan);

	emit planCanceled();
}
Esempio n. 11
0
void DivePlannerPointsModel::createTemporaryPlan()
{
	// Get the user-input and calculate the dive info
	free_dps(&diveplan);
	int lastIndex = -1;
	for (int i = 0; i < rowCount(); i++) {
		divedatapoint p = at(i);
		int deltaT = lastIndex != -1 ? p.time - at(lastIndex).time : p.time;
		lastIndex = i;
		if (i == 0 && mode == PLAN && prefs.drop_stone_mode) {
			/* Okay, we add a first segment where we go down to depth */
			plan_add_segment(&diveplan, p.depth.mm / prefs.descrate, p.depth.mm, p.cylinderid, p.setpoint, true);
			deltaT -= p.depth.mm / prefs.descrate;
		}
		if (p.entered)
			plan_add_segment(&diveplan, deltaT, p.depth.mm, p.cylinderid, p.setpoint, true);
	}

	// what does the cache do???
	struct deco_state *cache = NULL;
	struct divedatapoint *dp = NULL;
	for (int i = 0; i < MAX_CYLINDERS; i++) {
		cylinder_t *cyl = &displayed_dive.cylinder[i];
		if (cyl->depth.mm && cyl->cylinder_use != NOT_USED) {
			dp = create_dp(0, cyl->depth.mm, i, 0);
			if (diveplan.dp) {
				dp->next = diveplan.dp;
				diveplan.dp = dp;
			} else {
				dp->next = NULL;
				diveplan.dp = dp;
			}
		}
	}
#if DEBUG_PLAN
	dump_plan(&diveplan);
#endif
	if (recalcQ() && !diveplan_empty(&diveplan)) {
		struct decostop stoptable[60];
		plan(&diveplan, &displayed_dive, DECOTIMESTEP, stoptable, &cache, isPlanner(), false);
		computeVariations();
		emit calculatedPlanNotes();
	}
	// throw away the cache
	free(cache);
#if DEBUG_PLAN
	save_dive(stderr, &displayed_dive);
	dump_plan(&diveplan);
#endif
}
Esempio n. 12
0
void DivePlannerPointsModel::loadFromDive(dive *d)
{
	int depthsum = 0;
	int samplecount = 0;
	bool oldRec = recalc;
	recalc = false;
	CylindersModel::instance()->updateDive();
	duration_t lasttime = {};
	duration_t newtime = {};
	struct gasmix gas;
	free_dps(&diveplan);
	diveplan.when = d->when;
	// is this a "new" dive where we marked manually entered samples?
	// if yes then the first sample should be marked
	// if it is we only add the manually entered samples as waypoints to the diveplan
	// otherwise we have to add all of them

	bool hasMarkedSamples = false;

	if (d->dc.samples)
		hasMarkedSamples = d->dc.sample[0].manually_entered;

	// if this dive has more than 100 samples (so it is probably a logged dive),
	// average samples so we end up with a total of 100 samples.
	int plansamples = d->dc.samples <= 100 ? d->dc.samples : 100;
	int j = 0;
	for (int i = 0; i < plansamples - 1; i++) {
		while (j * plansamples <= i * d->dc.samples) {
			const sample &s = d->dc.sample[j];
			if (s.time.seconds != 0 && (!hasMarkedSamples || s.manually_entered)) {
				depthsum += s.depth.mm;
				++samplecount;
				newtime = s.time;
			}
			j++;
		}
		if (samplecount) {
			get_gas_at_time(d, &d->dc, lasttime, &gas);
			addStop(depthsum / samplecount, newtime.seconds, &gas, 0, true);
			lasttime = newtime;
			depthsum = 0;
			samplecount = 0;
		}
	}
	recalc = oldRec;
	emitDataChanged();
}
Esempio n. 13
0
void DivePlannerPointsModel::createPlan(bool replanCopy)
{
	// Ok, so, here the diveplan creates a dive
	char *cache = NULL;
	bool oldRecalc = setRecalc(false);
	removeDeco();
	createTemporaryPlan();
	setRecalc(oldRecalc);

	//TODO: C-based function here?
	bool did_deco = plan(&diveplan, &cache, isPlanner(), true);
	free(cache);
	if (!current_dive || displayed_dive.id != current_dive->id) {
		// we were planning a new dive, not re-planning an existing on
		record_dive(clone_dive(&displayed_dive));
	} else if (current_dive && displayed_dive.id == current_dive->id) {
		// we are replanning a dive - make sure changes are reflected
		// correctly in the dive structure and copy it back into the dive table
		displayed_dive.maxdepth.mm = 0;
		displayed_dive.dc.maxdepth.mm = 0;
		fixup_dive(&displayed_dive);
		if (replanCopy) {
			struct dive *copy = alloc_dive();
			copy_dive(current_dive, copy);
			copy->id = 0;
			copy->selected = false;
			copy->divetrip = NULL;
			if (current_dive->divetrip)
				add_dive_to_trip(copy, current_dive->divetrip);
			record_dive(copy);
			QString oldnotes(current_dive->notes);
			if (oldnotes.indexOf(QString(disclaimer)) >= 0)
				oldnotes.truncate(oldnotes.indexOf(QString(disclaimer)));
			if (did_deco)
				oldnotes.append(displayed_dive.notes);
			displayed_dive.notes = strdup(oldnotes.toUtf8().data());
		}
		copy_dive(&displayed_dive, current_dive);
	}
	mark_divelist_changed(true);

	// Remove and clean the diveplan, so we don't delete
	// the dive by mistake.
	free_dps(&diveplan);
	setPlanMode(NOTHING);
	planCreated();
}
Esempio n. 14
0
void setupPlanVpmb60m30minAir(struct diveplan *dp)
{
	dp->salinity = 10300;
	dp->surface_pressure = 1013;
	dp->bottomsac = 0;
	dp->decosac = 0;

	struct gasmix bottomgas = { {210}, {0} };
	pressure_t po2 = { 1600 };
	displayed_dive.cylinder[0].gasmix = bottomgas;
	displayed_dive.surface_pressure.mbar = 1013;
	reset_cylinders(&displayed_dive, true);
	free_dps(dp);

	int droptime = M_OR_FT(60, 200) * 60 / M_OR_FT(99, 330);
	plan_add_segment(dp, droptime, M_OR_FT(60, 200), bottomgas, 0, 1);
	plan_add_segment(dp, 30*60 - droptime, M_OR_FT(60, 200), bottomgas, 0, 1);
}
Esempio n. 15
0
void setupPlanVpmb30m20min(struct diveplan *dp)
{
	dp->salinity = 10300;
	dp->surface_pressure = 1013;
	dp->bottomsac = prefs.bottomsac;
	dp->decosac = prefs.decosac;

	struct gasmix bottomgas = {{210}, {0}};
	displayed_dive.cylinder[0].gasmix = bottomgas;
	displayed_dive.cylinder[0].type.size.mliter = 36000;
	displayed_dive.cylinder[0].type.workingpressure.mbar = 232000;
	displayed_dive.surface_pressure.mbar = 1013;
	reset_cylinders(&displayed_dive, true);
	free_dps(dp);

	int droptime = M_OR_FT(30, 100) * 60 / M_OR_FT(18, 60);
	plan_add_segment(dp, droptime, M_OR_FT(30, 100), 0, 0, 1, OC);
	plan_add_segment(dp, 20 * 60 - droptime, M_OR_FT(30, 100), 0, 0, 1, OC);
}
Esempio n. 16
0
void DivePlannerPointsModel::cancelPlan()
{
	/* TODO:
	 * This check shouldn't be here - this is the interface responsability.
	 * as soon as the interface thinks that it could cancel the plan, this should be
	 * called.
	 */

	/*
	if (mode == PLAN && rowCount()) {
		if (QMessageBox::warning(MainWindow::instance(), TITLE_OR_TEXT(tr("Discard the plan?"),
												 tr("You are about to discard your plan.")),
					 QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard) != QMessageBox::Discard) {
			return;
		}
	}
	*/

	setPlanMode(NOTHING);
	free_dps(&diveplan);

	emit planCanceled();
}
Esempio n. 17
0
void setupPlanSeveralGases(struct diveplan *dp)
{
	dp->salinity = 10300;
	dp->surface_pressure = 1013;
	dp->bottomsac = prefs.bottomsac;
	dp->decosac = prefs.decosac;

	struct gasmix ean36 = {{360}, {0}};
	struct gasmix tx11_50 = {{110}, {500}};

	displayed_dive.cylinder[0].gasmix = ean36;
	displayed_dive.cylinder[0].type.size.mliter = 36000;
	displayed_dive.cylinder[0].type.workingpressure.mbar = 232000;
	displayed_dive.cylinder[1].gasmix = tx11_50;
	displayed_dive.surface_pressure.mbar = 1013;
	reset_cylinders(&displayed_dive, true);
	free_dps(dp);

	plan_add_segment(dp, 120, 40000, 0, 0, true, OC);
	plan_add_segment(dp, 18 * 60, 40000, 0, 0, true, OC);
	plan_add_segment(dp, 10 * 60, 10000, 1, 0, true, OC);
	plan_add_segment(dp, 5 * 60, 10000, 0, 0, true, OC);
}
Esempio n. 18
0
void setupPlanVpmb100m60min(struct diveplan *dp)
{
	dp->salinity = 10300;
	dp->surface_pressure = 1013;
	dp->bottomsac = 0;
	dp->decosac = 0;

	struct gasmix bottomgas = { {180}, {450} };
	struct gasmix ean50 = { {500}, {0} };
	struct gasmix oxygen = { {1000}, {0} };
	pressure_t po2 = { 1600 };
	displayed_dive.cylinder[0].gasmix = bottomgas;
	displayed_dive.cylinder[1].gasmix = ean50;
	displayed_dive.cylinder[2].gasmix = oxygen;
	displayed_dive.surface_pressure.mbar = 1013;
	reset_cylinders(&displayed_dive, true);
	free_dps(dp);

	int droptime = M_OR_FT(100, 330) * 60 / M_OR_FT(99, 330);
	plan_add_segment(dp, droptime, M_OR_FT(100, 330), bottomgas, 0, 1);
	plan_add_segment(dp, 60*60 - droptime, M_OR_FT(100, 330), bottomgas, 0, 1);
	plan_add_segment(dp, 0, gas_mod(&ean50, po2, &displayed_dive, M_OR_FT(3,10)).mm, ean50, 0, 1);
	plan_add_segment(dp, 0, gas_mod(&oxygen, po2, &displayed_dive, M_OR_FT(3,10)).mm, oxygen, 0, 1);
}
Esempio n. 19
0
void DivePlannerPointsModel::deleteTemporaryPlan()
{
	free_dps(&diveplan);
}
Esempio n. 20
0
void DivePlannerPointsModel::loadFromDive(dive *d)
{
	int depthsum = 0;
	int samplecount = 0;
	o2pressure_t last_sp;
	bool oldRec = recalc;
	struct divecomputer *dc = &(d->dc);
	recalc = false;
	CylindersModel::instance()->updateDive();
	duration_t lasttime = {};
	duration_t lastrecordedtime = {};
	duration_t newtime = {};
	free_dps(&diveplan);
	if (mode != PLAN)
		clear();
	diveplan.when = d->when;
	// is this a "new" dive where we marked manually entered samples?
	// if yes then the first sample should be marked
	// if it is we only add the manually entered samples as waypoints to the diveplan
	// otherwise we have to add all of them

	bool hasMarkedSamples = false;

	if (dc->samples)
		hasMarkedSamples = dc->sample[0].manually_entered;
	else
		dc = fake_dc(dc, true);

	// if this dive has more than 100 samples (so it is probably a logged dive),
	// average samples so we end up with a total of 100 samples.
	int plansamples = dc->samples <= 100 ? dc->samples : 100;
	int j = 0;
	int cylinderid = 0;
	last_sp.mbar = 0;
	for (int i = 0; i < plansamples - 1; i++) {
		while (j * plansamples <= i * dc->samples) {
			const sample &s = dc->sample[j];
			if (s.time.seconds != 0 && (!hasMarkedSamples || s.manually_entered)) {
				depthsum += s.depth.mm;
				last_sp = s.setpoint;
				++samplecount;
				newtime = s.time;
			}
			j++;
		}
		if (samplecount) {
			cylinderid = get_cylinderid_at_time(d, dc, lasttime);
			if (newtime.seconds - lastrecordedtime.seconds > 10) {
				addStop(depthsum / samplecount, newtime.seconds, cylinderid, last_sp.mbar, true);
				lastrecordedtime = newtime;
			}
			lasttime = newtime;
			depthsum = 0;
			samplecount = 0;
		}
	}
	// make sure we get the last point right so the duration is correct
	if (!hasMarkedSamples) addStop(0, d->dc.duration.seconds,cylinderid, last_sp.mbar, true);
	recalc = oldRec;
	emitDataChanged();
}