stopToObstacle.cpp

障害物にて停止 (ログの使用例)

stopToObstacle_example.jpg

シミュレータによる実行結果

/*
  障害物にて停止 (ログの使用例)
  Satofumi KAMIMURA
  $Id$
*/

#include "mRunCtrl.h"
#include "mURGCtrl.h"
#include "vutils.h"
#include <stdlib.h>

enum {
  DangerAreaRadius = 600,
};

// 物体を検出したら停止する領域の円を描画
static void drawDangerZone(const Position& pos) {
  static unsigned long pre_box_index = 0;

  vmonitor::clear(pre_box_index);
  pre_box_index = vmonitor::drawCircle(pos, DangerAreaRadius, Blue);
}


// 測定データ、筐体位置の描画
static void drawInformation(mURGCtrl& urg, mRunCtrl& run, bool draw = true) {
  static TicksPosition ticksPos;
  static unsigned long pre_urg_index = 0;

  // 現在位置の取得、表示
  Position pos = run.getRunPosition();
  if (draw) {
    vmonitor::printf("position: %d, %d, %d[deg]\n",
                     pos.x, pos.y, pos.zt.to_deg());
  }
  ticksPos.add(run.crd_position, run.crd_ticks);

  // 判定領域の表示
  drawDangerZone(pos);

  // URG による周囲の情報を表示
  urg.convert(ticksPos);
  vmonitor::clear(pre_urg_index);
  pre_urg_index = vmonitor::drawPoints(urg.crd_points, White);

  ticksPos.del_olderThan(urg.crd_ticks - 5000);
}


// 筐体周辺に物体がなければ true を返す
static bool isSafeArea(mURGCtrl& urg, int radius) {
  static unsigned long pre_points_index = 0;

  int first = urg.rad2index(-60 * DEG2RAD);
  int last = urg.rad2index(+60 * DEG2RAD);
  int step = (last > first) ? +1 : -1;

  std::vector<Grid3D> points;
  bool safe = true;
  for (int i = first; i != last; i += step) {
    int length = urg.length[i];
    if ((length > 20) && (length < radius)) {
      safe = false;
      int x = static_cast<int>(length * cos(urg.index2rad(i) +
                                            urg.crd_position.zt.to_rad()));
      int y = static_cast<int>(length * sin(urg.index2rad(i) +
                                            urg.crd_position.zt.to_rad()));
      Grid3D p = Grid3D(urg.crd_position.x + x, urg.crd_position.y + y, 0);
      points.push_back(p);
    }
  }

  vmonitor::clear(pre_points_index);
  if (!points.empty()) {
    pre_points_index = vmonitor::drawPoints(points, Red);
  }
  return safe;
}


// URG データの更新
static bool captureUpdate(mURGCtrl& urg, mRunCtrl& run, bool draw = true) {
  if (urg.capture() <= 0) {
    return false;
  }

  drawInformation(urg, run, draw);
  return true;
}


// 到達目標の線を描画
static void drawGoal(int length) {
  vmonitor::drawLine(Grid(length, -1000), Grid(length, +1000), Red);
}


int main(int argc, char *argv[]) {
  try {
    mRunCtrl run;
    mURGCtrl urg;
    if ((initConnection(&run, argc, argv) < 0) ||
        (initConnection(&urg, argc, argv, true) < 0)) {
      exit(1);
    }
    urg.setOwnCrdToObject(&run);
    run.adjustSubTreeTicks(0);

    vmonitor::show();
    //vmonitor::setTimeMagnify(0.5);

    // 一定距離以上、直進して停止
    enum {
      MoveLength = 2000,
      ObstacleTimeout = 5000,
    };
    vmonitor::printf("go straight over %d [mm]\n", MoveLength);
    drawGoal(MoveLength);

    bool quit = false;
    run.followLine(Position(0, 0, deg(0)));
    while (!quit && run.getLengthToLine(Position(MoveLength, 0, deg(0))) < 0) {

      // 周囲の情報を取得、表示
      if (!captureUpdate(urg, run)) {
        break;
      }

      // 障害物があったら一時停止。ただしタイムアウトあり
      if (!isSafeArea(urg, DangerAreaRadius)) {
        // 現在の移動コマンドを待避
        run.push_runState();
        run.stop();

        vmonitor::printf("detect obstacle!!!\n");
        unsigned long ticks = vmonitor::getTicks();
        do {
          VXV::Delay(100);
          captureUpdate(urg, run, false);
          if (vmonitor::getTicks() - ticks > ObstacleTimeout) {
            vmonitor::printf("obstacle timeout\n");
            quit = true;
            break;
          }
        } while (!isSafeArea(urg, DangerAreaRadius));
        // 待避しておいた移動コマンドを復帰して実行
        run.pop_runState();
        run.lastMoveCommand();
      }
      VXV::Delay(100);
    }

    // 停止して終了
    vmonitor::printf("stop & quit\n");
    run.stop();
    VXV::Delay(1000);
    vmonitor::clear(3);

    VXV::Delay(1000);
  } catch (std::exception& e) {
    printf("exception: %s\n", e.what());
  }
  return 0;
}


Generated on Mon Apr 13 22:52:01 2009 by  doxygen 1.5.7.1