RobotStateMachine |
---|
class RobotStateMachine { private: static const int forward = 1; static const int pivotLeft = 2; static const int pivotRight = 3; int state; public: RobotStateMachine() { state = forward ; } void nextState ( int state ) { this->state = state; } int execute () { switch ( state ) { case forward: moveForward (); if ( obstacleToLeft ()) nextState ( pivotRight ); else if ( obstacleToRight ()) nextState ( pivotLeft ); break ; case pivotLeft: pivotLeft (); if ( obstacleToRight ()) nextState ( pivotRight ); else if ( ! obstacleToLeft ()) nextState ( forward ); break ; case pivotRight: pivotRight (); if ( obstacleToLeft ()) nextState ( pivotRight ); else if ( ! obstacleToRight ()) nextState ( forward ); break; } return state; } // 検出と動きに対する他のメソッドがここから始まる。 }; |
ラウンドロビン |
---|
一つの資源を順番に利用する手法。 ネットワークの負荷分散の場合、同様の構成にした系を複数用意して処理要求を順番に割り振ることをいう。ホスト名とIPアドレスの対応関係を利用して複数のサーバで負荷分散を行なう「DNSラウンドロビン」が有名。 コンピュータの並列処理の場合、各プロセスを一定時間ずつ順番に実行することをいう。「巡回的並列処理」とも呼ばれる。持ち時間を使い果たしたプロセスは一旦中断され、待ち行列の最後に回される。各プロセスに割り当てられるCPU時間の断片をタイムクォンタム(time quantum)もしくはタイムスライス(time slice)という。ラウンドロビン方式ではすべてのプロセスが平等に扱われる。 |
Event | ||||
Semaphore | ||||
Task | ||||
InterruptTask | ||||
TimerTask | ||||
TaskToneGenerator | ||||
CallableTask | ||||
WatchHeapTask | ||||
ShowStatus | ||||
TaskStatus | ||||
SemaphoreStatus |
Event.h | |
---|---|
/* * 協調的マルチタスク状態遷移マシンオペレーティングシステム * タスクはEventのサブクラスでタスクはEventによって再開される */ #ifndef _EVENT #define _EVENT #include "common.h" /** * イベントが生じたことを示すためのインターフェース */ class Event { public: static Event ev; static Event* nullEvent; static Event* checkEvent ( Event* event ); void notify( void* object ); void notify(); char* name (); Event (); Event (int x); String Name; }; #endif |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Event.cpp | |
---|---|
#include "Event.h" Event Event::ev; Event* Event::nullEvent= &Event::ev; Event* Event::checkEvent ( Event* event ) { return (event == nullEvent) ? nullEvent : event ; } void Event::notify( void* object ) { } void Event::notify() { notify(( void*)null); } char* Event::name () { return Name ; } Event::Event () { nullEvent = &ev; Name = "Event" ; } Event::Event (int x) { Name = "Event" ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
multi-thread |
---|
「thread」は「糸」という意味で、コンピュータ関連では、 プログラムの実行単位を表わす言葉として利用される。 一般に複数のプログラムが同時に実行可能なマルチタスクシステムでは、 それらの各プログラムに見掛け上、独立したメモリ空間やI/O空間などを 割り当てることで、それぞれのプログラムに対し、あたかもそれだけが 動いているように見せ掛ける。これにより各プログラムは、同時に実行 される他のプログラムとの相互作用を意識しなくてすむ。 マルチタスクシステムでは、このように、メモリ資源やディスク資源などを 独立して所有するプログラムの実行単位をプロセス(process。 「過程」の意)と呼んでいる。 しかしマルチタスクシステムが、あるプロセスから別のプロセスに実行を 切り替えるには、現在のCPUレジスタの内容をすべて保存し、これから制御を 切り替えるプロセスのためのレジスタ値をロードするなど、負荷が非常に 大きい(こうした処理により、プロセスの独立性が保証される)。 このような負荷の大きなプロセスの切り替え処理を必要とせず、同一 プロセス内でのマルチタスク処理を可能にしたものがマルチスレッド・ システムであり、この場合のタスクの実行の単位をスレッドと呼ぶ。 同一プロセス内のスレッド間では、処理の切り替えにかかる負荷が 小さく、またメモリやI/O資源などを共有するため、負荷の大きな プロセス間通信を伴わずに、スレッド間での通信が行なえるという メリットがある。 一般にマルチスレッドシステムでは、実行単位はすべてスレッドで 管理される。このためプロセスが生成されると、最低でも1つのスレッドが 同時に生成される。このようにプロセスを代表するスレッドを、 プライマリスレッド(primary thread)と呼んでいる。 |
Task.h | |
---|---|
#ifndef _TASK #define _TASK #include "Event.h" #include "mbed.h" class Task : public Event { public: const static int taskRunning=0; const static int taskSuspended=1; const static int taskSemaphoreWait=2; const static int initialState=0; const static int checkTimer=-1; // sleep()のサポート用 const static int _interrupt=-2; // InterruptTaskを見よ const static int terminate=-3; const static int stopped=-4; Timer timer; Task(); // コンストラクタ static void addTask(Task* aNewTask); char* name (); int taskStatus(); int getState (); bool suspend (); static bool removeTask(Task* aTaskToRemove); bool stop(); bool resume (); bool start(); void notify( void* object ); void nextState(int state); void sleep(int state); void sleep ( int nextState, unsigned int hi, unsigned int lo ) ; void sleep ( int nextState, int timeMS ) ; void sleepSec ( int nextState, int timeS ); static Task* getCurrentTask (); virtual int timeout(int tm); virtual int timeout(int hi, int lo); static void TaskManager(); static Task* currentTask; Task* nextTask; int __taskStatus ; int state; static Task* taskStatusList; Task* nextTaskStatus; static Task* taskList; protected: virtual void execute(){} int sleepState; int hi, lo; }; #endif |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
Task.cpp | |
---|---|
#include "Task.h" Task* Task::taskStatusList = (Task*)null ; Task* Task::taskList = (Task*)null; Task* Task::currentTask = (Task*)null ; Task::Task() { timer = Timer(); addTask ( this ) ; // タスクをステータスリストに加える nextTaskStatus = taskStatusList ; taskStatusList = this ; state = initialState; sleepState = checkTimer; Name = "Task"; } void Task::addTask(Task* aNewTask) { if ( Task::taskList == (Task*)null ) { aNewTask->nextTask = aNewTask ; } else { aNewTask->nextTask = taskList->nextTask ; taskList->nextTask = aNewTask ; } aNewTask->__taskStatus = taskRunning ; taskList = aNewTask ; } bool Task::removeTask(Task* aTaskToRemove) { // 空のリストを始めに処理する if ( taskList != (Task*)null ) { // 現在のタスクからリストを走査し見つかったらそれを削除する Task* scanTask = taskList ; do { if ( scanTask->nextTask == aTaskToRemove ) { // 削除するタスクが見つかった if ( scanTask == aTaskToRemove ) { // リストの中の一つだけのタスクを削除する taskList = (Task*)null ; } else { // 現在のタスクが削除されたかどうかチェックする if ( taskList == aTaskToRemove ) { taskList = aTaskToRemove->nextTask ; } scanTask->nextTask = aTaskToRemove->nextTask ; } aTaskToRemove->nextTask = (Task*)null ; return true ; } // リストの中の次のタスクをチェックする scanTask = scanTask->nextTask ; } while ( scanTask != taskList ); //全てのリストが走査されたら脱出 } return false ; } void Task::TaskManager() { Task *p, *q; while ( taskList != (Task*)null ) { // execute()がremoveTaskを通して変えることができるように // taskListを変える q = p = taskList; while(p != (Task*)null) { p = p->nextTask; if(p == q) break; } currentTask = taskList ; taskList = taskList->nextTask ; if (currentTask->state == checkTimer) { // タスクがタイムアウトを待機している if (currentTask->timeout(currentTask->hi,currentTask->lo)) { // タイムアウトが起こったら、次の状態を設定する currentTask->state = currentTask->sleepState ; // もし、次の状態が不適切に設定されていたらば抜け出す if ( currentTask->state == checkTimer ) { currentTask->state = terminate ; } } } else { // 次の状態を呼び出す currentTask->execute () ; } } } int Task::timeout(int tm) { if( timer.read_ms() >= tm) return true; else return false; } int Task::timeout(int hi, int lo) { if( timer.read_ms() >= lo) return true; else return false; } void Task::sleep ( int nextState, int timeMS ) { sleep ( nextState, 0, timeMS); } char* Task::name () { return Name ; } int Task::taskStatus() { return __taskStatus; } int Task::getState () { return state ; } bool Task::suspend () { if ( __taskStatus == taskRunning ) { // 注意: nextTaskがnullでなかったらマネージャーはnull // であってはいけない __taskStatus = taskSuspended ; return removeTask ( this ) ; } return false ; } bool Task::stop() { if ( suspend ()) { state = stopped ; return true ; } return false ; } bool Task::resume () { if ( __taskStatus == taskSuspended ) { // 注意: マネージャーはnextTaskがnullでなかったならばnullで // であってはいけない addTask ( this ) ; return true; } return false ; } bool Task::start() { return resume () ; } void Task::notify( void* object ) { resume () ; } void Task::nextState(int state) { this->state = state ; } void Task::sleep(int state) { this->state = state ; suspend(); } void Task::sleep ( int nextState, unsigned int hi, unsigned int lo ) { this->hi = hi; this->lo = lo; timer.reset(); sleepState = nextState ; state = checkTimer ; } void Task::sleepSec ( int nextState, int timeS ) { sleep ( nextState, 0, timeS*1000);} // タスクマネージャーサポート Task* Task::getCurrentTask () { return currentTask ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
class task1 extends Task { private: static const int initialState = 1 ; static const int newState = 2 ; static const int anotherState = 3 ; public: void execute () { switch ( state ) { case initialState: // この状態で行うことを記述 break; case newState: // この状態で行うことを記述 break; case anotherState: // この状態で行うことを記述 break; default: stop (); break; } } } ;変数の前についているstatic const intは整数型の定数を表しています。状態の数字はユニークである必要があります。それには連番が簡単ですが、そのようにしなければならないことはありません。定数値が使われると実際の値は無関係です。同様に状態定数は正の数値にすべきです。 ゼロとマイナスの数値は内部のTaskManagerの使用のために確保されています。