C言語でEV3開発(22)-ロギング機能

2021年2月6日

どもです。
前回は、モーターの出力を制御する方法について記載しました。
その際に、モータ/車体が期待通りに動かず、その解決のために、データの記録と解析が必要という結論に至りました。
なので今回は、このデータの記録方法について、記載します。

1.ログデータのフォーマット

一言で書けば「CSV」形式です。
以上!

2.記録するデータ

今回の解析のために、

  • 左右のモーター出力指示値
  • 左右のモーター出力動作値
  • 左右のモーター出力目標値
  • 左右のモーターのPID計算値
  • 超音波センサーの読取値
  • 超音波センサーの平均値

を記録するようにします

3.ログの方法
Ev3RTでは、標準Cライブラリが使用できます。
なので、データの書き込みのためには、この標準関数を使用します。
特別なこと、難しいこと、特筆すべきことは何もありません。
ええ、特筆すべきことは何もありません。

実装は、下記の通りです。
(左右のモーター出力指示値~左右の出力目標値)

/**
 *  @brief  Open logging file of motor.
 */
void init_motor_log(void)
{
    motor_log = fopen(motor_log_file_name, "a");
    if (NULL != motor_log) {
        fprintf(motor_log, (const char *)motor_log_format);
    }
}

/**
 *  @brief  Finalize loggin file of motor.
 */
void fin_motor_log(void)
{
    if (NULL != motor_log) { fclose(motor_log); }
}

/**
 *  @brief  Logging motor data, target and current motor power.
 */
void logging_motor(void)
{
    if (NULL != motor_log) {
        fprintf(motor_log,
            "%d,%d,%d,%d,%d,%d\n",
            left_motor_power, right_motor_power,
            left_motor_power_current, right_motor_power_current,
            target_motor_output_left, target_motor_output_right);
    }
}

(左右のモーターのPID制御値)

/**
 *  @brief  Open logging file of paramter in calculating motor power.
 */
void init_clc_motor_log(void)
{
    clc_motor_log = fopen(clc_motor_log_file_name, "a");
    if (NULL != clc_motor_log) {
        fprintf(clc_motor_log, (const char *)clc_motor_log_format);
    }

}

/**
 *  @brief  Close logging file.
 */
void fin_clc_motor_log(void) 
{
    if (NULL != clc_motor_log) { fclose(clc_motor_log); }
}

/**
 *  @brief  Logging parameter in calculating motor power.
 */
void logging_clc_motor(void)
{
    if (NULL != clc_motor_log) {
        fprintf(clc_motor_log,
            "%d,%d,%d,%d\n",
            left_power.diff, left_power.integral,
            right_power.diff, right_power.integral);
    }
}

(超音波センサの読取値、および平均値)

/**
 *  @brief  Open logging file of ultrasonic sensor.
 */
void init_sensor_log(void)
{
    sensor_log = fopen(sensor_log_file_name, "w");
    if (NULL != sensor_log) {
        fprintf(sensor_log, (const char *)sensor_log_format);
    }
}

/**
 *  @brief  Finalize logging file of ultrasonic sensor.
 */
void fin_sensor_log(void)
{
    if (NULL != sensor_log) { fclose(sensor_log); }
}

/**
 *  @brief  Logging sensor data, ultrasonic sensor, and the average value.
 */
void logging_sensor(void)
{
    if (NULL != sensor_log) {
        fprintf(sensor_log,
            "%d,%d\n",
            distance_sensor_value, distance_average_value);
    }
}

4.ログを録ってみた

上記の実装を追加したアプリケーションを動作させてみました。

このときの動作のログは、下記の通りです。
超音波センサのログ
モーター値
モータ動作/指示値

モーター動作値を見てみると、左右のモーター出力値/動作値に違いはほとんどありません。
あったとしても、ノイズ程度のものです。
しかし、動画を見てみると、少しずつですが、右側に曲がっているのが分かります。
このことから、曲がってしまった原因は、車体ではなく、車体の走行環境にあることが考えられます。
(カーペットがデコボコしていたのが悪い?)

5.まとめ

また、今回のデータでは、前回の動画でドリフト(?)らしき動きについては、説明がつきません。
停止間際に、「くいっ」と曲がるのは何でなんだか…。
この件については、引き続き調査していきます。

ではっ!

ex.追記

上記の機能を追加したソースコード一式を、公開しました。
GitHub