トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

独り言日記(2006/07)

独り言日記

printfの実数値表示のワナ(2006/07/30)

行列・ベクトル計算で変な挙動をしてしまう原因を探って約丸一日。原因がつかめました。ということで、メモ書きしておくことに(しかし、何をプログラムしてるか明記してないので、いきなりなんだ、って話ではありますが(^_^;;)。

 float fDat;
 char szStr[256];

 // fDat に何か値を入れているとする
 //....
 sprintf(szStr, "fDat = %f\n", fDat);
 printf(szStr);

このときに「fDat = 0.0000」と出たときに「ああ、実数値は0なんだ」と思い込んでいたのが悩みの原因でした。

 sprintf(szStr, "fDat = %.15f\n", fDat);
 printf(szStr);

みたいに、小数点以下の表示を大きく取ってみると、「0.000000087422777」みたいに非常に小さい値だけど0でなかったことが判明。これで計算を繰り返しているうちにアンダーフローしてたみたいです。こりゃ、単純ミスですね(^_^;;。もっときっちり何が入ってるのか知りたい場合は、floatをunsigned long型にキャストして16進数で表示するのも手であります。

unsigned long *pL;
pL = (unsigned long *)&fDat;
sprintf(szStr, "%08X\n", *pL);

このように計算結果が怪しくなるようなことがないように

if(fDat > (-1e-4) && fDat < (1e-4)) fDat = 0.0f;

のようにクリッピングしてあげるほうが確実ではありそうですね。

小数点演算では何回かこの手のドツボにはまってたりしますが、CPUやOSの違いによって結果が異なることがあるのも悩ましいところです。

バグがとれねぇ(2006/07/30)

行列・ベクトルと格闘中。う〜ん、変に回転してしまう・・・。座標系が異なる空間のコンバートってなんかいつも悩んでる気が・・・。

CEDECの予約&振込みは完了しました。結構埋まってて、希望のものに参加できないのもありました、残念。Havokの聞きたかったんだけどなぁ。でも、Ageiaのが取れたので(たぶん初歩的な話でしょうけど)いいかな。ほぼ、開催3日間の半分は講演を聞きにいく予定です(最終日は丸一日入れてやりました(笑)。仕事でスケジュールが押さないことを祈ります)。

仕様書どおり(2006/07/26)

なかなか予定どおりに作るのは難しいもんです。自分で書いたドキュメントではあるんですが、整合性とか考えると追加が出たり。今まで仕様書どおりにきっちり実装完了したためしナシ。う〜む、まだまだ修行が足りないですねぇ。

で、現プロジェクトのマイルストーン第一弾の追い込み中。いろいろ技術ネタもたまってるのですが、また時を見計らって書き溜めることにします。

CEDEC 2006にて、物理エンジン関連のプレゼンがありますね。ちょっと聞きにいこうかな。というか、早く申し込まないと。<私

http://cedec.cesa.or.jp/

とあるサイトで見たのですが、物理演算処理をハードウェア化したところで、もともと昨今のCPU自身が速いので見違えるほどの速度アップは期待できない、といったことが書いてました。内部的にはどういうことをハードウェアに任せているのかは分かりませんが、ラスタライズのような連続処理ではなくて、並列処理に集中してるのかなぁ。そうだとすると、結局はCPUが速くなればソフトウェアで物理処理をしたところで時代が追いつく可能性も捨てがたいですし、、いずれにせよ様子見は続きそうです。

浮力(2006/07/19)

物理シミュで、たとえば空間が空気の場合(密度が1.2kg/m^3くらい)よく考えると、同じ空気で出来た物体があったとすると、それは空気中で浮かんでいることになります。外部からの力が加わらない限り不動です。これって、空気抵抗だけでは表現できません(空気抵抗は速度が出てこないと、あくまでも存在しないに等しいですので)。この運動は、浮力が関係してます。

浮力の計算は簡単で

浮力(N) = 流体の密度(kg/m^3) x 重力加速度(m/s^2) x 物体の体積(m^3)

で計算できます。流体の密度は空気中なら空気密度を使います。水中なら水の密度(1000.0kg/m^3)になりますね。

で、ODEで浮力を導入してみると空気(と同じ密度)でできた物体は浮いた状態に、少し密度を軽くすると上方向に移動するようになりました。これは、ODEの関数dBodyAddForceで与えればOKです。

ということで、より現実に近い物理運動をする場合、以下の3つの力を考慮すればそれっぽくなりそうです。

  • 下向きの力(F = mg)
  • 進行方向向きの空気抵抗
  • 上向きの浮力

しかし、ODEは基本的に基本機能しか実装されてないですねぇ。ただ、後から力を加えたりちょっかい出すことができたりしますので、いろいろ拡張し甲斐があります。

ODEで再現性のある動きをさせる(2006/07/13)

物理エンジンのODEでは、シミュレーション処理での衝突時にランダムを使っているところがあるようで、たとえば複数回同じ条件下で衝突処理を行ったときに、2.0秒後の物体の位置は必ず同じになるとは限りません。「シミュレーション」では、これは困るわけで同じ条件下では同じ位置・姿勢を保っていてほしいところ。ですが、この部分は特にODE本体をいじらなくても回避可能です。

ランダムで挙動が変わるのは「ランダムシード」で制御しているわけですので、それに関連するODEのソースを探ってみました。すると、misc.cppの「dRandSetSeed」でどうやらランダムシードを固定化できそうです。

で、挙動を同じようにするためにはシミュレーションステップが呼ばれるたびに(呼ぶ前に)、dRandSetSeed(n);を実行させると、動きを固定化できます。ただ、ランダムっぽさがないと自然ではありませんので、経過秒数の累積を元に

float m_passTime = 0.0f;  // 経過秒数を保持する変数
... 
void step(const float passTime) {
  int cou;

  // ランダムシードの固定化(経過秒数によって変化させる)
  // +0.0001f は、誤差を丸め込むためのゲタ履かせ
  cou = (int)((m_passTime + 0.0001f) * 60.0f) & 32767;
  dRandSetSeed(cou);

  // 物理空間の時間をpassTime秒進める
  dWorldQuickStep(m_world, passTime); 
  ...

  m_passTime += passTime;
}
  

みたいにすることで、開始0秒目からシミュレーションすると同じ動きを再現できるようになります。PhysX SDKでは、このへんはすでに機能として内包されてるみたいですね。

YouOS(2006/07/12)

Webブラウザ上でAjaxを使って動作するOSのようなもの。

https://www.youos.com/

これ、いい意味でやりすぎです(笑)。Ajaxってここまでできるのか、という驚きと、新しい視点だなと思いました。OSをリモートで持てるとすると、極端な言い方だとOSをローカルで持つ必要はない(というか、本当の意味でのOSに戻る、かな)、どこからでも自分の環境にアクセスできる、などなどいろいろ考えることができそうです。このネタは想像してなかったですねぇ。ナイス発想。

YouOS上のWebブラウザから入れ子のようにサイトを見ることができますね。

ウォーターフォールモデル vs スパイラルモデル(2006/07/08)

開発を進めるための手法として、大きく「ウォーターフォールモデル」と「スパイラルモデル」があります。ウォーターフォールモデルは名前の通り水が上から下に落ちていくように、順序立って前から開発を進めていく方法です。古い言い方ですがよくあるのが、「企画・提案・調査→提案書作成→外部仕様作成→内部仕様作成→コーディング→テスト→運用」という流れ。外部仕様とは外向けの画面設計部分(インターフェース部など)やお客さんに目で見て分かる仕様、内部設計はプログラム設計になります。委託開発の場合は、外部仕様はお客さんが考えていて、それに突っ込みいれつつモノにしていく、が多いかもしれません。

実際、この流れでいくとスムーズに進むのですが、「やっぱりこの仕様に変更しよう」とか後から言われたりしてムッキーとなることが多いかと。ほぼ、100%、仕様どおりに通過することはないと思われます。進まなくなるプロジェクトっていうのは、たいていは仕様がお客さんまたは開発者(もしくはSE)が理解できていないのもあるのかなぁと。実際にできたモノを見て判断、だと、結局は後からの多くのフィードバックが発生するわけですし。ただ、大きいプロジェクトだとウォーターフォールモデルが適してそうですね。

これらの問題を緩和するのがスパイラルモデルです。これは、プロトタイプをさくっと作ってお客さんに提示、フィードバックをもらいつつ動的に仕様を改変しながら開発を進めていく手法です。私はこの方法のほうが好きだったりします。自分から仕様を考えたプロジェクトだと、だいたいこれを使いますね。ただ、大規模プロジェクトだと難しいですので、あくまでも部分的に、ですが。欠点としてはいつまでたっても終わりが見えない気がする、です(^_^;;。改善改善、は、結局は納得のいくまで試行錯誤するわけですので、ある程度で区切りをつけないといけません。

良いとこ取りをするのなら、外部設計まではしっかり作ってこの段階でフィードバックさせる(文章が読めるお客さんの場合は有効)、ここで「OKをもらったので、後からの変更は言わないようにしてください!」とハッパをかけておく(笑)。その後はプロトタイプを作りつつ自分自身でスパイラルしながら実装していく。動く形になったらもう一度お客さんに見せてフィードバックをもらう(プレアルファ版として)。このときに最新の仕様書を常に見せること。最終調整と細かい部分を実装し、完成に向けて突き進む。で、テストに入る(できれば他の方・部署にやってもらうこと)。今までの開発経験で、これが私にとっては効率がいいやり方になってます。

実は開発モデルは学生時代に授業で習いまして、結構感銘を受けたのを覚えています。そのときにもらった資料を今でも大切に保管しています。開発の流れ、仕様書の書き方、テストとは、などなどいろいろ書かれたいわば虎の巻です。もちろん、スタイルは時代で変わるので通用しなくなる部分もあるのですが、少なくとも効率よく進めるためには段階を踏んでいく理解が必要かな、と思ってます。

お客さんあってのお仕事の場合は、ずるずるいかないための割り切りも必要かと思います(仕様書にないことを後から言っても受け付けないようにする)。円滑にシステムを設計する場合は、やっぱり仕様書の作成とそれをお互いで共有する・理解するが大事だと思います。

今持ってるプロジェクトでは計画通りに事を進めてますが、研究的な要素が入るとちょっと不安材料になっちゃいますね(^_^;;。

GPGPU(2006/07/05)

先日サイトで見つけた「Sh」ですが、GPUでプログラムを行うための言語のようなもののようです。

http://journal.mycom.co.jp/articles/2005/09/06/siggraph2/004.html

で「GPGPU」というのが、汎用的な演算処理をGPUで行わせるための手法(?)らしい。

で、GPUレイトレのソースを読んでみたのですが、基本的な考え方は

  • スクリーンからのレイのトラバース〜交差判定〜シェーディング〜反射(再帰)をGPUにまるごと収める(すべてGPU任せ。つまり、ソフト<==>ハードのやり取りを極力少なくする)
  • 三角形頂点は、あらかじめテクスチャとして格納
  • 空間分割は前処理で

こんな感じですね。ちなみに、GeForce6600GTのボードでもそれなりにリアルタイムに動きました<レイトレース処理。う〜ん、ただやはりリアルタイムで行くとすると、CPU<==>GPUのやりとりが頻繁に発生するのは厳しいか・・・。大規模シーンであったりゲームであったりでは、ハードに全データを収めて処理する、というのはリスキーになりそうです。100歩引いて、オフラインレンダラでGPUを利用するとしても、結局ボトルネックになるのはこのCPU<==>GPUのデータ転送だったりしますので、根本から考えないとレイトレーシングでハードウェアを頼るのは難しいのかなぁ。ただ、以前考えていて保留中にしている方法があるので、なんとかGPUを利用できないものだろうか(経験上、CPUでシーケンシャルにぶっぱなした方が速かったりするのが世の常なので、回り道になるかも)。

しかし、海外サイトではGPUプログラムがアツいですねぇ。いろいろ情報が手に入りますし。

GPUレイトレの覚書(2006/07/04)

どう効率化できるのか、ってのが見えないので論文漁り中。早速考えるのは放棄です(^_^;;。

http://gpurt.sourceforge.net/DA07_ 0405_Ray_Tracing_on_GPU-1.0.5.pdf 

見てみると、もっと細分化してやればよさそうですね。でも、あまりCPUと速度差がないようなグラフが書いてあるなぁ。

「Stream Ray Tracer」ソースあり

http://www.cgl.uwaterloo.ca/~gmoreno/streamray.html

私が考えていた構造と似てます(三角形の交差部分のみ。もっと上流から含めてますねぇ)。

いまいち、どの程度の速度で動くのか分からないので、これは一度実験的に実装してみないと効果が見えないですね。GeForce6600と6800ですでに速度差がでかいですので、これからのGPUの進化を見越しての研究が多い、のかな。なんとな〜くですが、あまり目からウロコのことはしていないような予感。とりあえず、いろんな方の論文を読んで参考にしてみます。

後、上記で紹介されていた「Shライブラリ」ってなんだろ?GPUでうにゃうにゃするライブラリっぽいのでなんか使えそうです。

http://libsh.org/

ソフトウェア開発データ白書 2006(2006/07/02)

日経BP社から出ている「ソフトウェア開発データ白書 2006」を買ってきました。開発に関するさまざまな分析がなされています。それと、最近の傾向が分かるので業界の流れがつかめるかも。ただ、サンプル企業数が19社程度なので、おそらく偏りがあるかもしれませんが。主に基幹システムが大半って感じですね。

で、面白い傾向としてWebブラウザを主体(クライアントの窓口)としたシステムでなくて、独自でアプリケーションを開発してそれでネットワーク経由で情報をやりとりするプロジェクトが大半なのが目に付きました。

「Web技術の利用」の統計にて、HTML/XML/JavaScript/Apache/IISなどよりも圧倒的に「なし」が大半という、統計になってないやん状態(^_^;;。これって昔々のシステムからまったく変化がないってことかもしれないですね。Webブラウザがなかった時代には、GUIは当然独自実装でした。(クライアント)端末がWindows系が主流になってからはWindowsのウィジットに頼る(VBやVCでのMFCなどに頼る)、といった時代を経て、今の主流はWebブラウザ上のコントロール(HTML/JavaScriptなど)となってます。

開発言語は、というと未だ「COBOL > VB > Java > C」だそうで。これって、6-7年前と同じではないですか。これから分かることは、昔からのデータを引き継いで脱皮し切れていないという構図が見え隠れしますね(現に「データの移行」ってのは非常に大きな課題だったりします。システム開発ではいつも根本にこれがありますよね。これの苦労を理解してない人も多いです(^_^;;)。これが果たして開発者側がそもそもJavaとかについてこれていないのか、昔からのシステムと併用する都合上の選択なのか・・・・。

白書の考察で「大量の開発者を投入すれば短期間で大規模な開発も実現できるという誤解を生みやすい」というのはまさにそう。これを理解できない人が上に立っちゃダメです(^_^;;。なんというか、なんでも「人月」換算するのは誤解を生むんですよね。白書にも書いているのですが、開発者が増えれば開発効率が下がる傾向にある、とあります。なかなかよく分析されてます。意思疎通部分って、人数が増えれば増えるほど複雑になって、それがスケジュールに影響したりするんです。数値だけで開発を見る(現場を知らない)人だと、このへんは理解に乏しくなるかもしれません。

まだまだいろいろな分析をされてますので、PMの方とか経営の方・営業の方はぜひ読んでいただきたいものです。意外と最先端なことをしてるわけではなくて、昔とさほど変わらない、ってのが受け取れると思います。結局大事なのは上流工程での管理だと思います(下っ端がいくら先鋭でも、お客さんとの橋渡しをする営業もしくはPMがダメなら、プロジェクトは進みませんし)。後、大半は受託開発で業務パッケージは利用しない、となると、業務パッケージを作ること自体が果たしてプラスになっているのか、疑問が出てきそうですね。お客さんのニーズに合わせて、だと近道は結局はローテクかなぁ、と思ったり(そういう私も受託開発中です(^_^;;)。

Future's Laboratory 技術格納庫 2004-2013 Yutaka Yoshisaka.