From f10041eac27fa51e56d19c8d2d0ccdc7fd878ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sat, 27 Jun 2009 16:11:53 +0200 Subject: [PATCH] scenario 2001 working --- ovm/CMakeLists.txt | 9 +++ ovm/task2.c | 191 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 ovm/task2.c diff --git a/ovm/CMakeLists.txt b/ovm/CMakeLists.txt index 79704b0..bab8f58 100644 --- a/ovm/CMakeLists.txt +++ b/ovm/CMakeLists.txt @@ -41,6 +41,12 @@ ADD_EXECUTABLE(task1 task.c trace.c ) +ADD_EXECUTABLE(task2 + bin2.c + task2.c + task.c trace.c +) + SET(WARN_FLAGS "-g -O2 -g2 -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Wsign-compare -Wnested-externs -Wpointer-arith -Wl,--as-needed") # -Werror -Wbad-function-cast -Wmissing-prototypes @@ -53,6 +59,9 @@ ADD_TARGET_PROPERTIES(ovmjit COMPILE_FLAGS ${COMMON_CFLAGS}) ADD_TARGET_PROPERTIES(task1 LINK_FLAGS -lm ${COMMON_LDFLAGS}) ADD_TARGET_PROPERTIES(task1 COMPILE_FLAGS ${COMMON_CFLAGS}) +ADD_TARGET_PROPERTIES(task2 LINK_FLAGS -lm ${COMMON_LDFLAGS}) +ADD_TARGET_PROPERTIES(task2 COMPILE_FLAGS ${COMMON_CFLAGS}) + IF(CMAKE_COMPILER_IS_GNUCC) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -g -Wshadow -W -pedantic") SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2") diff --git a/ovm/task2.c b/ovm/task2.c new file mode 100644 index 0000000..194b6e5 --- /dev/null +++ b/ovm/task2.c @@ -0,0 +1,191 @@ +#include "task_main.h" +#include "physics.h" + +#include + +/* +Output Ports: +Address Sensor +0x0 Score +0x1 Fuel Remaining +0x2 s_x Relative to Earth +0x3 s_y Relative to Earth +0x4 s_x Relative to target satellite +0x5 s_y Relative to target satellite +*/ + +#define SCORE (task->out[0]) +#define FUEL (task->out[1]) +#define S_X (-task->out[2]) +#define S_Y (-task->out[3]) +#define T_X (S_X + task->out[4]) +#define T_Y (S_Y + task->out[5]) +#define DISTANCE (sqrt(task->out[4]*task->out[4]+task->out[5]*task->out[5])) + +#define DV_X (task->in[2]) +#define DV_Y (task->in[3]) + +static const gdouble mu = G * Me; + +static void debug(task_t * task) { + printf( + "Step: %9"G_GUINT64_FORMAT" Score: %8.5f Fuel: %14.3f x: %14.3f y: %14.3f tx: %14.3f ty: %14.3f dist: %14.3f\n", + task->timestamp, SCORE, FUEL, S_X, S_Y, T_X, T_Y, DISTANCE); +} + +static int plot_sat, plot_target_sat; +static GString *plot_str; + +static void open_data_files(task_t *task) { + plot_str = g_string_sized_new(0); + g_string_printf(plot_str, "plot_task2_%u_sat.dat", (guint) task->scenario); + plot_sat = g_open(plot_str->str, O_CREAT | O_TRUNC | O_WRONLY, 0644); + g_string_printf(plot_str, "plot_task2_%u_target_sat.dat", (guint) task->scenario); + plot_target_sat = g_open(plot_str->str, O_CREAT | O_TRUNC | O_WRONLY, 0644); +} + +static void trace_data(task_t *task) { + g_string_printf(plot_str, "%14.3f %14.3f\n", S_X, S_Y); + write(plot_sat, GSTR_LEN(plot_str)); + g_string_printf(plot_str, "%14.3f %14.3f\n", T_X, T_Y); + write(plot_target_sat, GSTR_LEN(plot_str)); +} + +static void data_close() { + close(plot_sat); + close(plot_target_sat); + g_string_free(plot_str, TRUE); +} + +static void run(task_t *task, gpointer userdata) { + static satellite_t sat, target_sat; + static gdouble phi, target_v = 0.0; + static guint start_hohmann = 0; + static gdouble dv, dv_tic; + static gboolean reached = FALSE, outoffuel = FALSE; + + UNUSED(userdata); + + /* v^2/r == G*M_e/r^2 => v^2 = mu/r */ + /* T = s/v = 2*pi*r/sqrt(mu/r) = 2*pi*r3*sqrt(r3/mu) */ + /* T' = pi*sqrt((r1+r2)^3/(8*G*Me)) */ + + if (task->finished) { + debug(task); + data_close(); + } else if (0 == task->timestamp) { + open_data_files(task); + } + if (0 == task->timestamp || task->finished) return; + + DV_X = DV_Y = 0.0; + + if (10 == (task->timestamp % 32) && task->timestamp > start_hohmann && (task->timestamp - start_hohmann) < 7000) trace_data(task); + + satellite_update_pos(&sat, S_X, S_Y); + satellite_update_pos(&target_sat, T_X, T_Y); + + if (!reached) { + if (2 == task->timestamp) { + gdouble target_sat_T_half = M_PI*target_sat.rad*sqrt(target_sat.rad/(G*Me)); + gdouble sat_T_half = M_PI*sat.rad*sqrt(sat.rad/(G*Me)); + gdouble hohmann_T = M_PI*(target_sat.rad+sat.rad)*sqrt((target_sat.rad+sat.rad)/(8*G*Me)); + gdouble timediff = target_sat_T_half + hohmann_T; + gdouble starttime = timediff*sat_T_half/(target_sat_T_half - sat_T_half); + satellite_update_move(&sat); + target_v = sqrt(mu/target_sat.rad); + dv = sqrt(mu/sat.rad)*(sqrt(2*target_sat.rad/(sat.rad + target_sat.rad))-1); + dv_tic = sqrt(mu/target_sat.rad)*(1-sqrt(2*sat.rad/(sat.rad + target_sat.rad))); + phi = M_PI * timediff / target_sat_T_half; + start_hohmann = starttime ; + if (sat.move.v.x * S_Y > 0.0 && sat.move.v.y * S_X < 0.0) target_v = -target_v; + printf("Vorsprung für Target: %u (Winkel: %14.3f)\n", start_hohmann, (180.0*phi/M_PI)); +// printf("T: %14.3f\n", 2*M_PI*target_sat.rad*sqrt(target_sat.rad/(G*Me))); + } else if (start_hohmann == task->timestamp) { + satellite_update_move(&sat); + DV_X = sat.move.v.x * (dv / sat.move.v_abs); + DV_Y = sat.move.v.y * (dv / sat.move.v_abs); + printf("-- Leaving initial orbit at %u\n", (guint) task->timestamp); + printf("-- Radius difference: %14.3f\n", fabs(atan2(S_Y, S_X) - atan2(T_Y, T_X))*180.0/M_PI); + debug(task); + printf("v: %f / %f\n", sat.move.v.x, sat.move.v.y); + printf("Dv: %f / %f\n", DV_X, DV_Y); + } else if (start_hohmann < task->timestamp) { + if (sat.rad +2.0 >= target_sat.rad) { + satellite_update_move(&sat); + debug(task); + reached = TRUE; + DV_X = sat.move.v.x * (dv_tic / sat.move.v_abs); + DV_Y = sat.move.v.y * (dv_tic / sat.move.v_abs); + printf("-- Reached target orbit at %u, distance: %14.3f\n", (guint) task->timestamp, DISTANCE); + printf("v: %f / %f\n", sat.move.v.x, sat.move.v.y); + printf("Dv: %f / %f\n", DV_X, DV_Y); + } + } +#if 0 + } else if (DISTANCE > 400) { + gdouble dx = task->out[4], dy = task->out[5]; +#endif +#if 0 + } else if (DISTANCE > 500.0) { + gdouble phidiff = 180.0*(atan2(S_Y, S_X) - atan2(T_Y, T_X))/M_PI; + gdouble target_rad = target_sat.rad - sat.rad; +/* gdouble tar_dv_x = -target_v * S_Y / sat.rad; + gdouble tar_dv_y = target_v * S_X / sat.rad;*/ + satellite_update_move(&sat); + printf("Distance: %14.3f\n", phidiff); + if (phidiff < 0 || phidiff > 180.0) { /* slow down */ + target_rad += 20.0; + } else { /* speed up */ + target_rad -= 20.0; + } + target_rad = fmax(-5.0, fmin(5.0, target_rad)); + DV_X = /*tar_dv_x - sat.move.v.x*/ + target_rad * S_X / sat.rad; + DV_Y = /*tar_dv_y - sat.move.v.y*/ + target_rad * S_Y / sat.rad; + printf("v: %f / %f\n", sat.move.v.x, sat.move.v.y); + printf("Dv: %f / %f\n", DV_X, DV_Y); + debug(task); +#endif + } else if (!outoffuel) { + satellite_update_move(&sat); + if (FALSE && fabs(sat.rad - target_sat.rad) > 3) { + gdouble tar_dv_x = -target_v * S_Y / sat.rad; + gdouble tar_dv_y = target_v * S_X / sat.rad; + gdouble target_rad = target_sat.rad - sat.rad; + target_rad = fmax(-10.0, fmin(10.0, target_rad)); + DV_X = tar_dv_x - sat.move.v.x + target_rad * S_X / sat.rad; + DV_Y = tar_dv_y - sat.move.v.y + target_rad * S_Y / sat.rad; + printf("-- orbit correction\n"); + printf("v: %f / %f\n", sat.move.v.x, sat.move.v.y); + printf("Dv: %f / %f\n", DV_X, DV_Y); + } else { + /* target_v is clockwise */ + gdouble tar_dv_x = -target_v * S_Y / sat.rad; + gdouble tar_dv_y = target_v * S_X / sat.rad; + DV_X = tar_dv_x - sat.move.v.x; + DV_Y = tar_dv_y - sat.move.v.y; + } + if (DV_X*DV_X + DV_Y*DV_Y > FUEL*FUEL) { + printf("-- Out of fuel\n"); + printf("v: %f / %f\n", sat.move.v.x, sat.move.v.y); + printf("Dv: %f / %f\n", DV_X, DV_Y); + DV_X = 0.0; DV_Y = 0.0; + outoffuel = TRUE; + } + } + + if (fabs(DV_X) < 0.1) DV_X = 0.0; + if (fabs(DV_Y) < 0.1) DV_Y = 0.0; + + sat.dv.x = DV_X; sat.dv.y = DV_Y; +} + +static void run_debug(task_t *task, gpointer userdata) { + debug(task); + run(task, userdata); +} + +int main(int argc, char **argv) { + task_main(argc, argv, run, run_debug, NULL, 2001); + return 0; +}