3. ⾛走⾏行行体サンプルプログラム
⽯石川 拓也
名古屋⼤大学  ⼤大学院情報科学研究科
最終更新⽇日:2012/05/30
2012/06/02 TOPPERSプロジェクト認定 1
内容
•  ⾛走⾏行行体サンプルプログラムについて
‒  サンプルプログラムの機能
‒  サンプルプログラムのタスク構成
•  モデリング
‒  TECSを⽤用いた開発
•  ソフトウェアプラットフォームでサポートする部分
•  ユーザが作成する部分
2012/06/02 TOPPERSプロジェクト認定 2
サンプルプログラムの機能(1/2)
•  プログラムの流れ
‒  プログラム起動直後
•  尻尾モータ制御
‒  ⾛走⾏行行体を⾃自⽴立立させる
•  Bluetooth通信確⽴立立
‒  ホストPCとペアリング
‒  ⾛走⾏行行開始待ち状態
•  ホストPCから、ʼ’gʼ’キーを送信すると⾛走⾏行行を開始する
‒  奇数'g'コマンドで左エッジスタート
‒  偶数'g'コマンドで右エッジスタート
‒  ⾛走⾏行行中
•  倒⽴立立⼆二輪制御
‒  バランサの機能により、設定された速度、舵⾓角で倒⽴立立⾛走⾏行行を⾏行行う
ためのモータのPWM値を計算し、それをモータにセットする
‒  4ミリ秒周期で処理する
•  ライントレース制御
‒  光センサの値からライントレースを⾏行行うための舵⾓角を計算する
‒  10ミリ秒周期で処理する
2012/06/02 TOPPERSプロジェクト認定 3
サンプルプログラムの機能(2/2)
•  プログラムの流れ(続き)
‒  プログラムの停⽌止
•  EXITボタンを押すとプログラムを終了
•  STOPボタンを押すとプログラムを再起動
•  STOP+ENTERボタンを押すとNXT BIOS書き換え
‒  コマンドの受信
•  'g':⾛走⾏行行開始
•  's':停⽌止
•  'b':光センサ(⿊黒)のキャリブレーション
•  'w':光センサ(⽩白)のキャリブレーション
•  'l':光センサ(⽬目標値)のキャリブレーション
•  'f':スピードのセット
•  't':尻尾⾓角のセット
2012/06/02 TOPPERSプロジェクト認定 4
サンプルプログラムのタスク構成
•  尻尾制御タスク
‒  尻尾のモータを制御する
•  倒⽴立立⼆二輪制御タスク
‒  指定された速度・舵⾓角で倒⽴立立⼆二輪⾛走⾏行行するように左右の
モータを制御する
•  ライントレース制御タスク
‒  ライントレース⾛走⾏行行するように舵⾓角を制御する
•  コマンド受信タスク
‒  シリアルポート(Bluetooth)経由でコマンドを受信・解析
し、各パラメータをセットする
•  ⾛走⾏行行開始待ちタスク
‒  ⾛走⾏行行開始待ち状態を維持し、⾛走⾏行行開始のシグナルを受け取
ると、倒⽴立立⼆二輪制御タスクとライントレース制御タスクを
起動して、⾛走⾏行行を開始させる
2012/06/02 TOPPERSプロジェクト認定 5
UMLによる設計
2012/06/02 TOPPERSプロジェクト認定 6
•  オブジェクト図(⼀一部)起動処理
ライントレース制御倒 輪制御
尻尾制御
センサドライバモータドライバ
ログ出
&
シリアル通信
コマンド受信
TECSコンポーネント図
2012/06/02 TOPPERSプロジェクト認定 7
•  ユーザアプリケーション起動処理
ライントレース制御倒 輪制御
尻尾制御
センサドライバモータドライバ
ログ出
&
シリアル通信
コマンド受信
TECSコンポーネント図
•  全体像
TOPPERSプロジェクト認定 82012/06/02
UMLからTECSのモデルへの変換
•  変換するメリット
‒  クラスのインスタンス化やインスタンス間の接続を
するためのC⾔言語のソースコードを⾃自動⽣生成してく
れる
•  ユーザがC⾔言語で書くのは、メソッドの中⾝身だけでよい
•  変換の⽅方針
‒  メソッドヘッダの集合 → シグニチャ
‒  クラス → セルタイプ
‒  クラスの属性 → セルタイプの属性、内部変数
‒  クラス間の関連 → 呼び⼝口と受け⼝口
•  シグニチャのインスタンス化
‒  インスタンス化と接続 →セルの⽣生成とセル間の結合
•  組上げ記述
TOPPERSプロジェクト認定 92012/06/02
TECSを⽤用いた開発の流れ
•  コンポーネントの設計
‒  シグニチャの定義
‒  セルタイプの定義
•  コンポーネントの実装
‒  コンポーネントの提
供する機能を実装
•  シグニチャとセルタイプ
の情報から⾃自動⽣生成され
たテンプレートコードを
利⽤用
•  C⾔言語実装
•  組上げ記述の作成
‒  組上げ記述によりア
プリケーションを構
築
コンポーネント
記述
組上げ記述
セルタイプ
コード
テンプレート
コード
コンパイラ
ヘッダ
インタフェース
コード
コンポーネント
設計者
コンポーネント
開発者
アプリケーション
開発者
設計
設計
実装
バイナリ
⾃自動⽣生成
⾃自動⽣生成
2012/06/02 TOPPERSプロジェクト認定 10
TECS
ジェネレータ
ソフトウェアの構成要素
•  ソフトウェアプラットフォームでサポートする部分
‒  ミドルウェア
•  ボタンチェック周期ハンドラ
•  Bluetooth接続タスク
•  バランサ
‒  デバイスドライバ
•  バッテリ
•  モータ
•  センサ
•  シリアル通信(Bluetooth)
•  ユーザアプリケーションの部分
‒  尻尾制御
‒  倒⽴立立⼆二輪制御
‒  ライントレース制御
‒  コマンド受信
‒  ⾛走⾏行行開始待ち
2012/06/02 TOPPERSプロジェクト認定 11
ソフトウェアプラットフォームで
サポートする部分
TOPPERSプロジェクト認定 122012/06/02
ASP+TECS
デバイスドライバ・
ミドルウェア
ソフトウェアプラットフォーム(1/4)
•  ASP+TECS
‒  カーネルオブジェクト
‒  タイマ
‒  シリアル通信
•  デバイスドライバ
‒  ボタン、バッテリ、センサ、モータ
•  コプロセッサ
‒  Bluetooth
‒  ディスプレイ
‒  サウンド
•  ミドルウェア
‒  ボタンチェック
‒  Bluetooth接続
‒  バランサ NXT
カーネル タイマ シリアル
ユーザアプリケーション
2012/06/02 TOPPERSプロジェクト認定 13
ソフトウェアプラットフォーム(2/4)
•  提供するコンポーネントの定義
‒  カーネル
•  include/kernel.cdl : カーネルオブジェクト
•  syssvc/tLogTask.cdl : システムログ出⼒力力タスク
•  syssvc/tSysLog.cdl : システムログバッファ
•  syssvc/tSerialPort.cdl: シリアルポート
•  target/mindstorms_nxt_gcc/target_syssvc_decl.cdl :
‒  tPutLogMindstormsNXT.cdl : 低レベル出⼒力力
‒  tSIOPortMindstormsNXT.cdl : シリアルドライバ
‒  NXTのデバイスドライバ、ミドルウェア
•  tecs_lib/mindstorms_nxt/target_lib_decl.cdl:
‒  tBluetooth_decl.cdl : Bluetooth
‒  tDisplay_decl.cdl,tLCD_decl.cdl,tSPI_decl.cdl : ディスプレイ
‒  tSound_decl.cdl : サウンド
‒  tAVR_decl.cdl,tTWI_decl.cdl : コプロセッサ
‒  tButton_decl.cdl : ボタン
‒  tBattery_decl.cdl : バッテリ
‒  tMotor_decl.cdl : モータ
‒  tSensor_decl.cdl : センサ
‒  tFlash_decl.cdl:フラッシュコントローラ
‒  tBalancer_decl.cdl : バランサ
TOPPERSプロジェクト認定 142012/06/02
ソフトウェアプラットフォーム(3/4)
•  提供するコンポーネントの⽣生成
‒  カーネル
•  target/mindstorms_nxt_gcc/target_syssvc_inst.cdl :
‒  低レベル出⼒力力
‒  シリアルドライバ
‒  tBluetooth_inst.cdl : NXTのBluetoothドライバ
‒  NXTのデバイスドライバ、ミドルウェア
•  tecs_lib/mindstorms_nxt/target_lib_inst.cdl:
‒  コプロセッサ
‒  ボタン
‒  ボタンチェック
‒  Flashコントローラ
※ その他のコンポーネントはユーザが⽣生成する
•  例
‒  モータ
‒  センサ
‒  バランサ
TOPPERSプロジェクト認定 152012/06/02
ソフトウェアプラットフォーム(4/4)
•  コンポーネント記述ファイルの読込み
‒  プラットフォームが提供するコンポーネントの定義や⽣生成
TOPPERSプロジェクト認定2012/06/02
//	 カーネルオブジェクトの定義

