名称 MIRS13CP 怪盗機プログラム詳細設計書
番号 MIRS13CP-SOFT-0001

最終更新日:2013.2.21

版数 最終更新日 作成 承認 改訂記事
A01 2013.2.03 山内佑哉 初版
A02 2013.2.21 山内佑哉 出川先生 追記

目次




1.はじめに

本ドキュメントは、怪盗機プログラムの詳細な設計についてのドキュメントである。

2.機能定義

  • 分岐での進行方向を操縦者からの入力によって決定する。
  • 白線をライントレースすることによって進む。
  • 宝物の押しボタンスイッチをアームを使って押す。
  • ライントレースの途中で停止して反転することができる。
  • 背後から迫ってくるMIRSを超音波で検知する。
  • マップデータを用いて、道がないときにはそちらに進めないようにする。
  • 非常用のマニュアルモードを搭載する。


  • 3.共有変数一覧

    怪盗機のプログラムで使用する共有変数の一覧を示す。
    変数宣言 概要
    int map[][4] マップの情報を格納する二次元配列。各要素には、分岐点ごとにどの方角に何番の分岐点があるかを示す。その方角に道がないときは-1を、宝があるときは255を、出入り口あるときは100をいれる。
    CHAR send_buf[BT_SEND_BUF_SIZE] 送る文字列を格納する配列。引数には送るデータのサイズをいれる。
    CHAR rcv_buf[BT_RCV_BUF_SIZE] 受け取った文字列を格納する配列。引数には受け取るデータのサイズをいれる。
    enum direction{NORTH,EAST,SOUTH,WEST}direction 現在向いている方角を記憶するための列挙型の変数。初期値として、進入するときの方角を与える。
    int location 現在いる分岐点を記憶しておくための変数。初期値として、進入する入り口の先にある分岐点の番号を与える。
    int light_r
    int light_l
    現在のライトセンサの値を格納するための変数。
    int light_past_r
    int light_past_l
    一つ前のライトセンサの値を格納するための変数。
    int speed_r
    int speed_l
    左右のモータの回転させる速さを格納するための変数。
    int rx_len 受け取った文字列が何文字かを記憶するための変数。
    int select[]={0,0,0,0} 分岐点で前後左右にある分岐点番号を一時的に格納する配列。

    4.関数機能定義

    自分で作成した関数についての概要を次の表に記す。
    関数宣言 概要
    void turning() 現在いる分岐点と向いている方角から、前後左右の道の先にある分岐点番号を配列selectに代入する関数。
    void turn_right()
    void turn_left()
    分岐点で左右のどちらかに曲がるときに使用する関数。
    適切な距離になるまで前進し、右折するときは左の、左折するときは右のタイヤを回転させて曲がる。その後、向いている方角を記録する変数directionの値を修正する。
    void turn_straight() 分岐点で真っ直ぐ進む時に使用する関数。
    ライトセンサが分岐点を越えるまで前進する。
    void turn_back() 分岐点で来た道に戻る時に使用する関数。 その場で180°回転し、向いている方角を記録する変数directionの値を修正する。
    void arm() 宝物を盗むため、腕を動かすときに使用する関数。
    腕を前に倒し、その状態でしばらく待つ。その後、腕を元に戻しまた少し待つ。途中で待つ動作をいれているのは、宝物を盗むのが早すぎるとMIRSが不利になってしまうためである。
    void arm_select() 宝物を盗むときの動作と、盗んだ後の進行方向を決める関数。
    適切な距離まで前進した後、arm()を実行し元の位置まで戻る。その後、turning()を実行して入力をまち、入力された文字に対応した方向に向きなおる。
    void manual() 機体がライン上からはずれてしまった時などに使用する関数
    入力された文字に応じた動作を行う。'w'なら前進、'd'なら右回転、'a'なら左回転、's'なら後退、'f'ならアームを前に倒す、'r'ならアームを起こす、'e'ならこの関数を終了し通常走行に戻る。それ以外の入力、もしくは入力が無かった時はすべてのモータを停止させる。
    void stop() 走行中に停止するときに使用する関数。
    走行を停止した後、入力に応じた動作を行う。'm'ならmanual()を実行した後、再び入力待ち状態になる。's'ならturn_back()を実行し方角と現在地を修正した後、再び入力待ち状態になる。'e'なら関数を終了する。'q'ならarm()を実行し、再び入力待ち状態になる。それ以外の入力があった場合、再び入力待ち状態になる。
    int select_course() 分岐点で何をするかを決めるときに使用する関数。
    入力に応じた動作を行う。入力が'w'ならturn_straight、'd'ならturn_right、'a'ならturn_left、's'ならturn_back,もし、道がなかったときはそれぞれの関数を実行せずに再び入力待ち状態になる。入力が'm'ならマニュアルモードに移行し、マニュアルモードが終了したらそのまま関数も終了する。入力が'e'なら何もせずに関数を終了する。

    5.フローチャート

    各関数のフローチャートを次に示す。

    turning()



    turn_right(),turn_left()



    turn_straight()



    turn_back()



    arm()



    arm_select()



    manual()



    stop()



    select_course()



    6.状態遷移図

    プログラム全体の状態遷移図を次に示す。




    7.開発所要時間

    上記のプログラムの開発には約70時間ほどかかった。パソコンとの通信部分やライントレースの調整、途中でフリーズする問題を解決するのに時間がかかった。フリーズする問題の原因は、nxt側からパソコンへデータを送信する際に使用したecrobot_send_btというAPIだった。このAPIを使用すると、実行ファイルのデータサイズが非常に大きくなってしまう。それにより、プログラム実行中に処理に不具合が生じ、フリーズしてしまったものと思われる。解決策としては、このAPIを使用する部分を別タスクにしてサイクルタイムを長くし、使用頻度を少なくするか、そもそも使わないということがあげられる。しかし、別タスクにして使用頻度を少なくしても、長時間プログラムを走らせているとフリーズしてしまうことがあったため、できればこのAPIを使用しないことを推奨する。





    MIRS13CPドキュメント管理台帳