SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

[組込み開発入門] ロボットを作ろう

【第4回】レゴマインドストームNXTでライントレーサを作成しよう

レゴマインドストームNXTでロボットプログラミング


コーディングして、動かしてみよう

 今回の設計に基づいたコーディング例は、以下の通りです。また、実際に動作している姿もお楽しみください。なお、今回は、黒のしきい値500、wait時間100ミリ秒という調整を行い、動作させています。

#include <time.h>
#include <stdio.h>
#include "kernel.h"
#include "kernel_id.h"
#include "ecrobot_interface.h"
#include "systick.h"

#define TOUCHED 0

/** 光センサのポート */
#define LIGHT_SENSOR_PORT NXT_PORT_S3
/** タッチセンサのポート */
#define BUMPER_SENSOR_PORT NXT_PORT_S1

/** 右モータ */
#define RIGHT_MOTOR_PORT NXT_PORT_A
/** 左モータ */
#define LEFT_MOTOR_PORT NXT_PORT_B
/** ライントレースかどうか */
#define LINE_TRACE 1
/** 停止する */
#define STOP 0

/** 黒のしきい値 */
#define IS_BLACK 500
/** Wait時間 */
#define WAIT_TIME 100

/*--------------------------------------------------------------------------*/
/* OSEK declarations                                                        */
/*--------------------------------------------------------------------------*/
DeclareCounter(SysTimerCnt);
DeclareResource(lcd);
DeclareTask(MainTask);

/*--------------------------------------------------------------------------*/
/* Globals                                                                  */
/*--------------------------------------------------------------------------*/
int pushedPls = 0;

/*--------------------------------------------------------------------------*/
/* ECRobot hooks                                                            */
/*--------------------------------------------------------------------------*/
const U8 target_subsystem_name[] = "DesignTest";

void ecrobot_device_initialize()
{
    /* write NXT device initializations */
    /** 光センサをONにする */
    ecrobot_set_light_sensor_active(LIGHT_SENSOR_PORT);
}

void ecrobot_device_terminate()
{
    /* write NXT device terminations */
}

/*--------------------------------------------------------------------------*/
/* OSEK hooks                                                               */
/*--------------------------------------------------------------------------*/
void StartupHook(void){}
void ShutdownHook(StatusType ercd){}
void PreTaskHook(void){}
void PostTaskHook(void){}
void ErrorHook(StatusType ercd){}

/*--------------------------------------------------------------------------*/
/* Function to be invoked from a category 2 interrupt                       */
/*--------------------------------------------------------------------------*/
void user_1ms_isr_type2(void)
{
    StatusType ercd;
    /*
     *  Increment OSEK Alarm System Timer Count
     */
    ercd = SignalCounter( SysTimerCnt );
    if( ercd != E_OK ){
        ShutdownOS( ercd );
    }
}

/**
 * LeftTire_front
 * 左のタイヤを正転させます.
 *
 */
void LeftTire_front(int speed_percent)
{
    nxt_motor_set_speed(LEFT_MOTOR_PORT, speed_percent, 1);
}

/**
 * LeftTire_stop
 * 左のタイヤを停止させます.
 *
 */
void LeftTire_stop()
{
    nxt_motor_set_speed(LEFT_MOTOR_PORT, 0, 1);
}

/**
 * RightTire_front
 * 右のタイヤを正転させます.
 *
 */
void RightTire_front(int speed_percent)
{
    nxt_motor_set_speed(RIGHT_MOTOR_PORT, speed_percent, 1);
}

/**
 * RightTire_stop
 * 右のタイヤを停止させます.
 *
 */
void RightTire_stop()
{
    nxt_motor_set_speed(RIGHT_MOTOR_PORT, 0, 1);
}

/**
 * rightTurn
 * 右に曲がります.
 *
 */
void Handle_rightTurn(void)
{
    LeftTire_front(50);
    RightTire_stop();
    systick_wait_ms(WAIT_TIME);
}

/**
 * leftTurn
 * 左に曲がります.
 *
 */
void Handle_leftTurn(void)
{
    RightTire_front(50);
    LeftTire_stop();
    systick_wait_ms(WAIT_TIME);
}

/**
 * TouchSensor_isTouched 
 * タッチセンサがタッチされたかを返します.
 *
 */
int TouchSensor_isTouched(void)
{
    int touch = FALSE;

    if (TOUCHED == ecrobot_get_touch_sensor(BUMPER_SENSOR_PORT)) {
        pushedPls = 1;
    }
    
    /** 信号の立下りを見てボタンが押されたかを判断する */
    if (1 == pushedPls && TOUCHED != ecrobot_get_touch_sensor(BUMPER_SENSOR_PORT)) {
        touch = TRUE;
        pushedPls = 0;
    }    

    return touch;
}

/**
 * LineSensor_initWork
 * センサの準備をします. 
 *
 */
void LineSensor_initWork(void)
{

}

/**
 * LineSensor_inOnline
 * 線上かどうかを返します.
 *
 * @return 線上の場合 ON_LINE, それ以外 OUT_LINE
 *
 */
int LineSensor_isOnline(void)
{
    int value = ecrobot_get_light_sensor(LIGHT_SENSOR_PORT);
    return value > IS_BLACK;
}

/**
 * Body_changeStatus
 * 運転状態を変更します.
 *
 */
int Body_changeStatus(int status)
{
    /** 現在は停止,運転のみのステータスなので単に反転させるだけ */
    return (TRUE == TouchSensor_isTouched())? !status: status; 
}

/**
 * MainTask
 * Mainタスクです.
 *
 */
TASK(MainTask)
{
    /** ステータス */
    int status = 0;

    /** 初期処理を行います */
    LineSensor_initWork();

    while(1) {
        status = Body_changeStatus(status); 
        switch(status) {
            case LINE_TRACE:
                if (LineSensor_isOnline()) {
                    /** 線上の場合は右に曲がる */
                    Handle_rightTurn();
                } else {
                    /** 線外の場合は左に曲がる */
                    Handle_leftTurn();
                }
                break;
            case STOP:
                /** 両輪を停止する */
                LeftTire_stop();
                RightTire_stop();
                break;
        }
    } 

    /** タスクを終了する */
    TerminateTask(); 

}

次のページ
課題と改善案

この記事は参考になりましたか?

[組込み開発入門] ロボットを作ろう連載記事一覧

もっと読む

この記事の著者

柏崎 真司(カシワザキ シンジ)

(株)永和システムマネジメント所属。カーネル開発から、組み込み開発の世界へと足を踏み入れた。共通部分を多く感じながらも、組込み独自の魅力に魅了されつつある。また、組込み開発と同様、それ以上に、家族と過ごす時間もこよなく愛している。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/3704 2009/03/16 19:17

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー