2008年7月31日木曜日

swfファイルからいろいろ抽出[swftools]

ニコ動の演奏してみた動画から音声だけ抽出してDMPで聴いたりしてるんですが、たまにflvファイルじゃなくswfファイルになってる動画があります。flvファイルならffmpegでイケるんですが、swfファイルは無理 orz
Windows環境ならhugflashというフリーソフトがあるんですが、linux環境でどうにか出来ないかなぁとググってみたら、ありました。
sudo apt-get install swftools

swftoolsはフラッシュファイルを作成・分割なんかしたり出来るパッケージです。
swftoolsをインストールすると、フラッシュファイルから各データストリームを抽出するswfextractというコマンドが追加されるので、swfファイルから音声を抽出したい時は次の様に端末で叩きます。
swfextract -m input.swf -o output.mp3

-mは音声を抽出するオプション、-oは出力先を指定するオプションです。

その他の使い方は$ man swfextractを参照。他にもswftoolsパッケージに含まれるコマンドが追加されるはすです。

2008年7月30日水曜日

以前のエントリでスマートフォンが欲しいが、Willcom 03を買うのに逡巡していることについて書きました。ですが、ここで新たなダークホースが現れました。

iPhoneを超越し、日本仕様に完全カスタムして発売予定の高機能携帯電話「OMNIA(オムニア)」、その全貌を探る
http://gigazine.net/index.php?/news/comments/20080728_samsung_mobile_phone/

日本のスマートフォン市場は私から見ると今まであまりパッとしてませんでしたが(iPhoneはただの若者の流行だし)、面白い端末が出てきてくれそうです。
つか、買いますよコレ。

iPhoneのパクリだなんだと声が聞こえてくるのは仕方がないですが、Windows Mobile機だから弄くりまわせるわけですよ。ここが全然違う。

え? 日本向けに独自プラットフォームにするかもって? そしたら誰も買いませんって。

2008年7月29日火曜日

週アスのUbuntuムック第2弾買ってきた/mp3タグ文字化け解決[EasyTAG]

週刊アスキー/カンタンUbuntu! 2 (2) (アスキームック)週刊アスキー/カンタンUbuntu! 2 (2) (アスキームック)

アスキー・メディアワークス 2008-07
売り上げランキング : 1775

Amazonで詳しく見る
by G-Tools


Slackware好きの女子校生が登場するトンデモ漫画はシャトルワースさんにも好評だったそうです。。。オイ

つーわけで、この本読んでたら予てよりの問題の解決法が載ってたのでチャレンジ。というか、このくらいはググりゃあすぐ解決したんでしょうが、なんとなく先延ばしにしてました。

問題というのは、Rhythmboxで音楽なんぞを管理・再生なんぞしようとするときに、タグ情報が文字化けしてしまうというもの。実はLast.fmユーザなんですが、文字化けしたままScrobbleしてたので、最近の再生アーティストの上位に文字化け名が食い込んでます orz

この原因は、Windowsでタグを編集する際にShift-JISで書き込まれてしまうためだそう。
そして、その原因を一気に解決してくれるのがEasyTagというソフト。
$ sudo apt-get install easytag

$ sudo apt-get install easytag-aac

(easytag-aacというもう一つのパッケージのほうがUbuntu推奨みたいなので、追記)
デフォルトではShift-JISを読んでくれないので、設定 > ID3タグの設定 で、Charactor Set for reading ID3 tagsのNon-standartにチェックし、右のリストボックスでShift-JISを選択します。これで、Shift-JISで書かれたタグが読み込めるようになります。

この状態でShift-JISで書かれたタグを読み込むと、自動で文字コードを変換してくれます。
ファイルを読み込む時点で勝手にShift-JISの文字コード変換してくれますので、EasyTagで変換したいファイルがあるディレクトリを読み込んでから、ディレクトリ中のファイルを全選択して、ファイル > ファイルの強制保存 で文字コードが変わってくれます。

ディレクトリを移動しようとすると、「いくつかのファイルを変更しましたが、保存していません...フォルダを移動する前に保存しますか」というダイアログが出るので、そこで「はい」を選択しても同じです。
20080730追記:強制保存しないとちゃんと文字コードが変わってくれない場合がありました。

Rhythmboxの方は、タグ情報が書き換わってもRhythmbox中のライブラリは更新されないので、全部のファイルを読み込み直しました orz(まぁ、対した労じゃないんですけど)

2008年7月28日月曜日

ffmpegで動画から音声を分離

ffmpegを使うと、動画から音声を分離したりするのは簡単にできる。

まず、音声コーデックをチェック
$ ffmpeg -i input.mp4 2>&1|grep Audio
Stream #0.1(und): Audio: aac, 44100 Hz, stereo
$

音声コーデックがaacなので、出力先の拡張子をaacとする。
$ ffmpeg -i input.mp4 -acodec copy output.aac

(<追記>aacはあくまでコーデックであり、ファイル形式(コンテナ)とは違うんですけどね)

ffmpegでは出力先に指定したファイル名の拡張子で、出力するファイルフォーマットを判断するので、先に必ず動画の音声コーデックをチェックしなければならない。音声コーデックがaacなのにmp3などの拡張子を付けるとエラーになる。

単純作業なので、動画から一発で音声を分離してくれるスクリプトでも組もうかと思ったのだが、実際は意外と面倒そう。
ffmpegは数々のフォーマットに対応しており、まずフォーマットと拡張子の対応テーブルを作らなければならないし、デコード出来てもエンコード出来ない、またはその逆のフォーマットもある。更には、出力にoutput.wmaと指定したら、WindowsMediaAudioの筈なのに動画ストリーム付きでファイルを書き出してくれたり。。。

正直、手作業の方が気楽。

<追記>
WMAとWMVってコンテナの形式は同じで、オーディオだけならWMA、動画ならWMVって違いなだけじゃね?と気付いた。
ちゃんとストリーム指定して出力すりゃいいのかな?

2008年7月27日日曜日

端末で動画のフォーマットを確認する の続き

一昨日のエントリで、端末からffmpegで動画のフォーマットを確認できることを確認したが、ffmpegのhelpなど余計なのも出力されてしまっていた。

「grepすればいいじゃん。何言ってんの?」とは言わないで欲しい。
だって、
$ ffmpeg -i smile.mp4 |grep Stream
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2007 Fabrice Bellard, et al.
configuration: --enable-gpl --enable-pp --enable-swscaler --enable-pthreads --enable-libvorbis --enable-libtheora --enable-libogg --enable-libgsm --enable-dc1394 --disable-debug --enable-libmp3lame --enable-libfaadbin --enable-libfaad --enable-libfaac --enable-xvid --enable-x264 --enable-liba52 --enable-amr_nb --enable-amr_wb --enable-shared --prefix=/usr
libavutil version: 1d.49.3.0
libavcodec version: 1d.51.38.0
libavformat version: 1d.51.10.0
built on Jul 16 2008 19:54:40, gcc: 4.2.3 (Ubuntu 4.2.3-2ubuntu7)

Seems stream 0 codec frame rate differs from container frame rate: 119.88 (120000/1001) -> 30.58 (367/12)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'smile.mp4':
Duration: 00:09:50.0, start: 0.000000, bitrate: 531 kb/s
Stream #0.0(und): Video: h264, yuv420p, 512x384, 30.58 fps(r)
Stream #0.1(und): Audio: aac, 44100 Hz, stereo
Must supply at least one output file
$

こうなっちゃうんだもの。

