Exemple #1
0
int main(int argc, char * argv[])
{
    struct playfield * field = malloc(HEIGHT * WIDTH *
                                      sizeof(struct playfield));

    struct player pl[4];
    struct monster mons[MONSTERS];
    struct bomb bm[(3 * WIDTH * HEIGHT) / 4];
    struct controller_handle * ch;
    struct command cmd;
    struct bl_timer * timer;
    int frame = 0;
    int n_bombs = 0;
    int n_monsters = MONSTERS;
    int mx[4], my[4];
    int last_ctype = 0;
    int p = 0;
    int i, j, k, l;

    ch = open_controller(CONTROLLER_TYPE_STDIN);

    if (!ch) {
        fprintf(stderr, "No joysticks/controllers found.\n");
        return -1;
    }

    srand(time(NULL));

    for (i=0; i<PLAYERS; i++) {
        mx[i] = 0;
        my[i] = 0;
        pl[i].fire = BEGIN_FIRE;
        pl[i].max_bombs = BEGIN_BOMBS;
        pl[i].cur_bombs = 0;
        pl[i].has_red_bombs = 0;
        pl[i].alive = 1;
        pl[i].last_move = 0;
    }

    for (i=0; i<MONSTERS; i++) {
        mons[i].x = WIDTH-1;
        mons[i].y = 0;
        mons[i].speed = 10;
        mons[i].alive = 1;
    }

    pl[0].x = 0;
    pl[0].y = 0;
    pl[1].x = WIDTH - 1 - ((WIDTH+1) % 2);
    pl[1].y = HEIGHT - 1;
    pl[2].x = WIDTH - 1 - ((WIDTH+1) % 2);
    pl[2].y = 0;
    pl[3].x = ((HEIGHT+1) % 2);
    pl[3].y = HEIGHT - 1;

    populate_playfield(field, mons, n_monsters);

    timer = bl_timer_create();

    while(1) {
        cmd = read_command(ch, DELAY);

        if (cmd.controller >= 0)
            p = cmd.controller;

        if ((cmd.type == 2 && cmd.number == KEY_QUIT) ||
            (cmd.type == IN_TYPE_STDIN && cmd.number == KEY_QUIT_K))
            goto exit;

        if (cmd.type > 0)
            last_ctype = cmd.type;

        if (cmd.controller >= 0) {
            switch (cmd.number) {
            case KEY_UP_K1:
            case KEY_UP_K2:
            case KEY_UP:
                if (cmd.value > 0) {
                    mx[p] = 0;
                    my[p] = -1;
                } else {
                    mx[p] = 0;
                    my[p] = 0;
                    pl[p].last_move = 0;
                }
                break;
            case KEY_DOWN_K1:
            case KEY_DOWN_K2:
            case KEY_DOWN:
                if (cmd.value > 0) {
                    mx[p] = 0;
                    my[p] = 1;
                } else {
                    mx[p] = 0;
                    my[p] = 0;
                    pl[p].last_move = 0;
                }
                break;
            case KEY_LEFT_K1:
            case KEY_LEFT_K2:
            case KEY_LEFT:
                if (cmd.value > 0) {
                    mx[p] = -1;
                    my[p] = 0;
                } else {
                    mx[p] = 0;
                    my[p] = 0;
                    pl[p].last_move = 0;
                }
                break;
            case KEY_RIGHT_K1:
            case KEY_RIGHT_K2:
            case KEY_RIGHT:
                if (cmd.value > 0) {
                    mx[p] = 1;
                    my[p] = 0;
                } else {
                    mx[p] = 0;
                    my[p] = 0;
                    pl[p].last_move = 0;
                }
                break;
            case KEY_B1_K1:
            case KEY_B1_K2:
            case KEY_B1:
                if (pl[p].alive && pl[p].cur_bombs < pl[p].max_bombs &&
                    !is_bomb(pl[p].x, pl[p].y, bm, n_bombs)) {
                    bm[n_bombs].x = pl[p].x;
                    bm[n_bombs].y = pl[p].y;
                    bm[n_bombs].ticks = DEFAULT_BOMB_TICKS;
                    bm[n_bombs].is_red = pl[p].has_red_bombs;
                    bm[n_bombs].length = pl[p].fire;
                    bm[n_bombs].max_length[0] = bm[n_bombs].length;
                    bm[n_bombs].max_length[1] = bm[n_bombs].length;
                    bm[n_bombs].max_length[2] = bm[n_bombs].length;
                    bm[n_bombs].max_length[3] = bm[n_bombs].length;
                    bm[n_bombs].current_length = 0;
                    bm[n_bombs].from_player = p;
                    pl[p].cur_bombs++;
                    n_bombs++;
                }
                break;
            default:
                break;     
            }
        }

        if (bl_timer_elapsed(timer) > DELAY) {

            for (i=0; i<n_monsters; i++) {
                if (frame % mons[i].speed == 0) {
                    int dx, dy, nx, ny, npos;
                    int dir = rand() % 4;
                    npos = get_newpos_from_i(mons[i].x, mons[i].y, &dx, &dy, dir);
                    nx = mons[i].x + dx;
                    ny = mons[i].y + dy;
                    if (nx >= 0 && nx < WIDTH &&
                        ny >= 0 && ny < HEIGHT &&
                        field[npos].type == FIELD_TYPE_EMPTY) {
                        if (!is_bomb(nx, ny, bm, n_bombs)) {
                            mons[i].x = nx;
                            mons[i].y = ny;
                        }
                    }
                }
            }

            for (i=0; i<PLAYERS; i++) {
                if (frame > pl[i].last_move + 1) {
                    int nx, ny, npos;
                    nx = pl[i].x + mx[i];
                    ny = pl[i].y + my[i];
                    npos = ny * WIDTH + nx;
                    if (nx >= 0 && nx < WIDTH &&
                        ny >= 0 && ny < HEIGHT &&
                        field[npos].type == FIELD_TYPE_EMPTY) {
                        if (!is_bomb(nx, ny, bm, n_bombs)) {
                            if (pl[i].alive &&
                                field[npos].special != FIELD_SPECIAL_NONE) {
                                switch (field[npos].special) {
                                case FIELD_SPECIAL_FIRE:
                                    pl[i].fire++;
                                    break;
                                case FIELD_SPECIAL_BOMB:
                                    pl[i].max_bombs++;
                                    break;
                                case FIELD_SPECIAL_RED:
                                    pl[i].has_red_bombs = 1;
                                    break;
                                default:
                                    break;
                                }
                                field[npos].special = FIELD_SPECIAL_NONE;
                            }

                            pl[i].x = nx;
                            pl[i].y = ny;
                        }
                    }
                    if (mx[i] != 0 || my[i] != 0) {
                        pl[i].last_move = frame;
                    }
                }
            }

            for (i=0; i<n_bombs; i++) {
                if (bm[i].current_length == bm[i].length) {
                    pl[bm[i].from_player].cur_bombs--;
                    n_bombs--;
                    for (j=i; j<n_bombs; j++) {
                        bm[j] = bm[j+1];
                    }
                }
            }

            for (i=0; i<n_bombs; i++)
            {
                if (bm[i].ticks == 0) {
                    if (bm[i].current_length < bm[i].length) {
                        bm[i].current_length++;
                    }
                } else {
                    if (frame % 3 == 0) {
                        bm[i].ticks--;
#ifdef RUMBLE
                        if (bm[i].ticks == 0) {
                            for (j=0; j<PLAYERS; j++) {
                                double power;
                                double dist = sqrt(pow((bm[i].x - pl[j].x), 2) +
                                                   pow((bm[i].y - pl[j].y), 2));
                                power = dist / MAX_DISTANCE;
                                if (power > 0.2) {
                                    joyrumble(j+1, 100, 100, 500);
                                }
                            }
                        }
#endif
                    }
                }

                if (bm[i].ticks == 0)
                {
                    for (j=0; j<4; j++) {
                        int dx, dy;
                        int pos = get_newpos_from_i(bm[i].x, bm[i].y, &dx, &dy, j);
                        if (field[pos].type != FIELD_TYPE_HARDWALL) {
                            for (k=0; k<bm[i].current_length; k++) {
                                int nx = bm[i].x + k * dx;
                                int ny = bm[i].y + k * dy;
                                if (nx >= 0 && nx < WIDTH &&
                                    ny >= 0 && ny < HEIGHT) {
                                    int npos = ny * WIDTH + nx;

                                    if (k >= bm[i].max_length[j])
                                        break;

                                    if (!bm[i].is_red &&
                                        field[npos].type == FIELD_TYPE_WALL) {
                                        bm[i].max_length[j] = k + 1;
                                    }

                                    for (l=0; l<PLAYERS; l++) {
                                        if (pl[l].x == nx && pl[l].y == ny) {
                                            pl[l].alive = 0;
                                        }
                                    }
                                    for (l=0; l<n_monsters; l++) {
                                        if (mons[l].x == nx && mons[l].y == ny) {
                                            mons[l].alive = 0;
                                        }
                                    }
                                    for (l=0; l<n_bombs; l++)
                                    {
                                        if (bm[l].x == nx && bm[l].y == ny &&
                                            bm[l].ticks > 1) {
                                            bm[l].ticks = 1;
                                        }
                                    }

                                    if (field[npos].type == FIELD_TYPE_EMPTY &&
                                        k == bm[i].current_length - 1) {
                                        field[npos].special = FIELD_SPECIAL_NONE;
                                    }
                                    field[npos].type = FIELD_TYPE_EMPTY;
                                }
                            }
                        }
                    }
                }
            }

            for (i=0; i<n_monsters; i++) {
                for (j=0; j<PLAYERS;j++) {
                    if (mons[i].alive &&
                        mons[i].x == pl[j].x &&
                        mons[i].y == pl[j].y)
                    {
                        pl[j].alive = 0;
                    }
                }
            }

            draw_field(field, pl, bm, n_bombs, mons, n_monsters);
            frame++;
            bl_timer_start(timer);

            if (last_ctype == IN_TYPE_STDIN) {
                mx[p] = 0;
                my[p] = 0;
                pl[p].last_move = 0;
            }
            last_ctype = 0;
        }
    }

exit:
    free(field);
    close_controller(ch);

    return 0;
}
int main(void) {

  InitPeripherals();
  mRedOFF; mGreenOFF; mBlueOFF;

  // startup blink
  const float kShortDelay = 0.1;
  const float kLongDelay = 0.3;
  mRedON; mGreenON; mBlueON;
  DelaySeconds(kShortDelay);
  mRedOFF; mGreenOFF; mBlueOFF;
  DelaySeconds(kLongDelay);
  mRedON; mGreenON; mBlueON;
  DelaySeconds(kShortDelay);
  mRedOFF; mGreenOFF; mBlueOFF;
  DelaySeconds(kLongDelay);
  mRedON; mGreenON; mBlueON;
  DelaySeconds(kShortDelay);
  mRedOFF; mGreenOFF; mBlueOFF;
  DelaySeconds(kLongDelay);

  UsbInterface usb = UsbInterface();
  usb.Init();

  PersistentMemory mem;

  DelaySeconds(1.0f);
  ZigbeeInterface zig = ZigbeeInterface();
  DelaySeconds(0.05f);
  zig.Init(mem);

  error_reporting_com1 = &usb;
  error_reporting_com2 = &zig;

  Mpu60XXImu imu(mem);
  GyroAccelDriftUkfIo est;

  BatteryMonitor battery(mem);
  battery_ptr = &battery;

  MotorHal motor_hal(mem);
  motor_hal_ptr = &motor_hal;

  // Get_pos addition:
  InitPositionSensor();
  tim1_set_position_callback_2(get_position);
  QuatPD pd(mem);
  PulsingCoaxControllerQuat uav(mem, pd, imu, est, motor_hal);

  CoaxOpenController open_controller(mem);
  CoaxOpenAttitudeController open_attitude_controller(mem, est);

  monitor = LoopMonitor(mem);
  UavReporter reporter(mem, imu, est, motor_hal, battery, uav, open_attitude_controller, pd, monitor);
  StateMachine state_machine;

  mem.Freeze();  // freeze memory to make writes possible

  imu.InitFromMemory();
  //imu.DefaultAccelSensitivity(1); // overwrite scale for off-datasheet fix
  imu.flip_z = 1;                   // flip z-axis direction for upside-down imu

  #ifdef STREAM_IMU_RAW
    imu_raw_msg_logger_init(imu);
  #endif

  monitor.InitFromMemory();

  PlayTimebase();
  imu.StartRead();
  DelayMilliseconds(10);

  tim1_init();
  tim1_set_supply_volts(3.7f);

  //////////////////////////////////////////////////////////////////////////////
  // Main Loop
  while(1) {
                                                                                monitor.Profile(0);
    ////////////////////////////////////////////////////////////////////////////
    // Get IMU Data and Start New Measurement
    while(!imu.FinishRead()) {};
    #ifdef STREAM_IMU_RAW
      imu_raw_msg_logger_push();
    #endif
    DelayMicroseconds(50); // this seems to be critical (?!?)
    imu.StartRead();
                                                                                monitor.Profile(1);
    ////////////////////////////////////////////////////////////////////////////
    // Update Estimator with Measurement
    est.Update(imu.time, imu.w, imu.a);

    ////////////////////////////////////////////////////////////////////////////
    // Control                                                                             

    // update control laws
    uav.Update();
    open_controller.Update();
    open_attitude_controller.Update();

    // map controllers to outputs based on state
    enum control_state state = state_machine.get_state();

    // in STOP state, send active kill messages to motors
    if(state == kStop) {
      mGreenOFF; mAmberON;
      motor_hal.set_top_cmd_volts(0);
      motor_hal.set_top_cmd_volts_pulse_amp(0);
      motor_hal.set_top_cmd_pulse_phase(0);
      motor_hal.set_bottom_cmd_volts(0);
    }

    // in STANDBY state, send no motor commands except on entry
    else if(state == kStandby) {
      mGreenOFF; mAmberOFF;
      if(state_machine.get_standby_needs_init()) {
        motor_hal.set_top_cmd_volts(0);
        motor_hal.set_top_cmd_volts_pulse_amp(0);
        motor_hal.set_top_cmd_pulse_phase(0);
        motor_hal.set_bottom_cmd_volts(0);
        state_machine.clear_standby_needs_init();
      }
    }

    // in QUAT state, send motor commands according to quat control law
    else if(state == kQuat) {
      mGreenON; mAmberOFF;
      motor_hal.set_top_cmd_volts(uav.top_mean);
      motor_hal.set_top_cmd_volts_pulse_amp(uav.top_pulse_amp);
      motor_hal.set_top_cmd_pulse_phase(uav.top_pulse_phase);
      motor_hal.set_bottom_cmd_volts(uav.bottom_mean);
    }

    // in OPEN state, send motor command according to open motor control commands
    else if(state == kOpen) {
      mGreenON; mAmberOFF;
      motor_hal.set_top_cmd_volts(open_controller.top_mean);
      motor_hal.set_top_cmd_volts_pulse_amp(open_controller.top_pulse_amp);
      motor_hal.set_top_cmd_pulse_phase(open_controller.top_pulse_phase);
      motor_hal.set_bottom_cmd_volts(open_controller.bottom_mean);
    }

    // in OPEN ATTITUDE state, send motor command according to open motor control commands
    else if(state == kOpenAttitude) {
      mGreenON; mAmberOFF;
      motor_hal.set_top_cmd_volts(open_attitude_controller.top_mean);
      motor_hal.set_top_cmd_volts_pulse_amp(open_attitude_controller.top_pulse_amp);
      motor_hal.set_top_cmd_pulse_phase(open_attitude_controller.top_pulse_phase);
      motor_hal.set_bottom_cmd_volts(open_attitude_controller.bottom_mean);
    }
                                                                                monitor.Profile(2);
    ////////////////////////////////////////////////////////////////////////////
    // Packet Communication
    uint8_t is_data;    // 1 iff data received
    uint8_t *rx_data;   // temporary pointer to received type+data bytes
    uint8_t rx_length;  // number of received type+data bytes

    ////////////////////////////////////////////////////////////////////////////
    // USB Input
    is_data = 0;
    usb.GetBytes();
    while(usb.PeekPacket(&rx_data, &rx_length)) {
      zig.ReadMsg(usb, rx_data, rx_length);
      imu.ReadMsg(usb, rx_data, rx_length);
      est.ReadMsg(usb, rx_data, rx_length);
      mem.ReadMsg(usb, rx_data, rx_length);
      uav.ReadMsg(usb, rx_data, rx_length);
      open_controller.ReadMsg(          usb, rx_data, rx_length);
      open_attitude_controller.ReadMsg( usb, rx_data, rx_length);
      pd.ReadMsg(       usb, rx_data, rx_length);
      monitor.ReadMsg(  usb, rx_data, rx_length);
      motor_hal.ReadMsg(usb, rx_data, rx_length);
      battery.ReadMsg(  usb, rx_data, rx_length);
      reporter.ReadMsg( usb, rx_data, rx_length);
      state_machine.ReadMsg(usb, rx_data, rx_length);
      usb.DropPacket();
      is_data = 1;
    } // while peek...
    if(is_data) {
      usb.SendNow();
    }

    ////////////////////////////////////////////////////////////////////////////
    // Radio Input
    is_data = 0;
    zig.GetBytes();
    while(zig.PeekPacket(&rx_data, &rx_length)) {
      #ifdef STREAM_IMU_RAW
        if(rx_data[0] == kTypeQuatPilot || rx_data[0] == kTypeQuatFullObsPilot || rx_data[0] == kTypeOpenPilot || rx_data[0] == kTypeOpenAttitudePilot) {
          imu_raw_msg_logger_send(zig);
        }
      #endif

      zig.ReadMsg(zig, rx_data, rx_length);
      imu.ReadMsg(zig, rx_data, rx_length);
      est.ReadMsg(zig, rx_data, rx_length);
      mem.ReadMsg(zig, rx_data, rx_length);
      uav.ReadMsg(zig, rx_data, rx_length);
      open_controller.ReadMsg(          zig, rx_data, rx_length);
      open_attitude_controller.ReadMsg( zig, rx_data, rx_length);
      pd.ReadMsg(       zig, rx_data, rx_length);
      monitor.ReadMsg(  zig, rx_data, rx_length);
      motor_hal.ReadMsg(zig, rx_data, rx_length);
      battery.ReadMsg(  zig, rx_data, rx_length);
      reporter.ReadMsg( zig, rx_data, rx_length);
      state_machine.ReadMsg(zig, rx_data, rx_length);
      zig.DropPacket();
      is_data = 1;
    } // while peek...
                                                                                monitor.Profile(3);
    if(is_data) {
      zig.SendNow();
    }
                                                                                monitor.Profile(4);
                                                                                monitor.Profile(5);
    ////////////////////////////////////////////////////////////////////////////    
    // Throttle main loop to main_freq
    monitor.EndMainLoop();
                                                                                monitor.Profile(6);
                                                                                //monitor.SendProfile(usb);
                                                                                //usb.SendNow();
  } // while(1)
  return(0);
}
Exemple #3
0
int main(int argc, char * argv[]) {
    struct coord snake[DISP_SIZE];
    struct coord dir;
    struct coord food;
    struct controller_handle * ch;
    struct command cmd;
    struct bl_timer * timer;
    struct snake_config conf;

    int i;
    int snake_length;

    int cmd_queue[CMD_QUEUE_SIZE];
    int cmdq_read = 0;
    int cmdq_write = 0;
    int cmdq_last = 0;
    int n_cmdq = 0;

    conf.delay = 100000;
    conf.rotate_x = 0;
    conf.rotate_y = 0;

    // Read configuration
    if (!read_config(config_handler, &conf, "snake")) {
        fprintf(stderr, "Error reading configuration\n");
        return 1;
    }

    srand (time(NULL));

    memset(snake, 0, DISP_SIZE * sizeof(struct coord));

    snake[0].x = WIDTH / 2;
    snake[0].y = HEIGHT / 2;
    snake[0].x = WIDTH / 2 + 1;
    snake[0].y = HEIGHT / 2;
    snake_length = 2;

    dir.x = -1;
    dir.y = 0;

    food = new_food(snake, snake_length);

    ch = open_controller(CONTROLLER_TYPE_JOYSTICK |
                         CONTROLLER_TYPE_STDIN);
    if (!ch) {
        fprintf(stderr, "No joysticks/controllers found.\n");
        return -1;
    }

    timer = bl_timer_create();

    while(1) {
        int n_wait = conf.delay - bl_timer_elapsed(timer);
        if (n_wait < 1)
            n_wait = 1;

        cmd = read_command(ch, n_wait);

        if (((cmd.number >= 'a' && cmd.number <= 'w') ||
            (cmd.number >= 8 && cmd.number <= 11)) &&
            cmd.number != cmdq_last &&
            (cmd.value == 1 || cmd.value > 10000) &&
            !n_cmdq < CMD_QUEUE_SIZE) {
            fprintf(stderr, "Cmd: %d\r\n", cmd.number);

            cmd_queue[cmdq_write++ % CMD_QUEUE_SIZE] =
                cmd.number;
            n_cmdq++;
            cmdq_last = cmd.number;
        }

        if (bl_timer_elapsed(timer) < conf.delay)
            continue;

        if (n_cmdq > 0) {
            switch(cmd_queue[cmdq_read++ % CMD_QUEUE_SIZE]) {
            case KEY_UP:
            case KEY_UP_K1:
                if (dir.y == 0) {
                    dir.x = 0;
                    dir.y = -1;
                }
                break;
            case KEY_DOWN:
            case KEY_DOWN_K1:
                if (dir.y == 0) {
                    dir.x = 0;
                    dir.y = 1;
                }
                break;
            case KEY_LEFT:
            case KEY_LEFT_K1:
                if (dir.x == 0) {
                    dir.x = -1;
                    dir.y = 0;
                }
                break;
            case KEY_RIGHT:
            case KEY_RIGHT_K1:
                if (dir.x == 0) {
                    dir.x = 1;
                    dir.y = 0;
                }
                break;
            case KEY_QUIT:
            case KEY_QUIT_K:
                goto exit;
            default:
                break;
            }

            n_cmdq--;
        }

        if (snake[0].x == food.x &&
            snake[0].y == food.y) {
            snake_length++;
            snake[snake_length] = snake[snake_length-1];
            food = new_food(snake, snake_length);
        }

        for (i=snake_length-1; i>=1; --i)
            snake[i] = snake[i-1];
        snake[0].x += dir.x;
        snake[0].y += dir.y;

        if (conf.rotate_x) {
            if (snake[0].x < 0)
                snake[0].x = WIDTH - 1;
            else if (snake[0].x >= WIDTH)
                snake[0].x = 0;
        }

        if (conf.rotate_y) {
            if (snake[0].y < 0)
                snake[0].y = HEIGHT - 1;
            else if (snake[0].y >= HEIGHT)
                snake[0].y = 0;
        }

        if (snake[0].x < 0 || snake[0].x >= WIDTH ||
            snake[0].y < 0 || snake[0].y >= HEIGHT) {
            fprintf(stderr, "Wand du trottel\n\r");
            goto exit;
        }

        for (i=1; i<snake_length; ++i) {
            if (snake[0].x == snake[i].x &&
                snake[0].y == snake[i].y) {
                fprintf(stderr, "Nom nom nom\n\r");
                goto exit;
            }
        }

        send_field(snake, snake_length, food);
        paint_field(snake, snake_length, food);

        bl_timer_start(timer);
    }

exit:
    bl_timer_free(timer);
    close_controller(ch);
    return 0;

}