diff options
Diffstat (limited to '')
| -rw-r--r-- | Makefile | 8 | ||||
| -rw-r--r-- | doc/datatypes.org | 36 | ||||
| -rw-r--r-- | include/ace.h | 17 | ||||
| -rw-r--r-- | include/atragmx.h | 9 | ||||
| -rw-r--r-- | include/ballistics.h | 16 | ||||
| -rw-r--r-- | include/constants.h | 13 | ||||
| -rw-r--r-- | include/context.h | 86 | ||||
| -rw-r--r-- | src/atragmx.c | 137 | ||||
| -rw-r--r-- | src/ballistics.c | 38 | ||||
| -rw-r--r-- | src/main.c | 2 |
10 files changed, 338 insertions, 24 deletions
@@ -1,6 +1,6 @@ CC := /usr/bin/gcc CFLAGS = -Wall -Wpedantic -I$(INC_DIR) -LDLIBS := +LDLIBS := -lm # DIRS BASE_DIR = $(pwd) @@ -14,14 +14,14 @@ INC_DIR = include # TARGETS TARGET := $(BIN_DIR)/catragmx SOURCES := $(wildcard $(SRC_DIR)/*.c) -OBJECTS := $(SOURCES:$(SRC_DIR)/%.c=$(BUILD_DIR)%.o) +OBJECTS := $(SOURCES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o) # ALL TARGET all: $(TARGET) # COMPILE MAIN TARGET -$(TARGET): $(SOURCES) | $(BIN_DIR) - $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ $(LDLIBS) +$(TARGET): $(OBJECTS) | $(BIN_DIR) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) # COMPILE OBJECTS $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR) diff --git a/doc/datatypes.org b/doc/datatypes.org new file mode 100644 index 0000000..4f7e28e --- /dev/null +++ b/doc/datatypes.org @@ -0,0 +1,36 @@ +* ATragMX solution +** ATragMXContext (input) +1. GunConfig + 1. Scope base angle + 2. Bullet mass + 3. Bore height + 4. Muzzle velocity + 5. Ballistic coefficient + 6. Twist direction + 7. Drag model + 8. Air friction +2. TargetContext + 1. Target speed + 2. Target range + 3. Inclination angle + 4. Latitude +3. AtmoContext + 1. Temperature + 2. Barometric pressure + 3. Relative humidity + 4. Wind speed + 5. Wind direction + 6. Atmosphere model +4. Simulation steps +5. Store range card data? +6. Stability factor +** ATragMXSolution (output) +1. Elevation +2. Windage +3. Lead +4. Time of flight +5. Remaining velocity +6. Remaining kinetic energy +7. Vertical coriolis drift +8. Horizontal coriolis drift +9. Spin drift diff --git a/include/ace.h b/include/ace.h new file mode 100644 index 0000000..90b1996 --- /dev/null +++ b/include/ace.h @@ -0,0 +1,17 @@ +#ifndef ACE_H +#define ACE_H + +#include <stdbool.h> + +typedef struct ace_ballistics ace_ballistics; + +typedef struct { + ace_ballistics *ballistics; +} ace_config; +extern ace_config *ace; + +struct ace_ballistics { + bool enabled; +}; + +#endif diff --git a/include/atragmx.h b/include/atragmx.h new file mode 100644 index 0000000..8e6c1e0 --- /dev/null +++ b/include/atragmx.h @@ -0,0 +1,9 @@ +#ifndef ATRAGMX_H +#define ATRAGMX_H + +#include "ace.h" +#include "context.h" + +ATragMXSolution *ATragMXCalcSolution(ATragMXContext *, ace_config *); + +#endif diff --git a/include/ballistics.h b/include/ballistics.h new file mode 100644 index 0000000..470c7a6 --- /dev/null +++ b/include/ballistics.h @@ -0,0 +1,16 @@ +#ifndef ACE_BALLISTICS_H +#define ACE_BALLISTICS_H + +#include "context.h" + +double atmospheric_correction(double ballistic_coefficient, + double temperature, + double pressure, + double relative_humidity, + AtmosphereModel atmosphere_model); + +double calculate_air_density(double temperature, + double pressure, + double relative_humidity); + +#endif diff --git a/include/constants.h b/include/constants.h new file mode 100644 index 0000000..cfc9c80 --- /dev/null +++ b/include/constants.h @@ -0,0 +1,13 @@ +#ifndef CONST_H +#define CONST_H + +static const double GRAVITY = 9.80665; + +static const double DRY_AIR_MOLAR_MASS = 0.028964; +static const double WATOR_VAPOR_MOLAR_MASS = 0.018016; +static const double UNIVERSAL_GAS_CONSTANT = 8.31432; +static const double SPECIFIC_GAST_CONSTANT_DRY_AIR = 287.057036320950; +static const double STD_AIR_DENSITY_ICAO = 1.22498; +static const double STD_AIR_DENSITY_ASM = 1.20886; + +#endif diff --git a/include/context.h b/include/context.h index 95580ee..a2f651f 100644 --- a/include/context.h +++ b/include/context.h @@ -1,34 +1,80 @@ +#ifndef CONTEXT_H +#define CONTEXT_H + +#include <stddef.h> #include <stdlib.h> +#include <stdbool.h> + +#include "ace.h" typedef enum { - ATM_1, - ATM_2 -} ATM_MODEL; + BC_UNKNOWN = 0, + BC_G1, + BC_G2, + BC_G3, + BC_G4, + BC_G5, + BC_G6, + BC_G7, +} BallisticModel; + +typedef enum { + ICAO, + ASM, +} AtmosphereModel; typedef struct { - float scope_angle; - float bullet_mass; - float bore_height; - float muzzle_vel; - float ballistic_coef; + double scope_angle; + double bullet_mass; + double bore_height; + double muzzle_velocity; + double ballistic_coef; size_t drag_model; - float twist_dir; -} gun_config; + double twist_dir; +} GunConfig; typedef struct { - float termperature; - float bar_pressure; - float rel_humidity; - float wind_speed; + double temperature; + double barometric_pressure; + double relative_humidity; + double wind_speed[2]; size_t wind_dir; - ATM_MODEL atmosphere_model; -} atmo_context; + AtmosphereModel atmosphere_model; +} AtmoContext; typedef struct { - float target_speed; - float target_range; -} target_context; + double speed; + double range; + double inclination_angle; + double latitude; + size_t direction; +} TargetContext; typedef struct { - gun_config gun; + GunConfig gun; + TargetContext target; + AtmoContext atmosphere; + size_t sim_steps; + bool store_range_card; + size_t stability_factor; +} ATragMXContext; + +typedef struct { + double w1; + double w2; +} Windage; + +typedef struct { + double elev; + Windage windage; + double lead; + double time_of_flight; + double remaining_velocity; + double remaining_energy; + double coriolis_vdrift; + double coriolis_hdrift; + double spin_drift; + double *range_card; } ATragMXSolution; + +#endif diff --git a/src/atragmx.c b/src/atragmx.c new file mode 100644 index 0000000..af68b2c --- /dev/null +++ b/src/atragmx.c @@ -0,0 +1,137 @@ +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <string.h> + +#include "ballistics.h" +#include "constants.h" +#include "atragmx.h" +#include "ace.h" + +ATragMXSolution *ATragMXCalcSolution(ATragMXContext *ctx, ace_config *ace) { + + // + // init section + // + + ATragMXSolution *sln = NULL; + + if ((sln = calloc(1, sizeof(ATragMXSolution))) == NULL) { + perror("ATragMXSolution: malloc failed"); + return NULL; + } + + // local data + + struct { + double speed1; + double speed2; + } wind = { + .speed1 = ctx->atmosphere.wind_speed[0], + .speed2 = ctx->atmosphere.wind_speed[1], + }; + + struct { + double tx; + double tz; + double last_pos[3]; + double pos[3]; + double velocity[3]; + double accel[3]; + double speed; + double gravity[3]; + double deltaT; + } bullet = { + .gravity = { + [0] = 0.0, + [1] = sin(ctx->gun.scope_angle + ctx->target.inclination_angle) + * -GRAVITY, + [2] = cos(ctx->gun.scope_angle + ctx->target.inclination_angle) + * -GRAVITY + }, + .deltaT = 1.0 / ctx->sim_steps, + }; + + struct { + double elevation; + Windage windage; + double lead; + double time_of_flight; + double true_velocity[3]; + double true_speed; + double v_coriolis; + double v_coriolis_deflection; + double h_coriolis; + double h_coriolis_deflection; + double spin_drift; + double spin_deflection; + } local_solution = {0}; + + struct { + double range; + double true_range; + double range_factor; + double *range_card; + } ctx_range = { + .range_factor = ctx->store_range_card ? 1.0936133 : 1, + .range_card = NULL, + }; + + double wind1[3] = { + [0] = cos(270 - ctx->atmosphere.wind_dir * 30) + * ctx->atmosphere.wind_speed[0], + [1] = sin(270 - ctx->atmosphere.wind_dir * 30) + * ctx->atmosphere.wind_speed[0], + [2] = 0 + }; + + double wind2[3] = { + [0] = cos(270 - ctx->atmosphere.wind_dir * 30) + * ctx->atmosphere.wind_speed[1], + [1] = sin(270 - ctx->atmosphere.wind_dir * 30) + * ctx->atmosphere.wind_speed[1], + [2] = 0 + }; + + double wind_drift = 0.0; + + if (ace->ballistics->enabled) + ctx->gun.ballistic_coef + = atmospheric_correction( + ctx->gun.ballistic_coef, + ctx->atmosphere.temperature, + ctx->atmosphere.barometric_pressure, + ctx->atmosphere.relative_humidity, + ctx->atmosphere.atmosphere_model); + + double eoetvoes_multiplier = 0.0; + if (ace->ballistics->enabled) { + eoetvoes_multiplier = 2 + * (0.0000729 * ctx->gun.muzzle_velocity / -GRAVITY) + * cos(ctx->target.latitude) + * sin(ctx->target.direction); + } + + memcpy(bullet.pos, + (double[3]){0.0, + 0.0, + -(ctx->gun.bore_height / 100.0)}, + sizeof(bullet.pos)); + + memcpy(bullet.velocity, + (double[3]){0.0, + cos(ctx->gun.scope_angle) * ctx->gun.muzzle_velocity, + sin(ctx->gun.scope_angle) * ctx->gun.muzzle_velocity}, + sizeof(bullet.pos)); + + while (local_solution.time_of_flight < 15 + && bullet.pos[1] < ctx->target.range) { + // calculate magnitude of bullet.velocity + bullet.speed = hypot(bullet.velocity[0], + hypot(bullet.velocity[1], bullet.velocity[2])); + + + } + + return sln; +} diff --git a/src/ballistics.c b/src/ballistics.c new file mode 100644 index 0000000..10d97da --- /dev/null +++ b/src/ballistics.c @@ -0,0 +1,38 @@ +#include <math.h> + +#include "ballistics.h" +#include "constants.h" +#include "context.h" + +double atmospheric_correction(double ballistic_coefficient, + double temperature, + double pressure, + double relative_humidity, + AtmosphereModel atmosphere_model) { + double air_density = calculate_air_density(temperature, pressure, relative_humidity); + + if (atmosphere_model == ICAO) + return (STD_AIR_DENSITY_ICAO / air_density) * ballistic_coefficient; + else + return (STD_AIR_DENSITY_ASM / air_density) * ballistic_coefficient; +} + +double calculate_air_density(double temperature, + double pressure, + double relative_humidity) { + pressure = pressure * 100; + + if (relative_humidity > 0.0) { + double p_sat = 610.78 * pow(10, (7.5 * temperature - 273.15) / + (temperature - 273.15 + 237.3)); + double vapor_pressure = relative_humidity * p_sat; + double partial_pressure = pressure - vapor_pressure; + + return fma(partial_pressure, + DRY_AIR_MOLAR_MASS, + vapor_pressure * WATOR_VAPOR_MOLAR_MASS) + / (UNIVERSAL_GAS_CONSTANT * temperature); + } + else + return pressure / (SPECIFIC_GAST_CONSTANT_DRY_AIR * temperature); +} @@ -2,7 +2,9 @@ #include <stdlib.h> #include "context.h" +#include "atragmx.h" int main(int argc, char** argv) { printf("Hello, %s\n", argv[0]); + exit(EXIT_SUCCESS); } |
