春鳥 -ハルドリ-

2006年11月

2006-11-29(WED)

チェックサめれた、と思う

先輩の言葉のおかげでできました。&0x7fですよ。&0x7f。説明書に1ビット削るって書いてあったから、1ビットしか減らしちゃいけないと思ってたんですけど、上のほうのビット、ガッツリ削ってよかったんですね。

そんなわけで、data[sort_count][53] = Convert.ToByte(sum & 0x7f);となりました。配列の配列の配列だったdataは、配列の配列に戻してあります。sort_countは並び替え後の行数のようなもの。全体のソースは、今度気が向いたときに公開します。

パソコン間で通信できなかった理由は不明ですが、ロボとの通信ができなかった理由の見当がついたので、今週はデータの送信ができそうです。

2006-11-27(MON)

チェックサム

どうやればいいんだ……。合計を出すってのはわかるんですけど、合計すると1バイトに収まりきらないわけで。

2号機の説明書にはチェックサムの説明が何もなく、1号機の説明書にはチェックサムに触れている部分があるからそれを見ながらやっています。これによると、コマンドからチェックサムの前までのデータ(1号機の場合は15個)の合計の値から最上位1ビット削った値、がチェックサムになるそうです。でも、1ビット削ったくらいでは、1バイトにならないんですよ。1号機も2号機も。

説明書に書いてあるチェックサムの最大値は7F(10進数で127、2進数で1111111)。ってことは、1ビット削る前の最大値は、11111111の255でFF?それ、1バイト以内じゃありませんか?

ロボからデータを読み取って確認する必要がありそうです。読み取りプログラムが動かないのにどうしようか。

あれ?

1号機のモータの数は17個(最大24個)のはずなのに、なんで説明書のCHは12までなんだろう。あ、1号機の場合は、基板が2枚で片側12だからか。となると、2号機は1枚の基板に24個になるから……どうなるんだ?1号機の説明書ではわからないということがわかりました。

やっぱり、ロボからデータを読み取るしかないのか。

2006-11-26(SUN)

ディジタル技術検定

2級を受けました。受かりそうにないです。

PS3で

Fedoraが動いてたりして楽しそうなことになっていますね。ただ、60GBの買ったとしても10GBと50GBにしか分けられないという謎な仕様みたいです。今後出てくるのその辺り変わったりするんでしょうか。

Fedoraが動くなら、メインパソコンとして使っても問題なさそう。Cellの動作周波数は3.2GHzだって言いますから、今のパソコンより性能よさそうですし。パソコンとしてみるならかなり安いですよね。どのくらい、パソコンとして使えるのかはわかりませんけど。

PS3を買う人でLinuxを入れる人、Linuxを使っている人でPS3を買う人、どのくらいいるんだろう。

2006-11-24(FRI)

動かねぇ。

パソコン間(送信側:自作プログラム、受信側:ハイパーターミナル)で、モーションデータを送ると怪しげな文字列が表示されました。送信側のデータをBitConverter.ToInt32()でintに変換して、送信側のプログラムのlistboxに表示させるとちゃんと数字は入っているようです。

今度はデータの受信機能を追加して、自作プログラム同士で送りあってみたけどこれは受信できてないみたいです。

PH、PLって。

動作パラメータの範囲が0~65535の2byteだから、PH、PLにそれぞれに1byteずつ入れたらいいってことなんじゃないか。おぉ、なんかわかってきた。

冬休みが始まるまでには、ロボを動かせるところまで進めたいです。でも、その間、資格試験やら中間テストやら、TOEICやらやらと頭と精神を酷使するイベントが多々あります。やる気が続いているか心配。

2006-11-23(THU)

祝200行超え

PHとPLってなんだろうね。数的にサーボの角度を設定するやつだと思うんだけど。よくわからないから、両方に同じ値を入れるようにしてみました。一応、どちらか一方だけに値を入れて、片方を0にすることもできるようにしてあります。

そんなこんなで、動作を送信する順番に並び替え、送信用の形に整形することができました。今のところ、ループ無しのモーションのみに対応しています。このデータを送信すれば、ロボが動いてくれるかもしれません。ちなみに、最初の動作を表していると思っていたMainの値はループのときに使う数値で、最初の動作は、[GraphicalEdit]のStartの値でした。