どうしてかなぁと思ってたのだが、「ffmpeg 標準出力」でググったらこの理由が分かった。
ffmpegが出力するこの文字列、実は標準出力ではなく標準エラー出力で吐き出されているそうなのだ。パイプで繋いでも標準エラー出力はgrepに渡ってくれず、標準エラー出力はそのまま表示されていたという訳。
ここまで分かれば簡単、標準エラー出力を標準出力にリダイレクションしてやればいいので、
$ ffmpeg -i smile.mp4 2>&1 | grep Stream
Stream #0.0(und): Video: h264, yuv420p, 512x384, 30.58 fps(r)
Stream #0.1(und): Audio: aac, 44100 Hz, stereo
$

これでOK。

つか、やっぱり同じことを考えてる先達はいた訳だけど、「ffmpeg 動画 情報」とかでググっても出てこなかったのが、「ffmpeg 標準出力」で一発だったのが泣ける。

<追記>
grepよりtailのほうがいいかも。
$ ffmpeg -i input.mp4 2>&1 | tail -n 5

2008年7月26日土曜日

Gnome MPlayerでWindowsMediaフォーマットの動画/音声を視聴する

Ubuntuを使っていて、ubuntu-restricted-extrasパッケージとかを入れていれば大抵のWindowsMediaのファイルなんかは普通にTotemとかで見れるんだけれど、たまに音声が出なかったりしてちゃんと見れないWMVファイルがある。
どうやら、WMA9とか一部のコーデックについてはTotemじゃあ見れないらしい。

そこんところ、GNOME-MPlayerだとちゃんと再生してくれるというので、さっそくインストール。
$ sudo apt-get install gnome-mplayer

GNOME-MPlayerは実際には、MPlayerという別のソフトのGNOMEデスクトップ環境向けのフロントエンド的なものみたい。

んで、実際に使ってみると、Totemで駄目だったファイルが確かに再生できるんだけど、プレイヤーというアプリケーションとしてはプレイリスト回りとかが使いづらく感じた。
それに、再生できるのはいいんだけど、シークが出来ないファイルもあるので、ちょっと残念。まぁ、これは仕方ないか。

2008年7月25日金曜日

端末で動画のフォーマットを確認する

Linuxを端末でいじってる時に、動画ファイルのコーデックなどを確認したい場合がある。ffmpegで動画を変換しようとする時とか。
ffmpegでは、エンコードする時に端末に動画の情報が表示されるが、それをする前に知りたいんだっつーの。情報を見るためffmpegを立ち上げエンコを速攻キャンセル、なんてなぁ。。。

そんな時に、いちいちnautilusを立ち上げ→ファイルアイコンのコンテキストメニュー→プロパティ→音声/動画タブを見る、なんてことしたくない。
コマンドでサクッと表示したい場合はどうするか。

いろいろググって見たはいいものの、なかなかそれらしいものは見つからない。
諦めて、やはりffmpegで見るしかないのか、、、と思ったがある事に気がついた。
ffmpegで入力ファイルだけ引数に与えたらどうなるだろう。。。

つーわけで、次みたいに端末を叩いてみた。
$ ffmpeg -i smile.mp4 
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2007 Fabrice Bellard, et al.
configuration: --enable-gpl --enable-pp --enable-swscaler --enable-pthreads --enable-libvorbis --enable-libtheora --enable-libogg --enable-libgsm --enable-dc1394 --disable-debug --enable-libmp3lame --enable-libfaadbin --enable-libfaad --enable-libfaac --enable-xvid --enable-x264 --enable-liba52 --enable-amr_nb --enable-amr_wb --enable-shared --prefix=/usr
libavutil version: 1d.49.3.0
libavcodec version: 1d.51.38.0
libavformat version: 1d.51.10.0
built on Jul 16 2008 19:54:40, gcc: 4.2.3 (Ubuntu 4.2.3-2ubuntu7)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'smile.mp4':
Duration: 00:13:54.1, start: 0.000000, bitrate: 204 kb/s
Stream #0.0(und): Video: h264, yuv420p, 512x384, 60.00 fps(r)
Stream #0.1(und): Audio: aac, 44100 Hz, stereo
Must supply at least one output file
$


smile.mp4はニコ動から落としてきた適当なファイル。
余計なものも表示されてしまったが、最後のほうでしっかり知りたかった情報が表示されている。

とりあえず、目的は達成したけど。。。なんか納得できない。

2008年7月24日木曜日

無線LANドングルをUbuntuで使う

BUFFALOのWLI-U2-KG54LをLinuxで使うTips

linuxwireless.orgからドライバをDLする
http://wireless.kernel.org/download/compat-wireless-2.6/
から
compat-wireless-2.6.tar.bz2
compat-wireless-2008-07-24.tar.bz2
のどちらかをDLする。どちらも中身は同じ
(<追記>
 2008年11月17日時点でcompat-wireless-2.6.tar.bz2の内容はcompat-wireless-2008-11-17.tar.bz2のものになっており、本記事で使用しているcompat-wireless-2008-07-24.tar.bz2は参考ページ上ではcompat-wireless-old.tar.bz2というファイル名として扱われている。
 compat-wireless-2.6.tar.bz2をDLして、makeしようとしてもエラーが出て、compat-wireless-old(つまりcompat-wireless-2008-07-24)の方を使うようにメッセージが出る。
 なので、compat-wireless-oldのほうをDLしていただきたい。)

compat-wireless-2.6.tar.bz2の方をDLしたとして、解凍→コンパイル→インストール→ロードをする手順は以下。
$ tar jxf compat-wireless-2.6.tar.bz2
$ cd compat-wireless-2.6.tar.bz2
$ make
$ sudo make install
$ sudo make load

これで使えるようになっているはず。
ドングルをUSBに指して、通知スペースのネットワークアプレットを見ると、ワイアレス接続が追加されていると思う。

この他にも、ndiskwrapperでWindows用のドライバを使う方法や、zd1211モジュールを使う方法がある。
後者を先に試してみたのだけれど、zd1211-firmware(本来Debian向けのパッケージ)はUbuntuの公式リポジトリから削除されていて、zd12111-sourceからビルドしなければいけないのに、Debianと仕様が変わっているUbuntuではコンパイルが出来なかった。(hardy heronで確認)

<追記>
Ubuntu 8.10 Intrepid Ibexでは、標準でWLI-U2-KG54Lが使えるようです。
Ubuntu8.10の無線LANドングルへの対応
http://mstssk.blogspot.com/2008/11/ubuntu810lan.html

2008年7月23日水曜日

Rubyをごにょごにょ その2

Rubyで文字コード指定を行う場合、rubyコマンドに-KCODEオプションを付けるか、スクリプト中でグローバル変数$KCODEに代入して指定する。
この$KCODEの扱いについてちょっとおもしろかったのでTipsというかColumn。

$KCODEに代入するのは、"EUC","SJIS","UTF8","NONE"という文字列。初期値は"NONE"
大文字小文字関係なく指定でき、さらにそれぞれ'e','s','u','n'と省略して書く事ができる。

なぜ省略できるかというと、実は$KCODEに文字コードを示す文字列を代入する時、実際には文字列の1バイト目だけを評価しているからである。
例えば、次の様に代入式を書いても$KCODEにはSJISを指定したことになる。
$KCODE = "SUGEEEEEEEEE"
要するに最初の1文字だけが'e','s','u','n'(及びそれぞれの大文字)なら、代入する文字列は何でも良いのだ。そして、これら以外のものを代入すると、$KCODEは"NONE"になる。