import("kernel.cdl");

//	 NXTのデバイスドライバ、ミドルウェアの定義

import(target_lib_decl.cdl);

//	 NXTのデバイスドライバ、ミドルウェアの生成

import(target_lib_decl.cdl);

//	 ターゲット依存のシステムサービスの定義

import("target_syssvc_decl.cdl");

//	 システムサービスの定義

import("syssvc/tSerialPort.cdl");

import("syssvc/tSysLog.cdl");

import("syssvc/tLogTask.cdl");

//	 ターゲット依存のシステムサービスの組上げ

import("target_syssvc_inst.cdl");

//	 ここからユーザアプリの記述

tSample.cdl
16
ミドルウェアの解説(1/2)
•  ボタンチェック周期ハンドラ(CheckNXTButton)
‒  機能概要
•  10ミリ秒周期でボタンの押下状態をチェックする
•  押下されているボタンに応じて以下の処理を⾏行行う
‒  STOP:プログラムを再起動する
‒  EXIT:プログラムを終了し、電源を切る
‒  STOP+ENTER:NXT BIOSを書き換え後、電源を切る
»  再度電源を⼊入れると、プログラムダウンロード可能な状態と
なる
•  Bluetooth接続タスク(ConnectBluetoothTask)
‒  機能概要
•  システムの起動時に起動する優先度2のタスク
•  NXTのBluetoothデバイス名を設定
•  NXTをスレーブとしてBluetooth接続を確⽴立立し、仮想シリアル
通信を可能にする
2012/06/02 TOPPERSプロジェクト認定 17
ミドルウェアの解説(2/2)
•  バランサ
‒  セルタイプ:tBalancer
‒  tBalancerセルのインタフェース
•  シグニチャ:sBalancer,受け⼝口:eBalancer
‒  void control([in] int16_t forward, [in] int16_t turn,
       [in] uint16_t gyro, [in] uint16_t gyroOffset,
     [in] int32_t leftRevolution,
               [in] int32_t rightRevolution,
     [in] uint16_t battery,
     [out] int8_t *pwm_l, [out] int8_t *pwm_r)
