2011/12/26

OpenCVで作るビジョンプログラム(5)

お疲れさまです。Shinpukuです。

白線情報を元にした自己位置推定法では、白線をいかに多く検出できるかが鍵となります。

メジャーなのはスキャンライン(走査線)を使った方法です。
最新のプログラムでは、スキャンラインは近・中・遠距離の3段構成でそれぞれ32本、64本、128本配置されています。多段構成にすることで、手前の白線だけでなく、その奥の白線も検出することが出来ます。

では、ソースコードを見ながら白線検出アルゴリズムを説明していきます。

cvThresholdで白色を抽出し、前回検出したフィールド領域との論理積をとります。白色は輝度が高いのでYに閾値を設定すればすぐに抽出できます。白線以外のものを検出しないようにマスクをかけるとなお良いでしょう。

スキャンラインの総数は以下の式で求められます。
コードにするとこんな感じです。

const int LAYER_NUM = 3;
const int LINE_NUM = 32;
const int TOTAL_LINE_NUM = (LINE_NUM*((1<<LAYER_NUM)-1));

i番目のスキャンラインの開始・終了点は以下の式で求められます。
求めた式を元に、画像の中心からスキャンラインを伸ばし、白線を検出します。

void Vision::detectLines(Data &data)
{
    const int minLen = 35;
    const int maxLen = 110;

    // フィールドとの論理積
    cvAnd(images.cvWhite, images.cvField, images.cvLines);

    // ここから白線検出
    for (int i = 0; i < LAYER_NUM; i++) {
        // スキャンライン数
        int lineNum = LINE_NUM * (1<<i);
        // 角度の変化
        double theta_k = (2.0 * M_PI) / lineNum;
        // 始点・終点
        int start = (int)(minLen + (i+0) * (maxLen - minLen) / LAYER_NUM);
        int end   = (int)(minLen + (i+1) * (maxLen - minLen) / LAYER_NUM);
        // スキャンラインを走査
        for (int j = 0; j < lineNum; j++) {
            // i層j番目のスキャンライン
            int k = LINE_NUM * ((1<<i)-1) + j;
            // スキャンライン角度
            double theta = -(j * theta_k + M_PI/2.0);
            // 初期化
            lines[k].distance = -1.0;
            lines[k].angle = 0.0;
            // 始めから終わりまで
            for (int l = start; l < end; l++) {
                CvPoint scanline;
                scanline.x = (int)(l * cos(theta) + images.center.x);
                scanline.y = (int)(l * sin(theta) + images.center.y);
                uchar val = CV_IMAGE_ELEM(images.cvLines, uchar, scanline.y, scanline.x);
                // 白線が見つかった
                if (val > 0) {
                    // 検出した白線を表示
                    lines[k].angle = CV_IMAGE_ELEM(images.cvAngle, float, scanline.y, scanline.x);
                    lines[k].distance = CV_IMAGE_ELEM(images.cvDistance, float, scanline.y, scanline.x);
                    break;
                }
            }
        }
    }
}
次回はパーティクルフィルタを用いた自己位置推定アルゴリズムを詳しく解説していこうと思います。

2011/12/23

進捗

こんにちは、Noguchiです。

今日は今(12/14現在)の活動内容を簡単に紹介します。


まず、ハード班です。

Shimizuはバッテリー部の改良です。
以前より、バッテリーの故障が目立っていました。
調べていくうちに様々な問題点が浮き彫りになってきており、現在改良中です。
この件については、年明けにでもブログ1回分取って、詳細説明いたします。

Tsutsumiはロボットカバーの改良とキッカー部分のリフター付けです。
カバーは以前に比べて、取り外しがしやすいものへと変更いたしました。
リフター部に関しては、キッカー部分に付けています。
図の○の箇所になります。

これを付けることにより、ボールと蹴ったときに浮いたボール、俗に言うループボールを
放つことが出来るようになりました。
しかしながらこれを付けたことにより、ドリブル等の別の問題点が発生すると話し合いにより、
判断し、更なる改良が必要だと考えております。


次にソフト班です。

InoueはPKの改良を行いました。
人間の行うPKとは異なり、ロボットはセンターサークルより動き始め、30秒以内に
ボールを蹴るというのが、ロボカップサッカー中型リーグにおけるルールです。
ルールに基づき、プログラムを新しいものへ変更いたしました。
ゴール確率もある程度期待できるモノになっております。
今後はインプレイ中のシュート条件の改良を行って行く予定です。

