3
1

More than 5 years have passed since last update.

後輩たちのためのEV3rt講座②(モーターを動かす)

Last updated at Posted at 2018-09-09

今回はロボットでは基本中の基本、モーター関連のことを教えていきます。
ただ、僕も使っていないAPIがあるので、それについては紹介できません。

でも安心してください。基本動作はできるようになります!!

以下はモーター関連のAPIです。これも参考にしながら見てください。
EV3RT C API Reference サーボモータ

①使うモーターをコンフィグする

前回もお伝えしましたが、モーターを使うには宣言をして置かなければなりません。
ここではモーターAとDにLモーターを繋ぐことにします。

app.c
#include "ev3api.h" //絶対必要
#include "app.h"//絶対必要
#include <stdio.h>
#include <stdbool.h>

#if defined(BUILD_MODULE)
#include "module_cfg.h"
#else
#include "kernel_cfg.h"
#endif

#define DEBUG

#ifdef DEBUG
#define _debug(x) (x)
#else
#define _debug(x)
#endif

void main_task(intptr_t unused)
{
    /* コンフィグゾーン */
    ev3_motor_config (EV3_PORT_A, LARGE_MOTOR);
    ev3_motor_config (EV3_PORT_D, LARGE_MOTOR);

これでモーターが使えるようになります。
ポートとの接続は
スクリーンショット 2018-08-22 10.39.57.png
もしくは
スクリーンショット 2018-09-10 12.46.25.png
つまり

ポート 列挙型① 列挙型②
A EV3_PORT_A 0
B EV3_PORT_B 1
C EV3_PORT_C 2
D EV3_PORT_D 3

という風にプログラムします。

センサーの対応表はこちら
スクリーンショット 2018-08-22 10.40.01.png

②モーターを動かしてみる

さて、いよいよ動かしていきます。
といっても、EV3には様々な命令方法がありますので、教育用ソフトウェアと比較して見ていきたいと思います。

モーターON

教育用ソフトウェアだと↓のコマンド
スクリーンショット 2018-08-22 10.48.55.png
EV3rtだと…

app.c
void main_task(intptr_t unused)
{
    /* コンフィグゾーン */
    ev3_motor_config (EV3_PORT_A, LARGE_MOTOR);
    ev3_motor_config (EV3_PORT_D, LARGE_MOTOR);

    ev3_motor_set_power(EV3_PORT_A,50);
    ev3_motor_set_power(EV3_PORT_D,50);
}

ただし、この命令はストップ命令を掛けない限り永遠に動き続けます。
ということで次は、

モーターOFF

教育用ソフトウェアだと↓のコマンド
スクリーンショット 2018-08-22 10.54.57.png
EV3rtだと…

app.c
void main_task(intptr_t unused)
{
    /* コンフィグゾーン */
    ev3_motor_config (EV3_PORT_A, LARGE_MOTOR);
    ev3_motor_config (EV3_PORT_D, LARGE_MOTOR);

    ev3_motor_stop(EV3_PORT_A, true);//Aで即時停止
    ev3_motor_stop(EV3_PORT_D, true);//Dで即時停止

    ev3_motor_stop(EV3_PORT_A, false);//Aで惰性減速
    ev3_motor_stop(EV3_PORT_D, false);//Dで惰性減速
}

こんな感じです。

さて、基本的にはこれだけで作業できますが、他にもいくつかあるので紹介しておきましょう。

③回転角を取得する

app.c
void main_task(intptr_t unused)
{
    /* コンフィグゾーン */
    ev3_motor_config (EV3_PORT_A, LARGE_MOTOR);
    ev3_motor_config (EV3_PORT_D, LARGE_MOTOR);

    int MotorAcount=ev3_motor_get_count(EV3_PORT_A);
    int MotorDcount=ev3_motor_get_count(EV3_PORT_D);
}

この例では変数MotorAcountとMotorDcountにAとDの回転角を代入します。
これを使うと何ができるか?
教育用ソフトウェアでいう↓のようなことができるようになります。
スクリーンショット 2018-08-22 11.16.37.png
角度を指定して動く事ができるのです。下に例を提示しておきます。

app.c
void main_task(intptr_t unused)
{
    /* コンフィグゾーン */
    ev3_motor_config (EV3_PORT_A, LARGE_MOTOR);
    ev3_motor_config (EV3_PORT_D, LARGE_MOTOR);

    ev3_motor_reset_counts(L_motorA);//回転角のリセット
    while (360>ev3_motor_get_counts(EV3_PORT_A)) {
        ev3_motor_set_power(EV3_PORT_A,50);
        ev3_motor_set_power(EV3_PORT_D,50);
    }
    ev3_motor_stop(EV3_PORT_A, true);//Aで即時停止
    ev3_motor_stop(EV3_PORT_D, true);//Dで即時停止
}

こんな風にすることで簡単に指定角文動かすことができます!!
さらに!!「C言語コンパイルが可能なんただったら、関数化してしまえばいいじゃないか」ということで、私は下の関数をめちゃくちゃ使ってプログラミングしました。よかったら参考にしてみてください。

④関数化してプログラムを効率化

app.c
void main_task(intptr_t unused)
{
    /* コンフィグゾーン */
    ev3_motor_config (EV3_PORT_A, LARGE_MOTOR);
    ev3_motor_config (EV3_PORT_D, LARGE_MOTOR);

    func_motor(50,50,360);
    func_motor_stop();
}

void func_motor(double a,double d,double dis);//aとdはパワーレベル・disは角度の指定

void func_motor(double a,double d,double dis)
{
    ev3_motor_reset_counts(EV3_PORT_A);
    if (a>0) {//パワーが正か負かで場合分け
        while (dis>ev3_motor_get_counts(EV3_PORT_A)) {
            ev3_motor_set_power(EV3_PORT_A,a);
            ev3_motor_set_power(EV3_PORT_D,d);
        }
    }
    else if(a<0){
        while (dis>-(ev3_motor_get_counts(EV3_PORT_A))) {
            ev3_motor_set_power(EV3_PORT_A,a);
            ev3_motor_set_power(EV3_PORT_D,d);
        }
    }
}

void func_motor_A(double a,double dis);

void func_motor_A(double a,double dis)
{
    ev3_motor_reset_counts(EV3_PORT_A);
    if (a>0) {
        while (dis>ev3_motor_get_counts(EV3_PORT_A)) {
            ev3_motor_set_power(EV3_PORT_A,a);
        }
    }
    else if(a<0)
    {
        while (dis>-(ev3_motor_get_counts(EV3_PORT_A))) {
            ev3_motor_set_power(EV3_PORT_A,a);
        }
    }
}

void func_motor_B(double a,double dis);

void func_motor_B(double a,double dis)
{
    ev3_motor_reset_counts(EV3_PORT_B);
    if (a>0) {
        while (dis>ev3_motor_get_counts(EV3_PORT_B)) {
            ev3_motor_set_power(EV3_PORT_B,a);
        }
    }
    else if(a<0)
    {
        while (dis>-(ev3_motor_get_counts(EV3_PORT_B))) {
            ev3_motor_set_power(EV3_PORT_B,a);
        }
    }
}

void func_motor_C(double a,double dis);

void func_motor_C(double a,double dis)
{
    ev3_motor_reset_counts(EV3_PORT_C);
    if (a>0) {
        while (dis>ev3_motor_get_counts(EV3_PORT_C)) {
            ev3_motor_set_power(EV3_PORT_C,a);
        }
    }
    else if(a<0)
    {
        while (dis>-(ev3_motor_get_counts(EV3_PORT_C))) {
            ev3_motor_set_power(EV3_PORT_C,a);
        }
    }
}

void func_motor_D(double a,double dis);

void func_motor_D(double a,double dis)
{
    ev3_motor_reset_counts(EV3_PORT_D);
    if (a>0) {
        while (dis>ev3_motor_get_counts(EV3_PORT_D)) {
            ev3_motor_set_power(EV3_PORT_D,a);
        }
    }
    else if(a<0)
    {
        while (dis>-(ev3_motor_get_counts(EV3_PORT_D))) {
            ev3_motor_set_power(EV3_PORT_D,a);
        }
    }
}

void func_motor_stop();

void func_motor_stop()
{
    ev3_motor_stop(EV3_PORT_A, true);
    ev3_motor_stop(EV3_PORT_B, true);
    ev3_motor_stop(EV3_PORT_C, true);
    ev3_motor_stop(EV3_PORT_D, true);
}

void func_motor_sleep();

void func_motor_sleep()
{
    ev3_motor_stop(EV3_PORT_A, false);
    ev3_motor_stop(EV3_PORT_B, false);
    ev3_motor_stop(EV3_PORT_C, false);
    ev3_motor_stop(EV3_PORT_D, false);
}

まとめ

今回はモーター関連のAPIを紹介しました。
また、今回以下の4つは紹介していません。

  • ev3_motor_get_type (motor_port_t port)
  • ev3_motor_get_power (motor_port_t port)
  • ev3_motor_rotate (motor_port_t port, int degrees, uint32_t speed_abs, bool_t blocking)
  • ev3_motor_steer (motor_port_t left_motor, motor_port_t right_motor, int power, int turn_ratio)

紹介しなかった理由としては大きく2つあります。
1つは使う機会がかなり限られているということ(特に上2つ)
もう1つは私自身使い方がイマイチわからないということ(特に下2つ)

ということで、これら4つを使いたい方は自分で使い方を調べてください。今回紹介した他のAPIとノリは同じなので、リファレンスを見ればだいたいわかります。また機会があれば紹介したいと思います。

次回:第3回
前回:第1回

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1