それと言わずもがな、$KCODEのKはKANJIのK。

2008年7月22日火曜日

Rubyをごにょごにょ

NXTのコントロールスクリプトをRubyで書いたので、なんとなくRubyを覚え始めるようなった。

というわけで、ちょっとしたRubyまとめ〜識別子編〜

ローカル変数  :小文字から始まるもの。:foo
インスタンス変数:@から始まるもの。   :@foo
クラス変数   :@@から始まるもの。  :@@foo
グローバル変数 :$から始まるもの。   :$foo
定数      :大文字で始まるもの。 :FOO
擬似変数    :真偽値などを定義する。代入は不可。
        :nil   …null、偽。NilClass
        :true   …真。TrueClass
        :false  …偽。FalseClass
        :__FILE__ …現在のソースファイル名
        :__LINE__ …現在のソースファイル中の行番号

 Tips
  グローバル変数でも定数のような使い方をする場合は、大文字で書いてやると分かり易い。
  例えば、$DEBUGはスクリプトの初めにデバッグするかどうか真偽値で決めた後は殆ど変更しない。
  例文) puts("This is debug message.") if $DEBUG # $DEBUGが真ならデバッグ用メッセージを表示
  インスタンス変数やクラス変数でも、同様だろう。

2008年7月21日月曜日

LEGO MINDSTORM NXTを操作するiアプリを作……れなかった

我武者羅に作ってきましたが、全部無駄だったと分かりました。

iアプリで、GPSやBluetoothやメール機能などなどのセキュリティ的に危うい部分にアクセスするには、iモードのコンテンツ提供業者として認可されないといけないみたいです。認可を受けるとTrustedAPIDというのが発行されて、そいつをADF設定に突っ込むことでBluetooth機能などがiアプリから制御可能になるということです。
下調べって重要ですね orz

あぁ……Smartphone買っちまうかなぁ……



それと、今日買ってきた参考書↓

Linuxの教科書―ホントに読んでほしいroot入門講座 (IDGムックシリーズ)Linuxの教科書―ホントに読んでほしいroot入門講座 (IDGムックシリーズ)
高町 健一郎

アイ・ディ・ジー・ジャパン 2007-10-06
売り上げランキング : 3878

Amazonで詳しく見る
by G-Tools

お勉強のために買ってみた。何分、にわかLinuxユーザなのもので……

たまたま持ってたUbuntu本の裏表紙にこの本の広告が載ってて、初心者なおいらにぴったりだろう、と思って購入してみた。
電車の中なんかで読みたいと思ってたのだけど、いざ書店に行ってみたらA4サイズだったのでちょっと逡巡したが結局買ってしまった。

そしてブログに書いておこうと思い、リンクを張るためにAmazonの商品ページに行ったらレビューで高評価だったので読む前から満足しちゃってる俺。つか、買う前にちったあ調べるべきだったよなァ

2008年7月20日日曜日

LEGO MINDSTORM NXTを操作するiアプリを作りたい3

とりあえず、Bluetooth接続まわりのコードを少しずつ書いてます。

とりあえず、Bluetooth接続してNXTとのメッセージ送受信を行うNXTCommクラスを作成中。
メソッドの名前とか定数名とかはRuby-NXTまんまにしとくのが分かり易いかな。

public class NXTComm implements BTStateListener{

static Bluetooth bt = null;
static RemoteDevice rd = null;
static SPPConnection connection = null;
static OutputStream output = null;
static InputStream input = null;

//Constructer
public NXTComm() {
Dialog dialog = null;

//Bluetooth initialize
//Connect NXT
try{
bt = Bluetooth.getInstance();
rd = bt.searchAndSelectDevice();
if(bt.isConnectable(Bluetooth.SPP) == false
|| rd.isAvailable(Bluetooth.SPP) == false){
throw new Exception("Cannot use SPP");
}
connection = (SPPConnection)rd.connect(Bluetooth.SPP);
connection.setBTStateListener(this);
output = connection.openOutputStream();
}catch(Exception e){
dialog = new Dialog(Dialog.DIALOG_ERROR,"Bluetooth");
dialog.setText("ERROR:" + e);
if(rd == null){
dialog.setText("ERROR:" + e + ",RemoteDevice:null");
}
dialog.show();
IApplication.getCurrentApp().terminate();
}
} //end of Constructer

//BTStateLisntener interface's abstract method
//call when Bluetooth connection state changes.
//ex:Disconnected.
public void stateChanged(int state){
Dialog dialog = new Dialog(Dialog.DIALOG_ERROR,"Bluetooth");
if(state == DISCONNECT){
dialog.setText("ERROR:Disconnected.");
}else{
dialog.setText("ERROR:" + Integer.toString(state));
}
dialog.show();
IApplication.getCurrentApp().terminate();
}

その他メソッドなどなど、、、工事中

}


ともかく動けば良い精神でテキトーに書き進めてるので、気づくと美味しいスパゲッティになってるんだろうなぁ。。。

2008年7月19日土曜日

iアプリの大会に出るのでDojaの基本をおさらい

出ます。

去年も出た大会なんだけども、その時は時間が無くててんで駄目だった。2次予選で落ちました。
今年こそは本戦出場!っていう感じで行きたいのです。

で、これだけだと記事としてどうなのよ、ということで、何となくiアプリ(Doja)の基本をおさらい。

Dojaでは、Java標準のパッケージの代わりにDoja専用のものを使う。
import com.nttdocomo.ui.*;
import com.nttdocomo.device.*;
こんな感じ。

Javaではプログラムはシステムから呼び出されたクラスのmain()メソッドから実行が開始されるが、DojaではIApplicationクラスを継承したクラスのstart()メソッドから実行される。
public class DojaApplication extends IApplication{
public void start(){
・・・
}
}
上記の事を除けば、あとはJavaとほとんど同じ。
ただし、iアプリを作る際には、この他にADF設定というのが必要になってくる。これはiアプリに関する各種パラメータを設定するもので、スクラッチパッドの使用量など、実際にiアプリが動作する際に重要になってくる部分だ。通常のJavaコンパイラを使わず、専用のiアプリ作成ツールが必要になる理由がこのあたり。

ぶっちゃけ、俺もADF設定のあたりはよく分かっていなかったり。

2008年7月18日金曜日

LinuxのコマンドラインスクリプトについてのTips

Linux環境なんかで、PerlやらRubyやらPythonやらのスクリプトについてのTips

スクリプトの1行めに、
#!/usr/bin/ruby
と、書くとRubyのスクリプトとして実行してくれるわけだけど。(rubyコマンドの引数にスクリプトを突っ込まず、直接スクリプトファイルから動作させる場合)
これでは、rubyコマンドが/usr/bin/ディレクトリに存在しない場合は動作しない。

そこで、
#!/usr/bin/env ruby
と書くと、環境変数PATHを見て回ってrubyコマンドを探してくれるので、可搬性がある。

今日は何も出来なかったので、これでお茶を濁す。

2008年7月17日木曜日

LEGO MINDSTORM NXTを操作するiアプリを作りたい2

何でお前ソフトバンクユーザなのにiアプリ作ろうとしてるんじゃい。というご意見はもっとですが、単にコンテンツアグリゲータに登録するのが面倒なだけです orz
何か作品を公開しようっていうわけじゃないし。このアプリを作ったらもう使わなくなるだろうし。。。
それに、iアプリは以前にコンテストに出場しようとした事があるので、作成経験があるのです。

