ホーム » 2013 (ページ 8)
年別アーカイブ: 2013
2013年7月21日(第330回)
学生さんがテスト期間中につき、教員による収録でお送りしました。
- 五味が答える!~かかってこいや~
- まるよし Train Pops ~ 国語と遊ぼう! 第16回 「新幹線の名前」
- テストの話
担当:青木先生、五味先生、丸山先生、西
2013年7月14日(第329回)
- まるよし Train Pops ~ 国語と遊ぼう! 第15便 「質問コーナー」
- 五味が答える!~かかってこいや~
担当:前田勝(4EI)、松島(2C)、山野(2C)、五味(教員)
自宅で監視カメラを動かしてみた
今度の週末は、家族旅行の予定。 だけど、子どもがその間、最近病院に連れて行った婆ちゃん猫を 心配している。
そこで、使っていなかったWebカメラで、急遽、監視カメラを動かしてみた。 奥さんからは、解像度低いじゃんとツッコミを受けるが、 もともとのWebカメラの性能だと思うし…
余りにも他愛もないコードだけど、 この手のお遊びプログラムは、 学生さんに「こんなこと簡単にできるよ」と見せることも多いので、 PHPコードに改良&コメント付けをしておく。

監視カメラを動かすまで
fswebcamが一番簡単に使えそうだったので…
(( fswebcamをインストール)) $ sudo aptitude install fswebcam
fswebcamの出力をそのまま画像形式で返すプログラム。
(( webcam.php )) <?php // 画像形式、キャッシュさせない header( "Content-Type: image/jpg" ) ; header( "Cache-Control: no-store, no-cache, must-revalidate" ); // 連続読み出し用にファイルロック $flock = fopen( "/var/www-support/.webcam.lock" , (file_exists( "/var/www-support/.webcam.lock" ) ? "rb+" : "wb+" )) ; if ( flock( $flock , LOCK_EX ) ) { system( "/usr/bin/fswebcam -q -d /dev/video1" ." -p YUYV" // 画像形式 ." -D 0" // delay ." -S 3" // skip frame ." -r 320x240" // 解像度 //." -r 640x480" ." --title \"tsaitoh.net's webcam\"" ." --jpeg 75 -" ) ; fclose( $flock ) ; } ?>
webcam.php の出力画像を、連続で読み出すように、 JavaScriptで設定を書き加える。 <meta http-equiv=”refresh” content=”5″> みたいな方法だと、reload の度に画像がちらつくので、JavaScriptで reload させることになった。
(( index.php )) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" id="sixapart-standard"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="viewport" content="width=320,height=320,initial-scale=1"/> <title>自宅監視カメラ</title> <script type="text/javascript"> <!-- var count = 0 ; function reload() { count = (count + 1) % 100 ; // 画像を更新(キャッシュ画像を使わないように番号付) var img = document.getElementById( "image" ) ; img.src = "webcam.php?"+String(count) ; img.id = "image" ; // 動きの少ない相手用に確認表示 var txt = document.getElementById( "text" ) ; txt.innerText = "自宅監視カメラ: "+String( count ) ; } // --> </script> </head> <body> <p align="center"> <img id="image" src="webcam.php" onload="reload()" /> <div id="text"></div> </p>
オブジェクト指向とGUIプログラミング
オブジェクト指向のプログラミングの基礎の話も終わり、 UMLによるプログラム設計の記述方法や、最後にソフトウェアの作成の流れ などを説明できたので、テストまでの今日を含めあと3回。 オブジェクト指向で分かりやすくなったGUIプログラミングについて解説を行う。
オブジェクト指向がないGUIプログラミング
技術の比較として、オブジェクト指向を使わないGUIプログラミングの例として、 unix の GUI 環境でもある X11 における Xlib を使ったプログラミングを最初に紹介。
なお、以下のプログラム例では、概念を示すために初期化や関数の引数は省略されており、 実際にはもう少し記述量が必要。
void main() { Display* display = ディスプレィの初期化 ; Window w1 = ウィンドウの初期化 ; Window w2 = ウィンドウの初期化 ; while(1) { // イベントが発生するまで待つ XNextEvent( display , &event ) ; // 発生したイベントを分類するswitch文 switch( event.type ) { case Expose: // ウィンドウの露出イベント // 対象となるウィンドウを調べて各種処理 if ( event.xany.window == w1 ) { w1の描画処理 ; } else if ( event.xany.window == w2 ) { w2の描画処理 ; } break ; case ButtonPress : // マウスが押されたイベント if ( event.xany.window == w1 ) { マウス処理 ; } break ; //------------------------ // ここが延々と巨大化 //------------------------ } } }
この方式では、XNextEvent() の後の何をすべきかの イベントの分岐命令が巨大化するし、対応するウィンドウを 探す if 文なども煩雑。
これではプログラムが大変なので、Xt(Xlib toolkit)では、コールバック関数を 用いて分岐までをスムーズに記載できるようになる。 コールバック関数とは、そのイベントが発生した時の処理関数を、 関数ポインタで登録しておき、イベント時に呼び出してもらう関数。
void w1_expose_callback( ... ) { w1の描画処理 ; } void w2_expose_callback( ... ) { w2の描画処理 } void w1_button_press_callback( ... ) { マウス処理 ; } //-------------------- // ここが延々と巨大化 //-------------------- void main() { Xtの初期化 ; // ウィジェットは、ウィンドウ上の部品を管理するデータ構造 Widget w1 = ウィンドウを初期化 ; Widget w2 = ウィンドウを初期化 ; // Xtにコールバック関数を登録する // (引数に関数名だけが書いてあることに注目) XtAddCallback( w1 , ExposureMask , w1_expose_callback , ... ) ; XtAddCallback( w2 , ExposureMask , w2_expose_callback , ... ) ; XtAddCallback( w1 , XtNcallback , w1_button_press_callback , ... ) ; // Xtに処理を完全に任せる... XtAppMainLoop( ... ) ; }
Xt では、ウィンドウの管理を行う toolkit に、自分の作ったウィンドウで、 必要なイベントが発生した時に実行してほしい処理を、 関数ポインタで登録しておく方法をとる。 この後、XtAppMainLoop() を呼び出して、この関数の中から必要な ウィンドウのイベントが発生する度に、コールバック関数を呼び出してくれる。
JavaアプレットのGUIプログラミング例
基本的には、ウィンドウ処理を記載する場合には、ウィンドウ画面を管理するための Applet と呼ばれる基底クラスを用いる。 自分で作るウィンドウの処理を記載する場合には、Applet クラスから 自分の処理のクラスを派生させ、その中で 描画処理を行う paint() や、 マウス処理を行う mousePressed() 等を記述すればいい。 そうすると、 Applet クラスが、仮想関数のメカニズムで、ユーザのクラスの paint() や mousePressed() などを、必要なタイミングで呼び出してくれる。 自分にとって特に記述の必要がなければ、イベント関係のメソッドを記述しなければ良い。 そうすれば親クラスのメソッド等が呼び出され、必要な処理を行なってくれる。
public class MyApplet extends Applet { // ウィンドウの露出に合わせて呼び出される。 public void paint( Graphics g ) { 描画処理 ; } // マウスが押された時に呼び出される。 public void mousePressed( MouseEvent e ) { マウス処理 ; } // 他にも、init , start , stop , destroy , // paint , repaint , update 等のメソッドなどを // 必要に応じて定義すればいい */ }
画面にボタンや、別の部品が必要な時は、ActionListener というインタフェース(interface)を実装(implement)する。 インタフェースとは、純粋仮想基底クラスのような物で、 Javaには多重継承の概念が無いため、インタフェースを実装するという形で、 プログラムを記述する。 特に、ActionListener インタフェースは、ウィンドウのイベントを処理する仮想関数を 記述するために使われる。
public class MyApplet extends Applet implements ActionListener { // クラス変数(Applet内のボタン等を記述する) Button b1 = new Button( "ボタン1" ) ; Button b2 = new Button( "ボタン2" ) ; // Appletの初期化関数 public void init() { b1.ボタンの配置を設定() ; b2.ボタンの配置を設定() ; // ボタンが押された時に呼び出してほしい事を、 // ActionListenerに登録する。 b1.actionListener( this ) ; b2.actionListener( this ) ; } // ウィンドウが露出した時に呼び出される。 public void paint( Graphics g ) { 描画処理 ; } // ボタンが押されるなどのタイミングで呼び出される。 public void actionPerformed( ActionEvent e ) { if ( e.getSource() == b1 ) { ボタン1の処理 ; } else if ( e.getSource() == b2 ) { ボタン2の処理 ; } } }
これらの方式は、基本的な考え方であり、最近の Java では、 さらに進んだイベント処理の考え方が取り入れられていたりするので、 あくまで、このプログラムの例は参考です。
電子情報でPC学生購入で簡単アンケート
今日は校長裁量経費のプレゼンテーションであった。 この中で、電子情報の実験環境として、**の実験設備が希望といった プレゼンを行った。 ただ、電子情報では実験用をサポートするためのPC購入を 希望しても、国への補正予算要求なども含め、 最近はなかなかPC購入にOKが出ない場合が多い。
この対応として、パソコンをバリバリに使うんなら、 学生が個人購入してもらい、それを使うという方法もある。 実際、他の高専の情報系の学科では、入学時購入や 3年で購入といった所もある。
個人的にも、1年購入であれば 4,5年でパソコンが 陳腐化するかもしれないので、なかなか賛成はしづらい。
情報系でPC購入のアンケート
ということで、授業の最後の5分で実際にパソコンをバリバリに 使っている4年を相手に挙手形式で簡単アンケートをしてみた。
1年でノートパソコン購入だと、高いと思う人...約90%
うーん、やっぱり入学時だと他にも購入するものも多いし、難しいかな。 関数電卓とか、TIのグラフ電卓の絡みもあるし、悩みどころ。
授業用パソコン購入をするのなら、何年がいい? 入学時...約20% 3年.....約50%
この辺は意見が分かれる所で、こんな結果であった。
パソコン購入は、高いというイメージがありそうなので、
皆さんがイメージするパソコンっていくら? 5万円... 20% 7万円... 30% 10万以上... 50%
うーむ、高い機種を考え過ぎだと思うんだけどな….
また、3年購入だとパソコンの使い方も色々なので、機種とかを 完全同一というのも難しいとも思うので、
3年でパソコン購入なら、機種は自分で選びたいと思う? ... 約90%
やっぱり3年購入だと、共通環境で購入してもらうのは、極めて難しそう。
んで、この質問タイムの間の意見で次のような意見もあった。 入学時購入ならOfficeなどのインストールはどうするの? (同一環境PCなら業者に事前に対応してもらうことになるだろうな…)
Office入れるぐらいなら、Google Document でいいんじゃ? といった意見もあった。これについては、私もクラウド利用もあると 思っていて、「Microsoft 包括協定」もあることだし、Office 365 を使う手もあるとは思っている。
また、自転車通学の学生からは、「ノートパソコンあっても学校に持っていくのは 大変。落として壊す心配もあるし、自転車だと *お*も*い* !!」とのことであった。 そーだよなぁ…. かといってタブレットじゃ、プログラミング系の課題はできんしなぁ…
C言語とファイル操作(OSの違い)
前回説明不足の点を補うために、全部座学で講義の予定であったが、 ファイル操作は演習を交えながらの方が効果的なので、 前半説明・後半演習とする。
ファイル操作でのOSの違い
C言語のファイル操作での、バイナリモードとテキストモードの違いを説明する。
OSの成り立ちの違いから、文字コードと機器の動きには違いがある。 特に、\n(行送り) , \r(復改) , \f(ページ送り) といった制御コードは違っている。
Windowsでは、行末文字は、"\r\n" , unix では"\n" , 古いMacOSでは"\r"と 違っている。このため、unix で printf( "Hello\n" ) ; といった処理が、 他のOSでも同じように動かすために、 Windows では、出力時には"\n"を"\r\n"に書き換えて出力し、 入力時には"\r\n"を"\n"に置き換えて入力する。 こういった、行末文字の置き換えをしながら入力するモードは、テキストモード と呼ばれる。 これに対し、記録されているデータの2進数データを扱っているときに、 上記のような変換が行われると、"\r(0x0D)"が消えたり(あるいは想定外に混入)してしまう。 こういったデータを扱う場合には、バイナリモードを使う。
これ以外にも、OSの違いによりデータがおかしくなる事例ということで、 日本語文字コードについても紹介する。よく使われてきた文字コードは、 JISコードは、文字種が変更されるときに、ここから後の文字コードは何…といった情報を 付加する方式。Shift-JISは、パソコン(Windows)で広く利用されている文字コード。 ただし2byteの漢字1文字の1byte目、2byte目の判別が面倒。この改良として、 EUC-JPといった文字コードがある。 しかし、最近では1つのファイルの中に、日本語・中国語・アラビア語といったような 複数の言語が混ざる場合が増えてきたため、"Unicode"という方式を使うのが主流となってきた。 この方式では、基本的にすべての文字=2byteで扱ったりする。 しかし、ファイルに保存するときに効率が良くなるように、"UTF-8"といった保存形式をとる。
ファイル入出力の課題
fopen,fscanf,fprintf,fclose の理解をしてもらうために、 (1)名前と3科目の成績のファイル上のデータで、各人の平均点をファイルに出力、 (2)名前と身長体重で、各人のBMI値をファイルに出力… の課題に取り組んでもらう。
課題途中で、行データの読み込みで混乱が見られたので、 ファイルポインタの説明と、 scanf("%s%d",…) といった入力時に、各項目の読み込み前に空白スキップ処理が 行われることを説明する。
Raspbianでサーボモータ制御
Raspberry Pi に Debian を入れてみたけど、USB-WiFiもつなげると、ほんと小さいけど ちゃんとしたサーバだわ…(^^; んで、最終的には画像処理系のロボットを組めればいいなということで、 その一環としてサーボモータを動かしてみた。
といっても、サーボモータでググって見つかった記事を動かしただけ。 GPIOポートに、ジャンプワイヤを接続するためのコネクタを作り、 上記記事の servod を動かして、以下のコマンドで簡単に動く。
$ for i in $(seq 50 20 240) $(seq 220 -20 50) do echo 0=$i > /dev/servoblaster sleep 1 done
ただ、参考にした ServoBlaster だけど、kill で servod を殺すと、 時々OSが異常停止してしまう。必要に応じてデーモンを動かし止めたりは不安定。
また、ServoBlaster で今回使用したサーボモータでは、 50以下の値や240以上の値を指定すると、サーボモータのポテンションメータの特性が 不安定なのか、 速度を変えてもいないのに、ジリジリという音がして角度を制御しようとしている様子。 ということで、50〜240の範囲で使う必要がありそう。
2013年7月7日(第328回)
- まるよし Train Pops ~ 国語と遊ぼう! 第14便 「手紙」
- 七夕のお話
- 高専大会について
- 香港の話
担当:前田勝(4EI)、松島(2C)、山野(2C)、西(教員)