送信には、

byte[]型に変換する必要があるみたいです。そこで、送信用の配列をbyte[][]にして、値を入れるときに、Convert.ToByteとしてみました。が、範囲が0~255のbyteの中に、3000を超える数値が入るはずもなく、エラー。

調べてみると、バイト列と数値を変換するには?というのがありました。これによると、BitConverter.GetBytes()を使えばいいらしいです。byte型の配列に入れるから、送信用の配列は、byte[][][]になりそうです。配列の配列の配列。

ソースの書き換えが面倒です。配列の合計、どうやって出そう。

できたー

明日の実験でパソコン間のデータ送信をして、できているようだったらロボへ送信。動きますように。

ループを使ったモーションへの対応は、後日。今日はもう、疲れました。

2006-11-20(MON)

新しいデザインは、順調に停滞してます。

C#は一休みして、GIMPの練習。

以上、今日の経験。まだ、背景色すら決まってないです。暗い感じの何色にしよう。

2006-11-19(SUN)

せっかく頑張ったのになー。

[GraphicalEdit]
Type=0
Width=778
Height=734
Items=6
Links=6
Start=0
Name=無題
Port=16777215
Ctrl=65535

Itemの数、モーションファイルの1番上に書いてありますやん。配列のサイズ変える必要ありませんやん。

まぁ、いいや。さぁ、書き直そう。

いやいや

どっちみち、値を取ってこないといけないし、繰り返し中に何行目にいるのか数えてないといけないから昨日のままでいいのか。

いいのか?

えーと、あの値を使うとすると、

int count=0;
int items;
int[][] motion;
int[] prm = int[25];

//ここからメソッド内

//whileでファイル読み出しここから(省略)
if (line.Contains("Items") == true)
{
    string str_items = line.Remove(0, 6);
    items = int.Parse(str_items);//Item数を取り出し
    motion = new int[items][];//Item数行の配列の配列
}


//prm[0]から[24]に値を入れる作業(省略)

if (count != items)//countの数がitem数でなければ
{
    motion[count] = new int[25];//motionのcount行目に25列用意
    for (int i =0; i <= 24; i++)
        motion[count][i] = prm[i];
    count++;
}
//上のwhileに戻る

ということになるのかな。試してないからものすごく自信ないです。

今気がついたけど、prm[0]から[24]に値を入れるのは、別にmotion[count][0]から[24]でもいいから、さらに行数が短くなるのか。

Array.ResizeをItem数回繰り返すのと、Item数を取り出すのだったら、後者の方が速そう。書き直さなくてもいいじゃないか、という結論を出すために書き始めたのに書き直すほうがよさそうに思えてきました。

だがしかし

実際つくってみると、両方ともサンプルの歩行(前)(Item数16個)で読み込みに3.4秒、Item数67の大きなファイルで42秒。まったく同じでした。

かかりすぎている読み込み時間の改善をしたいです。

そしてまた

時間がかかっていたのは、読み込みではなく表示でした。richTextBoxからlistBoxに変えると一瞬で表示されるようになりました。

2006-11-18(SAT)

なるほどなー

arr = new int[5];とか書くのは、arr[0]からarr[5]まで作っているんじゃなくて、配列を5つ、arr[0]からarr[4]までを作るって意味だったのかー。それでよく、配列の大きさを確かめろとデバックで言われてたわけですね。

さて、そういう新たな事実に気がついたりしながら7時間。モニタに向かい続けてできました。今日のMVPは、Array.Resizeに贈りたいと思います。配列のサイズを変えてくれるヤツなんですけど、配列の配列にも対応してくれているみたいで、本当に助かりました。

以下、例によってソース。昨日とは変数名が変わってたりします。