Noguchiは経路計画の再考をしております。
現在、机上で検討しております。
検討終了後に、プログラムへ移行する予定です。
こちらに関しても、詳しい事が言える段階で説明いたします。

Takenakaはゴールキーパーのプログラムを新バージョンへ移植しております。



--

先日の清掃の続きを行いました。

問題の倉庫でしたが、棚や道具の配置替えをし、必要用途や頻度に
合わせて棚の整理をしただけで、きれいになりました。

残りは、いろいろな場所に転がっていたネジの分類分けと雑用です。
地味な作業ではありますが、大事なことです。


"塵も積もれば山となる"ですね。

2011/12/19

OpenCVで作るビジョンプログラム(4)

こんにちは、Shinpukuです。

今回はフィールド領域の検出を行います。

これはフィールド外の物体を誤って検出しないようにするためです。

それではアルゴリズムを紹介していきます。

まず、閾値処理により緑色を抽出します。
次にノイズ除去のため膨張・収縮を行います。
一番大きい領域のみ残します。
cvConvexHull2関数を用いて欠けた領域の補間を行います。
これでフィールド領域を検出することが出来ました。

黄色や白色との論理積を取ることでボールや白線を検出することができます。 

コードは以下の通りです。

void Vision::detectField(Data &data)
{
    double max = 0;
    CvSeq *contour = NULL, *maxContour = NULL;
    CvMemStorage *contourStorage = cvCreateMemStorage();
    // 膨張・縮小
    cvMorphologyEx(images.cvGreen, images.cvField, NULL, NULL, CV_MOP_CLOSE);
    // 中心円を描く
    const int radius = MIN(IMAGE_HALF_WIDTH, IMAGE_HALF_HEIGHT) * 0.3;
    cvCircle(images.cvField, images.center, radius, cvScalarAll(255), -1);
    // 輪郭を抽出
    cvFindContours(images.cvField, contourStorage, &contour, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
    // 一番大きい領域を求める
    while (contour) {
        double size = fabs(cvContourArea(contour, CV_WHOLE_SEQ));
        if (size > max) {
            maxContour = contour;
            max = size;
        }
        contour = contour->h_next;
    }
    // 初期化
    cvZero(images.cvField);
    // 見つかった
    if (maxContour) {
        // 凸包を求める
        CvSeq *hull = cvConvexHull2(maxContour);
        // 凸包を構成する点
        CvPoint *pts = new CvPoint[hull->total];
        for(int i = 0; i < hull->total; ++i) pts[i] = **(CvPoint**)cvGetSeqElem(hull, i);
        // フィールド領域を描画
        cvFillConvexPoly(images.cvField, pts, hull->total, cvScalarAll(255));
        cvAnd(images.cvField, images.cvMask, images.cvField);
        // メモリ解放
        delete [] pts;
    }
    // メモリ解放
    cvReleaseMemStorage(&contourStorage);
}
次回は白線を検出してみようと思います。

2011/12/14

御挨拶と年末大掃除

お初に目にかかります。
2012年度ソフト班・HP担当になりましたNoguchiです。
今後、Hibikino-Musashiの日々の活動や技術的なお話ができればと思っております。
文章能力に欠ける私でありますが、温かく見守っていただけると幸いです。

--

先代より代替わりが行われ、早2ヶ月が経つでしょうか。

先日、年末ということもあり、部屋の大掃除を行いました。

片付けの最中です ( 掃除前の画像は取り忘れました… )



表だけでこれだけのゴミが出ました。
予想していたよりは意外と少なかったですね。






問題だった工具類の整理も我らがハード班Shimizuのおかげでこんなにきれいになりました。



数時間かけ、はきれいになりました。は…。

はい、まだ倉庫には手を付けていません。
たぶん表とは比べ物にならない大物が待ち構えていると思います。

はぁ~、まだまだ先が思いやられます。

2011/12/12

OpenCVで作るビジョンプログラム(3)

こんにちは、Shinpukuです。

今回は色抽出についてお話しします。

カメラから得た画像の中には、ボールや白線といった私たちが欲しい情報が含まれています。
具体的には黄色(オレンジ)、緑、白、黒がそれに当たります。

色抽出の前にカメラ画像の色空間をRGBからYUV(YCbCr)に変換します。
// RGB->YUV色変換
cvCvtColor(images.cvCamera, images.cvCameraYUV, CV_RGB2YCrCb);
cvSplit(images.cvCameraYUV, images.cvY, images.cvU, images.cvV, NULL);

YUVは明るさの変化に強く、ロボカップで用いられている色を簡単に表現することができます。
カメラからYUV422で出力されるのですがRGB->HSV変換の名残や僕の勉強不足のせいでこうなっています。

YUVの各チャンネルで閾値を設定して画像を2値化します。

OpenCVで代表的なものはcvThreshold、cvInRangeS、cvLUTですが、私たちのプログラムでは速度を優先してcvThresholdを用いています。
// 色抽出
cvThreshold(images.cvY, images.cvYellow, thresholds.maxYellowY, 0, CV_THRESH_TOZERO_INV);
cvThreshold(images.cvYellow, images.cvYellow, thresholds.minYellowY, 255, CV_THRESH_BINARY);
cvThreshold(images.cvU, images.cvBuf, thresholds.maxYellowU, 0, CV_THRESH_TOZERO_INV);
cvThreshold(images.cvBuf, images.cvBuf, thresholds.minYellowU, 255, CV_THRESH_BINARY);
cvAnd(images.cvYellow, images.cvBuf, images.cvYellow);
cvThreshold(images.cvV, images.cvBuf, thresholds.maxYellowV, 0, CV_THRESH_TOZERO_INV);
cvThreshold(images.cvBuf, images.cvBuf, thresholds.minYellowV, 255, CV_THRESH_BINARY);
cvAnd(images.cvYellow, images.cvBuf, images.cvYellow);

cvLUTは3ch→1chへの変換が出来ず、なぜかcvThresholdよりも遅いため使っていません。

cvInRangeSを使うと低速ですが、綺麗なコードになります。
// 色抽出
CvScalar lower = cvScalar(thresholds.minYellowY, thresholds.minYellowU, thresholds.minYellowV);
CvScalar upper = cvScalar(thresholds.maxYellowY, thresholds.maxYellowU, thresholds.maxYellowV);
cvInRangeS(images.cvCameraYUV, lower, upper, images.cvYellow);

色抽出の結果は以下のようになります。

2011/12/05

OpenCVで作るビジョンプログラム(2)

お疲れさまです。Shinpukuです。

本題に入る前に、私たちのプログラムに用いられている座標系についてお話ししようと思います。

ロボットの基本的な座標系は、フィールドの中心を原点とした右手座標系です。プログラム中では「絶対座標系」と呼ばれます。
 
これとは別に、ロボットを原点とした座標系は「相対座標系」と呼ばれます。
カメラから見える物体の位置は相対座標系となります。画像中の座標から実際の座標に変換するために、私たちは「距離・角度マップ」というものを作っています。
左の画像は距離、右の画像は角度を表しています。

距離はExcel等を使って、ピクセル距離から実距離に変換する式を求めます。
角度は簡単で、反時計回りを正として角度(+π~-π)を指定してきます。

プログラム中では、距離・角度マップはOpenCVで扱いやすいようにIplImageとして保存します。例えば、距離マップは32bitの1チャンネル画像として生成します。

#define IMAGE_HEIGHT  240
#define IMAGE_WIDTH   240
CvSize size = cvSize(IMAGE_WIDTH, IMAGE_HEIGHT);
IplImage *cvDistance = cvCreateImage(size, IPL_DEPTH_32F, 1);

マップの保存は、

// ピクセル距離と実距離(サンプル)
double pixel[] = {0,  30,  37,  43,  48,  53,  57,  61,  76,  85,  91,  96,  99, 103, 105, 106};
double distance[] = {0.0, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0};
// 5次多項式近似で求めた係数
double x[] = {-0.000984, 0.058100, -0.003357, 0.000089, -0.000001, 0.000000};
// 画像中心
CvPoint center = cvPoint(cvDistance->width/2, cvDistance->height/2);
for (int i = 0; i; cvDistance->height; i++) {
    for (int j = 0; j; cvDistance->width; j++) {
        // 画像中心から(i,j)までの距離
        int r = hypot(i - center.x, j - center.y);
        // pixel_distanceを近似関数に入力したときの距離
        double dist = x[5]*pow5(r) + x[4]*pow4(r) + x[3]*pow3(r) + x[2]*pow2(r) + x[1]*r + x[0];
        // 書き出し
        fwrite((float*)&dist, sizeof(float), 1, file);
    }
}

このように、バイナリでもASCIIでもいいので何かのファイルに保存します。
こうすれば毎回計算しなくて済みますね。

マップを読み込むときは、

for (int i = 0; i; cvDistance->height; i++) {
    for (int j = 0; j; cvDistance->width; j++) {
        fread((float*)cvDistance->imageData + i * cvDistance->width + j, sizeof(float), 1, file);
    }
}

IplImage構造体をマップのデータで埋めます。

結局何がしたいのかというと、画像中で見えている物体をこのように、
対応する距離と角度を一発でバシッと決めてやりたいのです。

// 距離・角度
double distance = CV_IMAGE_ELEM(cvDistance, float, img_y, img_x);
double angle = CV_IMAGE_ELEM(cvAngle, float, img_y, img_x);

CV_IMAGE_ELEMマクロを使えばこんなに簡単!

前回と同様、ちょっとした工夫ですが、かなり役に立ちます。

最後に、自己位置情報を用いると、

// 絶対座標系に変換
pos.x = data.position.x + distance * cos(angle + data.position.angle);
pos.y = data.position.y + distance * sin(angle + data.position.angle);

このように相対座標系から絶対座標系へ変換できます。

次回は色抽出をしてみましょう。

2011/12/01

OpenCVで作るビジョンプログラム(1)

お久しぶりです。

Hibikino-MusashiメインプログラマーShinpukuです。

今年はイランオープンにジャパンオープン、世界大会、秋季大会といろいろあって大変なとても充実した一年でした。

中型リーグの交流会もあり、ロボットのプログラムについて熱心な意見交換が行われていました。このブログを見てプログラムの参考にしているという話も聞き、他のチームの役に立ててもらって僕も嬉しい限りです。

さて、今回は質問の多かったビジョンについてお話ししようと思います。

僕たちのロボットには全方位カメラが搭載されてあり、これから画像を取得します。


カメラはSONY製のDFW-VL500です。ドライバは標準のものではなく、CMUのドライバを使っています。

取得したカメラ画像をビジョンで扱いやすいように加工します。
・BGR→RGB変換
・反転(鏡に映している為)
・カメラの取り付け角度に応じて回転
・240×240にトリミング

コードはこのようになります。

int Camera::getImage(IplImage *image)
{
    const int img_w = image->width, img_h = image->height; 
    const int cam_w = CAMERA_WIDTH, cam_h = CAMERA_HEIGHT;
    const int tmp_w = MAX(cam_w, cam_h), tmp_h = tmp_w;
    // 画像取得
    int camError = theCamera.AcquireImageEx(FALSE, NULL);
    // カメラの接続チェック
    if (camError != CAM_SUCCESS) {
        if (camError == CAM_ERROR_NOT_INITIALIZED) printf("Camera is not initialized.\n");
        printf("Some camera trouble.\n");
        return 0;
    }
    // 作業用イメージ
    IplImage *rawCamera = cvCreateImage(cvSize(cam_w, cam_h), IPL_DEPTH_8U, 3);
    IplImage *tmpCamera = cvCreateImage(cvSize(tmp_w, tmp_h), IPL_DEPTH_8U, 3);
    // 画像取得
    theCamera.getRGB((uchar*)rawCamera->imageData, rawCamera->imageSize);
    cvConvertImage(rawCamera, rawCamera, CV_CVTIMG_SWAP_RB);
    // コピー
    cvZero(tmpCamera);
    cvSetImageROI(tmpCamera, cvRect((tmp_w-cam_w)/2, (tmp_h-cam_h)/2, cam_w, cam_h));
    cvCopy(rawCamera, tmpCamera);
    cvResetImageROI(tmpCamera);
    cvReleaseImage(&rawCamera);
    // 反転(鏡に映しているため)
    cvFlip(tmpCamera, tmpCamera);
    // 回転
    IplImage *clnCamera = cvCloneImage(tmpCamera);
    CvMat *rotation = cvCreateMat(2, 3, CV_32FC1);
    CvPoint2D32f center = cvPoint2D32f(tmp_w/2, tmp_h/2);
    cv2DRotationMatrix(center, offset.angle, 1.0, rotation);
    cvWarpAffine(clnCamera, tmpCamera, rotation);
    cvReleaseMat(&rotation);
    cvReleaseImage(&clnCamera);
    // ROIで切り抜き
    CvRect ROI = cvRect((tmp_w-img_w)/2 + offset.x, (tmp_h-img_h)/2 + offset.y, img_w, img_h);
    if (ROI.x < 0) ROI.x = 0;
    if (ROI.y < 0) ROI.y = 0;
    if (ROI.x > (tmp_w - img_w)) ROI.x = tmp_w - img_w; 
    if (ROI.y > (tmp_h - img_h)) ROI.y = tmp_h - img_h; 
    cvSetImageROI(tmpCamera, ROI);
    cvCopy(tmpCamera, image);
    cvReleaseImage(&tmpCamera);
    return 1;
}

最終的に出力される画像はこのようになります。画像の上下左右はロボットの前後左右と対応しています。
面倒なことをしていますが、こうすることでこの後の処理がとてもわかりやすくなります。

ビジョンではいろいろな処理をしていますが、今回はこの辺で。

2011/09/25

イオン若松デモ


今年もイオン若松にてロボットのデモを行いました。
 ロボットとのPK対決は毎回大人気です。
11月には「ひびきの祭」が開催されます。

皆様のご来場を心待ちにしています。

2011/09/14

ロボカップ秋季大会2011


9月14日(水)に福井大学文京キャンパスにおいてロボカップ中型リーグ秋季競技会2011が開催されました。

結果は堂々の優勝、世界レベルのチームの実力を見せつける形となりました。

もはや恒例となりつつあるロボカップ懇親会も開かれました。他大学のチームとの親睦を深めるだけでなく、技術的な交流もできました。

皆様のご声援のおかげもあり、このような結果を残すことができました。

メンバー 一同感謝しております。

今後とも変わらぬご指導ご鞭撻の程よろしくお願い申し上げます。

2011/08/11

OB訪問

今日はチームのOBである米村さんがチーム訪問に来て下さいました。

米村さんは2007年アトランタのテクニカルチャレンジ部門で見事チームを優勝に導いた方です。
久々にPlayerのプログラムに触れる米村さん。

ゴーリーと戯れる米村さん。
当時はアームは可動式ではなかったので、ボールに対して素早く反応するゴーリーアームにとても驚かれていました。
当時のメンバーでもある北住さんとも久しぶりに再会され、とても楽しい時間を過ごされたようでした。

また来て下さいね!

2011/07/11

RoboCup 2011 TURKEY

RoboCup世界大会2011イスタンブールに参加しました。

場所:イスタンブールエキスポセンター
日時:7月5日(火)~7月11日(月)


今年はトーナメント戦では6位、テクニカルチャレンジ部門では優勝と、去年よりも良い成績を修めることが出来ました。特にテクニカルチャレンジにおいては、5年ぶりに世界1位になることが出来ました。

今回の成績は、様々な方のご声援やご支援の賜物であると思っております。今後ともHibikino-Musashiへのご声援をよろしくお願いします。

2011/07/10

RoboCup 2011 - 最終日 -

今日はMRLとの5位6位決定戦です。

調整の成果が現れたのか、予選の時とは全く異なり、どちらのロボットもよく動いています。


Hibikikno-Musashiは相手陣地で攻撃する機会が多くありましたが、一歩及ばず0対0の引き分けとなり、世界大会5位を賭けた戦いは、PK戦に持ち越されました。

PK戦では、1本シュートを決めたMRLが勝利し、Hibikikno-Musashiは6位となりました。

2011/07/09

RoboCup 2011 - 予選3日目 -

今日は昨年度優勝チームとの試合があります。

Hibikino-Musashi 2 - 6 Water

Hibikino-Musashi 0 - 0 RFC Stuttgart

2勝1敗引き分けで、2次予選を2位で通過しました。

次は3次予選です。どこも強豪揃いです。

Hibikino-Musashi 1 - 12 Tech United

Hibikino-Musashi 1 - 6 CAMBADA

本当に強いチームでしたが、なんとか1点を取ることができました。

明日はMRLとの5位6位決定戦があります。ぜひとも勝ちたいところです。

2011/07/08

RoboCup 2011 - 予選2日目 -

昨日に引き続き、予選2日目です。

Hibikino-Musashi 0 - 0 Carpe Noctem

2勝2敗1引き分けで1次予選を4位で通過し、2次予選に進みます。


Hibikino-Musashi 12 - 0 IsocRob
Hibikino-Musashi 1 - 0 Carpe Noctem

2011/07/07

RoboCup 2011 - 予選1日目 -

今日から予選が始まります。

Hibikino-MusashiはBグループでの試合となります。


Hibikino-Musashi 0 - 6 MRL
Hibikino-Musashi 0 - 7 Tech United
Hibikino-Musashi 5 - 0 Minho
Hibikino-Musashi 4 - 0 5DPO

2011/07/06

RoboCup 2011 - TC&FC -

全チームが通信のチェックを終え、いよいよテクニカルチャレンジとフリーチャレンジが始まります。

今年のテクニカルチャレンジの内容は去年と同じく、2台のロボットで
・色不定のボールを検出 (+1pt)
・パスを出す (+1pt)
・パスを受け取る (+1pt)
・ゴールする (+1pt)
となっています。


今年はフィールドの色が特殊で多くのチームが苦戦する中、Hibikino-Musashiのロボットは確実にボールを検出し、2回目のチャレンジでは、パスからのゴールが決まり、4点を獲得しました。

総得点7点を取り、テクニカルチャレンジ部門では1位に輝きました。

また。フリーチャレンジでは、シリコン網膜センサを用いたロボットビジョンや新しくロボットに組み込んだ機構について発表し、6位になりました。

明日からいよいよ本戦が始まります。

2011/07/05

RoboCup 2011 - 調整日 -

昨日の夜に現地入りしました。

会場は広く、世界各国から様々なチームが来ています。

私たちも早速ロボットの調整に取りかかります。


明日はテクニカルチャレンジとフリーチャレンジがあります。良い成績を残せるよう、気を引き締めて臨みたいと思います。

2011/07/03

ロボット梱包

世界大会まであと2日となりました。

今日はロボットの梱包を行ないます。


次々と分解されるロボットたち。


ゴーリーも分解します。慣れたものです。


ついでにリーダーも梱包しておきましょう。


冗談です(笑)。

明日の早朝に出発します。メンバー 一同、万全の状態で臨みたいと思います。

それでは!

2011/07/01

世界大会に向けて

今年も世界大会まであと僅かとなりました。

先月から大会に向けてプログラムのチェックやハードウェアの改良を行なっています。

新しく加わったメンバーも電子回路の作成に励んでいます。


特に今年は日本大会のみならず、イラン大会の参加もあり、メンバー全員ギリギリのスケジュールで動いていますが、一所懸命頑張った甲斐もあり、何とか形になってくれそうです。

2011/05/28

ROBOMEC2011岡山

日本機械学会ロボティクス・メカトロニクス講演会に行ってきました。
http://www.jsme.or.jp/rmd/robomec2011/index.html

私たちのチームからは7名がポスターセッションで発表しました。


我らがチームリーダーも参加!
全方位・単眼カメラを用いた3次元位置検出について発表しました。


今回、メンバーのほとんどが初めての学会発表で緊張していた部分もありましたが、たくさんの人との交流があり、とても良い経験になったと思います。

2011/05/21

九工大オープンキャンパス(若松)

今日は九州工業大学大学院のオープンキャンパスがありました。

ロボカップでは、ロボットの説明やPKのデモンストレーションを行いました。


@Homeのロボットも登場!


人の顔を認識して追従してくれるそうです。

これから大学院への進学を考えている方、一緒にロボカップをやってみませんか?

2011/05/07

RoboCup Japan Open 2011 Osaka

ロボカップジャパンオープン2011大坂(5/3~5/5、インテックス大坂)に参加しました。


結果は7戦7勝0敗で今年も優勝、テクニカルチャレンジでも1位という成績を修めました。

また、技術デモでは、ロボットの自己位置推定と協調行動を披露し、今年はロボット学会賞を頂きました。

多くの方々の支援により、このような素晴らしい成績を残すことができました。トルコで開催される世界大会におきましても優勝を目指し、チーム一丸となって努力したいと思います。

2011/05/06

大阪観光

おはようございます。

今日は大阪観光に行きます。久しぶりに日本橋に行って、電子パーツとガンプラを買いました。

通天閣にも行きましたよ。


串カツ!うまい!


お土産も買ったので、これからフェリーに乗って帰ります。明日の8時には福岡に着くそうです。

それでは、おやすみなさい。