sim_ev3_src_mix - HisatsuguShiine/athrill-target GitHub Wiki
シミュレータと実機(EV3)向けの切り分け方について
はじめに
シミュレーターについては、完全な実機のシミュレーショをしたものではありません。それにより以下の差異が生じます。
- 左コース、右コースパラメータ
- 実機とのパラメータや個体差
- 実機とのAPI(ログ出力等)
それぞれでソースを分けることも実装の一つですが、シミュレータと実機をコンパイル時に切り替えることで、ソースコードを共有することが可能です。
その方法として、以下の方法があります。
- プリプロセッサを使用し、実機またはシミュレーションのターゲットを切り分ける。
切替方法などについては、実行委員より提供している、「
sample_c4
」をもとに説明します。
サンプルプログラムの構成
【
sample_c4
の構成】
項番 | ファイル名 | 内容 | 備考 |
---|---|---|---|
① | app.c | サンプルプログラム | 説明対象 |
② | app.h | サンプルプログラムのヘッダーファイル | |
③ | app.cfg | コンフィグファイル |
実装例
差異によるソースコードの切り分けの実装例は以下の通りです。
1.左コース、右コースの切り分け方について
45 /**
46 * 左コース/右コース向けの設定を定義します
47 * デフォルトは左コース(ラインの右エッジをトレース)です
48 */
49 #if defined(MAKE_RIGHT)
50 static const int _LEFT = 0;
51 #define _EDGE -1
52 #else
53 static const int _LEFT = 1;
54 #define _EDGE 1
55 #endif
解説 49行目のコード「#if defined(MAKE_RIGHT)」は、コンパイル時に定義された場合、50~51行のコードが有効になります。
それにより、下記ソースコード(179~186行目)で右コースで走行するためのパラメータとしてエッジを切り替えることが可能になります。
165 /**
166 * Main loop
167 */
168 while(1)
169 {
170 if (ev3_button_is_pressed(BACK_BUTTON)) break;
171
172 if (sonar_alert() == 1) /* 障害物検知 */
173 {
174 forward = turn = 0; /* 障害物を検知したら停止 */
175 }
176 else
177 {
178 forward = 30; /* 前進命令 */
179 if (ev3_color_sensor_get_reflect(color_sensor) >= (LIGHT_WHITE + LIGHT_BLACK)/2)
180 {
181 turn = -80 * _EDGE; /* 右旋回命令 (右コースは逆) */
182 }
183 else
184 {
185 turn = 80 * _EDGE; /* 左旋回命令 (右コースは逆) */
186 }
187 }
シミュレータ環境にて左右コースを切り替えるには、以下のビルド方法になります。
make right app=sample_c4 sim
make left app=sample_c4 sim
3.実装例
3.1 実機とシミュレータの切り分け方 - 定義方法 -
シミュレータ、実機(EV3)をコンパイル時に切り分けには、以下のファイルの修正が必要になります。
■シミュレーションの場合
1 APPL_COBJS += 2 #COPTS += -DMAKE_BT_DISABLE 3 COPTS += -DMAKE_SIM
3行目の記載例のように、記載を行う。なお、サンプルプログラムでは省略時は シミュレーションの動作と同様になります。
■実機の場合 1 APPL_COBJS += 2 #COPTS += -DMAKE_BT_DISABLE 3 COPTS += -DMAKE_EV3
3行目の記載例のように、「DMAKE_EV3」を明示的に記載を行う
3.2 実機とシミュレータの切り分け方 - 実装方法 -
【実装方法】
①に対して、以下を用いて、コンパイラ時にソースの切り分け方をしています。
MAKE_SIM ・・・ シミュレータの場合 MAKE_EV3 ・・・ 実機(EV3)の場合
(a)シミュレータかどうかの定数を定義 ■ソースコード(抜粋) 34 /** 35 * シミュレータかどうかの定数を定義します 36 */ 37 #if defined(MAKE_SIM) 38 static const int _SIM = 1; 39 #elif defined(MAKE_EV3) 40 static const int _SIM = 0; 41 #else 42 static const int _SIM = 0; 43 #endif
■解説
38行にて、MAKE_SIM(シミュレータ)の場合、有効で、「_SIMに1を設定」 40行にて、MAKE_EV3(実機)の場合、有効で、「_SIMに0を設定」 42行にて、未定義の場合、シミュレータの動作と同様
(b) 定義によって実行処理(走行体のスタート処理)の切り分け ■ソースコード(抜粋) 129 ev3_led_set_color(LED_ORANGE); /* 初期化完了通知 */ 130 131 _log("Go to the start, ready?"); 132 if (_SIM) _log("Hit SPACE bar to start"); 133 else _log("Tap Touch Sensor to start");
■解説
シミュレータの場合 Ubuntuでリモート接続しているコンソールに、"Hit SPACE bar to start"が表示され、スペースキーの押下で走行体のライントレースが開始 実機の場合 EV3のコンソールに、"Tap Touch Sensor to start"が表示され、タッチセンサーの押下で走行体のライントレースが開始
(c) 定義によって実行処理(ログ出力)の切り分け ■ソースコード(抜粋) 282 static void _syslog(int level, char* text){ 283 static int _log_line = 0; 284 if (_SIM) 285 { 286 syslog(level, text); 287 } 288 else 289 { 290 ev3_lcd_draw_string(text, 0, CALIB_FONT_HEIGHT*_log_line++); 291 } 292 }
シミュレータの場合 syslog関数を使用して、メッセージの出力を行う。 実機の場合 ev3_lcd_draw_string関数を使用して、メッセージの出力を行う。
3.3 その他
シミュレーション、実機の切り分けと同様に、左コース/右コースをコンパイル時に切り分ける事も可能です。 以下に記載例を示します。 ■ソースコード(抜粋) 45 /** 46 * 左コース/右コース向けの設定を定義します 47 * デフォルトは左コース(ラインの右エッジをトレース)です 48 */ 49 #if defined(MAKE_RIGHT) 50 static const int _LEFT = 0; 51 #define _EDGE -1 52 #else 53 static const int _LEFT = 1; 54 #define _EDGE 1 55 #endif
シミュレータ環境では以下のようになります。 ビルド(Lコース): make left app=sample_c4 sim ビルド(Rコース):make right app=sample_c4 sim シミュレータの起動: sim (ver 2020_x.xx) ver の指定は必要な場合のみ プログラムの起動(Lコース): make left start プログラムの起動(Rコース): make right start ビルド,シミュレータ起動,プログラム起動をまとめて実行: make left app=sample_c4 sim up