んで、本題。
どうやら、iアプリ製作ツール標準のエミュレータでBluetooth機能も使えるらしいんだけど、その設定方法が分からない。
そもそも、全世界で日本のNTTドコモだけが使っている仕様だけに関する資料が少ない orz
APIリファレンスがあるからコーディングは出きるだろうけど、そのテストが出来ないんじゃなぁ。。。
MIDP羨ましい。。。
Willcom 03買ってMIDPで作っちまおうかとか考えてるくらいです。

2008年7月16日水曜日

LEGO MINDSTORM NXTを操作するiアプリを作りたい

目標はタイトルの通り。

言わずもがな、iアプリはJavaで作るわけだけども(正確にはiアプリ向けのプロファイルDoja)、JavaでNXTを動かすAPIは既に存在してる。
LeJOS, Java for Lego Mindstorms - http://lejos.sourceforge.net/

でも、これがDojaで、実機のFOMAで、動作するかはまったく分からない。そもそもiアプリ製作ツール付属のエミュレータってBluetooth機能を試すときはどうするんだ? その前に対応してるのか?

というわけで、まぁDoja標準のBluetoothの機能を使うなら確実だろうから、それを使うことになったときのためにまとめておく。

com.nttdocomo.device.Bluetooth
http://www.rcdtokyo.com/man/doja/api/com/nttdocomo/device/Bluetooth.html
端末のBluetooth 機能を表すクラスを定義します。このクラスでは、端末の Bluetooth 機能を呼び出して、 外部機器の検索、機器選択、機器登録、各種設定などを行います。 外部機器が選択されると、その外部機器に対応したRemoteDeviceクラスのオブジェクトを取得します。

com.nttdocomo.device.RemoteDevice
http://www.rcdtokyo.com/man/doja/api/com/nttdocomo/device/RemoteDevice.html
Bluetoothで端末と接続される外部機器を表すクラスを定義します。外部機器との接続は、 i アプリから接続要求(connect(int profile))を出すか、 もしくはその外部機器からの接続要求を受け付けること(accept(int profile))で行います。同じ Bluetooth アドレスを持つ有効なインスタンスが複数存在することはありません。

com.nttdocomo.device.BTStateListener
http://www.rcdtokyo.com/man/doja/api/com/nttdocomo/device/BTStateListener.html
Bluetoothの接続状態の変化に関するイベントのリスナを定義します。

com.nttdocomo.device.BTConnection
http://www.rcdtokyo.com/man/doja/api/com/nttdocomo/io/BTConnection.html
Bluetoothの接続を定義します。

com.nttdocomo.device.SPPConnection
http://www.rcdtokyo.com/man/doja/api/com/nttdocomo/io/SPPConnection.html
Serial Port Profile (SPP)で通信を行う場合の接続を定義します。 Serial Port Profile (SPP)を使ったデータの入出力のためのストリームを取得します。 端末がサスペンドし、レジュームした際、サスペンド前に取得済みのストリームを利用することができます。

そしてこの辺りを参考にすれば実装できるんじゃないかと思う。
http://bearmini.net/blog/View.aspx?bid=1&aid=133&cid=13


だが、最大の問題は俺がソフトバンクユーザなことだ。

2008年7月15日火曜日

Bluetooth接続でLEGO MINDSTORM NXTを動かした

昨日のエントリからの続き。


機体を改造して最終的に出来たのが写真のもの。(奥にあるのは先生が作った見本機。俺は男のロマンを追求してキャタピラにしたが)

元々、授業中の「ライントレースを行う」という課題のために作ったので、前に光センサx2とか付けていたりする。ただし、昨日のエントリで書いたスクリプトは単純に走行用のモータを制御するだけだ。

写真だと分かりづらいが、機体上部にロケットパンチ(?)みたいなのを付けてみた。3つ目のモータが回転するとクランクで力を伝えてスイッチを押し、ロケットパンチを発射する。(ちなみにロケットパンチはNXTの拡張キットにしか入ってないらしい)
ロケットパンチを発射するためのスクリプトも書いてみた。次のコードを昨日のエントリのコードに追記して、ENTERキーが押されたときにcanon_fireメソッドを呼び出すようにメインループにもコードを書き加えた。
@motor_canon = NXTComm::MOTOR_C

def canon_fire
@nxt.set_output_state(
@motor_canon,
100,
NXTComm::MOTORON,
NXTComm::REGULATION_MODE_IDLE,
0,
NXTComm::MOTOR_RUN_STATE_RUNNING,
360
)
end

@nxt.set_output_stateメソッドで、@motor_canon(ポートCのモータとして初期化)を360回転させるようにしている。
クランク部分や、実際の動作時の映像とかを撮っておけばよかったなぁ orz

普通に付属のソフトウェアで、動作ルーチンのプログラムも勿論組んだ。というか、授業ではそちらがメイン。俺だけだ、リモートコントロールなんてしてるのは。
そのプログラムでは、機体上部にモータと共に設置した超音波センサによって、前方に障害物があるとロケットパンチを発射する様にしたりしたw


さて、次はiアプリでコントロール出来るようにするか。

2008年7月14日月曜日

Bluetooth接続でLEGO MINDSTORM NXTを動かすRubyスクリプト

ヨドバシでBluetoothドングルを購入し、そのまま大学へ。
買ったのはPCIのBT-MicroEDR2
買った後に、先生から「MINDSTORMのBluetoothは相性キツいよ」と言われたが、問題なく繋がった。

んで、色々参考にしながら書いたのが下のRubyスクリプト。実行環境はUbuntu 8.04。
require 'sdl'
require 'rubygems'
require 'nxt_comm'

# control motors methods
# com is boolean. true/false = go/stop
def motor_right(com, pow)
if com
@nxt.set_output_state(
@motor_right,
pow,
NXTComm::MOTORON,
NXTComm::REGULATION_MODE_IDLE,
0,
NXTComm::MOTOR_RUN_STATE_RUNNING,
0
)
else
@nxt.set_output_state(@motor_right, 0, 0, 0, 0, 0, 0)
end
end

def motor_left(com, pow)
if com
@nxt.set_output_state(
@motor_left,
pow,
NXTComm::MOTORON,
NXTComm::REGULATION_MODE_IDLE,
0,
NXTComm::MOTOR_RUN_STATE_RUNNING,
0
)
else
@nxt.set_output_state(@motor_left, 0, 0, 0, 0, 0, 0)
end
end

#MoveMethods
def goAhead(com)
if com
puts "goAhead"
motor_right(true, -100)
motor_left(true, -100)
else
puts "goAhead stop"
motor_right(false, 0)
motor_left(false, 0)
end
end
def goBack(com)
if com
puts "goBack"
motor_right(true, 100)
motor_left(true, 100)
else
puts "goBack stop"
motor_right(false, 0)
motor_left(false, 0)
end
end
def rotateRight(com)
if com
puts "rotateRight"
motor_right(true, 85)
motor_left(true, -85)
else
puts "rotateRight stop"
motor_right(false, 0)
motor_left(false, 0)
end
end
def rotateLeft(com)
if com
puts "rotateLeft"
motor_right(true, -85)
motor_left(true, 85)
else
puts "rotateLeft stop"
motor_right(false, 0)
motor_left(false, 0)
end
end

#main

begin
@nxt = NXTComm.new("/dev/rfcomm0")
@motor_right = NXTComm::MOTOR_A
@motor_left = NXTComm::MOTOR_B
rescue
puts "Bluetooth Connection failed"
exit
end

puts "Connected to NXT"