int[] prm = new int[25];
int count = 0;
int[][] motion = new int[1][];//1行のジャグ配列
public void button2_Click(object sender, EventArgs e)
    {
    if (openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        System.IO.StreamReader sr = new
            System.IO.StreamReader(openFileDialog1.FileName);
        string line, prm_line;
        string[] output = new string[25];
        while ((line = sr.ReadLine()) != null)//1行ずつ入力ファイル読み込み
        {
            if (line.Contains("Prm") == true)//Prmが出てきたら
            {
                prm_line = line.Remove(0, 4);
                string[] str_prm = prm_line.Split(new char[] { ',' });
                //prm[0]は速度
                motion[count] = new int[25];//count行目に25列の配列
                for (int i = 0; i <= 24; i++)
                {
                    prm[i] = int.Parse(str_prm[i]);//str_prmをintに変換
                    motion[count][i] = prm[i];
                    output[i] = string.Format("ch{0} = {1}\n", i, prm[i]);
                    if (i != 0)
                    {
                        if (i == 1)
                            richTextBox1.Text
                            += string.Format("Item {0}\n", count);
                            richTextBox1.Text += output[i];
                    }
                    //m[count][i] = n[i];
                }
                count++;
                Array.Resize(ref motion, count+1);
            }
        }
        sr.Close();
    }
}

次、大雑把にわかりにくい解説。まず、配列を収めるための配列(motion)を1行用意します。それから、モーションファイルをlineに1行ずつ読み込み。行に「Prm」が現れると、motionのcount行目(初期値0)に25列の配列を指定します。その列の中にPrmの数字をバラしたもの(16384等々)を一つずつ入れていき、これが終わるとcountの値を一つ増やし、さらにmotionの行数を1つ増やして、読み込み再開。以上。

で、ここでまた恐ろしい事実をおもいだしてしまいました。モーションデータって配列の順番どおりに再生されているわけではないんですよ。たとえば、モーションファイルのItem0が腕を上げる動作でItem1が足を曲げる動作、Item2が腕を下げる動作だとすると、Item0→Item2→Item1かもしれないし、Item1→Item0→Item2かもしれないんですよ。更に、数回のループかもしれなかったり。

この情報は、モーションファイルの後半(前半は昨日のモーションデータ)に書かれていて、驚くべきことに順番がかなりランダムなんです。以下、モーションファイル後半。

(前略)
[Link0]
Main=0
Origin=2
Final=5
Point=

[Link1]
Main=0
Origin=5
Final=3
Point=

[Link2]
Main=0
Origin=6
Final=7
Point=
(後略)

「=」の後の数字がItemの数字と一致していますから、Mainが1番最初に実行される動作、OriginとFinalでつながりをあらわしているみたいです。だから、一連のモーションにするにはOriginとFinalの値が同じものを追いかけていけばいいはず。ですが、ループするモーションの場合、同じ数字のOriginが複数あったりするわけで、その辺どうなっているのか考えなければなりません。それができたら今度は、配列の順番入れ替えをして、ようやくデータが送信できるようになります。

2006-11-17(FRI)

実験が進まない

以下、モーションデータとプログラムの一部。

[GraphicalEdit]
Type=0
Width=778
Height=734
Items=6
Links=6
Start=0
Name=無題
Port=16777215
Ctrl=65535

[Item0]
Name=POS1
Width=50
Height=30
Left=47
Top=26
Color=16777215
Type=0
Prm=100,16384,16384,16384,16384,0,16384,16384,16384,0,0,16384,
16384,16384,16384,16384,0,16384,16384,16384,16384,16384,0,0,0

[Item1]
Name=POS3
Width=50
Height=30
Left=47
Top=134
Color=16777215
Type=0
Prm=50,16465,16392,16452,16188,0,15868,16292,16376,0,0,16408,
16328,16416,16380,16392,0,16412,16356,16532,16480,16376,0,0,0
(以下略)
public void button2_Click(object sender, EventArgs e)
{
    if (openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        System.IO.StreamReader sr = new//ファイルダイアログオープン
           System.IO.StreamReader(openFileDialog1.FileName);
        string line, prm;
        string[] output = new string[25];
        while ((line = sr.ReadLine()) != null)//1行ずつ入力ファイル読み込み
        {
            if (line.Contains("Prm") == true)//Prmが出てきたら
            {
                prm = line.Remove(0, 4);//Prm=を削除
                string[] c = prm.Split(new char[] { ',' });//,ごとに分解
                //c[0]は速度
                for (int i = 0; i <= 24; i++)
                {
                    n[i] = int.Parse(c[i]);
                    output[i] = string.Format("ch{0} = {1}\n", i, n[i]);
                    if (i != 0)
                    {
                       if (i == 1)
                            richTextBox1.Text 
                            += string.Format("Item {0}\n", count);
                        richTextBox1.Text += output[i];
                    }
                }
                count++;//Item数のカウント
            }
        }
        sr.Close();
    }
}

