2014年5月2日金曜日

Arduinoでヘッドマウントディスプレイ用のヘッドトラッカーを作る

きっかけ

Furlan氏のOculusRiftライクなHMDを自作する記事を見て、真似して作ってみたはいいものの、ヘッドトラッカーだけ無い状態だった。 氏の記事ではHillcrest Freespace FSRK-USB-2 IMUを買えとあるが、どうやらもう売ってないみたいだし、そもそも売っていたとしても高すぎる。 そうして、自作することにした。

目的

安価な部品でヘッドトラッカーを作成する。このヘッドトラッカーはUSBでPCと接続し向きを変えることによってマウスカーソルを動かすことができるものである。HMDに設置し、マウスで視点が動かせるようなゲームなどで使用することを想定している。

必要な部品

  • Arduino UNO R3(もしくはUSBシリアル通信のチップがAtmega16u2であるような同等品)
  • Amazonで売ってるが、ebayの互換品のほうが安い。

    USBシリアル通信のチップの背面を見て、Atmega16u2と書いてあればOK。

  • MPU6050モジュール
  • Amazonebayで買える。

  • ブレッドボード
  • 小さいものでOK。とりあえずAmazonで買える。

  • ジャンパーコード
  • 5本必要。Amazonでやっぱり買える。

  • USBケーブル
  • 用意したArduinoと接続できるタイプのもの

  • 段ボール
  • Amazonの箱とかでOK

  • ガムテープ
  • ダクトテープやビニールテープでもOK

必要な工具など

  • ハンダこて
  • ハンダ
  • PC

作り方

Arduinoの開発環境を整える。公式サイトでダウンロードできる。

Arduinoに以下のスケッチを書き込む

github: okdshin/HeadTrackerSketch

dfu-programmerをPCにインストールする。ここでダウンロードできる。

ArduinoをPCにUSBケーブルで接続し、リセットピンをジャンパーコードで3秒くらいショートさせて、Atmega16u2をリセットする。リセットピンの位置はここのStep1に図が載っている。

darran氏のページからArduino-mouse-0.1.hexをダウンロードする。

Arduino-mouse-0.1.hexが存在するディレクトリで次のコマンドを打ち込む

sudo dfu-programmer atmega16u2 erase
sudo dfu-programmer atmega16u2 flash --debug 1 Arduino-mouse-0.1.hex
sudo dfu-programmer atmega16u2 reset

ArduinoとPCを切り離す

MPU6050モジュールをハンダ付けして組み立てる。

ArduinoとMPU6050モジュールをジャンパーコードとブレッドボードで接続する。

わかりやすいつなぎ方の図が載っているページ

完成である。

Arduinoを元に戻したり、スケッチを書き換えたい場合

ArduinoをPCにUSBケーブルで接続し、リセットピンをジャンパーコードで3秒くらいショートさせて、Atmega16u2をリセットする。

次のコマンドを打ち込む。ただしArduino-usbserial-uno.hexはarduino-1.0.5/hardware/arduino/firmwares/atmegaxxu2/arduino-usbserial直下にある。arduino-1.0.5の部分は適宜変えること。

sudo dfu-programmer atmega16u2 erase
sudo dfu-programmer atmega16u2 flash --debug 1 Arduino-usbserial-uno.hex
sudo dfu-programmer atmega16u2 reset

ちなみにArduino-usbserial-uno.hex自体はgithubでも中身が見られる。

ArduinoとPCを切り離す。

これでArduinoはスケッチを書き込める元の状態に戻る。

既知の問題

ゆっくり動かす分には大丈夫だが、ちょっとでも速く動かすと累積誤差がひどい。ソースコードを改善する必要がある。そのうちやる予定。というか誰かやってくれ。プルリク歓迎。

備考

マウスカーソルを動かす速度を変えたい場合はスケッチの800行目前後にある

float ratio = 10.0;
の値を変えてください。

参考にしたサイト

Gyroscopes and Accelerometers on a Chip

Turning your Arduino Uno R3 into an USB mouse

2014年4月6日日曜日

OculusRiftライクなHMDを自作する

20140617追記

この記事中で作ったHMDの後継機についての記事がここにあります。

これから作る人は上記事を参考にしたほうが良いです。

きっかけ

Boost.勉強会 #14 東京の懇親会でhecomi氏がOculusRiftをデモしていたのだけれど、その時僕は度肝を抜かれた。懇親会は中華料理屋で行われていて、赤い照明に中華風の装飾の狭い部屋の中にいたはずなのに、手渡されたOculusRiftをかぶるとそこは西洋風の建物の上空で、ジェットコースターのようにレールを走るトロッコの上に僕は突っ立っていた。トロッコが曲がろうとすると、反射的に体を傾けてしまう。落下するときには胃が確かに持ち上がる感覚がした。ソニーのHMZ-T1を持っているが、比べ物にならない自然な没入感があった。hecomi氏は他にもいくつかのデモを見せてくれたが、どれもHMDの新しい可能性を示唆するものだった。

早速、その時やっかいになっていた江添氏の住むシェアハウスに戻ると、僕はOculusRiftを注文した。注文してから、しかしそれでいいのだろうかと思った。江添氏曰く、製品版が近々出るらしいし(実際出たのは製品版ではなくDK2だったが)、そんな不自由なハードウェアを今慌てて買わなくてもいいのではないか(ちなみに、江添氏のOculusRiftを使ってみた感想が含まれる記事)。その通りだと思った。しかし可能ならば今すぐにOculusRiftが欲しい。どうしても欲しかった。

そうして、自作することにした。

幸い、調べると、ネット上には既に自作している人がいて、作り方も公開してくれていた。基本的には、Furlan氏の自作したやり方を参考にすることにした。(この記事はほとんどFurlan氏のやり方を日本語で解説するだけである)

目的

OculusRift(DK1、以下ORDK1と表記する)と同等なHMDを自作する。ただし、今回はヘッドトラッキングシステムは省く(別記事でヘッドトラッキングシステムの自作は載せる予定である)。

必要な材料

5.6インチで画素数は1280x800のTFT液晶ディスプレイとそのコントロールボード、倍率5倍で直径5cmのレンズが2つ、黒い発泡スチロール板、スキー用ゴーグル、黒いダクトテープ、ダンボールの切れ端が少々。

5.6インチのTFT液晶ディスプレイとそのコントロールボードについて

ebayでこれを購入した。ORD1は画素数1280x800で7インチのTFT液晶を使っているらしいが、Furlan氏にならって、画素数は同じだが5.6インチの液晶を使うことにした。ちなみに電源装置が付属していなかったのでAmazonでこれを購入した。

倍率5倍で直径5cmのレンズについて

これを用意するのが一番手間取った。探してもFurlan氏の紹介しているような安いものが日本ではなかなか見つからなかった。結局、品質は疑問("約"5倍ってどういうことだ?)だが、条件に合致して安かったこれを使うことにした。

黒い発泡スチロール板について

A3サイズのものを近所のホームセンターで購入した。Furlan氏は4mm厚のものを使っていたが、なかったので5mm厚のものにした。

スキー用ゴーグルについて

これを購入した。

黒いダクトテープについて

近所のホームセンターで購入した。僕は実際に使用してみるまで、「ダクトテープってガムテープとどう違うの?」という感じだったが、まったく違った。ダクトテープはあなたの想像を凌駕する。何かを強力に貼り付けたい? ダクトテープをどうぞ。何かを完璧に密閉したい? ダクトテープをどうぞ。貼りつけた後きれいに剥がして再度貼りたい? ダクトテープをどうぞ。局部を隠したい? ダクトテープをどうぞ。HMDを作りたい? ダクトテープをどうぞ。

ダンボールについて

Amazonの箱を使った。

必要な道具

カッターナイフ、はさみ、ニッパー、ノコギリ、鉄の定規、A3サイズ以上の方眼用紙、ペン、両面テープ、ガムテープ

作り方

まず、液晶ディスプレイがちゃんと動作するか確かめる。Furlan氏曰く

(略)...次に、LVDSケーブル(訳注:液晶ディスプレイとコントロールボードを繋ぐケーブル)がノイズに弱くないか確かめよう。ちゃんとしたLVDSケーブルはノイズの影響を軽減するために特定のコードのペア同士が撚り合わせられているのだけれど、ebayで売られているほとんどのLVDSケーブルはちゃんと撚り合わせられていないため、画像に変なものが交じる可能性がある。君の購入したLVDSケーブルがちゃんとしているかどうか確かめるには、幾つかの異なる画像を試しに映してみればよい。その時、映してみる画像が多ければ多いほどよい。なぜならば、変なものは特定の色を映した時に現れることがあるからだ。

