#ifndef _CONTROL_H #define _CONTROL_H #include "config.h" #include #include #include #define INLINE static inline #define UNUSED(x) ((void)(x)) typedef enum { RUN_ERROR, RUN_DONE, RUN_GO_ON, RUN_FINISHED } run_t; typedef enum { ACCEL, ROLL, BREAK } 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 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; GArray *solid_objects; }; struct trial { map map; timestamp last_ts; GQueue telemetry; vehicle vehicle; /* our view */ int alive, finished; struct timeval started; /* internal */ int socket; control_parser_ctx *parse_ctx; }; /* 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); /* debugging stuff */ void object_print(object *o); void vehicle_print(vehicle *v); void telemetry_print(telemetry *t); void trial_print(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) write(t->socket, cmd, sizeof(cmd)-1) INLINE void vehicle_accel(trial *t) { switch (t->vehicle.accel) { case ACCEL: return; case ROLL: SENDCMD(t, "a;"); break; case BREAK: 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 BREAK: 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 BREAK: return; } t->vehicle.accel = BREAK; } 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); return (tv.tv_sec - t->started.tv_sec) * 1000 + (tv.tv_usec - t->started.tv_sec) / 1000; } #endif