データベース・ガイダンス&導入説明
5年後期のデータベース(選択)の授業の最初ということで、 シラバスやガイダンスといった説明の後、データベースの利便性の導入を説明した。
最初に、JABEEで学習・教育目標を決めているけど、本科学生の学習・教育目標が 不明確ということで、本科の内容を少し変更された。特に4,5年生は、 本科学生かつJABEE対象ということで、2つの学習・教育目標(言い回しが微妙に違うだけ) が記載されている。
授業の方針などを話した後、データベースの利便性を説明するために、 1行1件可変長データでは、while+fscanf+if+処理では、シーケンシャルしかできず、 O(N)にしかならない話をする。速度向上のためには、2分探索などが必要であり、 ランダムアクセス機能が重要であることなどを説明する。 データベースシステムを使わない場合、ランダムアクセスをどのようにするかということで、 fseek+freadなどのC言語の関数を説明する。(参考:昨年度の初回内容)
しかしながら、fseek+freadでランダムアクセスのできる処理が書けたとしても、 以下のような問題が残っている。これらの問題が行ないようにするために、 データベースシステムを使わずにプログラムを書こうと思ったら、 プログラマーには大変な負担となる。
- OSが落ちた場合に処理が中途半端にならない原子性(Atomicity)
- データがあってはいけない値にならない整合性(Consistency)
- マルチタスクで複数の問い合わせがあった場合の、排他制御の重要性(Isolation)
- データが消失しない耐久性(Durability)
自律部門ビギナーの部の工作教室
歯みがきロボットコンテストの自律部門のビギナーの部の 参加者対象ということで、 WROに参加した中学生を対象に工作教室を開催した。
講師には、福井工業大学の小沢先生にお願いし、 私は歯ブラシの取り付けを中心に説明を行った。

といっても、WROで車体の組み立てやプログラミングは 経験しているし、自分たちで作っていた車体をベースに 動かしたいという思いもあって、こちらの説明の資料が あんまり役に立たない。 このため、コースに合わせた調整が中心となった。
これとは別に、例年参加してくれている家族の方が 試走および調整に来られた。 リモコンの部も含め、興味深い車体で撮影したものを 掲載したいんだけど、作戦もあるでしょうから ひとまず、ナ・イ・ショ。
NXTのモーターの中身
工作教室の中で、小沢先生がNXTのモータの中が見えるようにしたものを見せてくれた。 興味深いので写真をとる。右側のギアには穴が空いており、フォトインタラプタで回転数が 取れるようになっている。