もし何らかの変なものが映ったならば、それをほとんど、もしくは完璧に全て除去できるいい方法がある。必要なのはテープの切れ端と手伝ってくれる人間だ。まず、LVDSケーブルを優しく力を加え過ぎないように慎重に捻る。そして手伝ってくれる人に捻ったLVDSケーブルをテープで元に戻らないように固定するよう頼む。このトリックは私の場合はいつもうまくいっているんだよ!

僕の場合は、手伝ってくれる人間がいなかったので、ここは適当に省いた。特に気になるような変なものは映らなかったし、必要になった後でもできる。

レンズを用意する。虫眼鏡のレンズ部分を汚さないようにガムテープで覆い、柄をノコギリで切り落とす。本当は枠も外したかったが、レンズとの一体成型のようで外せなかった。直径5cmの中に枠が含まれているのはいかがなものか。レンズについては改めて考える必要がある。覆いのガムテープを剥がすとき、糊がレンズに残る場合があるが、別のガムテープを上から貼って剥がすとうまくとれる。

次に、箱を組み立てる。寸法は以下の通り。ただしレンズとレンズの間の距離は個人によって異なるので自分のものを計測したほうがよい。(僕は7cmだった)

方眼紙に寸法通りの線を引いて、発泡スチロール板に両面テープで貼り付けて、カッターナイフで切り出す。各折り目の部分に曲げるためのVカットを施す。カットが深かったり浅かったりして折り曲げた時割れても気にしなくてよい。何かを強力に貼り付けたい? ダクトテープをどうぞ。思う存分補強すればよい。辺の部分も折りあわせた時にうまく重なるように斜めに切り込みを入れておく。

レンズをはめ込むための穴をあける。試しにレンズをはめてみて、きちんとはまるまで少しずつ穴をカッターナイフで削って大きくしていくとうまくいく。

箱をとりあえず組み立ててみて、顔に当ててみる。鼻がぶつからないように切り込みを適当に入れる。

Vカットが表になるように発泡スチロール板を置き、レンズの"太ったほう"の面が同じく表を向くように穴にはめこむ。ダクトテープでレンズの端を固定する。

液晶ディスプレイにかからないように、ディスプレイの枠をダクトテープで発泡スチロール板に固定する。上下の向きに注意すること。枠が若干はみ出したのでニッパーでネジ止めの部分を切った。

液晶ディスプレイのコントロールボードを液晶ディスプレイの貼り付けられた面の裏にダクトテープを輪っかにして両面テープのようにしたもので仮固定する。

液晶ディスプレイとコントロールボードを繋ぐケーブル用の穴としての切り込みを適当に入れる。(写真は完成後だが、切り込みにケーブルを通しているのが分かる)

箱を組み立てる。ダクトテープをどうぞ。

ここで、Furlan氏曰く、

私はテープの切れ端で左のレンズの左側と、右のレンズの右側のそれぞれ1cmを覆ったが、君もそうすることをおすすめする...(略)...そうすることでディスプレイの端が視界に入らなくなり、より没入できるHMDになるはずだ。

そうらしいので、僕もそうした。(しかし7インチのディスプレイならばこうした問題は起きなかった可能性がある)

ここで一度、動作確認をする。適当にOculusRift用の映像を流しつつ、顔に当てて確かめる。

ゴーグルの板を外して組み立てた発泡スチロール箱にダクトテープで固定する。ゴーグルの枠は湾曲しているので隙間があくが、ダンボールの切れ端で上から覆って適当に塞ぎながら固定するとよい。

ダクトテープで液晶ディスプレイのコントロールボードを落ちないように固定する。

完成である。

サンプル動画

とりあえずYoutubeに落ちているOculusRift用の動画を見ると楽しい。

Oculus Rift Canyon Run

既知の問題点とその解決方法案

次回作る場合や、このページを見て自作する人に向けた改善したらいいと思う点。

レンズと目との距離が離れすぎているために視野角が狭い

単なる距離の問題である。ゴーグルを削るか、発泡スチロール箱を削って、ゴーグルの中にレンズを押し込めるようにすれば、レンズと目との距離が縮まり、改善するだろう。

