0
0

More than 1 year has passed since last update.

クラシックマウス 作ってみた その7 座標の設定

Posted at

はじめに

  • 作成したクラシックマウスの解説。
  • 今回はプログラムを作るにあたって、座標の設定など。
  • 機体写真、動画などは「その1」をご参照。

座標など

プログラムを作るにあたって、以下の情報の設定を行った。独学なので非効率な部分や間違いがあるかもしれません。

  • 区画(場所)
  • 壁情報
  • 機体の向き
  • 歩数情報
    これらの情報をもとに、機体をコントロールしています。

区画(場所)

  • いろいろ試したのですが、16x16の迷路の左下からスタートするとして、左上隅を(0,0)、右下隅を(15,15)としています。(縦=行、横=列)としているので、スタート位置は(15,0)となります。ゴールは(7,7)(7,8)(8,7)(8,8)の4つです。
  • プログラム上はサイズを可変できるようにしています。
  • (gyo,retu)という2つの変数で場所を決定しています。
  • この向きで座標を設定したのは、Arduino言語の配列宣言に合わせたのも理由の一つです。下の壁情報で配列を宣言していますが、見た目に合わせた形にすると、この向きになりました。

壁情報

  • 各区画に壁があるわけですが、その壁の有無をどのように設定するか悩みました。各区域に4つの壁がある、とするとわかりやすいのですが、同じ壁に二つの異なる呼び方ができてしまうのがいやでした。
  • 何とか壁情報を一つの情報で管理できないかと考えて、以下のような形にしてみました。
    • 各区画の上側にある壁をwu[gyo][retu]であらわす。
    • 各区画の左側にある壁をwl[gyo][retu]であらわす。
    • ただし、区画は0から15までしかないので、このままでは、一番下の壁と一番右の壁が表現できなくなってしまいます。なので、16x16の外側に仮想的に区画があるようにしています。一番下の壁はwu[16][retu]、一番右の壁はwl[gyo][16]として定義しています。
    • 従って、壁情報については以下の2種類の配列で定義しています。壁の枚数もこれで合うはず。
      • bool wu[17][16]; と bool wl[16][17]
      • 各要素は0(壁なし)、1(壁あり)で定義します。
  • 探索に従って壁情報を更新していくわけですが、初期値としては、周囲の壁と、スタート位置の壁はあるものとして与えています。以下ご参照ください。あまりスマートではないですが。
bool wu[17][16]= {
  {1,1,1,1,1,1,1,1,1,1,1, 1, 1, 1, 1, 1},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},  
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0},
  {1,1,1,1,1,1,1,1,1,1,1, 1, 1, 1, 1, 1}};
//{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}

bool wl[16][17]= {
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1},
  {1,1,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 1}};
//{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}

機体の向き

  • 機体の向きは、座標の取り方に合わせて以下としています。左下がスタートだとして
    • 上向き: (-1,0) スタート時の向き
    • 下向き: (1,0)
    • 左向き: (0,-1)
    • 右向き: (0.1)
  • (mg,mr)の二つの変数で向きを決定しています。
  • この定義にしておくと、機体が回転したときの向きが、回転行列を適用することによって、mg,mrのまま扱えるのでプログラムが楽です。ベクトルを90°回転させればよいので、2x2の回転行列を作用させればよいですが、数学で使う座標系と向きが違うので、その点を考慮して適用することになります。
    • 回転前 (mg,mr)  → 右90°回転後 (mr,-mg)
    • 回転前 (mg,mr)  → 左90°回転後 (-mr,mg)
    • プログラム上は一旦別変数を用いる必要があります。
  • また、この形で向きを定義しておくと、現在位置の座標に向きを足せば、そのまま正面の区画の座標になるので、何かと便利です。

歩数情報

  • 足立法で、各区画の歩数情報を計算するので、そのための配列を準備します。
  • 単純に各区画に対応して、s[16][16];と宣言しています。各配列にその区画に対応した歩数が入ることになります。
  • 歩数の最大値は16*16-1になるので、データ型はuint8_tにしています。配列が大きいので、データ型はなるべく小さくしたいところです。初期値としては、ゴールは0とし、その他は255としています。
  • 別途解説する足立法では、都度初期状態から計算しなおしているので、初期値も都度設定しています。
  • プログラムの中で、上記の宣言外の配列を参照するように見える部分があるのですが、実際に参照されることはないので、エラーにはならないようになっています。

以上

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0