ROBOLAB
講習会では、プログラムの作成はROBOLABを使っていた。 うちの高専では、NXTソフトウェアを使っており、 ちょっと使い方のインタフェースが違うので、中学生のROBOLABのプログラムは、 横で見ていててよく解らない。 工大の方の動きの説明でのデモを見ていると、ROBOLABの方がループの周回速度は 早そうな雰囲気(1光センサーのライントレースでの頭の振り方がスムーズ)。
NXTソフトウェアでは、「moveの1つのアイコンで2モータへの速度指定ができる」という点では、 解りやすいと思う。しかし、ROBOLABでは、1つのモータ速度指定の定数を、 複数の処理アイコンに接続できるので、便利そう。 あえて言うなら、最近のNXT2.0であれば、35000円の中に、 NXTソフトウェア2.0が含まれている点がお勧めかも。
LEGO基本ライントレース車体の高速化
LEGO MindStorms NXTのライントレース処理で実験を行った。 プログラムはNXTソフトウェア2.0で記述した。 光センサーが1個しかない場合、白黒の境界に沿って車体をすすめることになるが、 「黒なら左折、白なら右折」の処理だと、 左右に車体を振りながらで余り速い動きにはならない。 NXTソフトウェアのブロック記述ではループ1周の速度も遅いため、 高速移動のために直進性を高めてモータ速度を上げると、 半径30cmほどのカーブでさえ曲がりきれない。 色々と条件を変えてみたけど、安定して半径20cm程を曲がるには、
for(;;) { // 実際はNXTソフトウェアのブロック if ( 光センサ==黒 ) 左前進0%,右前進30% ; else 左前進30%,右前進0% ; }
といったプログラムで、移動を高速化するのは難しい。

NXTソフトウェアでは状態遷移図は辛い…
NXTソフトウェアのループ周期で高速化しようとすると、 連続して黒or白なら高速カーブ、白黒が交互に変化するときは直進性を高めて左右にカーブという処理といった処理がしたくなってきた。 理想的には、状態遷移図で速度制御したいけど、 大人気なくC言語で書くのも気が引けるし、ROBOLABで1万円かけるのもイヤとなると、 状態遷移図的なコードも書きにくい。 色々と試し、以下のようなコードとしてみたら、それなりに高速化ができた。
# 直進時に速度 (30+0)/2 = 15% ⇒ 速度 (30%+50%)/4 = 20%
for(;;) { if ( 光センサ==黒 ) { 左前進0%,右前進30% ; if ( 光センサ==黒 ) 左前進0%,右前進100% ; else 左前進50%,右前進0% ; } else { 左前進30%,右前進0% ; if ( 光センサ==黒 ) 左前進0%,右前進50% ; else 左前進100%,右前進0% ; } }

NXT基本車体にブラシの取付け方法
歯みがきロボコンの自律ビギナー部門のための講習会が開催されるので、 NXTの基本車体にブラシを取り付けてみた。
![]() ローリング方式 |
![]() ワイパー方式 |
小中学生向けの講習会なので、写真だけではダメだろうから、 金曜には取り付けまでの部品のつけ方を1つ1つ写真にとったマニュアルを作ろう。
自律部門工作教室(追記)
明日に工作教室を控え、歯ブラシの取り付け方法の講習会の資料を作った。 基本車体までの作成などの説明は、別途工大の先生が担当なので、 歯ブラシの取り付けのみの資料。 (バドミントンの合宿で夜が暇だったしぃ…) LEGOのマニュアルは、基本組立ての絵が中心で、何をどこに刺すといった文章は 何も書いてないのが基本なので、この資料もそれを見習ってみた。(「文章書くのが面倒くさいんだろう」ってことは言いっこなし) 自宅用の一眼レフが大活躍(^_^;
学力強化週間で補講
今週は、福井高専では『学力強化週間』ということで、前期授業で理解が浅い学生さんのために、 補講を行うことになっている。 ということで、3年のプログラミング応用、4年の情報構造論について補講を行った。
4年情報構造論
前期では、リスト構造のプログラミングが中心であったので、以下のような課題を、 実際に黒板に書いてもらいながら、説明をしたり、穴埋めや処理の目的を聞きながら、 補講となった。補講は2コマ分しかないので、必要最小限でかつ自分で考えることを目標に行った。
- 昇順の配列の途中にデータを挿入。(挿入場所を探して、後続のデータを1件分後ろにずらして挿入)
- 配列中のデタラメな順序の配列と、昇順になるように次のデータの配列添え字の配列で、 リストもどき。(配列添え字をたどりながら全データ表示)
- リスト処理の宣言の後、リストのデータを1件づつ表示。
やはり成績不振の学生さんは、2年レベルの配列処理でさえもコードが書けない。 すこしづつ経験と、処理を追いかけることができるようになることが重要。 ということで、ループの処理順序と値の変化を追う練習ということで、 上記課題の処理順序と値の変化を処理終了まで記載する課題をだして終了。
3EIプログラミング応用
前期では、2年の復習およびファイル処理とポインタの基礎だったので、 これを踏まえ処理の順序を追いかける練習を中心に補講を行った。
- forループ途中でbreakのプログラムの処理トレース、およびフローチャートを記述
- forの2重ループで、処理のトレース、およびフローチャートの記述
- 配列中の最大値・最小値の差を表示プログラムを作成
- ファイルからのデータ入力の基礎プログラムを説明。(fopen,fclose,fscanf)
- ファイルに記載されているデータを読み込み、最大最小値の差を表示
LEGOの初めての造形
来週にLEGOの工作教室をちょいと協力するので、 自宅の子どもとのお遊び用に半年ほど前に購入した蓋も開けてなかった ものを開封し、自宅にて夜中にいろいろと触ってみた。
まず、戸惑ったのが中身。学校で実験で使っているものと、部品が違う。 学校で使っているのは、2タイヤ+キャスターでライントレース車体 を構成されている。しかし、自宅で購入したのはAmazonで発注した英語版。 (ちょっとだけ安かったんだもん…)おかげで、足回りはキャタピラ。
しかも、歯みがきロボコンのブラシ動作用に1つモータを温存したいので、 同封マニュアル通りに作るわけにはいかないし、キャスターを構成する 細かい部品が無い。本当は、子供と一緒に作るつもりだったけど、 子どもを差し置いて、マニュアルをヒントに完全オリジナルの を作るしかない。
LEGO-NXTを使った講習会の講師などもしているけど、教えているのは プログラム中心。LEGOの造形は今回が初体験。んで、 ここで90度ひねりたいけど、適当な部品がなかったりと、意外と難しい。
んで、工作教室用の写真なども取りながら、夜中にひとまず完成。 でもよくよく考えると、近接確認用の超音波センサーの取り付け位置が最悪。 見栄えというのもあるけど、前部に超音波センサーをつけると、 近距離が測定に不向きということで、後方につけた。 しかし、前部に取り付けた歯みがき用ブラシの後ろじゃあ、 正確に距離を測れない。
ということで、週末に子どもを交えて車体の作り直しだな。
歯みがきロボコンのLEGOでの工作教室にて、歯ブラシを車体に取り付ける方法だけど、 汎用性を考えたら、ブラシの柄にポッチの直径の穴を開ければ簡単そう。 Webで調べてみると、LEGOは1/8インチ基準で設計されているようで、 ポッチの直径は、1.5/8インチ=4.7625mmみたい。+断面のポッチを指すのであれば、 4.5mmあたりのドリルビットだろうか… ひとまず、工作室のドリルで試してから、 工作教室に持ち込むドリルを買いに行こう。
LEGOへの歯ブラシの取付
歯みがきロボコンで、LEGOへの歯ブラシの取り付け方法を色々試してみた。 最初は手持ちのM3ネジで取り付けようとしていたけど、 どうせハブラシに穴をあけるんだし、LEGOの寸法に合わせて穴を開けてみたら、 思ったよりうまくいった。

Φ4.8、2stud間隔の穴をあける
LEGOの寸法で調べると、ポッチ(studと言うらしい)の直径は、1.5/8インチ=4.76mm。 工作ドリルにM4.5mm,M4.8mm径があって穴を開けて試すと、 M4.5mmは、細身の十字型のポッチでもまるっきり刺さらない。 M4.8mmを試すと、十字型は軽く回転する隙間があり固定用のポッチだと、 正規品の穴と同じ位の刺さり具合でちょうどいい。
LEGO-NXTのモータには、2stud幅で対角4個の穴があるので、 これに合わせて穴を開けてみた。 手元にあった歯科医師会さんからもらっていたハブラシの柄の厚さも、 それなりなので、それなりにうまく刺さってくれた。
実際には、動きの中で外れやすかったりするだろうから、 ポッチをいくつかダメにする覚悟で、 接着剤で固定するなり、 ほかのブロックを間にはさんで結束バンドで固定するなりすればいいだろう。
Wiimote.pdeにIRセンサー取得を追加
ProcessingでWiiリモコンを使う方法で、WiiFlashを使って加速度などの基本値はとれるようになったけど、 「IRイメージセンサの座標が取れない」との質問。 仕方がないので、WiiFlashのソースコード"Window1.xaml.cs"をざら読み。 ネットワークに取得値を書き込んでいる所のコードを眺めて、 以下のような追加をすればいいことが分かった。
class Wiimote { ...略... void update() { boolean dataHasCome = false; while (client.available() > 80) { if (buffer == null) { buffer = new int[80]; } for (int i = 0; i < 80; i++) { buffer[i] = client.read(); } dataHasCome = true; } if (buffer == null || !dataHasCome) { return; } bufferPos = 1; batteryLevel = (float)readByte() / 0xC8; updateButtons(readShort()); x = readFloat(); y = readFloat(); z = readFloat(); extensionType = readByte(); /** IRセンサー added by T-Saitoh **/ bufferPos += 21 ; ir0 = readByte() ; // 1つ目のIRセンサーが値をとれた ir0x = readFloat() ; // 1つ目のX,Y ir0y = readFloat() ; // (9/15)readShort()->readFloat()修正 ir1 = readByte() ; // 2つ目のIRセンサーが値をとれた ir1x = readFloat() ; // 2つ目のX,Y ir1y = readFloat() ; } ...略... /** 拡張タイプ */ int extensionType; /** 各ボタン */ Button one = new Button(); : 略... Button right = new Button(); /** バッテリーの残量 */ float batteryLevel; /** 加速度 */ float x, y, z; /** IRセンサー added by T-Saitoh **/ int ir0 ; float ir0x , ir0y ; // (9/15)int->float修正 int ir1 ; float ir1x , ir1y ; ...略... }
# 初心者学生さんに、『WiiFlashのコード嫁!!』 とは言えんか…
cvWaitKey(1)がダメとな…
画像処理によるロボット制御のネタで、 学生さんのコードで、OpenCV使っているんだけど、 画像データは取得できているのに、cvShowImage() で画像が表示されない。 訳が解らず、ほとんどのコードをコメントアウトしたのに動かない。 カメラ画像もそれなりにリアルタイムに変化する値もとれている。 Webに載っている cvQueryFrame() + cvShowImage() のサンプルコードなら 簡単に動いた。見比べてみると、画像読み込みループの中の、cvWaitKey()の違いだけ。
cvWaitKey()の引数は、キー入力がタイムアウトするまでの時間[msec]で、 学生さんのコードでは1msecとなっていた。べつに支障が無いと思うのだが、 「ともかく動作検証。動作サンプルが5msecで動いたし」ということで、 cvWaitKey(5)に変更したら動いた…..うーむ….なぜだ….
オムニホイールでやってはいけないこと
歯みがきロボコンでは、オムニホイールの車体を今年も参戦させる予定。 昨年よりさらなる応用ということで、今年は反射型光センサーを前4個、後2個にしてみた。
SS SS /-\ |〇| \-/ S S
エントリーしている学生さんに応用してもらうための、 サンプルプログラムを書いてみた。 しかし、思ったほどプログラム通り動いてくれない。 色々実験して解ったのは、「車体の重心と歪みの影響」が重要であること。
車体の重心と歪みの影響
一昨年度の画像処理のロボットでも、プログラムの通りに動かないトラブルがあった。 この時の問題点は、重心と駆動輪の関係。 この時の車体は、前に2つの駆動モータと後ろに2つのキャスターを積んでいたが、 車体に歪みがあると、4つのタイヤの接地圧力に偏りが発生し、 駆動輪の片側が空すべりが発生しやすい。 そこで昨年度の車体では、車体の重心を駆動輪側に寄せた。 これにより空すべりはキャスター側で発生するため、車体はスムーズに動くようになった。
o---o o---o キャスター | | |(W)| (W)重心 # | | # # | | # #=M(W)M=# #=M M=# 駆動輪 # |___| # # |___| # 良い例 悪い例
オムニホイールでも同様で、車体に歪みがあると、4つのタイヤの接地圧力に偏りが発生し、 空すべりが発生しやすい。高価なウレタンフォームのタイヤを使えばある程度は改善するとは 思われるが、歪みが大きければたとえウレタンでも空すべりは発生するだろう。
今日、試作で作った車体では、オムニホイール上に制御部を乗せる時に、 オムニホイールの取り付けてある板と、制御部の板をスペーサを挟んで外れにくいように ネジ止めした。 しかし、ネジ穴の位置の微妙なズレから、オムニホイールの板を微妙に歪ませてしまった。 このため移動方向にムラが発生し、プログラムでの回転方向どおりに動いてくれなかった。
ということで、オムニホイールのロボットでやってはいけないこと。
- オムニホイールの板と制御部の板を、歪むような強い力でネジ止めしてはいけない。
- 対角の2つのタイヤを動かし、逆対角を止めるようなプログラムは書いてはいけない。 車体の歪みによっては、回転を止めている逆対角の車輪で接地している状態になり、 空回りが発生する。
前-止 転-止 左-左 |〇| |〇| |〇| 前-止 止-転 止-止 良い例 悪い例 良い例