レンズ間の距離が人によって異なり、合わないことがある

何らかの後からアジャストできる仕組みが必要である。スライドできるような感じにできればいいのだが。

ダクトテープの臭いがひどい

鼻をダクトテープで固めた箱に突っ込んでいるせいである。鼻あてを別に作って貼り付ければ改善する(はず)。

埃が入り込んで画面に張り付く

発泡スチロール箱を完全に密封するか、後で開けられるようにしておくことで対応できるだろう。

発泡スチロール板の値段が高い

今からしてみればダンボールで十分だったかもしれない。実際にググるとダンボールで作っているひともけっこういる。

箱を作るのがめんどくさい

タッパーで作ったらどうかと考えている。フタにディスプレイを貼り付けたら簡単に着脱できるし便利だ。

直径5cmで倍率5倍のレンズがなかなか手に入らない

倍率が低いレンズを複数枚重ねたり、倍率が低いレンズで箱の奥行きを大きくして対応したりすることが解決法として考えられる。

まとめ

けっこういきあたりばったりで作ったが、そこそこのクオリティのものができた。今後はもっと工程を省略して、材料も安く、どこでも手に入るようなもので作れるように、既知の問題点も含め改善していきたい。

2014年2月15日土曜日

ヘッダファイルだけでC++から使えるSHA256のハッシュ計算ライブラリ『PicoSHA2』

を作りました。

https://github.com/okdshin/PicoSHA2

例えば次のようなソースコード

std::string src_str = "The quick brown fox jumps over the lazy dog";
std::string hash_hex_str = picosha2::hash256_hex_string(src_str);
std::cout << hash_hex_str << std::endl;

で、以下が出力されます。

d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592

より詳しくはREADMEを読んでください。

2013年12月29日日曜日

C++11のlvalueとrvalueで引っかかるところ

lvalueとrvalueについて、僕が引っかかったところをメモしておく。

とりあえずひと通りは江添氏の本の虫で読めば分かる。

本の虫

ここから先は本の虫の記事を読んでもイマイチ腑に落ちない人向けである。以下の様なコードを考える。


#include <iostream>

void f(int&& i){
    std::cout << "rvalue" << std::endl;
}

void f(int& i){
    std::cout << "lvalue" << std::endl;
}

void g(int&& i){
    f(i);
}

int main(){
    int i = 0;
    g(std::move(i));
}

さて、ここで出力はどうなるだろうか? Wandboxで確かめてみよう。