»  倒⽴立立制御に必要なモータのPWM値を求める
»  balance_controlと同様
2012/06/02 TOPPERSプロジェクト認定 18
ミドルウェアの⽣生成(1/3)
•  コンポーネント記述(組上げ記述)
※これは提供物に含まれているので、改めて記述する必要はな
い
‒  target_lib_inst.cdlからimportされる
//	 ボタンチェック周期ハンドラ

cell	 tCheckNXTButtonBody	 CheckNXTButtonBody	 {

	 	 cButton	 =	 Button.eButton;

	 	 //	 NXT	 BIOSを使用する場合、Flashを結合(ram+rom.cdl)

	 	 cFlash	 =	 Flash.eFlash;

};

cell	 tCyclicHandler	 CheckNXTButton	 {

	 	 ciBody	 =	 CheckNXTButtonBody.eiBody;

	 	 attribute	 =	 C_EXP("TA_STA");

	 	 cyclicTime	 =	 10;

	 	 cyclicPhase	 =	 1;

};

2012/06/02 TOPPERSプロジェクト認定 19
ram_only.cdl /
ram+rom.cdl
ミドルウェアの⽣生成(2/3)
•  コンポーネント記述(組上げ記述)
※これは提供物に含まれているので、改めて記述する必要はな
い
‒  target_syssvc_inst.cdlからimportされる
//	 Bluetooth接続タスク

cell	 tConnectBluetooth	 ConnectBluetooh	 {

	 	 cBluetooth	 =	 Bluetooth.eBluetooth;

};

cell	 tTask	 ConnectBluetoothTask{

	 	 cBody	 =	 ConnectBluetooth.eConnectBluetooth;



	 	 taskAttribute	 =	 C_EXP("TA_ACT");

	 	 priority	 =	 2;

	 	 stackSize	 =	 512;

};

2012/06/02 TOPPERSプロジェクト認定 20
tBluetooth_inst.cdl
参考情報
•  Bluetoothのキーコードとデバイス名の設定
‒  セルBluetoothの属性keyCodeと セル
ConnectBluetoothの属性deviceNameを設定する
•  デフォルト値はそれぞれ、 1234 と"ET1234"
2012/06/02 TOPPERSプロジェクト認定
tBluetooth_inst.cdl
cell	 tBluetooth	 Bluetooth	 {	 //	 Bluetooth本体

	 	 cSemaphore	 =	 BluetoothSemapohre.eSemaphore;

	 	 //	 キーコードの設定

	 	 keyCode	 =	 "1234";

};

cell	 tConnectBluetooth	 ConnectBluetooth	 {

	 	 cBluetooth	 =	 Bluetooth.eBluetooth;

	 	 //	 デバイス名の設定

	 	 deviceName	 =	 {	 'E',	 'T',	 '1',	 '2',	 '3',	 '4',	 '0'	 };

};





21
ミドルウェアの⽣生成(3/3)
•  セルタイプtBalancerの⽣生成例
‒  コンポーネント記述(組上げ記述)
//	 バランサ

cell	 tBalancer	 Balancer	 {

};

tSample_inst.cdl
2012/06/02 TOPPERSプロジェクト認定 22
デバイスドライバの解説(1/3)
•  バッテリ
‒  セルタイプ:tBattery
•  バッテリ電圧の残量を取得
•  モータ
‒  セルタイプ:tRotaryEncoder
•  モータの割込みハンドラと終了処理ルーチン
•  モータを使⽤用するときは、 tMotorDriver のインスタンスの呼
び⼝口とモータのインスタンスの受け⼝口を結合
‒  セルタイプ:tMotor
•  モータの回転数を取得/設定
•  モータのPWM値を設定
2012/06/02 TOPPERSプロジェクト認定 23
デバイスドライバの解説(2/3)
•  センサ
‒  セルタイプ:tSensorDriver
•  センサの初期化ルーチンとI2Cの割込みハンドラ
•  各種センサを使⽤用するときは、 tSensorDriver のインスタン
スの呼び⼝口と各種センサのインスタンスの受け⼝口を結合
‒  セルタイプ:tXXXSensor
•  各種センサのセンサ値を取得
•  XXXは、
‒  Light(光センサ)
‒  Gyro(ジャイロセンサ)
‒  Touch(タッチセンサ)
‒  Sonic(超⾳音波センサ)
TOPPERSプロジェクト認定 242012/06/02
デバイスドライバの解説(3/3)
•  シリアル通信
‒  セルタイプ:tSerialPort
•  シリアルポート(Bluetooth)を通じて、シリアル通信を⾏行行う
•  受信
•  送信(ログ出⼒力力)
TOPPERSプロジェクト認定 252012/06/02
デバイスドライバの⽣生成(1/6)
•  バッテリの⽣生成(組上げ記述)
//	 バッテリセンサ

cell	 tBattery	 Battery{

	 	 cAvrBattery	 =	 AVR.eAvrBattery;

};



2012/06/02 TOPPERSプロジェクト認定 26
tSample_inst.cdl
モータとセンサの接続ポート
•  モータ
‒  ポートA:尻尾モータ
‒  ポートB:右モータ
‒  ポートC:左モータ
•  センサ
‒  ポート1:ジャイロセンサ
‒  ポート2:超⾳音波センサ
‒  ポート3:光センサ
‒  ポート4:タッチセンサ
2012/06/02 TOPPERSプロジェクト認定 27
デバイスドライバの⽣生成(2/6)
•  モータの⽣生成(組上げ記述)
cell	 tMotor	 TailMotor{	 //	 尻尾モータ

	 	 cAvrMotor	 =	 AVR.eAvrMotor;

	 	 portNumber	 =	 NXT_PORT_A;

};

cell	 tMotor	 RightMotor{	 //	 右モータ

	 	 cAvrMotor	 =	 AVR.eAvrMotor;

	 	 portNumber	 =	 NXT_PORT_B;

};

cell	 tMotor	 LeftMotor{	 //左モータ

	 	 cAvrMotor	 =	 AVR.eAvrMotor;

	 	 portNumber	 =	 NXT_PORT_C;

};

2012/06/02 TOPPERSプロジェクト認定 28
tSample_inst.cdl
デバイスドライバの⽣生成(3/6)
•  モータの⽣生成(組上げ記述)
cell	 tRotaryEncoder	 RotaryEncoder{

	 	 ciMotorInterrupt[0]	 =	 TailMotor.eiMotorInterrupt;

	 	 ciMotorInterrupt[1]	 =	 RightMotor.eiMotorInterrupt;

	 	 ciMotorInterrupt[2]	 =	 LeftMotor.eiMotorInterrupt;

};

2012/06/02 TOPPERSプロジェクト認定 29
tSample_inst.cdl
デバイスドライバの⽣生成(4/6)
•  センサの⽣生成(組上げ記述)
cell	 tGyroSensor	 GyroSensor{	 //	 ジャイロセンサ

	 	 cAvrSensor	 =	 AVR.eAvrSensor;

	 	 portNumber	 =	 NXT_PORT_S1;

};

cell	 tSonicSensor	 SonicSensor{	 //	 超音波センサ

	 	 cAvrSensor	 =	 AVR.eAvrSensor;

	 	 portNumber	 =	 NXT_PORT_S2;

};

cell	 tLightSensor	 LightSensor{	 //	 光センサ

	 	 cAvrSensor	 =	 AVR.eAvrSensor;

	 	 portNumber	 =	 NXT_PORT_S3;

};

2012/06/02 TOPPERSプロジェクト認定 30
tSample_inst.cdl
デバイスドライバの⽣生成(5/6)
•  センサの⽣生成(組上げ記述)
‒  続き
cell	 tTouchSensor	 TouchSensor{	 //タッチセンサ

	 	 cAvrSensor	 =	 AVR.eAvrSensor;

	 	 portNumber	 =	 NXT_PORT_S4;

};



cell	 tSensorDriver	 SensorDriver{

	 	 ciSensorDriver[0]	 =	 GyroSensor.eiSensorDriver;

	 	 ciSensorDriver[1]	 =	 SonicSensor.eiSensorDriver;

	 	 ciSensorDriver[2]	 =	 LightSensor.eiSensorDriver;

	 	 ciSensorDriver[3]	 =	 TouchSensor.eiSensorDriver;

};

2012/06/02 TOPPERSプロジェクト認定 31
tSample_inst.cdl
デバイスドライバの⽣生成(6/6)
•  シリアルドライバの⽣生成(組上げ記述)
cell	 tSerialPort	 SerialPort1	 {	 //	 シリアルドライバ

	 	 //	 ターゲット依存部のシリアルドライバと結合

	 	 cSIOPort	 =	 SIOPortTarget.eSIOPort;

	 	 receiveBufferSize	 =	 256;

	 	 sendBufferSize	 =	 256;

};



2012/06/02 TOPPERSプロジェクト認定 32
tSample_inst.cdl
ユーザが作成する部分
TOPPERSプロジェクト認定 332012/06/02
コンポーネントの設計(1/7)
•  コンポーネントの設計
‒  シグニチャの定義
‒  セルタイプの定義
•  コンポーネントの実装
‒  コンポーネントの提
供する機能を実装
•  シグニチャとセルタイプ
の情報から⾃自動⽣生成され
たテンプレートコードを
利⽤用
•  C⾔言語実装
•  組上げ記述の作成
‒  組上げ記述によりア
プリケーションを構
築
コンポーネント
記述
組上げ記述
セルタイプ
コード
テンプレート
コード
コンパイラ
ヘッダ
インタフェース
コード
コンポーネント
設計者
コンポーネント
開発者
アプリケーション
開発者
設計
設計
実装
バイナリ
⾃自動⽣生成
⾃自動⽣生成
2012/06/02 TOPPERSプロジェクト認定 34
TECS
ジェネレータ
コンポーネントの設計(2/7)
•  シグニチャ定義
2012/06/02 TOPPERSプロジェクト認定 35
//	 尻尾ターゲット角制御のシグニチャ

signature	 sTailController{

	 	 void	 setAngle([in]	 int32_t	 angle);

	 	 void	 getAngle([out]	 int32_t	 *angle);

	 	 void	 signalStop(void);

	 	 void	 signalStart(void);

	 	 void	 calibrate(void);

};

//	 バランサタスクパラメータセット

//	 のシグニチャ

signature	 sBalancerControl{

	 	 void	 setSpeed([in]	 int16_t	 speed);

	 	 void	 getSpeed([out]	 int16_t	 *speed);

	 	 void	 setTurn([in]	 int16_t	 turn);

	 	 void	 getTurn([out]	 int16_t	 *turn);

	 	 void	 calibrate(void);

};



tSample_decl.cdl
//	 ライントレーサタスクパラメータセットの

//	 シグニチャ

signature	 sLinetracerControl{

	 	 void	 setLightThreshold	 ([in]	 uint8_t	 

	 	 	 	 	 	 	 	 	 	 	 	 	 	 color,	 [in]	 uint16_t	 light);

	 	 void	 getLightThreshold	 ([in]	 uint8_t	 	 	 

	 	 	 	 	 	 	 	 	 	 	 	 color,	 [out]	 uint16_t	 *light);

	 	 void	 setEdge([in]	 int8_t	 edge);

	 	 void	 getEdge([out]	 int8_t	 *edge);

};
コンポーネントの設計(3/7)
•  尻尾制御コンポーネント
2012/06/02 TOPPERSプロジェクト認定 36
[singleton]

celltype	 tTailControllerTaskBody{

	 	 require	 tKernel.eKernel;


	 	 entry	 sTaskBody	 eBody;

	 	 entry	 sTailController	 eTailController;

	 	 call	 sMotor	 cTailMotor; 


	 	 attr{

	 	 	 	 int32_t	 tailAngleStop;

	 	 	 	 int32_t	 tailAngleDrive;

	 	 	 	 float32_t	 kp;

	 	 	 	 int8_t	 maxPwm;

	 	 	 	 int8_t	 minPwm;

	 	 };

	 var{

	 	 	 	 int32_t	 targetAngle;

	 	 };

};

tSample_decl.cdl
コンポーネントの設計(4/7)
•  倒⽴立立⼆二輪制御コンポーネント
2012/06/02 TOPPERSプロジェクト認定 37
[singleton]

celltype	 tBalancerTaskBody{

	 	 require	 tKernel.eKernel;

	 	 entry	 sTaskBody	 eBody;

	 	 entry	 sBalancerControl	 eBalancerControl;

	 	 call	 sMotor	 cRightMotor;

	 	 call	 sMotor	 cLeftMotor;

	 	 call	 sSensor	 cGyroSensor;

	 	 call	 sBattery	 cBattery;

	 	 call	 sBalancer	 cBalancer; 


	 	 attr{

	 	 	 	 int16_t	 maxSpeed;

	 	 	 	 int16_t	 minSpeed;

	 	 };

	 	 var{

	 	 	 	 uint16_t	 gyroOffset;

	 	 	 	 int16_t	 speed;

	 	 	 	 int16_t	 turn;

	 	 };

};

tSample_decl.cdl
コンポーネントの設計(5/7)
•  ライントレース制御コンポーネント
2012/06/02 TOPPERSプロジェクト認定 38
[singleton]

celltype	 tLinetracerTaskBody{

	 	 require	 tKernel.eKernel;

	 	 entry	 sTaskBody	 eBody;

	 	 entry	 sLinetracerControl	 eLinetracerControl;

	 	 call	 sSensor	 cLightSensor;

	 	 call	 sSensorControl	 cLightSensorControl;

	 	 call	 sBalancerControl	 cBalancerControl;

	 	 attr{

	 	 	 	 int16_t	 maxTurn;

	 	 	 	 int16_t	 minTurn;

	 	 };

	 	 var{

	 	 	 	 uint16_t	 lightThreshold;

	 	 	 	 int8_t	 edge;

	 	 	 	 int16_t	 black;

	 	 	 	 int16_t	 white;

	 	 };

};

tSample_decl.cdl
コンポーネントの設計(6/7)
•  コマンド受信コンポーネント
2012/06/02 TOPPERSプロジェクト認定 39
[singleton]

celltype	 tGetCommandTaskBody{

	 	 require	 tKernel.eKernel;


	 	 entry	 sTaskBody	 eBody;	 	 	 	 	 

	 	 call	 sSerialPort	 cSerialPort;

	 	 call	 sSysLog	 cSysLog;

	 	 call	 sLinetracerControl	 cLinetracerControl;

	 	 call	 sBalancerControl	 cBalancerControl;

	 	 call	 sTailController	 cTailController;

	 	 call	 sSemaphore	 cSemaphore;

	 	 var{

	 	 	 	 int32_t	 parameter	 =	 0;

	 	 	 	 int8_t	 	 sign	 =	 1;

	 	 };

};



tSample_decl.cdl
コンポーネントの設計(7/7)
•  ⾛走⾏行行開始待ちコンポーネント
[singleton]

celltype	 tStarterTaskBody{

	 	 require	 tKernel.eKernel;


	 	 entry	 sTaskBody	 eBody;

	 	 call	 sCyclic	 cTailControllerTask;

	 	 call	 sCyclic	 cBalancerTask;

	 	 call	 sCyclic	 cLinetracerTask;

	 	 call	 sTailController	 cTailController;

	 	 call	 sSemaphore	 cSemaphore;

	 	 [optional]	 call	 sSensor	 cTouchSensor; 


};



2012/06/02 TOPPERSプロジェクト認定 40
tSample_decl.cdl
コンポーネントの実装(1/9)
•  コンポーネントの設計
‒  シグニチャの定義
‒  セルタイプの定義
•  コンポーネントの実装
‒  コンポーネントの提
供する機能を実装
•  シグニチャとセルタイプ
の情報から⾃自動⽣生成され
たテンプレートコードを
利⽤用
•  C⾔言語実装
•  組上げ記述の作成
‒  組上げ記述によりア
プリケーションを構
築
コンポーネント
記述
組上げ記述
セルタイプ
コード
テンプレート
コード
コンパイラ
ヘッダ
インタフェース
コード
コンポーネント
設計者
コンポーネント
開発者
アプリケーション
開発者
設計
設計
実装
バイナリ
⾃自動⽣生成
⾃自動⽣生成
2012/06/02 TOPPERSプロジェクト認定 41
TECS
ジェネレータ
コンポーネントの実装(2/9)
•  テンプレートコードの例(singletonなし)
‒  ⾃自動⽣生成される部分
TOPPERSプロジェクト認定 422012/06/02
void

eMotor_setPWM(CELLIDX	 idx,	 int8_t	 pwm,	 bool_t	 brakeMode)

{

	 	 CELLCB 

*p_cellcb;

	 	 if	 (VALID_IDX(idx))	 {

	 	 	 	 p_cellcb	 =	 GET_CELLCB(idx);

	 	 }

	 	 else	 {

	 	 	 	 /*	 エラー処理コードをここに記述します	 */

	 	 }



	 	 /*	 ここに処理本体を記述します	 #_TEFB_#	 */



}

gen/tMotor_templ.c
コンポーネントの実装(3/9)
•  テンプレートコードの例(singletonあり)
‒  ⾃自動⽣生成される部分
TOPPERSプロジェクト認定 432012/06/02
void

eBody_main()

{

}



gen/tStarterTaskBody_templ.c
コンポーネントの実装(4/9)
TOPPERSプロジェクト認定 442012/06/02
void

eBody_main()

{

	 	 //	 一部省略

	 	 cTailMotor_getRevolution(&rev);

	 	 pwm_f	 =	 (float32_t)(VAR_targetAngle	 -	 rev)	 *	 ATTR_kp;

	 	 if(pwm_f	 >	 (float32_t)ATTR_maxPwm){

	 	 	 	 pwm	 =	 ATTR_maxPwm;

	 	 }	 else	 if(pwm_f	 <	 (float32_t)ATTR_minPwm){

	 	 	 	 pwm	 =	 ATTR_minPwm;

	 	 }	 else	 {

	 	 	 	 pwm	 =	 (int8_t)pwm_f;

	 	 }

	 	 cTailMotor_setPWM(pwm,	 1);

}

tTailControllerTaskBody.c
結合先セルの
機能を呼び出す
⾃自⾝身の変数を
参照
⾃自⾝身の属性を
参照
コンポーネントの実装(5/9)
•  尻尾制御コンポーネント:tTailControllerTaskBody.c
‒  受け⼝口関数 eBody_main
•  尻尾モータを⽬目標⾓角度になるようにP制御する周期タスク本体
•  ⽬目標⾓角度は、変数targetAngle
‒  受け⼝口関数 eTailController_calibrate
•  尻尾モータのキャリブレーション
•  モータを逆回転させ、⽌止まった位置で、ロータリエンコーダの
回転数を初期化する
‒  受け⼝口関数 eTailController_signalStop
•  ⽬目標⾓角度を、NXTが⾃自⽴立立する際の位置に設定
‒  属性tailAngleStop
‒  受け⼝口関数 eTailController_signalStart
•  ⽬目標⾓角度を、NXTが⾛走⾏行行する際の位置に設定
‒  属性tailAngleDrive
‒  受け⼝口関数 eTailController_setAngle
•  ⽬目標⾓角度をセットする
‒  受け⼝口関数 eTailController_getAngle
•  ⽬目標⾓角度を取得する
TOPPERSプロジェクト認定 452012/06/02
コンポーネントの実装(6/9)
•  倒⽴立立⼆二輪制御コンポーネント:tBalancerTaskBody.c
‒  受け⼝口関数 eBody_main
•  倒⽴立立⼆二輪制御のためのパラメータを計算し、モータの出⼒力力を設定
する周期タスク
•  ⽬目標速度は、変数speed
•  ⽬目標舵⾓角は、変数turn
•  セルBalancerの機能により、パラメータ計算
‒  受け⼝口関数 eBalancerControl_calibrate
•  ジャイロセンサオフセット値のキャリブレーション
•  現在のジャイロセンサの値を、ジャイロセンサのオフセット値と
する(変数gyroOffset)
‒  受け⼝口関数 eBalancerControl_setXXX
•  ⽬目標速度/⾓角度を設定する
‒  XXXは、Speed / Turn
‒  受け⼝口関数 eBalancerControl_getXXX
•  ⽬目標速度/⾓角度を取得する
TOPPERSプロジェクト認定 462012/06/02
コンポーネントの実装(7/9)
•  ライントレース制御コンポーネント:tLinetracerTaskBody.c
‒  受け⼝口関数 eBody_main
•  光センサの値からライントレースのための舵⾓角を計算し、倒⽴立立⼆二輪
制御コンポーネントに伝達する周期タスク
•  光センサの値が閾値より⼤大きいか⼩小さいかを判定し、舵⾓角を決定す
る、単純な制御
•  光センサ値の閾値は、変数lightThreshold
‒  受け⼝口関数 eLinetracerControl_setLightThreshold
•  光センサ値の閾値をセットする
‒  引数に指定された値が有効範囲外であった場合には、現在の光センサ
の値を、光センサ値の閾値とする
‒  受け⼝口関数 eLinetracerControl_getLightThreshold
•  光センサ値の閾値を取得する
‒  受け⼝口関数 eLinetracerControl_setEdge/getEdge
•  ⾛走⾏行行時のエッジをセットする/取得する
TOPPERSプロジェクト認定 472012/06/02
コンポーネントの実装(8/9)
•  コマンド受信コンポーネント:tGetCommandTaskBody.c
‒  受け⼝口関数 eBody_main
•  シリアルポート(Bluetooth)経由でコマンドを受信し、制御
タスクのパラメータをセットする
‒  コマンドの形式:'整数''コマンド⼀一⽂文字'
•  'g'コマンド:⾛走⾏行行開始
‒  奇数'g'コマンドで左エッジスタート
‒  偶数'g'コマンドで右エッジスタート
‒  倒⽴立立⼆二輪制御コンポーネントのジャイロセンサオフセット値を
キャリブレーション(NXTが静⽌止しているはずなので、ジャイロ
センサオフセット値が適切に設定されるはず)
•  's'コマンド:停⽌止
•  'b'コマンド:光センサ(⿊黒)のキャリブレーション
•  'w'コマンド:光センサ(⽩白)のキャリブレーション
•  'l'コマンド:光センサ(⽬目標値)のキャリブレーション
•  'i'コマンド:出⼒力力するログの優先度をセット
•  'f'コマンド:スピードのセット
TOPPERSプロジェクト認定 482012/06/02
コンポーネントの実装(9/9)
•  ⾛走⾏行行開始待ちコンポーネント:tStarterTaskBody.c
‒  受け⼝口関数 eBody_main
•  プログラムの起動時の処理を⾏行行うタスク
•  尻尾モータを⾃自⽴立立時の位置に制御
‒  尻尾モータのキャリブレーション
‒  ⾃自⽴立立位置に⽬目標⾓角度を設定
‒  尻尾モータ制御タスクをstart
•  コマンド受信タスクから⾛走⾏行行開始のシグナルを受信する
‒  セマフォを使⽤用
‒  倒⽴立立⼆二輪制御タスクをstart
‒  尻尾モータの⽬目標⾓角度を⾛走⾏行行時の位置に制御
‒  ライントレース制御タスクをstart
TOPPERSプロジェクト認定 492012/06/02
アプリケーションの組上げ(1/8)
•  コンポーネントの設計
‒  シグニチャの定義
‒  セルタイプの定義
•  コンポーネントの実装
‒  コンポーネントの提
供する機能を実装
•  シグニチャとセルタイプ
の情報から⾃自動⽣生成され
たテンプレートコードを
利⽤用
•  C⾔言語実装
•  組上げ記述の作成
‒  組上げ記述によりア
プリケーションを構
築
TECS
ジェネレータ
コンポーネント
記述
組上げ記述
セルタイプ
コード
テンプレート
コード
コンパイラ
ヘッダ
インタフェース
コード
コンポーネント
設計者
コンポーネント
開発者
アプリケーション
開発者
設計
設計
実装
バイナリ
⾃自動⽣生成
⾃自動⽣生成
2012/06/02 TOPPERSプロジェクト認定 50
アプリケーションの組上げ(2/8)
2012/06/02 TOPPERSプロジェクト認定 51
•  TECSコンポーネント図 起動処理
ライントレース制御倒 輪制御
尻尾制御
センサドライバモータドライバ
ログ出
&
シリアル通信
コマンド受信
アプリケーションの組上げ(3/8)
•  尻尾制御コンポーネントの⽣生成
TOPPERSプロジェクト認定 522012/06/02
cell	 tTailControllerTaskBody	 TailControllerTaskBody{

	 	 cTailMotor	 =	 TailMotor.eMotor; 


	 	 tailAngleStop	 =	 108;

	 	 tailAngleDrive	 =	 0;

	 	 kp	 =	 2.5;

	 	 maxPwm	 =	 60;

	 	 minPwm	 =	 -60;

};

cell	 tCyclicTask	 TailControllerTask{

	 	 cBody	 =	 TailControllerTaskBody.eBody;

	 	 cyclicAttribute	 =	 C_EXP("TA_NULL");

	 	 cyclicTime	 =	 4;

	 	 cyclicPhase	 =	 1;

	 	 priority	 =	 5;

	 	 stackSize	 =	 512;

};



セルの結合
属性の設定
tSample_inst.cdl
アプリケーションの組上げ(4/8)
•  倒⽴立立⼆二輪制御コンポーネントの⽣生成
TOPPERSプロジェクト認定 532012/06/02
cell	 tBalancerTaskBody	 BalancerTaskBody{

	 	 cRightMotor	 =	 RightMotor.eMotor;

	 	 cLeftMotor	 =	 LeftMotor.eMotor;

	 	 cGyroSensor	 =	 GyroSensor.eSensor;

	 	 cBattery	 =	 Battery.eBattery;

	 	 cBalancer	 =	 Balancer.eBalancer;

	 	 maxSpeed	 =	 100;

	 	 minSpeed	 =	 -100;

};

cell	 tCyclicTask	 BalancerTask{

	 	 cBody	 =	 BalancerTaskBody.eBody;

	 	 cyclicAttribute	 =	 C_EXP("TA_NULL");

	 	 cyclicTime	 =	 4;

	 	 cyclicPhase	 =	 1;

	 	 priority	 =	 1;

	 	 stackSize	 =	 1024;

};



tSample_inst.cdl
アプリケーションの組上げ(5/8)
•  ライントレース制御コンポーネントの⽣生成
TOPPERSプロジェクト認定 542012/06/02
cell	 tLinetracerTaskBody	 LinetracerTaskBody{

	 	 cLightSensor	 =	 LightSensor.eSensor;

	 	 cLightSensorControl	 =	 LightSensor.eSensorControl;

	 	 cBalancerControl	 =	 BalancerTaskBody.eBalancerControl;

	 	 maxTurn	 =	 100;

	 	 minTurn	 =	 -100;

};

cell	 tCyclicTask	 LinetracerTask{

	 	 cBody	 =	 LinetracerTaskBody.eBody;

	 	 cyclicAttribute	 =	 C_EXP("TA_NULL");

	 	 cyclicTime	 =	 10;

	 	 cyclicPhase	 =	 1;

	 	 priority	 =	 4;

	 	 stackSize	 =	 512;

};



tSample_inst.cdl
アプリケーションの組上げ(6/8)
•  ⾛走⾏行行開始シグナル⽤用セマフォの⽣生成
TOPPERSプロジェクト認定 552012/06/02
cell	 tSemaphore	 StartSemaphore{

	 	 attribute	 =	 C_EXP("TA_NULL");

	 	 count	 =	 0;	 	 /*	 初期資源数は0	 */

	 	 max	 =	 1;	 	 	 	 /*	 最大資源数は1	 */

};



tSample_inst.cdl
アプリケーションの組上げ(7/8)
•  コマンド受信コンポーネントの⽣生成
TOPPERSプロジェクト認定 562012/06/02
cell	 tGetCommandTaskBody	 GetCommandTaskBody{

	 	 cSerialPort	 =	 SerialPort1.eSerialPort;

	 	 cSysLog	 =	 SysLog.eSysLog;

	 	 cLinetracerControl	 =	 LinetracerTaskBody.eLinetracerControl;

	 	 cBalancerControl	 =	 BalancerTaskBody.eBalancerControl;

	 	 cTailController	 =	 TailControllerTaskBody.eTailController;

	 	 cSemaphore	 =	 StartSemaphore.eSemaphore;

};

cell	 tTask	 GetCommandTask{

	 	 cBody	 =	 GetCommandTaskBody.eBody;

	 	 taskAttribute	 =	 C_EXP("TA_ACT");

	 	 priority	 =	 5;

	 	 stackSize	 =	 1024;

};



tSample_inst.cdl
アプリケーションの組上げ(8/8)
•  ⾛走⾏行行開始待ちコンポーネントの⽣生成
TOPPERSプロジェクト認定 572012/06/02
cell	 tStarterTaskBody	 StarterTaskBody{

	 	 cTailControllerTask	 =	 TailControllerTask.eCyclic;

	 	 cBalancerTask	 =	 BalancerTask.eCyclic;

	 	 cLinetracerTask	 =	 LinetracerTask.eCyclic;

	 	 cTailController	 =	 TailControllerTaskBody.eTailController;

	 	 cSemaphore	 =	 StartSemaphore.eSemaphore; 


};

cell	 tTask	 StarterTask{



cBody	 =	 StarterTaskBody.eBody;



taskAttribute	 =	 C_EXP("TA_ACT");



priority	 =	 6;



stackSize	 =	 1024;

};

tSample_inst.cdl

NXT走行体サンプルプログラム(ETロボコン向けTOPPERS活用セミナー3)