#ifndef _CONTROL_H #define _CONTROL_H #include "config.h" #include #include #include #include #define INLINE static inline #define UNUSED(x) ((void)(x)) #define VEHICLE_RADIUS 0.5 #define HOMEBASE_RADIUS 5 #define MARTIAN_RADIUS 0.4 typedef enum { RUN_ERROR, RUN_DONE, RUN_GO_ON, RUN_FINISHED } run_t; typedef enum { ACCEL, ROLL, BRAKE } accel_t; typedef enum { TURN_HARD_LEFT, TURN_LEFT, TURN_STRAIGHT, TURN_RIGHT, TURN_HARD_RIGHT } turn_t; typedef enum { BOLDER, CRATER, MARTIAN } object_t; struct object; typedef struct object object; struct vehicle; typedef struct vehicle vehicle; struct telemetry; typedef struct telemetry telemetry; struct simulated; typedef struct simulated simulated; struct map; typedef struct map map; struct trial; typedef struct trial trial; typedef unsigned int timestamp; #include "control_parser.h" struct object { object_t type; double x, y, rad; double dir, speed; }; struct vehicle { accel_t accel; turn_t turn; double x, y; double dir, speed; }; struct telemetry { timestamp ts; vehicle vehicle; GArray *objects; }; struct map { float dx, dy; timestamp limit; float min_sensor, max_sensor; float max_speed, max_turn, max_hard_turn; GHashTable *solid_objects; }; struct simulated { telemetry tm; guint steps; }; struct trial { map map; timestamp last_ts; GQueue telemetry; vehicle vehicle; int alive, finished; simulated sim; int runcnt; /* internal */ struct timeval started; int socket; control_parser_ctx *parse_ctx; }; /* extern */ void simulate(trial *t, timestamp ts); void godown(trial *t); void goradar(trial *t); /* trial */ trial *trial_new(const char *hostname, const char *port); void trial_reset_run(trial *t); int trial_wait_for_start(trial *t); int trial_check_input(trial *t); int trial_wait_for_input(trial *t); void trial_free(trial *t); object* object_new(object_t type, double x, double y, double rad, double dir, double speed); /* debugging stuff */ void object_print(object *o); void vehicle_print(vehicle *v); void telemetry_print(telemetry *t); void trial_print(trial *t); void trial_matlab(trial *t); void map_print(map *m); INLINE void vehicle_accel(trial *t); INLINE void vehicle_roll(trial *t); INLINE void vehicle_break(trial *t); INLINE void vehicle_hard_left(trial *t); INLINE void vehicle_left(trial *t); INLINE void vehicle_straight(trial *t); INLINE void vehicle_right(trial *t); INLINE void vehicle_hard_right(trial *t); INLINE timestamp getcurts(trial *t); /* needed by parser */ telemetry* telemetry_new(); /* Inline functions */ #define SENDCMD(t, cmd) do { \ write(t->socket, cmd, sizeof(cmd)-1); \ /* write(1, cmd, sizeof(cmd)-1); */ \ } while(0) INLINE void vehicle_accel(trial *t) { switch (t->vehicle.accel) { case ACCEL: return; case ROLL: SENDCMD(t, "a;"); break; case BRAKE: SENDCMD(t, "a;a;"); break; } t->vehicle.accel = ACCEL; } INLINE void vehicle_roll(trial *t) { switch (t->vehicle.accel) { case ACCEL: SENDCMD(t, "b;"); break; case ROLL: return; case BRAKE: SENDCMD(t, "a;"); break; } t->vehicle.accel = ROLL; } INLINE void vehicle_break(trial *t) { switch (t->vehicle.accel) { case ACCEL: SENDCMD(t, "b;b;"); break; case ROLL: SENDCMD(t, "b;"); break; case BRAKE: return; } t->vehicle.accel = BRAKE; } INLINE void vehicle_hard_left(trial *t) { switch (t->vehicle.turn) { case TURN_HARD_LEFT: return; case TURN_LEFT: SENDCMD(t, "l;"); break; case TURN_STRAIGHT: SENDCMD(t, "l;l;"); break; case TURN_RIGHT: SENDCMD(t, "l;l;l;"); break; case TURN_HARD_RIGHT: SENDCMD(t, "l;l;l;l;"); break; } t->vehicle.turn = TURN_HARD_LEFT; } INLINE void vehicle_left(trial *t) { switch (t->vehicle.turn) { case TURN_HARD_LEFT: SENDCMD(t, "r;"); break; case TURN_LEFT: return; case TURN_STRAIGHT: SENDCMD(t, "l;"); break; case TURN_RIGHT: SENDCMD(t, "l;l;"); break; case TURN_HARD_RIGHT: SENDCMD(t, "l;l;l;"); break; } t->vehicle.turn = TURN_LEFT; } INLINE void vehicle_straight(trial *t) { switch (t->vehicle.turn) { case TURN_HARD_LEFT: SENDCMD(t, "r;r;"); break; case TURN_LEFT: SENDCMD(t, "r;"); break; case TURN_STRAIGHT: return; case TURN_RIGHT: SENDCMD(t, "l;"); break; case TURN_HARD_RIGHT: SENDCMD(t, "l;l;"); break; } t->vehicle.turn = TURN_STRAIGHT; } INLINE void vehicle_right(trial *t) { switch (t->vehicle.turn) { case TURN_HARD_LEFT: SENDCMD(t, "r;r;r;"); break; case TURN_LEFT: SENDCMD(t, "r;r;"); break; case TURN_STRAIGHT: SENDCMD(t, "r;"); break; case TURN_RIGHT: return; case TURN_HARD_RIGHT: SENDCMD(t, "l;"); break; } t->vehicle.turn = TURN_RIGHT; } INLINE void vehicle_hard_right(trial *t) { switch (t->vehicle.turn) { case TURN_HARD_LEFT: SENDCMD(t, "r;r;r;r;"); break; case TURN_LEFT: SENDCMD(t, "r;r;r;"); break; case TURN_STRAIGHT: SENDCMD(t, "r;r;"); break; case TURN_RIGHT: SENDCMD(t, "r;"); break; case TURN_HARD_RIGHT: return; } t->vehicle.turn = TURN_HARD_RIGHT; } INLINE timestamp getcurts(trial *t) { struct timeval tv; gettimeofday(&tv, NULL); timestamp ts = (tv.tv_sec - t->started.tv_sec) * 1000 + (tv.tv_usec - t->started.tv_usec) / 1000; // printf("Timestamp: %u\n", ts); return ts; } #endif