SDL.init(SDL::INIT_VIDEO)
screen = SDL.setVideoMode(320, 240, 16, SDL::SWSURFACE)

puts "press ESC to exit"

while true
begin
case event = SDL::Event2.poll
when SDL::Event2::Quit
exit
when SDL::Event2::KeyDown
if event.sym == SDL::Key::UP
goAhead(true)
end
if event.sym == SDL::Key::DOWN
goBack(true)
end
if event.sym == SDL::Key::RIGHT
rotateRight(true)
end
if event.sym == SDL::Key::LEFT
rotateLeft(true)
end
when SDL::Event2::KeyUp
if event.sym == SDL::Key::UP
goAhead(false)
end
if event.sym == SDL::Key::DOWN
goBack(false)
end
if event.sym == SDL::Key::RIGHT
rotateRight(false)
end
if event.sym == SDL::Key::LEFT
rotateLeft(false)
end
if event.sym == SDL::Key::ESCAPE
puts "bye"
exit
end
end
rescue
puts "Error"
exit
end
end

exit
余計な部分もあるが、まだ少し弄くろうと思ってるので分かり易さ重視。

作ったのは戦車のような機体。
モータの回転力を与える部分で、前進させるのに-100と指定しているのは、機体のモータの向きを逆に付けてしまっているため。
超信地旋回では、少し回転力を弱くして(85)回りすぎないようにしている。初め、50に設定してみたが、弱すぎて動かず、ビープ音が(汗


事前にインストールしておくもの
  • libserialport-ruby
    Rubyで使うシリアルポートライブラリ。
  • rubygems
    ruby-nxt-0.8.1.gemをインストールするのに必要。gemはRubyでパッケージ/ライブラリを管理するコマンド。
  • ruby-nxt-0.8.1.gem
    RubyからNXTを使うためのライブラリ。aptではなく、直接DLしてきてgemでインストールする。sudo gem install ruby-nxt-0.8.1.gem。http://rubyforge.org/projects/ruby-nxt/
  • libsdl-ruby
    RubyからSDLを使うためのライブラリ。キー入力を取得するのに使った。
また、実行前にNXTとPCをBluetooth接続して、デバイスファイルを作っておく必要がある。そして、デバイスファイルのパスを、スクリプト中のNXTComm.newの引数として渡してやらなければならない。


デバイスファイルの作成方法は次の手順。

NXTのBluetoothをONにして、PCにBluetoothドングルを差した状態で
$ hcitool scan
を実行してNXTのMACアドレスを表示させる。
/etc/bluetooth/rfcomm.confを編集し、次の様にする。
rfcomm0 {
bind yes;
device MACアドレス;
channel 1;
comment "NXT";
}
Bluetoothデーモンを再起動。
/etc/init.d/bluetooth restart
PC側から、もしくはNXT側からBluetooth接続要求を出して接続をペアリングする。ペアリングは上のサ行の前にやっても良かったかもしれない。
これで、Bluetooth接続したNXTへのデバイスファイルが/dev/rfcomm0というパスで出来ている筈。


設定ファイルをいじらずにデバイスファイルを作成する方法が合ったので追記。
$ hcitool scan
で機器を検索し、MACアドレスを表示させる。

$ sudo rfcomm bind 1 MACアドレス チャンネル番号
で、MACアドレスで指定した機器への/dev/rfcomm1というデバイスファイルが出来る。チャンネル番号は省略して良い。省略すると自動で1が割り当てられる。

$ rfcomm
何もオプションを指定せずにrfcommコマンドを叩くと、現在登録している機器の情報が表示される。
rfcomm1: 01:23:45:67:89:10 channel 1 clean
という感じ。

登録機器を開放する場合は、
$ sudo rfcomm releace rfcomm1



これで、取り合えずは動いたのだが、キーを連打すると実際の動作が追いつかなかったり、左右のモータを同時に動かそうとしても少し時間差が出てしまったり、、、

<追記>
ってか、Rubyの標準ライブラリにCursesあるんじゃん。SDLいらんかった orz

2008年7月13日日曜日

Rubyコンチクショウ

昨日のエントリで言っていたBluetoothドングルは買いにいけなかった orz
まぁ、明日行けばいいや。

ともかく、MINDSTORMのための簡単なコントロールプログラムを書きたい。
とりあえず、リアルタイムで受け付けるキー入力に合わせてモータの回転を制御をする、というプログラムを書きたい。上キーが押されたら前転、下キーが押されれば逆転、という具合。

ちょうどRubyでモータの回転を制御するコードを載せている記事を見つけたので、あとはキー入力を判断する部分を書けばいいや、と思ったのだが躓いた orz

素のRubyに用意されている入力といったら、readlineメソッドくらい。つまり、キー入力→エンターキー、としなければ入力を受け付けてくれない。そんなのコントローラじゃねぇ!

適当なGUIツールを使ってやらなきゃいけないわけだが、このエントリを書いてる間にもう日付変わっちまうよオイ。
というわけで、明日へ続く。

メモ
SDLライブラリを使うのが手っ取り早そう。

2008年7月12日土曜日

LEGO MINDSTORM NXT

火曜日に大学でLEGO MINDSTORM NXTを使った授業があった。
いろいろいじくっていると、「おっ!これBluetooth使えるんじゃん」ということで色々試したくなった。

ググってみると、やはり先達が多くいらっしゃる様子。
lego mindstorm bluetooth control - Google 検索:

ようし、俺も……と思ったが、ちょっと待て。
俺Bluetoothのドングルって、以前に上海問屋で激安で買った粗悪品しか持ってないぞ。
XP以降のWindowsなら大抵のBluetooth機器はOS標準のドライバで動くはずだが、こいつの場合はBluesoleil使わないと何故か全く動作しないようになっている。
Amazon.co.jpでドングル買おうかと思ったが、次の授業までに届かないだろうし。。。

とりあえず、明日はドングル買いに行ってみようかな。

以下、使えそうな記事のメモ

Linuxを使ってLEGO Mindstorms NXTを動かす - れごぼく@1981s~2年目組込みエンジニアの奮闘記~ - 1981s:
http://born1981.g.hatena.ne.jp/skelton_boy/20061207/1165491354

Linux上のRubyからBluetooth経由でLEGO MINDSTORMS NXTを制御♪ - verus diary
http://d.hatena.ne.jp/verus/20080318/1205774233

2008年7月11日金曜日

Willcom 03に手を出せない

1日1更新!を掲げてみたはいいものの、毎日プログラムやるわけではないから、いきなり記事ネタがなくなりかけている。
ただでさえ、バイトに時間取られるのに orz

Google Notebookに覚書をいろいろ書きためてはいるが、それに安易に手を出すのもどうかと思う。
というわけで、買おうか迷っているWillcom 03の話を。(ぉぃ

買おうか逡巡する理由
  1. 家が電波圏内ギリギリ
    いきなり致命的です。はい。
    だってアンテナが600m弱先にあるんですもの。500m圏内なら概ね良好に使えるということをWillcomは言っていますが、我が家は危うい。友達の端末を借りて試してみたんですが、庭では電波がそれなりに入るものの、自分の部屋の中では窓際ギリギリに行かないと辛い様。

  2. つーか行動範囲が田舎
    mstはそれなりな田舎都市に住んでいます。幹線となる大きな国道が通っているので市街地は田舎らしい発展をしてます、つまり田舎です。
    電波サービスエリアについて、Willcomは人口カバー率99%とか言ってますが、サイトに乗っている人口カバー率に関する但し書きを見ると、次のよう書かれています。
    人口カバー率 = 開業市町村の総人口※ / 日本総人口
    ※当社の開業市町村は、市町村役場及び市街地をカバーしていることを前提とし、お客さまの利便性を考慮した上で決定しています。
    我が家がある所はまったく市街地でないので、99%という数字が意味をなさないことがよく分かります。
    ちなみに、うちの教授が「mstの自宅をGoogleMapで見てみたらものすごい豪邸だった」とか言ってましたが、田舎の農家なので敷地が大きい&納屋がデカいだけです。。。

  3. ポケベル入力がない
    「お前は何を言っているんだ」という感じでしょうが、mstはかなりのベル打ちユーザです。ぶっちゃけ「QWERTYフルキーボードがあっても、ベル打ちのが早いんじゃね?」とか思ってます。でも、いっぱしの理系学生としてはスマートフォンが欲しいんです(T_T)
    ZERO-3系端末で動作するキーバインドを変更するアプリがあるんですが(ctrlswapmini)、そいつは03では動作しない模様なので。。。

  4. 不具合出まくり?
    03に関する2chスレやmixiなんかの書き込みを見てると、どうも初期不良が出てる端末が幾つかある様。それに加えてメニュー周りがあまり作り込まれていない、とかなんとか聞きます。
    いずれにしろ初期ロットはスルーしようと思ってるのですが、ヨドバシ行ったら売れ残りまくりだったぞオイ。
こんな感じで、今なかなか03に手を出せずにいます。
本当はこのブログで03弄り日記を付けようと思ったのですが、まだまだ先になりそうです。

2008年7月10日木曜日

世界一汚いCコードを読み解く

昨日のエントリ「世界一汚いCコード」を読み解いてみる。

まずは原型。
printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);
これの結果がunixになるのは何故なのか、少しずつ文を読み解いていく。

実はCでは#define unix 1 となっているので
printf(&1["\021%six\012\0"],1["have"]+"fun"-0x60);
配列を扱う書き方においては、x[1] = *(x+1) = *(1+x) = 1[x] なので
printf(&*("\021%six\012\0"+1),*("have"+1)+"fun"-0x60);
&* は意味が無いので
printf(("\021%six\012\0"+1),*("have"+1)+"fun"-0x60);
"\021%six\012\0"の1つ目の\0はNULL文字かと思ってしまうが、Cでは数値の先頭に0を付けると8進数を表すので、021の部分は8進数21という数値であり\021で1文字と見なされる。
ダブルクウォートで括った文字列"string”はstringという文字列の先頭ポインタとなる。
("\021%six\012\0"+1)ならば+1で先頭の位置が一文字ずれて、"%six\012\0"という文字列の先頭ポインタとなる。
ただし、*("have"+1)は*が付いているので、文字列の2文字目の値自体を指す。
printf(("%six\012\0"),'a'+"fun"-0x60);
'a'のASCIIコードは0x61であり、0x60を引くと1となるので、"fun"+'a'-0x60は"fun"+1となる。
さらに先の"\021%six\012\0"+1→"21%six\012\0"と同様に、"un"になる。
printf(("%six\012\0"),"un");
NULL文字(\0)は文字列の末尾を示すので、"%six\012\0"は実質"%six"
printf(("%six"),"un");
%sは第二引数の値と入れ替わるので、
printf("unix");


汚いっていうか、如何に読みづらくしているか、っていうコンテストじゃねコレ?

2008年7月9日水曜日

世界一汚いCコード

大学で、たまたま「汚いCコードコンテスト」の話になった。

例えばこれ。
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
1987年の入賞作品だそう。
http://www0.us.ioccc.org/1987/korn.c
実行結果は「unix」と表示される。

何故そうなるのか初見ではまったく分からない orz

このコードを読み解くためのヒントなんていうものが一緒にあった。
http://www0.us.ioccc.org/1987/korn.hint

ヒント1:unix
unixというシンボルはコード中で宣言も定義もされていない。unixは何を意味するのか。

ヒント2:"have"
"have"というのが出てくるが、""で括ってあるので文字列かと思いきや、さらに[]で括ってある。

ヒント3:[]
Cではx[1]と書くのは、*(x+1)の省略形になっている。数学的に考えれば、*(1+x)でも意味は同じだ。じゃあ、1[x]とx[1]は同じじゃないか。

本当はコードを読み解いていこうと思ったけど、今日は力尽きてしまったので終了 orz
また後で追記するかも。

---------------------------------
7月10日、追記しました。
世界一汚いCコードを読み解く:
http://mstssk.blogspot.com/2008/07/c_10.html

2008年7月8日火曜日

pkg-configについて

gtkを弄ってみるネタの続き

Ubuntuではgtkの開発ライブラリがlibgtk2.0-devというパッケージ名になっている。libgtk2.0-docも一緒にインストールしておいた。

ところが、サンプルプログラムをコンパイルしようとしてちょっとつまづいた。
GUIを作るのはJavaくらいしかやったことが無かったわ俺。

gccでコンパイルしようとしてもヘッダファイルが読み込めない云々なエラーが出てしまった。
サンプルプログラムについてたMakefileの中身を見ると、pkg-configとか使っているのがわかる。
(何故素直にmakeを使わないのかというツッコミは無しで。事細かに手順が知りたいのよ。)

以下、pkg-configについて調べたりした覚書。

・pkg-config
gtkプログラムのソースでは『#include 』という具合でgtkのヘッダファイルをインクルードしているが、実際のgtk.hは/usr/include/gtk-2.0/gtk/gtk.hというパスだったりするし、さらにはgtk.hから他の多くのライブラリを読み込むので、gccでのコンパイル時に-I/usr/include/gtk-2.0……などなど多くのオプションを付けなければならない。
pkg-configはこれらの面倒なオプション文字列を自動生成してくれるというにくいヤツ。

例えば、gtkのVer.2のプログラムをコンパイルするのに必要なgccのオプション文字列を生成するには次の様にする。
$ pkg-config --cflags gtk+-2.0 --libs
これの出力結果は、
-I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/pixman-1 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0
となる。
実際には、
$ gcc GTK_SOURCE.c `pkg-config --cflags gtk+-2.0 --libs`
と、バッククウォートで括ってgccの末尾につけて使う。
上記のコマンドが実際には次の様に置き換わるわけだ。
$ gcc GTK_SOURCE.c -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/pixman-1 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0

もちろん、pkg-configの--cflagsオプションに指定できるものはgtkライブラリだけではない。次のコマンドでpkg-configが扱える(gccのオプションを生成できる)ライブラリの一覧が表示できる。
$ pkg-config --list-all
--libsオプションは、--cflagsについてのリンカのオプションを生成する。--libs-only-l gtk+-2.0としてもよい。二つのオプションの差異については省略。

bashでのバッククウォートに関して、一応覚書程度に書いておく。
$ echo `expr 1 + 2`
これは、exprの計算結果の出力を受けて次の様に置き換わり、
$ echo 3
結果は3と表示される。
(あんまりいい例じゃないなぁ。)

結局今日はgtkの中身について触れられなかった orz

2008年7月7日月曜日

Evince文書ビューアの文字化け

gtkのプログラミングをやってみようと思い、いろいろググっているとかなりいい資料を発見した。

GTK/GNOMEによるGUIプログラミング

豊橋技術科学大学の講師の菅谷先生という方が公開しているpdfドキュメント。(上記リンク先はwikiページ)
内容は、「これ本当にタダでもらっていいの?」という位の情報量だ。

だが、このpdfドキュメントを開く段で、本来ならどうでもいい筈のことでちょっと躓いた。
Ubuntu標準のEvinceという文書ビューアで開くと文字化けしてしまってまるで漢語文書 orz
今まではgoogle Documentにアップロードして見てみたりOpenOfficeで開いたりしていたが、ちゃんと問題を解決せねば、ということで調べてみた。

どうやら、デフォのEvinceでは日本語文字を含んだpdfが文字化けしてしまうそうだ。
Evinceを日本語に対応させるには、xpdf-japanesepoppler-dataの2つのパッケージが必要なのだそう。

と、ここまで調べた時点であることに気づいた。
「これ、日本語版セットアップヘルパにあるんじゃね?」
パネルのシステム → システム管理 → 日本語版セットアップ・ヘルパ を開いて2ページ目に、案の定これら2つのパッケージのインストールを促す旨が書いてあった。
そのままパッケージをインストールして、、、文字化けが直りました。

そういえば、Ubuntuを今の8.04にしてから日本語版セットアップ・ヘルパは開いてなかった。以前に7.10を使っていた時に日本語のpdfが普通に読めていたのは、インストール後最初に律儀に日本語版セットアップ・ヘルパを開いたからだった。

それにしたって、どうせなら初めからインストールしておいてくれたっていいのに。。。

というわけで、今後ちょくちょくgtkの話題を扱っていこうと思う。

メモ
http://gtklab.sourceforge.jp/gtkwin/
http://dolphin2005.blog.so-net.ne.jp/2008-02-12

2008年7月6日日曜日

ふがいない

下級生のプログラミングの実習の授業で教員の手伝いをしてます。ちなみにC言語。
それで、来週の授業で使う課題問題を事前にメールで送ってもらったので自分でやってみてるんですが、やはりプログラミングで一番重要なのはアルゴリズムを考える能力だよなぁ、と改めて感じてます。

Cの文法なんかは分かるんだよ! ただ、どうやりゃいいのかわかんねぇんだよ!

という感じ。
ぁ、ぃゃ、今回の課題が分からないって意味じゃないですよ。途中ですけど。ただ、普段プログラムやってて一番ぶち当たるのはアルゴリズムの部分だと思うので。

まぁどうせ教科書の例題をそのまま課題にしてるので、授業ではみんな教科書丸写しで提出しようとするんですが、そこで俺が「コード説明してみて」と千尋の谷に突き落とすわけです。

日付が変わっちゃいそうなので、今日の記事はこれでお茶を濁そうとしてる俺は卑怯者さ orz

2008年7月5日土曜日

Linuxでiso9660ディスクイメージのマウント

ディスクイメージをそのままマウントするのは、Windowsだと仮想ドライブソフトを使わなきゃできませんが、LinuxのカーネルVer 2.4以降はISO9660フォーマットのディスクイメージをmountコマンドで普通にマウントできます。

root権限(Ubuntuとかなら、sudoで)でこんな感じで出来ます。マウントポイントはそれぞれの環境に合わせて変えましょう。
# mount -t iso9660 -o loop [isoファイル].iso /media/cdrom0/
アンマウントする時も普通にumountコマンドを使います。
$ umount [マウントしたisoファイル].iso

ただし、isoファイル内に日本語(2バイト文字)がある場合は、このままでは文字化けするのでオプションで文字コードを変換してやらなきゃいけません。
例えば、Shift-JISエンコードのファイル名を含んでいるイメージをUTF8環境でマウントするなら、mountコマンドの-oオプションにiocharsetを付け足します。
# mount -t iso9660 -o loop,iocharset=sjis,utf8 [isoファイル].iso /media/cdrom0/
これで、ファイル名をShift-JISからUTF8に変換して表示してくれます。

GNOMEデスクトップ環境でnautilusを使っている人は、nautilus-mount-imageというスクリプトのプラグインを導入するとisoファイルのコンテキストメニューからマウントできるようになります。

Nautilus scripts - http://mundogeek.net/nautilus-scripts/#nautilus-mount-image

ただしこのスクリプトは日本語文字コードの変換をしてくれませんので、注意です。

2008年7月4日金曜日

Linux(Ubuntu)で横チルト付きマウスを使う

横チルトマウスが欲しい!と、LogitechのMX3を買ったは良いものの、Linux向けドライバなんてありゃしないので、以前に四苦八苦しながら使えるようにしたのを思い出しながら書いてみます。

Linux(というかX Windowか?)では横チルトマウスはサポートしてませんが、evdevというドライバを使うと使えるようになります。

マシンはHPのnx6125ノート、Ubuntu 8.04を使ってます。
evdevはUbuntuではxserver-xorg-input-evdevというパッケージ名になってます。
8.04 Hardyでは初めからVer 1.2.0がインストールされてます。
んでもって、次みたいな感じで/etc/X11/xorg.confに追記。
Section "InputDevice"
Identifier "LogitechMX3"
Driver "evdev"
Option "SendCoreEvents" "true"
Option "Device" "/dev/input/by-id/usb-Logitech_USB-PS.2_Optical_Mouse-event-mouse"
Option "Protocol" "auto"
Option "RelHWHEELMapTo" "Buttons 7 6"
EndSection
似たようなの(他のInputDeviceセクション)があるあたりに付け足しときましょう。
さらにはServerLayoutセクションにも次みたいに書き足します。
Section "ServerLayout"
Identifier "Default Layout"
Screen "Default Screen"
InputDevice "Synaptics Touchpad"
InputDevice "LogitechMX3" #この行を追記した
EndSection
これで、問題なく使えるようになりました。

InputDeviceセクションをもうちょっと詳しく説明すると、、、

・Identifier……セクションを識別する名前。自由に付けてOK
・Driver……このInputDeviceに使用するドライバを指定。今回はevdevを使用。
・SendCoreEventsオプション……これがtrueでないとボタンイベントが届かない?
・Deviceオプション……デバイスファイルを指定する。
・Protocolオプション……とりあえず、autoに。
・RelHWHEELMapToオプション……デフォルトだと横チルトの左右が逆になっているのでこのオプションで指定しなおす。ただし、evdevのバージョンごとに指定方法が違うので要確認。
こんな感じ。

あと、Deviceオプションについてですが、デバイスファイルはログイン毎に変わる事があるので直接デバイスファイルを指定しないようにしてます。
/dev/input/by-id/ディレクトリには、機器の接続時に機器ごとに一定な名前のシ ンボリックリンクが、適切なデバイスファイルにリンクされるのでこちらを指定しておきます。/proc/bus/input/devicesに記述されている 機器名(Name行)及びデバイスファイル名(Handlers行)を確認して、使用したい機器の適切なシンボリックリンクを見つけましょう。
RelHWHEELMapToオプションも要注意。
$ man evdev
で自分のディストリビューションに入っているバージョンのevdevでの指定方法を確認しましょう。

<追記>
Firefoxで横スクロールをするには、about:configでmousewheel.horizscroll.withnokey.numlinesの値を0にします。
また、横チルトに対する動作量をしていするmousewheel.horizscroll.withnokey.numlinesオプションの値がデフォルトだと-1になってたりします。これでは、せっかくXの設定で左右逆にしたのに、fxでだけ結局また左右逆になってしまうので、値を1にしましょう。
横チルトの左右が逆になってしまうことへの配慮なのかどうかは分かりませんが、fxでだけ対応されても困るって訳です。

2008年7月3日木曜日

1番じゃなきゃ嫌だという駄々っ子なWindowsをgrubで騙す

昨日に続いてまたgrubネタです。
昨日のエントリーで授業で自作したマシンにLinuxを突っ込んだという話をしましたが、実は面倒なことが起こってたのです。

マシンを自作したというのは実はけっこう前の話で、既にWindowsとFedoraを突っ込んでデュアルブート環境を作ってありました。そこに、いらなくなった他のマシンからHDDを持ってきて増設し、ついでに何かOSをインスコしてみようという流れでした。

既存HDD - WinXP、Fedora
増設HDD - 各々が選んだLinuxディストリビューション
という具合にしたのですが、ここで面倒な事が起こりました。

インストール時に既存HDD上のOSを認識していなかったため、grubの起動メニューにWinとFedoraが出てこなかったり、
そもそも増設HDDはBIOSで2番目になってるので、既存HDDの方のgrubが起動して新しく入れたLinuxが起動できなかったり、e.t.c...
ディストリのインストール時に、grubメニューについて訊いてくるのでちゃんと既存OSを設定しておけばいいんですけど、皆何も知らずにOKボタン連打 orz
Ubuntuだけはちゃんと既存OSを認識してたのには、やっぱこだわってるんだなぁ、と思いました。

まぁ、grubのmenu.lst(grub.conf)を書き変えて解決!と思いきや、1台面倒なことになってるのがありました。

既存HDD側のgrubがおかしなことになっていてgrubが起動しなかったので、ちょっとLiveCDで中を覗いてみたら、、、なんじゃこりゃ??

既存HDDのパーティションが何故か、WinのNTFS領域とあとは全部LVMの中。
grubが入ってる/bootパーティションもおそらくLVMの中。
素のままじゃアクセス出来ないLVMの中。。。 orz
これが、grubが起動出来なかった原因なのか、MBRの方が書き換わってしまっていたのかよく分かりませんが。このマシンを組んだ奴がとちりやがったということはよく分かりました。(#^ω^)

マシンを作った時に、
・/bootは別の基本パーティションにすること。
・Win、/boot、Fedoraのルート、SWAP、WinとFedoraの共有領域、で5つになるので拡張パーティションを使うこと。(基本パーティションは4つまで)
ということを教授に言われた筈だったんですがね。
学生がそれぞれ1台ずつ作ったんですが、危なっかしいのがいたしなぁ。
まぁ正直、MBRとかパーティション回りのことあんまり知らないので、ここいらで文句はやめときます。

んで、来週の授業でWinを使わなきゃならないそうなので、Winだけでも起動するようにしたい。
起動順序を増設HDDを1番にして、こっちのgrubからWinが呼ばれるようにすればいい、と考えたのですが。。。Windowsたんってば1番目のHDDじゃなきゃ起動してくれないのね。。。T T

何とかしてLVMの中が見えないものかと、GpartedのLive CDなんかを使ってみると、、、
おぉ、Live CDの中のgrubがパーティションを指定して起動出来るようになってる〜。
試しにWinが入ってるパーティションを指定してみると、久しぶりのWin起動画面が!
HDDが2番のままでも起動出来る方法があるわけね。

Live CDのgrubのWinのパーティションを起動するオプションの内容をみてみると、
map (hd0) (hd1)
map (hd1) (hd0)
rootnoverify (hd1,0)
chainloader +1
普通、hd1からWinは起動できませんが、hd1とhd0を仮想的に入れ替えて、Winを騙せるようです。
あとはこいつを増設HDDのgrubに書き込んで、作業完了!
とりあえずWinが起動するようになりました。

後に残ったLVM領域は…
…今度考えることにします。 orz

2008年7月2日水曜日

GRUBのsplashimage(背景画像)

大学でGRUBを弄る機会があって、その時に思ったこと。

「Ubuntuだけgrubの背景画像が無い!」

その時は、授業内で自作してみたマシンに各自好きなOSぶち込んでいいよー、という授業だったのです。
CentOSやFedoraでは、自己主張しまくりなsplashimage(背景画像)付きのGRUBがインストールされたのですが。Ubuntuはただの白黒の画面。
普段自宅ではUbuntu使っていて、気にせず白黒画面のままにしていたのですが、ユーザーフレンドリーを目指すUbuntuなら、見た目に楽しいように画像くらい付けやがれ!と思いまして、ちょっとやってみようかと。

調べてみると、splashimageに設定できる画像は結構制限があるようです。
・gzipで圧縮されたxpmまたはpng
・640x480 px
・14色

14色ってハンパだなー、と思ったのですが、どうやらgrubが動作している16色モードで背景色と前景色(文字色)を除いて14色、ということらしいです。

とりあえず、画像を用意。Ubuntu 8.04デフォルト壁紙の頑丈なサギ(Hardy Heron)画像を上記の通りにしてみます。


Bloggerがxpmを受け付けてくれなかったので、jpgを表示してますが、実際にはxpmを使いました。
それをgzipで固めて、ubuntu-hardy.xpm.gzを用意。grubのディレクトリに写します。
$ sudo cp ubuntu-hardy.xpm.gz /boot/grub/

そして、grubの設定ファイルである/boot/grub/menu.lstにsplashimageの設定を書き加えます。
ここで、注意するのが書き加える位置。ファイル後半部の、ブートローダが起動させる各OSのリストになってる部分より前に書き加えなきゃいけないそうです。
とりあえず、defaultやtimeoutが書いてあるあたりにすれば間違いはないかと。
#Splash Image
background=000000
foreground=ffffff
splashimage=(hd0,1)/grub/ubuntu-hardy.xpm.gz

こんな感じで書き加えます。backgroundとforegroundは必ずしも書かなくて大丈夫です。書かない場合はデフォルトの白黒になります。
splashimageでは画像ファイルを
HDDとボリュームを含めて場所を指定するのですが、これはマシンごとににまちまち。
私は/bootディレクトリのみ個別のパーティションに切り分けていて、それが1番めのHDDの2番めのパーティションに当たるので、(hd0,1)と指定して/bootから先のファイルパスを書いてます。

これで、grubが画像付きになった筈!ということで再起動...
って、画像が化けまくり orz

色々ググってみると、凡ミスだと気づきました。
画像を編集する時に、画像をRGBモードのままGIMPのポスタリゼーション機能で14色に減色してましたが、これじゃあ画像のカラーマップは14色になってません。

ということで、改めて画像を作り直して再起動。
ちゃんと頑丈なサギが表示されましたッ!

2008年7月1日火曜日

1 Entry per Day

まずは自己紹介から

mstsskと申します。
某地方私立大学で計算機科学とか勉強してる大学4年生です。
大学生活の山場である就職活動が終わり、来年度から新米プログラマとして働くことが決まりました。

そして、このブログは何のために作ったかというと、自分の勉強のため、です。

元々WEB技術なんかに興味があったので、ブログのような簡単なツールから始めてみよう、と思いつつも、なんとなく始める機会を逃していました。
ですが、就職活動が終わり、キリが良い所でそろそろ始めてみよう、と考えました。
同時に、社会人になるまでにもっと自分の能力を高めておきたい、という思いもありました。

そこで、このブログを運営するにあたっての目標を
1日1記事
としたいと思います。同時にこのブログのタイトルでもあります。

毎日必ず、何かしら技術に関する記事を書きます。
プログラミングに関する覚書や、技術記事についてなどを考えてます。
勉強するだけならブログなんて書く必要無いんですが、形にして表に出すことで自分を律する効果を狙っていたりします。正直、私は不精な人間なので。。。

とりあえず今日は、自己紹介までに ^ ^