制御レイヤー構成
各レイヤーの意味は「リアルタイムシステム実現のための自立オブジェクト指向」(岩橋正実), CQ出版 を参考にすること。
vxv_tools/src/runCtrl/tRunCtrl のソースコードのレイヤー所属を以下に示す。
整数型の算術関数
通信まわり
タスク管理
走行モード管理
並進制御・回転制御
自己位置推定
車輪制御
モータ制御
エンコーダ制御
以上
#!/usr/bin/ruby # # isin(), icos() を作るためのスクリプト # Satofumi KAMIMURA # $Id$ # 絶対値の最大値、角度分割数の設定 angle_div = 65536 # [0, 65535] divid_shift = 15 divid_max = 1 << divid_shift # [-32767, +32767] angle_quad = angle_div >> 2 # 分割具合の設定 (0で誤差なし) #table_shift_value = 5 table_shift_value = 0 if ARGV[0] == "header" print <<-"EOB" #ifndef I_SIN_COS_H #define I_SIN_COS_H enum { ISINCOS_ANGLE_DIVIDED = #{angle_div}, /* [0, #{angle_div}] */ ISINCOS_VALUE_MAX = #{divid_max}, /* [-#{divid_max}, +#{divid_max}] */ ISINCOS_VALUE_SHIFT = #{divid_shift}, }; #include "cpp_extern_macro.h" BEGIN_C_DECLS; extern int isin(unsigned short div16); extern int icos(unsigned short div16); END_C_DECLS; #endif /* !I_SIN_COS_H */ EOB exit end # テーブル部分の出力 # get this file name __FILE__ =~ /\/*(.+)$/ thisFile = $1 print <<-"EOB" /* \\brief 整数型の sin, cos 関数 This program generated by #{thisFile} \\author Satofumi KAMIMURA $Id$ angle_max = #{angle_div-1} divid_max = #{divid_max} */ #include "isincos.h" static unsigned short sin_table[] = { EOB # 中の数値の表示 for i in 0 .. angle_div.to_i if i > (angle_quad.to_i >> table_shift_value) break end sin_val = divid_max.to_i \ * Math::sin((2.0 * Math::PI * (i << table_shift_value).to_f / angle_div.to_f)) print ' ', sin_val.to_i, ',' if (i+1) % 10 == 0 print "\n" end end print "};\n\n" # isin(), icos() の部分の出力 print <<-"EOB" static int sin_table_func(int n) { EOB if table_shift_value == 0 print " return sin_table[n];\n" else print " return sin_table[n >> #{table_shift_value}];\n" end print <<-"EOB" } int isin(unsigned short div16) { int ret; if (div16 <= #{angle_quad}) { ret = sin_table_func(div16); } else if (div16 <= #{2 * angle_quad}) { ret = sin_table_func(#{2 * angle_quad} - div16); } else if (div16 <= #{3 * angle_quad}) { ret = -sin_table_func(div16 -#{2 * angle_quad}); } else { ret = -sin_table_func(#{4 * angle_quad} - div16); } return ret; } int icos(unsigned short div16) { div16 += #{3 * angle_quad}; EOB if angle_div-1 != 0xffff print " div16 &= #{angle_div - 1};\n" end print <<-"EOB" return -1 * isin(div16); } EOB
テーブルサイズが小さい状態において精度が要求される場合には、テーブル間の値を線形補間等で計算すべきである。テーブル生成は、整数型の atan() の生成にも用いられている。
以上
これらの通信規格については相互に関連性がないため、ターゲットに送信する側のプログラムは、必要な規格のプロトコルのみ扱えればよいとする。 これは、ターゲット側が受動的であり、メッセージを動的にホスト側に返すことがない、という仮定において成り立つ。
V コマンドの定義は以下の通り。
ホストからターゲットへの V コマンドパケット
ターゲットからホストへの応答
走行制御コントローラを識別するための情報として、ターゲットから送られるファームウェアバージョンの情報に "tRunCtrl" なる文字列を含めることとする。
であるとし、上記の各々の通信に対して以下の機能を持つとする。
"V\r\r"
からなる文字列であり、応答として
"V\r"
"ステータス" "\r"
"ベンダ情報" "\r"
"製品情報" "\r"
"ファームウェア情報" "\r"
"プロトコルバージョン" "\r"
"センサ固有シリアル番号" "\r\r"
という文字列を返す。
通信時の手順を書き出すと以下の通り。
要求送信(要求側)
要求受信(応答側)
応答受信(要求側)
以上
正常時の書き込みトランザクション
タイムアウトにより、書き込み要求の再送を行った場合
つまり、書き込み要求の応答が正常に戻ってくる、という仮定の下では、書き込み応答パケットを待つ必要はない。以下では、書き込み応答の評価を先送りする場合の実装例について述べる。
という手順を取る。書きコマンドを2つ転送し、応答を待っている場合の保持パケットのイメージは以下の通り。待機中のパケットと到着したユニークID の評価は、キューの先頭から行われる。
保持中の書き込みパケット
上記実装の問題点を以下にあげる。
従って、上記実装はオプションで切り替えられるとし、通信時間の遅延が極端に気になる場合に用いるとよい。