From 569ad230c20dce6b5db49b961e5198c490ba59fd Mon Sep 17 00:00:00 2001 From: Tim Segers Date: Thu, 20 Oct 2022 17:09:18 +0200 Subject: Add dirty hack to print gas usage --- src/opendeco.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++-------- src/output.h | 2 ++ 2 files changed, 96 insertions(+), 15 deletions(-) diff --git a/src/opendeco.c b/src/opendeco.c index fc1f423..7759b1d 100644 --- a/src/opendeco.c +++ b/src/opendeco.c @@ -13,10 +13,16 @@ #define MOD_OXY (abs_depth(msw_to_bar(6))) +#define RMV_DIVE_DEFAULT 20 +#define RMV_DECO_DEFAULT 15 + #ifndef VERSION #define VERSION "unknown version" #endif +double RMV_DIVE = RMV_DIVE_DEFAULT; +double RMV_DECO = RMV_DECO_DEFAULT; + /* argp settings */ static char args_doc[] = ""; static char doc[] = "Implementation of Buhlmann ZH-L16 with Gradient Factors:" @@ -28,21 +34,23 @@ const char *argp_program_bug_address = "<~tsegers/opendeco@lists.sr.ht> or https const char *argp_program_version = "opendeco " VERSION; static struct argp_option options[] = { - {0, 0, 0, 0, "Dive options:", 0}, - {"depth", 'd', "NUMBER", 0, "Set the depth of the dive in meters", 0}, - {"time", 't', "NUMBER", 0, "Set the time of the dive in minutes", 1}, - {"gas", 'g', "STRING", 0, "Set the bottom gas used during the dive, defaults to Air", 2}, - {"pressure", 'p', "NUMBER", 0, "Set the surface air pressure, defaults to 1.01325bar or 1atm", 3}, - - {0, 0, 0, 0, "Deco options:", 0}, - {"gflow", 'l', "NUMBER", 0, "Set the gradient factor at the first stop, defaults to 30", 4}, - {"gfhigh", 'h', "NUMBER", 0, "Set the gradient factor at the surface, defaults to 75", 5}, - {"decogasses", 'G', "LIST", 0, "Set the gasses available for deco", 6}, - {0, 's', 0, OPTION_ARG_OPTIONAL, "Only switch gas at deco stops", 7}, - {0, '6', 0, OPTION_ARG_OPTIONAL, "Perform last deco stop at 6m", 8}, - - {0, 0, 0, 0, "Informational options:", 0}, - {0, 0, 0, 0, 0, 0} + {0, 0, 0, 0, "Dive options:", 0 }, + {"depth", 'd', "NUMBER", 0, "Set the depth of the dive in meters", 0 }, + {"time", 't', "NUMBER", 0, "Set the time of the dive in minutes", 1 }, + {"gas", 'g', "STRING", 0, "Set the bottom gas used during the dive, defaults to Air", 2 }, + {"pressure", 'p', "NUMBER", 0, "Set the surface air pressure, defaults to 1.01325bar or 1atm", 3 }, + {"rmv", 'r', "NUMBER", 0, "Set the RMV during the dive portion of the dive, defaults to 20", 4 }, + + {0, 0, 0, 0, "Deco options:", 0 }, + {"gflow", 'l', "NUMBER", 0, "Set the gradient factor at the first stop, defaults to 30", 5 }, + {"gfhigh", 'h', "NUMBER", 0, "Set the gradient factor at the surface, defaults to 75", 6 }, + {"decogasses", 'G', "LIST", 0, "Set the gasses available for deco", 7 }, + {0, 's', 0, OPTION_ARG_OPTIONAL, "Only switch gas at deco stops", 8 }, + {0, '6', 0, OPTION_ARG_OPTIONAL, "Perform last deco stop at 6m", 9 }, + {"decormv", 'R', "NUMBER", 0, "Set the RMV during the deco portion of the dive, defaults to 15", 10}, + + {0, 0, 0, 0, "Informational options:", 0 }, + {0, 0, 0, 0, 0, 0 } }; struct arguments { @@ -55,6 +63,8 @@ struct arguments { double SURFACE_PRESSURE; int SWITCH_INTERMEDIATE; int LAST_STOP_AT_SIX; + double RMV_DIVE; + double RMV_DECO; }; static error_t parse_opt(int key, char *arg, struct argp_state *state) @@ -80,6 +90,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) case '6': arguments->LAST_STOP_AT_SIX = 1; break; + case 'r': + arguments->RMV_DIVE = arg ? atof(arg) : -1; + break; case 'G': arguments->decogasses = arg; break; @@ -89,6 +102,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) case 'h': arguments->gfhigh = arg ? atoi(arg) : 100; break; + case 'R': + arguments->RMV_DECO = arg ? atof(arg) : -1; + break; case ARGP_KEY_END: if (arguments->depth < 0 || arguments->time < 0) { argp_state_help(state, stderr, ARGP_HELP_USAGE); @@ -103,6 +119,14 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) argp_failure(state, 1, 0, "GF Low must not be greater than GF High"); exit(ARGP_ERR_UNKNOWN); } + if (arguments->RMV_DIVE <= 0) { + argp_failure(state, 1, 0, "Dive RMV must be greater than 0"); + exit(ARGP_ERR_UNKNOWN); + } + if (arguments->RMV_DECO <= 0) { + argp_failure(state, 1, 0, "Deco RMV must be greater than 0"); + exit(ARGP_ERR_UNKNOWN); + } default: return ARGP_ERR_UNKNOWN; } @@ -110,6 +134,46 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) return 0; } +static struct gas_usage { + const gas_t *gas; + double usage; +} gas_usage[10]; + +int register_gas_use(const double depth, const double time, const gas_t *gas, const double rmv) +{ + double usage = depth * time * rmv; + + for (int i = 0; i < 10; i++) { + if (!gas_usage[i].gas) { + gas_usage[i] = (struct gas_usage){ + .gas = gas, + .usage = usage, + }; + return 0; + } else if (gas_usage[i].gas == gas) { + gas_usage[i].usage += usage; + return 0; + } + } + + return -1; +} + +void print_gas_use() +{ + static char gasbuf[12]; + + wprintf(L"\n"); + + for (int i = 0; i < 10; i++) { + if (gas_usage[i].gas) { + format_gas(gasbuf, len(gasbuf), gas_usage[i].gas); + strcat(gasbuf, ":"); + wprintf(L"%-12s%5i%lc\n", gasbuf, (int) ceil(gas_usage[i].usage), LTR); + } + } +} + void print_segment_callback(const decostate_t *ds, const waypoint_t wp, segtype_t type) { static double last_depth; @@ -117,6 +181,10 @@ void print_segment_callback(const decostate_t *ds, const waypoint_t wp, segtype_ wchar_t sign; + /* first time initialization */ + if (!last_depth) + last_depth = SURFACE_PRESSURE; + runtime += wp.time; if (wp.depth < last_depth) @@ -129,6 +197,12 @@ void print_segment_callback(const decostate_t *ds, const waypoint_t wp, segtype_ if (type != SEG_TRAVEL) print_planline(sign, wp.depth, wp.time, runtime, wp.gas); + /* register gas use */ + double avg_seg_depth = wp.depth == last_depth ? last_depth : (wp.depth + last_depth) / 2; + double rmv = type == SEG_DIVE ? RMV_DIVE : RMV_DECO; + + register_gas_use(avg_seg_depth, wp.time, wp.gas, rmv); + last_depth = wp.depth; } @@ -187,6 +261,8 @@ int main(int argc, char *argv[]) .SURFACE_PRESSURE = SURFACE_PRESSURE_DEFAULT, .SWITCH_INTERMEDIATE = SWITCH_INTERMEDIATE_DEFAULT, .LAST_STOP_AT_SIX = LAST_STOP_AT_SIX_DEFAULT, + .RMV_DIVE = RMV_DIVE_DEFAULT, + .RMV_DECO = RMV_DECO_DEFAULT, }; argp_parse(&argp, argc, argv, 0, 0, &arguments); @@ -195,6 +271,8 @@ int main(int argc, char *argv[]) SURFACE_PRESSURE = arguments.SURFACE_PRESSURE; SWITCH_INTERMEDIATE = arguments.SWITCH_INTERMEDIATE; LAST_STOP_AT_SIX = arguments.LAST_STOP_AT_SIX; + RMV_DIVE = arguments.RMV_DIVE; + RMV_DECO = arguments.RMV_DECO; /* setup */ decostate_t ds; @@ -237,6 +315,7 @@ int main(int argc, char *argv[]) decoinfo_t di = calc_deco(&ds, depth, gas, deco_gasses, nof_gasses, &print_segment_callback); /* output deco info and disclaimer */ + print_gas_use(); wprintf(L"\nNDL: %i TTS: %i TTS @+5: %i\n", (int) floor(di.ndl), (int) ceil(di.tts), (int) ceil(di_plus5.tts)); print_planfoot(&ds); diff --git a/src/output.h b/src/output.h index 017e319..8e602a6 100644 --- a/src/output.h +++ b/src/output.h @@ -11,6 +11,7 @@ #define LVL 0x2192 /* Unicode Rightwards Arrow */ #define DEC 0x2198 /* Unicode South East Arrow */ #define SWI 0x21BB /* Clockwise Open Circle Arrow */ +#define LTR 0x2113 /* Script Small L */ /* functions */ void print_planhead(void); @@ -18,5 +19,6 @@ void print_planline(const wchar_t sign, const double depth, const double time, c void print_planfoot(const decostate_t *ds); void scan_gas(gas_t *gas, char *str); +void format_gas(char *buf, const size_t buflen, const gas_t *gas); #endif /* end of include guard: OUTPUT_H */ -- cgit v1.2.3-70-g09d2