[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

出力が「lvalue」であることが確認できただろうか。

なぜか?

関数gの仮引数iがlvalueだからである。

言い換えると、iはrvalueリファレンス型のlvalueだからである。

つまり、「rvalueリファレンス型のインスタンスである」ということと、「rvalueである」こと、すなわち「rvalueリファレンスでキャプチャされる」ということは本質的に無関係である。

C++におけるvalueカテゴリと型システムはまったく無関係なのだ。

2013年12月15日日曜日

RSA暗号の特徴と原理

この文章では非対称鍵暗号の一種であるRSA暗号についてその特徴と原理を説明する。

対称鍵暗号と非対称鍵暗号

暗号には対称鍵暗号と非対称鍵暗号の二つの種類がある。暗号化の鍵と復号化の鍵が同一であれば称鍵暗号で、そうでなければ非対称鍵暗号である。

対称鍵暗号は非対称鍵暗号よりも一般的に頑強であり、かつ高速に暗号化と復号化の処理ができるが、鍵をいかにして安全に配送するかという問題(鍵の配送問題)が生じる。鍵の配送問題とは次のようなものである。ここでは、暗号化には対称鍵暗号を用いるとする。

ある秘密のメッセージを安全に送るには送信者はその秘密のメッセージを暗号化する必要があるが、受信者が暗号化された秘密のメッセージを復号化するには鍵が必要であるため、その鍵も安全に送る必要がある。すなわち、その鍵を安全に送るためにその鍵を暗号化する必要があるが、今度は暗号化された鍵を復号化するための鍵を安全に配送しなければならないという問題が生じる。

この、鍵を安全に送る問題には終わりがないため、対称鍵暗号では安全なメッセージをやり取りすることは本質的にできないことが分かる。

これに対して非対称鍵暗号は対称鍵暗号に比べれば一般的に脆弱であり、かつ暗号化と復号化の処理に時間がかかるが、鍵の配送問題を回避することができる。非対称鍵暗号がいかにして鍵の配送問題を回避するかを以下に手順として示す。ここでは、アリスがボブに秘密のメッセージを送ることを考える。

  1. ボブは暗号化用の鍵と復号化用の鍵のペアを生成する。
  2. ボブは暗号化用の鍵を公開する。公開された鍵はアリスはもちろん、世界中の誰に知られても構わない。
  3. アリスはボブが公開した暗号化用の鍵を用いて秘密のメッセージを暗号化し、その暗号化した秘密のメッセージをボブに送信する。
  4. ボブはアリスから暗号化された秘密のメッセージを受け取り、復号化用の鍵を用いて復号化して秘密のメッセージを得る。

このように非対称鍵暗号は鍵の配送問題を回避することができる。

現実の暗号システムの多くは対称鍵暗号と非対称鍵暗号を組み合わせて利用している。すなわちメッセージの暗号化には対称鍵暗号を用い、対称鍵暗号で用いた鍵を非対称鍵暗号でやり取りする。普通、メッセージに対して鍵ははるかに小さい。ゆえに、こうすることでメッセージ全体に非対称鍵暗号を適用した場合よりも高速にメッセージをやり取りすることができる。

非対称鍵暗号の鍵のペアが持つべき性質とRSA暗号

非対称鍵暗号で使われる暗号化用の鍵と復号化用の鍵のペアは上述したやり取りを安全に行うために、次の性質を満たさなければならない。

  • 暗号化用の鍵と暗号化されたメッセージから、復号化用の鍵を推測することが困難である。
  • 暗号化されたメッセージは復号化用の鍵で容易に復号化できる。

ところで、ある大きな数を分解して素因数を導出することは困難であるが、逆にその素因数からその大きな数を導出することは容易である。RSA暗号はこの事実を利用して上述の性質を満たす鍵を構成する。

RSA暗号の手順

ここでは、上述したアリスがボブに秘密のメッセージを送ることを考え、具体的にどのような手順を二人が行うかを示す。

  1. ボブは無作為に素数pとqを選び、その二つの積nを求める。

    さらに次の条件を満たす自然数eを選ぶ。 \[1<e<(p-1)(q-1)\,かつ\,eと(p-1)(q-1)の最大公約数が1である。\]

    そして、次の条件を満たす自然数dを求める。このようなdはeが満たす条件から必ず存在する。 \[1<d<(p-1)(q-1)\,かつ\,ed\equiv1\mod{(p-1)(q-1)}\]

    暗号化用の鍵は(n, e)、復号化用の鍵は(n, d)である。

  2. ボブは暗号化用の鍵(n, e)を公開する。

  3. アリスはボブが公開した暗号化用の鍵(n, e)と秘密のメッセージmから次の式を使って暗号化されたメッセージcを求める。 \[c\equiv m^{e}\mod{n}\]

  4. ボブは自分しか知らない復号化用の鍵(n, d)とアリスから受け取った暗号化されたメッセージcから、次の式を使って秘密のメッセージmを求める。 \[m\equiv c^d\mod{n}\]

RSA暗号が正しく復号化できる証明

RSA暗号の復号化は次の定理に依っている。 \[(m^{e})^{d}\mod{n}=m\]

この定理は次のように証明される

dが満たす条件\[ed\equiv 1\mod{(p-1)(q-1)}\]より、\[ed=1+l(p-1)(q-1)\]となるlが存在する。 よって\[(m^{e})^{d}=m^{ed}=m^{1+l(p-1)(q-1)}=m(m^{(p-1)(q-1)})^{l}\]が成立し、 ゆえに\[(m^{e})^d\equiv m(m^{(p-1)})^{(q-1)l}\mod{p}\]である。

ところでフェルマーの小定理を次に示す。

nが素数であれば、nとの最大公約数が1である全ての整数aについて、\[a^{n-1}\equiv 1\mod{n}\]が成立する。

今、pがmの約数ではないと仮定すると、pは素数でありpとmの最大公約数は1なので、フェルマーの小定理より次の等式が成立する。 \[m^{(p-1)}\equiv 1\mod{p}\] よって、\[(m^{e})^d\equiv m(m^{(p-1)})^{(q-1)l}\equiv m(1)^{(q-1)l}\equiv m\mod{p}\]である。 また、pがmの約数であると仮定しても、両辺は\[0\mod{p}\]となるので同様に等式が成立する。 よって、pがmの約数かどうかに関わらず、\[(m^{e})^{d}\equiv m\mod{p}\]が成立する。

pとqの対称性より、qについても同様に\[(m^{e})^{d}\equiv m\mod{q}\]が成立する。 pとqは異なった素数であるから、pとqの積であるnについて\[(m^{e})^{d}\equiv m\mod{n}\]が成立する。よって示された。

RSA暗号の安全性

RSA暗号を破るには任意の自然数を高速に素因数分解できなければならないと考えられている。そして今のところ、数十年にもわたる多くの優秀な数学者たちの努力にも関わらず、大きな自然数の素因数分解を高速に実行するアルゴリズムは発見されていない。また、そのようなアルゴリズムが存在することも証明されていない。このことから、今のところRSA暗号は正しく運用されれば安全であると考えられている。

ただしRSA暗号を破るには自然数を高速に素因数分解することが必須であるとは証明されておらず、未解決問題の一つとなっている。

また、量子コンピュータを用いれば任意の自然数を高速に素因数分解できる可能性が示唆されており、そういった計算機の著しい能力の向上によってRSA暗号の安全性が脅かされることは有りうる。

任意の自然数を高速に素因数分解する能力を持つ攻撃者オスカーが存在すると仮定する。上述したRSA暗号についてのアリスとボブの例において、オスカーは以下の手順で秘密のメッセージを傍受することができる。

  1. ボブが公開した暗号化用の鍵(n, e)を受け取り、nとeを取り出す。

  2. nを素因数分解してpとqを得る。

  3. eとp、qを用いて上述した条件を満たすdを求める。

  4. オスカーはnとdを用いて暗号化された秘密のメッセージcを復号化して秘密のメッセージmを得る。

このように、RSA暗号は任意の自然数を高速に素因数分解する能力を持つ攻撃者に対して無力である。

参考:暗号理論入門(J.A.ブーフマン著 林 芳樹訳)

2013年11月12日火曜日

QtはMinGWのgcc4.8.1ではコンパイルできない

参考:https://qt-project.org/forums/viewthread/33370/
参考:http://stackoverflow.com/questions/18739688/compile-time-error-from-a-qt-file-expected-unqualified-id-before-token

ひとつはMinGWのバグのせい。io.hのoff64_t_を_off64_tに置換すれば解決する。
もうひとつはQtのバグのせい。MemoryBarrierという名前がWindowsのものとQtのものとで競合するため。Qt5.1.2とQt5.2では修正される予定。

しょうがないのでQt5.1.2か5.2がリリースされるまではQtをソースからビルドする場合にはQt4.8.5を使おう。
やり方は以下に以前書いた。
http://wirelessia-liberation.blogspot.jp/2012/12/windows764bitmingw-gcc47-qtsdk484.html

Qt4.8.5も無理でした。MinGWのバグのようです。
結局バイナリインストーラを使うしかないのか……

既にあるMinGW+Msys環境からMsysGitを使うシンプルなやり方

WindowsでGitを使おうとするとたいていMsysGitを使うことになるのだけれど、MsysGitにはMinGWが付属していて、既にMinGW環境がある場合にはちょっとややこしいことになる。
できれば既にあるMinGW環境でGitを使えるようにしたい。
mingw-getで入ればいいのだけれど、少なくともこの記事を書いている現在はできない。

参考:http://sourceforge.net/p/mingw/feature-requests/127/

上のリンクにすべて書いてあるけれど、改めてきちんと書き出してみる。

MsysGitをインストールする。Msysからしか使わない場合は最小構成でOK。
Program Files/MsysGit/bin/の中にあるmsys-1.0.dllを削除する。(削除しなかった場合は後述)
Windowsシステムの環境変数のPATHの末尾(というかMinGW/binより後)にProgram Files/MsysGit/binを突っ込む。

これで既にあるMinGW環境からgitコマンドが使えるようになる。
ただしgit commitでvimが起動しないのでgit commit -mで使うしかないようだ……
msys-1.0.dllを削除しないでおくとvimが起動しないままストップし、削除しておくとプロシージャエントリポイントが云々のエラーが出る。