EV3RTのathrill移植調査状況

#概要
「[EV3RT を athrill に移植するまで](https://qiita.com/kanetugu2018/items/833da7a268a3f34bead4)」にて，EV3RTのシミュレータを作る宣言しています．

ここで，EV3RTをathrillを移植するには以下の２つの課題があります．

1. hrp2をathrillに移植する
* EV3RTの機能をathrillに移植する

当初は，1. の方から攻めていましたが，移植難易度が高く立ち往生しておりました．さらに，今後はベースのOSがHRP3になるらしく，一旦，こちらはペンディングすることに決めました．

その代わり，EV3RTのシミュレータとしてのOSは手軽な aspカーネルにして，2. の方の検討を進めることにしました．

本記事では，その内容をまとめていくことにします(半分，自分の整理用です)．

#EV3RTの開発ページ
EV3RT開発向けの解説ページをここにリスト化しておきます．

* https://dev.toppers.jp/trac_user/ev3pf/wiki/WhatsEV3RT
* https://www.toppers.jp/docs/etrobo15/ev3rt_seminar_04.pdf


#EV3RTのソースを取得する
まずは，EV3RTの移植対象ソースとしてはβ7に決めました．
[ダウンロードページ](https://dev.toppers.jp/trac_user/ev3pf/wiki/Download#%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89)から早速ソースを取得させて頂きました．

#EV3RTのathrill用移植用のソースをgithubで管理
EV3RTのathrill向け個の移植コードをathrillのsample管理用のプロジェクトの以下に配置しました．

https://github.com/tmori/athrill-sample/tree/master/ev3rt

* 2019/10/14
  * 一旦，asp3ベースでリンクまで通しました．
  * ただし，以下の課題が残っています．
     * SVCコール部分は未実装
     * EV3，Newlib機能は未実装
     * athrillのシステムコール機能追加が必要(fopen/fdopen等)

* 2019/10/20
  * athrill で動作させながら実装を進めています．
  * 詳細は後述しますが，センサ系およびボタンは一通り動いています．

* 2019/11/04
  * モーター機能を追加しました．
  * Unityと連携してライントレースできるようになりました． 

#EV3RTのathrill移植用開発環境
Windows10 WSL※で開発しています．
※Linuxでも開発可能．

#EV3RT機能一覧と移植範囲および実装状況
EV3RTのリファレンスマニュアルを参照して，ロボットを動かす上で必須機能となるものは移植対象として選定しました．

センサアクチュエータ周りは基本的に外部の物理シミュレータとの連携を想定しているので，UDPでの送受信で実現することに決めました．UDP実現部分はおおよそ実装が出来ています．

|機能|サブ機能|移植有無|実現方法|実装状況|
|---|---|---|---|---|
|EV3本体機能|バッテリ|〇|UDP|×|
|EV3本体機能|ボタン|〇|UDP|〇|
|EV3本体機能|LEDライト|〇|UDP|〇|
|EV3本体機能|スピーカ|×|-|-|
|ファイルシステム|-|〇|(T.B.D)|-|
|LCD|-|×|(T.B.D)|-|
|サーボモータ|-|〇|UDP|〇|
|拡張RTOS機能|-|〇|(T.B.D)|-|
|各種センサ|温度センサ|〇|UDP|〇|
|各種センサ|加速度センサ|〇|UDP|〇|
|各種センサ|超音波センサ|〇|UDP|〇|
|各種センサ|タッチセンサ|〇|UDP|〇|
|各種センサ|IRセンサ|〇|UDP|〇|
|各種センサ|ジャイロセンサ|〇|UDP|〇|
|各種センサ|カラーセンサ|〇|UDP|〇|

#EV3RTの開発モードとOSとの関係
EV3RTには，以下の２つの開発モードがありますが，今回は Standalone Mode で移植します．

* Dynamic Loading Mode
  * アプリケーションのダイナミックローディングが可能になる
  * HRP2のようなOSのサポートは必須と思われる
     * アプリは特権モードでカーネル機能呼び出しは SVCコールで切り替える
* Standalone Mode (Advanced)
  * アプリケーションとカーネルとが同じモジュールとして静的にリンクされる

#EV3RTのアプリケーション・インタフェース調査
EV3RTのアプリケーション・インタフェース部分は，「Platform Interface Layer(PIL)」と呼ばれているようです．
Dynamic Loading Mode の場合は，このインタフェース実装が SVC コールになると思われる．
Standalone Mode の場合は，SVCコールから呼び出されるサービス処理そのものを直接呼び出すのではないか．

EV3RT上のアプリケーションは，PIL層のAPIを直接呼び出すわけではなく，
「Application Programming Interface(API)」を利用するようです．

このAPIは，以下の３つに分類されているようです．

* HRP2 API
* EV3 API
* Newlib API

##API実装状況

|機能|サブ機能|API名|サポート有無|実装状況|
|---|---|---|---|---|
|HRP2|-|HRP2のAPI一式|△(asp3)|〇|
|EV3|バッテリ|ev3_battery_current_mA|〇|×|
|EV3|バッテリ|ev3_battery_voltage_mV|〇|×|
|EV3|ボタン|ev3_button_is_pressed|〇|〇|
|EV3|ボタン|ev3_button_set_on_clicked|〇|〇|
|EV3|LEDライト|ev3_led_set_color|〇|〇|
|EV3|スピーカ|(省略)|-|-|-|
|EV3|LCD|(省略)|-|-|-|
|EV3|サーボモータ|ev3_motor_config|〇|〇|
|EV3|サーボモータ|ev3_motor_get_type|〇|〇|
|EV3|サーボモータ|ev3_motor_get_counts|〇|〇|
|EV3|サーボモータ|ev3_motor_reset_counts|〇|〇|
|EV3|サーボモータ|ev3_motor_set_power|〇|〇|
|EV3|サーボモータ|ev3_motor_get_power|〇|〇|
|EV3|サーボモータ|ev3_motor_stop|〇|×|
|EV3|サーボモータ|ev3_motor_rotate|×|-|
|EV3|サーボモータ|ev3_motor_steer|×|-|
|EV3|センサ|ev3_sensor_config|×|-|
|EV3|センサ|ev3_sensor_get_type|〇|〇|
|EV3|カラーセンサ|ev3_color_sensor_get_color|〇|〇|
|EV3|カラーセンサ|ev3_color_sensor_get_reflect|〇|〇|
|EV3|カラーセンサ|ev3_color_sensor_get_rgb_raw|〇|〇|
|EV3|ジャイロセンサ|ev3_gyro_sensor_get_angle|〇|〇|
|EV3|ジャイロセンサ|ev3_gyro_sensor_get_rate|〇|〇|
|EV3|ジャイロセンサ|ev3_gyro_sensor_reset|〇|〇|
|EV3|IRセンサ|ev3_infrared_sensor_get_distance|〇|〇|
|EV3|IRセンサ|ev3_infrared_sensor_seek|〇|〇|
|EV3|タッチセンサ|ev3_touch_sensor_is_pressed|〇|〇|
|EV3|超音波センサ|ev3_ultrasonic_sensor_get_distance|〇|〇|
|EV3|超音波センサ|ev3_ultrasonic_sensor_listen|〇|〇|
|EV3|加速度センサ|ht_nxt_accel_sensor_measure|〇|〇|
|EV3|温度センサ|nxt_temp_sensor_measure|〇|〇|
|Newlib|Newlib向けのAPI群|-|〇|×|

#デモ
ライントレースが出来るようになりました．
athrill側での制御処理は以下のコードで100msec周期で制御しています．

```
    while(1) {

    /**
     * PID controller
     */
#define white 100
#define black 10
        static float lasterror = 0, integral = 0;
        static float midpoint = (white - black) / 2 + black;
        {
            float error = midpoint - ev3_color_sensor_get_reflect(EV3_PORT_1);
            integral = error + integral * 0.5;
            float steer = 0.07 * error + 0.3 * integral + 1 * (error - lasterror);
            ev3_motor_steer(left_motor, right_motor, 10, steer);
            lasterror = error;
        }
        tslp_tsk(100);

    }
```

Unity側は，単純なコースを作って，照度センサとモータを作りました．
UnityとathrillはUDPで連携していて，1msec周期でセンサ/アクチュエータ連動させています．

その結果が以下です．
![ev3_trace3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/5306fa68-e973-a92c-7cda-05b201ad3d3d.gif)

現状のソースは以下で公開しています．

* athrill
   *  https://github.com/tmori/athrill-target/tree/master/v850e2m
* EV3RTおよびデモコード
   * https://github.com/tmori/athrill-sample/tree/master/ev3rt/ev3rt-beta7-release/asp3/sdk/OBJ
* Unityパッケージ
   *  https://github.com/tmori/athrill-sample/tree/master/ev3rt/ev3rt-beta7-release/unity