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