モーションデータで、Prm=のあとにある数字が速度と回転角度。プログラムでは、行列n[0]からn[25]の中に一動作分のモーターの速度と回転角度の値(整数)が入っていることになっています。この次にしたいのは、nをItemの数だけ用意した配列の配列に入れること。上のプログラムでは、読み込んだファイルに「Prm」という文字が出てくる度にn[0]からn[25]が上書きされるので、他所にデータを保管しておきたいんです。そこで、多次元配列の出番なのですが、最大の行数を指定しないと使えないようなんですよね。ここでの行数というのは、countで数えているItem(=Prm)数。これは、モーションデータによって数が違うから決められないんですよ。さてどうしよう。

2回ファイルを読み込んで1回目でItem数を数えるなんてことも考えたけど、わかりにくくなりそう。行数無しでうまくやれる方法はないものだろうか。

2006-11-14(TUE)

MSなのにタダで使える

Visual C# 2005 Express Edition。こ、こんなものがあったのかー!ありがとー、ありがとー。

ひとしきり喜んだところで、自宅で実験開始。手近な目標は、この間つくったモーションデータ読み込み(と出力)プログラムをGUIなプログラムにすることと、C#のクラスについて学ぶこと。あるクラスであれやこれやした変数を他のクラスで使うにはどうしたらいいのか……とかいう基本的な知識がないのです。

で、学ぶのは後にして、数時間に渡ってソースをこねくりまわした結果、テキストボックス内に文字を表示させることができました。richTextBoxとかいうのを使えばいいみたいです。

表示がコンソールからウィンドウに変わっただけで、実験的には前進してないような気がするのは何故だろう。次の実験の時間中にデータが送れるようになるといいなぁ。

2006-11-13(MON)

mono

using System.Collections.Generic;は、.NET FrameWork 2.0でないと使えないのかー。これが使えないと、「,」ごとに区切られた文字列を分解して……ってのができないんですよね。学校のはVisual Studio 2005だからできるんですけど、家のは2003ですから。monoもこれには対応していないみたいで、実験のは家で進められないなぁ。

とか思って調べてたたら、Mono 1.2で対応してそうだ。すぞいぞ、mono。ただ、NET Framework 2.0との完全な互換性を提供するMono 2.0のテクニカル・プレビュー版を来年3月にリリースする計画ってのが気になります。僕が使いたい所が1.2の段階で対応していてくれたら良いのですけど。

ということで、使えることを祈ってインストールすることにしました。今回は珍しくソースコードからのインストールです。予想外に時間がかかって待つこと数十分。インストールが終わり、試してみると期待を裏切ってエラーを返してくれました。

残念を通り越してがっかりだ。来年3月じゃ実験終わってますよ。

2006-11-11(SAT)

ワカラナイホウガイイ

CSSを書きはじめました。今回のテーマは「くねくね」。ずっと、直線ばかりでしたから、たまには丸っこいのも作ってみたいわけなのですよ。あと、白っぽいのが続いているから、暗い感じのにしたいです。怪しくなりすぎない程度に。

今まで直線ばかりだった理由は、CSSだけでは曲線が使えないのと、GIMPで曲線の描きかたがわかってなかったから。しかし今回、曲線練習用に作った画像が思いのほかうまく出来たため、これならいけるということで、テーマをくねくねにしました。暗い背景も、色を合わせにくいとから敬遠していたんですけど、だったら、色を使わなければ良いじゃないか、と。

発想の転換というより開きなおりの精神です。

2006-11-10(FRI)

ロボのアレ。

モーションデータを読み込みサーボの速度と回転角度を配列に格納する、というのができました。

「,」ごとに区切られた文字列を分解して、それぞれstring型の配列に入れるなんてことが、たった1行でできてしまうことに感動。こんなに簡単で良いのですか。

2006-11-09(THU)

P。

ロボ用プログラム全然やってないよ。帰りの自転車上でアレコレ考えているんだけど、家に着くと途端にやる気が。

とりあえず、入力ファイルを1行ずつ読み込み、Console.WriteLine(line[0]);で、各行の最初の文字だけを表示させようとすると、空白行が出てくるまで表示されて、

Unhandled Exception: System.IndexOutOfRangeException:
 Array index is out of range.
  at Read.Main (System.String[] args) [0x00000]

とかいうエラーがでることがわかりました。続きは明日の実験の時間に考えます。

2006-11-08(WED)

RC1、大丈夫じゃなかった。

まぁ、そのうち慣れるか直るかするでしょう。

放課後に進路説明会

企業名や就職人数、簡単な企業説明なんかがダァーっと書かれた資料をもらいました。

就職先を考えるのは大変そうですね。転職は別として、基本的には数十年間、その就職先で働くわけで。そう考えるとかなり悩むというか決め難いというか、こんな何もわかってない状態で決められるものなのか、と。

最終的な判断は数ヶ月先、でも、その数ヶ月先の時点で決められている自信がないです。ネットで調べたり、説明会を聞いたりしたとしても、「自分はここで働くんだ!」と、そんなにハッキリ決められるものなのですか?どーれーにーしーよーうーかーなー、で決めようとしている自分が目に浮かぶんですけど……。あぁ、恐ろしい。

どの方向に進むかも悩みどころですね。電子回路系は苦手ですし、かといって、プログラミングが得意とは口が裂けても言えないし、Linuxは趣味で使うには不便でない程度の知識しかないですから。プログラミングはC++のほうがいいのかなぁ。C#ってどうなん?それに、Linuxにしても、使用人口的にそれほど需要がなさそうだから就職で有利になるってこともないような気がします。いいとこ無しか。

企業側も新人ごときに期待なんてしてないでしょうから、もっと気楽に考えて良いのかな。良くないよなぁ。

2006-11-06(MON)

Opera日和

RC1にしたら大丈夫っぽい。

旧版からiniファイルを上書きしたのが悪かったのか、Opera-USBの様子も変だったので再設定。学校でも使うものなので念のためブックマークからハルドリ関連のものを削除しておきました。万が一落としても大丈夫です。

見られたくないなら、Operaにパスワードかけるなり、フラッシュメモリそのものにパスワードかけるなりすれば済む話なんですけどね。でも、使うとき面倒じゃないですか。などと言いつつOSの自動ログインは使わないタイプです。

2006-11-05(SUN)

Operaの調子が変

かなりの頻度で固まります。ページをすべて読み込む前にスクロールさせるとなるみたいなんですが、それも必ずというわけではなく。何が原因なのやら。

9.10 RC1がでてるからバージョンアップして様子をみてみます。

2006-11-03(FRI)

3日じゃ無理。3か月では?

3連休ですね。というわけで、これから実験に必要になるかもしれないプログラムをC#の練習を兼ねて作ってみることにしました。作りたいのは、ロボのモーションデータのファイルを読み込んで、その中にあるサーボの数値を探して配列に格納する、というモノ。参考になりそうなのは、C#プログラミングTips:ファイル入出力の基礎。これが完成して、パソコンとマイコンとで通信ができたらあとは、モーションデータの値を送ってやるだけでロボが動……いや、もしかして動かない?

そういえば、スピードの設定やらモーションのループ処理とかあるではありませんか。そもそも、データの値ってどういう形というか型で送ってやればいいのか知らないじゃないか……。10進数?それとも16進数?データの値はコマンドの値と一緒に送ればいいの?等々。それに、ロボを動かすだけではダメですよね。圧力センサーを付けるとか付けないとかという話を聞いた気がします。3か月ちょいでどうにかできるものなんだろうか。

今月末付近に資格試験を受ける予定だから、それの勉強もしなくちゃいけないし、それとほぼ同時にテスト発表。思っていたより、はるかに時間がないです。

2006-11-02(THU)

激しく模様替えしたい

新しいテーマは考えてはいるんだけど、いざそれを作るとなるとうまくできないですね。そんなわけで、気分転換+やる気を起こさせるために一時的に2005年度版のCSSに戻します。手を加えてないから、表示に不具合とかあるかもしれないです。htmlの変更点もないからたぶん大丈夫だとは思いますが。